Home Assistant Unofficial Reference 2024.12.1
binary_sensor.py
Go to the documentation of this file.
1 """Platform allowing several binary sensor to be grouped into one binary sensor."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 import voluptuous as vol
8 
10  DEVICE_CLASSES_SCHEMA,
11  DOMAIN as BINARY_SENSOR_DOMAIN,
12  PLATFORM_SCHEMA as BINARY_SENSOR_PLATFORM_SCHEMA,
13  BinarySensorDeviceClass,
14  BinarySensorEntity,
15 )
16 from homeassistant.config_entries import ConfigEntry
17 from homeassistant.const import (
18  ATTR_ENTITY_ID,
19  CONF_DEVICE_CLASS,
20  CONF_ENTITIES,
21  CONF_NAME,
22  CONF_UNIQUE_ID,
23  STATE_ON,
24  STATE_UNAVAILABLE,
25  STATE_UNKNOWN,
26 )
27 from homeassistant.core import HomeAssistant, callback
28 from homeassistant.helpers import config_validation as cv, entity_registry as er
29 from homeassistant.helpers.entity_platform import AddEntitiesCallback
30 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
31 
32 from .entity import GroupEntity
33 
34 DEFAULT_NAME = "Binary Sensor Group"
35 
36 CONF_ALL = "all"
37 REG_KEY = f"{BINARY_SENSOR_DOMAIN}_registry"
38 
39 PLATFORM_SCHEMA = BINARY_SENSOR_PLATFORM_SCHEMA.extend(
40  {
41  vol.Required(CONF_ENTITIES): cv.entities_domain(BINARY_SENSOR_DOMAIN),
42  vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
43  vol.Optional(CONF_UNIQUE_ID): cv.string,
44  vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
45  vol.Optional(CONF_ALL): cv.boolean,
46  }
47 )
48 
49 
51  hass: HomeAssistant,
52  config: ConfigType,
53  async_add_entities: AddEntitiesCallback,
54  discovery_info: DiscoveryInfoType | None = None,
55 ) -> None:
56  """Set up the Binary Sensor Group platform."""
58  [
60  config.get(CONF_UNIQUE_ID),
61  config[CONF_NAME],
62  config.get(CONF_DEVICE_CLASS),
63  config[CONF_ENTITIES],
64  config.get(CONF_ALL),
65  )
66  ]
67  )
68 
69 
71  hass: HomeAssistant,
72  config_entry: ConfigEntry,
73  async_add_entities: AddEntitiesCallback,
74 ) -> None:
75  """Initialize Binary Sensor Group config entry."""
76  registry = er.async_get(hass)
77  entities = er.async_validate_entity_ids(
78  registry, config_entry.options[CONF_ENTITIES]
79  )
80  mode = config_entry.options[CONF_ALL]
81 
83  [
85  config_entry.entry_id, config_entry.title, None, entities, mode
86  )
87  ]
88  )
89 
90 
91 @callback
93  hass: HomeAssistant, name: str, validated_config: dict[str, Any]
94 ) -> BinarySensorGroup:
95  """Create a preview sensor."""
96  return BinarySensorGroup(
97  None,
98  name,
99  None,
100  validated_config[CONF_ENTITIES],
101  validated_config[CONF_ALL],
102  )
103 
104 
106  """Representation of a BinarySensorGroup."""
107 
108  _attr_available: bool = False
109 
110  def __init__(
111  self,
112  unique_id: str | None,
113  name: str,
114  device_class: BinarySensorDeviceClass | None,
115  entity_ids: list[str],
116  mode: bool | None,
117  ) -> None:
118  """Initialize a BinarySensorGroup entity."""
119  super().__init__()
120  self._entity_ids_entity_ids = entity_ids
121  self._attr_name_attr_name = name
122  self._attr_extra_state_attributes_attr_extra_state_attributes = {ATTR_ENTITY_ID: entity_ids}
123  self._attr_unique_id_attr_unique_id = unique_id
124  self._device_class_device_class = device_class
125  self.modemode = any
126  if mode:
127  self.modemode = all
128 
129  @callback
130  def async_update_group_state(self) -> None:
131  """Query all members and determine the binary sensor group state."""
132  states = [
133  state.state
134  for entity_id in self._entity_ids_entity_ids
135  if (state := self.hasshass.states.get(entity_id)) is not None
136  ]
137 
138  # Set group as unavailable if all members are unavailable or missing
139  self._attr_available_attr_available = any(state != STATE_UNAVAILABLE for state in states)
140 
141  valid_state = self.modemode(
142  state not in (STATE_UNKNOWN, STATE_UNAVAILABLE) for state in states
143  )
144  if not valid_state:
145  # Set as unknown if any / all member is not unknown or unavailable
146  self._attr_is_on_attr_is_on = None
147  else:
148  # Set as ON if any / all member is ON
149  self._attr_is_on_attr_is_on = self.modemode(state == STATE_ON for state in states)
150 
151  @property
152  def device_class(self) -> BinarySensorDeviceClass | None:
153  """Return the sensor class of the binary sensor."""
154  return self._device_class_device_class
None __init__(self, str|None unique_id, str name, BinarySensorDeviceClass|None device_class, list[str] entity_ids, bool|None mode)
BinarySensorGroup async_create_preview_binary_sensor(HomeAssistant hass, str name, dict[str, Any] validated_config)
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
None async_setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback async_add_entities, DiscoveryInfoType|None discovery_info=None)