Home Assistant Unofficial Reference 2024.12.1
binary_sensor.py
Go to the documentation of this file.
1 """Support for Rflink binary sensors."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 import voluptuous as vol
8 
10  DEVICE_CLASSES_SCHEMA,
11  PLATFORM_SCHEMA as BINARY_SENSOR_PLATFORM_SCHEMA,
12  BinarySensorDeviceClass,
13  BinarySensorEntity,
14 )
15 from homeassistant.const import (
16  CONF_DEVICE_CLASS,
17  CONF_DEVICES,
18  CONF_FORCE_UPDATE,
19  CONF_NAME,
20  STATE_ON,
21 )
22 from homeassistant.core import HomeAssistant, callback
24 from homeassistant.helpers.entity_platform import AddEntitiesCallback
25 import homeassistant.helpers.event as evt
26 from homeassistant.helpers.restore_state import RestoreEntity
27 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
28 
29 from .const import CONF_ALIASES
30 from .entity import RflinkDevice
31 
32 CONF_OFF_DELAY = "off_delay"
33 DEFAULT_FORCE_UPDATE = False
34 
35 PLATFORM_SCHEMA = BINARY_SENSOR_PLATFORM_SCHEMA.extend(
36  {
37  vol.Optional(CONF_DEVICES, default={}): {
38  cv.string: vol.Schema(
39  {
40  vol.Optional(CONF_NAME): cv.string,
41  vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
42  vol.Optional(
43  CONF_FORCE_UPDATE, default=DEFAULT_FORCE_UPDATE
44  ): cv.boolean,
45  vol.Optional(CONF_OFF_DELAY): cv.positive_int,
46  vol.Optional(CONF_ALIASES, default=[]): vol.All(
47  cv.ensure_list, [cv.string]
48  ),
49  }
50  )
51  }
52  },
53  extra=vol.ALLOW_EXTRA,
54 )
55 
56 
57 def devices_from_config(domain_config):
58  """Parse configuration and add Rflink sensor devices."""
59  devices = []
60  for device_id, config in domain_config[CONF_DEVICES].items():
61  device = RflinkBinarySensor(device_id, **config)
62  devices.append(device)
63 
64  return devices
65 
66 
68  hass: HomeAssistant,
69  config: ConfigType,
70  async_add_entities: AddEntitiesCallback,
71  discovery_info: DiscoveryInfoType | None = None,
72 ) -> None:
73  """Set up the Rflink platform."""
75 
76 
78  """Representation of an Rflink binary sensor."""
79 
80  def __init__(
81  self,
82  device_id: str,
83  device_class: BinarySensorDeviceClass | None = None,
84  force_update: bool = False,
85  off_delay: int | None = None,
86  **kwargs: Any,
87  ) -> None:
88  """Handle sensor specific args and super init."""
89  self._state_state = None
90  self._attr_device_class_attr_device_class = device_class
91  self._attr_force_update_attr_force_update = force_update
92  self._off_delay_off_delay = off_delay
93  self._delay_listener_delay_listener = None
94  super().__init__(device_id, **kwargs)
95 
96  async def async_added_to_hass(self) -> None:
97  """Restore RFLink BinarySensor state."""
98  await super().async_added_to_hass()
99  if (old_state := await self.async_get_last_stateasync_get_last_state()) is not None:
100  if self._off_delay_off_delay is None:
101  self._state_state = old_state.state == STATE_ON
102  else:
103  self._state_state = False
104 
105  def _handle_event(self, event):
106  """Domain specific event handler."""
107  command = event["command"]
108  if command in ["on", "allon"]:
109  self._state_state = True
110  elif command in ["off", "alloff"]:
111  self._state_state = False
112 
113  if self._state_state and self._off_delay_off_delay is not None:
114 
115  @callback
116  def off_delay_listener(now):
117  """Switch device off after a delay."""
118  self._delay_listener_delay_listener = None
119  self._state_state = False
120  self.async_write_ha_stateasync_write_ha_state()
121 
122  if self._delay_listener_delay_listener is not None:
123  self._delay_listener_delay_listener()
124  self._delay_listener_delay_listener = evt.async_call_later(
125  self.hasshass, self._off_delay_off_delay, off_delay_listener
126  )
127 
128  @property
129  def is_on(self):
130  """Return true if the binary sensor is on."""
131  return self._state_state