Skip to content
Open
101 changes: 99 additions & 2 deletions zhaquirks/candeo/__init__.py
Original file line number Diff line number Diff line change
@@ -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"
Comment on lines +22 to +33
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just move all of them into the zhaquirks const.py file? We're gonna add translations for this in ZHA either way, so that way, other quirks can also use them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I don't see why not, as long as they don't conflict with or overwrite anything that's already defined?



class CandeoSwitchType(t.enum8):
Expand All @@ -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."""

Expand Down Expand Up @@ -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={},
)
118 changes: 118 additions & 0 deletions zhaquirks/candeo/rotary_dimmer_switches.py
Original file line number Diff line number Diff line change
@@ -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()
)
37 changes: 37 additions & 0 deletions zhaquirks/candeo/smart_led_controllers.py
Original file line number Diff line number Diff line change
@@ -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()
)
Loading