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>
HaEntity describes an entity for device-based discovery, throttles its
state (SEN-14) and reports availability (SEN-15); HaSensor is the
`sensor` type. HaDevice publishes discovery, availability and states
after each connect and after HA's birth message, provides the last
will and removes itself from HA. Unit tests with a fake MQTT client.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MqttClient is the interface the HA layer will use; MosquittoClient
implements it with one std::thread for DNS, connect, network loop and
reconnect with backoff (D45, amends D42: mosquitto_loop_start() blocks
the caller on DNS and stops silently on TLS/protocol errors).
tst_mqtt tests it against a local mosquitto: messages, retained
messages, first connect and reconnect, last will, login.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cmake/Mosquitto.cmake finds it through pkg-config; with
FRAMEASSISTANT_SHIP_MOSQUITTO=ON (all package presets) it installs
lib/libmosquitto.so.1 and Debian's copyright file and excludes the
library from the Qt bundler (D35). The build containers get
libmosquitto-dev, the test container the mosquitto broker.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
libmosquitto's own thread (D42), app commands in the platform for
--ha-remove (D43), committed TLS test certificates (D44).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Frame checks 3 and 4 are postponed (no device access). Iteration 2
publishes a dummy sensor instead of a real one (D41) and includes TLS,
--desktop-novr and --ha-remove.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DSH-1 ended with a negative result: the Frame's system WebEngine can't be
loaded, and bundling our own failed (no sandbox, ICU resources, Vulkan
abort, empty page). Reverts the tab (60deb43), the container packages
(0676998) and the bundler's WebEngine support (b823ff3, e2cfa8e), and
updates the docs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
file(INSTALL) without a type installs 0644; Chromium then can't launch
its helper process ("LaunchProcess: failed to execvp").
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When a bundled library is Qt WebEngine, the bundler also installs
QtWebEngineProcess (plus its libraries) to libexec/, the resources and
the en-US/de locales, and points qt.conf at them. The cross image unpacks
the arm64 QtWebEngineProcess (its package can't be co-installed with the
amd64 one). Experiment for DSH-1: the Frame's system WebEngine (6.7.0,
built against FFmpeg 6) can't be loaded.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ls fails for the pattern that matches nothing; with pipefail and set -e
the script ended without a message.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The manifest passes --log-file, so a settings error (CFG-2) ends up in a
log file in the install folder. Package README and docs updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README: settings file, --config, the new tab. ARCHITECTURE.md and
CLAUDE.md: prepare() hook, app command-line options, app code layout,
WebEngine notes, the moc raw-string pitfall. THIRD_PARTY_NOTICES: Qt
WebEngine. Ship config.example.json; the package README explains the
set-up. PROGRESS.md and DESIGN.md: phase 3 results and deviations.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
qt6-webengine-dev and its QML module in the native and cross (arm64)
images, for the "HA Dashboard" tab.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A second dashboard surface shows a WebEngineView at homeassistant.url, or
a hint when none is set. HaWebUi (QML singleton owned by Dashboard) holds
the URL and a persistent WebEngine profile under
~/.local/share/frameassistant/webengine so the HA login survives restarts.
QtWebEngineQuick::initialize() runs in main() before the app object (D39).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Config parses and validates the JSON settings (D34): required device name
and broker host, defaults, type checks, device id from ha_unique_id or
derived from the name (D31), warnings for unknown keys and for a password
in a file others can read. Dashboard::prepare() loads it in overlay and
desktop mode; --config selects another file (D22). New static library
frameassistant_lib for app logic; tst_config covers it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
prepare() runs once mode and app key are known, before engine, surfaces
and SteamVR; returning false ends exec() with exit code 1 (D21). The base
constructor takes the app's own QCommandLineOptions, parses them with its
own and exposes them via isOptionSet()/optionValue() (D38).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
D38: app-specific command-line options in the platform. D39: WebEngine
initialisation in main.cpp, persistent profile, tab "HA Dashboard".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
D31/D32: ids, topics, retain and availability for the HA MQTT interface,
MVP entity list. D33: MVP notification via the notify entity. D34:
configuration file format. D35: shipping libmosquitto. D36: NFR-3
measurement. D37: MVP implemented in four iterations, DSH-1 first.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
D29: only the MQTT client runs in its own thread; OpenVR and the HA
layer stay in the main thread. D30: four-level test strategy.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
D25: dashboard tabs and world overlays; premultiplied-alpha flag.
D26: one world overlay for all notifications. D27: MVP placement
"spawn in front, then stay". D28: DSH-1 (web UI out-of-the-box test)
joins the MVP, full dashboard becomes DSH-2. Add the research on
notification UI in VR (DESIGN.md, Appendix A).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
D20: requirement UI-1 (status in the main tab). D21: failing start-up
hook prepare() in the platform. D22: modes incl. --desktop with optional
SteamVR, --desktop-novr, --config. D23: one class per HA entity type,
native types preferred, own JSON service only as fallback.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DESIGN.md: one process with several threads (D16), three layers (D17),
HA-centric object classes (D18), injected configuration (D19). Design
decisions move from REQUIREMENTS.md to DESIGN.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
Requirements engineering for iteration 1 is finished (D13); phase 2
(planning and design) starts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Template stripped to the overlay platform (examples, demo UI and Frame
test package removed), renamed to FrameAssistant, and working rules for
the project recorded in CLAUDE.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>