d2775e35d9
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_<slug> service names. See docs/superpowers/specs/2026-05-18-ha-push-notifications.md. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
3.6 KiB
3.6 KiB
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_appintegration is enabled (already inextraComponentsand present asmobile_app = {}in config). - Each smartphone runs the HA Companion app, signs in to HA, and
auto-registers as a
notify.mobile_app_<device_slug>service. - Reach: phones connect to HA via Tailscale, so HA's
external_urlis set to the Headscale FQDNhttp://jupiter.solar.internal:8123. Theinternal_urlishttp://jupiter:8123for 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:
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:
- Install the Companion app:
- iOS: search "Home Assistant" in the App Store.
- Android: search "Home Assistant" in Google Play.
- Ensure Tailscale is running and connected on the phone.
- Open the Companion app. When asked to connect, enter
http://jupiter.solar.internal:8123and sign in with the HA account. - Approve the registration prompt in HA.
- In HA, go to Settings → Devices & Services → Mobile App and confirm the phone appears as a device.
- 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_<your_device>→ 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:
-
A
notifygroup fanning out to every registered phone:notify = [ { name = "all_phones"; platform = "group"; services = [ { service = "mobile_app_<slug_1>"; } { service = "mobile_app_<slug_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_phonesfrom Developer Tools (no automation in YAML). - Compromise: switch
automation = "!include automations.yaml"to!include_dir_merge_list automations/so a Nix-managed00-smoke-test.yamlcan coexist with UI-editable automations.
- Pragmatic: document a one-time UI call to
Verifying Phase B end-to-end
- Restart HA, watch
journalctl -u home-assistantfor YAML schema errors. - Call
notify.all_phonesfrom Developer Tools — every registered phone receives the push.
Open items
- After Companion registration, collect the
mobile_app_<slug>service names from HA and update this spec + open Phase B PR.