core/homeassistant/components/openweathermap/weather.py

169 lines
5.4 KiB
Python

"""Support for the OpenWeatherMap (OWM) service."""
from __future__ import annotations
from homeassistant.components.weather import (
Forecast,
SingleCoordinatorWeatherEntity,
WeatherEntityFeature,
)
from homeassistant.const import (
UnitOfLength,
UnitOfPrecipitationDepth,
UnitOfPressure,
UnitOfSpeed,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import OpenweathermapConfigEntry
from .const import (
ATTR_API_CLOUDS,
ATTR_API_CONDITION,
ATTR_API_CURRENT,
ATTR_API_DAILY_FORECAST,
ATTR_API_DEW_POINT,
ATTR_API_FEELS_LIKE_TEMPERATURE,
ATTR_API_HOURLY_FORECAST,
ATTR_API_HUMIDITY,
ATTR_API_PRESSURE,
ATTR_API_TEMPERATURE,
ATTR_API_VISIBILITY_DISTANCE,
ATTR_API_WIND_BEARING,
ATTR_API_WIND_GUST,
ATTR_API_WIND_SPEED,
ATTRIBUTION,
DEFAULT_NAME,
DOMAIN,
MANUFACTURER,
OWM_MODE_FREE_FORECAST,
OWM_MODE_V25,
OWM_MODE_V30,
)
from .coordinator import WeatherUpdateCoordinator
async def async_setup_entry(
hass: HomeAssistant,
config_entry: OpenweathermapConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up OpenWeatherMap weather entity based on a config entry."""
domain_data = config_entry.runtime_data
name = domain_data.name
mode = domain_data.mode
weather_coordinator = domain_data.coordinator
unique_id = f"{config_entry.unique_id}"
owm_weather = OpenWeatherMapWeather(name, unique_id, mode, weather_coordinator)
async_add_entities([owm_weather], False)
class OpenWeatherMapWeather(SingleCoordinatorWeatherEntity[WeatherUpdateCoordinator]):
"""Implementation of an OpenWeatherMap sensor."""
_attr_attribution = ATTRIBUTION
_attr_should_poll = False
_attr_native_precipitation_unit = UnitOfPrecipitationDepth.MILLIMETERS
_attr_native_pressure_unit = UnitOfPressure.HPA
_attr_native_temperature_unit = UnitOfTemperature.CELSIUS
_attr_native_wind_speed_unit = UnitOfSpeed.METERS_PER_SECOND
_attr_native_visibility_unit = UnitOfLength.METERS
def __init__(
self,
name: str,
unique_id: str,
mode: str,
weather_coordinator: WeatherUpdateCoordinator,
) -> None:
"""Initialize the sensor."""
super().__init__(weather_coordinator)
self._attr_name = name
self._attr_unique_id = unique_id
self._attr_device_info = DeviceInfo(
entry_type=DeviceEntryType.SERVICE,
identifiers={(DOMAIN, unique_id)},
manufacturer=MANUFACTURER,
name=DEFAULT_NAME,
)
if mode in (OWM_MODE_V30, OWM_MODE_V25):
self._attr_supported_features = (
WeatherEntityFeature.FORECAST_DAILY
| WeatherEntityFeature.FORECAST_HOURLY
)
elif mode == OWM_MODE_FREE_FORECAST:
self._attr_supported_features = WeatherEntityFeature.FORECAST_HOURLY
@property
def condition(self) -> str | None:
"""Return the current condition."""
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_CONDITION)
@property
def cloud_coverage(self) -> float | None:
"""Return the Cloud coverage in %."""
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_CLOUDS)
@property
def native_apparent_temperature(self) -> float | None:
"""Return the apparent temperature."""
return self.coordinator.data[ATTR_API_CURRENT].get(
ATTR_API_FEELS_LIKE_TEMPERATURE
)
@property
def native_temperature(self) -> float | None:
"""Return the temperature."""
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_TEMPERATURE)
@property
def native_pressure(self) -> float | None:
"""Return the pressure."""
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_PRESSURE)
@property
def humidity(self) -> float | None:
"""Return the humidity."""
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_HUMIDITY)
@property
def native_dew_point(self) -> float | None:
"""Return the dew point."""
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_DEW_POINT)
@property
def native_wind_gust_speed(self) -> float | None:
"""Return the wind gust speed."""
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_WIND_GUST)
@property
def native_wind_speed(self) -> float | None:
"""Return the wind speed."""
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_WIND_SPEED)
@property
def wind_bearing(self) -> float | str | None:
"""Return the wind bearing."""
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_WIND_BEARING)
@property
def visibility(self) -> float | str | None:
"""Return visibility."""
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_VISIBILITY_DISTANCE)
@callback
def _async_forecast_daily(self) -> list[Forecast] | None:
"""Return the daily forecast in native units."""
return self.coordinator.data[ATTR_API_DAILY_FORECAST]
@callback
def _async_forecast_hourly(self) -> list[Forecast] | None:
"""Return the hourly forecast in native units."""
return self.coordinator.data[ATTR_API_HOURLY_FORECAST]