Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Sensor for Risco Events."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Collection, Mapping
6 from datetime import datetime
7 from typing import Any
8 
9 from pyrisco.cloud.event import Event
10 
11 from homeassistant.components.binary_sensor import DOMAIN as BS_DOMAIN
12 from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
13 from homeassistant.config_entries import ConfigEntry
14 from homeassistant.core import HomeAssistant
15 from homeassistant.helpers import entity_registry as er
16 from homeassistant.helpers.entity_platform import AddEntitiesCallback
17 from homeassistant.helpers.update_coordinator import CoordinatorEntity
18 from homeassistant.util import dt as dt_util
19 
20 from . import is_local
21 from .const import DOMAIN, EVENTS_COORDINATOR
22 from .coordinator import RiscoEventsDataUpdateCoordinator
23 from .entity import zone_unique_id
24 
25 CATEGORIES = {
26  2: "Alarm",
27  4: "Status",
28  7: "Trouble",
29 }
30 EVENT_ATTRIBUTES = [
31  "category_id",
32  "category_name",
33  "type_id",
34  "type_name",
35  "name",
36  "text",
37  "partition_id",
38  "zone_id",
39  "user_id",
40  "group",
41  "priority",
42  "raw",
43 ]
44 
45 
47  hass: HomeAssistant,
48  config_entry: ConfigEntry,
49  async_add_entities: AddEntitiesCallback,
50 ) -> None:
51  """Set up sensors for device."""
52  if is_local(config_entry):
53  # no events in local comm
54  return
55 
56  coordinator: RiscoEventsDataUpdateCoordinator = hass.data[DOMAIN][
57  config_entry.entry_id
58  ][EVENTS_COORDINATOR]
59  sensors = [
60  RiscoSensor(coordinator, category_id, [], name, config_entry.entry_id)
61  for category_id, name in CATEGORIES.items()
62  ]
63  sensors.append(
65  coordinator, None, CATEGORIES.keys(), "Other", config_entry.entry_id
66  )
67  )
68  async_add_entities(sensors)
69 
70 
71 class RiscoSensor(CoordinatorEntity[RiscoEventsDataUpdateCoordinator], SensorEntity):
72  """Sensor for Risco events."""
73 
74  _entity_registry: er.EntityRegistry
75 
76  def __init__(
77  self,
78  coordinator: RiscoEventsDataUpdateCoordinator,
79  category_id: int | None,
80  excludes: Collection[int],
81  name: str,
82  entry_id: str,
83  ) -> None:
84  """Initialize sensor."""
85  super().__init__(coordinator)
86  self._event_event: Event | None = None
87  self._category_id_category_id = category_id
88  self._excludes_excludes = excludes
89  self._name_name = name
90  self._entry_id_entry_id = entry_id
91  self._attr_unique_id_attr_unique_id = f"events_{name}_{self.coordinator.risco.site_uuid}"
92  self._attr_name_attr_name = f"Risco {self.coordinator.risco.site_name} {name} Events"
93  self._attr_device_class_attr_device_class = SensorDeviceClass.TIMESTAMP
94 
95  async def async_added_to_hass(self) -> None:
96  """When entity is added to hass."""
97  await super().async_added_to_hass()
98  self._entity_registry_entity_registry = er.async_get(self.hasshasshass)
99 
100  def _handle_coordinator_update(self) -> None:
101  events = self.coordinator.data
102  for event in reversed(events):
103  if event.category_id in self._excludes_excludes:
104  continue
105  if self._category_id_category_id is not None and event.category_id != self._category_id_category_id:
106  continue
107 
108  self._event_event = event
109  self.async_write_ha_stateasync_write_ha_state()
110 
111  @property
112  def native_value(self) -> datetime | None:
113  """Value of sensor."""
114  if self._event_event is None:
115  return None
116 
117  if res := dt_util.parse_datetime(self._event_event.time):
118  return res.replace(tzinfo=dt_util.get_default_time_zone())
119  return None
120 
121  @property
122  def extra_state_attributes(self) -> Mapping[str, Any] | None:
123  """State attributes."""
124  if self._event_event is None:
125  return None
126 
127  attrs = {atr: getattr(self._event_event, atr, None) for atr in EVENT_ATTRIBUTES}
128  if self._event_event.zone_id is not None:
129  uid = zone_unique_id(self.coordinator.risco, self._event_event.zone_id)
130  zone_entity_id = self._entity_registry_entity_registry.async_get_entity_id(
131  BS_DOMAIN, DOMAIN, uid
132  )
133  if zone_entity_id is not None:
134  attrs["zone_entity_id"] = zone_entity_id
135 
136  return attrs
None __init__(self, RiscoEventsDataUpdateCoordinator coordinator, int|None category_id, Collection[int] excludes, str name, str entry_id)
Definition: sensor.py:83
Mapping[str, Any]|None extra_state_attributes(self)
Definition: sensor.py:122
str zone_unique_id(RiscoCloud risco, int zone_id)
Definition: entity.py:21
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:50
bool is_local(ConfigEntry entry)
Definition: __init__.py:58