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
722 stars 670 forks source link

[Device Support Request] TZE204_ex3rcdha presence and lux sensor #3309

Open agf102 opened 3 weeks ago

agf102 commented 3 weeks ago

Problem description

I've just bought a couple of these from Aliexpress (https://www.aliexpress.com/item/1005007335302133.html) and have been playing around to see if they work in HA / ZHA. I copied a quirks file I found on the HA forum and added the model references in.

I can now see controls for detection delay; fading time; max / min range; sensitivity and can see sensors for illuminance (shows unknown), occupancy (shows clear) and firmware (shows up to date)

Solution description

Correctly operating illuminance and occupancy sensors

Screenshots/Video

Screenshots/Video [Paste/upload your media here]

Device signature

Device signature 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 { "node_descriptor": { "logical_type": 1, "complex_descriptor_available": 0, "user_descriptor_available": 0, "reserved": 0, "aps_flags": 0, "frequency_band": 8, "mac_capability_flags": 142, "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": "0x0107", "input_clusters": [ "0x0000", "0x0004", "0x0005", "0x000c", "0x000d", "0x0400", "0x0406", "0xef00" ], "output_clusters": [ "0x000a", "0x0019" ] }, "2": { "profile_id": "0x0104", "device_type": "0x0007", "input_clusters": [ "0x000d" ], "output_clusters": [] }, "3": { "profile_id": "0x0104", "device_type": "0x0007", "input_clusters": [ "0x000d" ], "output_clusters": [] }, "4": { "profile_id": "0x0104", "device_type": "0x0007", "input_clusters": [ "0x000d" ], "output_clusters": [] }, "5": { "profile_id": "0x0104", "device_type": "0x0007", "input_clusters": [ "0x000d" ], "output_clusters": [] }, "242": { "profile_id": "0xa1e0", "device_type": "0x0061", "input_clusters": [], "output_clusters": [ "0x0021" ] } }, "manufacturer": "_TZE204_ex3rcdha", "model": "TS0601", "class": "ts0601_radar.TuyaMmwRadarOccupancyVariant1GPP" }

Diagnostic information

Diagnostic information { "home_assistant": { "installation_type": "Home Assistant OS", "version": "2024.8.2", "dev": false, "hassio": true, "virtualenv": false, "python_version": "3.12.4", "docker": true, "arch": "x86_64", "timezone": "Europe/London", "os_name": "Linux", "os_version": "6.6.46-haos", "supervisor": "2024.08.0", "host_os": "Home Assistant OS 13.1", "docker_version": "26.1.4", "chassis": "vm", "run_as_root": true }, "custom_components": { "truenas": { "documentation": "https://github.com/tomaae/homeassistant-truenas", "version": "0.0.0", "requirements": [] }, "spook_inverse": { "documentation": "https://spook.boo", "version": "3.1.0", "requirements": [] }, "frigate": { "documentation": "https://github.com/blakeblackshear/frigate", "version": "5.3.0", "requirements": [ "pytz" ] }, "hypervolt_charger": { "documentation": "https://github.com/gndean/home-assistant-hypervolt-charger", "version": "2.3.2", "requirements": [ "websockets==11.0.3", "aiofiles==24.1.0" ] }, "octopus_energy": { "documentation": "https://bottlecapdave.github.io/HomeAssistant-OctopusEnergy", "version": "12.2.0", "requirements": [] }, "spook": { "documentation": "https://spook.boo", "version": "3.1.0", "requirements": [] }, "mass": { "documentation": "https://music-assistant.io", "version": "2024.8.0", "requirements": [ "music-assistant==2.1.3" ] }, "scrypted": { "documentation": "https://www.home-assistant.io/integrations/scrypted", "version": "0.0.9", "requirements": [] }, "foxess": { "documentation": "https://github.com/macxq/foxess-ha", "version": "v0.4", "requirements": [ "random_user_agent" ] }, "uptime_kuma": { "documentation": "https://github.com/meichthys/uptime_kuma/blob/main/README.md", "version": "2.1.0", "requirements": [ "pyuptimekuma-hass" ] }, "powercalc": { "documentation": "https://docs.powercalc.nl", "version": "v1.14.2", "requirements": [ "numpy>=1.21.1" ] }, "flightradar24": { "documentation": "https://github.com/AlexandrErohin/home-assistant-flightradar24", "version": "1.15.0", "requirements": [ "FlightRadarAPI==1.3.25", "pycountry==23.12.11" ] }, "hacs": { "documentation": "https://hacs.xyz/docs/configuration/start", "version": "2.0.0", "requirements": [ "aiogithubapi>=22.10.1" ] } }, "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.00018496799999923041 }, "1939130f5ea2867d4ad08cc2b59a92ce": { "wait_import_platforms": -0.07864109599999836, "config_entry_setup": 20.42540425099999 } }, "data": { "ieee": "**REDACTED**", "nwk": 9290, "manufacturer": "_TZE204_ex3rcdha", "model": "TS0601", "name": "_TZE204_ex3rcdha TS0601", "quirk_applied": true, "quirk_class": "ts0601_radar.TuyaMmwRadarOccupancyVariant1GPP", "quirk_id": null, "manufacturer_code": 4417, "power_source": "Mains", "lqi": 36, "rssi": null, "last_seen": "2024-08-22T10:21:22", "available": true, "device_type": "Router", "signature": { "node_descriptor": { "logical_type": 1, "complex_descriptor_available": 0, "user_descriptor_available": 0, "reserved": 0, "aps_flags": 0, "frequency_band": 8, "mac_capability_flags": 142, "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": "0x0107", "input_clusters": [ "0x0000", "0x0004", "0x0005", "0x000c", "0x000d", "0x0400", "0x0406", "0xef00" ], "output_clusters": [ "0x000a", "0x0019" ] }, "2": { "profile_id": "0x0104", "device_type": "0x0007", "input_clusters": [ "0x000d" ], "output_clusters": [] }, "3": { "profile_id": "0x0104", "device_type": "0x0007", "input_clusters": [ "0x000d" ], "output_clusters": [] }, "4": { "profile_id": "0x0104", "device_type": "0x0007", "input_clusters": [ "0x000d" ], "output_clusters": [] }, "5": { "profile_id": "0x0104", "device_type": "0x0007", "input_clusters": [ "0x000d" ], "output_clusters": [] }, "242": { "profile_id": "0xa1e0", "device_type": "0x0061", "input_clusters": [], "output_clusters": [ "0x0021" ] } }, "manufacturer": "_TZE204_ex3rcdha", "model": "TS0601" }, "active_coordinator": false, "entities": [ { "entity_id": "binary_sensor.zigbee_presence_2_small_occupancy", "name": "_TZE204_ex3rcdha TS0601" }, { "entity_id": "number.zigbee_presence_2_small_number_sensitivity", "name": "_TZE204_ex3rcdha TS0601" }, { "entity_id": "number.zigbee_presence_2_small_number_min_range", "name": "_TZE204_ex3rcdha TS0601" }, { "entity_id": "number.zigbee_presence_2_small_number_max_range", "name": "_TZE204_ex3rcdha TS0601" }, { "entity_id": "number.zigbee_presence_2_small_number_detection_delay", "name": "_TZE204_ex3rcdha TS0601" }, { "entity_id": "number.zigbee_presence_2_small_number_fading_time", "name": "_TZE204_ex3rcdha TS0601" }, { "entity_id": "sensor.zigbee_presence_2_small_illuminance", "name": "_TZE204_ex3rcdha TS0601" }, { "entity_id": "update.zigbee_presence_2_small_firmware", "name": "_TZE204_ex3rcdha TS0601" } ], "neighbors": [ { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Parent", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x1B1F", "permit_joining": "Unknown", "depth": "2", "lqi": "151" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x771B", "permit_joining": "Unknown", "depth": "0", "lqi": "15" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x7A23", "permit_joining": "Unknown", "depth": "0", "lqi": "51" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x4D60", "permit_joining": "Unknown", "depth": "0", "lqi": "69" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x1EE3", "permit_joining": "Unknown", "depth": "0", "lqi": "15" }, { "device_type": "Coordinator", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x0000", "permit_joining": "Unknown", "depth": "0", "lqi": "36" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x242D", "permit_joining": "Unknown", "depth": "0", "lqi": "30" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x46E5", "permit_joining": "Unknown", "depth": "0", "lqi": "0" } ], "routes": [], "endpoint_names": [ { "name": "OCCUPANCY_SENSOR" }, { "name": "COMBINED_INTERFACE" }, { "name": "COMBINED_INTERFACE" }, { "name": "COMBINED_INTERFACE" }, { "name": "COMBINED_INTERFACE" }, { "name": "PROXY_BASIC" } ], "user_given_name": "ZigBee Presence 2 small", "device_reg_id": "6a3b86ff04cd4ccc64ae5027c75088d6", "area_id": null, "cluster_details": { "1": { "device_type": { "name": "OCCUPANCY_SENSOR", "id": 263 }, "profile_id": 260, "in_clusters": { "0x0000": { "endpoint_attribute": "basic", "attributes": { "0x0001": { "attribute_name": "app_version", "value": 74 }, "0x0004": { "attribute_name": "manufacturer", "value": "_TZE204_ex3rcdha" }, "0x0005": { "attribute_name": "model", "value": "TS0601" } }, "unsupported_attributes": {} }, "0x0004": { "endpoint_attribute": "groups", "attributes": {}, "unsupported_attributes": {} }, "0x0005": { "endpoint_attribute": "scenes", "attributes": {}, "unsupported_attributes": {} }, "0xef00": { "endpoint_attribute": "tuya_manufacturer", "attributes": { "0xef00": { "attribute_name": "mcu_version", "value": "1.0.2" } }, "unsupported_attributes": {} }, "0x0400": { "endpoint_attribute": "illuminance", "attributes": {}, "unsupported_attributes": { "0x0000": { "attribute_name": "measured_value" } } }, "0x0406": { "endpoint_attribute": "occupancy", "attributes": {}, "unsupported_attributes": { "0x0000": { "attribute_name": "occupancy" } } }, "0x000c": { "endpoint_attribute": "analog_input", "attributes": { "0x001c": { "attribute_name": "description", "value": "Target distance" }, "0x0075": { "attribute_name": "engineering_units", "value": 31 } }, "unsupported_attributes": {} }, "0x000d": { "endpoint_attribute": "analog_output", "attributes": { "0x001c": { "attribute_name": "description", "value": "Sensitivity" }, "0x0041": { "attribute_name": "max_present_value", "value": 9 }, "0x0045": { "attribute_name": "min_present_value", "value": 1 }, "0x006a": { "attribute_name": "resolution", "value": 1 } }, "unsupported_attributes": {} } }, "out_clusters": { "0x000a": { "endpoint_attribute": "time", "attributes": {}, "unsupported_attributes": {} }, "0x0019": { "endpoint_attribute": "ota", "attributes": { "0x0002": { "attribute_name": "current_file_version", "value": 74 } }, "unsupported_attributes": {} } } }, "2": { "device_type": { "name": "COMBINED_INTERFACE", "id": 7 }, "profile_id": 260, "in_clusters": { "0x000d": { "endpoint_attribute": "analog_output", "attributes": { "0x001c": { "attribute_name": "description", "value": "Min range" }, "0x0075": { "attribute_name": "engineering_units", "value": 118 }, "0x0041": { "attribute_name": "max_present_value", "value": 950 }, "0x0045": { "attribute_name": "min_present_value", "value": 0 }, "0x006a": { "attribute_name": "resolution", "value": 10 } }, "unsupported_attributes": {} } }, "out_clusters": {} }, "3": { "device_type": { "name": "COMBINED_INTERFACE", "id": 7 }, "profile_id": 260, "in_clusters": { "0x000d": { "endpoint_attribute": "analog_output", "attributes": { "0x001c": { "attribute_name": "description", "value": "Max range" }, "0x0075": { "attribute_name": "engineering_units", "value": 118 }, "0x0041": { "attribute_name": "max_present_value", "value": 950 }, "0x0045": { "attribute_name": "min_present_value", "value": 10 }, "0x006a": { "attribute_name": "resolution", "value": 10 } }, "unsupported_attributes": {} } }, "out_clusters": {} }, "4": { "device_type": { "name": "COMBINED_INTERFACE", "id": 7 }, "profile_id": 260, "in_clusters": { "0x000d": { "endpoint_attribute": "analog_output", "attributes": { "0x001c": { "attribute_name": "description", "value": "Detection delay" }, "0x0075": { "attribute_name": "engineering_units", "value": 159 }, "0x0041": { "attribute_name": "max_present_value", "value": 20000 }, "0x0045": { "attribute_name": "min_present_value", "value": 0 }, "0x0055": { "attribute_name": "present_value", "value": 0 }, "0x006a": { "attribute_name": "resolution", "value": 100 } }, "unsupported_attributes": {} } }, "out_clusters": {} }, "5": { "device_type": { "name": "COMBINED_INTERFACE", "id": 7 }, "profile_id": 260, "in_clusters": { "0x000d": { "endpoint_attribute": "analog_output", "attributes": { "0x001c": { "attribute_name": "description", "value": "Fading time" }, "0x0075": { "attribute_name": "engineering_units", "value": 159 }, "0x0041": { "attribute_name": "max_present_value", "value": 200000 }, "0x0045": { "attribute_name": "min_present_value", "value": 2000 }, "0x006a": { "attribute_name": "resolution", "value": 1000 } }, "unsupported_attributes": {} } }, "out_clusters": {} }, "242": { "device_type": { "name": "PROXY_BASIC", "id": 97 }, "profile_id": 41440, "in_clusters": {}, "out_clusters": { "0x0021": { "endpoint_attribute": "green_power", "attributes": {}, "unsupported_attributes": {} } } } } } }

Logs

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

Custom quirk

Custom quirk """Tuya mmw radar occupancy sensor.""" #https://github.com/zigpy/zha-device-handlers/issues/2457 import math from typing import Dict from zigpy.profiles import zgp, zha from zigpy.quirks import CustomDevice import zigpy.types as t from zigpy.zcl.clusters.general import ( AnalogInput, AnalogOutput, Basic, GreenPowerProxy, Groups, Ota, Scenes, Time, ) from zigpy.zcl.clusters.measurement import IlluminanceMeasurement, OccupancySensing from zhaquirks.const import ( DEVICE_TYPE, ENDPOINTS, INPUT_CLUSTERS, MODELS_INFO, OUTPUT_CLUSTERS, PROFILE_ID, ) from zhaquirks.tuya import NoManufacturerCluster, TuyaLocalCluster, TuyaNewManufCluster from zhaquirks.tuya.mcu import ( DPToAttributeMapping, TuyaAttributesCluster, TuyaMCUCluster, ) ZONE_TYPE = 0x0001 class TuyaMmwRadarSelfTest(t.enum8): """Mmw radar self test values.""" TESTING = 0 TEST_SUCCESS = 1 TEST_FAILURE = 2 OTHER = 3 COMM_FAULT = 4 RADAR_FAULT = 5 class TuyaOccupancySensing(OccupancySensing, TuyaLocalCluster): """Tuya local OccupancySensing cluster.""" class TuyaAnalogInput(AnalogInput, TuyaLocalCluster): """Tuya local AnalogInput cluster.""" class TuyaIlluminanceMeasurement(IlluminanceMeasurement, TuyaLocalCluster): """Tuya local IlluminanceMeasurement cluster.""" class TuyaMmwRadarSensitivity(TuyaAttributesCluster, AnalogOutput): """AnalogOutput cluster for sensitivity.""" def __init__(self, *args, **kwargs): """Init.""" super().__init__(*args, **kwargs) self._update_attribute(self.attributes_by_name["description"].id, "Sensitivity") self._update_attribute(self.attributes_by_name["min_present_value"].id, 1) self._update_attribute(self.attributes_by_name["max_present_value"].id, 9) self._update_attribute(self.attributes_by_name["resolution"].id, 1) class TuyaMmwRadarMinRange(TuyaAttributesCluster, AnalogOutput): """AnalogOutput cluster for min range.""" def __init__(self, *args, **kwargs): """Init.""" super().__init__(*args, **kwargs) self._update_attribute(self.attributes_by_name["description"].id, "Min range") self._update_attribute(self.attributes_by_name["min_present_value"].id, 0) self._update_attribute(self.attributes_by_name["max_present_value"].id, 950) self._update_attribute(self.attributes_by_name["resolution"].id, 10) self._update_attribute( self.attributes_by_name["engineering_units"].id, 118 ) # 31: meters class TuyaMmwRadarMaxRange(TuyaAttributesCluster, AnalogOutput): """AnalogOutput cluster for max range.""" def __init__(self, *args, **kwargs): """Init.""" super().__init__(*args, **kwargs) self._update_attribute(self.attributes_by_name["description"].id, "Max range") self._update_attribute(self.attributes_by_name["min_present_value"].id, 10) self._update_attribute(self.attributes_by_name["max_present_value"].id, 950) self._update_attribute(self.attributes_by_name["resolution"].id, 10) self._update_attribute( self.attributes_by_name["engineering_units"].id, 118 ) # 31: meters class TuyaMmwRadarDetectionDelay(TuyaAttributesCluster, AnalogOutput): """AnalogOutput cluster for detection delay.""" def __init__(self, *args, **kwargs): """Init.""" super().__init__(*args, **kwargs) self._update_attribute( self.attributes_by_name["description"].id, "Detection delay" ) self._update_attribute(self.attributes_by_name["min_present_value"].id, 000) self._update_attribute(self.attributes_by_name["max_present_value"].id, 20000) self._update_attribute(self.attributes_by_name["resolution"].id, 100) self._update_attribute( self.attributes_by_name["engineering_units"].id, 159 ) # 73: seconds class TuyaMmwRadarFadingTime(TuyaAttributesCluster, AnalogOutput): """AnalogOutput cluster for fading time.""" def __init__(self, *args, **kwargs): """Init.""" super().__init__(*args, **kwargs) self._update_attribute(self.attributes_by_name["description"].id, "Fading time") self._update_attribute(self.attributes_by_name["min_present_value"].id, 2000) self._update_attribute(self.attributes_by_name["max_present_value"].id, 200000) self._update_attribute(self.attributes_by_name["resolution"].id, 1000) self._update_attribute( self.attributes_by_name["engineering_units"].id, 159 ) # 73: seconds class TuyaMmwRadarTargetDistance(TuyaAttributesCluster, AnalogInput): """AnalogInput cluster for target distance.""" def __init__(self, *args, **kwargs): """Init.""" super().__init__(*args, **kwargs) self._update_attribute( self.attributes_by_name["description"].id, "Target distance" ) self._update_attribute( self.attributes_by_name["engineering_units"].id, 31 ) # 31: meters class TuyaMmwRadarClusterBase(NoManufacturerCluster, TuyaMCUCluster): """Mmw radar cluster, base class.""" attributes = TuyaMCUCluster.attributes.copy() attributes.update( { # ramdom attribute IDs 0xEF01: ("occupancy", t.uint32_t, True), 0xEF02: ("sensitivity", t.uint32_t, True), 0xEF03: ("min_range", t.uint32_t, True), 0xEF04: ("max_range", t.uint32_t, True), 0xEF06: ("self_test", TuyaMmwRadarSelfTest, True), 0xEF09: ("target_distance", t.uint32_t, True), 0xEF65: ("detection_delay", t.uint32_t, True), 0xEF66: ("fading_time", t.uint32_t, True), 0xEF67: ("cli", t.CharacterString, True), 0xEF68: ("illuminance", t.uint32_t, True), } ) class TuyaMmwRadarClusterVariant1(TuyaMmwRadarClusterBase): """Mmw radar cluster, variant 1.""" dp_to_attribute: Dict[int, DPToAttributeMapping] = { 1: DPToAttributeMapping( TuyaOccupancySensing.ep_attribute, "occupancy", ), 2: DPToAttributeMapping( TuyaMmwRadarSensitivity.ep_attribute, "present_value", ), 3: DPToAttributeMapping( TuyaMmwRadarMinRange.ep_attribute, "present_value", endpoint_id=2, ), 4: DPToAttributeMapping( TuyaMmwRadarMaxRange.ep_attribute, "present_value", endpoint_id=3, ), 6: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "self_test", ), 9: DPToAttributeMapping( TuyaMmwRadarTargetDistance.ep_attribute, "present_value", lambda x: x / 100, ), 101: DPToAttributeMapping( TuyaMmwRadarDetectionDelay.ep_attribute, "present_value", converter=lambda x: x * 100, dp_converter=lambda x: x // 100, endpoint_id=4, ), 102: DPToAttributeMapping( TuyaMmwRadarFadingTime.ep_attribute, "present_value", converter=lambda x: x * 100, dp_converter=lambda x: x // 100, endpoint_id=5, ), 103: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "cli", ), 104: DPToAttributeMapping( TuyaIlluminanceMeasurement.ep_attribute, "measured_value", converter=lambda x: int(math.log10(x) * 10000 + 1) if x > 0 else int(0), ), } data_point_handlers = { 1: "_dp_2_attr_update", 2: "_dp_2_attr_update", 3: "_dp_2_attr_update", 4: "_dp_2_attr_update", 6: "_dp_2_attr_update", 9: "_dp_2_attr_update", 101: "_dp_2_attr_update", 102: "_dp_2_attr_update", 103: "_dp_2_attr_update", 104: "_dp_2_attr_update", } class TuyaMmwRadarOccupancyVariant1(CustomDevice): """Millimeter wave occupancy sensor, variant 1.""" signature = { # endpoint=1, profile=260, device_type=81, device_version=1, # input_clusters=[0, 4, 5, 61184], output_clusters=[25, 10] MODELS_INFO: [ ("_TZE200_ar0slwnd", "TS0601"), ("_TZE200_sfiy5tfs", "TS0601"), ("_TZE200_mrf6vtua", "TS0601"), ("_TZE200_ztc6ggyl", "TS0601"), ("_TZE204_ztc6ggyl", "TS0601"), ("_TZE200_wukb7rhc", "TS0601"), ("_TZE204_qasjif9e", "TS0601"), ("_TZE204_dtzziy1e", "TS0601"), ("_TZE204_sbyx0lm6", "TS0601"), ("_TZE204_ex3rcdha", "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, TuyaNewManufCluster.cluster_id, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], }, }, } replacement = { ENDPOINTS: { 1: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, TuyaMmwRadarClusterVariant1, TuyaIlluminanceMeasurement, TuyaOccupancySensing, TuyaMmwRadarTargetDistance, TuyaMmwRadarSensitivity, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], }, 2: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE, INPUT_CLUSTERS: [ TuyaMmwRadarMinRange, ], OUTPUT_CLUSTERS: [], }, 3: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE, INPUT_CLUSTERS: [ TuyaMmwRadarMaxRange, ], OUTPUT_CLUSTERS: [], }, 4: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE, INPUT_CLUSTERS: [ TuyaMmwRadarDetectionDelay, ], OUTPUT_CLUSTERS: [], }, 5: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE, INPUT_CLUSTERS: [ TuyaMmwRadarFadingTime, ], OUTPUT_CLUSTERS: [], }, } } class TuyaMmwRadarOccupancyVariant1GPP(CustomDevice): """Millimeter wave occupancy sensor, variant 1 with GPP.""" signature = { # endpoint=1, profile=260, device_type=81, device_version=1, # input_clusters=[0, 4, 5, 61184], output_clusters=[25, 10]) MODELS_INFO: [ ("_TZE200_ar0slwnd", "TS0601"), ("_TZE200_sfiy5tfs", "TS0601"), ("_TZE200_mrf6vtua", "TS0601"), ("_TZE204_qasjif9e", "TS0601"), ("_TZE204_sbyx0lm6", "TS0601"), ("_TZE204_ex3rcdha", "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, TuyaNewManufCluster.cluster_id, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], }, 242: { # 0 else int(0), ), 105: DPToAttributeMapping( TuyaOccupancySensing.ep_attribute, "occupancy", ), 106: DPToAttributeMapping( TuyaMmwRadarSensitivity.ep_attribute, "present_value", ), 107: DPToAttributeMapping( TuyaMmwRadarMaxRange.ep_attribute, "present_value", endpoint_id=3, ), 108: DPToAttributeMapping( TuyaMmwRadarMinRange.ep_attribute, "present_value", endpoint_id=2, ), 109: DPToAttributeMapping( TuyaMmwRadarTargetDistance.ep_attribute, "present_value", ), 110: DPToAttributeMapping( TuyaMmwRadarFadingTime.ep_attribute, "present_value", converter=lambda x: x * 100, dp_converter=lambda x: x // 100, endpoint_id=5, ), 111: DPToAttributeMapping( TuyaMmwRadarDetectionDelay.ep_attribute, "present_value", converter=lambda x: x * 100, dp_converter=lambda x: x // 100, endpoint_id=4, ), } data_point_handlers = { 103: "_dp_2_attr_update", 104: "_dp_2_attr_update", 105: "_dp_2_attr_update", 106: "_dp_2_attr_update", 107: "_dp_2_attr_update", 108: "_dp_2_attr_update", 109: "_dp_2_attr_update", 110: "_dp_2_attr_update", 111: "_dp_2_attr_update", } class TuyaMmwRadarOccupancyVariant2(CustomDevice): """Millimeter wave occupancy sensor, variant 2.""" signature = { # endpoint=1, profile=260, device_type=81, device_version=1, # input_clusters=[0, 4, 5, 61184], output_clusters=[25, 10]) MODELS_INFO: [ ("_TZE204_sxm7l9xa", "TS0601"), ("_TZE204_bmdsp6bs", "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, TuyaNewManufCluster.cluster_id, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], }, 242: { #

Additional information

No response

dermaxxx213 commented 3 weeks ago

Sorry for my question, but works the sensor with this quirk? must i copy the hole code or only a part? i try both, but it didnt work.

agf102 commented 2 weeks ago

Sorry for my question, but works the sensor with this quirk? must i copy the hole code or only a part? i try both, but it didnt work.

Using the whole quirk included in this post I was able to get partial functionality but the illuminance and occupancy sensors don't work and I can't therefore test whether the controls are working either

fabianteunissen commented 1 week ago

Do you know what datapoints it uses?

https://github.com/Koenkk/zigbee2mqtt/issues/23705#issuecomment-2331261450?

lajoshanko commented 6 days ago

Seems to be the z2mqtt version is working, maybe it can speed up the zha support too: https://github.com/Koenkk/zigbee2mqtt/issues/23705#issuecomment-2344137902