Fix ZHA electrical measurement sensor initialization (#37915)
* Refactor cached ZHA channel reads. If doing a cached ZCL attribute read, do "only_from_cache" read for battery operated devices only. Mains operated devices will do a network read in case of a cache miss. * Use cached attributes for ZHA electrical measurement * Bump up ZHA zigpy dependency.
This commit is contained in:
parent
716cee6907
commit
33dc015083
6 changed files with 70 additions and 23 deletions
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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"
|
||||
],
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Reference in a new issue