ca_file or the system's CAs (MOSQ_OPT_TLS_USE_OS_CERTS), client
certificate, broker certificate and host name verified, settings errors
reported before connecting. The client thread blocks SIGPIPE: with TLS,
a write to a connection the broker closed killed the process. The
reason of a failed handshake (libmosquitto's log) is appended to the
error. tst_mqtt covers TLS with test certificates in tests/data (D44).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
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>
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>