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)
|
# 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 ~1–2 min.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
- A print takes ~1–2 min (gemma4:26b summarization). The button/scene returns
|
- A print takes ~1–2 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"
|
|
||||||
```
|
|
||||||
|
|||||||
Reference in New Issue
Block a user