Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
e63517e
update ipma component for pyipma 2.0
abmantis Jan 11, 2020
a41976a
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
abmantis Jan 13, 2020
9e8a2e5
fix wind speed; refactor forecast
abmantis Jan 13, 2020
752dc5f
update requirements*.txt
abmantis Jan 13, 2020
b9b59d2
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
abmantis Jan 14, 2020
7fdee81
fix tests; update CODEOWNERS; update pyipma to 2.0.1
abmantis Jan 15, 2020
0f36c9d
minor changes as suggested in PR
abmantis Jan 15, 2020
f72aedf
make lint happy
abmantis Jan 16, 2020
ff7ca8b
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
abmantis Jan 17, 2020
b0ae636
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
abmantis Jan 19, 2020
dab8df6
fix mocking coroutines
abmantis Jan 19, 2020
b62aac3
restore old unique id
abmantis Jan 20, 2020
a1fe8a7
fix station lat/lon; update pyipma version
abmantis Jan 20, 2020
7a036c4
add hourly forecast option to IPMA
abmantis Jan 13, 2020
baae1e9
add forecast tests
abmantis Jan 19, 2020
e7c2a4b
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
abmantis Jan 21, 2020
2e7ea85
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
abmantis Jan 22, 2020
a48f6f0
use for instead of lambda
abmantis Jan 30, 2020
15be6c3
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
abmantis Feb 8, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion homeassistant/components/ipma/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
import voluptuous as vol

from homeassistant import config_entries
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_MODE, CONF_NAME
import homeassistant.helpers.config_validation as cv

from .const import DOMAIN, HOME_LOCATION_NAME
from .weather import FORECAST_MODE


@config_entries.HANDLERS.register(DOMAIN)
Expand Down Expand Up @@ -49,6 +50,7 @@ async def _show_config_form(self, name=None, latitude=None, longitude=None):
vol.Required(CONF_NAME, default=name): str,
vol.Required(CONF_LATITUDE, default=latitude): cv.latitude,
vol.Required(CONF_LONGITUDE, default=longitude): cv.longitude,
vol.Required(CONF_MODE, default="daily"): vol.In(FORECAST_MODE),
}
),
errors=self._errors,
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/ipma/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"data": {
"name": "Name",
"latitude": "Latitude",
"longitude": "Longitude"
"longitude": "Longitude",
"mode": "Mode"
}
}
},
Expand Down
90 changes: 71 additions & 19 deletions homeassistant/components/ipma/weather.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,22 @@
ATTR_FORECAST_TEMP,
ATTR_FORECAST_TEMP_LOW,
ATTR_FORECAST_TIME,
ATTR_FORECAST_WIND_BEARING,
ATTR_FORECAST_WIND_SPEED,
PLATFORM_SCHEMA,
WeatherEntity,
)
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME, TEMP_CELSIUS
from homeassistant.const import (
CONF_LATITUDE,
CONF_LONGITUDE,
CONF_MODE,
CONF_NAME,
TEMP_CELSIUS,
)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.util import Throttle
from homeassistant.util.dt import now, parse_datetime

_LOGGER = logging.getLogger(__name__)

Expand All @@ -44,11 +53,14 @@
"exceptional": [],
}

FORECAST_MODE = ["hourly", "daily"]

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_LATITUDE): cv.latitude,
vol.Optional(CONF_LONGITUDE): cv.longitude,
vol.Optional(CONF_MODE, default="daily"): vol.In(FORECAST_MODE),
}
)

Expand Down Expand Up @@ -96,10 +108,12 @@ async def async_get_location(hass, api, latitude, longitude):
location = await Location.get(api, float(latitude), float(longitude))

_LOGGER.debug(
"Initializing for coordinates %s, %s -> station %s",
"Initializing for coordinates %s, %s -> station %s (%d, %d)",
latitude,
longitude,
location.station,
location.id_station,
location.global_id_local,
)

return location
Expand All @@ -112,6 +126,7 @@ def __init__(self, location: Location, api: IPMA_API, config):
"""Initialise the platform with a data instance and station name."""
self._api = api
self._location_name = config.get(CONF_NAME, location.name)
self._mode = config.get(CONF_MODE)
self._location = location
self._observation = None
self._forecast = None
Expand All @@ -129,7 +144,7 @@ async def async_update(self):
_LOGGER.warning("Could not update weather observation")

if new_forecast:
self._forecast = [f for f in new_forecast if f.forecasted_hours == 24]
self._forecast = new_forecast
else:
_LOGGER.warning("Could not update weather forecast")

Expand Down Expand Up @@ -220,22 +235,59 @@ def forecast(self):
if not self._forecast:
return []

fcdata_out = [
{
ATTR_FORECAST_TIME: data_in.forecast_date,
ATTR_FORECAST_CONDITION: next(
(
k
for k, v in CONDITION_CLASSES.items()
if int(data_in.weather_type) in v
if self._mode == "hourly":
forecast_filtered = [
x
for x in self._forecast
if x.forecasted_hours == 1
and parse_datetime(x.forecast_date)
> (now().utcnow() - timedelta(hours=1))
]

fcdata_out = [
{
ATTR_FORECAST_TIME: data_in.forecast_date,
ATTR_FORECAST_CONDITION: next(
(
k
for k, v in CONDITION_CLASSES.items()
if int(data_in.weather_type) in v
),
None,
),
ATTR_FORECAST_TEMP: float(data_in.feels_like_temperature),
ATTR_FORECAST_PRECIPITATION: (
data_in.precipitation_probability
if float(data_in.precipitation_probability) >= 0
else None
),
ATTR_FORECAST_WIND_SPEED: data_in.wind_strength,
ATTR_FORECAST_WIND_BEARING: data_in.wind_direction,
}
for data_in in forecast_filtered
]
else:
forecast_filtered = list(
filter(lambda x: x.forecasted_hours == 24, self._forecast)
Comment thread
dgomes marked this conversation as resolved.
Outdated
)
fcdata_out = [
{
ATTR_FORECAST_TIME: data_in.forecast_date,
ATTR_FORECAST_CONDITION: next(
(
k
for k, v in CONDITION_CLASSES.items()
if int(data_in.weather_type) in v
),
None,
),
None,
),
ATTR_FORECAST_TEMP_LOW: data_in.min_temperature,
ATTR_FORECAST_TEMP: data_in.max_temperature,
ATTR_FORECAST_PRECIPITATION: data_in.precipitation_probability,
}
for data_in in self._forecast
]
ATTR_FORECAST_TEMP_LOW: data_in.min_temperature,
ATTR_FORECAST_TEMP: data_in.max_temperature,
ATTR_FORECAST_PRECIPITATION: data_in.precipitation_probability,
ATTR_FORECAST_WIND_SPEED: data_in.wind_strength,
ATTR_FORECAST_WIND_BEARING: data_in.wind_direction,
}
for data_in in forecast_filtered
]

return fcdata_out
69 changes: 65 additions & 4 deletions tests/components/ipma/test_weather.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@

from homeassistant.components import weather
from homeassistant.components.weather import (
ATTR_FORECAST,
ATTR_FORECAST_CONDITION,
ATTR_FORECAST_PRECIPITATION,
ATTR_FORECAST_TEMP,
ATTR_FORECAST_TEMP_LOW,
ATTR_FORECAST_TIME,
ATTR_FORECAST_WIND_BEARING,
ATTR_FORECAST_WIND_SPEED,
ATTR_WEATHER_HUMIDITY,
ATTR_WEATHER_PRESSURE,
ATTR_WEATHER_TEMPERATURE,
Expand All @@ -12,6 +20,7 @@
DOMAIN as WEATHER_DOMAIN,
)
from homeassistant.setup import async_setup_component
from homeassistant.util.dt import now

from tests.common import MockConfigEntry, mock_coro

Expand Down Expand Up @@ -71,16 +80,16 @@ async def forecast(self, api):
"2020-01-15T07:51:00",
9,
"S",
None,
"10",
),
Forecast(
"7.7",
"2020-01-15T02:00:00",
now().utcnow().strftime("%Y-%m-%dT%H:%M:%S"),
Comment thread
dgomes marked this conversation as resolved.
1,
"86.9",
None,
None,
"-99.0",
"80.0",
10.6,
"2020-01-15T07:51:00",
10,
Expand Down Expand Up @@ -122,7 +131,9 @@ async def test_setup_configuration(hass):
return_value=mock_coro(MockLocation()),
):
assert await async_setup_component(
hass, weather.DOMAIN, {"weather": {"name": "HomeTown", "platform": "ipma"}}
hass,
weather.DOMAIN,
{"weather": {"name": "HomeTown", "platform": "ipma", "mode": "hourly"}},
)
await hass.async_block_till_done()

Expand Down Expand Up @@ -158,3 +169,53 @@ async def test_setup_config_flow(hass):
assert data.get(ATTR_WEATHER_WIND_SPEED) == 3.94
assert data.get(ATTR_WEATHER_WIND_BEARING) == "NW"
assert state.attributes.get("friendly_name") == "HomeTown"


async def test_daily_forecast(hass):
"""Test for successfully getting daily forecast."""
with patch(
"homeassistant.components.ipma.weather.async_get_location",
return_value=mock_coro(MockLocation()),
):
assert await async_setup_component(
hass,
weather.DOMAIN,
{"weather": {"name": "HomeTown", "platform": "ipma", "mode": "daily"}},
)
await hass.async_block_till_done()

state = hass.states.get("weather.hometown")
assert state.state == "rainy"

forecast = state.attributes.get(ATTR_FORECAST)[0]
assert forecast.get(ATTR_FORECAST_TIME) == "2020-01-15T00:00:00"
assert forecast.get(ATTR_FORECAST_CONDITION) == "rainy"
assert forecast.get(ATTR_FORECAST_TEMP) == 16.2
assert forecast.get(ATTR_FORECAST_TEMP_LOW) == 10.6
assert forecast.get(ATTR_FORECAST_PRECIPITATION) == "100.0"
assert forecast.get(ATTR_FORECAST_WIND_SPEED) == "10"
assert forecast.get(ATTR_FORECAST_WIND_BEARING) == "S"


async def test_hourly_forecast(hass):
"""Test for successfully getting daily forecast."""
with patch(
"homeassistant.components.ipma.weather.async_get_location",
return_value=mock_coro(MockLocation()),
):
assert await async_setup_component(
hass,
weather.DOMAIN,
{"weather": {"name": "HomeTown", "platform": "ipma", "mode": "hourly"}},
)
await hass.async_block_till_done()

state = hass.states.get("weather.hometown")
assert state.state == "rainy"

forecast = state.attributes.get(ATTR_FORECAST)[0]
assert forecast.get(ATTR_FORECAST_CONDITION) == "rainy"
assert forecast.get(ATTR_FORECAST_TEMP) == 7.7
assert forecast.get(ATTR_FORECAST_PRECIPITATION) == "80.0"
assert forecast.get(ATTR_FORECAST_WIND_SPEED) == "32.7"
assert forecast.get(ATTR_FORECAST_WIND_BEARING) == "S"