Closed dustinbvh closed 8 months ago
I'm using this custom quirk that I wrote:
Notes:
There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates. Please make sure to update to the latest version and check if that solves the issue. Let us know if that works for you by adding a comment 👍 This issue has now been marked as stale and will be closed if no further activity occurs. Thank you for your contributions.
Problem description
There is already a script which works (kind of). The script creates a on/off switch and a battery percentage. The battery only returns 0% (solar+battery powered product) & the switch only 'switches' when u physically push the button on the device. If you use the switch in home assistant, the log updates but the device does nothing.
Log for switching within home assistant: <- device does nothing
Log for switching by clicking the device button: <- home assistant switch does change state active/inactive
Used script (added the modelnumber): https://github.com/zigpy/zha-device-handlers/blob/dev/zhaquirks/tuya/ts0601_valve.py
Solution description
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 OS", "version": "2023.4.5", "dev": false, "hassio": true, "virtualenv": false, "python_version": "3.10.10", "docker": true, "arch": "aarch64", "timezone": "Europe/Amsterdam", "os_name": "Linux", "os_version": "6.1.21-v8", "supervisor": "2023.08.1", "host_os": "Home Assistant OS 10.0", "docker_version": "23.0.3", "chassis": "embedded", "run_as_root": true }, "custom_components": {}, "integration_manifest": { "domain": "zha", "name": "Zigbee Home Automation", "after_dependencies": [ "onboarding", "usb" ], "codeowners": [ "@dmulcahey", "@adminiuga", "@puddly" ], "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" ], "requirements": [ "bellows==0.35.1", "pyserial==3.5", "pyserial-asyncio==0.6", "zha-quirks==0.0.97", "zigpy-deconz==0.20.0", "zigpy==0.54.1", "zigpy-xbee==0.17.0", "zigpy-zigate==0.10.3", "zigpy-znp==0.10.0" ], "usb": [ { "vid": "10C4", "pid": "EA60", "description": "*2652*", "known_devices": [ "slae.sh cc2652rb stick" ] }, { "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": "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": "_slzb-06._tcp.local.", "name": "slzb-06*" } ], "is_built_in": true }, "data": { "ieee": "**REDACTED**", "nwk": 63795, "manufacturer": "_TZE200_anv5ujhv", "model": "TS0601", "name": "_TZE200_anv5ujhv TS0601", "quirk_applied": true, "quirk_class": "ts0601_valve.GiexValve", "manufacturer_code": 4417, "power_source": "Battery or Unknown", "lqi": 255, "rssi": -64, "last_seen": "2023-08-23T14:19:40", "available": true, "device_type": "EndDevice", "signature": { "node_descriptor": "NodeDescriptor(logical_type=Logs
Logs
```python _TZE200_anv5ujhv TS0601 Switch is ingeschakeld getriggerd door service switch.turn_on 14:24:12 - 11 minuten geleden - dustinbvh _TZE200_anv5ujhv TS0601 Switch is uitgeschakeld getriggerd door service switch.turn_off 14:24:10 - 11 minuten geleden - dustinbvh _TZE200_anv5ujhv TS0601 Switch is ingeschakeld 14:23:57 - 11 minuten geleden _TZE200_anv5ujhv TS0601 Switch is uitgeschakeld 14:23:44 - 12 minuten geleden _TZE200_anv5ujhv TS0601 Switch is ingeschakeld getriggerd door service switch.turn_off 14:23:34 - 12 minuten geleden - dustinbvh _TZE200_anv5ujhv TS0601 Switch is uitgeschakeld getriggerd door service switch.turn_off 14:23:30 - 12 minuten geleden - dustinbvh _TZE200_anv5ujhv TS0601 Switch is ingeschakeld getriggerd door service switch.turn_on ```Custom quirk
Custom quirk
```python """Collection of Tuya Valve devices e.g. water valves, gas valve etc.""" from typing import Dict 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 TuyaLocalCluster from zhaquirks.tuya.mcu import ( DPToAttributeMapping, EnchantedDevice, 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), } ) 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", ), } 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", } class TuyaValve(CustomDevice): """Tuya valve device.""" signature = { MODELS_INFO: [("_TZE200_anv5ujhv", "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, TuyaOnOffNM, TuyaValveWaterConsumed, TuyaPowerConfigurationCluster, DoublingPowerConfigurationCluster, 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_anv5ujhv", "TS0601")], # HG06875 ENDPOINTS: { #Additional information
I have tried multiple instances (found online) but this is the only one with actual visual results.