Use more decorators for ZHA Core registries. (#25737)

* Move ZIGBEE_CHANNEL_REGISTRY to ZHA core registries.
* Refactor more ZHA Core registries to use decorator.
* Cleanup.
* Use relative imports for component.
* Flake8.
* Make pylint happy again.
This commit is contained in:
Alexei Chetroi 2019-08-06 20:01:14 -04:00 committed by GitHub
parent 98eb8efc6b
commit 152a9eb466
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 212 additions and 161 deletions

View File

@ -13,7 +13,6 @@ from random import uniform
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.util.decorator import Registry
from ..const import ( from ..const import (
CHANNEL_ATTRIBUTE, CHANNEL_ATTRIBUTE,
@ -30,8 +29,6 @@ from ..registries import CLUSTER_REPORT_CONFIGS
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
ZIGBEE_CHANNEL_REGISTRY = Registry()
def parse_and_log_command(channel, tsn, command_id, args): def parse_and_log_command(channel, tsn, command_id, args):
"""Parse and log a zigbee cluster command.""" """Parse and log a zigbee cluster command."""

View File

@ -11,13 +11,14 @@ import zigpy.zcl.clusters.closures as closures
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.dispatcher import async_dispatcher_send
from . import ZIGBEE_CHANNEL_REGISTRY, ZigbeeChannel from . import ZigbeeChannel
from .. import registries
from ..const import REPORT_CONFIG_IMMEDIATE, SIGNAL_ATTR_UPDATED from ..const import REPORT_CONFIG_IMMEDIATE, SIGNAL_ATTR_UPDATED
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ZIGBEE_CHANNEL_REGISTRY.register(closures.DoorLock.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(closures.DoorLock.cluster_id)
class DoorLockChannel(ZigbeeChannel): class DoorLockChannel(ZigbeeChannel):
"""Door lock channel.""" """Door lock channel."""
@ -54,14 +55,14 @@ class DoorLockChannel(ZigbeeChannel):
await super().async_initialize(from_cache) await super().async_initialize(from_cache)
@ZIGBEE_CHANNEL_REGISTRY.register(closures.Shade.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(closures.Shade.cluster_id)
class Shade(ZigbeeChannel): class Shade(ZigbeeChannel):
"""Shade channel.""" """Shade channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(closures.WindowCovering.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(closures.WindowCovering.cluster_id)
class WindowCovering(ZigbeeChannel): class WindowCovering(ZigbeeChannel):
"""Window channel.""" """Window channel."""

View File

@ -12,12 +12,8 @@ from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.event import async_call_later from homeassistant.helpers.event import async_call_later
from . import ( from . import AttributeListeningChannel, ZigbeeChannel, parse_and_log_command
ZIGBEE_CHANNEL_REGISTRY, from .. import registries
AttributeListeningChannel,
ZigbeeChannel,
parse_and_log_command,
)
from ..const import ( from ..const import (
REPORT_CONFIG_ASAP, REPORT_CONFIG_ASAP,
REPORT_CONFIG_BATTERY_SAVE, REPORT_CONFIG_BATTERY_SAVE,
@ -32,42 +28,43 @@ from ..helpers import get_attr_id_by_name
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ZIGBEE_CHANNEL_REGISTRY.register(general.Alarms.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.Alarms.cluster_id)
class Alarms(ZigbeeChannel): class Alarms(ZigbeeChannel):
"""Alarms channel.""" """Alarms channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(general.AnalogInput.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.AnalogInput.cluster_id)
class AnalogInput(AttributeListeningChannel): class AnalogInput(AttributeListeningChannel):
"""Analog Input channel.""" """Analog Input channel."""
REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}]
@ZIGBEE_CHANNEL_REGISTRY.register(general.AnalogOutput.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.AnalogOutput.cluster_id)
class AnalogOutput(AttributeListeningChannel): class AnalogOutput(AttributeListeningChannel):
"""Analog Output channel.""" """Analog Output channel."""
REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}]
@ZIGBEE_CHANNEL_REGISTRY.register(general.AnalogValue.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.AnalogValue.cluster_id)
class AnalogValue(AttributeListeningChannel): class AnalogValue(AttributeListeningChannel):
"""Analog Value channel.""" """Analog Value channel."""
REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}]
@ZIGBEE_CHANNEL_REGISTRY.register(general.ApplianceControl.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.ApplianceControl.cluster_id)
class ApplianceContorl(ZigbeeChannel): class ApplianceContorl(ZigbeeChannel):
"""Appliance Control channel.""" """Appliance Control channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(general.Basic.cluster_id) @registries.CHANNEL_ONLY_CLUSTERS.register(general.Basic.cluster_id)
@registries.ZIGBEE_CHANNEL_REGISTRY.register(general.Basic.cluster_id)
class BasicChannel(ZigbeeChannel): class BasicChannel(ZigbeeChannel):
"""Channel to interact with the basic cluster.""" """Channel to interact with the basic cluster."""
@ -106,63 +103,66 @@ class BasicChannel(ZigbeeChannel):
return self._power_source return self._power_source
@ZIGBEE_CHANNEL_REGISTRY.register(general.BinaryInput.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.BinaryInput.cluster_id)
class BinaryInput(AttributeListeningChannel): class BinaryInput(AttributeListeningChannel):
"""Binary Input channel.""" """Binary Input channel."""
REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}]
@ZIGBEE_CHANNEL_REGISTRY.register(general.BinaryOutput.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.BinaryOutput.cluster_id)
class BinaryOutput(AttributeListeningChannel): class BinaryOutput(AttributeListeningChannel):
"""Binary Output channel.""" """Binary Output channel."""
REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}]
@ZIGBEE_CHANNEL_REGISTRY.register(general.BinaryValue.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.BinaryValue.cluster_id)
class BinaryValue(AttributeListeningChannel): class BinaryValue(AttributeListeningChannel):
"""Binary Value channel.""" """Binary Value channel."""
REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}]
@ZIGBEE_CHANNEL_REGISTRY.register(general.Commissioning.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.Commissioning.cluster_id)
class Commissioning(ZigbeeChannel): class Commissioning(ZigbeeChannel):
"""Commissioning channel.""" """Commissioning channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(general.DeviceTemperature.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.DeviceTemperature.cluster_id)
class DeviceTemperature(ZigbeeChannel): class DeviceTemperature(ZigbeeChannel):
"""Device Temperatur channel.""" """Device Temperature channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(general.GreenPowerProxy.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.GreenPowerProxy.cluster_id)
class GreenPowerProxy(ZigbeeChannel): class GreenPowerProxy(ZigbeeChannel):
"""Green Power Proxy channel.""" """Green Power Proxy channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(general.Groups.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.Groups.cluster_id)
class Groups(ZigbeeChannel): class Groups(ZigbeeChannel):
"""Groups channel.""" """Groups channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(general.Identify.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.Identify.cluster_id)
class Identify(ZigbeeChannel): class Identify(ZigbeeChannel):
"""Identify channel.""" """Identify channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(general.LevelControl.cluster_id) @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): class LevelControlChannel(ZigbeeChannel):
"""Channel for the LevelControl Zigbee cluster.""" """Channel for the LevelControl Zigbee cluster."""
@ -207,28 +207,33 @@ class LevelControlChannel(ZigbeeChannel):
await super().async_initialize(from_cache) await super().async_initialize(from_cache)
@ZIGBEE_CHANNEL_REGISTRY.register(general.MultistateInput.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.MultistateInput.cluster_id)
class MultistateInput(AttributeListeningChannel): class MultistateInput(AttributeListeningChannel):
"""Multistate Input channel.""" """Multistate Input channel."""
REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}]
@ZIGBEE_CHANNEL_REGISTRY.register(general.MultistateOutput.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.MultistateOutput.cluster_id)
class MultistateOutput(AttributeListeningChannel): class MultistateOutput(AttributeListeningChannel):
"""Multistate Output channel.""" """Multistate Output channel."""
REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}]
@ZIGBEE_CHANNEL_REGISTRY.register(general.MultistateValue.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.MultistateValue.cluster_id)
class MultistateValue(AttributeListeningChannel): class MultistateValue(AttributeListeningChannel):
"""Multistate Value channel.""" """Multistate Value channel."""
REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}] REPORT_CONFIG = [{"attr": "present_value", "config": REPORT_CONFIG_DEFAULT}]
@ZIGBEE_CHANNEL_REGISTRY.register(general.OnOff.cluster_id) @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)
class OnOffChannel(ZigbeeChannel): class OnOffChannel(ZigbeeChannel):
"""Channel for the OnOff Zigbee cluster.""" """Channel for the OnOff Zigbee cluster."""
@ -302,35 +307,36 @@ class OnOffChannel(ZigbeeChannel):
await super().async_update() await super().async_update()
@ZIGBEE_CHANNEL_REGISTRY.register(general.OnOffConfiguration.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.OnOffConfiguration.cluster_id)
class OnOffConfiguration(ZigbeeChannel): class OnOffConfiguration(ZigbeeChannel):
"""OnOff Configuration channel.""" """OnOff Configuration channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(general.Ota.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.Ota.cluster_id)
class Ota(ZigbeeChannel): class Ota(ZigbeeChannel):
"""OTA Channel.""" """OTA Channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(general.Partition.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.Partition.cluster_id)
class Partition(ZigbeeChannel): class Partition(ZigbeeChannel):
"""Partition channel.""" """Partition channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(general.PollControl.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.PollControl.cluster_id)
class PollControl(ZigbeeChannel): class PollControl(ZigbeeChannel):
"""Poll Control channel.""" """Poll Control channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(general.PowerConfiguration.cluster_id) @registries.DEVICE_TRACKER_CLUSTERS.register(general.PowerConfiguration.cluster_id)
@registries.ZIGBEE_CHANNEL_REGISTRY.register(general.PowerConfiguration.cluster_id)
class PowerConfigurationChannel(ZigbeeChannel): class PowerConfigurationChannel(ZigbeeChannel):
"""Channel for the zigbee power configuration cluster.""" """Channel for the zigbee power configuration cluster."""
@ -373,28 +379,29 @@ class PowerConfigurationChannel(ZigbeeChannel):
await self.get_attribute_value("battery_quantity", from_cache=from_cache) await self.get_attribute_value("battery_quantity", from_cache=from_cache)
@ZIGBEE_CHANNEL_REGISTRY.register(general.PowerProfile.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.PowerProfile.cluster_id)
class PowerProfile(ZigbeeChannel): class PowerProfile(ZigbeeChannel):
"""Power Profile channel.""" """Power Profile channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(general.RSSILocation.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.RSSILocation.cluster_id)
class RSSILocation(ZigbeeChannel): class RSSILocation(ZigbeeChannel):
"""RSSI Location channel.""" """RSSI Location channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(general.Scenes.cluster_id) @registries.OUTPUT_CHANNEL_ONLY_CLUSTERS.register(general.Scenes.cluster_id)
@registries.ZIGBEE_CHANNEL_REGISTRY.register(general.Scenes.cluster_id)
class Scenes(ZigbeeChannel): class Scenes(ZigbeeChannel):
"""Scenes channel.""" """Scenes channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(general.Time.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(general.Time.cluster_id)
class Time(ZigbeeChannel): class Time(ZigbeeChannel):
"""Time channel.""" """Time channel."""

View File

@ -10,7 +10,8 @@ import zigpy.zcl.clusters.homeautomation as homeautomation
from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.dispatcher import async_dispatcher_send
from . import ZIGBEE_CHANNEL_REGISTRY, AttributeListeningChannel, ZigbeeChannel from . import AttributeListeningChannel, ZigbeeChannel
from .. import registries
from ..const import ( from ..const import (
CHANNEL_ELECTRICAL_MEASUREMENT, CHANNEL_ELECTRICAL_MEASUREMENT,
REPORT_CONFIG_DEFAULT, REPORT_CONFIG_DEFAULT,
@ -20,39 +21,48 @@ from ..const import (
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ZIGBEE_CHANNEL_REGISTRY.register(homeautomation.ApplianceEventAlerts.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(
homeautomation.ApplianceEventAlerts.cluster_id
)
class ApplianceEventAlerts(ZigbeeChannel): class ApplianceEventAlerts(ZigbeeChannel):
"""Appliance Event Alerts channel.""" """Appliance Event Alerts channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(homeautomation.ApplianceIdentification.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(
homeautomation.ApplianceIdentification.cluster_id
)
class ApplianceIdentification(ZigbeeChannel): class ApplianceIdentification(ZigbeeChannel):
"""Appliance Identification channel.""" """Appliance Identification channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(homeautomation.ApplianceStatistics.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(
homeautomation.ApplianceStatistics.cluster_id
)
class ApplianceStatistics(ZigbeeChannel): class ApplianceStatistics(ZigbeeChannel):
"""Appliance Statistics channel.""" """Appliance Statistics channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(homeautomation.Diagnostic.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(homeautomation.Diagnostic.cluster_id)
class Diagnostic(ZigbeeChannel): class Diagnostic(ZigbeeChannel):
"""Diagnostic channel.""" """Diagnostic channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(homeautomation.ElectricalMeasurement.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(
homeautomation.ElectricalMeasurement.cluster_id
)
class ElectricalMeasurementChannel(AttributeListeningChannel): class ElectricalMeasurementChannel(AttributeListeningChannel):
"""Channel that polls active power level.""" """Channel that polls active power level."""
CHANNEL_NAME = CHANNEL_ELECTRICAL_MEASUREMENT CHANNEL_NAME = CHANNEL_ELECTRICAL_MEASUREMENT
REPORT_CONFIG = ({"attr": "active_power", "config": REPORT_CONFIG_DEFAULT},) REPORT_CONFIG = ({"attr": "active_power", "config": REPORT_CONFIG_DEFAULT},)
async def async_update(self): async def async_update(self):
@ -73,7 +83,9 @@ class ElectricalMeasurementChannel(AttributeListeningChannel):
await super().async_initialize(from_cache) await super().async_initialize(from_cache)
@ZIGBEE_CHANNEL_REGISTRY.register(homeautomation.MeterIdentification.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(
homeautomation.MeterIdentification.cluster_id
)
class MeterIdentification(ZigbeeChannel): class MeterIdentification(ZigbeeChannel):
"""Metering Identification channel.""" """Metering Identification channel."""

View File

@ -11,24 +11,26 @@ import zigpy.zcl.clusters.hvac as hvac
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.dispatcher import async_dispatcher_send
from . import ZIGBEE_CHANNEL_REGISTRY, ZigbeeChannel from . import ZigbeeChannel
from .. import registries
from ..const import REPORT_CONFIG_OP, SIGNAL_ATTR_UPDATED from ..const import REPORT_CONFIG_OP, SIGNAL_ATTR_UPDATED
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ZIGBEE_CHANNEL_REGISTRY.register(hvac.Dehumidification.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(hvac.Dehumidification.cluster_id)
class Dehumidification(ZigbeeChannel): class Dehumidification(ZigbeeChannel):
"""Dehumidification channel.""" """Dehumidification channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(hvac.Fan.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(hvac.Fan.cluster_id)
class FanChannel(ZigbeeChannel): class FanChannel(ZigbeeChannel):
"""Fan channel.""" """Fan channel."""
_value_attribute = 0 _value_attribute = 0
REPORT_CONFIG = ({"attr": "fan_mode", "config": REPORT_CONFIG_OP},) REPORT_CONFIG = ({"attr": "fan_mode", "config": REPORT_CONFIG_OP},)
async def async_set_speed(self, value) -> None: async def async_set_speed(self, value) -> None:
@ -71,21 +73,21 @@ class FanChannel(ZigbeeChannel):
await super().async_initialize(from_cache) await super().async_initialize(from_cache)
@ZIGBEE_CHANNEL_REGISTRY.register(hvac.Pump.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(hvac.Pump.cluster_id)
class Pump(ZigbeeChannel): class Pump(ZigbeeChannel):
"""Pump channel.""" """Pump channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(hvac.Thermostat.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(hvac.Thermostat.cluster_id)
class Thermostat(ZigbeeChannel): class Thermostat(ZigbeeChannel):
"""Thermostat channel.""" """Thermostat channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(hvac.UserInterface.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(hvac.UserInterface.cluster_id)
class UserInterface(ZigbeeChannel): class UserInterface(ZigbeeChannel):
"""User interface (thermostat) channel.""" """User interface (thermostat) channel."""

View File

@ -8,20 +8,24 @@ import logging
import zigpy.zcl.clusters.lighting as lighting import zigpy.zcl.clusters.lighting as lighting
from . import ZIGBEE_CHANNEL_REGISTRY, ZigbeeChannel from . import ZigbeeChannel
from .. import registries
from ..const import REPORT_CONFIG_DEFAULT from ..const import REPORT_CONFIG_DEFAULT
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ZIGBEE_CHANNEL_REGISTRY.register(lighting.Ballast.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(lighting.Ballast.cluster_id)
class Ballast(ZigbeeChannel): class Ballast(ZigbeeChannel):
"""Ballast channel.""" """Ballast channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(lighting.Color.cluster_id) @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): class ColorChannel(ZigbeeChannel):
"""Color channel.""" """Color channel."""

View File

@ -8,12 +8,14 @@ import logging
import zigpy.zcl.clusters.lightlink as lightlink import zigpy.zcl.clusters.lightlink as lightlink
from . import ZIGBEE_CHANNEL_REGISTRY, ZigbeeChannel from . import ZigbeeChannel
from .. import registries
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ZIGBEE_CHANNEL_REGISTRY.register(lightlink.LightLink.cluster_id) @registries.CHANNEL_ONLY_CLUSTERS.register(lightlink.LightLink.cluster_id)
@registries.ZIGBEE_CHANNEL_REGISTRY.register(lightlink.LightLink.cluster_id)
class LightLink(ZigbeeChannel): class LightLink(ZigbeeChannel):
"""Lightlink channel.""" """Lightlink channel."""

View File

@ -8,7 +8,8 @@ import logging
import zigpy.zcl.clusters.measurement as measurement import zigpy.zcl.clusters.measurement as measurement
from . import ZIGBEE_CHANNEL_REGISTRY, AttributeListeningChannel from . import AttributeListeningChannel
from .. import registries
from ..const import ( from ..const import (
REPORT_CONFIG_DEFAULT, REPORT_CONFIG_DEFAULT,
REPORT_CONFIG_IMMEDIATE, REPORT_CONFIG_IMMEDIATE,
@ -19,42 +20,47 @@ from ..const import (
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ZIGBEE_CHANNEL_REGISTRY.register(measurement.FlowMeasurement.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(measurement.FlowMeasurement.cluster_id)
class FlowMeasurement(AttributeListeningChannel): class FlowMeasurement(AttributeListeningChannel):
"""Flow Measurement channel.""" """Flow Measurement channel."""
REPORT_CONFIG = [{"attr": "measured_value", "config": REPORT_CONFIG_DEFAULT}] REPORT_CONFIG = [{"attr": "measured_value", "config": REPORT_CONFIG_DEFAULT}]
@ZIGBEE_CHANNEL_REGISTRY.register(measurement.IlluminanceLevelSensing.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(
measurement.IlluminanceLevelSensing.cluster_id
)
class IlluminanceLevelSensing(AttributeListeningChannel): class IlluminanceLevelSensing(AttributeListeningChannel):
"""Illuminance Level Sensing channel.""" """Illuminance Level Sensing channel."""
REPORT_CONFIG = [{"attr": "level_status", "config": REPORT_CONFIG_DEFAULT}] REPORT_CONFIG = [{"attr": "level_status", "config": REPORT_CONFIG_DEFAULT}]
@ZIGBEE_CHANNEL_REGISTRY.register(measurement.IlluminanceMeasurement.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(
measurement.IlluminanceMeasurement.cluster_id
)
class IlluminanceMeasurement(AttributeListeningChannel): class IlluminanceMeasurement(AttributeListeningChannel):
"""Illuminance Measurement channel.""" """Illuminance Measurement channel."""
REPORT_CONFIG = [{"attr": "measured_value", "config": REPORT_CONFIG_DEFAULT}] REPORT_CONFIG = [{"attr": "measured_value", "config": REPORT_CONFIG_DEFAULT}]
@ZIGBEE_CHANNEL_REGISTRY.register(measurement.OccupancySensing.cluster_id) @registries.BINARY_SENSOR_CLUSTERS.register(measurement.OccupancySensing.cluster_id)
@registries.ZIGBEE_CHANNEL_REGISTRY.register(measurement.OccupancySensing.cluster_id)
class OccupancySensing(AttributeListeningChannel): class OccupancySensing(AttributeListeningChannel):
"""Occupancy Sensing channel.""" """Occupancy Sensing channel."""
REPORT_CONFIG = [{"attr": "occupancy", "config": REPORT_CONFIG_IMMEDIATE}] REPORT_CONFIG = [{"attr": "occupancy", "config": REPORT_CONFIG_IMMEDIATE}]
@ZIGBEE_CHANNEL_REGISTRY.register(measurement.PressureMeasurement.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(measurement.PressureMeasurement.cluster_id)
class PressureMeasurement(AttributeListeningChannel): class PressureMeasurement(AttributeListeningChannel):
"""Pressure measurement channel.""" """Pressure measurement channel."""
REPORT_CONFIG = [{"attr": "measured_value", "config": REPORT_CONFIG_DEFAULT}] REPORT_CONFIG = [{"attr": "measured_value", "config": REPORT_CONFIG_DEFAULT}]
@ZIGBEE_CHANNEL_REGISTRY.register(measurement.RelativeHumidity.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(measurement.RelativeHumidity.cluster_id)
class RelativeHumidity(AttributeListeningChannel): class RelativeHumidity(AttributeListeningChannel):
"""Relative Humidity measurement channel.""" """Relative Humidity measurement channel."""
@ -66,7 +72,9 @@ class RelativeHumidity(AttributeListeningChannel):
] ]
@ZIGBEE_CHANNEL_REGISTRY.register(measurement.TemperatureMeasurement.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(
measurement.TemperatureMeasurement.cluster_id
)
class TemperatureMeasurement(AttributeListeningChannel): class TemperatureMeasurement(AttributeListeningChannel):
"""Temperature measurement channel.""" """Temperature measurement channel."""

View File

@ -8,145 +8,154 @@ import logging
import zigpy.zcl.clusters.protocol as protocol import zigpy.zcl.clusters.protocol as protocol
from ..channels import ZIGBEE_CHANNEL_REGISTRY, ZigbeeChannel from .. import registries
from ..channels import ZigbeeChannel
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.AnalogInputExtended.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.AnalogInputExtended.cluster_id)
class AnalogInputExtended(ZigbeeChannel): class AnalogInputExtended(ZigbeeChannel):
"""Analog Input Extended channel.""" """Analog Input Extended channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.AnalogInputRegular.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.AnalogInputRegular.cluster_id)
class AnalogInputRegular(ZigbeeChannel): class AnalogInputRegular(ZigbeeChannel):
"""Analog Input Regular channel.""" """Analog Input Regular channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.AnalogOutputExtended.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.AnalogOutputExtended.cluster_id)
class AnalogOutputExtended(ZigbeeChannel): class AnalogOutputExtended(ZigbeeChannel):
"""Analog Output Regular channel.""" """Analog Output Regular channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.AnalogOutputRegular.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.AnalogOutputRegular.cluster_id)
class AnalogOutputRegular(ZigbeeChannel): class AnalogOutputRegular(ZigbeeChannel):
"""Analog Output Regular channel.""" """Analog Output Regular channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.AnalogValueExtended.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.AnalogValueExtended.cluster_id)
class AnalogValueExtended(ZigbeeChannel): class AnalogValueExtended(ZigbeeChannel):
"""Analog Value Extended edition channel.""" """Analog Value Extended edition channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.AnalogValueRegular.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.AnalogValueRegular.cluster_id)
class AnalogValueRegular(ZigbeeChannel): class AnalogValueRegular(ZigbeeChannel):
"""Analog Value Regular channel.""" """Analog Value Regular channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.BacnetProtocolTunnel.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.BacnetProtocolTunnel.cluster_id)
class BacnetProtocolTunnel(ZigbeeChannel): class BacnetProtocolTunnel(ZigbeeChannel):
"""Bacnet Protocol Tunnel channel.""" """Bacnet Protocol Tunnel channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.BinaryInputExtended.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.BinaryInputExtended.cluster_id)
class BinaryInputExtended(ZigbeeChannel): class BinaryInputExtended(ZigbeeChannel):
"""Binary Input Extended channel.""" """Binary Input Extended channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.BinaryInputRegular.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.BinaryInputRegular.cluster_id)
class BinaryInputRegular(ZigbeeChannel): class BinaryInputRegular(ZigbeeChannel):
"""Binary Input Regular channel.""" """Binary Input Regular channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.BinaryOutputExtended.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.BinaryOutputExtended.cluster_id)
class BinaryOutputExtended(ZigbeeChannel): class BinaryOutputExtended(ZigbeeChannel):
"""Binary Output Extended channel.""" """Binary Output Extended channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.BinaryOutputRegular.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.BinaryOutputRegular.cluster_id)
class BinaryOutputRegular(ZigbeeChannel): class BinaryOutputRegular(ZigbeeChannel):
"""Binary Output Regular channel.""" """Binary Output Regular channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.BinaryValueExtended.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.BinaryValueExtended.cluster_id)
class BinaryValueExtended(ZigbeeChannel): class BinaryValueExtended(ZigbeeChannel):
"""Binary Value Extended channel.""" """Binary Value Extended channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.BinaryValueRegular.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.BinaryValueRegular.cluster_id)
class BinaryValueRegular(ZigbeeChannel): class BinaryValueRegular(ZigbeeChannel):
"""Binary Value Regular channel.""" """Binary Value Regular channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.GenericTunnel.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.GenericTunnel.cluster_id)
class GenericTunnel(ZigbeeChannel): class GenericTunnel(ZigbeeChannel):
"""Generic Tunnel channel.""" """Generic Tunnel channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.MultistateInputExtended.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(
protocol.MultistateInputExtended.cluster_id
)
class MultiStateInputExtended(ZigbeeChannel): class MultiStateInputExtended(ZigbeeChannel):
"""Multistate Input Extended channel.""" """Multistate Input Extended channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.MultistateInputRegular.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.MultistateInputRegular.cluster_id)
class MultiStateInputRegular(ZigbeeChannel): class MultiStateInputRegular(ZigbeeChannel):
"""Multistate Input Regular channel.""" """Multistate Input Regular channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.MultistateOutputExtended.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(
protocol.MultistateOutputExtended.cluster_id
)
class MultiStateOutputExtended(ZigbeeChannel): class MultiStateOutputExtended(ZigbeeChannel):
"""Multistate Output Extended channel.""" """Multistate Output Extended channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.MultistateOutputRegular.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(
protocol.MultistateOutputRegular.cluster_id
)
class MultiStateOutputRegular(ZigbeeChannel): class MultiStateOutputRegular(ZigbeeChannel):
"""Multistate Output Regular channel.""" """Multistate Output Regular channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.MultistateValueExtended.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(
protocol.MultistateValueExtended.cluster_id
)
class MultiStateValueExtended(ZigbeeChannel): class MultiStateValueExtended(ZigbeeChannel):
"""Multistate Value Extended channel.""" """Multistate Value Extended channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(protocol.MultistateValueRegular.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(protocol.MultistateValueRegular.cluster_id)
class MultiStateValueRegular(ZigbeeChannel): class MultiStateValueRegular(ZigbeeChannel):
"""Multistate Value Regular channel.""" """Multistate Value Regular channel."""

View File

@ -11,27 +11,29 @@ import zigpy.zcl.clusters.security as security
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.dispatcher import async_dispatcher_send
from . import ZIGBEE_CHANNEL_REGISTRY, ZigbeeChannel from . import ZigbeeChannel
from .. import registries
from ..const import SIGNAL_ATTR_UPDATED from ..const import SIGNAL_ATTR_UPDATED
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ZIGBEE_CHANNEL_REGISTRY.register(security.IasAce.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(security.IasAce.cluster_id)
class IasAce(ZigbeeChannel): class IasAce(ZigbeeChannel):
"""IAS Ancillary Control Equipment channel.""" """IAS Ancillary Control Equipment channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(security.IasWd.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(security.IasWd.cluster_id)
class IasWd(ZigbeeChannel): class IasWd(ZigbeeChannel):
"""IAS Warning Device channel.""" """IAS Warning Device channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(security.IasZone.cluster_id) @registries.BINARY_SENSOR_CLUSTERS.register(security.IasZone.cluster_id)
@registries.ZIGBEE_CHANNEL_REGISTRY.register(security.IasZone.cluster_id)
class IASZoneChannel(ZigbeeChannel): class IASZoneChannel(ZigbeeChannel):
"""Channel for the IASZone Zigbee cluster.""" """Channel for the IASZone Zigbee cluster."""

View File

@ -8,90 +8,91 @@ import logging
import zigpy.zcl.clusters.smartenergy as smartenergy import zigpy.zcl.clusters.smartenergy as smartenergy
from ..channels import ZIGBEE_CHANNEL_REGISTRY, AttributeListeningChannel, ZigbeeChannel from .. import registries
from ..channels import AttributeListeningChannel, ZigbeeChannel
from ..const import REPORT_CONFIG_DEFAULT from ..const import REPORT_CONFIG_DEFAULT
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Calendar.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Calendar.cluster_id)
class Calendar(ZigbeeChannel): class Calendar(ZigbeeChannel):
"""Calendar channel.""" """Calendar channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.DeviceManagement.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.DeviceManagement.cluster_id)
class DeviceManagement(ZigbeeChannel): class DeviceManagement(ZigbeeChannel):
"""Device Management channel.""" """Device Management channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Drlc.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Drlc.cluster_id)
class Drlc(ZigbeeChannel): class Drlc(ZigbeeChannel):
"""Demand Response and Load Control channel.""" """Demand Response and Load Control channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.EnergyManagement.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.EnergyManagement.cluster_id)
class EnergyManagement(ZigbeeChannel): class EnergyManagement(ZigbeeChannel):
"""Energy Management channel.""" """Energy Management channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Events.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Events.cluster_id)
class Events(ZigbeeChannel): class Events(ZigbeeChannel):
"""Event channel.""" """Event channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.KeyEstablishment.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.KeyEstablishment.cluster_id)
class KeyEstablishment(ZigbeeChannel): class KeyEstablishment(ZigbeeChannel):
"""Key Establishment channel.""" """Key Establishment channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.MduPairing.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.MduPairing.cluster_id)
class MduPairing(ZigbeeChannel): class MduPairing(ZigbeeChannel):
"""Pairing channel.""" """Pairing channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Messaging.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Messaging.cluster_id)
class Messaging(ZigbeeChannel): class Messaging(ZigbeeChannel):
"""Messaging channel.""" """Messaging channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Metering.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Metering.cluster_id)
class Metering(AttributeListeningChannel): class Metering(AttributeListeningChannel):
"""Metering channel.""" """Metering channel."""
REPORT_CONFIG = [{"attr": "instantaneous_demand", "config": REPORT_CONFIG_DEFAULT}] REPORT_CONFIG = [{"attr": "instantaneous_demand", "config": REPORT_CONFIG_DEFAULT}]
@ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Prepayment.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Prepayment.cluster_id)
class Prepayment(ZigbeeChannel): class Prepayment(ZigbeeChannel):
"""Prepayment channel.""" """Prepayment channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Price.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Price.cluster_id)
class Price(ZigbeeChannel): class Price(ZigbeeChannel):
"""Price channel.""" """Price channel."""
pass pass
@ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Tunneling.cluster_id) @registries.ZIGBEE_CHANNEL_REGISTRY.register(smartenergy.Tunneling.cluster_id)
class Tunneling(ZigbeeChannel): class Tunneling(ZigbeeChannel):
"""Tunneling channel.""" """Tunneling channel."""

View File

@ -0,0 +1,37 @@
"""Decorators for ZHA core registries."""
from typing import Callable, TypeVar, Union
CALLABLE_T = TypeVar("CALLABLE_T", bound=Callable) # noqa pylint: disable=invalid-name
class DictRegistry(dict):
"""Dict Registry of items."""
def register(
self, name: Union[int, str], item: Union[str, CALLABLE_T] = None
) -> Callable[[CALLABLE_T], CALLABLE_T]:
"""Return decorator to register item with a specific name."""
def decorator(channel: CALLABLE_T) -> CALLABLE_T:
"""Register decorated channel or item."""
if item is None:
self[name] = channel
else:
self[name] = item
return channel
return decorator
class SetRegistry(set):
"""Set Registry of items."""
def register(self, name: Union[int, str]) -> Callable[[CALLABLE_T], CALLABLE_T]:
"""Return decorator to register item with a specific name."""
def decorator(channel: CALLABLE_T) -> CALLABLE_T:
"""Register decorated channel or item."""
self.add(name)
return channel
return decorator

View File

@ -13,12 +13,7 @@ from homeassistant.components.sensor import DOMAIN as SENSOR
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.dispatcher import async_dispatcher_send
from .channels import ( from .channels import AttributeListeningChannel, EventRelayChannel, ZDOChannel
ZIGBEE_CHANNEL_REGISTRY,
AttributeListeningChannel,
EventRelayChannel,
ZDOChannel,
)
from .const import ( from .const import (
COMPONENTS, COMPONENTS,
CONF_DEVICE_CONFIG, CONF_DEVICE_CONFIG,
@ -39,6 +34,7 @@ from .registries import (
SENSOR_TYPES, SENSOR_TYPES,
SINGLE_INPUT_CLUSTER_DEVICE_CLASS, SINGLE_INPUT_CLUSTER_DEVICE_CLASS,
SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS, SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS,
ZIGBEE_CHANNEL_REGISTRY,
) )
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)

View File

@ -122,13 +122,12 @@ def async_is_bindable_target(source_zha_device, target_zha_device):
source_clusters = source_zha_device.async_get_std_clusters() source_clusters = source_zha_device.async_get_std_clusters()
target_clusters = target_zha_device.async_get_std_clusters() target_clusters = target_zha_device.async_get_std_clusters()
bindables = set(BINDABLE_CLUSTERS)
for endpoint_id in source_clusters: for endpoint_id in source_clusters:
for t_endpoint_id in target_clusters: for t_endpoint_id in target_clusters:
matches = set( matches = set(
source_clusters[endpoint_id][CLUSTER_TYPE_OUT].keys() source_clusters[endpoint_id][CLUSTER_TYPE_OUT].keys()
).intersection(target_clusters[t_endpoint_id][CLUSTER_TYPE_IN].keys()) ).intersection(target_clusters[t_endpoint_id][CLUSTER_TYPE_IN].keys())
if any(bindable in bindables for bindable in matches): if any(bindable in BINDABLE_CLUSTERS for bindable in matches):
return True return True
return False return False

View File

@ -4,6 +4,7 @@ Mapping registries for Zigbee Home Automation.
For more details about this component, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/zha/ https://home-assistant.io/components/zha/
""" """
import collections
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR
from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER
@ -33,24 +34,25 @@ from .const import (
ZONE, ZONE,
RadioType, RadioType,
) )
from .decorators import DictRegistry, SetRegistry
BINARY_SENSOR_CLUSTERS = set() BINARY_SENSOR_CLUSTERS = SetRegistry()
BINARY_SENSOR_TYPES = {} BINARY_SENSOR_TYPES = {}
BINDABLE_CLUSTERS = [] BINDABLE_CLUSTERS = SetRegistry()
CHANNEL_ONLY_CLUSTERS = [] CHANNEL_ONLY_CLUSTERS = SetRegistry()
CLUSTER_REPORT_CONFIGS = {} CLUSTER_REPORT_CONFIGS = {}
CUSTOM_CLUSTER_MAPPINGS = {} CUSTOM_CLUSTER_MAPPINGS = {}
DEVICE_CLASS = {} DEVICE_CLASS = collections.defaultdict(dict)
DEVICE_TRACKER_CLUSTERS = set() DEVICE_TRACKER_CLUSTERS = SetRegistry()
EVENT_RELAY_CLUSTERS = [] EVENT_RELAY_CLUSTERS = SetRegistry()
LIGHT_CLUSTERS = set() LIGHT_CLUSTERS = SetRegistry()
OUTPUT_CHANNEL_ONLY_CLUSTERS = [] OUTPUT_CHANNEL_ONLY_CLUSTERS = SetRegistry()
RADIO_TYPES = {} RADIO_TYPES = {}
REMOTE_DEVICE_TYPES = {} REMOTE_DEVICE_TYPES = collections.defaultdict(list)
SENSOR_TYPES = {} SENSOR_TYPES = {}
SINGLE_INPUT_CLUSTER_DEVICE_CLASS = {} SINGLE_INPUT_CLUSTER_DEVICE_CLASS = {}
SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS = {} SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS = {}
SWITCH_CLUSTERS = set() SWITCH_CLUSTERS = SetRegistry()
SMARTTHINGS_ACCELERATION_CLUSTER = 0xFC02 SMARTTHINGS_ACCELERATION_CLUSTER = 0xFC02
SMARTTHINGS_ARRIVAL_SENSOR_DEVICE_TYPE = 0x8000 SMARTTHINGS_ARRIVAL_SENSOR_DEVICE_TYPE = 0x8000
SMARTTHINGS_HUMIDITY_CLUSTER = 0xFC45 SMARTTHINGS_HUMIDITY_CLUSTER = 0xFC45
@ -62,6 +64,11 @@ COMPONENT_CLUSTERS = {
SWITCH: SWITCH_CLUSTERS, SWITCH: SWITCH_CLUSTERS,
} }
ZIGBEE_CHANNEL_REGISTRY = DictRegistry()
# importing channels updates registries
from . import channels # noqa pylint: disable=wrong-import-position,unused-import
def establish_device_mappings(): def establish_device_mappings():
"""Establish mappings between ZCL objects and HA ZHA objects. """Establish mappings between ZCL objects and HA ZHA objects.
@ -72,16 +79,6 @@ def establish_device_mappings():
from zigpy import zcl from zigpy import zcl
from zigpy.profiles import zha, zll from zigpy.profiles import zha, zll
if zha.PROFILE_ID not in DEVICE_CLASS:
DEVICE_CLASS[zha.PROFILE_ID] = {}
if zll.PROFILE_ID not in DEVICE_CLASS:
DEVICE_CLASS[zll.PROFILE_ID] = {}
if zha.PROFILE_ID not in REMOTE_DEVICE_TYPES:
REMOTE_DEVICE_TYPES[zha.PROFILE_ID] = []
if zll.PROFILE_ID not in REMOTE_DEVICE_TYPES:
REMOTE_DEVICE_TYPES[zll.PROFILE_ID] = []
def get_ezsp_radio(): def get_ezsp_radio():
import bellows.ezsp import bellows.ezsp
from bellows.zigbee.application import ControllerApplication from bellows.zigbee.application import ControllerApplication
@ -133,9 +130,6 @@ def establish_device_mappings():
} }
BINARY_SENSOR_CLUSTERS.add(SMARTTHINGS_ACCELERATION_CLUSTER) BINARY_SENSOR_CLUSTERS.add(SMARTTHINGS_ACCELERATION_CLUSTER)
BINARY_SENSOR_CLUSTERS.add(zcl.clusters.general.OnOff.cluster_id)
BINARY_SENSOR_CLUSTERS.add(zcl.clusters.measurement.OccupancySensing.cluster_id)
BINARY_SENSOR_CLUSTERS.add(zcl.clusters.security.IasZone.cluster_id)
BINARY_SENSOR_TYPES.update( BINARY_SENSOR_TYPES.update(
{ {
@ -146,13 +140,6 @@ def establish_device_mappings():
} }
) )
BINDABLE_CLUSTERS.append(zcl.clusters.general.LevelControl.cluster_id)
BINDABLE_CLUSTERS.append(zcl.clusters.general.OnOff.cluster_id)
BINDABLE_CLUSTERS.append(zcl.clusters.lighting.Color.cluster_id)
CHANNEL_ONLY_CLUSTERS.append(zcl.clusters.general.Basic.cluster_id)
CHANNEL_ONLY_CLUSTERS.append(zcl.clusters.lightlink.LightLink.cluster_id)
CLUSTER_REPORT_CONFIGS.update( CLUSTER_REPORT_CONFIGS.update(
{ {
SMARTTHINGS_ACCELERATION_CLUSTER: [ SMARTTHINGS_ACCELERATION_CLUSTER: [
@ -200,17 +187,6 @@ def establish_device_mappings():
} }
) )
DEVICE_TRACKER_CLUSTERS.add(zcl.clusters.general.PowerConfiguration.cluster_id)
EVENT_RELAY_CLUSTERS.append(zcl.clusters.general.LevelControl.cluster_id)
EVENT_RELAY_CLUSTERS.append(zcl.clusters.general.OnOff.cluster_id)
OUTPUT_CHANNEL_ONLY_CLUSTERS.append(zcl.clusters.general.Scenes.cluster_id)
LIGHT_CLUSTERS.add(zcl.clusters.general.LevelControl.cluster_id)
LIGHT_CLUSTERS.add(zcl.clusters.general.OnOff.cluster_id)
LIGHT_CLUSTERS.add(zcl.clusters.lighting.Color.cluster_id)
SINGLE_INPUT_CLUSTER_DEVICE_CLASS.update( SINGLE_INPUT_CLUSTER_DEVICE_CLASS.update(
{ {
# this works for now but if we hit conflicts we can break it out to # this works for now but if we hit conflicts we can break it out to
@ -251,8 +227,6 @@ def establish_device_mappings():
} }
) )
SWITCH_CLUSTERS.add(zcl.clusters.general.OnOff.cluster_id)
zhap = zha.PROFILE_ID zhap = zha.PROFILE_ID
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.COLOR_CONTROLLER) REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.COLOR_CONTROLLER)
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.COLOR_DIMMER_SWITCH) REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.COLOR_DIMMER_SWITCH)

View File

@ -1,10 +1,10 @@
"""Test ZHA Core channels.""" """Test ZHA Core channels."""
import homeassistant.components.zha.core.channels
import pytest import pytest
import zigpy.types as t import zigpy.types as t
import homeassistant.components.zha.core.channels as channels import homeassistant.components.zha.core.channels as channels
import homeassistant.components.zha.core.device as zha_device import homeassistant.components.zha.core.device as zha_device
import homeassistant.components.zha.core.registries as registries
from .common import make_device from .common import make_device
@ -77,7 +77,7 @@ async def test_in_channel_config(cluster_id, bind_count, attrs, zha_gateway, has
zha_dev = zha_device.ZHADevice(hass, zigpy_dev, zha_gateway) zha_dev = zha_device.ZHADevice(hass, zigpy_dev, zha_gateway)
cluster = zigpy_dev.endpoints[1].in_clusters[cluster_id] cluster = zigpy_dev.endpoints[1].in_clusters[cluster_id]
channel_class = channels.ZIGBEE_CHANNEL_REGISTRY.get( channel_class = registries.ZIGBEE_CHANNEL_REGISTRY.get(
cluster_id, channels.AttributeListeningChannel cluster_id, channels.AttributeListeningChannel
) )
channel = channel_class(cluster, zha_dev) channel = channel_class(cluster, zha_dev)
@ -136,7 +136,7 @@ async def test_out_channel_config(cluster_id, bind_count, zha_gateway, hass):
cluster = zigpy_dev.endpoints[1].out_clusters[cluster_id] cluster = zigpy_dev.endpoints[1].out_clusters[cluster_id]
cluster.bind_only = True cluster.bind_only = True
channel_class = homeassistant.components.zha.core.channels.ZIGBEE_CHANNEL_REGISTRY.get( channel_class = registries.ZIGBEE_CHANNEL_REGISTRY.get(
cluster_id, channels.AttributeListeningChannel cluster_id, channels.AttributeListeningChannel
) )
channel = channel_class(cluster, zha_dev) channel = channel_class(cluster, zha_dev)
@ -149,7 +149,7 @@ async def test_out_channel_config(cluster_id, bind_count, zha_gateway, hass):
def test_channel_registry(): def test_channel_registry():
"""Test ZIGBEE Channel Registry.""" """Test ZIGBEE Channel Registry."""
for cluster_id, channel in channels.ZIGBEE_CHANNEL_REGISTRY.items(): for (cluster_id, channel) in registries.ZIGBEE_CHANNEL_REGISTRY.items():
assert isinstance(cluster_id, int) assert isinstance(cluster_id, int)
assert 0 <= cluster_id <= 0xFFFF assert 0 <= cluster_id <= 0xFFFF
assert issubclass(channel, channels.ZigbeeChannel) assert issubclass(channel, channels.ZigbeeChannel)