Migrate AccuWeather to new entity naming style (#75127)
* Use new entity naming style * Move AccuWeatherSensorDescription and SENSOR consts to sensor platform * Remove duplicate code * Suggested change * Format urlpull/75591/head
parent
f3c4bf571b
commit
05b463b282
|
@ -11,12 +11,14 @@ from aiohttp.client_exceptions import ClientConnectorError
|
|||
from async_timeout import timeout
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_API_KEY, Platform
|
||||
from homeassistant.const import CONF_API_KEY, CONF_NAME, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.device_registry import DeviceEntryType
|
||||
from homeassistant.helpers.entity import DeviceInfo
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
|
||||
from .const import ATTR_FORECAST, CONF_FORECAST, DOMAIN
|
||||
from .const import ATTR_FORECAST, CONF_FORECAST, DOMAIN, MANUFACTURER
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -26,6 +28,7 @@ PLATFORMS = [Platform.SENSOR, Platform.WEATHER]
|
|||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Set up AccuWeather as config entry."""
|
||||
api_key: str = entry.data[CONF_API_KEY]
|
||||
name: str = entry.data[CONF_NAME]
|
||||
assert entry.unique_id is not None
|
||||
location_key = entry.unique_id
|
||||
forecast: bool = entry.options.get(CONF_FORECAST, False)
|
||||
|
@ -35,7 +38,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
websession = async_get_clientsession(hass)
|
||||
|
||||
coordinator = AccuWeatherDataUpdateCoordinator(
|
||||
hass, websession, api_key, location_key, forecast
|
||||
hass, websession, api_key, location_key, forecast, name
|
||||
)
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
|
||||
|
@ -73,12 +76,27 @@ class AccuWeatherDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
|||
api_key: str,
|
||||
location_key: str,
|
||||
forecast: bool,
|
||||
name: str,
|
||||
) -> None:
|
||||
"""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=self.location_key)
|
||||
self.accuweather = AccuWeather(api_key, session, location_key=location_key)
|
||||
self.device_info = DeviceInfo(
|
||||
entry_type=DeviceEntryType.SERVICE,
|
||||
identifiers={(DOMAIN, location_key)},
|
||||
manufacturer=MANUFACTURER,
|
||||
name=name,
|
||||
# You don't need to provide specific details for the URL,
|
||||
# so passing in _ characters is fine if the location key
|
||||
# is correct
|
||||
configuration_url=(
|
||||
"http://accuweather.com/en/"
|
||||
f"_/_/{location_key}/"
|
||||
f"weather-forecast/{location_key}/"
|
||||
),
|
||||
)
|
||||
|
||||
# Enabling the forecast download increases the number of requests per data
|
||||
# update, we use 40 minutes for current condition only and 80 minutes for
|
||||
|
|
|
@ -3,7 +3,6 @@ from __future__ import annotations
|
|||
|
||||
from typing import Final
|
||||
|
||||
from homeassistant.components.sensor import SensorDeviceClass, SensorStateClass
|
||||
from homeassistant.components.weather import (
|
||||
ATTR_CONDITION_CLEAR_NIGHT,
|
||||
ATTR_CONDITION_CLOUDY,
|
||||
|
@ -20,22 +19,6 @@ from homeassistant.components.weather import (
|
|||
ATTR_CONDITION_SUNNY,
|
||||
ATTR_CONDITION_WINDY,
|
||||
)
|
||||
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,
|
||||
)
|
||||
|
||||
from .model import AccuWeatherSensorDescription
|
||||
|
||||
API_IMPERIAL: Final = "Imperial"
|
||||
API_METRIC: Final = "Metric"
|
||||
|
@ -45,7 +28,6 @@ CONF_FORECAST: Final = "forecast"
|
|||
DOMAIN: Final = "accuweather"
|
||||
MANUFACTURER: Final = "AccuWeather, Inc."
|
||||
MAX_FORECAST_DAYS: Final = 4
|
||||
NAME: Final = "AccuWeather"
|
||||
|
||||
CONDITION_CLASSES: Final[dict[str, list[int]]] = {
|
||||
ATTR_CONDITION_CLEAR_NIGHT: [33, 34, 37],
|
||||
|
@ -63,264 +45,3 @@ CONDITION_CLASSES: Final[dict[str, list[int]]] = {
|
|||
ATTR_CONDITION_SUNNY: [1, 2, 5],
|
||||
ATTR_CONDITION_WINDY: [32],
|
||||
}
|
||||
|
||||
FORECAST_SENSOR_TYPES: Final[tuple[AccuWeatherSensorDescription, ...]] = (
|
||||
AccuWeatherSensorDescription(
|
||||
key="CloudCoverDay",
|
||||
icon="mdi:weather-cloudy",
|
||||
name="Cloud Cover Day",
|
||||
unit_metric=PERCENTAGE,
|
||||
unit_imperial=PERCENTAGE,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="CloudCoverNight",
|
||||
icon="mdi:weather-cloudy",
|
||||
name="Cloud Cover Night",
|
||||
unit_metric=PERCENTAGE,
|
||||
unit_imperial=PERCENTAGE,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
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,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="HoursOfSun",
|
||||
icon="mdi:weather-partly-cloudy",
|
||||
name="Hours Of Sun",
|
||||
unit_metric=TIME_HOURS,
|
||||
unit_imperial=TIME_HOURS,
|
||||
),
|
||||
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,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Ozone",
|
||||
icon="mdi:vector-triangle",
|
||||
name="Ozone",
|
||||
unit_metric=None,
|
||||
unit_imperial=None,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Ragweed",
|
||||
icon="mdi:sprout",
|
||||
name="Ragweed Pollen",
|
||||
unit_metric=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
unit_imperial=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="RealFeelTemperatureMax",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="RealFeel Temperature Max",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="RealFeelTemperatureMin",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="RealFeel Temperature Min",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
),
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="ThunderstormProbabilityDay",
|
||||
icon="mdi:weather-lightning",
|
||||
name="Thunderstorm Probability Day",
|
||||
unit_metric=PERCENTAGE,
|
||||
unit_imperial=PERCENTAGE,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="ThunderstormProbabilityNight",
|
||||
icon="mdi:weather-lightning",
|
||||
name="Thunderstorm Probability Night",
|
||||
unit_metric=PERCENTAGE,
|
||||
unit_imperial=PERCENTAGE,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Tree",
|
||||
icon="mdi:tree-outline",
|
||||
name="Tree Pollen",
|
||||
unit_metric=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
unit_imperial=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="UVIndex",
|
||||
icon="mdi:weather-sunny",
|
||||
name="UV Index",
|
||||
unit_metric=UV_INDEX,
|
||||
unit_imperial=UV_INDEX,
|
||||
),
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="WindDay",
|
||||
icon="mdi:weather-windy",
|
||||
name="Wind Day",
|
||||
unit_metric=SPEED_KILOMETERS_PER_HOUR,
|
||||
unit_imperial=SPEED_MILES_PER_HOUR,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="WindNight",
|
||||
icon="mdi:weather-windy",
|
||||
name="Wind Night",
|
||||
unit_metric=SPEED_KILOMETERS_PER_HOUR,
|
||||
unit_imperial=SPEED_MILES_PER_HOUR,
|
||||
),
|
||||
)
|
||||
|
||||
SENSOR_TYPES: Final[tuple[AccuWeatherSensorDescription, ...]] = (
|
||||
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,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Ceiling",
|
||||
icon="mdi:weather-fog",
|
||||
name="Cloud Ceiling",
|
||||
unit_metric=LENGTH_METERS,
|
||||
unit_imperial=LENGTH_FEET,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="RealFeelTemperature",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="RealFeel Temperature",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
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,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Precipitation",
|
||||
icon="mdi:weather-rainy",
|
||||
name="Precipitation",
|
||||
unit_metric=LENGTH_MILLIMETERS,
|
||||
unit_imperial=LENGTH_INCHES,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="PressureTendency",
|
||||
device_class="accuweather__pressure_tendency",
|
||||
icon="mdi:gauge",
|
||||
name="Pressure Tendency",
|
||||
unit_metric=None,
|
||||
unit_imperial=None,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="UVIndex",
|
||||
icon="mdi:weather-sunny",
|
||||
name="UV Index",
|
||||
unit_metric=UV_INDEX,
|
||||
unit_imperial=UV_INDEX,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
)
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
"""Type definitions for AccuWeather integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from homeassistant.components.sensor import SensorEntityDescription
|
||||
|
||||
|
||||
@dataclass
|
||||
class AccuWeatherSensorDescription(SensorEntityDescription):
|
||||
"""Class describing AccuWeather sensor entities."""
|
||||
|
||||
unit_metric: str | None = None
|
||||
unit_imperial: str | None = None
|
|
@ -1,14 +1,31 @@
|
|||
"""Support for the AccuWeather service."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, cast
|
||||
|
||||
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
SensorEntity,
|
||||
SensorEntityDescription,
|
||||
SensorStateClass,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_NAME
|
||||
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,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.device_registry import DeviceEntryType
|
||||
from homeassistant.helpers.entity import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
@ -20,28 +37,292 @@ from .const import (
|
|||
ATTR_FORECAST,
|
||||
ATTRIBUTION,
|
||||
DOMAIN,
|
||||
FORECAST_SENSOR_TYPES,
|
||||
MANUFACTURER,
|
||||
MAX_FORECAST_DAYS,
|
||||
NAME,
|
||||
SENSOR_TYPES,
|
||||
)
|
||||
from .model import AccuWeatherSensorDescription
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
|
||||
@dataclass
|
||||
class AccuWeatherSensorDescription(SensorEntityDescription):
|
||||
"""Class describing AccuWeather sensor entities."""
|
||||
|
||||
unit_metric: str | None = None
|
||||
unit_imperial: str | None = None
|
||||
|
||||
|
||||
FORECAST_SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
|
||||
AccuWeatherSensorDescription(
|
||||
key="CloudCoverDay",
|
||||
icon="mdi:weather-cloudy",
|
||||
name="Cloud cover day",
|
||||
unit_metric=PERCENTAGE,
|
||||
unit_imperial=PERCENTAGE,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="CloudCoverNight",
|
||||
icon="mdi:weather-cloudy",
|
||||
name="Cloud cover night",
|
||||
unit_metric=PERCENTAGE,
|
||||
unit_imperial=PERCENTAGE,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
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,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="HoursOfSun",
|
||||
icon="mdi:weather-partly-cloudy",
|
||||
name="Hours of sun",
|
||||
unit_metric=TIME_HOURS,
|
||||
unit_imperial=TIME_HOURS,
|
||||
),
|
||||
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,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Ozone",
|
||||
icon="mdi:vector-triangle",
|
||||
name="Ozone",
|
||||
unit_metric=None,
|
||||
unit_imperial=None,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Ragweed",
|
||||
icon="mdi:sprout",
|
||||
name="Ragweed pollen",
|
||||
unit_metric=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
unit_imperial=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="RealFeelTemperatureMax",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="RealFeel temperature max",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="RealFeelTemperatureMin",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="RealFeel temperature min",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
),
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="ThunderstormProbabilityDay",
|
||||
icon="mdi:weather-lightning",
|
||||
name="Thunderstorm probability day",
|
||||
unit_metric=PERCENTAGE,
|
||||
unit_imperial=PERCENTAGE,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="ThunderstormProbabilityNight",
|
||||
icon="mdi:weather-lightning",
|
||||
name="Thunderstorm probability night",
|
||||
unit_metric=PERCENTAGE,
|
||||
unit_imperial=PERCENTAGE,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Tree",
|
||||
icon="mdi:tree-outline",
|
||||
name="Tree pollen",
|
||||
unit_metric=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
unit_imperial=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="UVIndex",
|
||||
icon="mdi:weather-sunny",
|
||||
name="UV index",
|
||||
unit_metric=UV_INDEX,
|
||||
unit_imperial=UV_INDEX,
|
||||
),
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="WindDay",
|
||||
icon="mdi:weather-windy",
|
||||
name="Wind day",
|
||||
unit_metric=SPEED_KILOMETERS_PER_HOUR,
|
||||
unit_imperial=SPEED_MILES_PER_HOUR,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="WindNight",
|
||||
icon="mdi:weather-windy",
|
||||
name="Wind night",
|
||||
unit_metric=SPEED_KILOMETERS_PER_HOUR,
|
||||
unit_imperial=SPEED_MILES_PER_HOUR,
|
||||
),
|
||||
)
|
||||
|
||||
SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
|
||||
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,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Ceiling",
|
||||
icon="mdi:weather-fog",
|
||||
name="Cloud ceiling",
|
||||
unit_metric=LENGTH_METERS,
|
||||
unit_imperial=LENGTH_FEET,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="RealFeelTemperature",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name="RealFeel temperature",
|
||||
unit_metric=TEMP_CELSIUS,
|
||||
unit_imperial=TEMP_FAHRENHEIT,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
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,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Precipitation",
|
||||
icon="mdi:weather-rainy",
|
||||
name="Precipitation",
|
||||
unit_metric=LENGTH_MILLIMETERS,
|
||||
unit_imperial=LENGTH_INCHES,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="PressureTendency",
|
||||
device_class="accuweather__pressure_tendency",
|
||||
icon="mdi:gauge",
|
||||
name="Pressure tendency",
|
||||
unit_metric=None,
|
||||
unit_imperial=None,
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="UVIndex",
|
||||
icon="mdi:weather-sunny",
|
||||
name="UV index",
|
||||
unit_metric=UV_INDEX,
|
||||
unit_imperial=UV_INDEX,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
"""Add AccuWeather entities from a config_entry."""
|
||||
name: str = entry.data[CONF_NAME]
|
||||
|
||||
coordinator: AccuWeatherDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||
|
||||
sensors: list[AccuWeatherSensor] = []
|
||||
for description in SENSOR_TYPES:
|
||||
sensors.append(AccuWeatherSensor(name, coordinator, description))
|
||||
sensors.append(AccuWeatherSensor(coordinator, description))
|
||||
|
||||
if coordinator.forecast:
|
||||
for description in FORECAST_SENSOR_TYPES:
|
||||
|
@ -50,9 +331,7 @@ async def async_setup_entry(
|
|||
# locations.
|
||||
if description.key in coordinator.data[ATTR_FORECAST][0]:
|
||||
sensors.append(
|
||||
AccuWeatherSensor(
|
||||
name, coordinator, description, forecast_day=day
|
||||
)
|
||||
AccuWeatherSensor(coordinator, description, forecast_day=day)
|
||||
)
|
||||
|
||||
async_add_entities(sensors)
|
||||
|
@ -64,11 +343,11 @@ class AccuWeatherSensor(
|
|||
"""Define an AccuWeather entity."""
|
||||
|
||||
_attr_attribution = ATTRIBUTION
|
||||
_attr_has_entity_name = True
|
||||
entity_description: AccuWeatherSensorDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
coordinator: AccuWeatherDataUpdateCoordinator,
|
||||
description: AccuWeatherSensorDescription,
|
||||
forecast_day: int | None = None,
|
||||
|
@ -81,12 +360,11 @@ class AccuWeatherSensor(
|
|||
)
|
||||
self._attrs: dict[str, Any] = {}
|
||||
if forecast_day is not None:
|
||||
self._attr_name = f"{name} {description.name} {forecast_day}d"
|
||||
self._attr_name = f"{description.name} {forecast_day}d"
|
||||
self._attr_unique_id = (
|
||||
f"{coordinator.location_key}-{description.key}-{forecast_day}".lower()
|
||||
)
|
||||
else:
|
||||
self._attr_name = f"{name} {description.name}"
|
||||
self._attr_unique_id = (
|
||||
f"{coordinator.location_key}-{description.key}".lower()
|
||||
)
|
||||
|
@ -96,12 +374,7 @@ class AccuWeatherSensor(
|
|||
else:
|
||||
self._unit_system = API_IMPERIAL
|
||||
self._attr_native_unit_of_measurement = description.unit_imperial
|
||||
self._attr_device_info = DeviceInfo(
|
||||
entry_type=DeviceEntryType.SERVICE,
|
||||
identifiers={(DOMAIN, coordinator.location_key)},
|
||||
manufacturer=MANUFACTURER,
|
||||
name=NAME,
|
||||
)
|
||||
self._attr_device_info = coordinator.device_info
|
||||
self.forecast_day = forecast_day
|
||||
|
||||
@property
|
||||
|
|
|
@ -18,7 +18,6 @@ from homeassistant.components.weather import (
|
|||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
CONF_NAME,
|
||||
LENGTH_INCHES,
|
||||
LENGTH_KILOMETERS,
|
||||
LENGTH_MILES,
|
||||
|
@ -31,8 +30,6 @@ from homeassistant.const import (
|
|||
TEMP_FAHRENHEIT,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import DeviceEntryType
|
||||
from homeassistant.helpers.entity import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
from homeassistant.util.dt import utc_from_timestamp
|
||||
|
@ -45,8 +42,6 @@ from .const import (
|
|||
ATTRIBUTION,
|
||||
CONDITION_CLASSES,
|
||||
DOMAIN,
|
||||
MANUFACTURER,
|
||||
NAME,
|
||||
)
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
@ -56,11 +51,10 @@ async def async_setup_entry(
|
|||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
"""Add a AccuWeather weather entity from a config_entry."""
|
||||
name: str = entry.data[CONF_NAME]
|
||||
|
||||
coordinator: AccuWeatherDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||
|
||||
async_add_entities([AccuWeatherEntity(name, coordinator)])
|
||||
async_add_entities([AccuWeatherEntity(coordinator)])
|
||||
|
||||
|
||||
class AccuWeatherEntity(
|
||||
|
@ -68,9 +62,9 @@ class AccuWeatherEntity(
|
|||
):
|
||||
"""Define an AccuWeather entity."""
|
||||
|
||||
def __init__(
|
||||
self, name: str, coordinator: AccuWeatherDataUpdateCoordinator
|
||||
) -> None:
|
||||
_attr_has_entity_name = True
|
||||
|
||||
def __init__(self, coordinator: AccuWeatherDataUpdateCoordinator) -> None:
|
||||
"""Initialize."""
|
||||
super().__init__(coordinator)
|
||||
# Coordinator data is used also for sensors which don't have units automatically
|
||||
|
@ -90,21 +84,9 @@ class AccuWeatherEntity(
|
|||
self._attr_native_temperature_unit = TEMP_FAHRENHEIT
|
||||
self._attr_native_visibility_unit = LENGTH_MILES
|
||||
self._attr_native_wind_speed_unit = SPEED_MILES_PER_HOUR
|
||||
self._attr_name = name
|
||||
self._attr_unique_id = coordinator.location_key
|
||||
self._attr_attribution = ATTRIBUTION
|
||||
self._attr_device_info = DeviceInfo(
|
||||
entry_type=DeviceEntryType.SERVICE,
|
||||
identifiers={(DOMAIN, coordinator.location_key)},
|
||||
manufacturer=MANUFACTURER,
|
||||
name=NAME,
|
||||
# You don't need to provide specific details for the URL,
|
||||
# so passing in _ characters is fine if the location key
|
||||
# is correct
|
||||
configuration_url="http://accuweather.com/en/"
|
||||
f"_/_/{coordinator.location_key}/"
|
||||
f"weather-forecast/{coordinator.location_key}/",
|
||||
)
|
||||
self._attr_device_info = coordinator.device_info
|
||||
|
||||
@property
|
||||
def condition(self) -> str | None:
|
||||
|
|
Loading…
Reference in New Issue