Home Assistant Unofficial Reference 2024.12.1
binary_sensor.py
Go to the documentation of this file.
1 """Support for Hydrawise sprinkler binary sensors."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 from dataclasses import dataclass
7 from datetime import datetime
8 
9 from pydrawise import Zone
10 import voluptuous as vol
11 
13  BinarySensorDeviceClass,
14  BinarySensorEntity,
15  BinarySensorEntityDescription,
16 )
17 from homeassistant.config_entries import ConfigEntry
18 from homeassistant.core import HomeAssistant
19 from homeassistant.helpers import config_validation as cv, entity_platform
20 from homeassistant.helpers.entity_platform import AddEntitiesCallback
21 from homeassistant.helpers.typing import VolDictType
22 
23 from .const import DOMAIN, SERVICE_RESUME, SERVICE_START_WATERING, SERVICE_SUSPEND
24 from .coordinator import HydrawiseUpdateCoordinators
25 from .entity import HydrawiseEntity
26 
27 
28 @dataclass(frozen=True, kw_only=True)
30  """Describes Hydrawise binary sensor."""
31 
32  value_fn: Callable[[HydrawiseBinarySensor], bool | None]
33  always_available: bool = False
34 
35 
36 CONTROLLER_BINARY_SENSORS: tuple[HydrawiseBinarySensorEntityDescription, ...] = (
38  key="status",
39  device_class=BinarySensorDeviceClass.CONNECTIVITY,
40  value_fn=(
41  lambda status_sensor: status_sensor.coordinator.last_update_success
42  and status_sensor.controller.online
43  ),
44  # Connectivtiy sensor is always available
45  always_available=True,
46  ),
47 )
48 
49 RAIN_SENSOR_BINARY_SENSOR: tuple[HydrawiseBinarySensorEntityDescription, ...] = (
51  key="rain_sensor",
52  translation_key="rain_sensor",
53  device_class=BinarySensorDeviceClass.MOISTURE,
54  value_fn=lambda rain_sensor: rain_sensor.sensor.status.active,
55  ),
56 )
57 
58 ZONE_BINARY_SENSORS: tuple[HydrawiseBinarySensorEntityDescription, ...] = (
60  key="is_watering",
61  translation_key="watering",
62  device_class=BinarySensorDeviceClass.RUNNING,
63  value_fn=(
64  lambda watering_sensor: watering_sensor.zone.scheduled_runs.current_run
65  is not None
66  ),
67  ),
68 )
69 
70 SCHEMA_START_WATERING: VolDictType = {
71  vol.Optional("duration"): vol.All(vol.Coerce(int), vol.Range(min=0, max=90)),
72 }
73 SCHEMA_SUSPEND: VolDictType = {
74  vol.Required("until"): cv.datetime,
75 }
76 
77 
79  hass: HomeAssistant,
80  config_entry: ConfigEntry,
81  async_add_entities: AddEntitiesCallback,
82 ) -> None:
83  """Set up the Hydrawise binary_sensor platform."""
84  coordinators: HydrawiseUpdateCoordinators = hass.data[DOMAIN][config_entry.entry_id]
85  entities: list[HydrawiseBinarySensor] = []
86  for controller in coordinators.main.data.controllers.values():
87  entities.extend(
88  HydrawiseBinarySensor(coordinators.main, description, controller)
89  for description in CONTROLLER_BINARY_SENSORS
90  )
91  entities.extend(
93  coordinators.main,
94  description,
95  controller,
96  sensor_id=sensor.id,
97  )
98  for sensor in controller.sensors
99  for description in RAIN_SENSOR_BINARY_SENSOR
100  if "rain sensor" in sensor.model.name.lower()
101  )
102  entities.extend(
104  coordinators.main, description, controller, zone_id=zone.id
105  )
106  for zone in controller.zones
107  for description in ZONE_BINARY_SENSORS
108  )
109  async_add_entities(entities)
110  platform = entity_platform.async_get_current_platform()
111  platform.async_register_entity_service(SERVICE_RESUME, None, "resume")
112  platform.async_register_entity_service(
113  SERVICE_START_WATERING, SCHEMA_START_WATERING, "start_watering"
114  )
115  platform.async_register_entity_service(SERVICE_SUSPEND, SCHEMA_SUSPEND, "suspend")
116 
117 
119  """A sensor implementation for Hydrawise device."""
120 
121  entity_description: HydrawiseBinarySensorEntityDescription
122 
123  def _update_attrs(self) -> None:
124  """Update state attributes."""
125  self._attr_is_on_attr_is_on = self.entity_descriptionentity_description.value_fn(self)
126 
127  @property
128  def available(self) -> bool:
129  """Set the entity availability."""
130  if self.entity_descriptionentity_description.always_available:
131  return True
132  return super().available
133 
134 
136  """A binary sensor for a Hydrawise irrigation zone.
137 
138  This is only used for irrigation zones, as they have special methods for
139  service actions that don't apply to other binary sensors.
140  """
141 
142  zone: Zone
143 
144  async def start_watering(self, duration: int | None = None) -> None:
145  """Start watering in the irrigation zone."""
146  await self.coordinator.api.start_zone(
147  self.zonezone, custom_run_duration=int((duration or 0) * 60)
148  )
149 
150  async def suspend(self, until: datetime) -> None:
151  """Suspend automatic watering in the irrigation zone."""
152  await self.coordinator.api.suspend_zone(self.zonezone, until=until)
153 
154  async def resume(self) -> None:
155  """Resume automatic watering in the irrigation zone."""
156  await self.coordinator.api.resume_zone(self.zonezone)
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)