Skip to content

Add iOS Live Activity webhook handlers to mobile_app#166072

Open
rwarner wants to merge 29 commits into
home-assistant:devfrom
rwarner:feat/ios-live-activity
Open

Add iOS Live Activity webhook handlers to mobile_app#166072
rwarner wants to merge 29 commits into
home-assistant:devfrom
rwarner:feat/ios-live-activity

Conversation

@rwarner
Copy link
Copy Markdown

@rwarner rwarner commented Mar 20, 2026

Proposed change

Adds server-side support for iOS Live Activities in the `mobile_app` integration. This is the HA core companion to the iOS companion app PRs and the relay server PR.

Live Activities let Home Assistant automations push real-time state to the iOS Lock Screen and Dynamic Island. The iOS app handles the ActivityKit lifecycle; this PR adds the webhook handlers and notification routing that HA core needs.

How it works: When a notification contains `live_update: true` and a `tag`, the notify service looks up the stored APNs Live Activity token for that tag and includes it alongside the normal FCM registration token in the relay request. The relay places it in the FCM message's `apns.liveActivityToken` field — no separate APNs endpoint or credentials needed. If no per-activity token exists, it falls back to the device's push-to-start token (iOS 17.2+) to start a new activity remotely.

What this adds:

  • `live_activity_token` webhook — stores per-activity APNs push tokens sent by the iOS app when an activity is created via ActivityKit
  • `live_activity_dismissed` webhook — removes the stored token when the activity ends on device
  • `SCHEMA_APP_DATA` validation for the optional `live_activity_push_to_start_token` field in device registration
  • Notification routing in `notify.py` — extracts and forwards the Live Activity APNs token when `live_update: true` is present
  • In-memory `DATA_LIVE_ACTIVITY_TOKENS` store, initialized in `init.py` and cleaned up on config entry unload

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

Part of epic: home-assistant/epics#61
Fixes: home-assistant/iOS#4623

@home-assistant
Copy link
Copy Markdown
Contributor

Hey there @home-assistant/core, mind taking a look at this pull request as it has been labeled with an integration (mobile_app) you are listed as a code owner for? Thanks!

Code owner commands

Code owners of mobile_app can trigger bot actions by commenting:

  • @home-assistant close Closes the pull request.
  • @home-assistant rename Awesome new title Renames the pull request.
  • @home-assistant reopen Reopen the pull request.
  • @home-assistant unassign mobile_app Removes the current integration label and assignees on the pull request, add the integration domain after the command.
  • @home-assistant add-label needs-more-information Add a label (needs-more-information, problem in dependency, problem in custom component, problem in config, problem in device, feature-request) to the pull request.
  • @home-assistant remove-label needs-more-information Remove a label (needs-more-information, problem in dependency, problem in custom component, problem in config, problem in device, feature-request) on the pull request.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Home Assistant Core support in the mobile_app integration for iOS Live Activities by introducing webhook handlers that store and clear per-activity APNs push tokens and emit lifecycle events for automations.

Changes:

  • Extend SCHEMA_APP_DATA and constants to support Live Activities capability flags and push-to-start registration fields.
  • Add update_live_activity_token and live_activity_dismissed webhooks that manage an in-memory token store and fire remote-origin bus events.
  • Add a supports_live_activities() helper and webhook tests covering token storage, defaults, and cleanup.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
homeassistant/components/mobile_app/const.py Adds Live Activity-related constants/events and extends registration SCHEMA_APP_DATA.
homeassistant/components/mobile_app/__init__.py Initializes a new in-memory DATA_LIVE_ACTIVITY_TOKENS store under hass.data[DOMAIN].
homeassistant/components/mobile_app/webhook.py Implements the new Live Activity webhook handlers and fires lifecycle events.
homeassistant/components/mobile_app/util.py Adds supports_live_activities() helper based on stored app_data.
tests/components/mobile_app/test_webhook.py Adds tests for storing tokens, default env behavior, and dismiss cleanup/event firing.
Comments suppressed due to low confidence (1)

tests/components/mobile_app/test_webhook.py:1398

  • This test only asserts the HTTP status. To fully validate the contract of live_activity_dismissed (which returns empty_okay_response()), also assert the JSON body is {} (and optionally that no tokens were removed when none existed) to prevent regressions in response shape/side effects.
    resp = await webhook_client.post(
        f"/api/webhook/{webhook_id}",
        json={
            "type": "live_activity_dismissed",
            "data": {
                "tag": "nonexistent_activity",
            },
        },
    )

    assert resp.status == HTTPStatus.OK

Comment thread homeassistant/components/mobile_app/const.py Outdated
Comment thread homeassistant/components/mobile_app/__init__.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Comment thread homeassistant/components/mobile_app/notify.py
Comment thread homeassistant/components/mobile_app/webhook.py Outdated
Comment thread homeassistant/components/mobile_app/notify.py
Copilot AI review requested due to automatic review settings March 23, 2026 13:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Comment thread homeassistant/components/mobile_app/webhook.py Outdated
Comment thread homeassistant/components/mobile_app/webhook.py Outdated
Copilot AI review requested due to automatic review settings March 23, 2026 18:29
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment thread homeassistant/components/mobile_app/notify.py Outdated
Copilot AI review requested due to automatic review settings March 23, 2026 19:55
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Comment thread homeassistant/components/mobile_app/const.py Outdated
Comment thread homeassistant/components/mobile_app/notify.py Outdated
Comment thread homeassistant/components/mobile_app/webhook.py
Copilot AI review requested due to automatic review settings March 24, 2026 14:09
rwarner and others added 2 commits April 29, 2026 13:12
- Remove unused AsyncGenerator import from notify.py
- Sort ATTR_PUSH_TAG import alphabetically (after ATTR_PUSH_RATE_LIMITS_SUCCESSFUL)
- Wrap long line in webhook_update_live_activity_token

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- Store per-activity tokens as {"push_token": <token>} dict in
  DATA_LIVE_ACTIVITY_TOKENS so the structure matches test expectations
  and leaves room for additional fields without a schema change
- Update _get_live_activity_token to read the push_token key from the dict
- Update test_notify.py setups to use dict format
- Fix stale "mobile_app_live_activity_token" type name in test_init.py
  (should be "live_activity_token" after the prefix-drop rename)

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@rwarner rwarner force-pushed the feat/ios-live-activity branch from 9cf6a0e to eb478d4 Compare April 29, 2026 17:13
@rwarner rwarner marked this pull request as ready for review April 29, 2026 18:27
@home-assistant home-assistant Bot requested a review from edenhaus April 29, 2026 18:27
@edenhaus
Copy link
Copy Markdown
Member

Please don't rebase after a review have started as this means a reviewer needs to review again the whole PR instead of the changes. Keep this in mind and also instruct claude to do it

@edenhaus
Copy link
Copy Markdown
Member

Previously requested changes are not implemented. Drafting the PR. Not sure if the AI has reintroduced them or if they still pending to implement but due the rebase each commit is marked as new and I will not check each commit. Please make sure all previous requested changes are implemented correctly before marking the PR as ready for review.

and again we require the human in the loop and it feels from the comments that the are written completely by the AI

Copy link
Copy Markdown
Member

@edenhaus edenhaus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description not in sync with the changes

@home-assistant home-assistant Bot marked this pull request as draft April 30, 2026 08:07
@rwarner
Copy link
Copy Markdown
Author

rwarner commented Apr 30, 2026

Okay addressing some of the things here. This has unfortunately gotten to be a mess

we require the human in the loop and it feels from the comments that the are written completely by the AI

Yes, I did use AI for some responses that I felt like it could explain more sufficiently than I could. But I am personally involved in all of this. I apologize, as I was unaware this was against policy with OHF

PR description not in sync with the changes

Updated the description to match with current fork branch changes

don't rebase after a review have started

Sorry, again I was unaware this was a bad thing and now understand. It was 100+commits behind and I was simply doing this to try to fix CI solely.


Items that were tended to, as some things were lost during the rebase and I thought they were still in there:

  • ATTR_LIVE_ACTIVITY_PUSH_TO_START_APNS_ENVIRONMENT removed from const.py: had been removed, rebase brought it back
  • PUSH constants reordered in const.py: all push-related attrs grouped together, rebase undid the ordering
  • SCHEMA_APP_DATA simplified: vol.Inclusive pair for APNS environment removed, push-to-start token changed to vol.Optional with plain cv.string, rebase reverted all of this
  • Push-to-start return in notify.py: simplified to return app_data.get(...), rebase reverted it back to the walrus pattern
  • Verbose/AI-sounding docstrings and inline comments: had been written in a verbose style, @edenhaus flagged them all as AI-sounding on Apr 30. After the rebase, it exposed them again

I have "unresolved" the comments that were lost during the rebase so they can be re-verified.

Would it be better for you @edenhaus if I just started a new PR at this point?

Comment thread homeassistant/components/mobile_app/const.py
@edenhaus
Copy link
Copy Markdown
Member

edenhaus commented May 5, 2026

Would it be better for you @edenhaus if I just started a new PR at this point?

No let's continue in this PR. just don't do any force pushes.

Will do a full review after the store is in place so it's fine.

rwarner and others added 2 commits May 7, 2026 08:51
…anup

Tokens are now stored via a dedicated Store (mobile_app.live_activity_tokens)
so they survive HA restarts. Each token is saved with a stored_at timestamp;
tokens older than 8 hours are filtered on load and cleaned up lazily on lookup.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@rwarner
Copy link
Copy Markdown
Author

rwarner commented May 7, 2026

Re-instated the accidental removal of that comment above

Integrated the storage capability for tokens: 25340ac

Let me know how its looking overall and anything else to do

@edenhaus
Copy link
Copy Markdown
Member

edenhaus commented May 7, 2026

Please fix the merge conflict. If you think the PR is ready for another review please mark it as ready for review. Will wait for the next review until it's marked ready for review

@rwarner
Copy link
Copy Markdown
Author

rwarner commented May 7, 2026

Please fix the merge conflict. If you think the PR is ready for another review please mark it as ready for review. Will wait for the next review until it's marked ready for review

Sounds good. I was hesitant to mess it up again with the whole rebase and update from last time

@rwarner rwarner marked this pull request as ready for review May 7, 2026 13:46
@home-assistant home-assistant Bot requested a review from edenhaus May 7, 2026 13:46
Comment thread homeassistant/components/mobile_app/__init__.py
Comment thread homeassistant/components/mobile_app/__init__.py Outdated
@home-assistant home-assistant Bot marked this pull request as draft May 7, 2026 14:01
Removes the separate live_activity_tokens store. Tokens are now saved
in the main mobile_app store (STORAGE_VERSION bumped to 2). Existing
v1 data is migrated inline by defaulting the new key to {}. Stores
timestamps as floats so no custom datetime parsing is needed.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@rwarner
Copy link
Copy Markdown
Author

rwarner commented May 7, 2026

Added to existing store: b0cb713

Removed custom datetime parsing

@rwarner rwarner marked this pull request as ready for review May 7, 2026 15:32
@home-assistant home-assistant Bot requested a review from edenhaus May 7, 2026 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Live updates - main feature

4 participants