diff --git a/homeassistant/components/smhi/entity.py b/homeassistant/components/smhi/entity.py new file mode 100644 index 00000000000..8d650d31945 --- /dev/null +++ b/homeassistant/components/smhi/entity.py @@ -0,0 +1,36 @@ +"""Support for the Swedish weather institute weather base entities.""" + +from __future__ import annotations + +import aiohttp +from pysmhi import SMHIPointForecast + +from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo +from homeassistant.helpers.entity import Entity + +from .const import DOMAIN + + +class SmhiWeatherBaseEntity(Entity): + """Representation of a base weather entity.""" + + _attr_attribution = "Swedish weather institute (SMHI)" + _attr_has_entity_name = True + _attr_name = None + + def __init__( + self, + latitude: str, + longitude: str, + session: aiohttp.ClientSession, + ) -> None: + """Initialize the SMHI base weather entity.""" + self._attr_unique_id = f"{latitude}, {longitude}" + self._smhi_api = SMHIPointForecast(longitude, latitude, session=session) + self._attr_device_info = DeviceInfo( + entry_type=DeviceEntryType.SERVICE, + identifiers={(DOMAIN, f"{latitude}, {longitude}")}, + manufacturer="SMHI", + model="v2", + configuration_url="http://opendata.smhi.se/apidocs/metfcst/parameters.html", + ) diff --git a/homeassistant/components/smhi/weather.py b/homeassistant/components/smhi/weather.py index a263eeb6174..b9cac9bdf2e 100644 --- a/homeassistant/components/smhi/weather.py +++ b/homeassistant/components/smhi/weather.py @@ -9,7 +9,7 @@ import logging from typing import Any, Final import aiohttp -from pysmhi import SMHIForecast, SmhiForecastException, SMHIPointForecast +from pysmhi import SMHIForecast, SmhiForecastException from homeassistant.components.weather import ( ATTR_CONDITION_CLEAR_NIGHT, @@ -55,12 +55,12 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers import aiohttp_client, sun -from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from homeassistant.util import Throttle -from .const import ATTR_SMHI_THUNDER_PROBABILITY, DOMAIN, ENTITY_ID_SENSOR_FORMAT +from .const import ATTR_SMHI_THUNDER_PROBABILITY, ENTITY_ID_SENSOR_FORMAT +from .entity import SmhiWeatherBaseEntity _LOGGER = logging.getLogger(__name__) @@ -114,18 +114,14 @@ async def async_setup_entry( async_add_entities([entity], True) -class SmhiWeather(WeatherEntity): +class SmhiWeather(SmhiWeatherBaseEntity, WeatherEntity): """Representation of a weather entity.""" - _attr_attribution = "Swedish weather institute (SMHI)" _attr_native_temperature_unit = UnitOfTemperature.CELSIUS _attr_native_visibility_unit = UnitOfLength.KILOMETERS _attr_native_precipitation_unit = UnitOfPrecipitationDepth.MILLIMETERS _attr_native_wind_speed_unit = UnitOfSpeed.METERS_PER_SECOND _attr_native_pressure_unit = UnitOfPressure.HPA - - _attr_has_entity_name = True - _attr_name = None _attr_supported_features = ( WeatherEntityFeature.FORECAST_DAILY | WeatherEntityFeature.FORECAST_HOURLY ) @@ -137,18 +133,10 @@ class SmhiWeather(WeatherEntity): session: aiohttp.ClientSession, ) -> None: """Initialize the SMHI weather entity.""" - self._attr_unique_id = f"{latitude}, {longitude}" + super().__init__(latitude, longitude, session) self._forecast_daily: list[SMHIForecast] | None = None self._forecast_hourly: list[SMHIForecast] | None = None self._fail_count = 0 - self._smhi_api = SMHIPointForecast(longitude, latitude, session=session) - self._attr_device_info = DeviceInfo( - entry_type=DeviceEntryType.SERVICE, - identifiers={(DOMAIN, f"{latitude}, {longitude}")}, - manufacturer="SMHI", - model="v2", - configuration_url="http://opendata.smhi.se/apidocs/metfcst/parameters.html", - ) @property def extra_state_attributes(self) -> Mapping[str, Any] | None: diff --git a/tests/components/smhi/test_weather.py b/tests/components/smhi/test_weather.py index a39cb72d4b8..f47566f2d5c 100644 --- a/tests/components/smhi/test_weather.py +++ b/tests/components/smhi/test_weather.py @@ -110,7 +110,7 @@ async def test_properties_no_data(hass: HomeAssistant) -> None: entry.add_to_hass(hass) with patch( - "homeassistant.components.smhi.weather.SMHIPointForecast.async_get_daily_forecast", + "homeassistant.components.smhi.entity.SMHIPointForecast.async_get_daily_forecast", side_effect=SmhiForecastException("boom"), ): await hass.config_entries.async_setup(entry.entry_id) @@ -215,11 +215,11 @@ async def test_properties_unknown_symbol(hass: HomeAssistant) -> None: with ( patch( - "homeassistant.components.smhi.weather.SMHIPointForecast.async_get_daily_forecast", + "homeassistant.components.smhi.entity.SMHIPointForecast.async_get_daily_forecast", return_value=testdata, ), patch( - "homeassistant.components.smhi.weather.SMHIPointForecast.async_get_hourly_forecast", + "homeassistant.components.smhi.entity.SMHIPointForecast.async_get_hourly_forecast", return_value=None, ), ): @@ -254,7 +254,7 @@ async def test_refresh_weather_forecast_retry( now = dt_util.utcnow() with patch( - "homeassistant.components.smhi.weather.SMHIPointForecast.async_get_daily_forecast", + "homeassistant.components.smhi.entity.SMHIPointForecast.async_get_daily_forecast", side_effect=error, ) as mock_get_forecast: await hass.config_entries.async_setup(entry.entry_id)