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 <noreply@anthropic.com>
This commit is contained in:
2026-10-05 19:50:39 +02:00
co-authored by Claude Opus 5.5
parent ba6302a4c0
commit ed8b2237bd
3 changed files with 110 additions and 4 deletions
+74 -2
View File
@@ -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 `<prefix>/device/<id>/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.