From 20333703c56e924507aa2cfba4cdc633c14f2dfd Mon Sep 17 00:00:00 2001 From: Alexei Chetroi Date: Wed, 4 Mar 2020 13:11:53 -0500 Subject: [PATCH] Remove ZHA attribute listening channel (#32468) * remove AttributeListeningChannel * pull sleeps * update signature to fix pylint --- homeassistant/components/zha/binary_sensor.py | 4 +- .../components/zha/core/channels/__init__.py | 4 +- .../components/zha/core/channels/base.py | 50 ++++++------------- .../components/zha/core/channels/closures.py | 20 ++++++-- .../components/zha/core/channels/general.py | 35 +++++++------ .../zha/core/channels/homeautomation.py | 10 ++-- .../components/zha/core/channels/hvac.py | 9 ++-- .../zha/core/channels/manufacturerspecific.py | 13 +++-- .../zha/core/channels/measurement.py | 16 +++--- .../components/zha/core/channels/security.py | 11 +++- .../zha/core/channels/smartenergy.py | 6 +-- .../components/zha/core/discovery.py | 2 +- homeassistant/components/zha/cover.py | 14 +++--- .../components/zha/device_tracker.py | 4 +- homeassistant/components/zha/entity.py | 2 +- homeassistant/components/zha/fan.py | 6 +-- homeassistant/components/zha/light.py | 6 +-- homeassistant/components/zha/lock.py | 4 +- homeassistant/components/zha/sensor.py | 8 +-- homeassistant/components/zha/switch.py | 4 +- tests/components/zha/test_channels.py | 4 +- 21 files changed, 124 insertions(+), 108 deletions(-) diff --git a/homeassistant/components/zha/binary_sensor.py b/homeassistant/components/zha/binary_sensor.py index 93baf8e111b..def1588a127 100644 --- a/homeassistant/components/zha/binary_sensor.py +++ b/homeassistant/components/zha/binary_sensor.py @@ -103,9 +103,9 @@ class BinarySensor(ZhaEntity, BinarySensorDevice): return self._device_class @callback - def async_set_state(self, state): + def async_set_state(self, attr_id, attr_name, value): """Set the state.""" - self._state = bool(state) + self._state = bool(value) self.async_schedule_update_ha_state() async def async_update(self): diff --git a/homeassistant/components/zha/core/channels/__init__.py b/homeassistant/components/zha/core/channels/__init__.py index d884f359d47..715bc3e3e75 100644 --- a/homeassistant/components/zha/core/channels/__init__.py +++ b/homeassistant/components/zha/core/channels/__init__.py @@ -235,7 +235,7 @@ class ChannelPool: """Create and add channels for all input clusters.""" for cluster_id, cluster in self.endpoint.in_clusters.items(): channel_class = zha_regs.ZIGBEE_CHANNEL_REGISTRY.get( - cluster_id, base.AttributeListeningChannel + cluster_id, base.ZigbeeChannel ) # really ugly hack to deal with xiaomi using the door lock cluster # incorrectly. @@ -243,7 +243,7 @@ class ChannelPool: hasattr(cluster, "ep_attribute") and cluster.ep_attribute == "multistate_input" ): - channel_class = base.AttributeListeningChannel + channel_class = base.ZigbeeChannel # end of ugly hack channel = channel_class(cluster, self) if channel.name == const.CHANNEL_POWER_CONFIGURATION: diff --git a/homeassistant/components/zha/core/channels/base.py b/homeassistant/components/zha/core/channels/base.py index 7bb2ad7b57e..d94c01fe4cd 100644 --- a/homeassistant/components/zha/core/channels/base.py +++ b/homeassistant/components/zha/core/channels/base.py @@ -4,7 +4,6 @@ import asyncio from enum import Enum from functools import wraps import logging -from random import uniform from typing import Any, Union import zigpy.exceptions @@ -22,7 +21,6 @@ from ..const import ( ATTR_VALUE, CHANNEL_EVENT_RELAY, CHANNEL_ZDO, - REPORT_CONFIG_DEFAULT, REPORT_CONFIG_MAX_INT, REPORT_CONFIG_MIN_INT, REPORT_CONFIG_RPT_CHANGE, @@ -84,7 +82,7 @@ class ZigbeeChannel(LogMixin): REPORT_CONFIG = () def __init__( - self, cluster: zha_typing.ZigpyClusterType, ch_pool: zha_typing.ChannelPoolType, + self, cluster: zha_typing.ZigpyClusterType, ch_pool: zha_typing.ChannelPoolType ) -> None: """Initialize ZigbeeChannel.""" self._channel_name = cluster.ep_attribute @@ -97,6 +95,12 @@ class ZigbeeChannel(LogMixin): unique_id = ch_pool.unique_id.replace("-", ":") self._unique_id = f"{unique_id}:0x{cluster.cluster_id:04x}" self._report_config = self.REPORT_CONFIG + if not hasattr(self, "_value_attribute") and len(self._report_config) > 0: + attr = self._report_config[0].get("attr") + if isinstance(attr, str): + self.value_attribute = get_attr_id_by_name(self.cluster, attr) + else: + self.value_attribute = attr self._status = ChannelStatus.CREATED self._cluster.add_listener(self) @@ -200,7 +204,6 @@ class ZigbeeChannel(LogMixin): await self.configure_reporting( report_config["attr"], report_config["config"] ) - await asyncio.sleep(uniform(0.1, 0.5)) self.debug("finished channel configuration") else: self.debug("skipping channel configuration") @@ -209,6 +212,8 @@ class ZigbeeChannel(LogMixin): async def async_initialize(self, from_cache): """Initialize channel.""" self.debug("initializing channel: from_cache: %s", from_cache) + for report_config in self._report_config: + await self.get_attribute_value(report_config["attr"], from_cache=from_cache) self._status = ChannelStatus.INITIALIZED @callback @@ -219,7 +224,12 @@ class ZigbeeChannel(LogMixin): @callback def attribute_updated(self, attrid, value): """Handle attribute updates on this cluster.""" - pass + self.async_send_signal( + f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", + attrid, + self.cluster.attributes.get(attrid, [attrid])[0], + value, + ) @callback def zdo_command(self, *args, **kwargs): @@ -272,36 +282,6 @@ class ZigbeeChannel(LogMixin): return self.__getattribute__(name) -class AttributeListeningChannel(ZigbeeChannel): - """Channel for attribute reports from the cluster.""" - - REPORT_CONFIG = [{"attr": 0, "config": REPORT_CONFIG_DEFAULT}] - - def __init__( - self, cluster: zha_typing.ZigpyClusterType, ch_pool: zha_typing.ChannelPoolType, - ) -> None: - """Initialize AttributeListeningChannel.""" - super().__init__(cluster, ch_pool) - attr = self._report_config[0].get("attr") - if isinstance(attr, str): - self.value_attribute = get_attr_id_by_name(self.cluster, attr) - else: - self.value_attribute = attr - - @callback - def attribute_updated(self, attrid, value): - """Handle attribute updates on this cluster.""" - if attrid == self.value_attribute: - self.async_send_signal(f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", value) - - async def async_initialize(self, from_cache): - """Initialize listener.""" - await self.get_attribute_value( - self._report_config[0].get("attr"), from_cache=from_cache - ) - await super().async_initialize(from_cache) - - class ZDOChannel(LogMixin): """Channel for ZDO events.""" diff --git a/homeassistant/components/zha/core/channels/closures.py b/homeassistant/components/zha/core/channels/closures.py index e25c2253bb3..af6306c45e3 100644 --- a/homeassistant/components/zha/core/channels/closures.py +++ b/homeassistant/components/zha/core/channels/closures.py @@ -23,7 +23,9 @@ class DoorLockChannel(ZigbeeChannel): """Retrieve latest state.""" result = await self.get_attribute_value("lock_state", from_cache=True) - self.async_send_signal(f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", result) + self.async_send_signal( + f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", 0, "lock_state", result + ) @callback def attribute_updated(self, attrid, value): @@ -33,7 +35,9 @@ class DoorLockChannel(ZigbeeChannel): "Attribute report '%s'[%s] = %s", self.cluster.name, attr_name, value ) if attrid == self._value_attribute: - self.async_send_signal(f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", value) + self.async_send_signal( + f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", attrid, attr_name, value + ) async def async_initialize(self, from_cache): """Initialize channel.""" @@ -63,8 +67,12 @@ class WindowCovering(ZigbeeChannel): "current_position_lift_percentage", from_cache=False ) self.debug("read current position: %s", result) - - self.async_send_signal(f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", result) + self.async_send_signal( + f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", + 8, + "current_position_lift_percentage", + result, + ) @callback def attribute_updated(self, attrid, value): @@ -74,7 +82,9 @@ class WindowCovering(ZigbeeChannel): "Attribute report '%s'[%s] = %s", self.cluster.name, attr_name, value ) if attrid == self._value_attribute: - self.async_send_signal(f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", value) + self.async_send_signal( + f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", attrid, attr_name, value + ) async def async_initialize(self, from_cache): """Initialize channel.""" diff --git a/homeassistant/components/zha/core/channels/general.py b/homeassistant/components/zha/core/channels/general.py index 28bc9c7d763..aa2ddd44bf3 100644 --- a/homeassistant/components/zha/core/channels/general.py +++ b/homeassistant/components/zha/core/channels/general.py @@ -18,7 +18,7 @@ from ..const import ( SIGNAL_STATE_ATTR, ) from ..helpers import get_attr_id_by_name -from .base import AttributeListeningChannel, ZigbeeChannel, parse_and_log_command +from .base import ZigbeeChannel, parse_and_log_command _LOGGER = logging.getLogger(__name__) @@ -31,21 +31,21 @@ class Alarms(ZigbeeChannel): @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.AnalogInput.cluster_id) -class AnalogInput(AttributeListeningChannel): +class AnalogInput(ZigbeeChannel): """Analog Input channel.""" REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.AnalogOutput.cluster_id) -class AnalogOutput(AttributeListeningChannel): +class AnalogOutput(ZigbeeChannel): """Analog Output channel.""" REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.AnalogValue.cluster_id) -class AnalogValue(AttributeListeningChannel): +class AnalogValue(ZigbeeChannel): """Analog Value channel.""" REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] @@ -77,7 +77,7 @@ class BasicChannel(ZigbeeChannel): } def __init__( - self, cluster: zha_typing.ZigpyClusterType, ch_pool: zha_typing.ChannelPoolType, + self, cluster: zha_typing.ZigpyClusterType, ch_pool: zha_typing.ChannelPoolType ) -> None: """Initialize BasicChannel.""" super().__init__(cluster, ch_pool) @@ -101,21 +101,21 @@ class BasicChannel(ZigbeeChannel): @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.BinaryInput.cluster_id) -class BinaryInput(AttributeListeningChannel): +class BinaryInput(ZigbeeChannel): """Binary Input channel.""" REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.BinaryOutput.cluster_id) -class BinaryOutput(AttributeListeningChannel): +class BinaryOutput(ZigbeeChannel): """Binary Output channel.""" REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.BinaryValue.cluster_id) -class BinaryValue(AttributeListeningChannel): +class BinaryValue(ZigbeeChannel): """Binary Value channel.""" REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] @@ -209,21 +209,21 @@ class LevelControlChannel(ZigbeeChannel): @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.MultistateInput.cluster_id) -class MultistateInput(AttributeListeningChannel): +class MultistateInput(ZigbeeChannel): """Multistate Input channel.""" REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.MultistateOutput.cluster_id) -class MultistateOutput(AttributeListeningChannel): +class MultistateOutput(ZigbeeChannel): """Multistate Output channel.""" REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.MultistateValue.cluster_id) -class MultistateValue(AttributeListeningChannel): +class MultistateValue(ZigbeeChannel): """Multistate Value channel.""" REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] @@ -242,7 +242,7 @@ class OnOffChannel(ZigbeeChannel): REPORT_CONFIG = ({"attr": "on_off", "config": REPORT_CONFIG_IMMEDIATE},) def __init__( - self, cluster: zha_typing.ZigpyClusterType, ch_pool: zha_typing.ChannelPoolType, + self, cluster: zha_typing.ZigpyClusterType, ch_pool: zha_typing.ChannelPoolType ) -> None: """Initialize OnOffChannel.""" super().__init__(cluster, ch_pool) @@ -286,7 +286,9 @@ class OnOffChannel(ZigbeeChannel): def attribute_updated(self, attrid, value): """Handle attribute updates on this cluster.""" if attrid == self.ON_OFF: - self.async_send_signal(f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", value) + self.async_send_signal( + f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", attrid, "on_off", value + ) self._state = bool(value) async def async_initialize(self, from_cache): @@ -354,7 +356,12 @@ class PowerConfigurationChannel(ZigbeeChannel): else: attr_id = attr if attrid == attr_id: - self.async_send_signal(f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", value) + self.async_send_signal( + f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", + attrid, + self.cluster.attributes.get(attrid, [attrid])[0], + value, + ) return attr_name = self.cluster.attributes.get(attrid, [attrid])[0] self.async_send_signal( diff --git a/homeassistant/components/zha/core/channels/homeautomation.py b/homeassistant/components/zha/core/channels/homeautomation.py index e47aca5eafd..d4c1a1b7422 100644 --- a/homeassistant/components/zha/core/channels/homeautomation.py +++ b/homeassistant/components/zha/core/channels/homeautomation.py @@ -10,7 +10,7 @@ from ..const import ( REPORT_CONFIG_DEFAULT, SIGNAL_ATTR_UPDATED, ) -from .base import AttributeListeningChannel, ZigbeeChannel +from .base import ZigbeeChannel _LOGGER = logging.getLogger(__name__) @@ -52,7 +52,7 @@ class Diagnostic(ZigbeeChannel): @registries.ZIGBEE_CHANNEL_REGISTRY.register( homeautomation.ElectricalMeasurement.cluster_id ) -class ElectricalMeasurementChannel(AttributeListeningChannel): +class ElectricalMeasurementChannel(ZigbeeChannel): """Channel that polls active power level.""" CHANNEL_NAME = CHANNEL_ELECTRICAL_MEASUREMENT @@ -60,7 +60,7 @@ class ElectricalMeasurementChannel(AttributeListeningChannel): REPORT_CONFIG = ({"attr": "active_power", "config": REPORT_CONFIG_DEFAULT},) def __init__( - self, cluster: zha_typing.ZigpyClusterType, ch_pool: zha_typing.ChannelPoolType, + self, cluster: zha_typing.ZigpyClusterType, ch_pool: zha_typing.ChannelPoolType ) -> None: """Initialize Metering.""" super().__init__(cluster, ch_pool) @@ -73,7 +73,9 @@ class ElectricalMeasurementChannel(AttributeListeningChannel): # This is a polling channel. Don't allow cache. result = await self.get_attribute_value("active_power", from_cache=False) - self.async_send_signal(f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", result) + self.async_send_signal( + f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", 0x050B, "active_power", result + ) async def async_initialize(self, from_cache): """Initialize channel.""" diff --git a/homeassistant/components/zha/core/channels/hvac.py b/homeassistant/components/zha/core/channels/hvac.py index e4519d5cb2c..6d5ce4beb29 100644 --- a/homeassistant/components/zha/core/channels/hvac.py +++ b/homeassistant/components/zha/core/channels/hvac.py @@ -40,8 +40,9 @@ class FanChannel(ZigbeeChannel): async def async_update(self): """Retrieve latest state.""" result = await self.get_attribute_value("fan_mode", from_cache=True) - - self.async_send_signal(f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", result) + self.async_send_signal( + f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", 0, "fan_mode", result + ) @callback def attribute_updated(self, attrid, value): @@ -51,7 +52,9 @@ class FanChannel(ZigbeeChannel): "Attribute report '%s'[%s] = %s", self.cluster.name, attr_name, value ) if attrid == self._value_attribute: - self.async_send_signal(f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", value) + self.async_send_signal( + f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", attrid, attr_name, value + ) async def async_initialize(self, from_cache): """Initialize channel.""" diff --git a/homeassistant/components/zha/core/channels/manufacturerspecific.py b/homeassistant/components/zha/core/channels/manufacturerspecific.py index 2f30421822c..208bc8f8836 100644 --- a/homeassistant/components/zha/core/channels/manufacturerspecific.py +++ b/homeassistant/components/zha/core/channels/manufacturerspecific.py @@ -14,13 +14,13 @@ from ..const import ( SIGNAL_ATTR_UPDATED, UNKNOWN, ) -from .base import AttributeListeningChannel, ZigbeeChannel +from .base import ZigbeeChannel _LOGGER = logging.getLogger(__name__) @registries.ZIGBEE_CHANNEL_REGISTRY.register(registries.SMARTTHINGS_HUMIDITY_CLUSTER) -class SmartThingsHumidity(AttributeListeningChannel): +class SmartThingsHumidity(ZigbeeChannel): """Smart Things Humidity channel.""" REPORT_CONFIG = [ @@ -50,7 +50,7 @@ class OppleRemote(ZigbeeChannel): @registries.ZIGBEE_CHANNEL_REGISTRY.register( registries.SMARTTHINGS_ACCELERATION_CLUSTER ) -class SmartThingsAcceleration(AttributeListeningChannel): +class SmartThingsAcceleration(ZigbeeChannel): """Smart Things Acceleration channel.""" REPORT_CONFIG = [ @@ -64,7 +64,12 @@ class SmartThingsAcceleration(AttributeListeningChannel): def attribute_updated(self, attrid, value): """Handle attribute updates on this cluster.""" if attrid == self.value_attribute: - self.async_send_signal(f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", value) + self.async_send_signal( + f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", + attrid, + self._cluster.attributes.get(attrid, [UNKNOWN])[0], + value, + ) return self.zha_send_event( diff --git a/homeassistant/components/zha/core/channels/measurement.py b/homeassistant/components/zha/core/channels/measurement.py index 68952c64e8d..f05177de600 100644 --- a/homeassistant/components/zha/core/channels/measurement.py +++ b/homeassistant/components/zha/core/channels/measurement.py @@ -10,13 +10,13 @@ from ..const import ( REPORT_CONFIG_MAX_INT, REPORT_CONFIG_MIN_INT, ) -from .base import AttributeListeningChannel +from .base import ZigbeeChannel _LOGGER = logging.getLogger(__name__) @registries.ZIGBEE_CHANNEL_REGISTRY.register(measurement.FlowMeasurement.cluster_id) -class FlowMeasurement(AttributeListeningChannel): +class FlowMeasurement(ZigbeeChannel): """Flow Measurement channel.""" REPORT_CONFIG = [{"attr": "measured_value", "config": REPORT_CONFIG_DEFAULT}] @@ -25,7 +25,7 @@ class FlowMeasurement(AttributeListeningChannel): @registries.ZIGBEE_CHANNEL_REGISTRY.register( measurement.IlluminanceLevelSensing.cluster_id ) -class IlluminanceLevelSensing(AttributeListeningChannel): +class IlluminanceLevelSensing(ZigbeeChannel): """Illuminance Level Sensing channel.""" REPORT_CONFIG = [{"attr": "level_status", "config": REPORT_CONFIG_DEFAULT}] @@ -34,7 +34,7 @@ class IlluminanceLevelSensing(AttributeListeningChannel): @registries.ZIGBEE_CHANNEL_REGISTRY.register( measurement.IlluminanceMeasurement.cluster_id ) -class IlluminanceMeasurement(AttributeListeningChannel): +class IlluminanceMeasurement(ZigbeeChannel): """Illuminance Measurement channel.""" REPORT_CONFIG = [{"attr": "measured_value", "config": REPORT_CONFIG_DEFAULT}] @@ -42,21 +42,21 @@ class IlluminanceMeasurement(AttributeListeningChannel): @registries.BINARY_SENSOR_CLUSTERS.register(measurement.OccupancySensing.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(measurement.OccupancySensing.cluster_id) -class OccupancySensing(AttributeListeningChannel): +class OccupancySensing(ZigbeeChannel): """Occupancy Sensing channel.""" REPORT_CONFIG = [{"attr": "occupancy", "config": REPORT_CONFIG_IMMEDIATE}] @registries.ZIGBEE_CHANNEL_REGISTRY.register(measurement.PressureMeasurement.cluster_id) -class PressureMeasurement(AttributeListeningChannel): +class PressureMeasurement(ZigbeeChannel): """Pressure measurement channel.""" REPORT_CONFIG = [{"attr": "measured_value", "config": REPORT_CONFIG_DEFAULT}] @registries.ZIGBEE_CHANNEL_REGISTRY.register(measurement.RelativeHumidity.cluster_id) -class RelativeHumidity(AttributeListeningChannel): +class RelativeHumidity(ZigbeeChannel): """Relative Humidity measurement channel.""" REPORT_CONFIG = [ @@ -70,7 +70,7 @@ class RelativeHumidity(AttributeListeningChannel): @registries.ZIGBEE_CHANNEL_REGISTRY.register( measurement.TemperatureMeasurement.cluster_id ) -class TemperatureMeasurement(AttributeListeningChannel): +class TemperatureMeasurement(ZigbeeChannel): """Temperature measurement channel.""" REPORT_CONFIG = [ diff --git a/homeassistant/components/zha/core/channels/security.py b/homeassistant/components/zha/core/channels/security.py index 20390c018d8..cd826792790 100644 --- a/homeassistant/components/zha/core/channels/security.py +++ b/homeassistant/components/zha/core/channels/security.py @@ -124,7 +124,9 @@ class IASZoneChannel(ZigbeeChannel): """Handle commands received to this cluster.""" if command_id == 0: state = args[0] & 3 - self.async_send_signal(f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", state) + self.async_send_signal( + f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", 2, "zone_status", state + ) self.debug("Updated alarm state: %s", state) elif command_id == 1: self.debug("Enroll requested") @@ -165,7 +167,12 @@ class IASZoneChannel(ZigbeeChannel): """Handle attribute updates on this cluster.""" if attrid == 2: value = value & 3 - self.async_send_signal(f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", value) + self.async_send_signal( + f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}", + attrid, + self.cluster.attributes.get(attrid, [attrid])[0], + value, + ) async def async_initialize(self, from_cache): """Initialize channel.""" diff --git a/homeassistant/components/zha/core/channels/smartenergy.py b/homeassistant/components/zha/core/channels/smartenergy.py index c7cad5e455d..86533662838 100644 --- a/homeassistant/components/zha/core/channels/smartenergy.py +++ b/homeassistant/components/zha/core/channels/smartenergy.py @@ -8,7 +8,7 @@ from homeassistant.core import callback from .. import registries, typing as zha_typing from ..const import REPORT_CONFIG_DEFAULT -from .base import AttributeListeningChannel, ZigbeeChannel +from .base import ZigbeeChannel _LOGGER = logging.getLogger(__name__) @@ -70,7 +70,7 @@ class Messaging(ZigbeeChannel): @registries.ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Metering.cluster_id) -class Metering(AttributeListeningChannel): +class Metering(ZigbeeChannel): """Metering channel.""" REPORT_CONFIG = [{"attr": "instantaneous_demand", "config": REPORT_CONFIG_DEFAULT}] @@ -92,7 +92,7 @@ class Metering(AttributeListeningChannel): } def __init__( - self, cluster: zha_typing.ZigpyClusterType, ch_pool: zha_typing.ChannelPoolType, + self, cluster: zha_typing.ZigpyClusterType, ch_pool: zha_typing.ChannelPoolType ) -> None: """Initialize Metering.""" super().__init__(cluster, ch_pool) diff --git a/homeassistant/components/zha/core/discovery.py b/homeassistant/components/zha/core/discovery.py index e6b844b9c43..b60357cf9f3 100644 --- a/homeassistant/components/zha/core/discovery.py +++ b/homeassistant/components/zha/core/discovery.py @@ -134,7 +134,7 @@ class ProbeEndpoint: continue channel_class = zha_regs.ZIGBEE_CHANNEL_REGISTRY.get( - cluster_id, base.AttributeListeningChannel + cluster_id, base.ZigbeeChannel ) channel = channel_class(cluster, ep_channels) self.probe_single_cluster(component, channel, ep_channels) diff --git a/homeassistant/components/zha/cover.py b/homeassistant/components/zha/cover.py index 13de445cf37..46c97bc6b2b 100644 --- a/homeassistant/components/zha/cover.py +++ b/homeassistant/components/zha/cover.py @@ -91,10 +91,10 @@ class ZhaCover(ZhaEntity, CoverDevice): return self._current_position @callback - def async_set_position(self, pos): + def async_set_position(self, attr_id, attr_name, value): """Handle position update from channel.""" - _LOGGER.debug("setting position: %s", pos) - self._current_position = 100 - pos + _LOGGER.debug("setting position: %s", value) + self._current_position = 100 - value if self._current_position == 0: self._state = STATE_CLOSED elif self._current_position == 100: @@ -102,7 +102,7 @@ class ZhaCover(ZhaEntity, CoverDevice): self.async_schedule_update_ha_state() @callback - def async_set_state(self, state): + def async_update_state(self, state): """Handle state update from channel.""" _LOGGER.debug("state=%s", state) self._state = state @@ -112,20 +112,20 @@ class ZhaCover(ZhaEntity, CoverDevice): """Open the window cover.""" res = await self._cover_channel.up_open() if isinstance(res, list) and res[1] is Status.SUCCESS: - self.async_set_state(STATE_OPENING) + self.async_update_state(STATE_OPENING) async def async_close_cover(self, **kwargs): """Close the window cover.""" res = await self._cover_channel.down_close() if isinstance(res, list) and res[1] is Status.SUCCESS: - self.async_set_state(STATE_CLOSING) + self.async_update_state(STATE_CLOSING) async def async_set_cover_position(self, **kwargs): """Move the roller shutter to a specific position.""" new_pos = kwargs[ATTR_POSITION] res = await self._cover_channel.go_to_lift_percentage(100 - new_pos) if isinstance(res, list) and res[1] is Status.SUCCESS: - self.async_set_state( + self.async_update_state( STATE_CLOSING if new_pos < self._current_position else STATE_OPENING ) diff --git a/homeassistant/components/zha/device_tracker.py b/homeassistant/components/zha/device_tracker.py index 5481ec70f52..2643642c47d 100644 --- a/homeassistant/components/zha/device_tracker.py +++ b/homeassistant/components/zha/device_tracker.py @@ -83,8 +83,10 @@ class ZHADeviceScannerEntity(ScannerEntity, ZhaEntity): return SOURCE_TYPE_ROUTER @callback - def async_battery_percentage_remaining_updated(self, value): + def async_battery_percentage_remaining_updated(self, attr_id, attr_name, value): """Handle tracking.""" + if not attr_name == "battery_percentage_remaining": + return self.debug("battery_percentage_remaining updated: %s", value) self._connected = True self._battery_level = Battery.formatter(value) diff --git a/homeassistant/components/zha/entity.py b/homeassistant/components/zha/entity.py index 76d0908000b..799e1239f61 100644 --- a/homeassistant/components/zha/entity.py +++ b/homeassistant/components/zha/entity.py @@ -111,7 +111,7 @@ class ZhaEntity(RestoreEntity, LogMixin, entity.Entity): self.async_schedule_update_ha_state() @callback - def async_set_state(self, state): + def async_set_state(self, attr_id, attr_name, value): """Set the entity state.""" pass diff --git a/homeassistant/components/zha/fan.py b/homeassistant/components/zha/fan.py index 59a6bfb9c47..79b3bc62960 100644 --- a/homeassistant/components/zha/fan.py +++ b/homeassistant/components/zha/fan.py @@ -114,9 +114,9 @@ class ZhaFan(ZhaEntity, FanEntity): return self.state_attributes @callback - def async_set_state(self, state): + def async_set_state(self, attr_id, attr_name, value): """Handle state update from channel.""" - self._state = VALUE_TO_SPEED.get(state, self._state) + self._state = VALUE_TO_SPEED.get(value, self._state) self.async_schedule_update_ha_state() async def async_turn_on(self, speed: str = None, **kwargs) -> None: @@ -133,7 +133,7 @@ class ZhaFan(ZhaEntity, FanEntity): async def async_set_speed(self, speed: str) -> None: """Set the speed of the fan.""" await self._fan_channel.async_set_speed(SPEED_TO_VALUE[speed]) - self.async_set_state(speed) + self.async_set_state(0, "fan_mode", speed) async def async_update(self): """Attempt to retrieve on off state from the fan.""" diff --git a/homeassistant/components/zha/light.py b/homeassistant/components/zha/light.py index 4264fded26b..68032001816 100644 --- a/homeassistant/components/zha/light.py +++ b/homeassistant/components/zha/light.py @@ -155,10 +155,10 @@ class Light(ZhaEntity, light.Light): return self._supported_features @callback - def async_set_state(self, state): + def async_set_state(self, attr_id, attr_name, value): """Set the state.""" - self._state = bool(state) - if state: + self._state = bool(value) + if value: self._off_brightness = None self.async_schedule_update_ha_state() diff --git a/homeassistant/components/zha/lock.py b/homeassistant/components/zha/lock.py index 7ba31158fc3..a7f360b3424 100644 --- a/homeassistant/components/zha/lock.py +++ b/homeassistant/components/zha/lock.py @@ -103,9 +103,9 @@ class ZhaDoorLock(ZhaEntity, LockDevice): await self.async_get_state() @callback - def async_set_state(self, state): + def async_set_state(self, attr_id, attr_name, value): """Handle state update from channel.""" - self._state = VALUE_TO_STATE.get(state, self._state) + self._state = VALUE_TO_STATE.get(value, self._state) self.async_schedule_update_ha_state() async def async_get_state(self, from_cache=True): diff --git a/homeassistant/components/zha/sensor.py b/homeassistant/components/zha/sensor.py index e4788acfc53..01298a40fca 100644 --- a/homeassistant/components/zha/sensor.py +++ b/homeassistant/components/zha/sensor.py @@ -124,11 +124,11 @@ class Sensor(ZhaEntity): return self._state @callback - def async_set_state(self, state): + def async_set_state(self, attr_id, attr_name, value): """Handle state update from channel.""" - if state is not None: - state = self.formatter(state) - self._state = state + if value is not None: + value = self.formatter(value) + self._state = value self.async_schedule_update_ha_state() @callback diff --git a/homeassistant/components/zha/switch.py b/homeassistant/components/zha/switch.py index e6a82fe0270..15e10b50393 100644 --- a/homeassistant/components/zha/switch.py +++ b/homeassistant/components/zha/switch.py @@ -71,9 +71,9 @@ class Switch(ZhaEntity, SwitchDevice): self.async_schedule_update_ha_state() @callback - def async_set_state(self, state): + def async_set_state(self, attr_id, attr_name, value): """Handle state update from channel.""" - self._state = bool(state) + self._state = bool(value) self.async_schedule_update_ha_state() @property diff --git a/tests/components/zha/test_channels.py b/tests/components/zha/test_channels.py index 3f38108cf89..9eac267273b 100644 --- a/tests/components/zha/test_channels.py +++ b/tests/components/zha/test_channels.py @@ -98,7 +98,7 @@ async def test_in_channel_config( cluster = zigpy_dev.endpoints[1].in_clusters[cluster_id] channel_class = registries.ZIGBEE_CHANNEL_REGISTRY.get( - cluster_id, base_channels.AttributeListeningChannel + cluster_id, base_channels.ZigbeeChannel ) channel = channel_class(cluster, channel_pool) @@ -156,7 +156,7 @@ async def test_out_channel_config( cluster = zigpy_dev.endpoints[1].out_clusters[cluster_id] cluster.bind_only = True channel_class = registries.ZIGBEE_CHANNEL_REGISTRY.get( - cluster_id, base_channels.AttributeListeningChannel + cluster_id, base_channels.ZigbeeChannel ) channel = channel_class(cluster, channel_pool)