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>