"""Creates a the sensor entities for the mower.""" from collections.abc import Callable from dataclasses import dataclass from datetime import datetime import logging from aioautomower.model import MowerAttributes, MowerModes from homeassistant.components.sensor import ( SensorDeviceClass, SensorEntity, SensorEntityDescription, SensorStateClass, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfLength, UnitOfTime from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util from .const import DOMAIN from .coordinator import AutomowerDataUpdateCoordinator from .entity import AutomowerBaseEntity _LOGGER = logging.getLogger(__name__) @dataclass(frozen=True, kw_only=True) class AutomowerSensorEntityDescription(SensorEntityDescription): """Describes Automower sensor entity.""" exists_fn: Callable[[MowerAttributes], bool] = lambda _: True value_fn: Callable[[MowerAttributes], StateType | datetime] SENSOR_TYPES: tuple[AutomowerSensorEntityDescription, ...] = ( AutomowerSensorEntityDescription( key="battery_percent", state_class=SensorStateClass.MEASUREMENT, device_class=SensorDeviceClass.BATTERY, native_unit_of_measurement=PERCENTAGE, value_fn=lambda data: data.battery.battery_percent, ), AutomowerSensorEntityDescription( key="mode", translation_key="mode", device_class=SensorDeviceClass.ENUM, options=[option.lower() for option in list(MowerModes)], value_fn=( lambda data: data.mower.mode.lower() if data.mower.mode != MowerModes.UNKNOWN else None ), ), AutomowerSensorEntityDescription( key="cutting_blade_usage_time", translation_key="cutting_blade_usage_time", state_class=SensorStateClass.TOTAL, device_class=SensorDeviceClass.DURATION, native_unit_of_measurement=UnitOfTime.SECONDS, suggested_unit_of_measurement=UnitOfTime.HOURS, exists_fn=lambda data: data.statistics.cutting_blade_usage_time is not None, value_fn=lambda data: data.statistics.cutting_blade_usage_time, ), AutomowerSensorEntityDescription( key="total_charging_time", translation_key="total_charging_time", entity_category=EntityCategory.DIAGNOSTIC, state_class=SensorStateClass.TOTAL, device_class=SensorDeviceClass.DURATION, native_unit_of_measurement=UnitOfTime.SECONDS, suggested_unit_of_measurement=UnitOfTime.HOURS, exists_fn=lambda data: data.statistics.total_charging_time is not None, value_fn=lambda data: data.statistics.total_charging_time, ), AutomowerSensorEntityDescription( key="total_cutting_time", translation_key="total_cutting_time", entity_category=EntityCategory.DIAGNOSTIC, state_class=SensorStateClass.TOTAL, device_class=SensorDeviceClass.DURATION, native_unit_of_measurement=UnitOfTime.SECONDS, suggested_unit_of_measurement=UnitOfTime.HOURS, exists_fn=lambda data: data.statistics.total_cutting_time is not None, value_fn=lambda data: data.statistics.total_cutting_time, ), AutomowerSensorEntityDescription( key="total_running_time", translation_key="total_running_time", entity_category=EntityCategory.DIAGNOSTIC, state_class=SensorStateClass.TOTAL, device_class=SensorDeviceClass.DURATION, native_unit_of_measurement=UnitOfTime.SECONDS, suggested_unit_of_measurement=UnitOfTime.HOURS, exists_fn=lambda data: data.statistics.total_running_time is not None, value_fn=lambda data: data.statistics.total_running_time, ), AutomowerSensorEntityDescription( key="total_searching_time", translation_key="total_searching_time", entity_category=EntityCategory.DIAGNOSTIC, state_class=SensorStateClass.TOTAL, device_class=SensorDeviceClass.DURATION, native_unit_of_measurement=UnitOfTime.SECONDS, suggested_unit_of_measurement=UnitOfTime.HOURS, exists_fn=lambda data: data.statistics.total_searching_time is not None, value_fn=lambda data: data.statistics.total_searching_time, ), AutomowerSensorEntityDescription( key="number_of_charging_cycles", translation_key="number_of_charging_cycles", entity_category=EntityCategory.DIAGNOSTIC, state_class=SensorStateClass.TOTAL, exists_fn=lambda data: data.statistics.number_of_charging_cycles is not None, value_fn=lambda data: data.statistics.number_of_charging_cycles, ), AutomowerSensorEntityDescription( key="number_of_collisions", translation_key="number_of_collisions", entity_category=EntityCategory.DIAGNOSTIC, state_class=SensorStateClass.TOTAL, exists_fn=lambda data: data.statistics.number_of_collisions is not None, value_fn=lambda data: data.statistics.number_of_collisions, ), AutomowerSensorEntityDescription( key="total_drive_distance", translation_key="total_drive_distance", entity_category=EntityCategory.DIAGNOSTIC, state_class=SensorStateClass.TOTAL, device_class=SensorDeviceClass.DISTANCE, native_unit_of_measurement=UnitOfLength.METERS, suggested_unit_of_measurement=UnitOfLength.KILOMETERS, exists_fn=lambda data: data.statistics.total_drive_distance is not None, value_fn=lambda data: data.statistics.total_drive_distance, ), AutomowerSensorEntityDescription( key="next_start_timestamp", translation_key="next_start_timestamp", device_class=SensorDeviceClass.TIMESTAMP, value_fn=lambda data: dt_util.as_local(data.planner.next_start_datetime), ), ) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up sensor platform.""" coordinator: AutomowerDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] async_add_entities( AutomowerSensorEntity(mower_id, coordinator, description) for mower_id in coordinator.data for description in SENSOR_TYPES if description.exists_fn(coordinator.data[mower_id]) ) class AutomowerSensorEntity(AutomowerBaseEntity, SensorEntity): """Defining the Automower Sensors with AutomowerSensorEntityDescription.""" entity_description: AutomowerSensorEntityDescription def __init__( self, mower_id: str, coordinator: AutomowerDataUpdateCoordinator, description: AutomowerSensorEntityDescription, ) -> None: """Set up AutomowerSensors.""" super().__init__(mower_id, coordinator) self.entity_description = description self._attr_unique_id = f"{mower_id}_{description.key}" @property def native_value(self) -> StateType | datetime: """Return the state of the sensor.""" return self.entity_description.value_fn(self.mower_attributes)