"""Support for Toon sensors.""" import logging from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.typing import HomeAssistantType from homeassistant.const import ENERGY_KILO_WATT_HOUR, POWER_WATT from . import ( ToonData, ToonEntity, ToonElectricityMeterDeviceEntity, ToonGasMeterDeviceEntity, ToonSolarDeviceEntity, ToonBoilerDeviceEntity, ) from .const import ( CURRENCY_EUR, DATA_TOON, DOMAIN, VOLUME_CM3, VOLUME_M3, RATIO_PERCENT, ) _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistantType, entry: ConfigEntry, async_add_entities ) -> None: """Set up Toon sensors based on a config entry.""" toon = hass.data[DATA_TOON][entry.entry_id] sensors = [ ToonElectricityMeterDeviceSensor( toon, 'power', 'value', "Current Power Usage", 'mdi:power-plug', POWER_WATT, ), ToonElectricityMeterDeviceSensor( toon, 'power', 'average', "Average Power Usage", 'mdi:power-plug', POWER_WATT, ), ToonElectricityMeterDeviceSensor( toon, 'power', 'daily_value', "Power Usage Today", 'mdi:power-plug', ENERGY_KILO_WATT_HOUR, ), ToonElectricityMeterDeviceSensor( toon, 'power', 'daily_cost', "Power Cost Today", 'mdi:power-plug', CURRENCY_EUR, ), ToonElectricityMeterDeviceSensor( toon, 'power', 'average_daily', "Average Daily Power Usage", 'mdi:power-plug', ENERGY_KILO_WATT_HOUR, ), ToonElectricityMeterDeviceSensor( toon, 'power', 'meter_reading', "Power Meter Feed IN Tariff 1", 'mdi:power-plug', ENERGY_KILO_WATT_HOUR, ), ToonElectricityMeterDeviceSensor( toon, 'power', 'meter_reading_low', "Power Meter Feed IN Tariff 2", 'mdi:power-plug', ENERGY_KILO_WATT_HOUR, ), ] if toon.gas: sensors.extend( [ ToonGasMeterDeviceSensor( toon, 'gas', 'value', "Current Gas Usage", 'mdi:gas-cylinder', VOLUME_CM3, ), ToonGasMeterDeviceSensor( toon, 'gas', 'average', "Average Gas Usage", 'mdi:gas-cylinder', VOLUME_CM3, ), ToonGasMeterDeviceSensor( toon, 'gas', 'daily_usage', "Gas Usage Today", 'mdi:gas-cylinder', VOLUME_M3, ), ToonGasMeterDeviceSensor( toon, 'gas', 'average_daily', "Average Daily Gas Usage", 'mdi:gas-cylinder', VOLUME_M3, ), ToonGasMeterDeviceSensor( toon, 'gas', 'meter_reading', "Gas Meter", 'mdi:gas-cylinder', VOLUME_M3, ), ToonGasMeterDeviceSensor( toon, 'gas', 'daily_cost', "Gas Cost Today", 'mdi:gas-cylinder', CURRENCY_EUR, ), ] ) if toon.solar: sensors.extend( [ ToonSolarDeviceSensor( toon, 'solar', 'value', "Current Solar Production", 'mdi:solar-power', POWER_WATT, ), ToonSolarDeviceSensor( toon, 'solar', 'maximum', "Max Solar Production", 'mdi:solar-power', POWER_WATT, ), ToonSolarDeviceSensor( toon, 'solar', 'produced', "Solar Production to Grid", 'mdi:solar-power', POWER_WATT, ), ToonSolarDeviceSensor( toon, 'solar', 'average_produced', "Average Solar Production to Grid", 'mdi:solar-power', POWER_WATT, ), ToonElectricityMeterDeviceSensor( toon, 'solar', 'meter_reading_produced', "Power Meter Feed OUT Tariff 1", 'mdi:solar-power', ENERGY_KILO_WATT_HOUR, ), ToonElectricityMeterDeviceSensor( toon, 'solar', 'meter_reading_low_produced', "Power Meter Feed OUT Tariff 2", 'mdi:solar-power', ENERGY_KILO_WATT_HOUR, ), ] ) if toon.thermostat_info.have_ot_boiler: sensors.extend( [ ToonBoilerDeviceSensor( toon, 'thermostat_info', 'current_modulation_level', "Boiler Modulation Level", 'mdi:percent', RATIO_PERCENT, ) ] ) async_add_entities(sensors, True) class ToonSensor(ToonEntity): """Defines a Toon sensor.""" def __init__( self, toon: ToonData, section: str, measurement: str, name: str, icon: str, unit_of_measurement: str, ) -> None: """Initialize the Toon sensor.""" self._state = None self._unit_of_measurement = unit_of_measurement self.section = section self.measurement = measurement super().__init__(toon, name, icon) @property def unique_id(self) -> str: """Return the unique ID for this sensor.""" return '_'.join( [ DOMAIN, self.toon.agreement.id, 'sensor', self.section, self.measurement, ] ) @property def state(self): """Return the state of the sensor.""" return self._state @property def unit_of_measurement(self) -> str: """Return the unit this state is expressed in.""" return self._unit_of_measurement def update(self) -> None: """Get the latest data from the sensor.""" section = getattr(self.toon, self.section) value = None if not section: return if self.section == 'power' and self.measurement == 'daily_value': value = round( (float(section.daily_usage) + float(section.daily_usage_low)) / 1000.0, 2, ) if value is None: value = getattr(section, self.measurement) if self.section == 'power' and self.measurement in [ 'meter_reading', 'meter_reading_low', 'average_daily', ]: value = round(float(value) / 1000.0, 2) if self.section == 'solar' and self.measurement in [ 'meter_reading_produced', 'meter_reading_low_produced', ]: value = float(value) / 1000.0 if self.section == 'gas' and self.measurement in [ 'average_daily', 'daily_usage', 'meter_reading', ]: value = round(float(value) / 1000.0, 2) self._state = max(0, value) class ToonElectricityMeterDeviceSensor( ToonSensor, ToonElectricityMeterDeviceEntity ): """Defines a Electricity Meter sensor.""" pass class ToonGasMeterDeviceSensor(ToonSensor, ToonGasMeterDeviceEntity): """Defines a Gas Meter sensor.""" pass class ToonSolarDeviceSensor(ToonSensor, ToonSolarDeviceEntity): """Defines a Solar sensor.""" pass class ToonBoilerDeviceSensor(ToonSensor, ToonBoilerDeviceEntity): """Defines a Boiler sensor.""" pass