diff --git a/zigpy_quirks/_TZ3000_bjawzodf.py b/zigpy_quirks/_TZ3000_bjawzodf.py new file mode 100755 index 0000000..6a1dcc9 --- /dev/null +++ b/zigpy_quirks/_TZ3000_bjawzodf.py @@ -0,0 +1,66 @@ +"""Tuya TY0201 temperature, humidity and optional illumination sensors.""" + +from zigpy.profiles import zha +from zigpy.profiles.zha import DeviceType +from zigpy.quirks import CustomCluster, CustomDevice +import zigpy.types as t +from zigpy.zcl.clusters.general import Basic, Identify, Ota, PowerConfiguration, Time +from zigpy.zcl.clusters.measurement import ( + IlluminanceMeasurement, + RelativeHumidity, + TemperatureMeasurement, +) +from zigpy.zdo.types import NodeDescriptor + +from zhaquirks.const import ( + DEVICE_TYPE, + ENDPOINTS, + INPUT_CLUSTERS, + MODELS_INFO, + NODE_DESCRIPTOR, + OUTPUT_CLUSTERS, + PROFILE_ID, +) + +class TemperatureHumidtySensorWithScreen(CustomDevice): + """Temu temperature and humidity sensor with screen.""" + + signature = { + # + MODELS_INFO: [("_TZ3000_bjawzodf", "TY0201")], + ENDPOINTS: { + 1: { + PROFILE_ID: zha.PROFILE_ID, + DEVICE_TYPE: DeviceType.TEMPERATURE_SENSOR, + INPUT_CLUSTERS: [ + Basic.cluster_id, + PowerConfiguration.cluster_id, + Identify.cluster_id, + TemperatureMeasurement.cluster_id, + RelativeHumidity.cluster_id, + ], + OUTPUT_CLUSTERS: [ + Ota.cluster_id, + ], + }, + }, + } + + replacement = { + ENDPOINTS: { + 1: { + INPUT_CLUSTERS: [ + Basic.cluster_id, + PowerConfiguration.cluster_id, + Identify.cluster_id, + TemperatureMeasurement.cluster_id, + RelativeHumidity.cluster_id, + ], + OUTPUT_CLUSTERS: [ + Ota.cluster_id, + ], + }, + }, + } \ No newline at end of file diff --git a/zigpy_quirks/_TZ3210_up3pngle.py b/zigpy_quirks/_TZ3210_up3pngle.py new file mode 100755 index 0000000..e34535d --- /dev/null +++ b/zigpy_quirks/_TZ3210_up3pngle.py @@ -0,0 +1,124 @@ +"""Smoke Sensor.""" +import zigpy.profiles.zha +from zigpy.quirks import CustomCluster, CustomDevice +import zigpy.types as t +from zigpy.zcl.clusters.general import Basic, PowerConfiguration, Groups, Identify, OnOff, Ota, Scenes, Time +from zigpy.zcl.clusters.security import IasZone +from zigpy.zcl.clusters.lightlink import LightLink + +from zhaquirks import Bus +from zhaquirks.const import ( + DEVICE_TYPE, + ENDPOINTS, + INPUT_CLUSTERS, + MODELS_INFO, + OUTPUT_CLUSTERS, + PROFILE_ID, + ZONE_STATUS, + ZONE_TYPE, +) +from zhaquirks.tuya import TuyaManufCluster, TuyaManufClusterAttributes + + +TUYA_SMOKE_DETECTED_ATTR = 0x0401 # [0]/[1] [Detected]/[Clear]! + + +class TuyaSmokeDetectorCluster(TuyaManufClusterAttributes): + """Manufacturer Specific Cluster of the TS0601 smoke detector.""" + + attributes = { + TUYA_SMOKE_DETECTED_ATTR: ("smoke_detected", t.uint8_t, True), + } + + def _update_attribute(self, attrid, value): + super()._update_attribute(attrid, value) + if attrid == TUYA_SMOKE_DETECTED_ATTR: + if value == 0: + self.endpoint.device.ias_bus.listener_event( + "update_zone_status", IasZone.ZoneStatus.Alarm_1 + ) + else: + self.endpoint.device.ias_bus.listener_event("update_zone_status", 0) + 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(CustomCluster, IasZone): + """IAS Zone.""" + + _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) + + def update_zone_status(self, value): + """Update IAS status.""" + super()._update_attribute(ZONE_STATUS, value) + + +class TuyaSmokeDetector0205(CustomDevice): + """TS0601 Smoke detector quirk.""" + + def __init__(self, *args, **kwargs): + """Init.""" + self.ias_bus = Bus() + super().__init__(*args, **kwargs) + + signature = { + MODELS_INFO: [ + ("_TZ3210_up3pngle", "TS0205"), + ], + ENDPOINTS: { + 1: { + PROFILE_ID: zigpy.profiles.zha.PROFILE_ID, + DEVICE_TYPE: zigpy.profiles.zha.DeviceType.IAS_ZONE, + INPUT_CLUSTERS: [ + Basic.cluster_id, + PowerConfiguration.cluster_id, + Groups.cluster_id, + Scenes.cluster_id, + IasZone.cluster_id, + ], + OUTPUT_CLUSTERS: [ + Identify.cluster_id, + Groups.cluster_id, + Time.cluster_id, + OnOff.cluster_id, + Ota.cluster_id, + LightLink.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, + PowerConfiguration.cluster_id, + Groups.cluster_id, + Scenes.cluster_id, + TuyaIasZone, + ], + OUTPUT_CLUSTERS: [ + Identify.cluster_id, + Groups.cluster_id, + Time.cluster_id, + OnOff.cluster_id, + Ota.cluster_id, + LightLink.cluster_id, + ], + }, + }, + }