feat: enrich Zigbee sensors with room data from RoomControl#743
feat: enrich Zigbee sensors with room data from RoomControl#743CFenner merged 9 commits intoopenviess:masterfrom
Conversation
HA integration stepsOnce this lands and is released, the HA vicare integration needs:
That's enough to restore For the new features (heating targets, condensation risk, schedules, quick modes), we'd add entity descriptions in a follow-up HA PR. Impact and riskFor installations with RoomControl + Zigbee sensors (blob810's case): Temperature and humidity are restored on the physical sensor devices. Heating targets, condensation risk, and schedules become available. Confirmed working on a 10-room installation. For installations without RoomControl (our test case): The enrichment finds RoomControl devices with 0 rooms, builds an empty actor map, and does nothing. No extra API calls, no side effects. Verified on a CU401B_G + VitoCharge setup with two RoomControl devices present but no Zigbee sensors. For installations without RoomControl at all: The enrichment loop simply finds no
|
| self._room_control = None | ||
| self._room_id = None |
There was a problem hiding this comment.
This can move to class level, no?
| (self.asRadiatorActuator, r"E3_RadiatorActuator", ["type:radiator"]), | ||
| (self.asFloorHeating, r"Smart_zigbee_fht_main|E3_FloorHeatingCircuitDistributorBox", ["type:fhtMain"]), | ||
| (self.asFloorHeatingChannel, r"Smart_zigbee_fht_channel", ["type:fhtChannel"]), | ||
| (self.asRoomControl, r"E3_RoomControl|Smart_RoomControl", ["type:virtual;smartRoomControl"]), |
There was a problem hiding this comment.
Will this class only represent the virtual device that handles the room thermostat mapping or also in-room control real devices?
There was a problem hiding this comment.
Only the virtual device (role type:virtual;smartRoomControl). Physical in-room controllers like Vitotrol 300E are separate zigbee devices with their own device type and class.
1f03875 to
416ef89
Compare
|
Addressed review comments:
Re: RoomControl scope question - it only represents the virtual device (role |
|
|
||
| # RoomControl - room sensor data, used by enrichment (#743) | ||
| 'rooms', | ||
| 'rooms.0', |
There was a problem hiding this comment.
No, it's not limited to 10 rooms. I just realized these ignore entries are actually unnecessary -- find_feature_in_code already replaces single digits with {.*?}, so rooms.5.sensors.temperature in test data matches f"rooms.{room_id}.sensors.temperature" in code. The test passes without them. I'll remove the entire block.
c17da01 to
0d6735d
Compare
Adds sanitized RoomControl device data with 10 rooms including temperature, humidity, and actor mappings to Zigbee room sensors and floor heating channels. Data contributed by blob810 from a Vitocal 222-SI installation with E3_RoomControl_One_525 (RoomControl-1).
Viessmann removed temperature and humidity data from physical Zigbee room sensors and moved it to the RoomControl virtual device. This restores the data on the physical sensors by cross-referencing RoomControl actor mappings with Zigbee device IDs. Enriched data includes: - Temperature, humidity, CO2 sensors - Condensation risk - Operating state (level, demand, reason) - Heating programs (normal/reduced/comfort) with set commands - Quick mode (manual till next schedule) with activate/deactivate - Schedule (read) - Room name and type Changes: - Add RoomControl device class with full room API - Add roomControl to device type filter - Enrich RoomSensor after device discovery via actor cross-reference - RoomSensor transparently reads from RoomControl when enriched, falls back to device-level data for older API versions - Add auto-detect entries for E3_RoomControl and Smart_RoomControl
RoomControl: concrete return types with float/int/str/bool coercion at the Any boundary (matching existing PyViCare style). RoomSensor: _getRoomContext() returns (RoomControl, str) tuple, eliminating str|None arg-type errors cleanly.
find_feature_in_code already replaces digits with wildcards,
so rooms.N features match rooms.{room_id} in code automatically.
0d6735d to
5ccddfd
Compare
There was a problem hiding this comment.
The room thermostat can be enhanced the same way no?
There was a problem hiding this comment.
Yes, any device that shows up as an actor in a RoomControl room could be enriched the same way. Right now we only do it for RoomSensor, but extending to RadiatorActuator or FloorHeating would be straightforward -- same setRoomControlEnrichment pattern. Happy to add that in a follow-up if there's demand.
There was a problem hiding this comment.
Ok, then let's go with this first.
The RoomControl-driven Zigbee enrichment introduced in #743 does not work in practice: the rooms.{id}.actors mapping that drives buildActorRoomMap() is not returned by the API for end users, so the enrichment is silently no-op and the lib has no reliable path to associate physical Zigbee devices with rooms. Removes the enrichment plumbing and reverts RoomSensor to direct sensor reads (device.sensors.temperature, device.sensors.humidity). RoomControl itself stays for direct per-room access. BREAKING CHANGE: RoomSensor no longer exposes hybrid getters that required RoomControl context (getRoomName, getRoomType, getCondensationRisk, getOperatingState*, getNormal/Reduced/Comfort HeatingTemperature, getManualTillNextSchedule*, getSchedule). Use the corresponding RoomControl methods with a room_id directly. Co-authored-by: Christopher Fenner <9592452+CFenner@users.noreply.github.com>
Background
Viessmann has removed
device.sensors.temperatureanddevice.sensors.humidityfrom physical Zigbee room sensors (E3_RoomSensor). Comparing current API responses (Apr 2026) with #557 test data (May 2025), the sensors went from 12 features down to 6 — only battery, zigbee signal, and identification remain.The temperature and humidity data still exists, but only on the RoomControl virtual device under
rooms.N.sensors.*. This meansRoomSensor.getTemperature()andgetHumidity()silently stopped working for affected installations.Design
Rather than mapping Viessmann's room abstraction into a new device hierarchy (as #557 proposed), this PR enriches the existing physical Zigbee devices with data from RoomControl — following @CFenner's preferred approach (#557 (comment)).
The cross-referencing works because RoomControl lists "actors" per room — these are the Zigbee device IDs of the physical sensors and floor heating channels in that room. We reverse this mapping: given a Zigbee sensor's device ID, find which room it belongs to, then read that room's sensor data.
How it works
roomControladded to device type filter — PyViCare now discovers RoomControl devices__enrichZigbeeDevices()builds an actor→room mapping from each RoomControlPyViCareDeviceConfigasRoomSensor()creates a RoomSensor, the enrichment is appliedRoomSensor.getTemperature()transparently reads from RoomControl when enriched, falls back to device-level data for installations without RoomControl (older API or different device models)What's exposed
Sensors: temperature, humidity, CO2, condensation risk
Operating state: level, demand, reason
Heating programs: normal/reduced/comfort target temperatures with
setTemperaturecommandsQuick mode: manual till next schedule (activate/deactivate/set temperature)
Schedule: read (per room)
Room metadata: name, type
What's NOT in this PR
Test data
Depends on #742 for the E3_RoomControl_One_525 test data (contributed by blob810, sanitized).
Breaking changes
None. Existing behavior is preserved — enrichment only activates when a RoomControl device exists. Installations without RoomControl are unaffected.