"""OpenSprinkler integration.""" import logging from typing import Callable from homeassistant.const import CONF_NAME, DEVICE_CLASS_TIMESTAMP from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_platform from homeassistant.helpers.entity import Entity from homeassistant.util import slugify from homeassistant.util.dt import utc_from_timestamp from . import ( OpenSprinklerControllerEntity, OpenSprinklerSensor, OpenSprinklerStationEntity, ) from .const import ( DOMAIN, SCHEMA_SERVICE_RUN, SCHEMA_SERVICE_STOP, SERVICE_RUN, SERVICE_STOP, ) _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: dict, async_add_entities: Callable, ): """Set up the OpenSprinkler sensors.""" entities = _create_entities(hass, entry) async_add_entities(entities) platform = entity_platform.current_platform.get() platform.async_register_entity_service( SERVICE_RUN, SCHEMA_SERVICE_RUN, "run", ) platform.async_register_entity_service( SERVICE_STOP, SCHEMA_SERVICE_STOP, "stop", ) def _create_entities(hass: HomeAssistant, entry: dict): entities = [] controller = hass.data[DOMAIN][entry.entry_id]["controller"] coordinator = hass.data[DOMAIN][entry.entry_id]["coordinator"] name = entry.data[CONF_NAME] entities.append(LastRunSensor(entry, name, controller, coordinator)) entities.append(RainDelayStopTimeSensor(entry, name, controller, coordinator)) entities.append(WaterLevelSensor(entry, name, controller, coordinator)) entities.append(FlowRateSensor(entry, name, controller, coordinator)) for _, station in controller.stations.items(): entities.append(StationStatusSensor(entry, name, station, coordinator)) return entities class WaterLevelSensor(OpenSprinklerControllerEntity, OpenSprinklerSensor, Entity): """Represent a sensor for water level.""" def __init__(self, entry, name, controller, coordinator): """Set up a new opensprinkler water level sensor.""" self._name = name self._controller = controller self._entity_type = "sensor" super().__init__(entry, name, coordinator) @property def icon(self) -> str: """Return icon.""" return "mdi:water-percent" @property def name(self) -> str: """Return the name of this sensor including the controller name.""" return f"{self._name} Water Level" @property def unique_id(self) -> str: """Return a unique, Home Assistant friendly identifier for this entity.""" return slugify(f"{self._entry.unique_id}_{self._entity_type}_water_level") @property def unit_of_measurement(self) -> str: """Return the units of measurement.""" return "%" @property def device_state_attributes(self): controller = self._controller attributes = {} for attr in [ "last_weather_call_error", "last_weather_call_error_name", ]: try: attributes[attr] = getattr(controller, attr) except: pass for attr in [ "last_weather_call", "last_successfull_weather_call", ]: timestamp = getattr(controller, attr) if not timestamp: attributes[attr] = None else: attributes[attr] = utc_from_timestamp(timestamp).isoformat() return attributes def _get_state(self) -> int: """Retrieve latest state.""" return self._controller.water_level class FlowRateSensor(OpenSprinklerControllerEntity, OpenSprinklerSensor, Entity): """Represent a sensor for flow rate.""" def __init__(self, entry, name, controller, coordinator): """Set up a new opensprinkler water level sensor.""" self._name = name self._controller = controller self._entity_type = "sensor" super().__init__(entry, name, coordinator) @property def icon(self) -> str: """Return icon.""" return "mdi:speedometer" @property def name(self) -> str: """Return the name of this sensor including the controller name.""" return f"{self._name} Flow Rate" @property def unique_id(self) -> str: """Return a unique, Home Assistant friendly identifier for this entity.""" return slugify(f"{self._entry.unique_id}_{self._entity_type}_flow_rate") def _get_state(self) -> int: """Retrieve latest state.""" return self._controller.flow_rate class LastRunSensor(OpenSprinklerControllerEntity, OpenSprinklerSensor, Entity): """Represent a sensor that for last run time.""" def __init__(self, entry, name, controller, coordinator): """Set up a new opensprinkler last run sensor.""" self._controller = controller self._entity_type = "sensor" super().__init__(entry, name, coordinator) @property def device_class(self): """Return the device class.""" return DEVICE_CLASS_TIMESTAMP @property def icon(self) -> str: """Return icon.""" return "mdi:history" @property def name(self) -> str: """Return the name of this sensor including the controller name.""" return f"{self._name} Last Run" @property def unique_id(self) -> str: """Return a unique, Home Assistant friendly identifier for this entity.""" return slugify(f"{self._entry.unique_id}_{self._entity_type}_last_run") @property def device_state_attributes(self): controller = self._controller attributes = {} for attr in [ "last_run_station", "last_run_program", "last_run_duration", ]: try: attributes[attr] = getattr(controller, attr) except: pass return attributes def _get_state(self): """Retrieve latest state.""" last_run = self._controller.last_run_end_time if last_run == 0: return None return utc_from_timestamp(last_run).isoformat() class RainDelayStopTimeSensor( OpenSprinklerControllerEntity, OpenSprinklerSensor, Entity ): """Represent a sensor that for rain delay stop time.""" def __init__(self, entry, name, controller, coordinator): """Set up a new opensprinkler rain delay stop time sensor.""" self._controller = controller self._entity_type = "sensor" super().__init__(entry, name, coordinator) @property def device_class(self): """Return the device class.""" return DEVICE_CLASS_TIMESTAMP @property def icon(self) -> str: """Return icon.""" return "mdi:weather-rainy" @property def name(self) -> str: """Return the name of this sensor including the controller name.""" return f"{self._name} Rain Delay Stop Time" @property def unique_id(self) -> str: """Return a unique, Home Assistant friendly identifier for this entity.""" return slugify(f"{self._entry.unique_id}_{self._entity_type}_rdst") def _get_state(self): """Retrieve latest state.""" rdst = self._controller.rain_delay_stop_time if rdst == 0: return None return utc_from_timestamp(rdst).isoformat() class StationStatusSensor(OpenSprinklerStationEntity, OpenSprinklerSensor, Entity): """Represent a sensor for status of station.""" def __init__(self, entry, name, station, coordinator): """Set up a new OpenSprinkler station sensor.""" self._station = station self._entity_type = "sensor" super().__init__(entry, name, coordinator) @property def name(self) -> str: """Return the name of this sensor.""" return self._station.name + " Station Status" @property def unique_id(self) -> str: """Return a unique, Home Assistant friendly identifier for this entity.""" return slugify( f"{self._entry.unique_id}_{self._entity_type}_station_status_{self._station.index}" ) @property def icon(self) -> str: """Return icon.""" if self._station.is_master: if self.state == "master_engaged": return "mdi:water-pump" else: return "mdi:water-pump-off" if self._station.is_running: return "mdi:valve-open" return "mdi:valve-closed" def _get_state(self) -> str: """Retrieve latest state.""" return self._station.status