I’m wanting to use a Tuya ZG-204ZH presence sensor in a HA automation to control a room fan. It’s my understanding that when paired with ZHA, the ZG-204ZH only exposes a single presence state binary sensor and an illuminance sensor. You don’t get any configuration entities for detection distance, sensitivity, or cooldown time. Actually, the binary sensor is probably all I need for my application, but I’m thinking I could purchase an inexpensive Tuya hub to configure the device and then remove the device and control it with ZHA. Has anyone done this and can confirm that when removing the device from the Tuya app, that configuration settings remain?
Trying other Tuya Custom Integrations on github from community members is also an option. Best place to find than is thru HACS.
Nailed my first quirk! After many painful hours it finally works ![]()
I will say though, testing and debugging ZHA quirks is a pain in the 🫏.
All the editing, deleting, restarting, and re pairing over and over again.
Is there really no easier workflow for this?
Anyway, I digress, here is my working quirk for the ZG-204ZH:
"""Tuya HOBEIAN ZG-204ZH 24Ghz Human Presence Sensor"""
from typing import Any
from zigpy.quirks.v2 import EntityPlatform, EntityType
from zigpy.quirks.v2.homeassistant import LIGHT_LUX, UnitOfLength, UnitOfTime
from zigpy.quirks.v2.homeassistant.sensor import SensorDeviceClass, SensorStateClass
import zigpy.types as t
from zigpy.zcl.clusters.measurement import OccupancySensing
from zhaquirks.tuya import TuyaLocalCluster
from zhaquirks.tuya.builder import TuyaQuirkBuilder
class TuyaOccupancySensing(OccupancySensing, TuyaLocalCluster):
"""Tuya local OccupancySensing cluster."""
class TuyaHumanMotionState(t.enum8):
"""Tuya human motion state enum, variation 02."""
Off = 0x00
Large = 0x01
Small = 0x02
Static = 0x03
class TuyaMotionDetectionMode(t.enum8):
PIR_and_radar = 0x00
PIR_or_radar = 0x01
Only_radar = 0x02
class TuyaTemperatureUnit(t.enum8):
"""Tuya temperature unit enum."""
Celsius = 0x00
Fahrenheit = 0x01
(
TuyaQuirkBuilder("_TZE200_vuqzj1ej", "TS0601")
.applies_to("_TZE200_hdih4foa", "TS0601")
.applies_to("HOBEIAN", "ZG-204ZH")
.tuya_dp(
dp_id=1,
ep_attribute=TuyaOccupancySensing.ep_attribute,
attribute_name=OccupancySensing.AttributeDefs.occupancy.name,
converter=lambda x: x == 1,
)
.adds(TuyaOccupancySensing)
.tuya_number(
dp_id=2,
attribute_name="static_detection_sensitivity",
type=t.uint16_t,
min_value=0,
max_value=10,
step=1,
translation_key="static_detection_sensitivity",
fallback_name="Static detection sensitivity",
)
.tuya_number(
dp_id=4,
attribute_name="static_detection_distance",
type=t.uint16_t,
device_class=SensorDeviceClass.DISTANCE,
unit=UnitOfLength.METERS,
min_value=0,
max_value=500,
step=1,
multiplier=0.01,
translation_key="static_detection_distance",
fallback_name="Static detection distance",
)
.tuya_enum(
dp_id=103,
attribute_name="human_motion_state",
enum_class=TuyaHumanMotionState,
entity_platform=EntityPlatform.SENSOR,
entity_type=EntityType.STANDARD,
translation_key="human_motion_state",
fallback_name="Human motion state",
)
.tuya_number(
dp_id=102,
attribute_name="presence_timeout",
type=t.uint16_t,
device_class=SensorDeviceClass.DURATION,
unit=UnitOfTime.SECONDS,
min_value=0,
max_value=28800,
step=1,
translation_key="fading_time",
fallback_name="Fading time",
)
.tuya_illuminance(dp_id=106)
.tuya_switch(
dp_id=108,
attribute_name="find_switch",
entity_type=EntityType.STANDARD,
translation_key="led_indicator",
fallback_name="LED indicator",
)
.tuya_battery(dp_id=110)
.tuya_temperature(dp_id=111, scale=10)
.tuya_humidity(dp_id=101)
.tuya_enum(
dp_id=112,
attribute_name="motion_detection_mode",
enum_class=TuyaMotionDetectionMode,
translation_key="motion_detection_mode",
fallback_name="Motion detection mode",
)
.tuya_number(
dp_id=123,
attribute_name="motion_detection_sensitivity",
type=t.uint16_t,
min_value=0,
max_value=10,
step=1,
translation_key="motion_detection_sensitivity",
fallback_name="Motion detection sensitivity",
)
.tuya_number(
dp_id=107,
attribute_name="illuminance_interval",
type=t.uint16_t,
device_class=SensorDeviceClass.DURATION,
unit=UnitOfTime.MINUTES,
min_value=1,
max_value=720,
step=1,
translation_key="illuminance_interval",
fallback_name="Illuminance interval",
)
.tuya_number(
dp_id=105,
attribute_name="temperature_calibration",
type=t.int16s,
translation_key="temperature_calibration",
fallback_name="Temperature calibration",
)
.tuya_number(
dp_id=104,
attribute_name="humidity_calibration",
type=t.int16s,
translation_key="humidity_calibration",
fallback_name="Humidity calibration",
)
.tuya_enum(
dp_id=109,
attribute_name="temperature_unit",
enum_class=TuyaTemperatureUnit,
translation_key="temperature_unit",
fallback_name="Temperature unit",
)
.skip_configuration()
.add_to_registry()
)