Add type annotations to OpenWeatherMap (#58802)

This commit is contained in:
carstenschroeder 2021-11-01 14:28:30 +01:00 committed by GitHub
parent d125dc7dbf
commit 0e19278309
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 44 deletions

View File

@ -1,5 +1,8 @@
"""The openweathermap component.""" """The openweathermap component."""
from __future__ import annotations
import logging import logging
from typing import Any
from pyowm import OWM from pyowm import OWM
from pyowm.utils.config import get_default_config from pyowm.utils.config import get_default_config
@ -62,7 +65,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True return True
async def async_migrate_entry(hass, entry): async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Migrate old entry.""" """Migrate old entry."""
config_entries = hass.config_entries config_entries = hass.config_entries
data = entry.data data = entry.data
@ -83,7 +86,7 @@ async def async_migrate_entry(hass, entry):
return True return True
async def async_update_options(hass: HomeAssistant, entry: ConfigEntry): async def async_update_options(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Update options.""" """Update options."""
await hass.config_entries.async_reload(entry.entry_id) await hass.config_entries.async_reload(entry.entry_id)
@ -99,17 +102,13 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return unload_ok return unload_ok
def _filter_domain_configs(elements, domain): def _get_config_value(config_entry: ConfigEntry, key: str) -> Any:
return list(filter(lambda elem: elem["platform"] == domain, elements))
def _get_config_value(config_entry, key):
if config_entry.options: if config_entry.options:
return config_entry.options[key] return config_entry.options[key]
return config_entry.data[key] return config_entry.data[key]
def _get_owm_config(language): def _get_owm_config(language: str) -> dict[str, Any]:
"""Get OpenWeatherMap configuration and add language to it.""" """Get OpenWeatherMap configuration and add language to it."""
config_dict = get_default_config() config_dict = get_default_config()
config_dict["language"] = language config_dict["language"] = language

View File

@ -2,8 +2,12 @@
from __future__ import annotations from __future__ import annotations
from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.components.sensor import SensorEntity, SensorEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_ATTRIBUTION from homeassistant.const import ATTR_ATTRIBUTION
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo 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 DataUpdateCoordinator from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .const import ( from .const import (
@ -20,7 +24,11 @@ from .const import (
from .weather_update_coordinator import WeatherUpdateCoordinator from .weather_update_coordinator import WeatherUpdateCoordinator
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up OpenWeatherMap sensor entities based on a config entry.""" """Set up OpenWeatherMap sensor entities based on a config entry."""
domain_data = hass.data[DOMAIN][config_entry.entry_id] domain_data = hass.data[DOMAIN][config_entry.entry_id]
name = domain_data[ENTRY_NAME] name = domain_data[ENTRY_NAME]
@ -59,11 +67,11 @@ class AbstractOpenWeatherMapSensor(SensorEntity):
def __init__( def __init__(
self, self,
name, name: str,
unique_id, unique_id: str,
description: SensorEntityDescription, description: SensorEntityDescription,
coordinator: DataUpdateCoordinator, coordinator: DataUpdateCoordinator,
): ) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
self.entity_description = description self.entity_description = description
self._coordinator = coordinator self._coordinator = coordinator
@ -79,22 +87,22 @@ class AbstractOpenWeatherMapSensor(SensorEntity):
) )
@property @property
def attribution(self): def attribution(self) -> str:
"""Return the attribution.""" """Return the attribution."""
return ATTRIBUTION return ATTRIBUTION
@property @property
def available(self): def available(self) -> bool:
"""Return True if entity is available.""" """Return True if entity is available."""
return self._coordinator.last_update_success return self._coordinator.last_update_success
async def async_added_to_hass(self): async def async_added_to_hass(self) -> None:
"""Connect to dispatcher listening for entity data notifications.""" """Connect to dispatcher listening for entity data notifications."""
self.async_on_remove( self.async_on_remove(
self._coordinator.async_add_listener(self.async_write_ha_state) self._coordinator.async_add_listener(self.async_write_ha_state)
) )
async def async_update(self): async def async_update(self) -> None:
"""Get the latest data from OWM and updates the states.""" """Get the latest data from OWM and updates the states."""
await self._coordinator.async_request_refresh() await self._coordinator.async_request_refresh()
@ -104,17 +112,17 @@ class OpenWeatherMapSensor(AbstractOpenWeatherMapSensor):
def __init__( def __init__(
self, self,
name, name: str,
unique_id, unique_id: str,
description: SensorEntityDescription, description: SensorEntityDescription,
weather_coordinator: WeatherUpdateCoordinator, weather_coordinator: WeatherUpdateCoordinator,
): ) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
super().__init__(name, unique_id, description, weather_coordinator) super().__init__(name, unique_id, description, weather_coordinator)
self._weather_coordinator = weather_coordinator self._weather_coordinator = weather_coordinator
@property @property
def native_value(self): def native_value(self) -> StateType:
"""Return the state of the device.""" """Return the state of the device."""
return self._weather_coordinator.data.get(self.entity_description.key, None) return self._weather_coordinator.data.get(self.entity_description.key, None)
@ -124,17 +132,17 @@ class OpenWeatherMapForecastSensor(AbstractOpenWeatherMapSensor):
def __init__( def __init__(
self, self,
name, name: str,
unique_id, unique_id: str,
description: SensorEntityDescription, description: SensorEntityDescription,
weather_coordinator: WeatherUpdateCoordinator, weather_coordinator: WeatherUpdateCoordinator,
): ) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
super().__init__(name, unique_id, description, weather_coordinator) super().__init__(name, unique_id, description, weather_coordinator)
self._weather_coordinator = weather_coordinator self._weather_coordinator = weather_coordinator
@property @property
def native_value(self): def native_value(self) -> StateType:
"""Return the state of the device.""" """Return the state of the device."""
forecasts = self._weather_coordinator.data.get(ATTR_API_FORECAST) forecasts = self._weather_coordinator.data.get(ATTR_API_FORECAST)
if forecasts is not None and len(forecasts) > 0: if forecasts is not None and len(forecasts) > 0:

View File

@ -1,7 +1,12 @@
"""Support for the OpenWeatherMap (OWM) service.""" """Support for the OpenWeatherMap (OWM) service."""
from homeassistant.components.weather import WeatherEntity from __future__ import annotations
from homeassistant.components.weather import Forecast, WeatherEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import PRESSURE_HPA, PRESSURE_INHG, TEMP_CELSIUS from homeassistant.const import PRESSURE_HPA, PRESSURE_INHG, TEMP_CELSIUS
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util.pressure import convert as pressure_convert from homeassistant.util.pressure import convert as pressure_convert
from .const import ( from .const import (
@ -22,7 +27,11 @@ from .const import (
from .weather_update_coordinator import WeatherUpdateCoordinator from .weather_update_coordinator import WeatherUpdateCoordinator
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up OpenWeatherMap weather entity based on a config entry.""" """Set up OpenWeatherMap weather entity based on a config entry."""
domain_data = hass.data[DOMAIN][config_entry.entry_id] domain_data = hass.data[DOMAIN][config_entry.entry_id]
name = domain_data[ENTRY_NAME] name = domain_data[ENTRY_NAME]
@ -39,22 +48,22 @@ class OpenWeatherMapWeather(WeatherEntity):
def __init__( def __init__(
self, self,
name, name: str,
unique_id, unique_id: str,
weather_coordinator: WeatherUpdateCoordinator, weather_coordinator: WeatherUpdateCoordinator,
): ) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
self._name = name self._name = name
self._unique_id = unique_id self._unique_id = unique_id
self._weather_coordinator = weather_coordinator self._weather_coordinator = weather_coordinator
@property @property
def name(self): def name(self) -> str:
"""Return the name of the sensor.""" """Return the name of the sensor."""
return self._name return self._name
@property @property
def unique_id(self): def unique_id(self) -> str:
"""Return a unique_id for this entity.""" """Return a unique_id for this entity."""
return self._unique_id return self._unique_id
@ -69,32 +78,32 @@ class OpenWeatherMapWeather(WeatherEntity):
) )
@property @property
def should_poll(self): def should_poll(self) -> bool:
"""Return the polling requirement of the entity.""" """Return the polling requirement of the entity."""
return False return False
@property @property
def attribution(self): def attribution(self) -> str:
"""Return the attribution.""" """Return the attribution."""
return ATTRIBUTION return ATTRIBUTION
@property @property
def condition(self): def condition(self) -> str | None:
"""Return the current condition.""" """Return the current condition."""
return self._weather_coordinator.data[ATTR_API_CONDITION] return self._weather_coordinator.data[ATTR_API_CONDITION]
@property @property
def temperature(self): def temperature(self) -> float | None:
"""Return the temperature.""" """Return the temperature."""
return self._weather_coordinator.data[ATTR_API_TEMPERATURE] return self._weather_coordinator.data[ATTR_API_TEMPERATURE]
@property @property
def temperature_unit(self): def temperature_unit(self) -> str:
"""Return the unit of measurement.""" """Return the unit of measurement."""
return TEMP_CELSIUS return TEMP_CELSIUS
@property @property
def pressure(self): def pressure(self) -> float | None:
"""Return the pressure.""" """Return the pressure."""
pressure = self._weather_coordinator.data[ATTR_API_PRESSURE] pressure = self._weather_coordinator.data[ATTR_API_PRESSURE]
# OpenWeatherMap returns pressure in hPA, so convert to # OpenWeatherMap returns pressure in hPA, so convert to
@ -104,12 +113,12 @@ class OpenWeatherMapWeather(WeatherEntity):
return pressure return pressure
@property @property
def humidity(self): def humidity(self) -> float | None:
"""Return the humidity.""" """Return the humidity."""
return self._weather_coordinator.data[ATTR_API_HUMIDITY] return self._weather_coordinator.data[ATTR_API_HUMIDITY]
@property @property
def wind_speed(self): def wind_speed(self) -> float | None:
"""Return the wind speed.""" """Return the wind speed."""
wind_speed = self._weather_coordinator.data[ATTR_API_WIND_SPEED] wind_speed = self._weather_coordinator.data[ATTR_API_WIND_SPEED]
if self.hass.config.units.name == "imperial": if self.hass.config.units.name == "imperial":
@ -117,26 +126,26 @@ class OpenWeatherMapWeather(WeatherEntity):
return round(wind_speed * 3.6, 2) return round(wind_speed * 3.6, 2)
@property @property
def wind_bearing(self): def wind_bearing(self) -> float | str | None:
"""Return the wind bearing.""" """Return the wind bearing."""
return self._weather_coordinator.data[ATTR_API_WIND_BEARING] return self._weather_coordinator.data[ATTR_API_WIND_BEARING]
@property @property
def forecast(self): def forecast(self) -> list[Forecast] | None:
"""Return the forecast array.""" """Return the forecast array."""
return self._weather_coordinator.data[ATTR_API_FORECAST] return self._weather_coordinator.data[ATTR_API_FORECAST]
@property @property
def available(self): def available(self) -> bool:
"""Return True if entity is available.""" """Return True if entity is available."""
return self._weather_coordinator.last_update_success return self._weather_coordinator.last_update_success
async def async_added_to_hass(self): async def async_added_to_hass(self) -> None:
"""Connect to dispatcher listening for entity data notifications.""" """Connect to dispatcher listening for entity data notifications."""
self.async_on_remove( self.async_on_remove(
self._weather_coordinator.async_add_listener(self.async_write_ha_state) self._weather_coordinator.async_add_listener(self.async_write_ha_state)
) )
async def async_update(self): async def async_update(self) -> None:
"""Get the latest data from OWM and updates the states.""" """Get the latest data from OWM and updates the states."""
await self._weather_coordinator.async_request_refresh() await self._weather_coordinator.async_request_refresh()