-
Notifications
You must be signed in to change notification settings - Fork 726
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Device Support Request] SASWELL SAS980SWT-7-Z01 (_TZE200_akjefhj5, TS0601) Smart Irrigation Valve #1668
Comments
OK, I made a lot of trial and error with my main HA instance (too hard to implement the conbee on my development instance) and I managed to get the battery reporting to work correctly. Had to hack a bit and overload the handle_message() method into my MCU cluster to be able to use the battery bus and update the correct attribute from power configuration cluster. def handle_message(
self,
hdr,
args,
*,
dst_addressing,
):
if getattr(getattr(args, "data", None), "dp", None) == 7:
_LOGGER.debug(
"%s - TuyaValveManufCluster handling message triggers"
"battery_reported event with value=%s",
self.endpoint.device.nwk,
args.data.data.payload
)
self.endpoint.device.battery_bus.listener_event("battery_reported",
args.data.data.payload
)
return super().handle_message(hdr, args, dst_addressing=dst_addressing) Now working:
Not working yet:
Now, I need to understand how to make my Here is the file : ts0601_TZE200_akjefhj5_valve.py"""Tuya Valve."""
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, Scenes, Time, OnOff
from zigpy.zcl.clusters.smartenergy import Metering
from zhaquirks import Bus, LocalDataCluster, DoublingPowerConfigurationCluster
from zhaquirks.const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PROFILE_ID,
)
from zhaquirks.tuya import (
TuyaLocalCluster,
LocalDataCluster
)
from zhaquirks.tuya.mcu import (
DPToAttributeMapping,
TuyaDPType,
TuyaMCUCluster,
TuyaOnOff,
)
_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.DEBUG)
class TuyaValveWaterConsumed(Metering, TuyaLocalCluster):
"""Tuya Valve Water consumed cluster."""
VOLUME_LITERS = 0x0007
"""Setting unit of measurement."""
_CONSTANT_ATTRIBUTES = {0x0300: VOLUME_LITERS}
class NewDoublingPowerConfigurationCluster(LocalDataCluster, DoublingPowerConfigurationCluster):
"""Doubling Power Configuration cluster to receive reports that are sent to the MCU cluster."""
cluster_id = DoublingPowerConfigurationCluster.cluster_id
BATTERY_ID = 0x0021
def __init__(self, *args, **kwargs):
"""Init."""
super().__init__(*args, **kwargs)
self.endpoint.device.battery_bus.add_listener(self)
def battery_reported(self, value):
"""Battery reported."""
self._update_attribute(self.BATTERY_ID, value)
class TuyaValveManufCluster(TuyaMCUCluster):
"""On/Off Tuya cluster with extra device attributes."""
def handle_message(
self,
hdr,
args,
*,
dst_addressing,
):
if getattr(getattr(args, "data", None), "dp", None) == 7:
_LOGGER.debug(
"%s - TuyaValveManufCluster handling message triggers"
"battery_reported event with value=%s",
self.endpoint.device.nwk,
args.data.data.payload
)
self.endpoint.device.battery_bus.listener_event("battery_reported",
args.data.data.payload
)
return super().handle_message(hdr, args, dst_addressing=dst_addressing)
attributes = TuyaMCUCluster.attributes.copy()
attributes.update(
{
# 7: ("battery_percentage_remaining", t.uint16_t, True),
0xEF0B: ("time_left", t.uint16_t, True),
0xEF0C: ("state", t.enum8, True),
0xEF0F: ("last_valve_open_duration", t.uint16_t, True),
}
)
dp_to_attribute: Dict[int, DPToAttributeMapping] = {
1: DPToAttributeMapping(
TuyaOnOff.ep_attribute,
"on_off",
dp_type=TuyaDPType.BOOL,
),
5: DPToAttributeMapping(
TuyaValveWaterConsumed.ep_attribute,
"current_summ_delivered",
TuyaDPType.VALUE,
),
7: DPToAttributeMapping(
# DoublingPowerConfigurationCluster.ep_attribute,
NewDoublingPowerConfigurationCluster.ep_attribute,
"battery_percentage_remaining",
TuyaDPType.VALUE,
),
11: DPToAttributeMapping(
TuyaMCUCluster.ep_attribute,
"time_left",
TuyaDPType.VALUE,
),
12: DPToAttributeMapping(
TuyaMCUCluster.ep_attribute,
"state",
TuyaDPType.VALUE,
),
15: DPToAttributeMapping(
TuyaMCUCluster.ep_attribute,
"last_valve_open_duration",
TuyaDPType.VALUE,
),
}
data_point_handlers = {
1: "_dp_2_attr_update",
5: "_dp_2_attr_update",
7: "_dp_2_attr_update",
11: "_dp_2_attr_update",
12: "_dp_2_attr_update",
15: "_dp_2_attr_update",
}
class TuyaValve(CustomDevice):
"""Tuya valve device."""
def __init__(self, *args, **kwargs):
"""Init."""
self.battery_bus = Bus()
super().__init__(*args, **kwargs)
signature = {
MODELS_INFO: [("_TZE200_akjefhj5", "TS0601")],
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=81, device_version=1,
# input_clusters=[0, 1, 4, 5, 6, 1794, 61184], output_clusters=[25, 10])
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
INPUT_CLUSTERS: [
Basic.cluster_id,
# PowerConfiguration.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
# OnOff.cluster_id,
TuyaValveManufCluster.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
}
},
}
replacement = {
ENDPOINTS: {
1: {
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
INPUT_CLUSTERS: [
Basic.cluster_id,
# PowerConfiguration.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaOnOff,
TuyaValveWaterConsumed, # attr 0 = last volume delivered
NewDoublingPowerConfigurationCluster,
#DoublingPowerConfigurationCluster,
# OnOff.cluster_id,
TuyaValveManufCluster,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
}
}
} |
Hi, I will try to give you support in all the issues, but lately I don't have much free time and I think that the diferent timezone is not going to help (UTC+2 here). My first recommendation (if you're not doing it already) work with a local quirk in your installation, avoiding modifying the original class. That way it will be easier to create a PR and detect the changes. If you need to modify existing classes, do it in the local file. Create a new class name with their own signature. Enable debug logs for ZHA. It will be very verbose, but ZHA logs will have valuable information about device reports (DP, data types, values...). The logs will also report if there are unhandled messages (but I think that these comes in WARN level). One important thing to understand is that the device would not be queried from the cluster manager. All the attribute values are local to HA and are updated when device reports its values. So its important to listen at what is telling us the device to be able to understand how is internally working. Now I will try to review all the remaining issues. Battery reportYou have managed to make it work, but with an old implementation (bus) that we are trying to replace.
7: DPToAttributeMapping(
TuyaPowerConfigurationCluster.ep_attribute,
"battery_percentage_remaining",
TuyaDPType.VALUE,
),
replacement = {
ENDPOINTS: {
1: {
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaOnOff,
TuyaValveWaterConsumed, # attr 0 = last volume delivered
TuyaPowerConfigurationCluster,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
}
}
} The value can not be getted from device. You have to wait for the device to report it. Time leftI don't know if this is the same case, but in other valves they have 2 attributes:
I am going to try to help you in this matter, but I am not sure what atribute we are dealing with here (or if there are 2 or just 1). If the The bad new is that only works for one specific device: Soooo, what can be done here?
attributes = TuyaMCUCluster.attributes.copy()
attributes.update(
{
# 7: ("battery_percentage_remaining", t.uint16_t, True),
0xEF0B: ("timer_duration", t.uint32_t, True),
0xEF0C: ("state", t.enum8, True),
0xEF0F: ("last_valve_open_duration", t.uint16_t, True),
}
)
.../...
11: DPToAttributeMapping(
TuyaMCUCluster.ep_attribute,
"timer_duration",
TuyaDPType.VALUE,
),
And, just in case that there was already a The |
Water meteringFor the water metering, we are using the It seems that device is reporting the |
@ScratMan |
@dieneuser , you're welcome. This week-end I transferred my second valve that is used to irrigate my vegetable garden from Tuya to ZHA, and I have discovered that the metering cluster did not create any entity, so with the same code, I get different behaviour from two identical valves. |
I could get a lot of things working, yes, but with ZigBee2MQTT. Unfortunately ZHA doesn't work well to implement the entities as it relies on HA core itself to recognize entities and add them to device's panel. See here if you want to try with Z2M : Koenkk/zigbee-herdsman-converters#5727
I'm still working on the cycling and normal timers programming. They are working, but there is a small bug on the weekdays selection (understood, need to fix it and test); and the valve local time sync doesn't seem to work, as the timers are triggered 6 hours before the requested time (but it acts the same way with Tuya Smart Life app, so it might not be related to my implementation). |
There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates. Please make sure to update to the latest version and check if that solves the issue. Let us know if that works for you by adding a comment 👍 This issue has now been marked as stale and will be closed if no further activity occurs. Thank you for your contributions. |
I own this device and the same one with a slightly different model number. Did you manage to get thisnworking properly? zha seems to only connect but gives no controls |
The other device i have is TS0601 by _TZE204_qtnjuoae Tuya has the same controls, interface etc for them but id like to remove them from smart life to take the cloud out of the picture and use native zigbee |
Discussed in #1660
Originally posted by ScratMan July 25, 2022
Hello,
I need some help to develop the quirk for the SASWELL SAS980SWT-7-Z01 irrigation timer valve, with the vendor ID _TZE200_akjefhj5 and model TS0601.
https://www.saswell.com/smart-irrigation-wifi-water-timer-sas980swt-7-z01_p147.html
I own two units, and I can control it through Tuya SmartLife app, but I'd like to get rid of Tuya app and use Home Assistant instead through ZHA integration.
I've seen that this valve is already available with different vendors (RTX ZVG1 for example), and I could find in ZHA that there is a quirk that looks very similar to the result the scan of my valves but with different vendor ID :
MODELS_INFO: [("_TZE200_81isopgh", "TS0601")],
#1556This valve exists in the ts0601_valve.py file in ZHA device handlers, but unfortunately it seems it doesn't fully matches my valve's description, changing only the vendor ID didn't work, and I had to make some modifications based on some extractions from Tuya logs.
I could grab the following data from my valves :
In the tuya logs I could extract the DP codes using Chrome developers tool, but unfortunately, it doesn't indicates in which cluster the data are available (in bold those showing data received from valves in Tuya developers platform):
and in the debug tool from the Tuya developers platform, I could get the data types
I made some trials copying the TuyaValve class from ts0601_valve.py and made some changes, on the
The full file
With the file as shown above I can get the valve in HA as below :
And regarding what works and what doesn't work :
smartenergy_metering
sensor is supposed to report the volume of water during the last opening of the valve, but it reports garbage. I could fill 5 liters in a bucket, and it indicated 114, then I added 5 more liters and it said 55 ; while it said 615 and 543 when I added some water in my pool (around 150/160 liters both time, in 30mn).TuyaValveManufCluster
:time_left
attribute by writing the value in the field and using 1 in the replacement code before performing the write. Once the new time value written, it remains set up when reading the attribute, and this value is used when switching the valve on. Once the valve is switched off (either manually or after timer end), the value is then reset to 600 seconds.The doubling power management cluster doesn't seem to have the correct battery level configured, but I can't figure where this data is located in the clusters available in the data from the valve to change it in the quirk.
Could someone please help me to understand how to find the correct data point for battery level and water volume consumed and how to make the attributes be reported as sensor entities in HA ? When looking at the python code from the quirks, it looks really abstract to me, despite my knowledge in python. The behavior of the quirk looks strange, when I try to enable the clusters 1 (power configuration) and 6 (on_off) it breaks the quirk, and the modified clusters like
TuyaValveManufCluster
disappear from the interface. But it seems thePowerConfiguration
cluster should be closer to the one used in the valve, or am I wrong ?Thanks for your help.
The text was updated successfully, but these errors were encountered: