various incl zha quirks
This commit is contained in:
361
custom_zha_quirks/ts0601_motion.py
Normal file
361
custom_zha_quirks/ts0601_motion.py
Normal file
@@ -0,0 +1,361 @@
|
||||
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 (1 is higher, 9 is lower)
|
||||
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",
|
||||
# Value in Tuya App is 30 after Factory reset
|
||||
#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.illuminance_lux.name,
|
||||
HumanPresenceSensorManufCluster.cluster_id,
|
||||
step=1,
|
||||
min_value=0,
|
||||
max_value=2500,
|
||||
fallback_name="Illuminance (lx)",
|
||||
translation_key="illuminance_lux",
|
||||
#entity_type=EntityType.STANDARD # not yet :/
|
||||
)
|
||||
.number(
|
||||
HumanPresenceSensorManufCluster.AttributeDefs.target_distance.name,
|
||||
HumanPresenceSensorManufCluster.cluster_id,
|
||||
step=0.01,
|
||||
min_value=0,
|
||||
max_value=10,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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()
|
||||
)
|
Reference in New Issue
Block a user