This is what I have.
Works for a while then disconnects…
"""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,
TuyaDPType,
)
from zhaquirks.tuya.mcu import (
DPToAttributeMapping,
TuyaAttributesCluster,
TuyaMCUCluster,
TuyaOnOffNM,
TuyaPowerConfigurationCluster,
)
# info from https://github.com/Koenkk/zigbee-herdsman-converters/blob/7ecea3b807ec7643493f94614e84d0343423267d/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"),
("_TZE204_7ytb3h8u", "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,
TuyaOnOffNM,
TuyaPowerConfigurationCluster,
TuyaValveWaterConsumed,
GiexTuyaValveManufCluster,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
}
}
}