From 05b463b28254434ed9eecd4a68a74364551f1c7e Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Thu, 21 Jul 2022 18:38:59 +0200 Subject: [PATCH] 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 url --- .../components/accuweather/__init__.py | 26 +- homeassistant/components/accuweather/const.py | 279 --------------- homeassistant/components/accuweather/model.py | 14 - .../components/accuweather/sensor.py | 319 ++++++++++++++++-- .../components/accuweather/weather.py | 28 +- 5 files changed, 323 insertions(+), 343 deletions(-) delete mode 100644 homeassistant/components/accuweather/model.py diff --git a/homeassistant/components/accuweather/__init__.py b/homeassistant/components/accuweather/__init__.py index d36ea4e8466..9123648a38d 100644 --- a/homeassistant/components/accuweather/__init__.py +++ b/homeassistant/components/accuweather/__init__.py @@ -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 diff --git a/homeassistant/components/accuweather/const.py b/homeassistant/components/accuweather/const.py index 408d4700422..c1b90de09e7 100644 --- a/homeassistant/components/accuweather/const.py +++ b/homeassistant/components/accuweather/const.py @@ -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, - ), -) diff --git a/homeassistant/components/accuweather/model.py b/homeassistant/components/accuweather/model.py deleted file mode 100644 index e74a6d46057..00000000000 --- a/homeassistant/components/accuweather/model.py +++ /dev/null @@ -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 diff --git a/homeassistant/components/accuweather/sensor.py b/homeassistant/components/accuweather/sensor.py index 220575541ad..72182d4d635 100644 --- a/homeassistant/components/accuweather/sensor.py +++ b/homeassistant/components/accuweather/sensor.py @@ -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 diff --git a/homeassistant/components/accuweather/weather.py b/homeassistant/components/accuweather/weather.py index ae1824aef4a..e8a5b0ab396 100644 --- a/homeassistant/components/accuweather/weather.py +++ b/homeassistant/components/accuweather/weather.py @@ -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: