""" for sensors components """ import logging from datetime import datetime, timedelta from homeassistant.core import HomeAssistant, callback, Event, State from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.components.sensor import ( SensorEntity, SensorDeviceClass, SensorStateClass, ) from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, ) from homeassistant.helpers.event import ( async_track_time_interval, async_track_state_change_event, ) from homeassistant.const import ( ATTR_TEMPERATURE, UnitOfTime, UnitOfTemperature ) from .const import ( DOMAIN ) from .coordinator import KoolnovaCoordinator from .koolnova.device import ( Koolnova, Engine, ) _LOGGER = logging.getLogger(__name__) MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback): """ Configuration des entités sensor à partir de la configuration ConfigEntry passée en argument """ device = hass.data[DOMAIN]["device"] coordinator = hass.data[DOMAIN]["coordinator"] entities = [ DiagnosticsSensor(device, "Device", entry.data), DiagnosticsSensor(device, "Address", entry.data), DiagModbusSensor(device, entry.data), ] for engine in device.engines: entities.append(DiagEngineThroughputSensor(coordinator, device, engine)) entities.append(DiagEngineTempOrderSensor(coordinator, device, engine)) async_add_entities(entities) class DiagnosticsSensor(SensorEntity): # pylint: disable = too-many-instance-attributes """ Representation of a Sensor """ _attr_entity_category: EntityCategory | None = EntityCategory.DIAGNOSTIC def __init__(self, device: Koolnova, # pylint: disable=unused-argument, name:str, # pylint: disable=unused-argument entry_infos, # pylint: disable=unused-argument ) -> None: """ Class constructor """ self._device = device self._attr_name = f"{device.name} {name}" self._attr_entity_registry_enabled_default = True self._attr_device_info = self._device.device_info self._attr_unique_id = f"{DOMAIN}-{name}-sensor" self._attr_native_value = entry_infos.get(name) @property def icon(self) -> str | None: return "mdi:monitor" @property def should_poll(self) -> bool: """ Do not poll for those entities """ return False class DiagModbusSensor(SensorEntity): # pylint: disable = too-many-instance-attributes """ Representation of a Sensor """ _attr_entity_category: EntityCategory | None = EntityCategory.DIAGNOSTIC def __init__(self, device: Koolnova, # pylint: disable=unused-argument, entry_infos, # pylint: disable=unused-argument ) -> None: """ Class constructor """ self._device = device self._attr_name = f"{device.name} Modbus RTU" self._attr_entity_registry_enabled_default = True self._attr_device_info = self._device.device_info self._attr_unique_id = f"{DOMAIN}-Modbus-RTU-sensor" self._attr_native_value = "{} {}{}{}".format(entry_infos.get("Baudrate"), entry_infos.get("Sizebyte"), entry_infos.get("Parity")[0], entry_infos.get("Stopbits")) @property def icon(self) -> str | None: return "mdi:monitor" @property def should_poll(self) -> bool: """ Do not poll for those entities """ return False class DiagEngineThroughputSensor(CoordinatorEntity, SensorEntity): # pylint: disable = too-many-instance-attributes """ Representation of a Sensor """ _attr_entity_category: EntityCategory | None = EntityCategory.DIAGNOSTIC def __init__(self, coordinator: KoolnovaCoordinator, # pylint: disable=unused-argument device: Koolnova, # pylint: disable=unused-argument engine: Engine, # pylint: disable=unused-argument ) -> None: """ Class constructor """ super().__init__(coordinator) self._device = device self._engine = engine self._attr_name = f"{device.name} Engine AC{engine.engine_id} Throughput" self._attr_entity_registry_enabled_default = True self._attr_device_info = self._device.device_info self._attr_unique_id = f"{DOMAIN}-Engine-AC{engine.engine_id}-throughput-sensor" self._attr_native_value = "{}".format(engine.throughput) @property def icon(self) -> str | None: return "mdi:thermostat-cog" @callback def _handle_coordinator_update(self) -> None: """ Handle updated data from the coordinator """ for _cur_engine in self.coordinator.data['engines']: if self._engine.engine_id == _cur_engine.engine_id: _LOGGER.debug("[UPDATE] [ENGINE AC{}] Troughput: {}".format(_cur_engine.engine_id, _cur_engine.throughput)) self._attr_native_value = "{}".format(_cur_engine.throughput) self.async_write_ha_state() class DiagEngineTempOrderSensor(CoordinatorEntity, SensorEntity): # pylint: disable = too-many-instance-attributes """ Representation of a Sensor """ _attr_entity_category: EntityCategory | None = EntityCategory.DIAGNOSTIC _attr_native_unit_of_measurement: str = UnitOfTemperature.CELSIUS def __init__(self, coordinator: KoolnovaCoordinator, # pylint: disable=unused-argument device: Koolnova, # pylint: disable=unused-argument engine: Engine, # pylint: disable=unused-argument ) -> None: """ Class constructor """ super().__init__(coordinator) self._device = device self._engine = engine self._attr_name = f"{device.name} Engine AC{engine.engine_id} Temperature Order" self._attr_entity_registry_enabled_default = True self._attr_device_info = self._device.device_info self._attr_unique_id = f"{DOMAIN}-Engine-AC{engine.engine_id}-temp-order-sensor" self._attr_native_value = "{}".format(engine.order_temp) @property def icon(self) -> str | None: return "mdi:thermometer-lines" @callback def _handle_coordinator_update(self) -> None: """ Handle updated data from the coordinator """ for _cur_engine in self.coordinator.data['engines']: if self._engine.engine_id == _cur_engine.engine_id: _LOGGER.debug("[UPDATE] [ENGINE AC{}] Order temp: {}".format(_cur_engine.engine_id, _cur_engine.order_temp)) self._attr_native_value = "{}".format(_cur_engine.order_temp) self.async_write_ha_state()