Skip to content

Fix Focus sensors reporting a stale state - #6129

Merged
bgoncal merged 3 commits into
mainfrom
fix/focus-sensors
Oct 25, 2026
Merged

bgoncal merged 3 commits into
mainfrom
fix/focus-sensors

Conversation

@bgoncal

@bgoncal bgoncal commented Oct 25, 2026

Copy link
Copy Markdown
Member

AI Policy

Select exactly one option that describes AI usage in this contribution:

  • I have not used AI for this contribution.
  • AI assistance was used for this contribution.
  • AI fully generated the code for this contribution, but I've reviewed and understood it before submitting and will respond without AI during review.

Summary

The Focus sensor could report off while a Focus was on, and the Focus name could be cleared while its Focus was still on.

  • Extensions that can't ask iOS for the Focus status no longer rebuild it from an old push.
  • Each source keeps its newest reading, and every process reports from those.
  • The app also reads the Focus filter's current values, so a Focus that ended without its filter running stops being reported.

Screenshots

No UI changes, only the wording of three Focus help texts.

Link to pull request in Documentation repository

Documentation: home-assistant/companion.home-assistant#

Any other notes

Related to #5467.

The push provider extension could not ask iOS for the Focus status and
rebuilt the sensors from an old push, reporting off while a Focus was on.
The Focus name could also be cleared while the paired Focus was still on.

Each source now keeps its newest reading in the app group, and every
process reports from those. The app asks iOS for the status and for the
Focus filter's current values on every read.
Copilot AI balanced review requested due to automatic review settings October 25, 2026 00:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved observation-ordering, timeout task accumulation, foreground refresh, and name-deletion issues can undermine reliable Focus reporting.

4 open issues
What changed in this PR

This PR addresses stale Focus reporting across the app and its extensions, including the Focus name behavior reported in #5467.

Changes:

  • Stores filter runs, status pushes, and app readings separately, resolving reports from the newest observations.
  • Adds timeout-bounded reads of the Focus filter’s current values and updates sensor subscriptions.
  • Reworks regression tests and corrects three Focus help texts.
File Description
Tests/​Shared/​Sensors/​FocusSensor.test.swift Tests stored status ordering and sensor signaling.
Tests/​Shared/​Sensors/​FocusNameSensor.test.swift Tests name resolution, timeouts, and legacy stored data.
Tests/​App/​Settings/​FocusNameFocusFilterAppIntent.test.swift Tests current-values reading and error handling.
Sources/​Shared/​Resources/​Swiftgen/​Strings.swift Updates generated help-text comments.
Sources/​Shared/​Intents/​FocusStatusIntentHandler.swift Records status received through the intent.
Sources/​Shared/​Environment/​FocusStatusWrapper.swift Separates status pushes from app readings.
Sources/​Shared/​Environment/​FocusStatusObservation.swift Adds a timestamped status model.
Sources/​Shared/​Environment/​FocusReport.swift Resolves both sensors from stored observations.
Sources/​Shared/​Environment/​FocusFilterWrapper.swift Adds current-values reads, timeouts, and observation selection.
Sources/​Shared/​Environment/​FocusFilterState.swift Extracts the simplified filter-state model.
Sources/​Shared/​Environment/​FocusFilterLiveConfirmation.swift Removes the obsolete confirmation model.
Sources/​Shared/​API/​Webhook/​Sensors/​FocusSensor.swift Uses asynchronous reports and updated subscriptions.
Sources/​Shared/​API/​Webhook/​Sensors/​FocusNameSensor.swift Uses asynchronous reports and removes status observation.
Sources/​App/​Settings/​Sensors/​Permissions/​SensorPermission.swift Clarifies the permission comment; mapping is unchanged.
Sources/​App/​Settings/​Focus/​FocusSettingsViewModel.swift Clarifies the permission comment only.
Sources/​App/​Settings/​Focus/​FocusNameFocusFilterAppIntent.swift Bridges current filter values into Shared.
Sources/​App/​Resources/​en.lproj/​Localizable.strings Corrects three English Focus help texts.
Sources/​App/​AppDelegate.swift Registers the current-values reader during launch.
HomeAssistant.xcodeproj/​project.pbxproj Adds target-membership entries for the extracted models.

Review effort: Balanced

Comment on lines +54 to +56
switch await Self.withTimeout(Self.currentValuesTimeout, reader) {
case let .some(.success(name)):
readings.value = FocusFilterState(name: name, date: Current.date())
Comment on lines +24 to +28
// Only the filter's runs change the name. A status push changes the "Is focused"
// attribute too, but the Intents extension that received it reports both Focus sensors
// itself, and signalling here would add a full update of every sensor to that extension's
// short run.
focusFilterCancellable = Current.focusFilter.runs.observe { [weak self] _ in
Comment thread Sources/Shared/Environment/FocusFilterWrapper.swift Outdated
Comment on lines +129 to +131
Task {
do {
let value = try await operation()
Date each reading of the filter's current values by when it was asked,
share one request between concurrent reads, and stop asking again while
a timed-out request is still unanswered. Deleting a Focus name keeps the
date of the answer it clears. The Focus name sensor refreshes again on a
status push while the app is in the foreground.
@codecov

codecov Bot commented Oct 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 57.49%. Comparing base (3ef4355) to head (97277cb).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6129   +/-   ##
=======================================
  Coverage   57.48%   57.49%           
=======================================
  Files        1278     1279    +1     
  Lines       84565    84556    -9     
=======================================
- Hits        48614    48612    -2     
+ Misses      35951    35944    -7     
Files with missing lines Coverage Δ
Sources/App/AppDelegate.swift 16.12% <100.00%> (+0.54%) ⬆️
...Settings/Focus/FocusNameFocusFilterAppIntent.swift 61.36% <100.00%> (+9.93%) ⬆️
...es/App/Settings/Focus/FocusSettingsViewModel.swift 100.00% <ø> (ø)
...ettings/Sensors/Permissions/SensorPermission.swift 49.38% <100.00%> (ø)
...s/Shared/API/Webhook/Sensors/FocusNameSensor.swift 100.00% <100.00%> (+38.63%) ⬆️
...urces/Shared/API/Webhook/Sensors/FocusSensor.swift 88.67% <100.00%> (-6.24%) ⬇️
Sources/Shared/Environment/FocusFilterState.swift 100.00% <100.00%> (ø)
...ources/Shared/Environment/FocusFilterWrapper.swift 100.00% <100.00%> (ø)
Sources/Shared/Environment/FocusReport.swift 100.00% <100.00%> (ø)
...es/Shared/Environment/FocusStatusObservation.swift 100.00% <100.00%> (ø)
... and 2 more

... and 8 files with indirect coverage changes

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@bgoncal
bgoncal merged commit 053fb15 into main Oct 25, 2026
15 checks passed
@bgoncal
bgoncal deleted the fix/focus-sensors branch October 25, 2026 07:54
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.

2 participants