Je suis tombé sur un quirk (zha quirk v2) qui avait l'air de fonctionner pour quelques personnes pour un module mmwave.
J'ai donné le code source à Claude (AI) je lui ai demander d'adapter le code avec la configuration de zigbee2mqtt qui lui prenait déjà en compte ce capteur. Claude m'a renvoyé le résultat qui fonctionnait out of the box pour la moitié des capteurs/configs ! J'ai rajouté le reste.
Donc merci à
- Claude AI https://claude.ai/new
- Vinzent https://gist.github.com/vinzent/2cd645b848fd3b6a0c3e5762956ec89f
- Et au projet Koenkk/zigbee-herdsman-converters https://github.com/Koenkk/zigbee-herdsman-converters/blob/9ede78a950d703dac4e60271e08dabf7808661e6/src/devices/tuya.ts#L10736
Je vous le partage ici (lire ici pour ajouter un quirk qui est un script python pour supporter un capteur https://www.home-assistant.io/integrations/zha#how-to-add-support-for-new-and-unsupported-devices) :
J'ai donné le code source à Claude (AI) je lui ai demander d'adapter le code avec la configuration de zigbee2mqtt qui lui prenait déjà en compte ce capteur. Claude m'a renvoyé le résultat qui fonctionnait out of the box pour la moitié des capteurs/configs ! J'ai rajouté le reste.
Donc merci à
- Claude AI https://claude.ai/new
- Vinzent https://gist.github.com/vinzent/2cd645b848fd3b6a0c3e5762956ec89f
- Et au projet Koenkk/zigbee-herdsman-converters https://github.com/Koenkk/zigbee-herdsman-converters/blob/9ede78a950d703dac4e60271e08dabf7808661e6/src/devices/tuya.ts#L10736
Je vous le partage ici (lire ici pour ajouter un quirk qui est un script python pour supporter un capteur https://www.home-assistant.io/integrations/zha#how-to-add-support-for-new-and-unsupported-devices) :
# rivsc https://blog.rivsc.ovh import logging from typing import Final from zigpy.quirks.v2 import QuirkBuilder, BinarySensorDeviceClass import zigpy.types as t from zigpy.zcl.foundation import ZCLAttributeDef from zigpy.zcl.clusters.measurement import ( IlluminanceMeasurement, OccupancySensing, ) from zigpy.zcl.clusters.security import IasZone from zigpy.quirks.v2.homeassistant import EntityPlatform, EntityType from zhaquirks.tuya import ( TuyaLocalCluster, TuyaPowerConfigurationCluster2AAA, ) from zhaquirks.tuya.mcu import TuyaMCUCluster, DPToAttributeMapping class PresenceState(t.enum8): """Presence State values""" none = 0x00 presence = 0x01 peaceful = 0x02 small_movement = 0x03 large_movement = 0x04 class TuyaOccupancySensing(OccupancySensing, TuyaLocalCluster): """Tuya local OccupancySensing cluster.""" class TuyaIlluminanceMeasurement(IlluminanceMeasurement, TuyaLocalCluster): """Tuya local IlluminanceMeasurement cluster.""" class HumanPresenceSensorManufCluster(TuyaMCUCluster): """Human Presence Sensor ZG-205Z (5.8GHz)""" class AttributeDefs(TuyaMCUCluster.AttributeDefs): """Tuya DataPoints attributes""" # Presence state presence_state: Final = ZCLAttributeDef( id=0x0001, # DP 1 type=t.uint16_t, access="rp", is_manufacturer_specific=True, ) # Target distance target_distance: Final = ZCLAttributeDef( id=0x0101, # DP 101 type=t.uint16_t, access="rp", is_manufacturer_specific=True, ) # Illuminance value illuminance_lux: Final = ZCLAttributeDef( id=0x0102, # DP 102 type=t.uint16_t, access="rp", is_manufacturer_specific=True, ) # None delay time (presence keep time) none_delay_time: Final = ZCLAttributeDef( id=0x0103, # DP 103 type=t.uint16_t, is_manufacturer_specific=True, ) # Indicator indicator: Final = ZCLAttributeDef( id=0x0104, # DP 104 type=t.Bool, is_manufacturer_specific=True, ) # Move detection max distance move_detection_max: Final = ZCLAttributeDef( id=0x0107, # DP 107 type=t.uint16_t, is_manufacturer_specific=True, ) # Move detection min distance move_detection_min: Final = ZCLAttributeDef( id=0x0108, # DP 108 type=t.uint16_t, is_manufacturer_specific=True, ) # Breath detection max distance breath_detection_max: Final = ZCLAttributeDef( id=0x0109, # DP 109 type=t.uint16_t, is_manufacturer_specific=True, ) # Breath detection min distance breath_detection_min: Final = ZCLAttributeDef( id=0x0110, # DP 110 type=t.uint16_t, is_manufacturer_specific=True, ) # Small move detection max distance small_move_detection_max: Final = ZCLAttributeDef( id=0x0114, # DP 114 type=t.uint16_t, is_manufacturer_specific=True, ) # Small move detection min distance small_move_detection_min: Final = ZCLAttributeDef( id=0x0115, # DP 115 type=t.uint16_t, is_manufacturer_specific=True, ) # Move sensitivity move_sensitivity: Final = ZCLAttributeDef( id=0x0116, # DP 116 type=t.uint8_t, is_manufacturer_specific=True, ) # Small move sensitivity small_move_sensitivity: Final = ZCLAttributeDef( id=0x0117, # DP 117 type=t.uint8_t, is_manufacturer_specific=True, ) # Breath sensitivity breath_sensitivity: Final = ZCLAttributeDef( id=0x0118, # DP 118 type=t.uint8_t, is_manufacturer_specific=True, ) dp_to_attribute: dict[int, DPToAttributeMapping] = { 1: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "presence_state", converter=PresenceState ), 101: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "target_distance", converter=lambda x: x / 100 if x is not None else 0 ), 102: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "illuminance_lux", ), 103: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "none_delay_time", converter=lambda x: x if x is not None else 30 ), 104: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "indicator", ), 107: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "move_detection_max", converter=lambda x: x / 100 if x is not None else 10 ), 108: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "move_detection_min", converter=lambda x: x / 100 if x is not None else 0 ), 109: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "breath_detection_max", converter=lambda x: x / 100 if x is not None else 6 ), 110: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "breath_detection_min", converter=lambda x: x / 100 if x is not None else 0 ), 114: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "small_move_detection_max", converter=lambda x: x / 100 if x is not None else 6 ), 115: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "small_move_detection_min", converter=lambda x: x / 100 if x is not None else 0 ), 116: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "move_sensitivity", converter=lambda x: x if x is not None else 5 ), 117: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "small_move_sensitivity", converter=lambda x: x if x is not None else 5 ), 118: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "breath_sensitivity", converter=lambda x: x if x is not None else 5 ), } data_point_handlers = { 1: "_dp_2_attr_update", 101: "_dp_2_attr_update", 102: "_dp_2_attr_update", 103: "_dp_2_attr_update", 104: "_dp_2_attr_update", 107: "_dp_2_attr_update", 108: "_dp_2_attr_update", 109: "_dp_2_attr_update", 110: "_dp_2_attr_update", 114: "_dp_2_attr_update", 115: "_dp_2_attr_update", 116: "_dp_2_attr_update", 117: "_dp_2_attr_update", 118: "_dp_2_attr_update", } ( QuirkBuilder("_TZE204_dapwryy7", "TS0601") .skip_configuration() .removes(IasZone.cluster_id) .adds(HumanPresenceSensorManufCluster) #.adds(TuyaOccupancySensing) .replaces(TuyaPowerConfigurationCluster2AAA) .replaces(TuyaIlluminanceMeasurement) .binary_sensor( "presence_state", HumanPresenceSensorManufCluster.cluster_id, endpoint_id=1, #entity_type=EntityType.STANDARD, # very soon (zigpy channel #dev on github device_class=BinarySensorDeviceClass.OCCUPANCY, fallback_name="Presence" ) .enum( HumanPresenceSensorManufCluster.AttributeDefs.presence_state.name, PresenceState, HumanPresenceSensorManufCluster.cluster_id, entity_platform=EntityPlatform.SENSOR, entity_type=EntityType.STANDARD, fallback_name="Presence State", translation_key="presence_state" ) .number( HumanPresenceSensorManufCluster.AttributeDefs.target_distance.name, HumanPresenceSensorManufCluster.cluster_id, step=0.01, min_value=0, max_value=10, #unit="m", # fail :/ fallback_name="Target Distance (m)", translation_key="target_distance", #entity_type=EntityType.STANDARD # not yet :/ ) .number( HumanPresenceSensorManufCluster.AttributeDefs.none_delay_time.name, HumanPresenceSensorManufCluster.cluster_id, step=1, min_value=0, max_value=28800, unit="s", fallback_name="Hold Delay Time", translation_key="none_delay_time" ) .switch( HumanPresenceSensorManufCluster.AttributeDefs.indicator.name, HumanPresenceSensorManufCluster.cluster_id, fallback_name="LED Indicator", translation_key="indicator" ) .number( HumanPresenceSensorManufCluster.AttributeDefs.move_detection_max.name, HumanPresenceSensorManufCluster.cluster_id, step=0.01, min_value=0, max_value=10, #unit="m", fallback_name="Move Detection Max Distance (m)", translation_key="move_detection_max" ) .number( HumanPresenceSensorManufCluster.AttributeDefs.move_detection_min.name, HumanPresenceSensorManufCluster.cluster_id, step=0.01, min_value=0, max_value=10, #unit="m", fallback_name="Move Detection Min Distance (m)", translation_key="move_detection_min" ) .number( HumanPresenceSensorManufCluster.AttributeDefs.small_move_detection_max.name, HumanPresenceSensorManufCluster.cluster_id, step=0.01, min_value=0, max_value=6, #unit="m", fallback_name="Small Move Detection Max Distance (m)", translation_key="small_move_detection_max" ) .number( HumanPresenceSensorManufCluster.AttributeDefs.small_move_detection_min.name, HumanPresenceSensorManufCluster.cluster_id, step=0.01, min_value=0, max_value=6, #unit="m", fallback_name="Small Move Detection Min Distance (m)", translation_key="small_move_detection_min" ) .number( HumanPresenceSensorManufCluster.AttributeDefs.breath_detection_max.name, HumanPresenceSensorManufCluster.cluster_id, step=0.01, min_value=0, max_value=6, #unit="m", fallback_name="Breath Detection Max Distance (m)", translation_key="breath_detection_max" ) .number( HumanPresenceSensorManufCluster.AttributeDefs.breath_detection_min.name, HumanPresenceSensorManufCluster.cluster_id, step=0.01, min_value=0, max_value=6, #unit="m", fallback_name="Breath Detection Min Distance (m)", translation_key="breath_detection_min" ) .number( HumanPresenceSensorManufCluster.AttributeDefs.move_sensitivity.name, HumanPresenceSensorManufCluster.cluster_id, step=1, min_value=0, max_value=10, fallback_name="Move Sensitivity", translation_key="move_sensitivity" ) .number( HumanPresenceSensorManufCluster.AttributeDefs.small_move_sensitivity.name, HumanPresenceSensorManufCluster.cluster_id, step=1, min_value=0, max_value=10, fallback_name="Small Move Sensitivity", translation_key="small_move_sensitivity" ) .number( HumanPresenceSensorManufCluster.AttributeDefs.breath_sensitivity.name, HumanPresenceSensorManufCluster.cluster_id, step=1, min_value=0, max_value=10, fallback_name="Breath Sensitivity", translation_key="breath_sensitivity" ) .add_to_registry() )