1
0
mirror of https://github.com/home-assistant/core.git synced 2026-05-20 15:30:26 +01:00
Files
2026-05-11 13:23:50 +02:00

243 lines
9.2 KiB
Python

"""Sensor platform for CentriConnect/MyPropane API integration."""
from collections.abc import Callable
from dataclasses import dataclass
from datetime import datetime
from enum import StrEnum
from homeassistant.components.sensor import (
EntityCategory,
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
StateType,
UnitOfTemperature,
)
from homeassistant.const import (
PERCENTAGE,
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
UnitOfElectricPotential,
UnitOfLength,
UnitOfVolume,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import CentriConnectConfigEntry, CentriConnectCoordinator
from .entity import CentriConnectBaseEntity
# Coordinator is used to centralize the data updates.
PARALLEL_UPDATES = 0
_ALERT_STATUS_VALUES = {
"No Alert": "no_alert",
"Low Level": "low_level",
"Critical Level": "critical_level",
}
class CentriConnectSensorType(StrEnum):
"""Enumerates CentriConnect sensor types exposed by the device."""
ALERT_STATUS = "alert_status"
ALTITUDE = "altitude"
BATTERY_LEVEL = "battery_level"
BATTERY_VOLTAGE = "battery_voltage"
DEVICE_TEMPERATURE = "device_temperature"
LAST_POST_TIME = "last_post_time"
LATITUDE = "latitude"
LONGITUDE = "longitude"
LTE_SIGNAL_LEVEL = "lte_signal_level"
LTE_SIGNAL_STRENGTH = "lte_signal_strength"
NEXT_POST_TIME = "next_post_time"
SOLAR_LEVEL = "solar_level"
SOLAR_VOLTAGE = "solar_voltage"
TANK_LEVEL = "tank_level"
TANK_REMAINING_VOLUME = "tank_remaining_volume"
TANK_SIZE = "tank_size"
@dataclass(frozen=True, kw_only=True)
class CentriConnectSensorEntityDescription(SensorEntityDescription):
"""Description of a CentriConnect sensor entity."""
key: CentriConnectSensorType
value_fn: Callable[[CentriConnectCoordinator], StateType | datetime | None]
ENTITIES: tuple[CentriConnectSensorEntityDescription, ...] = (
CentriConnectSensorEntityDescription(
key=CentriConnectSensorType.ALERT_STATUS,
translation_key=CentriConnectSensorType.ALERT_STATUS,
device_class=SensorDeviceClass.ENUM,
options=list(_ALERT_STATUS_VALUES.values()),
value_fn=lambda coord: _ALERT_STATUS_VALUES.get(coord.data.alert_status),
),
CentriConnectSensorEntityDescription(
key=CentriConnectSensorType.ALTITUDE,
translation_key=CentriConnectSensorType.ALTITUDE,
native_unit_of_measurement=UnitOfLength.METERS,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.DISTANCE,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
suggested_display_precision=2,
value_fn=lambda coord: coord.data.altitude,
),
CentriConnectSensorEntityDescription(
key=CentriConnectSensorType.BATTERY_LEVEL,
translation_key=CentriConnectSensorType.BATTERY_LEVEL,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.BATTERY,
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda coord: coord.data.battery_level,
),
CentriConnectSensorEntityDescription(
key=CentriConnectSensorType.BATTERY_VOLTAGE,
translation_key=CentriConnectSensorType.BATTERY_VOLTAGE,
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.VOLTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
suggested_display_precision=0,
value_fn=lambda coord: coord.data.battery_voltage,
),
CentriConnectSensorEntityDescription(
key=CentriConnectSensorType.DEVICE_TEMPERATURE,
translation_key=CentriConnectSensorType.DEVICE_TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
suggested_display_precision=1,
value_fn=lambda coord: coord.data.device_temperature,
),
CentriConnectSensorEntityDescription(
key=CentriConnectSensorType.LTE_SIGNAL_LEVEL,
translation_key=CentriConnectSensorType.LTE_SIGNAL_LEVEL,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
entity_category=EntityCategory.DIAGNOSTIC,
suggested_display_precision=0,
value_fn=lambda coord: coord.data.lte_signal_level,
),
CentriConnectSensorEntityDescription(
key=CentriConnectSensorType.LTE_SIGNAL_STRENGTH,
translation_key=CentriConnectSensorType.LTE_SIGNAL_STRENGTH,
native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
value_fn=lambda coord: coord.data.lte_signal_strength,
),
CentriConnectSensorEntityDescription(
key=CentriConnectSensorType.SOLAR_LEVEL,
translation_key=CentriConnectSensorType.SOLAR_LEVEL,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
entity_category=EntityCategory.DIAGNOSTIC,
suggested_display_precision=0,
value_fn=lambda coord: coord.data.solar_level,
),
CentriConnectSensorEntityDescription(
key=CentriConnectSensorType.SOLAR_VOLTAGE,
translation_key=CentriConnectSensorType.SOLAR_VOLTAGE,
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.VOLTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
suggested_display_precision=0,
value_fn=lambda coord: coord.data.solar_voltage,
),
CentriConnectSensorEntityDescription(
key=CentriConnectSensorType.TANK_LEVEL,
translation_key=CentriConnectSensorType.TANK_LEVEL,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda coord: coord.data.tank_level,
),
CentriConnectSensorEntityDescription(
key=CentriConnectSensorType.TANK_REMAINING_VOLUME,
translation_key=CentriConnectSensorType.TANK_REMAINING_VOLUME,
native_unit_of_measurement=UnitOfVolume.GALLONS,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.VOLUME_STORAGE,
suggested_display_precision=2,
value_fn=lambda coord: (
coord.data.tank_remaining_volume
if coord.device_info.tank_size_unit == "Gallons"
else None
),
),
CentriConnectSensorEntityDescription(
key=CentriConnectSensorType.TANK_REMAINING_VOLUME,
translation_key=CentriConnectSensorType.TANK_REMAINING_VOLUME,
native_unit_of_measurement=UnitOfVolume.LITERS,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.VOLUME_STORAGE,
suggested_display_precision=2,
value_fn=lambda coord: (
coord.data.tank_remaining_volume
if coord.device_info.tank_size_unit == "Liters"
else None
),
),
CentriConnectSensorEntityDescription(
key=CentriConnectSensorType.TANK_SIZE,
translation_key=CentriConnectSensorType.TANK_SIZE,
native_unit_of_measurement=UnitOfVolume.GALLONS,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.VOLUME_STORAGE,
suggested_display_precision=2,
value_fn=lambda coord: (
coord.device_info.tank_size
if (coord.device_info.tank_size_unit == "Gallons")
else None
),
),
CentriConnectSensorEntityDescription(
key=CentriConnectSensorType.TANK_SIZE,
translation_key=CentriConnectSensorType.TANK_SIZE,
native_unit_of_measurement=UnitOfVolume.LITERS,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.VOLUME_STORAGE,
suggested_display_precision=2,
value_fn=lambda coord: (
coord.device_info.tank_size
if (coord.device_info.tank_size_unit == "Liters")
else None
),
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: CentriConnectConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up CentriConnect sensor entities from a config entry."""
async_add_entities(
CentriConnectSensor(entry.runtime_data, description)
for description in ENTITIES
if description.value_fn(entry.runtime_data) is not None
)
class CentriConnectSensor(CentriConnectBaseEntity, SensorEntity):
"""Representation of a CentriConnect sensor entity."""
entity_description: CentriConnectSensorEntityDescription
@property
def native_value(self) -> StateType | datetime | None:
"""Return the state of the sensor."""
return self.entity_description.value_fn(self.coordinator)