"""Support for Tasmota sensors.""" from typing import Optional from hatasmota.const import ( SENSOR_AMBIENT, SENSOR_APPARENT_POWERUSAGE, SENSOR_BATTERY, SENSOR_CCT, SENSOR_CO2, SENSOR_COLOR_BLUE, SENSOR_COLOR_GREEN, SENSOR_COLOR_RED, SENSOR_CURRENT, SENSOR_DEWPOINT, SENSOR_DISTANCE, SENSOR_ECO2, SENSOR_FREQUENCY, SENSOR_HUMIDITY, SENSOR_ILLUMINANCE, SENSOR_MOISTURE, SENSOR_PB0_3, SENSOR_PB0_5, SENSOR_PB1, SENSOR_PB2_5, SENSOR_PB5, SENSOR_PB10, SENSOR_PM1, SENSOR_PM2_5, SENSOR_PM10, SENSOR_POWERFACTOR, SENSOR_POWERUSAGE, SENSOR_PRESSURE, SENSOR_PRESSUREATSEALEVEL, SENSOR_PROXIMITY, SENSOR_REACTIVE_POWERUSAGE, SENSOR_TEMPERATURE, SENSOR_TODAY, SENSOR_TOTAL, SENSOR_TOTAL_START_TIME, SENSOR_TVOC, SENSOR_VOLTAGE, SENSOR_WEIGHT, SENSOR_YESTERDAY, ) from homeassistant.components import sensor from homeassistant.const import ( DEVICE_CLASS_BATTERY, DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_ILLUMINANCE, DEVICE_CLASS_POWER, DEVICE_CLASS_PRESSURE, DEVICE_CLASS_TEMPERATURE, ) from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import Entity from .const import DOMAIN as TASMOTA_DOMAIN from .discovery import TASMOTA_DISCOVERY_ENTITY_NEW from .mixins import TasmotaAvailability, TasmotaDiscoveryUpdate DEVICE_CLASS = "device_class" ICON = "icon" # A Tasmota sensor type may be mapped to either a device class or an icon, not both SENSOR_DEVICE_CLASS_ICON_MAP = { SENSOR_AMBIENT: {DEVICE_CLASS: DEVICE_CLASS_ILLUMINANCE}, SENSOR_APPARENT_POWERUSAGE: {DEVICE_CLASS: DEVICE_CLASS_POWER}, SENSOR_BATTERY: {DEVICE_CLASS: DEVICE_CLASS_BATTERY}, SENSOR_CCT: {ICON: "mdi:temperature-kelvin"}, SENSOR_CO2: {ICON: "mdi:molecule-co2"}, SENSOR_COLOR_BLUE: {ICON: "mdi:palette"}, SENSOR_COLOR_GREEN: {ICON: "mdi:palette"}, SENSOR_COLOR_RED: {ICON: "mdi:palette"}, SENSOR_CURRENT: {ICON: "mdi:alpha-a-circle-outline"}, SENSOR_DEWPOINT: {ICON: "mdi:weather-rainy"}, SENSOR_DISTANCE: {ICON: "mdi:leak"}, SENSOR_ECO2: {ICON: "mdi:molecule-co2"}, SENSOR_FREQUENCY: {ICON: "mdi:current-ac"}, SENSOR_HUMIDITY: {DEVICE_CLASS: DEVICE_CLASS_HUMIDITY}, SENSOR_ILLUMINANCE: {DEVICE_CLASS: DEVICE_CLASS_ILLUMINANCE}, SENSOR_MOISTURE: {ICON: "mdi:cup-water"}, SENSOR_PB0_3: {ICON: "mdi:flask"}, SENSOR_PB0_5: {ICON: "mdi:flask"}, SENSOR_PB10: {ICON: "mdi:flask"}, SENSOR_PB1: {ICON: "mdi:flask"}, SENSOR_PB2_5: {ICON: "mdi:flask"}, SENSOR_PB5: {ICON: "mdi:flask"}, SENSOR_PM10: {ICON: "mdi:air-filter"}, SENSOR_PM1: {ICON: "mdi:air-filter"}, SENSOR_PM2_5: {ICON: "mdi:air-filter"}, SENSOR_POWERFACTOR: {ICON: "mdi:alpha-f-circle-outline"}, SENSOR_POWERUSAGE: {DEVICE_CLASS: DEVICE_CLASS_POWER}, SENSOR_PRESSURE: {DEVICE_CLASS: DEVICE_CLASS_PRESSURE}, SENSOR_PRESSUREATSEALEVEL: {DEVICE_CLASS: DEVICE_CLASS_PRESSURE}, SENSOR_PROXIMITY: {ICON: "mdi:ruler"}, SENSOR_REACTIVE_POWERUSAGE: {DEVICE_CLASS: DEVICE_CLASS_POWER}, SENSOR_TEMPERATURE: {DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE}, SENSOR_TODAY: {DEVICE_CLASS: DEVICE_CLASS_POWER}, SENSOR_TOTAL: {DEVICE_CLASS: DEVICE_CLASS_POWER}, SENSOR_TOTAL_START_TIME: {ICON: "mdi:progress-clock"}, SENSOR_TVOC: {ICON: "mdi:air-filter"}, SENSOR_VOLTAGE: {ICON: "mdi:alpha-v-circle-outline"}, SENSOR_WEIGHT: {ICON: "mdi:scale"}, SENSOR_YESTERDAY: {DEVICE_CLASS: DEVICE_CLASS_POWER}, } async def async_setup_entry(hass, config_entry, async_add_entities): """Set up Tasmota sensor dynamically through discovery.""" async def async_discover_sensor(tasmota_entity, discovery_hash): """Discover and add a Tasmota sensor.""" async_add_entities( [ TasmotaSensor( tasmota_entity=tasmota_entity, discovery_hash=discovery_hash ) ] ) async_dispatcher_connect( hass, TASMOTA_DISCOVERY_ENTITY_NEW.format(sensor.DOMAIN, TASMOTA_DOMAIN), async_discover_sensor, ) class TasmotaSensor(TasmotaAvailability, TasmotaDiscoveryUpdate, Entity): """Representation of a Tasmota sensor.""" def __init__(self, **kwds): """Initialize the Tasmota sensor.""" self._state = False super().__init__( discovery_update=self.discovery_update, **kwds, ) @property def device_class(self) -> Optional[str]: """Return the device class of the sensor.""" class_or_icon = SENSOR_DEVICE_CLASS_ICON_MAP.get( self._tasmota_entity.quantity, {} ) return class_or_icon.get(DEVICE_CLASS) @property def icon(self): """Return the icon.""" class_or_icon = SENSOR_DEVICE_CLASS_ICON_MAP.get( self._tasmota_entity.quantity, {} ) return class_or_icon.get(ICON) @property def state(self): """Return the state of the entity.""" return self._state @property def unit_of_measurement(self): """Return the unit this state is expressed in.""" return self._tasmota_entity.unit