Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Feed Entity Manager Sensor support for GDACS Feed."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 from datetime import datetime
7 import logging
8 from typing import Any
9 
10 from aio_georss_client.status_update import StatusUpdate
11 
12 from homeassistant.components.sensor import SensorEntity
13 from homeassistant.config_entries import ConfigEntry
14 from homeassistant.core import HomeAssistant, callback
15 from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
16 from homeassistant.helpers.dispatcher import async_dispatcher_connect
17 from homeassistant.helpers.entity_platform import AddEntitiesCallback
18 from homeassistant.util import dt as dt_util
19 
20 from . import GdacsFeedEntityManager
21 from .const import DOMAIN, FEED
22 
23 _LOGGER = logging.getLogger(__name__)
24 
25 ATTR_STATUS = "status"
26 ATTR_LAST_UPDATE = "last_update"
27 ATTR_LAST_UPDATE_SUCCESSFUL = "last_update_successful"
28 ATTR_LAST_TIMESTAMP = "last_timestamp"
29 ATTR_CREATED = "created"
30 ATTR_UPDATED = "updated"
31 ATTR_REMOVED = "removed"
32 
33 DEFAULT_UNIT_OF_MEASUREMENT = "alerts"
34 
35 # An update of this entity is not making a web request, but uses internal data only.
36 PARALLEL_UPDATES = 0
37 
38 
40  hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
41 ) -> None:
42  """Set up the GDACS Feed platform."""
43  manager: GdacsFeedEntityManager = hass.data[DOMAIN][FEED][entry.entry_id]
44  sensor = GdacsSensor(entry, manager)
45  async_add_entities([sensor])
46 
47 
49  """Status sensor for the GDACS integration."""
50 
51  _attr_should_poll = False
52  _attr_native_unit_of_measurement = DEFAULT_UNIT_OF_MEASUREMENT
53  _attr_has_entity_name = True
54  _attr_name = None
55  _attr_translation_key = "alerts"
56 
57  def __init__(
58  self, config_entry: ConfigEntry, manager: GdacsFeedEntityManager
59  ) -> None:
60  """Initialize entity."""
61  assert config_entry.unique_id
62  self._config_entry_id_config_entry_id = config_entry.entry_id
63  self._attr_unique_id_attr_unique_id = config_entry.unique_id
64  self._manager_manager = manager
65  self._status_status: str | None = None
66  self._last_update_last_update: datetime | None = None
67  self._last_update_successful_last_update_successful: datetime | None = None
68  self._last_timestamp_last_timestamp: datetime | None = None
69  self._total_total: int | None = None
70  self._created_created: int | None = None
71  self._updated_updated: int | None = None
72  self._removed_removed: int | None = None
73  self._remove_signal_status_remove_signal_status: Callable[[], None] | None = None
74  self._attr_device_info_attr_device_info = DeviceInfo(
75  identifiers={(DOMAIN, config_entry.unique_id)},
76  entry_type=DeviceEntryType.SERVICE,
77  manufacturer="GDACS",
78  )
79 
80  async def async_added_to_hass(self) -> None:
81  """Call when entity is added to hass."""
82  self._remove_signal_status_remove_signal_status = async_dispatcher_connect(
83  self.hasshass,
84  f"gdacs_status_{self._config_entry_id}",
85  self._update_status_callback_update_status_callback,
86  )
87  _LOGGER.debug("Waiting for updates %s", self._config_entry_id_config_entry_id)
88  # First update is manual because of how the feed entity manager is updated.
89  await self.async_updateasync_update()
90 
91  async def async_will_remove_from_hass(self) -> None:
92  """Call when entity will be removed from hass."""
93  if self._remove_signal_status_remove_signal_status:
94  self._remove_signal_status_remove_signal_status()
95 
96  @callback
97  def _update_status_callback(self) -> None:
98  """Call status update method."""
99  _LOGGER.debug("Received status update for %s", self._config_entry_id_config_entry_id)
100  self.async_schedule_update_ha_stateasync_schedule_update_ha_state(True)
101 
102  async def async_update(self) -> None:
103  """Update this entity from the data held in the feed manager."""
104  _LOGGER.debug("Updating %s", self._config_entry_id_config_entry_id)
105  if self._manager_manager:
106  status_info = self._manager_manager.status_info()
107  if status_info:
108  self._update_from_status_info_update_from_status_info(status_info)
109 
110  def _update_from_status_info(self, status_info: StatusUpdate) -> None:
111  """Update the internal state from the provided information."""
112  self._status_status = status_info.status
113  self._last_update_last_update = (
114  dt_util.as_utc(status_info.last_update) if status_info.last_update else None
115  )
116  if status_info.last_update_successful:
117  self._last_update_successful_last_update_successful = dt_util.as_utc(
118  status_info.last_update_successful
119  )
120  else:
121  self._last_update_successful_last_update_successful = None
122  self._last_timestamp_last_timestamp = status_info.last_timestamp
123  self._total_total = status_info.total
124  self._created_created = status_info.created
125  self._updated_updated = status_info.updated
126  self._removed_removed = status_info.removed
127 
128  @property
129  def native_value(self) -> int | None:
130  """Return the state of the sensor."""
131  return self._total_total
132 
133  @property
134  def extra_state_attributes(self) -> dict[str, Any]:
135  """Return the device state attributes."""
136  return {
137  key: value
138  for key, value in (
139  (ATTR_STATUS, self._status_status),
140  (ATTR_LAST_UPDATE, self._last_update_last_update),
141  (ATTR_LAST_UPDATE_SUCCESSFUL, self._last_update_successful_last_update_successful),
142  (ATTR_LAST_TIMESTAMP, self._last_timestamp_last_timestamp),
143  (ATTR_CREATED, self._created_created),
144  (ATTR_UPDATED, self._updated_updated),
145  (ATTR_REMOVED, self._removed_removed),
146  )
147  if value or isinstance(value, bool)
148  }
None _update_from_status_info(self, StatusUpdate status_info)
Definition: sensor.py:110
None __init__(self, ConfigEntry config_entry, GdacsFeedEntityManager manager)
Definition: sensor.py:59
None async_schedule_update_ha_state(self, bool force_refresh=False)
Definition: entity.py:1265
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:41
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103