TZE200_lvkk0hdg ZHA

I have purchased several ultrasonic sensors TZE200_lvkk0hdg
Those are absolutely great sensors and very useful in household and garden, to be used both for water storage tanks, drainage tanks, swimming pool levels etc…

Unfortunatelly I have managed to pair them just with TUYA app on my phone, byt even local tuya cant see levels in HA.
I have tried to make a custom quirk for it but it doesnt work:

"""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,
                ],
            },
        },
    }

Could ZHA development team add support for the device like mqtt2zigbee did?

1 Like