Add hourly forecast to met.no (#38700)

* Add hourly forecast

* fix tests to assert for 2 entities created

* fix test to assert for 4 calls

* correct test tracking home number of calls

* fox tests

* fix test

* Apply suggestions from code review

* black

Co-authored-by: Chris Talkington <chris@talkingtontech.com>
This commit is contained in:
Vaclav 2020-08-11 03:22:39 +02:00 committed by GitHub
parent 844b3f8d23
commit 8555e17eb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 18 deletions

View File

@ -22,7 +22,7 @@ import homeassistant.util.dt as dt_util
from .const import CONF_TRACK_HOME, DOMAIN
URL = "https://aa015h6buqvih86i1.api.met.no/weatherapi/locationforecast/1.9/"
URL = "https://api.met.no/weatherapi/locationforecast/2.0/classic"
_LOGGER = logging.getLogger(__name__)
@ -116,7 +116,8 @@ class MetWeatherData:
self._is_metric = is_metric
self._weather_data = None
self.current_weather_data = {}
self.forecast_data = None
self.daily_forecast = None
self.hourly_forecast = None
def init_data(self):
"""Weather data inialization - get the coordinates."""
@ -149,5 +150,6 @@ class MetWeatherData:
await self._weather_data.fetching_data()
self.current_weather_data = self._weather_data.get_current_weather()
time_zone = dt_util.DEFAULT_TIME_ZONE
self.forecast_data = self._weather_data.get_forecast(time_zone)
self.daily_forecast = self._weather_data.get_forecast(time_zone, False)
self.hourly_forecast = self._weather_data.get_forecast(time_zone, True)
return self

View File

@ -66,18 +66,27 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
"""Add a weather entity from a config_entry."""
coordinator = hass.data[DOMAIN][config_entry.entry_id]
async_add_entities(
[MetWeather(coordinator, config_entry.data, hass.config.units.is_metric)]
[
MetWeather(
coordinator, config_entry.data, hass.config.units.is_metric, False
),
MetWeather(
coordinator, config_entry.data, hass.config.units.is_metric, True
),
]
)
class MetWeather(WeatherEntity):
"""Implementation of a Met.no weather condition."""
def __init__(self, coordinator, config, is_metric):
def __init__(self, coordinator, config, is_metric, hourly):
"""Initialise the platform with a data instance and site."""
self._config = config
self._coordinator = coordinator
self._is_metric = is_metric
self._hourly = hourly
self._name_appendix = "-hourly" if hourly else ""
async def async_added_to_hass(self):
"""Start fetching data."""
@ -103,9 +112,9 @@ class MetWeather(WeatherEntity):
def unique_id(self):
"""Return unique ID."""
if self.track_home:
return "home"
return f"home{self._name_appendix}"
return f"{self._config[CONF_LATITUDE]}-{self._config[CONF_LONGITUDE]}"
return f"{self._config[CONF_LATITUDE]}-{self._config[CONF_LONGITUDE]}{self._name_appendix}"
@property
def name(self):
@ -113,12 +122,12 @@ class MetWeather(WeatherEntity):
name = self._config.get(CONF_NAME)
if name is not None:
return name
return f"{name}{self._name_appendix}"
if self.track_home:
return self.hass.config.location_name
return f"{self.hass.config.location_name}{self._name_appendix}"
return DEFAULT_NAME
return f"{DEFAULT_NAME}{self._name_appendix}"
@property
def condition(self):
@ -173,4 +182,6 @@ class MetWeather(WeatherEntity):
@property
def forecast(self):
"""Return the forecast array."""
return self._coordinator.data.forecast_data
if self._hourly:
return self._coordinator.data.hourly_forecast
return self._coordinator.data.daily_forecast

View File

@ -5,14 +5,14 @@ async def test_tracking_home(hass, mock_weather):
"""Test we track home."""
await hass.config_entries.flow.async_init("met", context={"source": "onboarding"})
await hass.async_block_till_done()
assert len(hass.states.async_entity_ids("weather")) == 1
assert len(mock_weather.mock_calls) == 3
assert len(hass.states.async_entity_ids("weather")) == 2
assert len(mock_weather.mock_calls) == 4
# Test we track config
await hass.config.async_update(latitude=10, longitude=20)
await hass.async_block_till_done()
assert len(mock_weather.mock_calls) == 6
assert len(mock_weather.mock_calls) == 8
entry = hass.config_entries.async_entries()[0]
await hass.config_entries.async_remove(entry.entry_id)
@ -27,14 +27,14 @@ async def test_not_tracking_home(hass, mock_weather):
data={"name": "Somewhere", "latitude": 10, "longitude": 20, "elevation": 0},
)
await hass.async_block_till_done()
assert len(hass.states.async_entity_ids("weather")) == 1
assert len(mock_weather.mock_calls) == 3
assert len(hass.states.async_entity_ids("weather")) == 2
assert len(mock_weather.mock_calls) == 4
# Test we do not track config
await hass.config.async_update(latitude=10, longitude=20)
await hass.async_block_till_done()
assert len(mock_weather.mock_calls) == 3
assert len(mock_weather.mock_calls) == 4
entry = hass.config_entries.async_entries()[0]
await hass.config_entries.async_remove(entry.entry_id)

View File

@ -276,4 +276,4 @@ async def test_onboarding_core_sets_up_met(hass, hass_storage, hass_client):
assert resp.status == 200
await hass.async_block_till_done()
assert len(hass.states.async_entity_ids("weather")) == 1
assert len(hass.states.async_entity_ids("weather")) == 2