diff --git a/zhaquirks/sinope/sensor.py b/zhaquirks/sinope/sensor.py index b28fccf9f9..7fbdf1dbb7 100644 --- a/zhaquirks/sinope/sensor.py +++ b/zhaquirks/sinope/sensor.py @@ -4,9 +4,12 @@ Supported devices are WL4200, WL4200S and LM4110-ZB """ +from typing import Final + import zigpy.profiles.zha as zha_p from zigpy.quirks import CustomCluster, CustomDevice import zigpy.types as t +from zigpy.zcl import foundation from zigpy.zcl.clusters.general import ( AnalogInput, Basic, @@ -30,39 +33,58 @@ from zhaquirks.sinope import SINOPE, SINOPE_MANUFACTURER_CLUSTER_ID +class LeakStatus(t.enum8): + """Leak_status values.""" + + Dry = 0x00 + Leak = 0x01 + + class SinopeManufacturerCluster(CustomCluster): """SinopeManufacturerCluster manufacturer cluster.""" - cluster_id = SINOPE_MANUFACTURER_CLUSTER_ID - name = "Sinopé Manufacturer specific" - ep_attribute = "sinope_manufacturer_specific" - attributes = { - 0x0003: ("firmware_number", t.uint16_t, True), - 0x0004: ("firmware_version", t.CharacterString, True), - 0x0032: ("min_temperature_limit", t.int16s, True), - 0x0033: ("max_temperature_limit", t.int16s, True), - 0x0034: ("device_status", t.bitmap8, True), - 0x0036: ("battery_type", t.uint16_t, True), - 0x0200: ("status", t.bitmap32, True), - 0xFFFD: ("cluster_revision", t.uint16_t, True), - } + cluster_id: Final[t.uint16_t] = SINOPE_MANUFACTURER_CLUSTER_ID + name: Final = "SinopeManufacturerCluster" + ep_attribute: Final = "sinope_manufacturer_specific" + + class AttributeDefs(foundation.BaseAttributeDefs): + """Sinope Manufacturer Cluster Attributes.""" + + firmware_number: Final = foundation.ZCLAttributeDef( + id=0x0003, type=t.uint16_t, access="r", is_manufacturer_specific=True + ) + firmware_version: Final = foundation.ZCLAttributeDef( + id=0x0004, type=t.CharacterString, access="r", is_manufacturer_specific=True + ) + min_temperature_limit: Final = foundation.ZCLAttributeDef( + id=0x0032, type=t.int16s, access="rw", is_manufacturer_specific=True + ) + max_temperature_limit: Final = foundation.ZCLAttributeDef( + id=0x0033, type=t.int16s, access="rw", is_manufacturer_specific=True + ) + device_status: Final = foundation.ZCLAttributeDef( + id=0x0034, type=t.bitmap8, access="rp", is_manufacturer_specific=True + ) + battery_type: Final = foundation.ZCLAttributeDef( + id=0x0036, type=t.uint16_t, access="rw", is_manufacturer_specific=True + ) + status: Final = foundation.ZCLAttributeDef( + id=0x0200, type=t.bitmap32, access="rp", is_manufacturer_specific=True + ) + cluster_revision: Final = foundation.ZCL_CLUSTER_REVISION_ATTR class SinopeTechnologiesIasZoneCluster(CustomCluster, IasZone): """SinopeTechnologiesIasZoneCluster custom cluster.""" - class LeakStatus(t.enum8): - """Leak_status values.""" + LeakStatus: Final = LeakStatus - Dry = 0x00 - Leak = 0x01 + class AttributeDefs(IasZone.AttributeDefs): + """Sinope Manufacturer IasZone Cluster Attributes.""" - attributes = IasZone.attributes.copy() - attributes.update( - { - 0x0030: ("leak_status", LeakStatus, True), - } - ) + leak_status: Final = foundation.ZCLAttributeDef( + id=0x0030, type=LeakStatus, access="rw", is_manufacturer_specific=True + ) class SinopeTechnologiesSensor(CustomDevice): diff --git a/zhaquirks/sinope/switch.py b/zhaquirks/sinope/switch.py index ee345b8c93..e3eada7b84 100644 --- a/zhaquirks/sinope/switch.py +++ b/zhaquirks/sinope/switch.py @@ -5,9 +5,12 @@ 2nd gen VA4220ZB, VA4221ZB with flow meeter FS4220, FS4221. """ +from typing import Final + import zigpy.profiles.zha as zha_p from zigpy.quirks import CustomCluster, CustomDevice import zigpy.types as t +from zigpy.zcl import foundation from zigpy.zcl.clusters.general import ( Basic, BinaryInput, @@ -47,173 +50,259 @@ ) -class SinopeManufacturerCluster(CustomCluster): - """SinopeManufacturerCluster manufacturer cluster.""" +class KeypadLock(t.enum8): + """Keypad_lockout values.""" - class KeypadLock(t.enum8): - """Keypad_lockout values.""" - - Unlocked = 0x00 - Locked = 0x01 - Partial_lock = 0x02 - - class FlowAlarm(t.enum8): - """Abnormal flow alarm.""" - - Off = 0x00 - On = 0x01 - - class AlarmAction(t.enum8): - """Flow alarm action.""" - - Nothing = 0x00 - Notify = 0x01 - Close = 0x02 - Close_notify = 0x03 - No_flow = 0x04 - - class PowerSource(t.uint32_t): - """Valve power source types.""" - - Battery = 0x00000000 - ACUPS_01 = 0x00000001 - DC_power = 0x0001D4C0 - - class EmergencyPower(t.uint32_t): - """Valve emergency power source types.""" - - Battery = 0x00000000 - ACUPS_01 = 0x00000001 - Battery_ACUPS_01 = 0x0000003C - - class AbnormalAction(t.bitmap16): - """Action in case of abnormal flow detected.""" - - Nothing = 0x0000 - Close_valve = 0x0001 - Close_notify = 0x0003 - - class ColdStatus(t.enum8): - """Cold_load_pickup_status values.""" - - Active = 0x00 - Off = 0x01 - - class FlowDuration(t.uint32_t): - """Abnormal flow duration.""" - - M_15 = 0x00000384 - M_30 = 0x00000708 - M_45 = 0x00000A8C - M_60 = 0x00000E10 - M_75 = 0x00001194 - M_90 = 0x00001518 - H_3 = 0x00002A30 - H_6 = 0x00005460 - H_12 = 0x0000A8C0 - H_24 = 0x00015180 - - class InputDelay(t.uint16_t): - """Delay for on/off input.""" - - Off = 0x0000 - M_1 = 0x003C - M_2 = 0x0078 - M_5 = 0x012C - M_10 = 0x0258 - M_15 = 0x0384 - M_30 = 0x0708 - H_1 = 0x0E10 - H_2 = 0x1C20 - H_3 = 0x2A30 - - cluster_id = SINOPE_MANUFACTURER_CLUSTER_ID - name = "Sinopé Manufacturer specific" - ep_attribute = "sinope_manufacturer_specific" - attributes = { - 0x0002: ("keypad_lockout", KeypadLock, True), - 0x0003: ("firmware_number", t.uint16_t, True), - 0x0004: ("firmware_version", t.CharacterString, True), - 0x0010: ("outdoor_temp", t.int16s, True), - 0x0013: ("unknown_attr_1", t.enum8, True), - 0x0060: ("connected_load", t.uint16_t, True), - 0x0070: ("current_load", t.bitmap8, True), - 0x0076: ("dr_config_water_temp_min", t.uint8_t, True), - 0x0077: ("dr_config_water_temp_time", t.uint8_t, True), - 0x0078: ("dr_wt_time_on", t.uint16_t, True), - 0x007C: ("min_measured_temp", t.int16s, True), - 0x007D: ("max_measured_temp", t.int16s, True), - 0x0090: ("current_summation_delivered", t.uint32_t, True), - 0x00A0: ("timer", t.uint32_t, True), - 0x00A1: ("timer_countdown", t.uint32_t, True), - 0x0200: ("status", t.bitmap32, True), - 0x0230: ("alarm_flow_threshold", FlowAlarm, True), - 0x0231: ("alarm_options", AlarmAction, True), - 0x0240: ("flow_meter_config", Array, True), - 0x0241: ("valve_countdown", t.uint32_t, True), - 0x0250: ("power_source", PowerSource, True), - 0x0251: ("emergency_power_source", EmergencyPower, True), - 0x0252: ("abnormal_flow_duration", FlowDuration, True), - 0x0253: ("abnormal_flow_action", AbnormalAction, True), - 0x0280: ("max_measured_value", t.int16s, True), - 0x0283: ("cold_load_pickup_status", ColdStatus, True), - 0x0284: ("cold_load_pickup_remaining_time", t.uint16_t, True), - 0x02A0: ("input_on_delay", InputDelay, True), - 0x02A1: ("input_off_delay", InputDelay, True), - 0xFFFD: ("cluster_revision", t.uint16_t, True), - } + Unlocked = 0x00 + Locked = 0x01 + Partial_lock = 0x02 -class CustomBasicCluster(CustomCluster, Basic): - """Custom Basic Cluster.""" +class FlowAlarm(t.enum8): + """Abnormal flow alarm.""" - class PowerSource(t.enum8): - """Power source.""" + Off = 0x00 + On = 0x01 - Unknown = 0x0000 - DC_mains = 0x0001 - Battery = 0x0003 - DC_source = 0x0004 - ACUPS_01 = 0x0081 - ACUPS01 = 0x0082 - attributes = Basic.attributes.copy() - attributes.update( - { - 0x0007: ("power_source", PowerSource, True), - } - ) +class AlarmAction(t.enum8): + """Flow alarm action.""" + + Nothing = 0x00 + Notify = 0x01 + Close = 0x02 + Close_notify = 0x03 + No_flow = 0x04 + + +class PowerSource(t.uint32_t): + """Valve power source types.""" + + Battery = 0x00000000 + ACUPS_01 = 0x00000001 + DC_power = 0x0001D4C0 + + +class EmergencyPower(t.uint32_t): + """Valve emergency power source types.""" + + Battery = 0x00000000 + ACUPS_01 = 0x00000001 + Battery_ACUPS_01 = 0x0000003C + + +class AbnormalAction(t.bitmap16): + """Action in case of abnormal flow detected.""" + + Nothing = 0x0000 + Close_valve = 0x0001 + Close_notify = 0x0003 + + +class ColdStatus(t.enum8): + """Cold_load_pickup_status values.""" + Active = 0x00 + Off = 0x01 -class CustomMeteringCluster(CustomCluster, Metering): - """Custom Metering Cluster.""" - class ValveStatus(t.bitmap8): - """Valve_status.""" +class FlowDuration(t.uint32_t): + """Abnormal flow duration.""" - Off = 0x00 - Off_armed = 0x01 - On = 0x02 + M_15 = 0x00000384 + M_30 = 0x00000708 + M_45 = 0x00000A8C + M_60 = 0x00000E10 + M_75 = 0x00001194 + M_90 = 0x00001518 + H_3 = 0x00002A30 + H_6 = 0x00005460 + H_12 = 0x0000A8C0 + H_24 = 0x00015180 - class UnitOfMeasure(t.enum8): - """Unit_of_measure.""" - KWh = 0x00 - Lh = 0x07 +class InputDelay(t.uint16_t): + """Delay for on/off input.""" + + Off = 0x0000 + M_1 = 0x003C + M_2 = 0x0078 + M_5 = 0x012C + M_10 = 0x0258 + M_15 = 0x0384 + M_30 = 0x0708 + H_1 = 0x0E10 + H_2 = 0x1C20 + H_3 = 0x2A30 + + +class EnergySource(t.enum8): + """Power source.""" + + Unknown = 0x0000 + DC_mains = 0x0001 + Battery = 0x0003 + DC_source = 0x0004 + ACUPS_01 = 0x0081 + ACUPS01 = 0x0082 + + +class ValveStatus(t.bitmap8): + """Valve_status.""" + + Off = 0x00 + Off_armed = 0x01 + On = 0x02 + + +class UnitOfMeasure(t.enum8): + """Unit_of_measure.""" + + KWh = 0x00 + Lh = 0x07 + + +class SinopeManufacturerCluster(CustomCluster): + """SinopeManufacturerCluster manufacturer cluster.""" + + KeypadLock: Final = KeypadLock + FlowAlarm: Final = FlowAlarm + AlarmAction: Final = AlarmAction + PowerSource: Final = PowerSource + EmergencyPower: Final = EmergencyPower + AbnormalAction: Final = AbnormalAction + ColdStatus: Final = ColdStatus + FlowDuration: Final = FlowDuration + InputDelay: Final = InputDelay + + cluster_id: Final[t.uint16_t] = SINOPE_MANUFACTURER_CLUSTER_ID + name: Final = "SinopeManufacturerCluster" + ep_attribute: Final = "sinope_manufacturer_specific" + + class AttributeDefs(foundation.BaseAttributeDefs): + """Sinope Manufacturer Cluster Attributes.""" + + keypad_lockout: Final = foundation.ZCLAttributeDef( + id=0x0002, type=KeypadLock, access="rw", is_manufacturer_specific=True + ) + firmware_number: Final = foundation.ZCLAttributeDef( + id=0x0003, type=t.uint16_t, access="r", is_manufacturer_specific=True + ) + outdoor_temp: Final = foundation.ZCLAttributeDef( + id=0x0010, type=t.int16s, access="rp", is_manufacturer_specific=True + ) + unknown_attr_1: Final = foundation.ZCLAttributeDef( + id=0x0013, type=t.enum8, access="rw", is_manufacturer_specific=True + ) + connected_load: Final = foundation.ZCLAttributeDef( + id=0x0060, type=t.uint16_t, access="r", is_manufacturer_specific=True + ) + current_load: Final = foundation.ZCLAttributeDef( + id=0x0070, type=t.bitmap8, access="r", is_manufacturer_specific=True + ) + dr_config_water_temp_min: Final = foundation.ZCLAttributeDef( + id=0x0076, type=t.uint8_t, access="rwp", is_manufacturer_specific=True + ) + dr_config_water_temp_time: Final = foundation.ZCLAttributeDef( + id=0x0077, type=t.uint8_t, access="rwp", is_manufacturer_specific=True + ) + dr_wt_time_on: Final = foundation.ZCLAttributeDef( + id=0x0078, type=t.uint16_t, access="rwp", is_manufacturer_specific=True + ) + min_measured_temp: Final = foundation.ZCLAttributeDef( + id=0x007C, type=t.int16s, access="rp", is_manufacturer_specific=True + ) + max_measured_temp: Final = foundation.ZCLAttributeDef( + id=0x007D, type=t.int16s, access="rp", is_manufacturer_specific=True + ) + current_summation_delivered: Final = foundation.ZCLAttributeDef( + id=0x0090, type=t.uint32_t, access="rp", is_manufacturer_specific=True + ) + timer: Final = foundation.ZCLAttributeDef( + id=0x00A0, type=t.uint32_t, access="rwp", is_manufacturer_specific=True + ) + timer_countdown: Final = foundation.ZCLAttributeDef( + id=0x00A1, type=t.uint32_t, access="rp", is_manufacturer_specific=True + ) + status: Final = foundation.ZCLAttributeDef( + id=0x0200, type=t.bitmap32, access="rp", is_manufacturer_specific=True + ) + alarm_flow_threshold: Final = foundation.ZCLAttributeDef( + id=0x0230, type=FlowAlarm, access="rw", is_manufacturer_specific=True + ) + alarm_options: Final = foundation.ZCLAttributeDef( + id=0x0231, type=Array, access="r", is_manufacturer_specific=True + ) + flow_meter_config: Final = foundation.ZCLAttributeDef( + id=0x0240, type=AlarmAction, access="rw", is_manufacturer_specific=True + ) + valve_countdown: Final = foundation.ZCLAttributeDef( + id=0x0241, type=t.uint32_t, access="rw", is_manufacturer_specific=True + ) + power_source: Final = foundation.ZCLAttributeDef( + id=0x0250, type=PowerSource, access="rw", is_manufacturer_specific=True + ) + emergency_power_source: Final = foundation.ZCLAttributeDef( + id=0x0251, type=EmergencyPower, access="rw", is_manufacturer_specific=True + ) + abnormal_flow_duration: Final = foundation.ZCLAttributeDef( + id=0x0252, type=FlowDuration, access="rw", is_manufacturer_specific=True + ) + abnormal_flow_action: Final = foundation.ZCLAttributeDef( + id=0x0253, type=AbnormalAction, access="rw", is_manufacturer_specific=True + ) + max_measured_value: Final = foundation.ZCLAttributeDef( + id=0x0280, type=t.int16s, access="rwp", is_manufacturer_specific=True + ) + cold_load_pickup_status: Final = foundation.ZCLAttributeDef( + id=0x0283, type=ColdStatus, access="r", is_manufacturer_specific=True + ) + cold_load_pickup_remaining_time: Final = foundation.ZCLAttributeDef( + id=0x0284, type=t.uint16_t, access="r", is_manufacturer_specific=True + ) + input_on_delay: Final = foundation.ZCLAttributeDef( + id=0x02A0, type=InputDelay, access="rw", is_manufacturer_specific=True + ) + input_off_delay: Final = foundation.ZCLAttributeDef( + id=0x02A1, type=InputDelay, access="rw", is_manufacturer_specific=True + ) + cluster_revision: Final = foundation.ZCL_CLUSTER_REVISION_ATTR + + +class SinopeTechnologiesBasicCluster(CustomCluster, Basic): + """SinopetechnologiesBasicCluster custom cluster .""" + + EnergySource: Final = EnergySource + + class AttributeDefs(Basic.AttributeDefs): + """Sinope Manufacturer Basic Cluster Attributes.""" + + power_source: Final = foundation.ZCLAttributeDef( + id=0x0007, type=EnergySource, access="r", is_manufacturer_specific=True + ) + + +class SinopeTechnologiesMeteringCluster(CustomCluster, Metering): + """SinopeTechnologiesMeteringCluster custom cluster.""" + + ValveStatus: Final = ValveStatus + UnitOfMeasure: Final = UnitOfMeasure DIVISOR = 0x0302 _CONSTANT_ATTRIBUTES = {DIVISOR: 1000} - attributes = Metering.attributes.copy() - attributes.update( - { - 0x0200: ("status", ValveStatus, True), - 0x0300: ("unit_of_measure", UnitOfMeasure, True), - } - ) + class AttributeDefs(Metering.AttributeDefs): + """Sinope Manufacturer Metering Cluster Attributes.""" + + status: Final = foundation.ZCLAttributeDef( + id=0x0200, type=ValveStatus, access="r", is_manufacturer_specific=True + ) + unit_of_measure: Final = foundation.ZCLAttributeDef( + id=0x0300, type=UnitOfMeasure, access="r", is_manufacturer_specific=True + ) -class CustomFlowMeasurementCluster(CustomCluster, FlowMeasurement): +class SinopeTechnologiesFlowMeasurementCluster(CustomCluster, FlowMeasurement): """Custom flow measurement cluster that divides value by 10.""" def _update_attribute(self, attrid, value): @@ -258,7 +347,7 @@ class SinopeTechnologiesSwitch(CustomDevice): Basic.cluster_id, Identify.cluster_id, OnOff.cluster_id, - CustomMeteringCluster, + SinopeTechnologiesMeteringCluster, ElectricalMeasurement.cluster_id, SinopeManufacturerCluster, ], @@ -431,7 +520,7 @@ class SinopeTechnologiesValve(CustomDevice): ENDPOINTS: { 1: { INPUT_CLUSTERS: [ - CustomBasicCluster, + SinopeTechnologiesBasicCluster, PowerConfiguration.cluster_id, Identify.cluster_id, Groups.cluster_id, @@ -493,7 +582,7 @@ class SinopeTechnologiesValveG2(CustomDevice): ENDPOINTS: { 1: { INPUT_CLUSTERS: [ - CustomBasicCluster, + SinopeTechnologiesBasicCluster, PowerConfiguration.cluster_id, Identify.cluster_id, Groups.cluster_id, @@ -501,9 +590,9 @@ class SinopeTechnologiesValveG2(CustomDevice): OnOff.cluster_id, LevelControl.cluster_id, TemperatureMeasurement.cluster_id, - CustomFlowMeasurementCluster, + SinopeTechnologiesFlowMeasurementCluster, IasZone.cluster_id, - CustomMeteringCluster, + SinopeTechnologiesMeteringCluster, Diagnostic.cluster_id, SinopeManufacturerCluster, ], @@ -707,7 +796,7 @@ class SinopeTechnologiesSwitch_V2(CustomDevice): Basic.cluster_id, Identify.cluster_id, OnOff.cluster_id, - CustomMeteringCluster, + SinopeTechnologiesMeteringCluster, ElectricalMeasurement.cluster_id, LightLink.cluster_id, SinopeManufacturerCluster, diff --git a/zhaquirks/sinope/thermostat.py b/zhaquirks/sinope/thermostat.py index eda3e3874a..401015f194 100644 --- a/zhaquirks/sinope/thermostat.py +++ b/zhaquirks/sinope/thermostat.py @@ -4,9 +4,12 @@ of outdoor temperature, setting occupancy on/off and setting device time. """ +from typing import Final + import zigpy.profiles.zha as zha_p from zigpy.quirks import CustomCluster, CustomDevice import zigpy.types as t +from zigpy.zcl import foundation from zigpy.zcl.clusters.general import ( Basic, Groups, @@ -33,170 +36,284 @@ from zhaquirks.sinope import SINOPE, SINOPE_MANUFACTURER_CLUSTER_ID +class KeypadLock(t.enum8): + """Keypad_lockout values.""" + + Unlocked = 0x00 + Locked = 0x01 + Partial_lock = 0x02 + + +class Display(t.enum8): + """Config_2nd_display values.""" + + Auto = 0x00 + Setpoint = 0x01 + Outside_temperature = 0x02 + + +class FloorMode(t.enum8): + """Air_floor_mode values.""" + + Air_by_floor = 0x01 + Floor = 0x02 + + +class AuxMode(t.enum8): + """Aux_output_mode values.""" + + Off = 0x00 + On = 0x01 + + +class PumpStatus(t.uint8_t): + """Pump protection status.""" + + Off = 0x00 + On = 0x01 + + +class LimitStatus(t.uint8_t): + """Floor limit status values.""" + + Ok = 0x00 + Low_reached = 0x01 + Max_reached = 0x02 + Max_air_reached = 0x03 + + +class SensorType(t.enum8): + """Temp_sensor_type values.""" + + Sensor_10k = 0x00 + Sensor_12k = 0x01 + + +class TimeFormat(t.enum8): + """Time_format values.""" + + Format_24h = 0x00 + Format_12h = 0x01 + + +class GfciStatus(t.enum8): + """Gfci_status values.""" + + Ok = 0x00 + Error = 0x01 + + +class SystemMode(t.enum8): + """System mode values.""" + + Off = 0x00 + Auto = 0x01 + Cool = 0x03 + Heat = 0x04 + + +class PumpDuration(t.enum8): + """Pump protection duration period values.""" + + T5 = 0x05 + T10 = 0x0A + T15 = 0x0F + T20 = 0x14 + T30 = 0x1E + T60 = 0x3C + + +class CycleLength(t.uint16_t): + """Cycle length, 15 sec (15) or 15 min (900 sec).""" + + Sec_15 = 0x000F + Min_15 = 0x0384 + + +class Occupancy(t.enum8): + """Set_occupancy values.""" + + Away = 0x00 + Home = 0x01 + + +class Backlight(t.enum8): + """Backlight_auto_dim_param values.""" + + On_demand = 0x00 + Always_on = 0x01 + Bedroom = 0x02 + + +class CycleOutput(t.uint16_t): + """Main and aux cycle period values.""" + + Sec_15 = 0x000F + Min_5 = 0x012C + Min_10 = 0x0258 + Min_15 = 0x0384 + Min_20 = 0x04B0 + Min_25 = 0x05DC + Min_30 = 0x0708 + Off = 0xFFFF + + class SinopeTechnologiesManufacturerCluster(CustomCluster): """SinopeTechnologiesManufacturerCluster manufacturer cluster.""" - class KeypadLock(t.enum8): - """Keypad_lockout values.""" - - Unlocked = 0x00 - Locked = 0x01 - Partial_lock = 0x02 - - class Display(t.enum8): - """Config_2nd_display values.""" - - Auto = 0x00 - Setpoint = 0x01 - Outside_temperature = 0x02 - - class FloorMode(t.enum8): - """Air_floor_mode values.""" - - Air_by_floor = 0x01 - Floor = 0x02 - - class AuxMode(t.enum8): - """Aux_output_mode values.""" - - Off = 0x00 - On = 0x01 - - class PumpStatus(t.uint8_t): - """Pump protection status.""" - - Off = 0x00 - On = 0x01 - - class LimitStatus(t.uint8_t): - """Floor limit status values.""" - - Ok = 0x00 - Low_reached = 0x01 - Max_reached = 0x02 - Max_air_reached = 0x03 - - class SensorType(t.enum8): - """Temp_sensor_type values.""" - - Sensor_10k = 0x00 - Sensor_12k = 0x01 - - class TimeFormat(t.enum8): - """Time_format values.""" - - Format_24h = 0x00 - Format_12h = 0x01 - - class GfciStatus(t.enum8): - """Gfci_status values.""" - - Ok = 0x00 - Error = 0x01 - - class SystemMode(t.enum8): - """System mode values.""" - - Off = 0x00 - Auto = 0x01 - Cool = 0x03 - Heat = 0x04 - - class PumpDuration(t.enum8): - """Pump protection duration period values.""" - - T5 = 0x05 - T10 = 0x0A - T15 = 0x0F - T20 = 0x14 - T30 = 0x1E - T60 = 0x3C - - class CycleLength(t.uint16_t): - """Cycle length, 15 sec (15) or 15 min (900 sec).""" - - Sec_15 = 0x000F - Min_15 = 0x0384 - - cluster_id = SINOPE_MANUFACTURER_CLUSTER_ID - name = "Sinopé Technologies Manufacturer specific" - ep_attribute = "sinope_manufacturer_specific" - attributes = { - 0x0002: ("keypad_lockout", KeypadLock, True), - 0x0003: ("firmware_number", t.uint16_t, True), - 0x0004: ("firmware_version", t.CharacterString, True), - 0x0010: ("outdoor_temp", t.int16s, True), - 0x0011: ("outdoor_temp_timeout", t.uint16_t, True), - 0x0012: ("config_2nd_display", Display, True), - 0x0020: ("secs_since_2k", t.uint32_t, True), - 0x0070: ("current_load", t.bitmap8, True), - 0x0071: ("eco_delta_setpoint", t.int8s, True), - 0x0072: ("eco_max_pi_heating_demand", t.uint8_t, True), - 0x0073: ("eco_safety_temperature_delta", t.uint8_t, True), - 0x0101: ("unknown_attr_1", Array, True), - 0x0104: ("setpoint", t.int16s, True), - 0x0105: ("air_floor_mode", FloorMode, True), - 0x0106: ("aux_output_mode", AuxMode, True), - 0x0107: ("floor_temperature", t.int16s, True), - 0x0108: ("air_max_limit", t.int16s, True), - 0x0109: ("floor_min_setpoint", t.int16s, True), - 0x010A: ("floor_max_setpoint", t.int16s, True), - 0x010B: ("floor_sensor_type_param", SensorType, True), - 0x010C: ("floor_limit_status", LimitStatus, True), - 0x010D: ("room_temperature", t.int16s, True), - 0x0114: ("time_format", TimeFormat, True), - 0x0115: ("gfci_status", GfciStatus, True), - 0x0116: ("hvac_mode", SystemMode, True), - 0x0118: ("aux_connected_load", t.uint16_t, True), - 0x0119: ("connected_load", t.uint16_t, True), - 0x0128: ("pump_protection_status", PumpStatus, True), - 0x012A: ("pump_protection_duration", PumpDuration, True), - 0x012B: ("current_setpoint", t.int16s, True), - 0x012D: ("report_local_temperature", t.int16s, True), - 0x0200: ("status", t.bitmap32, True), - 0x0281: ("cycle_length", CycleLength, True), - 0xFFFD: ("cluster_revision", t.uint16_t, True), - } + KeypadLock: Final = KeypadLock + Display: Final = Display + FloorMode: Final = FloorMode + AuxMode: Final = AuxMode + PumpStatus: Final = PumpStatus + LimitStatus: Final = LimitStatus + SensorType: Final = SensorType + TimeFormat: Final = TimeFormat + GfciStatus: Final = GfciStatus + SystemMode: Final = SystemMode + PumpDuration: Final = PumpDuration + CycleLength: Final = CycleLength + + cluster_id: Final[t.uint16_t] = SINOPE_MANUFACTURER_CLUSTER_ID + name: Final = "SinopeTechnologiesManufacturerCluster" + ep_attribute: Final = "sinope_manufacturer_specific" + + class AttributeDefs(foundation.BaseAttributeDefs): + """Sinope Manufacturer Cluster Attributes.""" + + keypad_lockout: Final = foundation.ZCLAttributeDef( + id=0x0002, type=KeypadLock, access="rwp", is_manufacturer_specific=True + ) + firmware_number: Final = foundation.ZCLAttributeDef( + id=0x0003, type=t.uint16_t, access="rp", is_manufacturer_specific=True + ) + firmware_version: Final = foundation.ZCLAttributeDef( + id=0x0004, + type=t.CharacterString, + access="rp", + is_manufacturer_specific=True, + ) + outdoor_temp: Final = foundation.ZCLAttributeDef( + id=0x0010, type=t.int16s, access="rwp", is_manufacturer_specific=True + ) + outdoor_temp_timeout: Final = foundation.ZCLAttributeDef( + id=0x0011, type=t.uint16_t, access="rwp", is_manufacturer_specific=True + ) + config_2nd_display: Final = foundation.ZCLAttributeDef( + id=0x0012, type=Display, access="rwp", is_manufacturer_specific=True + ) + secs_since_2k: Final = foundation.ZCLAttributeDef( + id=0x0020, type=t.uint32_t, access="rwp", is_manufacturer_specific=True + ) + current_load: Final = foundation.ZCLAttributeDef( + id=0x0070, type=t.bitmap8, access="rp", is_manufacturer_specific=True + ) + eco_delta_setpoint: Final = foundation.ZCLAttributeDef( + id=0x0071, type=t.int8s, access="rwp", is_manufacturer_specific=True + ) + eco_max_pi_heating_demand: Final = foundation.ZCLAttributeDef( + id=0x0072, type=t.uint8_t, access="rwp", is_manufacturer_specific=True + ) + eco_safety_temperature_delta: Final = foundation.ZCLAttributeDef( + id=0x0073, type=t.uint8_t, access="rwp", is_manufacturer_specific=True + ) + unknown_attr_1: Final = foundation.ZCLAttributeDef( + id=0x0101, type=Array, access="r", is_manufacturer_specific=True + ) + setpoint: Final = foundation.ZCLAttributeDef( + id=0x0104, type=t.int16s, access="rw", is_manufacturer_specific=True + ) + air_floor_mode: Final = foundation.ZCLAttributeDef( + id=0x0105, type=FloorMode, access="rw", is_manufacturer_specific=True + ) + aux_output_mode: Final = foundation.ZCLAttributeDef( + id=0x0106, type=AuxMode, access="rw", is_manufacturer_specific=True + ) + floor_temperature: Final = foundation.ZCLAttributeDef( + id=0x0107, type=t.int16s, access="r", is_manufacturer_specific=True + ) + air_max_limit: Final = foundation.ZCLAttributeDef( + id=0x0108, type=t.int16s, access="rw", is_manufacturer_specific=True + ) + floor_min_setpoint: Final = foundation.ZCLAttributeDef( + id=0x0109, type=t.int16s, access="rw", is_manufacturer_specific=True + ) + floor_max_setpoint: Final = foundation.ZCLAttributeDef( + id=0x010A, type=t.int16s, access="rw", is_manufacturer_specific=True + ) + floor_sensor_type_param: Final = foundation.ZCLAttributeDef( + id=0x010B, type=SensorType, access="rw", is_manufacturer_specific=True + ) + floor_limit_status: Final = foundation.ZCLAttributeDef( + id=0x010C, type=LimitStatus, access="rp", is_manufacturer_specific=True + ) + room_temperature: Final = foundation.ZCLAttributeDef( + id=0x010D, type=t.int16s, access="r", is_manufacturer_specific=True + ) + time_format: Final = foundation.ZCLAttributeDef( + id=0x0114, type=TimeFormat, access="rwp", is_manufacturer_specific=True + ) + gfci_status: Final = foundation.ZCLAttributeDef( + id=0x0115, type=GfciStatus, access="rp", is_manufacturer_specific=True + ) + hvac_mode: Final = foundation.ZCLAttributeDef( + id=0x0116, type=SystemMode, access="r", is_manufacturer_specific=True + ) + aux_connected_load: Final = foundation.ZCLAttributeDef( + id=0x0118, type=t.uint16_t, access="rw", is_manufacturer_specific=True + ) + connected_load: Final = foundation.ZCLAttributeDef( + id=0x0119, type=t.uint16_t, access="rw", is_manufacturer_specific=True + ) + pump_protection_status: Final = foundation.ZCLAttributeDef( + id=0x0128, type=PumpStatus, access="rw", is_manufacturer_specific=True + ) + pump_protection_duration: Final = foundation.ZCLAttributeDef( + id=0x012A, type=PumpDuration, access="rwp", is_manufacturer_specific=True + ) + current_setpoint: Final = foundation.ZCLAttributeDef( + id=0x012B, type=t.int16s, access="rwp", is_manufacturer_specific=True + ) + report_local_temperature: Final = foundation.ZCLAttributeDef( + id=0x012D, type=t.int16s, access="rp", is_manufacturer_specific=True + ) + unknown_attr_11: Final = foundation.ZCLAttributeDef( + id=0x013B, type=t.bitmap8, access="rp", is_manufacturer_specific=True + ) + status: Final = foundation.ZCLAttributeDef( + id=0x0200, type=t.bitmap32, access="rp", is_manufacturer_specific=True + ) + unknown_attr_12: Final = foundation.ZCLAttributeDef( + id=0x0202, type=t.enum8, access="r", is_manufacturer_specific=True + ) + cycle_length: Final = foundation.ZCLAttributeDef( + id=0x0281, type=CycleLength, access="rwp", is_manufacturer_specific=True + ) + cluster_revision: Final = foundation.ZCL_CLUSTER_REVISION_ATTR class SinopeTechnologiesThermostatCluster(CustomCluster, Thermostat): """SinopeTechnologiesThermostatCluster custom cluster.""" - class Occupancy(t.enum8): - """Set_occupancy values.""" - - Away = 0x00 - Home = 0x01 - - class Backlight(t.enum8): - """Backlight_auto_dim_param values.""" - - On_demand = 0x00 - Always_on = 0x01 - Bedroom = 0x02 - - class CycleOutput(t.uint16_t): - """Main and aux cycle period values.""" - - Sec_15 = 0x000F - Min_5 = 0x012C - Min_10 = 0x0258 - Min_15 = 0x0384 - Min_20 = 0x04B0 - Min_25 = 0x05DC - Min_30 = 0x0708 - Off = 0xFFFF - - attributes = Thermostat.attributes.copy() - attributes.update( - { - 0x0400: ("set_occupancy", Occupancy, True), - 0x0401: ("main_cycle_output", CycleOutput, True), - 0x0402: ("backlight_auto_dim_param", Backlight, True), - 0x0404: ("aux_cycle_output", CycleOutput, True), - 0xFFFD: ("cluster_revision", t.uint16_t, True), - } - ) + Occupancy: Final = Occupancy + Backlight: Final = Backlight + CycleOutput: Final = CycleOutput + + class AttributeDefs(Thermostat.AttributeDefs): + """Sinope Manufacturer Thermostat Cluster Attributes.""" + + set_occupancy: Final = foundation.ZCLAttributeDef( + id=0x0400, type=Occupancy, access="rw", is_manufacturer_specific=True + ) + main_cycle_output: Final = foundation.ZCLAttributeDef( + id=0x0401, type=CycleOutput, access="rw", is_manufacturer_specific=True + ) + backlight_auto_dim_param: Final = foundation.ZCLAttributeDef( + id=0x0402, type=Backlight, access="rw", is_manufacturer_specific=True + ) + aux_cycle_output: Final = foundation.ZCLAttributeDef( + id=0x0404, type=CycleOutput, access="rw", is_manufacturer_specific=True + ) class SinopeTechnologiesElectricalMeasurementCluster( @@ -204,14 +321,18 @@ class SinopeTechnologiesElectricalMeasurementCluster( ): """SinopeTechnologiesElectricalMeasurementCluster custom cluster.""" - attributes = ElectricalMeasurement.attributes.copy() - attributes.update( - { - 0x0551: ("current_summation_delivered", t.uint32_t, True), - 0x0552: ("aux_setpoint_min", t.uint32_t, True), - 0x0553: ("aux_setpoint_max", t.uint32_t, True), - } - ) + class AttributeDefs(ElectricalMeasurement.AttributeDefs): + """Sinope Manufacturer ElectricalMeasurement Cluster Attributes.""" + + current_summation_delivered: Final = foundation.ZCLAttributeDef( + id=0x0551, type=t.uint32_t, access="rwp", is_manufacturer_specific=True + ) + aux_setpoint_min: Final = foundation.ZCLAttributeDef( + id=0x0552, type=t.uint32_t, access="rw", is_manufacturer_specific=True + ) + aux_setpoint_max: Final = foundation.ZCLAttributeDef( + id=0x0553, type=t.uint32_t, access="rw", is_manufacturer_specific=True + ) class SinopeTechnologiesThermostat(CustomDevice):