Tried it myself =)
Probably not perfect but it works with the WT-09W 2-Zone Water Timer (modelCode 270)
Changes to devices.py:
- Add this class before
class HWG0538WRF:
class DiivooWT09W(DiivooWT11W):
"""Diivoo WT-09W 2-Zone Water Timer (HTV0537FRF, modelCode 270)."""
MODEL_CODES = [270]
FRIENDLY_DESC = "Diivoo WT-09W 2-Zone Water Timer"
def __init__(self, **kwargs):
super().__init__(**kwargs)
# Only 2 zones, different port addresses than WT-11W
self.zones = {
1: {"active": False, "status": "off_idle", "countdown_timer": 0, "countdown_end_time": None, "duration_setting": 0},
2: {"active": False, "status": "off_idle", "countdown_timer": 0, "countdown_end_time": None, "duration_setting": 0},
}
def _parse_port_statuses_precise(self, hex_data):
"""WT-09W uses 19D8 (zone 1) and 1AD8 (zone 2)."""
status_map = {'D821': 'on', 'D820': 'off_recent', 'D800': 'off_idle'}
port_patterns = ['19D8', '1AD8']
for port_num, pattern in enumerate(port_patterns, 1):
pattern_pos = hex_data.find(pattern)
if pattern_pos >= 0 and pattern_pos + 6 <= len(hex_data):
status_hex = hex_data[pattern_pos + 2:pattern_pos + 6]
if status_hex in status_map:
self.zones[port_num]['active'] = status_map[status_hex] == 'on'
self.zones[port_num]['status'] = status_map[status_hex]
logger.debug("WT09W Zone %d status: %s", port_num, status_map[status_hex])
else:
logger.warning("WT09W Zone %d unknown status hex: %s", port_num, status_hex)
def _parse_countdown_timers_precise(self, hex_data, current_ticks, msg_time=None):
"""WT-09W uses 21B7 (zone 1) and 22B7 (zone 2)."""
timer_patterns = ['21B7', '22B7']
for port_num, pattern in enumerate(timer_patterns, 1):
pattern_pos = hex_data.find(pattern)
if pattern_pos >= 0 and pattern_pos + 12 <= len(hex_data):
timer_hex = hex_data[pattern_pos + 4:pattern_pos + 12]
try:
end_ticks = int.from_bytes(bytes.fromhex(timer_hex), "little")
if end_ticks > current_ticks > 0:
rem_s = end_ticks - current_ticks
else:
rem_s = 0
if self.zones[port_num]['active']:
self.zones[port_num]['active'] = False
self.zones[port_num]['status'] = 'off_idle'
self.zones[port_num]['countdown_timer'] = rem_s
if rem_s > 0:
base_time = msg_time if msg_time else datetime.now().timestamp()
new_end_time = base_time + rem_s
old_end_time = self.zones[port_num].get('countdown_end_time')
if not old_end_time or abs(new_end_time - old_end_time) > 10:
self.zones[port_num]['countdown_end_time'] = new_end_time
else:
self.zones[port_num]['countdown_end_time'] = None
except ValueError as e:
logger.debug("WT09W Zone %d timer error: %s", port_num, e)
def _parse_duration_settings_precise(self, hex_data):
"""WT-09W uses 25AD (zone 1) and 26AD (zone 2)."""
duration_patterns = ['25AD', '26AD']
for port_num, pattern in enumerate(duration_patterns, 1):
pattern_pos = hex_data.find(pattern)
if pattern_pos >= 0 and pattern_pos + 8 <= len(hex_data):
duration_hex = hex_data[pattern_pos + 4:pattern_pos + 8]
try:
self.zones[port_num]['duration_setting'] = int.from_bytes(
bytes.fromhex(duration_hex), "little")
except ValueError:
self.zones[port_num]['duration_setting'] = 0
def control_zone(self, api, zone_number, mode, duration=0):
"""Control zone 1 or 2."""
if zone_number not in [1, 2]:
raise ValueError("Zone number must be 1 or 2")
return api.control_device_work_mode(
device_name=self.hub_device_name,
product_key=self.hub_product_key,
mid=str(self.mid),
addr=self.address,
port=zone_number,
mode=mode,
duration=duration
)
def __str__(self):
s = super(HomgarSubDevice, self).__str__()
active_zones = [str(z) for z in [1, 2] if self.is_zone_active(z)]
if active_zones:
s += f" [Active zones: {', '.join(active_zones)}]"
return s
- Add
DiivooWT09W to MODEL_CODE_MAPPING:
MODEL_CODE_MAPPING = {
code: clazz
for clazz in (
RainPointDisplayHub,
RainPointSoilMoistureSensor,
RainPointRainSensor,
RainPointAirSensor,
RainPoint2ZoneTimer,
DiivooWT11W,
DiivooWT09W, # â added
HWG0538WRF,
HomgarWeatherHub,
HomgarWeatherStation,
HomgarIndoorSensor,
HTV405FRF
) for code in clazz.MODEL_CODES
}
Changes to switch.py:
- Update the import line:
from .devices import DiivooWT11W, DiivooWT09W, RainPoint2ZoneTimer, HWG0538WRF, HTV405FRF
- Update the device setup loop â check
DiivooWT09W before DiivooWT11W:
for device_id, device in coordinator.devices.items():
if isinstance(device, DiivooWT09W): # must check before DiivooWT11W
for zone in [1, 2]:
entities.append(
HomgarZoneSwitch(coordinator, device_id, device, zone)
)
elif isinstance(device, DiivooWT11W):
for zone in [1, 2, 3]:
entities.append(
HomgarZoneSwitch(coordinator, device_id, device, zone)
)
elif isinstance(device, RainPoint2ZoneTimer):
for zone in [1, 2]:
entities.append(
HomgarZoneSwitch(coordinator, device_id, device, zone)
)
elif isinstance(device, HTV405FRF):
for zone in [1, 2, 3, 4]:
entities.append(
HomgarZoneSwitch(coordinator, device_id, device, zone)
)