Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix smhi docstrings #18414

Merged
merged 4 commits into from Nov 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 8 additions & 9 deletions homeassistant/components/smhi/__init__.py
@@ -1,14 +1,13 @@
"""
Component for the swedish weather institute weather service.
Component for the Swedish weather institute weather service.

For more details about this component, please refer to the documentation at
https://home-assistant.io/components/smhi/
"""
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import Config, HomeAssistant

# Have to import for config_flow to work
# even if they are not used here
# Have to import for config_flow to work even if they are not used here
from .config_flow import smhi_locations # noqa: F401
from .const import DOMAIN # noqa: F401

Expand All @@ -18,21 +17,21 @@


async def async_setup(hass: HomeAssistant, config: Config) -> bool:
"""Set up configured smhi."""
"""Set up configured SMHI."""
# We allow setup only through config flow type of config
return True


async def async_setup_entry(hass: HomeAssistant,
config_entry: ConfigEntry) -> bool:
"""Set up smhi forecast as config entry."""
async def async_setup_entry(
hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Set up SMHI forecast as config entry."""
hass.async_create_task(hass.config_entries.async_forward_entry_setup(
config_entry, 'weather'))
return True


async def async_unload_entry(hass: HomeAssistant,
config_entry: ConfigEntry) -> bool:
async def async_unload_entry(
hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Unload a config entry."""
await hass.config_entries.async_forward_entry_unload(
config_entry, 'weather')
Expand Down
32 changes: 8 additions & 24 deletions homeassistant/components/smhi/config_flow.py
@@ -1,21 +1,11 @@
"""Config flow to configure smhi component.

First time the user creates the configuration and
a valid location is set in the hass configuration yaml
it will use that location and use it as default values.

Additional locations can be added in config form.
The input location will be checked by invoking
the API. Exception will be thrown if the location
is not supported by the API (Swedish locations only)
"""
"""Config flow to configure SMHI component."""
import voluptuous as vol

import homeassistant.helpers.config_validation as cv
from homeassistant import config_entries, data_entry_flow
from homeassistant.const import (CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME)
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import aiohttp_client
import homeassistant.helpers.config_validation as cv
from homeassistant.util import slugify

from .const import DOMAIN, HOME_LOCATION_NAME
Expand Down Expand Up @@ -45,9 +35,7 @@ async def async_step_user(self, user_input=None):

if user_input is not None:
is_ok = await self._check_location(
user_input[CONF_LONGITUDE],
user_input[CONF_LATITUDE]
)
user_input[CONF_LONGITUDE], user_input[CONF_LATITUDE])
if is_ok:
name = slugify(user_input[CONF_NAME])
if not self._name_in_configuration_exists(name):
Expand All @@ -60,9 +48,8 @@ async def async_step_user(self, user_input=None):
else:
self._errors['base'] = 'wrong_location'

# If hass config has the location set and
# is a valid coordinate the default location
# is set as default values in the form
# If hass config has the location set and is a valid coordinate the
# default location is set as default values in the form
if not smhi_locations(self.hass):
if await self._homeassistant_location_exists():
return await self._show_config_form(
Expand All @@ -79,8 +66,7 @@ async def _homeassistant_location_exists(self) -> bool:
self.hass.config.longitude != 0.0:
# Return true if valid location
if await self._check_location(
self.hass.config.longitude,
self.hass.config.latitude):
self.hass.config.longitude, self.hass.config.latitude):
return True
return False

Expand All @@ -90,9 +76,7 @@ def _name_in_configuration_exists(self, name: str) -> bool:
return True
return False

async def _show_config_form(self,
name: str = None,
latitude: str = None,
async def _show_config_form(self, name: str = None, latitude: str = None,
longitude: str = None):
"""Show the configuration form to edit location data."""
return self.async_show_form(
Expand Down
10 changes: 7 additions & 3 deletions homeassistant/components/smhi/const.py
@@ -1,12 +1,16 @@
"""Constants in smhi component."""
import logging
from homeassistant.components.weather import DOMAIN as WEATHER_DOMAIN

HOME_LOCATION_NAME = 'Home'
from homeassistant.components.weather import DOMAIN as WEATHER_DOMAIN

ATTR_SMHI_CLOUDINESS = 'cloudiness'

DOMAIN = 'smhi'
LOGGER = logging.getLogger('homeassistant.components.smhi')

HOME_LOCATION_NAME = 'Home'

ENTITY_ID_SENSOR_FORMAT = WEATHER_DOMAIN + ".smhi_{}"
ENTITY_ID_SENSOR_FORMAT_HOME = ENTITY_ID_SENSOR_FORMAT.format(
HOME_LOCATION_NAME)

LOGGER = logging.getLogger('homeassistant.components.smhi')
66 changes: 28 additions & 38 deletions homeassistant/components/weather/smhi.py
@@ -1,33 +1,28 @@
"""Support for the Swedish weather institute weather service.
"""
Support for the Swedish weather institute weather service.

For more details about this platform, please refer to the documentation
https://home-assistant.io/components/weather.smhi/
"""


import asyncio
import logging
from datetime import timedelta
import logging
from typing import Dict, List

import aiohttp
import async_timeout

from homeassistant.components.smhi.const import (
ATTR_SMHI_CLOUDINESS, ENTITY_ID_SENSOR_FORMAT)
from homeassistant.components.weather import (
ATTR_FORECAST_CONDITION, ATTR_FORECAST_PRECIPITATION, ATTR_FORECAST_TEMP,
ATTR_FORECAST_TEMP_LOW, ATTR_FORECAST_TIME, WeatherEntity)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONF_LATITUDE, CONF_LONGITUDE,
CONF_NAME, TEMP_CELSIUS)
CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME, TEMP_CELSIUS)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import aiohttp_client
from homeassistant.util import dt, slugify, Throttle

from homeassistant.components.weather import (
WeatherEntity, ATTR_FORECAST_CONDITION, ATTR_FORECAST_TEMP,
ATTR_FORECAST_TEMP_LOW, ATTR_FORECAST_TIME,
ATTR_FORECAST_PRECIPITATION)

from homeassistant.components.smhi.const import (
ENTITY_ID_SENSOR_FORMAT, ATTR_SMHI_CLOUDINESS)
from homeassistant.util import Throttle, dt, slugify

DEPENDENCIES = ['smhi']

Expand All @@ -51,15 +46,14 @@
'exceptional': [],
}


# 5 minutes between retrying connect to API again
RETRY_TIMEOUT = 5*60

MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=31)


async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
async def async_setup_platform(
hass, config, async_add_entities, discovery_info=None):
"""Old way of setting up components.

Can only be called when a user accidentally mentions smhi in the
Expand All @@ -68,18 +62,18 @@ async def async_setup_platform(hass, config, async_add_entities,
pass


async def async_setup_entry(hass: HomeAssistant,
config_entry: ConfigEntry,
config_entries) -> bool:
async def async_setup_entry(
hass: HomeAssistant, config_entry: ConfigEntry,
config_entries) -> bool:
"""Add a weather entity from map location."""
location = config_entry.data
name = slugify(location[CONF_NAME])

session = aiohttp_client.async_get_clientsession(hass)

entity = SmhiWeather(location[CONF_NAME], location[CONF_LATITUDE],
location[CONF_LONGITUDE],
session=session)
entity = SmhiWeather(
location[CONF_NAME], location[CONF_LATITUDE], location[CONF_LONGITUDE],
session=session)
entity.entity_id = ENTITY_ID_SENSOR_FORMAT.format(name)

config_entries([entity], True)
Expand All @@ -100,15 +94,15 @@ def __init__(self, name: str, latitude: str,
self._longitude = longitude
self._forecasts = None
self._fail_count = 0
self._smhi_api = Smhi(self._longitude, self._latitude,
session=session)
self._smhi_api = Smhi(self._longitude, self._latitude, session=session)

@Throttle(MIN_TIME_BETWEEN_UPDATES)
async def async_update(self) -> None:
"""Refresh the forecast data from SMHI weather API."""
from smhi.smhi_lib import SmhiForecastException

def fail():
"""Postpone updates."""
self._fail_count += 1
if self._fail_count < 3:
self.hass.helpers.event.async_call_later(
Expand All @@ -120,8 +114,8 @@ def fail():
self._fail_count = 0

except (asyncio.TimeoutError, SmhiForecastException):
_LOGGER.error("Failed to connect to SMHI API, "
"retry in 5 minutes")
_LOGGER.error(
"Failed to connect to SMHI API, retry in 5 minutes")
fail()

async def retry_update(self):
Expand Down Expand Up @@ -161,7 +155,7 @@ def wind_speed(self) -> float:
"""Return the wind speed."""
if self._forecasts is not None:
# Convert from m/s to km/h
return round(self._forecasts[0].wind_speed*18/5)
return round(self._forecasts[0].wind_speed * 18 / 5)
return None

@property
Expand Down Expand Up @@ -221,17 +215,13 @@ def forecast(self) -> List:
# Only get mid day forecasts
if forecast.valid_time.hour == 12:
data.append({
ATTR_FORECAST_TIME:
dt.as_local(forecast.valid_time),
ATTR_FORECAST_TEMP:
forecast.temperature_max,
ATTR_FORECAST_TEMP_LOW:
forecast.temperature_min,
ATTR_FORECAST_TIME: dt.as_local(forecast.valid_time),
ATTR_FORECAST_TEMP: forecast.temperature_max,
ATTR_FORECAST_TEMP_LOW: forecast.temperature_min,
ATTR_FORECAST_PRECIPITATION:
round(forecast.mean_precipitation*24),
ATTR_FORECAST_CONDITION:
condition
})
ATTR_FORECAST_CONDITION: condition,
})

return data

Expand Down