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
774 stars 703 forks source link

[Device Support Request] Tuya Outdoor Siren with Solar ts0601 #3250

Open Neolooser opened 4 months ago

Neolooser commented 4 months ago

Problem description

Hi, I can't find any quirks working on that device it's not working with the ts0601_siren.py

this is my config : zha: zigpy_config: database_path: /zigbee.db custom_quirks_path: /config/zha_quirks

thank's for your help

Solution description

Any quirks working on that device

Screenshots/Video

Screenshots/Video [Paste/upload your media here]

Device signature

{ "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.EndDevice: 2>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress: 128>, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=<DescriptorCapability.NONE: 0>, allocate_address=True, is_alternate_pan_coordinator=False, is_coordinator=False, is_end_device=True, is_full_function_device=False, is_mains_powered=False, is_receiver_on_when_idle=False, is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x0051", "input_clusters": [ "0x0000", "0x0004", "0x0005", "0xef00" ], "output_clusters": [ "0x000a", "0x0019" ] } }, "manufacturer": "_TZE204_nlrfgpny", "model": "TS0601", "class": "zigpy.device.Device" }

Diagnostic information

zha-8d888a1b0a2bd264aa75ceb1d89d2c61-_TZE204_nlrfgpny TS0601-43464bf368efc343ab7e786befe6bcac.json

Logs

Logs ```python [Paste the logs here] ```

Custom quirk

Custom quirk ```python [Paste your custom quirk here] ```

Additional information

No response

asiersan commented 2 months ago

Problem description

Same here, but changing the model info, in the ts0601_siren.py, from _TZE200_nlrfgpny to_TZE204_nlrfgpny , the siren works, with a on/off switch. No volume control, no melody control, no battery status, no tamper status,..... but its a step.

this is my config : zha: zigpy_config: database_path: /zigbee.db custom_quirks_path: /config/zha_quirks

Solution description

Captura de pantalla 2024-09-03 214504

Device signature

Device signature ```json `{ "node_descriptor": { "logical_type": 2, "complex_descriptor_available": 0, "user_descriptor_available": 0, "reserved": 0, "aps_flags": 0, "frequency_band": 8, "mac_capability_flags": 128, "manufacturer_code": 4417, "maximum_buffer_size": 66, "maximum_incoming_transfer_size": 66, "server_mask": 10752, "maximum_outgoing_transfer_size": 66, "descriptor_capability_field": 0 }, "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x0403", "input_clusters": [ "0x0000", "0x0004", "0x0005", "0x0006", "0xef00" ], "output_clusters": [ "0x000a", "0x0019" ] }, "242": { "profile_id": "0xa1e0", "device_type": "0x0061", "input_clusters": [], "output_clusters": [ "0x0021" ] } }, "manufacturer": "_TZE204_nlrfgpny", "model": "TS0601", "class": "ts0601_siren.TuyaSirenGPP_NoSensors" }` ```

Diagnostic information

Diagnostic information ```json { "home_assistant": { "installation_type": "Home Assistant OS", "version": "2024.8.3", "dev": false, "hassio": true, "virtualenv": false, "python_version": "3.12.4", "docker": true, "arch": "aarch64", "timezone": "Europe/Madrid", "os_name": "Linux", "os_version": "6.6.31-haos-raspi", "supervisor": "2024.08.0", "host_os": "Home Assistant OS 13.1", "docker_version": "26.1.4", "chassis": "embedded", "run_as_root": true }, "custom_components": { "irrigationprogram": { "documentation": "https://github.com/petergridge/irrigation-v5", "version": "5.4.20", "requirements": [] }, "alarmo": { "documentation": "https://github.com/nielsfaber/alarmo", "version": "v1.10.4", "requirements": [] }, "openweathermaphistory": { "documentation": "https://github.com/petergridge/openweathermaphistory", "version": "2.0.12", "requirements": [ "pyowm==3.2.0" ] }, "alexa_media": { "documentation": "https://github.com/alandtse/alexa_media_player/wiki", "version": "4.12.11", "requirements": [ "alexapy==1.28.2", "packaging>=20.3", "wrapt>=1.14.0" ] }, "hacs": { "documentation": "https://hacs.xyz/docs/configuration/start", "version": "2.0.0", "requirements": [ "aiogithubapi>=22.10.1" ] }, "sun2": { "documentation": "https://github.com/pnbruckner/ha-sun2/blob/3.3.2/README.md", "version": "3.3.2", "requirements": [] } }, "integration_manifest": { "domain": "zha", "name": "Zigbee Home Automation", "after_dependencies": [ "onboarding", "usb" ], "codeowners": [ "dmulcahey", "adminiuga", "puddly", "TheJulianJES" ], "config_flow": true, "dependencies": [ "file_upload" ], "documentation": "https://www.home-assistant.io/integrations/zha", "iot_class": "local_polling", "loggers": [ "aiosqlite", "bellows", "crccheck", "pure_pcapy3", "zhaquirks", "zigpy", "zigpy_deconz", "zigpy_xbee", "zigpy_zigate", "zigpy_znp", "zha", "universal_silabs_flasher" ], "requirements": [ "universal-silabs-flasher==0.0.22", "zha==0.0.31" ], "usb": [ { "vid": "10C4", "pid": "EA60", "description": "*2652*", "known_devices": [ "slae.sh cc2652rb stick" ] }, { "vid": "10C4", "pid": "EA60", "description": "*slzb-07*", "known_devices": [ "smlight slzb-07" ] }, { "vid": "1A86", "pid": "55D4", "description": "*sonoff*plus*", "known_devices": [ "sonoff zigbee dongle plus v2" ] }, { "vid": "10C4", "pid": "EA60", "description": "*sonoff*plus*", "known_devices": [ "sonoff zigbee dongle plus" ] }, { "vid": "10C4", "pid": "EA60", "description": "*tubeszb*", "known_devices": [ "TubesZB Coordinator" ] }, { "vid": "1A86", "pid": "7523", "description": "*tubeszb*", "known_devices": [ "TubesZB Coordinator" ] }, { "vid": "1A86", "pid": "7523", "description": "*zigstar*", "known_devices": [ "ZigStar Coordinators" ] }, { "vid": "1CF1", "pid": "0030", "description": "*conbee*", "known_devices": [ "Conbee II" ] }, { "vid": "0403", "pid": "6015", "description": "*conbee*", "known_devices": [ "Conbee III" ] }, { "vid": "10C4", "pid": "8A2A", "description": "*zigbee*", "known_devices": [ "Nortek HUSBZB-1" ] }, { "vid": "0403", "pid": "6015", "description": "*zigate*", "known_devices": [ "ZiGate+" ] }, { "vid": "10C4", "pid": "EA60", "description": "*zigate*", "known_devices": [ "ZiGate" ] }, { "vid": "10C4", "pid": "8B34", "description": "*bv 2010/10*", "known_devices": [ "Bitron Video AV2010/10" ] } ], "zeroconf": [ { "type": "_esphomelib._tcp.local.", "name": "tube*" }, { "type": "_zigate-zigbee-gateway._tcp.local.", "name": "*zigate*" }, { "type": "_zigstar_gw._tcp.local.", "name": "*zigstar*" }, { "type": "_uzg-01._tcp.local.", "name": "uzg-01*" }, { "type": "_slzb-06._tcp.local.", "name": "slzb-06*" }, { "type": "_xzg._tcp.local.", "name": "xzg*" }, { "type": "_czc._tcp.local.", "name": "czc*" } ], "is_built_in": true }, "setup_times": { "null": { "setup": 0.00042552000013529323 }, "1f0162327039a04f8c5ae3f973a92334": { "wait_import_platforms": -0.10252964899973449, "wait_base_component": -0.0060154510001666495, "config_entry_setup": 25.509830168000008 } }, "data": { "ieee": "**REDACTED**", "nwk": 20093, "manufacturer": "_TZE204_nlrfgpny", "model": "TS0601", "name": "_TZE204_nlrfgpny TS0601", "quirk_applied": true, "quirk_class": "ts0601_siren.TuyaSirenGPP_NoSensors", "quirk_id": null, "manufacturer_code": 4417, "power_source": "Battery or Unknown", "lqi": 240, "rssi": -40, "last_seen": "2024-09-03T21:26:59", "available": true, "device_type": "EndDevice", "signature": { "node_descriptor": { "logical_type": 2, "complex_descriptor_available": 0, "user_descriptor_available": 0, "reserved": 0, "aps_flags": 0, "frequency_band": 8, "mac_capability_flags": 128, "manufacturer_code": 4417, "maximum_buffer_size": 66, "maximum_incoming_transfer_size": 66, "server_mask": 10752, "maximum_outgoing_transfer_size": 66, "descriptor_capability_field": 0 }, "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x0403", "input_clusters": [ "0x0000", "0x0004", "0x0005", "0x0006", "0xef00" ], "output_clusters": [ "0x000a", "0x0019" ] }, "242": { "profile_id": "0xa1e0", "device_type": "0x0061", "input_clusters": [], "output_clusters": [ "0x0021" ] } }, "manufacturer": "_TZE204_nlrfgpny", "model": "TS0601" }, "active_coordinator": false, "entities": [ { "entity_id": "switch.tze204_nlrfgpny_ts0601_interruptor", "name": "_TZE204_nlrfgpny TS0601" }, { "entity_id": "update.tze204_nlrfgpny_ts0601_firmware", "name": "_TZE204_nlrfgpny TS0601" }, { "entity_id": "update.sirena_firmware", "name": "_TZE204_nlrfgpny TS0601" }, { "entity_id": "switch.sirena_interruptor", "name": "_TZE204_nlrfgpny TS0601" } ], "neighbors": [], "routes": [], "endpoint_names": [ { "name": "IAS_WARNING_DEVICE" }, { "name": "PROXY_BASIC" } ], "user_given_name": "Sirena", "device_reg_id": "e45778bf043a92091d9659e2e313a3a2", "area_id": null, "cluster_details": { "1": { "device_type": { "name": "IAS_WARNING_DEVICE", "id": 1027 }, "profile_id": 260, "in_clusters": { "0x0000": { "endpoint_attribute": "basic", "attributes": { "0x0001": { "attribute_name": "app_version", "value": 73 }, "0xfffe": { "attribute_name": "reporting_status", "value": 0 } }, "unsupported_attributes": { "0x0013": { "attribute_name": "alarm_mask" } } }, "0x0004": { "endpoint_attribute": "groups", "attributes": { "0x0000": { "attribute_name": "name_support", "value": 0 } }, "unsupported_attributes": {} }, "0x0005": { "endpoint_attribute": "scenes", "attributes": { "0x0001": { "attribute_name": "current_scene", "value": 0 }, "0x0004": { "attribute_name": "name_support", "value": 0 } }, "unsupported_attributes": {} }, "0xef00": { "endpoint_attribute": "tuya_manufacturer", "attributes": { "0xef00": { "attribute_name": "mcu_version", "value": "1.1.1" } }, "unsupported_attributes": {} }, "0x0006": { "endpoint_attribute": "on_off", "attributes": { "0x0000": { "attribute_name": "on_off", "value": 0 } }, "unsupported_attributes": {} } }, "out_clusters": { "0x0019": { "endpoint_attribute": "ota", "attributes": { "0x0002": { "attribute_name": "current_file_version", "value": 73 } }, "unsupported_attributes": {} }, "0x000a": { "endpoint_attribute": "time", "attributes": { "0xfffd": { "attribute_name": "cluster_revision", "value": 1 } }, "unsupported_attributes": {} } } }, "242": { "device_type": { "name": "PROXY_BASIC", "id": 97 }, "profile_id": 41440, "in_clusters": {}, "out_clusters": { "0x0021": { "endpoint_attribute": "green_power", "attributes": {}, "unsupported_attributes": {} } } } } } } ```

Logs

Custom quirk

Custom quirk ```python """Map from manufacturer to standard clusters for the NEO Siren device.""" from typing import Optional, Union from zigpy.profiles import zgp, zha from zigpy.quirks import CustomDevice import zigpy.types as t from zigpy.zcl import foundation from zigpy.zcl.clusters.general import ( Basic, GreenPowerProxy, Groups, Identify, OnOff, Ota, Scenes, Time, ) from zigpy.zcl.clusters.measurement import RelativeHumidity, TemperatureMeasurement from zhaquirks import Bus, LocalDataCluster from zhaquirks.const import ( DEVICE_TYPE, ENDPOINTS, INPUT_CLUSTERS, MODELS_INFO, OUTPUT_CLUSTERS, PROFILE_ID, ) from zhaquirks.tuya import TuyaManufCluster, TuyaManufClusterAttributes from zhaquirks.tuya.mcu import ( TUYA_MCU_COMMAND, DPToAttributeMapping, TuyaAttributesCluster, TuyaClusterData, TuyaMCUCluster, ) TUYA_BATTERY_ATTR = 0x020F # [0, 0, 0, 100] battery percentage TUYA_ALARM_ATTR = 0x0168 # [0]/[1] Alarm! TUYA_TEMP_ALARM_ATTR = 0x0171 # [0]/[1] Disable/Enable alarm by temperature TUYA_HUMID_ALARM_ATTR = 0x0172 # [0]/[1] Disable/Enable alarm by humidity TUYA_ALARM_DURATION_ATTR = 0x0267 # [0,0,0,10] alarm duration in seconds: 0-1800 TUYA_TEMPERATURE_ATTR = 0x0269 # [0,0,0,240] temperature in decidegree TUYA_HUMIDITY_ATTR = 0x026A # [0,0,0,36] humidity TUYA_ALARM_MIN_TEMP_ATTR = 0x026B # [0,0,0,18] min alarm temperature threshold TUYA_ALARM_MAX_TEMP_ATTR = 0x026C # [0,0,0,18] max alarm temperature threshold TUYA_ALARM_MIN_HUMID_ATTR = 0x026D # [0,0,0,18] min alarm humidity threshold TUYA_ALARM_MAX_HUMID_ATTR = 0x026E # [0,0,0,18] max alarm humidity threshold TUYA_MELODY_ATTR = 0x0466 # [5] Melody TUYA_VOLUME_ATTR = 0x0474 # [0]/[1]/[2] Volume 0-low, 2-high class NeoAlarmVolume(t.enum8): """Neo alarm volume enum.""" low = 0x00 medium = 0x01 high = 0x02 class NeoAlarmMelody(t.enum8): """Neo alarm melody enum.""" melody_01 = 0x01 melody_02 = 0x02 melody_03 = 0x03 melody_04 = 0x04 melody_05 = 0x05 melody_06 = 0x06 melody_07 = 0x07 melody_08 = 0x08 melody_09 = 0x09 melody_10 = 0x0A melody_11 = 0x0B melody_12 = 0x0C melody_13 = 0x0D melody_14 = 0x0E melody_15 = 0x0F melody_16 = 0x10 melody_17 = 0x11 melody_18 = 0x12 class TuyaManufClusterSiren(TuyaManufClusterAttributes): """Manufacturer Specific Cluster of the NEO Siren device.""" attributes = TuyaManufClusterAttributes.attributes.copy() attributes.update( { TUYA_ALARM_ATTR: ("alarm", t.uint8_t, True), TUYA_TEMP_ALARM_ATTR: ("enable_temperature_alarm", t.uint8_t, True), TUYA_HUMID_ALARM_ATTR: ("enable_humidity_alarm", t.uint8_t, True), TUYA_ALARM_DURATION_ATTR: ("alarm_duration", t.uint32_t, True), TUYA_TEMPERATURE_ATTR: ("temperature", t.uint32_t, True), TUYA_HUMIDITY_ATTR: ("humidity", t.uint32_t, True), TUYA_ALARM_MIN_TEMP_ATTR: ("alarm_temperature_min", t.uint32_t, True), TUYA_ALARM_MAX_TEMP_ATTR: ("alarm_temperature_max", t.uint32_t, True), TUYA_ALARM_MIN_HUMID_ATTR: ("alarm_humidity_min", t.uint32_t, True), TUYA_ALARM_MAX_HUMID_ATTR: ("alarm_humidity_max", t.uint32_t, True), TUYA_MELODY_ATTR: ("melody", t.uint8_t, True), TUYA_VOLUME_ATTR: ("volume", t.uint8_t, True), } ) def _update_attribute(self, attrid, value): super()._update_attribute(attrid, value) if attrid == TUYA_TEMPERATURE_ATTR: self.endpoint.device.temperature_bus.listener_event( "temperature_reported", value * 10, # decidegree to centidegree ) elif attrid == TUYA_HUMIDITY_ATTR: self.endpoint.device.humidity_bus.listener_event( "humidity_reported", value * 100, # whole percentage to 1/1000th ) elif attrid == TUYA_ALARM_ATTR: self.endpoint.device.switch_bus.listener_event( "switch_event", value, # boolean 1=on / 0=off ) class TuyaSirenOnOff(LocalDataCluster, OnOff): """Tuya On/Off cluster for siren device.""" ATTR_ID = 0 def __init__(self, *args, **kwargs): """Init.""" super().__init__(*args, **kwargs) self.endpoint.device.switch_bus.add_listener(self) def switch_event(self, state): """Switch event.""" self._update_attribute(self.ATTR_ID, state) 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 command and defer to the alarm attribute.""" if command_id in (0x0000, 0x0001): (res,) = await self.endpoint.tuya_manufacturer.write_attributes( {TUYA_ALARM_ATTR: command_id}, manufacturer=manufacturer ) return foundation.GENERAL_COMMANDS[ foundation.GeneralCommand.Default_Response ].schema(command_id=command_id, status=res[0].status) return foundation.GENERAL_COMMANDS[ foundation.GeneralCommand.Default_Response ].schema(command_id=command_id, status=foundation.Status.UNSUP_CLUSTER_COMMAND) class TuyaTemperatureMeasurement(LocalDataCluster, TemperatureMeasurement): """Temperature cluster acting from events from temperature bus.""" ATTR_ID = 0 def __init__(self, *args, **kwargs): """Init.""" super().__init__(*args, **kwargs) self.endpoint.device.temperature_bus.add_listener(self) def temperature_reported(self, value): """Temperature reported.""" self._update_attribute(self.ATTR_ID, value) class TuyaRelativeHumidity(LocalDataCluster, RelativeHumidity): """Humidity cluster acting from events from humidity bus.""" ATTR_ID = 0 def __init__(self, *args, **kwargs): """Init.""" super().__init__(*args, **kwargs) self.endpoint.device.humidity_bus.add_listener(self) def humidity_reported(self, value): """Humidity reported.""" self._update_attribute(self.ATTR_ID, value) class TuyaSiren(CustomDevice): """NEO Tuya Siren and humidity/temperature sensor.""" def __init__(self, *args, **kwargs): """Init device.""" self.temperature_bus = Bus() self.humidity_bus = Bus() self.switch_bus = Bus() super().__init__(*args, **kwargs) signature = { # endpoint=1 profile=260 device_type=0 device_version=0 input_clusters=[0, 3] # output_clusters=[3, 25]> MODELS_INFO: [("_TYST11_d0yu2xgi", "0yu2xgi")], ENDPOINTS: { 1: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH, INPUT_CLUSTERS: [Basic.cluster_id, Identify.cluster_id], OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], } }, } replacement = { ENDPOINTS: { 1: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.IAS_WARNING_DEVICE, INPUT_CLUSTERS: [ Basic.cluster_id, Identify.cluster_id, TuyaManufClusterSiren, TuyaTemperatureMeasurement, TuyaRelativeHumidity, TuyaSirenOnOff, ], OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], } } } class TuyaSiren2(TuyaSiren): """NEO Tuya Siren and humidity/temperature sensor.""" signature = { # endpoint=1 profile=260 device_type=81 device_version=1 input_clusters=[0, 4, 5, 61184] # output_clusters=[25, 10]> MODELS_INFO: [("_TZE204_nlrfgpny", "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, TuyaManufCluster.cluster_id, ], OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], } }, } class TuyaMCUSiren(OnOff, TuyaAttributesCluster): """Tuya MCU cluster for siren device.""" attributes = OnOff.attributes.copy() attributes.update( { TUYA_BATTERY_ATTR: ("battery", t.uint32_t, True), TUYA_ALARM_ATTR: ("alarm", t.uint8_t, True), TUYA_ALARM_DURATION_ATTR: ("alarm_duration", t.uint32_t, True), TUYA_MELODY_ATTR: ("melody", NeoAlarmMelody, True), TUYA_VOLUME_ATTR: ("volume", NeoAlarmVolume, True), } ) async def write_attributes(self, attributes, manufacturer=None): """Overwrite to force manufacturer code.""" return await super().write_attributes( attributes, manufacturer=foundation.ZCLHeader.NO_MANUFACTURER_ID ) 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.""" # (off, on) if command_id in (0x0000, 0x0001): cluster_data = TuyaClusterData( endpoint_id=self.endpoint.endpoint_id, cluster_name=self.ep_attribute, cluster_attr="on_off", attr_value=bool(command_id), expect_reply=expect_reply, manufacturer=foundation.ZCLHeader.NO_MANUFACTURER_ID, ) 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 NeoSirenManufCluster(TuyaMCUCluster): """Tuya with NEO Siren data points.""" dp_to_attribute: dict[int, DPToAttributeMapping] = { 5: DPToAttributeMapping( TuyaMCUSiren.ep_attribute, "volume", converter=lambda x: NeoAlarmVolume(x), ), 7: DPToAttributeMapping( TuyaMCUSiren.ep_attribute, "alarm_duration", ), 13: DPToAttributeMapping( TuyaMCUSiren.ep_attribute, "on_off", ), 15: DPToAttributeMapping( TuyaMCUSiren.ep_attribute, "battery", ), 21: DPToAttributeMapping( TuyaMCUSiren.ep_attribute, "melody", converter=lambda x: NeoAlarmMelody(x), ), } data_point_handlers = { 13: "_dp_2_attr_update", 5: "_dp_2_attr_update", 7: "_dp_2_attr_update", 15: "_dp_2_attr_update", 21: "_dp_2_attr_update", } class TuyaSirenGPP_NoSensors(CustomDevice): """NEO Tuya Siren without sensor.""" signature = { # endpoint=1 profile=260 device_type=81 device_version=1 input_clusters=[0, 4, 5, 61184] # output_clusters=[25, 10]> MODELS_INFO: [ ("_TZE200_nlrfgpny", "TS0601"), ("_TZE204_nlrfgpny", "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, TuyaManufCluster.cluster_id, ], OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], }, # 242: { # PROFILE_ID: zgp.PROFILE_ID, # DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, # INPUT_CLUSTERS: [], # OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], # }, }, } replacement = { ENDPOINTS: { 1: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.IAS_WARNING_DEVICE, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, NeoSirenManufCluster, TuyaMCUSiren, ], OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], }, 242: { PROFILE_ID: zgp.PROFILE_ID, DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, INPUT_CLUSTERS: [], OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], }, } } ```

Additional information

No response