Compare commits

...
3 Commits
Author SHA1 Message Date
Donavan FritzandClaude Opus 4.8 2a88f83b44 docs(website): refresh SKILL.md reference summary for Latchkey migration
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 22:53:09 -05:00
Donavan FritzandClaude Opus 4.8 52d09a4b8d docs(home-assistant): add HA reference for the lodge
Covers access (WS/REST API, no SSH, no backups), the dual Nest integration
(cloud Google Nest + local Matter), the 2026-06-15 Matter fabric loss and
on-site recommission steps, the temp scripts (label-driven, serialized to
dodge the Nest SDM 429), and the Lovelace dashboard layout. Registered in
SKILL.md references.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 22:51:44 -05:00
Donavan FritzandClaude Opus 4.8 de8803d959 docs(website): migrate to Latchkey managed-website service
Site now served by Latchkey 'Websites' (latchkey-sites bucket, sites anycast
edge, auto-TLS); retires the self-hosted Garage bucket + action/site-publish
+ Traefik Ingress flow. Edits via the app/API; /welcome stub re-key updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 22:51:44 -05:00
3 changed files with 126 additions and 41 deletions
+9 -2
View File
@@ -38,8 +38,15 @@ user-invocable: true
</references>
<references>
<reference file="reference/home-assistant.md"
summary="Home Assistant: access/WS API, dual Nest integration (cloud + Matter), 2026-06-15 Matter fabric loss + recommission steps, main Lovelace dashboard"
categories=["home-automation"]
keywords=["home assistant", "HA", "home.thelonglakelodge.com", "matter", "nest", "thermostat", "climate", "dashboard", "lovelace", "HVAC", "in floor heating", "environmentals", "core_matter_server", "172.24.24.50"] />
</references>
<references>
<reference file="reference/website.md"
summary="Lodge website: site-publish flow, /welcome PDF redirect, out-of-band PDF update via aws-cli"
summary="Lodge website: Latchkey managed-website service (latchkey-sites bucket, sites anycast edge, auto-TLS), Manage-files editing, /welcome PDF stub"
categories=["website"]
keywords=["website", "thelonglakelodge.com", "welcome packet", "PDF", "welcome.pdf", "/welcome", "Garage S3", "site-publish", "excludes"] />
keywords=["website", "thelonglakelodge.com", "welcome packet", "PDF", "welcome.pdf", "/welcome", "Latchkey", "managed-website", "Manage files", "custom_domains", "cd-tll0001"] />
</references>
+87
View File
@@ -0,0 +1,87 @@
# Home Assistant
<overview>
HA OS at `home.thelonglakelodge.com`, proxied via fritzlab sjc001 remote-proxy
to `172.24.24.50:8123` (also directly reachable on the lab network). Supervisor
Observer on `:4357` (read-only health, no auth). API token in `~/.env` as
`HA_TOKEN` (long-lived user token — has core API + service calls, but NOT the
`/api/hassio/*` Supervisor proxy → 401). No SSH (`:22` closed, no terminal addon).
No automatic backups configured (`backup/info` → 0 backups).
Local control via WebSocket: `wss://home.thelonglakelodge.com/api/websocket`,
auth with `{"type":"auth","access_token":HA_TOKEN}`. Useful WS cmds:
`config_entries/get`, `config/device_registry/list`, `config/entity_registry/list`,
`matter/node_diagnostics{device_id}`, `lovelace/config{url_path:null}` /
`lovelace/config/save`. Addon control via REST service:
`POST /api/services/hassio/addon_restart {"addon":"core_matter_server"}`.
</overview>
<thermostats>
## Nest thermostats are integrated TWICE
The 8 Nest thermostats appear via two independent paths:
- **Cloud (Google Nest)** — `nest` integration, entities `climate.*_google_nest`
(+ `climate.lodge_basement` = Basement Living Room) and per-zone
`sensor.*_temperature` / `sensor.*_humidity`. Reliable; cloud-dependent.
- **Matter (local)** — `matter` integration via the `core_matter_server` addon,
entities `climate.*_nest`. Local control, but see incident below.
8 zones: Office, Kitchen, Bunkhouse Kitchen (forced-air "HVAC"); Eat-in Kitchen,
Primary Bathroom, Basement Living Room, Basement Bedroom, Tub Room (in-floor heat).
Matter fabric id `1E5211CA4C7B5275`, node ids 15,7,8,9 (temp sensors are bridged
endpoint-101 sub-devices of their thermostat node).
`script.set_away_temperatures` (HVAC 5578 / in-floor 55) and
`script.set_occupied_temperatures` (HVAC 6876 / in-floor 67) set all zones,
targeting by **label**: `hvac` (3 forced-air) and `in_floor_heat` (5 in-floor),
both applied to the cloud `*_google_nest` devices (resolved in-script via
`label_devices(..) | map('device_entities') | ... | select('match','climate')`
since the labels are on devices, not entities). Commands are **serialized one
zone at a time with an 8 s delay** — firing all 8 at once trips the Google Nest
SDM per-user `ExecuteDeviceCommand` rate limit (429 RESOURCE_EXHAUSTED). (Matter copies carry parallel
`matter_hvac` / `matter_in_floor_heat` labels — used by the scripts before the
2026-06-15 repoint to cloud.) `google_nest` labels all 8 cloud devices.
</thermostats>
<matter-outage>
## Matter fabric loss (2026-06-15)
At 2026-06-15 13:53 UTC an HA Core/Supervisor restart (Supervisor → 2026.06.1)
left the `core_matter_server` addon (v8.5.0) with an **empty fabric** — all 11
Matter devices report `node_not_found`, all 59 `climate.*_nest` etc. entities
`unavailable`. Integration reconnects fine (config entry `loaded`); the server
simply has zero nodes. Addon restart + config-entry reload do NOT restore them
(storage lost, not transient), and there is no backup to restore from.
Cloud Nest is unaffected → thermostat control intact via `*_google_nest`.
Recovery = re-commission each thermostat on-site (non-destructive, no factory
reset needed — Nest supports Matter multi-admin):
1. On lodge WiFi, Google Home app (lodge account) → tap thermostat → Settings →
"Linked Matter apps & services" → "Link apps & services" → generate a Matter
setup code (11-digit / QR). Code is single-use, ~5 min TTL.
2. HA → Settings → Devices & Services → Matter → Add device → enter the code.
Wait ~12 min; node appears (bridged temp sensor comes with it).
3. Repeat per thermostat (one code at a time). Rename to match.
4. Delete the stale unavailable Matter devices afterward.
Then re-point dashboard climate tiles back to `climate.*_nest` if local control
is wanted (see dashboard note).
</matter-outage>
<dashboard>
## Main Lovelace (`lovelace` / "Overview", storage mode)
Views: `main` (single grid card, columns:1, headed sections: locks/lights,
Helpful Scripts, Water Sensors, then climate as three 2-col thermostat-card
grids — **Lodge HVAC** (office, kitchen), **In-Floor Heat** (5 in-floor zones),
**Bunkhouse** (bunkhouse kitchen)),
`Environmentals` (history page), and `Lock Management`. Edit via
`lovelace/config` / `lovelace/config/save` (WS).
HVAC climate tiles point at the **cloud** `*_google_nest` entities (repointed
off the dead Matter `*_nest` during the 2026-06-15 outage). The `Environmentals`
page is three per-category vertical-stacks (Lodge HVAC / In-Floor Heat /
Bunkhouse), each with Temperature, Humidity, and Heating/Cooling history-graphs
(72h) scoped to that category's entities.
If Matter is re-commissioned and local control is preferred, repoint these back.
</dashboard>
+30 -39
View File
@@ -1,60 +1,51 @@
# Lodge website
<overview>
Static site `www.thelonglakelodge.com` (apex → 301 → www). Source at
`git@code.fritzlab.net:websites/thelonglakelodge.com.git`. Published via
`action/site-publish@v1`: push to `main``aws s3 sync --delete` to Garage
bucket `thelonglakelodge.com`, ArgoCD reconciles Traefik Ingress + cert.
Static site at `thelonglakelodge.com` (+ `www`, a CNAME to the apex). Hosted
by Latchkey's managed-website service ("Websites" in the app): the files
live in the `latchkey-sites` Garage bucket under the `thelonglakelodge.com/`
key prefix, and the Latchkey `sites` edge serves them over its anycast IPs
with automatic Let's Encrypt TLS. No Traefik, no per-site bucket Ingress.
Registered in `custom_domains` (org "Fritz Family", id `cd-tll0001`).
</overview>
<editing>
## Update the site
In the Latchkey app: **Websites → thelonglakelodge.com → Manage files**
upload (replaces by path), list, delete. Files publish immediately. The
old git repo `~/code/git/code.fritzlab.net/websites/thelonglakelodge.com`
+ `action/site-publish` flow is retired; edits go through the app now (or
the API: `POST /v1/custom-domains/cd-tll0001/files`).
DNS: apex A/AAAA → the sites anycast set (142.202.202.22 / .203.22 /
23.145.176.22 + 2602:817:3000:ed6e::{202,203,176}:22); `www` CNAMEs the
apex. Managed in `dns/authoritative/zone-templates/thelonglakelodge.com.j2`.
</editing>
<welcome-packet>
## Welcome packet PDF (`/welcome`)
`https://www.thelonglakelodge.com/welcome` is a real HTTP 301 redirect to
`/welcome.pdf` (browser renders the PDF in its native viewer). Unlisted, not
in nav.
`/welcome` and `/welcome.pdf` both serve the guest packet. The `/welcome`
shortcut is the empty stub object carrying `x-amz-website-redirect-location:
/welcome.pdf`; the managed-sites server follows that metadata internally
(one hop) and streams the PDF — no browser-visible redirect.
Both objects live in the Garage S3 bucket only, NOT in git:
- `s3://thelonglakelodge.com/welcome` — empty object with
`x-amz-website-redirect-location: /welcome.pdf` and `content-type: text/html`
- `s3://thelonglakelodge.com/welcome.pdf` — the PDF itself
Preserved across site-publish runs via `excludes: [welcome, welcome.pdf]` in
`site.yaml` (the `--exclude` flag was added to `action/site-publish` for this
case).
### Update the packet
One command — change is live immediately, no git/CI involved:
Update the PDF by re-uploading `welcome.pdf` via Websites → Manage files
(or `POST /v1/custom-domains/cd-tll0001/files`). To recreate the `/welcome`
stub if lost:
```sh
aws --profile sjc001 s3 cp /path/to/new.pdf \
s3://thelonglakelodge.com/welcome.pdf \
--content-type application/pdf
aws --profile sjc001 s3api put-object --bucket latchkey-sites \
--key thelonglakelodge.com/welcome --content-type text/html \
--website-redirect-location /welcome.pdf --body /dev/null
```
### Recreate the /welcome redirect (rarely needed)
```sh
aws --profile sjc001 s3api put-object \
--bucket thelonglakelodge.com \
--key welcome \
--website-redirect-location /welcome.pdf \
--content-type text/html
```
The `sjc001` aws-cli profile is documented in fritzlab `garage.md`.
</welcome-packet>
<policy-sync>
## Guest-facing policy lives in two places
Check-out time, quiet hours, occupancy, and local-contact details are stated
both in the welcome PDF and in the quick-ref cards on `site/house-rules.html`.
both in the welcome PDF and in the quick-ref cards on `house-rules.html`.
When updating any of these values, update BOTH or they will drift.
`house-rules.html` no longer contains the full rules accordion; it links to
`/welcome` for the canonical detailed rules. The quick-ref cards remain on the
page as an at-a-glance summary.
</policy-sync>