From ed8b2237bd30a778a5a34e5d701c99b9757a80fb Mon Sep 17 00:00:00 2001 From: Matzman Date: Mon, 5 Oct 2026 19:50:39 +0200 Subject: [PATCH] Choose libmosquitto and an own HA discovery layer D14: libmosquitto from Debian, shipped in the package (Qt MQTT needs the exact Qt version; nothing on the Frame). D15: own device-based discovery layer on Qt's JSON classes. Document the libraries per requirement and what the Frame provides (Qt modules, OpenSSL 3.2.1, glibc 2.39). Co-Authored-By: Claude Opus 5.5 --- docs/PROGRESS.md | 16 ++++++++-- docs/REQUIREMENTS.md | 76 ++++++++++++++++++++++++++++++++++++++++++-- docs/STEAM-FRAME.md | 22 +++++++++++++ 3 files changed, 110 insertions(+), 4 deletions(-) diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index 8dc8986..2acc16d 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -13,8 +13,8 @@ CLAUDE.md ("Working rules"). Phase 2 for the MVP scope (D8: MQTT connection + discovery + availability, the MVP sensors, a basic notification). Design topics, proposed order: -1. Q4: MQTT client library (licence, availability on SteamOS, TLS/login, Qt event-loop - integration, deployment). +1. ~~Q4: MQTT client library~~: done, libmosquitto (D14). Remaining for the design: Qt + event-loop integration, shipping the library in the package (build + `install.sh`). 2. Component structure: configuration, MQTT/discovery layer, sensor sources, notification service; how they fit into `Dashboard` (the app class). 3. HA entity model: topics, discovery payloads, availability, device grouping (CON-2/3/5, @@ -31,6 +31,18 @@ whether they constrain the MVP architecture. ### 2026-10-05: requirements approved - User approved REQUIREMENTS.md including the priorities (D13). Phase 2 started. +- Q4 decided: libmosquitto, shipped in the package (D14). Qt MQTT ruled out: private Qt API + requires the exact Qt version. Checked on the Frame: no MQTT library installed; libssl/ + libcrypto 3 and libcjson 1 present. +- HA discovery: own small layer on QJson, device-based discovery (D15); hacpp and the + embedded libraries rejected. +- Checked on the Frame which Qt modules, plugins and audio/network tools exist; library list + per requirement in REQUIREMENTS.md Appendix C. Notable: Qt WebEngine and Qt WebSockets are + present (relevant for Q2/Q3). +- libmosquitto ABI check: Debian's 2.0.21 needs at most `OPENSSL_3.0.0`/`GLIBC_2.34`; the + Frame has OpenSSL 3.2.1 and glibc 2.39. No libcjson dependency. D14 holds. +- Stay with the Debian build container: an Arch container wouldn't match SteamOS's own package + versions (private repos, rolling Arch) and has no arm64 multiarch for cross builds. ### 2026-10-04/05: project set-up and requirements diff --git a/docs/REQUIREMENTS.md b/docs/REQUIREMENTS.md index 6602f28..ab4ad1b 100644 --- a/docs/REQUIREMENTS.md +++ b/docs/REQUIREMENTS.md @@ -126,9 +126,9 @@ FrameAssistant. | # | Question | Status | |---|----------|--------| | Q1 | Several notifications at once: stack, queue, replace by tag? | open, design exploration | -| Q2 | Dashboard: HA's own web UI vs. native VR UI? | open, design exploration | +| Q2 | Dashboard: HA's own web UI vs. native VR UI? | open, design exploration (Qt WebEngine exists on the Frame, Appendix C) | | Q3 | Dashboard data: HA WebSocket API (token) in addition to MQTT, or MQTT only? | open, design | -| Q4 | Which MQTT client library? Licence, availability on SteamOS, TLS/login support. | open, design | +| Q4 | Which MQTT client library? Licence, availability on SteamOS, TLS/login support. | answered: libmosquitto, shipped in the package (D14, Appendix B) | | Q5 | Status card: own tab or part of the main tab? | answered: own tab, on demand (D9) | | Q6 | MVP sensor list? | answered (MVP column) | | Q7 | Minimum supported HA version? | answered: current release, no legacy features (D10) | @@ -152,6 +152,8 @@ FrameAssistant. | D11 | 2026-10-05 | Fixed sensor set; unsupported or missing values are "unavailable" | Same entities on every device, predictable in HA | | D12 | 2026-10-05 | Notification confirmations are reported to HA as events, if easy | Cheap to add, useful for automations | | D13 | 2026-10-05 | Requirements approved as drafted, priorities included (MVP = Must, other wanted features = Should, SRV-7 and NOT-10 = Could) | End of phase 1 | +| D14 | 2026-10-05 | MQTT client: **libmosquitto** from Debian's package in the build container, shipped in the release package like `libopenvr_api.so` | Not on the Frame; Qt MQTT would need the exact Qt version (Appendix B) | +| D15 | 2026-10-05 | HA MQTT discovery: **own small layer on Qt's JSON classes**, using device-based discovery (one `/device//config` topic with all entities under `cmps`) | No suitable library (Appendix B); HA recommends device-based discovery for multi-entity devices (NFR-7) | ## Appendix A: data sources @@ -202,3 +204,73 @@ screenshot (`RequestScreenshot`), launch apps (`IVRApplications`), notifications - **VR session duration** (time since put on): break reminders, statistics. - **Mic in use**: user is talking (voice chat), so don't play announcements. - **Streaming from a PC** vs. standalone (Steam Link), if detectable. + +## Appendix B: MQTT client library (Q4) + +Evaluated 2026-10-05 for D14. + +| | libmosquitto (C) | Qt MQTT | Eclipse Paho C/C++ | +|---|---|---|---| +| Licence | EPL-2.0 / EDL-1.0 | GPL-3 or commercial (no LGPL) | EPL-2.0 / EDL-1.0 | +| On the Frame (SteamOS, checked) | no | no | no | +| Arch repos / Debian | `mosquitto` / `libmosquitto-dev` | `qt6-mqtt` / Qt add-on | AUR only / `libpaho-mqtt-dev` | +| Login, TLS | yes (OpenSSL) | yes (QSslSocket) | yes | + +- **Qt MQTT is ruled out**, not because of its licence (the user accepts GPL-3), but because it + uses Qt's private API: `QMqttClientPrivate` derives from `QObjectPrivate`. QtCore then requires + the *exact* Qt version (`checkForIncompatibleLibraryVersion()` in `qobject_p.h` calls + `qFatal("Cannot mix incompatible Qt library …")`). A Qt MQTT built against Debian's Qt 6.8.2 + aborts on the Frame's Qt 6.8.0 and would break with every SteamOS Qt update. It would only + work with Qt bundled (about 46 MB instead of about 3 MB). +- **libmosquitto** does not depend on Qt. Debian trixie's `libmosquitto1` 2.0.21 (arm64) + needs only `libssl.so.3`, `libcrypto.so.3` and `libc.so.6`, with symbol versions up to + `OPENSSL_3.0.0` and `GLIBC_2.34`. The Frame has OpenSSL 3.2.1 and glibc 2.39 (checked + 2026-10-05), so it fits. Licence per Debian: EPL-2.0 or EDL-1.0 (`uthash.h`: BSD-1-Clause); + the licence text must ship with the package. +- Paho: no advantage over libmosquitto; uses its own threads. +- Integration into the Qt event loop (`QSocketNotifier` on `mosquitto_socket()`) is part of the + design. + +### HA discovery libraries (D15) + +No library fits; discovery itself is just JSON on a config topic. + +- [hacpp](https://github.com/pblxptr/hacpp) (C++, Linux): rejected. Early stage ("everything + can be changed soon"); only binary sensor, sensor, button, cover; buffers messages on + reconnect (contradicts CON-4); own MQTT client (async_mqtt) on Boost.Asio ≥ 1.90 (not on the + Frame), Conan 2, GCC 14+; its own event loop next to Qt's; TLS/login undocumented. +- [HAMqttDevice](https://github.com/plapointe6/HAMqttDevice), + [KLib-HomeAssistantMqtt](https://github.com/KazaLab/KLib-HomeAssistantMqtt), + [hamqtt](https://registry.platformio.org/libraries/dalib666/hamqtt): Arduino/embedded payload + generators with per-component topics. +- homie-cpp: implements the Homie convention, not HA discovery. + +## Appendix C: libraries per requirement + +Checked on the Frame 2026-10-05 (SteamOS, system Qt 6.8.0). Rule: **a Qt add-on module must +come from the Frame's system Qt.** Shipping one fails like Qt MQTT (Appendix B): Qt's modules +use Qt's private API, which requires the exact Qt version. + +| Need | Requirements | Candidate | On the Frame | New dependency | +|---|---|---|---|---| +| JSON | CFG-1, CON-2 | `QJsonDocument` (QtCore) | ✓ | no | +| HA discovery | CON-2/3/5, SEN-15 | own layer (D15) | — | no | +| MQTT | CON-1 | libmosquitto (D14) | ✗, shipped; its deps `libssl.so.3`, `libcrypto.so.3` ✓ (Appendix B) | yes | +| IP address | SEN-12 | `QNetworkInterface` (QtNetwork) | ✓ | no | +| SSID, signal | SEN-12 | NetworkManager via QtDBus | ✓ `libQt6DBus`, `nmcli` | no | +| Volume, mute, output | SEN-13, SRV-3 | PipeWire via libpulse, or `wpctl`/`pactl` | ✓ `libpulse.so.0`, `libpipewire-0.3.so.0`, `wpctl`, `pactl` | to decide in design | +| Sounds, audio from URL | NOT-4, SRV-8 | Qt Multimedia + QtNetwork | ✓ `libQt6Multimedia`, FFmpeg plugin | no | +| HTTPS (downloads, WebSocket) | SRV-8, Q3 | Qt TLS plugin | ✓ `libqopensslbackend.so` | no | +| Translations | NFR-4 | `QTranslator`, `lupdate`/`lrelease` | ✓ (build-time tools) | no | +| Dashboard, HA web UI | DSH-1, Q2 | Qt WebEngine (Quick) | ✓ `libQt6WebEngineCore`, `libQt6WebEngineQuick`, `libQt6WebView` | no; works with our off-screen renderer and Vulkan? Needs a spike | +| Dashboard, native UI | DSH-1, Q2/Q3 | HA WebSocket API via Qt WebSockets | ✓ `libQt6WebSockets` | no | +| Haptics, fade, apps | SRV-1/2 | OpenVR | ✓ | no | +| Tests | NFR-8 | QtTest | ✓ (host only) | no | + +Also present and possibly useful later: `libQt6TextToSpeech`, Qt's `networkinformation` plugin. + +Open points: +- The Debian build container needs the matching `-dev` packages (amd64 and arm64) for every + module used. Not checked yet. +- WebEngine and Multimedia come with SteamOS's desktop (KDE) packages; a SteamOS update could + remove them. diff --git a/docs/STEAM-FRAME.md b/docs/STEAM-FRAME.md index 00940c1..c727bd6 100644 --- a/docs/STEAM-FRAME.md +++ b/docs/STEAM-FRAME.md @@ -62,6 +62,28 @@ Without the deploy script: copy the `.tar.gz`, unpack it on the Frame, run `./in | Process names are cut to 15 characters | Scripts find running instances by command line, not by name | | Floated/pinned dashboard tabs stay visible and operable in games | Rendering follows the overlay's visibility, not the dashboard's | +## Libraries on the Frame + +Checked 2026-10-05; details per requirement in [REQUIREMENTS.md](REQUIREMENTS.md), Appendix C. + +- **System Qt 6.8.0** under `/usr/lib` includes, besides the base modules: DBus, Network, + Multimedia (FFmpeg plugin), WebSockets, WebEngine (Core, Quick), WebView, TextToSpeech, + Positioning, Sensors, Svg, VirtualKeyboard. TLS plugins: `libqopensslbackend.so`, + `libqcertonlybackend.so`. +- It apparently comes with the KDE Plasma desktop mode (plugins for plasma, kwin, discover). + **SteamVR does not use Qt 6:** nothing under `/opt/steamvr` links or ships `libQt6*`. So the + system Qt is not a SteamVR dependency, which is one more reason to keep the bundled-Qt + fallback. +- **Qt add-on modules must come from the system Qt.** Shipping one fails: they use Qt's private + API, and QtCore aborts on any version mismatch ("Cannot mix incompatible Qt library"). +- **Not present:** any MQTT library (no `libmosquitto`, no Qt MQTT). FrameAssistant ships + libmosquitto. +- **Present:** OpenSSL 3.2.1 (`libssl.so.3`, `libcrypto.so.3`), glibc 2.39, `libcjson.so.1` + (1.7.17), `libpulse.so.0`, `libpipewire-0.3.so.0`, and the tools `wpctl`, `pactl`, `nmcli`. +- **Libraries we ship must not need newer symbol versions** than the Frame has (e.g. + `OPENSSL_3.x`, `GLIBC_2.x`): check with `readelf -V`. Debian's libmosquitto needs at most + `OPENSSL_3.0.0` and `GLIBC_2.34`. + ## Notes - **The Frame's package repositories** in `/etc/pacman.conf` are private (URLs marked