Skip to content

Commit

Permalink
GeoNet NZ Quakes feed integration (#25736)
Browse files Browse the repository at this point in the history
* initial working version

* support configured unit system and convert distance automatically

* properly unloading integration when removed and stopping refreshes

* ran isort

* fixed pylint

* introduced time filter of seven days into past

* adding unit tests

* fixed lint

* removed unused code

* added test case

* added test case for config flow

* fixed lint

* fixed comment

* removed unused test code

* increased test coverage

* fixed filtering by time

* changed wording in config flow

* reformatted with black

* removed unused logger

* fixed black

* changed default mmi

* reduced the options in the config flow form; fixed a few schema options and processing of data

* moved unsubscribing signals

* fixed minimum magnitude and modified tests

* fixed radius in imperial unit system

* increased test coverage

* simplified code

* fixed lint

* changed string formatting; simplified code

* removed unused strings

* added translation
  • Loading branch information
exxamalte authored and MartinHjelmare committed Aug 10, 2019
1 parent e685f07 commit 9e6732e
Show file tree
Hide file tree
Showing 15 changed files with 908 additions and 0 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Expand Up @@ -102,6 +102,7 @@ homeassistant/components/fronius/* @nielstron
homeassistant/components/frontend/* @home-assistant/frontend
homeassistant/components/gearbest/* @HerrHofrat
homeassistant/components/geniushub/* @zxdavb
homeassistant/components/geonetnz_quakes/* @exxamalte
homeassistant/components/gitter/* @fabaff
homeassistant/components/glances/* @fabaff
homeassistant/components/gntp/* @robbiet480
Expand Down
17 changes: 17 additions & 0 deletions homeassistant/components/geonetnz_quakes/.translations/en.json
@@ -0,0 +1,17 @@
{
"config": {
"error": {
"identifier_exists": "Location already registered"
},
"step": {
"user": {
"data": {
"mmi": "MMI",
"radius": "Radius"
},
"title": "Fill in your filter details."
}
},
"title": "GeoNet NZ Quakes"
}
}
101 changes: 101 additions & 0 deletions homeassistant/components/geonetnz_quakes/__init__.py
@@ -0,0 +1,101 @@
"""The GeoNet NZ Quakes integration."""
import voluptuous as vol

from homeassistant.config_entries import SOURCE_IMPORT
from homeassistant.const import (
CONF_LATITUDE,
CONF_LONGITUDE,
CONF_RADIUS,
CONF_SCAN_INTERVAL,
)
from homeassistant.helpers import config_validation as cv

from .config_flow import configured_instances
from .const import (
CONF_MINIMUM_MAGNITUDE,
CONF_MMI,
DEFAULT_MINIMUM_MAGNITUDE,
DEFAULT_MMI,
DEFAULT_RADIUS,
DEFAULT_SCAN_INTERVAL,
DOMAIN,
FEED,
)

CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.Schema(
{
vol.Optional(CONF_LATITUDE): cv.latitude,
vol.Optional(CONF_LONGITUDE): cv.longitude,
vol.Optional(CONF_MMI, default=DEFAULT_MMI): vol.All(
vol.Coerce(int), vol.Range(min=-1, max=8)
),
vol.Optional(CONF_RADIUS, default=DEFAULT_RADIUS): vol.Coerce(float),
vol.Optional(
CONF_MINIMUM_MAGNITUDE, default=DEFAULT_MINIMUM_MAGNITUDE
): vol.All(vol.Coerce(float), vol.Range(min=0)),
vol.Optional(
CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL
): cv.time_period,
}
)
},
extra=vol.ALLOW_EXTRA,
)


async def async_setup(hass, config):
"""Set up the GeoNet NZ Quakes component."""
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)
mmi = conf[CONF_MMI]
scan_interval = conf[CONF_SCAN_INTERVAL]

identifier = f"{latitude}, {longitude}"
if identifier in configured_instances(hass):
return True

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_MINIMUM_MAGNITUDE: conf[CONF_MINIMUM_MAGNITUDE],
CONF_MMI: mmi,
CONF_SCAN_INTERVAL: scan_interval,
},
)
)

return True


async def async_setup_entry(hass, config_entry):
"""Set up the GeoNet NZ Quakes component as config entry."""
hass.data[DOMAIN] = {}
hass.data[DOMAIN][FEED] = {}

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 GeoNet NZ Quakes component config entry."""
manager = hass.data[DOMAIN][FEED].pop(config_entry.entry_id)
await manager.async_stop()

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

return True
94 changes: 94 additions & 0 deletions homeassistant/components/geonetnz_quakes/config_flow.py
@@ -0,0 +1,94 @@
"""Config flow to configure the GeoNet NZ Quakes integration."""
import logging

import voluptuous as vol

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

from .const import (
CONF_MMI,
DEFAULT_MMI,
DEFAULT_RADIUS,
DEFAULT_SCAN_INTERVAL,
DOMAIN,
DEFAULT_MINIMUM_MAGNITUDE,
CONF_MINIMUM_MAGNITUDE,
)

_LOGGER = logging.getLogger(__name__)


@callback
def configured_instances(hass):
"""Return a set of configured GeoNet NZ Quakes instances."""
return set(
f"{entry.data[CONF_LATITUDE]}, {entry.data[CONF_LONGITUDE]}"
for entry in hass.config_entries.async_entries(DOMAIN)
)


@config_entries.HANDLERS.register(DOMAIN)
class GeonetnzQuakesFlowHandler(config_entries.ConfigFlow):
"""Handle a GeoNet NZ Quakes config flow."""

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_MMI, default=DEFAULT_MMI): vol.All(
vol.Coerce(int), vol.Range(min=-1, max=8)
),
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."""
_LOGGER.debug("User input: %s", user_input)
if not user_input:
return await self._show_form()

latitude = user_input.get(CONF_LATITUDE, self.hass.config.latitude)
user_input[CONF_LATITUDE] = latitude
longitude = user_input.get(CONF_LONGITUDE, self.hass.config.longitude)
user_input[CONF_LONGITUDE] = longitude

identifier = f"{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

scan_interval = user_input.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
user_input[CONF_SCAN_INTERVAL] = scan_interval.seconds

minimum_magnitude = user_input.get(
CONF_MINIMUM_MAGNITUDE, DEFAULT_MINIMUM_MAGNITUDE
)
user_input[CONF_MINIMUM_MAGNITUDE] = minimum_magnitude

return self.async_create_entry(title=identifier, data=user_input)
14 changes: 14 additions & 0 deletions homeassistant/components/geonetnz_quakes/const.py
@@ -0,0 +1,14 @@
"""Define constants for the GeoNet NZ Quakes integration."""
from datetime import timedelta

DOMAIN = "geonetnz_quakes"

CONF_MINIMUM_MAGNITUDE = "minimum_magnitude"
CONF_MMI = "mmi"

FEED = "feed"

DEFAULT_MINIMUM_MAGNITUDE = 0.0
DEFAULT_MMI = 3
DEFAULT_RADIUS = 50.0
DEFAULT_SCAN_INTERVAL = timedelta(minutes=5)

0 comments on commit 9e6732e

Please sign in to comment.