diff --git a/zhaquirks/candeo/__init__.py b/zhaquirks/candeo/__init__.py index c16157d25b..07128f2872 100644 --- a/zhaquirks/candeo/__init__.py +++ b/zhaquirks/candeo/__init__.py @@ -1,17 +1,36 @@ """Module for Candeo quirks implementations.""" import math +from typing import Final from zigpy.quirks import CustomCluster import zigpy.types as t -from zigpy.zcl.clusters.general import Basic +from zigpy.zcl.clusters.general import Basic, LevelControl, OnOff +from zigpy.zcl.clusters.lighting import Color from zigpy.zcl.clusters.measurement import IlluminanceMeasurement from zigpy.zcl.clusters.security import IasZone -from zigpy.zcl.foundation import DataTypeId, ZCLAttributeDef +from zigpy.zcl.foundation import ( + BaseCommandDefs, + DataTypeId, + ZCLAttributeDef, + ZCLCommandDef, +) from zhaquirks.const import ZONE_TYPE CANDEO = "Candeo" +COMMAND_PRESS = "press" +COMMAND_DOUBLE_PRESS = "double_press" +COMMAND_HOLD = "hold" +COMMAND_RELEASE = "release" +COMMAND_STARTED_ROTATING = "started_rotating" +COMMAND_CONTINUED_ROTATING = "continued_rotating" +COMMAND_STOPPED_ROTATING = "stopped_rotating" + +ROTARY_KNOB = "rotary_knob" +STARTED_ROTATING = "rotary_knob_started_rotating" +CONTINUED_ROTATING = "rotary_knob_continued_rotating" +STOPPED_ROTATING = "rotary_knob_stopped_rotating" class CandeoSwitchType(t.enum8): @@ -21,6 +40,13 @@ class CandeoSwitchType(t.enum8): Toggle = 0x01 +class CandeoRemoteDirection(t.enum8): + """Candeo Remote Direction.""" + + Right = 0x00 + Left = 0x01 + + class CandeoIlluminanceMeasurementCluster(IlluminanceMeasurement, CustomCluster): """Candeo Illuminance Measurement Cluster.""" @@ -77,3 +103,74 @@ class CandeoIasZoneWaterCluster(IasZone, CustomCluster): """Candeo IasZone Water Cluster.""" _CONSTANT_ATTRIBUTES = {ZONE_TYPE: IasZone.ZoneType.Water_Sensor} + + +class CandeoRGBColorCluster(Color, CustomCluster): + """Candeo RGB Color Cluster.""" + + _CONSTANT_ATTRIBUTES = { + Color.AttributeDefs.color_capabilities.id: Color.ColorCapabilities.XY_attributes, + Color.AttributeDefs.color_temperature.id: None, + Color.AttributeDefs.start_up_color_temperature.id: None, + } + + +class CandeoCCTColorCluster(Color, CustomCluster): + """Candeo CCT Color Cluster.""" + + _CONSTANT_ATTRIBUTES = { + Color.AttributeDefs.color_capabilities.id: Color.ColorCapabilities.Color_temperature + } + + +class CandeoRGBCCTColorCluster(Color, CustomCluster): + """Candeo RGBCCT Color Cluster.""" + + _CONSTANT_ATTRIBUTES = { + Color.AttributeDefs.color_capabilities.id: Color.ColorCapabilities.XY_attributes + + Color.ColorCapabilities.Color_temperature + } + + +class CandeoOnOffRemoteCluster(OnOff, CustomCluster): + """Candeo OnOff Remote Cluster.""" + + class ServerCommandDefs(BaseCommandDefs): + """overwrite ServerCommandDefs.""" + + double_press: Final = ZCLCommandDef( + id=0x00, + schema={}, + ) + press: Final = ZCLCommandDef( + id=0x01, + schema={}, + ) + hold: Final = ZCLCommandDef( + id=0x02, + schema={}, + ) + release: Final = ZCLCommandDef( + id=0x03, + schema={}, + ) + + +class CandeoLevelControlRemoteCluster(LevelControl, CustomCluster): + """Candeo LevelControl Remote Cluster.""" + + class ServerCommandDefs(BaseCommandDefs): + """overwrite ServerCommandDefs.""" + + started_rotating: Final = ZCLCommandDef( + id=0x05, + schema={"direction": CandeoRemoteDirection}, + ) + continued_rotating: Final = ZCLCommandDef( + id=0x06, + schema={"direction": CandeoRemoteDirection}, + ) + stopped_rotating: Final = ZCLCommandDef( + id=0x03, + schema={}, + ) diff --git a/zhaquirks/candeo/rotary_dimmer_switches.py b/zhaquirks/candeo/rotary_dimmer_switches.py new file mode 100644 index 0000000000..29108586bf --- /dev/null +++ b/zhaquirks/candeo/rotary_dimmer_switches.py @@ -0,0 +1,118 @@ +"""Candeo rotary dimmer switches.""" + +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl import ClusterType +from zigpy.zcl.clusters.general import Identify, Ota + +from zhaquirks.candeo import ( + CANDEO, + COMMAND_CONTINUED_ROTATING, + COMMAND_DOUBLE_PRESS, + COMMAND_HOLD, + COMMAND_PRESS, + COMMAND_RELEASE, + COMMAND_STARTED_ROTATING, + COMMAND_STOPPED_ROTATING, + CONTINUED_ROTATING, + ROTARY_KNOB, + STARTED_ROTATING, + STOPPED_ROTATING, + CandeoLevelControlRemoteCluster, + CandeoOnOffRemoteCluster, +) +from zhaquirks.const import ( + CLUSTER_ID, + COMMAND, + DOUBLE_PRESS, + ENDPOINT_ID, + LEFT, + LONG_PRESS, + LONG_RELEASE, + PARAMS, + RIGHT, + SHORT_PRESS, +) + +remote_quirk = ( + QuirkBuilder() + .replaces(CandeoOnOffRemoteCluster, endpoint_id=2, cluster_type=ClusterType.Client) + .replaces( + CandeoLevelControlRemoteCluster, endpoint_id=2, cluster_type=ClusterType.Client + ) + .device_automation_triggers( + { + (SHORT_PRESS, ROTARY_KNOB): { + COMMAND: COMMAND_PRESS, + CLUSTER_ID: 6, + ENDPOINT_ID: 2, + }, + (DOUBLE_PRESS, ROTARY_KNOB): { + COMMAND: COMMAND_DOUBLE_PRESS, + CLUSTER_ID: 6, + ENDPOINT_ID: 2, + }, + (LONG_PRESS, ROTARY_KNOB): { + COMMAND: COMMAND_HOLD, + CLUSTER_ID: 6, + ENDPOINT_ID: 2, + }, + (LONG_RELEASE, ROTARY_KNOB): { + COMMAND: COMMAND_RELEASE, + CLUSTER_ID: 6, + ENDPOINT_ID: 2, + }, + (STARTED_ROTATING, LEFT): { + COMMAND: COMMAND_STARTED_ROTATING, + CLUSTER_ID: 8, + ENDPOINT_ID: 2, + PARAMS: {"direction": 1}, + }, + (CONTINUED_ROTATING, LEFT): { + COMMAND: COMMAND_CONTINUED_ROTATING, + CLUSTER_ID: 8, + ENDPOINT_ID: 2, + PARAMS: {"direction": 1}, + }, + (STARTED_ROTATING, RIGHT): { + COMMAND: COMMAND_STARTED_ROTATING, + CLUSTER_ID: 8, + ENDPOINT_ID: 2, + PARAMS: {"direction": 0}, + }, + (CONTINUED_ROTATING, RIGHT): { + COMMAND: COMMAND_CONTINUED_ROTATING, + CLUSTER_ID: 8, + ENDPOINT_ID: 2, + PARAMS: {"direction": 0}, + }, + (STOPPED_ROTATING, ROTARY_KNOB): { + COMMAND: COMMAND_STOPPED_ROTATING, + CLUSTER_ID: 8, + ENDPOINT_ID: 2, + }, + } + ) +) + +( + QuirkBuilder(CANDEO, "C-ZB-RD1") + .applies_to(CANDEO, "C-ZB-RD1P-DIM") + .removes(Ota.cluster_id) + .add_to_registry() +) + +( + remote_quirk.clone() + .applies_to(CANDEO, "C-ZB-RD1P-REM") + .removes(Identify.cluster_id, endpoint_id=1) + .removes(Identify.cluster_id, endpoint_id=2) + .removes(Ota.cluster_id) + .add_to_registry() +) + +( + remote_quirk.clone() + .applies_to(CANDEO, "C-ZB-RD1P-DPM") + .removes(Ota.cluster_id) + .add_to_registry() +) diff --git a/zhaquirks/candeo/smart_led_controllers.py b/zhaquirks/candeo/smart_led_controllers.py new file mode 100644 index 0000000000..c8cc696afc --- /dev/null +++ b/zhaquirks/candeo/smart_led_controllers.py @@ -0,0 +1,37 @@ +"""Candeo smart led controllers.""" + +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.lighting import Color + +from zhaquirks.candeo import ( + CANDEO, + CandeoCCTColorCluster, + CandeoRGBCCTColorCluster, + CandeoRGBColorCluster, +) + +( + QuirkBuilder(CANDEO, "C-ZB-LC20-Dim") + .applies_to(CANDEO, "C-ZB-LC20-DIM") + .removes(Color.cluster_id, endpoint_id=11) + .add_to_registry() +) + +( + QuirkBuilder(CANDEO, "C-ZB-LC20-CCT") + .replaces(CandeoCCTColorCluster, endpoint_id=11) + .add_to_registry() +) + +( + QuirkBuilder(CANDEO, "C-ZB-LC20-RGB") + .replaces(CandeoRGBColorCluster, endpoint_id=11) + .add_to_registry() +) + +( + QuirkBuilder(CANDEO, "C-ZB-LC20-RGBCCT") + .applies_to(CANDEO, "C-ZB-LC20-RGBW") + .replaces(CandeoRGBCCTColorCluster, endpoint_id=11) + .add_to_registry() +)