Skip to content

Commit

Permalink
Remove ZHA attribute listening channel (home-assistant#32468)
Browse files Browse the repository at this point in the history
* remove AttributeListeningChannel
* pull sleeps
* update signature to fix pylint
  • Loading branch information
Adminiuga authored Mar 4, 2020
1 parent 7f91501 commit 2033370
Show file tree
Hide file tree
Showing 21 changed files with 124 additions and 108 deletions.
4 changes: 2 additions & 2 deletions homeassistant/components/zha/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ def device_class(self) -> str:
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):
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/zha/core/channels/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,15 +235,15 @@ def add_all_channels(self) -> None:
"""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.
if (
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:
Expand Down
50 changes: 15 additions & 35 deletions homeassistant/components/zha/core/channels/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from enum import Enum
from functools import wraps
import logging
from random import uniform
from typing import Any, Union

import zigpy.exceptions
Expand All @@ -22,7 +21,6 @@
ATTR_VALUE,
CHANNEL_EVENT_RELAY,
CHANNEL_ZDO,
REPORT_CONFIG_DEFAULT,
REPORT_CONFIG_MAX_INT,
REPORT_CONFIG_MIN_INT,
REPORT_CONFIG_RPT_CHANGE,
Expand Down Expand Up @@ -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
Expand All @@ -97,6 +95,12 @@ def __init__(
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)

Expand Down Expand Up @@ -200,7 +204,6 @@ async def async_configure(self):
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")
Expand All @@ -209,6 +212,8 @@ async def async_configure(self):
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
Expand All @@ -219,7 +224,12 @@ def cluster_command(self, tsn, command_id, args):
@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):
Expand Down Expand Up @@ -272,36 +282,6 @@ def __getattr__(self, name):
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."""

Expand Down
20 changes: 15 additions & 5 deletions homeassistant/components/zha/core/channels/closures.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ async def async_update(self):
"""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):
Expand All @@ -33,7 +35,9 @@ def attribute_updated(self, attrid, value):
"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."""
Expand Down Expand Up @@ -63,8 +67,12 @@ async def async_update(self):
"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):
Expand All @@ -74,7 +82,9 @@ def attribute_updated(self, attrid, value):
"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."""
Expand Down
35 changes: 21 additions & 14 deletions homeassistant/components/zha/core/channels/general.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
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__)

Expand All @@ -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}]
Expand Down Expand Up @@ -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)
Expand All @@ -101,21 +101,21 @@ def get_power_source(self):


@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}]
Expand Down Expand Up @@ -209,21 +209,21 @@ async def async_initialize(self, from_cache):


@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}]
Expand All @@ -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)
Expand Down Expand Up @@ -286,7 +286,9 @@ def set_to_off(self, *_):
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):
Expand Down Expand Up @@ -354,7 +356,12 @@ def attribute_updated(self, attrid, value):
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(
Expand Down
10 changes: 6 additions & 4 deletions homeassistant/components/zha/core/channels/homeautomation.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
REPORT_CONFIG_DEFAULT,
SIGNAL_ATTR_UPDATED,
)
from .base import AttributeListeningChannel, ZigbeeChannel
from .base import ZigbeeChannel

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -52,15 +52,15 @@ 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

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)
Expand All @@ -73,7 +73,9 @@ async def async_update(self):

# 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."""
Expand Down
9 changes: 6 additions & 3 deletions homeassistant/components/zha/core/channels/hvac.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ async def async_set_speed(self, value) -> None:
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):
Expand All @@ -51,7 +52,9 @@ def attribute_updated(self, attrid, value):
"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."""
Expand Down
Loading

0 comments on commit 2033370

Please sign in to comment.