diff --git a/docs/ha-setup.md b/docs/ha-setup.md index e0272aa..30a0c61 100644 --- a/docs/ha-setup.md +++ b/docs/ha-setup.md @@ -1,67 +1,62 @@ # HA + Google Home setup — POS Briefing button (DEPLOYED 2026-06-07) -Status: **deployed and verified end-to-end** on VM HA (`192.168.0.146`, HAOS 2026.2.3), -except the final Google-app tap (yours to try). +Status: deployed on VM HA (`192.168.0.146`, HAOS 2026.2.3) and verified end-to-end +through HA. Final Google-app surfacing is yours (see "Your steps"). -Chain: **Google Home tap → HA `script.print_daily_briefing` → `button.press` → -MQTT `posbriefing/button/press` (broker CT 301) → `pos-briefing-mqtt.service` on -steel141 → `pos_briefing.py` → printer (by MAC) → TM-m30.** +Chain: **Google Home tile → HA `switch.print_daily_briefing` → `button.press` on +`button.pos_briefing_print_daily_briefing` → MQTT `posbriefing/button/press` +(broker CT 301) → `pos-briefing-mqtt.service` on steel141 → `pos_briefing.py` → +printer (by MAC) → TM-m30.** -Google's `google_assistant` integration doesn't support `button` entities, so the -MQTT-discovery button is wrapped in a `script`, which Google exposes as a **Scene** -(a tappable button in the Home app). +## Why a switch, not a scene +A `script`/`scene` exposed to Google gets the **Scene** trait, which Google Home +does **not** render as a tappable tile (it's voice/Routine-only). A **switch** +renders as a tile (like the LG TV). So the action is exposed as a template switch. -## What was deployed (VM HA `/config`, backed up to `/config/.backup/`) +Because HomeGraph state reporting is currently broken (see below), the switch is +forced **always-off** and **both on and off fire the print**, so a tap always +prints regardless of Google's cached state. The bridge debounce prevents any +double-print. (Once the SA key is fixed, this can be simplified to on-only.) -1. **`scripts.yaml`** — the script (note the real discovery entity id, which HA - prefixed with the device name): - ```yaml - print_daily_briefing: - alias: Print Daily Briefing - sequence: - - action: button.press - target: - entity_id: button.pos_briefing_print_daily_briefing - mode: single - ``` -2. **`configuration.yaml`** — `script.print_daily_briefing` added to the existing - `google_assistant.entity_config` (alongside the LG TV + projector; nothing else - touched): - ```yaml - google_assistant: - # ...existing project_id / service_account / report_state / expose_by_default... - entity_config: - script.print_daily_briefing: - name: Print Daily Briefing - expose: true - # switch.big_tv_lg_tv ... media_player.mitsubishi_projector ... (unchanged) - ``` -3. `ha core check` passed → `ha core restart` → `google_assistant.request_sync` (HTTP 200). +## What is deployed on VM HA `/config` (backups in `/config/.backup/`) +- **`scripts.yaml`** — `script.print_daily_briefing` (presses the button). Kept as + an alternate trigger; not exposed to Google. +- **`configuration.yaml`**: + - `switch:` template `print_daily_briefing` (the tile; entity `switch.print_daily_briefing`). + - `google_assistant.entity_config` exposes `switch.print_daily_briefing` + (alongside the LG TV + projector; nothing else changed). +- `ha core check` passed → `ha core restart`. Local SYNC webhook confirms the entity + is reported to Google as `action.devices.types.SWITCH`. ## Verified -- `script.print_daily_briefing` loaded in HA (state `off`, "Print Daily Briefing"). -- Firing the script via HA API → bridge logged `Received: PRESS` → `Running briefing...` - → `Briefing printed OK` → **physical receipt printed**. -- MQTT discovery button is `button.pos_briefing_print_daily_briefing` (Settings → - Devices → MQTT → **POS Briefing**). +- Local Google SYNC (the manual integration's local-fulfillment webhook) returns 3 + devices: **Print Daily Briefing (SWITCH)**, Big TV (SWITCH), Projector (SETTOP). +- `switch.turn_on switch.print_daily_briefing` → bridge `Briefing printed OK` → + **physical receipt**. (Same for the earlier `script` path.) -## Your only remaining step -Open the Google Home app (account `slingshooter08`). **Print Daily Briefing** should -appear as a control (after the request_sync; if not, say "Hey Google, sync my -devices"). Tap it → receipt prints. Optionally assign it a room / rename. +## Known issue — HomeGraph auth broken (pre-existing, not from this work) +HA's `SERVICE_ACCOUNT.json` (project `seth-freiberg`, SA `claude@seth-freiberg.iam`) +has an **invalid private key** (`invalid_grant: Invalid JWT Signature`) — the key was +rotated/deleted during the lgtv 2026-06-06 security cleanup but the HA copy was never +refreshed. Effects: +- `devices:requestSync` 400 → HA can't proactively push device-list changes; you must + re-sync from the Google side ("Hey Google, sync my devices"). +- `devices:reportStateAndNotification` 400 → device states (incl. the TV/projector) + don't push to Google in real time. +**Fix (GCP, your call):** create a new JSON key for `claude@seth-freiberg.iam` +(HomeGraph API enabled), deploy to `/config/SERVICE_ACCOUNT.json` (chmod 600), restart +HA. Then `request_sync` and live state work for all devices, and this switch can drop +the both-directions-fire hack. + +## Your steps (Google Home app, account `slingshooter08`) +1. Say **"Hey Google, sync my devices"** (linking-based sync; works despite the SA-key + issue). **Print Daily Briefing** should appear as a tile. +2. Remove any **stale/phantom device** — HA only sends 3 devices; if Google shows 4, + the extra is leftover from a prior link. (Settings → the duplicate → Remove.) +3. Tap **Print Daily Briefing** → receipt prints in ~1–2 min. ## Notes -- A print takes ~1–2 min (gemma4:26b summarization). The button/scene returns - immediately; `posbriefing/status` goes `printing` → `ok`. A second press while one - is in flight is ignored (debounced) — no double prints. -- Google-linking invariants (from lgtv 2026-06-06, already satisfied — don't re-fix): - manual `google_assistant` integration; account-linking scopes include `email`+`name`; - "HTTP basic auth header" checkbox OFF; the GCP OAuth consent screen is unrelated. -- Optional MQTT status sensor (configuration.yaml) if you want last-result visibility: - ```yaml - mqtt: - sensor: - - name: "POS Briefing Status" - state_topic: "posbriefing/status" - availability_topic: "posbriefing/availability" - ``` +- A print takes ~1–2 min (gemma4:26b). `posbriefing/status` goes `printing` → `ok`. +- Google-linking invariants (lgtv 2026-06-06, satisfied — don't re-fix): manual + `google_assistant`, scopes `email`+`name`, "HTTP basic auth header" OFF, GCP consent + screen untouched (shared project).