1
0
mirror of https://github.com/home-assistant/core.git synced 2026-05-30 12:14:20 +01:00
Files
2026-04-30 21:14:48 +02:00

148 lines
4.9 KiB
Python

"""Support for Traccar server sensors."""
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any, Literal
from pytraccar import DeviceModel, GeofenceModel, PositionModel
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import (
PERCENTAGE,
EntityCategory,
UnitOfElectricPotential,
UnitOfLength,
UnitOfSpeed,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.typing import StateType
from .coordinator import TraccarServerConfigEntry, TraccarServerCoordinator
from .entity import TraccarServerEntity
@dataclass(frozen=True, kw_only=True)
class TraccarServerSensorEntityDescription[_T](SensorEntityDescription):
"""Describe Traccar Server sensor entity."""
data_key: Literal["position", "device", "geofence", "attributes"]
entity_registry_enabled_default = False
entity_category = EntityCategory.DIAGNOSTIC
value_fn: Callable[[_T], StateType]
TRACCAR_SERVER_SENSOR_ENTITY_DESCRIPTIONS: tuple[
TraccarServerSensorEntityDescription[Any], ...
] = (
TraccarServerSensorEntityDescription[PositionModel](
key="attributes.batteryLevel",
data_key="position",
native_unit_of_measurement=PERCENTAGE,
device_class=SensorDeviceClass.BATTERY,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
value_fn=lambda x: x["attributes"].get("batteryLevel"),
),
TraccarServerSensorEntityDescription[PositionModel](
key="attributes.power",
data_key="position",
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
device_class=SensorDeviceClass.VOLTAGE,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=2,
value_fn=lambda x: x["attributes"].get("power"),
translation_key="power",
),
TraccarServerSensorEntityDescription[PositionModel](
key="attributes.battery",
data_key="position",
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
device_class=SensorDeviceClass.VOLTAGE,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=2,
value_fn=lambda x: x["attributes"].get("battery"),
translation_key="battery",
),
TraccarServerSensorEntityDescription[PositionModel](
key="speed",
data_key="position",
device_class=SensorDeviceClass.SPEED,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfSpeed.KNOTS,
suggested_display_precision=0,
value_fn=lambda x: x["speed"],
),
TraccarServerSensorEntityDescription[PositionModel](
key="altitude",
data_key="position",
translation_key="altitude",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfLength.METERS,
suggested_display_precision=1,
value_fn=lambda x: x["altitude"],
),
TraccarServerSensorEntityDescription[PositionModel](
key="address",
data_key="position",
translation_key="address",
value_fn=lambda x: x["address"],
),
TraccarServerSensorEntityDescription[GeofenceModel | None](
key="name",
data_key="geofence",
translation_key="geofence",
value_fn=lambda x: x["name"] if x else None,
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: TraccarServerConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up sensor entities."""
coordinator = entry.runtime_data
async_add_entities(
TraccarServerSensor(
coordinator=coordinator,
device=device_entry["device"],
description=description,
)
for device_entry in coordinator.data.values()
for description in TRACCAR_SERVER_SENSOR_ENTITY_DESCRIPTIONS
)
class TraccarServerSensor[_T](TraccarServerEntity, SensorEntity):
"""Represent a tracked device."""
_attr_has_entity_name = True
entity_description: TraccarServerSensorEntityDescription[_T]
def __init__(
self,
coordinator: TraccarServerCoordinator,
device: DeviceModel,
description: TraccarServerSensorEntityDescription[_T],
) -> None:
"""Initialize the Traccar Server sensor."""
super().__init__(coordinator, device)
self.entity_description = description
self._attr_unique_id = (
f"{device['uniqueId']}_{description.data_key}_{description.key}"
)
@property
def native_value(self) -> StateType:
"""Return the value of the sensor."""
return self.entity_description.value_fn(
getattr(self, f"traccar_{self.entity_description.data_key}")
)