-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: migrate to other valve integration since the newer one broke wit…
…h 2024.8
- Loading branch information
Showing
1 changed file
with
94 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,165 +1,152 @@ | ||
"""Royal Gardineer Tuya Water Valve device.""" | ||
"""Collection of Tuya Valve devices e.g. water valves, gas valve etc.""" | ||
from typing import Dict | ||
|
||
from zigpy.profiles import zha | ||
from zigpy.quirks import CustomDevice | ||
from zigpy.quirks.v2 import add_to_registry_v2 | ||
from zigpy.quirks.v2.homeassistant import EntityPlatform, UnitOfTime, EntityType | ||
import zigpy.types as t | ||
from zigpy.zcl.clusters.general import Basic, Groups, Ota, Scenes, Time | ||
from zigpy.zcl.clusters.general import Basic, Groups, Identify, OnOff, Ota, Scenes, Time | ||
from zigpy.zcl.clusters.smartenergy import Metering | ||
|
||
from zhaquirks.tuya import TuyaLocalCluster | ||
from zhaquirks import DoublingPowerConfigurationCluster | ||
from zhaquirks import Bus | ||
from zhaquirks.const import ( | ||
DEVICE_TYPE, | ||
ENDPOINTS, | ||
INPUT_CLUSTERS, | ||
MODELS_INFO, | ||
OUTPUT_CLUSTERS, | ||
PROFILE_ID, | ||
) | ||
from zhaquirks.tuya import ( | ||
TuyaLocalCluster, | ||
TuyaPowerConfigurationCluster, | ||
) | ||
from zhaquirks.tuya.mcu import ( | ||
DPToAttributeMapping, | ||
EnchantedDevice, | ||
# TuyaDPType, | ||
TuyaMCUCluster, | ||
TuyaOnOff, | ||
TuyaPowerConfigurationCluster, | ||
) | ||
|
||
# Timer time left to auto-off. | ||
TIMER_TIME_LEFT_ATTR_ID = 0xEF01 | ||
TIMER_TIME_LEFT_ATTR_NAME = "timer_time_left" | ||
|
||
# Timer state. | ||
TIMER_STATE_ATTR_ID = 0xEF02 | ||
TIMER_STATE_ATTR_NAME = "timer_state" | ||
|
||
# Last valve open duration. | ||
LAST_VALVE_OPEN_DURATION_ATTR_ID = 0xEF03 | ||
LAST_VALVE_OPEN_DURATION_ATTR_NAME = "last_valve_open_duration" | ||
|
||
# Weather delay. | ||
WEATHER_DELAY_ATTR_ID = 0xEF04 | ||
WEATHER_DELAY_ATTR_NAME = "weather_delay" | ||
|
||
class RoyalGardineerWeatherDelay(t.enum8): | ||
"""Royal Gardineer weather delay enum.""" | ||
|
||
Disabled = 0x00 | ||
Delayed_24h = 0x01 | ||
Delayed_48h = 0x02 | ||
Delayed_72h = 0x03 | ||
class TuyaValveWaterConsumed(Metering, TuyaLocalCluster): | ||
"""Tuya Valve Water consumed cluster.""" | ||
|
||
class RoyalGardineerTimerState(t.enum8): | ||
"""Royal Gardineer timer state enum.""" | ||
|
||
Disabled = 0x00 | ||
Active = 0x01 | ||
Enabled = 0x02 | ||
|
||
class RoyalGardineerValveWaterConsumed(Metering, TuyaLocalCluster): | ||
"""Royal Gardineer Tuya Water Valve - water consumed cluster.""" | ||
|
||
UNIT_VOLUME_LITERS = 0x0007 | ||
TYPE_WATER_METERING = 0x02 | ||
VOLUME_LITERS = 0x0007 | ||
|
||
"""Setting unit of measurement.""" | ||
_CONSTANT_ATTRIBUTES = { | ||
0x0300: UNIT_VOLUME_LITERS, | ||
0x0306: TYPE_WATER_METERING, | ||
} | ||
_CONSTANT_ATTRIBUTES = {0x0300: VOLUME_LITERS} | ||
|
||
|
||
class RoyalGardineerValveManufCluster(TuyaMCUCluster): | ||
"""On/Off Royal Gardineer Tuya cluster with extra device attributes.""" | ||
class TuyaValveManufCluster(TuyaMCUCluster): | ||
"""On/Off Tuya cluster with extra device attributes.""" | ||
|
||
attributes = TuyaMCUCluster.attributes.copy() | ||
attributes.update( | ||
{ | ||
TIMER_TIME_LEFT_ATTR_ID: (TIMER_TIME_LEFT_ATTR_NAME, t.uint32_t, True), | ||
TIMER_STATE_ATTR_ID: (TIMER_STATE_ATTR_NAME, RoyalGardineerTimerState, True), | ||
LAST_VALVE_OPEN_DURATION_ATTR_ID: (LAST_VALVE_OPEN_DURATION_ATTR_NAME, t.uint32_t, True), | ||
WEATHER_DELAY_ATTR_ID: (WEATHER_DELAY_ATTR_NAME, RoyalGardineerWeatherDelay, True) | ||
0xEF01: ("time_left", t.uint32_t, True), | ||
0xEF02: ("state", t.enum8, True), | ||
0xEF03: ("last_valve_open_duration", t.uint32_t, True), | ||
0xEF04: ("dp_6", t.uint32_t, True), | ||
} | ||
) | ||
|
||
dp_to_attribute: dict[int, DPToAttributeMapping] = { | ||
dp_to_attribute: Dict[int, DPToAttributeMapping] = { | ||
1: DPToAttributeMapping( | ||
TuyaOnOff.ep_attribute, | ||
"on_off", | ||
# dp_type=TuyaDPType.BOOL, | ||
), | ||
5: DPToAttributeMapping( | ||
RoyalGardineerValveWaterConsumed.ep_attribute, | ||
TuyaValveWaterConsumed.ep_attribute, | ||
"current_summ_delivered", | ||
lambda x: x // 10, | ||
# TuyaDPType.VALUE, | ||
), | ||
6: DPToAttributeMapping( | ||
TuyaMCUCluster.ep_attribute, | ||
"dp_6", | ||
# TuyaDPType.VALUE, | ||
), | ||
7: DPToAttributeMapping( | ||
TuyaPowerConfigurationCluster.ep_attribute, | ||
# DoublingPowerConfigurationCluster.ep_attribute, | ||
"battery_percentage_remaining", | ||
), | ||
10: DPToAttributeMapping( | ||
TuyaMCUCluster.ep_attribute, | ||
"weather_delay", | ||
lambda x: RoyalGardineerWeatherDelay(x), | ||
# TuyaDPType.VALUE, | ||
), | ||
11: DPToAttributeMapping( | ||
TuyaMCUCluster.ep_attribute, | ||
"timer_time_left", | ||
lambda x: x // 60, | ||
lambda x: x * 60, | ||
"time_left", | ||
# TuyaDPType.VALUE, | ||
), | ||
12: DPToAttributeMapping( | ||
TuyaMCUCluster.ep_attribute, | ||
"timer_state", | ||
lambda x: RoyalGardineerTimerState(x), | ||
"state", | ||
# TuyaDPType.VALUE, | ||
), | ||
15: DPToAttributeMapping( | ||
TuyaMCUCluster.ep_attribute, | ||
"last_valve_open_duration", | ||
lambda x: x // 60, | ||
# TuyaDPType.VALUE, | ||
), | ||
#16 - cycle timer, | ||
#17 - normal timer, | ||
} | ||
|
||
data_point_handlers = { | ||
1: "_dp_2_attr_update", | ||
5: "_dp_2_attr_update", | ||
6: "_dp_2_attr_update", | ||
7: "_dp_2_attr_update", | ||
10: "_dp_2_attr_update", | ||
11: "_dp_2_attr_update", | ||
12: "_dp_2_attr_update", | ||
15: "_dp_2_attr_update", | ||
} | ||
|
||
( | ||
add_to_registry_v2("_TZE200_2wg5qrjy", "TS0601") | ||
.replaces(RoyalGardineerValveManufCluster) | ||
.adds(TuyaOnOff) | ||
.adds(RoyalGardineerValveWaterConsumed) | ||
.adds(TuyaPowerConfigurationCluster) | ||
# Timer time left/remaining. | ||
.number( | ||
TIMER_TIME_LEFT_ATTR_NAME, | ||
RoyalGardineerValveManufCluster.cluster_id, | ||
min_value=1, | ||
max_value=600, | ||
step=1, | ||
unit=UnitOfTime.MINUTES, | ||
translation_key="timer_time_left", | ||
) | ||
# Weather delay. | ||
.enum( | ||
WEATHER_DELAY_ATTR_NAME, | ||
RoyalGardineerWeatherDelay, | ||
RoyalGardineerValveManufCluster.cluster_id, | ||
translation_key="weather_delay", | ||
) | ||
# Timer state - read-only. | ||
.enum( | ||
TIMER_STATE_ATTR_NAME, | ||
RoyalGardineerTimerState, | ||
RoyalGardineerValveManufCluster.cluster_id, | ||
entity_platform=EntityPlatform.SENSOR, | ||
entity_type=EntityType.DIAGNOSTIC, | ||
translation_key="timer_state", | ||
) | ||
# Last valve open duration - read-only. | ||
.sensor( | ||
LAST_VALVE_OPEN_DURATION_ATTR_NAME, | ||
RoyalGardineerValveManufCluster.cluster_id, | ||
entity_type=EntityType.DIAGNOSTIC, | ||
unit=UnitOfTime.MINUTES, | ||
translation_key="last_valve_open_duration", | ||
) | ||
) | ||
|
||
class TuyaValve(CustomDevice): | ||
"""Tuya valve device.""" | ||
|
||
def __init__(self, *args, **kwargs): | ||
"""Init device.""" | ||
self.battery_bus = Bus() | ||
super().__init__(*args, **kwargs) | ||
|
||
|
||
signature = { | ||
MODELS_INFO: [("_TZE200_2wg5qrjy", "TS0601")], | ||
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=81, device_version=1, | ||
# input_clusters=[0, 4, 5, 61184], output_clusters=[25, 10]) | ||
ENDPOINTS: { | ||
1: { | ||
PROFILE_ID: zha.PROFILE_ID, | ||
DEVICE_TYPE: zha.DeviceType.SMART_PLUG, | ||
INPUT_CLUSTERS: [ | ||
Basic.cluster_id, | ||
Groups.cluster_id, | ||
Scenes.cluster_id, | ||
TuyaValveManufCluster.cluster_id, | ||
], | ||
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], | ||
} | ||
}, | ||
} | ||
|
||
replacement = { | ||
ENDPOINTS: { | ||
1: { | ||
DEVICE_TYPE: zha.DeviceType.SMART_PLUG, | ||
INPUT_CLUSTERS: [ | ||
Basic.cluster_id, | ||
Groups.cluster_id, | ||
Scenes.cluster_id, | ||
TuyaOnOff, | ||
TuyaValveWaterConsumed, | ||
TuyaPowerConfigurationCluster, | ||
# DoublingPowerConfigurationCluster, | ||
TuyaValveManufCluster, | ||
], | ||
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], | ||
} | ||
} | ||
} | ||
|