Repository navigation
Add a button event entity for remotes - #959
zigpy-review-bot wants to merge 6 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev #959 +/- ##
=======================================
Coverage 97.23% 97.24%
=======================================
Files 61 61
Lines 10719 10785 +66
=======================================
+ Hits 10423 10488 +65
- Misses 296 297 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
ZhaEventButton maps the zha_events of its device to standard button event types with ZhaEventMatch entries, matched like the data of a ZHA device automation trigger. The first match fires, so one event from the device fires at most one event type, and a long_press_start the device repeats while held fires once per hold.
A ZhaEventMatch with while_held only matches after a long_press_start of the entity, which ends the hold for a release that does not tell the button or a short press apart (home-assistant/architecture#1502 rule 7).
An error firing an event no longer keeps the zha_event from the device's other listeners, a release matching while held wins regardless of its position, and an entity matching while held needs a long_press_start.
d749a72 to
684b4be
Compare
|
@zigpy-review-bot #958 was just merged. Update this if needed. Investigate test failure and possibly update PR or open new one(s) after review rounds. |
…ntities EventBase.emit() now contains listener errors itself (#930), so the entity's own handler only sees errors from matching and firing.
|
The test failure came from #930, not from #958:
Full suite passes locally (1523), ruff and mypy are clean. One Fable review round on the delta found only the comment and description inaccuracies above, now fixed. I skipped the Copilot pass because the change is test and comment only. |
Note
Part of the standardized button event entities work tracked in #961: all PRs, design choices and alternatives, open decisions.
Summary
Remotes report button presses as cluster commands, which ZHA relays as
zha_events, and quirks map those to device automation triggers. This addsZhaEventButton, a button event entity that maps the samezha_events to the standard button event types (home-assistant/architecture#1502), so quirks can give every physical button an event entity. The quirk side,QuirkBuilder.button_event()and the device conversions, is in zigpy/zha-device-handlers#5480 and the PRs stacked on it.Changes
ZhaEventMatch: an event type, thezha_eventdata it fires for, and optional event attributes (press_countformulti_press). The data is matched like the data of a ZHA device automation trigger: every key has to be equal, nested mappings such asparamsonly need to contain the expected keys, and lists and tuples compare by their items. A quirk can pass a trigger's data as is, so the event fires for thezha_events that trigger's data matches.ZhaEventButton: aZclPlatformEntityattached to one of the button's clusters (MakePlatformEntitydevice bound and addZclPlatformEntity#919), listening to its device'szha_events. It fires the event type of the first match, so one event from the device fires at most one event type. Its only state is whether the button is held, which the proposal allows for two things (rule 7):repeats=Trueon along_press_startfires it once per hold when the device repeats it while the button is held (Philips Hue remotes);while_held=Trueon along_press_endonly matches after along_press_startof the same entity, ahead of the entity's other matches. This handles a release that doesn't say which button was held, like the arrow release of the IKEA STYRBAR, or that is the same for a short press and a hold.Both rely on the device's releases. If one gets lost, the whole next hold of a
repeatsentity is taken for repeats until its release, and withwhile_heldthe next release the device doesn't tell apart is taken for the end of the hold once.The entity is validated when it is created, not when an event fires: a
multi_pressneeds a validpress_count,while_heldneeds along_press_starton the same entity, andrepeatsneeds another event type that ends the hold.An error while matching or firing an event is logged with the entity and the
zha_eventdata. Since Contain listener errors inEventBase.emit()#930,emit()keeps thezha_eventflowing to the device's other listeners, such as HA's device triggers, either way.EntityPlatform.EVENT, so quirks can expose event entities.Alternatives
CommandEvententity in Add a ZGP quirk builder and EnOcean PTM 216Z + Hue Tap quirks zha-device-handlers#5273. This PR keeps it in ZHA because the entity is generic: it only needs the device'szha_events, it has no quirk-specific logic, and ZHA already holds the other entity classes quirks map their metadata to (button.Button,sensor.Sensor, …). A future entity API for quirks (Add APIs to directly create ZHA entities zha-device-handlers#5410) can reuse the class as it is.PlatformEntitydevice bound and addZclPlatformEntity#919, the entity could also be device-bound, without a cluster. It is ZCL-backed for now because the quirks' entity discovery and metadata are built around a cluster per entity. Once quirks can create device-bound entities, the cluster can be dropped from the button event API.Testing
tests/test_platform_event.py: the matching rules, an end-to-end test where real ZCL frames of an Innr RC 250 fixture fire the entity, first-match-wins, repeated holds, releases while held (one button, two buttons sharing a release, and in any order), errors in listeners and while firing, other devices' events, removal and validation.