Connect the app to MQTT and show the connection status (iteration 2, step 4)

Dashboard creates the MQTT client and the HA device with the dummy
"Uptime" sensor (D41) in overlay and both desktop modes, connects in
started() and disconnects gracefully on aboutToQuit. The new platform
mode --desktop-novr behaves like --desktop for now (D22). The main tab
shows device, broker, connection state and last error (UI-1) through
the ConnectionStatus QML singleton.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-06 16:18:17 +02:00
co-authored by Claude Opus 5.5
parent 466743eff9
commit 943e90c1b1
15 changed files with 335 additions and 32 deletions
+16 -3
View File
@@ -62,6 +62,7 @@ cmake --preset native-debug && cmake --build --preset native-debug # system Qt
ctest --preset native-debug # all tests
build/native-debug/bin/tst_inputbridge clickUsesGlCoordinates # one QtTest function
build/native-debug/bin/frame-assistant --desktop # UI preview in a window, no SteamVR
build/native-debug/bin/frame-assistant --desktop-novr # same, and never SteamVR (from iteration 3 on the difference)
build/native-debug/bin/frame-assistant --snapshot x.png # one frame via the real offscreen path
scripts/container-build.sh cross # x86_64 → aarch64 against the Frame's system Qt (default)
scripts/container-build.sh native # same for the host arch (use on the Frame)
@@ -75,7 +76,9 @@ build/native-debug/bin/frame-assistant --graphics-api vulkan --benchmark 600 #
- Use `--snapshot` and then read the PNGs to check UI or rendering changes without a headset.
With several surfaces it writes `<name>-<id>.png` per surface (`-0` for an empty id).
Snapshot and benchmark don't load the settings.
- Overlay and desktop mode need a settings file; pass a test one with `--config <path>`.
- Overlay and both desktop modes need a settings file and connect to its MQTT broker; pass a
test one with `--config <path>` (e.g. `mosquitto -p 18883` and `"mqtt": {"host":
"127.0.0.1", "port": 18883}`).
- `tst_render` runs once per backend (`VRDASH_TEST_API`, separate CTest entries, because the
Qt graphics API is process-global). It QSKIPs without a GPU context or when Vulkan isn't
compiled in.
@@ -108,7 +111,8 @@ into Qt events.
- `src/app/DashboardApplication` is the **base class of every app** (in `vrdashboard_core`):
CLI, logging, SteamVR connection, backend selection, surfaces, controller navigation, and the
modes (overlay, `--desktop`, `--snapshot`, `--benchmark`, manifest install).
modes (overlay, `--desktop`, `--desktop-novr`, `--snapshot`, `--benchmark`, manifest
install).
- **Inheritance for the app, components for the surfaces** (the user's decision, after
trying composition): the app derives from `DashboardApplication`. In its constructor it
configures (`addSurface`, optional `setAppKey`/`setDisplayName`) and passes its own
@@ -202,7 +206,16 @@ into Qt events.
they must be part of the QML module. The generated type registration includes their
headers by file name only, so their directory is on the app's include path.
- **Settings** (`src/config/Config`) are loaded once in `Dashboard::prepare()` (overlay and
desktop mode) and passed on as an immutable value (DESIGN.md, D19).
both desktop modes) and passed on as an immutable value (DESIGN.md, D19).
- **MQTT and HA** (DESIGN.md, "Iteration 2"): `Dashboard::loading()` creates `MosquittoClient`
(`src/mqtt/`) and `HaDevice` (`src/ha/`), `started()` connects; `aboutToQuit` disconnects
gracefully (publishes "offline"). The HA layer only knows the `MqttClient` interface;
tests use `tests/FakeMqttClient.h`. `MosquittoClient`'s callbacks run in its own
`std::thread` and may only emit signals with copied values (D45).
- **Error texts are English** regardless of the locale: `strerror()` is translated (German on
the dev host), so use `strerrordesc_np()`.
- **`QTRY_*` evaluates its expression once more at the end:** never consume data in it
(e.g. `readAllStandardOutput()`); accumulate into a variable instead.
- **No Qt WebEngine** (REQUIREMENTS.md, D40): the Frame's system WebEngine can't be loaded, and bundling our own
failed (STEAM-FRAME.md). Don't link it: the whole app would fail to start on the Frame.
- **Check Frame libraries by loading, not by file:** before relying on a system library, check