Files
FrameAssistant/docs/PROGRESS.md
T
matzmanandClaude Opus 5.5 873892c129 Log SteamVR-started instances to logs/<exe>.log
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>
2026-10-05 22:24:36 +02:00

9.5 KiB
Raw Blame History

Progress

Where the project stands, and what happened in each session. Newest first. The process is in CLAUDE.md ("Working rules").

Current state

  • Implementation iteration 1 (DSH-1 and configuration), phase 3 (implementation) done, waiting for the user's approval. All plan steps are implemented and committed; next is phase 4, testing on the Frame (plan item 10).
  • Started by SteamVR, the app now logs to logs/frame-assistant.log in the install folder: the manifest passes --log-file (CFG-2 wants the settings error in a log file). Whether SteamVR on the Frame honours the manifest's arguments is checked in phase 4.

Next steps

Requirements and design cover the whole MVP; it is implemented in four small iterations (D37), each with implementation, testing and assessment:

Iteration Content Platform change Checked by
1 DSH-1: HA web UI (Qt WebEngine) in a dashboard tab; configuration (D34) with start-up hook and --config start-up hook (D21), WebEngine initialisation before the QGuiApplication HA web UI in the tab on the Frame; result documented
2 MQTT client (own thread), HA device with discovery and availability, libmosquitto in the package, status display UI-1 modes (D22) device appears in HA, online/offline right, reconnect works
3 OpenVR wrappers and the 13 sensor entities --desktop with optional SteamVR (D22) sensor values in HA on the Frame
4 notification manager, notify entity, world overlay world overlay, premultiplied flag (D25) notification from HA in VR, also in a game

Plan for implementation iteration 1: DSH-1 and configuration

Goal: a second dashboard tab "HA Dashboard" shows HA's web UI at the URL from the configuration; what works out of the box is tested and documented. The main tab stays "Frame Assistant".

Platform (vrdashboard_core):

  1. Start-up hook prepare() (D21).
  2. App-specific command-line options (D38): the base constructor takes an optional list of extra QCommandLineOptions, adds them to parsing and --help, and exposes their values.

App: 3. QtWebEngineQuick::initialize() in main.cpp before the app object (D39); no platform change. 4. Configuration (src/config/): immutable value plus load(path, &error), complete per D34; path from --config, else $XDG_CONFIG_HOME or ~/.config/frameassistant/config.json; loaded in Dashboard::prepare() (overlay and desktop modes). 5. HA web UI (src/ha/HaWebUi, D18): holds the URL (injected), exposed to QML as a singleton owned by Dashboard; a named, persistent WebEngine profile under ~/.local/share/frameassistant/ so the HA login survives restarts (D39). 6. New surface dashboard ("HA Dashboard"), QML root HaDashboard.qml with a WebEngineView; without a URL it shows a hint. 7. Build: find_package(Qt6 … WebEngineQuick); qt6-webengine-dev (native and :arm64) in the containers; a new static library for app logic (configuration, HaWebUi) that tests link.

Tests (D30): 8. tst_config: valid file, missing required fields, invalid JSON, wrong types, defaults, derived and explicit ha_unique_id, unknown keys, --config. 9. Platform: tst_surfaces extended for prepare() (success/abort) and extra options. 10. Manual, results documented: host --desktop; Frame desktop mode over RDP; Frame in VR with Vulkan and OpenGL: page loads, laser click, scrolling, SteamVR keyboard in the page's input fields, login kept after restart; CPU/GPU while the tab is open. 11. clang-format clean, ctest green; container-test.sh only if Vulkan code is touched.

Docs: 12. README (configuration file, --config, new tab), ARCHITECTURE.md and CLAUDE.md (new hook, app options), THIRD_PARTY_NOTICES (Qt WebEngine from the system), STEAM-FRAME.md (results), PROGRESS.md.

Known limitation: the bundled-Qt package does not support WebEngine in this iteration.

Log

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.
  • Phase 3 of implementation iteration 1:
    • Platform: prepare() hook and app-specific command-line options, tested in tst_surfaces (incl. surfaces_prepare_fail).
    • Settings file (src/config/, new library frameassistant_lib), --config; tst_config (37 cases). config.example.json in the package; README.txt explains the set-up.
    • "HA Dashboard" tab: WebEngineView, HaWebUi with a persistent profile, WebEngine initialisation in main(). Host: desktop mode loads a local test page, profile data lands in ~/.local/share/frameassistant/webengine; snapshot renders both tabs.
    • Build containers with Qt WebEngine. Cross build: the aarch64 binary needs no private Qt symbols, at most Qt_6.8 and GLIBC_2.34. Container tests 8/8 (incl. Vulkan with validation layers, no messages).
    • Snags: moc misses classes in files with raw strings containing // (CLAUDE.md); generated QML type registration includes headers by file name; Qt ≥ 6.9 hints at WebEngineProfilePrototype (not in the Frame's 6.8). Deviations: HaWebUi lives in the app, not the library; the password warning needs a password in the file.
    • Log file for SteamVR-started instances: the manifest passes --log-file logs/frame-assistant.log (user's choice among: default log path in the app, manifest argument, document only).
    • Not verified yet: WebEngine with a URL in the off-screen pipeline (Frame, phase 4); the bundled package (not supported for WebEngine in this iteration).
  • Plan for implementation iteration 1 approved; phase 3 started.
  • Plan for implementation iteration 1 written; new tab "HA Dashboard" (D38, D39).
  • MVP implemented in four iterations; DSH-1 first, at the user's wish (D37).
  • NFR-3 measurement method, manual in the MVP (D36). MVP details done.
  • Shipping libmosquitto (D35).
  • Configuration file format (D34).
  • MVP notification: notify entity with first line as title; JSON command later (D33).
  • HA MQTT interface: ids (D31), topics, retain, availability (D32), MVP entity list.
  • Test strategy in four levels (D30). High-level architecture done.
  • Threads: MQTT client in its own thread, everything else incl. OpenVR in the main thread (D29).
  • DSH-1 split: web UI out-of-the-box test in the MVP, full dashboard as DSH-2 (D28).
  • Overlays: two kinds (D25), one overlay for all notifications (D26), MVP placement "spawn in front, then stay" (D27). Researched notification UI in VR (DESIGN.md, Appendix A). Found: premultiplied-alpha flag missing in the platform.
  • HA channels: MQTT for everything device-related; dashboard channel decided with Q2/Q3 (D24).
  • Entities: one class per HA entity type, native types preferred, own service only as fallback (D23). Found: MQTT notify drops the title.
  • Start-up hook prepare() in the platform (D21); modes, --desktop-novr and --config (D22).
  • New requirement UI-1: status display in the main tab (D20).
  • The user installed mosquitto on the dev host, so native builds can use libmosquitto.
  • Started docs/DESIGN.md: one process (D16), three layers (D17), HA-centric object classes (D18). HA side: FrameAssistant needs only stock HA; how the user wraps commands (scripts, pyscript) is up to them (NFR-6 unchanged).
  • Agreed to settle the high-level architecture first (list under "Next steps"), before component details.
  • 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

  • Copied the vrdashboard template. Removed what the app doesn't need:

    • examples/ (diagnostics app) and the VRDASH_BUILD_EXAMPLES option
    • the Frame test package (scripts/package-frame-test.sh, docs/FRAME-TESTING.md, screenshots)
    • the demo UI (src/qml/DemoPage.qml)

    Main.qml shows a placeholder card.

  • Named the app FrameAssistant, "Steam Frame companion for Home Assistant":

    • CMake project frameassistant, executable frame-assistant
    • app key net.matzman.frameassistant, tab "Frame Assistant", QML module FrameAssistant

    Names rejected:

    • "Steam…" and "…Home Assistant": trademarks
    • "HASS…": the user dislikes it, because "Hass" is German for hate.
  • Agreed working rules (in CLAUDE.md):

    • explicit permission for everything; ask instead of assuming
    • iterative five-phase cycle; an informal "ok" approves a phase
    • document everything in Markdown in docs/
  • git init. Baseline commit 4a5b090.

  • Requirements engineering (several question rounds with the user). The results are in REQUIREMENTS.md:

    • decisions D1–D12
    • 51 requirements
    • research on OpenVR data sources (Appendix A)
  • Checks: native-debug builds, ctest passes 6/6 (Vulkan surface test skipped, no Vulkan on this host), --snapshot renders.