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
721 stars 670 forks source link

[Device Support Request] TS0601 TZE200_sh1btabb Tuya Garden Water Valve #1622

Closed MQTT-ESP8266 closed 1 year ago

MQTT-ESP8266 commented 2 years ago

I cannot get this Tuya water valve to run. There are no entities shown in the device manager.

It would be great if this device could be added to tuva quirks so that it is usable with ZHA. There already exists a solution for zigbee2mqtt (link below). Maybe that makes it easier.

``` { "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": 260, "device_type": "0x0051", "in_clusters": [ "0x0000", "0x0004", "0x0005", "0xef00" ], "out_clusters": [ "0x000a", "0x0019" ] } }, "manufacturer": "_TZE200_sh1btabb", "model": "TS0601", "class": "zigpy.device.Device" } ```
```yaml { "home_assistant": { "installation_type": "Home Assistant OS", "version": "2022.5.5", "dev": false, "hassio": true, "virtualenv": false, "python_version": "3.9.9", "docker": true, "arch": "x86_64", "timezone": "Europe/Berlin", "os_name": "Linux", "os_version": "5.15.45", "supervisor": "2022.05.3", "host_os": "Home Assistant OS 8.2", "docker_version": "20.10.14", "chassis": "vm", "run_as_root": true }, "custom_components": {}, "integration_manifest": { "domain": "zha", "name": "Zigbee Home Automation", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/zha", "requirements": [ "bellows==0.29.0", "pyserial==3.5", "pyserial-asyncio==0.6", "zha-quirks==0.0.73", "zigpy-deconz==0.16.0", "zigpy==0.45.1", "zigpy-xbee==0.14.0", "zigpy-zigate==0.7.4", "zigpy-znp==0.7.0" ], "usb": [ { "vid": "10C4", "pid": "EA60", "description": "*2652*", "known_devices": [ "slae.sh cc2652rb stick" ] }, { "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": "10C4", "pid": "8B34", "description": "*bv 2010/10*", "known_devices": [ "Bitron Video AV2010/10" ] } ], "codeowners": [ "@dmulcahey", "@adminiuga" ], "zeroconf": [ { "type": "_esphomelib._tcp.local.", "name": "tube*" } ], "after_dependencies": [ "usb", "zeroconf" ], "iot_class": "local_polling", "loggers": [ "aiosqlite", "bellows", "crccheck", "pure_pcapy3", "zhaquirks", "zigpy", "zigpy_deconz", "zigpy_xbee", "zigpy_zigate", "zigpy_znp" ], "is_built_in": true }, "data": { "ieee": "**REDACTED**", "nwk": 30371, "manufacturer": "_TZE200_sh1btabb", "model": "TS0601", "name": "_TZE200_sh1btabb TS0601", "quirk_applied": false, "quirk_class": "zigpy.device.Device", "manufacturer_code": 4417, "power_source": "Battery or Unknown", "lqi": null, "rssi": null, "last_seen": "2022-06-14T21:08:59", "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": 260, "device_type": "0x0051", "in_clusters": [ "0x0000", "0x0004", "0x0005", "0xef00" ], "out_clusters": [ "0x000a", "0x0019" ] } } }, "entities": [], "neighbors": [], "endpoint_names": [ { "name": "SMART_PLUG" } ], "user_given_name": null, "device_reg_id": "4a2865a9419105f14f181082bdc80c34", "area_id": "garten" } } ```
Additional logs ``` [0x0000:zdo] ZDO request ZDOCmd.Mgmt_Permit_Joining_req: [60, ] New device 0x7ca8 (a4:c1:38:4a:ea:11:11:2f) joined the network [0x7ca8] Scheduling initialization Tries remaining: 3 [0x7ca8] Requesting 'Node Descriptor' Tries remaining: 2 [0x7ca8] Extending timeout for 0x2d request [0xA546](TS0201): Device seen - marking the device available and resetting counter [0xA546](TS0201): Update device availability - device available: True - new availability: True - changed: False [0x2ADE](MS01): Device seen - marking the device available and resetting counter [0x2ADE](MS01): Update device availability - device available: True - new availability: True - changed: False Device 0x7ca8 (a4:c1:38:4a:ea:11:11:2f) joined the network [0x7ca8] Scheduling initialization [0x7ca8] Canceling old initialize call Tries remaining: 3 [0x7ca8] Requesting 'Node Descriptor' Tries remaining: 2 [0x7ca8] Extending timeout for 0x2f request Device 0x7ca8 (a4:c1:38:4a:ea:11:11:2f) joined the network [0x7ca8] Scheduling initialization [0x7ca8] Canceling old initialize call Received frame on uninitialized device from ep 0 to ep 0, cluster 19: b"'\xa8|/\x11\x11\xeaJ8\xc1\xa4\x80" [0x7ca8:zdo] ZDO request ZDOCmd.Device_annce: [0x7CA8, a4:c1:38:4a:ea:11:11:2f, 128] Tries remaining: 3 [0x7ca8] Requesting 'Node Descriptor' Tries remaining: 2 [0x7ca8] Extending timeout for 0x31 request Received frame on uninitialized device from ep 0 to ep 0, cluster 32770: b'/\x00\xa8|\x02@\x80A\x11BB\x00\x00*B\x00\x00' Received frame on uninitialized device from ep 0 to ep 0, cluster 32770: b'1\x00\xa8|\x02@\x80A\x11BB\x00\x00*B\x00\x00' [0x7ca8] Got 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) [0x7ca8] Discovering endpoints Tries remaining: 3 [0x7ca8] Extending timeout for 0x33 request Received frame on uninitialized device from ep 0 to ep 0, cluster 32773: b'3\x00\xa8|\x01\x01' [0x7ca8] Discovered endpoints: [1] [0x7ca8] Initializing endpoints [>] [0x7ca8:1] Discovering endpoint information Tries remaining: 3 [0x7ca8] Extending timeout for 0x35 request Received frame on uninitialized device from ep 0 to ep 0, cluster 2: b'(\x00\x00' [0x7ca8:zdo] ZDO request ZDOCmd.Node_Desc_req: [0x0000] [0x7ca8:zdo] No handler for ZDO request:ZDOCmd.Node_Desc_req([0x0000]) Received frame on uninitialized device from ep 0 to ep 0, cluster 32772: b'5\x00\xa8|\x14\x01\x04\x01Q\x00\x01\x04\x04\x00\x05\x00\x00\xef\x00\x00\x02\x19\x00\n\x00' [0x7ca8:1] Discovered endpoint information: SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=81, device_version=1, input_clusters=[4, 5, 61184, 0], output_clusters=[25, 10]) Unknown cluster 0xEF00 [0x7CA8:1:0x0000] Sending request header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=False, is_reply=0, disable_default_response=0, reserved=0, *is_cluster=False, *is_general=True), tsn=55, command_id=, *is_reply=False) [0x7CA8:1:0x0000] Sending request: Read_Attributes(attribute_ids=[4, 5]) [0x7ca8] Extending timeout for 0x37 request [0x7ca8:zdo] ZDO request ZDOCmd.Mgmt_Permit_Joining_req: [180, ] [0x7CA8:1:0x0000] Received ZCL frame: b'\x187\x01\x04\x00\x00B\x10_TZE200_sh1btabb\x05\x00\x00B\x06TS0601' [0x7CA8:1:0x0000] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=55, command_id=1, *is_reply=True) [0x7CA8:1:0x0000] Decoded ZCL frame: Basic:Read_Attributes_rsp(status_records=[ReadAttributeRecord(attrid=0x0004, status=, value=TypeValue(type=CharacterString, value='_TZE200_sh1btabb')), ReadAttributeRecord(attrid=0x0005, status=, value=TypeValue(type=CharacterString, value='TS0601'))]) [0x7ca8] Read model 'TS0601' and manufacturer '_TZE200_sh1btabb' from > [0x7ca8] Discovered basic device information for Device is initialized Checking quirks for _TZE200_sh1btabb TS0601 (a4:c1:38:4a:ea:11:11:2f) Considering Fail because endpoint list mismatch: {232, 230} {1} Considering Fail because endpoint list mismatch: {232, 230} {1} Considering Fail because device_type mismatch on at least one endpoint Considering Fail because device_type mismatch on at least one endpoint Considering Fail because device_type mismatch on at least one endpoint Considering Fail because endpoint list mismatch: {11, 13} {1} Considering Fail because device_type mismatch on at least one endpoint 'sensor' component -> 'RSSISensor' using ['basic'] 'sensor' component -> 'LQISensor' using ['basic'] device - 0x7CA8:a4:c1:38:4a:ea:11:11:2f entering async_device_initialized - is_new_join: True device - 0x7CA8:a4:c1:38:4a:ea:11:11:2f has joined the ZHA zigbee network [0x7CA8](TS0601): started configuration [0x7CA8:ZDO](TS0601): 'async_configure' stage succeeded Error handling '_save_attribute' event with (a4:c1:38:4a:ea:11:11:2f, 1, 0, 4, '_TZE200_sh1btabb') params: FOREIGN KEY constraint failed [0x7CA8:1:0x0000]: Configuring cluster attribute reporting [0x7CA8:1:0x0000]: finished channel configuration [0x7CA8:1:0x0019]: finished channel configuration Error handling '_save_attribute' event with (a4:c1:38:4a:ea:11:11:2f, 1, 0, 5, 'TS0601') params: FOREIGN KEY constraint failed [0x7CA8:1:0x0000]: 'async_configure' stage succeeded [0x7CA8:1:0x0019]: 'async_configure' stage succeeded [0x7CA8](TS0601): completed configuration [0x7CA8](TS0601): stored in registry: ZhaDeviceEntry(name='_TZE200_sh1btabb TS0601', ieee='a4:c1:38:4a:ea:11:11:2f', last_seen=1655237424.153496) [0x7CA8](TS0601): started initialization [0x7CA8:ZDO](TS0601): 'async_initialize' stage succeeded [0x7CA8:1:0x0000]: initializing channel: from_cache: False [0x7CA8:1:0x0000]: finished channel initialization [0x7CA8:1:0x0019]: initializing channel: from_cache: False [0x7CA8:1:0x0019]: finished channel initialization [0x7CA8:1:0x0000]: 'async_initialize' stage succeeded [0x7CA8:1:0x0019]: 'async_initialize' stage succeeded [0x7CA8](TS0601): power source: Battery or Unknown [0x7CA8](TS0601): completed initialization [0x7CA8:1:0xef00] Received ZCL frame: b'\t\x95\x11\x00o@' [0x7CA8:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=149, command_id=17, *is_reply=True) [0x7CA8:1:0xef00] Unknown cluster command 17 b'\x00o@' [0x7CA8:1:0xef00] Received command 0x11 (TSN 149): b'\x00o@' [0x7CA8:1:0xef00] No explicit handler for cluster command 0x11: b'\x00o@' [0x7CA8:1:0xef00] Received ZCL frame: b'\t\x95\x11\x00o@' [0x7CA8:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=149, command_id=17, *is_reply=True) [0x7CA8:1:0xef00] Unknown cluster command 17 b'\x00o@' [0x7CA8:1:0xef00] Received command 0x11 (TSN 149): b'\x00o@' [0x7CA8:1:0xef00] No explicit handler for cluster command 0x11: b'\x00o@' [0x7CA8:1:0xef00] Received ZCL frame: b'\t\x95\x11\x00o@' [0x7CA8:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=149, command_id=17, *is_reply=True) [0x7CA8:1:0xef00] Unknown cluster command 17 b'\x00o@' [0x7CA8:1:0xef00] Received command 0x11 (TSN 149): b'\x00o@' [0x7CA8:1:0xef00] No explicit handler for cluster command 0x11: b'\x00o@' [0x7C3F](TH01): Device seen - marking the device available and resetting counter [0x7C3F](TH01): Update device availability - device available: True - new availability: True - changed: False [0x7CA8:1:0x0000] Received ZCL frame: b'\x08\x96\n\x01\x00 F\xe2\xff 6\xe4\xff \x00' [0x7CA8:1:0x0000] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=False, *is_general=True), tsn=150, command_id=10, *is_reply=True) [0x7CA8:1:0x0000] Decoded ZCL frame: Basic:Report_Attributes(attribute_reports=[Attribute(attrid=0x0001, value=TypeValue(type=uint8_t, value=70)), Attribute(attrid=0xFFE2, value=TypeValue(type=uint8_t, value=54)), Attribute(attrid=0xFFE4, value=TypeValue(type=uint8_t, value=0))]) [0x7CA8:1:0x0000] Received command 0x0A (TSN 150): Report_Attributes(attribute_reports=[Attribute(attrid=0x0001, value=TypeValue(type=uint8_t, value=70)), Attribute(attrid=0xFFE2, value=TypeValue(type=uint8_t, value=54)), Attribute(attrid=0xFFE4, value=TypeValue(type=uint8_t, value=0))]) [0x7CA8:1:0x0000] Attribute report received: app_version=70, 0xFFE2=54, 0xFFE4=0 [0x7CA8:1:0x0000] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=150, command_id=, *is_reply=True) [0x7CA8:1:0x0000] Sending reply: Default_Response(command_id=10, status=) [0x7CA8:1:0x000a] Received ZCL frame: b'\x00\x97\x00\x07\x00' [0x7CA8:1:0x000a] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=0, disable_default_response=0, reserved=0, *is_cluster=False, *is_general=True), tsn=151, command_id=0, *is_reply=False) [0x7CA8:1:0x000a] Decoded ZCL frame: Time:Read_Attributes(attribute_ids=[7]) [0x7CA8:1:0x000a] Received command 0x00 (TSN 151): Read_Attributes(attribute_ids=[7]) [0x7CA8:1:0x000a] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=151, command_id=, *is_reply=True) [0x7CA8:1:0x000a] Sending reply: Read_Attributes_rsp(status_records=[ReadAttributeRecord(attrid=0x0007, status=, value=TypeValue(type=LocalTime, value=708559831))]) [0x7CA8:1:0x0000] Received ZCL frame: b'\x08\x98\n\xdf\xffB<\xc7\xc2;*i\xcd\xc2;*i\xe0\xc2;*i\xea\xc2;*i\xf4\xc2;*i\xfe\xc2;*i\x08\xc3;*i\xa9\xc3;*\x13\xa9\xc3;*e\xaa\xc3;*\x12\xc8\xc3;*er\xc2;*i' [0x7CA8:1:0x0000] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=False, *is_general=True), tsn=152, command_id=10, *is_reply=True) [0x7CA8:1:0x0000] Decoded ZCL frame: Basic:Report_Attributes(attribute_reports=[Attribute(attrid=0xFFDF, value=TypeValue(type=CharacterString, value='��;*i��;*i��;*i��;*i��;*i��;*i\x08�;*i��;*\x13��;*e��;*\x12��;*er�;*i'))]) [0x7CA8:1:0x0000] Received command 0x0A (TSN 152): Report_Attributes(attribute_reports=[Attribute(attrid=0xFFDF, value=TypeValue(type=CharacterString, value='��;*i��;*i��;*i��;*i��;*i��;*i\x08�;*i��;*\x13��;*e��;*\x12��;*er�;*i'))]) [0x7CA8:1:0x0000] Attribute report received: 0xFFDF='��;*i��;*i��;*i��;*i��;*i��;*i\x08�;*i��;*\x13��;*e��;*\x12��;*er�;*i' [0x7CA8:1:0x0000] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=152, command_id=, *is_reply=True) [0x7CA8:1:0x0000] Sending reply: Default_Response(command_id=10, status=) [0x7CA8:1:0x0000] Received ZCL frame: b'\x08\x99\n\xdf\xffB({\xc2;*i\x84\xc2;*i\x89\xc2;*\x13\x89\xc2;*e\x8a\xc2;*\x12\xae\xc2;*e\xc5\xc2;*i\xc6\xc2;*i' [0x7CA8:1:0x0000] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=False, *is_general=True), tsn=153, command_id=10, *is_reply=True) [0x7CA8:1:0x0000] Decoded ZCL frame: Basic:Report_Attributes(attribute_reports=[Attribute(attrid=0xFFDF, value=TypeValue(type=CharacterString, value='{�;*i��;*i��;*\x13��;*e��;*\x12��;*e��;*i��;*i'))]) [0x7CA8:1:0x0000] Received command 0x0A (TSN 153): Report_Attributes(attribute_reports=[Attribute(attrid=0xFFDF, value=TypeValue(type=CharacterString, value='{�;*i��;*i��;*\x13��;*e��;*\x12��;*e��;*i��;*i'))]) [0x7CA8:1:0x0000] Attribute report received: 0xFFDF='{�;*i��;*i��;*\x13��;*e��;*\x12��;*e��;*i��;*i' [0x7CA8:1:0x0000] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=153, command_id=, *is_reply=True) [0x7CA8:1:0x0000] Sending reply: Default_Response(command_id=10, status=) [0x7CA8:1:0xef00] Received ZCL frame: b'\t\x9a\x02\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=154, command_id=2, *is_reply=True) [0x7CA8:1:0xef00] Unknown cluster command 2 b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Received command 0x02 (TSN 154): b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] No explicit handler for cluster command 0x02: b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Received ZCL frame: b'\t\x9a\x02\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=154, command_id=2, *is_reply=True) [0x7CA8:1:0xef00] Unknown cluster command 2 b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Received command 0x02 (TSN 154): b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] No explicit handler for cluster command 0x02: b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Received ZCL frame: b'\t\x9a\x02\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=154, command_id=2, *is_reply=True) [0x7CA8:1:0xef00] Unknown cluster command 2 b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Received command 0x02 (TSN 154): b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] No explicit handler for cluster command 0x02: b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Received ZCL frame: b'\t\x9a\x02\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=154, command_id=2, *is_reply=True) [0x7CA8:1:0xef00] Unknown cluster command 2 b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Received command 0x02 (TSN 154): b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] No explicit handler for cluster command 0x02: b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Received ZCL frame: b'\t\x9a\x02\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=154, command_id=2, *is_reply=True) [0x7CA8:1:0xef00] Unknown cluster command 2 b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Received command 0x02 (TSN 154): b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] No explicit handler for cluster command 0x02: b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Received ZCL frame: b'\t\x9a\x02\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=154, command_id=2, *is_reply=True) [0x7CA8:1:0xef00] Unknown cluster command 2 b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Received command 0x02 (TSN 154): b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] No explicit handler for cluster command 0x02: b'\x00\x93j\x02\x00\x04\x00\x00\x00\x00' [0xBFE0](TS0201): Device seen - marking the device available and resetting counter [0xBFE0](TS0201): Update device availability - device available: True - new availability: True - changed: False [0x7CA8:1:0xef00] Received ZCL frame: b'\t\x9b\x02\x00\x94g\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=155, command_id=2, *is_reply=True) [0x7CA8:1:0xef00] Unknown cluster command 2 b'\x00\x94g\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Received command 0x02 (TSN 155): b'\x00\x94g\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] No explicit handler for cluster command 0x02: b'\x00\x94g\x02\x00\x04\x00\x00\x00\x00' [0x7CA8:1:0xef00] Received ZCL frame: b'\t\x9c\x02\x00\x95\x02\x01\x00\x01\x00' [0x7CA8:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=156, command_id=2, *is_reply=True) [0x7CA8:1:0xef00] Unknown cluster command 2 b'\x00\x95\x02\x01\x00\x01\x00' [0x7CA8:1:0xef00] Received command 0x02 (TSN 156): b'\x00\x95\x02\x01\x00\x01\x00' [0x7CA8:1:0xef00] No explicit handler for cluster command 0x02: b'\x00\x95\x02\x01\x00\x01\x00' [0x7CA8:1:0xef00] Received ZCL frame: b'\t\x9d\x02\x00\x96f\x03\x00\x0810:21:46' [0x7CA8:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=157, command_id=2, *is_reply=True) [0x7CA8:1:0xef00] Unknown cluster command 2 b'\x00\x96f\x03\x00\x0810:21:46' [0x7CA8:1:0xef00] Received command 0x02 (TSN 157): b'\x00\x96f\x03\x00\x0810:21:46' [0x7CA8:1:0xef00] No explicit handler for cluster command 0x02: b'\x00\x96f\x03\x00\x0810:21:46' ```

Additional context

cloudbr34k84 commented 1 year ago

FYI if you want to change the light switch to a switch MODIFYING THE DEVICE TYPE - https://www.home-assistant.io/integrations/zha/#modifying-the-device-type As not all device manufacturers follow the Zigbee standard, at times a device can be incorrectly classified. For example, a switch could be classified as a light.

To correct the device type, also called domain, add the following to your configuration.yaml and restart Home Assistant:

zha: device_config: 84:71:27:ff:fe:93:17:24-1: # format: {ieee}-{endpoint_id} type: "switch" # corrected device type YAML {ieee} is the device hardware address which can be read from the Home Assistant UI when looking at Device info. From device info, you can find the {endpoint_id} by viewing the Zigbee device signature. under zha in config file add device_config:

hkoci commented 1 year ago

Thank you @cloudbr34k84 , it has caused a lot of issues with homekit manipulating the device as a brightness slider!

hkoci commented 1 year ago

oh man awesome! "Though there were some connection issues with when the toggle does not actually toggle but this has not happened frequently" To be honest when i was testing this in Tuya, i had the same issue. It came good after 1 hr or so?

Pretty much, I used it as a sunrise automation with HA when it was the summer. Yeah, I believe its the h/w if it occurs on Tuya as well - you'll enjoy it for sure. Made my life a lot easier on vacation.

i just like to buy these things and play around. but my goal is to use it with this. Basically the liquid fertilizer injects into into hose. https://www.ezflo.com.au/product/ez-flo-3-2l/

Looks impressive 😲 - hope this goes well! We used the cheap irrigation system with the sprinklers around the garden, and might look into adding fertilizer now.

i only have real grass out the front, no in ground irrigation, just an osculating fan water sprayer. The quirks works, but there are not alot of entities in the quirk??

With ZHA there is only battery level and a light entity to toggle the water valve Screenshot 2022-11-05 at 13 40 50 If you use Zigbee2MQTT, you'll see more entities exposed like:

  • irrigation_target
  • cycle_irrigation_num_times
  • cycle_irrigation_interval
  • irrigation_start_time
  • irrigation_end_time
  • last_irrigation_duration
  • water_consumed

which are missing on the zha quirk atm.

Yeah thats all i have, light and battery, how come we cant get the the others??

I think the issue is that originally, we were having issues porting over the quirk from Z2M and then @infinitejest realised that the datapoints were incorrect for the battery and valve switches.

If we were to improve the quirk, it would be to add the missing entities - most likely, comparing their script data points and ours.

The referenced data points from Z2M are the following:

cloudbr34k84 commented 1 year ago

oh man awesome! "Though there were some connection issues with when the toggle does not actually toggle but this has not happened frequently" To be honest when i was testing this in Tuya, i had the same issue. It came good after 1 hr or so?

Pretty much, I used it as a sunrise automation with HA when it was the summer. Yeah, I believe its the h/w if it occurs on Tuya as well - you'll enjoy it for sure. Made my life a lot easier on vacation.

i just like to buy these things and play around. but my goal is to use it with this. Basically the liquid fertilizer injects into into hose. https://www.ezflo.com.au/product/ez-flo-3-2l/

Looks impressive 😲 - hope this goes well! We used the cheap irrigation system with the sprinklers around the garden, and might look into adding fertilizer now.

i only have real grass out the front, no in ground irrigation, just an osculating fan water sprayer. The quirks works, but there are not alot of entities in the quirk??

With ZHA there is only battery level and a light entity to toggle the water valve Screenshot 2022-11-05 at 13 40 50 If you use Zigbee2MQTT, you'll see more entities exposed like:

  • irrigation_target
  • cycle_irrigation_num_times
  • cycle_irrigation_interval
  • irrigation_start_time
  • irrigation_end_time
  • last_irrigation_duration
  • water_consumed

which are missing on the zha quirk atm.

Yeah thats all i have, light and battery, how come we cant get the the others??

I think the issue is that originally, we were having issues porting over the quirk from Z2M and then @infinitejest realised that the datapoints were incorrect for the battery and valve switches.

If we were to improve the quirk, it would be to add the missing entities - most likely, comparing their script data points and ours.

The referenced data points from Z2M are the following:

  • giexWaterValveState: 2,
  • giexWaterValveMode: 1,
  • giexWaterValveIrrigationTarget: 104,
  • giexWaterValveWaterConsumed: 111,
  • giexWaterValveIrrigationStartTime: 101,
  • giexWaterValveIrrigationEndTime: 102,
  • giexWaterValveLastIrrigationDuration: 114,
  • giexWaterValveBattery: 108,
  • giexWaterValveCycleIrrigationNumTimes: 103,
  • giexWaterValveCycleIrrigationInterval: 105,
  • giexWaterValveCurrentTempurature: 106,

I have no idea how to do any of this??

hkoci commented 1 year ago

oh man awesome! "Though there were some connection issues with when the toggle does not actually toggle but this has not happened frequently" To be honest when i was testing this in Tuya, i had the same issue. It came good after 1 hr or so?

Pretty much, I used it as a sunrise automation with HA when it was the summer. Yeah, I believe its the h/w if it occurs on Tuya as well - you'll enjoy it for sure. Made my life a lot easier on vacation.

i just like to buy these things and play around. but my goal is to use it with this. Basically the liquid fertilizer injects into into hose. https://www.ezflo.com.au/product/ez-flo-3-2l/

Looks impressive 😲 - hope this goes well! We used the cheap irrigation system with the sprinklers around the garden, and might look into adding fertilizer now.

i only have real grass out the front, no in ground irrigation, just an osculating fan water sprayer. The quirks works, but there are not alot of entities in the quirk??

With ZHA there is only battery level and a light entity to toggle the water valve Screenshot 2022-11-05 at 13 40 50 If you use Zigbee2MQTT, you'll see more entities exposed like:

  • irrigation_target
  • cycle_irrigation_num_times
  • cycle_irrigation_interval
  • irrigation_start_time
  • irrigation_end_time
  • last_irrigation_duration
  • water_consumed

which are missing on the zha quirk atm.

Yeah thats all i have, light and battery, how come we cant get the the others??

I think the issue is that originally, we were having issues porting over the quirk from Z2M and then @infinitejest realised that the datapoints were incorrect for the battery and valve switches. If we were to improve the quirk, it would be to add the missing entities - most likely, comparing their script data points and ours. The referenced data points from Z2M are the following:

  • giexWaterValveState: 2,
  • giexWaterValveMode: 1,
  • giexWaterValveIrrigationTarget: 104,
  • giexWaterValveWaterConsumed: 111,
  • giexWaterValveIrrigationStartTime: 101,
  • giexWaterValveIrrigationEndTime: 102,
  • giexWaterValveLastIrrigationDuration: 114,
  • giexWaterValveBattery: 108,
  • giexWaterValveCycleIrrigationNumTimes: 103,
  • giexWaterValveCycleIrrigationInterval: 105,
  • giexWaterValveCurrentTempurature: 106,

I have no idea how to do any of this??

Me neither just an experiment for me tbh 😆

One day I will code a quirk!

cloudbr34k84 commented 1 year ago

oh man awesome! "Though there were some connection issues with when the toggle does not actually toggle but this has not happened frequently" To be honest when i was testing this in Tuya, i had the same issue. It came good after 1 hr or so?

Pretty much, I used it as a sunrise automation with HA when it was the summer. Yeah, I believe its the h/w if it occurs on Tuya as well - you'll enjoy it for sure. Made my life a lot easier on vacation.

i just like to buy these things and play around. but my goal is to use it with this. Basically the liquid fertilizer injects into into hose. https://www.ezflo.com.au/product/ez-flo-3-2l/

Looks impressive 😲 - hope this goes well! We used the cheap irrigation system with the sprinklers around the garden, and might look into adding fertilizer now.

i only have real grass out the front, no in ground irrigation, just an osculating fan water sprayer. The quirks works, but there are not alot of entities in the quirk??

With ZHA there is only battery level and a light entity to toggle the water valve Screenshot 2022-11-05 at 13 40 50 If you use Zigbee2MQTT, you'll see more entities exposed like:

  • irrigation_target
  • cycle_irrigation_num_times
  • cycle_irrigation_interval
  • irrigation_start_time
  • irrigation_end_time
  • last_irrigation_duration
  • water_consumed

which are missing on the zha quirk atm.

Yeah thats all i have, light and battery, how come we cant get the the others??

I think the issue is that originally, we were having issues porting over the quirk from Z2M and then @infinitejest realised that the datapoints were incorrect for the battery and valve switches. If we were to improve the quirk, it would be to add the missing entities - most likely, comparing their script data points and ours. The referenced data points from Z2M are the following:

  • giexWaterValveState: 2,
  • giexWaterValveMode: 1,
  • giexWaterValveIrrigationTarget: 104,
  • giexWaterValveWaterConsumed: 111,
  • giexWaterValveIrrigationStartTime: 101,
  • giexWaterValveIrrigationEndTime: 102,
  • giexWaterValveLastIrrigationDuration: 114,
  • giexWaterValveBattery: 108,
  • giexWaterValveCycleIrrigationNumTimes: 103,
  • giexWaterValveCycleIrrigationInterval: 105,
  • giexWaterValveCurrentTempurature: 106,

I have no idea how to do any of this??

Me neither just an experiment for me tbh 😆

One day I will code a quirk!

bugger! well thanks for helping me, im trying to see if i can find some other quirks for devices i have, that arent working

mbo18 commented 1 year ago

If you want the valve to be detected as a switch instead of a light, change this line in the replacement part of the quirk: DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT, with: DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,

cloudbr34k84 commented 1 year ago

Is anyone else having an issue with this quirk where it just shuts off by its self after 3-4 mins image

mbo18 commented 1 year ago

Is anyone else having an issue with this quirk where it just shuts off by its self after 3-4 mins

It may be setup like this in the valve. To change this you need a tuya gateway or move to Z2M to change this setting or wait for a better quirk

cloudbr34k84 commented 1 year ago

I have a tuya gateway and connected it and it's fine on there . So frustrating

mbo18 commented 1 year ago

I've made some progress, can someone try this quirk:

Click me ```python """Giex Tuya valve devices.""" import logging 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, Ota, PowerConfiguration, Scenes, Time, ) from zigpy.zcl.clusters.smartenergy import Metering 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, TuyaAttributesCluster, TuyaDPType, TuyaMCUCluster, TuyaOnOffNM, TuyaPowerConfigurationCluster, ) # info from https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/devices/giex.js GIEX_TUYA_VALVE_MODE_ATTR = 0xEF01 # Mode [0] duration [1] capacity GIEX_TUYA_VALVE_START_TIME_ATTR = 0xEF65 # Last irrigation start time (GMT) GIEX_TUYA_VALVE_END_TIME_ATTR = 0xEF66 # Last irrigation end time (GMT) GIEX_TUYA_VALVE_NUM_TIMES_ATTR = 0xEF67 # Number of cycle irrigation times, set to 0 for single cycle, min=0 max=100 GIEX_TUYA_VALVE_TARGET_ATTR = 0xEF68 # Irrigation target, duration in seconds or capacity in litres (depending on mode), min=0, max=3600 GIEX_TUYA_VALVE_INTERVAL_ATTR = 0xEF69 # Cycle irrigation interval in seconds, min=0, max=3600 GIEX_TUYA_VALVE_DURATION_ATTR = 0xEF72 # Last irrigation duration _LOGGER = logging.getLogger(__name__) class GiexTuyaValveMode(t.enum8): """Giex valve mode enum.""" duration = 0x00 capacity = 0x01 class TuyaValveWaterConsumed(Metering, TuyaLocalCluster): """Tuya Valve Water consumed cluster.""" VOLUME_LITERS = 0x0007 """Setting unit of measurement.""" _CONSTANT_ATTRIBUTES = {0x0300: VOLUME_LITERS} class GiexTuyaValveManufCluster(TuyaMCUCluster): """Tuya valve manufacturer cluster.""" attributes = TuyaMCUCluster.attributes.copy() attributes.update( { GIEX_TUYA_VALVE_MODE_ATTR: ("mode", t.uint8_t, True), GIEX_TUYA_VALVE_START_TIME_ATTR: ("start_time", t.uint32_t, True), GIEX_TUYA_VALVE_END_TIME_ATTR: ("end_time", t.uint32_t, True), GIEX_TUYA_VALVE_NUM_TIMES_ATTR: ("num_times", t.uint32_t, True), GIEX_TUYA_VALVE_TARGET_ATTR: ("target", t.uint32_t, True), GIEX_TUYA_VALVE_INTERVAL_ATTR: ("interval", t.uint32_t, True), GIEX_TUYA_VALVE_DURATION_ATTR: ("duration", t.uint32_t, True), } ) dp_to_attribute: Dict[int, DPToAttributeMapping] = { 1: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_mode", dp_type=TuyaDPType.ENUM, converter=lambda x: GiexTuyaValveMode(x), ), 2: DPToAttributeMapping( TuyaOnOffNM.ep_attribute, "on_off", dp_type=TuyaDPType.BOOL, ), 101: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_start_time", dp_type=TuyaDPType.VALUE, ), 102: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_end_time", dp_type=TuyaDPType.VALUE, ), 103: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_num_times", dp_type=TuyaDPType.VALUE, ), 104: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_target", dp_type=TuyaDPType.VALUE, ), 105: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_interval", dp_type=TuyaDPType.VALUE, ), 108: DPToAttributeMapping( TuyaPowerConfigurationCluster.ep_attribute, "battery_percentage_remaining", dp_type=TuyaDPType.VALUE, ), 111: DPToAttributeMapping( TuyaValveWaterConsumed.ep_attribute, "current_summ_delivered", TuyaDPType.VALUE, ), 114: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_duration", dp_type=TuyaDPType.VALUE, ), } data_point_handlers = { 1: "_dp_2_attr_update", 2: "_dp_2_attr_update", 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", 108: "_dp_2_attr_update", 111: "_dp_2_attr_update", 114: "_dp_2_attr_update", } class GiexTuyaValve(CustomDevice): """Tuya valve device.""" signature = { MODELS_INFO: [ ("_TZE200_sh1btabb", "TS0601"), ("_TZE200_a7sghmms", "TS0601") ], ENDPOINTS: { # 1: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.SMART_PLUG, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, GiexTuyaValveManufCluster.cluster_id, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], } }, } replacement = { ENDPOINTS: { 1: { DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, TuyaOnOffNM, TuyaPowerConfigurationCluster, TuyaValveWaterConsumed, GiexTuyaValveManufCluster, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], } } } ```

I will try to make changes in order for us to be able to change the valve mode between duration or capacity, and also change the target, number of cycle or circle interval. But I think that I will need the help of some quirks experts!

infinitejest commented 1 year ago

That is awesome. I meant to figure this out,. But didn't have the time. You can see most entities in the home assistant logs but could not figure out how to translate to the quirk.

Great job

On Wed, Nov 16, 2022, 5:05 PM mbo18 @.***> wrote:

I've made some progress, can someone try this quirk: Click me

"""Giex Tuya valve devices.""" import loggingfrom typing import Dict from zigpy.profiles import zhafrom zigpy.quirks import CustomDeviceimport zigpy.types as tfrom zigpy.zcl import foundationfrom zigpy.zcl.clusters.general import ( Basic, Groups, Ota, PowerConfiguration, Scenes, Time, )from zigpy.zcl.clusters.smartenergy import Metering from zhaquirks.const import ( DEVICE_TYPE, ENDPOINTS, INPUT_CLUSTERS, MODELS_INFO, OUTPUT_CLUSTERS, PROFILE_ID, )from zhaquirks.tuya import TuyaLocalClusterfrom zhaquirks.tuya.mcu import ( DPToAttributeMapping, TuyaAttributesCluster, TuyaDPType, TuyaMCUCluster, TuyaOnOff, TuyaPowerConfigurationCluster, )

info from https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/devices/giex.jsGIEX_TUYA_VALVE_MODE_ATTR = 0xEF01 # Mode [0] duration [1] capacityGIEX_TUYA_VALVE_START_TIME_ATTR = 0xEF65 # Last irrigation start time (GMT)GIEX_TUYA_VALVE_END_TIME_ATTR = 0xEF66 # Last irrigation end time (GMT)GIEX_TUYA_VALVE_NUM_TIMES_ATTR = 0xEF67 # Number of cycle irrigation times, set to 0 for single cycle, min=0 max=100GIEX_TUYA_VALVE_TARGET_ATTR = 0xEF68 # Irrigation target, duration in seconds or capacity in litres (depending on mode), min=0, max=3600GIEX_TUYA_VALVE_INTERVAL_ATTR = 0xEF69 # Cycle irrigation interval in seconds, min=0, max=3600GIEX_TUYA_VALVE_DURATION_ATTR = 0xEF72 # Last irrigation duration

_LOGGER = logging.getLogger(name)

class GiexTuyaValveMode(t.enum8): """Giex valve mode enum."""

duration = 0x00
capacity = 0x01

class TuyaValveWaterConsumed(Metering, TuyaLocalCluster): """Tuya Valve Water consumed cluster."""

VOLUME_LITERS = 0x0007

"""Setting unit of measurement."""
_CONSTANT_ATTRIBUTES = {0x0300: VOLUME_LITERS}

class GiexTuyaValveManufCluster(TuyaMCUCluster): """Tuya valve manufacturer cluster."""

attributes = TuyaMCUCluster.attributes.copy()
attributes.update(
    {
        GIEX_TUYA_VALVE_MODE_ATTR: ("mode", t.uint8_t, True),
        GIEX_TUYA_VALVE_START_TIME_ATTR: ("start_time", t.uint32_t, True),
        GIEX_TUYA_VALVE_END_TIME_ATTR: ("end_time", t.uint32_t, True),
        GIEX_TUYA_VALVE_NUM_TIMES_ATTR: ("num_times", t.uint32_t, True),
        GIEX_TUYA_VALVE_TARGET_ATTR: ("target", t.uint32_t, True),
        GIEX_TUYA_VALVE_INTERVAL_ATTR: ("interval", t.uint32_t, True),
        GIEX_TUYA_VALVE_DURATION_ATTR: ("duration", t.uint32_t, True),
    }
)

dp_to_attribute: Dict[int, DPToAttributeMapping] = {
    1: DPToAttributeMapping(
        TuyaMCUCluster.ep_attribute,
        "irrigation_mode",
        dp_type=TuyaDPType.ENUM,
        converter=lambda x: GiexTuyaValveMode(x),
    ),
    2: DPToAttributeMapping(
        TuyaOnOff.ep_attribute,
        "on_off",
        dp_type=TuyaDPType.BOOL,
    ),
    101: DPToAttributeMapping(
        TuyaMCUCluster.ep_attribute,
        "irrigation_start_time",
        dp_type=TuyaDPType.VALUE,
    ),
    102: DPToAttributeMapping(
        TuyaMCUCluster.ep_attribute,
        "irrigation_end_time",
        dp_type=TuyaDPType.VALUE,
    ),
    103: DPToAttributeMapping(
        TuyaMCUCluster.ep_attribute,
        "irrigation_num_times",
        dp_type=TuyaDPType.VALUE,
    ),
    104: DPToAttributeMapping(
        TuyaMCUCluster.ep_attribute,
        "irrigation_target",
        dp_type=TuyaDPType.VALUE,
    ),
    105: DPToAttributeMapping(
        TuyaMCUCluster.ep_attribute,
        "irrigation_interval",
        dp_type=TuyaDPType.VALUE,
    ),
    108: DPToAttributeMapping(
        TuyaPowerConfigurationCluster.ep_attribute,
        "battery_percentage_remaining",
        dp_type=TuyaDPType.VALUE,
    ),
    111: DPToAttributeMapping(
        TuyaValveWaterConsumed.ep_attribute,
        "current_summ_delivered",
        TuyaDPType.VALUE,
    ),
    114: DPToAttributeMapping(
        TuyaMCUCluster.ep_attribute,
        "irrigation_duration",
        dp_type=TuyaDPType.VALUE,
    ),
}

data_point_handlers = {
    1: "_dp_2_attr_update",
    2: "_dp_2_attr_update",
    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",
    108: "_dp_2_attr_update",
    111: "_dp_2_attr_update",
    114: "_dp_2_attr_update",
}

class GiexTuyaValve(CustomDevice): """Tuya valve device."""

signature = {
    MODELS_INFO: [
        ("_TZE200_sh1btabb", "TS0601"),
        ("_TZE200_a7sghmms", "TS0601")
    ],
    ENDPOINTS: {
        # <SimpleDescriptor endpoint=1 profile=260 device_type=0x0051
        # input_clusters=[0x0000, 0x0004, 0x0005, 0xef00]
        # output_clusters=[0x000a, 0x0019]>
        1: {
            PROFILE_ID: zha.PROFILE_ID,
            DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
            INPUT_CLUSTERS: [
                Basic.cluster_id,
                Groups.cluster_id,
                Scenes.cluster_id,
                GiexTuyaValveManufCluster.cluster_id,
            ],
            OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
        }
    },
}

replacement = {
    ENDPOINTS: {
        1: {
            DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
            INPUT_CLUSTERS: [
                Basic.cluster_id,
                Groups.cluster_id,
                Scenes.cluster_id,
                TuyaOnOff,
                TuyaPowerConfigurationCluster,
                TuyaValveWaterConsumed,
                GiexTuyaValveManufCluster,
            ],
            OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
        }
    }
}

I will try to make changes in order for us to be able to change the valve mode between duration or capacity, and also change the target, number of cycle or circle interval. But I think that I will need the help of some quirks experts!

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

cloudbr34k84 commented 1 year ago

Great work! I finally got this working as it was always turning off and yeah in th Tuya App it was turning off after 60L. Annoying that it does that. Just a heads up for anyone else I guess Screenshot_20221117-094856

javicalle commented 1 year ago

I will try to make changes in order for us to be able to change the valve mode between duration or capacity, and also change the target, number of cycle or circle interval. But I think that I will need the help of some quirks experts!

My suggestion is that that part be addressed from the ZHA implementation. To be able to do tests it is possible to configure the ZHA integration as a local custom_component and thus validate the changes.

That approach is the same that I myself have suggested in this other issue:

The quirk part is fine as is. To create (i.e.) a select entity for the valve_mode, check this PR:

If you want explore that path I can try to guide you.

mbo18 commented 1 year ago

Thanks @javicalle! My goal is to have this fully integrated to ZHA and HA before next summer 😃 so I will let you know how things are going. I still need to work on the quirk regarding the valve mode. It seems that it’s a Boolean if I understand the Z2M converter correctly, I need to do more tests. After that I will check to update ZHA.

javicalle commented 1 year ago

I still need to work on the quirk regarding the valve mode. It seems that it’s a Boolean if I understand the Z2M converter correctly, I need to do more tests.

In the HA logs, the device report will tell you which dp_type it is, look for the dp=1 report.

Your code declares it as an ENUM:

        1: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "irrigation_mode",
            dp_type=TuyaDPType.ENUM,
            converter=lambda x: GiexTuyaValveMode(x),
        ),

And I must warn you that if you try to wrap the Bool in any way, it is not an easy task:

Let me know if I can help you in this matter in any way.

hollow901 commented 1 year ago

Any one having an issue where it won’t turn off? My HA says it is off, but it certainly isn’t. Was on for almost an hour and a half before I realised!!

mbo18 commented 1 year ago

Any one having an issue where it won’t turn off? My HA says it is off, but it certainly isn’t. Was on for almost an hour and a half before I realised!!

If you are using my quirk, I made a small mistake in it. Please update it (I have updated my post above)

mbo18 commented 1 year ago

@javicalle from the logs, dp=1 is a boolean. If I set it as a boolean I'm able to update it from Bool.false to Bool.true. But if I set it as an ENUM I am unable to update it. Maybe I'm doing something wrong.

Here is my last update to the quirk ```python """GiEX Tuya valve devices.""" import logging 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, Ota, PowerConfiguration, Scenes, Time, ) from zigpy.zcl.clusters.smartenergy import Metering 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, TuyaAttributesCluster, TuyaDPType, TuyaMCUCluster, TuyaOnOffNM, TuyaPowerConfigurationCluster, ) # info from https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/devices/giex.js GIEX_TUYA_VALVE_MODE_ATTR = 0xEF01 # Mode [0] duration [1] capacity GIEX_TUYA_VALVE_START_TIME_ATTR = 0xEF65 # Last irrigation start time (GMT) GIEX_TUYA_VALVE_END_TIME_ATTR = 0xEF66 # Last irrigation end time (GMT) GIEX_TUYA_VALVE_NUM_TIMES_ATTR = 0xEF67 # Number of cycle irrigation times, set to 0 for single cycle, min=0 max=100 GIEX_TUYA_VALVE_TARGET_ATTR = 0xEF68 # Irrigation target, duration in seconds or capacity in litres (depending on mode), min=0, max=3600 GIEX_TUYA_VALVE_INTERVAL_ATTR = 0xEF69 # Cycle irrigation interval in seconds, min=0, max=3600 GIEX_TUYA_VALVE_DURATION_ATTR = 0xEF72 # Last irrigation duration _LOGGER = logging.getLogger(__name__) class TuyaValveWaterConsumed(Metering, TuyaLocalCluster): """Tuya Valve Water consumed cluster.""" VOLUME_LITERS = 0x0007 """Setting unit of measurement.""" _CONSTANT_ATTRIBUTES = {0x0300: VOLUME_LITERS} class GiexTuyaValveManufCluster(TuyaMCUCluster): """GiEX Tuya valve manufacturer cluster.""" class GiexTuyaValveMode(t.enum8): """GiEX valve mode enum.""" duration = 0x00 capacity = 0x01 attributes = TuyaMCUCluster.attributes.copy() attributes.update( { GIEX_TUYA_VALVE_MODE_ATTR: ("irrigation_mode", GiexTuyaValveMode, True), GIEX_TUYA_VALVE_START_TIME_ATTR: ("irrigation_start_time", t.uint32_t, True), GIEX_TUYA_VALVE_END_TIME_ATTR: ("irrigation_end_time", t.uint32_t, True), GIEX_TUYA_VALVE_NUM_TIMES_ATTR: ("irrigation_num_times", t.uint32_t, True), GIEX_TUYA_VALVE_TARGET_ATTR: ("irrigation_target", t.uint32_t, True), GIEX_TUYA_VALVE_INTERVAL_ATTR: ("irrigation_interval", t.uint32_t, True), GIEX_TUYA_VALVE_DURATION_ATTR: ("irrigation_duration", t.uint32_t, True), } ) dp_to_attribute: Dict[int, DPToAttributeMapping] = { 1: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_mode", dp_type=TuyaDPType.ENUM, converter=lambda x: GiexTuyaValveMode(x), ), 2: DPToAttributeMapping( TuyaOnOffNM.ep_attribute, "on_off", dp_type=TuyaDPType.BOOL, ), 101: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_start_time", dp_type=TuyaDPType.VALUE, ), 102: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_end_time", dp_type=TuyaDPType.VALUE, ), 103: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_num_times", dp_type=TuyaDPType.VALUE, ), 104: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_target", dp_type=TuyaDPType.VALUE, ), 105: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_interval", dp_type=TuyaDPType.VALUE, ), 108: DPToAttributeMapping( TuyaPowerConfigurationCluster.ep_attribute, "battery_percentage_remaining", dp_type=TuyaDPType.VALUE, ), 111: DPToAttributeMapping( TuyaValveWaterConsumed.ep_attribute, "current_summ_delivered", dp_type=TuyaDPType.VALUE, ), 114: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_duration", dp_type=TuyaDPType.VALUE, ), } data_point_handlers = { 1: "_dp_2_attr_update", 2: "_dp_2_attr_update", 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", 108: "_dp_2_attr_update", 111: "_dp_2_attr_update", 114: "_dp_2_attr_update", } async def write_attributes(self, attributes, manufacturer=None): """Overwrite to force manufacturer code.""" return await super().write_attributes( attributes, manufacturer=foundation.ZCLHeader.NO_MANUFACTURER_ID ) class GiexTuyaValve(CustomDevice): """Tuya valve device.""" signature = { MODELS_INFO: [ ("_TZE200_sh1btabb", "TS0601"), ("_TZE200_a7sghmms", "TS0601") ], ENDPOINTS: { # 1: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.SMART_PLUG, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, GiexTuyaValveManufCluster.cluster_id, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], } }, } replacement = { ENDPOINTS: { 1: { DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, TuyaOnOffNM, TuyaPowerConfigurationCluster, TuyaValveWaterConsumed, GiexTuyaValveManufCluster, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], } } } ```

Also, if it works as an ENUM, do you know how to get something like "GiexTuyaValveMode.duration" or "GiexTuyaValveMode.capacity" instead of 0/0x00 or 1/0x01 in the value field when playing with cluster/attribute in HA/Manage Zigbee Device?

javicalle commented 1 year ago

do you know how to get something like "GiexTuyaValveMode.duration" or "GiexTuyaValveMode.capacity" instead of 0/0x00 or 1/0x01 in the value field when playing with cluster/attribute in HA/Manage Zigbee Device?

No I don't know. That's what I was looking at https://github.com/zigpy/zigpy/issues/948 but I didn't get a way to do it.

I believe that the way to do it is in the HA interface. IMHO makes more sense to do the conversion in the UI layer, that not add the extra code in the zigbee/zigpy layer.

Now that it is easy to get the ZHA entities in HA my opinion is to keep the quirk much simple as posible and move all the UI to HA.

mbo18 commented 1 year ago

Thank you for your help. I will now try to improve ZHA

mbo18 commented 1 year ago

Ok I have something working fine when adding things in HA. I will open a PR to push my quirk and then will update HA

Here is my last update to the quirk ```python """GiEX Tuya valve devices.""" import logging 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, Ota, PowerConfiguration, Scenes, Time, ) from zigpy.zcl.clusters.smartenergy import Metering 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, TuyaAttributesCluster, TuyaDPType, TuyaMCUCluster, TuyaOnOffNM, TuyaPowerConfigurationCluster, ) # info from https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/devices/giex.js GIEX_TUYA_VALVE_MODE_ATTR = 0xEF01 # Mode [0] duration [1] capacity GIEX_TUYA_VALVE_START_TIME_ATTR = 0xEF65 # Last irrigation start time (GMT) GIEX_TUYA_VALVE_END_TIME_ATTR = 0xEF66 # Last irrigation end time (GMT) GIEX_TUYA_VALVE_NUM_TIMES_ATTR = 0xEF67 # Number of cycle irrigation times, set to 0 for single cycle, min=0 max=100 GIEX_TUYA_VALVE_TARGET_ATTR = 0xEF68 # Irrigation target, duration in seconds or capacity in litres (depending on mode), min=0, max=3600 GIEX_TUYA_VALVE_INTERVAL_ATTR = 0xEF69 # Cycle irrigation interval in seconds, min=0, max=3600 GIEX_TUYA_VALVE_DURATION_ATTR = 0xEF72 # Last irrigation duration _LOGGER = logging.getLogger(__name__) class TuyaValveWaterConsumed(Metering, TuyaLocalCluster): """Tuya Valve Water consumed cluster.""" VOLUME_LITERS = 0x0007 """Setting unit of measurement.""" _CONSTANT_ATTRIBUTES = {0x0300: VOLUME_LITERS} class GiexTuyaValveManufCluster(TuyaMCUCluster): """GiEX Tuya valve manufacturer cluster.""" attributes = TuyaMCUCluster.attributes.copy() attributes.update( { GIEX_TUYA_VALVE_MODE_ATTR: ("irrigation_mode", t.Bool, True), GIEX_TUYA_VALVE_START_TIME_ATTR: ("irrigation_start_time", t.uint32_t, True), GIEX_TUYA_VALVE_END_TIME_ATTR: ("irrigation_end_time", t.uint32_t, True), GIEX_TUYA_VALVE_NUM_TIMES_ATTR: ("irrigation_num_times", t.uint32_t, True), GIEX_TUYA_VALVE_TARGET_ATTR: ("irrigation_target", t.uint32_t, True), GIEX_TUYA_VALVE_INTERVAL_ATTR: ("irrigation_interval", t.uint32_t, True), GIEX_TUYA_VALVE_DURATION_ATTR: ("irrigation_duration", t.uint32_t, True), } ) dp_to_attribute: Dict[int, DPToAttributeMapping] = { 1: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_mode", dp_type=TuyaDPType.BOOL, ), 2: DPToAttributeMapping( TuyaOnOffNM.ep_attribute, "on_off", dp_type=TuyaDPType.BOOL, ), 101: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_start_time", dp_type=TuyaDPType.VALUE, ), 102: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_end_time", dp_type=TuyaDPType.VALUE, ), 103: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_num_times", dp_type=TuyaDPType.VALUE, ), 104: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_target", dp_type=TuyaDPType.VALUE, ), 105: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_interval", dp_type=TuyaDPType.VALUE, ), 108: DPToAttributeMapping( TuyaPowerConfigurationCluster.ep_attribute, "battery_percentage_remaining", dp_type=TuyaDPType.VALUE, ), 111: DPToAttributeMapping( TuyaValveWaterConsumed.ep_attribute, "current_summ_delivered", dp_type=TuyaDPType.VALUE, ), 114: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "irrigation_duration", dp_type=TuyaDPType.VALUE, ), } data_point_handlers = { 1: "_dp_2_attr_update", 2: "_dp_2_attr_update", 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", 108: "_dp_2_attr_update", 111: "_dp_2_attr_update", 114: "_dp_2_attr_update", } async def write_attributes(self, attributes, manufacturer=None): """Overwrite to force manufacturer code.""" return await super().write_attributes( attributes, manufacturer=foundation.ZCLHeader.NO_MANUFACTURER_ID ) class GiexTuyaValve(CustomDevice): """Tuya valve device.""" signature = { MODELS_INFO: [ ("_TZE200_sh1btabb", "TS0601"), ("_TZE200_a7sghmms", "TS0601") ], ENDPOINTS: { # 1: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.SMART_PLUG, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, GiexTuyaValveManufCluster.cluster_id, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], } }, } replacement = { ENDPOINTS: { 1: { DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, TuyaOnOffNM, TuyaPowerConfigurationCluster, TuyaValveWaterConsumed, GiexTuyaValveManufCluster, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], } } }
infinitejest commented 1 year ago

Do you need any help ?

On Fri, Nov 18, 2022 at 12:12 PM mbo18 @.***> wrote:

Ok I have something working fine when adding things in HA. I will open a PR to push my quirk and then will update HA

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

-- Dr.Andres A. Rodriguez-Ruiz

mbo18 commented 1 year ago

I should be fine, I will let you know. I'm currently adding things to HA:

Capture d’écran 2022-11-18 à 18 31 25

I hope to be able to open PR next week

javicalle commented 1 year ago

Do you mind to include this?

class TuyaValveWaterConsumed(Metering, TuyaLocalCluster):
    """Tuya Valve Water consumed cluster."""

    VOLUME_LITERS = 0x0007
    WATER_METERING = 0x02

    """Setting unit of measurement."""
    _CONSTANT_ATTRIBUTES = {
        0x0300: VOLUME_LITERS,  # UnitofMeasure
        0x0306: WATER_METERING,  # MeteringDeviceType
    }

The MeteringDeviceType is used in HA (not sure how, but there it is).

hollow901 commented 1 year ago

Any one having an issue where it won’t turn off? My HA says it is off, but it certainly isn’t. Was on for almost an hour and a half before I realised!!

If you are using my quirk, I made a small mistake in it. Please update it (I have updated my post above)

Still having the same issue, tap doesn’t turn off. I sometimes have to turn on and off a few times in HA

mbo18 commented 1 year ago

Still having the same issue, tap doesn’t turn off. I sometimes have to turn on and off a few times in HA

You need to redo the pairing or click on "Reconfigure" after having wake up the device. Also be sure that signal is good

mbo18 commented 1 year ago

I have been able to add all settings in HA:

Capture d’écran 2022-11-20 à 22 35 12

but I'm unable to add sensor that return the start and end time and the duration:

Capture d’écran 2022-11-20 à 22 35 27

I may be wrong but it seems that the current ZHA code in HA only accept sensors to be int or float and not text. This is the error I have: 2022-11-20 22:46:35.834 ERROR (MainThread) [homeassistant.components.sensor] Error adding entities for domain sensor with platform zha Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 428, in async_add_entities await asyncio.gather(*tasks) File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 692, in _async_add_entity await entity.add_to_platform_finish() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 789, in add_to_platform_finish self.async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 545, in async_write_ha_state self._async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 583, in _async_write_ha_state state = self._stringify_state(available) File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 551, in _stringify_state if (state := self.state) is None: File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 669, in state value = self.native_value File "/config/custom_components/zha/sensor.py", line 179, in native_value return self.formatter(raw_state) File "/config/custom_components/zha/sensor.py", line 190, in formatter float(value * self._multiplier) / self._divisor, self._decimals ValueError: could not convert string to float: '00:42:25,0'

javicalle commented 1 year ago

If you create the PR you can get help from the HA community. I believe that you don't need a text and can make use of a time sensor of type DURATION and TIMESTAMP for the last times.

mbo18 commented 1 year ago
Capture d’écran 2022-11-21 à 22 23 02

I was wrong :)

javicalle commented 1 year ago

And i'm glad for that 😆 Are these diagnostic entities?

mbo18 commented 1 year ago

Good question. I’m even wondering if these are useful… this information is available in HA which logs everything. What’s your opinion? Thank you

javicalle commented 1 year ago

I'm of opinion of making everything accessible from HA. Maybe disabled, if we believe that would not be useful for the average user, but accessible for everyone. And IMHO would be a diagnostic entity like this: https://github.com/home-assistant/core/blob/1e64d830ac5dfb9a1e23121a269cf9fa73e9d226/homeassistant/components/zha/sensor.py#L549-L559

mbo18 commented 1 year ago

Ok I will add them as diagnostic and disabled by default 👍 I will open a PR to HA this week

hollow901 commented 1 year ago

I have been able to add all settings in HA: Capture d’écran 2022-11-20 à 22 35 12

but I'm unable to add sensor that return the start and end time and the duration: Capture d’écran 2022-11-20 à 22 35 27

~I may be wrong but it seems that the current ZHA code in HA only accept sensors to be int or float and not text. This is the error I have:~ 2022-11-20 22:46:35.834 ERROR (MainThread) [homeassistant.components.sensor] Error adding entities for domain sensor with platform zha Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 428, in async_add_entities await asyncio.gather(*tasks) File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 692, in _async_add_entity await entity.add_to_platform_finish() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 789, in add_to_platform_finish self.async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 545, in async_write_ha_state self._async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 583, in _async_write_ha_state state = self._stringify_state(available) File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 551, in _stringify_state if (state := self.state) is None: File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 669, in state value = self.native_value File "/config/custom_components/zha/sensor.py", line 179, in native_value return self.formatter(raw_state) File "/config/custom_components/zha/sensor.py", line 190, in formatter float(value * self._multiplier) / self._divisor, self._decimals ValueError: could not convert string to float: '00:42:25,0'

How did you add these settings in HA? I have the latest quirk from this thread, but all I get is the on/off switch

mbo18 commented 1 year ago

I need to open a PR and push my code to HA, you won’t have this with only the quirk. If you want to modify these settings now, you need to click on the 3 dots, then "Manage zigbee device", in cluster select "GiexTuyaValveManufCluster", then select the attribute you want to change, read the attribute, change the value and write the attribute

infinitejest commented 1 year ago

Why not to reassign the value to a standard zigbee attribute so home assistant can recognize it, without modify HA if that is possible.

Andres Rodriguez

On Wed, Nov 23, 2022, 4:12 AM mbo18 @.***> wrote:

I need to open a PR and push my code to HA, you won’t have this with only the quirk. If you want to modify these settings now, you need to click on the 3 dots, then "Manage zigbee device", in cluster select "GiexTuyaValveManufCluster", then select the attribute you want to change, read the attribute, change the value and write the attribute

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

josecarre commented 1 year ago

I'm thinking in getting this water valve, to be used with SkyConnect as gateway, any experience? good or bad 😆

jacobwtyler commented 1 year ago

The Liters that it is measuring is no where near accurate for my water flow. I've got the custom quirk installed. Just wondering if there is a way to modify the calculations now. Any advice?

jacobwtyler commented 1 year ago

I'd also love to change it to gallons

CJMonty commented 1 year ago

HI Guys, thanks a million for working on this. Just one question, did anyone find the way how to disable 1 minute timeout for the valve? If I swith it on manually by the button on the valve, the device runs for as long as I want, but when I turn it on from HA it turns off after 1 minute. Thanks!

mbo18 commented 1 year ago

You need to change device settings in ZHA 92436D82-C7B9-4FB3-80DA-858282F91B0D

KikoSerranoH commented 1 year ago

Hello, thank you for your information.

I am a novice in these matters.

Ok, I set that parameter to zero, but how do I save that value?

mbo18 commented 1 year ago

Click on "Write attribute"

KikoSerranoH commented 1 year ago

Forgive me for asking so many questions.... I thank you very much for your attention.

So, let me see if I have understood correctly:

In the Tab "CLUSTERS" I choose the drop down "GiexValveManufCluster (Endpoint id:1, ld:O>".

Then I choose the Attribute "irrigation_target (id:...)" and there I put a ZERO in the "Value" box.

Finally I click on "WRITE ATTRIBUTE".

Is this correct?

On the other hand, what is the purpose of this attribute? What does it mean that I put a ZERO?

Thanks for everything.

mbo18 commented 1 year ago

Yes correct. 0 = no limit. See some doc here: https://www.zigbee2mqtt.io/devices/QT06.html

KikoSerranoH commented 1 year ago

It's strange because I do what you tell me but it doesn't stick.

image

If I go back in, it no longer has a ZERO value even though I have clicked on WRITE.

image

What am I doing wrong?

javicalle commented 1 year ago

You need to push the "read attribute" to get the current value. Do you have pushed to read?

CJMonty commented 1 year ago

You need to change device settings in ZHA 92436D82-C7B9-4FB3-80DA-858282F91B0D

Thanks guys! Works like a charm, do only thing I'm struggling with right now, the counter for the flow shiws nothing. Is there a fix for that as well?

Thanks!

javicalle commented 1 year ago

I'm struggling with right now, the counter for the flow shiws nothing. Is there a fix for that as well?

According with Z2M is not possible. That must be a limitation from device or maybe it hasn't been discovered the command to get it. In any case you will not get it from reading the cluster attribute, you need to wait to the device reports by itself. I can't say when or how it does, but in the logs it seems that device reports the value in some way.