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
731 stars 673 forks source link

[Device Support Request] Tuya SmartLife compatible "Smart Water Valve" #1551

Closed wishie closed 1 year ago

wishie commented 2 years ago

Is your feature request related to a problem? Please describe. I have a new Zigbee "Smart Water Valve". It's a battery/solar powered device that connects to an external garden tap. It is sold as a Tuya SmartLife compatible device.

Describe the solution you'd like I would like this device to be supported via ZHA

Device signature - this can be acquired by clicking on the "Zigbee Device Signature" button in the device settings ``` { "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_arge1ptm", "model": "TS0601", "class": "zigpy.device.Device" } ```
Diagnostic information - this can be acquired by clicking on the "Download Diagnostics" button in the device settings ``` { "home_assistant": { "installation_type": "Home Assistant Container", "version": "2022.4.7", "dev": false, "hassio": false, "virtualenv": false, "python_version": "3.9.9", "docker": true, "arch": "x86_64", "timezone": "Australia/Brisbane", "os_name": "Linux", "os_version": "5.10.28-Unraid", "run_as_root": true }, "custom_components": { "unifigateway": { "version": "0.3.3", "requirements": [ "pyunifi==2.21" ] }, "bayislandsguide": { "version": "1.0.0", "requirements": [] }, "iotawatt": { "version": "0.2.1", "requirements": [ "iotawattpy==0.1.0" ] }, "plex_recently_added": { "version": "0.3.8", "requirements": [] }, "fullykiosk": { "version": "1.0.1", "requirements": [ "python-fullykiosk==0.0.11" ] }, "weatherflow": { "version": "1.0.4", "requirements": [ "pyweatherflowrest==1.0.8" ] }, "smartthinq_sensors": { "version": "0.12.12", "requirements": [ "pycountry>=20.7.3", "xmltodict>=0.12.0" ] }, "bureau_of_meteorology": { "version": "1.1.2", "requirements": [] }, "goodwe": { "version": "1.0.0", "requirements": [ "goodwe==0.2.17" ] }, "hacs": { "version": "1.24.5", "requirements": [ "aiogithubapi>=21.11.0" ] }, "spotcast": { "version": "v3.6.29", "requirements": [ "spotify_token==1.0.0" ] }, "sonoff": { "version": "3.0.3", "requirements": [ "pycryptodome>=3.6.6" ] }, "watchman": { "version": "0.5.0", "requirements": [ "prettytable==3.0.0" ] } }, "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.72", "zigpy-deconz==0.14.0", "zigpy==0.44.2", "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": 45888, "manufacturer": "_TZE200_arge1ptm", "model": "TS0601", "name": "_TZE200_arge1ptm TS0601", "quirk_applied": false, "quirk_class": "zigpy.device.Device", "manufacturer_code": 4417, "power_source": "Battery or Unknown", "lqi": 87, "rssi": null, "last_seen": "2022-05-06T20:18:03", "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": "09f15feed7b6da3de8ba64044d92e581", "area_id": null } } ```
Tropaion commented 2 years ago

Try if this quirk works: ts0601_valve.zip

wishie commented 2 years ago

No entities still :( Although it appears that the quirk is being loaded.

Screen Shot 2022-05-07 at 8 12 34 am

dedwards66 commented 2 years ago

I just got this smart water valve as well. If there is anything I can do to help let me know.

javicalle commented 2 years ago

Any link to the device description and its functionalities? It will be necessary to translate the Tuya DPs to standard Zigbee clusters and without the messaging or knowing what the device can do it will be complicated

wishie commented 2 years ago

This is the best i can do is a link to where I bought it.

Tuya Smart WiFi Valve Watering Timer 1/2' 3/4'  Timing Alexa Google ON/OFF Percentage Control Garden Irrigator

https://www.aliexpress.com/item/1005003703086386.html

wishie commented 2 years ago

As far as I can tell, it supports (just guessing based on product description)

Open Close Open/Close to a percentage

Like a window cover/blind does, I believe.

javicalle commented 2 years ago

This quirk isn't going to work, but I hope it gives us the information we need to set it up. Although it will show you 2 new entities in HA, these will not work.

ts0601_valve.py ```python """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.clusters.general import ( Basic, Groups, Ota, PowerConfiguration, Scenes, Time, ) from zhaquirks.const import ( DEVICE_TYPE, ENDPOINTS, INPUT_CLUSTERS, MODELS_INFO, OUTPUT_CLUSTERS, PROFILE_ID, ) from zhaquirks.tuya.mcu import ( DPToAttributeMapping, TuyaAttributesCluster, TuyaDPType, TuyaLevelControl, TuyaMCUCluster, TuyaOnOff, ) _LOGGER = logging.getLogger(__name__) class TuyaPowerConfiguration(PowerConfiguration, TuyaAttributesCluster): """Tuya PowerConfiguration.""" class TuyaValveManufCluster(TuyaMCUCluster): """Tuya valve manufacturer cluster.""" attributes = TuyaMCUCluster.attributes.copy() attributes.update( { 0xEF02: ("dp_2", t.uint32_t, True), 0xEF65: ("dp_101", t.uint32_t, True), } ) dp_to_attribute: Dict[int, DPToAttributeMapping] = { # 1: DPToAttributeMapping( # TuyaOnOff.ep_attribute, # "on_off", # dp_type=TuyaDPType.BOOL, # ), 2: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "dp_2", dp_type=TuyaDPType.VALUE, ), 3: DPToAttributeMapping( TuyaLevelControl.ep_attribute, "current_level", dp_type=TuyaDPType.VALUE, converter=lambda x: (x * 255) // 1000, dp_converter=lambda x: (x * 1000) // 255, ), 101: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "dp_101", dp_type=TuyaDPType.VALUE, ), # 104: DPToAttributeMapping( # TuyaLevelControl.ep_attribute, # "dp_104", # dp_type=TuyaDPType.BITMAP, # ), } data_point_handlers = { # 1: "_dp_2_attr_update", 2: "_dp_2_attr_update", 3: "_dp_2_attr_update", 101: "_dp_2_attr_update", # 104: "_dp_2_attr_update", } class TuyaValve(CustomDevice): """Tuya valve device.""" signature = { MODELS_INFO: [("_TZE200_arge1ptm", "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, TuyaValveManufCluster.cluster_id, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], } }, } replacement = { ENDPOINTS: { 1: { DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, TuyaValveManufCluster, TuyaOnOff, TuyaLevelControl, TuyaPowerConfiguration, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], } } } ```

It is absolutely necessary that you provide the traces of the device. After pairing, remove the batteries and put them back. Normally the device will report its status, which should give us the list of DP's it uses.

wishie commented 2 years ago

I am new to all of this, and unsure how to get 'traces'.

But if I do as you said above, and filter the logs based on 'ts0601' I get the following output

2022-05-09 08:17:15 DEBUG (MainThread) [zhaquirks] Loading quirks module zhaquirks.tuya.air.ts0601_air_quality
2022-05-09 08:17:15 DEBUG (MainThread) [zhaquirks] Loading quirks module zhaquirks.tuya.ts0601_co
2022-05-09 08:17:15 DEBUG (MainThread) [zhaquirks] Loading quirks module zhaquirks.tuya.ts0601_cover
2022-05-09 08:17:15 DEBUG (MainThread) [zhaquirks] Loading quirks module zhaquirks.tuya.ts0601_dimmer
2022-05-09 08:17:15 DEBUG (MainThread) [zhaquirks] Loading quirks module zhaquirks.tuya.ts0601_din_power
2022-05-09 08:17:15 DEBUG (MainThread) [zhaquirks] Loading quirks module zhaquirks.tuya.ts0601_electric_heating
2022-05-09 08:17:15 DEBUG (MainThread) [zhaquirks] Loading quirks module zhaquirks.tuya.ts0601_gas
2022-05-09 08:17:15 DEBUG (MainThread) [zhaquirks] Loading quirks module zhaquirks.tuya.ts0601_motion
2022-05-09 08:17:15 DEBUG (MainThread) [zhaquirks] Loading quirks module zhaquirks.tuya.ts0601_siren
2022-05-09 08:17:15 DEBUG (MainThread) [zhaquirks] Loading quirks module zhaquirks.tuya.ts0601_smoke
2022-05-09 08:17:15 DEBUG (MainThread) [zhaquirks] Loading quirks module zhaquirks.tuya.ts0601_switch
2022-05-09 08:17:15 DEBUG (MainThread) [zhaquirks] Loading quirks module zhaquirks.tuya.ts0601_trv
2022-05-09 08:17:15 DEBUG (MainThread) [zhaquirks] Loading quirks module zhaquirks.tuya.ts0601_trv_sas
2022-05-09 08:17:15 DEBUG (MainThread) [zhaquirks] Loading custom quirks module ts0601_valve
2022-05-09 08:17:16 DEBUG (MainThread) [zigpy.appdb] [0xef6a:1:0x0000] Attribute id: 5 value: TS0601
2022-05-09 08:17:16 DEBUG (MainThread) [zigpy.quirks.registry] Checking quirks for _TZE200_arge1ptm TS0601 (a4:c1:38:ce:0d:f4:c7:bc)
2022-05-09 08:17:16 DEBUG (MainThread) [zigpy.quirks.registry] Considering <class 'ts0601_valve.TuyaValve'>
2022-05-09 08:17:16 DEBUG (MainThread) [zigpy.quirks.registry] Found custom device replacement for a4:c1:38:ce:0d:f4:c7:bc: <class 'ts0601_valve.TuyaValve'>
2022-05-09 08:17:16 DEBUG (MainThread) [zigpy.appdb] [0xef6a:1:0x0000] Attribute id: 5 value: TS0601
2022-05-09 08:17:26 DEBUG (MainThread) [homeassistant.components.zha.core.gateway] [0xEF6A](_TZE200_arge1ptm TS0601) restored as 'available', last seen: 0:00:57 ago, consider_unavailable_time: 21600 seconds
2022-05-09 08:17:26 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xEF6A](TS0601): started initialization
2022-05-09 08:17:26 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0xEF6A:ZDO](TS0601): 'async_initialize' stage succeeded
2022-05-09 08:17:26 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xEF6A](TS0601): power source: Battery or Unknown
2022-05-09 08:17:26 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xEF6A](TS0601): completed initialization
2022-05-09 08:17:26 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event entity_registry_updated[L]: action=create, entity_id=light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off>
2022-05-09 08:17:26 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event entity_registry_updated[L]: action=create, entity_id=sensor.tze200_arge1ptm_ts0601_bcc7f40d_power>
2022-05-09 08:17:26 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off, old_state=None, new_state=<state light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off=off; supported_color_modes=[<ColorMode.BRIGHTNESS: 'brightness'>], off_brightness=None, friendly_name=_TZE200_arge1ptm TS0601 bcc7f40d level, on_off, supported_features=33 @ 2022-05-09T08:17:26.743013+10:00>>
2022-05-09 08:17:26 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=sensor.tze200_arge1ptm_ts0601_bcc7f40d_power, old_state=None, new_state=<state sensor.tze200_arge1ptm_ts0601_bcc7f40d_power=unknown; state_class=measurement, unit_of_measurement=%, device_class=battery, friendly_name=_TZE200_arge1ptm TS0601 bcc7f40d power @ 2022-05-09T08:17:26.755523+10:00>>
2022-05-09 08:18:20 DEBUG (MainThread) [zigpy.application] Device is initialized <TuyaValve model='TS0601' manuf='_TZE200_arge1ptm' nwk=0xAEB4 ieee=a4:c1:38:ce:0d:f4:c7:bc is_initialized=True>
2022-05-09 08:18:20 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xAEB4](TS0601): started configuration
2022-05-09 08:18:20 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0xAEB4:ZDO](TS0601): 'async_configure' stage succeeded
2022-05-09 08:18:20 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xAEB4](TS0601): completed configuration
2022-05-09 08:18:20 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xAEB4](TS0601): stored in registry: ZhaDeviceEntry(name='_TZE200_arge1ptm TS0601', ieee='a4:c1:38:ce:0d:f4:c7:bc', last_seen=1652048300.062236)
2022-05-09 08:18:20 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xAEB4](TS0601): Update device availability - device available: False - new availability: True - changed: True
2022-05-09 08:18:20 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xAEB4](TS0601): Device availability changed and device became available, reinitializing channels
2022-05-09 08:18:20 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xAEB4](TS0601): started initialization
2022-05-09 08:18:20 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0xAEB4:ZDO](TS0601): 'async_initialize' stage succeeded
2022-05-09 08:18:20 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xAEB4](TS0601): power source: Battery or Unknown
2022-05-09 08:18:20 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xAEB4](TS0601): completed initialization
2022-05-09 08:18:55 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xAEB4](TS0601): Device seen - marking the device available and resetting counter
2022-05-09 08:18:55 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xAEB4](TS0601): Update device availability - device available: True - new availability: True - changed: False
2022-05-09 08:20:24 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xAEB4](TS0601): Device seen - marking the device available and resetting counter
2022-05-09 08:20:24 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xAEB4](TS0601): Update device availability - device available: True - new availability: True - changed: False
2022-05-09 08:21:53 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xAEB4](TS0601): Device seen - marking the device available and resetting counter
2022-05-09 08:21:53 DEBUG (MainThread) [homeassistant.components.zha.core.device] [0xAEB4](TS0601): Update device availability - device available: True - new availability: True - changed: False
javicalle commented 2 years ago

Yes, that is what we need (I was referring to the logs).

Have you tried removing and inserting the batteries? I missed any device status report in the logs. Is there a button or something that can be operated from the device?

wishie commented 2 years ago

There is a button on the side of the device. I believe 'tap' toggles open/close and holding it is how you pair the device it seems.

I will try toggling it and watching the logs when I get home in about 3hrs.

wishie commented 2 years ago
Logger: zigpy.zcl
Source: /usr/local/lib/python3.9/site-packages/zhaquirks/tuya/__init__.py:1390 
First occurred: 8:18:29 AM (91 occurrences) 
Last logged: 5:27:19 PM

[0xAEB4:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=100, dp=3, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\n\x00\x00\x00', *payload=10)))
[0xAEB4:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=101, dp=3, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x00\x00\x00\x00', *payload=0)))
[0xAEB4:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=102, dp=2, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x00\x00\x00\x00', *payload=0)))
[0xAEB4:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=103, dp=101, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x00\x00\x00\x00', *payload=0)))
[0xAEB4:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=104, dp=104, data=TuyaData(dp_type=<TuyaDPType.BITMAP: 5>, function=0, raw=b'\x00', *payload=<bitmap8.0: 0>)))

and

[0xAEB4:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=127, dp=104, data=TuyaData(dp_type=<TuyaDPType.BITMAP: 5>, function=0, raw=b'\x00', *payload=<bitmap8.0: 0>)))
[0xAEB4:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=128, dp=2, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'd\x00\x00\x00', *payload=100)))
[0xAEB4:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=129, dp=3, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x00\x00\x00\x00', *payload=0)))
[0xAEB4:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=130, dp=3, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x14\x00\x00\x00', *payload=20)))
[0xAEB4:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=131, dp=3, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x1e\x00\x00\x00', *payload=30)))
wishie commented 2 years ago

so the 'payload' appears to be the current position. hopefully this information helps.

dedwards66 commented 2 years ago

Thanks for both of your help with this. From what I have seen from other wafer valves I doubt that it would support partial open/close. If the device is reporting a percentage value it might be a charge level on the batteries or solar panel.

On Mon, May 9, 2022 at 1:32 AM wishie @.***> wrote:

so the 'payload' appears to be the current position. hopefully this information helps.

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

javicalle commented 2 years ago

There are at least 4 Tuya DP Normally DP2 is associated with DIM values in the lights, but it is not certain that it will be also here. DP104 have an usual (at least to me) BITMAP type. Let's put it aside for now. I'm not familiar with the workings (and implementations) of water valves, but let's try something.

I have updated the code of the class with the detected DPs. The DP2 will respond to the dim events of the light entity that you must have in HA. You can get & set the DPs 3 and 101 from the device view as attributes of TuyaValveManufCluster cluster.

Update the code in your local file, delete any __pycache__ folder and restart. Try to play with the dimmer and attributes and get the logs for further analysis.

javicalle commented 2 years ago

If the device is reporting a percentage value it might be a charge level on the batteries or solar panel.

Maybe these 0, 20 and 30 values for DP3? @wishie any thought about this? Can be these logs from diferents times? or are all from the same moment?

wishie commented 2 years ago

From the same moment when pressing the button to open/close the valve.One of its selling points is being able to partially open etc, instead of a simple open or closed.On 10 May 2022 5:11 am, javicalle @.***> wrote:

If the device is reporting a percentage value it might be a charge level on the batteries or solar panel.

Maybe these 0, 20 and 30 values for DP3? @wishie any thought about this? Can be these logs from diferents times? or are all from the same momment?

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: @.***>

wishie commented 2 years ago

I will do this shortly when I am at my desk. Give me 30-45 minutes.On 10 May 2022 5:09 am, javicalle @.***> wrote: There are at least 4 Tuya DP Normally DP2 is associated with DIM values in the lights, but it is not certain that it will be also here. DP104 have an usual (at least to me) BITMAP type. Let's put it aside for now. I'm not familiar with the workings (and implementations) of water valves, but let's try something. I have updated the code of the class with the detected DPs. The DP2 will respond to the dim events of the light entity that you must have in HA. You can get & set the DPs 3 and 101 from the device view as attributes of TuyaValveManufCluster cluster. Update the code in your local file, delete any pycache folder and restart. Try to play with the dimmer and attributes and get the logs for further analysis.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you authored the thread.Message ID: @.***>

wishie commented 2 years ago

Ok, so the switch and slider in HA do nothing, but I am confident that the values shown are percentages of open/close as I watched them go 10, 20, 30, 40 etc etc as the valve moved. Also, the unit is sold as "ON/OFF Percentage Control Garden Irrigator"

wishie commented 2 years ago

I have subscribed to zha_event in Developer Tools in HA and pressed the button on the device.. nothing. Does this indicate we are looking at the wrong DP?

wishie commented 2 years ago

Logs show:

[0x3148:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=72, dp=110, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'd\x00\x00\x00', *payload=100)))
8:18:26 AM – (WARNING) /usr/local/lib/python3.9/site-packages/zhaquirks/tuya/__init__.py - message first occurred at 8:05:07 AM and shows up 13 times
[0xAEB4:1:0xef00] no MCU command for data TuyaClusterData(endpoint_id=1, cluster_attr='on_off', attr_value=1, expect_reply=True)
8:17:49 AM – (WARNING) /usr/local/lib/python3.9/site-packages/zhaquirks/tuya/mcu/__init__.py - message first occurred at 8:02:27 AM and shows up 16 times
[0xAEB4:1:0xef00] No cluster_dp found for 1, on_off
8:17:49 AM – (WARNING) /usr/local/lib/python3.9/site-packages/zhaquirks/tuya/mcu/__init__.py - message first occurred at 8:02:27 AM and shows up 16 times
wishie commented 2 years ago

Toggle the switch in HA gives the following in the logs:

[0x3148:1:0xef00] no MCU command for data TuyaClusterData(endpoint_id=1, cluster_attr='on_off', attr_value=0, expect_reply=True)
8:24:18 AM – (WARNING) /usr/local/lib/python3.9/site-packages/zhaquirks/tuya/mcu/__init__.py
[0x3148:1:0xef00] No cluster_dp found for 1, on_off
8:24:18 AM – (WARNING) /usr/local/lib/python3.9/site-packages/zhaquirks/tuya/mcu/__init__.py

Adjusting the slider in HA gives the following in the logs:

[0x3148:1:0xef00] no MCU command for data TuyaClusterData(endpoint_id=1, cluster_attr='on_off', attr_value=1, expect_reply=True)
8:25:27 AM – (WARNING) /usr/local/lib/python3.9/site-packages/zhaquirks/tuya/mcu/__init__.py
[0x3148:1:0xef00] No cluster_dp found for 1, on_off
8:25:27 AM – (WARNING) /usr/local/lib/python3.9/site-packages/zhaquirks/tuya/mcu/__init__.py
wishie commented 2 years ago

An update:

Pressing the PHYSICAL BUTTON on the device, while watching the home_assistant.log shows a change.

2022-05-10 08:37:49 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off, old_state=<state light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off=on; supported_color_modes=[<ColorMode.BRIGHTNESS: 'brightness'>], color_mode=brightness, brightness=0, off_brightness=None, friendly_name=_TZE200_arge1ptm TS0601 bcc7f40d level, on_off, supported_features=33 @ 2022-05-10T08:36:06.874516+10:00>, new_state=<state light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off=on; supported_color_modes=[<ColorMode.BRIGHTNESS: 'brightness'>], color_mode=brightness, brightness=25, off_brightness=None, friendly_name=_TZE200_arge1ptm TS0601 bcc7f40d level, on_off, supported_features=33 @ 2022-05-10T08:36:06.874516+10:00>>
2022-05-10 08:39:04 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off, old_state=<state light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off=on; supported_color_modes=[<ColorMode.BRIGHTNESS: 'brightness'>], color_mode=brightness, brightness=25, off_brightness=None, friendly_name=_TZE200_arge1ptm TS0601 bcc7f40d level, on_off, supported_features=33 @ 2022-05-10T08:36:06.874516+10:00>, new_state=<state light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off=on; supported_color_modes=[<ColorMode.BRIGHTNESS: 'brightness'>], color_mode=brightness, brightness=0, off_brightness=None, friendly_name=_TZE200_arge1ptm TS0601 bcc7f40d level, on_off, supported_features=33 @ 2022-05-10T08:36:06.874516+10:00>>
wishie commented 2 years ago

Pressing button on device:

2022-05-10 08:58:26 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off, old_state=<state light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off=on; supported_color_modes=[<ColorMode.BRIGHTNESS: 'brightness'>], color_mode=brightness, brightness=26, off_brightness=None, friendly_name=_TZE200_arge1ptm TS0601 bcc7f40d level, on_off, supported_features=33 @ 2022-05-10T08:36:06.874516+10:00>, new_state=<state light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off=on; supported_color_modes=[<ColorMode.BRIGHTNESS: 'brightness'>], color_mode=brightness, brightness=25, off_brightness=None, friendly_name=_TZE200_arge1ptm TS0601 bcc7f40d level, on_off, supported_features=33 @ 2022-05-10T08:36:06.874516+10:00>>
2022-05-10 08:58:38 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off, old_state=<state light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off=on; supported_color_modes=[<ColorMode.BRIGHTNESS: 'brightness'>], color_mode=brightness, brightness=25, off_brightness=None, friendly_name=_TZE200_arge1ptm TS0601 bcc7f40d level, on_off, supported_features=33 @ 2022-05-10T08:36:06.874516+10:00>, new_state=<state light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off=on; supported_color_modes=[<ColorMode.BRIGHTNESS: 'brightness'>], color_mode=brightness, brightness=0, off_brightness=None, friendly_name=_TZE200_arge1ptm TS0601 bcc7f40d level, on_off, supported_features=33 @ 2022-05-10T08:36:06.874516+10:00>>

Adjusting slider in HA (valve does NOT move):

2022-05-10 08:58:53 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=light, service=turn_on, service_data=entity_id=light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off, brightness_pct=10>
2022-05-10 08:58:53 DEBUG (MainThread) [homeassistant.components.zha.entity] light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off: turned on: {'move_to_level_with_on_off': Default_Response(command_id=4, status=<Status.SUCCESS: 0>)}
2022-05-10 08:58:53 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off, old_state=<state light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off=on; supported_color_modes=[<ColorMode.BRIGHTNESS: 'brightness'>], color_mode=brightness, brightness=0, off_brightness=None, friendly_name=_TZE200_arge1ptm TS0601 bcc7f40d level, on_off, supported_features=33 @ 2022-05-10T08:36:06.874516+10:00>, new_state=<state light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off=on; supported_color_modes=[<ColorMode.BRIGHTNESS: 'brightness'>], color_mode=brightness, brightness=26, off_brightness=None, friendly_name=_TZE200_arge1ptm TS0601 bcc7f40d level, on_off, supported_features=33 @ 2022-05-10T08:36:06.874516+10:00>>
javicalle commented 2 years ago

All the errors regarding No cluster_dp found for 1, on_off are expected because HA manages the device as a light. Can be ommited by now. We are only going to try to find out what are the DPs and their functions.

So, if DP3 can be the open value, let's to put in the level cluster... I had switched DP definitions 2 and 3 in the code. Please update and test. Can you also test to read and change the other DPs values? You can do it from the device view, selecting cluster TuyaValveManufCluster and getting/setting the attribute values.

wishie commented 2 years ago

When I select "TuyaVavleManufCluster" I get 3 cluster attributes:

  1. dp_101 (value: 0)
  2. dp_2 (value: none)
  3. mcc_version (value: 1.0.0)

If I press the button on the unit to open the valve, once fully opened, dp_2 value is '100'. When I close the valve again, dp_2 value is '0'.

dp_101 remains at '0' the entire time. mcc_version remains at '1.0.0' the entire time.

Using "Set Zigbee Attribute" appears to do nothing.

dedwards66 commented 2 years ago

I found the manufacture web page for the valve and they have a support email at support@rehentech.com. I sent an email requesting any information they have. I will let you know if they respond.

javicalle commented 2 years ago

I hope @dedwards66 has luck with his support, but my previous experience with other manufacturer's support hasn't been very positive.

With the latest version I expected the dim bar from the light that is created in HA would reflect the valve ratio (which is what we have assumed that DP3 reports). It is not like this? DP101 could be the timer or countdown value.

To understand why the value assignment doesn't work, we would need the logs when using the "Set Zigbee Attribute" or the dim bar.

dedwards66 commented 2 years ago

Yeah, @javicalle and @wishie I am not expecting much. At your pace, I am sure you will have this sorted out before I hear anything, but if you don't ask the answer is always no. Thanks for working on this, now that I know it can control the flow to a percentage I would like to get a few of these set up for my wife's garden. Here is a question, if I had the Tuya hub is there an easy way to sniff the Zigbee traffic, or is it easier to just reverse engineer it. I might consider getting one for sniffing future Tuya stuff if there is value.

javicalle commented 2 years ago

There's a way, but I don't know if it is an easy one. It requires to have a device acting as sniffer in the same network. Then, it would be doable.

Unfortunately, I am not the right person for give you advices in that matter.

tube0013 commented 2 years ago

If it's this device (https://www.aliexpress.com/item/1005003703086386.html) I have one on it's way and have a tuya gateway I bought a while back to take a look inside, but have never set up. I can definitely do some sniffing once it arrives.

wishie commented 2 years ago

If it's this device (https://www.aliexpress.com/item/1005003703086386.html) I have one on it's way and have a tuya gateway I bought a while back to take a look inside, but have never set up. I can definitely do some sniffing once it arrives.

That looks like the device, yes.

wishie commented 2 years ago

With the latest version I expected the dim bar from the light that is created in HA would reflect the valve ratio (which is what we have assumed that DP3 reports). It is not like this? DP101 could be the timer or countdown value.

To understand why the value assignment doesn't work, we would need the logs when using the "Set Zigbee Attribute" or the dim bar.

I don't think DP3 is exposed. Only 101, 2, and MCU_VERSION.

I will get some logs while doing "Set ZigBee Attribute" when I get home today (its 9AM now)

javicalle commented 2 years ago

DP3 is 'linked' to current-level attribute on LevelControl cluster:

        3: DPToAttributeMapping(
            TuyaLevelControl.ep_attribute,
            "current_level",
            dp_type=TuyaDPType.VALUE,
            converter=lambda x: (x * 255) // 1000,
            dp_converter=lambda x: (x * 1000) // 255,
        ),

This cluster creates a dimmable light on HA. That's the reason there are some on command errors, because the HA behaviour. You can also get the attribute value from the device view.

dedwards66 commented 2 years ago

Well I made contact with an actual human at sales support. They immediately thought I was requesting Google Assistant support. I asked if they could let me talk to the engineer who wrote the protocols. I expect to be ghosted or politely declined, but here is hoping.

wishie commented 2 years ago

Ok, so here is an observation.

I am playing with DP3 at the moment (current_level).. it seems to be from 0 to 25.

0 = Fully Closed 25 = Fully Open

If the valve is fully open (current_level = 25) and I change to '0' and press "SET ZIGBEE ATTRIBUTE" I see the following in the logs:

2022-05-11 16:18:38 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off, old_state=<state light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off=on; supported_color_modes=[<ColorMode.BRIGHTNESS: 'brightness'>], color_mode=brightness, brightness=25, off_brightness=None, friendly_name=_TZE200_arge1ptm TS0601 bcc7f40d level, on_off, supported_features=33 @ 2022-05-11T16:05:24.411168+10:00>, new_state=<state light.tze200_arge1ptm_ts0601_bcc7f40d_level_on_off=on; supported_color_modes=[<ColorMode.BRIGHTNESS: 'brightness'>], color_mode=brightness, brightness=0, off_brightness=None, friendly_name=_TZE200_arge1ptm TS0601 bcc7f40d level, on_off, supported_features=33 @ 2022-05-11T16:05:24.411168+10:00>>

But, the valve does not move.

wishie commented 2 years ago

DP2 = 0 or 100 DP3 = 0 to 25 (0 = fully closed, 25 = fully open) DP101 = 0

dedwards66 commented 2 years ago

Is this a ZHA quirk for this device?

dedwards66 commented 2 years ago

I found this page on adding Tuya devices to ZigbeeToMQTT.

wishie commented 2 years ago

Is this a ZHA quirk for this device?

It appears to be a quirk for some other device, which has temperature control and other things.

dedwards66 commented 2 years ago

It appears to be a quirk for some other device, which has temperature control and other things.

The TS0601 got me excited and then I saw things for valve position and battery level and missed the other things. It looks like there are a lot of "TS0601" devices. I wonder if these devices are based on a standard template from Tuya.

tube0013 commented 2 years ago

I got mine today. here's a basic capture from the tuya gateway paring, and then turning it on to 50%, then 75% then 100% then off. I'll hook up to a water line tomorrow and get some captures to see if it reads flow rate.

Valve_join_On50-75-100-Off.pcapng.zip

key: 2b8cfd4ec0b120ac9d32050a87404dc8

wishie commented 2 years ago

Hopefully we can make some more progress soon then :)

Thanks for the update.

dedwards66 commented 2 years ago

Thanks very much for this!

MattWestb commented 2 years ago

Thanks @tube0013 i taking on look in the evening after work is being done and see what tuya is doing, perhaps they casting some magic :-)))) The DP side i dont knowing so well but @javicalle is more family with that.

dedwards66 commented 2 years ago

Since it has been over 10 years since I last played with Wireshark, I am a little confused about the encrypted payloads in the ZigBee. I assumed that the key @tube0013 included is needed, but I am unsure as to where to put it.

tube0013 commented 2 years ago

Since it has been over 10 years since I last played with Wireshark, I am a little confused about the encrypted payloads in the ZigBee. I assumed that the key @tube0013 included is needed, but I am unsure as to where to put it.

z2m has guide to this in their docs https://www.zigbee2mqtt.io/advanced/zigbee/04_sniff_zigbee_traffic.html#_3-sniffing-traffic

basically Preferences>Protocols>Zigbee and then you can open the key store and add it in.

tube0013 commented 2 years ago

I hooked it up to water, it was less than optimal connection due to crapy hose bib. But from using it very limitedly with the tuya app, there is no flow rate reported it just shows how open the valve is in 5% increments and runs a timer for how long long it's open.

valve.pcapng.zip

DIdn't really look too much into the capture, and not sure if my nordic stick sniffer caught all the traffic due to range.

dedwards66 commented 2 years ago

basically Preferences>Protocols>Zigbee and then you can open the key store and add it in.

Thanks for the link and the summary. I will have to look at that later today.

MattWestb commented 2 years ago

Some interesting for tubes sniff. I have only looking on the pairing then tuya ZBGW is setting up the device / Zigbee chip and after that is only DP commands that is out of my scope. First we is knowing that also tuya DP devices can needing the tuya magic spell for working OK then the Zigbee module is sending some data to the MCU for configuring it. Then the device is joining its reporting one attribute then its have getting the network key (its not normal):

ZigBee Network Layer Data, Dst: 0x0000, Src: 0xef44
ZigBee Application Support Layer Data, Dst Endpt: 1, Src Endpt: 1
    Frame Control Field: Data (0x00)
    Destination Endpoint: 1
    Cluster: Basic (0x0000)
    Profile: Home Automation (0x0104)
    Source Endpoint: 1
    Counter: 228
ZigBee Cluster Library Frame, Command: Report Attributes, Seq: 190
    Frame Control Field: Profile-wide (0x08)
    Sequence Number: 190
    Command: Report Attributes (0x0a)
    Attribute Field, Uint8: 70
        Attribute: Application Version (0x0001)
        Data Type: 8-Bit Unsigned Integer (0x20)
        Uint8: 70 (0x46)
    Attribute Field, Uint8: 54
        Attribute: Unknown (0xffe2)
        Data Type: 8-Bit Unsigned Integer (0x20)
        Uint8: 54 (0x36)
    Attribute Field, Uint8: 1
        Attribute: Unknown (0xffe4)
        Data Type: 8-Bit Unsigned Integer (0x20)
        Uint8: 1 (0x01)

then the normal tuya init with one magic spell being casted:

ZigBee Network Layer Data, Dst: 0xef44, Src: 0x0000
ZigBee Application Support Layer Data, Dst Endpt: 255, Src Endpt: 1
    Frame Control Field: Data (0x40)
    Destination Endpoint: 255
    Cluster: Basic (0x0000)
    Profile: Home Automation (0x0104)
    Source Endpoint: 1
    Counter: 48
ZigBee Cluster Library Frame, Command: Read Attributes, Seq: 22
    Frame Control Field: Profile-wide (0x10)
    Sequence Number: 22
    Command: Read Attributes (0x00)
    Attribute: Manufacturer Name (0x0004)
    Attribute: ZCL Version (0x0000)
    Attribute: Application Version (0x0001)
    Attribute: Model Identifier (0x0005)
    Attribute: Power Source (0x0007)
    Attribute: Unknown (0xfffe)

(its sent to EP 255 and the coordinator is acking it back from EP 255 !!!) and the rest is normal INIT until the device is requesting one update of the trust center link key the coordinator is sending this:

ZigBee Network Layer Data, Dst: 0xef44, Src: 0x0000
ZigBee Application Support Layer Data, Dst Endpt: 1, Src Endpt: 1
    Frame Control Field: Data (0x00)
    Destination Endpoint: 1
    Cluster: Basic (0x0000)
    Profile: Home Automation (0x0104)
    Source Endpoint: 1
    Counter: 52
ZigBee Cluster Library Frame, Command: Write Attributes, Seq: 23
    Frame Control Field: Profile-wide (0x10)
    Sequence Number: 23
    Command: Write Attributes (0x02)
    Attribute Field, Uint8: 13
        Attribute: Unknown (0xffde)
        Data Type: 8-Bit Unsigned Integer (0x20)
        Uint8: 13 (0x0d)

five times and then sending the updated key ( = the INIT is made). The MCU is sending its DPs to the host system as normal. The device is sending:

ZigBee Network Layer Data, Dst: 0x0000, Src: 0xef44
ZigBee Application Support Layer Data, Dst Endpt: 1, Src Endpt: 1
    Frame Control Field: Data (0x00)
    Destination Endpoint: 1
    Cluster: Basic (0x0000)
    Profile: Home Automation (0x0104)
    Source Endpoint: 1
    Counter: 251
ZigBee Cluster Library Frame, Command: Report Attributes, Seq: 200
    Frame Control Field: Profile-wide (0x08)
    Sequence Number: 200
    Command: Report Attributes (0x0a)
    Attribute Field, String: 
        Attribute: Unknown (0xffdf)
        Data Type: Character String (0x42)
        String: 

Plus one normal time request:

ZigBee Network Layer Data, Dst: 0x0000, Src: 0xef44
ZigBee Application Support Layer Data, Dst Endpt: 1, Src Endpt: 1
    Frame Control Field: Data (0x00)
    Destination Endpoint: 1
    Cluster: Time (0x000a)
    Profile: Home Automation (0x0104)
    Source Endpoint: 1
    Counter: 252
ZigBee Cluster Library Frame, Command: Read Attributes, Seq: 201
    Frame Control Field: Profile-wide (0x00)
    Sequence Number: 201
    Command: Read Attributes (0x00)
    Attribute: Local Time (0x0007)

and the coordinator is responding:

ZigBee Network Layer Data, Dst: 0xef44, Src: 0x0000
ZigBee Application Support Layer Data, Dst Endpt: 1, Src Endpt: 1
    Frame Control Field: Data (0x00)
    Destination Endpoint: 1
    Cluster: Time (0x000a)
    Profile: Home Automation (0x0104)
    Source Endpoint: 1
    Counter: 74
ZigBee Cluster Library Frame, Command: Read Attributes Response, Seq: 201
    Frame Control Field: Profile-wide (0x18)
    Sequence Number: 201
    Command: Read Attributes Response (0x01)
    Status Record, Uint32: 705710509
        Attribute: Local Time (0x0007)
        Status: Success (0x00)
        Data Type: 32-Bit Unsigned Integer (0x23)
        Uint32: 705710509 (0x2a1049ad)

And the rest is normal DP communication.

If not getting the MCU working ok its needed casting one normal tuya magic spell on the module then it joining the network (as being done with the TS004F DMS) and if its not enough trye sending the 0xffde after the normal magic is being casted and perhaps also the 0xffdf.

All the MCU commands is better persons with more knowledge is looking on if its somthing interesting but need copy every data sent from the DP cluster and encoding it by hand for doing it.

javicalle commented 2 years ago

I haven't had time to review the Zigbee messaging sniff (I have to look where I have the Wireshark...), but I have a new proposal:

ts0601_valve.py ```python """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.clusters.general import ( Basic, Groups, Ota, PowerConfiguration, Scenes, Time, ) from zhaquirks.const import ( DEVICE_TYPE, ENDPOINTS, INPUT_CLUSTERS, MODELS_INFO, OUTPUT_CLUSTERS, PROFILE_ID, ) from zhaquirks.tuya.mcu import ( DPToAttributeMapping, TuyaAttributesCluster, TuyaDPType, TuyaLevelControl, TuyaMCUCluster, TuyaOnOff, ) from zhaquirks.tuya.ts0601_dimmer import NoManufacturerCluster, TuyaOnOffNM _LOGGER = logging.getLogger(__name__) class TuyaPowerConfiguration(PowerConfiguration, TuyaAttributesCluster): """Tuya PowerConfiguration.""" class TuyaLevelControlNM(NoManufacturerCluster, TuyaLevelControl): """Tuya LevelControl cluster with NoManufacturerID.""" class TuyaValveManufCluster(TuyaMCUCluster): """Tuya valve manufacturer cluster.""" attributes = TuyaMCUCluster.attributes.copy() attributes.update( { 0xEF02: ("dp_2", t.uint32_t, True), 0xEF65: ("dp_101", t.uint32_t, True), } ) dp_to_attribute: Dict[int, DPToAttributeMapping] = { # 1: DPToAttributeMapping( # TuyaOnOff.ep_attribute, # "on_off", # dp_type=TuyaDPType.BOOL, # ), 2: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "dp_2", dp_type=TuyaDPType.VALUE, ), 3: DPToAttributeMapping( TuyaLevelControl.ep_attribute, "current_level", dp_type=TuyaDPType.VALUE, converter=lambda x: (x * 255) // 100, dp_converter=lambda x: (x * 100) // 255, ), 101: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "dp_101", dp_type=TuyaDPType.VALUE, ), # 104: DPToAttributeMapping( # TuyaLevelControl.ep_attribute, # "dp_104", # dp_type=TuyaDPType.BITMAP, # ), } data_point_handlers = { # 1: "_dp_2_attr_update", 2: "_dp_2_attr_update", 3: "_dp_2_attr_update", 101: "_dp_2_attr_update", # 104: "_dp_2_attr_update", } class TuyaValve(CustomDevice): """Tuya valve device.""" signature = { MODELS_INFO: [("_TZE200_arge1ptm", "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, TuyaValveManufCluster.cluster_id, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], } }, } replacement = { ENDPOINTS: { 1: { DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT, INPUT_CLUSTERS: [ Basic.cluster_id, Groups.cluster_id, Scenes.cluster_id, TuyaValveManufCluster, TuyaOnOffNM, TuyaLevelControlNM, TuyaPowerConfiguration, ], OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], } } } ```

I have fixed the DP3 values. Now the range must be 0-254 (same as dim values) Now the NO_MANUFACTURER_ID is used in Zigbee.