mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 08:47:57 +00:00
Rework Accuweather sensors (#76567)
This commit is contained in:
parent
2b9116f1f8
commit
9c6780f76a
@ -81,7 +81,6 @@ class AccuWeatherDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
"""Initialize."""
|
||||
self.location_key = location_key
|
||||
self.forecast = forecast
|
||||
self.is_metric = hass.config.units.is_metric
|
||||
self.accuweather = AccuWeather(api_key, session, location_key=location_key)
|
||||
self.device_info = DeviceInfo(
|
||||
entry_type=DeviceEntryType.SERVICE,
|
||||
@ -116,7 +115,9 @@ class AccuWeatherDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
async with timeout(10):
|
||||
current = await self.accuweather.async_get_current_conditions()
|
||||
forecast = (
|
||||
await self.accuweather.async_get_forecast(metric=self.is_metric)
|
||||
await self.accuweather.async_get_forecast(
|
||||
metric=self.hass.config.units.is_metric
|
||||
)
|
||||
if self.forecast
|
||||
else {}
|
||||
)
|
||||
|
@ -23,7 +23,13 @@ from homeassistant.components.weather import (
|
||||
API_IMPERIAL: Final = "Imperial"
|
||||
API_METRIC: Final = "Metric"
|
||||
ATTRIBUTION: Final = "Data provided by AccuWeather"
|
||||
ATTR_CATEGORY: Final = "Category"
|
||||
ATTR_DIRECTION: Final = "Direction"
|
||||
ATTR_ENGLISH: Final = "English"
|
||||
ATTR_LEVEL: Final = "level"
|
||||
ATTR_FORECAST: Final = "forecast"
|
||||
ATTR_SPEED: Final = "Speed"
|
||||
ATTR_VALUE: Final = "Value"
|
||||
CONF_FORECAST: Final = "forecast"
|
||||
DOMAIN: Final = "accuweather"
|
||||
MANUFACTURER: Final = "AccuWeather, Inc."
|
||||
|
@ -1,6 +1,7 @@
|
||||
"""Support for the AccuWeather service."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, cast
|
||||
|
||||
@ -34,7 +35,13 @@ from . import AccuWeatherDataUpdateCoordinator
|
||||
from .const import (
|
||||
API_IMPERIAL,
|
||||
API_METRIC,
|
||||
ATTR_CATEGORY,
|
||||
ATTR_DIRECTION,
|
||||
ATTR_ENGLISH,
|
||||
ATTR_FORECAST,
|
||||
ATTR_LEVEL,
|
||||
ATTR_SPEED,
|
||||
ATTR_VALUE,
|
||||
ATTRIBUTION,
|
||||
DOMAIN,
|
||||
MAX_FORECAST_DAYS,
|
||||
@ -44,11 +51,20 @@ PARALLEL_UPDATES = 1
|
||||
|
||||
|
||||
@dataclass
|
||||
class AccuWeatherSensorDescription(SensorEntityDescription):
|
||||
class AccuWeatherSensorDescriptionMixin:
|
||||
"""Mixin for AccuWeather sensor."""
|
||||
|
||||
value_fn: Callable[[dict[str, Any], str], StateType]
|
||||
|
||||
|
||||
@dataclass
|
||||
class AccuWeatherSensorDescription(
|
||||
SensorEntityDescription, AccuWeatherSensorDescriptionMixin
|
||||
):
|
||||
"""Class describing AccuWeather sensor entities."""
|
||||
|
||||
unit_metric: str | None = None
|
||||
unit_imperial: str | None = None
|
||||
attr_fn: Callable[[dict[str, Any]], dict[str, StateType]] = lambda _: {}
|
||||
unit_fn: Callable[[bool], str | None] = lambda _: None
|
||||
|
||||
|
||||
FORECAST_SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
|
||||
@ -56,145 +72,162 @@ FORECAST_SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
|
||||
key="CloudCoverDay",
|
||||
icon="mdi:weather-cloudy",
|
||||
name="Cloud cover day",
|
||||
unit_metric=PERCENTAGE,
|
||||
unit_imperial=PERCENTAGE,
|
||||
entity_registry_enabled_default=False,
|
||||
unit_fn=lambda _: PERCENTAGE,
|
||||
value_fn=lambda data, _: cast(int, data),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="CloudCoverNight",
|
||||
icon="mdi:weather-cloudy",
|
||||
name="Cloud cover night",
|
||||
unit_metric=PERCENTAGE,
|
||||
unit_imperial=PERCENTAGE,
|
||||
entity_registry_enabled_default=False,
|
||||
unit_fn=lambda _: PERCENTAGE,
|
||||
value_fn=lambda data, _: cast(int, data),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Grass",
|
||||
icon="mdi:grass",
|
||||
name="Grass pollen",
|
||||
unit_metric=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
unit_imperial=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
unit_fn=lambda _: CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
value_fn=lambda data, _: cast(int, data[ATTR_VALUE]),
|
||||
attr_fn=lambda data: {ATTR_LEVEL: data[ATTR_CATEGORY]},
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="HoursOfSun",
|
||||
icon="mdi:weather-partly-cloudy",
|
||||
name="Hours of sun",
|
||||
unit_metric=TIME_HOURS,
|
||||
unit_imperial=TIME_HOURS,
|
||||
unit_fn=lambda _: TIME_HOURS,
|
||||
value_fn=lambda data, _: cast(float, data),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Mold",
|
||||
icon="mdi:blur",
|
||||
name="Mold pollen",
|
||||
unit_metric=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
unit_imperial=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
unit_fn=lambda _: CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
value_fn=lambda data, _: cast(int, data[ATTR_VALUE]),
|
||||
attr_fn=lambda data: {ATTR_LEVEL: data[ATTR_CATEGORY]},
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Ozone",
|
||||
icon="mdi:vector-triangle",
|
||||
name="Ozone",
|
||||
unit_metric=None,
|
||||
unit_imperial=None,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data, _: cast(int, data[ATTR_VALUE]),
|
||||
attr_fn=lambda data: {ATTR_LEVEL: data[ATTR_CATEGORY]},
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Ragweed",
|
||||
icon="mdi:sprout",
|
||||
name="Ragweed pollen",
|
||||
unit_metric=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
unit_imperial=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
unit_fn=lambda _: 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]},
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="RealFeelTemperatureMax",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="RealFeel temperature max",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
|
||||
value_fn=lambda data, _: cast(float, data[ATTR_VALUE]),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="RealFeelTemperatureMin",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="RealFeel temperature min",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
|
||||
value_fn=lambda data, _: cast(float, data[ATTR_VALUE]),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="RealFeelTemperatureShadeMax",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="RealFeel temperature shade max",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
entity_registry_enabled_default=False,
|
||||
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
|
||||
value_fn=lambda data, _: cast(float, data[ATTR_VALUE]),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="RealFeelTemperatureShadeMin",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="RealFeel temperature shade min",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
entity_registry_enabled_default=False,
|
||||
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
|
||||
value_fn=lambda data, _: cast(float, data[ATTR_VALUE]),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="ThunderstormProbabilityDay",
|
||||
icon="mdi:weather-lightning",
|
||||
name="Thunderstorm probability day",
|
||||
unit_metric=PERCENTAGE,
|
||||
unit_imperial=PERCENTAGE,
|
||||
unit_fn=lambda _: PERCENTAGE,
|
||||
value_fn=lambda data, _: cast(int, data),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="ThunderstormProbabilityNight",
|
||||
icon="mdi:weather-lightning",
|
||||
name="Thunderstorm probability night",
|
||||
unit_metric=PERCENTAGE,
|
||||
unit_imperial=PERCENTAGE,
|
||||
unit_fn=lambda _: PERCENTAGE,
|
||||
value_fn=lambda data, _: cast(int, data),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Tree",
|
||||
icon="mdi:tree-outline",
|
||||
name="Tree pollen",
|
||||
unit_metric=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
unit_imperial=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
unit_fn=lambda _: 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]},
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="UVIndex",
|
||||
icon="mdi:weather-sunny",
|
||||
name="UV index",
|
||||
unit_metric=UV_INDEX,
|
||||
unit_imperial=UV_INDEX,
|
||||
unit_fn=lambda _: UV_INDEX,
|
||||
value_fn=lambda data, _: cast(int, data[ATTR_VALUE]),
|
||||
attr_fn=lambda data: {ATTR_LEVEL: data[ATTR_CATEGORY]},
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="WindGustDay",
|
||||
icon="mdi:weather-windy",
|
||||
name="Wind gust day",
|
||||
unit_metric=SPEED_KILOMETERS_PER_HOUR,
|
||||
unit_imperial=SPEED_MILES_PER_HOUR,
|
||||
entity_registry_enabled_default=False,
|
||||
unit_fn=lambda metric: SPEED_KILOMETERS_PER_HOUR
|
||||
if metric
|
||||
else SPEED_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",
|
||||
icon="mdi:weather-windy",
|
||||
name="Wind gust night",
|
||||
unit_metric=SPEED_KILOMETERS_PER_HOUR,
|
||||
unit_imperial=SPEED_MILES_PER_HOUR,
|
||||
entity_registry_enabled_default=False,
|
||||
unit_fn=lambda metric: SPEED_KILOMETERS_PER_HOUR
|
||||
if metric
|
||||
else SPEED_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",
|
||||
icon="mdi:weather-windy",
|
||||
name="Wind day",
|
||||
unit_metric=SPEED_KILOMETERS_PER_HOUR,
|
||||
unit_imperial=SPEED_MILES_PER_HOUR,
|
||||
unit_fn=lambda metric: SPEED_KILOMETERS_PER_HOUR
|
||||
if metric
|
||||
else SPEED_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",
|
||||
icon="mdi:weather-windy",
|
||||
name="Wind night",
|
||||
unit_metric=SPEED_KILOMETERS_PER_HOUR,
|
||||
unit_imperial=SPEED_MILES_PER_HOUR,
|
||||
unit_fn=lambda metric: SPEED_KILOMETERS_PER_HOUR
|
||||
if metric
|
||||
else SPEED_MILES_PER_HOUR,
|
||||
value_fn=lambda data, _: cast(float, data[ATTR_SPEED][ATTR_VALUE]),
|
||||
attr_fn=lambda data: {"direction": data[ATTR_DIRECTION][ATTR_ENGLISH]},
|
||||
),
|
||||
)
|
||||
|
||||
@ -203,112 +236,117 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
|
||||
key="ApparentTemperature",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="Apparent temperature",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
|
||||
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Ceiling",
|
||||
icon="mdi:weather-fog",
|
||||
name="Cloud ceiling",
|
||||
unit_metric=LENGTH_METERS,
|
||||
unit_imperial=LENGTH_FEET,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
unit_fn=lambda metric: LENGTH_METERS if metric else LENGTH_FEET,
|
||||
value_fn=lambda data, unit: round(data[unit][ATTR_VALUE]),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="CloudCover",
|
||||
icon="mdi:weather-cloudy",
|
||||
name="Cloud cover",
|
||||
unit_metric=PERCENTAGE,
|
||||
unit_imperial=PERCENTAGE,
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
unit_fn=lambda _: PERCENTAGE,
|
||||
value_fn=lambda data, _: cast(int, data),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="DewPoint",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="Dew point",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
|
||||
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="RealFeelTemperature",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="RealFeel temperature",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
|
||||
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="RealFeelTemperatureShade",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="RealFeel temperature shade",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
|
||||
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Precipitation",
|
||||
icon="mdi:weather-rainy",
|
||||
name="Precipitation",
|
||||
unit_metric=LENGTH_MILLIMETERS,
|
||||
unit_imperial=LENGTH_INCHES,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
unit_fn=lambda metric: LENGTH_MILLIMETERS if metric else LENGTH_INCHES,
|
||||
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
|
||||
attr_fn=lambda data: {"type": data["PrecipitationType"]},
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="PressureTendency",
|
||||
device_class="accuweather__pressure_tendency",
|
||||
icon="mdi:gauge",
|
||||
name="Pressure tendency",
|
||||
unit_metric=None,
|
||||
unit_imperial=None,
|
||||
value_fn=lambda data, _: cast(str, data["LocalizedText"]).lower(),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="UVIndex",
|
||||
icon="mdi:weather-sunny",
|
||||
name="UV index",
|
||||
unit_metric=UV_INDEX,
|
||||
unit_imperial=UV_INDEX,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
unit_fn=lambda _: UV_INDEX,
|
||||
value_fn=lambda data, _: cast(int, data),
|
||||
attr_fn=lambda data: {ATTR_LEVEL: data["UVIndexText"]},
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="WetBulbTemperature",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="Wet bulb temperature",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
|
||||
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="WindChillTemperature",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="Wind chill temperature",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
unit_fn=lambda metric: TEMP_CELSIUS if metric else TEMP_FAHRENHEIT,
|
||||
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Wind",
|
||||
icon="mdi:weather-windy",
|
||||
name="Wind",
|
||||
unit_metric=SPEED_KILOMETERS_PER_HOUR,
|
||||
unit_imperial=SPEED_MILES_PER_HOUR,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
unit_fn=lambda metric: SPEED_KILOMETERS_PER_HOUR
|
||||
if metric
|
||||
else SPEED_MILES_PER_HOUR,
|
||||
value_fn=lambda data, unit: cast(float, data[ATTR_SPEED][unit][ATTR_VALUE]),
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="WindGust",
|
||||
icon="mdi:weather-windy",
|
||||
name="Wind gust",
|
||||
unit_metric=SPEED_KILOMETERS_PER_HOUR,
|
||||
unit_imperial=SPEED_MILES_PER_HOUR,
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
unit_fn=lambda metric: SPEED_KILOMETERS_PER_HOUR
|
||||
if metric
|
||||
else SPEED_MILES_PER_HOUR,
|
||||
value_fn=lambda data, unit: cast(float, data[ATTR_SPEED][unit][ATTR_VALUE]),
|
||||
),
|
||||
)
|
||||
|
||||
@ -328,9 +366,9 @@ async def async_setup_entry(
|
||||
# Some air quality/allergy sensors are only available for certain
|
||||
# locations.
|
||||
sensors.extend(
|
||||
AccuWeatherSensor(coordinator, description, forecast_day=day)
|
||||
for description in FORECAST_SENSOR_TYPES
|
||||
AccuWeatherForecastSensor(coordinator, description, forecast_day=day)
|
||||
for day in range(MAX_FORECAST_DAYS + 1)
|
||||
for description in FORECAST_SENSOR_TYPES
|
||||
if description.key in coordinator.data[ATTR_FORECAST][0]
|
||||
)
|
||||
|
||||
@ -356,9 +394,8 @@ class AccuWeatherSensor(
|
||||
super().__init__(coordinator)
|
||||
self.entity_description = description
|
||||
self._sensor_data = _get_sensor_data(
|
||||
coordinator.data, forecast_day, description.key
|
||||
coordinator.data, description.key, forecast_day
|
||||
)
|
||||
self._attrs: dict[str, Any] = {}
|
||||
if forecast_day is not None:
|
||||
self._attr_name = f"{description.name} {forecast_day}d"
|
||||
self._attr_unique_id = (
|
||||
@ -368,82 +405,40 @@ class AccuWeatherSensor(
|
||||
self._attr_unique_id = (
|
||||
f"{coordinator.location_key}-{description.key}".lower()
|
||||
)
|
||||
if coordinator.is_metric:
|
||||
if self.coordinator.hass.config.units.is_metric:
|
||||
self._unit_system = API_METRIC
|
||||
self._attr_native_unit_of_measurement = description.unit_metric
|
||||
else:
|
||||
self._unit_system = API_IMPERIAL
|
||||
self._attr_native_unit_of_measurement = description.unit_imperial
|
||||
self._attr_native_unit_of_measurement = self.entity_description.unit_fn(
|
||||
self.coordinator.hass.config.units.is_metric
|
||||
)
|
||||
self._attr_device_info = coordinator.device_info
|
||||
self.forecast_day = forecast_day
|
||||
if forecast_day is not None:
|
||||
self.forecast_day = forecast_day
|
||||
|
||||
@property
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state."""
|
||||
if self.forecast_day is not None:
|
||||
if self.entity_description.device_class == SensorDeviceClass.TEMPERATURE:
|
||||
return cast(float, self._sensor_data["Value"])
|
||||
if self.entity_description.key == "UVIndex":
|
||||
return cast(int, self._sensor_data["Value"])
|
||||
if self.entity_description.key in ("Grass", "Mold", "Ragweed", "Tree", "Ozone"):
|
||||
return cast(int, self._sensor_data["Value"])
|
||||
if self.entity_description.key == "Ceiling":
|
||||
return round(self._sensor_data[self._unit_system]["Value"])
|
||||
if self.entity_description.key == "PressureTendency":
|
||||
return cast(str, self._sensor_data["LocalizedText"].lower())
|
||||
if self.entity_description.device_class == SensorDeviceClass.TEMPERATURE:
|
||||
return cast(float, self._sensor_data[self._unit_system]["Value"])
|
||||
if self.entity_description.key == "Precipitation":
|
||||
return cast(float, self._sensor_data[self._unit_system]["Value"])
|
||||
if self.entity_description.key in ("Wind", "WindGust"):
|
||||
return cast(float, self._sensor_data["Speed"][self._unit_system]["Value"])
|
||||
if self.entity_description.key in (
|
||||
"WindDay",
|
||||
"WindNight",
|
||||
"WindGustDay",
|
||||
"WindGustNight",
|
||||
):
|
||||
return cast(StateType, self._sensor_data["Speed"]["Value"])
|
||||
return cast(StateType, self._sensor_data)
|
||||
return self.entity_description.value_fn(self._sensor_data, self._unit_system)
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return the state attributes."""
|
||||
if self.forecast_day is not None:
|
||||
if self.entity_description.key in (
|
||||
"WindDay",
|
||||
"WindNight",
|
||||
"WindGustDay",
|
||||
"WindGustNight",
|
||||
):
|
||||
self._attrs["direction"] = self._sensor_data["Direction"]["English"]
|
||||
elif self.entity_description.key in (
|
||||
"Grass",
|
||||
"Mold",
|
||||
"Ozone",
|
||||
"Ragweed",
|
||||
"Tree",
|
||||
"UVIndex",
|
||||
):
|
||||
self._attrs["level"] = self._sensor_data["Category"]
|
||||
return self._attrs
|
||||
if self.entity_description.key == "UVIndex":
|
||||
self._attrs["level"] = self.coordinator.data["UVIndexText"]
|
||||
elif self.entity_description.key == "Precipitation":
|
||||
self._attrs["type"] = self.coordinator.data["PrecipitationType"]
|
||||
return self._attrs
|
||||
return self.entity_description.attr_fn(self.coordinator.data)
|
||||
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle data update."""
|
||||
self._sensor_data = _get_sensor_data(
|
||||
self.coordinator.data, self.forecast_day, self.entity_description.key
|
||||
self.coordinator.data, self.entity_description.key
|
||||
)
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
||||
def _get_sensor_data(
|
||||
sensors: dict[str, Any], forecast_day: int | None, kind: str
|
||||
sensors: dict[str, Any],
|
||||
kind: str,
|
||||
forecast_day: int | None = None,
|
||||
) -> Any:
|
||||
"""Get sensor data."""
|
||||
if forecast_day is not None:
|
||||
@ -453,3 +448,20 @@ def _get_sensor_data(
|
||||
return sensors["PrecipitationSummary"][kind]
|
||||
|
||||
return sensors[kind]
|
||||
|
||||
|
||||
class AccuWeatherForecastSensor(AccuWeatherSensor):
|
||||
"""Define an AccuWeather forecast entity."""
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return the state attributes."""
|
||||
return self.entity_description.attr_fn(self._sensor_data)
|
||||
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle data update."""
|
||||
self._sensor_data = _get_sensor_data(
|
||||
self.coordinator.data, self.entity_description.key, self.forecast_day
|
||||
)
|
||||
self.async_write_ha_state()
|
||||
|
@ -70,7 +70,7 @@ class AccuWeatherEntity(
|
||||
# Coordinator data is used also for sensors which don't have units automatically
|
||||
# converted, hence the weather entity's native units follow the configured unit
|
||||
# system
|
||||
if coordinator.is_metric:
|
||||
if coordinator.hass.config.units.is_metric:
|
||||
self._attr_native_precipitation_unit = LENGTH_MILLIMETERS
|
||||
self._attr_native_pressure_unit = PRESSURE_HPA
|
||||
self._attr_native_temperature_unit = TEMP_CELSIUS
|
||||
|
Loading…
x
Reference in New Issue
Block a user