Use EntityDescription - aemet (#55744)

This commit is contained in:
Marc Mueller 2021-09-06 10:12:09 +02:00 committed by GitHub
parent 77b60c712e
commit 655399eb7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 182 additions and 168 deletions

View File

@ -1,5 +1,7 @@
"""Constant values for the AEMET OpenData component.""" """Constant values for the AEMET OpenData component."""
from __future__ import annotations
from homeassistant.components.sensor import SensorEntityDescription
from homeassistant.components.weather import ( from homeassistant.components.weather import (
ATTR_CONDITION_CLEAR_NIGHT, ATTR_CONDITION_CLEAR_NIGHT,
ATTR_CONDITION_CLOUDY, ATTR_CONDITION_CLOUDY,
@ -40,9 +42,6 @@ DEFAULT_NAME = "AEMET"
DOMAIN = "aemet" DOMAIN = "aemet"
ENTRY_NAME = "name" ENTRY_NAME = "name"
ENTRY_WEATHER_COORDINATOR = "weather_coordinator" ENTRY_WEATHER_COORDINATOR = "weather_coordinator"
SENSOR_NAME = "sensor_name"
SENSOR_UNIT = "sensor_unit"
SENSOR_DEVICE_CLASS = "sensor_device_class"
ATTR_API_CONDITION = "condition" ATTR_API_CONDITION = "condition"
ATTR_API_FORECAST_DAILY = "forecast-daily" ATTR_API_FORECAST_DAILY = "forecast-daily"
@ -200,118 +199,145 @@ FORECAST_MODE_ATTR_API = {
FORECAST_MODE_HOURLY: ATTR_API_FORECAST_HOURLY, FORECAST_MODE_HOURLY: ATTR_API_FORECAST_HOURLY,
} }
FORECAST_SENSOR_TYPES = { FORECAST_SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
ATTR_FORECAST_CONDITION: { SensorEntityDescription(
SENSOR_NAME: "Condition", key=ATTR_FORECAST_CONDITION,
}, name="Condition",
ATTR_FORECAST_PRECIPITATION: { ),
SENSOR_NAME: "Precipitation", SensorEntityDescription(
SENSOR_UNIT: PRECIPITATION_MILLIMETERS_PER_HOUR, key=ATTR_FORECAST_PRECIPITATION,
}, name="Precipitation",
ATTR_FORECAST_PRECIPITATION_PROBABILITY: { native_unit_of_measurement=PRECIPITATION_MILLIMETERS_PER_HOUR,
SENSOR_NAME: "Precipitation probability", ),
SENSOR_UNIT: PERCENTAGE, SensorEntityDescription(
}, key=ATTR_FORECAST_PRECIPITATION_PROBABILITY,
ATTR_FORECAST_TEMP: { name="Precipitation probability",
SENSOR_NAME: "Temperature", native_unit_of_measurement=PERCENTAGE,
SENSOR_UNIT: TEMP_CELSIUS, ),
SENSOR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, SensorEntityDescription(
}, key=ATTR_FORECAST_TEMP,
ATTR_FORECAST_TEMP_LOW: { name="Temperature",
SENSOR_NAME: "Temperature Low", native_unit_of_measurement=TEMP_CELSIUS,
SENSOR_UNIT: TEMP_CELSIUS, device_class=DEVICE_CLASS_TEMPERATURE,
SENSOR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, ),
}, SensorEntityDescription(
ATTR_FORECAST_TIME: { key=ATTR_FORECAST_TEMP_LOW,
SENSOR_NAME: "Time", name="Temperature Low",
SENSOR_DEVICE_CLASS: DEVICE_CLASS_TIMESTAMP, native_unit_of_measurement=TEMP_CELSIUS,
}, device_class=DEVICE_CLASS_TEMPERATURE,
ATTR_FORECAST_WIND_BEARING: { ),
SENSOR_NAME: "Wind bearing", SensorEntityDescription(
SENSOR_UNIT: DEGREE, key=ATTR_FORECAST_TIME,
}, name="Time",
ATTR_FORECAST_WIND_SPEED: { device_class=DEVICE_CLASS_TIMESTAMP,
SENSOR_NAME: "Wind speed", ),
SENSOR_UNIT: SPEED_KILOMETERS_PER_HOUR, SensorEntityDescription(
}, key=ATTR_FORECAST_WIND_BEARING,
} name="Wind bearing",
WEATHER_SENSOR_TYPES = { native_unit_of_measurement=DEGREE,
ATTR_API_CONDITION: { ),
SENSOR_NAME: "Condition", SensorEntityDescription(
}, key=ATTR_FORECAST_WIND_SPEED,
ATTR_API_HUMIDITY: { name="Wind speed",
SENSOR_NAME: "Humidity", native_unit_of_measurement=SPEED_KILOMETERS_PER_HOUR,
SENSOR_UNIT: PERCENTAGE, ),
SENSOR_DEVICE_CLASS: DEVICE_CLASS_HUMIDITY, )
}, WEATHER_SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
ATTR_API_PRESSURE: { SensorEntityDescription(
SENSOR_NAME: "Pressure", key=ATTR_API_CONDITION,
SENSOR_UNIT: PRESSURE_HPA, name="Condition",
SENSOR_DEVICE_CLASS: DEVICE_CLASS_PRESSURE, ),
}, SensorEntityDescription(
ATTR_API_RAIN: { key=ATTR_API_HUMIDITY,
SENSOR_NAME: "Rain", name="Humidity",
SENSOR_UNIT: PRECIPITATION_MILLIMETERS_PER_HOUR, native_unit_of_measurement=PERCENTAGE,
}, device_class=DEVICE_CLASS_HUMIDITY,
ATTR_API_RAIN_PROB: { ),
SENSOR_NAME: "Rain probability", SensorEntityDescription(
SENSOR_UNIT: PERCENTAGE, key=ATTR_API_PRESSURE,
}, name="Pressure",
ATTR_API_SNOW: { native_unit_of_measurement=PRESSURE_HPA,
SENSOR_NAME: "Snow", device_class=DEVICE_CLASS_PRESSURE,
SENSOR_UNIT: PRECIPITATION_MILLIMETERS_PER_HOUR, ),
}, SensorEntityDescription(
ATTR_API_SNOW_PROB: { key=ATTR_API_RAIN,
SENSOR_NAME: "Snow probability", name="Rain",
SENSOR_UNIT: PERCENTAGE, native_unit_of_measurement=PRECIPITATION_MILLIMETERS_PER_HOUR,
}, ),
ATTR_API_STATION_ID: { SensorEntityDescription(
SENSOR_NAME: "Station ID", key=ATTR_API_RAIN_PROB,
}, name="Rain probability",
ATTR_API_STATION_NAME: { native_unit_of_measurement=PERCENTAGE,
SENSOR_NAME: "Station name", ),
}, SensorEntityDescription(
ATTR_API_STATION_TIMESTAMP: { key=ATTR_API_SNOW,
SENSOR_NAME: "Station timestamp", name="Snow",
SENSOR_DEVICE_CLASS: DEVICE_CLASS_TIMESTAMP, native_unit_of_measurement=PRECIPITATION_MILLIMETERS_PER_HOUR,
}, ),
ATTR_API_STORM_PROB: { SensorEntityDescription(
SENSOR_NAME: "Storm probability", key=ATTR_API_SNOW_PROB,
SENSOR_UNIT: PERCENTAGE, name="Snow probability",
}, native_unit_of_measurement=PERCENTAGE,
ATTR_API_TEMPERATURE: { ),
SENSOR_NAME: "Temperature", SensorEntityDescription(
SENSOR_UNIT: TEMP_CELSIUS, key=ATTR_API_STATION_ID,
SENSOR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, name="Station ID",
}, ),
ATTR_API_TEMPERATURE_FEELING: { SensorEntityDescription(
SENSOR_NAME: "Temperature feeling", key=ATTR_API_STATION_NAME,
SENSOR_UNIT: TEMP_CELSIUS, name="Station name",
SENSOR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, ),
}, SensorEntityDescription(
ATTR_API_TOWN_ID: { key=ATTR_API_STATION_TIMESTAMP,
SENSOR_NAME: "Town ID", name="Station timestamp",
}, device_class=DEVICE_CLASS_TIMESTAMP,
ATTR_API_TOWN_NAME: { ),
SENSOR_NAME: "Town name", SensorEntityDescription(
}, key=ATTR_API_STORM_PROB,
ATTR_API_TOWN_TIMESTAMP: { name="Storm probability",
SENSOR_NAME: "Town timestamp", native_unit_of_measurement=PERCENTAGE,
SENSOR_DEVICE_CLASS: DEVICE_CLASS_TIMESTAMP, ),
}, SensorEntityDescription(
ATTR_API_WIND_BEARING: { key=ATTR_API_TEMPERATURE,
SENSOR_NAME: "Wind bearing", name="Temperature",
SENSOR_UNIT: DEGREE, native_unit_of_measurement=TEMP_CELSIUS,
}, device_class=DEVICE_CLASS_TEMPERATURE,
ATTR_API_WIND_MAX_SPEED: { ),
SENSOR_NAME: "Wind max speed", SensorEntityDescription(
SENSOR_UNIT: SPEED_KILOMETERS_PER_HOUR, key=ATTR_API_TEMPERATURE_FEELING,
}, name="Temperature feeling",
ATTR_API_WIND_SPEED: { native_unit_of_measurement=TEMP_CELSIUS,
SENSOR_NAME: "Wind speed", device_class=DEVICE_CLASS_TEMPERATURE,
SENSOR_UNIT: SPEED_KILOMETERS_PER_HOUR, ),
}, SensorEntityDescription(
} key=ATTR_API_TOWN_ID,
name="Town ID",
),
SensorEntityDescription(
key=ATTR_API_TOWN_NAME,
name="Town name",
),
SensorEntityDescription(
key=ATTR_API_TOWN_TIMESTAMP,
name="Town timestamp",
device_class=DEVICE_CLASS_TIMESTAMP,
),
SensorEntityDescription(
key=ATTR_API_WIND_BEARING,
name="Wind bearing",
native_unit_of_measurement=DEGREE,
),
SensorEntityDescription(
key=ATTR_API_WIND_MAX_SPEED,
name="Wind max speed",
native_unit_of_measurement=SPEED_KILOMETERS_PER_HOUR,
),
SensorEntityDescription(
key=ATTR_API_WIND_SPEED,
name="Wind speed",
native_unit_of_measurement=SPEED_KILOMETERS_PER_HOUR,
),
)
WIND_BEARING_MAP = { WIND_BEARING_MAP = {
"C": None, "C": None,

View File

@ -1,5 +1,7 @@
"""Support for the AEMET OpenData service.""" """Support for the AEMET OpenData service."""
from homeassistant.components.sensor import SensorEntity from __future__ import annotations
from homeassistant.components.sensor import SensorEntity, SensorEntityDescription
from homeassistant.const import ATTR_ATTRIBUTION from homeassistant.const import ATTR_ATTRIBUTION
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
@ -14,9 +16,6 @@ from .const import (
FORECAST_MONITORED_CONDITIONS, FORECAST_MONITORED_CONDITIONS,
FORECAST_SENSOR_TYPES, FORECAST_SENSOR_TYPES,
MONITORED_CONDITIONS, MONITORED_CONDITIONS,
SENSOR_DEVICE_CLASS,
SENSOR_NAME,
SENSOR_UNIT,
WEATHER_SENSOR_TYPES, WEATHER_SENSOR_TYPES,
) )
from .weather_update_coordinator import WeatherUpdateCoordinator from .weather_update_coordinator import WeatherUpdateCoordinator
@ -28,36 +27,29 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
name = domain_data[ENTRY_NAME] name = domain_data[ENTRY_NAME]
weather_coordinator = domain_data[ENTRY_WEATHER_COORDINATOR] weather_coordinator = domain_data[ENTRY_WEATHER_COORDINATOR]
weather_sensor_types = WEATHER_SENSOR_TYPES unique_id = config_entry.unique_id
forecast_sensor_types = FORECAST_SENSOR_TYPES entities: list[AbstractAemetSensor] = [
AemetSensor(name, unique_id, weather_coordinator, description)
entities = [] for description in WEATHER_SENSOR_TYPES
for sensor_type in MONITORED_CONDITIONS: if description.key in MONITORED_CONDITIONS
unique_id = f"{config_entry.unique_id}-{sensor_type}" ]
entities.append( entities.extend(
AemetSensor( [
name,
unique_id,
sensor_type,
weather_sensor_types[sensor_type],
weather_coordinator,
)
)
for mode in FORECAST_MODES:
name = f"{domain_data[ENTRY_NAME]} {mode}"
for sensor_type in FORECAST_MONITORED_CONDITIONS:
unique_id = f"{config_entry.unique_id}-forecast-{mode}-{sensor_type}"
entities.append(
AemetForecastSensor( AemetForecastSensor(
f"{name} Forecast", name_prefix,
unique_id, unique_id_prefix,
sensor_type,
forecast_sensor_types[sensor_type],
weather_coordinator, weather_coordinator,
mode, mode,
description,
) )
for mode in FORECAST_MODES
if (
(name_prefix := f"{domain_data[ENTRY_NAME]} {mode} Forecast")
and (unique_id_prefix := f"{unique_id}-forecast-{mode}")
)
for description in FORECAST_SENSOR_TYPES
if description.key in FORECAST_MONITORED_CONDITIONS
]
) )
async_add_entities(entities) async_add_entities(entities)
@ -72,20 +64,14 @@ class AbstractAemetSensor(CoordinatorEntity, SensorEntity):
self, self,
name, name,
unique_id, unique_id,
sensor_type,
sensor_configuration,
coordinator: WeatherUpdateCoordinator, coordinator: WeatherUpdateCoordinator,
description: SensorEntityDescription,
): ):
"""Initialize the sensor.""" """Initialize the sensor."""
super().__init__(coordinator) super().__init__(coordinator)
self._name = name self.entity_description = description
self._unique_id = unique_id self._attr_name = f"{name} {description.name}"
self._sensor_type = sensor_type self._attr_unique_id = unique_id
self._sensor_name = sensor_configuration[SENSOR_NAME]
self._attr_name = f"{self._name} {self._sensor_name}"
self._attr_unique_id = self._unique_id
self._attr_device_class = sensor_configuration.get(SENSOR_DEVICE_CLASS)
self._attr_native_unit_of_measurement = sensor_configuration.get(SENSOR_UNIT)
class AemetSensor(AbstractAemetSensor): class AemetSensor(AbstractAemetSensor):
@ -95,20 +81,21 @@ class AemetSensor(AbstractAemetSensor):
self, self,
name, name,
unique_id, unique_id,
sensor_type,
sensor_configuration,
weather_coordinator: WeatherUpdateCoordinator, weather_coordinator: WeatherUpdateCoordinator,
description: SensorEntityDescription,
): ):
"""Initialize the sensor.""" """Initialize the sensor."""
super().__init__( super().__init__(
name, unique_id, sensor_type, sensor_configuration, weather_coordinator name=name,
unique_id=f"{unique_id}-{description.key}",
coordinator=weather_coordinator,
description=description,
) )
self._weather_coordinator = weather_coordinator
@property @property
def native_value(self): def native_value(self):
"""Return the state of the device.""" """Return the state of the device."""
return self._weather_coordinator.data.get(self._sensor_type) return self.coordinator.data.get(self.entity_description.key)
class AemetForecastSensor(AbstractAemetSensor): class AemetForecastSensor(AbstractAemetSensor):
@ -118,16 +105,17 @@ class AemetForecastSensor(AbstractAemetSensor):
self, self,
name, name,
unique_id, unique_id,
sensor_type,
sensor_configuration,
weather_coordinator: WeatherUpdateCoordinator, weather_coordinator: WeatherUpdateCoordinator,
forecast_mode, forecast_mode,
description: SensorEntityDescription,
): ):
"""Initialize the sensor.""" """Initialize the sensor."""
super().__init__( super().__init__(
name, unique_id, sensor_type, sensor_configuration, weather_coordinator name=name,
unique_id=f"{unique_id}-{description.key}",
coordinator=weather_coordinator,
description=description,
) )
self._weather_coordinator = weather_coordinator
self._forecast_mode = forecast_mode self._forecast_mode = forecast_mode
self._attr_entity_registry_enabled_default = ( self._attr_entity_registry_enabled_default = (
self._forecast_mode == FORECAST_MODE_DAILY self._forecast_mode == FORECAST_MODE_DAILY
@ -137,9 +125,9 @@ class AemetForecastSensor(AbstractAemetSensor):
def native_value(self): def native_value(self):
"""Return the state of the device.""" """Return the state of the device."""
forecast = None forecast = None
forecasts = self._weather_coordinator.data.get( forecasts = self.coordinator.data.get(
FORECAST_MODE_ATTR_API[self._forecast_mode] FORECAST_MODE_ATTR_API[self._forecast_mode]
) )
if forecasts: if forecasts:
forecast = forecasts[0].get(self._sensor_type) forecast = forecasts[0].get(self.entity_description.key)
return forecast return forecast