From 559f63bfc347ef3d25a6c9fb38168b51fbfbe5ef Mon Sep 17 00:00:00 2001 From: happyleaves Date: Tue, 27 Sep 2016 16:30:26 -0400 Subject: [PATCH 001/112] bump limitlessled version --- homeassistant/components/light/limitlessled.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py index aac28f9ced8ef..17bfb88706360 100644 --- a/homeassistant/components/light/limitlessled.py +++ b/homeassistant/components/light/limitlessled.py @@ -14,7 +14,7 @@ SUPPORT_RGB_COLOR, SUPPORT_TRANSITION, Light) _LOGGER = logging.getLogger(__name__) -REQUIREMENTS = ['limitlessled==1.0.0'] +REQUIREMENTS = ['limitlessled==1.0.2'] RGB_BOUNDARY = 40 DEFAULT_TRANSITION = 0 DEFAULT_PORT = 8899 diff --git a/requirements_all.txt b/requirements_all.txt index c0ef98ffdc162..90d729e3b9505 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -225,7 +225,7 @@ liffylights==0.9.4 lightify==1.0.3 # homeassistant.components.light.limitlessled -limitlessled==1.0.0 +limitlessled==1.0.2 # homeassistant.components.notify.message_bird messagebird==1.2.0 From 9780ea5c52271f7ecf8c3c2927e11c5643ac348a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 28 Sep 2016 21:20:47 -0700 Subject: [PATCH 002/112] Version bump to 0.29 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 872f60562cddf..8b18b808d797a 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 29 -PATCH_VERSION = '0.dev0' +PATCH_VERSION = '0' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 4, 2) From 6e80581b307241c44d341aba2d87e895944abc9f Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 28 Sep 2016 21:21:03 -0700 Subject: [PATCH 003/112] Version bump to 0.30.0.dev0 --- homeassistant/const.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 8b18b808d797a..c50a9b7dc4fff 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,8 +1,8 @@ # coding: utf-8 """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 -MINOR_VERSION = 29 -PATCH_VERSION = '0' +MINOR_VERSION = 30 +PATCH_VERSION = '0.dev0' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 4, 2) From 48ffdea31f7346021d7d88a21a245e08d1ab1603 Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Thu, 29 Sep 2016 01:07:23 -0400 Subject: [PATCH 004/112] Fixed typo (#3569) Sep 29 00:59:22 pi hass[21333]: if self.device.measurment_scale == 'F': Sep 29 00:59:22 pi hass[21333]: AttributeError: 'Device' object has no attribute 'measurment_scale' --- homeassistant/components/climate/nest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/climate/nest.py b/homeassistant/components/climate/nest.py index 91e5f5824e9df..10abf812116d9 100644 --- a/homeassistant/components/climate/nest.py +++ b/homeassistant/components/climate/nest.py @@ -57,7 +57,7 @@ def name(self): @property def unit_of_measurement(self): """Return the unit of measurement.""" - if self.device.measurment_scale == 'F': + if self.device.measurement_scale == 'F': return TEMP_FAHRENHEIT elif self.device.measurement_scale == 'C': return TEMP_CELSIUS From abd1213cc4904dae224380ef3c50aadaccb3f50c Mon Sep 17 00:00:00 2001 From: pavoni Date: Thu, 29 Sep 2016 09:55:05 +0100 Subject: [PATCH 005/112] Bump library to catch more exceptions in poll thread. --- homeassistant/components/sensor/loopenergy.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/sensor/loopenergy.py b/homeassistant/components/sensor/loopenergy.py index 04a1d946d45f0..bc295c3a1057e 100644 --- a/homeassistant/components/sensor/loopenergy.py +++ b/homeassistant/components/sensor/loopenergy.py @@ -15,7 +15,7 @@ _LOGGER = logging.getLogger(__name__) -REQUIREMENTS = ['pyloopenergy==0.0.14'] +REQUIREMENTS = ['pyloopenergy==0.0.15'] CONF_ELEC = 'electricity' CONF_GAS = 'gas' diff --git a/requirements_all.txt b/requirements_all.txt index 0a3f4607a6bca..640931ceb89ce 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -340,7 +340,7 @@ pyicloud==0.9.1 pylast==1.6.0 # homeassistant.components.sensor.loopenergy -pyloopenergy==0.0.14 +pyloopenergy==0.0.15 # homeassistant.components.device_tracker.netgear pynetgear==0.3.3 From 7d86fb8c7281a6c3259fd147252cf11d96b1750a Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Thu, 29 Sep 2016 16:45:25 +0200 Subject: [PATCH 006/112] Remove duplicate port entry (fixes #3583) (#3584) --- homeassistant/components/influxdb.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/homeassistant/components/influxdb.py b/homeassistant/components/influxdb.py index 2f6be852ceadf..1ce137ffc9145 100644 --- a/homeassistant/components/influxdb.py +++ b/homeassistant/components/influxdb.py @@ -38,8 +38,7 @@ vol.All(cv.ensure_list, [cv.entity_id]), vol.Optional(CONF_DB_NAME, default=DEFAULT_DATABASE): cv.string, vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, - vol.Optional(CONF_PORT, default=False): cv.boolean, - vol.Optional(CONF_SSL, default=False): cv.boolean, + vol.Optional(CONF_SSL, default=DEFAULT_SSL): cv.boolean, vol.Optional(CONF_TAGS, default={}): vol.Schema({cv.string: cv.string}), vol.Optional(CONF_WHITELIST, default=[]): From dd551cf056ec3743d62220f9eca569f177506d18 Mon Sep 17 00:00:00 2001 From: Hugo Dupras Date: Thu, 29 Sep 2016 16:45:54 +0200 Subject: [PATCH 007/112] Netatmo: Hotfix for hass 0.29 (#3576) Signed-off-by: Hugo D. (jabesq) --- homeassistant/components/camera/netatmo.py | 10 +++++++--- homeassistant/components/sensor/netatmo.py | 9 ++++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/camera/netatmo.py b/homeassistant/components/camera/netatmo.py index 457c63d1ad783..9069a5c6c2853 100644 --- a/homeassistant/components/camera/netatmo.py +++ b/homeassistant/components/camera/netatmo.py @@ -36,10 +36,14 @@ def setup_platform(hass, config, add_devices, discovery_info=None): """Setup access to Netatmo Welcome cameras.""" netatmo = get_component('netatmo') home = config.get(CONF_HOME) - data = WelcomeData(netatmo.NETATMO_AUTH, home) + import lnetatmo + try: + data = WelcomeData(netatmo.NETATMO_AUTH, home) + except lnetatmo.NoDevice: + return None for camera_name in data.get_camera_names(): - if CONF_CAMERAS in config: + if config[CONF_CAMERAS] != []: if camera_name not in config[CONF_CAMERAS]: continue add_devices([WelcomeCamera(data, camera_name, home)]) @@ -49,7 +53,7 @@ class WelcomeCamera(Camera): """Representation of the images published from Welcome camera.""" def __init__(self, data, camera_name, home): - """Setup for access to the BloomSky camera images.""" + """Setup for access to the Netatmo camera images.""" super(WelcomeCamera, self).__init__() self._data = data self._camera_name = camera_name diff --git a/homeassistant/components/sensor/netatmo.py b/homeassistant/components/sensor/netatmo.py index c3588e2485373..be8f2e7d76d3b 100644 --- a/homeassistant/components/sensor/netatmo.py +++ b/homeassistant/components/sensor/netatmo.py @@ -21,7 +21,6 @@ ATTR_MODULE = 'modules' CONF_MODULES = 'modules' -CONF_MODULE_NAME = 'module_name' CONF_STATION = 'station' DEPENDENCIES = ['netatmo'] @@ -50,7 +49,7 @@ } MODULE_SCHEMA = vol.Schema({ - vol.Required(CONF_MODULE_NAME, default=[]): + vol.Required(cv.string, default=[]): vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]), }) @@ -84,11 +83,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None): # pylint: disable=too-few-public-methods class NetAtmoSensor(Entity): - """Implementation of a NetAtmo sensor.""" + """Implementation of a Netatmo sensor.""" def __init__(self, netatmo_data, module_name, sensor_type): """Initialize the sensor.""" - self._name = 'NetAtmo {} {}'.format(module_name, + self._name = 'Netatmo {} {}'.format(module_name, SENSOR_TYPES[sensor_type][0]) self.netatmo_data = netatmo_data self.module_name = module_name @@ -232,7 +231,7 @@ def get_module_names(self): @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): - """Call the NetAtmo API to update the data.""" + """Call the Netatmo API to update the data.""" import lnetatmo dev_list = lnetatmo.DeviceList(self.auth) From 08bacd8e310c03949a598f72308e474f647a5531 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Thu, 29 Sep 2016 18:06:41 +0200 Subject: [PATCH 008/112] Bugfix voluptuous for hue (#3589) --- homeassistant/components/light/hue.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/light/hue.py b/homeassistant/components/light/hue.py index 767cd1855ae82..ce2ae7b54f71a 100644 --- a/homeassistant/components/light/hue.py +++ b/homeassistant/components/light/hue.py @@ -50,7 +50,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_HOST): cv.string, vol.Optional(CONF_ALLOW_UNREACHABLE): cv.boolean, - vol.Optional(CONF_FILENAME): cv.isfile, + vol.Optional(CONF_FILENAME): cv.string, }) From 01435f7f424c439944b70782011b380c8a97da96 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Fri, 30 Sep 2016 03:36:20 +0200 Subject: [PATCH 009/112] Bugfix voluptuous acer_projector (#3598) --- homeassistant/components/switch/acer_projector.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/switch/acer_projector.py b/homeassistant/components/switch/acer_projector.py index 5845e611c319e..7817a127642ef 100644 --- a/homeassistant/components/switch/acer_projector.py +++ b/homeassistant/components/switch/acer_projector.py @@ -4,6 +4,7 @@ For more details about this component, please refer to the documentation at https://home-assistant.io/components/switch.acer_projector/ """ +import os import logging import re @@ -45,8 +46,18 @@ STATE_ON: '* 0 IR 001\r', STATE_OFF: '* 0 IR 002\r'} + +def isdevice(dev): + """Check if dev a real device.""" + try: + os.stat(dev) + return str(dev) + except OSError: + raise vol.Invalid("No device found!") + + PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ - vol.Required(CONF_FILENAME): cv.isfile, + vol.Required(CONF_FILENAME): isdevice, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int, vol.Optional(CONF_WRITE_TIMEOUT, default=DEFAULT_WRITE_TIMEOUT): From 733120c5772425a2184b59c4447c88cff20146eb Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 29 Sep 2016 18:45:55 -0700 Subject: [PATCH 010/112] Fix voluptuous alexa config (#3596) --- homeassistant/components/alexa.py | 2 +- tests/components/test_alexa.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/alexa.py b/homeassistant/components/alexa.py index e1b860e95c3c9..94d5b24cbf009 100644 --- a/homeassistant/components/alexa.py +++ b/homeassistant/components/alexa.py @@ -63,7 +63,7 @@ class CardType(enum.Enum): } } } -}) +}, extra=vol.ALLOW_EXTRA) def setup(hass, config): diff --git a/tests/components/test_alexa.py b/tests/components/test_alexa.py index 0c0a30dc71864..a40b401c77709 100644 --- a/tests/components/test_alexa.py +++ b/tests/components/test_alexa.py @@ -41,6 +41,8 @@ def setUpModule(): # pylint: disable=invalid-name hass.services.register('test', 'alexa', lambda call: calls.append(call)) bootstrap.setup_component(hass, alexa.DOMAIN, { + # Key is here to verify we allow other keys in config too + 'homeassistant': {}, 'alexa': { 'intents': { 'WhereAreWeIntent': { From 68028afb98d41ec705cd529497da6902fd43176a Mon Sep 17 00:00:00 2001 From: Dan Cinnamon Date: Thu, 29 Sep 2016 20:55:43 -0500 Subject: [PATCH 011/112] Passing original config reference to load_platform. (#3602) --- homeassistant/components/envisalink.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/envisalink.py b/homeassistant/components/envisalink.py index 3e947e55a4d3b..0572de9aba60a 100644 --- a/homeassistant/components/envisalink.py +++ b/homeassistant/components/envisalink.py @@ -184,13 +184,13 @@ def start_envisalink(event): load_platform(hass, 'alarm_control_panel', 'envisalink', {CONF_PARTITIONS: _partitions, CONF_CODE: _code, - CONF_PANIC: _panic_type}, config) + CONF_PANIC: _panic_type}, base_config) load_platform(hass, 'sensor', 'envisalink', {CONF_PARTITIONS: _partitions, - CONF_CODE: _code}, config) + CONF_CODE: _code}, base_config) if _zones: load_platform(hass, 'binary_sensor', 'envisalink', - {CONF_ZONES: _zones}, config) + {CONF_ZONES: _zones}, base_config) return True From a7266ae6cfbc02947ff99d16b19b938d5e6d2fd0 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 30 Sep 2016 04:02:22 +0200 Subject: [PATCH 012/112] Check that no configuration is provided (#3553) --- homeassistant/components/conversation.py | 13 ++++++--- homeassistant/components/discovery.py | 6 +++++ homeassistant/components/introduction.py | 6 +++++ homeassistant/components/sun.py | 34 ++++++++++++++++-------- homeassistant/components/updater.py | 29 ++++++++++++-------- homeassistant/components/upnp.py | 22 ++++++++------- homeassistant/components/zeroconf.py | 31 ++++++++++++--------- tests/components/test_updater.py | 18 ++++++------- 8 files changed, 101 insertions(+), 58 deletions(-) diff --git a/homeassistant/components/conversation.py b/homeassistant/components/conversation.py index 2a9a55d289ac3..b688e3d7082d9 100644 --- a/homeassistant/components/conversation.py +++ b/homeassistant/components/conversation.py @@ -29,6 +29,10 @@ vol.Required(ATTR_TEXT): vol.All(cv.string, vol.Lower), }) +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({}), +}, extra=vol.ALLOW_EXTRA) + def setup(hass, config): """Register the process service.""" @@ -48,8 +52,8 @@ def process(service): name, command = match.groups() entities = {state.entity_id: state.name for state in hass.states.all()} - entity_ids = fuzzyExtract.extractOne(name, entities, - score_cutoff=65)[2] + entity_ids = fuzzyExtract.extractOne( + name, entities, score_cutoff=65)[2] if not entity_ids: logger.error( @@ -70,6 +74,7 @@ def process(service): logger.error('Got unsupported command %s from text %s', command, text) - hass.services.register(DOMAIN, SERVICE_PROCESS, process, - schema=SERVICE_PROCESS_SCHEMA) + hass.services.register( + DOMAIN, SERVICE_PROCESS, process, schema=SERVICE_PROCESS_SCHEMA) + return True diff --git a/homeassistant/components/discovery.py b/homeassistant/components/discovery.py index 0ac40c00f9048..fa48be04e74d5 100644 --- a/homeassistant/components/discovery.py +++ b/homeassistant/components/discovery.py @@ -9,6 +9,8 @@ import logging import threading +import voluptuous as vol + from homeassistant.const import EVENT_HOMEASSISTANT_START from homeassistant.helpers.discovery import load_platform, discover @@ -33,6 +35,10 @@ 'directv': ('media_player', 'directv'), } +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({}), +}, extra=vol.ALLOW_EXTRA) + def setup(hass, config): """Start a discovery service.""" diff --git a/homeassistant/components/introduction.py b/homeassistant/components/introduction.py index 59e6e7a2f3dbf..afbcca14253cc 100644 --- a/homeassistant/components/introduction.py +++ b/homeassistant/components/introduction.py @@ -6,8 +6,14 @@ """ import logging +import voluptuous as vol + DOMAIN = 'introduction' +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({}), +}, extra=vol.ALLOW_EXTRA) + def setup(hass, config=None): """Setup the introduction component.""" diff --git a/homeassistant/components/sun.py b/homeassistant/components/sun.py index 4b2cd10b78178..858d49a8e4388 100644 --- a/homeassistant/components/sun.py +++ b/homeassistant/components/sun.py @@ -7,26 +7,38 @@ import logging from datetime import timedelta -import homeassistant.util as util +import voluptuous as vol + +from homeassistant.const import CONF_ELEVATION from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import ( track_point_in_utc_time, track_utc_time_change) from homeassistant.util import dt as dt_util -from homeassistant.const import CONF_ELEVATION +import homeassistant.helpers.config_validation as cv +import homeassistant.util as util + REQUIREMENTS = ['astral==1.2'] -DOMAIN = "sun" -ENTITY_ID = "sun.sun" -STATE_ABOVE_HORIZON = "above_horizon" -STATE_BELOW_HORIZON = "below_horizon" +_LOGGER = logging.getLogger(__name__) -STATE_ATTR_NEXT_RISING = "next_rising" -STATE_ATTR_NEXT_SETTING = "next_setting" -STATE_ATTR_ELEVATION = "elevation" -STATE_ATTR_AZIMUTH = "azimuth" +DOMAIN = 'sun' -_LOGGER = logging.getLogger(__name__) +ENTITY_ID = 'sun.sun' + +STATE_ABOVE_HORIZON = 'above_horizon' +STATE_BELOW_HORIZON = 'below_horizon' + +STATE_ATTR_AZIMUTH = 'azimuth' +STATE_ATTR_ELEVATION = 'elevation' +STATE_ATTR_NEXT_RISING = 'next_rising' +STATE_ATTR_NEXT_SETTING = 'next_setting' + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({ + vol.Optional(CONF_ELEVATION): cv.positive_int, + }), +}, extra=vol.ALLOW_EXTRA) def is_on(hass, entity_id=None): diff --git a/homeassistant/components/updater.py b/homeassistant/components/updater.py index 6c0ca6d082e9a..ec91149a87d3d 100644 --- a/homeassistant/components/updater.py +++ b/homeassistant/components/updater.py @@ -1,28 +1,35 @@ """ Support to check for available updates. -For more details about this platform, please refer to the documentation at -at https://home-assistant.io/components/updater/ +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/updater/ """ import logging import requests +import voluptuous as vol from homeassistant.const import __version__ as CURRENT_VERSION from homeassistant.const import ATTR_FRIENDLY_NAME from homeassistant.helpers import event _LOGGER = logging.getLogger(__name__) -PYPI_URL = 'https://pypi.python.org/pypi/homeassistant/json' + DOMAIN = 'updater' + ENTITY_ID = 'updater.updater' +PYPI_URL = 'https://pypi.python.org/pypi/homeassistant/json' + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({}), +}, extra=vol.ALLOW_EXTRA) + def setup(hass, config): """Setup the updater component.""" if 'dev' in CURRENT_VERSION: - # This component only makes sense in release versions - _LOGGER.warning('Updater not supported in development version') + _LOGGER.warning("Updater not supported in development version") return False def check_newest_version(_=None): @@ -31,10 +38,10 @@ def check_newest_version(_=None): if newest != CURRENT_VERSION and newest is not None: hass.states.set( - ENTITY_ID, newest, {ATTR_FRIENDLY_NAME: 'Update Available'}) + ENTITY_ID, newest, {ATTR_FRIENDLY_NAME: 'Update available'}) - event.track_time_change(hass, check_newest_version, - hour=[0, 12], minute=0, second=0) + event.track_time_change( + hass, check_newest_version, hour=[0, 12], minute=0, second=0) check_newest_version() @@ -48,11 +55,11 @@ def get_newest_version(): return req.json()['info']['version'] except requests.RequestException: - _LOGGER.exception('Could not contact PyPI to check for updates') + _LOGGER.exception("Could not contact PyPI to check for updates") return None except ValueError: - _LOGGER.exception('Received invalid response from PyPI') + _LOGGER.exception("Received invalid response from PyPI") return None except KeyError: - _LOGGER.exception('Response from PyPI did not include version') + _LOGGER.exception("Response from PyPI did not include version") return None diff --git a/homeassistant/components/upnp.py b/homeassistant/components/upnp.py index bb4dbe8fe86f8..3bd7d4dacc6f5 100644 --- a/homeassistant/components/upnp.py +++ b/homeassistant/components/upnp.py @@ -6,39 +6,41 @@ """ import logging -from homeassistant.const import (EVENT_HOMEASSISTANT_STOP) +import voluptuous as vol -DEPENDENCIES = ["api"] +from homeassistant.const import (EVENT_HOMEASSISTANT_STOP) _LOGGER = logging.getLogger(__name__) -DOMAIN = "upnp" +DEPENDENCIES = ['api'] +DOMAIN = 'upnp' + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({}), +}, extra=vol.ALLOW_EXTRA) +# pylint: disable=import-error, no-member, broad-except def setup(hass, config): """Register a port mapping for Home Assistant via UPnP.""" - # pylint: disable=import-error import miniupnpc - # pylint: disable=no-member upnp = miniupnpc.UPnP() upnp.discoverdelay = 200 upnp.discover() try: upnp.selectigd() - # pylint: disable=broad-except except Exception: _LOGGER.exception("Error when attempting to discover a UPnP IGD") return False - upnp.addportmapping(hass.config.api.port, "TCP", - hass.config.api.host, hass.config.api.port, - "Home Assistant", "") + upnp.addportmapping(hass.config.api.port, 'TCP', hass.config.api.host, + hass.config.api.port, 'Home Assistant', '') def deregister_port(event): """De-register the UPnP port mapping.""" - upnp.deleteportmapping(hass.config.api.port, "TCP") + upnp.deleteportmapping(hass.config.api.port, 'TCP') hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, deregister_port) diff --git a/homeassistant/components/zeroconf.py b/homeassistant/components/zeroconf.py index 3974f7b322018..dca7baa997ab0 100644 --- a/homeassistant/components/zeroconf.py +++ b/homeassistant/components/zeroconf.py @@ -1,25 +1,28 @@ """ This module exposes Home Assistant via Zeroconf. -Zeroconf is also known as Bonjour, Avahi or Multicast DNS (mDNS). - -For more details about Zeroconf, please refer to the documentation at +For more details about this component, please refer to the documentation at https://home-assistant.io/components/zeroconf/ """ import logging import socket +import voluptuous as vol + from homeassistant.const import (EVENT_HOMEASSISTANT_STOP, __version__) -REQUIREMENTS = ["zeroconf==0.17.6"] +_LOGGER = logging.getLogger(__name__) -DEPENDENCIES = ["api"] +DEPENDENCIES = ['api'] +DOMAIN = 'zeroconf' -_LOGGER = logging.getLogger(__name__) +REQUIREMENTS = ['zeroconf==0.17.6'] -DOMAIN = "zeroconf" +ZEROCONF_TYPE = '_home-assistant._tcp.local.' -ZEROCONF_TYPE = "_home-assistant._tcp.local." +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({}), +}, extra=vol.ALLOW_EXTRA) def setup(hass, config): @@ -28,12 +31,14 @@ def setup(hass, config): zeroconf = Zeroconf() - zeroconf_name = "{}.{}".format(hass.config.location_name, - ZEROCONF_TYPE) + zeroconf_name = '{}.{}'.format(hass.config.location_name, ZEROCONF_TYPE) - requires_api_password = (hass.config.api.api_password is not None) - params = {"version": __version__, "base_url": hass.config.api.base_url, - "requires_api_password": requires_api_password} + requires_api_password = hass.config.api.api_password is not None + params = { + 'version': __version__, + 'base_url': hass.config.api.base_url, + 'requires_api_password': requires_api_password, + } info = ServiceInfo(ZEROCONF_TYPE, zeroconf_name, socket.inet_aton(hass.config.api.host), diff --git a/tests/components/test_updater.py b/tests/components/test_updater.py index 75879f3cbd01b..ec958a0d26416 100644 --- a/tests/components/test_updater.py +++ b/tests/components/test_updater.py @@ -33,11 +33,11 @@ def test_new_version_shows_entity_on_start(self, mock_get_newest_version): updater.CURRENT_VERSION = MOCK_CURRENT_VERSION self.assertTrue(setup_component(self.hass, updater.DOMAIN, { - 'updater': None + 'updater': {} })) - self.assertTrue(self.hass.states.is_state(updater.ENTITY_ID, - NEW_VERSION)) + self.assertTrue(self.hass.states.is_state( + updater.ENTITY_ID, NEW_VERSION)) @patch('homeassistant.components.updater.get_newest_version') def test_no_entity_on_same_version(self, mock_get_newest_version): @@ -46,20 +46,20 @@ def test_no_entity_on_same_version(self, mock_get_newest_version): updater.CURRENT_VERSION = MOCK_CURRENT_VERSION self.assertTrue(setup_component(self.hass, updater.DOMAIN, { - 'updater': None + 'updater': {} })) self.assertIsNone(self.hass.states.get(updater.ENTITY_ID)) mock_get_newest_version.return_value = NEW_VERSION - fire_time_changed(self.hass, - dt_util.utcnow().replace(hour=0, minute=0, second=0)) + fire_time_changed( + self.hass, dt_util.utcnow().replace(hour=0, minute=0, second=0)) self.hass.block_till_done() - self.assertTrue(self.hass.states.is_state(updater.ENTITY_ID, - NEW_VERSION)) + self.assertTrue(self.hass.states.is_state( + updater.ENTITY_ID, NEW_VERSION)) @patch('homeassistant.components.updater.requests.get') def test_errors_while_fetching_new_version(self, mock_get): @@ -78,5 +78,5 @@ def test_updater_disabled_on_dev(self): updater.CURRENT_VERSION = MOCK_CURRENT_VERSION + 'dev' self.assertFalse(setup_component(self.hass, updater.DOMAIN, { - 'updater': None + 'updater': {} })) From 6632747543bc0a943e689721cfa54593ac73c2c3 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 30 Sep 2016 04:06:28 +0200 Subject: [PATCH 013/112] Migrate to voluptuous (#3341) --- .../components/light/limitlessled.py | 45 ++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py index aac28f9ced8ef..bbe3a11a778f4 100644 --- a/homeassistant/components/light/limitlessled.py +++ b/homeassistant/components/light/limitlessled.py @@ -7,19 +7,35 @@ # pylint: disable=abstract-method import logging +import voluptuous as vol + +from homeassistant.const import (CONF_NAME, CONF_HOST, CONF_PORT) from homeassistant.components.light import ( ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_EFFECT, ATTR_FLASH, ATTR_RGB_COLOR, ATTR_TRANSITION, EFFECT_COLORLOOP, EFFECT_WHITE, FLASH_LONG, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_EFFECT, SUPPORT_FLASH, - SUPPORT_RGB_COLOR, SUPPORT_TRANSITION, Light) + SUPPORT_RGB_COLOR, SUPPORT_TRANSITION, Light, PLATFORM_SCHEMA) +import homeassistant.helpers.config_validation as cv -_LOGGER = logging.getLogger(__name__) REQUIREMENTS = ['limitlessled==1.0.0'] -RGB_BOUNDARY = 40 -DEFAULT_TRANSITION = 0 + +_LOGGER = logging.getLogger(__name__) + +CONF_BRIDGES = 'bridges' +CONF_GROUPS = 'groups' +CONF_NUMBER = 'number' +CONF_TYPE = 'type' +CONF_VERSION = 'version' + +DEFAULT_LED_TYPE = 'rgbw' DEFAULT_PORT = 8899 +DEFAULT_TRANSITION = 0 DEFAULT_VERSION = 5 -DEFAULT_LED_TYPE = 'rgbw' + +LED_TYPE = ['rgbw', 'white'] + +RGB_BOUNDARY = 40 + WHITE = [255, 255, 255] SUPPORT_LIMITLESSLED_WHITE = (SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP | @@ -28,6 +44,25 @@ SUPPORT_FLASH | SUPPORT_RGB_COLOR | SUPPORT_TRANSITION) +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_BRIDGES): vol.All(cv.ensure_list, [ + { + vol.Required(CONF_HOST): cv.string, + vol.Optional(CONF_VERSION, + default=DEFAULT_VERSION): cv.positive_int, + vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, + vol.Required(CONF_GROUPS): vol.All(cv.ensure_list, [ + { + vol.Required(CONF_NAME): cv.string, + vol.Optional(CONF_TYPE, default=DEFAULT_LED_TYPE): + vol.In(LED_TYPE), + vol.Required(CONF_NUMBER): cv.positive_int, + } + ]), + }, + ]), +}) + def rewrite_legacy(config): """Rewrite legacy configuration to new format.""" From c000e74d0a5df0f0486796fbbcfe5acbeb9e3120 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 30 Sep 2016 04:07:35 +0200 Subject: [PATCH 014/112] Migrate to voluptuous (#3374) --- .../components/binary_sensor/nx584.py | 60 ++++++++++++------- tests/components/binary_sensor/test_nx584.py | 39 +++++++----- 2 files changed, 62 insertions(+), 37 deletions(-) diff --git a/homeassistant/components/binary_sensor/nx584.py b/homeassistant/components/binary_sensor/nx584.py index 6a287599e6955..e158da02f2b4b 100644 --- a/homeassistant/components/binary_sensor/nx584.py +++ b/homeassistant/components/binary_sensor/nx584.py @@ -1,41 +1,56 @@ """ -Support for exposing nx584 elements as sensors. +Support for exposing NX584 elements as sensors. For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/sensor.nx584/ +https://home-assistant.io/components/binary_sensor.nx584/ """ import logging import threading import time import requests +import voluptuous as vol from homeassistant.components.binary_sensor import ( - SENSOR_CLASSES, BinarySensorDevice) + SENSOR_CLASSES, BinarySensorDevice, PLATFORM_SCHEMA) +from homeassistant.const import (CONF_HOST, CONF_PORT) +import homeassistant.helpers.config_validation as cv REQUIREMENTS = ['pynx584==0.2'] + _LOGGER = logging.getLogger(__name__) +CONF_EXCLUDE_ZONES = 'exclude_zones' +CONF_ZONE_TYPES = 'zone_types' -def setup_platform(hass, config, add_devices, discovery_info=None): - """Setup nx584 binary sensor platform.""" - from nx584 import client as nx584_client +DEFAULT_HOST = 'localhost' +DEFAULT_PORT = '5007' +DEFAULT_SSL = False - host = config.get('host', 'localhost:5007') - exclude = config.get('exclude_zones', []) - zone_types = config.get('zone_types', {}) +ZONE_TYPES_SCHEMA = vol.Schema({ + cv.positive_int: vol.In(SENSOR_CLASSES), +}) - if not all(isinstance(zone, int) for zone in exclude): - _LOGGER.error('Invalid excluded zone specified (use zone number)') - return False +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Optional(CONF_EXCLUDE_ZONES, default=[]): + vol.All(cv.ensure_list, [cv.positive_int]), + vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string, + vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, + vol.Optional(CONF_ZONE_TYPES, default={}): ZONE_TYPES_SCHEMA, +}) - if not all(isinstance(zone, int) and ztype in SENSOR_CLASSES - for zone, ztype in zone_types.items()): - _LOGGER.error('Invalid zone_types entry') - return False + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Setup the NX584 binary sensor platform.""" + from nx584 import client as nx584_client + + host = config.get(CONF_HOST) + port = config.get(CONF_PORT) + exclude = config.get(CONF_EXCLUDE_ZONES) + zone_types = config.get(CONF_ZONE_TYPES) try: - client = nx584_client.Client('http://%s' % host) + client = nx584_client.Client('http://{}:{}'.format(host, port)) zones = client.list_zones() except requests.exceptions.ConnectionError as ex: _LOGGER.error('Unable to connect to NX584: %s', str(ex)) @@ -43,7 +58,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): version = [int(v) for v in client.get_version().split('.')] if version < [1, 1]: - _LOGGER.error('NX584 is too old to use for sensors (>=0.2 required)') + _LOGGER.error("NX584 is too old to use for sensors (>=0.2 required)") return False zone_sensors = { @@ -57,13 +72,12 @@ def setup_platform(hass, config, add_devices, discovery_info=None): watcher = NX584Watcher(client, zone_sensors) watcher.start() else: - _LOGGER.warning('No zones found on NX584') - + _LOGGER.warning("No zones found on NX584") return True class NX584ZoneSensor(BinarySensorDevice): - """Represents a NX584 zone as a sensor.""" + """Representation of a NX584 zone as a sensor.""" def __init__(self, zone, zone_type): """Initialize the nx594 binary sensor.""" @@ -96,7 +110,7 @@ class NX584Watcher(threading.Thread): """Event listener thread to process NX584 events.""" def __init__(self, client, zone_sensors): - """Initialize nx584 watcher thread.""" + """Initialize NX584 watcher thread.""" super(NX584Watcher, self).__init__() self.daemon = True self._client = client @@ -130,5 +144,5 @@ def run(self): try: self._run() except requests.exceptions.ConnectionError: - _LOGGER.error('Failed to reach NX584 server') + _LOGGER.error("Failed to reach NX584 server") time.sleep(10) diff --git a/tests/components/binary_sensor/test_nx584.py b/tests/components/binary_sensor/test_nx584.py index 21323702447fe..84500eeafb647 100644 --- a/tests/components/binary_sensor/test_nx584.py +++ b/tests/components/binary_sensor/test_nx584.py @@ -3,9 +3,11 @@ import unittest from unittest import mock -from homeassistant.components.binary_sensor import nx584 from nx584 import client as nx584_client +from homeassistant.components.binary_sensor import nx584 +from homeassistant.bootstrap import setup_component + class StopMe(Exception): """Stop helper.""" @@ -14,7 +16,7 @@ class StopMe(Exception): class TestNX584SensorSetup(unittest.TestCase): - """Test the nx584 sensor platform.""" + """Test the NX584 sensor platform.""" def setUp(self): """Setup things to be run when tests are started.""" @@ -35,16 +37,26 @@ def tearDown(self): """Stop everything that was started.""" self._mock_client.stop() + def test_setup_no_config(self): + """Test the setup with no configuration.""" + hass = mock.MagicMock() + assert setup_component(hass, 'binary_sensor', {'nx584': {}}) + @mock.patch('homeassistant.components.binary_sensor.nx584.NX584Watcher') @mock.patch('homeassistant.components.binary_sensor.nx584.NX584ZoneSensor') - def test_setup_no_config(self, mock_nx, mock_watcher): + def test_setup_defaults(self, mock_nx, mock_watcher): """Test the setup with no configuration.""" add_devices = mock.MagicMock() hass = mock.MagicMock() - self.assertTrue(nx584.setup_platform(hass, {}, add_devices)) - mock_nx.assert_has_calls([ - mock.call(zone, 'opening') - for zone in self.fake_zones]) + config = { + 'host': nx584.DEFAULT_HOST, + 'port': nx584.DEFAULT_PORT, + 'exclude_zones': [], + 'zone_types': {}, + } + self.assertTrue(nx584.setup_platform(hass, config, add_devices)) + mock_nx.assert_has_calls( + [mock.call(zone, 'opening') for zone in self.fake_zones]) self.assertTrue(add_devices.called) nx584_client.Client.assert_called_once_with('http://localhost:5007') @@ -53,7 +65,8 @@ def test_setup_no_config(self, mock_nx, mock_watcher): def test_setup_full_config(self, mock_nx, mock_watcher): """Test the setup with full configuration.""" config = { - 'host': 'foo:123', + 'host': 'foo', + 'port': 123, 'exclude_zones': [2], 'zone_types': {3: 'motion'}, } @@ -71,8 +84,7 @@ def test_setup_full_config(self, mock_nx, mock_watcher): def _test_assert_graceful_fail(self, config): """Test the failing.""" hass = add_devices = mock.MagicMock() - self.assertFalse(nx584.setup_platform(hass, config, - add_devices)) + self.assertFalse(setup_component(hass, 'binary_sensor.nx584', config)) self.assertFalse(add_devices.called) def test_setup_bad_config(self): @@ -101,13 +113,12 @@ def test_setup_no_zones(self): """Test the setup with no zones.""" nx584_client.Client.return_value.list_zones.return_value = [] hass = add_devices = mock.MagicMock() - self.assertTrue(nx584.setup_platform(hass, {}, - add_devices)) + self.assertTrue(nx584.setup_platform(hass, {}, add_devices)) self.assertFalse(add_devices.called) class TestNX584ZoneSensor(unittest.TestCase): - """Test for the nx584 zone sensor.""" + """Test for the NX584 zone sensor.""" def test_sensor_normal(self): """Test the sensor.""" @@ -122,7 +133,7 @@ def test_sensor_normal(self): class TestNX584Watcher(unittest.TestCase): - """Test the nx584 watcher.""" + """Test the NX584 watcher.""" @mock.patch.object(nx584.NX584ZoneSensor, 'update_ha_state') def test_process_zone_event(self, mock_update): From 7ac842509957a7c77c7671a70576ee5716e20208 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 29 Sep 2016 21:42:36 -0700 Subject: [PATCH 015/112] Fix tests --- tests/components/binary_sensor/test_nx584.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/components/binary_sensor/test_nx584.py b/tests/components/binary_sensor/test_nx584.py index 84500eeafb647..ea4d997c2c35a 100644 --- a/tests/components/binary_sensor/test_nx584.py +++ b/tests/components/binary_sensor/test_nx584.py @@ -40,6 +40,7 @@ def tearDown(self): def test_setup_no_config(self): """Test the setup with no configuration.""" hass = mock.MagicMock() + hass.pool.worker_count = 2 assert setup_component(hass, 'binary_sensor', {'nx584': {}}) @mock.patch('homeassistant.components.binary_sensor.nx584.NX584Watcher') From 9ea030f42e0da8ec125e28715a6e5ca00777653e Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Fri, 30 Sep 2016 01:17:13 -0400 Subject: [PATCH 016/112] Fixed issue #3574 - Temperature slider fixed on frontend on heat/cool mode (#3606) * Fixed issue #3574 - Temperature slider fixed on frontend on heat/cool mode * Fixed target_temperature to return None when self.is_away_mode_on is True --- homeassistant/components/climate/nest.py | 41 +++++++++++++++++------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/climate/nest.py b/homeassistant/components/climate/nest.py index 10abf812116d9..52b7c2bddd927 100644 --- a/homeassistant/components/climate/nest.py +++ b/homeassistant/components/climate/nest.py @@ -9,9 +9,10 @@ import homeassistant.components.nest as nest from homeassistant.components.climate import ( STATE_AUTO, STATE_COOL, STATE_HEAT, STATE_IDLE, ClimateDevice, - PLATFORM_SCHEMA, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW) + PLATFORM_SCHEMA, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW, + ATTR_TEMPERATURE) from homeassistant.const import ( - TEMP_CELSIUS, CONF_SCAN_INTERVAL, STATE_ON, TEMP_FAHRENHEIT) + TEMP_CELSIUS, CONF_SCAN_INTERVAL, STATE_ON) from homeassistant.util.temperature import convert as convert_temperature DEPENDENCIES = ['nest'] @@ -40,6 +41,7 @@ def __init__(self, structure, device, temp_unit): self.structure = structure self.device = device self._fan_list = [STATE_ON, STATE_AUTO] + self._operation_list = [STATE_COOL, STATE_IDLE, STATE_HEAT] @property def name(self): @@ -57,10 +59,7 @@ def name(self): @property def unit_of_measurement(self): """Return the unit of measurement.""" - if self.device.measurement_scale == 'F': - return TEMP_FAHRENHEIT - elif self.device.measurement_scale == 'C': - return TEMP_CELSIUS + return TEMP_CELSIUS @property def device_state_attributes(self): @@ -78,15 +77,23 @@ def current_temperature(self): return self.device.temperature @property - def operation(self): + def current_operation(self): """Return current operation ie. heat, cool, idle.""" - if self.device.hvac_ac_state is True: + if self.device.hvac_ac_state: return STATE_COOL - elif self.device.hvac_heater_state is True: + elif self.device.hvac_heater_state: return STATE_HEAT else: return STATE_IDLE + @property + def target_temperature(self): + """Return the temperature we try to reach.""" + if self.device.mode != 'range' and not self.is_away_mode_on: + return self.device.target + else: + return None + @property def target_temperature_low(self): """Return the lower bound temperature we try to reach.""" @@ -95,7 +102,8 @@ def target_temperature_low(self): return self.device.away_temperature[0] if self.device.mode == 'range': return self.device.target[0] - return self.target_temperature + else: + return None @property def target_temperature_high(self): @@ -105,7 +113,8 @@ def target_temperature_high(self): return self.device.away_temperature[1] if self.device.mode == 'range': return self.device.target[1] - return self.target_temperature + else: + return None @property def is_away_mode_on(self): @@ -121,7 +130,10 @@ def set_temperature(self, **kwargs): target_temp_low = convert_temperature(kwargs.get( ATTR_TARGET_TEMP_LOW), self._unit, TEMP_CELSIUS) - temp = (target_temp_low, target_temp_high) + if self.device.mode == 'range': + temp = (target_temp_low, target_temp_high) + else: + temp = kwargs.get(ATTR_TEMPERATURE) _LOGGER.debug("Nest set_temperature-output-value=%s", temp) self.device.target = temp @@ -129,6 +141,11 @@ def set_operation_mode(self, operation_mode): """Set operation mode.""" self.device.mode = operation_mode + @property + def operation_list(self): + """List of available operation modes.""" + return self._operation_list + def turn_away_mode_on(self): """Turn away on.""" self.structure.away = True From a89d036e2668045e7a0c0ac27d88db96f7140528 Mon Sep 17 00:00:00 2001 From: Jeff Wilson Date: Fri, 30 Sep 2016 02:44:14 -0400 Subject: [PATCH 017/112] Nest operation modes (#3609) * Add ability to change Nest mode to all available options * Make Nest state reflect current operation not current operation mode * Update Nest sensor to use operation mode * Fix linting * Revert "Make Nest state reflect current operation not current operation mode" This reverts commit 573ba028d8ed11a2f228ca4b21cd7d88b7d0a919. Conflicts: homeassistant/components/climate/nest.py --- homeassistant/components/climate/nest.py | 27 +++++++++++++++++------- homeassistant/components/sensor/nest.py | 2 +- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/climate/nest.py b/homeassistant/components/climate/nest.py index 52b7c2bddd927..2d3b95bb5cf55 100644 --- a/homeassistant/components/climate/nest.py +++ b/homeassistant/components/climate/nest.py @@ -12,7 +12,7 @@ PLATFORM_SCHEMA, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW, ATTR_TEMPERATURE) from homeassistant.const import ( - TEMP_CELSIUS, CONF_SCAN_INTERVAL, STATE_ON) + TEMP_CELSIUS, CONF_SCAN_INTERVAL, STATE_ON, STATE_OFF, STATE_UNKNOWN) from homeassistant.util.temperature import convert as convert_temperature DEPENDENCIES = ['nest'] @@ -31,7 +31,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): for structure, device in nest.devices()]) -# pylint: disable=abstract-method +# pylint: disable=abstract-method,too-many-public-methods class NestThermostat(ClimateDevice): """Representation of a Nest thermostat.""" @@ -41,7 +41,8 @@ def __init__(self, structure, device, temp_unit): self.structure = structure self.device = device self._fan_list = [STATE_ON, STATE_AUTO] - self._operation_list = [STATE_COOL, STATE_IDLE, STATE_HEAT] + self._operation_list = [STATE_HEAT, STATE_COOL, STATE_AUTO, + STATE_OFF] @property def name(self): @@ -68,7 +69,6 @@ def device_state_attributes(self): return { "humidity": self.device.humidity, "target_humidity": self.device.target_humidity, - "mode": self.device.mode } @property @@ -79,12 +79,16 @@ def current_temperature(self): @property def current_operation(self): """Return current operation ie. heat, cool, idle.""" - if self.device.hvac_ac_state: + if self.device.mode == 'cool': return STATE_COOL - elif self.device.hvac_heater_state: + elif self.device.mode == 'heat': return STATE_HEAT + elif self.device.mode == 'range': + return STATE_AUTO + elif self.device.mode == 'off': + return STATE_OFF else: - return STATE_IDLE + return STATE_UNKNOWN @property def target_temperature(self): @@ -139,7 +143,14 @@ def set_temperature(self, **kwargs): def set_operation_mode(self, operation_mode): """Set operation mode.""" - self.device.mode = operation_mode + if operation_mode == STATE_HEAT: + self.device.mode = 'heat' + elif operation_mode == STATE_COOL: + self.device.mode = 'cool' + elif operation_mode == STATE_AUTO: + self.device.mode = 'range' + elif operation_mode == STATE_OFF: + self.device.mode = 'off' @property def operation_list(self): diff --git a/homeassistant/components/sensor/nest.py b/homeassistant/components/sensor/nest.py index 7a89265a8bd4c..13a97b7be04cf 100644 --- a/homeassistant/components/sensor/nest.py +++ b/homeassistant/components/sensor/nest.py @@ -16,7 +16,7 @@ DEPENDENCIES = ['nest'] SENSOR_TYPES = ['humidity', - 'mode', + 'operation_mode', 'last_ip', 'local_ip', 'last_connection', From 234f4449b02622322f5fdb827f7d06b47b50fb89 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 30 Sep 2016 00:14:08 -0700 Subject: [PATCH 018/112] Lint --- homeassistant/components/climate/nest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/climate/nest.py b/homeassistant/components/climate/nest.py index 2d3b95bb5cf55..2884f4d2eb2aa 100644 --- a/homeassistant/components/climate/nest.py +++ b/homeassistant/components/climate/nest.py @@ -8,7 +8,7 @@ import voluptuous as vol import homeassistant.components.nest as nest from homeassistant.components.climate import ( - STATE_AUTO, STATE_COOL, STATE_HEAT, STATE_IDLE, ClimateDevice, + STATE_AUTO, STATE_COOL, STATE_HEAT, ClimateDevice, PLATFORM_SCHEMA, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW, ATTR_TEMPERATURE) from homeassistant.const import ( From 521080d1b0cf605ba82394ce8d209c0765fb8868 Mon Sep 17 00:00:00 2001 From: John Arild Berentsen Date: Fri, 30 Sep 2016 17:43:18 +0200 Subject: [PATCH 019/112] Zwave: Update commandclasses and deviceclasses according to sigma SDK (#3495) * Update Command classes and device types to Sigma SDK * Fix some pylint * Seperate constants to file * Flake8 * coverage and flake8 pylint * Add services.yaml * Service descriptions was missing * Spelling :) * grammar * Remove zwave service descriptions from main --- .coveragerc | 2 +- .../components/binary_sensor/zwave.py | 6 +- homeassistant/components/climate/zwave.py | 69 ++-- homeassistant/components/cover/zwave.py | 60 ++-- homeassistant/components/garage_door/zwave.py | 12 +- homeassistant/components/hvac/zwave.py | 52 ++-- homeassistant/components/light/zwave.py | 16 +- homeassistant/components/lock/zwave.py | 10 +- .../components/rollershutter/zwave.py | 52 ++-- homeassistant/components/sensor/zwave.py | 14 +- homeassistant/components/services.yaml | 38 --- homeassistant/components/switch/zwave.py | 11 +- homeassistant/components/thermostat/zwave.py | 37 +-- .../{zwave.py => zwave/__init__.py} | 294 +++++++----------- homeassistant/components/zwave/const.py | 292 +++++++++++++++++ homeassistant/components/zwave/services.yaml | 36 +++ 16 files changed, 614 insertions(+), 387 deletions(-) rename homeassistant/components/{zwave.py => zwave/__init__.py} (67%) create mode 100644 homeassistant/components/zwave/const.py create mode 100644 homeassistant/components/zwave/services.yaml diff --git a/.coveragerc b/.coveragerc index 8f12390556c04..0bfa3fb1a04f4 100644 --- a/.coveragerc +++ b/.coveragerc @@ -77,7 +77,7 @@ omit = homeassistant/components/zigbee.py homeassistant/components/*/zigbee.py - homeassistant/components/zwave.py + homeassistant/components/zwave/* homeassistant/components/*/zwave.py homeassistant/components/enocean.py diff --git a/homeassistant/components/binary_sensor/zwave.py b/homeassistant/components/binary_sensor/zwave.py index 1b47b98fe9fa5..69688c7e4f6fd 100644 --- a/homeassistant/components/binary_sensor/zwave.py +++ b/homeassistant/components/binary_sensor/zwave.py @@ -36,8 +36,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if discovery_info is None or zwave.NETWORK is None: return - node = zwave.NETWORK.nodes[discovery_info[zwave.ATTR_NODE_ID]] - value = node.values[discovery_info[zwave.ATTR_VALUE_ID]] + node = zwave.NETWORK.nodes[discovery_info[zwave.const.ATTR_NODE_ID]] + value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]] value.set_change_verified(False) # Make sure that we have values for the key before converting to int @@ -58,7 +58,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): ]) return - if value.command_class == zwave.COMMAND_CLASS_SENSOR_BINARY: + if value.command_class == zwave.const.COMMAND_CLASS_SENSOR_BINARY: add_devices([ZWaveBinarySensor(value, None)]) diff --git a/homeassistant/components/climate/zwave.py b/homeassistant/components/climate/zwave.py index 4eec1f9c652ab..0fb13d258aab3 100755 --- a/homeassistant/components/climate/zwave.py +++ b/homeassistant/components/climate/zwave.py @@ -9,8 +9,7 @@ import logging from homeassistant.components.climate import DOMAIN from homeassistant.components.climate import ClimateDevice -from homeassistant.components.zwave import ( - ATTR_NODE_ID, ATTR_VALUE_ID, ZWaveDeviceEntity) +from homeassistant.components.zwave import ZWaveDeviceEntity from homeassistant.components import zwave from homeassistant.const import ( TEMP_CELSIUS, TEMP_FAHRENHEIT, ATTR_TEMPERATURE) @@ -28,12 +27,6 @@ HORSTMANN_HRT4_ZW = 0x3 HORSTMANN_HRT4_ZW_THERMOSTAT = (HORSTMANN, HORSTMANN_HRT4_ZW) -COMMAND_CLASS_SENSOR_MULTILEVEL = 0x31 -COMMAND_CLASS_THERMOSTAT_MODE = 0x40 -COMMAND_CLASS_THERMOSTAT_SETPOINT = 0x43 -COMMAND_CLASS_THERMOSTAT_FAN_MODE = 0x44 -COMMAND_CLASS_CONFIGURATION = 0x70 - WORKAROUND_ZXT_120 = 'zxt_120' WORKAROUND_HRT4_ZW = 'hrt4_zw' @@ -67,19 +60,19 @@ def setup_platform(hass, config, add_devices, discovery_info=None): discovery_info, zwave.NETWORK) return temp_unit = hass.config.units.temperature_unit - node = zwave.NETWORK.nodes[discovery_info[ATTR_NODE_ID]] - value = node.values[discovery_info[ATTR_VALUE_ID]] + node = zwave.NETWORK.nodes[discovery_info[zwave.const.ATTR_NODE_ID]] + value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]] value.set_change_verified(False) add_devices([ZWaveClimate(value, temp_unit)]) _LOGGER.debug("discovery_info=%s and zwave.NETWORK=%s", discovery_info, zwave.NETWORK) -# pylint: disable=too-many-arguments, abstract-method +# pylint: disable=abstract-method class ZWaveClimate(ZWaveDeviceEntity, ClimateDevice): """Represents a ZWave Climate device.""" - # pylint: disable=too-many-public-methods, too-many-instance-attributes + # pylint: disable=too-many-instance-attributes def __init__(self, value, temp_unit): """Initialize the zwave climate device.""" from openzwave.network import ZWaveNetwork @@ -130,7 +123,7 @@ def update_properties(self): """Callback on data change for the registered node/value pair.""" # Operation Mode for value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_MODE).values(): + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_MODE).values(): self._current_operation = value.data self._index_operation = SET_TEMP_TO_INDEX.get( self._current_operation) @@ -139,14 +132,16 @@ def update_properties(self): _LOGGER.debug("self._current_operation=%s", self._current_operation) # Current Temp - for value in self._node.get_values( - class_id=COMMAND_CLASS_SENSOR_MULTILEVEL).values(): + for value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_SENSOR_MULTILEVEL) + .values()): if value.label == 'Temperature': self._current_temperature = int(value.data) self._unit = value.units # Fan Mode - for value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_FAN_MODE).values(): + for value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_FAN_MODE) + .values()): self._current_fan_mode = value.data self._fan_list = list(value.data_items) _LOGGER.debug("self._fan_list=%s", self._fan_list) @@ -154,17 +149,21 @@ def update_properties(self): self._current_fan_mode) # Swing mode if self._zxt_120 == 1: - for value in self._node.get_values( - class_id=COMMAND_CLASS_CONFIGURATION).values(): - if value.command_class == 112 and value.index == 33: + for value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_CONFIGURATION) + .values()): + if value.command_class == \ + zwave.const.COMMAND_CLASS_CONFIGURATION and \ + value.index == 33: self._current_swing_mode = value.data self._swing_list = list(value.data_items) _LOGGER.debug("self._swing_list=%s", self._swing_list) _LOGGER.debug("self._current_swing_mode=%s", self._current_swing_mode) # Set point - for value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_SETPOINT).values(): + for value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_SETPOINT) + .values()): if self.current_operation is not None and \ self.current_operation != 'Off': if self._index_operation != value.index: @@ -232,7 +231,6 @@ def target_temperature(self): """Return the temperature we try to reach.""" return self._target_temperature -# pylint: disable=too-many-branches, too-many-statements def set_temperature(self, **kwargs): """Set new target temperature.""" if kwargs.get(ATTR_TEMPERATURE) is not None: @@ -240,8 +238,9 @@ def set_temperature(self, **kwargs): else: return - for value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_SETPOINT).values(): + for value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_SETPOINT) + .values()): if self.current_operation is not None: if self._hrt4_zw and self.current_operation == 'Off': # HRT4-ZW can change setpoint when off. @@ -279,17 +278,21 @@ def set_temperature(self, **kwargs): def set_fan_mode(self, fan): """Set new target fan mode.""" - for value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_FAN_MODE).values(): - if value.command_class == 68 and value.index == 0: + for value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_FAN_MODE). + values()): + if value.command_class == \ + zwave.const.COMMAND_CLASS_THERMOSTAT_FAN_MODE and \ + value.index == 0: value.data = bytes(fan, 'utf-8') break def set_operation_mode(self, operation_mode): """Set new target operation mode.""" for value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_MODE).values(): - if value.command_class == 64 and value.index == 0: + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_MODE).values(): + if value.command_class == \ + zwave.const.COMMAND_CLASS_THERMOSTAT_MODE and value.index == 0: value.data = bytes(operation_mode, 'utf-8') break @@ -297,7 +300,9 @@ def set_swing_mode(self, swing_mode): """Set new target swing mode.""" if self._zxt_120 == 1: for value in self._node.get_values( - class_id=COMMAND_CLASS_CONFIGURATION).values(): - if value.command_class == 112 and value.index == 33: + class_id=zwave.const.COMMAND_CLASS_CONFIGURATION).values(): + if value.command_class == \ + zwave.const.COMMAND_CLASS_CONFIGURATION and \ + value.index == 33: value.data = bytes(swing_mode, 'utf-8') break diff --git a/homeassistant/components/cover/zwave.py b/homeassistant/components/cover/zwave.py index df7b2e14cb524..a3db374ddf149 100644 --- a/homeassistant/components/cover/zwave.py +++ b/homeassistant/components/cover/zwave.py @@ -12,9 +12,6 @@ from homeassistant.components import zwave from homeassistant.components.cover import CoverDevice -COMMAND_CLASS_SWITCH_MULTILEVEL = 0x26 # 38 -COMMAND_CLASS_SWITCH_BINARY = 0x25 # 37 - SOMFY = 0x47 SOMFY_ZRTSI = 0x5a52 SOMFY_ZRTSI_CONTROLLER = (SOMFY, SOMFY_ZRTSI) @@ -32,17 +29,17 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if discovery_info is None or zwave.NETWORK is None: return - node = zwave.NETWORK.nodes[discovery_info[zwave.ATTR_NODE_ID]] - value = node.values[discovery_info[zwave.ATTR_VALUE_ID]] + node = zwave.NETWORK.nodes[discovery_info[zwave.const.ATTR_NODE_ID]] + value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]] - if (value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL and - value.index == 0): + if node.has_command_class(zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL) \ + and value.index == 0: value.set_change_verified(False) add_devices([ZwaveRollershutter(value)]) - elif (value.command_class == zwave.COMMAND_CLASS_SWITCH_BINARY or - value.command_class == zwave.COMMAND_CLASS_BARRIER_OPERATOR): - if value.type != zwave.TYPE_BOOL and \ - value.genre != zwave.GENRE_USER: + elif node.has_command_class(zwave.const.COMMAND_CLASS_SWITCH_BINARY) or \ + node.has_command_class(zwave.const.COMMAND_CLASS_BARRIER_OPERATOR): + if value.type != zwave.const.TYPE_BOOL and \ + value.genre != zwave.const.GENRE_USER: return value.set_change_verified(False) add_devices([ZwaveGarageDoor(value)]) @@ -59,6 +56,7 @@ def __init__(self, value): from openzwave.network import ZWaveNetwork from pydispatch import dispatcher ZWaveDeviceEntity.__init__(self, value, DOMAIN) + # pylint: disable=no-member self._lozwmgr = libopenzwave.PyManager() self._lozwmgr.create() self._node = value.node @@ -88,9 +86,10 @@ def update_properties(self): """Callback on data change for the registered node/value pair.""" # Position value for value in self._node.get_values( - class_id=COMMAND_CLASS_SWITCH_MULTILEVEL).values(): - if value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL \ - and value.label == 'Level': + class_id=zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL).values(): + if value.command_class == \ + zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and \ + value.label == 'Level': self._current_position = value.data @property @@ -118,22 +117,24 @@ def current_cover_position(self): def open_cover(self, **kwargs): """Move the roller shutter up.""" for value in self._node.get_values( - class_id=COMMAND_CLASS_SWITCH_MULTILEVEL).values(): - if value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL \ - and value.label == 'Open' or \ - value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL \ - and value.label == 'Down': + class_id=zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL).values(): + if value.command_class == \ + zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and value.label == \ + 'Open' or value.command_class == \ + zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and value.label == \ + 'Down': self._lozwmgr.pressButton(value.value_id) break def close_cover(self, **kwargs): """Move the roller shutter down.""" for value in self._node.get_values( - class_id=COMMAND_CLASS_SWITCH_MULTILEVEL).values(): - if value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL \ - and value.label == 'Up' or \ - value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL \ - and value.label == 'Close': + class_id=zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL).values(): + if value.command_class == \ + zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and value.label == \ + 'Up' or value.command_class == \ + zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and value.label == \ + 'Close': self._lozwmgr.pressButton(value.value_id) break @@ -144,11 +145,12 @@ def set_cover_position(self, position, **kwargs): def stop_cover(self, **kwargs): """Stop the roller shutter.""" for value in self._node.get_values( - class_id=COMMAND_CLASS_SWITCH_MULTILEVEL).values(): - if value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL \ - and value.label == 'Open' or \ - value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL \ - and value.label == 'Down': + class_id=zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL).values(): + if value.command_class == \ + zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and value.label == \ + 'Open' or value.command_class == \ + zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and value.label == \ + 'Down': self._lozwmgr.releaseButton(value.value_id) break diff --git a/homeassistant/components/garage_door/zwave.py b/homeassistant/components/garage_door/zwave.py index 8ef0fcbed6391..b180dd76e460f 100644 --- a/homeassistant/components/garage_door/zwave.py +++ b/homeassistant/components/garage_door/zwave.py @@ -22,15 +22,15 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if discovery_info is None or zwave.NETWORK is None: return - node = zwave.NETWORK.nodes[discovery_info[zwave.ATTR_NODE_ID]] - value = node.values[discovery_info[zwave.ATTR_VALUE_ID]] + node = zwave.NETWORK.nodes[discovery_info[zwave.const.ATTR_NODE_ID]] + value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]] - if value.command_class != zwave.COMMAND_CLASS_SWITCH_BINARY and \ - value.command_class != zwave.COMMAND_CLASS_BARRIER_OPERATOR: + if value.command_class != zwave.const.COMMAND_CLASS_SWITCH_BINARY and \ + value.command_class != zwave.const.COMMAND_CLASS_BARRIER_OPERATOR: return - if value.type != zwave.TYPE_BOOL: + if value.type != zwave.const.TYPE_BOOL: return - if value.genre != zwave.GENRE_USER: + if value.genre != zwave.const.GENRE_USER: return value.set_change_verified(False) diff --git a/homeassistant/components/hvac/zwave.py b/homeassistant/components/hvac/zwave.py index f8cb3fa5c9e1b..5415fe0b41c51 100755 --- a/homeassistant/components/hvac/zwave.py +++ b/homeassistant/components/hvac/zwave.py @@ -9,8 +9,7 @@ import logging from homeassistant.components.hvac import DOMAIN from homeassistant.components.hvac import HvacDevice -from homeassistant.components.zwave import ( - ATTR_NODE_ID, ATTR_VALUE_ID, ZWaveDeviceEntity) +from homeassistant.components.zwave import ZWaveDeviceEntity from homeassistant.components import zwave from homeassistant.const import (TEMP_FAHRENHEIT, TEMP_CELSIUS) @@ -23,12 +22,6 @@ REMOTEC_ZXT_120 = 0x8377 REMOTEC_ZXT_120_THERMOSTAT = (REMOTEC, REMOTEC_ZXT_120, 0) -COMMAND_CLASS_SENSOR_MULTILEVEL = 0x31 -COMMAND_CLASS_THERMOSTAT_MODE = 0x40 -COMMAND_CLASS_THERMOSTAT_SETPOINT = 0x43 -COMMAND_CLASS_THERMOSTAT_FAN_MODE = 0x44 -COMMAND_CLASS_CONFIGURATION = 0x70 - WORKAROUND_ZXT_120 = 'zxt_120' DEVICE_MAPPINGS = { @@ -50,8 +43,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): discovery_info, zwave.NETWORK) return - node = zwave.NETWORK.nodes[discovery_info[ATTR_NODE_ID]] - value = node.values[discovery_info[ATTR_VALUE_ID]] + node = zwave.NETWORK.nodes[discovery_info[zwave.const.ATTR_NODE_ID]] + value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]] value.set_change_verified(False) add_devices([ZWaveHvac(value)]) _LOGGER.debug("discovery_info=%s and zwave.NETWORK=%s", @@ -107,25 +100,29 @@ def value_changed(self, value): def update_properties(self): """Callback on data change for the registered node/value pair.""" # Set point - for value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_SETPOINT).values(): + for value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_SETPOINT) + .values()): if int(value.data) != 0: self._target_temperature = int(value.data) # Operation Mode - for value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_MODE).values(): + for value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_MODE) + .values()): self._current_operation = value.data self._operation_list = list(value.data_items) _LOGGER.debug("self._operation_list=%s", self._operation_list) # Current Temp - for value in self._node.get_values( - class_id=COMMAND_CLASS_SENSOR_MULTILEVEL).values(): + for value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_SENSOR_MULTILEVEL) + .values()): if value.label == 'Temperature': self._current_temperature = int(value.data) self._unit = value.units # Fan Mode - for value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_FAN_MODE).values(): + for value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_FAN_MODE) + .values()): self._current_operation_state = value.data self._fan_list = list(value.data_items) _LOGGER.debug("self._fan_list=%s", self._fan_list) @@ -133,8 +130,9 @@ def update_properties(self): self._current_operation_state) # Swing mode if self._zxt_120 == 1: - for value in self._node.get_values( - class_id=COMMAND_CLASS_CONFIGURATION).values(): + for value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_CONFIGURATION) + .values()): if value.command_class == 112 and value.index == 33: self._current_swing_mode = value.data self._swing_list = list(value.data_items) @@ -199,8 +197,9 @@ def target_temperature(self): def set_temperature(self, temperature): """Set new target temperature.""" - for value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_SETPOINT).values(): + for value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_SETPOINT) + .values()): if value.command_class != 67: continue if self._zxt_120: @@ -217,8 +216,9 @@ def set_temperature(self, temperature): def set_fan_mode(self, fan): """Set new target fan mode.""" - for value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_FAN_MODE).values(): + for value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_FAN_MODE) + .values()): if value.command_class == 68 and value.index == 0: value.data = bytes(fan, 'utf-8') break @@ -226,7 +226,7 @@ def set_fan_mode(self, fan): def set_operation_mode(self, operation_mode): """Set new target operation mode.""" for value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_MODE).values(): + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_MODE).values(): if value.command_class == 64 and value.index == 0: value.data = bytes(operation_mode, 'utf-8') break @@ -235,7 +235,7 @@ def set_swing_mode(self, swing_mode): """Set new target swing mode.""" if self._zxt_120 == 1: for value in self._node.get_values( - class_id=COMMAND_CLASS_CONFIGURATION).values(): + class_id=zwave.const.COMMAND_CLASS_CONFIGURATION).values(): if value.command_class == 112 and value.index == 33: value.data = bytes(swing_mode, 'utf-8') break diff --git a/homeassistant/components/light/zwave.py b/homeassistant/components/light/zwave.py index 49c4b5f8dd924..14d635153fb05 100644 --- a/homeassistant/components/light/zwave.py +++ b/homeassistant/components/light/zwave.py @@ -50,19 +50,19 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if discovery_info is None or zwave.NETWORK is None: return - node = zwave.NETWORK.nodes[discovery_info[zwave.ATTR_NODE_ID]] - value = node.values[discovery_info[zwave.ATTR_VALUE_ID]] + node = zwave.NETWORK.nodes[discovery_info[zwave.const.ATTR_NODE_ID]] + value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]] - if value.command_class != zwave.COMMAND_CLASS_SWITCH_MULTILEVEL: + if value.command_class != zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL: return - if value.type != zwave.TYPE_BYTE: + if value.type != zwave.const.TYPE_BYTE: return - if value.genre != zwave.GENRE_USER: + if value.genre != zwave.const.GENRE_USER: return value.set_change_verified(False) - if node.has_command_class(zwave.COMMAND_CLASS_COLOR): + if node.has_command_class(zwave.const.COMMAND_CLASS_SWITCH_COLOR): try: add_devices([ZwaveColorLight(value)]) except ValueError as exception: @@ -195,8 +195,8 @@ def __init__(self, value): raise ValueError("No matching color command found.") for value_color_channels in value.node.get_values( - class_id=zwave.COMMAND_CLASS_COLOR, genre='System', - type="Int").values(): + class_id=zwave.const.COMMAND_CLASS_SWITCH_COLOR, + genre='System', type="Int").values(): self._value_color_channels = value_color_channels if self._value_color_channels is None: diff --git a/homeassistant/components/lock/zwave.py b/homeassistant/components/lock/zwave.py index 9a3b24deb8ac5..4c0b7ae34ac46 100644 --- a/homeassistant/components/lock/zwave.py +++ b/homeassistant/components/lock/zwave.py @@ -16,14 +16,14 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if discovery_info is None or zwave.NETWORK is None: return - node = zwave.NETWORK.nodes[discovery_info[zwave.ATTR_NODE_ID]] - value = node.values[discovery_info[zwave.ATTR_VALUE_ID]] + node = zwave.NETWORK.nodes[discovery_info[zwave.const.ATTR_NODE_ID]] + value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]] - if value.command_class != zwave.COMMAND_CLASS_DOOR_LOCK: + if value.command_class != zwave.const.COMMAND_CLASS_DOOR_LOCK: return - if value.type != zwave.TYPE_BOOL: + if value.type != zwave.const.TYPE_BOOL: return - if value.genre != zwave.GENRE_USER: + if value.genre != zwave.const.GENRE_USER: return value.set_change_verified(False) diff --git a/homeassistant/components/rollershutter/zwave.py b/homeassistant/components/rollershutter/zwave.py index 1e193830005f6..e0f1d2b6e4bae 100644 --- a/homeassistant/components/rollershutter/zwave.py +++ b/homeassistant/components/rollershutter/zwave.py @@ -12,9 +12,6 @@ from homeassistant.components import zwave from homeassistant.components.rollershutter import RollershutterDevice -COMMAND_CLASS_SWITCH_MULTILEVEL = 0x26 # 38 -COMMAND_CLASS_SWITCH_BINARY = 0x25 # 37 - SOMFY = 0x47 SOMFY_ZRTSI = 0x5a52 SOMFY_ZRTSI_CONTROLLER = (SOMFY, SOMFY_ZRTSI) @@ -32,10 +29,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if discovery_info is None or zwave.NETWORK is None: return - node = zwave.NETWORK.nodes[discovery_info[zwave.ATTR_NODE_ID]] - value = node.values[discovery_info[zwave.ATTR_VALUE_ID]] + node = zwave.NETWORK.nodes[discovery_info[zwave.const.ATTR_NODE_ID]] + value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]] - if value.command_class != zwave.COMMAND_CLASS_SWITCH_MULTILEVEL: + if value.command_class != zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL: return if value.index != 0: return @@ -82,9 +79,10 @@ def update_properties(self): """Callback on data change for the registered node/value pair.""" # Position value for value in self._node.get_values( - class_id=COMMAND_CLASS_SWITCH_MULTILEVEL).values(): - if value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL \ - and value.label == 'Level': + class_id=zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL).values(): + if value.command_class == \ + zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and \ + value.label == 'Level': self._current_position = value.data @property @@ -101,23 +99,26 @@ def current_position(self): def move_up(self, **kwargs): """Move the roller shutter up.""" - for value in self._node.get_values( - class_id=COMMAND_CLASS_SWITCH_MULTILEVEL).values(): - if value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL \ - and value.label == 'Open' or \ - value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL \ - and value.label == 'Down': + for value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL) + .values()): + if value.command_class == \ + zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and value.label == \ + 'Open' or value.command_class == \ + zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and value.label == \ + 'Down': self._lozwmgr.pressButton(value.value_id) break def move_down(self, **kwargs): """Move the roller shutter down.""" for value in self._node.get_values( - class_id=COMMAND_CLASS_SWITCH_MULTILEVEL).values(): - if value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL \ - and value.label == 'Up' or \ - value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL \ - and value.label == 'Close': + class_id=zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL).values(): + if value.command_class == \ + zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and value.label == \ + 'Up' or value.command_class == \ + zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and value.label == \ + 'Close': self._lozwmgr.pressButton(value.value_id) break @@ -128,10 +129,11 @@ def move_position(self, position, **kwargs): def stop(self, **kwargs): """Stop the roller shutter.""" for value in self._node.get_values( - class_id=COMMAND_CLASS_SWITCH_MULTILEVEL).values(): - if value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL \ - and value.label == 'Open' or \ - value.command_class == zwave.COMMAND_CLASS_SWITCH_MULTILEVEL \ - and value.label == 'Down': + class_id=zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL).values(): + if value.command_class == \ + zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and value.label == \ + 'Open' or value.command_class == \ + zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and value.label == \ + 'Down': self._lozwmgr.releaseButton(value.value_id) break diff --git a/homeassistant/components/sensor/zwave.py b/homeassistant/components/sensor/zwave.py index 023ddf4db82b0..4f474dbe73f92 100644 --- a/homeassistant/components/sensor/zwave.py +++ b/homeassistant/components/sensor/zwave.py @@ -37,8 +37,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if discovery_info is None or zwave.NETWORK is None: return - node = zwave.NETWORK.nodes[discovery_info[zwave.ATTR_NODE_ID]] - value = node.values[discovery_info[zwave.ATTR_VALUE_ID]] + node = zwave.NETWORK.nodes[discovery_info[zwave.const.ATTR_NODE_ID]] + value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]] value.set_change_verified(False) @@ -59,15 +59,15 @@ def setup_platform(hass, config, add_devices, discovery_info=None): return # Generic Device mappings - if value.command_class == zwave.COMMAND_CLASS_SENSOR_MULTILEVEL: + if node.has_command_class(zwave.const.COMMAND_CLASS_SENSOR_MULTILEVEL): add_devices([ZWaveMultilevelSensor(value)]) - elif (value.command_class == zwave.COMMAND_CLASS_METER and - value.type == zwave.TYPE_DECIMAL): + elif node.has_command_class(zwave.const.COMMAND_CLASS_METER) and \ + value.type == zwave.const.TYPE_DECIMAL: add_devices([ZWaveMultilevelSensor(value)]) - elif (value.command_class == zwave.COMMAND_CLASS_ALARM or - value.command_class == zwave.COMMAND_CLASS_SENSOR_ALARM): + elif node.has_command_class(zwave.const.COMMAND_CLASS_ALARM) or \ + node.has_command_class(zwave.const.COMMAND_CLASS_SENSOR_ALARM): add_devices([ZWaveAlarmSensor(value)]) diff --git a/homeassistant/components/services.yaml b/homeassistant/components/services.yaml index 13078418e93fa..3df736647cb29 100644 --- a/homeassistant/components/services.yaml +++ b/homeassistant/components/services.yaml @@ -101,41 +101,3 @@ openalpr: restart: description: Restart ffmpeg process of device. - -zwave: - add_node: - description: Add a new node to the zwave network. Refer to OZW.log for details. - - add_node_secure: - description: Add a new node to the zwave network with secure communications. Node must support this, and network key must be set. Refer to OZW.log for details. - - cancel_command: - description: Cancel a running zwave controller command. Use this to exit add_node, if you wasn't going to use it but activated it. - - heal_network: - description: Start a zwave network heal. This might take a while and will slow down the zwave network greatly while it is being processed. Refer to OZW.log for details. - - remove_node: - description: Remove a node from the zwave network. Refer to OZW.log for details. - - start_network: - description: Start the zwave network. This might take a while, depending on how big your zwave network is. - - stop_network: - description: Stop the zwave network, all updates into HASS will stop. - - soft_reset: - description: This will reset the controller without removing its data. Use carefully because not all controllers support this. Refer to controllers manual. - - test_network: - description: This will send test to nodes in the zwave network. This will greatly slow down the zwave network while it is being processed. Refer to OZW.log for details. - - rename_node: - description: Set the name of a node. - fields: - entity_id: - description: Name(s) of entities to to rename - example: 'light.leviton_vrmx11lz_multilevel_scene_switch_level_40' - name: - description: New Name - example: 'kitchen' diff --git a/homeassistant/components/switch/zwave.py b/homeassistant/components/switch/zwave.py index c1ad3d36f2d71..4ba9cff378e55 100644 --- a/homeassistant/components/switch/zwave.py +++ b/homeassistant/components/switch/zwave.py @@ -16,14 +16,13 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if discovery_info is None or zwave.NETWORK is None: return - node = zwave.NETWORK.nodes[discovery_info[zwave.ATTR_NODE_ID]] - value = node.values[discovery_info[zwave.ATTR_VALUE_ID]] + node = zwave.NETWORK.nodes[discovery_info[zwave.const.ATTR_NODE_ID]] + value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]] - if value.command_class != zwave.COMMAND_CLASS_SWITCH_BINARY: + if not node.has_command_class(zwave.const.COMMAND_CLASS_SWITCH_BINARY): return - if value.type != zwave.TYPE_BOOL: - return - if value.genre != zwave.GENRE_USER: + if value.type != zwave.const.TYPE_BOOL or value.genre != \ + zwave.const.GENRE_USER: return value.set_change_verified(False) diff --git a/homeassistant/components/thermostat/zwave.py b/homeassistant/components/thermostat/zwave.py index 6bed82284bbd6..de1bd3bc03bd1 100644 --- a/homeassistant/components/thermostat/zwave.py +++ b/homeassistant/components/thermostat/zwave.py @@ -25,12 +25,6 @@ REMOTEC_ZXT_120_THERMOSTAT: WORKAROUND_IGNORE } -COMMAND_CLASS_THERMOSTAT_FAN_STATE = 69 # 0x45 -COMMAND_CLASS_THERMOSTAT_SETPOINT = 67 # 0x43 -COMMAND_CLASS_SENSOR_MULTILEVEL = 49 # 0x31 -COMMAND_CLASS_THERMOSTAT_OPERATING_STATE = 66 # 0x42 -COMMAND_CLASS_THERMOSTAT_MODE = 64 # 0x40 - def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the ZWave thermostats.""" @@ -39,8 +33,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): discovery_info, zwave.NETWORK) return - node = zwave.NETWORK.nodes[discovery_info[zwave.ATTR_NODE_ID]] - value = node.values[discovery_info[zwave.ATTR_VALUE_ID]] + node = zwave.NETWORK.nodes[discovery_info[zwave.const.ATTR_NODE_ID]] + value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]] value.set_change_verified(False) # Make sure that we have values for the key before converting to int if (value.node.manufacturer_id.strip() and @@ -52,13 +46,13 @@ def setup_platform(hass, config, add_devices, discovery_info=None): _LOGGER.debug("Remotec ZXT-120 Zwave Thermostat, ignoring") return if not (value.node.get_values_for_command_class( - COMMAND_CLASS_SENSOR_MULTILEVEL) and + zwave.const.COMMAND_CLASS_SENSOR_MULTILEVEL) and value.node.get_values_for_command_class( - COMMAND_CLASS_THERMOSTAT_SETPOINT)): + zwave.const.COMMAND_CLASS_THERMOSTAT_SETPOINT)): return - if value.command_class != COMMAND_CLASS_SENSOR_MULTILEVEL and \ - value.command_class != COMMAND_CLASS_THERMOSTAT_SETPOINT: + if value.command_class != zwave.const.COMMAND_CLASS_SENSOR_MULTILEVEL and \ + value.command_class != zwave.const.COMMAND_CLASS_THERMOSTAT_SETPOINT: return add_devices([ZWaveThermostat(value)]) @@ -99,20 +93,22 @@ def update_properties(self): """Callback on data change for the registered node/value pair.""" # current Temp for _, value in self._node.get_values_for_command_class( - COMMAND_CLASS_SENSOR_MULTILEVEL).items(): + zwave.const.COMMAND_CLASS_SENSOR_MULTILEVEL).items(): if value.label == 'Temperature': self._current_temperature = int(value.data) self._unit = value.units # operation state - for _, value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_OPERATING_STATE).items(): + for _, value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_OPERATING_STATE) + .items()): self._current_operation_state = value.data_as_string # target temperature temps = [] - for _, value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_SETPOINT).items(): + for _, value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_SETPOINT) + .items()): temps.append(int(value.data)) if value.index == self._index: self._target_temperature = value.data @@ -120,8 +116,9 @@ def update_properties(self): self._target_temperature_low = min(temps) # fan state - for _, value in self._node.get_values( - class_id=COMMAND_CLASS_THERMOSTAT_FAN_STATE).items(): + for _, value in (self._node.get_values( + class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_FAN_STATE) + .items()): self._current_fan_state = value.data_as_string @property @@ -165,7 +162,7 @@ def set_temperature(self, temperature): """Set new target temperature.""" # set point for _, value in self._node.get_values_for_command_class( - COMMAND_CLASS_THERMOSTAT_SETPOINT).items(): + zwave.const.COMMAND_CLASS_THERMOSTAT_SETPOINT).items(): if int(value.data) != 0 and value.index == self._index: value.data = temperature break diff --git a/homeassistant/components/zwave.py b/homeassistant/components/zwave/__init__.py similarity index 67% rename from homeassistant/components/zwave.py rename to homeassistant/components/zwave/__init__.py index eb1d048244b5b..d5080752eab66 100644 --- a/homeassistant/components/zwave.py +++ b/homeassistant/components/zwave/__init__.py @@ -19,6 +19,7 @@ from homeassistant.util import convert, slugify import homeassistant.config as conf_util import homeassistant.helpers.config_validation as cv +from . import const DOMAIN = "zwave" REQUIREMENTS = ['pydispatcher==2.0.5'] @@ -30,175 +31,93 @@ CONF_POLLING_INTENSITY = "polling_intensity" CONF_AUTOHEAL = "autoheal" DEFAULT_CONF_AUTOHEAL = True - -# How long to wait for the zwave network to be ready. -NETWORK_READY_WAIT_SECS = 30 - -SERVICE_ADD_NODE = "add_node" -SERVICE_ADD_NODE_SECURE = "add_node_secure" -SERVICE_REMOVE_NODE = "remove_node" -SERVICE_CANCEL_COMMAND = "cancel_command" -SERVICE_HEAL_NETWORK = "heal_network" -SERVICE_SOFT_RESET = "soft_reset" -SERVICE_TEST_NETWORK = "test_network" -SERVICE_STOP_NETWORK = "stop_network" -SERVICE_START_NETWORK = "start_network" -SERVICE_RENAME_NODE = "rename_node" - -EVENT_SCENE_ACTIVATED = "zwave.scene_activated" -EVENT_NODE_EVENT = "zwave.node_event" -EVENT_NETWORK_READY = "zwave.network_ready" -EVENT_NETWORK_COMPLETE = "zwave.network_complete" -EVENT_NETWORK_START = "zwave.network_start" -EVENT_NETWORK_STOP = "zwave.network_stop" - -COMMAND_CLASS_WHATEVER = None -COMMAND_CLASS_SENSOR_MULTILEVEL = 49 -COMMAND_CLASS_COLOR = 51 -COMMAND_CLASS_METER = 50 -COMMAND_CLASS_ALARM = 113 -COMMAND_CLASS_SWITCH_BINARY = 37 -COMMAND_CLASS_SENSOR_BINARY = 48 -COMMAND_CLASS_SWITCH_MULTILEVEL = 38 -COMMAND_CLASS_DOOR_LOCK = 98 -COMMAND_CLASS_THERMOSTAT_SETPOINT = 67 -COMMAND_CLASS_THERMOSTAT_FAN_MODE = 68 -COMMAND_CLASS_BARRIER_OPERATOR = 102 -COMMAND_CLASS_BATTERY = 128 -COMMAND_CLASS_SENSOR_ALARM = 156 - -GENERIC_COMMAND_CLASS_WHATEVER = None -GENERIC_COMMAND_CLASS_REMOTE_CONTROLLER = 1 -GENERIC_COMMAND_CLASS_NOTIFICATION = 7 -GENERIC_COMMAND_CLASS_REPEATER_SLAVE = 15 -GENERIC_COMMAND_CLASS_BINARY_SWITCH = 16 -GENERIC_COMMAND_CLASS_MULTILEVEL_SWITCH = 17 -GENERIC_COMMAND_CLASS_REMOTE_SWITCH = 18 -GENERIC_COMMAND_CLASS_WALL_CONTROLLER = 24 -GENERIC_COMMAND_CLASS_ENTRY_CONTROL = 64 -GENERIC_COMMAND_CLASS_BINARY_SENSOR = 32 -GENERIC_COMMAND_CLASS_MULTILEVEL_SENSOR = 33 -GENERIC_COMMAND_CLASS_METER = 49 -GENERIC_COMMAND_CLASS_ALARM_SENSOR = 161 -GENERIC_COMMAND_CLASS_THERMOSTAT = 8 - -SPECIFIC_DEVICE_CLASS_WHATEVER = None -SPECIFIC_DEVICE_CLASS_NOT_USED = 0 -SPECIFIC_DEVICE_CLASS_MULTILEVEL_POWER_SWITCH = 1 -SPECIFIC_DEVICE_CLASS_ADVANCED_DOOR_LOCK = 2 -SPECIFIC_DEVICE_CLASS_MULTIPOSITION_MOTOR = 3 -SPECIFIC_DEVICE_CLASS_SECURE_KEYPAD_DOOR_LOCK = 3 -SPECIFIC_DEVICE_CLASS_MULTILEVEL_SCENE = 4 -SPECIFIC_DEVICE_CLASS_SECURE_DOOR = 5 -SPECIFIC_DEVICE_CLASS_MOTOR_CONTROL_CLASS_A = 5 -SPECIFIC_DEVICE_CLASS_MOTOR_CONTROL_CLASS_B = 6 -SPECIFIC_DEVICE_CLASS_SECURE_BARRIER_ADD_ON = 7 -SPECIFIC_DEVICE_CLASS_MOTOR_CONTROL_CLASS_C = 7 - -GENRE_WHATEVER = None -GENRE_USER = "User" - -TYPE_WHATEVER = None -TYPE_BYTE = "Byte" -TYPE_BOOL = "Bool" -TYPE_DECIMAL = "Decimal" - +NETWORK = None # List of tuple (DOMAIN, discovered service, supported command classes, # value type, genre type, specific device class). DISCOVERY_COMPONENTS = [ ('sensor', - [GENERIC_COMMAND_CLASS_WHATEVER], - [SPECIFIC_DEVICE_CLASS_WHATEVER], - [COMMAND_CLASS_SENSOR_MULTILEVEL, - COMMAND_CLASS_METER, - COMMAND_CLASS_ALARM, - COMMAND_CLASS_SENSOR_ALARM], - TYPE_WHATEVER, - GENRE_USER), + [const.GENERIC_TYPE_WHATEVER], + [const.SPECIFIC_TYPE_WHATEVER], + [const.COMMAND_CLASS_SENSOR_MULTILEVEL, + const.COMMAND_CLASS_METER, + const.COMMAND_CLASS_ALARM, + const.COMMAND_CLASS_SENSOR_ALARM], + const.TYPE_WHATEVER, + const.GENRE_USER), ('light', - [GENERIC_COMMAND_CLASS_MULTILEVEL_SWITCH, - GENERIC_COMMAND_CLASS_REMOTE_SWITCH], - [SPECIFIC_DEVICE_CLASS_MULTILEVEL_POWER_SWITCH, - SPECIFIC_DEVICE_CLASS_MULTILEVEL_SCENE, - SPECIFIC_DEVICE_CLASS_NOT_USED], - [COMMAND_CLASS_SWITCH_MULTILEVEL], - TYPE_BYTE, - GENRE_USER), + [const.GENERIC_TYPE_SWITCH_MULTILEVEL, + const.GENERIC_TYPE_SWITCH_REMOTE], + [const.SPECIFIC_TYPE_POWER_SWITCH_MULTILEVEL, + const.SPECIFIC_TYPE_SCENE_SWITCH_MULTILEVEL, + const.SPECIFIC_TYPE_NOT_USED], + [const.COMMAND_CLASS_SWITCH_MULTILEVEL], + const.TYPE_BYTE, + const.GENRE_USER), ('switch', - [GENERIC_COMMAND_CLASS_ALARM_SENSOR, - GENERIC_COMMAND_CLASS_BINARY_SENSOR, - GENERIC_COMMAND_CLASS_BINARY_SWITCH, - GENERIC_COMMAND_CLASS_ENTRY_CONTROL, - GENERIC_COMMAND_CLASS_MULTILEVEL_SENSOR, - GENERIC_COMMAND_CLASS_MULTILEVEL_SWITCH, - GENERIC_COMMAND_CLASS_NOTIFICATION, - GENERIC_COMMAND_CLASS_REMOTE_CONTROLLER, - GENERIC_COMMAND_CLASS_REMOTE_SWITCH, - GENERIC_COMMAND_CLASS_REPEATER_SLAVE, - GENERIC_COMMAND_CLASS_THERMOSTAT, - GENERIC_COMMAND_CLASS_WALL_CONTROLLER], - [SPECIFIC_DEVICE_CLASS_WHATEVER], - [COMMAND_CLASS_SWITCH_BINARY], - TYPE_BOOL, - GENRE_USER), + [const.GENERIC_TYPE_SENSOR_ALARM, + const.GENERIC_TYPE_SENSOR_BINARY, + const.GENERIC_TYPE_SWITCH_BINARY, + const.GENERIC_TYPE_ENTRY_CONTROL, + const.GENERIC_TYPE_SENSOR_MULTILEVEL, + const.GENERIC_TYPE_SWITCH_MULTILEVEL, + const.GENERIC_TYPE_SENSOR_NOTIFICATION, + const.GENERIC_TYPE_GENERIC_CONTROLLER, + const.GENERIC_TYPE_SWITCH_REMOTE, + const.GENERIC_TYPE_REPEATER_SLAVE, + const.GENERIC_TYPE_THERMOSTAT, + const.GENERIC_TYPE_WALL_CONTROLLER], + [const.SPECIFIC_TYPE_WHATEVER], + [const.COMMAND_CLASS_SWITCH_BINARY], + const.TYPE_BOOL, + const.GENRE_USER), ('binary_sensor', - [GENERIC_COMMAND_CLASS_ALARM_SENSOR, - GENERIC_COMMAND_CLASS_BINARY_SENSOR, - GENERIC_COMMAND_CLASS_BINARY_SWITCH, - GENERIC_COMMAND_CLASS_METER, - GENERIC_COMMAND_CLASS_MULTILEVEL_SENSOR, - GENERIC_COMMAND_CLASS_MULTILEVEL_SWITCH, - GENERIC_COMMAND_CLASS_NOTIFICATION, - GENERIC_COMMAND_CLASS_THERMOSTAT], - [SPECIFIC_DEVICE_CLASS_WHATEVER], - [COMMAND_CLASS_SENSOR_BINARY], - TYPE_BOOL, - GENRE_USER), + [const.GENERIC_TYPE_SENSOR_ALARM, + const.GENERIC_TYPE_SENSOR_BINARY, + const.GENERIC_TYPE_SWITCH_BINARY, + const.GENERIC_TYPE_METER, + const.GENERIC_TYPE_SENSOR_MULTILEVEL, + const.GENERIC_TYPE_SWITCH_MULTILEVEL, + const.GENERIC_TYPE_SENSOR_NOTIFICATION, + const.GENERIC_TYPE_THERMOSTAT], + [const.SPECIFIC_TYPE_WHATEVER], + [const.COMMAND_CLASS_SENSOR_BINARY], + const.TYPE_BOOL, + const.GENRE_USER), ('lock', - [GENERIC_COMMAND_CLASS_ENTRY_CONTROL], - [SPECIFIC_DEVICE_CLASS_ADVANCED_DOOR_LOCK, - SPECIFIC_DEVICE_CLASS_SECURE_KEYPAD_DOOR_LOCK], - [COMMAND_CLASS_DOOR_LOCK], - TYPE_BOOL, - GENRE_USER), + [const.GENERIC_TYPE_ENTRY_CONTROL], + [const.SPECIFIC_TYPE_ADVANCED_DOOR_LOCK, + const.SPECIFIC_TYPE_SECURE_KEYPAD_DOOR_LOCK], + [const.COMMAND_CLASS_DOOR_LOCK], + const.TYPE_BOOL, + const.GENRE_USER), ('cover', - [GENERIC_COMMAND_CLASS_MULTILEVEL_SWITCH, - GENERIC_COMMAND_CLASS_ENTRY_CONTROL], - [SPECIFIC_DEVICE_CLASS_MOTOR_CONTROL_CLASS_A, - SPECIFIC_DEVICE_CLASS_MOTOR_CONTROL_CLASS_B, - SPECIFIC_DEVICE_CLASS_MOTOR_CONTROL_CLASS_C, - SPECIFIC_DEVICE_CLASS_MULTIPOSITION_MOTOR, - SPECIFIC_DEVICE_CLASS_SECURE_BARRIER_ADD_ON, - SPECIFIC_DEVICE_CLASS_SECURE_DOOR], - [COMMAND_CLASS_SWITCH_BINARY, - COMMAND_CLASS_BARRIER_OPERATOR, - COMMAND_CLASS_SWITCH_MULTILEVEL], - TYPE_WHATEVER, - GENRE_USER), + [const.GENERIC_TYPE_SWITCH_MULTILEVEL, + const.GENERIC_TYPE_ENTRY_CONTROL], + [const.SPECIFIC_TYPE_CLASS_A_MOTOR_CONTROL, + const.SPECIFIC_TYPE_CLASS_B_MOTOR_CONTROL, + const.SPECIFIC_TYPE_CLASS_C_MOTOR_CONTROL, + const.SPECIFIC_TYPE_MOTOR_MULTIPOSITION, + const.SPECIFIC_TYPE_SECURE_BARRIER_ADDON, + const.SPECIFIC_TYPE_SECURE_DOOR], + [const.COMMAND_CLASS_SWITCH_BINARY, + const.COMMAND_CLASS_BARRIER_OPERATOR, + const.COMMAND_CLASS_SWITCH_MULTILEVEL], + const.TYPE_WHATEVER, + const.GENRE_USER), ('climate', - [GENERIC_COMMAND_CLASS_THERMOSTAT], - [SPECIFIC_DEVICE_CLASS_WHATEVER], - [COMMAND_CLASS_THERMOSTAT_SETPOINT], - TYPE_WHATEVER, - GENRE_WHATEVER), + [const.GENERIC_TYPE_THERMOSTAT], + [const.SPECIFIC_TYPE_WHATEVER], + [const.COMMAND_CLASS_THERMOSTAT_SETPOINT], + const.TYPE_WHATEVER, + const.GENRE_WHATEVER), ] - -ATTR_NODE_ID = "node_id" -ATTR_VALUE_ID = "value_id" -ATTR_OBJECT_ID = "object_id" -ATTR_NAME = "name" -ATTR_SCENE_ID = "scene_id" -ATTR_BASIC_LEVEL = "basic_level" - RENAME_NODE_SCHEMA = vol.Schema({ vol.Required(ATTR_ENTITY_ID): cv.entity_id, - vol.Required(ATTR_NAME): cv.string, + vol.Required(const.ATTR_NAME): cv.string, }) -NETWORK = None - _LOGGER = logging.getLogger(__name__) @@ -386,23 +305,23 @@ def value_added(node, value): value.disable_poll() discovery.load_platform(hass, component, DOMAIN, { - ATTR_NODE_ID: node.node_id, - ATTR_VALUE_ID: value.value_id, + const.ATTR_NODE_ID: node.node_id, + const.ATTR_VALUE_ID: value.value_id, }, config) def scene_activated(node, scene_id): """Called when a scene is activated on any node in the network.""" - hass.bus.fire(EVENT_SCENE_ACTIVATED, { + hass.bus.fire(const.EVENT_SCENE_ACTIVATED, { ATTR_ENTITY_ID: _node_object_id(node), - ATTR_OBJECT_ID: _node_object_id(node), - ATTR_SCENE_ID: scene_id + const.ATTR_OBJECT_ID: _node_object_id(node), + const.ATTR_SCENE_ID: scene_id }) def node_event_activated(node, value): """Called when a nodeevent is activated on any node in the network.""" - hass.bus.fire(EVENT_NODE_EVENT, { - ATTR_OBJECT_ID: _node_object_id(node), - ATTR_BASIC_LEVEL: value + hass.bus.fire(const.EVENT_NODE_EVENT, { + const.ATTR_OBJECT_ID: _node_object_id(node), + const.ATTR_BASIC_LEVEL: value }) def network_ready(): @@ -410,13 +329,13 @@ def network_ready(): _LOGGER.info("Zwave network is ready for use. All awake nodes" " have been queried. Sleeping nodes will be" " queried when they awake.") - hass.bus.fire(EVENT_NETWORK_READY) + hass.bus.fire(const.EVENT_NETWORK_READY) def network_complete(): """Called when all nodes on network have been queried.""" _LOGGER.info("Zwave network is complete. All nodes on the network" " have been queried") - hass.bus.fire(EVENT_NETWORK_COMPLETE) + hass.bus.fire(const.EVENT_NETWORK_COMPLETE) dispatcher.connect( value_added, ZWaveNetwork.SIGNAL_VALUE_ADDED, weak=False) @@ -468,14 +387,14 @@ def stop_zwave(_service_or_event): """Stop Z-Wave network.""" _LOGGER.info("Stopping ZWave network.") NETWORK.stop() - hass.bus.fire(EVENT_NETWORK_STOP) + hass.bus.fire(const.EVENT_NETWORK_STOP) def rename_node(service): """Rename a node.""" state = hass.states.get(service.data.get(ATTR_ENTITY_ID)) - node_id = state.attributes.get(ATTR_NODE_ID) + node_id = state.attributes.get(const.ATTR_NODE_ID) node = NETWORK.nodes[node_id] - name = service.data.get(ATTR_NAME) + name = service.data.get(const.ATTR_NAME) node.name = name _LOGGER.info( "Renamed ZWave node %d to %s", node_id, name) @@ -484,12 +403,12 @@ def start_zwave(_service_or_event): """Startup Z-Wave network.""" _LOGGER.info("Starting ZWave network.") NETWORK.start() - hass.bus.fire(EVENT_NETWORK_START) + hass.bus.fire(const.EVENT_NETWORK_START) # Need to be in STATE_AWAKED before talking to nodes. # Wait up to NETWORK_READY_WAIT_SECS seconds for the zwave network # to be ready. - for i in range(NETWORK_READY_WAIT_SECS): + for i in range(const.NETWORK_READY_WAIT_SECS): _LOGGER.debug( "network state: %d %s", NETWORK.state, NETWORK.state_str) if NETWORK.state >= NETWORK.STATE_AWAKED: @@ -499,7 +418,7 @@ def start_zwave(_service_or_event): else: _LOGGER.warning( "zwave not ready after %d seconds, continuing anyway", - NETWORK_READY_WAIT_SECS) + const.NETWORK_READY_WAIT_SECS) _LOGGER.info( "final network state: %d %s", NETWORK.state, NETWORK.state_str) @@ -514,18 +433,31 @@ def start_zwave(_service_or_event): hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zwave) # Register node services for Z-Wave network - hass.services.register(DOMAIN, SERVICE_ADD_NODE, add_node) - hass.services.register(DOMAIN, SERVICE_ADD_NODE_SECURE, - add_node_secure) - hass.services.register(DOMAIN, SERVICE_REMOVE_NODE, remove_node) - hass.services.register(DOMAIN, SERVICE_CANCEL_COMMAND, cancel_command) - hass.services.register(DOMAIN, SERVICE_HEAL_NETWORK, heal_network) - hass.services.register(DOMAIN, SERVICE_SOFT_RESET, soft_reset) - hass.services.register(DOMAIN, SERVICE_TEST_NETWORK, test_network) - hass.services.register(DOMAIN, SERVICE_STOP_NETWORK, stop_zwave) - hass.services.register(DOMAIN, SERVICE_START_NETWORK, start_zwave) - hass.services.register(DOMAIN, SERVICE_RENAME_NODE, rename_node, - descriptions[DOMAIN][SERVICE_RENAME_NODE], + hass.services.register(DOMAIN, const.SERVICE_ADD_NODE, add_node, + descriptions[const.SERVICE_ADD_NODE]) + hass.services.register(DOMAIN, const.SERVICE_ADD_NODE_SECURE, + add_node_secure, + descriptions[const.SERVICE_ADD_NODE_SECURE]) + hass.services.register(DOMAIN, const.SERVICE_REMOVE_NODE, remove_node, + descriptions[const.SERVICE_REMOVE_NODE]) + hass.services.register(DOMAIN, const.SERVICE_CANCEL_COMMAND, + cancel_command, + descriptions[const.SERVICE_CANCEL_COMMAND]) + hass.services.register(DOMAIN, const.SERVICE_HEAL_NETWORK, + heal_network, + descriptions[const.SERVICE_HEAL_NETWORK]) + hass.services.register(DOMAIN, const.SERVICE_SOFT_RESET, soft_reset, + descriptions[const.SERVICE_SOFT_RESET]) + hass.services.register(DOMAIN, const.SERVICE_TEST_NETWORK, + test_network, + descriptions[const.SERVICE_TEST_NETWORK]) + hass.services.register(DOMAIN, const.SERVICE_STOP_NETWORK, stop_zwave, + descriptions[const.SERVICE_STOP_NETWORK]) + hass.services.register(DOMAIN, const.SERVICE_START_NETWORK, + start_zwave, + descriptions[const.SERVICE_START_NETWORK]) + hass.services.register(DOMAIN, const.SERVICE_RENAME_NODE, rename_node, + descriptions[const.SERVICE_RENAME_NODE], schema=RENAME_NODE_SCHEMA) # Setup autoheal @@ -574,7 +506,7 @@ def _object_id(self): def device_state_attributes(self): """Return the device specific state attributes.""" attrs = { - ATTR_NODE_ID: self._value.node.node_id, + const.ATTR_NODE_ID: self._value.node.node_id, } battery_level = self._value.node.get_battery_level() diff --git a/homeassistant/components/zwave/const.py b/homeassistant/components/zwave/const.py new file mode 100644 index 0000000000000..155bc545ad417 --- /dev/null +++ b/homeassistant/components/zwave/const.py @@ -0,0 +1,292 @@ +"""Z-Wave Constants.""" + +ATTR_NODE_ID = "node_id" +ATTR_VALUE_ID = "value_id" +ATTR_OBJECT_ID = "object_id" +ATTR_NAME = "name" +ATTR_SCENE_ID = "scene_id" +ATTR_BASIC_LEVEL = "basic_level" +NETWORK_READY_WAIT_SECS = 30 + +SERVICE_ADD_NODE = "add_node" +SERVICE_ADD_NODE_SECURE = "add_node_secure" +SERVICE_REMOVE_NODE = "remove_node" +SERVICE_CANCEL_COMMAND = "cancel_command" +SERVICE_HEAL_NETWORK = "heal_network" +SERVICE_SOFT_RESET = "soft_reset" +SERVICE_TEST_NETWORK = "test_network" +SERVICE_STOP_NETWORK = "stop_network" +SERVICE_START_NETWORK = "start_network" +SERVICE_RENAME_NODE = "rename_node" + +EVENT_SCENE_ACTIVATED = "zwave.scene_activated" +EVENT_NODE_EVENT = "zwave.node_event" +EVENT_NETWORK_READY = "zwave.network_ready" +EVENT_NETWORK_COMPLETE = "zwave.network_complete" +EVENT_NETWORK_START = "zwave.network_start" +EVENT_NETWORK_STOP = "zwave.network_stop" + +COMMAND_CLASS_ALARM = 113 +COMMAND_CLASS_ANTITHEFT = 93 +COMMAND_CLASS_APPLICATION_CAPABILITY = 87 +COMMAND_CLASS_APPLICATION_STATUS = 34 +COMMAND_CLASS_ASSOCIATION = 133 +COMMAND_CLASS_ASSOCIATION_COMMAND_CONFIGURATION = 155 +COMMAND_CLASS_ASSOCIATION_GRP_INFO = 89 +COMMAND_CLASS_BARRIER_OPERATOR = 102 +COMMAND_CLASS_BASIC = 32 +COMMAND_CLASS_BASIC_TARIFF_INFO = 54 +COMMAND_CLASS_BASIC_WINDOW_COVERING = 80 +COMMAND_CLASS_BATTERY = 128 +COMMAND_CLASS_CENTRAL_SCENE = 91 +COMMAND_CLASS_CLIMATE_CONTROL_SCHEDULE = 70 +COMMAND_CLASS_CLOCK = 129 +COMMAND_CLASS_CONFIGURATION = 112 +COMMAND_CLASS_CONTROLLER_REPLICATION = 33 +COMMAND_CLASS_CRC_16_ENCAP = 86 +COMMAND_CLASS_DCP_CONFIG = 58 +COMMAND_CLASS_DCP_MONITOR = 59 +COMMAND_CLASS_DEVICE_RESET_LOCALLY = 90 +COMMAND_CLASS_DOOR_LOCK = 98 +COMMAND_CLASS_DOOR_LOCK_LOGGING = 76 +COMMAND_CLASS_ENERGY_PRODUCTION = 144 +COMMAND_CLASS_ENTRY_CONTROL = 111 +COMMAND_CLASS_FIRMWARE_UPDATE_MD = 122 +COMMAND_CLASS_GEOGRAPHIC_LOCATION = 140 +COMMAND_CLASS_GROUPING_NAME = 123 +COMMAND_CLASS_HAIL = 130 +COMMAND_CLASS_HRV_CONTROL = 57 +COMMAND_CLASS_HRV_STATUS = 55 +COMMAND_CLASS_HUMIDITY_CONTROL_MODE = 109 +COMMAND_CLASS_HUMIDITY_CONTROL_OPERATING_STATE = 110 +COMMAND_CLASS_HUMIDITY_CONTROL_SETPOINT = 100 +COMMAND_CLASS_INDICATOR = 135 +COMMAND_CLASS_IP_ASSOCIATION = 92 +COMMAND_CLASS_IP_CONFIGURATION = 14 +COMMAND_CLASS_IRRIGATION = 107 +COMMAND_CLASS_LANGUAGE = 137 +COMMAND_CLASS_LOCK = 118 +COMMAND_CLASS_MAILBOX = 105 +COMMAND_CLASS_MANUFACTURER_PROPRIETARY = 145 +COMMAND_CLASS_MANUFACTURER_SPECIFIC = 114 +COMMAND_CLASS_MARK = 239 +COMMAND_CLASS_METER = 50 +COMMAND_CLASS_METER_PULSE = 53 +COMMAND_CLASS_METER_TBL_CONFIG = 60 +COMMAND_CLASS_METER_TBL_MONITOR = 61 +COMMAND_CLASS_METER_TBL_PUSH = 62 +COMMAND_CLASS_MTP_WINDOW_COVERING = 81 +COMMAND_CLASS_MULTI_CHANNEL = 96 +COMMAND_CLASS_MULTI_CHANNEL_ASSOCIATION = 142 +COMMAND_CLASS_MULTI_COMMAND = 143 +COMMAND_CLASS_NETWORK_MANAGEMENT_BASIC = 77 +COMMAND_CLASS_NETWORK_MANAGEMENT_INCLUSION = 52 +COMMAND_CLASS_NETWORK_MANAGEMENT_PRIMARY = 84 +COMMAND_CLASS_NETWORK_MANAGEMENT_PROXY = 82 +COMMAND_CLASS_NO_OPERATION = 0 +COMMAND_CLASS_NODE_NAMING = 119 +COMMAND_CLASS_NON_INTEROPERABLE = 240 +COMMAND_CLASS_NOTIFICATION = 113 +COMMAND_CLASS_POWERLEVEL = 115 +COMMAND_CLASS_PREPAYMENT = 63 +COMMAND_CLASS_PREPAYMENT_ENCAPSULATION = 65 +COMMAND_CLASS_PROPRIETARY = 136 +COMMAND_CLASS_PROTECTION = 117 +COMMAND_CLASS_RATE_TBL_CONFIG = 72 +COMMAND_CLASS_RATE_TBL_MONITOR = 73 +COMMAND_CLASS_REMOTE_ASSOCIATION_ACTIVATE = 124 +COMMAND_CLASS_REMOTE_ASSOCIATION = 125 +COMMAND_CLASS_SCENE_ACTIVATION = 43 +COMMAND_CLASS_SCENE_ACTUATOR_CONF = 44 +COMMAND_CLASS_SCENE_CONTROLLER_CONF = 45 +COMMAND_CLASS_SCHEDULE = 83 +COMMAND_CLASS_SCHEDULE_ENTRY_LOCK = 78 +COMMAND_CLASS_SCREEN_ATTRIBUTES = 147 +COMMAND_CLASS_SCREEN_MD = 146 +COMMAND_CLASS_SECURITY = 152 +COMMAND_CLASS_SECURITY_SCHEME0_MARK = 61696 +COMMAND_CLASS_SENSOR_ALARM = 156 +COMMAND_CLASS_SENSOR_BINARY = 48 +COMMAND_CLASS_SENSOR_CONFIGURATION = 158 +COMMAND_CLASS_SENSOR_MULTILEVEL = 49 +COMMAND_CLASS_SILENCE_ALARM = 157 +COMMAND_CLASS_SIMPLE_AV_CONTROL = 148 +COMMAND_CLASS_SUPERVISION = 108 +COMMAND_CLASS_SWITCH_ALL = 39 +COMMAND_CLASS_SWITCH_BINARY = 37 +COMMAND_CLASS_SWITCH_COLOR = 51 +COMMAND_CLASS_SWITCH_MULTILEVEL = 38 +COMMAND_CLASS_SWITCH_TOGGLE_BINARY = 40 +COMMAND_CLASS_SWITCH_TOGGLE_MULTILEVEL = 41 +COMMAND_CLASS_TARIFF_TBL_CONFIG = 74 +COMMAND_CLASS_TARIFF_TBL_MONITOR = 75 +COMMAND_CLASS_THERMOSTAT_FAN_MODE = 68 +COMMAND_CLASS_THERMOSTAT_FAN_STATE = 69 +COMMAND_CLASS_THERMOSTAT_MODE = 64 +COMMAND_CLASS_THERMOSTAT_OPERATING_STATE = 66 +COMMAND_CLASS_THERMOSTAT_SETBACK = 71 +COMMAND_CLASS_THERMOSTAT_SETPOINT = 67 +COMMAND_CLASS_TIME = 138 +COMMAND_CLASS_TIME_PARAMETERS = 139 +COMMAND_CLASS_TRANSPORT_SERVICE = 85 +COMMAND_CLASS_USER_CODE = 99 +COMMAND_CLASS_VERSION = 134 +COMMAND_CLASS_WAKE_UP = 132 +COMMAND_CLASS_ZIP = 35 +COMMAND_CLASS_ZIP_NAMING = 104 +COMMAND_CLASS_ZIP_ND = 88 +COMMAND_CLASS_ZIP_6LOWPAN = 79 +COMMAND_CLASS_ZIP_GATEWAY = 95 +COMMAND_CLASS_ZIP_PORTAL = 97 +COMMAND_CLASS_ZWAVEPLUS_INFO = 94 +COMMAND_CLASS_WHATEVER = None # Match ALL +COMMAND_CLASS_WINDOW_COVERING = 106 + +GENERIC_TYPE_WHATEVER = None # Match ALL +SPECIFIC_TYPE_WHATEVER = None # Match ALL +SPECIFIC_TYPE_NOT_USED = 0 # Available in all Generic types + +GENERIC_TYPE_AV_CONTROL_POINT = 3 +SPECIFIC_TYPE_DOORBELL = 18 +SPECIFIC_TYPE_SATELLITE_RECIEVER = 4 +SPECIFIC_TYPE_SATELLITE_RECIEVER_V2 = 17 + +GENERIC_TYPE_DISPLAY = 4 +SPECIFIC_TYPE_SIMPLE_DISPLAY = 1 + +GENERIC_TYPE_ENTRY_CONTROL = 64 +SPECIFIC_TYPE_DOOR_LOCK = 1 +SPECIFIC_TYPE_ADVANCED_DOOR_LOCK = 2 +SPECIFIC_TYPE_SECURE_KEYPAD_DOOR_LOCK = 3 +SPECIFIC_TYPE_SECURE_KEYPAD_DOOR_LOCK_DEADBOLT = 4 +SPECIFIC_TYPE_SECURE_DOOR = 5 +SPECIFIC_TYPE_SECURE_GATE = 6 +SPECIFIC_TYPE_SECURE_BARRIER_ADDON = 7 +SPECIFIC_TYPE_SECURE_BARRIER_OPEN_ONLY = 8 +SPECIFIC_TYPE_SECURE_BARRIER_CLOSE_ONLY = 9 +SPECIFIC_TYPE_SECURE_LOCKBOX = 10 +SPECIFIC_TYPE_SECURE_KEYPAD = 11 + +GENERIC_TYPE_GENERIC_CONTROLLER = 1 +SPECIFIC_TYPE_PORTABLE_CONTROLLER = 1 +SPECIFIC_TYPE_PORTABLE_SCENE_CONTROLLER = 2 +SPECIFIC_TYPE_PORTABLE_INSTALLER_TOOL = 3 +SPECIFIC_TYPE_REMOTE_CONTROL_AV = 4 +SPECIFIC_TYPE_REMOTE_CONTROL_SIMPLE = 6 + +GENERIC_TYPE_METER = 49 +SPECIFIC_TYPE_SIMPLE_METER = 1 +SPECIFIC_TYPE_ADV_ENERGY_CONTROL = 2 +SPECIFIC_TYPE_WHOLE_HOME_METER_SIMPLE = 3 + +GENERIC_TYPE_METER_PULSE = 48 + +GENERIC_TYPE_NON_INTEROPERABLE = 255 + +GENERIC_TYPE_REPEATER_SLAVE = 15 +SPECIFIC_TYPE_REPEATER_SLAVE = 1 +SPECIFIC_TYPE_VIRTUAL_NODE = 2 + +GENERIC_TYPE_SECURITY_PANEL = 23 +SPECIFIC_TYPE_ZONED_SECURITY_PANEL = 1 + +GENERIC_TYPE_SEMI_INTEROPERABLE = 80 +SPECIFIC_TYPE_ENERGY_PRODUCTION = 1 + +GENERIC_TYPE_SENSOR_ALARM = 161 +SPECIFIC_TYPE_ADV_ZENSOR_NET_ALARM_SENSOR = 5 +SPECIFIC_TYPE_ADV_ZENSOR_NET_SMOKE_SENSOR = 10 +SPECIFIC_TYPE_BASIC_ROUTING_ALARM_SENSOR = 1 +SPECIFIC_TYPE_BASIC_ROUTING_SMOKE_SENSOR = 6 +SPECIFIC_TYPE_BASIC_ZENSOR_NET_ALARM_SENSOR = 3 +SPECIFIC_TYPE_BASIC_ZENSOR_NET_SMOKE_SENSOR = 8 +SPECIFIC_TYPE_ROUTING_ALARM_SENSOR = 2 +SPECIFIC_TYPE_ROUTING_SMOKE_SENSOR = 7 +SPECIFIC_TYPE_ZENSOR_NET_ALARM_SENSOR = 4 +SPECIFIC_TYPE_ZENSOR_NET_SMOKE_SENSOR = 9 +SPECIFIC_TYPE_ALARM_SENSOR = 11 + +GENERIC_TYPE_SENSOR_BINARY = 32 +SPECIFIC_TYPE_ROUTING_SENSOR_BINARY = 1 + +GENERIC_TYPE_SENSOR_MULTILEVEL = 33 +SPECIFIC_TYPE_ROUTING_SENSOR_MULTILEVEL = 1 +SPECIFIC_TYPE_CHIMNEY_FAN = 2 + +GENERIC_TYPE_STATIC_CONTROLLER = 2 +SPECIFIC_TYPE_PC_CONTROLLER = 1 +SPECIFIC_TYPE_SCENE_CONTROLLER = 2 +SPECIFIC_TYPE_STATIC_INSTALLER_TOOL = 3 +SPECIFIC_TYPE_SET_TOP_BOX = 4 +SPECIFIC_TYPE_SUB_SYSTEM_CONTROLLER = 5 +SPECIFIC_TYPE_TV = 6 +SPECIFIC_TYPE_GATEWAY = 7 + +GENERIC_TYPE_SWITCH_BINARY = 16 +SPECIFIC_TYPE_POWER_SWITCH_BINARY = 1 +SPECIFIC_TYPE_SCENE_SWITCH_BINARY = 3 +SPECIFIC_TYPE_POWER_STRIP = 4 +SPECIFIC_TYPE_SIREN = 5 +SPECIFIC_TYPE_VALVE_OPEN_CLOSE = 6 +SPECIFIC_TYPE_COLOR_TUNABLE_BINARY = 2 +SPECIFIC_TYPE_IRRIGATION_CONTROLLER = 7 + +GENERIC_TYPE_SWITCH_MULTILEVEL = 17 +SPECIFIC_TYPE_CLASS_A_MOTOR_CONTROL = 5 +SPECIFIC_TYPE_CLASS_B_MOTOR_CONTROL = 6 +SPECIFIC_TYPE_CLASS_C_MOTOR_CONTROL = 7 +SPECIFIC_TYPE_MOTOR_MULTIPOSITION = 3 +SPECIFIC_TYPE_POWER_SWITCH_MULTILEVEL = 1 +SPECIFIC_TYPE_SCENE_SWITCH_MULTILEVEL = 4 +SPECIFIC_TYPE_FAN_SWITCH = 8 +SPECIFIC_TYPE_COLOR_TUNABLE_MULTILEVEL = 2 + +GENERIC_TYPE_SWITCH_REMOTE = 18 +SPECIFIC_TYPE_REMOTE_BINARY = 1 +SPECIFIC_TYPE_REMOTE_MULTILEVEL = 2 +SPECIFIC_TYPE_REMOTE_TOGGLE_BINARY = 3 +SPECIFIC_TYPE_REMOTE_TOGGLE_MULTILEVEL = 4 + +GENERIC_TYPE_SWITCH_TOGGLE = 19 +SPECIFIC_TYPE_SWITCH_TOGGLE_BINARY = 1 +SPECIFIC_TYPE_SWITCH_TOGGLE_MULTILEVEL = 2 + +GENERIC_TYPE_THERMOSTAT = 8 +SPECIFIC_TYPE_SETBACK_SCHEDULE_THERMOSTAT = 3 +SPECIFIC_TYPE_SETBACK_THERMOSTAT = 5 +SPECIFIC_TYPE_SETPOINT_THERMOSTAT = 4 +SPECIFIC_TYPE_THERMOSTAT_GENERAL = 2 +SPECIFIC_TYPE_THERMOSTAT_GENERAL_V2 = 6 +SPECIFIC_TYPE_THERMOSTAT_HEATING = 1 + +GENERIC_TYPE_VENTILATION = 22 +SPECIFIC_TYPE_RESIDENTIAL_HRV = 1 + +GENERIC_TYPE_WINDOWS_COVERING = 9 +SPECIFIC_TYPE_SIMPLE_WINDOW_COVERING = 1 + +GENERIC_TYPE_ZIP_NODE = 21 +SPECIFIC_TYPE_ZIP_ADV_NODE = 2 +SPECIFIC_TYPE_ZIP_TUN_NODE = 1 + +GENERIC_TYPE_WALL_CONTROLLER = 24 +SPECIFIC_TYPE_BASIC_WALL_CONTROLLER = 1 + +GENERIC_TYPE_NETWORK_EXTENDER = 5 +SPECIFIC_TYPE_SECURE_EXTENDER = 1 + +GENERIC_TYPE_APPLIANCE = 6 +SPECIFIC_TYPE_GENERAL_APPLIANCE = 1 +SPECIFIC_TYPE_KITCHEN_APPLIANCE = 2 +SPECIFIC_TYPE_LAUNDRY_APPLIANCE = 3 + +GENERIC_TYPE_SENSOR_NOTIFICATION = 7 +SPECIFIC_TYPE_NOTIFICATION_SENSOR = 1 + +GENRE_WHATEVER = None +GENRE_USER = "User" + +TYPE_WHATEVER = None +TYPE_BYTE = "Byte" +TYPE_BOOL = "Bool" +TYPE_DECIMAL = "Decimal" diff --git a/homeassistant/components/zwave/services.yaml b/homeassistant/components/zwave/services.yaml new file mode 100644 index 0000000000000..234faf0a87dd2 --- /dev/null +++ b/homeassistant/components/zwave/services.yaml @@ -0,0 +1,36 @@ +add_node: + description: Add a new node to the Z-Wave network. Refer to OZW.log for details. + +add_node_secure: + description: Add a new node to the Z-Wave network with secure communications. Node must support this, and network key must be set. Refer to OZW.log for details. + +cancel_command: + description: Cancel a running Z-Wave controller command. Use this to exit add_node, if you wasn't going to use it but activated it. + +heal_network: + description: Start a Z-Wave network heal. This might take a while and will slow down the Z-Wave network greatly while it is being processed. Refer to OZW.log for details. + +remove_node: + description: Remove a node from the Z-Wave network. Refer to OZW.log for details. + +start_network: + description: Start the Z-Wave network. This might take a while, depending on how big your Z-Wave network is. + +stop_network: + description: Stop the Z-Wave network, all updates into HASS will stop. + +soft_reset: + description: This will reset the controller without removing its data. Use carefully because not all controllers support this. Refer to controllers manual. + +test_network: + description: This will send test to nodes in the Z-Wave network. This will greatly slow down the Z-Wave network while it is being processed. Refer to OZW.log for details. + +rename_node: + description: Set the name(s) of a node. + fields: + entity_id: + description: Name(s) of entities to to rename + example: 'light.leviton_vrmx11lz_multilevel_scene_switch_level_40' + name: + description: New Name + example: 'kitchen' From 7e50ccd32a1e231e1fa64ad162d0711b28b09be2 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 30 Sep 2016 18:30:44 +0200 Subject: [PATCH 020/112] Component for Digital Ocean (#3322) * Add Digital Ocean implementation * Remove kernel --- .coveragerc | 3 + .../components/binary_sensor/digital_ocean.py | 91 +++++++++++++++++ homeassistant/components/digital_ocean.py | 86 ++++++++++++++++ .../components/switch/digital_ocean.py | 97 +++++++++++++++++++ requirements_all.txt | 3 + 5 files changed, 280 insertions(+) create mode 100644 homeassistant/components/binary_sensor/digital_ocean.py create mode 100644 homeassistant/components/digital_ocean.py create mode 100644 homeassistant/components/switch/digital_ocean.py diff --git a/.coveragerc b/.coveragerc index 0bfa3fb1a04f4..c2a0e2636e816 100644 --- a/.coveragerc +++ b/.coveragerc @@ -16,6 +16,9 @@ omit = homeassistant/components/bloomsky.py homeassistant/components/*/bloomsky.py + homeassistant/components/digital_ocean.py + homeassistant/components/*/digital_ocean.py + homeassistant/components/dweet.py homeassistant/components/*/dweet.py diff --git a/homeassistant/components/binary_sensor/digital_ocean.py b/homeassistant/components/binary_sensor/digital_ocean.py new file mode 100644 index 0000000000000..821acb2da95aa --- /dev/null +++ b/homeassistant/components/binary_sensor/digital_ocean.py @@ -0,0 +1,91 @@ +""" +Support for monitoring the state of Digital Ocean droplets. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/binary_sensor.digital_ocean/ +""" +import logging + +import voluptuous as vol + +from homeassistant.components.binary_sensor import ( + BinarySensorDevice, PLATFORM_SCHEMA) +from homeassistant.components.digital_ocean import ( + CONF_DROPLETS, ATTR_CREATED_AT, ATTR_DROPLET_ID, ATTR_DROPLET_NAME, + ATTR_FEATURES, ATTR_IPV4_ADDRESS, ATTR_IPV6_ADDRESS, ATTR_MEMORY, + ATTR_REGION, ATTR_VCPUS) +from homeassistant.loader import get_component +import homeassistant.helpers.config_validation as cv + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_NAME = 'Droplet' +DEFAULT_SENSOR_CLASS = 'motion' +DEPENDENCIES = ['digital_ocean'] + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_DROPLETS): vol.All(cv.ensure_list, [cv.string]), +}) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Setup the Digital Ocean droplet sensor.""" + digital_ocean = get_component('digital_ocean') + droplets = config.get(CONF_DROPLETS) + + dev = [] + for droplet in droplets: + droplet_id = digital_ocean.DIGITAL_OCEAN.get_droplet_id(droplet) + dev.append(DigitalOceanBinarySensor( + digital_ocean.DIGITAL_OCEAN, droplet_id)) + + add_devices(dev) + + +class DigitalOceanBinarySensor(BinarySensorDevice): + """Representation of a Digital Ocean droplet sensor.""" + + def __init__(self, do, droplet_id): + """Initialize a new Digital Ocean sensor.""" + self._digital_ocean = do + self._droplet_id = droplet_id + self._state = None + self.update() + + @property + def name(self): + """Return the name of the sensor.""" + return self.data.name + + @property + def is_on(self): + """Return true if the binary sensor is on.""" + return self.data.status == 'active' + + @property + def sensor_class(self): + """Return the class of this sensor.""" + return DEFAULT_SENSOR_CLASS + + @property + def state_attributes(self): + """Return the state attributes of the Digital Ocean droplet.""" + return { + ATTR_CREATED_AT: self.data.created_at, + ATTR_DROPLET_ID: self.data.id, + ATTR_DROPLET_NAME: self.data.name, + ATTR_FEATURES: self.data.features, + ATTR_IPV4_ADDRESS: self.data.ip_address, + ATTR_IPV6_ADDRESS: self.data.ip_v6_address, + ATTR_MEMORY: self.data.memory, + ATTR_REGION: self.data.region['name'], + ATTR_VCPUS: self.data.vcpus, + } + + def update(self): + """Update state of sensor.""" + self._digital_ocean.update() + + for droplet in self._digital_ocean.data: + if droplet.id == self._droplet_id: + self.data = droplet diff --git a/homeassistant/components/digital_ocean.py b/homeassistant/components/digital_ocean.py new file mode 100644 index 0000000000000..b91ec2672afff --- /dev/null +++ b/homeassistant/components/digital_ocean.py @@ -0,0 +1,86 @@ +""" +Support for Digital Ocean. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/digital_ocean/ +""" +import logging +from datetime import timedelta + +import voluptuous as vol + +from homeassistant.const import CONF_ACCESS_TOKEN +from homeassistant.util import Throttle +import homeassistant.helpers.config_validation as cv + +REQUIREMENTS = ['python-digitalocean==1.9.0'] + +_LOGGER = logging.getLogger(__name__) + +ATTR_CREATED_AT = 'created_at' +ATTR_DROPLET_ID = 'droplet_id' +ATTR_DROPLET_NAME = 'droplet_name' +ATTR_FEATURES = 'features' +ATTR_IPV4_ADDRESS = 'ipv4_address' +ATTR_IPV6_ADDRESS = 'ipv6_address' +ATTR_MEMORY = 'memory' +ATTR_REGION = 'region' +ATTR_VCPUS = 'vcpus' + +CONF_DROPLETS = 'droplets' + +DIGITAL_OCEAN = None +DIGITAL_OCEAN_PLATFORMS = ['switch', 'binary_sensor'] +DOMAIN = 'digital_ocean' + +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60) + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({ + vol.Required(CONF_ACCESS_TOKEN): cv.string, + }), +}, extra=vol.ALLOW_EXTRA) + + +# pylint: disable=unused-argument,too-few-public-methods +def setup(hass, config): + """Setup the Digital Ocean component.""" + conf = config[DOMAIN] + access_token = conf.get(CONF_ACCESS_TOKEN) + + global DIGITAL_OCEAN + DIGITAL_OCEAN = DigitalOcean(access_token) + + if not DIGITAL_OCEAN.manager.get_account(): + _LOGGER.error("No Digital Ocean account found for the given API Token") + return False + + return True + + +class DigitalOcean(object): + """Handle all communication with the Digital Ocean API.""" + + def __init__(self, access_token): + """Initialize the Digital Ocean connection.""" + import digitalocean + + self._access_token = access_token + self.data = None + self.manager = digitalocean.Manager(token=self._access_token) + + def get_droplet_id(self, droplet_name): + """Get the status of a Digital Ocean droplet.""" + droplet_id = None + + all_droplets = self.manager.get_all_droplets() + for droplet in all_droplets: + if droplet_name == droplet.name: + droplet_id = droplet.id + + return droplet_id + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + def update(self): + """Use the data from Digital Ocean API.""" + self.data = self.manager.get_all_droplets() diff --git a/homeassistant/components/switch/digital_ocean.py b/homeassistant/components/switch/digital_ocean.py new file mode 100644 index 0000000000000..8df79bebc5dfe --- /dev/null +++ b/homeassistant/components/switch/digital_ocean.py @@ -0,0 +1,97 @@ +""" +Support for interacting with Digital Ocean droplets. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/switch.digital_ocean/ +""" +import logging + +import voluptuous as vol + +from homeassistant.components.switch import (SwitchDevice, PLATFORM_SCHEMA) +from homeassistant.components.digital_ocean import ( + CONF_DROPLETS, ATTR_CREATED_AT, ATTR_DROPLET_ID, ATTR_DROPLET_NAME, + ATTR_FEATURES, ATTR_IPV4_ADDRESS, ATTR_IPV6_ADDRESS, ATTR_MEMORY, + ATTR_REGION, ATTR_VCPUS) +from homeassistant.loader import get_component +import homeassistant.helpers.config_validation as cv + +_LOGGER = logging.getLogger(__name__) + +DEPENDENCIES = ['digital_ocean'] + +DEFAULT_NAME = 'Droplet' + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_DROPLETS): vol.All(cv.ensure_list, [cv.string]), +}) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Setup the Digital Ocean droplet switch.""" + digital_ocean = get_component('digital_ocean') + droplets = config.get(CONF_DROPLETS) + + dev = [] + for droplet in droplets: + droplet_id = digital_ocean.DIGITAL_OCEAN.get_droplet_id(droplet) + dev.append(DigitalOceanSwitch( + digital_ocean.DIGITAL_OCEAN, droplet_id)) + + add_devices(dev) + + +class DigitalOceanSwitch(SwitchDevice): + """Representation of a Digital Ocean droplet switch.""" + + def __init__(self, do, droplet_id): + """Initialize a new Digital Ocean sensor.""" + self._digital_ocean = do + self._droplet_id = droplet_id + self.data = None + self._state = None + + self.update() + + @property + def name(self): + """Return the name of the switch.""" + return self.data.name + + @property + def is_on(self): + """Return true if switch is on.""" + return self.data.status == 'active' + + @property + def state_attributes(self): + """Return the state attributes of the Digital Ocean droplet.""" + return { + ATTR_CREATED_AT: self.data.created_at, + ATTR_DROPLET_ID: self.data.id, + ATTR_DROPLET_NAME: self.data.name, + ATTR_FEATURES: self.data.features, + ATTR_IPV4_ADDRESS: self.data.ip_address, + ATTR_IPV6_ADDRESS: self.data.ip_v6_address, + ATTR_MEMORY: self.data.memory, + ATTR_REGION: self.data.region['name'], + ATTR_VCPUS: self.data.vcpus, + } + + def turn_on(self, **kwargs): + """Boot-up the droplet.""" + if self.data.status != 'active': + self.data.power_on() + + def turn_off(self, **kwargs): + """Shutdown the droplet.""" + if self.data.status == 'active': + self.data.power_off() + + def update(self): + """Get the latest data from the device and update the data.""" + self._digital_ocean.update() + + for droplet in self._digital_ocean.data: + if droplet.id == self._droplet_id: + self.data = droplet diff --git a/requirements_all.txt b/requirements_all.txt index 640931ceb89ce..21e387ab0085c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -362,6 +362,9 @@ pyserial==3.1.1 # homeassistant.components.sensor.snmp pysnmp==4.3.2 +# homeassistant.components.digital_ocean +python-digitalocean==1.9.0 + # homeassistant.components.sensor.forecast python-forecastio==1.3.4 From b650b2b0db16bdba57583d4ffcc6c936e835cd1b Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 30 Sep 2016 12:57:24 -0700 Subject: [PATCH 021/112] Spread async love (#3575) * Convert Entity.update_ha_state to be async * Make Service.call async * Update entity.py * Add Entity.async_update * Make automation zone trigger async * Fix linting * Reduce flakiness in hass.block_till_done * Make automation.numeric_state async * Make mqtt.subscribe async * Make automation.mqtt async * Make automation.time async * Make automation.sun async * Add async_track_point_in_utc_time * Make helpers.track_sunrise/set async * Add async_track_state_change * Make automation.state async * Clean up helpers/entity.py tests * Lint * Lint * Core.is_state and Core.is_state_attr are async friendly * Lint * Lint --- homeassistant/components/automation/mqtt.py | 4 +- .../components/automation/numeric_state.py | 9 +- homeassistant/components/automation/state.py | 46 ++++---- homeassistant/components/automation/sun.py | 4 +- homeassistant/components/automation/time.py | 4 +- homeassistant/components/automation/zone.py | 4 +- homeassistant/components/logbook.py | 16 ++- homeassistant/components/mqtt/__init__.py | 17 ++- homeassistant/core.py | 101 +++++++++--------- homeassistant/helpers/condition.py | 16 ++- homeassistant/helpers/entity.py | 29 ++++- homeassistant/helpers/event.py | 81 +++++++++----- homeassistant/helpers/template.py | 4 +- tests/components/test_init.py | 3 +- tests/components/test_logbook.py | 13 ++- tests/helpers/test_entity.py | 96 +++++++++++------ tests/test_core.py | 25 ++++- 17 files changed, 322 insertions(+), 150 deletions(-) diff --git a/homeassistant/components/automation/mqtt.py b/homeassistant/components/automation/mqtt.py index 6824c32bf07ce..f774991c54761 100644 --- a/homeassistant/components/automation/mqtt.py +++ b/homeassistant/components/automation/mqtt.py @@ -4,6 +4,7 @@ For more details about this automation rule, please refer to the documentation at https://home-assistant.io/components/automation/#mqtt-trigger """ +import asyncio import voluptuous as vol import homeassistant.components.mqtt as mqtt @@ -26,10 +27,11 @@ def trigger(hass, config, action): topic = config.get(CONF_TOPIC) payload = config.get(CONF_PAYLOAD) + @asyncio.coroutine def mqtt_automation_listener(msg_topic, msg_payload, qos): """Listen for MQTT messages.""" if payload is None or payload == msg_payload: - action({ + hass.async_add_job(action, { 'trigger': { 'platform': 'mqtt', 'topic': msg_topic, diff --git a/homeassistant/components/automation/numeric_state.py b/homeassistant/components/automation/numeric_state.py index 168ca05b62bc9..780ab4400b0c2 100644 --- a/homeassistant/components/automation/numeric_state.py +++ b/homeassistant/components/automation/numeric_state.py @@ -4,6 +4,7 @@ For more details about this automation rule, please refer to the documentation at https://home-assistant.io/components/automation/#numeric-state-trigger """ +import asyncio import logging import voluptuous as vol @@ -34,7 +35,7 @@ def trigger(hass, config, action): if value_template is not None: value_template.hass = hass - # pylint: disable=unused-argument + @asyncio.coroutine def state_automation_listener(entity, from_s, to_s): """Listen for state changes and calls action.""" if to_s is None: @@ -50,19 +51,19 @@ def state_automation_listener(entity, from_s, to_s): } # If new one doesn't match, nothing to do - if not condition.numeric_state( + if not condition.async_numeric_state( hass, to_s, below, above, value_template, variables): return # Only match if old didn't exist or existed but didn't match # Written as: skip if old one did exist and matched - if from_s is not None and condition.numeric_state( + if from_s is not None and condition.async_numeric_state( hass, from_s, below, above, value_template, variables): return variables['trigger']['from_state'] = from_s variables['trigger']['to_state'] = to_s - action(variables) + hass.async_add_job(action, variables) return track_state_change(hass, entity_id, state_automation_listener) diff --git a/homeassistant/components/automation/state.py b/homeassistant/components/automation/state.py index 8e0eb5231a540..dbe7447907082 100644 --- a/homeassistant/components/automation/state.py +++ b/homeassistant/components/automation/state.py @@ -4,12 +4,15 @@ For more details about this automation rule, please refer to the documentation at https://home-assistant.io/components/automation/#state-trigger """ +import asyncio import voluptuous as vol import homeassistant.util.dt as dt_util from homeassistant.const import MATCH_ALL, CONF_PLATFORM -from homeassistant.helpers.event import track_state_change, track_point_in_time +from homeassistant.helpers.event import ( + async_track_state_change, async_track_point_in_utc_time) import homeassistant.helpers.config_validation as cv +from homeassistant.util.async import run_callback_threadsafe CONF_ENTITY_ID = "entity_id" CONF_FROM = "from" @@ -38,16 +41,17 @@ def trigger(hass, config, action): from_state = config.get(CONF_FROM, MATCH_ALL) to_state = config.get(CONF_TO) or config.get(CONF_STATE) or MATCH_ALL time_delta = config.get(CONF_FOR) - remove_state_for_cancel = None - remove_state_for_listener = None + async_remove_state_for_cancel = None + async_remove_state_for_listener = None + @asyncio.coroutine def state_automation_listener(entity, from_s, to_s): """Listen for state changes and calls action.""" - nonlocal remove_state_for_cancel, remove_state_for_listener + nonlocal async_remove_state_for_cancel, async_remove_state_for_listener def call_action(): """Call action with right context.""" - action({ + hass.async_add_job(action, { 'trigger': { 'platform': 'state', 'entity_id': entity, @@ -61,35 +65,41 @@ def call_action(): call_action() return + @asyncio.coroutine def state_for_listener(now): """Fire on state changes after a delay and calls action.""" - remove_state_for_cancel() + async_remove_state_for_cancel() call_action() + @asyncio.coroutine def state_for_cancel_listener(entity, inner_from_s, inner_to_s): """Fire on changes and cancel for listener if changed.""" if inner_to_s.state == to_s.state: return - remove_state_for_listener() - remove_state_for_cancel() + async_remove_state_for_listener() + async_remove_state_for_cancel() - remove_state_for_listener = track_point_in_time( + async_remove_state_for_listener = async_track_point_in_utc_time( hass, state_for_listener, dt_util.utcnow() + time_delta) - remove_state_for_cancel = track_state_change( + async_remove_state_for_cancel = async_track_state_change( hass, entity, state_for_cancel_listener) - unsub = track_state_change(hass, entity_id, state_automation_listener, - from_state, to_state) + unsub = async_track_state_change( + hass, entity_id, state_automation_listener, from_state, to_state) - def remove(): - """Remove state listeners.""" + def async_remove(): + """Remove state listeners async.""" unsub() # pylint: disable=not-callable - if remove_state_for_cancel is not None: - remove_state_for_cancel() + if async_remove_state_for_cancel is not None: + async_remove_state_for_cancel() + + if async_remove_state_for_listener is not None: + async_remove_state_for_listener() - if remove_state_for_listener is not None: - remove_state_for_listener() + def remove(): + """Remove state listeners.""" + run_callback_threadsafe(hass.loop, async_remove).result() return remove diff --git a/homeassistant/components/automation/sun.py b/homeassistant/components/automation/sun.py index 991f9b3b385e9..faa628f572ac5 100644 --- a/homeassistant/components/automation/sun.py +++ b/homeassistant/components/automation/sun.py @@ -4,6 +4,7 @@ For more details about this automation rule, please refer to the documentation at https://home-assistant.io/components/automation/#sun-trigger """ +import asyncio from datetime import timedelta import logging @@ -30,9 +31,10 @@ def trigger(hass, config, action): event = config.get(CONF_EVENT) offset = config.get(CONF_OFFSET) + @asyncio.coroutine def call_action(): """Call action with right context.""" - action({ + hass.async_add_job(action, { 'trigger': { 'platform': 'sun', 'event': event, diff --git a/homeassistant/components/automation/time.py b/homeassistant/components/automation/time.py index 0732e2b212ca3..91f196eaf3f51 100644 --- a/homeassistant/components/automation/time.py +++ b/homeassistant/components/automation/time.py @@ -4,6 +4,7 @@ For more details about this automation rule, please refer to the documentation at https://home-assistant.io/components/automation/#time-trigger """ +import asyncio import logging import voluptuous as vol @@ -38,9 +39,10 @@ def trigger(hass, config, action): minutes = config.get(CONF_MINUTES) seconds = config.get(CONF_SECONDS) + @asyncio.coroutine def time_automation_listener(now): """Listen for time changes and calls action.""" - action({ + hass.async_add_job(action, { 'trigger': { 'platform': 'time', 'now': now, diff --git a/homeassistant/components/automation/zone.py b/homeassistant/components/automation/zone.py index ec948684805cb..971257350e3b1 100644 --- a/homeassistant/components/automation/zone.py +++ b/homeassistant/components/automation/zone.py @@ -4,6 +4,7 @@ For more details about this automation rule, please refer to the documentation at https://home-assistant.io/components/automation/#zone-trigger """ +import asyncio import voluptuous as vol from homeassistant.const import ( @@ -31,6 +32,7 @@ def trigger(hass, config, action): zone_entity_id = config.get(CONF_ZONE) event = config.get(CONF_EVENT) + @asyncio.coroutine def zone_automation_listener(entity, from_s, to_s): """Listen for state changes and calls action.""" if from_s and not location.has_location(from_s) or \ @@ -47,7 +49,7 @@ def zone_automation_listener(entity, from_s, to_s): # pylint: disable=too-many-boolean-expressions if event == EVENT_ENTER and not from_match and to_match or \ event == EVENT_LEAVE and from_match and not to_match: - action({ + hass.async_add_job(action, { 'trigger': { 'platform': 'zone', 'entity_id': entity, diff --git a/homeassistant/components/logbook.py b/homeassistant/components/logbook.py index e65232b28a93c..9100c09841386 100644 --- a/homeassistant/components/logbook.py +++ b/homeassistant/components/logbook.py @@ -4,6 +4,7 @@ For more details about this component, please refer to the documentation at https://home-assistant.io/components/logbook/ """ +import asyncio import logging from datetime import timedelta from itertools import groupby @@ -20,6 +21,7 @@ STATE_NOT_HOME, STATE_OFF, STATE_ON, ATTR_HIDDEN) from homeassistant.core import State, split_entity_id, DOMAIN as HA_DOMAIN +from homeassistant.util.async import run_callback_threadsafe DOMAIN = "logbook" DEPENDENCIES = ['recorder', 'frontend'] @@ -57,6 +59,13 @@ def log_entry(hass, name, message, domain=None, entity_id=None): + """Add an entry to the logbook.""" + run_callback_threadsafe( + hass.loop, async_log_entry, hass, name, message, domain, entity_id + ).result() + + +def async_log_entry(hass, name, message, domain=None, entity_id=None): """Add an entry to the logbook.""" data = { ATTR_NAME: name, @@ -67,11 +76,12 @@ def log_entry(hass, name, message, domain=None, entity_id=None): data[ATTR_DOMAIN] = domain if entity_id is not None: data[ATTR_ENTITY_ID] = entity_id - hass.bus.fire(EVENT_LOGBOOK_ENTRY, data) + hass.bus.async_fire(EVENT_LOGBOOK_ENTRY, data) def setup(hass, config): """Listen for download events to download files.""" + @asyncio.coroutine def log_message(service): """Handle sending notification message service calls.""" message = service.data[ATTR_MESSAGE] @@ -80,8 +90,8 @@ def log_message(service): entity_id = service.data.get(ATTR_ENTITY_ID) message.hass = hass - message = message.render() - log_entry(hass, name, message, domain, entity_id) + message = message.async_render() + async_log_entry(hass, name, message, domain, entity_id) hass.wsgi.register_view(LogbookView(hass, config)) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index abf52da4359b0..01956a85c36f2 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -4,6 +4,7 @@ For more details about this component, please refer to the documentation at https://home-assistant.io/components/mqtt/ """ +import asyncio import logging import os import socket @@ -11,6 +12,7 @@ import voluptuous as vol +from homeassistant.core import JobPriority from homeassistant.bootstrap import prepare_setup_platform from homeassistant.config import load_yaml_config_file from homeassistant.exceptions import HomeAssistantError @@ -164,11 +166,20 @@ def publish_template(hass, topic, payload_template, qos=None, retain=None): def subscribe(hass, topic, callback, qos=DEFAULT_QOS): """Subscribe to an MQTT topic.""" + @asyncio.coroutine def mqtt_topic_subscriber(event): """Match subscribed MQTT topic.""" - if _match_topic(topic, event.data[ATTR_TOPIC]): - callback(event.data[ATTR_TOPIC], event.data[ATTR_PAYLOAD], - event.data[ATTR_QOS]) + if not _match_topic(topic, event.data[ATTR_TOPIC]): + return + + if asyncio.iscoroutinefunction(callback): + yield from callback( + event.data[ATTR_TOPIC], event.data[ATTR_PAYLOAD], + event.data[ATTR_QOS]) + else: + hass.add_job(callback, event.data[ATTR_TOPIC], + event.data[ATTR_PAYLOAD], event.data[ATTR_QOS], + priority=JobPriority.EVENT_CALLBACK) remove = hass.bus.listen(EVENT_MQTT_MESSAGE_RECEIVED, mqtt_topic_subscriber) diff --git a/homeassistant/core.py b/homeassistant/core.py index bcea24246ca52..2a6372dbf6f1d 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -248,12 +248,16 @@ def sleep_wait(): def notify_when_done(): """Notify event loop when pool done.""" + count = 0 while True: # Wait for the work queue to empty self.pool.block_till_done() # Verify the loop is empty if self._loop_empty(): + count += 1 + + if count == 2: break # sleep in the loop executor, this forces execution back into @@ -675,40 +679,29 @@ def async_all(self): return list(self._states.values()) def get(self, entity_id): - """Retrieve state of entity_id or None if not found.""" + """Retrieve state of entity_id or None if not found. + + Async friendly. + """ return self._states.get(entity_id.lower()) def is_state(self, entity_id, state): - """Test if entity exists and is specified state.""" - return run_callback_threadsafe( - self._loop, self.async_is_state, entity_id, state - ).result() - - def async_is_state(self, entity_id, state): """Test if entity exists and is specified state. - This method must be run in the event loop. + Async friendly. """ - entity_id = entity_id.lower() + state_obj = self.get(entity_id) - return (entity_id in self._states and - self._states[entity_id].state == state) + return state_obj and state_obj.state == state def is_state_attr(self, entity_id, name, value): - """Test if entity exists and has a state attribute set to value.""" - return run_callback_threadsafe( - self._loop, self.async_is_state_attr, entity_id, name, value - ).result() - - def async_is_state_attr(self, entity_id, name, value): """Test if entity exists and has a state attribute set to value. - This method must be run in the event loop. + Async friendly. """ - entity_id = entity_id.lower() + state_obj = self.get(entity_id) - return (entity_id in self._states and - self._states[entity_id].attributes.get(name, None) == value) + return state_obj and state_obj.attributes.get(name, None) == value def remove(self, entity_id): """Remove the state of an entity. @@ -799,7 +792,8 @@ def async_set(self, entity_id, new_state, attributes=None, class Service(object): """Represents a callable service.""" - __slots__ = ['func', 'description', 'fields', 'schema'] + __slots__ = ['func', 'description', 'fields', 'schema', + 'iscoroutinefunction'] def __init__(self, func, description, fields, schema): """Initialize a service.""" @@ -807,6 +801,7 @@ def __init__(self, func, description, fields, schema): self.description = description or '' self.fields = fields or {} self.schema = schema + self.iscoroutinefunction = asyncio.iscoroutinefunction(func) def as_dict(self): """Return dictionary representation of this service.""" @@ -815,19 +810,6 @@ def as_dict(self): 'fields': self.fields, } - def __call__(self, call): - """Execute the service.""" - try: - if self.schema: - call.data = self.schema(call.data) - call.data = MappingProxyType(call.data) - - self.func(call) - except vol.MultipleInvalid as ex: - _LOGGER.error('Invalid service data for %s.%s: %s', - call.domain, call.service, - humanize_error(call.data, ex)) - # pylint: disable=too-few-public-methods class ServiceCall(object): @@ -839,7 +821,7 @@ def __init__(self, domain, service, data=None, call_id=None): """Initialize a service call.""" self.domain = domain.lower() self.service = service.lower() - self.data = data or {} + self.data = MappingProxyType(data or {}) self.call_id = call_id def __repr__(self): @@ -983,9 +965,9 @@ def async_call(self, domain, service, service_data=None, blocking=False): fut = asyncio.Future(loop=self._loop) @asyncio.coroutine - def service_executed(call): + def service_executed(event): """Callback method that is called when service is executed.""" - if call.data[ATTR_SERVICE_CALL_ID] == call_id: + if event.data[ATTR_SERVICE_CALL_ID] == call_id: fut.set_result(True) unsub = self._bus.async_listen(EVENT_SERVICE_EXECUTED, @@ -1000,9 +982,10 @@ def service_executed(call): unsub() return success + @asyncio.coroutine def _event_to_service_call(self, event): """Callback for SERVICE_CALLED events from the event bus.""" - service_data = event.data.get(ATTR_SERVICE_DATA) + service_data = event.data.get(ATTR_SERVICE_DATA) or {} domain = event.data.get(ATTR_DOMAIN).lower() service = event.data.get(ATTR_SERVICE).lower() call_id = event.data.get(ATTR_SERVICE_CALL_ID) @@ -1014,19 +997,41 @@ def _event_to_service_call(self, event): return service_handler = self._services[domain][service] + + def fire_service_executed(): + """Fire service executed event.""" + if not call_id: + return + + data = {ATTR_SERVICE_CALL_ID: call_id} + + if service_handler.iscoroutinefunction: + self._bus.async_fire(EVENT_SERVICE_EXECUTED, data) + else: + self._bus.fire(EVENT_SERVICE_EXECUTED, data) + + try: + if service_handler.schema: + service_data = service_handler.schema(service_data) + except vol.Invalid as ex: + _LOGGER.error('Invalid service data for %s.%s: %s', + domain, service, humanize_error(service_data, ex)) + fire_service_executed() + return + service_call = ServiceCall(domain, service, service_data, call_id) - # Add a job to the pool that calls _execute_service - self._add_job(self._execute_service, service_handler, service_call, - priority=JobPriority.EVENT_SERVICE) + if not service_handler.iscoroutinefunction: + def execute_service(): + """Execute a service and fires a SERVICE_EXECUTED event.""" + service_handler.func(service_call) + fire_service_executed() - def _execute_service(self, service, call): - """Execute a service and fires a SERVICE_EXECUTED event.""" - service(call) + self._add_job(execute_service, priority=JobPriority.EVENT_SERVICE) + return - if call.call_id is not None: - self._bus.fire( - EVENT_SERVICE_EXECUTED, {ATTR_SERVICE_CALL_ID: call.call_id}) + yield from service_handler.func(service_call) + fire_service_executed() def _generate_unique_id(self): """Generate a unique service call id.""" diff --git a/homeassistant/helpers/condition.py b/homeassistant/helpers/condition.py index f4ce02c0846d9..041f514aedae7 100644 --- a/homeassistant/helpers/condition.py +++ b/homeassistant/helpers/condition.py @@ -84,6 +84,15 @@ def if_or_condition(hass: HomeAssistant, def numeric_state(hass: HomeAssistant, entity, below=None, above=None, value_template=None, variables=None): """Test a numeric state condition.""" + return run_callback_threadsafe( + hass.loop, async_numeric_state, hass, entity, below, above, + value_template, variables, + ).result() + + +def async_numeric_state(hass: HomeAssistant, entity, below=None, above=None, + value_template=None, variables=None): + """Test a numeric state condition.""" if isinstance(entity, str): entity = hass.states.get(entity) @@ -96,7 +105,7 @@ def numeric_state(hass: HomeAssistant, entity, below=None, above=None, variables = dict(variables or {}) variables['state'] = entity try: - value = value_template.render(variables) + value = value_template.async_render(variables) except TemplateError as ex: _LOGGER.error("Template error: %s", ex) return False @@ -290,7 +299,10 @@ def time_if(hass, variables=None): def zone(hass, zone_ent, entity): - """Test if zone-condition matches.""" + """Test if zone-condition matches. + + Can be run async. + """ if isinstance(zone_ent, str): zone_ent = hass.states.get(zone_ent) diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index 0b4768b809d55..7529d6288ab7d 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -1,4 +1,5 @@ """An abstract class for entities.""" +import asyncio import logging from typing import Any, Optional, List, Dict @@ -11,6 +12,7 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import NoEntitySpecifiedError from homeassistant.util import ensure_unique_string, slugify +from homeassistant.util.async import run_coroutine_threadsafe # Entity attributes that we will overwrite _OVERWRITE = {} # type: Dict[str, Any] @@ -143,6 +145,23 @@ def update_ha_state(self, force_refresh=False): If force_refresh == True will update entity before setting state. """ + # We're already in a thread, do the force refresh here. + if force_refresh and not hasattr(self, 'async_update'): + self.update() + force_refresh = False + + run_coroutine_threadsafe( + self.async_update_ha_state(force_refresh), self.hass.loop + ).result() + + @asyncio.coroutine + def async_update_ha_state(self, force_refresh=False): + """Update Home Assistant with current state of entity. + + If force_refresh == True will update entity before setting state. + + This method must be run in the event loop. + """ if self.hass is None: raise RuntimeError("Attribute hass is None for {}".format(self)) @@ -151,7 +170,13 @@ def update_ha_state(self, force_refresh=False): "No entity id specified for entity {}".format(self.name)) if force_refresh: - self.update() + if hasattr(self, 'async_update'): + # pylint: disable=no-member + self.async_update() + else: + # PS: Run this in our own thread pool once we have + # future support? + yield from self.hass.loop.run_in_executor(None, self.update) state = STATE_UNKNOWN if self.state is None else str(self.state) attr = self.state_attributes or {} @@ -192,7 +217,7 @@ def update_ha_state(self, force_refresh=False): # Could not convert state to float pass - return self.hass.states.set( + self.hass.states.async_set( self.entity_id, state, attr, self.force_update) def remove(self) -> None: diff --git a/homeassistant/helpers/event.py b/homeassistant/helpers/event.py index 7331525c05279..e27f711afda50 100644 --- a/homeassistant/helpers/event.py +++ b/homeassistant/helpers/event.py @@ -18,6 +18,28 @@ def track_state_change(hass, entity_ids, action, from_state=None, Returns a function that can be called to remove the listener. """ + async_unsub = run_callback_threadsafe( + hass.loop, async_track_state_change, hass, entity_ids, action, + from_state, to_state).result() + + def remove(): + """Remove listener.""" + run_callback_threadsafe(hass.loop, async_unsub).result() + + return remove + + +def async_track_state_change(hass, entity_ids, action, from_state=None, + to_state=None): + """Track specific state changes. + + entity_ids, from_state and to_state can be string or list. + Use list to match multiple. + + Returns a function that can be called to remove the listener. + + Must be run within the event loop. + """ from_state = _process_state_match(from_state) to_state = _process_state_match(to_state) @@ -52,7 +74,7 @@ def state_change_listener(event): event.data.get('old_state'), event.data.get('new_state')) - return hass.bus.listen(EVENT_STATE_CHANGED, state_change_listener) + return hass.bus.async_listen(EVENT_STATE_CHANGED, state_change_listener) def track_point_in_time(hass, action, point_in_time): @@ -69,6 +91,19 @@ def utc_converter(utc_now): def track_point_in_utc_time(hass, action, point_in_time): + """Add a listener that fires once after a specific point in UTC time.""" + async_unsub = run_callback_threadsafe( + hass.loop, async_track_point_in_utc_time, hass, action, point_in_time + ).result() + + def remove(): + """Remove listener.""" + run_callback_threadsafe(hass.loop, async_unsub).result() + + return remove + + +def async_track_point_in_utc_time(hass, action, point_in_time): """Add a listener that fires once after a specific point in UTC time.""" # Ensure point_in_time is UTC point_in_time = dt_util.as_utc(point_in_time) @@ -88,20 +123,14 @@ def point_in_time_listener(event): # listener gets lined up twice to be executed. This will make # sure the second time it does nothing. point_in_time_listener.run = True - async_remove() + async_unsub() hass.async_add_job(action, now) - future = run_callback_threadsafe( - hass.loop, hass.bus.async_listen, EVENT_TIME_CHANGED, - point_in_time_listener) - async_remove = future.result() + async_unsub = hass.bus.async_listen(EVENT_TIME_CHANGED, + point_in_time_listener) - def remove(): - """Remove listener.""" - run_callback_threadsafe(hass.loop, async_remove).result() - - return remove + return async_unsub def track_sunrise(hass, action, offset=None): @@ -118,19 +147,21 @@ def next_rise(): return next_time + @asyncio.coroutine def sunrise_automation_listener(now): """Called when it's time for action.""" nonlocal remove - remove = track_point_in_utc_time(hass, sunrise_automation_listener, - next_rise()) - action() + remove = async_track_point_in_utc_time( + hass, sunrise_automation_listener, next_rise()) + hass.async_add_job(action) - remove = track_point_in_utc_time(hass, sunrise_automation_listener, - next_rise()) + remove = run_callback_threadsafe( + hass.loop, async_track_point_in_utc_time, hass, + sunrise_automation_listener, next_rise()).result() def remove_listener(): - """Remove sunrise listener.""" - remove() + """Remove sunset listener.""" + run_callback_threadsafe(hass.loop, remove).result() return remove_listener @@ -149,19 +180,21 @@ def next_set(): return next_time + @asyncio.coroutine def sunset_automation_listener(now): """Called when it's time for action.""" nonlocal remove - remove = track_point_in_utc_time(hass, sunset_automation_listener, - next_set()) - action() + remove = async_track_point_in_utc_time( + hass, sunset_automation_listener, next_set()) + hass.async_add_job(action) - remove = track_point_in_utc_time(hass, sunset_automation_listener, - next_set()) + remove = run_callback_threadsafe( + hass.loop, async_track_point_in_utc_time, hass, + sunset_automation_listener, next_set()).result() def remove_listener(): """Remove sunset listener.""" - remove() + run_callback_threadsafe(hass.loop, remove).result() return remove_listener diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index d8005858a1ec9..6193d7f9ab883 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -149,8 +149,8 @@ def _ensure_compiled(self): global_vars = ENV.make_globals({ 'closest': location_methods.closest, 'distance': location_methods.distance, - 'is_state': self.hass.states.async_is_state, - 'is_state_attr': self.hass.states.async_is_state_attr, + 'is_state': self.hass.states.is_state, + 'is_state_attr': self.hass.states.is_state_attr, 'states': AllStates(self.hass), }) diff --git a/tests/components/test_init.py b/tests/components/test_init.py index 62467c14a2f76..76878432ecd70 100644 --- a/tests/components/test_init.py +++ b/tests/components/test_init.py @@ -77,7 +77,8 @@ def test_turn_on_to_not_block_for_domains_without_service(self, mock_call): service_call = ha.ServiceCall('homeassistant', 'turn_on', { 'entity_id': ['light.test', 'sensor.bla', 'light.bla'] }) - self.hass.services._services['homeassistant']['turn_on'](service_call) + service = self.hass.services._services['homeassistant']['turn_on'] + service.func(service_call) self.assertEqual(2, mock_call.call_count) self.assertEqual( diff --git a/tests/components/test_logbook.py b/tests/components/test_logbook.py index a2cbd7094ca86..539622d9296d9 100644 --- a/tests/components/test_logbook.py +++ b/tests/components/test_logbook.py @@ -1,7 +1,8 @@ """The tests for the logbook component.""" # pylint: disable=protected-access,too-many-public-methods -import unittest from datetime import timedelta +import unittest +from unittest.mock import patch from homeassistant.components import sun import homeassistant.core as ha @@ -18,13 +19,17 @@ class TestComponentLogbook(unittest.TestCase): """Test the History component.""" - EMPTY_CONFIG = logbook.CONFIG_SCHEMA({ha.DOMAIN: {}, logbook.DOMAIN: {}}) + EMPTY_CONFIG = logbook.CONFIG_SCHEMA({logbook.DOMAIN: {}}) def setUp(self): """Setup things to be run when tests are started.""" self.hass = get_test_home_assistant() mock_http_component(self.hass) - assert setup_component(self.hass, logbook.DOMAIN, self.EMPTY_CONFIG) + self.hass.config.components += ['frontend', 'recorder', 'api'] + with patch('homeassistant.components.logbook.' + 'register_built_in_panel'): + assert setup_component(self.hass, logbook.DOMAIN, + self.EMPTY_CONFIG) def tearDown(self): """Stop everything that was started.""" @@ -44,7 +49,6 @@ def event_listener(event): logbook.ATTR_DOMAIN: 'switch', logbook.ATTR_ENTITY_ID: 'switch.test_switch' }, True) - self.hass.block_till_done() self.assertEqual(1, len(calls)) last_call = calls[-1] @@ -65,7 +69,6 @@ def event_listener(event): self.hass.bus.listen(logbook.EVENT_LOGBOOK_ENTRY, event_listener) self.hass.services.call(logbook.DOMAIN, 'log', {}, True) - self.hass.block_till_done() self.assertEqual(0, len(calls)) diff --git a/tests/helpers/test_entity.py b/tests/helpers/test_entity.py index 593e8b433c0a2..81ef17ff0fdf0 100644 --- a/tests/helpers/test_entity.py +++ b/tests/helpers/test_entity.py @@ -1,6 +1,9 @@ """Test the entity helper.""" # pylint: disable=protected-access,too-many-public-methods -import unittest +import asyncio +from unittest.mock import MagicMock + +import pytest import homeassistant.helpers.entity as entity from homeassistant.const import ATTR_HIDDEN @@ -8,26 +11,75 @@ from tests.common import get_test_home_assistant -class TestHelpersEntity(unittest.TestCase): +def test_generate_entity_id_requires_hass_or_ids(): + """Ensure we require at least hass or current ids.""" + fmt = 'test.{}' + with pytest.raises(ValueError): + entity.generate_entity_id(fmt, 'hello world') + + +def test_generate_entity_id_given_keys(): + """Test generating an entity id given current ids.""" + fmt = 'test.{}' + assert entity.generate_entity_id( + fmt, 'overwrite hidden true', current_ids=[ + 'test.overwrite_hidden_true']) == 'test.overwrite_hidden_true_2' + assert entity.generate_entity_id( + fmt, 'overwrite hidden true', current_ids=[ + 'test.another_entity']) == 'test.overwrite_hidden_true' + + +def test_async_update_support(event_loop): + """Test async update getting called.""" + sync_update = [] + async_update = [] + + class AsyncEntity(entity.Entity): + hass = MagicMock() + entity_id = 'sensor.test' + + def update(self): + sync_update.append([1]) + + ent = AsyncEntity() + ent.hass.loop = event_loop + + @asyncio.coroutine + def test(): + yield from ent.async_update_ha_state(True) + + event_loop.run_until_complete(test()) + + assert len(sync_update) == 1 + assert len(async_update) == 0 + + ent.async_update = lambda: async_update.append(1) + + event_loop.run_until_complete(test()) + + assert len(sync_update) == 1 + assert len(async_update) == 1 + + +class TestHelpersEntity(object): """Test homeassistant.helpers.entity module.""" - def setUp(self): # pylint: disable=invalid-name + def setup_method(self, method): """Setup things to be run when tests are started.""" self.entity = entity.Entity() self.entity.entity_id = 'test.overwrite_hidden_true' self.hass = self.entity.hass = get_test_home_assistant() self.entity.update_ha_state() - def tearDown(self): # pylint: disable=invalid-name + def teardown_method(self, method): """Stop everything that was started.""" - self.hass.stop() entity.set_customize({}) + self.hass.stop() def test_default_hidden_not_in_attributes(self): """Test that the default hidden property is set to False.""" - self.assertNotIn( - ATTR_HIDDEN, - self.hass.states.get(self.entity.entity_id).attributes) + assert ATTR_HIDDEN not in self.hass.states.get( + self.entity.entity_id).attributes def test_overwriting_hidden_property_to_true(self): """Test we can overwrite hidden property to True.""" @@ -35,31 +87,11 @@ def test_overwriting_hidden_property_to_true(self): self.entity.update_ha_state() state = self.hass.states.get(self.entity.entity_id) - self.assertTrue(state.attributes.get(ATTR_HIDDEN)) - - def test_generate_entity_id_requires_hass_or_ids(self): - """Ensure we require at least hass or current ids.""" - fmt = 'test.{}' - with self.assertRaises(ValueError): - entity.generate_entity_id(fmt, 'hello world') + assert state.attributes.get(ATTR_HIDDEN) def test_generate_entity_id_given_hass(self): """Test generating an entity id given hass object.""" fmt = 'test.{}' - self.assertEqual( - 'test.overwrite_hidden_true_2', - entity.generate_entity_id(fmt, 'overwrite hidden true', - hass=self.hass)) - - def test_generate_entity_id_given_keys(self): - """Test generating an entity id given current ids.""" - fmt = 'test.{}' - self.assertEqual( - 'test.overwrite_hidden_true_2', - entity.generate_entity_id( - fmt, 'overwrite hidden true', - current_ids=['test.overwrite_hidden_true'])) - self.assertEqual( - 'test.overwrite_hidden_true', - entity.generate_entity_id(fmt, 'overwrite hidden true', - current_ids=['test.another_entity'])) + assert entity.generate_entity_id( + fmt, 'overwrite hidden true', + hass=self.hass) == 'test.overwrite_hidden_true_2' diff --git a/tests/test_core.py b/tests/test_core.py index 9b57f07e9e6ae..9fa742985c4ab 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1,6 +1,7 @@ """Test to verify that Home Assistant core works.""" # pylint: disable=protected-access,too-many-public-methods # pylint: disable=too-few-public-methods +import asyncio import os import signal import unittest @@ -362,7 +363,6 @@ def setUp(self): # pylint: disable=invalid-name self.hass = get_test_home_assistant() self.services = self.hass.services self.services.register("Test_Domain", "TEST_SERVICE", lambda x: None) - self.hass.block_till_done() def tearDown(self): # pylint: disable=invalid-name """Stop down stuff we started.""" @@ -387,8 +387,13 @@ def test_services(self): def test_call_with_blocking_done_in_time(self): """Test call with blocking.""" calls = [] + + def service_handler(call): + """Service handler.""" + calls.append(call) + self.services.register("test_domain", "register_calls", - lambda x: calls.append(1)) + service_handler) self.assertTrue( self.services.call('test_domain', 'REGISTER_CALLS', blocking=True)) @@ -404,6 +409,22 @@ def test_call_non_existing_with_blocking(self): finally: ha.SERVICE_CALL_LIMIT = prior + def test_async_service(self): + """Test registering and calling an async service.""" + calls = [] + + @asyncio.coroutine + def service_handler(call): + """Service handler coroutine.""" + calls.append(call) + + self.services.register('test_domain', 'register_calls', + service_handler) + self.assertTrue( + self.services.call('test_domain', 'REGISTER_CALLS', blocking=True)) + self.hass.block_till_done() + self.assertEqual(1, len(calls)) + class TestConfig(unittest.TestCase): """Test configuration methods.""" From d5f8aa52c416aca33961209cd4596cceb3a984fd Mon Sep 17 00:00:00 2001 From: Otto Winter Date: Sat, 1 Oct 2016 01:36:04 +0200 Subject: [PATCH 022/112] Add support for MySensors cover (#3512) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added support for MySensors cover device * Fixed set_req not defined * Fixed V_PERCENTAGE is str * Removed set_cover_position The MySensors documentation doesn’t specify when sending a V_PERCENTAGE is allowed. * Fixed homeassistant/components/mysensors.py line too long * Fixed lint ATTR_POSITION imported but unused * Use V_PERCENTAGE for MySensors cover * Revert "Removed set_cover_position" This reverts commit d78cb3a04d61f84385d1b46ae3396192c10073f6. * Fix set_req, ATTR_POSITION not defined * Added support for non-exactly positionable covers * Fixed V_PERCENTAGE cast to bool * Ported MySensors cover back to v1.4 `V_PERCENTAGE` and `V_DIMMER` are aliases just like `V_STATUS` and `V_LIGHT`, so the code inside `MySensorsCover` doesn’t need to be updated. * Fixed v1.5 V_TYPES not in in v1.4 gateway SetReq --- homeassistant/components/cover/mysensors.py | 103 ++++++++++++++++++++ homeassistant/components/mysensors.py | 5 +- 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 homeassistant/components/cover/mysensors.py diff --git a/homeassistant/components/cover/mysensors.py b/homeassistant/components/cover/mysensors.py new file mode 100644 index 0000000000000..aa3d866bcd6ba --- /dev/null +++ b/homeassistant/components/cover/mysensors.py @@ -0,0 +1,103 @@ +""" +Support for MySensors covers. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/cover.mysensors/ +""" +import logging + +from homeassistant.components import mysensors +from homeassistant.components.cover import CoverDevice, ATTR_POSITION +from homeassistant.const import STATE_ON, STATE_OFF + +_LOGGER = logging.getLogger(__name__) +DEPENDENCIES = [] + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Setup the mysensors platform for covers.""" + if discovery_info is None: + return + for gateway in mysensors.GATEWAYS.values(): + pres = gateway.const.Presentation + set_req = gateway.const.SetReq + map_sv_types = { + pres.S_COVER: [set_req.V_DIMMER, set_req.V_LIGHT], + } + if float(gateway.protocol_version) >= 1.5: + map_sv_types.update({ + pres.S_COVER: [set_req.V_PERCENTAGE, set_req.V_STATUS], + }) + devices = {} + gateway.platform_callbacks.append(mysensors.pf_callback_factory( + map_sv_types, devices, add_devices, MySensorsCover)) + + +class MySensorsCover(mysensors.MySensorsDeviceEntity, CoverDevice): + """Representation of the value of a MySensors Cover child node.""" + + @property + def assumed_state(self): + """Return True if unable to access real state of entity.""" + return self.gateway.optimistic + + @property + def is_closed(self): + """Return True if cover is closed.""" + set_req = self.gateway.const.SetReq + if set_req.V_DIMMER in self._values: + return self._values.get(set_req.V_DIMMER) == 0 + else: + return self._values.get(set_req.V_LIGHT) == STATE_OFF + + @property + def current_cover_position(self): + """Return current position of cover. + + None is unknown, 0 is closed, 100 is fully open. + """ + set_req = self.gateway.const.SetReq + return self._values.get(set_req.V_DIMMER) + + def open_cover(self, **kwargs): + """Move the cover up.""" + set_req = self.gateway.const.SetReq + self.gateway.set_child_value( + self.node_id, self.child_id, set_req.V_UP, 1) + if self.gateway.optimistic: + # Optimistically assume that cover has changed state. + if set_req.V_DIMMER in self._values: + self._values[set_req.V_DIMMER] = 100 + else: + self._values[set_req.V_LIGHT] = STATE_ON + self.update_ha_state() + + def close_cover(self, **kwargs): + """Move the cover down.""" + set_req = self.gateway.const.SetReq + self.gateway.set_child_value( + self.node_id, self.child_id, set_req.V_DOWN, 1) + if self.gateway.optimistic: + # Optimistically assume that cover has changed state. + if set_req.V_DIMMER in self._values: + self._values[set_req.V_DIMMER] = 0 + else: + self._values[set_req.V_LIGHT] = STATE_OFF + self.update_ha_state() + + def set_cover_position(self, **kwargs): + """Move the cover to a specific position.""" + position = kwargs.get(ATTR_POSITION) + set_req = self.gateway.const.SetReq + self.gateway.set_child_value( + self.node_id, self.child_id, set_req.V_DIMMER, position) + if self.gateway.optimistic: + # Optimistically assume that cover has changed state. + self._values[set_req.V_DIMMER] = position + self.update_ha_state() + + def stop_cover(self, **kwargs): + """Stop the device.""" + set_req = self.gateway.const.SetReq + self.gateway.set_child_value( + self.node_id, self.child_id, set_req.V_STOP, 1) diff --git a/homeassistant/components/mysensors.py b/homeassistant/components/mysensors.py index 84d1150a6d8a8..0c13347ebd1ec 100644 --- a/homeassistant/components/mysensors.py +++ b/homeassistant/components/mysensors.py @@ -158,7 +158,8 @@ def gw_start(event): 'No devices could be setup as gateways, check your configuration') return False - for component in 'sensor', 'switch', 'light', 'binary_sensor', 'climate': + for component in ['sensor', 'switch', 'light', 'binary_sensor', 'climate', + 'cover']: discovery.load_platform(hass, component, DOMAIN, {}, config) return True @@ -340,5 +341,7 @@ def update(self): set_req.V_LOCK_STATUS, set_req.V_TRIPPED): self._values[value_type] = ( STATE_ON if int(value) == 1 else STATE_OFF) + elif value_type == set_req.V_DIMMER: + self._values[value_type] = int(value) else: self._values[value_type] = value From 412b5350ce3c16c55c6625e772f560aba351364b Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 30 Sep 2016 23:26:15 -0700 Subject: [PATCH 023/112] Service config calls will no longer mutate original config (#3628) --- homeassistant/helpers/service.py | 26 +++++++++++--------------- homeassistant/helpers/template.py | 6 ++++++ tests/helpers/test_service.py | 29 +++++++++++++++++------------ 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/homeassistant/helpers/service.py b/homeassistant/helpers/service.py index 092d5983308cd..665e22404c645 100644 --- a/homeassistant/helpers/service.py +++ b/homeassistant/helpers/service.py @@ -62,22 +62,18 @@ def call_from_config(hass, config, blocking=False, variables=None, domain, service_name = domain_service.split('.', 1) service_data = dict(config.get(CONF_SERVICE_DATA, {})) - def _data_template_creator(value): - """Recursive template creator helper function.""" - if isinstance(value, list): - for idx, element in enumerate(value): - value[idx] = _data_template_creator(element) - return value - if isinstance(value, dict): - for key, element in value.items(): - value[key] = _data_template_creator(element) - return value - value.hass = hass - return value.render(variables) - if CONF_SERVICE_DATA_TEMPLATE in config: - for key, value in config[CONF_SERVICE_DATA_TEMPLATE].items(): - service_data[key] = _data_template_creator(value) + def _data_template_creator(value): + """Recursive template creator helper function.""" + if isinstance(value, list): + return [_data_template_creator(item) for item in value] + elif isinstance(value, dict): + return {key: _data_template_creator(item) + for key, item in value.items()} + value.hass = hass + return value.render(variables) + service_data.update(_data_template_creator( + config[CONF_SERVICE_DATA_TEMPLATE])) if CONF_SERVICE_ENTITY_ID in config: service_data[ATTR_ENTITY_ID] = config[CONF_SERVICE_ENTITY_ID] diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index 6193d7f9ab883..03029c369e655 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -159,6 +159,12 @@ def _ensure_compiled(self): return self._compiled + def __eq__(self, other): + """Compare template with another.""" + return (self.__class__ == other.__class__ and + self.template == other.template and + self.hass == other.hass) + class AllStates(object): """Class to expose all HA states as attributes.""" diff --git a/tests/helpers/test_service.py b/tests/helpers/test_service.py index d9fe3ff9c153f..38af217834099 100644 --- a/tests/helpers/test_service.py +++ b/tests/helpers/test_service.py @@ -1,4 +1,5 @@ """Test service helpers.""" +from copy import deepcopy import unittest from unittest.mock import patch @@ -6,7 +7,8 @@ import homeassistant.components # noqa from homeassistant import core as ha, loader from homeassistant.const import STATE_ON, STATE_OFF, ATTR_ENTITY_ID -from homeassistant.helpers import service +from homeassistant.helpers import service, template +import homeassistant.helpers.config_validation as cv from tests.common import get_test_home_assistant, mock_service @@ -97,22 +99,25 @@ def test_split_entity_string(self): def test_not_mutate_input(self): """Test for immutable input.""" - orig = { + config = cv.SERVICE_SCHEMA({ 'service': 'test_domain.test_service', 'entity_id': 'hello.world, sensor.beer', 'data': { 'hello': 1, }, - } - service.call_from_config(self.hass, orig) - self.hass.block_till_done() - self.assertEqual({ - 'service': 'test_domain.test_service', - 'entity_id': 'hello.world, sensor.beer', - 'data': { - 'hello': 1, - }, - }, orig) + 'data_template': { + 'nested': { + 'value': '{{ 1 + 1 }}' + } + } + }) + orig = deepcopy(config) + + # Only change after call is each template getting hass attached + template.attach(self.hass, orig) + + service.call_from_config(self.hass, config, validate_config=False) + assert orig == config @patch('homeassistant.helpers.service._LOGGER.error') def test_fail_silently_if_no_service(self, mock_log): From 15ed8c633212a7dfd0b5b05f90cdc3a451541fab Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sat, 1 Oct 2016 17:35:32 +0200 Subject: [PATCH 024/112] Add units (fixes #3619) (#3633) --- homeassistant/components/sensor/glances.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/sensor/glances.py b/homeassistant/components/sensor/glances.py index 51a8ac4d46fa9..22071fb518f86 100644 --- a/homeassistant/components/sensor/glances.py +++ b/homeassistant/components/sensor/glances.py @@ -1,5 +1,5 @@ """ -Support gahtering system information of hosts which are running glances. +Support gathering system information of hosts which are running glances. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.glances/ @@ -24,6 +24,8 @@ DEFAULT_NAME = 'Glances' DEFAULT_PORT = '61208' +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60) + SENSOR_TYPES = { 'disk_use_percent': ['Disk Use', '%'], 'disk_use': ['Disk Use', 'GiB'], @@ -34,11 +36,11 @@ 'swap_use_percent': ['Swap Use', '%'], 'swap_use': ['Swap Use', 'GiB'], 'swap_free': ['Swap Free', 'GiB'], - 'processor_load': ['CPU Load', None], - 'process_running': ['Running', None], - 'process_total': ['Total', None], - 'process_thread': ['Thread', None], - 'process_sleeping': ['Sleeping', None] + 'processor_load': ['CPU Load', '15 min'], + 'process_running': ['Running', 'Count'], + 'process_total': ['Total', 'Count'], + 'process_thread': ['Thread', 'Count'], + 'process_sleeping': ['Sleeping', 'Count'] } PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ @@ -50,10 +52,6 @@ }) -# Return cached results if last scan was less then this time ago. -MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60) - - # pylint: disable=unused-variable def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the Glances sensor.""" @@ -66,7 +64,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): try: response = requests.get(url, timeout=10) if not response.ok: - _LOGGER.error('Response status is "%s"', response.status_code) + _LOGGER.error("Response status is '%s'", response.status_code) return False except requests.exceptions.ConnectionError: _LOGGER.error("No route to resource/endpoint: %s", url) From bb03960ba55084839d182ebe58cafc90f8e5b05b Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 1 Oct 2016 09:45:43 -0700 Subject: [PATCH 025/112] Voluptuous arest (#3558) * Migrate to voluptuous * Adjust sensor.arest for new template system * Use items() to align the var section with the pins --- .../components/binary_sensor/arest.py | 34 ++++--- homeassistant/components/sensor/arest.py | 89 ++++++++++--------- homeassistant/components/switch/arest.py | 88 ++++++++++-------- 3 files changed, 118 insertions(+), 93 deletions(-) diff --git a/homeassistant/components/binary_sensor/arest.py b/homeassistant/components/binary_sensor/arest.py index 5636261151411..02f9d75c4041e 100644 --- a/homeassistant/components/binary_sensor/arest.py +++ b/homeassistant/components/binary_sensor/arest.py @@ -1,5 +1,5 @@ """ -Support for exposed aREST RESTful API of a device. +Support for an exposed aREST RESTful API of a device. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/binary_sensor.arest/ @@ -8,31 +8,32 @@ from datetime import timedelta import requests +import voluptuous as vol from homeassistant.components.binary_sensor import ( - BinarySensorDevice, SENSOR_CLASSES) -from homeassistant.const import CONF_RESOURCE, CONF_PIN + BinarySensorDevice, PLATFORM_SCHEMA, SENSOR_CLASSES_SCHEMA) +from homeassistant.const import ( + CONF_RESOURCE, CONF_PIN, CONF_NAME, CONF_SENSOR_CLASS) from homeassistant.util import Throttle +import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_RESOURCE): cv.url, + vol.Optional(CONF_NAME): cv.string, + vol.Required(CONF_PIN): cv.string, + vol.Optional(CONF_SENSOR_CLASS): SENSOR_CLASSES_SCHEMA, +}) + def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the aREST binary sensor.""" resource = config.get(CONF_RESOURCE) pin = config.get(CONF_PIN) - - sensor_class = config.get('sensor_class') - if sensor_class not in SENSOR_CLASSES: - _LOGGER.warning('Unknown sensor class: %s', sensor_class) - sensor_class = None - - if None in (resource, pin): - _LOGGER.error('Not all required config keys present: %s', - ', '.join((CONF_RESOURCE, CONF_PIN))) - return False + sensor_class = config.get(CONF_SENSOR_CLASS) try: response = requests.get(resource, timeout=10).json() @@ -49,11 +50,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): arest = ArestData(resource, pin) add_devices([ArestBinarySensor( - arest, - resource, - config.get('name', response['name']), - sensor_class, - pin)]) + arest, resource, config.get(CONF_NAME, response[CONF_NAME]), + sensor_class, pin)]) # pylint: disable=too-many-instance-attributes, too-many-arguments diff --git a/homeassistant/components/sensor/arest.py b/homeassistant/components/sensor/arest.py index 80ff1f7d975a2..c13ea15b22287 100644 --- a/homeassistant/components/sensor/arest.py +++ b/homeassistant/components/sensor/arest.py @@ -1,5 +1,5 @@ """ -The arest sensor will consume an exposed aREST API of a device. +Support for an exposed aREST RESTful API of a device. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.arest/ @@ -8,30 +8,48 @@ from datetime import timedelta import requests +import voluptuous as vol +from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( - ATTR_UNIT_OF_MEASUREMENT, CONF_VALUE_TEMPLATE, DEVICE_DEFAULT_NAME, - CONF_RESOURCE, CONF_MONITORED_VARIABLES) + CONF_UNIT_OF_MEASUREMENT, CONF_VALUE_TEMPLATE, CONF_RESOURCE, + CONF_MONITORED_VARIABLES, CONF_NAME, STATE_UNKNOWN) from homeassistant.exceptions import TemplateError from homeassistant.helpers.entity import Entity -from homeassistant.helpers import template from homeassistant.util import Throttle +import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) +CONF_FUNCTIONS = 'functions' +CONF_PINS = 'pins' +DEFAULT_NAME = 'aREST sensor' + +PIN_VARIABLE_SCHEMA = vol.Schema({ + vol.Optional(CONF_NAME): cv.string, + vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string, + vol.Optional(CONF_VALUE_TEMPLATE): cv.template, +}) + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_RESOURCE): cv.url, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_PINS, default={}): + vol.Schema({cv.string: PIN_VARIABLE_SCHEMA}), + vol.Optional(CONF_MONITORED_VARIABLES, default={}): + vol.Schema({cv.string: PIN_VARIABLE_SCHEMA}), +}) + + +# pylint: disable=too-many-locals def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the aREST sensor.""" resource = config.get(CONF_RESOURCE) var_conf = config.get(CONF_MONITORED_VARIABLES) - pins = config.get('pins', None) - - if resource is None: - _LOGGER.error('Not all required config keys present: %s', - CONF_RESOURCE) - return False + pins = config.get(CONF_PINS) try: response = requests.get(resource, timeout=10).json() @@ -52,7 +70,7 @@ def make_renderer(value_template): if value_template is None: return lambda value: value - value_template = template.Template(value_template, hass) + value_template.hass = hass def _render(value): try: @@ -66,33 +84,26 @@ def _render(value): dev = [] if var_conf is not None: - for variable in var_conf: - if variable['name'] not in response['variables']: - _LOGGER.error('Variable: "%s" does not exist', - variable['name']) + for variable, var_data in var_conf.items(): + if variable not in response['variables']: + _LOGGER.error("Variable: '%s' does not exist", variable) continue - renderer = make_renderer(variable.get(CONF_VALUE_TEMPLATE)) - dev.append(ArestSensor(arest, - resource, - config.get('name', response['name']), - variable['name'], - variable=variable['name'], - unit_of_measurement=variable.get( - ATTR_UNIT_OF_MEASUREMENT), - renderer=renderer)) + renderer = make_renderer(var_data.get(CONF_VALUE_TEMPLATE)) + dev.append(ArestSensor( + arest, resource, config.get(CONF_NAME, response[CONF_NAME]), + variable, variable=variable, + unit_of_measurement=var_data.get(CONF_UNIT_OF_MEASUREMENT), + renderer=renderer)) if pins is not None: for pinnum, pin in pins.items(): renderer = make_renderer(pin.get(CONF_VALUE_TEMPLATE)) - dev.append(ArestSensor(ArestData(resource, pinnum), - resource, - config.get('name', response['name']), - pin.get('name'), - pin=pinnum, - unit_of_measurement=pin.get( - ATTR_UNIT_OF_MEASUREMENT), - renderer=renderer)) + dev.append(ArestSensor( + ArestData(resource, pinnum), resource, + config.get(CONF_NAME, response[CONF_NAME]), pin.get(CONF_NAME), + pin=pinnum, unit_of_measurement=pin.get( + CONF_UNIT_OF_MEASUREMENT), renderer=renderer)) add_devices(dev) @@ -106,18 +117,17 @@ def __init__(self, arest, resource, location, name, variable=None, """Initialize the sensor.""" self.arest = arest self._resource = resource - self._name = '{} {}'.format(location.title(), name.title()) \ - or DEVICE_DEFAULT_NAME + self._name = '{} {}'.format(location.title(), name.title()) self._variable = variable self._pin = pin - self._state = 'n/a' + self._state = STATE_UNKNOWN self._unit_of_measurement = unit_of_measurement self._renderer = renderer self.update() if self._pin is not None: - request = requests.get('{}/mode/{}/i'.format - (self._resource, self._pin), timeout=10) + request = requests.get( + '{}/mode/{}/i'.format(self._resource, self._pin), timeout=10) if request.status_code is not 200: _LOGGER.error("Can't set mode. Is device offline?") @@ -139,9 +149,8 @@ def state(self): if 'error' in values: return values['error'] - value = self._renderer(values.get('value', - values.get(self._variable, - 'N/A'))) + value = self._renderer( + values.get('value', values.get(self._variable, STATE_UNKNOWN))) return value def update(self): diff --git a/homeassistant/components/switch/arest.py b/homeassistant/components/switch/arest.py index 18fabd3cb7490..ce5c946b43610 100644 --- a/homeassistant/components/switch/arest.py +++ b/homeassistant/components/switch/arest.py @@ -1,5 +1,5 @@ """ -Support for device running with the aREST RESTful framework. +Support for an exposed aREST RESTful API of a device. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/switch.arest/ @@ -8,17 +8,36 @@ import logging import requests +import voluptuous as vol -from homeassistant.components.switch import SwitchDevice -from homeassistant.const import ( - DEVICE_DEFAULT_NAME, CONF_NAME, CONF_RESOURCE) +from homeassistant.components.switch import (SwitchDevice, PLATFORM_SCHEMA) +from homeassistant.const import (CONF_NAME, CONF_RESOURCE) +import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) +CONF_FUNCTIONS = 'functions' +CONF_PINS = 'pins' + +DEFAULT_NAME = 'aREST switch' + +PIN_FUNCTION_SCHEMA = vol.Schema({ + vol.Optional(CONF_NAME): cv.string, +}) + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_RESOURCE): cv.url, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_PINS, default={}): + vol.Schema({cv.string: PIN_FUNCTION_SCHEMA}), + vol.Optional(CONF_FUNCTIONS, default={}): + vol.Schema({cv.string: PIN_FUNCTION_SCHEMA}), +}) + def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the aREST switches.""" - resource = config.get(CONF_RESOURCE, None) + resource = config.get(CONF_RESOURCE) try: response = requests.get(resource, timeout=10) @@ -33,29 +52,28 @@ def setup_platform(hass, config, add_devices, discovery_info=None): return False dev = [] - pins = config.get('pins', {}) + pins = config.get(CONF_PINS) for pinnum, pin in pins.items(): dev.append(ArestSwitchPin( - resource, config.get(CONF_NAME, response.json()['name']), - pin.get('name'), pinnum)) + resource, config.get(CONF_NAME, response.json()[CONF_NAME]), + pin.get(CONF_NAME), pinnum)) - functions = config.get('functions', {}) + functions = config.get(CONF_FUNCTIONS) for funcname, func in functions.items(): dev.append(ArestSwitchFunction( - resource, config.get(CONF_NAME, response.json()['name']), - func.get('name'), funcname)) + resource, config.get(CONF_NAME, response.json()[CONF_NAME]), + func.get(CONF_NAME), funcname)) add_devices(dev) class ArestSwitchBase(SwitchDevice): - """representation of an aREST switch.""" + """Representation of an aREST switch.""" def __init__(self, resource, location, name): """Initialize the switch.""" self._resource = resource - self._name = '{} {}'.format(location.title(), name.title()) \ - or DEVICE_DEFAULT_NAME + self._name = '{} {}'.format(location.title(), name.title()) self._state = None @property @@ -77,8 +95,8 @@ def __init__(self, resource, location, name, func): super().__init__(resource, location, name) self._func = func - request = requests.get('{}/{}'.format(self._resource, self._func), - timeout=10) + request = requests.get( + '{}/{}'.format(self._resource, self._func), timeout=10) if request.status_code is not 200: _LOGGER.error("Can't find function. Is device offline?") @@ -90,36 +108,36 @@ def __init__(self, resource, location, name, func): _LOGGER.error("No return_value received. " "Is the function name correct.") except ValueError: - _LOGGER.error("Response invalid. Is the function name correct.") + _LOGGER.error("Response invalid. Is the function name correct?") def turn_on(self, **kwargs): """Turn the device on.""" - request = requests.get('{}/{}'.format(self._resource, self._func), - timeout=10, params={"params": "1"}) + request = requests.get( + '{}/{}'.format(self._resource, self._func), timeout=10, + params={'params': '1'}) if request.status_code == 200: self._state = True else: _LOGGER.error("Can't turn on function %s at %s. " - "Is device offline?", - self._func, self._resource) + "Is device offline?", self._func, self._resource) def turn_off(self, **kwargs): """Turn the device off.""" - request = requests.get('{}/{}'.format(self._resource, self._func), - timeout=10, params={"params": "0"}) + request = requests.get( + '{}/{}'.format(self._resource, self._func), timeout=10, + params={'params': '0'}) if request.status_code == 200: self._state = False else: _LOGGER.error("Can't turn off function %s at %s. " - "Is device offline?", - self._func, self._resource) + "Is device offline?", self._func, self._resource) def update(self): """Get the latest data from aREST API and update the state.""" - request = requests.get('{}/{}'.format(self._resource, - self._func), timeout=10) + request = requests.get( + '{}/{}'.format(self._resource, self._func), timeout=10) self._state = request.json()['return_value'] != 0 @@ -131,15 +149,15 @@ def __init__(self, resource, location, name, pin): super().__init__(resource, location, name) self._pin = pin - request = requests.get('{}/mode/{}/o'.format(self._resource, - self._pin), timeout=10) + request = requests.get( + '{}/mode/{}/o'.format(self._resource, self._pin), timeout=10) if request.status_code is not 200: _LOGGER.error("Can't set mode. Is device offline?") def turn_on(self, **kwargs): """Turn the device on.""" - request = requests.get('{}/digital/{}/1'.format(self._resource, - self._pin), timeout=10) + request = requests.get( + '{}/digital/{}/1'.format(self._resource, self._pin), timeout=10) if request.status_code == 200: self._state = True else: @@ -148,8 +166,8 @@ def turn_on(self, **kwargs): def turn_off(self, **kwargs): """Turn the device off.""" - request = requests.get('{}/digital/{}/0'.format(self._resource, - self._pin), timeout=10) + request = requests.get( + '{}/digital/{}/0'.format(self._resource, self._pin), timeout=10) if request.status_code == 200: self._state = False else: @@ -158,6 +176,6 @@ def turn_off(self, **kwargs): def update(self): """Get the latest data from aREST API and update the state.""" - request = requests.get('{}/digital/{}'.format(self._resource, - self._pin), timeout=10) + request = requests.get( + '{}/digital/{}'.format(self._resource, self._pin), timeout=10) self._state = request.json()['return_value'] != 0 From 892bbdc2ddf0948046a4bde4249da4479a7adfa0 Mon Sep 17 00:00:00 2001 From: Ben Bangert Date: Sat, 1 Oct 2016 12:08:25 -0700 Subject: [PATCH 026/112] Monkey-patch a weakref set in Task to be a no-op. (#3639) * Monkey-patch a weakref set in Task to be a no-op. * Fix linting issues --- homeassistant/__main__.py | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index a7b2027963f90..30dfa6b6db093 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -19,6 +19,49 @@ from homeassistant.util.async import run_callback_threadsafe +def monkey_patch_asyncio(): + """Replace weakref.WeakSet to address Python 3 bug. + + Under heavy threading operations that schedule calls into + the asyncio event loop, Task objects are created. Due to + a bug in Python, GC may have an issue when switching between + the threads and objects with __del__ (which various components + in HASS have). + + This monkey-patch removes the weakref.Weakset, and replaces it + with an object that ignores the only call utilizing it (the + Task.__init__ which calls _all_tasks.add(self)). It also removes + the __del__ which could trigger the future objects __del__ at + unpredictable times. + + The side-effect of this manipulation of the Task is that + Task.all_tasks() is no longer accurate, and there will be no + warning emitted if a Task is GC'd while in use. + + On Python 3.6, after the bug is fixed, this monkey-patch can be + disabled. + + See https://bugs.python.org/issue26617 for details of the Python + bug. + """ + # pylint: disable=no-self-use, too-few-public-methods, protected-access + # pylint: disable=bare-except + import asyncio.tasks + + class IgnoreCalls: + """Ignore add calls.""" + + def add(self, other): + """No-op add.""" + return + + asyncio.tasks.Task._all_tasks = IgnoreCalls() + try: + del asyncio.tasks.Task.__del__ + except: + pass + + def validate_python() -> None: """Validate we're running the right Python version.""" if sys.version_info[:3] < REQUIRED_PYTHON_VER: @@ -308,6 +351,8 @@ def try_to_restart() -> None: def main() -> int: """Start Home Assistant.""" + monkey_patch_asyncio() + validate_python() args = get_arguments() From 3e24a35c1e46586cd3d27cced3e15db70b798a11 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 1 Oct 2016 13:57:10 -0700 Subject: [PATCH 027/112] Skip RFXtrx tests unless RFXTRX=RUN (#3625) * Skip RFXtrx tests unless RFXTRX=RUN * Remove my previous hacks to slightly speed up rfxtrx * Exclude RFXTRX tests from coverage * Remove unused import in rfxtrx tstt * Add close connection back to RFXtrx tests * Typo --- .coveragerc | 3 +++ tests/components/cover/test_rfxtrx.py | 2 +- tests/components/light/test_rfxtrx.py | 2 +- tests/components/rollershutter/test_rfxtrx.py | 2 +- tests/components/sensor/test_rfxtrx.py | 4 +++- tests/components/switch/test_rfxtrx.py | 2 +- tests/components/test_rfxtrx.py | 19 ++++++++----------- 7 files changed, 18 insertions(+), 16 deletions(-) diff --git a/.coveragerc b/.coveragerc index c2a0e2636e816..e1652fb23b621 100644 --- a/.coveragerc +++ b/.coveragerc @@ -49,6 +49,9 @@ omit = homeassistant/components/qwikswitch.py homeassistant/components/*/qwikswitch.py + homeassistant/components/rfxtrx.py + homeassistant/components/*/rfxtrx.py + homeassistant/components/rpi_gpio.py homeassistant/components/*/rpi_gpio.py diff --git a/tests/components/cover/test_rfxtrx.py b/tests/components/cover/test_rfxtrx.py index a73a2b978dc54..80d49dface44f 100644 --- a/tests/components/cover/test_rfxtrx.py +++ b/tests/components/cover/test_rfxtrx.py @@ -9,7 +9,7 @@ from tests.common import get_test_home_assistant -@pytest.mark.skipif("os.environ.get('RFXTRX') == 'SKIP'") +@pytest.mark.skipif("os.environ.get('RFXTRX') != 'RUN'") class TestCoverRfxtrx(unittest.TestCase): """Test the Rfxtrx cover platform.""" diff --git a/tests/components/light/test_rfxtrx.py b/tests/components/light/test_rfxtrx.py index 80014dfd1c16f..a9c2b2d8bcb2f 100644 --- a/tests/components/light/test_rfxtrx.py +++ b/tests/components/light/test_rfxtrx.py @@ -9,7 +9,7 @@ from tests.common import get_test_home_assistant -@pytest.mark.skipif("os.environ.get('RFXTRX') == 'SKIP'") +@pytest.mark.skipif("os.environ.get('RFXTRX') != 'RUN'") class TestLightRfxtrx(unittest.TestCase): """Test the Rfxtrx light platform.""" diff --git a/tests/components/rollershutter/test_rfxtrx.py b/tests/components/rollershutter/test_rfxtrx.py index 1218ab37a5981..e16f841c3fef5 100644 --- a/tests/components/rollershutter/test_rfxtrx.py +++ b/tests/components/rollershutter/test_rfxtrx.py @@ -9,7 +9,7 @@ from tests.common import get_test_home_assistant -@pytest.mark.skipif("os.environ.get('RFXTRX') == 'SKIP'") +@pytest.mark.skipif("os.environ.get('RFXTRX') != 'RUN'") class TestRollershutterRfxtrx(unittest.TestCase): """Test the Rfxtrx roller shutter platform.""" diff --git a/tests/components/sensor/test_rfxtrx.py b/tests/components/sensor/test_rfxtrx.py index e42aaea7e04d4..cfe5a95605db1 100644 --- a/tests/components/sensor/test_rfxtrx.py +++ b/tests/components/sensor/test_rfxtrx.py @@ -10,7 +10,7 @@ from tests.common import get_test_home_assistant -@pytest.mark.skipif("os.environ.get('RFXTRX') == 'SKIP'") +@pytest.mark.skipif("os.environ.get('RFXTRX') != 'RUN'") class TestSensorRfxtrx(unittest.TestCase): """Test the Rfxtrx sensor platform.""" @@ -23,6 +23,8 @@ def tearDown(self): """Stop everything that was started.""" rfxtrx_core.RECEIVED_EVT_SUBSCRIBERS = [] rfxtrx_core.RFX_DEVICES = {} + if rfxtrx_core.RFXOBJECT: + rfxtrx_core.RFXOBJECT.close_connection() self.hass.stop() def test_default_config(self): diff --git a/tests/components/switch/test_rfxtrx.py b/tests/components/switch/test_rfxtrx.py index 729abf6db063e..4caf7b3405d97 100644 --- a/tests/components/switch/test_rfxtrx.py +++ b/tests/components/switch/test_rfxtrx.py @@ -9,7 +9,7 @@ from tests.common import get_test_home_assistant -@pytest.mark.skipif("os.environ.get('RFXTRX') == 'SKIP'") +@pytest.mark.skipif("os.environ.get('RFXTRX') != 'RUN'") class TestSwitchRfxtrx(unittest.TestCase): """Test the Rfxtrx switch platform.""" diff --git a/tests/components/test_rfxtrx.py b/tests/components/test_rfxtrx.py index bd37d87315078..b26483c877158 100644 --- a/tests/components/test_rfxtrx.py +++ b/tests/components/test_rfxtrx.py @@ -1,7 +1,6 @@ -"""Th tests for the Rfxtrx component.""" +"""The tests for the Rfxtrx component.""" # pylint: disable=too-many-public-methods,protected-access import unittest -from unittest.mock import patch import pytest @@ -10,7 +9,7 @@ from tests.common import get_test_home_assistant -@pytest.mark.skipif("os.environ.get('RFXTRX') == 'SKIP'") +@pytest.mark.skipif("os.environ.get('RFXTRX') != 'RUN'") class TestRFXTRX(unittest.TestCase): """Test the Rfxtrx component.""" @@ -22,10 +21,11 @@ def tearDown(self): """Stop everything that was started.""" rfxtrx.RECEIVED_EVT_SUBSCRIBERS = [] rfxtrx.RFX_DEVICES = {} + if rfxtrx.RFXOBJECT: + rfxtrx.RFXOBJECT.close_connection() self.hass.stop() - @patch('RFXtrx.sleep') - def test_default_config(self, mock_sleep): + def test_default_config(self): """Test configuration.""" self.assertTrue(_setup_component(self.hass, 'rfxtrx', { 'rfxtrx': { @@ -41,8 +41,7 @@ def test_default_config(self, mock_sleep): self.assertEqual(len(rfxtrx.RFXOBJECT.sensors()), 2) - @patch('RFXtrx.sleep') - def test_valid_config(self, mock_sleep): + def test_valid_config(self): """Test configuration.""" self.assertTrue(_setup_component(self.hass, 'rfxtrx', { 'rfxtrx': { @@ -71,8 +70,7 @@ def test_invalid_config(self): '-RFXCOM_RFXtrx433_A1Y0NJGR-if00-port0', 'invalid_key': True}})) - @patch('RFXtrx.sleep') - def test_fire_event(self, mock_sleep): + def test_fire_event(self): """Test fire event.""" self.assertTrue(_setup_component(self.hass, 'rfxtrx', { 'rfxtrx': { @@ -116,8 +114,7 @@ def record_event(event): self.assertEqual(calls[0].data, {'entity_id': 'switch.test', 'state': 'on'}) - @patch('RFXtrx.sleep') - def test_fire_event_sensor(self, mock_sleep): + def test_fire_event_sensor(self): """Test fire event.""" self.assertTrue(_setup_component(self.hass, 'rfxtrx', { 'rfxtrx': { From 4198c427362f8e6373a0b71b188c9638f7e54736 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 30 Sep 2016 21:38:39 -0700 Subject: [PATCH 028/112] Have template platforms never leave the event loop --- .../components/binary_sensor/template.py | 9 +++++--- homeassistant/components/sensor/template.py | 9 +++++--- homeassistant/components/switch/template.py | 9 +++++--- homeassistant/helpers/entity.py | 21 ++++++++++++----- .../components/binary_sensor/test_template.py | 2 +- tests/helpers/test_entity.py | 23 ++++++++++++++++++- 6 files changed, 56 insertions(+), 17 deletions(-) diff --git a/homeassistant/components/binary_sensor/template.py b/homeassistant/components/binary_sensor/template.py index 662a6982a1106..85c9f0e895053 100644 --- a/homeassistant/components/binary_sensor/template.py +++ b/homeassistant/components/binary_sensor/template.py @@ -4,6 +4,7 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/binary_sensor.template/ """ +import asyncio import logging import voluptuous as vol @@ -81,9 +82,10 @@ def __init__(self, hass, device, friendly_name, sensor_class, self.update() + @asyncio.coroutine def template_bsensor_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" - self.update_ha_state(True) + yield from self.async_update_ha_state(True) track_state_change(hass, entity_ids, template_bsensor_state_listener) @@ -107,10 +109,11 @@ def should_poll(self): """No polling needed.""" return False - def update(self): + @asyncio.coroutine + def async_update(self): """Get the latest data and update the state.""" try: - self._state = self._template.render().lower() == 'true' + self._state = self._template.async_render().lower() == 'true' except TemplateError as ex: if ex.args and ex.args[0].startswith( "UndefinedError: 'None' has no attribute"): diff --git a/homeassistant/components/sensor/template.py b/homeassistant/components/sensor/template.py index c7c94aeaf9e75..4b6f322b5aa0c 100644 --- a/homeassistant/components/sensor/template.py +++ b/homeassistant/components/sensor/template.py @@ -4,6 +4,7 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.template/ """ +import asyncio import logging import voluptuous as vol @@ -78,9 +79,10 @@ def __init__(self, hass, device_id, friendly_name, unit_of_measurement, self.update() + @asyncio.coroutine def template_sensor_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" - self.update_ha_state(True) + yield from self.async_update_ha_state(True) track_state_change(hass, entity_ids, template_sensor_state_listener) @@ -104,10 +106,11 @@ def should_poll(self): """No polling needed.""" return False - def update(self): + @asyncio.coroutine + def async_update(self): """Get the latest data and update the states.""" try: - self._state = self._template.render() + self._state = self._template.async_render() except TemplateError as ex: if ex.args and ex.args[0].startswith( "UndefinedError: 'None' has no attribute"): diff --git a/homeassistant/components/switch/template.py b/homeassistant/components/switch/template.py index 5358a23d8c6d4..7c6f4f5886d22 100644 --- a/homeassistant/components/switch/template.py +++ b/homeassistant/components/switch/template.py @@ -4,6 +4,7 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/switch.template/ """ +import asyncio import logging import voluptuous as vol @@ -87,9 +88,10 @@ def __init__(self, hass, device_id, friendly_name, state_template, self.update() + @asyncio.coroutine def template_switch_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" - self.update_ha_state(True) + yield from self.async_update_ha_state(True) track_state_change(hass, entity_ids, template_switch_state_listener) @@ -121,10 +123,11 @@ def turn_off(self, **kwargs): """Fire the off action.""" self._off_script.run() - def update(self): + @asyncio.coroutine + def async_update(self): """Update the state from the template.""" try: - state = self._template.render().lower() + state = self._template.async_render().lower() if state in _VALID_STATES: self._state = state in ('true', STATE_ON) diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index 7529d6288ab7d..3c119eb456eba 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -49,6 +49,11 @@ class Entity(object): # SAFE TO OVERWRITE # The properties and methods here are safe to overwrite when inheriting # this class. These may be used to customize the behavior of the entity. + entity_id = None # type: str + + # Owning hass instance. Will be set by EntityComponent + hass = None # type: Optional[HomeAssistant] + @property def should_poll(self) -> bool: """Return True if entity has to be polled for state. @@ -128,18 +133,22 @@ def force_update(self) -> bool: return False def update(self): - """Retrieve latest state.""" - pass + """Retrieve latest state. - entity_id = None # type: str + When not implemented, will forward call to async version if available. + """ + async_update = getattr(self, 'async_update', None) + + if async_update is None: + return + + run_coroutine_threadsafe(async_update(), self.hass.loop).result() # DO NOT OVERWRITE # These properties and methods are either managed by Home Assistant or they # are used to perform a very specific function. Overwriting these may # produce undesirable effects in the entity's operation. - hass = None # type: Optional[HomeAssistant] - def update_ha_state(self, force_refresh=False): """Update Home Assistant with current state of entity. @@ -172,7 +181,7 @@ def async_update_ha_state(self, force_refresh=False): if force_refresh: if hasattr(self, 'async_update'): # pylint: disable=no-member - self.async_update() + yield from self.async_update() else: # PS: Run this in our own thread pool once we have # future support? diff --git a/tests/components/binary_sensor/test_template.py b/tests/components/binary_sensor/test_template.py index 7337bd4de0314..c9e4bf6138b79 100644 --- a/tests/components/binary_sensor/test_template.py +++ b/tests/components/binary_sensor/test_template.py @@ -119,7 +119,7 @@ def test_event(self): vs.update_ha_state() self.hass.block_till_done() - with mock.patch.object(vs, 'update') as mock_update: + with mock.patch.object(vs, 'async_update') as mock_update: self.hass.bus.fire(EVENT_STATE_CHANGED) self.hass.block_till_done() assert mock_update.call_count == 1 diff --git a/tests/helpers/test_entity.py b/tests/helpers/test_entity.py index 81ef17ff0fdf0..f63e80ec1f97d 100644 --- a/tests/helpers/test_entity.py +++ b/tests/helpers/test_entity.py @@ -53,7 +53,12 @@ def test(): assert len(sync_update) == 1 assert len(async_update) == 0 - ent.async_update = lambda: async_update.append(1) + @asyncio.coroutine + def async_update_func(): + """Async update.""" + async_update.append(1) + + ent.async_update = async_update_func event_loop.run_until_complete(test()) @@ -95,3 +100,19 @@ def test_generate_entity_id_given_hass(self): assert entity.generate_entity_id( fmt, 'overwrite hidden true', hass=self.hass) == 'test.overwrite_hidden_true_2' + + def test_update_calls_async_update_if_available(self): + """Test async update getting called.""" + async_update = [] + + class AsyncEntity(entity.Entity): + hass = self.hass + entity_id = 'sensor.test' + + @asyncio.coroutine + def async_update(self): + async_update.append([1]) + + ent = AsyncEntity() + ent.update() + assert len(async_update) == 1 From 33a51623f893d0b2aa5d1e99fbaebaa538bd87a0 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 30 Sep 2016 22:34:45 -0700 Subject: [PATCH 029/112] Make Service.call_from_config async --- homeassistant/helpers/service.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/homeassistant/helpers/service.py b/homeassistant/helpers/service.py index 665e22404c645..06df2eb992db5 100644 --- a/homeassistant/helpers/service.py +++ b/homeassistant/helpers/service.py @@ -1,4 +1,5 @@ """Service calling related helpers.""" +import asyncio import functools import logging # pylint: disable=unused-import @@ -11,6 +12,7 @@ from homeassistant.exceptions import TemplateError from homeassistant.loader import get_component import homeassistant.helpers.config_validation as cv +from homeassistant.util.async import run_coroutine_threadsafe HASS = None # type: Optional[HomeAssistant] @@ -37,6 +39,15 @@ def register_service_decorator(action): def call_from_config(hass, config, blocking=False, variables=None, validate_config=True): """Call a service based on a config hash.""" + run_coroutine_threadsafe( + async_call_from_config(hass, config, blocking, variables, + validate_config), hass.loop).result() + + +@asyncio.coroutine +def async_call_from_config(hass, config, blocking=False, variables=None, + validate_config=True): + """Call a service based on a config hash.""" if validate_config: try: config = cv.SERVICE_SCHEMA(config) @@ -49,7 +60,8 @@ def call_from_config(hass, config, blocking=False, variables=None, else: try: config[CONF_SERVICE_TEMPLATE].hass = hass - domain_service = config[CONF_SERVICE_TEMPLATE].render(variables) + domain_service = config[CONF_SERVICE_TEMPLATE].async_render( + variables) domain_service = cv.service(domain_service) except TemplateError as ex: _LOGGER.error('Error rendering service name template: %s', ex) @@ -71,14 +83,15 @@ def _data_template_creator(value): return {key: _data_template_creator(item) for key, item in value.items()} value.hass = hass - return value.render(variables) + return value.async_render(variables) service_data.update(_data_template_creator( config[CONF_SERVICE_DATA_TEMPLATE])) if CONF_SERVICE_ENTITY_ID in config: service_data[ATTR_ENTITY_ID] = config[CONF_SERVICE_ENTITY_ID] - hass.services.call(domain, service_name, service_data, blocking) + yield from hass.services.async_call( + domain, service_name, service_data, blocking) def extract_entity_ids(hass, service_call): From 185bd6c28a5c8abbfa62d7eeda43c135e012d96d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 30 Sep 2016 23:11:57 -0700 Subject: [PATCH 030/112] Make helpers.condition.* async --- homeassistant/helpers/condition.py | 101 ++++++++++++++++++++++------- 1 file changed, 78 insertions(+), 23 deletions(-) diff --git a/homeassistant/helpers/condition.py b/homeassistant/helpers/condition.py index 041f514aedae7..ae1dc47170658 100644 --- a/homeassistant/helpers/condition.py +++ b/homeassistant/helpers/condition.py @@ -20,15 +20,43 @@ from homeassistant.util.async import run_callback_threadsafe FROM_CONFIG_FORMAT = '{}_from_config' +ASYNC_FROM_CONFIG_FORMAT = 'async_{}_from_config' _LOGGER = logging.getLogger(__name__) +# PyLint does not like the use of _threaded_factory +# pylint: disable=invalid-name -def from_config(config: ConfigType, config_validation: bool=True): - """Turn a condition configuration into a method.""" - factory = getattr( - sys.modules[__name__], - FROM_CONFIG_FORMAT.format(config.get(CONF_CONDITION)), None) + +def _threaded_factory(async_factory): + """Helper method to create threaded versions of async factories.""" + def factory(config, config_validation=True): + """Threaded factory.""" + async_check = async_factory(config, config_validation) + + def condition_if(hass, variables=None): + """Validate condition.""" + return run_callback_threadsafe( + hass.loop, async_check, hass, variables, + ).result() + + return condition_if + + return factory + + +def async_from_config(config: ConfigType, config_validation: bool=True): + """Turn a condition configuration into a method. + + Should be run on the event loop. + """ + for fmt in (ASYNC_FROM_CONFIG_FORMAT, FROM_CONFIG_FORMAT): + factory = getattr( + sys.modules[__name__], + fmt.format(config.get(CONF_CONDITION)), None) + + if factory: + break if factory is None: raise HomeAssistantError('Invalid condition "{}" specified {}'.format( @@ -37,49 +65,70 @@ def from_config(config: ConfigType, config_validation: bool=True): return factory(config, config_validation) -def and_from_config(config: ConfigType, config_validation: bool=True): +from_config = _threaded_factory(async_from_config) + + +def async_and_from_config(config: ConfigType, config_validation: bool=True): """Create multi condition matcher using 'AND'.""" if config_validation: config = cv.AND_CONDITION_SCHEMA(config) - checks = [from_config(entry, False) for entry in config['conditions']] + checks = None def if_and_condition(hass: HomeAssistant, variables=None) -> bool: """Test and condition.""" - for check in checks: - try: + nonlocal checks + + if checks is None: + checks = [async_from_config(entry, False) for entry + in config['conditions']] + + try: + for check in checks: if not check(hass, variables): return False - except Exception as ex: # pylint: disable=broad-except - _LOGGER.warning('Error during and-condition: %s', ex) - return False + except Exception as ex: # pylint: disable=broad-except + _LOGGER.warning('Error during and-condition: %s', ex) + return False return True return if_and_condition -def or_from_config(config: ConfigType, config_validation: bool=True): +and_from_config = _threaded_factory(async_and_from_config) + + +def async_or_from_config(config: ConfigType, config_validation: bool=True): """Create multi condition matcher using 'OR'.""" if config_validation: config = cv.OR_CONDITION_SCHEMA(config) - checks = [from_config(entry, False) for entry in config['conditions']] + checks = None def if_or_condition(hass: HomeAssistant, variables=None) -> bool: """Test and condition.""" - for check in checks: - try: + nonlocal checks + + if checks is None: + checks = [async_from_config(entry, False) for entry + in config['conditions']] + + try: + for check in checks: if check(hass, variables): return True - except Exception as ex: # pylint: disable=broad-except - _LOGGER.warning('Error during or-condition: %s', ex) + except Exception as ex: # pylint: disable=broad-except + _LOGGER.warning('Error during or-condition: %s', ex) return False return if_or_condition +or_from_config = _threaded_factory(async_or_from_config) + + # pylint: disable=too-many-arguments def numeric_state(hass: HomeAssistant, entity, below=None, above=None, value_template=None, variables=None): @@ -125,7 +174,7 @@ def async_numeric_state(hass: HomeAssistant, entity, below=None, above=None, return True -def numeric_state_from_config(config, config_validation=True): +def async_numeric_state_from_config(config, config_validation=True): """Wrap action method with state based condition.""" if config_validation: config = cv.NUMERIC_STATE_CONDITION_SCHEMA(config) @@ -139,12 +188,15 @@ def if_numeric_state(hass, variables=None): if value_template is not None: value_template.hass = hass - return numeric_state(hass, entity_id, below, above, value_template, - variables) + return async_numeric_state( + hass, entity_id, below, above, value_template, variables) return if_numeric_state +numeric_state_from_config = _threaded_factory(async_numeric_state_from_config) + + def state(hass, entity, req_state, for_period=None): """Test if state matches requirements.""" if isinstance(entity, str): @@ -235,7 +287,7 @@ def async_template(hass, value_template, variables=None): return value.lower() == 'true' -def template_from_config(config, config_validation=True): +def async_template_from_config(config, config_validation=True): """Wrap action method with state based condition.""" if config_validation: config = cv.TEMPLATE_CONDITION_SCHEMA(config) @@ -245,11 +297,14 @@ def template_if(hass, variables=None): """Validate template based if-condition.""" value_template.hass = hass - return template(hass, value_template, variables) + return async_template(hass, value_template, variables) return template_if +template_from_config = _threaded_factory(async_template_from_config) + + def time(before=None, after=None, weekday=None): """Test if local time condition matches. From b8504f8fc8ff7767de62ed1b6db56694b3e2c56e Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 30 Sep 2016 23:26:01 -0700 Subject: [PATCH 031/112] Make helpers.script async --- homeassistant/helpers/script.py | 153 ++++++++++++++++++-------------- 1 file changed, 87 insertions(+), 66 deletions(-) diff --git a/homeassistant/helpers/script.py b/homeassistant/helpers/script.py index 071326bf973d5..1bfe7d550adc9 100644 --- a/homeassistant/helpers/script.py +++ b/homeassistant/helpers/script.py @@ -1,6 +1,6 @@ """Helpers to execute scripts.""" +import asyncio import logging -import threading from itertools import islice from typing import Optional, Sequence @@ -10,9 +10,11 @@ from homeassistant.const import CONF_CONDITION from homeassistant.helpers import ( service, condition, template, config_validation as cv) -from homeassistant.helpers.event import track_point_in_utc_time +from homeassistant.helpers.event import async_track_point_in_utc_time from homeassistant.helpers.typing import ConfigType import homeassistant.util.dt as date_util +from homeassistant.util.async import ( + run_coroutine_threadsafe, run_callback_threadsafe) _LOGGER = logging.getLogger(__name__) @@ -47,8 +49,7 @@ def __init__(self, hass: HomeAssistant, sequence, name: str=None, self.last_action = None self.can_cancel = any(CONF_DELAY in action for action in self.sequence) - self._lock = threading.Lock() - self._unsub_delay_listener = None + self._async_unsub_delay_listener = None self._template_cache = {} @property @@ -56,94 +57,107 @@ def is_running(self) -> bool: """Return true if script is on.""" return self._cur != -1 - def run(self, variables: Optional[Sequence]=None) -> None: + def run(self, variables=None): """Run script.""" - with self._lock: - if self._cur == -1: - self._log('Running script') - self._cur = 0 - - # Unregister callback if we were in a delay but turn on is called - # again. In that case we just continue execution. - self._remove_listener() - - for cur, action in islice(enumerate(self.sequence), self._cur, - None): - - if CONF_DELAY in action: - # Call ourselves in the future to continue work - def script_delay(now): - """Called after delay is done.""" - self._unsub_delay_listener = None - self.run(variables) - - delay = action[CONF_DELAY] - - if isinstance(delay, template.Template): - delay = vol.All( - cv.time_period, - cv.positive_timedelta)( - delay.render()) - - self._unsub_delay_listener = track_point_in_utc_time( + run_coroutine_threadsafe( + self.async_run(variables), self.hass.loop).result() + + @asyncio.coroutine + def async_run(self, variables: Optional[Sequence]=None) -> None: + """Run script. + + Returns a coroutine. + """ + if self._cur == -1: + self._log('Running script') + self._cur = 0 + + # Unregister callback if we were in a delay but turn on is called + # again. In that case we just continue execution. + self._async_remove_listener() + + for cur, action in islice(enumerate(self.sequence), self._cur, + None): + + if CONF_DELAY in action: + # Call ourselves in the future to continue work + @asyncio.coroutine + def script_delay(now): + """Called after delay is done.""" + self._async_unsub_delay_listener = None + yield from self.async_run(variables) + + delay = action[CONF_DELAY] + + if isinstance(delay, template.Template): + delay = vol.All( + cv.time_period, + cv.positive_timedelta)( + delay.async_render()) + + self._async_unsub_delay_listener = \ + async_track_point_in_utc_time( self.hass, script_delay, date_util.utcnow() + delay) - self._cur = cur + 1 - if self._change_listener: - self._change_listener() - return + self._cur = cur + 1 + self._trigger_change_listener() + return - elif CONF_CONDITION in action: - if not self._check_condition(action, variables): - break + elif CONF_CONDITION in action: + if not self._async_check_condition(action, variables): + break - elif CONF_EVENT in action: - self._fire_event(action) + elif CONF_EVENT in action: + self._async_fire_event(action) - else: - self._call_service(action, variables) + else: + yield from self._async_call_service(action, variables) - self._cur = -1 - self.last_action = None - if self._change_listener: - self._change_listener() + self._cur = -1 + self.last_action = None + self._trigger_change_listener() def stop(self) -> None: """Stop running script.""" - with self._lock: - if self._cur == -1: - return + run_callback_threadsafe(self.hass.loop, self.async_stop).result() - self._cur = -1 - self._remove_listener() - if self._change_listener: - self._change_listener() + def async_stop(self) -> None: + """Stop running script.""" + if self._cur == -1: + return - def _call_service(self, action, variables): + self._cur = -1 + self._async_remove_listener() + self._trigger_change_listener() + + @asyncio.coroutine + def _async_call_service(self, action, variables): """Call the service specified in the action.""" self.last_action = action.get(CONF_ALIAS, 'call service') self._log("Executing step %s" % self.last_action) - service.call_from_config(self.hass, action, True, variables, - validate_config=False) + yield from service.async_call_from_config( + self.hass, action, True, variables, validate_config=False) - def _fire_event(self, action): + def _async_fire_event(self, action): """Fire an event.""" self.last_action = action.get(CONF_ALIAS, action[CONF_EVENT]) self._log("Executing step %s" % self.last_action) - self.hass.bus.fire(action[CONF_EVENT], action.get(CONF_EVENT_DATA)) + self.hass.bus.async_fire(action[CONF_EVENT], + action.get(CONF_EVENT_DATA)) - def _check_condition(self, action, variables): + def _async_check_condition(self, action, variables): """Test if condition is matching.""" self.last_action = action.get(CONF_ALIAS, action[CONF_CONDITION]) - check = condition.from_config(action, False)(self.hass, variables) + check = condition.async_from_config(action, False)( + self.hass, variables) self._log("Test condition {}: {}".format(self.last_action, check)) return check - def _remove_listener(self): + def _async_remove_listener(self): """Remove point in time listener, if any.""" - if self._unsub_delay_listener: - self._unsub_delay_listener() - self._unsub_delay_listener = None + if self._async_unsub_delay_listener: + self._async_unsub_delay_listener() + self._async_unsub_delay_listener = None def _log(self, msg): """Logger helper.""" @@ -151,3 +165,10 @@ def _log(self, msg): msg = "Script {}: {}".format(self.name, msg) _LOGGER.info(msg) + + def _trigger_change_listener(self): + """Trigger the change listener.""" + if not self._change_listener: + return + + self.hass.async_add_job(self._change_listener) From 16ff68ca84930da572fce6c205438815812449de Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 1 Oct 2016 00:39:07 -0700 Subject: [PATCH 032/112] Add mqtt.async_subscribe --- homeassistant/components/mqtt/__init__.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 01956a85c36f2..86896e8309e34 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -21,6 +21,7 @@ from homeassistant.const import ( EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, CONF_PLATFORM, CONF_SCAN_INTERVAL, CONF_VALUE_TEMPLATE) +from homeassistant.util.async import run_callback_threadsafe _LOGGER = logging.getLogger(__name__) @@ -165,6 +166,18 @@ def publish_template(hass, topic, payload_template, qos=None, retain=None): def subscribe(hass, topic, callback, qos=DEFAULT_QOS): + """Subscribe to an MQTT topic.""" + async_remove = run_callback_threadsafe( + hass.loop, async_subscribe, hass, topic, callback, qos).result() + + def remove_mqtt(): + """Remove MQTT subscription.""" + run_callback_threadsafe(hass.loop, async_remove).result() + + return remove_mqtt + + +def async_subscribe(hass, topic, callback, qos=DEFAULT_QOS): """Subscribe to an MQTT topic.""" @asyncio.coroutine def mqtt_topic_subscriber(event): @@ -181,13 +194,13 @@ def mqtt_topic_subscriber(event): event.data[ATTR_PAYLOAD], event.data[ATTR_QOS], priority=JobPriority.EVENT_CALLBACK) - remove = hass.bus.listen(EVENT_MQTT_MESSAGE_RECEIVED, - mqtt_topic_subscriber) + async_remove = hass.bus.async_listen(EVENT_MQTT_MESSAGE_RECEIVED, + mqtt_topic_subscriber) # Future: track subscriber count and unsubscribe in remove MQTT_CLIENT.subscribe(topic, qos) - return remove + return async_remove def _setup_server(hass, config): From 7ab7edd81c5d4428113528b6e00a105434e24645 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 1 Oct 2016 01:22:13 -0700 Subject: [PATCH 033/112] Make automation async --- .../components/automation/__init__.py | 210 +++++++----------- homeassistant/components/automation/event.py | 4 +- homeassistant/components/automation/mqtt.py | 4 +- .../components/automation/numeric_state.py | 6 +- homeassistant/components/automation/state.py | 9 +- homeassistant/components/automation/sun.py | 8 +- .../components/automation/template.py | 8 +- homeassistant/components/automation/time.py | 8 +- homeassistant/components/automation/zone.py | 8 +- homeassistant/helpers/condition.py | 2 + homeassistant/helpers/entity.py | 9 +- homeassistant/helpers/event.py | 107 +++++---- tests/components/automation/test_init.py | 140 ++---------- .../automation/test_numeric_state.py | 2 +- tests/components/automation/test_state.py | 4 +- tests/components/automation/test_sun.py | 12 +- tests/components/automation/test_template.py | 2 +- tests/components/automation/test_time.py | 8 +- tests/components/automation/test_zone.py | 2 +- 19 files changed, 206 insertions(+), 347 deletions(-) diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index b65516130d989..37102cd386360 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -4,6 +4,7 @@ For more details about this component, please refer to the documentation at https://home-assistant.io/components/automation/ """ +import asyncio from functools import partial import logging import os @@ -23,6 +24,7 @@ from homeassistant.loader import get_platform from homeassistant.util.dt import utcnow import homeassistant.helpers.config_validation as cv +from homeassistant.util.async import run_coroutine_threadsafe DOMAIN = 'automation' ENTITY_ID_FORMAT = DOMAIN + '.{}' @@ -44,9 +46,6 @@ DEFAULT_CONDITION_TYPE = CONDITION_TYPE_AND DEFAULT_HIDE_ENTITY = False -METHOD_TRIGGER = 'trigger' -METHOD_IF_ACTION = 'if_action' - ATTR_LAST_TRIGGERED = 'last_triggered' ATTR_VARIABLES = 'variables' SERVICE_TRIGGER = 'trigger' @@ -55,21 +54,14 @@ _LOGGER = logging.getLogger(__name__) -def _platform_validator(method, schema): - """Generate platform validator for different steps.""" - def validator(config): - """Validate it is a valid platform.""" - platform = get_platform(DOMAIN, config[CONF_PLATFORM]) - - if not hasattr(platform, method): - raise vol.Invalid('invalid method platform') - - if not hasattr(platform, schema): - return config +def _platform_validator(config): + """Validate it is a valid platform.""" + platform = get_platform(DOMAIN, config[CONF_PLATFORM]) - return getattr(platform, schema)(config) + if not hasattr(platform, 'TRIGGER_SCHEMA'): + return config - return validator + return getattr(platform, 'TRIGGER_SCHEMA')(config) _TRIGGER_SCHEMA = vol.All( cv.ensure_list, @@ -78,33 +70,17 @@ def validator(config): vol.Schema({ vol.Required(CONF_PLATFORM): cv.platform_validator(DOMAIN) }, extra=vol.ALLOW_EXTRA), - _platform_validator(METHOD_TRIGGER, 'TRIGGER_SCHEMA') + _platform_validator ), ] ) -_CONDITION_SCHEMA = vol.Any( - CONDITION_USE_TRIGGER_VALUES, - vol.All( - cv.ensure_list, - [ - vol.All( - vol.Schema({ - CONF_PLATFORM: str, - CONF_CONDITION: str, - }, extra=vol.ALLOW_EXTRA), - cv.has_at_least_one_key(CONF_PLATFORM, CONF_CONDITION), - ), - ] - ) -) +_CONDITION_SCHEMA = vol.All(cv.ensure_list, [cv.CONDITION_SCHEMA]) PLATFORM_SCHEMA = vol.Schema({ CONF_ALIAS: cv.string, vol.Optional(CONF_HIDE_ENTITY, default=DEFAULT_HIDE_ENTITY): cv.boolean, vol.Required(CONF_TRIGGER): _TRIGGER_SCHEMA, - vol.Required(CONF_CONDITION_TYPE, default=DEFAULT_CONDITION_TYPE): - vol.All(vol.Lower, vol.Any(CONDITION_TYPE_AND, CONDITION_TYPE_OR)), vol.Optional(CONF_CONDITION): _CONDITION_SCHEMA, vol.Required(CONF_ACTION): cv.SCRIPT_SCHEMA, }) @@ -165,7 +141,8 @@ def setup(hass, config): """Setup the automation.""" component = EntityComponent(_LOGGER, DOMAIN, hass) - success = _process_config(hass, config, component) + success = run_coroutine_threadsafe( + _async_process_config(hass, config, component), hass.loop).result() if not success: return False @@ -173,22 +150,27 @@ def setup(hass, config): descriptions = conf_util.load_yaml_config_file( os.path.join(os.path.dirname(__file__), 'services.yaml')) + @asyncio.coroutine def trigger_service_handler(service_call): """Handle automation triggers.""" for entity in component.extract_from_service(service_call): - entity.trigger(service_call.data.get(ATTR_VARIABLES)) + yield from entity.async_trigger( + service_call.data.get(ATTR_VARIABLES)) + @asyncio.coroutine def service_handler(service_call): """Handle automation service calls.""" + method = 'async_{}'.format(service_call.service) for entity in component.extract_from_service(service_call): - getattr(entity, service_call.service)() + yield from getattr(entity, method)() def reload_service_handler(service_call): """Remove all automations and load new ones from config.""" conf = component.prepare_reload() if conf is None: return - _process_config(hass, conf, component) + run_coroutine_threadsafe( + _async_process_config(hass, conf, component), hass.loop).result() hass.services.register(DOMAIN, SERVICE_TRIGGER, trigger_service_handler, descriptions.get(SERVICE_TRIGGER), @@ -209,14 +191,16 @@ def reload_service_handler(service_call): class AutomationEntity(ToggleEntity): """Entity to show status of entity.""" + # pylint: disable=abstract-method # pylint: disable=too-many-arguments, too-many-instance-attributes - def __init__(self, name, attach_triggers, cond_func, action, hidden): + def __init__(self, name, async_attach_triggers, cond_func, async_action, + hidden): """Initialize an automation entity.""" self._name = name - self._attach_triggers = attach_triggers - self._detach_triggers = attach_triggers(self.trigger) + self._async_attach_triggers = async_attach_triggers + self._async_detach_triggers = async_attach_triggers(self.async_trigger) self._cond_func = cond_func - self._action = action + self._async_action = async_action self._enabled = True self._last_triggered = None self._hidden = hidden @@ -248,39 +232,53 @@ def is_on(self) -> bool: """Return True if entity is on.""" return self._enabled - def turn_on(self, **kwargs) -> None: + @asyncio.coroutine + def async_turn_on(self, **kwargs) -> None: """Turn the entity on.""" if self._enabled: return - self._detach_triggers = self._attach_triggers(self.trigger) + self._async_detach_triggers = self._async_attach_triggers( + self.async_trigger) self._enabled = True - self.update_ha_state() + yield from self.async_update_ha_state() - def turn_off(self, **kwargs) -> None: + @asyncio.coroutine + def async_turn_off(self, **kwargs) -> None: """Turn the entity off.""" if not self._enabled: return - self._detach_triggers() - self._detach_triggers = None + self._async_detach_triggers() + self._async_detach_triggers = None self._enabled = False - self.update_ha_state() + yield from self.async_update_ha_state() + + @asyncio.coroutine + def async_toggle(self): + """Toggle the state of the entity.""" + if self._enabled: + yield from self.async_turn_off() + else: + yield from self.async_turn_on() - def trigger(self, variables): + @asyncio.coroutine + def async_trigger(self, variables): """Trigger automation.""" if self._cond_func(variables): - self._action(variables) + yield from self._async_action(variables) self._last_triggered = utcnow() - self.update_ha_state() + yield from self.async_update_ha_state() def remove(self): """Remove automation from HASS.""" - self.turn_off() + run_coroutine_threadsafe(self.async_turn_off(), + self.hass.loop).result() super().remove() -def _process_config(hass, config, component): +@asyncio.coroutine +def _async_process_config(hass, config, component): """Process config and add automations.""" success = False @@ -293,10 +291,11 @@ def _process_config(hass, config, component): hidden = config_block[CONF_HIDE_ENTITY] - action = _get_action(hass, config_block.get(CONF_ACTION, {}), name) + action = _async_get_action(hass, config_block.get(CONF_ACTION, {}), + name) if CONF_CONDITION in config_block: - cond_func = _process_if(hass, config, config_block) + cond_func = _async_process_if(hass, config, config_block) if cond_func is None: continue @@ -305,101 +304,68 @@ def cond_func(variables): """Condition will always pass.""" return True - attach_triggers = partial(_process_trigger, hass, config, - config_block.get(CONF_TRIGGER, []), name) - entity = AutomationEntity(name, attach_triggers, cond_func, action, - hidden) - component.add_entities((entity,)) + async_attach_triggers = partial( + _async_process_trigger, hass, config, + config_block.get(CONF_TRIGGER, []), name) + entity = AutomationEntity(name, async_attach_triggers, cond_func, + action, hidden) + yield from hass.loop.run_in_executor( + None, component.add_entities, [entity]) success = True return success -def _get_action(hass, config, name): +def _async_get_action(hass, config, name): """Return an action based on a configuration.""" script_obj = script.Script(hass, config, name) + @asyncio.coroutine def action(variables=None): """Action to be executed.""" _LOGGER.info('Executing %s', name) - logbook.log_entry(hass, name, 'has been triggered', DOMAIN) - script_obj.run(variables) + logbook.async_log_entry(hass, name, 'has been triggered', DOMAIN) + yield from script_obj.async_run(variables) return action -def _process_if(hass, config, p_config): +def _async_process_if(hass, config, p_config): """Process if checks.""" - cond_type = p_config.get(CONF_CONDITION_TYPE, - DEFAULT_CONDITION_TYPE).lower() - - # Deprecated since 0.19 - 5/5/2016 - if cond_type != DEFAULT_CONDITION_TYPE: - _LOGGER.warning('Using condition_type: "or" is deprecated. Please use ' - '"condition: or" instead.') - if_configs = p_config.get(CONF_CONDITION) - use_trigger = if_configs == CONDITION_USE_TRIGGER_VALUES - - if use_trigger: - if_configs = p_config[CONF_TRIGGER] checks = [] for if_config in if_configs: - # Deprecated except for used by use_trigger_values - # since 0.19 - 5/5/2016 - if CONF_PLATFORM in if_config: - if not use_trigger: - _LOGGER.warning("Please switch your condition configuration " - "to use 'condition' instead of 'platform'.") - if_config = dict(if_config) - if_config[CONF_CONDITION] = if_config.pop(CONF_PLATFORM) - - # To support use_trigger_values with state trigger accepting - # multiple entity_ids to monitor. - if_entity_id = if_config.get(ATTR_ENTITY_ID) - if isinstance(if_entity_id, list) and len(if_entity_id) == 1: - if_config[ATTR_ENTITY_ID] = if_entity_id[0] - try: - checks.append(condition.from_config(if_config)) + checks.append(condition.async_from_config(if_config, False)) except HomeAssistantError as ex: - # Invalid conditions are allowed if we base it on trigger - if use_trigger: - _LOGGER.warning('Ignoring invalid condition: %s', ex) - else: - _LOGGER.warning('Invalid condition: %s', ex) - return None - - if cond_type == CONDITION_TYPE_AND: - def if_action(variables=None): - """AND all conditions.""" - return all(check(hass, variables) for check in checks) - else: - def if_action(variables=None): - """OR all conditions.""" - return any(check(hass, variables) for check in checks) + _LOGGER.warning('Invalid condition: %s', ex) + return None + + def if_action(variables=None): + """AND all conditions.""" + return all(check(hass, variables) for check in checks) return if_action -def _process_trigger(hass, config, trigger_configs, name, action): +def _async_process_trigger(hass, config, trigger_configs, name, action): """Setup the triggers.""" removes = [] for conf in trigger_configs: - platform = _resolve_platform(METHOD_TRIGGER, hass, config, - conf.get(CONF_PLATFORM)) + platform = prepare_setup_platform(hass, config, DOMAIN, + conf.get(CONF_PLATFORM)) if platform is None: - continue + return None - remove = platform.trigger(hass, conf, action) + remove = platform.async_trigger(hass, conf, action) if not remove: - _LOGGER.error("Error setting up rule %s", name) + _LOGGER.error("Error setting up trigger %s", name) continue - _LOGGER.info("Initialized rule %s", name) + _LOGGER.info("Initialized trigger %s", name) removes.append(remove) if not removes: @@ -411,17 +377,3 @@ def remove_triggers(): remove() return remove_triggers - - -def _resolve_platform(method, hass, config, platform): - """Find the automation platform.""" - if platform is None: - return None - platform = prepare_setup_platform(hass, config, DOMAIN, platform) - - if platform is None or not hasattr(platform, method): - _LOGGER.error("Unknown automation platform specified for %s: %s", - method, platform) - return None - - return platform diff --git a/homeassistant/components/automation/event.py b/homeassistant/components/automation/event.py index 7b77dd046270d..ae0f219a01ad2 100644 --- a/homeassistant/components/automation/event.py +++ b/homeassistant/components/automation/event.py @@ -24,7 +24,7 @@ }) -def trigger(hass, config, action): +def async_trigger(hass, config, action): """Listen for events based on configuration.""" event_type = config.get(CONF_EVENT_TYPE) event_data = config.get(CONF_EVENT_DATA) @@ -41,4 +41,4 @@ def handle_event(event): }, }) - return hass.bus.listen(event_type, handle_event) + return hass.bus.async_listen(event_type, handle_event) diff --git a/homeassistant/components/automation/mqtt.py b/homeassistant/components/automation/mqtt.py index f774991c54761..7897a9bc22135 100644 --- a/homeassistant/components/automation/mqtt.py +++ b/homeassistant/components/automation/mqtt.py @@ -22,7 +22,7 @@ }) -def trigger(hass, config, action): +def async_trigger(hass, config, action): """Listen for state changes based on configuration.""" topic = config.get(CONF_TOPIC) payload = config.get(CONF_PAYLOAD) @@ -40,4 +40,4 @@ def mqtt_automation_listener(msg_topic, msg_payload, qos): } }) - return mqtt.subscribe(hass, topic, mqtt_automation_listener) + return mqtt.async_subscribe(hass, topic, mqtt_automation_listener) diff --git a/homeassistant/components/automation/numeric_state.py b/homeassistant/components/automation/numeric_state.py index 780ab4400b0c2..4d6cdc21190c3 100644 --- a/homeassistant/components/automation/numeric_state.py +++ b/homeassistant/components/automation/numeric_state.py @@ -12,7 +12,7 @@ from homeassistant.const import ( CONF_VALUE_TEMPLATE, CONF_PLATFORM, CONF_ENTITY_ID, CONF_BELOW, CONF_ABOVE) -from homeassistant.helpers.event import track_state_change +from homeassistant.helpers.event import async_track_state_change from homeassistant.helpers import condition, config_validation as cv TRIGGER_SCHEMA = vol.All(vol.Schema({ @@ -26,7 +26,7 @@ _LOGGER = logging.getLogger(__name__) -def trigger(hass, config, action): +def async_trigger(hass, config, action): """Listen for state changes based on configuration.""" entity_id = config.get(CONF_ENTITY_ID) below = config.get(CONF_BELOW) @@ -66,4 +66,4 @@ def state_automation_listener(entity, from_s, to_s): hass.async_add_job(action, variables) - return track_state_change(hass, entity_id, state_automation_listener) + return async_track_state_change(hass, entity_id, state_automation_listener) diff --git a/homeassistant/components/automation/state.py b/homeassistant/components/automation/state.py index dbe7447907082..0649834ff3306 100644 --- a/homeassistant/components/automation/state.py +++ b/homeassistant/components/automation/state.py @@ -12,7 +12,6 @@ from homeassistant.helpers.event import ( async_track_state_change, async_track_point_in_utc_time) import homeassistant.helpers.config_validation as cv -from homeassistant.util.async import run_callback_threadsafe CONF_ENTITY_ID = "entity_id" CONF_FROM = "from" @@ -35,7 +34,7 @@ ) -def trigger(hass, config, action): +def async_trigger(hass, config, action): """Listen for state changes based on configuration.""" entity_id = config.get(CONF_ENTITY_ID) from_state = config.get(CONF_FROM, MATCH_ALL) @@ -98,8 +97,4 @@ def async_remove(): if async_remove_state_for_listener is not None: async_remove_state_for_listener() - def remove(): - """Remove state listeners.""" - run_callback_threadsafe(hass.loop, async_remove).result() - - return remove + return async_remove diff --git a/homeassistant/components/automation/sun.py b/homeassistant/components/automation/sun.py index faa628f572ac5..9892707a13987 100644 --- a/homeassistant/components/automation/sun.py +++ b/homeassistant/components/automation/sun.py @@ -12,7 +12,7 @@ from homeassistant.const import ( CONF_EVENT, CONF_OFFSET, CONF_PLATFORM, SUN_EVENT_SUNRISE) -from homeassistant.helpers.event import track_sunrise, track_sunset +from homeassistant.helpers.event import async_track_sunrise, async_track_sunset import homeassistant.helpers.config_validation as cv DEPENDENCIES = ['sun'] @@ -26,7 +26,7 @@ }) -def trigger(hass, config, action): +def async_trigger(hass, config, action): """Listen for events based on configuration.""" event = config.get(CONF_EVENT) offset = config.get(CONF_OFFSET) @@ -44,6 +44,6 @@ def call_action(): # Do something to call action if event == SUN_EVENT_SUNRISE: - return track_sunrise(hass, call_action, offset) + return async_track_sunrise(hass, call_action, offset) else: - return track_sunset(hass, call_action, offset) + return async_track_sunset(hass, call_action, offset) diff --git a/homeassistant/components/automation/template.py b/homeassistant/components/automation/template.py index 1ca0c6794248d..94f57dbbc02d1 100644 --- a/homeassistant/components/automation/template.py +++ b/homeassistant/components/automation/template.py @@ -11,7 +11,7 @@ from homeassistant.const import CONF_VALUE_TEMPLATE, CONF_PLATFORM from homeassistant.helpers import condition -from homeassistant.helpers.event import track_state_change +from homeassistant.helpers.event import async_track_state_change import homeassistant.helpers.config_validation as cv @@ -23,7 +23,7 @@ }) -def trigger(hass, config, action): +def async_trigger(hass, config, action): """Listen for state changes based on configuration.""" value_template = config.get(CONF_VALUE_TEMPLATE) value_template.hass = hass @@ -51,5 +51,5 @@ def state_changed_listener(entity_id, from_s, to_s): elif not template_result: already_triggered = False - return track_state_change(hass, value_template.extract_entities(), - state_changed_listener) + return async_track_state_change(hass, value_template.extract_entities(), + state_changed_listener) diff --git a/homeassistant/components/automation/time.py b/homeassistant/components/automation/time.py index 91f196eaf3f51..190a651927831 100644 --- a/homeassistant/components/automation/time.py +++ b/homeassistant/components/automation/time.py @@ -11,7 +11,7 @@ from homeassistant.const import CONF_AFTER, CONF_PLATFORM from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.event import track_time_change +from homeassistant.helpers.event import async_track_time_change CONF_HOURS = "hours" CONF_MINUTES = "minutes" @@ -29,7 +29,7 @@ CONF_SECONDS, CONF_AFTER)) -def trigger(hass, config, action): +def async_trigger(hass, config, action): """Listen for state changes based on configuration.""" if CONF_AFTER in config: after = config.get(CONF_AFTER) @@ -49,5 +49,5 @@ def time_automation_listener(now): }, }) - return track_time_change(hass, time_automation_listener, - hour=hours, minute=minutes, second=seconds) + return async_track_time_change(hass, time_automation_listener, + hour=hours, minute=minutes, second=seconds) diff --git a/homeassistant/components/automation/zone.py b/homeassistant/components/automation/zone.py index 971257350e3b1..59812738692fa 100644 --- a/homeassistant/components/automation/zone.py +++ b/homeassistant/components/automation/zone.py @@ -9,7 +9,7 @@ from homeassistant.const import ( CONF_EVENT, CONF_ENTITY_ID, CONF_ZONE, MATCH_ALL, CONF_PLATFORM) -from homeassistant.helpers.event import track_state_change +from homeassistant.helpers.event import async_track_state_change from homeassistant.helpers import ( condition, config_validation as cv, location) @@ -26,7 +26,7 @@ }) -def trigger(hass, config, action): +def async_trigger(hass, config, action): """Listen for state changes based on configuration.""" entity_id = config.get(CONF_ENTITY_ID) zone_entity_id = config.get(CONF_ZONE) @@ -60,5 +60,5 @@ def zone_automation_listener(entity, from_s, to_s): }, }) - return track_state_change(hass, entity_id, zone_automation_listener, - MATCH_ALL, MATCH_ALL) + return async_track_state_change(hass, entity_id, zone_automation_listener, + MATCH_ALL, MATCH_ALL) diff --git a/homeassistant/helpers/condition.py b/homeassistant/helpers/condition.py index ae1dc47170658..bfc637cf9460c 100644 --- a/homeassistant/helpers/condition.py +++ b/homeassistant/helpers/condition.py @@ -1,5 +1,6 @@ """Offer reusable conditions.""" from datetime import timedelta +import functools as ft import logging import sys @@ -30,6 +31,7 @@ def _threaded_factory(async_factory): """Helper method to create threaded versions of async factories.""" + @ft.wraps(async_factory) def factory(config, config_validation=True): """Threaded factory.""" async_check = async_factory(config, config_validation) diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index 3c119eb456eba..99384764b5bf4 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -24,13 +24,20 @@ def generate_entity_id(entity_id_format: str, name: Optional[str], current_ids: Optional[List[str]]=None, hass: Optional[HomeAssistant]=None) -> str: """Generate a unique entity ID based on given entity IDs or used IDs.""" - name = (name or DEVICE_DEFAULT_NAME).lower() if current_ids is None: if hass is None: raise ValueError("Missing required parameter currentids or hass") current_ids = hass.states.entity_ids() + return async_generate_entity_id(entity_id_format, name, current_ids) + + +def async_generate_entity_id(entity_id_format: str, name: Optional[str], + current_ids: Optional[List[str]]=None) -> str: + """Generate a unique entity ID based on given entity IDs or used IDs.""" + name = (name or DEVICE_DEFAULT_NAME).lower() + return ensure_unique_string( entity_id_format.format(slugify(name)), current_ids) diff --git a/homeassistant/helpers/event.py b/homeassistant/helpers/event.py index e27f711afda50..bf781e7e746bf 100644 --- a/homeassistant/helpers/event.py +++ b/homeassistant/helpers/event.py @@ -3,30 +3,36 @@ import functools as ft from datetime import timedelta +from ..core import HomeAssistant from ..const import ( ATTR_NOW, EVENT_STATE_CHANGED, EVENT_TIME_CHANGED, MATCH_ALL) from ..util import dt as dt_util from ..util.async import run_callback_threadsafe +# PyLint does not like the use of _threaded_factory +# pylint: disable=invalid-name -def track_state_change(hass, entity_ids, action, from_state=None, - to_state=None): - """Track specific state changes. - entity_ids, from_state and to_state can be string or list. - Use list to match multiple. +def _threaded_factory(async_factory): + """Convert an async event helper to a threaded one.""" + @ft.wraps(async_factory) + def factory(*args, **kwargs): + """Call async event helper safely.""" + hass = args[0] - Returns a function that can be called to remove the listener. - """ - async_unsub = run_callback_threadsafe( - hass.loop, async_track_state_change, hass, entity_ids, action, - from_state, to_state).result() + if not isinstance(hass, HomeAssistant): + raise TypeError('First parameter needs to be a hass instance') + + async_remove = run_callback_threadsafe( + hass.loop, ft.partial(async_factory, *args, **kwargs)).result() - def remove(): - """Remove listener.""" - run_callback_threadsafe(hass.loop, async_unsub).result() + def remove(): + """Threadsafe removal.""" + run_callback_threadsafe(hass.loop, async_remove).result() - return remove + return remove + + return factory def async_track_state_change(hass, entity_ids, action, from_state=None, @@ -77,7 +83,10 @@ def state_change_listener(event): return hass.bus.async_listen(EVENT_STATE_CHANGED, state_change_listener) -def track_point_in_time(hass, action, point_in_time): +track_state_change = _threaded_factory(async_track_state_change) + + +def async_track_point_in_time(hass, action, point_in_time): """Add a listener that fires once after a spefic point in time.""" utc_point_in_time = dt_util.as_utc(point_in_time) @@ -87,20 +96,11 @@ def utc_converter(utc_now): """Convert passed in UTC now to local now.""" hass.async_add_job(action, dt_util.as_local(utc_now)) - return track_point_in_utc_time(hass, utc_converter, utc_point_in_time) - - -def track_point_in_utc_time(hass, action, point_in_time): - """Add a listener that fires once after a specific point in UTC time.""" - async_unsub = run_callback_threadsafe( - hass.loop, async_track_point_in_utc_time, hass, action, point_in_time - ).result() + return async_track_point_in_utc_time(hass, utc_converter, + utc_point_in_time) - def remove(): - """Remove listener.""" - run_callback_threadsafe(hass.loop, async_unsub).result() - return remove +track_point_in_time = _threaded_factory(async_track_point_in_time) def async_track_point_in_utc_time(hass, action, point_in_time): @@ -133,7 +133,10 @@ def point_in_time_listener(event): return async_unsub -def track_sunrise(hass, action, offset=None): +track_point_in_utc_time = _threaded_factory(async_track_point_in_utc_time) + + +def async_track_sunrise(hass, action, offset=None): """Add a listener that will fire a specified offset from sunrise daily.""" from homeassistant.components import sun offset = offset or timedelta() @@ -147,6 +150,7 @@ def next_rise(): return next_time + @ft.wraps(action) @asyncio.coroutine def sunrise_automation_listener(now): """Called when it's time for action.""" @@ -155,18 +159,20 @@ def sunrise_automation_listener(now): hass, sunrise_automation_listener, next_rise()) hass.async_add_job(action) - remove = run_callback_threadsafe( - hass.loop, async_track_point_in_utc_time, hass, - sunrise_automation_listener, next_rise()).result() + remove = async_track_point_in_utc_time( + hass, sunrise_automation_listener, next_rise()) def remove_listener(): """Remove sunset listener.""" - run_callback_threadsafe(hass.loop, remove).result() + remove() return remove_listener -def track_sunset(hass, action, offset=None): +track_sunrise = _threaded_factory(async_track_sunrise) + + +def async_track_sunset(hass, action, offset=None): """Add a listener that will fire a specified offset from sunset daily.""" from homeassistant.components import sun offset = offset or timedelta() @@ -180,6 +186,7 @@ def next_set(): return next_time + @ft.wraps(action) @asyncio.coroutine def sunset_automation_listener(now): """Called when it's time for action.""" @@ -188,20 +195,23 @@ def sunset_automation_listener(now): hass, sunset_automation_listener, next_set()) hass.async_add_job(action) - remove = run_callback_threadsafe( - hass.loop, async_track_point_in_utc_time, hass, - sunset_automation_listener, next_set()).result() + remove = async_track_point_in_utc_time( + hass, sunset_automation_listener, next_set()) def remove_listener(): """Remove sunset listener.""" - run_callback_threadsafe(hass.loop, remove).result() + remove() return remove_listener +track_sunset = _threaded_factory(async_track_sunset) + + # pylint: disable=too-many-arguments -def track_utc_time_change(hass, action, year=None, month=None, day=None, - hour=None, minute=None, second=None, local=False): +def async_track_utc_time_change(hass, action, year=None, month=None, day=None, + hour=None, minute=None, second=None, + local=False): """Add a listener that will fire if time matches a pattern.""" # We do not have to wrap the function with time pattern matching logic # if no pattern given @@ -211,7 +221,7 @@ def time_change_listener(event): """Fire every time event that comes in.""" action(event.data[ATTR_NOW]) - return hass.bus.listen(EVENT_TIME_CHANGED, time_change_listener) + return hass.bus.async_listen(EVENT_TIME_CHANGED, time_change_listener) pmp = _process_time_match year, month, day = pmp(year), pmp(month), pmp(day) @@ -237,15 +247,22 @@ def pattern_time_change_listener(event): hass.async_add_job(action, now) - return hass.bus.listen(EVENT_TIME_CHANGED, pattern_time_change_listener) + return hass.bus.async_listen(EVENT_TIME_CHANGED, + pattern_time_change_listener) + + +track_utc_time_change = _threaded_factory(async_track_utc_time_change) # pylint: disable=too-many-arguments -def track_time_change(hass, action, year=None, month=None, day=None, - hour=None, minute=None, second=None): +def async_track_time_change(hass, action, year=None, month=None, day=None, + hour=None, minute=None, second=None): """Add a listener that will fire if UTC time matches a pattern.""" - return track_utc_time_change(hass, action, year, month, day, hour, minute, - second, local=True) + return async_track_utc_time_change(hass, action, year, month, day, hour, + minute, second, local=True) + + +track_time_change = _threaded_factory(async_track_time_change) def _process_state_match(parameter): diff --git a/tests/components/automation/test_init.py b/tests/components/automation/test_init.py index cc10b134caff2..b667436d9a6e7 100644 --- a/tests/components/automation/test_init.py +++ b/tests/components/automation/test_init.py @@ -2,7 +2,7 @@ import unittest from unittest.mock import patch -from homeassistant.bootstrap import _setup_component +from homeassistant.bootstrap import setup_component import homeassistant.components.automation as automation from homeassistant.const import ATTR_ENTITY_ID from homeassistant.exceptions import HomeAssistantError @@ -31,7 +31,7 @@ def tearDown(self): # pylint: disable=invalid-name def test_service_data_not_a_dict(self): """Test service data not dict.""" - assert not _setup_component(self.hass, automation.DOMAIN, { + assert not setup_component(self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'event', @@ -46,7 +46,7 @@ def test_service_data_not_a_dict(self): def test_service_specify_data(self): """Test service data.""" - assert _setup_component(self.hass, automation.DOMAIN, { + assert setup_component(self.hass, automation.DOMAIN, { automation.DOMAIN: { 'alias': 'hello', 'trigger': { @@ -77,7 +77,7 @@ def test_service_specify_data(self): def test_service_specify_entity_id(self): """Test service data.""" - assert _setup_component(self.hass, automation.DOMAIN, { + assert setup_component(self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'event', @@ -98,7 +98,7 @@ def test_service_specify_entity_id(self): def test_service_specify_entity_id_list(self): """Test service data.""" - assert _setup_component(self.hass, automation.DOMAIN, { + assert setup_component(self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'event', @@ -119,7 +119,7 @@ def test_service_specify_entity_id_list(self): def test_two_triggers(self): """Test triggers.""" - assert _setup_component(self.hass, automation.DOMAIN, { + assert setup_component(self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': [ { @@ -147,7 +147,7 @@ def test_two_triggers(self): def test_two_conditions_with_and(self): """Test two and conditions.""" entity_id = 'test.entity' - assert _setup_component(self.hass, automation.DOMAIN, { + assert setup_component(self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': [ { @@ -188,123 +188,9 @@ def test_two_conditions_with_and(self): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) - def test_two_conditions_with_or(self): - """Test two or conditions.""" - entity_id = 'test.entity' - assert _setup_component(self.hass, automation.DOMAIN, { - automation.DOMAIN: { - 'trigger': [ - { - 'platform': 'event', - 'event_type': 'test_event', - }, - ], - 'condition_type': 'OR', - 'condition': [ - { - 'platform': 'state', - 'entity_id': entity_id, - 'state': '200' - }, - { - 'platform': 'numeric_state', - 'entity_id': entity_id, - 'below': 150 - } - ], - 'action': { - 'service': 'test.automation', - } - } - }) - - self.hass.states.set(entity_id, 200) - self.hass.bus.fire('test_event') - self.hass.block_till_done() - self.assertEqual(1, len(self.calls)) - - self.hass.states.set(entity_id, 100) - self.hass.bus.fire('test_event') - self.hass.block_till_done() - self.assertEqual(2, len(self.calls)) - - self.hass.states.set(entity_id, 250) - self.hass.bus.fire('test_event') - self.hass.block_till_done() - self.assertEqual(2, len(self.calls)) - - def test_using_trigger_as_condition(self): - """Test triggers as condition.""" - entity_id = 'test.entity' - assert _setup_component(self.hass, automation.DOMAIN, { - automation.DOMAIN: { - 'trigger': [ - { - 'platform': 'state', - 'entity_id': entity_id, - 'from': '120', - 'state': '100' - }, - { - 'platform': 'numeric_state', - 'entity_id': entity_id, - 'below': 150 - } - ], - 'condition': 'use_trigger_values', - 'action': { - 'service': 'test.automation', - } - } - }) - - self.hass.states.set(entity_id, 100) - self.hass.block_till_done() - self.assertEqual(1, len(self.calls)) - - self.hass.states.set(entity_id, 120) - self.hass.block_till_done() - self.assertEqual(1, len(self.calls)) - - self.hass.states.set(entity_id, 100) - self.hass.block_till_done() - self.assertEqual(2, len(self.calls)) - - self.hass.states.set(entity_id, 151) - self.hass.block_till_done() - self.assertEqual(2, len(self.calls)) - - def test_using_trigger_as_condition_with_invalid_condition(self): - """Event is not a valid condition.""" - entity_id = 'test.entity' - self.hass.states.set(entity_id, 100) - assert _setup_component(self.hass, automation.DOMAIN, { - automation.DOMAIN: { - 'trigger': [ - { - 'platform': 'event', - 'event_type': 'test_event', - }, - { - 'platform': 'numeric_state', - 'entity_id': entity_id, - 'below': 150 - } - ], - 'condition': 'use_trigger_values', - 'action': { - 'service': 'test.automation', - } - } - }) - - self.hass.bus.fire('test_event') - self.hass.block_till_done() - self.assertEqual(1, len(self.calls)) - def test_automation_list_setting(self): """Event is not a valid condition.""" - self.assertTrue(_setup_component(self.hass, automation.DOMAIN, { + self.assertTrue(setup_component(self.hass, automation.DOMAIN, { automation.DOMAIN: [{ 'trigger': { 'platform': 'event', @@ -335,7 +221,7 @@ def test_automation_list_setting(self): def test_automation_calling_two_actions(self): """Test if we can call two actions from automation definition.""" - self.assertTrue(_setup_component(self.hass, automation.DOMAIN, { + self.assertTrue(setup_component(self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'event', @@ -366,7 +252,7 @@ def test_services(self): assert self.hass.states.get(entity_id) is None assert not automation.is_on(self.hass, entity_id) - assert _setup_component(self.hass, automation.DOMAIN, { + assert setup_component(self.hass, automation.DOMAIN, { automation.DOMAIN: { 'alias': 'hello', 'trigger': { @@ -433,7 +319,7 @@ def test_services(self): }) def test_reload_config_service(self, mock_load_yaml): """Test the reload config service.""" - assert _setup_component(self.hass, automation.DOMAIN, { + assert setup_component(self.hass, automation.DOMAIN, { automation.DOMAIN: { 'alias': 'hello', 'trigger': { @@ -483,7 +369,7 @@ def test_reload_config_service(self, mock_load_yaml): }) def test_reload_config_when_invalid_config(self, mock_load_yaml): """Test the reload config service handling invalid config.""" - assert _setup_component(self.hass, automation.DOMAIN, { + assert setup_component(self.hass, automation.DOMAIN, { automation.DOMAIN: { 'alias': 'hello', 'trigger': { @@ -517,7 +403,7 @@ def test_reload_config_when_invalid_config(self, mock_load_yaml): def test_reload_config_handles_load_fails(self): """Test the reload config service.""" - assert _setup_component(self.hass, automation.DOMAIN, { + assert setup_component(self.hass, automation.DOMAIN, { automation.DOMAIN: { 'alias': 'hello', 'trigger': { diff --git a/tests/components/automation/test_numeric_state.py b/tests/components/automation/test_numeric_state.py index 01ce5e7c4e6cc..fecd8474763c1 100644 --- a/tests/components/automation/test_numeric_state.py +++ b/tests/components/automation/test_numeric_state.py @@ -499,7 +499,7 @@ def test_if_action(self): 'event_type': 'test_event', }, 'condition': { - 'platform': 'numeric_state', + 'condition': 'numeric_state', 'entity_id': entity_id, 'above': test_state, 'below': test_state + 2 diff --git a/tests/components/automation/test_state.py b/tests/components/automation/test_state.py index 7132bf9e7a268..d6fe56453eea8 100644 --- a/tests/components/automation/test_state.py +++ b/tests/components/automation/test_state.py @@ -213,7 +213,7 @@ def test_if_action(self): 'event_type': 'test_event', }, 'condition': [{ - 'platform': 'state', + 'condition': 'state', 'entity_id': entity_id, 'state': test_state }], @@ -360,7 +360,7 @@ def test_if_fires_on_for_condition(self): 'event_type': 'test_event', }, 'condition': { - 'platform': 'state', + 'condition': 'state', 'entity_id': 'test.entity', 'state': 'on', 'for': { diff --git a/tests/components/automation/test_sun.py b/tests/components/automation/test_sun.py index 8058854aaa906..815c540eb3e28 100644 --- a/tests/components/automation/test_sun.py +++ b/tests/components/automation/test_sun.py @@ -172,7 +172,7 @@ def test_if_action_before(self): 'event_type': 'test_event', }, 'condition': { - 'platform': 'sun', + 'condition': 'sun', 'before': 'sunrise', }, 'action': { @@ -208,7 +208,7 @@ def test_if_action_after(self): 'event_type': 'test_event', }, 'condition': { - 'platform': 'sun', + 'condition': 'sun', 'after': 'sunrise', }, 'action': { @@ -244,7 +244,7 @@ def test_if_action_before_with_offset(self): 'event_type': 'test_event', }, 'condition': { - 'platform': 'sun', + 'condition': 'sun', 'before': 'sunrise', 'before_offset': '+1:00:00' }, @@ -281,7 +281,7 @@ def test_if_action_after_with_offset(self): 'event_type': 'test_event', }, 'condition': { - 'platform': 'sun', + 'condition': 'sun', 'after': 'sunrise', 'after_offset': '+1:00:00' }, @@ -319,7 +319,7 @@ def test_if_action_before_and_after_during(self): 'event_type': 'test_event', }, 'condition': { - 'platform': 'sun', + 'condition': 'sun', 'after': 'sunrise', 'before': 'sunset' }, @@ -365,7 +365,7 @@ def test_if_action_after_different_tz(self): 'event_type': 'test_event', }, 'condition': { - 'platform': 'sun', + 'condition': 'sun', 'after': 'sunset', }, 'action': { diff --git a/tests/components/automation/test_template.py b/tests/components/automation/test_template.py index 327bedb23f20b..1334608ecdbe9 100644 --- a/tests/components/automation/test_template.py +++ b/tests/components/automation/test_template.py @@ -339,7 +339,7 @@ def test_if_action(self): 'event_type': 'test_event', }, 'condition': [{ - 'platform': 'template', + 'condition': 'template', 'value_template': '{{ is_state("test.entity", "world") }}' }], 'action': { diff --git a/tests/components/automation/test_time.py b/tests/components/automation/test_time.py index edc5fb4cdc11f..afdab68146094 100644 --- a/tests/components/automation/test_time.py +++ b/tests/components/automation/test_time.py @@ -250,7 +250,7 @@ def test_if_action_before(self): 'event_type': 'test_event' }, 'condition': { - 'platform': 'time', + 'condition': 'time', 'before': '10:00', }, 'action': { @@ -285,7 +285,7 @@ def test_if_action_after(self): 'event_type': 'test_event' }, 'condition': { - 'platform': 'time', + 'condition': 'time', 'after': '10:00', }, 'action': { @@ -320,7 +320,7 @@ def test_if_action_one_weekday(self): 'event_type': 'test_event' }, 'condition': { - 'platform': 'time', + 'condition': 'time', 'weekday': 'mon', }, 'action': { @@ -356,7 +356,7 @@ def test_if_action_list_weekday(self): 'event_type': 'test_event' }, 'condition': { - 'platform': 'time', + 'condition': 'time', 'weekday': ['mon', 'tue'], }, 'action': { diff --git a/tests/components/automation/test_zone.py b/tests/components/automation/test_zone.py index 8041eceaeb3c1..e454b8b5b8bf5 100644 --- a/tests/components/automation/test_zone.py +++ b/tests/components/automation/test_zone.py @@ -197,7 +197,7 @@ def test_zone_condition(self): 'event_type': 'test_event' }, 'condition': { - 'platform': 'zone', + 'condition': 'zone', 'entity_id': 'test.entity', 'zone': 'zone.test', }, From e18825ba201cf1440fd623efacf476fc24a8a458 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 1 Oct 2016 09:19:20 -0700 Subject: [PATCH 034/112] Automation: only call executor once when processing config --- homeassistant/components/automation/__init__.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index 37102cd386360..76543f6e9a767 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -280,7 +280,7 @@ def remove(self): @asyncio.coroutine def _async_process_config(hass, config, component): """Process config and add automations.""" - success = False + entities = [] for config_key in extract_domain_configs(config, DOMAIN): conf = config[config_key] @@ -307,13 +307,13 @@ def cond_func(variables): async_attach_triggers = partial( _async_process_trigger, hass, config, config_block.get(CONF_TRIGGER, []), name) - entity = AutomationEntity(name, async_attach_triggers, cond_func, - action, hidden) - yield from hass.loop.run_in_executor( - None, component.add_entities, [entity]) - success = True + entities.append(AutomationEntity(name, async_attach_triggers, + cond_func, action, hidden)) - return success + yield from hass.loop.run_in_executor( + None, component.add_entities, entities) + + return len(entities) > 0 def _async_get_action(hass, config, name): From 56fdc2a62586de05c3c4c4089047f6c5b5428875 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 1 Oct 2016 14:11:07 -0700 Subject: [PATCH 035/112] Automation: call prepare_setup_platform in executor --- .../components/automation/__init__.py | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index 76543f6e9a767..3142d759926c7 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -198,10 +198,10 @@ def __init__(self, name, async_attach_triggers, cond_func, async_action, """Initialize an automation entity.""" self._name = name self._async_attach_triggers = async_attach_triggers - self._async_detach_triggers = async_attach_triggers(self.async_trigger) + self._async_detach_triggers = None self._cond_func = cond_func self._async_action = async_action - self._enabled = True + self._enabled = False self._last_triggered = None self._hidden = hidden @@ -234,13 +234,8 @@ def is_on(self) -> bool: @asyncio.coroutine def async_turn_on(self, **kwargs) -> None: - """Turn the entity on.""" - if self._enabled: - return - - self._async_detach_triggers = self._async_attach_triggers( - self.async_trigger) - self._enabled = True + """Turn the entity on and update the state.""" + yield from self.async_enable() yield from self.async_update_ha_state() @asyncio.coroutine @@ -276,6 +271,16 @@ def remove(self): self.hass.loop).result() super().remove() + @asyncio.coroutine + def async_enable(self): + """Enable this automation entity.""" + if self._enabled: + return + + self._async_detach_triggers = yield from self._async_attach_triggers( + self.async_trigger) + self._enabled = True + @asyncio.coroutine def _async_process_config(hass, config, component): @@ -307,8 +312,10 @@ def cond_func(variables): async_attach_triggers = partial( _async_process_trigger, hass, config, config_block.get(CONF_TRIGGER, []), name) - entities.append(AutomationEntity(name, async_attach_triggers, - cond_func, action, hidden)) + entity = AutomationEntity(name, async_attach_triggers, cond_func, + action, hidden) + yield from entity.async_enable() + entities.append(entity) yield from hass.loop.run_in_executor( None, component.add_entities, entities) @@ -349,13 +356,16 @@ def if_action(variables=None): return if_action +@asyncio.coroutine def _async_process_trigger(hass, config, trigger_configs, name, action): """Setup the triggers.""" removes = [] for conf in trigger_configs: - platform = prepare_setup_platform(hass, config, DOMAIN, - conf.get(CONF_PLATFORM)) + platform = yield from hass.loop.run_in_executor( + None, prepare_setup_platform, hass, config, DOMAIN, + conf.get(CONF_PLATFORM)) + if platform is None: return None From 8f3e12c9b867fa435fa9c661b62afe5fa3ab5945 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 1 Oct 2016 15:42:17 -0700 Subject: [PATCH 036/112] Make Automation.reload_service_handler async --- homeassistant/components/automation/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index 3142d759926c7..a677fe1da4e1b 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -164,13 +164,14 @@ def service_handler(service_call): for entity in component.extract_from_service(service_call): yield from getattr(entity, method)() + @asyncio.coroutine def reload_service_handler(service_call): """Remove all automations and load new ones from config.""" - conf = component.prepare_reload() + conf = yield from hass.loop.run_in_executor( + None, component.prepare_reload) if conf is None: return - run_coroutine_threadsafe( - _async_process_config(hass, conf, component), hass.loop).result() + yield from _async_process_config(hass, conf, component) hass.services.register(DOMAIN, SERVICE_TRIGGER, trigger_service_handler, descriptions.get(SERVICE_TRIGGER), From c36d30f4fe11968d889c716690ca4dec7deb2755 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 1 Oct 2016 15:43:33 -0700 Subject: [PATCH 037/112] Typo --- homeassistant/core.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/core.py b/homeassistant/core.py index 2a6372dbf6f1d..43c20f18b75ae 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -122,8 +122,8 @@ class HomeAssistant(object): def __init__(self, loop=None): """Initialize new Home Assistant object.""" self.loop = loop or asyncio.get_event_loop() - self.executer = ThreadPoolExecutor(max_workers=5) - self.loop.set_default_executor(self.executer) + self.executor = ThreadPoolExecutor(max_workers=5) + self.loop.set_default_executor(self.executor) self.pool = pool = create_worker_pool() self.bus = EventBus(pool, self.loop) self.services = ServiceRegistry(self.bus, self.add_job, self.loop) @@ -287,7 +287,7 @@ def async_stop(self) -> None: self.bus.async_fire(EVENT_HOMEASSISTANT_STOP) yield from self.loop.run_in_executor(None, self.pool.block_till_done) yield from self.loop.run_in_executor(None, self.pool.stop) - self.executer.shutdown() + self.executor.shutdown() self.state = CoreState.not_running self.loop.stop() From 1f38e9fa571906e44534c0f58a086bf15b1f6e4c Mon Sep 17 00:00:00 2001 From: William Scanlon Date: Sat, 1 Oct 2016 23:45:39 -0400 Subject: [PATCH 038/112] Support for wink oath2 and relay sensors (#3496) --- .../components/binary_sensor/wink.py | 19 +++++--- homeassistant/components/sensor/wink.py | 4 +- homeassistant/components/wink.py | 46 +++++++++++++++++-- requirements_all.txt | 2 +- 4 files changed, 57 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/binary_sensor/wink.py b/homeassistant/components/binary_sensor/wink.py index 636a5747ed52a..736643fd8dfbd 100644 --- a/homeassistant/components/binary_sensor/wink.py +++ b/homeassistant/components/binary_sensor/wink.py @@ -20,7 +20,8 @@ "vibration": "vibration", "loudness": "sound", "liquid_detected": "moisture", - "motion": "motion" + "motion": "motion", + "presence": "occupancy" } @@ -58,17 +59,21 @@ def _pubnub_update(self, message, channel): def is_on(self): """Return true if the binary sensor is on.""" if self.capability == "loudness": - return self.wink.loudness_boolean() + state = self.wink.loudness_boolean() elif self.capability == "vibration": - return self.wink.vibration_boolean() + state = self.wink.vibration_boolean() elif self.capability == "brightness": - return self.wink.brightness_boolean() + state = self.wink.brightness_boolean() elif self.capability == "liquid_detected": - return self.wink.liquid_boolean() + state = self.wink.liquid_boolean() elif self.capability == "motion": - return self.wink.motion_boolean() + state = self.wink.motion_boolean() + elif self.capability == "presence": + state = self.wink.presence_boolean() else: - return self.wink.state() + state = self.wink.state() + + return state @property def sensor_class(self): diff --git a/homeassistant/components/sensor/wink.py b/homeassistant/components/sensor/wink.py index 92ee3aa25428e..8ba2e09c6c98b 100644 --- a/homeassistant/components/sensor/wink.py +++ b/homeassistant/components/sensor/wink.py @@ -14,7 +14,7 @@ DEPENDENCIES = ['wink'] -SENSOR_TYPES = ['temperature', 'humidity', 'balance'] +SENSOR_TYPES = ['temperature', 'humidity', 'balance', 'proximity'] def setup_platform(hass, config, add_devices, discovery_info=None): @@ -58,6 +58,8 @@ def state(self): return round(self.wink.temperature_float(), 1) elif self.capability == "balance": return round(self.wink.balance() / 100, 2) + elif self.capability == "proximity": + return self.wink.proximity_float() else: return STATE_OPEN if self.is_open else STATE_CLOSED diff --git a/homeassistant/components/wink.py b/homeassistant/components/wink.py index 4aa05d3d5e878..d4ce99e646312 100644 --- a/homeassistant/components/wink.py +++ b/homeassistant/components/wink.py @@ -10,11 +10,12 @@ import voluptuous as vol from homeassistant.helpers import discovery -from homeassistant.const import CONF_ACCESS_TOKEN, ATTR_BATTERY_LEVEL +from homeassistant.const import CONF_ACCESS_TOKEN, ATTR_BATTERY_LEVEL, \ + CONF_EMAIL, CONF_PASSWORD from homeassistant.helpers.entity import Entity import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['python-wink==0.7.15', 'pubnub==3.8.2'] +REQUIREMENTS = ['python-wink==0.8.0', 'pubnub==3.8.2'] _LOGGER = logging.getLogger(__name__) @@ -23,19 +24,54 @@ DOMAIN = 'wink' SUBSCRIPTION_HANDLER = None +CONF_CLIENT_ID = 'client_id' +CONF_CLIENT_SECRET = 'client_secret' +CONF_USER_AGENT = 'user_agent' +CONF_OATH = 'oath' +CONF_DEFINED_BOTH_MSG = 'Remove access token to use oath2.' +CONF_MISSING_OATH_MSG = 'Missing oath2 credentials.' CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ - vol.Required(CONF_ACCESS_TOKEN): cv.string, - }), + vol.Inclusive(CONF_EMAIL, CONF_OATH, + msg=CONF_MISSING_OATH_MSG): cv.string, + vol.Inclusive(CONF_PASSWORD, CONF_OATH, + msg=CONF_MISSING_OATH_MSG): cv.string, + vol.Inclusive(CONF_CLIENT_ID, CONF_OATH, + msg=CONF_MISSING_OATH_MSG): cv.string, + vol.Inclusive(CONF_CLIENT_SECRET, CONF_OATH, + msg=CONF_MISSING_OATH_MSG): cv.string, + vol.Exclusive(CONF_EMAIL, CONF_OATH, + msg=CONF_DEFINED_BOTH_MSG): cv.string, + vol.Exclusive(CONF_ACCESS_TOKEN, CONF_OATH, + msg=CONF_DEFINED_BOTH_MSG): cv.string, + vol.Optional(CONF_USER_AGENT, default=None): cv.string + }) }, extra=vol.ALLOW_EXTRA) def setup(hass, config): """Setup the Wink component.""" import pywink + + user_agent = config[DOMAIN][CONF_USER_AGENT] + + if user_agent: + pywink.set_user_agent(user_agent) + from pubnub import Pubnub - pywink.set_bearer_token(config[DOMAIN][CONF_ACCESS_TOKEN]) + access_token = config[DOMAIN].get(CONF_ACCESS_TOKEN) + + if access_token: + pywink.set_bearer_token(access_token) + else: + email = config[DOMAIN][CONF_EMAIL] + password = config[DOMAIN][CONF_PASSWORD] + client_id = config[DOMAIN]['client_id'] + client_secret = config[DOMAIN]['client_secret'] + pywink.set_wink_credentials(email, password, client_id, + client_secret) + global SUBSCRIPTION_HANDLER SUBSCRIPTION_HANDLER = Pubnub( 'N/A', pywink.get_subscription_key(), ssl_on=True) diff --git a/requirements_all.txt b/requirements_all.txt index 21e387ab0085c..dfa8eb2d86b9e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -396,7 +396,7 @@ python-telegram-bot==5.1.0 python-twitch==1.3.0 # homeassistant.components.wink -python-wink==0.7.15 +python-wink==0.8.0 # homeassistant.components.keyboard # pyuserinput==0.1.11 From 9da2d6edd00962467f6ad8ad0b2589a231ff6d15 Mon Sep 17 00:00:00 2001 From: Klaas Hoekema Date: Sun, 2 Oct 2016 00:18:10 -0400 Subject: [PATCH 039/112] Make forecast.io update interval configurable (#3520) Adds a config parameter (`update_interval`) to the `forecast` sensor to set the minimum update interval. The default remains 120 seconds. --- homeassistant/components/sensor/forecast.py | 39 ++++++++++++--------- tests/components/sensor/test_forecast.py | 4 ++- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/homeassistant/components/sensor/forecast.py b/homeassistant/components/sensor/forecast.py index b9a3f9f644752..e0beb65c04567 100644 --- a/homeassistant/components/sensor/forecast.py +++ b/homeassistant/components/sensor/forecast.py @@ -23,11 +23,10 @@ _LOGGER = logging.getLogger(__name__) CONF_UNITS = 'units' +CONF_UPDATE_INTERVAL = 'update_interval' DEFAULT_NAME = 'Forecast.io' -MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=120) - # Sensor types are defined like so: # Name, si unit, us unit, ca unit, uk unit, uk2 unit SENSOR_TYPES = { @@ -84,10 +83,13 @@ vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]), vol.Required(CONF_API_KEY): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, - vol.Optional(CONF_UNITS): vol.In(['auto', 'si', 'us', 'ca', 'uk', 'uk2']) + vol.Optional(CONF_UNITS): vol.In(['auto', 'si', 'us', 'ca', 'uk', 'uk2']), + vol.Optional(CONF_UPDATE_INTERVAL, default=timedelta(seconds=120)): ( + vol.All(cv.time_period, cv.positive_timedelta)), }) +# pylint: disable=too-many-arguments def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the Forecast.io sensor.""" # Validate the configuration @@ -106,8 +108,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None): # the first call to init the data and confirm we can connect. try: forecast_data = ForeCastData( - config.get(CONF_API_KEY, None), hass.config.latitude, - hass.config.longitude, units) + api_key=config.get(CONF_API_KEY, None), + latitude=hass.config.latitude, + longitude=hass.config.longitude, + units=units, + interval=config.get(CONF_UPDATE_INTERVAL)) forecast_data.update_currently() except ValueError as error: _LOGGER.error(error) @@ -247,7 +252,7 @@ class ForeCastData(object): # pylint: disable=too-many-instance-attributes - def __init__(self, api_key, latitude, longitude, units): + def __init__(self, api_key, latitude, longitude, units, interval): """Initialize the data object.""" self._api_key = api_key self.latitude = latitude @@ -261,10 +266,16 @@ def __init__(self, api_key, latitude, longitude, units): self.data_hourly = None self.data_daily = None + # Apply throttling to methods using configured interval + self.update = Throttle(interval)(self._update) + self.update_currently = Throttle(interval)(self._update_currently) + self.update_minutely = Throttle(interval)(self._update_minutely) + self.update_hourly = Throttle(interval)(self._update_hourly) + self.update_daily = Throttle(interval)(self._update_daily) + self.update() - @Throttle(MIN_TIME_BETWEEN_UPDATES) - def update(self): + def _update(self): """Get the latest data from Forecast.io.""" import forecastio @@ -275,22 +286,18 @@ def update(self): raise ValueError("Unable to init Forecast.io. - %s", error) self.unit_system = self.data.json['flags']['units'] - @Throttle(MIN_TIME_BETWEEN_UPDATES) - def update_currently(self): + def _update_currently(self): """Update currently data.""" self.data_currently = self.data.currently() - @Throttle(MIN_TIME_BETWEEN_UPDATES) - def update_minutely(self): + def _update_minutely(self): """Update minutely data.""" self.data_minutely = self.data.minutely() - @Throttle(MIN_TIME_BETWEEN_UPDATES) - def update_hourly(self): + def _update_hourly(self): """Update hourly data.""" self.data_hourly = self.data.hourly() - @Throttle(MIN_TIME_BETWEEN_UPDATES) - def update_daily(self): + def _update_daily(self): """Update daily data.""" self.data_daily = self.data.daily() diff --git a/tests/components/sensor/test_forecast.py b/tests/components/sensor/test_forecast.py index af88eec6b94d2..f11a0ebccbec8 100644 --- a/tests/components/sensor/test_forecast.py +++ b/tests/components/sensor/test_forecast.py @@ -6,6 +6,7 @@ import forecastio from requests.exceptions import HTTPError import requests_mock +from datetime import timedelta from homeassistant.components.sensor import forecast @@ -21,7 +22,8 @@ def setUp(self): self.key = 'foo' self.config = { 'api_key': 'foo', - 'monitored_conditions': ['summary', 'icon'] + 'monitored_conditions': ['summary', 'icon'], + 'update_interval': timedelta(seconds=120), } self.lat = 37.8267 self.lon = -122.423 From a61e08680a632588e2ee9ae48f7438adcf524fe5 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sun, 2 Oct 2016 06:20:16 +0200 Subject: [PATCH 040/112] Add persistent notification for failed login attempts (#3528) --- homeassistant/components/http.py | 36 ++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/homeassistant/components/http.py b/homeassistant/components/http.py index c3a8ccd85f660..73c8079023f7a 100644 --- a/homeassistant/components/http.py +++ b/homeassistant/components/http.py @@ -11,18 +11,20 @@ import threading import re import ssl + import voluptuous as vol import homeassistant.remote as rem from homeassistant import util from homeassistant.const import ( SERVER_PORT, HTTP_HEADER_HA_AUTH, HTTP_HEADER_CACHE_CONTROL, - HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, + HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, CONTENT_TYPE_JSON, HTTP_HEADER_ACCESS_CONTROL_ALLOW_HEADERS, ALLOWED_CORS_HEADERS, EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_START) from homeassistant.core import split_entity_id import homeassistant.util.dt as dt_util import homeassistant.helpers.config_validation as cv +from homeassistant.components import persistent_notification DOMAIN = 'http' REQUIREMENTS = ('cherrypy==8.1.0', 'static3==0.7.0', 'Werkzeug==0.11.11') @@ -37,6 +39,7 @@ CONF_CORS_ORIGINS = 'cors_allowed_origins' DATA_API_PASSWORD = 'api_password' +NOTIFICATION_ID_LOGIN = 'http-login' # TLS configuation follows the best-practice guidelines specified here: # https://wiki.mozilla.org/Security/Server_Side_TLS @@ -106,7 +109,7 @@ def setup(hass, config): api_password = util.convert(conf.get(CONF_API_PASSWORD), str) server_host = conf.get(CONF_SERVER_HOST, '0.0.0.0') server_port = conf.get(CONF_SERVER_PORT, SERVER_PORT) - development = str(conf.get(CONF_DEVELOPMENT, "")) == "1" + development = str(conf.get(CONF_DEVELOPMENT, '')) == '1' ssl_certificate = conf.get(CONF_SSL_CERTIFICATE) ssl_key = conf.get(CONF_SSL_KEY) cors_origins = conf.get(CONF_CORS_ORIGINS, []) @@ -365,8 +368,8 @@ def __init__(self, context): context.load_cert_chain(self.ssl_certificate, self.ssl_key) self.server.ssl_adapter = ContextSSLAdapter(context) - threading.Thread(target=self.server.start, daemon=True, - name='WSGI-server').start() + threading.Thread( + target=self.server.start, daemon=True, name='WSGI-server').start() def stop(self): """Stop the wsgi server.""" @@ -391,10 +394,10 @@ def dispatch_request(self, request): resp = ex.get_response(request.environ) if request.accept_mimetypes.accept_json: resp.data = json.dumps({ - "result": "error", - "message": str(ex), + 'result': 'error', + 'message': str(ex), }) - resp.mimetype = "application/json" + resp.mimetype = CONTENT_TYPE_JSON return resp def base_app(self, environ, start_response): @@ -403,11 +406,11 @@ def base_app(self, environ, start_response): response = self.dispatch_request(request) if self.cors_origins: - cors_check = (environ.get("HTTP_ORIGIN") in self.cors_origins) + cors_check = (environ.get('HTTP_ORIGIN') in self.cors_origins) cors_headers = ", ".join(ALLOWED_CORS_HEADERS) if cors_check: response.headers[HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN] = \ - environ.get("HTTP_ORIGIN") + environ.get('HTTP_ORIGIN') response.headers[HTTP_HEADER_ACCESS_CONTROL_ALLOW_HEADERS] = \ cors_headers @@ -425,7 +428,7 @@ def __call__(self, environ, start_response): # Strip out any cachebusting MD5 fingerprints fingerprinted = _FINGERPRINT.match(environ.get('PATH_INFO', '')) if fingerprinted: - environ['PATH_INFO'] = "{}.{}".format(*fingerprinted.groups()) + environ['PATH_INFO'] = '{}.{}'.format(*fingerprinted.groups()) return app(environ, start_response) @@ -489,6 +492,10 @@ def handle_request(self, request, **values): if self.requires_auth and not authenticated: _LOGGER.warning('Login attempt or request with an invalid ' 'password from %s', request.remote_addr) + persistent_notification.create( + self.hass, + 'Invalid password used from {}'.format(request.remote_addr), + 'Login attempt failed', NOTIFICATION_ID_LOGIN) raise Unauthorized() request.authenticated = authenticated @@ -512,12 +519,9 @@ def handle_request(self, request, **values): def json(self, result, status_code=200): """Return a JSON response.""" msg = json.dumps( - result, - sort_keys=True, - cls=rem.JSONEncoder - ).encode('UTF-8') - return self.Response(msg, mimetype="application/json", - status=status_code) + result, sort_keys=True, cls=rem.JSONEncoder).encode('UTF-8') + return self.Response( + msg, mimetype=CONTENT_TYPE_JSON, status=status_code) def json_message(self, error, status_code=200): """Return a JSON message response.""" From 9683e3e3ad46dadd50f350adbe950343f42898f1 Mon Sep 17 00:00:00 2001 From: Lewis Juggins Date: Sun, 2 Oct 2016 05:56:45 +0100 Subject: [PATCH 041/112] Correctly define requirements for emulated hue (#3535) --- homeassistant/components/emulated_hue.py | 2 ++ requirements_all.txt | 3 +++ 2 files changed, 5 insertions(+) diff --git a/homeassistant/components/emulated_hue.py b/homeassistant/components/emulated_hue.py index 3c7f81b2ed991..88a5ff58fe5e6 100644 --- a/homeassistant/components/emulated_hue.py +++ b/homeassistant/components/emulated_hue.py @@ -25,6 +25,8 @@ from homeassistant.components.http import ( HomeAssistantView, HomeAssistantWSGI ) +# pylint: disable=unused-import +from homeassistant.components.http import REQUIREMENTS # noqa import homeassistant.helpers.config_validation as cv DOMAIN = 'emulated_hue' diff --git a/requirements_all.txt b/requirements_all.txt index dfa8eb2d86b9e..8009a244828e0 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -28,6 +28,7 @@ SoCo==0.11.1 # homeassistant.components.notify.twitter TwitterAPI==2.4.2 +# homeassistant.components.emulated_hue # homeassistant.components.http Werkzeug==0.11.11 @@ -55,6 +56,7 @@ blockchain==1.3.3 # homeassistant.components.notify.aws_sqs boto3==1.3.1 +# homeassistant.components.emulated_hue # homeassistant.components.http cherrypy==8.1.0 @@ -452,6 +454,7 @@ speedtest-cli==0.3.4 # homeassistant.scripts.db_migrator sqlalchemy==1.0.15 +# homeassistant.components.emulated_hue # homeassistant.components.http static3==0.7.0 From c189c05676b2881eac998069e1890caf794c33bd Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Sun, 2 Oct 2016 07:15:19 +0200 Subject: [PATCH 042/112] Add temp convert to climate base object (#3611) * Add temp convert to climate base object * fix nest * fix lint --- homeassistant/components/climate/__init__.py | 11 +++++++++-- homeassistant/components/climate/nest.py | 10 +++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/climate/__init__.py b/homeassistant/components/climate/__init__.py index 726ed4f674cf0..f670cbc45e144 100644 --- a/homeassistant/components/climate/__init__.py +++ b/homeassistant/components/climate/__init__.py @@ -235,10 +235,17 @@ def aux_heat_set_service(service): def temperature_set_service(service): """Set temperature on the target climate devices.""" target_climate = component.extract_from_service(service) - kwargs = service.data + for climate in target_climate: - climate.set_temperature(**kwargs) + kwargs = {} + for value, temp in service.data.items(): + kwargs[value] = convert_temperature( + temp, + hass.config.units.temperature_unit, + climate.unit_of_measurement + ) + climate.set_temperature(**kwargs) if climate.should_poll: climate.update_ha_state(True) diff --git a/homeassistant/components/climate/nest.py b/homeassistant/components/climate/nest.py index 2884f4d2eb2aa..36be2ca25f5b9 100644 --- a/homeassistant/components/climate/nest.py +++ b/homeassistant/components/climate/nest.py @@ -13,7 +13,6 @@ ATTR_TEMPERATURE) from homeassistant.const import ( TEMP_CELSIUS, CONF_SCAN_INTERVAL, STATE_ON, STATE_OFF, STATE_UNKNOWN) -from homeassistant.util.temperature import convert as convert_temperature DEPENDENCIES = ['nest'] _LOGGER = logging.getLogger(__name__) @@ -127,12 +126,9 @@ def is_away_mode_on(self): def set_temperature(self, **kwargs): """Set new target temperature.""" - if kwargs.get(ATTR_TARGET_TEMP_LOW) is not None and \ - kwargs.get(ATTR_TARGET_TEMP_HIGH) is not None: - target_temp_high = convert_temperature(kwargs.get( - ATTR_TARGET_TEMP_HIGH), self._unit, TEMP_CELSIUS) - target_temp_low = convert_temperature(kwargs.get( - ATTR_TARGET_TEMP_LOW), self._unit, TEMP_CELSIUS) + target_temp_low = kwargs.get(ATTR_TARGET_TEMP_LOW) + target_temp_high = kwargs.get(ATTR_TARGET_TEMP_HIGH) + if target_temp_low is not None and target_temp_high is not None: if self.device.mode == 'range': temp = (target_temp_low, target_temp_high) From 646eaccd4d569b3a057f84d7fec7ec270dbc6ad8 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Sat, 1 Oct 2016 22:19:17 -0700 Subject: [PATCH 043/112] =?UTF-8?q?Update=20notify=20to=20expect=20a=20lis?= =?UTF-8?q?t=20of=20string=20targets=20instead=20of=20a=20single=20?= =?UTF-8?q?=E2=80=A6=20(#3548)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update notify to expect a list of string targets instead of a single string * Actually do the thing I set out to do * Fix notify.group test to expect an array of targets * REST platform will only use the first target in the list * Update notify platforms to expect a list of targets * Update notify services.yaml --- homeassistant/components/notify/__init__.py | 2 +- homeassistant/components/notify/aws_lambda.py | 3 --- homeassistant/components/notify/aws_sns.py | 3 --- homeassistant/components/notify/aws_sqs.py | 3 --- homeassistant/components/notify/html5.py | 2 -- .../components/notify/message_bird.py | 3 --- homeassistant/components/notify/pushbullet.py | 4 --- homeassistant/components/notify/pushover.py | 22 ++++++++-------- homeassistant/components/notify/rest.py | 6 +++-- homeassistant/components/notify/services.yaml | 4 +-- homeassistant/components/notify/slack.py | 25 +++++++++++-------- homeassistant/components/notify/twilio_sms.py | 3 --- tests/components/notify/test_group.py | 2 +- 13 files changed, 34 insertions(+), 48 deletions(-) diff --git a/homeassistant/components/notify/__init__.py b/homeassistant/components/notify/__init__.py index 5bd99678f8032..e56dfa5586dc1 100644 --- a/homeassistant/components/notify/__init__.py +++ b/homeassistant/components/notify/__init__.py @@ -42,7 +42,7 @@ NOTIFY_SERVICE_SCHEMA = vol.Schema({ vol.Required(ATTR_MESSAGE): cv.template, vol.Optional(ATTR_TITLE): cv.template, - vol.Optional(ATTR_TARGET): cv.string, + vol.Optional(ATTR_TARGET): vol.All(cv.ensure_list, [cv.string]), vol.Optional(ATTR_DATA): dict, }) diff --git a/homeassistant/components/notify/aws_lambda.py b/homeassistant/components/notify/aws_lambda.py index 3e3003763eaaf..9ac9c4cbc18c0 100644 --- a/homeassistant/components/notify/aws_lambda.py +++ b/homeassistant/components/notify/aws_lambda.py @@ -79,9 +79,6 @@ def send_message(self, message="", **kwargs): _LOGGER.info("At least 1 target is required") return - if not isinstance(targets, list): - targets = [targets] - for target in targets: cleaned_kwargs = dict((k, v) for k, v in kwargs.items() if v) payload = {"message": message} diff --git a/homeassistant/components/notify/aws_sns.py b/homeassistant/components/notify/aws_sns.py index 88233234ecafa..fb6ae8984c694 100644 --- a/homeassistant/components/notify/aws_sns.py +++ b/homeassistant/components/notify/aws_sns.py @@ -70,9 +70,6 @@ def send_message(self, message="", **kwargs): _LOGGER.info("At least 1 target is required") return - if not isinstance(targets, list): - targets = [targets] - message_attributes = {k: {"StringValue": json.dumps(v), "DataType": "String"} for k, v in kwargs.items() if v} diff --git a/homeassistant/components/notify/aws_sqs.py b/homeassistant/components/notify/aws_sqs.py index a1ddbcea3dd00..edd8c4bec690f 100644 --- a/homeassistant/components/notify/aws_sqs.py +++ b/homeassistant/components/notify/aws_sqs.py @@ -69,9 +69,6 @@ def send_message(self, message="", **kwargs): _LOGGER.info("At least 1 target is required") return - if not isinstance(targets, list): - targets = [targets] - for target in targets: cleaned_kwargs = dict((k, v) for k, v in kwargs.items() if v) message_body = {"message": message} diff --git a/homeassistant/components/notify/html5.py b/homeassistant/components/notify/html5.py index 0cf7028351b9b..a868552d051a1 100644 --- a/homeassistant/components/notify/html5.py +++ b/homeassistant/components/notify/html5.py @@ -359,8 +359,6 @@ def send_message(self, message="", **kwargs): if not targets: targets = self.registrations.keys() - elif not isinstance(targets, list): - targets = [targets] for target in targets: info = self.registrations.get(target) diff --git a/homeassistant/components/notify/message_bird.py b/homeassistant/components/notify/message_bird.py index 3a2770a65b59b..5e7cc9eaf176a 100644 --- a/homeassistant/components/notify/message_bird.py +++ b/homeassistant/components/notify/message_bird.py @@ -58,9 +58,6 @@ def send_message(self, message=None, **kwargs): _LOGGER.error('No target specified.') return - if not isinstance(targets, list): - targets = [targets] - for target in targets: try: self.client.message_create(self.sender, diff --git a/homeassistant/components/notify/pushbullet.py b/homeassistant/components/notify/pushbullet.py index d54025485085d..71b3f227e9bfc 100644 --- a/homeassistant/components/notify/pushbullet.py +++ b/homeassistant/components/notify/pushbullet.py @@ -87,10 +87,6 @@ def send_message(self, message=None, **kwargs): _LOGGER.info('Sent notification to self') return - # Make list if not so - if not isinstance(targets, list): - targets = [targets] - # Main loop, Process all targets specified for target in targets: try: diff --git a/homeassistant/components/notify/pushover.py b/homeassistant/components/notify/pushover.py index c0a067fe91864..bd7542c21cd0f 100644 --- a/homeassistant/components/notify/pushover.py +++ b/homeassistant/components/notify/pushover.py @@ -61,13 +61,15 @@ def send_message(self, message='', **kwargs): data['title'] = kwargs.get(ATTR_TITLE, ATTR_TITLE_DEFAULT) - target = kwargs.get(ATTR_TARGET) - if target is not None: - data['device'] = target - - try: - self.pushover.send_message(message, **data) - except ValueError as val_err: - _LOGGER.error(str(val_err)) - except RequestError: - _LOGGER.exception('Could not send pushover notification') + targets = kwargs.get(ATTR_TARGET) + + for target in targets: + if target is not None: + data['device'] = target + + try: + self.pushover.send_message(message, **data) + except ValueError as val_err: + _LOGGER.error(str(val_err)) + except RequestError: + _LOGGER.exception('Could not send pushover notification') diff --git a/homeassistant/components/notify/rest.py b/homeassistant/components/notify/rest.py index 0a82b8d5d724c..a7d31593ce3c8 100644 --- a/homeassistant/components/notify/rest.py +++ b/homeassistant/components/notify/rest.py @@ -75,8 +75,10 @@ def send_message(self, message="", **kwargs): data[self._title_param_name] = kwargs.get(ATTR_TITLE, ATTR_TITLE_DEFAULT) - if self._target_param_name is not None: - data[self._target_param_name] = kwargs.get(ATTR_TARGET) + if self._target_param_name is not None and ATTR_TARGET in kwargs: + # Target is a list as of 0.29 and we don't want to break existing + # integrations, so just return the first target in the list. + data[self._target_param_name] = kwargs[ATTR_TARGET][0] if self._method == 'POST': response = requests.post(self._resource, data=data, timeout=10) diff --git a/homeassistant/components/notify/services.yaml b/homeassistant/components/notify/services.yaml index 419a796199afe..a3980f658ead0 100644 --- a/homeassistant/components/notify/services.yaml +++ b/homeassistant/components/notify/services.yaml @@ -11,9 +11,9 @@ notify: example: 'Your Garage Door Friend' target: - description: Target of the notification. Optional depending on the platform + description: An array of targets to send the notification to. Optional depending on the platform. example: platform specific data: - description: Extended information for notification. Optional depending on the platform + description: Extended information for notification. Optional depending on the platform. example: platform specific diff --git a/homeassistant/components/notify/slack.py b/homeassistant/components/notify/slack.py index aded8cd56a94c..75ebb9b26fee9 100644 --- a/homeassistant/components/notify/slack.py +++ b/homeassistant/components/notify/slack.py @@ -9,7 +9,7 @@ import voluptuous as vol from homeassistant.components.notify import ( - PLATFORM_SCHEMA, BaseNotificationService) + ATTR_TARGET, PLATFORM_SCHEMA, BaseNotificationService) from homeassistant.const import ( CONF_API_KEY, CONF_USERNAME, CONF_ICON) import homeassistant.helpers.config_validation as cv @@ -68,16 +68,19 @@ def send_message(self, message="", **kwargs): """Send a message to a user.""" import slacker - channel = kwargs.get('target') or self._default_channel + targets = kwargs.get(ATTR_TARGET, [self._default_channel]) + data = kwargs.get('data') attachments = data.get('attachments') if data else None - try: - self.slack.chat.post_message(channel, message, - as_user=self._as_user, - username=self._username, - icon_emoji=self._icon, - attachments=attachments, - link_names=True) - except slacker.Error as err: - _LOGGER.error("Could not send slack notification. Error: %s", err) + for target in targets: + try: + self.slack.chat.post_message(target, message, + as_user=self._as_user, + username=self._username, + icon_emoji=self._icon, + attachments=attachments, + link_names=True) + except slacker.Error as err: + _LOGGER.error("Could not send slack notification. Error: %s", + err) diff --git a/homeassistant/components/notify/twilio_sms.py b/homeassistant/components/notify/twilio_sms.py index 8e59cf6d20cd4..d7e78ac7d1a77 100644 --- a/homeassistant/components/notify/twilio_sms.py +++ b/homeassistant/components/notify/twilio_sms.py @@ -57,9 +57,6 @@ def send_message(self, message="", **kwargs): _LOGGER.info("At least 1 target is required") return - if not isinstance(targets, list): - targets = [targets] - for target in targets: self.client.messages.create(to=target, body=message, from_=self.from_number) diff --git a/tests/components/notify/test_group.py b/tests/components/notify/test_group.py index f1289a3dec130..e1c6d9f5bd405 100644 --- a/tests/components/notify/test_group.py +++ b/tests/components/notify/test_group.py @@ -74,7 +74,7 @@ def test_entity_data_passes_through(self): data = self.events[-1].data assert { 'message': 'Hello', - 'target': 'unnamed device', + 'target': ['unnamed device'], 'title': 'Test notification', 'data': {'hello': 'world', 'test': 'message'} } == data From 183936375f6b1cf03ccff4481ca9bb05563254bc Mon Sep 17 00:00:00 2001 From: Simon Szustkowski Date: Sun, 2 Oct 2016 07:29:06 +0200 Subject: [PATCH 044/112] Add a Timeout for InfluxDB connections (#3563) * Add a Timeout for InfluxDB connections * Removed trailing whitespace --- homeassistant/components/influxdb.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/influxdb.py b/homeassistant/components/influxdb.py index 1ce137ffc9145..6bac1fa7cfb2f 100644 --- a/homeassistant/components/influxdb.py +++ b/homeassistant/components/influxdb.py @@ -28,6 +28,7 @@ DEFAULT_SSL = False DEFAULT_VERIFY_SSL = False DOMAIN = 'influxdb' +TIMEOUT = 5 CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ @@ -69,7 +70,8 @@ def setup(hass, config): try: influx = InfluxDBClient( host=host, port=port, username=username, password=password, - database=database, ssl=ssl, verify_ssl=verify_ssl) + database=database, ssl=ssl, verify_ssl=verify_ssl, + timeout=TIMEOUT) influx.query("select * from /.*/ LIMIT 1;") except exceptions.InfluxDBClientError as exc: _LOGGER.error("Database host is not accessible due to '%s', please " From fcbfcf0aa7d8cb8d9f1ce2ceadf2226c8d78d5e7 Mon Sep 17 00:00:00 2001 From: Greg Dowling Date: Sun, 2 Oct 2016 06:53:24 +0100 Subject: [PATCH 045/112] Bump pywemo version - changes port order for faster startup. (#3612) --- homeassistant/components/wemo.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/wemo.py b/homeassistant/components/wemo.py index c80ec8cbc12c7..71bb2984c7e0b 100644 --- a/homeassistant/components/wemo.py +++ b/homeassistant/components/wemo.py @@ -14,7 +14,7 @@ from homeassistant.const import EVENT_HOMEASSISTANT_STOP -REQUIREMENTS = ['pywemo==0.4.6'] +REQUIREMENTS = ['pywemo==0.4.7'] DOMAIN = 'wemo' diff --git a/requirements_all.txt b/requirements_all.txt index ddbfd4d2befe8..df94534bab1ad 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -407,7 +407,7 @@ python-wink==0.8.0 pyvera==0.2.20 # homeassistant.components.wemo -pywemo==0.4.6 +pywemo==0.4.7 # homeassistant.components.climate.radiotherm # homeassistant.components.thermostat.radiotherm From d55ed7a3a2be0a7f12034fb13dc0a5279c49f745 Mon Sep 17 00:00:00 2001 From: Jeff Wilson Date: Sun, 2 Oct 2016 01:57:15 -0400 Subject: [PATCH 046/112] Flux switch improvements (#3615) * Make flux always adjust brightness of light (even when not in XY mode) * Remove kelvin mode from flux switch The light/turn_on service only works with mired values, kelvin values are out of range per the schema. * Use already defined min/max values for light/turn_on schema * Clamp temp value to light/turn_on allowed values --- homeassistant/components/light/__init__.py | 3 +- homeassistant/components/switch/flux.py | 29 ++++++++------- tests/components/switch/test_flux.py | 43 ---------------------- 3 files changed, 17 insertions(+), 58 deletions(-) diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index 85f611a679b59..d3abd3c2c1a97 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -93,7 +93,8 @@ vol.Coerce(tuple)), ATTR_XY_COLOR: vol.All(vol.ExactSequence((cv.small_float, cv.small_float)), vol.Coerce(tuple)), - ATTR_COLOR_TEMP: vol.All(int, vol.Range(min=154, max=500)), + ATTR_COLOR_TEMP: vol.All(int, vol.Range(min=color_util.HASS_COLOR_MIN, + max=color_util.HASS_COLOR_MAX)), ATTR_WHITE_VALUE: vol.All(int, vol.Range(min=0, max=255)), ATTR_FLASH: vol.In([FLASH_SHORT, FLASH_LONG]), ATTR_EFFECT: vol.In([EFFECT_COLORLOOP, EFFECT_RANDOM, EFFECT_WHITE]), diff --git a/homeassistant/components/switch/flux.py b/homeassistant/components/switch/flux.py index a0c982952e2b7..d0814010d1e03 100644 --- a/homeassistant/components/switch/flux.py +++ b/homeassistant/components/switch/flux.py @@ -15,8 +15,9 @@ from homeassistant.components.switch import DOMAIN, SwitchDevice from homeassistant.const import CONF_NAME, CONF_PLATFORM from homeassistant.helpers.event import track_utc_time_change -from homeassistant.util.color import color_temperature_to_rgb as temp_to_rgb -from homeassistant.util.color import color_RGB_to_xy +from homeassistant.util.color import ( + color_temperature_to_rgb, color_RGB_to_xy, + color_temperature_kelvin_to_mired, HASS_COLOR_MIN, HASS_COLOR_MAX) from homeassistant.util.dt import now as dt_now from homeassistant.util.dt import as_local import homeassistant.helpers.config_validation as cv @@ -36,7 +37,6 @@ MODE_XY = 'xy' MODE_MIRED = 'mired' -MODE_KELVIN = 'kelvin' DEFAULT_MODE = MODE_XY PLATFORM_SCHEMA = vol.Schema({ @@ -54,7 +54,7 @@ vol.Optional(CONF_BRIGHTNESS): vol.All(vol.Coerce(int), vol.Range(min=0, max=255)), vol.Optional(CONF_MODE, default=DEFAULT_MODE): - vol.Any(MODE_XY, MODE_MIRED, MODE_KELVIN) + vol.Any(MODE_XY, MODE_MIRED) }) @@ -68,15 +68,13 @@ def set_lights_xy(hass, lights, x_val, y_val, brightness): transition=30) -def set_lights_temp(hass, lights, kelvin, mode): +def set_lights_temp(hass, lights, mired, brightness): """Set color of array of lights.""" - temp = kelvin - if mode == MODE_MIRED: - temp = 1000000 / kelvin for light in lights: if is_on(hass, light): turn_on(hass, light, - color_temp=int(temp), + color_temp=int(mired), + brightness=brightness, transition=30) @@ -194,9 +192,9 @@ def flux_update(self, now=None): temp = self._sunset_colortemp - temp_offset else: temp = self._sunset_colortemp + temp_offset + x_val, y_val, b_val = color_RGB_to_xy(*color_temperature_to_rgb(temp)) + brightness = self._brightness if self._brightness else b_val if self._mode == MODE_XY: - x_val, y_val, b_val = color_RGB_to_xy(*temp_to_rgb(temp)) - brightness = self._brightness if self._brightness else b_val set_lights_xy(self.hass, self._lights, x_val, y_val, brightness) _LOGGER.info("Lights updated to x:%s y:%s brightness:%s, %s%%" @@ -205,9 +203,12 @@ def flux_update(self, now=None): percentage_complete * 100), time_state, as_local(now)) else: - set_lights_temp(self.hass, self._lights, temp, self._mode) - _LOGGER.info("Lights updated to temp:%s, %s%%" - " of %s cycle complete at %s", temp, + # Convert to mired and clamp to allowed values + mired = color_temperature_kelvin_to_mired(temp) + mired = max(HASS_COLOR_MIN, min(mired, HASS_COLOR_MAX)) + set_lights_temp(self.hass, self._lights, mired, brightness) + _LOGGER.info("Lights updated to mired:%s brightness:%s, %s%%" + " of %s cycle complete at %s", mired, brightness, round(percentage_complete * 100), time_state, as_local(now)) diff --git a/tests/components/switch/test_flux.py b/tests/components/switch/test_flux.py index ffb413ada4cf7..01b5d79722233 100644 --- a/tests/components/switch/test_flux.py +++ b/tests/components/switch/test_flux.py @@ -532,46 +532,3 @@ def test_flux_with_mired(self): self.hass.block_till_done() call = turn_on_calls[-1] self.assertEqual(call.data[light.ATTR_COLOR_TEMP], 269) - - def test_flux_with_kelvin(self): - """Test the flux switch´s mode kelvin.""" - platform = loader.get_component('light.test') - platform.init() - self.assertTrue( - setup_component(self.hass, light.DOMAIN, - {light.DOMAIN: {CONF_PLATFORM: 'test'}})) - - dev1 = platform.DEVICES[0] - - # Verify initial state of light - state = self.hass.states.get(dev1.entity_id) - self.assertEqual(STATE_ON, state.state) - self.assertIsNone(state.attributes.get('color_temp')) - - test_time = dt_util.now().replace(hour=8, minute=30, second=0) - sunset_time = test_time.replace(hour=17, minute=0, second=0) - sunrise_time = test_time.replace(hour=5, - minute=0, - second=0) + timedelta(days=1) - - with patch('homeassistant.util.dt.now', return_value=test_time): - with patch('homeassistant.components.sun.next_rising', - return_value=sunrise_time): - with patch('homeassistant.components.sun.next_setting', - return_value=sunset_time): - assert setup_component(self.hass, switch.DOMAIN, { - switch.DOMAIN: { - 'platform': 'flux', - 'name': 'flux', - 'lights': [dev1.entity_id], - 'mode': 'kelvin' - } - }) - turn_on_calls = mock_service( - self.hass, light.DOMAIN, SERVICE_TURN_ON) - switch.turn_on(self.hass, 'switch.flux') - self.hass.block_till_done() - fire_time_changed(self.hass, test_time) - self.hass.block_till_done() - call = turn_on_calls[-1] - self.assertEqual(call.data[light.ATTR_COLOR_TEMP], 3708) From 9f8acbec9595e7d9055a5762670de117bb432834 Mon Sep 17 00:00:00 2001 From: Erik Eriksson Date: Sun, 2 Oct 2016 08:00:01 +0200 Subject: [PATCH 047/112] Add support for tracking position and status for a Volvo car (#3617) --- .coveragerc | 1 + .../components/device_tracker/volvooncall.py | 105 ++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 homeassistant/components/device_tracker/volvooncall.py diff --git a/.coveragerc b/.coveragerc index e1652fb23b621..ee2551e4a202d 100644 --- a/.coveragerc +++ b/.coveragerc @@ -141,6 +141,7 @@ omit = homeassistant/components/device_tracker/tomato.py homeassistant/components/device_tracker/tplink.py homeassistant/components/device_tracker/ubus.py + homeassistant/components/device_tracker/volvooncall.py homeassistant/components/discovery.py homeassistant/components/downloader.py homeassistant/components/fan/mqtt.py diff --git a/homeassistant/components/device_tracker/volvooncall.py b/homeassistant/components/device_tracker/volvooncall.py new file mode 100644 index 0000000000000..6876d63c22354 --- /dev/null +++ b/homeassistant/components/device_tracker/volvooncall.py @@ -0,0 +1,105 @@ +""" +Support for Volvo On Call. + +http://www.volvocars.com/intl/own/owner-info/volvo-on-call +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/device_tracker.volvooncall/ +""" +import logging +from datetime import timedelta +from urllib.parse import urljoin +import voluptuous as vol +import requests + +import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.event import track_point_in_utc_time +from homeassistant.util.dt import utcnow +from homeassistant.const import ( + CONF_PASSWORD, + CONF_SCAN_INTERVAL, + CONF_USERNAME) +from homeassistant.components.device_tracker import ( + DEFAULT_SCAN_INTERVAL, + PLATFORM_SCHEMA) + +MIN_TIME_BETWEEN_SCANS = timedelta(minutes=1) + +_LOGGER = logging.getLogger(__name__) + +SERVICE_URL = 'https://vocapi.wirelesscar.net/customerapi/rest/v3.0/' +HEADERS = {"X-Device-Id": "Device", + "X-OS-Type": "Android", + "X-Originator-Type": "App"} + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_USERNAME): cv.string, + vol.Required(CONF_PASSWORD): cv.string, +}) + + +def setup_scanner(hass, config, see): + """Validate the configuration and return a scanner.""" + username = config.get(CONF_USERNAME) + password = config.get(CONF_PASSWORD) + + interval = max(MIN_TIME_BETWEEN_SCANS.seconds, + config.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)) + + session = requests.Session() + session.headers.update(HEADERS) + session.auth = (username, password) + + def query(ref, rel=SERVICE_URL): + """Perform a query to the online service.""" + url = urljoin(rel, ref) + try: + _LOGGER.debug("Request for %s", url) + res = session.get(url) + res.raise_for_status() + _LOGGER.debug("Received %s", res.json()) + return res.json() + except requests.exceptions.RequestException: + _LOGGER.exception("Could not make query to %s", url) + raise + + try: + _LOGGER.info('Logging in to service') + user = query("customeraccounts") + rel = query(user["accountVehicleRelations"][0]) + vehicle_url = rel["vehicle"] + '/' + except requests.exceptions.RequestException: + _LOGGER.error("Could not log in to service. " + "Please check configuration.") + return False + + def update(now): + """Update status from the online service.""" + _LOGGER.debug("Updating") + + status = query("status", vehicle_url) + position = query("position", vehicle_url) + attributes = query("attributes", vehicle_url) + + dev_id = "volvo_" + attributes["vin"] + host_name = "%s %s/%s" % (attributes["registrationNumber"], + attributes["vehicleType"], + attributes["modelYear"]) + + see(dev_id=dev_id, + host_name=host_name, + gps=(position["position"]["latitude"], + position["position"]["longitude"]), + attributes=dict( + tank_volume=attributes["fuelTankVolume"], + washer_fluid=status["washerFluidLevel"], + brake_fluid=status["brakeFluid"], + service_warning=status["serviceWarningStatus"], + fuel=status["fuelAmount"], + odometer=status["odometer"], + range=status["distanceToEmpty"])) + + track_point_in_utc_time(hass, update, + now + timedelta(seconds=interval)) + + update(utcnow()) + return True From d5ab292ff321fee4d41418406659babed2fd6fd3 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 1 Oct 2016 23:12:58 -0700 Subject: [PATCH 048/112] Sensor.emoncms: Never disable SSL verification. --- homeassistant/components/sensor/emoncms.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/homeassistant/components/sensor/emoncms.py b/homeassistant/components/sensor/emoncms.py index 9cd131f9dc152..6ed269bc467e0 100644 --- a/homeassistant/components/sensor/emoncms.py +++ b/homeassistant/components/sensor/emoncms.py @@ -202,8 +202,7 @@ def update(self): """Get the latest data.""" try: req = requests.get(self._url, params={"apikey": self._apikey}, - verify=False, allow_redirects=True, - timeout=5) + allow_redirects=True, timeout=5) except requests.exceptions.RequestException as exception: _LOGGER.error(exception) return From b6b0bad0c7009b56e8193010bedc5a5ba6005093 Mon Sep 17 00:00:00 2001 From: Martin Hjelmare Date: Sun, 2 Oct 2016 08:23:31 +0200 Subject: [PATCH 049/112] Add new mysensors types (#3637) * Add S_INFO, S_GAS, S_GPS, S_WATER_QUALITY. * Extend S_CUSTOM, S_POWER. * Add more units. --- homeassistant/components/sensor/mysensors.py | 20 +++++++++++++++++++- homeassistant/components/switch/mysensors.py | 7 +++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/sensor/mysensors.py b/homeassistant/components/sensor/mysensors.py index eff67a1f9e223..ba9896b004031 100644 --- a/homeassistant/components/sensor/mysensors.py +++ b/homeassistant/components/sensor/mysensors.py @@ -11,7 +11,6 @@ from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) -DEPENDENCIES = [] def setup_platform(hass, config, add_devices, discovery_info=None): @@ -66,6 +65,18 @@ def setup_platform(hass, config, add_devices, discovery_info=None): }) map_sv_types[pres.S_LIGHT_LEVEL].append(set_req.V_LEVEL) + if float(gateway.protocol_version) >= 2.0: + map_sv_types.update({ + pres.S_INFO: [set_req.V_TEXT], + pres.S_GAS: [set_req.V_FLOW, set_req.V_VOLUME], + pres.S_GPS: [set_req.V_POSITION], + pres.S_WATER_QUALITY: [set_req.V_TEMP, set_req.V_PH, + set_req.V_ORP, set_req.V_EC] + }) + map_sv_types[pres.S_CUSTOM].append(set_req.V_CUSTOM) + map_sv_types[pres.S_POWER].extend( + [set_req.V_VAR, set_req.V_VA, set_req.V_POWER_FACTOR]) + devices = {} gateway.platform_callbacks.append(mysensors.pf_callback_factory( map_sv_types, devices, add_devices, MySensorsSensor)) @@ -104,4 +115,11 @@ def unit_of_measurement(self): return self._values[ set_req.V_UNIT_PREFIX] unit_map.update({set_req.V_PERCENTAGE: '%'}) + if float(self.gateway.protocol_version) >= 2.0: + unit_map.update({ + set_req.V_ORP: 'mV', + set_req.V_EC: 'μS/cm', + set_req.V_VAR: 'var', + set_req.V_VA: 'VA', + }) return unit_map.get(self.value_type) diff --git a/homeassistant/components/switch/mysensors.py b/homeassistant/components/switch/mysensors.py index 6e0ed7528a28f..f303a07686cff 100644 --- a/homeassistant/components/switch/mysensors.py +++ b/homeassistant/components/switch/mysensors.py @@ -73,6 +73,13 @@ def setup_platform(hass, config, add_devices, discovery_info=None): pres.S_VIBRATION: MySensorsSwitch, pres.S_MOISTURE: MySensorsSwitch, }) + if float(gateway.protocol_version) >= 2.0: + map_sv_types.update({ + pres.S_WATER_QUALITY: [set_req.V_STATUS], + }) + device_class_map.update({ + pres.S_WATER_QUALITY: MySensorsSwitch, + }) devices = {} gateway.platform_callbacks.append(mysensors.pf_callback_factory( From e455daa61db5965b004aa2f5f9e4832751ed3b65 Mon Sep 17 00:00:00 2001 From: John Arild Berentsen Date: Sun, 2 Oct 2016 17:47:04 +0200 Subject: [PATCH 050/112] Make sure temperature slider is shown if reported temp is 0 (#3653) --- homeassistant/components/climate/zwave.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/homeassistant/components/climate/zwave.py b/homeassistant/components/climate/zwave.py index 0fb13d258aab3..d744f9a139122 100755 --- a/homeassistant/components/climate/zwave.py +++ b/homeassistant/components/climate/zwave.py @@ -164,6 +164,12 @@ def update_properties(self): for value in (self._node.get_values( class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_SETPOINT) .values()): + if value.data == 0: + _LOGGER.debug("Setpoint is 0, setting default to " + "current_temperature=%s", + self._current_temperature) + self._target_temperature = int(self._current_temperature) + break if self.current_operation is not None and \ self.current_operation != 'Off': if self._index_operation != value.index: From abb8bcb6d934d22144c40e22459dd2b62e7353b9 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 2 Oct 2016 15:07:23 -0700 Subject: [PATCH 051/112] Protect waiting for event loop from within event loop (#3658) * Protect waiting for event loop from within event loop * Faster fetching of loop attribute for ident check --- homeassistant/core.py | 2 + homeassistant/util/async.py | 13 +++++++ tests/common.py | 1 + tests/util/test_async.py | 77 +++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+) diff --git a/homeassistant/core.py b/homeassistant/core.py index 43c20f18b75ae..1ef0adc596140 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -199,6 +199,8 @@ def async_start(self): This method is a coroutine. """ + # pylint: disable=protected-access + self.loop._thread_ident = threading.get_ident() async_create_timer(self) async_monitor_worker_pool(self) self.bus.async_fire(EVENT_HOMEASSISTANT_START) diff --git a/homeassistant/util/async.py b/homeassistant/util/async.py index 54a3204c78df6..ff498912fc2fc 100644 --- a/homeassistant/util/async.py +++ b/homeassistant/util/async.py @@ -1,5 +1,6 @@ """Asyncio backports for Python 3.4.3 compatibility.""" import concurrent.futures +import threading from asyncio import coroutines from asyncio.futures import Future @@ -97,6 +98,10 @@ def run_coroutine_threadsafe(coro, loop): Return a concurrent.futures.Future to access the result. """ + ident = loop.__dict__.get("_thread_ident") + if ident is not None and ident == threading.get_ident(): + raise RuntimeError('Cannot be called from within the event loop') + if not coroutines.iscoroutine(coro): raise TypeError('A coroutine object is required') future = concurrent.futures.Future() @@ -122,6 +127,10 @@ def fire_coroutine_threadsafe(coro, loop): is intended for fire-and-forget use. This reduces the work involved to fire the function on the loop. """ + ident = loop.__dict__.get("_thread_ident") + if ident is not None and ident == threading.get_ident(): + raise RuntimeError('Cannot be called from within the event loop') + if not coroutines.iscoroutine(coro): raise TypeError('A coroutine object is required: %s' % coro) @@ -139,6 +148,10 @@ def run_callback_threadsafe(loop, callback, *args): Return a concurrent.futures.Future to access the result. """ + ident = loop.__dict__.get("_thread_ident") + if ident is not None and ident == threading.get_ident(): + raise RuntimeError('Cannot be called from within the event loop') + future = concurrent.futures.Future() def run_callback(): diff --git a/tests/common.py b/tests/common.py index ceb9bf3c058c6..b44cbee4b6fef 100644 --- a/tests/common.py +++ b/tests/common.py @@ -58,6 +58,7 @@ def get_test_home_assistant(num_threads=None): stop_event = threading.Event() def run_loop(): + loop._thread_ident = threading.get_ident() loop.run_forever() loop.close() stop_event.set() diff --git a/tests/util/test_async.py b/tests/util/test_async.py index 079097f332685..f88887e3c6e3e 100644 --- a/tests/util/test_async.py +++ b/tests/util/test_async.py @@ -1,10 +1,87 @@ """Tests for async util methods from Python source.""" import asyncio from asyncio import test_utils +from unittest.mock import MagicMock, patch + +import pytest from homeassistant.util import async as hasync +@patch('asyncio.coroutines.iscoroutine', return_value=True) +@patch('concurrent.futures.Future') +@patch('threading.get_ident') +def test_run_coroutine_threadsafe_from_inside_event_loop(mock_ident, _, __): + """Testing calling run_coroutine_threadsafe from inside an event loop.""" + coro = MagicMock() + loop = MagicMock() + + loop._thread_ident = None + mock_ident.return_value = 5 + hasync.run_coroutine_threadsafe(coro, loop) + assert len(loop.call_soon_threadsafe.mock_calls) == 1 + + loop._thread_ident = 5 + mock_ident.return_value = 5 + with pytest.raises(RuntimeError): + hasync.run_coroutine_threadsafe(coro, loop) + assert len(loop.call_soon_threadsafe.mock_calls) == 1 + + loop._thread_ident = 1 + mock_ident.return_value = 5 + hasync.run_coroutine_threadsafe(coro, loop) + assert len(loop.call_soon_threadsafe.mock_calls) == 2 + + +@patch('asyncio.coroutines.iscoroutine', return_value=True) +@patch('concurrent.futures.Future') +@patch('threading.get_ident') +def test_fire_coroutine_threadsafe_from_inside_event_loop(mock_ident, _, __): + """Testing calling fire_coroutine_threadsafe from inside an event loop.""" + coro = MagicMock() + loop = MagicMock() + + loop._thread_ident = None + mock_ident.return_value = 5 + hasync.fire_coroutine_threadsafe(coro, loop) + assert len(loop.call_soon_threadsafe.mock_calls) == 1 + + loop._thread_ident = 5 + mock_ident.return_value = 5 + with pytest.raises(RuntimeError): + hasync.fire_coroutine_threadsafe(coro, loop) + assert len(loop.call_soon_threadsafe.mock_calls) == 1 + + loop._thread_ident = 1 + mock_ident.return_value = 5 + hasync.fire_coroutine_threadsafe(coro, loop) + assert len(loop.call_soon_threadsafe.mock_calls) == 2 + + +@patch('concurrent.futures.Future') +@patch('threading.get_ident') +def test_run_callback_threadsafe_from_inside_event_loop(mock_ident, _): + """Testing calling run_callback_threadsafe from inside an event loop.""" + callback = MagicMock() + loop = MagicMock() + + loop._thread_ident = None + mock_ident.return_value = 5 + hasync.run_callback_threadsafe(loop, callback) + assert len(loop.call_soon_threadsafe.mock_calls) == 1 + + loop._thread_ident = 5 + mock_ident.return_value = 5 + with pytest.raises(RuntimeError): + hasync.run_callback_threadsafe(loop, callback) + assert len(loop.call_soon_threadsafe.mock_calls) == 1 + + loop._thread_ident = 1 + mock_ident.return_value = 5 + hasync.run_callback_threadsafe(loop, callback) + assert len(loop.call_soon_threadsafe.mock_calls) == 2 + + class RunCoroutineThreadsafeTests(test_utils.TestCase): """Test case for asyncio.run_coroutine_threadsafe.""" From 148ea82513802bfe9a7c31a193e55f101b533857 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 2 Oct 2016 15:38:07 -0700 Subject: [PATCH 052/112] Update frontend --- homeassistant/components/frontend/version.py | 4 ++-- .../frontend/www_static/frontend.html | 10 +++++----- .../frontend/www_static/frontend.html.gz | Bin 127107 -> 127562 bytes .../www_static/home-assistant-polymer | 2 +- .../components/frontend/www_static/mdi.html | 2 +- .../frontend/www_static/mdi.html.gz | Bin 174998 -> 176048 bytes .../frontend/www_static/service_worker.js | 2 +- .../frontend/www_static/service_worker.js.gz | Bin 2438 -> 2278 bytes 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/frontend/version.py b/homeassistant/components/frontend/version.py index 151bc954cfa37..6ea4ac35b3a6e 100644 --- a/homeassistant/components/frontend/version.py +++ b/homeassistant/components/frontend/version.py @@ -2,8 +2,8 @@ FINGERPRINTS = { "core.js": "78862c0984279b6876f594ffde45177c", - "frontend.html": "c1753e1ce530f978036742477c96d2fd", - "mdi.html": "6bd013a8252e19b3c1f1de52994cfbe4", + "frontend.html": "6101173e9a8930f9c74767a3bc493bff", + "mdi.html": "46a76f877ac9848899b8ed382427c16f", "panels/ha-panel-dev-event.html": "c4a5f70eece9f92616a65e8d26be803e", "panels/ha-panel-dev-info.html": "34e2df1af32e60fffcafe7e008a92169", "panels/ha-panel-dev-service.html": "07e83c6b7f79d78a59258f6dba477b54", diff --git a/homeassistant/components/frontend/www_static/frontend.html b/homeassistant/components/frontend/www_static/frontend.html index 2ca0e8d217ffe..74a6b91189514 100644 --- a/homeassistant/components/frontend/www_static/frontend.html +++ b/homeassistant/components/frontend/www_static/frontend.html @@ -1,5 +1,5 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/frontend.html.gz b/homeassistant/components/frontend/www_static/frontend.html.gz index 3f49436d6c0f19e1b0d39dae0fa604cbb09f592d..b6cff9882d161516cf5289227812891cf396fc07 100644 GIT binary patch delta 125400 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 V7t_zU4WW+5{||eBv>0Cb2LM}YK&$`& delta 124939 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 diff --git a/homeassistant/components/frontend/www_static/home-assistant-polymer b/homeassistant/components/frontend/www_static/home-assistant-polymer index 0a4454c68f3c2..95cbc85b7f6a5 160000 --- a/homeassistant/components/frontend/www_static/home-assistant-polymer +++ b/homeassistant/components/frontend/www_static/home-assistant-polymer @@ -1 +1 @@ -Subproject commit 0a4454c68f3c29c77cd60f4315d410d8b3737543 +Subproject commit 95cbc85b7f6a5cd969598614122bf2b247817d68 diff --git a/homeassistant/components/frontend/www_static/mdi.html b/homeassistant/components/frontend/www_static/mdi.html index 0f1aa609e4622..e9f69984a4769 100644 --- a/homeassistant/components/frontend/www_static/mdi.html +++ b/homeassistant/components/frontend/www_static/mdi.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/mdi.html.gz b/homeassistant/components/frontend/www_static/mdi.html.gz index 2be36b99edb9d597b4ef8101533e4e5001e22582..e219e5bcd4527f8cacb7e0198575debb207cb75e 100644 GIT binary patch delta 170495 zcmV(|K+(UJ*9x%T3V$Dq2naNc@mB)>ZDeUKXmo9C0PMXk;?c|iqIDdy`g@6y&T@lYO945ARG?Ij60tD?~gCf zPj4RIK0keaczyHvFYh-`_a7hr_rHC7_xNucWdEPX|LQ+|{C~Iq`1k(wKmPsQ!%v_8 z;o2Q4@zdpbGaZFQ2Q1feS+4Q2 zT>W{urt@;mTCUYr>wwkjE~_xH~O_3|!FAM}s)O2f&;y>l!3 z;rYw_#KyA!p)X0k?>L^*pX|%!cU?Y>+_-%(^EM*EHJZl7T2Fr1qno>Exn-Lwit()* z&3}7y|KZ_f-pFCz$T)AtFmGgDK8>gVjf~bvSFJfnu#p~(^p=~(M&hj__uHv(wEf-> z%*YsElJ;an{S@Kync9m zdYDZbS93b0{<)*7oP6W^8@B6z(G(n1J;m1HU`V`k(oV^Ke)W+HOm1vV4*FHj&&&AI z$(23cVEo?+*W+Hxe?iahDHpY?kX6Ize%(Jil;j^xodTynFNR;r0IU!++=L z@cBMqz7rK;JEY$0e)#lhNcf9^+x5SFJcgdZ0^Z?N$C|kK3jLNSRZ$TsNFtuh^a3fE-@y&52%V4mV}Oe_XOS)C$-0d6gTL z(p-P@vOY24ZSt#5S9TvYw|JUwj(^|J4{v9edcSFZz&hyv&KslutlMRF<0ofX=|;iS zYwdj~eYN#_q$tfxCvAggqHtN^_-0avNq^R9pOwMYqroZ zb}D&0mH4|CE#tA7vEPcb_j?DdQu_+Nmga|0T^wL;c7QFOa!2|fc&CoX0H$f0ff9=% zBmLcPp@R1I4ZvbIN9pDrgGOhI1NV*f(yqz8U!IiXy0| z2#Ua;DFQG;w|Dx-$EPo|d(|b*s<+u9s~rOViVzH>1cPORuhQ9wZy;+W`7_l5Jzvq@IgAvDX2>wm@ac>6ABzJX`&g5(?Y&Q)f( zRnmFV5AznctCp1O_NLWBXl+?*taB?(C@XD^H_G*vf)WA!mPoCOhZ^~FENC8m%?^E> zF1QE+MLUJ(P2{>xo00QMxFnlps&*Vxmc$2+B*FPjzfJa0e=gWRlJ#~OYi#EV-KCt8 zs*vC2fq$qotW!(eVqwbuky7u+c-`_;D|#o5=N>*VR2_1Da!C5|l*Ge29*O$mH<$CL z5C3z_{PT{P)H&F28qb@aNa^F}( zZCY@kJkCK-)Z2xXO}S($eNA#~#S>v2gRgYB`G54B3xk_wk3|8tXu;Md(pcBrE=cuR zR=rj5CI#~R(@)=!5<=M8I4f~Wv1_W>pAdpLh_Wk0$>fA9sPlemfMV#ZQXJ)mTMsGQ z0sKzwq+aKD!6X%roDxI=GI5b1W-wfK>SUa-l}eFbOaF51pBvI4;vUurfp9%aS(-W#yv6CIi*W14Z@nZy_-`KpGdU|_VE{F8LAAbaqA}VbEh=U;i6G-)!hmX&Hd06Sl*uZm> zkziLaCA+bI=MEc#krr&Dn=^)Kz7N~-X}{hfP)hAkwv<%H+;?IEHBjpzL&oHsa&S3# z6~j3b4?LKn>szT-%X0mFD;OY*>hCg(wXqz(pikZ!qR$WaFK>UIiRf?+{a|F-<$p|R zpd=G6|Xf7{WLVk9U#}>2Qm|MLbjUJH(snZ!a$orV=ls!;HsG@_uH0%l$g~KMFOC;TC zcrTx8Q?aPGBEQ?OA0DoFXC&tentxcXpNy2}GQWSuf8~{Qdj?-$AD`ZT{7KIDb z5J5U?LnoL#8g@V{*;Gh}b5IAo=hrP+^>#V*x{<~xK)+PS(Lp+E(0}mxqOnBP8evpj zybV0kmeumgS>)OU1Wwp- z47DaOKsAiX>v!itjg zQjyhTPbfNW{ies8WumCT(z^WWQ$N)lxy8eR4ou(fBQ-4n`f&QQEuWSnS)4KvT9-s7 z69+%F3IW0%7=PKEm^>uVLj9S&cs17V{=YAumqs(cPDgoFhE;(qOgKL_WN|xzYPOEZ z-td{2W>QOi#AFecrUs0BO^>~*9=V>mPA|=LddtUcuGCv$dmdk)Jbm{F4b;Qzc*T8R7X&SZOib9A=YgMYyBh3ZZyqzZCc_G2{S~8{ab;&Z{YD-d9h{~JkT<(f#!`_vf*L^%|zA(d7+stS=`c`%ol3D zkSvu_mMX(eN&q3PqEZmT;LNK#@Hms;3Pf6<{a&IKo=hQotGNLo^}-extK*PM{hHIM z8K_k$*nfmBVeiqT6qW-rE`f}t(E!nH`8@F0%+N5mXmZ;`L0TVTzYEfaLOYxx6)Cvo z8yTBcc1k3085vqT=OIv`>?HPw9w`smX@p&E$rPW){vilZA>j+KjLaSegOti>`f*R> zeVGcvc^HdU-zTKPRPToq!tu2;d%UN_7#+=h4}U|DgQ@SN{BRiaP3H--l)A^89%+=R zGui(gth8oXcyDE0|9Jo5!}CI|+BZ{}bp)T|vEtpdN=U1qbH)zC@&<=Wmat*%b7{dy zVC(Zvq_ZbgKr2VFzQ*`^E;xy9gHGE#{}9EA^TEZAqcRY$RI3K3cUApZ$NFNU9RZus zr+>;>;~Wh_csxKNJpSkQlDq7#n)c_z%O(toMn?X>Ic_diW9a0wkM$-%xr4|>({67nYr zEWrPrQ1rkL-)iBT{@=UKsLootm3-Q5d7bfEZpTJ}0!~wKM1#pc4rDG#7bhN%ylVQf z+|y$EaGf}DlNfXFxO#cOwb3#IFUmTI>{fL=i2^sM8Md%Q-*N+pBeGZ(rD3Jq=YOs< zi5{Ey@sxW92SvdzYJ zHX(eYoyb{&aOm`FFXdHJgA9sxq@AW_(Hm-{eei!oSV2A*eTBai36*Hu~)Ie)B(ilbXhP~S2YQ;8`a`cmz!16e=d{sr|aPRWT( z@|naRNO+tWxbqH}I3)WL3$#IxkUmOahwXQec^McqSvv6^$Dn6wI-29c$AyM=GD%}~ z%I-VU7B`o!tPjiI=T^25{6P4RO9Hl|`!Ka_h52Ne8KU;FD=-KRr^M@|kbgwRfKE+M zVD&$v~?Q&(%>-pDN6J58-uxc z9;JSj9*TmGLN#ioTtmVee;9?Coi?t=0(KntSD!wd-L>y3UM8A)NInkdGJUP#na7Hb zD(uJyvH~#Sj+&r@m0KOPYkxyd&^yurLz^UFFup3HCvtOxtjd(;WTr>SPNd-y*Y8-z zpJguo1w*@LPt@=+V}Bf6r20qT;1D8?Nq(yw&V|&DK!JOO!&M2AiLnMrw)lpXJCbdy zcXbq+VD=`zK`{-J-|6Zxj@LdRy=9}g8$~WZNeWGWx2xxL)u5dN&wqbU6U$5yR*+0j z64lJZBJ@)^!NM!%tni%qkmju*z38C*+=@B*S?O6ZqS19j`$fma}} z6T0Q$q5#uS!+D*9DxmY8!`%Yeh!e}w8LOrdE@^d-?Zg*)%Bh3HU^yE8LT%ES7%Wo= zeLe2hKzUrjcPm$OU!`L!|Iz(*TstLpW^@P1E^osqS0dV<^nbI+S_9cJn052-E5R%} zqFX&EXutx_zlkxX8Os1qt$t7!ydnIH+8#e>8D@ajcl8G+qj{m!R$hx1YR+ zs6BOmnq%`jC+Z(NUe|}|^V9S5e?82N!~eiD`}euvfBPhXqJv_p)97TVJQssReGYm9 z2?60G(y8NXgMZ5pKYm%#J~N|g=jJxoJanhO!}W8q)R_ihq**Q|VrI?;=Fkj~Dd3QU zP8vl#X_VTG=4$@zFqF)FA?u~lALw_I>|GDf(y1-n*_Io)&BDb}2tR2~M3;cRkou3+ z`j#$c{lJ}CO!Huw`B_O(;r3I5!!Y;%!s1bL`i;m2g@3VqMQcHa#Cn5P{7(YCBOEHT zYFI})n>GD$<894ZwcLUHf@hsI2RSe*1d=ej&A*54comofYlb+p}9u)#;fO zER$qsEoUSIXn{6-UhyHkgT#*YFsn!)-3kmsAb%Cka8GKqhs>0<;A9IR2Rs~L{H}_Q zf}=UfbgP%0f=F0dfIk@GhROpPr?t*-Q$1SFtw(CdT9k>J!83X}YEzIze`+*~62ThP zR%jlZI=~TSr=Wf<%JgI3&u&{bE-a$4;)@zVsL;n;wTGikTR=`iI!MG5C_RyFAY~eb zrhm+pwv}uLh_KRWy_ovBSI}q|DS@fRBb(si{yIke){=-v7820%06U{ zZlhwBek|+_gx)(Rk-b(J$J_bQ<_XNy9=)tPlP42;0=uuz2sg3}C%oIq2%FiWg!{;G z5mB!dcH;u=1bd>u2X~-SFp6$of*vens();8#d@kiAYpd6PBR^T040GY4uavpo$5r@ z(Bnuh{eebNbW~&83l9fbfMBswDxRPUDFHpCtw}&7q5p;ri=7f6NoXO`%IMpYO=n+B zDFYE+qi3QJ8O}Duu&OofJCZvygBi0MM;Nke8cPaj;5=;*@KuUCQ>N0%Nzi4wDt~N0 zsjwU^VX2x&e*(2U%pI7NkuxcJ78pR(V~8Ux%e*wGv5#@#)~J+y<6EUE)xUu$NXBMV z%Ff7TG=ruH4ipl*)~H1?BoncgUTI8I^kcr`fKo9h6Q9T~H14Y22I>Es^4NM-0qjFFN%br*Q!hdtNggvAB zJ6$OEhUbk2>=bHVOV&T$|JQ{NM-Da&ZW0>U}j%KLn8a8xqDEk4W9U9(G zBVGqo;swq_B{NCuJy=li9HMFrR%uu*6nEiVE~6$Ovgn-2(9Z8teozbMw13o(_C#$2M9P?3Rglein`xR1#4#U?KZHIRjyRQ)zah}n%+Wfo zj8HvDJinSOLx4^*yye zGQLZsy$bbw-mEPLk~xk2k=hTogRo3MQxXSOt&I}6Rdqr(bbp0HHrNF^3g|2L`lUDP zr_P(VAD+Lwd-t-S!y}iSL+g{xxbyUsqlgQ;M#^$fEd}@JKrzgTpBf5Mh?R;mi09gtxq)*S zc!%QdZDyp=?|)=ZNDk$T77odv#d6xo%(l^f5yi^*ZrPc=3v4^!od>^pZr7bm(aC7Q zx_l$^#w<9i2%bZx>dtR2Lw!9%KYsae|Md1@>1STAwVjmBlw~fDk*l)#R@n;iOViOV zBQ>Zrqc}Zef{eKScv-72uYEe+D2Wfl3W3IWqAF%4W`EG%FYKcFtv$)f^8%7^ocfV~ z3!_gqZJglkj&4=ZA^p%l0UM`Z*b=-FVx?0d4avN}HdOfd>BHksk8_Fwz))8XYk_7k zgwmPhSIQ|azsZ=FNlu;@AR15Tq{_mX4OXBDt!$l^Nu9RHljkt|yZq|gZC3yM8Fe$j zogqneB7f9ThS0f!aLK?($uR4w7_)4$#Hq7Xr`P7*Qf=-nb@kj~yr#{Cyl39KI`ijS zJiMlMpWgob{BmU%cyWvDw8ahtfd{ETR~dd2G>IDoeF4&~LM_mE2f(ZhE1DNj!p^3G zQ;Q^=h^GW139cf%kLUyk;2+9}9B!e?UxkD|3x7BxtfbQ(W&0UCRwSH@%z9EDq0-n2 z$|HNr*vc#+WhbSobT8^mQs-QndytyIYql`qWIFljmou?=dad1hdiV1D_->>@jM+}=Mf(s=EqbF%6oCi8OSTe-TSU|2QIo`b?XcE*){*rcqMGicZ`{|KM zn15B;QqhMCNApJ3U$BahgpFEMAB@a}T)p5OevEj1s=wgzm~{3$qe`~WQaO)LD}+FB zOxO~5$cUyots zBmUMm!rCX&tuL@@-UAao0T`S;3;?f+-8jYF1|=bhJO$4 zs1K*0hEk=9Dc2p?$XGPx%CJBJopWnxV7ilQMV1>iHz8~_N1c}J0jR>nvb!}gpI^Vc zdwgD+d}3Wh8VxKRHt0ruYKKvB6{AF;^facgIz>c|5KE0c=#wH>9~v`}I&5L|Yb@r6 zGGyolgE=x8S#7S+Ihbo>BIZ;g0)J*SOa$X*og{)Z>x2x+JR4D<60QMn9cZ@8y2AMb zfeaYFir%P8eQ})9b?4D4`PUs;mXHf(rHs=MJnPUV_Z_?C_9Q~eh zLNg1e<%LY6l^j?Li}n8wmroyOx5zNR&xNx&*DfxeuB?jpo#ef`(YK@3OMjx!UBoWM z&R&RN@tgy^1uMoEc@1v!K}Hs34{idwd&4xQU|04^Br0(WAM^@X?JP0do{Tl}E1m4l z53bw)`0)xFsxzWHFW4n-s7ZibihEw1@#Ob_^utBc%itD40vMW5pOF5lAV>w!yOYS* z8R{viTf$>{JQBA!+Oi0N&3|+8)4tt%VHBba5i z2b<;6R5tTip}0O%G?h_*rbN5SnZc1Iqsb=)0Mxux9;bnhT5fbzfVLl_r!zusasx4^ zGc81Awvy?6sC>Z$XNeaG%VU!Oy=BLM}cXO^O@(}BTx|87B(>F8F zeAvX^IG_)5hr&ech&Iua?2*UU1o#HNZZ3j`k@H;NPE?D%6B;=UtRQjWHkNB=OXkzi zi!CJL?UZK%@pz1^9#$GAv>bhAJ*TkBffzS9y^Cpo#?=&*K!1Ld*sCw(QY8!$MkP=S zA%50%;RR8Uqv`w3H;kuxgcAUkg$V+H^Mme!YhW@A6@bKV-*)EJPGJfrwljH>={JCo z(n}w@Pfr18k^!)G#+~DFY3QOODbmU)J&atRkW!9VDrqYp-O*>cn4!D#X4TCe@1(B8 z*4W4*u-H5^vww0;N}}bNA1QImaRk2vKi{_+cr@3kzzPR8o|>R$`tS91`S?6XdmZ|n z3ryNMa5U^}ra76K{dzL>L)p*Z^XNi9)qjXOWiy%?JTx%xPPPtHXuX1OP0gE|>@=oz zK`MWmzJywiRF!1(7R$5kGl4kTdbfXh`1_B~K)ii>|9|Nk{)5~;C>19U8TglmKA4S6 zD{s@`z#D@Cq71w3Veg5X2|Y(OkAJuj9fcp*;1~pdo#9&zdj9yalZ6XY@;Q(+r4zAl z%1LgW6~g|XKSf)K7VYZ1-0ZgmG&6{6Omn7WsLsHxXXO^vKy^pxqkWzg%JUisw^!%O z#1D&=w10T+D4oH$M)pb87C>A9KQ>*rasFb}ALh{2JQ^KAges-00gk&2X#v+}QgF%Kg|Vk;!u_DK;KAk=T0bFuL~ zVq2Dt@ZFrWX2xbk)5}1mCWU;>=VXBsm?sTJ+Z?|(PWWm zQh(Im2T&Zm@S9_js2SCAd6iIeWVgxyL-BLEjYXUr%Lw9zG*zZfBSn+^n^6opzCOgC z?|-^~dHjkmvb(ZCb5~YsZnIkCII}_qob9wP9*JJVcAeM>FBp6{6i(l9SyQ( z<{FczJCju^3N}=BBTJvDTnn7&M1S^&LZqJF(=}};M>KotsYRnjoTY{PKBfVC;;3vU zmjniaFn@4IaGNt!&QPam{aw0ACa4+>JPNM0w0nT6ALg3S zB0vx)9)Z9&HXW1XF-oPH!Y;}>09+0Ib z>f@gup5DFr@&4^E|484|A29VskM`Dm^#i?g_{K`#tUuuCBYhm=ynk=(iMR^u9=gh9 zXWHA!mFG-j7i7)9(wgVLzPbPKVQI7N=(cLcP4o`NRRC-l`Ph2PlUwcCi-C4wL8E^- zdo&y*A>tb*sI2hplWAkmYv+Q*B)daGwG*>I5jd=N-0F09Da0FWhxC=&I}7>g<>B+^1uLPu?Lhn4L=|P= zS{qP5zw0UE=3I`&&vuV^=RiAJO6jSa8t4KhqdPJPGysfWZ-3R*k~_C-@_CLx1?G2T6TmhWN#stvV0uzicKN=h-NMo>2UR;r(n5+_ z_5Q((&gADRzcPRR%?bGV;csxu`4!#t3c0Y;-%2C9BC~%tx=6qwgZ}!|Qb5M<%_y%? z{7ZPi(Noq*bwPn@8_PHfpYiS?n7Ij^RfNsx$q4Z4L4T@v*w6;q_XkPnOOx+PCU$`8 zqasD0A+M`XvmquNmV1D+=js8NEp;rLr$}k~fH#){{+0QFG-@s#V461&r2~hLwoD>k z8gfpRN3P0#WwPGAJb(IQcMF67Y@bDT+L!NZ&Mhyf-w$`}n;vIh_gDMwo<02S(?YOH zRUs}`-GAx28zObkWJ3nrv%KnM_XGvXa1?E$%SM+xrN8b3_Ys=b^Pb}AZ+M_q{%h@8 zUW=C|Oxh*5BO2$?F0QwVhFGaxntW9GHg zOUFd<#mh%8-4$tscfuI0t)29>$;gf6*T-Z@cYo1;0(WgS-zr8ZlL`n|)*%{ss61iD zD4tL!2kCn;-2T$l)kxj1JkhPuZhqx@{6;_j=XU((+>V^98@J={x!53Q z2Y)N$3Ef^!<@=hmwsO{Qx?go)9)HDsxV%ljw`*6-XdE57gm7eMt|NoMGthiWyk(9+ zT{?7$BY2A!EVQZ54gr3i*z8rhuB~L!(~K40rp? zy=vPk!8Je3>-j8qI*oq6F8m4}WN{{cvwxdk<4L~J&;L1f|2e0wX6x3m`#Wx!fh>ID ztPj{WW9 zUH6KV(dvdI5%xEXjcu6R^(=sNXYOac?k}Gfl4D5#t7KAvf-}&|-UP9cf>;Tdlz&&p zfP;X$=VAn+dpr(Tmfk$U)mTBsG3<7K_%cY20xmO5LgI@ zhPZvX(Wi`$Aa&VggH90uNgHDo1tO0qN<`bpkz&hrOpJI_ixqkv4v~me} zFa(8q8Xb%n9x5o{!4M_^4+3Ee%*`bU%|}iYi2Wuz^gxUC7%YlX5q7sD^gWKFjliz+ zhJ#=z|9oaei|i-pW<%5)e2AXnCn>Zkb&On?43+^{KDkD~5Sxt^5;)AD@z@D#j?HuY z701VMjMP1tdAYme2w#%{uYa%iZ-4&y@N^ZxzOP3M3OP9dwrP<`SNUsuRJSl(O)y0G z!7Hl#*>RWk%`+wL6adLqZ(SU148LZYWg^o=>*YyJqsO6J%N@YS=Wt;Ie+Dz$pPMp6N>^Pr*V)_I&48Q@Z8T3OnVEy)(#x_P!0&c;iOQr78tBVtwgozC$M+$k z@p?V#?V^WC?-sop^?#-xbQAs3TL>~pU=g?s?XbappTaHG&v0y^ z7eOU@50RA$QJ8`-TLC;_f5zsmPUM$QAD-`Lbhsk10T)Y};eSIhJc*o+*y}*JrQ>+q zLS)`({j^2kM;UT=QiZci;5^u~cpB3<8h2+hB|uG*kx4Sqy3`SQt%)xWPY-`xT>2S) zlKGB1#hum+O92iHgR>DpPa)niApEneIDtUtg0i6i`#xt$kXzQ-u=>%@5OvaCiRT)nNSP4WOT1mPnHe*F(4POuTx& z@N0CODB^L3Q=*+~OpK8^2>yBjRqGZ|wTtKBsDF8wbgwL6V)OO$uyDBc$3>w< znR@kf`h~nAE&K8Q$GFL^7m2gnGMoLH8p0?U>+Sr-rhMBY{1xZqflt|zqoJBSTTcYbo6hDii zjiu&+-oZGF8{I$P1j(vq>Wl+@_2>hwCrNQ5>3^x}7uESu;=fahL8`nga5J%pE?qv> z>vfdJR?f5Q68XlcwzZPtk*;bM{M*W+E7x_87*#7}uLTe=$Ncfj%lrAMiBlii6I@hT zcvlC7r}4}|ST2~59cVJ^sWC}M8oF0ms(LrZ@)>cJuThlo?a!a?-!2tNVP6E7iCd|_ z)_**}O_CvvI#-69;gA$;4Q>y~qGjf|F+BPW5q7+v@_%s-v`j`g9L4%yM2_VkmOxel zw8lQ1iztY(Kk&#O3+RpEQU~J(s(?jNUg>t{++Q9(&`#^J21}2w>yr6j~ zxgJIY{=w98MNW?K`cp4&pWiLy@R>oA_rOy^1G)5prbIBMflSef7Rs3lGHn!$qJKH} z(YsODOP<9EzJyI>BqI87qa|-Xzr9}|4_FJLwV;j-Xy@-Yd@cwGN^s2_B0@hove=on zzhiSy9{2@yKb+>y(w&1l#XT({rm&qpvUG2KWRy7AaD%>rZ}u$|s%mECwUID_ z7nxCe<((B%A};EySBLnGmp@HUgGJIA=o|z{$B& z_$@@ZJtK$)G26j<02lN-BB1upS&-i-tiUnut_=!-6EsjVgBJ!vv;kGPvT_p19fHMd z)CX)zk_B+|_96L0mGhJ;$$xp)*EIWXgm-pfGeX4-CMqB{Xf*_a5Jn##eKl{-A5G^7 z#&J7-GhJdC7Yp(yAc!z_5!8wGk*B$%wBDb*thIY`*T!enth$0NDb};Hqh209EHMaa zn2#_9G$J%7Ie6bgOBaMrXCC|zs>IJrpWHN-@U?A3YBUvgQ3Wpi*R!t^EQG@`%)XM~L z7lq3V^0YFZT7)y~z)az1W{Z<3kQq9gGE^_)tU;nX0O~aJ>0kk+5vWd>C;d9!&{dWm zwZbhSmD}f0*6B%z;D7kYrkV7F(M2WI2LCPW5KmvX!SG>+Vx$2j!Y1vK_>%? zYK90e;BN)7b#i3hIRgO?evB(bKyVOD95$khT3lK31vS~)Fre8nzIh6Y>4^L)q;K*R z3Z6z8ha{&iZO+MdPI_XLttVbs4xRJRo-#m!PzfEA!YURY8;CL7wRo;~7IuUnKUb*m{Z0LToVX!YI^600cso$PH%<^k77?0e`vk7zOIK;GG6T;3iy{0?iVW z*YR$U_l=OADQ5# zmOw;$ajVrl+Y{Yl<;Lb2c|pj~?F>&$JQpw5*4`Zy$t(iIVaFki1Zt+n7TcSx^wLcb zU_cNIE`M9V(njcigG4IL9P;JR3eSB5QsR!x+^TT-_lkLo=w)y;h8Q*4?H0nFfU1FX zcSr6%MzV&~+jt~3F~Gu$77`d|5|N03AXNA~B_?;m?-_H$rGO7(0n38!`<%?qp1N&1 zXGXrlEf&s?8AZEz3lbIxNfM1O83`89k75D1@buL*UVhUAL9u5?E$ulY~y&(j@~Hvyh_6!!1xKhW93qhH6pC^hbk^`dq+@#@%rKQJ%iaKhUz34F$%6$^4pcBz zQwSj#HV4)TpPvKkg@E08NFYTN!UDj~od|!57#R1EKpyPbjq&;NbUi{Ekv)Y6z<L&H(luYE3G98sC2Sbg}$S;vYk0Wk_5BQ09OOTHK%WM zqhI;6#YF5fA{WtZL5d346j~1*>A1KLYd!SS`S5DIR}aJ3Lq=l)vBn-o>wjUK^zeGN z{CCaBf)Mb5ag@-Ro;V3Z-nxVg^=hD11LDeI1K~GvJHbg{UKHCWzK$N(>mH+mX{Ygf z?02$`SL=9Tq=u+i;qhG3l3(qA@!!$^1x?`vPLdTS?q5HDH`W$I-MDXdE`HxK#qItl z>hm|dm9OT^{l7D3^*iUR{eQQbvi6<5s{b8&_3`oP%jcE5Y&YI7cH7iR>lWW|b_tP3 zrf!*y9&fnYjdQy9;-1FKiC}rXC}aeF#4GSO+WqwK{{D3tGug4}*Ubylp_LlYpvh$? zrN(>Su4=rqGGA-FSK|@3z!B*W6%o<4*A)a4-8*m`Ltq0hcTL8m4u7qAt7M@A{>dr3 zPapntD~PNqjn)~)%$>+SS%`btw4mtC9zB14{8KJ2Mrfh^NueIumKf3kO0$*soonvP z(=Sg;0J2eG>j~|mn4OM?PNqReab~XIMuUdIEIK82=B zHTgjapAF=31VQba_lHj5pEV<;FO0G>N59N1Mh%WN%^mE@JRHXu`EZJG?Aoc! z9Q)EK^hPM!^M45@Year>gg|$r+v^zpnc)VKxf2)RHJ#FGgI_-{k#5fY9JM8r-`CG+ zG6Bt{0&X!}eS-%#0{Kyojs->oie$>7Uxg2_gZV<(AmY(bHne`l$!=Ix-oj6L#ubiR zMQE3zA8PM|qSr8l1`el24DqO##z9f%Wf&Q^v#@`I`G1AM@ND+L3H@-V3Yy+$MAlR- zR!*ZUPBd6}wMwQF1~r^VQ>bgBy@zFh7$}bDf#mo3(0?8g<0}GzpTxly7^o30#33>& zJB%1AyfJWgI`bN26j_DJ4rlah>@S#JA&5}i_iC>j^Yc~E)y7CDo*rNd^6t268qY|D zEULC)&3|r$hB7IR+Wvuh>tYdAU=&lv%+WqjaSofJG0||vV(ju9*AO-ufotEx<9l@S z7rH;A9tp>O7y<38+shd;yGdU{b0Y}*hGM8ssR+^5f zWz3faN6|$pqnS#%LslPjqwVHcIJg%FL6@uLx^3<^9~hkxI4E2Ln_h=AitnlmtcX51KVfQtWUOOXZ} zTt$tBbfpOBV5cBuT%v7DoQ2}e5|1XQ>NRZbL5;u$YojX}=Hb|ldqjdtfsPb3vc1cO zIIp;5v@R($DnigLnYJlasseE}9x*J)@wN9+8H`SNme8J$)`kiV$9NsE#xQtADSv() zNedaWUdHjLsAK(}1E)cGVV`sg7xM|Z*Qe(K<2c^U-En!{O@15vyCG{%!_|gUG*jA2 zk5qC~MduC;^Yg(I6EeU@A1Hsjtmj1Q*Bg#tS*I`$ZoAs-H_t!)^y`}57=syG;V0~*HXn#41I1mSTpdzGi1LQan41icM`M~j3kN&~21Cw*8 zSj;f|+A*eMl*K#3S1A4$zqCG7t9-k;O7vp@2ANIExnIs;Ycj*9ibH`xOV#M$W~xRh z^TvxtvxCn%h3n9;bg)}y4)EVP;gucP16E>`v@Tby7KYYvVi~JELuT$lgn!Khg2Z<2 zD$a7N!*C@87#Lz=fMc>YTf0O?otfcycQi9j+*BvWSoXDAm_ZtH(jymbqSc$jV6-1( zafd5pircZw9ONejZ14W&4rJ<`IrusYaL5!jPlR%j4I+Ii6c9U_(wMN^hHox=Zg;8% zpziY8pu8;gL>fSzXQOxk&VO27_Qbg77`ZMb;mR0y4L+`#7Xb|l&Bo7*tkPVOviRDx zaiRU|RsdE&slOS~LFm8V2+*ron4*5N83cQn9m1!Xv8g>byg)bly?|vA5m*|`ET%3n z$=Z%|97d@_;$eXc79JT^AI#YJ5u&ofJePwI5M!j%18H-9|37cdo_x4J6;}` zM9ZHn9d}teHqN{0*pJh3o}t5K-gcAOoX)Yc*=L29S=-q(T;_!qWc?^O&)j7;&og}Z z`mBBa@bK_yagFun6PSTCufTsSV7}LX9E^&9A6VsG_TT?pe!ZWgNz3@VpM}7UKpdx9 zPq40oWh}(A9@eq}mz^`x0n)o&qX{T4#B%42$nunRQh5pdsX#quCxGdFlQSbC(YG3w zx!GHiw(m-2vca%`$0*Qgp)lMOIOdWVmx|S6R>CNC1ettl;gke)4CZ*cFXvkP$TIgDDFftV}p+ z5dcr}8K8!Mw!vk}u%~}M(2q?iAdMJO5yQU<@ni`(bc)41G&6Gg(s;%Jx0b zkDkWg(F&XacMuthhRmI3*4HR59w=;6JdwZ%Bk2-f$gEheCGLNZzsy_D%X{W;k62nT zMp$G@47JFt>m^YqoYkkIx?wKKQI0yr@5f z0jhUIV{q6x^d+Smp!Si!vp<2+sqtP?Ev)l;)y?V8-lu-MfZ2h5nG{(P&D}RNB0e>c zqm_{b9bJh4TydaV3&4}A+-#cf7nujzLAd_l^IOEN|Ga+yoyiu5hd$ozZf25QY1%)t z+Ge<(LpD$GDT4?2AV#_x?o!|UiesQiSe=!dYZlsyn zJ3n3$-kiuymD6tV8eVPhA zXN!sIgdzxcDsR5k*kaT?Mmn<%V;S$vi!i5=6DxlTi*6F&5haE0SNh2cy#lMs;W+N( zGOA1hO+YPZehgK945{dE7{5g6u{B`e`h)I7Re-F{MS5BNy(7rntF@W0bu~0ri*O z^u@BGo+haXq^+SJo$~ApaGlp79HIpS^};^`=m+V?au;O2z`(iYbYBgPsBDWmN>^0t zJv<-14T=voP~(O;HVX&rC^8**y-}>nd(M9gGK7R&7<1?_Y{epHQ?G-S5ikIOkOqoY z8r2em)KSP9RO<5GqoUbHs)eeh#a7^kA5%;2g?`pojE;02-i`4cAVaw<}u2;v~YTGb}9|& z(+?g={CAn-N^RRfGOc2UJeQvHmc)O1yJjGG((R5P(Pxix3FOZ4Jl4fQS`z%>PRYdS zX;ex%ayoMV4OG50t^%T=5`vG@6$Fw1%M1K3z+wh<6}%pcL{1#vjO71VVI(cX?@)-w zuNx>wZxT~%Cyys@QK{)y z=$WZ$A3>&19&x~1u$zH?kA_T!x5zTHF0vx}g81GnSZ4x->9+&JV*0)+&?xmIu^G%2 zuUp2yyYY7=|5qsE@Jfst*kaNo6&w@0Ne&`i0>|5aUn@c;fQzw%6S`LgZ;s=fu;UbJ4upU9BgS21YL7|} zoGiS*#{AA8V1d|3xM;>`G(ZzR z*=|f=JXAJ}vKkwlJy@tiV=)d2pN&^t;yp703zTM!!_=2CU4#lfP=*u*C_)O-pRYEg z_X=g}g$e=FAIME{?AU+YSio>L&<_Skkj5nDYG-MZ>tD9Rv^Y+#HSnK^7o{TOsUMZ93}w1)7p!xvFq*04BlY@Y(g!eRz5|H+%szTxsmH zA%YXmaf&^HVUy>*zotka1z6;HLM;-2PRGm$TeFc_5X>Bon6{Rx3qllbNEnqF@0Ou1r8%afy)&0=fZ&-=aY&gM!r45jKTdWydRUpov_i ztr$sd{oM%Ul9N_}5YcFkQFx_RTT($v_e9xv*fDrKA#Z4C&>!95f`P9-UHSnu9>6%a zseKzFl}~;XM16ny`}%pKLE>;a6@x7Zmd3P%6 zl;&RFf^7?P8Gy53yB9PqOmwwoWc0u$KZ^}2AMU2y7fw@q^J zy*SGmR*DSkK|yyS4mX|xy}Si!=CdHS4*Va2!c5SfJ8ytU@l1xThiusK1S0T?K+-lc z4FH_fL6}nby`u##$^azfOl++T&HDxBC*?XQAH8V zs&CTSf;Ri4h)K$K*lCkIk_}l%EXVHE^f%~Pj$AsA>*FD(|K~l zqw{;rD8#yD@3to!j50FdC;S}{WT@a5t4`T2Ej_#Dkjz|+GK zq&D_fKiQ8o!mr_=B8B#sG|sFDIZ>QtdEs*)e~f>xZqe2SF9RS|o=^20{Yb{62qg~p zn}cc_+aNOGaQVc|e!L;t|9sa?dgJE3an>7u>5a4Aq)Trw4NaYi>P%2)s`VvUU!wJ; zO}a81RMpr3b>%1&ugv;s-bmhuFk!Il99cpGXORK!$Pq^BglijlYBP@naU01!cp5Vb z_bPu^L23>l{bAXvEF(1oY$7} zkIJ&eJlK-pTpuQn0E}Bn)j4QiD}$7FUK9~JDkHG+cV9A~__Jwf4N7-y4=nHhdd*-^ zJvc0L?W!;pSB=pEp`Ml|?0WQAt}=vV4DDSW8&c z5*MY?qL$_Jz=iAA7hPOgbm_*TTPth(qRiKQo-g}ZY^dc!Zi(yVKsk80%0#q{MP^$s z7}To zK5F??`**mpCx`1j*=}t0m7;&N-OjTH%v+adO)raQn31+VA;a}B59Y!|utR#~2V zg;)7X_4WFVvR?U0$;y)@oZ!rM3P+Qlt@a|Xv@G4|#ada!Ep3Y#ALcXK<`Z78o|dCo z)6Fjj8@YL=2{q@L;YP_oySuhpbG<5_SL?kl*EqV~Sx}D9``_l>ue1J@S?A}^3~_!w zcz!-S?sn8FylgR}*9LztUk^!KAH0>4WlhH0xBP+^{R3~X-+bi#;g|Oxc2)egqxz4h zkADw7#xov(!sb~@kho|Ki^g(f}SnmTp$Q|Rz{u)MSCk=mx%$>|8&P<=^y$Nv( zjYJU|ldI6fOAk(RhjBRncoy!P?9bO(r{nioT1aUC^<4&%VMzt|SbFF@EYdvm~om-OK&E$NLXg>Zir7UaFMR zH&sq@wuAm`H%Q81g`^yAkg6+Xn`r2j zyH3@|mFnY->etGS%qkVn-uZd;h*&8| zRQ0uST^-idQ7t!0j`YKNTii-x+>H*dmd$K=TW|Pq-JE}6z2Vm-o3%U4>7KZtYtn-5 zSw5#MtO`j>Yq9d;jN;KQ0`a5xDG!pqL*1Y!||Ny%R>)PvCM*!)yK}6c6D! zGTpt2V8bXNw0KcwQ*<;GRq})YM}S@^>6Cu}#?zgje4<*!*y|@*&2=Q%Cbq9p&PwU} z3C&~~5>S8PvKcc;0i1+S6O163#hUCS%`Db&RIKAl=U!*;4~()67Zr>m!#X0wUqOIC zMj8b8nADqf|%{;sme=Ex_y_hwpfaX+y zq^%Vg3@%}6iqK|t(-6(f(F%Qz75ytRO-Q#(x;ENVFlyQVJ*L`A;U+Bcu>-`^T$sHyL02G8+< zunM7hz^4LP0QQPrP7^@gL_ydd!IKF#ne=|5Cl+j1x0VuEr{&2d49-LJnm`g566Sy9 zl?=a|FcM6_(9*JKEyIGMV|NMxDw{MI)?2YMzA9UAX2PhJ$x6>uH8N$QAF7$mkJdOk zuc~q0pBsu%_rlR)V(2rlC4wTxY)CvSF*XHB>>OAx(6j}PfQ-mAhSH-0Xgx>ctTM%} zmdB2<`6BHZPL!Tl{GvtzbHLHjXr+Hsy178tW*aRe3Pqz!JAv1V@Ol{i^o;Ko)gn60 zaOkr&ATo-ioM{vzc5ADIhSTRa?lKWRVH&L2v++moww4+f3G=i_+HK5f(d-imy)~9k_@p+ssbD1g1LG_st)EuBP>vnx< zTtN-}@z+*V&?ntlJODG@bK~SL!<(z^U0KChXy8uKyRiy@k;VJ*`!4ira$$NB*AOV-prxgyv+g3$uKZLxpiM{#LaO4%$ z=f6Ds9^+NzI0I}YnGeFcR|2ExaF)s1miO%0W-+=kQ{l5&c7)xwOx4MT?z7^6TQ0e~PN9(vsc z){cNaE+ZbnOlIOF`dUh2oWxvxrk2^mdg)&EaSUfZWdKJg;7Oh|+Ow>9qZFm5I&Ev!p+|RkgTV)u5~FRc?R1U3TSydU^No^5%X4 znu#Tk&6gkq!LK%M#io-OQ6=||M)Uny(k?x#%>#mTx*Om6@%i=j`QscQ#UZSxEBl4! zoq>e-U82A=JSf&A89(4h-vWCa8A6IFeEZyR0)jINyv}Er?63w_IHQI-Sy1pabitmL zbBL^dKI}0NLal$loS(;r)4o5DNp!lv*>ms+4vqu&#wfgf{_s3Atnq^&rUr&G26`e% zGF}pThOoi(+$nd80A26i3|k8KI-RE^p*a}c)ky|Nm0~CPjuQQq1GP9kKMH^tZN`&> zJ-^Z1pPyeI|Lghb^?tcd&a>s{k_KNxA)qI&4Mly>Qn`OQf#EVu#6I!vjD~VGrL$?9 z&eLpmFLQI5KEl2u2yZ{#V1%?MfK-?)AFjP5h`^i6_wniT*{rUwQ*-&FquyRU3bd=hbvg&KBG4;doj|aKAbnSG!>H`PpF1TDjOAUmwxgAkO<9 z`WG~8;SMKrVG2j6_SbZQOqRmczMBu!bg);aV@;sIq3e|6a>Gmx$mQ9oyC&)4nOr9; zNA&b8o}L7!TW8qISs;HlQK-Vjk_Rj_cN?L<0tRhY z40EPbglnL07csOHpGvW9;Fr2-!Wj$a;0%OAp_3bNPAF&u(zrf+Js*EtMBWPI<_D}8 zVwxojawPCCA5EcY&|Qu&UT%!0#oz`$kL8t~)~1|9KizXshq1Dr+}Ssnt52)&rD34m z-JR9PWEOvPFBN;laZ+_iGZt^gEIi)CM*?CMgQ=O@=aW-{j z3{M4Us66W2lf|!yz$#IM9B8{u$KA_%b0j_2qYO@}-oR9=8qB}yMxH*%f|thh^NDG2 zb|?N1ok0_bjNb_FIN0CbC?yJ26tyZk8FyJFK)9C%$>)s>8ZgTqX$3e7)YrE$TMzW{ngo{_5MN?^4!N^=>P5f!q~~ zX>v|S!c{2k8BIyOb>w_Qn2yr^3|iLm!Jtn1a2~9n<4Sg1$tvi!!mpM!L(Ai52Vx10 z>FjprbRZ177Yd8OIKaO~5n3#>szK zU;?M`a)1S5itgQbez-K}NU(qE*C5cXLf8xkVY)>o86|bsFy^2W9GV{PIII27W00hnRlP_ho9cwe|}ilI%kV=8i6iD^=gECkU%B%4snzXaHbzHhzSM2nL0N&iDV%bfHQzF zhgDcU1I{4$*j>Kat`!xgEI@y0Z$%7jVZ#Br!0;~-)D(y&pbBvl4Q-r&;f_jT^zI+* z*pA@D4uN0+v*X6@Q6vlYNN_qVvC_?N_p|Tcrw`Bf@0Q`msZ2G7Wn^B;Z|TYJKSf_Y zEgO#Va}e%254B17|1)S2co@%H%f4?^&9cZC5dneFw4ncpU`4uCVUq-8* zM~lj|mFBS@Be;{V z5)pY}l)EwOl%3uMr>4q0eM1(8`ooo>{_xe7hPikS+!*7B=5s{RO!PVeC<9%#SYX*i zb)TSEGuMB@sx*DKKGxJrezpGR0 zjriTW`ITPft6rV{o3y+vT7C(lZC<~ZpK_U>{LWX;>+dzC|MGQu|K;_0frb+HwJ%Gq6eI4;Xr^|iqITIkHjzS7l5}jst{6@agZ4k8pFq^u<>yDo`i8A zsvx@%PA+9Kxf!-NEg6Y{e;_D#HSDcSC;*Q;7Qw&F3Ujc~cojw$kQgZJy3*^R&5CPwwJu%0Yza zvKvKQ;&~g%5{SM?r64pBEjW3NO?Tfg^;D2^)Ky2n{Imr5@%p}j+GgZ` z!M&3^MdT?$Im%5?s_|0F8!CHX!Fqp_1;wM&g?sGt$J9 z7F2x+*iI7tR>p-!x{L(?m(0bg5oRTYo~*Vm*$c#q8LiYA1Kl;7{!AJXjRjRX#t8FU zYNSR>b|j7pH{d98ZzJNpBZzh$*9GW0i`3E?{b-h0Hn|W&^~t57UMCI}m?dm@z_zdp z#!9mU1;etXhL!)5$zKhBFIW+jwv}otf=TfEJI081PSGe0H)F8IbGUTR z=;3+vQbXeUn0>!=-u7n}T3*=vIZ8M>uZRUo*;}+LGfN_u)TF|jibCJEc_)sb#37K<->=E z*T<(fKRz!)TPc=$AMJy}mG339J!c>3a>iQAp5ai47fa)RgGH3EGIun9fTEA%GzVt= zW#-iY6KB$S!%^CfXwC;kaEDxPl?E&k*e+g%$_Vwj*2kZpU!IoXY!Sy~9u&=8VqlIA znM@2~Vl5W2<0_=ikcW%J*`&-&2L(we&c%&zfk8P&sRaGOxZ|ZsE@!GPM+p zLXxTD>DN<#M!;VJxi4YXXG1xQm^O8WhmUGy_<8u{l4JLG)w;kS4eS-^*vRm{QGtDu z`GiuO+D8Z5_HNpSKAL$7%I&T}x#{ykqKMGP9#=k`fdpwR_+u*HQiS42&ZeNWsc$9) zOnHSH-H_eRB2h6^0M#^duvT;*>CAB8^ebK;f)S^G07IZKT=hWcE9LXU-ygmrwE9h$ z4c~zg@pXiWlTc#oAb%;!Uqp?3kB!rMhGs>Z4|Da zU(3tCynKFr^YM9M=Xpmf<-WO3z#XIK18vn{LedYVVU8tpy2eb}`zg8?Nx)N{+vS_h z*x?+194z4$!d;%JZslcLs%&A_+%~Sfw4B@138tEDd0ED;$2>UN)TxGQ++uVgY@ zqOIUrESLYJDD5=~@CeWqm=93OPQkKSGh_DLL8pGFc$iX|qjn!G1hp6SO%oUHs@~U= z4|_uSLory`dE@V72O|p4$n-mMm~bIN%o_(MaJewmt?@5E&>3`r?n9UFt4CFEee>KA z?`^HD+o!81VXb&tt6Ai@BAd@EN4x)jb7cbGe7OJn!^?aLd#J|xK2;G`n>_MY7VnNP3ipg}GLWskDF(^*X|f1ZLCv5NS-C=JG(r&V@0(@PFLe2O z&3!P%pD$=p4A9_IE!qY=6=k8%RmT=h)r2eQTG01>|h&Wz7}GC^a42_ zcQkukzc*eenK4JkE74w&({>>Dq*s)~U`=|Zf{AO!SvmV{0m$`=atd?O%Ah?tRF&y_ zrxMGKc4-X7xe-)o!QVW!EAM>aj!*8I1?^PaL0b5gQ$1poG>~3!GFys&t}%<_yla%< z_|=KaKKy|eS(uS<1!JtnFX5?appUIP%R@j|V>u1}n3F-KpK|#Q*>0;q&X` z^V1xo#Ql!v>GG&PCb{|RKtD?3!l5^Ttec8z~VIae&Fyq96 za;CoV=MRkX;6g<>7XY@O38JB$^08IA;o zHmj3zgBgH-B+F%`_Vt^C^ZM|&*QNF?VxlvZZ~s)H5!VYoZ5+t$Hb1|+|NFw|eAr9E zQ2wcHUTNZoHy`hpe$w!eRM@(x@OuY_^z+njRmNwd8Gl->?&0PA5)KEfH>3Jla08!Frb-yUO$Ug8bX-H74)XuNb4JMr!P$G7waUIH!+zzLj+ ztMgrd-p3i(Pno0tVBzfNA$SUvmcif#i+}zl zz#s|J5%*JBm6ujzW|}@+o2FOd;(<*t)AUG;xUaTs8Mh?gLF-+@L2>*%52k$d^b0va z*yhWDA&}vx7@fp@Q1bhHqn!}72O6ApBGDgz<|_u858(PZme0rzDe%#37;Y zB(Q`PLvv>dnV(llqoov@A&tL0=pVvCB5|PG%lEC1oeV1Jcqi>jqjf|gAB?^= z_M3Z>=_5_k&gR#qIZ6!^1=kpln!viC0QaU0ox z(&($y15o^s7i1=e{b5prs%Z_*jF#9oPs^e8(;q~{N)!@6$#%EgzumhB5>dG3 z{jyf9h;HS;Z^{q8%P7lm6;LN;&o6#*xLN+*Ue63WSm`+XR-(Moc^)>GhyCooqqFfZ z=V!FUKYse*;nVxotOeH;X~f#TpMP6_SW0f&KAa?CRl`hAuX3#!Qu~I*Px_M=Kev~i zJjTqo@2l1e7S#2Oq67`po9l_fJ33p4`F_7N{{HgZ`T%5+g|2Nss-F}tuF0=0-!s7) zm`e`z`c*uvThR&nB}uU~k(LHug;7ka;^mnvf%wuoMpElRh^+^Gb+w3!llr!QSTIX? z2~5X?Tlt7(fv1oxEwum7S4wA}m$Tb2g8IvXom-5cam_aBFUwn!GMd^>I;{GrZ~Ex! zYGS9jXlDYOb0RPFy#cHoBko{{6s%yZC^qwpJJN;IjyR=NO34U;>?97%c4lhFmn{jm zmD1D8Q)}4>j9mowsgOxHi&B?=#{(g@o-sAXa~#1ytN7}Qr7YZ}4{X@cVsPV`$V-O> zZ74S0Gujdm!6dF;5*Ra97o*#m(X9Z`V`thEB76t(`GN3Ka=jC-h5HXz9=df zNry9nfW*#Gg{;NGDu_Cn%0~HO8MVxfvk)w!VtE7O&}A_IbXD&=GtTHij*cZ^>j=aN z@UCUz=0W!h)RJ_JhjXQs;2sH~Sn%)$MPH>0lqN+#SaWQod9X`cj7J}o^?oy|23IP;x3oPtig|~7>Ye4^jyW9 zWbqqdBewiHN^~5oTn6@MFXjzmc&7y~5T#wP(=w^W!}hCL3*>nghblSO2Y>M10G056 zvQ{rOLUKl&Quo}o{&Yd#M%k~u#IXjt?b}<@H=Ulp#q5f#{^66WZ`TQH974OsSY7r1 zV!-^G;U?`3hQ!C&cMyR{wv=&3O>47eP2W{L! zH3U6^6-MG(0y4_*$I%K2&#!}m&Pa;#6Ev|$_LH5qGVq`!N zMB5Aaf~GXkesmA$!E}a_1r4qz-L*q{6y$YUshuo(%r1RL5D>Mc&`F zh_GoiZNb32H>}SNx9?5owDWmuC54to;TdyPt%&|CKoYAEa1m)|3hedEr-8p=R}*R=Kui=h*v zUR(}@S~6h?b4=~6J?@N)6M_(9g#v&2$QD-A!pbznORJoH%_yUP7{`~rZn8u%q=_=b zUR3T5=;p%UD(K%#6ZAvWjT5UYm{YY^h!5Iq<&}gx^-_+qb%FeEA5X- z{dV-aac8kcS#0#m*U>BM>-jo*88cy?N3U`st5jnOo<^^*9=*ibRoWXddWG%ih2a8J zu1R)1OebN7;j(fY(>&~_I!Cfz=(N(Vx_Fjp9Ti-L*5^vL=vHt4n)o%Cg zNXE_RuW=Ecj8Mi5pEBh(LjHMA>h z^Uc%x)w&ATy6Ua2`fFYJf2ywfZ&O!ig<4h>2^D02y4)=D^Y3ig<=V276*~fvPsXn~ zWdyu$2tpn1!wIqYdCyahdi?zH;g_dR-~U>DE^@iZJ4@qKOJ{70>{^aZ;W`UYxK_hl zJEytI#$`QP)h=p#(FPVR!y3zJZa(9+NnM-S-1JU!a~#_?I=9@t`aH7M8WT|MP9)_$ zU2k1~)avP4U*n<@+nQB<+bG9oaKW?73a(X&+RdunWu0H|JQuOp^wBK$$QQ|9qGC1> zy`mW29&N>L-WiQwp5N9n*WF3-d7!Y|k@cp{cvr%mMBvHX7x_r`?A3jKSJYbEyBM0p z;n%Iqj=nWpOpQQb;T^?vw<~lmX2j#PzB^HW^%qM`&}k2_#b=r2hg$R?C-7wyR0b$X zC<4M5G+==NnA6Dk$3Wm^r`2T|4pq<5Q4?-@@)8=G#GP+!8`I_m-ysy@j?pt#;=x@rV_u7(W4?@@c8 z0{35|SeMzB213!M9z9j9N8S2sAgt8wGX@Sj#7UEVbufRFCwGb**BG)h)B3Hp54V47JpFo&Cl0^%cGh|8^!Sz9UO7beEBc1I;0mX|31qV_j3Tcpuu^QjcIev0 zYZpDD?V@Ek`9&AId}!Rx1+nN2wZKl-QXHG^R14h7Xc~XrqRy@rxvFDmzOnAv?eiR; zk+pf`9uoS5)?61Ycpg_4jXl7{aq;I>xvh$grB;6n&B}~LHg{huFqK!LbRidEX=(^0 z;+1hX?N;O_EW-jML|j{86~uHWlScWMTGOhTbiZu`Z?8{p`D$OgF^smI3jO(krQPmk{&KEAEswJwhI{3w{Uzca{-;$J|GKgV^GX@fk9Tx{h(2a{rVLr3~ho*FEc+Q5X9ni#Tv2~r3v?CQko%w_ThG{C4#jbZp$(6rIYM;M}J4u(*sXryCc(x*h^?6p=^uy&o;JA{rvd>E1MwTX(I`{azPzpj7aU06$agN- zyhzih<%dBH{w0&@cpDl$*j3%LcpMZbcG-&{TEm^`uKL^by2ajiN|PUX8C5Ty#US90 zOX62Y-eY$+hn*toRC?TZ$ZC*a9j20ap*Y&IfGsN2TUaQfRqsd|6ZSH>?>zehKK@S> zArwAjbg_Em!8xspfLsB&OoR`!wLs^X5 zt(W|Z?vvShYB$A+Ly+&oM#1&6q@{@XcB@b7{M6zKNT+uf+HnF(9E|ac$BRq-BH3Y+^gI+L**olKP z1DDf$UM6jBQJdAE#e^P#&R&1NGlm}dN}?s#T{GeCv$Dqcx2Lg7a(|VcQeY*erzogHh^c~mhqG-! zd)3#D9@Vv+Kdi}NXksg9jmaw7SjvD+6GvING;ObFx4UeO7;`V8gt{`IvBuBVG%#^a zH5G2B>}lIm5~*4*5|Ki;gA>06DKNHR16^=iAPx5fx9;`cc0k9xC6#*B=75fyTkSyngvI<3Pl9p#ftS2P^zV&6Yb+Nv_W&_ z3{4^rtNsQjoR3{?OW53|uP1n8$-a@wKp2f;i7ZFt6B*2zTKw-wIprE8e8wbBzkwfs zP+sa!oq$8b^j`V&!0;^)PFENQ+qXH*7W~>lbAO092C{pA3A~&X6h93Sr}+zK#+kr; zJf*!L=_t$F<@Eaa_V)DY``2~*rYe;6y=n8fsE7o>eQEj~!KkZ#S6aY5k?e$NfqurD zO1F=Kq?^_`_AlT`yZD_c>*ej~?@!Zm?{Njv(~fOglG_3u+yH&EW23i_!1tcO_j0ES z-hXW4rlt9b<=3~tkU?w&G?XD=6VdeLPGEOWUI!AslE{i535=z;y|&08JVEjx&Blft zO#{c6aHm~gybR!46|f#F^6hx^!^6|dyVv(WJU_2xl*v}0kkW8><;0OsrQC~qj&cbn z(Uo{`oKFkHo-N5AgAC_^OcG<_avQLBntx#Kv(cMR>$$1X7WfSdKp2G_1S1f;K-gln zJYZjyf`CvFGA&Z-12x;dc-`|ID+9)=GwqS_By&6+v@m;nF=m4tbEgnq-rhaDv=egT zihGc6Sng~F@Z2k4fstrMv@e7e4V1~IN0H~Ntb;TooD@j)Mk?G-E2;~nDX|6g$$vx_ zOfAHMfwJL?3paE$7i$vN^JfK@jx10IK`t7CKzfsn&k#@xt>QsO7PyF?(!$$HmVg2y z{}5W0q=*Tyvjb-!1bMMgoWAdiB3fOUBU(9=Kyrit2}Cw1*zACyMTUu=vQaiV$b1M9 zP^7tHlNLk8xC*c^J;Zfrl}~auKYz>k+>_Z})MMZyW1I1HLUXt3^zi{q5bGr=H;TOl z?`OydVH@g+@x5s83O^a8!(bpD7(Crctu%799MEDTk(ybe+b6lzQDAUjlBH`Z(R`u+ zEjK$5BbdLvpXBda5O? z0wuvk2SeEvrGX58h`d*w&^fQTJF{b;Diy)wk}a z;q%jm1d#HyVM%oF?nE%@cHBORK1V?=ews*Z8L*pi07)3b}%o}Ceip{BLUtg4aztvO)ppxPj=s#EM;Q- z@H9`roS%52U~%G&cYjJZor!asL%cPwlZXs!1hcuF#7xFjuBT1N9@)<#0_xU{Z6{+Q zb|URqW}hG(n+g2F;egP7+)sTItTEB!b~@~qdJ+62Qx1$b0|WQq#4UF+fg)4(Cb1G8 z*nR7}hmXzrsWUdy=uV7^6uT)}=E;er?kpzHo~I~{rLScLKYu1O2*T^EtFV(&08Bu$ zzak9gPI03S_IQ;6LM)*(N&tlHm0PKO|Mc?yun8j+EetdZO$BNAjYx0wg zJW;K-oXi2885;&b9?lJ5koh+@K_zyt4gStF|M7L*Bz3RO{|RNDQH-fkaOFsoZX`8` zG)^;s-C`9@&fxIW%JYYRI>+Zaa&<*xnXBUzX24`KV${^dz2|>*Nbkz870-TOsI9jD zR|wKc!~933zA`v(24wHs{fzwo)v!zr!D%;)KhvUQq(tU$;6)EB*9Lk7_w1QF-OH|? znU+U8puPR1?sc81c`PO`Ed7>q86dLDxz2B{`!o4VzydSU37HA51of=VuZ!C|`X0gY zL*Jv&z5@fX6$gJXFwU`KP|5%SFX9rRG%0W!P;Usf^orTgCey3Cj9mFZ)S?R}g(&|j zydR^^k|$TXd)%RRBX)W{{Iirtb>T2)=l2!rZe#w}3s=e_kaZK}BT2mxDVJ-N+%Pof zP>sYb<)PuvUMd2CGVgzTZQU4)MM&%f)cMo);_Y<(e=C2jgtJAs_p{Nm8s97{aN0{@ z80F%&D41Lnv%fWq{~f7*Puo8$wk=_vb0X%l@}BB}{)2lG4S^o2AmFQ3)9I|8yG=^psbV}skw~sXVPMxA-xC7fp!&+$K1$b-n`BRh8}6M! z1Lnp45l(+()BN8%T;5)zX}mNy=D#xdG^4Jg1a)Q`uGO=sGEdJKD`pTE!0GzLKRvoW zzHC%!VJe-iqTp%0nDWn1c{bo(+S{f7`1Jna|MMkVz1Jm+#G!|HavtrG%Uiu3GL1UMn#FW~qoBC|rvife=qH zE%*6{vf4SLwcFh0O^?obVbTl`ABnQ!z&H@}-e;3E1GnO+e|i#=m^cv~W1~6JKVM)Fs(1(o3Vgk|itdL~7AtT(kg@ zY%SS@gQZd2S1L)}8R`p8i{zX|U`S;JBz3F_FXoeQ#MUFChgwSLn#x=Tk}6rL6f3IJ z^>sVF{->Ace^2i|Jb(G_BS1z!uQZ^qE2Cl*`QbG6WSN0=!PmKHzS*8rl#nac-9Ma2 zXec6UPeqW#XHW9)QuPFqDGAV8eY!qyCh@&Ji~aO$ zzbz+S(xbUPIp6*(X?%J5{)Z-!lq=wOm_)vfDU^hp+qne(3p^`eaqZ5PY=i6_+f75{aTGQ;$R@MErWyGoE%bj_f%4u=` ztxs&~f4|haD%Hb;;d`#zPQH2PMW%VW-hS%~d-d1XD(Xlmslqqi2@a!xekTKz*!|o0 zKYealI;nU=7Zu@b1D#bQ=5btSn2c(!5dxG#q%WVEQ*;*x+>1cGBlKqzWi@?8YR3>OlW`7`E7MhI}oMnU&vO-<5hxQO&vVS2o@$;Q*` z`{!x-_1)wDS$PM-B7%an63d7RIDQwu!{+j|2!zM90E7Kb&`$Ejf;hq*v9+q|s=_qXU;V7f z#Giv=caDnqb`(n@b8|0v0FNoFlA)Xflj((SWRS4-YA@1MV{WPphV z29WYTiAG*)v}lVKhAl+%|~Lm4&$lf8#1P z1pA-26kcAQf8MSpu^l>PF-2S$O-60C|J=sFV%RJ=k|@Pv&!p9nR(QjIY`N@Mr}7<0C`>T)k_4&C{}I#BMw>4a-<{{6d4av>aGIScfNHw!co_qS7^xfUnCe@V&HxVWru z`pt!W{UD1rT}w7u#_)Gc%=R=GD9{nHYd|()&3+oFlOYjY!M=fM&f*Ez{aH+YA?h6E z$3Y8-SOqvysKQ2bZa@@cBv=wg!D%c`OypES)7lwj!l2F2v?b(idmax>CDK#)HPNL5 z2T2$8auHEwO2SZl8OazGe{jIG5z(&%t0^%T3L4efATHUE4K|-;MG{*&u(KZKzGOnS zy&>=ynHddyB1rUIkY(8$;cCYd3f&zRnHdmt-mB5&Ag*AmjI&ZY)Rgk*AknUY0j$#R z>c)CN(m347&T2U|?O-Cob-G{N-Pc$2*Vp3K;aXHURNom?^_G%6e?O7!CHeZ|Jg1^u z6H(?g4A(pDa2)2>mHPepquYUQ9kciwpohN#T>Q;A$&oD#WID3C-hxWP+jwyz6V2iz zI9aEMtzE#Hi|7=0Gq}6tub)S(+Vd8+?%C}(3Q-fqpe<@0ZP<8qphp5rn&xqGd^Tx6S=3?PYfubVs2K{J6F2j%Jj3PvC zEMwZ~_Dk&X(}(rGU=*Y2K@5)5pN7Rj5=%V|@C>TQ*qO<0GBU*8DTpcAe9jfaz3Yu= zColve!Ky(y6CJX63mbSUm2k(CtkLTLaTQ2VS&-i$W$V-Sf3-7#@{nSiHIBimCGjSr z$kp7yJ=$~9H#?c9G7Kn22R3nrVEafr1vp-I3-Rx3zLLI$iH23P=-XD4H~)LZvP3o4$$V3eb>)x?J!qo#p*=Wf1yPwkYrK>*r4twHwWaz8oz&A}7~aPu z%3HWNs{CgVe;?e@D`KH}$~R>9FcpCVx0ivvBOhKkPl;`ATYecqwhZ=*3NlaP^z`JS zL!fNjZ``Zk2Dt7z_~-E-P>mqCKp4VwfVY$jDAha}OUcfmorr60PmKQz>FAwOB09CVt4;7)m5p!zCCOvtp9}raHQxN*zZheAWA!#?vhj) z{I(_dx(56vIUni$JXKzIA-OT)=(3co{7G6LcG(T))S6#_GlShCVQ+Ya^o{>#FD)DS zYi@O?^~7;n+-)|n(>Vx-#+{ukZpWovH1hO5KD*Vp@9$@q;gno|QAlPfoF_uILg3C2sL!yLDLy}CovRkM6M4&hsD*_SZxfkYi&P36Cu`~6(*$Eu9%@mN`6 zX&LiEhZGkMcG>T)f7*zgTN~eZx7$MXgC-x z?!rk%6wJjL#JLnyIO>ad?Z zC@oUngcI2G>!Ra$&!KcWK`E~L;W8cKZo*clc~9DT4D(ybtS|q3IWb?Rg?! zOm?>{dk0SHoxGPHx+S=RLi+IT{ln+Crxon67JLq8CA|0{Zs^iO~S-ZwCsS z0IWes2cwoHitxJkOqSNGd^6FUqvtk%GZ3XY@bg^V&q>)$_Dye94Xw^Kw0aq&2O^BS zq2g{j;dkmKOF^z2K`gWGASZGoi|e~Etvok|hkilgWXJqG!2$oYb$ zn4M|u;~?AT=4_Qt{NutOSrTwte|&!Uu;%^~h;ie<{!7*Jjfll^OpAH}`eX5blXMEO zyTG47OZ`B>S*hp!O$eb@e2z>{)M&l76~E#H=Xd{#g|}u+%fx(lHWU7OS)SpTpx6WW zh(>A?L1IyP$ay~#J+g_O<`0Bi4+hW z$ujdMy>tY1;`lRlnr3E zZIQ%Lqo9>ZnaiZqGU?|s(U@?SQf_~O8@iKb03@s_>H#mXsFD+`r^!fvNf=GmGiqa$ z`;scQ9z}0~=mZ91Jb_3N9+I#JKJLXA1Rk{@ZFhiBJvWpjf*rg9I8HTjXGS*^^7D0! z>ggy5&-)jrsBU!;_hk zHh<~-?&abAW5efJ7N!am$}|WrQbn>ULfB&~0KYOW7UN!?hK#b5YT!udTOQs{A}|4o zZ_Fg6`M6x<0xXA?j+2<&Rq>Jjo;EY$+VYLguz6Oii025~jHPR1GM{+sV z0!5%5NfQz1TEp$8>(Bw4)(za{MSnX#EoS}=`TG3u^7!fPhsW1;(&Ap~4s?-%y7?@w z(7s>zJbDW>X4t@eCSL({A8Emd{sm0Do;xsLgv4b!T<@EYC?S8)h0~a9jtfO6T$>QOQ3WU|s&hco$}4yMF_ zJvzHwInDP@y8+n=h@-(A3xCHd9ISZ4JZj}s@4A_gt(7;4tYI3287XPOs|@~h7=3}M zpaYNG0Q21zMr;h1y6C8KBU&zZe~l-`>##dGU7rCP=`~n7$lsEX0q&{b^P#s0e@ZoMpO;6eU{P<~QfsZs`d*WrZcG0h+A@jZ3gnNpms8Q{IT1J};vNpbXJz#4YY-(Y{eo!3vO4p7!-K#b&k*k8|vgA{8A zQ?4CMrB#1Pd9DX}sDB6HavP}OIuJk4#fc7SD{7PBr`H+at z!u*k*qHqzxca=!e9Ns|w9Og)eRFp-lzR&4zFhAVkzj^Ng#tTdvBQ@Z0$Twz;?tGMt z>WS~pcwy36yfBFf9!J#lO-OxWo)g}hSZ>szO8h`dJUr|jl7IF-Qk|P1Z*cZc#Y$$H zFdz0r8i6RD+ulT?_^4MkM?oJYjXYBlz;e#y!G6Fb6Kc+E1lU-aHzK&1;Q+c26hbhj zbax=%2TLmmjF$0Up2BN6nP%`N(>##zsE*2kMo?B#xOY}_M6k0uAxW+}u18Sja!##b zI#LS>SR1m{kbmljO{pGXiPB{?Itngq_4AEWVeAr*l zW@W_n%AV^Fi@#iybbL^UJWI!VmsD;z%;S8>a?uWtwSU7SRJPM$R7Fu&;d;ml*Eq*| z)>3{@l>^W3)FN=`5A$JAiysv8o8>Nor9Hw#x50)Ml=?h#yJ(GhCh|C zCwkY}D*L`zb!hNZC234m-Cd8pjlimD4a{l)8n4wZG>ogcT#xns!5SB*0yQ~J5Ne1f zbjS92J+%Jw{skVM-2lf|}m9vg(2Yo%L z4;51@xe;s@e5pOcg2V+7?nWA{;+UP6oQZ9 z;tY9e$O^Vny(t&^w8E@i8Yp?QpQ3kf&+oo}ZZ{#4Q5QzQtJ9OzC}mqlSraLC5)zvA zW`DNLlceVYVThuZtwO`J3cE@@j6gX6tq95;$gs<+RZ5Z$3%7K^JAp{9XRutl>;j^m zpFaJ$3ClA*Wz_Zwl6-3w68&Wb5@R4eF=+DjbY@*#!_kPjUI{0XRfMu|dj<9S?ISaO zHTL3HA~(4Lu=rNlEsIcrnnRb!2RVkBzZp1NVq7UaEL$l^tvO%>`=ZI~Vs{0e?v)+!n8E%g?Qf*R`eZzFxfRD9S%op~9zpNmYDY zV@xFe#c96zYPS9Z+Dy39?5Jt4yRyjXRD%mF>sTn{7tqT;2IcQG6J zB%o~~n;#HQ$1vb~hQ1c@C(kD{Z{^rM;CU@s$t>>44XI30oPItkqch`t$IFwQoEv{q zJg`ihqKpQQ%bXTLbL}c!xl|rUCt`a~+ULq;9uy)$Bw?tW&O9Ft#F+5q!uV-NzJ3yb z;L{-y!8m;yNYc(+DYQFciyrNexwaz`un(m8;cFtwSFGCwAn@#F!kk*@{rwzmE^~@M z-tGl2k3T;D^!V2w6f7LFMn}%kk~M#{aS`ii(T{UHWQ~xlA(J(PauHLR=j%78k~Klv zpQ-qI>1YoS514)oHcbxvMP6ObFS{s~YwrH~jRcS;5+SEcJ|~++jNf=C=RoglSnTU=~55GPuBJlND`sDWRonCSyv-<>$E~~lVKiJ->9WR(TqQ6L3iZTChNF8C- z6)VF8tj?0lV%VHj#%oWfIs}i^F;cW2M z-tWpy1KtR0ZJoT+* zq}Aq8PGF~ENu(IQ8C+H_Y%PVbb^{TFvLeJg^csn-$MN+`8EaYhYi4PhY1 z1O;YGDeBi}Sp%DU{jGba3#86(11`!)^xiZQkUtGAu z@OEq;NsLL4ad?1OR(hhes?J#H7PPD@vX@|R+cG#~tjNp81mvVkPCQK{Tc1-ZMGXMJU z)8ooJT?K2|(TA3~KYfMRpS8KVPHWR@Mfy81@#I4ZUrT@cTA&{5vrCw1q%of@16u)B zS^h>e*Yda9UT3=`dtAR~Qm%|L!-0-+Gf;Y3QRhDV*ml5{1@?88LwwDWvkKyFa3|#|ED-ymV1YSt^a*2&`-m};p zTV(*B8q|MK{5jKE%S&lOM(N0kRw)_aq)@Z zQ1Y7MNKh{9o&4@Q~$k7Mm93su8gRp1(RdP40a8F&Bbry5PQI%-+Wg|3VjAQpi*{f z^7$W6k2e)}x>ixATM6zM6o;@jL{k`m&Q*9HR17_N;Iz52|7k&Bd<{k@{fB;$DVc~- zNdJFP#0WM-E<*L+nI_mxtO**{>LhL)R_Dr%`_ftD?3>$nf<;7xvpU(|yt6xNsp!^e z4tIN@EBqOE;!|$j>x`;qog!CugJ6u-MwIvMrCvcWZvUCURZrRts>wTP!(6&8=o`20 zw9C)GY=p!p>`t0^N-N5^+;giU9tGHcJBoii8dp9*U6ciY6?I2jto^qEo5x1<-{mrhk*Uoc>7&2fzBA}7F;0oSlRU>o2Vf7 z;Ajv5+kMRDPBSl^PIjRMP+J&&ZEOOo<#pB z0?zHA_hniFzqD@DxH0pu7OSM4UvEZBBW*LiWqOkqd_XbLN+q@kM&;1Y*prlnE=2~z zns<>HYtjgogVaMw{820fs6T&E{1^ zmpSB2gNrluj>PK&WH~qurBVGPnS40O2*UM)47@`*j$h85N`>&p6=Ou6=r{2kB6RK8m3sG z4Fji=fqlMI37J4K8Z0;MY*DxZLY)@JV{@K#%8p7TMNHd_W(=Z^@6KYJNykh%U6}lP zBbmtwD^diEGvY0}BktW@L;k#)rHR*G+smk)ygti&ht1jB_m;E9!p-~R?lWQc{o(e# zg&roiVvY1G>dCOe)~|mqyR&xMD;)g_M88sX+FW-e;VdIHF(4(+fSoHLFGBI~E7@iE zsK%<=ZjIH$=q4VcQRgrP&?X*e8%HRwyhPKy+S3_;*coZf*TZPngVt8)|AGWe@9+w( z>wEC+V3B};b%7xc=7AqzGavvVD`AC9OFT8CQ^pDb9B_!B2N8cnM|?d>5<#{DHgjNV z!Q^0D-5$a~1Hz35pfE@b6e&X;FqDy@3Ck~0xY_K-X*xN(9%0_rQv~zzRXCgVehgXz zzl<>pWUzM{pqx^O&hD6O>;@U%C_aI{uOlQ+YAnr}<=_V8klaF9rA5VYD?xuxa^t|Q zl)51Z=edJI1(1I>&Z@=9kE7$vu&Ius6P3L{b*vO==1+>xLQkglaR45If>+WbzV z2AO7urNQ}7_r;nQ9qZaF9v+t&uRdypq_vRa0?8YBr4}nZIFLJ(O9ZxUEjfA)@k!&I zVXygrW9{{KrHyCuNFUaNp*~sIg89P17C)Y&2udnS=JS7it!1{a&CmvBnKd&m%wu3A zjFf+ZRkyd_iDB2%au-2Om}T%AmNff~`=MpWIPU>7qdK70gQtP~`>y`Hs#@b-DaqQ0 z_&@E*gPq|AXxa|;F`dDDT$95)w>kXq^!D!kO81o^Wb}x2S}Pn0_|~s@1alzibG>ol z{$?K+5L$n6Mrd)Nv{&jiO*4RYBl6TAzgp3N(yl5QA7t>6cf@WC zm7}l_K0;k?vZykXjAN6+vOfkB(ViZdhHfiAXG4_A&uE<8%mclrA<3`qL~|_?{`$V9 zXhMG>CwPY&XE<2d{3XKKOgha72Nd%c+fL%oT#t3F-vbl=k$jn0f$=T1J+58q0y@&Y zg_>z`mr1OWD~`2vDJ{8LI<{cVau%PZH$KaRrAa|J2rR^I3x9uk{=7z&T$~&&mwfD7 z+3{?e*s5cID8j`=F$omPBQbee@=i@0219?Ek7?WN_dfpa?=O!#$RpFV7`6d)GrmXy z-Te(v5)%Z-7j@k?)@Y`_2ldWHZY2QYSE3xd$^H27>BH2JK5uwSQCL@hdHbr|7Guwp zuhWd^0dW1y8Kr{Fekwjczr4LXJgsF);r2nnDdzUresg7%7k&Q9MNgwVLv(8$5422I_WZHk!zqsP3`ybO1cfQ!KcE;;Sy4G}wWE#Y62<*ps~I&ce-E4M{q53t_x(Z|t{p1#=M%**#4KtxyGNhp%UPP6=9#Z1EOf zzFV(aF-(m5Tj-e0G|zZ3glB)L`cbBfgAkAtWXi%8kt3F0Z2w9BduQ&8q2A+2D1v8C zf%2JI6egSs?#b$=uk$Z7v8I*)JD(T53bx<}J_+5wlfCcWF$@5o0i}k0+L)!4tb-+$ z*OdcMe<@?hSdL7wj&K%yl7GSR%>frmYW)cYdYm<0t-?Lekm@PivsZuAdtlc87Wp?T za;|yq2PgQ_y~nB;rc-*uKwmpu(-w6)0GWw9nTHd^?POiEi@TNgx>iL^(=K@+cQ@b7 zID~0;EUKSjT6KcA+|dVbs)z-NrJ*EI6`3ql{kgl#jO`*!13m|1uBE**^QV!ru({xd z3x9I|o%s_tV_8ljVg`RqMe+{|G`W|bFQ5MY{PDx%hn6=Kyugea@Pu7BA+@A)3QT=v za}JfnI8AfC;_rYDIExy9e9Td6a7AEyMY0tOZ6g3U85`h}Yzkq7^_qIU;XwK7sY7G|TxhE#$$ZIn2eC9zA4GqPJ%*hGthdM1ugusS zgItrCPwtE*|3LG#*CH)qf*REMB>u*)GcnlSD{afMH!^(woyG-{0XX8+fQ{8>4f5-WE&#Sx0vp=qeUS1wQz5nIi zcW>`od{Pet@3eo@6_+*;Ewl~vTI`!rrqL+)o?bA6kyXPywIwK~F)%>GA1U(y>lY;l z(jq)CYoB^Ofmjr%QuQ#|qgTo;s8BI}(xS%bhb7b*Hf1^!^Vu*Jz=;zzde9o6{*6>5 z*Rp_)#^&$MGJ5>-((YVf)O4pTv}-5zoN0d0mVxv`Q?q}N>Ubs)fUpE7g!(X2)s#QW zy>#~mDmTa(jd9{$#@?w0VJ5{Vyu{+j6w)D{2;8$o>-7f_S|6vzjg+iafgLXpgEjIQ zi-ers5)QJ0Bh|D$i}aSWXkZi_dPy&vHe661^Nt*0Q*R~KzBkZCPx0M4|6!sac?rR8VFq8%X z9vvZ0R5b{67?8PhS{$If>F@{~)`Iy<0~YFuZ76?(nm7!q7y%8ELKqz}1=IA;b{vol z8suT_VkjxUPg*j;2jtiHd=H^6ca)xH!qa_B7WAnwQ%9yqPquM*f~Eq)4p|XlRkID8 zj)K&gF!D9@)kWDEMKU2Ju-FeaMW(OxxTjAqD>Z|oqkaUPsyWg{;mK{m z;edbY(>01T+r6;(jBEi_Cc`r=fzhRmh6-49K%C~@whNfL19~^7xiMSXb2$xgF+1ha4EN_u~4 zVgP4>%^944R9Yjm|I~&-Hip87&k=NigAx2Yy6uAzw{*0}E%wBj!A-->7v9bk zUl8j~4{&fCuBR@}zrcKOz5)bRf;jZ_X_Od7f!%m20Fgx>r&J%I^p1f_W-)>xI*e4H zxZ;?j43h}5fSHt?Hp%c1d4P4(m^6RCgGt?ZrKQ=WSVN>Bn|w_aNGTLMl)eoQC6VLI z_vy?OG38oHUC4CehRxwKoHbDa@S^L6!N6&7!y06v2=E@L48#Ftuz6RreWpX!kRdji z5`#r=b2dy9#}L? zB|@Lrz}YH+CmPFWKXwt^YK345oD9AQPIS>s#SjcuuzFP&hA+mgN2Cx+wD@5~ySMbejo7{-aKbQd7DEyJWwgo9} z$JNS?!T-a<+rxJcubXHZ%y@+X{e(+TQ|8DTL)>ve!^_j_Vd0E0j%Yt^-?);Q z^9A<9A=afA{+K`1##5$Um=x4E<^Z?N(&6rRADk zU-x8e^o)Nj*XkN)F>bI4`%w3#GN7Eh&mmm^8^&ZM+R@$;9rKP17FV7es19y@A} zF@4}1!Uzl#h2;XLa=lHncluh2e_G9>)SqsW)ZhR&N$$4SNQ)Dga5QTsR7@vQt5ZtwmvJ+v?3s$%pyi8PfItUq< z4aXzJAb+~1Zd)+#pMHG!I4zEWV%(5gt)9P-eCBI4tcQ(u4VVxAb0`FNShVk`HY6LV{{Lbs-;1z#BC4GF{ zP*g6r5oB05VC>cmV~9jq=9y zayy1AMj&wm;9eEtUR6nk^%87QZNn)y zvi0}pm&et}_`6E$To~;HJN{{~xb8@u=9vdj{>eyUP31;wR$&n?Z5P^&^Ab3Vk+^u#pD3_x!3O|Z@-;GeYbqEQRU#A!CTN_tt0`yE2rTN#G!1)vxK6Yh-%(&aD8}u{m17Yots8$<)s6TCYWfT$j?ppWV2>P-~j{ zK9@&;Ax(vM+*v&T^!V}l^W%TZyYHUY@ifzN_QFj<-;T0jMO?OmQ%8=>Yj`asl`u^8 z+;#*WQ~zn&jd<==h9g-v0jIcXjB`9E$}+P!I*@{7k$O7$$c)~Rmoqs-+)g$zL_M^M z6~riGd{=x!(im;x$c2|W1u<|mA=)5qsbxMqJ$(H9@L|1J9a>eBra6C#N57FZSzlKn zH08Pyy>Dj2_8Ntpn`ejidP`c@UL;FuXqm73_VL_;w^vsKsPx%b#g|Ra8l# zEx_h0oRHfB++1fe+P9?DU8Q}C@3zWG}Uv-qc8kvUe^?o)--ze^H)ye*VN=yI2mDZMdzbezbD)V7`z56CTtz{!^KC()~u(|pN z)%pkD{Wt36_eZ_J7t#$E3u|FuY3b)M6-1Z}bM%XgBI)q?Z}!PP*FIDMO+Zl+t0??9 zUABQh?T!wCA?SbD*t~R_)N8t1hrrMCZQBpcX*dfdHBiq1L|-CU14fDgFs@vWb7rzg zNGBpMK_*EYc2DHlAYa5-k?%-nzFvPY6{OCck_pRXaNX3yLlO@Q z8RRH*|zB zC2}R4gzh~^6M8d`;u=GfqOTA1Y?Pg;oReXi&x>R0dY()H?l^TGfn^Sk@F6)w@8uHh zM@DpdR;+&*Jjr9~m|5bTd1z2@Z-jW)qp4X1fN2V!>=EPKMSF>7Xs6zdTND`zrkhk9 zvz`s#lZ^sY8x$S~gqe^aK(`|zc6fHbsQ;j8Z)q6pQH65u1^AaM;bX^KJ0q8@$76F| z@WzgGHr`ORMfk3vp0}8lsF)Q4n2nSxW-G`RH$Z=shYrU1j1X7GcFty-Kzb8Mz9iD^ zp^84$Ly~))6(EmxZm}7Tu$sb`%unryi zwQhfKMC0)}9J0BCA*^t4j@Lt&!g;T(;=CCEwPdfeW8so@57VJXnI@J{sA=`6E9x;$ z|DO{>eY|Xqq!h|*{XB!1hLhdFz;Hsq0=l)K!eFc%?!6t6dvUa5$LJE~I&qGOEQ~Hw zYAasB$Q<@vm=6iYC8?bA^|^F!q31&4_F{j8#GX%IBDh z!FZWW9WwQUv5At2bg+CX>n6{T`d#fD5H9UV;viUIS3l>*{doVGN@V?5`IsblGmxs! z6wrFpLUWwi#m>usAO4k!o1H=8oGkzbdlpA}pRb?bCwKY*IH?}mxPu-@d_P9IhJb(H zjDnn9d^Zv%*@2i%$T}LFYFZ6 z%OeYGCG13kEz;RAHl}fV(~pnnkPCmqpR-7oDV`;&+LNe%r`|mvrX^RVSVch~luSo{ z;5`Ur9rWbrRPX3}R6s&pmo9ro(CH!Rbn#W5RcWAKFYtSIri5r|qO>c0F!n;PMmT+C zk?Pw;0|#*z9XPA}T%MJ9R}lT#um0hf#g{3LS=+ zi?g72(?)7>I4;g|iJ=_}|1xlH-tiEshuap%V{@KCiTW10VI-|xZ%bC{I@%#a9fPG_ z@F!(zam-NEXhncP53ho`9&)cTs0gVYiee?uA6rk(ojN)Qr=U7Xn4Et^MLQpIHY7EV zq>~_*BbLm57!~TtV@?R{b}k+2lu(k*4xSk1&I*Kc;vgS7iK_=Y%Sd$HtV6z{9%|87 zzjsXrMeAycV%=5^m0emXs>h|W=~|j}f1UT8rO9Z@b=uqVsqgEtUQ>@1Ru$*Z&Z*fB zKd=ATVD)TaZ39iXHv)fX4nA6Y>AH<4TtPejjP-`b)>a{W-(Cg|$(OwS3b+sMa?6A2 zcP6J~`btfIx3nag7}N@i81cSky8S9$U7K#Maog)6dIm=vozK$!ptslrad-0dKVMed zLkuGKT7)4UfCO4-;iB0x5fTwwgZD%0dJ?32;|m8(p_vlw$d7+s@zP*|O|t6XJ2ao9 zini)ou+_mX&UXVwrA5`in93o_{4&rugrGHxPXnrI+PurD?KH|@L!J-STvO8F`Ytuc zX>2;O+AbI-kJ5}yUIqvadLW#&Lr=hSw7?clg~{G>sIS{E?%lX0E)b~4Fr|RnAWCYAmRFmi<(pHJj7K9TU}{RUqQEfi5lRIU z)w}@HQVb=ObWY7Psj)(b2W{8dlZ=}B&G>~XQ z5UEtp5r0hCWNdRy(iw0}NbO-SG9WSx0n1&Q_5e{puD{jLoXl)8h(ZipJa>g+Q`-9^ zYP_dVn&aLUK5P_C`j-2(GS3 z@`{5iIe_tsk#E$6q7k1o0Seb1;%WZCnV}4h^B1p>8&H4r48A+fSGQg2wIz@p8sltk z1m~7x+_1Vvu`{6Tu6>yM+hw?5B=ybm44d6$`4HZ6&h2>Fx5H&_N84d@Rl;lQ#1Nj? zq{eSk!|nc&zFQkgzm*`$l@$lL)L%)&hNvJ{#4O@|NldPW zR7Ma^OQ3&87<+W08;KYPL0QHAg;vPc8EB@aMS-b1Q_}|jov@0SzDG9#dlgl1@caP_ zI&zrrmB^^ROpLY2mDms2kC=Em9usNT9SO?t|7rg4xz36Jv141$z0@&pOYP%#zqB;c zbUsXL_5SDqB7~l8KB89_B)l7{1(NE{cOswRsFQ!l)FBFfhM{D(yG)Z`Zz@QGGuvYn zy+SqG*b95nMBpnxpP~8fr1{5(r%!A0*uG*%iwNrY6EIK-Wmj=PS@=9JMbX2Mw}xb1 z#{%$bCoK+8-_;+z)Kcx&aFiytbm;+jO%kP#WYfcNY}_`CcsMeEk1_;cmZ9)GcSbuQ zD9?XyukU_%etG);AOQVw1?_9MYNg%E`EGkXwysDYfq? zo2#)^sNK)@Pt&gU>HR9xeia%QSD|x$746q;uABbD@6P19khGg`Ua|_>TgCLPu5LGB z&tJYh?S74p-PsXQFPXxyeo*p|6kVj0mCl$W`0ZLM4W4qy$B_73f6Lurq(8 zY(?wNyGc17F4^uC137;7d)d3uS%W1C&Vge%2Yr%ztgz10HodDH?&YA(@+MD2lMtcr zj60qTcVeJ-dos<;%w88HfxQ!_JmPXHoqd>o4npuF@!$}-W0*2i$`~?d#1+VzI6{xt zygA&_TYLbDf_L;s5u7sjXOZH&i&1~vi^QR_C`>x3p z4(2IV^q3rDTr5-kfwKe87ZIB4reVq zyqxq$>0bQND!CtCp1%9;yH!l2(K<~3o6b*v<;)C3<^{4t^(q=?Afhf^T>>5VHdq(b zLyNMs`-(vzfHbO zx!V_Ib39ZIpB|0~CllhBX}Kj8Sk)K9zMo*9JeqkgrE1n2%&zCptWJM2WZw1E-~$|p zd(?xv6?tq1Nu*L&3wMyYx9D)}EiXDdA9Vtxc~Y6e`CTuWb(BXjh}U_9>$+qy${my_ zp#f>xE!c*8^8!ht0g#$IiR$&Z4)Qc%b&6@dPK}GiJR&J`M#0%3Q<1<6>P=OkObq%2 zzX@hwM@VFmte?2a2I+swisv=UUrZ6kWF{f*KBTfpYlaRl{GYQvl=L z+({)CyItYPBD5BO6)@hxpp06g&Bt@@#bMG*ZCTHrHjAUa=&(UJ=hEnR8d1ngsOl`7Dk<@csnMoDkP*=le4oh3Ti!`_JK=qq{%fq9pKlp*e{FA&iYF?b~c4|wLtYewQv z`{=;rX}w;~p(X7jS4~5skrx^-FibTJf4*hpXaZvKW`FEvnnxI&+kl{^%OIhdpXuAw zY)Cz-=b4hJ-tAP*=k*d>Zc%``h?FnJrz2Bz4`R+>;f^yQ=Y^L}G{D&d_7+*qy)-Kl z(fhOt;*1wHDG8E1n&J?34&z0#8)?)(iLfvi`-INTclKD>@o{HwtX~!CjU1+&BXtu} z;)W9^ihp{BcWsO3%jb5(XQ3JqD-1jC!EA0~jsmo33&f$DW`t}MjN&@gS~^A@V>)8& zhkPi4<`=GbG@E3ZJByAPeL<;QGM;Cr!?AGCow(~r+I5lY=P)(@o+*;!+6LPLk>l_nJh&bU~W8&d_ZTD1ZyJCo4A^??Kms zfXQe-=HLa8hlgb738GcfrbId`Fk2MHRMmu$PsWmK$I3-F=M4`E*I{E04|CnVlYi>9 z6A+41FVz6Z@g}06%q0)EjD-tkQ~S%7PH!mbG;`l5Q#xi=y*QK#xnrjx{8|TRmKerJ zZ)XdJbI-MZqJ){bK&SH4VNd6fZ4P>@5xjzGfJv}mo`c>+UzTW!2D$f(f?nu};UUS& z6M<7$$;*}08#c5aqH8Le9UB9$VPq**cX;^3_fV>OC(|VtyoFK<7zlNilDe}u`5j!h8j5t)l3JMBn%O1f5utxmLVkc*_!9bt2_ z6gMPX?(PrWX0w#n4q9quKz^w+%^WlzQVjZX&}PW|v&#>->MfPz4CZwYV6|*TxmV95 z*mSD+Xky3w|Bm!}J;NFowR|n&x!A9@&=FwAUGhM)C<7S^8&$N3rO5r2f8eT8PV&Nx z-&qI(nR2c9EZfw!Mj??*vSFuvDi=}IkjY$pvGaQlRvpY-9gTki%G2Iw?;+jC^o_+jJwTQe;TflV>dls*ckx~17jHls_xOnIYuzUo0j+C`*xp3TR)-! zM~UHPA}^a{YioP?%XQr zGCycfAsO=NA$@k1f4fB8i|Yz5?=QDg_}q$g-68z^E*(wKIvpYFBcO{2??{D4Rx7H( z)kuDSY|)Z~L3tLZBt_R4ABE&;a6$f@?~J63ym8yA|MB5zwKo(Ikb~$t*|xAehM9x@ z>R46dr>RRSynZd*OWO5TW4sE>*GC+Md-1y6^t^li{J0V%f2wJs?mT}eedSE6NCOEV z!0xy#34ULe7mvOa28o1ubw);B-F3FO=>kt-c1q6ft4~hfx}D-(w6(Nh(uut{q$-=- z(Kuii{|for(LiNuXgKD6YfET}xD-oJAUVA(1>t&X1B5B^8zO~OcbajFf`dr~`Wn-KJWXMD5?m_~&dL~>y|g>B zVnAhc#WBM~DO5zHRh5P%2O;I@$`*0@_~Y~2)B6=9Upm1IqxsFUl$;cjMid}nzDF!0 zN7{09LE3`ZVt=Q;u$k^9=bqrEp2G%>;T6t-h-%{#J^8Ai^6Q7fy z(HehbF$My*o(|T3`r$#OD~LUHX$Sfpdpj>#D>{ba`Np=bIkS69dq?FSz=Do`N8jrh z-b%3#!9^$L3Pv-)M>ozon?%qk1XZL5Jg~L8ouoRY-7Gi-;dP?tiNf0thCZQ7MG2^> zy4hAfJZ{)UoAwEUZ&7wTi?xk;=0e&w(y@QCf-i!7zD>VL!boJAU+4)e+}(D`&W7cw zL5$lJj*E8Ad3)4OYIgI8diJq7si%3mT-lxRnR6C>#k2!0#h#J!85hlq6MBc!3kK7k zOL~sy_$HpCZ0YqJpX52c&OT`|p&Cr1Y~>YwQn*D2BJf_yIr0Q3E-!?tp&Y-`41RxV zSJa}mnRbN;3IjPvA!ZAky95KUr@AaH{2bujOiL9R5NQAac`ORj6D4{qDc9*mSjkOq z_I~~n*m`iy^BVPAxjLbOUnC$NA`)JT9*5uBd&hb|Or_<359obxvhf?>rO}6Lw$FP} zufH>9_ADDoXSNd9JO{(VQ9tIMapr&eT}iX-;8GOy-V@-P>@}(0RAc@rWmuij)lD7d zyL2RJUl2CC}n)R^OJ%o!F#jf^MNbUHzi#KU~QdtC4Apm3rPwynZP*TYYRjRcXoy!3$~gZ3G2;@ zi#Dz}xoh!DAJ&Wis@?O`V(YoA^IJKYwmv^+bokcqqF&*?YQ~ z^M;I8v{K@|f8N3QvW~ ze@Zj6vvJjFeIl>I^g5xv3a2GU5w@wWqo6==;Sc&dX8TR-0whhxpf=$-*bSV|=r_Y& zDvdpr49#sn4Q0qbvNqi1aiA6@WaT*WMG;A22X~l@gmM}p!xLr&8!Gx|LNFk92o?9J zlTkrDyqSS_<;)Ew9Yf?{B^EzZI*~XMfACQbSAjbK>Ph`#7pb>4iV`Le=)ySefs38q zm`ubA66!sHkA(V$p!c)w)75en&`UZ9CZ87wH5DyNzeBb@_k`DWBlM@6(QZ#0-(o)c z!)8no*=RPQE6fjd3aT>?+~AsyH1}zmvRR1Ot}5lJ8IFM9qB}GXX6f>3b}aCRe`R-_ z6@CBf8=$x6Pv3ueY)8T-aL%z^I+^c`Pp>26tKtMm`WFUqkciAxO&W`Q>d$6F@?-Dj z)q4fq&$VRJA-55M!yQGJO6x;GLh1vAqFX{zO-Py(0;gP@+dj7m(!vdMVhp58uyak0 zcFtsoT7@XGsr(sd$*`Rz<7$@de@6oGjE1R5n`#s%jJ(o}S#bS&HjV9Ux?Ko;`hMkR z$Wq~%Hgd;&;*M@gU?B1WreDU;0njPs3wXM~=66-l9C%148-uP0=GgOu@ymOTj&kQr z}-RVC3UNX)_?#Hy0-e^fp!m2J*m z9$r_M0Pf9%QaNXM)@dUtYsJ9zAK|BTV3?tp zPYw4Phf+9Q-?d*{yRH{Te=%{uPtao2tBIf@30(lpPsmrq(m}AxS-6|w)PPCib%ZiN zIW@4wf=wAUp~wngK)u2TL7>HmLQnfsWRMZ}Kz-upxR%Hj#g+QI8v7sEDvCrxqR z^Y#71$F(yZK0z9x`;#zVTgO-%gFf{Lcs_+39G1Ks7>S1C1{QNMe-ciB3HH2It#hjE z;91=sPIZ4{mT%m*wG_Pl@c8oS@og1mjc8pXI_;~pJY$jJ=;y$|FxsRLZpN1*-j-~= z=$eS%@Gy$fa0ti^S*E6yI+VSptAFzXc7~ZH-gw%MQGEPevgLKhmA>fOE_lIc@8dm) zIK($^+F(L{)BzkC@xYu7=ak$K) zB*xQoXw{0S%Q_8EYO!Ok0)0K-BS>>P=5qbs)z@HK#pA*)UzbpGZs7Kd?*UWz0B9Aq zUPQVVk&}toDH-Yv_i)LOOWn^U0%Hrui=I@Lna>(s5;t$McVtGE6~0G-K?7MZ#kxA6 zb-5^VcjJdrJS*{SIVlPn36@{VWyR9Uwvu`~lO5S10i=^Z*%p5rl7%Y`@h~5|q259f z0{Q+2LZrFsPufxy3;JVNB-0??O&`pQ&-FTChcrnKG&@CYQG~m5WNqg+1zL_4f;kvj zcY%qEAu8hdM6g%Mx(qBjH@b}Aq5y%>3jzWM1k|X=tVn`RC}2REo%jU+)Fe(pF=>L? zd8HsK)*--@M}dFM5DKAu2kB=u84=V?QXa?chWrOb5c6ryVW5IVKrk94SO@|@!X5cY z0}heb#77PciR8mQRRnO3l(q~51aTy3dq(oELYN{6rtTOf?3FOf<^X=Rj=)_6dXqBC zgQ>~~M%(EefPFebOd`VeyJF2TbF08um0aUzuVP1dFGuL6_FdE&+PT2uy8Q3R6 zPkLbV@?m6*Cy+dV^A8*=3e;KakgyqRetP%%M)+L2io`g;{hkonnJCx9LHnLM68$MR=&5 z3$fc){V0DNQv*MmxunBAp_RS9w@E63*qU=fzTmsV$Yc234&s!`WZ9kz?<|_0|DU~Y z*>c<1viuc(0L6uPM-06<$pJa#pl4|*EoD2URHaha_tw`p_TDE*00h(WE!)-Is|Hen zAP58kfq0y=AF~p-`7O<$L~Z%)IDxM;$3-EbL7;ieH6!CDSO=KZM9a1} z@Rglz?I-)tf5|1HQi%(sg$-xMULab|C&x+6*z+DL-i)znHb`vmBU_`x`a?R{PFujr z@8y3gfIW@TkbwBVlZ_B9CmI7Ek({f1ALoq(+_`1%aPQhzRnD|Q{Sw{)Q%EABOAxb@H}#n zhL{HmTi#-ps*`V3Arj6w*CW5m%|glf(%LPsTCV=X`v9_xk+q{_EGp>V92)1@nLS zbb)avL>T^UL6)Nk6SzpS2WAT&OE3#t_!DO47b*Y{%eWRZ9iev zJaJdMe3Y*1`ESLR@z8@%n2gqjCm=BL##DCKs7E;Eml!Rg}&E z@iuF=&qkf&A*^d7*6AENsjje68`o&0fzQFH3n7|BN6E<+*6wmh+1vFRi zwpH?X2J!2-q@*GzgdQ17mZkQx>F}X@qW7{^Ei@dIZSrXK z!gboAQVe|OB8jf39nrmHI0u^vG$1Ub94Q-)#4`F1dQR)1dT_qXQB$8_JUr=#h~|z> zbdq#CK|Q##(WXR0sgV&6qQ5r=2cx)=jZhI4VWq2|U^Gqc6^_imawd*)NueO_mh@07 z^s+X7xqtt#OsmUG3CVvb%u@`?ERTt+{fr6t>*Fn(wfY05cLfMrxss*eu74>DzqM=S z8`tXB_)}$cDWqS-S{6?Ee@mE6$8u&fp($mFY19Iu$un|?J= z=|yfC1m6ve8bJiSDOiY*J;EBz0G^R9Q0jOuh-8+|7=V`2T5Ep-@4mh~|MK|s@K}xpSR+0H%>=0iE^6ZI_?j2mvuqv2U!1=trWS$TJj45 z)QqJ^0+hcZKuJK~%La|zpKQ`@-pJ>NZ{Hrid|V8l6B7yqs2PDL4o12J02)hn0D&*9 z%OXT(kP$odu&?8$5_wF!5AvxXvIIlz#u96CKkL8C7sZ*344U44$R~YOl)!5<`{b9hIrEFa^E;4}-x=}-yn%BlsA;HByPGxJ~MxDYlETtl})LwJ2MQjXpzZPG3~m> zHw6%V_z!Z9S&5WLoCYeU>7n7m=mOs0Z2D>t{uKGagU92W3B5IAIaj1GG{%M|f_cQ^%dK~|T@vn!3P1KlkWhE3aUo8-o1Ur&E|AUf9 zAgbG}k%u+*^5ZuLMgIu14cM71hv$*7Lk=&^*71BR$G13}*9Lfk&{v$UFd=j;E#;Ze z+Aw|Z#J>)UpzZQ|vOdaa3l~DNC-2OG_d@HqyAsiW4wqD0xWf@QA1 zLUUt7$GZwyS`dVy<`Qu^{V+GyIop4F9NM6d04JffOTK&m>3-ooCpt8B92kD*wJ}vA zO?xg&fO@#gRxp;#(LRWio?cFsdOQgf5{A2`86Kc)Zfi3zPf>7!SWUcu=&1E-8q54J zmm2#k%giZ02c2y4t$`M+(O#i&up<)KXY$J!hqD8bpQ)R5*csMu=jr+ThrfUAc9e=| z23+E(Y`!GQ$vu$m8n0LP0IyKtAz1>r%PtKo+1Nx|kXbmDe!6REH&JV<`6Ee9)MT-( zP^;DR;o<4=^A(BdudJd-VGw7gzJe2Y^tcKyR+_jW($u}okzOIjTE>xF>fE}U=l9<~ zKYV%p`=0k!I79&&r4vd74bgvqD|3WtDX&&l$XwmYr6A57d`R)Rqp?EyJ0#^<&WC@# ze|TCwT--p|GeDzr5mIzM}Z^EEh=~X_gok~TH>^OhjLR?-{-l|wS zr)A{OA(Zg9J-B7YXfeS3;qlELosE}c^&Vx$hI|46UaiMI*%KlCMF$8!nC8}GAD2dJ z#s1~-%ZEjDGAvRUd67I?em~4}PeE=*5cBHe^lZYkUIzrxkoh9G4d!mi1WQ2yCM`hA zG){jSw}F2OL~Ij2IZJ<%gn5FhE|L%;g~YS#9cASS55Zb19r{hIKI~7AA3n?#e$?X$ z=;ySCXh%J{gK{R>nB){2&0Ql#plWBXBvr{*nq}L%ARy%A#x1zYYaIjYrj?%YP82?B z2nKQE8IgAVt!Lx9>Om}OR0--HIA`HXz(NR>z9$SL$X6ae@yCDKcR1{*N6r%0x^OLE z;PivuicyU_x?mx!fsYWDg7X`J;8KxMI0N-E9)OM>236}*jmOXTA0Pg%p(kr9z`zNR z@9g+YX8C|G$7*S_w(X|s(g-I^@jk=y>vrQ7|N5SV;%yfldPOh>E^otJfG73R|}1W`=Z#VV6-B4?t+xzm4zC*NG@eLL*G+1S%jTHI86^n zErM3A{~pn3PJ)7&&Cq&9QLfb|_4)hL>*LqOvM13bP5}cb#+R{?fR1tS3%#i>83f5= zNd^grzfn+cW?wcOS$lLd^>G0t_vkp{jS_x)eE)a7E^U816YVV9*|Tli*~6!#=fv|4 z9^8OGHlsW{b9NAuaP{WaQndCn(*f=u)7gK(ovy?hSs;{It_@ESW@z0-lN3 zyyClcY-Or8Nkutv6J|u!Vz#nwNI`QQvs2*qL3zzcsD<9=8im_45VY?_B=}8ETVAop zV);dLfUJc6QHRl6mr!VDLD9NmLP-J`Yy>A6x1fKS#2jP@_Qh6{mqFIOL)k0Gz{K5P z07t zHd)r?1N`TM%$nfqN64Os9F0Vz$F?K!H@JaQ*Pn{iL_OlUu}Fq{{j zDwO&xcwdQOQtIH7UVu0ScV$?+%Abp2_F#X00tY({p-)MPaAGN1oA1D51X9mJPpFm`g;TfN`a8qb;klu(pXv6qhv z!=jP7g{Z`fk|K&#d2{v|s8B0`UUo%Fw&7J#`o-<^vL_`Xm>XwCsdQoXVCM{ct%rXq zpE|tja%Q7HSP(%%3>JoSYurpqPjzOIjM+4cP+rU@#%R{yT38IkFZ=UOzOgWx;7Cy=Z(GP8P z8C6uda$qy;&Gb6K>7~f_1F-$71tx#M{Bj7V)o?Q742u;Ga061xs$Klj3bfxvmka}2pjrGLkuP; zX_H}X#+jZ$_1z`Nv&Aw@A)`4n_mG8F6dtMhPNDIjzF=UKU@$RyMZO?xg9_!=Gekbv zFgwV+j^iem!8`6Y^cqK5XL{N^#8R0X*LAiv%=YH~SA;99Bwg`xm zdp$!LoAU*Z!ZcRS@*JCMN`_aj9DJQ9Fa)$Gis!LUr&U+td?iCjL~nmZW(Hc`K9O;y zz)f%S8VD{DM!7YJyzr;p%Pcd%;-qku+vZZZ_3`5Qw}+Rn&yQbT|MFmH-JU&Qv0Nl; zSZ=?vd7Xy4C?zoYOvl(t!2B%18W)lSp&QADyBllA%MCBbNrpYgPSN7_!9E(v0F!Jo zl${2tz3Du7f)4W8CPsg3Jm~8*wqQ(wQ2qMp*y^f@>=eUV)Id1wF3@z`G0qB(PyAt` z{gu_=g=0UV*z@-MsptavB4HrMoH zvAJaP=Qxe0$2$jm0$^}|>rdw8;oHL(@y}L3SyV2lW?=lcgqj7%^1MFJld|ky0S}WA z?J5F&d6PZuE(M2&=f5qJaP1Wad!ECJ{*sf6?OX_3pZ3qsPk&pJ@9jPUpJ$UV?rQ|+ zZ?7+tp6;Uob(2ExQ3M`7KmU`L?{oomlML`10h^O3@Eie`vqkXU0|8~TB=l_pf74RL z0X!g4Gc?uA3M5EcH*S&yJCK=9TxJmIlMJYd;Uj3$8urRSU%y)NM$YU!$KG$!zqJ&733qHm*Vl>V&Rve^#av5ss$0?LezKo>BrX6d*8lRf!GdO`j3vZ0kC7 zbVNp0E}jY}TdvHES*XRrg~QoSp)5oi@x1M#o@p#kDhu@A~kvU_kPmJ=Px%VknYX>+TZ8v!y|mnJSRTwV3g=e>YGRjK1Vm zq?vlxPVhRwUk3^bviv;S@t1*zNAm0=L%bBwmIZ?2Rfc{QoO<lsXjerSgElla#kEx*jN;B2nP+z@R&1QydQ_Wk&@2f{}eWR%3Ao<_V?}6yZi62f6oiTCXvLM>?kVD zIek8w0>(keCBP7N4C)&JBGWlb?%_L+6wQegG32_qyV1}3Zv8H<(r5F+D-C7PK!gX6 zk|jKtN+Ml3%H-aIY35dezyrrO<~q)jhU?`RJF|C7UCzAaTyR{b6Y4A6ciK{pGEOw@~~xCs}Y)d_VdvgK>e@6Hx0qY ztV2LT+Uv7UA!`82J{&1GzVwLaDl{*5a;~)88P<;keq!}84|4NG1USkhcS9@7Ec7sH zj)YJFG$~eL5fVg7Z?ur7$B&<07ZlgwFjnK8JUqtc0;Z<8e>`_IN&t+&NSR}o(AFtp z3tgkM&^=my|3=}KZFt>)VdC1rNV;4b#^KCgOdD_?$!?11;-1}A&UbQ)B=(&c(&;v%zR0|x4VS#NcxJo7F|GmH(qh3?#J&)8L-7RHA8 zgcBVUCdR4ve^iaP3wo(233f6i0}2~*M2K(lKt$xM(?`@OL!&pHt4hg5D-Gw664@q2X)=2Pg~1E^ zohhkJe_k81{YvEwTzLDP;oMaY5XOW!uGx^sM4C+sA+1j2;}5|^E7k_V$FI=2|M`9) z(j>5@#AB$pOF?(QJda>~ugcpK#45?QvcO9w1Cci%JBoc6r>35IEP%=z%&N?2)WY-z z6R@MP1psQ^t&?lcR0MDv##07SwBY5*gU1Qye;qGn5-`|?LQVt9_*T{Y^78y;;qc|1 z7!`%8SOOL|E~}f|ztR~q->!>ra%pjsToVhdw*;D|TSTHsl{?Hi;X5!smm~ILXIMNQ zw7+8B1V`eeDVwwkiGF%s7@x;3@r`yg>v-bUU%9cxIfxarJg>I2h~31yGV6pjDTPf# zf5IYhn1AW6duSk;2;R%mBm-T*)LU#0zSfNjb9!rQ%2;;ITl7f`B1rK8QUb&K_Eq2=~{tMq*_^sOs- zFV5)~`(lqh_N^GsJLv>=zLJYZ(@wRsf6-Vhr3kz+MTIpG7ddv18g33ok*72#QB&24 z6hoCUf~TsIP&_I#V_zBAE%wXEGVv;+h~wIUCr+lT&TuASUD2MBcy+cF`aTm6zFH2d zo)){B4&1l?)7H<{`URTo9V3tmIjAI+!RM=|Yx&5;L?v&NX2G~~(i|a|L7H;pf1#|d zb4!tO&7|FW*ImZV%w8?|s{KDdeOTxf4}kFPnPY}lF);-T1rG`)4_AW8i0DaUxCbGGBO=znsJf83~v56{1Sd3wGw<<9dSwXTV&So!=QgGc#nLgCYj ztHMW`Cjz>Os4c7=2zW9CwWu2d{Q`_#y4n{-MDGp+_>2#s=iTEC}|dF zdUO(~`F%R!lj8={g+e|Q3UcH&d6=c&D*0N03G#<`@c4rL{jK-w)Aw)7f4NY9-~Z%pgwqse zM13c*YKa}Y**qy@=|)Lch&6v@Sv~Vg1C_AM4B%ip0fp}3oS8C2x%);)_(3}f7q){5 zC3K|OFx`z|H8Q6t}8@0T{@fASc6G&QEez9E@#7I4873sPuEc6(lM z3nsgBma-OpRSyOif7g!IaT#O;$qE@KuR@5&yTQ;C&~51D9GYFq*1=?H47 zm#zI}Uk2A?kV4iro#?1e6H>wp3&Fm_>b?B({PHWN`d@xsu<QG)6uf79RzgO=fTx7bz8m5oO205{7&fPzOIz&|j|S^0iXO44TKf+c-j#ET2z z#>*&j8EZ4nLQG-iuyK8!xO$$rI8Q)$j*e4dulJo^cG=SrTbQUopE|7meG*TY`UI3) z0I`-c55NXUbA_vJ)aybyLI#yn=I|DXso=Y{qqQnye-4g2;cGw*9F=DES-+j2z2@i& zIpFU4Do0rZ62Kc7IG$orRj%61V1uVne(cp+d0n057RqXOpwvT85&w9{Q=-^g9Nf65 zES&MwAMamQt8)c5!=YtrjwNm4G~MM)_?<)&K50qTj<+Uv4ZqXqNtP4MQYv%#cOGwF zV_l9ze|V5KR@i%miGV2_04>VE83Gv)!0A4etr*@wcota*W*`!xepJmma6C~nUDC#` zY2}_@f4+a32^Sge25_N#C7{o9zj3dAJ8pL)Z)2)apxzSBWV*%3Z zJvuaWM-e7cssaU|jABUfv^^Oqe6E5-8xr#je??@Vvq~;9bYEz(SojX{ToRq*6{rBm ztAZ9lNcjL_Vmz9os(X=bzvOb zP~`nbTLley_${qUyl9vdwhm_LbuhM7e=z09e*96Anfw*iKSYw_Ox_rEL}n_)7U(?P zk3VwwLd-26XgtX@<>8z)EmRqiIAp*R?MELuhHsnAoIU3DIds2O3kTYa_;5M)sB8yD zp+hyD5>r|=4SSocj<3|=a_mupgOyhcvdUEBWxvKCCx15Vc&m2o&6e}&;py|kf5QDk z8SVMxMX%IymZM{@_NLp%dYzxVJY@L@VMCgQzE69>tF!0FNT?fnXR7^Y+02`s$v{v& zFw^F}MoOOaYx5nu6w14k#!e<6RP^7;Pt z-T2af{POPo!X4rZP?7#?YBR;UqGjsj~k9tS-ThKIODmyrs-Zzef~obQ|0{oiB1 z^Z3iZZeAGrMB|4xez?9cCqteg!SF{f{Pgh4>zh}lBg4(BDlqYfullkCeY$`_JYZt~-!X{t%LG*i2i4Cx};ao>#O zvTNIO9L;7^7rM6TusTw+y52uM%;P!ZboB%{)q#L33fX!u4LvAN7>k0|rM&c(YDx(r zBIxwe0llXuj!{PJ@xbAEY=jcPlJ|PhOeZjOLH!5fp;J09g~oH;e=76y)AP%_UmoW( zVAo8O(db~N?^>jkJaqHM6^`4YeEz6E|rN?&VcRDd$=(@*dPZ+F|o?Hcd z?o*Qyk9T5QpU%cszIWl}4|d@y#+T=%rqmn7_!F;tHFU^XmvIIG6@SyiJ;JPRe)Hge z0YWcyrz6$MV_zN570IE}qCF!(-ov$e zk|YNgPGl%T28$CmJb&8yc4dS=_AD?+&4hZfWSeKc2u#?SsGRJr?bx~~7){=f# zd5$Leo#z<;SkY^Dhd~o2#pq6XHN61ctm@dwVpv8e`LN#oUM;3SUW=kPst(Hh;kr0~ z_PHBk9WF4_xDVni6y$p?BYz3{wh9R+2*pp^(Q4xOth!FCSpuy7u;?td~2$ z$Bv)Jd`n1p&OE&aizaBd$DM!X6Dv~+*&P=Db`jQIz8@^Y{7OgGOJ;@7N;gi!ZWUpy z=7oJ5P}~F!dMsk-17pUx^00G^7)#=a%)d3wT%DbS@^4@7-#>o&xVVO+%{Oz;{Mh)h z*vEoTTterq#HN#c`WRqPo}4>rgD1Tyi0r;uj@N%ZEvDJy7*X+>qX~ZoaFvn1Xz zDVmS$!g@!FnN4rQ?05Wd_Uo=ozwUbF*Inh;eQBZCgC@$>!=^HzEEEX0?%TY-(E+M| zk1M3q$zA^Ta2*diH<19f_RufhbOWKcG+sOW*pJka=NfiOO4zrHT;uZX9}2jq5J9U3yXqcBQN0Nxc4u}UZ zi}4mR3;^?HE^`9K#nr*=m{a?X+c?Oyro{ZiK!*oH9I zGZ|+dlO1vFk;@Fk0EeHsB1$=B3ucaQ{EUDro{pb$ay|7#G>X-mC4IU7_;UaC(_(O3 zEEi@;@N-X7HI;t~Mj)OqH>V%NHe1(p^AZ2Y_vhD#YY%jwwa`Yim?QWdqQm7*S{T@$ zWC@n6*MsG;rXnjtSNNvd|H7QC?#%PkO+-BIC z$__)B%uo_`GShT zp;QetQ!0PJ5$MoXC_h2JOv+JIv_oipj`vQ528u`nGI_W(0&}H;hM1?^nGe;MnCcb3*&xTR}K@ z2K@T)`swBQ`^Qh0dJF-<2mbc{MTvmvL%p z=(@tmVy`BRCwWLs&*g6bRY0o0FQ5ML@bdcj{v1pF`T6zr`SYUBRTMRtn`rIEbNB)= zk7lM*O)uU$h=JA5{9~ecKkw;BP;^b2aNBW^KtG+3-J23=i&500&A54n#THpTT z`~5;?ALVsSG!z#88ef(TUe>`1RbYjStrk&V7Ysq2VhHj%cYi5({o@6Hy$aUi7m`Rm%t@q2~;z4L$nyp)pk^H35g0u&{lzAbd>v4|?Bk9H` z-zzO#5Adk+vuG54vr@F*?&qeK5K25z98e%1Y0V-Qyp}!u{<6|U0sa!ujoPYNxD3Lx z{g$dF4NwKfN6c-N|Lqm1;E350C6dp7o29{9Wv`E|n~q4{)l-AgOX`(&Ky--(aCxw+ zXiwv+J#etEg2OQkAk4jNa#|Fc+59Jhfyr|Rg+)!%sc9}*3>gAbxhjU7RJdJ7+3qcrF;wUAi}_Z6DL^x zmXn`>wg-#>Cbqpu7a+PFq40FRDxh-|P6_GglxRVj>Xs8r{FU_!47|pt2lpwcbg@eh>*ask-DrCNbtw%Wp9xP#`&=H*?O~WzkWYn z9zT3s=mwylpc?R0BL%R?840{l*>;Y5hzl?5V&`(y$!+v5Bi(=5^Le)$Y==>`XzwRoGi~Am|UvD@ip>16X)}PVf0Dq{=i;2p3vRMWu&h_4U@tS!rOW$i!J`+$pEf7DR#kxFq zG?K1jhL-ZXW&Zy3G_KYk=8_*2ryH2;b4aTsg#FVJv8|5Brou*XE+=`lnsnWXLgq~V z-oEm?hkri4E^`bzZ|?Sgs1fIt)I<)Fkk*QZfF2PIckvj_D9Khe9$9 zDiGHwB7z{3LMNbtExMTuUFi$nu3O17qJUc&ZK8k-_wVIdiJ_Q|E_C)eM@0Qq)qlMI z{P1mx@-x!yU0s_GLk)2zC?x7+t0J+Nq<5(B3PnB{D&xLcd@TH{)~q+V>>z7{M_Tk zj~U_?uRuV_qL`N?qole$(EKioWarCoe` z_x@i`fX=)umaz?S1JbdkU3z48b-Jr^Y8%HDTib)9>!R3yT5v%mXMaZ=R6BVKb_CEN z!d|YfIx6dTxawL7zlk8T$Rf`ripsW4Kh|xXer(HcDGq`Tg^tP?Xys|?$xkl05zm)m zuuviAWQ;&NXRjb9zN+4*fE%o=R(I_f&oMb{&V@F1BtO(zjS6`H|&G$%#_k;^McbwrWj zVz2M@`^Uv<4iw+IH-luE)a~db;r!gpZt87^4Ea9lP;qiM$)xd<6#!n9j808yFAF%YaowIj52bYnLlsv zdkW2#>NHyHo1yS~(5xuPnfF{TS9z3ji&m?D869&KA>Ld1BQVXiQ`|oGt)lG6L53ML zCQF#N1mX;Avw1Vrhy)L705GfXo=ixnf`JQe`fO-3^=v~yTmozIjW%IcZ3n2N9Vn0w zN)3S#f{tpyO(}(0oNdZeEF~F`vmUT+ZnApTCIBEz=+$1&#@A(jDX~_yvQ0fV>a9Y5 zcnofHAeSZ65-M}s$3As|lcF6GI~y*Tf*WgH9_6fcB#QQW6xg`|JMp|3^tEGH!4Yc0 zO?q>lTMPw#+FWzV7HNLIG($6QE6T$kA23;X_shfQ`=@0{HBKj23LBA=--`J|TS}L8 z(EJ(0$$s6N`f)R`ClA^8?C}oL_$f0J8;nURf#N3fJ(1}P|E8I=x_6V0Vfn2@ zz-MWri5?5{M$@DcYkmH;d*i0po-pr>$s#WvG^oS8F|MT=6YYtUn?csk>;&b17$tc% zxfoJ&ElPVn@A_gEQxeal#(-_+0x|U-kARD^w;%Nr(Kl^eGfsvQgfFQx-^}GNDAiYk zJr=r%O;tT}MAUowIbMC=ZdBUq%l(&c+Mcrrh@|7h0W%baxT6tW&XtxYl~!13 zg_Tx%rKL%wg-fL+%fk3z85!+=cB-^`skD9~o|acA^3+B=RG#+KBFK>tvqO?zZOjJ> zz#wjVprblm*bjkFG0xZUoPxXv_-p*|P_>e+jy!by?m&YrB(4v{Xcc;}!+SC4(V;D1 zRNN9T*Pma!JU`VV-t_77Ym4XO7tb$UeSiJ@K0SY1CRwJE)X1E`dkUa`nM0$&4?+kB zDxryNO^qo4@D~c~$0-$23Q5zoQ=88u%JSQKoWV!cDu#t9v|p0X=HFk1pFTeRa;5C# z*TnAUvU^l_oX(_BE7P(8*@_mu=b{O{zy^Op!k>xoRNHcPBp2u^qy?k|F;|GEz$KWc zCZs|n<2w`hju0T`H3O4>4&B_}gZ^{8po9on1RzmRvf0??MR}RZeV`JKR8*ArAmsm# zUgDtM)*VD}$C*r9nn}3jIS_gNrHFfT@1U8NK$`zPFTagqqzrOS3`X1``(RDU>*GAY zXIfgs_5{S1IAt8@Wws}`wXo{Al9Ty49aq8J8mEN&E@quI!zD(4g-efVaMaI1?_7>> zQKG|xoNTknBEll8+3+zG8yAV>%o-IPCwj9sZoVXo813@=!4fyLR%5nfFjXVmGREN+ zlvRtE(ByR-pHR_Np;Py{?N&~nOIF+4~iAZ-SU zZNW;-6JVd`f9Y87E~)Jy-81K3LJ9b&rSD$hN7*I%&L<2Hl(ZrP22n;qr2v-I zuAkrkNuO};DXj09btlVSMxD>JQ<`>G(@t#Gx5)vr_jqk*_AFS9*WM|fyG$=U1XKBm z;S#2QPN}`a_hDeTqBq)Q>`qh7t2g55{@b^AzdU_^U4X2{4!avzlcW&{72!l1(|~?c z&a6u$#u=DjAwUBtdx=mb!u&EYsTSHs9t|QpTB=xqYH}%%!efz zU4IG(Izrh;hHS=ds<0wyeNY}|Ed4bRz_NcR$d zM3~37;Z*6gwO;UVulHX*uCy$atDgM%PU7kI&A)zsdi;8`ae6*Qw$H$aoETTJz@qvu zV@U;pqBy-P(TK#6OTX4LFy(mxv2+CS-AUYeJS%!HzJ|puZ9W+W|5~DW2D5%SxRvcOdT!yL{z*YF~ z4ztY6k4h-gv%E^Eyh3v}Ws`SpHs8m1%WDRkfI&|EoEsR}`EjX)&v($01mAb>O&V=L zFvd|&Z{V!~mT>5@t>dE{Ocrf_T#DnI7*hvA6A{04VlTqUnl4})aEqH7u#gj#xO-Dw z8-K$^6a!;UbV+%D8=tQcT;_}-NPkK1&zm{g0ibf&&%B~rjw>=cZ#Q<;(bDK=WE&#wZ?Ai7kT${d(`uZHs^ zs?$K5y=^d5Xe~x6w*$j2)N2|b*DS+!If^D@T*(C;ZBjTupum|U2Cb{}pwOJXIIv{i zAZejgnfC} zCk>tqMOH(vcqWsoTqXQ}$;t(3CHo0dPE7hFsagfpm~ zn|qO&xEJjez*74iS3Y15A#$Nj0z1=rvmp3ZqRiX_Gi`jU$H}#S5j+bU1K*`$vs5sn z`Fox6h)a_PzNgUwpIMC@m)sN5_#d=x)zJRp%qOQShACUFdv$@K4RAjaNB{ijiH=K zno{+ZJJZ&2|>S9?l!kvWVnc>aXdjicZeS8#=KK5bbzRwSmYD|AMZGxJrKsy-aDK zec(BEaQ+;EZNekKIJ_8cHkYcHY@YDndNsa#fB*7-;pgWC#X|-h8R{u}PWJM~E0nD6 z@$jPo}h$;p72sG) zwJVY(-t`0`XTAKTZTpThW_V-Jk}_Lvpq%jvgMspfpxgp~)%vMwKmX;rw;Ii-m*tR- zAVr@%QPDT1PMje%nGlB(CMk2O4)6z!Uqm{8tKT_^pEmhVVDu;Ivn>H-0&NY)jw2fo z1B;rb(*y*#n1dQ(ydzkqaaNUja$&{;iT06Z7l}(GjxYo~RJlS%ApC z@i@=Mx<$6u&6BzOx=lX{AM3Z2Rv8y1f(9|sN62)ezBbuSSW2M5V8IZuHB9Z7Y%r*vdYYHf6 zg<9BfqujWVciv~S+G4mFy}}+Tyc9Oj{@&8lgRx+&-tm053CT*p>&BOPoVsNpr5wmc zl*HycJLSYeo`4|{Z+%5&WLdFM7XGMz-1H^YJ~qTM&AdZpcLuCjd<#hK`2QUIT^88y zF#Sxx2Mm%lXTTJR2fbbM@7_Ou{`~#Rn-GlYq2~eB(ms%Za153dz+Q zKY1JD)yo+tAJ^aAKd(uG<$)fMvL!+YciaVEU4lvV-LP$o#IBnsc8Nanb2+qsX*IP) zEjiYb>$NnfmT->Wd0Y?wd|a#%XYWuIUXg?kCT0mkguX*Sgy{2My*qG`3pPs%lz7@gmF^ ztr>7d-Mij7DsQ1XfY)FO@mqYk5`&yKq>nGp-@h&_uZOu}pWkz`F-}4F42Zc#_sG_} zDfV5NH+-CimM&9eI2>~Mm}atZZTTgXF*(!{lV6D`qLG`~S5iK~9kF14iJE9e(GUi@ za$z|<7Bk5;Z$Q8g!yS7r3>*C5xuWv)@*U@^Y&io*802gMRq`-6=o8Nc7L{Fqf-bUU zB=B~_aySkYbcg49mL#`!t*-30+ zZheNuQyw38caVPB*lZ}^s=O{<0xd7^q=8bwd)5@W=^#aZ$7ifbHBVMnE+t3Src7Wd zDjG@}R9>#lNK+y633qiYLItH$=le^gm~_2*s&_@yFW5pBs9KeO2?MFfBK7(!lEro_ zU&wUj=5Ok;XBO9vFtyR^{pP0S(^?_ZTfedeveJ2FwZON2U(Nn@?W*mq-{_iI%gc15 zUb#wLucWaPUa!};e&be%b;}n2JHD6$p$wjKKS8)g;nvxZ{=|0!%4!2vzKME}v>Bvu zdG4l{X)BK1xxu1;oPtw~O<9$jfBa3_+p3l8`^-hQ)V%27M!c(D&i{EA{{Ma#KD<26 z?ZyiR6Nz6FZ-0o&%z{cItEnShV#jatP9CxJeDpFIN=HuvK-yw6M1@5&SJ2~n%!CRd z^ypVC`K(M2_b;z=k=b!!-DL_Ps@eq3M#vmKc8*-7B2;aEK=7ksDTh^UL!^zcGzQ!) zQ5^}H$s)xBV(M&jV#b6w2|O2)W2$9ZhMi`a)i$YVMh;5Y$gC8}^2TjGl1hO$xpd|Z zC!uZM=6qL2$?=nLB|1lzg%X453^#Hy>8PrjZLc%U%E0`kGLT>aFf`$WXGeIxa1IS2 z4O1cAh(QB?u@Rf4&}%g^BgU)*DP3@A))soGdNzM<-Xi}tnihM9(z7SWY1`#Nz z;GR)!j=4(pY@Fg)!Sj zQuX+MERonl7r|5=1MY$*H+Xv-jk-HaJAm0v=!+tJR5c7vyfb#P&1`w|*}OV+txMEu zXaXiM=BG|UGP2ENctKTD07>~p#w@cb3?bflD3&(%-E|xNYo+qjTq~Vshov0|A0!{- zAmKoW$J_WKc${Q~>26EMCRR?7ySPlDlv`kbCRI;ZUnqdRXJW_o7lx;@(~F7^jrz%o zHk*6;bj`bdRGja!bKPheU&cY<=b6hUP+UZCl`Z|RC0&QkeQXs}EzBD^#>Ne+rtTTj zkMPJ=UV%Wc*6p1)O6udUB&wS!P#fsdLg&GcInQ>Ykd4(80URkipf71p-s1Gl$r&$CvuB=#axE9FA)Ml)}s4vb_P z5&0QTM3re6Bru{-lq5*(MhHRL>*hRvhl`SJ1CV46yf}io^Q~p_*ZYr)aA@07U64|i(l4a>1f3nJB0#xQu0aDMw^HxRWTdr) zA7nGZdekM=-L77DXI?81h2z>4RyUAO*@9n|_CX2;LDvr3TW`|WPyhNx?ZV%G9)4cr zUN9l;{H(rm=th-J4sWfy&Q%L_h|o#PVQYHI%Sq{guSv13VKGc`tO$!;2C_lhw;v}< z(q#ltnqBCSSQb7;MO|2|b972qyWEWK?x-Pf$--p}qGKSHI+H{MW>v@xHk-8&Imuq$ zooCjyoS8EwLT3PGriBF3Q@F!__yq$sSo?3Q$$&WvO5rj9m=YOYtsvP7C%oE%+dJM? ze;ApDr@r-!h$Ea{a&X=>ptW6`jybqqk(s6UXNBv&Es&}5Rs-#I!L;^doO$C~XO3sN zUbcPHF$Wb5KQ)SKl^VY`2}tZ^ztv!$?icpTcwtXa%mX^JAr={^LyYNvDM$)CM{;@IuFlW;GQUNn7N{U(5|vG(E12M;`4R?y%9&yk8kssI(I09XC=*vI8~xeSivpj6X7jdz)dR*5L?SU! z1DF)L>5Z$OOpGs3PC8))@?mUZ0GRBJNd^FBBi5V@5TNq8+;GfCo!K`Sx|Q}&4h~)& zXvMbWcjn)Lnb)Ro5dh7uyS`CrOX?RQLq9*HLL)2{YZS;5FXRHX*6BEV5w2AegWGX!zGzfyK$aq$s zcF;#ar)UPi$#tW(s0YdgP?x{7JC zW(KCE38}reZAY(vlD>WBAhHs!9VYC7k!Sw2(9&U~pD)^m>Kx-~DSf)Al66<_+Yw{o{l=>BpVAUJZ>I=H4t{bghiI zv_(;G#2;e|*l>j{fOGB#Hskyh=$H-pgwJR5^$V#21DxVzS@`)HSr}v3Ps`ua(6+bXSExBiiNCqZ@OiKv4w&27dU!@_NiW(8{UJQ3kg9<|D zC1aDtZe&f{|<6ck2zl1v(ZXA07~@ptYQgaIWSBt>P`xwnErkwl%QKV2|K= zen(jg#ZMsX%LTFH4%*myVzN-V4D3~cy67r@y)l-Pu=mNJzKL;V1?rq^vt$vXo=t=W zu}DQ#$$X(REiQ_^#Xj_HZ$gocM0y@u2s{@355Y}oDMn%k**kV|aB>FEw=En8qdf5=9dktO{InUs8NIfD+7K zV3AadQf5{7ZfERX%$vtoL8y=cq$w_c@%GJT-h2l&NK`ID*maXUWP?SvA7^h4jaQxK z%l(JPhc8P<+SXP7os>eIIUQhzt&nb?-%)7Z(HDja%HwXxE7RZuslKKlLz=}v(^_!g zI-HQ^3J|dAqG>2F(kCe1g{{d*$&92PyVbW$y}74t7mEVhPTZEs9<4q(CFOK~HQAQC zqpTqAexc#21$ z`=?5oCn;{DZv&I6vbq~jWf3M_fMnt>K&gO1qwrZe2$W2;KbfoOo1rzv#0*YutLOqG zc3|&=2-l8)aLg2By+@iC`$0>8{EBO*&?C1j>bv6%y)Yz}L1UMj-cZkK0g2IK$(EIa z^i|7MO+S9PqR-Y&I>pS2=Bsqv&V8aKWBQ@*$x?Qa?(vaqYx7_8^!~1A>HhIEHMAps z4RK_C1XVXu5}Pvgclw$a`f&*jP>Vp)0gBTTmi{A}2jkr@GyDTsIb(HyaejvNHPt)8 z;6dxbyj>Pk;f<@}1Uiqgcp-aNIa-YOiX7L0zHMvwhGCPY2V+xVHDZ)HSYqr_^H^^~ zOOO40*2>WHNDKknw;mzge<>2gxkjN+aNNSiZQO|n@wn^!FdUB@_yS2M+a54$$y)vI zJ!~9XcxZp_*Nj?vI&c|X<-eRynP67wcIU2{4dvLYa({n(y?=T4@bvKh^=0l{&A<<_ zA(`WOJxGZ^TSQ(20qjs5}Xh4;$lt!?lfc+(cyv zil%OqRn2=ZG6q5!lJ`Is1`L&9AC2Ob(VbZ|jf68vG-A{ajOu5L84kFk$RK{jEsFro z)Gj+niikM*i5f9~mzlGsj14K!%Gs2&F_xq}=(gCE$P4Fl&eG|@1PYyWoxBCH3)LI6 z)(XW)vrbClqAn-KR=rvG4aED4a+bJVy6pxDvRJk9^r}daQk6l zZNc&+qDL$BR2X5lxueX@Dv=Mw_=J^tiW>3P$M?T35*X2cAP1nkQ@LMc3W|C9* zchBEnmxfG#|5JlkHApxW`ztN<815G2KT5)vi%BXaFkIZu!Y~ZfGE*B(RhUs>zZ2P0 z`X&Cn-S;?3x3c5pns3u|v*hjSylp29pp79)Xb`Ld<(&jr0hCd(lhAAEA-9kcVx$7= zj4kbi>4{VMcf7*ZBH?tz!E=*SFA>{hGV2e4JKHFKub(JAT&Y9QYXunF_;i^h~!TuW1C`{X~fA?jY>IJ*>_4F zkBi)R^^FeSpMQQnV=yoD@oIs3D4bq#xYfo+&BH9cWbYM)bBS|5dcU2qbcS&vJ#)B! z2ft(TF@w;NEv^`C!WPArLcaGfsfnYsuP8{{XaLF8s9Tp=+pus5@Cye4clAAjSguaQSrG-9nFsn|rV_jOmWB*HQ&X7Yt`_o; z>^scX7S7e8lh??jAB<400j1uknQsrT z7-O%V;u5kneUN%*<%pv2!sS^G^JgiZ+KE;t<1g~$96`@<0VhK5=VNz&MT^$m*`B~X z4i;E3sl%s zw-tVC^Ny2YnQ23XgphL!KJ#D#9&%;&3r=bjMq(lOU3vhX6Cub}5#JbS#7z_dpsfsg zbB>J3rK`8@cS#ZQgsv8Uj^r^&i4&PCWJLf*+*S!0Z5cFMw8S7Ai8~8ip;e-Xqrioy zUk|GAKrtU&=@3i-Q{hQ2?+@o9sIfTVRXc=|;4L!y1G!5Dp>EHiDF5Lb)&Y*OcQzcd?QzXs{Q3kY~C@YOUVyR zfC3o@j+SmV)NM%U=L&%+2;ydGU#}dq^aI)7u&9aPUCNee7qVengEo_q05N^7LL%qw zJbk~Kvg`7cqlgHLb?9YXy{To_o`4^nS&g`P*U7hdY%FOeB0tOR&=K`$4%*(_3<4i@ zU^b9w58{!9LEck;I8M1bQN+Ai%oZkJgC!ri@TO`lo#VEmA2`Xxde$a$r4_5|V!y6N z@`Q^5FVZjCOHp^-xK?HjfOD+5iJ$9hHR__fy_{ojr|nm{T$P2mlyrwZRMVvLdVNkR*s8oggUfT#-TsMBK5gY2KYnv}tJS@KJpVd(()=&KQ4G*Be~JzX zDg{zV3)G`(ICWFp^ZZ7f`2X?GdA+!v)9Dqh;e`Ndmk1}R3V|@?q@wD&>lL)x#CF7m zB}GQ60c&g1PDrElkU6K_0ZIe7gSeGobz-mx0$z>XFO_0Idv=CC5BZK0cnU2N#!tnT zt`#N>K36q=W`Tb{c=`nR6Q*Y8i?7NkTlfmp2A;4vkBJi#&=_#hOp~z-h zl(Cy+)6AR3G*Nkkt$Jyr?L(b&8~G^WDbjv#mu4>Q^20puP_p4JaV&M`z$jL9{coU> zQtf(A@b{RU@al{d7(jS1*eX+mJW`fQ*WMgVhf|Oz;ruI{YZ#(D6kCK=)Oe6G6oGsO zfClM*g%??Q>`z}8d1}|X>D53+lb1s{@h;{Wgg-pjFrD#M+h*mbZQLC=9p?dA>kB9Nq_9fMsN>Pm(o3|>$+ymm7$o_d$( zOEte%6>Bp6-2ucC@?et2?CX?KG$Ed_)4frD4^UYsM(vgC(xHLDy{=(yCK{9tB<_~D z&mk!wmh^W`6K5V4Ys;`$nuo=jg~ga2$%3D;f9|(MM2f7LFoFMT8JCk3_vDQkq0YekaivgRfGytcY1Gw4VJ;U-xXtn$6qXjh5^AxryC> zz!XzoQ7sjWJHYyXNjHXb?RCGr0Oz94>#xkCZ`9yg!~CC`e6uFS z?{evY+56CFk?7<`Mh;JtDBr0vZ?0pnYX9-$r{Cs`Be-!L>XvXhPt?tLI|yNC#J&;j zIr?og)RTiaDI$RfVPBb%Vg}12ihG9hG>+{Q( z-97b&8G}EnG{H2PRFvnMQXBIu!!0$mP;|X~I z(^Xr@FArUzWwGB&dG1Q8`Npv~D&zUX!^@XN_G#`GShvj2hf|)%JgWtA9ehc~O@Bf% zF>lJ8tN`~W67e{1Ziu@oJOpy_iTSgYUIj&38EjgoB|8$Ah5KzHs#(7ZM$92g-T>ce zqK@9x7DyzX$bwUIQY3QukgW^G-_-*B@(Rz%)4(hTk1;>raKvvTvwV^!swGr4>6gw7P zsG6*ZClE0inbpx%T2nz0{&|tjhaZqUM6aKH1${=BE1531*1o`1LSE$1|W z*qR`lBC5Z5Q@p|YOUBY%@;b)sa_oD;PPs0VP46cVj!x%2mw2*y3Ph6DrM zde?k%L1kq<)lR^vA}*;?YoCcRRYwAM+tbYAa*4_2b^HAG_3`!oX({O`^mG+^+U6O< zDR)fu-;Sl4!|S5sbd3EH z_{kMbrivs(cb@RRw3Eg18C^A*IE-bDISk}P26C9`uE93AoY;4%UUdEAHBO{?#JP5H zT_`*IxpMR3>$rYvKtq1}@ci4Cm%c**eSe>j5t_8_%g3^HE45tzXf?C_^eC^pg#+Q8 z{xvTnjUwl84!jKvWOLc6@fx4T2X>luyZrs_!me~63=dEJylmPnwUu>^V%j({wL}pyjimM4`1--m*@B2m)V0h%j-{UnTCaH zlMHbd-#6VI7kKMxkeAzZCZy1)F1eI-7$Z=VZ;h`sUrg`|aWW z*TuZ{t#iLwt{=FqAFG~gaQedXB!AECQm&xwTJ6uLrgN0B-_G;r@%sDtW-Werx&M5> zY}denT;LHb!{y^F$*v+vdrycY21Ok~wVsSbNL@q43#*@6#e_8RNjcf&F7Dbv5$FvC zh@ULc{laXF<%Ha9kZ?;Ryo>nmW*`p3C{SfM0^dW$Wf0A&5jW5znX0mRBY*!j{F#$u znD#lZWd{1MB>Jy-%fK~WU!b2}mN%>Xm$AwhY!75_GeZpZXiUUYW{wjGCs1q+On9-g z)l2{u^6_pu_kpeLY{JA$?$XwFoG|726zc6VfBG;FGsZ1d1iTnlK?K@rU^PyZojDp7 zIt6kbgoXt@hq%peUhK>BHGiz&zhOi|HLA za+uUPk0u|UcjV}oD9g>gA56uzrk-C;y_utGhzf0%2#(Yxc4xJ>^M5IiYop2^9FvaX z0R|-F=)BIN1QSA_m9Wne(mEuQA*(dk3Ra$IiR74#Qy7jsaIE12e@qE2o)HgAX>v^G z2l4{=%j;0JPOGdzHxAAbX?xeq3=4sdgDvc~YzNl0~1F9(dv4pIeVM&`x>>wCpD3n<9dJSlxJ zscA5S_Rai)0~5^@;Us#bF+VFo8tOeeCAPv&Mwf(*acAmB3Z9beEP7byd~@@XHr(sc z8m>jr*t~ zOH{l2Jb(S45wVe#H_B?a?e_PrGq43_Wg-D2u6xIhSXz4Eb;;LkWJvIZ!fE;)g4~-H z{kV3)H6Hs`E+4ma2$3Fcc7B`tsoU>(ghS!pJbeEA{L7n-FCr5X8?U7+zR9=um#x6k zn?MK8$zm!|@-95U=v~&1yjY!k@4IUB`&MRCmw&gigogOj9oG6}YgKACN0Mznm{JyYTs^2B#L${|v3aBJ z3-?3;^vwXecv}}sG7dpKHBq~})TI%m2B3+Sub!pJeRBg3()%zTg@7FkH}wNfaI1^- zGk>_%MG>(I_$Ne*CX$yHg5BdD`?xQXN-lLJ@+@e@wUb+zp-^g*6reiJ<_Dm7#& zN>D}ExTvPz(2Q6?msi>L!|Gys?M~OF-G8Okrfw|v5bUx?njdK54nq9 zSH+GIJ??F#A1@B}dPXt~2%iKiCbxds^AQ$4YbTaH0i5iCpfAR*o&^w6+RhBluz#TH zsHSEm{$ZsqMM%*=_E5TWxUZ$e8}COak(^xZM_9CE{coOt<&grw$b`VjGb|%p?&LrJJy+uWmB`NmHzL#W*ez8*W zo;tMxD}$|7vx|HSYdsZbr+Ynr{(tcB^0W--K$Itp^a|8b5S5d%*B>YlKP${DK|72Y zE2NhBV}opdw^$%Iqboq<)3@rp%KP~~7p zy&lVr)Y05-nN;R-)Z$mMXOZ2q+A=8ubi|%15|g$!tlr|Zp$op6K*wMUcz+<*q8BDt z-9CsAG8vgVGN7JI>ePyj;BL-M<1XV!ikMEO6nUO1_fqK*yH@LH+(I)!GzK~DHKLY3 zS^@&~D;(8XorDf=>7%jm6b8-F@JSv9mP88Cf~HGoG8plX@Hzzf7I&1)>7ek%JF&}8 zA7a}%zPvpA`1#?(64d|?FMmcfH3I-!hN*)Qxdogt<1c^1R0*1-X>CD=JwYQ4btmC1 z9v0cBzm7kw9^qRqxuFsDVmX3{II? zh`BOj&^WAD!d<~jGy7%iN!-`Zt|WbvE1`K{mzn=aS;U=P#|tP2 zU*0_a^V9q1&#SVG6@Upkm=XqvmJ3g%*p9*4BI;a3){+Gdykxc)VQjHyoH1$ZJylLc z-v>%v&7PfiXu^knn~q z!e$?K6Rraah@!1HgO0E&a_*prwE;?`G%#Z$O>1?6O-qZ9sqQ4WOBi80P#lbr>VO1< zN-xf_h_xai{=V3jL~{)k1dsCTNa!>x*#C}8F=uN^@HDOT5q~L@IXiKKM$$=V?x08} z3p`#BOfbOKIb=;83LCECoe6BA63HHL)YWKmeHboOohAggHlB@4px0AFC|c6;zo^kb z6)cYPiuQ;`8eAC(2J+scz`C3Vh5P~CG1w@Cv}aVJbaKg-1Z6_|Aj7uP{^RlU%bT~) zV~^dCNYU-j|9^{kl}W5u%|2wY^`U}sS&|Z&xc+o6d_O_}K=VdcV|CY}re$BfTM9@c#zFKZR45y4?W zA%Rs8tD;Ly%Dzk-XIBa}jmSC^u_|H{4>}?Sf*x;4;~2{1%VbhQla{Rg2Ff7clE>xM zCSHSs2{$M54n%3c8R8f7NniU7Axd3IL8a8!)j(H>6JbrGNRfmGobAbJt1cu(3}UV} zL$<~=x_=#0Q35-ZyGgp_2uQspk2_b{Yx{>jMd5UU>u?!O|pI zYh8Ch6juNX4{6#1RlzgjMzSWTRYr@H_h#Z)#L>Utf zqhd3Tb(T6b!`wE}p)ak_s45}Z=SASzq z$sH|eU8#Q=XeYYKa|ioe70i8uc7EVv7^3MtTJp$$D=fMcFNgIDQcFi_3}Ewui*jfq zk-@Y^8URp0ufKpOtu-xCIKGlbfP(SSu6hP;3gj>tY)3|Or4x?Hr%i#O2JKAWF2nB8M(3a_IH%$#!ki#kRbsF0&|`U#H#KE!)*i1Q^W!PTSu% zpZ({@AD3TU+_23jD^jldx0V76xoDN|?&>1-Z;6ET9y+QNUpk}2ji zzY>-=L^`bV{8HJPg?@f~d09tfk=d_say}3t1(w2gWgz-+--+I#bZtZ|9`H2HFmTm% zH&N82DpM&L4{=-~_xX`}+K@)zncG|N2n_&?_B@!HnG@46ITosrZ_G|zu2UM(hC>P* zQ!2+PN;D4+(KmDn%LGDk73_aFLZ1%gA-tpGFXK;!=0g|=29~}6m3vatwnC0lpeNfA zn+&e%lprml{A22xNL#?coJ<1J>@F~(@TggcJ4-Zi9H~EW7i?n8WIE)BxEK!)g@ZI1 z1>;~F;zS`bu=JtJ9aoDRr@=Z|Z-j43Bg-s#yQS;&CmWU#1nCrriHF@1q*DMoH~nhrQ&#Gv^v$!^3DkT*PFK# zmso^F8KqHVL_XaH68Iem3`EFm<$xq3G*yhTx8#k63kQ*xi4LGW>pAuw-pC3Ow|Kst0U5h9N7lE2nxR-b~v4+t}&@4_@bXSgX=yEWCY|ic& zWdA-_%cM!|`)s^lJ&$b+3YvB=7>>$4w<#o9$guF~ke)*{2hTT@rsmd~>(Gq16u9Es zUt?M4oTd@PYJ`7IxI?#fIHGzArQ#!(^Exg^X@M?V1{lmYw{7*?-n#Jj=ZDYl*2YXI zVPe8pv{mRTyX}SotX<_a5JBhqp9S3&?h>q;;GC)_QKp=d2>U8QcLVm@6gll^LMh%% z+PL_0BC>G|hV7xQ>Cj_aml3fD|C$DiPvAZAHIw4)=uO=s^S~64?jhZUTn90&HXzQINADNh%N`9)5Ie z`WwG_>(GD8F-=v}sxN+%e8yiBc@JZV`}YQHNYUcUKw^RZw%^Eh0GnOkw&9ghvotTn=}Y-;pw8)Vm+ zVzem=*UnF6L+xsKRdRb`Kj`noeMABnI4hxHKX!kDGZih;Mn)IoY>4_VsJ}-&U)9wp;>+zTE?#psO-3>#zpd6q9&JOMU;}Y$n?N9a%R89J+FU+&yO!( zKd%F}rG||$*QOx{dOy0dfhMXnn7!0Y7{4Z(Rldjw6Wqxu znEHQS+6k%I`=|p>W&>c?@ACQf?5pqISy!?VMhI38`T>QZ6Q<5tGYxs{ z&(TH#ak_UrGMlZM!Dh4=da}pBWlr@4cspu5nvZbErb|hxx`4Q&0QA*B_XptBEt9Yj zDR^O^JgjgVDqLWhZzQ+lQ8^#j->W~!qLz>R*Ju45AW1sVQV>xD*TWGNp+=RN+D(56 zO=LaBJwAxNGsw@yGjCA9XbC2oC+sO8y?3+|;xuleq_S*gRjVi{C=yB}L#d~A+7s){ zmh-gCnt2e|*Mqe3>RnlO>ZVPxlhW84Tpia&&)c*GkK47REyM?17dQ7;1?{PZRRf-U5X{i4=PY zD$;xkaILu;Xr6-E*-!Fu(Awl9j$#H@p#XhX!YpVi!dr{bDk_W`rKx??R5ecxXw7;d zWEfo#H~^9|!`G0iB$-Hu0dzmmB{1axLL-*|0)n^?C5(QsvW~O;U^PPHcO!rF(OEPs zP_MLPu_p#PQKGo3nF72E4e5UK!VVlURdw1w1(@q&;G>f@U5I zV(Ko^>^@2v-qFn0jQ^5=%^`n?Rr$z}J9e-`Pu65N;G1ISPY6yR{L<&{c!YenkQ-z< zg(-n9GY4c6I}){vqx7v9uEEcMpGXy*Js**%D6`7JM2FGo6b0bBz_rU(9`yZW#T5R% z-V+bVMa#kg6{(7G5Uuu-E45ZJ&_ZB2CZo!&ZP&B&`-i`;$Q3P85juaV)Hjn(1c}$k zh@Vy*2dmw@bSpWFnY1T!aUyf=AHpS(*`9B&+b!8H@R4`K9Y3NazuV=**?m&?z-*WiGj1w z*_e#|Q3A+qcI;8S*wOX(x&A`e-{|@)U4JKe$G&0l=T^PH)%Sn5TC`p5+dF4lDMkcg zb4AApUo`fSE0$lQ4ogNQM&AA5BGo_(=ZhDr|B((F`~8cl0Zw9jW#==!dHekF{Nu)kPdBuXCju#>uW`PtXtV>7gyQsKHw*=ftYWW-5IOi*r!g=uI7Fid(8k+ zX)s`(1HrgZ*VKRcBXDEPc?`wTo{48dy3(i_OaP^MKgsWe#$h~xhc^)Z$Vn4h9QwMS z8r@eX-L2`I=|t`W{f_?T-P4!9L?ixpn<|*^IgYaiPo%)7p0)ogc4=H; zp{Y@2--~BOFt|P~;ZmopV1N?&s_hc9t0v+*zJ%Ksa8`d!@BO~7_382Bnzs4B(%;F~ z&ePm~{mYqo0CpKG%%T->L$yhzjyGicQ^#HKy0wa zwWudh!pijAIN1sPTn&tdy$~_J((IN#A&ocMWhv}2cJz5QVQ_BvqDA~GkPtHI;^!jC zypm91IRbw~29=J?wJFeTRVm+5#qJ{=Fz%w7m_&0TljuD*0E%6y)EsRTqQqlC=O!d0 zw{R3Ch5eeYXX!adP*T#C&ma=HMMG!Wy(_i>t+dWp<1;OUr5PhqMmYmjBD@jjC1Wmw{z+NWbjuH za6o_Jr0(NT2cV2(kq=_9E;Q(RCAExo zfM{PoGVYmQKM@nek1s}_e8~1)Y2zsN<(uGEz6qIbpMBsE&^uGJ z&Qz^4vPoCn>rh#vtkQ^O@$Sa)s1TXP$fBma={OUg zn*D~dUo5H_7G9RN_R`gITMaW!L-%|EbddeFw+JDqaxojHeW zIj=-)ff$iVOfi-`G>Zr3vg&_K;qH7ZA4XoW>}cZ^f{hX~ekv`)9Gg*o#D2BibDvhS zB@1^LO#t0WtZr!*LMCxjjP62|Tj==KEFG(X@LKMViKFf5K=IMq3{0-uJ$Fx8d`OuV zAo@mlxk$XG_BaVQ~J@mu72f)nPfwgpTQ(#z!T$QG+r?t^vN z!W{^ra^y;4af7-`GOP)dn~rjPusd@jNCovnGjo5$4k1LD+Yf&V{&k|9SFbG?-omo; zVzK}#Mr{D`2f=tkN6}7>Uav!u3j&;kJX81jUF3Ny6g8*hJZp)}8A~E8E!DiG8{OvzYej(pnTpts zyo=4m>x=oUym^1GPW1SYIclsCMN0BT#dM*MeD*ZbC0JL3pQm>=C$c5>Hb)L8$DkcW zts-WrDbRsA1nY6sP`56J&11Gc=d5?~u&;j3UZ)L2u|5YLT5WsK<1oTW#d-T0Mbnmq z%vw;0kxi89P3(3kru95$(SK3oP1f@)KGRzSi|>7pz6pQpeAp$KFU^9R)%}D$VE;qV zZL$vN1>j^4l<$sR&=2Z>jOWrfsxb5L8{r&szSa2kIqF|8KdqQq=))0xP^HZ@&***e z`YY7}Hb3h@SWA5;so)A5m~Oe#Lm{o;fwAV>T&P3z6|aWZVF~TQv5ixP z2cf`tTa_=e+V>z--Z_b$4?I8n#w0>h5NcF<=&*mUq>XB7dO#`eWmiX}J%b;OEt4*x z48RRUXE>x;3o*B}+*=LlQ{@NKaK~@7;BYr-Nx*FgPCudG7j`E&PQ}4X7b=Sc7^6~* zZnBi0=uoNTW2!Vq8nB`~Br)hdOI5GfEau1i>>c*rUl}xSULOCsL`HUcR%}6e=rrXg z$FF~e?I;hQ3iU@ZeCrVr7Od3}Fmg{pQ_!_sNe~+q|4F=40k1<Eb+nMUl@06~Y*c*IeJs%ZdV;L6UUz z`J?b62$-y<#OW}ws>FuTOOjDYfS^DMkx}Cgl*gHIwB%ZdGN>OcrWCzBlUhP9@QEf> z>o;z|2jk`@IMIAH_`A8+MVQGkihYgIx1JhO7~G`5&D<+!4_!i!ia?`*>VbqkoymWr zvE7o94aP;9yIpq^XZIw}<#FFICk#}^Jg$h9uI?$aSlCjJVoT#D+MC8RkqroMj>ce^ zB)CmK1ml3k^}&Fhqb-h!_>HdDnGPMOf||hNFP0Tgriv(9V9`_1ci2f-`iJwJ?)zuH z^8ec&^6BOI)6$WVX*SEJC`jCzr4@fPsa`ax1XYsrD|QehI);9OD&vwn)z#BL1vV;h zZs|o-m^W{K`uzOi@$b*iKd<3=;98}8jbmn}P81E29pLd@zT%bozWMO*c0*sXin*)b zipdMx-=V6Rex>Dh;i&uQ)@{oz`17e_H@_0^zSX3^Jbirk{L7c6F(Gc$MEQT-*%eZ& z!Ip&u9(D(`E#~HO3iJC|w}oUWd{x;juw#2{i}mH@hYxFQR+6_EokQXIFB-cEw*zu8 z3{+03TJ~w5wbPt2bylHwiq~|`Jq`n}lTidkSY4@7)0Bc1G5>|Q?Lpg-jA=^yqij*g z-mc2-&R7ED9EeniFNSuK#gTt>I>g|*Y8jCk3L1dBno4u2=lTffbaKC(K zl%YT>wfkZ$Y0Y+7DRwYdvKVa7y-Ksmm@&;PySrHh0(bJE8aib~HcF(P^a4SL94w;^HGE?9n$x#Mw(TaBXUQ;Z3 zgQy@g=i0$ol6W*yV%w{~eti4Wifov2vM`aKi>Xx;#cb>c@l4*GNbOqhu3ff;?8E;0 zA1Dz^)!Xg(Qvdb1C2xOXlPh{1koR%Pq{R|yPG`AI2Ljf)FG~^E*i_Y>g91%u;Y31u zP6O>>fjbq^o#Mg$(yWp9+WDNt?sUdBA0XRRVa`_WC}EF4C$NY_Z|}4F_X~=Ng+mon z+@MX+Sq8}x&ML%Zzg?QZvtF5qSRu{Z5YJ)mN{i-5W=&+gt2lq@Fh-trJe4zHpu@Mzhl;{7T%uVw zhj{kdjg~e_Fpo$JG*N#YOe~2+sh($5rz2~yu+e*p(ygn9&_YTX0n7_tl*jwJ>h9EpkCm@l8*FRp!nNrgq=&TSrDG zAcBkG2{2vKX{>e?^v096 ziJpV%Zy0~Vv1nykvT&gpWgLb0AY~T3BUB|7h)idYW7Nt2O8O4gn)721m%0T|2|RZpnpC3N| zYgMqiWI;_!5>&sSP+k2f4L2N3kMwXtBTV7<<92@oL9PNkVOyPrZkLdW#}h*H*u|pz zv;(O}Ig<~%rP*VA(JOU&gHzv^b@12NxKfOuV_Z6&$>I{5!V-V8=Ez35LK z_77jbJiXlzeceC+Py#))BimfJDs9V#D>i6Wc?jm>9sakhvr-G z=!AdTu@A;gar!HKx*vaf`TN)Rf8Q|vjk}_0gRO`Z*nhGGc1I%?De*cp43M3;uGoUH zSGn?53o-bOA!pfi^g!l*=CQ4Tv&4PUnmYE!LVnZs_iBRx?&-U>4> zVcynIJV5o-R%Am~!CCY47E80*xm)cFPQHIIKsbG?VZm$UNkkuK>V~455#y>%U7p$s zg9v1~%mM;NXJRs2X%)kf(X`&p)e@2Ywgo@_yowKDNbS|ytDX4D&A2iFC|8}g~nvs$vnaJ+wD zEyA1OZWjs@Q4R{($x3-e<~p)6)t#VRG{bsZVVi-zHP}W)N8vtLW$Xsd3S10$1NILD z!2r<#<1Pt=g52;Vf}Sd_a^A{bts%LystYOwNl6S+$D@`7OwcqNK#83N<|mv#H7Pv+ zk3!o6Uyw{_ghJ5whR9=-UNK5IedvE6gN2jILGJ{&j-kLDG(uMRG$omF3AQN+XL!Wx zD1`oM05rgaq;PX`dG}-N2^fgrA_$^Lm+e7v-jP7#WMsTYfp-A8G3I|ux?(pJL!ney ztUO$4#fTbVy13$hXZbKCC=_u?2$vS_OdPQAU z`n0>(tQxPAquEB({y2?RZ6v_?M_(6C3kM}7u)-Ts$LrvT9_fkkJsIzv5R*m>g6bU= zJWeZ7Gj$?AwH+GvBIXg^j0VPwxvwGcT1iqZ+QmEV9AN<34UUy+=3@+-#gQ{8_ShGBA3`d3bTAHV){ zC8Xr4Kmiy8G{pPd1MHIpAU>nxSRLWuMF~xlA=(U12l$QQ2C zfE`8RN5z6lFOV(ZxC`452||mFLT=ka3QrYT>1_AV%Wcmdg(gv!O5;7c11E}Fsb3@p zikP|&B8`6sk#Wj7k{Lrd-^yAJ{FjtC{gUH7<39{>$CLUsi8qk{Ud+8g0B-*&=w|BX z1Z5I#Z;JM&czaXQO$iSqJsfXu(i=9j&GXxzH$fkB9_Yw!8+*_z`>I93&Tkv;mh{oc z26ni)0UjTCxGos892hrdO2CeTZk%h6s2}wL#x{RG0Bl&Ud8Kf*?B|(Osxl?dZL++c z#)lWC*|66TZ=OFreq4bkzOMquPBJXg;a-c`jl@fCi?J-~seES@x8G>h_`mvbUakMG zZL6w2#wt<&M>LFERotx_#;qF8eXC)1?S0s%5?g^#lc9%Na=;9Izzp-a@n3uQ@88h3 zaa4c*%z?BqS63rGT-pcS!u*IAtl(M0a$_Y5@0A4jvO__+=dNC$U<92If(aC|)u8Lf z1@c}p@lF>K4U67VD8%^KRfK@Ka~Q+ucM@}Y=NUj6P`qse{P?tHSfLLZPl(NJxMr?g zf@M=Vop*@Zr7T(QsK*PV?f%DHR!+GuVYKE~iP zK))Cv!FTF#AE`)VEGuBnZE(~LhWASKY}l@|sFb|^X2AJSjiXb5SR8g7sho2EnK|rK zZXB~Ke8Th<>=aV;8NBbG!ES+A-9l<$JTzQsc!l_s*ZC#W&c66E*ioJqng!hTFIRuJ z(~dcqh28xWvDdKmh%^X3(2mI#h_?nxY%*^O!u-?qJD9`1R0FdiM%#oWB)tHDmqBbo z*i&h+4&vQHL}I*Z{YAYeF=TUF;k7psj(>)x-+0=~DI9~@fePhd=u6B{ zSY}`dfN=_}1ey$@Lv!4ym(7B*+BJWZo9C!Ar{h5e=o-_%+E(Z5r;RV@zbx^)cmCX! z`3-knA-VM6|IicNLfMe*y0f3Aokfvx6fGWPn!An+peCeU3LLmCSl0R4_Z42dqE zZ&_RvG^!h-5&boqmpmn-&WWZU&<22FrU<8MzXvj`PB~n3RpI3%8eqPR7gc{@f++&l zXg6>^u#9!fl*L7ClDyiCLehdZId?EJxkzHCHwAyRTX^Ms%VgcIA0B@E__&Hq#%K8( zNN(l=&bPm54WjTG?pt>1y3~LjZ^Ja080@u}w6!e)_C1J;3U1Nz^Zs63w##m?oNbrx-Y7>=NWc*v?=8;5W zimF5?kSE7Ux_hmKwyFkg>95Z4SIgp3WP_82w1vKk4o7X1&zw)_9q@l_6+m^2NM1+& z?2Z=Z&*N@kd!RLLZ}bZf_E?%r0w~7lmS3&MdTaUDt46&8DSI+z-*B^eGO{9_>b7c6 z@85j>y2HWbs5F(}T%mAypp2i)bEGT@MPajWz$E=tEg;tQB)Lwi(MqD1WUnB1M(ru0 zNYr|@Ur#n!hi<}yPS}4%(_=PiD`L)r#AFZ@FtELIA(6_pGH5pm1`AD57@xXb8!7H! z+)y3~sL}`Ky5XOlqY{Sa~+&dMKu=CJu>2r?Uh8wF#V{Kqu*_dy1G+ zqp(W20Z`f``XI^yQlriruUF;G+o#WO-*30Xe?#zaKM9Sy(c7QIBHjMv7I^vd_iufdx9r|?F}=gJ1TGhR zx4!DRX0I-WS8heN7luV6f|x3mfK$OO%6}O;tW{jpHvQk@^mk(Lll{y2zw&X0WN=V2 z`){=W&SHPR=}&`#Qrqfc+w`ZdFSEXny=h$VNRCK_D>#Z>xGlm_=5jd2(WTm5k1Hp3 zf4y#s64i&U{!+eG!LRRMo<6O*Slq4TUg2HbspW2SSfc8s z1?r?c2WgujPf+Rr6L*#ysBnnBHnU0AyjeW32m(U0yeXWiGp3xT)qnz7)0rquw$m9K z8$*8-i)-~_egoXi;%Vf?BsW(kLlTIcxQkawztP&;J?sCJ(I~Y@awXfyT*$or$|(K( z@b2mB+R)>SmYR9Yx$?fQ;89gtZ9(CpO7?wVh z)z6u+#mzj+lHZO{?_u@;@r@fvA7o$mT)=;tgeSqk-}QYFXlhK>0fC80QT@kkK2KGp zZ<`P*#%QQotu9*XTyG+p_w~E0y8pHtD~!Qpp2l2-S26yisRZczrCP!KV1;Epw_ok^ z+H4)Qfh&mm1Dz^UmECS&$`Q76*5tv!F&o4uG~M}@fvL(fK9yR;9m5hA8k^1HVPk(_ z&5QPBMrtCLiEc63PiMMd#(RQ;p59~ci=81p8tA%40}jg+P|1ZfBau(+aFy-a4kEb4 zEv=t1dM3K16PCqG;n|%fr^{Eu;ZEms;U2RwSHhUdvZ>6*|LLJ++9+kpXZd5|t%eKfinaWeI)4xwxL< zxsU>CAn^F~IRi9AeBkJP7}XDEOp4b`T#gm}zhviHe*(P-Y!k-UsrVa2c-Mhbj4tMg5!wdV|Yl5Wx#SOq1Lh`~XCF zP0aq-d&vC*H6-u|5Nexob`5_54dKLGMINLe-f%WDeG-`3afvr-uxAZ_63-6iJhbu}6O|7Ug;qnbRm7 z5vaNdMtxe6Nnow;>sEw};g$#lg;#(^iD!&n%EMPv%8J%wGUOmw;EQnP$sSNHxNxm3 z;5c`m86%PE6_fo|u z`~ZG$XU^o1okkEkB{zSlEJfaSg<5fx*t$(`E&n3aWd?B(YKJdW!5A)mr_%#mx+B_;2fRF_~OtLN&5-b@`M_W zWnoRp(c?sxPT&{8kHvJSl5nrh_Q5;r^vma`e=g@|sC}4clDdDp{^~E}jzN4DLU5;0 zEx04cO=9XcNoNr%hyp0%KIH(%Btd+!-*5sk=Cvpe$$ z#Ezm>tOq&Og~)%%L}bMKPP!OzD>$p}DCNTlb4KP9n+UYrosMJqUL=Cj$0qjO2|}FN z3+jM{OCGh*KMg@3+% zw_K|SbWcOp70fhQ5bjE09hC3{TcLO+DhOS@So+6BXn=nP4fx&0%djd(qtj?7;{M2o zmF?FI3`NnHE~dG|p~(Q8N(C;mSCZv$kf1rQ(2+e*NR)hEXNiS@PM+{~+#?$<@rs2o zL{(~2|Htuo@nH$m#-xfRrc*p;JI5vzA<|YzWjcuu23nL8fyS|z4gd^+=UYyfTMUD@ zcw83Q)5U)vauryENtA39CQfrJ=tuD6rHNzVC`S_Tww$g@7K=N*OP-woH9iWEfGNt$ z3d_Sq9Y;B~2cR>`)FTVTM|;F_f$<#MZxlImxpAbXYGh^;lsD$HhCy}XDo| z_QUfk7Mfo1LIMD2T#iZVvPrj(v-p_9P0*5h zi)ktK#O^o6fVWu;csngYaP3a=j9yV+jU4ujkL!pX3`=C@6eGK>@yD-Ae`iK!bu3qg z%!ae9QDFSdUm?1&g8@QbZ`K=WEMX$Q7JcZcy!zNHAUvo;V!G8?^DH+P2^KC2G!Z03 zKpB6iNSyoS-8a2|T#?s}8=14@HY1f*cc1!9vPmX$zOlIm~(NoNYPEy)hiCuf~YC#=zz6i@tn$`0;VYiZ+Mx3XM3&OVhD}pwXHDK2}+q#UBZxqAUhlXuD@1|ja`$WW;h!Tv|XmD9xioi zB0By(X%{d-_9xc0U_5C%t1{L`l5&7a%3A?XH0GYgWoC6iOu|5BejHRQm4J96Y9fEc zqO0%w=m2_s-+g}gWj!9^$tDLoT~`#D{PVn6xi62#W*~7HD)jVZq8KZ+8Yo>L3ddvz z=AHz5T$0Nc62TIA{A2s*(}&gIM6Wql1v#H(UP0bTipKGuk`ux)BDB#1#PpJ!KMUTj!0KEL0scE-?ky{ zb$zmPob9HGaGKis3_~+JOStM7zf0jZe8T@}Z_U%xCSkW;i#V_GHwyFG5c+>ldve4x zj7^rbI2l*Rlkr$!x-wuEDwo`;Q%EuNYS;e9)4Rv#%_Msk@eAD|tY^GZhNRx*KdL{! zJU%ZhqR#i3rt$ zp}tAG+4TUNh%^WQ8`3;|zU6)?X04XvS9Upat@iXmL7(_AiUj3hmyvc8J(Yt4$V*P* zmOf8;Z~FAp+t1IRetOlwZT2^ol51Mt;6;sOzM3S`($?cqg9t|Z zd6LAqrK>Gj2xnplr<;Ev#ASwD#I9(8Yp+*qvlE?4MRf)Vkz)gAIscWf1o@ zT|+Tw4Ct#{veS0Ky#s36-FR<9cAMMYxaa5O5X+s z6E=K+B+>OKX_iK< zr|tI#I2+=$ge9n2-})*$XGyi_(GUYP#^z-)Zw0rSNN(tqj=ie0+RM~wtrM(uOcF#l zG<%4B0`8MsvxHT%Ag*Uw z?M1UdH)HjC09ivk(H}6r=v%F{6A9F242iTrms6TuU_gHrgcAUJ^*j`b$Gt644&JQ- zN87lOnP-g1Xu2yJDM|(%CFc+6RN3Ya!Ra^qyE5B)0>v;*+LSuTu)qeyvnaZ|1%v868ST zjr?k(RLXxhqAe2YJb;;tblbVp!|Z%`?DNi9;uPK}ZeR#5Sg6CcFGwNlOxE=8ZSQ}p z2Ne>MIs=Vo>wlN;?o4Bw(TN#M_@#aPDGD=$0W9J2!5O~g8bDcP8K=&?^C?Q6I)=QBwP};&xob1IEPKgz#4*OV5OeA<3Za+Z$qa0t@zyxDkXiCLnCt5LO zW%v}PYLS5mptqq2n<3FX@sBc^im=B@;l;?^)W9@dACY%pA-NM-IQk;lzvTAhrc24hzag?@5sl)znr8ScRuCE$G4v!eput#r>Z0PD!`ip5Y{M-nPRY$OksOJhRZy@_GpG zZ;#jAFU1bfds&d*4YK{M_rJ!+`CpE~{2qTGdbyhdEz52VKR&+v^89(tnn`P#EOr@9 z9+vUBh|XTdj9XA=o70{0TtLMW?R!?7p<%-rN@&5bU@1j~nnjJ8gU^wr6uV`dsIO^3 zNrlR8KjlB)zJLDuZso~!5}T*-p_oL^&|_?P{w3oOSl)0Bh9cHd=FbuNa?2d#hZ z)u?(*E+~=NQfX-O9sNWfqaY%#6)9LYgUTYwEtAYE6G>?i+E1z%O*~yRQOo2|2**LB zj%bZw`ws?c^`XCCN~8p(>FC^?JxnAb3n=0`W*SVI=+;;lv21$67=_C6JZ+X}ocL1v zpp~pcqbW`xDj?$4(7wKh0##EWrc{5IGmaxAS>~Q}%%Wx^xwAYRtxwfXCAzK#Y`zy| zAYP%%D3HTfGL%X3VA7W)lFUb2z5URa`PkEHL8VidNX!gNQzlUSGGHGxXQ>RCdJ9>z zU9|T|!~iA((n^q_NJq_*s=FnnK-)!549+1!B1IswDoNN^s@o>XW1IY)IzWHq*|ViC z0~t*fIg<=LmD_dQ!nnpLQbgP#!LP_OV)Y75?sQz9qFu4a1ICVaKkU#Q#HA_S@=bBa{PC}s|>L%F62WlTba9+X6Io85rE4BbACGBP|i zHzjkh8*(Qu#K}Qpr)Kg3Ntu5z+%9^8LdkdNO$~4C5lltt6PXlzI80v|{ID>k+~-aS zRcxy`l+K#iJG7g=yVA3sAry8rZp?PVdET4)1b(q`?NlaK6Y~%Zeof`!9-Q$MjP4#akuY4dbCp^jct>he#Iwo-ZMug#LvR#R#Ma zl$VGy!gN?V0zbKYG3|*56+zB;Uw=*zhXs#H;`<17Jq_0dSH>L#=dt(PR^{{KX7{!Y z7ZWmjeU+VfeXkjFckX`;3Pjq=-|s#X_wu(nY3JU+5R#qjcT2xpcsIOqEAob(%L(Sd zfL*1@>5PYFhGYXpe8#rxoV3|O&}=f+gbbTopt+pm)4Q!s8#k`eHm*TBa61G=AD+ja z_xGotAJ+j;6#FcM6OV@~iu-1&(vDLBu6l2Qw1e4X$HO?|%f^2v3E~?kK$2jN`-Y*5 zlp;LK(Kq0LEDLOYr&k?rZzUTJ6(V5IgP%Q|B|AQ@U2yD!m8O}x??8Ckpe+eE1uckF zT1kkK9CSyaW;;ZFENcZdc`~qO+880md?#C&LCT^W0M)K?p8+Me1J8CXoh5B_q)bo+ zS}%*km0u|m<5-vNi2(?IRV#?8HEzLTNosv!p(#3|dThyp2`{@WbxJ0W#TKv5tN_&& zTg*LCpF+$v=`{|p2?XtxC^Sp6LbRWhEP~!f%R)&}L1m+F9k>PQ&3+N0A2T*MK%#Co-U?;M(ay&DBi9%Q7&pK52hiz?xWr8`=|ENvej*R+f;__1oZXG<4XL= z*(c|uiC7?RH6uw-E~JXv6?{4SBP zY%C{AeO17K|7LUjhEC@NqRvMP(DdEg9)4396XAc>)xP6{>DvJ5eFmWf(c;H05(rLS za(?qJeZ4Dv@n>-~Tbo>7|9D3cn|o*B(VnE`qylJvW><|SU2IP*V|}!YJhPD{4i(9 zm1FNqHSmJs!by07NIOXT9AWaFrS##tGS?PZ5K*z&WwxL*ntAvylj#~n#+6Aip;khO zjMg4a9(dql$UO8Fx*c_jT4FaqH?o#}J3;z-@vGG(DD_YL@afymTOwp1rec0lo zfP>sB2il48>FvYI(?&v(5eFt>+9Z9LQA+6-Tl^joH8ivV?ApZSjo(DoHlZ4b3nryJ z#nsPZ^dFxJjG}h100~2=PcpXA~HJ zsUlH#6q#*eS0oCNr1p~~J&5+aiX@OtTV)~2j9D%H88%5V8%gfYH@!{4-eE5=0NQSw z#>lqV#x4JY47#hUVu#1AqDk#M?|?t{nsxgCms2P0O9 zqTKL~cX;Ywc?p?F#l*@}P@Vz1ZLEOfzWglYCIhnRA(vEb>+HJmc8@VEGDe@Pu7co# zfe0w@ECPRCBx1rS8F4R+mz9Bb4x4rT$jP^~D}K0$V#4=3dY;m{zw)Q=X~_+c53LDl zInIsaA-~RALi<+K1Hs9dDt$J8T&523kh9hf)V*MK7x$*e1Y6mU7n+=7E; zii>ecZvweU?w#GklRs_bJ+$z9M(R%w?|=9!mYpnjnWewzy_|PvJoQF@G1qzxbatrzGU_51(6K74-JaQ%g@GpE!nKVKdnKmIjG9Kbc)S$yB%`{k$S)y8BhYn~SsCC&4a z=3Y|rHLc4zFDAXJCC*AIsoE%Sxfd)B?Z;E8-+X#}UU>`S zmWFW!YlWIa@0@dS29U$YN~VEsdJs4skb^4-(Z!Fw@TBZK&I>)q!FF( zG`~O|88G3`S}0%bYqi_gQW5pFZYAF~;y<2#+@71qPIHd3<@$z6%rOuEBaDW(cBf53 zzhiGV{PFSO^P3NUk1JO*330}b7!-xt%njm9b&&vh7$tD)HpjW*TpWMI+{_mX%lUIE99BCd7yNy-SLQjo|WPfMBGRc8`0cL zZDIC)(b0oOB+FtR8P$LbqP?eURYX0&3*@s{ZOeV+=Fazj=XilY78U?cK(N2Eb%zZO z-2(K0{dV9=1)o~mHt3fZ#B07hzI|D9&CW%S$-)Qr4(TT+(@*x)QyEvn3>6vtl$Ywr z%;yg=WDxkffScF(pLz4M%S+(3-))PRpB_Jdc>eP8@Urp*H_oPwF~v1>u}`6TqWD<= z-O-zkRNhk*v$PxYe>lKCgT#)>m`nn(W_wU4cfAbwJS68P9~?=K z$mHT+++s9hr7b+*ee}f&cw3jvB*gr&s^CVYbMIzirDu7c@XjM?P*jv;#p9WLAvm6X zI}8$WkJ*CzlCei^KhZC1yAYf)M`7I}p}R5y)0}t|ON(;`e}?m>4K%4WvUIuuw#9tx z&lAK9j~mV`TuEU&kW`E(%Uc0&2yxo!gugVKF;pd;2)Z+PwTI2Q=|%y&q0=c`^SBh) zHR!i@YnlMyBDh8t3nHxbr>s@QV#a}T5pTur+ zmdejje_B66?kXTm+fpupf!k6`5`@aM0H&mmrT%XrAXNmS0wC7=I7=SqSKGabeRS9> zn)|9bSTTF~gK-rHF*puyEKU9HwgDQgGB1>^!J2jH8EwKDv@?R$4A$ zUGzqQ>2pV?CX3mu1fTXa*KwaPg-5%H1Wa5K-<(K)RtR$fIp-BYJhBHxqS1g!A> ze^tcFu-7_!ZpU%^c3O%1 zNaV)JlBqL7pL%8#4b=v1ttR!!D?AE23d^<`0FSko?BSl!@@vcrAD`bn{+~5Fwd25{ zwz}iEaoj6$XgRX60)7`Tr;QyL+gP&1e<8@GNM-`IQykHJ6IW`*tZPoj10NLQIUz7O zUy<6E?tLFfc!mj3I?faTuZA@9z`JG1lITu@3mBngh^1Epjg~lv1!74#kN5q?kwU$nyrbh%MwNo(Zqdw(zh$x;TUz6e;NBh zG(~uqNvt7zo0|w=%xupu$XPa8Af{PB>i#(R1TclF`KaI2n8CLfa74czhP+A9mQV7#`}x zdk>2kvv<@X&teZeFh+xf6KCsbe~vVYBtitRteWbNr&-fkq61azBF$&I*`u#96S}~? zDORH{)*HpgYqBM`j|N!5y<#YeI=7zBc9cf8q$m(&A;*S*NgOd6L>CcWviZ2t$xc$F zN|LeP==5cctURp8iE2P03)v#p8-uW!k0O zNi8c8ZfPB8Bje1Z5V#T421na9dn?Jk618|@>c0*|BL?=eo~8h_aGsj5urD}HuLQBL6 zDkK`@%;Ks7u+G(2%emW%Niq0hX}0o4l$Y{%tMXF(VltU1_W7QBS_W5GY=z1@W-?}! zOcR7$m18TC?vX^Se;I{Vh^qFszT@o5X}=B|`m{f|2cSgJx37|Mm(tlGx{uCR8jnC>D zrgA8Zj1x2WjrhzlO8hU`enW9KQX29mcLPqHJKyP#0}orxf9Vm-^Og@zvgIyH03oi+ zvsWNVC1AXdwOOEDac)1!ESBXLV?y_3v0V}8S{ccyO|j(F8bdv~UE9PQ(Ki7;&h;J=$kzvmxk6=Sc)TO)7Qa2m>+M*_ z_%R|$%jQTYe_r433Ip@9_gtMK!4gN)_>QBZD4VeGI@>b#4PoMdTrJPV=%q*TOOepr zNZb9L=~ZI>d8JL>48Ik;_#Ln^pj{V8);5o19}XSUIKL!|?fi-~jggs5mNdb(Z`S9V z>n9bauVghS7C1RK5O}I%lw}i)(_&fF4>>GWM-WOwfB2Sw(*_9cYH4=YBtcx*eV5_< zbQ~@e%4tbh*%!hhz7ZKw@0neapuq6$HrZQG+MO_eT0MX7Z+}`>tF4#}G_THEzb!vM zYtE>VX4aLq!(ZC#={9{i@&$}u7|=xV4}^y9K!8hw;DKVMN1XM81n`5q43IL^RZP z=;{{~(s6>&w2g_-nxy<;{qQ$;I{#{?)08MRe}MIRfhZD&nboeUsYRoS@tAbQi)BcT zFPHwPzWiGC!d}lEUQr_@XeZjj6OfTA9bcUnykT=>~23_N$$9*vyW*lVkg{ zx=i}+DNjOGeGb#?Y<;`TKKB2lIV}C!e;jrc6ueJL(&L&02GXr-{Do$v{CjoBos*9Q z_Ov@K2OXl)?>he6-C~1~zFEs}_uFve-Z!P2y*~LJJ$to5E$kR1l;94X^iFKE^w-<7 z=2yG8yPJBh>=*mSj_(-+s|_sXv17A7#e+U{Ybly?+0ce*3WhgL~|sJ8QH* za@LruQ<-SwUdy>-Giza!GVT1!f4;KK-2W`!tmU^y^KBDEk=eaL){f$!n8wVsHTdQ+ zV1E$*^#)pdb)YR&#{Te+_~#D+did875x>3TuZE8VYEE=x~rzIR0dH*M)X==t-3_9P@ zCH@GTk4gKeBS@F#3Z-ms7((5&PpUJX4RFQTvl z$<^3M#M}%w$pO4qC>Chso;H3bJGeDsf;VOF&{GedvLKbFfEF}hZMj?1T zk&1;_&Y&F{*`_K{xs(cpb{Lr$=?4H1!;u)niv_$9HP`^H6ojHue_GD*GQ~${CEV2I z?aRZDtAJJ_tHY_1Ne+nTLZAsaiF{!X6zQ82h4U4c_p{v_6;;w%uV;KzOlRwHEToBE zyzFd6ydboMq2Uc0DdS&PrAZ`>P%?LBpx$_5yLam%zWez6^ZSP{Up_wl{In9Zs*LU_ zvBNXHQIr?Okx+}If4E6)#n;X)?pKN9bfpou$z-K!IG!!W$Uf$n35w;5at}t1lKnw< zB1M4+N`mNw6M{Y}LFS1#*+G&hH^8hTr2~`Wv}iqpD@zkUwr4X}@COj19q<-no`<5J zy+!I_RRpfJ0In@Ixe9!dx6Qy1bc4d48L|}^=i3NojbsHKf9`3AQcfiFw&x}MKBdJP znn|+-`eG-XEa~e=E3P!lt6NwL#K;wHx5)uaWbV=U+ZkON{f%?HHz4I?tXUBl5UjOl zo#4Xgqr_;RK!S=Q68XfQ5E)!NkU~B&7T};88>62*|0PmeNiyv6w$`6)Q)awNZ_vLN zkxR%oDY7Sme}D(l#bitB{Y;7&8TT4a4dlh7WQh8WDL#;mR|cfNzGrQT%{=kL4^MAb zpjcPWBKa7Pus|3lQs13}2o^k1hu(J<%5)8w@%TObnW0K)2aWms^nSf&V5D?$08z!} z!bDz0_N>Bs5S=&l+xzqS7Xma(c@83{7P=f2`vu5~e|Mrtp0^e7&HzT>-5FT{PWADB zXUI-477!GR4J5pQ;bw@iBtD-K7@lJmaepig)U2g-!Dz-a)f*5d!C8*|w2@>tayn09 z#z;I&5^S^DtRkFj37i_nReM|pXSGX{AJ)G8pg7Y z&2pGtzSDEwygYvR^!Ry8(ZS~3oZP{BM*6s8qy7mN>_an7h-Q=^OL8=cQmwBV6_sKh zi^Ld1H@6UY+eK=Grz-NrB_qBHSHHC@@Xw35e~HU+;6hN)Jd)Y~DYaMZ;n+cWmEr52 zHwvJ6WH2!3vB)!JRO7|jQ@M-JwnJx`P6x)eM4WOF-KqyMbsiD}5)y;i`DTU*MVoTV z_(m%tIwj(|u(Lmed&R~;bA)f^Q{J*2uR7kC&=C_ES6N-G0?bT`T~^^Tt8uwiSuxX2 zf2u?6=$+Nt`&+fWzt!8TP|VZ!f|87yl*ej8s=}0JrS$GrWk1~N?E7~iXq9oa%+0l1 zy|E|k6=z|3&5Ko?wFWWnaLkHwIwa|o;Wjol->=4IvDDa}%FSMlJ^m5IJu)@6p7OSb zMC^`b8!1;Y9+ME)z`$CJV^8%JTZ*AQf6O=gse`fI)WJL={(V#j^HCj4zq5nsslu!H z3KHW$=p4#ht?(j8;qUGCE=j3M5obUc-q%3-zDPwt;5-~<<f9es7 zrKT1!?>N@@C64wqzYg|4{iCVx*|!{ST|j-$D>&0z-}B!3p6*fK)3fS(>Qw4`o&?up zw{y|@owiVRPq@98N0gqY?@i_TUP>KEx;S%-1_^6^Erhlmr(nFwTLx_asi1l*+Hfmc zvy#=Fu-xYlk3T*vkJ#E}f(9ahe^Qv*jG}U2{B!1F8yF>)ZQ-qq9!m`9;$?@}DeVyh zEGj5b1ZqEXq#!zt1_x|&8M03r7o50s2OAmstK1%gy9jXvPU2O?qJk^LdL%a_QZW`W z_jo>(oQK-`npBVR02VPx4_sA(H{ybTrBF$Pei_4nI1jSKe=4F7GWcc`e>k5MW*ICX zSF}1jxgccA!rQ4u7#Wuj1vDOBs`8Xzm0n{lj_87;rGt$XF(*i(LouQiq|f){gWi0~ zkB{#@KmB8+VQ=(5Sv(~?`c&=hu;)2=;|a2$fnp+IJf$(*l4%qDCZSss+mZ3O;}cNy z?2sp!W=n!;S87byqM8`4e@Dn&yH_+}@n@6CEZ`3cI>Uv(Avzh{6%*%JM$baXzA+`? zXpvB}MmmC|C`4oZ$1vcDB>S$}#c7l2ai4+cSx^T|K@CH*4cV-3mFV57er} zkhT=-s3f|T9W*my33HeA0z*sq8#lN3-_5*&&T+&M7F#^-TPyluf0D8`sGg-BHK0#M z98UtJH^8NXXydyoRxeP$6*#`euh2x&z=&YmKVsi`m+xf=8Oohh)F?5bs|B?#7B7iy zc7t`2#+OW01kOL1f!G6&i!1~+U`VroW0+_5&GCJP<;fg3+;uE=?vfdPH?AvVH93iX9!>4=X5V;|dkA zW=ChK$np#w`*fP+bLvk5n8z;G1qvDQF>`ek7?PjKeUL|-mG3!MAc}!VoXb!eT};W8ZZv_YwGkBrJF95Rbq%Vg$Q8jMq=7yM0r3& ze@zxRAc8$zM0Si!@h_DO$isLj<~!r$iu?UhS+LOADw21+lh41rU-!d&bX_yJ%78C> z7->*M<;q}woB?pKI2tXjZgEEIQ|0-gq%>Bo6&4~audspqawmd&NNOo2=t^)ZJc!Eh zvdMRo?Iu^twC6cxX*m*vR^~ECJU+~?6=-v_xDs~m8MC>pGjp5FHhG2Z9mtnXsR0&$ zoki?TH%3(|S{FMIRdg|N*pYp;a6DDo*-55Hhbg}@*%qVgSF&kiXNC1w%fKv?%-88v zvv*6Jx*UywFwg@)ps}ZFEo*>PzNlIhN|Vy{*a>;E#!@@TC;_)lZt@9XQO;2pB1RVP zQfsX{`glJ1`QgXK8Jh<)P9d@CU)kZQ~r zdB>S#^?&p3`InE|MmQ(co~>|Zi-?sKqx!7vCSebf>-AhS&-VMQozAzi9p@!~o+>d` z3g>Rt@K)ui8O~GF9B0ji##=Y{>*s?^?R0#j**BX?_*%Ps{j@T_{LlIFzuJ%GdDUm^ zyeasMY5I(9%kJJAW@op;BQUJbIx%4eppu7d3`Q*7#%~FD+YuH=n9dHINoZmLr(Y&} zwc}af-jUx6QxC_vZ0vU4kS&;hEcecS_dGJdo<){3Wa{yuGO~quCKd9?GYP{nERsV# zOYd_$pwqEII|$Gro_h+cBPel zW*=^5A5QIdD2zeR!e1k)r)8{Y+#!Q#!7^K z{kDIvM@czI$F#cYG28Dxe)J!nK7Uzpk#A z$2IT1?)}5^Z4y_s<0!3r(p%K~m4Bdw-T2n&W;k@Sq)9_Expr>*eyd9 zbkd;J_J)+2g1%&bdaro!ex)XdCT)5I=3}!zbe=Ci) z-Y9jsZSy3usn>8J>wP$hFS-5AV|cKeNsBcQ@8heobfQZK^(Raq?DflH5g!ZSqsOk0|DY=5=w|(R z{4pN&@miRyFljEIGuK@fATK+sE>#cT3zNZP>%!1LVc7uG^wO6Q+DwXvl4W6n$mEdCB z)r5r6Mj~_*H4RNI>D&qY#cs>>jLUWvg)7}|Uc9a8Z*2MzIQwAIAC}Xr+g#Oa z{w50Ao`>uC7kc|VPt%3()sC@$i13v*2<~rk?HAp>1nE6{R+aMph3Nr8%AuJo2BOfK%D?lD$e54N4#AP9hMt}#&JDd~zo0>|RCx8yF#1=9|&8M-^uKY_HoTLP1vGv@n3OkKC zw&jP1C3c+{ZHr$fuO_J)xpgb2bio3)^e&D=bW3p4$NeB-%t#A=xIc1l+QdfAZbR@(qy)^M-(X4i^ab-V{X91><8zEVY=1D> z8EMd%@l!v|9b3T|<@Nhku_nACSu@q}r{~X4|M&Uh%fk{1%yUAATM;ws?O$%$0f7dp z01TYjq!!XWeO8H9Gm>)x3sF5;IuG2T@Il6BL}1%8{~3=KU~yG{{&z%&dumKzt3Dof z=rb#@OA?8$CqSrgI4b7He`^(y`H`=MxdH(IjhiGfMpp4j56v#I4!ALOxeh+B>LO2P z2q`s)X#5LF(*0B}FFB8^gh6^0cwe*!DXWlq-p6!Lg%6@ZYF7x%93qwgki6Qpe4p)3 zIh7NvKHyNr2`UhO%?CdV+kX7#sQe0{v4t+hK-e0ddbJn)g}r~<>Bzn^3$Ds2_NNPz^9;8f~Tnu z0)+sw;LCO08YcNOmvb5dD**nL*gQNBFc?sK{8aciXZ?$R7#{rVxo1NkqPz*Xr1>Se zMJDQ#C@?*Ne{$hp1rh>qz2glS2YPLiW^Ho^i(5G+Q>YyPFeN$))rdgcsCKNS-r;~H z;=eKI`nc0qNdQU%=nv=wj0-EYFp0cRi5QMbgkV=x!`_&$c7k7?-iAOtTm&eej0w)vQn?+@O4T$~iN0 zoYNsUQ8=gzw_;_QD%s72sx0?56e+XQ^dv16)xvL}SLcGxM;ySezkVuGpE#SLKnXIm zS%L8rJwpg_o%Nn*0aP0D()tWG@n0xHMR0Va95_gMFN8Ix53H(H)7w#s5g3rV8U0MR24KZ}wA`Y-!PYIkoxig{QRN*= zSyWz=>QE@?wg-KB{QTza*O%RSL^h{Dv*}} zh#0eaYUc=R$lcsgUhn3jYU9V7JJE;Lj}hp9poN<~F7ANB^8C-d{x!;_yR4uqs|Kjc z=%3B+v?$N?MU_ij-IZ3ktbY$CtF+8z{W1J1m-X+%Zufrs{^`?dvk&oU+E(U*j@l8= zuT?|MUY7wbe7V2hT*RIlQOoy>+D_`a^RnCV1v;}o@Tt1KYEPw^;v(8%_GdwV z2~e|iFBQjGem<7qyjWu%HW3<0?1TJG#%!ktm+#sn!xLB&Gq z4LlVz{eW$W-RV+islLe=&uxb-|bYmU);tTv@*aW#K z_V*o^kLB}8?xTl%1QeZ7# z=oF(%*y%Fd#8tO?I^mQ7_Lr8elPFg(T&^=wr=#oTk_lR6m1o8P5rL*&1RAT3dilkI z<*J<tDKR#ebhQB>e_bk~ zfo8=l6)l~w75nFVV`hGuTRZFwlsC^m{IG-}L=I4#urY?UwlmCHCo)*2ss+fi`3E*& zwvDP6bm1@4t}>w)fQ~D7nYn3O@91Dwb-#a#2(U91S##;m&6H>yM=AuG5jx;?d;p#V z^`TVW|CwGT#wa zPXV`N^eBy}eP?ljkw&(p(+p4C76%_`yJnY^(tTv7mr}L?DSv-ZKm2x9ty9p7~uGY*D#eje9E`=S?$fu-=O2sb!DL=AM0oWrNKd zXWnLwV;B@=-)gY;&u@QTp#Z}gP z9bXz&n24g6LfLnNm(Y?Soz`$9ZHNMOG4N!FW~8r&DMuDV7tCVFcJf|U`2l<-_fE#O zgC!5%maHsYc!Dtr32@c&Z_=-@5?sU^0@w99-9~ri=x#Q;JG)5UiOaHYvD)uoH<<5e zPNyZVQhyJY?=PsIXZdzGb*8vp+FTXMe`kkCDL) z^XJKRG0zVs@cG|y^Sh(739(1#B=6#xt`lI_80-X%UH-nQ%})=XKRmqs*Gf4QfuYir zamEMdZzQCMjUu-r;K8A*n;H%jOEy|B;}{$MfA-#GJ8mP}7X6j{fD{J;@osvcla0)7 zHh*@HmS~H|l&DQn<*NGngE{94Bwkdhs_eb*xuY7kKmZ8@0)cp}H6PcE#tJzyiTweo zrzI>G$a$;%_vPdBvRj?#v2_q#(aQmxY}iP|WWz@K(g;|Qa7UH`9a96D1ha4rlk=_w z$f6R1k^^c?-g)57ke>)N&vtf%a7j4EI)CnYd=m0{d2tzf6ml(1!eOC-G4%sF%()^K z0}h{8B`+Smx)VW~@A6g^yS4W2=cjKEug}k~AD7b&1B~3BZ~oNt%9vNutnO}AdY)DF zFn@u_3=5@=^XKK(^gt#-(>QDZ%kA(V-^8SOqZe=oJpJL2YjY}X+K*LHdPD8|Z$ z7Ez#0w-i(48Y=T}Qe6`MF1IuG;PZUT@1d%`a+ch} z;G#Z z@Y+O3dSWihjeifFV#1TOu)Vre_CQ#J>mj2-Zm?+!HfKr0PJgx3kP}28 zp2y*y?-G`wrq5LmjG(2cfBkr$AiP=cZE%Hn&0W^J!{RFHh05OA5P21@5*_tesY`Ys zHby?mW9LU5Bnfcq|I);&W=~_Z##tHz@sdSa1EbC?rLj3Ih%2?gm-8(S2WgX-;DEG| z_Im4F|5o$=<@x3J`3`z>Q5WYN$oz>E=4${sr^xDczg|DyfByB`S}}s!LF0ER z93#Un`c5+xfAN(O)#C9{XH%4kN#8f37eGSD@t%yV%H>1>mcYo_SqdHOTlDT)=MvSq z^tP`z{TqB=?3*G!FLqdr`KXV>JPz%X9990yZVqWwb#wY!^)piNy?>$@3|^1@r!Y0_ zJI0xsMK*X?U$TCrPuaeFC2#FtfR}>Z-_Amj?8lyzA!l;2F%8yj=&{(F=wZ952CVC` z-BwrDNwNMMY>i4_VU#9BMe^B*HIDBmJFdDd{S38$S{%jJnQAz}u z-M!KH5ztsNAP}Gg2ySe<5MpH`HldS5;`?1OlFXf0m_fTJAAif!u;od7Jpx*?87cYW zZC)Rc-ZhxxT9<$g@GiRL8?M*Y+YSHu!hY}zdwTwLXY%nUFBZc;xmYac|GjlHmm`>O zK$Hoi0_+QD^LUY~0B0gRl5nKhkxBxwvqSY{E3CNt7REmA+t)v_lS_Z%7m(ln0?I%4 z1%&-C08kKs9Dl|dOmEcQ*EP4*8%ENW98>m5qJ1V^twko8roJV^I>UChbtWbooP1@j zG*tuq7jrUs`(l>HpB2uC1n1_2h&pT?=0lkKVNRs^Ah)#G)Xty`sTP~~akj-~MaECl z&ML)J;fQmu)utr2IBzYQwYV5`m~MDvvw8MLF= z{Hl1npH0U~TX+U5olW1W$v~Fgo~6lp+uBpl%z2?|g0n^2E7{NPw)SLQ+S-#<+-9s< zt53ZPZP<(zFUw9!Z2@ZSfgH(bOkI*O7%w5V6M0{(PH7G1Pw?(S*Y{@U`TXtm*XRFC zPrf@nfq$3|~;P}`#0y4B;$pkTdSm&lX`%(SRNWZgQ76gl8B>C#! zsMn|e3^{KPIcaRR4H=g>au*wdNb%jR(XS7$uVZiUb?fWXGu!Z=wz}U|Z)Q;#>Th1X z*Ebd{e|cU(ndu8fNZ}k_Op#9#xKB&ub)a8Uw|`J|L#UAy@1?JUQ)v)wyv(AQv(RRX zcFv=pQ@Er|(ULj~mbh84#NC1=I|12QoYsQ3^N8*(%sY?$&O*YoK=C4c98t1yiV$0z zqy?Q@9GXFC#LD8~7P7|F!hoKI0s0o1`7eE6BFwo#c_#O-`RY zG)|a0b00JFE)YsL?e}rn~E4TPfIF7UQrPc_r|5lb+gcT zTw`E>Ui;SsW;YgM={R$J3roI*TM#ZXvwyLRAX-{wfYAkBtEn&*%)vH~a{u{xHFRxw zG%Eor_DO3Ou)5;{7WF#DH%qgcIL=|H%G=(yc2Xf)M)icU(5tSK+^-I}T?GE)Vy;*> zA{^bG2!|yh`W@@m{Zp%?OX^0EWA6vbT5K+!-aMD-7Sf;+8L^a@p!9+`WQ9Q>`F~zX z*_tctdTbpW$w#7?g6M$Wq$l2xN0Y`MEhRLg?!KA2*v&eJZic++u40TIN zQQaO+>`l^gKwF*_R=gy?J#M_Dfq%Y3LV`vxG|_JiQYs`dF)WFRNyJ1u&R%A4?YBC? zd7~^5=L=sm5p4qq)qyY#P|&8W;kFOHVd>7$_X(QL8I=!Z+XFeFmx8Hv1PYa-AxRZfXPry!(-{Yp9I&0Lr$(;Rhvl>seCm0FEiUe5+s^*iO0rV`1 zc9}9#S@Xa|cQj1?V%rRjVhT}}BBC-JUP?2gyOr(|St5Fo1T(~7U_#VOQfG-q9|vNI zVe^&d8A!U^>7g4S-&FqP;-~h5$wug7GFMkh9tR}`bNDcWj zonWB{axABezQ_aLQE1gAXHH4?VUM_IZ{A@&T^PHF%^(|oh^!hGgKW7GO!{CG9hh1{i6)(M zpl=AM8IVrk02gclmfI$a#7(G3V;J(YB}AWvaLsnu)!TE}wkM${8>RgwakPtEZw-3` zUZ+-~ln%LNJb!NG)y3|11fH_PW#o+<3JMToQ)e zusZF70^(8Xaohw}c+e)!=dY5$454lJJV)DJKAYBd9e+jW1UPWXbl2T9u;Zt}wv7FB zr|2l@IMh$2p1>WVPE-nEMd%dP5r3Aox`%+)q^s?PtANjqwPuB);O2d2I^DOaTs9!^ zkWEJmqkCpBUm>2cT@6iotN`xKJBspSrN9=*R5D`?Dtfr%yeahBf%z5B;g&r#H{ol= z&_T8qr++qxh}PKS58(Mw^G7_Q<-pL(`#gaWQBeL%7~;uw%@_u|Gt*BbMu88 zrpq4E1|*`f`=i!3W;FBD&{fR;#$_(!a$tb!M*-Cg9TOz}=V!s|^Y$l*+B~mPdK{qV zEZHNzNXV!3wB3OB42Loxy4{g_L%HY(u`X{38-G3BBb4~@@!{#i`k~KUp}Rp^sZjx! zo*^V^kq^qt^ak9sv#7^+Rlt5&F3IP!4Bhy7cbtr2@7`~}%Y*p?OxFPp@@(iJ%6NrMFipE+!b7tf{Iy%O z9mak)spV=8`)3mMZ$;Rxpg&no?2mb1>w-jRZ4He<$2rzX|v8O zcSw*?y1F;P;YnC=QW(}L;~bMVNI_iVdY)ZouL_uY9jf|SFUrB10u_#KwutSnPeQch6k<*GwB7ZM~G+=*8 zWsV3vPatjO+9NdgY9k!CWTLlMcBLd2*=Ni^BE5LqW(-&`lBDM!EOOuIwUvEEVJCxK+gHAVniy~;|NP#>6P zDXhz6t2YlVrJq16ooym7nt%A=QUWgOZXHbR*s;<+RnU>i$~wcKBeS+DbF9%c>>1Fc zN2XmCQ}U~pL4`|IH2s0pREjO&l2|=WPqJ;$59=Vz?p%AIqA7T|JlMAxH%ZyfG&b#w zotbx=dY|A98mYtH8>3iLlb$){a>7wg@%pn)+!pxTCjYG@nKG$B)qkKrbu(D%b+4oR z_I0!D&FxazE|u+4xm_yT6m6c@D)rx-rtOw(XHND*#rqSdX;Z1*efswF`uOFI`C4K) z(2C~#$vV`;?aKY^XQ6kHI27^M~ z2>;5Ww;n{hp^6688GqpHl4&+egD!qx3}_(yri?!Ajw;qT2YqYf2^>C+w{`~UWIx25e+a%I$X-zM*&w>_cet+o}1O>VIo_w@I{HZ99 zJVYT25A4$Eoe&pEVj`>dpMFL4)#6U`vA_vS!Lx@G?V*4s;{2Je*-!_mwiL+YsxAn< zpYLFi)NNOVK*M;LaCWr}j|Tj0`-} zAhy_+4iT+Xq<<<)kMo=lNhz!|g;V5KKC~qPr$iy!CRG}E!dWh_p6-qWvSdc91Z1IY zR$-_=OB6yXw*{)Q}zqxF2YQ%tz$6y(|++g15|3xmmSWiZ*V3?#$KU~+wYyLx$kx_^0IS{KU$ zY?*von~oI>^J$TNT46pC!7EXjD99%6-1=!52!QMHiFrN-aM1NInbz}rhM+N*CXRdZ z-u3n-Hh;MROtRo?ZQgLHrbyDA>i@{(=K1MwpB`RTQ#f#e&iPLBU|6$pR!FDqbEiLK zsZ9|hES-EdB?U;r9%-x%2)B0Zm}q}_etudli1DB)8!|mo_Y6)RTwRR4WL&CLuoLmk z_^CIkEc_p(?-oKU)cOp|D`e@0=nD0Ag=$yGD}NPPX~Yb+j*#-P1ndC_8!SODd}rd? zM30aM^SzNaVWm&0EW)6iAGA_o3<14LW@sTCsqsi}!6KL${`O`;PfHG_=lDH)#kw)Y zLhp^t|Da1EIZ3@WyQNmd9Pq4EwUv|0-Kfcqo<%Ct09v-EtM+u9n=y0h?CG#aSFU!e zYJX2x^>h%RXV!WD1?LzXVCXR;s+i zi6fCE(uT1^MHim_1^*B0mMF?$MO?$c23%ER>VcAWKn#X^Aufy-X!oO$JAOBIEk5vq9aU^}m2Ja#-9+Y>Q^c{~%L}0?t}P*EMt{11 zEpVEn84b+_lK6jGZXr>x@$AFE~iG-LeC+e@4Xeum47gCFC(S zHFl*?X6L5V+7=JAz4y1zAC?+bbnQFK^EjV+ipp!I1>^91<|MAdQ^lW!Zaz^LiE}JG zB_eT>OXBo_I!ZbuWuB~K2v^`l3iCrU`dfk+zJPG>tQ|G`r}rNY^!Xx^)A)0OUFVyf$5rE=(>%n@usCK z88bp`C~ao@Gxsa=Pik#uY(DT^G8lRmZ2~P%@y|OE3?+vb?3iMsPRD2tV1K{jkJ<%! zy>>I+s}+RhK%p<@72mNU9lvUxURg9dxUJIPSF;1c%p%Y%C@CYHgoG3-n{P`k5<4=F%wKD7(TumYBmse!)24Xw8%M$!B_KC4}kCwB!8GWHKZn!91BZW zK9y;iA?!#arXDh(=#1!&L0nwo3Wbkrti*^#VBtgpw86us63pfWAAf{z8n}g^nP{}e zz!-=kzA0GXx^H|3Sm$8S9~5ww&Man}@+46hD2qpkdwB)A$vmbCD=C?T8wSJm?N|RU zsb?Hb1vKo*_GL2)w@)D6K7nMPKwG9dxB3L~@)K}F(z*Nu()0<$=@SUkClK`s6#E3+ z@)H>Qu;nMJH*VMSthll-IN*&n;LrO9K^G)<;>q zxhstbGAtJvNN#K+^X0HYf^s@#V2vBfhYHqHQ_Ce*N@=c4qW?vYX!5Xl#X+D_-YD74 zMMX!PWMCqi3`e?*%4jTlK}5|ax)SK*6flgs>3V8DJ8`I6a| zy0kt5c7K7PEzF?#35>(bqMd@nYbh@r1_tHKCZW!vF^7n9r2xWfBylG{#)H zg^Yi5o|P0?iCou^YZ-5!`H9lh*Ip?9F`)mx0ew93<4Q&-%(H-Qog-UecT`XCpeOPk zp#wl!7Vv-J9G4@QVD&vOejzlS_p$|$GihQ1bQnYu_EVT;#`pwU7Jyv{{gkHdc|4z% zxLBTN+12#o(C)ZHxs5jzXP#geQ^ltTJUj?5E*e^-cVZA;T8SP4W0)?Kfq-JL^>#|N zU)9@%cp74vpf-xP%v4fN+O{*Ov)s1(cJ-b}8l8Vkrj+0>h87QPC$zEK$+kV%hAyj< zbvrA=&Ik2>9^St`uh!r4>4SX@UjQ1HkLIJC8#X)hTP0ouZ+c*7)bJuM)0-1L^jwi# z^P8nad9nU{aiV5I%U$i<34>zs<75~VhxKpY3dJ+%ZwYkWon9XKdUDMJVv5UCF1t5A z;Cg?XZoOA<$o1a-jdRD#UdHb3L~HkOC9SuvQdNtlo#uG*&SsH|BHCt$i;=} zx0VI=Z@%DnU*EqxEL|T>UAJV<*66>^XSnIBZt6xq^$ESbXJkz(IpB}${ToTU#HXN@QPUz(v7nb7F z<3<{5cN~gRh*2_P;YxE#UQqq zpghbkEb0H$_CRcR{dm3K6V$b;TG#1+|M&Zk_lqg3zZ3mnTrK*BJSDZ5G&lzh=4Lx7 z`&zUCAPqd`^a)#$ktrPJmaAlYan*lGa(aQwFZ1fbSl(_L#iI@BMRoy&!$4p38w9;= z^-B3eUb}7f92`|L=RNCG!4Qb#jGPFjF;rYjB&!`SSkx!@B3;iiWuwhnY>B z6shBdqCch#;!GyOan(iX^a+1ycgx`@wgZtMh6`*(#ckJy+}M5_d9`Y*FFUzT;)E2d z@R-U(1FHj8fB<(Lk9i9Q0abudkXKMnra$bDdA-c|+kQoi!_)n0a0&()57!{kPbI6z zwVPy7VnY}Td8lnd!O(qZJ93-4&b`3zv^u0AE#qE+$#7tT>@;2$Lt}qu7_0GIxL^X& zUdAy-`8-KQ1LJt1K8k=?ILgtPW#Q=j#%r?-A?K}RIbhK^-fO{g?hxoXap}6CL&4n;T# zPY+!swiEE&RkT}(KzV$%f`ZNj^FUB=U5REg>8MWTNFikC??F(< z^NjJIBJB=4r6ZWW=MD$}$Z0Gwnc*D?Q5~V^VgTU4#5FEWtWZ}7cFDlo297$3|1Y|8 z&!k@Obsku9iGK-GDr=F!Nk@=IYrXK?2R%9&;s$z0#x0N~E(d?^L9AY$+_ejIcEyf7 zaoj5EzMi+`UF{T<6p#%gA)_2@+j0mi1ZeRiHqW+pDZ9*u1Is^jjGOjrHqU zw@5GP9T6}jBOqt?L2J*VxNA04HuIDH^Ss(w+FW)=DW4Uxo%pEk&vG&sIGj9Wx~iL6Up(8NW@)=voK zAE`Ld7VLc#lUobLao|2@8xeb8vqbXBxJjkZKvyxdQ8X3vo@D3hCfM5Cgy>e_7rNwdN{QRb25DU4pqqmA>0QMkOOP35{UuKa;y6dw2CWc^dp@U!|-%syk#K* zf$v)?a`j8WF52DC4HmE*U-~Toq1cmPMTDY!aElU!j7}uN+vK2|31?*d?O+>@dK)^S zBVK>gncfMtAEph$89VcwlU%gakBc$j4>Bty5Mfiw4RYh<{=@wWLyKh(v2M)UP<@Ka zGbo;r-BIn|8I;AXpe!@CNQEv(N3mkM)&d)LW#3W+9Dp7pL=u@b>*rqc3*3#uR{dZA zd*UoS%u!3Qm}Dm4i0V#&THswr1XZeO#8rRG9xd&3($Z}QY#U{8tJcuaPovi^^A~-Q z+$7+voS@Q@_s78FoVw|BDq44(gh>vwVAlPw5n~XWB!@|Yb%`Pi(_7qm;g9#L$SlNA zj$SFvC{tm|@`MwRO&F)m(vN`H@jH^%)mZ;kyZEC-v@E(vUGE}FDdM(FjPTlL?KFSS z(8`M-*k`v0gn;(4`*L;@+s9w`yvg}?Y3h3L7DW&#i~;!7RaY){S&qwc5yL2AcAOj# ziDv`u^laC16KWl=6)jvQ-;yhvLEebndZ@DbIBAH6fvp*M3 zk*fFQ;Wr)^=1(6!uH;kdB79zsp7g(z527`DEY!N87)Q1kiYP-!q6GW?i_`jTeLF@P)s7C-B#IHC4b$ZD;IPcH|z0wjkSf@Wcgo28EaQL;-cVz zDt)~)rOymFGW^SrKgbK50*it);4+Xf zO2z{(gt&PK45bYiG|m5<#w359JdxImGm8RT_AG%>-VCEs<+z`${EIP(y?h}bYX*w5 z!ITJh#m%vb7D-hdG({6D;?I$5E=Q(Uq+sGwx_lZQ+pYBD68kwb65W&9eg) zos)Tw1o@J0pso9j{{H>z<6j>BVbfW?(Xdic+I{1Q@^&<3K-5+|@<4y#DMo35!6x%J zaQdZ}!wfE3!o(<}L$Kyrp`8-+Ggg7qwHS9Vb_*MiEWzJM$(e>3T#u2Jh8%k?XJ;1f zJ`G&CR7vUj!e)9BUJG+N+v~VGWNw45Xr2uU-#ukAtKFct8}eFE4*v>Tz?V z>IqQb@I>UzYI4GOdR63KLZVg3zU2@qeW1P*1_^OvI6h-@B|)99c`+Y~jO#~ZdnrlK zPe}qouE;OMNJ5-$WPCea(+T+67WmHNfXBFZH~vu>!lq3TN!WkQP=}f?f^8)uybz3q z&WCq3{MEMl{`T(S^V+nswxkzHVGZ;zI5^;iBsX#akxfj*k^GcMfukM396ib9;zInq zzEO^M_b)Fi%#;X;mSy<&Zu;G)ir2B<*^!V%$-chcFClniXEP`{2@X`ROUYEHz2qc$ zkkDI6qXb>>1ulQcipK?rF6>tg3$U#mJ|scb>EF8L+s`sK)k4Lmx9erye!hRb*&8$} ziCzib&m7e1mxbi(9j3RvXaeT%`N!7yUmjjwmwGKg#+|rquD8;6)}ZJ}>h;uMW!Phz zlJfN7431$U`Jukgg5(9@<^<1PP5Hnu~(j}2a-f&$>L2^DKhUPxIvw7LpyjqIa--A zTd;pnGQt~9=VngCgH5z~>5GV_P<{gz*7Z&?lu8o=Zz&uX&ti1MQ*I_dX5!hDeEiAg-$AxNE0YhLy#O|I4V{h_ z_i|0r(V#0UcaQb2@jI|Z$jQT6U|Y$5Td9x{>CR;}TcVfkL$r(|@M6p+R<7c^WE^x5 zG`#7I7B$wnIRVgK?ChBFqn$&dEJ1%}A2@b%rs+p@<8j-oQz2HZ73V@688m%PR1G$T z0nbt-={F>qppj?Fm~x>0Z#}D@U_e|Ro(Pu%rOBQhP*uqhCE`CbdeuIh4ddO_a}=SN zxL78f$L^GAX1ZT6s=liM5ZH!Jy-Tmd6}wQn?o`Edz6yq zShdP9;X)p}F?Hyr`-G_=?}mT35+oB_C<{-WZI%Xd9Yl9RfsqA=ut#M$sKUADNS+O! zcjCW5#U1=EG!lUPNCh}^R0Y?=NyfXSEC+rP2I|nipmDSM@I%hwbgjN!T=%+2cwRd9 zPJr4bBF`=AwQz!gmL_SNLzS{SDv5s+lRJ*fwjqpe&rp}wWpx{>axs4=KM2I+4SK{N ztPW7MB}>UND?|&%4X>1VViH`q$iE~Ef-w;trGKM51~|0}ru~k(=kFDDO;S&Fx{GUS zH!9r4%w z&EKMyVB>Gg!5SWnV}XBKV-#2%4Mu?@BuYG=dkCh7UeG=*ooC#YPHT$Lc1E-QlasE- zA#j_#@wW1LD$!oi-~HwOJ3kjr|NgtIcHZ%?s(5bnl?jXP#0#9A zSt~O5KuagP8+DTCsFl-|O1V@7k?{^|M4v~ZyFefi;3|<~K3e2=#>Z`noU95lsInc$ zy1Oe^3C|R}9Okv@&d6Sb!BdD#(+DZ%5O_0a> z>#Cu{Ss$Jo!;JqnpR6nYZ?o-qbC%BrjfzaKD<4MEPF02!8(g0)R43iigkp8HcPkO0 z(@w*Cx<`r#*zGlU1)nMPznQHKjWZSwy#bEa7$u4|t^GWNQEESNccxw%+Dux);{Ao~ zC{YBHtv`QE60~ime9IQ^JjL_|r&?{W}RBuE#MBwvkf#J7+M z4$@AbDXun>6bvXjrZs$rc}7rx!2Fyr%^Zq6(mM_vUbsm{>0+_aiqpgmN*)9IDaNhv zZ;ybOHxu)LI1GAX9AH2=PH+N4lGY;G^e? zD(sXr>x@v3gk{jIcpUAbkcJ79ksjK*T=W`GCTJS~nWHynw*cohM=!te0=}{5sZ+zW z8@uc7l4bDGF%E^=4zRo;b}~}a!M1_ zCG&p-lYLq>(gD`)zV9fr%7y-8D;YjGu~N6So|omj@_`%fEB zHiZCOXFWTijRj~KiSb}$CUz-FlisYI(bd*zGuESEbhO8UaFor63fGFZS^0`RLNt_| zB02kiLXh(1;rZpm!^^vm&o7UEfByV>zmk9BH0F#Kdxg#%JsC4#H;Sf1N(^Z_p1c=0 zb)4S35rX)S@0Yh3%Vks?f2uIft8~#p+{rT6bsc?#sQYq_l2Omsynlm#+Q5+0CenT|yHz>R4`-u)i;_$spLl;Q zb2mfDo+ArNRHzvWT%8e+`l-|o;toYBAEgIh>dnG`e*dsGJR^pd+JG2H94X|@cH@t& zzO@MmrBcT0O8DMg^9rcqSBg$`Ig5l>`f`@)R>Dkvc|7iw>2E7(>GA71d$Y1}R2lKTGD{}GO4o{;!|3QACo zizZk?t7TfMQaM?(l)|AsNa;0cRW=Cqi2GDoR^Ra!SzsY9eM*$ap6L(J%|d^Gmei1_ zk$tHQQX$(5I7*1@*x9rIh#)~PT^tVG8Y0Mm>miFk-unFtkm?TeHr zdG^cR!&B91}pEv*#B*1+xNG%u6fH+rI&uQh5~7-HoQ(R3!j~m zeR=-;bp_-KM_v_LzDr*^Is`5Cu3bZIAidTd#iv|BPR51V0&)^IAQyk!Z-r+O6H!mw zQM=YqkavPbCO)iNEK(>4-4PAs6wRM&hB4ho*7$m_I998@{oChu7t2JikH+2K#NF$s zx6kb;jn_%Nkd@$@lu4CM?`bE?{_yqn`DHzf-FO&^U!2@INCXQ-}d9s-#FEAaXtX1Vx7U`x#rKVX!2JoOQ%Wlli z|IASCw=umm)Ln zq#PojUFx~44&8NAo$JN4lZLH0*B9$!yo5#YXJ}H%m(Y4iV)XYeyc@DClaZ*{wJpywlQlYpB?n6&6OTz;^)%b>Dc{hVain&#(8d4{Nzi;v9bvI6OvavZXqU5%-*|SM%GXtV_?P z)l)9Tb9XRLh;bw~+=BBaLR~EiNk9>orp3I1uZl&%W0)%esnU6}Cm|q!76z>pAlL7p ziIPF0%MOm^6tI*kA&-_0VJ%N}?}^-{YfrOgMn?{jC1CD78m zmKA?Y5tlIS)tR7**V&nJhjg>EC_#LlPP?cEF;}5T1iNFx^%=?=|97PZI%Ur(wT??( zDS`$$J$}y&dQt19B6`)uCY1vO-NCjazfL9Y@c%)-By8f~OofIsqYg`)PI)EA`4rij zWRGe|b(SP`#|UpnJ!%utWw@3k3Os@CXiI-LVJvk8gwD;l9m3k$7Fcbnk2l`Y)59;X zt9d5rpzcg)S|kLI`pF`nM+sBMEN%AA&-gaM(odE<^ZdfV0lyOYF(}aLxagJ{85Av> zzD^V4;{^XB%ZN#pe7v`qMf=N^?2#b-h&p7NaLR%;H!mx;KfCJ18t+v>5XHS+HGpKM_JC3-aw=z{Mkb_%S=a2W z?eQ*blBsGmz`RmrM4 zLq}U5lu^GMbB$kLHc$}4VDsTUYQ6NKs zU^LPf2$F&L1LII8lWsy_&`+i!zq?tf_HO4KqWP-yyL#k1q`Qpt$M`3j=A0Upi z7W(5tdo?a`hk1RJjlZXI0p_1k-ed5?V#f=u;~@*>8qid8n8?6q-{eqODKDqxidMI<{WWnBJR1IQm>>F)Xp2>Gu;P9(+vZ48w~9HasZS zR-!RZnDj9BM?-5Vc4jhRGS)0vERll+2b&C|z%Ftjq9i!PsZmFpceeb_6UpLO3;qN_ zYpPl|p$}s+7s7uT2`z`(Hm1$|)i{ri=6zcaa>MR77r9;kBD0g99OXOt|C!!zG6%Bk zf5MtsNaR_H0NG0Vnn--}r%Hh9BtHWLAER7jrThd7cKNX1Mk@}Z;}3VLW1WWoaTBRU zP-f*t32_gGI@ZfsPDs`}Eq=1xS>HS}0u_MF!`gufai@P<`jLopN+vG3?MV&fCz4I3 zbGNapB%T*SeygP$NbM z6A{m#ROx?nz&f!<#7D>Zr2PAQtEX+1eqP}tS>&@I^HO3GY04}881}}lH5Bcg^2_SI7NAyH3O~3{AU1&h9Exr+m7?ep;dk57w!jqAo>3V@2Mbh4>>~ zh1VRXLu62|<{RB&vQa^n7JI==bH)kAayl~qJ!G<(@641E_$|^cf>2(8t=yjFLJa1rAENBj zy2Bz=dK2n<ru8y|LrSXLUaG9>nqOTYY_a zdU{-<>d-%*8)xsVp3Ef4Z6;MNX4o*Fly`qe@``R@c$@>p-cwl^rxZh9&E`3OEb?l4 zsNKaL3A@sZFV;_xWK*OZFXct-bwXxz)#Rn5UrM$NQ(~MpiOtw?wk_Q@@r%{3W%eSS zCS!rK94&rnIF*}1Hh1kR1ZiiX6FQdozEh zc6Oo%E~4^t>eJ%Km{Fa*Y!B%$!Z9QrxPg!Fz=LqkKGQxMe@eEJ)FTZRUDA{Z2hW=4Ix{H_`i_B}ka@Uhv5EKg-r1#9SRdN#u&_hp=g^)0>RbnXyoeQit zE$&j8m?OLI_TA6-PxosqV}E~SGBtbRs5R*kyYYlHFepWcjg7U;IV}aEvnd0M&{YK< zBXjHw{PHnR8WX^^iSa?BJ&mP>3H@H0;R3M00hH?f#m)=UZ`sN+gRI5`CB}_qF>;sG zW0?zstBaL~eG4bR@n|U9n|Ot$W%S(illbTAb6kCmc}cEa9gWhP?x=qlj2mV;pR&pgCs|bUJA)AzaGY6zT4Fmb`SFN@Zb=ZKtDu z4F1~Q5ym?27|UM4O|wiY!1w5*#Mutw@Fs@+r3Z0>6xz_S$yar<8CI$6Rya3FkeA0q zy5PlPf|V{pAt{y5>^s+@vaY4CJB}zje=%(dM1km|?r;~0*l2$XQ%UM1W3^I9eX^O? zfg6=FDqPBRY*uuIB1L$B)zJ@`ct7gBg}_}sDY~R}V+-Lwk2q7g_IGrjKB5&@-l|x7o~LX%RRnsQk)MV7_Qa_)ae05vX3-4U64;>0MxnWKVl;&+ zKlIKU8%oFUW`~wd@n!J$+t%2!>0#T;lLBxH5%=NK!X}=eK$;07@V52@v^$zE4*=by z2YYwhrfoYLww^GsVf)sa54P#quy2*H*U*0d@bdVVjj^obAjdeHDMHq8j z_{5Y*IiM$kdfSH&q{t>vOMK;dsO9%?$QX7j)#JW>+ukU_&y5DMC z$fySbIkPn|k6fCKY`IS0d;;$Q@Q~k@v=GKgjFWV2C88FJpJS!UGvW})8&P*ldykm1mlTDQE!v^oXt%l^KYxFC z{LABqZ}(5{zJ6PU+t6xPa?#y_2$Gjl)60Wm?h)<^6fByP%{iT$&&KOkO_U{jdiWJ< zhj$NueSNuKrN#TJm+$dH#59}JR9@%`I?zN6vEB#cDjAo{qF#MAymI33S}m9>oQYwO zsE3>^K?$B-^G>ZIF~+44dEpX?C>(#f>tYH>Mgfe{dZA-5;qaX4mBXxv->r?$&o7^r z9bQy*_+@p7#!5-0Wsnoq(OG&Dq5Nfz7mUEG1hHlhqZGBGA>Ag@OU(3kuWs_)hk1GU z@a_FdDOdV|<7Wwcp|jb(S@89)`2|ULLu={Nd_Y6EtH0~ z0aE03=xOAs5J^)@>Te-q@u2!A2pl)_g;Ve_Jbu%olM4r zbt~BS2X2w#mo>?a1>b^Sf1i`dPg{?zuG>BZxF2|eJg66MNBWV39ZPLUvka1x$1Dkx8nSxsd& z0LqbAmMD}LC`Km%6hnW9P*|e(;BH2~Y>Cfh`JZHF5XbQ{gHc3s5&VeaYWylEv6Jwz zbDgt&ckjQwY;`cP5~Rde$Y!`~Qu&pt2&B?gO4^Nc?K`4>{2g#?$mlSMt9dR3 z35!`Yd+3IAV#~{;=fL$XKr5OY6H2plnp|wb!`qpQPKt|G=E)B8Oq!pszkaL?x17dTRAThIx%&QYqDR^5J;O=i*= zR^V;W|g8&QY-q_qxnpzfp0Ipa1gk^7Ua2xnilW(@j}n*H(4(D_6~2 z>-6x~n*)EiV#-_7UAB)I%Jv4QZAjV~mUjaAHb5^Q>W#-(X>!o9Z(Mj`K=6XzQImsW zWr%JuF4tRoSJ@!N5s5EX!#h!&Ls$C4zQ+IcFY8CXrd9ABFmcQh!ij1Dr*Wb>F52wB z6U4`R!X1!pK9F7kqhkFEaU1yZ!uRncy$mT=@qd5gk)dxthpJUCr+a5tAeem83m}BO zv#azL7SjLQg-D#&mHG+Ijy|qkiyU)21`M!n1>mz?ra0(mk3CO8p-+g-g{O#-7`+NN;<9k`v zO1F9tKwsyN5ia%E>`Jc1Tum}vP0G>chqCQ{qg?+BbGY@3j!XIGAkD$mOLi;Lb!Uuw zSIGKWpFj5T%d^YsuKDU0_w3>Pq5yWiri+3hoe4-IlMJE1vFp=8868L_-ZU%p^ zx9V17l%}T8ixT8$Y*#QD!&0<}wBBF#Mm%o(54{>d$ANM5J9Ub(pZ5poAAL=rcbt)k z8NcfQj&m<`STDIW_~#)YF%k8Ctf5Gc+hmI{tna^V;4G*i!gmmU>{YK`@elT!b44$9 zD_3UWMQMlUg_h7@vN98>-jpgkc=>-lp)h@zTEP$Wc&15aUamjT;hxwid3!SCr6mZo zix+Ds;dPLa0U62Vd$*F(560A`8DzjeYx*tcC++O2e zXa3K3;9s8pSNd7bVea&)Z}8Kl#qWb_ar;T zWN7kPgz)Jcz*Cs7Z z>3ndaqF|X8lLgH`a4rK^8nS%4 zk%mH1=-kxE18Lr9YhaW)Lb-ZQA;xcgASwwA&+)cAq1ulSvZwmATy}Wzj0{?own_-f zwNmgMMH@JAV0n2vK16?@RJFzqdQoOLMvxGWI$#=(6@yuvIigPLw5 zw|2qqt_C50R@YPvEAeK1wntE_(vzvN@qy23gRF-^P1CB!nZ;5rEy;??JkP$5w?5X5 z9&Z+UXlNT$O3daJ6^K0Rr5{7K3~dk!m79yP63Ay_#@oOZ!38j#RHTC4Ad{s{}Oz0#m zY0P9hwc`_)JK4eFs)GTQsV~p$B@3WuMY+!8U9z}CGNffi#xC1Km>n-UQPIRbdN>8T zRzrG7R$MgmuENxqYI(eD&Q|w{kH}YIn}hx(!6X@fJ3@acsYqz&94#^EfCdp3qQi}# z&`gUYX@O)XX+0$R29`cc2ZYJL4tYKDOUW=RgqJ{glh)BO3D2F`pLI0ZKC3dLnKSn! zrYmFSk0Ku*DQgx6y&-XndpnKqGP2DCUT@Gl&#lY!y02PDHgIKCsRy+u7F*3Mn?Qw6 z$HqFN+(mz;lUK2-uqMn3vZmdU`j~}T@%kvd)v^c{t8g zhbgG$=U2oXP&2lL2(^HIt`k=BEsv_Pr z2fab&ix6ZYn4bnH5KiC-%*$LzHK+a)xCkTPnEKOg*hG)%U6i}1bG5U^sn3{)3MGM;t{`7rF%Rn7V72U{VRc8 z+hTuV$v!@;L0WLF=EZB7izHR+_SlH@a|KltR)4D=zW(>O`b zxMpQMcJKGHvK>3h&?8*S0I(6dYEs;V3Zd7gj1$Pjx}*Cbf34f0Y|y`Nzn30BFi%Ky|7VWh5t0Q6wsrPPn#53iGXfcNlLO&t_*GPd z&Ll(1Ofuw+M|$_+@$3E1E8u^&qfXmZzz`=LX*t5m>xg1PmL138+77$)#$EOX!pyKV z`VRS9nM6b%O=3Xl`a+*g+GK_xR}PAFrzVsV%`pZ^fwQu%k!m2s+Y&WO!Z|N<)b!*6 zi6Y#j3XzB$$DP2FL7ezH{&M>rKmPh@2`D|%1+|_OGDQx9W%3j@0tbKjtYtjvNwYC& z&!3_snIXcvLruYb-aS44zLji~@hx;$=@t=8%oELQ;NnKYL_ERt^&pvg;IW`ngQWEd zI0Yapb0n`#`;TiF+M5mJBPT(+YE#{lOo6D%<}>JIAQ8A@5;Dk&A?U|CZsrSnHT(J9 z`}=QOK!k4w@`WEL;*Ng|o1VDUBhy}FbEYq&j`Kn;KFvn`#KRXV*m8EqSI+!Kly@=C z!O=@*WJO#rE=@a7#F~#ij$R@u&gVd9j%x*0?G*P2n&b1VJ$_W?aO_0s$ctNEXRSAl;N+!1<=iTYC4xipfK zn*g(;lZcWy2RIq-X7kluFS+uiSRy0XX+~%%M1$<*Ngkj6^6>KeYC>LwZS~l)Q?5c|<$1TI*&vY$A#T2ElI6>^i*kvvx8i~G# z9d35*RL{UMEYN?=6s6Ff+=S8;nJSl6-PmO#~g{sivnScEl-r*333am%a>9oUzH&7IBW@Q>UeTUB!al8{d=p zyoY~6&+{D=;8~usd(Jr9ldCc~@f6WGP8M6?ACzb>?DGefOpc-)SU6qOD9~i^oh(3- zmZ0WLEvi&oW4PHGql)e%pHe(D%<|Mk@W=+4DSJ=+<>lcokI&0^FS+-|c}|yVa&x5L z7n2?MukT&!Pk*OGFeSPF>RH_z4RuwdA9#PMZgXF^DVsa&o}!m(ufkr;O=vy1Lwkef zG~QnC^ulL02(cbo>)=aWJSmXbMYQzoOa1orw0XRn4Hxz1nXK*_93W8%OQyr-)ES8*$Qx`k)e%>saZEXK5`TTNG$Ze%Ks@h{+5rh(#I2eHI>ZDGZjH&L!Ur$M=Zwr}u~6!) z2<7O9qRc3flAaSj{PO7Om4fRb)XaYXe}%AErMd?c(U=s-1_h|%ixZwCWJoS;+tVmP z+tgF$QH+2=wwBEC)+R`Z_dyP1kur9&1gjM1D&aVtl!-bjwR7dn3Hu;-X6|D0nvbsF zUL~`VvAJr6;G`QS5Zr`zfVRw}L=;+vX$sd91E&|*m1*J8Qve_C}Db8P>PE1yA|k)WIQ>Ta)e_e*&9^S7^KPx*C)C*!mn!XdKR<|dff%?(GJL9XWf zV6lQKlD6(MOCP08OiI3S(pn!g2> zl>mbst85V@@6}7M#~B98%M&3Uvyh_5+B1hiA2-e=Xv5&mNh5!nsZV5I)XOp}MQTAH z22$9WB#tjF@H@ULYMh}pF;l_P(WZ~3i38;(vf}+-Di1_{^@D+`=q8$_`ao$jATDVt zQILc2dJ(`+$R#M42q+-LXrfXd9;Bganiv35K&`($goijr_fS@%fgOu^E+*nu4C+cR zr16GDEgj+-y^sVPXiz49nMz=^^u0{lFoMdYiSiwO!dfu#l=1kP0RvAcjTCA#`Ua_{ z3d5E)S*6%&HE6t(y5d+>kydNmFBxb2R1@kRUr9!i&q>`dnnb^zfiJnJ)P!6(c^h#W zp+Z~lDad0od}Lvp5+sru^K{^4%L=BsPCNu{WzMrUe?izn+6{w$N#i8g!}OXO(Z)Lv z8$er_%rGB2uW(n*BCfYLkfAA=(I5)2yHw1FW<<}(9evlRxSol?hLW2nTGj5q{mdU8 z7LgJnP`L=`OxKICj(|`{A|_jeA_&MRt4qEZ8aV|pPF2wk*R`2nQ1nDJRiqo`8j1ZN z84)Tk)AmAo>TVH#*8!j7gp5Atg!%MYzz|%nadZP@R zfL|otNYOXhno|#rn?x1#msa^lLyQOXV;NG6oUSJ>pF2i>+)>#!H1;DE*L_v+yD z{g?M2?>DZzoO58p;1cLT={`QkIrTlRRDH$ z%R<*5G@|i;_fqmkQdg)rPDCSBjk25yJ$pF#d9u^Pe2FuD($my)c|oKoEU(!g&SJOM zq-*IIN}W(ZljQwYAmF2UO$Q03D(ygSYDSNdiRd77{?fpt#I|4ygIx7`{aU*G)!8GB zU(GPhU9*`lB6%ToC`v1lQ-e7#G>m$Q>hxx1jfp;g)Q*y!kT~%NZALxwxFr)j?jsD3 zD2;=V!<`m&6f@6eh)3BZBW`%e6D23TDh!~|BaLJyaU$#pUGs*G8$WfOXyg-L%=MC& zBraX|amh4xBV&QNTA^sRuA&-HALXZ9`m|R9Qi-!X0n3Rf;P}dl0hgh)b0{b!fvRf8 zO)!yvEj9~?xk;}(-6&OiJ=BG>w`Rp^Qn>96JLyOf;w{SrLAASV4TSoD)^4;qEJA); z^ODxD8lCZb2@vj#ix3U2M?qc5brm?_^39`ZlOK6E!N#*qCu938Om4hQCwu#ZoaQuQ zA5cw9bMnG31s@^38|~AyCn_zR(A$TM>A^&QcZl}Qo8Ec7lX^}QgZ5^o65^rtBilab z`S(xvpVu(t6>hBW7Z^TF4up}VUYZ;%ip?{i6Gg8HT1E3?8)u~WcVPP%XVVhj_WGCD zCt3rQEC@!Sr3}6~I@NNeh(zEyNTzC>;rB}DA@fIDUCa~B{-xq75GBU^oXfyK`wK3A zuBksyk^zk~I6l;&%J$Sn6TN~cB$Jj{!}MIGz+n@hy+b|5CGN0a;u1NNOIna8 z#0d&aoh8u6x^~1A^986&gCCn4Z1v-RoB3!zGdbaV#y8YnzxiG9-z@~~`ThG9!s!pq zZ7AxM#fq(hBaXBFgatZyB-YP%jCVxeWdCW^g{YCdiFiSd zOwpW%up+Ag4!w9a7>(FD7Yxq!Q{>CiNyb`#2-Ly0gNYoI`qgA%UC;_ZIGz^LCHW5dIw`uQ?955sl4b&J$?{iD$6uQn50T={HQF zm(Kjdv9h3j3G<3xHp(_GXNG4u%%7OPyAxzEB_mDZf9KoP5u=BL9euaehNONEYqTQX zRGDOg6EIhw~7*y}m~`C^Sk9#l+L24ZH|yHcuqf0k3Uz z4)vZ!7gRg85F5q0B@Uceid_=)^DpIx)98~R@3CUNZBrJE61|| zSX}voT^GzCs&;PpMu6SQo?y;sCgXp>aSlQNGnq_9q+-bKXcKrN*^ted&j(0uv z;o65&w>kA??ZWH4wDg$OrYw-4!a$x?+mo-269T_K2ObR4`E&|%%C$fm$#Jj0(;`0u zhPU&kUZ8FE<>UR&53i5!m*73FV51pRwg?Y84_c_{4_9?u?gR2-laNTfu&+ixe@cLt zQqZ*L=LQi){7$e5G_CW0bn^I-dwsVB4+f&4fpM^zvU&`RAs8p9wn=kvE?>^6os5sC zT?g15&`kmEAbcUy5WGU2uM!6tDJ3<2IM<@K%`gVmd1GgSBjqaTiZ1R~;n(*MpFgYt z|6LQuDtxJYd2u4}=3u|DvzyqK4FbO^}JJqPGMzrK|loX#9COMIR2i9udMt@Ix=4?E9jQ$d9 z7z@rdjgk-5OeyixChqHLjSv{t@lvd)tu_hX6Y-wdMQH&u-Nk@xU^HG!R-O^q!!ViU z48-l_B-&A3g1lVM1xL16BjUz`mRf4_bVSK~HUb2JakS(;9d}U0UE6SEs#Rk+I}zU< zS9R5B(V3}#|ISY-hZLHQXi>6`xfDUU6SG*^{8z=T6KWv2;TA>Z{E#ya3O7hyfPI{& zJ2ruXNw1r2MW!<(4v>1r3>@p7o;ZR0 zGfup0Vk@JlLHjkIZP|##^&lquq?v_gKu9rqXT<$~pmldKrw?a#2~qw5vuzRdwb*z1 zsgi-B|5sikX$?`bIfd|(x>eb~J8fk{O$9H z_fOB?KCC<;qn15VL>ynVq*jdkKRzpEx2YVg6oelnjZi4VAZTu4pupSqATWNSE{MgN zs666-l@D$}&uXl4*G~&Vx=Cc$^1s;0Xtq{~Q(-Sm#G=VnOI1``u(EkZ^oLyJ2_iba z_iH7kvO|wrrTon1E0lvSHO^e97VY^f>N{72lB%xiG3qeAMNN&QEv30_UkGi>E+qCe zB_h!puZCsliX5Mk!mq_0blxRc3YlUhGS57J$oiG4=7Bu`EMZ6~8>{2WaDqu4m>5Y7 z7D}3~c9C^w4}v4@{1lKJzX17o;$M#Y0A*a|i{b5F4%QDbNlRVlVQXj(pxCK3+~IbY zi`0w9PrN0*Z6Lu%N68Rm=5QyxY=g1j6$@){u%GWV;+OXi?|y!{|NQ>r8kQT(dyC+I z2N_^RLq{ZZ#MJ_=nShtfcwx76tAXX#(%Ydbtefhg>2bs&cW-dA5fw9W22zk1Pz%Rp za$pf1=@1?1bfU>gjK9RBsd$>9!LFl}rgz?HJxSssgC{_h5MB@!cx8u5K?e+%7S5+; z1V$fN10LsY70^qad-063G<>baq=BG+Kh1@ousekVw%A=gM_|qXsH+r^Aenn!F>`+V zGtcFrX=|`N>X57ni{Hn^32E``&g$T1|k zLP>|i7lqrixZqAgzcK|V3i@HeJyf$wQDnDxX;&~g?%ST&&Pndv>n@A(g9I%KukVSC4%2L<%1V+!VhnOV+kAroG9grz4{jaOy)MYSf#Vk{bOTr|+MXq$O;EYP=W z*&gGvwJw@=T^|kRmpa?&mY)|x-78bv)$!dK0zQFpZTIWSrN=LOFhGaokil>u94rJN zDgt&zX(Tzmel8g_zmr{J<-9Msb`HTI&KuTr(O6wtwq;2>V9i5NVa(=#n`f#Cge^#t z2>3Q*(AI;(f*^*-an<6qr^YZCUoGOXIfn(M)=IT(&xwmJMrh2Y#%p*t=>t0xxJHW)m)cvBrV^FCrHgs^|v0SE-so{~1 z=qx)3c#*0alt&bQT4(uUI6xD3VUeeveQgX<5~O&V_d>l{REKaiq&AjsYocg)r5cny zbXB-oDLer=#`H5&ykVL{F#p+Hy)SNiU8Y=+9AxBUyu%==2`R@xX%g>b^SOj(S=>H0 zc}<34dgoIcn6(++u`FfD5Dc+XAxfs!vh!viK0JSVc-?+~DQQ{bUP?%X&P~n?oz2?W zlL-nV2^#$d3)*=q$_X^?IWc4Z&)P{-{;)XZ52Zb-fJdOdvZ;20IY0|A>V+|<9w%Zv ziBf(D29{-dmjX;~I-UL^1N>ssc3_XrN$HXxj|5sepzOQF^Rxcfro# zqh9%ci*-z>304g@Ji{bJiWK80T0GLx%Xb_g2b%X*a;77`<%le1k7Dd6#;4Cz+e9iRHc8WT z8V>+!kR+MsfN5>N+7|oy_3@X#t<*THp=RJji5aGk3_T{IzjGvdw%#>3cxuv)V>c8P zk&85{bl5<&8?*^Zh#%xkof&5^6-3YXqYI(_<-bj7TRE)`S{pfHzZJi7S|GES7v_`@ zs%89tkVt?|@>J{-8{mlM**qr1Z`DQlTwLr!_LAWgBGMH9K1753pudvpWjpH79+MTw zGo-*tfOVUUxym+PC94*(Q*)MY@>KK-vFeD(5YM12bTmXZm!1a;UMAKEg+=3CZ-9Qx z=?^Vcfiw)K#d>4tOK1|vAK=4x?R>!|s23`K&*Z@_=NVQNg-6EFO8*QB|3)jD%H!hU zR{B2>QnA-opB{hxxb(6;QV$hNpcwfA@vRE-<|YLhkChUuH82a$6ysQ0c(9Z!$h)2{ zYD5*%WYCZ^%xLsL+`wUtycLLURXfPQBhEi3^>Ad1I;pafz@#Ri+<}#Y1Y=5~u#7x^ zqgr3@_#6=2PA1KQULq=~=7<5p`3DuG4Y-2}X%H+sBeq-|?WlWl0_R@8jB3sQ?$^>O z>%&E|p!0F{N8~_P$GbP*>${&H?msPw>Q16bs?I2JK8`=dxCw+3ops_x+DzS9BvP0S zQ@&V1b9yE?_5P;f)Lmdve59iS6)*sQpaqSfDPjQE)zim#phs{dpbc9H10Hx3{Q0w# z&~TpOgMz3cK7y_3E*FuHDEz>@d_iG~iB9+BY>I?2OB$C1ClX0u@R*nw)bF>I_;UZZ zRU#T@+*kQr&_1Y|RS-cT((S*HVGD^Iu$~ihwxAdlQ&*DH2;LjU^f$$S1M%ZNRXgd-5gO4`nq!fcX_*# z-o3y7`f(}5GyWRFRO6&v^NAaO&L-Y*mb5-14_-L1tdDd=CSA7&c$bTyz|>6}Y&$W| zZ#`3CKB<^w-IZ`Y_O?ngd&3e_6YDU$81iHZeiIm3xgPXEyud0m+3K|ggyF!g#IF?& zI!7{0>Qe4*7 zSVKcr;tlICQ6!3$fZWV0QI-R7(5x4(-8fs9+L;%l=FDs=Flpp#GV6R$`ntC30qBg0 z^Y}IO>@Zkz?4Vx?qkTS#T!-;Hn<%^%Rl!E}o>7fpdNet;_k=9@Rc-=EuSkiWEa99Q zS8O}6e7%4F+rwYqf4u*H{Oihx1aq)Jp=8Pwc0tAyojm2x8DUBXse6XPldR)Br`{c1 zaK}z9Tq)fjv_EPENj*a>BFA6jl93nWaz|+C!iHT`cf1G9+|eD&Gp9nOkE}+lhz`Mi z#Q7LCTkaNln zR^QxGV)L}e@X*e_G?W%s3yCwKGhqfIW}aoIf%)(Gb}G`h(D}S`G)D4h^I3RbeO6~v z$alo!PA6jolT&e){#{2YCZ)n0CGja|%c06nyfm&ypoeR6R7{kzfrp<~zld#F`WbaH26Sb5v{i+7T5fY`Bv#iD1 zA-$s$vdxw&Br!|hd~0y!y%OwcgveC8m`hFoosm>OgXIBtb7pM4l0DfeaScIFf{39! zfWH}DDwzFN&Mll!IDGrO0Vn2zY`qT@BmV`TqA`#J=1MhthK~ zdTB}kzKG0!RL;=|%mSrXNm0;K8dK=$)w$`_@znP6{PglDS-JUm{PN@RKk)H<_p{tS z^lI7A(yF;4dgHxB4tjDq3YM8<@QfKN0;$`w^=2B>xwQX z;zBkgy50K1`G;T3H1R8D3d9f<@jDEpi{C(VQg5h#RP|69s^@2HMb>7%qojJe6&9O6 zF>Q+f-DY@|#aQpx^Lg-(4ZIbX#kIT3SEd&ry^_?e5OAz*JMxsaU1s}BoNa>}W7wH6 z1R*3*eg3XJuzX|Yh3KsGv-vw}^S3YciEELNScISB_AMJ2XT*oSn6Pti_C2+FhQk^DQnj+cy`hWT# zX6AtekSI$1jk-rO(+jeYxFfC}?&fB+p$*hEdW$v#a-@EKU@8O$H`-6+7$HACg^yzI z83%pFrMFu4BpTw4!4TnQifyjyf4KF__1^I2skrOTi1GA#&k_G;)0{EN&}biP0W5}p zzbtALtu&CJe?;yVa1h0gpf->pY?qdYIl6^bb3#@pu`5BWE=UrjfBQf{HPA9TqZIV+jaReF*KbxNHAx~& zdoSra&o4%KcD&Z^TYdfI<;(k*4dGTh5{wC0B_&XSi{6N4GSzhy4XGP6|0H@8n6xWbk=^}TQAxK3be$cu&-H0+B-2@Qf{@YKPCQUr{0S88~t6Z4MNzRk4w$x|VT=ubN))${wiz`4b|B2(#Xoi*Mvh1()O z5#4-XKLgr27`0V0P_4niZ#Tq$sL1r_6I2fY6|>9*I69kHX0WYwT#lote4VrS6dI4y za9&6dQsg34@!>+u$Ud{S9WB^_wC+NB4;G>(DHKI0qiqauc2qMS51pZa0CvxKTd)j; zTl|Ks5r_UkT7Yo$Bk~QRe^idEM6+`>iA8ecvfs;|VL@ga{nk-VuPA4KK=?vA%F?Le z9jY;=x^U?HN+PyJ+V?1fJsi9xS~IZ_4*hb_>+RdtFYmVm6$sgH1JPu)<2>3z0u>>5&0X7yS+HE= znwJo62k~eWaeeGK=D)sw{JNDAs#7n?bkx?p)Bm+BnC&Ra;dE+mKl}e&4%3FlLO$f3 z&wIUF(4i`jV@XYLxvXK3JIb(+*o>w22Sd8;6WVtQ>I$?(p&L8%%&ZBAdY z)7HW=o1^7I9QjH(zOFxKb%U@yT2SwBoKgY(N(U*akHJO* ze(t=w{rUy+>gH)AbF2vbe{v){H}R3MM>qQI#}CiYczb#M$GgYZ*O%YkeSG@qmn|&< zA%B6#zHS4_B$%TcSiD-b-#Q7V)AKR$m2kk?IebOrR5Bks?L7InbzF|A-Ahqz>DVlG zh__=|6}x8ukJ?P;uUwl2KbLpbWV4dFPTPBHHGF@Lw2-E?!qksP`WXmu2N1|&;f+Eq z8K~{dfonSV2QV)lNxx_)SP?#vrA_D;c9+d90$~9~moF{?8yhKm&&qq3m%S&oH_w#Y z67$+r7zg;q5}?-CJC|iH0waI?@$t)-r!O1QuxSn)jRNm5SoU$5jD3>@cJVwgXBI%B zvFl$O?HA;yCd~4AFXJ*wklLn`th)|cb%bE9$ z|3*t(Z9y<4Xe`e#C8A*ydmaUl`=c*^0G;!D*q)04BkBFeUAbiNsS`f&k*=eMmnfw< zlebz5FbR+fWr{Nu8l@%f`OT8WN(-YncCC7^B3r!3zX($F+v82IlL7ns{Qtdt{<@~t z@U$<=FSsZ_8+sKEAQ3hW!6;3TN1;I&VS-4@qa4Hx9yk>( zoMrSvToL0Eag;w=7RA*;P!Kz?T)jQ`Huf_hW9aE(%ns~qwNFjt$4JIdB2>L($L`)C z?tTA`yptnrJ;-fdF z;9eH=Vy!cZ^%yJc7?3kx2aKxcOGN*$Q{37ZLF;@i)R4vQT$p4-HFJ&vQ5Uk>a}fh^V!Z zTS+uWO=$*RQ3)ZUh&ypzu?zo`5)wdvD+lUGD}#%u2&|rw^Za zZ0Gs!zJ31k^zrHa*Nx_{?pvg_bD_=ArFZBpL_|_raeT{#gU#Lm2N02K7`lyrKF>=B z&c17!f=D5^`>K~j`=y=2=3_6UMx&b!5T6G5&7EJA@+0>bV0Uif*;p-aG4hs5B&$&x5kWBrm>umEDATge3u_m)v)jPDKiU0DF1g?C5h((OVOAq^N$UZ${b+UL~t?%QYPLIP^xbb06}6&BfgJqG}VEcQ!(_T%I07H=NzB06c^ zPT*?X={;%nc44{`SMi8vMR7Q4O-~X>jT4fm=P(hi4RIW1iQ!TwQc03Rs)-4@%sqZ~ z5uhPoq)#fzdp{37o{tc+{f*Xz_{J|!+W-e$k5Z?Zr{VB+=d`BiFxNT;`H87>A zQtjZ%A`iqTp$sMW&g!zNy&7ldT({S~>cv_>lY(|aOr1eNCy0@0(#GHUr2F~FZ~R@` zZ({5k@kR#iBuy_&lJ@Flu-w1(I1%+=r5hJ5$ z?)Bc~cKfjV8LXLpvtY=n^#!_Cq|x%9$%m{p>g^l@1yk;Zw?V#KKV#rs%DLK2>^X!W zZ<>YMG>g0V>`vIXO+|+iM(nS#p`+M105y2^Sjd|caqy|Vp4|Hn%}5_qH(<$go^`tI@bhu4?q4Mfi<52M^3PTYv*VPYF%w0bx# zFQCAMTeX?3(Q&uu|9txd=qM3w`n2VY@fH zeJ;Fv%!orWo|jPi+_yZ#RCfoW(&3mXx4A^9qN~4uJEEuDfB(C$ zp(}5k2VNT^-b`|gl4+w-Bnodx@E2w1XgV@nM!pm;@)P=oh#$mR2L`El?ZL}f>*`Zn z)nn9RM42)>Pqh|;;=_hmV?VPB-OtVq%iajt_O0|H2Xyub_jCzGA(?uRSZujrp zDd%^8KRv#G+NKe~GwviQqY!6csMC*4IAtBo$~$HL1`FdU?>Qr#mK~bVR4Fl!$4Q?a#;hAH<#$q z*1du2UObJ)t6Qe7#w8s)7eHI0vMrIBli1aNXdJ`2Gc!a};H$b`CESPXRFk@S(hUI{ZGaG zZ?2e257al=eWEZayds(A0KR%Y>r#yQDw3UL5FXT~N@jbUZ)e@JL)Vs>CU^IMM>*FkcDUp$5fKV(hC_N3Y$t+%45&uuts{l?S_8&hw8dwi#|{_A<| znRSqL;*;@liOyelaUI6G0WQ)Fyxq%l@790q?Q`=b@7+G_U6J>0Uf(it5$h$eM32D82Idy%a6WU|B%Zr4E zCfj%o`oxWc z)h~V$wz2%(?v9gK7kNlWr4Pg_0b1AQ9?z$bPd~qIXrnkJ!+Cy|908#~ zLb*Z+95^J=zyWANYn9b6#Sz%!4PDR8xfp~hYq5DEN4*&QZmL5GHX0D z$~`R{W;``Y1kNNI)wu0ss!7tjn`EwYG6pJUGrUa|@l0h#A8zu{Q7EaV8y;>SzgJX$ zfBy3P@_7RgaN>NDgE@3(0Methc0>~?E9m6xcr<6@21Qx0^6XbTtvrXF;PCuH?|%OF z{NZT>)5C2}bg+7V;y_mIHmqOD^^kDJYt`$X8++ZD5na9jtLGSGPS=8wi!o!zBu*}r z%}otYsMgK&RnsB5GZH?1`t|Ac@$0wOr+4q4K7M)r_GLr$L19MLcv5CCRCFk1Cr*39 zjDktFn=)jK)<~;R-W4=FB7QRxUaIF1#U?D-`y?DKCn=?BZWAU`%BV`z!z5*KnOgT&!1F-@s< zI>R7;(pCdz$_O;bYfZYo0ek`VM0nSpW%T9iyRYAV+(;~d?+|&dGj6_Tg)V*rPc4Q+ ze^Ry$A=vV2vRB#PQF*xZh)@uR0Ykb&`ODi;&vU(9$)h53$bunoh1lh1+=JMn9j_R8 z{R6YZNudZ2qvXw^9gRFU+La<&kyX!ZLQ+G2GR%2jMAM@C%P)@~)}&^bHl4DIfF43< zEL;QXwx@%7Oq85fi)DurN{w-rR;}pEhaUH4?3K$7?op2y1)_eo$0A7a(gIQf_ZLVz1;YZAq1gh(v74K@CCL!IyMBAM}8N9MuJ{)%>U zSG2wL_o^)aX-cd>%QTzrUn1020RASwar<8>w9(ifm_3w5jo2#$yl0%75K!_{HEpm$ z#h8B9=T;GKuKR+i?aK8ghMd(^@hA|mG`4>S=J;dLwcoGAn`S;tN|SmKl2`@;nTs8e zx(MFJ$lsXsif70KAP!3Pgeu}iEOP}Cko*px`zgi-3ibI>lp zyhA~8WotNckHAlG@Qe(tnRNMpi&PPi84ZuZkx;xYzmU#Gj5E;npz}aXGcDW`F?)Y3 z8**nCnNI<#@!<^n4g7Nqh=fl6IlUT)5h=~#EZ`PI0w{m0rys)Z4w~b3v;ZIzWGj3o z!F7e`ETuHK0V(1IjDDk?3`y(&GV6hI>$G<1*kEcx$eku|GTr8f2n~KuQLG|hc4;*> zTt?-^k1nD^6h&t}^-TT9T|huOiDZ9FaxA_0AZZB(toq8Bvq2yy3pvN_6#4||pAB3{ zOJpm%v)9`clA+$tx!5@h7z0F!RY0`Un?Wx78J9-Zay=g=o?Z(%1bmZnzMZhsa$i5~ zXqZsFYOTEE*TOwzEXJr)xTXl?T0(b98-2L7LK2)MeH_tEWzB z`6iXAvX&K^`ukdTsMta>i#o5^9h@?i3o*;zDTa3l9evpp2D1y`poaa*N!DrJDFP-C znn>?_QKVyIuFqxJb zrf22cgcCK9qDp~m)~_^T%vIUqg!kEC46P42A^;>KIa6eL(l|WBr}W2 z=eAkF)XijC67=hG&p4TWS^K`li~!jVm&=gBb@0wdvNyghmOI=9!HU;XwqxW@H#1`Q7!vnrr;Nf#26e+&JDoeNh~@QaUe6Z(J7YT+kGlVA3<(8{q5r z8cYT(NIY#RlB+}Z3G2VG=es~benClY2RZM>r|b{b2*bn7^0VAL|!%u>DRX63*6fuD*x638u>|28P7Ze5Oa9 z;roVi#+mE^;4B%Ljsna4Fp%Jye=whJ-o=>~%LyvZBSn9CDdf|nBSaa7EDmQTlvnDo z5&?*OY)6IRLM)e8ig~`*Z6UklIx>+6$I1`lghzQwCk%Uy#Rcg<$%?QC$?E{!;9K_<{*Etr$66w}~Zads? z!!}vNNS;KkA`U0APjIG}23YU+_>mGG;KM1 z9@6D6)8ICais6l7`1R@a{ap;@-}<8eWT!Qqn=|Ep(^xUcjL^CST(8O29838f#n&FEC!@gO~a zdiwbI>z6ws(qX2>aBHRxw`RF@8xoC$TJE1lX1bt+ND>+28V|lI(fk2mwBT0&(u7kt z&uV>>x3M#-`Pvj87H|B5GitAxUhj*jBZPmrEDVdEc&X*jc6S&>ME$2?N~{rHqXvc+ z7y$B+8Uka0X_iD}MT8f*gd^7;jIkQ?@MOB(7KCB(Q}Jp__tIlr7`Jf5h&nURJlW>N zoi)GMErXCNX{<-cWB}*FZW+CE!-j;K#VimhH>)(O*mD9|r3FnbVw97D?tyv1GY5aQ z`bH_8qfN>Qo~Ws8sSy+_ovc`kUS^h|BP)oZ3-Q;)5w&YD{i+){i8pA*Q|!G>Mtoc| zOlX0xB1*9ms-yP8jUC(Mwqz0oYJFAv=)TEJPH6CH#~>4pf#&RVo9RD_kpdJBLk`iI znDqvg$H>ywlJN1uEARuz`ljzHRm&h@)JR@VDm?IV$+Z|Kpp%f~l_hXtkzjZwyA@EFlJaEd4!n7yl#^sG zNax8HPNW9MpHY19iJ*zvsCOBiuAxVhHxjrsLj)5MUOW&gW^nhynT2@+*xP?5qOW45 zkBNcvBMfhCIxdQ^{u+zv7Ew@*H4Tw!(|`+6jFS$xuN-d@JPkGl&=DbTD_*V{X^U!^ z3l%g!1`gFas~8%!VQsrwp^}^HAmkk{H5rg%rJ3wGDs4SpOpJOfA`a=`h|*#W;*F{H zO#m=d`%>HXl*4mmQICe<8F+uRG?g6hCE7IJz8d*sVWXMr{etyaH7Z3f0As|heBgJB zA2mFPX)DteQ2W%21sF|YAL-|ic}yt0WH&P5G7_^547+fegXu z4NG%2dc~=nR`iVvH_!P)05vZceHY#Gb_mR9k<8;X%uM_9#-=(~1)syeedq%?#s5N&rC^J}E~>GJ#1jN&A~E*kPP` zGnqU`3p%7259YHAx3#D*Eb?%aERph~9J&1~zt2WQspCb&z2m=~@(}K?&VhOi-O9R8|!u72#=I6B(%?#PnjgJvC|DW*}OD zp5XgUJSjAuP60H`pr#StuE~VT#RwH1VsC+F9GZ|f#S;zgYkaSBnZI^!lK@_S-!p0%pw$nIo zR<@<4Szga;#^Gk~!3i5;51hOcn|RVD`R#6dht@~BW~j93YpBJ}ZExK>i^j%8%oRKc(#Gs%of7Sc35SjU{^4S)>A zLySS+3prjyzdLYh@#NVJeD1*gg0vKN(PEO|){QfV0C9ivR@(?|XHkxYke+7+iq0cFUNmfO+{b*B)u^t9%338M9*x|=P zMK6iUru5-zQwqwh+LU4tW=<(qnVM3H%_oXdcoSX7eLl%1qUME7^?g3cHn%9K;cA~x zGADe^Cs}_pMVYr!8v7=JtUA@}gw|&j1-keeVb;ycHYrdXMs)GKtb{(TC-1*bH_ zL}M9cJVxrgRRYPyW|;I~iUkVzt3Y8~$J`2^ac8%&~HmspUAe4@7oy5Y`ytY{@MHR<4M_#$G-~1|c7* zj?6bn^JwX0?|Pn%d36|x%fgVrC41#aG;ewG_*W`?inN{%0*Q#jIm!?9mI~^$3>)}K z6_KlAF8=NU8JOS$jc@pwrgqU3g=&9@nrAww4jkpM{w~Tz?xUDX3b{&I3|h0}V1~>bb|IBP&H=2=&1J%D%0gccNxpxzSjSca zs=pK^B{Zoq6sN6*m$j{gD=KNl4^0yfE_7Datv7%m4+aUN#%2=N#iZjoF&;EjAxY2t z2*4gdUs0R*B(1y#XoOD&6=ly()4Pt<43i96_QcI%{&6p-mT+AZAq&oIo+iTyxhw3K zz*8TZDZ$eJB#BU_`VFyDFb{u9fAF`>Y+l(Ux0)>B%!HSs{0Q;x(=AeLw3>%t^WIAw zPy<+m@_;P%0Pnu+X;9P1(s!tPy86a!)X$Y|MTj28VWnn`6TApQAZ)-%!v4a?dIBxS zD0M=Bg4iPI2s}uZMu&@%aGa1rQ_&?en8~JGLeGa5PjA7CYP_t)-X4EVGZD}?wOg6| z*c`bE)m}|u_?u0vjm4@_+5#b5M06Z`;rK6Kh(henrlZuym`tHqTe87b=K5;Q&D+rg zGKQ|jDIHplQ!=4Tu%U?U!fqYdnF3nhY(Sh>b$--xJ^D#p+TS7zW zaguFF!idN{jn_;hU6dg!7oic#bNp0@Lbi_P*Bbs%3}F%6INyIhbiXNldAw6d@dW2z z>y591+2rEryUw`1bQe$eBpglGWU&RM2 z*MSomp$Gz*_AN5POoD6=#g2g~Mob%f`vc!Sefst5KmNj>Nr5YU*WOp$5k%Add6N1n zc#8;TR;W$LWIBH)Qc$Y=H0obTl)A^xincu}A)T2sMk_T)#WgJ(aI&5`G@~X7%pjpS z2L%`I5fwXB!-*+kP~YyV^8+cNsO!lj0dP}Rk#bI57l~q3)a3PK+-ktyV1ktm$O+VI zMeS|=8;JD3NW%%Lt}yEG->fG?YgnVXbO7ks58iSxoXCIKcdit1JC`>#-F%2yu_axJ zjk}tB`T6IMPw#dVKc+HXz<(8#UBH9y;lkVFg>0Vd!uRVm3S-6JA;?|6)^=)GzuET5 zn-{w~s>B@=8o1B>@EasUgmm2kZ_Ft8?I&i)B^r6y9=;y|US7c0wPnrTNgTDUQ zCxbFXVviO^3q{t-6V6G9{Me@h_{&8$=*C-ud06s~z%Q?2Oym%J6_ zxCYIxkEORhYX{x>ullgayL5d^s>YO?0wuHQ;_rXFCV7SbD(^}@BqjP`+7l!!8a#{& zvF@7R`XJ=`{X0Gc$pCUdjlUG+`ADZk+%n!X5x5KknSgmngq`+U$eNXYvRlVU8dW6Y z*U?*;o|$P(A*Nyq)wiqhej!>G~oHb}-j9{NH8zV^fwlkKJoPc?xaEQC_eKae{$h?8p6S~i#_WjZuFzu66H z7k`R}IzLLL5_e|vur{o7L>Dl?CnBJ?Lqp()P4>utRDoP!PV0-Qn0C6`7OljzeyrG7 zH;qefp$F#wuWQX!w^3a6G?patCnb9tN~G}8B7I)`(WQ_KvRMciNTb4@q(2~KL>|k$ zJ~Q}$m+H05?2 zs0d1=Jfk7i9F|t%i_QB6_1m<1`SI!T&Q|1qa#qr6lsp1SS2$T#Ak!$B8GII`e_A*t z0`s|#p@!+~a2E5*Kt+;54dcMo4{0ne#aLS-PZTPKP{(Nyy&WTzw2&enXEF+Yk{3Ku03E{7SYVC<8`)8RuIM?|^0+Q`x2v69?j$_Dpq}fGo}l{T$cN8FpIBhDWEW(I*N~d({A)+7#cEGV9D;6Rct+iz#Nv72m~L zO9Z#O2#)dRC_pE|tY!shJ;DHhFr_Fto#?LF`SMTO)MrNE3Dl5FH|y_c4xNL4jw*YW zc8t-Q+tJE%t6ix8ox*jOtjH3O^^^58A{av+sw1KSRLxAHx`JKdbXc0EXXz;p4>FuM zIdS%5NQ^Hy{XM}2kI3@Dj>JQMCm|K#>}tEz!Rx0*tg=UKd+lm&Nj$;9^@}x7+%< z-PYIbw!SX6^>w+eugh(HU2J_FxxOxMfBw7oA7Abh3IY{T`m%?bWnn9Sc(m%R#`(Bj z7^SV?Q7;cMaNf!zS$U*IdDL5Rlv{C>TX7Ulfh>-6D~@z4j&v)IWX0iG9BH>Wep)9D zK$aZ|Q>SpPQ?IBeDmWK76`7?Qj6=6xPH`htowgk;}R%8ZZ}oni3aR zj4it-;S~svnM|fLDJWRGewssJzjzq+4lzMl_Xp~LV$?uXv=9j%B>0VZD_l#-(yA*F z98OpzN<9b;l}H5;h+jV{=1*tpp>EEWq7RC%BRYnNYcBSB-eQfZVjykc&yGE> zw=miH_Fa;)fgQwuppxeh8|jA;V;Xfwy`&gvBq!RS;u0+9j)Tpmi!4K`YdUyez)w$G z0!_#UcBBJi$c^$216fBE-vYe_cm<_)3(OwljYiNYh&%0ZaB+;F{Ya^h$>2E2R5gUjIc|Al48FZ(lTpNfc{GKRpsw9W?oHGXO&7OQ zEFV9<>Cl^-KE~C}*HBJVn0zQ_@N4q! z$2>oN{&^EmB#k(iyZ(*Scj-es@*j0AGxLq8n5>_FvE1G1<=0;}QP^o2>`z88Ky$AkRib{oj3Jskc3fu$Il+r0IJypEPUXK&MXR zlIx+6b`0Fm4>b9C1fEEpD((XWp$+NFdzJ_JVT#gDEz=^r=ueQPHs`# zIDuJzBm%{?Dxs96V{ea^ZZOR$l#SivlV&--d;IP3bt9ep;Ei>h1wp$HXy-FunZ#P` zAm>Q%Rbce|tV)bWj`UIc`<)nQo{B)0Qjf!}wAw;m#@}b2X{mluY)Y&8nrHIeu zpqk$(*1tcZ_kO+Wb9lJ1)gm7Aoo+Q5e_A6(A`!WQG$z^y(9MihGUqJspz_YU<(=kqv&c#Dy@xs7ZzuUX4sl|-74=rwY+gAo{354I!8~zNae>S8Sa*wm_}z!6kI#R9di}?GnY$#M_*c9OzxqO|1NwB& zCg6*yGW5d3oGfIUp}#iQrjR&V zu47mv7YUCy3cWGg0$y*nnWn@=2Rij14T=_aXn7bnJp`7xT)(4AxU^M(p*5m1a4A?J&cdt)B zetcP}1qWr2o@)>PXD&h=NrF+FYdj1`LrV3)7ikyMG9)n&0}MV*p9P*5h`!MWeXT2^ zbQY|qw^SG2zwO#?3JVhHQ@8}-YseHztvT^O3-c>@jiYlVT#C>)TwK!)5AmHs&Q%hK z(v?VN)pQhD>y5>g4Q%g!)!t3B=-21>>(%_!%YdRI9EnjW(8ZsqWKTv|cSLPBhMMi| zxSb^JM$TAanN$gd=g{knFN@d?+n2cmgc8yOhDvrx=nP@LHB$V^@7YG%W#DacMvi`nxP4BT`2lfzJJu(lRQbfwwtXYJAKn$oVp|e)?38Xti z&Pwtr#0Un$i;35$5)#9x@0eBScrL@2fyjEM^X4NhV1hR?VMpXVNc5{Z$sb`{wapwX z`#}mbr2KEQ^ep%xKm_WPlLdnGGQBbY02E;(*Nxs?TR`4hep5J*lwA-Y`iTb;wP$bC z4NS#=DX(yf>QYyE`=m`Mm-e z9uST&!WPGQ5i->MCTYPuIg+jC#<%0|9 zO*q3ARwj{6^+7m#$Kp<6x$0~J-KcE;iIbFAhMe|v_+2Va~pD=&b?Ne9ZKbOj~s21gaH<#+7tZx;tsFg)s-D>bwt+%Sa zRsW(z%&lb6b`~va(ax5QZ*Gx`cDiW2i#EMz>Ff62d&Q!!SnuhbY0iqAl79x#LA3%U|z`Ij`f`AGsr2Hl*63K%t*jzVCuYQOi4yL@}NMup*uTN9;us!yF^S)_#-_ddg6Vaxim+CGQ!1bfOV2m+@f&6n~MS zL@;TNhLeiQxUI^Jl%s-0Gt`b?PL>;6{7mIQq^n5_9gOe8Qvf5G(GbWOAZa=-U5d94 zo{Qnq6VvGlAn1)xqtqN+RJs=|xwAdPu^tqZ7S>6b-}aK#7VJZ{VUW07PT>4djAo<0 zzC0*Seq$Z;81ow0umE=N7pd7VoD z?zt+uu(5X1E(|A)113fx^5i*4oe+6L7xv5KLeON{U`A>UAtt{%imr>}7<`;J;$B{xETFzh+|B^tQMFGvc`-fQF-(Xz!`I4oWR2oa;LNdiYu z+Qz6CY!mGJ{EMc{)260yNG3Ar%?`yr5x9Es32<}NU*0VnUqe02PrV!DKK=Om_@;+ACp{Y!wFfra<7$7hwC*hG(mwta>&Bk*y7e+K z`gp#^Sy$GFJkDG6K5`xtRlCgm+?f091moy$vfUn6`v)6c29jdhT?)sCset%gf`T1p%9|Iy+ z%CKy5#@~9SH{#aJI2q`{FQVocqNs4%X&NX;vJsGmw36i;m;7)4q|YB-HaI5e{xS`< zYIMTdjJ+kFx!4D~?OggK0%n6kuqacD%uOirPpxfXkM*5m?D2ioek7)Wp8aI}ejC2s-Ga-!5 z(%zVzjuGihYBPvl0fi)02B5Br@Em}4NI*gv@0qX8TVRiv!hd)c(evlqWpBLMr^nZP_QmzScddhs`zUKME+dw)H2uxV_;@;=IqS)-aR5V`s{)>D8RE>?|=*%g0t`Ad3ppw7Jp|hdN3#w*UQHxTsEI^UpikO zfBkihVQLUyF*PpE*ZVRepqHW9V8zKuVyFp z*}#CdWgW942AMYI4YxTo^FES%idfIq$3KgBb_(nw!)8=Moj86(00<_Z14-$qD>+KE z1~-I<(SHdTpoNBXQXYabMh>Fd1?$WV`NUyQ!?1;J#Ww0=H##lHA`og~CM0GDQmrB@ zawMfvwKYyd5}uYaO7SMogQNS_K)dmQ_9pi^E`X>mFc1_;Ex>{Ke3K;h4E+<=r{ydF;(YF$HXSAE`p@^;+ zjen^b6{M%Eq$%?Z^z~&a7?IDKEmlnNX1+^fnifC|of<e=TvslI6Pdti6bCg~F4xtLNuQ_2EyY}ciWlW^H?I8pVT1Y> zXO5#>t>^gF%uT_y(^TCDN`^;LUJaPxuz#3g&PF3_kIOn=byNy^%q}kGz|f`^F{D@& z-Bp&Tq-vWhdq)u}XZv7WiONdRSOOse*L0N$rj^aMZ&J}pXNZV9vREFRIM8sM^RH72 z_gvb8($O}_0*T{*e+TlvcrzuhPF^LG3gD_mYn*7xtCbla_l5oO<#9EJH}iBQnSTiQ z?7?DU?UIz+hN*Wlt?uvk<;OLw@mLmy zj8RjTI7x8nVIn+I9zD~BcIKDDRlEno!m_5KB;+gQBSFP9z!*bj?o>R~7=NU5rZNw^ zDKIdKo06Q@c7_53ZKRl-1qdc<70V1HaQ#j>{rL28t#psTg8wHULqDj{EGV}EV8qBb zFNdPjC$oB#%}@@aE)7JTy!D|M30SpWG#7c6S!O6bw2tdrMf}Gr`t(*ix{skWfFePj zK%WPPBzlqX^T2d{YCES>6o12l#%<471zY;i)!!3M{d6^6h+?)72Tx<=raCXPgP3E* zbQa_PuX>^`<7?1%nYxTe^q%%QmH`(MZ!&BT0XAuJImKzXoP|%*NWlpz$RhmUY*d6W zd5|wn`JXNtU4`Hm06EA4tKJT0<5ne4qUXzl>x2*IF+R||5r~`c4S$JqJ#p+KZWxY& zL0JaWiXrX*D`WS)s@g>Y`=d&Za}`tVl$J*=Q6`El91?U9OiiDNxdUfuZ~0^*SBCNG zj7?bKUR959xIHfd>bGLk9f@Wld15D2Zn~d?_X?9-6aEh?2yM~32)}bwU`whh%J8AB z&s%13fn#>IihHAIUVlFQ`26{QVH`A;Uv}9}u%WH0p8Tf`RYtm^&`&P7(^>;>8 zpviP<6lQB$Zr+bV_|!uEI|cLcopBn6+p*cGJdHU(UJ+15+j4p>7@kK?=0?4e3mxA4 zkI&wp8Sa5Oy=K0>uIDG_2>A_A6A7*Nn9iyOAv1@8YKo)_%6~5=x3iFjmGqBPWoKh- zj4Y9i9%YMqfF39UK3C9&AgP9A=zyplIxxhE<2?RgE179!Fy~srmzJa+r4lv z2gy?p!So7-WFvSJa%U9dqKz2bL|a>!ChoZQoc{hWwX_?jji^q&=D$K^cb5@t0x5r< zfBNa^_388b|NhtjAJQM2jxW3B0BpG?CakHW!Z}ssfMQN3fphZW^!H0yYT{Fwo`42)DAws2Ct}*%?-w#wI9Npt6e4%{Ff2(m z5L&P%im{2NEhwJszp-!CKY2X2QJ8=KaYVgU&>2{UI|mpzflR#pT9o6ewns6>Zt-R|G zI&fgw4Ib3r-tGwxw(_E@iX`wHc433w^@lfCBu*=lm3h+%t^3{b{o4xNm`6d0)4kc^ zv?6L~`tvBp^7_tjv@t^13-lO9KcNdx6{CY8z?Xf&(6Vf4YIS5u`A!SHHDg{|mreis zorGxSq33m>d%V#I?&6YwA2WZFQk3U+0`~()1p3p-3qXuCfyT*J`{hD95`u%@Fm-=@ zdH($Mj`N##2VE)d?E3cf{`JUL=i*9?%L53Erv)6AEFO74q}+;RLHHkUJ@Vr}eqJ|j zq;!Jpz}K@_uQCXf2}p)FJcDk7ZgG~f<3Om)=K-JX(Y!Ncg{kIV!RIHzuoK)_2>e){ zr4~vcZn=u21!l@rkBF|c&c7^(HUfiZ(~CJt;GCCTZUP+*uEH}*gyK~ABobbnESHCF z0!@FHPL2fAs$gDZer2%ScURYJ$}> ze)JECN8Ou{crBN+OMk~x+1DLmB)3-oHHG{Xq3Le@-mGStd(di zq3keht@(Bo<{uQ{EcD}$dVeiUu0W@XOtpVCX!K%HDhZPr6K(FCj#+q0qv%D9`@p#L zOWrl36+5Y=B3b(ca$L>C>J@757v?eG*JQ(?ELQm=X7X8@1o(9@pPZBnaYeFe!QGkb zfgFk@$y<}Tvu2ayaBa4xtjWB?DBP>-e|~#>-R6pmi6vi|IZzhLCR-X>H{XQrN1k&CmdAYl~`ov#ssXFSH}5a2s?C66H$f z9zIv4s-B^ovy`ZqI>nR}<{%YH9C-3uo`vc%s`V>3mt9#eJDYR+FZ%8CeTVob)<1vh zQsg_UC-WCCtY=zp_oe^({L}N(I?#WNWG^J;8-{@qU1heCv^a~U3n_2aC=k!cT5@je zl7|!`cjz8w#U0JjEH+*6|}f}vF9IOxBNs1%$>-2pT#BxH^F)ljGSKNWFgMC zIZ)`5BlFMZh*MPg8t;$rDP+)Q?i7fRFB-9?c@&Edcmz(!*a{ap_NF2qc4&XN{{H;o z>19i^2a3P4rd!OXCI4a&N!x8l6l3$65>a%ANH7+44G|Q&{qAdQ+3W-QjXwkFLroIM zbo`;$7)97A=%gT*zT@`_^%u~2fxz&J2!;!zO!MpAe?5d_?L$BT@zxjYs0B!Ptmnc# zAc2pF3^lZIlE8DjxBKw;<(D5{wtO;y(~?#jDoUs3b>S~K z^%F;6n3#^H(i2fSw8nB)TMTEv*MZV~yuMWkz6*I|Vb;5uGxS~l&z$j`6O zA2xHEvvP91nwtCUsA9<&R`fiMxa8 zbnlPPU%sxbg`{dpm)7r4|7gt~V#qaPgUP|Ma%TB-7psryo%z(9}crtLA@xd;a)!Gd+JVp1Xe1UISNV>l-cn z%h%VZHT`Q`+&$iI{$>yU?dj=no9=-!ShT{n9Yo!r?A_%qnvJWmc)HKUIEgot#O7`s z7w&q(`fj)pvXcJ5=$=<}$D8})<4$Azw4T{%t3`SYDZ3XaAejgm8i+Mg8bK7jKjV8I zv`CVlb=nYqS^Iw~9ZJwzJ5)=~5$hx|C?Z!*)Rd#!HUYm;MdS{WWnk@@h`=uP`r%2Vcy+J96+#)rF6Hk9MdK*gj1;Wu7ga_jst$2iMBJ*{D zkS7>Tt>V7*Y+N7BgcBQ;lq8Z1c$g4UjPVc>;fSBGozd7qdoq%wQlms{6uutd4k{+v znn!Sw?C{QR@Kk6=fz(-7LP|@wUmNjwEhDiw>gFvk9AbrQ(XTj?iqg zFt44PfR-_2MbeY0s|Y@sk3G#(&P&Vq1Q^blSY;qMuNf65Lyf_}uVO)uL|6`t7dA%2 z8Gi-#OOmyzSr(F4;tLUx1qzGc%o06k0xq;fx!!+FP8I#pj~3p4aHc;<%s+7~z4IC{ zpQ$fug+*EXMY{IUa{HZP&xEAWzh%Wlx$rBS!F`K)`M9AfcZdNmhu45r)o^Tk43^|0 z@~b1Rr#js2Wus!&<=7143kDO&jpEN0j0MOEL-A$ukCKM8QRwXluRH>~8_86|W@k35 zoh*Ocye&mUnR`f|kGiyUCaRs%d8h9lq3qJ_GYptHEu&qvjJixTEUEpkVLj{6i%G## zHUgwP0Q^TadU}WWb3T4wJzu^(e*E(F+lS}vdXK9QqfllFA3aP+(ThTdL~&V`>(oxp zO#VAJ;p_&gQ1~;!#p#N~hoW$Kh*GIO_j`Z9>mAS8#9BOwWdnZiBg#tD~`R93(1gw49 zev{ys*_5W1>clgFxo5dO?(SF4rBbIe!P`nzt!(kqC8dvI-ab*bokLBvqfI%42g!eu zmQjOk5K%<1#P@k?T<-G>8(|BRO9n8Vqcb@&%4*{TZB_}iQlIr`Dy>Bqa;8C&gOp>d z{Tb(96lb0jGeIY!EI!OY2aPXY3czZ9(R6SzfFT#1=;FoJxY|cE0r#PtF{NIZ-O>mX z=T|z30&@<<$$Hx=#&!ZfJ+AOkn!|rxC6-aIOhPLlstpfFedw-!Qw&+($PB;$TQ+W` zptP<~tcf^7-jg$1(>GIwIWU;fg&?mSBG@=&@LmhtdTt{oNZ4MWc^2&f5cxH!tg-@MNX|BHfy~ zFiLp!7*-^FM22ol+GhHRk{&EqeNd)3Ipnb`S0-Cjs(90?9rD5GkO#o;DXjqDsO5HN zqZx06&y$m(vGoq7?H%HBd)(|7`Mb-e;DnNa(vv9RIXtpAL8OffkO6-KXtk0pN>=dx zwuLAzGzdj0QZe#5=1y1DrDZ>Gs}zFHX-*>9fIJ_;-?qlvzHF7%vP9Dn3mu!G#srB} zy183!pE&H;;A2NUsp~Sw8qaKo%qhm(G&Rp2qUpPBkK6rv3uhTXu4_lOG%sS5a$SN! zOxb(b$o1N?Rr)8)o1A}Jm88gy)3<3#DpT>G{=__c_AOdkwdYbONBY)>cZQA~N|-;5 zOyobq$A5;8{|q1h7Y`pF-*0oQxooaN0K=U@OC2H8f=pYI;#Fn}2Ba}^<)Dy~h;)DFnMbKo^|P}{t95qv z7W$cXHK~j!GEc_?n^EQ3gRQ@7zG*!)DA%$nozmXplGxw@S@S^gK%G zKrA-Ev^e(ryhpQYbTy zK1y@Q_eG8)9|amTSKd*Mra}>W&M=Pf0R~`|Qb|wk^eT4C-Gcq}`26uMrA)k z;chR^t(%=Yz+L)uFgDPiR5rd7&y9m_Jy`k z?a>j}PZxhWVsqED^Q7Ue6DgQ>cf`lN^Ysn)_4M)Er>A$nJpa57h@*CWxF(Wx@G_bn!`Uap&wePC8?<(_m<=c0a+jrI5cj@XkUSWgCK+xcf{A%=Z zGKau}b|JtioH5_|GFd>A`PxolSxk-)4yW<5SU^MsDY8?m=&&?C=|S0I%-U9- zU*><+E#HGV#M1&)$E_{NhOd%fzzwSLOXYZGQk@W3n0+$m*(Ro?@Q}XWtiIol|6rpV zKzfJiPoaZgrz@4;Hhm|+zptxbKX2w4OS!H{xxPs6FOuK_Y9g-lW$W)MFWIjpA1zT> zu?yuklf<>NXT;R0GbO!vNXMlrXIMQ1FEW3s zxWN%R^q0>rd+PiJt_bJNrKDX>zz#DIqCO#PKkVoC>&z8_t;yWPUKn8}SE|`5@tQnf{;-;Ch)Nc&31dKRX5Yam`~YAi)W#k-%MfBO1<1AqcDED|k@#PV}7bvgR{fv0!$Rfydyo+VM3XUX06@vCl*MI?*FwM@hE3`lA$f5z=m;?qGcOJYs>*ppT{FuxQ3 zE?Mf*(c6mLTgcg)PX_HZaC(0rVGn=OjBMG?L0tJr^zTZOh6;{&R+iE$S+Nnh>@o`Z zz*Kn1D4=nUltqR4Z%r}^-`C;9h9WjNF$Mv^iSrFk%%t@EMhp1#^y$Z^*Dt?3|GI4h zKug75dqgmW&cU!N_<&iTv%kIRWOPRA1YdiG%~`2)Yz6lAjtR$h6?K1i*R0lW(OTQv ze|>%Y`x;$%YrRbLYN9$YY4qK;NGgO=>kZ=y_65CwBtOWd;Co6Oa(%s0#Q=-{H&@x` zJ8x}0)*EPd7|mUCAXjSiCU*(?mbOK0F%Jcq5Nm9K2e5p(D;)*IM{qoCFkOv_L50L) zdSoE7l<&Ysw0J@Jg-L%x>B%iAmMhPoFLKXM76v1Im=5?(LfJ$T6$8DSG;wInz!i3& zml)J?m7?f<=X{=Bdg+`;f@bk>JQz@>GUn!(!;wfo3**%e#D1^a9WF540XKx3(KHtV z>@N9Fv$m!xvA^&q@HEbo2hk)U!D*nm5^R6AQ}K7qx>GjyEC_#h2QF18B!I#bi7`>+q2_0sz z$L)k_*H9@!SPhGBmj1XRCppF8>BGOhWLms@>R*&@Uzu*-t~a=3x@5x%jbfC=8|9x) zGhJ+9us=aNKs$f4)VX+~-GCqw3f!@Ij%u%P1$xflS^tl=?aaYg$X&(@sZE)WmWtMF zHNt1~#qlt+XdyLlbaA;`{$ZWX``ix*8vxCV*^fVxE2MY5J~T?2nz57&(7o|lld;XE05krGJR z7#%!KefiU?vvFj)oNu)I>F=KY>(`gpuN$`r`Jj{sKu8V&nanlxp8iX3`|xCco`uWF z*JY%Zm%Xytlq}(j$80RdS$<@K**v+%srXXM`JX7byezo%#|zFLXB?N^-&z(50$OPj zq=PTpFV27GPut?;7=@$}m1UZX5;h)-GTllt_JS--+q*BuVbcT$E61s;OHG~GBL{k) zS&AUvR3XkqHhunZ`+64QqLKD?JGWvrp=G;T6XbjK%gEVEFRtuX6LqY)>8@@@{0%$gU0WE z{o-9OMJ(j4j5fGN!zX2943)bm<{zd*0F1_VOU#P%7jwHQ9u@_!(zVDAgW@u-EQ>TS z9^HSbnzhQ4+$XCZ9$5_J`Zj5|K#r{bo8m_JKdy%YKkPp3&h1w^c`OWKxuejh2(LtH z7Fs{3W&%n4P+xRPFnmeI8H$I*b^q~0hof@NAlptb@UyE52Bt-$AHLv8)?XSbs z$T->u@^kIa*ne?#4-Q&|bip@gzQ${70##YB6Df&QQonmt;BxX=u0wE9@Y*ew{kEsKX`c=hF_l$ z6ggJD+opl$O#>~b^}W;PS(*1bE|)rl0!%A;aA&6wA(&kjC6Lz|6U_Hsm;LHEu1E4} zyDR$DY2=WZy}zigMWgaToI`(5u2Gn(+AZgb}ZFK;;4+jehw``m0nz&j_q z-*w&(LOZPYwzp69Z?&?I&p-e2_4D)RpEphIKaJ^)#&jy{{+rf)GM^|1M2{0=Rf_b| zZZc{p$Wn;9!u@WoynB6o{=AxKqsgtbG1)pR8EH8IjD(;xFsYL73RJLyYKe<~66$bQ z{y#E?4&a{2Dg1kCc~hmUDsD>-n}1vVYQmt1ELW~WJy;oMl4G<>GYt+CwjrL3Kd1r0 zTq^N}X@iWsNvy2~>1gDP%gp_w%S{}=kv~H}9{M#B$n$n)#}WFT%DULgyBAA7v1h*3 zs6L}nZDl&i<=oDawacu<41Z5B<6i0sVVw@2OtGC#4DVd%_!G zvgg0mJb!(B{rd4A_bZDY%!w-hqv4T*Y)*qcS_U|yEL7YuM}d>aAd|955)v$)f#Vhh z`fOb4gM!7)7QY=ymX`1sdLC~-IW1&3nS}_#Kuo8Vj{+OQ$Dca_xk+Zn-@;U}Kx$Gs zYJbeF%jT;bn#g^bE5=sFY&}WmWCDww5blvZikW+JUbUL`3@7$faxifjid1mTA>e&b z7Qa&9Kp<(!^?E4^i&1I@ry@c9Aa#-;B(`$+odk*sSfxBil$){;o4jwh1ShPma84bC?cPfwBm$jvEwg*gq$ zfIii*Wo>rnQ<8|v!&)F#qr3)O=U}(IC`H^&^%WlEz`-iRN6Xm|=zbc$Y{3aiA*qRs z=shhQ`r;^K-m!aeDQkpjbMsRD`NeM%7Uq?T^9mA{nQXjab6Nf7bKdNSFW+7__J1HT zdKw@|N=kwWEv=Z5N$n!|x}4~&S8lI08Yb_w8SE`6cig~nHJDo!><3wj78w!)N` zf}ktv#ACdaGtG(0AD%_7_guKW7$xBC%`BgWuLe|hl-qhv!A~}ZLIlR7ZN1YFHZ^CS z03rfj#lRjxj=|`h4(UQzXj-M6yAR*@?P$-paMPgHKTUBASEPNphVzfBkAuyNDONX1_7;j?J zgL2eb$B~Cwqr2y98L1NQeV&_2;`%ZlMV6qYO65`|v*}t6N$9|WOxvg!1&$JJl$kk$#imjYGy{*|f+2byrH+NWv zc?xX9?q)t+V<#)<=zws;t}Z;svS7XD{eiZ{dG3$Vp%N*7VB|nl;0f$`HHcRT%t*in z4ngxiPS6U~9c~TdyWQ}9R?s?Ie}0B~^Gy`LgbroVzIa0 zd=v9CFT6bD(U|VhLBy|t3lC%vB{uS`R((!fHn&`-(kiN(xfx%{i{SiSjSTgZ!DNQs%Wd6yj_R)MqHe7pAo`~R0Ky^Qu zvbp+%wq4RG@=sOB3UgsTtyty48kAk?X!mw4C=cU%U~W$Zbgj?=_FQ=?k0+kZ|3s(( z-*G_JwB+^ZA5nXOc$q5xfAasbo6*5k4Rn@xt^67XSt?(7k@2Au2<}JS1r5~GxD_;d zbLm)bn?`CkwL7NYA}doyF__N2<6-{t?ek__@W-;8hRZq{$dPyP`~ENmGnUaf^u8tF z-7`OP34q@oCndDJ2uv8_;*JW#;yb8u4jsD(36>zCMaSt@Oq6v1e;SzXslo<|)h1kQ zz;U4=hb&>rBz7Wb2E&;|Zw&#d2Qgw#<9a*mKDZs`p{boKBIDuGV?7;`dCqi4;nYS2 zm60}Y-GvHt)?Gq5+x?J~JAGh*AG20HauhWM@j$|t_+UN=5;PPnEsA;72u@4#EyIs@ zwj1)s=yL`_6nkE=e}wCrI-yqg6jE4=g70QK6j5YQvkWiC)`=88yDzJXu5YeN6R~zd z+R8LCmpR;)SkFayp3jl92-mX8{CC>wmvwdxy8NkZ+TXVI-iO7*CM+Je@%6Bd@p{TY zE`2G&j+V`EQdhC$xIRI_y-nbkBkkG(MXu92BJDPTV+fP%fAyM8pF2rn{;%1O{#EV$ z`)%jlhnL?z|8HqP|EaGx#wWU_7#$!VhD1HZ3$N9%j8QEhI{PTaKFvCS(}fP@dfU`` z1DU!aRBtvu@vtqM)h^pZwI)i(ur*Ow%d-KiwF8>yycwNN zu_ih#1ldG&8JeihWE1V1uG(?7OFd0Z6z`xG$~C2$C|-E%3wviRbdgj-yCoZQtC0%X zcfQp?e|!GCj>^TOTLYrnY6e`v9GTFy$x>x5R)jsRf0a(89m3@?yuZqWHxGQ0UyS?7 zi87rm%E%yLa%x&qKYl75f`bQau}dyj2Ge3=o#gJQ-O`qDO+`!GCR#GELHS#Qa!j!^ zHk*M21I$++jNH+ezMZX6ddt#j55`)d^_!vMt9T%daT`ejSVnNEvyM!9yb z?s&R3g16LuZ5EbfkJm+>BFfC->7cB~6;nImpIbGJ?>65($>ym=oU?Ll2G9|cl)J!Z zJ6XZjfR;=umJ3}JEo5~?4kxTc$7L$^{;`_df5eoBRZKZwu!vkm`G!@Lk5&77?e;{H z{|H*-+JifTNP1Zf0j|Sy5KEUuFA4yaogn=^WuyqHV~A5hdS7ho*-{rPwW&Z7L37-O)X2E8!eFKrq-mKXEw5QOVi3Wjo~J=97hJ8J+s-PT|S z*(oCA;gw`*a=M`nReTJ=BX}~%e-c)(=t^AFPL2HX^0MZU8R%4kmc6%>3&mg(;5`FP zT5vqj3nktqkqIJ0o`XdpZ3@}y(8WYcSJCkjz4!%Xka?;f1)2ydBWbG__AmKL5qx0Y zB2Wcf+cg|j=H@iIh?);sa!6Fn3evXj-)2@x5iPuxFr^Ectxq%YwV41YfBDoZH@V=9 zlH-=6VRd7z!XE2_L&VWnO zPTXk_b-Pb}>{VpR_(;713o&YbO9B}LPGH&u7LPJBzDgYcQ37Y2e~%`~W7r=~HbN7H zY>@|RD$bU@y*4jKECFeDY-RaHrdARkm_Lv`(S78YHCbxW9xEA=6`CICUM5FmQ~ofB zr(!X~kKre0T)T}RX2wo*t70qgr2J1Wi-AHfq+{YzuQEB892v+F%ESj|QxSkYlE`mt z>H}UyFToM42W`!Ue?}ifh2bp?n@Of(%>Ys6q4U&6tTIEBV_d!k^4nIEDNLB0rAjft ziJ{SxtOSXJg@Yes$ckkH)l`h=HyToCdi_NEB`Sy73)hqdXQa2llGdOSNNg=>^QO0< zB^eINy(;-ISK|G6{Qj56wcZ)xSU@D_X}N**E_9WwZ%E(B`fQ%Hz9oC{&RM)Eavo{$9ZA%s zP&2hqN0Ry(e=9d;YZ36#KY$=|Gj#}>Po2U9f!Z^t;Inb=N;5=pViMAM`8T!NB-xQY zloSJeNE3_2!-l&`S;nhe#IW8I_Rewm&U$yhc6V;QyIe>_VD0$=M$yVEj7~PpXpm0Ym4|I}^o^o?_qXSd zFF(KD+06eb(?3$Cmu8XD7zzI%UfXk88O#jIj1)9+MMO%-pQ~Y81Gs~NCM~9QKEuTYf5lwN&OP#k|p~hDb|)v>n;7a#=OP!WCXk2A$-ivZX)} zD%14`37atn3GJ6dp_=i;WF7LTI$L+;jg|K;)5UpGFjqJqujQ;2+^ z*wsY|MSnAn9M+?GvZHaa2-{Uv=*brT^(Y=GS^kM7E*U%)@=Z@58pf~DrVGLW2FX>z zOo;Ntpc<;g+|W;8nkmJiz|A4YdI~)$CMaL2@)|O@aM4!q_Vj2XQcz@-R!TLVxKN-g z%LuzzT}_gXk(gQv6^gp7IOD4tY^0+}oN0C8)PF#`hGeUJv!(;s95J9Js{i3SCZU_c4AI z9&DWmlAOjJffn#o#o&?x&+n)!GBfq2uYW)2o|Rm}Q*VM+CI43H$Tdw`89WG{>q*Q_ zqM{$!I`cvP6kdpp=}uAkO~%74yIH_WjmDj-+!D~`Hs;%7Z7WSy z&>@cLOm$WO(D G7s-0C%Key` zyHP=Wf*=SaG9x44I+@CvwN(tLt`5#*tN$5e-FRmo+QaR9s^RTt^z!Zb!_QBjpI$#c ze|Y--?QP>A)XXr`$TE!jIg^?CxL6_cpfP(kD|104SrPit{ux$7V%C)MWq(BGy*+EI z5-rJn#9QEuh{YrvuZEb-Ffh{pTKlHLv7%1nBrLCgab_gL!-mL0UOq34C=z04vDWEB zKa@4)OL7oxUOpPg=VIIMx6{k($EVj%&tGrotSp}+Q9nI@W0*Gi)IDEICZW36<<*;c zQDTA}@~Wbz6`%1kj2@Ss_kUQADo%rS7R4V-uA&*-@--(I3>Me)SmRD9qq}D^B0Z6UpIp_1Sf6%V)FLzq? zFI?WWB7=hcOTQ~VNd}KADns}1gEun&;0+$OkAM6VO?B`EI_S>_BY&osO89ov%(YN; z)%qRUv_~n6tAUNzH^+MxkKjEvudC*}0S})Vroa1+%0(mo)z@zYr;8r<*E%ImIQzWM zdQf-2htmrwKlr5j%_p@s>HJ5{e}Gq>#y-03Z@!5;U1$E?E_U;RUOxTr^S7_p__0oR zRMN;Cc{EBLOUcTk=YOq`eMz9G6Y&=t#l=3b!f7A7V|ReRspTjgbbI%|y=-G}?V9xS zfH$|C6)I%oTP%yor0{QjST!t|Im?5wVsrr6_*H7(B1Vwhz%t=H;JBQ-eVy#tYvJ%q z`x4Bbu*OH;0DC0>0Z;3mWpLF%)ki?T$w6=hh+QlO@+@e*1%IdjkfE%);yg{ohTG5( zw={`~dwJ4^EEF$gQ;-llH%dLlTm?Z@V8ntf9gx!XUb}9o9;M8@Uj`FPxsU-Mf4`$= z%kv6qXQ{1=CL%{#i6gx={m8XJE4OyD^?MMrB`}9ncMcdsZSOq&fCI9#^j<2l0Iy!b z^aDB4IbQFX8h_aPp#N!+<_&z{W!u}@NLBD>Mh%#ms2k1ZtDoj1tfsYnl#qa8X z%kaZq(EffeC|A9}^1?to6TU7frHLg0E48usp!rzr^6XZyMHhkad#^qHiMRf;ne4rW zu6F*QMl-;NJ@!Yo9~kMRC5-lObu6pmI+q2k(obf^SAQFvh#-d=r{$m+0kZ-{ZeM)r z5X2fewvBO^Zzx(9$30a!$vsEq*dCQj$#)SIZD@%_WS_9f1x zdR)*OQyk}89#~;0JcA2ub{wHyB>~6K*hz+yG^=tT<>{1g*^naUIMBHiX=TE0%tOTA z6&8t-Mt_eKXXnW9Z4?CRW1}5unauYn&B=Ae`b~}s`P%k#NaR||K31)(E(ecuo?D;3TD*j7=YZ0Ji!?ZpZz4{JoVk}1!^E2I~?bVQ~v zY1$o;ftOOo18+~Hn-2(PNJb$&Ao&xEJ+fwo@PCGt(5dU&qYM=hp-<5I!yu}VX={;$ ze5A$)4>gJvPV1;MSZlScabK6^hUJ>obKP>rZL9qK<;(M@m#2*|j%!!R&NKT;CGKml zOeHuZU)5mpX^v%HK@!UhLTtP!YFv$M-W)3gjlRk#6ZZ~N3o>iTGC$d9nn`~h$!kY` zmVZ8^u;H<=wCl|$!-y_7L&ist*_Eu=if611d{nXbZVa7w`A-Q`TR_S^ZVY7yulJ*#0tY$ED=+9?hw^f#54e6-YPtI0UzR8cS-BG@*7 ztWEekau;Frib4g5w2ZUN+A)ccxyhwRqkq!|Py;a3I3!1V7pJ;2xuEAs6dpMV>np9L zW|&rz_J$GD+*l>x9eNe<0L9I}Qn{B967D)iu3*j*qs*$F06|lZRBsDB+P9o$d=LZT z_0_XH`L4tdj0hF4{^wTy_SgXc-F++FA@`!Ma*Vmw~p*zz$mbtv!h{9O0$}} zFUKt3K?!-e%rZ+cWG!w=v@-Yjy*ho`a2H6%LhQX5!|izN9}E2RvVfMN^0LOoCKhVz z@rq`0S!MLcdyuIOw(E+Txa@yaxqn}tetr4n<)6>jFnsCgs1D0GCcrQZ!=o^~Kf21x z>&;bGWt+BHE_VO4w=d7H*X<%0p;W0Ph!d?c(kPAEC(|g+!DK|E$mrEn|L=|T{`~dZ z+xw=C#>Wx8p`*Mt#jQ0eLci3jSM7?PMa)acT+oI~Yos4F;@54O&aogxtbeJfBe>Vj zT_|4gzXWmd`B#Y%Dv5IMHPu`lKhtuz&IYn(btV(Uq>RE*Ln?O_Sq$g0=ca0J@1MRb zkN>KW4@W;&?iwKLo2I)APjO|}@8Q5@KU&{{SV8Pm@0II88lJ} zx-g(S*vdVyS}5B3K)NA2U5L71r6T=lN%;W_8wNJZXNQ^{zG?&Q8h@m;Q@`?X*ghB{ zQo5Esi&XR}*AkR1R=SVk7#M1bhTf^6`x5E7Bc%JCMc>^UmK&gb2Ot=y0>JU5BrP{9 zCkZcJs-bQ|PXhm%4BZYgnhv5h$I>8F!!*r6>O?1L=xXWa!Sz7jAxgW!SMO9Bshak3 zLjkvU&Y5{sm0dr*(0@B$$=`3p8d_N+85wJPsQ_ss+N?pNg3m9(LDHv__u?>KC^Fg+ z)m{D%-iAy;5P^F{v#b-U-@FV4StE~lLs;GpNEH^BG^R|a(r&Pdmmblgnl*ciIX4W> zJ{5zBV4_+y&DO@6c*DiW)EnCEqcz&2He1`r(}oFJS+m`DVfl)NW#8a65v$>_jMj?@BDzu26iy9MwPnd_IG$A5 z93x{0fk-3RP=Bi96$orYB7^BB0rrR1Ss#=%gtAvI3ddF^?NA_sU!Amzr?`3C@2{Vp z-#@>6-NXva&_R!#{m&6UZS9aBPU1WqeP|3inL(Q8S-E8?%v0Uj+n0;Q zaW_@}`R&&$6APw&P1wajUqyK{WGTC1_$@MHvX?xlo~9~zLsCFrl8J&*F73$;N>2N- zaonwBgnxT8KbZk2B=WMxZGP;^V_u7dOGexhJe-}v3UI>=9T&$^Uuv)5M28q(%VMP( zwX34GBGju?PcY~#g;%;4L}tz8>XcB3($I;)xthr^BFGjKmP;WM%=8{C7cF3y8VIe< zU!0kS$|>9{9zJk9)ou*k)K-Z-R~-WmIJbD9Lw|tm6PGudBC$T|A1n|b11w_=KBtT` zZUg|cCmM}YZ1N8)T5ZqxF>7aN$+U908mD3=B0L9XQqH}nNvIX&t~KmSMe{@svT4?$ zsd$pSsP<1*Pz3UJE>pN>SZ?0tP-8k3b!(gqy=P!ajf$#s;8je6sf%m8dtPJ4k}Ar{ zXn$o26=C^?)_veqnmXrcso~YoKgtgx1Hk-xBwxw)>@VNnxws2P=;6Vvn=8GE$vB;; zWR4d1|MQEy_gQ}U`1bnk{q6JTYtzAe%*sTV%Bi?R!>bP@W8L8aFFVgOc&`*wY%3ba z)2SpuTDgkU4hUtMdvL!B!)(@{ zi=4>CfWG`U?XNN>yY1fL4;t$xc40NDPS$yEG&5pPq_(70y6RNDKWtU|QG1!wifnQ9 z!++9kSs+%x=j-esfo?qO5zePV?c^*GFsim0yz)h)T` zMewz4?4(Fn)D(+tabVz$rMeF6k+>N)aP_T{Eq?)pG0HtKCLmX5!(vH=!pX>5b7%wjnV6zG{2gR- zLBHhfD*;3WRRkRy#1dm%1ZC+c=Zj-HMEbm>s!8E%RHF+CS%^&cBC&Om1Y{Kb9&B%m z7fxfNSM_`Vs{a9?F+}>*S0$z4Eqz{m9CDquBE)KNHELT!SWYNCdn1WsB!6qA^<=at zKg77Cywd!V4H#s2lc&(^0HFg;qWHDV=5tk z2wr6QKW`vpVu_aTRocoFFgf0o;!$BA4p} zdZ;-g&3pxZn!(EmW9uHQ<>8cIHv&!-!Z3Wi#T>Sg1}_&WEB+p1r3Pu_P$TbH*CqX` z=~n=G`{2|NtI|==dQm*NO$@z~p|Oj0I1FaTABx-%6RAh~Z%1|}o_{G)#0;=854&Rl zYbw~#`i-m7>7qD+7dBnV4s(VifA>g4{Cn1u#!hkHnRK4z6n%smf zs?A)&lQ9)XJBfA;@}(3Dk7AsS3e%dSKPchj9DQ38Ir!rOCZau=w zlYWh%Sp~xVFZIy@J3!~n5Nva1i5=TBjIZ=-IJCp@*5YmJ9GHO!z=@twB*2j!S_AmE zFX3@3sE}%$mJ6&-(cf4gkuftM_8{jK4D<$xw#2evcYat2pMQHFx)!H(p;FT+FxS!< zi;Iu)K~7EPK83{igqImfy(KGY<;E@!+e$@B6;!5za#|Q z)i$8wn{6%bnaPXEGOpUbEu%DRH15Chj2Op4I!9+nXMaGuIl^CXHRnk%?4Hxw8+%Q9 zYxOp_T4n8xR+$s9Hyg_jk8H?f&6B1DC3+C0M1w{2q(NlTqoUsPj!--?v-#eB4UWmT z9pdws4Ln&CU6a#~Q&6a53eu%8qy4h9I)+KRTRERn}uj-UVmwmzaF&U?>NhV-_GVf2)Nkca~6eFW`GE^L_Kp&rRRppAMnzCx_ zky*G#^Z53ze1EVCb+W>U)dT1_CKRVq^4g1=XBaGD!m3s)4O_%m@Y4`H(0%Y0gK1TG z!GE+C=CBTh;>l5&jP*S<#$q=T=V8dpYu7gkG zb!^JSG`9kgME`DOC+mGF$va1u2p;sCGn!Zlm+jVctAp9N9(RwugGc}E?fbXyKRq03^2Xu-Z_l^a@?sf_sXMfzm zpkn2z_28yJk44W}AzbKcWCVl4Im!MY(rJM!7GEWuF1-4gxg`gHB6Ib(kN?k?FWYq} zMC*7r2q`KC=duXI_EvRnfi-k%8B|L;4l3m+L5J8qLbp@bC2d`PHk#7eE7=W?dOhY? vy@Ks*S-xHdY5wQa^WVNMKVSb({}#NwzrB8V`S=F;sW$x!+AE9Me}V`A(4XCG delta 169716 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 diff --git a/homeassistant/components/frontend/www_static/service_worker.js b/homeassistant/components/frontend/www_static/service_worker.js index b32fd52b70ba9..5f227d1154616 100644 --- a/homeassistant/components/frontend/www_static/service_worker.js +++ b/homeassistant/components/frontend/www_static/service_worker.js @@ -1 +1 @@ -"use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}function notificationEventCallback(e,t){firePushCallback({action:t.action,data:t.notification.data,tag:t.notification.tag,type:e},t.notification.data.jwt)}function firePushCallback(e,t){delete e.data.jwt,0===Object.keys(e.data).length&&e.data.constructor===Object&&delete e.data,fetch("/api/notify.html5/callback",{method:"POST",headers:new Headers({"Content-Type":"application/json",Authorization:"Bearer "+t}),body:JSON.stringify(e)})}var precacheConfig=[["/","c19243c260ff1ff7f679e70e1fdb2fd3"],["/frontend/panels/dev-event-c4a5f70eece9f92616a65e8d26be803e.html","8626b97f56c0056659c8214414b98e9b"],["/frontend/panels/dev-info-34e2df1af32e60fffcafe7e008a92169.html","7e939dc762dc0c0ec769db4ea76a4b09"],["/frontend/panels/dev-service-07e83c6b7f79d78a59258f6dba477b54.html","98ae94372a50c279c8f3d82f473241bb"],["/frontend/panels/dev-state-fd8eb946856b1346a87a51d0c86854ff.html","6ad0c48237a02429dc444ca21cb7f713"],["/frontend/panels/dev-template-7cff8a2ef3f44fdaf357a0d41696bf6d.html","aa9d7a78f7fd8ca85528f9b059106cd4"],["/frontend/panels/history-efe1bcdd7733b09e55f4f965d171c295.html","91e823105f7d77beac1dc4190e03e1df"],["/frontend/panels/iframe-d920f0aa3c903680f2f8795e2255daab.html","5957b790aa78da7cbd80961409e8fd6a"],["/frontend/panels/logbook-66108d82763359a218c9695f0553de40.html","fd03dc06b40d72c0888f659874328e5a"],["/frontend/panels/map-af7d04aff7dd5479c5a0016bc8d4dd7d.html","6031df1b4d23d5b321208449b2d293f8"],["/static/core-78862c0984279b6876f594ffde45177c.js","70c1c2d9ab233c6ba7f18f6bfc7028b0"],["/static/frontend-c1753e1ce530f978036742477c96d2fd.html","1c2a5c8f561228244b9e0d7c7655843c"],["/static/mdi-6bd013a8252e19b3c1f1de52994cfbe4.html","3af09b4ea66071ef4e9fb0385ee0d399"],["static/fonts/roboto/Roboto-Bold.ttf","d329cc8b34667f114a95422aaad1b063"],["static/fonts/roboto/Roboto-Light.ttf","7b5fb88f12bec8143f00e21bc3222124"],["static/fonts/roboto/Roboto-Medium.ttf","fe13e4170719c2fc586501e777bde143"],["static/fonts/roboto/Roboto-Regular.ttf","ac3f799d5bbaf5196fab15ab8de8431c"],["static/icons/favicon-192x192.png","419903b8422586a7e28021bbe9011175"],["static/icons/favicon.ico","04235bda7843ec2fceb1cbe2bc696cf4"],["static/images/card_media_player_bg.png","a34281d1c1835d338a642e90930e61aa"],["static/webcomponents-lite.min.js","b0f32ad3c7749c40d486603f31c9d8b1"]],cacheName="sw-precache-v2--"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var a=new URL(e);return"/"===a.pathname.slice(-1)&&(a.pathname+=t),a.toString()},createCacheKey=function(e,t,a,n){var c=new URL(e);return n&&c.toString().match(n)||(c.search+=(c.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(a)),c.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var a=new URL(t).pathname;return e.some(function(e){return a.match(e)})},stripIgnoredUrlParameters=function(e,t){var a=new URL(e);return a.search=a.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),a.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],a=e[1],n=new URL(t,self.location),c=createCacheKey(n,hashParamName,a,!1);return[n.toString(),c]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(a){if(!t.has(a))return e.add(new Request(a,{credentials:"same-origin"}))}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(a){return Promise.all(a.map(function(a){if(!t.has(a.url))return e.delete(a)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,a=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);t=urlsToCacheKeys.has(a);var n="index.html";!t&&n&&(a=addDirectoryIndex(a,n),t=urlsToCacheKeys.has(a));var c="/";!t&&c&&"navigate"===e.request.mode&&isPathWhitelisted(["^((?!(static|api|local|service_worker.js|manifest.json)).)*$"],e.request.url)&&(a=new URL(c,self.location).toString(),t=urlsToCacheKeys.has(a)),t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(a))}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}),self.addEventListener("push",function(e){var t;e.data&&(t=e.data.json(),e.waitUntil(self.registration.showNotification(t.title,t).then(function(e){firePushCallback({type:"received",tag:t.tag,data:t.data},t.data.jwt)})))}),self.addEventListener("notificationclick",function(e){var t;notificationEventCallback("clicked",e),e.notification.close(),e.notification.data&&e.notification.data.url&&(t=e.notification.data.url,t&&e.waitUntil(clients.matchAll({type:"window"}).then(function(e){var a,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 E0Q4Em00000 From 73d93e526e6df66fcd52a0d1f7be06026c8d582c Mon Sep 17 00:00:00 2001 From: hexa- Date: Mon, 3 Oct 2016 01:51:15 +0200 Subject: [PATCH 053/112] Add anel_pwrctrl platform to control switches on ANEL PwrCtrl devices (#3644) * Add pwrctrl platform to control switches on ANEL PwrCtrl devices * make requested changes --- .coveragerc | 1 + .../components/switch/anel_pwrctrl.py | 125 ++++++++++++++++++ requirements_all.txt | 3 + 3 files changed, 129 insertions(+) create mode 100644 homeassistant/components/switch/anel_pwrctrl.py diff --git a/.coveragerc b/.coveragerc index ee2551e4a202d..5cedb8c5c485c 100644 --- a/.coveragerc +++ b/.coveragerc @@ -273,6 +273,7 @@ omit = homeassistant/components/sensor/yahoo_finance.py homeassistant/components/sensor/yweather.py homeassistant/components/switch/acer_projector.py + homeassistant/components/switch/anel_pwrctrl.py homeassistant/components/switch/arest.py homeassistant/components/switch/dlink.py homeassistant/components/switch/edimax.py diff --git a/homeassistant/components/switch/anel_pwrctrl.py b/homeassistant/components/switch/anel_pwrctrl.py new file mode 100644 index 0000000000000..61e0985b647d4 --- /dev/null +++ b/homeassistant/components/switch/anel_pwrctrl.py @@ -0,0 +1,125 @@ +""" +Support for ANEL PwrCtrl switches. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/switch.pwrctrl/ +""" +import logging +import socket +from datetime import timedelta + +import voluptuous as vol + +import homeassistant.helpers.config_validation as cv +from homeassistant.components.switch import (SwitchDevice, PLATFORM_SCHEMA) +from homeassistant.const import (CONF_HOST, CONF_PASSWORD, CONF_USERNAME) +from homeassistant.util import Throttle + + +REQUIREMENTS = ['https://github.com/mweinelt/anel-pwrctrl/archive/' + 'master.zip#anel_pwrctrl==0.0.1'] + +CONF_PORT_RECV = "port_recv" +CONF_PORT_SEND = "port_send" + +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=5) + +_LOGGER = logging.getLogger(__name__) + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_PORT_RECV): cv.port, + vol.Required(CONF_PORT_SEND): cv.port, + vol.Required(CONF_USERNAME): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + vol.Optional(CONF_HOST): cv.string, +}) + + +# pylint: disable=unused-variable +def setup_platform(hass, config, add_devices, discovery_info=None): + """Setup PwrCtrl devices/switches.""" + host = config.get(CONF_HOST, None) + username = config.get(CONF_USERNAME) + password = config.get(CONF_PASSWORD) + port_recv = config.get(CONF_PORT_RECV) + port_send = config.get(CONF_PORT_SEND) + + from anel_pwrctrl import DeviceMaster + + try: + master = DeviceMaster(username=username, + password=password, + read_port=port_send, + write_port=port_recv) + master.query(ip_addr=host) + except socket.error as ex: + _LOGGER.error('Unable to discover PwrCtrl device: %s', str(ex)) + return False + + devices = [] + for device in master.devices.values(): + parent_device = PwrCtrlDevice(device) + devices.extend( + PwrCtrlSwitch(switch, parent_device) + for switch in device.switches.values() + ) + + add_devices(devices) + + +class PwrCtrlSwitch(SwitchDevice): + """Representation of a PwrCtrl switch.""" + + def __init__(self, port, parent_device): + """Initialize the PwrCtrl switch.""" + self._port = port + self._parent_device = parent_device + + @property + def should_poll(self): + """Polling is needed.""" + return True + + @property + def unique_id(self): + """Return the unique ID of the device.""" + return "{device}-{switch_idx}".format( + device=self._port.device.host, + switch_idx=self._port.get_index() + ) + + @property + def name(self): + """Return the name of the device.""" + return self._port.label + + @property + def is_on(self): + """Return true if the device is on.""" + return self._port.get_state() + + def update(self): + """Trigger update for all switches on the parent device.""" + self._parent_device.update() + + def turn_on(self): + """Turn the switch on.""" + self._port.on() + + def turn_off(self): + """Turn the switch off.""" + self._port.off() + + +# pylint: disable=too-few-public-methods +class PwrCtrlDevice(object): + """Device representation for per device throttling.""" + + def __init__(self, device): + """Initialize the PwrCtrl device.""" + self._device = device + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + def update(self): + """Update the device and all its switches.""" + self._device.update() diff --git a/requirements_all.txt b/requirements_all.txt index df94534bab1ad..a884b7226c75d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -185,6 +185,9 @@ https://github.com/kellerza/pyqwikswitch/archive/v0.4.zip#pyqwikswitch==0.4 # homeassistant.components.media_player.russound_rnet https://github.com/laf/russound/archive/0.1.6.zip#russound==0.1.6 +# homeassistant.components.switch.anel_pwrctrl +https://github.com/mweinelt/anel-pwrctrl/archive/master.zip#anel_pwrctrl==0.0.1 + # homeassistant.components.ecobee https://github.com/nkgilley/python-ecobee-api/archive/4856a704670c53afe1882178a89c209b5f98533d.zip#python-ecobee==0.0.6 From b586e80977183c8b1812f799b4172994e910377d Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Sun, 2 Oct 2016 18:04:00 -0700 Subject: [PATCH 054/112] Squashed commit of the following: commit 220331260e9748ac8e17b3ce776330c1dfb7725b Merge: 73d93e5 c891820 Author: Robbie Trencheny Date: Sun Oct 2 17:57:24 2016 -0700 Merge branch 'color_temp_for_mqtt_light' of https://github.com/alterscape/home-assistant into alterscape-color_temp_for_mqtt_light commit c89182008a7946ce405e4477e5d0f16cce6a11d1 Author: Ryan Spicer Date: Sun Sep 18 23:06:34 2016 -0700 fix missing docstring. commit e61dda4dd349a6f357185854ead952167222ff1e Author: Ryan Spicer Date: Sun Sep 18 22:43:04 2016 -0700 fix pep8 errors and typos in tests. commit 559d1752d223b9d7f4608a57c454b4e6c0d7c447 Author: Ryan Spicer Date: Sun Sep 18 21:41:07 2016 -0700 add tests for mqtt color temp support commit 702defb932fc61d2160b24282b5f95cfd2101a8f Author: Ryan Spicer Date: Sun Sep 18 20:55:07 2016 -0700 Add color temp support to mqtt lights. --- homeassistant/components/light/mqtt.py | 54 +++++++++++++++++++++-- homeassistant/const.py | 1 + tests/components/light/test_mqtt.py | 61 +++++++++++++++++++++++++- 3 files changed, 111 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/light/mqtt.py b/homeassistant/components/light/mqtt.py index a28b6285bdd14..e0464533a1b2f 100644 --- a/homeassistant/components/light/mqtt.py +++ b/homeassistant/components/light/mqtt.py @@ -10,11 +10,12 @@ import homeassistant.components.mqtt as mqtt from homeassistant.components.light import ( - ATTR_BRIGHTNESS, ATTR_RGB_COLOR, SUPPORT_BRIGHTNESS, SUPPORT_RGB_COLOR, - Light) + ATTR_BRIGHTNESS, ATTR_RGB_COLOR, ATTR_COLOR_TEMP, SUPPORT_BRIGHTNESS, + SUPPORT_RGB_COLOR, SUPPORT_COLOR_TEMP, Light) from homeassistant.const import ( CONF_NAME, CONF_OPTIMISTIC, CONF_VALUE_TEMPLATE, CONF_PAYLOAD_OFF, - CONF_PAYLOAD_ON, CONF_STATE, CONF_BRIGHTNESS, CONF_RGB) + CONF_PAYLOAD_ON, CONF_STATE, CONF_BRIGHTNESS, CONF_RGB, + CONF_COLOR_TEMP) from homeassistant.components.mqtt import ( CONF_STATE_TOPIC, CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN) import homeassistant.helpers.config_validation as cv @@ -31,6 +32,9 @@ CONF_RGB_COMMAND_TOPIC = 'rgb_command_topic' CONF_RGB_VALUE_TEMPLATE = 'rgb_value_template' CONF_BRIGHTNESS_SCALE = 'brightness_scale' +CONF_COLOR_TEMP_STATE_TOPIC = 'color_temp_state_topic' +CONF_COLOR_TEMP_COMMAND_TOPIC = 'color_temp_command_topic' +CONF_COLOR_TEMP_VALUE_TEMPLATE = 'color_temp_value_template' DEFAULT_NAME = 'MQTT Light' DEFAULT_PAYLOAD_ON = 'ON' @@ -44,6 +48,9 @@ vol.Optional(CONF_BRIGHTNESS_STATE_TOPIC): mqtt.valid_subscribe_topic, vol.Optional(CONF_BRIGHTNESS_COMMAND_TOPIC): mqtt.valid_publish_topic, vol.Optional(CONF_BRIGHTNESS_VALUE_TEMPLATE): cv.template, + vol.Optional(CONF_COLOR_TEMP_STATE_TOPIC): mqtt.valid_subscribe_topic, + vol.Optional(CONF_COLOR_TEMP_COMMAND_TOPIC): mqtt.valid_publish_topic, + vol.Optional(CONF_COLOR_TEMP_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_RGB_STATE_TOPIC): mqtt.valid_subscribe_topic, vol.Optional(CONF_RGB_COMMAND_TOPIC): mqtt.valid_publish_topic, vol.Optional(CONF_RGB_VALUE_TEMPLATE): cv.template, @@ -70,12 +77,15 @@ def setup_platform(hass, config, add_devices, discovery_info=None): CONF_BRIGHTNESS_COMMAND_TOPIC, CONF_RGB_STATE_TOPIC, CONF_RGB_COMMAND_TOPIC, + CONF_COLOR_TEMP_STATE_TOPIC, + CONF_COLOR_TEMP_COMMAND_TOPIC ) }, { CONF_STATE: config.get(CONF_STATE_VALUE_TEMPLATE), CONF_BRIGHTNESS: config.get(CONF_BRIGHTNESS_VALUE_TEMPLATE), - CONF_RGB: config.get(CONF_RGB_VALUE_TEMPLATE) + CONF_RGB: config.get(CONF_RGB_VALUE_TEMPLATE), + CONF_COLOR_TEMP: config.get(CONF_COLOR_TEMP_VALUE_TEMPLATE) }, config.get(CONF_QOS), config.get(CONF_RETAIN), @@ -92,6 +102,7 @@ class MqttLight(Light): """MQTT light.""" # pylint: disable=too-many-arguments,too-many-instance-attributes + # pylint: disable=too-many-locals,too-many-branches def __init__(self, hass, name, topic, templates, qos, retain, payload, optimistic, brightness_scale): """Initialize MQTT light.""" @@ -106,6 +117,8 @@ def __init__(self, hass, name, topic, templates, qos, retain, payload, optimistic or topic[CONF_RGB_STATE_TOPIC] is None self._optimistic_brightness = ( optimistic or topic[CONF_BRIGHTNESS_STATE_TOPIC] is None) + self._optimistic_color_temp = ( + optimistic or topic[CONF_COLOR_TEMP_STATE_TOPIC] is None) self._brightness_scale = brightness_scale self._state = False self._supported_features = 0 @@ -114,6 +127,9 @@ def __init__(self, hass, name, topic, templates, qos, retain, payload, self._supported_features |= ( topic[CONF_BRIGHTNESS_STATE_TOPIC] is not None and SUPPORT_BRIGHTNESS) + self._supported_features |= ( + topic[CONF_COLOR_TEMP_STATE_TOPIC] is not None and + SUPPORT_COLOR_TEMP) for key, tpl in list(templates.items()): if tpl is None: @@ -168,6 +184,21 @@ def rgb_received(topic, payload, qos): else: self._rgb = None + def color_temp_received(topic, payload, qos): + """A new MQTT message for color temp has been received.""" + self._color_temp = int(templates[CONF_COLOR_TEMP](payload)) + self.update_ha_state() + + if self._topic[CONF_COLOR_TEMP_STATE_TOPIC] is not None: + mqtt.subscribe( + self._hass, self._topic[CONF_COLOR_TEMP_STATE_TOPIC], + color_temp_received, self._qos) + self._color_temp = 150 + if self._topic[CONF_COLOR_TEMP_COMMAND_TOPIC] is not None: + self._color_temp = 150 + else: + self._color_temp = None + @property def brightness(self): """Return the brightness of this light between 0..255.""" @@ -178,6 +209,11 @@ def rgb_color(self): """Return the RGB color value.""" return self._rgb + @property + def color_temp(self): + """Return the color temperature in mired.""" + return self._color_temp + @property def should_poll(self): """No polling needed for a MQTT light.""" @@ -230,6 +266,16 @@ def turn_on(self, **kwargs): self._brightness = kwargs[ATTR_BRIGHTNESS] should_update = True + if ATTR_COLOR_TEMP in kwargs and \ + self._topic[CONF_COLOR_TEMP_COMMAND_TOPIC] is not None: + color_temp = int(kwargs[ATTR_COLOR_TEMP]) + mqtt.publish( + self._hass, self._topic[CONF_COLOR_TEMP_COMMAND_TOPIC], + color_temp, self._qos, self._retain) + if self._optimistic_color_temp: + self._color_temp = kwargs[ATTR_COLOR_TEMP] + should_update = True + mqtt.publish(self._hass, self._topic[CONF_COMMAND_TOPIC], self._payload['on'], self._qos, self._retain) diff --git a/homeassistant/const.py b/homeassistant/const.py index c50a9b7dc4fff..b8cd3a8335330 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -63,6 +63,7 @@ CONF_BLACKLIST = 'blacklist' CONF_BRIGHTNESS = 'brightness' CONF_CODE = 'code' +CONF_COLOR_TEMP = 'color_temp' CONF_COMMAND = 'command' CONF_COMMAND_CLOSE = 'command_close' CONF_COMMAND_OFF = 'command_off' diff --git a/tests/components/light/test_mqtt.py b/tests/components/light/test_mqtt.py index c6fc07fa43850..375a4a459051d 100644 --- a/tests/components/light/test_mqtt.py +++ b/tests/components/light/test_mqtt.py @@ -55,6 +55,23 @@ qos: 0 payload_on: "on" payload_off: "off" + +config with brightness and color temp + +light: + platform: mqtt + name: "Office Light Color Temp" + state_topic: "office/rgb1/light/status" + command_topic: "office/rgb1/light/switch" + brightness_state_topic: "office/rgb1/brightness/status" + brightness_command_topic: "office/rgb1/brightness/set" + brightness_scale: 99 + color_temp_state_topic: "office/rgb1/color_temp/status" + color_temp_command_topic: "office/rgb1/color_temp/set" + qos: 0 + payload_on: "on" + payload_off: "off" + """ import unittest @@ -88,7 +105,7 @@ def test_fail_setup_if_no_command_topic(self): }) self.assertIsNone(self.hass.states.get('light.test')) - def test_no_color_or_brightness_if_no_topics(self): + def test_no_color_or_brightness_or_color_temp_if_no_topics(self): """Test if there is no color and brightness if no topic.""" self.hass.config.components = ['mqtt'] assert _setup_component(self.hass, light.DOMAIN, { @@ -104,6 +121,7 @@ def test_no_color_or_brightness_if_no_topics(self): self.assertEqual(STATE_OFF, state.state) self.assertIsNone(state.attributes.get('rgb_color')) self.assertIsNone(state.attributes.get('brightness')) + self.assertIsNone(state.attributes.get('color_temp')) fire_mqtt_message(self.hass, 'test_light_rgb/status', 'ON') self.hass.block_till_done() @@ -112,6 +130,7 @@ def test_no_color_or_brightness_if_no_topics(self): self.assertEqual(STATE_ON, state.state) self.assertIsNone(state.attributes.get('rgb_color')) self.assertIsNone(state.attributes.get('brightness')) + self.assertIsNone(state.attributes.get('color_temp')) def test_controlling_state_via_topic(self): """Test the controlling of the state via topic.""" @@ -126,6 +145,8 @@ def test_controlling_state_via_topic(self): 'brightness_command_topic': 'test_light_rgb/brightness/set', 'rgb_state_topic': 'test_light_rgb/rgb/status', 'rgb_command_topic': 'test_light_rgb/rgb/set', + 'color_temp_state_topic': 'test_light_rgb/color_temp/status', + 'color_temp_command_topic': 'test_light_rgb/color_temp/set', 'qos': '0', 'payload_on': 1, 'payload_off': 0 @@ -136,6 +157,7 @@ def test_controlling_state_via_topic(self): self.assertEqual(STATE_OFF, state.state) self.assertIsNone(state.attributes.get('rgb_color')) self.assertIsNone(state.attributes.get('brightness')) + self.assertIsNone(state.attributes.get('color_temp')) self.assertIsNone(state.attributes.get(ATTR_ASSUMED_STATE)) fire_mqtt_message(self.hass, 'test_light_rgb/status', '1') @@ -145,6 +167,7 @@ def test_controlling_state_via_topic(self): self.assertEqual(STATE_ON, state.state) self.assertEqual([255, 255, 255], state.attributes.get('rgb_color')) self.assertEqual(255, state.attributes.get('brightness')) + self.assertEqual(150, state.attributes.get('color_temp')) fire_mqtt_message(self.hass, 'test_light_rgb/status', '0') self.hass.block_till_done() @@ -163,6 +186,12 @@ def test_controlling_state_via_topic(self): self.assertEqual(100, light_state.attributes['brightness']) + fire_mqtt_message(self.hass, 'test_light_rgb/color_temp/status', '300') + self.hass.block_till_done() + light_state = self.hass.states.get('light.test') + self.hass.block_till_done() + self.assertEqual(300, light_state.attributes['color_temp']) + fire_mqtt_message(self.hass, 'test_light_rgb/status', '1') self.hass.block_till_done() @@ -231,9 +260,11 @@ def test_controlling_state_via_topic_with_templates(self): 'state_topic': 'test_light_rgb/status', 'command_topic': 'test_light_rgb/set', 'brightness_state_topic': 'test_light_rgb/brightness/status', + 'color_temp_state_topic': 'test_light_rgb/color_temp/status', 'rgb_state_topic': 'test_light_rgb/rgb/status', 'state_value_template': '{{ value_json.hello }}', 'brightness_value_template': '{{ value_json.hello }}', + 'color_temp_value_template': '{{ value_json.hello }}', 'rgb_value_template': '{{ value_json.hello | join(",") }}', } }) @@ -249,12 +280,15 @@ def test_controlling_state_via_topic_with_templates(self): '{"hello": "ON"}') fire_mqtt_message(self.hass, 'test_light_rgb/brightness/status', '{"hello": "50"}') + fire_mqtt_message(self.hass, 'test_light_rgb/color_temp/status', + '{"hello": "300"}') self.hass.block_till_done() state = self.hass.states.get('light.test') self.assertEqual(STATE_ON, state.state) self.assertEqual(50, state.attributes.get('brightness')) self.assertEqual([1, 2, 3], state.attributes.get('rgb_color')) + self.assertEqual(300, state.attributes.get('color_temp')) def test_sending_mqtt_commands_and_optimistic(self): """Test the sending of command in optimistic mode.""" @@ -266,6 +300,7 @@ def test_sending_mqtt_commands_and_optimistic(self): 'command_topic': 'test_light_rgb/set', 'brightness_command_topic': 'test_light_rgb/brightness/set', 'rgb_command_topic': 'test_light_rgb/rgb/set', + 'color_temp_command_topic': 'test_light_rgb/color_temp/set', 'qos': 2, 'payload_on': 'on', 'payload_off': 'off' @@ -338,3 +373,27 @@ def test_show_brightness_if_only_command_topic(self): state = self.hass.states.get('light.test') self.assertEqual(STATE_ON, state.state) self.assertEqual(255, state.attributes.get('brightness')) + + def test_show_color_temp_only_if_command_topic(self): + """Test the color temp only if a command topic is present.""" + self.hass.config.components = ['mqtt'] + assert _setup_component(self.hass, light.DOMAIN, { + light.DOMAIN: { + 'platform': 'mqtt', + 'name': 'test', + 'color_temp_command_topic': 'test_light_rgb/brightness/set', + 'command_topic': 'test_light_rgb/set', + 'state_topic': 'test_light_rgb/status' + } + }) + + state = self.hass.states.get('light.test') + self.assertEqual(STATE_OFF, state.state) + self.assertIsNone(state.attributes.get('color_temp')) + + fire_mqtt_message(self.hass, 'test_light_rgb/status', 'ON') + self.hass.block_till_done() + + state = self.hass.states.get('light.test') + self.assertEqual(STATE_ON, state.state) + self.assertEqual(150, state.attributes.get('color_temp')) From 0219df17f5f4f27fdc519e62f3645e2551153c3c Mon Sep 17 00:00:00 2001 From: Justin Weberg Date: Mon, 3 Oct 2016 02:04:43 -0500 Subject: [PATCH 055/112] Expose Configuration path to frontend (#3660) * Expose config path to frontend * Fix typo * Add deleted code. --- homeassistant/core.py | 1 + tests/test_core.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/homeassistant/core.py b/homeassistant/core.py index 1ef0adc596140..83056d6d7f260 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -1088,6 +1088,7 @@ def as_dict(self): 'location_name': self.location_name, 'time_zone': time_zone.zone, 'components': self.components, + 'config_dir': self.config_dir, 'version': __version__ } diff --git a/tests/test_core.py b/tests/test_core.py index 9fa742985c4ab..80a8c6d4c5f37 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -448,6 +448,7 @@ def test_path_with_dir_and_file(self): def test_as_dict(self): """Test as dict.""" + self.config.config_dir = '/tmp/ha-config' expected = { 'latitude': None, 'longitude': None, @@ -455,6 +456,7 @@ def test_as_dict(self): 'location_name': None, 'time_zone': 'UTC', 'components': [], + 'config_dir': '/tmp/ha-config', 'version': __version__, } From 41aff96375655f57333ea80ee3a1af7fc5dbe172 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Mon, 3 Oct 2016 10:46:31 +0200 Subject: [PATCH 056/112] Bugfix temp convert on none temp attribute / unittest for that (#3654) --- homeassistant/components/climate/__init__.py | 19 ++++++++++++++----- tests/components/climate/test_demo.py | 12 +++++++++++- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/climate/__init__.py b/homeassistant/components/climate/__init__.py index f670cbc45e144..93330603828f4 100644 --- a/homeassistant/components/climate/__init__.py +++ b/homeassistant/components/climate/__init__.py @@ -58,6 +58,12 @@ ATTR_SWING_MODE = "swing_mode" ATTR_SWING_LIST = "swing_list" +CONVERTIBLE_ATTRIBUTE = [ + ATTR_TEMPERATURE, + ATTR_TARGET_TEMP_LOW, + ATTR_TARGET_TEMP_HIGH, +] + _LOGGER = logging.getLogger(__name__) SET_AWAY_MODE_SCHEMA = vol.Schema({ @@ -239,11 +245,14 @@ def temperature_set_service(service): for climate in target_climate: kwargs = {} for value, temp in service.data.items(): - kwargs[value] = convert_temperature( - temp, - hass.config.units.temperature_unit, - climate.unit_of_measurement - ) + if value in CONVERTIBLE_ATTRIBUTE: + kwargs[value] = convert_temperature( + temp, + hass.config.units.temperature_unit, + climate.unit_of_measurement + ) + else: + kwargs[value] = temp climate.set_temperature(**kwargs) if climate.should_poll: diff --git a/tests/components/climate/test_demo.py b/tests/components/climate/test_demo.py index f44cb6aabf42c..aa94bdf63c92f 100644 --- a/tests/components/climate/test_demo.py +++ b/tests/components/climate/test_demo.py @@ -2,7 +2,7 @@ import unittest from homeassistant.util.unit_system import ( - METRIC_SYSTEM, + METRIC_SYSTEM ) from homeassistant.bootstrap import setup_component from homeassistant.components import climate @@ -12,6 +12,7 @@ ENTITY_CLIMATE = 'climate.hvac' ENTITY_ECOBEE = 'climate.ecobee' +ENTITY_HEATPUMP = 'climate.heatpump' class TestDemoClimate(unittest.TestCase): @@ -68,6 +69,15 @@ def test_set_only_target_temp(self): state = self.hass.states.get(ENTITY_CLIMATE) self.assertEqual(30.0, state.attributes.get('temperature')) + def test_set_only_target_temp_with_convert(self): + """Test the setting of the target temperature.""" + state = self.hass.states.get(ENTITY_HEATPUMP) + self.assertEqual(20, state.attributes.get('temperature')) + climate.set_temperature(self.hass, 21, ENTITY_HEATPUMP) + self.hass.block_till_done() + state = self.hass.states.get(ENTITY_HEATPUMP) + self.assertEqual(21.0, state.attributes.get('temperature')) + def test_set_target_temp_range(self): """Test the setting of the target temperature with range.""" state = self.hass.states.get(ENTITY_ECOBEE) From 4a5a1e1e96c86a8da6a2b24339c2e06256b047a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=B8yer=20Iversen?= Date: Mon, 3 Oct 2016 22:03:16 +0200 Subject: [PATCH 057/112] Ensure unique entity id for input_boolean --- homeassistant/components/input_boolean.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/input_boolean.py b/homeassistant/components/input_boolean.py index 0477bb1dbfb55..9b764868b3dbf 100644 --- a/homeassistant/components/input_boolean.py +++ b/homeassistant/components/input_boolean.py @@ -12,7 +12,7 @@ ATTR_ENTITY_ID, CONF_ICON, CONF_NAME, SERVICE_TURN_OFF, SERVICE_TURN_ON, SERVICE_TOGGLE, STATE_ON) import homeassistant.helpers.config_validation as cv -from homeassistant.helpers.entity import ToggleEntity +from homeassistant.helpers.entity import ToggleEntity, generate_entity_id from homeassistant.helpers.entity_component import EntityComponent DOMAIN = 'input_boolean' @@ -103,7 +103,7 @@ class InputBoolean(ToggleEntity): def __init__(self, object_id, name, state, icon): """Initialize a boolean input.""" - self.entity_id = ENTITY_ID_FORMAT.format(object_id) + self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, object_id) self._name = name self._state = state self._icon = icon From c3ea04f2dd776e056340b71ffe092d62d0fae633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=B8yer=20Iversen?= Date: Mon, 3 Oct 2016 22:05:06 +0200 Subject: [PATCH 058/112] revert update of input_boolean --- homeassistant/components/input_boolean.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/input_boolean.py b/homeassistant/components/input_boolean.py index 9b764868b3dbf..0477bb1dbfb55 100644 --- a/homeassistant/components/input_boolean.py +++ b/homeassistant/components/input_boolean.py @@ -12,7 +12,7 @@ ATTR_ENTITY_ID, CONF_ICON, CONF_NAME, SERVICE_TURN_OFF, SERVICE_TURN_ON, SERVICE_TOGGLE, STATE_ON) import homeassistant.helpers.config_validation as cv -from homeassistant.helpers.entity import ToggleEntity, generate_entity_id +from homeassistant.helpers.entity import ToggleEntity from homeassistant.helpers.entity_component import EntityComponent DOMAIN = 'input_boolean' @@ -103,7 +103,7 @@ class InputBoolean(ToggleEntity): def __init__(self, object_id, name, state, icon): """Initialize a boolean input.""" - self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, object_id) + self.entity_id = ENTITY_ID_FORMAT.format(object_id) self._name = name self._state = state self._icon = icon From 625319846c77b37a9f2a5ffcf8d3be311cd534fe Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Mon, 3 Oct 2016 23:21:53 +0200 Subject: [PATCH 059/112] Big Homematic update (#3677) * Update homeassistant with new pyhomematic layout * fix linter --- .../components/binary_sensor/homematic.py | 1 + homeassistant/components/homematic.py | 174 ++++++++---------- homeassistant/components/sensor/homematic.py | 4 +- requirements_all.txt | 2 +- 4 files changed, 82 insertions(+), 99 deletions(-) diff --git a/homeassistant/components/binary_sensor/homematic.py b/homeassistant/components/binary_sensor/homematic.py index 073f5d7eb6d79..35550d15bc8ad 100644 --- a/homeassistant/components/binary_sensor/homematic.py +++ b/homeassistant/components/binary_sensor/homematic.py @@ -16,6 +16,7 @@ SENSOR_TYPES_CLASS = { "Remote": None, "ShutterContact": "opening", + "IPShutterContact": "opening", "Smoke": "smoke", "SmokeV2": "smoke", "Motion": "motion", diff --git a/homeassistant/components/homematic.py b/homeassistant/components/homematic.py index 466a81563e8bc..b09f53ae748ad 100644 --- a/homeassistant/components/homematic.py +++ b/homeassistant/components/homematic.py @@ -23,7 +23,7 @@ from homeassistant.util import Throttle DOMAIN = 'homematic' -REQUIREMENTS = ["pyhomematic==0.1.14"] +REQUIREMENTS = ["pyhomematic==0.1.16"] HOMEMATIC = None HOMEMATIC_LINK_DELAY = 0.5 @@ -52,17 +52,22 @@ SERVICE_SET_VALUE = 'set_value' HM_DEVICE_TYPES = { - DISCOVER_SWITCHES: ['Switch', 'SwitchPowermeter'], - DISCOVER_LIGHTS: ['Dimmer'], - DISCOVER_SENSORS: ['SwitchPowermeter', 'Motion', 'MotionV2', - 'RemoteMotion', 'ThermostatWall', 'AreaThermostat', - 'RotaryHandleSensor', 'WaterSensor', 'PowermeterGas', - 'LuxSensor', 'WeatherSensor', 'WeatherStation'], - DISCOVER_CLIMATE: ['Thermostat', 'ThermostatWall', 'MAXThermostat'], - DISCOVER_BINARY_SENSORS: ['ShutterContact', 'Smoke', 'SmokeV2', 'Motion', - 'MotionV2', 'RemoteMotion', 'WeatherSensor', - 'TiltSensor'], - DISCOVER_COVER: ['Blind'] + DISCOVER_SWITCHES: [ + 'Switch', 'SwitchPowermeter', 'IOSwitch', 'IPSwitch', + 'IPSwitchPowermeter', 'KeyMatic'], + DISCOVER_LIGHTS: ['Dimmer', 'KeyDimmer'], + DISCOVER_SENSORS: [ + 'SwitchPowermeter', 'Motion', 'MotionV2', 'RemoteMotion', + 'ThermostatWall', 'AreaThermostat', 'RotaryHandleSensor', + 'WaterSensor', 'PowermeterGas', 'LuxSensor', 'WeatherSensor', + 'WeatherStation', 'ThermostatWall2', 'TemperatureDiffSensor', + 'TemperatureSensor', 'CO2Sensor'], + DISCOVER_CLIMATE: [ + 'Thermostat', 'ThermostatWall', 'MAXThermostat', 'ThermostatWall2'], + DISCOVER_BINARY_SENSORS: [ + 'ShutterContact', 'Smoke', 'SmokeV2', 'Motion', 'MotionV2', + 'RemoteMotion', 'WeatherSensor', 'TiltSensor', 'IPShutterContact'], + DISCOVER_COVER: ['Blind', 'KeyBlind'] } HM_IGNORE_DISCOVERY_NODE = [ @@ -87,11 +92,12 @@ 'PRESS_SHORT', 'PRESS_LONG', 'PRESS_CONT', - 'PRESS_LONG_RELEASE' + 'PRESS_LONG_RELEASE', + 'PRESS', ] HM_IMPULSE_EVENTS = [ - 'SEQUENCE_OK' + 'SEQUENCE_OK', ] _LOGGER = logging.getLogger(__name__) @@ -111,6 +117,15 @@ CONF_DELAY = 'delay' CONF_VARIABLES = 'variables' +DEFAULT_LOCAL_IP = "0.0.0.0" +DEFAULT_LOCAL_PORT = 0 +DEFAULT_RESOLVENAMES = False +DEFAULT_REMOTE_PORT = 2001 +DEFAULT_USERNAME = "Admin" +DEFAULT_PASSWORD = "" +DEFAULT_VARIABLES = False +DEFAULT_DELAY = 0.5 + DEVICE_SCHEMA = vol.Schema({ vol.Required(CONF_PLATFORM): "homematic", @@ -122,16 +137,16 @@ CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ - vol.Required(CONF_LOCAL_IP): cv.string, - vol.Optional(CONF_LOCAL_PORT, default=8943): cv.port, vol.Required(CONF_REMOTE_IP): cv.string, - vol.Optional(CONF_REMOTE_PORT, default=2001): cv.port, - vol.Optional(CONF_RESOLVENAMES, default=False): + vol.Optional(CONF_LOCAL_IP, default=DEFAULT_LOCAL_IP): cv.string, + vol.Optional(CONF_LOCAL_PORT, default=DEFAULT_LOCAL_PORT): cv.port, + vol.Optional(CONF_REMOTE_PORT, default=DEFAULT_REMOTE_PORT): cv.port, + vol.Optional(CONF_RESOLVENAMES, default=DEFAULT_RESOLVENAMES): vol.In(CONF_RESOLVENAMES_OPTIONS), - vol.Optional(CONF_USERNAME, default="Admin"): cv.string, - vol.Optional(CONF_PASSWORD, default=""): cv.string, - vol.Optional(CONF_DELAY, default=0.5): vol.Coerce(float), - vol.Optional(CONF_VARIABLES, default=False): cv.boolean, + vol.Optional(CONF_USERNAME, default=DEFAULT_USERNAME): cv.string, + vol.Optional(CONF_PASSWORD, default=DEFAULT_PASSWORD): cv.string, + vol.Optional(CONF_DELAY, default=DEFAULT_DELAY): vol.Coerce(float), + vol.Optional(CONF_VARIABLES, default=DEFAULT_VARIABLES): cv.boolean, }), }, extra=vol.ALLOW_EXTRA) @@ -323,83 +338,45 @@ def _get_devices(device_type, keys): metadata.update(device.SENSORNODE) elif device_type == DISCOVER_BINARY_SENSORS: metadata.update(device.BINARYNODE) + else: + metadata.update({None: device.ELEMENT}) - params = _create_params_list(device, metadata, device_type) - if params: + if metadata: # Generate options for 1...n elements with 1...n params - for channel in range(1, device.ELEMENT + 1): - _LOGGER.debug("Handling %s:%i", key, channel) - if channel in params: - for param in params[channel]: - name = _create_ha_name( - name=device.NAME, - channel=channel, - param=param - ) - device_dict = { - CONF_PLATFORM: "homematic", - ATTR_ADDRESS: key, - ATTR_NAME: name, - ATTR_CHANNEL: channel - } - if param is not None: - device_dict.update({ATTR_PARAM: param}) - - # Add new device - try: - DEVICE_SCHEMA(device_dict) - device_arr.append(device_dict) - except vol.MultipleInvalid as err: - _LOGGER.error("Invalid device config: %s", - str(err)) - else: - _LOGGER.debug("Channel %i not in params", channel) + for param, channels in metadata.items(): + if param in HM_IGNORE_DISCOVERY_NODE: + continue + + # add devices + _LOGGER.debug("Handling %s: %s", param, channels) + for channel in channels: + name = _create_ha_name( + name=device.NAME, + channel=channel, + param=param + ) + device_dict = { + CONF_PLATFORM: "homematic", + ATTR_ADDRESS: key, + ATTR_NAME: name, + ATTR_CHANNEL: channel + } + if param is not None: + device_dict[ATTR_PARAM] = param + + # Add new device + try: + DEVICE_SCHEMA(device_dict) + device_arr.append(device_dict) + except vol.MultipleInvalid as err: + _LOGGER.error("Invalid device config: %s", + str(err)) else: _LOGGER.debug("Got no params for %s", key) _LOGGER.debug("%s autodiscovery: %s", device_type, str(device_arr)) return device_arr -def _create_params_list(hmdevice, metadata, device_type): - """Create a list from HMDevice with all possible parameters in config.""" - params = {} - merge = False - - # use merge? - if device_type in (DISCOVER_SENSORS, DISCOVER_BINARY_SENSORS): - merge = True - - # Search in sensor and binary metadata per elements - for channel in range(1, hmdevice.ELEMENT + 1): - param_chan = [] - for node, meta_chan in metadata.items(): - try: - # Is this attribute ignored? - if node in HM_IGNORE_DISCOVERY_NODE: - continue - if meta_chan == 'c' or meta_chan is None: - # Only channel linked data - param_chan.append(node) - elif channel == 1: - # First channel can have other data channel - param_chan.append(node) - except (TypeError, ValueError): - _LOGGER.error("Exception generating %s (%s)", - hmdevice.ADDRESS, str(metadata)) - - # default parameter is merge is off - if len(param_chan) == 0 and not merge: - param_chan.append(None) - - # Add to channel - if len(param_chan) > 0: - params.update({channel: param_chan}) - - _LOGGER.debug("Create param list for %s with: %s", hmdevice.ADDRESS, - str(params)) - return params - - def _create_ha_name(name, channel, param): """Generate a unique object name.""" # HMDevice is a simple device @@ -484,12 +461,12 @@ def _hm_service_virtualkey(call): hmdevice = HOMEMATIC.devices.get(address) # if param exists for this device - if param not in hmdevice.ACTIONNODE: + if hmdevice is None or param not in hmdevice.ACTIONNODE: _LOGGER.error("%s not datapoint in hm device %s", param, address) return # channel exists? - if channel > hmdevice.ELEMENT: + if channel in hmdevice.ACTIONNODE[param]: _LOGGER.error("%i is not a channel in hm device %s", channel, address) return @@ -743,19 +720,22 @@ def _subscribe_homematic_events(self): self._hmdevice.ATTRIBUTENODE, self._hmdevice.WRITENODE, self._hmdevice.EVENTNODE, self._hmdevice.ACTIONNODE): - for node, channel in metadata.items(): + for node, channels in metadata.items(): # Data is needed for this instance if node in self._data: # chan is current channel - if channel == 'c' or channel is None: + if len(channels) == 1: + channel = channels[0] + else: channel = self._channel + # Prepare for subscription try: if int(channel) >= 0: channels_to_sub.update({int(channel): True}) except (ValueError, TypeError): - _LOGGER("Invalid channel in metadata from %s", - self._name) + _LOGGER.error("Invalid channel in metadata from %s", + self._name) # Set callbacks for channel in channels_to_sub: diff --git a/homeassistant/components/sensor/homematic.py b/homeassistant/components/sensor/homematic.py index 8857ee6d88993..fc907ae76b706 100644 --- a/homeassistant/components/sensor/homematic.py +++ b/homeassistant/components/sensor/homematic.py @@ -18,7 +18,8 @@ HM_STATE_HA_CAST = { "RotaryHandleSensor": {0: "closed", 1: "tilted", 2: "open"}, - "WaterSensor": {0: "dry", 1: "wet", 2: "water"} + "WaterSensor": {0: "dry", 1: "wet", 2: "water"}, + "CO2Sensor": {0: "normal", 1: "added", 2: "strong"}, } HM_UNIT_HA_CAST = { @@ -38,6 +39,7 @@ "WIND_DIRECTION_RANGE": "°", "SUNSHINEDURATION": "#", "AIR_PRESSURE": "hPa", + "FREQUENCY": "Hz", } diff --git a/requirements_all.txt b/requirements_all.txt index a884b7226c75d..b86a8a37ea8f4 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -336,7 +336,7 @@ pyenvisalink==1.7 pyfttt==0.3 # homeassistant.components.homematic -pyhomematic==0.1.14 +pyhomematic==0.1.16 # homeassistant.components.device_tracker.icloud pyicloud==0.9.1 From f2a12b7ac2c7863d1c1b5e18a9d7e98a5c245834 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Mon, 3 Oct 2016 17:36:00 -0700 Subject: [PATCH 060/112] Add @mention-bot configuration --- .mention-bot | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .mention-bot diff --git a/.mention-bot b/.mention-bot new file mode 100644 index 0000000000000..2e1f786bf038d --- /dev/null +++ b/.mention-bot @@ -0,0 +1,6 @@ +{ + "userBlacklist": [ + "balloob" + ], + "skipAlreadyMentionedPR": true +} From d58548dd1c830f0aa5b6d68c8b9e0c68be5e014e Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 3 Oct 2016 22:39:27 -0700 Subject: [PATCH 061/112] Address asyncio comments (#3663) * Template platforms: create_task instead of yield from * Automation: less yielding, more create_tasking * Helpers.script: less yielding, more create_tasking * Deflake logbook test * Deflake automation reload config test * MQTT: Use async_add_job and threaded_listener_factory * Deflake other logbook test * lint * Add test for automation trigger service * MQTT client can be called from within async --- .../components/automation/__init__.py | 74 ++++++++++++------- .../components/binary_sensor/template.py | 2 +- homeassistant/components/mqtt/__init__.py | 32 ++------ homeassistant/components/script.py | 2 +- homeassistant/components/sensor/template.py | 2 +- homeassistant/components/switch/template.py | 2 +- homeassistant/helpers/event.py | 19 ++--- homeassistant/helpers/script.py | 25 +++---- tests/components/automation/test_init.py | 31 ++++++++ tests/components/test_logbook.py | 10 +++ 10 files changed, 123 insertions(+), 76 deletions(-) diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index a677fe1da4e1b..579d4b400035c 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -154,15 +154,24 @@ def setup(hass, config): def trigger_service_handler(service_call): """Handle automation triggers.""" for entity in component.extract_from_service(service_call): - yield from entity.async_trigger( - service_call.data.get(ATTR_VARIABLES)) + hass.loop.create_task(entity.async_trigger( + service_call.data.get(ATTR_VARIABLES), True)) @asyncio.coroutine - def service_handler(service_call): - """Handle automation service calls.""" + def turn_onoff_service_handler(service_call): + """Handle automation turn on/off service calls.""" method = 'async_{}'.format(service_call.service) for entity in component.extract_from_service(service_call): - yield from getattr(entity, method)() + hass.loop.create_task(getattr(entity, method)()) + + @asyncio.coroutine + def toggle_service_handler(service_call): + """Handle automation toggle service calls.""" + for entity in component.extract_from_service(service_call): + if entity.is_on: + hass.loop.create_task(entity.async_turn_off()) + else: + hass.loop.create_task(entity.async_turn_on()) @asyncio.coroutine def reload_service_handler(service_call): @@ -171,7 +180,7 @@ def reload_service_handler(service_call): None, component.prepare_reload) if conf is None: return - yield from _async_process_config(hass, conf, component) + hass.loop.create_task(_async_process_config(hass, conf, component)) hass.services.register(DOMAIN, SERVICE_TRIGGER, trigger_service_handler, descriptions.get(SERVICE_TRIGGER), @@ -181,8 +190,12 @@ def reload_service_handler(service_call): descriptions.get(SERVICE_RELOAD), schema=RELOAD_SERVICE_SCHEMA) - for service in (SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE): - hass.services.register(DOMAIN, service, service_handler, + hass.services.register(DOMAIN, SERVICE_TOGGLE, toggle_service_handler, + descriptions.get(SERVICE_TOGGLE), + schema=SERVICE_SCHEMA) + + for service in (SERVICE_TURN_ON, SERVICE_TURN_OFF): + hass.services.register(DOMAIN, service, turn_onoff_service_handler, descriptions.get(service), schema=SERVICE_SCHEMA) @@ -236,8 +249,11 @@ def is_on(self) -> bool: @asyncio.coroutine def async_turn_on(self, **kwargs) -> None: """Turn the entity on and update the state.""" + if self._enabled: + return + yield from self.async_enable() - yield from self.async_update_ha_state() + self.hass.loop.create_task(self.async_update_ha_state()) @asyncio.coroutine def async_turn_off(self, **kwargs) -> None: @@ -248,23 +264,18 @@ def async_turn_off(self, **kwargs) -> None: self._async_detach_triggers() self._async_detach_triggers = None self._enabled = False - yield from self.async_update_ha_state() + self.hass.loop.create_task(self.async_update_ha_state()) @asyncio.coroutine - def async_toggle(self): - """Toggle the state of the entity.""" - if self._enabled: - yield from self.async_turn_off() - else: - yield from self.async_turn_on() + def async_trigger(self, variables, skip_condition=False): + """Trigger automation. - @asyncio.coroutine - def async_trigger(self, variables): - """Trigger automation.""" - if self._cond_func(variables): + This method is a coroutine. + """ + if skip_condition or self._cond_func(variables): yield from self._async_action(variables) self._last_triggered = utcnow() - yield from self.async_update_ha_state() + self.hass.loop.create_task(self.async_update_ha_state()) def remove(self): """Remove automation from HASS.""" @@ -274,7 +285,10 @@ def remove(self): @asyncio.coroutine def async_enable(self): - """Enable this automation entity.""" + """Enable this automation entity. + + This method is a coroutine. + """ if self._enabled: return @@ -285,8 +299,12 @@ def async_enable(self): @asyncio.coroutine def _async_process_config(hass, config, component): - """Process config and add automations.""" + """Process config and add automations. + + This method is a coroutine. + """ entities = [] + tasks = [] for config_key in extract_domain_configs(config, DOMAIN): conf = config[config_key] @@ -315,9 +333,10 @@ def cond_func(variables): config_block.get(CONF_TRIGGER, []), name) entity = AutomationEntity(name, async_attach_triggers, cond_func, action, hidden) - yield from entity.async_enable() + tasks.append(hass.loop.create_task(entity.async_enable())) entities.append(entity) + yield from asyncio.gather(*tasks, loop=hass.loop) yield from hass.loop.run_in_executor( None, component.add_entities, entities) @@ -333,7 +352,7 @@ def action(variables=None): """Action to be executed.""" _LOGGER.info('Executing %s', name) logbook.async_log_entry(hass, name, 'has been triggered', DOMAIN) - yield from script_obj.async_run(variables) + hass.loop.create_task(script_obj.async_run(variables)) return action @@ -359,7 +378,10 @@ def if_action(variables=None): @asyncio.coroutine def _async_process_trigger(hass, config, trigger_configs, name, action): - """Setup the triggers.""" + """Setup the triggers. + + This method is a coroutine. + """ removes = [] for conf in trigger_configs: diff --git a/homeassistant/components/binary_sensor/template.py b/homeassistant/components/binary_sensor/template.py index 85c9f0e895053..339a5cb9ba122 100644 --- a/homeassistant/components/binary_sensor/template.py +++ b/homeassistant/components/binary_sensor/template.py @@ -85,7 +85,7 @@ def __init__(self, hass, device, friendly_name, sensor_class, @asyncio.coroutine def template_bsensor_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" - yield from self.async_update_ha_state(True) + hass.loop.create_task(self.async_update_ha_state(True)) track_state_change(hass, entity_ids, template_bsensor_state_listener) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 86896e8309e34..7995d9bf39ae2 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -12,16 +12,14 @@ import voluptuous as vol -from homeassistant.core import JobPriority from homeassistant.bootstrap import prepare_setup_platform from homeassistant.config import load_yaml_config_file from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers import template -import homeassistant.helpers.config_validation as cv +from homeassistant.helpers import template, config_validation as cv +from homeassistant.helpers.event import threaded_listener_factory from homeassistant.const import ( EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, CONF_PLATFORM, CONF_SCAN_INTERVAL, CONF_VALUE_TEMPLATE) -from homeassistant.util.async import run_callback_threadsafe _LOGGER = logging.getLogger(__name__) @@ -165,18 +163,6 @@ def publish_template(hass, topic, payload_template, qos=None, retain=None): hass.services.call(DOMAIN, SERVICE_PUBLISH, data) -def subscribe(hass, topic, callback, qos=DEFAULT_QOS): - """Subscribe to an MQTT topic.""" - async_remove = run_callback_threadsafe( - hass.loop, async_subscribe, hass, topic, callback, qos).result() - - def remove_mqtt(): - """Remove MQTT subscription.""" - run_callback_threadsafe(hass.loop, async_remove).result() - - return remove_mqtt - - def async_subscribe(hass, topic, callback, qos=DEFAULT_QOS): """Subscribe to an MQTT topic.""" @asyncio.coroutine @@ -185,14 +171,8 @@ def mqtt_topic_subscriber(event): if not _match_topic(topic, event.data[ATTR_TOPIC]): return - if asyncio.iscoroutinefunction(callback): - yield from callback( - event.data[ATTR_TOPIC], event.data[ATTR_PAYLOAD], - event.data[ATTR_QOS]) - else: - hass.add_job(callback, event.data[ATTR_TOPIC], - event.data[ATTR_PAYLOAD], event.data[ATTR_QOS], - priority=JobPriority.EVENT_CALLBACK) + hass.async_add_job(callback, event.data[ATTR_TOPIC], + event.data[ATTR_PAYLOAD], event.data[ATTR_QOS]) async_remove = hass.bus.async_listen(EVENT_MQTT_MESSAGE_RECEIVED, mqtt_topic_subscriber) @@ -203,6 +183,10 @@ def mqtt_topic_subscriber(event): return async_remove +# pylint: disable=invalid-name +subscribe = threaded_listener_factory(async_subscribe) + + def _setup_server(hass, config): """Try to start embedded MQTT broker.""" conf = config.get(DOMAIN, {}) diff --git a/homeassistant/components/script.py b/homeassistant/components/script.py index b235c4d4eb75b..961c37f896a08 100644 --- a/homeassistant/components/script.py +++ b/homeassistant/components/script.py @@ -124,7 +124,7 @@ class ScriptEntity(ToggleEntity): def __init__(self, hass, object_id, name, sequence): """Initialize the script.""" self.entity_id = ENTITY_ID_FORMAT.format(object_id) - self.script = Script(hass, sequence, name, self.update_ha_state) + self.script = Script(hass, sequence, name, self.async_update_ha_state) @property def should_poll(self): diff --git a/homeassistant/components/sensor/template.py b/homeassistant/components/sensor/template.py index 4b6f322b5aa0c..ed905f44ebd58 100644 --- a/homeassistant/components/sensor/template.py +++ b/homeassistant/components/sensor/template.py @@ -82,7 +82,7 @@ def __init__(self, hass, device_id, friendly_name, unit_of_measurement, @asyncio.coroutine def template_sensor_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" - yield from self.async_update_ha_state(True) + hass.loop.create_task(self.async_update_ha_state(True)) track_state_change(hass, entity_ids, template_sensor_state_listener) diff --git a/homeassistant/components/switch/template.py b/homeassistant/components/switch/template.py index 7c6f4f5886d22..bcd74454ce54a 100644 --- a/homeassistant/components/switch/template.py +++ b/homeassistant/components/switch/template.py @@ -91,7 +91,7 @@ def __init__(self, hass, device_id, friendly_name, state_template, @asyncio.coroutine def template_switch_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" - yield from self.async_update_ha_state(True) + hass.loop.create_task(self.async_update_ha_state(True)) track_state_change(hass, entity_ids, template_switch_state_listener) diff --git a/homeassistant/helpers/event.py b/homeassistant/helpers/event.py index bf781e7e746bf..69f620adb8232 100644 --- a/homeassistant/helpers/event.py +++ b/homeassistant/helpers/event.py @@ -9,11 +9,11 @@ from ..util import dt as dt_util from ..util.async import run_callback_threadsafe -# PyLint does not like the use of _threaded_factory +# PyLint does not like the use of threaded_listener_factory # pylint: disable=invalid-name -def _threaded_factory(async_factory): +def threaded_listener_factory(async_factory): """Convert an async event helper to a threaded one.""" @ft.wraps(async_factory) def factory(*args, **kwargs): @@ -83,7 +83,7 @@ def state_change_listener(event): return hass.bus.async_listen(EVENT_STATE_CHANGED, state_change_listener) -track_state_change = _threaded_factory(async_track_state_change) +track_state_change = threaded_listener_factory(async_track_state_change) def async_track_point_in_time(hass, action, point_in_time): @@ -100,7 +100,7 @@ def utc_converter(utc_now): utc_point_in_time) -track_point_in_time = _threaded_factory(async_track_point_in_time) +track_point_in_time = threaded_listener_factory(async_track_point_in_time) def async_track_point_in_utc_time(hass, action, point_in_time): @@ -133,7 +133,8 @@ def point_in_time_listener(event): return async_unsub -track_point_in_utc_time = _threaded_factory(async_track_point_in_utc_time) +track_point_in_utc_time = threaded_listener_factory( + async_track_point_in_utc_time) def async_track_sunrise(hass, action, offset=None): @@ -169,7 +170,7 @@ def remove_listener(): return remove_listener -track_sunrise = _threaded_factory(async_track_sunrise) +track_sunrise = threaded_listener_factory(async_track_sunrise) def async_track_sunset(hass, action, offset=None): @@ -205,7 +206,7 @@ def remove_listener(): return remove_listener -track_sunset = _threaded_factory(async_track_sunset) +track_sunset = threaded_listener_factory(async_track_sunset) # pylint: disable=too-many-arguments @@ -251,7 +252,7 @@ def pattern_time_change_listener(event): pattern_time_change_listener) -track_utc_time_change = _threaded_factory(async_track_utc_time_change) +track_utc_time_change = threaded_listener_factory(async_track_utc_time_change) # pylint: disable=too-many-arguments @@ -262,7 +263,7 @@ def async_track_time_change(hass, action, year=None, month=None, day=None, minute, second, local=True) -track_time_change = _threaded_factory(async_track_time_change) +track_time_change = threaded_listener_factory(async_track_time_change) def _process_state_match(parameter): diff --git a/homeassistant/helpers/script.py b/homeassistant/helpers/script.py index 1bfe7d550adc9..cb4a1fbbe0436 100644 --- a/homeassistant/helpers/script.py +++ b/homeassistant/helpers/script.py @@ -66,7 +66,7 @@ def run(self, variables=None): def async_run(self, variables: Optional[Sequence]=None) -> None: """Run script. - Returns a coroutine. + This method is a coroutine. """ if self._cur == -1: self._log('Running script') @@ -85,7 +85,7 @@ def async_run(self, variables: Optional[Sequence]=None) -> None: def script_delay(now): """Called after delay is done.""" self._async_unsub_delay_listener = None - yield from self.async_run(variables) + self.hass.loop.create_task(self.async_run(variables)) delay = action[CONF_DELAY] @@ -100,7 +100,8 @@ def script_delay(now): self.hass, script_delay, date_util.utcnow() + delay) self._cur = cur + 1 - self._trigger_change_listener() + if self._change_listener: + self.hass.async_add_job(self._change_listener) return elif CONF_CONDITION in action: @@ -115,7 +116,8 @@ def script_delay(now): self._cur = -1 self.last_action = None - self._trigger_change_listener() + if self._change_listener: + self.hass.async_add_job(self._change_listener) def stop(self) -> None: """Stop running script.""" @@ -128,11 +130,15 @@ def async_stop(self) -> None: self._cur = -1 self._async_remove_listener() - self._trigger_change_listener() + if self._change_listener: + self.hass.async_add_job(self._change_listener) @asyncio.coroutine def _async_call_service(self, action, variables): - """Call the service specified in the action.""" + """Call the service specified in the action. + + This method is a coroutine. + """ self.last_action = action.get(CONF_ALIAS, 'call service') self._log("Executing step %s" % self.last_action) yield from service.async_call_from_config( @@ -165,10 +171,3 @@ def _log(self, msg): msg = "Script {}: {}".format(self.name, msg) _LOGGER.info(msg) - - def _trigger_change_listener(self): - """Trigger the change listener.""" - if not self._change_listener: - return - - self.hass.async_add_job(self._change_listener) diff --git a/tests/components/automation/test_init.py b/tests/components/automation/test_init.py index b667436d9a6e7..8cc7825bb1f69 100644 --- a/tests/components/automation/test_init.py +++ b/tests/components/automation/test_init.py @@ -144,6 +144,35 @@ def test_two_triggers(self): self.hass.block_till_done() self.assertEqual(2, len(self.calls)) + def test_trigger_service_ignoring_condition(self): + """Test triggers.""" + assert setup_component(self.hass, automation.DOMAIN, { + automation.DOMAIN: { + 'trigger': [ + { + 'platform': 'event', + 'event_type': 'test_event', + }, + ], + 'condition': { + 'condition': 'state', + 'entity_id': 'non.existing', + 'state': 'beer', + }, + 'action': { + 'service': 'test.automation', + } + } + }) + + self.hass.bus.fire('test_event') + self.hass.block_till_done() + assert len(self.calls) == 0 + + self.hass.services.call('automation', 'trigger', blocking=True) + self.hass.block_till_done() + assert len(self.calls) == 1 + def test_two_conditions_with_and(self): """Test two and conditions.""" entity_id = 'test.entity' @@ -348,6 +377,8 @@ def test_reload_config_service(self, mock_load_yaml): automation.reload(self.hass) self.hass.block_till_done() + # De-flake ?! + self.hass.block_till_done() assert self.hass.states.get('automation.hello') is None assert self.hass.states.get('automation.bye') is not None diff --git a/tests/components/test_logbook.py b/tests/components/test_logbook.py index 539622d9296d9..9e8ab09a5a634 100644 --- a/tests/components/test_logbook.py +++ b/tests/components/test_logbook.py @@ -50,6 +50,11 @@ def event_listener(event): logbook.ATTR_ENTITY_ID: 'switch.test_switch' }, True) + # Logbook entry service call results in firing an event. + # Our service call will unblock when the event listeners have been + # scheduled. This means that they may not have been processed yet. + self.hass.block_till_done() + self.assertEqual(1, len(calls)) last_call = calls[-1] @@ -70,6 +75,11 @@ def event_listener(event): self.hass.bus.listen(logbook.EVENT_LOGBOOK_ENTRY, event_listener) self.hass.services.call(logbook.DOMAIN, 'log', {}, True) + # Logbook entry service call results in firing an event. + # Our service call will unblock when the event listeners have been + # scheduled. This means that they may not have been processed yet. + self.hass.block_till_done() + self.assertEqual(0, len(calls)) def test_humanify_filter_sensor(self): From 194402f7e7face6471d279b1b1c075eb115b511d Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 4 Oct 2016 09:47:28 +0200 Subject: [PATCH 062/112] Upgrade Sphinx to 1.4.8 and set missing variables (#3650) --- docs/source/conf.py | 10 +++++----- requirements_docs.txt | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 18b14795caa89..bcb2699f57b37 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -340,8 +340,8 @@ def linkcode_resolve(domain, info): # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'Home-Assistant.tex', 'Home-Assistant Documentation', - 'Home-Assistant Team', 'manual'), + (master_doc, 'home-assistant.tex', 'Home Assistant Documentation', + 'Home Assistant Team', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -382,7 +382,7 @@ def linkcode_resolve(domain, info): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (master_doc, 'home-assistant', 'Home-Assistant Documentation', + (master_doc, 'home-assistant', 'Home Assistant Documentation', [author], 1) ] @@ -397,8 +397,8 @@ def linkcode_resolve(domain, info): # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'Home-Assistant', 'Home-Assistant Documentation', - author, 'Home-Assistant', 'One line description of project.', + (master_doc, 'Home-Assistant', 'Home Assistant Documentation', + author, 'Home Assistant', 'Open-source home automation platform.', 'Miscellaneous'), ] diff --git a/requirements_docs.txt b/requirements_docs.txt index df88ba8fb58cb..85405fb6eab48 100644 --- a/requirements_docs.txt +++ b/requirements_docs.txt @@ -1,3 +1,3 @@ -Sphinx==1.4.6 +Sphinx==1.4.8 sphinx-autodoc-typehints==1.1.0 sphinx-autodoc-annotation==1.0.post1 From c93b63963bc6148fcf5db37be1faf38ae8c4b751 Mon Sep 17 00:00:00 2001 From: deisi Date: Tue, 4 Oct 2016 09:47:58 +0200 Subject: [PATCH 063/112] Fix 3621 (#3642) Happens when the scanner searches for a mac address, that has been forgotten by the fritzbox. --- homeassistant/components/device_tracker/fritz.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/device_tracker/fritz.py b/homeassistant/components/device_tracker/fritz.py index 202919871ad14..0e8ed5120725b 100644 --- a/homeassistant/components/device_tracker/fritz.py +++ b/homeassistant/components/device_tracker/fritz.py @@ -85,7 +85,9 @@ def scan_devices(self): def get_device_name(self, mac): """Return the name of the given device or None if is not known.""" - ret = self.fritz_box.get_specific_host_entry(mac)['NewHostName'] + ret = self.fritz_box.get_specific_host_entry(mac).get( + 'NewHostName' + ) if ret == {}: return None return ret From 8592ba3cb9d21feeb18d5f4c4ad078f2cab25372 Mon Sep 17 00:00:00 2001 From: William Scanlon Date: Tue, 4 Oct 2016 03:51:45 -0400 Subject: [PATCH 064/112] Report availability of arest (#3614) --- homeassistant/components/sensor/arest.py | 11 ++++++-- homeassistant/components/switch/arest.py | 32 +++++++++++++++++++----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/sensor/arest.py b/homeassistant/components/sensor/arest.py index c13ea15b22287..cad9a5fc41654 100644 --- a/homeassistant/components/sensor/arest.py +++ b/homeassistant/components/sensor/arest.py @@ -74,7 +74,7 @@ def make_renderer(value_template): def _render(value): try: - return value_template.render({'value': value}) + return value_template.async_render({'value': value}) except TemplateError: _LOGGER.exception('Error parsing value') return value @@ -157,6 +157,11 @@ def update(self): """Get the latest data from aREST API.""" self.arest.update() + @property + def available(self): + """Could the device be accessed during the last update call.""" + return self.arest.available + # pylint: disable=too-few-public-methods class ArestData(object): @@ -167,6 +172,7 @@ def __init__(self, resource, pin=None): self._resource = resource self._pin = pin self.data = {} + self.available = True @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): @@ -188,7 +194,8 @@ def update(self): response = requests.get('{}/digital/{}'.format( self._resource, self._pin), timeout=10) self.data = {'value': response.json()['return_value']} + self.available = True except requests.exceptions.ConnectionError: _LOGGER.error("No route to device %s. Is device offline?", self._resource) - self.data = {'error': 'error fetching'} + self.available = False diff --git a/homeassistant/components/switch/arest.py b/homeassistant/components/switch/arest.py index ce5c946b43610..76f5bc7b580e8 100644 --- a/homeassistant/components/switch/arest.py +++ b/homeassistant/components/switch/arest.py @@ -75,6 +75,7 @@ def __init__(self, resource, location, name): self._resource = resource self._name = '{} {}'.format(location.title(), name.title()) self._state = None + self._available = True @property def name(self): @@ -86,6 +87,11 @@ def is_on(self): """Return true if device is on.""" return self._state + @property + def available(self): + """Could the device be accessed during the last update call.""" + return self._available + class ArestSwitchFunction(ArestSwitchBase): """Representation of an aREST switch.""" @@ -136,9 +142,15 @@ def turn_off(self, **kwargs): def update(self): """Get the latest data from aREST API and update the state.""" - request = requests.get( - '{}/{}'.format(self._resource, self._func), timeout=10) - self._state = request.json()['return_value'] != 0 + try: + request = requests.get('{}/{}'.format(self._resource, + self._func), timeout=10) + self._state = request.json()['return_value'] != 0 + self._available = True + except requests.exceptions.ConnectionError: + _LOGGER.warning("No route to device %s. Is device offline?", + self._resource) + self._available = False class ArestSwitchPin(ArestSwitchBase): @@ -153,6 +165,7 @@ def __init__(self, resource, location, name, pin): '{}/mode/{}/o'.format(self._resource, self._pin), timeout=10) if request.status_code is not 200: _LOGGER.error("Can't set mode. Is device offline?") + self._available = False def turn_on(self, **kwargs): """Turn the device on.""" @@ -176,6 +189,13 @@ def turn_off(self, **kwargs): def update(self): """Get the latest data from aREST API and update the state.""" - request = requests.get( - '{}/digital/{}'.format(self._resource, self._pin), timeout=10) - self._state = request.json()['return_value'] != 0 + try: + request = requests.get('{}/digital/{}'.format(self._resource, + self._pin), + timeout=10) + self._state = request.json()['return_value'] != 0 + self._available = True + except requests.exceptions.ConnectionError: + _LOGGER.warning("No route to device %s. Is device offline?", + self._resource) + self._available = False From 287a7e27201a12a0ab5411668058e3a17546bea5 Mon Sep 17 00:00:00 2001 From: Erik Eriksson Date: Tue, 4 Oct 2016 09:57:37 +0200 Subject: [PATCH 065/112] Support for encrypted payload (#3587) --- .../components/device_tracker/owntracks.py | 77 ++++++++++- requirements_all.txt | 3 + .../device_tracker/test_owntracks.py | 120 ++++++++++++++++++ 3 files changed, 195 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/device_tracker/owntracks.py b/homeassistant/components/device_tracker/owntracks.py index 1395f2940fe7e..619d3f0ee5de1 100644 --- a/homeassistant/components/device_tracker/owntracks.py +++ b/homeassistant/components/device_tracker/owntracks.py @@ -7,6 +7,7 @@ import json import logging import threading +import base64 from collections import defaultdict import voluptuous as vol @@ -19,6 +20,7 @@ from homeassistant.components.device_tracker import PLATFORM_SCHEMA DEPENDENCIES = ['mqtt'] +REQUIREMENTS = ['libnacl==1.5.0'] REGIONS_ENTERED = defaultdict(list) MOBILE_BEACONS_ACTIVE = defaultdict(list) @@ -36,6 +38,7 @@ CONF_MAX_GPS_ACCURACY = 'max_gps_accuracy' CONF_WAYPOINT_IMPORT = 'waypoints' CONF_WAYPOINT_WHITELIST = 'waypoint_whitelist' +CONF_SECRET = 'secret' VALIDATE_LOCATION = 'location' VALIDATE_TRANSITION = 'transition' @@ -47,24 +50,88 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_MAX_GPS_ACCURACY): vol.Coerce(float), vol.Optional(CONF_WAYPOINT_IMPORT, default=True): cv.boolean, - vol.Optional(CONF_WAYPOINT_WHITELIST): vol.All(cv.ensure_list, [cv.string]) + vol.Optional(CONF_WAYPOINT_WHITELIST): vol.All( + cv.ensure_list, [cv.string]), + vol.Optional(CONF_SECRET): vol.Any( + vol.Schema({vol.Optional(cv.string): cv.string}), + cv.string) }) +def get_cipher(): + """Return decryption function and length of key.""" + from libnacl import crypto_secretbox_KEYBYTES as KEYLEN + from libnacl.secret import SecretBox + + def decrypt(ciphertext, key): + """Decrypt ciphertext using key.""" + return SecretBox(key).decrypt(ciphertext) + return (KEYLEN, decrypt) + + def setup_scanner(hass, config, see): """Setup an OwnTracks tracker.""" max_gps_accuracy = config.get(CONF_MAX_GPS_ACCURACY) waypoint_import = config.get(CONF_WAYPOINT_IMPORT) waypoint_whitelist = config.get(CONF_WAYPOINT_WHITELIST) + secret = config.get(CONF_SECRET) + + def decrypt_payload(topic, ciphertext): + """Decrypt encrypted payload.""" + try: + keylen, decrypt = get_cipher() + except OSError: + _LOGGER.warning('Ignoring encrypted payload ' + 'because libsodium not installed.') + return None + + if isinstance(secret, dict): + key = secret.get(topic) + else: + key = secret + + if key is None: + _LOGGER.warning('Ignoring encrypted payload ' + 'because no decryption key known ' + 'for topic %s.', topic) + return None + + key = key.encode("utf-8") + key = key[:keylen] + key = key.ljust(keylen, b'\0') - def validate_payload(payload, data_type): + try: + ciphertext = base64.b64decode(ciphertext) + message = decrypt(ciphertext, key) + message = message.decode("utf-8") + _LOGGER.debug("Decrypted payload: %s", message) + return message + except ValueError: + _LOGGER.warning('Ignoring encrypted payload ' + 'because unable to decrypt using key ' + 'for topic %s.', topic) + return None + + def validate_payload(topic, payload, data_type): """Validate OwnTracks payload.""" + # pylint: disable=too-many-return-statements + try: data = json.loads(payload) except ValueError: # If invalid JSON _LOGGER.error('Unable to parse payload as JSON: %s', payload) return None + + if isinstance(data, dict) and \ + data.get('_type') == 'encrypted' and \ + 'data' in data: + plaintext_payload = decrypt_payload(topic, data['data']) + if plaintext_payload is None: + return None + else: + return validate_payload(topic, plaintext_payload, data_type) + if not isinstance(data, dict) or data.get('_type') != data_type: _LOGGER.debug('Skipping %s update for following data ' 'because of missing or malformatted data: %s', @@ -90,7 +157,7 @@ def owntracks_location_update(topic, payload, qos): """MQTT message received.""" # Docs on available data: # http://owntracks.org/booklet/tech/json/#_typelocation - data = validate_payload(payload, VALIDATE_LOCATION) + data = validate_payload(topic, payload, VALIDATE_LOCATION) if not data: return @@ -111,7 +178,7 @@ def owntracks_event_update(topic, payload, qos): """MQTT event (geofences) received.""" # Docs on available data: # http://owntracks.org/booklet/tech/json/#_typetransition - data = validate_payload(payload, VALIDATE_TRANSITION) + data = validate_payload(topic, payload, VALIDATE_TRANSITION) if not data: return @@ -206,7 +273,7 @@ def owntracks_waypoint_update(topic, payload, qos): """List of waypoints published by a user.""" # Docs on available data: # http://owntracks.org/booklet/tech/json/#_typewaypoints - data = validate_payload(payload, VALIDATE_WAYPOINTS) + data = validate_payload(topic, payload, VALIDATE_WAYPOINTS) if not data: return diff --git a/requirements_all.txt b/requirements_all.txt index b86a8a37ea8f4..d80c0aff49ae8 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -235,6 +235,9 @@ keyring>=9.3,<10.0 # homeassistant.components.knx knxip==0.3.3 +# homeassistant.components.device_tracker.owntracks +libnacl==1.5.0 + # homeassistant.components.light.lifx liffylights==0.9.4 diff --git a/tests/components/device_tracker/test_owntracks.py b/tests/components/device_tracker/test_owntracks.py index 2d2495aa68f9e..ef3d79d089b21 100644 --- a/tests/components/device_tracker/test_owntracks.py +++ b/tests/components/device_tracker/test_owntracks.py @@ -2,6 +2,7 @@ import json import os import unittest +from unittest.mock import patch from collections import defaultdict @@ -31,6 +32,7 @@ CONF_MAX_GPS_ACCURACY = 'max_gps_accuracy' CONF_WAYPOINT_IMPORT = owntracks.CONF_WAYPOINT_IMPORT CONF_WAYPOINT_WHITELIST = owntracks.CONF_WAYPOINT_WHITELIST +CONF_SECRET = owntracks.CONF_SECRET LOCATION_MESSAGE = { 'batt': 92, @@ -184,6 +186,26 @@ BAD_JSON_PREFIX = '--$this is bad json#--' BAD_JSON_SUFFIX = '** and it ends here ^^' +SECRET_KEY = "s3cretkey" +ENCRYPTED_LOCATION_MESSAGE = { + # Encrypted version of LOCATION_MESSAGE using libsodium and SECRET_KEY + '_type': 'encrypted', + 'data': ('qm1A83I6TVFRmH5343xy+cbex8jBBxDFkHRuJhELVKVRA/DgXcyKtghw' + '9pOw75Lo4gHcyy2wV5CmkjrpKEBR7Qhye4AR0y7hOvlx6U/a3GuY1+W8' + 'I4smrLkwMvGgBOzXSNdVTzbFTHDvG3gRRaNHFkt2+5MsbH2Dd6CXmpzq' + 'DIfSN7QzwOevuvNIElii5MlFxI6ZnYIDYA/ZdnAXHEVsNIbyT2N0CXt3' + 'fTPzgGtFzsufx40EEUkC06J7QTJl7lLG6qaLW1cCWp86Vp0eL3vtZ6xq')} + +MOCK_ENCRYPTED_LOCATION_MESSAGE = { + # Mock-encrypted version of LOCATION_MESSAGE using pickle + '_type': 'encrypted', + 'data': ('gANDCXMzY3JldGtleXEAQ6p7ImxvbiI6IDEuMCwgInQiOiAidSIsICJi' + 'YXR0IjogOTIsICJhY2MiOiA2MCwgInZlbCI6IDAsICJfdHlwZSI6ICJs' + 'b2NhdGlvbiIsICJ2YWMiOiA0LCAicCI6IDEwMS4zOTc3NTg0ODM4ODY3' + 'LCAidHN0IjogMSwgImxhdCI6IDIuMCwgImFsdCI6IDI3LCAiY29nIjog' + 'MjQ4LCAidGlkIjogInVzZXIifXEBhnECLg==') +} + class TestDeviceTrackerOwnTracks(unittest.TestCase): """Test the OwnTrack sensor.""" @@ -650,3 +672,101 @@ def test_waypoint_import_existing(self): self.send_message(WAYPOINT_TOPIC, waypoints_message) new_wayp = self.hass.states.get(WAYPOINT_ENTITY_NAMES[0]) self.assertTrue(wayp == new_wayp) + + try: + import libnacl + except (ImportError, OSError): + libnacl = None + + @unittest.skipUnless(libnacl, + "libnacl/libsodium is not installed") + def test_encrypted_payload_libsodium(self): + """Test sending encrypted message payload.""" + self.assertTrue(device_tracker.setup(self.hass, { + device_tracker.DOMAIN: { + CONF_PLATFORM: 'owntracks', + CONF_SECRET: SECRET_KEY, + }})) + + self.send_message(LOCATION_TOPIC, ENCRYPTED_LOCATION_MESSAGE) + self.assert_location_latitude(2.0) + + def mock_cipher(): + """Return a dummy pickle-based cipher.""" + def mock_decrypt(ciphertext, key): + """Decrypt/unpickle.""" + import pickle + (mkey, plaintext) = pickle.loads(ciphertext) + if key != mkey: + raise ValueError() + return plaintext + return (len(SECRET_KEY), mock_decrypt) + + @patch('homeassistant.components.device_tracker.owntracks.get_cipher', + mock_cipher) + def test_encrypted_payload(self): + self.assertTrue(device_tracker.setup(self.hass, { + device_tracker.DOMAIN: { + CONF_PLATFORM: 'owntracks', + CONF_SECRET: SECRET_KEY, + }})) + self.send_message(LOCATION_TOPIC, MOCK_ENCRYPTED_LOCATION_MESSAGE) + self.assert_location_latitude(2.0) + + @patch('homeassistant.components.device_tracker.owntracks.get_cipher', + mock_cipher) + def test_encrypted_payload_topic_key(self): + self.assertTrue(device_tracker.setup(self.hass, { + device_tracker.DOMAIN: { + CONF_PLATFORM: 'owntracks', + CONF_SECRET: { + LOCATION_TOPIC: SECRET_KEY, + }}})) + self.send_message(LOCATION_TOPIC, MOCK_ENCRYPTED_LOCATION_MESSAGE) + self.assert_location_latitude(2.0) + + @patch('homeassistant.components.device_tracker.owntracks.get_cipher', + mock_cipher) + def test_encrypted_payload_no_key(self): + self.assertTrue(device_tracker.setup(self.hass, { + device_tracker.DOMAIN: { + CONF_PLATFORM: 'owntracks', + # key missing + }})) + self.send_message(LOCATION_TOPIC, MOCK_ENCRYPTED_LOCATION_MESSAGE) + self.assert_location_latitude(None) + + @patch('homeassistant.components.device_tracker.owntracks.get_cipher', + mock_cipher) + def test_encrypted_payload_wrong_key(self): + self.assertTrue(device_tracker.setup(self.hass, { + device_tracker.DOMAIN: { + CONF_PLATFORM: 'owntracks', + CONF_SECRET: 'wrong key', + }})) + self.send_message(LOCATION_TOPIC, MOCK_ENCRYPTED_LOCATION_MESSAGE) + self.assert_location_latitude(None) + + @patch('homeassistant.components.device_tracker.owntracks.get_cipher', + mock_cipher) + def test_encrypted_payload_wrong_topic_key(self): + self.assertTrue(device_tracker.setup(self.hass, { + device_tracker.DOMAIN: { + CONF_PLATFORM: 'owntracks', + CONF_SECRET: { + LOCATION_TOPIC: "wrong key" + }}})) + self.send_message(LOCATION_TOPIC, MOCK_ENCRYPTED_LOCATION_MESSAGE) + self.assert_location_latitude(None) + + @patch('homeassistant.components.device_tracker.owntracks.get_cipher', + mock_cipher) + def test_encrypted_payload_no_topic_key(self): + self.assertTrue(device_tracker.setup(self.hass, { + device_tracker.DOMAIN: { + CONF_PLATFORM: 'owntracks', + CONF_SECRET: { + "owntracks/{}/{}".format(USER, "otherdevice"): "foobar" + }}})) + self.send_message(LOCATION_TOPIC, MOCK_ENCRYPTED_LOCATION_MESSAGE) + self.assert_location_latitude(None) From 5900d8a2c1ece557dac8a91225c701ca84e0a9b1 Mon Sep 17 00:00:00 2001 From: Erik Eriksson Date: Tue, 4 Oct 2016 09:58:25 +0200 Subject: [PATCH 066/112] only query vehicle attributes once (#3668) use registration number as dev id --- .../components/device_tracker/volvooncall.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/device_tracker/volvooncall.py b/homeassistant/components/device_tracker/volvooncall.py index 6876d63c22354..703fe32e53869 100644 --- a/homeassistant/components/device_tracker/volvooncall.py +++ b/homeassistant/components/device_tracker/volvooncall.py @@ -67,6 +67,12 @@ def query(ref, rel=SERVICE_URL): user = query("customeraccounts") rel = query(user["accountVehicleRelations"][0]) vehicle_url = rel["vehicle"] + '/' + attributes = query("attributes", vehicle_url) + + dev_id = "volvo_" + attributes["registrationNumber"] + host_name = "%s %s/%s" % (attributes["registrationNumber"], + attributes["vehicleType"], + attributes["modelYear"]) except requests.exceptions.RequestException: _LOGGER.error("Could not log in to service. " "Please check configuration.") @@ -78,12 +84,6 @@ def update(now): status = query("status", vehicle_url) position = query("position", vehicle_url) - attributes = query("attributes", vehicle_url) - - dev_id = "volvo_" + attributes["vin"] - host_name = "%s %s/%s" % (attributes["registrationNumber"], - attributes["vehicleType"], - attributes["modelYear"]) see(dev_id=dev_id, host_name=host_name, From 694983379f075db020123fef6cfe79f101b77315 Mon Sep 17 00:00:00 2001 From: Rob Capellini Date: Tue, 4 Oct 2016 04:01:41 -0400 Subject: [PATCH 067/112] test: mocking IO in HTML5 notify tests (#3685) Replacing temporary file creation in tests with mock's mock_open for faster IO. --- tests/components/notify/test_html5.py | 124 +++++++++++++++----------- 1 file changed, 72 insertions(+), 52 deletions(-) diff --git a/tests/components/notify/test_html5.py b/tests/components/notify/test_html5.py index d3d20d0128910..e3439e4cb2f67 100644 --- a/tests/components/notify/test_html5.py +++ b/tests/components/notify/test_html5.py @@ -1,7 +1,6 @@ """Test HTML5 notify platform.""" import json -import tempfile -from unittest.mock import patch, MagicMock +from unittest.mock import patch, MagicMock, mock_open from werkzeug.test import EnvironBuilder @@ -44,8 +43,10 @@ def test_get_service_with_no_json(self): """Test empty json file.""" hass = MagicMock() - with tempfile.NamedTemporaryFile() as fp: - hass.config.path.return_value = fp.name + m = mock_open() + with patch( + 'homeassistant.components.notify.html5.open', m, create=True + ): service = html5.get_service(hass, {}) assert service is not None @@ -54,10 +55,10 @@ def test_get_service_with_bad_json(self): """Test .""" hass = MagicMock() - with tempfile.NamedTemporaryFile() as fp: - fp.write('I am not JSON'.encode('utf-8')) - fp.flush() - hass.config.path.return_value = fp.name + m = mock_open(read_data='I am not JSON') + with patch( + 'homeassistant.components.notify.html5.open', m, create=True + ): service = html5.get_service(hass, {}) assert service is None @@ -71,10 +72,10 @@ def test_sending_message(self, mock_wp): 'device': SUBSCRIPTION_1 } - with tempfile.NamedTemporaryFile() as fp: - fp.write(json.dumps(data).encode('utf-8')) - fp.flush() - hass.config.path.return_value = fp.name + m = mock_open(read_data=json.dumps(data)) + with patch( + 'homeassistant.components.notify.html5.open', m, create=True + ): service = html5.get_service(hass, {'gcm_sender_id': '100'}) assert service is not None @@ -97,9 +98,11 @@ def test_registering_new_device_view(self): """Test that the HTML view works.""" hass = MagicMock() - with tempfile.NamedTemporaryFile() as fp: - hass.config.path.return_value = fp.name - fp.close() + m = mock_open() + with patch( + 'homeassistant.components.notify.html5.open', m, create=True + ): + hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {}) assert service is not None @@ -108,7 +111,7 @@ def test_registering_new_device_view(self): assert len(hass.mock_calls) == 3 view = hass.mock_calls[1][1][0] - assert view.json_path == fp.name + assert view.json_path == hass.config.path.return_value assert view.registrations == {} builder = EnvironBuilder(method='POST', @@ -122,15 +125,18 @@ def test_registering_new_device_view(self): assert resp.status_code == 200, resp.response assert view.registrations == expected - with open(fp.name) as fpp: - assert json.load(fpp) == expected + handle = m() + assert json.loads(handle.write.call_args[0][0]) == expected def test_registering_new_device_validation(self): """Test various errors when registering a new device.""" hass = MagicMock() - with tempfile.NamedTemporaryFile() as fp: - hass.config.path.return_value = fp.name + m = mock_open() + with patch( + 'homeassistant.components.notify.html5.open', m, create=True + ): + hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {}) assert service is not None @@ -164,8 +170,10 @@ def test_registering_new_device_validation(self): resp = view.post(Request(builder.get_environ())) assert resp.status_code == 400, resp.response - def test_unregistering_device_view(self): + @patch('homeassistant.components.notify.html5.os') + def test_unregistering_device_view(self, mock_os): """Test that the HTML unregister view works.""" + mock_os.path.isfile.return_value = True hass = MagicMock() config = { @@ -173,10 +181,11 @@ def test_unregistering_device_view(self): 'other device': SUBSCRIPTION_2, } - with tempfile.NamedTemporaryFile() as fp: - hass.config.path.return_value = fp.name - fp.write(json.dumps(config).encode('utf-8')) - fp.flush() + m = mock_open(read_data=json.dumps(config)) + with patch( + 'homeassistant.components.notify.html5.open', m, create=True + ): + hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {}) assert service is not None @@ -185,7 +194,7 @@ def test_unregistering_device_view(self): assert len(hass.mock_calls) == 3 view = hass.mock_calls[1][1][0] - assert view.json_path == fp.name + assert view.json_path == hass.config.path.return_value assert view.registrations == config builder = EnvironBuilder(method='DELETE', data=json.dumps({ @@ -198,11 +207,13 @@ def test_unregistering_device_view(self): assert resp.status_code == 200, resp.response assert view.registrations == config - with open(fp.name) as fpp: - assert json.load(fpp) == config + handle = m() + assert json.loads(handle.write.call_args[0][0]) == config - def test_unregistering_device_view_handles_unknown_subscription(self): + @patch('homeassistant.components.notify.html5.os') + def test_unregister_device_view_handle_unknown_subscription(self, mock_os): """Test that the HTML unregister view handles unknown subscriptions.""" + mock_os.path.isfile.return_value = True hass = MagicMock() config = { @@ -210,10 +221,11 @@ def test_unregistering_device_view_handles_unknown_subscription(self): 'other device': SUBSCRIPTION_2, } - with tempfile.NamedTemporaryFile() as fp: - hass.config.path.return_value = fp.name - fp.write(json.dumps(config).encode('utf-8')) - fp.flush() + m = mock_open(read_data=json.dumps(config)) + with patch( + 'homeassistant.components.notify.html5.open', m, create=True + ): + hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {}) assert service is not None @@ -222,7 +234,7 @@ def test_unregistering_device_view_handles_unknown_subscription(self): assert len(hass.mock_calls) == 3 view = hass.mock_calls[1][1][0] - assert view.json_path == fp.name + assert view.json_path == hass.config.path.return_value assert view.registrations == config builder = EnvironBuilder(method='DELETE', data=json.dumps({ @@ -233,11 +245,13 @@ def test_unregistering_device_view_handles_unknown_subscription(self): assert resp.status_code == 200, resp.response assert view.registrations == config - with open(fp.name) as fpp: - assert json.load(fpp) == config + handle = m() + assert handle.write.call_count == 0 - def test_unregistering_device_view_handles_json_safe_error(self): + @patch('homeassistant.components.notify.html5.os') + def test_unregistering_device_view_handles_json_safe_error(self, mock_os): """Test that the HTML unregister view handles JSON write errors.""" + mock_os.path.isfile.return_value = True hass = MagicMock() config = { @@ -245,10 +259,11 @@ def test_unregistering_device_view_handles_json_safe_error(self): 'other device': SUBSCRIPTION_2, } - with tempfile.NamedTemporaryFile() as fp: - hass.config.path.return_value = fp.name - fp.write(json.dumps(config).encode('utf-8')) - fp.flush() + m = mock_open(read_data=json.dumps(config)) + with patch( + 'homeassistant.components.notify.html5.open', m, create=True + ): + hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {}) assert service is not None @@ -257,7 +272,7 @@ def test_unregistering_device_view_handles_json_safe_error(self): assert len(hass.mock_calls) == 3 view = hass.mock_calls[1][1][0] - assert view.json_path == fp.name + assert view.json_path == hass.config.path.return_value assert view.registrations == config builder = EnvironBuilder(method='DELETE', data=json.dumps({ @@ -271,16 +286,18 @@ def test_unregistering_device_view_handles_json_safe_error(self): assert resp.status_code == 500, resp.response assert view.registrations == config - with open(fp.name) as fpp: - assert json.load(fpp) == config + handle = m() + assert handle.write.call_count == 0 def test_callback_view_no_jwt(self): """Test that the notification callback view works without JWT.""" hass = MagicMock() - with tempfile.NamedTemporaryFile() as fp: - hass.config.path.return_value = fp.name - fp.close() + m = mock_open() + with patch( + 'homeassistant.components.notify.html5.open', m, create=True + ): + hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {}) assert service is not None @@ -299,19 +316,22 @@ def test_callback_view_no_jwt(self): assert resp.status_code == 401, resp.response + @patch('homeassistant.components.notify.html5.os') @patch('pywebpush.WebPusher') - def test_callback_view_with_jwt(self, mock_wp): + def test_callback_view_with_jwt(self, mock_wp, mock_os): """Test that the notification callback view works with JWT.""" + mock_os.path.isfile.return_value = True hass = MagicMock() data = { 'device': SUBSCRIPTION_1, } - with tempfile.NamedTemporaryFile() as fp: - fp.write(json.dumps(data).encode('utf-8')) - fp.flush() - hass.config.path.return_value = fp.name + m = mock_open(read_data=json.dumps(data)) + with patch( + 'homeassistant.components.notify.html5.open', m, create=True + ): + hass.config.path.return_value = 'file.conf' service = html5.get_service(hass, {'gcm_sender_id': '100'}) assert service is not None From 74b0e4cb45c0c0bd425e8a6922190ccab6d06bdb Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 4 Oct 2016 10:04:00 +0200 Subject: [PATCH 068/112] Statistics sensor (#3513) * Initial stats sensor * Add total and tests * Use deque, rename var, set default, and only update sensor --- homeassistant/components/sensor/statistics.py | 151 ++++++++++++++++++ tests/components/sensor/test_statistics.py | 97 +++++++++++ 2 files changed, 248 insertions(+) create mode 100644 homeassistant/components/sensor/statistics.py create mode 100644 tests/components/sensor/test_statistics.py diff --git a/homeassistant/components/sensor/statistics.py b/homeassistant/components/sensor/statistics.py new file mode 100644 index 0000000000000..0c413ab9263d5 --- /dev/null +++ b/homeassistant/components/sensor/statistics.py @@ -0,0 +1,151 @@ +""" +Support for statistics for sensor values. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.statistics/ +""" +import logging +import statistics +from collections import deque + +import voluptuous as vol + +from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.const import ( + CONF_NAME, CONF_ENTITY_ID, STATE_UNKNOWN, ATTR_UNIT_OF_MEASUREMENT) +import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.entity import Entity +from homeassistant.helpers.event import track_state_change + +_LOGGER = logging.getLogger(__name__) + +ATTR_MIN_VALUE = 'min_value' +ATTR_MAX_VALUE = 'max_value' +ATTR_COUNT = 'count' +ATTR_MEAN = 'mean' +ATTR_MEDIAN = 'median' +ATTR_VARIANCE = 'variance' +ATTR_STANDARD_DEVIATION = 'standard_deviation' +ATTR_SAMPLING_SIZE = 'sampling_size' +ATTR_TOTAL = 'total' + +CONF_SAMPLING_SIZE = 'sampling_size' +DEFAULT_NAME = 'Stats' +DEFAULT_SIZE = 20 +ICON = 'mdi:calculator' + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_ENTITY_ID): cv.entity_id, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_SAMPLING_SIZE, default=DEFAULT_SIZE): cv.positive_int, +}) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Setup the Statistics sensor.""" + entity_id = config.get(CONF_ENTITY_ID) + name = config.get(CONF_NAME) + sampling_size = config.get(CONF_SAMPLING_SIZE) + + add_devices([StatisticsSensor(hass, entity_id, name, sampling_size)]) + + +# pylint: disable=too-many-instance-attributes +class StatisticsSensor(Entity): + """Representation of a Statistics sensor.""" + + def __init__(self, hass, entity_id, name, sampling_size): + """Initialize the Statistics sensor.""" + self._hass = hass + self._entity_id = entity_id + self.is_binary = True if self._entity_id.split('.')[0] == \ + 'binary_sensor' else False + if not self.is_binary: + self._name = '{} {}'.format(name, ATTR_MEAN) + else: + self._name = '{} {}'.format(name, ATTR_COUNT) + self._sampling_size = sampling_size + self._unit_of_measurement = None + if self._sampling_size == 0: + self.states = deque() + else: + self.states = deque(maxlen=self._sampling_size) + self.median = self.mean = self.variance = self.stdev = 0 + self.min = self.max = self.total = self.count = 0 + self.update() + + def calculate_sensor_state_listener(entity, old_state, new_state): + """Called when the sensor changes state.""" + self._unit_of_measurement = new_state.attributes.get( + ATTR_UNIT_OF_MEASUREMENT) + + try: + self.states.append(float(new_state.state)) + self.count = self.count + 1 + except ValueError: + self.count = self.count + 1 + + self.update_ha_state(True) + + track_state_change(hass, entity_id, calculate_sensor_state_listener) + + @property + def name(self): + """Return the name of the sensor.""" + return self._name + + @property + def state(self): + """Return the state of the sensor.""" + return self.mean if not self.is_binary else self.count + + @property + def unit_of_measurement(self): + """Return the unit the value is expressed in.""" + return self._unit_of_measurement if not self.is_binary else None + + @property + def should_poll(self): + """No polling needed.""" + return False + + @property + def state_attributes(self): + """Return the state attributes of the sensor.""" + if not self.is_binary: + return { + ATTR_MEAN: self.mean, + ATTR_COUNT: self.count, + ATTR_MAX_VALUE: self.max, + ATTR_MEDIAN: self.median, + ATTR_MIN_VALUE: self.min, + ATTR_SAMPLING_SIZE: 'unlimited' if self._sampling_size is + 0 else self._sampling_size, + ATTR_STANDARD_DEVIATION: self.stdev, + ATTR_TOTAL: self.total, + ATTR_VARIANCE: self.variance, + } + + @property + def icon(self): + """Return the icon to use in the frontend, if any.""" + return ICON + + def update(self): + """Get the latest data and updates the states.""" + if not self.is_binary: + try: + self.mean = round(statistics.mean(self.states), 2) + self.median = round(statistics.median(self.states), 2) + self.stdev = round(statistics.stdev(self.states), 2) + self.variance = round(statistics.variance(self.states), 2) + except statistics.StatisticsError as err: + _LOGGER.warning(err) + self.mean = self.median = STATE_UNKNOWN + self.stdev = self.variance = STATE_UNKNOWN + if self.states: + self.total = round(sum(self.states), 2) + self.min = min(self.states) + self.max = max(self.states) + else: + self.min = self.max = self.total = STATE_UNKNOWN diff --git a/tests/components/sensor/test_statistics.py b/tests/components/sensor/test_statistics.py new file mode 100644 index 0000000000000..75649a0c140c2 --- /dev/null +++ b/tests/components/sensor/test_statistics.py @@ -0,0 +1,97 @@ +"""The test for the statistics sensor platform.""" +import unittest +import statistics + +from homeassistant.bootstrap import setup_component +from homeassistant.const import (ATTR_UNIT_OF_MEASUREMENT, TEMP_CELSIUS) +from tests.common import get_test_home_assistant + + +class TestStatisticsSensor(unittest.TestCase): + """Test the Statistics sensor.""" + + def setup_method(self, method): + """Setup things to be run when tests are started.""" + self.hass = get_test_home_assistant() + self.values = [17, 20, 15.2, 5, 3.8, 9.2, 6.7, 14, 6] + self.count = len(self.values) + self.min = min(self.values) + self.max = max(self.values) + self.total = sum(self.values) + self.mean = round(sum(self.values) / len(self.values), 2) + self.median = round(statistics.median(self.values), 2) + self.deviation = round(statistics.stdev(self.values), 2) + self.variance = round(statistics.variance(self.values), 2) + + def teardown_method(self, method): + """Stop everything that was started.""" + self.hass.stop() + + def test_binary_sensor_source(self): + """Test if source is a sensor.""" + values = [1, 0, 1, 0, 1, 0, 1] + assert setup_component(self.hass, 'sensor', { + 'sensor': { + 'platform': 'statistics', + 'name': 'test', + 'entity_id': 'binary_sensor.test_monitored', + } + }) + + for value in values: + self.hass.states.set('binary_sensor.test_monitored', value) + self.hass.block_till_done() + + state = self.hass.states.get('sensor.test_count') + + self.assertEqual(str(len(values)), state.state) + + def test_sensor_source(self): + """Test if source is a sensor.""" + assert setup_component(self.hass, 'sensor', { + 'sensor': { + 'platform': 'statistics', + 'name': 'test', + 'entity_id': 'sensor.test_monitored', + } + }) + + for value in self.values: + self.hass.states.set('sensor.test_monitored', value, + {ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) + self.hass.block_till_done() + + state = self.hass.states.get('sensor.test_mean') + + self.assertEqual(str(self.mean), state.state) + self.assertEqual(self.min, state.attributes.get('min_value')) + self.assertEqual(self.max, state.attributes.get('max_value')) + self.assertEqual(self.variance, state.attributes.get('variance')) + self.assertEqual(self.median, state.attributes.get('median')) + self.assertEqual(self.deviation, + state.attributes.get('standard_deviation')) + self.assertEqual(self.mean, state.attributes.get('mean')) + self.assertEqual(self.count, state.attributes.get('count')) + self.assertEqual(self.total, state.attributes.get('total')) + self.assertEqual('°C', state.attributes.get('unit_of_measurement')) + + def test_sampling_size(self): + """Test rotation.""" + assert setup_component(self.hass, 'sensor', { + 'sensor': { + 'platform': 'statistics', + 'name': 'test', + 'entity_id': 'sensor.test_monitored', + 'sampling_size': 5, + } + }) + + for value in self.values: + self.hass.states.set('sensor.test_monitored', value, + {ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) + self.hass.block_till_done() + + state = self.hass.states.get('sensor.test_mean') + + self.assertEqual(3.8, state.attributes.get('min_value')) + self.assertEqual(14, state.attributes.get('max_value')) From a072047d9daad37fbe0d42e4ada34553744d082d Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 4 Oct 2016 10:07:17 +0200 Subject: [PATCH 069/112] Auth and headers support for REST sensor (#3592) * Add auth and header support * Update header part --- .../components/binary_sensor/rest.py | 27 ++++++++++++-- homeassistant/components/sensor/pi_hole.py | 4 ++- homeassistant/components/sensor/rest.py | 36 ++++++++++++++----- homeassistant/const.py | 1 + 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/binary_sensor/rest.py b/homeassistant/components/binary_sensor/rest.py index b8be340d43c3e..3e22150a4fd45 100644 --- a/homeassistant/components/binary_sensor/rest.py +++ b/homeassistant/components/binary_sensor/rest.py @@ -5,15 +5,19 @@ https://home-assistant.io/components/binary_sensor.rest/ """ import logging +import json import voluptuous as vol +from requests.auth import HTTPBasicAuth, HTTPDigestAuth from homeassistant.components.binary_sensor import ( BinarySensorDevice, SENSOR_CLASSES_SCHEMA, PLATFORM_SCHEMA) from homeassistant.components.sensor.rest import RestData from homeassistant.const import ( CONF_PAYLOAD, CONF_NAME, CONF_VALUE_TEMPLATE, CONF_METHOD, CONF_RESOURCE, - CONF_SENSOR_CLASS, CONF_VERIFY_SSL) + CONF_SENSOR_CLASS, CONF_VERIFY_SSL, CONF_USERNAME, CONF_PASSWORD, + CONF_HEADERS, CONF_AUTHENTICATION, HTTP_BASIC_AUTHENTICATION, + HTTP_DIGEST_AUTHENTICATION) import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) @@ -24,16 +28,21 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_RESOURCE): cv.url, + vol.Optional(CONF_AUTHENTICATION): + vol.In([HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION]), + vol.Optional(CONF_HEADERS): cv.string, vol.Optional(CONF_METHOD, default=DEFAULT_METHOD): vol.In(['POST', 'GET']), vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_PASSWORD): cv.string, vol.Optional(CONF_PAYLOAD): cv.string, vol.Optional(CONF_SENSOR_CLASS): SENSOR_CLASSES_SCHEMA, + vol.Optional(CONF_USERNAME): cv.string, vol.Optional(CONF_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean, }) -# pylint: disable=unused-variable +# pylint: disable=unused-variable, too-many-locals def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the REST binary sensor.""" name = config.get(CONF_NAME) @@ -41,11 +50,23 @@ def setup_platform(hass, config, add_devices, discovery_info=None): method = config.get(CONF_METHOD) payload = config.get(CONF_PAYLOAD) verify_ssl = config.get(CONF_VERIFY_SSL) + username = config.get(CONF_USERNAME) + password = config.get(CONF_PASSWORD) + headers = json.loads(config.get(CONF_HEADERS, '{}')) sensor_class = config.get(CONF_SENSOR_CLASS) value_template = config.get(CONF_VALUE_TEMPLATE) if value_template is not None: value_template.hass = hass - rest = RestData(method, resource, payload, verify_ssl) + + if username and password: + if config.get(CONF_AUTHENTICATION) == HTTP_DIGEST_AUTHENTICATION: + auth = HTTPDigestAuth(username, password) + else: + auth = HTTPBasicAuth(username, password) + else: + auth = None + + rest = RestData(method, resource, auth, headers, payload, verify_ssl) rest.update() if rest.data is None: diff --git a/homeassistant/components/sensor/pi_hole.py b/homeassistant/components/sensor/pi_hole.py index 7cd3423bf65b2..c6ffdcaf64cb2 100644 --- a/homeassistant/components/sensor/pi_hole.py +++ b/homeassistant/components/sensor/pi_hole.py @@ -43,6 +43,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): host = config.get(CONF_HOST) method = 'GET' payload = None + auth = None + headers = None verify_ssl = config.get(CONF_VERIFY_SSL) use_ssl = config.get(CONF_SSL) @@ -53,7 +55,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): resource = "{}{}{}".format(uri_scheme, host, _ENDPOINT) - rest = RestData(method, resource, payload, verify_ssl) + rest = RestData(method, resource, auth, headers, payload, verify_ssl) rest.update() if rest.data is None: diff --git a/homeassistant/components/sensor/rest.py b/homeassistant/components/sensor/rest.py index edd5dc44865a4..cb856ae992a8e 100644 --- a/homeassistant/components/sensor/rest.py +++ b/homeassistant/components/sensor/rest.py @@ -1,5 +1,5 @@ """ -Support for REST API sensors. +Support for RESTful API sensors. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.rest/ @@ -8,11 +8,14 @@ import voluptuous as vol import requests +from requests.auth import HTTPBasicAuth, HTTPDigestAuth from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( CONF_PAYLOAD, CONF_NAME, CONF_VALUE_TEMPLATE, CONF_METHOD, CONF_RESOURCE, - CONF_UNIT_OF_MEASUREMENT, STATE_UNKNOWN, CONF_VERIFY_SSL) + CONF_UNIT_OF_MEASUREMENT, STATE_UNKNOWN, CONF_VERIFY_SSL, CONF_USERNAME, + CONF_PASSWORD, CONF_AUTHENTICATION, HTTP_BASIC_AUTHENTICATION, + HTTP_DIGEST_AUTHENTICATION, CONF_HEADERS) from homeassistant.helpers.entity import Entity import homeassistant.helpers.config_validation as cv @@ -24,16 +27,21 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_RESOURCE): cv.url, + vol.Optional(CONF_AUTHENTICATION): + vol.In([HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION]), + vol.Optional(CONF_HEADERS): {cv.string: cv.string}, vol.Optional(CONF_METHOD, default=DEFAULT_METHOD): vol.In(['POST', 'GET']), vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_PASSWORD): cv.string, vol.Optional(CONF_PAYLOAD): cv.string, vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string, + vol.Optional(CONF_USERNAME): cv.string, vol.Optional(CONF_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean, }) -# pylint: disable=unused-variable +# pylint: disable=unused-variable, too-many-locals def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the RESTful sensor.""" name = config.get(CONF_NAME) @@ -41,11 +49,22 @@ def setup_platform(hass, config, add_devices, discovery_info=None): method = config.get(CONF_METHOD) payload = config.get(CONF_PAYLOAD) verify_ssl = config.get(CONF_VERIFY_SSL) + username = config.get(CONF_USERNAME) + password = config.get(CONF_PASSWORD) + headers = config.get(CONF_HEADERS) unit = config.get(CONF_UNIT_OF_MEASUREMENT) value_template = config.get(CONF_VALUE_TEMPLATE) if value_template is not None: value_template.hass = hass - rest = RestData(method, resource, payload, verify_ssl) + + if username and password: + if config.get(CONF_AUTHENTICATION) == HTTP_DIGEST_AUTHENTICATION: + auth = HTTPDigestAuth(username, password) + else: + auth = HTTPBasicAuth(username, password) + else: + auth = None + rest = RestData(method, resource, auth, headers, payload, verify_ssl) rest.update() if rest.data is None: @@ -102,9 +121,10 @@ def update(self): class RestData(object): """Class for handling the data retrieval.""" - def __init__(self, method, resource, data, verify_ssl): + def __init__(self, method, resource, auth, headers, data, verify_ssl): """Initialize the data object.""" - self._request = requests.Request(method, resource, data=data).prepare() + self._request = requests.Request( + method, resource, headers=headers, auth=auth, data=data).prepare() self._verify_ssl = verify_ssl self.data = None @@ -112,8 +132,8 @@ def update(self): """Get the latest data from REST service with GET method.""" try: with requests.Session() as sess: - response = sess.send(self._request, timeout=10, - verify=self._verify_ssl) + response = sess.send( + self._request, timeout=10, verify=self._verify_ssl) self.data = response.text except requests.exceptions.RequestException: diff --git a/homeassistant/const.py b/homeassistant/const.py index b8cd3a8335330..3c8c74d5bad78 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -87,6 +87,7 @@ CONF_FILE_PATH = 'file_path' CONF_FILENAME = 'filename' CONF_FRIENDLY_NAME = 'friendly_name' +CONF_HEADERS = 'headers' CONF_HOST = 'host' CONF_HOSTS = 'hosts' CONF_ICON = 'icon' From 2cf49f3de6c2c921662bb30fd23050bb835b7a42 Mon Sep 17 00:00:00 2001 From: William Scanlon Date: Tue, 4 Oct 2016 04:07:50 -0400 Subject: [PATCH 070/112] Added support for Wink Smoke and CO detectors (#3645) --- homeassistant/components/binary_sensor/wink.py | 11 ++++++++++- homeassistant/components/wink.py | 2 +- requirements_all.txt | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/binary_sensor/wink.py b/homeassistant/components/binary_sensor/wink.py index 736643fd8dfbd..9813ca213e65f 100644 --- a/homeassistant/components/binary_sensor/wink.py +++ b/homeassistant/components/binary_sensor/wink.py @@ -21,7 +21,9 @@ "loudness": "sound", "liquid_detected": "moisture", "motion": "motion", - "presence": "occupancy" + "presence": "occupancy", + "co_detected": "gas", + "smoke_detected": "smoke" } @@ -36,6 +38,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None): for key in pywink.get_keys(): add_devices([WinkBinarySensorDevice(key)]) + for sensor in pywink.get_smoke_and_co_detectors(): + add_devices([WinkBinarySensorDevice(sensor)]) + class WinkBinarySensorDevice(WinkDevice, BinarySensorDevice, Entity): """Representation of a Wink binary sensor.""" @@ -70,6 +75,10 @@ def is_on(self): state = self.wink.motion_boolean() elif self.capability == "presence": state = self.wink.presence_boolean() + elif self.capability == "co_detected": + state = self.wink.co_detected_boolean() + elif self.capability == "smoke_detected": + state = self.wink.smoke_detected_boolean() else: state = self.wink.state() diff --git a/homeassistant/components/wink.py b/homeassistant/components/wink.py index d4ce99e646312..2e5e7ebcfb4b7 100644 --- a/homeassistant/components/wink.py +++ b/homeassistant/components/wink.py @@ -15,7 +15,7 @@ from homeassistant.helpers.entity import Entity import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['python-wink==0.8.0', 'pubnub==3.8.2'] +REQUIREMENTS = ['python-wink==0.9.0', 'pubnub==3.8.2'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index d80c0aff49ae8..0e85ce33acffc 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -404,7 +404,7 @@ python-telegram-bot==5.1.0 python-twitch==1.3.0 # homeassistant.components.wink -python-wink==0.8.0 +python-wink==0.9.0 # homeassistant.components.keyboard # pyuserinput==0.1.11 From 85782f9c29198e284c68d2e86f5eba8f3576b1e4 Mon Sep 17 00:00:00 2001 From: sam-io Date: Tue, 4 Oct 2016 16:41:39 +0100 Subject: [PATCH 071/112] fix for date formatting issue (#3693) --- homeassistant/components/sensor/imap_email_content.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/sensor/imap_email_content.py b/homeassistant/components/sensor/imap_email_content.py index bea4288f8843a..5af26c072b9d5 100644 --- a/homeassistant/components/sensor/imap_email_content.py +++ b/homeassistant/components/sensor/imap_email_content.py @@ -104,7 +104,7 @@ def read_next(self): self.connection.select() if len(self._unread_ids) == 0: - search = "SINCE {0:%d-%b-%y}".format(datetime.date.today()) + search = "SINCE {0:%d-%b-%Y}".format(datetime.date.today()) if self._last_id is not None: search = "UID {}:*".format(self._last_id) From 5d3e93b4eff6a746edf9ef737296157179605fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Sandstr=C3=B6m?= Date: Tue, 4 Oct 2016 22:01:36 +0200 Subject: [PATCH 072/112] vsure 0.10.3 --- homeassistant/components/verisure.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/verisure.py b/homeassistant/components/verisure.py index 8634184fe5796..e8eabddc440d4 100644 --- a/homeassistant/components/verisure.py +++ b/homeassistant/components/verisure.py @@ -16,7 +16,7 @@ from homeassistant.util import Throttle import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['vsure==0.10.2'] +REQUIREMENTS = ['vsure==0.10.3'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 0e85ce33acffc..9d5821733493d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -500,7 +500,7 @@ urllib3 uvcclient==0.9.0 # homeassistant.components.verisure -vsure==0.10.2 +vsure==0.10.3 # homeassistant.components.switch.wake_on_lan wakeonlan==0.2.2 From 2fd83b439cfbfef1031f5d0bd73299cb3cf07d19 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Tue, 4 Oct 2016 13:25:16 -0700 Subject: [PATCH 073/112] Update .mention-bot to add more users to blacklist and remove skipAlreadyMentionedPR --- .mention-bot | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.mention-bot b/.mention-bot index 2e1f786bf038d..80fbe4cd9f053 100644 --- a/.mention-bot +++ b/.mention-bot @@ -1,6 +1,8 @@ { "userBlacklist": [ - "balloob" - ], - "skipAlreadyMentionedPR": true + "balloob", + "fabaff", + "pavoni", + "rmkraus" + ] } From be7401f4a212f544adcab95a9f784bbed0bb3af1 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Tue, 4 Oct 2016 13:38:56 -0700 Subject: [PATCH 074/112] Now no one wants to be blacklisted, so lets remove the configuration entirely --- .mention-bot | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 .mention-bot diff --git a/.mention-bot b/.mention-bot deleted file mode 100644 index 80fbe4cd9f053..0000000000000 --- a/.mention-bot +++ /dev/null @@ -1,8 +0,0 @@ -{ - "userBlacklist": [ - "balloob", - "fabaff", - "pavoni", - "rmkraus" - ] -} From 5085cdb0f791dfc80def514d6cdd74ce81123bd8 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 4 Oct 2016 20:44:32 -0700 Subject: [PATCH 075/112] Add async_safe annotation (#3688) * Add async_safe annotation * More async_run_job * coroutine -> async_save * Lint * Rename async_safe -> callback * Add tests to core for different job types * Add one more test with different type of callbacks * Fix typing signature for callback methods * Fix callback service executed method * Fix method signatures for callback --- homeassistant/components/automation/event.py | 6 +- homeassistant/components/automation/mqtt.py | 6 +- .../components/automation/numeric_state.py | 6 +- homeassistant/components/automation/state.py | 10 +- homeassistant/components/automation/sun.py | 6 +- .../components/automation/template.py | 6 +- homeassistant/components/automation/time.py | 6 +- homeassistant/components/automation/zone.py | 6 +- .../components/binary_sensor/template.py | 3 +- homeassistant/components/mqtt/__init__.py | 2 +- homeassistant/components/sensor/template.py | 3 +- homeassistant/components/switch/template.py | 3 +- homeassistant/core.py | 58 ++++++-- homeassistant/helpers/event.py | 37 ++--- tests/common.py | 2 +- tests/components/test_api.py | 3 +- tests/helpers/test_event.py | 23 ++-- tests/test_core.py | 130 ++++++++++++++++-- tests/test_remote.py | 2 +- 19 files changed, 231 insertions(+), 87 deletions(-) diff --git a/homeassistant/components/automation/event.py b/homeassistant/components/automation/event.py index ae0f219a01ad2..a51f9fa818770 100644 --- a/homeassistant/components/automation/event.py +++ b/homeassistant/components/automation/event.py @@ -4,11 +4,11 @@ For more details about this automation rule, please refer to the documentation at https://home-assistant.io/components/automation/#event-trigger """ -import asyncio import logging import voluptuous as vol +from homeassistant.core import callback from homeassistant.const import CONF_PLATFORM from homeassistant.helpers import config_validation as cv @@ -29,12 +29,12 @@ def async_trigger(hass, config, action): event_type = config.get(CONF_EVENT_TYPE) event_data = config.get(CONF_EVENT_DATA) - @asyncio.coroutine + @callback def handle_event(event): """Listen for events and calls the action when data matches.""" if not event_data or all(val == event.data.get(key) for key, val in event_data.items()): - hass.async_add_job(action, { + hass.async_run_job(action, { 'trigger': { 'platform': 'event', 'event': event, diff --git a/homeassistant/components/automation/mqtt.py b/homeassistant/components/automation/mqtt.py index 7897a9bc22135..39deae3d66e2d 100644 --- a/homeassistant/components/automation/mqtt.py +++ b/homeassistant/components/automation/mqtt.py @@ -4,9 +4,9 @@ For more details about this automation rule, please refer to the documentation at https://home-assistant.io/components/automation/#mqtt-trigger """ -import asyncio import voluptuous as vol +from homeassistant.core import callback import homeassistant.components.mqtt as mqtt from homeassistant.const import (CONF_PLATFORM, CONF_PAYLOAD) import homeassistant.helpers.config_validation as cv @@ -27,11 +27,11 @@ def async_trigger(hass, config, action): topic = config.get(CONF_TOPIC) payload = config.get(CONF_PAYLOAD) - @asyncio.coroutine + @callback def mqtt_automation_listener(msg_topic, msg_payload, qos): """Listen for MQTT messages.""" if payload is None or payload == msg_payload: - hass.async_add_job(action, { + hass.async_run_job(action, { 'trigger': { 'platform': 'mqtt', 'topic': msg_topic, diff --git a/homeassistant/components/automation/numeric_state.py b/homeassistant/components/automation/numeric_state.py index 4d6cdc21190c3..9c3ac7d839647 100644 --- a/homeassistant/components/automation/numeric_state.py +++ b/homeassistant/components/automation/numeric_state.py @@ -4,11 +4,11 @@ For more details about this automation rule, please refer to the documentation at https://home-assistant.io/components/automation/#numeric-state-trigger """ -import asyncio import logging import voluptuous as vol +from homeassistant.core import callback from homeassistant.const import ( CONF_VALUE_TEMPLATE, CONF_PLATFORM, CONF_ENTITY_ID, CONF_BELOW, CONF_ABOVE) @@ -35,7 +35,7 @@ def async_trigger(hass, config, action): if value_template is not None: value_template.hass = hass - @asyncio.coroutine + @callback def state_automation_listener(entity, from_s, to_s): """Listen for state changes and calls action.""" if to_s is None: @@ -64,6 +64,6 @@ def state_automation_listener(entity, from_s, to_s): variables['trigger']['from_state'] = from_s variables['trigger']['to_state'] = to_s - hass.async_add_job(action, variables) + hass.async_run_job(action, variables) return async_track_state_change(hass, entity_id, state_automation_listener) diff --git a/homeassistant/components/automation/state.py b/homeassistant/components/automation/state.py index 0649834ff3306..fb1469916023c 100644 --- a/homeassistant/components/automation/state.py +++ b/homeassistant/components/automation/state.py @@ -4,9 +4,9 @@ For more details about this automation rule, please refer to the documentation at https://home-assistant.io/components/automation/#state-trigger """ -import asyncio import voluptuous as vol +from homeassistant.core import callback import homeassistant.util.dt as dt_util from homeassistant.const import MATCH_ALL, CONF_PLATFORM from homeassistant.helpers.event import ( @@ -43,14 +43,14 @@ def async_trigger(hass, config, action): async_remove_state_for_cancel = None async_remove_state_for_listener = None - @asyncio.coroutine + @callback def state_automation_listener(entity, from_s, to_s): """Listen for state changes and calls action.""" nonlocal async_remove_state_for_cancel, async_remove_state_for_listener def call_action(): """Call action with right context.""" - hass.async_add_job(action, { + hass.async_run_job(action, { 'trigger': { 'platform': 'state', 'entity_id': entity, @@ -64,13 +64,13 @@ def call_action(): call_action() return - @asyncio.coroutine + @callback def state_for_listener(now): """Fire on state changes after a delay and calls action.""" async_remove_state_for_cancel() call_action() - @asyncio.coroutine + @callback def state_for_cancel_listener(entity, inner_from_s, inner_to_s): """Fire on changes and cancel for listener if changed.""" if inner_to_s.state == to_s.state: diff --git a/homeassistant/components/automation/sun.py b/homeassistant/components/automation/sun.py index 9892707a13987..2baa0726813ae 100644 --- a/homeassistant/components/automation/sun.py +++ b/homeassistant/components/automation/sun.py @@ -4,12 +4,12 @@ For more details about this automation rule, please refer to the documentation at https://home-assistant.io/components/automation/#sun-trigger """ -import asyncio from datetime import timedelta import logging import voluptuous as vol +from homeassistant.core import callback from homeassistant.const import ( CONF_EVENT, CONF_OFFSET, CONF_PLATFORM, SUN_EVENT_SUNRISE) from homeassistant.helpers.event import async_track_sunrise, async_track_sunset @@ -31,10 +31,10 @@ def async_trigger(hass, config, action): event = config.get(CONF_EVENT) offset = config.get(CONF_OFFSET) - @asyncio.coroutine + @callback def call_action(): """Call action with right context.""" - hass.async_add_job(action, { + hass.async_run_job(action, { 'trigger': { 'platform': 'sun', 'event': event, diff --git a/homeassistant/components/automation/template.py b/homeassistant/components/automation/template.py index 94f57dbbc02d1..90d75d0d98200 100644 --- a/homeassistant/components/automation/template.py +++ b/homeassistant/components/automation/template.py @@ -4,11 +4,11 @@ For more details about this automation rule, please refer to the documentation at https://home-assistant.io/components/automation/#template-trigger """ -import asyncio import logging import voluptuous as vol +from homeassistant.core import callback from homeassistant.const import CONF_VALUE_TEMPLATE, CONF_PLATFORM from homeassistant.helpers import condition from homeassistant.helpers.event import async_track_state_change @@ -31,7 +31,7 @@ def async_trigger(hass, config, action): # Local variable to keep track of if the action has already been triggered already_triggered = False - @asyncio.coroutine + @callback def state_changed_listener(entity_id, from_s, to_s): """Listen for state changes and calls action.""" nonlocal already_triggered @@ -40,7 +40,7 @@ def state_changed_listener(entity_id, from_s, to_s): # Check to see if template returns true if template_result and not already_triggered: already_triggered = True - hass.async_add_job(action, { + hass.async_run_job(action, { 'trigger': { 'platform': 'template', 'entity_id': entity_id, diff --git a/homeassistant/components/automation/time.py b/homeassistant/components/automation/time.py index 190a651927831..d0315f26de08f 100644 --- a/homeassistant/components/automation/time.py +++ b/homeassistant/components/automation/time.py @@ -4,11 +4,11 @@ For more details about this automation rule, please refer to the documentation at https://home-assistant.io/components/automation/#time-trigger """ -import asyncio import logging import voluptuous as vol +from homeassistant.core import callback from homeassistant.const import CONF_AFTER, CONF_PLATFORM from homeassistant.helpers import config_validation as cv from homeassistant.helpers.event import async_track_time_change @@ -39,10 +39,10 @@ def async_trigger(hass, config, action): minutes = config.get(CONF_MINUTES) seconds = config.get(CONF_SECONDS) - @asyncio.coroutine + @callback def time_automation_listener(now): """Listen for time changes and calls action.""" - hass.async_add_job(action, { + hass.async_run_job(action, { 'trigger': { 'platform': 'time', 'now': now, diff --git a/homeassistant/components/automation/zone.py b/homeassistant/components/automation/zone.py index 59812738692fa..935dc3cf24c69 100644 --- a/homeassistant/components/automation/zone.py +++ b/homeassistant/components/automation/zone.py @@ -4,9 +4,9 @@ For more details about this automation rule, please refer to the documentation at https://home-assistant.io/components/automation/#zone-trigger """ -import asyncio import voluptuous as vol +from homeassistant.core import callback from homeassistant.const import ( CONF_EVENT, CONF_ENTITY_ID, CONF_ZONE, MATCH_ALL, CONF_PLATFORM) from homeassistant.helpers.event import async_track_state_change @@ -32,7 +32,7 @@ def async_trigger(hass, config, action): zone_entity_id = config.get(CONF_ZONE) event = config.get(CONF_EVENT) - @asyncio.coroutine + @callback def zone_automation_listener(entity, from_s, to_s): """Listen for state changes and calls action.""" if from_s and not location.has_location(from_s) or \ @@ -49,7 +49,7 @@ def zone_automation_listener(entity, from_s, to_s): # pylint: disable=too-many-boolean-expressions if event == EVENT_ENTER and not from_match and to_match or \ event == EVENT_LEAVE and from_match and not to_match: - hass.async_add_job(action, { + hass.async_run_job(action, { 'trigger': { 'platform': 'zone', 'entity_id': entity, diff --git a/homeassistant/components/binary_sensor/template.py b/homeassistant/components/binary_sensor/template.py index 339a5cb9ba122..d179edfc1d858 100644 --- a/homeassistant/components/binary_sensor/template.py +++ b/homeassistant/components/binary_sensor/template.py @@ -9,6 +9,7 @@ import voluptuous as vol +from homeassistant.core import callback from homeassistant.components.binary_sensor import ( BinarySensorDevice, ENTITY_ID_FORMAT, PLATFORM_SCHEMA, SENSOR_CLASSES_SCHEMA) @@ -82,7 +83,7 @@ def __init__(self, hass, device, friendly_name, sensor_class, self.update() - @asyncio.coroutine + @callback def template_bsensor_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" hass.loop.create_task(self.async_update_ha_state(True)) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 7995d9bf39ae2..3edd0ffc500bc 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -171,7 +171,7 @@ def mqtt_topic_subscriber(event): if not _match_topic(topic, event.data[ATTR_TOPIC]): return - hass.async_add_job(callback, event.data[ATTR_TOPIC], + hass.async_run_job(callback, event.data[ATTR_TOPIC], event.data[ATTR_PAYLOAD], event.data[ATTR_QOS]) async_remove = hass.bus.async_listen(EVENT_MQTT_MESSAGE_RECEIVED, diff --git a/homeassistant/components/sensor/template.py b/homeassistant/components/sensor/template.py index ed905f44ebd58..1abd1d2fd9493 100644 --- a/homeassistant/components/sensor/template.py +++ b/homeassistant/components/sensor/template.py @@ -9,6 +9,7 @@ import voluptuous as vol +from homeassistant.core import callback from homeassistant.components.sensor import ENTITY_ID_FORMAT, PLATFORM_SCHEMA from homeassistant.const import ( ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT, CONF_VALUE_TEMPLATE, @@ -79,7 +80,7 @@ def __init__(self, hass, device_id, friendly_name, unit_of_measurement, self.update() - @asyncio.coroutine + @callback def template_sensor_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" hass.loop.create_task(self.async_update_ha_state(True)) diff --git a/homeassistant/components/switch/template.py b/homeassistant/components/switch/template.py index bcd74454ce54a..b6ce400d0acc4 100644 --- a/homeassistant/components/switch/template.py +++ b/homeassistant/components/switch/template.py @@ -9,6 +9,7 @@ import voluptuous as vol +from homeassistant.core import callback from homeassistant.components.switch import ( ENTITY_ID_FORMAT, SwitchDevice, PLATFORM_SCHEMA) from homeassistant.const import ( @@ -88,7 +89,7 @@ def __init__(self, hass, device_id, friendly_name, state_template, self.update() - @asyncio.coroutine + @callback def template_switch_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" hass.loop.create_task(self.async_update_ha_state(True)) diff --git a/homeassistant/core.py b/homeassistant/core.py index 83056d6d7f260..0e0d19539924b 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -78,6 +78,18 @@ def valid_entity_id(entity_id: str) -> bool: return ENTITY_ID_PATTERN.match(entity_id) is not None +def callback(func: Callable[..., None]) -> Callable[..., None]: + """Annotation to mark method as safe to call from within the event loop.""" + # pylint: disable=protected-access + func._hass_callback = True + return func + + +def is_callback(func: Callable[..., Any]) -> bool: + """Check if function is safe to be called in the event loop.""" + return '_hass_callback' in func.__dict__ + + class CoreState(enum.Enum): """Represent the current state of Home Assistant.""" @@ -224,11 +236,24 @@ def async_add_job(self, target: Callable[..., None], *args: Any): target: target to call. args: parameters for method to call. """ - if asyncio.iscoroutinefunction(target): + if is_callback(target): + self.loop.call_soon(target, *args) + elif asyncio.iscoroutinefunction(target): self.loop.create_task(target(*args)) else: self.add_job(target, *args) + def async_run_job(self, target: Callable[..., None], *args: Any): + """Run a job from within the event loop. + + target: target to call. + args: parameters for method to call. + """ + if is_callback(target): + target(*args) + else: + self.async_add_job(target, *args) + def _loop_empty(self): """Python 3.4.2 empty loop compatibility function.""" # pylint: disable=protected-access @@ -380,7 +405,6 @@ def fire(self, event_type: str, event_data=None, origin=EventOrigin.local): self._loop.call_soon_threadsafe(self.async_fire, event_type, event_data, origin) - return def async_fire(self, event_type: str, event_data=None, origin=EventOrigin.local, wait=False): @@ -408,6 +432,8 @@ def async_fire(self, event_type: str, event_data=None, for func in listeners: if asyncio.iscoroutinefunction(func): self._loop.create_task(func(event)) + elif is_callback(func): + self._loop.call_soon(func, event) else: sync_jobs.append((job_priority, (func, event))) @@ -795,7 +821,7 @@ class Service(object): """Represents a callable service.""" __slots__ = ['func', 'description', 'fields', 'schema', - 'iscoroutinefunction'] + 'is_callback', 'is_coroutinefunction'] def __init__(self, func, description, fields, schema): """Initialize a service.""" @@ -803,7 +829,8 @@ def __init__(self, func, description, fields, schema): self.description = description or '' self.fields = fields or {} self.schema = schema - self.iscoroutinefunction = asyncio.iscoroutinefunction(func) + self.is_callback = is_callback(func) + self.is_coroutinefunction = asyncio.iscoroutinefunction(func) def as_dict(self): """Return dictionary representation of this service.""" @@ -934,7 +961,7 @@ def call(self, domain, service, service_data=None, blocking=False): self._loop ).result() - @asyncio.coroutine + @callback def async_call(self, domain, service, service_data=None, blocking=False): """ Call a service. @@ -966,7 +993,7 @@ def async_call(self, domain, service, service_data=None, blocking=False): if blocking: fut = asyncio.Future(loop=self._loop) - @asyncio.coroutine + @callback def service_executed(event): """Callback method that is called when service is executed.""" if event.data[ATTR_SERVICE_CALL_ID] == call_id: @@ -1007,7 +1034,8 @@ def fire_service_executed(): data = {ATTR_SERVICE_CALL_ID: call_id} - if service_handler.iscoroutinefunction: + if (service_handler.is_coroutinefunction or + service_handler.is_callback): self._bus.async_fire(EVENT_SERVICE_EXECUTED, data) else: self._bus.fire(EVENT_SERVICE_EXECUTED, data) @@ -1023,17 +1051,19 @@ def fire_service_executed(): service_call = ServiceCall(domain, service, service_data, call_id) - if not service_handler.iscoroutinefunction: + if service_handler.is_callback: + service_handler.func(service_call) + fire_service_executed() + elif service_handler.is_coroutinefunction: + yield from service_handler.func(service_call) + fire_service_executed() + else: def execute_service(): """Execute a service and fires a SERVICE_EXECUTED event.""" service_handler.func(service_call) fire_service_executed() self._add_job(execute_service, priority=JobPriority.EVENT_SERVICE) - return - - yield from service_handler.func(service_call) - fire_service_executed() def _generate_unique_id(self): """Generate a unique service call id.""" @@ -1098,7 +1128,7 @@ def async_create_timer(hass, interval=TIMER_INTERVAL): stop_event = asyncio.Event(loop=hass.loop) # Setting the Event inside the loop by marking it as a coroutine - @asyncio.coroutine + @callback def stop_timer(event): """Stop the timer.""" stop_event.set() @@ -1212,7 +1242,7 @@ def check_pool_threshold(): schedule() - @asyncio.coroutine + @callback def stop_monitor(event): """Stop the monitor.""" handle.cancel() diff --git a/homeassistant/helpers/event.py b/homeassistant/helpers/event.py index 69f620adb8232..390af3c7ad15b 100644 --- a/homeassistant/helpers/event.py +++ b/homeassistant/helpers/event.py @@ -1,9 +1,8 @@ """Helpers for listening to events.""" -import asyncio import functools as ft from datetime import timedelta -from ..core import HomeAssistant +from ..core import HomeAssistant, callback from ..const import ( ATTR_NOW, EVENT_STATE_CHANGED, EVENT_TIME_CHANGED, MATCH_ALL) from ..util import dt as dt_util @@ -57,8 +56,7 @@ def async_track_state_change(hass, entity_ids, action, from_state=None, else: entity_ids = tuple(entity_id.lower() for entity_id in entity_ids) - @ft.wraps(action) - @asyncio.coroutine + @callback def state_change_listener(event): """The listener that listens for specific state changes.""" if entity_ids != MATCH_ALL and \ @@ -76,7 +74,7 @@ def state_change_listener(event): new_state = None if _matcher(old_state, from_state) and _matcher(new_state, to_state): - hass.async_add_job(action, event.data.get('entity_id'), + hass.async_run_job(action, event.data.get('entity_id'), event.data.get('old_state'), event.data.get('new_state')) @@ -90,11 +88,10 @@ def async_track_point_in_time(hass, action, point_in_time): """Add a listener that fires once after a spefic point in time.""" utc_point_in_time = dt_util.as_utc(point_in_time) - @ft.wraps(action) - @asyncio.coroutine + @callback def utc_converter(utc_now): """Convert passed in UTC now to local now.""" - hass.async_add_job(action, dt_util.as_local(utc_now)) + hass.async_run_job(action, dt_util.as_local(utc_now)) return async_track_point_in_utc_time(hass, utc_converter, utc_point_in_time) @@ -108,8 +105,7 @@ def async_track_point_in_utc_time(hass, action, point_in_time): # Ensure point_in_time is UTC point_in_time = dt_util.as_utc(point_in_time) - @ft.wraps(action) - @asyncio.coroutine + @callback def point_in_time_listener(event): """Listen for matching time_changed events.""" now = event.data[ATTR_NOW] @@ -125,7 +121,7 @@ def point_in_time_listener(event): point_in_time_listener.run = True async_unsub() - hass.async_add_job(action, now) + hass.async_run_job(action, now) async_unsub = hass.bus.async_listen(EVENT_TIME_CHANGED, point_in_time_listener) @@ -151,14 +147,13 @@ def next_rise(): return next_time - @ft.wraps(action) - @asyncio.coroutine + @callback def sunrise_automation_listener(now): """Called when it's time for action.""" nonlocal remove remove = async_track_point_in_utc_time( hass, sunrise_automation_listener, next_rise()) - hass.async_add_job(action) + hass.async_run_job(action) remove = async_track_point_in_utc_time( hass, sunrise_automation_listener, next_rise()) @@ -187,14 +182,13 @@ def next_set(): return next_time - @ft.wraps(action) - @asyncio.coroutine + @callback def sunset_automation_listener(now): """Called when it's time for action.""" nonlocal remove remove = async_track_point_in_utc_time( hass, sunset_automation_listener, next_set()) - hass.async_add_job(action) + hass.async_run_job(action) remove = async_track_point_in_utc_time( hass, sunset_automation_listener, next_set()) @@ -217,10 +211,10 @@ def async_track_utc_time_change(hass, action, year=None, month=None, day=None, # We do not have to wrap the function with time pattern matching logic # if no pattern given if all(val is None for val in (year, month, day, hour, minute, second)): - @ft.wraps(action) + @callback def time_change_listener(event): """Fire every time event that comes in.""" - action(event.data[ATTR_NOW]) + hass.async_run_job(action, event.data[ATTR_NOW]) return hass.bus.async_listen(EVENT_TIME_CHANGED, time_change_listener) @@ -228,8 +222,7 @@ def time_change_listener(event): year, month, day = pmp(year), pmp(month), pmp(day) hour, minute, second = pmp(hour), pmp(minute), pmp(second) - @ft.wraps(action) - @asyncio.coroutine + @callback def pattern_time_change_listener(event): """Listen for matching time_changed events.""" now = event.data[ATTR_NOW] @@ -246,7 +239,7 @@ def pattern_time_change_listener(event): mat(now.minute, minute) and \ mat(now.second, second): - hass.async_add_job(action, now) + hass.async_run_job(action, now) return hass.bus.async_listen(EVENT_TIME_CHANGED, pattern_time_change_listener) diff --git a/tests/common.py b/tests/common.py index b44cbee4b6fef..fb5dab7004b3b 100644 --- a/tests/common.py +++ b/tests/common.py @@ -111,7 +111,7 @@ def mock_service(hass, domain, service): """ calls = [] - hass.services.register(domain, service, calls.append) + hass.services.register(domain, service, lambda call: calls.append(call)) return calls diff --git a/tests/components/test_api.py b/tests/components/test_api.py index 4e7d98cd6cce0..dee4320824b37 100644 --- a/tests/components/test_api.py +++ b/tests/components/test_api.py @@ -139,7 +139,8 @@ def test_api_state_change_push(self): hass.states.set("test.test", "not_to_be_set") events = [] - hass.bus.listen(const.EVENT_STATE_CHANGED, events.append) + hass.bus.listen(const.EVENT_STATE_CHANGED, + lambda ev: events.append(ev)) requests.post(_url(const.URL_API_STATES_ENTITY.format("test.test")), data=json.dumps({"state": "not_to_be_set"}), diff --git a/tests/helpers/test_event.py b/tests/helpers/test_event.py index 4993ce92b3a86..89c97434f8dc0 100644 --- a/tests/helpers/test_event.py +++ b/tests/helpers/test_event.py @@ -1,6 +1,7 @@ """Test event helpers.""" # pylint: disable=protected-access,too-many-public-methods # pylint: disable=too-few-public-methods +import asyncio import unittest from datetime import datetime, timedelta @@ -113,17 +114,23 @@ def test_track_state_change(self): wildcard_runs = [] wildercard_runs = [] - track_state_change( - self.hass, 'light.Bowl', lambda a, b, c: specific_runs.append(1), - 'on', 'off') + def specific_run_callback(entity_id, old_state, new_state): + specific_runs.append(1) track_state_change( - self.hass, 'light.Bowl', - lambda _, old_s, new_s: wildcard_runs.append((old_s, new_s))) + self.hass, 'light.Bowl', specific_run_callback, 'on', 'off') - track_state_change( - self.hass, MATCH_ALL, - lambda _, old_s, new_s: wildercard_runs.append((old_s, new_s))) + @ha.callback + def wildcard_run_callback(entity_id, old_state, new_state): + wildcard_runs.append((old_state, new_state)) + + track_state_change(self.hass, 'light.Bowl', wildcard_run_callback) + + @asyncio.coroutine + def wildercard_run_callback(entity_id, old_state, new_state): + wildercard_runs.append((old_state, new_state)) + + track_state_change(self.hass, MATCH_ALL, wildercard_run_callback) # Adding state to state machine self.hass.states.set("light.Bowl", "on") diff --git a/tests/test_core.py b/tests/test_core.py index 80a8c6d4c5f37..6f480baa71bf1 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -23,13 +23,70 @@ PST = pytz.timezone('America/Los_Angeles') -class TestMethods(unittest.TestCase): - """Test the Home Assistant helper methods.""" +def test_split_entity_id(): + """Test split_entity_id.""" + assert ha.split_entity_id('domain.object_id') == ['domain', 'object_id'] - def test_split_entity_id(self): - """Test split_entity_id.""" - self.assertEqual(['domain', 'object_id'], - ha.split_entity_id('domain.object_id')) + +def test_async_add_job_schedule_callback(): + """Test that we schedule coroutines and add jobs to the job pool.""" + hass = MagicMock() + job = MagicMock() + + ha.HomeAssistant.async_add_job(hass, ha.callback(job)) + assert len(hass.loop.call_soon.mock_calls) == 1 + assert len(hass.loop.create_task.mock_calls) == 0 + assert len(hass.add_job.mock_calls) == 0 + + +@patch('asyncio.iscoroutinefunction', return_value=True) +def test_async_add_job_schedule_coroutinefunction(mock_iscoro): + """Test that we schedule coroutines and add jobs to the job pool.""" + hass = MagicMock() + job = MagicMock() + + ha.HomeAssistant.async_add_job(hass, job) + assert len(hass.loop.call_soon.mock_calls) == 0 + assert len(hass.loop.create_task.mock_calls) == 1 + assert len(hass.add_job.mock_calls) == 0 + + +@patch('asyncio.iscoroutinefunction', return_value=False) +def test_async_add_job_add_threaded_job_to_pool(mock_iscoro): + """Test that we schedule coroutines and add jobs to the job pool.""" + hass = MagicMock() + job = MagicMock() + + ha.HomeAssistant.async_add_job(hass, job) + assert len(hass.loop.call_soon.mock_calls) == 0 + assert len(hass.loop.create_task.mock_calls) == 0 + assert len(hass.add_job.mock_calls) == 1 + + +def test_async_run_job_calls_callback(): + """Test that the callback annotation is respected.""" + hass = MagicMock() + calls = [] + + def job(): + calls.append(1) + + ha.HomeAssistant.async_run_job(hass, ha.callback(job)) + assert len(calls) == 1 + assert len(hass.async_add_job.mock_calls) == 0 + + +def test_async_run_job_delegates_non_async(): + """Test that the callback annotation is respected.""" + hass = MagicMock() + calls = [] + + def job(): + calls.append(1) + + ha.HomeAssistant.async_run_job(hass, job) + assert len(calls) == 0 + assert len(hass.async_add_job.mock_calls) == 1 class TestHomeAssistant(unittest.TestCase): @@ -173,6 +230,44 @@ def test_listen_once_event(self): self.hass.block_till_done() self.assertEqual(1, len(runs)) + def test_thread_event_listener(self): + """Test a event listener listeners.""" + thread_calls = [] + + def thread_listener(event): + thread_calls.append(event) + + self.bus.listen('test_thread', thread_listener) + self.bus.fire('test_thread') + self.hass.block_till_done() + assert len(thread_calls) == 1 + + def test_callback_event_listener(self): + """Test a event listener listeners.""" + callback_calls = [] + + @ha.callback + def callback_listener(event): + callback_calls.append(event) + + self.bus.listen('test_callback', callback_listener) + self.bus.fire('test_callback') + self.hass.block_till_done() + assert len(callback_calls) == 1 + + def test_coroutine_event_listener(self): + """Test a event listener listeners.""" + coroutine_calls = [] + + @asyncio.coroutine + def coroutine_listener(event): + coroutine_calls.append(event) + + self.bus.listen('test_coroutine', coroutine_listener) + self.bus.fire('test_coroutine') + self.hass.block_till_done() + assert len(coroutine_calls) == 1 + class TestState(unittest.TestCase): """Test State methods.""" @@ -330,7 +425,7 @@ def test_last_changed_not_updated_on_same_state(self): def test_force_update(self): """Test force update option.""" events = [] - self.hass.bus.listen(EVENT_STATE_CHANGED, events.append) + self.hass.bus.listen(EVENT_STATE_CHANGED, lambda ev: events.append(ev)) self.states.set('light.bowl', 'on') self.hass.block_till_done() @@ -425,6 +520,22 @@ def service_handler(call): self.hass.block_till_done() self.assertEqual(1, len(calls)) + def test_callback_service(self): + """Test registering and calling an async service.""" + calls = [] + + @ha.callback + def service_handler(call): + """Service handler coroutine.""" + calls.append(call) + + self.services.register('test_domain', 'register_calls', + service_handler) + self.assertTrue( + self.services.call('test_domain', 'REGISTER_CALLS', blocking=True)) + self.hass.block_till_done() + self.assertEqual(1, len(calls)) + class TestConfig(unittest.TestCase): """Test configuration methods.""" @@ -524,8 +635,7 @@ def test_worker_pool_monitor(self, mock_warning, event_loop): check_threshold() assert mock_warning.called - event_loop.run_until_complete( - hass.bus.async_listen_once.mock_calls[0][1][1](None)) + hass.bus.async_listen_once.mock_calls[0][1][1](None) assert schedule_handle.cancel.called @@ -561,5 +671,5 @@ def test_create_timer(self, mock_utcnow, mock_event, event_loop): assert {ha.ATTR_NOW: now} == event_data stop_timer = hass.bus.async_listen_once.mock_calls[0][1][1] - event_loop.run_until_complete(stop_timer(None)) + stop_timer(None) assert event.set.called diff --git a/tests/test_remote.py b/tests/test_remote.py index a5212face2c6c..653971f8bc1c6 100644 --- a/tests/test_remote.py +++ b/tests/test_remote.py @@ -163,7 +163,7 @@ def test_set_state(self): def test_set_state_with_push(self): """Test Python API set_state with push option.""" events = [] - hass.bus.listen(EVENT_STATE_CHANGED, events.append) + hass.bus.listen(EVENT_STATE_CHANGED, lambda ev: events.append(ev)) remote.set_state(master_api, 'test.test', 'set_test_2') remote.set_state(master_api, 'test.test', 'set_test_2') From 0bf8bb62ad84833aba1abc6b084beddf3a2cdd7a Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Wed, 5 Oct 2016 06:00:36 +0200 Subject: [PATCH 076/112] Service & signal (stop/restart) fix (#3690) * Bugfix signhandling/services * change from coroutine to callback * add error handling * fix bug with endless running * fix unit test * Revert "fix unit test" This reverts commit 31135c770923161f7afb3a31f4dd4fea99533a9c. * Disable sigterm/sighup test --- homeassistant/core.py | 40 +++++++++++++++++++++------------------- tests/test_core.py | 25 +++++++++++++------------ 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/homeassistant/core.py b/homeassistant/core.py index 0e0d19539924b..bfca43723e5ae 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -158,17 +158,15 @@ def start(self) -> None: # Register the async start self.loop.create_task(self.async_start()) - @asyncio.coroutine def stop_homeassistant(*args): """Stop Home Assistant.""" self.exit_code = 0 - yield from self.async_stop() + self.async_add_job(self.async_stop) - @asyncio.coroutine def restart_homeassistant(*args): """Restart Home Assistant.""" self.exit_code = RESTART_EXIT_CODE - yield from self.async_stop() + self.async_add_job(self.async_stop) # Register the restart/stop event self.loop.call_soon( @@ -181,18 +179,22 @@ def restart_homeassistant(*args): ) # Setup signal handling - try: - signal.signal(signal.SIGTERM, stop_homeassistant) - except ValueError: - _LOGGER.warning( - 'Could not bind to SIGTERM. Are you running in a thread?') - try: - signal.signal(signal.SIGHUP, restart_homeassistant) - except ValueError: - _LOGGER.warning( - 'Could not bind to SIGHUP. Are you running in a thread?') - except AttributeError: - pass + if sys.platform != 'win32': + try: + self.loop.add_signal_handler( + signal.SIGTERM, + stop_homeassistant + ) + except ValueError: + _LOGGER.warning('Could not bind to SIGTERM.') + + try: + self.loop.add_signal_handler( + signal.SIGHUP, + restart_homeassistant + ) + except ValueError: + _LOGGER.warning('Could not bind to SIGHUP.') # Run forever and catch keyboard interrupt try: @@ -200,10 +202,10 @@ def restart_homeassistant(*args): _LOGGER.info("Starting Home Assistant core loop") self.loop.run_forever() except KeyboardInterrupt: - pass - finally: - self.loop.create_task(stop_homeassistant()) + self.loop.call_soon(stop_homeassistant) self.loop.run_forever() + finally: + self.loop.close() @asyncio.coroutine def async_start(self): diff --git a/tests/test_core.py b/tests/test_core.py index 6f480baa71bf1..ab96fc59e07a3 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -100,24 +100,25 @@ def tearDown(self): # pylint: disable=invalid-name """Stop everything that was started.""" self.hass.stop() - def test_start_and_sigterm(self): - """Start the test.""" - calls = [] - self.hass.bus.listen_once(EVENT_HOMEASSISTANT_START, - lambda event: calls.append(1)) + # This test hangs on `loop.add_signal_handler` + # def test_start_and_sigterm(self): + # """Start the test.""" + # calls = [] + # self.hass.bus.listen_once(EVENT_HOMEASSISTANT_START, + # lambda event: calls.append(1)) - self.hass.start() + # self.hass.start() - self.assertEqual(1, len(calls)) + # self.assertEqual(1, len(calls)) - self.hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, - lambda event: calls.append(1)) + # self.hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, + # lambda event: calls.append(1)) - os.kill(os.getpid(), signal.SIGTERM) + # os.kill(os.getpid(), signal.SIGTERM) - self.hass.block_till_done() + # self.hass.block_till_done() - self.assertEqual(1, len(calls)) + # self.assertEqual(1, len(calls)) class TestEvent(unittest.TestCase): From d2d393feb53e32cffb98a8b0ad610c14a373733e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=B8yer=20Iversen?= Date: Wed, 5 Oct 2016 06:20:48 +0200 Subject: [PATCH 077/112] Add automations and scripts to group.all_automations and group.all_scripts (#3664) * Add automations to group.all_automations * Add scripts to group.all_scripts --- homeassistant/components/automation/__init__.py | 5 ++++- homeassistant/components/script.py | 4 +++- tests/components/automation/test_init.py | 4 ++++ tests/components/test_script.py | 4 ++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index 579d4b400035c..25754d32ead16 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -31,6 +31,8 @@ DEPENDENCIES = ['group'] +GROUP_NAME_ALL_AUTOMATIONS = 'all automations' + CONF_ALIAS = 'alias' CONF_HIDE_ENTITY = 'hide_entity' @@ -139,7 +141,8 @@ def reload(hass): def setup(hass, config): """Setup the automation.""" - component = EntityComponent(_LOGGER, DOMAIN, hass) + component = EntityComponent(_LOGGER, DOMAIN, hass, + group_name=GROUP_NAME_ALL_AUTOMATIONS) success = run_coroutine_threadsafe( _async_process_config(hass, config, component), hass.loop).result() diff --git a/homeassistant/components/script.py b/homeassistant/components/script.py index 961c37f896a08..dfaa6b250b046 100644 --- a/homeassistant/components/script.py +++ b/homeassistant/components/script.py @@ -23,6 +23,7 @@ DOMAIN = "script" ENTITY_ID_FORMAT = DOMAIN + '.{}' +GROUP_NAME_ALL_SCRIPTS = 'all scripts' DEPENDENCIES = ["group"] CONF_SEQUENCE = "sequence" @@ -73,7 +74,8 @@ def toggle(hass, entity_id): def setup(hass, config): """Load the scripts from the configuration.""" - component = EntityComponent(_LOGGER, DOMAIN, hass) + component = EntityComponent(_LOGGER, DOMAIN, hass, + group_name=GROUP_NAME_ALL_SCRIPTS) def service_handler(service): """Execute a service call to script. \ No newline at end of file +},customStyle:null,getComputedStyleValue:function(e){return!i&&this._styleProperties&&this._styleProperties[e]||getComputedStyle(this).getPropertyValue(e)},_setupStyleProperties:function(){this.customStyle={},this._styleCache=null,this._styleProperties=null,this._scopeSelector=null,this._ownStyleProperties=null,this._customStyle=null},_needsStyleProperties:function(){return Boolean(!i&&this._ownStylePropertyNames&&this._ownStylePropertyNames.length)},_validateApplyShim:function(){if(this.__applyShimInvalid){Polymer.ApplyShim.transform(this._styles,this.__proto__);var e=n.elementStyles(this);if(s){var t=this._template.content.querySelector("style");t&&(t.textContent=e)}else{var r=this._scopeStyle&&this._scopeStyle.nextSibling;r&&(r.textContent=e)}}},_beforeAttached:function(){this._scopeSelector&&!this.__stylePropertiesInvalid||!this._needsStyleProperties()||(this.__stylePropertiesInvalid=!1,this._updateStyleProperties())},_findStyleHost:function(){for(var e,t=this;e=Polymer.dom(t).getOwnerRoot();){if(Polymer.isInstance(e.host))return e.host;t=e.host}return r},_updateStyleProperties:function(){var e,n=this._findStyleHost();n._styleProperties||n._computeStyleProperties(),n._styleCache||(n._styleCache=new Polymer.StyleCache);var r=t.propertyDataFromStyles(n._styles,this),i=!this.__notStyleScopeCacheable;i&&(r.key.customStyle=this.customStyle,e=n._styleCache.retrieve(this.is,r.key,this._styles));var a=Boolean(e);a?this._styleProperties=e._styleProperties:this._computeStyleProperties(r.properties),this._computeOwnStyleProperties(),a||(e=o.retrieve(this.is,this._ownStyleProperties,this._styles));var l=Boolean(e)&&!a,c=this._applyStyleProperties(e);a||(c=c&&s?c.cloneNode(!0):c,e={style:c,_scopeSelector:this._scopeSelector,_styleProperties:this._styleProperties},i&&(r.key.customStyle={},this.mixin(r.key.customStyle,this.customStyle),n._styleCache.store(this.is,e,r.key,this._styles)),l||o.store(this.is,Object.create(e),this._ownStyleProperties,this._styles))},_computeStyleProperties:function(e){var n=this._findStyleHost();n._styleProperties||n._computeStyleProperties();var r=Object.create(n._styleProperties),s=t.hostAndRootPropertiesForScope(this);this.mixin(r,s.hostProps),e=e||t.propertyDataFromStyles(n._styles,this).properties,this.mixin(r,e),this.mixin(r,s.rootProps),t.mixinCustomStyle(r,this.customStyle),t.reify(r),this._styleProperties=r},_computeOwnStyleProperties:function(){for(var e,t={},n=0;n0&&l.push(t);return[{removed:a,added:l}]}},Polymer.Collection.get=function(e){return Polymer._collections.get(e)||new Polymer.Collection(e)},Polymer.Collection.applySplices=function(e,t){var n=Polymer._collections.get(e);return n?n._applySplices(t):null},Polymer({is:"dom-repeat",extends:"template",_template:null,properties:{items:{type:Array},as:{type:String,value:"item"},indexAs:{type:String,value:"index"},sort:{type:Function,observer:"_sortChanged"},filter:{type:Function,observer:"_filterChanged"},observe:{type:String,observer:"_observeChanged"},delay:Number,renderedItemCount:{type:Number,notify:!0,readOnly:!0},initialCount:{type:Number,observer:"_initializeChunking"},targetFramerate:{type:Number,value:20},_targetFrameTime:{type:Number,computed:"_computeFrameTime(targetFramerate)"}},behaviors:[Polymer.Templatizer],observers:["_itemsChanged(items.*)"],created:function(){this._instances=[],this._pool=[],this._limit=1/0;var e=this;this._boundRenderChunk=function(){e._renderChunk()}},detached:function(){this.__isDetached=!0;for(var e=0;e=0;t--){var n=this._instances[t];n.isPlaceholder&&t=this._limit&&(n=this._downgradeInstance(t,n.__key__)),e[n.__key__]=t,n.isPlaceholder||n.__setProperty(this.indexAs,t,!0)}this._pool.length=0,this._setRenderedItemCount(this._instances.length),this.fire("dom-change"),this._tryRenderChunk()},_applyFullRefresh:function(){var e,t=this.collection;if(this._sortFn)e=t?t.getKeys():[];else{e=[];var n=this.items;if(n)for(var r=0;r=r;a--)this._detachAndRemoveInstance(a)},_numericSort:function(e,t){return e-t},_applySplicesUserSort:function(e){for(var t,n,r=this.collection,s={},i=0;i=0;i--){var c=a[i];void 0!==c&&this._detachAndRemoveInstance(c)}var h=this;if(l.length){this._filterFn&&(l=l.filter(function(e){return h._filterFn(r.getItem(e))})),l.sort(function(e,t){return h._sortFn(r.getItem(e),r.getItem(t))});var u=0;for(i=0;i>1,a=this._instances[o].__key__,l=this._sortFn(n.getItem(a),r);if(l<0)e=o+1;else{if(!(l>0)){i=o;break}s=o-1}}return i<0&&(i=s+1),this._insertPlaceholder(i,t),i},_applySplicesArrayOrder:function(e){for(var t,n=0;n=0?(e=this.as+"."+e.substring(n+1),i._notifyPath(e,t,!0)):i.__setProperty(this.as,t,!0))}},itemForElement:function(e){var t=this.modelForElement(e);return t&&t[this.as]},keyForElement:function(e){var t=this.modelForElement(e);return t&&t.__key__},indexForElement:function(e){var t=this.modelForElement(e);return t&&t[this.indexAs]}}),Polymer({is:"array-selector",_template:null,properties:{items:{type:Array,observer:"clearSelection"},multi:{type:Boolean,value:!1,observer:"clearSelection"},selected:{type:Object,notify:!0},selectedItem:{type:Object,notify:!0},toggle:{type:Boolean,value:!1}},clearSelection:function(){if(Array.isArray(this.selected))for(var e=0;e \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/frontend.html.gz b/homeassistant/components/frontend/www_static/frontend.html.gz index b6cff9882d161516cf5289227812891cf396fc07..d44321775a8accf498908a5badefa53f3f58cca2 100644 GIT binary patch delta 53401 zcmV(vK>M}5uSkLQY&;^bw_Rl>{MMqy zT<#DUw!dQ#I}Cx|c^1|n6#7nrRy!R}IgwZ)n%JrM*x_vl`;^G`^_|jG?%Au@GGE^* z?!o)?xf>xDg3|vXQZ9&g$E9wYbY$!8&X=G3Uq

hQ*a`{4PQ!m-oMsHMsbc&HsOf ze@;Qe-v7@d+8={qwA_C>xvE-j*F~%US8wdNNe?V zN$WVtGo$1)r(LMg^Q8l zp3{MT0y|Yj^b1<A>Iwr_;+~&2IKA`$|a9zJ${YcZHy&lTtVNm6L=5cXz#4e{es- z2%nD4r<`rX8e}B~ux{PfsK;Orkf5kYX0T;?;+62OP^Wwgxa;gw?%`#9y;7mVRp;}0 ze&r(eB@`@Bb=cW6r>Jw!{%p?j#ZNbFP@r;zcdL$KmbzY)A(a`(7s-gU^NI4vh+oj| z$Nc7}f_wmBjryWkHU~|1Hi2}ye=Jd@514$Eonbr?sN-4@m<9qEWQ)*D#v8DMb^K{a znOyFa&=Uz%xUks{0-GbA24i#sFzTa=toa!h=?DmHdQ5M?z`n{?731e%1<0|2giAOO zFHkv}^FQbLNBFZWfE76Dc*+&giVm$6kuKiMK`Yw;cX(Q9&aE=UvKXa!e=wH%f-d1n zNxAQo<1jD={72DTd>~PS;m=ZErtpDR$QdUM8BADcV7=h7mU=!!9%{yajz=exT!=&| z%+at|#5^+xdqq@{;L!TP8VNNv#qc=Pbta9o2`B?V;Q`=qbg;{DdT=l$Re2fl=JyXS z!{9ZaBrR_VKw~YREKH$He+a*ST3uIO?2}yE!eB(f=j@z|wD*QyH6w<1F0hP>V5Fu! z5pG57(06RSBN5NtU|g@yMlx8N$(O?{Px<)w9J)+OkRCL5cex6>W|Oh) zS{NdzixVq^&D$sn+MaTgsMV~T<139K4!G5zO2=Y`1P8d#eq--`wy)T-`31{;aFAdd zslpVeN2YtO&US8vf5(0gGn3l1=<+`&YMk8G<#jdBUn2iI0l?j2P(~7fBxl!Wu)As? zkK$J{&(`yt6apbpe~_V?%aS?4))kUcnYKMF*G0wmVe1Q#n*b=`07gaTd0sAis463~ zvJ_^Q!`Y&$;_cK)l0QVHX(l7RwbGK!rsEcq9=FjsE2Qe-e|UWJ@A-`%Z#8@`I@#jc zgV6_Bf4E>@vmMAz?mehtyCP3eHlCjw)~F>bW?sY~ zmuQ5-L{a>`f4hsKsk9&A;0jI2jrU{WTii&Q+RZufRMmAT!mxPxK^i^4ms_ibeP9|j zBw4bji^O}YpBn1mk40d@T#0RhnK&_>!0d>K)ZIimDq+MhE_DI3Zh<_~R8kpphZS15 z1AxiD{tKG@uWEO2S^pP+LV7yzJ^8rdfb3>_>r$Mge?%Qnd}j(gP`1Zc49*`Y&)#iJ zMc=)VnAdo6{*8y&K=M}fRBrNKq^&L_QamcK9R-{i!M~Xwg50YrUlw0Z ztO(#7w~WJ6ruj@aT#Fc@by z)Stt2f2fWZ@=jrvGcFpP5TOVXl*-|_APL#xf$;Bs%W)qz8v}N?x8f(J3dx<}K>@~( z%>_hyj0_~k8wgn(t)3;>6VByXeudfUgN6(An@0;jFhR6KX;-=hDb%BM`5}=CMDz2fKo{smL%RXKuO<@ z{i|Y*VFksti&s&6$ktE{rkcVJo(2iR#4PAHl_yCUm!_WtLLmubIEs((9z^2_akweN9n-&%MBRozk6zV!lVxyZL6ZK} zOk0poLk9d+SzS8rLOOWxla4nNYOT;00P6_@kQW#&*8H=LH$K@h1uPK@aDU4J?Ip@k z9aj2BDgN6}d9})}Tp6p>1+cnRaz*_ze|AWZYR>zL@E8=zTin1dFXm>J>QlG+mfU)T zJQt44_Z8XEj>U2J0hHegAzrI+{FDHMTRiaRjDJWW#u@ytwR zOAM+$vC^UCpU_GQK=gc70EpjHeEA`1Kk1G+j_}v_ECP4$)U}M`Ec<>9_oH2Ve;)1D z1zovR2S?@AAKX61N#*8+66HG!sbz1z%?w(+Kr_F>DLB>k+|3YW7)O8-FcQogzIglm zw>K|;Jvx2${_x-E$FFZ+yhIr^+??<-fNn#01SCGsf429HA;LH<>i0*lIqpHFEZ<1! z#I7U5A0Y4|6dm!eEv321jVXe4e@b@A?rCgk1lQ$At^or5xp0s`aR3D57Sh!aU)^jn zk_OVGs3f>Vi4yM^`xfBKFH!0C!O#V4)?pM5IAj}r#}l0%6Aks?AtxZ8FUXm21&54E zAiH4_8N(1r4~XcAExHn7XhCcwGIq`=DLV6q=20Q#&7%GEmIW|W8Yr8Le zhax^4LX5^D6j2zfp?IOEf10oYter(b!xv=+FWKh-CF~bNnU;)4@!j1B%Lt&_g+$|A z3ZJ6MPat81D%cD;83?m%uCkkwCEgp2CBk2$SLi27m!$~NyfS#m$U$v*FWG0jeBYB; zE$ZRArNImyO&Vw_vCA8~L(e-kuw5k*_HC>DlhJSOrRyf@Z5{s9e>ws33nnOz%R05e z3Beu)6fJEUY;5afU#nJYCv_)Sz1LmWZgLn>;SS%oPk~{zA@zg2d1VuI<6%mU^6u_- zGhLQdAM*;hBKMl1OW@)bx^rBdq<(2gbsH?awsiHvu4$8UCLbuwX`6>VDsloyd#h;8 z2IS*jB!uK)w$wjce_EA~aN$#f!NiFIA0pU)E^MNJdnf@E?!3ek^vL+e3ABe%nNoJN3Az$QRlhuKoMx2~G;1CC@J_VQU1^5J< z)=zn$Krri6jJX=rPtPf#8l1;*vU*CRhm=*y^T-CPr%U?I2Fo~3wlO%+P|a=}xAHd7 z;>s+lak3sTe|O>KB5tk*#Jo@*SuF^bG{|#0TTW_3?6Bvi0a`h2h9+w@)ST7bU4Q!? zwYL}gW3*Z``K;aB)0;THCn=yA7M=Th+9*W25d5gvKbZUiZW`+vAzmb{kV%NiOe9O0 zM7;PkecASBW{r1i+5}U=>}Mjl%_Jfmq~p(S#&{USf8CqFE|$yg^r!QojU5_6AYRyL z0;FL_Dz{3-h~a`)&T0n4q!z#iB2u6WFCY`u4AA~~eKKi|^An&37lI%jSF?PwK7s8Y zv4hy?piG#zI$oX(JcNM6Y1?6r?~zdb1a{c@ARCAsmhcttzhQS-%S@^wjkUw}8f)#9 zue0zDe`(#E)&^|fbH={fVWaGPuzB-h3|gl&ut7nj4Gsgw0QeRsz=MZVXAWy#A8yYE z47OONJO^lkNGY^Q*ahEw_}DGdbW1^0ar^ia33_5m+m%CLLu)}6UAV+$Xe6$B;)1V5 zh4T0|GsOL^@-n!FxP$pMHj}1pvBd12S0zSle>$x4%-Pv;P1NB$O6bgq4~!IbVE6ev zQcD#Bmtxh#Njp`UBj}4`PA-Y^=}Tp^v%0^IzZIDWDy_scDYUdWnGOPVd~3_9nJT-| zZ9z_Pt@!w-^;!%05*qGlz9|cZH3g-`y>f<#4XafkDd+ zBGF&MmMZx)Sfo~k!MXW`o%I(_M|XEjnXd2Ui{{aGZ3m~5bd-|6g^`SA9Soi5Kk-7|Qt z=(^_MVe=-MTJN@DT(Gp~cr26Ke{k5>uu+#`BgEBPygjQm%GV1r135BNqIQ>gr=s2W z*;0siTAyRMpj36WhSN6+#AJVlFIlZE>`C`-;<0Og-+T(QG+yH&+W`%Xv=o2-S^15+4-L?fRkKSk< z+mE<_xamtYHy`iNlz!9ie^#{M)Ar^~w$9G;ids&+u?P}Ur^hE^TEL_hm)Dp7nT|(e zktFGhVC{L-va5fC8DCfEhJUe8dkOCS*_D)tm+R-*6_x=ueE!j#Mxqtf7Yov%e=Uei zKO(&?uZdTfYWl9;8+EoKZPna%{yo1z+ZLy#O|k`mfbeBgBJE5$f3|9MjW!OGE!F64 z+<~HFDdYlK-bX#)tI0Bnm94d$2uiouX@;Nc7kPelXqpK0HDlXmMR0d#k)~-*Mjtjw z&4nR|RdE{I1|#7@(ku-K&>5=I2xuO{1$vQxIVxYlG@CY)B!$k$IWz5&54Up#`#KmW znOm=-dYL?R>WlJvf3^4t!>|CNh_S%^Dg&Ob8Vr)Xe*P@2V*ARNec`1O{zgQt|CEw^ zwZmd!tT_!<<3C}zPnFB|Q(`n!-6mNBjeS~8V{f9~)DOldNsb0@?$lDWXis31ysh5T zks+G54+lYTSg!^Pi&^JFWuP*vQb;3RXzRi#>&Be9@@MHNf3~+l>!JgA$YpX*#^srR z{7E3S5Gl2+b6}MR03vs}cnvadmEb~e}fA}OrBjv1_D0+?e;mF#g%!{aKv zac#<0Y{?T9FiF9pzFML0mMR%3OF;*Q_|(>h72DRbvCLAvUYleb?h_+SSlh%mGHcnp zQwwd3{ouCvf1ho}nPSuVTa|{DuhGHY8v$+KEKDDi&T`501h)pAV%<}7`<@be#w+?t z+GJW_+X5rBTs3w^KbOLF=M0GDayjWjDEKehd^YY61WVx7ki705&KU)7BHs!Mu1^+Z zHd46iJq@nyv^h9%$y{?X{A^4MAw+T$uUKrHAaazue_%iucrk`631x-nH3AYHo)XaG zSn0qS$ZE|hZbxYvY3q)ZC^sd}T%38VAllEZ<-EIVd#v>d7-w=5O>n}99H*De zZi)Mhe}p9Fv2mxtfwqCs+lb0Y-x^}yVq#)4gGZ};Qk`_V;)s7X_j<4HUDnrWP_VK0 zX|msCTR8-N`K-(;W~1MrMR8tZ0a&gmujf%bGl%rDo+DfE)h#yJ8QRO4O&(=u&?HVW zc(ewMmiKbu2;nX27LmtS{kiF4>QnS>zlC}Ce=b?uBs6A2?H+ric&1h4l5F+6!*^V# z5t*o(LDP}9=p?00>a$5qB4jmYW(3EDs`Y4C|0>{c#&n|doJRF_4HyH9zeB;d*G*k4 z#D;Avj)E6p7vJYuU9KHZh;Su^n;Gw#x9nhVi~k-%7taZcAS@y4f_B7_4jytAB)J;) zf2JoEy0^h#i+|!}5M zsTE6d9A(EBRlYo-;IX;>D3&M|fgjp_2tR~;^yQ*xu(1>k@lGOS6pn>iT@tbN4|-+E zzckn=supmB+LNS6a}G}O7mhV9TTjumf5b_g{3SkU%QX(MC@!r`xVzK8pBd%G z6X1ASWAmM!7PXLWtfe}oLa zjVMZ{wpyc-~#VRixfsZ7fg3Hg<>{ci4h5 zd0IwEp4=M#IbaN^|0Jz7*cuikfA#&qKt}FBkbN-_a?&PtrCimfnW)|65PL0*??v<} zGslTb)hV|ZF{^o@4Oaw)0dypUJhrnPvp~Wo($b|>KpJn+h>?<(ugM)#hd^EonV3I^ zi}B-BnkRqiC!u0<;wKMfyP}Htf(`?mj@PMu1KpFpa)VxwWGJ%j-j3SHf9FUnML1uA z+gnUMge}zBLRu9IRWGMa9Xwglsd)S0$n0;KoAnP2k7nD=dJ&S#h@BryBP~Jedmci<`P1AgXJ)!7#*}zUJhtbLQTANo=(~u|`OY8yb?+cZ?1!DqQq5HUenWwC+A}+ZKmZURak}O1N zQ`-Y3$Bdql7}JR$o)}LbVovhNw3ep}&MiLJrBQ5e6zD8O}quh23PwNy7(TlsgQXG?;8Xa2=g=3f( z%ow-qhtSIK3TWZR7Hu7iVymsv&O{Phz>8$u!M>ss`}jZ|+ZKk}YEiIzA*QJBUbKui zRld;s&=N_N)r^ce+jV2x)|TWVcwzx)1|GWjnz`dG)6ngoe;OCgoi$|4Ykw}ho5mPA zBI%H>+MWar4gJtZPBoGuS?gCn^l9B&$Hj4TlCJr=3HZi!E|y$Zl1d`C zMg1HLpp3zO#J2nEuahE9*8KK&XwTz)4o7`$MaG3eC5_=L)UME)!JZHI_aoU*1mqqt zrCj#fi>&e>v?hPNRQ8ucW|S^q|w5^1AA2 z_2u4Q^nUtFucVzrK1}m$fyGN^OYmpW45OIoPl@MVnHICq6po9NNhm!ztg7q=ufX`X zU&eQL(8h6j5+`M>-guJ?UwP9Kb@wyz04Z8RIuM&5!>*MR9%S$Cc;V=5?on&SLO$WH zkMZkde_GA@)li@fj7lVnGu*(oeibLGmhviTV^x*paFWO-@(uOd@N0S=v-=-s%poM+ zpkQ7aYTQyF$HSH+ASyXJ8hIAnnF zTHH~ejf{nDXkl>+)625plUmg6a*B9NxTZHXS`eXK6W9!vi2Edb91x z&6bIi6_~6{cZ%NUQSdj!-PF(E*k&)!&XD5 zVFXlblkM*p4Eo!(Ip#^3@CYY>;VLnMgO~8b>P1M34x))}9=N9761DpGBBe4=s7KuA zf1ducK|l)>60+{Z+EJH?_$mvh*B)Z^iQcjV5b_lalnohOHlr|lo_F^-nijgd0=ioR zT^L$0(W=Lk$MDgZ+}4I3qqsZ76wAUm>Gg<`!qVXJ_Yn+QD0K+NZmvVkiw}L+iG<_z zi4tU~DL4h%GXr}{D8P-_e+LZC+&>Ihu7a=}C}0eDDWjxFZl!1Jz41nR z?@1{xeAm{e)S6B$U9n-Dx1NXDor^d z2J^hw#Oz-Neaa|(K-I1$6F>m6n{=e!kQXnk1jHpvJbGF*B4{{=Wf-~1e|0Kfy(Q|Z zGI$1{j>da9v~(%yM-IC|du!PdBYPU*>7P}0>MJpk^rfCtW$1Un;rt@Mf`-uqs~-s` zzCFfH_JdmkLOdLezZ;Am4Mq>)1O5HIBtNM67j(ypbLoAC`S;F{Kvw1FwdA{jlR#Su z)pgm=fgo0rV?vdxwS;;BBy_hNG8}17Cgo5;hAmBj9TMxSm?7kf>tC~9;jo#hXrFLN zVYhZZ0gnNH6j}WKxK76pl+{mhkmlb4Q#>gCyf&I7L!S3=@qOQF{j?}P!4-!NsW^G> z9=VEOMo~wmJWN_k&~}W75&^l5i7NJx+$rMOZw{hfQTOmVl(8f99`QElQNG92JBkBG z(n=n6g5IOqx+wKh4D0PM|B?fA#f3oRUJuzKnL|K-4QtXB8^^=T?5fWi;IVXJ^3iOd zkPXa5v3_wphHJrXjR)K0OLAE(7OQ-6n4tCOyUlTN{P09v57y~F@RlqZSkKlI;~=^) z9E2#Ox`f0BjYVFJU3zI$;i%1$6tEFJP&swJqElRz{jHg!+gr$;i&uSMFkr>xY(Izz z6hk_H`VY|khCKGwvOHDZIz%y`AG7C^{8{Q|9H3p+?8W4j?)*xU96S;0&xN?I&r$gG zd?M%~0s-#QiyE;BP98cM;U~#oba6lXW{1ASB zB7uioSxZVqWN`$Ql*Gg1+h`&*hOF;ZDdC9w2F<@W+7;LifAgf z3f0n^1y;`ZBxV*J(w+B9FFjOKwu+AM&iYP)43HwZPCsGq%1tsPE4o*>jBNipChs1f zQ@u0pB#z%9cHa>bPP(u_?eBnTJW{ZKy;Ey+=dYGoBy(gkFxJlq$g>y51kM6)d zLgKz@7Q}#u<2)w;W)n+0Wm0Fb+oMEoNK)`%TQXBOr;0l*%5-iNcU!PQ;`3EwRLs?_ zFUapP#yhpPk~rl1k^u%z^yw&W=O!Y%dhhbOZty;q0fVs~taH?a_>}jU%T9W**K+t? zOfZ@!v;NK&pL&zA3+QP%19v8WXy=O6RQP6HyKr~xJYU&{nyEEU4AKFOIui{{N?qhM z2Fby>NF>t56ePI{Bc-~w>1I_0w_TYb5R}NBZq>QRulmU1syLPg?lQ-yF_+tM@s?5@ zgsZiTyj93rpXeu#$@`G7iW^omniJ^H0#PCLwd4HUIk!j5Qa^j&( zM9(&q@($+qo}XWSO{2g69d2EN+28-ZIQaYDhxqr~JNz7CN{qQt@|L6`@ALDQU#|L= z0Q2vE??(r}9>7i9{rB&Ge~;nJ`j|ez&g;MTu^Vc!{x-qiH10bd=^cy>GyWbwNIn4c zo&zXfqz{u<>7!{gq!&Wth`|F1E(jn0U+&($v27zs9Q^-21%)IYAOa~$wiAamtZ{5- z#=lKspY6;{j^St_5|S{c04@O9RwRD+t4F`lASorenZ3=9MfAIWtGlbKs_P-rk}~dK zsWDux_mWELxbwbAF3h}_a+P0Kl97xB$aHnPNkT2LW$4T-puOb04ky%ds}Ak|OV7*szKKh{y4nPM<|TS|RE^AELhdgXvvC6wx6oL@_kr?Jo*yW0t!UqECG%nDc9?Di`|CpCKSKkUR|D+ zi+lI@uOLfG-~o9jDf)YGR+X2)=uMo0_@bF5To{X>jj*Gzk>M`Pk`l8NG|;swib7nA zpxk^ipy!=Tc}~Um8zf-F9!2fRYZFMMTOx!e!0GIN<@I-Y0Rx2(|Hb-W*%jG5_P9mk zdZk9{0S8AeQ6O19IlN^fr&;qc%Yf7FrNz8=I0z&*z&YqsAg2+e^LapgcaY9zt4l(| zn84lgv)uDnKfI970D~W2y*qjP)9cr--n@J9{N%-(H!-PC1wWR}+tm`oeP(kSWDs9+ zn6wdpcG8o5)1w2+#A;bSSQCh=jDp?;d$N0X*7EH_&7+4g`+)u^_XC_MO|(oTK0v0r zb(O%ni~^`Ju0rzPu1+^UEnu(_b*SV|VIikWa0gVvd76phe2u*G-Vm7Ket38=MDBMu zUTNKcl{|SfIC-n~$(zy2%pTX9m%i?$RYq`sT$E*Cx#XN!Cy+M`Gl6|{%LEF(VOOFgyBa0g6*<6(U6a%7s+?xm#pn}uO-!-tVG7rh z)8v-aWPJ^H55R^PeRYG)0~FtM^)zI=n4+51GuS*!yNNgHJYUu3*su(zn#)LIbdq_H z-8n`}syp&~I_X~LuH9gd8a)k6y7riVZx`CtIUv$x<0kd3bQ`>K%bYE;PtYL#`3s;R zD1$%WUQ~JUUVMBDcn<-Ak;}0t{P`}u%onI>h9BY#(@!yc{QWny9;GvjUw_Ypvwp;$ zA{xL{24+Gp^ddqKlrW;*sIPBjAORg92dc~1)RRE`lKW14%HfDlIp-zZQm9dXG6}>l z?pJ)sj>V_yS$uQXYe4n>H>n@rhQUSCEJp_iA3uH^e7rv>tMh}yZ@&5F;L}BOxqz1F z(JG!LC=@70!6C-GxXfU?U5$FVKZ3d>n~t^bOSxA98|D zIl}VmSZ{#QHDA)B;K6W+LCzL)=nj6aV{?&Ur0DA5?L`ViB-SY~XVF&iHL}KKfu5w_l|(~gq*LaGB?Y0b-Xv}Dosy}##)iyy_{8#m#BRQ`9HT1? zfCro-pcwF)e-0IZZje6>Ul3$G`~yJjA|%Z~{u%Ax2a+>PAEP-AvA5aHjjaUw_w2N1 zD8ZtzWZvN9R^#xS*EKxyOB>3rjYxFHTP~RHC#pN zu9~kCZS@u0V1oWkQUE-UVHmA}_1QZWEY{jmp2BwuTfU*$LSVapS!J~`RaR|%MASbq zSf4#~Feqtj{?H7?UQ#GG_kwT7`jYDu+Ip14zlD|`rT~kz9+Ns5{)0}wV*H`lZ%bQT zEm}4yi8CAS0X!6cdvkM$->J4c78$=QL-QIIFHaY}_bpo7;Az(Fhy6cM7&65@kMerh7FTa)F#1=z&H8{ zStaOlHw9Kt_HYEL7x-uyA129+6iQYRI+$S%ake4@ZhN$d>G!*GbP>}&7NLmEv1CAs z%hZ*#4W#sL5(RV@B=4I;|KcW0o}PQdagB&d@r)DNKM{b0xz@~Gaxi{($C z6SXAw?%_cetFrcB4|O>6eqm0EHBX|yX^K~v?~0(fh3d%H$FAJ1KxZyVLA1r<_-@Sqk^8LUa^4=@z|;FB?d{Hdh@DFH-n4?&eT@oWF<6cKZ*mC zVdbO`QNe=fFVxUbpX?a2N>-C}YSe*EgZd(ztfg|J`cx%3=G zQw6DiIj&F$-5i&rIohADHEOpT4S^;AddMd_fx6W?lH!py9-jGJ8)E$x=&waqCFPhE z^{yRh#V9a|)wnG`0qXXP9unFuh8tDni9iu-ke{U;aq!0uPS}&n6ghJy4ma-aQ8OiG zCCv@{YZ;7-S?w)G1wi%xBb_GsVt+%HD8QP3k1Y;xv+TY}hQg28@obSVM*+U;p`*;;{s~WN<&s^~iY0+&BeUQNNqUn6gwc(mb=|x=gNE%tLd=Rssty z%oLPC$Zr{wS}41#kk;~B#a9*;WK3rMl#x|}!vRdoBcoFpa0q?18^HQ_xMr-HTx$`)qhSB5Gh6p;96FuW+vOvA4k zG+XOYo()b`%Q@Owc#t#DxoH2zWLHwJ<1@6Q1&YIMke&f3`y#F1!c;hDqOVQ#v(Zpd z5n3gu-xj1+P6C$5=Rn+_t>bL)BXs71N=X?^6E|f2(Xj)+Qm83s?J29#aj>0#%pDMh zqwAWQa<6*`75zjQI&7e8)#3k@W9UhvHZ52`^<&~fnl7I5Ar!FYT^%!38^e@NnZ`NrM-uRo;A%81rYPiiU@JhVZa0w zmYb$@l*!DXi1xEDS>ybaebL%~wOfg*dhvMh@VFUeENx*zD@mkVE={9W=!V^6V_7kc z3*!e;HAbEr=PF@Vt%<7+e#q-fa^^hmS>!*k#pfhYsaftc3ih*gV-rn@g~N)ru|TD_ zZI}!73E~617!Wu(bSqNKGJceWDe+3T3bJ=q+U3I0oFU0cG7+Ib>;OuC6RMk}8X8FJ zPj-RN_Mgg`n06kilSJcIkFHBeRhqt8ABKEo51zg|dH3|qUtYY^<9geqm&*i2bAT>C z0@nf;h7$E9E!Qm=H7bG1Gd+Tlb6xBuEhuY$(`;jdNk@>ZTv3xp z%Ds-Ftxfi1D4=Rxb|bam#+oVBWuwKGrXp(C-E{2^5hc^jWpzxmRn-1W_M2EMWMT}Y ztY!sU>+Iazup*6f$h7-eb?n4E<+>RC^_zn>WTH)*yq(ADyBZ4ChjGBgfmZ-_HUX?X z<_Yo9^BfuAxz-+kmod#~9n{p^RZtlWSzWFTR~wY(BDUezG2(C&VC^=dFI$Iw+g$IW zEpL?;o__W`n_n>j4lWpbka6Qj;{k&%5Y4Oi3X}_>UTix(^da!W*tc1%!?y)afe;h4hLCvAX!1$o!5V5eIk>!48?8Qn#el2^TH4yu5W_5_Hv|FH zhk=e6_9HK5P#*1gG#<}L4J3az5+UxmV9io}xBZQm>b9G} z^;xgxq6oCmA^n`C9(Iu3dfB#6*t=8q4!OyjaoYrc#oPEs>iEkOwo93Y1N#4B6+jYDP6=T}fXl5y>Nu56K%UdKh}a zv87F+hC-Nn{n&P(y@FCUL@qa2G|^hnxQXJ9QP0X^mI{MI$z>f+tk3CaGL6PSeqdAO zsxf_kb>?1`g@&DW$^gSLy~D;sKh7EoRb?+e6U>CmL9|G6iHt(;&3LTvk#VN`EifIl zX}D1r_G{CMyO4xY>}6kCW@=Vt|Y6THN8I!&uzNqrMZ*+ZRVSqocdydo-WT*?30siN_}chv!XBY*zim;;Knw zp>k4_npi12F+z|0S^F?z#1DKJMgO^R3KLu;{CeuVbQ_NVjx4C3xhdwGxAIA6u6A30 ztR{rC%dEoZ6TIy1-7`K=kag^QhtX(gzKciKb3d-Zcl&rQg`7jvXH3I#Xo{qADWe@! ziI!oEE1N`!FJ!3_=aJ$+G@})2?x?p9FPIr8kU9qn)a6Zm9H!#Jkq3#g_3k96&ZV!6 zxrf7uk`xXgtsP*f$I`+@b%ULeZysiR42H1Zxt3%JQGS9aP>{m zBrD$Fy4q@c)^Uc0Q+D})rzx?fi&tA|i34r=AGLe7+50QMa$-60GB<>chDK2}0m(WvB$g&g1T)KptDGpBV9aH|_9g8#8!f8~Lf;M!-ZpLu zLc0R6bKL55I!B)2PHucM+l>#V=jX7&GSu=p&QU+IDZej2 zN(HA8CdHE+odm5;>!u2&dQvo9yXLc5l4&iffBsT`c@PJI0>0Dtgjz=TL7qBO%ifkX zgPSC0f0@i#7|wwa(~gx#8C*%+2C3|*j5$8Lz?i56ir!ID=o;`f@FUQFdc2q3+@O~x zOtmUmAWg_wmizjyFUeG>~kEb@?gb2CI$y>TIY)Q0GJ2QzX&O3Lsq z5~*l0*6*VVW`6G;REcwx6Gh~%Rt7B()shU&r#7klTL~X{qe-O~uP`B7x)T9FC)pT# z97p++;yC{zDMrN?Nj}zp+vUsbAk6noFFA(iwqDy{l9t_Y>xZi@kOi8+*>|ts1DLQN zHc{GfF#<%Lo6E8aEnPZPoQ?5OuhOA^4O3Rq;jdSh*}E#gyhN39RHe;%=ajq^O57;I zhn-R&!$gd)NLz_YpcyOf5aH%aovp(0ZWcQ}I&D$`Rdkhy>9~@Ahm5Ydv&S=2=M6mz zpM4?A!YtuSR+#b(7INHzl336{Yx#jLyH@h!Xeu>cCuv;A?h>|aVa;V)O){nwITEH3 zlJdBL%{D65Q_CS+>{}yxP$t?5Z6Sx_TB|_T(xY>WZOCl_Gr*_!Q~0 z{RG`3hNMHUJ-kiVdV`klGxU|{?pSiiAd=YZF{2nNGVL{KBVA;5j^dpvmWZCbGn6F$ zOc(5tfh(XqBUz!3hYaq>9|3b^bJg(7K)phk$mRZC!KIvk&E4WMn;JcHG#;!w%GQ1` zm6443!_|-%b=DlfMP%P#s7H*Jw?ItfW2fr(1m{=P>#UlQ`*pV}FN8Q2IUi=X5mHDq zk=SvFKE5F_;TtR(3I0e1YQXVe%w^H~2oE=DwXrr$m9*9^%;ST99*C(`Kr-V!Z28H? zjRpJHx^p#uYHYQaL3{Cmz-Oo_jW*8uX6vD$zj?)~V>!+gQ24L#YL|Wr-JCdg5~6XG z*&w}Mei~s&Olmp*O)cmCmO1nR?EqB9DaamsZ!Z%ol{L z7{WmU(TGj`90;(YX20gLG@u|oZ2UM%52qIv%-trrkM2QXSo*<{<`_ZG~$#@&=JoN7epN(UhUZT z2mA4VT&SiY{msov&%`mRzqu*H3XMN#40zpEBDK(|@)n(`EA&hmiFnZ^%{N88LSfEk zV$V2;d-ycuRqO^#P{wGX`>9`(o~a01Ex%xwY}Ot##4=6!9XbmS??;Nl4hBP1AqEQD zCa_J9waQy%7ONAAA`08ofmkgf*eCt{>2dgf%lyk<2GKFPGpfJ*Tu{D^^a0!xjxU<1 zMShC?Nn@B=RHcxne>9~R*uHWQA^@fc}#@?Ii)!1*fyhzc- zR{%pVKh_&7%%H-reGW)V<;eU?Xqr`uL}5QD(h=1us^PQkX_9-C{@U)Ikg}9Y*W|&; z_)^Yj&{depjVKq($?&)tp=;vfOzUoc6XoWe6^{(?!X(g2-@BY=^l$`qFGD0m(MKTJ zr6<8>bd=2`>5AA$W4_m{b#`{<)QYpjtP)-G#~U(O5U$b$RaBx$F*)aWo;In<9n9ft zT(Wv@yIuj5(*5bd(Zh#hgZD?5&2U@LpCkNJm?x(&-FG9eXE7#TjHj^GFjhE!4Em%~ zj#n#;K^v|T$9|vKak3~iutQE9`vH~LG&y`F?mi2}3C6<}bNM)^&QH@Y*w2_Hf(;Kh zWrQ1p`Sv^8{m;_kLt3LB=mDL6xK;SzCsO`g;p#jq3%oGG;Ap<-mMLP>-%5XGx!mZp z0gIc8wkB>G*-N;IO}SJ_Gux?uf=Z`bZJy0a@jA}wblOeIJMl9##)X4LVVNcI4!Zbql6G5>M=`p4oaPrS^`sL?0 z|3pg&aqXQ((KWWMyYmqYyhOGsb8K)Gpr4u|jj@tGvaqO-~Q zREWx=KYR{;%XlZz=_F>;aCYukyq5p{sxldP~8ndPmSSP@!OwxpM8^hKl- z;U-e@<03*OGF?bHx~^LO%48OKFdU+nIk%ABXXv1T3$=(R5ogMOY2Hx3Kh!aufNLR# zYnri(hiE(QV$Cetuh5oXNR5Kteowo%myJC+JPz>OAS%V}J<0?MJxkzN-ei|I*{7S? z#Z3jjK773SaB=ei5I+2qLh|L!<>d{0Et{L=EP%aZ$uIPBpV4xY?Py1V{on?@l2EDK zDs?c=&Tp!8eshk0|KQjU&WTk(T7^Xq$$4yjD^Wyp0U3TNMUrkqco&gu^=WawKx>24 z#q? zYWscai{j#ctFnAVVL$i*zcf_f!-a}+b1F4P@*fFJi|&_fHk+?o4r!IR6mFvf@~QoC zKLVn5^3Q1cC6TqUvW(2pRf>3Q7m)#penWSqG9*?a()M$`^TyKG$03R_FELgy5}>tu zgA|WlM^otlDkev8H8g=Gr9#W&mA#eK;LmV>gmW0-T>H|POL^!rK1o)SIa22{_=62D zlau4?r=vDiN&HbJz;%2f{qqnxLTa)*Z3ipU@FW^tr=yFw z7@eVfyBRIk$P_3aS4%ZZriz!u>ec!>(1?r+SZ%Aw>Pk5u&z# z<)~>WqX(g7yK-Y&7D!X<;luE?CnL$n5{05~bs(Lq{L^!@6athsk*`tQ$(}|tsU*8y+lj@frZ6x^sHI$JSxF~0M z>!~dz_PP6+e7c$**h{(cmkdAMT;2S7bAKKke-1V7&&@hB(^|X}?)UDY))VSS;nB|2 z3&oyNtGU*RVZ}j?^B6-=M^1>_tmP+YM!wDl=-`Wf%zPmna#Ae$iwLPa0GZt zf1QyTo{<)U-55i2u{nn3Lce9Bx*J_R7l}`Yz@mgWsFIz6rWrt^At;5EmOt*#Nx>c? zE~?zj&P7xtG^pU86A{N-0&XwSKqoKzCZau0_&krH{yFSCYU3QAV6mNv>@tS5qbdB~ z+HzghxkB-&T%!-<)CqoE$;JA}Df9Rpe<1(UY5W5Ie4r6ugs1U`sAH59td2Tb_y@+z zt9nk)jZ67~Z;dBH!_gf(>p`$UEcp=4l2fIS^bQK#yZ3_rt;5qON$L;=0(TC4z{oK_ zyozAxSSI`!XZMqAt$~PgFj6cFZ(fAYmo8S!Mr~C_W z)oZx|_`oaH=95~Or+QUp@oOkScNdT9$7Bu=SpqPAl#jUccv|f z=m3k9Pm}_Wfjsr0qLQffbodoMf3j=ZL+iVVB8fhHFfmTs4}kv6iT+gbo*+`P9HKQB ziFnh!NUrDEIsUp#uDPwzB>0j34>rJAd`54>@-M$K$Zve}MyJ3$0##4{Ux4{liG~l5 z`!tXrpRBJd>+4tROE!xs29|=v?;(XyEfxT_EDve4cHaf<2w9_kKCM}vK z%{21sa^uC;>HC$u&u|Qme`!K?OF|K7JSMoex5OVGF>xF=mPxT&}$ zN03Ed8;PxAZo98rS^VT`IMeYtE-FZ7+z9t7Yhau9Z2MhBp>K}9s$J(s16&8xwiiY> zc=hdI2NJP`PFp>%WgoKUi><4?=^@2&pY%KVg5l}y(LSvcGESzZ84uCB@de;5NWB+0;DA#ERi$8&6I zg#CXTjY)*2%_uID&(}WHGjIT*<~93u-`j3nnVZ&pxns?jV-QB5sj9hU{G+G=y=Lph{fjl67C%Qzm#zLUYHD6!ae=`;b_!Z`KrDd7u9iF+>(TR20 zZKsIN90k4NfJ*Ll(^@a3TZltsA_)g+67fqaS6*RpAZrEj^$fi#oWsQegy9Ir;+Ut4 zxurk>x@dm-w?S`JRy?o$3zm8+#r(33Dcpv*4v#r$a-WuD+A zhWZ3%Vd(O;Je~<3*;u;9>5irCcCSc;*hDo3it6-DXqW7AgkFcm<3HYL+vJAcO$!w z`8&IO*wKz2xkAv`lr{8LQ&!=o7vAGlst2F?YOSXOz$v4jUtv2 z(9wH)&JG=y$IOQe-%=VDJls6Kw*s-f*l9L| z%`@0fH}-ZesvNrkBeFT_0`}&sKF)UYa0?aUUHTPA6?=h00-faqKws zDMlivI&KlLmCUp60iR1jy97`uVm7pWf5WI70gI$(csW38KL2+TJbn*~7DiS+cgQaU zJ69ijub;L6BUfZSFj>X98WOPNjkQo)Hy8qFANC0<$StWE<Oe;J>k z#!*wPX3aCZ+NOoIC$i&uGL7r>5?TwTXYN~UY1r-fEzhHl4I|xx6wcXdp>ErqWFgOh zMcv!eQ^~P^2Nu8Q4)kn2r$5JUm=H$Th~v0vpMTTStH&+asL|E;-1hc86>t^<$DiQF z3c}}?Tv3;Ymg!quhN{&#b}vpnW^;9!+Ive+yiDq9C^| zyiI2QL91@j@;ffM$s=rC@2rNIsx>; zE^4mbg&TIxtIOl})Z99uMJC+EF3qYtSov}pMp}O$ww80`v%s-M7D}+7bUD1;Z<4~O znjP{IwbQoBtr{W<3{{c**0O?pAAMu;I8!U^Vbn>g`=oG%e@|-T5mk?+%#kAEZj7MV z9gwkz;tHKU#=?6!Y#WYaQ$>+x9K3jAy;iPmpBi#q^}F*y(6;*%sDL6?`@>jgmct-z ztdEfh#w)c;#TB+1)ED^~`f64B2}%TnF$?#G%Hxu7s^p3XO$n1Q_1#GxzC{Y|$QHd4 z#WJ)ci4|XTk@7OjK+#OXpN_tbXdj z3Johyj&?184uVtxejh3EjeArWphcmcfziYhE=J!D3-7JwD~>F>^O!;1q1$(>ym}vX zn^zg_*BiUs#wSyn9$5?ULS&X}Mhx67>+^eQS7cIje@|n0iRzhZqFN@Z!CJ8=nXJlZ z?9=&O$$A0kx?Rza($_O0iA7mh?w_4xHG4F{t^#M0S3cWns9Y=uErZiZ7qwp zS(YZmgdDksb0t?6#HkOlGfwwrqe3;S~^CpxM!3KL^z%k=egxh z0C)xsApopN*WPLBU@E@XT%it(3LouL+&b!df6qlmcwXO@@7xSX%f5Gtz1NwNY_*l) zjLRw{P3WoAm`amwZPFdoNSoav=(b*>Sf9!lMYj=AbcJ5^o!x1X^}%@OxA_*ip?Pm! z;+vZ~CKvMx*ghVGTws$ir!*8bmme;Cz%~u8|5{lpWJyi-pX6m+YI}(o3mLj*FQ#-k ze{I$laQGtiuIxD+iiY*Yt&OHz-gEyE5$MRHSj9s z$GVYQVkQ-CU1jU>Ce^z*aEp61?=rfx<<|$)*0zt)E*iFi>z;`fq&=;oAM1e0A*o+< z728#vH*VIziF-9w68Ct;oyy^smafNcf2O5jIB;StY*3z+QUd)TF1Mecp9qCHueLj| zD74F!Fogm=S>Gr%O6AsxF%D7Pt>{@rE$^p%GShL&`j8Yt!s{Y^m+&~~oGbGIsnMcV z>uq+^!>qL5l<^h!Pc6sL(#S|ke@big=I(qmu7C~N5^iTg+Q#SH(7t(fXAioBNo z{~Wc-0*<<|!n2MS7Sc+RA_QW(?kYk6vcHJoAC?;w5w%4e6l6f-D@aI>b2R9RXf2+xVaVpuD zA>!GoT4kw7=k-(Q70^&M^2>IxzC5PcShyQfeysO~V?_9pZ4rrwTHn@{^lC}{xEV(p zkOL18JrH!k7voM4y^nt@SElyn$QH|*JcSXh$0PD;NYWw>0(06Yu;(0!v=gi*I}Vz*71tVEz34`n^B*OQoA&C$@QZrAkbl70H9%dCiS|5LX z`QpvfH_!h1^U0eR|MyQX-kKU9f6W0eSF?+&H+*TbGDr+pOP!u)qg?w?@eD;Mh%12| z(=0fak)5$BScFP>V;65kwhaM2wGiMuafb!$Lv;YihiNQ;xLbw8f1Mb1)*-8EQQt1* zh+1tpOometPy^dQ-%hu0!dIk!DBEob6O7}%6ECm0w&Jm`C*ElKQCN?wm~#7JWEoqT zl4=8g9V4@Be1{k$WrT?~dZhGQ@c*$F$r^Z2FjP$1g$9O<;*DlbT@AtwVc{uY!Mw3J zhhy&&`&>6P7?gsde-#?B3}7#7uE+q~?=UrQYk$PN5@SA?La*XDt!*m$NlOnn7RC@| zo0v|t!32fQu^5TmR8~{U-IiCejDwKnov%@&At`s{mgWcgI1VfFf7KcN(4x8{4#RpU zI=G7B{vk$yV?tP4AfqqpeB*1k`J&xNi|;LyRgr??bi)%!f2?9Z;x9uIm@1KZQpO(b z?bIsNb-B0#;y1j`>k-<`177K?xdriQc9DL_%c>qtM9IOASy`x|eJk=YKog64 zGS3S*I?9+ke=2m{4_SFUQEmZ(!(bg-UsIDj{;n!7pHatT(w?&`nSm&ejt8s&>Tn~K zxcZGfNFJVBHvnAF0+;EbC0Ny250)~YHG%ZywghVAAERN6e}6_VOpWxt}H0vpM%8CxN)ZE%8&aaLNGgTA;BT5Ynu< zwkNe6$eZE(U6o}Rq#=ddoQT?ZajfUBTB7EaFAt$DQ*;-JQC}B-YY18J@q<|V=XjC~ z0pku8e|zR%49Oi}E_d{@Kx8|!6*t_DWbew(k&gcGc{nl=QwUe@YT>? zQoNEk_!55Sp~kzykn8)Ph+LIZ7o*5|Mnj}(>>Y~8^6%x5FH}I+CNwrlADPsy&EMUq zcjLOv`VNTEWGtkv7(%OztFefdCJ$1id26K8e;0|wS99_-GJvb0x_S$E1U1~BE*4>c zbInI9HjT$7Z`5T z9J3(ba!=J4T5Q<%W^OZ!r|3DK3yO&)T^Z6YxeFqu3ZIfRx3u+w zj~AJ8y5;GGBwHJ*UzTuH{>C<*zxv?^Y=$e{y`2V^gdWU(V;hJ|H#f14J28~GsH!8M za^vkl?``4s(DycTw*~Mvb^A5wZf2)tfAAmbQ9DwvgYv4f6rSVA{k-mQkGyvSXUa4R zi4Bti$UGhhRN!6^voMNtT3!P42^8zz!uF%RH`E<5fD+l0O>mWNPcMtJQU_Vxb8=y} zIE)Z@R2059=|AL;pAkOo@mjFa0#vv|7fEI*?fZ$vNQiBc1qo?{Lpux$h7&wIf5br0 zM0UT!sR`F&CDY*JfYB8~xf%ettFuM<5jba(+B%70)%9E*mZ)>Ob5j_xfn!ofYpp36 zw_s>ps6aE)MRIeqFe0OoWFbAR!vzq9>Z6g@WZSE8MIMafnQ&`8ON!&gDZp32c>%e$)`8jyAw4&;7NU`)-wce*Sfu}Kr~j;5NPg)4BI9SduNLHse@}ClfE4Ngh7#y5pxCN$(3Z!cftkMU;lgCX4Om5m_z_sEz zcrv;u>*iWIP#>M4JO1@&f_UR77FBOF5(!Vfyp~5|gr~$UDQ!xNbAO$Sd_K>LHB62= ze>~4W(4_2EV3;Do%na~7e*wh;!9Y%^FSDLJK9IdVK7dByUt^+M*mFzFVT0Ev<3J7_ zDNWe>?D56SczSqv^rbm0jbu7c%bXTV^I32ZNe;|6CELst5u+)}> z`gOLs$QfMQHQ$>~PEi`h7@YNOSuV1)5Q9VdJzc;)dbMimd@iVs&Z2zfzbc-kOE_3| z>F>l|XzLkSoKS14bJZu!dSV)@KW+U=*BS1T15D*{nPOV4l`lh4wt7 zNg#BL#Qu0Kqe#e8f635_d)Dg3J!d!Q{8to2$t=JrQ7~nzSLTznSVhg+Bt!@TpAW>j z>fp^Ngc!DYVyvqJMI%SB9PR*6{E*H)Hiha^Qy#+fO{J1xx8}_&AuW6J^t*%~n9`;p zHoDbno&SnY`7|KG*_lbgRvcBD+^obqdJKb*b@atNq^T9Zf0=Bp+XS?;fune~`kkgmZQWvSJnYW7c`uIEncXmG;j6PfZgJX7cP4KPXopfDZf5adLmrrYqq;+C zpFi!c#KzS3?g{qH!6&Tk=&uuXVf{_cez`5GV(Plee~DJ4g3`iGC>&^^EU$E?mQ0|y z66A#S{nc4iGj8o0Zd)ZRBvG=_mwLSJj;f&gR7Fn9`ISzO+Jo7(RV?gnmPX5`)&uSx z;kpAH69*pgE?`XD`I@-D6MWrWb;G9BQ`Z`FH|_wnJ@&SrWKw~j&De!*HwVE>j=}`mi%r{qw5)DB|w^QIm)BpCgO-Ez-a+@@FJAe1r3)P$2{E z{x&e;8l&RiXg^qfLO973{=NmI;*F4@AjJPRz)JIP3jtCT16xE=N?81{yNJ?m}9kYE_AmPUb!ANF%N zjLhRHc4kM}{?TyxDY_$~bA;i>!kn&}rra(NZ`J4)iqG?!JYD4lg(g46*V?g?lvmk; z;@Xczs7b&VLxRd9T&tG?UJMkq*;r3ADc)IEVSGmU!f*;--kN4QJJe>!;m zsDFqF_zQn@G|hFrt&3(4jb=qs|Iq0QyIz0Rz)?NVD!Dh7WsW)m?Y9$AF6hC`n{){Y z<@xy{Gagae?EpiuN_Gcc5{`YfZt^*=c&3xi2{CNcuvf0HDD(%Z&( zqx|elV?AD`|{bzw=e#mmoMIog4ya6w%%#>YYun* z;C?*#=3zW|7#~JKj9w*mwRbOncyaQ>+tGvJa2+e1kQSLBZlkXE!;Q~`=HsIM{>R6z zac4SebWP^7aLo*36)x`x_9~EP zTy-n+v!S8Ghr>8aYs}6D{-f00QJZAmG~}-zZtrQj-r>c0Cr~<4e*rZxW8&V4bumgC zW_CvqcJdvqvBGN09s>A_`y^mk-Qw-sb0_%A4lxv)eK*<9`gpGEMqvRsV9+tljVxAx z5lO2&?O&wzvRuM9atbSSe{a666V^|~nc_EfLZUJy<`R69=zKn_!j-TL@J6NyQYrBhYm zu2y9Sxe3XpQQ!Z#oS|X9@>uWe6)hPyVvDkHHLtQzoB%}{$k#)*{g&3$-lF0)jw1yU zeA^?7uDkBtfm_Qjag8%azUzR*PbhhGOEaNr2Asd84O*Cbf2Ofmc0s+P%Aivg`QCA< zRWMQapL`fPy6M1EONTx0feb;VQ=j)w4!RBhXo1M!HG=sEKuO;ciGyZlT_R^Xl{wn9 zWlg{SaNa|#mbeRr=ncrg{8z|2dH_@(lmtpLJFA~OJ||i+t?>T93VmWko;=2R_8{kn zuX~5X#ls%_f7gHbD^iS@1AoqODAdFOHFw~Sr9+fpjSAV`3Yc$Vxau863swuiS-3!a zKXF7Oq{_y9jw+6fUjG8Ff(2a%%vqC+MYtW823U<{ zI?F~yiN=jQLRBtXEb?WY*TBwx;%gCazc0q8<)=Ptf6|PEi~v%`4r}Z3^cE<6Vv|kf z4Oxh&SU@-Lfj8&EuwR#pOszu!i>M3s7wKuX=);uK#;t)I`XgY_TZxA#@4!_W4ab7D zN10GXLb2h-$%$s7b&G{i0~9+%2%EMvCnZhB;%){O6%kS+JSEq+l|nhq&9HYRsxbI8 z3qfo@e}cc$q3h+vY_XbWyBzZ;YS^&Piyl%dNg((+%!5QkK+ZbR1TGa?+)3iGqwHj> zV8kQuAP@o7f{6NW7Mm0n<@dO`zr(#9QTt+fscCt*b`erY34vtcZMsWk1KDI3crFtB z5+#ie+2>V`T%wiP`o(-N&IA~N;)r#1)2nR z!jULtOypT-^OvwYX$>$Jw&^TG2me`xWsFbE&Cr)gU$`>Cd`kF%zgY_%eC z%vv@_+);r!x?P%Hv<5*zLFC4Da?CC3WO)Tzx>F_E+91%n1ygJ8_bwq?huq3NP#gN# zL6)?O5RS-(U{`tDM#-ARO#?+p9P+yqe`^8t|7}ihjL2xOmOVPbBUaOlvwAiXYK>iN zJlr#wSZ5WwvaI( zzkG?Io&y!0y!jg*9qqQunI#=@8FjRSj`Eq~XUF{qqepBUM_3(|db-T^wb*A*Xs1&2 zI4K5_pZD$wzZrDeH|g*j2SEs;fB2lCjB`<=A*}b5kXP8+f+HQ*>=RJBbHK6a*J_hy zS@)a#UHIoNwpkoe1eqiUo@g7hfkB97^XoH61{Rn&udj#x*LYdD&u3wC`iZ;ks)@heI`}>fYwKDNEMY0Exya!Sj=s7h z<9Q2yb4NCFGk58c2H8yhqvfaG&|HtU?u4Tju~B29W8=CNx2T##wg!UWvf2x#-+OOs zoZ0cF+DVX;Fj5lEyQ{#meI&qaw(o$(o>SIlCI`D?rbZ$JI~-9*K~^x z6dj+t;9IQd#kV>;_HNP^lDf!eddJ6%!UA!u2uF$6}xqI>>`ZgY20 z%L4s-8XlcyXMpDI_C@0DZZ6|i+T{}4;pQ@j-sd6RRosb9{kEg(-Z~ys;Jo{A@mAdakV9B;&6Q5m`FVCtayEXpF_imAd(b0qa?q=&LC*;f??V-11yvV4{#~B_ zi^Plg@#^$nB)B^;ib z8{@&^PbL%mGo3y*j+cFS_2AWq1;g&6?%T~>o6dIe05Ed=BIL#MJYAIMo#G@pXQ!UM zV7BN;3)JjVe@d>#?l6s&7q>{pzUKZvVFWdx%8sm zWsXCX-W!~>A`Y+3B{$`+UD|71a!H`8w(7lIrk{Lee^4vQC{;Jv(p$_dL@Gx94h;dZ zQN!!!BBVNT4+anaq@Us*c8>Br3?DIjL!Gp@oAmg%NH3RCe$%HkXec`1Y;0J=&4W_)L!Cf0@+Aa5*AbK}gBbb{>{vLeP`tIZF5P-Cyp!k~evOHg8eaOD* z-yaU82FQRkUvhMX5cOKK@s(*!@LDO>h+;rR30!_PvhvXGY3wVdb3JV-El%%DJq6>z zfACQqjemzGJfmUV(!M;lTU&I>qZ(>vjqUeo&<8hCwB0&mEENwOc-^k*F2}&np0>6} zzogd@Vi9`GV2w9swptj~fEcrXgu`g;OZ%8F7X2B~TYB5ICb0E@aeM{O>B@@!Lp)v{ z2yAOp)$lias86jS*y!DQ=t{!TIfpBre}bp4+fPdMwrO@2N&@6>_1d1IjT5gsHxa!T zckUu9SGJ+Fdq!3tz%*7p@BHjyv#S}*NMVtqI_jaI2klr3bRE-V<3GHIJAzSOEmATR z1l^~Tfz}CGJ9`^w(Fb~i<^Ndt{=VI;|177aqObN^>v=u=;<^(*9Y#H60sM~;e^2)p z(fZ-;HQ>B_{qPp0+w0J}dTfiYqet=JtD|^u|Lb`0&0)005ngXVx6a_ULrAX3MlcP& ze&_(|=pg{={_X4B8UPQD;vs+_9z2TH-`u7@9^z(r`RlCzyk$G>zKwRN$*N*CVAR|8dp(obh`FEGR}ZXSG!dgMvfz%Ii>gGgRx?s_CU! z3l+=6t$HhsIkQ>Ek|uD4LTdSy(wECs_8fr`ii-Ttw6ZP0ATV^_jM_R*e_ZGpN~ckT zXwE*)q|J@9VNe95_Pbg)!{(`C2@5`r^I-_~s{=SD`#}_pWjrC(LLyTbgT7Pg7_9LU z&IB#FPccda#&d@f`iD&+>Rf2qEhe)npi?&zDij0E(n{ zW$x-QRRL4GrqtdZ+v~Vse~@8WTWuwo%xLLD(H<{FWt)9k zR}-=h>`+I`3tRMJMV}%X2Ghy5J6Nd~_(Hm)5RD6)A~e#uUiQg&h-`;QHGIQMWc&H? zU#q&w&+=^E{W56^}%c6X7^+%;(8x!?qY{Ibh6j&j@GtT zg3>`)f5vTT*=k#EYbcKh(I{fB@IGv;-hR(BE+Hg6T7HTm>*1E_9X{Nl-a+q3RjqWN zJJ)T^OQ;fdPkfNge{)jUx;7uDk6PYoFljx2`&7$WHO$h}x?BKOBELAw>TM{k;H2rB zD+wRq8{`wGQ4O)30jA}1EG8QqKB{{tBjg?itin2&SLyk=r$?hYng5xUNTM)U=0(&! z&PTUgoNs}xk$O+GvO{yPZS<5R8s?GUmNzhr=Ttc&abHuef7E=J!|Hh{uxH%EDX#}2 z5jN6$pz%7k3vciTyRP-tzOkge@%o48fXZumx>3ictq$W%sV(1KWUYA%8B^>)!y|g? z*8HFuh>Hz=2^f%HEz8r^L*M@SY&cZM{=bUy)Uyr(Tzq<4n5$2lw7<*h@EC7{CvT5h z*T&n-6LVfJe;Rl+ycB4_DAk1!F;8KLHcF_AbXh;yR<lqcI9#!HO+A+U0wqR~eBD4Gl(Vx20>ss8> ze&!Z7zq;*GOFg0Cg|g}Witn1%jbW_mlh*onNXf#(f5F4nD-I=!>vChGJFhzh4)fh1 zJFh#pAQnq0k2~a-JHU}t+}vfL0K?ARwMGbUgoWzLz_48e3#-?`4z-c)eT{X$GSKc< zKD^tL{~LOq=c*D_i^Bechx6<_>hYSIVnO@mZkOU7(DFUg35Sh%N|8*hbD^{RC~TLS zv|8J@fA6h#hq;T}n~yr>L%CbGJ1(3lE)EaBUVe)E`0v&g?5elRUbcw^RJRL-cFryL z^jB(6-#>Epw4ov|p0PTCPx`(LcT}{G#;gFG|C;fI)rH);_q>0T@4kc#piZP}wcB2= z4W$%0$L=#2b`Noqu2+;TPE=apZ8q@T+bU8+pJWtB{QkqWqj`X%h2-x ze}*~evF$jWw1h>SI4Z0Jf3W;z`iZ{MPxyrjkgN!vEiLaG_SC4T5+lh$v6l`WuD;;F9q@R1& z)Op9-25Gr>P16AK{6dj7@mC<6z!db(*4|#5wxSJh(Ol=Y->^~9TQ5Bh0HpW_Wl_fa z>`JTyb?{%=)pJ@4*WF9da=>CN_%3ER;t}9ZE^RltKw&GM;yp(;@mAmTc#3Cbf2&8_ zb-c`r9ZK!?6zli2+p4R5l*nz??OfJc^4lobqjvufLb9~Y5J2#$o$t8D)3HSLI~CTq z!A`|5t>Hecs`Sd59M_sm{l)``2RsG@e0{MUK^&Y=0r{ZJ1T!YvaF+RYDi!3u1YkoA z<5r*DPto$cD2w5t>u!aFRpe(Ke**y1kBjn>Je}-@L%ea`HT)jK1?dnw=t7D@nRkLq5I&vXye|JGnQ~VgG z9r3jF%A%o&Ex)XfHl-G^-Lkn|Lc zrLyg>Wbv04NJ7_CM}1-oDy|<|@VJ&HUMmv^FGNxo#1ICv)&?GAt>{3q!~Nh3;ciB* z`MrCh7o>HFL->^F@tncodqn2(KCWKnS8~ zU2L@J*$5vK3p&6x4A>JQMXeW0-3{y$b1_an#r{`(?o-nDe`TbfWQC8Od~5SK z@kQlEG0($uktWU;1Fa1LSylKBa+bibH&eE5G*HLdjb^16c#h9B7VyMW_OmfZE86kA zaT5muDv_c5>)}bmy#Wnbkg%T+=Oi69M!V4Uh{y zCu);yx{e0_DgmVhJ=*A&gsUC$K}3-=M-W~s^;XL%8}W-AEO=}jA)8Vwp#W>w?LsZ z*&7noc5W+{HVmO#8nYngx) z=&?CiLB0z86SzP|n{wHgr&R*|y&??ZB1L>&vC^AZ&TUF=boV=8GA*rSiEt(`rFIrIp%aJ)l5(XUU7RveP*W47EQej~?ty zn!S6Ne_mU#x|B!q&^F2$h2-#>JxQQv7FSBS#M+h|QTpUC+0~%aCybIE@@Vd2C(*U+ ze~kAN)4_?zhg2<*bNyzty<~ViV%RQ{MVcOf?w|`daTVnmC6@S4XBhrekW-5#a`u-< zKS|LCuD7p`h6$kO3Uq3v?A?@$P7^fPnA5)J z>1y(Hq2UXvj7qI4^?x8VI_8J&||d7KK+f!?Bk+UvreitPAfy!R4yXXH3Mm+81g`CkQKF|0%3!-Hd|f zLw!+x+@+B)^A&-s26hHdC-&y2b&1iy+F98$ugiG`q;IyL1iiPxerNst;Dt9=e>4#R zv`1Dppr#WHX?5&P9RBf zDq0UkGr64SB6`VcsfpjR_@Vre{j|gg306=Sb+o@*Ef!Z46w!51c+l!Er}>BQV+wJ2{LF~=JE>tfADXg$z5%vJNNn@EoW$dgL^}Us*b|4p^kog2dXkPC^K3iMicj}xr+pgVHsBA%Cn;xYf4%u+$zSicw|Mh={%t9b1iH2k#f3LR$=_gO0 zy?gmLpm`*Uaj?tX@CvWuABIn?DQx3C37=ukNF| zL0R;6rtOx!de{evXi>$gVG2!1z&~Fe9b;KgP z8lJ2nd*M)4?_k}sD#b`wCgI!`y9giz98UDfGyYs$je0VcDE-@kM+6Dk=-#jos?p<$ z_LskzRgpI*<=M$4@VP5~V^hui2C0v8n2jy}`yA*lfNyn0Zh&h)f9N?(y$2Y(o@qkB z|EBZ&AAUjp&R5)T+K0SMe-tga+g|yYodSY=|Jx%<3{aNz8{YwZn0lMYe(Z|o$K4xl zmyi_OHhopFXkluM?$u<3b zu$vo`Q-;{?Egd<_Mxr0sNMfveBSmzzh+Z>ZPRdwX& zRh|3VM({>6JFu(mH%aPv_rN}FTSg+-yCB*|VXfJi?TCYCO^`zb=}XFNtlM-_ZH?R9 zG%Xac4c#(GOgpM|Y%E9@IZcm(9gm2aeP526$#9C1e~wdhT&@$8{(y70 zr0jyVe{8swFa!P@?ao+zFg`@}Ne2fwdjP>$h^5#I_ZpaNc5?${3B_iTftZ5w?950& zox&o?U~kMeAoEb?pHi{2x=e^~_DxVB?oiU63f=iq28oCq_HkS4n{ zL&-gAJL|K^a)E_)RU&<1&V z0PUkvc3<=XTg#q!5BP%`4mYzH*ydf^eaX-v6hfe?c$3$^wP`pntJ6gWh@ixD=<1!F z(gVa?$(&*T&0%_ak6`9F_(G?&{QVMo0wgeREstE9SN@Xe-*No z=xPJR&+ZP_Tdprt1MW6FpA%yoxmaK^dmF`xoF+99P&4nzZb6;3f2X12`|POg2?_ng z7JjF?hW8znX@^cRO2A!vo{d)3A|$FipB+$2eSknYG2wP{dOlbd=a%C`W*tUFDSmZ2 zMYJVhVs>z`(nW4g)5xMH5F<}ce_6T`v*BsDpffzZN_qkB@P}W0VY*i{vU-C@wQPL= zlbIo~WjAIM-yG^;JQ+~2>y6IAv}0c7u=j40zul_RE~4R?GZtZ&akeTt^P!q|UiX3E zl(UlgLu0xr1@-jv{+#D?mDULdcdJzAr>QW(HpoH!iY22)YvIKsDKqI7f2|r$(;h%U z_kCQrZ^c072B6wr_8!)4I0qz~6i8`K8}(t|=gU5tN9X0L-eEYeMNx8LfrB!2 zTy^oh7Gt)jE^F_sZY!oN7Bvt9*Jc^eA#VR?yi_kC*WQ47LNuS9tKDu^c5`>pO2$iVmQmmL2O%B1(>}fZ`?Hsx-${Vm zHe^wdvrQUXRw%D!Il}_QFnmv{sf>a+lUcWAsaFV zBTPdSg?4axf3!gpaOR@_dIJ#Fu|_|;DGF*#R!C%rZUNf3X1C_wQnZeo9sd@7o$P)=lat`od*>nb$R$e;Yl2`SypGZ{N1`eD5k(+X(x+ zT>w)+tiOw$511V~fLIDqhDEPaI72aOXYcu)^3bv5Cgh<66qq%ceH^!|(+EiRXBTBz zyQWW=^E_?RE*}Om-w2`TBAJrcI zr@nLnZ~B1me^RnfV8&QKz)~t{Khk0Mexs3!`+&u8mdi1q*jY+iv;Q>k;sPL zXZmpDQ#r;?fSJ{HaSeV8z41MRNtx4-40R#+)IvqWTO(t%1Kkm54(3fwSTZaJ!J}&RbQAJXGEROkaEIzQ? zUB@5t>|;k34SbV^D1#0aGV4$bOX{$}UuQyb&m2bFGde~kQll+fhqQ=G4B}hfyH^RX zH`;BWQ7MRBLf-67)HM2(USMgGthy`68lDez9a+jdn#*#ASz@@}=vp0(+@ghC&v}{= z3V$2LJ>Vg`h}MxlU#Vtihd`=U;WEj_%g0xPMOK_Q7vtsresrCmg;$g1^zlOs6})5* zu4_uUnq*UCa+77W7DK_L{RAeaJ6X{@OYR6`4(IV|Jlso?OmqWHRLNu-*Z5DK4C8D7 zV|kIzE<&4X<8zPGD2~Hwuw2y_kP+wmNq;esxzlJA)<)JodSQeTwdm{#oW>+Y_mC=O zc<W3na7e)8U<2cFOUbIwiNJ6V7L#VugW|49XgOR&?IpKYZWotn#Id_ zo@foKMN+XM*|%5W1|A;9bCF!HWhI=P;6be62pEn!8m+=&>sTW^L28W?y(v184s1Vpw6H3$66t$zW&^geCACW>iL#;j3=m93DM$$Xzo#mfU#xH6$aB;&ZiR!$}ij|Zz z6y%ZwDNO!F%HwdvsgTqy`hNj_E8^3r&7>`R$3jjXdvoL=c&oyN4-6j>S?KgNawH!9 zw}UD>tFrncXulo4;T#sEvhsdjf0s403-+qzJ~X_MEin(sF=^_z4cvzqDDqA&VSq~q zlI;SWZJN#Q&C=p~qAlCQ;PhvU+zdEmKWJDBg`fqlX7(O^ep;OnOn=2mHB7{DPxg2V zrSy1(!IRjfAVH7KRR0E*i9Z1nybs&6ugf6sAq)d(@N_UaTTTLNzZDhCj(bL3;lz@C zRMK$XmG8i>G6n7dDJFKge4+wOLvYMan7V}Dy20#twGDGxKv_guI2 zqqy(7q9kc~FJr{N(-2s|8*E~yjXq8`@aY(6O5J8o3&?K%xSGLl<4wk}3>x60)n797 z!2}pYwX()0)qQvCHmRa+RWg#YI>3lfHa?Fy5+y&=UaYn%#i41(Ty(f zOp2;`lZW`If`8%$_J15{E+5%*HG_NiiZ#ZmYM+wZf@14$+{fK|d&di1o zibz=+Fo~vaRhP z?tsM$Auw1Ypvl$y+~X0=J^V>Wx@qCXo}&L}Q74o8!+&A?75wiT_}}5ta5x=Yrb}z` zEcFy9?lOh5`~%88!ytsyC!Py>!G4BuQ=&jI_5}v2`CizqhaH28;=++$q4WRQg=eNX z+&0q+K0~RPA$~ZOhK2yPR4&$sJvi%=p zd?DtO_oIK~a7TF_=jqdnlK2nq>W2PLX%$(;~klRPb^R?JH^B zObmQwHnvDs{c^l`QXLzOCc>?^ufZhA(OA$Z+<$}%3YR#~mfe^&uA3TNg% z!q;{q9)iVyb$AtoD@#7wp5cY{6soJL2GiuPPFIMm&)ynzZIfFWwU1UNBVG_Gc5X$c zGkKxt=B8LJ7O{vlWMB%;7#C=3DfZU}#Sug|w$cc;5f-);=unH2+nlZ!j~(MnLcPoj zOMlbGd4ac%kP`D82eu7YFe)rn9qZM>-s$Rr2ZdoMGB0j!*u5qS1D&^a|6B5ti{^51 z?I_y&j5$Z24UZl@dVVhR8du`^P&hbCW{gA7` z)i9B-@INh{GL5MFfGTJ2GYskQUW4VE)9m4v^78XGRkR??Dc=f}?bm|e66<@XN^lZx zQJTC)X1A!I*UhZs*!R-_Raj^Bb{}XEl?AJ^3EQdKHx2^!<|3G^c4Ry)1kEoSmUd&PEWtm zIW&R?Jc9J$nO^0x!mFLL&d$=WkG>i!Qv#l)G7lOY9*sN93?TFVqj8rR59B_4F!q~# zK;EOT)oJhOQ)ae1Rhhm{ziwd>Wq%4a7_R>;1=8=ct24Y9>z=^M*TXNaWu_JiS0z%c z_#op+TcZhDccuFeznN#}o|+wb5A5maFeiw0}%}YCS?6 zp)J(Kp?A1c+;G#_C1UA##$izpf@<->@o;~;_ZR7dg9%p569e;CFAq2`m8YjlwQEq>Xgrz|-P=+C-`27`lBR0}*Ybe4^> zJ9_KXmge+C-f5nz8*Z_9@n`ps@IS|Er%^)`J3GYxqA^PBq&YJw8!HJO@U>d^nS2BF z@RA>&mYVjRQ zr*OeOxu!rrq<CM)Iu6o85q zQ5r^o{<6gLtBz$Wm*iX6>w}YzX;p;5e~VK84J2M~o-M0vh7T8U50$w88@FXP|8H^{ z1+0vWcFxJ%3&tG4;ZyJ&CvL6;BC7aV342L$crfgKCOJuEi?rinb2B|XJiK~Z6r`?O z4Ww|H{eM1@Q-M&p!?UQ1pr%C%k^})<-oUoZs#lZ|Mx%C?2(Lw9pSiv#ZYeIj^nk4QgVwRe1NM}p=1vhAsNCK| z*48}^ak6`ImYD=m%&$piWNBhhQ?cKIm^Tc^@B0YEH5hBei&N0S&{cE4j{pe6%r$#pQC5TMi z0vMe6|84JEnA=E>H2(_N_GkgC0f8E6c7F^A;%Y`3OS>a!PSV)B$6+v9M3Za_1aRo4 zL@k7f`!)B&?w4FX>XG&6MuVj092;wgEuy*}Sy@$CSyh=|^4`i`+%z%!K*EA$fByu9 zKV1*xj@2O5vD?u$+Ql1Nw&e9k!*G|2o(!cau%ywLAwW-GiS(CwSpx0yoQM)zW`Du6 zqMsHGjQ+;~F_Ml5-6mg6j?K=H-Es*{)~Jt(v(0)1Y#1esXrH82_MYcM(%(l@9l=c) zt87-sJlC=1nDT1ubNZ2XU{!&3m`~AL#m9_?)xxy0?I#}gv+3t>t2{>M)>l!DLmjE2 z-_mI5XXVMi<)8g>oGMHFt*Fj_fPd4?bcJudnEpwmz*3jJwKNwg?=#&(o$~(?sZSf) zg~N6lt=@c)HL*iMQ*{mB)bwuRPz@>3)SBufb3Qe)#i>AYkhXE%h*de7Wqw}e4j;?jIlmvl5Y?9> zS&vHc;xa(D_W7;qloA+V(C@Bm>Z+AH<$Q$Wp!SmO(pZ3 zj&LexpHHF*X;@AjKkQWNO#wMcs=<0KelT*9Ou8K;Xpdu6pmEPn`zSVnA z&Jg1@w3}SF<=RSie}DDpwQR0z3+)C6JcbiUR|+sVSZi!u4chxp|1@q1qpRPSW4noK zf@5!w=ZY4hWT5E+0jjTznM5l#k;3d0j!Ml08YtWA(>SoaU%NX+z+=u?Cw6T;Q0ZwQ zOd(WpNb?@tDU6z!G8(+kCdGxz&VYS&lhir8@#kkViW1lmz$r`6rt+*wRcftw{m@#y|n=sf2}3ltYm;S0)9MHR5_*X@`x2) zoSuRlc}^4hQC;2qIaYbN)*30i+f2aY$rcKLVUpni+nhNz36s8j@t;lch=OLquNG5% zKPU_6dvuvLF#BfnS99LkqSyBxPloDv?$*Tbit1`E;7o+i;kDo??qh2EiFK@|IL&q{ z8@u1Be+8eBhns(e1J?5A;{6KrHFNw~OMx)sk5L~VV~#<$Tc1a8+Q+s0dOrJ1PdKV9 z8NsN_t=QubJ!ZtK@NSD#g}<)Mm61)s+oCXooqQ`TSBmlt3LM2-TS6b@(OO5bgq{Zk z2Y$?EGu%r=t>mL{&;_{++fhE?_ajxD41YSOWLbgxZ<4MC7t91LmS9Q!9I~iu^XYq% zx}4$)Uu01ZRC`*`Fl))fO!bj2@%?Ym6Y8$*zFfKdsAS4nwyEYLTne0ZPSgi-T(6b; zYJAMy(Y6uVj0sa^vd)&p%WOGXZ&F379G5n?0WE*Jl>OXA0VryBW}w;xS2ncR;cuhg z?)~=7ZwJ5K`EBsqKQo$|33RA1EC@+NSdL)AOsbUc@ehMfM@sHqo}9qK2&Ns#Nsf}u!bV2Nf&iR@UCGO;M%ObyOp;%q7=)5QrrC=K}8R!MH!bTQI<4;n02CleUA z0ciciW#QXJ%oY@n`L4}W3KMJfncZ%1P;`H#U%r?ecyltY#0H6hwLp6RK)QVwXN%c{ zpe)`I^1kEuNUcB4ChD`BkeePFNpTjpITTUag@`&EO5|YbY4ORD6C+*WP$Z5xBhMy% z;Rl=1<&s{wc?txb;-NGmWtEqgvuZ*eS?wQ&x~u|o(w z9RD4~N?*x`TKkxo@Nu8*tb{RW-h#A*0X)AQ8a`TwwXW7Z;K5=GsJ9NfuV|0kC zPoF*wxMf60yZ84Jr2m2L(ZrEW8>fF)u}YyV5supjp2py}J%n*9EdwIMP=oCG3}r}$HrUl;M^Eqy-ZST|rfUU8MVQh4DH8M%)ZX{_qFIp1NN;I9u zFlF^oWtE|a?TQYd=7-ECp&SWBui%YgN--k6_@UzrH={R;Pu;^Ronq!AMmB%T(+qz> z+AOdc?WGHKNCHB~dgHg9;D?>@4AvtEWouX3Qz=qR`72TO4!?ihMPqnRc8e}35u?R2H)#SrDX}~%fT}7G#f7bRPOnmV zML!BOpQgWhclY7LW1S6Of=!uTI-LyDMbv4W)LED}Gqwj?upy#{Dws`(NC)&L1}>Nz zH9-ZeVR83cY$zzP_nRK_&Ey`Eft1bpf zD9WG6B@2EW@QHY{RTO{UL=0neL}%Y1SQGenmOmw2)>`A2YYXs{sD3s-qY?Cg&i@fb zyBc&7%$HgSBjeIi2xPBaV~S@xt51_6X{*Hi88R_-N}0Miu4761@yQiVnjs7ZxwkJiHOqg8NA3xX5$G~_$)0>S zOj5S!PX7E5)sg&aIfLWIYP8PSDSvdB08`K2E&k^MuNxD(l_#5ocZ)YU$UsQr48LUa z}7{j|ON)r1&o9Eb?W*Y%w--6V=&lK;1=A z$nbh3GP8l{+5mrhHhC~~(pUgZlJAG#B+dt5_2eO>^meNgyxcf%uVrXSd>-HRaU0>C9~Bwg`jhHBUtKIv$f8Xz?0LncY7X)J<%gDn|gcGtM3y=cp zau+8FtOoW))2auFh`q?!sE++)IuDS&??Sod%q*-UzNPJ%*Tc2D33A~sL< z5kE=o5C;Y9M5Ds)Kq01;-GrL92-MgHe_s?-B27*&@xAr%aG1hI2PcvJlzdv*uj%zE zbExd%eHwhr;@?1hMDp~#pjGnt7;_1v^|l$1MAZ8o0?WjVLpB5Db#8%D)~!FbH;S>=t78V~7r`FP$dp2JOkR;KwL5l!_G!FbCjBWZmbD&%fW3ddK}vHUo8y zmI0w(Ge-$6H0IRrh8&f^$jS*?M^!asaV)B)xG!A(MfvPvS$*ahR?nFXD*I}|7@~%@ zQ`C8#5bsU*ZXF%egs{`|>043%Kxd-Bn`KPDB;B~rfi@IUvrv~6lt4pcZLnEmbSN6) zJ)vIUG0Fh9;tvX@sk%mq_~WMi;65}*bJ=1w6J43kp<9ly=R{&=jRF}F{LN1IVMuMba<7UPOx;Hy(oxUth$=%Tx6!LqGm>07{Df!2aKcHFXpF2FpZ+*Da=_cudtz3kVTLqhs{FmX^)3NWI>wZD?g~4d_9k2R$R&&~3oF z3cUjb8TTBokA^f8-p?te8|=`f6B51 z$H2xSTT3WRkcLJ#f8bKDK^m-{79Wp?=Co7HQRw&CBA#cBtRkFLVP*RfcNmG5_AN}p z&fSizRu3uVO7AbPdcCm|s8avZ*66}rXy}E<9BP7IW>;&k0gC||V`%LJX_`daAwC;s zQ!B*J<`vTt19Zy*iuR&z@;1%#f7URm+b4ZfRkd@x&7v?<_9fy!US|M=q}$5>f6$rs zUweQG$>Du47^h8r zJ*PnC`jf@iu~`T?1uZBvd7*=jK!S4pmq-|fG{3;h8PQ>q?@AtnLhucge|W!gkrO$- z)3w?kFBkM;+NWUHCBbUi`z2zq;5CToq@&Sp>Apz+Pyvz@uT5^3+a?+LT~_&$72bS_ zr7sGKQUm|cuk4C`Wmou%?gA(j4*v0y6YatUl@s<#4mYDpD0bM+i~BF4;`irWG2exE z#XQQpVvf9h9NEe!mRfrJfPl+3Q8p?rod%Ia~wX486YUAujpgwet+ z+kOgD>xSf074a^#s3Mzv%08DEtl*bozSY}jlP+83D(Bg`ike}gtv(pBJFn&sQG z*ZG>D$(1(fhU4rn{2J0_EBu0te8$>gQA;0usUovm6RIUCE+~k0mG`M_yd}l}R;j$u zDab?TuWEwA2z4RlOr?}6NddR2+UQeCK0atSC}}w60I>fC+CGf4n}FxF0At74|Jf`-wW+vNiMuGW{O#{ddaTjiNsloA zhwKn&IueTnbr6XhRoG4x{zyt$$_jRoI@5_zsZ7nz^tUw^b5k=C6bRu+&9G7nmuA0m z;~1+mbcLaYBni^@O*&&xJ!LIlYX_XjtC-}8dqQ@aEk702$$2+|KLvjxNkz$GqnR}Z zvQFqaAW`TebOI;81*nSgs>YOyJ~+Al-OB;za_2jo%F#VG6?Hmv>M#EuVcOOHF%F&j zF~lEt4e`?}C9gHg=j`MyXuir<8Km7C?C&p&vg^-~RMvh^{h(7yPY0jFZ!omBGF6w2KN@qJp4yj*UkVO(#|mI<$haHG`Egc&67UA{Qi#5;8QrUXPFC2x zdzFqC2qSX0{F9OTeItCvT4`7OWe|bhCZCmgClE|Ee8anh@Lhjc>R|`XRgJ;~^ zsLj${l<^)UT{eG7dP}6 zQ24~R$nwLa{=G0c3Tlw@oyxO~=q}UW|E6znrOf2nV8MT@CW&~OQRg259{pA9G?PQ4 zXKJZ=83p2QHyyZkSuk-$^0WaGiR<4sRne z1xm&(RW)2-^rB(Jj(XbR!1P-2-7ejBtjNAy#&du3c*x7%a9qS!J=QYqKnoqUh5JsW z>>n6zC2p?T94^7k^~ly0Y11loHI%Wt>#dO%>u5+?5|P5&)%)n+1tY=S8P!p8y=J&J z$9}B|Bi7pNY2T~XW|CphE&U#`>xPYQbdoKL z3T=O3^UZiOu(`9#tK;)Lt5TT;J1`>8=Q8m$n;#>bqf9%$yeOtc^;xDZ$jJznTadf_ z1S1=y3b!ODP$h;hEe&~{D9MyV6WfXR0P|?tJJJ4N4&9SZw0D@p?N_Iv$C%spwNt|Z z%q4x=wy;FG=!EolXdV^tp?(zNc?6B-`&xfve`9nr3WqlA3^xi0bhTLGgFD6D6w$h1 zq+m2!TN&9P#XH$`nQ+J$_bM6iE!O`3{ zw51Ccq24{+MQRryr|X6CT;-0fk}cz>8)`9zGAj?@z8TQQNiGWp{L{2=nXp?q=I+^{ za9b^ArLmQBHscOOrvznkkyY3i`Z-Bn>k3UN%B-q1H7JB|lozN-!!a>guMK}OFAx`W zvq{=`b~X!C?3DvD_QyeYpd;lDG-%;CdZ!sJ&Zk{^hB2Y?g=WV&K7G(pTlmao0nIe z=TKS8US3``cG7-s-^blOy~B%vYkBg?=zZ$Dg+O!VaLh=vFY(jZCC~_doQ1Y7EreRu z0^-gsZyZHn<@^MtFi4OD3uVCX!hgsfo zOjd7k!VCL(K3k%haG5(GP825D{2Eo87?I(TElR1vhYf06s z|1dvF8wXwQsm*_+>s&y({u2k?&>mC7ZrB4?pl$7kyFWMg#?1?Taub}M`KsLwdu2uO z)*jhizqvOyAN0ijP`wBWi4LH7NHs7B7?U^xM%oTv!yFB;+Cg=m&$}UJv7^y;okTZG zLpwy56U1Tr+OL!bc2K*4q!x&&WLo<3w&s+HI(}QVD&+hee*BOk1&^u&f6amz4jS{zZpM!_)#DJFb z4C}n+Tnme~y5hd(MG8r-+rLJsTWronhRRmMD>rMyJw&CWOxCnHiGsHpNoUK}5E3u% zEa}FBSmgtsHXgbvICKSqFRhUzN4+SkYgx2?_vC;1KpQ&!Eoj(^QI#48#mZ6lH@(`C zzD-J9*0dnkDG;SOCM#nD3le}p;9Admjx@^fs&=J0KR_f zCs@mMnireR^;^ds>{$J{Ar_kzt_qs(mKDQ}`HPW)363&Q77^UBPr(B$IqKCNLzIa%kWIg{cA#H&k;TDgj>k;7_$q`d&j z{*qS}hIdqo0S9MG^<9eo%D-M_%QTL4d*CP;X7?lbV1nD{8xf3l42$Z2XyXNa<__q~ z6e~$N9iu)wIU>-`Wm-^pz13uI9}yA=Mp+{p_b{GUNiotO19`i36TKBDrn4`mJ^p07 zlB7zOz*xXW*hbY zuMT{ze)<_?XK|vSiP@ijWu+YnqRS~wUcP?wtpDQGPp|vo(+qL%r5f>fFiSwD464Pi zOPFjwW@X;(rB?K=Qkr>2`@v8c^B`hj9U&OC$b=reb7$^^CKR9AUW}EO^WRtdX|1lj zMrgn8swf$NJ%{NEt3~|?ZlbQOqC6^>*<2aG{Fp7-Ee8H3<$}I{)k7_7nTPo~9w8U3 zfmW{7cCZ+0Ii}^fT5}s6em2WLX5vOGMo{dQIoIWyw64|y8|PgM)g-m!zXe|Z4P~?{ zZ9;BORlCA(Ij1ablp?M;rU{u?Vvcm4=U3G+lWk9^s(~GAQ5~?=(3+^hLw}qf93~tT z4q8u+K_HgSq|73EDR$9 zpD0GOa&r2^kKf(@{{HunT3)`tD5^-@8FiEYU>{URCnk%3c0_q#!Q|<02Tl3@4Gx$# zP)mWn*39AeGxiNwI-zJ{f@GTWxREHSlQvGK&ZBH=t+QhO;rMbjBh_=2pVq?Qi+p^Y zG)a!%&$9W4I#Q?v9=1^MWeOr+vx^2T*-9N{E9<+fzq^(5NGH2+^tial&UhqX{&mXL zNgX5Ng|Pj9Yg*$L`D|KB%Tm`3Pr%^w7cS6WuPIhdF(u1ZGL}_a;y^Q<6CY7AB8t7U z@Fxr+2zC?k27ge*o2f}Ed|OCrH@LC)sCD)=Ga$Se6E8%u)JZMpBlNl)2XaR4d95V zQ6yF656B^Ns#Ok}eGud)dR&tjA|(~n$1zb6JIHRZaw+Pz$K#Q?9j(L}y4r9>&RDtq z4z(AV*J+EU`U~a$Dik1YXT6b;ft>DzOiJ{aQlQ0x&pcMYambCbSQ;!)?&A~A{^biQ z8XY@-XYg@A(H@*g3vGf^sKWF=grm zXB*z=FvendCm1)l-+Brh}4o)7`@9O*@=KbwI+^c!uz0<3? z;HNfB0Wa$|H-r|?`;Be})%DyAss=X$#R)f$c3>4*5Z^53yn4$v0oJ5+7u)I9&*^f1 zQbnwSx4)%J!|C89y^34B0(Gzzl@-E8`i89eojb|m^t7FsuJUW(&KzqC-0t46H_AZ) zfWh8tQ;piw!g}@zJjqSH4JOC!gsXJ>3-s?~*~l4w-#gsK>w??3qoiPWJU~0%Qc{#V zJ}vn7lsCDpWG1(HOKljm^Q=!N*?by*3jw!tcw!xSSU(N221Dj`-lHLY8EgD;6_hYr zeK3d>>QirHQBTNwb%d6DQb~FcugAhFn3@zMk%*iuLwntSP;>i4)Z^Hm*i$Nvo1sh@ z9m4VWgzt|Y-80`@$9j)|B(7F9MLAioKPsERI>WvlW>Yx&&U8A79QEL^coHOkT?Bjo zMX>LG3^sTf$)S0Q(gkFHiRYzVCg@2v|Cp8Qlgm}PSdC6ri?Te=ij^H@&d?#{99d0& z(6t8LQPNW}{l$aI*>`5KL%qvjx>$9!uTLVli{_oWGWBd5XDV_5RCKYpEOT^x9>KQt z5`R#Tos`lqmnQYsWdhsk<;gjJfm37hJN!i;(&|e-pPFc7o}Drf`z&*^&Dl zh`%k0!@5U)r02y%d92`SuS2*VgVISq|NYT|(5*oY)G3cAoOE}=n7{VZe?Vr~v_t~t zg%rrji(F}wi@7^=s^&gdoSNc&D$N#^(JrM69g0GkEYI=T27C1aFW51RIA%)s)BPUV z{}}{ss;|3VjmU`N4F1`FKT6-jKlhJRq!P*zGpUATjR?t3yp*KDBS39koxLB~yjWd4 zl8wd=}69u>M2 zGZpTTbJUohLGQ>`rX$022(%6KnBQaiozQMyt#$i)NZZVc+-^sDx(Dial*V~-{XY6eBm3`aZ)4TB;#Cghs zgl|~}pU#UaKeh(Ub$)GQ8~k!)^K}Lf%TAt^Nbbf{-@Ma~vW$K>q^IoN8@g{BqHA8; zp^noza;q~P>^PmpZ=%DUy54{PKwl=qOgN?*I)3j&_BwNa?_J&TY&R0JT5``D9d*Q* zBtO`E!iUS2?mtuqB3K3DFk~}$4pZWy)z2fYTmyolSUQ^7%{`#iCNIuqNB9!wBCibA z-TuP|sz(o9Pq3=KC;HotJrFaZxeI^8j2&uO5)VQk?|)jXrf_(_iVnl4kM%_BZ*7S7 zCL~oORR=YH8o%&6wK=BUM-Hk}9IQswgskaicP%W=ZvWmqI(wrr9yh5oFKY5Q!w}E2 z<<1=MPt_$i<)PLaKUqI4i$c)%jSPRm|Pqt%1ed&gHrgZM40zP^Fhr zBQa8E@!=(WjWh~QA^AjTb@FN)b-Qr^biC^3Jy0Zn(cw$oW!K#$zk_bQK0WQm?}dA# zb{ElV6(q={<95z+wzH$0J^HKL>GfBm*pA(Z9w9vG^^Zrem|sk>s-Fq=k7#%-LEMDv z5|O87qK^)X!3tFDGx*>8BX)f>vN`IdLml`~EPu554n8gl_2NLK6`L{0%&03*lRB6b zG@r_U_ZHF3uHkXo1O~xa$Z4cab^YLxhzCiJ%BT7J1@sTJ<(zCm7nfBakYv^B>~||9 z2h{Bca<1(=4aF)wMt$~o0HUDA`qaS&gz3PA{t&@~Xht46VEfq#KHVE&>yL}s5kWx7blB( z068sba~lWW%>cKvT!bJ;ENhs?KAJ7G=Ic~{ca5HTjE%2aYA^9hQ4Ohi8FFdha!8$d4T@z5 zs6;7#d2tOwe_dXO%wLy{ME)9MBu>))Lp?dHXvJMeGwYS%Frl|?5JS&6%=7J0;Z zXu&F`wZxmL<996%&EX+4#Iwp1hk5y3pJTnfVJp0mlBJzstFfjSF5|_DxY3(b*QllG#-eXhyqT`ik>qj=(P)C(ZdUu)5rhang<6|m$7>#^qM$0!RK z$k7H1eoun6%!w@6n$^)$w&pf}yZhFhtmU=K)-cpjiMutolqt2DJ#DZq-zI(jXtT$h&yd>kUQO?b zX~)mv(a!H$KAi&DnIoJNSfmOr>Cey!>?nV7z=!4eNfSn^%0-ec%43y(^8!Dr<1Vq@ zgPf)`^<7T<$q)$Z?%#29bB=s^%%TQ%lM7gD`t3Ma6I{uI8&raQ<66GIRxQp-QhoaF zS~Zzf#Jk0c!JF92#4HqSyPn*WLL}*WC!}EmyI^kW+42D0U+V;;uw8`CXMZimr3u zAB;wUg6{yKyE5HH-BD=h)t4{AH7s(pj~7GuT2m}?gqD^c@|x2~-h)s|aqmdntBw&A zCjY7Y2IChX4vlFk7`9i9_DZLivvY0l+gqi11_cD>(U#d8$zYIwh{Z)uVB{k&pY4uz zVD6ts>MxiFramnq8!JncZmIGfS11WZ9qw?pstSr6^T?TMP{y_?OYjLE368oKL1*4` zZiT;mVX@QX-5>@AX8fZe{NLkNxfPrZSthl~za0Xa@`muw2>gt5?U*wl?laFhiCk?? z&7nzHu+_$z5Q+qUG~j6#qdlpFY`jKYGgM(a_s4<0$`~uv$rk$CV)X%SJykOZ{FJAA zL$7Mrgf?0^X4zW(l#F{L4RF3dOms^gFYG>+P6 zQ)!e9(VY~3w#I3Gu{cQX;Xn62$*6+FY+2l6;$bUVTzx)f&;EPKT?<2Y zH#w*l9}r35uIpZSg4W8%^le1WOC##Yy|dzU{5~u5?;fOYhO@uCemXmU@;{#Z@C5(! zWAXIqdN-fmBa$HDUWkRlsA!!Rb70^lFFi&-xxw|5=D;qPly6}F0@lA; z)WK285nOTR<2mO3^5t5bXg8SIEL&Y1tLs(JQs$tif3;WLEl-95z(ik!o}kB~H5sET zcZ8CEo07p8kO;rk)%P_2iEx$(5Qnf-me3Mfp!pZW)0}_~{#uj;qy0E|CpN>gIVC#x z=9nJ2pRVst^nM=%8?fEK-`|^3GOO)P)crM^5gN>6uEz&JX=wQQB79cZgDNn6hjyQ= zE;?9bhnCS1KGrg(@7OXH2|!@Se* z8P!5*%*czguIFZqYXNCK;#c4)@~~XNr=w4|o6eI7rk<0!%*iXsO$3_H&XA$OO>bmI?oP>$ZN_HyB-S01J(%0k?6+_? z=1K476FiF*CIrqHC**LCx#TWpDpiuXO_lgR;{Mi3mC$WlDGgmirOk(;OdX1{+d33Q z<#L{8HIM{?*a^s#-606jJ!1#0R%ir&# zMSFmGH0_;ee=vvcNhjJn%;EN{)6iqgZTs4(;Q;0meeY~x3GWFJ`a8yMsD2dUc?69X z@kF8b-oL-R>L6fBXNV}ip&gC`FK0uze;eathX1{V*m^OpxLN!F^1A`b#dbT5o+Thr zqS+LJmIpnj5ao=4+m^7uK1SQM(C4BiZ|*d1$21)%_Zl424YlB!%<9LPYvh|O7%(jw zHfg zBi`SDYntS*$FC@-L4ffa2mqBp`fXFJv6 z#xzH3Ub7}!*5JqAPPSv3rvA9Lf5$w{)%mOzxHNA7E`?@sBDW}~75+RXnc3V)GkOxu z6E_&rq1lx;vZ(^tn%D1~+@3p0CJp)HZMz}V6$M_UJ{?xJDibd=IVLsvY7C`J&~w$U zs7Tw`er+2-Zy9&Oa8h+ffdY#(F~TrS930rhD7_ReRBCf+VziJn5!>u8e`vMFg2Xi& z88;dy2?Cn~)Vqkb4q)xZ5E<2VZ%CnLS~Gc;wQKz+6BcZ85pp!t!&ZpfG_#~@s9hvJ zYbGuZRGSfb-u84I>a-xbCUIuAuJxZxT1@yyO!E>%2gaClWDAdXYW1Y*Nxs!)P7A?i z(seE%UH|DA&&9UC8}`6mf45uv;R@8|-ne<8Pi}(KGk-(9VXv&j*>25f#B_6SY(6w> zG(S`?fe23Ubpv z`r@up7ONo2q8nP#_PuHy5xU4`i!iTmyw%3~y&jBXuY5oV z7=*=awy}4lk`NjXe?1DHit4CAq9zh!7zm<^HWv>o6w z*T^3C(NMM6Mgx>VdA|7coQL~I4V6q+0kN6TaS{!6sytCtlEEh$si7&Ne%hlHl??$! zWoTWu2{(k5U~!)Z0PQ1)+x90^6$qHtJcRaw!uC4DZ`u2Df8CR?nkio;^6!=?znv{n zem9M0Z8_Y#w7M;}u&Oc*OYZG~Fg~m(K5!bFO51~4g=M=|IVzKF$yCIq&Y%f!18C7~$DZOXiEiTHpD!+F z)1SnLT}kohe*h2@nFVjFY?g1Q<hY3nfYnpH>>1f9HUn(k=4Zgw@Aw3#O%PI+%+;l^Y>j3*OJJy)|mXdoq+ zp|O_t3|9^NyN!-OWog#E=I%7-hYVi!UPw0trmiDrzqch01n}hqR3P@k-BB<0U)5F6 z+3(3^e@5xHtY>~ZBs^cpqM>t#u98b-ypSZD0orsph+Pl94WOEY6S|LnbLXlha%VnOQoO=dm#NCU6JSu{aEV1yW z@p7JBTv)3c&@_B2LLzlU_x1X;m}fIP@We{|f6}20rqBKap@8guq6r4y`M>}B|F{o0 z*Vkg}7THae*_&>!9^+h-yr^a(9ha#~S}h62APrc1lj>o-SJ?}{MpAF(>}jK1)wbbQ z#i}!f8@YMKrk)L}Vf>r=bDEuO4Kn*SEYcN~q9QIy?xj*b8Oj>7#(&9{%h~5{zt3;mef!$o8~fk*L0qJB zTfC)SzCQLL9kdj+v9Q=ZLUcgr)zvXmu zHVJR;vFj?qxFTNVHDkp|)B3RvIPkzAqB<4|YaPdr!~TsfU_*ujq*dqI1d(fvf14W9 zGvK_s@}K}gIy_sgfNycl!Zq4JzNy%=_3>Y|X@^onOvGeQ2XPyY8+7cj-Mhni(@lQI zVCVAgV0*B0-SeB(47GSwQ>7Snye8bJ2|aDfNvw5Bb9abQ{pW0jp@W*wIAt---)B37 zxoa6Klhd^Fk3L*#QTBC{WR*T@f3u$WF!agX-1{#8V>e8SIY4BW)neSgDEpTsD$N|L zilSaaW$!-}Rpi6P;y;7b4M=2|_KO)%y_U2*09xA6|9-K;K#V#T2f99vz<*YLO zWemU87{sivn$5q*|C*NfH)FqB1DYzr_iSOx`ZB!ohKTMz%f9K<2l1_^$~{y zuL_(EYMy~S{Uq_ES+2f>wN!`7>kualW%2nPl*Cov8pcxiUIlGnQx6aI->P9TRe)Zo zi{Y(YxL%runo7*{<4nbsv8_z_nWS{DAoL=@n+>5SESIIH4mhWJe?4E5$8V`lb$oYt z!gjdZt$j5j8PZsGiPR8-x=jaJ-@vtUxkATGihsJLv#LNe+HFmbRS}wS=HepK^Wb@K zhmqpNZuD;Tv&F#WR|Q=p!2q`F&CiRo&g;vnp&QbA+P@M~G9%GCe$)FcgI)b{S)O|q z+`6*R$k>7?yFMl?f0vTSSXt*4hTa9OT7jt48XOCKRe`2KY1WYvYmK~KFCp2n9hCu! zeFe3~&O4OcVO}HD8!@n( zB`}7Xt#Wq-V7~#at+kA11nAuji?a{Y0}sm~5tvC4@Phtq z-}ZH_{l)R*re{Ukl+O_l&$EBGyS1@>*I~w4x9|&;vCP}gg>#_uj99GChWrjdTPhkj z!;z5pRaNnmf7L4cyxkHate0y^qf}Ije|-x_LNtF6vcB$)d~2sr3`@~24%8aT7Q5vO z>s`;(_02pX9&Q>8_Kq=h(v(f?DCDS$rFtn+#Dk#)U*)j~<8Og>4{Ci1+x`2+;=|~E zsw^Hx-@=TU93E*{7@m295BcX3t@L1pJ(Be_?*aI?A0pbLwRmlX{z8ieY_L zBFa;RSIx?kePGV#$8(rCa3JsG>0&aErE6-6J9icb`JrF-sGlGD<&H+hL4SX=IM^Rm zOx@!-|7%ko=@iH~L~`Xq8ih~69KWiYNUp2!QF>1eqkaF^=nZF}7-D#Ea|vVxg1!h+ zDfxg8fQTKGR)camE2?gCFX@>V@|{P?K-(HEAkDQ8@a*KpO_sl;&85}ld)x`$Qyx3;kub6rgqee0tW9jo7Lbq7D;_2TMz+y$p%+ zSrt{RUBd8|bT5OIMD9KcIPacjvl-r0sbq@UOAJF7u*K{nvP<5J2%U!9`_-qu@odn= zKQh`D9Xdd3%VvLMXUGEJWS5DYpmek<;ze?X~UJtmh+f zUwAs(skozx9FYe%)sJ5}YBMc1Bc+eKZCv^&_+9;##EXw>vj)f=Y*>ZvNwg5A<;j^Yi&$Na^-s9u(5 znqu{?1#9Wo)$A?W1X>kc2;^Fuj6F2U$ip^e<%^}Q+kKd(dz7XP*x61Vckxd!jK8G=``9Kzi{mM>0$~S@?S$*}m|nE^5VW;+@jPLCHT@riTwRz+w-})5sy(7UHT7&% zL(y6-17U1L|TDyk%Ru zJR4v>wy<5q^HmOK9&+O;PVQYyi+*y~7QdSe&Z~=Ak}lGq`gn1Zf6+rX+qf0H>4m@a W-!G=0aT!7#kN+QsZe-cO`v(9AoUI`M delta 53337 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 KfV3E1`3C?-HAJ}p diff --git a/homeassistant/components/frontend/www_static/home-assistant-polymer b/homeassistant/components/frontend/www_static/home-assistant-polymer index 95cbc85b7f6a5..71278d7d6b0e1 160000 --- a/homeassistant/components/frontend/www_static/home-assistant-polymer +++ b/homeassistant/components/frontend/www_static/home-assistant-polymer @@ -1 +1 @@ -Subproject commit 95cbc85b7f6a5cd969598614122bf2b247817d68 +Subproject commit 71278d7d6b0e1a680b6336615fb6f4b5775f6d6c diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-info.html b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-info.html index e255ca2f83de6..5aca7e0c32a1e 100644 --- a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-info.html +++ b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-info.html @@ -1,2 +1,2 @@ \ No newline at end of file + clear: both;white-space:pre-wrap}


Home Assistant
[[hassVersion]]

Path to configuration.yaml: [[hassConfigDir]]

Developed by a bunch of awesome people.

Published under the MIT license
Source: server — frontend-ui — frontend-core

Built using Python 3, Polymer [[polymerVersion]], NuclearJS [[nuclearVersion]]
Icons by Google and MaterialDesignIcons.com.

The following errors have been logged this session:

[[errorLog]]
\ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-info.html.gz b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-info.html.gz index aa8a5cc85170da70f52c2bda3d694f55d5f9dc59..36dd8becdf7423264a9cd481c874ad54cba22bc8 100644 GIT binary patch literal 1345 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 Sym^!Ujr=##Td(~p3jhFgFqU}$ diff --git a/homeassistant/components/frontend/www_static/service_worker.js b/homeassistant/components/frontend/www_static/service_worker.js index 5f227d1154616..a86c2dbb93243 100644 --- a/homeassistant/components/frontend/www_static/service_worker.js +++ b/homeassistant/components/frontend/www_static/service_worker.js @@ -1 +1 @@ -"use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}function notificationEventCallback(e,t){firePushCallback({action:t.action,data:t.notification.data,tag:t.notification.tag,type:e},t.notification.data.jwt)}function firePushCallback(e,t){delete e.data.jwt,0===Object.keys(e.data).length&&e.data.constructor===Object&&delete e.data,fetch("/api/notify.html5/callback",{method:"POST",headers:new Headers({"Content-Type":"application/json",Authorization:"Bearer "+t}),body:JSON.stringify(e)})}var precacheConfig=[["/","08922b69751f2a9b221948f0ce1652f7"],["/frontend/panels/dev-event-c4a5f70eece9f92616a65e8d26be803e.html","8626b97f56c0056659c8214414b98e9b"],["/frontend/panels/dev-info-34e2df1af32e60fffcafe7e008a92169.html","7e939dc762dc0c0ec769db4ea76a4b09"],["/frontend/panels/dev-service-07e83c6b7f79d78a59258f6dba477b54.html","98ae94372a50c279c8f3d82f473241bb"],["/frontend/panels/dev-state-fd8eb946856b1346a87a51d0c86854ff.html","6ad0c48237a02429dc444ca21cb7f713"],["/frontend/panels/dev-template-7cff8a2ef3f44fdaf357a0d41696bf6d.html","aa9d7a78f7fd8ca85528f9b059106cd4"],["/frontend/panels/map-af7d04aff7dd5479c5a0016bc8d4dd7d.html","6031df1b4d23d5b321208449b2d293f8"],["/static/core-78862c0984279b6876f594ffde45177c.js","70c1c2d9ab233c6ba7f18f6bfc7028b0"],["/static/frontend-6101173e9a8930f9c74767a3bc493bff.html","988f2761a8e1ce66be76ac470d603340"],["/static/mdi-6bd013a8252e19b3c1f1de52994cfbe4.html","3af09b4ea66071ef4e9fb0385ee0d399"],["static/fonts/roboto/Roboto-Bold.ttf","d329cc8b34667f114a95422aaad1b063"],["static/fonts/roboto/Roboto-Light.ttf","7b5fb88f12bec8143f00e21bc3222124"],["static/fonts/roboto/Roboto-Medium.ttf","fe13e4170719c2fc586501e777bde143"],["static/fonts/roboto/Roboto-Regular.ttf","ac3f799d5bbaf5196fab15ab8de8431c"],["static/icons/favicon-192x192.png","419903b8422586a7e28021bbe9011175"],["static/icons/favicon.ico","04235bda7843ec2fceb1cbe2bc696cf4"],["static/images/card_media_player_bg.png","a34281d1c1835d338a642e90930e61aa"],["static/webcomponents-lite.min.js","b0f32ad3c7749c40d486603f31c9d8b1"]],cacheName="sw-precache-v2--"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var a=new URL(e);return"/"===a.pathname.slice(-1)&&(a.pathname+=t),a.toString()},createCacheKey=function(e,t,a,n){var c=new URL(e);return n&&c.toString().match(n)||(c.search+=(c.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(a)),c.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var a=new URL(t).pathname;return e.some(function(e){return a.match(e)})},stripIgnoredUrlParameters=function(e,t){var a=new URL(e);return a.search=a.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),a.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],a=e[1],n=new URL(t,self.location),c=createCacheKey(n,hashParamName,a,!1);return[n.toString(),c]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(a){if(!t.has(a))return e.add(new Request(a,{credentials:"same-origin"}))}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(a){return Promise.all(a.map(function(a){if(!t.has(a.url))return e.delete(a)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,a=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);t=urlsToCacheKeys.has(a);var n="index.html";!t&&n&&(a=addDirectoryIndex(a,n),t=urlsToCacheKeys.has(a));var c="/";!t&&c&&"navigate"===e.request.mode&&isPathWhitelisted(["^((?!(static|api|local|service_worker.js|manifest.json)).)*$"],e.request.url)&&(a=new URL(c,self.location).toString(),t=urlsToCacheKeys.has(a)),t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(a))}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}),self.addEventListener("push",function(e){var t;e.data&&(t=e.data.json(),e.waitUntil(self.registration.showNotification(t.title,t).then(function(e){firePushCallback({type:"received",tag:t.tag,data:t.data},t.data.jwt)})))}),self.addEventListener("notificationclick",function(e){var t;notificationEventCallback("clicked",e),e.notification.close(),e.notification.data&&e.notification.data.url&&(t=e.notification.data.url,t&&e.waitUntil(clients.matchAll({type:"window"}).then(function(e){var a,n;for(a=0;ai-xsP+ZomC5i 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 Date: Wed, 5 Oct 2016 08:48:25 +0200 Subject: [PATCH 088/112] Add possibility to set temperature to a given operation_mode (#3646) * Add possibility to set temperature to a given operation_mode * Correctly break * Review changes --- homeassistant/components/climate/__init__.py | 6 +++++- homeassistant/components/climate/services.yaml | 12 ++++++++++++ homeassistant/components/climate/zwave.py | 13 ++++++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/climate/__init__.py b/homeassistant/components/climate/__init__.py index 93330603828f4..e8047093cc8f6 100644 --- a/homeassistant/components/climate/__init__.py +++ b/homeassistant/components/climate/__init__.py @@ -79,6 +79,7 @@ vol.Inclusive(ATTR_TARGET_TEMP_HIGH, 'temperature'): vol.Coerce(float), vol.Inclusive(ATTR_TARGET_TEMP_LOW, 'temperature'): vol.Coerce(float), vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, + vol.Optional(ATTR_OPERATION_MODE): cv.string, }) SET_FAN_MODE_SCHEMA = vol.Schema({ vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, @@ -122,8 +123,10 @@ def set_aux_heat(hass, aux_heat, entity_id=None): hass.services.call(DOMAIN, SERVICE_SET_AUX_HEAT, data) +# pylint: disable=too-many-arguments def set_temperature(hass, temperature=None, entity_id=None, - target_temp_high=None, target_temp_low=None): + target_temp_high=None, target_temp_low=None, + operation_mode=None): """Set new target temperature.""" kwargs = { key: value for key, value in [ @@ -131,6 +134,7 @@ def set_temperature(hass, temperature=None, entity_id=None, (ATTR_TARGET_TEMP_HIGH, target_temp_high), (ATTR_TARGET_TEMP_LOW, target_temp_low), (ATTR_ENTITY_ID, entity_id), + (ATTR_OPERATION_MODE, operation_mode) ] if value is not None } _LOGGER.debug("set_temperature start data=%s", kwargs) diff --git a/homeassistant/components/climate/services.yaml b/homeassistant/components/climate/services.yaml index 3a037d2a48bc6..d28e8c4dd88a8 100644 --- a/homeassistant/components/climate/services.yaml +++ b/homeassistant/components/climate/services.yaml @@ -34,6 +34,18 @@ set_temperature: description: New target temperature for hvac example: 25 + target_temp_high: + description: New target high tempereature for hvac + example: 26 + + target_temp_low: + description: New target low temperature for hvac + example: 20 + + operation_mode: + description: Operation mode to set temperature to. This defaults to current_operation mode if not set, or set incorrectly. + example: 'Heat' + set_humidity: description: Set target humidity of climate device diff --git a/homeassistant/components/climate/zwave.py b/homeassistant/components/climate/zwave.py index d744f9a139122..767bed6ff9429 100755 --- a/homeassistant/components/climate/zwave.py +++ b/homeassistant/components/climate/zwave.py @@ -8,7 +8,8 @@ # pylint: disable=import-error import logging from homeassistant.components.climate import DOMAIN -from homeassistant.components.climate import ClimateDevice +from homeassistant.components.climate import ( + ClimateDevice, ATTR_OPERATION_MODE) from homeassistant.components.zwave import ZWaveDeviceEntity from homeassistant.components import zwave from homeassistant.const import ( @@ -243,10 +244,20 @@ def set_temperature(self, **kwargs): temperature = kwargs.get(ATTR_TEMPERATURE) else: return + operation_mode = kwargs.get(ATTR_OPERATION_MODE) + _LOGGER.debug("set_temperature operation_mode=%s", operation_mode) for value in (self._node.get_values( class_id=zwave.const.COMMAND_CLASS_THERMOSTAT_SETPOINT) .values()): + if operation_mode is not None: + setpoint_mode = SET_TEMP_TO_INDEX.get(operation_mode) + if value.index != setpoint_mode: + continue + _LOGGER.debug("setpoint_mode=%s", setpoint_mode) + value.data = temperature + break + if self.current_operation is not None: if self._hrt4_zw and self.current_operation == 'Off': # HRT4-ZW can change setpoint when off. From 46f3337b07266f701fff9e8cb5a5ffbb644d921c Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 4 Oct 2016 08:41:08 +0200 Subject: [PATCH 089/112] Customize initial state of automation --- .../components/automation/__init__.py | 7 +++- tests/components/automation/test_init.py | 40 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index 579d4b400035c..0de3cf93df179 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -38,6 +38,7 @@ CONF_ACTION = 'action' CONF_TRIGGER = 'trigger' CONF_CONDITION_TYPE = 'condition_type' +CONF_INITIAL_STATE = 'initial_state' CONDITION_USE_TRIGGER_VALUES = 'use_trigger_values' CONDITION_TYPE_AND = 'and' @@ -45,6 +46,7 @@ DEFAULT_CONDITION_TYPE = CONDITION_TYPE_AND DEFAULT_HIDE_ENTITY = False +DEFAULT_INITIAL_STATE = True ATTR_LAST_TRIGGERED = 'last_triggered' ATTR_VARIABLES = 'variables' @@ -79,6 +81,8 @@ def _platform_validator(config): PLATFORM_SCHEMA = vol.Schema({ CONF_ALIAS: cv.string, + vol.Optional(CONF_INITIAL_STATE, + default=DEFAULT_INITIAL_STATE): cv.boolean, vol.Optional(CONF_HIDE_ENTITY, default=DEFAULT_HIDE_ENTITY): cv.boolean, vol.Required(CONF_TRIGGER): _TRIGGER_SCHEMA, vol.Optional(CONF_CONDITION): _CONDITION_SCHEMA, @@ -333,7 +337,8 @@ def cond_func(variables): config_block.get(CONF_TRIGGER, []), name) entity = AutomationEntity(name, async_attach_triggers, cond_func, action, hidden) - tasks.append(hass.loop.create_task(entity.async_enable())) + if config_block[CONF_INITIAL_STATE]: + tasks.append(hass.loop.create_task(entity.async_enable())) entities.append(entity) yield from asyncio.gather(*tasks, loop=hass.loop) diff --git a/tests/components/automation/test_init.py b/tests/components/automation/test_init.py index 8cc7825bb1f69..f33c6964f2e65 100644 --- a/tests/components/automation/test_init.py +++ b/tests/components/automation/test_init.py @@ -96,6 +96,46 @@ def test_service_specify_entity_id(self): self.assertEqual(['hello.world'], self.calls[0].data.get(ATTR_ENTITY_ID)) + def test_service_initial_value_off(self): + """Test initial value off.""" + entity_id = 'automation.hello' + + assert setup_component(self.hass, automation.DOMAIN, { + automation.DOMAIN: { + 'alias': 'hello', + 'initial_state': 'off', + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'action': { + 'service': 'test.automation', + 'entity_id': ['hello.world', 'hello.world2'] + } + } + }) + assert not automation.is_on(self.hass, entity_id) + + def test_service_initial_value_on(self): + """Test initial value on.""" + entity_id = 'automation.hello' + + assert setup_component(self.hass, automation.DOMAIN, { + automation.DOMAIN: { + 'alias': 'hello', + 'initial_state': 'on', + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'action': { + 'service': 'test.automation', + 'entity_id': ['hello.world', 'hello.world2'] + } + } + }) + assert automation.is_on(self.hass, entity_id) + def test_service_specify_entity_id_list(self): """Test service data.""" assert setup_component(self.hass, automation.DOMAIN, { From 350d23f7eb1d10c8f42033bc869fe7bcbf1a01a8 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 2 Oct 2016 15:36:57 +0200 Subject: [PATCH 090/112] customize if pushetta should send test message on start up --- homeassistant/components/notify/pushetta.py | 42 ++++++++++++--------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/homeassistant/components/notify/pushetta.py b/homeassistant/components/notify/pushetta.py index ab304dc651491..15a750e5ad800 100644 --- a/homeassistant/components/notify/pushetta.py +++ b/homeassistant/components/notify/pushetta.py @@ -18,45 +18,51 @@ CONF_CHANNEL_NAME = 'channel_name' +CONF_SEND_TEST_MSG = 'send_test_msg' PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_API_KEY): cv.string, vol.Required(CONF_CHANNEL_NAME): cv.string, + vol.Optional(CONF_SEND_TEST_MSG, default=False): cv.boolean, }) def get_service(hass, config): """Get the Pushetta notification service.""" - from pushetta import Pushetta, exceptions + pushetta_service = PushettaNotificationService(config[CONF_API_KEY], + config[CONF_CHANNEL_NAME], + config[CONF_SEND_TEST_MSG]) - try: - pushetta = Pushetta(config[CONF_API_KEY]) - pushetta.pushMessage(config[CONF_CHANNEL_NAME], - "Home Assistant started") - except exceptions.TokenValidationError: - _LOGGER.error("Please check your access token") - return None - except exceptions.ChannelNotFoundError: - _LOGGER.error("Channel '%s' not found", config[CONF_CHANNEL_NAME]) - return None - - return PushettaNotificationService(config[CONF_API_KEY], - config[CONF_CHANNEL_NAME]) + if pushetta_service.is_valid: + return pushetta_service # pylint: disable=too-few-public-methods class PushettaNotificationService(BaseNotificationService): """Implement the notification service for Pushetta.""" - def __init__(self, api_key, channel_name): + def __init__(self, api_key, channel_name, send_test_msg): """Initialize the service.""" from pushetta import Pushetta self._api_key = api_key self._channel_name = channel_name - self.pushetta = Pushetta(self._api_key) + self.is_valid = True + self.pushetta = Pushetta(api_key) + + if send_test_msg: + self.send_message("Home Assistant started") def send_message(self, message="", **kwargs): """Send a message to a user.""" + from pushetta import exceptions title = kwargs.get(ATTR_TITLE, ATTR_TITLE_DEFAULT) - self.pushetta.pushMessage(self._channel_name, - "{} {}".format(title, message)) + + try: + self.pushetta.pushMessage(self._channel_name, + "{} {}".format(title, message)) + except exceptions.TokenValidationError: + _LOGGER.error("Please check your access token") + self.is_valid = False + except exceptions.ChannelNotFoundError: + _LOGGER.error("Channel '%s' not found", self._channel_name) + self.is_valid = False From 201294e4811ff1b8d49a29419cbe6fb78b862848 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 5 Oct 2016 10:49:33 +0200 Subject: [PATCH 091/112] Update flux led library --- homeassistant/components/light/flux_led.py | 4 ++-- requirements_all.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/light/flux_led.py b/homeassistant/components/light/flux_led.py index 5b25b86b9b909..035307f567834 100644 --- a/homeassistant/components/light/flux_led.py +++ b/homeassistant/components/light/flux_led.py @@ -17,8 +17,8 @@ PLATFORM_SCHEMA) import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['https://github.com/Danielhiversen/flux_led/archive/0.6.zip' - '#flux_led==0.6'] +REQUIREMENTS = ['https://github.com/Danielhiversen/flux_led/archive/0.7.zip' + '#flux_led==0.7'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 2cf6e33051e0b..7bcdf36634cfe 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -139,7 +139,7 @@ hikvision==0.4 # http://github.com/adafruit/Adafruit_Python_DHT/archive/310c59b0293354d07d94375f1365f7b9b9110c7d.zip#Adafruit_DHT==1.3.0 # homeassistant.components.light.flux_led -https://github.com/Danielhiversen/flux_led/archive/0.6.zip#flux_led==0.6 +https://github.com/Danielhiversen/flux_led/archive/0.7.zip#flux_led==0.7 # homeassistant.components.switch.dlink https://github.com/LinuxChristian/pyW215/archive/v0.3.5.zip#pyW215==0.3.5 From 0c68f381b04d758853ff97f42b077a2c63fc3abd Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Wed, 5 Oct 2016 14:40:08 +0200 Subject: [PATCH 092/112] Migrate to voluptuous (#3679) --- homeassistant/components/zwave/__init__.py | 74 ++++++++++++++-------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py index 5aa9c5dc13220..e32aff988d826 100644 --- a/homeassistant/components/zwave/__init__.py +++ b/homeassistant/components/zwave/__init__.py @@ -8,29 +8,36 @@ import os.path import time from pprint import pprint + import voluptuous as vol from homeassistant.helpers import discovery from homeassistant.const import ( - ATTR_BATTERY_LEVEL, ATTR_LOCATION, ATTR_ENTITY_ID, - CONF_CUSTOMIZE, EVENT_HOMEASSISTANT_START, - EVENT_HOMEASSISTANT_STOP) + ATTR_BATTERY_LEVEL, ATTR_LOCATION, ATTR_ENTITY_ID, CONF_CUSTOMIZE, + EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP) from homeassistant.helpers.event import track_time_change from homeassistant.util import convert, slugify import homeassistant.config as conf_util import homeassistant.helpers.config_validation as cv from . import const -DOMAIN = "zwave" REQUIREMENTS = ['pydispatcher==2.0.5'] -CONF_USB_STICK_PATH = "usb_path" -DEFAULT_CONF_USB_STICK_PATH = "/zwaveusbstick" -CONF_DEBUG = "debug" -CONF_POLLING_INTERVAL = "polling_interval" -CONF_POLLING_INTENSITY = "polling_intensity" -CONF_AUTOHEAL = "autoheal" +_LOGGER = logging.getLogger(__name__) + +CONF_AUTOHEAL = 'autoheal' +CONF_DEBUG = 'debug' +CONF_POLLING_INTENSITY = 'polling_intensity' +CONF_POLLING_INTERVAL = 'polling_interval' +CONF_USB_STICK_PATH = 'usb_path' +CONF_CONFIG_PATH = 'config_path' + DEFAULT_CONF_AUTOHEAL = True +DEFAULT_CONF_USB_STICK_PATH = '/zwaveusbstick' +DEFAULT_POLLING_INTERVAL = 60000 +DEFAULT_DEBUG = True +DOMAIN = 'zwave' + NETWORK = None # List of tuple (DOMAIN, discovered service, supported command classes, @@ -124,7 +131,24 @@ vol.Optional(const.ATTR_CONFIG_SIZE): vol.Coerce(int) }) -_LOGGER = logging.getLogger(__name__) +CUSTOMIZE_SCHEMA = vol.Schema({ + vol.Optional(CONF_POLLING_INTENSITY): + vol.All(cv.positive_int, vol.In([0, 1, 2])), +}) + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({ + vol.Optional(CONF_AUTOHEAL, default=DEFAULT_CONF_AUTOHEAL): cv.boolean, + vol.Optional(CONF_CONFIG_PATH): cv.string, + vol.Optional(CONF_CUSTOMIZE, default={}): + vol.Schema({cv.string: CUSTOMIZE_SCHEMA}), + vol.Optional(CONF_DEBUG, default=False): cv.boolean, + vol.Optional(CONF_POLLING_INTERVAL, default=DEFAULT_POLLING_INTERVAL): + cv.positive_int, + vol.Optional(CONF_USB_STICK_PATH, default=DEFAULT_CONF_USB_STICK_PATH): + cv.string, + }), +}, extra=vol.ALLOW_EXTRA) def _obj_to_dict(obj): @@ -136,20 +160,18 @@ def _obj_to_dict(obj): def _node_name(node): """Return the name of the node.""" - return node.name or "{} {}".format( + return node.name or '{} {}'.format( node.manufacturer_name, node.product_name) def _value_name(value): """Return the name of the value.""" - return "{} {}".format(_node_name(value.node), value.label) + return '{} {}'.format(_node_name(value.node), value.label) def _node_object_id(node): """Return the object_id of the node.""" - node_object_id = "{}_{}".format(slugify(_node_name(node)), - node.node_id) - + node_object_id = '{}_{}'.format(slugify(_node_name(node)), node.node_id) return node_object_id @@ -159,13 +181,11 @@ def _object_id(value): The object_id contains node_id and value instance id to not collide with other entity_ids. """ - object_id = "{}_{}".format(slugify(_value_name(value)), - value.node.node_id) + object_id = "{}_{}".format(slugify(_value_name(value)), value.node.node_id) # Add the instance id if there is more than one instance for the value if value.instance > 1: - return "{}_{}".format(object_id, value.instance) - + return '{}_{}'.format(object_id, value.instance) return object_id @@ -204,7 +224,7 @@ def setup(hass, config): global NETWORK descriptions = conf_util.load_yaml_config_file( - os.path.join(os.path.dirname(__file__), "services.yaml")) + os.path.join(os.path.dirname(__file__), 'services.yaml')) try: import libopenzwave @@ -221,16 +241,16 @@ def setup(hass, config): libopenzwave.__file__), 'config') # Load configuration - use_debug = str(config[DOMAIN].get(CONF_DEBUG)) == '1' - customize = config[DOMAIN].get(CONF_CUSTOMIZE, {}) - autoheal = config[DOMAIN].get(CONF_AUTOHEAL, DEFAULT_CONF_AUTOHEAL) + use_debug = config[DOMAIN].get(CONF_DEBUG) + customize = config[DOMAIN].get(CONF_CUSTOMIZE) + autoheal = config[DOMAIN].get(CONF_AUTOHEAL) # Setup options options = ZWaveOption( - config[DOMAIN].get(CONF_USB_STICK_PATH, DEFAULT_CONF_USB_STICK_PATH), + config[DOMAIN].get(CONF_USB_STICK_PATH), user_path=hass.config.config_dir, - config_path=config[DOMAIN].get('config_path', - default_zwave_config_path),) + config_path=config[DOMAIN].get( + CONF_CONFIG_PATH, default_zwave_config_path)) options.set_console_output(use_debug) options.lock() From 5d339fb1410cfb323e42e008e16a9e8a2c7987d5 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Wed, 5 Oct 2016 16:28:38 +0200 Subject: [PATCH 093/112] Fix sentence (#3709) --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 72586cc4f21e3..998905c929bc7 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -15,7 +15,7 @@ If user exposed functionality or configuration variables are added/changed: - [ ] Documentation added/updated in [home-assistant.io](https://github.com/home-assistant/home-assistant.io) -If code communicates with devices, web services, or a: +If the code communicates with devices, web services, or third-party tools: - [ ] Local tests with `tox` run successfully. **Your PR cannot be merged unless tests pass** - [ ] New dependencies have been added to the `REQUIREMENTS` variable ([example][ex-requir]). - [ ] New dependencies are only imported inside functions that use them ([example][ex-import]). From 1bc6366051a626762f188cf14305040d61d04390 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 5 Oct 2016 10:58:06 -0400 Subject: [PATCH 094/112] Increase allowable polling intensity values (#3711) --- homeassistant/components/zwave/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py index e32aff988d826..32d4f42c1a1bf 100644 --- a/homeassistant/components/zwave/__init__.py +++ b/homeassistant/components/zwave/__init__.py @@ -133,7 +133,7 @@ CUSTOMIZE_SCHEMA = vol.Schema({ vol.Optional(CONF_POLLING_INTENSITY): - vol.All(cv.positive_int, vol.In([0, 1, 2])), + vol.All(cv.positive_int, vol.In([0, 1, 2, 3, 4, 5])), }) CONFIG_SCHEMA = vol.Schema({ From cb3a78b330d4bb54eb0cd3ae1ab2bae34eaac6cd Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Wed, 5 Oct 2016 18:02:45 +0200 Subject: [PATCH 095/112] Adjust vol to accept filenames (fixes #3701) (#3707) --- homeassistant/components/sensor/gtfs.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/sensor/gtfs.py b/homeassistant/components/sensor/gtfs.py index a9c6f36bf5483..2a5f4aa0de6ce 100644 --- a/homeassistant/components/sensor/gtfs.py +++ b/homeassistant/components/sensor/gtfs.py @@ -36,14 +36,14 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_ORIGIN): cv.string, vol.Required(CONF_DESTINATION): cv.string, - vol.Required(CONF_DATA): cv.isfile, + vol.Required(CONF_DATA): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, }) # pylint: disable=too-many-locals def get_next_departure(sched, start_station_id, end_station_id): - """Get the next departure for the given sched.""" + """Get the next departure for the given schedule.""" origin_station = sched.stops_by_id(start_station_id)[0] destination_station = sched.stops_by_id(end_station_id)[0] @@ -147,7 +147,7 @@ def get_next_departure(sched, start_station_id, end_station_id): def setup_platform(hass, config, add_devices, discovery_info=None): - """Get the GTFS sensor.""" + """Set up the GTFS sensor.""" gtfs_dir = hass.config.path(DEFAULT_PATH) data = config.get(CONF_DATA) origin = config.get(CONF_ORIGIN) From a94571fd10cedfbc9acd971a98caef6b6a379df4 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Wed, 5 Oct 2016 21:42:58 +0200 Subject: [PATCH 096/112] Change name of Forecast.io platform to Dark Sky (#3698) * Rename Forecast.io platform to Dark Sky * Upgrade to python-forecastio to 1.3.5 * Update to reflect name change (Forecast.io -> Dark Sky) * Rename forecast to darksky --- .coveragerc | 2 +- .../sensor/{forecast.py => darksky.py} | 36 +++++++++---------- requirements_all.txt | 4 +-- .../{test_forecast.py => test_darksky.py} | 28 +++++++++------ .../fixtures/{forecast.json => darksky.json} | 0 5 files changed, 38 insertions(+), 32 deletions(-) rename homeassistant/components/sensor/{forecast.py => darksky.py} (92%) rename tests/components/sensor/{test_forecast.py => test_darksky.py} (66%) rename tests/fixtures/{forecast.json => darksky.json} (100%) diff --git a/.coveragerc b/.coveragerc index 467950e16e828..80bc6905c21e7 100644 --- a/.coveragerc +++ b/.coveragerc @@ -220,6 +220,7 @@ omit = homeassistant/components/sensor/bom.py homeassistant/components/sensor/coinmarketcap.py homeassistant/components/sensor/cpuspeed.py + homeassistant/components/sensor/darksky.py homeassistant/components/sensor/deutsche_bahn.py homeassistant/components/sensor/dht.py homeassistant/components/sensor/dte_energy_bridge.py @@ -229,7 +230,6 @@ omit = homeassistant/components/sensor/fastdotcom.py homeassistant/components/sensor/fitbit.py homeassistant/components/sensor/fixer.py - homeassistant/components/sensor/forecast.py homeassistant/components/sensor/fritzbox_callmonitor.py homeassistant/components/sensor/glances.py homeassistant/components/sensor/google_travel_time.py diff --git a/homeassistant/components/sensor/forecast.py b/homeassistant/components/sensor/darksky.py similarity index 92% rename from homeassistant/components/sensor/forecast.py rename to homeassistant/components/sensor/darksky.py index e0beb65c04567..241ab5f465589 100644 --- a/homeassistant/components/sensor/forecast.py +++ b/homeassistant/components/sensor/darksky.py @@ -1,8 +1,8 @@ """ -Support for Forecast.io weather service. +Support for Dark Sky weather service. For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/sensor.forecast/ +https://home-assistant.io/components/sensor.darksky/ """ import logging from datetime import timedelta @@ -18,14 +18,14 @@ from homeassistant.util import Throttle import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['python-forecastio==1.3.4'] +REQUIREMENTS = ['python-forecastio==1.3.5'] _LOGGER = logging.getLogger(__name__) CONF_UNITS = 'units' CONF_UPDATE_INTERVAL = 'update_interval' -DEFAULT_NAME = 'Forecast.io' +DEFAULT_NAME = 'Dark Sky' # Sensor types are defined like so: # Name, si unit, us unit, ca unit, uk unit, uk2 unit @@ -91,7 +91,7 @@ # pylint: disable=too-many-arguments def setup_platform(hass, config, add_devices, discovery_info=None): - """Setup the Forecast.io sensor.""" + """Setup the Dark Sky sensor.""" # Validate the configuration if None in (hass.config.latitude, hass.config.longitude): _LOGGER.error("Latitude or longitude not set in Home Assistant config") @@ -107,7 +107,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): # Create a data fetcher to support all of the configured sensors. Then make # the first call to init the data and confirm we can connect. try: - forecast_data = ForeCastData( + forecast_data = DarkSkyData( api_key=config.get(CONF_API_KEY, None), latitude=hass.config.latitude, longitude=hass.config.longitude, @@ -122,14 +122,14 @@ def setup_platform(hass, config, add_devices, discovery_info=None): sensors = [] for variable in config[CONF_MONITORED_CONDITIONS]: - sensors.append(ForeCastSensor(forecast_data, variable, name)) + sensors.append(DarkSkySensor(forecast_data, variable, name)) add_devices(sensors) # pylint: disable=too-few-public-methods -class ForeCastSensor(Entity): - """Implementation of a Forecast.io sensor.""" +class DarkSkySensor(Entity): + """Implementation of a Dark Sky sensor.""" def __init__(self, forecast_data, sensor_type, name): """Initialize the sensor.""" @@ -180,10 +180,10 @@ def icon(self): # pylint: disable=too-many-branches,too-many-statements def update(self): - """Get the latest data from Forecast.io and updates the states.""" + """Get the latest data from Dark Sky and updates the states.""" # Call the API for new forecast data. Each sensor will re-trigger this - # same exact call, but thats fine. We cache results for a short period - # of time to prevent hitting API limits. Note that forecast.io will + # same exact call, but that's fine. We cache results for a short period + # of time to prevent hitting API limits. Note that Dark Sky will # charge users for too many calls in 1 day, so take care when updating. self.forecast_data.update() self.update_unit_of_measurement() @@ -197,7 +197,8 @@ def update(self): hourly = self.forecast_data.data_hourly self._state = getattr(hourly, 'summary', '') elif self.type in ['daily_summary', - 'temperature_min', 'temperature_max', + 'temperature_min', + 'temperature_max', 'apparent_temperature_min', 'apparent_temperature_max', 'precip_intensity_max']: @@ -247,11 +248,10 @@ def convert_to_camel(data): return components[0] + "".join(x.title() for x in components[1:]) -class ForeCastData(object): - """Gets the latest data from Forecast.io.""" +class DarkSkyData(object): + """Get the latest data from Darksky.""" # pylint: disable=too-many-instance-attributes - def __init__(self, api_key, latitude, longitude, units, interval): """Initialize the data object.""" self._api_key = api_key @@ -276,14 +276,14 @@ def __init__(self, api_key, latitude, longitude, units, interval): self.update() def _update(self): - """Get the latest data from Forecast.io.""" + """Get the latest data from Dark Sky.""" import forecastio try: self.data = forecastio.load_forecast( self._api_key, self.latitude, self.longitude, units=self.units) except (ConnectError, HTTPError, Timeout, ValueError) as error: - raise ValueError("Unable to init Forecast.io. - %s", error) + raise ValueError("Unable to init Dark Sky. %s", error) self.unit_system = self.data.json['flags']['units'] def _update_currently(self): diff --git a/requirements_all.txt b/requirements_all.txt index 7bcdf36634cfe..0a9468acacb8e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -373,8 +373,8 @@ pysnmp==4.3.2 # homeassistant.components.digital_ocean python-digitalocean==1.9.0 -# homeassistant.components.sensor.forecast -python-forecastio==1.3.4 +# homeassistant.components.sensor.darksky +python-forecastio==1.3.5 # homeassistant.components.sensor.hp_ilo python-hpilo==3.8 diff --git a/tests/components/sensor/test_forecast.py b/tests/components/sensor/test_darksky.py similarity index 66% rename from tests/components/sensor/test_forecast.py rename to tests/components/sensor/test_darksky.py index f11a0ebccbec8..f44f7385e5bc9 100644 --- a/tests/components/sensor/test_forecast.py +++ b/tests/components/sensor/test_darksky.py @@ -1,4 +1,4 @@ -"""The tests for the forecast.io platform.""" +"""The tests for the Dark Sky platform.""" import re import unittest from unittest.mock import MagicMock, patch @@ -8,13 +8,14 @@ import requests_mock from datetime import timedelta -from homeassistant.components.sensor import forecast +from homeassistant.components.sensor import darksky +from homeassistant.bootstrap import setup_component from tests.common import load_fixture, get_test_home_assistant -class TestForecastSetup(unittest.TestCase): - """Test the forecast.io platform.""" +class TestDarkSkySetup(unittest.TestCase): + """Test the Dark Sky platform.""" def setUp(self): """Initialize values for this testcase class.""" @@ -30,33 +31,38 @@ def setUp(self): self.hass.config.latitude = self.lat self.hass.config.longitude = self.lon + def test_setup_with_config(self): + """Test the platform setup with configuration.""" + self.assertTrue( + setup_component(self.hass, 'sensor', {'darksky': self.config})) + def test_setup_no_latitude(self): """Test that the component is not loaded without required config.""" self.hass.config.latitude = None - self.assertFalse(forecast.setup_platform(self.hass, {}, MagicMock())) + self.assertFalse(darksky.setup_platform(self.hass, {}, MagicMock())) @patch('forecastio.api.get_forecast') def test_setup_bad_api_key(self, mock_get_forecast): """Test for handling a bad API key.""" - # The forecast API wrapper that we use raises an HTTP error + # The Dark Sky API wrapper that we use raises an HTTP error # when you try to use a bad (or no) API key. - url = 'https://api.forecast.io/forecast/{}/{},{}?units=auto'.format( + url = 'https://api.darksky.net/forecast/{}/{},{}?units=auto'.format( self.key, str(self.lat), str(self.lon) ) msg = '400 Client Error: Bad Request for url: {}'.format(url) mock_get_forecast.side_effect = HTTPError(msg,) - response = forecast.setup_platform(self.hass, self.config, MagicMock()) + response = darksky.setup_platform(self.hass, self.config, MagicMock()) self.assertFalse(response) @requests_mock.Mocker() @patch('forecastio.api.get_forecast', wraps=forecastio.api.get_forecast) def test_setup(self, m, mock_get_forecast): """Test for successfully setting up the forecast.io platform.""" - uri = ('https://api.forecast.io\/forecast\/(\w+)\/' + uri = ('https://api.darksky.net\/forecast\/(\w+)\/' '(-?\d+\.?\d*),(-?\d+\.?\d*)') m.get(re.compile(uri), - text=load_fixture('forecast.json')) - forecast.setup_platform(self.hass, self.config, MagicMock()) + text=load_fixture('darksky.json')) + darksky.setup_platform(self.hass, self.config, MagicMock()) self.assertTrue(mock_get_forecast.called) self.assertEqual(mock_get_forecast.call_count, 1) diff --git a/tests/fixtures/forecast.json b/tests/fixtures/darksky.json similarity index 100% rename from tests/fixtures/forecast.json rename to tests/fixtures/darksky.json From 12f1be9b1c4b5ce4b86f8fee8a222bec59f50074 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Thu, 6 Oct 2016 02:32:29 +0200 Subject: [PATCH 097/112] Fix PEP257 issues and ordering (#3720) --- .../components/device_tracker/owntracks.py | 28 ++++++++++--------- .../device_tracker/test_owntracks.py | 27 ++++++++++-------- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/homeassistant/components/device_tracker/owntracks.py b/homeassistant/components/device_tracker/owntracks.py index 619d3f0ee5de1..d903c25a5c8f5 100644 --- a/homeassistant/components/device_tracker/owntracks.py +++ b/homeassistant/components/device_tracker/owntracks.py @@ -19,26 +19,27 @@ from homeassistant.components import zone as zone_comp from homeassistant.components.device_tracker import PLATFORM_SCHEMA -DEPENDENCIES = ['mqtt'] REQUIREMENTS = ['libnacl==1.5.0'] -REGIONS_ENTERED = defaultdict(list) -MOBILE_BEACONS_ACTIVE = defaultdict(list) +_LOGGER = logging.getLogger(__name__) BEACON_DEV_ID = 'beacon' -LOCATION_TOPIC = 'owntracks/+/+' -EVENT_TOPIC = 'owntracks/+/+/event' -WAYPOINT_TOPIC = 'owntracks/{}/{}/waypoint' +CONF_MAX_GPS_ACCURACY = 'max_gps_accuracy' +CONF_SECRET = 'secret' +CONF_WAYPOINT_IMPORT = 'waypoints' +CONF_WAYPOINT_WHITELIST = 'waypoint_whitelist' -_LOGGER = logging.getLogger(__name__) +DEPENDENCIES = ['mqtt'] + +EVENT_TOPIC = 'owntracks/+/+/event' +LOCATION_TOPIC = 'owntracks/+/+' LOCK = threading.Lock() -CONF_MAX_GPS_ACCURACY = 'max_gps_accuracy' -CONF_WAYPOINT_IMPORT = 'waypoints' -CONF_WAYPOINT_WHITELIST = 'waypoint_whitelist' -CONF_SECRET = 'secret' +MOBILE_BEACONS_ACTIVE = defaultdict(list) + +REGIONS_ENTERED = defaultdict(list) VALIDATE_LOCATION = 'location' VALIDATE_TRANSITION = 'transition' @@ -46,6 +47,7 @@ WAYPOINT_LAT_KEY = 'lat' WAYPOINT_LON_KEY = 'lon' +WAYPOINT_TOPIC = 'owntracks/{}/{}/waypoint' PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_MAX_GPS_ACCURACY): vol.Coerce(float), @@ -70,7 +72,7 @@ def decrypt(ciphertext, key): def setup_scanner(hass, config, see): - """Setup an OwnTracks tracker.""" + """Set up an OwnTracks tracker.""" max_gps_accuracy = config.get(CONF_MAX_GPS_ACCURACY) waypoint_import = config.get(CONF_WAYPOINT_IMPORT) waypoint_whitelist = config.get(CONF_WAYPOINT_WHITELIST) @@ -113,7 +115,7 @@ def decrypt_payload(topic, ciphertext): return None def validate_payload(topic, payload, data_type): - """Validate OwnTracks payload.""" + """Validate the OwnTracks payload.""" # pylint: disable=too-many-return-statements try: diff --git a/tests/components/device_tracker/test_owntracks.py b/tests/components/device_tracker/test_owntracks.py index ef3d79d089b21..9ee9c80dc4368 100644 --- a/tests/components/device_tracker/test_owntracks.py +++ b/tests/components/device_tracker/test_owntracks.py @@ -17,17 +17,17 @@ USER = 'greg' DEVICE = 'phone' -LOCATION_TOPIC = "owntracks/{}/{}".format(USER, DEVICE) -EVENT_TOPIC = "owntracks/{}/{}/event".format(USER, DEVICE) +LOCATION_TOPIC = 'owntracks/{}/{}'.format(USER, DEVICE) +EVENT_TOPIC = 'owntracks/{}/{}/event'.format(USER, DEVICE) WAYPOINT_TOPIC = owntracks.WAYPOINT_TOPIC.format(USER, DEVICE) USER_BLACKLIST = 'ram' -WAYPOINT_TOPIC_BLOCKED = owntracks.WAYPOINT_TOPIC.format(USER_BLACKLIST, - DEVICE) +WAYPOINT_TOPIC_BLOCKED = owntracks.WAYPOINT_TOPIC.format( + USER_BLACKLIST, DEVICE) -DEVICE_TRACKER_STATE = "device_tracker.{}_{}".format(USER, DEVICE) +DEVICE_TRACKER_STATE = 'device_tracker.{}_{}'.format(USER, DEVICE) IBEACON_DEVICE = 'keys' -REGION_TRACKER_STATE = "device_tracker.beacon_{}".format(IBEACON_DEVICE) +REGION_TRACKER_STATE = 'device_tracker.beacon_{}'.format(IBEACON_DEVICE) CONF_MAX_GPS_ACCURACY = 'max_gps_accuracy' CONF_WAYPOINT_IMPORT = owntracks.CONF_WAYPOINT_IMPORT @@ -186,7 +186,7 @@ BAD_JSON_PREFIX = '--$this is bad json#--' BAD_JSON_SUFFIX = '** and it ends here ^^' -SECRET_KEY = "s3cretkey" +SECRET_KEY = 's3cretkey' ENCRYPTED_LOCATION_MESSAGE = { # Encrypted version of LOCATION_MESSAGE using libsodium and SECRET_KEY '_type': 'encrypted', @@ -678,8 +678,7 @@ def test_waypoint_import_existing(self): except (ImportError, OSError): libnacl = None - @unittest.skipUnless(libnacl, - "libnacl/libsodium is not installed") + @unittest.skipUnless(libnacl, "libnacl/libsodium is not installed") def test_encrypted_payload_libsodium(self): """Test sending encrypted message payload.""" self.assertTrue(device_tracker.setup(self.hass, { @@ -705,6 +704,7 @@ def mock_decrypt(ciphertext, key): @patch('homeassistant.components.device_tracker.owntracks.get_cipher', mock_cipher) def test_encrypted_payload(self): + """Test encrypted payload.""" self.assertTrue(device_tracker.setup(self.hass, { device_tracker.DOMAIN: { CONF_PLATFORM: 'owntracks', @@ -716,6 +716,7 @@ def test_encrypted_payload(self): @patch('homeassistant.components.device_tracker.owntracks.get_cipher', mock_cipher) def test_encrypted_payload_topic_key(self): + """Test encrypted payload with a topic key.""" self.assertTrue(device_tracker.setup(self.hass, { device_tracker.DOMAIN: { CONF_PLATFORM: 'owntracks', @@ -728,6 +729,7 @@ def test_encrypted_payload_topic_key(self): @patch('homeassistant.components.device_tracker.owntracks.get_cipher', mock_cipher) def test_encrypted_payload_no_key(self): + """Test encrypted payload with no key.""" self.assertTrue(device_tracker.setup(self.hass, { device_tracker.DOMAIN: { CONF_PLATFORM: 'owntracks', @@ -739,6 +741,7 @@ def test_encrypted_payload_no_key(self): @patch('homeassistant.components.device_tracker.owntracks.get_cipher', mock_cipher) def test_encrypted_payload_wrong_key(self): + """Test encrypted payload with wrong key.""" self.assertTrue(device_tracker.setup(self.hass, { device_tracker.DOMAIN: { CONF_PLATFORM: 'owntracks', @@ -750,11 +753,12 @@ def test_encrypted_payload_wrong_key(self): @patch('homeassistant.components.device_tracker.owntracks.get_cipher', mock_cipher) def test_encrypted_payload_wrong_topic_key(self): + """Test encrypted payload with wrong topic key.""" self.assertTrue(device_tracker.setup(self.hass, { device_tracker.DOMAIN: { CONF_PLATFORM: 'owntracks', CONF_SECRET: { - LOCATION_TOPIC: "wrong key" + LOCATION_TOPIC: 'wrong key' }}})) self.send_message(LOCATION_TOPIC, MOCK_ENCRYPTED_LOCATION_MESSAGE) self.assert_location_latitude(None) @@ -762,11 +766,12 @@ def test_encrypted_payload_wrong_topic_key(self): @patch('homeassistant.components.device_tracker.owntracks.get_cipher', mock_cipher) def test_encrypted_payload_no_topic_key(self): + """Test encrypted payload with no topic key.""" self.assertTrue(device_tracker.setup(self.hass, { device_tracker.DOMAIN: { CONF_PLATFORM: 'owntracks', CONF_SECRET: { - "owntracks/{}/{}".format(USER, "otherdevice"): "foobar" + 'owntracks/{}/{}'.format(USER, 'otherdevice'): 'foobar' }}})) self.send_message(LOCATION_TOPIC, MOCK_ENCRYPTED_LOCATION_MESSAGE) self.assert_location_latitude(None) From 8b059e9aadc704257a60a11711a93c9997ec667a Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Thu, 6 Oct 2016 16:11:08 +0200 Subject: [PATCH 098/112] Migrate to voluptuous (#3687) --- .../components/media_player/webostv.py | 57 ++++++++++++------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/homeassistant/components/media_player/webostv.py b/homeassistant/components/media_player/webostv.py index a0ba223739104..a283c8ce9b248 100644 --- a/homeassistant/components/media_player/webostv.py +++ b/homeassistant/components/media_player/webostv.py @@ -8,24 +8,31 @@ from datetime import timedelta from urllib.parse import urlparse +import voluptuous as vol + import homeassistant.util as util from homeassistant.components.media_player import ( SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PREVIOUS_TRACK, SUPPORT_TURN_OFF, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP, SUPPORT_SELECT_SOURCE, SUPPORT_PLAY_MEDIA, MEDIA_TYPE_CHANNEL, - MediaPlayerDevice) + MediaPlayerDevice, PLATFORM_SCHEMA) from homeassistant.const import ( CONF_HOST, CONF_CUSTOMIZE, STATE_OFF, STATE_PLAYING, STATE_PAUSED, - STATE_UNKNOWN) + STATE_UNKNOWN, CONF_NAME) from homeassistant.loader import get_component - -_CONFIGURING = {} -_LOGGER = logging.getLogger(__name__) +import homeassistant.helpers.config_validation as cv REQUIREMENTS = ['https://github.com/TheRealLink/pylgtv' '/archive/v0.1.2.zip' '#pylgtv==0.1.2'] +_CONFIGURING = {} +_LOGGER = logging.getLogger(__name__) + +CONF_SOURCES = 'sources' + +DEFAULT_NAME = 'LG WebOS Smart TV' + SUPPORT_WEBOSTV = SUPPORT_PAUSE | SUPPORT_VOLUME_STEP | \ SUPPORT_VOLUME_MUTE | SUPPORT_PREVIOUS_TRACK | \ SUPPORT_NEXT_TRACK | SUPPORT_TURN_OFF | \ @@ -44,6 +51,17 @@ 'makotv': WEBOS_APP_MAKO } +CUSTOMIZE_SCHEMA = vol.Schema({ + vol.Optional(CONF_SOURCES): + vol.All(cv.ensure_list, [vol.In(WEBOS_APPS_SHORT)]), +}) + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_HOST): cv.string, + vol.Optional(CONF_CUSTOMIZE, default={}): CUSTOMIZE_SCHEMA, +}) + # pylint: disable=unused-argument def setup_platform(hass, config, add_devices, discovery_info=None): @@ -51,21 +69,22 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if discovery_info is not None: host = urlparse(discovery_info[1]).hostname else: - host = config.get(CONF_HOST, None) + host = config.get(CONF_HOST) if host is None: - _LOGGER.error('No host found in configuration') + _LOGGER.error("No host found in configuration") return False # Only act if we are not already configuring this host if host in _CONFIGURING: return - customize = config.get(CONF_CUSTOMIZE, {}) - setup_tv(host, customize, hass, add_devices) + name = config.get(CONF_NAME) + customize = config.get(CONF_CUSTOMIZE) + setup_tv(host, name, customize, hass, add_devices) -def setup_tv(host, customize, hass, add_devices): +def setup_tv(host, name, customize, hass, add_devices): """Setup a phue bridge based on host parameter.""" from pylgtv import WebOsClient from pylgtv import PyLGTVPairException @@ -79,15 +98,15 @@ def setup_tv(host, customize, hass, add_devices): client.register() except PyLGTVPairException: _LOGGER.warning( - 'Connected to LG WebOS TV at %s but not paired.', host) + "Connected to LG WebOS TV at %s but not paired", host) return except OSError: - _LOGGER.error('Unable to connect to host %s.', host) + _LOGGER.error("Unable to connect to host %s", host) return else: # Not registered, request configuration. _LOGGER.warning('LG WebOS TV at %s needs to be paired.', host) - request_configuration(host, customize, hass, add_devices) + request_configuration(host, name, customize, hass, add_devices) return # If we came here and configuring this host, mark as done. @@ -96,10 +115,10 @@ def setup_tv(host, customize, hass, add_devices): configurator = get_component('configurator') configurator.request_done(request_id) - add_devices([LgWebOSDevice(host, customize)]) + add_devices([LgWebOSDevice(host, name, customize)]) -def request_configuration(host, customize, hass, add_devices): +def request_configuration(host, name, customize, hass, add_devices): """Request configuration steps from the user.""" configurator = get_component('configurator') @@ -112,7 +131,7 @@ def request_configuration(host, customize, hass, add_devices): # pylint: disable=unused-argument def lgtv_configuration_callback(data): """The actions to do when our configuration callback is called.""" - setup_tv(host, customize, hass, add_devices) + setup_tv(host, name, customize, hass, add_devices) _CONFIGURING[host] = configurator.request_config( hass, 'LG WebOS TV', lgtv_configuration_callback, @@ -128,13 +147,13 @@ class LgWebOSDevice(MediaPlayerDevice): """Representation of a LG WebOS TV.""" # pylint: disable=too-many-public-methods - def __init__(self, host, customize): + def __init__(self, host, name, customize): """Initialize the webos device.""" from pylgtv import WebOsClient self._client = WebOsClient(host) self._customize = customize - self._name = 'LG WebOS TV Remote' + self._name = name # Assume that the TV is not muted self._muted = False # Assume that the TV is in Play mode @@ -160,7 +179,7 @@ def update(self): self._app_list = {} custom_sources = [] - for source in self._customize.get('sources', []): + for source in self._customize.get(CONF_SOURCES, []): app_id = WEBOS_APPS_SHORT.get(source, None) if app_id: custom_sources.append(app_id) From 5e16dc63073c764d64f1ca2fab58298df7fcd5dd Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 7 Oct 2016 09:00:12 +0200 Subject: [PATCH 099/112] Fix typo (#3744) --- homeassistant/components/netatmo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/netatmo.py b/homeassistant/components/netatmo.py index 2769f8e2f730c..07f90d0879e55 100644 --- a/homeassistant/components/netatmo.py +++ b/homeassistant/components/netatmo.py @@ -37,7 +37,7 @@ def setup(hass, config): - """Setup the Netatmo devices.""" + """Set up the Netatmo devices.""" import lnetatmo global NETATMO_AUTH @@ -47,7 +47,7 @@ def setup(hass, config): config[DOMAIN][CONF_USERNAME], config[DOMAIN][CONF_PASSWORD], 'read_station read_camera access_camera') except HTTPError: - _LOGGER.error("Unable to connect to NatAtmo API") + _LOGGER.error("Unable to connect to Netatmo API") return False for component in 'camera', 'sensor': From 58b3dd7cc0f4007fd3b931ec6d379ac9e249c113 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Fri, 7 Oct 2016 11:34:41 -0700 Subject: [PATCH 100/112] Set specific commit for Hunter Douglas API package due to upstream rename --- homeassistant/components/scene/hunterdouglas_powerview.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/scene/hunterdouglas_powerview.py b/homeassistant/components/scene/hunterdouglas_powerview.py index 934d06e21228a..9fc36cf1cfff5 100644 --- a/homeassistant/components/scene/hunterdouglas_powerview.py +++ b/homeassistant/components/scene/hunterdouglas_powerview.py @@ -12,7 +12,7 @@ _LOGGER = logging.getLogger(__name__) REQUIREMENTS = [ 'https://github.com/sander76/powerviewApi/' - 'archive/master.zip#powerviewApi==0.2'] + 'archive/cc6f75dd39160d4aaf46cb2ed9220136b924bcb4.zip#powerviewApi==0.2'] HUB_ADDRESS = 'address' diff --git a/requirements_all.txt b/requirements_all.txt index 0a9468acacb8e..a8ffdb6a160fc 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -205,7 +205,7 @@ https://github.com/rkabadi/pyedimax/archive/365301ce3ff26129a7910c501ead09ea625f https://github.com/robbiet480/pygtfs/archive/00546724e4bbcb3053110d844ca44e2246267dd8.zip#pygtfs==0.1.3 # homeassistant.components.scene.hunterdouglas_powerview -https://github.com/sander76/powerviewApi/archive/master.zip#powerviewApi==0.2 +https://github.com/sander76/powerviewApi/archive/cc6f75dd39160d4aaf46cb2ed9220136b924bcb4.zip#powerviewApi==0.2 # homeassistant.components.mysensors https://github.com/theolind/pymysensors/archive/8ce98b7fb56f7921a808eb66845ce8b2c455c81e.zip#pymysensors==0.7.1 From 3cfec2b5e2935591db616056a189a141628feb0b Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Fri, 7 Oct 2016 11:36:43 -0700 Subject: [PATCH 101/112] Set TP-Link switch to specific commit instead of master --- homeassistant/components/switch/tplink.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/switch/tplink.py b/homeassistant/components/switch/tplink.py index ddb10e74c3755..7937a4c77ac0f 100644 --- a/homeassistant/components/switch/tplink.py +++ b/homeassistant/components/switch/tplink.py @@ -13,7 +13,7 @@ import homeassistant.helpers.config_validation as cv REQUIREMENTS = ['https://github.com/gadgetreactor/pyHS100/archive/' - 'master.zip#pyHS100==0.1.2'] + 'ef85f939fd5b07064a0f34dfa673fa7d6140bd95.zip#pyHS100==0.1.2'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index a8ffdb6a160fc..dc3467ed65fc2 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -171,7 +171,7 @@ https://github.com/danieljkemp/onkyo-eiscp/archive/python3.zip#onkyo-eiscp==0.9. # https://github.com/deisi/fritzconnection/archive/b5c14515e1c8e2652b06b6316a7f3913df942841.zip#fritzconnection==0.4.6 # homeassistant.components.switch.tplink -https://github.com/gadgetreactor/pyHS100/archive/master.zip#pyHS100==0.1.2 +https://github.com/gadgetreactor/pyHS100/archive/ef85f939fd5b07064a0f34dfa673fa7d6140bd95.zip#pyHS100==0.1.2 # homeassistant.components.netatmo https://github.com/jabesq/netatmo-api-python/archive/v0.5.0.zip#lnetatmo==0.5.0 From f030ff67ad0848431bc91b624d62f2e32be38ac7 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Fri, 7 Oct 2016 11:38:39 -0700 Subject: [PATCH 102/112] Set anel_pwrctrl switch to specific commit instead of master --- homeassistant/components/switch/anel_pwrctrl.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/switch/anel_pwrctrl.py b/homeassistant/components/switch/anel_pwrctrl.py index 61e0985b647d4..93e34a61baae9 100644 --- a/homeassistant/components/switch/anel_pwrctrl.py +++ b/homeassistant/components/switch/anel_pwrctrl.py @@ -17,7 +17,7 @@ REQUIREMENTS = ['https://github.com/mweinelt/anel-pwrctrl/archive/' - 'master.zip#anel_pwrctrl==0.0.1'] + 'ed26e8830e28a2bfa4260a9002db23ce3e7e63d7.zip#anel_pwrctrl==0.0.1'] CONF_PORT_RECV = "port_recv" CONF_PORT_SEND = "port_send" diff --git a/requirements_all.txt b/requirements_all.txt index dc3467ed65fc2..8a65b76f5cca4 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -186,7 +186,7 @@ https://github.com/kellerza/pyqwikswitch/archive/v0.4.zip#pyqwikswitch==0.4 https://github.com/laf/russound/archive/0.1.6.zip#russound==0.1.6 # homeassistant.components.switch.anel_pwrctrl -https://github.com/mweinelt/anel-pwrctrl/archive/master.zip#anel_pwrctrl==0.0.1 +https://github.com/mweinelt/anel-pwrctrl/archive/ed26e8830e28a2bfa4260a9002db23ce3e7e63d7.zip#anel_pwrctrl==0.0.1 # homeassistant.components.ecobee https://github.com/nkgilley/python-ecobee-api/archive/4856a704670c53afe1882178a89c209b5f98533d.zip#python-ecobee==0.0.6 From f37038921f78c9e67425849de9d5db546d12d61c Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Fri, 7 Oct 2016 11:48:38 -0700 Subject: [PATCH 103/112] Fix E501 line too long error --- homeassistant/components/switch/anel_pwrctrl.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/switch/anel_pwrctrl.py b/homeassistant/components/switch/anel_pwrctrl.py index 93e34a61baae9..024fefe2bc549 100644 --- a/homeassistant/components/switch/anel_pwrctrl.py +++ b/homeassistant/components/switch/anel_pwrctrl.py @@ -17,7 +17,8 @@ REQUIREMENTS = ['https://github.com/mweinelt/anel-pwrctrl/archive/' - 'ed26e8830e28a2bfa4260a9002db23ce3e7e63d7.zip#anel_pwrctrl==0.0.1'] + 'ed26e8830e28a2bfa4260a9002db23ce3e7e63d7.zip' + '#anel_pwrctrl==0.0.1'] CONF_PORT_RECV = "port_recv" CONF_PORT_SEND = "port_send" From 1c24018fbb48a88f72d733ebb9e5d9b50d395e2c Mon Sep 17 00:00:00 2001 From: Erik Eriksson Date: Sat, 8 Oct 2016 02:16:35 +0200 Subject: [PATCH 104/112] Improved exception handling (#3746) --- .../components/media_player/squeezebox.py | 80 ++++++++++--------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/homeassistant/components/media_player/squeezebox.py b/homeassistant/components/media_player/squeezebox.py index 62b82048eb1fd..d54226b05660e 100644 --- a/homeassistant/components/media_player/squeezebox.py +++ b/homeassistant/components/media_player/squeezebox.py @@ -79,18 +79,11 @@ def __init__(self, host, port, username, password): def _get_http_port(self): """Get http port from media server, it is used to get cover art.""" - http_port = None - try: - http_port = self.query('pref', 'httpport', '?') - if not http_port: - _LOGGER.error("Unable to read data from server %s:%s", - self.host, self.port) - return - return http_port - except ConnectionError as ex: - _LOGGER.error("Failed to connect to server %s:%s - %s", - self.host, self.port, ex) - return + http_port = self.query('pref', 'httpport', '?') + if not http_port: + _LOGGER.error("Failed to connect to server %s:%s", + self.host, self.port) + return http_port def create_players(self): """Create a list of SqueezeBoxDevices connected to the LMS.""" @@ -104,20 +97,27 @@ def create_players(self): def query(self, *parameters): """Send request and await response from server.""" - telnet = telnetlib.Telnet(self.host, self.port) - if self._username and self._password: - telnet.write('login {username} {password}\n'.format( - username=self._username, - password=self._password).encode('UTF-8')) - telnet.read_until(b'\n', timeout=3) - message = '{}\n'.format(' '.join(parameters)) - telnet.write(message.encode('UTF-8')) - response = telnet.read_until(b'\n', timeout=3)\ - .decode('UTF-8')\ - .split(' ')[-1]\ - .strip() - telnet.write(b'exit\n') - return urllib.parse.unquote(response) + try: + telnet = telnetlib.Telnet(self.host, self.port) + if self._username and self._password: + telnet.write('login {username} {password}\n'.format( + username=self._username, + password=self._password).encode('UTF-8')) + telnet.read_until(b'\n', timeout=3) + message = '{}\n'.format(' '.join(parameters)) + telnet.write(message.encode('UTF-8')) + response = telnet.read_until(b'\n', timeout=3)\ + .decode('UTF-8')\ + .split(' ')[-1]\ + .strip() + telnet.write(b'exit\n') + return urllib.parse.unquote(response) + except (OSError, ConnectionError) as error: + _LOGGER.error("Could not communicate with %s:%d: %s", + self.host, + self.port, + error) + return None def get_player_status(self, player): """Get ithe status of a player.""" @@ -128,18 +128,24 @@ def get_player_status(self, player): # K (artwork_url): URL to remote artwork tags = 'adK' new_status = {} - telnet = telnetlib.Telnet(self.host, self.port) - telnet.write('{player} status - 1 tags:{tags}\n'.format( - player=player, - tags=tags + try: + telnet = telnetlib.Telnet(self.host, self.port) + telnet.write('{player} status - 1 tags:{tags}\n'.format( + player=player, + tags=tags ).encode('UTF-8')) - response = telnet.read_until(b'\n', timeout=3)\ - .decode('UTF-8')\ - .split(' ') - telnet.write(b'exit\n') - for item in response: - parts = urllib.parse.unquote(item).partition(':') - new_status[parts[0]] = parts[2] + response = telnet.read_until(b'\n', timeout=3)\ + .decode('UTF-8')\ + .split(' ') + telnet.write(b'exit\n') + for item in response: + parts = urllib.parse.unquote(item).partition(':') + new_status[parts[0]] = parts[2] + except (OSError, ConnectionError) as error: + _LOGGER.error("Could not communicate with %s:%d: %s", + self.host, + self.port, + error) return new_status From f1e5d32ef5468ff30100e2984a0f4a21818bce76 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Sat, 8 Oct 2016 02:20:39 +0200 Subject: [PATCH 105/112] Async exception handling (#3731) * remove unused exception * add logging * disable pylint broad-except * add exception handler * fix lint * update log output * change log message in async with exc_info * Add exc_info to asyncio exception handler --- homeassistant/core.py | 20 ++++++++++++++++++++ homeassistant/util/async.py | 12 ++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/homeassistant/core.py b/homeassistant/core.py index bcd96b9d3a9e5..cf3d2e2504308 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -136,6 +136,7 @@ def __init__(self, loop=None): self.loop = loop or asyncio.get_event_loop() self.executor = ThreadPoolExecutor(max_workers=5) self.loop.set_default_executor(self.executor) + self.loop.set_exception_handler(self._async_exception_handler) self.pool = pool = create_worker_pool() self.bus = EventBus(pool, self.loop) self.services = ServiceRegistry(self.bus, self.add_job, self.loop) @@ -318,6 +319,25 @@ def async_stop(self) -> None: self.state = CoreState.not_running self.loop.stop() + # pylint: disable=no-self-use + def _async_exception_handler(self, loop, context): + """Handle all exception inside the core loop.""" + message = context.get('message') + if message: + _LOGGER.warning( + "Error inside async loop: %s", + message + ) + + # for debug modus + exception = context.get('exception') + if exception is not None: + exc_info = (type(exception), exception, exception.__traceback__) + _LOGGER.debug( + "Exception inside async loop: ", + exc_info=exc_info + ) + class EventOrigin(enum.Enum): """Represent the origin of an event.""" diff --git a/homeassistant/util/async.py b/homeassistant/util/async.py index ff498912fc2fc..de34a12774869 100644 --- a/homeassistant/util/async.py +++ b/homeassistant/util/async.py @@ -1,6 +1,7 @@ """Asyncio backports for Python 3.4.3 compatibility.""" import concurrent.futures import threading +import logging from asyncio import coroutines from asyncio.futures import Future @@ -13,6 +14,9 @@ ensure_future = async +_LOGGER = logging.getLogger(__name__) + + def _set_result_unless_cancelled(fut, result): """Helper setting the result only if the future was not cancelled.""" if fut.cancelled(): @@ -111,10 +115,12 @@ def callback(): try: # pylint: disable=deprecated-method _chain_future(ensure_future(coro, loop=loop), future) + # pylint: disable=broad-except except Exception as exc: if future.set_running_or_notify_cancel(): future.set_exception(exc) - raise + else: + _LOGGER.warning("Exception on lost future: ", exc_info=True) loop.call_soon_threadsafe(callback) return future @@ -158,10 +164,12 @@ def run_callback(): """Run callback and store result.""" try: future.set_result(callback(*args)) + # pylint: disable=broad-except except Exception as exc: if future.set_running_or_notify_cancel(): future.set_exception(exc) - raise + else: + _LOGGER.warning("Exception on lost future: ", exc_info=True) loop.call_soon_threadsafe(run_callback) return future From fccc7e69d025b6d3cc0e1cd2b981e8f62fb2ba96 Mon Sep 17 00:00:00 2001 From: Erik Eriksson Date: Sat, 8 Oct 2016 02:24:02 +0200 Subject: [PATCH 106/112] Improved exception handling. Don't stop updating from server because of exception. (#3724) --- .../components/device_tracker/volvooncall.py | 79 +++++++++---------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/homeassistant/components/device_tracker/volvooncall.py b/homeassistant/components/device_tracker/volvooncall.py index 703fe32e53869..8f5cf5fff7a0c 100644 --- a/homeassistant/components/device_tracker/volvooncall.py +++ b/homeassistant/components/device_tracker/volvooncall.py @@ -39,28 +39,46 @@ def setup_scanner(hass, config, see): """Validate the configuration and return a scanner.""" - username = config.get(CONF_USERNAME) - password = config.get(CONF_PASSWORD) + session = requests.Session() + session.headers.update(HEADERS) + session.auth = (config.get(CONF_USERNAME), + config.get(CONF_PASSWORD)) interval = max(MIN_TIME_BETWEEN_SCANS.seconds, config.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)) - session = requests.Session() - session.headers.update(HEADERS) - session.auth = (username, password) - def query(ref, rel=SERVICE_URL): """Perform a query to the online service.""" url = urljoin(rel, ref) + _LOGGER.debug("Request for %s", url) + res = session.get(url, timeout=15) + res.raise_for_status() + _LOGGER.debug("Received %s", res.json()) + return res.json() + + def update(now): + """Update status from the online service.""" try: - _LOGGER.debug("Request for %s", url) - res = session.get(url) - res.raise_for_status() - _LOGGER.debug("Received %s", res.json()) - return res.json() - except requests.exceptions.RequestException: - _LOGGER.exception("Could not make query to %s", url) - raise + _LOGGER.debug("Updating") + status = query("status", vehicle_url) + position = query("position", vehicle_url) + see(dev_id=dev_id, + host_name=host_name, + gps=(position["position"]["latitude"], + position["position"]["longitude"]), + attributes=dict( + tank_volume=attributes["fuelTankVolume"], + washer_fluid=status["washerFluidLevel"], + brake_fluid=status["brakeFluid"], + service_warning=status["serviceWarningStatus"], + fuel=status["fuelAmount"], + odometer=status["odometer"], + range=status["distanceToEmpty"])) + except requests.exceptions.RequestException as error: + _LOGGER.error("Could not query server: %s", error) + finally: + track_point_in_utc_time(hass, update, + now + timedelta(seconds=interval)) try: _LOGGER.info('Logging in to service') @@ -73,33 +91,10 @@ def query(ref, rel=SERVICE_URL): host_name = "%s %s/%s" % (attributes["registrationNumber"], attributes["vehicleType"], attributes["modelYear"]) - except requests.exceptions.RequestException: + update(utcnow()) + return True + except requests.exceptions.RequestException as error: _LOGGER.error("Could not log in to service. " - "Please check configuration.") + "Please check configuration: " + "%s", error) return False - - def update(now): - """Update status from the online service.""" - _LOGGER.debug("Updating") - - status = query("status", vehicle_url) - position = query("position", vehicle_url) - - see(dev_id=dev_id, - host_name=host_name, - gps=(position["position"]["latitude"], - position["position"]["longitude"]), - attributes=dict( - tank_volume=attributes["fuelTankVolume"], - washer_fluid=status["washerFluidLevel"], - brake_fluid=status["brakeFluid"], - service_warning=status["serviceWarningStatus"], - fuel=status["fuelAmount"], - odometer=status["odometer"], - range=status["distanceToEmpty"])) - - track_point_in_utc_time(hass, update, - now + timedelta(seconds=interval)) - - update(utcnow()) - return True From 2d4df42a6596d7004efa9d470a8b67bb046e8ae7 Mon Sep 17 00:00:00 2001 From: Erik Eriksson Date: Sat, 8 Oct 2016 02:25:51 +0200 Subject: [PATCH 107/112] improved error handling (#3725) --- homeassistant/components/tellduslive.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/tellduslive.py b/homeassistant/components/tellduslive.py index 3f9e67cf2bc0f..c83c0c4d25d19 100644 --- a/homeassistant/components/tellduslive.py +++ b/homeassistant/components/tellduslive.py @@ -62,23 +62,25 @@ def setup(hass, config): def request_switches(): """Make request to online service.""" _LOGGER.debug("Updating switches from Telldus Live") - switches = NETWORK.request('devices/list')['device'] + switches = NETWORK.request('devices/list') # Filter out any group of switches. - switches = {switch["id"]: switch for switch in switches + if switches and 'device' in switches: + return {switch["id"]: switch for switch in switches['device'] if switch["type"] == "device"} - return switches + return None @Throttle(MIN_TIME_BETWEEN_SENSOR_UPDATES) def request_sensors(): """Make request to online service.""" _LOGGER.debug("Updating sensors from Telldus Live") - units = NETWORK.request('sensors/list')['sensor'] + units = NETWORK.request('sensors/list') # One unit can contain many sensors. - sensors = {unit['id']+sensor['name']: dict(unit, data=sensor) - for unit in units - for sensor in unit['data']} - return sensors + if units and 'sensor' in units: + return {unit['id']+sensor['name']: dict(unit, data=sensor) + for unit in units['sensor'] + for sensor in unit['data']} + return None class TelldusLiveData(object): @@ -155,8 +157,9 @@ def request(self, what, **params): response = self._client.request(what, params) _LOGGER.debug("got response %s", response) return response - except (ConnectionError, TimeoutError): - _LOGGER.error("failed to make request to Tellduslive servers") + except (ConnectionError, TimeoutError, OSError) as error: + _LOGGER.error("failed to make request to Tellduslive servers: %s", + error) return None def update_devices(self, local_devices, remote_devices, component_name): From b09b13f5527da97e54915b89480bfe5922db2fce Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sat, 8 Oct 2016 02:30:59 +0200 Subject: [PATCH 108/112] Catch exception (fixes #3699) (#3727) --- homeassistant/components/sensor/pi_hole.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/sensor/pi_hole.py b/homeassistant/components/sensor/pi_hole.py index c6ffdcaf64cb2..a578a6bb11973 100644 --- a/homeassistant/components/sensor/pi_hole.py +++ b/homeassistant/components/sensor/pi_hole.py @@ -25,7 +25,7 @@ DEFAULT_HOST = 'localhost' DEFAULT_METHOD = 'GET' -DEFAULT_NAME = 'Pi-hole' +DEFAULT_NAME = 'Pi-Hole' DEFAULT_SSL = False DEFAULT_VERIFY_SSL = True @@ -59,7 +59,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): rest.update() if rest.data is None: - _LOGGER.error('Unable to fetch REST data') + _LOGGER.error("Unable to fetch data from Pi-Hole") return False add_devices([PiHoleSensor(hass, rest, name)]) @@ -99,5 +99,8 @@ def state_attributes(self): def update(self): """Get the latest data from REST API and updates the state.""" - self.rest.update() - self._state = json.loads(self.rest.data) + try: + self.rest.update() + self._state = json.loads(self.rest.data) + except TypeError: + _LOGGER.error("Unable to fetch data from Pi-Hole") From fb94aaa5a1a1e125dafb681e50c18be45dfe1b19 Mon Sep 17 00:00:00 2001 From: Johann Kellerman Date: Sat, 8 Oct 2016 03:08:33 +0200 Subject: [PATCH 109/112] Load yaml using validator and include consider_home (#3743) * Load yaml using validator, consider_home * timedelta, track_if_away * improve voluptuous * Add default back * Change time_period validation order --- .../components/device_tracker/__init__.py | 46 ++++++++++++------- homeassistant/helpers/config_validation.py | 11 ++++- tests/components/device_tracker/test_init.py | 22 ++++----- tests/helpers/test_config_validation.py | 5 +- 4 files changed, 53 insertions(+), 31 deletions(-) diff --git a/homeassistant/components/device_tracker/__init__.py b/homeassistant/components/device_tracker/__init__.py index 236fde6fb3ffb..a05b57cff3385 100644 --- a/homeassistant/components/device_tracker/__init__.py +++ b/homeassistant/components/device_tracker/__init__.py @@ -46,7 +46,6 @@ DEFAULT_TRACK_NEW = True CONF_CONSIDER_HOME = 'consider_home' -DEFAULT_CONSIDER_HOME = 180 # seconds CONF_SCAN_INTERVAL = 'interval_seconds' DEFAULT_SCAN_INTERVAL = 12 @@ -70,8 +69,10 @@ _CONFIG_SCHEMA = vol.Schema({DOMAIN: vol.All(cv.ensure_list, [ vol.Schema({ - vol.Optional(CONF_TRACK_NEW): cv.boolean, - vol.Optional(CONF_CONSIDER_HOME): cv.positive_int # seconds + vol.Optional(CONF_TRACK_NEW, default=DEFAULT_TRACK_NEW): cv.boolean, + vol.Optional( + CONF_CONSIDER_HOME, default=timedelta(seconds=180)): vol.All( + cv.time_period, cv.positive_timedelta) }, extra=vol.ALLOW_EXTRA)])}, extra=vol.ALLOW_EXTRA) DISCOVERY_PLATFORMS = { @@ -118,9 +119,8 @@ def setup(hass: HomeAssistantType, config: ConfigType): return False else: conf = conf[0] if len(conf) > 0 else {} - consider_home = timedelta( - seconds=conf.get(CONF_CONSIDER_HOME, DEFAULT_CONSIDER_HOME)) - track_new = conf.get(CONF_TRACK_NEW, DEFAULT_TRACK_NEW) + consider_home = conf[CONF_CONSIDER_HOME] + track_new = conf[CONF_TRACK_NEW] devices = load_config(yaml_path, hass, consider_home) @@ -282,7 +282,7 @@ class Device(Entity): def __init__(self, hass: HomeAssistantType, consider_home: timedelta, track: bool, dev_id: str, mac: str, name: str=None, picture: str=None, gravatar: str=None, - away_hide: bool=False) -> None: + hide_if_away: bool=False) -> None: """Initialize a device.""" self.hass = hass self.entity_id = ENTITY_ID_FORMAT.format(dev_id) @@ -307,7 +307,7 @@ def __init__(self, hass: HomeAssistantType, consider_home: timedelta, else: self.config_picture = picture - self.away_hide = away_hide + self.away_hide = hide_if_away @property def name(self): @@ -398,15 +398,29 @@ def update(self): def load_config(path: str, hass: HomeAssistantType, consider_home: timedelta): """Load devices from YAML configuration file.""" + dev_schema = vol.Schema({ + vol.Required('name'): cv.string, + vol.Optional('track', default=False): cv.boolean, + vol.Optional('mac', default=None): vol.Any(None, vol.All(cv.string, + vol.Upper)), + vol.Optional(CONF_AWAY_HIDE, default=DEFAULT_AWAY_HIDE): cv.boolean, + vol.Optional('gravatar', default=None): vol.Any(None, cv.string), + vol.Optional('picture', default=None): vol.Any(None, cv.string), + vol.Optional(CONF_CONSIDER_HOME, default=consider_home): vol.All( + cv.time_period, cv.positive_timedelta) + }) try: - return [ - Device(hass, consider_home, device.get('track', False), - str(dev_id).lower(), None if device.get('mac') is None - else str(device.get('mac')).upper(), - device.get('name'), device.get('picture'), - device.get('gravatar'), - device.get(CONF_AWAY_HIDE, DEFAULT_AWAY_HIDE)) - for dev_id, device in load_yaml_config_file(path).items()] + result = [] + devices = load_yaml_config_file(path) + for dev_id, device in devices.items(): + try: + device = dev_schema(device) + device['dev_id'] = cv.slug(dev_id) + except vol.Invalid as exp: + log_exception(exp, dev_id, devices) + else: + result.append(Device(hass, **device)) + return result except (HomeAssistantError, FileNotFoundError): # When YAML file could not be loaded/did not contain a dict return [] diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index 0981c20f40740..7236debbe8825 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -167,7 +167,16 @@ def time_period_str(value: str) -> timedelta: return offset -time_period = vol.Any(time_period_str, timedelta, time_period_dict) +def time_period_seconds(value: Union[int, str]) -> timedelta: + """Validate and transform seconds to a time offset.""" + try: + return timedelta(seconds=int(value)) + except (ValueError, TypeError): + raise vol.Invalid('Expected seconds, got {}'.format(value)) + + +time_period = vol.Any(time_period_str, time_period_seconds, timedelta, + time_period_dict) def match_all(value): diff --git a/tests/components/device_tracker/test_init.py b/tests/components/device_tracker/test_init.py index 9490938a6460e..f195712285aae 100644 --- a/tests/components/device_tracker/test_init.py +++ b/tests/components/device_tracker/test_init.py @@ -59,15 +59,13 @@ def test_is_on(self): def test_reading_broken_yaml_config(self): # pylint: disable=no-self-use """Test when known devices contains invalid data.""" files = {'empty.yaml': '', - 'bad.yaml': '100', - 'ok.yaml': 'my_device:\n name: Device'} + 'nodict.yaml': '100', + 'allok.yaml': 'my_device:\n name: Device'} + args = {'hass': self.hass, 'consider_home': timedelta(seconds=60)} with patch_yaml_files(files): - # File is empty - assert device_tracker.load_config('empty.yaml', None, False) == [] - # File contains a non-dict format - assert device_tracker.load_config('bad.yaml', None, False) == [] - # A file that works fine - assert len(device_tracker.load_config('ok.yaml', None, False)) == 1 + assert device_tracker.load_config('empty.yaml', **args) == [] + assert device_tracker.load_config('nodict.yaml', **args) == [] + assert len(device_tracker.load_config('allok.yaml', **args)) == 1 def test_reading_yaml_config(self): """Test the rendering of the YAML configuration.""" @@ -75,7 +73,7 @@ def test_reading_yaml_config(self): device = device_tracker.Device( self.hass, timedelta(seconds=180), True, dev_id, 'AB:CD:EF:GH:IJ', 'Test name', picture='http://test.picture', - away_hide=True) + hide_if_away=True) device_tracker.update_config(self.yaml_devices, dev_id, device) self.assertTrue(setup_component(self.hass, device_tracker.DOMAIN, TEST_PLATFORM)) @@ -211,7 +209,7 @@ def test_entity_attributes(self): device = device_tracker.Device( self.hass, timedelta(seconds=180), True, dev_id, None, - friendly_name, picture, away_hide=True) + friendly_name, picture, hide_if_away=True) device_tracker.update_config(self.yaml_devices, dev_id, device) self.assertTrue(setup_component(self.hass, device_tracker.DOMAIN, @@ -228,7 +226,7 @@ def test_device_hidden(self): entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id) device = device_tracker.Device( self.hass, timedelta(seconds=180), True, dev_id, None, - away_hide=True) + hide_if_away=True) device_tracker.update_config(self.yaml_devices, dev_id, device) scanner = get_component('device_tracker.test').SCANNER @@ -246,7 +244,7 @@ def test_group_all_devices(self): entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id) device = device_tracker.Device( self.hass, timedelta(seconds=180), True, dev_id, None, - away_hide=True) + hide_if_away=True) device_tracker.update_config(self.yaml_devices, dev_id, device) scanner = get_component('device_tracker.test').SCANNER diff --git a/tests/helpers/test_config_validation.py b/tests/helpers/test_config_validation.py index 7614375522085..9f929244888a0 100644 --- a/tests/helpers/test_config_validation.py +++ b/tests/helpers/test_config_validation.py @@ -200,17 +200,18 @@ def test_time_period(): schema = vol.Schema(cv.time_period) for value in ( - None, '', 1234, 'hello:world', '12:', '12:34:56:78', + None, '', 'hello:world', '12:', '12:34:56:78', {}, {'wrong_key': -10} ): with pytest.raises(vol.MultipleInvalid): schema(value) for value in ( - '8:20', '23:59', '-8:20', '-23:59:59', '-48:00', {'minutes': 5} + '8:20', '23:59', '-8:20', '-23:59:59', '-48:00', {'minutes': 5}, 1, '5' ): schema(value) + assert timedelta(seconds=180) == schema('180') assert timedelta(hours=23, minutes=59) == schema('23:59') assert -1 * timedelta(hours=1, minutes=15) == schema('-1:15') From 09cbf68637b8afbd866fe5089f0561e35e6bc1fd Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 8 Oct 2016 09:21:09 -0700 Subject: [PATCH 110/112] Update frontend --- homeassistant/components/frontend/version.py | 12 ++++++------ .../frontend/www_static/frontend.html | 4 ++-- .../frontend/www_static/frontend.html.gz | Bin 127662 -> 128054 bytes .../www_static/home-assistant-polymer | 2 +- .../www_static/panels/ha-panel-dev-event.html | 2 +- .../panels/ha-panel-dev-event.html.gz | Bin 2645 -> 2656 bytes .../www_static/panels/ha-panel-dev-info.html | 2 +- .../panels/ha-panel-dev-info.html.gz | Bin 1345 -> 1343 bytes .../panels/ha-panel-dev-service.html | 2 +- .../panels/ha-panel-dev-service.html.gz | Bin 2831 -> 2842 bytes .../www_static/panels/ha-panel-dev-state.html | 2 +- .../panels/ha-panel-dev-state.html.gz | Bin 2776 -> 2786 bytes .../panels/ha-panel-dev-template.html | 2 +- .../panels/ha-panel-dev-template.html.gz | Bin 7303 -> 7310 bytes .../frontend/www_static/service_worker.js | 2 +- .../frontend/www_static/service_worker.js.gz | Bin 2277 -> 2277 bytes 16 files changed, 15 insertions(+), 15 deletions(-) diff --git a/homeassistant/components/frontend/version.py b/homeassistant/components/frontend/version.py index d56a6fa53f6f4..2c8b0cc8bedd7 100644 --- a/homeassistant/components/frontend/version.py +++ b/homeassistant/components/frontend/version.py @@ -2,13 +2,13 @@ FINGERPRINTS = { "core.js": "9b3e5ab4eac7e3b074e0daf3f619a638", - "frontend.html": "82d72070030da9517180cd04830d36ab", + "frontend.html": "5854807d361de26fe93ad474010f19d2", "mdi.html": "46a76f877ac9848899b8ed382427c16f", - "panels/ha-panel-dev-event.html": "c4a5f70eece9f92616a65e8d26be803e", - "panels/ha-panel-dev-info.html": "8270b588aa06668e34f74f51b708a6bb", - "panels/ha-panel-dev-service.html": "07e83c6b7f79d78a59258f6dba477b54", - "panels/ha-panel-dev-state.html": "fd8eb946856b1346a87a51d0c86854ff", - "panels/ha-panel-dev-template.html": "7cff8a2ef3f44fdaf357a0d41696bf6d", + "panels/ha-panel-dev-event.html": "550bf85345c454274a40d15b2795a002", + "panels/ha-panel-dev-info.html": "ec613406ce7e20d93754233d55625c8a", + "panels/ha-panel-dev-service.html": "c7974458ebc33412d95497e99b785e12", + "panels/ha-panel-dev-state.html": "4be627b74e683af14ef779d8203ec674", + "panels/ha-panel-dev-template.html": "d23943fa0370f168714da407c90091a2", "panels/ha-panel-history.html": "efe1bcdd7733b09e55f4f965d171c295", "panels/ha-panel-iframe.html": "d920f0aa3c903680f2f8795e2255daab", "panels/ha-panel-logbook.html": "66108d82763359a218c9695f0553de40", diff --git a/homeassistant/components/frontend/www_static/frontend.html b/homeassistant/components/frontend/www_static/frontend.html index 3e7d725b2e739..adf2980c1b2d1 100644 --- a/homeassistant/components/frontend/www_static/frontend.html +++ b/homeassistant/components/frontend/www_static/frontend.html @@ -1,5 +1,5 @@

\ No newline at end of file +},customStyle:null,getComputedStyleValue:function(e){return!i&&this._styleProperties&&this._styleProperties[e]||getComputedStyle(this).getPropertyValue(e)},_setupStyleProperties:function(){this.customStyle={},this._styleCache=null,this._styleProperties=null,this._scopeSelector=null,this._ownStyleProperties=null,this._customStyle=null},_needsStyleProperties:function(){return Boolean(!i&&this._ownStylePropertyNames&&this._ownStylePropertyNames.length)},_validateApplyShim:function(){if(this.__applyShimInvalid){Polymer.ApplyShim.transform(this._styles,this.__proto__);var e=n.elementStyles(this);if(s){var t=this._template.content.querySelector("style");t&&(t.textContent=e)}else{var r=this._scopeStyle&&this._scopeStyle.nextSibling;r&&(r.textContent=e)}}},_beforeAttached:function(){this._scopeSelector&&!this.__stylePropertiesInvalid||!this._needsStyleProperties()||(this.__stylePropertiesInvalid=!1,this._updateStyleProperties())},_findStyleHost:function(){for(var e,t=this;e=Polymer.dom(t).getOwnerRoot();){if(Polymer.isInstance(e.host))return e.host;t=e.host}return r},_updateStyleProperties:function(){var e,n=this._findStyleHost();n._styleProperties||n._computeStyleProperties(),n._styleCache||(n._styleCache=new Polymer.StyleCache);var r=t.propertyDataFromStyles(n._styles,this),i=!this.__notStyleScopeCacheable;i&&(r.key.customStyle=this.customStyle,e=n._styleCache.retrieve(this.is,r.key,this._styles));var a=Boolean(e);a?this._styleProperties=e._styleProperties:this._computeStyleProperties(r.properties),this._computeOwnStyleProperties(),a||(e=o.retrieve(this.is,this._ownStyleProperties,this._styles));var l=Boolean(e)&&!a,c=this._applyStyleProperties(e);a||(c=c&&s?c.cloneNode(!0):c,e={style:c,_scopeSelector:this._scopeSelector,_styleProperties:this._styleProperties},i&&(r.key.customStyle={},this.mixin(r.key.customStyle,this.customStyle),n._styleCache.store(this.is,e,r.key,this._styles)),l||o.store(this.is,Object.create(e),this._ownStyleProperties,this._styles))},_computeStyleProperties:function(e){var n=this._findStyleHost();n._styleProperties||n._computeStyleProperties();var r=Object.create(n._styleProperties),s=t.hostAndRootPropertiesForScope(this);this.mixin(r,s.hostProps),e=e||t.propertyDataFromStyles(n._styles,this).properties,this.mixin(r,e),this.mixin(r,s.rootProps),t.mixinCustomStyle(r,this.customStyle),t.reify(r),this._styleProperties=r},_computeOwnStyleProperties:function(){for(var e,t={},n=0;n0&&l.push(t);return[{removed:a,added:l}]}},Polymer.Collection.get=function(e){return Polymer._collections.get(e)||new Polymer.Collection(e)},Polymer.Collection.applySplices=function(e,t){var n=Polymer._collections.get(e);return n?n._applySplices(t):null},Polymer({is:"dom-repeat",extends:"template",_template:null,properties:{items:{type:Array},as:{type:String,value:"item"},indexAs:{type:String,value:"index"},sort:{type:Function,observer:"_sortChanged"},filter:{type:Function,observer:"_filterChanged"},observe:{type:String,observer:"_observeChanged"},delay:Number,renderedItemCount:{type:Number,notify:!0,readOnly:!0},initialCount:{type:Number,observer:"_initializeChunking"},targetFramerate:{type:Number,value:20},_targetFrameTime:{type:Number,computed:"_computeFrameTime(targetFramerate)"}},behaviors:[Polymer.Templatizer],observers:["_itemsChanged(items.*)"],created:function(){this._instances=[],this._pool=[],this._limit=1/0;var e=this;this._boundRenderChunk=function(){e._renderChunk()}},detached:function(){this.__isDetached=!0;for(var e=0;e=0;t--){var n=this._instances[t];n.isPlaceholder&&t=this._limit&&(n=this._downgradeInstance(t,n.__key__)),e[n.__key__]=t,n.isPlaceholder||n.__setProperty(this.indexAs,t,!0)}this._pool.length=0,this._setRenderedItemCount(this._instances.length),this.fire("dom-change"),this._tryRenderChunk()},_applyFullRefresh:function(){var e,t=this.collection;if(this._sortFn)e=t?t.getKeys():[];else{e=[];var n=this.items;if(n)for(var r=0;r=r;a--)this._detachAndRemoveInstance(a)},_numericSort:function(e,t){return e-t},_applySplicesUserSort:function(e){for(var t,n,r=this.collection,s={},i=0;i=0;i--){var c=a[i];void 0!==c&&this._detachAndRemoveInstance(c)}var h=this;if(l.length){this._filterFn&&(l=l.filter(function(e){return h._filterFn(r.getItem(e))})),l.sort(function(e,t){return h._sortFn(r.getItem(e),r.getItem(t))});var u=0;for(i=0;i>1,a=this._instances[o].__key__,l=this._sortFn(n.getItem(a),r);if(l<0)e=o+1;else{if(!(l>0)){i=o;break}s=o-1}}return i<0&&(i=s+1),this._insertPlaceholder(i,t),i},_applySplicesArrayOrder:function(e){for(var t,n=0;n=0?(e=this.as+"."+e.substring(n+1),i._notifyPath(e,t,!0)):i.__setProperty(this.as,t,!0))}},itemForElement:function(e){var t=this.modelForElement(e);return t&&t[this.as]},keyForElement:function(e){var t=this.modelForElement(e);return t&&t.__key__},indexForElement:function(e){var t=this.modelForElement(e);return t&&t[this.indexAs]}}),Polymer({is:"array-selector",_template:null,properties:{items:{type:Array,observer:"clearSelection"},multi:{type:Boolean,value:!1,observer:"clearSelection"},selected:{type:Object,notify:!0},selectedItem:{type:Object,notify:!0},toggle:{type:Boolean,value:!1}},clearSelection:function(){if(Array.isArray(this.selected))for(var e=0;e \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/frontend.html.gz b/homeassistant/components/frontend/www_static/frontend.html.gz index d44321775a8accf498908a5badefa53f3f58cca2..ac7a962c7130ce2104fd99f55edafb9f15b14ee8 100644 GIT binary patch delta 69225 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%0An6rAwi0MOwWZ0Q&Je4VA{|n9TTRE&2?H>vD=sZ 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
8a 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 delta 68943 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 Vrk`;cLLHC)ABS#a1=+y+2LO8$^ZNh* diff --git a/homeassistant/components/frontend/www_static/home-assistant-polymer b/homeassistant/components/frontend/www_static/home-assistant-polymer index 71278d7d6b0e1..db109f5dda043 160000 --- a/homeassistant/components/frontend/www_static/home-assistant-polymer +++ b/homeassistant/components/frontend/www_static/home-assistant-polymer @@ -1 +1 @@ -Subproject commit 71278d7d6b0e1a680b6336615fb6f4b5775f6d6c +Subproject commit db109f5dda043182a7e9647b161851e83be9b91e diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-event.html b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-event.html index 6babc87e2efb8..b0ed61ad6dfcb 100644 --- a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-event.html +++ b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-event.html @@ -1 +1 @@ -

\ No newline at end of file + \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-event.html.gz b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-event.html.gz index 09b6fecfc091602978733fc9912108ede41af8f7..6f30190703efd18965a1d592ec522cd803f04d40 100644 GIT binary patch delta 2596 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 R?+AYp{x6K1fYcZs0090-^D6)V diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-info.html b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-info.html index 5aca7e0c32a1e..83a2738e42234 100644 --- a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-info.html +++ b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-info.html @@ -1,2 +1,2 @@ \ No newline at end of file + clear: both;white-space:pre-wrap}
About


Home Assistant
[[hassVersion]]

Path to configuration.yaml: [[hassConfigDir]]

Developed by a bunch of awesome people.

Published under the MIT license
Source: server — frontend-ui — frontend-core

Built using Python 3, Polymer [[polymerVersion]], NuclearJS [[nuclearVersion]]
Icons by Google and MaterialDesignIcons.com.

The following errors have been logged this session:

[[errorLog]]
\ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-info.html.gz b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-info.html.gz index 36dd8becdf7423264a9cd481c874ad54cba22bc8..280bf68a9a11358a47d0d524cb763e2d5a0a5f03 100644 GIT binary patch delta 1301 zcmV+w1?u|23cm^>ABzYGyBzsf0t0AaEpTCOWo#{EWp*uTZf0*TXmo9C0IiWCJb!Ep z5I`os`|bz7J91iLrRLKTL^hvRfP$r^unus>f4%-O_=eA?QNNk!Y&D-|x(X_tH42!_ zX1o-E5jChFgGC_gToWFlGD;xKrw&&hSEs7UV8*4@bzroUD0MCCf{}Fx;q$oE4%dlD z?+UA%Itx;*w2i;W^ZYERT+leMfqw%9DaNuU0-?@=B_wwekMC9b{jrTUOm&S=?Q>fZ-0oGCU>+ggyYBdTdeM4Sy zVhwzqyur8)sT`oRISO-4;*sOQD--KJ*@dtK%!IuQjFpwJtG)^Z1Z%Yolz%R$#%T4L zHVat?s7-wGwYfh_w9SaV`)%%-(@JKn=TkoRM}%iX@>_zo4^L8Yf}}yD1aqYY#@1W! z_&=IZsxvqlf5wKtRDrNDOEi{e%Tgi)&WIFZVX~S!L&zf{D7pxM##u62HZ|DB7rV(ure9v?A5L|DVD&gFW4^pFmk?(DE=T1vz zvoNU2r^HGNIW-odad8xtx`Kc((xIp^l)k}aRWN7M8K*i5lxgJ8&3{F?Sab(?^6lw8 z{fDM5IP0}Ljte9X) zQ>P`H1dCN^UnQ^hg4hGspv%` z6|%3g(WFO+k(&EcHiu|x1T%#?^C4dq~Fny?tknKf_dA6NN@vuN2N!Z zwLw|Q_n=ncPzBOh-E?D#(mkTBH~r?%SL9>>?m6*NdFgx1Ywu_#h1LbB&zCy`M;FM@ zlZU=ubja@DM4cV7y{4Pf(oJ>Q(R5xt?IF<g;W(OSCr$g5?N0A((z z0`U!%Bh$;!kGG3q^>#uMrN~i&i`RZ9UgOF@{7d46+kZ~_J7!qCpo;-SJy{6VK>Ybh zJK5YdPXczP?|`{NOUE)vD40Q>aZWSOPvDUquPtC>Yi7fKHopKQHMp>!J_A$R^KNJK ze_~EIEX2Csi2JmCPD8mj&m}6*URxbA;V0qq@JrrKHiv!`#L2xt6e-R1hp@+MFVpam z;6~$i@@i;lKhtN=Y)G$?1zpmYkc&p)XgukdHZjcjD=o5ZfB2^O^zl#LgM4wf$n%cY zg*jll6G2F~PCeT7y3cPveBf{NVfR@u+9G5jZ$p1lBX2eyx9yl-Pran4QU4^5x+nZ! Lk`Wx8$qN7gW-^G} delta 1303 zcmV+y1?c*}3c(5@ABzYGIGXfV0t0AaEpTCOWo#{EWp*uTZf0*TXmo9C0Hu*4Jb$bK z0?6cd-~HfsM@~zu)O=ck$mY`uP_VQV)&b7=@7F&E-|_i0>NgXet>)8AS3#w-Mgf!A zjF%!Xq6QUYun1(GYr-Q`MhS%Z)ZxnG>Qpru%(%3=4vcmZrLJXNFtY9-d>)tD;W`oN zU14=oXF;l!w((bao}UGk3mOMDaDSj6#aPxvAk_$r^$ZWKm*#3RN2}z&eV4{ev(@twsT*Z^%nd ztbwnSHyF1el>?MEM`5l>JaRmEWn$eYyAYOunXq?(v9c0&)mMRlV6C=+(ticj7_DB@ zW+CeUwTVx@HTP$Uwi(fPzs)^!TFH#{e9FiEi12JkeoN5y;Ylh^kTi&tV6L>l*m~<7 z|3?!_bp|KnFWB&xDiAhiiN^A5SxSV!8IeM4ECfp{OgoLbQ=dpxTSfT>&?c5*MG@=cH?|F_Mg6j=aC7he_L248*^1Y4j+-b>d z76w)MlvrsYr^Z4wE{>v7R}c_JIutdA(l?l_3g&D&<5Wk1GL8JXxqm1Zi|znVzCXRE z|IpM0XT5f3oEChVg8JCbe<4zKz9IE1H#byy_eUSb?d>!&6y5x-z>=Y6#G1>ZvBEcQ zxDu6$S#R-Uw{t1&#%7bz&;b7>qiDdA^C-2DNpulsND}u`=+8un`i{>p2T;b66%#CJ z>a=7!XJQG?r(-}H1%F|e;t+k4DCtVFpn*cV!4lZ(m)A^5YHkNU?JM0_QYJeHvXEFd z2@Q)XN`z8cCy(Mj43LHm9i#WpK7IV_e^AnBRI3W?A$4v$C1pV)KZpOF`xoj|Ti7Yy zMI#lm#`!UQ;A**ChGvB&i9y?f&);_6?76p}JOS@>qd}zK(SJPd><)r?+k;431AIr2 zN13%jS;_aHR^gC7$*FF-2}J20kf`sPloPnde zVraiZUoSdjcVeQ>4%uGQC28qWy6k8=ub%dh=n0@_4!iT}r_#3h9$goFeofNPX{hR@ zKhJL4(X3qnOMd`rM#zHN1WW0d1Lvy|PYA!EKnF<_`>}{uufh`!H$u?g(0Ycws~j?-6=#q*fZ-sA#m7EZyGW3(|VpzSMkVGkRl;GmE--*|_G7$fkcz@xxlm0px7BA=y08vjCLNyS7 zdD2cc*UFQCok2TbuF%r4OcDxakY}9Jc=N+{WXEd@*w~ucuph%O07(rl?B~tE)b_mF zar{}#>4t?^_ZxAaw$EuO_vU3p1=?$?V($y+sWq8kAgV47l)I^9n&U;8Gofkw(Sq!6rVo+&3lk9?iP98 z(Yi1POm`v(>4K?8yI%MC?S~KijXvx?3r1UnEaYwIPio}N#^bgf(?hA3^fc;U-% \ No newline at end of file + \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-service.html.gz b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-service.html.gz index 0683f460f7d099e070aaa73944c9ba27c7658622..cdfed733269eebef744f0afb5f822096ffd39ee6 100644 GIT binary patch delta 2833 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 X*zHBk|5)hj|Kadod(5=e=pX<9*)@r; diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-state.html b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-state.html index 90a36bccc6a09..d6f91e28853d4 100644 --- a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-state.html +++ b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-state.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-state.html.gz b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-state.html.gz index e40d047db4865f75a114c0381d7c665c20f7e0f8..d397aee1a1ebc25940e04a298a1b4cc227bb760f 100644 GIT binary patch delta 2779 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 delta 2769 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 X2rM7gp*95JPvHLrO2dGe2_FCe=A2iq diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-template.html b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-template.html index b9aba112b638a..0b665c3b98392 100644 --- a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-template.html +++ b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-template.html @@ -1,2 +1,2 @@ -