zigpy / zha-device-handlers

ZHA device handlers bridge the functionality gap created when manufacturers deviate from the ZCL specification, handling deviations and exceptions by parsing custom messages to and from Zigbee devices.
Apache License 2.0
721 stars 670 forks source link

[Device Support Request] _TZE200_abatw3kj 3 Phase Circuit Breaker #2559

Closed yannik1015 closed 6 months ago

yannik1015 commented 1 year ago

Problem description

I am currently working on implementing a quirk for this 3 phase circuit breaker. ZMB9-125 ARD W 3P 63~100A (https://www.cnzmele.com/smart-circuit-breaker/zigbee-smart-circuit-breaker.html)

I adapted the quirk for https://github.com/zigpy/zha-device-handlers/blob/master/zhaquirks/tuya/ts0601_rcbo.py (Just the signatures) but all entities are just shown as unknown.

I am new to developing quirks so any help going forward from here is greatly appreciated as I would have expected for at least the sensors to be copy paste from the similar device.

Solution description

Implementing a quirk for the device or helping me to move forward with my implementation.

Screenshots/Video

Screenshots/Video ![Screenshot_20230831_192547](https://github.com/zigpy/zha-device-handlers/assets/34042618/01f1139e-f42d-4a9e-ad95-6eb3642cc130)

Device signature

Device signature ```yaml model: TS0601 manufacturer: _TZE200_abatw3kj manufacturer_id: "0x4417" endpoints: - id: 1 device_type: "0x0051" profile: "0x0104" in_clusters: "0x0000": cluster_id: "0x0000" title: Basic name: basic attributes: "0x0000": attribute_id: "0x0000" attribute_name: zcl_version value_type: - "0x20" - uint8_t - Analog access: "5" access_acl: 5 attribute_value: 3 "0x0001": attribute_id: "0x0001" attribute_name: app_version value_type: - "0x20" - uint8_t - Analog access: "5" access_acl: 5 attribute_value: 70 "0x0002": attribute_id: "0x0002" attribute_name: stack_version value_type: - "0x20" - uint8_t - Analog access: "5" access_acl: 5 attribute_value: 0 "0x0003": attribute_id: "0x0003" attribute_name: hw_version value_type: - "0x20" - uint8_t - Analog access: "5" access_acl: 5 attribute_value: 1 "0x0004": attribute_id: "0x0004" attribute_name: manufacturer value_type: - "0x42" - CharacterString - Discrete access: "5" access_acl: 5 attribute_value: _TZE200_abatw3kj "0x0005": attribute_id: "0x0005" attribute_name: model value_type: - "0x42" - CharacterString - Discrete access: "5" access_acl: 5 attribute_value: TS0601 "0x0006": attribute_id: "0x0006" attribute_name: date_code value_type: - "0x42" - CharacterString - Discrete access: "5" access_acl: 5 attribute_value: "" "0x0007": attribute_id: "0x0007" attribute_name: power_source value_type: - "0x30" - enum8 - Discrete access: "5" access_acl: 5 attribute_value: 1 "0xffde": attribute_id: "0xffde" attribute_name: "65502" value_type: - "0x20" - uint8_t - Analog access: "7" access_acl: 7 attribute_value: 13 "0xffe2": attribute_id: "0xffe2" attribute_name: "65506" value_type: - "0x20" - uint8_t - Analog access: "5" access_acl: 5 attribute_value: 54 "0xffe3": attribute_id: "0xffe3" attribute_name: "65507" value_type: - "0x48" - Array - Discrete access: "5" access_acl: 5 "0xfffd": attribute_id: "0xfffd" attribute_name: cluster_revision value_type: - "0x21" - uint16_t - Analog access: "5" access_acl: 5 attribute_value: 2 "0xfffe": attribute_id: "0xfffe" attribute_name: reporting_status value_type: - "0x30" - enum8 - Discrete access: "5" access_acl: 5 attribute_value: 0 commands_received: {} commands_generated: {} "0x0004": cluster_id: "0x0004" title: Groups name: groups attributes: "0x0000": attribute_id: "0x0000" attribute_name: name_support value_type: - "0x18" - bitmap8 - Discrete access: "5" access_acl: 5 attribute_value: 0 "0xfffd": attribute_id: "0xfffd" attribute_name: cluster_revision value_type: - "0x21" - uint16_t - Analog access: "5" access_acl: 5 attribute_value: 2 commands_received: {} commands_generated: {} "0x0005": cluster_id: "0x0005" title: Scenes name: scenes attributes: "0x0000": attribute_id: "0x0000" attribute_name: count value_type: - "0x20" - uint8_t - Analog access: "5" access_acl: 5 attribute_value: 0 "0x0001": attribute_id: "0x0001" attribute_name: current_scene value_type: - "0x20" - uint8_t - Analog access: "5" access_acl: 5 attribute_value: 0 "0x0002": attribute_id: "0x0002" attribute_name: current_group value_type: - "0x21" - uint16_t - Analog access: "5" access_acl: 5 attribute_value: 0 "0x0003": attribute_id: "0x0003" attribute_name: scene_valid value_type: - "0x10" - Bool - Discrete access: "5" access_acl: 5 attribute_value: 0 "0x0004": attribute_id: "0x0004" attribute_name: name_support value_type: - "0x18" - bitmap8 - Discrete access: "5" access_acl: 5 attribute_value: 0 "0xfffd": attribute_id: "0xfffd" attribute_name: cluster_revision value_type: - "0x21" - uint16_t - Analog access: "5" access_acl: 5 attribute_value: 2 commands_received: {} commands_generated: {} "0xef00": cluster_id: "0xef00" title: Cluster name: null attributes: "0x0000": attribute_id: "0x0000" attribute_name: "0" value_type: - "0x20" - uint8_t - Analog access: "5" access_acl: 5 attribute_value: 0 commands_received: {} commands_generated: {} out_clusters: "0x000a": cluster_id: "0x000a" title: Time name: time attributes: "0xfffd": attribute_id: "0xfffd" attribute_name: cluster_revision value_type: - "0x21" - uint16_t - Analog access: "1" access_acl: 1 attribute_value: 1 commands_received: {} commands_generated: {} "0x0019": cluster_id: "0x0019" title: Ota name: ota attributes: "0x0000": attribute_id: "0x0000" attribute_name: upgrade_server_id value_type: - "0xf0" - EUI64 - Discrete access: "1" access_acl: 1 attribute_value: - 255 - 255 - 255 - 255 - 255 - 255 - 255 - 255 "0x0001": attribute_id: "0x0001" attribute_name: file_offset value_type: - "0x23" - uint32_t - Analog access: "1" access_acl: 1 attribute_value: 4294967295 "0x0002": attribute_id: "0x0002" attribute_name: current_file_version value_type: - "0x23" - uint32_t - Analog access: "1" access_acl: 1 attribute_value: 70 "0x0003": attribute_id: "0x0003" attribute_name: current_zigbee_stack_version value_type: - "0x21" - uint16_t - Analog access: "1" access_acl: 1 attribute_value: 2 "0x0004": attribute_id: "0x0004" attribute_name: downloaded_file_version value_type: - "0x23" - uint32_t - Analog access: "1" access_acl: 1 attribute_value: 4294967295 "0x0005": attribute_id: "0x0005" attribute_name: downloaded_zigbee_stack_version value_type: - "0x21" - uint16_t - Analog access: "1" access_acl: 1 attribute_value: 65535 "0x0006": attribute_id: "0x0006" attribute_name: image_upgrade_status value_type: - "0x30" - enum8 - Discrete access: "1" access_acl: 1 attribute_value: 0 "0x0007": attribute_id: "0x0007" attribute_name: manufacturer_id value_type: - "0x21" - uint16_t - Analog access: "1" access_acl: 1 attribute_value: 4417 "0x0008": attribute_id: "0x0008" attribute_name: image_type_id value_type: - "0x21" - uint16_t - Analog access: "1" access_acl: 1 attribute_value: 65535 "0x0009": attribute_id: "0x0009" attribute_name: minimum_block_req_delay value_type: - "0x21" - uint16_t - Analog access: "1" access_acl: 1 attribute_value: 0 "0xfffd": attribute_id: "0xfffd" attribute_name: cluster_revision value_type: - "0x21" - uint16_t - Analog access: "1" access_acl: 1 attribute_value: 3 commands_received: {} commands_generated: {} - id: 242 device_type: "0x0061" profile: "0xa1e0" ```

Custom quirk

Custom quirk ```python """Tuya Din RCBO Circuit Breaker.""" from typing import Any, Dict, Optional, Union from zigpy.profiles import zgp, zha from zigpy.quirks import CustomCluster, CustomDevice import zigpy.types as t from zigpy.zcl import foundation from zigpy.zcl.clusters.general import ( Basic, GreenPowerProxy, DeviceTemperature, Groups, Ota, Scenes, Time, ) from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement from zigpy.zcl.clusters.smartenergy import Metering from zhaquirks.const import ( DEVICE_TYPE, ENDPOINTS, INPUT_CLUSTERS, MODELS_INFO, OUTPUT_CLUSTERS, PROFILE_ID, ) from zhaquirks.tuya import TUYA_MCU_COMMAND, AttributeWithMask, PowerOnState from zhaquirks.tuya.mcu import ( DPToAttributeMapping, TuyaAttributesCluster, TuyaClusterData, TuyaMCUCluster, TuyaOnOff, ) TUYA_DP_STATE = 1 TUYA_DP_COUNTDOWN_TIMER = 9 TUYA_DP_FAULT_CODE = 26 TUYA_DP_RELAY_STATUS = 27 # power recovery behaviour TUYA_DP_CHILD_LOCK = 29 TUYA_DP_VOLTAGE = 101 TUYA_DP_CURRENT = 102 TUYA_DP_ACTIVE_POWER = 103 TUYA_DP_LEAKAGE_CURRENT = 104 TUYA_DP_TEMPERATURE = 105 TUYA_DP_REMAINING_ENERGY = 106 TUYA_DP_RECHARGE_ENERGY = 107 TUYA_DP_COST_PARAMETERS = 108 TUYA_DP_LEAKAGE_PARAMETERS = 109 TUYA_DP_VOLTAGE_THRESHOLD = 110 TUYA_DP_CURRENT_THRESHOLD = 111 TUYA_DP_TEMPERATURE_THRESHOLD = 112 TUYA_DP_TOTAL_ACTIVE_POWER = 113 TUYA_DP_EQUIPMENT_NUMBER_AND_TYPE = 114 TUYA_DP_CLEAR_ENERGY = 115 TUYA_DP_LOCKING = 116 # test button pressed TUYA_DP_TOTAL_REVERSE_ACTIVE_POWER = 117 TUYA_DP_HISTORICAL_VOLTAGE = 118 TUYA_DP_HISTORICAL_CURRENT = 119 class FaultCode(t.enum8): """Fault Code enum.""" CLEAR = 0x00 OVERVOLTAGE = 0x01 UNDERVOLTAGE = 0x02 OVERCURRENT = 0x04 OVERTEMPERATURE = 0x08 OVERLEAKAGECURRENT = 0x0A TRIPTEST = 0x10 SAFETYLOCK = 0x80 class SelfTest(t.enum8): """Self test enum.""" CLEAR = 0x00 TEST = 0x01 class CostParameters(t.Struct): """Tuya cost parameters.""" cost_parameters: t.uint16_t_be cost_parameters_enabled: t.Bool class LeakageParameters(t.Struct): """Tuya leakage parameters.""" self_test_auto_days: t.uint8_t self_test_auto_hours: t.uint8_t self_test_auto: t.Bool over_leakage_current_threshold: t.uint16_t_be over_leakage_current_trip: t.Bool over_leakage_current_alarm: t.Bool self_test: SelfTest class VoltageParameters(t.Struct): """Tuya voltage parameters.""" over_voltage_threshold: t.uint16_t_be over_voltage_trip: t.Bool over_voltage_alarm: t.Bool under_voltage_threshold: t.uint16_t_be under_voltage_trip: t.Bool under_voltage_alarm: t.Bool class CurrentParameters(t.Struct): """Tuya current parameters.""" over_current_threshold: t.uint24_t_be over_current_trip: t.Bool over_current_alarm: t.Bool class TemperatureSetting(t.Struct): """Tuya temperature parameters.""" over_temperature_threshold: t.int8s over_temperature_trip: t.Bool over_temperature_alarm: t.Bool class TuyaRCBOBasic(CustomCluster, Basic): """Provide Tuya Basic Cluster with custom attributes.""" attributes = Basic.attributes.copy() attributes.update( { 0xFFE2: ("tuya_FFE2", t.uint8_t), 0xFFE4: ("tuya_FFE4", t.uint8_t), } ) class TuyaRCBOOnOff(TuyaOnOff, TuyaAttributesCluster): """Custom class for on off switch.""" attributes = TuyaOnOff.attributes.copy() attributes.update( { 0x8000: ("child_lock", t.Bool), 0x8002: ("power_on_state", PowerOnState), 0xF090: ("countdown_timer", t.uint32_t), 0xF740: ("trip", t.Bool), } ) server_commands = TuyaOnOff.server_commands.copy() server_commands.update( { 0x74: foundation.ZCLCommandDef("clear_locking", {}, False), } ) async def command( self, command_id: Union[foundation.GeneralCommand, int, t.uint8_t], *args, manufacturer: Optional[Union[int, t.uint16_t]] = None, expect_reply: bool = True, tsn: Optional[Union[int, t.uint8_t]] = None, ): """Override the default Cluster command.""" # clear_locking if command_id == 0x74: self.debug( "Sending Tuya Cluster Command... Cluster Command is %x, Arguments are %s", command_id, args, ) cluster_data = TuyaClusterData( endpoint_id=self.endpoint.endpoint_id, cluster_name=self.ep_attribute, cluster_attr="trip", attr_value=True, expect_reply=expect_reply, manufacturer=manufacturer, ) self.endpoint.device.command_bus.listener_event( TUYA_MCU_COMMAND, cluster_data, ) return foundation.GENERAL_COMMANDS[ foundation.GeneralCommand.Default_Response ].schema(command_id=command_id, status=foundation.Status.SUCCESS) return await super().command(command_id, args, manufacturer, expect_reply, tsn) class TuyaRCBOElectricalMeasurement(ElectricalMeasurement, TuyaAttributesCluster): """Custom class for power, voltage and current measurement.""" AC_VOLTAGE_MULTIPLIER = 0x0600 AC_VOLTAGE_DIVISOR = 0x0601 AC_CURRENT_MULTIPLIER = 0x0602 AC_CURRENT_DIVISOR = 0x0603 AC_POWER_MULTIPLIER = 0x0604 AC_POWER_DIVISOR = 0x0605 _CONSTANT_ATTRIBUTES = { AC_VOLTAGE_MULTIPLIER: 1, AC_VOLTAGE_DIVISOR: 10, AC_CURRENT_MULTIPLIER: 1, AC_CURRENT_DIVISOR: 1000, AC_POWER_MULTIPLIER: 1, AC_POWER_DIVISOR: 10, } attributes = ElectricalMeasurement.attributes.copy() attributes.update( { 0x0802: ("ac_current_overload", t.uint24_t), 0xF1A0: ("alarm", FaultCode), 0xF680: ("leakage_current", t.uint32_t), 0xF6D0: ("self_test_auto_days", t.uint8_t), 0xF6D1: ("self_test_auto_hours", t.uint8_t), 0xF6D2: ("self_test_auto", t.Bool), 0xF6D3: ("over_leakage_current_threshold", t.uint16_t), 0xF6D5: ("over_leakage_current_trip", t.Bool), 0xF6D6: ("over_leakage_current_alarm", t.Bool), 0xF6D7: ("self_test", SelfTest), 0xF6E3: ("over_voltage_trip", t.Bool), 0xF6E7: ("under_voltage_trip", t.Bool), 0xF6F3: ("over_current_trip", t.Bool), 0xF760: ("rms_historical_voltage", t.uint16_t), 0xF770: ("rms_historical_current", t.uint16_t), } ) def update_attribute(self, attr_name: str, value: Any) -> None: """Calculate active current and power factor.""" super().update_attribute(attr_name, value) if attr_name == "rms_current": rms_voltage = self.get("rms_voltage") if rms_voltage: apparent_power = value * rms_voltage / 1000 super().update_attribute("apparent_power", int(apparent_power)) if attr_name == "active_power": apparent_power = self.get("apparent_power") if apparent_power: power_factor = value / apparent_power * 1000 if power_factor > 1000: power_factor = 1000 super().update_attribute("power_factor", int(power_factor)) class TuyaRCBODeviceTemperature(DeviceTemperature, TuyaAttributesCluster): """Tuya device temperature.""" attributes = DeviceTemperature.attributes.copy() attributes.update( { 0xFF10: ("over_temp_trip", t.Bool), } ) class TuyaRCBOMetering(Metering, TuyaAttributesCluster): """Custom class for total energy measurement.""" UNIT_OF_MEASURE = 0x0300 MULTIPLIER = 0x0301 DIVISOR = 0x0302 POWER_WATT = 0x0000 _CONSTANT_ATTRIBUTES = {UNIT_OF_MEASURE: POWER_WATT, MULTIPLIER: 1, DIVISOR: 100} attributes = Metering.attributes.copy() attributes.update( { 0xF6A0: ("remaining_energy", t.uint32_t), 0xF6C0: ("cost_parameters", t.uint16_t), 0xF6C1: ("cost_parameters_enabled", t.Bool), 0xF720: ("meter_number", t.LimitedCharString(20)), } ) server_commands = Metering.server_commands.copy() server_commands.update( { 0x73: foundation.ZCLCommandDef("clear_device_data", {}, False), } ) async def command( self, command_id: Union[foundation.GeneralCommand, int, t.uint8_t], *args, manufacturer: Optional[Union[int, t.uint16_t]] = None, expect_reply: bool = True, tsn: Optional[Union[int, t.uint8_t]] = None, ): """Override the default Cluster command.""" self.debug( "Sending Tuya Cluster Command... Cluster Command is %x, Arguments are %s", command_id, args, ) # clear_device_data if command_id == 0x73: cluster_data = TuyaClusterData( endpoint_id=self.endpoint.endpoint_id, cluster_name=self.ep_attribute, cluster_attr="clear_device_data", attr_value=True, expect_reply=expect_reply, manufacturer=manufacturer, ) self.endpoint.device.command_bus.listener_event( TUYA_MCU_COMMAND, cluster_data, ) return foundation.GENERAL_COMMANDS[ foundation.GeneralCommand.Default_Response ].schema(command_id=command_id, status=foundation.Status.SUCCESS) self.warning("Unsupported command_id: %s", command_id) return foundation.GENERAL_COMMANDS[ foundation.GeneralCommand.Default_Response ].schema(command_id=command_id, status=foundation.Status.UNSUP_CLUSTER_COMMAND) class TuyaRCBOManufCluster(TuyaMCUCluster): """Tuya with power measurement data points.""" dp_to_attribute: Dict[int, DPToAttributeMapping] = { TUYA_DP_STATE: DPToAttributeMapping( TuyaRCBOOnOff.ep_attribute, "on_off", ), TUYA_DP_COUNTDOWN_TIMER: DPToAttributeMapping( TuyaRCBOOnOff.ep_attribute, "countdown_timer", ), TUYA_DP_FAULT_CODE: DPToAttributeMapping( TuyaRCBOElectricalMeasurement.ep_attribute, "alarm", lambda x: FaultCode(x), ), TUYA_DP_RELAY_STATUS: DPToAttributeMapping( TuyaRCBOOnOff.ep_attribute, "power_on_state", lambda x: PowerOnState(x), ), TUYA_DP_CHILD_LOCK: DPToAttributeMapping( TuyaRCBOOnOff.ep_attribute, "child_lock", ), TUYA_DP_VOLTAGE: DPToAttributeMapping( TuyaRCBOElectricalMeasurement.ep_attribute, "rms_voltage", lambda x: x[1] | x[0] << 8, ), TUYA_DP_CURRENT: DPToAttributeMapping( TuyaRCBOElectricalMeasurement.ep_attribute, "rms_current", lambda x: x[2] | x[1] << 8, ), TUYA_DP_ACTIVE_POWER: DPToAttributeMapping( TuyaRCBOElectricalMeasurement.ep_attribute, "active_power", lambda x: x[2] | x[1] << 8, ), TUYA_DP_LEAKAGE_CURRENT: DPToAttributeMapping( TuyaRCBOElectricalMeasurement.ep_attribute, "leakage_current", ), TUYA_DP_TEMPERATURE: DPToAttributeMapping( TuyaRCBODeviceTemperature.ep_attribute, "current_temperature", lambda x: x * 100, ), TUYA_DP_REMAINING_ENERGY: DPToAttributeMapping( TuyaRCBOMetering.ep_attribute, "remaining_energy", ), TUYA_DP_COST_PARAMETERS: DPToAttributeMapping( TuyaRCBOMetering.ep_attribute, ("cost_parameters", "cost_parameters_enabled"), lambda x: (x[1] | x[0] << 8, x[2]), lambda *fields: CostParameters(*fields), ), TUYA_DP_LEAKAGE_PARAMETERS: DPToAttributeMapping( TuyaRCBOElectricalMeasurement.ep_attribute, ( "self_test_auto_days", "self_test_auto_hours", "self_test_auto", "over_leakage_current_threshold", "over_leakage_current_trip", "over_leakage_current_alarm", "self_test", ), lambda x: (x[0], x[1], x[2], x[4] | x[3] << 8, x[5], x[6], SelfTest(x[7])), lambda *fields: LeakageParameters(*fields), ), TUYA_DP_VOLTAGE_THRESHOLD: DPToAttributeMapping( TuyaRCBOElectricalMeasurement.ep_attribute, ( "rms_extreme_over_voltage", "over_voltage_trip", "ac_alarms_mask", "rms_extreme_under_voltage", "under_voltage_trip", ), lambda x: ( x[1] | x[0] << 8, x[2], AttributeWithMask(x[3] << 6 | x[7] << 7, 1 << 6 | 1 << 7), x[5] | x[4] << 8, x[6], ), lambda rms_extreme_over_voltage, over_voltage_trip, ac_alarms_mask, rms_extreme_under_voltage, under_voltage_trip: VoltageParameters( rms_extreme_over_voltage, over_voltage_trip, bool(ac_alarms_mask & 0x40), rms_extreme_under_voltage, under_voltage_trip, bool(ac_alarms_mask & 0x80), ), ), TUYA_DP_CURRENT_THRESHOLD: DPToAttributeMapping( TuyaRCBOElectricalMeasurement.ep_attribute, ("ac_current_overload", "over_current_trip", "ac_alarms_mask"), lambda x: ( (x[2] | x[1] << 8 | x[0] << 16), x[3], AttributeWithMask(x[4] << 1, 1 << 1), ), lambda ac_current_overload, over_current_trip, ac_alarms_mask: CurrentParameters( ac_current_overload, over_current_trip, bool(ac_alarms_mask & 0x02) ), ), TUYA_DP_TEMPERATURE_THRESHOLD: DPToAttributeMapping( TuyaRCBODeviceTemperature.ep_attribute, ("high_temp_thres", "over_temp_trip", "dev_temp_alarm_mask"), lambda x: (x[0] if x[0] <= 127 else x[0] - 256, x[1], x[2] << 1), lambda x, y, z: TemperatureSetting(x, y, bool(z & 0x02)), ), TUYA_DP_TOTAL_ACTIVE_POWER: DPToAttributeMapping( TuyaRCBOMetering.ep_attribute, "current_summ_delivered", ), TUYA_DP_EQUIPMENT_NUMBER_AND_TYPE: DPToAttributeMapping( TuyaRCBOMetering.ep_attribute, "meter_number", lambda x: x.rstrip(), ), TUYA_DP_CLEAR_ENERGY: DPToAttributeMapping( TuyaRCBOMetering.ep_attribute, "clear_device_data" ), TUYA_DP_LOCKING: DPToAttributeMapping(TuyaRCBOOnOff.ep_attribute, "trip"), TUYA_DP_TOTAL_REVERSE_ACTIVE_POWER: DPToAttributeMapping( TuyaRCBOMetering.ep_attribute, "current_summ_received", ), TUYA_DP_HISTORICAL_VOLTAGE: DPToAttributeMapping( TuyaRCBOElectricalMeasurement.ep_attribute, "rms_historical_voltage", lambda x: x[1] | x[0] << 8, ), TUYA_DP_HISTORICAL_CURRENT: DPToAttributeMapping( TuyaRCBOElectricalMeasurement.ep_attribute, "rms_historical_current", lambda x: x[2] | x[1] << 8, ), } data_point_handlers: Dict[int, str] = { TUYA_DP_STATE: "_dp_2_attr_update", TUYA_DP_COUNTDOWN_TIMER: "_dp_2_attr_update", TUYA_DP_FAULT_CODE: "_dp_2_attr_update", TUYA_DP_RELAY_STATUS: "_dp_2_attr_update", TUYA_DP_CHILD_LOCK: "_dp_2_attr_update", TUYA_DP_VOLTAGE: "_dp_2_attr_update", TUYA_DP_CURRENT: "_dp_2_attr_update", TUYA_DP_ACTIVE_POWER: "_dp_2_attr_update", TUYA_DP_LEAKAGE_CURRENT: "_dp_2_attr_update", TUYA_DP_TEMPERATURE: "_dp_2_attr_update", TUYA_DP_REMAINING_ENERGY: "_dp_2_attr_update", TUYA_DP_COST_PARAMETERS: "_dp_2_attr_update", TUYA_DP_LEAKAGE_PARAMETERS: "_dp_2_attr_update", TUYA_DP_VOLTAGE_THRESHOLD: "_dp_2_attr_update", TUYA_DP_CURRENT_THRESHOLD: "_dp_2_attr_update", TUYA_DP_TEMPERATURE_THRESHOLD: "_dp_2_attr_update", TUYA_DP_TOTAL_ACTIVE_POWER: "_dp_2_attr_update", TUYA_DP_EQUIPMENT_NUMBER_AND_TYPE: "_dp_2_attr_update", TUYA_DP_LOCKING: "_dp_2_attr_update", TUYA_DP_TOTAL_REVERSE_ACTIVE_POWER: "_dp_2_attr_update", TUYA_DP_HISTORICAL_VOLTAGE: "_dp_2_attr_update", TUYA_DP_HISTORICAL_CURRENT: "_dp_2_attr_update", } class TuyaCircuitBreaker(CustomDevice): """Tuya RCBO with power meter device.""" signature = { # "node_descriptor": "", # device_version=1 # input_clusters=[0x0000, 0x0004, 0x0005, 0xef00] # output_clusters=[0x000a, 0x0019] MODELS_INFO: [ ("_TZE200_abatw3kj", "TS0601"), ], ENDPOINTS: { # 1: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.SMART_PLUG, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, TuyaMCUCluster.cluster_id, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], }, 242: { #
github-actions[bot] commented 6 months ago

There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates. Please make sure to update to the latest version and check if that solves the issue. Let us know if that works for you by adding a comment 👍 This issue has now been marked as stale and will be closed if no further activity occurs. Thank you for your contributions.