Files

130 lines
4.0 KiB
Python

"""Sensor platform for FireServiceRota integration."""
import logging
from typing import Any, override
from homeassistant.components.sensor import SensorEntity
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.restore_state import RestoreEntity
from .const import DOMAIN
from .coordinator import FireServiceConfigEntry, FireServiceRotaClient
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
hass: HomeAssistant,
entry: FireServiceConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up FireServiceRota sensor based on a config entry."""
async_add_entities([IncidentsSensor(entry.runtime_data.client)])
# pylint: disable-next=home-assistant-invalid-inheritance # needs fixing
class IncidentsSensor(RestoreEntity, SensorEntity):
"""Representation of FireServiceRota incidents sensor."""
_attr_should_poll = False
_attr_has_entity_name = True
_attr_translation_key = "incidents"
def __init__(self, client: FireServiceRotaClient) -> None:
"""Initialize."""
self._client = client
self._entry_id = self._client.entry_id
self._attr_unique_id = f"{self._client.unique_id}_Incidents"
self._state: str | None = None
self._state_attributes: dict[str, Any] = {}
@property
@override
def icon(self) -> str:
"""Return the icon to use in the frontend."""
if (
"prio" in self._state_attributes
and self._state_attributes["prio"][0] == "a"
):
return "mdi:ambulance"
return "mdi:fire-truck"
@property
@override
def native_value(self) -> str | None:
"""Return the state of the sensor."""
return self._state
@property
@override
def extra_state_attributes(self) -> dict[str, Any]:
"""Return available attributes for sensor."""
attr: dict[str, Any] = {}
if not (data := self._state_attributes):
return attr
for value in (
"id",
"trigger",
"created_at",
"message_to_speech_url",
"prio",
"type",
"responder_mode",
"can_respond_until",
"task_ids",
):
if data.get(value):
attr[value] = data[value]
if "address" not in data:
continue
for address_value in (
"latitude",
"longitude",
"address_type",
"formatted_address",
):
if address_value in data["address"]:
attr[address_value] = data["address"][address_value]
return attr
@override
async def async_added_to_hass(self) -> None:
"""Run when about to be added to hass."""
await super().async_added_to_hass()
if state := await self.async_get_last_state():
self._state = state.state
self._state_attributes = state.attributes
if "id" in self._state_attributes:
self._client.incident_id = self._state_attributes["id"]
_LOGGER.debug("Restored entity 'Incidents' to: %s", self._state)
self.async_on_remove(
async_dispatcher_connect(
self.hass,
f"{DOMAIN}_{self._entry_id}_update",
self.client_update,
)
)
@callback
def client_update(self) -> None:
"""Handle updated data from the data client."""
data = self._client.websocket.incident_data
if not data or "body" not in data:
return
self._state = data["body"]
self._state_attributes = data
if "id" in self._state_attributes:
self._client.incident_id = self._state_attributes["id"]
self.async_write_ha_state()