1
mirror of https://github.com/home-assistant/core synced 2024-09-12 15:16:21 +02:00

Fix smhi docstrings (#18414)

* Fix docstrings

* Fix lint

* Fix another typo

* Fix mobile phone edit
This commit is contained in:
Fabian Affolter 2018-11-13 10:01:14 +01:00 committed by Martin Hjelmare
parent f78dcb96b0
commit 7113ec6073
4 changed files with 51 additions and 74 deletions

View File

@ -1,5 +1,5 @@
""" """
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 For more details about this component, please refer to the documentation at
https://home-assistant.io/components/smhi/ https://home-assistant.io/components/smhi/
@ -7,8 +7,7 @@ https://home-assistant.io/components/smhi/
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import Config, HomeAssistant from homeassistant.core import Config, HomeAssistant
# Have to import for config_flow to work # Have to import for config_flow to work even if they are not used here
# even if they are not used here
from .config_flow import smhi_locations # noqa: F401 from .config_flow import smhi_locations # noqa: F401
from .const import DOMAIN # noqa: F401 from .const import DOMAIN # noqa: F401
@ -18,21 +17,21 @@ DEFAULT_NAME = 'smhi'
async def async_setup(hass: HomeAssistant, config: Config) -> bool: 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 # We allow setup only through config flow type of config
return True return True
async def async_setup_entry(hass: HomeAssistant, async def async_setup_entry(
config_entry: ConfigEntry) -> bool: hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Set up smhi forecast as config entry.""" """Set up SMHI forecast as config entry."""
hass.async_create_task(hass.config_entries.async_forward_entry_setup( hass.async_create_task(hass.config_entries.async_forward_entry_setup(
config_entry, 'weather')) config_entry, 'weather'))
return True return True
async def async_unload_entry(hass: HomeAssistant, async def async_unload_entry(
config_entry: ConfigEntry) -> bool: hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Unload a config entry.""" """Unload a config entry."""
await hass.config_entries.async_forward_entry_unload( await hass.config_entries.async_forward_entry_unload(
config_entry, 'weather') config_entry, 'weather')

View File

@ -1,21 +1,11 @@
"""Config flow to configure smhi component. """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)
"""
import voluptuous as vol import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant import config_entries, data_entry_flow 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.core import HomeAssistant, callback
from homeassistant.helpers import aiohttp_client from homeassistant.helpers import aiohttp_client
import homeassistant.helpers.config_validation as cv
from homeassistant.util import slugify from homeassistant.util import slugify
from .const import DOMAIN, HOME_LOCATION_NAME from .const import DOMAIN, HOME_LOCATION_NAME
@ -45,9 +35,7 @@ class SmhiFlowHandler(data_entry_flow.FlowHandler):
if user_input is not None: if user_input is not None:
is_ok = await self._check_location( is_ok = await self._check_location(
user_input[CONF_LONGITUDE], user_input[CONF_LONGITUDE], user_input[CONF_LATITUDE])
user_input[CONF_LATITUDE]
)
if is_ok: if is_ok:
name = slugify(user_input[CONF_NAME]) name = slugify(user_input[CONF_NAME])
if not self._name_in_configuration_exists(name): if not self._name_in_configuration_exists(name):
@ -60,9 +48,8 @@ class SmhiFlowHandler(data_entry_flow.FlowHandler):
else: else:
self._errors['base'] = 'wrong_location' self._errors['base'] = 'wrong_location'
# If hass config has the location set and # If hass config has the location set and is a valid coordinate the
# is a valid coordinate the default location # default location is set as default values in the form
# is set as default values in the form
if not smhi_locations(self.hass): if not smhi_locations(self.hass):
if await self._homeassistant_location_exists(): if await self._homeassistant_location_exists():
return await self._show_config_form( return await self._show_config_form(
@ -79,8 +66,7 @@ class SmhiFlowHandler(data_entry_flow.FlowHandler):
self.hass.config.longitude != 0.0: self.hass.config.longitude != 0.0:
# Return true if valid location # Return true if valid location
if await self._check_location( if await self._check_location(
self.hass.config.longitude, self.hass.config.longitude, self.hass.config.latitude):
self.hass.config.latitude):
return True return True
return False return False
@ -90,9 +76,7 @@ class SmhiFlowHandler(data_entry_flow.FlowHandler):
return True return True
return False return False
async def _show_config_form(self, async def _show_config_form(self, name: str = None, latitude: str = None,
name: str = None,
latitude: str = None,
longitude: str = None): longitude: str = None):
"""Show the configuration form to edit location data.""" """Show the configuration form to edit location data."""
return self.async_show_form( return self.async_show_form(

View File

@ -1,12 +1,16 @@
"""Constants in smhi component.""" """Constants in smhi component."""
import logging import logging
from homeassistant.components.weather import DOMAIN as WEATHER_DOMAIN from homeassistant.components.weather import DOMAIN as WEATHER_DOMAIN
ATTR_SMHI_CLOUDINESS = 'cloudiness'
DOMAIN = 'smhi'
HOME_LOCATION_NAME = 'Home' HOME_LOCATION_NAME = 'Home'
ATTR_SMHI_CLOUDINESS = 'cloudiness'
DOMAIN = 'smhi'
LOGGER = logging.getLogger('homeassistant.components.smhi')
ENTITY_ID_SENSOR_FORMAT = WEATHER_DOMAIN + ".smhi_{}" ENTITY_ID_SENSOR_FORMAT = WEATHER_DOMAIN + ".smhi_{}"
ENTITY_ID_SENSOR_FORMAT_HOME = ENTITY_ID_SENSOR_FORMAT.format( ENTITY_ID_SENSOR_FORMAT_HOME = ENTITY_ID_SENSOR_FORMAT.format(
HOME_LOCATION_NAME) HOME_LOCATION_NAME)
LOGGER = logging.getLogger('homeassistant.components.smhi')

View File

@ -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 For more details about this platform, please refer to the documentation
https://home-assistant.io/components/weather.smhi/ https://home-assistant.io/components/weather.smhi/
""" """
import asyncio import asyncio
import logging
from datetime import timedelta from datetime import timedelta
import logging
from typing import Dict, List from typing import Dict, List
import aiohttp import aiohttp
import async_timeout 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.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
CONF_LATITUDE, CONF_LONGITUDE, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME, TEMP_CELSIUS)
CONF_NAME, TEMP_CELSIUS)
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import aiohttp_client from homeassistant.helpers import aiohttp_client
from homeassistant.util import dt, slugify, Throttle from homeassistant.util import Throttle, dt, slugify
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)
DEPENDENCIES = ['smhi'] DEPENDENCIES = ['smhi']
@ -51,15 +46,14 @@ CONDITION_CLASSES = {
'exceptional': [], 'exceptional': [],
} }
# 5 minutes between retrying connect to API again # 5 minutes between retrying connect to API again
RETRY_TIMEOUT = 5*60 RETRY_TIMEOUT = 5*60
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=31) MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=31)
async def async_setup_platform(hass, config, async_add_entities, async def async_setup_platform(
discovery_info=None): hass, config, async_add_entities, discovery_info=None):
"""Old way of setting up components. """Old way of setting up components.
Can only be called when a user accidentally mentions smhi in the Can only be called when a user accidentally mentions smhi in the
@ -68,18 +62,18 @@ async def async_setup_platform(hass, config, async_add_entities,
pass pass
async def async_setup_entry(hass: HomeAssistant, async def async_setup_entry(
config_entry: ConfigEntry, hass: HomeAssistant, config_entry: ConfigEntry,
config_entries) -> bool: config_entries) -> bool:
"""Add a weather entity from map location.""" """Add a weather entity from map location."""
location = config_entry.data location = config_entry.data
name = slugify(location[CONF_NAME]) name = slugify(location[CONF_NAME])
session = aiohttp_client.async_get_clientsession(hass) session = aiohttp_client.async_get_clientsession(hass)
entity = SmhiWeather(location[CONF_NAME], location[CONF_LATITUDE], entity = SmhiWeather(
location[CONF_LONGITUDE], location[CONF_NAME], location[CONF_LATITUDE], location[CONF_LONGITUDE],
session=session) session=session)
entity.entity_id = ENTITY_ID_SENSOR_FORMAT.format(name) entity.entity_id = ENTITY_ID_SENSOR_FORMAT.format(name)
config_entries([entity], True) config_entries([entity], True)
@ -100,8 +94,7 @@ class SmhiWeather(WeatherEntity):
self._longitude = longitude self._longitude = longitude
self._forecasts = None self._forecasts = None
self._fail_count = 0 self._fail_count = 0
self._smhi_api = Smhi(self._longitude, self._latitude, self._smhi_api = Smhi(self._longitude, self._latitude, session=session)
session=session)
@Throttle(MIN_TIME_BETWEEN_UPDATES) @Throttle(MIN_TIME_BETWEEN_UPDATES)
async def async_update(self) -> None: async def async_update(self) -> None:
@ -109,6 +102,7 @@ class SmhiWeather(WeatherEntity):
from smhi.smhi_lib import SmhiForecastException from smhi.smhi_lib import SmhiForecastException
def fail(): def fail():
"""Postpone updates."""
self._fail_count += 1 self._fail_count += 1
if self._fail_count < 3: if self._fail_count < 3:
self.hass.helpers.event.async_call_later( self.hass.helpers.event.async_call_later(
@ -120,8 +114,8 @@ class SmhiWeather(WeatherEntity):
self._fail_count = 0 self._fail_count = 0
except (asyncio.TimeoutError, SmhiForecastException): except (asyncio.TimeoutError, SmhiForecastException):
_LOGGER.error("Failed to connect to SMHI API, " _LOGGER.error(
"retry in 5 minutes") "Failed to connect to SMHI API, retry in 5 minutes")
fail() fail()
async def retry_update(self): async def retry_update(self):
@ -161,7 +155,7 @@ class SmhiWeather(WeatherEntity):
"""Return the wind speed.""" """Return the wind speed."""
if self._forecasts is not None: if self._forecasts is not None:
# Convert from m/s to km/h # 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 return None
@property @property
@ -221,17 +215,13 @@ class SmhiWeather(WeatherEntity):
# Only get mid day forecasts # Only get mid day forecasts
if forecast.valid_time.hour == 12: if forecast.valid_time.hour == 12:
data.append({ data.append({
ATTR_FORECAST_TIME: ATTR_FORECAST_TIME: dt.as_local(forecast.valid_time),
dt.as_local(forecast.valid_time), ATTR_FORECAST_TEMP: forecast.temperature_max,
ATTR_FORECAST_TEMP: ATTR_FORECAST_TEMP_LOW: forecast.temperature_min,
forecast.temperature_max,
ATTR_FORECAST_TEMP_LOW:
forecast.temperature_min,
ATTR_FORECAST_PRECIPITATION: ATTR_FORECAST_PRECIPITATION:
round(forecast.mean_precipitation*24), round(forecast.mean_precipitation*24),
ATTR_FORECAST_CONDITION: ATTR_FORECAST_CONDITION: condition,
condition })
})
return data return data