# ha-parental-controls A Home Assistant dashboard for per-user, per-device internet blocking via OPNsense firewall alias management. Assign devices to users by MAC address, block/unblock individually or per-user, and optionally enforce scheduled access windows. --- ## How it works 1. OPNsense maintains a firewall alias called `parental_blocked` 2. A LAN rule blocks all traffic from IPs in that alias 3. The HA dashboard looks up each device's current IP from `device_tracker` entities (provided by the OPNsense integration), then adds/removes IPs from the alias via OPNsense API Because devices are identified by **MAC address**, blocks re-apply automatically when a device reconnects with a new IP (handled by a state change listener in the dashboard). --- ## Step 1 — OPNsense setup ### 1.1 Create the firewall alias Firewall → Aliases → + | Field | Value | |---|---| | Name | `parental_blocked` | | Type | `Host(s)` | | Description | `Parental Controls — blocked devices` | | Content | *(leave empty — managed via API)* | Save, then **Apply**. ### 1.2 Create the blocking rule Firewall → Rules → LAN → + | Field | Value | |---|---| | Action | **Block** | | Interface | LAN | | Direction | in | | Protocol | any | | Source | Single host or alias → `parental_blocked` | | Destination | any | | Description | `Parental Controls — block internet` | Position this rule **above** your default allow-all LAN rule. Save and Apply. ### 1.3 Create an API key System → Access → Users → (your admin user or a dedicated user) → API Keys → + Permissions needed: **Firewall: Alias** (read + write) Note the **Key** and **Secret** — you'll need them for secrets.yaml. --- ## Step 2 — Home Assistant setup ### 2.1 Add secrets to `/config/secrets.yaml` Replace values with your actual OPNsense details: ```yaml opnsense_alias_add_url: "https://YOUR_OPNSENSE_IP/api/firewall/alias_util/add/parental_blocked" opnsense_alias_del_url: "https://YOUR_OPNSENSE_IP/api/firewall/alias_util/delete/parental_blocked" opnsense_apply_url: "https://YOUR_OPNSENSE_IP/api/firewall/alias/reconfigure" # Generate with: echo -n "APIKEY:APISECRET" | base64 opnsense_basic_auth: "Basic BASE64_OF_KEY_COLON_SECRET" ``` To generate the base64 string on any Linux/macOS machine: ```bash echo -n "your_api_key:your_api_secret" | base64 ``` ### 2.2 Copy files into place ```bash # From your config directory cp packages/parental_controls.yaml /config/packages/ cp www/parental_controls.html /config/www/ ``` > If you don't use packages yet, add this to `/config/configuration.yaml`: > ```yaml > homeassistant: > packages: !include_dir_named packages > ``` ### 2.3 Add the sidebar panel Add to `/config/configuration.yaml`: ```yaml panel_iframe: parental_controls: title: "Parental Controls" icon: mdi:shield-account url: /local/parental_controls.html require_admin: true ``` ### 2.4 Restart Home Assistant Check for errors in Settings → System → Logs. The `input_text.parental_control_config` entity should now exist. --- ## Step 3 — Dashboard first run 1. Open the **Parental Controls** sidebar panel 2. On first load, you'll see a setup screen. Enter: - **HA URL**: your HA URL (e.g. `https://ha.hideawaygaming.com.au`) - **Long-Lived Token**: from your HA Profile → Security → Long-Lived Access Tokens → Create Token 3. Click **Connect** Your credentials are saved to browser `localStorage` — you won't need to enter them again on the same device. --- ## Usage ### Adding users Click **+ Add User**, give them a name and pick a colour. ### Adding devices On a user card, click **+ Add Device**. Either: - Pick from the **discovered devices** list (devices seen by the OPNsense integration) - Or enter a MAC address manually > **Tip**: Set DHCP static leases in OPNsense for kids' devices so their IPs stay consistent, though the dashboard handles IP changes automatically. ### Blocking - **User toggle** (top right of card): blocks/unblocks all devices for that user simultaneously - **Device toggle** (on each device row): individual device control If a device is offline when you block it, the dashboard marks it blocked and will apply the firewall rule automatically when the device reconnects. ### Scheduling Expand the **🕐 Schedule** section on any user card: 1. Enable the schedule toggle 2. Set **block** and **unblock** times for weekdays and weekends 3. Times are enforced every minute while the dashboard page is open The time range is the **blocked** window — e.g. `21:00 → 07:00` means blocked from 9pm until 7am (overnight ranges work correctly). #### HA-native schedule enforcement (optional) For schedules to be enforced even when the dashboard isn't open, uncomment the `automation:` block at the bottom of `packages/parental_controls.yaml` and restart HA. Note: the YAML automation requires the `from_json` Jinja2 filter and HA 2023.4+. --- ## Troubleshooting **Block doesn't seem to apply** - Confirm the `parental_blocked` alias exists in OPNsense → Firewall → Aliases - Check the blocking rule is above the default LAN allow rule - Verify your API credentials: test in a browser → `https://YOUR_OPNSENSE/api/firewall/alias_util/aliases` — should return JSON **Device not appearing in discovered list** - Make sure the OPNsense integration is installed and the device has been seen recently - Try using a manual MAC entry instead **"Failed to save config"** - Check HA logs for `input_text.parental_control_config` errors - Ensure the package loaded correctly (no YAML errors in startup logs) **Dashboard won't connect** - Confirm the Long-Lived Token is correct - If using a self-signed cert on HA, the page may have cert warnings — trust the cert first by visiting the HA URL directly