mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Refactor ZHA EventChannels (#32709)
* Refactor EventChannels. * Rename EventRelayChannel. * Fully rename EventRelayChannel. - update docstrings - rename all references from "relay" to "client" * Remove CHANNEL_NAME. * Update stale docstring.
This commit is contained in:
parent
d5e606640c
commit
991afccbd4
@ -163,12 +163,12 @@ class ChannelPool:
|
||||
self._channels: Channels = channels
|
||||
self._claimed_channels: ChannelsDict = {}
|
||||
self._id: int = ep_id
|
||||
self._relay_channels: Dict[str, zha_typing.EventRelayChannelType] = {}
|
||||
self._client_channels: Dict[str, zha_typing.ClientChannelType] = {}
|
||||
self._unique_id: str = f"{channels.unique_id}-{ep_id}"
|
||||
|
||||
@property
|
||||
def all_channels(self) -> ChannelsDict:
|
||||
"""All channels of an endpoint."""
|
||||
"""All server channels of an endpoint."""
|
||||
return self._all_channels
|
||||
|
||||
@property
|
||||
@ -176,6 +176,11 @@ class ChannelPool:
|
||||
"""Channels in use."""
|
||||
return self._claimed_channels
|
||||
|
||||
@property
|
||||
def client_channels(self) -> Dict[str, zha_typing.ClientChannelType]:
|
||||
"""Return a dict of client channels."""
|
||||
return self._client_channels
|
||||
|
||||
@property
|
||||
def endpoint(self) -> zha_typing.ZigpyEndpointType:
|
||||
"""Return endpoint of zigpy device."""
|
||||
@ -216,11 +221,6 @@ class ChannelPool:
|
||||
"""Return device model."""
|
||||
return self._channels.zha_device.model
|
||||
|
||||
@property
|
||||
def relay_channels(self) -> Dict[str, zha_typing.EventRelayChannelType]:
|
||||
"""Return a dict of event relay channels."""
|
||||
return self._relay_channels
|
||||
|
||||
@property
|
||||
def skip_configuration(self) -> bool:
|
||||
"""Return True if device does not require channel configuration."""
|
||||
@ -236,7 +236,7 @@ class ChannelPool:
|
||||
"""Create new channels for an endpoint."""
|
||||
pool = cls(channels, ep_id)
|
||||
pool.add_all_channels()
|
||||
pool.add_relay_channels()
|
||||
pool.add_client_channels()
|
||||
zha_disc.PROBE.discover_entities(pool)
|
||||
return pool
|
||||
|
||||
@ -270,13 +270,13 @@ class ChannelPool:
|
||||
self.all_channels[channel.id] = channel
|
||||
|
||||
@callback
|
||||
def add_relay_channels(self) -> None:
|
||||
"""Create relay channels for all output clusters if in the registry."""
|
||||
for cluster_id in zha_regs.EVENT_RELAY_CLUSTERS:
|
||||
def add_client_channels(self) -> None:
|
||||
"""Create client channels for all output clusters if in the registry."""
|
||||
for cluster_id, channel_class in zha_regs.CLIENT_CHANNELS_REGISTRY.items():
|
||||
cluster = self.endpoint.out_clusters.get(cluster_id)
|
||||
if cluster is not None:
|
||||
channel = base.EventRelayChannel(cluster, self)
|
||||
self.relay_channels[channel.id] = channel
|
||||
channel = channel_class(cluster, self)
|
||||
self.client_channels[channel.id] = channel
|
||||
|
||||
async def async_initialize(self, from_cache: bool = False) -> None:
|
||||
"""Initialize claimed channels."""
|
||||
@ -293,7 +293,7 @@ class ChannelPool:
|
||||
async with self._channels.semaphore:
|
||||
return await coro
|
||||
|
||||
channels = [*self.claimed_channels.values(), *self.relay_channels.values()]
|
||||
channels = [*self.claimed_channels.values(), *self.client_channels.values()]
|
||||
tasks = [_throttle(getattr(ch, func_name)(*args)) for ch in channels]
|
||||
results = await asyncio.gather(*tasks, return_exceptions=True)
|
||||
for channel, outcome in zip(channels, results):
|
||||
|
@ -19,7 +19,6 @@ from ..const import (
|
||||
ATTR_COMMAND,
|
||||
ATTR_UNIQUE_ID,
|
||||
ATTR_VALUE,
|
||||
CHANNEL_EVENT_RELAY,
|
||||
CHANNEL_ZDO,
|
||||
REPORT_CONFIG_MAX_INT,
|
||||
REPORT_CONFIG_MIN_INT,
|
||||
@ -78,7 +77,6 @@ class ChannelStatus(Enum):
|
||||
class ZigbeeChannel(LogMixin):
|
||||
"""Base channel for a Zigbee cluster."""
|
||||
|
||||
CHANNEL_NAME = None
|
||||
REPORT_CONFIG = ()
|
||||
|
||||
def __init__(
|
||||
@ -87,8 +85,6 @@ class ZigbeeChannel(LogMixin):
|
||||
"""Initialize ZigbeeChannel."""
|
||||
self._generic_id = f"channel_0x{cluster.cluster_id:04x}"
|
||||
self._channel_name = getattr(cluster, "ep_attribute", self._generic_id)
|
||||
if self.CHANNEL_NAME:
|
||||
self._channel_name = self.CHANNEL_NAME
|
||||
self._ch_pool = ch_pool
|
||||
self._cluster = cluster
|
||||
self._id = f"{ch_pool.id}:0x{cluster.cluster_id:04x}"
|
||||
@ -361,10 +357,8 @@ class ZDOChannel(LogMixin):
|
||||
_LOGGER.log(level, msg, *args)
|
||||
|
||||
|
||||
class EventRelayChannel(ZigbeeChannel):
|
||||
"""Event relay that can be attached to zigbee clusters."""
|
||||
|
||||
CHANNEL_NAME = CHANNEL_EVENT_RELAY
|
||||
class ClientChannel(ZigbeeChannel):
|
||||
"""Channel listener for Zigbee client (output) clusters."""
|
||||
|
||||
@callback
|
||||
def attribute_updated(self, attrid, value):
|
||||
|
@ -20,7 +20,7 @@ from ..const import (
|
||||
SIGNAL_SET_LEVEL,
|
||||
SIGNAL_STATE_ATTR,
|
||||
)
|
||||
from .base import ZigbeeChannel, parse_and_log_command
|
||||
from .base import ClientChannel, ZigbeeChannel, parse_and_log_command
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -166,8 +166,14 @@ class Identify(ZigbeeChannel):
|
||||
self.async_send_signal(f"{self.unique_id}_{cmd}", args[0])
|
||||
|
||||
|
||||
@registries.CLIENT_CHANNELS_REGISTRY.register(general.LevelControl.cluster_id)
|
||||
class LevelControlClientChannel(ClientChannel):
|
||||
"""LevelControl client cluster."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@registries.BINDABLE_CLUSTERS.register(general.LevelControl.cluster_id)
|
||||
@registries.EVENT_RELAY_CLUSTERS.register(general.LevelControl.cluster_id)
|
||||
@registries.LIGHT_CLUSTERS.register(general.LevelControl.cluster_id)
|
||||
@registries.ZIGBEE_CHANNEL_REGISTRY.register(general.LevelControl.cluster_id)
|
||||
class LevelControlChannel(ZigbeeChannel):
|
||||
@ -233,9 +239,15 @@ class MultistateValue(ZigbeeChannel):
|
||||
REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}]
|
||||
|
||||
|
||||
@registries.CLIENT_CHANNELS_REGISTRY.register(general.OnOff.cluster_id)
|
||||
class OnOffClientChannel(ClientChannel):
|
||||
"""OnOff client channel."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@registries.BINARY_SENSOR_CLUSTERS.register(general.OnOff.cluster_id)
|
||||
@registries.BINDABLE_CLUSTERS.register(general.OnOff.cluster_id)
|
||||
@registries.EVENT_RELAY_CLUSTERS.register(general.OnOff.cluster_id)
|
||||
@registries.LIGHT_CLUSTERS.register(general.OnOff.cluster_id)
|
||||
@registries.SWITCH_CLUSTERS.register(general.OnOff.cluster_id)
|
||||
@registries.ZIGBEE_CHANNEL_REGISTRY.register(general.OnOff.cluster_id)
|
||||
@ -437,7 +449,13 @@ class RSSILocation(ZigbeeChannel):
|
||||
pass
|
||||
|
||||
|
||||
@registries.EVENT_RELAY_CLUSTERS.register(general.Scenes.cluster_id)
|
||||
@registries.CLIENT_CHANNELS_REGISTRY.register(general.Scenes.cluster_id)
|
||||
class ScenesClientChannel(ClientChannel):
|
||||
"""Scenes channel."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@registries.ZIGBEE_CHANNEL_REGISTRY.register(general.Scenes.cluster_id)
|
||||
class Scenes(ZigbeeChannel):
|
||||
"""Scenes channel."""
|
||||
|
@ -5,7 +5,7 @@ import zigpy.zcl.clusters.lighting as lighting
|
||||
|
||||
from .. import registries, typing as zha_typing
|
||||
from ..const import REPORT_CONFIG_DEFAULT
|
||||
from .base import ZigbeeChannel
|
||||
from .base import ClientChannel, ZigbeeChannel
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -17,8 +17,14 @@ class Ballast(ZigbeeChannel):
|
||||
pass
|
||||
|
||||
|
||||
@registries.CLIENT_CHANNELS_REGISTRY.register(lighting.Color.cluster_id)
|
||||
class ColorClientChannel(ClientChannel):
|
||||
"""Color client channel."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@registries.BINDABLE_CLUSTERS.register(lighting.Color.cluster_id)
|
||||
@registries.EVENT_RELAY_CLUSTERS.register(lighting.Color.cluster_id)
|
||||
@registries.LIGHT_CLUSTERS.register(lighting.Color.cluster_id)
|
||||
@registries.ZIGBEE_CHANNEL_REGISTRY.register(lighting.Color.cluster_id)
|
||||
class ColorChannel(ZigbeeChannel):
|
||||
|
@ -123,9 +123,9 @@ DEVICE_CLASS = {
|
||||
DEVICE_CLASS = collections.defaultdict(dict, DEVICE_CLASS)
|
||||
|
||||
DEVICE_TRACKER_CLUSTERS = SetRegistry()
|
||||
EVENT_RELAY_CLUSTERS = SetRegistry()
|
||||
LIGHT_CLUSTERS = SetRegistry()
|
||||
OUTPUT_CHANNEL_ONLY_CLUSTERS = SetRegistry()
|
||||
CLIENT_CHANNELS_REGISTRY = DictRegistry()
|
||||
|
||||
RADIO_TYPES = {
|
||||
RadioType.deconz.name: {
|
||||
|
@ -12,7 +12,7 @@ CALLABLE_T = TypeVar("CALLABLE_T", bound=Callable)
|
||||
ChannelType = "ZigbeeChannel"
|
||||
ChannelsType = "Channels"
|
||||
ChannelPoolType = "ChannelPool"
|
||||
EventRelayChannelType = "EventRelayChannel"
|
||||
ClientChannelType = "ClientChannel"
|
||||
ZDOChannelType = "ZDOChannel"
|
||||
ZhaDeviceType = "ZHADevice"
|
||||
ZhaEntityType = "ZHAEntity"
|
||||
@ -33,7 +33,7 @@ if TYPE_CHECKING:
|
||||
ChannelType = base_channels.ZigbeeChannel
|
||||
ChannelsType = channels.Channels
|
||||
ChannelPoolType = channels.ChannelPool
|
||||
EventRelayChannelType = base_channels.EventRelayChannel
|
||||
ClientChannelType = base_channels.ClientChannel
|
||||
ZDOChannelType = base_channels.ZDOChannel
|
||||
ZhaDeviceType = homeassistant.components.zha.core.device.ZHADevice
|
||||
ZhaEntityType = homeassistant.components.zha.entity.ZhaEntity
|
||||
|
@ -274,7 +274,9 @@ def test_epch_claim_channels(channel):
|
||||
assert "1:0x0300" in ep_channels.claimed_channels
|
||||
|
||||
|
||||
@mock.patch("homeassistant.components.zha.core.channels.ChannelPool.add_relay_channels")
|
||||
@mock.patch(
|
||||
"homeassistant.components.zha.core.channels.ChannelPool.add_client_channels"
|
||||
)
|
||||
@mock.patch(
|
||||
"homeassistant.components.zha.core.discovery.PROBE.discover_entities",
|
||||
mock.MagicMock(),
|
||||
@ -319,7 +321,9 @@ def test_ep_channels_all_channels(m1, zha_device_mock):
|
||||
assert "2:0x0300" in ep_channels.all_channels
|
||||
|
||||
|
||||
@mock.patch("homeassistant.components.zha.core.channels.ChannelPool.add_relay_channels")
|
||||
@mock.patch(
|
||||
"homeassistant.components.zha.core.channels.ChannelPool.add_client_channels"
|
||||
)
|
||||
@mock.patch(
|
||||
"homeassistant.components.zha.core.discovery.PROBE.discover_entities",
|
||||
mock.MagicMock(),
|
||||
@ -387,14 +391,14 @@ async def test_ep_channels_configure(channel):
|
||||
ep_channels = zha_channels.ChannelPool(channels, mock.sentinel.ep)
|
||||
|
||||
claimed = {ch_1.id: ch_1, ch_2.id: ch_2, ch_3.id: ch_3}
|
||||
relay = {ch_4.id: ch_4, ch_5.id: ch_5}
|
||||
client_chans = {ch_4.id: ch_4, ch_5.id: ch_5}
|
||||
|
||||
with mock.patch.dict(ep_channels.claimed_channels, claimed, clear=True):
|
||||
with mock.patch.dict(ep_channels.relay_channels, relay, clear=True):
|
||||
with mock.patch.dict(ep_channels.client_channels, client_chans, clear=True):
|
||||
await ep_channels.async_configure()
|
||||
await ep_channels.async_initialize(mock.sentinel.from_cache)
|
||||
|
||||
for ch in [*claimed.values(), *relay.values()]:
|
||||
for ch in [*claimed.values(), *client_chans.values()]:
|
||||
assert ch.async_initialize.call_count == 1
|
||||
assert ch.async_initialize.await_count == 1
|
||||
assert ch.async_initialize.call_args[0][0] is mock.sentinel.from_cache
|
||||
|
@ -103,7 +103,7 @@ async def test_action(hass, device_ias):
|
||||
await hass.async_block_till_done()
|
||||
calls = async_mock_service(hass, DOMAIN, "warning_device_warn")
|
||||
|
||||
channel = zha_device.channels.pools[0].relay_channels["1:0x0006"]
|
||||
channel = zha_device.channels.pools[0].client_channels["1:0x0006"]
|
||||
channel.zha_send_event(COMMAND_SINGLE, [])
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -172,7 +172,7 @@ async def test_if_fires_on_event(hass, mock_devices, calls):
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
channel = zha_device.channels.pools[0].relay_channels["1:0x0006"]
|
||||
channel = zha_device.channels.pools[0].client_channels["1:0x0006"]
|
||||
channel.zha_send_event(COMMAND_SINGLE, [])
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -111,7 +111,7 @@ async def test_devices(
|
||||
)
|
||||
|
||||
event_channels = {
|
||||
ch.id for pool in zha_dev.channels.pools for ch in pool.relay_channels.values()
|
||||
ch.id for pool in zha_dev.channels.pools for ch in pool.client_channels.values()
|
||||
}
|
||||
|
||||
entity_map = device["entity_map"]
|
||||
@ -266,7 +266,7 @@ async def test_discover_endpoint(device_info, channels_mock, hass):
|
||||
)
|
||||
|
||||
assert device_info["event_channels"] == sorted(
|
||||
[ch.id for pool in channels.pools for ch in pool.relay_channels.values()]
|
||||
[ch.id for pool in channels.pools for ch in pool.client_channels.values()]
|
||||
)
|
||||
assert new_ent.call_count == len(
|
||||
[
|
||||
|
Loading…
x
Reference in New Issue
Block a user