Skip to content

Fix stale HomeKit characteristic entities after config changes - #177696

Open
jfremy wants to merge 2 commits into
home-assistant:devfrom
jfremy:codex/homekit-rebind-characteristic
Open

Fix stale HomeKit characteristic entities after config changes#177696
jfremy wants to merge 2 commits into
home-assistant:devfrom
jfremy:codex/homekit-rebind-characteristic

Conversation

@jfremy

@jfremy jfremy commented Jul 31, 2026

Copy link
Copy Markdown

Breaking change

None.

Proposed change

Context

HomeKit-over-IP climate accessories can stop updating characteristic-backed entities after a reconnect or configuration refresh, while reloading the integration temporarily restores updates. Similar symptoms were reported in #100331 and #102258. #116200 attempted to reduce HomeKit polling and #139550 later reverted those polling changes, but neither addresses stale characteristic references when aiohomekit replaces the accessory map. This fix has kept the affected current-temperature sensor updating for five days on a real AC controller.

Issue

When aiohomekit reports a configuration-number change, it replaces the accessory, service, and characteristic object graph. HomeKitEntity rebinds its accessory and service during reconfiguration, but BaseCharacteristicEntity only checks that a characteristic with the same IID exists and then keeps its original self._char reference. Polling and events update the new characteristic object, while the entity continues reading the old object. It should rebind self._char to the characteristic in the current accessory map before reconfiguring.

Fix

In BaseCharacteristicEntity._async_config_changed, replace the characteristic-disappearance helper with logic that resolves the characteristic by IID from the current accessory map. If the accessory, service, or characteristic no longer exists, remove the entity as before. Otherwise, assign the resolved characteristic to self._char and then run the existing reconfiguration logic to rebuild polling and event subscriptions against the replacement map.

Unit test

The Ecobee regression test first creates the current-temperature sensor from an accessory map where the value is 21.8. It then loads a fresh accessory map, changes that map's current-temperature value to 22.4, and triggers the existing configuration-change flow that replaces the complete accessory map. The test verifies that the existing sensor now reports 22.4; without the fix, it continues reading the old characteristic and remains at 21.8.

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

Checklist

  • I understand the code I am submitting and can explain how it works.
  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.
  • Any generated code has been carefully reviewed for correctness and compliance with project standards.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running: python3 -m script.gen_requirements_all.
  • For the updated dependencies a diff between library versions and ideally a link to the changelog/release notes is added to the PR description.

To help with the load of incoming pull requests:

Characteristic-backed entities retained objects from the previous accessory map after a HomeKit configuration refresh, leaving their values stale even though polling updated the replacement map.

Resolve the characteristic by IID from the current accessory map before reconfiguring the entity, and remove the entity when the characteristic disappeared. Add an Ecobee regression test that replaces the map with a new current-temperature value.

Tests: HomeKit Controller suite (352 passed; unrelated connection retry-count test failed), Ecobee module (7 passed), patch-specific prek hooks (passed), all-files prek hooks (all passed except existing duplicate-module mypy error).
Copilot AI review requested due to automatic review settings July 31, 2026 03:12

@home-assistant home-assistant Bot 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.

Hi @jfremy

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!

@home-assistant home-assistant Bot added bugfix cla-needed has-tests integration: homekit_controller small-pr PRs with less than 30 lines. Top 100 Integration is ranked within the top 100 by usage Top 200 Integration is ranked within the top 200 by usage labels Jul 31, 2026
@home-assistant

Copy link
Copy Markdown
Contributor

Hey there @Jc2k, @bdraco, mind taking a look at this pull request as it has been labeled with an integration (homekit_controller) you are listed as a code owner for? Thanks!

Code owner commands

Code owners of homekit_controller can trigger bot actions by commenting:

  • @home-assistant close Closes the pull request.
  • @home-assistant mark-draft Mark the pull request as draft.
  • @home-assistant ready-for-review Remove the draft status from the pull request.
  • @home-assistant rename Awesome new title Renames the pull request.
  • @home-assistant reopen Reopen the pull request.
  • @home-assistant unassign homekit_controller Removes the current integration label and assignees on the pull request, add the integration domain after the command.
  • @home-assistant update-branch Update the pull request branch with the base branch.
  • @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.

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.

Pull request overview

Fixes stale HomeKit characteristic-backed entities after accessory-map replacement.

Changes:

  • Rebinds entities to replacement characteristics during reconfiguration.
  • Adds an Ecobee temperature regression test.

Reviewed changes

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

File Description
homeassistant/components/homekit_controller/entity.py Refreshes characteristic references after configuration changes.
tests/components/homekit_controller/specific_devices/test_ecobee3.py Verifies temperature updates from the replacement accessory map.

@jfremy
jfremy marked this pull request as ready for review July 31, 2026 03:24
@jfremy
jfremy requested review from Jc2k and bdraco as code owners July 31, 2026 03:24
Exercise the BaseCharacteristicEntity config-change branches for a removed service and a removed characteristic using replacement accessory maps. Verify the derived sensor is removed in both cases so the rebind callback is fully covered.

Tests:
- uv run pytest tests/components/homekit_controller/test_sensor.py tests/components/homekit_controller/specific_devices/test_ecobee3.py (24 passed)
- uv run prek run --files tests/components/homekit_controller/test_sensor.py (passed)
Copilot AI review requested due to automatic review settings August 3, 2026 02:12

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.

Pull request overview

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

Suppressed comments (1)

tests/components/homekit_controller/test_sensor.py:383

  • Exercise the real configuration-change path via device_config_changed instead of invoking entity and pairing internals. This bypasses HKDevice.async_update_new_accessories_state, so the test can pass even if normal config notifications no longer remove these entities; the existing helper also avoids coupling to DATA_INSTANCES, _accessories_state, and _async_config_changed.
    helper.pairing._accessories_state = AccessoriesState(
        accessories, helper.pairing.config_num + 1
    )
    entity._async_config_changed()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix cla-signed has-tests integration: homekit_controller Quality Scale: No score small-pr PRs with less than 30 lines. Top 100 Integration is ranked within the top 100 by usage Top 200 Integration is ranked within the top 200 by usage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants