2026-08-14 22:31:31 +08:00
[hosts/hass.windy.lan.md#8DF6 ]
2026-08-13 14:10:39 +08:00
# 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` |
2026-08-18 13:29:25 +08:00
| **Host** | **x88 Pro physical box** (HAOS bare-metal, `machine: green` ; verified 2026-08-18) |
2026-08-13 14:10:39 +08:00
| 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 17:54:33 +08:00
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:
```bash
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.
2026-08-13 14:10:39 +08:00
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 |
|---|---|
2026-08-22 10:14:29 +08:00
| `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) |
2026-08-14 16:11:03 +08:00
| `wlan0` | Supervisor **disabled** (verified 2026-08-14, W1N-104); IPv6 remains off on this RTL8821CS radio |
2026-08-13 14:10:39 +08:00
| `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 ](dns.windy.lan.md ).
2026-08-13 17:20:49 +08:00
## 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** .
```bash
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.
- `404` on `/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:
```bash
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.
2026-08-13 14:10:39 +08:00
## Safe verification
```bash
2026-08-22 10:14:29 +08:00
ssh -o BatchMode = yes hassio@hass.windy.lan 'hostname; ip -4 addr show end0'
2026-08-13 14:10:39 +08:00
```
From a LAN client, confirm DNS and UI reachability:
```bash
getent hosts hass.windy.lan
# expect 192.168.55.11
```
2026-08-13 19:48:18 +08:00
## Local patches (custom components)
2026-08-16 20:34:38 +08:00
2026-08-14 22:31:31 +08:00
### 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 ](https://developers.home-assistant.io/docs/creating_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 ](https://github.com/windyboy/china_southern_power_grid_stat )):
HACS **or** [手动下载安装 ](https://github.com/windyboy/china_southern_power_grid_stat/releases ).
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):**
1. Download Source code (zip) from the GitHub Release.
2. Extract. Copy only the inner
`custom_components/china_southern_power_grid_stat/` tree — not the repo
root, not a nested extra folder.
3. Place it at `/config/custom_components/china_southern_power_grid_stat/` .
4. Restart Core (**Settings → System → Restart**).
5. 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:
```bash
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:
```bash
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 with `No module named '...bak-YYYYMMDD-...'` .
- Do not install this fork via HACS on this host. HACS still tracks
`CubicPill/china_southern_power_grid_stat` `v1.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 `unknown` while last-month filled, reload the config entry
(UI: integration → Reload, or supervisor
`POST /core/api/config/config_entries/entry/<id>/reload` ).
- `runbooks/scripts/ha-maintenance.sh --restart-core --yes` can print
nothing and exit 1 in under a second **without restarting Core** . The
wrapper's ssh line discards stderr (`2>/dev/null` ); with `pipefail` ,
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) and `ha core info` . Prefer
`ssh -o BatchMode=yes hassio@hass.windy.lan 'sudo -n -i ha core restart'` .
Full command family: [runbooks/home-assistant-maintenance.md ](../runbooks/home-assistant-maintenance.md ).
### `china_southern_power_grid_stat` live tree
2026-08-18 13:29:25 +08:00
**v1.3.2** (`934f58c` , verified 2026-08-15, W1N-118): manual zipball of
2026-08-14 22:31:31 +08:00
GitHub release
2026-08-18 13:29:25 +08:00
[v1.3.2 ](https://github.com/windyboy/china_southern_power_grid_stat/releases/tag/v1.3.2 )
2026-08-14 22:31:31 +08:00
copied to `/config/custom_components/china_southern_power_grid_stat` .
2026-08-18 13:29:25 +08:00
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).
2026-08-14 22:31:31 +08:00
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.
2026-08-14 15:47:08 +08:00
2026-08-14 16:11:03 +08:00
Home PPPoE IPv4 to CSG is still blackholed (`curl -4` to `218.19.148.218:443`
2026-08-22 10:14:29 +08:00
times out). `end0` IPv6 is enabled (`ipv6.method: auto` ); from HA,
2026-08-14 16:11:03 +08:00
`curl -6 https://95598.csg.cn` returns HTTP 200 via `240e:f9:8060::1:16` .
2026-08-14 15:47:08 +08:00
2026-08-13 19:48:18 +08:00
** `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` ).
2026-08-16 20:34:38 +08:00
2026-08-21 08:56:26 +08:00
### `matrix_e2ee` live tree (E2E Matrix bot, verified 2026-08-20)
2026-08-16 20:34:38 +08:00
2026-08-21 08:56:26 +08:00
**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` ).
2026-08-18 13:29:25 +08:00
Custom ** `matrix_e2ee` ** integration — **Config Flow** (UI). See
[docs/home-assistant-matrix.md ](../docs/home-assistant-matrix.md ).
**Update runbook:** [runbooks/matrix-e2ee-update.md ](../runbooks/matrix-e2ee-update.md ).
2026-08-16 20:34:38 +08:00
2026-08-21 08:56:26 +08:00
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` ).
2026-08-18 13:29:25 +08:00
- Bot `@hass:chans.xyz` reused (E2EE device `rO1R915ncu` ). Config Entry
`01M04D7C1M4T2GX5VPG7NVQ7GV` (`source: import` , `state: loaded` ). All
settings via **Settings → Devices & Services → Matrix E2EE → Configure** .
2026-08-16 20:34:38 +08:00
- Config Entry options: `allowed_rooms` `["!gidvAzpDzwtzfEDrqu:chans.xyz", "!boxfylDSzOvrWkcsyY:chans.xyz"]` ,
`allowed_users` `["@zhiqiang:chans.xyz"]` , `command_prefix` `"!"` .
2026-08-21 08:56:26 +08:00
** `verification_peer_users` not set** (v0.3.9+ SAS allowlist split from
`allowed_users` , W1N-156): defaults to empty → only the bot's own account
may drive SAS; `@zhiqiang` is denied until the option is added via
Settings → Devices & Services → Matrix E2EE → Configure.
2026-08-18 13:29:25 +08:00
- Storage: `/config/.storage/matrix_e2ee_session.json` +
`/config/.storage/matrix_e2ee_store/` . Backups:
2026-08-21 08:56:26 +08:00
`/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` ,
2026-08-18 13:29:25 +08:00
`matrix_e2ee.bak-20260816-v0.2.9` , `matrix_e2ee.bak-20260816-v0.2.8` );
2026-08-16 20:34:38 +08:00
full HA backup slugs `3d9d36db` (pre-v0.1.4) + `9f223f35` (pre-v0.2.0).
2026-08-21 08:56:26 +08:00
- 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 split
`verification_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.done` handshake 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 ).
2026-08-18 13:29:25 +08:00
v0.2.11: `receive_mac_event` no 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_SECONDS` 600→240.
- Automation `1761188403590` 「Matrix 聊天关卫生间灯」: trigger
`matrix_e2ee_command` (command `关卫生间灯` ), actions `light.turn_off` +
`matrix_e2ee.send_message` (room `!gidvAzpDzwtzfEDrqu` ).
2026-08-16 20:34:38 +08:00
- **SAS not yet completed:** every device requires explicit `confirm_verification` .
Encrypted-room commands stay fail-closed until `@zhiqiang` 's device is verified.
2026-08-21 08:56:26 +08:00
Since v0.3.9 the SAS driver gate uses `verification_peer_users` (empty on
this host) instead of `allowed_users` — add `@zhiqiang:chans.xyz` there
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
2026-08-16 20:34:38 +08:00
[docs/home-assistant-matrix.md § Device verification ](../docs/home-assistant-matrix.md ).
2026-08-13 19:48:18 +08:00
## 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.
2026-08-21 08:56:26 +08:00
## 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 container `app_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 GUA `240e: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._tcp` instances 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 and `curl -6 --noproxy` work) — not the Matter root cause; re-check
> on the next health snapshot.
2026-08-23 11:06:35 +08:00
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 ](../docs/matter-pairing-troubleshoot.md )).
2026-08-13 14:10:39 +08:00
## Related docs
2026-08-14 22:31:31 +08:00
- [runbooks/home-assistant-maintenance.md ](../runbooks/home-assistant-maintenance.md ) — `ha` CLI maintenance runbook + [script ](../runbooks/scripts/ha-maintenance.sh ); custom-component zip install is §7
2026-08-13 14:10:39 +08:00
- [docs/lan-overview.md ](../docs/lan-overview.md ) — LAN map and gw port-forward
2026-08-14 22:31:31 +08:00
- [hosts/dns.windy.lan.md ](dns.windy.lan.md ) — `hass.windy.lan` / `hass.local` rewrites