Repository navigation
Fix wirelesstag KeyError when a tag disappears from a reload #172600
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
11ddd0c
3e73c26
bd61e8d
4d4a80d
417ddb4
e57ea13
1faac3c
551e5a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,7 @@ def __init__(self, api: WirelessTagPlatform, tag: SensorTag) -> None: | |
| self.tag_manager_mac = self._tag.tag_manager_mac | ||
| self._attr_name = self._tag.name | ||
| self._state = None | ||
| self._tag_missing = False | ||
|
|
||
| @property | ||
| def principal_value(self): | ||
|
|
@@ -63,19 +64,29 @@ def decorate_value(self, value): | |
| @override | ||
| def available(self) -> bool: | ||
| """Return True if entity is available.""" | ||
| return self._tag.is_alive | ||
| return not self._tag_missing and self._tag.is_alive | ||
|
|
||
| def update(self) -> None: | ||
| """Update state.""" | ||
| if not self.should_poll: | ||
| return | ||
|
|
||
| updated_tags = self._api.load_tags() | ||
| if (updated_tag := updated_tags[self._uuid]) is None: | ||
| _LOGGER.error('Unable to update tag: "%s"', self.name) | ||
| if (updated_tag := updated_tags.get(self._uuid)) is None: | ||
| # The tag is gone from the account, so there is nothing left to | ||
| # poll. Reported through availability rather than a log message | ||
| # repeated on every poll. | ||
| _LOGGER.debug('Unable to update tag: "%s"', self.name) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair point — the debug line does fire on every poll, so that sentence described the change from Replaced in 1faac3c with a single line stating the constraint that actually matters, which is why this is # A tag can be removed from the account, so this is not an error. |
||
| self._tag_missing = True | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct, and thanks — that was a real hole in the flag I just added. A push proves the tag exists, but neither callback cleared Fixed in 4d4a80d by routing all three paths through one helper on the base entity rather than repeating the reset: def _apply_tag(self, tag: SensorTag) -> None:
"""Adopt a freshly received tag and refresh the state from it."""
self._tag_missing = False
self._tag = tag
self._state = self.updated_state_value()
|
||
| self._state = None | ||
| return | ||
|
|
||
| self._tag = updated_tag | ||
| self._apply_tag(updated_tag) | ||
|
|
||
| def _apply_tag(self, tag: SensorTag) -> None: | ||
| """Adopt a freshly received tag and refresh the state from it.""" | ||
| self._tag_missing = False | ||
| self._tag = tag | ||
| self._state = self.updated_state_value() | ||
|
|
||
| @property | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This bugfix is reasonable, however the below log might be over-logging at error. Consider lowering the level, or setting unavailable and clearing state if actually gone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch — the error was firing on every poll, and worse, the entity kept serving its last value while the tag was gone.
Went with the second option in bd61e8d:
update()now records the missing tag,availablereturnsFalsefor it, and the log drops to debug since the condition is visible to the user as unavailable. The state is cleared, and the entity recovers if the tag comes back. The test asserts the unavailable/recover transitions instead of scraping the log.