diff --git a/homeassistant/components/zha/core/channels/base.py b/homeassistant/components/zha/core/channels/base.py index 83accc5b86c..ebc2cd5cd0f 100644 --- a/homeassistant/components/zha/core/channels/base.py +++ b/homeassistant/components/zha/core/channels/base.py @@ -245,7 +245,7 @@ class ZigbeeChannel(LogMixin): self._cluster, [attribute], allow_cache=from_cache, - only_cache=from_cache, + only_cache=from_cache and not self._ch_pool.is_mains_powered, manufacturer=manufacturer, ) return result.get(attribute) @@ -260,7 +260,7 @@ class ZigbeeChannel(LogMixin): result, _ = await self.cluster.read_attributes( attributes, allow_cache=from_cache, - only_cache=from_cache, + only_cache=from_cache and not self._ch_pool.is_mains_powered, manufacturer=manufacturer, ) return result diff --git a/homeassistant/components/zha/core/channels/homeautomation.py b/homeassistant/components/zha/core/channels/homeautomation.py index d95180ce780..e18f4ae9c17 100644 --- a/homeassistant/components/zha/core/channels/homeautomation.py +++ b/homeassistant/components/zha/core/channels/homeautomation.py @@ -4,7 +4,7 @@ from typing import Optional import zigpy.zcl.clusters.homeautomation as homeautomation -from .. import registries, typing as zha_typing +from .. import registries from ..const import ( CHANNEL_ELECTRICAL_MEASUREMENT, REPORT_CONFIG_DEFAULT, @@ -51,14 +51,6 @@ class ElectricalMeasurementChannel(ZigbeeChannel): REPORT_CONFIG = ({"attr": "active_power", "config": REPORT_CONFIG_DEFAULT},) - def __init__( - self, cluster: zha_typing.ZigpyClusterType, ch_pool: zha_typing.ChannelPoolType - ) -> None: - """Initialize Metering.""" - super().__init__(cluster, ch_pool) - self._divisor = None - self._multiplier = None - async def async_update(self): """Retrieve latest state.""" self.debug("async_update") @@ -80,7 +72,9 @@ class ElectricalMeasurementChannel(ZigbeeChannel): async def fetch_config(self, from_cache): """Fetch config from device and updates format specifier.""" - results = await self.get_attributes( + + # prime the cache + await self.get_attributes( [ "ac_power_divisor", "power_divisor", @@ -89,22 +83,20 @@ class ElectricalMeasurementChannel(ZigbeeChannel): ], from_cache=from_cache, ) - self._divisor = results.get( - "ac_power_divisor", results.get("power_divisor", self._divisor) - ) - self._multiplier = results.get( - "ac_power_multiplier", results.get("power_multiplier", self._multiplier) - ) @property def divisor(self) -> Optional[int]: """Return active power divisor.""" - return self._divisor or 1 + return self.cluster.get( + "ac_power_divisor", self.cluster.get("power_divisor", 1) + ) @property def multiplier(self) -> Optional[int]: """Return active power divisor.""" - return self._multiplier or 1 + return self.cluster.get( + "ac_power_multiplier", self.cluster.get("power_multiplier", 1) + ) @registries.ZIGBEE_CHANNEL_REGISTRY.register( diff --git a/homeassistant/components/zha/manifest.json b/homeassistant/components/zha/manifest.json index e469cc90cc4..24d9a0a3962 100644 --- a/homeassistant/components/zha/manifest.json +++ b/homeassistant/components/zha/manifest.json @@ -9,7 +9,7 @@ "zha-quirks==0.0.42", "zigpy-cc==0.4.4", "zigpy-deconz==0.9.2", - "zigpy==0.22.1", + "zigpy==0.22.2", "zigpy-xbee==0.12.1", "zigpy-zigate==0.6.1" ], diff --git a/requirements_all.txt b/requirements_all.txt index 76468fa970f..d42d86276ce 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2269,7 +2269,7 @@ zigpy-xbee==0.12.1 zigpy-zigate==0.6.1 # homeassistant.components.zha -zigpy==0.22.1 +zigpy==0.22.2 # homeassistant.components.zoneminder zm-py==0.4.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index e2b2c32f484..a318da8ed17 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -999,4 +999,4 @@ zigpy-xbee==0.12.1 zigpy-zigate==0.6.1 # homeassistant.components.zha -zigpy==0.22.1 +zigpy==0.22.2 diff --git a/tests/components/zha/test_sensor.py b/tests/components/zha/test_sensor.py index 064b0251e6b..25fecd2d82c 100644 --- a/tests/components/zha/test_sensor.py +++ b/tests/components/zha/test_sensor.py @@ -265,3 +265,58 @@ async def test_temp_uom( assert state is not None assert round(float(state.state)) == expected assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == uom + + +async def test_electrical_measurement_init( + hass, zigpy_device_mock, zha_device_joined, +): + """Test proper initialization of the electrical measurement cluster.""" + + cluster_id = homeautomation.ElectricalMeasurement.cluster_id + zigpy_device = zigpy_device_mock( + { + 1: { + "in_clusters": [cluster_id, general.Basic.cluster_id], + "out_cluster": [], + "device_type": 0x0000, + } + } + ) + cluster = zigpy_device.endpoints[1].in_clusters[cluster_id] + zha_device = await zha_device_joined(zigpy_device) + entity_id = await find_entity_id(DOMAIN, zha_device, hass) + + # allow traffic to flow through the gateway and devices + await async_enable_traffic(hass, [zha_device]) + + # test that the sensor now have a state of unknown + assert hass.states.get(entity_id).state == STATE_UNKNOWN + + await send_attributes_report(hass, cluster, {0: 1, 1291: 100, 10: 1000}) + assert int(hass.states.get(entity_id).state) == 100 + + channel = zha_device.channels.pools[0].all_channels["1:0x0b04"] + assert channel.divisor == 1 + assert channel.multiplier == 1 + + # update power divisor + await send_attributes_report(hass, cluster, {0: 1, 1291: 20, 0x0403: 5, 10: 1000}) + assert channel.divisor == 5 + assert channel.multiplier == 1 + assert hass.states.get(entity_id).state == "4.0" + + await send_attributes_report(hass, cluster, {0: 1, 1291: 30, 0x0605: 10, 10: 1000}) + assert channel.divisor == 10 + assert channel.multiplier == 1 + assert hass.states.get(entity_id).state == "3.0" + + # update power multiplier + await send_attributes_report(hass, cluster, {0: 1, 1291: 20, 0x0402: 6, 10: 1000}) + assert channel.divisor == 10 + assert channel.multiplier == 6 + assert hass.states.get(entity_id).state == "12.0" + + await send_attributes_report(hass, cluster, {0: 1, 1291: 30, 0x0604: 20, 10: 1000}) + assert channel.divisor == 10 + assert channel.multiplier == 20 + assert hass.states.get(entity_id).state == "60.0"