Home Assistant Unofficial Reference 2024.12.1
binary_sensor.py
Go to the documentation of this file.
1 """Support for Envisalink zone states- represented as binary sensors."""
2 
3 from __future__ import annotations
4 
5 import datetime
6 import logging
7 
8 from homeassistant.components.binary_sensor import BinarySensorEntity
9 from homeassistant.const import ATTR_LAST_TRIP_TIME
10 from homeassistant.core import HomeAssistant, callback
11 from homeassistant.helpers.dispatcher import async_dispatcher_connect
12 from homeassistant.helpers.entity_platform import AddEntitiesCallback
13 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
14 from homeassistant.util import dt as dt_util
15 
16 from . import CONF_ZONENAME, CONF_ZONETYPE, DATA_EVL, SIGNAL_ZONE_UPDATE, ZONE_SCHEMA
17 from .entity import EnvisalinkEntity
18 
19 _LOGGER = logging.getLogger(__name__)
20 
21 
23  hass: HomeAssistant,
24  config: ConfigType,
25  async_add_entities: AddEntitiesCallback,
26  discovery_info: DiscoveryInfoType | None = None,
27 ) -> None:
28  """Set up the Envisalink binary sensor entities."""
29  if not discovery_info:
30  return
31  configured_zones = discovery_info["zones"]
32 
33  entities = []
34  for zone_num in configured_zones:
35  entity_config_data = ZONE_SCHEMA(configured_zones[zone_num])
36  entity = EnvisalinkBinarySensor(
37  hass,
38  zone_num,
39  entity_config_data[CONF_ZONENAME],
40  entity_config_data[CONF_ZONETYPE],
41  hass.data[DATA_EVL].alarm_state["zone"][zone_num],
42  hass.data[DATA_EVL],
43  )
44  entities.append(entity)
45 
46  async_add_entities(entities)
47 
48 
50  """Representation of an Envisalink binary sensor."""
51 
52  def __init__(self, hass, zone_number, zone_name, zone_type, info, controller):
53  """Initialize the binary_sensor."""
54  self._zone_type_zone_type = zone_type
55  self._zone_number_zone_number = zone_number
56 
57  _LOGGER.debug("Setting up zone: %s", zone_name)
58  super().__init__(zone_name, info, controller)
59 
60  async def async_added_to_hass(self) -> None:
61  """Register callbacks."""
62  self.async_on_removeasync_on_remove(
64  self.hasshass, SIGNAL_ZONE_UPDATE, self.async_update_callbackasync_update_callback
65  )
66  )
67 
68  @property
70  """Return the state attributes."""
71  attr = {}
72 
73  # The Envisalink library returns a "last_fault" value that's the
74  # number of seconds since the last fault, up to a maximum of 327680
75  # seconds (65536 5-second ticks).
76  #
77  # We don't want the HA event log to fill up with a bunch of no-op
78  # "state changes" that are just that number ticking up once per poll
79  # interval, so we subtract it from the current second-accurate time
80  # unless it is already at the maximum value, in which case we set it
81  # to None since we can't determine the actual value.
82  seconds_ago = self._info_info["last_fault"]
83  if seconds_ago < 65536 * 5:
84  now = dt_util.now().replace(microsecond=0)
85  delta = datetime.timedelta(seconds=seconds_ago)
86  last_trip_time = (now - delta).isoformat()
87  else:
88  last_trip_time = None
89 
90  attr[ATTR_LAST_TRIP_TIME] = last_trip_time
91 
92  # Expose the zone number as an attribute to allow
93  # for easier entity to zone mapping (e.g. to bypass
94  # the zone).
95  attr["zone"] = self._zone_number_zone_number
96 
97  return attr
98 
99  @property
100  def is_on(self):
101  """Return true if sensor is on."""
102  return self._info_info["status"]["open"]
103 
104  @property
105  def device_class(self):
106  """Return the class of this sensor, from DEVICE_CLASSES."""
107  return self._zone_type_zone_type
108 
109  @callback
110  def async_update_callback(self, zone):
111  """Update the zone's state, if needed."""
112  if zone is None or int(zone) == self._zone_number_zone_number:
113  self.async_write_ha_stateasync_write_ha_state()
None async_on_remove(self, CALLBACK_TYPE func)
Definition: entity.py:1331
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103