Hello Community,
Some time ago, I purchased Zigbee smoke detectors from AliExpress for non-critical areas. Unfortunately, they are not recognized as smoke detectors in ZHA (Zigbee Home Automation), but rather as motion detectors, as shown in the attached screenshot.
I have already attempted to solve this issue using so-called “quirks.” To do this, I added the following to my configuration.yaml:
zha:
custom_quirks_path: /config/custom_zha_quirks/
I created the corresponding folder beforehand. Inside it, I created a file named TS0205_Update.js with the following content:
"""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,
],
},
},
}
Despite several attempts to delete and reset the “motion detector,” everything remains the same. Of course, I have also performed a restart.
Do you have any tips or suggestions on how I can solve this problem?
Thank you in advance!
Best regards,
Joscha