111198bb12
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
59 lines
3.6 KiB
Markdown
59 lines
3.6 KiB
Markdown
# LG TV Bridge — Decisions
|
||
|
||
Format: `YYYY-MM-DD: <decision> — <why>`
|
||
|
||
- **2026-06-01: Single bridge, single host — runs on steel141, pve173 retired.**
|
||
The bridge had been running on pve173 (always-on node) since 2026-03-23,
|
||
SSHing to steel141 for every TV op. Consolidated everything onto steel141.
|
||
*Why:* the WebOS pairing key (`/home/seth/.aiopylgtv.sqlite`) lives only on
|
||
steel141, so `power_off` always routes through it regardless of bridge host —
|
||
pve173 added an SSH hop and a second host for no real availability gain (the
|
||
TV is uncontrollable whenever steel141 is down anyway). One host, no SSH hop.
|
||
|
||
- **2026-06-01: Cached-IP discovery, sweep only on miss.** Persist last-known TV
|
||
IP in `~/.cache/lgtv/last_ip`; probe it directly (TCP :3000/:3001). Full /24
|
||
ping-sweep runs only on a cache miss, then re-caches. *Why:* the old code
|
||
ping-swept all 254 hosts over SSH on every 30s HA state poll — slow, network
|
||
spam, and racy (stale ARP) → the chronic "flaky state in HA" symptom.
|
||
|
||
- **2026-06-01: Robust WoL — unicast + broadcast, ports 9/7, 3 bursts.** *Why:*
|
||
old code sent broadcast-only on ports 9/1235 once. Unreliable wakes. NOTE: the
|
||
remaining wake failures are TV-side (Quick Start+ / Mobile TV On must be ON;
|
||
wired Ethernet far more reliable than Wi-Fi for LG WoL) — not fixable in code.
|
||
|
||
- **2026-06-01: Deps via `pip --user --break-system-packages` for `seth`.** paho
|
||
+ bscpylgtv live in `/home/seth/.local` (PEP 668 box). Matches how bscpylgtv
|
||
was already installed; the systemd unit runs `User=seth`.
|
||
|
||
- **2026-06-01: power_off must pass an absolute `key_file_path`.** bscpylgtv's
|
||
`StorageSqliteDict` defaults the key DB to `os.getcwd()/.aiopylgtv.sqlite`
|
||
(its `$USER_HOME` fallback is not `$HOME`). The old pve173 setup worked only
|
||
because it SSHed in as seth, landing CWD in `/home/seth`. Under systemd
|
||
(cwd=/) it threw `sqlite3.OperationalError: unable to open database file`.
|
||
Fix: `WebOsClient.create(ip, key_file_path="~/.aiopylgtv.sqlite")`.
|
||
|
||
- **2026-06-01: power_off retries (2×, 10s apart).** A TV woken seconds earlier
|
||
answers TCP :3000 but refuses a WebSocket control session for ~20-30s, so an
|
||
immediate OFF-after-ON can fail. Retry covers it; normal case (TV already up)
|
||
succeeds first try in ~3s. Bounded under the bridge's 60s subprocess timeout.
|
||
|
||
- **2026-06-06: Google Home via the free manual `google_assistant` integration**
|
||
(not Nabu Casa). Exposed only `switch.big_tv_lg_tv`. Linked end-to-end and verified.
|
||
Three non-obvious requirements that were each a separate failure mode:
|
||
account-linking **Scopes must include `email` + `name`** (blank → no login page);
|
||
the **"HTTP basic auth header" checkbox must be OFF** (HA OAuth is secretless →
|
||
checked = `/auth/token` 401); and the Google **Test must be activated by the same
|
||
account used in the Home app** (slingshooter08). The GCP OAuth consent screen is
|
||
*not* part of smart-home linking — don't touch it (shared project runs WP Mail SMTP).
|
||
Full detail + security-cleanup list in `.claude/handoffs/2026-06-06-*.md`.
|
||
|
||
## Deferred / Rejected
|
||
- **DHCP reservation for the TV (static IP):** not done — Pi-hole doesn't run
|
||
DHCP (router does), so it's Seth's action on the router. The cached-IP probe
|
||
makes it unnecessary for correctness; a reservation would just let us drop the
|
||
sweep-fallback entirely. Add if convenient.
|
||
- **Unique per-instance MQTT client_id:** rejected — keeping a fixed
|
||
`lgtv-bridge` id means a duplicate instance is *loud* (reconnect war in broker
|
||
logs) rather than silent. Single-instance discipline is the real guard. (A
|
||
duplicate on 2026-06-01 during this very migration is what surfaced all this.)
|