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:
+51
-56
@@ -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).
|
||||
|
||||
Reference in New Issue
Block a user