Always poll Ubisys EM cluster via active power entity#658
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #658 +/- ##
==========================================
+ Coverage 97.41% 97.44% +0.02%
==========================================
Files 62 62
Lines 10724 10732 +8
==========================================
+ Hits 10447 10458 +11
+ Misses 277 274 -3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR introduces specialized handling for ubisys devices' electrical measurement polling to ensure continuous monitoring of EM cluster attributes even when the active power entity is disabled by default.
The problem: ubisys devices use a quirk to disable the active_power entity by default (since instantaneous_demand supports reporting). However, PolledElectricalMeasurement manages polling for the entire ElectricalMeasurement cluster, so disabling it stops updates for voltage, current, and power factor entities.
The solution: Create a ubisys-specific UbisysPolledElectricalMeasurement subclass that overrides disable() and enable() to bypass PollableSensor's polling task management, keeping the polling task alive permanently regardless of entity enabled state.
Changes:
- Introduced
EM_ACTIVE_POWERfeature group to coordinate active power entity discovery - Added feature priorities to prevent multiple active power entities from being created per device
- Implemented ubisys-specific polling entity that maintains persistent polling
- Added comprehensive test coverage for the ubisys polling behavior
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| zha/application/platforms/init.py | Adds EM_ACTIVE_POWER feature group for entity priority coordination |
| zha/application/platforms/sensor/init.py | Adds feature priorities to active power entities and implements UbisysPolledElectricalMeasurement with persistent polling |
| tests/test_sensor.py | Tests that ubisys entity keeps polling when disabled and doesn't create duplicate tasks when re-enabled |
| tests/data/devices/ubisys-s1-5501.json | Adds test device data for ubisys S1 (5501) smart plug with EM cluster |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Proposed change
This keeps the cluster-wide
ElectricalMeasurementpolling active for Ubisys devices, even when the active power entity is disabled (here: by default from a quirk, since theinstantaneous_demandattribute supports reporting, while the EM attributes do not).Note
I'm aware this isn't a great solution. It's not permanent, but doesn't have any big downsides at the moment and we need this.
Related Ubisys PRs
Related quirks PR for Ubisys device support (notice how modifying the default entities is really great...):
Related PR for aligning the default precision for
instantaneous_demandwith the EM one and making the current one a bit more useful:Below is an accurate AI-generated summary of the problem and changes.
Problem
ubisys devices disable the
active_powerentity by default via a quirk. On all other devices,PolledElectricalMeasurement(the active power entity) is responsible for polling the entire ElectricalMeasurement cluster, which updates all EM-related entities (voltage, current, power factor, etc.).When the active power entity is disabled on ubisys devices,
PollableSensor.disable()cancels the polling task. This means no EM cluster attributes get polled, and the remaining EM entities (voltage, current, power factor) stop receiving updates.Solution
Introduce
UbisysPolledElectricalMeasurement, a ubisys-specific subclass ofPolledElectricalMeasurementthat keeps its polling task alive even when the entity is disabled.This is achieved by overriding
disable()andenable()to callPlatformEntitydirectly, bypassingPollableSensor's polling task management:disable()setsenabled = Falsebut does not cancel the polling taskenable()setsenabled = Truebut does not start a duplicate polling taskThe existing polling task created during
on_add()runs for the full lifetime of the entity, regardless of enable/disable state.Feature priority
To ensure only one active power entity is discovered per device, the three active power entity classes now use the
EM_ACTIVE_POWERfeature group:PolledElectricalMeasurementReportingElectricalMeasurementUbisysPolledElectricalMeasurementFor ubisys devices,
UbisysPolledElectricalMeasurement(priority 1) wins over the genericPolledElectricalMeasurement(priority 0). This prevents both classes from being instantiated for the same device.