Open dethegeek opened 2 months ago
Hi @dethegeek I bought the same valve but unfortunately I cannot integrate it successfully as suggestedabove. I copied the quirk file adding the model and I see it in HA with only switch e battery sensor. the problem is that the switch doesn't work (like the valve ignores it) an battery is unknown. same behaviour with 2 identical valves. have I missed anything?
I added _TZE200_7ytb3h8u
to line 384. No idea how to report this, so I'll just comment it here, and hope a grown-up can assist. It's for this unit: https://www.aliexpress.com/item/1005006547328147.html?spm=a2g0o.order_list.order_list_main.4.787f18021Qrnq9
MODELS_INFO: [("_TZE200_sh1btabb", "TS0601"), ("_TZE200_a7sghmms", "TS0601"), ( "_TZE200_7ytb3h8u", "TS0601"), ( "_TZE204_7ytb3h8u", "TS0601")],
Hi @jaggaer-alocatel
On my side I can switch the state of my device.
However I noticed some issues
Hi @liksvette
My device looks the same as yours.
Hi @jaggaer-alocatel
On my side I can switch the state of my device.
However I noticed some issues
- Battery level is often reported 200% or sometimes 400%. It usually drops to 100% when I switch on the device, and since a few days it dropped to 90% (seems legit, depite the battery is drained quite fast).
- Instant water delivery is empty
- Summation of delivered water is reset to zero when I switch on the device again.
sorry, it was by bad... wrong change in the file. Now my devices look as ours. Thanks a lot
Hi @liksvette
My device looks the same as yours.
Your code snippet had _TZE204 as opposed to _TZE200, so it didn't work on mine.
@liksvette the code snippet is the original line (this is a reference to the line in the repository). You just need to add the device in it.
The result should look like this
MODELS_INFO: [("_TZE200_sh1btabb", "TS0601"), ("_TZE200_a7sghmms", "TS0601"), ( "_TZE204_7ytb3h8u", "TS0601"), ( "_TZE200_7ytb3h8u", "TS0601")],
Problem description
Similar device aded to solve the following issue #3124
My device is detected as TS0601 _TZE200_7ytb3h8u
Bought here: https://fr.aliexpress.com/item/1005006548852233.html
Solution description
I succesfully aded the device by adding the above model in https://github.com/zigpy/zha-device-handlers/blob/c6ed94a52a469e72b32ece2a92d528060c7fd034/zhaquirks/tuya/ts0601_valve.py#L384
I'm rather new with domotic and Home Assistant, I'm not skilled enough to get a zigbee to MQTT dump for now, then I did a try after roughly understanding how the ZHA quirks works.
Screenshots/Video
Screenshots/Video
[Paste/upload your media here]Device signature
Device signature
```json { "node_descriptor": "NodeDescriptor(logical_type=Diagnostic information
Diagnostic information
```json { "home_assistant": { "installation_type": "Home Assistant Container", "version": "2024.6.2", "dev": false, "hassio": false, "virtualenv": false, "python_version": "3.12.2", "docker": true, "arch": "aarch64", "timezone": "Europe/Paris", "os_name": "Linux", "os_version": "6.2.0-1018-raspi", "run_as_root": true }, "custom_components": {}, "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.0", "pyserial==3.5", "zha-quirks==0.0.116", "zigpy-deconz==0.23.1", "zigpy==0.64.0", "zigpy-xbee==0.20.1", "zigpy-zigate==0.12.0", "zigpy-znp==0.12.1", "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*" } ], "is_built_in": true }, "setup_times": { "null": { "setup": 0.00021338602527976036 }, "0ffe77e8ceb946efe67b9ae06341980c": { "wait_import_platforms": -0.0004412168636918068, "wait_base_component": -0.001689257100224495, "config_entry_setup": 13.71825297595933 } }, "data": { "ieee": "**REDACTED**", "nwk": 47845, "manufacturer": "_TZE200_7ytb3h8u", "model": "TS0601", "name": "_TZE200_7ytb3h8u TS0601", "quirk_applied": true, "quirk_class": "ts0601_valve.GiexValve", "quirk_id": null, "manufacturer_code": 4417, "power_source": "Battery or Unknown", "lqi": null, "rssi": null, "last_seen": "2024-06-16T16:15:49", "available": true, "device_type": "EndDevice", "signature": { "node_descriptor": "NodeDescriptor(logical_type=Logs
Logs
```python [Paste the logs here] ```Custom quirk
ts0601_valve.py
```python """Collection of Tuya Valve devices e.g. water valves, gas valve etc.""" from zigpy.profiles import zha from zigpy.quirks import CustomDevice import zigpy.types as t from zigpy.zcl import foundation from zigpy.zcl.clusters.general import Basic, Groups, Identify, OnOff, Ota, Scenes, Time from zigpy.zcl.clusters.smartenergy import Metering from zhaquirks import DoublingPowerConfigurationCluster from zhaquirks.const import ( DEVICE_TYPE, ENDPOINTS, INPUT_CLUSTERS, MODELS_INFO, OUTPUT_CLUSTERS, PROFILE_ID, ) from zhaquirks.tuya import EnchantedDevice, TuyaLocalCluster from zhaquirks.tuya.mcu import ( DPToAttributeMapping, TuyaMCUCluster, TuyaOnOff, TuyaOnOffNM, TuyaPowerConfigurationCluster, ) class TuyaValveWaterConsumed(Metering, TuyaLocalCluster): """Tuya Valve Water consumed cluster.""" VOLUME_LITERS = 0x0007 WATER_METERING = 0x02 """Setting unit of measurement.""" _CONSTANT_ATTRIBUTES = { 0x0300: VOLUME_LITERS, 0x0306: WATER_METERING, } class TuyaValveManufCluster(TuyaMCUCluster): """On/Off Tuya cluster with extra device attributes.""" attributes = TuyaMCUCluster.attributes.copy() attributes.update( { 0xEF01: ("time_left", t.uint32_t, True), 0xEF02: ("state", t.enum8, True), 0xEF03: ("last_valve_open_duration", t.uint32_t, True), 0xEF04: ("dp_6", t.uint32_t, True), 0xEF05: ("valve_position", t.uint32_t, True), } ) dp_to_attribute: dict[int, DPToAttributeMapping] = { 1: DPToAttributeMapping( TuyaOnOff.ep_attribute, "on_off", ), 5: DPToAttributeMapping( TuyaValveWaterConsumed.ep_attribute, "current_summ_delivered", ), 6: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "dp_6", ), 7: DPToAttributeMapping( DoublingPowerConfigurationCluster.ep_attribute, "battery_percentage_remaining", ), 11: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "time_left", ), 12: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "state", ), 15: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "last_valve_open_duration", ), 102: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "valve_position", ), } data_point_handlers = { 1: "_dp_2_attr_update", 5: "_dp_2_attr_update", 6: "_dp_2_attr_update", 7: "_dp_2_attr_update", 11: "_dp_2_attr_update", 12: "_dp_2_attr_update", 15: "_dp_2_attr_update", 102: "_dp_2_attr_update", } class TuyaValve(CustomDevice): """Tuya valve device.""" signature = { MODELS_INFO: [("_TZE200_81isopgh", "TS0601")], # SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=81, device_version=1, # input_clusters=[0, 4, 5, 61184], output_clusters=[25, 10]) ENDPOINTS: { 1: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.SMART_PLUG, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, TuyaValveManufCluster.cluster_id, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], } }, } replacement = { ENDPOINTS: { 1: { DEVICE_TYPE: zha.DeviceType.SMART_PLUG, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, TuyaOnOff, TuyaValveWaterConsumed, DoublingPowerConfigurationCluster, TuyaValveManufCluster, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], } } } class BasicTuyaValve(CustomDevice): """Basic Tuya valve device.""" signature = { MODELS_INFO: [("_TZE200_1n2zev06", "TS0601")], # SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=81, device_version=1, # input_clusters=[0, 4, 5, 61184], output_clusters=[25, 10]) ENDPOINTS: { 1: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.SMART_PLUG, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, TuyaValveManufCluster.cluster_id, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], } }, } replacement = { ENDPOINTS: { 1: { DEVICE_TYPE: zha.DeviceType.SMART_PLUG, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, TuyaOnOff, TuyaValveManufCluster, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], } } } class ParksideTuyaValveManufCluster(TuyaMCUCluster): """Manufacturer Specific Cluster for the _TZE200_htnnfasr water valve sold as PARKSIDE.""" attributes = TuyaMCUCluster.attributes.copy() attributes.update( { 0xEF11: ("timer_duration", t.uint32_t, True), 0xEF12: ("timer_time_left", t.uint32_t, True), 0xEF13: ("frost_lock", t.Bool, True), 0xEF14: ("frost_lock_reset", t.Bool, True), # 0 resets frost lock } ) dp_to_attribute: dict[int, DPToAttributeMapping] = { 1: DPToAttributeMapping( TuyaOnOff.ep_attribute, "on_off", ), 5: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "timer_duration", ), 6: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "timer_time_left", ), 11: DPToAttributeMapping( TuyaPowerConfigurationCluster.ep_attribute, "battery_percentage_remaining", ), 108: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "frost_lock", lambda x: not x, # invert for lock entity ), 109: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "frost_lock_reset", ), } data_point_handlers = { 1: "_dp_2_attr_update", 5: "_dp_2_attr_update", 6: "_dp_2_attr_update", 11: "_dp_2_attr_update", 108: "_dp_2_attr_update", 109: "_dp_2_attr_update", } async def bind(self): """Bind cluster. When adding this device tuya gateway issues factory reset, we just need to reset the frost lock, because its state is unknown to us. """ result = await super().bind() await self.write_attributes({self.attributes_by_name["frost_lock_reset"].id: 0}) return result class ParksidePSBZS(EnchantedDevice): """LIDL Parkside water without implemented scheduler.""" signature = { MODELS_INFO: [("_TZE200_htnnfasr", "TS0601")], # HG06875 ENDPOINTS: { #Additional information
Enable / disable test done
No response