31 KiB
[hosts/hass.windy.lan.md#8DF6]
hass.windy.lan — Home Assistant (HAOS)
Role and access
| Item | Value |
|---|---|
| Role | Home Assistant automation hub |
| IPv4 | 192.168.55.11 (LAN55) |
| DNS | hass.windy.lan (AdGuard rewrite on dns.windy.lan; legacy hass.local alias) |
| SSH | ssh hassio@hass.windy.lan |
| Host | x88 Pro physical box (HAOS bare-metal, machine: green; verified 2026-08-18) |
| Platform | Home Assistant OS; kernel 6.1.115-haos (aarch64) |
| Web UI | http://hass.windy.lan:8123 (LAN); WAN port-forward hass on gw → :8123 |
Use hassio for routine SSH inspection. Key-only login was verified on
2026-08-13 from the WSL client (BatchMode=yes).
The ha supervisor CLI (/usr/bin/ha) authenticates with SUPERVISOR_TOKEN.
Interactive login works because ~hassio/.zprofile runs exec sudo -i, which
loads a root environment carrying the supervisor API token. Non-interactive
ssh hassio 'command' does not source .zprofile and fails with
unauthorized: missing or invalid API token. Run ha non-interactively via:
ssh -o BatchMode=yes hassio@hass.windy.lan 'sudo -n -i ha core info'
Verified 2026-08-13 that sudo -n -i ha core info works from the WSL client.
Never copy the supervisor token into this repository.
The current SSH ED25519 host-key fingerprint is
SHA256:DMcMOgDzFsFTon1fndXowEP7jlyOK3/AX3PVK8BATvk (verified 2026-08-13).
Verify a changed key out of band before accepting it.
Do not store Home Assistant long-lived tokens, integration credentials, or recovery codes in this repository.
Network
| Interface | Address / role |
|---|---|
end0 |
IPv4 static 192.168.55.11/24 (gw .254, DNS 192.168.66.36); IPv6 SLAAC auto with GUA on the current PD-derived /64 (240e:3bd:235:1fb2:* at 2026-08-22; rotates on PPPoE redial); primary LAN55 NIC (interface name verified live 2026-08-22 — end1 does not exist) |
wlan0 |
Supervisor disabled (verified 2026-08-14, W1N-104); IPv6 remains off on this RTL8821CS radio |
wg0 |
10.13.13.2/32; WireGuard (add-on / integration tunnel) |
hassio / docker0 |
internal HAOS Docker bridges (172.30.32.0/23, 172.30.232.0/23) |
LAN55 clients reach the HTTP API on dns.windy.lan:80 for the AdGuard Home
integration; see hosts/dns.windy.lan.md.
API access
Home Assistant exposes a REST API at http://hass.windy.lan:8123/api/ (same
as http://192.168.55.11:8123/api/). Authenticate with a long-lived access
token created under Profile → Security → Long-lived access tokens.
HA_URL="http://hass.windy.lan:8123"
HA_TOKEN="<long-lived-access-token>"
# Health check — expect {"message":"API running."} and HTTP:200
curl -sS -w "\nHTTP:%{http_code}\n" \
-H "Authorization: Bearer $HA_TOKEN" "$HA_URL/api/"
# Read one entity state
curl -sS -H "Authorization: Bearer $HA_TOKEN" \
"$HA_URL/api/states/sensor.csg_30d_max"
# List entities / recent errors
curl -sS -H "Authorization: Bearer $HA_TOKEN" "$HA_URL/api/states"
curl -sS -H "Authorization: Bearer $HA_TOKEN" "$HA_URL/api/error_log"
401→ token invalid or expired; create a new one.404on/api/states/<id>→ entity does not exist.- The token is a secret: never commit it here; keep it in the shell environment or a secrets file outside the repo.
HTTP proxy gotcha (verified 2026-08-13)
The WSL client had http_proxy set to Mihomo (192.168.66.99:7890). LAN
hostnames sent through that proxy returned empty 502, even though DNS
resolved and the HA UI was up. Direct 192.168.55.11:8123 worked, and
hass.windy.lan:8123 worked only after clearing the HTTP proxy.
Before debugging a "502" on a LAN URL, check env | grep -i proxy and bypass
the proxy:
unset http_proxy HTTP_PROXY all_proxy ALL_PROXY
curl -sS -w "\nHTTP:%{http_code}\n" \
-H "Authorization: Bearer $HA_TOKEN" "$HA_URL/api/"
For a persistent fix, add .windy.lan (leading dot) and the LAN ranges to
NO_PROXY, or add *.windy.lan to the proxy's own bypass/skip-proxy list.
See ~/.config/zsh/env/local/environment.env for the client-side setting.
Safe verification
ssh -o BatchMode=yes hassio@hass.windy.lan 'hostname; ip -4 addr show end0'
From a LAN client, confirm DNS and UI reachability:
getent hosts hass.windy.lan
# expect 192.168.55.11
Local patches (custom components)
Manual custom-component install (this host)
Home Assistant loads custom integrations from
<config>/custom_components/<domain>/ (HAOS: /config ≡ /homeassistant).
A folder named after the integration domain, containing at least
manifest.json and __init__.py, is enough; Core must be restarted after
copying files. Official HA lookup order:
<config>/custom_components/<domain> then built-in
homeassistant/components/<domain>.
See Integration file structure.
This host does not git-clone custom components. The live tree is a file
copy. Do not git pull on HA.
Official plugin path (from windyboy/china_southern_power_grid_stat README): HACS or 手动下载安装. This host uses the latter. Releases here have no uploaded zip assets; use GitHub's Source code (zip) / zipball of the tag.
UI (Samba / File editor / Studio Code Server):
- Download Source code (zip) from the GitHub Release.
- Extract. Copy only the inner
custom_components/china_southern_power_grid_stat/tree — not the repo root, not a nested extra folder. - Place it at
/config/custom_components/china_southern_power_grid_stat/. - Restart Core (Settings → System → Restart).
- First install only: Settings → Devices & services → Add integration.
SSH from the workstation (verified 2026-08-14, W1N-107). Replace v1.3.1
with the tag being installed:
TAG=v1.3.1
STAGE=/tmp/csg-${TAG}-deploy
mkdir -p "$STAGE"
gh api "repos/windyboy/china_southern_power_grid_stat/zipball/${TAG}" \
> "$STAGE/src.zip"
unzip -q "$STAGE/src.zip" -d "$STAGE"
SRC=$(find "$STAGE" -type d -path '*/custom_components/china_southern_power_grid_stat' | head -1)
# expect .../custom_components/china_southern_power_grid_stat
ssh -o BatchMode=yes hassio@hass.windy.lan \
'sudo -n -i mkdir -p /homeassistant/.csg-backups &&
sudo -n -i cp -a /homeassistant/custom_components/china_southern_power_grid_stat \
/homeassistant/.csg-backups/china_southern_power_grid_stat.bak-$(date +%Y%m%d)-manual'
rsync -a --delete \
-e 'ssh -o BatchMode=yes' \
"$SRC/" \
hassio@hass.windy.lan:/homeassistant/custom_components/china_southern_power_grid_stat/
# --delete cannot remove Core-owned __pycache__; wipe as root, then restart
ssh -o BatchMode=yes hassio@hass.windy.lan \
'sudo -n -i rm -rf /homeassistant/custom_components/china_southern_power_grid_stat/__pycache__ \
/homeassistant/custom_components/china_southern_power_grid_stat/*/__pycache__ &&
sudo -n -i ha core restart'
Wait until Core is up (ha core info returns, typically 1–2 min; this CLI
build does not print a state: field).
Then:
ssh -o BatchMode=yes hassio@hass.windy.lan \
'sudo -n -i cat /homeassistant/custom_components/china_southern_power_grid_stat/manifest.json'
# version must match the tag
ssh -o BatchMode=yes hassio@hass.windy.lan \
'sudo -n -i ha core logs -n 2500' | grep -E 'china_southern_power_grid_stat|cannot pickle' || true
Host constraints (do not skip):
- Backups must live in
/homeassistant/.csg-backups/. A*.bak-*directory next to the live folder is scanned as the same domain and Core fails withNo module named '...bak-YYYYMMDD-...'. - Do not install this fork via HACS on this host. HACS still tracks
CubicPill/china_southern_power_grid_statv1.2.0; a HACS update would overwrite the live copy. - First poll after restart can time out to CSG over IPv4; if this-month
sensors stay
unknownwhile last-month filled, reload the config entry (UI: integration → Reload, or supervisorPOST /core/api/config/config_entries/entry/<id>/reload). runbooks/scripts/ha-maintenance.sh --restart-core --yescan print nothing and exit 1 in under a second without restarting Core. The wrapper's ssh line discards stderr (2>/dev/null); withpipefail, an ssh failure yields empty stdout + exit 1 before any remote command runs. Do not treat that as a completed restart. Confirm with elapsed time (~2 min for a real restart) andha core info. Preferssh -o BatchMode=yes hassio@hass.windy.lan 'sudo -n -i ha core restart'.
Full command family: runbooks/home-assistant-maintenance.md.
china_southern_power_grid_stat live tree
v1.3.2 (934f58c, verified 2026-08-15, W1N-118): manual zipball of
GitHub release
v1.3.2
copied to /config/custom_components/china_southern_power_grid_stat.
Earlier trees: v1.3.1/55a293fc (W1N-107), v1.3.0/69f13c90 (W1N-106),
a433e8c (W1N-105), de01914 (W1N-103), eb8b174 (W1N-102). Backups:
/homeassistant/.csg-backups/ (w1n102/104/105/106/107/118).
v1.3.0 crashed the coordinator on first refresh
(TypeError: cannot pickle 'mappingproxy' object in
copy.deepcopy(self._config) under Python 3.14 / HA 2026.8.1). v1.3.1
wraps those deepcopy calls with dict(...). Post-restart 22:13 CST:
entry loaded, no pickle traceback. Native this-month sensors filled after
reloading entry 01KGCQDSZCF523A9X6SV3BZ1B9 (ip_family: ipv4). Native
cost/ladder sensors can stay unknown because CSG
get_month_daily_cost_detail returns a marketing-system SQL error; the
dashboard uses template ladder/cost entities instead. Do not change
templates/csg_sensors.yaml or the 电力监控 dashboard for an install.
templates/csg_sensors.yaml hardened 2026-08-29 (W1N-239): added
availability templates to all 12 csg_* sensors (numeric sensors can't
render unknown/unavailable in state; availability suppresses
rendering instead — native CSG down ⇒ derived sensors show unavailable,
no more fake zeros / "一档" / 0%). csg_yesterday_kwh now falls back to
last_month_by_day's last entry when this_month_by_day is empty (month
start); ladder constants (t1/t2/p1/p2/p3) deduped into per-block
variables: (Block B + Block D); csg_mom_change parses date
defensively. Backup:
/homeassistant/.csg-backups/csg_sensors.yaml.bak-20260829-w1n239.
Verified: ha core check OK; Core restart required (trigger-based
template blocks don't settle on template.reload — W1N-114 precedent);
post-restart all 12 entities numeric & consistent (302.47 kWh→180.28 元,
324.03 kWh→194.06 元, mom_change -3.6%, yesterday 7.66 kWh/2026-08-28),
no template errors in Core logs.
csg_sensors.yaml off-by-one fixed 2026-08-29 (W1N-241): CSG data
lags 1 day (sum(this_month_by_day) == this_month_total_usage, data
stops at yesterday), but templates used now().day as "days elapsed" →
csg_predicted_usage underestimated ~1 daily avg (~3%) and
csg_mom_change compared this-month 28 days vs last-month 29 days
(-3.6% vs true -0.3%). Both now derive the day number from
this_month_by_day[-1].date (fallback now().day when empty). Added
sensor.csg_this_month_daily_avg (month-to-date avg, 302.47/28=10.8) and
sensor.csg_prediction_progress (usage/predicted %, 90.3) in Block C
(trigger adds csg_predicted_usage). Backup:
/homeassistant/.csg-backups/csg_sensors.yaml.bak-20260829-w1n241.
Verified (8/29): predicted 324.03→334.81, mom_change -3.6→-0.3,
daily_avg 10.8, progress 90.3, predicted_cost 194.06→200.94 (334.81 kWh
ladder), ladder cost 180.28 unchanged, ha core check OK after restart,
no template errors; 14 csg_* entities total.
电力监控面板(lovelace.dashboard_unknown / view power-monitor)
updated 2026-08-29 (W1N-240 + W1N-242): 「本月累计」gauge 对齐夏季阶梯:
max:650、segments 0/260/600(绿/橙/红 = 一/二/三档;冬季 11-01 需切
max:450、0/200/400 — seasonal switch point,见下文)。「📊 统计
数据」卡新增本年/去年 4 行(原生传感器,口径标注「电费(账单)」、本年
「(至今)」)+ 本月日均/预测进度 2 行(csg_this_month_daily_avg /
csg_prediction_progress,W1N-242);面板共引用 20 个实体。改前备份:
/homeassistant/.lovelace-backups/dashboard-unknown-power-monitor-20260829-204845.json
(W1N-240)、-20260829-210708.json(W1N-242)
(改法:WS lovelace/config/save,参数 url_path: dashboard-unknown +
config;勿直改 .storage/)。验证:WS 读回 18→20 实体 diff ✓、gauge
配置一致 ✓、URL http://hass.windy.lan:8123/dashboard-unknown/power-monitor。
csg_sensors.yaml W1N-242: csg_predicted_usage /
csg_mom_change / csg_this_month_daily_avg 三处取 days[-1] 前补
sort(attribute='date')(与 csg_yesterday_kwh 一致,防上游乱序取错
数据日)。备份 csg_sensors.yaml.bak-20260829-w1n242。验证:Core
restart 后回归值不变(334.81 / -0.3 / 10.8 / 90.3 / 200.94 / 180.28)。
Seasonal gauge switch (W1N-240 已知事项): 每年 11-01 把
power-monitor视图「本月累计」gauge 切到冬季max:450/0/200/400,5-01 切回夏季max:650/0/260/600(与模板now().month季节逻辑对齐;模板常量在 Block B/Dvariables)。
Home PPPoE IPv4 to CSG is still blackholed (curl -4 to 218.19.148.218:443
times out). end0 IPv6 is enabled (ipv6.method: auto); from HA,
curl -6 https://95598.csg.cn returns HTTP 200 via 240e:f9:8060::1:16.
tianqi weather recorder patch (verified 2026-08-13, W1N-75):
/config/custom_components/tianqi/weather.py has a local patch adding
_unrecorded_attributes = frozenset({"hourly_temperature", "hourly_skycon", "hourly_cloudrate", "hourly_precipitation"}) to the WeatherEntity class.
Without it, weather.guangzhou's state attributes (~19 KB, dominated by the 4
hourly_* arrays of up to 48 entries) exceed the recorder 16384-byte limit, so
the recorder drops all attributes for the entity and logs
Recorder.db_schema: State attributes for weather.guangzhou exceed maximum size of 16384 bytes. The patch excludes only the 4 arrays from recording
(live state unchanged; other attributes still stored; ~6.3 KB payload). Backup
at weather.py.bak-w1n75. Re-apply after any tianqi component update.
The _unrecorded_attributes mechanism exists in Core 2026.8.1
(Entity.__init_subclass__ → state_info["unrecorded_attributes"], consumed
by recorder shared_attrs_bytes_from_event).
matrix_e2ee live tree (E2E Matrix bot, verified 2026-08-20)
v0.3.12 (tag v0.3.12; feat — Matrix activity events
matrix_e2ee_message_received / matrix_e2ee_verification_done + push
diagnostics; v0.3.9 added Connection health binary sensor, SAS/command
allowlist split, URL normalization, single-entry enforcement):
source copy from /home/windy/project/ha-matrix-e2ee ea421ed (tag
v0.3.12) deployed 2026-08-20 via SSH rsync from workstation (upgraded
from v0.3.2, backup matrix_e2ee.bak-20260820-v0.3.2).
Custom matrix_e2ee integration — Config Flow (UI). See
docs/home-assistant-matrix.md.
Update runbook: runbooks/matrix-e2ee-update.md.
Earlier: v0.3.2 (tag v0.3.2, W1N-182/#34: wizard waits for inbound SAS
emojis) deployed 2026-08-18 from d35c484 (backup
matrix_e2ee.bak-20260818-v0.3.1); v0.3.1 (GitHub #33: peer-initiated
verification wizard fix) deployed 2026-08-18 from d22e935 (backup
matrix_e2ee.bak-20260818-v0.3.0); v0.3.0 (W1N-180/#32: bot-initiated
verification wizard; W1N-179/#31 receive_mac_event cancel-state fix)
deployed 2026-08-18 from 216cc99 (backup
matrix_e2ee.bak-20260818-v0.2.10).
- Bot
@hass:chans.xyzreused (E2EE devicerO1R915ncu). Config Entry01M04D7C1M4T2GX5VPG7NVQ7GV(source: import,state: loaded). All settings via Settings → Devices & Services → Matrix E2EE → Configure. - Config Entry options:
allowed_rooms["!gidvAzpDzwtzfEDrqu:chans.xyz", "!boxfylDSzOvrWkcsyY:chans.xyz"],allowed_users["@zhiqiang:chans.xyz"],command_prefix"!".verification_peer_usersnot set (v0.3.9+ SAS allowlist split fromallowed_users, W1N-156): defaults to empty → only the bot's own account may drive SAS;@zhiqiangis denied until the option is added via Settings → Devices & Services → Matrix E2EE → Configure. - Storage:
/config/.storage/matrix_e2ee_session.json+/config/.storage/matrix_e2ee_store/. Backups:/homeassistant/.matrix-e2ee-backups/(incl.matrix_e2ee.bak-20260820-v0.3.2,matrix_e2ee.bak-20260818-v0.3.1,matrix_e2ee.bak-20260818-v0.3.0,matrix_e2ee.bak-20260818-v0.2.10,matrix_e2ee.bak-20260816-v0.2.9,matrix_e2ee.bak-20260816-v0.2.8); full HA backup slugs3d9d36db(pre-v0.1.4) +9f223f35(pre-v0.2.0). - v0.3.12: Matrix activity events + push diagnostics
(
matrix_e2ee_message_received/matrix_e2ee_verification_done). v0.3.9: Connection health binary sensor (W1N-185/#40), config-entry diagnostics (W1N-184/#39), SAS/command allowlist splitverification_peer_users(W1N-156/#41), SAS/sync logs demoted warning→info/debug (W1N-188/#38), URL normalization + single-entry enforcement (W1N-190/#42). v0.3.8:m.key.verification.donehandshake for request-based SAS (W1N-183/#35). v0.3.2: wizard waits for inbound SAS emojis before the compare step (W1N-182/#34). v0.3.1: verification wizard waits for a peer-initiated inbound SAS instead of the bot starting SAS (GitHub #33). v0.3.0: bot-initiated device verification wizard (W1N-180/#32). v0.2.11:receive_mac_eventno longer overrides canceled state (W1N-179/#31). - v0.2.9: restore SAS emoji rendering after vodozemac migration (W1N-175/#29).
v0.2.8: SAS commitment unpadded base64 for Element interop (W1N-174/#28).
v0.2.7: SAS cancel code/reason logging. v0.2.6: verification state logging +
request→ready bridge. v0.2.4:
_patch_nio_sas_timeout()+_repair_dropped_start();VERIFICATION_TIMEOUT_SECONDS600→240. - Automation
1761188403590「Matrix 聊天关卫生间灯」: triggermatrix_e2ee_command(command关卫生间灯), actionslight.turn_off+matrix_e2ee.send_message(room!gidvAzpDzwtzfEDrqu). - SAS not yet completed: every device requires explicit
confirm_verification. Encrypted-room commands stay fail-closed until@zhiqiang's device is verified. Since v0.3.9 the SAS driver gate usesverification_peer_users(empty on this host) instead ofallowed_users— add@zhiqiang:chans.xyzthere before retrying the wizard. Three paths available: SAS manual confirm, fingerprint, or the device verification wizard (v0.3.0 bot-initiated, reworked in v0.3.1/v0.3.2 to wait for a peer-initiated inbound SAS from Element with emoji comparison), see docs/home-assistant-matrix.md § Device verification.
Scribe long-term history (verified 2026-08-29)
- Scribe 3.8.0 (
/homeassistant/custom_components/scribe/), configured from/homeassistant/scribe.yaml— W1N-238 moved the block out ofconfiguration.yamlon 2026-08-29 (main config now carriesscribe: !include scribe.yaml; content moved verbatim; backupconfiguration.yaml.bak-20260829-201724-w1n238). Config entry01KC2VFJWEQ3XDHY6TQKHPDVRB,source: import— UI "Configure → Advanced" edits are overridden by the YAML on restart; treat YAML as authoritative. - TimescaleDB at
192.168.55.15:5432/scribe(DB userhass; host in inventory, see hosts/pgdb.md). Database re-initialized 2026-08-29 14:06 CST (user-handled; earlierrelation "entities" does not existerrors resolved). Health:binary_sensor.scribe_database_connection. - 2026-08-29 config applied (backup
/homeassistant/configuration.yaml.bak-20260829-scribe):record_events: truewithinclude_eventswhitelist:automation_triggered,matrix_e2ee_command,matrix_e2ee_message_received,matrix_e2ee_verification_done,script_started,tag_scanned,mobile_app_notification_action,homeassistant_start,homeassistant_stop.- State noise trimmed:
exclude_domainsupdate/button; globsensor.zigbee2mqtt_bridge_*; 4 hassio cpu/mem-percent entities. - Global
exclude_attributesdrops tianqihourly_*arrays (~19 KB/state — the recorder-side_unrecorded_attributespatch does not apply to Scribe). enable_stats_io+enable_stats_sizeon → 14sensor.scribe_*stats entities (scribe_states_written,scribe_events_written, rates, sizes).- Verified post-restart 14:23 CST: writer started,
scribe_events_written=1(homeassistant_start), states ~110/min, buffer 3, no scribe log errors.
- Scribe 3.8.0 has no retention option. Retention ships only in the v4.x line, which as of 2026-08-29 has no stable release (v4.0.0rc1/v4.1.0rc1 are prereleases; user declined RCs — data keeps growing until an upgrade). v4.x is a major rewrite (writer.py largely rewritten, migration.py removed, TimescaleDB extension required): re-read release notes before upgrading. Do not expect retention YAML keys to validate on 3.8.0.
- Recorder stays external-Postgres with
purge_keep_days: 30for daily UI history; Scribe is the permanent archive.
Config layout: scribe.yaml + templates/ merge (W1N-238, verified 2026-08-29)
configuration.yamlline 29:scribe: !include scribe.yaml; line 9:template: !include_dir_merge_list templates. Nopackages/.scribe.yaml(config root): the Scribe block, content identical to the former inline one; import semantics unchanged.templates/:csg_sensors.yaml(12 template sensors, top-level list)quick_sensors.yaml(scaffold for Quick-derivedquick_*sensors, empty list with convention header).!include_dir_merge_listmerges per-file lists; non-list files are silently skipped — every file intemplates/must be a top-level list (- sensor:blocks). Directory include only picks up*.yaml, so the.bak/.pre-*backups in the dir are ignored. After adding sensors, verify template-platform entity count = 12 + N (entity registryplatform: template).
- Convention (per review + W1N-233): pure sums/averages stay min_max helpers
(e.g.
sensor.dang_qian_zong_gong_lu); only template-logic derivations (ladder pricing, cross-entity conditions) go intoquick_sensors.yaml. - Post-change verification 20:19 CST:
ha core checkok, 92 s restart (2026.8.3),binary_sensor.scribe_database_connectionon,scribe_states_written18581→19426 growing, template entities still 12, csg sensors numeric, no scribe/template log errors.
Timescale Plotly card + database reader (verified 2026-08-29)
Chart stack over the Scribe TimescaleDB archive. Upstream pair (no HACS;
manual copies): reader remmob/timescale_database_reader v1.1.0 (main
bb8776a) + card remmob/timescale-plotly-card 2.2.0 (main 217961d).
- Reader integration:
/homeassistant/custom_components/timescale_database_reader/. Config entry01M165P77QT1FQEAVPNZHDT82W("Scribe",source: user): connectshass@192.168.55.15:5432/scribe(credentials =secrets.yamlscribe_url),table: sensor_minute. Exposes no entities/services — it serves WS commandtimescale/query(window ≤ 365 d, ≤ 50 000 rows,downsamplebucket seconds). Benign startup warningError executing test query: column "time" does not exist: the self-test SQL assumes the LTSS column name; the scribe table usesminute— real queries work (verified: 70 rows for a live power sensor). - Card:
/homeassistant/www/community/timescale-plotly-card/timescale-plotly-card.js(root-owned, same convention as HACS dirs). Lovelace resource (storage) id2e360d17b5aa4ce59c2fd13c43b51215→/hacsfiles/timescale-plotly-card/timescale-plotly-card.js, typemodule. Card config matches the entry bydatabase: scribe(name from the reader entry). Updates: replace the file, resource URL unchanged — browsers need a hard refresh or a bumped?v=query on the resource URL. - pgdb side (
sensor_minute_aggregatecagg +sensor_minutehypertable + every-minute refresh job): see hosts/pgdb.md § Databases. - Agent-side HA WebSocket without a long-lived token (verified 2026-08-29):
connect
ws://supervisor/core/websocketwith headerAuthorization: Bearer $SUPERVISOR_TOKEN, then send{"type":"auth","access_token":"$SUPERVISOR_TOKEN"}— the Supervisor proxy swaps it for a core token (works as the internal Supervisor admin user). Notelovelace/resources/createin HA 2026.8 takesres_type(NOTresource_type). - Scribe stores numeric sensor values in
states_raw.valuewithstateNULL, sosensor_minute.stateshows'0'for numeric sensors; the card plotsavg_state(fromvalue) — expected, not a bug. - Quick 仪表盘(
dashboard-quick)图表套件(2026-08-29 创建,经 WSlovelace/config/save写入;W1N-230 修复 + W1N-231 round-2 改进): 5 张 timescale 卡——大功率电器/常驻负载功率(按量级拆图,避免尖峰压扁 <70 W 基线)、按插座用电量(energy_mode+ cumulative/diff,数据质量前提 见 pgdb 的 refresh 过程补丁)、室内外温湿度(温度左轴/湿度右轴,4 位置同色 配对)、人体感应活动状态(3 个motion_state,bandedstate_mapnone/small/medium/large → 0-11,per-entityline_color红/蓝/绿)。 空调实体引用为kong_diao_*(kong_tiao是笔误,W1N-230 修复;grep -c kong_tiao应为 0)。灯区:2×2 嵌套 grid(grid_options: {columns: "full"}, 内层columns: 2)+ 4 卡统一mushroom-light-card(显式 name、use_light_color: false、内联亮度/色温控制),heading iconmdi:lightbulb-group。heading badges:环境 4 温度(迷你/mini数显/数显/广州)、 大功率电器 空调/电脑当前功率、常驻负载 总功率 (sensor.dang_qian_zong_gong_lu,min_max sum helper,round_digits: 0, 任一源掉线 fail-closed → unknown)。常驻负载图卡级fill: 'tozeroy'+ 冰箱/主网络 per-entityfill_color(线色 20% 透明)+ 其余 5 条fill: false(per-entity fill 逐系列退出,卡 JSseriesConfig.fill !== false)。 布局:视图type: sections+max_columns: 4;灯/用电/环境/人体感应column_span: 4,功率两图拆两个column_span: 2分区并排(等高 280px, 桌面并排、手机回落堆叠;去卡内 title 省半宽图垂直空间)。 分区/卡片是两套尺寸键,不可混用:分区宽 =column_span(hui-sections-view.ts缺省按 1 列渲染,绝不省略);卡片宽 =grid_options: {columns: <n|"full">}(hui-card.ts只读config.grid_options, 写在卡片上的column_span被静默忽略;缺省 12 列,分区内格 = 12 × 分区 span,故 span-4 分区里缺省卡片只有 1/4 宽)。 修改前备份:/homeassistant/.lovelace-backups/dashboard-quick-*.json(W1N-230 修复:20260829-190256;round-2 改进:20260829-194040)。
Known issues
Bluetooth hci0 instability — RTL8821CS (verified 2026-08-13, W1N-74):
The local Bluetooth controller hci0 is an RTL8821CS combo chip on the
x88 Pro board. Kernel logs show recurring hci0: hardware error 0x00,
Opcode 0x200c tx timeout (HCI_LE_Set_Scan_Parameters), Unable to disable scanning: -110, Peer device has reset — the chip hardware-stalls during
active scanning. HA's bluetooth_auto_recovery power-cycle then times out
after 5 s and retries every ~2 min:
bluetooth_auto_recovery.recover: Could not reset the power state of the Bluetooth adapter hci0 ... due to timeout after 5 seconds. The HAOS image
already ships custom systemd units to cope (x88-bt-hci-recovery.service and
a "Patch HA Bluetooth scanner mode for x88 RTL8821CS" service, visible in host
journal). No user impact: there are no BLE entities in HA
(xiaomi_ble / bthome / led_ble / bluetooth / esphome domains are all empty;
platforms merely load from stray advertisements). Real IoT devices are Zigbee
(via Zigbee2MQTT) or WiFi/MQTT/cloud. An ESPHome Bluetooth-proxy ESP32
(/config/esphome/bluetooth.yaml, bluetooth_proxy: active, WiFi ubnt-haas)
is configured but currently offline (ESPHome add-on stopped, port 6053
unreachable) and produced no entities. Follow-up (optional): disable the
local adapter and rely on the ESPHome proxy, or stop the bluetooth
integration entirely.
eMMC disk lifetime 10% (verified 2026-08-13, W1N-76): ha host info
reports disk_life_time: 10 — the boot eMMC (/dev/mmcblk2, CJTD4R
0xacacc064, 64 GB) has ~10% life left. disk_free: 40.2/56.4 GB. Full
backup pre-maintenance-20260813 (slug 411a4ba5, 144.26 MB) taken
2026-08-13 covers current config; monitor disk_life_time on each health
snapshot and plan a disk replacement / data-disk migration before the eMMC
fails.
Matter Server (verified 2026-08-21)
- Add-on
core_matter_server(homeassistant/aarch64-addon-matter-server) runs the Matter commissioner on this host (host networking; add-on containerapp_core_matter_server). - After the ISP PD prefix rotates (PPPoE redial), the add-on can cache a stale IPv6 GUA
in its mDNS advertisement — clients trying that dead address make Matter
commissioning/connection fail. Fix: restart the add-on so it re-enumerates addresses:
ssh hassio@hass.windy.lan 'sudo -n -i ha apps restart core_matter_server'(ha addons restart ...also works; "addons" is deprecated in favor of "apps"). - Verified 2026-08-21 (W1N-207): stale
240e:3bd:234:2f22:*AAAA in mDNS removed by restart; advertisement now carries only current GUA240e:3bd:235:1fb2:*+ link-local; CASE sessions with Aqara M3 / SmartThings hubs resumed over IPv6 link-local.
Open items (2026-08-21, W1N-207): a phone on LAN55 was querying five known
_matter._tcpinstances of which only HA answered — the other Matter nodes are offline / not announcing (device-side; user to confirm power/Wi-Fi). HA's IPv6 default route via NetworkManager was observed missing once (curl -6 intermittent, while ping6 andcurl -6 --noproxywork) — not the Matter root cause; re-check on the next health snapshot.
Verified 2026-08-23 (read-only, W1N-207): add-on started, version 9.0.4, no
update pending; current GUA 240e:3bd:238:4812:* (PD rotated again since 08-22)
advertised correctly over v4+v6. Both ESP32-C2 bulbs now announce _matter._tcp
(multi-fabric, including this host's fabric DCE86145C137AF0E) — but they
refuse TCP 5540 on IPv4 and IPv6, so matter-server holds zero established
:5540 sessions (device-side failure mode C; no errors logged — see
docs/matter-pairing-troubleshoot.md §8).
Related docs
- runbooks/home-assistant-maintenance.md —
haCLI maintenance runbook + script; custom-component zip install is §7 - docs/lan-overview.md — LAN map and gw port-forward
- hosts/dns.windy.lan.md —
hass.windy.lan/hass.localrewrites