Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,8 @@ omit =
homeassistant/components/worldtidesinfo/sensor.py
homeassistant/components/worxlandroid/sensor.py
homeassistant/components/wunderlist/*
homeassistant/components/wwlln/__init__.py
homeassistant/components/wwlln/geo_location.py
homeassistant/components/x10/light.py
homeassistant/components/xbox_live/sensor.py
homeassistant/components/xeoma/camera.py
Expand Down
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ homeassistant/components/weblink/* @home-assistant/core
homeassistant/components/websocket_api/* @home-assistant/core
homeassistant/components/wemo/* @sqldiablo
homeassistant/components/worldclock/* @fabaff
homeassistant/components/wwlln/* @bachya
homeassistant/components/xfinity/* @cisasteelersfan
homeassistant/components/xiaomi_aqara/* @danielhiversen @syssi
homeassistant/components/xiaomi_miio/* @rytilahti @syssi
Expand Down
18 changes: 18 additions & 0 deletions homeassistant/components/wwlln/.translations/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"config": {
"error": {
"identifier_exists": "Location already registered"
},
"step": {
"user": {
"data": {
"latitude": "Latitude",
"longitude": "Longitude",
"radius": "Radius (using your base unit system)"
},
"title": "Fill in your location information."
}
},
"title": "World Wide Lightning Location Network (WWLLN)"
}
}
87 changes: 87 additions & 0 deletions homeassistant/components/wwlln/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""Support for World Wide Lightning Location Network."""
import logging

from aiowwlln import Client
import voluptuous as vol

from homeassistant.config_entries import SOURCE_IMPORT
from homeassistant.const import (
CONF_LATITUDE, CONF_LONGITUDE, CONF_RADIUS, CONF_UNIT_SYSTEM,
CONF_UNIT_SYSTEM_IMPERIAL, CONF_UNIT_SYSTEM_METRIC)
from homeassistant.helpers import aiohttp_client, config_validation as cv

from .config_flow import configured_instances
from .const import (
CONF_WINDOW, DATA_CLIENT, DEFAULT_RADIUS, DEFAULT_WINDOW, DOMAIN)

_LOGGER = logging.getLogger(__name__)

CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Optional(CONF_LATITUDE): cv.latitude,
vol.Optional(CONF_LONGITUDE): cv.longitude,
vol.Optional(CONF_RADIUS, default=DEFAULT_RADIUS): cv.positive_int,
vol.Optional(CONF_WINDOW, default=DEFAULT_WINDOW):
vol.All(cv.time_period, cv.positive_timedelta)
})
}, extra=vol.ALLOW_EXTRA)


async def async_setup(hass, config):
"""Set up the WWLLN component."""
hass.data[DOMAIN] = {}
hass.data[DOMAIN][DATA_CLIENT] = {}

if DOMAIN not in config:
return True

conf = config[DOMAIN]

latitude = conf.get(CONF_LATITUDE, hass.config.latitude)
longitude = conf.get(CONF_LONGITUDE, hass.config.longitude)

identifier = '{0}, {1}'.format(latitude, longitude)
if identifier in configured_instances(hass):
return True

if hass.config.units.name == CONF_UNIT_SYSTEM_IMPERIAL:
unit_system = CONF_UNIT_SYSTEM_IMPERIAL
else:
unit_system = CONF_UNIT_SYSTEM_METRIC

hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={'source': SOURCE_IMPORT},
data={
CONF_LATITUDE: latitude,
CONF_LONGITUDE: longitude,
CONF_RADIUS: conf[CONF_RADIUS],
CONF_WINDOW: conf[CONF_WINDOW],
CONF_UNIT_SYSTEM: unit_system,
}))

return True


async def async_setup_entry(hass, config_entry):
"""Set up the WWLLN as config entry."""
websession = aiohttp_client.async_get_clientsession(hass)

hass.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] = Client(websession)

hass.async_create_task(
hass.config_entries.async_forward_entry_setup(
config_entry, 'geo_location'))

return True


async def async_unload_entry(hass, config_entry):
"""Unload an WWLLN config entry."""
hass.data[DOMAIN][DATA_CLIENT].pop(config_entry.entry_id)

await hass.config_entries.async_forward_entry_unload(
config_entry, 'geo_location')

return True
70 changes: 70 additions & 0 deletions homeassistant/components/wwlln/config_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""Config flow to configure the WWLLN integration."""
import voluptuous as vol

from homeassistant import config_entries
from homeassistant.helpers import config_validation as cv
from homeassistant.const import (
CONF_LATITUDE, CONF_LONGITUDE, CONF_RADIUS, CONF_UNIT_SYSTEM,
CONF_UNIT_SYSTEM_IMPERIAL, CONF_UNIT_SYSTEM_METRIC)
from homeassistant.core import callback

from .const import CONF_WINDOW, DEFAULT_RADIUS, DEFAULT_WINDOW, DOMAIN


@callback
def configured_instances(hass):
"""Return a set of configured WWLLN instances."""
return set(
'{0}, {1}'.format(
entry.data[CONF_LATITUDE], entry.data[CONF_LONGITUDE])
for entry in hass.config_entries.async_entries(DOMAIN)
)


@config_entries.HANDLERS.register(DOMAIN)
class WWLLNFlowHandler(config_entries.ConfigFlow):
"""Handle a WWLLN config flow."""

VERSION = 1
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL

async def _show_form(self, errors=None):
"""Show the form to the user."""
data_schema = vol.Schema({
vol.Optional(CONF_LATITUDE, default=self.hass.config.latitude):
cv.latitude,
vol.Optional(CONF_LONGITUDE, default=self.hass.config.longitude):
cv.longitude,
vol.Optional(CONF_RADIUS, default=DEFAULT_RADIUS): cv.positive_int,
})

return self.async_show_form(
step_id="user", data_schema=data_schema, errors=errors or {})

async def async_step_import(self, import_config):
"""Import a config entry from configuration.yaml."""
return await self.async_step_user(import_config)

async def async_step_user(self, user_input=None):
"""Handle the start of the config flow."""
if not user_input:
return await self._show_form()

identifier = '{0}, {1}'.format(
user_input[CONF_LATITUDE], user_input[CONF_LONGITUDE])
if identifier in configured_instances(self.hass):
return await self._show_form({'base': 'identifier_exists'})

if self.hass.config.units.name == CONF_UNIT_SYSTEM_IMPERIAL:
user_input[CONF_UNIT_SYSTEM] = CONF_UNIT_SYSTEM_IMPERIAL
else:
user_input[CONF_UNIT_SYSTEM] = CONF_UNIT_SYSTEM_METRIC

# To simplify things, we don't allow users of the config flow to
# input a window; instead, we make a sane assumption to use the
# default (stored as seconds, since timedelta's aren't
# JSON-serializable):
if CONF_WINDOW not in user_input:
user_input[CONF_WINDOW] = DEFAULT_WINDOW.total_seconds()

return self.async_create_entry(title=identifier, data=user_input)
11 changes: 11 additions & 0 deletions homeassistant/components/wwlln/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""Define constants for the WWLLN integration."""
from datetime import timedelta

DOMAIN = 'wwlln'

CONF_WINDOW = 'window'

DATA_CLIENT = 'client'

DEFAULT_RADIUS = 25
DEFAULT_WINDOW = timedelta(minutes=10)
Loading