From d2775e35d904c6b47fa47fb2a6f7d4f5fd798b1e Mon Sep 17 00:00:00 2001 From: marthsincemelee Date: Mon, 18 May 2026 12:07:31 +0200 Subject: [PATCH] feat(home-assistant): set internal/external URLs for mobile_app push The HA Companion app needs an external_url for clickable notification deep-links to resolve when the phone is off the home Wi-Fi. Reach is via Tailscale (Headscale tailnet solar.internal), so external_url points at the FQDN jupiter.solar.internal:8123; internal_url stays on the bare hostname for LAN-attached devices. Phase A only: device registration + notify group + smoke-test land in a follow-up commit once Companion has registered real mobile_app_ service names. See docs/superpowers/specs/2026-05-18-ha-push-notifications.md. Co-Authored-By: Claude Opus 4.7 --- .../specs/2026-05-18-ha-push-notifications.md | 111 ++++++++++++++++++ .../environments/home-assistant/default.nix | 2 + 2 files changed, 113 insertions(+) create mode 100644 docs/superpowers/specs/2026-05-18-ha-push-notifications.md diff --git a/docs/superpowers/specs/2026-05-18-ha-push-notifications.md b/docs/superpowers/specs/2026-05-18-ha-push-notifications.md new file mode 100644 index 0000000..635ade8 --- /dev/null +++ b/docs/superpowers/specs/2026-05-18-ha-push-notifications.md @@ -0,0 +1,111 @@ +# Smartphone push notifications from Home Assistant + +## Goal + +Send push notifications from jupiter's Home Assistant to the user's +smartphones over the home Tailscale (Headscale) tailnet `solar.internal`. + +## Architecture + +- HA's `mobile_app` integration is enabled (already in `extraComponents` + and present as `mobile_app = {}` in config). +- Each smartphone runs the **HA Companion app**, signs in to HA, and + auto-registers as a `notify.mobile_app_` service. +- Reach: phones connect to HA via Tailscale, so HA's `external_url` is + set to the Headscale FQDN `http://jupiter.solar.internal:8123`. The + `internal_url` is `http://jupiter:8123` for LAN-attached devices. +- No public exposure, no reverse proxy, no TLS termination in scope. + +## Phase A — done in this branch + +NixOS module change in `modules/environments/home-assistant/default.nix`: + +```nix +homeassistant = { + name = "Home - Rechberg"; + unit_system = "metric"; + internal_url = "http://${hostName}:8123"; + external_url = "http://jupiter.solar.internal:8123"; +}; +``` + +After deploy, perform the user-side registration: + +1. Install the Companion app: + - iOS: search "Home Assistant" in the App Store. + - Android: search "Home Assistant" in Google Play. +2. Ensure Tailscale is running and connected on the phone. +3. Open the Companion app. When asked to connect, enter + `http://jupiter.solar.internal:8123` and sign in with the HA account. +4. Approve the registration prompt in HA. +5. In HA, go to **Settings → Devices & Services → Mobile App** and + confirm the phone appears as a device. +6. In HA, go to **Developer Tools → Services**, type `notify.mobile_app_` + and note the exact service slug for each phone (e.g. + `notify.mobile_app_iphone_finn`). These slugs are needed for Phase B. + +### Verifying Phase A end-to-end + +Build-time: + +``` +nix eval '.#nixosConfigurations.jupiter.config.services.home-assistant.config.homeassistant' \ + --extra-experimental-features 'nix-command flakes' +``` + +Expect the rendered attrset to contain both `external_url` and +`internal_url`. + +Deploy on jupiter: + +``` +sudo nixos-rebuild switch --flake '.#jupiter' +systemctl status home-assistant +journalctl -u home-assistant -n 50 --no-pager +``` + +Functional check after Companion sign-in: + +- HA UI → **Developer Tools → Services** → choose + `notify.mobile_app_` → service data + `{ "message": "Phase A test" }` → **Call Service** → push arrives on + the phone. + +## Phase B — follow-up commit (after registration) + +Once device slugs are known, a separate commit adds: + +1. A `notify` group fanning out to every registered phone: + + ```nix + notify = [ + { + name = "all_phones"; + platform = "group"; + services = [ + { service = "mobile_app_"; } + { service = "mobile_app_"; } + ]; + } + ]; + ``` + +2. A smoke-test mechanism. Approach to be decided in Phase B based on + whether future Nix-managed automations are expected: + + - Pragmatic: document a one-time UI call to `notify.all_phones` from + Developer Tools (no automation in YAML). + - Compromise: switch `automation = "!include automations.yaml"` to + `!include_dir_merge_list automations/` so a Nix-managed + `00-smoke-test.yaml` can coexist with UI-editable automations. + +### Verifying Phase B end-to-end + +- Restart HA, watch `journalctl -u home-assistant` for YAML schema errors. +- Call `notify.all_phones` from Developer Tools — every registered phone + receives the push. + +## Open items + +- After Companion registration, collect the `mobile_app_` service + names from HA and update this spec + open Phase B PR. diff --git a/modules/environments/home-assistant/default.nix b/modules/environments/home-assistant/default.nix index eb4eb99..759a54f 100644 --- a/modules/environments/home-assistant/default.nix +++ b/modules/environments/home-assistant/default.nix @@ -40,6 +40,8 @@ in homeassistant = { name = "Home - Rechberg"; unit_system = "metric"; + internal_url = "http://${hostName}:8123"; + external_url = "http://jupiter.solar.internal:8123"; }; mobile_app = {}; automation = "!include automations.yaml";