Apply consistent naming to ZHA cluster handler implementations (#108851)

* Apply consistent naming to ZHA cluster handler implentations

* remove import alias

* remove if statement around assert in test
This commit is contained in:
David F. Mulcahey 2024-01-25 20:09:38 -05:00 committed by GitHub
parent eb85f469e9
commit 3f31a76692
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 450 additions and 443 deletions

View file

@ -28,7 +28,7 @@ from .core import discovery
from .core.cluster_handlers.security import (
SIGNAL_ALARM_TRIGGERED,
SIGNAL_ARMED_STATE_CHANGED,
IasAce as AceClusterHandler,
IasAceClusterHandler,
)
from .core.const import (
CLUSTER_HANDLER_IAS_ACE,
@ -96,7 +96,7 @@ class ZHAAlarmControlPanel(ZhaEntity, AlarmControlPanelEntity):
"""Initialize the ZHA alarm control device."""
super().__init__(unique_id, zha_device, cluster_handlers, **kwargs)
cfg_entry = zha_device.gateway.config_entry
self._cluster_handler: AceClusterHandler = cluster_handlers[0]
self._cluster_handler: IasAceClusterHandler = cluster_handlers[0]
self._cluster_handler.panel_code = async_get_zha_config_value(
cfg_entry, ZHA_ALARM_OPTIONS, CONF_ALARM_MASTER_CODE, "1234"
)

View file

@ -4,7 +4,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any
import zigpy.zcl
from zigpy.zcl.clusters import closures
from zigpy.zcl.clusters.closures import DoorLock, Shade, WindowCovering
from homeassistant.core import callback
@ -16,14 +16,14 @@ if TYPE_CHECKING:
from ..endpoint import Endpoint
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(closures.DoorLock.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(DoorLock.cluster_id)
class DoorLockClusterHandler(ClusterHandler):
"""Door lock cluster handler."""
_value_attribute = 0
REPORT_CONFIG = (
AttrReportConfig(
attr=closures.DoorLock.AttributeDefs.lock_state.name,
attr=DoorLock.AttributeDefs.lock_state.name,
config=REPORT_CONFIG_IMMEDIATE,
),
)
@ -31,13 +31,13 @@ class DoorLockClusterHandler(ClusterHandler):
async def async_update(self):
"""Retrieve latest state."""
result = await self.get_attribute_value(
closures.DoorLock.AttributeDefs.lock_state.name, from_cache=True
DoorLock.AttributeDefs.lock_state.name, from_cache=True
)
if result is not None:
self.async_send_signal(
f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}",
closures.DoorLock.AttributeDefs.lock_state.id,
closures.DoorLock.AttributeDefs.lock_state.name,
DoorLock.AttributeDefs.lock_state.id,
DoorLock.AttributeDefs.lock_state.name,
result,
)
@ -80,20 +80,20 @@ class DoorLockClusterHandler(ClusterHandler):
await self.set_pin_code(
code_slot - 1, # start code slots at 1, Zigbee internals use 0
closures.DoorLock.UserStatus.Enabled,
closures.DoorLock.UserType.Unrestricted,
DoorLock.UserStatus.Enabled,
DoorLock.UserType.Unrestricted,
user_code,
)
async def async_enable_user_code(self, code_slot: int) -> None:
"""Enable the code slot."""
await self.set_user_status(code_slot - 1, closures.DoorLock.UserStatus.Enabled)
await self.set_user_status(code_slot - 1, DoorLock.UserStatus.Enabled)
async def async_disable_user_code(self, code_slot: int) -> None:
"""Disable the code slot."""
await self.set_user_status(code_slot - 1, closures.DoorLock.UserStatus.Disabled)
await self.set_user_status(code_slot - 1, DoorLock.UserStatus.Disabled)
async def async_get_user_code(self, code_slot: int) -> int:
"""Get the user code from the code slot."""
@ -123,26 +123,26 @@ class DoorLockClusterHandler(ClusterHandler):
return result
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(closures.Shade.cluster_id)
class Shade(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Shade.cluster_id)
class ShadeClusterHandler(ClusterHandler):
"""Shade cluster handler."""
@registries.CLIENT_CLUSTER_HANDLER_REGISTRY.register(closures.WindowCovering.cluster_id)
class WindowCoveringClient(ClientClusterHandler):
@registries.CLIENT_CLUSTER_HANDLER_REGISTRY.register(WindowCovering.cluster_id)
class WindowCoveringClientClusterHandler(ClientClusterHandler):
"""Window client cluster handler."""
@registries.BINDABLE_CLUSTERS.register(closures.WindowCovering.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(closures.WindowCovering.cluster_id)
class WindowCovering(ClusterHandler):
@registries.BINDABLE_CLUSTERS.register(WindowCovering.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(WindowCovering.cluster_id)
class WindowCoveringClusterHandler(ClusterHandler):
"""Window cluster handler."""
_value_attribute_lift = (
closures.WindowCovering.AttributeDefs.current_position_lift_percentage.id
WindowCovering.AttributeDefs.current_position_lift_percentage.id
)
_value_attribute_tilt = (
closures.WindowCovering.AttributeDefs.current_position_tilt_percentage.id
WindowCovering.AttributeDefs.current_position_tilt_percentage.id
)
REPORT_CONFIG = (
AttrReportConfig(

View file

@ -8,7 +8,36 @@ from zhaquirks.quirk_ids import TUYA_PLUG_ONOFF
import zigpy.exceptions
import zigpy.types as t
import zigpy.zcl
from zigpy.zcl.clusters import general
from zigpy.zcl.clusters.general import (
Alarms,
AnalogInput,
AnalogOutput,
AnalogValue,
ApplianceControl,
Basic,
BinaryInput,
BinaryOutput,
BinaryValue,
Commissioning,
DeviceTemperature,
GreenPowerProxy,
Groups,
Identify,
LevelControl,
MultistateInput,
MultistateOutput,
MultistateValue,
OnOff,
OnOffConfiguration,
Ota,
Partition,
PollControl,
PowerConfiguration,
PowerProfile,
RSSILocation,
Scenes,
Time,
)
from zigpy.zcl.foundation import Status
from homeassistant.core import callback
@ -40,122 +69,110 @@ if TYPE_CHECKING:
from ..endpoint import Endpoint
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.Alarms.cluster_id)
class Alarms(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Alarms.cluster_id)
class AlarmsClusterHandler(ClusterHandler):
"""Alarms cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.AnalogInput.cluster_id)
class AnalogInput(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(AnalogInput.cluster_id)
class AnalogInputClusterHandler(ClusterHandler):
"""Analog Input cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=general.AnalogInput.AttributeDefs.present_value.name,
attr=AnalogInput.AttributeDefs.present_value.name,
config=REPORT_CONFIG_DEFAULT,
),
)
@registries.BINDABLE_CLUSTERS.register(general.AnalogOutput.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.AnalogOutput.cluster_id)
class AnalogOutput(ClusterHandler):
@registries.BINDABLE_CLUSTERS.register(AnalogOutput.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(AnalogOutput.cluster_id)
class AnalogOutputClusterHandler(ClusterHandler):
"""Analog Output cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=general.AnalogOutput.AttributeDefs.present_value.name,
attr=AnalogOutput.AttributeDefs.present_value.name,
config=REPORT_CONFIG_DEFAULT,
),
)
ZCL_INIT_ATTRS = {
general.AnalogOutput.AttributeDefs.min_present_value.name: True,
general.AnalogOutput.AttributeDefs.max_present_value.name: True,
general.AnalogOutput.AttributeDefs.resolution.name: True,
general.AnalogOutput.AttributeDefs.relinquish_default.name: True,
general.AnalogOutput.AttributeDefs.description.name: True,
general.AnalogOutput.AttributeDefs.engineering_units.name: True,
general.AnalogOutput.AttributeDefs.application_type.name: True,
AnalogOutput.AttributeDefs.min_present_value.name: True,
AnalogOutput.AttributeDefs.max_present_value.name: True,
AnalogOutput.AttributeDefs.resolution.name: True,
AnalogOutput.AttributeDefs.relinquish_default.name: True,
AnalogOutput.AttributeDefs.description.name: True,
AnalogOutput.AttributeDefs.engineering_units.name: True,
AnalogOutput.AttributeDefs.application_type.name: True,
}
@property
def present_value(self) -> float | None:
"""Return cached value of present_value."""
return self.cluster.get(general.AnalogOutput.AttributeDefs.present_value.name)
return self.cluster.get(AnalogOutput.AttributeDefs.present_value.name)
@property
def min_present_value(self) -> float | None:
"""Return cached value of min_present_value."""
return self.cluster.get(
general.AnalogOutput.AttributeDefs.min_present_value.name
)
return self.cluster.get(AnalogOutput.AttributeDefs.min_present_value.name)
@property
def max_present_value(self) -> float | None:
"""Return cached value of max_present_value."""
return self.cluster.get(
general.AnalogOutput.AttributeDefs.max_present_value.name
)
return self.cluster.get(AnalogOutput.AttributeDefs.max_present_value.name)
@property
def resolution(self) -> float | None:
"""Return cached value of resolution."""
return self.cluster.get(general.AnalogOutput.AttributeDefs.resolution.name)
return self.cluster.get(AnalogOutput.AttributeDefs.resolution.name)
@property
def relinquish_default(self) -> float | None:
"""Return cached value of relinquish_default."""
return self.cluster.get(
general.AnalogOutput.AttributeDefs.relinquish_default.name
)
return self.cluster.get(AnalogOutput.AttributeDefs.relinquish_default.name)
@property
def description(self) -> str | None:
"""Return cached value of description."""
return self.cluster.get(general.AnalogOutput.AttributeDefs.description.name)
return self.cluster.get(AnalogOutput.AttributeDefs.description.name)
@property
def engineering_units(self) -> int | None:
"""Return cached value of engineering_units."""
return self.cluster.get(
general.AnalogOutput.AttributeDefs.engineering_units.name
)
return self.cluster.get(AnalogOutput.AttributeDefs.engineering_units.name)
@property
def application_type(self) -> int | None:
"""Return cached value of application_type."""
return self.cluster.get(
general.AnalogOutput.AttributeDefs.application_type.name
)
return self.cluster.get(AnalogOutput.AttributeDefs.application_type.name)
async def async_set_present_value(self, value: float) -> None:
"""Update present_value."""
await self.write_attributes_safe(
{general.AnalogOutput.AttributeDefs.present_value.name: value}
{AnalogOutput.AttributeDefs.present_value.name: value}
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.AnalogValue.cluster_id)
class AnalogValue(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(AnalogValue.cluster_id)
class AnalogValueClusterHandler(ClusterHandler):
"""Analog Value cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=general.AnalogValue.AttributeDefs.present_value.name,
attr=AnalogValue.AttributeDefs.present_value.name,
config=REPORT_CONFIG_DEFAULT,
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
general.ApplianceControl.cluster_id
)
class ApplianceContorl(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(ApplianceControl.cluster_id)
class ApplianceControlClusterHandler(ClusterHandler):
"""Appliance Control cluster handler."""
@registries.CLUSTER_HANDLER_ONLY_CLUSTERS.register(general.Basic.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.Basic.cluster_id)
@registries.CLUSTER_HANDLER_ONLY_CLUSTERS.register(Basic.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Basic.cluster_id)
class BasicClusterHandler(ClusterHandler):
"""Cluster handler to interact with the basic cluster."""
@ -187,77 +204,75 @@ class BasicClusterHandler(ClusterHandler):
self.ZCL_INIT_ATTRS["transmit_power"] = True
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.BinaryInput.cluster_id)
class BinaryInput(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(BinaryInput.cluster_id)
class BinaryInputClusterHandler(ClusterHandler):
"""Binary Input cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=general.BinaryInput.AttributeDefs.present_value.name,
attr=BinaryInput.AttributeDefs.present_value.name,
config=REPORT_CONFIG_DEFAULT,
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.BinaryOutput.cluster_id)
class BinaryOutput(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(BinaryOutput.cluster_id)
class BinaryOutputClusterHandler(ClusterHandler):
"""Binary Output cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=general.BinaryOutput.AttributeDefs.present_value.name,
attr=BinaryOutput.AttributeDefs.present_value.name,
config=REPORT_CONFIG_DEFAULT,
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.BinaryValue.cluster_id)
class BinaryValue(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(BinaryValue.cluster_id)
class BinaryValueClusterHandler(ClusterHandler):
"""Binary Value cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=general.BinaryValue.AttributeDefs.present_value.name,
attr=BinaryValue.AttributeDefs.present_value.name,
config=REPORT_CONFIG_DEFAULT,
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.Commissioning.cluster_id)
class Commissioning(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Commissioning.cluster_id)
class CommissioningClusterHandler(ClusterHandler):
"""Commissioning cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
general.DeviceTemperature.cluster_id
)
class DeviceTemperature(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(DeviceTemperature.cluster_id)
class DeviceTemperatureClusterHandler(ClusterHandler):
"""Device Temperature cluster handler."""
REPORT_CONFIG = (
{
"attr": general.DeviceTemperature.AttributeDefs.current_temperature.name,
"attr": DeviceTemperature.AttributeDefs.current_temperature.name,
"config": (REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT, 50),
},
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.GreenPowerProxy.cluster_id)
class GreenPowerProxy(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(GreenPowerProxy.cluster_id)
class GreenPowerProxyClusterHandler(ClusterHandler):
"""Green Power Proxy cluster handler."""
BIND: bool = False
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.Groups.cluster_id)
class Groups(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Groups.cluster_id)
class GroupsClusterHandler(ClusterHandler):
"""Groups cluster handler."""
BIND: bool = False
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.Identify.cluster_id)
class Identify(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Identify.cluster_id)
class IdentifyClusterHandler(ClusterHandler):
"""Identify cluster handler."""
BIND: bool = False
@ -267,40 +282,40 @@ class Identify(ClusterHandler):
"""Handle commands received to this cluster."""
cmd = parse_and_log_command(self, tsn, command_id, args)
if cmd == general.Identify.ServerCommandDefs.trigger_effect.name:
if cmd == Identify.ServerCommandDefs.trigger_effect.name:
self.async_send_signal(f"{self.unique_id}_{cmd}", args[0])
@registries.CLIENT_CLUSTER_HANDLER_REGISTRY.register(general.LevelControl.cluster_id)
@registries.CLIENT_CLUSTER_HANDLER_REGISTRY.register(LevelControl.cluster_id)
class LevelControlClientClusterHandler(ClientClusterHandler):
"""LevelControl client cluster."""
@registries.BINDABLE_CLUSTERS.register(general.LevelControl.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.LevelControl.cluster_id)
@registries.BINDABLE_CLUSTERS.register(LevelControl.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(LevelControl.cluster_id)
class LevelControlClusterHandler(ClusterHandler):
"""Cluster handler for the LevelControl Zigbee cluster."""
CURRENT_LEVEL = 0
REPORT_CONFIG = (
AttrReportConfig(
attr=general.LevelControl.AttributeDefs.current_level.name,
attr=LevelControl.AttributeDefs.current_level.name,
config=REPORT_CONFIG_ASAP,
),
)
ZCL_INIT_ATTRS = {
general.LevelControl.AttributeDefs.on_off_transition_time.name: True,
general.LevelControl.AttributeDefs.on_level.name: True,
general.LevelControl.AttributeDefs.on_transition_time.name: True,
general.LevelControl.AttributeDefs.off_transition_time.name: True,
general.LevelControl.AttributeDefs.default_move_rate.name: True,
general.LevelControl.AttributeDefs.start_up_current_level.name: True,
LevelControl.AttributeDefs.on_off_transition_time.name: True,
LevelControl.AttributeDefs.on_level.name: True,
LevelControl.AttributeDefs.on_transition_time.name: True,
LevelControl.AttributeDefs.off_transition_time.name: True,
LevelControl.AttributeDefs.default_move_rate.name: True,
LevelControl.AttributeDefs.start_up_current_level.name: True,
}
@property
def current_level(self) -> int | None:
"""Return cached value of the current_level attribute."""
return self.cluster.get(general.LevelControl.AttributeDefs.current_level.name)
return self.cluster.get(LevelControl.AttributeDefs.current_level.name)
@callback
def cluster_command(self, tsn, command_id, args):
@ -308,13 +323,13 @@ class LevelControlClusterHandler(ClusterHandler):
cmd = parse_and_log_command(self, tsn, command_id, args)
if cmd in (
general.LevelControl.ServerCommandDefs.move_to_level.name,
general.LevelControl.ServerCommandDefs.move_to_level_with_on_off.name,
LevelControl.ServerCommandDefs.move_to_level.name,
LevelControl.ServerCommandDefs.move_to_level_with_on_off.name,
):
self.dispatch_level_change(SIGNAL_SET_LEVEL, args[0])
elif cmd in (
general.LevelControl.ServerCommandDefs.move.name,
general.LevelControl.ServerCommandDefs.move_with_on_off.name,
LevelControl.ServerCommandDefs.move.name,
LevelControl.ServerCommandDefs.move_with_on_off.name,
):
# We should dim slowly -- for now, just step once
rate = args[1]
@ -322,8 +337,8 @@ class LevelControlClusterHandler(ClusterHandler):
rate = 10 # Should read default move rate
self.dispatch_level_change(SIGNAL_MOVE_LEVEL, -rate if args[0] else rate)
elif cmd in (
general.LevelControl.ServerCommandDefs.step.name,
general.LevelControl.ServerCommandDefs.step_with_on_off.name,
LevelControl.ServerCommandDefs.step.name,
LevelControl.ServerCommandDefs.step_with_on_off.name,
):
# Step (technically may change on/off)
self.dispatch_level_change(
@ -342,61 +357,59 @@ class LevelControlClusterHandler(ClusterHandler):
self.async_send_signal(f"{self.unique_id}_{command}", level)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.MultistateInput.cluster_id)
class MultistateInput(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(MultistateInput.cluster_id)
class MultistateInputClusterHandler(ClusterHandler):
"""Multistate Input cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=general.MultistateInput.AttributeDefs.present_value.name,
attr=MultistateInput.AttributeDefs.present_value.name,
config=REPORT_CONFIG_DEFAULT,
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
general.MultistateOutput.cluster_id
)
class MultistateOutput(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(MultistateOutput.cluster_id)
class MultistateOutputClusterHandler(ClusterHandler):
"""Multistate Output cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=general.MultistateOutput.AttributeDefs.present_value.name,
attr=MultistateOutput.AttributeDefs.present_value.name,
config=REPORT_CONFIG_DEFAULT,
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.MultistateValue.cluster_id)
class MultistateValue(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(MultistateValue.cluster_id)
class MultistateValueClusterHandler(ClusterHandler):
"""Multistate Value cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=general.MultistateValue.AttributeDefs.present_value.name,
attr=MultistateValue.AttributeDefs.present_value.name,
config=REPORT_CONFIG_DEFAULT,
),
)
@registries.CLIENT_CLUSTER_HANDLER_REGISTRY.register(general.OnOff.cluster_id)
@registries.CLIENT_CLUSTER_HANDLER_REGISTRY.register(OnOff.cluster_id)
class OnOffClientClusterHandler(ClientClusterHandler):
"""OnOff client cluster handler."""
@registries.BINDABLE_CLUSTERS.register(general.OnOff.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.OnOff.cluster_id)
@registries.BINDABLE_CLUSTERS.register(OnOff.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(OnOff.cluster_id)
class OnOffClusterHandler(ClusterHandler):
"""Cluster handler for the OnOff Zigbee cluster."""
REPORT_CONFIG = (
AttrReportConfig(
attr=general.OnOff.AttributeDefs.on_off.name, config=REPORT_CONFIG_IMMEDIATE
attr=OnOff.AttributeDefs.on_off.name, config=REPORT_CONFIG_IMMEDIATE
),
)
ZCL_INIT_ATTRS = {
general.OnOff.AttributeDefs.start_up_on_off.name: True,
OnOff.AttributeDefs.start_up_on_off.name: True,
}
def __init__(self, cluster: zigpy.zcl.Cluster, endpoint: Endpoint) -> None:
@ -422,25 +435,21 @@ class OnOffClusterHandler(ClusterHandler):
@property
def on_off(self) -> bool | None:
"""Return cached value of on/off attribute."""
return self.cluster.get(general.OnOff.AttributeDefs.on_off.name)
return self.cluster.get(OnOff.AttributeDefs.on_off.name)
async def turn_on(self) -> None:
"""Turn the on off cluster on."""
result = await self.on()
if result[1] is not Status.SUCCESS:
raise HomeAssistantError(f"Failed to turn on: {result[1]}")
self.cluster.update_attribute(
general.OnOff.AttributeDefs.on_off.id, t.Bool.true
)
self.cluster.update_attribute(OnOff.AttributeDefs.on_off.id, t.Bool.true)
async def turn_off(self) -> None:
"""Turn the on off cluster off."""
result = await self.off()
if result[1] is not Status.SUCCESS:
raise HomeAssistantError(f"Failed to turn off: {result[1]}")
self.cluster.update_attribute(
general.OnOff.AttributeDefs.on_off.id, t.Bool.false
)
self.cluster.update_attribute(OnOff.AttributeDefs.on_off.id, t.Bool.false)
@callback
def cluster_command(self, tsn, command_id, args):
@ -448,20 +457,16 @@ class OnOffClusterHandler(ClusterHandler):
cmd = parse_and_log_command(self, tsn, command_id, args)
if cmd in (
general.OnOff.ServerCommandDefs.off.name,
general.OnOff.ServerCommandDefs.off_with_effect.name,
OnOff.ServerCommandDefs.off.name,
OnOff.ServerCommandDefs.off_with_effect.name,
):
self.cluster.update_attribute(
general.OnOff.AttributeDefs.on_off.id, t.Bool.false
)
self.cluster.update_attribute(OnOff.AttributeDefs.on_off.id, t.Bool.false)
elif cmd in (
general.OnOff.ServerCommandDefs.on.name,
general.OnOff.ServerCommandDefs.on_with_recall_global_scene.name,
OnOff.ServerCommandDefs.on.name,
OnOff.ServerCommandDefs.on_with_recall_global_scene.name,
):
self.cluster.update_attribute(
general.OnOff.AttributeDefs.on_off.id, t.Bool.true
)
elif cmd == general.OnOff.ServerCommandDefs.on_with_timed_off.name:
self.cluster.update_attribute(OnOff.AttributeDefs.on_off.id, t.Bool.true)
elif cmd == OnOff.ServerCommandDefs.on_with_timed_off.name:
should_accept = args[0]
on_time = args[1]
# 0 is always accept 1 is only accept when already on
@ -470,7 +475,7 @@ class OnOffClusterHandler(ClusterHandler):
self._off_listener()
self._off_listener = None
self.cluster.update_attribute(
general.OnOff.AttributeDefs.on_off.id, t.Bool.true
OnOff.AttributeDefs.on_off.id, t.Bool.true
)
if on_time > 0:
self._off_listener = async_call_later(
@ -480,25 +485,23 @@ class OnOffClusterHandler(ClusterHandler):
)
elif cmd == "toggle":
self.cluster.update_attribute(
general.OnOff.AttributeDefs.on_off.id, not bool(self.on_off)
OnOff.AttributeDefs.on_off.id, not bool(self.on_off)
)
@callback
def set_to_off(self, *_):
"""Set the state to off."""
self._off_listener = None
self.cluster.update_attribute(
general.OnOff.AttributeDefs.on_off.id, t.Bool.false
)
self.cluster.update_attribute(OnOff.AttributeDefs.on_off.id, t.Bool.false)
@callback
def attribute_updated(self, attrid: int, value: Any, _: Any) -> None:
"""Handle attribute updates on this cluster."""
if attrid == general.OnOff.AttributeDefs.on_off.id:
if attrid == OnOff.AttributeDefs.on_off.id:
self.async_send_signal(
f"{self.unique_id}_{SIGNAL_ATTR_UPDATED}",
attrid,
general.OnOff.AttributeDefs.on_off.name,
OnOff.AttributeDefs.on_off.name,
value,
)
@ -509,21 +512,19 @@ class OnOffClusterHandler(ClusterHandler):
from_cache = not self._endpoint.device.is_mains_powered
self.debug("attempting to update onoff state - from cache: %s", from_cache)
await self.get_attribute_value(
general.OnOff.AttributeDefs.on_off.id, from_cache=from_cache
OnOff.AttributeDefs.on_off.id, from_cache=from_cache
)
await super().async_update()
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
general.OnOffConfiguration.cluster_id
)
class OnOffConfiguration(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(OnOffConfiguration.cluster_id)
class OnOffConfigurationClusterHandler(ClusterHandler):
"""OnOff Configuration cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.Ota.cluster_id)
@registries.CLIENT_CLUSTER_HANDLER_REGISTRY.register(general.Ota.cluster_id)
class Ota(ClientClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Ota.cluster_id)
@registries.CLIENT_CLUSTER_HANDLER_REGISTRY.register(Ota.cluster_id)
class OtaClientClusterHandler(ClientClusterHandler):
"""OTA cluster handler."""
BIND: bool = False
@ -544,14 +545,14 @@ class Ota(ClientClusterHandler):
self.async_send_signal(SIGNAL_UPDATE_DEVICE.format(signal_id), args[3])
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.Partition.cluster_id)
class Partition(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Partition.cluster_id)
class PartitionClusterHandler(ClusterHandler):
"""Partition cluster handler."""
@registries.CLUSTER_HANDLER_ONLY_CLUSTERS.register(general.PollControl.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.PollControl.cluster_id)
class PollControl(ClusterHandler):
@registries.CLUSTER_HANDLER_ONLY_CLUSTERS.register(PollControl.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(PollControl.cluster_id)
class PollControlClusterHandler(ClusterHandler):
"""Poll Control cluster handler."""
CHECKIN_INTERVAL = 55 * 60 * 4 # 55min
@ -564,9 +565,7 @@ class PollControl(ClusterHandler):
async def async_configure_cluster_handler_specific(self) -> None:
"""Configure cluster handler: set check-in interval."""
await self.write_attributes_safe(
{
general.PollControl.AttributeDefs.checkin_interval.name: self.CHECKIN_INTERVAL
}
{PollControl.AttributeDefs.checkin_interval.name: self.CHECKIN_INTERVAL}
)
@callback
@ -581,7 +580,7 @@ class PollControl(ClusterHandler):
self.debug("Received %s tsn command '%s': %s", tsn, cmd_name, args)
self.zha_send_event(cmd_name, args)
if cmd_name == general.PollControl.ClientCommandDefs.checkin.name:
if cmd_name == PollControl.ClientCommandDefs.checkin.name:
self.cluster.create_catching_task(self.check_in_response(tsn))
async def check_in_response(self, tsn: int) -> None:
@ -597,19 +596,17 @@ class PollControl(ClusterHandler):
self._IGNORED_MANUFACTURER_ID.add(manufacturer_code)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
general.PowerConfiguration.cluster_id
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(PowerConfiguration.cluster_id)
class PowerConfigurationClusterHandler(ClusterHandler):
"""Cluster handler for the zigbee power configuration cluster."""
REPORT_CONFIG = (
AttrReportConfig(
attr=general.PowerConfiguration.AttributeDefs.battery_voltage.name,
attr=PowerConfiguration.AttributeDefs.battery_voltage.name,
config=REPORT_CONFIG_BATTERY_SAVE,
),
AttrReportConfig(
attr=general.PowerConfiguration.AttributeDefs.battery_percentage_remaining.name,
attr=PowerConfiguration.AttributeDefs.battery_percentage_remaining.name,
config=REPORT_CONFIG_BATTERY_SAVE,
),
)
@ -617,34 +614,34 @@ class PowerConfigurationClusterHandler(ClusterHandler):
def async_initialize_cluster_handler_specific(self, from_cache: bool) -> Coroutine:
"""Initialize cluster handler specific attrs."""
attributes = [
general.PowerConfiguration.AttributeDefs.battery_size.name,
general.PowerConfiguration.AttributeDefs.battery_quantity.name,
PowerConfiguration.AttributeDefs.battery_size.name,
PowerConfiguration.AttributeDefs.battery_quantity.name,
]
return self.get_attributes(
attributes, from_cache=from_cache, only_cache=from_cache
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.PowerProfile.cluster_id)
class PowerProfile(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(PowerProfile.cluster_id)
class PowerProfileClusterHandler(ClusterHandler):
"""Power Profile cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.RSSILocation.cluster_id)
class RSSILocation(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(RSSILocation.cluster_id)
class RSSILocationClusterHandler(ClusterHandler):
"""RSSI Location cluster handler."""
@registries.CLIENT_CLUSTER_HANDLER_REGISTRY.register(general.Scenes.cluster_id)
@registries.CLIENT_CLUSTER_HANDLER_REGISTRY.register(Scenes.cluster_id)
class ScenesClientClusterHandler(ClientClusterHandler):
"""Scenes cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.Scenes.cluster_id)
class Scenes(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Scenes.cluster_id)
class ScenesClusterHandler(ClusterHandler):
"""Scenes cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(general.Time.cluster_id)
class Time(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Time.cluster_id)
class TimeClusterHandler(ClusterHandler):
"""Time cluster handler."""

View file

@ -3,8 +3,14 @@ from __future__ import annotations
import enum
from zigpy.zcl.clusters import homeautomation
from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement
from zigpy.zcl.clusters.homeautomation import (
ApplianceEventAlerts,
ApplianceIdentification,
ApplianceStatistics,
Diagnostic,
ElectricalMeasurement,
MeterIdentification,
)
from .. import registries
from ..const import (
@ -16,31 +22,23 @@ from ..const import (
from . import AttrReportConfig, ClusterHandler
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
homeautomation.ApplianceEventAlerts.cluster_id
)
class ApplianceEventAlerts(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(ApplianceEventAlerts.cluster_id)
class ApplianceEventAlertsClusterHandler(ClusterHandler):
"""Appliance Event Alerts cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
homeautomation.ApplianceIdentification.cluster_id
)
class ApplianceIdentification(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(ApplianceIdentification.cluster_id)
class ApplianceIdentificationClusterHandler(ClusterHandler):
"""Appliance Identification cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
homeautomation.ApplianceStatistics.cluster_id
)
class ApplianceStatistics(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(ApplianceStatistics.cluster_id)
class ApplianceStatisticsClusterHandler(ClusterHandler):
"""Appliance Statistics cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
homeautomation.Diagnostic.cluster_id
)
class Diagnostic(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Diagnostic.cluster_id)
class DiagnosticClusterHandler(ClusterHandler):
"""Diagnostic cluster handler."""
@ -232,8 +230,6 @@ class ElectricalMeasurementClusterHandler(ClusterHandler):
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
homeautomation.MeterIdentification.cluster_id
)
class MeterIdentification(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(MeterIdentification.cluster_id)
class MeterIdentificationClusterHandler(ClusterHandler):
"""Metering Identification cluster handler."""

View file

@ -7,8 +7,13 @@ from __future__ import annotations
from typing import Any
from zigpy.zcl.clusters import hvac
from zigpy.zcl.clusters.hvac import Fan, Thermostat
from zigpy.zcl.clusters.hvac import (
Dehumidification,
Fan,
Pump,
Thermostat,
UserInterface,
)
from homeassistant.core import callback
@ -26,8 +31,8 @@ REPORT_CONFIG_CLIMATE_DEMAND = (REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT, 5)
REPORT_CONFIG_CLIMATE_DISCRETE = (REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT, 1)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(hvac.Dehumidification.cluster_id)
class Dehumidification(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Dehumidification.cluster_id)
class DehumidificationClusterHandler(ClusterHandler):
"""Dehumidification cluster handler."""
@ -75,8 +80,8 @@ class FanClusterHandler(ClusterHandler):
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(hvac.Pump.cluster_id)
class Pump(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Pump.cluster_id)
class PumpClusterHandler(ClusterHandler):
"""Pump cluster handler."""
@ -333,6 +338,6 @@ class ThermostatClusterHandler(ClusterHandler):
return bool(self.occupancy)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(hvac.UserInterface.cluster_id)
class UserInterface(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(UserInterface.cluster_id)
class UserInterfaceClusterHandler(ClusterHandler):
"""User interface (thermostat) cluster handler."""

View file

@ -1,8 +1,7 @@
"""Lighting cluster handlers module for Zigbee Home Automation."""
from __future__ import annotations
from zigpy.zcl.clusters import lighting
from zigpy.zcl.clusters.lighting import Color
from zigpy.zcl.clusters.lighting import Ballast, Color
from homeassistant.backports.functools import cached_property
@ -11,8 +10,8 @@ from ..const import REPORT_CONFIG_DEFAULT
from . import AttrReportConfig, ClientClusterHandler, ClusterHandler
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(lighting.Ballast.cluster_id)
class Ballast(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Ballast.cluster_id)
class BallastClusterHandler(ClusterHandler):
"""Ballast cluster handler."""

View file

@ -2,16 +2,16 @@
import asyncio
import zigpy.exceptions
from zigpy.zcl.clusters import lightlink
from zigpy.zcl.clusters.lightlink import LightLink
from zigpy.zcl.foundation import GENERAL_COMMANDS, GeneralCommand
from .. import registries
from . import ClusterHandler, ClusterHandlerStatus
@registries.CLUSTER_HANDLER_ONLY_CLUSTERS.register(lightlink.LightLink.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(lightlink.LightLink.cluster_id)
class LightLink(ClusterHandler):
@registries.CLUSTER_HANDLER_ONLY_CLUSTERS.register(LightLink.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(LightLink.cluster_id)
class LightLinkClusterHandler(ClusterHandler):
"""Lightlink cluster handler."""
BIND: bool = False

View file

@ -25,7 +25,7 @@ from ..const import (
UNKNOWN,
)
from . import AttrReportConfig, ClientClusterHandler, ClusterHandler
from .general import MultistateInput
from .general import MultistateInputClusterHandler
if TYPE_CHECKING:
from ..endpoint import Endpoint
@ -36,7 +36,7 @@ _LOGGER = logging.getLogger(__name__)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
registries.SMARTTHINGS_HUMIDITY_CLUSTER
)
class SmartThingsHumidity(ClusterHandler):
class SmartThingsHumidityClusterHandler(ClusterHandler):
"""Smart Things Humidity cluster handler."""
REPORT_CONFIG = (
@ -49,7 +49,7 @@ class SmartThingsHumidity(ClusterHandler):
@registries.CLUSTER_HANDLER_ONLY_CLUSTERS.register(0xFD00)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(0xFD00)
class OsramButton(ClusterHandler):
class OsramButtonClusterHandler(ClusterHandler):
"""Osram button cluster handler."""
REPORT_CONFIG = ()
@ -57,7 +57,7 @@ class OsramButton(ClusterHandler):
@registries.CLUSTER_HANDLER_ONLY_CLUSTERS.register(registries.PHILLIPS_REMOTE_CLUSTER)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(registries.PHILLIPS_REMOTE_CLUSTER)
class PhillipsRemote(ClusterHandler):
class PhillipsRemoteClusterHandler(ClusterHandler):
"""Phillips remote cluster handler."""
REPORT_CONFIG = ()
@ -84,7 +84,7 @@ class TuyaClusterHandler(ClusterHandler):
@registries.CLUSTER_HANDLER_ONLY_CLUSTERS.register(0xFCC0)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(0xFCC0)
class OppleRemote(ClusterHandler):
class OppleRemoteClusterHandler(ClusterHandler):
"""Opple cluster handler."""
REPORT_CONFIG = ()
@ -173,7 +173,7 @@ class OppleRemote(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
registries.SMARTTHINGS_ACCELERATION_CLUSTER
)
class SmartThingsAcceleration(ClusterHandler):
class SmartThingsAccelerationClusterHandler(ClusterHandler):
"""Smart Things Acceleration cluster handler."""
REPORT_CONFIG = (
@ -220,7 +220,7 @@ class SmartThingsAcceleration(ClusterHandler):
@registries.CLIENT_CLUSTER_HANDLER_REGISTRY.register(0xFC31)
class InovelliNotificationClusterHandler(ClientClusterHandler):
class InovelliNotificationClientClusterHandler(ClientClusterHandler):
"""Inovelli Notification cluster handler."""
@callback
@ -412,7 +412,7 @@ class IkeaAirPurifierClusterHandler(ClusterHandler):
@registries.CLUSTER_HANDLER_ONLY_CLUSTERS.register(0xFC80)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(0xFC80)
class IkeaRemote(ClusterHandler):
class IkeaRemoteClusterHandler(ClusterHandler):
"""Ikea Matter remote cluster handler."""
REPORT_CONFIG = ()
@ -421,13 +421,13 @@ class IkeaRemote(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
DoorLock.cluster_id, XIAOMI_AQARA_VIBRATION_AQ1
)
class XiaomiVibrationAQ1ClusterHandler(MultistateInput):
class XiaomiVibrationAQ1ClusterHandler(MultistateInputClusterHandler):
"""Xiaomi DoorLock Cluster is in fact a MultiStateInput Cluster."""
@registries.CLUSTER_HANDLER_ONLY_CLUSTERS.register(0xFC11)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(0xFC11)
class SonoffPresenceSenor(ClusterHandler):
class SonoffPresenceSenorClusterHandler(ClusterHandler):
"""SonoffPresenceSensor cluster handler."""
ZCL_INIT_ATTRS = {"last_illumination_state": True}

View file

@ -4,7 +4,21 @@ from __future__ import annotations
from typing import TYPE_CHECKING
import zigpy.zcl
from zigpy.zcl.clusters import measurement
from zigpy.zcl.clusters.measurement import (
PM25,
CarbonDioxideConcentration,
CarbonMonoxideConcentration,
FlowMeasurement,
FormaldehydeConcentration,
IlluminanceLevelSensing,
IlluminanceMeasurement,
LeafWetness,
OccupancySensing,
PressureMeasurement,
RelativeHumidity,
SoilMoisture,
TemperatureMeasurement,
)
from .. import registries
from ..const import (
@ -20,57 +34,49 @@ if TYPE_CHECKING:
from ..endpoint import Endpoint
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
measurement.FlowMeasurement.cluster_id
)
class FlowMeasurement(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(FlowMeasurement.cluster_id)
class FlowMeasurementClusterHandler(ClusterHandler):
"""Flow Measurement cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=measurement.FlowMeasurement.AttributeDefs.measured_value.name,
attr=FlowMeasurement.AttributeDefs.measured_value.name,
config=REPORT_CONFIG_DEFAULT,
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
measurement.IlluminanceLevelSensing.cluster_id
)
class IlluminanceLevelSensing(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(IlluminanceLevelSensing.cluster_id)
class IlluminanceLevelSensingClusterHandler(ClusterHandler):
"""Illuminance Level Sensing cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=measurement.IlluminanceLevelSensing.AttributeDefs.level_status.name,
attr=IlluminanceLevelSensing.AttributeDefs.level_status.name,
config=REPORT_CONFIG_DEFAULT,
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
measurement.IlluminanceMeasurement.cluster_id
)
class IlluminanceMeasurement(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(IlluminanceMeasurement.cluster_id)
class IlluminanceMeasurementClusterHandler(ClusterHandler):
"""Illuminance Measurement cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=measurement.IlluminanceMeasurement.AttributeDefs.measured_value.name,
attr=IlluminanceMeasurement.AttributeDefs.measured_value.name,
config=REPORT_CONFIG_DEFAULT,
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
measurement.OccupancySensing.cluster_id
)
class OccupancySensing(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(OccupancySensing.cluster_id)
class OccupancySensingClusterHandler(ClusterHandler):
"""Occupancy Sensing cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=measurement.OccupancySensing.AttributeDefs.occupancy.name,
attr=OccupancySensing.AttributeDefs.occupancy.name,
config=REPORT_CONFIG_IMMEDIATE,
),
)
@ -87,123 +93,115 @@ class OccupancySensing(ClusterHandler):
self.ZCL_INIT_ATTRS["ultrasonic_u_to_o_threshold"] = True
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
measurement.PressureMeasurement.cluster_id
)
class PressureMeasurement(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(PressureMeasurement.cluster_id)
class PressureMeasurementClusterHandler(ClusterHandler):
"""Pressure measurement cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=measurement.PressureMeasurement.AttributeDefs.measured_value.name,
attr=PressureMeasurement.AttributeDefs.measured_value.name,
config=REPORT_CONFIG_DEFAULT,
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
measurement.RelativeHumidity.cluster_id
)
class RelativeHumidity(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(RelativeHumidity.cluster_id)
class RelativeHumidityClusterHandler(ClusterHandler):
"""Relative Humidity measurement cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=measurement.RelativeHumidity.AttributeDefs.measured_value.name,
attr=RelativeHumidity.AttributeDefs.measured_value.name,
config=(REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT, 100),
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
measurement.SoilMoisture.cluster_id
)
class SoilMoisture(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(SoilMoisture.cluster_id)
class SoilMoistureClusterHandler(ClusterHandler):
"""Soil Moisture measurement cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=measurement.SoilMoisture.AttributeDefs.measured_value.name,
attr=SoilMoisture.AttributeDefs.measured_value.name,
config=(REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT, 100),
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(measurement.LeafWetness.cluster_id)
class LeafWetness(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(LeafWetness.cluster_id)
class LeafWetnessClusterHandler(ClusterHandler):
"""Leaf Wetness measurement cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=measurement.LeafWetness.AttributeDefs.measured_value.name,
attr=LeafWetness.AttributeDefs.measured_value.name,
config=(REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT, 100),
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
measurement.TemperatureMeasurement.cluster_id
)
class TemperatureMeasurement(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(TemperatureMeasurement.cluster_id)
class TemperatureMeasurementClusterHandler(ClusterHandler):
"""Temperature measurement cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=measurement.TemperatureMeasurement.AttributeDefs.measured_value.name,
attr=TemperatureMeasurement.AttributeDefs.measured_value.name,
config=(REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT, 50),
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
measurement.CarbonMonoxideConcentration.cluster_id
CarbonMonoxideConcentration.cluster_id
)
class CarbonMonoxideConcentration(ClusterHandler):
class CarbonMonoxideConcentrationClusterHandler(ClusterHandler):
"""Carbon Monoxide measurement cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=measurement.CarbonMonoxideConcentration.AttributeDefs.measured_value.name,
attr=CarbonMonoxideConcentration.AttributeDefs.measured_value.name,
config=(REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT, 0.000001),
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
measurement.CarbonDioxideConcentration.cluster_id
CarbonDioxideConcentration.cluster_id
)
class CarbonDioxideConcentration(ClusterHandler):
class CarbonDioxideConcentrationClusterHandler(ClusterHandler):
"""Carbon Dioxide measurement cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=measurement.CarbonDioxideConcentration.AttributeDefs.measured_value.name,
attr=CarbonDioxideConcentration.AttributeDefs.measured_value.name,
config=(REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT, 0.000001),
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(measurement.PM25.cluster_id)
class PM25(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(PM25.cluster_id)
class PM25ClusterHandler(ClusterHandler):
"""Particulate Matter 2.5 microns or less measurement cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=measurement.PM25.AttributeDefs.measured_value.name,
attr=PM25.AttributeDefs.measured_value.name,
config=(REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT, 0.1),
),
)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
measurement.FormaldehydeConcentration.cluster_id
FormaldehydeConcentration.cluster_id
)
class FormaldehydeConcentration(ClusterHandler):
class FormaldehydeConcentrationClusterHandler(ClusterHandler):
"""Formaldehyde measurement cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=measurement.FormaldehydeConcentration.AttributeDefs.measured_value.name,
attr=FormaldehydeConcentration.AttributeDefs.measured_value.name,
config=(REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT, 0.000001),
),
)

View file

@ -1,143 +1,128 @@
"""Protocol cluster handlers module for Zigbee Home Automation."""
from zigpy.zcl.clusters import protocol
from zigpy.zcl.clusters.protocol import (
AnalogInputExtended,
AnalogInputRegular,
AnalogOutputExtended,
AnalogOutputRegular,
AnalogValueExtended,
AnalogValueRegular,
BacnetProtocolTunnel,
BinaryInputExtended,
BinaryInputRegular,
BinaryOutputExtended,
BinaryOutputRegular,
BinaryValueExtended,
BinaryValueRegular,
GenericTunnel,
MultistateInputExtended,
MultistateInputRegular,
MultistateOutputExtended,
MultistateOutputRegular,
MultistateValueExtended,
MultistateValueRegular,
)
from .. import registries
from . import ClusterHandler
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.AnalogInputExtended.cluster_id
)
class AnalogInputExtended(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(AnalogInputExtended.cluster_id)
class AnalogInputExtendedClusterHandler(ClusterHandler):
"""Analog Input Extended cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.AnalogInputRegular.cluster_id
)
class AnalogInputRegular(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(AnalogInputRegular.cluster_id)
class AnalogInputRegularClusterHandler(ClusterHandler):
"""Analog Input Regular cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.AnalogOutputExtended.cluster_id
)
class AnalogOutputExtended(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(AnalogOutputExtended.cluster_id)
class AnalogOutputExtendedClusterHandler(ClusterHandler):
"""Analog Output Regular cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.AnalogOutputRegular.cluster_id
)
class AnalogOutputRegular(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(AnalogOutputRegular.cluster_id)
class AnalogOutputRegularClusterHandler(ClusterHandler):
"""Analog Output Regular cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.AnalogValueExtended.cluster_id
)
class AnalogValueExtended(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(AnalogValueExtended.cluster_id)
class AnalogValueExtendedClusterHandler(ClusterHandler):
"""Analog Value Extended edition cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.AnalogValueRegular.cluster_id
)
class AnalogValueRegular(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(AnalogValueRegular.cluster_id)
class AnalogValueRegularClusterHandler(ClusterHandler):
"""Analog Value Regular cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.BacnetProtocolTunnel.cluster_id
)
class BacnetProtocolTunnel(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(BacnetProtocolTunnel.cluster_id)
class BacnetProtocolTunnelClusterHandler(ClusterHandler):
"""Bacnet Protocol Tunnel cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.BinaryInputExtended.cluster_id
)
class BinaryInputExtended(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(BinaryInputExtended.cluster_id)
class BinaryInputExtendedClusterHandler(ClusterHandler):
"""Binary Input Extended cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.BinaryInputRegular.cluster_id
)
class BinaryInputRegular(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(BinaryInputRegular.cluster_id)
class BinaryInputRegularClusterHandler(ClusterHandler):
"""Binary Input Regular cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.BinaryOutputExtended.cluster_id
)
class BinaryOutputExtended(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(BinaryOutputExtended.cluster_id)
class BinaryOutputExtendedClusterHandler(ClusterHandler):
"""Binary Output Extended cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.BinaryOutputRegular.cluster_id
)
class BinaryOutputRegular(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(BinaryOutputRegular.cluster_id)
class BinaryOutputRegularClusterHandler(ClusterHandler):
"""Binary Output Regular cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.BinaryValueExtended.cluster_id
)
class BinaryValueExtended(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(BinaryValueExtended.cluster_id)
class BinaryValueExtendedClusterHandler(ClusterHandler):
"""Binary Value Extended cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.BinaryValueRegular.cluster_id
)
class BinaryValueRegular(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(BinaryValueRegular.cluster_id)
class BinaryValueRegularClusterHandler(ClusterHandler):
"""Binary Value Regular cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(protocol.GenericTunnel.cluster_id)
class GenericTunnel(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(GenericTunnel.cluster_id)
class GenericTunnelClusterHandler(ClusterHandler):
"""Generic Tunnel cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.MultistateInputExtended.cluster_id
)
class MultiStateInputExtended(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(MultistateInputExtended.cluster_id)
class MultiStateInputExtendedClusterHandler(ClusterHandler):
"""Multistate Input Extended cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.MultistateInputRegular.cluster_id
)
class MultiStateInputRegular(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(MultistateInputRegular.cluster_id)
class MultiStateInputRegularClusterHandler(ClusterHandler):
"""Multistate Input Regular cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.MultistateOutputExtended.cluster_id
MultistateOutputExtended.cluster_id
)
class MultiStateOutputExtended(ClusterHandler):
class MultiStateOutputExtendedClusterHandler(ClusterHandler):
"""Multistate Output Extended cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.MultistateOutputRegular.cluster_id
)
class MultiStateOutputRegular(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(MultistateOutputRegular.cluster_id)
class MultiStateOutputRegularClusterHandler(ClusterHandler):
"""Multistate Output Regular cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.MultistateValueExtended.cluster_id
)
class MultiStateValueExtended(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(MultistateValueExtended.cluster_id)
class MultiStateValueExtendedClusterHandler(ClusterHandler):
"""Multistate Value Extended cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
protocol.MultistateValueRegular.cluster_id
)
class MultiStateValueRegular(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(MultistateValueRegular.cluster_id)
class MultiStateValueRegularClusterHandler(ClusterHandler):
"""Multistate Value Regular cluster handler."""

View file

@ -9,8 +9,7 @@ from collections.abc import Callable
from typing import TYPE_CHECKING, Any
import zigpy.zcl
from zigpy.zcl.clusters import security
from zigpy.zcl.clusters.security import IasAce as AceCluster, IasZone
from zigpy.zcl.clusters.security import IasAce as AceCluster, IasWd, IasZone
from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
@ -34,7 +33,7 @@ SIGNAL_ALARM_TRIGGERED = "zha_armed_triggered"
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(AceCluster.cluster_id)
class IasAce(ClusterHandler):
class IasAceClusterHandler(ClusterHandler):
"""IAS Ancillary Control Equipment cluster handler."""
def __init__(self, cluster: zigpy.zcl.Cluster, endpoint: Endpoint) -> None:
@ -236,16 +235,16 @@ class IasAce(ClusterHandler):
"""Handle the IAS ACE zone status command."""
@registries.CLUSTER_HANDLER_ONLY_CLUSTERS.register(security.IasWd.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(security.IasWd.cluster_id)
class IasWd(ClusterHandler):
@registries.CLUSTER_HANDLER_ONLY_CLUSTERS.register(IasWd.cluster_id)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(IasWd.cluster_id)
class IasWdClusterHandler(ClusterHandler):
"""IAS Warning Device cluster handler."""
@staticmethod
def set_bit(destination_value, destination_bit, source_value, source_bit):
"""Set the specified bit in the value."""
if IasWd.get_bit(source_value, source_bit):
if IasWdClusterHandler.get_bit(source_value, source_bit):
return destination_value | (1 << destination_bit)
return destination_value
@ -267,15 +266,15 @@ class IasWd(ClusterHandler):
is currently active (warning in progress).
"""
value = 0
value = IasWd.set_bit(value, 0, squawk_level, 0)
value = IasWd.set_bit(value, 1, squawk_level, 1)
value = IasWdClusterHandler.set_bit(value, 0, squawk_level, 0)
value = IasWdClusterHandler.set_bit(value, 1, squawk_level, 1)
value = IasWd.set_bit(value, 3, strobe, 0)
value = IasWdClusterHandler.set_bit(value, 3, strobe, 0)
value = IasWd.set_bit(value, 4, mode, 0)
value = IasWd.set_bit(value, 5, mode, 1)
value = IasWd.set_bit(value, 6, mode, 2)
value = IasWd.set_bit(value, 7, mode, 3)
value = IasWdClusterHandler.set_bit(value, 4, mode, 0)
value = IasWdClusterHandler.set_bit(value, 5, mode, 1)
value = IasWdClusterHandler.set_bit(value, 6, mode, 2)
value = IasWdClusterHandler.set_bit(value, 7, mode, 3)
await self.squawk(value)
@ -304,15 +303,15 @@ class IasWd(ClusterHandler):
and then turn OFF for 6/10ths of a second.
"""
value = 0
value = IasWd.set_bit(value, 0, siren_level, 0)
value = IasWd.set_bit(value, 1, siren_level, 1)
value = IasWdClusterHandler.set_bit(value, 0, siren_level, 0)
value = IasWdClusterHandler.set_bit(value, 1, siren_level, 1)
value = IasWd.set_bit(value, 2, strobe, 0)
value = IasWdClusterHandler.set_bit(value, 2, strobe, 0)
value = IasWd.set_bit(value, 4, mode, 0)
value = IasWd.set_bit(value, 5, mode, 1)
value = IasWd.set_bit(value, 6, mode, 2)
value = IasWd.set_bit(value, 7, mode, 3)
value = IasWdClusterHandler.set_bit(value, 4, mode, 0)
value = IasWdClusterHandler.set_bit(value, 5, mode, 1)
value = IasWdClusterHandler.set_bit(value, 6, mode, 2)
value = IasWdClusterHandler.set_bit(value, 7, mode, 3)
await self.start_warning(
value, warning_duration, strobe_duty_cycle, strobe_intensity

View file

@ -6,7 +6,20 @@ from functools import partialmethod
from typing import TYPE_CHECKING
import zigpy.zcl
from zigpy.zcl.clusters import smartenergy
from zigpy.zcl.clusters.smartenergy import (
Calendar,
DeviceManagement,
Drlc,
EnergyManagement,
Events,
KeyEstablishment,
MduPairing,
Messaging,
Metering,
Prepayment,
Price,
Tunneling,
)
from .. import registries
from ..const import (
@ -21,108 +34,99 @@ if TYPE_CHECKING:
from ..endpoint import Endpoint
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(smartenergy.Calendar.cluster_id)
class Calendar(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Calendar.cluster_id)
class CalendarClusterHandler(ClusterHandler):
"""Calendar cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
smartenergy.DeviceManagement.cluster_id
)
class DeviceManagement(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(DeviceManagement.cluster_id)
class DeviceManagementClusterHandler(ClusterHandler):
"""Device Management cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(smartenergy.Drlc.cluster_id)
class Drlc(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Drlc.cluster_id)
class DrlcClusterHandler(ClusterHandler):
"""Demand Response and Load Control cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
smartenergy.EnergyManagement.cluster_id
)
class EnergyManagement(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(EnergyManagement.cluster_id)
class EnergyManagementClusterHandler(ClusterHandler):
"""Energy Management cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(smartenergy.Events.cluster_id)
class Events(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Events.cluster_id)
class EventsClusterHandler(ClusterHandler):
"""Event cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(
smartenergy.KeyEstablishment.cluster_id
)
class KeyEstablishment(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(KeyEstablishment.cluster_id)
class KeyEstablishmentClusterHandler(ClusterHandler):
"""Key Establishment cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(smartenergy.MduPairing.cluster_id)
class MduPairing(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(MduPairing.cluster_id)
class MduPairingClusterHandler(ClusterHandler):
"""Pairing cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(smartenergy.Messaging.cluster_id)
class Messaging(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Messaging.cluster_id)
class MessagingClusterHandler(ClusterHandler):
"""Messaging cluster handler."""
SEAttrs = smartenergy.Metering.AttributeDefs
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(smartenergy.Metering.cluster_id)
class Metering(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Metering.cluster_id)
class MeteringClusterHandler(ClusterHandler):
"""Metering cluster handler."""
REPORT_CONFIG = (
AttrReportConfig(
attr=SEAttrs.instantaneous_demand.name,
attr=Metering.AttributeDefs.instantaneous_demand.name,
config=REPORT_CONFIG_OP,
),
AttrReportConfig(
attr=SEAttrs.current_summ_delivered.name,
attr=Metering.AttributeDefs.current_summ_delivered.name,
config=REPORT_CONFIG_DEFAULT,
),
AttrReportConfig(
attr=SEAttrs.current_tier1_summ_delivered.name,
attr=Metering.AttributeDefs.current_tier1_summ_delivered.name,
config=REPORT_CONFIG_DEFAULT,
),
AttrReportConfig(
attr=SEAttrs.current_tier2_summ_delivered.name,
attr=Metering.AttributeDefs.current_tier2_summ_delivered.name,
config=REPORT_CONFIG_DEFAULT,
),
AttrReportConfig(
attr=SEAttrs.current_tier3_summ_delivered.name,
attr=Metering.AttributeDefs.current_tier3_summ_delivered.name,
config=REPORT_CONFIG_DEFAULT,
),
AttrReportConfig(
attr=SEAttrs.current_tier4_summ_delivered.name,
attr=Metering.AttributeDefs.current_tier4_summ_delivered.name,
config=REPORT_CONFIG_DEFAULT,
),
AttrReportConfig(
attr=SEAttrs.current_tier5_summ_delivered.name,
attr=Metering.AttributeDefs.current_tier5_summ_delivered.name,
config=REPORT_CONFIG_DEFAULT,
),
AttrReportConfig(
attr=SEAttrs.current_tier6_summ_delivered.name,
attr=Metering.AttributeDefs.current_tier6_summ_delivered.name,
config=REPORT_CONFIG_DEFAULT,
),
AttrReportConfig(
attr=SEAttrs.current_summ_received.name,
attr=Metering.AttributeDefs.current_summ_received.name,
config=REPORT_CONFIG_DEFAULT,
),
AttrReportConfig(
attr=SEAttrs.status.name,
attr=Metering.AttributeDefs.status.name,
config=REPORT_CONFIG_ASAP,
),
)
ZCL_INIT_ATTRS = {
SEAttrs.demand_formatting.name: True,
SEAttrs.divisor.name: True,
SEAttrs.metering_device_type.name: True,
SEAttrs.multiplier.name: True,
SEAttrs.summation_formatting.name: True,
SEAttrs.unit_of_measure.name: True,
Metering.AttributeDefs.demand_formatting.name: True,
Metering.AttributeDefs.divisor.name: True,
Metering.AttributeDefs.metering_device_type.name: True,
Metering.AttributeDefs.multiplier.name: True,
Metering.AttributeDefs.summation_formatting.name: True,
Metering.AttributeDefs.unit_of_measure.name: True,
}
metering_device_type = {
@ -174,12 +178,12 @@ class Metering(ClusterHandler):
@property
def divisor(self) -> int:
"""Return divisor for the value."""
return self.cluster.get(SEAttrs.divisor.name) or 1
return self.cluster.get(Metering.AttributeDefs.divisor.name) or 1
@property
def device_type(self) -> str | int | None:
"""Return metering device type."""
dev_type = self.cluster.get(SEAttrs.metering_device_type.name)
dev_type = self.cluster.get(Metering.AttributeDefs.metering_device_type.name)
if dev_type is None:
return None
return self.metering_device_type.get(dev_type, dev_type)
@ -187,14 +191,14 @@ class Metering(ClusterHandler):
@property
def multiplier(self) -> int:
"""Return multiplier for the value."""
return self.cluster.get(SEAttrs.multiplier.name) or 1
return self.cluster.get(Metering.AttributeDefs.multiplier.name) or 1
@property
def status(self) -> int | None:
"""Return metering device status."""
if (status := self.cluster.get(SEAttrs.status.name)) is None:
if (status := self.cluster.get(Metering.AttributeDefs.status.name)) is None:
return None
if self.cluster.get(SEAttrs.metering_device_type.name) == 0:
if self.cluster.get(Metering.AttributeDefs.metering_device_type.name) == 0:
# Electric metering device type
return self.DeviceStatusElectric(status)
return self.DeviceStatusDefault(status)
@ -202,18 +206,18 @@ class Metering(ClusterHandler):
@property
def unit_of_measurement(self) -> int:
"""Return unit of measurement."""
return self.cluster.get(SEAttrs.unit_of_measure.name)
return self.cluster.get(Metering.AttributeDefs.unit_of_measure.name)
async def async_initialize_cluster_handler_specific(self, from_cache: bool) -> None:
"""Fetch config from device and updates format specifier."""
fmting = self.cluster.get(
SEAttrs.demand_formatting.name, 0xF9
Metering.AttributeDefs.demand_formatting.name, 0xF9
) # 1 digit to the right, 15 digits to the left
self._format_spec = self.get_formatting(fmting)
fmting = self.cluster.get(
SEAttrs.summation_formatting.name, 0xF9
Metering.AttributeDefs.summation_formatting.name, 0xF9
) # 1 digit to the right, 15 digits to the left
self._summa_format = self.get_formatting(fmting)
@ -277,16 +281,16 @@ class Metering(ClusterHandler):
summa_formatter = partialmethod(_formatter_function, FormatSelector.SUMMATION)
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(smartenergy.Prepayment.cluster_id)
class Prepayment(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Prepayment.cluster_id)
class PrepaymentClusterHandler(ClusterHandler):
"""Prepayment cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(smartenergy.Price.cluster_id)
class Price(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Price.cluster_id)
class PriceClusterHandler(ClusterHandler):
"""Price cluster handler."""
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(smartenergy.Tunneling.cluster_id)
class Tunneling(ClusterHandler):
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Tunneling.cluster_id)
class TunnelingClusterHandler(ClusterHandler):
"""Tunneling cluster handler."""

View file

@ -22,7 +22,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_call_later
from .core import discovery
from .core.cluster_handlers.security import IasWd
from .core.cluster_handlers.security import IasWdClusterHandler
from .core.const import (
CLUSTER_HANDLER_IAS_WD,
SIGNAL_ADD_ENTITIES,
@ -101,7 +101,9 @@ class ZHASiren(ZhaEntity, SirenEntity):
WARNING_DEVICE_MODE_EMERGENCY_PANIC: "Emergency Panic",
}
super().__init__(unique_id, zha_device, cluster_handlers, **kwargs)
self._cluster_handler: IasWd = cast(IasWd, cluster_handlers[0])
self._cluster_handler: IasWdClusterHandler = cast(
IasWdClusterHandler, cluster_handlers[0]
)
self._attr_is_on: bool = False
self._off_listener: Callable[[], None] | None = None

View file

@ -713,7 +713,9 @@ async def test_zll_device_groups(
"""Test adding coordinator to ZLL groups."""
cluster = zigpy_zll_device.endpoints[1].lightlink
cluster_handler = cluster_handlers.lightlink.LightLink(cluster, endpoint)
cluster_handler = cluster_handlers.lightlink.LightLinkClusterHandler(
cluster, endpoint
)
get_group_identifiers_rsp = zigpy.zcl.clusters.lightlink.LightLink.commands_by_name[
"get_group_identifiers_rsp"
@ -980,3 +982,23 @@ async def test_retry_request(
assert func.await_count == 3
assert isinstance(exc.value, HomeAssistantError)
assert str(exc.value) == expected_error
async def test_cluster_handler_naming() -> None:
"""Test that all cluster handlers are named appropriately."""
for client_cluster_handler in registries.CLIENT_CLUSTER_HANDLER_REGISTRY.values():
assert issubclass(client_cluster_handler, cluster_handlers.ClientClusterHandler)
assert client_cluster_handler.__name__.endswith("ClientClusterHandler")
server_cluster_handlers = []
for cluster_handler_dict in registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.values():
# remove this filter in the update platform PR
server_cluster_handlers += [
cluster_handler
for cluster_handler in cluster_handler_dict.values()
if cluster_handler.__name__ != "OtaClientClusterHandler"
]
for cluster_handler in server_cluster_handlers:
assert not issubclass(cluster_handler, cluster_handlers.ClientClusterHandler)
assert cluster_handler.__name__.endswith("ClusterHandler")