Home Assistant Unofficial Reference 2024.12.1
binary_sensor.py
Go to the documentation of this file.
1 """Support for ONVIF binary sensors."""
2 
3 from __future__ import annotations
4 
6  BinarySensorDeviceClass,
7  BinarySensorEntity,
8 )
9 from homeassistant.config_entries import ConfigEntry
10 from homeassistant.const import STATE_ON
11 from homeassistant.core import HomeAssistant, callback
12 from homeassistant.helpers import entity_registry as er
13 from homeassistant.helpers.entity_platform import AddEntitiesCallback
14 from homeassistant.helpers.restore_state import RestoreEntity
15 from homeassistant.util.enum import try_parse_enum
16 
17 from .const import DOMAIN
18 from .device import ONVIFDevice
19 from .entity import ONVIFBaseEntity
20 
21 
23  hass: HomeAssistant,
24  config_entry: ConfigEntry,
25  async_add_entities: AddEntitiesCallback,
26 ) -> None:
27  """Set up a ONVIF binary sensor."""
28  device: ONVIFDevice = hass.data[DOMAIN][config_entry.unique_id]
29 
30  entities = {
31  event.uid: ONVIFBinarySensor(event.uid, device)
32  for event in device.events.get_platform("binary_sensor")
33  }
34 
35  ent_reg = er.async_get(hass)
36  for entry in er.async_entries_for_config_entry(ent_reg, config_entry.entry_id):
37  if entry.domain == "binary_sensor" and entry.unique_id not in entities:
38  entities[entry.unique_id] = ONVIFBinarySensor(
39  entry.unique_id, device, entry
40  )
41 
42  async_add_entities(entities.values())
43  uids_by_platform = device.events.get_uids_by_platform("binary_sensor")
44 
45  @callback
46  def async_check_entities() -> None:
47  """Check if we have added an entity for the event."""
48  nonlocal uids_by_platform
49  if not (missing := uids_by_platform.difference(entities)):
50  return
51  new_entities: dict[str, ONVIFBinarySensor] = {
52  uid: ONVIFBinarySensor(uid, device) for uid in missing
53  }
54  if new_entities:
55  entities.update(new_entities)
56  async_add_entities(new_entities.values())
57 
58  device.events.async_add_listener(async_check_entities)
59 
60 
62  """Representation of a binary ONVIF event."""
63 
64  _attr_should_poll = False
65  _attr_unique_id: str
66 
67  def __init__(
68  self, uid: str, device: ONVIFDevice, entry: er.RegistryEntry | None = None
69  ) -> None:
70  """Initialize the ONVIF binary sensor."""
71  self._attr_unique_id_attr_unique_id = uid
72  if entry is not None:
73  self._attr_device_class_attr_device_class = try_parse_enum(
74  BinarySensorDeviceClass, entry.original_device_class
75  )
76  self._attr_entity_category_attr_entity_category = entry.entity_category
77  self._attr_name_attr_name = entry.name
78  else:
79  event = device.events.get_uid(uid)
80  assert event
81  self._attr_device_class_attr_device_class = try_parse_enum(
82  BinarySensorDeviceClass, event.device_class
83  )
84  self._attr_entity_category_attr_entity_category = event.entity_category
85  self._attr_entity_registry_enabled_default_attr_entity_registry_enabled_default = event.entity_enabled
86  self._attr_name_attr_name = f"{device.name} {event.name}"
87  self._attr_is_on_attr_is_on = event.value
88 
89  super().__init__(device)
90 
91  @property
92  def is_on(self) -> bool | None:
93  """Return true if the binary sensor is on."""
94  if (event := self.device.events.get_uid(self._attr_unique_id_attr_unique_id)) is not None:
95  return event.value
96  return self._attr_is_on_attr_is_on
97 
98  async def async_added_to_hass(self) -> None:
99  """Connect to dispatcher listening for entity data notifications."""
100  self.async_on_removeasync_on_remove(
101  self.device.events.async_add_listener(self.async_write_ha_stateasync_write_ha_state)
102  )
103  if (last_state := await self.async_get_last_stateasync_get_last_state()) is not None:
104  self._attr_is_on_attr_is_on = last_state.state == STATE_ON
None __init__(self, str uid, ONVIFDevice device, er.RegistryEntry|None entry=None)
None async_on_remove(self, CALLBACK_TYPE func)
Definition: entity.py:1331
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)