Skip to content

Commit 9ab432c

Browse files
committed
Sync zone smart_watering_enabled on program create/destroy events
When a smart program is destroyed (turned off via app), update all zones on the device to smart_watering_enabled=false so the smart watering switches reflect the correct state. Similarly, set to true when a smart program is created (turned on).
1 parent 1117505 commit 9ab432c

1 file changed

Lines changed: 36 additions & 12 deletions

File tree

custom_components/bhyve/coordinator.py

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -295,19 +295,34 @@ async def async_handle_device_event(self, event_data: dict[str, Any]) -> None:
295295
# Notify all listening entities
296296
self.async_set_updated_data(self.data)
297297

298+
def _set_zones_smart_watering(
299+
self, device_id: str | None, *, enabled: bool
300+
) -> None:
301+
"""Update smart_watering_enabled on all zones of a device."""
302+
if not device_id:
303+
return
304+
device_data = self.data.get("devices", {}).get(device_id, {})
305+
device = device_data.get("device", {})
306+
for zone in device.get("zones", []):
307+
zone["smart_watering_enabled"] = enabled
308+
309+
@staticmethod
310+
def _get_program_id(event_data: dict[str, Any]) -> str | None:
311+
"""Extract program ID from event data."""
312+
program_id = event_data.get("program_id")
313+
if not program_id:
314+
program = event_data.get("program", {})
315+
program_id = program.get("id") if isinstance(program, dict) else None
316+
return program_id
317+
298318
async def async_handle_program_event(self, event_data: dict[str, Any]) -> None:
299319
"""Handle WebSocket program events."""
300320
if not self.data:
301321
_LOGGER.debug("Coordinator data not initialized, ignoring event")
302322
return
303323

304324
lifecycle_phase = event_data.get("lifecycle_phase")
305-
program_id = event_data.get("program_id")
306-
307-
if not program_id:
308-
# Some program events have program in a different structure
309-
program = event_data.get("program", {})
310-
program_id = program.get("id") if isinstance(program, dict) else None
325+
program_id = self._get_program_id(event_data)
311326

312327
if not program_id:
313328
_LOGGER.debug("No program_id found in event, ignoring")
@@ -319,11 +334,15 @@ async def async_handle_program_event(self, event_data: dict[str, Any]) -> None:
319334
if isinstance(program_data, dict):
320335
_LOGGER.debug("Adding new program %s to coordinator data", program_id)
321336
self.data["programs"][program_id] = program_data
322-
# Fire an event so the switch platform can create a new entity
323-
self.hass.bus.async_fire(
324-
"bhyve_program_created",
325-
{"program_id": program_id, "program": program_data},
326-
)
337+
if program_data.get("is_smart_program"):
338+
# Smart program created means water_sense_mode turned on
339+
device_id = event_data.get("device_id")
340+
self._set_zones_smart_watering(device_id, enabled=True)
341+
else:
342+
self.hass.bus.async_fire(
343+
"bhyve_program_created",
344+
{"program_id": program_id, "program": program_data},
345+
)
327346
self.async_set_updated_data(self.data)
328347
return
329348

@@ -342,7 +361,12 @@ async def async_handle_program_event(self, event_data: dict[str, Any]) -> None:
342361
)
343362
self.async_set_updated_data(self.data)
344363
return
345-
# Smart program "destroy" falls through to update the program data
364+
if is_smart:
365+
# Smart program destroy means water_sense_mode was turned off.
366+
# Update zone data so smart watering switches reflect the change.
367+
device_id = event_data.get("device_id")
368+
self._set_zones_smart_watering(device_id, enabled=False)
369+
# Fall through to update the program data
346370

347371
# For update events, check if program exists
348372
if program_id not in self.data["programs"]:

0 commit comments

Comments
 (0)