Home Assistant Unofficial Reference 2024.12.1
switch.py
Go to the documentation of this file.
1 """Support for Rain Bird Irrigation system LNK Wi-Fi Module."""
2 
3 from __future__ import annotations
4 
5 import logging
6 
7 from pyrainbird.exceptions import RainbirdApiException, RainbirdDeviceBusyException
8 import voluptuous as vol
9 
10 from homeassistant.components.switch import SwitchEntity
11 from homeassistant.core import HomeAssistant
12 from homeassistant.exceptions import HomeAssistantError
13 from homeassistant.helpers import config_validation as cv, entity_platform
14 from homeassistant.helpers.device_registry import DeviceInfo
15 from homeassistant.helpers.entity_platform import AddEntitiesCallback
16 from homeassistant.helpers.typing import VolDictType
17 from homeassistant.helpers.update_coordinator import CoordinatorEntity
18 
19 from .const import ATTR_DURATION, CONF_IMPORTED_NAMES, DOMAIN, MANUFACTURER
20 from .coordinator import RainbirdUpdateCoordinator
21 from .types import RainbirdConfigEntry
22 
23 _LOGGER = logging.getLogger(__name__)
24 
25 SERVICE_START_IRRIGATION = "start_irrigation"
26 
27 SERVICE_SCHEMA_IRRIGATION: VolDictType = {
28  vol.Required(ATTR_DURATION): cv.positive_float,
29 }
30 
31 
33  hass: HomeAssistant,
34  config_entry: RainbirdConfigEntry,
35  async_add_entities: AddEntitiesCallback,
36 ) -> None:
37  """Set up entry for a Rain Bird irrigation switches."""
38  coordinator = config_entry.runtime_data.coordinator
41  coordinator,
42  zone,
43  config_entry.options[ATTR_DURATION],
44  config_entry.data.get(CONF_IMPORTED_NAMES, {}).get(str(zone)),
45  )
46  for zone in coordinator.data.zones
47  )
48 
49  platform = entity_platform.async_get_current_platform()
50  platform.async_register_entity_service(
51  SERVICE_START_IRRIGATION,
52  SERVICE_SCHEMA_IRRIGATION,
53  "async_turn_on",
54  )
55 
56 
57 class RainBirdSwitch(CoordinatorEntity[RainbirdUpdateCoordinator], SwitchEntity):
58  """Representation of a Rain Bird switch."""
59 
60  def __init__(
61  self,
62  coordinator: RainbirdUpdateCoordinator,
63  zone: int,
64  duration_minutes: int,
65  imported_name: str | None,
66  ) -> None:
67  """Initialize a Rain Bird Switch Device."""
68  super().__init__(coordinator)
69  self._zone_zone = zone
70  _LOGGER.debug("coordinator.unique_id=%s", coordinator.unique_id)
71  if coordinator.unique_id is not None:
72  self._attr_unique_id_attr_unique_id = f"{coordinator.unique_id}-{zone}"
73  device_name = f"{MANUFACTURER} Sprinkler {zone}"
74  if imported_name:
75  self._attr_name_attr_name = imported_name
76  self._attr_has_entity_name_attr_has_entity_name = False
77  else:
78  self._attr_name_attr_name = None if coordinator.unique_id is not None else device_name
79  self._attr_has_entity_name_attr_has_entity_name = True
80  self._duration_minutes_duration_minutes = duration_minutes
81  if coordinator.unique_id is not None and self._attr_unique_id_attr_unique_id is not None:
82  self._attr_device_info_attr_device_info = DeviceInfo(
83  name=device_name,
84  identifiers={(DOMAIN, self._attr_unique_id_attr_unique_id)},
85  manufacturer=MANUFACTURER,
86  via_device=(DOMAIN, coordinator.unique_id),
87  )
88 
89  @property
91  """Return state attributes."""
92  return {"zone": self._zone_zone}
93 
94  async def async_turn_on(self, **kwargs):
95  """Turn the switch on."""
96  try:
97  await self.coordinator.controller.irrigate_zone(
98  int(self._zone_zone),
99  int(kwargs.get(ATTR_DURATION, self._duration_minutes_duration_minutes)),
100  )
101  except RainbirdDeviceBusyException as err:
102  raise HomeAssistantError(
103  "Rain Bird device is busy; Wait and try again"
104  ) from err
105  except RainbirdApiException as err:
106  raise HomeAssistantError("Rain Bird device failure") from err
107 
108  # The device reflects the old state for a few moments. Update the
109  # state manually and trigger a refresh after a short debounced delay.
110  self.coordinator.data.active_zones.add(self._zone_zone)
111  self.async_write_ha_stateasync_write_ha_state()
112  await self.coordinator.async_request_refresh()
113 
114  async def async_turn_off(self, **kwargs):
115  """Turn the switch off."""
116  try:
117  await self.coordinator.controller.stop_irrigation()
118  except RainbirdDeviceBusyException as err:
119  raise HomeAssistantError(
120  "Rain Bird device is busy; Wait and try again"
121  ) from err
122  except RainbirdApiException as err:
123  raise HomeAssistantError("Rain Bird device failure") from err
124 
125  # The device reflects the old state for a few moments. Update the
126  # state manually and trigger a refresh after a short debounced delay.
127  if self.is_onis_onis_on:
128  self.coordinator.data.active_zones.remove(self._zone_zone)
129  self.async_write_ha_stateasync_write_ha_state()
130  await self.coordinator.async_request_refresh()
131 
132  @property
133  def is_on(self):
134  """Return true if switch is on."""
135  return self._zone_zone in self.coordinator.data.active_zones
None __init__(self, RainbirdUpdateCoordinator coordinator, int zone, int duration_minutes, str|None imported_name)
Definition: switch.py:66
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88
None async_setup_entry(HomeAssistant hass, RainbirdConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: switch.py:36