Skip to content

Instantly share code, notes, and snippets.

@smileham
Last active September 5, 2026 07:29
Show Gist options
  • Select an option

  • Save smileham/ed42f5ec62f9aca380211454c2f904e7 to your computer and use it in GitHub Desktop.

Select an option

Save smileham/ed42f5ec62f9aca380211454c2f904e7 to your computer and use it in GitHub Desktop.
ZHA quirk for NTCHT01 sensor
"""ZHA Quirk for NTCHT01 Dual Temperature and Humidity Sensor."""
import zigpy.types as t
from zhaquirks.builder import (
PERCENTAGE,
BinarySensorDeviceClass,
EntityPlatform,
EntityType,
SensorDeviceClass,
SensorStateClass,
UnitOfTemperature,
UnitOfTime,
)
from zhaquirks.tuya.builder import TuyaQuirkBuilder
from zigpy.quirks.v2.homeassistant import UnitOfTemperature
from zigpy.quirks.v2.homeassistant.sensor import SensorDeviceClass, SensorStateClass
class TuyaProbeTempWarning(t.enum8):
"""Tuya probe temperature warning enum."""
Normal = 0x00
Low = 0x01
High = 0x02
class TuyaTempWarning(t.enum8):
"""Tuya temperature warning enum."""
Normal = 0x00
Low = 0x01
High = 0x02
class TuyaHumiWarning(t.enum8):
"""Tuya humidity warning enum."""
Normal = 0x00
Low = 0x01
High = 0x02
# Excellux ZG-105NTH Temperature and Humidity Sensor with Probe
# White-label: ZG-106NTH (NTCHT02), EZ-L01NTH (NTCHT03)
# Note: Device IDs (_TZE2...) need to be discovered from actual devices
(
TuyaQuirkBuilder("Excellux", "NTCHT01")
.applies_to("Excellux", "NTCHT02")
.applies_to("Excellux", "NTCHT03")
.applies_to("NTCHT01", "Excellux")
.tuya_temperature(
dp_id=1,
scale=10,
)
.tuya_battery(dp_id=4)
.tuya_sensor(dp_id=5,
attribute_name="probe_temperature",
translation_key="probe_temperature",
fallback_name="Probe Temperature",
type=t.uint16_t,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
multiplier=0.01,
unit=UnitOfTemperature.CELSIUS)
.tuya_humidity(dp_id=118, scale=1)
.tuya_number(
dp_id=101,
attribute_name="sampling_interval",
type=t.uint16_t,
unit=UnitOfTime.SECONDS,
min_value=5,
max_value=1200,
step=5,
entity_type=EntityType.CONFIG,
translation_key="sampling_interval",
fallback_name="Sampling interval",
)
.tuya_number(
dp_id=108,
attribute_name="probe_temperature_calibration",
type=t.uint16_t,
unit=UnitOfTemperature.CELSIUS,
min_value=-2,
max_value=2,
step=0.1,
multiplier=0.1,
entity_type=EntityType.CONFIG,
translation_key="probe_temperature_calibration",
fallback_name="Probe temperature calibration",
)
.tuya_number(
dp_id=109,
attribute_name="probe_temperature_v0_set",
type=t.uint16_t,
unit=UnitOfTemperature.CELSIUS,
min_value=-40,
max_value=125,
step=0.1,
multiplier=0.1,
entity_type=EntityType.CONFIG,
translation_key="probe_temperature_v0_set",
fallback_name="Probe temperature v0 threshold",
)
.tuya_number(
dp_id=110,
attribute_name="probe_temperature_v1_set",
type=t.uint16_t,
unit=UnitOfTemperature.CELSIUS,
min_value=-40,
max_value=125,
step=0.1,
multiplier=0.1,
entity_type=EntityType.CONFIG,
translation_key="probe_temperature_v1_set",
fallback_name="Probe temperature v1 threshold",
)
.tuya_enum(
dp_id=112,
attribute_name="probe_temperature_warning",
enum_class=TuyaProbeTempWarning,
entity_platform=EntityPlatform.SENSOR,
entity_type=EntityType.STANDARD,
translation_key="probe_temperature_warning",
fallback_name="Probe temperature warning",
)
.tuya_number(
dp_id=114,
attribute_name="temperature_calibration",
type=t.uint16_t,
unit=UnitOfTemperature.CELSIUS,
min_value=-2,
max_value=2,
step=0.01,
multiplier=0.01,
entity_type=EntityType.CONFIG,
translation_key="temperature_calibration",
fallback_name="Temperature calibration",
)
.tuya_number(
dp_id=115,
attribute_name="temperature_v0_set",
type=t.uint16_t,
unit=UnitOfTemperature.CELSIUS,
min_value=-40,
max_value=85,
step=0.01,
multiplier=0.01,
entity_type=EntityType.CONFIG,
translation_key="temperature_v0_set",
fallback_name="Temperature v0 threshold",
)
.tuya_number(
dp_id=116,
attribute_name="temperature_v1_set",
type=t.uint16_t,
unit=UnitOfTemperature.CELSIUS,
min_value=-40,
max_value=85,
step=0.01,
multiplier=0.01,
entity_type=EntityType.CONFIG,
translation_key="temperature_v1_set",
fallback_name="Temperature v1 threshold",
)
.tuya_enum(
dp_id=117,
attribute_name="temperature_warning",
enum_class=TuyaTempWarning,
entity_platform=EntityPlatform.SENSOR,
entity_type=EntityType.STANDARD,
translation_key="temperature_warning",
fallback_name="Temperature warning",
)
.tuya_number(
dp_id=119,
attribute_name="humidity_calibration",
type=t.uint16_t,
unit=PERCENTAGE,
min_value=-10,
max_value=10,
step=0.01,
multiplier=0.01,
entity_type=EntityType.CONFIG,
translation_key="humidity_calibration",
fallback_name="Humidity calibration",
)
.tuya_number(
dp_id=120,
attribute_name="humidity_v0_set",
type=t.uint16_t,
unit=PERCENTAGE,
min_value=0,
max_value=100,
step=0.01,
multiplier=0.01,
entity_type=EntityType.CONFIG,
translation_key="humidity_v0_set",
fallback_name="Humidity v0 threshold",
)
.tuya_number(
dp_id=121,
attribute_name="humidity_v1_set",
type=t.uint16_t,
unit=PERCENTAGE,
min_value=0,
max_value=100,
step=0.01,
multiplier=0.01,
entity_type=EntityType.CONFIG,
translation_key="humidity_v1_set",
fallback_name="Humidity v1 threshold",
)
.tuya_enum(
dp_id=122,
attribute_name="humidity_warning",
enum_class=TuyaHumiWarning,
entity_platform=EntityPlatform.SENSOR,
entity_type=EntityType.STANDARD,
translation_key="humidity_warning",
fallback_name="Humidity warning",
)
.skip_configuration()
.add_to_registry()
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment