Use new device class in accuweather (#83318)

pull/83393/head
epenet 2022-12-06 11:54:59 +01:00 committed by GitHub
parent 10db0d8bb1
commit 72fd57a685
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 68 deletions

View File

@ -14,17 +14,13 @@ from homeassistant.components.sensor import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONCENTRATION_PARTS_PER_CUBIC_METER,
LENGTH_FEET,
LENGTH_INCHES,
LENGTH_METERS,
LENGTH_MILLIMETERS,
PERCENTAGE,
SPEED_KILOMETERS_PER_HOUR,
SPEED_MILES_PER_HOUR,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
TIME_HOURS,
UV_INDEX,
UnitOfLength,
UnitOfPrecipitationDepth,
UnitOfSpeed,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -65,7 +61,8 @@ class AccuWeatherSensorDescription(
"""Class describing AccuWeather sensor entities."""
attr_fn: Callable[[dict[str, Any]], dict[str, StateType]] = lambda _: {}
unit_fn: Callable[[bool], str | None] = lambda _: None
metric_unit: str | None = None
us_customary_unit: str | None = None
FORECAST_SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
@ -74,7 +71,7 @@ FORECAST_SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
icon="mdi:weather-cloudy",
name="Cloud cover day",
entity_registry_enabled_default=False,
unit_fn=lambda _: PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
value_fn=lambda data, _: cast(int, data),
),
AccuWeatherSensorDescription(
@ -82,7 +79,7 @@ FORECAST_SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
icon="mdi:weather-cloudy",
name="Cloud cover night",
entity_registry_enabled_default=False,
unit_fn=lambda _: PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
value_fn=lambda data, _: cast(int, data),
),
AccuWeatherSensorDescription(
@ -90,7 +87,7 @@ FORECAST_SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
icon="mdi:grass",
name="Grass pollen",
entity_registry_enabled_default=False,
unit_fn=lambda _: CONCENTRATION_PARTS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
value_fn=lambda data, _: cast(int, data[ATTR_VALUE]),
attr_fn=lambda data: {ATTR_LEVEL: data[ATTR_CATEGORY]},
),
@ -98,7 +95,7 @@ FORECAST_SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
key="HoursOfSun",
icon="mdi:weather-partly-cloudy",
name="Hours of sun",
unit_fn=lambda _: TIME_HOURS,
native_unit_of_measurement=TIME_HOURS,
value_fn=lambda data, _: cast(float, data),
),
AccuWeatherSensorDescription(
@ -106,7 +103,7 @@ FORECAST_SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
icon="mdi:blur",
name="Mold pollen",
entity_registry_enabled_default=False,
unit_fn=lambda _: CONCENTRATION_PARTS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
value_fn=lambda data, _: cast(int, data[ATTR_VALUE]),
attr_fn=lambda data: {ATTR_LEVEL: data[ATTR_CATEGORY]},
),
@ -122,7 +119,7 @@ FORECAST_SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
key="Ragweed",
icon="mdi:sprout",
name="Ragweed pollen",
unit_fn=lambda _: CONCENTRATION_PARTS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
entity_registry_enabled_default=False,
value_fn=lambda data, _: cast(int, data[ATTR_VALUE]),
attr_fn=lambda data: {ATTR_LEVEL: data[ATTR_CATEGORY]},
@ -131,14 +128,16 @@ FORECAST_SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
key="RealFeelTemperatureMax",
device_class=SensorDeviceClass.TEMPERATURE,
name="RealFeel temperature max",
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
metric_unit=UnitOfTemperature.CELSIUS,
us_customary_unit=UnitOfTemperature.FAHRENHEIT,
value_fn=lambda data, _: cast(float, data[ATTR_VALUE]),
),
AccuWeatherSensorDescription(
key="RealFeelTemperatureMin",
device_class=SensorDeviceClass.TEMPERATURE,
name="RealFeel temperature min",
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
metric_unit=UnitOfTemperature.CELSIUS,
us_customary_unit=UnitOfTemperature.FAHRENHEIT,
value_fn=lambda data, _: cast(float, data[ATTR_VALUE]),
),
AccuWeatherSensorDescription(
@ -146,7 +145,8 @@ FORECAST_SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
device_class=SensorDeviceClass.TEMPERATURE,
name="RealFeel temperature shade max",
entity_registry_enabled_default=False,
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
metric_unit=UnitOfTemperature.CELSIUS,
us_customary_unit=UnitOfTemperature.FAHRENHEIT,
value_fn=lambda data, _: cast(float, data[ATTR_VALUE]),
),
AccuWeatherSensorDescription(
@ -154,28 +154,29 @@ FORECAST_SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
device_class=SensorDeviceClass.TEMPERATURE,
name="RealFeel temperature shade min",
entity_registry_enabled_default=False,
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
metric_unit=UnitOfTemperature.CELSIUS,
us_customary_unit=UnitOfTemperature.FAHRENHEIT,
value_fn=lambda data, _: cast(float, data[ATTR_VALUE]),
),
AccuWeatherSensorDescription(
key="ThunderstormProbabilityDay",
icon="mdi:weather-lightning",
name="Thunderstorm probability day",
unit_fn=lambda _: PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
value_fn=lambda data, _: cast(int, data),
),
AccuWeatherSensorDescription(
key="ThunderstormProbabilityNight",
icon="mdi:weather-lightning",
name="Thunderstorm probability night",
unit_fn=lambda _: PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
value_fn=lambda data, _: cast(int, data),
),
AccuWeatherSensorDescription(
key="Tree",
icon="mdi:tree-outline",
name="Tree pollen",
unit_fn=lambda _: CONCENTRATION_PARTS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
entity_registry_enabled_default=False,
value_fn=lambda data, _: cast(int, data[ATTR_VALUE]),
attr_fn=lambda data: {ATTR_LEVEL: data[ATTR_CATEGORY]},
@ -184,53 +185,45 @@ FORECAST_SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
key="UVIndex",
icon="mdi:weather-sunny",
name="UV index",
unit_fn=lambda _: UV_INDEX,
native_unit_of_measurement=UV_INDEX,
value_fn=lambda data, _: cast(int, data[ATTR_VALUE]),
attr_fn=lambda data: {ATTR_LEVEL: data[ATTR_CATEGORY]},
),
AccuWeatherSensorDescription(
key="WindGustDay",
device_class=SensorDeviceClass.WIND_SPEED,
icon="mdi:weather-windy",
name="Wind gust day",
entity_registry_enabled_default=False,
unit_fn=lambda metric: SPEED_KILOMETERS_PER_HOUR
if metric
else SPEED_MILES_PER_HOUR,
metric_unit=UnitOfSpeed.KILOMETERS_PER_HOUR,
us_customary_unit=UnitOfSpeed.MILES_PER_HOUR,
value_fn=lambda data, _: cast(float, data[ATTR_SPEED][ATTR_VALUE]),
attr_fn=lambda data: {"direction": data[ATTR_DIRECTION][ATTR_ENGLISH]},
),
AccuWeatherSensorDescription(
key="WindGustNight",
device_class=SensorDeviceClass.WIND_SPEED,
icon="mdi:weather-windy",
name="Wind gust night",
entity_registry_enabled_default=False,
unit_fn=lambda metric: SPEED_KILOMETERS_PER_HOUR
if metric
else SPEED_MILES_PER_HOUR,
metric_unit=UnitOfSpeed.KILOMETERS_PER_HOUR,
us_customary_unit=UnitOfSpeed.MILES_PER_HOUR,
value_fn=lambda data, _: cast(float, data[ATTR_SPEED][ATTR_VALUE]),
attr_fn=lambda data: {"direction": data[ATTR_DIRECTION][ATTR_ENGLISH]},
),
AccuWeatherSensorDescription(
key="WindDay",
device_class=SensorDeviceClass.WIND_SPEED,
icon="mdi:weather-windy",
name="Wind day",
unit_fn=lambda metric: SPEED_KILOMETERS_PER_HOUR
if metric
else SPEED_MILES_PER_HOUR,
metric_unit=UnitOfSpeed.KILOMETERS_PER_HOUR,
us_customary_unit=UnitOfSpeed.MILES_PER_HOUR,
value_fn=lambda data, _: cast(float, data[ATTR_SPEED][ATTR_VALUE]),
attr_fn=lambda data: {"direction": data[ATTR_DIRECTION][ATTR_ENGLISH]},
),
AccuWeatherSensorDescription(
key="WindNight",
device_class=SensorDeviceClass.WIND_SPEED,
icon="mdi:weather-windy",
name="Wind night",
unit_fn=lambda metric: SPEED_KILOMETERS_PER_HOUR
if metric
else SPEED_MILES_PER_HOUR,
metric_unit=UnitOfSpeed.KILOMETERS_PER_HOUR,
us_customary_unit=UnitOfSpeed.MILES_PER_HOUR,
value_fn=lambda data, _: cast(float, data[ATTR_SPEED][ATTR_VALUE]),
attr_fn=lambda data: {"direction": data[ATTR_DIRECTION][ATTR_ENGLISH]},
),
@ -243,7 +236,8 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
name="Apparent temperature",
entity_registry_enabled_default=False,
state_class=SensorStateClass.MEASUREMENT,
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
metric_unit=UnitOfTemperature.CELSIUS,
us_customary_unit=UnitOfTemperature.FAHRENHEIT,
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
),
AccuWeatherSensorDescription(
@ -252,7 +246,8 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
icon="mdi:weather-fog",
name="Cloud ceiling",
state_class=SensorStateClass.MEASUREMENT,
unit_fn=lambda metric: LENGTH_METERS if metric else LENGTH_FEET,
metric_unit=UnitOfLength.METERS,
us_customary_unit=UnitOfLength.FEET,
value_fn=lambda data, unit: round(cast(float, data[unit][ATTR_VALUE])),
),
AccuWeatherSensorDescription(
@ -261,7 +256,7 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
name="Cloud cover",
entity_registry_enabled_default=False,
state_class=SensorStateClass.MEASUREMENT,
unit_fn=lambda _: PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
value_fn=lambda data, _: cast(int, data),
),
AccuWeatherSensorDescription(
@ -270,7 +265,8 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
name="Dew point",
entity_registry_enabled_default=False,
state_class=SensorStateClass.MEASUREMENT,
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
metric_unit=UnitOfTemperature.CELSIUS,
us_customary_unit=UnitOfTemperature.FAHRENHEIT,
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
),
AccuWeatherSensorDescription(
@ -278,7 +274,8 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
device_class=SensorDeviceClass.TEMPERATURE,
name="RealFeel temperature",
state_class=SensorStateClass.MEASUREMENT,
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
metric_unit=UnitOfTemperature.CELSIUS,
us_customary_unit=UnitOfTemperature.FAHRENHEIT,
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
),
AccuWeatherSensorDescription(
@ -287,15 +284,17 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
name="RealFeel temperature shade",
entity_registry_enabled_default=False,
state_class=SensorStateClass.MEASUREMENT,
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
metric_unit=UnitOfTemperature.CELSIUS,
us_customary_unit=UnitOfTemperature.FAHRENHEIT,
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
),
AccuWeatherSensorDescription(
key="Precipitation",
icon="mdi:weather-rainy",
device_class=SensorDeviceClass.PRECIPITATION,
name="Precipitation",
state_class=SensorStateClass.MEASUREMENT,
unit_fn=lambda metric: LENGTH_MILLIMETERS if metric else LENGTH_INCHES,
metric_unit=UnitOfPrecipitationDepth.MILLIMETERS,
us_customary_unit=UnitOfPrecipitationDepth.INCHES,
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
attr_fn=lambda data: {"type": data["PrecipitationType"]},
),
@ -311,7 +310,7 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
icon="mdi:weather-sunny",
name="UV index",
state_class=SensorStateClass.MEASUREMENT,
unit_fn=lambda _: UV_INDEX,
native_unit_of_measurement=UV_INDEX,
value_fn=lambda data, _: cast(int, data),
attr_fn=lambda data: {ATTR_LEVEL: data["UVIndexText"]},
),
@ -321,7 +320,8 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
name="Wet bulb temperature",
entity_registry_enabled_default=False,
state_class=SensorStateClass.MEASUREMENT,
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
metric_unit=UnitOfTemperature.CELSIUS,
us_customary_unit=UnitOfTemperature.FAHRENHEIT,
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
),
AccuWeatherSensorDescription(
@ -330,30 +330,27 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
name="Wind chill temperature",
entity_registry_enabled_default=False,
state_class=SensorStateClass.MEASUREMENT,
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
metric_unit=UnitOfTemperature.CELSIUS,
us_customary_unit=UnitOfTemperature.FAHRENHEIT,
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
),
AccuWeatherSensorDescription(
key="Wind",
device_class=SensorDeviceClass.WIND_SPEED,
icon="mdi:weather-windy",
name="Wind",
state_class=SensorStateClass.MEASUREMENT,
unit_fn=lambda metric: SPEED_KILOMETERS_PER_HOUR
if metric
else SPEED_MILES_PER_HOUR,
metric_unit=UnitOfSpeed.KILOMETERS_PER_HOUR,
us_customary_unit=UnitOfSpeed.MILES_PER_HOUR,
value_fn=lambda data, unit: cast(float, data[ATTR_SPEED][unit][ATTR_VALUE]),
),
AccuWeatherSensorDescription(
key="WindGust",
device_class=SensorDeviceClass.WIND_SPEED,
icon="mdi:weather-windy",
name="Wind gust",
entity_registry_enabled_default=False,
state_class=SensorStateClass.MEASUREMENT,
unit_fn=lambda metric: SPEED_KILOMETERS_PER_HOUR
if metric
else SPEED_MILES_PER_HOUR,
metric_unit=UnitOfSpeed.KILOMETERS_PER_HOUR,
us_customary_unit=UnitOfSpeed.MILES_PER_HOUR,
value_fn=lambda data, unit: cast(float, data[ATTR_SPEED][unit][ATTR_VALUE]),
),
)
@ -413,13 +410,15 @@ class AccuWeatherSensor(
self._attr_unique_id = (
f"{coordinator.location_key}-{description.key}".lower()
)
self._attr_native_unit_of_measurement = description.native_unit_of_measurement
if self.coordinator.hass.config.units is METRIC_SYSTEM:
self._unit_system = API_METRIC
if metric_unit := description.metric_unit:
self._attr_native_unit_of_measurement = metric_unit
else:
self._unit_system = API_IMPERIAL
self._attr_native_unit_of_measurement = self.entity_description.unit_fn(
self.coordinator.hass.config.units is METRIC_SYSTEM
)
if us_customary_unit := description.us_customary_unit:
self._attr_native_unit_of_measurement = us_customary_unit
self._attr_device_info = coordinator.device_info
if forecast_day is not None:
self.forecast_day = forecast_day

View File

@ -60,9 +60,10 @@ async def test_sensor_without_forecast(hass):
assert state.state == "0.0"
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == LENGTH_MILLIMETERS
assert state.attributes.get(ATTR_ICON) == "mdi:weather-rainy"
assert state.attributes.get(ATTR_ICON) is None
assert state.attributes.get("type") is None
assert state.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.PRECIPITATION
entry = registry.async_get("sensor.home_precipitation")
assert entry
@ -435,7 +436,7 @@ async def test_sensor_enabled_without_forecast(hass):
assert state.state == "20.3"
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == SPEED_KILOMETERS_PER_HOUR
assert state.attributes.get(ATTR_ICON) == "mdi:weather-windy"
assert state.attributes.get(ATTR_ICON) is None
assert state.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.WIND_SPEED
@ -448,7 +449,7 @@ async def test_sensor_enabled_without_forecast(hass):
assert state.state == "14.5"
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == SPEED_KILOMETERS_PER_HOUR
assert state.attributes.get(ATTR_ICON) == "mdi:weather-windy"
assert state.attributes.get(ATTR_ICON) is None
assert state.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.WIND_SPEED
@ -582,7 +583,7 @@ async def test_sensor_enabled_without_forecast(hass):
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == SPEED_KILOMETERS_PER_HOUR
assert state.attributes.get("direction") == "SSE"
assert state.attributes.get(ATTR_ICON) == "mdi:weather-windy"
assert state.attributes.get(ATTR_ICON) is None
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.WIND_SPEED
entry = registry.async_get("sensor.home_wind_day_0d")
@ -595,7 +596,7 @@ async def test_sensor_enabled_without_forecast(hass):
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == SPEED_KILOMETERS_PER_HOUR
assert state.attributes.get("direction") == "WNW"
assert state.attributes.get(ATTR_ICON) == "mdi:weather-windy"
assert state.attributes.get(ATTR_ICON) is None
assert state.attributes.get(ATTR_STATE_CLASS) is None
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.WIND_SPEED
@ -609,7 +610,7 @@ async def test_sensor_enabled_without_forecast(hass):
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == SPEED_KILOMETERS_PER_HOUR
assert state.attributes.get("direction") == "S"
assert state.attributes.get(ATTR_ICON) == "mdi:weather-windy"
assert state.attributes.get(ATTR_ICON) is None
assert state.attributes.get(ATTR_STATE_CLASS) is None
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.WIND_SPEED
@ -623,7 +624,7 @@ async def test_sensor_enabled_without_forecast(hass):
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == SPEED_KILOMETERS_PER_HOUR
assert state.attributes.get("direction") == "WSW"
assert state.attributes.get(ATTR_ICON) == "mdi:weather-windy"
assert state.attributes.get(ATTR_ICON) is None
assert state.attributes.get(ATTR_STATE_CLASS) is None
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.WIND_SPEED