zigpy / zha-device-handlers

ZHA device handlers bridge the functionality gap created when manufacturers deviate from the ZCL specification, handling deviations and exceptions by parsing custom messages to and from Zigbee devices.
Apache License 2.0
719 stars 664 forks source link

[Device Support Request] Tuya rainsensor TS0207_TZ3210_tgvtvdoc #3249

Open wbmk78 opened 1 month ago

wbmk78 commented 1 month ago

Problem description

I have a TS0207 battery powered outdoor rain and light intensity sensor: https://a.aliexpress.com/_EjJGdz9

The sensors are reported as a motion and open/close sensor. It seems like the movement sensor is triggered when rain is detected, but it seems like it is rarely updated.

Solution description

Correctly mapped sensor output so a action can be created.

Screenshots/Video

Screenshots/Video ![TS0207 and Tuya](https://github.com/user-attachments/assets/12d70ced-2f1a-4709-8795-7e08a63bf001)

Device signature

Device signature ```json { "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x0402", "input_clusters": [ "0x0000", "0x0001", "0x0004", "0x0005", "0x0500", "0xef00" ], "output_clusters": [ "0x0003", "0x0004", "0x0006", "0x000a", "0x0019", "0x1000" ] } }, "manufacturer": "_TZ3210_tgvtvdoc", "model": "TS0207", } ```

Diagnostic information

Diagnostic information ```json { "home_assistant": { "installation_type": "Home Assistant OS", "version": "2024.7.2", "dev": false, "hassio": true, "virtualenv": false, "python_version": "3.12.4", "docker": true, "arch": "aarch64", "timezone": "Europe/Amsterdam", "os_name": "Linux", "os_version": "6.6.31-haos-raspi", "supervisor": "2024.06.2", "host_os": "Home Assistant OS 12.4", "docker_version": "26.1.4", "chassis": "embedded", "run_as_root": true }, "custom_components": { "nest_protect": { "documentation": "https://github.com/imicknl/ha-nest-protect", "version": "0.4.0b5", "requirements": [] }, "hacs": { "documentation": "https://hacs.xyz/docs/configuration/start", "version": "1.34.0", "requirements": [ "aiogithubapi>=22.10.1" ] }, "hon": { "documentation": "https://github.com/gvigroux/hon", "version": "0.7.4", "requirements": [] } }, "integration_manifest": { "domain": "zha", "name": "Zigbee Home Automation", "after_dependencies": [ "onboarding", "usb" ], "codeowners": [ "dmulcahey", "adminiuga", "puddly", "TheJulianJES" ], "config_flow": true, "dependencies": [ "file_upload" ], "documentation": "https://www.home-assistant.io/integrations/zha", "iot_class": "local_polling", "loggers": [ "aiosqlite", "bellows", "crccheck", "pure_pcapy3", "zhaquirks", "zigpy", "zigpy_deconz", "zigpy_xbee", "zigpy_zigate", "zigpy_znp", "universal_silabs_flasher" ], "requirements": [ "bellows==0.39.1", "pyserial==3.5", "zha-quirks==0.0.117", "zigpy-deconz==0.23.2", "zigpy==0.64.1", "zigpy-xbee==0.20.1", "zigpy-zigate==0.12.1", "zigpy-znp==0.12.2", "universal-silabs-flasher==0.0.20", "pyserial-asyncio-fast==0.11" ], "usb": [ { "vid": "10C4", "pid": "EA60", "description": "*2652*", "known_devices": [ "slae.sh cc2652rb stick" ] }, { "vid": "10C4", "pid": "EA60", "description": "*slzb-07*", "known_devices": [ "smlight slzb-07" ] }, { "vid": "1A86", "pid": "55D4", "description": "*sonoff*plus*", "known_devices": [ "sonoff zigbee dongle plus v2" ] }, { "vid": "10C4", "pid": "EA60", "description": "*sonoff*plus*", "known_devices": [ "sonoff zigbee dongle plus" ] }, { "vid": "10C4", "pid": "EA60", "description": "*tubeszb*", "known_devices": [ "TubesZB Coordinator" ] }, { "vid": "1A86", "pid": "7523", "description": "*tubeszb*", "known_devices": [ "TubesZB Coordinator" ] }, { "vid": "1A86", "pid": "7523", "description": "*zigstar*", "known_devices": [ "ZigStar Coordinators" ] }, { "vid": "1CF1", "pid": "0030", "description": "*conbee*", "known_devices": [ "Conbee II" ] }, { "vid": "0403", "pid": "6015", "description": "*conbee*", "known_devices": [ "Conbee III" ] }, { "vid": "10C4", "pid": "8A2A", "description": "*zigbee*", "known_devices": [ "Nortek HUSBZB-1" ] }, { "vid": "0403", "pid": "6015", "description": "*zigate*", "known_devices": [ "ZiGate+" ] }, { "vid": "10C4", "pid": "EA60", "description": "*zigate*", "known_devices": [ "ZiGate" ] }, { "vid": "10C4", "pid": "8B34", "description": "*bv 2010/10*", "known_devices": [ "Bitron Video AV2010/10" ] } ], "zeroconf": [ { "type": "_esphomelib._tcp.local.", "name": "tube*" }, { "type": "_zigate-zigbee-gateway._tcp.local.", "name": "*zigate*" }, { "type": "_zigstar_gw._tcp.local.", "name": "*zigstar*" }, { "type": "_uzg-01._tcp.local.", "name": "uzg-01*" }, { "type": "_slzb-06._tcp.local.", "name": "slzb-06*" }, { "type": "_xzg._tcp.local.", "name": "xzg*" }, { "type": "_czc._tcp.local.", "name": "czc*" } ], "is_built_in": true }, "setup_times": { "null": { "setup": 7.696299871895462e-05 }, "3402b9691794fee151a5736bcf588534": { "wait_import_platforms": -0.00024816500081215054, "wait_base_component": -0.0006417189979401883, "config_entry_setup": 12.806632286999957 } }, "data": { "ieee": "**REDACTED**", "nwk": 27934, "manufacturer": "_TZ3210_tgvtvdoc", "model": "TS0207", "name": "_TZ3210_tgvtvdoc TS0207", "quirk_applied": false, "quirk_class": "zigpy.device.Device", "quirk_id": null, "manufacturer_code": 4417, "power_source": "Battery or Unknown", "lqi": 112, "rssi": -72, "last_seen": "2024-07-12T14:01:01", "available": true, "device_type": "EndDevice", "signature": { "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x0402", "input_clusters": [ "0x0000", "0x0001", "0x0004", "0x0005", "0x0500", "0xef00" ], "output_clusters": [ "0x0003", "0x0004", "0x0006", "0x000a", "0x0019", "0x1000" ] } }, "manufacturer": "_TZ3210_tgvtvdoc", "model": "TS0207" }, "active_coordinator": false, "entities": [ { "entity_id": "binary_sensor.tz3210_tgvtvdoc_ts0207_beweging", "name": "_TZ3210_tgvtvdoc TS0207" }, { "entity_id": "binary_sensor.tz3210_tgvtvdoc_ts0207_openen", "name": "_TZ3210_tgvtvdoc TS0207" }, { "entity_id": "sensor.tz3210_tgvtvdoc_ts0207_batterij", "name": "_TZ3210_tgvtvdoc TS0207" }, { "entity_id": "update.tz3210_tgvtvdoc_ts0207_firmware", "name": "_TZ3210_tgvtvdoc TS0207" } ], "neighbors": [], "routes": [], "endpoint_names": [ { "name": "IAS_ZONE" } ], "user_given_name": "Regensensor", "device_reg_id": "e160386800c6e305dae008df8ea9e2e7", "area_id": "slaapkamer", "cluster_details": { "1": { "device_type": { "name": "IAS_ZONE", "id": 1026 }, "profile_id": 260, "in_clusters": { "0x0000": { "endpoint_attribute": "basic", "attributes": { "0x0004": { "attribute_name": "manufacturer", "value": "_TZ3210_tgvtvdoc" }, "0x0005": { "attribute_name": "model", "value": "TS0207" } }, "unsupported_attributes": {} }, "0x0004": { "endpoint_attribute": "groups", "attributes": {}, "unsupported_attributes": {} }, "0x0005": { "endpoint_attribute": "scenes", "attributes": {}, "unsupported_attributes": {} }, "0x0001": { "endpoint_attribute": "power", "attributes": { "0x0021": { "attribute_name": "battery_percentage_remaining", "value": 196 }, "0x0020": { "attribute_name": "battery_voltage", "value": 0 } }, "unsupported_attributes": { "0x0033": { "attribute_name": "battery_quantity" }, "0x0031": { "attribute_name": "battery_size" } } }, "0x0500": { "endpoint_attribute": "ias_zone", "attributes": { "0x0010": { "attribute_name": "cie_addr", "value": [ 220, 64, 34, 254, 255, 39, 135, 4 ] }, "0x0000": { "attribute_name": "zone_state", "value": 1 }, "0x0002": { "attribute_name": "zone_status", "value": 1 }, "0x0001": { "attribute_name": "zone_type", "value": 13 } }, "unsupported_attributes": {} }, "0xef00": { "endpoint_attribute": null, "attributes": {}, "unsupported_attributes": {} } }, "out_clusters": { "0x0003": { "endpoint_attribute": "identify", "attributes": {}, "unsupported_attributes": {} }, "0x0004": { "endpoint_attribute": "groups", "attributes": {}, "unsupported_attributes": {} }, "0x0006": { "endpoint_attribute": "on_off", "attributes": { "0x0000": { "attribute_name": "on_off", "value": 0 } }, "unsupported_attributes": { "0x0000": { "attribute_name": "on_off" }, "0x4003": { "attribute_name": "start_up_on_off" } } }, "0x1000": { "endpoint_attribute": "lightlink", "attributes": {}, "unsupported_attributes": {} }, "0x000a": { "endpoint_attribute": "time", "attributes": {}, "unsupported_attributes": {} }, "0x0019": { "endpoint_attribute": "ota", "attributes": { "0x0002": { "attribute_name": "current_file_version", "value": 67 } }, "unsupported_attributes": {} } } } } } } ```

Logs

Logs ```python [Paste the logs here] ```

Custom quirk

Custom quirk ```python [Paste your custom quirk here] ```

Additional information

No response

Chrisni2 commented 1 month ago

I would be interested in this too

Andrik45719 commented 1 month ago
const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

const definition = {
    fingerprint: [
        {
            modelID: 'TS0207',
            manufacturerName: '_TZ3210_tgvtvdoc',
        },
    ],
    model: 'TS0207_rain_sensor',
    vendor: 'Tuya',
    description: 'TUYA TS0207 Rain Sensor RB-SRAN01',
    fromZigbee: [tuya.fz.datapoints, fz.battery],
    toZigbee: [],
    onEvent: tuya.onEventSetTime, // Add this if you are getting no converter for 'commandMcuSyncTime'
    configure: tuya.configureMagicPacket,
    exposes: [
        // Here you should put all functionality that your device exposes
        e.water_leak(), e.battery_low(), e.battery(),
        exposes.numeric('illuminance', ea.STATE).withDescription('Raw measured illuminance').withUnit('mV'),
        exposes.numeric('rainIntensity', ea.STATE).withDescription('Raw measured rain intensity').withUnit('mV')
    ],
    meta: {
        // All datapoints go in here
        tuyaDatapoints: [
            [101, 'illuminance', tuya.valueConverter.raw],
            [105, 'rainIntensity', tuya.valueConverter.raw]
        ],
    },
};

module.exports = definition;
Chrisni2 commented 1 month ago

Please excuse my ignorance but I'm very new to HA, but where does this code go?

frankfrommelt commented 1 month ago

This is the integration of the sensor for Zigbee2Mqtt. For ZHA we will need a 'custom quirk'. Sadly I have no idea how to create one.

Chrisni2 commented 1 month ago

Oops, told you I was a newbie.

pbutterworth commented 1 month ago

I tried asking ChatGPT to port the Z2M converter to a ZHA quirk. I added it as a custom quirk, fixed the errors, but it doesn't work (no surprises there).

from zigpy.profiles import zha
from zigpy.quirks import CustomDevice
from zigpy.zcl.clusters.general import Basic, PowerConfiguration
from zigpy.zcl.clusters.measurement import IlluminanceMeasurement

from zhaquirks import CustomCluster
from zhaquirks.tuya import TuyaPowerConfigurationCluster, TuyaManufClusterAttributes

class TuyaRainSensor(CustomDevice):
    """Custom device representing Tuya Rain Sensor."""

    signature = {
        MODELS_INFO: [("_TZ3210_tgvtvdoc", "TS0207")],
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.SIMPLE_SENSOR,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    TuyaManufClusterAttributes.cluster_id,
                    IlluminanceMeasurement.cluster_id,
                ],
                OUTPUT_CLUSTERS: [
                    Basic.cluster_id,
                ],
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.SIMPLE_SENSOR,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    TuyaPowerConfigurationCluster,
                    CustomIlluminanceCluster,
                    CustomRainIntensityCluster,
                ],
                OUTPUT_CLUSTERS: [
                    Basic.cluster_id,
                ],
            },
        },
    }

class CustomIlluminanceCluster(CustomCluster, IlluminanceMeasurement):
    """Custom cluster for illuminance measurement."""

    cluster_id = IlluminanceMeasurement.cluster_id

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.attributes.update({
            0x0400: ('illuminance', t.uint16_t),
        })

    def _update_attribute(self, attrid, value):
        if attrid == 0x0400:
            self.endpoint.device.illuminance = value
        super()._update_attribute(attrid, value)

class CustomRainIntensityCluster(CustomCluster):
    """Custom cluster for rain intensity."""

    cluster_id = 0x0401  # Example cluster ID, replace with appropriate one

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.attributes.update({
            0x0401: ('rainIntensity', t.uint16_t),
        })

    def _update_attribute(self, attrid, value):
        if attrid == 0x0401:
            self.endpoint.device.rainIntensity = value
        super()._update_attribute(attrid, value)
hadeshimself commented 1 month ago

There are more datapoints: https://github.com/Koenkk/zigbee2mqtt/issues/23532

Has anyone began the work on the quirk file?

hadeshimself commented 1 month ago

Here's a quirk that works, but does not expose the secondary measurement values to HA yet. If anyone wants to tackle that it would be great. Pretty much all DP values are DC voltages measured in mV, except for the cleaning reminder.

edit: code removed to avoid confusion. please see new code bellow.

pbutterworth commented 3 weeks ago

Thanks for that @hadeshimself. I've tested this out and can confirm that binary_sensor for moisture reports correctly, but only while the device is in pairing mode (green flashing light). Once the device is out of pairing mode, we never hear from it again. The device appears as red in the network visualisation:

image

Device diagnostics: zha-538856afef528ecfa5f3aa6173859876-_TZ3210_tgvtvdoc TS0207-aa565ac66d71ea26618fcdc8a739c403 (4).json

hadeshimself commented 3 weeks ago

@pbutterworth, could you please try this one and let me know?

"""Quirk for TS0207 rain sensors."""

import zigpy.types as t
from typing import Any, Type
from zigpy.profiles import zha 
from zigpy.quirks import CustomDevice, CustomCluster
from zigpy.zcl.clusters.general import (
    Basic,
    Groups,
    Identify,
    OnOff,
    Ota,
    PowerConfiguration,
    Scenes,
    Time,
)
from zigpy.zcl.clusters.lightlink import LightLink
from zigpy.zcl.clusters.security import IasZone
from zhaquirks.const import (
    DEVICE_TYPE,
    ENDPOINTS,
    INPUT_CLUSTERS,
    MODELS_INFO,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
)
from zhaquirks.tuya.mcu import TuyaMCUCluster
from zhaquirks.tuya import (
    TuyaManufCluster,
    DPToAttributeMapping,
    EnchantedDevice,
    TuyaNoBindPowerConfigurationCluster,
)

ZONE_TYPE = 0x0001

class TuyaSolarRainSensorCluster(TuyaMCUCluster):
    """Tuya manufacturer cluster."""

    attributes = TuyaMCUCluster.attributes.copy()
    attributes.update(
        {
            0xEF65: ("light_intensity", t.uint32_t, True),
            0xEF66: ("average_light_intensity_20mins", t.uint32_t, True),
            0xEF67: ("todays_max_light_intensity", t.uint32_t, True),
            0xEF68: ("cleaning_reminder", t.Bool, True),
            0xEF69: ("rain_sensor_voltage", t.uint32_t, True),
        }
    )

    dp_to_attribute: dict[int, DPToAttributeMapping] = {
        101: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "light_intensity",
        ),
        102: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "average_light_intensity_20mins",
        ),
        103: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "todays_max_light_intensity",
        ),
        104: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "cleaning_reminder",
        ),
        105: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "rain_sensor_voltage",
        ),
    }

    data_point_handlers = {
        101: "_dp_2_attr_update",
        102: "_dp_2_attr_update",
        103: "_dp_2_attr_update",
        104: "_dp_2_attr_update",
        105: "_dp_2_attr_update",
    }

class TuyaIasZone(CustomCluster, IasZone):
    """IAS Zone for rain sensors."""

    _CONSTANT_ATTRIBUTES = {ZONE_TYPE: IasZone.ZoneType.Water_Sensor}

class TuyaSolarRainSensor(EnchantedDevice):
    """TS0207 Rain sensor quirk."""

    signature = {
        MODELS_INFO: [("_TZ3210_tgvtvdoc", "TS0207")],
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.IAS_ZONE,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    IasZone.cluster_id,
                    TuyaMCUCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [
                    Identify.cluster_id,
                    Groups.cluster_id,
                    OnOff.cluster_id,
                    Time.cluster_id,
                    Ota.cluster_id,
                    LightLink.cluster_id,
                ],
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.IAS_ZONE,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaNoBindPowerConfigurationCluster,
                    TuyaIasZone,
                    TuyaSolarRainSensorCluster,
                ],
                OUTPUT_CLUSTERS: [
                    Time.cluster_id,
                    Ota.cluster_id,
                ],
            },
        },
    }
pbutterworth commented 3 weeks ago

@hadeshimself same symptoms. Once the unit stops flashing, there are no further updates. Triggering pairing mode again does not help. The device must be removed and re-added before getting any new updates.

hadeshimself commented 3 weeks ago

Just to make sure you replaced the file and reloaded everything before adding the device again. You should see a TuyaNoBindPowerConfigurationCluster entry in the device clusters.

Did you add this device previously to any other Zigbee hub? Tuya or zigbee2mqtt?

pbutterworth commented 3 weeks ago

@hadeshimself, ah yes, excuse me; my mistake. Failed to save the file (I think) 🤦‍♂️. Take 2:

Outcome: sensor does not update at all, even when the device is in pairing mode (green flashing light).

PS: this device has not been added to any other hub. Tuya: don't have one. Z2M: I'm only using ZHA. PPS: Come to think of it, I have a tuya hub somewhere gathering dust. Shall I try pairing it to that hub, then bring it back to ZHA and see if there is a change of behaviour?

frankfrommelt commented 3 weeks ago

Hey @hadeshimself ,

first of all thank you for that quirk and I guess it is almost the solution (at least for me...).

For me it looks different after adding the quirk, removing the device, restarting HA an re-adding the device it is working quite well. Battery and Rain sensors are exposed. And I have the "TuyaSolarRainSensorCluster".

But I do not see all the other attributes.

The diagnostics shows them as "unsupported attributes".

image image

"data": { "ieee": "REDACTED", "nwk": 6580, "manufacturer": "_TZ3210_tgvtvdoc", "model": "TS0207", "name": "_TZ3210_tgvtvdoc TS0207", "quirk_applied": true, "quirk_class": "Tuya_rain.TuyaSolarRainSensor", "quirk_id": null, "manufacturer_code": 4417, "power_source": "Battery or Unknown", "lqi": 176, "rssi": -56, "last_seen": "2024-08-12T09:08:46", "available": true, "device_type": "EndDevice", "signature": { "node_descriptor": { "logical_type": 2, "complex_descriptor_available": 0, "user_descriptor_available": 0, "reserved": 0, "aps_flags": 0, "frequency_band": 8, "mac_capability_flags": 128, "manufacturer_code": 4417, "maximum_buffer_size": 66, "maximum_incoming_transfer_size": 66, "server_mask": 10752, "maximum_outgoing_transfer_size": 66, "descriptor_capability_field": 0 }, "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x0402", "input_clusters": [ "0x0000", "0x0001", "0x0004", "0x0005", "0x0500", "0xef00" ], "output_clusters": [ "0x000a", "0x0019" ] } }, "manufacturer": "_TZ3210_tgvtvdoc", "model": "TS0207" }, "active_coordinator": false, "entities": [ { "entity_id": "binary_sensor.tz3210_tgvtvdoc_ts0207_feuchtigkeit", "name": "_TZ3210_tgvtvdoc TS0207" }, { "entity_id": "sensor.tz3210_tgvtvdoc_ts0207_batterie", "name": "_TZ3210_tgvtvdoc TS0207" }, { "entity_id": "update.tz3210_tgvtvdoc_ts0207_firmware", "name": "_TZ3210_tgvtvdoc TS0207" }, { "entity_id": "sensor.regensensor_batterie", "name": "_TZ3210_tgvtvdoc TS0207" }, { "entity_id": "binary_sensor.regensensor_feuchtigkeit", "name": "_TZ3210_tgvtvdoc TS0207" }, { "entity_id": "update.regensensor_firmware", "name": "_TZ3210_tgvtvdoc TS0207" } ], "neighbors": [], "routes": [], "endpoint_names": [ { "name": "IAS_ZONE" } ], "user_given_name": "Regensensor", "device_reg_id": "8897db1af17f002c7d17cd98678279d9", "area_id": "draussen", "cluster_details": { "1": { "device_type": { "name": "IAS_ZONE", "id": 1026 }, "profile_id": 260, "in_clusters": { "0x0000": { "endpoint_attribute": "basic", "attributes": { "0x0001": { "attribute_name": "app_version", "value": 67 }, "0x0004": { "attribute_name": "manufacturer", "value": "_TZ3210_tgvtvdoc" }, "0x0005": { "attribute_name": "model", "value": "TS0207" }, "0x0007": { "attribute_name": "power_source", "value": 3 }, "0xfffe": { "attribute_name": "reporting_status", "value": 0 }, "0x0000": { "attribute_name": "zcl_version", "value": 3 } }, "unsupported_attributes": {} }, "0x0001": { "endpoint_attribute": "power", "attributes": { "0x0021": { "attribute_name": "battery_percentage_remaining", "value": 194 }, "0x0020": { "attribute_name": "battery_voltage", "value": 0 } }, "unsupported_attributes": { "0x0031": { "attribute_name": "battery_size" }, "0x0033": { "attribute_name": "battery_quantity" } } }, "0x0004": { "endpoint_attribute": "groups", "attributes": {}, "unsupported_attributes": {} }, "0x0005": { "endpoint_attribute": "scenes", "attributes": {}, "unsupported_attributes": {} }, "0x0500": { "endpoint_attribute": "ias_zone", "attributes": { "0x0010": { "attribute_name": "cie_addr", "value": [ 34, 103, 240, 254, 255, 129, 118, 40 ] }, "0x0000": { "attribute_name": "zone_state", "value": 1 }, "0x0002": { "attribute_name": "zone_status", "value": 0 }, "0x0001": { "attribute_name": "zone_type", "value": 42 } }, "unsupported_attributes": {} }, "0xef00": { "endpoint_attribute": "tuya_manufacturer", "attributes": { "0xef66": { "attribute_name": "average_light_intensity_20mins", "value": 4291 }, "0xef68": { "attribute_name": "cleaning_reminder", "value": 0 }, "0xef65": { "attribute_name": "light_intensity", "value": 4444 }, "0xef69": { "attribute_name": "rain_sensor_voltage", "value": 5 }, "0xef67": { "attribute_name": "todays_max_light_intensity", "value": 4444 } }, "unsupported_attributes": {} } }, "out_clusters": { "0x000a": { "endpoint_attribute": "time", "attributes": {}, "unsupported_attributes": {} }, "0x0019": { "endpoint_attribute": "ota", "attributes": { "0x0002": { "attribute_name": "current_file_version", "value": 67 } }, "unsupported_attributes": {} } } } } } }

pbutterworth commented 3 weeks ago

Quick update: I dusted off an old Tuya gateway and added the rain sensor to that. Check for updates (none), version is V1.0.3. I then removed it from the Tuya gateway, and added it back to ZHA, and observed no change. Note: when adding the device to the Tuya gateway, once the device was added, the pairing mode terminated immediately (unlike ZHA where the pairing mode persists after the handshake is complete). Also, it appears that the rain detection event in the device is an immediate push (tuya app responds immediately). Other attributes update periodically.

hadeshimself commented 3 weeks ago

@pbutterworth did you use the code you received by email or did you copy it from the GitHub page? Because I edited the post with some updated code a few minutes later.

@frankfrommelt yeah, I don’t know how to expose those other attributes. There’s no standard to represent that kind of data, except from some energy related stuff. You would get 4 sensors for Voltage. How to tell them apart? If I had to pick one I would use the rain sensor voltage as it may indicate the intensity of the rain (?).

pbutterworth commented 3 weeks ago

@frankfrommelt when you paired the device, did you notice whether the green light stopped flashing once the ZHA handshake was complete? Or, did the green light keep flashing for another couple of minutes?

hadeshimself commented 3 weeks ago

@pbutterworth, make sure you are using that last code I posted, which includes the enchanted device code (it will have a TuyaNoBindPowerConfigurationCluster cluster shown on the UI). When you trigger your rain sensor do you see a red LED blink on the back? Also, make sure you reload everything and even clear the pycache directory where you have your custom quirk files before adding the device again.

@frankfrommelt, you could try https://github.com/mdeweerd/zha-toolkit meanwhile to read the other values. Setup an action every minute or so to feed a sensor, something like:

action: zha_toolkit.attr_read
data:
  ieee: binary_sensor.rain_sensor_moisture
  cluster: 61184
  attribute: light_intensity
  state_id: sensor.rain_sensor_light_intensity
  allow_create: true
  use_cache: true

Replace "rain_sensor" accordingly.

pbutterworth commented 3 weeks ago

OK, another round of this. BTW @hadeshimself, feel free to step away from this; you've helped a lot already!

Re: red light on moisture detection: yes, once pairing mode has timed out, the red light flashes once when moisture is detected.

image image

Here's a log file that covers (sorry very noisy log file):

hadeshimself commented 3 weeks ago

@pbutterworth, also check if you have the latest coordinator firmware. At one point when debuging I couldn't pair it anymore and it only got back to normal after I updated the firmware. I'm using the Sonoff 3.0 dongle.

pbutterworth commented 3 weeks ago

@pbutterworth, also check if you have the latest coordinator firmware. At one point when debuging I couldn't pair it anymore and it only got back to normal after I updated the firmware. I'm using the Sonoff 3.0 dongle.

@hadeshimself nailed it! silabs firmware was 6.10, updated to 7.4, problem solved. 🤜🤛 Thanks for the quality assistance.

frankfrommelt commented 3 weeks ago

@frankfrommelt, you could try https://github.com/mdeweerd/zha-toolkit meanwhile to read the other values. Setup an action every minute or so to feed a sensor, something like:

action: zha_toolkit.attr_read
data:
  ieee: binary_sensor.rain_sensor_moisture
  cluster: 61184
  attribute: light_intensity
  state_id: sensor.rain_sensor_light_intensity
  allow_create: true
  use_cache: true

Replace "rain_sensor" accordingly.

That is a good workaround.

And this is how I create statistics from the States. As soon as I have a min/max value I will add some calculations to the state.

image

hadeshimself commented 3 weeks ago

@frankfrommelt yes, please let me know the max value you can get. I topped at around 5500.

frankfrommelt commented 3 weeks ago

image

My max value was 4983 and now it is dropping rapidly as some heavy thunderstorms are approaching my area...

frankfrommelt commented 3 weeks ago

OK, I had a maximum of 5492.

In comparison to a real light sensor you can see that the values delivered by the rain sensor are not realistic. I guess it is only calculating a value from the current the solar panel is producing.

image

hadeshimself commented 3 weeks ago

@frankfrommelt, my peak was 5880. But it's really not a good light measurement device. I've also compared it to a real light sensor and it's not even close to the same precision.

Screenshot 2024-08-15 at 08 32 59

wbmk78 commented 3 weeks ago

@hadeshimself thanx a lot! The second quirk seems to work nicely for rain measurement!

manuscho commented 2 weeks ago

I struggle with the same problem for a water leak sensor (Model) which also uses the TS0207 chip.

Same behavior: Works great with generic Tuya hub, connects smoothly with ZHA (through SkyConnect; water leak is correctly showing the first minutes after initial setup), but then never updates again.

The water leak sensor is explicitly mentioned here as compatible with ZHA, which makes the whole thing a bit odd.

pbutterworth commented 1 week ago

I struggle with the same problem for a water leak sensor (Model) which also uses the TS0207 chip.

Same behavior: Works great with generic Tuya hub, connects smoothly with ZHA (through SkyConnect; water leak is correctly showing the first minutes after initial setup), but then never updates again.

The water leak sensor is explicitly mentioned here as compatible with ZHA, which makes the whole thing a bit odd.

Updating the zigbee radio firmware solved these symptoms for me.

HaareistNase commented 1 week ago

OMG. Für einen Zigbee-Anfänger alles Bömische Dörfer^^ For a Zigbee-Beginner is all this bohemian Villages ..

but thanx for your efford. I have the same Sensor and will try to get it work.

First: Create Directory for Quirks. ---> /custom_components/zhaquirks 2nd: Create Quirk-File (how do I name this?). I choose a random name and put the code from @hadeshimself into it. 3rd: Add zha: and directory-location to configuration.yaml. 4th: Restart HA.

Hmmm... not working. More Google.

File renamed after device-Name. Here: TS0207_TZ3210_tgvtvdoc.py

Restart HA

Ah .. now I see "Loaded custom quirks" in Logs. Its going forward. Try to pair the device ... again :-)

Hours later. I manage it to update the firmware of my Zonoff-Stick using https://github.com/mercenaruss/zigstar_addons/blob/main/zigstar-silabs-flasher/README.md Zigstar Addon. Takes so long, because the firmware-zip has a macos-Folder inside it, which brings the TI-firmware-flasher and the Zigstar-Addon out of tune ... removing it solves it.

Now I will try the HACS-ZHA-Integration. I get data from the Rain-Sensor .... "Yippeee". Now to "use" it ... transfer-work for me. I will figure it out.

grafik

Ok. Action for Light-Sensor is running.

`alias: "ZHA: Regensensor Daten abholen" description: "" trigger:

And I get a 5464 in sensor.rain_sensor_light_intensity back and 0 for the rain-voltage (its not raining, seems legit^^). Nice... So what will I do with this Numbers^^ I will figure it out (again).

grafik Could be worse. Thank you all for your effort and sharing. I guess I had this not figured out in weeks without you.

Manuito83 commented 1 week ago

Apologies, but here's a question from an new HA user that doesn't have the knowledge to properly follow what's being done here. All I know is that I bought this same rain/light sensor and can't see any details other than connection status and such (useless for the purpose I bought it for).

So here's the question: is this issue, and its solution, something that will be merged and eventually reach the end-user of Home Assistant? Is there a way I can follow the process? Or should I really look into making manual changes to the configuration (as explained above) to make this work in the medium-term future?

Thanks!

HaareistNase commented 1 week ago

Maybe (I have not tryed) you can reach the sensor over the Cloud-Based Tuya Integration for Home-Assistant. Very simple. Just install the Tuya-App on your phone/tablet, connect the sensor, and use the official Tuya-Integration in Home-Assist to reach the sensor.

The Drawback: Cloud-Based. If the Tuya-App does not work, because the Servers of Tuya failed. You get no Data. If the Tuya-App decides to Update the Sensor every 30 Minutes, than you get Data every 30 Minutes, not every 5 Minutes. And if Tuya decides to remove the support for this device: Elektro-Schrott.

Thats the reason we do the complicated way. No Cloud. No addiction to someone else.

frankfrommelt commented 1 week ago

OK,, I was lucky and the device did what it was intended to (telling me if rain is falling or not) out of the box with my Skyconnect ZigBee stick. And, looking atz the data the device provides, from my perspective the rest of the information is mostly useless... The light intensity reported by the device is depending on the amount of electricity that is being generated by the solar cell. and, looking at my screen shot two weeks ago is telling you something like "it is night or day" (in comparison to a real light sensor). The rain intensity is pretty similar as it is based on the resistance between the two metal wires on the outside. This ist not rain intensity at all. So, except it is great to have the ability to extract all these bits of information from a ZigBee device, from my opinion most information ist useless as it is VERY inaccurate.

hadeshimself commented 1 week ago

I'm not happy with the moisture sensor not clearing fast enough (sometimes remains 'wet' hours after the rain stops, even with the sensor tilted more than 45 degrees). I was trying to correlate the rain sensor voltage with the moisture sensor to create a new binary sensor that is more accurate. That's only a plan, I don't have enough data yet.

I've noticed that during the night condensation might build on the sensor and that raises the sensor voltage considerably.

pbutterworth commented 1 week ago

I'm not happy with the moisture sensor not clearing fast enough (sometimes remains 'wet' hours after the rain stops, even with the sensor tilted more than 45 degrees). I was trying to correlate the rain sensor voltage with the moisture sensor to create a new binary sensor that is more accurate. That's only a plan, I don't have enough data yet.

I've noticed that during the night condensation might build on the sensor and that raises the sensor voltage considerably.

What you need to combat this situation is a heated rain sensor, which is what would be used in an industrial situation. The aren't any wireless ones of these given their increase power demands.

HaareistNase commented 1 week ago

After the hassle with the cheap Zigbee-Sensor, which data is only good for guesses (or when to open or close windows), I changed for a Cheap Ecowitt-Clone.

Its not that much more money, and you have installed it into Home-Assistant in minutes. And it has a working Rain-Sensor^^

https://www.expondo.de/steinberg-systems-wifi-wetterstation-aussensensor-innensensor-10030583

grafik

budcalloway commented 1 week ago

Hi ! I'm the new owner of the TS0207 and have data on rain but nothing on illuminance. It remains at 0 mV. Do you have encountered this issue ? Thx

frankfrommelt commented 1 week ago

I have a similar weather station running for years and integrated into HA.

You are right, they deliver good rain measurements.

But, at least for my weather station, the rain sensor has one disadvantage!:

There has to be a certain (not too low) amount of rain for the device to count an trigger.

My rain sensor very often is missing light rain. And then the garage doors do not close when it rains and I get into trouble...

--- Original Nachricht --- Von: HaareistNase @. Datum: 31. August 2024 12:27:56 An: zigpy/zha-device-handlers @. CC: Frank Frommelt @., Mention @. Betreff: Re: [zigpy/zha-device-handlers] [Device Support Request] Tuya rainsensor TS0207_TZ3210_tgvtvdoc (Issue #3249)

After the hassle with the cheap Zigbee-Sensor, which data is only good for guesses (or when to open or close windows), I changed for a Cheap Ecowitt-Clone. Its not that much more money, and you have installed it into Home-Assistant in minutes. And it has a working Rain-Sensor^^https://www.expondo.de/steinberg-systems-wifi-wetterstation-aussensensor-innensensor-10030583 grafik.png (view on web) — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

wsegatto commented 3 days ago

ChatGPT told me that the quirk was not exposing all parameters mapped in the quirk as sensors (?). It even gave me a new code to try out but it didn't work, back to square one where we see the generic "Motion/Opening" entities. I am able to read the values through the "Manage zigbee device" option with the original quirk (non-GenAI'ed). Perhaps it's just a matter of enhancing it a little bit to get all the other values? I'm running HA Yellow with the Silicon Labs radio (ezsp_version='7.4.3.0'), but I'm new to zigbee so not sure the radio should impact the mapping of entities here since the attributes are readable...

Any help is appreciated. Here are some screenshots:

image

image

image

image

image

wsegatto commented 3 days ago

After the hassle with the cheap Zigbee-Sensor, which data is only good for guesses (or when to open or close windows), I changed for a Cheap Ecowitt-Clone.

Its not that much more money, and you have installed it into Home-Assistant in minutes. And it has a working Rain-Sensor^^

https://www.expondo.de/steinberg-systems-wifi-wetterstation-aussensensor-innensensor-10030583

Do you have any plans to come to Brazil and bring me one? Wünderbar! :)

hadeshimself commented 2 days ago

I can't believe the ChatGPT code didn't work! :-)

I didn't bother exposing those values because they are pretty much useless, but it's rather easy to do that. Most (all?) values are mV measurements, but I wouldn't bother using an electricity class for that. I would just implement them as AnalogInput and let the user deal with values as they wish.

I will try to work on that in the future.

wsegatto commented 2 days ago

Hahhaha. :) If you could provide some directions on how I could do it myself, it would be much appreciated. I look at the code and I don't see where the Wet/Dry parameter gets exposed at all. :( A kick-start and I could maybe make this work for us. I think (only) a binary sensor wet/dry is not so appropriate sometimes e.g. if you have dew in the night it would trigger the sensor and would stay like that for a long time until the sun dries it out middle morning next day. :D

On Thu, Sep 5, 2024 at 1:37 PM Luis Balbinot @.***> wrote:

I can't believe the ChatGPT code didn't work! :-)

I didn't bother exposing those values because they are pretty much useless, but it's rather easy to do that. Most (all?) values are mV measurements, but I wouldn't bother using an electricity class for that. I would just implement them as AnalogInput and let the user deal with values as they wish.

I will try to work on that in the future.

— Reply to this email directly, view it on GitHub https://github.com/zigpy/zha-device-handlers/issues/3249#issuecomment-2332186554, or unsubscribe https://github.com/notifications/unsubscribe-auth/AIQVI2NK7XZYPRRH7TFABETZVCCGHAVCNFSM6AAAAABKY3CGOSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMZSGE4DMNJVGQ . You are receiving this because you commented.Message ID: @.***>

--

Will

hadeshimself commented 2 days ago

The wet/dry sensor is exposed using a standard TuyaIasZone cluster. I only change the zone type to IasZone.ZoneType.Water_Sensor to make it appear as a water sensor. The other parameters are exposed on the Tuya manufacturer cluster (0xef00) and are exposed as-is for now.