various tidyups
This commit is contained in:
@@ -1,137 +0,0 @@
|
||||
"""Quirk for TS0207 rain sensors."""
|
||||
|
||||
import zigpy.types as t
|
||||
from typing import Any, Type
|
||||
from zigpy.profiles import zha
|
||||
from zigpy.quirks import CustomDevice, CustomCluster
|
||||
from zigpy.zcl.clusters.general import (
|
||||
Basic,
|
||||
Groups,
|
||||
Identify,
|
||||
OnOff,
|
||||
Ota,
|
||||
PowerConfiguration,
|
||||
Scenes,
|
||||
Time,
|
||||
)
|
||||
from zigpy.zcl.clusters.lightlink import LightLink
|
||||
from zigpy.zcl.clusters.security import IasZone
|
||||
from zhaquirks.const import (
|
||||
DEVICE_TYPE,
|
||||
ENDPOINTS,
|
||||
INPUT_CLUSTERS,
|
||||
MODELS_INFO,
|
||||
OUTPUT_CLUSTERS,
|
||||
PROFILE_ID,
|
||||
)
|
||||
from zhaquirks.tuya.mcu import TuyaMCUCluster
|
||||
from zhaquirks.tuya import (
|
||||
TuyaManufCluster,
|
||||
DPToAttributeMapping,
|
||||
EnchantedDevice,
|
||||
TuyaNoBindPowerConfigurationCluster,
|
||||
)
|
||||
|
||||
ZONE_TYPE = 0x0001
|
||||
|
||||
class TuyaSolarRainSensorCluster(TuyaMCUCluster):
|
||||
"""Tuya manufacturer cluster."""
|
||||
|
||||
attributes = TuyaMCUCluster.attributes.copy()
|
||||
attributes.update(
|
||||
{
|
||||
0xEF65: ("light_intensity", t.uint32_t, True),
|
||||
0xEF66: ("average_light_intensity_20mins", t.uint32_t, True),
|
||||
0xEF67: ("todays_max_light_intensity", t.uint32_t, True),
|
||||
0xEF68: ("cleaning_reminder", t.Bool, True),
|
||||
0xEF69: ("rain_sensor_voltage", t.uint32_t, True),
|
||||
}
|
||||
)
|
||||
|
||||
dp_to_attribute: dict[int, DPToAttributeMapping] = {
|
||||
101: DPToAttributeMapping(
|
||||
TuyaMCUCluster.ep_attribute,
|
||||
"light_intensity",
|
||||
),
|
||||
102: DPToAttributeMapping(
|
||||
TuyaMCUCluster.ep_attribute,
|
||||
"average_light_intensity_20mins",
|
||||
),
|
||||
103: DPToAttributeMapping(
|
||||
TuyaMCUCluster.ep_attribute,
|
||||
"todays_max_light_intensity",
|
||||
),
|
||||
104: DPToAttributeMapping(
|
||||
TuyaMCUCluster.ep_attribute,
|
||||
"cleaning_reminder",
|
||||
),
|
||||
105: DPToAttributeMapping(
|
||||
TuyaMCUCluster.ep_attribute,
|
||||
"rain_sensor_voltage",
|
||||
),
|
||||
}
|
||||
|
||||
data_point_handlers = {
|
||||
101: "_dp_2_attr_update",
|
||||
102: "_dp_2_attr_update",
|
||||
103: "_dp_2_attr_update",
|
||||
104: "_dp_2_attr_update",
|
||||
105: "_dp_2_attr_update",
|
||||
}
|
||||
|
||||
|
||||
class TuyaIasZone(CustomCluster, IasZone):
|
||||
"""IAS Zone for rain sensors."""
|
||||
|
||||
_CONSTANT_ATTRIBUTES = {ZONE_TYPE: IasZone.ZoneType.Water_Sensor}
|
||||
|
||||
|
||||
class TuyaSolarRainSensor(EnchantedDevice):
|
||||
"""TS0207 Rain sensor quirk."""
|
||||
|
||||
signature = {
|
||||
MODELS_INFO: [("_TZ3210_tgvtvdoc", "TS0207")],
|
||||
ENDPOINTS: {
|
||||
1: {
|
||||
PROFILE_ID: zha.PROFILE_ID,
|
||||
DEVICE_TYPE: zha.DeviceType.IAS_ZONE,
|
||||
INPUT_CLUSTERS: [
|
||||
Basic.cluster_id,
|
||||
PowerConfiguration.cluster_id,
|
||||
Groups.cluster_id,
|
||||
Scenes.cluster_id,
|
||||
IasZone.cluster_id,
|
||||
TuyaMCUCluster.cluster_id,
|
||||
],
|
||||
OUTPUT_CLUSTERS: [
|
||||
Identify.cluster_id,
|
||||
Groups.cluster_id,
|
||||
OnOff.cluster_id,
|
||||
Time.cluster_id,
|
||||
Ota.cluster_id,
|
||||
LightLink.cluster_id,
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
replacement = {
|
||||
ENDPOINTS: {
|
||||
1: {
|
||||
PROFILE_ID: zha.PROFILE_ID,
|
||||
DEVICE_TYPE: zha.DeviceType.IAS_ZONE,
|
||||
INPUT_CLUSTERS: [
|
||||
Basic.cluster_id,
|
||||
Groups.cluster_id,
|
||||
Scenes.cluster_id,
|
||||
TuyaNoBindPowerConfigurationCluster,
|
||||
TuyaIasZone,
|
||||
TuyaSolarRainSensorCluster,
|
||||
],
|
||||
OUTPUT_CLUSTERS: [
|
||||
Time.cluster_id,
|
||||
Ota.cluster_id,
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,358 +0,0 @@
|
||||
# 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()
|
||||
)
|
||||
@@ -1,293 +0,0 @@
|
||||
"""Tuya Din Power Meter."""
|
||||
|
||||
from zigpy.profiles import zha
|
||||
import zigpy.types as t
|
||||
from zigpy.zcl.clusters.general import Basic, Groups, Ota, Scenes, Time
|
||||
from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement
|
||||
from zigpy.zcl.clusters.smartenergy import Metering
|
||||
|
||||
from zhaquirks import Bus, LocalDataCluster
|
||||
from zhaquirks.const import (
|
||||
DEVICE_TYPE,
|
||||
ENDPOINTS,
|
||||
INPUT_CLUSTERS,
|
||||
MODELS_INFO,
|
||||
OUTPUT_CLUSTERS,
|
||||
PROFILE_ID,
|
||||
)
|
||||
from zhaquirks.tuya import TuyaManufClusterAttributes, TuyaOnOff, TuyaSwitch
|
||||
|
||||
TUYA_TOTAL_ENERGY_ATTR = 0x0211
|
||||
TUYA_CURRENT_ATTR = 0x0212
|
||||
TUYA_POWER_ATTR = 0x0213
|
||||
TUYA_VOLTAGE_ATTR = 0x0214
|
||||
TUYA_DIN_SWITCH_ATTR = 0x0101
|
||||
|
||||
SWITCH_EVENT = "switch_event"
|
||||
|
||||
"""Hiking Power Meter Attributes"""
|
||||
HIKING_DIN_SWITCH_ATTR = 0x0110
|
||||
HIKING_TOTAL_ENERGY_DELIVERED_ATTR = 0x0201
|
||||
HIKING_TOTAL_ENERGY_RECEIVED_ATTR = 0x0266
|
||||
HIKING_VOLTAGE_CURRENT_ATTR = 0x0006
|
||||
HIKING_POWER_ATTR = 0x0267
|
||||
HIKING_FREQUENCY_ATTR = 0x0269
|
||||
HIKING_POWER_FACTOR_ATTR = 0x026F
|
||||
HIKING_TOTAL_REACTIVE_ATTR = 0x026D
|
||||
HIKING_REACTIVE_POWER_ATTR = 0x026E
|
||||
|
||||
|
||||
class TuyaManufClusterDinPower(TuyaManufClusterAttributes):
|
||||
"""Manufacturer Specific Cluster of the Tuya Power Meter device."""
|
||||
|
||||
attributes = {
|
||||
TUYA_TOTAL_ENERGY_ATTR: ("energy", t.uint32_t, True),
|
||||
TUYA_CURRENT_ATTR: ("current", t.int16s, True),
|
||||
TUYA_POWER_ATTR: ("power", t.uint16_t, True),
|
||||
TUYA_VOLTAGE_ATTR: ("voltage", t.uint16_t, True),
|
||||
TUYA_DIN_SWITCH_ATTR: ("switch", t.uint8_t, True),
|
||||
}
|
||||
|
||||
def _update_attribute(self, attrid, value):
|
||||
super()._update_attribute(attrid, value)
|
||||
if attrid == TUYA_TOTAL_ENERGY_ATTR:
|
||||
self.endpoint.smartenergy_metering.energy_deliver_reported(value / 100)
|
||||
elif attrid == TUYA_CURRENT_ATTR:
|
||||
self.endpoint.electrical_measurement.current_reported(value)
|
||||
elif attrid == TUYA_POWER_ATTR:
|
||||
self.endpoint.electrical_measurement.power_reported(value / 10)
|
||||
elif attrid == TUYA_VOLTAGE_ATTR:
|
||||
self.endpoint.electrical_measurement.voltage_reported(value / 10)
|
||||
elif attrid == TUYA_DIN_SWITCH_ATTR:
|
||||
self.endpoint.device.switch_bus.listener_event(
|
||||
SWITCH_EVENT, self.endpoint.endpoint_id, value
|
||||
)
|
||||
|
||||
|
||||
class TuyaPowerMeasurement(LocalDataCluster, ElectricalMeasurement):
|
||||
"""Custom class for power, voltage and current measurement."""
|
||||
|
||||
POWER_ID = 0x050B
|
||||
VOLTAGE_ID = 0x0505
|
||||
CURRENT_ID = 0x0508
|
||||
REACTIVE_POWER_ID = 0x050E
|
||||
AC_FREQUENCY_ID = 0x0300
|
||||
TOTAL_REACTIVE_POWER_ID = 0x0305
|
||||
POWER_FACTOR_ID = 0x0510
|
||||
|
||||
AC_CURRENT_MULTIPLIER = 0x0602
|
||||
AC_CURRENT_DIVISOR = 0x0603
|
||||
AC_FREQUENCY_MULTIPLIER = 0x0400
|
||||
AC_FREQUENCY_DIVISOR = 0x0401
|
||||
|
||||
_CONSTANT_ATTRIBUTES = {
|
||||
AC_CURRENT_MULTIPLIER: 1,
|
||||
AC_CURRENT_DIVISOR: 1000,
|
||||
AC_FREQUENCY_MULTIPLIER: 1,
|
||||
AC_FREQUENCY_DIVISOR: 100,
|
||||
}
|
||||
|
||||
def voltage_reported(self, value):
|
||||
"""Voltage reported."""
|
||||
self._update_attribute(self.VOLTAGE_ID, value)
|
||||
|
||||
def power_reported(self, value):
|
||||
"""Power reported."""
|
||||
self._update_attribute(self.POWER_ID, value)
|
||||
|
||||
def power_factor_reported(self, value):
|
||||
"""Power Factor reported."""
|
||||
self._update_attribute(self.POWER_FACTOR_ID, value)
|
||||
|
||||
def reactive_power_reported(self, value):
|
||||
"""Reactive Power reported."""
|
||||
self._update_attribute(self.REACTIVE_POWER_ID, value)
|
||||
|
||||
def current_reported(self, value):
|
||||
"""Ampers reported."""
|
||||
self._update_attribute(self.CURRENT_ID, value)
|
||||
|
||||
def frequency_reported(self, value):
|
||||
"""AC Frequency reported."""
|
||||
self._update_attribute(self.AC_FREQUENCY_ID, value)
|
||||
|
||||
def reactive_energy_reported(self, value):
|
||||
"""Summation Reactive Energy reported."""
|
||||
self._update_attribute(self.TOTAL_REACTIVE_POWER_ID, value)
|
||||
|
||||
|
||||
class TuyaElectricalMeasurement(LocalDataCluster, Metering):
|
||||
"""Custom class for total energy measurement."""
|
||||
|
||||
CURRENT_DELIVERED_ID = 0x0000
|
||||
CURRENT_RECEIVED_ID = 0x0001
|
||||
POWER_WATT = 0x0000
|
||||
|
||||
"""Setting unit of measurement."""
|
||||
_CONSTANT_ATTRIBUTES = {0x0300: POWER_WATT}
|
||||
|
||||
def energy_deliver_reported(self, value):
|
||||
"""Summation Energy Deliver reported."""
|
||||
self._update_attribute(self.CURRENT_DELIVERED_ID, value)
|
||||
|
||||
def energy_receive_reported(self, value):
|
||||
"""Summation Energy Receive reported."""
|
||||
self._update_attribute(self.CURRENT_RECEIVED_ID, value)
|
||||
|
||||
|
||||
class HikingManufClusterDinPower(TuyaManufClusterAttributes):
|
||||
"""Manufacturer Specific Cluster of the Hiking Power Meter device."""
|
||||
|
||||
attributes = {
|
||||
HIKING_DIN_SWITCH_ATTR: ("switch", t.uint8_t, True),
|
||||
HIKING_TOTAL_ENERGY_DELIVERED_ATTR: ("energy_delivered", t.uint32_t, True),
|
||||
HIKING_TOTAL_ENERGY_RECEIVED_ATTR: ("energy_received", t.uint16_t, True),
|
||||
HIKING_VOLTAGE_CURRENT_ATTR: ("voltage_current", t.uint32_t, True),
|
||||
HIKING_POWER_ATTR: ("power", t.uint16_t, True),
|
||||
HIKING_FREQUENCY_ATTR: ("frequency", t.uint16_t, True),
|
||||
HIKING_TOTAL_REACTIVE_ATTR: ("total_reactive_energy", t.int32s, True),
|
||||
HIKING_REACTIVE_POWER_ATTR: ("reactive_power", t.int16s, True),
|
||||
HIKING_POWER_FACTOR_ATTR: ("power_factor", t.uint16_t, True),
|
||||
}
|
||||
|
||||
def _update_attribute(self, attrid, value):
|
||||
super()._update_attribute(attrid, value)
|
||||
if attrid == HIKING_DIN_SWITCH_ATTR:
|
||||
self.endpoint.device.switch_bus.listener_event(SWITCH_EVENT, 16, value)
|
||||
elif attrid == HIKING_TOTAL_ENERGY_DELIVERED_ATTR:
|
||||
self.endpoint.smartenergy_metering.energy_deliver_reported(value / 100)
|
||||
elif attrid == HIKING_TOTAL_ENERGY_RECEIVED_ATTR:
|
||||
self.endpoint.smartenergy_metering.energy_receive_reported(value / 100)
|
||||
elif attrid == HIKING_VOLTAGE_CURRENT_ATTR:
|
||||
self.endpoint.electrical_measurement.current_reported(value >> 16)
|
||||
self.endpoint.electrical_measurement.voltage_reported(
|
||||
(value & 0x0000FFFF) / 10
|
||||
)
|
||||
elif attrid == HIKING_POWER_ATTR:
|
||||
self.endpoint.electrical_measurement.power_reported(value)
|
||||
elif attrid == HIKING_FREQUENCY_ATTR:
|
||||
self.endpoint.electrical_measurement.frequency_reported(value)
|
||||
elif attrid == HIKING_TOTAL_REACTIVE_ATTR:
|
||||
self.endpoint.electrical_measurement.reactive_energy_reported(value)
|
||||
elif attrid == HIKING_REACTIVE_POWER_ATTR:
|
||||
self.endpoint.electrical_measurement.reactive_power_reported(value)
|
||||
elif attrid == HIKING_POWER_FACTOR_ATTR:
|
||||
self.endpoint.electrical_measurement.power_factor_reported(value / 10)
|
||||
|
||||
|
||||
class TuyaPowerMeter(TuyaSwitch):
|
||||
"""Tuya power meter device."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Init device."""
|
||||
self.switch_bus = Bus()
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
signature = {
|
||||
# "node_descriptor": "<NodeDescriptor byte1=1 byte2=64 mac_capability_flags=142 manufacturer_code=4098
|
||||
# maximum_buffer_size=82 maximum_incoming_transfer_size=82 server_mask=11264
|
||||
# maximum_outgoing_transfer_size=82 descriptor_capability_field=0>",
|
||||
# device_version=1
|
||||
# input_clusters=[0x0000, 0x0004, 0x0005, 0xef00]
|
||||
# output_clusters=[0x000a, 0x0019]
|
||||
MODELS_INFO: [
|
||||
("_TZE200_byzdayie", "TS0601"),
|
||||
("_TZE200_ewxhg6o9", "TS0601"),
|
||||
],
|
||||
ENDPOINTS: {
|
||||
# <SimpleDescriptor endpoint=1 profile=260 device_type=51
|
||||
# device_version=1
|
||||
# input_clusters=[0, 4, 5, 61184]
|
||||
# output_clusters=[10, 25]>
|
||||
1: {
|
||||
PROFILE_ID: zha.PROFILE_ID,
|
||||
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
|
||||
INPUT_CLUSTERS: [
|
||||
Basic.cluster_id,
|
||||
Groups.cluster_id,
|
||||
Scenes.cluster_id,
|
||||
TuyaManufClusterAttributes.cluster_id,
|
||||
],
|
||||
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
replacement = {
|
||||
ENDPOINTS: {
|
||||
1: {
|
||||
PROFILE_ID: zha.PROFILE_ID,
|
||||
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
|
||||
INPUT_CLUSTERS: [
|
||||
Basic.cluster_id,
|
||||
Groups.cluster_id,
|
||||
Scenes.cluster_id,
|
||||
TuyaManufClusterDinPower,
|
||||
TuyaPowerMeasurement,
|
||||
TuyaElectricalMeasurement,
|
||||
TuyaOnOff,
|
||||
],
|
||||
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class HikingPowerMeter(TuyaSwitch):
|
||||
"""Hiking Power Meter Device - DDS238-2."""
|
||||
|
||||
signature = {
|
||||
# "node_descriptor": "<NodeDescriptor byte1=1 byte2=64 mac_capability_flags=142 manufacturer_code=4098
|
||||
# maximum_buffer_size=82 maximum_incoming_transfer_size=82 server_mask=11264
|
||||
# maximum_outgoing_transfer_size=82 descriptor_capability_field=0>",
|
||||
# device_version=1
|
||||
# input_clusters=[0x0000, 0x0004, 0x0005, 0xef00]
|
||||
# output_clusters=[0x000a, 0x0019]
|
||||
MODELS_INFO: [
|
||||
("_TZE200_bkkmqmyo", "TS0601"),
|
||||
("_TZE204_81yrt3lo", "TS0601"),
|
||||
],
|
||||
ENDPOINTS: {
|
||||
# <SimpleDescriptor endpoint=1 profile=260 device_type=51
|
||||
# device_version=1
|
||||
# input_clusters=[0, 4, 5, 61184]
|
||||
# output_clusters=[10, 25]>
|
||||
1: {
|
||||
PROFILE_ID: zha.PROFILE_ID,
|
||||
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
|
||||
INPUT_CLUSTERS: [
|
||||
Basic.cluster_id,
|
||||
Groups.cluster_id,
|
||||
Scenes.cluster_id,
|
||||
TuyaManufClusterAttributes.cluster_id,
|
||||
],
|
||||
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
replacement = {
|
||||
ENDPOINTS: {
|
||||
1: {
|
||||
PROFILE_ID: zha.PROFILE_ID,
|
||||
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
|
||||
INPUT_CLUSTERS: [
|
||||
Basic.cluster_id,
|
||||
Groups.cluster_id,
|
||||
Scenes.cluster_id,
|
||||
HikingManufClusterDinPower,
|
||||
TuyaElectricalMeasurement,
|
||||
TuyaPowerMeasurement,
|
||||
],
|
||||
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
|
||||
},
|
||||
16: {
|
||||
PROFILE_ID: zha.PROFILE_ID,
|
||||
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
|
||||
INPUT_CLUSTERS: [
|
||||
TuyaOnOff,
|
||||
],
|
||||
OUTPUT_CLUSTERS: [],
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
"""
|
||||
DY-YG400A Smoke Sensor, TS0601 from _TZE204_ntcy3xu1
|
||||
https://www.aliexpress.com/item/1005005863519099.html
|
||||
https://www.aliexpress.com/item/1005005854203557.html
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
import zigpy.profiles.zha
|
||||
from zigpy.quirks import CustomDevice
|
||||
import zigpy.types as t
|
||||
from zigpy.zcl.clusters.general import (
|
||||
Basic,
|
||||
Groups,
|
||||
Ota,
|
||||
Scenes,
|
||||
Time,
|
||||
BinaryInput,
|
||||
BatterySize,
|
||||
)
|
||||
from zigpy.zcl.clusters.security import IasZone
|
||||
from zhaquirks import Bus
|
||||
from zhaquirks.const import (
|
||||
DEVICE_TYPE,
|
||||
ENDPOINTS,
|
||||
INPUT_CLUSTERS,
|
||||
MODELS_INFO,
|
||||
OUTPUT_CLUSTERS,
|
||||
PROFILE_ID,
|
||||
ZONE_TYPE,
|
||||
)
|
||||
from zhaquirks.tuya import (
|
||||
TuyaLocalCluster,
|
||||
TuyaManufCluster,
|
||||
TuyaManufClusterAttributes,
|
||||
TuyaPowerConfigurationCluster,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
TUYA_SMOKE_DETECTED_ATTR = 0x0401 # [0]/[1] [Detected]/[Clear]!
|
||||
TUYA_SMOKE_TAMPERED_ATTR = 0x0104 # [0]/[1] [Clear]/[Tampered]!
|
||||
TUYA_SMOKE_BATTERY_ATTR = 0x040e # [0]/[1]/[2] [Low]/[Med]]/[Full]!
|
||||
|
||||
|
||||
class TuyaSmokeDetectorCluster(TuyaManufClusterAttributes):
|
||||
"""Manufacturer Specific Cluster of the TS0601 smoke detector."""
|
||||
|
||||
attributes = {
|
||||
TUYA_SMOKE_DETECTED_ATTR: ("smoke_detected", t.uint8_t, True),
|
||||
TUYA_SMOKE_TAMPERED_ATTR: ("tampered_device", t.uint8_t, True),
|
||||
TUYA_SMOKE_BATTERY_ATTR: ("battery_status", t.uint8_t, True),
|
||||
}
|
||||
|
||||
def _update_attribute(self, attrid, value):
|
||||
super()._update_attribute(attrid, value)
|
||||
if attrid == TUYA_SMOKE_DETECTED_ATTR:
|
||||
status = IasZone.ZoneStatus.Alarm_1 if value == 0 else 0
|
||||
self.endpoint.device.ias_bus.listener_event("update_attribute", "zone_status", status)
|
||||
elif attrid == TUYA_SMOKE_TAMPERED_ATTR:
|
||||
self.endpoint.device.tamper_detection_bus.listener_event(
|
||||
"update_attribute", "present_value", bool(value)
|
||||
)
|
||||
elif attrid == TUYA_SMOKE_BATTERY_ATTR:
|
||||
batt = 5 if value == 0 else 40 if value == 1 else 100
|
||||
self.endpoint.device.battery_bus.listener_event("battery_change", batt)
|
||||
else:
|
||||
_LOGGER.warning(
|
||||
"[0x%04x:%s:0x%04x] unhandled attribute: 0x%04x",
|
||||
self.endpoint.device.nwk,
|
||||
self.endpoint.endpoint_id,
|
||||
self.cluster_id,
|
||||
attrid,
|
||||
)
|
||||
|
||||
|
||||
class TuyaIasZone(TuyaLocalCluster, IasZone):
|
||||
"""
|
||||
IAS Zone: this generates the "Smoke" entity for HA.
|
||||
Receives updates from TuyaSmokeDetectorCluster.
|
||||
"""
|
||||
|
||||
_CONSTANT_ATTRIBUTES = {ZONE_TYPE: IasZone.ZoneType.Fire_Sensor}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Init."""
|
||||
super().__init__(*args, **kwargs)
|
||||
self.endpoint.device.ias_bus.add_listener(self)
|
||||
|
||||
|
||||
class TuyaPowerConfigCluster(TuyaPowerConfigurationCluster):
|
||||
"""
|
||||
Power Config Cluster: this generates the "Battery" entity for HA.
|
||||
Receives updates from TuyaSmokeDetectorCluster.
|
||||
"""
|
||||
|
||||
_CONSTANT_ATTRIBUTES = {
|
||||
TuyaPowerConfigurationCluster.attributes_by_name["battery_size"].id: BatterySize.AAA,
|
||||
TuyaPowerConfigurationCluster.attributes_by_name["battery_quantity"].id: 2,
|
||||
TuyaPowerConfigurationCluster.attributes_by_name["battery_rated_voltage"].id: 15,
|
||||
}
|
||||
|
||||
|
||||
class TuyaTamperDetection(TuyaLocalCluster, BinaryInput):
|
||||
"""
|
||||
Tamper Detection Cluster: this generates the "Binary input" entity for HA, which is updated
|
||||
with the Tampered state. Receives updates from TuyaSmokeDetectorCluster.
|
||||
"""
|
||||
|
||||
_CONSTANT_ATTRIBUTES = {
|
||||
BinaryInput.attributes_by_name["description"].id: "Tamper Detected",
|
||||
BinaryInput.attributes_by_name["active_text"].id: "Tampered",
|
||||
BinaryInput.attributes_by_name["inactive_text"].id: "Clear",
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Init."""
|
||||
super().__init__(*args, **kwargs)
|
||||
self.endpoint.device.tamper_detection_bus.add_listener(self)
|
||||
|
||||
|
||||
class TuyaSmokeDetector0601(CustomDevice):
|
||||
"""TS0601 Smoke detector quirk."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Init."""
|
||||
self.ias_bus = Bus()
|
||||
self.battery_bus = Bus()
|
||||
self.tamper_detection_bus = Bus()
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
signature = {
|
||||
MODELS_INFO: [
|
||||
"""("_TZE200_uebojraa", "TS0601"),"""
|
||||
("_TZE200_uebojraa"),
|
||||
],
|
||||
ENDPOINTS: {
|
||||
1: {
|
||||
PROFILE_ID: zigpy.profiles.zha.PROFILE_ID,
|
||||
DEVICE_TYPE: zigpy.profiles.zha.DeviceType.SMART_PLUG,
|
||||
INPUT_CLUSTERS: [
|
||||
Basic.cluster_id,
|
||||
Groups.cluster_id,
|
||||
Scenes.cluster_id,
|
||||
TuyaManufCluster.cluster_id,
|
||||
],
|
||||
OUTPUT_CLUSTERS: [
|
||||
Time.cluster_id,
|
||||
Ota.cluster_id,
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
replacement = {
|
||||
ENDPOINTS: {
|
||||
1: {
|
||||
PROFILE_ID: zigpy.profiles.zha.PROFILE_ID,
|
||||
DEVICE_TYPE: zigpy.profiles.zha.DeviceType.IAS_ZONE,
|
||||
INPUT_CLUSTERS: [
|
||||
Basic.cluster_id,
|
||||
Groups.cluster_id,
|
||||
Scenes.cluster_id,
|
||||
TuyaIasZone,
|
||||
TuyaSmokeDetectorCluster,
|
||||
TuyaPowerConfigCluster,
|
||||
TuyaTamperDetection,
|
||||
],
|
||||
OUTPUT_CLUSTERS: [
|
||||
Time.cluster_id,
|
||||
Ota.cluster_id,
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
"""Tuya valve devices."""
|
||||
|
||||
import logging
|
||||
from typing import Dict
|
||||
|
||||
from zigpy.profiles import zha
|
||||
from zigpy.quirks import CustomDevice
|
||||
import zigpy.types as t
|
||||
from zigpy.zcl import foundation
|
||||
from zigpy.zcl.clusters.general import (
|
||||
Basic,
|
||||
Groups,
|
||||
Ota,
|
||||
PowerConfiguration,
|
||||
Scenes,
|
||||
Time,
|
||||
)
|
||||
|
||||
from zhaquirks.const import (
|
||||
DEVICE_TYPE,
|
||||
ENDPOINTS,
|
||||
INPUT_CLUSTERS,
|
||||
MODELS_INFO,
|
||||
OUTPUT_CLUSTERS,
|
||||
PROFILE_ID,
|
||||
)
|
||||
from zhaquirks.tuya import NoManufacturerCluster
|
||||
from zhaquirks.tuya.mcu import (
|
||||
DPToAttributeMapping,
|
||||
TuyaAttributesCluster,
|
||||
TuyaDPType,
|
||||
TuyaLevelControl,
|
||||
TuyaMCUCluster,
|
||||
TuyaOnOff,
|
||||
TuyaOnOffNM,
|
||||
TuyaPowerConfigurationCluster,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TuyaLevelControlNM(NoManufacturerCluster, TuyaLevelControl):
|
||||
"""Tuya LevelControl cluster with NoManufacturerID."""
|
||||
|
||||
|
||||
class TuyaValveManufCluster(TuyaMCUCluster):
|
||||
"""Tuya valve manufacturer cluster."""
|
||||
|
||||
attributes = TuyaMCUCluster.attributes.copy()
|
||||
attributes.update(
|
||||
{
|
||||
0xEF03: ("dp_3", t.uint32_t, True),
|
||||
0xEF65: ("dp_101", t.uint32_t, True),
|
||||
0xEF66: ("dp_102", t.uint32_t, True), # <-- new cluster attribute with fake IDs (102=0x66).Format= ID: ("name", type, True)
|
||||
}
|
||||
)
|
||||
|
||||
dp_to_attribute: Dict[int, DPToAttributeMapping] = {
|
||||
2: DPToAttributeMapping(
|
||||
TuyaOnOffNM.ep_attribute,
|
||||
"on_off",
|
||||
dp_type=TuyaDPType.BOOL,
|
||||
),
|
||||
1: DPToAttributeMapping(
|
||||
TuyaLevelControlNM.ep_attribute,
|
||||
"current_level",
|
||||
dp_type=TuyaDPType.VALUE,
|
||||
converter=lambda x: (x * 255) // 100,
|
||||
dp_converter=lambda x: (x * 100) // 255,
|
||||
),
|
||||
3: DPToAttributeMapping(
|
||||
TuyaMCUCluster.ep_attribute,
|
||||
"dp_3",
|
||||
dp_type=TuyaDPType.VALUE,
|
||||
),
|
||||
101: DPToAttributeMapping(
|
||||
TuyaMCUCluster.ep_attribute,
|
||||
"dp_101",
|
||||
dp_type=TuyaDPType.VALUE,
|
||||
),
|
||||
102: DPToAttributeMapping( # <-- device DP102
|
||||
TuyaMCUCluster.ep_attribute, # <-- reference to the cluster which has the attribute
|
||||
"dp_102", # <-- attribute "name"
|
||||
dp_type=TuyaDPType.VALUE, # <-- DP Type it is related to the attribute type
|
||||
),
|
||||
108: DPToAttributeMapping(
|
||||
TuyaPowerConfigurationCluster.ep_attribute,
|
||||
"battery_percentage_remaining",
|
||||
dp_type=TuyaDPType.VALUE,
|
||||
),
|
||||
}
|
||||
|
||||
data_point_handlers = {
|
||||
2: "_dp_2_attr_update",
|
||||
1: "_dp_2_attr_update",
|
||||
3: "_dp_2_attr_update",
|
||||
101: "_dp_2_attr_update",
|
||||
102: "_dp_2_attr_update",
|
||||
108: "_dp_2_attr_update",
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
|
||||
class TuyaValve(CustomDevice):
|
||||
"""Tuya valve device."""
|
||||
|
||||
signature = {
|
||||
"""MODELS_INFO: [("_TZE200_sh1btabb", "TS0601")],"""
|
||||
MODELS_INFO: [("_TZE200_sh1btabb")],
|
||||
|
||||
ENDPOINTS: {
|
||||
# <SimpleDescriptor endpoint=1 profile=260 device_type=0x0051
|
||||
# input_clusters=[0x0000, 0x0004, 0x0005, 0xef00]
|
||||
# output_clusters=[0x000a, 0x0019]>
|
||||
1: {
|
||||
PROFILE_ID: zha.PROFILE_ID,
|
||||
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
|
||||
INPUT_CLUSTERS: [
|
||||
Basic.cluster_id,
|
||||
Groups.cluster_id,
|
||||
Scenes.cluster_id,
|
||||
TuyaValveManufCluster.cluster_id,
|
||||
],
|
||||
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
replacement = {
|
||||
ENDPOINTS: {
|
||||
1: {
|
||||
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
|
||||
INPUT_CLUSTERS: [
|
||||
Basic.cluster_id,
|
||||
Groups.cluster_id,
|
||||
Scenes.cluster_id,
|
||||
TuyaValveManufCluster,
|
||||
TuyaOnOffNM,
|
||||
TuyaLevelControlNM,
|
||||
TuyaPowerConfigurationCluster,
|
||||
],
|
||||
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user