diff --git a/.claude-context/sessions/2026-05-18-opnsense-alias-dashboard.md b/.claude-context/sessions/2026-05-18-opnsense-alias-dashboard.md new file mode 100644 index 0000000..29558c3 --- /dev/null +++ b/.claude-context/sessions/2026-05-18-opnsense-alias-dashboard.md @@ -0,0 +1,47 @@ +# Parental Controls Dashboard with OPNsense Alias Blocking + +**Date:** 2026-05-18 +**Project:** ha-parental-controls +**Status:** resolved +**Tags:** home-assistant, opnsense, firewall-alias, dhcp, websocket, rest_command, input_text, dashboard + +## Context +Jess wanted a Home Assistant panel to block and unblock internet access per child and per device, backed by the OPNsense firewall, with optional scheduled access windows. The first version (2026-05-10) worked in principle but hit a series of problems over the following week: WebSocket timeouts on load, broken HA auth handshake, config too large for a single `input_text`, OPNsense rejecting alias updates, and tablets needing credentials entered on every device. + +## Key Decisions +- **OPNsense firewall alias (`parental_blocked`) + one LAN block rule** — HA only adds/removes IPs from the alias; no per-device firewall rules to manage. +- **Identify devices by MAC, resolve to current IP at block time** — blocks re-apply automatically when a device reconnects with a new IP. +- **Standalone HTML panel (`panel_iframe`) instead of Lovelace cards** — the UI (users, devices, toggles, schedules) is too interactive for core cards. +- **Device discovery/status from an OPNsense DHCP lease REST sensor** rather than `device_tracker` entities alone — gives hostnames, addresses and expiry in one place. +- **Config persisted in HA, chunked across 12 `input_text` entities (12 × 255 = 3060 chars)** — a single `input_text` with max 10000 is invalid (HA caps at 255), and HA storage means config is shared across devices, unlike localStorage. +- **REST API for initial state load, WebSocket for live updates** — loading all states over WS timed out; WS timeout raised to 60s. +- **OPNsense `alias_util` calls use a JSON payload** — the API rejects form-encoded bodies. +- **Auto-detect HA URL from `window.location.origin`** — works over HTTP, HTTPS, LAN IP or domain without configuration. +- **Optional token in a `CONFIG` block in the HTML** so the panel works on every device without per-device setup. Trade-off: this contradicts the project principle of no hardcoded credentials — the repo copy must stay blank (`CONFIG_HA_TOKEN = ''`), and the token is only filled in on the HA host's copy. + +## Technical Details +- Files: `packages/parental_controls.yaml` (rest_commands, scripts, sensors, `input_text` chunks, optional schedule automation), `www/parental_controls.html` (panel), `secrets_example.yaml`. +- Secrets used: `opnsense_alias_add_url`, `opnsense_alias_del_url`, `opnsense_apply_url` (`/api/firewall/alias/reconfigure`), `opnsense_basic_auth` (base64 of key:secret), `opnsense_leases_url`. Values ``. +- OPNsense API key needs Firewall: Alias read/write. +- DHCP sensor: `sensor.home_dhcp_leases_lan`, data under `attributes.Leases` (capital L) with `address` / `hostname` / `expires`. +- HA WS auth: send the auth message with raw `ws.send()` — the helper `send()` waits for a `result`, but HA replies to auth with `auth_ok` / `auth_invalid`. +- `lastSaveTime` guard prevents the display blanking when the `input_text` state echo arrives right after a save. +- Panel added via `panel_iframe` at `/local/parental_controls.html`, `require_admin: true`. + +## Code Changes +- `packages/parental_controls.yaml` — rest_commands (JSON payload), DHCP lease REST sensor, 12 chunked `input_text` entities, scripts, optional schedule automation. +- `www/parental_controls.html` — REST initial load + WS updates, WS auth fix, DHCP-based discovery and HA/DHCP status indicators, chunked `parseCfg`/`saveCfg`, save-error handling, `lastSaveTime` guard, URL auto-detect, optional CONFIG token. +- `secrets_example.yaml`, `README.md` — setup docs. + +## Open Questions / Next Steps +- **Schedules only run while the panel is open in a browser.** For reliable enforcement, move schedule logic into an HA automation (the package has an optional one) so it runs server-side. +- Consider an HA-side way to supply the token (e.g. trusted network auth or a proxy) so the HTML never needs a hardcoded token. +- Overlaps with `opnsense-device-control`, `ha-device-assignment` and the newer `homenet-guardrails` — decide which is canonical going forward. + +## Artifacts +- `bd49964` — Auto-detect URL from page origin +- `4142d1c` — Fix empty display after save + OPNsense JSON payload fix +- `8a5fe10` / `cf8d7ee` — Chunked storage (12×255) +- `4ecdda5` — Redesign on OPNsense DHCP lease sensor +- `5593d14` — WS auth via `ws.send()` +- `76b67d3` — REST initial load, 60s WS timeout