I got zigbee ultrasonic water level sensor made by EPTTECH, it works fine in Tuya application, however neithe ZHA supports it nor Local Tuya shows level in Home Assistant.
Unfortunatelly my custom quirk did not work either, or I may missed something in it…
"""Custom quirk for EPTTECH TLC2206-ZB Tank Level Sensor."""
from zigpy.profiles import zha
from zigpy.quirks import CustomDevice
from zigpy.zcl.clusters.general import Basic, Groups, Scenes, Ota, Time
from zigpy.zcl.clusters.measurement import FlowMeasurement
from zhaquirks.const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PROFILE_ID,
)
from zhaquirks.tuya import TuyaLocalCluster
from zhaquirks.tuya.mcu import DPToAttributeMapping, TuyaMCUCluster
import zigpy.types as t
# Define the data points (DPs) for the sensor
TUYA_TANK_LEVEL_PERCENT_DP = 22
TUYA_TANK_DEPTH_DP = 2
TUYA_TANK_STATE_DP = 1
TUYA_INSTALLATION_HEIGHT_DP = 19
TUYA_MAX_SET_DP = 7
TUYA_MIN_SET_DP = 8
TUYA_DEPTH_MAX_DP = 21
class LiquidLevelStatus(t.enum8):
"""Enum for liquid level status."""
NORMAL = 0x00
LOW = 0x01
HIGH = 0x02
class TuyaTankLevelMeasurement(TuyaLocalCluster):
"""Custom cluster for tank level measurement."""
cluster_id = FlowMeasurement.cluster_id
name = "Tank Level Measurement"
ep_attribute = "liquid_level_measurement"
attributes = {
0x0000: ("measured_value", t.uint16_t, True),
0x0001: ("min_measured_value", t.uint16_t, True),
0x0002: ("max_measured_value", t.uint16_t, True),
0xFF00: ("liquid_level_percent", t.uint8_t, True),
0xFF01: ("liquid_depth", t.uint16_t, True), # Assuming depth is in mm
0xFF02: ("liquid_state", LiquidLevelStatus, True),
0xFF03: ("installation_height", t.uint16_t, True), # mm
0xFF04: ("max_set", t.uint8_t, True), # Percentage
0xFF05: ("mini_set", t.uint8_t, True), # Percentage
0xFF06: ("liquid_depth_max", t.uint16_t, True), # mm
}
class TuyaTankLevelCluster(TuyaMCUCluster):
"""Custom cluster for handling EPTTECH TLC2206-ZB tank level sensor data points."""
dp_to_attribute: dict[int, DPToAttributeMapping] = {
TUYA_TANK_LEVEL_PERCENT_DP: DPToAttributeMapping(
TuyaTankLevelMeasurement.ep_attribute,
"liquid_level_percent",
),
TUYA_TANK_DEPTH_DP: DPToAttributeMapping(
TuyaTankLevelMeasurement.ep_attribute,
"liquid_depth",
converter=lambda x: x / 100, # Convert mm to meters
),
TUYA_TANK_STATE_DP: DPToAttributeMapping(
TuyaTankLevelMeasurement.ep_attribute,
"liquid_state",
converter=lambda x: LiquidLevelStatus(x),
),
TUYA_INSTALLATION_HEIGHT_DP: DPToAttributeMapping(
TuyaTankLevelMeasurement.ep_attribute,
"installation_height",
),
TUYA_MAX_SET_DP: DPToAttributeMapping(
TuyaTankLevelMeasurement.ep_attribute,
"max_set",
),
TUYA_MIN_SET_DP: DPToAttributeMapping(
TuyaTankLevelMeasurement.ep_attribute,
"mini_set",
),
TUYA_DEPTH_MAX_DP: DPToAttributeMapping(
TuyaTankLevelMeasurement.ep_attribute,
"liquid_depth_max",
),
}
data_point_handlers = {
TUYA_TANK_LEVEL_PERCENT_DP: "_dp_2_attr_update",
TUYA_TANK_DEPTH_DP: "_dp_2_attr_update",
TUYA_TANK_STATE_DP: "_dp_2_attr_update",
TUYA_INSTALLATION_HEIGHT_DP: "_dp_2_attr_update",
TUYA_MAX_SET_DP: "_dp_2_attr_update",
TUYA_MIN_SET_DP: "_dp_2_attr_update",
TUYA_DEPTH_MAX_DP: "_dp_2_attr_update",
}
class EPTTECH_TLC2206ZB(CustomDevice):
"""Custom quirk for EPTTECH TLC2206-ZB Tank Level Sensor."""
signature = {
MODELS_INFO: [("TS0601", "_TZE200_lvkk0hdg")],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.IAS_ZONE, # Device type commonly used for sensors
INPUT_CLUSTERS: [
Basic.cluster_id,
TuyaTankLevelCluster.cluster_id, # Custom cluster for tank level
],
OUTPUT_CLUSTERS: [
Ota.cluster_id,
Time.cluster_id,
],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.IAS_ZONE,
INPUT_CLUSTERS: [
Basic.cluster_id,
TuyaTankLevelCluster, # Custom cluster for tank level
],
OUTPUT_CLUSTERS: [
Ota.cluster_id,
Time.cluster_id,
],
},
},
}
Help is much appreciated!