docs: expose POS briefing as a switch tile (scenes don't tile in Google Home)

Google renders SCENE devices (HA scripts/scenes) as voice/Routine-only, not as
tappable tiles -> the button was invisible. Switched the Google exposure to a
template switch (tiles like the TV). Documents the broken HomeGraph SA key
(invalid_grant) that disables requestSync/reportState until regenerated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mortdecai
2026-06-07 14:15:41 -04:00
parent 2691dc4073
commit b540d5e394
+51 -56
View File
@@ -1,67 +1,62 @@
# HA + Google Home setup — POS Briefing button (DEPLOYED 2026-06-07) # 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), Status: deployed on VM HA (`192.168.0.146`, HAOS 2026.2.3) and verified end-to-end
except the final Google-app tap (yours to try). through HA. Final Google-app surfacing is yours (see "Your steps").
Chain: **Google Home tap → HA `script.print_daily_briefing``button.press` Chain: **Google Home tile → HA `switch.print_daily_briefing``button.press` on
MQTT `posbriefing/button/press` (broker CT 301) → `pos-briefing-mqtt.service` on `button.pos_briefing_print_daily_briefing` → MQTT `posbriefing/button/press`
steel141 → `pos_briefing.py` printer (by MAC) → TM-m30.** (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 ## Why a switch, not a scene
MQTT-discovery button is wrapped in a `script`, which Google exposes as a **Scene** A `script`/`scene` exposed to Google gets the **Scene** trait, which Google Home
(a tappable button in the Home app). 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 ## What is deployed on VM HA `/config` (backups in `/config/.backup/`)
prefixed with the device name): - **`scripts.yaml`** — `script.print_daily_briefing` (presses the button). Kept as
```yaml an alternate trigger; not exposed to Google.
print_daily_briefing: - **`configuration.yaml`**:
alias: Print Daily Briefing - `switch:` template `print_daily_briefing` (the tile; entity `switch.print_daily_briefing`).
sequence: - `google_assistant.entity_config` exposes `switch.print_daily_briefing`
- action: button.press (alongside the LG TV + projector; nothing else changed).
target: - `ha core check` passed → `ha core restart`. Local SYNC webhook confirms the entity
entity_id: button.pos_briefing_print_daily_briefing is reported to Google as `action.devices.types.SWITCH`.
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).
## Verified ## Verified
- `script.print_daily_briefing` loaded in HA (state `off`, "Print Daily Briefing"). - Local Google SYNC (the manual integration's local-fulfillment webhook) returns 3
- Firing the script via HA API → bridge logged `Received: PRESS` → `Running briefing...` devices: **Print Daily Briefing (SWITCH)**, Big TV (SWITCH), Projector (SETTOP).
→ `Briefing printed OK` → **physical receipt printed**. - `switch.turn_on switch.print_daily_briefing` → bridge `Briefing printed OK`
- MQTT discovery button is `button.pos_briefing_print_daily_briefing` (Settings → **physical receipt**. (Same for the earlier `script` path.)
Devices → MQTT → **POS Briefing**).
## Your only remaining step ## Known issue — HomeGraph auth broken (pre-existing, not from this work)
Open the Google Home app (account `slingshooter08`). **Print Daily Briefing** should HA's `SERVICE_ACCOUNT.json` (project `seth-freiberg`, SA `claude@seth-freiberg.iam`)
appear as a control (after the request_sync; if not, say "Hey Google, sync my has an **invalid private key** (`invalid_grant: Invalid JWT Signature`) — the key was
devices"). Tap it → receipt prints. Optionally assign it a room / rename. 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 ~12 min.
## Notes ## Notes
- A print takes ~12 min (gemma4:26b summarization). The button/scene returns - A print takes ~12 min (gemma4:26b). `posbriefing/status` goes `printing``ok`.
immediately; `posbriefing/status` goes `printing` → `ok`. A second press while one - Google-linking invariants (lgtv 2026-06-06, satisfied — don't re-fix): manual
is in flight is ignored (debounced) — no double prints. `google_assistant`, scopes `email`+`name`, "HTTP basic auth header" OFF, GCP consent
- Google-linking invariants (from lgtv 2026-06-06, already satisfied — don't re-fix): screen untouched (shared project).
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"
```