From 3acd926d294983dce60680de77f0244c04a523fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=B8yer=20Iversen?= Date: Thu, 23 Mar 2017 21:58:22 +0100 Subject: [PATCH 001/116] Flux led update lib (#6763) * Update flux_led lib --- homeassistant/components/light/flux_led.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/light/flux_led.py b/homeassistant/components/light/flux_led.py index f0f719fd15fd28..ca18511c660e3b 100644 --- a/homeassistant/components/light/flux_led.py +++ b/homeassistant/components/light/flux_led.py @@ -18,7 +18,7 @@ PLATFORM_SCHEMA) import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['flux_led==0.15'] +REQUIREMENTS = ['flux_led==0.16'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index e766ed0c854ec3..0c41139c3f483a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -161,7 +161,7 @@ fitbit==0.2.3 fixerio==0.1.1 # homeassistant.components.light.flux_led -flux_led==0.15 +flux_led==0.16 # homeassistant.components.notify.free_mobile freesms==0.1.1 From 6c5989895a41d62948da7ca18d06f02696c51102 Mon Sep 17 00:00:00 2001 From: micw Date: Thu, 23 Mar 2017 22:55:07 +0100 Subject: [PATCH 002/116] Adding expire_after to mqtt sensor to expire outdated values (#6708) * Adding expire_after to mqtt sensor to expire outdated values * Extending test case * mqtt: refactoring expire_after to use timed events instead of polling; lint * refactor to reset unused trigger * Fix: handler must be set to None after execution or removal to avoid warning * Commenting out non-working test * Fix lint * Commit to trigger new build * Commit to trigger new build * Make testcase work * Undo unnecessary change * Remove default value, add extra check --- homeassistant/components/sensor/mqtt.py | 33 ++++++++++- tests/components/sensor/test_mqtt.py | 73 ++++++++++++++++++++++++- 2 files changed, 104 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/sensor/mqtt.py b/homeassistant/components/sensor/mqtt.py index 1e17e929b2cc7b..9fcb9298805bf4 100644 --- a/homeassistant/components/sensor/mqtt.py +++ b/homeassistant/components/sensor/mqtt.py @@ -6,6 +6,7 @@ """ import asyncio import logging +from datetime import timedelta import voluptuous as vol @@ -16,10 +17,13 @@ from homeassistant.helpers.entity import Entity import homeassistant.components.mqtt as mqtt import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.event import async_track_point_in_utc_time +from homeassistant.util import dt as dt_util _LOGGER = logging.getLogger(__name__) CONF_FORCE_UPDATE = 'force_update' +CONF_EXPIRE_AFTER = 'expire_after' DEFAULT_NAME = 'MQTT Sensor' DEFAULT_FORCE_UPDATE = False @@ -28,6 +32,7 @@ PLATFORM_SCHEMA = mqtt.MQTT_RO_PLATFORM_SCHEMA.extend({ vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string, + vol.Optional(CONF_EXPIRE_AFTER): cv.positive_int, vol.Optional(CONF_FORCE_UPDATE, default=DEFAULT_FORCE_UPDATE): cv.boolean, }) @@ -48,6 +53,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): config.get(CONF_QOS), config.get(CONF_UNIT_OF_MEASUREMENT), config.get(CONF_FORCE_UPDATE), + config.get(CONF_EXPIRE_AFTER), value_template, )]) @@ -56,7 +62,7 @@ class MqttSensor(Entity): """Representation of a sensor that can be updated using MQTT.""" def __init__(self, name, state_topic, qos, unit_of_measurement, - force_update, value_template): + force_update, expire_after, value_template): """Initialize the sensor.""" self._state = STATE_UNKNOWN self._name = name @@ -65,6 +71,8 @@ def __init__(self, name, state_topic, qos, unit_of_measurement, self._unit_of_measurement = unit_of_measurement self._force_update = force_update self._template = value_template + self._expire_after = expire_after + self._expiration_trigger = None def async_added_to_hass(self): """Subscribe mqtt events. @@ -74,6 +82,22 @@ def async_added_to_hass(self): @callback def message_received(topic, payload, qos): """A new MQTT message has been received.""" + # auto-expire enabled? + if self._expire_after is not None and self._expire_after > 0: + # Reset old trigger + if self._expiration_trigger: + self._expiration_trigger() + self._expiration_trigger = None + + # Set new trigger + expiration_at = ( + dt_util.utcnow() + timedelta(seconds=self._expire_after)) + + self._expiration_trigger = async_track_point_in_utc_time( + self.hass, + self.value_is_expired, + expiration_at) + if self._template is not None: payload = self._template.async_render_with_possible_json_value( payload, self._state) @@ -83,6 +107,13 @@ def message_received(topic, payload, qos): return mqtt.async_subscribe( self.hass, self._state_topic, message_received, self._qos) + @callback + def value_is_expired(self, *_): + """Triggered when value is expired.""" + self._expiration_trigger = None + self._state = STATE_UNKNOWN + self.hass.async_add_job(self.async_update_ha_state()) + @property def should_poll(self): """No polling needed.""" diff --git a/tests/components/sensor/test_mqtt.py b/tests/components/sensor/test_mqtt.py index 336c7fd57c561e..42136966e13150 100644 --- a/tests/components/sensor/test_mqtt.py +++ b/tests/components/sensor/test_mqtt.py @@ -1,12 +1,16 @@ """The tests for the MQTT sensor platform.""" import unittest +from datetime import timedelta, datetime +from unittest.mock import patch + import homeassistant.core as ha from homeassistant.setup import setup_component import homeassistant.components.sensor as sensor from homeassistant.const import EVENT_STATE_CHANGED -from tests.common import mock_mqtt_component, fire_mqtt_message +import homeassistant.util.dt as dt_util +from tests.common import mock_mqtt_component, fire_mqtt_message from tests.common import get_test_home_assistant, mock_component @@ -42,6 +46,69 @@ def test_setting_sensor_value_via_mqtt_message(self): self.assertEqual('fav unit', state.attributes.get('unit_of_measurement')) + @patch('homeassistant.core.dt_util.utcnow') + def test_setting_sensor_value_expires(self, mock_utcnow): + """Test the expiration of the value.""" + mock_component(self.hass, 'mqtt') + assert setup_component(self.hass, sensor.DOMAIN, { + sensor.DOMAIN: { + 'platform': 'mqtt', + 'name': 'test', + 'state_topic': 'test-topic', + 'unit_of_measurement': 'fav unit', + 'expire_after': '4', + 'force_update': True + } + }) + + state = self.hass.states.get('sensor.test') + self.assertEqual('unknown', state.state) + + now = datetime(2017, 1, 1, 1, tzinfo=dt_util.UTC) + mock_utcnow.return_value = now + fire_mqtt_message(self.hass, 'test-topic', '100') + self.hass.block_till_done() + + # Value was set correctly. + state = self.hass.states.get('sensor.test') + self.assertEqual('100', state.state) + + # Time jump +3s + now = now + timedelta(seconds=3) + self._send_time_changed(now) + self.hass.block_till_done() + + # Value is not yet expired + state = self.hass.states.get('sensor.test') + self.assertEqual('100', state.state) + + # Next message resets timer + mock_utcnow.return_value = now + fire_mqtt_message(self.hass, 'test-topic', '101') + self.hass.block_till_done() + + # Value was updated correctly. + state = self.hass.states.get('sensor.test') + self.assertEqual('101', state.state) + + # Time jump +3s + now = now + timedelta(seconds=3) + self._send_time_changed(now) + self.hass.block_till_done() + + # Value is not yet expired + state = self.hass.states.get('sensor.test') + self.assertEqual('101', state.state) + + # Time jump +2s + now = now + timedelta(seconds=2) + self._send_time_changed(now) + self.hass.block_till_done() + + # Value is expired now + state = self.hass.states.get('sensor.test') + self.assertEqual('unknown', state.state) + def test_setting_sensor_value_via_mqtt_json_message(self): """Test the setting of the value via MQTT with JSON playload.""" mock_component(self.hass, 'mqtt') @@ -117,3 +184,7 @@ def callback(event): fire_mqtt_message(self.hass, 'test-topic', '100') self.hass.block_till_done() self.assertEqual(2, len(events)) + + def _send_time_changed(self, now): + """Send a time changed event.""" + self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: now}) From 5dfdb9e48184cd9fa6e7dded307658b65dff367e Mon Sep 17 00:00:00 2001 From: Tim Soderstrom Date: Thu, 23 Mar 2017 22:48:31 -0500 Subject: [PATCH 003/116] New indexes for states and recording_runs tables (#6688) * New indexes for states table * Added recorder_runs indexes * Created a new function for compound indexes. A new function was created because it makes it a little cleaner when creating a single-field index since one doesn't have to create a list. This is mostly when creating the name of the index so with a bit more logic it's possible to combine it into one function. Given how often migration changes are run, I thought that code bloat was probably a worthy trade-off for now. * Adjusted indexes, POC for ref indexes by name. * Corrected lint errors * Fixed pydocstyle error * Moved create_index function outside apply_update * Moved to single line (just barely) --- homeassistant/components/recorder/__init__.py | 1 + .../components/recorder/migration.py | 39 ++++++++++++------- homeassistant/components/recorder/models.py | 11 ++++-- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/homeassistant/components/recorder/__init__.py b/homeassistant/components/recorder/__init__.py index 8ac610f1bcfab2..0ed5c3126b71c0 100644 --- a/homeassistant/components/recorder/__init__.py +++ b/homeassistant/components/recorder/__init__.py @@ -166,6 +166,7 @@ def run(self): migration.migrate_schema(self) self._setup_run() connected = True + _LOGGER.debug("Connected to recorder database") except Exception as err: # pylint: disable=broad-except _LOGGER.error("Error during connection setup: %s (retrying " "in %s seconds)", err, CONNECT_RETRY_WAIT) diff --git a/homeassistant/components/recorder/migration.py b/homeassistant/components/recorder/migration.py index 09c5e9837c3418..0fac32bdec75b3 100644 --- a/homeassistant/components/recorder/migration.py +++ b/homeassistant/components/recorder/migration.py @@ -36,25 +36,34 @@ def migrate_schema(instance): _LOGGER.info("Upgrade to version %s done", new_version) -def _apply_update(engine, new_version): - """Perform operations to bring schema up to date.""" +def _create_index(engine, table_name, index_name): + """Create an index for the specified table. + + The index name should match the name given for the index + within the table definition described in the models + """ from sqlalchemy import Table from . import models + table = Table(table_name, models.Base.metadata) + _LOGGER.debug("Looking up index for table %s", table_name) + # Look up the index object by name from the table is the the models + index = next(idx for idx in table.indexes if idx.name == index_name) + _LOGGER.debug("Creating %s index", index_name) + index.create(engine) + _LOGGER.debug("Finished creating %s", index_name) + + +def _apply_update(engine, new_version): + """Perform operations to bring schema up to date.""" if new_version == 1: - def create_index(table_name, column_name): - """Create an index for the specified table and column.""" - table = Table(table_name, models.Base.metadata) - name = "_".join(("ix", table_name, column_name)) - # Look up the index object that was created from the models - index = next(idx for idx in table.indexes if idx.name == name) - _LOGGER.debug("Creating index for table %s column %s", - table_name, column_name) - index.create(engine) - _LOGGER.debug("Index creation done for table %s column %s", - table_name, column_name) - - create_index("events", "time_fired") + _create_index(engine, "events", "ix_events_time_fired") + elif new_version == 2: + # Create compound start/end index for recorder_runs + _create_index(engine, "recorder_runs", "ix_recorder_runs_start_end") + # Create indexes for states + _create_index(engine, "states", "ix_states_last_updated") + _create_index(engine, "states", "ix_states_entity_id_created") else: raise ValueError("No schema migration defined for version {}" .format(new_version)) diff --git a/homeassistant/components/recorder/models.py b/homeassistant/components/recorder/models.py index 4bc044a51bd15d..ce42ba187c2312 100644 --- a/homeassistant/components/recorder/models.py +++ b/homeassistant/components/recorder/models.py @@ -16,7 +16,7 @@ # pylint: disable=invalid-name Base = declarative_base() -SCHEMA_VERSION = 1 +SCHEMA_VERSION = 2 _LOGGER = logging.getLogger(__name__) @@ -66,13 +66,16 @@ class States(Base): # type: ignore attributes = Column(Text) event_id = Column(Integer, ForeignKey('events.event_id')) last_changed = Column(DateTime(timezone=True), default=datetime.utcnow) - last_updated = Column(DateTime(timezone=True), default=datetime.utcnow) + last_updated = Column(DateTime(timezone=True), default=datetime.utcnow, + index=True) created = Column(DateTime(timezone=True), default=datetime.utcnow) __table_args__ = (Index('states__state_changes', 'last_changed', 'last_updated', 'entity_id'), Index('states__significant_changes', - 'domain', 'last_updated', 'entity_id'), ) + 'domain', 'last_updated', 'entity_id'), + Index('ix_states_entity_id_created', + 'entity_id', 'created'),) @staticmethod def from_event(event): @@ -124,6 +127,8 @@ class RecorderRuns(Base): # type: ignore closed_incorrect = Column(Boolean, default=False) created = Column(DateTime(timezone=True), default=datetime.utcnow) + __table_args__ = (Index('ix_recorder_runs_start_end', 'start', 'end'),) + def entity_ids(self, point_in_time=None): """Return the entity ids that existed in this run. From efbd66bca1e21e7e96ff42d6d2b22ac59ef66e8b Mon Sep 17 00:00:00 2001 From: Adam Mills Date: Thu, 23 Mar 2017 23:56:39 -0400 Subject: [PATCH 004/116] Fix flaky template test (#6768) --- tests/helpers/test_template.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/helpers/test_template.py b/tests/helpers/test_template.py index 18656acac51196..b6951172c64dce 100644 --- a/tests/helpers/test_template.py +++ b/tests/helpers/test_template.py @@ -151,13 +151,14 @@ def test_strptime(self): def test_timestamp_custom(self): """Test the timestamps to custom filter.""" + now = dt_util.utcnow() tests = [ (None, None, None, 'None'), (1469119144, None, True, '2016-07-21 16:39:04'), (1469119144, '%Y', True, '2016'), (1469119144, 'invalid', True, 'invalid'), - (dt_util.as_timestamp(dt_util.utcnow()), None, False, - dt_util.now().strftime('%Y-%m-%d %H:%M:%S')) + (dt_util.as_timestamp(now), None, False, + now.strftime('%Y-%m-%d %H:%M:%S')) ] for inp, fmt, local, out in tests: @@ -202,11 +203,12 @@ def test_max(self): def test_timestamp_utc(self): """Test the timestamps to local filter.""" + now = dt_util.utcnow() tests = { None: 'None', 1469119144: '2016-07-21 16:39:04', - dt_util.as_timestamp(dt_util.utcnow()): - dt_util.now().strftime('%Y-%m-%d %H:%M:%S') + dt_util.as_timestamp(now): + now.strftime('%Y-%m-%d %H:%M:%S') } for inp, out in tests.items(): From 22613d8e2e1b0231e30f707b469284614d5c79a9 Mon Sep 17 00:00:00 2001 From: Adam Mills Date: Thu, 23 Mar 2017 23:57:15 -0400 Subject: [PATCH 005/116] Repair zwave sensor coverage (#6764) --- tests/components/sensor/test_zwave.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/components/sensor/test_zwave.py b/tests/components/sensor/test_zwave.py index 8affe9d489ce9e..e3792c27d77d26 100644 --- a/tests/components/sensor/test_zwave.py +++ b/tests/components/sensor/test_zwave.py @@ -37,6 +37,7 @@ def test_get_device_detects_multilevelsensor(mock_openzwave): device = zwave.get_device(node=node, values=values, node_config={}) assert isinstance(device, zwave.ZWaveMultilevelSensor) + assert device.force_update def test_get_device_detects_multilevel_meter(mock_openzwave): @@ -107,3 +108,18 @@ def test_multilevelsensor_value_changed_integer(mock_openzwave): value.data = 6 value_changed(value) assert device.state == 6 + + +def test_alarm_sensor_value_changed(mock_openzwave): + """Test value changed for Z-Wave sensor.""" + node = MockNode(command_classes=[const.COMMAND_CLASS_ALARM, + const.COMMAND_CLASS_SENSOR_ALARM]) + value = MockValue(data=12.34, node=node, units='%') + values = MockEntityValues(primary=value) + + device = zwave.get_device(node=node, values=values, node_config={}) + assert device.state == 12.34 + assert device.unit_of_measurement == '%' + value.data = 45.67 + value_changed(value) + assert device.state == 45.67 From 9f2f0c556655ab2e58f9e8c1c6c3e9c3b7f2fc1a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 23 Mar 2017 23:33:49 -0700 Subject: [PATCH 006/116] Version bump to 0.42.0.dev0 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 6c36dc4bda28f9..bb882ca4ea92c2 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ # coding: utf-8 """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 -MINOR_VERSION = 41 +MINOR_VERSION = 42 PATCH_VERSION = '0.dev0' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) From 82c599a7494931eb5e50863797ae764db168d856 Mon Sep 17 00:00:00 2001 From: John Arild Berentsen Date: Fri, 24 Mar 2017 07:50:36 +0100 Subject: [PATCH 007/116] current temp could be none (#6759) --- homeassistant/components/climate/zwave.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/climate/zwave.py b/homeassistant/components/climate/zwave.py index 4aaea884816e11..74fadb8c5fd02e 100755 --- a/homeassistant/components/climate/zwave.py +++ b/homeassistant/components/climate/zwave.py @@ -112,8 +112,9 @@ def update_properties(self): _LOGGER.debug("Setpoint is 0, setting default to " "current_temperature=%s", self._current_temperature) - self._target_temperature = ( - round((float(self._current_temperature)), 1)) + if self._current_temperature is not None: + self._target_temperature = ( + round((float(self._current_temperature)), 1)) else: self._target_temperature = round( (float(self.values.primary.data)), 1) From ee6c9ab6a93f0e4f4d651af3319bbb115984eef3 Mon Sep 17 00:00:00 2001 From: John Arild Berentsen Date: Fri, 24 Mar 2017 07:53:59 +0100 Subject: [PATCH 008/116] Typing error and update test (#6757) --- homeassistant/components/lock/zwave.py | 8 ++++---- tests/components/lock/test_zwave.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/lock/zwave.py b/homeassistant/components/lock/zwave.py index 1a3b9bd662c0d4..676775aace5ec8 100644 --- a/homeassistant/components/lock/zwave.py +++ b/homeassistant/components/lock/zwave.py @@ -53,8 +53,8 @@ '9': 'Deadbolt Jammed', '18': 'Locked with Keypad by user ', '19': 'Unlocked with Keypad by user ', - '21': 'Manually Locked by ', - '22': 'Manually Unlocked by Key or Inside thumb turn', + '21': 'Manually Locked ', + '22': 'Manually Unlocked ', '24': 'Locked by RF', '25': 'Unlocked by RF', '27': 'Auto re-lock', @@ -69,8 +69,8 @@ } MANUAL_LOCK_ALARM_LEVEL = { - '1': 'Key Cylinder or Inside thumb turn', - '2': 'Touch function (lock and leave)' + '1': 'by Key Cylinder or Inside thumb turn', + '2': 'by Touch function (lock and leave)' } TAMPER_ALARM_LEVEL = { diff --git a/tests/components/lock/test_zwave.py b/tests/components/lock/test_zwave.py index ff7dd15c4c4d7d..33cc2e61483c9e 100644 --- a/tests/components/lock/test_zwave.py +++ b/tests/components/lock/test_zwave.py @@ -115,7 +115,7 @@ def test_lock_alarm_type(mock_openzwave): values.alarm_type.data = 21 value_changed(values.alarm_type) assert device.device_state_attributes[zwave.ATTR_LOCK_STATUS] == \ - 'Manually Locked by None' + 'Manually Locked None' values.alarm_type.data = 18 value_changed(values.alarm_type) From 06d3889e1bcdf0d6cdb32ee7bb85a9bff6947798 Mon Sep 17 00:00:00 2001 From: geekofweek Date: Fri, 24 Mar 2017 15:13:14 -0500 Subject: [PATCH 009/116] Wink Aros Fixes (#6726) Wink Aros only supports 3 Fan Modes: Low Medium High Fan Mode had a Typo and wasn't represented in the UI --- homeassistant/components/climate/wink.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/climate/wink.py b/homeassistant/components/climate/wink.py index f2c2551d371a08..df29768b3ffaca 100644 --- a/homeassistant/components/climate/wink.py +++ b/homeassistant/components/climate/wink.py @@ -19,7 +19,6 @@ STATE_AUX = 'aux' STATE_ECO = 'eco' STATE_FAN = 'fan' -SPEED_LOWEST = 'lowest' SPEED_LOW = 'low' SPEED_MEDIUM = 'medium' SPEED_HIGH = 'high' @@ -400,7 +399,7 @@ def operation_list(self): op_list.append(STATE_COOL) if 'auto_eco' in modes: op_list.append(STATE_ECO) - if 'fan_eco' in modes: + if 'fan_only' in modes: op_list.append(STATE_FAN) return op_list @@ -439,9 +438,7 @@ def target_temperature_high(self): def current_fan_mode(self): """Return the current fan mode.""" speed = self.wink.current_fan_speed() - if speed <= 0.3 and speed >= 0.0: - return SPEED_LOWEST - elif speed <= 0.5 and speed > 0.3: + if speed <= 0.4 and speed > 0.3: return SPEED_LOW elif speed <= 0.8 and speed > 0.5: return SPEED_MEDIUM @@ -453,14 +450,12 @@ def current_fan_mode(self): @property def fan_list(self): """List of available fan modes.""" - return [SPEED_LOWEST, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH] + return [SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH] def set_fan_mode(self, mode): """Set fan speed.""" - if mode == SPEED_LOWEST: - speed = 0.3 - elif mode == SPEED_LOW: - speed = 0.5 + if mode == SPEED_LOW: + speed = 0.4 elif mode == SPEED_MEDIUM: speed = 0.8 elif mode == SPEED_HIGH: From 1be2706de3a2e55e3df50741b27638eb9964af24 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 24 Mar 2017 21:42:00 +0100 Subject: [PATCH 010/116] Upgrade pydroid-ipcam to 0.7 (#6772) --- homeassistant/components/android_ip_webcam.py | 38 +++++++++---------- requirements_all.txt | 2 +- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/homeassistant/components/android_ip_webcam.py b/homeassistant/components/android_ip_webcam.py index e2929d159daa7c..7699242e47842d 100644 --- a/homeassistant/components/android_ip_webcam.py +++ b/homeassistant/components/android_ip_webcam.py @@ -26,17 +26,24 @@ from homeassistant.components.camera.mjpeg import ( CONF_MJPEG_URL, CONF_STILL_IMAGE_URL) -DOMAIN = 'android_ip_webcam' -REQUIREMENTS = ["pydroid-ipcam==0.6"] +REQUIREMENTS = ['pydroid-ipcam==0.7'] _LOGGER = logging.getLogger(__name__) -SCAN_INTERVAL = timedelta(seconds=10) - -DATA_IP_WEBCAM = 'android_ip_webcam' +ATTR_AUD_CONNS = 'Audio Connections' ATTR_HOST = 'host' ATTR_VID_CONNS = 'Video Connections' -ATTR_AUD_CONNS = 'Audio Connections' + +CONF_MOTION_SENSOR = 'motion_sensor' + +DATA_IP_WEBCAM = 'android_ip_webcam' +DEFAULT_NAME = 'IP Webcam' +DEFAULT_PORT = 8080 +DEFAULT_TIMEOUT = 10 +DOMAIN = 'android_ip_webcam' + +SCAN_INTERVAL = timedelta(seconds=10) +SIGNAL_UPDATE_DATA = 'android_ip_webcam_update' KEY_MAP = { 'audio_connections': 'Audio Connections', @@ -123,15 +130,6 @@ 'battery_voltage', 'light', 'motion', 'pressure', 'proximity', 'sound', 'video_connections'] -SIGNAL_UPDATE_DATA = 'android_ip_webcam_update' - -CONF_MOTION_SENSOR = 'motion_sensor' - -DEFAULT_NAME = 'IP Webcam' -DEFAULT_PORT = 8080 -DEFAULT_TIMEOUT = 10 - - CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.All(cv.ensure_list, [vol.Schema({ vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, @@ -153,7 +151,7 @@ @asyncio.coroutine def async_setup(hass, config): - """Setup the IP Webcam component.""" + """Set up the IP Webcam component.""" from pydroid_ipcam import PyDroidIPCam webcams = hass.data[DATA_IP_WEBCAM] = {} @@ -161,7 +159,7 @@ def async_setup(hass, config): @asyncio.coroutine def async_setup_ipcamera(cam_config): - """Setup a ip camera.""" + """Set up an IP camera.""" host = cam_config[CONF_HOST] username = cam_config.get(CONF_USERNAME) password = cam_config.get(CONF_PASSWORD) @@ -171,7 +169,7 @@ def async_setup_ipcamera(cam_config): sensors = cam_config[CONF_SENSORS] motion = cam_config[CONF_MOTION_SENSOR] - # init ip webcam + # Init ip webcam cam = PyDroidIPCam( hass.loop, websession, host, cam_config[CONF_PORT], username=username, password=password, @@ -192,7 +190,7 @@ def async_setup_ipcamera(cam_config): @asyncio.coroutine def async_update_data(now): - """Update data from ipcam in SCAN_INTERVAL.""" + """Update data from IP camera in SCAN_INTERVAL.""" yield from cam.update() async_dispatcher_send(hass, SIGNAL_UPDATE_DATA, host) @@ -201,7 +199,7 @@ def async_update_data(now): yield from async_update_data(None) - # load platforms + # Load platforms webcams[host] = cam mjpeg_camera = { diff --git a/requirements_all.txt b/requirements_all.txt index 0c41139c3f483a..b6d4034b91984f 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -490,7 +490,7 @@ pycmus==0.1.0 pydispatcher==2.0.5 # homeassistant.components.android_ip_webcam -pydroid-ipcam==0.6 +pydroid-ipcam==0.7 # homeassistant.components.sensor.ebox pyebox==0.1.0 From 7ae814357a0c52b0ff7332b45529cecd6f5967cd Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 24 Mar 2017 21:43:48 +0100 Subject: [PATCH 011/116] Upgrade psutil to 5.2.1 (#6771) --- homeassistant/components/sensor/systemmonitor.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/sensor/systemmonitor.py b/homeassistant/components/sensor/systemmonitor.py index fbdb302b84b673..4b402d32792ff8 100755 --- a/homeassistant/components/sensor/systemmonitor.py +++ b/homeassistant/components/sensor/systemmonitor.py @@ -16,7 +16,7 @@ import homeassistant.helpers.config_validation as cv import homeassistant.util.dt as dt_util -REQUIREMENTS = ['psutil==5.2.0'] +REQUIREMENTS = ['psutil==5.2.1'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index b6d4034b91984f..7dea8509fa1092 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -435,7 +435,7 @@ pmsensor==0.4 proliphix==0.4.1 # homeassistant.components.sensor.systemmonitor -psutil==5.2.0 +psutil==5.2.1 # homeassistant.components.wink pubnubsub-handler==1.0.1 From 8d606f8d16731a02e7a9ba58f8810d261af2b7d7 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 24 Mar 2017 21:44:04 +0100 Subject: [PATCH 012/116] Upgrade sleekxmpp to 1.3.2 (#6773) --- homeassistant/components/notify/xmpp.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/notify/xmpp.py b/homeassistant/components/notify/xmpp.py index e0228e967a9ac1..ee358ed069ce7c 100644 --- a/homeassistant/components/notify/xmpp.py +++ b/homeassistant/components/notify/xmpp.py @@ -13,7 +13,7 @@ ATTR_TITLE, ATTR_TITLE_DEFAULT, PLATFORM_SCHEMA, BaseNotificationService) from homeassistant.const import CONF_PASSWORD, CONF_SENDER, CONF_RECIPIENT -REQUIREMENTS = ['sleekxmpp==1.3.1', +REQUIREMENTS = ['sleekxmpp==1.3.2', 'dnspython3==1.15.0', 'pyasn1==0.2.3', 'pyasn1-modules==0.0.8'] diff --git a/requirements_all.txt b/requirements_all.txt index 7dea8509fa1092..bc697d6a657a3a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -692,7 +692,7 @@ simplisafe-python==1.0.2 slacker==0.9.42 # homeassistant.components.notify.xmpp -sleekxmpp==1.3.1 +sleekxmpp==1.3.2 # homeassistant.components.sleepiq sleepyq==0.6 From cffc6c7beaf3c48d619ef295ebe888e60691ca35 Mon Sep 17 00:00:00 2001 From: Adam Mills Date: Fri, 24 Mar 2017 18:31:46 -0400 Subject: [PATCH 013/116] Tests for zwave workaround detection (#6761) * Tests for zwave workaround detection * Remove unused code * Revert "Remove unused code" This reverts commit e06cce0abecc233dab3488dc4194b2d296eee002. * Tests for empty manufacturer ID --- .coveragerc | 1 - tests/components/zwave/test_workaround.py | 40 +++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/components/zwave/test_workaround.py diff --git a/.coveragerc b/.coveragerc index d57aa96b40d1f2..91cb5ef640493f 100644 --- a/.coveragerc +++ b/.coveragerc @@ -436,7 +436,6 @@ omit = homeassistant/components/zeroconf.py homeassistant/components/zwave/__init__.py homeassistant/components/zwave/util.py - homeassistant/components/zwave/workaround.py [report] diff --git a/tests/components/zwave/test_workaround.py b/tests/components/zwave/test_workaround.py new file mode 100644 index 00000000000000..2ef54ae066b0e3 --- /dev/null +++ b/tests/components/zwave/test_workaround.py @@ -0,0 +1,40 @@ +"""Test Z-Wave workarounds.""" +from homeassistant.components.zwave import const, workaround +from tests.mock.zwave import MockNode, MockValue + + +def test_get_device_no_component_mapping(): + """Test that None is returned.""" + node = MockNode(manufacturer_id=' ') + value = MockValue(data=0, node=node) + assert workaround.get_device_component_mapping(value) is None + + +def test_get_device_component_mapping(): + """Test that component is returned.""" + node = MockNode(manufacturer_id='010f', product_type='0b00') + value = MockValue(data=0, node=node, + command_class=const.COMMAND_CLASS_SENSOR_ALARM) + assert workaround.get_device_component_mapping(value) == 'binary_sensor' + + +def test_get_device_no_mapping(): + """Test that no device mapping is returned.""" + node = MockNode(manufacturer_id=' ') + value = MockValue(data=0, node=node) + assert workaround.get_device_mapping(value) is None + + +def test_get_device_mapping_mt(): + """Test that device mapping mt is returned.""" + node = MockNode(manufacturer_id='0047', product_type='5a52') + value = MockValue(data=0, node=node) + assert workaround.get_device_mapping(value) == 'workaround_no_position' + + +def test_get_device_mapping_mtii(): + """Test that device mapping mtii is returned.""" + node = MockNode(manufacturer_id='013c', product_type='0002', + product_id='0002') + value = MockValue(data=0, node=node, index=0) + assert workaround.get_device_mapping(value) == 'trigger_no_off_event' From f4e9466394e1cb94a9173c915e9137ead174d8f7 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Fri, 24 Mar 2017 23:52:14 +0100 Subject: [PATCH 014/116] Bugfix automation fire on bootstrap (#6770) * Bugfix automation fire on bootstrap * Add test & fix bug * fix lint --- .../components/automation/__init__.py | 21 ++++++++++- tests/components/automation/test_init.py | 37 ++++++++++++++++++- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index 96d5b0499d2d50..451a0c538b8a7f 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -12,10 +12,11 @@ import voluptuous as vol from homeassistant.setup import async_prepare_setup_platform +from homeassistant.core import CoreState from homeassistant import config as conf_util from homeassistant.const import ( ATTR_ENTITY_ID, CONF_PLATFORM, STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, - SERVICE_TOGGLE, SERVICE_RELOAD) + SERVICE_TOGGLE, SERVICE_RELOAD, EVENT_HOMEASSISTANT_START) from homeassistant.components import logbook from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import extract_domain_configs, script, condition @@ -266,15 +267,31 @@ def is_on(self) -> bool: @asyncio.coroutine def async_added_to_hass(self) -> None: """Startup with initial state or previous state.""" + enable_automation = False + state = yield from async_get_last_state(self.hass, self.entity_id) if state is None: if self._initial_state: - yield from self.async_enable() + enable_automation = True else: self._last_triggered = state.attributes.get('last_triggered') if state.state == STATE_ON: + enable_automation = True + + # HomeAssistant is on bootstrap + if enable_automation and self.hass.state == CoreState.not_running: + @asyncio.coroutine + def async_enable_automation(event): + """Start automation on startup.""" yield from self.async_enable() + self.hass.bus.async_listen_once( + EVENT_HOMEASSISTANT_START, async_enable_automation) + + # HomeAssistant is running + elif enable_automation: + yield from self.async_enable() + @asyncio.coroutine def async_turn_on(self, **kwargs) -> None: """Turn the entity on and update the state.""" diff --git a/tests/components/automation/test_init.py b/tests/components/automation/test_init.py index 271aa58f7fb7d0..629ee8e29759b5 100644 --- a/tests/components/automation/test_init.py +++ b/tests/components/automation/test_init.py @@ -4,10 +4,11 @@ import unittest from unittest.mock import patch -from homeassistant.core import State +from homeassistant.core import State, CoreState from homeassistant.setup import setup_component, async_setup_component import homeassistant.components.automation as automation -from homeassistant.const import ATTR_ENTITY_ID, STATE_ON, STATE_OFF +from homeassistant.const import ( + ATTR_ENTITY_ID, STATE_ON, STATE_OFF, EVENT_HOMEASSISTANT_START) from homeassistant.exceptions import HomeAssistantError import homeassistant.util.dt as dt_util @@ -568,6 +569,38 @@ def test_reload_config_handles_load_fails(self): self.hass.block_till_done() assert len(self.calls) == 2 + def test_automation_not_trigger_on_bootstrap(self): + """Test if automation is not trigger on bootstrap.""" + self.hass.state = CoreState.not_running + + assert setup_component(self.hass, automation.DOMAIN, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'event', + 'event_type': 'test_event', + }, + 'action': { + 'service': 'test.automation', + 'entity_id': 'hello.world' + } + } + }) + + self.hass.bus.fire('test_event') + self.hass.block_till_done() + + assert len(self.calls) == 0 + + self.hass.bus.fire(EVENT_HOMEASSISTANT_START) + self.hass.block_till_done() + self.hass.states = CoreState.running + + self.hass.bus.fire('test_event') + self.hass.block_till_done() + + assert len(self.calls) == 1 + assert ['hello.world'] == self.calls[0].data.get(ATTR_ENTITY_ID) + @asyncio.coroutine def test_automation_restore_state(hass): From 447048701c313ea83c2d9dbafa9bc2704efa5700 Mon Sep 17 00:00:00 2001 From: Daniel Perna Date: Sat, 25 Mar 2017 09:48:05 +0100 Subject: [PATCH 015/116] Homematic Fixes (#6769) * Added missing operational modes for thermostats * Added attributes * Updated requirements * Bumped dependency --- homeassistant/components/climate/homematic.py | 4 ++++ homeassistant/components/homematic.py | 9 +++++++-- requirements_all.txt | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/climate/homematic.py b/homeassistant/components/climate/homematic.py index 66b50cd507d9f8..7385eeac98aea3 100644 --- a/homeassistant/components/climate/homematic.py +++ b/homeassistant/components/climate/homematic.py @@ -16,11 +16,15 @@ STATE_MANUAL = "manual" STATE_BOOST = "boost" +STATE_COMFORT = "comfort" +STATE_LOWERING = "lowering" HM_STATE_MAP = { "AUTO_MODE": STATE_AUTO, "MANU_MODE": STATE_MANUAL, "BOOST_MODE": STATE_BOOST, + "COMFORT_MODE": STATE_COMFORT, + "LOWERING_MODE": STATE_LOWERING } HM_TEMP_MAP = [ diff --git a/homeassistant/components/homematic.py b/homeassistant/components/homematic.py index e9bcfa80f6c67e..e40cab05b29693 100644 --- a/homeassistant/components/homematic.py +++ b/homeassistant/components/homematic.py @@ -22,7 +22,7 @@ from homeassistant.config import load_yaml_config_file DOMAIN = 'homematic' -REQUIREMENTS = ["pyhomematic==0.1.22"] +REQUIREMENTS = ["pyhomematic==0.1.24"] SCAN_INTERVAL_HUB = timedelta(seconds=300) SCAN_INTERVAL_VARIABLES = timedelta(seconds=30) @@ -82,7 +82,12 @@ 'RSSI_DEVICE': ['rssi', {}], 'VALVE_STATE': ['valve', {}], 'BATTERY_STATE': ['battery', {}], - 'CONTROL_MODE': ['mode', {0: 'Auto', 1: 'Manual', 2: 'Away', 3: 'Boost'}], + 'CONTROL_MODE': ['mode', {0: 'Auto', + 1: 'Manual', + 2: 'Away', + 3: 'Boost', + 4: 'Comfort', + 5: 'Lowering'}], 'POWER': ['power', {}], 'CURRENT': ['current', {}], 'VOLTAGE': ['voltage', {}], diff --git a/requirements_all.txt b/requirements_all.txt index bc697d6a657a3a..67c67f53b57f34 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -517,7 +517,7 @@ pyharmony==1.0.12 pyhik==0.1.0 # homeassistant.components.homematic -pyhomematic==0.1.22 +pyhomematic==0.1.24 # homeassistant.components.sensor.hydroquebec pyhydroquebec==1.0.0 From f8005153c95b2ffda072e95f1613c3210b8d9616 Mon Sep 17 00:00:00 2001 From: William Scanlon Date: Sat, 25 Mar 2017 10:28:16 -0400 Subject: [PATCH 016/116] Fix wink siren (#6775) * Fix siren/switch attributes and update python-wink * Updated requirements_all.txt --- homeassistant/components/switch/wink.py | 8 ++++---- homeassistant/components/wink.py | 2 +- requirements_all.txt | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/switch/wink.py b/homeassistant/components/switch/wink.py index 1f534f7290f778..5d5b477be99a75 100644 --- a/homeassistant/components/switch/wink.py +++ b/homeassistant/components/switch/wink.py @@ -56,10 +56,10 @@ def turn_off(self): @property def device_state_attributes(self): """Return the state attributes.""" + attributes = super(WinkToggleDevice, self).device_state_attributes try: event = self.wink.last_event() + attributes["last_event"] = event except AttributeError: - event = None - return { - 'last_event': event - } + pass + return attributes diff --git a/homeassistant/components/wink.py b/homeassistant/components/wink.py index 67cfcc7074d1d3..92cd7baa65ef6c 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==1.2.1', 'pubnubsub-handler==1.0.1'] +REQUIREMENTS = ['python-wink==1.2.3', 'pubnubsub-handler==1.0.1'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 67c67f53b57f34..ef14d3641367a6 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -626,7 +626,7 @@ python-twitch==1.3.0 python-vlc==1.1.2 # homeassistant.components.wink -python-wink==1.2.1 +python-wink==1.2.3 # homeassistant.components.device_tracker.trackr pytrackr==0.0.5 From c817ab08b76399cd902cf7c3781d6f00ba98cc73 Mon Sep 17 00:00:00 2001 From: Nick Sabinske Date: Sat, 25 Mar 2017 10:32:57 -0400 Subject: [PATCH 017/116] Fix bridge-led support in limitlessled.py (#6776) Addressing #6382 . Feedback from github & forums is the bridge_led feature never worked and defining the bridge LED as another group+bulb type is the right way to do this in the limitlessled component. --- homeassistant/components/light/limitlessled.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py index 23d0716e0b4e7f..c2769ab66386ea 100644 --- a/homeassistant/components/light/limitlessled.py +++ b/homeassistant/components/light/limitlessled.py @@ -25,14 +25,13 @@ CONF_GROUPS = 'groups' CONF_NUMBER = 'number' CONF_VERSION = 'version' -CONF_BRIDGE_LED = 'bridge_led' DEFAULT_LED_TYPE = 'rgbw' DEFAULT_PORT = 5987 DEFAULT_TRANSITION = 0 DEFAULT_VERSION = 6 -LED_TYPE = ['rgbw', 'rgbww', 'white'] +LED_TYPE = ['rgbw', 'rgbww', 'white', 'bridge-led'] RGB_BOUNDARY = 40 @@ -54,7 +53,6 @@ vol.Optional(CONF_VERSION, default=DEFAULT_VERSION): cv.positive_int, vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, - vol.Optional(CONF_BRIDGE_LED, default=False): cv.boolean, vol.Required(CONF_GROUPS): vol.All(cv.ensure_list, [ { vol.Required(CONF_NAME): cv.string, @@ -116,8 +114,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): group_conf.get(CONF_NAME), group_conf.get(CONF_TYPE, DEFAULT_LED_TYPE)) lights.append(LimitlessLEDGroup.factory(group)) - if bridge_conf.get(CONF_BRIDGE_LED) and bridge.bridge_led is not None: - lights.append(LimitlessLEDGroup.factory(bridge.bridge_led)) add_devices(lights) From 5a7155fc4a1336d6d91f00f409da62687da98034 Mon Sep 17 00:00:00 2001 From: John Arild Berentsen Date: Sat, 25 Mar 2017 19:39:03 +0100 Subject: [PATCH 018/116] Wrong info in discovery schema (#6779) --- homeassistant/components/zwave/discovery_schemas.py | 1 - 1 file changed, 1 deletion(-) diff --git a/homeassistant/components/zwave/discovery_schemas.py b/homeassistant/components/zwave/discovery_schemas.py index 7753d58651d2e8..12a8c8c4375276 100644 --- a/homeassistant/components/zwave/discovery_schemas.py +++ b/homeassistant/components/zwave/discovery_schemas.py @@ -164,7 +164,6 @@ 'v2btze_advanced': { const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_CONFIGURATION], const.DISC_INDEX: [12], - const.DISC_LABEL: 'Access Control', const.DISC_OPTIONAL: True, }})}, {const.DISC_COMPONENT: 'sensor', From f5d4f853ba8eea966052eb98e54d48040a2e385c Mon Sep 17 00:00:00 2001 From: Teemu R Date: Sun, 26 Mar 2017 10:55:17 +0200 Subject: [PATCH 019/116] switch.tplink: upgrade to the newest upstream release which adds support for plugs using the newer communication protocol (#6790) --- 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 f740a5f16141c2..b4c1df3db739e2 100644 --- a/homeassistant/components/switch/tplink.py +++ b/homeassistant/components/switch/tplink.py @@ -14,7 +14,7 @@ from homeassistant.const import (CONF_HOST, CONF_NAME) import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['pyHS100==0.2.3'] +REQUIREMENTS = ['pyHS100==0.2.4.1'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index ef14d3641367a6..b06d6545d0098e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -456,7 +456,7 @@ py-cpuinfo==0.2.7 pyCEC==0.4.13 # homeassistant.components.switch.tplink -pyHS100==0.2.3 +pyHS100==0.2.4.1 # homeassistant.components.rfxtrx pyRFXtrx==0.17.0 From 22b28d85db1a9ae753a777e3bbdff3c6aaf60470 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sun, 26 Mar 2017 15:48:28 +0200 Subject: [PATCH 020/116] Add switch to MQTT discovery (#6733) --- homeassistant/components/mqtt/discovery.py | 5 +++-- homeassistant/components/switch/mqtt.py | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/mqtt/discovery.py b/homeassistant/components/mqtt/discovery.py index 86cce757449c0a..c3ff0f9dce55b2 100644 --- a/homeassistant/components/mqtt/discovery.py +++ b/homeassistant/components/mqtt/discovery.py @@ -19,12 +19,13 @@ TOPIC_MATCHER = re.compile( r'(?P\w+)/(?P\w+)/(?P\w+)/config') -SUPPORTED_COMPONENTS = ['binary_sensor', 'light', 'sensor'] +SUPPORTED_COMPONENTS = ['binary_sensor', 'light', 'sensor', 'switch'] ALLOWED_PLATFORMS = { 'binary_sensor': ['mqtt'], 'light': ['mqtt', 'mqtt_json', 'mqtt_template'], - 'sensor': ['mqtt'] + 'sensor': ['mqtt'], + 'switch': ['mqtt'], } diff --git a/homeassistant/components/switch/mqtt.py b/homeassistant/components/switch/mqtt.py index d94815a1d2e0b9..391df2ad67e5ad 100644 --- a/homeassistant/components/switch/mqtt.py +++ b/homeassistant/components/switch/mqtt.py @@ -38,7 +38,10 @@ @asyncio.coroutine def async_setup_platform(hass, config, async_add_devices, discovery_info=None): - """Setup the MQTT switch.""" + """Set up the MQTT switch.""" + if discovery_info is not None: + config = PLATFORM_SCHEMA(discovery_info) + value_template = config.get(CONF_VALUE_TEMPLATE) if value_template is not None: value_template.hass = hass From 5d5547cdb6dd91924e719c0b5e61e2b89e48e14b Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sun, 26 Mar 2017 15:50:40 +0200 Subject: [PATCH 021/116] Update docstrings (#6795) * Add link to docs and remove comments which are obvious * Update docstrings * Repleace conf details with link to docs * Add link to docs * Update docstrings * Update import * Update ordering * Update ordering * Update docstring * Update ordering * Update ordering --- .../components/binary_sensor/blink.py | 2 +- .../components/binary_sensor/workday.py | 32 ++---- homeassistant/components/blink.py | 26 +++-- homeassistant/components/climate/tado.py | 104 +++++++++--------- homeassistant/components/light/piglow.py | 10 +- .../components/light/yeelightsunflower.py | 16 ++- .../media_player/frontier_silicon.py | 6 +- .../components/media_player/volumio.py | 55 +++------ homeassistant/components/notify/ciscospark.py | 6 +- .../components/sensor/api_streams.py | 10 +- homeassistant/components/sensor/blink.py | 7 +- homeassistant/components/sensor/ring.py | 4 +- homeassistant/components/tado.py | 44 ++++---- homeassistant/components/twilio.py | 14 ++- 14 files changed, 152 insertions(+), 184 deletions(-) diff --git a/homeassistant/components/binary_sensor/blink.py b/homeassistant/components/binary_sensor/blink.py index 8d84ffb9c90ee9..1e95d4d466b9b2 100644 --- a/homeassistant/components/binary_sensor/blink.py +++ b/homeassistant/components/binary_sensor/blink.py @@ -11,7 +11,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): - """Setup the blink binary sensors.""" + """Set up the blink binary sensors.""" if discovery_info is None: return diff --git a/homeassistant/components/binary_sensor/workday.py b/homeassistant/components/binary_sensor/workday.py index 1b53738a25f31c..c2590925df7f13 100644 --- a/homeassistant/components/binary_sensor/workday.py +++ b/homeassistant/components/binary_sensor/workday.py @@ -1,4 +1,9 @@ -"""Sensor to indicate whether the current day is a workday.""" +""" +Sensor to indicate whether the current day is a workday. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/binary_sensor.workday/ +""" import asyncio import logging import datetime @@ -6,8 +11,8 @@ import voluptuous as vol from homeassistant.components.sensor import PLATFORM_SCHEMA -from homeassistant.const import (STATE_ON, STATE_OFF, STATE_UNKNOWN, - CONF_NAME, WEEKDAYS) +from homeassistant.const import ( + STATE_ON, STATE_OFF, STATE_UNKNOWN, CONF_NAME, WEEKDAYS) import homeassistant.util.dt as dt_util from homeassistant.helpers.entity import Entity import homeassistant.helpers.config_validation as cv @@ -48,29 +53,18 @@ def setup_platform(hass, config, add_devices, discovery_info=None): - """Setup the Workday sensor.""" + """Set up the Workday sensor.""" import holidays - # Get the Sensor name from the config sensor_name = config.get(CONF_NAME) - - # Get the country code from the config country = config.get(CONF_COUNTRY) - - # Get the province from the config province = config.get(CONF_PROVINCE) - - # Get the list of workdays from the config workdays = config.get(CONF_WORKDAYS) - - # Get the list of excludes from the config excludes = config.get(CONF_EXCLUDES) - # Instantiate the holidays module for the current year year = datetime.datetime.now().year obj_holidays = getattr(holidays, country)(years=year) - # Also apply the provience, if available for the configured country if province: if province not in obj_holidays.PROVINCES: _LOGGER.error('There is no province/state %s in country %s', @@ -81,14 +75,12 @@ def setup_platform(hass, config, add_devices, discovery_info=None): obj_holidays = getattr(holidays, country)(prov=province, years=year) - # Output found public holidays via the debug channel _LOGGER.debug("Found the following holidays for your configuration:") for date, name in sorted(obj_holidays.items()): _LOGGER.debug("%s %s", date, name) - # Add ourselves as device - add_devices([IsWorkdaySensor(obj_holidays, workdays, - excludes, sensor_name)], True) + add_devices([IsWorkdaySensor( + obj_holidays, workdays, excludes, sensor_name)], True) def day_to_string(day): @@ -122,7 +114,6 @@ def state(self): def is_include(self, day, now): """Check if given day is in the includes list.""" - # Check includes if day in self._workdays: return True elif 'holiday' in self._workdays and now in self._obj_holidays: @@ -132,7 +123,6 @@ def is_include(self, day, now): def is_exclude(self, day, now): """Check if given day is in the excludes list.""" - # Check excludes if day in self._excludes: return True elif 'holiday' in self._excludes and now in self._obj_holidays: diff --git a/homeassistant/components/blink.py b/homeassistant/components/blink.py index 2a079716b6820f..4ae5007d665c4e 100644 --- a/homeassistant/components/blink.py +++ b/homeassistant/components/blink.py @@ -5,17 +5,19 @@ https://home-assistant.io/components/blink/ """ import logging + import voluptuous as vol + import homeassistant.helpers.config_validation as cv -from homeassistant.const import (CONF_USERNAME, - CONF_PASSWORD, - ATTR_FRIENDLY_NAME, - ATTR_ARMED) +from homeassistant.const import ( + CONF_USERNAME, CONF_PASSWORD, ATTR_FRIENDLY_NAME, ATTR_ARMED) from homeassistant.helpers import discovery + +REQUIREMENTS = ['blinkpy==0.5.2'] + _LOGGER = logging.getLogger(__name__) DOMAIN = 'blink' -REQUIREMENTS = ['blinkpy==0.5.2'] CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ @@ -50,7 +52,7 @@ def __init__(self, config_info): def setup(hass, config): - """Setup Blink System.""" + """Set up Blink System.""" hass.data[DOMAIN] = BlinkSystem(config) discovery.load_platform(hass, 'camera', DOMAIN, {}, config) discovery.load_platform(hass, 'sensor', DOMAIN, {}, config) @@ -77,11 +79,11 @@ def arm_system(call): hass.data[DOMAIN].blink.arm = value hass.data[DOMAIN].blink.refresh() - hass.services.register(DOMAIN, 'snap_picture', snap_picture, - schema=SNAP_PICTURE_SCHEMA) - hass.services.register(DOMAIN, 'arm_camera', arm_camera, - schema=ARM_CAMERA_SCHEMA) - hass.services.register(DOMAIN, 'arm_system', arm_system, - schema=ARM_SYSTEM_SCHEMA) + hass.services.register( + DOMAIN, 'snap_picture', snap_picture, schema=SNAP_PICTURE_SCHEMA) + hass.services.register( + DOMAIN, 'arm_camera', arm_camera, schema=ARM_CAMERA_SCHEMA) + hass.services.register( + DOMAIN, 'arm_system', arm_system, schema=ARM_SYSTEM_SCHEMA) return True diff --git a/homeassistant/components/climate/tado.py b/homeassistant/components/climate/tado.py index e5242f88162f45..734b13dc7e7c39 100644 --- a/homeassistant/components/climate/tado.py +++ b/homeassistant/components/climate/tado.py @@ -1,40 +1,40 @@ -"""tado component to create a climate device for each zone.""" +""" +Tado component to create a climate device for each zone. +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/climate.tado/ +""" import logging from homeassistant.const import TEMP_CELSIUS +from homeassistant.components.climate import ClimateDevice +from homeassistant.const import ATTR_TEMPERATURE +from homeassistant.components.tado import DATA_TADO -from homeassistant.components.climate import ( - ClimateDevice) -from homeassistant.const import ( - ATTR_TEMPERATURE) -from homeassistant.components.tado import ( - DATA_TADO) +_LOGGER = logging.getLogger(__name__) -CONST_MODE_SMART_SCHEDULE = "SMART_SCHEDULE" # Default mytado mode -CONST_MODE_OFF = "OFF" # Switch off heating in a zone +CONST_MODE_SMART_SCHEDULE = 'SMART_SCHEDULE' # Default mytado mode +CONST_MODE_OFF = 'OFF' # Switch off heating in a zone # When we change the temperature setting, we need an overlay mode # wait until tado changes the mode automatic -CONST_OVERLAY_TADO_MODE = "TADO_MODE" +CONST_OVERLAY_TADO_MODE = 'TADO_MODE' # the user has change the temperature or mode manually -CONST_OVERLAY_MANUAL = "MANUAL" +CONST_OVERLAY_MANUAL = 'MANUAL' # the temperature will be reset after a timespan -CONST_OVERLAY_TIMER = "TIMER" +CONST_OVERLAY_TIMER = 'TIMER' OPERATION_LIST = { - CONST_OVERLAY_MANUAL: "Manual", - CONST_OVERLAY_TIMER: "Timer", - CONST_OVERLAY_TADO_MODE: "Tado mode", - CONST_MODE_SMART_SCHEDULE: "Smart schedule", - CONST_MODE_OFF: "Off"} - -_LOGGER = logging.getLogger(__name__) + CONST_OVERLAY_MANUAL: 'Manual', + CONST_OVERLAY_TIMER: 'Timer', + CONST_OVERLAY_TADO_MODE: 'Tado mode', + CONST_MODE_SMART_SCHEDULE: 'Smart schedule', + CONST_MODE_OFF: 'Off', +} def setup_platform(hass, config, add_devices, discovery_info=None): - """Setup the climate platform.""" - # get the PyTado object from the hub component + """Set up the Tado climate platform.""" tado = hass.data[DATA_TADO] try: @@ -45,10 +45,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): climate_devices = [] for zone in zones: - climate_devices.append(create_climate_device(tado, hass, - zone, - zone['name'], - zone['id'])) + climate_devices.append(create_climate_device( + tado, hass, zone, zone['name'], zone['id'])) if len(climate_devices) > 0: add_devices(climate_devices, True) @@ -58,13 +56,13 @@ def setup_platform(hass, config, add_devices, discovery_info=None): def create_climate_device(tado, hass, zone, name, zone_id): - """Create a climate device.""" + """Create a Tado climate device.""" capabilities = tado.get_capabilities(zone_id) unit = TEMP_CELSIUS - min_temp = float(capabilities["temperatures"]["celsius"]["min"]) - max_temp = float(capabilities["temperatures"]["celsius"]["max"]) - ac_mode = capabilities["type"] != "HEATING" + min_temp = float(capabilities['temperatures']['celsius']['min']) + max_temp = float(capabilities['temperatures']['celsius']['max']) + ac_mode = capabilities['type'] != 'HEATING' data_id = 'zone {} {}'.format(name, zone_id) device = TadoClimate(tado, @@ -74,10 +72,10 @@ def create_climate_device(tado, hass, zone, name, zone_id): ac_mode) tado.add_sensor(data_id, { - "id": zone_id, - "zone": zone, - "name": name, - "climate": device + 'id': zone_id, + 'zone': zone, + 'name': name, + 'climate': device }) return device @@ -89,7 +87,7 @@ class TadoClimate(ClimateDevice): def __init__(self, store, zone_name, zone_id, data_id, min_temp, max_temp, ac_mode, tolerance=0.3): - """Initialization of TadoClimate device.""" + """Initialization of Tado climate device.""" self._store = store self._data_id = data_id @@ -202,8 +200,7 @@ def update(self): data = self._store.get_data(self._data_id) if data is None: - _LOGGER.debug('Recieved no data for zone %s', - self.zone_name) + _LOGGER.debug("Recieved no data for zone %s", self.zone_name) return if 'sensorDataPoints' in data: @@ -232,11 +229,11 @@ def update(self): if 'tadoMode' in data: mode = data['tadoMode'] - self._is_away = mode == "AWAY" + self._is_away = mode == 'AWAY' if 'setting' in data: power = data['setting']['power'] - if power == "OFF": + if power == 'OFF': self._current_operation = CONST_MODE_OFF self._device_is_active = False else: @@ -249,48 +246,47 @@ def update(self): overlay = False termination = "" - # if you set mode manualy to off, there will be an overlay - # and a termination, but we want to see the mode "OFF" + # If you set mode manualy to off, there will be an overlay + # and a termination, but we want to see the mode "OFF" if overlay and self._device_is_active: - # there is an overlay the device is on + # There is an overlay the device is on self._overlay_mode = termination self._current_operation = termination else: - # there is no overlay, the mode will always be - # "SMART_SCHEDULE" + # There is no overlay, the mode will always be + # "SMART_SCHEDULE" self._overlay_mode = CONST_MODE_SMART_SCHEDULE self._current_operation = CONST_MODE_SMART_SCHEDULE def _control_heating(self): """Send new target temperature to mytado.""" - if not self._active and None not in (self._cur_temp, - self._target_temp): + if not self._active and None not in ( + self._cur_temp, self._target_temp): self._active = True - _LOGGER.info('Obtained current and target temperature. ' - 'tado thermostat active.') + _LOGGER.info("Obtained current and target temperature. " + "Tado thermostat active") if not self._active or self._current_operation == self._overlay_mode: return if self._current_operation == CONST_MODE_SMART_SCHEDULE: - _LOGGER.info('Switching mytado.com to SCHEDULE (default) ' - 'for zone %s', self.zone_name) + _LOGGER.info("Switching mytado.com to SCHEDULE (default) " + "for zone %s", self.zone_name) self._store.reset_zone_overlay(self.zone_id) self._overlay_mode = self._current_operation return if self._current_operation == CONST_MODE_OFF: - _LOGGER.info('Switching mytado.com to OFF for zone %s', + _LOGGER.info("Switching mytado.com to OFF for zone %s", self.zone_name) self._store.set_zone_overlay(self.zone_id, CONST_OVERLAY_MANUAL) self._overlay_mode = self._current_operation return - _LOGGER.info('Switching mytado.com to %s mode for zone %s', + _LOGGER.info("Switching mytado.com to %s mode for zone %s", self._current_operation, self.zone_name) - self._store.set_zone_overlay(self.zone_id, - self._current_operation, - self._target_temp) + self._store.set_zone_overlay( + self.zone_id, self._current_operation, self._target_temp) self._overlay_mode = self._current_operation diff --git a/homeassistant/components/light/piglow.py b/homeassistant/components/light/piglow.py index d4e9c9ed106efa..afdda745721094 100644 --- a/homeassistant/components/light/piglow.py +++ b/homeassistant/components/light/piglow.py @@ -9,15 +9,12 @@ import voluptuous as vol -# Import the device class from the component that you want to support +import homeassistant.helpers.config_validation as cv from homeassistant.components.light import ( - ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, - ATTR_RGB_COLOR, SUPPORT_RGB_COLOR, + ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, ATTR_RGB_COLOR, SUPPORT_RGB_COLOR, Light, PLATFORM_SCHEMA) from homeassistant.const import CONF_NAME -import homeassistant.helpers.config_validation as cv -# Home Assistant depends on 3rd party packages for API specific code. REQUIREMENTS = ['piglow==1.2.4'] _LOGGER = logging.getLogger(__name__) @@ -32,7 +29,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): - """Setup the Piglow Light platform.""" + """Set up the Piglow Light platform.""" import piglow if subprocess.getoutput("i2cdetect -q -y 1 | grep -o 54") != '54': @@ -41,7 +38,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): name = config.get(CONF_NAME) - # Add devices add_devices([PiglowLight(piglow, name)]) diff --git a/homeassistant/components/light/yeelightsunflower.py b/homeassistant/components/light/yeelightsunflower.py index 204803e9991f63..70df2136716014 100644 --- a/homeassistant/components/light/yeelightsunflower.py +++ b/homeassistant/components/light/yeelightsunflower.py @@ -5,21 +5,19 @@ https://home-assistant.io/components/light.yeelightsunflower/ """ import logging + import voluptuous as vol -from homeassistant.components.light import (Light, - ATTR_RGB_COLOR, SUPPORT_RGB_COLOR, - ATTR_BRIGHTNESS, - SUPPORT_BRIGHTNESS, - PLATFORM_SCHEMA) -from homeassistant.const import CONF_HOST import homeassistant.helpers.config_validation as cv +from homeassistant.components.light import ( + Light, ATTR_RGB_COLOR, SUPPORT_RGB_COLOR, ATTR_BRIGHTNESS, + SUPPORT_BRIGHTNESS, PLATFORM_SCHEMA) +from homeassistant.const import CONF_HOST REQUIREMENTS = ['yeelightsunflower==0.0.8'] _LOGGER = logging.getLogger(__name__) - SUPPORT_YEELIGHT_SUNFLOWER = (SUPPORT_BRIGHTNESS | SUPPORT_RGB_COLOR) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ @@ -35,7 +33,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): hub = yeelightsunflower.Hub(host) if not hub.available: - _LOGGER.error('Could not connect to Yeelight Sunflower hub') + _LOGGER.error("Could not connect to Yeelight Sunflower hub") return False add_devices(SunflowerBulb(light) for light in hub.get_lights()) @@ -55,7 +53,7 @@ def __init__(self, light): @property def name(self): """Return the display name of this light.""" - return "sunflower_{}".format(self._light.zid) + return 'sunflower_{}'.format(self._light.zid) @property def available(self): diff --git a/homeassistant/components/media_player/frontier_silicon.py b/homeassistant/components/media_player/frontier_silicon.py index 386a489b646e03..8bd36b4535cdce 100644 --- a/homeassistant/components/media_player/frontier_silicon.py +++ b/homeassistant/components/media_player/frontier_silicon.py @@ -42,7 +42,7 @@ # pylint: disable=unused-argument def setup_platform(hass, config, add_devices, discovery_info=None): - """Setup the Frontier Silicon platform.""" + """Set up the Frontier Silicon platform.""" import requests if discovery_info is not None: @@ -59,10 +59,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None): add_devices( [FSAPIDevice(DEVICE_URL.format(host, port), password)], update_before_add=True) - _LOGGER.debug('FSAPI device %s:%s -> %s', host, port, password) + _LOGGER.debug("FSAPI device %s:%s -> %s", host, port, password) return True except requests.exceptions.RequestException: - _LOGGER.error('Could not add the FSAPI device at %s:%s -> %s', + _LOGGER.error("Could not add the FSAPI device at %s:%s -> %s", host, port, password) return False diff --git a/homeassistant/components/media_player/volumio.py b/homeassistant/components/media_player/volumio.py index 46345f9c7f3d03..bcd4ebd0c11ddb 100755 --- a/homeassistant/components/media_player/volumio.py +++ b/homeassistant/components/media_player/volumio.py @@ -1,49 +1,31 @@ """ Volumio Platform. -The volumio platform allows you to control a Volumio media player -from Home Assistant. - - -To add a Volumio player to your installation, add the following to -your configuration.yaml file. - -# Example configuration.yaml entry -media_player: - - platform: volumio - name: 'Volumio Home Audio' - host: homeaudio.local - port: 3000 -Configuration variables: - -- **name** (*Optional*): Name of the device -- **host** (*Required*): IP address or hostname of the device -- **port** (*Required*): Port number of Volumio service +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/media_player.volumio/ """ import logging import asyncio import aiohttp + import voluptuous as vol from homeassistant.components.media_player import ( - SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, - SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK, - SUPPORT_PLAY_MEDIA, SUPPORT_VOLUME_MUTE, - SUPPORT_VOLUME_SET, SUPPORT_STOP, - SUPPORT_PLAY, MediaPlayerDevice, - PLATFORM_SCHEMA, MEDIA_TYPE_MUSIC) + SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK, + SUPPORT_PLAY_MEDIA, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, SUPPORT_STOP, + SUPPORT_PLAY, MediaPlayerDevice, PLATFORM_SCHEMA, MEDIA_TYPE_MUSIC) from homeassistant.const import ( STATE_PLAYING, STATE_PAUSED, STATE_IDLE, CONF_HOST, CONF_PORT, CONF_NAME) import homeassistant.helpers.config_validation as cv from homeassistant.helpers.aiohttp_client import async_get_clientsession - _CONFIGURING = {} _LOGGER = logging.getLogger(__name__) DEFAULT_HOST = 'localhost' DEFAULT_NAME = 'Volumio' DEFAULT_PORT = 3000 + TIMEOUT = 10 SUPPORT_VOLUMIO = SUPPORT_PAUSE | SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE | \ @@ -60,10 +42,11 @@ @asyncio.coroutine def async_setup_platform(hass, config, async_add_devices, discovery_info=None): - """Setup the Volumio platform.""" + """Set up the Volumio platform.""" host = config.get(CONF_HOST) port = config.get(CONF_PORT) name = config.get(CONF_NAME) + async_add_devices([Volumio(name, host, port, hass)]) @@ -75,7 +58,7 @@ def __init__(self, name, host, port, hass): self.host = host self.port = port self.hass = hass - self._url = host + ":" + str(port) + self._url = '{}:{}'.format(host, str(port)) self._name = name self._state = {} self.async_update() @@ -84,8 +67,7 @@ def __init__(self, name, host, port, hass): @asyncio.coroutine def send_volumio_msg(self, method, params=None): """Send message.""" - url = "http://{}:{}/api/v1/{}/".format( - self.host, self.port, method) + url = "http://{}:{}/api/v1/{}/".format(self.host, self.port, method) response = None _LOGGER.debug("URL: %s params: %s", url, params) @@ -218,9 +200,8 @@ def async_media_pause(self): def async_set_volume_level(self, volume): """Send volume_up command to media player.""" - return self.send_volumio_msg('commands', - params={'cmd': 'volume', - 'volume': int(volume * 100)}) + return self.send_volumio_msg( + 'commands', params={'cmd': 'volume', 'volume': int(volume * 100)}) def async_mute_volume(self, mute): """Send mute command to media player.""" @@ -228,10 +209,8 @@ def async_mute_volume(self, mute): if mute: # mute is implemenhted as 0 volume, do save last volume level self._lastvol = self._state['volume'] - return self.send_volumio_msg('commands', - params={'cmd': 'volume', - 'volume': mutecmd}) + return self.send_volumio_msg( + 'commands', params={'cmd': 'volume', 'volume': mutecmd}) else: - return self.send_volumio_msg('commands', - params={'cmd': 'volume', - 'volume': self._lastvol}) + return self.send_volumio_msg( + 'commands', params={'cmd': 'volume', 'volume': self._lastvol}) diff --git a/homeassistant/components/notify/ciscospark.py b/homeassistant/components/notify/ciscospark.py index 3a4ef1384d9c90..ee6115c3f790ce 100644 --- a/homeassistant/components/notify/ciscospark.py +++ b/homeassistant/components/notify/ciscospark.py @@ -5,17 +5,19 @@ https://home-assistant.io/components/notify.ciscospark/ """ import logging + import voluptuous as vol + from homeassistant.components.notify import ( PLATFORM_SCHEMA, BaseNotificationService, ATTR_TITLE) from homeassistant.const import (CONF_TOKEN) import homeassistant.helpers.config_validation as cv -CONF_ROOMID = "roomid" +REQUIREMENTS = ['ciscosparkapi==0.4.2'] _LOGGER = logging.getLogger(__name__) -REQUIREMENTS = ['ciscosparkapi==0.4.2'] +CONF_ROOMID = 'roomid' PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_TOKEN): cv.string, diff --git a/homeassistant/components/sensor/api_streams.py b/homeassistant/components/sensor/api_streams.py index e1d6c7751962a1..c15ca41d2bf825 100644 --- a/homeassistant/components/sensor/api_streams.py +++ b/homeassistant/components/sensor/api_streams.py @@ -1,4 +1,9 @@ -"""Entity to track connections to stream API.""" +""" +Entity to track connections to stream API. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.api_stream/ +""" import asyncio import logging @@ -6,7 +11,6 @@ from homeassistant.core import callback from homeassistant.helpers.entity import Entity - NAME_WS = 'homeassistant.components.websocket_api' NAME_STREAM = 'homeassistant.components.api' @@ -46,7 +50,7 @@ def handle(self, record): @asyncio.coroutine def async_setup_platform(hass, config, async_add_devices, discovery_info=None): - """Set up the logger for filters.""" + """Set up the API stream platform.""" entity = APICount() handler = StreamHandler(entity) diff --git a/homeassistant/components/sensor/blink.py b/homeassistant/components/sensor/blink.py index 738f8cb27688da..e069dfa00f7d10 100644 --- a/homeassistant/components/sensor/blink.py +++ b/homeassistant/components/sensor/blink.py @@ -10,18 +10,19 @@ from homeassistant.const import TEMP_FAHRENHEIT from homeassistant.helpers.entity import Entity +_LOGGER = logging.getLogger(__name__) + DEPENDENCIES = ['blink'] + SENSOR_TYPES = { 'temperature': ['Temperature', TEMP_FAHRENHEIT], 'battery': ['Battery', ''], 'notifications': ['Notifications', ''] } -_LOGGER = logging.getLogger(__name__) - def setup_platform(hass, config, add_devices, discovery_info=None): - """Setup a Blink sensor.""" + """Set up a Blink sensor.""" if discovery_info is None: return diff --git a/homeassistant/components/sensor/ring.py b/homeassistant/components/sensor/ring.py index ab64557dd2f127..7c342a75f13460 100644 --- a/homeassistant/components/sensor/ring.py +++ b/homeassistant/components/sensor/ring.py @@ -8,15 +8,15 @@ from datetime import timedelta import voluptuous as vol -import homeassistant.helpers.config_validation as cv +import homeassistant.loader as loader +import homeassistant.helpers.config_validation as cv from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( CONF_ENTITY_NAMESPACE, CONF_MONITORED_CONDITIONS, CONF_SCAN_INTERVAL, CONF_USERNAME, CONF_PASSWORD, STATE_UNKNOWN, ATTR_ATTRIBUTION) from homeassistant.helpers.entity import Entity -import homeassistant.loader as loader from requests.exceptions import HTTPError, ConnectTimeout diff --git a/homeassistant/components/tado.py b/homeassistant/components/tado.py index b0aae8b3f4abef..ffb4da61fedc37 100644 --- a/homeassistant/components/tado.py +++ b/homeassistant/components/tado.py @@ -1,30 +1,30 @@ """ -Support for the (unofficial) tado api. +Support for the (unofficial) Tado api. For more details about this component, please refer to the documentation at https://home-assistant.io/components/tado/ """ - import logging import urllib - from datetime import timedelta + import voluptuous as vol from homeassistant.helpers.discovery import load_platform from homeassistant.helpers import config_validation as cv -from homeassistant.const import ( - CONF_USERNAME, CONF_PASSWORD) +from homeassistant.const import CONF_USERNAME, CONF_PASSWORD from homeassistant.util import Throttle +REQUIREMENTS = ['https://github.com/wmalgadey/PyTado/archive/' + '0.1.10.zip#' + 'PyTado==0.1.10'] _LOGGER = logging.getLogger(__name__) +DATA_TADO = 'tado_data' DOMAIN = 'tado' -REQUIREMENTS = ['https://github.com/wmalgadey/PyTado/archive/' - '0.1.10.zip#' - 'PyTado==0.1.10'] +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=10) TADO_COMPONENTS = [ 'sensor', 'climate' @@ -37,13 +37,9 @@ }) }, extra=vol.ALLOW_EXTRA) -MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=10) - -DATA_TADO = 'tado_data' - def setup(hass, config): - """Your controller/hub specific code.""" + """Set up of the Tado component.""" username = config[DOMAIN][CONF_USERNAME] password = config[DOMAIN][CONF_PASSWORD] @@ -64,7 +60,7 @@ def setup(hass, config): class TadoDataStore: - """An object to store the tado data.""" + """An object to store the Tado data.""" def __init__(self, tado): """Initialize Tado data store.""" @@ -80,19 +76,19 @@ def update(self): data = None try: - if "zone" in sensor: - _LOGGER.info("querying mytado.com for zone %s %s", - sensor["id"], sensor["name"]) - data = self.tado.getState(sensor["id"]) - - if "device" in sensor: - _LOGGER.info("querying mytado.com for device %s %s", - sensor["id"], sensor["name"]) + if 'zone' in sensor: + _LOGGER.info("Querying mytado.com for zone %s %s", + sensor['id'], sensor['name']) + data = self.tado.getState(sensor['id']) + + if 'device' in sensor: + _LOGGER.info("Querying mytado.com for device %s %s", + sensor['id'], sensor['name']) data = self.tado.getDevices()[0] except RuntimeError: _LOGGER.error("Unable to connect to myTado. %s %s", - sensor["id"], sensor["id"]) + sensor['id'], sensor['id']) self.data[data_id] = data @@ -103,7 +99,7 @@ def add_sensor(self, data_id, sensor): def get_data(self, data_id): """Get the cached data.""" - data = {"error": "no data"} + data = {'error': 'no data'} if data_id in self.data: data = self.data[data_id] diff --git a/homeassistant/components/twilio.py b/homeassistant/components/twilio.py index e4b36d41e145d3..9f32a44ce7edb2 100644 --- a/homeassistant/components/twilio.py +++ b/homeassistant/components/twilio.py @@ -5,21 +5,25 @@ https://home-assistant.io/components/twilio/ """ import voluptuous as vol + import homeassistant.helpers.config_validation as cv from homeassistant.core import callback from homeassistant.components.http import HomeAssistantView -DEPENDENCIES = ['http'] REQUIREMENTS = ['twilio==5.7.0'] DOMAIN = 'twilio' -DATA_TWILIO = DOMAIN + API_PATH = '/api/{}'.format(DOMAIN) -RECEIVED_DATA = '{}_data_received'.format(DOMAIN) CONF_ACCOUNT_SID = 'account_sid' CONF_AUTH_TOKEN = 'auth_token' +DATA_TWILIO = DOMAIN +DEPENDENCIES = ['http'] + +RECEIVED_DATA = '{}_data_received'.format(DOMAIN) + CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ vol.Required(CONF_ACCOUNT_SID): cv.string, @@ -32,8 +36,8 @@ def setup(hass, config): """Set up the Twilio component.""" from twilio.rest import TwilioRestClient conf = config[DOMAIN] - hass.data[DATA_TWILIO] = TwilioRestClient(conf.get(CONF_ACCOUNT_SID), - conf.get(CONF_AUTH_TOKEN)) + hass.data[DATA_TWILIO] = TwilioRestClient( + conf.get(CONF_ACCOUNT_SID), conf.get(CONF_AUTH_TOKEN)) hass.http.register_view(TwilioReceiveDataView()) return True From 7782e7e948ae6bdf322169fe0c8acaa143f7fcdc Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sun, 26 Mar 2017 15:52:59 +0200 Subject: [PATCH 022/116] Add optional unit of measurement (#6796) --- homeassistant/components/sensor/random.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/sensor/random.py b/homeassistant/components/sensor/random.py index 21251ab5f3b015..0b0761d70761a5 100644 --- a/homeassistant/components/sensor/random.py +++ b/homeassistant/components/sensor/random.py @@ -11,7 +11,8 @@ import homeassistant.helpers.config_validation as cv from homeassistant.components.sensor import PLATFORM_SCHEMA -from homeassistant.const import (CONF_NAME, CONF_MINIMUM, CONF_MAXIMUM) +from homeassistant.const import ( + CONF_NAME, CONF_MINIMUM, CONF_MAXIMUM, CONF_UNIT_OF_MEASUREMENT) from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) @@ -26,6 +27,7 @@ vol.Optional(CONF_MAXIMUM, default=DEFAULT_MAX): cv.positive_int, vol.Optional(CONF_MINIMUM, default=DEFAULT_MIN): cv.positive_int, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string, }) @@ -35,19 +37,21 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): name = config.get(CONF_NAME) minimum = config.get(CONF_MINIMUM) maximum = config.get(CONF_MAXIMUM) + unit = config.get(CONF_UNIT_OF_MEASUREMENT) - async_add_devices([RandomSensor(name, minimum, maximum)], True) + async_add_devices([RandomSensor(name, minimum, maximum, unit)], True) return True class RandomSensor(Entity): """Representation of a Random number sensor.""" - def __init__(self, name, minimum, maximum): + def __init__(self, name, minimum, maximum, unit_of_measurement): """Initialize the sensor.""" self._name = name self._minimum = minimum self._maximum = maximum + self._unit_of_measurement = unit_of_measurement self._state = None @property @@ -65,6 +69,11 @@ def icon(self): """Icon to use in the frontend, if any.""" return ICON + @property + def unit_of_measurement(self): + """Return the unit this state is expressed in.""" + return self._unit_of_measurement + @asyncio.coroutine def async_update(self): """Get a new number and updates the states.""" From ad649009cdbd4f05018974feaa9ddc0609f874bd Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sun, 26 Mar 2017 15:53:42 +0200 Subject: [PATCH 023/116] Upgrade zeroconf to 0.19.0 (#6792) --- homeassistant/components/zeroconf.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/zeroconf.py b/homeassistant/components/zeroconf.py index d0a61e0cec020c..3dc30f3a24e709 100644 --- a/homeassistant/components/zeroconf.py +++ b/homeassistant/components/zeroconf.py @@ -17,7 +17,7 @@ DEPENDENCIES = ['api'] DOMAIN = 'zeroconf' -REQUIREMENTS = ['zeroconf==0.18.0'] +REQUIREMENTS = ['zeroconf==0.19.0'] ZEROCONF_TYPE = '_home-assistant._tcp.local.' diff --git a/requirements_all.txt b/requirements_all.txt index b06d6545d0098e..e78297ca418e5a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -796,4 +796,4 @@ yeelightsunflower==0.0.8 zengge==0.2 # homeassistant.components.zeroconf -zeroconf==0.18.0 +zeroconf==0.19.0 From 6e44ccf683b0e1661f1fe593d6883be5bc7fb992 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sun, 26 Mar 2017 15:53:53 +0200 Subject: [PATCH 024/116] Upgrade pysnmp to 4.3.5 (#6793) --- homeassistant/components/device_tracker/snmp.py | 2 +- homeassistant/components/sensor/snmp.py | 14 +++++++------- requirements_all.txt | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/device_tracker/snmp.py b/homeassistant/components/device_tracker/snmp.py index 6e8b07e6babf94..cbe70075665fd5 100644 --- a/homeassistant/components/device_tracker/snmp.py +++ b/homeassistant/components/device_tracker/snmp.py @@ -19,7 +19,7 @@ _LOGGER = logging.getLogger(__name__) -REQUIREMENTS = ['pysnmp==4.3.4'] +REQUIREMENTS = ['pysnmp==4.3.5'] CONF_COMMUNITY = 'community' CONF_AUTHKEY = 'authkey' diff --git a/homeassistant/components/sensor/snmp.py b/homeassistant/components/sensor/snmp.py index b72398c3736c5c..1342f3d2a9e74e 100644 --- a/homeassistant/components/sensor/snmp.py +++ b/homeassistant/components/sensor/snmp.py @@ -16,7 +16,7 @@ import homeassistant.helpers.config_validation as cv from homeassistant.util import Throttle -REQUIREMENTS = ['pysnmp==4.3.4'] +REQUIREMENTS = ['pysnmp==4.3.5'] _LOGGER = logging.getLogger(__name__) @@ -42,9 +42,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the SNMP sensor.""" - from pysnmp.hlapi import (getCmd, CommunityData, SnmpEngine, - UdpTransportTarget, ContextData, ObjectType, - ObjectIdentity) + from pysnmp.hlapi import ( + getCmd, CommunityData, SnmpEngine, UdpTransportTarget, ContextData, + ObjectType, ObjectIdentity) name = config.get(CONF_NAME) host = config.get(CONF_HOST) @@ -114,9 +114,9 @@ def __init__(self, host, port, community, baseoid): @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): """Get the latest data from the remote SNMP capable host.""" - from pysnmp.hlapi import (getCmd, CommunityData, SnmpEngine, - UdpTransportTarget, ContextData, ObjectType, - ObjectIdentity) + from pysnmp.hlapi import ( + getCmd, CommunityData, SnmpEngine, UdpTransportTarget, ContextData, + ObjectType, ObjectIdentity) errindication, errstatus, errindex, restable = next( getCmd(SnmpEngine(), CommunityData(self._community, mpModel=0), diff --git a/requirements_all.txt b/requirements_all.txt index e78297ca418e5a..05655e3ed07bf5 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -577,7 +577,7 @@ pysma==0.1.3 # homeassistant.components.device_tracker.snmp # homeassistant.components.sensor.snmp -pysnmp==4.3.4 +pysnmp==4.3.5 # homeassistant.components.media_player.clementine python-clementine-remote==1.0.1 From 78b5eb7aac10adb3b0083498afe240d299923f64 Mon Sep 17 00:00:00 2001 From: David Straub Date: Sun, 26 Mar 2017 19:06:40 +0200 Subject: [PATCH 025/116] Platform for Munich public transport departure times (#6704) * Add MVGLive (Munich public transport real-time departure) sensor platform * Move update on startup to add_devices; rewrite dictionary filtering * Fix lint error * Updated requirement to PyMVGLive 1.1.3 (PyPI version) * Refactor and clean up MVGLiveData.update method * Shorten line --- .coveragerc | 1 + homeassistant/components/sensor/mvglive.py | 159 +++++++++++++++++++++ requirements_all.txt | 3 + 3 files changed, 163 insertions(+) create mode 100644 homeassistant/components/sensor/mvglive.py diff --git a/.coveragerc b/.coveragerc index 91cb5ef640493f..fac7edfa42b816 100644 --- a/.coveragerc +++ b/.coveragerc @@ -360,6 +360,7 @@ omit = homeassistant/components/sensor/miflora.py homeassistant/components/sensor/modem_callerid.py homeassistant/components/sensor/mqtt_room.py + homeassistant/components/sensor/mvglive.py homeassistant/components/sensor/netdata.py homeassistant/components/sensor/neurio_energy.py homeassistant/components/sensor/nut.py diff --git a/homeassistant/components/sensor/mvglive.py b/homeassistant/components/sensor/mvglive.py new file mode 100644 index 00000000000000..734744378bac7a --- /dev/null +++ b/homeassistant/components/sensor/mvglive.py @@ -0,0 +1,159 @@ +""" +Support for real-time departure information for public transport in Munich. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.mvglive/ +""" + +import logging +from datetime import timedelta + +import voluptuous as vol + +from homeassistant.util import Throttle +from homeassistant.helpers.entity import Entity +from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.const import STATE_UNKNOWN +import homeassistant.helpers.config_validation as cv + +_LOGGER = logging.getLogger(__name__) +# A typo in the file name of the PyPI version prevents installation from PyPI +REQUIREMENTS = ["PyMVGLive==1.1.3"] +ICON = 'mdi:bus' + +# Return cached results if last scan was less then this time ago. +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=15) + +CONF_STATION = 'station' +CONF_DEST = 'destination' +CONF_LINE = 'line' +CONF_OFFSET = 'offset' +CONF_UBAHN = 'ubahn' +CONF_TRAM = 'tram' +CONF_BUS = 'bus' +CONF_SBAHN = 'sbahn' + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_STATION): cv.string, + vol.Optional(CONF_DEST, default=None): cv.string, + vol.Optional(CONF_LINE, default=None): cv.string, + vol.Optional(CONF_OFFSET, default=0): cv.positive_int, + vol.Optional(CONF_UBAHN, default=True): cv.boolean, + vol.Optional(CONF_TRAM, default=True): cv.boolean, + vol.Optional(CONF_BUS, default=True): cv.boolean, + vol.Optional(CONF_SBAHN, default=True): cv.boolean, +}) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Setup the MVG Live Sensor.""" + station = config.get(CONF_STATION) + destination = config.get(CONF_DEST) + line = config.get(CONF_LINE) + offset = config.get(CONF_OFFSET) + ubahn = config.get(CONF_UBAHN) + tram = config.get(CONF_TRAM) + bus = config.get(CONF_BUS) + sbahn = config.get(CONF_SBAHN) + + add_devices([MVGLiveSensor(station, destination, line, + offset, ubahn, tram, bus, sbahn)], True) + + +# pylint: disable=too-few-public-methods +class MVGLiveSensor(Entity): + """Implementation of an MVG Live sensor.""" + + def __init__(self, station, destination, line, + offset, ubahn, tram, bus, sbahn): + """Initialize the sensor.""" + self._station = station + self._destination = destination + self._line = line + self.data = MVGLiveData(station, destination, line, + offset, ubahn, tram, bus, sbahn) + self._state = STATE_UNKNOWN + + @property + def name(self): + """Return the name of the sensor.""" + # e.g. + # 'Hauptbahnhof (S1)' + # 'Hauptbahnhof-Marienplatz' + # 'Hauptbahnhof-Marienplatz (S1)' + namestr = self._station + if self._destination: + namestr = namestr + '-' + self._destination + if self._line: + namestr = namestr + ' (' + self._line + ')' + return namestr + + @property + def icon(self): + """Return the icon for the frontend.""" + return ICON + + @property + def state(self): + """Return the departure time of the next train.""" + return self._state + + @property + def state_attributes(self): + """Return the state attributes.""" + return self.data.nextdeparture + + def update(self): + """Get the latest data and update the state.""" + self.data.update() + if not self.data.nextdeparture: + self._state = '-' + else: + self._state = self.data.nextdeparture.get('time', '-') + + +class MVGLiveData(object): + """Pull data from the mvg-live.de web page.""" + + def __init__(self, station, destination, line, + offset, ubahn, tram, bus, sbahn): + """Initialize the sensor.""" + import MVGLive + self._station = station + self._destination = destination + self._line = line + self._offset = offset + self._ubahn = ubahn + self._tram = tram + self._bus = bus + self._sbahn = sbahn + self.mvg = MVGLive.MVGLive() + self.nextdeparture = {} + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + def update(self): + """Update the connection data.""" + try: + _departures = self.mvg.getlivedata(station=self._station, + ubahn=self._ubahn, + tram=self._tram, + bus=self._bus, + sbahn=self._sbahn) + except ValueError: + self.nextdeparture = {} + _LOGGER.warning("Returned data not understood.") + return + for _departure in _departures: + # find the first departure meeting the criteria + if not _departure['destination'].startswith(self._destination): + continue + elif _departure['time'] < self._offset: + continue + # now select the relevant data + _nextdep = {} + for k in ['destination', 'linename', 'time', 'direction', + 'product']: + _nextdep[k] = _departure.get(k, '') + _nextdep['time'] = int(_nextdep['time']) + self.nextdeparture = _nextdep + break diff --git a/requirements_all.txt b/requirements_all.txt index 05655e3ed07bf5..475993accedfb9 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -21,6 +21,9 @@ PyISY==1.0.7 # homeassistant.components.notify.html5 PyJWT==1.4.2 +# homeassistant.components.sensor.mvglive +PyMVGLive==1.1.3 + # homeassistant.components.arduino PyMata==2.13 From 84287872bbe51c9876d63a9e6413580e8d755ea2 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sun, 26 Mar 2017 21:13:38 +0200 Subject: [PATCH 026/116] Use string formatting and remove already global disabled pylint issue (#6801) --- homeassistant/components/sensor/mvglive.py | 42 ++++++++++------------ 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/homeassistant/components/sensor/mvglive.py b/homeassistant/components/sensor/mvglive.py index 734744378bac7a..7043da53222e7d 100644 --- a/homeassistant/components/sensor/mvglive.py +++ b/homeassistant/components/sensor/mvglive.py @@ -4,34 +4,33 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.mvglive/ """ - import logging from datetime import timedelta import voluptuous as vol +import homeassistant.helpers.config_validation as cv from homeassistant.util import Throttle from homeassistant.helpers.entity import Entity from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import STATE_UNKNOWN -import homeassistant.helpers.config_validation as cv -_LOGGER = logging.getLogger(__name__) -# A typo in the file name of the PyPI version prevents installation from PyPI -REQUIREMENTS = ["PyMVGLive==1.1.3"] -ICON = 'mdi:bus' +REQUIREMENTS = ['PyMVGLive==1.1.3'] -# Return cached results if last scan was less then this time ago. -MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=15) +_LOGGER = logging.getLogger(__name__) -CONF_STATION = 'station' +CONF_BUS = 'bus' CONF_DEST = 'destination' CONF_LINE = 'line' CONF_OFFSET = 'offset' -CONF_UBAHN = 'ubahn' -CONF_TRAM = 'tram' -CONF_BUS = 'bus' CONF_SBAHN = 'sbahn' +CONF_STATION = 'station' +CONF_TRAM = 'tram' +CONF_UBAHN = 'ubahn' + +ICON = 'mdi:bus' + +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=15) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_STATION): cv.string, @@ -46,7 +45,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): - """Setup the MVG Live Sensor.""" + """Set up the MVG Live Sensor.""" station = config.get(CONF_STATION) destination = config.get(CONF_DEST) line = config.get(CONF_LINE) @@ -56,11 +55,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None): bus = config.get(CONF_BUS) sbahn = config.get(CONF_SBAHN) - add_devices([MVGLiveSensor(station, destination, line, - offset, ubahn, tram, bus, sbahn)], True) + add_devices([MVGLiveSensor( + station, destination, line, offset, ubahn, tram, bus, sbahn)], True) -# pylint: disable=too-few-public-methods class MVGLiveSensor(Entity): """Implementation of an MVG Live sensor.""" @@ -83,9 +81,9 @@ def name(self): # 'Hauptbahnhof-Marienplatz (S1)' namestr = self._station if self._destination: - namestr = namestr + '-' + self._destination + namestr = '{}-{}'.format(namestr, self._destination) if self._line: - namestr = namestr + ' (' + self._line + ')' + namestr = '{} ({})'.format(namestr, self._line) return namestr @property @@ -134,11 +132,9 @@ def __init__(self, station, destination, line, def update(self): """Update the connection data.""" try: - _departures = self.mvg.getlivedata(station=self._station, - ubahn=self._ubahn, - tram=self._tram, - bus=self._bus, - sbahn=self._sbahn) + _departures = self.mvg.getlivedata( + station=self._station, ubahn=self._ubahn, tram=self._tram, + bus=self._bus, sbahn=self._sbahn) except ValueError: self.nextdeparture = {} _LOGGER.warning("Returned data not understood.") From f4f72e420ad696a26a194749740a829ab69de656 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Mon, 27 Mar 2017 10:35:27 +0200 Subject: [PATCH 027/116] Fix typo and update name (#6809) --- homeassistant/components/notify/pushbullet.py | 38 +++++++++---------- homeassistant/components/notify/smtp.py | 15 ++++---- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/homeassistant/components/notify/pushbullet.py b/homeassistant/components/notify/pushbullet.py index 4f50146ac61383..fb6543afcb44fd 100644 --- a/homeassistant/components/notify/pushbullet.py +++ b/homeassistant/components/notify/pushbullet.py @@ -1,5 +1,5 @@ """ -PushBullet platform for notify component. +Pushbullet platform for notify component. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/notify.pushbullet/ @@ -26,7 +26,7 @@ # pylint: disable=unused-argument def get_service(hass, config, discovery_info=None): - """Get the PushBullet notification service.""" + """Get the Pushbullet notification service.""" from pushbullet import PushBullet from pushbullet import InvalidKeyError @@ -53,9 +53,9 @@ def __init__(self, pb): def refresh(self): """Refresh devices, contacts, etc. - pbtargets stores all targets available from this pushbullet instance - into a dict. These are PB objects!. It sacrifices a bit of memory - for faster processing at send_message. + pbtargets stores all targets available from this Pushbullet instance + into a dict. These are Pushbullet objects!. It sacrifices a bit of + memory for faster processing at send_message. As of sept 2015, contacts were replaced by chats. This is not implemented in the module yet. @@ -73,7 +73,7 @@ def send_message(self, message=None, **kwargs): """Send a message to a specified target. If no target specified, a 'normal' push will be sent to all devices - linked to the PB account. + linked to the Pushbullet account. Email is special, these are assumed to always exist. We use a special call which doesn't require a push object. """ @@ -86,37 +86,37 @@ def send_message(self, message=None, **kwargs): refreshed = False if not targets: - # Backward compatebility, notify all devices in own account + # Backward compatibility, notify all devices in own account if url: self.pushbullet.push_link(title, url, body=message) else: self.pushbullet.push_note(title, message) - _LOGGER.info('Sent notification to self') + _LOGGER.info("Sent notification to self") return - # Main loop, Process all targets specified + # Main loop, process all targets specified for target in targets: try: ttype, tname = target.split('/', 1) except ValueError: - _LOGGER.error('Invalid target syntax: %s', target) + _LOGGER.error("Invalid target syntax: %s", target) continue # Target is email, send directly, don't use a target object # This also seems works to send to all devices in own account if ttype == 'email': if url: - self.pushbullet.push_link(title, url, - body=message, email=tname) + self.pushbullet.push_link( + title, url, body=message, email=tname) else: self.pushbullet.push_note(title, message, email=tname) - _LOGGER.info('Sent notification to email %s', tname) + _LOGGER.info("Sent notification to email %s", tname) continue # Refresh if name not found. While awaiting periodic refresh # solution in component, poor mans refresh ;) if ttype not in self.pbtargets: - _LOGGER.error('Invalid target syntax: %s', target) + _LOGGER.error("Invalid target syntax: %s", target) continue tname = tname.lower() @@ -129,14 +129,14 @@ def send_message(self, message=None, **kwargs): # name. Dict pbtargets has all *actual* targets. try: if url: - self.pbtargets[ttype][tname].push_link(title, url, - body=message) + self.pbtargets[ttype][tname].push_link( + title, url, body=message) else: self.pbtargets[ttype][tname].push_note(title, message) - _LOGGER.info('Sent notification to %s/%s', ttype, tname) + _LOGGER.info("Sent notification to %s/%s", ttype, tname) except KeyError: - _LOGGER.error('No such target: %s/%s', ttype, tname) + _LOGGER.error("No such target: %s/%s", ttype, tname) continue except self.pushbullet.errors.PushError: - _LOGGER.error('Notify failed to: %s/%s', ttype, tname) + _LOGGER.error("Notify failed to: %s/%s", ttype, tname) continue diff --git a/homeassistant/components/notify/smtp.py b/homeassistant/components/notify/smtp.py index 460659b321492f..fbfa9e7a970817 100644 --- a/homeassistant/components/notify/smtp.py +++ b/homeassistant/components/notify/smtp.py @@ -156,8 +156,8 @@ def _send_email(self, msg): msg.as_string()) break except smtplib.SMTPException: - _LOGGER.warning('SMTPException sending mail: ' - 'retrying connection') + _LOGGER.warning( + "SMTPException sending mail: retrying connection") mail.quit() mail = self.connect() @@ -166,13 +166,13 @@ def _send_email(self, msg): def _build_text_msg(message): """Build plaintext email.""" - _LOGGER.debug('Building plain text email') + _LOGGER.debug("Building plain text email") return MIMEText(message) def _build_multipart_msg(message, images): """Build Multipart message with in-line images.""" - _LOGGER.debug('Building multipart email with embedded attachment(s)') + _LOGGER.debug("Building multipart email with embedded attachment(s)") msg = MIMEMultipart('related') msg_alt = MIMEMultipart('alternative') msg.attach(msg_alt) @@ -191,16 +191,15 @@ def _build_multipart_msg(message, images): msg.attach(attachment) attachment.add_header('Content-ID', '<{}>'.format(cid)) except TypeError: - _LOGGER.warning('Attachment %s has an unkown MIME type.' - ' Falling back to file', atch_name) + _LOGGER.warning("Attachment %s has an unkown MIME type." + " Falling back to file", atch_name) attachment = MIMEApplication(file_bytes, Name=atch_name) attachment['Content-Disposition'] = ('attachment; ' 'filename="%s"' % atch_name) msg.attach(attachment) except FileNotFoundError: - _LOGGER.warning('Attachment %s not found. Skipping', - atch_name) + _LOGGER.warning("Attachment %s not found. Skipping", atch_name) body_html = MIMEText(''.join(body_text), 'html') msg_alt.attach(body_html) From be04ef7be1e6a1936b1526caba0d6a727e7827b8 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Mon, 27 Mar 2017 10:35:40 +0200 Subject: [PATCH 028/116] Upgrade matrix-client to 0.0.6 (#6808) --- homeassistant/components/notify/matrix.py | 35 ++++++++--------------- requirements_all.txt | 2 +- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/homeassistant/components/notify/matrix.py b/homeassistant/components/notify/matrix.py index b36721e8f80f4d..15da3f053d851e 100644 --- a/homeassistant/components/notify/matrix.py +++ b/homeassistant/components/notify/matrix.py @@ -15,7 +15,9 @@ ATTR_TARGET, PLATFORM_SCHEMA, BaseNotificationService) from homeassistant.const import CONF_USERNAME, CONF_PASSWORD, CONF_VERIFY_SSL -REQUIREMENTS = ['matrix-client==0.0.5'] +REQUIREMENTS = ['matrix-client==0.0.6'] + +_LOGGER = logging.getLogger(__name__) SESSION_FILE = 'matrix.conf' AUTH_TOKENS = dict() @@ -31,8 +33,6 @@ vol.Required(CONF_DEFAULT_ROOM): cv.string, }) -_LOGGER = logging.getLogger(__name__) - def get_service(hass, config, discovery_info=None): """Get the Matrix notification service.""" @@ -49,7 +49,7 @@ def get_service(hass, config, discovery_info=None): class MatrixNotificationService(BaseNotificationService): - """Wrapper for the MatrixNotificationClient.""" + """Wrapper for the Matrix Notification Client.""" def __init__(self, homeserver, default_room, verify_ssl, username, password): @@ -107,32 +107,23 @@ def login_by_token(): valid_cert_check=verify_tls ) except MatrixRequestError as ex: - _LOGGER.info( - 'login_by_token: (%d) %s', ex.code, ex.content - ) + _LOGGER.info("login_by_token: (%d) %s", ex.code, ex.content) def login_by_password(): """Login using password authentication.""" try: _client = MatrixClient( - base_url=homeserver, - valid_cert_check=verify_tls - ) + base_url=homeserver, valid_cert_check=verify_tls) _client.login_with_password(username, password) store_token(mx_id, _client.token) return _client except MatrixRequestError as ex: - _LOGGER.error( - 'login_by_password: (%d) %s', ex.code, ex.content - ) + _LOGGER.error("login_by_password: (%d) %s", ex.code, ex.content) - # this is as close as we can get to the mx_id, since there is no + # This is as close as we can get to the mx_id, since there is no # homeserver discovery protocol we have to fall back to the homeserver url # instead of the actual domain it serves. - mx_id = "{user}@{homeserver}".format( - user=username, - homeserver=homeserver - ) + mx_id = "{user}@{homeserver}".format(user=username, homeserver=homeserver) if mx_id in AUTH_TOKENS: client = login_by_token() @@ -140,14 +131,12 @@ def login_by_password(): client = login_by_password() if not client: _LOGGER.error( - 'login failed, both token and username/password ' - 'invalid' - ) + "Login failed, both token and username/password invalid") return else: client = login_by_password() if not client: - _LOGGER.error('login failed, username/password invalid') + _LOGGER.error("Login failed, username/password invalid") return rooms = client.get_rooms() @@ -161,6 +150,6 @@ def login_by_password(): _LOGGER.debug(room.send_text(message)) except MatrixRequestError as ex: _LOGGER.error( - 'Unable to deliver message to room \'%s\': (%d): %s', + "Unable to deliver message to room '%s': (%d): %s", target_room, ex.code, ex.content ) diff --git a/requirements_all.txt b/requirements_all.txt index 475993accedfb9..8e093156b10041 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -360,7 +360,7 @@ liveboxplaytv==1.4.9 lyft_rides==0.1.0b0 # homeassistant.components.notify.matrix -matrix-client==0.0.5 +matrix-client==0.0.6 # homeassistant.components.maxcube maxcube-api==0.1.0 From a70af62e60705b30876e360659b72c4ca7a6b0aa Mon Sep 17 00:00:00 2001 From: tantecky Date: Mon, 27 Mar 2017 12:22:59 +0200 Subject: [PATCH 029/116] Make get_snmp_data more robust (#6798) --- homeassistant/components/device_tracker/snmp.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/device_tracker/snmp.py b/homeassistant/components/device_tracker/snmp.py index cbe70075665fd5..1449ae6dbef326 100644 --- a/homeassistant/components/device_tracker/snmp.py +++ b/homeassistant/components/device_tracker/snmp.py @@ -125,7 +125,10 @@ def get_snmp_data(self): for resrow in restable: for _, val in resrow: - mac = binascii.hexlify(val.asOctets()).decode('utf-8') + try: + mac = binascii.hexlify(val.asOctets()).decode('utf-8') + except AttributeError: + continue _LOGGER.debug("Found MAC %s", mac) mac = ':'.join([mac[i:i+2] for i in range(0, len(mac), 2)]) devices.append({'mac': mac}) From f242ad26ca5bd7c648d33632314319e5288847a8 Mon Sep 17 00:00:00 2001 From: John Mihalic Date: Mon, 27 Mar 2017 06:41:57 -0400 Subject: [PATCH 030/116] Add NVR support to Hikvision Binary Sensors (#6807) * Add NVR support to hikvision * Only append channel for nvr devices * Descriptor cleanup * Update requirements --- .../components/binary_sensor/hikvision.py | 65 ++++++++++++------- requirements_all.txt | 2 +- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/homeassistant/components/binary_sensor/hikvision.py b/homeassistant/components/binary_sensor/hikvision.py index 135d9a1e02857e..ac1b2657448a6e 100644 --- a/homeassistant/components/binary_sensor/hikvision.py +++ b/homeassistant/components/binary_sensor/hikvision.py @@ -18,7 +18,7 @@ CONF_SSL, EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_START, ATTR_LAST_TRIP_TIME, CONF_CUSTOMIZE) -REQUIREMENTS = ['pyhik==0.1.0'] +REQUIREMENTS = ['pyhik==0.1.1'] _LOGGER = logging.getLogger(__name__) CONF_IGNORED = 'ignored' @@ -33,7 +33,6 @@ DEVICE_CLASS_MAP = { 'Motion': 'motion', 'Line Crossing': 'motion', - 'IO Trigger': None, 'Field Detection': 'motion', 'Video Loss': None, 'Tamper Detection': 'motion', @@ -47,6 +46,7 @@ 'Bad Video': None, 'PIR Alarm': 'motion', 'Face Detection': 'motion', + 'Scene Change Detection': 'motion', } CUSTOMIZE_SCHEMA = vol.Schema({ @@ -91,24 +91,30 @@ def setup_platform(hass, config, add_entities, discovery_info=None): entities = [] - for sensor in data.sensors: - # Build sensor name, then parse customize config. - sensor_name = sensor.replace(' ', '_') - - custom = customize.get(sensor_name.lower(), {}) - ignore = custom.get(CONF_IGNORED) - delay = custom.get(CONF_DELAY) - - _LOGGER.debug('Entity: %s - %s, Options - Ignore: %s, Delay: %s', - data.name, sensor_name, ignore, delay) - if not ignore: - entities.append(HikvisionBinarySensor(hass, sensor, data, delay)) + for sensor, channel_list in data.sensors.items(): + for channel in channel_list: + # Build sensor name, then parse customize config. + if data.type == 'NVR': + sensor_name = '{}_{}'.format( + sensor.replace(' ', '_'), channel[1]) + else: + sensor_name = sensor.replace(' ', '_') + + custom = customize.get(sensor_name.lower(), {}) + ignore = custom.get(CONF_IGNORED) + delay = custom.get(CONF_DELAY) + + _LOGGER.debug('Entity: %s - %s, Options - Ignore: %s, Delay: %s', + data.name, sensor_name, ignore, delay) + if not ignore: + entities.append(HikvisionBinarySensor( + hass, sensor, channel[1], data, delay)) add_entities(entities) class HikvisionData(object): - """Hikvision camera event stream object.""" + """Hikvision device event stream object.""" def __init__(self, hass, url, port, name, username, password): """Initialize the data oject.""" @@ -144,25 +150,40 @@ def sensors(self): @property def cam_id(self): - """Return camera id.""" + """Return device id.""" return self.camdata.get_id @property def name(self): - """Return camera name.""" + """Return device name.""" return self._name + @property + def type(self): + """Return device type.""" + return self.camdata.get_type + + def get_attributes(self, sensor, channel): + """Return attribute list for sensor/channel.""" + return self.camdata.fetch_attributes(sensor, channel) + class HikvisionBinarySensor(BinarySensorDevice): """Representation of a Hikvision binary sensor.""" - def __init__(self, hass, sensor, cam, delay): + def __init__(self, hass, sensor, channel, cam, delay): """Initialize the binary_sensor.""" self._hass = hass self._cam = cam - self._name = self._cam.name + ' ' + sensor - self._id = self._cam.cam_id + '.' + sensor self._sensor = sensor + self._channel = channel + + if self._cam.type == 'NVR': + self._name = '{} {} {}'.format(self._cam.name, sensor, channel) + else: + self._name = '{} {}'.format(self._cam.name, sensor) + + self._id = '{}.{}.{}'.format(self._cam.cam_id, sensor, channel) if delay is None: self._delay = 0 @@ -176,11 +197,11 @@ def __init__(self, hass, sensor, cam, delay): def _sensor_state(self): """Extract sensor state.""" - return self._cam.sensors[self._sensor][0] + return self._cam.get_attributes(self._sensor, self._channel)[0] def _sensor_last_update(self): """Extract sensor last update time.""" - return self._cam.sensors[self._sensor][3] + return self._cam.get_attributes(self._sensor, self._channel)[3] @property def name(self): diff --git a/requirements_all.txt b/requirements_all.txt index 8e093156b10041..d449f7e2d11318 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -517,7 +517,7 @@ pygatt==3.0.0 pyharmony==1.0.12 # homeassistant.components.binary_sensor.hikvision -pyhik==0.1.0 +pyhik==0.1.1 # homeassistant.components.homematic pyhomematic==0.1.24 From c53de19246ea10597a1a22c0f809546b2b5b2bc7 Mon Sep 17 00:00:00 2001 From: Greg Dowling Date: Mon, 27 Mar 2017 11:43:43 +0100 Subject: [PATCH 031/116] Update Insight parameters using the subscription data. (#6782) * Update Insight parameters using the subscription dta. * Minor refactor. * Tidy. --- homeassistant/components/switch/wemo.py | 15 +++++++-------- homeassistant/components/wemo.py | 2 +- requirements_all.txt | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/switch/wemo.py b/homeassistant/components/switch/wemo.py index 97c0fb3d386620..e78190bf444d70 100644 --- a/homeassistant/components/switch/wemo.py +++ b/homeassistant/components/switch/wemo.py @@ -61,16 +61,14 @@ def __init__(self, device): wemo.SUBSCRIPTION_REGISTRY.register(self.wemo) wemo.SUBSCRIPTION_REGISTRY.on(self.wemo, None, self._update_callback) - def _update_callback(self, _device, _params): + def _update_callback(self, _device, _type, _params): """Called by the Wemo device callback to update state.""" _LOGGER.info( 'Subscription update for %s', _device) - if self._model_name == 'CoffeeMaker': - self.wemo.subscription_callback(_params) - self._update(force_update=False) - else: - self.update() + updated = self.wemo.subscription_update(_type, _params) + self._update(force_update=(not updated)) + if not hasattr(self, 'hass'): return self.schedule_update_ha_state() @@ -219,5 +217,6 @@ def _update(self, force_update=True): self.maker_params = self.wemo.maker_params elif self._model_name == 'CoffeeMaker': self.coffeemaker_mode = self.wemo.mode - except AttributeError: - _LOGGER.warning('Could not update status for %s', self.name) + except AttributeError as err: + _LOGGER.warning('Could not update status for %s (%s)', + self.name, err) diff --git a/homeassistant/components/wemo.py b/homeassistant/components/wemo.py index c121c58470bd5a..7cec1707211a6b 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.13'] +REQUIREMENTS = ['pywemo==0.4.15'] DOMAIN = 'wemo' diff --git a/requirements_all.txt b/requirements_all.txt index d449f7e2d11318..bb0993338f3f67 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -647,7 +647,7 @@ pyvera==0.2.24 pywebpush==0.6.1 # homeassistant.components.wemo -pywemo==0.4.13 +pywemo==0.4.15 # homeassistant.components.zabbix pyzabbix==0.7.4 From b8c1bc9542130ee2133ab555a8537d1fe9c88b7e Mon Sep 17 00:00:00 2001 From: goto100 Date: Mon, 27 Mar 2017 20:02:43 +0800 Subject: [PATCH 032/116] fix WOL in docker/jail (#6810) * fix WOL in docker/jail add ip_address parameter to send_magic_packet if host specific. in docker/jail, WOL doesn't works due to subnet broadcast issues. * Update wake_on_lan.py lint --- homeassistant/components/switch/wake_on_lan.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/switch/wake_on_lan.py b/homeassistant/components/switch/wake_on_lan.py index ba3439dc951d7d..c86a4674bb6e67 100644 --- a/homeassistant/components/switch/wake_on_lan.py +++ b/homeassistant/components/switch/wake_on_lan.py @@ -75,7 +75,11 @@ def name(self): def turn_on(self): """Turn the device on.""" - self._wol.send_magic_packet(self._mac_address) + if self._host: + self._wol.send_magic_packet(self._mac_address, + ip_address=self._host) + else: + self._wol.send_magic_packet(self._mac_address) def turn_off(self): """Turn the device off if an off action is present.""" From d027df5a897b8a60415e4ff115f9dfbf386c3832 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Mon, 27 Mar 2017 22:11:15 +0200 Subject: [PATCH 033/116] Allow to monitor Windows hosts (#6803) --- homeassistant/components/sensor/glances.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/sensor/glances.py b/homeassistant/components/sensor/glances.py index 0896e99989f60a..699781d323b2f7 100644 --- a/homeassistant/components/sensor/glances.py +++ b/homeassistant/components/sensor/glances.py @@ -133,7 +133,11 @@ def state(self): elif self.type == 'swap_free': return round(value['memswap']['free'] / 1024**3, 1) elif self.type == 'processor_load': - return value['load']['min15'] + # Windows systems don't provide load details + try: + return value['load']['min15'] + except KeyError: + return value['cpu']['total'] elif self.type == 'process_running': return value['processcount']['running'] elif self.type == 'process_total': From 5c80da6a8f475f2abc2608e4a7f0bc6df62a1588 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Tue, 28 Mar 2017 00:04:28 +0200 Subject: [PATCH 034/116] lights/hue: use device class for on/off devices like the osram lightify plug (#6817) * hue: remove duplicate SUPPORT_FLASH flag * hue: use correct device class for the Osram Lightify Plug --- homeassistant/components/light/hue.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/light/hue.py b/homeassistant/components/light/hue.py index 1c0970f154c66a..31ec88f3c97669 100644 --- a/homeassistant/components/light/hue.py +++ b/homeassistant/components/light/hue.py @@ -47,7 +47,7 @@ PHUE_CONFIG_FILE = 'phue.conf' -SUPPORT_HUE_ON_OFF = (SUPPORT_FLASH | SUPPORT_TRANSITION | SUPPORT_FLASH) +SUPPORT_HUE_ON_OFF = (SUPPORT_FLASH | SUPPORT_TRANSITION) SUPPORT_HUE_DIMMABLE = (SUPPORT_HUE_ON_OFF | SUPPORT_BRIGHTNESS) SUPPORT_HUE_COLOR_TEMP = (SUPPORT_HUE_DIMMABLE | SUPPORT_COLOR_TEMP) SUPPORT_HUE_COLOR = (SUPPORT_HUE_DIMMABLE | SUPPORT_EFFECT | @@ -58,6 +58,7 @@ 'Extended color light': SUPPORT_HUE_EXTENDED, 'Color light': SUPPORT_HUE_COLOR, 'Dimmable light': SUPPORT_HUE_DIMMABLE, + 'On/Off plug-in unit': SUPPORT_HUE_ON_OFF, 'Color temperature light': SUPPORT_HUE_COLOR_TEMP } From 6dba05c79f189aaaed88b18c22cf27b1ff277068 Mon Sep 17 00:00:00 2001 From: Lewis Juggins Date: Tue, 28 Mar 2017 16:24:33 +0100 Subject: [PATCH 035/116] [switch.wemo] Fix mW to kW conversion. (#6826) * Fix mW to kW conversion. * Line length. --- homeassistant/components/switch/wemo.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/switch/wemo.py b/homeassistant/components/switch/wemo.py index e78190bf444d70..7518a1958cff00 100644 --- a/homeassistant/components/switch/wemo.py +++ b/homeassistant/components/switch/wemo.py @@ -148,7 +148,8 @@ def current_power_w(self): def today_energy_kwh(self): """Today total energy usage in kWh.""" if self.insight_params: - return convert(self.insight_params['todaymw'], float, 0.0) / 1000.0 + miliwatts = convert(self.insight_params['todaymw'], float, 0.0) + return miliwatts / 1000000.0 @property def detail_state(self): From 429367409c0538e936322e5249a4a26764b06415 Mon Sep 17 00:00:00 2001 From: Teemu R Date: Tue, 28 Mar 2017 17:26:43 +0200 Subject: [PATCH 036/116] yeelight: adjust supported features on update() (#6799) * yeelight: adjust supported features on update() Earlier we checked for the type only during the initialization, but this won't work when the bulb is disconnected during the init, causing failures to adjust rgb&color temperature even if those should be supported. fixes #6692 * Use reassign instead of OR for updating the supported features --- homeassistant/components/light/yeelight.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/light/yeelight.py b/homeassistant/components/light/yeelight.py index 7e0bd0e253ee5d..65b32786ce7480 100644 --- a/homeassistant/components/light/yeelight.py +++ b/homeassistant/components/light/yeelight.py @@ -44,13 +44,14 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( {vol.Optional(CONF_DEVICES, default={}): {cv.string: DEVICE_SCHEMA}, }) -SUPPORT_YEELIGHT_RGB = (SUPPORT_RGB_COLOR | - SUPPORT_COLOR_TEMP) - SUPPORT_YEELIGHT = (SUPPORT_BRIGHTNESS | SUPPORT_TRANSITION | SUPPORT_FLASH) +SUPPORT_YEELIGHT_RGB = (SUPPORT_YEELIGHT | + SUPPORT_RGB_COLOR | + SUPPORT_COLOR_TEMP) + def _cmd(func): """A wrapper to catch exceptions from the bulb.""" @@ -179,9 +180,6 @@ def _bulb(self) -> object: self._bulb_device = yeelight.Bulb(self._ipaddr) self._bulb_device.get_properties() # force init for type - btype = self._bulb_device.bulb_type - if btype == yeelight.BulbType.Color: - self._supported_features |= SUPPORT_YEELIGHT_RGB self._available = True except yeelight.BulbException as ex: self._available = False @@ -203,6 +201,9 @@ def update(self) -> None: try: self._bulb.get_properties() + if self._bulb_device.bulb_type == yeelight.BulbType.Color: + self._supported_features = SUPPORT_YEELIGHT_RGB + self._is_on = self._properties.get("power") == "on" bright = self._properties.get("bright", None) From b5336ed04ee863187848d2937d06bebc706b0ea0 Mon Sep 17 00:00:00 2001 From: William Scanlon Date: Tue, 28 Mar 2017 14:13:45 -0400 Subject: [PATCH 037/116] Updated pubnubsub-handler version (#6829) --- homeassistant/components/wink.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/wink.py b/homeassistant/components/wink.py index 92cd7baa65ef6c..8cf32f64d61c14 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==1.2.3', 'pubnubsub-handler==1.0.1'] +REQUIREMENTS = ['python-wink==1.2.3', 'pubnubsub-handler==1.0.2'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index bb0993338f3f67..ea986259ea823d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -441,7 +441,7 @@ proliphix==0.4.1 psutil==5.2.1 # homeassistant.components.wink -pubnubsub-handler==1.0.1 +pubnubsub-handler==1.0.2 # homeassistant.components.notify.pushbullet pushbullet.py==0.10.0 From fb8323f48d576341310ba878d281d00cd1e57043 Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 28 Mar 2017 23:01:29 +0300 Subject: [PATCH 038/116] Remove zwave cover invert workaround. Use config instead. (#6832) --- homeassistant/components/cover/zwave.py | 11 ++++++----- homeassistant/components/zwave/__init__.py | 4 ++++ homeassistant/components/zwave/workaround.py | 3 --- tests/components/cover/test_zwave.py | 7 +++++-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/cover/zwave.py b/homeassistant/components/cover/zwave.py index 129dbd32ffed93..3f26da183b5474 100644 --- a/homeassistant/components/cover/zwave.py +++ b/homeassistant/components/cover/zwave.py @@ -20,12 +20,13 @@ SUPPORT_GARAGE = SUPPORT_OPEN | SUPPORT_CLOSE -def get_device(values, **kwargs): +def get_device(values, node_config, **kwargs): """Create zwave entity device.""" + invert_buttons = node_config.get(zwave.CONF_INVERT_OPENCLOSE_BUTTONS) if (values.primary.command_class == zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL and values.primary.index == 0): - return ZwaveRollershutter(values) + return ZwaveRollershutter(values, invert_buttons) elif (values.primary.command_class in [ zwave.const.COMMAND_CLASS_SWITCH_BINARY, zwave.const.COMMAND_CLASS_BARRIER_OPERATOR]): @@ -36,13 +37,14 @@ def get_device(values, **kwargs): class ZwaveRollershutter(zwave.ZWaveDeviceEntity, CoverDevice): """Representation of an Zwave roller shutter.""" - def __init__(self, values): + def __init__(self, values, invert_buttons): """Initialize the zwave rollershutter.""" ZWaveDeviceEntity.__init__(self, values, DOMAIN) # pylint: disable=no-member self._open_id = None self._close_id = None self._current_position = None + self._invert_buttons = invert_buttons self._workaround = workaround.get_device_mapping(values.primary) if self._workaround: @@ -56,10 +58,9 @@ def update_properties(self): if self.values.open and self.values.close and \ self._open_id is None and self._close_id is None: - if self._workaround == workaround.WORKAROUND_REVERSE_OPEN_CLOSE: + if self._invert_buttons: self._open_id = self.values.close.value_id self._close_id = self.values.open.value_id - self._workaround = None else: self._open_id = self.values.open.value_id self._close_id = self.values.close.value_id diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py index 83fa38862c3be6..4eea502d40a8b2 100755 --- a/homeassistant/components/zwave/__init__.py +++ b/homeassistant/components/zwave/__init__.py @@ -45,6 +45,7 @@ CONF_USB_STICK_PATH = 'usb_path' CONF_CONFIG_PATH = 'config_path' CONF_IGNORED = 'ignored' +CONF_INVERT_OPENCLOSE_BUTTONS = 'invert_openclose_buttons' CONF_REFRESH_VALUE = 'refresh_value' CONF_REFRESH_DELAY = 'delay' CONF_DEVICE_CONFIG = 'device_config' @@ -58,6 +59,7 @@ DEFAULT_POLLING_INTERVAL = 60000 DEFAULT_DEBUG = False DEFAULT_CONF_IGNORED = False +DEFAULT_CONF_INVERT_OPENCLOSE_BUTTONS = False DEFAULT_CONF_REFRESH_VALUE = False DEFAULT_CONF_REFRESH_DELAY = 5 @@ -105,6 +107,8 @@ DEVICE_CONFIG_SCHEMA_ENTRY = vol.Schema({ vol.Optional(CONF_POLLING_INTENSITY): cv.positive_int, vol.Optional(CONF_IGNORED, default=DEFAULT_CONF_IGNORED): cv.boolean, + vol.Optional(CONF_INVERT_OPENCLOSE_BUTTONS, + default=DEFAULT_CONF_INVERT_OPENCLOSE_BUTTONS): cv.boolean, vol.Optional(CONF_REFRESH_VALUE, default=DEFAULT_CONF_REFRESH_VALUE): cv.boolean, vol.Optional(CONF_REFRESH_DELAY, default=DEFAULT_CONF_REFRESH_DELAY): diff --git a/homeassistant/components/zwave/workaround.py b/homeassistant/components/zwave/workaround.py index 17dbf1437f306f..27e98457a2d256 100644 --- a/homeassistant/components/zwave/workaround.py +++ b/homeassistant/components/zwave/workaround.py @@ -30,7 +30,6 @@ # Workarounds WORKAROUND_NO_OFF_EVENT = 'trigger_no_off_event' WORKAROUND_NO_POSITION = 'workaround_no_position' -WORKAROUND_REVERSE_OPEN_CLOSE = 'reverse_open_close' WORKAROUND_REFRESH_NODE_ON_UPDATE = 'refresh_node_on_update' WORKAROUND_IGNORE = 'workaround_ignore' @@ -43,12 +42,10 @@ } SOMFY_ZRTSI_CONTROLLER_MT = (SOMFY, SOMFY_ZRTSI) -FIBARO_FGRM222_MT = (FIBARO, FGRM222_SHUTTER2) # List of workarounds by (manufacturer_id, product_type) DEVICE_MAPPINGS_MT = { SOMFY_ZRTSI_CONTROLLER_MT: WORKAROUND_NO_POSITION, - FIBARO_FGRM222_MT: WORKAROUND_REVERSE_OPEN_CLOSE, } diff --git a/tests/components/cover/test_zwave.py b/tests/components/cover/test_zwave.py index 1b4ce015987f12..425331ff35c48a 100644 --- a/tests/components/cover/test_zwave.py +++ b/tests/components/cover/test_zwave.py @@ -120,14 +120,17 @@ def test_roller_commands(mock_network, mock_openzwave): @patch('homeassistant.components.zwave.NETWORK') def test_roller_reverse_open_close(mock_network, mock_openzwave): """Test position changed.""" - node = MockNode(manufacturer_id='010f', product_type='0301') + node = MockNode() value = MockValue(data=50, node=node, command_class=const.COMMAND_CLASS_SWITCH_MULTILEVEL) open_value = MockValue(data=False, node=node) close_value = MockValue(data=False, node=node) values = MockEntityValues(primary=value, open=open_value, close=close_value, node=node) - device = zwave.get_device(node=node, values=values, node_config={}) + device = zwave.get_device( + node=node, + values=values, + node_config={zwave.zwave.CONF_INVERT_OPENCLOSE_BUTTONS: True}) device.open_cover() assert mock_network.manager.pressButton.called From 63c15e997a665624c1d541244ba63bf1bf44bdea Mon Sep 17 00:00:00 2001 From: Oleksii Serdiuk Date: Wed, 29 Mar 2017 06:58:59 +0200 Subject: [PATCH 039/116] history_stats: Fix schema, as `state` can be arbitrary string (#6753) --- homeassistant/components/sensor/history_stats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/sensor/history_stats.py b/homeassistant/components/sensor/history_stats.py index d5a02f8744e58e..fe073b89fcda96 100644 --- a/homeassistant/components/sensor/history_stats.py +++ b/homeassistant/components/sensor/history_stats.py @@ -66,7 +66,7 @@ def exactly_two_period_keys(conf): PLATFORM_SCHEMA = vol.All(PLATFORM_SCHEMA.extend({ vol.Required(CONF_ENTITY_ID): cv.entity_id, - vol.Required(CONF_STATE): cv.slug, + vol.Required(CONF_STATE): cv.string, vol.Optional(CONF_START, default=None): cv.template, vol.Optional(CONF_END, default=None): cv.template, vol.Optional(CONF_DURATION, default=None): cv.time_period, From e1ed076015b0c8904caf208dbe556485131f963b Mon Sep 17 00:00:00 2001 From: Johan Bloemberg Date: Wed, 29 Mar 2017 07:04:25 +0200 Subject: [PATCH 040/116] Rflink group commands (#5969) * Add support for group commands (allon/alloff). Add 'group_aliasses' config attribute that only respond to group commands. Add nogroup_aliases that only respond to 'on' 'off' commands. Allow settings device id group behaviour. * Fix linting. * Fix lint. --- homeassistant/components/light/rflink.py | 32 ++++- homeassistant/components/rflink.py | 35 ++++-- requirements_all.txt | 2 +- tests/components/light/test_rflink.py | 148 +++++++++++++++++++++++ 4 files changed, 200 insertions(+), 17 deletions(-) diff --git a/homeassistant/components/light/rflink.py b/homeassistant/components/light/rflink.py index 0630792602d404..ad25ae6a38d578 100644 --- a/homeassistant/components/light/rflink.py +++ b/homeassistant/components/light/rflink.py @@ -11,11 +11,13 @@ ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, Light) from homeassistant.components.rflink import ( CONF_ALIASSES, CONF_DEVICE_DEFAULTS, CONF_DEVICES, CONF_FIRE_EVENT, - CONF_IGNORE_DEVICES, CONF_SIGNAL_REPETITIONS, DATA_DEVICE_REGISTER, - DATA_ENTITY_LOOKUP, DEVICE_DEFAULTS_SCHEMA, DOMAIN, - EVENT_KEY_COMMAND, EVENT_KEY_ID, SwitchableRflinkDevice, cv, vol) + CONF_GROUP, CONF_GROUP_ALIASSES, CONF_IGNORE_DEVICES, + CONF_NOGROUP_ALIASSES, CONF_SIGNAL_REPETITIONS, DATA_DEVICE_REGISTER, + DATA_ENTITY_GROUP_LOOKUP, DATA_ENTITY_LOOKUP, DEVICE_DEFAULTS_SCHEMA, + DOMAIN, EVENT_KEY_COMMAND, EVENT_KEY_ID, SwitchableRflinkDevice, cv, vol) from homeassistant.const import ( CONF_NAME, CONF_PLATFORM, CONF_TYPE, STATE_UNKNOWN) + DEPENDENCIES = ['rflink'] _LOGGER = logging.getLogger(__name__) @@ -38,8 +40,13 @@ TYPE_HYBRID, TYPE_TOGGLE), vol.Optional(CONF_ALIASSES, default=[]): vol.All(cv.ensure_list, [cv.string]), + vol.Optional(CONF_GROUP_ALIASSES, default=[]): + vol.All(cv.ensure_list, [cv.string]), + vol.Optional(CONF_NOGROUP_ALIASSES, default=[]): + vol.All(cv.ensure_list, [cv.string]), vol.Optional(CONF_FIRE_EVENT, default=False): cv.boolean, vol.Optional(CONF_SIGNAL_REPETITIONS): vol.Coerce(int), + vol.Optional(CONF_GROUP, default=True): cv.boolean, }, }), }) @@ -110,7 +117,24 @@ def devices_from_config(domain_config, hass=None): devices.append(device) # Register entity (and aliasses) to listen to incoming rflink events - for _id in [device_id] + config[CONF_ALIASSES]: + + # device id and normal aliasses respond to normal and group command + hass.data[DATA_ENTITY_LOOKUP][ + EVENT_KEY_COMMAND][device_id].append(device) + if config[CONF_GROUP]: + hass.data[DATA_ENTITY_GROUP_LOOKUP][ + EVENT_KEY_COMMAND][device_id].append(device) + for _id in config[CONF_ALIASSES]: + hass.data[DATA_ENTITY_LOOKUP][ + EVENT_KEY_COMMAND][_id].append(device) + hass.data[DATA_ENTITY_GROUP_LOOKUP][ + EVENT_KEY_COMMAND][_id].append(device) + # group_aliasses only respond to group commands + for _id in config[CONF_GROUP_ALIASSES]: + hass.data[DATA_ENTITY_GROUP_LOOKUP][ + EVENT_KEY_COMMAND][_id].append(device) + # nogroup_aliasses only respond to normal commands + for _id in config[CONF_NOGROUP_ALIASSES]: hass.data[DATA_ENTITY_LOOKUP][ EVENT_KEY_COMMAND][_id].append(device) diff --git a/homeassistant/components/rflink.py b/homeassistant/components/rflink.py index df1ca955a4dddc..2986b898ed0586 100644 --- a/homeassistant/components/rflink.py +++ b/homeassistant/components/rflink.py @@ -20,7 +20,7 @@ import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity -REQUIREMENTS = ['rflink==0.0.28'] +REQUIREMENTS = ['rflink==0.0.31'] _LOGGER = logging.getLogger(__name__) @@ -28,6 +28,9 @@ ATTR_STATE = 'state' CONF_ALIASSES = 'aliasses' +CONF_GROUP_ALIASSES = 'group_aliasses' +CONF_GROUP = 'group' +CONF_NOGROUP_ALIASSES = 'nogroup_aliasses' CONF_DEVICE_DEFAULTS = 'device_defaults' CONF_DEVICES = 'devices' CONF_FIRE_EVENT = 'fire_event' @@ -38,6 +41,7 @@ DATA_DEVICE_REGISTER = 'rflink_device_register' DATA_ENTITY_LOOKUP = 'rflink_entity_lookup' +DATA_ENTITY_GROUP_LOOKUP = 'rflink_entity_group_only_lookup' DEFAULT_RECONNECT_INTERVAL = 10 DEFAULT_SIGNAL_REPETITIONS = 1 CONNECTION_TIMEOUT = 10 @@ -48,6 +52,8 @@ EVENT_KEY_SENSOR = 'sensor' EVENT_KEY_UNIT = 'unit' +RFLINK_GROUP_COMMANDS = ['allon', 'alloff'] + DOMAIN = 'rflink' DEVICE_DEFAULTS_SCHEMA = vol.Schema({ @@ -94,6 +100,10 @@ def async_setup(hass, config): EVENT_KEY_COMMAND: defaultdict(list), EVENT_KEY_SENSOR: defaultdict(list), } + hass.data[DATA_ENTITY_GROUP_LOOKUP] = { + EVENT_KEY_COMMAND: defaultdict(list), + EVENT_KEY_SENSOR: defaultdict(list), + } # Allow platform to specify function to register new unknown devices hass.data[DATA_DEVICE_REGISTER] = {} @@ -116,7 +126,14 @@ def event_callback(event): # Lookup entities who registered this device id as device id or alias event_id = event.get('id', None) - entities = hass.data[DATA_ENTITY_LOOKUP][event_type][event_id] + + is_group_event = (event_type == EVENT_KEY_COMMAND and + event[EVENT_KEY_COMMAND] in RFLINK_GROUP_COMMANDS) + if is_group_event: + entities = hass.data[DATA_ENTITY_GROUP_LOOKUP][event_type].get( + event_id, []) + else: + entities = hass.data[DATA_ENTITY_LOOKUP][event_type][event_id] if entities: # Propagate event to every entity matching the device id @@ -202,8 +219,8 @@ class RflinkDevice(Entity): platform = None _state = STATE_UNKNOWN - def __init__(self, device_id, hass, name=None, - aliasses=None, fire_event=False, + def __init__(self, device_id, hass, name=None, aliasses=None, group=True, + group_aliasses=None, nogroup_aliasses=None, fire_event=False, signal_repetitions=DEFAULT_SIGNAL_REPETITIONS): """Initialize the device.""" self.hass = hass @@ -215,12 +232,6 @@ def __init__(self, device_id, hass, name=None, else: self._name = device_id - # Generate list of device_ids to match against - if aliasses: - self._aliasses = aliasses - else: - self._aliasses = [] - self._should_fire_event = fire_event self._signal_repetitions = signal_repetitions @@ -375,9 +386,9 @@ def _handle_event(self, event): self.cancel_queued_send_commands() command = event['command'] - if command == 'on': + if command in ['on', 'allon']: self._state = True - elif command == 'off': + elif command in ['off', 'alloff']: self._state = False def async_turn_on(self, **kwargs): diff --git a/requirements_all.txt b/requirements_all.txt index ea986259ea823d..dac5add5c94e2e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -659,7 +659,7 @@ qnapstats==0.2.3 radiotherm==1.2 # homeassistant.components.rflink -rflink==0.0.28 +rflink==0.0.31 # homeassistant.components.sensor.ring ring_doorbell==0.1.0 diff --git a/tests/components/light/test_rflink.py b/tests/components/light/test_rflink.py index 2cd6d6fd092400..9f1d98b0ffd5c2 100644 --- a/tests/components/light/test_rflink.py +++ b/tests/components/light/test_rflink.py @@ -81,6 +81,25 @@ def test_default_setup(hass, monkeypatch): assert hass.states.get('light.test').state == 'off' + # should repond to group command + event_callback({ + 'id': 'protocol_0_0', + 'command': 'allon', + }) + yield from hass.async_block_till_done() + + light_after_first_command = hass.states.get('light.test') + assert light_after_first_command.state == 'on' + + # should repond to group command + event_callback({ + 'id': 'protocol_0_0', + 'command': 'alloff', + }) + yield from hass.async_block_till_done() + + assert hass.states.get('light.test').state == 'off' + # test following aliasses # mock incoming command event for this device alias event_callback({ @@ -385,3 +404,132 @@ def test_type_toggle(hass, monkeypatch): yield from hass.async_block_till_done() assert hass.states.get('light.toggle_test').state == 'off' + + +@asyncio.coroutine +def test_group_alias(hass, monkeypatch): + """Group aliases should only respond to group commands (allon/alloff).""" + config = { + 'rflink': { + 'port': '/dev/ttyABC0', + }, + DOMAIN: { + 'platform': 'rflink', + 'devices': { + 'protocol_0_0': { + 'name': 'test', + 'group_aliasses': ['test_group_0_0'], + }, + }, + }, + } + + # setup mocking rflink module + event_callback, _, _, _ = yield from mock_rflink( + hass, config, DOMAIN, monkeypatch) + + assert hass.states.get('light.test').state == 'off' + + # test sending group command to group alias + event_callback({ + 'id': 'test_group_0_0', + 'command': 'allon', + }) + yield from hass.async_block_till_done() + + assert hass.states.get('light.test').state == 'on' + + # test sending group command to group alias + event_callback({ + 'id': 'test_group_0_0', + 'command': 'off', + }) + yield from hass.async_block_till_done() + + assert hass.states.get('light.test').state == 'on' + + +@asyncio.coroutine +def test_nogroup_alias(hass, monkeypatch): + """Non group aliases should not respond to group commands.""" + config = { + 'rflink': { + 'port': '/dev/ttyABC0', + }, + DOMAIN: { + 'platform': 'rflink', + 'devices': { + 'protocol_0_0': { + 'name': 'test', + 'nogroup_aliasses': ['test_nogroup_0_0'], + }, + }, + }, + } + + # setup mocking rflink module + event_callback, _, _, _ = yield from mock_rflink( + hass, config, DOMAIN, monkeypatch) + + assert hass.states.get('light.test').state == 'off' + + # test sending group command to nogroup alias + event_callback({ + 'id': 'test_nogroup_0_0', + 'command': 'allon', + }) + yield from hass.async_block_till_done() + # should not affect state + assert hass.states.get('light.test').state == 'off' + + # test sending group command to nogroup alias + event_callback({ + 'id': 'test_nogroup_0_0', + 'command': 'on', + }) + yield from hass.async_block_till_done() + # should affect state + assert hass.states.get('light.test').state == 'on' + + +@asyncio.coroutine +def test_nogroup_device_id(hass, monkeypatch): + """Device id that do not respond to group commands (allon/alloff).""" + config = { + 'rflink': { + 'port': '/dev/ttyABC0', + }, + DOMAIN: { + 'platform': 'rflink', + 'devices': { + 'test_nogroup_0_0': { + 'name': 'test', + 'group': False, + }, + }, + }, + } + + # setup mocking rflink module + event_callback, _, _, _ = yield from mock_rflink( + hass, config, DOMAIN, monkeypatch) + + assert hass.states.get('light.test').state == 'off' + + # test sending group command to nogroup + event_callback({ + 'id': 'test_nogroup_0_0', + 'command': 'allon', + }) + yield from hass.async_block_till_done() + # should not affect state + assert hass.states.get('light.test').state == 'off' + + # test sending group command to nogroup + event_callback({ + 'id': 'test_nogroup_0_0', + 'command': 'on', + }) + yield from hass.async_block_till_done() + # should affect state + assert hass.states.get('light.test').state == 'on' From d1b519a41809edc9dfbb1d1706cbb3e2b583f724 Mon Sep 17 00:00:00 2001 From: Xorso Date: Wed, 29 Mar 2017 00:21:40 -0600 Subject: [PATCH 041/116] Updating Alarm.com Component for async and no Selenium (#6752) * Updating Alarm.com Component for async and no Selenium * Fixed gen_all_requirements --- .../alarm_control_panel/alarmdotcom.py | 91 ++++++++++--------- requirements_all.txt | 6 +- 2 files changed, 51 insertions(+), 46 deletions(-) diff --git a/homeassistant/components/alarm_control_panel/alarmdotcom.py b/homeassistant/components/alarm_control_panel/alarmdotcom.py index 07f90cf44763d5..22cbdefd40399e 100644 --- a/homeassistant/components/alarm_control_panel/alarmdotcom.py +++ b/homeassistant/components/alarm_control_panel/alarmdotcom.py @@ -1,13 +1,13 @@ """ + Interfaces with Alarm.com alarm control panels. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/alarm_control_panel.alarmdotcom/ """ import logging - +import asyncio import voluptuous as vol - import homeassistant.components.alarm_control_panel as alarm from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA from homeassistant.const import ( @@ -15,10 +15,9 @@ STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_UNKNOWN, CONF_CODE, CONF_NAME) import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.aiohttp_client import async_get_clientsession -REQUIREMENTS = ['https://github.com/Xorso/pyalarmdotcom' - '/archive/0.1.1.zip' - '#pyalarmdotcom==0.1.1'] +REQUIREMENTS = ['pyalarmdotcom==0.2.9'] _LOGGER = logging.getLogger(__name__) @@ -32,14 +31,17 @@ }) -def setup_platform(hass, config, add_devices, discovery_info=None): - """Setup an Alarm.com control panel.""" +@asyncio.coroutine +def async_setup_platform(hass, config, async_add_devices, discovery_info=None): + """Setup a Alarm.com control panel.""" name = config.get(CONF_NAME) code = config.get(CONF_CODE) username = config.get(CONF_USERNAME) password = config.get(CONF_PASSWORD) - add_devices([AlarmDotCom(hass, name, code, username, password)], True) + alarmdotcom = AlarmDotCom(hass, name, code, username, password) + yield from alarmdotcom.async_login() + async_add_devices([alarmdotcom]) class AlarmDotCom(alarm.AlarmControlPanel): @@ -47,18 +49,30 @@ class AlarmDotCom(alarm.AlarmControlPanel): def __init__(self, hass, name, code, username, password): """Initialize the Alarm.com status.""" - from pyalarmdotcom.pyalarmdotcom import Alarmdotcom - self._alarm = Alarmdotcom(username, password, timeout=10) + from pyalarmdotcom import Alarmdotcom + _LOGGER.debug('Setting up Alarm.com...') self._hass = hass self._name = name self._code = str(code) if code else None self._username = username self._password = password + self._websession = async_get_clientsession(self._hass) self._state = STATE_UNKNOWN - - def update(self): + self._alarm = Alarmdotcom(username, + password, + self._websession, + hass.loop) + + @asyncio.coroutine + def async_login(self): + """Login to Alarm.com.""" + yield from self._alarm.async_login() + + @asyncio.coroutine + def async_update(self): """Fetch the latest state.""" - self._state = self._alarm.state + yield from self._alarm.async_update() + return self._alarm.state @property def name(self): @@ -73,45 +87,36 @@ def code_format(self): @property def state(self): """Return the state of the device.""" - if self._state == 'Disarmed': + if self._alarm.state.lower() == 'disarmed': return STATE_ALARM_DISARMED - elif self._state == 'Armed Stay': + elif self._alarm.state.lower() == 'armed stay': return STATE_ALARM_ARMED_HOME - elif self._state == 'Armed Away': + elif self._alarm.state.lower() == 'armed away': return STATE_ALARM_ARMED_AWAY else: return STATE_UNKNOWN - def alarm_disarm(self, code=None): + @asyncio.coroutine + def async_alarm_disarm(self, code=None): """Send disarm command.""" - if not self._validate_code(code, 'disarming home'): - return - from pyalarmdotcom.pyalarmdotcom import Alarmdotcom - # Open another session to alarm.com to fire off the command - _alarm = Alarmdotcom(self._username, self._password, timeout=10) - _alarm.disarm() - - def alarm_arm_home(self, code=None): - """Send arm home command.""" - if not self._validate_code(code, 'arming home'): - return - from pyalarmdotcom.pyalarmdotcom import Alarmdotcom - # Open another session to alarm.com to fire off the command - _alarm = Alarmdotcom(self._username, self._password, timeout=10) - _alarm.arm_stay() - - def alarm_arm_away(self, code=None): + if self._validate_code(code): + yield from self._alarm.async_alarm_disarm() + + @asyncio.coroutine + def async_alarm_arm_home(self, code=None): + """Send arm hom command.""" + if self._validate_code(code): + yield from self._alarm.async_alarm_arm_home() + + @asyncio.coroutine + def async_alarm_arm_away(self, code=None): """Send arm away command.""" - if not self._validate_code(code, 'arming home'): - return - from pyalarmdotcom.pyalarmdotcom import Alarmdotcom - # Open another session to alarm.com to fire off the command - _alarm = Alarmdotcom(self._username, self._password, timeout=10) - _alarm.arm_away() - - def _validate_code(self, code, state): + if self._validate_code(code): + yield from self._alarm.async_alarm_arm_away() + + def _validate_code(self, code): """Validate given code.""" check = self._code is None or code == self._code if not check: - _LOGGER.warning('Wrong code entered for %s', state) + _LOGGER.warning('Wrong code entered.') return check diff --git a/requirements_all.txt b/requirements_all.txt index dac5add5c94e2e..2c3301671a35d9 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -236,9 +236,6 @@ https://github.com/TheRealLink/pylgtv/archive/v0.1.4.zip#pylgtv==0.1.4 # homeassistant.components.switch.thinkingcleaner https://github.com/TheRealLink/pythinkingcleaner/archive/v0.0.2.zip#pythinkingcleaner==0.0.2 -# homeassistant.components.alarm_control_panel.alarmdotcom -https://github.com/Xorso/pyalarmdotcom/archive/0.1.1.zip#pyalarmdotcom==0.1.1 - # homeassistant.components.media_player.braviatv https://github.com/aparraga/braviarc/archive/0.3.6.zip#braviarc==0.3.6 @@ -464,6 +461,9 @@ pyHS100==0.2.4.1 # homeassistant.components.rfxtrx pyRFXtrx==0.17.0 +# homeassistant.components.alarm_control_panel.alarmdotcom +pyalarmdotcom==0.2.9 + # homeassistant.components.notify.xmpp pyasn1-modules==0.0.8 From 7c614a67389b76c8d73c2e169bf4778e95c7aa03 Mon Sep 17 00:00:00 2001 From: Martin Hjelmare Date: Wed, 29 Mar 2017 08:39:53 +0200 Subject: [PATCH 042/116] Add voluptuous config validation to scenes (#6830) * Add platform schema to scene component and homeassistant platform. * Clean up code and add constants. * Add unit test and clean up tests. --- homeassistant/components/scene/__init__.py | 54 +++++++---- .../components/scene/homeassistant.py | 44 +++++---- tests/components/scene/test_init.py | 96 +++++++++++-------- 3 files changed, 117 insertions(+), 77 deletions(-) diff --git a/homeassistant/components/scene/__init__.py b/homeassistant/components/scene/__init__.py index 1abe6432409598..0d407ac3a9aa47 100644 --- a/homeassistant/components/scene/__init__.py +++ b/homeassistant/components/scene/__init__.py @@ -6,28 +6,55 @@ """ import asyncio import logging -from collections import namedtuple import voluptuous as vol from homeassistant.const import ( - ATTR_ENTITY_ID, SERVICE_TURN_ON, CONF_PLATFORM) -from homeassistant.helpers import extract_domain_configs + ATTR_ENTITY_ID, CONF_PLATFORM, SERVICE_TURN_ON) import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_component import EntityComponent +from homeassistant.helpers.state import HASS_DOMAIN +from homeassistant.loader import get_platform DOMAIN = 'scene' STATE = 'scening' +STATES = 'states' -CONF_ENTITIES = "entities" + +def _hass_domain_validator(config): + """Validate platform in config for homeassistant domain.""" + if CONF_PLATFORM not in config: + config = { + CONF_PLATFORM: HASS_DOMAIN, STATES: config} + + return config + + +def _platform_validator(config): + """Validate it is a valid platform.""" + p_name = config[CONF_PLATFORM] + platform = get_platform(DOMAIN, p_name) + + if not hasattr(platform, 'PLATFORM_SCHEMA'): + return config + + return getattr(platform, 'PLATFORM_SCHEMA')(config) + + +PLATFORM_SCHEMA = vol.Schema( + vol.All( + _hass_domain_validator, + vol.Schema({ + vol.Required(CONF_PLATFORM): cv.platform_validator(DOMAIN) + }, extra=vol.ALLOW_EXTRA), + _platform_validator + ), extra=vol.ALLOW_EXTRA) SCENE_SERVICE_SCHEMA = vol.Schema({ vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, }) -SceneConfig = namedtuple('SceneConfig', ['name', 'states']) - def activate(hass, entity_id=None): """Activate a scene.""" @@ -43,21 +70,6 @@ def activate(hass, entity_id=None): def async_setup(hass, config): """Setup scenes.""" logger = logging.getLogger(__name__) - - # You are not allowed to mutate the original config so make a copy - config = dict(config) - - for config_key in extract_domain_configs(config, DOMAIN): - platform_config = config[config_key] - if not isinstance(platform_config, list): - platform_config = [platform_config] - - if not any(CONF_PLATFORM in entry for entry in platform_config): - platform_config = [{'platform': 'homeassistant', 'states': entry} - for entry in platform_config] - - config[config_key] = platform_config - component = EntityComponent(logger, DOMAIN, hass) yield from component.async_setup(config) diff --git a/homeassistant/components/scene/homeassistant.py b/homeassistant/components/scene/homeassistant.py index 2081dfe89ab83d..39942eea301cc3 100644 --- a/homeassistant/components/scene/homeassistant.py +++ b/homeassistant/components/scene/homeassistant.py @@ -7,26 +7,38 @@ import asyncio from collections import namedtuple -from homeassistant.components.scene import Scene +import voluptuous as vol + +import homeassistant.helpers.config_validation as cv +from homeassistant.components.scene import Scene, STATES from homeassistant.const import ( - ATTR_ENTITY_ID, STATE_OFF, STATE_ON) + ATTR_ENTITY_ID, ATTR_STATE, CONF_ENTITIES, CONF_NAME, CONF_PLATFORM, + STATE_OFF, STATE_ON) from homeassistant.core import State -from homeassistant.helpers.state import async_reproduce_state - -STATE = 'scening' - -CONF_ENTITIES = "entities" - -SceneConfig = namedtuple('SceneConfig', ['name', 'states']) +from homeassistant.helpers.state import async_reproduce_state, HASS_DOMAIN + +PLATFORM_SCHEMA = vol.Schema({ + vol.Required(CONF_PLATFORM): HASS_DOMAIN, + vol.Required(STATES): vol.All( + cv.ensure_list, + [ + { + vol.Required(CONF_NAME): cv.string, + vol.Required(CONF_ENTITIES): { + cv.entity_id: vol.Any(str, bool, dict) + }, + } + ] + ), +}, extra=vol.ALLOW_EXTRA) + +SCENECONFIG = namedtuple('SceneConfig', [CONF_NAME, STATES]) @asyncio.coroutine def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Setup home assistant scene entries.""" - scene_config = config.get("states") - - if not isinstance(scene_config, list): - scene_config = [scene_config] + scene_config = config.get(STATES) async_add_devices(HomeAssistantScene( hass, _process_config(scene)) for scene in scene_config) @@ -38,7 +50,7 @@ def _process_config(scene_config): Async friendly. """ - name = scene_config.get('name') + name = scene_config.get(CONF_NAME) states = {} c_entities = dict(scene_config.get(CONF_ENTITIES, {})) @@ -46,7 +58,7 @@ def _process_config(scene_config): for entity_id in c_entities: if isinstance(c_entities[entity_id], dict): entity_attrs = c_entities[entity_id].copy() - state = entity_attrs.pop('state', None) + state = entity_attrs.pop(ATTR_STATE, None) attributes = entity_attrs else: state = c_entities[entity_id] @@ -61,7 +73,7 @@ def _process_config(scene_config): states[entity_id.lower()] = State(entity_id, state, attributes) - return SceneConfig(name, states) + return SCENECONFIG(name, states) class HomeAssistantScene(Scene): diff --git a/tests/components/scene/test_init.py b/tests/components/scene/test_init.py index d84d6ad37f468e..25ea818c774d69 100644 --- a/tests/components/scene/test_init.py +++ b/tests/components/scene/test_init.py @@ -1,9 +1,11 @@ """The tests for the Scene component.""" +import io import unittest from homeassistant.setup import setup_component from homeassistant import loader from homeassistant.components import light, scene +from homeassistant.util import yaml from tests.common import get_test_home_assistant @@ -14,6 +16,22 @@ class TestScene(unittest.TestCase): def setUp(self): # pylint: disable=invalid-name """Setup things to be run when tests are started.""" self.hass = get_test_home_assistant() + test_light = loader.get_component('light.test') + test_light.init() + + self.assertTrue(setup_component(self.hass, light.DOMAIN, { + light.DOMAIN: {'platform': 'test'} + })) + + self.light_1, self.light_2 = test_light.DEVICES[0:2] + + light.turn_off( + self.hass, [self.light_1.entity_id, self.light_2.entity_id]) + + self.hass.block_till_done() + + self.assertFalse(self.light_1.is_on) + self.assertFalse(self.light_2.is_on) def tearDown(self): # pylint: disable=invalid-name """Stop everything that was started.""" @@ -36,19 +54,6 @@ def test_config_yaml_alias_anchor(self): reference to the original dictionary, instead of creating a copy, so care needs to be taken to not modify the original. """ - test_light = loader.get_component('light.test') - test_light.init() - - self.assertTrue(setup_component(self.hass, light.DOMAIN, { - light.DOMAIN: {'platform': 'test'} - })) - - light_1, light_2 = test_light.DEVICES[0:2] - - light.turn_off(self.hass, [light_1.entity_id, light_2.entity_id]) - - self.hass.block_till_done() - entity_state = { 'state': 'on', 'brightness': 100, @@ -57,8 +62,8 @@ def test_config_yaml_alias_anchor(self): 'scene': [{ 'name': 'test', 'entities': { - light_1.entity_id: entity_state, - light_2.entity_id: entity_state, + self.light_1.entity_id: entity_state, + self.light_2.entity_id: entity_state, } }] })) @@ -66,34 +71,45 @@ def test_config_yaml_alias_anchor(self): scene.activate(self.hass, 'scene.test') self.hass.block_till_done() - self.assertTrue(light_1.is_on) - self.assertTrue(light_2.is_on) - self.assertEqual(100, - light_1.last_call('turn_on')[1].get('brightness')) - self.assertEqual(100, - light_2.last_call('turn_on')[1].get('brightness')) + self.assertTrue(self.light_1.is_on) + self.assertTrue(self.light_2.is_on) + self.assertEqual( + 100, self.light_1.last_call('turn_on')[1].get('brightness')) + self.assertEqual( + 100, self.light_2.last_call('turn_on')[1].get('brightness')) + + def test_config_yaml_bool(self): + """Test parsing of booleans in yaml config.""" + config = ( + 'scene:\n' + ' - name: test\n' + ' entities:\n' + ' {0}: on\n' + ' {1}:\n' + ' state: on\n' + ' brightness: 100\n').format( + self.light_1.entity_id, self.light_2.entity_id) + + with io.StringIO(config) as file: + doc = yaml.yaml.safe_load(file) + + self.assertTrue(setup_component(self.hass, scene.DOMAIN, doc)) + scene.activate(self.hass, 'scene.test') + self.hass.block_till_done() + + self.assertTrue(self.light_1.is_on) + self.assertTrue(self.light_2.is_on) + self.assertEqual( + 100, self.light_2.last_call('turn_on')[1].get('brightness')) def test_activate_scene(self): """Test active scene.""" - test_light = loader.get_component('light.test') - test_light.init() - - self.assertTrue(setup_component(self.hass, light.DOMAIN, { - light.DOMAIN: {'platform': 'test'} - })) - - light_1, light_2 = test_light.DEVICES[0:2] - - light.turn_off(self.hass, [light_1.entity_id, light_2.entity_id]) - - self.hass.block_till_done() - self.assertTrue(setup_component(self.hass, scene.DOMAIN, { 'scene': [{ 'name': 'test', 'entities': { - light_1.entity_id: 'on', - light_2.entity_id: { + self.light_1.entity_id: 'on', + self.light_2.entity_id: { 'state': 'on', 'brightness': 100, } @@ -104,7 +120,7 @@ def test_activate_scene(self): scene.activate(self.hass, 'scene.test') self.hass.block_till_done() - self.assertTrue(light_1.is_on) - self.assertTrue(light_2.is_on) - self.assertEqual(100, - light_2.last_call('turn_on')[1].get('brightness')) + self.assertTrue(self.light_1.is_on) + self.assertTrue(self.light_2.is_on) + self.assertEqual( + 100, self.light_2.last_call('turn_on')[1].get('brightness')) From c935bfce2ac447adf387a8e9e69cbdf755d31727 Mon Sep 17 00:00:00 2001 From: Anubhaw Arya Date: Wed, 29 Mar 2017 08:25:23 -0700 Subject: [PATCH 043/116] Integration with lockitron (#6805) * Integration with lockitron * Let super class deal with polling and updating --- .coveragerc | 1 + homeassistant/components/lock/lockitron.py | 92 ++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 homeassistant/components/lock/lockitron.py diff --git a/.coveragerc b/.coveragerc index fac7edfa42b816..c6bf3d197ae4dc 100644 --- a/.coveragerc +++ b/.coveragerc @@ -235,6 +235,7 @@ omit = homeassistant/components/light/zengge.py homeassistant/components/lirc.py homeassistant/components/lock/nuki.py + homeassistant/components/lock/lockitron.py homeassistant/components/media_player/anthemav.py homeassistant/components/media_player/apple_tv.py homeassistant/components/media_player/aquostv.py diff --git a/homeassistant/components/lock/lockitron.py b/homeassistant/components/lock/lockitron.py new file mode 100644 index 00000000000000..86821711fd2075 --- /dev/null +++ b/homeassistant/components/lock/lockitron.py @@ -0,0 +1,92 @@ +""" +Lockitron lock platform. + +For more details about this platform, please refer to the documentation +https://home-assistant.io/components/lockitron/ +""" +import logging + +import requests +import voluptuous as vol + +import homeassistant.helpers.config_validation as cv +from homeassistant.components.lock import LockDevice, PLATFORM_SCHEMA +from homeassistant.const import CONF_ACCESS_TOKEN, CONF_ID + +_LOGGER = logging.getLogger(__name__) + +DOMAIN = 'lockitron' + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_ACCESS_TOKEN): cv.string, + vol.Required(CONF_ID): cv.string +}) +BASE_URL = 'https://api.lockitron.com' +API_STATE_URL = BASE_URL + '/v2/locks/{}?access_token={}' +API_ACTION_URL = BASE_URL + '/v2/locks/{}?access_token={}&state={}' + + +# pylint: disable=unused-argument +def setup_platform(hass, config, add_devices, discovery_info=None): + """Setup the Lockitron platform.""" + access_token = config.get(CONF_ACCESS_TOKEN) + device_id = config.get(CONF_ID) + response = requests.get(API_STATE_URL.format(device_id, access_token)) + if response.status_code == 200: + add_devices([Lockitron(response.json()['state'], access_token, + device_id)]) + else: + _LOGGER.error('Error retrieving lock status during init: %s', + response.text) + + +class Lockitron(LockDevice): + """Representation of a Lockitron lock.""" + + LOCK_STATE = 'lock' + UNLOCK_STATE = 'unlock' + + def __init__(self, state, access_token, device_id): + """Initialize the lock.""" + self._state = state + self.access_token = access_token + self.device_id = device_id + + @property + def name(self): + """Return the name of the device.""" + return DOMAIN + + @property + def is_locked(self): + """Return True if the lock is currently locked, else False.""" + return self._state == Lockitron.LOCK_STATE + + def lock(self, **kwargs): + """Lock the device.""" + self._state = self.do_change_request(Lockitron.LOCK_STATE) + + def unlock(self, **kwargs): + """Unlock the device.""" + self._state = self.do_change_request(Lockitron.UNLOCK_STATE) + + def update(self): + """Update the internal state of the device.""" + response = requests \ + .get(API_STATE_URL.format(self.device_id, self.access_token)) + if response.status_code == 200: + self._state = response.json()['state'] + else: + _LOGGER.error('Error retrieving lock status: %s', response.text) + + def do_change_request(self, requested_state): + """Execute the change request and pull out the new state.""" + response = requests.put( + API_ACTION_URL.format(self.device_id, self.access_token, + requested_state)) + if response.status_code == 200: + return response.json()['state'] + else: + _LOGGER.error('Error setting lock state: %s\n%s', + requested_state, response.text) + return self._state From 9de4c2b056db06b262f70d758241cf7f2f653d20 Mon Sep 17 00:00:00 2001 From: Lewis Juggins Date: Wed, 29 Mar 2017 20:49:28 +0100 Subject: [PATCH 044/116] [switch.wemo] Fix today_energy_kwh calculation. (#6846) * [switch.wemo] Fix today_energy_kwh calculation. * Blank line fail * Round to two decimal places. --- homeassistant/components/switch/wemo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/switch/wemo.py b/homeassistant/components/switch/wemo.py index 7518a1958cff00..0e40c3eff3bcac 100644 --- a/homeassistant/components/switch/wemo.py +++ b/homeassistant/components/switch/wemo.py @@ -149,7 +149,7 @@ def today_energy_kwh(self): """Today total energy usage in kWh.""" if self.insight_params: miliwatts = convert(self.insight_params['todaymw'], float, 0.0) - return miliwatts / 1000000.0 + return round(miliwatts / (1000.0 * 1000.0 * 60), 2) @property def detail_state(self): From bfe0aee468d8726ee008fbf4ba1c0364e11cd002 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 29 Mar 2017 22:19:58 -0700 Subject: [PATCH 045/116] Locative tests to use aiohttp test utils (#6838) --- .../components/device_tracker/locative.py | 3 +- .../device_tracker/test_locative.py | 409 ++++++++---------- 2 files changed, 194 insertions(+), 218 deletions(-) diff --git a/homeassistant/components/device_tracker/locative.py b/homeassistant/components/device_tracker/locative.py index 75cebbd95e7468..255440a18e1530 100644 --- a/homeassistant/components/device_tracker/locative.py +++ b/homeassistant/components/device_tracker/locative.py @@ -18,6 +18,7 @@ _LOGGER = logging.getLogger(__name__) DEPENDENCIES = ['http'] +URL = '/api/locative' def setup_scanner(hass, config, see, discovery_info=None): @@ -30,7 +31,7 @@ def setup_scanner(hass, config, see, discovery_info=None): class LocativeView(HomeAssistantView): """View to handle locative requests.""" - url = '/api/locative' + url = URL name = 'api:locative' def __init__(self, see): diff --git a/tests/components/device_tracker/test_locative.py b/tests/components/device_tracker/test_locative.py index 5f3f12ba82a4a8..2476247e069bd4 100644 --- a/tests/components/device_tracker/test_locative.py +++ b/tests/components/device_tracker/test_locative.py @@ -1,21 +1,13 @@ """The tests the for Locative device tracker platform.""" -import unittest +import asyncio from unittest.mock import patch -import requests +import pytest -from homeassistant import setup, const +from homeassistant.setup import async_setup_component import homeassistant.components.device_tracker as device_tracker -import homeassistant.components.http as http from homeassistant.const import CONF_PLATFORM - -from tests.common import ( - assert_setup_component, get_test_home_assistant, get_test_instance_port) - -SERVER_PORT = get_test_instance_port() -HTTP_BASE_URL = "http://127.0.0.1:{}".format(SERVER_PORT) - -hass = None # pylint: disable=invalid-name +from homeassistant.components.device_tracker.locative import URL def _url(data=None): @@ -23,213 +15,196 @@ def _url(data=None): data = data or {} data = "&".join(["{}={}".format(name, value) for name, value in data.items()]) - return "{}{}locative?{}".format(HTTP_BASE_URL, const.URL_API, data) - - -# pylint: disable=invalid-name -def setUpModule(): - """Initalize a Home Assistant server.""" - global hass + return "{}?{}".format(URL, data) - hass = get_test_home_assistant() - # http is not platform based, assert_setup_component not applicable - setup.setup_component(hass, http.DOMAIN, { - http.DOMAIN: { - http.CONF_SERVER_PORT: SERVER_PORT - }, - }) - # Set up device tracker - with assert_setup_component(1, device_tracker.DOMAIN): - setup.setup_component(hass, device_tracker.DOMAIN, { +@pytest.fixture +def locative_client(loop, hass, test_client): + """Locative mock client.""" + assert loop.run_until_complete(async_setup_component( + hass, device_tracker.DOMAIN, { device_tracker.DOMAIN: { CONF_PLATFORM: 'locative' } - }) - - hass.start() - - -def tearDownModule(): # pylint: disable=invalid-name - """Stop the Home Assistant server.""" - hass.stop() - - -# Stub out update_config or else Travis CI raises an exception -@patch('homeassistant.components.device_tracker.update_config') -class TestLocative(unittest.TestCase): - """Test Locative platform.""" - - def tearDown(self): - """Stop everything that was started.""" - hass.block_till_done() - - def test_missing_data(self, update_config): - """Test missing data.""" - data = { - 'latitude': 1.0, - 'longitude': 1.1, - 'device': '123', - 'id': 'Home', - 'trigger': 'enter' - } - - # No data - req = requests.get(_url({})) - self.assertEqual(422, req.status_code) - - # No latitude - copy = data.copy() - del copy['latitude'] - req = requests.get(_url(copy)) - self.assertEqual(422, req.status_code) - - # No device - copy = data.copy() - del copy['device'] - req = requests.get(_url(copy)) - self.assertEqual(422, req.status_code) - - # No location - copy = data.copy() - del copy['id'] - req = requests.get(_url(copy)) - self.assertEqual(422, req.status_code) - - # No trigger - copy = data.copy() - del copy['trigger'] - req = requests.get(_url(copy)) - self.assertEqual(422, req.status_code) - - # Test message - copy = data.copy() - copy['trigger'] = 'test' - req = requests.get(_url(copy)) - self.assertEqual(200, req.status_code) - - # Test message, no location - copy = data.copy() - copy['trigger'] = 'test' - del copy['id'] - req = requests.get(_url(copy)) - self.assertEqual(200, req.status_code) - - # Unknown trigger - copy = data.copy() - copy['trigger'] = 'foobar' - req = requests.get(_url(copy)) - self.assertEqual(422, req.status_code) - - def test_enter_and_exit(self, update_config): - """Test when there is a known zone.""" - data = { - 'latitude': 40.7855, - 'longitude': -111.7367, - 'device': '123', - 'id': 'Home', - 'trigger': 'enter' - } - - # Enter the Home - req = requests.get(_url(data)) - self.assertEqual(200, req.status_code) - state_name = hass.states.get('{}.{}'.format('device_tracker', - data['device'])).state - self.assertEqual(state_name, 'home') - - data['id'] = 'HOME' - data['trigger'] = 'exit' - - # Exit Home - req = requests.get(_url(data)) - self.assertEqual(200, req.status_code) - state_name = hass.states.get('{}.{}'.format('device_tracker', - data['device'])).state - self.assertEqual(state_name, 'not_home') - - data['id'] = 'hOmE' - data['trigger'] = 'enter' - - # Enter Home again - req = requests.get(_url(data)) - self.assertEqual(200, req.status_code) - state_name = hass.states.get('{}.{}'.format('device_tracker', - data['device'])).state - self.assertEqual(state_name, 'home') - - data['trigger'] = 'exit' - - # Exit Home - req = requests.get(_url(data)) - self.assertEqual(200, req.status_code) - state_name = hass.states.get('{}.{}'.format('device_tracker', - data['device'])).state - self.assertEqual(state_name, 'not_home') - - data['id'] = 'work' - data['trigger'] = 'enter' - - # Enter Work - req = requests.get(_url(data)) - self.assertEqual(200, req.status_code) - state_name = hass.states.get('{}.{}'.format('device_tracker', - data['device'])).state - self.assertEqual(state_name, 'work') - - def test_exit_after_enter(self, update_config): - """Test when an exit message comes after an enter message.""" - data = { - 'latitude': 40.7855, - 'longitude': -111.7367, - 'device': '123', - 'id': 'Home', - 'trigger': 'enter' - } - - # Enter Home - req = requests.get(_url(data)) - self.assertEqual(200, req.status_code) - - state = hass.states.get('{}.{}'.format('device_tracker', - data['device'])) - self.assertEqual(state.state, 'home') - - data['id'] = 'Work' - - # Enter Work - req = requests.get(_url(data)) - self.assertEqual(200, req.status_code) - - state = hass.states.get('{}.{}'.format('device_tracker', - data['device'])) - self.assertEqual(state.state, 'work') - - data['id'] = 'Home' - data['trigger'] = 'exit' - - # Exit Home - req = requests.get(_url(data)) - self.assertEqual(200, req.status_code) - - state = hass.states.get('{}.{}'.format('device_tracker', - data['device'])) - self.assertEqual(state.state, 'work') - - def test_exit_first(self, update_config): - """Test when an exit message is sent first on a new device.""" - data = { - 'latitude': 40.7855, - 'longitude': -111.7367, - 'device': 'new_device', - 'id': 'Home', - 'trigger': 'exit' - } - - # Exit Home - req = requests.get(_url(data)) - self.assertEqual(200, req.status_code) - - state = hass.states.get('{}.{}'.format('device_tracker', - data['device'])) - self.assertEqual(state.state, 'not_home') + })) + + with patch('homeassistant.components.device_tracker.update_config'): + yield loop.run_until_complete(test_client(hass.http.app)) + + +@asyncio.coroutine +def test_missing_data(locative_client): + """Test missing data.""" + data = { + 'latitude': 1.0, + 'longitude': 1.1, + 'device': '123', + 'id': 'Home', + 'trigger': 'enter' + } + + # No data + req = yield from locative_client.get(_url({})) + assert req.status == 422 + + # No latitude + copy = data.copy() + del copy['latitude'] + req = yield from locative_client.get(_url(copy)) + assert req.status == 422 + + # No device + copy = data.copy() + del copy['device'] + req = yield from locative_client.get(_url(copy)) + assert req.status == 422 + + # No location + copy = data.copy() + del copy['id'] + req = yield from locative_client.get(_url(copy)) + assert req.status == 422 + + # No trigger + copy = data.copy() + del copy['trigger'] + req = yield from locative_client.get(_url(copy)) + assert req.status == 422 + + # Test message + copy = data.copy() + copy['trigger'] = 'test' + req = yield from locative_client.get(_url(copy)) + assert req.status == 200 + + # Test message, no location + copy = data.copy() + copy['trigger'] = 'test' + del copy['id'] + req = yield from locative_client.get(_url(copy)) + assert req.status == 200 + + # Unknown trigger + copy = data.copy() + copy['trigger'] = 'foobar' + req = yield from locative_client.get(_url(copy)) + assert req.status == 422 + + +@asyncio.coroutine +def test_enter_and_exit(hass, locative_client): + """Test when there is a known zone.""" + data = { + 'latitude': 40.7855, + 'longitude': -111.7367, + 'device': '123', + 'id': 'Home', + 'trigger': 'enter' + } + + # Enter the Home + req = yield from locative_client.get(_url(data)) + assert req.status == 200 + state_name = hass.states.get('{}.{}'.format('device_tracker', + data['device'])).state + assert 'home' == state_name + + data['id'] = 'HOME' + data['trigger'] = 'exit' + + # Exit Home + req = yield from locative_client.get(_url(data)) + assert req.status == 200 + state_name = hass.states.get('{}.{}'.format('device_tracker', + data['device'])).state + assert 'not_home' == state_name + + data['id'] = 'hOmE' + data['trigger'] = 'enter' + + # Enter Home again + req = yield from locative_client.get(_url(data)) + assert req.status == 200 + state_name = hass.states.get('{}.{}'.format('device_tracker', + data['device'])).state + assert 'home' == state_name + + data['trigger'] = 'exit' + + # Exit Home + req = yield from locative_client.get(_url(data)) + assert req.status == 200 + state_name = hass.states.get('{}.{}'.format('device_tracker', + data['device'])).state + assert 'not_home' == state_name + + data['id'] = 'work' + data['trigger'] = 'enter' + + # Enter Work + req = yield from locative_client.get(_url(data)) + assert req.status == 200 + state_name = hass.states.get('{}.{}'.format('device_tracker', + data['device'])).state + assert 'work' == state_name + + +@asyncio.coroutine +def test_exit_after_enter(hass, locative_client): + """Test when an exit message comes after an enter message.""" + data = { + 'latitude': 40.7855, + 'longitude': -111.7367, + 'device': '123', + 'id': 'Home', + 'trigger': 'enter' + } + + # Enter Home + req = yield from locative_client.get(_url(data)) + assert req.status == 200 + + state = hass.states.get('{}.{}'.format('device_tracker', + data['device'])) + assert state.state == 'home' + + data['id'] = 'Work' + + # Enter Work + req = yield from locative_client.get(_url(data)) + assert req.status == 200 + + state = hass.states.get('{}.{}'.format('device_tracker', + data['device'])) + assert state.state == 'work' + + data['id'] = 'Home' + data['trigger'] = 'exit' + + # Exit Home + req = yield from locative_client.get(_url(data)) + assert req.status == 200 + + state = hass.states.get('{}.{}'.format('device_tracker', + data['device'])) + assert state.state == 'work' + + +@asyncio.coroutine +def test_exit_first(hass, locative_client): + """Test when an exit message is sent first on a new device.""" + data = { + 'latitude': 40.7855, + 'longitude': -111.7367, + 'device': 'new_device', + 'id': 'Home', + 'trigger': 'exit' + } + + # Exit Home + req = yield from locative_client.get(_url(data)) + assert req.status == 200 + + state = hass.states.get('{}.{}'.format('device_tracker', + data['device'])) + assert state.state == 'not_home' From 556dba40201b4807bd763f80acc09d1c98e44e33 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 29 Mar 2017 22:21:39 -0700 Subject: [PATCH 046/116] Convert Alexa tests to use aiohttp test utils (#6839) --- tests/components/test_alexa.py | 680 ++++++++++++++++----------------- 1 file changed, 334 insertions(+), 346 deletions(-) diff --git a/tests/components/test_alexa.py b/tests/components/test_alexa.py index f25eb2b097027c..66d506d40c9e98 100644 --- a/tests/components/test_alexa.py +++ b/tests/components/test_alexa.py @@ -1,33 +1,20 @@ """The tests for the Alexa component.""" # pylint: disable=protected-access +import asyncio import json import datetime -import unittest -import requests +import pytest from homeassistant.core import callback -from homeassistant import setup, const -from homeassistant.components import alexa, http - -from tests.common import get_test_instance_port, get_test_home_assistant - -API_PASSWORD = "test1234" -SERVER_PORT = get_test_instance_port() -BASE_API_URL = "http://127.0.0.1:{}".format(SERVER_PORT) -INTENTS_API_URL = "{}{}".format(BASE_API_URL, alexa.INTENTS_API_ENDPOINT) - -HA_HEADERS = { - const.HTTP_HEADER_HA_AUTH: API_PASSWORD, - const.HTTP_HEADER_CONTENT_TYPE: const.CONTENT_TYPE_JSON, -} +from homeassistant.setup import async_setup_component +from homeassistant.components import alexa SESSION_ID = "amzn1.echo-api.session.0000000-0000-0000-0000-00000000000" APPLICATION_ID = "amzn1.echo-sdk-ams.app.000000-d0ed-0000-ad00-000000d00ebe" REQUEST_ID = "amzn1.echo-api.request.0000000-0000-0000-0000-00000000000" # pylint: disable=invalid-name -hass = None calls = [] NPR_NEWS_MP3_URL = "https://pd.npr.org/anon.npr-mp3/npr/news/newscast.mp3" @@ -36,25 +23,16 @@ STATIC_TIME = datetime.datetime.utcfromtimestamp(1476129102) -# pylint: disable=invalid-name -def setUpModule(): +@pytest.fixture +def alexa_client(loop, hass, test_client): """Initialize a Home Assistant server for testing this module.""" - global hass - - hass = get_test_home_assistant() - - setup.setup_component( - hass, http.DOMAIN, - {http.DOMAIN: {http.CONF_API_PASSWORD: API_PASSWORD, - http.CONF_SERVER_PORT: SERVER_PORT}}) - @callback def mock_service(call): calls.append(call) - hass.services.register("test", "alexa", mock_service) + hass.services.async_register("test", "alexa", mock_service) - setup.setup_component(hass, alexa.DOMAIN, { + assert loop.run_until_complete(async_setup_component(hass, alexa.DOMAIN, { # Key is here to verify we allow other keys in config too "homeassistant": {}, "alexa": { @@ -122,357 +100,367 @@ def mock_service(call): } } } - }) - - hass.start() + })) + return loop.run_until_complete(test_client(hass.http.app)) -# pylint: disable=invalid-name -def tearDownModule(): - """Stop the Home Assistant server.""" - hass.stop() - - -def _intent_req(data={}): - return requests.post(INTENTS_API_URL, data=json.dumps(data), timeout=5, - headers=HA_HEADERS) - +def _intent_req(client, data={}): + return client.post(alexa.INTENTS_API_ENDPOINT, data=json.dumps(data), + headers={'content-type': 'application/json'}) -def _flash_briefing_req(briefing_id=None): - url_format = "{}/api/alexa/flash_briefings/{}" - FLASH_BRIEFING_API_URL = url_format.format(BASE_API_URL, - briefing_id) - return requests.get(FLASH_BRIEFING_API_URL, timeout=5, - headers=HA_HEADERS) +def _flash_briefing_req(client, briefing_id): + return client.get( + "/api/alexa/flash_briefings/{}".format(briefing_id)) -class TestAlexa(unittest.TestCase): - """Test Alexa.""" - def tearDown(self): - """Stop everything that was started.""" - hass.block_till_done() - - def test_intent_launch_request(self): - """Test the launch of a request.""" - data = { - "version": "1.0", - "session": { - "new": True, - "sessionId": SESSION_ID, - "application": { - "applicationId": APPLICATION_ID - }, - "attributes": {}, - "user": { - "userId": "amzn1.account.AM3B00000000000000000000000" - } +@asyncio.coroutine +def test_intent_launch_request(alexa_client): + """Test the launch of a request.""" + data = { + "version": "1.0", + "session": { + "new": True, + "sessionId": SESSION_ID, + "application": { + "applicationId": APPLICATION_ID }, - "request": { - "type": "LaunchRequest", - "requestId": REQUEST_ID, - "timestamp": "2015-05-13T12:34:56Z" + "attributes": {}, + "user": { + "userId": "amzn1.account.AM3B00000000000000000000000" } + }, + "request": { + "type": "LaunchRequest", + "requestId": REQUEST_ID, + "timestamp": "2015-05-13T12:34:56Z" } - req = _intent_req(data) - self.assertEqual(200, req.status_code) - resp = req.json() - self.assertIn("outputSpeech", resp["response"]) - - def test_intent_request_with_slots(self): - """Test a request with slots.""" - data = { - "version": "1.0", - "session": { - "new": False, - "sessionId": SESSION_ID, - "application": { - "applicationId": APPLICATION_ID - }, - "attributes": { - "supportedHoroscopePeriods": { - "daily": True, - "weekly": False, - "monthly": False - } - }, - "user": { - "userId": "amzn1.account.AM3B00000000000000000000000" + } + req = yield from _intent_req(alexa_client, data) + assert req.status == 200 + resp = yield from req.json() + assert "outputSpeech" in resp["response"] + + +@asyncio.coroutine +def test_intent_request_with_slots(alexa_client): + """Test a request with slots.""" + data = { + "version": "1.0", + "session": { + "new": False, + "sessionId": SESSION_ID, + "application": { + "applicationId": APPLICATION_ID + }, + "attributes": { + "supportedHoroscopePeriods": { + "daily": True, + "weekly": False, + "monthly": False } }, - "request": { - "type": "IntentRequest", - "requestId": REQUEST_ID, - "timestamp": "2015-05-13T12:34:56Z", - "intent": { - "name": "GetZodiacHoroscopeIntent", - "slots": { - "ZodiacSign": { - "name": "ZodiacSign", - "value": "virgo" - } + "user": { + "userId": "amzn1.account.AM3B00000000000000000000000" + } + }, + "request": { + "type": "IntentRequest", + "requestId": REQUEST_ID, + "timestamp": "2015-05-13T12:34:56Z", + "intent": { + "name": "GetZodiacHoroscopeIntent", + "slots": { + "ZodiacSign": { + "name": "ZodiacSign", + "value": "virgo" } } } } - req = _intent_req(data) - self.assertEqual(200, req.status_code) - text = req.json().get("response", {}).get("outputSpeech", - {}).get("text") - self.assertEqual("You told us your sign is virgo.", text) - - def test_intent_request_with_slots_but_no_value(self): - """Test a request with slots but no value.""" - data = { - "version": "1.0", - "session": { - "new": False, - "sessionId": SESSION_ID, - "application": { - "applicationId": APPLICATION_ID - }, - "attributes": { - "supportedHoroscopePeriods": { - "daily": True, - "weekly": False, - "monthly": False - } - }, - "user": { - "userId": "amzn1.account.AM3B00000000000000000000000" + } + req = yield from _intent_req(alexa_client, data) + assert req.status == 200 + data = yield from req.json() + text = data.get("response", {}).get("outputSpeech", + {}).get("text") + assert text == "You told us your sign is virgo." + + +@asyncio.coroutine +def test_intent_request_with_slots_but_no_value(alexa_client): + """Test a request with slots but no value.""" + data = { + "version": "1.0", + "session": { + "new": False, + "sessionId": SESSION_ID, + "application": { + "applicationId": APPLICATION_ID + }, + "attributes": { + "supportedHoroscopePeriods": { + "daily": True, + "weekly": False, + "monthly": False } }, - "request": { - "type": "IntentRequest", - "requestId": REQUEST_ID, - "timestamp": "2015-05-13T12:34:56Z", - "intent": { - "name": "GetZodiacHoroscopeIntent", - "slots": { - "ZodiacSign": { - "name": "ZodiacSign", - } + "user": { + "userId": "amzn1.account.AM3B00000000000000000000000" + } + }, + "request": { + "type": "IntentRequest", + "requestId": REQUEST_ID, + "timestamp": "2015-05-13T12:34:56Z", + "intent": { + "name": "GetZodiacHoroscopeIntent", + "slots": { + "ZodiacSign": { + "name": "ZodiacSign", } } } } - req = _intent_req(data) - self.assertEqual(200, req.status_code) - text = req.json().get("response", {}).get("outputSpeech", - {}).get("text") - self.assertEqual("You told us your sign is .", text) - - def test_intent_request_without_slots(self): - """Test a request without slots.""" - data = { - "version": "1.0", - "session": { - "new": False, - "sessionId": SESSION_ID, - "application": { - "applicationId": APPLICATION_ID - }, - "attributes": { - "supportedHoroscopePeriods": { - "daily": True, - "weekly": False, - "monthly": False - } - }, - "user": { - "userId": "amzn1.account.AM3B00000000000000000000000" - } + } + req = yield from _intent_req(alexa_client, data) + assert req.status == 200 + data = yield from req.json() + text = data.get("response", {}).get("outputSpeech", + {}).get("text") + assert text == "You told us your sign is ." + + +@asyncio.coroutine +def test_intent_request_without_slots(hass, alexa_client): + """Test a request without slots.""" + data = { + "version": "1.0", + "session": { + "new": False, + "sessionId": SESSION_ID, + "application": { + "applicationId": APPLICATION_ID }, - "request": { - "type": "IntentRequest", - "requestId": REQUEST_ID, - "timestamp": "2015-05-13T12:34:56Z", - "intent": { - "name": "WhereAreWeIntent", + "attributes": { + "supportedHoroscopePeriods": { + "daily": True, + "weekly": False, + "monthly": False } + }, + "user": { + "userId": "amzn1.account.AM3B00000000000000000000000" + } + }, + "request": { + "type": "IntentRequest", + "requestId": REQUEST_ID, + "timestamp": "2015-05-13T12:34:56Z", + "intent": { + "name": "WhereAreWeIntent", } } - req = _intent_req(data) - self.assertEqual(200, req.status_code) - text = req.json().get("response", {}).get("outputSpeech", - {}).get("text") - - self.assertEqual("Anne Therese is at unknown and Paulus is at unknown", - text) - - hass.states.set("device_tracker.paulus", "home") - hass.states.set("device_tracker.anne_therese", "home") - - req = _intent_req(data) - self.assertEqual(200, req.status_code) - text = req.json().get("response", {}).get("outputSpeech", - {}).get("text") - self.assertEqual("You are both home, you silly", text) - - def test_intent_request_calling_service(self): - """Test a request for calling a service.""" - data = { - "version": "1.0", - "session": { - "new": False, - "sessionId": SESSION_ID, - "application": { - "applicationId": APPLICATION_ID - }, - "attributes": {}, - "user": { - "userId": "amzn1.account.AM3B00000000000000000000000" - } + } + req = yield from _intent_req(alexa_client, data) + assert req.status == 200 + json = yield from req.json() + text = json.get("response", {}).get("outputSpeech", + {}).get("text") + + assert text == "Anne Therese is at unknown and Paulus is at unknown" + + hass.states.async_set("device_tracker.paulus", "home") + hass.states.async_set("device_tracker.anne_therese", "home") + + req = yield from _intent_req(alexa_client, data) + assert req.status == 200 + json = yield from req.json() + text = json.get("response", {}).get("outputSpeech", + {}).get("text") + assert text == "You are both home, you silly" + + +@asyncio.coroutine +def test_intent_request_calling_service(alexa_client): + """Test a request for calling a service.""" + data = { + "version": "1.0", + "session": { + "new": False, + "sessionId": SESSION_ID, + "application": { + "applicationId": APPLICATION_ID }, - "request": { - "type": "IntentRequest", - "requestId": REQUEST_ID, - "timestamp": "2015-05-13T12:34:56Z", - "intent": { - "name": "CallServiceIntent", - "slots": { - "ZodiacSign": { - "name": "ZodiacSign", - "value": "virgo", - } + "attributes": {}, + "user": { + "userId": "amzn1.account.AM3B00000000000000000000000" + } + }, + "request": { + "type": "IntentRequest", + "requestId": REQUEST_ID, + "timestamp": "2015-05-13T12:34:56Z", + "intent": { + "name": "CallServiceIntent", + "slots": { + "ZodiacSign": { + "name": "ZodiacSign", + "value": "virgo", } } } } - call_count = len(calls) - req = _intent_req(data) - self.assertEqual(200, req.status_code) - self.assertEqual(call_count + 1, len(calls)) - call = calls[-1] - self.assertEqual("test", call.domain) - self.assertEqual("alexa", call.service) - self.assertEqual(["switch.test"], call.data.get("entity_id")) - self.assertEqual("virgo", call.data.get("hello")) - - def test_intent_session_ended_request(self): - """Test the request for ending the session.""" - data = { - "version": "1.0", - "session": { - "new": False, - "sessionId": SESSION_ID, - "application": { - "applicationId": APPLICATION_ID - }, - "attributes": { - "supportedHoroscopePeriods": { - "daily": True, - "weekly": False, - "monthly": False - } - }, - "user": { - "userId": "amzn1.account.AM3B00000000000000000000000" + } + call_count = len(calls) + req = yield from _intent_req(alexa_client, data) + assert req.status == 200 + assert call_count + 1 == len(calls) + call = calls[-1] + assert call.domain == "test" + assert call.service == "alexa" + assert call.data.get("entity_id") == ["switch.test"] + assert call.data.get("hello") == "virgo" + + +@asyncio.coroutine +def test_intent_session_ended_request(alexa_client): + """Test the request for ending the session.""" + data = { + "version": "1.0", + "session": { + "new": False, + "sessionId": SESSION_ID, + "application": { + "applicationId": APPLICATION_ID + }, + "attributes": { + "supportedHoroscopePeriods": { + "daily": True, + "weekly": False, + "monthly": False } }, - "request": { - "type": "SessionEndedRequest", - "requestId": REQUEST_ID, - "timestamp": "2015-05-13T12:34:56Z", - "reason": "USER_INITIATED" + "user": { + "userId": "amzn1.account.AM3B00000000000000000000000" } + }, + "request": { + "type": "SessionEndedRequest", + "requestId": REQUEST_ID, + "timestamp": "2015-05-13T12:34:56Z", + "reason": "USER_INITIATED" } - - req = _intent_req(data) - self.assertEqual(200, req.status_code) - self.assertEqual("", req.text) - - def test_intent_from_built_in_intent_library(self): - """Test intents from the Built-in Intent Library.""" - data = { - 'request': { - 'intent': { - 'name': 'AMAZON.PlaybackAction', - 'slots': { - 'object.byArtist.name': { - 'name': 'object.byArtist.name', - 'value': 'the shins' - }, - 'object.composer.name': { - 'name': 'object.composer.name' - }, - 'object.contentSource': { - 'name': 'object.contentSource' - }, - 'object.era': { - 'name': 'object.era' - }, - 'object.genre': { - 'name': 'object.genre' - }, - 'object.name': { - 'name': 'object.name' - }, - 'object.owner.name': { - 'name': 'object.owner.name' - }, - 'object.select': { - 'name': 'object.select' - }, - 'object.sort': { - 'name': 'object.sort' - }, - 'object.type': { - 'name': 'object.type', - 'value': 'music' - } + } + + req = yield from _intent_req(alexa_client, data) + assert req.status == 200 + text = yield from req.text() + assert text == '' + + +@asyncio.coroutine +def test_intent_from_built_in_intent_library(alexa_client): + """Test intents from the Built-in Intent Library.""" + data = { + 'request': { + 'intent': { + 'name': 'AMAZON.PlaybackAction', + 'slots': { + 'object.byArtist.name': { + 'name': 'object.byArtist.name', + 'value': 'the shins' + }, + 'object.composer.name': { + 'name': 'object.composer.name' + }, + 'object.contentSource': { + 'name': 'object.contentSource' + }, + 'object.era': { + 'name': 'object.era' + }, + 'object.genre': { + 'name': 'object.genre' + }, + 'object.name': { + 'name': 'object.name' + }, + 'object.owner.name': { + 'name': 'object.owner.name' + }, + 'object.select': { + 'name': 'object.select' + }, + 'object.sort': { + 'name': 'object.sort' + }, + 'object.type': { + 'name': 'object.type', + 'value': 'music' } - }, - 'timestamp': '2016-12-14T23:23:37Z', - 'type': 'IntentRequest', - 'requestId': REQUEST_ID, - - }, - 'session': { - 'sessionId': SESSION_ID, - 'application': { - 'applicationId': APPLICATION_ID } + }, + 'timestamp': '2016-12-14T23:23:37Z', + 'type': 'IntentRequest', + 'requestId': REQUEST_ID, + + }, + 'session': { + 'sessionId': SESSION_ID, + 'application': { + 'applicationId': APPLICATION_ID } } - req = _intent_req(data) - self.assertEqual(200, req.status_code) - text = req.json().get("response", {}).get("outputSpeech", - {}).get("text") - self.assertEqual("Playing the shins.", text) - - def test_flash_briefing_invalid_id(self): - """Test an invalid Flash Briefing ID.""" - req = _flash_briefing_req() - self.assertEqual(404, req.status_code) - self.assertEqual("", req.text) - - def test_flash_briefing_date_from_str(self): - """Test the response has a valid date parsed from string.""" - req = _flash_briefing_req("weather") - self.assertEqual(200, req.status_code) - self.assertEqual(req.json()[0].get(alexa.ATTR_UPDATE_DATE), - "2016-10-09T19:51:42.0Z") - - def test_flash_briefing_date_from_datetime(self): - """Test the response has a valid date from a datetime object.""" - req = _flash_briefing_req("weather") - self.assertEqual(200, req.status_code) - self.assertEqual(req.json()[1].get(alexa.ATTR_UPDATE_DATE), - '2016-10-10T19:51:42.0Z') - - def test_flash_briefing_valid(self): - """Test the response is valid.""" - data = [{ - "titleText": "NPR", - "redirectionURL": "https://npr.org", - "streamUrl": NPR_NEWS_MP3_URL, - "mainText": "", - "uid": "uuid", - "updateDate": '2016-10-10T19:51:42.0Z' - }] - - req = _flash_briefing_req("news_audio") - self.assertEqual(200, req.status_code) - response = req.json() - self.assertEqual(response, data) + } + req = yield from _intent_req(alexa_client, data) + assert req.status == 200 + data = yield from req.json() + text = data.get("response", {}).get("outputSpeech", + {}).get("text") + assert text == "Playing the shins." + + +@asyncio.coroutine +def test_flash_briefing_invalid_id(alexa_client): + """Test an invalid Flash Briefing ID.""" + req = yield from _flash_briefing_req(alexa_client, 10000) + assert req.status == 404 + text = yield from req.text() + assert text == '' + + +@asyncio.coroutine +def test_flash_briefing_date_from_str(alexa_client): + """Test the response has a valid date parsed from string.""" + req = yield from _flash_briefing_req(alexa_client, "weather") + assert req.status == 200 + data = yield from req.json() + assert data[0].get(alexa.ATTR_UPDATE_DATE) == "2016-10-09T19:51:42.0Z" + + +@asyncio.coroutine +def test_flash_briefing_date_from_datetime(alexa_client): + """Test the response has a valid date from a datetime object.""" + req = yield from _flash_briefing_req(alexa_client, "weather") + assert req.status == 200 + data = yield from req.json() + assert data[1].get(alexa.ATTR_UPDATE_DATE) == '2016-10-10T19:51:42.0Z' + + +@asyncio.coroutine +def test_flash_briefing_valid(alexa_client): + """Test the response is valid.""" + data = [{ + "titleText": "NPR", + "redirectionURL": "https://npr.org", + "streamUrl": NPR_NEWS_MP3_URL, + "mainText": "", + "uid": "uuid", + "updateDate": '2016-10-10T19:51:42.0Z' + }] + + req = yield from _flash_briefing_req(alexa_client, "news_audio") + assert req.status == 200 + json = yield from req.json() + assert json == data From ead00e956f758a73b86b384c23ee0abbd7f2f0fd Mon Sep 17 00:00:00 2001 From: Johan Bloemberg Date: Thu, 30 Mar 2017 07:50:32 +0200 Subject: [PATCH 047/116] Handle initial event after entity is instantiated. (#6760) --- homeassistant/components/light/rflink.py | 4 ++-- homeassistant/components/sensor/rflink.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/light/rflink.py b/homeassistant/components/light/rflink.py index ad25ae6a38d578..a36a4f43f22b6e 100644 --- a/homeassistant/components/light/rflink.py +++ b/homeassistant/components/light/rflink.py @@ -162,8 +162,8 @@ def add_new_device(event): hass.data[DATA_ENTITY_LOOKUP][ EVENT_KEY_COMMAND][device_id].append(device) - # Make sure the event is processed by the new entity - device.handle_event(event) + # Schedule task to process event after entity is created + hass.async_add_job(device.handle_event, event) hass.data[DATA_DEVICE_REGISTER][EVENT_KEY_COMMAND] = add_new_device diff --git a/homeassistant/components/sensor/rflink.py b/homeassistant/components/sensor/rflink.py index 8f8ae769d0e5ec..80a5b7dfb8daea 100644 --- a/homeassistant/components/sensor/rflink.py +++ b/homeassistant/components/sensor/rflink.py @@ -88,8 +88,8 @@ def add_new_device(event): hass.data[DATA_ENTITY_LOOKUP][ EVENT_KEY_SENSOR][device_id].append(device) - # Make sure the event is processed by the new entity - device.handle_event(event) + # Schedule task to process event after entity is created + hass.async_add_job(device.handle_event, event) hass.data[DATA_DEVICE_REGISTER][EVENT_KEY_SENSOR] = add_new_device From 7b83a836f3975b13f1931d8a061d5934a3811cff Mon Sep 17 00:00:00 2001 From: Anders Melchiorsen Date: Thu, 30 Mar 2017 08:00:22 +0200 Subject: [PATCH 048/116] Lifx legacy (#6847) * Add legacy LIFX platform for Windows support The async platform introduced in 9ef084d9034351a7aa26480d0604aad9857dbbc7 has turned out to use Python functionality that is not available in Windows. This commit restores the previous implementation, now named lifx_legacy. * Add a comment about the platform being a legacy implementation * Warn when using unsupported lifx platform on Windows * Update .coveragerc --- .coveragerc | 1 + homeassistant/components/light/lifx.py | 5 + homeassistant/components/light/lifx_legacy.py | 280 ++++++++++++++++++ requirements_all.txt | 3 + 4 files changed, 289 insertions(+) create mode 100644 homeassistant/components/light/lifx_legacy.py diff --git a/.coveragerc b/.coveragerc index c6bf3d197ae4dc..52b88444dc6686 100644 --- a/.coveragerc +++ b/.coveragerc @@ -225,6 +225,7 @@ omit = homeassistant/components/light/hue.py homeassistant/components/light/hyperion.py homeassistant/components/light/lifx.py + homeassistant/components/light/lifx_legacy.py homeassistant/components/light/limitlessled.py homeassistant/components/light/osramlightify.py homeassistant/components/light/tikteck.py diff --git a/homeassistant/components/light/lifx.py b/homeassistant/components/light/lifx.py index 990fc2acc1fc03..d3b084b3b941b2 100644 --- a/homeassistant/components/light/lifx.py +++ b/homeassistant/components/light/lifx.py @@ -7,6 +7,7 @@ import colorsys import logging import asyncio +import sys from functools import partial from datetime import timedelta @@ -51,6 +52,10 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Setup the LIFX platform.""" import aiolifx + if sys.platform == 'win32': + _LOGGER.warning('The lifx platform is known to not work on Windows. ' + 'Consider using the lifx_legacy platform instead.') + server_addr = config.get(CONF_SERVER) lifx_manager = LIFXManager(hass, async_add_devices) diff --git a/homeassistant/components/light/lifx_legacy.py b/homeassistant/components/light/lifx_legacy.py new file mode 100644 index 00000000000000..8a81c992a13219 --- /dev/null +++ b/homeassistant/components/light/lifx_legacy.py @@ -0,0 +1,280 @@ +""" +Support for the LIFX platform that implements lights. + +This is a legacy platform, included because the current lifx platform does +not yet support Windows. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/light.lifx/ +""" +import colorsys +import logging + +import voluptuous as vol + +from homeassistant.components.light import ( + ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_RGB_COLOR, ATTR_TRANSITION, + SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_RGB_COLOR, + SUPPORT_TRANSITION, Light, PLATFORM_SCHEMA) +from homeassistant.helpers.event import track_time_change +from homeassistant.util.color import ( + color_temperature_mired_to_kelvin, color_temperature_kelvin_to_mired) +import homeassistant.helpers.config_validation as cv + +_LOGGER = logging.getLogger(__name__) + +REQUIREMENTS = ['liffylights==0.9.4'] + +BYTE_MAX = 255 + +CONF_BROADCAST = 'broadcast' +CONF_SERVER = 'server' + +SHORT_MAX = 65535 + +TEMP_MAX = 9000 +TEMP_MAX_HASS = 500 +TEMP_MIN = 2500 +TEMP_MIN_HASS = 154 + +SUPPORT_LIFX = (SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP | SUPPORT_RGB_COLOR | + SUPPORT_TRANSITION) + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Optional(CONF_SERVER, default=None): cv.string, + vol.Optional(CONF_BROADCAST, default=None): cv.string, +}) + + +# pylint: disable=unused-argument +def setup_platform(hass, config, add_devices, discovery_info=None): + """Setup the LIFX platform.""" + server_addr = config.get(CONF_SERVER) + broadcast_addr = config.get(CONF_BROADCAST) + + lifx_library = LIFX(add_devices, server_addr, broadcast_addr) + + # Register our poll service + track_time_change(hass, lifx_library.poll, second=[10, 40]) + + lifx_library.probe() + + +class LIFX(object): + """Representation of a LIFX light.""" + + def __init__(self, add_devices_callback, server_addr=None, + broadcast_addr=None): + """Initialize the light.""" + import liffylights + + self._devices = [] + + self._add_devices_callback = add_devices_callback + + self._liffylights = liffylights.LiffyLights( + self.on_device, self.on_power, self.on_color, server_addr, + broadcast_addr) + + def find_bulb(self, ipaddr): + """Search for bulbs.""" + bulb = None + for device in self._devices: + if device.ipaddr == ipaddr: + bulb = device + break + return bulb + + def on_device(self, ipaddr, name, power, hue, sat, bri, kel): + """Initialize the light.""" + bulb = self.find_bulb(ipaddr) + + if bulb is None: + _LOGGER.debug("new bulb %s %s %d %d %d %d %d", + ipaddr, name, power, hue, sat, bri, kel) + bulb = LIFXLight( + self._liffylights, ipaddr, name, power, hue, sat, bri, kel) + self._devices.append(bulb) + self._add_devices_callback([bulb]) + else: + _LOGGER.debug("update bulb %s %s %d %d %d %d %d", + ipaddr, name, power, hue, sat, bri, kel) + bulb.set_power(power) + bulb.set_color(hue, sat, bri, kel) + bulb.schedule_update_ha_state() + + def on_color(self, ipaddr, hue, sat, bri, kel): + """Initialize the light.""" + bulb = self.find_bulb(ipaddr) + + if bulb is not None: + bulb.set_color(hue, sat, bri, kel) + bulb.schedule_update_ha_state() + + def on_power(self, ipaddr, power): + """Initialize the light.""" + bulb = self.find_bulb(ipaddr) + + if bulb is not None: + bulb.set_power(power) + bulb.schedule_update_ha_state() + + # pylint: disable=unused-argument + def poll(self, now): + """Polling for the light.""" + self.probe() + + def probe(self, address=None): + """Probe the light.""" + self._liffylights.probe(address) + + +def convert_rgb_to_hsv(rgb): + """Convert Home Assistant RGB values to HSV values.""" + red, green, blue = [_ / BYTE_MAX for _ in rgb] + + hue, saturation, brightness = colorsys.rgb_to_hsv(red, green, blue) + + return [int(hue * SHORT_MAX), + int(saturation * SHORT_MAX), + int(brightness * SHORT_MAX)] + + +class LIFXLight(Light): + """Representation of a LIFX light.""" + + def __init__(self, liffy, ipaddr, name, power, hue, saturation, brightness, + kelvin): + """Initialize the light.""" + _LOGGER.debug("LIFXLight: %s %s", ipaddr, name) + + self._liffylights = liffy + self._ip = ipaddr + self.set_name(name) + self.set_power(power) + self.set_color(hue, saturation, brightness, kelvin) + + @property + def should_poll(self): + """No polling needed for LIFX light.""" + return False + + @property + def name(self): + """Return the name of the device.""" + return self._name + + @property + def ipaddr(self): + """Return the IP address of the device.""" + return self._ip + + @property + def rgb_color(self): + """Return the RGB value.""" + _LOGGER.debug( + "rgb_color: [%d %d %d]", self._rgb[0], self._rgb[1], self._rgb[2]) + return self._rgb + + @property + def brightness(self): + """Return the brightness of this light between 0..255.""" + brightness = int(self._bri / (BYTE_MAX + 1)) + _LOGGER.debug("brightness: %d", brightness) + return brightness + + @property + def color_temp(self): + """Return the color temperature.""" + temperature = color_temperature_kelvin_to_mired(self._kel) + + _LOGGER.debug("color_temp: %d", temperature) + return temperature + + @property + def is_on(self): + """Return true if device is on.""" + _LOGGER.debug("is_on: %d", self._power) + return self._power != 0 + + @property + def supported_features(self): + """Flag supported features.""" + return SUPPORT_LIFX + + def turn_on(self, **kwargs): + """Turn the device on.""" + if ATTR_TRANSITION in kwargs: + fade = int(kwargs[ATTR_TRANSITION] * 1000) + else: + fade = 0 + + if ATTR_RGB_COLOR in kwargs: + hue, saturation, brightness = \ + convert_rgb_to_hsv(kwargs[ATTR_RGB_COLOR]) + else: + hue = self._hue + saturation = self._sat + brightness = self._bri + + if ATTR_BRIGHTNESS in kwargs: + brightness = kwargs[ATTR_BRIGHTNESS] * (BYTE_MAX + 1) + else: + brightness = self._bri + + if ATTR_COLOR_TEMP in kwargs: + kelvin = int(color_temperature_mired_to_kelvin( + kwargs[ATTR_COLOR_TEMP])) + else: + kelvin = self._kel + + _LOGGER.debug("turn_on: %s (%d) %d %d %d %d %d", + self._ip, self._power, + hue, saturation, brightness, kelvin, fade) + + if self._power == 0: + self._liffylights.set_color(self._ip, hue, saturation, + brightness, kelvin, 0) + self._liffylights.set_power(self._ip, 65535, fade) + else: + self._liffylights.set_color(self._ip, hue, saturation, + brightness, kelvin, fade) + + def turn_off(self, **kwargs): + """Turn the device off.""" + if ATTR_TRANSITION in kwargs: + fade = int(kwargs[ATTR_TRANSITION] * 1000) + else: + fade = 0 + + _LOGGER.debug("turn_off: %s %d", self._ip, fade) + self._liffylights.set_power(self._ip, 0, fade) + + def set_name(self, name): + """Set name of the light.""" + self._name = name + + def set_power(self, power): + """Set power state value.""" + _LOGGER.debug("set_power: %d", power) + self._power = (power != 0) + + def set_color(self, hue, sat, bri, kel): + """Set color state values.""" + self._hue = hue + self._sat = sat + self._bri = bri + self._kel = kel + + red, green, blue = colorsys.hsv_to_rgb(hue / SHORT_MAX, + sat / SHORT_MAX, + bri / SHORT_MAX) + + red = int(red * BYTE_MAX) + green = int(green * BYTE_MAX) + blue = int(blue * BYTE_MAX) + + _LOGGER.debug("set_color: %d %d %d %d [%d %d %d]", + hue, sat, bri, kel, red, green, blue) + + self._rgb = [red, green, blue] diff --git a/requirements_all.txt b/requirements_all.txt index 2c3301671a35d9..d97e830874c723 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -347,6 +347,9 @@ libnacl==1.5.0 # homeassistant.components.media_player.soundtouch libsoundtouch==0.1.0 +# homeassistant.components.light.lifx_legacy +liffylights==0.9.4 + # homeassistant.components.light.limitlessled limitlessled==1.0.5 From 714b5161767bc426f261835b4fc06519435076e3 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 30 Mar 2017 00:50:53 -0700 Subject: [PATCH 049/116] aiohttp 2 (#6835) * Upgrade aiohttp2 * Fix resource caching * Fix helpers.aiohttp_client * Lint * Use static path for api error_log * Fix ClientErrors import * Remove not needed DisconnectError * Remove releasing responses code * Add timeout if stream starts non responding * More async_aiohttp_proxy_stream cleanup * Fix references to ClientError * Fix fingerprinting * Fix aiohttp stream tests * Rename aiohttp_proxy_stream * Remove impossible darksky test * Fix sleepiq requests escaping mocker * Lint * Remove deprecated parameter * Break up aiohttp_proxy_stream in 2 methods * Lint * Upgrade to aiohttp 2.0.4 * Convert connector close to a callback * Fix static fingerprinted links --- homeassistant/components/api.py | 18 +-- homeassistant/components/camera/__init__.py | 7 +- homeassistant/components/camera/amcrest.py | 4 +- homeassistant/components/camera/ffmpeg.py | 30 ++--- homeassistant/components/camera/generic.py | 8 +- homeassistant/components/camera/mjpeg.py | 12 +- homeassistant/components/camera/synology.py | 26 ++-- .../components/device_tracker/__init__.py | 7 +- .../components/device_tracker/tado.py | 8 +- .../components/device_tracker/upc_connect.py | 23 +--- homeassistant/components/frontend/__init__.py | 2 +- homeassistant/components/http/__init__.py | 53 ++++---- homeassistant/components/http/static.py | 63 ++++++---- .../image_processing/openalpr_cloud.py | 8 +- .../components/media_player/__init__.py | 12 +- .../components/media_player/squeezebox.py | 14 +-- .../components/media_player/volumio.py | 8 +- homeassistant/components/microsoft_face.py | 21 ++-- homeassistant/components/rest_command.py | 15 +-- homeassistant/components/sensor/yr.py | 11 +- homeassistant/components/switch/hook.py | 25 +--- homeassistant/components/switch/rest.py | 29 ++--- homeassistant/components/tts/google.py | 7 +- homeassistant/components/tts/voicerss.py | 7 +- homeassistant/components/tts/yandextts.py | 8 +- homeassistant/helpers/aiohttp_client.py | 56 +++++---- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- setup.py | 2 +- tests/components/sensor/test_darksky.py | 11 +- tests/components/switch/test_rest.py | 2 +- tests/components/test_api.py | 19 --- tests/components/test_frontend.py | 116 ++++++++---------- tests/components/test_rest_command.py | 2 +- tests/components/test_sleepiq.py | 10 +- tests/helpers/test_aiohttp_client.py | 44 ++----- 36 files changed, 250 insertions(+), 442 deletions(-) diff --git a/homeassistant/components/api.py b/homeassistant/components/api.py index 1af85605874678..b22bd8511906f5 100644 --- a/homeassistant/components/api.py +++ b/homeassistant/components/api.py @@ -50,9 +50,11 @@ def setup(hass, config): hass.http.register_view(APIDomainServicesView) hass.http.register_view(APIEventForwardingView) hass.http.register_view(APIComponentsView) - hass.http.register_view(APIErrorLogView) hass.http.register_view(APITemplateView) + hass.http.register_static_path( + URL_API_ERROR_LOG, hass.config.path(ERROR_LOG_FILENAME), False) + return True @@ -402,20 +404,6 @@ def get(self, request): return self.json(request.app['hass'].config.components) -class APIErrorLogView(HomeAssistantView): - """View to handle ErrorLog requests.""" - - url = URL_API_ERROR_LOG - name = "api:error-log" - - @asyncio.coroutine - def get(self, request): - """Serve error log.""" - resp = yield from self.file( - request, request.app['hass'].config.path(ERROR_LOG_FILENAME)) - return resp - - class APITemplateView(HomeAssistantView): """View to handle requests.""" diff --git a/homeassistant/components/camera/__init__.py b/homeassistant/components/camera/__init__.py index b531a931a7af4a..d3c6699f77c8e7 100644 --- a/homeassistant/components/camera/__init__.py +++ b/homeassistant/components/camera/__init__.py @@ -58,7 +58,6 @@ def async_get_image(hass, entity_id, timeout=10): state.attributes.get(ATTR_ENTITY_PICTURE) ) - response = None try: with async_timeout.timeout(timeout, loop=hass.loop): response = yield from websession.get(url) @@ -70,13 +69,9 @@ def async_get_image(hass, entity_id, timeout=10): image = yield from response.read() return image - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): raise HomeAssistantError("Can't connect to {0}".format(url)) - finally: - if response is not None: - yield from response.release() - @asyncio.coroutine def async_setup(hass, config): diff --git a/homeassistant/components/camera/amcrest.py b/homeassistant/components/camera/amcrest.py index f272dda4bb398c..9bf89b8b3a5e79 100644 --- a/homeassistant/components/camera/amcrest.py +++ b/homeassistant/components/camera/amcrest.py @@ -16,7 +16,7 @@ CONF_HOST, CONF_NAME, CONF_USERNAME, CONF_PASSWORD, CONF_PORT) from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import ( - async_get_clientsession, async_aiohttp_proxy_stream) + async_get_clientsession, async_aiohttp_proxy_web) REQUIREMENTS = ['amcrest==1.1.4'] @@ -125,7 +125,7 @@ def handle_async_mjpeg_stream(self, request): stream_coro = websession.get( streaming_url, auth=self._token, timeout=TIMEOUT) - yield from async_aiohttp_proxy_stream(self.hass, request, stream_coro) + yield from async_aiohttp_proxy_web(self.hass, request, stream_coro) @property def name(self): diff --git a/homeassistant/components/camera/ffmpeg.py b/homeassistant/components/camera/ffmpeg.py index ed8c84f90dfbd3..d4c7b54fc7f5d9 100644 --- a/homeassistant/components/camera/ffmpeg.py +++ b/homeassistant/components/camera/ffmpeg.py @@ -8,14 +8,14 @@ import logging import voluptuous as vol -from aiohttp import web +from homeassistant.const import CONF_NAME from homeassistant.components.camera import Camera, PLATFORM_SCHEMA from homeassistant.components.ffmpeg import ( DATA_FFMPEG, CONF_INPUT, CONF_EXTRA_ARGUMENTS) import homeassistant.helpers.config_validation as cv -from homeassistant.const import CONF_NAME - +from homeassistant.helpers.aiohttp_client import ( + async_aiohttp_proxy_stream) DEPENDENCIES = ['ffmpeg'] _LOGGER = logging.getLogger(__name__) @@ -69,26 +69,10 @@ def handle_async_mjpeg_stream(self, request): yield from stream.open_camera( self._input, extra_cmd=self._extra_arguments) - response = web.StreamResponse() - response.content_type = 'multipart/x-mixed-replace;boundary=ffserver' - - yield from response.prepare(request) - - try: - while True: - data = yield from stream.read(102400) - if not data: - break - response.write(data) - - except asyncio.CancelledError: - _LOGGER.debug("Close stream by frontend.") - response = None - - finally: - yield from stream.close() - if response is not None: - yield from response.write_eof() + yield from async_aiohttp_proxy_stream( + self.hass, request, stream, + 'multipart/x-mixed-replace;boundary=ffserver') + yield from stream.close() @property def name(self): diff --git a/homeassistant/components/camera/generic.py b/homeassistant/components/camera/generic.py index 3f50bc799c4932..a330836f32bf5c 100644 --- a/homeassistant/components/camera/generic.py +++ b/homeassistant/components/camera/generic.py @@ -107,7 +107,6 @@ def fetch(): None, fetch) # async else: - response = None try: websession = async_get_clientsession(self.hass) with async_timeout.timeout(10, loop=self.hass.loop): @@ -117,14 +116,9 @@ def fetch(): except asyncio.TimeoutError: _LOGGER.error('Timeout getting camera image') return self._last_image - except (aiohttp.errors.ClientError, - aiohttp.errors.DisconnectedError, - aiohttp.errors.HttpProcessingError) as err: + except aiohttp.ClientError as err: _LOGGER.error('Error getting new camera image: %s', err) return self._last_image - finally: - if response is not None: - yield from response.release() self._last_url = url return self._last_image diff --git a/homeassistant/components/camera/mjpeg.py b/homeassistant/components/camera/mjpeg.py index 532b91e7442b0f..a158c36152e077 100644 --- a/homeassistant/components/camera/mjpeg.py +++ b/homeassistant/components/camera/mjpeg.py @@ -19,7 +19,7 @@ HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION) from homeassistant.components.camera import (PLATFORM_SCHEMA, Camera) from homeassistant.helpers.aiohttp_client import ( - async_get_clientsession, async_aiohttp_proxy_stream) + async_get_clientsession, async_aiohttp_proxy_web) from homeassistant.helpers import config_validation as cv _LOGGER = logging.getLogger(__name__) @@ -93,7 +93,6 @@ def async_camera_image(self): return image websession = async_get_clientsession(self.hass) - response = None try: with async_timeout.timeout(10, loop=self.hass.loop): response = yield from websession.get( @@ -105,14 +104,9 @@ def async_camera_image(self): except asyncio.TimeoutError: _LOGGER.error('Timeout getting camera image') - except (aiohttp.errors.ClientError, - aiohttp.errors.ClientDisconnectedError) as err: + except aiohttp.ClientError as err: _LOGGER.error('Error getting new camera image: %s', err) - finally: - if response is not None: - yield from response.release() - def camera_image(self): """Return a still image response from the camera.""" if self._username and self._password: @@ -140,7 +134,7 @@ def handle_async_mjpeg_stream(self, request): websession = async_get_clientsession(self.hass) stream_coro = websession.get(self._mjpeg_url, auth=self._auth) - yield from async_aiohttp_proxy_stream(self.hass, request, stream_coro) + yield from async_aiohttp_proxy_web(self.hass, request, stream_coro) @property def name(self): diff --git a/homeassistant/components/camera/synology.py b/homeassistant/components/camera/synology.py index 2b4d72f92f8282..e986d81887b033 100644 --- a/homeassistant/components/camera/synology.py +++ b/homeassistant/components/camera/synology.py @@ -19,7 +19,7 @@ Camera, PLATFORM_SCHEMA) from homeassistant.helpers.aiohttp_client import ( async_get_clientsession, async_create_clientsession, - async_aiohttp_proxy_stream) + async_aiohttp_proxy_web) import homeassistant.helpers.config_validation as cv from homeassistant.util.async import run_coroutine_threadsafe @@ -74,7 +74,6 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): 'version': '1', 'query': 'SYNO.' } - query_req = None try: with async_timeout.timeout(timeout, loop=hass.loop): query_req = yield from websession_init.get( @@ -88,14 +87,10 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): camera_path = query_resp['data'][CAMERA_API]['path'] streaming_path = query_resp['data'][STREAMING_API]['path'] - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.exception("Error on %s", syno_api_url) return False - finally: - if query_req is not None: - yield from query_req.release() - # Authticate to NAS to get a session id syno_auth_url = SYNO_API_URL.format( config.get(CONF_URL), WEBAPI_PATH, auth_path) @@ -128,13 +123,12 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): syno_camera_url, params=camera_payload ) - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.exception("Error on %s", syno_camera_url) return False camera_resp = yield from camera_req.json() cameras = camera_resp['data']['cameras'] - yield from camera_req.release() # add cameras devices = [] @@ -172,7 +166,6 @@ def get_session_id(hass, websession, username, password, login_url, timeout): 'session': 'SurveillanceStation', 'format': 'sid' } - auth_req = None try: with async_timeout.timeout(timeout, loop=hass.loop): auth_req = yield from websession.get( @@ -182,14 +175,10 @@ def get_session_id(hass, websession, username, password, login_url, timeout): auth_resp = yield from auth_req.json() return auth_resp['data']['sid'] - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.exception("Error on %s", login_url) return False - finally: - if auth_req is not None: - yield from auth_req.release() - class SynologyCamera(Camera): """An implementation of a Synology NAS based IP camera.""" @@ -235,12 +224,11 @@ def async_camera_image(self): image_url, params=image_payload ) - except (asyncio.TimeoutError, aiohttp.errors.ClientError): - _LOGGER.exception("Error on %s", image_url) + except (asyncio.TimeoutError, aiohttp.ClientError): + _LOGGER.error("Error fetching %s", image_url) return None image = yield from response.read() - yield from response.release() return image @@ -260,7 +248,7 @@ def handle_async_mjpeg_stream(self, request): stream_coro = self._websession.get( streaming_url, params=streaming_payload) - yield from async_aiohttp_proxy_stream(self.hass, request, stream_coro) + yield from async_aiohttp_proxy_web(self.hass, request, stream_coro) @property def name(self): diff --git a/homeassistant/components/device_tracker/__init__.py b/homeassistant/components/device_tracker/__init__.py index 3e04f46cb50eaa..f2a538507a08f9 100644 --- a/homeassistant/components/device_tracker/__init__.py +++ b/homeassistant/components/device_tracker/__init__.py @@ -553,7 +553,6 @@ def get_vendor_for_mac(self): # bytes like 00 get truncates to 0, API needs full bytes oui = '{:02x}:{:02x}:{:02x}'.format(*[int(b, 16) for b in oui_bytes]) url = 'http://api.macvendors.com/' + oui - resp = None try: websession = async_get_clientsession(self.hass) @@ -570,13 +569,9 @@ def get_vendor_for_mac(self): # in the 'known_devices.yaml' file which only happens # the first time the device is seen. return 'unknown' - except (asyncio.TimeoutError, aiohttp.errors.ClientError, - aiohttp.errors.ClientDisconnectedError): + except (asyncio.TimeoutError, aiohttp.ClientError): # same as above return 'unknown' - finally: - if resp is not None: - yield from resp.release() @asyncio.coroutine def async_added_to_hass(self): diff --git a/homeassistant/components/device_tracker/tado.py b/homeassistant/components/device_tracker/tado.py index ca0bec297066a8..3c21037d028b30 100644 --- a/homeassistant/components/device_tracker/tado.py +++ b/homeassistant/components/device_tracker/tado.py @@ -105,8 +105,6 @@ def _update_info(self): _LOGGER.debug("Requesting Tado") last_results = [] - response = None - tado_json = None try: with async_timeout.timeout(10, loop=self.hass.loop): @@ -127,14 +125,10 @@ def _update_info(self): tado_json = yield from response.json() - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.error("Cannot load Tado data") return False - finally: - if response is not None: - yield from response.release() - # Without a home_id, we fetched an URL where the mobile devices can be # found under the mobileDevices key. if 'mobileDevices' in tado_json: diff --git a/homeassistant/components/device_tracker/upc_connect.py b/homeassistant/components/device_tracker/upc_connect.py index 879a645fe3036d..cec00221aaf0f2 100644 --- a/homeassistant/components/device_tracker/upc_connect.py +++ b/homeassistant/components/device_tracker/upc_connect.py @@ -101,7 +101,6 @@ def async_get_device_name(self, device): @asyncio.coroutine def async_login(self): """Login into firmware and get first token.""" - response = None try: # get first token with async_timeout.timeout(10, loop=self.hass.loop): @@ -109,7 +108,8 @@ def async_login(self): "http://{}/common_page/login.html".format(self.host) ) - yield from response.text() + yield from response.text() + self.token = response.cookies['sessionToken'].value # login @@ -119,18 +119,12 @@ def async_login(self): }) # successfull? - if data is not None: - return True - return False + return data is not None - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.error("Can not load login page from %s", self.host) return False - finally: - if response is not None: - yield from response.release() - @asyncio.coroutine def _async_ws_function(self, function, additional_form=None): """Execute a command on UPC firmware webservice.""" @@ -142,8 +136,7 @@ def _async_ws_function(self, function, additional_form=None): if additional_form: form_data.update(additional_form) - redirects = True if function != CMD_DEVICES else False - response = None + redirects = function != CMD_DEVICES try: with async_timeout.timeout(10, loop=self.hass.loop): response = yield from self.websession.post( @@ -163,10 +156,6 @@ def _async_ws_function(self, function, additional_form=None): self.token = response.cookies['sessionToken'].value return (yield from response.text()) - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.error("Error on %s", function) self.token = None - - finally: - if response is not None: - yield from response.release() diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index 7d95cfb20fe67c..b6f65d9953aa08 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -153,7 +153,7 @@ def setup(hass, config): sw_path = "service_worker.js" hass.http.register_static_path("/service_worker.js", - os.path.join(STATIC_PATH, sw_path), 0) + os.path.join(STATIC_PATH, sw_path), False) hass.http.register_static_path("/robots.txt", os.path.join(STATIC_PATH, "robots.txt")) hass.http.register_static_path("/static", STATIC_PATH) diff --git a/homeassistant/components/http/__init__.py b/homeassistant/components/http/__init__.py index d6e03e76619564..f99b2390bb8929 100644 --- a/homeassistant/components/http/__init__.py +++ b/homeassistant/components/http/__init__.py @@ -9,7 +9,6 @@ import logging import ssl from ipaddress import ip_network -from pathlib import Path import os import voluptuous as vol @@ -31,7 +30,8 @@ KEY_USE_X_FORWARDED_FOR, KEY_TRUSTED_NETWORKS, KEY_BANS_ENABLED, KEY_LOGIN_THRESHOLD, KEY_DEVELOPMENT, KEY_AUTHENTICATED) -from .static import FILE_SENDER, CACHING_FILE_SENDER, staticresource_middleware +from .static import ( + staticresource_middleware, CachingFileResponse, CachingStaticResource) from .util import get_real_ip DOMAIN = 'http' @@ -187,7 +187,7 @@ def __init__(self, hass, development, api_password, ssl_certificate, if is_ban_enabled: middlewares.insert(0, ban_middleware) - self.app = web.Application(middlewares=middlewares, loop=hass.loop) + self.app = web.Application(middlewares=middlewares) self.app['hass'] = hass self.app[KEY_USE_X_FORWARDED_FOR] = use_x_forwarded_for self.app[KEY_TRUSTED_NETWORKS] = trusted_networks @@ -255,31 +255,39 @@ def redirect(request): self.app.router.add_route('GET', url, redirect) - def register_static_path(self, url_root, path, cache_length=31): - """Register a folder to serve as a static path. - - Specify optional cache length of asset in days. - """ + def register_static_path(self, url_path, path, cache_headers=True): + """Register a folder or file to serve as a static path.""" if os.path.isdir(path): - self.app.router.add_static(url_root, path) - return + if cache_headers: + resource = CachingStaticResource + else: + resource = web.StaticResource - filepath = Path(path) + self.app.router.register_resource(resource(url_path, path)) + return - @asyncio.coroutine - def serve_file(request): - """Serve file from disk.""" - res = yield from CACHING_FILE_SENDER.send(request, filepath) - return res + if cache_headers: + @asyncio.coroutine + def serve_file(request): + """Serve file from disk.""" + return CachingFileResponse(path) + else: + @asyncio.coroutine + def serve_file(request): + """Serve file from disk.""" + return web.FileResponse(path) # aiohttp supports regex matching for variables. Using that as temp # to work around cache busting MD5. # Turns something like /static/dev-panel.html into # /static/{filename:dev-panel(-[a-z0-9]{32}|)\.html} - base, ext = url_root.rsplit('.', 1) - base, file = base.rsplit('/', 1) - regex = r"{}(-[a-z0-9]{{32}}|)\.{}".format(file, ext) - url_pattern = "{}/{{filename:{}}}".format(base, regex) + base, ext = os.path.splitext(url_path) + if ext: + base, file = base.rsplit('/', 1) + regex = r"{}(-[a-z0-9]{{32}}|){}".format(file, ext) + url_pattern = "{}/{{filename:{}}}".format(base, regex) + else: + url_pattern = url_path self.app.router.add_route('GET', url_pattern, serve_file) @@ -318,7 +326,7 @@ def start(self): # re-register all redirects, views, static paths. self.app._frozen = True # pylint: disable=protected-access - self._handler = self.app.make_handler() + self._handler = self.app.make_handler(loop=self.hass.loop) try: self.server = yield from self.hass.loop.create_server( @@ -365,8 +373,7 @@ def json_message(self, error, status_code=200): def file(self, request, fil): """Return a file.""" assert isinstance(fil, str), 'only string paths allowed' - response = yield from FILE_SENDER.send(request, Path(fil)) - return response + return web.FileResponse(fil) def register(self, router): """Register the view with a router.""" diff --git a/homeassistant/components/http/static.py b/homeassistant/components/http/static.py index 6489144ec704c0..21e955fc9686ef 100644 --- a/homeassistant/components/http/static.py +++ b/homeassistant/components/http/static.py @@ -3,14 +3,45 @@ import re from aiohttp import hdrs -from aiohttp.file_sender import FileSender +from aiohttp.web import FileResponse +from aiohttp.web_exceptions import HTTPNotFound from aiohttp.web_urldispatcher import StaticResource +from yarl import unquote + from .const import KEY_DEVELOPMENT _FINGERPRINT = re.compile(r'^(.+)-[a-z0-9]{32}\.(\w+)$', re.IGNORECASE) -class CachingFileSender(FileSender): +class CachingStaticResource(StaticResource): + """Static Resource handler that will add cache headers.""" + + @asyncio.coroutine + def _handle(self, request): + filename = unquote(request.match_info['filename']) + try: + # PyLint is wrong about resolve not being a member. + # pylint: disable=no-member + filepath = self._directory.joinpath(filename).resolve() + if not self._follow_symlinks: + filepath.relative_to(self._directory) + except (ValueError, FileNotFoundError) as error: + # relatively safe + raise HTTPNotFound() from error + except Exception as error: + # perm error or other kind! + request.app.logger.exception(error) + raise HTTPNotFound() from error + + if filepath.is_dir(): + return (yield from super()._handle(request)) + elif filepath.is_file(): + return CachingFileResponse(filepath, chunk_size=self._chunk_size) + else: + raise HTTPNotFound + + +class CachingFileResponse(FileResponse): """FileSender class that caches output if not in dev mode.""" def __init__(self, *args, **kwargs): @@ -20,46 +51,34 @@ def __init__(self, *args, **kwargs): orig_sendfile = self._sendfile @asyncio.coroutine - def sendfile(request, resp, fobj, count): + def sendfile(request, fobj, count): """Sendfile that includes a cache header.""" if not request.app[KEY_DEVELOPMENT]: cache_time = 31 * 86400 # = 1 month - resp.headers[hdrs.CACHE_CONTROL] = "public, max-age={}".format( + self.headers[hdrs.CACHE_CONTROL] = "public, max-age={}".format( cache_time) - yield from orig_sendfile(request, resp, fobj, count) + yield from orig_sendfile(request, fobj, count) # Overwriting like this because __init__ can change implementation. self._sendfile = sendfile -FILE_SENDER = FileSender() -CACHING_FILE_SENDER = CachingFileSender() - - @asyncio.coroutine def staticresource_middleware(app, handler): - """Enhance StaticResourceHandler middleware. - - Adds gzip encoding and fingerprinting matching. - """ - inst = getattr(handler, '__self__', None) - if not isinstance(inst, StaticResource): - return handler - - # pylint: disable=protected-access - inst._file_sender = CACHING_FILE_SENDER - + """Middleware to strip out fingerprint from fingerprinted assets.""" @asyncio.coroutine def static_middleware_handler(request): """Strip out fingerprints from resource names.""" + if not request.path.startswith('/static/'): + return handler(request) + fingerprinted = _FINGERPRINT.match(request.match_info['filename']) if fingerprinted: request.match_info['filename'] = \ '{}.{}'.format(*fingerprinted.groups()) - resp = yield from handler(request) - return resp + return handler(request) return static_middleware_handler diff --git a/homeassistant/components/image_processing/openalpr_cloud.py b/homeassistant/components/image_processing/openalpr_cloud.py index 7f8bd83116cbe8..1ba8dfcfbc44fa 100644 --- a/homeassistant/components/image_processing/openalpr_cloud.py +++ b/homeassistant/components/image_processing/openalpr_cloud.py @@ -112,8 +112,6 @@ def async_process_image(self, image): params['image_bytes'] = str(b64encode(image), 'utf-8') - data = None - request = None try: with async_timeout.timeout(self.timeout, loop=self.hass.loop): request = yield from websession.post( @@ -127,14 +125,10 @@ def async_process_image(self, image): request.status, data.get('error')) return - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.error("Timeout for openalpr api.") return - finally: - if request is not None: - yield from request.release() - # processing api data vehicles = 0 result = {} diff --git a/homeassistant/components/media_player/__init__.py b/homeassistant/components/media_player/__init__.py index a603cb9c3e30a5..511cb8208a5ee0 100644 --- a/homeassistant/components/media_player/__init__.py +++ b/homeassistant/components/media_player/__init__.py @@ -864,21 +864,17 @@ def _async_fetch_image(hass, url): content, content_type = (None, None) websession = async_get_clientsession(hass) - response = None try: with async_timeout.timeout(10, loop=hass.loop): response = yield from websession.get(url) - if response.status == 200: - content = yield from response.read() - content_type = response.headers.get(CONTENT_TYPE_HEADER) + + if response.status == 200: + content = yield from response.read() + content_type = response.headers.get(CONTENT_TYPE_HEADER) except asyncio.TimeoutError: pass - finally: - if response is not None: - yield from response.release() - if not content: return (None, None) diff --git a/homeassistant/components/media_player/squeezebox.py b/homeassistant/components/media_player/squeezebox.py index 6db376aa073fd8..eec8eeb8177742 100644 --- a/homeassistant/components/media_player/squeezebox.py +++ b/homeassistant/components/media_player/squeezebox.py @@ -117,7 +117,6 @@ def create_players(self): @asyncio.coroutine def async_query(self, *command, player=""): """Abstract out the JSON-RPC connection.""" - response = None auth = None if self._username is None else aiohttp.BasicAuth( self._username, self._password) url = "http://{}:{}/jsonrpc.js".format( @@ -138,22 +137,17 @@ def async_query(self, *command, player=""): data=data, auth=auth) - if response.status == 200: - data = yield from response.json() - else: + if response.status != 200: _LOGGER.error( "Query failed, response code: %s Full message: %s", response.status, response) return False - except (asyncio.TimeoutError, - aiohttp.errors.ClientError, - aiohttp.errors.ClientDisconnectedError) as error: + data = yield from response.json() + + except (asyncio.TimeoutError, aiohttp.ClientError) as error: _LOGGER.error("Failed communicating with LMS: %s", type(error)) return False - finally: - if response is not None: - yield from response.release() try: return data['result'] diff --git a/homeassistant/components/media_player/volumio.py b/homeassistant/components/media_player/volumio.py index bcd4ebd0c11ddb..5944921f94f096 100755 --- a/homeassistant/components/media_player/volumio.py +++ b/homeassistant/components/media_player/volumio.py @@ -68,7 +68,6 @@ def __init__(self, name, host, port, hass): def send_volumio_msg(self, method, params=None): """Send message.""" url = "http://{}:{}/api/v1/{}/".format(self.host, self.port, method) - response = None _LOGGER.debug("URL: %s params: %s", url, params) @@ -83,14 +82,9 @@ def send_volumio_msg(self, method, params=None): response.status, response) return False - except (asyncio.TimeoutError, - aiohttp.errors.ClientError, - aiohttp.errors.ClientDisconnectedError) as error: + except (asyncio.TimeoutError, aiohttp.ClientError) as error: _LOGGER.error("Failed communicating with Volumio: %s", type(error)) return False - finally: - if response is not None: - yield from response.release() try: return data diff --git a/homeassistant/components/microsoft_face.py b/homeassistant/components/microsoft_face.py index dc0e9001b24ae8..5d98f04d01ea67 100644 --- a/homeassistant/components/microsoft_face.py +++ b/homeassistant/components/microsoft_face.py @@ -359,30 +359,25 @@ def call_api(self, method, function, data=None, binary=False, else: payload = None - response = None try: with async_timeout.timeout(self.timeout, loop=self.hass.loop): response = yield from getattr(self.websession, method)( url, data=payload, headers=headers, params=params) answer = yield from response.json() - _LOGGER.debug("Read from microsoft face api: %s", answer) - if response.status == 200 or response.status == 202: - return answer - _LOGGER.warning("Error %d microsoft face api %s", - response.status, response.url) - raise HomeAssistantError(answer['error']['message']) + _LOGGER.debug("Read from microsoft face api: %s", answer) + if response.status < 300: + return answer - except (aiohttp.errors.ClientError, - aiohttp.errors.ClientDisconnectedError): + _LOGGER.warning("Error %d microsoft face api %s", + response.status, response.url) + raise HomeAssistantError(answer['error']['message']) + + except aiohttp.ClientError: _LOGGER.warning("Can't connect to microsoft face api") except asyncio.TimeoutError: _LOGGER.warning("Timeout from microsoft face api %s", response.url) - finally: - if response is not None: - yield from response.release() - raise HomeAssistantError("Network error on microsoft face api.") diff --git a/homeassistant/components/rest_command.py b/homeassistant/components/rest_command.py index abf25981af6cc5..7084339ab420c7 100644 --- a/homeassistant/components/rest_command.py +++ b/homeassistant/components/rest_command.py @@ -81,7 +81,6 @@ def async_service_handler(service): template_payload.async_render(variables=service.data), 'utf-8') - request = None try: with async_timeout.timeout(timeout, loop=hass.loop): request = yield from getattr(websession, method)( @@ -90,22 +89,18 @@ def async_service_handler(service): auth=auth ) - if request.status < 400: - _LOGGER.info("Success call %s.", request.url) - return - + if request.status < 400: + _LOGGER.info("Success call %s.", request.url) + else: _LOGGER.warning( "Error %d on call %s.", request.status, request.url) + except asyncio.TimeoutError: _LOGGER.warning("Timeout call %s.", request.url) - except aiohttp.errors.ClientError: + except aiohttp.ClientError: _LOGGER.error("Client error %s.", request.url) - finally: - if request is not None: - yield from request.release() - # register services hass.services.async_register(DOMAIN, name, async_service_handler) diff --git a/homeassistant/components/sensor/yr.py b/homeassistant/components/sensor/yr.py index 047edd0b994e64..4306ad68553723 100644 --- a/homeassistant/components/sensor/yr.py +++ b/homeassistant/components/sensor/yr.py @@ -151,6 +151,8 @@ def __init__(self, hass, coordinates, devices): @asyncio.coroutine def async_update(self, *_): """Get the latest data from yr.no.""" + import xmltodict + def try_again(err: str): """Retry in 15 minutes.""" _LOGGER.warning('Retrying in 15 minutes: %s', err) @@ -161,7 +163,6 @@ def try_again(err: str): nxt) if self._nextrun is None or dt_util.utcnow() >= self._nextrun: - resp = None try: websession = async_get_clientsession(self.hass) with async_timeout.timeout(10, loop=self.hass.loop): @@ -172,17 +173,11 @@ def try_again(err: str): return text = yield from resp.text() - except (asyncio.TimeoutError, aiohttp.errors.ClientError, - aiohttp.errors.ClientDisconnectedError) as err: + except (asyncio.TimeoutError, aiohttp.ClientError) as err: try_again(err) return - finally: - if resp is not None: - yield from resp.release() - try: - import xmltodict self.data = xmltodict.parse(text)['weatherdata'] model = self.data['meta']['model'] if '@nextrun' not in model: diff --git a/homeassistant/components/switch/hook.py b/homeassistant/components/switch/hook.py index a21d98147687b4..33b49a24caafde 100644 --- a/homeassistant/components/switch/hook.py +++ b/homeassistant/components/switch/hook.py @@ -34,7 +34,6 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): password = config.get(CONF_PASSWORD) websession = async_get_clientsession(hass) - response = None try: with async_timeout.timeout(TIMEOUT, loop=hass.loop): response = yield from websession.post( @@ -43,14 +42,9 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): 'username': username, 'password': password}) data = yield from response.json() - except (asyncio.TimeoutError, - aiohttp.errors.ClientError, - aiohttp.errors.ClientDisconnectedError) as error: + except (asyncio.TimeoutError, aiohttp.ClientError) as error: _LOGGER.error("Failed authentication API call: %s", error) return False - finally: - if response is not None: - yield from response.release() try: token = data['data']['token'] @@ -58,21 +52,15 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): _LOGGER.error("No token. Check username and password") return False - response = None try: with async_timeout.timeout(TIMEOUT, loop=hass.loop): response = yield from websession.get( '{}{}'.format(HOOK_ENDPOINT, 'device'), params={"token": data['data']['token']}) data = yield from response.json() - except (asyncio.TimeoutError, - aiohttp.errors.ClientError, - aiohttp.errors.ClientDisconnectedError) as error: + except (asyncio.TimeoutError, aiohttp.ClientError) as error: _LOGGER.error("Failed getting devices: %s", error) return False - finally: - if response is not None: - yield from response.release() async_add_devices( HookSmartHome( @@ -110,7 +98,6 @@ def is_on(self): @asyncio.coroutine def _send(self, url): """Send the url to the Hook API.""" - response = None try: _LOGGER.debug("Sending: %s", url) websession = async_get_clientsession(self.hass) @@ -119,16 +106,10 @@ def _send(self, url): url, params={"token": self._token}) data = yield from response.json() - except (asyncio.TimeoutError, - aiohttp.errors.ClientError, - aiohttp.errors.ClientDisconnectedError) as error: + except (asyncio.TimeoutError, aiohttp.ClientError) as error: _LOGGER.error("Failed setting state: %s", error) return False - finally: - if response is not None: - yield from response.release() - _LOGGER.debug("Got: %s", data) return data['return_value'] == '1' diff --git a/homeassistant/components/switch/rest.py b/homeassistant/components/switch/rest.py index 74add400850b6f..179b3b24068651 100644 --- a/homeassistant/components/switch/rest.py +++ b/homeassistant/components/switch/rest.py @@ -57,20 +57,21 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): body_off.hass = hass timeout = config.get(CONF_TIMEOUT) - req = None try: with async_timeout.timeout(timeout, loop=hass.loop): req = yield from websession.get(resource) + + if req.status >= 400: + _LOGGER.error('Got non-ok response from resource: %s', req.status) + return False + except (TypeError, ValueError): _LOGGER.error("Missing resource or schema in configuration. " "Add http:// or https:// to your URL") return False - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.error("No route to resource/endpoint: %s", resource) return False - finally: - if req is not None: - yield from req.release() async_add_devices( [RestSwitch(hass, name, resource, body_on, body_off, @@ -108,17 +109,13 @@ def async_turn_on(self, **kwargs): body_on_t = self._body_on.async_render() websession = async_get_clientsession(self.hass) - request = None try: with async_timeout.timeout(self._timeout, loop=self.hass.loop): request = yield from websession.post( self._resource, data=bytes(body_on_t, 'utf-8')) - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.error("Error while turn on %s", self._resource) return - finally: - if request is not None: - yield from request.release() if request.status == 200: self._state = True @@ -132,17 +129,13 @@ def async_turn_off(self, **kwargs): body_off_t = self._body_off.async_render() websession = async_get_clientsession(self.hass) - request = None try: with async_timeout.timeout(self._timeout, loop=self.hass.loop): request = yield from websession.post( self._resource, data=bytes(body_off_t, 'utf-8')) - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.error("Error while turn off %s", self._resource) return - finally: - if request is not None: - yield from request.release() if request.status == 200: self._state = False @@ -155,17 +148,13 @@ def async_update(self): """Get the latest data from REST API and update the state.""" websession = async_get_clientsession(self.hass) - request = None try: with async_timeout.timeout(self._timeout, loop=self.hass.loop): request = yield from websession.get(self._resource) text = yield from request.text() - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.exception("Error while fetch data.") return - finally: - if request is not None: - yield from request.release() if self._is_on_template is not None: text = self._is_on_template.async_render_with_possible_json_value( diff --git a/homeassistant/components/tts/google.py b/homeassistant/components/tts/google.py index be84e0e029b954..d433aef8c47ce4 100644 --- a/homeassistant/components/tts/google.py +++ b/homeassistant/components/tts/google.py @@ -95,7 +95,6 @@ def async_get_tts_audio(self, message, language, options=None): 'textlen': len(part), } - request = None try: with async_timeout.timeout(10, loop=self.hass.loop): request = yield from websession.get( @@ -109,14 +108,10 @@ def async_get_tts_audio(self, message, language, options=None): return (None, None) data += yield from request.read() - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.error("Timeout for google speech.") return (None, None) - finally: - if request is not None: - yield from request.release() - return ("mp3", data) @staticmethod diff --git a/homeassistant/components/tts/voicerss.py b/homeassistant/components/tts/voicerss.py index ee50cc30ccabb6..e8622d3b9a1eb4 100644 --- a/homeassistant/components/tts/voicerss.py +++ b/homeassistant/components/tts/voicerss.py @@ -123,7 +123,6 @@ def async_get_tts_audio(self, message, language, options=None): form_data['src'] = message form_data['hl'] = language - request = None try: with async_timeout.timeout(10, loop=self.hass.loop): request = yield from websession.post( @@ -141,12 +140,8 @@ def async_get_tts_audio(self, message, language, options=None): "Error receive %s from VoiceRSS", str(data, 'utf-8')) return (None, None) - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.error("Timeout for VoiceRSS API") return (None, None) - finally: - if request is not None: - yield from request.release() - return (self._extension, data) diff --git a/homeassistant/components/tts/yandextts.py b/homeassistant/components/tts/yandextts.py index b60f9cab61ee3a..fb95faf1ecf878 100644 --- a/homeassistant/components/tts/yandextts.py +++ b/homeassistant/components/tts/yandextts.py @@ -98,10 +98,8 @@ def supported_languages(self): def async_get_tts_audio(self, message, language, options=None): """Load TTS from yandex.""" websession = async_get_clientsession(self.hass) - actual_language = language - request = None try: with async_timeout.timeout(10, loop=self.hass.loop): url_param = { @@ -123,12 +121,8 @@ def async_get_tts_audio(self, message, language, options=None): return (None, None) data = yield from request.read() - except (asyncio.TimeoutError, aiohttp.errors.ClientError): + except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.error("Timeout for yandex speech kit api.") return (None, None) - finally: - if request is not None: - yield from request.release() - return (self._codec, data) diff --git a/homeassistant/helpers/aiohttp_client.py b/homeassistant/helpers/aiohttp_client.py index 75755ad36859b2..8dc64105e8b52b 100644 --- a/homeassistant/helpers/aiohttp_client.py +++ b/homeassistant/helpers/aiohttp_client.py @@ -5,7 +5,7 @@ import aiohttp from aiohttp.hdrs import USER_AGENT, CONTENT_TYPE from aiohttp import web -from aiohttp.web_exceptions import HTTPGatewayTimeout +from aiohttp.web_exceptions import HTTPGatewayTimeout, HTTPBadGateway import async_timeout from homeassistant.core import callback @@ -71,42 +71,46 @@ def async_create_clientsession(hass, verify_ssl=True, auto_cleanup=True, @asyncio.coroutine -def async_aiohttp_proxy_stream(hass, request, stream_coro, buffer_size=102400, - timeout=10): +def async_aiohttp_proxy_web(hass, request, web_coro, buffer_size=102400, + timeout=10): """Stream websession request to aiohttp web response.""" - response = None - stream = None - try: with async_timeout.timeout(timeout, loop=hass.loop): - stream = yield from stream_coro + req = yield from web_coro + + except asyncio.TimeoutError as err: + raise HTTPGatewayTimeout() from err + + except aiohttp.ClientError as err: + raise HTTPBadGateway() from err - response = web.StreamResponse() - response.content_type = stream.headers.get(CONTENT_TYPE) + yield from async_aiohttp_proxy_stream(hass, request, req.content, + req.headers.get(CONTENT_TYPE)) - yield from response.prepare(request) +@asyncio.coroutine +def async_aiohttp_proxy_stream(hass, request, stream, content_type, + buffer_size=102400, timeout=10): + """Stream a stream to aiohttp web response.""" + response = web.StreamResponse() + response.content_type = content_type + yield from response.prepare(request) + + try: while True: - data = yield from stream.content.read(buffer_size) + with async_timeout.timeout(timeout, loop=hass.loop): + data = yield from stream.read(buffer_size) + if not data: + yield from response.write_eof() break - response.write(data) - except asyncio.TimeoutError: - raise HTTPGatewayTimeout() + response.write(data) - except (aiohttp.errors.ClientError, - aiohttp.errors.ClientDisconnectedError): + except (asyncio.TimeoutError, aiohttp.ClientError): pass - except (asyncio.CancelledError, ConnectionResetError): - response = None - - finally: - if stream is not None: - stream.close() - if response is not None: - yield from response.write_eof() + yield from response.write_eof() @callback @@ -149,10 +153,10 @@ def _async_get_connector(hass, verify_ssl=True): connector = hass.data[DATA_CONNECTOR_NOTVERIFY] if is_new: - @asyncio.coroutine + @callback def _async_close_connector(event): """Close connector pool.""" - yield from connector.close() + connector.close() hass.bus.async_listen_once( EVENT_HOMEASSISTANT_CLOSE, _async_close_connector) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index cc8280bd6c5f88..2b22a367121f64 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -5,5 +5,5 @@ pip>=7.1.0 jinja2>=2.9.5 voluptuous==0.9.3 typing>=3,<4 -aiohttp==1.3.5 +aiohttp==2.0.4 async_timeout==1.2.0 diff --git a/requirements_all.txt b/requirements_all.txt index d97e830874c723..29ef28c5ed7600 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -6,7 +6,7 @@ pip>=7.1.0 jinja2>=2.9.5 voluptuous==0.9.3 typing>=3,<4 -aiohttp==1.3.5 +aiohttp==2.0.4 async_timeout==1.2.0 # homeassistant.components.nuimo_controller diff --git a/setup.py b/setup.py index 0f2c6e6d876b12..966ae72bc88951 100755 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ 'jinja2>=2.9.5', 'voluptuous==0.9.3', 'typing>=3,<4', - 'aiohttp==1.3.5', + 'aiohttp==2.0.4', 'async_timeout==1.2.0', ] diff --git a/tests/components/sensor/test_darksky.py b/tests/components/sensor/test_darksky.py index 54453f42d43914..7ee04b0df4cda0 100644 --- a/tests/components/sensor/test_darksky.py +++ b/tests/components/sensor/test_darksky.py @@ -36,10 +36,8 @@ def setUp(self): 'monitored_conditions': ['summary', 'icon', 'temperature_max'], 'update_interval': timedelta(seconds=120), } - self.lat = 37.8267 - self.lon = -122.423 - self.hass.config.latitude = self.lat - self.hass.config.longitude = self.lon + self.lat = self.hass.config.latitude = 37.8267 + self.lon = self.hass.config.longitude = -122.423 self.entities = [] def tearDown(self): # pylint: disable=invalid-name @@ -51,11 +49,6 @@ def test_setup_with_config(self): 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(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.""" diff --git a/tests/components/switch/test_rest.py b/tests/components/switch/test_rest.py index a2da94b614aea8..5a9ce679edfc05 100644 --- a/tests/components/switch/test_rest.py +++ b/tests/components/switch/test_rest.py @@ -42,7 +42,7 @@ def test_setup_missing_schema(self): def test_setup_failed_connect(self, aioclient_mock): """Test setup when connection error occurs.""" - aioclient_mock.get('http://localhost', exc=aiohttp.errors.ClientError) + aioclient_mock.get('http://localhost', exc=aiohttp.ClientError) assert not run_coroutine_threadsafe( rest.async_setup_platform(self.hass, { 'platform': 'rest', diff --git a/tests/components/test_api.py b/tests/components/test_api.py index 2cdc359bfeac7b..e2d93c9cce7008 100644 --- a/tests/components/test_api.py +++ b/tests/components/test_api.py @@ -1,12 +1,9 @@ """The tests for the Home Assistant API component.""" # pylint: disable=protected-access -import asyncio from contextlib import closing import json import unittest -from unittest.mock import Mock, patch -from aiohttp import web import requests from homeassistant import setup, const @@ -247,22 +244,6 @@ def test_api_get_components(self): headers=HA_HEADERS) self.assertEqual(hass.config.components, set(req.json())) - def test_api_get_error_log(self): - """Test the return of the error log.""" - test_string = 'Test String°' - - @asyncio.coroutine - def mock_send(): - """Mock file send.""" - return web.Response(text=test_string) - - with patch('homeassistant.components.http.HomeAssistantView.file', - Mock(return_value=mock_send())): - req = requests.get(_url(const.URL_API_ERROR_LOG), - headers=HA_HEADERS) - self.assertEqual(test_string, req.text) - self.assertIsNone(req.headers.get('expires')) - def test_api_get_event_listeners(self): """Test if we can get the list of events being listened for.""" req = requests.get(_url(const.URL_API_EVENTS), diff --git a/tests/components/test_frontend.py b/tests/components/test_frontend.py index 0c42d05f3aeefc..952061be3c2d02 100644 --- a/tests/components/test_frontend.py +++ b/tests/components/test_frontend.py @@ -1,89 +1,69 @@ """The tests for Home Assistant frontend.""" -# pylint: disable=protected-access +import asyncio import re -import unittest -import requests +import pytest -from homeassistant import setup -from homeassistant.components import http -from homeassistant.const import HTTP_HEADER_HA_AUTH +from homeassistant.setup import async_setup_component -from tests.common import get_test_instance_port, get_test_home_assistant -API_PASSWORD = "test1234" -SERVER_PORT = get_test_instance_port() -HTTP_BASE_URL = "http://127.0.0.1:{}".format(SERVER_PORT) -HA_HEADERS = {HTTP_HEADER_HA_AUTH: API_PASSWORD} +@pytest.fixture +def mock_http_client(loop, hass, test_client): + """Start the Hass HTTP component.""" + loop.run_until_complete(async_setup_component(hass, 'frontend', {})) + return loop.run_until_complete(test_client(hass.http.app)) -hass = None +@asyncio.coroutine +def test_frontend_and_static(mock_http_client): + """Test if we can get the frontend.""" + resp = yield from mock_http_client.get('') + assert resp.status == 200 + assert 'cache-control' not in resp.headers -def _url(path=""): - """Helper method to generate URLs.""" - return HTTP_BASE_URL + path + text = yield from resp.text() + # Test we can retrieve frontend.js + frontendjs = re.search( + r'(?P\/static\/frontend-[A-Za-z0-9]{32}.html)', text) -# pylint: disable=invalid-name -def setUpModule(): - """Initialize a Home Assistant server.""" - global hass + assert frontendjs is not None + resp = yield from mock_http_client.get(frontendjs.groups(0)[0]) + assert resp.status == 200 + assert 'public' in resp.headers.get('cache-control') - hass = get_test_home_assistant() - assert setup.setup_component( - hass, http.DOMAIN, - {http.DOMAIN: {http.CONF_API_PASSWORD: API_PASSWORD, - http.CONF_SERVER_PORT: SERVER_PORT}}) +@asyncio.coroutine +def test_dont_cache_service_worker(mock_http_client): + """Test that we don't cache the service worker.""" + resp = yield from mock_http_client.get('/service_worker.js') + assert resp.status == 200 + assert 'cache-control' not in resp.headers - assert setup.setup_component(hass, 'frontend') - hass.start() +@asyncio.coroutine +def test_404(mock_http_client): + """Test for HTTP 404 error.""" + resp = yield from mock_http_client.get('/not-existing') + assert resp.status == 404 -# pylint: disable=invalid-name -def tearDownModule(): - """Stop everything that was started.""" - hass.stop() +@asyncio.coroutine +def test_we_cannot_POST_to_root(mock_http_client): + """Test that POST is not allow to root.""" + resp = yield from mock_http_client.post('/') + assert resp.status == 405 -class TestFrontend(unittest.TestCase): - """Test the frontend.""" +@asyncio.coroutine +def test_states_routes(hass, mock_http_client): + """All served by index.""" + resp = yield from mock_http_client.get('/states') + assert resp.status == 200 - def tearDown(self): - """Stop everything that was started.""" - hass.block_till_done() + resp = yield from mock_http_client.get('/states/group.non_existing') + assert resp.status == 404 - def test_frontend_and_static(self): - """Test if we can get the frontend.""" - req = requests.get(_url("")) - self.assertEqual(200, req.status_code) - - # Test we can retrieve frontend.js - frontendjs = re.search( - r'(?P\/static\/frontend-[A-Za-z0-9]{32}.html)', - req.text) - - self.assertIsNotNone(frontendjs) - req = requests.get(_url(frontendjs.groups(0)[0])) - self.assertEqual(200, req.status_code) - - def test_404(self): - """Test for HTTP 404 error.""" - self.assertEqual(404, requests.get(_url("/not-existing")).status_code) - - def test_we_cannot_POST_to_root(self): - """Test that POST is not allow to root.""" - self.assertEqual(405, requests.post(_url("")).status_code) - - def test_states_routes(self): - """All served by index.""" - req = requests.get(_url("/states")) - self.assertEqual(200, req.status_code) - - req = requests.get(_url("/states/group.non_existing")) - self.assertEqual(404, req.status_code) - - hass.states.set('group.existing', 'on', {'view': True}) - req = requests.get(_url("/states/group.existing")) - self.assertEqual(200, req.status_code) + hass.states.async_set('group.existing', 'on', {'view': True}) + resp = yield from mock_http_client.get('/states/group.existing') + assert resp.status == 200 diff --git a/tests/components/test_rest_command.py b/tests/components/test_rest_command.py index a62bddc4a0fa23..0648a30c922506 100644 --- a/tests/components/test_rest_command.py +++ b/tests/components/test_rest_command.py @@ -107,7 +107,7 @@ def test_rest_command_aiohttp_error(self, aioclient_mock): with assert_setup_component(4): setup_component(self.hass, rc.DOMAIN, self.config) - aioclient_mock.get(self.url, exc=aiohttp.errors.ClientError()) + aioclient_mock.get(self.url, exc=aiohttp.ClientError()) self.hass.services.call(rc.DOMAIN, 'get_test', {}) self.hass.block_till_done() diff --git a/tests/components/test_sleepiq.py b/tests/components/test_sleepiq.py index 3c7551d130c4ef..becf897a8e9c79 100644 --- a/tests/components/test_sleepiq.py +++ b/tests/components/test_sleepiq.py @@ -1,5 +1,7 @@ """The tests for the SleepIQ component.""" import unittest +from unittest.mock import MagicMock, patch + import requests_mock from homeassistant import setup @@ -49,8 +51,12 @@ def test_setup(self, mock): """Test the setup.""" mock_responses(mock) - response = sleepiq.setup(self.hass, self.config) - self.assertTrue(response) + # We're mocking the load_platform discoveries or else the platforms + # will be setup during tear down when blocking till done, but the mocks + # are no longer active. + with patch( + 'homeassistant.helpers.discovery.load_platform', MagicMock()): + assert sleepiq.setup(self.hass, self.config) @requests_mock.Mocker() def test_setup_login_failed(self, mock): diff --git a/tests/helpers/test_aiohttp_client.py b/tests/helpers/test_aiohttp_client.py index 42e2697b7a7ea7..7aa7f6fa4d16ec 100644 --- a/tests/helpers/test_aiohttp_client.py +++ b/tests/helpers/test_aiohttp_client.py @@ -5,7 +5,7 @@ import aiohttp from homeassistant.core import EVENT_HOMEASSISTANT_CLOSE -from homeassistant.setup import setup_component +from homeassistant.setup import async_setup_component import homeassistant.helpers.aiohttp_client as client from homeassistant.util.async import run_callback_threadsafe @@ -119,22 +119,19 @@ def test_get_clientsession_cleanup_without_ssl(self): @asyncio.coroutine -def test_fetching_url(aioclient_mock, hass, test_client): +def test_async_aiohttp_proxy_stream(aioclient_mock, hass, test_client): """Test that it fetches the given url.""" aioclient_mock.get('http://example.com/mjpeg_stream', content=[ b'Frame1', b'Frame2', b'Frame3' ]) - def setup_platform(): - """Setup the platform.""" - assert setup_component(hass, 'camera', { - 'camera': { - 'name': 'config_test', - 'platform': 'mjpeg', - 'mjpeg_url': 'http://example.com/mjpeg_stream', - }}) - - yield from hass.loop.run_in_executor(None, setup_platform) + result = yield from async_setup_component(hass, 'camera', { + 'camera': { + 'name': 'config_test', + 'platform': 'mjpeg', + 'mjpeg_url': 'http://example.com/mjpeg_stream', + }}) + assert result, 'Failed to setup camera' client = yield from test_client(hass.http.app) @@ -151,29 +148,12 @@ def setup_platform(): content=[b'Frame1', b'Frame2', b'Frame3']) resp = yield from client.get('/api/camera_proxy_stream/camera.config_test') - - assert resp.status == 200 - body = yield from resp.text() - assert body == '' - - aioclient_mock.clear_requests() - aioclient_mock.get( - 'http://example.com/mjpeg_stream', exc=asyncio.CancelledError(), - content=[b'Frame1', b'Frame2', b'Frame3']) - - resp = yield from client.get('/api/camera_proxy_stream/camera.config_test') - - assert resp.status == 200 - body = yield from resp.text() - assert body == '' + assert resp.status == 504 aioclient_mock.clear_requests() aioclient_mock.get( - 'http://example.com/mjpeg_stream', exc=aiohttp.errors.ClientError(), + 'http://example.com/mjpeg_stream', exc=aiohttp.ClientError(), content=[b'Frame1', b'Frame2', b'Frame3']) resp = yield from client.get('/api/camera_proxy_stream/camera.config_test') - - assert resp.status == 200 - body = yield from resp.text() - assert body == '' + assert resp.status == 502 From ee8701b560e180caa6a446be270c3a493a66c5eb Mon Sep 17 00:00:00 2001 From: Beat Date: Thu, 30 Mar 2017 15:26:11 +0200 Subject: [PATCH 050/116] Fix configuration setup (#6853) When the user exceeds the request limit for google APIs, the response status stays at 200 but the response body is different: ``` { "error_message" : "You have exceeded your daily request quota for this API. We recommend registering for a key at the Google Developers Console: https://console.developers.google.com/apis/credentials?project=_", "results" : [], "status" : "OVER_QUERY_LIMIT" } ``` This prevents HA from creating the initial configuration --- homeassistant/util/location.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/util/location.py b/homeassistant/util/location.py index d3c35457dbcac6..950f2f99fedc5b 100644 --- a/homeassistant/util/location.py +++ b/homeassistant/util/location.py @@ -76,7 +76,7 @@ def elevation(latitude, longitude): try: return int(float(req.json()['results'][0]['elevation'])) - except (ValueError, KeyError): + except (ValueError, KeyError, IndexError): return 0 From 816b1891b52edb77a9874cc9779e10af234413e9 Mon Sep 17 00:00:00 2001 From: Johan Bloemberg Date: Thu, 30 Mar 2017 17:02:03 +0200 Subject: [PATCH 051/116] Add option to disable automatic add for lights and sensors. (#6852) --- homeassistant/components/light/rflink.py | 8 +++--- homeassistant/components/rflink.py | 1 + homeassistant/components/sensor/rflink.py | 10 +++++--- tests/components/light/test_rflink.py | 28 +++++++++++++++++++++ tests/components/sensor/test_rflink.py | 30 +++++++++++++++++++++++ 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/light/rflink.py b/homeassistant/components/light/rflink.py index a36a4f43f22b6e..e0b627f1ffa77d 100644 --- a/homeassistant/components/light/rflink.py +++ b/homeassistant/components/light/rflink.py @@ -10,8 +10,8 @@ from homeassistant.components.light import ( ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, Light) from homeassistant.components.rflink import ( - CONF_ALIASSES, CONF_DEVICE_DEFAULTS, CONF_DEVICES, CONF_FIRE_EVENT, - CONF_GROUP, CONF_GROUP_ALIASSES, CONF_IGNORE_DEVICES, + CONF_ALIASSES, CONF_AUTOMATIC_ADD, CONF_DEVICE_DEFAULTS, CONF_DEVICES, + CONF_FIRE_EVENT, CONF_GROUP, CONF_GROUP_ALIASSES, CONF_IGNORE_DEVICES, CONF_NOGROUP_ALIASSES, CONF_SIGNAL_REPETITIONS, DATA_DEVICE_REGISTER, DATA_ENTITY_GROUP_LOOKUP, DATA_ENTITY_LOOKUP, DEVICE_DEFAULTS_SCHEMA, DOMAIN, EVENT_KEY_COMMAND, EVENT_KEY_ID, SwitchableRflinkDevice, cv, vol) @@ -32,6 +32,7 @@ vol.Optional(CONF_IGNORE_DEVICES): vol.All(cv.ensure_list, [cv.string]), vol.Optional(CONF_DEVICE_DEFAULTS, default=DEVICE_DEFAULTS_SCHEMA({})): DEVICE_DEFAULTS_SCHEMA, + vol.Optional(CONF_AUTOMATIC_ADD, default=True): cv.boolean, vol.Optional(CONF_DEVICES, default={}): vol.Schema({ cv.string: { vol.Optional(CONF_NAME): cv.string, @@ -165,7 +166,8 @@ def add_new_device(event): # Schedule task to process event after entity is created hass.async_add_job(device.handle_event, event) - hass.data[DATA_DEVICE_REGISTER][EVENT_KEY_COMMAND] = add_new_device + if config[CONF_AUTOMATIC_ADD]: + hass.data[DATA_DEVICE_REGISTER][EVENT_KEY_COMMAND] = add_new_device class RflinkLight(SwitchableRflinkDevice, Light): diff --git a/homeassistant/components/rflink.py b/homeassistant/components/rflink.py index 2986b898ed0586..52fd602f0ded97 100644 --- a/homeassistant/components/rflink.py +++ b/homeassistant/components/rflink.py @@ -33,6 +33,7 @@ CONF_NOGROUP_ALIASSES = 'nogroup_aliasses' CONF_DEVICE_DEFAULTS = 'device_defaults' CONF_DEVICES = 'devices' +CONF_AUTOMATIC_ADD = 'automatic_add' CONF_FIRE_EVENT = 'fire_event' CONF_IGNORE_DEVICES = 'ignore_devices' CONF_RECONNECT_INTERVAL = 'reconnect_interval' diff --git a/homeassistant/components/sensor/rflink.py b/homeassistant/components/sensor/rflink.py index 80a5b7dfb8daea..c6660701c2152e 100644 --- a/homeassistant/components/sensor/rflink.py +++ b/homeassistant/components/sensor/rflink.py @@ -9,9 +9,9 @@ import logging from homeassistant.components.rflink import ( - CONF_ALIASSES, CONF_DEVICES, DATA_DEVICE_REGISTER, DATA_ENTITY_LOOKUP, - DOMAIN, EVENT_KEY_ID, EVENT_KEY_SENSOR, EVENT_KEY_UNIT, RflinkDevice, - cv, vol) + CONF_ALIASSES, CONF_AUTOMATIC_ADD, CONF_DEVICES, DATA_DEVICE_REGISTER, + DATA_ENTITY_LOOKUP, DOMAIN, EVENT_KEY_ID, EVENT_KEY_SENSOR, EVENT_KEY_UNIT, + RflinkDevice, cv, vol) from homeassistant.const import ( ATTR_UNIT_OF_MEASUREMENT, CONF_NAME, CONF_PLATFORM, CONF_UNIT_OF_MEASUREMENT) @@ -30,6 +30,7 @@ PLATFORM_SCHEMA = vol.Schema({ vol.Required(CONF_PLATFORM): DOMAIN, + vol.Optional(CONF_AUTOMATIC_ADD, default=True): cv.boolean, vol.Optional(CONF_DEVICES, default={}): vol.Schema({ cv.string: { vol.Optional(CONF_NAME): cv.string, @@ -91,7 +92,8 @@ def add_new_device(event): # Schedule task to process event after entity is created hass.async_add_job(device.handle_event, event) - hass.data[DATA_DEVICE_REGISTER][EVENT_KEY_SENSOR] = add_new_device + if config[CONF_AUTOMATIC_ADD]: + hass.data[DATA_DEVICE_REGISTER][EVENT_KEY_SENSOR] = add_new_device class RflinkSensor(RflinkDevice): diff --git a/tests/components/light/test_rflink.py b/tests/components/light/test_rflink.py index 9f1d98b0ffd5c2..7eaa8e8fc6dd36 100644 --- a/tests/components/light/test_rflink.py +++ b/tests/components/light/test_rflink.py @@ -533,3 +533,31 @@ def test_nogroup_device_id(hass, monkeypatch): yield from hass.async_block_till_done() # should affect state assert hass.states.get('light.test').state == 'on' + + +@asyncio.coroutine +def test_disable_automatic_add(hass, monkeypatch): + """If disabled new devices should not be automatically added.""" + config = { + 'rflink': { + 'port': '/dev/ttyABC0', + }, + DOMAIN: { + 'platform': 'rflink', + 'automatic_add': False, + }, + } + + # setup mocking rflink module + event_callback, _, _, _ = yield from mock_rflink( + hass, config, DOMAIN, monkeypatch) + + # test event for new unconfigured sensor + event_callback({ + 'id': 'protocol_0_0', + 'command': 'off', + }) + yield from hass.async_block_till_done() + + # make sure new device is not added + assert not hass.states.get('light.protocol_0_0') diff --git a/tests/components/sensor/test_rflink.py b/tests/components/sensor/test_rflink.py index 2925551ee06834..a99d14cc735007 100644 --- a/tests/components/sensor/test_rflink.py +++ b/tests/components/sensor/test_rflink.py @@ -70,3 +70,33 @@ def test_default_setup(hass, monkeypatch): assert new_sensor.state == '0' assert new_sensor.attributes['unit_of_measurement'] == '°C' assert new_sensor.attributes['icon'] == 'mdi:thermometer' + + +@asyncio.coroutine +def test_disable_automatic_add(hass, monkeypatch): + """If disabled new devices should not be automatically added.""" + config = { + 'rflink': { + 'port': '/dev/ttyABC0', + }, + DOMAIN: { + 'platform': 'rflink', + 'automatic_add': False, + }, + } + + # setup mocking rflink module + event_callback, _, _, _ = yield from mock_rflink( + hass, config, DOMAIN, monkeypatch) + + # test event for new unconfigured sensor + event_callback({ + 'id': 'test2', + 'sensor': 'temperature', + 'value': 0, + 'unit': '°C', + }) + yield from hass.async_block_till_done() + + # make sure new device is not added + assert not hass.states.get('sensor.test2') From 72db4a80ddd8a1286f41d84667ca10cee4487009 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Thu, 30 Mar 2017 17:27:53 +0200 Subject: [PATCH 052/116] Update aioHTTP to 2.0.5 (#6856) --- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 2b22a367121f64..e052c662e3b235 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -5,5 +5,5 @@ pip>=7.1.0 jinja2>=2.9.5 voluptuous==0.9.3 typing>=3,<4 -aiohttp==2.0.4 +aiohttp==2.0.5 async_timeout==1.2.0 diff --git a/requirements_all.txt b/requirements_all.txt index 29ef28c5ed7600..cb2f9fdff5c9ac 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -6,7 +6,7 @@ pip>=7.1.0 jinja2>=2.9.5 voluptuous==0.9.3 typing>=3,<4 -aiohttp==2.0.4 +aiohttp==2.0.5 async_timeout==1.2.0 # homeassistant.components.nuimo_controller diff --git a/setup.py b/setup.py index 966ae72bc88951..5e973790dcc253 100755 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ 'jinja2>=2.9.5', 'voluptuous==0.9.3', 'typing>=3,<4', - 'aiohttp==2.0.4', + 'aiohttp==2.0.5', 'async_timeout==1.2.0', ] From 5bb201c7fc5f8a8232385d09ef4be6bc68cd7111 Mon Sep 17 00:00:00 2001 From: "Craig J. Ward" Date: Fri, 31 Mar 2017 01:53:11 -0500 Subject: [PATCH 053/116] use change light level to avoid variable ramp speeds (#6860) --- homeassistant/components/light/insteon_local.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/light/insteon_local.py b/homeassistant/components/light/insteon_local.py index 865458eae24a25..27f297a82f03e8 100644 --- a/homeassistant/components/light/insteon_local.py +++ b/homeassistant/components/light/insteon_local.py @@ -175,7 +175,7 @@ def turn_on(self, **kwargs): if ATTR_BRIGHTNESS in kwargs: brightness = int(kwargs[ATTR_BRIGHTNESS]) / 255 * 100 - self.node.on(brightness) + self.node.change_level(brightness) def turn_off(self, **kwargs): """Turn device off.""" From 8c97bccaaa3950fbe2701d213ab51782f62daec5 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 31 Mar 2017 02:55:22 -0700 Subject: [PATCH 054/116] Handle aiohttp task cancellation better (#6862) --- homeassistant/components/camera/__init__.py | 21 ++++++++++----------- homeassistant/helpers/aiohttp_client.py | 13 +++++++++++-- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/camera/__init__.py b/homeassistant/components/camera/__init__.py index d3c6699f77c8e7..388a9fce39bbbd 100644 --- a/homeassistant/components/camera/__init__.py +++ b/homeassistant/components/camera/__init__.py @@ -7,6 +7,7 @@ """ import asyncio import collections +from contextlib import suppress from datetime import timedelta import logging import hashlib @@ -167,7 +168,7 @@ def write(img_bytes): if not img_bytes: break - if img_bytes is not None and img_bytes != last_image: + if img_bytes and img_bytes != last_image: write(img_bytes) # Chrome seems to always ignore first picture, @@ -180,8 +181,8 @@ def write(img_bytes): yield from asyncio.sleep(.5) - except (asyncio.CancelledError, ConnectionResetError): - _LOGGER.debug("Close stream by frontend.") + except asyncio.CancelledError: + _LOGGER.debug("Stream closed by frontend.") response = None finally: @@ -263,16 +264,14 @@ class CameraImageView(CameraView): @asyncio.coroutine def handle(self, request, camera): """Serve camera image.""" - try: - image = yield from camera.async_camera_image() + with suppress(asyncio.CancelledError, asyncio.TimeoutError): + with async_timeout.timeout(10, loop=request.app['hass'].loop): + image = yield from camera.async_camera_image() - if image is None: - return web.Response(status=500) + if image: + return web.Response(body=image) - return web.Response(body=image) - - except asyncio.CancelledError: - _LOGGER.debug("Close stream by frontend.") + return web.Response(status=500) class CameraMjpegStream(CameraView): diff --git a/homeassistant/helpers/aiohttp_client.py b/homeassistant/helpers/aiohttp_client.py index 8dc64105e8b52b..9aac258684f85b 100644 --- a/homeassistant/helpers/aiohttp_client.py +++ b/homeassistant/helpers/aiohttp_client.py @@ -78,10 +78,16 @@ def async_aiohttp_proxy_web(hass, request, web_coro, buffer_size=102400, with async_timeout.timeout(timeout, loop=hass.loop): req = yield from web_coro + except asyncio.CancelledError: + # The user cancelled the request + return + except asyncio.TimeoutError as err: + # Timeout trying to start the web request raise HTTPGatewayTimeout() from err except aiohttp.ClientError as err: + # Something went wrong with the connection raise HTTPBadGateway() from err yield from async_aiohttp_proxy_stream(hass, request, req.content, @@ -108,9 +114,12 @@ def async_aiohttp_proxy_stream(hass, request, stream, content_type, response.write(data) except (asyncio.TimeoutError, aiohttp.ClientError): - pass + # Something went wrong fetching data, close connection gracefully + yield from response.write_eof() - yield from response.write_eof() + except asyncio.CancelledError: + # The user closed the connection + pass @callback From 05398a9dff06bd9d79783786ccab3fa194748786 Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Fri, 31 Mar 2017 11:53:56 -0400 Subject: [PATCH 055/116] Introduced Ring binary sensors and refactored Ring component (#6520) * - Introduced Ring binary_sensor. - Added unittest for Ring binary_sensor. - Bumped ring_doorbell 3rd party module. * Updated requirements * Added correct file for unittest * - Introduced Ring binary_sensor. - Added unittest for Ring binary_sensor. - Bumped ring_doorbell 3rd party module. * Updated requirements * Added correct file for unittest * Added extra sensors last_ding and last_motion * Modified Ring binary_sensor and sensor to inherit DOMAIN configuration * Moved static to top ring.py * Fixed requirements * Bump version ring_doorbell to 0.1.2 * testing unittests * Use hass.data dict instead GLOBALS * Fixed unittests * Bump ring_doorbell to 0.1.3 * Updated unittest and coverted to use decorator @requests_mock.Mocker() * Updated ring_session with lower case --- .../components/binary_sensor/ring.py | 109 ++++++++++ homeassistant/components/ring.py | 63 ++++++ homeassistant/components/sensor/ring.py | 64 ++---- requirements_all.txt | 4 +- tests/components/binary_sensor/test_ring.py | 63 ++++++ tests/components/sensor/test_ring.py | 202 +++--------------- tests/components/test_ring.py | 56 +++++ tests/fixtures/ring_devices.json | 79 +++++++ tests/fixtures/ring_ding_active.json | 26 +++ tests/fixtures/ring_doorbots.json | 10 + tests/fixtures/ring_session.json | 36 ++++ 11 files changed, 494 insertions(+), 218 deletions(-) create mode 100644 homeassistant/components/binary_sensor/ring.py create mode 100644 homeassistant/components/ring.py create mode 100644 tests/components/binary_sensor/test_ring.py create mode 100644 tests/components/test_ring.py create mode 100644 tests/fixtures/ring_devices.json create mode 100644 tests/fixtures/ring_ding_active.json create mode 100644 tests/fixtures/ring_doorbots.json create mode 100644 tests/fixtures/ring_session.json diff --git a/homeassistant/components/binary_sensor/ring.py b/homeassistant/components/binary_sensor/ring.py new file mode 100644 index 00000000000000..429e92afa7fc30 --- /dev/null +++ b/homeassistant/components/binary_sensor/ring.py @@ -0,0 +1,109 @@ +""" +This component provides HA sensor support for Ring Door Bell/Chimes. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/binary_sensor.ring/ +""" +import logging +from datetime import timedelta + +import voluptuous as vol +import homeassistant.helpers.config_validation as cv + +from homeassistant.components.ring import ( + CONF_ATTRIBUTION, DEFAULT_ENTITY_NAMESPACE) + +from homeassistant.const import ( + ATTR_ATTRIBUTION, CONF_ENTITY_NAMESPACE, CONF_MONITORED_CONDITIONS) + +from homeassistant.components.binary_sensor import ( + BinarySensorDevice, PLATFORM_SCHEMA) + +DEPENDENCIES = ['ring'] + +_LOGGER = logging.getLogger(__name__) + +SCAN_INTERVAL = timedelta(seconds=5) + +# Sensor types: Name, category, device_class +SENSOR_TYPES = { + 'ding': ['Ding', ['doorbell'], 'occupancy'], + 'motion': ['Motion', ['doorbell'], 'motion'], +} + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Optional(CONF_ENTITY_NAMESPACE, default=DEFAULT_ENTITY_NAMESPACE): + cv.string, + vol.Required(CONF_MONITORED_CONDITIONS, default=[]): + vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]), +}) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Set up a sensor for a Ring device.""" + ring = hass.data.get('ring') + + sensors = [] + for sensor_type in config.get(CONF_MONITORED_CONDITIONS): + for device in ring.doorbells: + if 'doorbell' in SENSOR_TYPES[sensor_type][1]: + sensors.append(RingBinarySensor(hass, + device, + sensor_type)) + add_devices(sensors, True) + return True + + +class RingBinarySensor(BinarySensorDevice): + """A binary sensor implementation for Ring device.""" + + def __init__(self, hass, data, sensor_type): + """Initialize a sensor for Ring device.""" + super(RingBinarySensor, self).__init__() + self._sensor_type = sensor_type + self._data = data + self._name = "{0} {1}".format(self._data.name, + SENSOR_TYPES.get(self._sensor_type)[0]) + self._device_class = SENSOR_TYPES.get(self._sensor_type)[2] + self._state = None + + @property + def name(self): + """Return the name of the sensor.""" + return self._name + + @property + def is_on(self): + """Return True if the binary sensor is on.""" + return self._state + + @property + def device_class(self): + """Return the class of the binary sensor.""" + return self._device_class + + @property + def device_state_attributes(self): + """Return the state attributes.""" + attrs = {} + attrs[ATTR_ATTRIBUTION] = CONF_ATTRIBUTION + + attrs['device_id'] = self._data.id + attrs['firmware'] = self._data.firmware + attrs['timezone'] = self._data.timezone + + if self._data.alert and self._data.alert_expires_at: + attrs['expires_at'] = self._data.alert_expires_at + attrs['state'] = self._data.alert.get('state') + + return attrs + + def update(self): + """Get the latest data and updates the state.""" + self._data.check_alerts() + + if self._data.alert: + self._state = (self._sensor_type == + self._data.alert.get('kind')) + else: + self._state = False diff --git a/homeassistant/components/ring.py b/homeassistant/components/ring.py new file mode 100644 index 00000000000000..61c772eced730a --- /dev/null +++ b/homeassistant/components/ring.py @@ -0,0 +1,63 @@ +""" +Support for Ring Doorbell/Chimes. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/ring/ +""" +from datetime import timedelta +import logging +import voluptuous as vol +import homeassistant.helpers.config_validation as cv + +from homeassistant.const import CONF_USERNAME, CONF_PASSWORD +import homeassistant.loader as loader + +from requests.exceptions import HTTPError, ConnectTimeout + +REQUIREMENTS = ['ring_doorbell==0.1.3'] + +_LOGGER = logging.getLogger(__name__) + +CONF_ATTRIBUTION = "Data provided by Ring.com" + +NOTIFICATION_ID = 'ring_notification' +NOTIFICATION_TITLE = 'Ring Sensor Setup' + +DOMAIN = 'ring' +DEFAULT_CACHEDB = '.ring_cache.pickle' +DEFAULT_ENTITY_NAMESPACE = 'ring' +DEFAULT_SCAN_INTERVAL = timedelta(seconds=30) + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({ + vol.Required(CONF_USERNAME): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + }), +}, extra=vol.ALLOW_EXTRA) + + +def setup(hass, config): + """Set up Ring component.""" + conf = config[DOMAIN] + username = conf.get(CONF_USERNAME) + password = conf.get(CONF_PASSWORD) + + persistent_notification = loader.get_component('persistent_notification') + try: + from ring_doorbell import Ring + + cache = hass.config.path(DEFAULT_CACHEDB) + ring = Ring(username=username, password=password, cache_file=cache) + if not ring.is_connected: + return False + hass.data['ring'] = ring + except (ConnectTimeout, HTTPError) as ex: + _LOGGER.error("Unable to connect to Ring service: %s", str(ex)) + persistent_notification.create( + hass, 'Error: {}
' + 'You will need to restart hass after fixing.' + ''.format(ex), + title=NOTIFICATION_TITLE, + notification_id=NOTIFICATION_ID) + return False + return True diff --git a/homeassistant/components/sensor/ring.py b/homeassistant/components/sensor/ring.py index 7c342a75f13460..665fb167bccad7 100644 --- a/homeassistant/components/sensor/ring.py +++ b/homeassistant/components/sensor/ring.py @@ -5,43 +5,32 @@ https://home-assistant.io/components/sensor.ring/ """ import logging -from datetime import timedelta import voluptuous as vol -import homeassistant.loader as loader import homeassistant.helpers.config_validation as cv +from homeassistant.components.ring import ( + CONF_ATTRIBUTION, DEFAULT_ENTITY_NAMESPACE, DEFAULT_SCAN_INTERVAL) from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( CONF_ENTITY_NAMESPACE, CONF_MONITORED_CONDITIONS, CONF_SCAN_INTERVAL, - CONF_USERNAME, CONF_PASSWORD, STATE_UNKNOWN, - ATTR_ATTRIBUTION) + STATE_UNKNOWN, ATTR_ATTRIBUTION) from homeassistant.helpers.entity import Entity -from requests.exceptions import HTTPError, ConnectTimeout - -REQUIREMENTS = ['ring_doorbell==0.1.0'] +DEPENDENCIES = ['ring'] _LOGGER = logging.getLogger(__name__) -NOTIFICATION_ID = 'ring_notification' -NOTIFICATION_TITLE = 'Ring Sensor Setup' - -DEFAULT_ENTITY_NAMESPACE = 'ring' -DEFAULT_SCAN_INTERVAL = timedelta(seconds=30) - -CONF_ATTRIBUTION = "Data provided by Ring.com" - -# Sensor types: Name, category, units, icon +# Sensor types: Name, category, units, icon, kind SENSOR_TYPES = { - 'battery': ['Battery', ['doorbell'], '%', 'battery-50'], - 'last_activity': ['Last Activity', ['doorbell'], None, 'history'], - 'volume': ['Volume', ['chime', 'doorbell'], None, 'bell-ring'], + 'battery': ['Battery', ['doorbell'], '%', 'battery-50', None], + 'last_activity': ['Last Activity', ['doorbell'], None, 'history', None], + 'last_ding': ['Last Ding', ['doorbell'], None, 'history', 'ding'], + 'last_motion': ['Last Motion', ['doorbell'], None, 'history', 'motion'], + 'volume': ['Volume', ['chime', 'doorbell'], None, 'bell-ring', None], } PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ - vol.Required(CONF_USERNAME): cv.string, - vol.Required(CONF_PASSWORD): cv.string, vol.Optional(CONF_ENTITY_NAMESPACE, default=DEFAULT_ENTITY_NAMESPACE): cv.string, vol.Optional(CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL): @@ -53,22 +42,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): """Set up a sensor for a Ring device.""" - from ring_doorbell import Ring - - ring = Ring(config.get(CONF_USERNAME), config.get(CONF_PASSWORD)) - - persistent_notification = loader.get_component('persistent_notification') - try: - ring.is_connected - except (ConnectTimeout, HTTPError) as ex: - _LOGGER.error("Unable to connect to Ring service: %s", str(ex)) - persistent_notification.create( - hass, 'Error: {}
' - 'You will need to restart hass after fixing.' - ''.format(ex), - title=NOTIFICATION_TITLE, - notification_id=NOTIFICATION_ID) - return False + ring = hass.data.get('ring') sensors = [] for sensor_type in config.get(CONF_MONITORED_CONDITIONS): @@ -98,6 +72,7 @@ def __init__(self, hass, data, sensor_type): self._data = data self._extra = None self._icon = 'mdi:{}'.format(SENSOR_TYPES.get(self._sensor_type)[3]) + self._kind = SENSOR_TYPES.get(self._sensor_type)[4] self._name = "{0} {1}".format(self._data.name, SENSOR_TYPES.get(self._sensor_type)[0]) self._state = STATE_UNKNOWN @@ -125,7 +100,7 @@ def device_state_attributes(self): attrs['timezone'] = self._data.timezone attrs['type'] = self._data.family - if self._extra and self._sensor_type == 'last_activity': + if self._extra and self._sensor_type.startswith('last_'): attrs['created_at'] = self._extra['created_at'] attrs['answered'] = self._extra['answered'] attrs['recording_status'] = self._extra['recording']['status'] @@ -153,8 +128,11 @@ def update(self): if self._sensor_type == 'battery': self._state = self._data.battery_life - if self._sensor_type == 'last_activity': - self._extra = self._data.history(limit=1, timezone=self._tz)[0] - created_at = self._extra['created_at'] - self._state = '{0:0>2}:{1:0>2}'.format(created_at.hour, - created_at.minute) + if self._sensor_type.startswith('last_'): + history = self._data.history(timezone=self._tz, + kind=self._kind) + if history: + self._extra = history[0] + created_at = self._extra['created_at'] + self._state = '{0:0>2}:{1:0>2}'.format(created_at.hour, + created_at.minute) diff --git a/requirements_all.txt b/requirements_all.txt index cb2f9fdff5c9ac..ac0d6a3752fa9f 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -664,8 +664,8 @@ radiotherm==1.2 # homeassistant.components.rflink rflink==0.0.31 -# homeassistant.components.sensor.ring -ring_doorbell==0.1.0 +# homeassistant.components.ring +ring_doorbell==0.1.3 # homeassistant.components.switch.rpi_rf # rpi-rf==0.9.6 diff --git a/tests/components/binary_sensor/test_ring.py b/tests/components/binary_sensor/test_ring.py new file mode 100644 index 00000000000000..75c7aced3699af --- /dev/null +++ b/tests/components/binary_sensor/test_ring.py @@ -0,0 +1,63 @@ +"""The tests for the Ring binary sensor platform.""" +import unittest +import requests_mock + +from homeassistant.components.binary_sensor import ring +from homeassistant.components import ring as base_ring + +from tests.components.test_ring import ATTRIBUTION, VALID_CONFIG +from tests.common import get_test_home_assistant, load_fixture + + +class TestRingBinarySensorSetup(unittest.TestCase): + """Test the Ring Binary Sensor platform.""" + + DEVICES = [] + + def add_devices(self, devices, action): + """Mock add devices.""" + for device in devices: + self.DEVICES.append(device) + + def setUp(self): + """Initialize values for this testcase class.""" + self.hass = get_test_home_assistant() + self.config = { + 'username': 'foo', + 'password': 'bar', + 'monitored_conditions': ['ding', 'motion'], + } + + def tearDown(self): + """Stop everything that was started.""" + self.hass.stop() + + @requests_mock.Mocker() + def test_binary_sensor(self, mock): + """Test the Ring sensor class and methods.""" + mock.post('https://api.ring.com/clients_api/session', + text=load_fixture('ring_session.json')) + mock.get('https://api.ring.com/clients_api/ring_devices', + text=load_fixture('ring_devices.json')) + mock.get('https://api.ring.com/clients_api/dings/active', + text=load_fixture('ring_ding_active.json')) + + base_ring.setup(self.hass, VALID_CONFIG) + ring.setup_platform(self.hass, + self.config, + self.add_devices, + None) + + for device in self.DEVICES: + device.update() + if device.name == 'Front Door Ding': + self.assertEqual('on', device.state) + self.assertEqual('America/New_York', + device.device_state_attributes['timezone']) + elif device.name == 'Front Door Motion': + self.assertEqual('off', device.state) + self.assertEqual('motion', device.device_class) + + self.assertIsNone(device.entity_picture) + self.assertEqual(ATTRIBUTION, + device.device_state_attributes['attribution']) diff --git a/tests/components/sensor/test_ring.py b/tests/components/sensor/test_ring.py index c7bf966a3e997d..0ee7210741394c 100644 --- a/tests/components/sensor/test_ring.py +++ b/tests/components/sensor/test_ring.py @@ -1,171 +1,17 @@ """The tests for the Ring sensor platform.""" import unittest -from unittest import mock +import requests_mock from homeassistant.components.sensor import ring -from tests.common import get_test_home_assistant +from homeassistant.components import ring as base_ring -VALID_CONFIG = { - "platform": "ring", - "username": "foo", - "password": "bar", - "monitored_conditions": [ - "battery", "last_activity", "volume" - ] -} +from tests.components.test_ring import ATTRIBUTION, VALID_CONFIG +from tests.common import get_test_home_assistant, load_fixture -ATTRIBUTION = 'Data provided by Ring.com' - -def mocked_requests_get(*args, **kwargs): - """Mock requests.get invocations.""" - class MockResponse: - """Class to represent a mocked response.""" - - def __init__(self, json_data, status_code): - """Initialize the mock response class.""" - self.json_data = json_data - self.status_code = status_code - - def json(self): - """Return the json of the response.""" - return self.json_data - - if str(args[0]).startswith('https://api.ring.com/clients_api/session'): - return MockResponse({ - "profile": { - "authentication_token": "12345678910", - "email": "foo@bar.org", - "features": { - "chime_dnd_enabled": False, - "chime_pro_enabled": True, - "delete_all_enabled": True, - "delete_all_settings_enabled": False, - "device_health_alerts_enabled": True, - "floodlight_cam_enabled": True, - "live_view_settings_enabled": True, - "lpd_enabled": True, - "lpd_motion_announcement_enabled": False, - "multiple_calls_enabled": True, - "multiple_delete_enabled": True, - "nw_enabled": True, - "nw_larger_area_enabled": False, - "nw_user_activated": False, - "owner_proactive_snoozing_enabled": True, - "power_cable_enabled": False, - "proactive_snoozing_enabled": False, - "reactive_snoozing_enabled": False, - "remote_logging_format_storing": False, - "remote_logging_level": 1, - "ringplus_enabled": True, - "starred_events_enabled": True, - "stickupcam_setup_enabled": True, - "subscriptions_enabled": True, - "ujet_enabled": False, - "video_search_enabled": False, - "vod_enabled": False}, - "first_name": "Home", - "id": 999999, - "last_name": "Assistant"} - }, 201) - elif str(args[0])\ - .startswith("https://api.ring.com/clients_api/ring_devices"): - return MockResponse({ - "authorized_doorbots": [], - "chimes": [ - { - "address": "123 Main St", - "alerts": {"connection": "online"}, - "description": "Downstairs", - "device_id": "abcdef123", - "do_not_disturb": {"seconds_left": 0}, - "features": {"ringtones_enabled": True}, - "firmware_version": "1.2.3", - "id": 999999, - "kind": "chime", - "latitude": 12.000000, - "longitude": -70.12345, - "owned": True, - "owner": { - "email": "foo@bar.org", - "first_name": "Marcelo", - "id": 999999, - "last_name": "Assistant"}, - "settings": { - "ding_audio_id": None, - "ding_audio_user_id": None, - "motion_audio_id": None, - "motion_audio_user_id": None, - "volume": 2}, - "time_zone": "America/New_York"}], - "doorbots": [ - { - "address": "123 Main St", - "alerts": {"connection": "online"}, - "battery_life": 4081, - "description": "Front Door", - "device_id": "aacdef123", - "external_connection": False, - "features": { - "advanced_motion_enabled": False, - "motion_message_enabled": False, - "motions_enabled": True, - "people_only_enabled": False, - "shadow_correction_enabled": False, - "show_recordings": True}, - "firmware_version": "1.4.26", - "id": 987652, - "kind": "lpd_v1", - "latitude": 12.000000, - "longitude": -70.12345, - "motion_snooze": None, - "owned": True, - "owner": { - "email": "foo@bar.org", - "first_name": "Home", - "id": 999999, - "last_name": "Assistant"}, - "settings": { - "chime_settings": { - "duration": 3, - "enable": True, - "type": 0}, - "doorbell_volume": 1, - "enable_vod": True, - "live_view_preset_profile": "highest", - "live_view_presets": [ - "low", - "middle", - "high", - "highest"], - "motion_announcement": False, - "motion_snooze_preset_profile": "low", - "motion_snooze_presets": [ - "none", - "low", - "medium", - "high"]}, - "subscribed": True, - "subscribed_motions": True, - "time_zone": "America/New_York"}] - }, 200) - elif str(args[0]).startswith("https://api.ring.com/clients_api/doorbots"): - return MockResponse([{ - "answered": False, - "created_at": "2017-03-05T15:03:40.000Z", - "events": [], - "favorite": False, - "id": 987654321, - "kind": "motion", - "recording": {"status": "ready"}, - "snapshot_url": "" - }], 200) - - -class TestRingSetup(unittest.TestCase): +class TestRingSensorSetup(unittest.TestCase): """Test the Ring platform.""" - # pylint: disable=invalid-name DEVICES = [] def add_devices(self, devices, action): @@ -176,25 +22,35 @@ def add_devices(self, devices, action): def setUp(self): """Initialize values for this testcase class.""" self.hass = get_test_home_assistant() - self.config = VALID_CONFIG + self.config = { + 'username': 'foo', + 'password': 'bar', + 'monitored_conditions': [ + 'battery', + 'last_activity', + 'last_ding', + 'last_motion', + 'volume'] + } def tearDown(self): """Stop everything that was started.""" self.hass.stop() - @mock.patch('requests.Session.get', side_effect=mocked_requests_get) - @mock.patch('requests.Session.post', side_effect=mocked_requests_get) - def test_setup(self, get_mock, post_mock): - """Test if component loaded successfully.""" - self.assertTrue( - ring.setup_platform(self.hass, VALID_CONFIG, - self.add_devices, None)) - - @mock.patch('requests.Session.get', side_effect=mocked_requests_get) - @mock.patch('requests.Session.post', side_effect=mocked_requests_get) - def test_sensor(self, get_mock, post_mock): - """Test the Ring sensor class and methods.""" - ring.setup_platform(self.hass, VALID_CONFIG, self.add_devices, None) + @requests_mock.Mocker() + def test_sensor(self, mock): + """Test the Ring senskor class and methods.""" + mock.post('https://api.ring.com/clients_api/session', + text=load_fixture('ring_session.json')) + mock.get('https://api.ring.com/clients_api/ring_devices', + text=load_fixture('ring_devices.json')) + mock.get('https://api.ring.com/clients_api/doorbots/987652/history', + text=load_fixture('ring_doorbots.json')) + base_ring.setup(self.hass, VALID_CONFIG) + ring.setup_platform(self.hass, + self.config, + self.add_devices, + None) for device in self.DEVICES: device.update() diff --git a/tests/components/test_ring.py b/tests/components/test_ring.py new file mode 100644 index 00000000000000..e10e5c20aea0d5 --- /dev/null +++ b/tests/components/test_ring.py @@ -0,0 +1,56 @@ +"""The tests for the Ring component.""" +import unittest +import requests_mock + +from homeassistant import setup +import homeassistant.components.ring as ring + +from tests.common import get_test_home_assistant, load_fixture + +ATTRIBUTION = 'Data provided by Ring.com' + +VALID_CONFIG = { + "ring": { + "username": "foo", + "password": "bar", + } +} + + +class TestRing(unittest.TestCase): + """Tests the Ring component.""" + + def setUp(self): + """Initialize values for this test case class.""" + self.hass = get_test_home_assistant() + self.config = VALID_CONFIG + + def tearDown(self): # pylint: disable=invalid-name + """Stop everything that was started.""" + self.hass.stop() + + @requests_mock.Mocker() + def test_setup(self, mock): + """Test the setup.""" + mock.post('https://api.ring.com/clients_api/session', + text=load_fixture('ring_session.json')) + response = ring.setup(self.hass, self.config) + self.assertTrue(response) + + @requests_mock.Mocker() + def test_setup_component_no_login(self, mock): + """Test the setup when no login is configured.""" + mock.post('https://api.ring.com/clients_api/session', + text=load_fixture('ring_session.json')) + conf = self.config.copy() + del conf['ring']['username'] + assert not setup.setup_component(self.hass, ring.DOMAIN, conf) + + @requests_mock.Mocker() + def test_setup_component_no_pwd(self, mock): + """Test the setup when no password is configured.""" + mock.post('https://api.ring.com/clients_api/session', + text=load_fixture('ring_session.json')) + conf = self.config.copy() + del conf['ring']['password'] + assert not setup.setup_component(self.hass, ring.DOMAIN, conf) diff --git a/tests/fixtures/ring_devices.json b/tests/fixtures/ring_devices.json new file mode 100644 index 00000000000000..4d204ba5250ece --- /dev/null +++ b/tests/fixtures/ring_devices.json @@ -0,0 +1,79 @@ +{ + "authorized_doorbots": [], + "chimes": [ + { + "address": "123 Main St", + "alerts": {"connection": "online"}, + "description": "Downstairs", + "device_id": "abcdef123", + "do_not_disturb": {"seconds_left": 0}, + "features": {"ringtones_enabled": true}, + "firmware_version": "1.2.3", + "id": 999999, + "kind": "chime", + "latitude": 12.000000, + "longitude": -70.12345, + "owned": true, + "owner": { + "email": "foo@bar.org", + "first_name": "Marcelo", + "id": 999999, + "last_name": "Assistant"}, + "settings": { + "ding_audio_id": null, + "ding_audio_user_id": null, + "motion_audio_id": null, + "motion_audio_user_id": null, + "volume": 2}, + "time_zone": "America/New_York"}], + "doorbots": [ + { + "address": "123 Main St", + "alerts": {"connection": "online"}, + "battery_life": 4081, + "description": "Front Door", + "device_id": "aacdef123", + "external_connection": false, + "features": { + "advanced_motion_enabled": false, + "motion_message_enabled": false, + "motions_enabled": true, + "people_only_enabled": false, + "shadow_correction_enabled": false, + "show_recordings": true}, + "firmware_version": "1.4.26", + "id": 987652, + "kind": "lpd_v1", + "latitude": 12.000000, + "longitude": -70.12345, + "motion_snooze": null, + "owned": true, + "owner": { + "email": "foo@bar.org", + "first_name": "Home", + "id": 999999, + "last_name": "Assistant"}, + "settings": { + "chime_settings": { + "duration": 3, + "enable": true, + "type": 0}, + "doorbell_volume": 1, + "enable_vod": true, + "live_view_preset_profile": "highest", + "live_view_presets": [ + "low", + "middle", + "high", + "highest"], + "motion_announcement": false, + "motion_snooze_preset_profile": "low", + "motion_snooze_presets": [ + "null", + "low", + "medium", + "high"]}, + "subscribed": true, + "subscribed_motions": true, + "time_zone": "America/New_York"}] +} diff --git a/tests/fixtures/ring_ding_active.json b/tests/fixtures/ring_ding_active.json new file mode 100644 index 00000000000000..6bbcc0ee3f95f8 --- /dev/null +++ b/tests/fixtures/ring_ding_active.json @@ -0,0 +1,26 @@ +[{ + "audio_jitter_buffer_ms": 0, + "device_kind": "lpd_v1", + "doorbot_description": "Front Door", + "doorbot_id": 12345, + "expires_in": 180, + "id": 123456789, + "id_str": "123456789", + "kind": "ding", + "motion": false, + "now": 1490949469.5498993, + "optimization_level": 1, + "protocol": "sip", + "sip_ding_id": "123456789", + "sip_endpoints": null, + "sip_from": "sip:abc123@ring.com", + "sip_server_ip": "192.168.0.1", + "sip_server_port": "15063", + "sip_server_tls": "false", + "sip_session_id": "28qdvjh-2043", + "sip_to": "sip:28qdvjh-2043@192.168.0.1:15063;transport=tcp", + "sip_token": "adecc24a428ed704b2d80adb621b5775755915529639e", + "snapshot_url": "", + "state": "ringing", + "video_jitter_buffer_ms": 0 +}] diff --git a/tests/fixtures/ring_doorbots.json b/tests/fixtures/ring_doorbots.json new file mode 100644 index 00000000000000..7ec2d4fd0b7c5d --- /dev/null +++ b/tests/fixtures/ring_doorbots.json @@ -0,0 +1,10 @@ +[{ + "answered": false, + "created_at": "2017-03-05T15:03:40.000Z", + "events": [], + "favorite": false, + "id": 987654321, + "kind": "motion", + "recording": {"status": "ready"}, + "snapshot_url": "" +}] diff --git a/tests/fixtures/ring_session.json b/tests/fixtures/ring_session.json new file mode 100644 index 00000000000000..21ae51c6bf623a --- /dev/null +++ b/tests/fixtures/ring_session.json @@ -0,0 +1,36 @@ +{ + "profile": { + "authentication_token": "12345678910", + "email": "foo@bar.org", + "features": { + "chime_dnd_enabled": false, + "chime_pro_enabled": true, + "delete_all_enabled": true, + "delete_all_settings_enabled": false, + "device_health_alerts_enabled": true, + "floodlight_cam_enabled": true, + "live_view_settings_enabled": true, + "lpd_enabled": true, + "lpd_motion_announcement_enabled": false, + "multiple_calls_enabled": true, + "multiple_delete_enabled": true, + "nw_enabled": true, + "nw_larger_area_enabled": false, + "nw_user_activated": false, + "owner_proactive_snoozing_enabled": true, + "power_cable_enabled": false, + "proactive_snoozing_enabled": false, + "reactive_snoozing_enabled": false, + "remote_logging_format_storing": false, + "remote_logging_level": 1, + "ringplus_enabled": true, + "starred_events_enabled": true, + "stickupcam_setup_enabled": true, + "subscriptions_enabled": true, + "ujet_enabled": false, + "video_search_enabled": false, + "vod_enabled": false}, + "first_name": "Home", + "id": 999999, + "last_name": "Assistant"} +} From ac25eff2d0f0dce92de901f946d3546d26b91f5f Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 31 Mar 2017 21:37:34 +0200 Subject: [PATCH 056/116] Upgrade sendgrid to 3.6.5 (#6866) --- homeassistant/components/notify/sendgrid.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/notify/sendgrid.py b/homeassistant/components/notify/sendgrid.py index 458113d1cdff50..f2ef64a9ea0e10 100644 --- a/homeassistant/components/notify/sendgrid.py +++ b/homeassistant/components/notify/sendgrid.py @@ -13,7 +13,7 @@ from homeassistant.const import (CONF_API_KEY, CONF_SENDER, CONF_RECIPIENT) import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['sendgrid==3.6.3'] +REQUIREMENTS = ['sendgrid==3.6.5'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index ac0d6a3752fa9f..678f1d8c464e1a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -683,7 +683,7 @@ schiene==0.18 scsgate==0.1.0 # homeassistant.components.notify.sendgrid -sendgrid==3.6.3 +sendgrid==3.6.5 # homeassistant.components.sensor.sensehat sense-hat==2.2.0 From 573b2a11c0c6f6938235c50c5951879d68e1a408 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 31 Mar 2017 21:39:22 +0200 Subject: [PATCH 057/116] Upgrade sphinx-autodoc-typehints to 1.2.0 (#6865) --- requirements_docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_docs.txt b/requirements_docs.txt index e3e8942510956b..19c305afc4d378 100644 --- a/requirements_docs.txt +++ b/requirements_docs.txt @@ -1,3 +1,3 @@ Sphinx==1.5.3 -sphinx-autodoc-typehints==1.1.0 +sphinx-autodoc-typehints==1.2.0 sphinx-autodoc-annotation==1.0.post1 From 2d6b09586db3d9d8c3c082ea117c9edc22e93107 Mon Sep 17 00:00:00 2001 From: Jacob Tomlinson Date: Fri, 31 Mar 2017 21:03:27 +0100 Subject: [PATCH 058/116] Added Met Office weather and sensor components (#6742) * Added Met Office weather and sensor components * Removed unnecessary dependancy * Generated requirements * Fix time interval * Updated coverage * Some review changes * Allow user to specify lat and lon in component * Added missing import * Fixed unit * Fixed import indent * Updated condition to use CONDITION_CLASSES --- .coveragerc | 4 +- homeassistant/components/sensor/metoffice.py | 176 ++++++++++++++++++ homeassistant/components/weather/metoffice.py | 122 ++++++++++++ requirements_all.txt | 4 + 4 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 homeassistant/components/sensor/metoffice.py create mode 100644 homeassistant/components/weather/metoffice.py diff --git a/.coveragerc b/.coveragerc index 52b88444dc6686..939565ed43ae63 100644 --- a/.coveragerc +++ b/.coveragerc @@ -147,7 +147,7 @@ omit = homeassistant/components/tado.py homeassistant/components/*/tado.py - + homeassistant/components/alarm_control_panel/alarmdotcom.py homeassistant/components/alarm_control_panel/concord232.py homeassistant/components/alarm_control_panel/nx584.py @@ -359,6 +359,7 @@ omit = homeassistant/components/sensor/linux_battery.py homeassistant/components/sensor/loopenergy.py homeassistant/components/sensor/lyft.py + homeassistant/components/sensor/metoffice.py homeassistant/components/sensor/miflora.py homeassistant/components/sensor/modem_callerid.py homeassistant/components/sensor/mqtt_room.py @@ -434,6 +435,7 @@ omit = homeassistant/components/tts/picotts.py homeassistant/components/upnp.py homeassistant/components/weather/bom.py + homeassistant/components/weather/metoffice.py homeassistant/components/weather/openweathermap.py homeassistant/components/weather/zamg.py homeassistant/components/zeroconf.py diff --git a/homeassistant/components/sensor/metoffice.py b/homeassistant/components/sensor/metoffice.py new file mode 100644 index 00000000000000..725fca1db44156 --- /dev/null +++ b/homeassistant/components/sensor/metoffice.py @@ -0,0 +1,176 @@ +""" +Support for UK Met Office weather service. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.metoffice/ +""" + +import logging +from datetime import timedelta + +import voluptuous as vol + +from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.const import ( + CONF_MONITORED_CONDITIONS, TEMP_CELSIUS, STATE_UNKNOWN, CONF_NAME, + ATTR_ATTRIBUTION, CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE) +from homeassistant.helpers.entity import Entity +from homeassistant.util import Throttle +import homeassistant.helpers.config_validation as cv + +_LOGGER = logging.getLogger(__name__) + +REQUIREMENTS = ['datapoint==0.4.3'] + +CONF_ATTRIBUTION = "Data provided by the Met Office" + +CONDITION_CLASSES = { + 'cloudy': ["7", "8"], + 'fog': ["5", "6"], + 'hail': ["19", "20", "21"], + 'lightning': ["30"], + 'lightning-rainy': ["28", "29"], + 'partlycloudy': ["2", "3"], + 'pouring': ["13", "14", "15"], + 'rainy': ["9", "10", "11", "12"], + 'snowy': ["22", "23", "24", "25", "26", "27"], + 'snowy-rainy': ["16", "17", "18"], + 'sunny': ["0", "1"], + 'windy': [], + 'windy-variant': [], + 'exceptional': [], +} + +SCAN_INTERVAL = timedelta(minutes=35) + +# Sensor types are defined like: Name, units +SENSOR_TYPES = { + 'name': ['Station Name', None], + 'weather': ['Weather', None], + 'temperature': ['Temperature', TEMP_CELSIUS], + 'feels_like_temperature': ['Feels Like Temperature', TEMP_CELSIUS], + 'wind_speed': ['Wind Speed', 'm/s'], + 'wind_direction': ['Wind Direction', None], + 'wind_gust': ['Wind Gust', 'm/s'], + 'visibility': ['Visibility', 'km'], + 'uv': ['UV', None], + 'precipitation': ['Probability of Precipitation', '%'], + 'humidity': ['Humidity', '%'] +} + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Optional(CONF_NAME, default=None): cv.string, + vol.Required(CONF_API_KEY): cv.string, + vol.Required(CONF_MONITORED_CONDITIONS, default=[]): + vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]), +}) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Setup the sensor platform.""" + import datapoint as dp + datapoint = dp.connection(api_key=config.get(CONF_API_KEY)) + + latitude = config.get(CONF_LATITUDE, hass.config.latitude) + longitude = config.get(CONF_LONGITUDE, hass.config.longitude) + + if None in (latitude, longitude): + _LOGGER.error("Latitude or longitude not set in Home Assistant config") + return False + + try: + site = datapoint.get_nearest_site(latitude=latitude, + longitude=longitude) + except dp.exceptions.APIException as err: + _LOGGER.error("Received error from Met Office Datapoint: %s", err) + return False + + if not site: + _LOGGER.error("Unable to get nearest Met Office forecast site") + return False + + # Get data + data = MetOfficeCurrentData(hass, datapoint, site) + try: + data.update() + except (ValueError, dp.exceptions.APIException) as err: + _LOGGER.error("Received error from Met Office Datapoint: %s", err) + return False + + # Add + add_devices([MetOfficeCurrentSensor(site, data, variable) + for variable in config[CONF_MONITORED_CONDITIONS]]) + return True + + +class MetOfficeCurrentSensor(Entity): + """Implementation of a Met Office current sensor.""" + + def __init__(self, site, data, condition): + """Initialize the sensor.""" + self.site = site + self.data = data + self._condition = condition + + @property + def name(self): + """Return the name of the sensor.""" + return 'Met Office {}'.format(SENSOR_TYPES[self._condition][0]) + + @property + def state(self): + """Return the state of the sensor.""" + if self._condition in self.data.data.__dict__.keys(): + variable = getattr(self.data.data, self._condition) + if self._condition == "weather": + return [k for k, v in CONDITION_CLASSES.items() if + self.data.data.weather.value in v][0] + else: + return variable.value + else: + return STATE_UNKNOWN + + @property + def unit_of_measurement(self): + """Return the unit of measurement.""" + return SENSOR_TYPES[self._condition][1] + + @property + def device_state_attributes(self): + """Return the state attributes of the device.""" + attr = {} + attr['Sensor Id'] = self._condition + attr['Site Id'] = self.site.id + attr['Site Name'] = self.site.name + attr['Last Update'] = self.data.lastupdate + attr[ATTR_ATTRIBUTION] = CONF_ATTRIBUTION + return attr + + def update(self): + """Update current conditions.""" + self.data.update() + + +class MetOfficeCurrentData(object): + """Get data from Datapoint.""" + + def __init__(self, hass, datapoint, site): + """Initialize the data object.""" + self._hass = hass + self._datapoint = datapoint + self._site = site + self.data = None + + @Throttle(SCAN_INTERVAL) + def update(self): + """Get the latest data from Datapoint.""" + import datapoint as dp + + try: + forecast = self._datapoint.get_forecast_for_site(self._site.id, + "3hourly") + self.data = forecast.now() + except (ValueError, dp.exceptions.APIException) as err: + _LOGGER.error("Check Met Office %s", err.args) + self.data = None + raise diff --git a/homeassistant/components/weather/metoffice.py b/homeassistant/components/weather/metoffice.py new file mode 100644 index 00000000000000..50bbb84faa7af3 --- /dev/null +++ b/homeassistant/components/weather/metoffice.py @@ -0,0 +1,122 @@ +""" +Support for UK Met Office weather service. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/weather.metoffice/ +""" +import logging + +import voluptuous as vol + +from homeassistant.components.weather import WeatherEntity, PLATFORM_SCHEMA +from homeassistant.const import ( + CONF_NAME, TEMP_CELSIUS, CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE) +from homeassistant.helpers import config_validation as cv +# Reuse data and API logic from the sensor implementation +from homeassistant.components.sensor.metoffice import \ + MetOfficeCurrentData, CONF_ATTRIBUTION, CONDITION_CLASSES + +_LOGGER = logging.getLogger(__name__) + +REQUIREMENTS = ['datapoint==0.4.3'] + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Optional(CONF_NAME): cv.string, + vol.Required(CONF_API_KEY): cv.string, +}) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Set up the Met Office weather platform.""" + import datapoint as dp + datapoint = dp.connection(api_key=config.get(CONF_API_KEY)) + + latitude = config.get(CONF_LATITUDE, hass.config.latitude) + longitude = config.get(CONF_LONGITUDE, hass.config.longitude) + + if None in (latitude, longitude): + _LOGGER.error("Latitude or longitude not set in Home Assistant config") + return False + + try: + site = datapoint.get_nearest_site(latitude=latitude, + longitude=longitude) + except dp.exceptions.APIException as err: + _LOGGER.error("Received error from Met Office Datapoint: %s", err) + return False + + if not site: + _LOGGER.error("Unable to get nearest Met Office forecast site") + return False + + # Get data + data = MetOfficeCurrentData(hass, datapoint, site) + try: + data.update() + except (ValueError, dp.exceptions.APIException) as err: + _LOGGER.error("Received error from Met Office Datapoint: %s", err) + return False + add_devices([MetOfficeWeather(site, data, config.get(CONF_NAME))], + True) + return True + + +class MetOfficeWeather(WeatherEntity): + """Implementation of a Met Office weather condition.""" + + def __init__(self, site, data, config): + """Initialise the platform with a data instance and site.""" + self.data = data + self.site = site + + def update(self): + """Update current conditions.""" + self.data.update() + + @property + def name(self): + """Return the name of the sensor.""" + return 'Met Office ({})'.format(self.site.name) + + @property + def condition(self): + """Return the current condition.""" + return [k for k, v in CONDITION_CLASSES.items() if + self.data.data.weather.value in v][0] + + # Now implement the WeatherEntity interface + + @property + def temperature(self): + """Return the platform temperature.""" + return self.data.data.temperature.value + + @property + def temperature_unit(self): + """Return the unit of measurement.""" + return TEMP_CELSIUS + + @property + def pressure(self): + """Return the mean sea-level pressure.""" + return None + + @property + def humidity(self): + """Return the relative humidity.""" + return self.data.data.humidity.value + + @property + def wind_speed(self): + """Return the wind speed.""" + return self.data.data.wind_speed.value + + @property + def wind_bearing(self): + """Return the wind bearing.""" + return self.data.data.wind_direction.value + + @property + def attribution(self): + """Return the attribution.""" + return CONF_ATTRIBUTION diff --git a/requirements_all.txt b/requirements_all.txt index 678f1d8c464e1a..9caba7d75d5b9c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -105,6 +105,10 @@ colorlog>2.1,<3 # homeassistant.components.binary_sensor.concord232 concord232==0.14 +# homeassistant.components.sensor.metoffice +# homeassistant.components.weather.metoffice +datapoint==0.4.3 + # homeassistant.components.light.decora # decora==0.3 From a0bb554f8ac6d3e84729ab75498eb9795e5eed4e Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 31 Mar 2017 22:57:29 +0200 Subject: [PATCH 059/116] Upgrade speedtest-cli to 1.0.3 (#6867) --- homeassistant/components/sensor/speedtest.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/sensor/speedtest.py b/homeassistant/components/sensor/speedtest.py index 00d8d24853e14f..76dbbe4ed3955b 100644 --- a/homeassistant/components/sensor/speedtest.py +++ b/homeassistant/components/sensor/speedtest.py @@ -20,7 +20,7 @@ from homeassistant.helpers.event import track_time_change from homeassistant.helpers.restore_state import async_get_last_state -REQUIREMENTS = ['speedtest-cli==1.0.2'] +REQUIREMENTS = ['speedtest-cli==1.0.3'] _LOGGER = logging.getLogger(__name__) _SPEEDTEST_REGEX = re.compile(r'Ping:\s(\d+\.\d+)\sms[\r\n]+' diff --git a/requirements_all.txt b/requirements_all.txt index 9caba7d75d5b9c..cdebbdf5b0faff 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -714,7 +714,7 @@ snapcast==1.2.2 somecomfort==0.4.1 # homeassistant.components.sensor.speedtest -speedtest-cli==1.0.2 +speedtest-cli==1.0.3 # homeassistant.components.recorder # homeassistant.scripts.db_migrator From 65b9383e04c9f7031495476af6cfd9a4b8e641aa Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Sat, 1 Apr 2017 06:36:04 -0400 Subject: [PATCH 060/116] Bumped amcrest module to 1.1.5 (#6872) --- homeassistant/components/camera/amcrest.py | 2 +- homeassistant/components/sensor/amcrest.py | 2 +- requirements_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/camera/amcrest.py b/homeassistant/components/camera/amcrest.py index 9bf89b8b3a5e79..294a63bcff9fc0 100644 --- a/homeassistant/components/camera/amcrest.py +++ b/homeassistant/components/camera/amcrest.py @@ -18,7 +18,7 @@ from homeassistant.helpers.aiohttp_client import ( async_get_clientsession, async_aiohttp_proxy_web) -REQUIREMENTS = ['amcrest==1.1.4'] +REQUIREMENTS = ['amcrest==1.1.5'] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/sensor/amcrest.py b/homeassistant/components/sensor/amcrest.py index f250905e9523eb..79e886c154dc20 100644 --- a/homeassistant/components/sensor/amcrest.py +++ b/homeassistant/components/sensor/amcrest.py @@ -20,7 +20,7 @@ from requests.exceptions import HTTPError, ConnectTimeout -REQUIREMENTS = ['amcrest==1.1.4'] +REQUIREMENTS = ['amcrest==1.1.5'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index cdebbdf5b0faff..94f4ecadfae631 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -48,7 +48,7 @@ aiolifx==0.4.2 # homeassistant.components.camera.amcrest # homeassistant.components.sensor.amcrest -amcrest==1.1.4 +amcrest==1.1.5 # homeassistant.components.media_player.anthemav anthemav==1.1.8 From ec2df2ca0f631fb213c4a66a119889666cb836a0 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sat, 1 Apr 2017 12:36:24 +0200 Subject: [PATCH 061/116] Upgrade pytz to 2017.02 (#6875) --- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index e052c662e3b235..a8e8df3d250c70 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -1,6 +1,6 @@ requests>=2,<3 pyyaml>=3.11,<4 -pytz>=2016.10 +pytz>=2017.02 pip>=7.1.0 jinja2>=2.9.5 voluptuous==0.9.3 diff --git a/requirements_all.txt b/requirements_all.txt index 94f4ecadfae631..cf0d5ee646dee2 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1,7 +1,7 @@ # Home Assistant core requests>=2,<3 pyyaml>=3.11,<4 -pytz>=2016.10 +pytz>=2017.02 pip>=7.1.0 jinja2>=2.9.5 voluptuous==0.9.3 diff --git a/setup.py b/setup.py index 5e973790dcc253..cdc4c43e7a207d 100755 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ REQUIRES = [ 'requests>=2,<3', 'pyyaml>=3.11,<4', - 'pytz>=2016.10', + 'pytz>=2017.02', 'pip>=7.1.0', 'jinja2>=2.9.5', 'voluptuous==0.9.3', From 7afe694cc7451ea76c48b6f4539a33825764e1c2 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sat, 1 Apr 2017 12:36:35 +0200 Subject: [PATCH 062/116] Upgrade aiohttp_cors to 0.5.2 (#6874) --- homeassistant/components/http/__init__.py | 3 ++- requirements_all.txt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/http/__init__.py b/homeassistant/components/http/__init__.py index f99b2390bb8929..ee107ec5cfa689 100644 --- a/homeassistant/components/http/__init__.py +++ b/homeassistant/components/http/__init__.py @@ -34,8 +34,9 @@ staticresource_middleware, CachingFileResponse, CachingStaticResource) from .util import get_real_ip +REQUIREMENTS = ['aiohttp_cors==0.5.2'] + DOMAIN = 'http' -REQUIREMENTS = ('aiohttp_cors==0.5.0',) CONF_API_PASSWORD = 'api_password' CONF_SERVER_HOST = 'server_host' diff --git a/requirements_all.txt b/requirements_all.txt index cf0d5ee646dee2..0b0e53fdefea84 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -41,7 +41,7 @@ aiodns==1.1.1 # homeassistant.components.emulated_hue # homeassistant.components.http -aiohttp_cors==0.5.0 +aiohttp_cors==0.5.2 # homeassistant.components.light.lifx aiolifx==0.4.2 From 395f9b654891a0c6454e7e869893f6fadf5ad148 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sat, 1 Apr 2017 12:36:46 +0200 Subject: [PATCH 063/116] Upgrade sqlalchemy to 1.1.8 (#6873) --- homeassistant/components/recorder/__init__.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/recorder/__init__.py b/homeassistant/components/recorder/__init__.py index 0ed5c3126b71c0..a56ad775eac821 100644 --- a/homeassistant/components/recorder/__init__.py +++ b/homeassistant/components/recorder/__init__.py @@ -35,7 +35,7 @@ DOMAIN = 'recorder' -REQUIREMENTS = ['sqlalchemy==1.1.6'] +REQUIREMENTS = ['sqlalchemy==1.1.8'] DEFAULT_URL = 'sqlite:///{hass_config_path}' DEFAULT_DB_FILE = 'home-assistant_v2.db' diff --git a/requirements_all.txt b/requirements_all.txt index 0b0e53fdefea84..088d81dde6552b 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -718,7 +718,7 @@ speedtest-cli==1.0.3 # homeassistant.components.recorder # homeassistant.scripts.db_migrator -sqlalchemy==1.1.6 +sqlalchemy==1.1.8 # homeassistant.components.statsd statsd==3.2.1 From 2413d97415a62eebad4540c4704fed8bd8b02c97 Mon Sep 17 00:00:00 2001 From: ChristianKuehnel Date: Sun, 2 Apr 2017 11:41:53 +0200 Subject: [PATCH 064/116] added support for Fibaro FGR-222 (similar to FGRM-222) (#6890) --- homeassistant/components/zwave/workaround.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/homeassistant/components/zwave/workaround.py b/homeassistant/components/zwave/workaround.py index 27e98457a2d256..8971658d9ece9e 100644 --- a/homeassistant/components/zwave/workaround.py +++ b/homeassistant/components/zwave/workaround.py @@ -15,6 +15,7 @@ # Product Types FGFS101_FLOOD_SENSOR_TYPE = 0x0b00 FGRM222_SHUTTER2 = 0x0301 +FGR222_SHUTTER2 = 0x0302 PHILIO_SWITCH = 0x0001 PHILIO_SENSOR = 0x0002 SOMFY_ZRTSI = 0x5a52 @@ -54,12 +55,15 @@ FIBARO, FGFS101_FLOOD_SENSOR_TYPE, const.COMMAND_CLASS_SENSOR_ALARM) FIBARO_FGRM222_BINARY = ( FIBARO, FGRM222_SHUTTER2, const.COMMAND_CLASS_SWITCH_BINARY) +FIBARO_FGR222_BINARY = ( + FIBARO, FGR222_SHUTTER2, const.COMMAND_CLASS_SWITCH_BINARY) # List of component workarounds by # (manufacturer_id, product_type, command_class) DEVICE_COMPONENT_MAPPING = { FIBARO_FGFS101_SENSOR_ALARM: 'binary_sensor', FIBARO_FGRM222_BINARY: WORKAROUND_IGNORE, + FIBARO_FGR222_BINARY: WORKAROUND_IGNORE, } From 8806265e99b8bfb93cd5dfdba65bc9998eaf736f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=B8yer=20Iversen?= Date: Sun, 2 Apr 2017 14:12:38 +0200 Subject: [PATCH 065/116] Fluxled (#6892) * Update flux_led lib --- homeassistant/components/light/flux_led.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/light/flux_led.py b/homeassistant/components/light/flux_led.py index ca18511c660e3b..97b2d1a1d23c89 100644 --- a/homeassistant/components/light/flux_led.py +++ b/homeassistant/components/light/flux_led.py @@ -18,7 +18,7 @@ PLATFORM_SCHEMA) import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['flux_led==0.16'] +REQUIREMENTS = ['flux_led==0.17'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 088d81dde6552b..a77400657762bf 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -168,7 +168,7 @@ fitbit==0.2.3 fixerio==0.1.1 # homeassistant.components.light.flux_led -flux_led==0.16 +flux_led==0.17 # homeassistant.components.notify.free_mobile freesms==0.1.1 From 864b57d42c4a9bc490dbe0dd6cc738929d38cd6b Mon Sep 17 00:00:00 2001 From: Wolfgang Malgadey Date: Sun, 2 Apr 2017 18:47:15 +0200 Subject: [PATCH 066/116] Fix Tado climate set off mode (#6848) --- homeassistant/components/tado.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/tado.py b/homeassistant/components/tado.py index ffb4da61fedc37..b7758c95c0e2f1 100644 --- a/homeassistant/components/tado.py +++ b/homeassistant/components/tado.py @@ -122,6 +122,6 @@ def reset_zone_overlay(self, zone_id): """Wrapper for resetZoneOverlay(..).""" return self.tado.resetZoneOverlay(zone_id) - def set_zone_overlay(self, zone_id, mode, temperature): + def set_zone_overlay(self, zone_id, mode, temperature=None, duration=None): """Wrapper for setZoneOverlay(..).""" - return self.tado.setZoneOverlay(zone_id, mode, temperature) + return self.tado.setZoneOverlay(zone_id, mode, temperature, duration) From f0027e3cc1cff9c860f60cf3f1514058783f308a Mon Sep 17 00:00:00 2001 From: Dan Date: Sun, 2 Apr 2017 18:31:28 -0400 Subject: [PATCH 067/116] Fox UMP volume set (#6904) async needs consistant paramater namming accross platforms. This fixes UMP's volume set method by renaming the paramater. --- homeassistant/components/media_player/universal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/media_player/universal.py b/homeassistant/components/media_player/universal.py index b5f88eb28a4cf9..5dfe007976f6fe 100644 --- a/homeassistant/components/media_player/universal.py +++ b/homeassistant/components/media_player/universal.py @@ -425,12 +425,12 @@ def async_mute_volume(self, is_volume_muted): return self._async_call_service( SERVICE_VOLUME_MUTE, data, allow_override=True) - def async_set_volume_level(self, volume_level): + def async_set_volume_level(self, volume): """Set volume level, range 0..1. This method must be run in the event loop and returns a coroutine. """ - data = {ATTR_MEDIA_VOLUME_LEVEL: volume_level} + data = {ATTR_MEDIA_VOLUME_LEVEL: volume} return self._async_call_service( SERVICE_VOLUME_SET, data, allow_override=True) From 36e5878b2e3a741e2a022eca22dae716d48d6cae Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 2 Apr 2017 17:01:51 -0700 Subject: [PATCH 068/116] Move examples out (#6908) * Remove examples from main repo * Simplify README * Point screenshot for components at dev branch for now --- .gitignore | 11 - README.rst | 82 +---- config/configuration.yaml.example | 158 --------- config/custom_components/example.py | 149 -------- config/custom_components/hello_world.py | 27 -- config/custom_components/mqtt_example.py | 55 --- config/panels/react.html | 432 ----------------------- docs/screenshot-components.png | Bin 0 -> 47635 bytes 8 files changed, 9 insertions(+), 905 deletions(-) delete mode 100644 config/configuration.yaml.example delete mode 100644 config/custom_components/example.py delete mode 100644 config/custom_components/hello_world.py delete mode 100644 config/custom_components/mqtt_example.py delete mode 100644 config/panels/react.html create mode 100755 docs/screenshot-components.png diff --git a/.gitignore b/.gitignore index aa27aa435bd714..d5c29180e094ed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,4 @@ config/* -!config/home-assistant.conf.default - -# There is not a better solution afaik.. -!config/custom_components -config/custom_components/* -!config/custom_components/example.py -!config/custom_components/hello_world.py -!config/custom_components/mqtt_example.py -!config/panels -config/panels/* -!config/panels/react.html tests/testing_config/deps tests/testing_config/home-assistant.log diff --git a/README.rst b/README.rst index 2b166cd9a1350c..ec0a770b1dae4f 100644 --- a/README.rst +++ b/README.rst @@ -1,9 +1,7 @@ Home Assistant |Build Status| |Coverage Status| |Join the chat at https://gitter.im/home-assistant/home-assistant| |Join the dev chat at https://gitter.im/home-assistant/home-assistant/devs| ============================================================================================================================================================================================== -Home Assistant is a home automation platform running on Python 3. The -goal of Home Assistant is to be able to track and control all devices at -home and offer a platform for automating control. +Home Assistant is a home automation platform running on Python 3. It is to be able to track and control all devices at home and offer a platform for automating control. To get started: @@ -12,83 +10,19 @@ To get started: python3 -m pip install homeassistant hass --open-ui -Check out `the website `__ for `a -demo `__, installation instructions, -tutorials and documentation. +Check out `home-assistant.io `__ for `a +demo `__, `installation instructions `__, +`tutorials `__ and `documentation `__. |screenshot-states| -Examples of devices Home Assistant can interface with: +|screenshot-components| -- Monitoring connected devices to a wireless router: - `OpenWrt `__, - `Tomato `__, - `Netgear `__, - `DD-WRT `__, - `TPLink `__, - `ASUSWRT `__, - `Xiaomi `__ and any SNMP - capable Linksys WAP/WRT -- `Philips Hue `__ lights, - `WeMo `__ - switches, `Edimax `__ switches, - `Efergy `__ energy monitoring, and - `Tellstick `__ devices and - sensors -- `Google - Chromecasts `__, - `Music Player Daemon `__, `Logitech - Squeezebox `__, - `Plex `__, `Kodi (XBMC) `__, - iTunes (by way of - `itunes-api `__), and Amazon - Fire TV (by way of - `python-firetv `__) -- Support for - `ISY994 `__ - (Insteon and X10 devices), `Z-Wave `__, `Nest - Thermostats `__, - `RFXtrx `__, - `Arduino `__, `Raspberry - Pi `__, and - `Modbus `__ -- Interaction with `IFTTT `__ -- Integrate data from the `Bitcoin `__ network, - meteorological data from - `OpenWeatherMap `__ and - `Forecast.io `__, - `Transmission `__, or - `SABnzbd `__. -- `See full list of supported - devices `__ - -Build home automation on top of your devices: - -- Keep a precise history of every change to the state of your house -- Turn on the lights when people get home after sunset -- Turn on lights slowly during sunset to compensate for less light -- Turn off all lights and devices when everybody leaves the house -- Offers a `REST API `__ - and can interface with MQTT for easy integration with other projects - like `OwnTracks `__ -- Allow sending notifications using - `Instapush `__, `Notify My Android - (NMA) `__, - `PushBullet `__, - `PushOver `__, - `Slack `__, - `Telegram `__, `Join `__, and `Jabber - (XMPP) `__ - -The system is built using a modular approach so support for other devices or actions can -be implemented easily. See also the `section on -architecture `__ -and the `section on creating your own +The system is built using a modular approach so support for other devices or actions can be implemented easily. See also the `section on architecture `__ and the `section on creating your own components `__. If you run into issues while using Home Assistant or during development -of a component, check the `Home Assistant help -section `__ of our website for further help and information. +of a component, check the `Home Assistant help section `__ of our website for further help and information. .. |Build Status| image:: https://travis-ci.org/home-assistant/home-assistant.svg?branch=master :target: https://travis-ci.org/home-assistant/home-assistant @@ -100,3 +34,5 @@ section `__ of our website for further help and :target: https://gitter.im/home-assistant/home-assistant/devs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge .. |screenshot-states| image:: https://raw.github.com/home-assistant/home-assistant/master/docs/screenshots.png :target: https://home-assistant.io/demo/ +.. |screenshot-components| image:: https://raw.github.com/home-assistant/home-assistant/dev/docs/screenshot-components.png + :target: https://home-assistant.io/components/ \ No newline at end of file diff --git a/config/configuration.yaml.example b/config/configuration.yaml.example deleted file mode 100644 index 08b0324371f180..00000000000000 --- a/config/configuration.yaml.example +++ /dev/null @@ -1,158 +0,0 @@ -homeassistant: - # Omitted values in this section will be auto detected using freegeoip.io - - # Location required to calculate the time the sun rises and sets. - # Coordinates are also used for location for weather related components. - # Google Maps can be used to determine more precise GPS coordinates. - latitude: 32.87336 - longitude: 117.22743 - - # Impacts weather/sunrise data - elevation: 665 - - # 'metric' for Metric System, 'imperial' for imperial system - unit_system: metric - - # Pick yours from here: - # http://en.wikipedia.org/wiki/List_of_tz_database_time_zones - time_zone: America/Los_Angeles - - # Name of the location where Home Assistant is running - name: Home - -http: - api_password: mypass - # Set to 1 to enable development mode - # development: 1 - -# Enable the frontend -frontend: - -light: -# platform: hue - -wink: - # Get your token at https://winkbearertoken.appspot.com - access_token: 'YOUR_TOKEN' - -device_tracker: - # The following tracker are available: - # https://home-assistant.io/components/#presence-detection - platform: netgear - host: 192.168.1.1 - username: admin - password: PASSWORD - -switch: - platform: wemo - -climate: - platform: nest - # Required: username and password that are used to login to the Nest thermostat. - username: myemail@mydomain.com - password: mypassword - -downloader: - download_dir: downloads - -notify: - platform: pushbullet - api_key: ABCDEFGHJKLMNOPQRSTUVXYZ - -device_sun_light_trigger: - # Optional: specify a specific light/group of lights that has to be turned on - light_group: group.living_room - # Optional: specify which light profile to use when turning lights on - light_profile: relax - # Optional: disable lights being turned off when everybody leaves the house - # disable_turn_off: 1 - -# A comma separated list of states that have to be tracked as a single group -# Grouped states should share the same type of states (ON/OFF or HOME/NOT_HOME) -# You can also have groups within groups. -# https://home-assistant.io/components/group/ -group: - default_view: - view: yes - entities: - - group.awesome_people - - group.climate - kitchen: - name: Kitchen - entities: - - switch.kitchen_pin_3 - upstairs: - name: Kids - icon: mdi:account-multiple - view: yes - entities: - - input_boolean.notify_home - - camera.demo_camera - -browser: -keyboard: - -# https://home-assistant.io/getting-started/automation/ -automation: - - alias: Turn on light when sun sets - trigger: - platform: sun - event: sunset - offset: "-01:00:00" - condition: - condition: state - entity_id: group.all_devices - state: 'home' - action: - service: light.turn_on - -# Another way to do is to collect all entries under one "sensor:" -# sensor: -# - platform: mqtt -# name: "MQTT Sensor 1" -# - platform: mqtt -# name: "MQTT Sensor 2" -# -# Details: https://home-assistant.io/getting-started/devices/ - -sensor: - platform: systemmonitor - resources: - - type: 'disk_use_percent' - arg: '/' - - type: 'disk_use_percent' - arg: '/home' - -sensor 2: - platform: cpuspeed - -script: - wakeup: - alias: Wake Up - sequence: - - event: LOGBOOK_ENTRY - event_data: - name: Paulus - message: is waking up - entity_id: device_tracker.paulus - domain: light - - alias: Bedroom lights on - service: light.turn_on - data: - entity_id: group.bedroom - brightness: 100 - - delay: - minutes: 1 - - alias: Living room lights on - service: light.turn_on - data: - entity_id: group.living_room - -scene: - - name: Romantic - entities: - light.tv_back_light: on - light.ceiling: - state: on - xy_color: [0.33, 0.66] - brightness: 200 diff --git a/config/custom_components/example.py b/config/custom_components/example.py deleted file mode 100644 index 4d3df9328d8a8b..00000000000000 --- a/config/custom_components/example.py +++ /dev/null @@ -1,149 +0,0 @@ -""" -Example of a custom component. - -Example component to target an entity_id to: - - turn it on at 7AM in the morning - - turn it on if anyone comes home and it is off - - turn it off if all lights are turned off - - turn it off if all people leave the house - - offer a service to turn it on for 10 seconds - -Configuration: - -To use the Example custom component you will need to add the following to -your configuration.yaml file. - -example: - target: TARGET_ENTITY - -Variable: - -target -*Required -TARGET_ENTITY should be one of your devices that can be turned on and off, -ie a light or a switch. Example value could be light.Ceiling or switch.AC -(if you have these devices with those names). -""" -import time -import logging - -from homeassistant.const import STATE_HOME, STATE_NOT_HOME, STATE_ON, STATE_OFF -from homeassistant.helpers import validate_config -from homeassistant.helpers.event_decorators import \ - track_state_change, track_time_change -from homeassistant.helpers.service import service -import homeassistant.components as core -from homeassistant.components import device_tracker -from homeassistant.components import light - -# The domain of your component. Should be equal to the name of your component. -DOMAIN = "example" - -# List of component names (string) your component depends upon. -# We depend on group because group will be loaded after all the components that -# initialize devices have been setup. -DEPENDENCIES = ['group', 'device_tracker', 'light'] - -# Configuration key for the entity id we are targeting. -CONF_TARGET = 'target' - -# Variable for storing configuration parameters. -TARGET_ID = None - -# Name of the service that we expose. -SERVICE_FLASH = 'flash' - -# Shortcut for the logger -_LOGGER = logging.getLogger(__name__) - - -def setup(hass, config): - """Setup example component.""" - global TARGET_ID - - # Validate that all required config options are given. - if not validate_config(config, {DOMAIN: [CONF_TARGET]}, _LOGGER): - return False - - TARGET_ID = config[DOMAIN][CONF_TARGET] - - # Validate that the target entity id exists. - if hass.states.get(TARGET_ID) is None: - _LOGGER.error("Target entity id %s does not exist", - TARGET_ID) - - # Tell the bootstrapper that we failed to initialize and clear the - # stored target id so our functions don't run. - TARGET_ID = None - return False - - # Tell the bootstrapper that we initialized successfully. - return True - - -@track_state_change(device_tracker.ENTITY_ID_ALL_DEVICES) -def track_devices(hass, entity_id, old_state, new_state): - """Called when the group.all devices change state.""" - # If the target id is not set, return - if not TARGET_ID: - return - - # If anyone comes home and the entity is not on, turn it on. - if new_state.state == STATE_HOME and not core.is_on(hass, TARGET_ID): - - core.turn_on(hass, TARGET_ID) - - # If all people leave the house and the entity is on, turn it off. - elif new_state.state == STATE_NOT_HOME and core.is_on(hass, TARGET_ID): - - core.turn_off(hass, TARGET_ID) - - -@track_time_change(hour=7, minute=0, second=0) -def wake_up(hass, now): - """Turn light on in the morning. - - Turn the light on at 7 AM if there are people home and it is not already - on. - """ - if not TARGET_ID: - return - - if device_tracker.is_on(hass) and not core.is_on(hass, TARGET_ID): - _LOGGER.info('People home at 7AM, turning it on') - core.turn_on(hass, TARGET_ID) - - -@track_state_change(light.ENTITY_ID_ALL_LIGHTS, STATE_ON, STATE_OFF) -def all_lights_off(hass, entity_id, old_state, new_state): - """If all lights turn off, turn off.""" - if not TARGET_ID: - return - - if core.is_on(hass, TARGET_ID): - _LOGGER.info('All lights have been turned off, turning it off') - core.turn_off(hass, TARGET_ID) - - -@service(DOMAIN, SERVICE_FLASH) -def flash_service(hass, call): - """Service that will toggle the target. - - Set the light to off for 10 seconds if on and vice versa. - """ - if not TARGET_ID: - return - - if core.is_on(hass, TARGET_ID): - core.turn_off(hass, TARGET_ID) - - time.sleep(10) - - core.turn_on(hass, TARGET_ID) - - else: - core.turn_on(hass, TARGET_ID) - - time.sleep(10) - - core.turn_off(hass, TARGET_ID) diff --git a/config/custom_components/hello_world.py b/config/custom_components/hello_world.py deleted file mode 100644 index b35e9f6c0ed972..00000000000000 --- a/config/custom_components/hello_world.py +++ /dev/null @@ -1,27 +0,0 @@ -""" -The "hello world" custom component. - -This component implements the bare minimum that a component should implement. - -Configuration: - -To use the hello_word component you will need to add the following to your -configuration.yaml file. - -hello_world: -""" - -# The domain of your component. Should be equal to the name of your component. -DOMAIN = "hello_world" - -# List of component names (string) your component depends upon. -DEPENDENCIES = [] - - -def setup(hass, config): - """Setup our skeleton component.""" - # States are in the format DOMAIN.OBJECT_ID. - hass.states.set('hello_world.Hello_World', 'Works!') - - # Return boolean to indicate that initialization was successfully. - return True diff --git a/config/custom_components/mqtt_example.py b/config/custom_components/mqtt_example.py deleted file mode 100644 index 451a60deef4da9..00000000000000 --- a/config/custom_components/mqtt_example.py +++ /dev/null @@ -1,55 +0,0 @@ -""" -Example of a custom MQTT component. - -Shows how to communicate with MQTT. Follows a topic on MQTT and updates the -state of an entity to the last message received on that topic. - -Also offers a service 'set_state' that will publish a message on the topic that -will be passed via MQTT to our message received listener. Call the service with -example payload {"new_state": "some new state"}. - -Configuration: - -To use the mqtt_example component you will need to add the following to your -configuration.yaml file. - -mqtt_example: - topic: "home-assistant/mqtt_example" -""" -import homeassistant.loader as loader - -# The domain of your component. Should be equal to the name of your component. -DOMAIN = "mqtt_example" - -# List of component names (string) your component depends upon. -DEPENDENCIES = ['mqtt'] - -CONF_TOPIC = 'topic' -DEFAULT_TOPIC = 'home-assistant/mqtt_example' - - -def setup(hass, config): - """Setup the MQTT example component.""" - mqtt = loader.get_component('mqtt') - topic = config[DOMAIN].get('topic', DEFAULT_TOPIC) - entity_id = 'mqtt_example.last_message' - - # Listen to a message on MQTT. - def message_received(topic, payload, qos): - """A new MQTT message has been received.""" - hass.states.set(entity_id, payload) - - mqtt.subscribe(hass, topic, message_received) - - hass.states.set(entity_id, 'No messages') - - # Service to publish a message on MQTT. - def set_state_service(call): - """Service to send a message.""" - mqtt.publish(hass, topic, call.data.get('new_state')) - - # Register our service with Home Assistant. - hass.services.register(DOMAIN, 'set_state', set_state_service) - - # Return boolean to indicate that initialization was successfully. - return True diff --git a/config/panels/react.html b/config/panels/react.html deleted file mode 100644 index dc2735cf75951c..00000000000000 --- a/config/panels/react.html +++ /dev/null @@ -1,432 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/docs/screenshot-components.png b/docs/screenshot-components.png new file mode 100755 index 0000000000000000000000000000000000000000..247f3073a5e228cb7118ecbbecacefe4f03f5706 GIT binary patch literal 47635 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 Date: Sun, 2 Apr 2017 17:35:03 -0700 Subject: [PATCH 069/116] Update README.rst --- README.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index ec0a770b1dae4f..66c9cedea7448e 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ Home Assistant |Build Status| |Coverage Status| |Join the chat at https://gitter.im/home-assistant/home-assistant| |Join the dev chat at https://gitter.im/home-assistant/home-assistant/devs| ============================================================================================================================================================================================== -Home Assistant is a home automation platform running on Python 3. It is to be able to track and control all devices at home and offer a platform for automating control. +Home Assistant is a home automation platform running on Python 3. It is able to track and control all devices at home and offer a platform for automating control. To get started: @@ -16,6 +16,9 @@ demo `__, `installation instructions `__ and the `section on creating your own @@ -35,4 +38,4 @@ of a component, check the `Home Assistant help section Date: Mon, 3 Apr 2017 02:46:18 -0400 Subject: [PATCH 070/116] Makes amcrest.sensor to handle properly the scan_interval option. (#6885) * Makes amcrest.sensor to handle scan_interval option as expected. * Added _LOGGER.debug statement for troubleshooting. * Fixed lint --- homeassistant/components/sensor/amcrest.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/sensor/amcrest.py b/homeassistant/components/sensor/amcrest.py index 79e886c154dc20..5a349d28b7cb03 100644 --- a/homeassistant/components/sensor/amcrest.py +++ b/homeassistant/components/sensor/amcrest.py @@ -13,8 +13,7 @@ from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( CONF_HOST, CONF_NAME, CONF_MONITORED_CONDITIONS, - CONF_SCAN_INTERVAL, CONF_USERNAME, CONF_PASSWORD, - CONF_PORT, STATE_UNKNOWN) + CONF_USERNAME, CONF_PASSWORD, CONF_PORT, STATE_UNKNOWN) from homeassistant.helpers.entity import Entity import homeassistant.loader as loader @@ -29,7 +28,7 @@ DEFAULT_NAME = 'Amcrest' DEFAULT_PORT = 80 -DEFAULT_SCAN_INTERVAL = timedelta(seconds=10) +SCAN_INTERVAL = timedelta(seconds=10) # Sensor types are defined like: Name, units, icon SENSOR_TYPES = { @@ -44,8 +43,6 @@ vol.Required(CONF_PASSWORD): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, - vol.Optional(CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL): - vol.All(vol.Coerce(int), vol.Range(min=1)), vol.Required(CONF_MONITORED_CONDITIONS, default=[]): vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]), }) @@ -122,6 +119,8 @@ def unit_of_measurement(self): def update(self): """Get the latest data and updates the state.""" + _LOGGER.debug("Pulling data from %s sensor.", self._name) + try: version, build_date = self._camera.software_information self._attrs['Build Date'] = build_date.split('=')[-1] From f4d2ece2fed2f0727e50d3236cb3e0898046630e Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Mon, 3 Apr 2017 02:46:54 -0400 Subject: [PATCH 071/116] Make sensor.ring to handle scan_interval option as expected. (#6886) * Make sensor.ring to handle scan_interval option as expected. * Fix lint * Fixed lint timedelta --- homeassistant/components/ring.py | 2 -- homeassistant/components/sensor/ring.py | 11 +++++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/ring.py b/homeassistant/components/ring.py index 61c772eced730a..01b9cee99965cb 100644 --- a/homeassistant/components/ring.py +++ b/homeassistant/components/ring.py @@ -4,7 +4,6 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/ring/ """ -from datetime import timedelta import logging import voluptuous as vol import homeassistant.helpers.config_validation as cv @@ -26,7 +25,6 @@ DOMAIN = 'ring' DEFAULT_CACHEDB = '.ring_cache.pickle' DEFAULT_ENTITY_NAMESPACE = 'ring' -DEFAULT_SCAN_INTERVAL = timedelta(seconds=30) CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ diff --git a/homeassistant/components/sensor/ring.py b/homeassistant/components/sensor/ring.py index 665fb167bccad7..dfe791c4c41ffc 100644 --- a/homeassistant/components/sensor/ring.py +++ b/homeassistant/components/sensor/ring.py @@ -4,16 +4,17 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.ring/ """ +from datetime import timedelta import logging import voluptuous as vol import homeassistant.helpers.config_validation as cv from homeassistant.components.ring import ( - CONF_ATTRIBUTION, DEFAULT_ENTITY_NAMESPACE, DEFAULT_SCAN_INTERVAL) + CONF_ATTRIBUTION, DEFAULT_ENTITY_NAMESPACE) from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( - CONF_ENTITY_NAMESPACE, CONF_MONITORED_CONDITIONS, CONF_SCAN_INTERVAL, + CONF_ENTITY_NAMESPACE, CONF_MONITORED_CONDITIONS, STATE_UNKNOWN, ATTR_ATTRIBUTION) from homeassistant.helpers.entity import Entity @@ -21,6 +22,8 @@ _LOGGER = logging.getLogger(__name__) +SCAN_INTERVAL = timedelta(seconds=30) + # Sensor types: Name, category, units, icon, kind SENSOR_TYPES = { 'battery': ['Battery', ['doorbell'], '%', 'battery-50', None], @@ -33,8 +36,6 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_ENTITY_NAMESPACE, default=DEFAULT_ENTITY_NAMESPACE): cv.string, - vol.Optional(CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL): - vol.All(vol.Coerce(int), vol.Range(min=1)), vol.Required(CONF_MONITORED_CONDITIONS, default=[]): vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]), }) @@ -120,6 +121,8 @@ def unit_of_measurement(self): def update(self): """Get the latest data and updates the state.""" + _LOGGER.debug("Pulling data from %s sensor.", self._name) + self._data.update() if self._sensor_type == 'volume': From c27a526f5be39efeca94a96f1859d2507adeef81 Mon Sep 17 00:00:00 2001 From: David McNett Date: Mon, 3 Apr 2017 02:01:53 -0500 Subject: [PATCH 072/116] Eliminate needless async_add_job invocation of async_add_devices (#6864) --- homeassistant/components/binary_sensor/insteon_plm.py | 2 +- homeassistant/components/light/insteon_plm.py | 2 +- homeassistant/components/light/lifx.py | 2 +- homeassistant/components/switch/insteon_plm.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/binary_sensor/insteon_plm.py b/homeassistant/components/binary_sensor/insteon_plm.py index f6c8d9edbd146a..03cc7e6bd9bdbd 100644 --- a/homeassistant/components/binary_sensor/insteon_plm.py +++ b/homeassistant/components/binary_sensor/insteon_plm.py @@ -32,7 +32,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): InsteonPLMBinarySensorDevice(hass, plm, address, name) ) - hass.async_add_job(async_add_devices(device_list)) + async_add_devices(device_list) class InsteonPLMBinarySensorDevice(BinarySensorDevice): diff --git a/homeassistant/components/light/insteon_plm.py b/homeassistant/components/light/insteon_plm.py index 2d043a9f9856df..2cd22cf6d4dc8e 100644 --- a/homeassistant/components/light/insteon_plm.py +++ b/homeassistant/components/light/insteon_plm.py @@ -36,7 +36,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): InsteonPLMDimmerDevice(hass, plm, address, name, dimmable) ) - hass.async_add_job(async_add_devices(device_list)) + async_add_devices(device_list) class InsteonPLMDimmerDevice(Light): diff --git a/homeassistant/components/light/lifx.py b/homeassistant/components/light/lifx.py index d3b084b3b941b2..76a2a9e907d090 100644 --- a/homeassistant/components/light/lifx.py +++ b/homeassistant/components/light/lifx.py @@ -95,7 +95,7 @@ def ready(self, device, msg): entity = LIFXLight(device) _LOGGER.debug("%s register READY", entity.ipaddr) self.entities[device.mac_addr] = entity - self.hass.async_add_job(self.async_add_devices, [entity]) + self.async_add_devices([entity]) @callback def unregister(self, device): diff --git a/homeassistant/components/switch/insteon_plm.py b/homeassistant/components/switch/insteon_plm.py index 646e6d4416bc01..ee192b82be44db 100644 --- a/homeassistant/components/switch/insteon_plm.py +++ b/homeassistant/components/switch/insteon_plm.py @@ -32,7 +32,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): InsteonPLMSwitchDevice(hass, plm, address, name) ) - hass.async_add_job(async_add_devices(device_list)) + async_add_devices(device_list) class InsteonPLMSwitchDevice(SwitchDevice): From 134b21dfea9d8cd3fb7466e3448a453e621fabf2 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 3 Apr 2017 03:35:36 -0400 Subject: [PATCH 073/116] Onkyo update (#6906) * Update onkyo req, change volume to int * Update Onkyo Updates onkyo component. Pulls added sources (Bluetooth, built-in streaming, etc.) * Regenerated requirements_all.txt via script * Update onkyo.py * Update requirements_all.txt --- homeassistant/components/media_player/onkyo.py | 7 ++++--- requirements_all.txt | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/media_player/onkyo.py b/homeassistant/components/media_player/onkyo.py index 017581f8186422..67197d7d0da2d9 100644 --- a/homeassistant/components/media_player/onkyo.py +++ b/homeassistant/components/media_player/onkyo.py @@ -14,8 +14,9 @@ from homeassistant.const import (STATE_OFF, STATE_ON, CONF_HOST, CONF_NAME) import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['https://github.com/danieljkemp/onkyo-eiscp/archive/' - 'python3.zip#onkyo-eiscp==0.9.2'] +REQUIREMENTS = ['https://github.com/miracle2k/onkyo-eiscp/archive/' + '066023aec04770518d494c32fb72eea0ec5c1b7c.zip#' + 'onkyo-eiscp==1.0'] _LOGGER = logging.getLogger(__name__) @@ -127,7 +128,7 @@ def update(self): self._current_source = '_'.join( [i for i in current_source_tuples[1]]) self._muted = bool(mute_raw[1] == 'on') - self._volume = int(volume_raw[1], 16) / 80.0 + self._volume = volume_raw[1] / 80.0 @property def name(self): diff --git a/requirements_all.txt b/requirements_all.txt index a77400657762bf..76a7afe62b8356 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -252,9 +252,6 @@ https://github.com/bah2830/python-roku/archive/3.1.3.zip#roku==3.1.3 # homeassistant.components.modbus https://github.com/bashwork/pymodbus/archive/d7fc4f1cc975631e0a9011390e8017f64b612661.zip#pymodbus==1.2.0 -# homeassistant.components.media_player.onkyo -https://github.com/danieljkemp/onkyo-eiscp/archive/python3.zip#onkyo-eiscp==0.9.2 - # homeassistant.components.lutron_caseta https://github.com/gurumitts/pylutron-caseta/archive/v0.2.4.zip#pylutron-caseta==v0.2.4 @@ -273,6 +270,9 @@ https://github.com/joopert/nad_receiver/archive/0.0.3.zip#nad_receiver==0.0.3 # homeassistant.components.media_player.russound_rnet https://github.com/laf/russound/archive/0.1.7.zip#russound==0.1.7 +# homeassistant.components.media_player.onkyo +https://github.com/miracle2k/onkyo-eiscp/archive/066023aec04770518d494c32fb72eea0ec5c1b7c.zip#onkyo-eiscp==1.0 + # homeassistant.components.sensor.pocketcasts https://github.com/molobrakos/python-pocketcasts/archive/9f61ff00c77c7c98ffa0af9dd3540df3dce4a836.zip#python-pocketcasts==0.0.1 From a107a592de1851f7daa0868f3bba6208fa96d329 Mon Sep 17 00:00:00 2001 From: John Arild Berentsen Date: Mon, 3 Apr 2017 14:42:21 +0200 Subject: [PATCH 074/116] Fix for #6691 Neato Connection error handling (#6731) * Responsiveness * Delay was not needed as commands does not return until done. * Offline error catch * Remove unneeded code --- homeassistant/components/sensor/neato.py | 10 ++++++++-- homeassistant/components/switch/neato.py | 7 ++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/sensor/neato.py b/homeassistant/components/sensor/neato.py index 438e5fb189b074..ca5cff1d24a0dd 100644 --- a/homeassistant/components/sensor/neato.py +++ b/homeassistant/components/sensor/neato.py @@ -5,7 +5,7 @@ https://home-assistant.io/components/sensor.neato/ """ import logging - +import requests from homeassistant.helpers.entity import Entity from homeassistant.components.neato import ( NEATO_ROBOTS, NEATO_LOGIN, ACTION, ERRORS, MODE, ALERTS) @@ -52,7 +52,13 @@ def update(self): self.neato.update_robots() if not self._state: return - self._state = self.robot.state + try: + self._state = self.robot.state + except requests.exceptions.HTTPError as ex: + self._state = None + self._status_state = 'Offline' + _LOGGER.debug('Neato connection issue: %s', ex) + return _LOGGER.debug('self._state=%s', self._state) if self.type == SENSOR_TYPE_STATUS: if self._state['state'] == 1: diff --git a/homeassistant/components/switch/neato.py b/homeassistant/components/switch/neato.py index 3b723acb748c19..6cd5c5088dc2ed 100644 --- a/homeassistant/components/switch/neato.py +++ b/homeassistant/components/switch/neato.py @@ -5,7 +5,7 @@ https://home-assistant.io/components/switch.neato/ """ import logging - +import requests from homeassistant.const import STATE_OFF, STATE_ON from homeassistant.helpers.entity import ToggleEntity from homeassistant.components.neato import NEATO_ROBOTS, NEATO_LOGIN @@ -53,6 +53,11 @@ def update(self): self.neato.update_robots() if not self._state: return + try: + self._state = self.robot.state + except requests.exceptions.HTTPError: + self._state = None + return self._state = self.robot.state _LOGGER.debug('self._state=%s', self._state) if self.type == SWITCH_TYPE_CLEAN: From 01e581acede049bb551333e8133606e344c9c2b1 Mon Sep 17 00:00:00 2001 From: Mitesh Patel Date: Mon, 3 Apr 2017 10:52:02 -0500 Subject: [PATCH 075/116] Adds support for the PlugInDimmer hardware (#6915) --- homeassistant/components/light/lutron_caseta.py | 2 +- homeassistant/components/lutron_caseta.py | 4 ++-- requirements_all.txt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/light/lutron_caseta.py b/homeassistant/components/light/lutron_caseta.py index aef3f8ae799035..e77501e8ce4d38 100644 --- a/homeassistant/components/light/lutron_caseta.py +++ b/homeassistant/components/light/lutron_caseta.py @@ -19,7 +19,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): """Setup Lutron Caseta lights.""" devs = [] bridge = hass.data[LUTRON_CASETA_SMARTBRIDGE] - light_devices = bridge.get_devices_by_type("WallDimmer") + light_devices = bridge.get_devices_by_types(["WallDimmer", "PlugInDimmer"]) for light_device in light_devices: dev = LutronCasetaLight(light_device, bridge) devs.append(dev) diff --git a/homeassistant/components/lutron_caseta.py b/homeassistant/components/lutron_caseta.py index 6cb42618af27e9..416c9f7fd003b5 100644 --- a/homeassistant/components/lutron_caseta.py +++ b/homeassistant/components/lutron_caseta.py @@ -17,8 +17,8 @@ from homeassistant.helpers.entity import Entity REQUIREMENTS = ['https://github.com/gurumitts/' - 'pylutron-caseta/archive/v0.2.4.zip#' - 'pylutron-caseta==v0.2.4'] + 'pylutron-caseta/archive/v0.2.5.zip#' + 'pylutron-caseta==v0.2.5'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 76a7afe62b8356..f9715190e5a25a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -253,7 +253,7 @@ https://github.com/bah2830/python-roku/archive/3.1.3.zip#roku==3.1.3 https://github.com/bashwork/pymodbus/archive/d7fc4f1cc975631e0a9011390e8017f64b612661.zip#pymodbus==1.2.0 # homeassistant.components.lutron_caseta -https://github.com/gurumitts/pylutron-caseta/archive/v0.2.4.zip#pylutron-caseta==v0.2.4 +https://github.com/gurumitts/pylutron-caseta/archive/v0.2.5.zip#pylutron-caseta==v0.2.5 # homeassistant.components.netatmo https://github.com/jabesq/netatmo-api-python/archive/v0.9.1.zip#lnetatmo==0.9.1 From 06e1c21b1f32576ff1c11d7131a6b77225ccd00a Mon Sep 17 00:00:00 2001 From: Adam Mills Date: Mon, 3 Apr 2017 14:56:48 -0400 Subject: [PATCH 076/116] Support for zwave light transitions (#6868) * Support for zwave light transitions * Dimming duration is optional * Updated supported_features to show transition --- homeassistant/components/light/zwave.py | 84 ++++++++++++++----- homeassistant/components/zwave/__init__.py | 5 ++ .../components/zwave/discovery_schemas.py | 7 ++ tests/components/light/test_zwave.py | 63 +++++++++++++- 4 files changed, 132 insertions(+), 27 deletions(-) diff --git a/homeassistant/components/light/zwave.py b/homeassistant/components/light/zwave.py index a2ba8e7c2a072d..45660474fde704 100644 --- a/homeassistant/components/light/zwave.py +++ b/homeassistant/components/light/zwave.py @@ -10,8 +10,8 @@ # pylint: disable=import-error from threading import Timer from homeassistant.components.light import ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, \ - ATTR_RGB_COLOR, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, \ - SUPPORT_RGB_COLOR, DOMAIN, Light + ATTR_RGB_COLOR, ATTR_TRANSITION, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, \ + SUPPORT_RGB_COLOR, SUPPORT_TRANSITION, DOMAIN, Light from homeassistant.components import zwave from homeassistant.components.zwave import async_setup_platform # noqa # pylint: disable=unused-import from homeassistant.const import STATE_OFF, STATE_ON @@ -43,11 +43,6 @@ TEMP_WARM_HASS = (HASS_COLOR_MAX - HASS_COLOR_MIN) / 3 * 2 + HASS_COLOR_MIN TEMP_COLD_HASS = (HASS_COLOR_MAX - HASS_COLOR_MIN) / 3 + HASS_COLOR_MIN -SUPPORT_ZWAVE_DIMMER = SUPPORT_BRIGHTNESS -SUPPORT_ZWAVE_COLOR = SUPPORT_BRIGHTNESS | SUPPORT_RGB_COLOR -SUPPORT_ZWAVE_COLORTEMP = (SUPPORT_BRIGHTNESS | SUPPORT_RGB_COLOR - | SUPPORT_COLOR_TEMP) - def get_device(node, values, node_config, **kwargs): """Create zwave entity device.""" @@ -72,6 +67,13 @@ def brightness_state(value): return 0, STATE_OFF +def ct_to_rgb(temp): + """Convert color temperature (mireds) to RGB.""" + colorlist = list( + color_temperature_to_rgb(color_temperature_mired_to_kelvin(temp))) + return [int(val) for val in colorlist] + + class ZwaveDimmer(zwave.ZWaveDeviceEntity, Light): """Representation of a Z-Wave dimmer.""" @@ -80,6 +82,7 @@ def __init__(self, values, refresh, delay): zwave.ZWaveDeviceEntity.__init__(self, values, DOMAIN) self._brightness = None self._state = None + self._supported_features = None self._delay = delay self._refresh_value = refresh self._zw098 = None @@ -100,6 +103,7 @@ def __init__(self, values, refresh, delay): self._timer = None _LOGGER.debug('self._refreshing=%s self.delay=%s', self._refresh_value, self._delay) + self.value_added() self.update_properties() def update_properties(self): @@ -107,6 +111,12 @@ def update_properties(self): # Brightness self._brightness, self._state = brightness_state(self.values.primary) + def value_added(self): + """Called when a new value is added to this entity.""" + self._supported_features = SUPPORT_BRIGHTNESS + if self.values.dimming_duration is not None: + self._supported_features |= SUPPORT_TRANSITION + def value_changed(self): """Called when a value for this entity's node has changed.""" if self._refresh_value: @@ -139,10 +149,43 @@ def is_on(self): @property def supported_features(self): """Flag supported features.""" - return SUPPORT_ZWAVE_DIMMER + return self._supported_features + + def _set_duration(self, **kwargs): + """Set the transition time for the brightness value. + + Zwave Dimming Duration values: + 0x00 = instant + 0x01-0x7F = 1 second to 127 seconds + 0x80-0xFE = 1 minute to 127 minutes + 0xFF = factory default + """ + if self.values.dimming_duration is None: + if ATTR_TRANSITION in kwargs: + _LOGGER.debug("Dimming not supported by %s.", self.entity_id) + return + + if ATTR_TRANSITION not in kwargs: + self.values.dimming_duration.data = 0xFF + return + + transition = kwargs[ATTR_TRANSITION] + if transition <= 127: + self.values.dimming_duration.data = int(transition) + elif transition > 7620: + self.values.dimming_duration.data = 0xFE + _LOGGER.warning("Transition clipped to 127 minutes for %s.", + self.entity_id) + else: + minutes = int(transition / 60) + _LOGGER.debug("Transition rounded to %d minutes for %s.", + minutes, self.entity_id) + self.values.dimming_duration.data = minutes + 0x7F def turn_on(self, **kwargs): """Turn the device on.""" + self._set_duration(**kwargs) + # Zwave multilevel switches use a range of [0, 99] to control # brightness. Level 255 means to set it to previous value. if ATTR_BRIGHTNESS in kwargs: @@ -156,17 +199,12 @@ def turn_on(self, **kwargs): def turn_off(self, **kwargs): """Turn the device off.""" + self._set_duration(**kwargs) + if self.node.set_dimmer(self.values.primary.value_id, 0): self._state = STATE_OFF -def ct_to_rgb(temp): - """Convert color temperature (mireds) to RGB.""" - colorlist = list( - color_temperature_to_rgb(color_temperature_mired_to_kelvin(temp))) - return [int(val) for val in colorlist] - - class ZwaveColorLight(ZwaveDimmer): """Representation of a Z-Wave color changing light.""" @@ -178,6 +216,14 @@ def __init__(self, values, refresh, delay): super().__init__(values, refresh, delay) + def value_added(self): + """Called when a new value is added to this entity.""" + super().value_added() + + self._supported_features |= SUPPORT_RGB_COLOR + if self._zw098: + self._supported_features |= SUPPORT_COLOR_TEMP + def update_properties(self): """Update internal properties based on zwave values.""" super().update_properties() @@ -288,11 +334,3 @@ def turn_on(self, **kwargs): self.values.color.data = rgbw super().turn_on(**kwargs) - - @property - def supported_features(self): - """Flag supported features.""" - if self._zw098: - return SUPPORT_ZWAVE_COLORTEMP - else: - return SUPPORT_ZWAVE_COLOR diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py index 4eea502d40a8b2..efef8b39b6405a 100755 --- a/homeassistant/components/zwave/__init__.py +++ b/homeassistant/components/zwave/__init__.py @@ -669,6 +669,7 @@ def check_value(self, value): continue self._values[name] = value if self._entity: + self._entity.value_added() self._entity.value_changed() self._check_entity_ready() @@ -778,6 +779,10 @@ def network_value_changed(self, value): if value.value_id in [v.value_id for v in self.values if v]: return self.value_changed() + def value_added(self): + """Called when a new value is added to this entity.""" + pass + def value_changed(self): """Called when a value for this entity's node has changed.""" self._update_attributes() diff --git a/homeassistant/components/zwave/discovery_schemas.py b/homeassistant/components/zwave/discovery_schemas.py index 12a8c8c4375276..f6e56ce79c81d7 100644 --- a/homeassistant/components/zwave/discovery_schemas.py +++ b/homeassistant/components/zwave/discovery_schemas.py @@ -121,6 +121,13 @@ const.DISC_GENRE: const.GENRE_USER, const.DISC_TYPE: const.TYPE_BYTE, }, + 'dimming_duration': { + const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL], + const.DISC_GENRE: const.GENRE_SYSTEM, + const.DISC_TYPE: const.TYPE_BYTE, + const.DISC_LABEL: 'Dimming Duration', + const.DISC_OPTIONAL: True, + }, 'color': { const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_COLOR], const.DISC_GENRE: const.GENRE_USER, diff --git a/tests/components/light/test_zwave.py b/tests/components/light/test_zwave.py index dc4096ac68cf76..0afe9ec8f6ac00 100644 --- a/tests/components/light/test_zwave.py +++ b/tests/components/light/test_zwave.py @@ -4,7 +4,9 @@ import homeassistant.components.zwave from homeassistant.components.zwave import const from homeassistant.components.light import ( - zwave, ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_RGB_COLOR) + zwave, ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_RGB_COLOR, ATTR_TRANSITION, + SUPPORT_BRIGHTNESS, SUPPORT_TRANSITION, SUPPORT_RGB_COLOR, + SUPPORT_COLOR_TEMP) from tests.mock.zwave import ( MockNode, MockValue, MockEntityValues, value_changed) @@ -15,6 +17,7 @@ class MockLightValues(MockEntityValues): def __init__(self, **kwargs): """Initialize the mock zwave values.""" + self.dimming_duration = None self.color = None self.color_channels = None super().__init__(**kwargs) @@ -28,7 +31,7 @@ def test_get_device_detects_dimmer(mock_openzwave): device = zwave.get_device(node=node, values=values, node_config={}) assert isinstance(device, zwave.ZwaveDimmer) - assert device.supported_features == zwave.SUPPORT_ZWAVE_DIMMER + assert device.supported_features == SUPPORT_BRIGHTNESS def test_get_device_detects_colorlight(mock_openzwave): @@ -39,7 +42,7 @@ def test_get_device_detects_colorlight(mock_openzwave): device = zwave.get_device(node=node, values=values, node_config={}) assert isinstance(device, zwave.ZwaveColorLight) - assert device.supported_features == zwave.SUPPORT_ZWAVE_COLOR + assert device.supported_features == SUPPORT_BRIGHTNESS | SUPPORT_RGB_COLOR def test_get_device_detects_zw098(mock_openzwave): @@ -50,7 +53,8 @@ def test_get_device_detects_zw098(mock_openzwave): values = MockLightValues(primary=value) device = zwave.get_device(node=node, values=values, node_config={}) assert isinstance(device, zwave.ZwaveColorLight) - assert device.supported_features == zwave.SUPPORT_ZWAVE_COLORTEMP + assert device.supported_features == ( + SUPPORT_BRIGHTNESS | SUPPORT_RGB_COLOR | SUPPORT_COLOR_TEMP) def test_dimmer_turn_on(mock_openzwave): @@ -77,6 +81,57 @@ def test_dimmer_turn_on(mock_openzwave): assert value_id == value.value_id assert brightness == 46 # int(120 / 255 * 99) + with patch.object(zwave, '_LOGGER', MagicMock()) as mock_logger: + device.turn_on(**{ATTR_TRANSITION: 35}) + assert mock_logger.debug.called + assert node.set_dimmer.called + msg, entity_id = mock_logger.debug.mock_calls[0][1] + assert entity_id == device.entity_id + + +def test_dimmer_transitions(mock_openzwave): + """Test dimming transition on a dimmable Z-Wave light.""" + node = MockNode() + value = MockValue(data=0, node=node) + duration = MockValue(data=0, node=node) + values = MockLightValues(primary=value, dimming_duration=duration) + device = zwave.get_device(node=node, values=values, node_config={}) + assert device.supported_features == SUPPORT_BRIGHTNESS | SUPPORT_TRANSITION + + # Test turn_on + # Factory Default + device.turn_on() + assert duration.data == 0xFF + + # Seconds transition + device.turn_on(**{ATTR_TRANSITION: 45}) + assert duration.data == 45 + + # Minutes transition + device.turn_on(**{ATTR_TRANSITION: 245}) + assert duration.data == 0x83 + + # Clipped transition + device.turn_on(**{ATTR_TRANSITION: 10000}) + assert duration.data == 0xFE + + # Test turn_off + # Factory Default + device.turn_off() + assert duration.data == 0xFF + + # Seconds transition + device.turn_off(**{ATTR_TRANSITION: 45}) + assert duration.data == 45 + + # Minutes transition + device.turn_off(**{ATTR_TRANSITION: 245}) + assert duration.data == 0x83 + + # Clipped transition + device.turn_off(**{ATTR_TRANSITION: 10000}) + assert duration.data == 0xFE + def test_dimmer_turn_off(mock_openzwave): """Test turning off a dimmable Z-Wave light.""" From 4c7ec4932c509821963a029f0aa81a4fbd7e3d60 Mon Sep 17 00:00:00 2001 From: John Mihalic Date: Tue, 4 Apr 2017 00:54:33 -0400 Subject: [PATCH 077/116] Bump pyHik library version to support more cameras (#6921) --- homeassistant/components/binary_sensor/hikvision.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/binary_sensor/hikvision.py b/homeassistant/components/binary_sensor/hikvision.py index ac1b2657448a6e..9a7a1dcf5463ed 100644 --- a/homeassistant/components/binary_sensor/hikvision.py +++ b/homeassistant/components/binary_sensor/hikvision.py @@ -18,7 +18,7 @@ CONF_SSL, EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_START, ATTR_LAST_TRIP_TIME, CONF_CUSTOMIZE) -REQUIREMENTS = ['pyhik==0.1.1'] +REQUIREMENTS = ['pyhik==0.1.2'] _LOGGER = logging.getLogger(__name__) CONF_IGNORED = 'ignored' diff --git a/requirements_all.txt b/requirements_all.txt index f9715190e5a25a..5cac1151302b47 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -524,7 +524,7 @@ pygatt==3.0.0 pyharmony==1.0.12 # homeassistant.components.binary_sensor.hikvision -pyhik==0.1.1 +pyhik==0.1.2 # homeassistant.components.homematic pyhomematic==0.1.24 From 5b9d9954c56f8a203e207700a78a2a081af9dff7 Mon Sep 17 00:00:00 2001 From: Greg Dowling Date: Tue, 4 Apr 2017 06:44:52 +0100 Subject: [PATCH 078/116] Update vera cover refresh logic (#6897) * Update cover update logic to fix compatibility bug. Bump vera library. * Tidy. * Add missed file. --- homeassistant/components/cover/vera.py | 4 ++++ homeassistant/components/vera.py | 2 +- requirements_all.txt | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/cover/vera.py b/homeassistant/components/cover/vera.py index 48abe373eacc2d..033cea4a82800f 100644 --- a/homeassistant/components/cover/vera.py +++ b/homeassistant/components/cover/vera.py @@ -47,6 +47,7 @@ def current_cover_position(self): def set_cover_position(self, position, **kwargs): """Move the cover to a specific position.""" self.vera_device.set_level(position) + self.schedule_update_ha_state() @property def is_closed(self): @@ -60,11 +61,14 @@ def is_closed(self): def open_cover(self, **kwargs): """Open the cover.""" self.vera_device.open() + self.schedule_update_ha_state() def close_cover(self, **kwargs): """Close the cover.""" self.vera_device.close() + self.schedule_update_ha_state() def stop_cover(self, **kwargs): """Stop the cover.""" self.vera_device.stop() + self.schedule_update_ha_state() diff --git a/homeassistant/components/vera.py b/homeassistant/components/vera.py index 4d14db5b7d7cb8..555a800708c9d5 100644 --- a/homeassistant/components/vera.py +++ b/homeassistant/components/vera.py @@ -20,7 +20,7 @@ EVENT_HOMEASSISTANT_STOP) from homeassistant.helpers.entity import Entity -REQUIREMENTS = ['pyvera==0.2.24'] +REQUIREMENTS = ['pyvera==0.2.25'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 5cac1151302b47..efe8db79624293 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -648,7 +648,7 @@ pyunifi==2.0 # pyuserinput==0.1.11 # homeassistant.components.vera -pyvera==0.2.24 +pyvera==0.2.25 # homeassistant.components.notify.html5 pywebpush==0.6.1 From 3895979e390b3d52a3c5f42775202549d086fca3 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 3 Apr 2017 23:02:04 -0700 Subject: [PATCH 079/116] Update frontend --- homeassistant/components/frontend/version.py | 8 ++++---- .../frontend/www_static/frontend.html | 10 +++++----- .../frontend/www_static/frontend.html.gz | Bin 139220 -> 139452 bytes .../www_static/home-assistant-polymer | 2 +- .../components/frontend/www_static/mdi.html | 2 +- .../frontend/www_static/mdi.html.gz | Bin 194233 -> 194700 bytes .../www_static/panels/ha-panel-history.html | 2 +- .../panels/ha-panel-history.html.gz | Bin 11873 -> 11885 bytes .../www_static/panels/ha-panel-map.html | 2 +- .../www_static/panels/ha-panel-map.html.gz | Bin 43996 -> 44162 bytes .../frontend/www_static/service_worker.js | 2 +- .../frontend/www_static/service_worker.js.gz | Bin 2514 -> 2513 bytes 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/frontend/version.py b/homeassistant/components/frontend/version.py index cae324af9baf14..44563480cdb369 100644 --- a/homeassistant/components/frontend/version.py +++ b/homeassistant/components/frontend/version.py @@ -3,8 +3,8 @@ FINGERPRINTS = { "compatibility.js": "83d9c77748dafa9db49ae77d7f3d8fb0", "core.js": "5d08475f03adb5969bd31855d5ca0cfd", - "frontend.html": "53c45b837a3bcae7cfb9ef4a5919844f", - "mdi.html": "4921d26f29dc148c3e8bd5bcd8ce5822", + "frontend.html": "feaf3e9453eca239f29eb10e7645a84f", + "mdi.html": "989f02c51eba561dc32b9ecc628a84b3", "micromarkdown-js.html": "93b5ec4016f0bba585521cf4d18dec1a", "panels/ha-panel-config.html": "6dcb246cd356307a638f81c4f89bf9b3", "panels/ha-panel-dev-event.html": "1f169700c2345785855b1d7919d12326", @@ -12,9 +12,9 @@ "panels/ha-panel-dev-service.html": "0fe8e6acdccf2dc3d1ae657b2c7f2df0", "panels/ha-panel-dev-state.html": "48d37db4a1d6708314ded1d624d0f4d4", "panels/ha-panel-dev-template.html": "6f353392d68574fbc5af188bca44d0ae", - "panels/ha-panel-history.html": "bfd5f929d5aa9cefdd799ec37624efa1", + "panels/ha-panel-history.html": "6945cebe5d8075aae560d2c4246b063f", "panels/ha-panel-iframe.html": "d920f0aa3c903680f2f8795e2255daab", "panels/ha-panel-logbook.html": "a1fc2b5d739bedb9d87e4da4cd929a71", - "panels/ha-panel-map.html": "9aa065b1908089f3bb5af7fdf9485be5", + "panels/ha-panel-map.html": "e3c7a54f90dd4269d7e53cdcd96514c6", "websocket_test.html": "575de64b431fe11c3785bf96d7813450" } diff --git a/homeassistant/components/frontend/www_static/frontend.html b/homeassistant/components/frontend/www_static/frontend.html index ead35a04662dec..ce38aab68211db 100644 --- a/homeassistant/components/frontend/www_static/frontend.html +++ b/homeassistant/components/frontend/www_static/frontend.html @@ -391,7 +391,7 @@ }; window.hassUtil.computeStateName = function (stateObj) { - if (!stateObj._entityDisplay) { + if (stateObj._entityDisplay === undefined) { stateObj._entityDisplay = ( stateObj.attributes.friendly_name || window.HAWS.extractObjectId(stateObj.entity_id) @@ -419,7 +419,7 @@ window.hassUtil.computeLocationName = function (hass) { return hass.config.core.location_name; -}; \ 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 09e5808da651f875100923881edc3dc352dcd000..f41ff60ac7600e79608fd580e7832c236c02c5d9 100644 GIT binary patch delta 90864 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 z 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

S#*daM^9q4p zUS9kC8o+sW8KfcVm~c{sXpRwGeUpC&(??(3{TmG(_O4z<<>se8CCUy0ouj?EJN_NC4d@ z;A{V29{Cp-3*m)U4QFVG6|FnE3UBAh(>a5#M} zKi_;9;_nXueSLs()93;Y>c#Q7pvA)T$;Fh*$ii`;iw`j;^1s4>>QE_+FAfe!fBgj^ zXGy)H)_;vR6Fg(~DP06-&Y8k0UheOu(*?vpB`kMSlY{2e)x%79Lb+p3lWazIWg$zx1N9 zr^B(2=LQief_I#81bUvpvAoN!?y~E<+2vgYzdn7w`*eBt2{1VPlS1;<-PP3{d@Y;1 z<;(}zF$5QCyU%I6$uP8|z=3~I={QXe{k%F7sMkVk-}sS$wg#* zOMe+eatRr3@kEktLwA>FumM+qmqHW8w`pFH@Q3*Yzj8dnEkslSCZEVO`2@b1t$~A0UEGz?IhdcH z7e&qseX{X_7>1VV^@;HUA)dM~%`3*0seeloV-4et)lvQu#x=2S)X#=@B#VyMuURXN zU9(mqUb7;J$nZ0ApTxW%vC&2TrS1)>C%@pJm>;4caZihH_IJ}Pv(_wW29@dVO60Mb z*qJyLXD!TVRpD-uumb%-tJYr4Y#^oMrrw$9$f?JR^RLQq`h@-92mDg20w4CONPicl z+%8mgA`*Bn;D4bf2`!X12xGK?8x0}>QcPS&OPMHPjKXfH(@QQRI_COLIt zC8F~U%!IC=(J3IkyK4zv(T?=cV7Ilm0YiEmOoWg*Fk8`)=fBa|`4Ih1?@$(Kr!Z{G zxpfkdA)nn^3!$|s7qb@o``@Ba)PI(=TC&kf=R}xIEsK7^f9B)K-T@aqc8&IMFI?(?}ZyJO@=LSOMN>_52a2FktFYM0;A&|6_e}~gYMASyo^f5=@C;W|_ z$MYlV4LxCsKvoG)JIEE>jkt3Tl-btF6-M|)^0SstkNl16XevB9Mda75h9G zoD;~mO`Jya_#B<=D395i;i@!1bsio~cKV$qJ8g?k(?A6ML9=z~fPc3vkfPYb_uyMc zMv{*N0!5$bKsZ2I%Qpe4wz=cnsBE_Wt)OZK&Sl@sz6I-)!${t~-|imI!|_*8 z2GxD^ z)I~q$K&ksRPzZ?KW=c8aNjM(HfS=^qnBm!IA=Zr%FBh95UVkps(>3a}(S>u#&<<%Y zvG~_w3VVr~K6$9uQQc|6PSgnMpTf3N8>jg8iS3{dPh4d`g0!P4{BLb|gX&x>z;ArD z&XSz{_#~F?hNaA-&wzd}rqK!fIinG~lpYKUjzw`YQ_yZi43i0#*~jBKY5!w{N12W+d;}=PC7S56jseAMp z3heKn(7$zX5hh8E@+`P#-~-kQ^Mg+zEEbjtZbD^Z^%?pEm_DIDD=5B~tb)!-+-Gxn zeC=7X5`!4ZK@4#a^6~E_0@^kH^9=ua3vlrE_>+Kxw|@c-eob01{%P`dIyRpa+LRXD zlD`I6GP;3(!qH3kH^CW1*X$Rdre|UY@GY0`%}cp4*J@X0(K9GP_Z1t}yW|p9WDbk* zPQ2G52kG<<-qyttXw}M5(x~MmLw{DJXCifVh!^G%Ey0mWqJq=#JA6-9^oCMx<3$n$ zwlFc4c7Nal#hDYuDJ49Jl)3bVsLMsdpKmXd+j(|@zpj#7)>b_6U(^2p0M4UxdIlDM z*^`3!#^-JH>&r$U>#6_wm|vA>&j7j4eDQH@eBBsdzZqYmSxnK+HzfW9DTHRR05D>C zK%>QTSMVH~3eOo*4*NL`d4U^QV92YopR&MjT7LmOT?~sRSbxku99>~`O_ve?_I<{iiB+lXYu4S7sK zpZumpu4EQA$4FJKZ^J%r0&3E8Ga9^Scd+dUnaxdG39n`Iv1WH#S9#s%iRB9E3wd{8 z)B6v2clobw_bxzFZu4+7+T8_`=7c$CR)2bAM1aYovVY3vs5@0D<*p|(R%Du#d^JYm zhrV5@YFIo#lW7C*ij=_7vZWAyK#Wc;lSGy&O%mDXCX>WslSyJOOcHZ$lE@&bh6&lm zrlWRJvXlKO2O@MC>71Xk!%^!`S}|N;Q1%^msZy-u%1qiut7;IY(W*6;4x?48lz(ot zN+)z>4?W^xKiY2vT}TQ(c7roJA_|+j)|d>lwPg!r89R^8(i7 z=9c`4u>}lB5U^JW3x_Xwj&;4S|9@}8M)3%;83mAXdCI4H8V(@Tyk55gvAOLfasLE@ z9_5yyUXGy>ftsr3hSeqo9nwv57|lB_0k&edeNqu})s9W}XS*Ax39(e5s~qXRl9;u; z8a2SwRbFQ}dbE#-b}NfGOS2G@27WEa0b49Gx!$v@E#0QA(>mA+UfJG}mVZ$ix4c5j z+>Y7l?Pn^adi{^QxfErRu8fUgnRu7xGPZ}^cE7M`)9ht#&A4+!%5BPC(l{OKs6-m6 zX;~=GiES>($PXonbJ_*wnqA;OvNJWe*V%Q$jLY$q*((<5=ZpJiaF?^)pJ*F_M%3)~ zQm(F87+!8MR~kl#&f)2xj(^^$%We}y^v%f06>F&ktm_7ODP2M=kR_6EkS6fHAacbG z7WtxW)4(NrU%eUfiChWjQ!qZK6ylcCANgqTyqR|jk zr>jA;WS3_HeUwpVdFnC|1n_+G8{Qs31dDDTu$jRvKbC%c@L;^t3d_OkEeHd_SUQtZ zWH21-a`7oM+t3T@UVnqyP1@c=b{+GNX8E9_9W`=^p0O!o=&h!V!cEHsTE`3w7&7<9 zv82M|h}9@L+UkP1uB%Kz7$HU;hzN-2y*&#;M{vk{WF0<# z`^rxPKD%!z4I3V89^ZS8*k0~58$xCenhMq2HUm{CH0}V-6bdgefFjeY<$|scyNTzk zx+$;pC5RA?hMEsa)Ayk8?uVgBP5(Sa%yX)7i+rs_o_P@)m_0^d1iHNtJ z?BF1D+*hSbuXOJMJf=aIIbfW24l}U7Iaz zw=E~+dDsCk!rw<>ovjw?HoZd@;tUwHy*WLZ9JwK|_>vIl06nWe%MBQpM3{(U+_cZX z?zq+A2c+S>=zbgW^KYL6A}|2XAhw%Mf-5e_tC2KD~SvI0C;t z`{B*I6D{D|voqjNn9onth|pm&GUz?a|LtZ{v11X!I56WhDjrHKq=)QnUS;0@m3~U! z&#HXch&)eXHFQuaVpQPX69u_#<4rR2588EumVe)I%XJ=M>wb3?{{5RRSd+ain{Bc* zu8IFq+bn!EcA^UD#gRFXmgSq4q)<88cf4yfW7F%Icw?gn0A18;;PAK+qZA~6_b6Ej zF-l(EIZFQE^u_`DY@7Qg7w+a2z1f-j28heLJh{8umn3q>9C3zb`L$%koLp4ay#j7$*Bx7F z3+P%RWy|Bf(+``vgf^6RTtjmI;qLmJ=6}t51%Wz|;#@M#tj^d3Ic{^gHb6{=e{J`I zxgumpsb^Q94{cF7fq$+;ML`)Zzl`8fCkyE^pb}@uw+xYIU`d zb#n})%d7RqYh%+P<_+$$L$atkx{Xr+(mnhw?zQ=A?8vR=5afwDApNqw|B@M5@|#3;;6g5lC2t8kls9a|95xDm$^4x-%|2{D3_BqWFwrgmds!|phVMSmDo=%q2@uEhatSdf_t-3@HS8|$_7K>JLS(#qfH z0yNte$B`of3LWi^C!HDoeUynk1_>CgB#hp!`t@ag-T+8ivP}vgxHpiFk+|<8Tg0bJ ziMV0zPBQH+l59&p=#&bUfguf~m}hL!e_kyb6BDWSCR3N=J^@0Ld^#%dW`9F)8IvE|AVJ-sCw8N}eB-p6ml^FB0AE0$zZkRJ#%E8O9%=fsjmQiSiWoav)Msy=U137e zkBsKb$${(YFLzo;hWhi*X6=l6qBXU zoQM?&s)*CMMj08Pj?k#fKjt_<1q2n`n?0&n`^f@(Kj{s=Q-QtB5`FPdqr!ZPImxNa zB^H6pIPT75!6oE<{ZZ9oDJC}G5Or2xQxy{i9YMj*HUwD8NTk={P(*Tx0=j?ZGVaXj zp1;7qLOQ|LRhV9NbS}pmgl$cU_gT}x63DhZG)!ar%<1WVcDqz=ggR4}g%N2lZk~m(%7Ke~TNEZ^MqmAt_e}bZviCmwJEVlj+EoWEg`G z&trWpLR=%CGhv+uNwSiBf?J2KlJ2G(0TMHzGHYu~k2WdKMZR6!p*xq+oh`mTp}Mts zjCRqH<-GQc?;ydn3`eXY7zd<6(N%0$h1{rF1OM&RHc9N`6?JNN8+x`5!vcPnaEVar7+JD2Gw zWg3kX-NEU{e3ytd=twJbEm5PytH$fA-y6YHXxSkp<)9d`iltuVX}fE zq_&8Ef(&SU1qtamM|-SDOfrn|TYN=XTMYv$!wRfNGehqynpyCM36>IVd2oP)i&SZy zMMW@^`qAWmnRI`z9a^WV@wT0TVjl%&xhKh4uKZ9NY2~~fwTdsrk#Uag@$DS;auBP_} zBSiOtW#NfKr7vsCc9m>?)Qm#4kbTD@I#$qLz6c?K_dfc)9GQg8*c8O-{Dc-z$06=& zNXo(w0^_nz0p=_jv=vV#8~e}G0y#01loxX^1(KL=iU!j2pg zkD?%@Of2MtElVQiv9YvXUPUcP(w?)l&Tb^7k*|NYC$_qqnh-*Ujp)$H=-9lJ7_ zGDid#OPyY1ajyKHIEKO%yrr;?Q7kx?*vwcJOn6FpBO7morVRi+uF%3c!T|HN599$L zZ=(@k#N8?kcVgC=4p>$5`erFh%xbQ~WH9A1FR*_N^uu)jCR{~&L(y(akf0s!o%ndk zu@%Rzo*1C1XJ9q1V#?YNLc>%_mr`r^YmAJt_8njxlNb|C^hoLV;Qb>flGX4aXQmio z7ibtVj5Zo6bu|b#gn_4k{c?uJ9E_Y>>~gx$VB81_BdCQN09aNWk+yJOU~10R{)l-c z+I)X7h2Ft&TH93Yla?ND#ElusHYuGbg9nOkW3Umqu52civkebm8H*E^cfLQx15)S6 z`*z&=pdz1DonZ+Lnmc4sQ6EGFS7Fo}VpK^+1}pPn^ctOSeBajJuzP5(y=Ag8m`{{$ zc>aiFP)7WvNdZ$SE>FtHp?#e?ML^c3GpTYE7dJrq2Df<~qscp9m7biLADv~FmzIJ7 zH32=B%z^#m{L06)JlD5K4nT zm9vj9Md7E#y8IVLZas0Ps_Ph_ho!x$S&!Iy*49oil~>Fm7_KKJ8O{P62>)`z!0a-u zpTmjI=Bytv3B(L`iC>C^RR%EE0!`I`jAoi@dqTT`e_RgEPpT}#PzovBAqeZaBDhOwnB=LTy|8tyaibANLX~*BVcg0pQz#WX{~1A$SAKWgWdL5Y^61MGd>M z7-QEwl{u?xiYO@;R7=O~bdA^UIgT108#Qp3BzGjWhY z#aSbjzDNYVnv;`|K3ome&3nKjsGt69u?T#uiyp8;9*%4wsPcn@k`z7)qm2bdB}0MW ziyYDB8NLy`2F#04&mw^qs)0)JkIr*nU_4NLf6ST$ptd1`ySQnYvuVzr1WeVJj2S0!APzq5@OZ+`w6 zf16>I9^OuaTS8A|zq1X*rJI{rN1Yf--&EO=OPTS0OYdyq{;Th7=3yJ)Z0i1d(A~^V z+u%ObaXXZ*h4QMh@^~ve$H!ofahjmyG?t_vM zieh0~pz!Y~Ugg0u=Gsjm}XPvde0fBKOw zmAkt|sAQ2OV@S{HU;zZ8{Ak3L+4h87k=J92fG}Ph55`rWjrycqJ{`o`*RlBhw~Phh z=+728EIs>-8?Ek7*?FT?#!p%M9~eeMR;Dk_{d#0VSj#`r0=>i{JjIOwECyEM`(G4| z%V&8$d8Ah1)CnuS(6Sc1k)+r3f3?hrr~k`L|Ceehz0PZ^i6Ke%F=LEl0kUBMoSAIt z$dxS{bYAR*>tdJv@f*HZ@EczC#IJgu@h<^T3-YC>SWLhSy{mG*LRG$b;^)96_U4>T z^u4sMvj(w7;`jT9XBZTL5k>_Pw}(dQL;vY(yx%d&26e}&)k_#D0G zum8j;I2LlE^5U2$JbiR4jzWy5!!9YzLW>J`oy&Ya&x$onjygY{=bva&W-BmEo}g#? z_@scc0lzOM)Du}xj}Jv}$A{1;{HslL3y*HdI?UyD2|AEXM{*NjpE+&OGoB5HH~*d8 z)ItDaWWIrASfn?tJVSKye{NO4Ev5u0OX);6zP&7~{5Pa@7tb)3Ow8U&c#KM>FvBD4 zRM|PM)k*oR;UsmuH&{m^7EO0`idoZ98wR4r$>b}%4JNoHxqh8(E^-cccg-$OE2k(m z3k;U^Ls>4ewBUn7B0gOJ9KBgJbw1}LM`uxX@4qRYr%O0kX6YX}e=M}sj12awG%IUl zF>3cOILQH{^$XZTB_ZoEvnD_GPcdATw!O?U+=sD*p{dJkkrWl+d3tQ&+|;DcOpgwN8!D3VhY)=cf0de+D zPvYj@sMBO;CC<^aNdditw}rDu#!l+0@tY~wx=l-4U>rtUrG|Z5t|P4HPw^aQ^XHf7 zT%$c$mdh7rp4UkG&Bxk2f-nv`rsZ^;$R)8Nw@$^NB%t#wf7bIj*uY}#vNDXwZ6k{P z{q1XJ%K5lPTpax8wkzCpgS>((u5WH_z zW5e#8oAdf;f1TM4gXS(b+vDb^P4`RkPFw9j$j0?7HrRj-%)D3aA+^t+@;hSU>-~Ms zoLTsUDLuODgk89Qlh0n(7FE#|Ud2Q!(nV?ECX^GjP?l3rQwtuDUkqZx>K5xPs@S*o zJ-4kA77{2~>r1|3cLzq0eaa$d<@`pahwZ`a+A0=ye>O{_WvAA$+&ix84(pg$>k;j; zjEOy89rt%GUw2pCYt!nfYY(~`w-&WM_O`oaPLVqlZ%Q|96QOL!^vU050#KPUGzz)+ z04n8D2y27{C@DuS^qkycpK(|3jOmCw`(4Xru;}X+%F63!oMzR`OUiwoWc}oF5O-+wW)=aR&9ij%*af7TwLzr-=qzUe~{_}L6 z_44A2J@)59n?JwTV}GVU_78S_?9Zk5CH}C#-lEw+vn^N6|6tvQ!Diitdrfzl0&UO( z$XN9*s`4|BoBKyi9&ksFT;mT&5W~oylO*vSf6kYpfAm@R_gN!WBQ6e)4*cacu9HY% z-}hLlXyeLI5aIvW!cgz`Sr@9HFAGoja;s8bR(bL9|Il@@R;33EHTdF7^FQM-VF=Wv zu|ze7Fv&=;D^)7d3cCXZKnL7~OZ@D+C?h38eapt$rS9yvVzetA9OVaVgb z=zp;ry4P!U7_O=LU?RjV)9`k-s_L>LDf?(vF5oAC15_48dK7D%a>5Nw%ktsc5N+RX zs=~{J>z1TlRjV&k$mnH@>=P4t9?h4be`76pPIxM=JPy+#6y7{=y#}O|!br)_Jo- zty!Mb8(Ljq*Xutua8xg{O2Edl%u#os{hY$f`5w%?NtcjNUR*3P?Omn)lp^Z1f1gqe zxS{sd^AjUt6aV&>{aUYmP3+8*q37#MeXkC>g z;x_wYVsE1}Rm_x@W1*t#l|*DOF~2Ao#l6HVoSi1#XZRXRIT#WwPmGAOf{R7roon%A zsDCB5!UDt-^tjnB@E&U!M~P#@@;rwa zi#G*HeP|Vm9svVerJEiT*x>%3o|c8iq&(*tK7&b;Mk%n-p6!1BJD&la_j>o^y1CC@ zzxw&v$*VW7PoMwt!>i|~KfL^ZUcG!5`?J*KfgTv`F;HDV6cv)u1Jea;I~oNlj6pgL;bzcd=g~GuHy|XVhk*r(~IXOe38=S z#c)aghhG)-Gi}a89~wKQJf8=rXN?ckEY(nUEH2Nu-SJLukuYEsU=g%-7NRrtrXbS@ zv?K2-x9xGY>!osX%M9The~de$qvBgKs)cK25XlI5M*yopp0TQ1nV$^}4WA66EUhs+ z>${IqcSmiKdDD>p{A7Di)AbII&^s-qB^8hZ(?Tq9?5uJJ`TQpNLXY5##OioW9V_Xicvry;lqr&I z)2=0mb}mEwO5TLB8WVc9-+^R7-Wk2rsHwLt7jz^hM3z=niMv{rE#$@}n_7MMOLKML0B!h32}AmCafyEhbo2v}H)wd)C2pn@nWL3kf7bNsPZu6yw8Y*dL~TF< z=D$JK(YHYHK}nz@v-A4t@deR|X@z$OR_GBE^7I&I=|RrVfA)rh#S;(yulM9Pq!uv; z{#@WtsEI>r?$91fhZw;a6|%e)Fy6#$)jNt6j23>kV1amk;)Y_R$VNRDAsm^!-X&ZE z3%UvzS55L2f9{B2=W?8N&e0UKC!Q|&cWmqNjXq!I4X_!@be6?MiRO-MgtA<=Smet( zuYr}lW>+HKd|!{w%Ih9etckgN08&O4TWj<4#!|XOCY#D@au8mzfNnklU(N~xye=1+ z+=l`-Q5Ebh(z9&QgDItrT?4uE?}0gQB@R*6fx8qBe@2|GM|n_10xiiY6S5-{4Ke^wpo1l3 z^#!k^-T5B=<2-M%eV=>v>ij&vh9%K2YPry~v_kyzd*ny0L;G;8aTluU67(>P&{iGq z)G5cP>YNUC3WxrVz?3!!FK)H*7TlOJ8YLt`XnX_ENIaZg%VeKBDlqnMm!=o3K~N+S ze*w5wjt;U`mQ(trI+b#;4brcBaKJjecS+njgk1K4+R(=if~Q?1c0_0Ry9(zvi{b9U z`WtLIkekGMpQP9Wuoge$^mvIJ{A%gZX^)vQXq45nm@7|q$p_#PJ1c=u6e0qA8xx)z zpdF;yx}^t(zP%3H925dQ4K?Lm`r~>ue;$KD9Z_rvy$NYJoHg&Yhfb$7?St_qk8d`k91%)kqt3ononzrx7SzKmwxfBYTK zhVl|-&63c82vXWXq`B<>vvKd+_ha!3w8MkQ1YZbt^-TK=7fAneD3daM;&yW zH(3g32Z2kt*f~St>7quyrT=0r!^+lmQuky6K#9$=`9(GZNjB66iYWY%6&t0oQz7lt_JNhDS66r|Zhs{rthi>C&eHisc1toj_9moh4U$@-LpEihS6+kO zDxN%sD%uXpE{k-<9csmd0MzJD>LJ!JDpW#FFPN%=XAs6h{&*{w zo0S1be^@(W<^fiNmmkJDb{}^aM0Ww6=~4pL$nwLG7ccU3QC@V4pTwN4dgi8?q9!GP zGfPQ19P`1cZ*1%cXTq&JanQds`J&$f2IQlyEp@fiIJQeYllN(Yp*^D(8w~CFK8w66 zyax0oJk(mGcpNW9&wLMyfQ}G-b3^!|oC?D4f0q4-n+V_)?upZU9-FPp^feCCJXNvj zk=Dwk*ZwXuAtDst;WQ;}d8Ods_PPg0$H|IAMYx?c9lVGDXmo9WJ_l;y%4EB zxjWQk(OM0sOOAl*L>>$t{z>T*NxOJ|8BWCOqOX?XC#zH@zfp%F_@n? zCR|6BdLm*c2pVl3s)A{80x8GCadsFCwIT7i`jSdX zmDxReFJrQ)#hl6}%mX!si`SE5u0KOHfA9oLQ_;375@U3MCd?xk2mnMMspV&B+5q9u zZDFdG+@JQ2^qDBWBeB4_l%oOK6*%Z-%R$qQOv<0cD4q*V5u2eB1(Ys{!$!o>PDI!k zs6YS>+zu{yaj<-{2f^|I$A=A)fI&DZkN#9=FoLwFPH@(M$fzVFrlU7cS{u)BBH5*r%)&y^*(hn~NL>R~AH?fh2_E;lVDV6JJOKO)o zXX+>z^#|YA;phuA;TR3mdF_c~yR}8DJgUcL#@N10gRXTW1>mhS#!}J1TCe+6-Q^g# zx!V?a^h$bMAr8Z1{Ml$@W~+s`e+I;u{WBPZBUjqze6i@wh{94}*P6iA1ID63I8Ikq z^q%1Ha;(6%Hf0TWvqN=iHMxj)@1aWpN#`7H*c2Rn-G5TDw@tG%P!b@2qu2HnO`Le! z2}JZX-3diTu4qGQ9>qoREe|};u)X@`IsK@uOe{=5z`1U9oz!F6L@5A+9?$aL|;^y^o*IECsE#R~}80`i= z+rj2{fy*vnvI}_J2P}34hlhf}eYStsZEsmtw-^Cm<+Uzh-(w8aSEPb_i3(p}S_(R*_k}V`6g<;SW znU0|)ui#A3mb>(-e|Q)_dnkc>*c4FDUT|aBQH_yHvbJC-!?+=>)GFlRZe6093_}XK zGAa@7k<_+ys18yY-nDB=ZSdG$$6f{zM7Gsdl8KC#Iu*fSQGWI@_}a!oSLper-c~3@ z&n?^R=DL~?bpS#wB{6K#i4|RXY#96}+wSLx$Wvw8Q!rY?-*Mo)8QizkVpRgL3gnv(P?3{(Bhm0GtG+okSl{^ew+ z4L*{soXM(sl65=-py~a2fW++H|K6bY2Me{qOAjhx6kLTRU|6(MyX)_-D!m2kE#_|=qGcxO14;4wg^cfeV)&7%uL zEP5Q1?$w@iH9=idNaAAy?e03inZ-)al$I`(+#Y2)uR0uv^CL-fSuG{fDflhjt< zv1Zm5R46a9Yr7B^YDLzfIAmSjnkqB{ev`tldo6|Ol>a3l#PlRd@RZ{ z$DZ;vXV{^ICwm0;y?dN=Hs1%}=m%r>wf4;P)R?V}b-o{5374sy0Z0OSV3+fp0Wbki zmn5A5J{(vf`0o^kr{66&_r!k#$J1j~qTW={`}WB^y9k$lodG3(d&7wi(GEbwe%UeI zx#u0XP#1~^!#^*tqaOadbuYW>?FiT=k%F3p0aru1CxCw^0sQfi1>l+~0e`RS+yc^z z<}}Iq`FS{EiqiRS8N0~3Fkbfo=z#e9Y$RKwPGoB|-QKkgrR2e5ZcNznJ;8a}-f6Zt zvuUkx%i)aPQJcYkltz`e4uW|tbHB*NA;k&C?Qb(EyIdf)T(6@U5M^-e)gj%~Qx1f%8*cypcSVFLuCqak`Hf#qU9D2p;aW;c8@sDuB`ZeGxa z*iLr*mfIT*5_U0Y;_o33@;bc9@eH$vDn7E{GtTONo8FP}5N&l@ypEQ6u|uidUZvg6 zkXv zGJMg2r?mvkLoAyt!_M>`?S!nhe_npj##&Q|k%eWAib3pd*y+iwvWj&M^3?YS!0`Vnl00QsU6I$}~?<%wg9!hx)wMLy(&yG`QfAnUJ!*9GDNd~!RqM}rGrJ5NMu3qB zZqJP!Z)a(p`7|9rmMSWiAl{l^iNq70+dKdlmk*R*_~57F*0(%N(Y!solEZud|b7iF0qQYlKz5zT|gjfM6`gwT4 z)A;#fi`HHOQI-2;vbI1o#*>DCG*HVFkY=SeczzuUB_?wX4zdvoF}34)V@(|LRS7lC zDC_*@Y^-&%%W-^UuCm&%QR@iREQpl*9EoKGSnDtzY@hhirp*+Qb2snjP=%s@ke4FFwC@f4z+jj6Bso<340*&*@_dbIo&F`09q$@C4 zo&*vMuX_x^h5~@1T06=LmQEyHiigE@+Y3Tr&Tk>(5{m2viN1qYYVHe;b*A~|(|Z$J znbtSOEN~MHayxce<`$D|nP&5UU_MD3JUd4ysWHJm*aR6MeStlovY>n?Q=$E++w$hU z%rN3jpEhv2rHSsVPPBlb;E3uEQo6E$%e!Ejs9Ei@SJwT>HzBOvq5*Qj<)ChoP1j-n z*Ah^g?-8II!mu_^!9)M)BM5G#?yuqSjyOmbrW@#e#&)s^6QhB$$=GoNLXQ)d8>0bE z0r!_`qX9@BOly%K=~OmUPU3QXnxq-~(q*bq3|;WzLIDz3KirqlqX8ZwEAG_Ua5$t3 zzHapgH}d}F@+haYnLMez>oN5uUpT?Zi}RNdqyZiQx0f%Z0UHNH>`A(|{g0PXqyZg& zTlt-B8moeSeu=S)1SV7&n(rB8<065%-6hg%As0aia24TV8rS~2B|m$KXvg8RCfw$< zhHtWPT0<@R5%&$FI{BTxYhY2cExv2Iu@K$mr-m#&QWO^0Vr`mJ7jXXz5?mqq?t zru8#v(vM=MQ)AlSq7yPDl6ugn%-X`i?SB-N>yKTSY`%ZVb@4rIVd(W}kAWqfH!-af zD2ZKA{05%McY)Nhp{_RiC{`KnhUr*nkJUe;$KA!l0*a`B& zk-tolK=G%Mbrl$A?~n2|Cg*Bi5#06HoP5ROueYLHfSpI4bnm8l9Ft{q>oUd2AmhXR zj{S^NW5r(*5~G4U;-q?(0kQR;B#C$kAtRO#qqpU;=OMo>u?qv*#zT{tlolh#wjF;?Jw zFnus^iGBSt2+s}$B_ct8eKA+RR%Dlw05tFq;e4ix zLx$Z?SNWkfN&lcZ@cWm|)xwW73Da8tz~H(tr#^*m3;dV($6G*u$G|>%U)SDwRbF|U zI{CWhJv8Kef?m$`3F}W^X~Y9J)fkBjU$OjEk$y_^1-@9Iljcl#WcFoer<8Jvoxw_a zx=d{x)QKTub5#;gjgF-a>M)G!#0Fxj`y8sCz?R~RT^QL#cpNq!PwE$X>tk}d$R{qm z_x#zr7qA294d$1BC4kuT6a#cc49FSl*sz)EXx;B`!>AA0$>E_${G zwXpn_R`wK`gGtAPQ8=1GlYGkx4BW>E0Bv8hbR}RGqV}+j;J1mnM7L3jr5h~6?in>%RIUzVT$igiwC-ujq0@~T5OcVf|4 z=B2DPvjcOD;*?mqEiQ4 zou5H4XLB+7;0|>#dahPuuj#{Y=6vs0BZ|4Shq`xfV^wWG51 z7kS(rZCwQG`f46$cs)fHKCs{+KM(dA7=3nk=QD#NrhcH`(JaCh6o8o`u_v$m^88#& z;O_1Bh9khm0j__q*42M%7}9 z)~P8B!{|dMZ?s-5guerfOE2zYb?q$jThkK`hPf9J9dFH`T0F8AKph;Ah2?wRdIZa^ z^cXeYw;k>n%ooR79y?cw|Bq||$2Rl+2LJ4tm{&!E+i>fUP-UK7m54%5N{Tz|7z^C%Ib1e&9d5SN)MyKlKNvd?;o!gyHDkKkqhP$;Hqhsb$ob;BkReb_4D!& z+DDC~9`6G{%bd6e9AFK{n=z5t=0n?k#a4fZkO(bR#els2y-mY;SpiWG=%U1Q=<38w z@c=znVt1&2)und(J*;;Cvh)0cJE=HqvFuNu^L!kKxwQA4x8|;{-OV$>+jy$j7hc%j zwy8Ro-Kccm5nX1BrE9YFN1W!>s(|~#1ElR?L2XmF92C4+{+7?PR|*RG>1R5=q|<-p z5lcrFv-(T`jy%EvPmP)NZ_=v;KiOVd%!P#@G?nr4I%XFo56MJJ2Ad9H>!&(7fzddq)3(ga=O?Zdh?B`!onyiP=Ixc_&HJ;l5`ZynOm zaAayg-{ke1^Yd>a&t5OjGvnpxVkZyC8t)sRSiYea!%?fvSMx>ophk17*wyOK_;9{^ zvl`u%*QcM##p)_My}~xSI(SP80}mQF(>3TE`dg-y@UW(N-R@jAn{9Jr9l@ZkB zsd1^7c|eGJy`g(F436HDiW%v#J!l~~G%m7F*}{9|4F>~vZ@4VNL~c_@VnW=0MZlYP zcjt)|T8+@#-{(cY;c774ZsC6$yhggl+gXdN`p-|(W@7`PdwM)D>3wFn1-8V%yaTZ! z!3!wchy8~Zdvf1VXXb_Ek+!#|O*9O>L)@`JsL$%~k(brLM>N8L30lgZ<;~~3&b&v5 z_P(x`D92{IvT@p-h@`GP%vdyjvf5s`nvuD{=@ z>$g?*DKA$w*&u$&CI4=x?q6ru&6n=_@zG9QpFq=ZiZ40kqwja`cr$r%&z_H-?6%s7 z|LD^Af_*<39^C`RS&;MkORoCh=-Ztq|3v}(@%N676~fDkt@ut;75yEALxW;axYKl+ zca!i{lY&X2zGLZheN=zv2=jA!xe~!8(svy@FtETyGTveBWeZp(tw}~xsW!1BWnKf5sduV%`*Md~ zc?%<1fBj$LueBS{s(Z0rji<}yDRNW0Z>p%l`_O^-8=a2j+#P?)5H5k1D^Y|f zgg_09`#4Z4SKlag=2IehzX|!EBDN-lxOsMH1fuyw}VS4KcoZ8Vee7fT_=WEDBM9RTFxQS&8cXyDVOwSr8li*kq)<(C%O@yX3aTh zzKXR_1mb^b44eD}5PgICM)`rp^0bzq2LsGm&7mU3cd97e4KP;nPoys8!fJ?-bS zLrSR+aYIk_JwH9W=r4;4!|6EFPl%yw_N&t&x%mtzhRo;Q!+WwvGAgk~`uuT0TC;Q& z{Qi5j*iZXxF*dr#RnanJ6pe>%@#tP_PVh;?)AxV1T&6RWU&Ee``0scq=bhI*xD&*z zME*dVZo0%~+}c7c&*dz*a~Rq&dwNdwvHj7lsxaLEn&V z(B3&_ZSp&w)7FB7>q%aG%Ih4Rn%>fne1U(f$gV~;X@?PnuHg3roiE`MMcPQVoc|Ku zVhZK#r$Y~ppV6(#=2{gx&0CFFHyNs)Ri>G$<&~KGNa$u@Meqp2GppdOgd;1m(olgp z`RwpHRL0^nmQGA>sYT$l-3D7)D0B+BnwZN*Mft5&@Z{m|#J`&7@e;Wqr9ya_7W02a zcA^+1RJ7&b(wYM1|G(|Mi+bBgk|z2p6uMdslt7x4Ew_s_q;c7!efu=~VEZH|BJzF#2+FSBIkP)8T_q;+5*ZnJi;Vb#X~+D%sItWc z4@9RhmNl4JMG*C>ozUt-zU+(pqfLL6?&$2(5+hM!Du{7n+3C`!o24=ih|&$zx`fJs zBOwep;gVlJo0sn6nZq-yL!HZQ*DbTU&b_mSp&)PbjYA+cqBQs!k{ z^*^FX0^E)4n%^z6;w>B?kI^phA%eQSLzVXq)ycZ`_i#qnuuWuT3fW}o${T-g>7+(G zBY#WH5~@`x0Vhoelx&fGOr3Oro8ph7i{`upXXJv8u-Cnxtu~XEZv({I6<|mXX*0#X!=*xVD`u0hA6lTf1oZaBPcEHHx2-jh7{Pr(F6la67KrfZV?!-6jxX*Ev z)K-6tSF|L+TU)SKV$fWwgWP{!5?NbuvsgfSwVENmUq-*zS}(OSTQq0@IFTmqLf2Z=GPf)Z_|9fyE|KC>FSgvg!X5*K!T`tJh#@_OdwWm>aeFq zA~HV69!H$?lH=}fW}bS_KMGB-L0TpWjkDnccH|frD3};wi!{e0AdG)g?avWLoL;95 zU<$FG^Q_VW@WOI`q9zj%D4lq zYlbFfF?C$?IYDxE9ASSI#&h%7PJ#Ph3!aJYQPGNLQd8LN=3S(TNHK#HRrIoQ#E!H0 zXE0_*mAYKw@ClO{Hqz#hYn4E?ybky)7^5(cgRkj9s*X0@eDamZYY#u78vPv8t-4K~ z5iQ7B-oxXzov#qwzlEGe+If)~bI1Izb`4XLT^qV^RFK zsw|do^7kt^LkbASU`*B=8D< zT`h!juSy|zUMGWM>qFi4x3M`x z1YZ!_beX?Rm*ab^nMl=#sTQ8lDchs*8U2Szrbi|tm z(OxixHV~03PjrDp5U%_}8^0W;M{;%^@30R$VJ=Nh4ZgokXR9(ggaZzD_3C{rb2dWE z9X(NxpFw}q^3Y3rfBd7U@sEG(!O0mqi?`9d>T$-;(JE7oTY#A8$qM?jAkhq3q)MWx_mKPjY4UklY*1jsv}8LClE7^-b1b z3?>7KZ@M;dOqvK9#Dh1Co4ix-2T|Msh}jy&6NZ1wE-MAWTHT!xq9hKAsPyw^nFE#R zlbT;(ek$h~dYi%O{XM-sg}Dq3!pbH&P7n0%uzMteX;89OAD?wjItPM(d6h4?46!U` zbL^aM){w5qjMOsI_otG>^hbeI<(3uJ%9mxozAX8V+GNstKOMN zzl-Wb^TmNJigJ~5M}e`3W295{M~!WbEkc(!)fH5T4{&!qf`h0z8jKSqw ze9UlJYK4&+AC1W(P21vl(nj189yg<9Dk(W*QZaP2CQW~lRx@< z1*`v&=uu*3i9zDl7i5supjI#0rHh1Jbk+2DbzZiJ>0h30|q^X zz`6GrFtC0|&8}}26k%-{Na|oxNY>^UF-jq0)FR z*D@Lsb^gYF)Sft)XJ|t;r6CEn@4bRcS z|Dfdz^{RFBSv}L(7an6T%#L8oUM_MtY{fw|K08+`8fPy0bw2fx5spK59ddsnb0`H$ zrcT#Uk|h1n8XE@=nA6Cw6Y{`q_@_Kjt3a z#Vji?xMA?oe>-{i)1aae#2d>hrYrb9WR@J%=AgeLx>>Ty3ww%j25`5PPaw%x+gRrv zwqq-NtxdqU=i_^v*hmw8DtLdf%-IDSw=7>F7n{Kc4CJ>z5I_wgci==6lPsMbovBWT4LUc9+Zp>13y1k|!AS0ti?5(Ixs#tznJ!fh~a zERO?`t!Rrlhr@p|oYc=#4%srP_x2*YsxUpP&+&|v;cHP8(@&!o3Eu|}yn#$FuPE9Zf4kz-B8nPWB5tiM z%;s6X{9AxfEs>8>Vs*vEOFNS1dDEk z8c#A1l5b2r`V95)#VSkT{($z6`v)-@+Q!`MD?n4eAZ7>R;5+=A8%FLQz>wX*Y(O-< zaUl8;tS1zS?v$!I{YIM?P@$vlMuFHS;KCBH?a1G_iGIwo; z8QQp&A=j1#hiQKd+?`D~iLn5z=XrIVR~2HR9=1jVCAmU0PTH&&?#&xiq>@=78|WXHq|{``zreGJFLhh{3)sCyt*|)du#=yqQQUVOtUXXEVWB{3H=7*f`1E$@kjP= zB`ffS)z5Z2HW57(`C;s}qV1}&Ca}!DZUNmv;YdU=)>lHC$bQ-vN=)mKWRE)PGO>iL z6L&|WMkykJJR69`hJeEQsJ#?4HZn{v)(p++Bz%$LPdeAv`aX&emE}HWEG#YDNfs;ChzqJC-UZ=~JsIwJp&5-K8Kyl-glyDm`QvsCY$s$^_Ef{tg*p1Th zlUTPS9zTv7PGI9<%&-6BCvaFw?iHL|xf*}>_lJ!I`=bMHrniDhs+(dwin-d8JhmZu zKTa3v>Uzq352nks$QD3Ll@*8+eGtQmCSBc4`R}K&*(a@-xf9=RTXn*fJJ!(X8o}-P zoc5U)?^`Is(#jh9^cyp7H|t%;AM@;!_mkcv_Mi<+pYa&c*{hJ#Cvd3YzgExUo=$&H z+|ww)bFEgF8KJp|E3~A6YkMxP*+WXBJUfbG)S1rc^*+VRj%C$4KfAH60mu z!gw^)4x1*WNM{+{D~vs5u{k7-%`C|#v*!z;d716)kwwPhYUKP9=ZC@sG>+CZ0`(1l=z%c|$V)DDhu6$uQ2m^On&G z$FXRF9?!k}DC94HS(1h~Q7lu2ySsC- z6+xd^VKxVru{i9F0|A#E2q7*F{OjWLXOKl$O1zYJXaKvV?rAkFM-f|*X7Msnh{W@M zUoOGzeUnE@jHiHqJJOr#pNZ`tild$@JChx9`@>G~_CgAO3p6UO&FSBXsBrm*R`$ejQ)qzwY2) z6HmKu1M}ae-87r>KulG*3@woi!BwTf{O=?1>D3Sm)LBGrv=Jm6<)-q zbg-eMECZ%x5oxj5tXRQoqaaKy9*n@qcEupOtCmTmkHKYD|3ykNNO%afMH8%lTcLgH z1CUvJulBA4rx0krX0+aQp;by=qGYuB;i{IC7K?6BeJv3?C|!6iTRg}GKV%2^4_ATJ>HErzD1i>dLOF+D zdHtv)dY|fU&UWym8@$HO;3%elEa{5mUcglY{=H>>g!p1;{&6cqv% z9?B#jfZxL3@@TG=W(R*3vK3WK*qWvP!>txh0T`_YIYow@@}Zsv8lKU}YNn%! z+umgL?yQza-t8qm1vO4x9GTWRFFvU^?j*oMeeNo(R2)@L)=2Ar2(F;|X-;Rlbs-A1 zMllMR`oa|J?22?E!}@5tC-s5+)cHmaAEuh>$BvRi_aV^(@?X|2NQMHY+D^P(Ry4@= ze;MxR;;7`!5JbMccYlt0_4yJx0C6~kMI6}I(_x-?Th1|FwnSP8-kW#n&O0qA2-i%?OF=m8Ap2);MPEk1rAY# zhNpCpXb#WE4-{4gRU_Lu|4Jul_N)-JDKWIFr!Cr%5xuNi(qq-+7@{3JCCCFE9l`bO z)^G9VR`*6LBP-Gbe1miPOO;cWrs-#fjneioOB1AK#0H0d``=_nbN(^+dwr7(TD;fY zflM0G9gmFb|5#MX+2i3behUBl4*oaV9}dr*i;;2Lx=!oa6}e`HL3j;^Qug4`qo9k+ z+bB>bD`=zeh6mXU8;FYH%rKcp&em|<^Yj$SZBT_WABc@@DaS-T*?odl&8;#J%q;Yq zE$(HE8(Fn~j)&ZNNz9JqEnL#z^KCea>pr(RVv|Ulo@=;R6{rubd+pzBMM|&B%F%fNWbAlx@jN&3uDCrEUfK#)K(`48$ zMaP(oz9{l*nqSBBB#$-qwlI&>D!WNm{bF)+2vT)_q*a>?$Bk7cNsih=Epry$#ATeu zP)Q`bCuE5qR)qMYOAs1zpzjEWXK=3w9!GBs!BM9<4;=<9RmR)K1tj|X8CT{>wv!}W zrKx5v`xfcWeav^ZNI&M67iy0l`v-QRen*2+z(0rq+lIr>r9k?xT;Oh5mZun(p0bFRbnXXB=uyzxx2dq z*-<@Qp^mjkhLhs?N@)9wy}hVRR%Znogo=`9CH&H5im5I>e-80elFCi1TC;lVBTKu8 zgiGb3s5X}M*XL5|x|V3>^?B5}Q&fw4M3uJj?Xf4*DB3~Od3?LD`4GDYBLCW8EP+9P zU|Prctv?RYqUhcNdlYKF%T;#QKNybxaFOCaW;*Nw<3D8de-mHe!0{i3`_G=e8sSGK zkk0qVFTVTX$)w+yz92wD>+AQAUmyJN626k!(fW8n|2Hw=8c|F6-Lv6PYpDqoQ15m$ z@x}ig|6zZG|4jTA_2WPMc_075UJLktKK<+aIsQXmKVtA269BNs{(msqR}hm%D9=6_ za6+AV@j^ocyJSxvc7N%!z$im$!;0z3M3Da)={>hWae^wuV-oq7) zeR;C~?BL>w`U0|?73|aS;=B35Gxg~%Tc9ZweY<$_{t25PVg^8|C-~**)A#S6s;N&c zJz*`S2Ny~v$`zjA*{6$(^w0ZGClbbz@kHX^f_P6FATHtK<7bm5oLcyL@MPkL8-;Jr z{w&vwhBn1Vw^8}g*XW;}wMb%r{SGwSVAnX0Ti9uDMKXxz!-BPLe%3Li-u|pt5o_-W z_uWuZb+hOv1`6<6tE^`}o9vybCzEsIjcFgTWv@ow9#eL@LBP~WSwzr7(nT#6eGZAv z8yFX59V&R$C^ie}7SncCGx)7h(V&c5JXCU_L}r<4Ud>i z?}x&;Ac)rozh{Zpq@B0$yKE|02)0$-?H)&-5+3?Io7UOvD071|mQK}`GVE5Sm zMz5TYj4xduC+zwOV1i74(eWjkq@p(tn@kNW$iT%2GMcZB+F+oqFyz?IC!s+yH|S`U z8kHGEDF@e0n%VZE4O-i7g#{}b6}S2*G-hJ9dF_fzek1r9vvM7&4iSpUy79VO$mdCn zXbY%0XQpJ;Ste2Y@b@{V%&~yyvDY&fO6MC^6U_6fCUg|8m=WoJ4sME5AmTbb!Px|c zKtXYEPRc~hlOh}3tQN8BSk=KoUr-T~y9`NXut!J~Oglh2keJD&GN|G*rzshgEE&p1 zKEByHimk4hjwQD4)$FmEcSj*L`aHdbZbE={pwdzAX`~oV9wQlbNwXHqc$X5rdztJ~ zVro-coHGVLH0P+_ zB)=d5XZoLz`naWC30`DZFF)utp)uY#Y^$#2o4{FX;ZOr9-qeQbbmn|&Ws6aP&OrjK zVzmDBxwnt!<2%u$75Tg-P;^n{Qv5q<7>hVKInIXK}#6p3lu z#;|Z>Es8nlwUE0=mE6J^{x5D>{t^R2=^ZRpaFP@s;|=TPd5hH|o)S6H)m4f&2Rcog zCX9o@qxa}RG1Z*MjG_YTsrlM!`hsy^TD;-)o(zqDSR{t7O;m4PKjW4w?8MdB$w4uT z>OdDQ@mAy~;13)Q`V!T=KYBV}Iz?Gy(VDt_I39Cf-otOj-4^}d_J_&=ZanPKP1i1f zaglfy<>~C?8iSlw&<)&{jTU@Wj&TP!^9m<;Pxju`z9%vbAG+bB`C9I0iMX@dtqj>+n*Mb%c5szc;8@5EKU zm}1zUKT>~ncL%fXUs^AG&~BckM=nc0Wo02>f`7Te8>vEm(@s-Cks*SN$l1Thi@drD z=!9j|@dNt+I}2Pq;4+Vh$sR+58Eu`il#U92tP%sl4#Q_VUKy_R53lStuc8}IiYP8 zMbhA7D8o*eRW%sQaI9(~%(TAZiB7|RMgR|Ot_2ciRx&`@?i>p2YooN99=^im#RaS* zKaxN{Z>pPp_EqlAwN?uE+6g#JHc$Wz(;4ot&5*IgP5S)VR*OU$wr}hf5N?@z+Cc7` z?O)}6XT!N3v8nm>+^ng}{{f=Ly6SSq!)GO~OxqR)7r2iJixE%98j6#&Q(4!4yx>L0TCv;wwiph+g=NARu-kFxFK^*!6yL1vi;_rfCl& zo}z1Z?M%@GCJDOjR?2O6GxXUhmjg~-x&;VXs-bx?83-8UV-V-_alkxpgLSkiBN%rQ@qNF2I$OIK#gnq#6YLAGPa*6ECi6Yd`3YZS$Q^X)26Z_Ubu znOcA3X$7l46q#WFRa({U2o=ieBC?hfMQB_f#Cqti8w1{PZ{^-o+Z9)IB{le2^qd_9FGxE8NLmOBnR9Nor za?3CLaTIF9mzg|@>oBE%xm6%Pcp;=MBFBP+>I#i74K<;6tEdd>&6zJc$CFEA@p^i2 zu=iyD+dLNQ<@g@;@i6t@r0=suHLj%R`Z~UPaSO}sJ%d{vmuqwp-zsv7xd@3NSP7T$ zG^r=)^K6m=tt;lRtjyY02DXTJnjq+@9~Nbbpd>u&PG0?#{sioQ-`&kCyk;SDq9f*- zvEI0Ie95kXV8@1+0&XNH@ZUxDijXxLU+*5g-^3bNpnVknPq`EEL5G=_$7mnUcMN15 zh_l)~td@TlC`?$6aKbP23IFBDlOJE)qSy>!ILJo4THAAnEp%%KqcV6pREU%Z2veWk zF5&VAqkhkAK*nc(0kHM*wETZdJRt{kkt8+xY57YA=U)V`rVKx)MQ|Q}$g<^e@jYHE ziQ@E@kXIBAdJHQ#)^%Kr2l(>E`L0VX@@2r-G7wxzcxTfAbr<&(=GaQBX*!Ty8(`0p zCqpBRtv*Tc3}H9*55Vf=04_gjT@zavMOdjuWjqCoAx)> zfWEsG#_kpt{gv3%O5D_d4JZ`@CKPgqgKy3!eY-1ZyKBy&?R{>4bm$e@%3*6l01gJs zfm}Psr`YPhE^_rn?oqPEm?pRxTI)k%r%>e>}3v) zJG8x=$0bb4@iu(XI`}nvr+wW-HX}N&<$3Z3F5SUwfm)#K|H|M0mB0TT^4HJ>y0bCt zH}ncy?Czc+-E|}K52K&q#QF%4*Ps<618&2R$+IIxN<;}u8;V>Z)K)Sg4>`8Y9ObZ` zjdQhsjoEW1({{49y#vpqEF=UfK!S@KRDhnH4P)3X;gU6iYZZ(m^QV4y!Prz0nm2q) z{omktoYT$GkNAB9q(z%vbUfFWZqTl9$NA8^T4fiB44#z!9gae*_vw=P=~0@57N%ya zN0%S-e>@ruhK~?G{1MmM4Q3TIyvi0x6TUfrUS$~q@-)5*tq0tORQW~RJFu?$Yp*OI zF0Mlf?kb>Nw}?bB?Hr1t#Wr@DSGwh`ZqsY`t=TZQmoDJ&Ms|dR?Zn2CFd}?LyY_oZ zn{BW~Ut3Rv2W0j7dRgCvoC-WL5it2rCBu!7Q{6T>N8|alUwYLq^^`U-~9bzeQLnY z+2X0pJNr%hXGKpFR0V1txRhwwEad~-`7x4aJ5qbB2^R0Jk;&~T z*|JTaY$v|%$n1`Ed$Yq`jN3A#)m@?W<=_>~Z-sf_ z<3Ga1Fq7QJ`Ri;3ps<`fisW3cfrDkxmhsgnF*8?MrN$Q*KwU9;iWZY%JZ-L#)HX%=G zMk9KN1bqOEHB*0oXd{UDqu>$#=h3I^JuqhQ_vK|UhCM5Vbhu|eV$7NXuWs+ARlUm6 zYYc{^gmf=Bs>=@y|e|h(6arNT= zdGY-V{J)op!qk??A{`ukw%6q0~a>1?ocj%te7ojb4Q-RBmM>kAISmN%0tju(#LKtL3^xb9|{t zyuZASqKOfIH%$Bzz5<#v*U*YqHe3%_b^i+dd7Bq+)7yL334vE@R6uD&Z+~Cen}?%QwRX6|5Ihhb=I;rK16=MVFsD-A6{naWJ{4>Y&x*NL878CoyF=tLzKv=Y{LD*G7Y z`|$aH`;`eyWO9J-naZop+DY3w+|oCr8qvcR3b3Kyje_*nM}c>AIUAQH8NBu>{%%F+ zTAM=L(?W14Y|- zI15>phjYo9r6cbw9rQhw&TN`aN6VQh$2K*1vJ(1LoE zT_7C!X(>@Y=!Km6_0YmF7`~_s!wx0WTW>svVTZC}kRRBzm}U=dA0^UTxMSO|@{5aq zFC?F;@OPm@73tzrdRHNk`_Fk(P*PRPI$n0lRTb&7>X1*Y4PC0Fd3r)p-XS~f!LKkB ziVC)B22(x2TWf_^>;+9#>cxB&MvQU>Uy;p!LAHd^BwJM3z3|G^`t^L2J(d9#;M)Z1 zL+khQrq(y6i zdo{;o1|Qk9BWBFAxatiCgFwXRQ1tHYttB`I@15(j1epaS#}xYWGqWWOd5BHcPe0Eg z=WE=$WmJ+NzouZ!b=D`b>oYsmz=$xJQ!~HuB^3lBgp^C3Qt>2?H^^(FPcg-wKqRPd z29k=wG`od!#T?IWq46!fHNOdeJU~Ynf5%>^AOU7qA}=)!JpFxmXspP)yDd!Jf^okC zqgqLI#~9%qqzv2Mba^r_XE)^M&piIPV?Kh9eZ=)=P#JMim@QTuxVo|)>BN?|lb!^# zo}g|2fb36yJbn8n3G#x6|2oZX>mZg*BRCf1tKdlWJt4M)x%H9oQef79qS-TFM{@(T z;nDs?^H1c~zZgk|0u%{22>s*tr2Z7&a}9yP@FmYV1Ah}+zH6tap9WM2AQlNj`xFac zjH!MCX)KTzG1>&!f}z7IN?%sK7l9;j@QP~^i|70Yv|aH$Xr`d&sZ}0|vytuY?uZD( zXNn@EM*9UP{s{|KoE_zVV>4TtR7dsL$UG6f%nRu|7xD@rO+=g^WfK|o{(HTMghE=V8AbmkdzVyR=qxq^LV6FbzGn97>q za%zY9bHTjNpYuc6Q~W}cJBsBL4{I%NZRD+uyz(4dQ#Cp#Bd3Gf9_nmYR6rtv+P!wS zoo!CR`Y|!NIq7V?t|Z)|^>2>$PlEGj&C)dD7fI+mXo4 zS>LFyR-f{Eb`^S1LSeJxk=*(;9?(3FeXKX(G_UXH zncC0ALM~Spgzx2u?6`Onn$OP2SbVH3##$s`H#q8ov6sX};%*HS&uPaqzsv)Md75g= zo-wFHNjt57L1U}Wl;}HlRlep5OV&U_^`#3r<cRTt5rMaj%CzyujQM2yQZrtOJ zI@C9A=<*8TJKP>`-=xdIao9kY)@JN*Qp8$GfLSx~Lq~_05!%D^9bEEuT*s^R#a8tK?1N|2Z z)!6-iA{GMD8k%G<^)VcAZFWWK46OC4snOVAfV*>QRA^)BUrx-`N~sa`MM$Qy#c#9z z_WRU125UP@LwQocf2%hX>#KUh{BTRD9($G(eR*>`i)qG|O7HOY=}y}>tjmv$7MIfv zSlv?SF3^&a~Jo#YWx%K@;;>Jx2$oeG_mODtwt{fa-5gwkCFfAQ~@3XbJj z!eHzSo9?ztF;q)&*m1buo`qc*@QH_eKH#4XH96UWV2A%y50=u;h&(M%@Pcs`G#fGo z=S~g!ZI;S2@PcjvO$p*{U0;paRY##3CxK>L#P3KHk>XeF8l9X;9f??q&#fygEtOk; z-D_J^U{RYSv~S~ahkX~l#2R!04K3i)3%7uQE0|XfSu+h8tyA-)!>f*=BDbm?A!eYV zn07L(A&2o`D1!>w{T9oOJ?Lk{^Ca=E^G?o@nKQkW&vXrv)S&r{H~M+$T?i11goe`A ziwPlpo(rKtgNi(oIx?ZB+CtI=$x{7)ScxyRgkbPtFaSA3IkJdOCWVRz0b8gv0XHVFFmo{$^ z+gG8PBX%ufYvMZP*R*j~ekOOi!9?qI6DEoXiA8M))5*w&*<^T$4I90O5H?J$1!Ubp z(>bFH3GMuAE7VLo6*8`!jeKG7quVfMGbguY%+^ftkIe?AP@$#`z2Q#l6;Vg!!KxlN zai+zTq=mzVbJymGHXcKcFLd~SBH-X<|I<}oXK-$uG4o|_?Bg%+@zQ<9W;d& zk-z_}J7me~+gv$1cn;W&JoYvsV`*>I8E+|Uu*u8JZExG&H5K%<%A?1Bj4w*Kf<^Zr zTZE)7eT(F5^EixY-br86cZ>x^KG?Pr^5-(V&c2``r~8aSE&Lf|^Sq|`Hkzy3XkUi+ z65ei@v>q^*EQhsLOrWN~J2raU03W0dtx6RyAI3`M%P_{OdV|rks+Xlz#+n`R6XZuc_G5DCCg7uKfu@0%UyVr`A{Ojy~Ej`dpk zJ1q))rgdaY4>=?JEBhdcAF@@|Aa88CJb93?Y)2IqGiAC@L8QvtJ`46T<{mjRzq8{+=Sb<;cQ@5ypFROH(-&ErRp8)=0 zIFu_2p2Pl+@qewQHs(<8zPm%O~VC|6-!loLmMKEL-J=5f*@nP%5N;xjZo|6+3MwH7Q2v$DteU0jL*{0K_ zeBA&KbL=#Cv4=^7>&O{5LKsNWWjw^KyC7X?Jwmv~foNr! z6NeF2^42(vD9GmG{#dQQUY$A7~q2nly^kEtO zd3hW6@!uPVv#DGc!8T7Q2#XVv5;)pcz@JJ1f4pxAxC?IGZ6pX7j19scE-o%OQW#

Hg+vuD3d{h244p7YSFx#2S}P1y|Ogi?VenEe)B=`CpbG!`~D&0BHM1=F7AZLKNr zLK|Cu2`<)z&Jh&RZCK*N=)gKoWtxf7VLt@2A^pZXrau4w7ETM4IJQfF39N4( zvSceP1e4#qx<;{Y5maCp^B@FHu|Mb&efW^w@o}IA{x!Q}kPb!JCyev{1qL^ycMl6= z+#58Y86m;51Aos;;mEIYhW2Mf{*K5gMjH1A8KFCJuqqbF{C7{^LaEeAj9591_ z3_bw-V2;TqpT&2}&lWSXwm4%$#bc+Xi&lY7e)=)gY+ei?*mp3PP?U0_OyfQ`MIC1r&FkY5c>e=Qf9J@TK9^%PrZ zxb6NTy=EpMnvL6@G?Bp&oY{lx>Ff1>Xd^b(V~)jnTp>)UFt^m)jA`emnt;zioGF`3 zf2I^YcsFD!%1?pv1rgUXk|X8KKz67hGxODjrvcy9aE8Y+Udi%BI;ClKq(jB}J?x{g z&2h5{a^CT;I3CkiD`UeDI{7H#y);eq*Z^nsYx<0~gaog^PXQie@M4xNUS;op;m|%q z|9Dkxpjjb`+Q>OcAF8qLM=!G<8!QRE&MEj4YY-7vagenZ`M}$P;Pt;}HWC_YrtX?I z8V;HDH0d?>fv@4Rw^ZM^G(Y2y2fEVZG6Rg|Jq>gLSj-ApQ97Ru0Wyur?e8YmbMZ6ogNS!5z3l z_$=ldnLX79V|p9=M~Ua+Ux9VEN#FM&y%hyMdA=LMLx)8~j6nE^Fc5;G&xcn$jn6N} zG?xXUD0hgkhJcy#n!fNvXly!}Q?Jwj&u^8Bqrro{Ov6LzFyB}e-0kaslkV|l&EK5S zS|wekmwXr+sX4Y(lZkkof5ky}%N!G0i>5vUlHT87_yT3!9y* zvB_{AR#cFti(w;$@-!wc3-*Bw7JadLkm)x&`JQpq6%M6ADz`Aq`xze%I_XW)!QNwY6!Go7ypJnIkh=te; zdI9$-RO&8$GV4xz1_j~01Vl3opy|FS{c+eOQ*)^yM|95&eJ&lc#bt}d6Jgpkd8sni zZ2kJARxYM#lNU!;4gW>ZKKj|;vmx+)eEuBLri!v6CKRyt$X;j=5s*V*@oJ@18sdvB z>vxm(mPIt5_NE1Yr)9m(O>3GEw`E=@pB?OH!-}ZuO{}@)oOrNVLP+|Bl(>yz#dN$< z59`j&4H}Q*>*Zo#G(|y1c;vr$O3Onwch2}oHJ|obQQfR~VZp?!v=RyO1ju-K^>E{m!ITRD2f%p^QlV|ef z5dU2JLL$1v28SG{_58edc7}0GtMhXgqt>F5sb;0VR1wp|zmwp4o{wi&*~b;BgB7Z? zTuqqrQt2aqRSg>SYq$F625z)mG&Z-;2^!WTxQ4#*qpP4(IzU}<5UgY3u7U3Ag0{L~ ztSu0yYfZ;vErL1}qpi|mXCysXc7g%42Sxb_RtXI_L|>b;v1gCabVD24?{{rqp_puF zAFr#ex*5HR-CZ6~$LGNarwBy>o-eh6hsl2S7?#R^%-S|$Gh4#pHTH)icB|;VIBJoK zn5g}J;ZgN<&=;eHmKzIozU_rvz2MH$C7ebOqH{fAs~XFl-rP>FU=NG+v`^{X^co{8 zYKa$VF3MsHIm~|bT6&DRRbP7z9Kc*!-+LQa!b7UN^s}86*U#or@aNHJ zl;4FB<~}~Iqp?eG*cAsPELCI06ms^##i}}z9G;>$sVx` z+wKnGNa)?2884C4{4?9WTxD6o8=sZs;$e+{t6Cn~Z!Wc+Ta;xV)}ZU&b-z_aEg!eL z1w-+$s#{box5xi`qH5_=MZDdXpQJ|yx^@gP3ZPiITh?^6=Ly``SBIlegJ$k>4qde#PO zp)Mt9j7I@lT46kmR+-WZI{X)GU{1S#+7Rdr>A-w*0}p(+y-Hfd7&~*%G%8^~li;1G zP?n<1BFKrTft$!8Gtr$DgHGSyOJa`kWqiHvWZTrfJYcVMn;s~oLYazX4R62r1+Tm+ zpJ^DQ`XYZA?C8L2ag^GMpFgBU?=7rx4`3&>_oa*!BwH-}iv03&N*x)u;?)U%7JDeS zsLe0smm>V1%rSWrv8FJon|ex%)nm%2p1r(^0_>uQfxL;2#wuHvmt=IxR4}uvZ1w?J zcXo!2pVG&dEYVuB^zYU}Wz^YW4v9+&6u@kN?6j8-`}=*{^t~bSe4pzsI{2` z1xv|F8uIzuX5Y1TwThrk@#@m{>}$pWAD|^5d(epw@U9y--vN9f!ZS%{@Iw&oBtXT{ zXgoMj^;nl6PbE7|61uxyKF#zyA@~gS)g|6IFP$p9O$>1XkUAmi?G5mT0(F@sW^yxYvG->$Q(OO%~cH zoiSY7Q;lF2Sj7JcfyR@z?$}b5cFm1K#;qZ`almY8T*r28<5V$!#(Smv!l4s#)IM%X z+U~`lY{Z;{n}-~}`3%oR6t+I{jnj%NTBY@1Dg-X41;^j07|lR*lcZ|MT$SWDA1 z^{iqPJl1f^XO+kx)ke#9*W7J1NBX*J`c3+DMR3rXY0-Plh}7J00R7C2)yDGqK)I(gmi_bR;3TViYS{33h12dc{N!#J{5(71iU-lrvm7T~lC%4R zWF!-K*Vo}*b_-4q4{!lDDjC?P|^dLOsuf1^QlTWbs_cWNItfsq#eb0Hf z)i;tIcC^OnP~9xCcNI)lQIWN|c^cX9cI)Y{!GG~O4r#rmujhWV*%VGRpAZz49XQp0 z_E#2g^((Nt({u^jcU~_tdewy$3KCId`S5Eu-H+x2*$c zkgrpH0>35I8)+1|>6pp7h)JxA+Y`gM$?#zb!AYm=<)W-Io1v80m7}tTjVz^{^A1ey zI3KX4uQn(2%6#*}ZLE`B!$Z$NxORVk{kJpObF+wZBzZ0Jh1e`&6sSW<(^6y^gtv{5 znN^-bWUGdwmpp@@R~FY}zr@N}cFNN71}0v>n#fL!qm8rWsIm=x@s~GN!B)M!I%9Rw z(bw^ryR*a%i|={l9j!(dY4akhU+M)z(?cn09NsPJ)(gA!8!NqIG_Pud2~x;^>Ov~0 zFKI0$XPC_@s;$#4C2@7v3wAn=aj5-H2ePZQuVji%zJB@s@A~bTt)NE6hb}gPvJQ8x zZe6`di{Jm;DUB}X`6`?7qo=abS!UUsRG%JudRe09uZC>bWd*(VYMD*?*EBs1k*tAH}{7*J5Dyvz4zQ7m*#bw~Ju*JvLcOpw!w6OnSMmnPIj~Et8~lo1L(d4_}Gj9S-RXp42%|$|~N_2Y#YtKlD?WR9yUm^#GGGi#0ymo^&}$ z&ZR-p^b7mKiQ>OnsiHg`$og7#Q@D11{d1q1;~VXiD63{|)gZCmjgaVn2**rd8tO8S zP}+=+YyTR;Stz#WU-@eDoVPJqA*JV}cH7 zS`pp8wLIEtf~6FY@=Blh?!bT0as-e??7-4^x z-H*g@y1mL5^ZqPd&F{^KKQui0&|>yctz+IRnQ1O>Oc1p z%xsF!S@_F3LrJS2hw4+F*IIi2><8 z=1?AaV2G)EQDEUhvYLdcg38R&5ueeh&e}{bN(634%&D{UI5lNk&A~hwPV(pJV38G< z_0=Tb+hZ$anPhB#%2sFTS$=*#DR+0P!SbfM3d?BCrM(ip^>63YdYs02T*j+pXM}Ot z(I|yCb~udgt0X%cp2JrTjstASFN^RVDmGRSjbhb}v0F&%WVB`gKSg5io1AN}%4<0G zhJ<9X3R7T2`drX9Nr4eSZVvRN=Wzk6etRu>1Zx2HkucwX*6Y=goqv8;q}TcEC6iSa zLzc(t{$}8vb#d_a-7l~E$3Ok>uJ7*t#QC=%v&SH^ryy+5lR;hnx&)bhnN|psqVDIb zm;_iZ;Ol4{mWhCEftk@tNEDZZ5bzSG?(S~MfxzfzsC{aGbh=6zh%ZKwbK@bl0;h04 ze=}ARcm9-rVbGr9sz--*Yn7u&1m!ZF;Uf<7Ii07g57P0Je~Q-1x0|lb6e(z;1z&sO zuSYr4$(jasJg$2^Hp2dsCR7uo9xXU#>It2eG)Wo1$H0Ag#*AB@Ka$^kz}PNkxvn;E zzX&ygmDQgfUIYKZOv|@CnmGW0?gdD zm`Rt(NB$;i>EZE^pB032d|e`N6GBbF{rN5aAiVCF(r=bB^;g(U>+)uHML33-e2Tva z$B}=3!BEm79U;^4Br0okHO2fR#(oY3I2)`76tVRUCol|%4qU1@@RL?5k`4UoYH`{6 zwq<3iOFnYx>jrX(5k?ELlxo33b8M!!Q*CBwZ9(p}=-6>}dbNU8bb(j4u<;vge5?(S zvKhklqJW){`Vf`&G`<+uz7$p{tYt22BsxoUPytgY?5=IfU+=$j@R60700r8 zpGvcb6mOT}(zt2U3H`RlULB();H$JwF;hH>N6`R|Lg_>xT~mGG{c21n!%O(j=sbRZ z5C7Re$NQnk;d{G-WD($;BOGCpP-DZLbanZDtny-Y2+w}!ft6;BB*rg&Slh-w*2YnQ z<*{F}&J26FU$W#d*q;kv)%hy@^cM^RM%aM_UN3(;W=_D(435n?<0MIdP*m_C4(o*4 zVYiVJ+?cqrP|Sso%gr(ct{oRB0h9uNQXIv6C`Dyj9v*>lM6ja9cr(zyH*f$+SF$6B zR$IoH8P`B2KOjwz9>4&F`v(UIXd4AihQa8mo(2Bx%k+4kWg0eTdGbtT!I~N}J$<5Q z^3wB6k<*lCiL;I>Bdht}f>lr;In>*Rtp3!ss zruDvOvI4(q?C3S|<{4g^C^txd)s)2mwEM1QrwI06;l)*>b*qQg*HrESFRiS>FMVp& z$o{9iwJKQ%$TGpa>-G5cE(yL@`LriFRl0w`FQc&VXctkH!7|~}-b3v?Ca8}|koOr> zNNjr#Xo1u5mh_I)SJ~>iyw1p}g09%3gD1R42c~UW-P{xLZOa~L6Q{j@3xCCoJsx&R z5fAHb*8fzl<`_lSI}D#bHWMwrbs^fCw^WUORO6%ZGjm{&SLA)bS9g1)7*dIP?n=g3gWjosMVBn{gn2j&JEUzl- zor&H6P3zc@@rFExNcr=BYNuJGl0FQGRi?fincw_+-Moi}iQjlxZj;4Ew7J2Id6 zTfKv`D%nGL!&c}SB<&Vwpv%KuZj!?w{S;;qTpWjp$a2()+KY=WIUy)pgvXQ&Ace`qr82YrcrGn=FDzB$` zvB(Py|LYjWZt_K*mGf+hsIF=4ggWJyFU+DHTghq@A2sKHbZ7;V;ddjfrddDt{#`<6 z@o4Ns9yR=Qg)t!mYWTIl&XLQE-lx2JQ*v|8Lzcz%lWnQc2V;#H zU(J-9q~~{WTM?t|b@N5@3Tt3I!Thwf?51Fp-p>fVf}8hCNs@pZZ@N^rsj6mpw&*?+ z&lh5(6RIwMn=_y^7O&2L*04Y|a6g$P_2&fil02{0iSv>2wOi%!!DNgsV?qk|1 zO3Hu;=u-z<5TPAI-7~~BqMhvAh%J!L&;XnRRj&sh%f-!g=GtCOzEGn_N-kFUbdi0` z7CqIJtoRA4x8&3Rpek=xvy88?0v7wv3X=oP7e)tv63D|)=a_|cLxmA}!!p9p4IhcG z>IKV<=#^Q$&xpR&rhAEy>9{EJapUXayNe4Q7lBPzW*YjlDB*JkppV~EBO%oi_kORlT()6c+;_v!2dx523d1t1k~QJ#5vq;GzH|5DiQ`xuce zFK;S;n+re7bYs8e0jD8Y-n|lEDS+nIR`#+xR#%Q^mUD$olbPKlt!tH128=M_oqckV zX9X-3Hf=vqnvYlbrJYYM=7p`gI@napk|cegL7rE+0bX zugg{>*BQU$y6>{*5t6S@#L!J#9nQ zC1+9Mf7bjFBY?Bxj%NGkdz#WZ+%xNJ@D8Lr4{;Bqf?w<(NVWVE9dE4OF$mW z7;*#o_^aF$X+k!lGUYVlZMaQ*iE74mA~|ljgvQ!j@xFJsaNtxxk?*X14NogdiW*4~ zBA&vo)&f&y?I#^`B9k^|HBOovbIY^V#+>Y&-Yr{;FgS}q$G-EOa$|0NGw4J_VsM+)7)@joJUy?b zJm)ojB|Aq!=l()f3MCMCn2BpmH#f9=mwky%pCE-L-xL8Y-bRQ%bN#f@3W$bY(J z6>@4)@yGjH7H9L7HNF4rA%#Kuu=M`Hwv@}cP2~?p`w!whpYf~*!~JasP+tgGKZZ}9 zJ)k3e@E$+wKmb0T^oBc$Pps(_Cg!%bWi{qi&(x|!6h&V%m_RF{eXlEey}k@^fAkyf zDT*6`2P)rO(qw+~%Hxe{aAaSc$Ib=N@Gdp?4s)U9u>bYv&l)15M_uGEhL8TTm`8`w z6#QE*-AC>+$9hLQ2JaXlnvETqbO2JRcA$Wv_>DMpM(?s&wH!dZ;BfIvP!X!^|7 zCkVAmAIaz0v3j(Z^@+Wp{XK)9?s?v6jVr%ahbdv5s)8a@CQPy#+*7)gMTMPBf^lm0 zV5ILDj~|~uv&FCtXkU{Fn1s)V@UO#8xw%s*8Q^!xzY&O?vbrGb2)~X}e?Day5Ph9V zyM`Vw)jY1#gL9PdwV)l1pnmJDG~UsVRd%DMqm||z^36c#-X{Dos0#hHTzx=qCf*GC zWoPlu(5l*W67yD$SvFQrA=rHluzbz}6;?uUxS7ykS>|{z$JQdTed-L%T0M$9q+v@t zBX?Jf%!^=i{0K55`2jUOf1w$7gS<5khe!1zI4X~alg7cWGK>zP@0;U_f__-a2&3`Q zW7;!6WOpxB!~m{y2+6jD{&YqS8JlPikc4n63?Qljv>D$BcX6n^3abbv#0q_*(2pCA z&y)K3jqu~HnIHGfS$(cT3{5N8iP+@8==9*u+SxhaZ z%HbogQj&nX=6y2|dZNKaIlHOCXybEk#h-Jlhd<|<3YsjgIzH>N4FB8*-PZU4I#yL$ zr+p~8x)W+!sjF>#Uj!)%4&S6z-FuejO-VY_G3|?INYk#@+j5GPG!R=Ky z#Xon%HmiX7ap>I&f0nOsl_Q4QD^v*dfXJHvaNdd^JiyPZWm<4OvVc*?zatzp`i3Sl zs|>+iK4$$ozs`Dy(SUylLmAAEREdJzB*rLo*djhyjFc0qWxt?&jSjztl{$TZJZGX@ zGkM#{@lDYQpI?pt2GrSKD5HUZugS}X!Y3@JURoZ@S;an7e;>q@rC~P=jp@+I$d0sY z1~sr{ExZG&8k!S+fZO^oJ30$!OAes*;Cy^W|0M*b;Cvlx0`5mUs>oFSC}17#!6krG z-3wT0Vq{xU=5($`Ot{I4QDD_D-E;>GTV`K|=8*i7BBoj06~_LC!KrM6o`gYHL@b=) zt!{5^ysRDRRMu#Dzt$aDWEgE(Of z=EeXY^vw9x?F6Csl2DA3>!xRp~9kZEer4jN4-f3Zou1=!EFpgy$&>SH4LCU*b(O>8i$pG@PqEj8j??_{Tj&930yZK-%#yn920-`Y6bRG#CdWLOL=m3F8wo( zLOj#1UZ=CG(B@nbr-%tfcc%d=|HRSO0d}g-#3i~vI*%s&&^6+f1?<#PM!trrpW7Qc`>~P$-Y@-bb`rExrbAGn(XWpySs%x8$2cB^eBa6QZGNs z&(d?&ejSbRM*=sD@k%5CYk?~L3X?~J>vZX%@E+TNk;Ov*)Ks5i*?Y8{9v3m5Ht5e4 z3^q$VJ6EY^keS_sfq@15YhokBFe6|Pi@IFhfAz7A4b#ndnye}JXNw7Ka@r4z6wnbmUADA35UUeWt}!Ic?hK=NWktvlI3Jjk;fL@GwN-Rv$MK70YmRm#Pl~hb97)Z0 zcd>VaqWly_{hY%q%%4Bao(Nx)oB@>(e-q&(z^2V3m@RoZ4<@KOSnVaj5gU@Jx|Rof z8H1ur6Z0niVws1*UtXUE@yZSdq@DNR&aWuLA$K(O*avh!A>F!kjic0ivDv9A*wjeZ zaY~#q4|^mutcL|`JjW;R*hCDYz2FGMZi>qb^e8t!iZ-*e)%oYoA^xYauNLPXe+7FR zdY^kcO>M|dM=}0})o~qm!r9N$MR{o)7g~;DVZfbsjPzuq#!37?PayU`3Cv~%T81Y$% ziM@XBDKs2SWY;e8+ib4P$0q`cbV3&A!^z6Fn}@+HVTje~TqlIaRgC7R9L@*$?0|+} zXx4^tADDp}%YxA&(4tBk8{G(uV>z03>R0<6VM@6JjfGSSCjw3?vq$#Af0kk!Eym&1 zRr%>hCMohU2&-OYP}}vADi%II?w;;Y#1^Q&2x~Z1TMsz^(Yn=V@eN&NBE|24TFL4U zzjDHmt$Ed7uvOUp$`@w_CFrG6Fxi|DJw1ygh*wJ7l}*Yl^2ETi;a;Ib#+og7Ze6;3 z^_ldcc`AvT`Uw>}x0TLPe*x_|g_YT&-Lm!N!67`@GhsYQEM? zDX~!FW8Z*oj?L(n3FjH=y63OtTEMY%&E~n8p*`U?wfLi3L|QHSCUAp+mWR=v!l8#i zGXRrX@R}M@1E%t-A#-@uXm~blIQ$DcL-T~VZo*vqW}pOqz$kjXf1rz%c*kRjQhUKx zYp>qos2!{qZe@Woybyxy*MM*kR7z@QFFUK1KgY>bub1 zrr+T|8_%}?g$}Tep9*_=(-M*Ifr}eW7**s5TT%q6*_Gu2Tz3ykS9P zzy8Pn^wR=oe{Iv*XGbUK1zbn*?_N2hAbayc@7IFPjCI+&xLF{gA=L06H*jDdn2%}? zKiD=2^9xgWTde!2pWe@(9j0+rz`I#;Q5S0lY|O8)J2!xJ5#Zmbhoq zZ=Pq}vf67xUgW427c*%DjC zq+UXi2u{ibK6c4HO&K@^#e517Jc0voYm!4Ep0xCDkiI8F9J}%1#+r+HdpAe^ZVo3r zPPo=Lwi<9nt2NPMA2%(|>9kIo<9ef(IOTygIk+?I;kZ;_6d$I~s^dD^)OALoA}d#s zJ8Gj}e=&xrjVt_DmgGE@OtL50^IZ0n+dXAy_aqX}vU7~Ci+njM_7Xk)Yo0m8`T+_=UjV5P%PDqf^%r2_3Q`y z-w^?xG!f(}9%1(`N3GSW){opH?Kl_5MC1JWf3Wws1kOA~21B#v3R)ghhBW`sPBHkH zXP=UcU1g%USj%cM-RQt9mK_C;g1veV{|)y${CjQhOgF1VAJ5JYd{A2ZA5jXlxrB>B zCGG`8HyC< zf7}%OSYBtn7vgz5i22oMQO;=f7~qM#NUt-Fhn8O!&;;5&zsi^~FKgyxV}qlS+rg~80Ak^nOJWWiUJT%bfYf1F5Y;O$|qOHq-2%r7ZG950S+N$WbDU72Xt@G3di#Txb6ffN# z!YEVZ2Cm~Yp)*rpU5)$vHY~ODf3#r0El$=)cTy{iocgK$(nip8BeSI=exF@|oRw%# zAS`iy#yrRH^?Uy9T;JG@OP{OR!DYEm1`9cp`ijT+?G&lV7j{^`(bA$X+yv>JM~ivO zUs)`e4esp&1=*Sr=y8m(z89n<(C_?qP~z=wyv-cgaL`cJAFu)G9kp(be_qoNp~}XN zzDN)h9Rft82}Tnb69#Y^5vq{_GZ0d)6&^2>@D!i zgs;BkO89j!UzY*B40y~wf2b%PA%Dw z{H)VTHYAaR3smB5oab{ZHmvZFB+}kfDV?uX$PXJgMOz;9_HX)X`^r3ko4L9P8BCRp zhW9s63%3O169IVPVKM_q7S;;af$L;mv3-KWR{D{{|5Kre~a=qhz|RsBl&9_ z%&u0j?*}kqrrF5P?@rKegiXi6ReilUK;Je^2*!2%epP;gh7q{dq7{cq7lEN60kS6u z;>}%m(2ed#mgc z&NeId<08#rl^q0df152Tm|{%#jrL8sac0qHa(pk`jL@;j?BEDH*d}JbqaZo6((dGw9sdlnlvf$*E6T;k%tMGR7r-{4q_zxI%`pi`rG;jm z)LswE!x^&MNCiL8K=%}>Xmk(qLDlq(ZEb+jkT<>bRQWu6f1hp1`nZ(z*>R0vCntTT zKJ|RKF8|@CzAw>{g1;+`mWYD2fNL%f-kE>oF)|6y6ONj2mM9m{yL+APCqVb6e)4ui zAfVQUCU`@~e>khfyzi^m{v53pw3QulXt=h{ocGRgeJp}fa?jND#5qlmr5^-zwOfEw zvl0OXW(veSyGU;qwd~l2?o)M_tL(17KO9Dqj?sEzcXB}DDH^?R>`yBhE%o=v1BC`y z-EMTjkJ>5H%d2MWB8&2}RCucd&`JTMxU}5!mq-vMf0t!6Qv3-MCQ{EkY(ng`sI<&8 zqp4E^ej$X${W(O;T|sH~k!DOK5od?JXPsl@${UOkDuKoVCH6 z!FlW>4hKbu*KasQ3XAtA9e0%79p1vsYJx#Ch|^&4&=&x1(W}0K!6U0eQWxpqc+BR@ z(1~yge>9l^!l6=zQDI^=k~|7>G1JQhkBXz3ON4&bc<>do0pF1obD%$!^{i_=mkPlR z4p~%j;T!qLqN$66ClOcK=#yP~^o{Vg9NerHQ{31rphQpacmZ!<VdwsAm4qEFZ2s@$)cwbM$$3;$*EyKx)btHXL0Q! zv&nXacF8LQd$DYU)%Ka$9%O9Sw+pbne~G8QSgq1K*Jy+`>q=Vjwy6y@l~|K|=@cWs z%$YAJ#XaROBR5)#@o;WX;Q@BZ1UL%o3;Ot7r*MjlVUKxVmLJCZF@IzkKVHYB=9Q`Y z9@dfTpNT=$&}e`JVRyIWo{NY}w2tDE;jOrsBqfo=ub)%YPvS+nh|{F@r3-4xf8E{m zs5rCBp7)D0yWIJ>JnE0e>CtGMG3uVz?7x`IlMY4F2<}Hft}Y#8*Orq7!JFeV2WTN%|NFNF7KsGk(0NwK@TQ%<59axGIlBXYCn4dvpZ z-^a4t_Z~Y(k`k7P%p=dWV?W{^f2k>Ei?Yh-I1msZkF3M!Relj>0*%T!%F<_XsL>q# z$YQsrVH&~V1kNU5+e;ibR>+j?>()b~Lb70MZGGn?w`*7o*Y-YMOAJ*D+q5k`i|udG z>iQw<{xpjTPk!wyW%Zf;xqe3kX%88h?J%#$SCpScS+JDQ|p~=HHZ8VqZA9Wh>%Gk2L@W))p*f3XtJ<2ES)VI0SLVgizEg^CDn^qi z|B>nQ=_m=iYq}s0w2HYj@iSP5p7qewi53h@GzLUG@oBZI#>`IemvpmVU$b?yZXuR5 z1R6HHlE^KOE1p$hi^oU*aYP?V(~HJAmAurly3SX6MVdE{&a6$gf3mOi%;NO3ju+e> z1p3C7P&7_wyN5t3M`JZoro_$$BeJ~2Bs~wA^09SEW;(&N-zZ7KIm#q6G}ZtyM}G$H zr7r;o_{=Y(9lU%T?6}D5x7DR)jj65P zI&xiMK(iJK)>oH(FEFd#8O{GomuYV~gL`c|y)aEktGc6259RfF(6EOR^I^mE9ckBq zQ^n3BK>UZt`}j{ZX)3|9U5xObNO#O(9yU3*tQqe=!{53lf44`j;_u5_e44>T`JBO1 zuTmK9@vyfKc@I$C+*@6~Ps3r1{|xq@$_Eg3`=o9`R!4>oJO-GB2 zW+dSiwl{cO#awlaf9qk?nllMS^l;)-$V%bB{TurEps`WgH=p?wo}%#jn^sx0reO~U zvvgU3P(}9^e?#!Ki)Xn2GT8G?bgw%f$pIQ#+?1OBp{PP1cU+Vr^~})T(_up|hnhN` zw2L??C}K%)cu!XC(!HjeUDS>P#)`Y&#A7bSCY{ez>KJzIcd)6!Jd(yz#zqUAJTB_e zx7V^2O4}EwW$^>cu69MGZF_+)pI+}(dPG>q0&TK6eT0+|9g z&K^H5DzFVPB;SLq52l~eRS^dN&U5{HFRyy@Y`My2sP~9_H&xdAcjmbU-wJ3vod&3@32T9KtFnxqIzp#U!w0Cy{z9cc|d_fDs@CyeACJXG0 zHND7-yt?{@>}%f92XV$SKGDd|2?uA&%6kqsIPgMaq2xiKG2;Y#L7u%<76B+^%8((t ze@7v9c1QFw6D*1u+;nV5HAuO<3FjaN0gMZ(XiT34f<}!3%@0`(No>pswD!*=<3mAp z%Q|`t%k{uy;DGIL)Cm|#GB`vn`R|nL@;*9L=hnL z75oD)w?)}!lG$gvdR+YB0tKr-Wt(}n1=Fk+s&!j~ExI^mEedHNEeUJ>C46Oyh8~Pg zJ?Np^6-z2E|JVQcpUMH5+<0NP%F=7ghnF|J%?;Yi?oFzHt@+L1A2O>{-g_C?e~fA2 z?$MfIFzQzkHgTb-bVE(Mw0LkG5DNlz+{AO-7n`;i{<#6?;)FsGif7H1oJ4ooy*<&w~9Z8ymvJ>=S+0fKY^T*>h4Yjd2 z;T!iVyXfNs5KJ(yewcp~PvTnk!{@$9>MWL(Px0vQJyO*)e0xVu2NQ|bxBsI8+po{>|H_RdBcrAe>@suw{ONG z+QP1#CVsK-pmY*J!PS~G=V%s#>`K~OIms!M1)wi zHWD#IBK+&GuHE7Xm!>g{8#35Tk5gFeXQ48haZVazojBMu3SoK1yv5uO$g3=E8OE&E zKk@1lhQT1)7bke5*`n!zcO%=~g?@mSO;}9@2!wi^e-&4QO-)Z&|C^hQCd{${J#9sM zxYe5I5|R?i8^r;lM>G{7pb1&xBcX064%DIx+P&o~G0@y$B?Xwgj_joi|I0xf6j!~s z-$LHSO@}vkUl1*F|G7xB?kY{|t~s9bvmW_ZpKyxg$~@8VDU=XStlzp&PU_X&z4e_* zEAtP8FD|SLr5yJIn#xlnFkIJ2J55S(5$_}n{e>*$!25E3hqp>N2Oj=^V!efJrmzSA D+gAN) delta 90616 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⩔Vv7X`K)oQ2Hw7`hvis^YR;g(d(2 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 PJox_r2O>Zna;yjd@{ \ 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 e58a965a79ce1cfa8a1da7639a655cb3b67e5bb9..638f13140e4bdc1d4d3df02c5aa0193a959c0130 100644 GIT binary patch delta 140113 zcmV(zK<2->?F)?Y3kn~L2nfkG<5&X!u?oF^e=M989yZy2j!0(0l*yP0M}rnuSbhNm z)nALtxEcK2wageh23acxl7nBHEZDUB(-no~SC$^4zRl%#-JW<|K+J ze=wUG!J`39y+pwo^kpoFy@Zl#REKel3?lLjgkt!KLA@lzo{ik43 zG)f<|ltVNY0v~s=AyxBEe2&B3+ra3xKY5X1!d4J18an~yW>h`pWK^_Z#|*64ETcy+ znj>tWQW5Fej^?uloWg#Tk(mu{&s&_>e>V9(>?^&!&{Hl?=UpY1m!AhJC0VMxAkR#! zf!>vePWi%Gx(3VZs3k^15hLo2Bzmq{)p&8Tvk`b*|Xx_To9ekOo(xPU3#jKr2iler!b=7#naFlc5=O&w1;t5f2}-` z7A}1xU-oqN))SdaE)om`y`YK$jdK}8{L^?|9uAIHv&FMTPahG-u>5{!Tvl?OMN6)` zX2R{Wvc^c!wW0pu5i+80J}gCyiy~;Fan2>Sk73n)LYxE2vn))_-Q3hntMvM7A3l8g z>1l13sgxPF1^8&Tz&c$9K#+FKf4A{r1%ZYdEys$hA(f-a%|yJp|M>p->2V%REOIag zc_Q3~zlo$KeTf$ZG+02&WQ^^_hjl$sn7}EGm=B|tJ?!+_n3iVE;=WXy5$#k-Qb~zJ1Yuw3e9tDENQ8)IxaBaie@(3MGKXM0 zT$*Th2LM#p)V8&47C&L%R)?NvVq>VG=8_YJQmiJ0Pi2KMG-@u-Gm&TdrpT0=B%A`C zDGBE^S!ET${A^7F)AUeN;daU%f7d-FkwW<*aW`~wAV}s28OHpqa5HX=;^Kzw*1g`__Vk$7 zgpcsKT=?Yt0^l)T=B*W_B)@doAe-b@ZWqEZIQ@O8sw`tj2ipj=M2>C|A`J441sf}H zd{Zkl+Q+5NgIUWNT45e8mlb|LAG_9;V0lPiPVmaja3ht07%s*5e_4*m^Ha@}U;OV# zIb~ENNXR4(zX4u>fMx1Wolt9ac&{AFVBQx3tSgL9@8>zq7L?vW3ydHdvhIMPznnx? zF$@u>@e60hf5Emtq`e^ND9hXB^z!ifI!rt-%l1vRHtT!C&VEu634t(W*6)afUi7;% z4}@Wa2{D48h4K_Ke|P*Dv}8pvEjE|nFTD7TDeL+5@rTD@arv-7h-y1MEa`2556+H$ zww)L^+NcM3xBlCjuA`eb4#rs88kdfCA3g}ZIq@->O;`Llw)4=hjzp*&jYKt`2~XB0Re?HNE4 z7`SB^(!$$HmaqvUauM>Fq*M!}y#tpggtD_$`j#8wBWRn&{IJpY2@L9xLX-`4YL_f-F?Ws5+N;1dG zFHB3Tm*#}&rXpGDV90DWRq38>Izhrro%BgLQJ zzMb1JvXQkJZMjnbn&NJQ9Y&$HqDjE$&b&9Uf5UJvY(1jHD0b~8d#t@kH{k8u=lh?R($p5BshtA(9$jzx)We9m{jyaTXMYUI@`kyw>2a=NM9Q}&~?LX7|Qg#cf)u^_Vci{ zJYzCHJ+4?!smC3r${vmuluCGru$x2yfAzFtc|sQ=mAMk5?0W`xJ5v5}N{}*8Z*at( z>I>|5k%TBk?O7l%4(YU|>?v0(r86lF;dN(BR#P1j(s4rd3CjgZ$fiS(k%v_8oRaa> zb_u+^V@%Me4^KlYeE6TYk00l~0UAl3%XOMFy;$nRTZSDPi0(Ao;iN7IBdUfQq(1MA~i&%V_>GUKjMs6QGYu+B&&LSd+mwjR* zV`8!ct=CZ;isYX(MRTXoo5MW?ov?Vvz_2l{thr`E$TZ}@h=MR9RwpvelPR*DWPT)* z93I$w>zn%zvxRAA^vzM7#OR#Se=<)_w47&A7xz3xEkJ!OE807mT^CpjU9GhEC$Ke@ zJCQ+Gd%WqMA$Zyu2MS`8%dOPDdwhQP;o*A)1=Gk(WVLZ^^wkWn5`se}t22hVr2N`L zUrO#Koa(#AGB1O(mqE$%>v7DvJ0}}?qFQY^8SEl6 z;uA1boU5SB`U9Jw61&v~e`lJ%e_hX#x>e`@f)v?76wy&2{YYDRBo~rIoioBUM5COX z1-Vch)bIY~9G~0B)fJ6pf3A&Fm;sZ`h*47)H}%&cy(?cUp6$NST5bRDC_<2T{(Ggq zQP!^pWbfzOE}>qU#h#+6c~8szuqZiD6S(ep(ZhVW0^GsNex?cGvMJ!G<lgSH9zv)~?$J%7B^Q-IrOu{D6ULEL5&V&?$Yuo16$?Y9of5;#;qYGIW_ey#N zMfX%jFLw+zt57T?8W+;Kf^-7wi4bb9NG$Dzy&L&PhRqIq7cVD2A9w% zH`3h!8`2(bcJha~up6`U`wDflG5`C8D=8)DSPJNrBv*@+%R^2wEZWH^zvR+H^9-cgVlwRCBgZI#j(zX_vQU%YM>!fX%Ua zHj2lgYbtXY5Vd5bQmm*>*Vk?I`hPw@eSGu&f9dnv4?u7IvJkz$u8fLlf`rr1lVt|h z1>feP@n(BYv2m_697R2m!Ce+)*Pcz+XL<4~N&N8e!yK1Pkrc|13`LM6;6d+9X#y(A zq*G|EK3yL;Q|ZH=#eRCU-CxPt9B=c6zQD$T=$f8l$q+fJYd=fxg;y54^43tRQqw<_w$psT_+ zp&bsRK=3C+>e&73_dkA`(-KF(4(OsHPO#EhMY=7=b%yCi=N1=3?N`DWD6&VdHW*28 zge3`351D~9=^{Tv-{7hJ(Sqwncq$;TXA6KTf;Vg_%Kr5Ec|kplIC2**BoCC%fA>Bz zu!2-}43pi<_a5iqQ^jk}=#vF>ix7o@WD9Y+VjD*|SiO*b5Ckei#u4bjAsYqVlO{Sz zl;$FqcLk^N(kdH&q;KLs)fw^l^6qI^qP~6jpGBg>B>abjI@537lLM)23(sH5gbGl?Qg9;xhf7qv%yfdcU%GIm`7zC$9irU_~&d2MoOS5rrj$z4~ zp)ci&g?EKJ0=v~6f(8H8_DfLl(0*1$^&Q0p;g0=qC+YlqAw76Zt*s0>HJFtzbhU$- zyJzQQXqy=Y=*rq3A$q?US@cw2qCouw#TywBN<9Ga4yL%V-`K-Yv=~ z%;Ulrm-9TYZk`)A&#Rl4gtcj@<3);Ja@zxC3_<;v04!QFKF-j-5~Ugtj?)3~+iB-r zOZvmZ^D?&VD_Qw+G02!_8v(Gv2<$C<;?G+O&(BZ4tXJIFGM=(HWG;-ElYNgEf6|?9 z;nkjLbPFe~Ahimvf7x>R;ltA}i@7phlgU_Q7%8;D<_4bLV_GUBV`D0b&0JD~<08T7 zG7BK+jWd3hV1Tja366r<%*uOCZGV^M<-NEXEnth0Du^!7#;|L#TRk}x-JRmQ>d}H6 zsRp{ScpQssV@;Ruz~*D3+m|FTe`)?p%-TynqyL;dahmd%YUJgm@tEgEd!9sremn0g zZQsl|lsq!8C@5tN`^$c~yOxuZx?14gOR69f2!>lbKZ|n1TXeg1M!tse7QurIYsF#b)FjG=4 z!QhN!926MEv@!BX306~LE)+_yvq6OGAzOG)mQhxcB7mZMSkH;Wa>3|-p~EyY2g7nH z5CWbq%MR(8JDw1sL7ilVx;MQVT@E7Dx5_vxrM0D$M>~mrR)+OU|Fb)^12T`|PIgwy zDUT0||Iq1va(CZe(O+MSTkEx`aHzghRrQvVJU)@_CHeZ|Jf@;t6H&%A)a#vgc&Ov+ zO8fr!(e*&LjII6+NZzl1;DCQK?D)VI21YhHF>WD`;k>^%F>YsZubiyY!*wN`+C`ka zn;G2P9k$OSrgr`D?kcKj8k=MY6OlY)r8%llxCU!P$oZj~!<850Yskf(B)8-Z4W?XK zC5ui`OAvU_jbEciXFmeSGp&Ww5*UkxGX;u@ zsp!!w0BH7;4b(N+dR!x=1uY%0e4*q!3MA+Qy0m@izW^vmL?9dS9bp`)kUekyxy-Stp9@paHMD| zC{#_2hYmL{PKDHHVAm!1vc%6P`SJ-SI5qJT1x8@R(Pb%N`jZ5)?6RxoBOYIXGu3Y4 zc{*A3jsLfmmN##o{$~~2g7w64Slq2Pu){e})WwZ|oh)w0rA=`E@IF4f+}pw#J$m4W z;`-wx~f7F+gdR754A&=*tr z@8*6xm)q{u1A9DHmRMTGJkc@7g`HjYo2%f^_~6`#!yt!&5A9t)q3wyIHyMq)m$CCc?TWHjomL?xwYmqBPfmS_~J z;$*6i(-KYg5`AO4L_a>f{_^xZ-+=M{WTY^E_Dz6A@+3(e!6VlsMZs$(NfIQ$Pmd;ZYgni86LNf~whatr})Yu%x9@lz* z$E3Sh2O7InYZ9&3jdxtTB`$p_3tK(wt64di3M7S_MrS8ep8jhF=#Q$32JA z;RN+6_w_Oy;%=hA!T*ziOd*u0Wd^5+bv^MutZVA5UkC;32_*B??w#}woYXscFF$lk zl}v@SE*yi!o~RN#yeg1b2Yf~8E(jifmXq;Bu+DjzdP=z6J9}PtcxTu_AN2|@|9S0v z&6!9izy)-Y=%Bq~%vmu5S^IEL`I^?G_+p-tJ|XWL7aoQT&XxfCjD35v`M-bj?*7y3 z;{se=jC+W>RjhLHdfT}m+Lvi}B$UG~d{5%Lp7ri}oNG9hJ7XMhAZ60$a{F3;wU4>Q z$4EuEkYQeY3T}t_w;P3VYypsQ7esj-mMqyEomOiIvSd4B$?nLKjn{1y>*u-cqZ)?1 zBVap0rL!lxJ2fHB12NLz#X{vKD7Oa~#XB&N1)z08+8J#-vC7vid9t)N-eB>^^#?Xl zJO=1AKhI6in3TfUY%{S%ij;f#*zT=Ur4~Y zye{bki72?XXp$5j6e#7e1b}%NVE{l>QW_9K?6AEs^kCoRgAbg*NNndh^9-B(f2)$V zgV(=WE1>dq@P*OKR0*zs_*b$&^~+Z(1^oxL@K4W=AJLffI&D*H%7d{05MdWX0q`J z^LM$3>vu>;{X*t%wVx?Tv!8(+O-zQu*2Ai`pEZ}R)vxfg^baO~1ltX3*J+cqarpX^ z!FdKqPr}ZkGqF@AWpyn-6z7EbUu|Bc&!x#VW|Lc8tFLPXUMqF1XRCMF6I$_GjgVd5 z62$6IG#^y~&iXciIrV}r0CScpbHEkO`r;v_S+>_dZ(e@=_-@e_<6-PJlb$rT>Q*#r z?bj|qHI`Y~0L(vsFOqmr2eUFMW0{mzCjD3@>b2+05b6Z)d?!7gp<;=j?cf|2uYQ72 zIT=Gd)dfgeN!_WkFR4ZFpy-Y6g5d`kj3EGsha{SXk9)C_fd(^hp2slGb-EXicl8Pr zJGI1}8ADY_ui7zo5W2LsS%)BSN8E;#vxs%+jG{yVW;qyta|!a7cT5P)u5>O#q#$rx zB^4vkgCeetgsi>s8+P;`YKaFG0~b}obb!M+OoRD_niykhx7)<$PpicRWnYbOG90tw zK}4zrjb%T>W`z~PtKUR;X=CEyr@{_HFfZ`0rADAG`ZWh0wq#_= zjxt$};&}0YqL7rdna;P*_wOEF<`Mv5M!!4^f|FE{(vE>L)96Tsip+LL#i;X#A)`!X zkT??hIgNTJfwh3d&#Xsf_HiKx1o;nhHf5sP7sW@d6w<(pqImw|xhQk8M8r!texacL z{_y&;biQ6vn+of$kcBrm)1$!p;&khxdw6 zWPzU$3s?Lfo7gu`&+9_|a=9wnT|9tBc2zA)HYhUoEftG`{DX4!;o;?FUH)MV&$FOQ zi^)rWC)bh+r=3@{ppuG@01D!oG||4^9)Fey)AcC!<<$QE3c#RRCpA#SEgyUf9c}sI zeb;*V1M1-8)9YrJg>(d>2x+z&Gv-XTR2g%_jf7E$Kcd5qDczD|M-(v^w*i*l5L!Gj ze6b|9Z3T*OUQ)9noW2G14%eZvNfTwS)dS9d4~v;UAYY&EpC3NH{`BxNpR~9Uy#pz& z5P&|5IJxg9uAtuN3>bK`&tyfRrZOEH5KDsPTSihqr$kX6G+jW|L*M|jw^lDD@h+U~ z>u1p1Ll*2VYK=)#?QmbxlbHDwpXK0VlF_#-R1yK_10VOGHz%_{>ItftqtW@P48Yf(c!?9a)7~T0t1SjQ8>sUdzcegPon`fs99WRCcr= zvy#HzSu2>!3_)*)@vy(1&B}=Dl|9$*e&j1#i@31v0ajd-}*I;v7pFkFzC9Ly1zW5k{HdxTCCT zG*X5&NU0n&cByzYqOs64&Z#Ih{HcUJLCwxq+52MEp}|v?q%l=>cRltt0;{GqFslJ* zyjHu=Fs|luJ=XiHH7-sCYI2$&)DTS-mF@F-f1D4RWz?EA`KXa!kD27k{-B9#a$pmk zdeQZ`pB%$dZT-*=>@OxOXC2oL`gYJBDy9U^$w&wBf`LJEulF_=SNprMjQin-hoz&in5;NCLpCgO4=zN@%7qTWFzSK_Dwb`hXp`0OP7FMV ze|2z{xC_a7N=x3HDz(3q1^1zNYQofc&cM+!IYTRQIEvXu^2T$cBcUlX#kk>t{zg7t zpWgiVw15d!8mWnO@EW{``bpWAgVxlGorDr}yP19LBn8w!l&Ofgi-p9}y6qZKJK`XL zqa)_Jl8>BMn|?AKFK${IPGFep87%uQf17x>r^kaYqQuEZPE&nq%lh;fq| z7vX>)jqJ#8311;Y1uOTuaQ@aCf2rLf2Kp1FnvN+_*+)BP8+sA);%ea*<&=vg!n!URdsp`?NccGCNxnmKd(ao9b)AQ52hnJUy z5A9Etf6VO{VIakx6zqgEM|#z7vMbfEXY?;n;Up4uU=qc?(alLne{ljuG871LjP6#E z{NwY(3*uk43IsYF6NAV+SKQ?yxPKVMuCz*wRzuv12lQ6?YWcio9a$pIawQYb(rv{H zlMBpf(Ch@xh(;c?@)m!A;=!2++F}nlUN41$KoF|}gL;NucQ61GB1&-do`6Ju2f7@+^pJZ%Asmf1si+x5G&Pu4sqkCCx@d3y7YiIVvS?$-u+N<|4NF@nq($9J?!? z*OHYw44w@1q(Le*K<^gE6c9gnQJ?uTty{=6JHZizS1Zthy=)P7`8>OPC{8NxOEJ7Z2_U&7vgE(}GZkM? zCS?FRj{WeXf7&!z`HL*%oL@H4IM>|$=Qk2Svq&4CF8Q2n7BM#Xjhq98w5DH(MjRkz z9e?>9Z?|z|F;Y&GtQLyHx8xy zk!O(38^1g&*@Wd;`WCnD9bR%Hv)kOFE~~lVKiJ+gf06n$)+36I)WsO{|Ay2N9^NoN zOu*tSsY>eVtTMK~7m_)DD%<+H=svzYeOT#FRSG-NU9;($nM26X1(!XX4c^-O9<4dv z$t}Z8*(l3^<*MZ3fjva1E}1v5fWVY}ph7qyL)_+d43-FtYZE1-Z`hz?FA@X3Y$Kbm z_wR=Nf9w6@hlMbCx#W|AR>2Ktk{uBK8A<~fq4$IYRnK2UMe=RgOf?-l*nT?jyHA=(vd3GSbet={B z=KXm8SzHsOIOq@Nmc!r!GicCwbD&5#e~vd~<3P<@jfYmDr%y{&1dknMHcbQo2dD84 z`7*I;Ff<~pnVa1u&k?XaZMushr*}$G3Kw@XeGC4q3g&{KmhIe$Gio?%2m|*i7*6Mm zf3bdfmNl@t*WbE#xIm$idEiJn5QR951f+*Z42qlF0;u9ax?kjc0$~f@GQ6tH-js$H z#rB>!+!JSSNr%Gy1K$C8ymH1`8(S7^bx0rz=Bm!ZhlaniNIgFb&FxLX{%Vi~*e+lM+f@S{s>G!!VVE4`<=fh0V!ID_aM zL?h_L!FU?;d#jDS|NQC0*4>l_)T2)elSGHz@ zx?l3FZu%AKc-A|FIu6G&3oa63plCsLD@Vi3|GHe14Fgg?tnx%Q4F#NPv+$IXe{f7?=ih+CyBTG2uvuS`XKsVFhh)SFO zcI)eGmm~-5w@k{7FsSb6C^rLjf0z*lQR{qYu*Th)vGAV7tFhgGF`F+Budk0Ee_SF7 z%Fs3m|4?m}Y1;c~5W1~AC%^0ZazXKtQ(!hjw?Ns3=0`y|GEA78*AwcN*@}5yMrHqYuV8M9d8bVaxcdgN_P+0BbmV@TapXtZUg~e(*8Rqfh9IkWCFF?^{0MC9Ty zStJIsz@ii)BWbAEi#1!df4>_dT8V6?i3ZNXUJpShJru8`L2@c5Dd~lrEJvX z)88K-Zfb9Jb8W3|A-!c#9K!Pu6=Fa@*Iv>-XL0YZZr=!c5uwlGe`J62&hD(GqFbgp z+--&6@MqkJv$=JzGs>N1id@+Y<}rF6DH_Z#^$O;3+s_29deUZaP~J!z=F)XR-?(+7 zU4Hs?CA$biJj3b>g=l45?zvSF9|Y{b9VKy13IU)lsy@JqtUDQg5ePVLs8KU(yWW(s zheL_KS)>PPYXvN2e|{^8`Ms#w0?pIsq4OL3E zR!iYvtWTuY=bp9dZz0+IQ2MkW58o@sw7?fJerd=cNFdm{!2yv-JVB0rL6j+<>qh}) zVZe)$9>q6tFh+<(#s^0;Uoxd%(ZGd*0t&93r^6h_G_)mgzf&zCQw=#7ZaR}4!lb8B zJ$-MeZ;2O(e^OpOjV=ns!=Z|(9FMKFoESwc7qH)&EQ1RsXBY|pQnQII68deN%VX1 ztF8yV&%+YMIMu}W2eo0rO2RO z^DYu&O_s>Alh!f`Op1jv^(RWDqYk(d^{ftGcuYc&9*&|;g!W>#cWjY%KnaxIoOhW+ z&M>$*e-md(yk4QY!f7ZS)K3zk5}K-SxE|3~O%)Y-MeT4WUtgk%3XNw%a*2yyBrXI3 zOPyTw`GjDO$4Exx5Kx(ZF+S#J83xsS+?8(`A%*yr>@s{* ze+Ti-fti_&)x+o}KBj}tVG5v4JkU0dkYss@hIzH8GXOC_uo#B%FxvH?wH5lmAOXWW zyg~%~9=t(VBp~o!V2GW0;45qf1R!K3tdKE^rz$vOLnRR)m;gX%(Gg#dl0>j@#byqS zGngD~tJ_2OsUmE;0);_>BaA5>UIq1Zf6nUJi0o|k<20R|U5_wt>nVcy_$r*udOrrO z$}eNg0@v@I1}LW#qO&_D8@oZqX^I!2@7oB;lNw8NW;wX39Fij`tF+*a4OW7FPwwi# zt(3YU^aQwrLIsdJ(5l7BkE7$v@UM=VB8`PXb*vO==1+=2YspmmkixAt3{r1Mf7<*G zqXvnD>(t=9Yx`o&i;i{e6&HldjJrQ*g`~BR;{wSW38xk-JlK%~l}iM+Z7n%^4)ICj zonf!}|IFI!@5($b%OibQ4~F(+VGHI9t1W&!M-h}%l;H3ATFY!-tDy}HIZK9Ln8!d% z8L93Ct8Q<<6T`=c7^-c zAL9SCCs#Ye574w7>|;8E`M4#Acdm2z{_*wAyM+QYL*eKV>$Fxl67a2G@dyS)(g1to z^!?2~E+Dkxh|uCfX{*#*nnnQa$_Y74S%`!K6M|6&G6G5`;v5{C7QhJ1e?_Auld30K zmdrFHuvhweWiVp_=FY)X-@RX2GC}DYw&dR@nRxo)hgnz+S|-)!*?GWgz(pLKv!pWt z(zdOQu!GjwHx`Yx1>b*)s1MbNy1;= z&8enP$O+!znKK;ha{dzGY$h#egaeBCi}Oz6&s>jnbH4{B{3Cfkf3X7NTUvWuy3_@9 zqj1hD zUqp*FjP#qfWhMxaf3F@*Y-NpR>U&TKUF22*Fn*!AvYFfu_aEO64e8U0e-(vw^_S0I zmFLCSGv&)PBYFUwMPo)OP_&(jPfyRU&-af@6w) zJmaYo$b(`1<^u>qA=ZepLCA-F3Yg$wTiPAO3P*g?a6kWsO2QKcDI-t)NlJtsmKx}9 zMXdU;nB#yLaYzm*1pG^2vv9LLY;g&O!iOv}4e{MrywUxSX^A^u>{mPErzGucxql&a8U!oW*>d?@{i9;h#sF$v<;jouRR|M78AY5K$imw=cmpF*ebsN zvNh2^y}bN%|M)x``GX125uT492+O@=v@ZTLRnj|Lxe$fPdr($fx}%lb?M7ALIG_Mc z1=9jA^X{FV@j@ljGuCquau?mo&+&2?pRv@PsjGa|e*okDZY~K{r@!m!dVjk#-u(FK zW#N-43krNc{f!x8^1G}qm;cL!`pd_8)U`_|EXj+JS^2x(SbXUU<{}!Zikb@Mf*Yhy zzMknhC1^FW##?-TyIi$mm^kQfp<_1FJmWIUr27u3i z8pJ+r4B1N7&XUUO$^j_Ml(A%NO(sZ4I14_>zu+q8fD56#{saR(&Kf^h;hv|ab_(}w z74;^E#(#_aTNOFiJp1YdU)p=DieWmXHw-kqf5SCxQHKMNvbd9ZI6**9_Bgw^S$Qu@ z(c3iak}EmL`EJG`47+1d7S&-Q}7!zYQPhA zf8m7Gl8h}d^^KJ}G&1Hi%=L=D13us^Y5?*|N3FpXf$bH^RxGrQTmTl^)^4$AzIEY$ znos`p93FcFxzc(U=_1J30H0)22nSfNDaRakR3{%gL>9n>wn~!amuz?aOo6h`DWh`NURcez{+`aBi3B7U1kqn{le!r}pj}i7KwYbc$sWB@Zb5~L@sk!cMn5c}&af%dnV8RpsQ^x# zsL`F)0PSz2;JlUvbTrQX-Ylbs&(HIn3yhlXl!bQfqyjX|585)2erRYG5|z&c0uYwq zgix;siq`UH*-KWjQh`FwXp9qke;Ip+8ibh?pYYNGBvVL-cp`A<60O(oM9h7JUK@gy z7NXCN7l^?+@EMDQ9NrRkvVtSkv^|Twm$PVK6dig=FPk=8P#*J+9AQImCDy(-&;@+; z^u|FNBvEdxaz9n*i3bv_%QuVo$G4vr{Hwyf;=7q*JC%3>x*x&EjIVJjf6fpVE=K%Q zjS;R8Bv4f2C*cL)pFS}+Hr^lW9=-?Pi?I|?Rodxc4rd&t2OfgcQF1~YlQ52m4u}pp z`Od?>g>VK#X%OJi5#mI3hCqh_8Ayl40m_>WkHBFqn7=e&p`O@=GANcqRmBKskQBn` zh$$GRf41X*WY8cFa~DHNfBAjVs|h|JzrN>t2z9xmvN#i-_Ayz|r@~Af881Cq)8Ppk z3Jg1BMT9l&IdD@7QsZL7RuE((H)&<$Yv`McvTOQ&fRw;uUu}v^U+8gI9n+k(RZ#l>3`X|{V|@j0*sG`SDYv;;<%G8!si)d7*6f4yxNFm(s?Y+A;N zvb8R$*ip2&7F!74a8$YEK(l7lW*2xyOCNrR(P30MEL^WBI4Q~u zqWCZQ!>pgjn>WEc<+t;Ov*>d z8vOyRGoXra)KTJ?xw(8K`F0xLDR4XGGMg@U0CgKP|i51%7w5330ke>l4BgAuoMw8u^M#F@cO z^=9%vzswij&Xj8q>rM}Fa2&3OF3!Ked~m)31XjX6^z>ZMCf?!(M1Bs9A%hbCvMmrKEqiP6#y@~Zm0%MgB#W$3q^qUK!qa?DAnd& z&GwlNSwn`{WJ(Mcz0KJ$O|1sLRAs9*vv0*8$KsFI;_oRQ%Hq%0;!k7o$FcaGir;Y$ z2^iW?#T7>}X^h%qpeNnkfkQuC?Nwj2M4U1AVR-C?PY^EV$AC_R=P%W zPR8~s9X&1EI9-bbtz@e#-zv*>V{O%IZPm808fq(FYpYIb%S~!4PHKyi28nAxI=r-| zigKND=Yd7TP$Kk+RnArkT;-PEjVgP2dVcf%;fMRrA6^%NB+wNbiY_0-h~WKRB)5H( z#erZCe~0NtNI6XQCn_kAA^jjg5Qxsf5Jn09(Nor40_2P7j6Bgv7?%1hqxd~ zp(J(DN;+cUvZ8n+a)T-=K$1og!)_7#mbhxfz9AQPIS>s#Sjcu$f4*A>wt!^^|#e_`Q_ zFpg+HZQr<(vhxM@>XukW8X4I6`jMhoJNrlxgqj~&f|zWMp_;~WkGDXyq;bXFik z;W!mkv~sM*->G7h$_M{u!uR-8P%+ZiuTpeYO19dN8P494c2|U2Rw0r+izk8=VrA#B zGIZ_g9bzC=hR(_;S{YWe&d|@$e@y$GW)U1jh`0{_o5KOE!y8wv_&5@c~^tpbYo%jcnPk1|M2$nk8fUHA3nVq2KlFDkfC3U zpxuH@w#>O^m)AWR8$Bb-wYmnICzj9J9C8^wY$nN*#Z#%>|7TmQRWGBL&7p!n2 zc$ui|v=cHg8;(cHNB(q8f8DxZ-rfKBeE;*zAxa55Jf0Z(c4BZaR$wS-56d7tEj`x5 zJn13R2D2W1QN5XW1X{0pI8vhKGC^7SlL8IA1-q@R$K(UVtGwbsq$h_j;Y70UxbW^JFzw^ol7D49L ze}`pK@Cv+Vnivv4%u*u+)Z}+wCI_$h4wdxbVa1&i>F{8`f4B>D51KY1 zJ*R~xGq9{_YfHfo-ry);6h{Edsb?UIA{Y;H6ZZ0lhbwp`acA#$?Xqsxle%UBj~QMH z1|S3pOLiOz`nyaYXf*%iTlZ~u~x&Lv+CTemLHy; z9~MiF-&Nb^!Z1QO$WGM=6EroB1e3B0!R|FG&e%>Of~(z(sy#_XjD(w|*ttTq zlWy&dxbyn`Gp$|mRx7@!k>4nXmtP(pJ}sD9Y=n}ue@r5G3oz+Y;VHbsb9k4_#)DeC z%;D6a+@F>l=~oJ&{fMsv9v&49v7%s3Pw|oEa075{$zw-A_KRtb1s?z*M z!P~DWUZak+SE}My>WPYndX!jGM>N&&bM!FMZ&`@da?Kn^QRtrgFGT$erN{@2lN7)8 zfKC{Bc@ssdqf`-|$%Zt63f8&pmdS3v(QaP;{`&Ok&417L@0OUtI5fg&p+%hShEVu|{p+yO6UlA2fn>bc{WO@xo_3Fi9?e6@o)V)6a^007#`{R5UQ|2UE zt~Kg8by#bai}Jf=Y0u+8^00@P!a44dY5y38EMbHbN1i=zYEP8M6Plk?elQ+YX)jK^(c6GPPf zTndKZe~j-697-CaO+CHvQm5!3jwXchq%~*L`+vv#51;PeFBjW&E*CUwjuNPt=>;vX zs}N@88fMV}{cJXzU!&6d?AbcMK4*iRUnKo-m{ZF4^T+c-$!>l%pgQ|`0|<+mdM&3*@ouh@v87@V_0Xf%>3R3?#(k&Raw*P57O{Ex#6??LUhg&&?7vTf z^Q<=eyLm+4v~ASIH8IZ4+CsnRD0wk5)qnN%elxS-Ph2~H(jtq0(e{D2EMBs>XYq=~ z)&9Il#Uc@lG}P7A?c(nLTiiE_`&)Ig?@(#!FI;K!GVd2gWOq2EB|?<#M6C(ZSAi8!hR_|j8o=5H@3;(>|shgReJA2`-~?-5#PQLnq?*>X=r(GUPrx!!hcAOTu>Ds z%x%_dwH*zfDH5q(@XXq7j{Dr+!QAoP%(6bHazH9BOc9K4!hw?Y$oOM<1mv~1mgY^q z(CtkH3wSIwDIIkP-3J=Z+XDx}XT3P8?6vl#lkOJ&2Na~mu%vqxATFK8bkQ1Z5yC?r zPDBQJ*(vrU*$I-MvHp}H#eY#?B0;2&c(TCp8-$ogBP04Klnd|P9&vp4-vHL%AHa%! z+trIjsM2Ry`Z3}Z!J>5xWOY$|TR#8IKH29sYd35%0wNf8AYUfYSAj8C9lK`@IyPcX zohFN_?$#kf;rO=ohsHFV1$eGD(1$3lRKT4%sMlx7x*7+ow+G0em5|iuV z^;j`yj6^1oUto)zCx3^hNoKb@Wn3V)jlz*(FNlPOxWtj?MX@QKM4T+>RE1?ihYYSU z$~gM=K+i@gf-b#O&kH7TJx|gfcfxNWaTL$eCN#TGuwgb+D4t$&+h7eSWN2jkABl48q=-6nvypa)p19+uvm}K%)4Sa@McZ{< zmK-NUGjlm&0B0?@yd81!w8b4gxT47|qcXqTxP8Lx3Q9QIro54mvB`rEhX(%x89 z6jaiS;CZNlX!r3bFe)nA`zo7-zS3EqyGBi%ibbR_nSVND>Z=iBlT^D}K9zM-8cO}9 z3>>%vH`Lt_ceg18cjJD%|4dO$TLo2x9AO<RWUG~N6x-VWAe(}2Ui`S)JysrJ?b@3O+)n6Q!e{o#@#c=@`uPeYf zE&=1X27ip>A~24tz<6B-My>oX7TQv9a%Nl(ZbC-T(zi$qF{UzDb?B>}jgEoU9b$wT zXO6JdM)`E)-B=BAqGAv|gDTj~hf5dSEkd)NWId5@(>D+u7Qs%LwC`e=a<)+Ov{wWc zIl^MJu_KaLi}yy0KZ%itf75h|ec#BNo3cF{M1RGqjzxK~ly}#!g9||&MPSJyns*Xi z5h`XR&_T_NJf%V7Z6U{LYDD5 z4anyK-8cSJAX9y@$sn7t0b%!^5i|~L!$mPkUQv@cLTG%pla*o7NkR0Pc8h+Iy>2&t z`P_4OW-IuH>ng&XF zD2`L>0FPlBE61R$+o2co@ednwm8t+JzH-kyT4=WMGDBG zv1P;pd+q%^Lb*rGF3J;F7esnR1*cqmci?c^fx=laI7A9K5fAeOwJUK48A~q=_kZvs z&6_7l7QEY4h_PWP&3Eo@}M5)RM?6<8F7x@XzOQSJ@cG;-r6_N z2bGpgDwB*shScwb+9#ur;G`Qx_58rXT1ddszCq$kM$yl3hy+$5j{HIpY?d4gWp*WM zags>LP-T@>*)$~-FAdTO9r?<8K!15t_2j{6TEz%NtyC~T=(49hMGr~Qm#^}yN(&G4 z3X{#wG}A3jICE%57QE0bFT+=>^M1%&I-fylkgpw&*=2mSSkQJ`SKf~ZR55ym(QHuT|obdc1D!;I6L(ubcO zV({Z2-EqGzf{yDEu;5rU4}V`F0t!q0tRS6z@{_~EW%Q=1NrGn2V*@3Uj2N%yyHm9sRN zpiwYOevR$+W{587a5YLNTdmk<$JDHcpO?R{qIzuKZUar&n^X)3pN`X!uG@IR4Z7pc z*lw6P4_mO$w-<~?@_*mle|UIaNLe8h#qyx~9ck>DzS7d)OSqYjENk(IQht}ED;P3q${l2q{$-Yvfth<%A zXV6<1lLcVz@D~X)s!;~^zPxMJ;F5ONcd0oJW7Cn7d>HyIANK%jElkOHa*D&3)Ny`%Iaq8<4|GlewWu_zmWUZWSX5UdO+ zRMm_tiiVV*1$StX+qtvhKSb*Ap6wZQ|&og#(4BF*`uh=qbF$Rma(r^d8* z*790Yw0v`t@o2=__xHvZfoYG}aBOSF1(=p%D50ctYJZ+djTMTW+#?%xA(OMN_w$f)xXV{uicr^OrG;wHCv$Le~2E9qM@p}`azg2{x2-(ux8 zK~~$yHdF7R34}^6R7PW=8E1?Dv+y7k$t z1>Eki@qeUM0OMN`gH!-AOxzVxvcD=HJ z4#VZ8cFUFgBg5z{)cLT#w4Eo&4R?}(A&-ygqJQLi$i^H(VQ+0@WUW^Ciek#e-r8}L ztFRzfap8HDqpUY9Tqh%pA>*+S%7QO&_mH{7l4n0@iIK;YsDP9{G9K)!?S#2cMn*`W zj_jEsi&<7eR1&T?c|uJHqMsEqL)jEUz>;)EdO-DCpcmVkVz4)xkOndses=`;95lo=H z(N?;KZy_fb(?W%n;S~qIQ5T9vd=iR@*r~?T_<=Kno*m~eULlLPh}=AV>bkn_QZI9< zi8}NB-A{!9egd?gVpO0(QT zfLdU*O`hcdX&Om+D(DfN=td$ARk1nZ36=pc5YSP~qQKOhseXz7PPCy%c`4besDGD< z=Xb;|)f**pP+w-ym}pqp5802Hc;Xro1)3bGjPd_z{P4NWii%F}w3j;Ob*X)LJCB-_ zZ*y3y_eYPYh&+s_`G{U!6!YC2Jg`)9U8DVFgmu1{kVa*wV`jU{H2L+Wms*{*)FvY?3!mquC?ZKRT$1+p zSP+fVNwp6o+3g2yb)o&L3`@l?vIbwEv`w$Hs!m5Y8j1J}6iQ4oZ(vh&!VV z2hY>%%bTB`o*)0er;o4q9~Q9+^Q~H$Z{>Wqz8>dsS_BxaH>%xYskYk4E`OG4{=B#; z&EHX0SK~}R^hUP-IqYg5-z_rj7bF^SL9*c&ydd4`x+%r|?o2KVNxS*kOBVDV3-*u2 z)%7Oq>GRu#*wgUP&{()fPNu2~&8`clzW^EtPhA&^zKfw$+HEqoQ9nx*oeZ7^Q|XyL zW{PKl`;+&@BOLuFU0EmVmw%5Rp60P#il1c!E|n~(X%vpoKI$#_4rgz@>dnW8*IyRK zUXZZP*W@syPtRly9b&JKbM;HcpK_7Z&u#sX2I*!dbr9>I5bHu!vs$QK6K=~p84vKM zpCLZ9WNKS;quTC}GIGzLoK5T?ZmcJs?|)oqS1~M*+D=jt;BU*PqkqpqXB1tkxB(0% z)Qi$1Bez`N9?==G=kgIq090;^Ec~@zqhDQbCp4Sl{(O-J7VoA$Q($B}?v-2lG29B$=cp5;}Zh}UD(r8A)|(t%5^i+kP8%xsN9RQqxg z;6ki*)BXy>&#I_QB!3=+i+AL7VoJ$t;Ed%DS(Bi`@tQY>J9=w~C<@-uAEgGt+@Gs8 zRnr3#<6V;!3zyAY{POs5*682?4S(zRqF^68i)p%7!{Ue$K+p^B7pRoS36f`w=Z<$8 zrFJyu>f+rLAYGhe8g8U@wWXKp6u;}~k_y@y((f6?2PtM&fPXZy8H(u#q>n!G2(A*~ zY=?hsIAD^B!8Q7Z)Xg-k;i$?mZ#)S*$=W-uy}V#hM~MW6W>ruVvph zwc^%A^Z54d+Xc$QIPeJE<~pmt3Jipu@X;ti4UL4W>v+@jr?&$~&A&W4nwEIT(>KuF3^>*3xB+^PF?5HgcoX@&l0Y|y}c z&s|){{lDT7Tq9Ek)|NHIboRuV7yA1R*(If7ITNxNmYM)|rS~T&MV81jEr0&d41j4g z1%`H1U=@ry3AQb#Bhxn6L)V}K79iQ(@K4F#Pb6M*4Sx`wT+R6}@CrTcGjXG+boSY+fI)B2XX9v*YofOD>TnE#%(2(r39mbeM7E^;CnO*^rQ<2aRQAm% z8h=(CK$}EP5)2uqYNcn7c}@Vj;CV7D=$&G4&Z6 z{?sCQ%3dTuT`@?Oa9W*7V(*dxCPTDCY&&}ROB_h>D}@lG$-%WjG~gxGU}RJw%HQUL z4j7VbK)i6P$&OmvQP=o}8y2Q?N7XMc8mP9TV0G9(0kw6?`qxd@A;bUX-{6>&d@ z!6vg&C8@!H3J#La819MoY`8~)9p!UR_7!~?v$W@{$;n?W3M)(ZzL(pJwS#0dkXX;r zqI$!@_J&Dgd=op0-9{U4utg3Xej24tieNKg_h@uiG^j*CgcGf*magxhjQIX}!GHY2 z^h55-lT|_D<^;&~--K5_IfMWk~H!zq4SWJxs1(yt(e{ z5EgZ*q_J~neL;kV7`zg(7d&(1HB&sJiMTR(TCbOLm@}M{*mFkhmM4Oku+7cr(EXex zZbou~H)A(5dxVTD^G&P!8yGvsXMg&6YF0#Z&H0Yy((v#`<$PK$v9(N#?*$uL%7+lDp6$K6ua}5ln@vGtbpl$H_y^H{WJc4xCDoBD<8- zVZrCNZP6w4zQ?f>jygKR?bQfp7_?rjB@K zW`O1I0YVPBVLy7B<`aTkJc9?R$07i|hcvc?B28Q%OAlqt=c?g-et-A(o%*FVEq=vN#8WUtNjdHMChlmf)z;IRx3^s&jwOvYt>XFS0`Er14yG5 zloOzgsKsQTbK?7VbSjagU3~wPSfZ!^;hBcDAs!A=01;INOI$+FgNh7TXM1fP{iZO$ z`_DhWef#j?!(2?z{C_wMLA8)6Z(FPsb~+qdPnK#hVQWK^gDC{lP2xe~QV7>hWRPa7 zpn3-=l51l=#BEr@U~Zy>5gPAK*MdSr(0x2kT7xt zT5|1Jx#-5c;Xy%LY|PB^LJ)0MJC_f$c^pDx*pvM})D{K+43=5Yu zus+>+qMocmI245y(iz1=Dmx`&$FP!@H?22#Y&%5PcA76z9P`lA+g9MfYk4^H|GQvZ zpxn9wTx{VODSw{$9_+EvQ{)woai_yVFC%Y2qA*Gp5^mELly#_g$#d6R6bL>22)5)f zXNTG{Bgm+5pG>c0^adkshXCJ`Y#HS~wlvGbvOhiCKfnGoH`MQ|=3*j`IH&Z)AYj$5 zkYK^!!(52Nd87DSXlal#HOvV<`in>a=vc)>4|f&@Yk#@54icZ}Xp>U=;5yn8CNnxV zL99n)E=n1qqe29=EgZHw(Yis#p)el95>=Ms8L=ux_V2jOW+`v%vA?NF5x$z9t&+YQ zSvwlJc3?D8sv;X;bsFyg77E;D&xKVQ`W;com&zN5wmYj@3A)uw;?=O{PNW1y+{^bw zcqEc^)_=4^?IOWpL}b9B)KLJe(~>DyQ!&fDi9UpGBeGyD)1~j<2h#w?md)oas|C(u zaLRC~2h#}V|A=7L^JW9tQ{)jV3K;6S-D)|TWHt~mgJKwxeko165?*eiBLk!4g)HU~ zi&X{8*v?Zk#3l&wGQ+CE6D^spY(dpbaF2KDi+^q`!fu}o%-UJdPe%&mEC<7$ti2XO zcd?d$Xo6WQnYJEwK9J}V=g^yZOGutX+k!+x`Og2Jy>HoW8_BZ$6@CD%g?L8{Yhj`R zIpthwE1kM6TW(pdth!%+vG+bf0wCygR%d2+-|m5}AP52hAP|pp_9KSf*hLqLThy)wCd9WlAZ+O|cP& zR;j4kw8Xn~pyRw-?LDn^yNIrUyCRHQmS-?lC5LD$B~Hx<(~DZ&-i6)fQ)OIZ&moOE zAEI1hv4ELO7IBos3Fy8vs5rI6y}0JO;H#GR;o~xD!S)UHfsr$fcMf&ta@C4X5r6gs zHHPdgNLI`OR|W^3)X}6D#huXNg1O@Q08l!o8WC?S@8p;i;ANmJE1G4c@v^OI`jBWK zsnD4^AcmZ$+tFyxjayK5m+QE?;{Wsber?5)zU`wSP#nTjdy`?NGWPYO|Mc**ij+v|)P<=trJgVriwOD=z!LA{=xGwYqdPR>e2^Ai zY9|l(ey-QXCBi9>zW)UHGR_3!W_>mYF&VQ=inqF{UggwS4v0WD8A~jHQsuNn8Bveg zY7T6!TtTr$Ih6&J37|7^U4KrJdiH0!3%M>(Zke`hSNrA5F;HQu$Zb=@Yv~gxOHr->2?q_b`>PkPqy#( zhR=gNJ9OVM==&qc=zN{+@ik<9(dCCsi}U5)1ov)$PZK#FVgjiNXoP(vHd zc!}mkTojI?(>OAXyn9*9S2{9bK=E=bE#k5(ae^}G?zCnmVw5g#c`tEzL>yosdVT7b zx2N|jYLQ4;qb0wKysJg6C7PLZg?r3?M=dk>MI%bFm_*F%ciZ;(MDd6)U0KgHcfqBl?N)(NG`2^)y_w${UGIhjJ^|p3m;{yDVi*MY)#>Q zh(K$$q>^uuI)7T`y3DFYE*Ao}15$Vd(_pzOs!+WrC5MP8+b$z-W_RQ9#%go1WpkJ1 z9z^D-X?ubPd{P;Z1Bo;u&n|&4va*n92NPDI62jm_rT5a-N<2_72D_KEtM5At6GfP? zR1BkdL(L#$%!{f5y;e8d%7@1*+lNK_gmaXQXX^w^2Q^@w! zYQK@!JLmed4LXL?0l0!rHgotM(zKPH{ zr}M-w4u3>;^4H&K27g~J1f&2sEoMP(4Twn*c!@P>Mi$58ZRfJRvV(VL^-hWqdqeRk z?N}v<Dr=JI8}*vBoY;} z9VYjkx^_w02^W+s+2i!~_q|jS!o5;%^uKE__4tqXPj8R^Jvyq6S5Tkhtj}q)F2`Bl zqHRem)Jkz?Y&x=!XqT=9iaz>W#r&;a{X@HS5AJaO)valo``z=jo6qByhc91N=6wJ0 z*MH>?9gPQJzX!pls5Rqkk~k8(!2k)q4aTqkmZ+w_D^!PGjl0x!ttE7l|ucR9*teOKuDyo``uWT|gDG;jG<7;Zp`zaa`(8@q>H~C{{C8{YqcS9bSAM z0)uqqY)2NjS2EN)`&z>q`!5|_N^5$r!e~I*oqer4;Eq}nAhC2V;qZ|Tu?#fObAOgd zo<3@xi#y--0$Q{w2ZCIYtENo(r+QaR>0Fe5C{t6}lP{;!{6xu+>2QK7W+htu?TEcTfIBuJNzL2bgbvuhmBnEWQ8ZNz{0g4mm>E5r5U(%Qa^)4v_ez}ucZ zUzFZ9R&cxXEuqh$G=l{^!-9%wrGF5NO%Xx|FKc5I8Ie1aKwOVpP%@uIgA5XCfc72* z27_!j^Iwhf#YkaO!pgp++~O!{t3b3G^(Y!AJINH8q;C}ZK7l_8{RlzFXWM6nNZGdj zbrEE||2XReJoe2u;p=iC^j~g7yFG0D5#!OHHeyPUOQQ)hc)s-^sE<4{4u6-5C59{w zQ#J|_pef?-Xd@g^{Z)H3OMd%s=%Zsr8n3v^sOZygFM!@&K7ai7xaE zor>qW9?ytNAoL6Ikblk@D1BN;Dq7J5-2#T32@DGq^H-8?259DRIo9^=+DyHWipUN> zhrQGyyiRmrzJGXLV}AgU6J!uN9R%FGPK+(J zG^RHKnNPug+i9VGFfH$|bPtA;i3tM(v6Zb_Ca3BKDBW#=&9@h3<;H&3k%G5h9$!B{ zzOA$pK)E-;=45W?6kH}gfgJ<6@L5t6)X4y8o~8~2>*atDVv7tM0x3kbyhPt5eET;q zbaptK>6qT+eSef~(U5I=J#eNk*~t?QFxv6B4`{QrgJA!I$?PwOUeKhR$j^#5#kkF z$;pc7EPqX^H!7hfdcQX#dJ_tqUj;2 zSDblE+@9#VY(UT5x$Iisgm2CX-18axYS2pY+N| zp<&>6;k7{g0&sQm@WP5&G-LTSfZFZ=tY%4m5+QSc(lKc5KpHtsF9?IcazpupDxSzR z=8$b*_h!+G^#&)YwSURjY=ML^BXqnJ)wCb@#51RB6cmsKKG>9L ziL0TG`vQ7H+4rS8Y9h2Ro>ngJ;XW_mM`um^a7RRF()q5c3MT4en~*O!ZyQ-g-fbss zyh68t^UXU-ZfsHGw!EYTl&G!0g#`#eEvzII>Gn4G0F1KnET=K;R#5%wnxmvcZ zfv@bmG|sl6|LO)FP!t67Xvdkc7xtI)$!Sspv&V`zV``cWRsmyVYjjwDNYCG?1j5TG z^C@g;jD`fn|DD_xX&%xT_=qGdSM(HQ7okFOy;yB+*M+oBnFGjK< znBA#uFC5PD-MLsO%%U=p{8nz}iPOvDayvB-u@+Hb{I*JFP)u*I{ihn7%d3`3Ldm!5mW}ggQ6Tcqr&w%fKgzHQD^0EXTdwIMz z06U!~%L-N;oiNQ#a6yESA_QUY*P3^^uV~hbon=sMS{E+l^S1iXf37jQ?Qd8$&up(R zAEi${`<$-6Z^|~#n8ZMg&xyql$)0_@{#r766g0yBBH|WKrzMbHf`3UHb>fP*S+jjM z{wsIky*75Nj-i9<3>$ajdToS`yd5+-Mz~l7XVc{&ZQce30BINFsG+^H;~XiY)$S1H z;8YdkP-D!6f=|uNptkNjRiZpoSKbJ`jq+nzma&8>u~(1uhfM0$*$Gp;aO=^Ga=600 zt_zy=DjvNkaZy;A1b^LpJPIs$$zzyWC}|GA`Cx*1PZ1k9$eyaNC?K4Kx2=+PG>9b2 zB_)-GAy~^;ayV`^9X@nV^j_Agg}$uW^mQs(tVvd2jGk%OQOJh7gH`+8MlzBW7nK&s z@>Rn!f!uD+0R#6b9D{=q_jtFUjp&lcFphLlD)RDaSu*(8JJce}p@m&YLi zUV~bDVBrfjULaXU5^~IkPHLNX0M^E>$xENgC~D1!i~w{4M&hVi$~o$gxB_Z~Lp;H1$Qo=O++t=k3T6cwP&Se4DzwMo3VdZzQwi(cI= zyB_yr&v4e`y7EKK@zSf8-+z<&WVK1rV($1uji73^kAF2J{hX(LZr@F4;(S>}@2ZqBWDgi|8LCPWxAw?_|5@o6?-kiWy0JM8#wv|-M zT0-Gn3VMytCfBj!8)eE42{Z;<4oYrt30$Nx#VMR;MXCv#@uq7`KX*Fl;7R;FD>ZQW zuY}8s(*h3SEyIMpqQy_wB zw8hM;^{au>YI5izP#Vo!lY z%k>VYJd=Wh0QpA#x1aw{)YLRF3g{gxM1Op4NQ^2vtF)u{fKv`#OVqUF`)8&fPdD%3 zyHAf_zdnBcxEeWUo>#~tF;PainlymG2av=M;?tVzMhLngaee678ONgX?L^0z9X0`A z7-e^s|CZUBAIzsMi=*GqXf;^iw1cI-F`o3KLBUikUAB^EAtMik0zEbB=pV1m{eKu6 zH|OnTX^R_8yB`G4`*@TKZI*NCJstMUN>=8y17DEXffGp0aSQjsmP(@W9wy!gn!bs1 z$-jj$2f8mga`>1p^w+h#;^w)PBb8q{PKA{t)%tq?U~!iTRy3SA^#}A;b74j?QBGDk zZKkefvmjWbu2IlDI5HwO1WOz-+kb&knyC}2YB;h#DE&)12OkIp$y8*vE=mfT-9+s` zfXoRtwJ0dC$GjG6*}6b$WS%c{U#dz7SYQtt3G7trtXf(?>LLswd91WyZ%n=!rGzEo zjEnBb>`Zv+(6v-t_mq?o)F4MVd1@BZiEVsSz@&lQF{hW6fTqM5pi&PWdVgs$`mO+g zNXrx=+u|sB(CvIPQPu8lUXf|k@EV%rLzvl-@-|L9&88h^TbQNOYgv!_x>bFBgOl&C z4@<{e$Q4Y@7O0A3mLZ%4Gx8Ss-S-Z)x!B436J2N-uZHB%HAiL5}bWyXs=_o1p+lK z-omG8-KT{JDf;`e&>=-Xv_z610kZ&;T*;&S{P+NL!P?0feXQ@Y z>&Tc?DT!AACgjLYG_rsb5aB}uf^VFnLh#;H^jIOOXjn~|wUyX&3xAxB^Fb5I8z@Z& zvqa8`cFL6pYM&_t;*G=P?xaiR4~BkBchdD0qBT>B&oqRn&O-=R7QZ!1svH@u1Jzu( z;-U_cy%4A*w#u-U9%ssWCxjZrbB~&J;dP4ieL5En(Zv+K-=O9G{P?;YOEOv@=-`bq z0hRvPEgz*F4Gmp{6q8x<4K+2Hvq|piQvVv=<>>lP(S6~2c_twa1056Q<6#Cqo;%&4 z54nYQ-&F)Pg4&DJ(y4ft%p%#7oAO=+pVn;Dll}5Jf09apO@57Y!3v!5ej#ch8$u}K zz*KVUlFzk`(GYj|FS!P zEa-jHf8qm(Xh-Z~AS}#ri+q{{bxo)3rZUy}aVb0dr#`iT?`YSul)y7Vq3TA$!S+C4 z_#peZsgpdAK#;n3ogHEOa-LtlefY~RM~E)QDJ7K8SD3L$nQ8OgMi(PS1WgI5ICp^W zcbfoN2qZSvMOF?EFm0hX6dtW+7b<0Wvq-T@e{J5L50B4JpRTyDf9`wg&Pz^M?E#hM zDL%+MROxAqAZX>POPPEQ@bXdTAbsmKB)WmSl?F(`2js74|}`=i@)#KRz#K8sEQfi`gP>*}~?}ANvECKMq-MvY!f! zf2MeOKT45{zyb4aru+dKKOsTvefZe|0tH&bq za9HGd6N&edC7mADooYp?g?+h4dRK}NRVmqWFAMKL&edP`;MTx{)gb@7$9Q{mHfNY_ z?@`{wm?je^+v%z_4mUP!VqNc z2`S4yS6NINx9NV(}xdBp*Zz;!izg$$lFm*?x56rHbD{!&*v^RHq3&4e|$yz z3+oXXjAu*3IL$I3-aJjgPjE8b=o#K7};*lRlSmP^flypCG@3?2+JkFHHs)e_^227&^8B)#(*8#)4Y%G^wNJs=scw~U zm!mMcNJM_fScxN({o;KFqB489bQM%}{r5*fMDwvERZeD@k@LLM2WmNbd=<73_<>CNIQDRmL)z17l8kFr2*5ZCyX% zB=n-PVweQV(L~s9J}1rdJi(5-vsk{1hF?Y|KLS!BQMwTzoCr>x+n9M5p$$K@qW}Rg z@F>Z+6E@egKKQCqfBXN~dzbCFaV%^2RpJ3;E#eLgbHyYE5z`oaGo`IetJ9YJ%W`E^ zKmE_W_W^@sP|8a?tEy}DAkz?o7Z3zN;GBI)TOp0>AV^wD@&weR9%%jnX?j*f0`;e%AAsNx|*!y4m2#mom{uufBoIpabkV{_tuzH;f%2vE(T2C;pDc8E3-MH;80xNzl_bWvWr$FYV#AlKmVWqfMYFD*oQ#I1EO_GwvxT6ztuspuM|6b zU%h@5E7&CZvc%`un{P10c@A-KM4*8lXe6>Rpyy>`ky|kso&jZats6ekk3E?u`dElG zaXjT4`7;e%`om;#tX)250<~k$Hs&5Dxb8yV9$xOA-`%}`fBN?I<>CF>#Q|Rw?`hP% zwr@xbz=#|Zyn-^AC0wivnyd@zGNEadjlfA135&#tm_tfMrZ~EI8=wNINjcxOU4i8e5e$Utnn}D+rK( zlo_*!E7WjHZ5;tk$=RI5%1keAP+_l}ktuxnX1g*KiW3|KPy(whSlGYqgVCKCjE|VC z;a}m4Gca_Te<9PDxO5=|De2d1>DrAb>c4keKw;I>t6eM9UZj*o+hhC=VquIT2{PwrvR7)nv zPvySF(Njy(!}zf8nr@c#c%8T1N~>;Xz%49)k`xUan@G-Bz@w?!Ngz?I-);((p_7(r zH;L^S6&WIY54RlUE*JIOq7n>IPq+U=eB4cxp?s9lT@U~;vtaaETP-BP#_7RRtvXY? zuKVc6yZ67`KR@38y3CAVBIKzx1Wg~;QT>?F0OlK*3d_=mk)nc=DbTolJ>H$bJC$pF?iy$v;%3?u&<4Xh|0n;V&ay# z81W`bdmew&rht_-{HHKo<*JhkF!;bT9W?B9Q77#+rvNs|b>4KiYzO&2rd})j-FFZd z&koi%iSO2RLp*+X_vPu~@#W$1=WCmP4?t~JvcPj6L;^#IXAWfOGs`1gQ|5;0Bg)(& zIl;1Q_KLy*zbafM-GQm|P~?8>hJ8_hoA5be9J$saUW!J}?nsztG{M7cl2=|)N8hGm zsuVP#gyNCW0q;(FXyhu4^Wcp(S@(>=9Qr~eO*t8<8(%TwC#PzR<)!_pQ|{e=yF2O_`>c;w3zQw=?1Jeg6?W<#oU`mHaxIGp5~1pnKer&m4da}?E)i^TIhRB{ z&BC(L^j>TxiFEmK))FUaG}0-o;i+jcFZ5?K)^}qAG@_77w@}1wOOSw}D(MZ-FU%&4 z?WphMZ@1IHTYqD6yCQmFvL*aDA7{Q2{Xl z&X@gB0XlzUSmcZ;_rCwt!@j@!@a5yv;|jAi-Ujfo2uQNeji0$0t(i;uCNrM#_AnKg zZZFLLY&_I=1I;?;Q6trWvDov=o*C9<`@LSpb)vp-RL7QcnWZR0VYwCy;V~$ITM^MgfgLieN#efN&aWecV`( z%RK2fyT5Q)7kMc~gJd58<~o>Ddj0IE zuNT*II=!MbilJ7FiqN_xKP3?5om5p_ce{Z;-hKLMMQ$4hVbYP~k$MLlvi_%y2BRr| zOs27t#|2)m%)6hyefqSL8KUGKePf6RGUF2Bv?{)&A;#V zB>s7W@*54dF-k;UI;tT$HL8*k#s-5J8e^>9poSut}5;SgtR zqL2?YbQ)ELGxYTueU3+8B+P63PFbKt4`wHub&B=~GUlblJxH}+ zN4e;6RzH46j|JdE;H~xq6KCn94PXs2y%&kb4VGgIJv!h>r?wLjLhB_dsPNnY(#2$p znHH_WwL8jGr&S%rTVxu85_Ca-LN{Dm1nOl)WgP?L?s%7H7_Q-xvtUQh?@k+-a~wbB ze1F}P^SEuh>EA#t!rB!RVMRAP;nf*M90uIU0!X5?lY&~hdi7vR)&hen6HI{0QOd=v1)RJE zqS*liz6qH(1SotE44(nEAZGJk=5o~O?+pL$B+*C*35=pOZ-79-#}&vN?8=RdwP3IU zdC&Qo2_Zz&>LD+qFn+5k){6jqjw;uynXnte1M)KB0fd1*;K|>AZ$i3x%Nyoc-Jj1B|7Jc2oVmp`Q|}A6dYlvycGL)94l*>G zwv$rLang)W%;Jt(!z5vl1TZ9p_mlqJ64F}+`P(|kzr}zTpfs6Jsc2^Xwg^vbtTw_C zf2~Zztd%!Ed0Tz#y9pCA3rmkJKS(q*PP7?v@%fvS;*85ctpyV)*k0*-FGdJtf(kdA7p?NGFN%;dKREvoG zaOqmGb|Y|8%FfiJON+O%;N2!u7nR(Lb)9ShpF~?5YG*S*oQ?T%2Ff67&KV70DYPhT zM6b!H5U{GDnX++zR#pw6D5m$FjMI{wE`#-9FL%tSHTJZzbdI_iag}85teJtMKzBFa z3u$kK%1y8>Wj$aCeIwAkSExzWo0)FOERy-v2-B%_R!+(gHLGZFMADmwHd{ssj$3sk z*E`Z+D)0l}{TQtx)ZyQo=)+)sLe%VS<}KB@Sc}5!%bFp7i)toRJ22hUc{ZtiX?j=t zw+L0jMl8Y;D3-}@Vl}`&-HeijFC3q?o<4^H1@Hp{s~b_?zu*1*^tei4Qw>l5)@mYN zL^E@`&g65bX0QvUDxZLyMjNNGehxOFS%mkN*Rp+_3>blt3MSVds?_;(rC?W=Wg(>Q z_onH?oicKNUqRh3lW!jBKwkHD8S!j*>5jQ!wRToj{;oSf^iwy6bM1A%yZ|Ff&g)+Q z%{Pz{YQcA(zkPan__F%$QRGGI&M3#?>}Z6;B5LW$P;Nwld#UKBX-lCsY;N5yX)qHI z335i7Wa}D$uj4h6PBuuBk{+o*x&)^a9E13J<7st&9s7H{Fn2<2_B@hROwxHLWek%y ze&%$wV7KIg-IEdS2XkVZ?uzVmiXW8ezKA-v8^aX5-~n!s~IL}-zMZCX@+LvNP(^IZ%vi(%&7U1>W%6bC{rW4o7X#M7!3V?uQJ^iGz4%z#W13U_6U`7(3a9jD-N8Bi^GRu^Q#OhpiJqRBZh3`IjX)ZGG(goF_VS%RdhVfqUC+RKYCf zZ_OXen#Et5h^S5cRBz4C7zG>;NeG^h7cdR&Elz;D#{YY%j9+sCw)cIdF`hnu+&@3A zAW&{$GFfj35)J3POuSb^6F7KKjz!X{uqMe}NUlk~$PMFg1Dp!)53)vQg19zD6;x^C zW7E1IlH;sF+`T5T2^&|zYCmQPtKm0=lrXwlD39cE>ZF|&N&uRW57~xb{JUA9zui4Q z+${-`#FG$C(tDl6kd)EqgWkf7^{Qm^=p z*fBo#1zIvM(UNf?+PB71j>m4b$yLT9*!?@I&4_YQ?GB2xJ_A+b81|KaeOE0v^x+QF zD@k3e6zXa&$a<2tjdIbX&tl|$@c)vn0zNv?<|IvlC|vWjxGT53=M{d`E$^AX#?vKN z6OB*r7}=NoSak+kw2XPRSrEKF2nC^ZJ0(s2=tIXNEXSpmw8CtdE0T?Z+3Px|bp4Q) z(u@o+^ULJzJKH~kTIF+pcH|X@KABd3M`qeTCPpABfBx?z(ZRj`**TN(b6uw@c1KGy zxtXkPP?l;Ve{8nDv*Yb_{O4q!y1*~%r7W9?oq1JMGfuHNXztza`TkpcuBF0%e z)vo?frJA8et$hhWpd;18+MbS^mrKlw*ZuSBmxq_TPix&V4(k?fD&y`a8X7Hz+l7NtSy&{+^^aS#pKt&D-|L2oka|IfirPW=ScI4~45dK6_v#Z!r_$tR`+=<|+j>&Y+G(!UMUTb=L8ddKMIXEMTxb zngv?!ql@Ezo>`ur*^W8M7^mobj+hCdp2m%TVVddN=eu>xvJv{~FL@85aNGE3@nn?( zS$>#TpKbHM$(j`jpo*E1zxdz0l8!-b-o5`gzToRex->;gOUtynFjQOp=m{={MLS(4 zH3QD(+isH1xX10v{B-~M?$ec{-P`v+|8rRX>g9WXAUr1$Y#pw#e2NQ$@e^Yi`v%WB|sOs|tR$E7%Fy3&>NBuAxN$rnuA zw8YO?);EWVqsYV&1Nk*rf$QLX_Y=a zK3)NT!p)$M1I;bfq=KxN6lAT9F@D*yQmD;E`!UY)RD*$Z2da7k4b7JHnC7(mGNB(bv66KC>!}@6c-M_1nKPdfF4n zyu0`YVc8t~MqOl?0O2w1i0?18TW_ENGhaM^p?6>YEH`eWmFpjEX7-<+Rd%nT=y|7q z&C6K$_AJ2gcpI2FXS_t;Yy34nu=8Trgb7LIbIfWb|IuSVi$qlg?&; zFB3c0^|7qVmwtR57#GL*%x<~es9&D%e|}s=7RE35zUlMQ?CavRhH?x`hno(J0HOGX zZW{WLd`7&}Rql}dsbQ&^nVZQbcr7@rdBQJeB?#fp{;Xo2*v!%en-IFKPw$Uo|M>CS zetxfl|VlRa5Je0%Ny-=~CL0!Yx_Ce(a@m5;i2jO#@4j!lJ4CCT3%u zAwL)?=32tgOkGWED(`pcBHH`Fuy>(8E z0+01%!+VaFP%#eV!Hh#Q$s-wRqC+Kro!GB{&k7c*d=jW#U{YOr#PF%@rv(M3u+lZ` zeK5S_cmqC|a&uyNsFEImlvOSE$@LPKO7h)k+zibS0!#_VrG5yxxbZl<(z@S0e7;-C zB2^_D1P*7?R07;gxYR>By|GGv`%?;Kn>BiO_vy!PpO-;Z$SF$3mNMv3igpA(QL&?D zQuEruNbsClS5w+1y^kIhhk5WUF1e{BhWRVQ@&!3nKA5l6`uYBDr4O8zDoW6RUm0<> zi8tRw#g>g2WMfS=R$t6`g9YSC^SfrxWiSwb(w#yU3Ol@By?5_FJ$=1@`f7$_Rp6QH zlYokcWyM#x9ENsQ!p1AaOoX-#>l>%~lKM`HbB9FY=k3~VFfQ7%R!*}07TIo+FW_7z zoiC^%#;GkF!F(rr?B;rCJO{h?=3)xxM;GQf3(s%**e4o3z?%!!Tr)ecMCGdW4p^@yR{J~lMr=E66W&UK+JSIX8W7&Uv;BVR&9O~ z?-{0GQjZV6Yw?MEFln}llU>enqiFBgvUy`aJ$!muNgy}|Y0rWB2@u~Zi!mn5Uob`q zptLZ5pBcjqt6>Nh5Qtg0#Rz5sUQ~ci$eK>lOfo~Lp(}ihw^H%o(R>ztca6;M={7ZYxe&B5&!)3^#0pA-P#tA-I-_ku(C9l zTlDJprn_TcVcWRla+}W7BO8rC)>@Y1;^WZH*Np-BG(L(g-w!H9q>X^vt9SqI*ZaF) zR_m#^&i!V+e#dQp{l4b8rj)Pzfb-Hz_==FODARIDwB!c+nQld4KG91z(+B5^QM^%l6 zf0mLK%#+XD#*lAGG$-~3S!lez@cg|lZ#MZ)W0S8m8UT063~kku=?9%NK_MV7U}9<% zzpapZkpMx|}c(`m)&KsWh3FQ>eG={PDvwyd9A+Hvry|=yEI}jfcVo zn#>LoNviyR-;wBS2tvl2{N}|TpRRFO|AH^d`R(!NW&G#e*N+cBEk5T`v?lnKl0WW9Rldp^qk-Doh z3Vf>z^>d!g=`BmYun-Lt!rl*N-BVKsN#cGwU2_xni@vyY? z!*qTiu$0>0CaIlpIby9nLOeRj$rOvosA|-DDm($(uqZZ%rcKmatwNbok{vRc7fmCc zzn|=Xq(>Twu;!DdWx6A6C@DNLq_dRC`DCLdC<{c_Di`RDv4RunSwlIq37by9e#uj^ zv*J2Oin2jHhy5^$XO^O!Stoh(ZTQ>62?Wi)4$yC<&MtGxtd}UP$AC1VT(wxN`ig=)s53rvZBNlu= z$*fbd>_nzF=Cm7ulgJx`9q0KkUR&^Ux;=^{*>C7cgdx;vQ`1fj;Vm6Z^97!+Npqg& zd{w-G9YfJsE_!4g?6ZLJULHFMKC<3^@^tQj?G`-_1`<4jV%U31w2MQM%@vkjCXm-m&y?Wk~SSZSJEIVDsBV_HEtTW(B!PvQBJokb68!Z|cAKZm^@tpNd* z6)47tV*^7ebQ1*0bba}n9V$KSj}O*a^(U?e6k%SaEhefgYCO&K|OBfv#n`fXhHtx}DDZkdRr zCjM;wHpfS_@3@3R<=)*rKR^BY?kWeCN&SjvdDRXFxedmD+Z$MBu^1sem=Y3d-aR6z zxy8Gquy!{b_+5AOeQ)OKUfw_b{P^(lw8qKqn+!;q--q4CrF6{5xmUvkV9WkeB!{7y z=+H^Xs7KRcJYAEYc0HPG_XvogsN7qm6AUgJ^-VB2u9eB=PP+Q|HtTWys3gpkrgQptmo z>pu;=1D$z1r)`Z8%xvnlf?3NvICS*7Ss`lQV4sCSBsHBl^h<@UYAOMLwyvkd@;CRD zkkl}x$criacFj#UNfTyc<$+B;;qye>?P>|OkDiH+9lB<@`JjkA@1mOiN*vTGy4=dP zA66UFYkRuXU6QYqN4E}9i>=S@;;Z{^1Z*CEdKllXf2_Sjj9%h2hr!nq8sc95MohCb zuB|mY2wk3q-b<8=?VFQ-WR^{SLkiBO4H}>Yucb*98lA#nyKEDUP$dgNx{bFl{kUTlc(?+hFg1iPuDpwC(gz)*I7ndooMTAY&l~yOB>^cDB^(3T!CtE$x=+-zI3^sRey(3qYnJ_nd5Z9gK>&xBG&v&1f zXc}aA@kY}q5pa2gIw-bNp!7Qa@&krSh#ODe7IfGH?Cf#xbj-oQI}YjoJpQmcgjYFH z#r_9a5{&zOvVig3LO` z@dglr4rc!er>4SHDW+qHw$Lb=qB+!V4+MocsnKN$cQsPk`1{y(B)UJ~UE(-;oT8;o zZk$ohqr|ohW~FYtKo!n2?<979nmR51xP@s%;M~ev?ddzwTewi zG}gcYXs^5u5Kc74rTQB`#T>2aJKXf8k0_b9`+*ZQT17ZZ2Sw^nQa27HmI1L&JU0v- zlEMXsMtVa3NOTS23E>PI*y>l=KN;);xeIb%86Q=o(!<4OPa8#39O=pg&B5x zZ_*|r1ZTzl##Z*){-D+m^}p`#zdYXmV;#dIr(vK^VUdBQt#pXnlU1tIla9=Po6Y6- z)eOY@%oO`MdI~ZGAnyDCezh4^TI$RVb__0I{vL3)@l#Di0VXwgIem3IlL}aGu4|h! z;f%NUOd>0-eh}R3`T!+XR@=(!`=*nA9mM!5_^I&qft9~CgbNn4#cD^r%k)i2ZKxR7?bvN;ahSjHVnwjwXCVv>_8^F1~jaNF0% zIv{LU;Bwg$nawoZ022bMBmy)z+b(TZJaFjPYXE5su1tr{iYM)WNMqT5&&qw|;gL;2 z0hg&Ut5Z-L6miI1l$?B_2!%?@t!Cv`L)NbeE3+a?9}13U3^Ty4nG>gcVuT8~%#%=aPaumeOyuEnym!h4Y ziCq~{u+h}!r)ETk~3PO(*2$&5X6Zrv6$f| zsK-^Iw?Am+2LT%?jQOd!57Gt;=pCWaqYVDidx{)m@`8;@XrqvSp^r}8lqiFFeWI{@ zrS1wz^wGBZ!L;0x6(yuNl@pf%p$i_)+UV3w^QyB!~p#ndRoJzqwIX1Y^`j& z_-g+4I8*6mRw~=9ORubWyUp2IA_q&Ym!d^(l078Nav4g0Me}55UTbVoHfL`^xEzs< z)fLV3KGgnzQM`VKm(fljfXg|_CuM=?^$VOZ)k?s!7S_52TQ$z%)^3q5!z_lmyd^?v z!|P>3cO&mTU=jCC{j z?oCUE28NC)S9!qGG{OW*)+(ESKn5wvTkyh8%sR z@S4aY3;>X2yfX`TCx0MndsHFccsg~tt^vmw4mHC_1d{)Nba5QmH%tjD1VT$x%s4_H z4!R*QHUID@B_Ti*Lx81!fXXcmWm=)L2+)&lk4Xl<>XD*gQuAi%oJ>Kq1^Xr4THFOe z6lvOj6L&@`6jL{J#?io-DPqnCaWdgDDvD|_3Z^wY#7T2$VC^l5U3S&<3K+0X)*F!< zBpY!hN#?Hm#A10@mPqHceACMk=iIJ-1&5y!9&}3OdYXDSfE|y&=ehaY+(%3{YfTEgIBVj+s{|U7MwT%u+v28VO|1s8dL!$_sJ`q{i$wAHiU(UUs}lL@-q_!N zt}Bfg^6Kth+cR%H$IlOsOHM^LLztLvdJD`NAWLu1RTJh|-m$yfvC|zh&*zk~-AU@# zlR&21)!km-?Did8-|F^$8DBQBTd7r6wr>2(r~ladc3ls+w}BDr-COPPeE<3BZ}`I2Ygtn!SxU@EaFODP=F9U6}6pz2s+pQ zEazv;j|KTH(1@ux~5&{wk{d5 zL@TswfGOFq{SZfsZ=CM6ws`mB-TPm@ez|*pMf8C230Ql~))aQCn+$PdPxnCk0lljp zZL!8rvwQVY@9&l}ZuFFvs!S$-NvrF!G+L-g?6N8)f{WPSQu<+H1V_Anxo!F`o?AOm zd#g(4${zg09zEG?8$ane6FAxWU(~M(dg}E6^(Q`bO!^z2dF#;2v7Aw^dg5(@aNw^= zG>RPJ{=5Mj5?g#pBo^rJ`gx}_{cytcyn*Ps#)?j@^2gnsN_d-jO;aI%qz*Hu;x;=D z-ML9?LpC*fx4mRW)>U|(@7cL_T{L^u&W2Z|7&7LA{zjTx6dppd^4O?baHJ1qIxMV{ zjX}Pb*LNj~EfNVr;0|5PkySCcB_C(K>2zq;UxAkKX#*-d&Z)7H!oawbQ?V*C`%$Dm z3XPj1`z`i){UJQxzkGXtUK6%C>Lk2#ZF=RPhssno(Bw9%^NmZFH?C}$T25Dbx%+WN zvzG@c`D>Dz8aiR> z97R(HtS1OWyS~AMREccXmclKO6l-OmJhuQr@48?r9#ppoI{jJ`ZxZI!#!igLB zH~(Y=?$ETt;D*E_y29PK1=81$w1c>HV!4pCT3MD1E#G;f-!OQv^8Ax(T9Ipf_&kUeoDt8b(~s-k^( zNn=o!QTi?_HRkSrTleu}ptlR2M*4hnF?36rc_#oI(Eu`vCL<#=6d<22l$V>MI!KUu4bBua%hg2`@jhIod+x#=vkO=NTf- zK>|{+u)zpC6h0_evX7S|RYo*3UMvH<>CB&u=r1^b?GzG!t%#|s2#m%V(x-d=ofJA} zTN9|^EDla`ERE-QB?KUX+%7BKE~%120#ece%ylae$_%lhoSe}nGH;Oqq}r+xa->r; zD0dYwXkHIWPahsu0U@Lp_cr1Z4}QbYjO9c~YGh>EQymM?40?02TgAQQq6cQBp;m=N zbpXFD0OdD-FwF)Sf6G)-MhV$IKmICO7bS@?oop2EWJo6OIIdQ|Q{*=9t1K1t_t?Uf z^+rs3PbGEHUaNU8;J_ZTY7!$eFQ-AW+ClkL##Vxe$%QT_1${m+Bn`8QyM(UG!h2Bj)hgUH${a&xUvr(X?$u>fHlYtRD zba`?fCOgnhnkbl?Fqz_!6!n7X1H^4~tpf&4>&~$V`yuEZwz>Arx47(}20u~8SOb8hQs-@HuhDfe=NY@yw zuH&p?uscHI_hiT38S5J8YMGRvN`c9`C{qcRU_oGBaWdIJ9#mK-G%mK%wPVLV#ldec z(PY^!p-uU3EPExXDA5dV;ZBs3hV9rH5E|-#sf-Uk$*71-f98W}VuTAf`5s_fZxU;; zlk5Hf@?xr!daAQ9Y>EJJ^%j$qu&b#hPpfJX5SN3H1sZ z&2mq0JB%jm8B}pb$jY?C3n_?jMTDh?+|Nl1^0IU>FOckc2qVFTr^+?lT}kZ3+i=e1{A8%PQ{4Edl2pJalzJG#lSIv^_YTpm$qGx&Y$jnT#3gT zBeu$c7XxPqCM-#Zv9!|CSgjh9)Qk2eMcH;bi<4M&e-JK7W&U`%+-A)-0rp%NGXat@ zJ4ob^{~Oi&^N%0yRxShsW)4)=YY3iy1jLUjK(T{meF@emB59L4CBz4otGTaZiH~K% zp^ycTOiG}HZq$b<&(Rzp2LUGZkI1)Mm8k>9x#n{jU9TRLL018N%Bv?I8#{IAlmcj{tmgJ## z5;GOb@wlGjaZ(sAOll`nw`EyWLt9>pm$-NRdahs4^((r5N!PDQUBx#tOI#B6tNMOb zV|CWPjBqw(C-V%GcqZU@p|Ovg@%c4r#AH&5G{hOuuyLY|Mywmlfj$jbS8^3mx^Y9= z2y}jejPKLqa`a=H z|NIR?2k%z~xnf5&F79i8QBR-?vRQ(gBP71K)j*G!3lU4sj?;pfPfFPo=ys0&v9lcH zMKR7bG2x4*EFr?`xK!Fn2aYBhD#9LZpXp_pktBz(2-BmLzFJi(QnHffEUHNfp6Q}<1hNi7)A4g5(` z3ihf5yMg3a&<#9)X)o*s&K5w$FpG`=M)m+l*aqcdi&rNIHzqMecWg?D(eWP3z#F2A zkvZW+j$HuG$<_lnol_5>Ly3BT>z1@fGvXN-ZnX{o?y_cK9Kd?u^7X= zkUb#XQbaPNj?t?F7;c*qM%DqMJ^e_2J)eFe_KXi-%29cLm+iSS#!>9aH^KURQ&h+v z`@mO}k9~TEmt<4B$Yh#i<|LnqkyLV(7;2hLgA6Lh$f{==iwKF=`_b2rch6r|s?1YY zad! zq0-c$(xpQs>rlx$RJwGieCbfukqn!fX$m)WC=r@8k_@vhfO|9rA9OrX@ad2N0X@oAW4=xQM#OlLsK+mVO~3G)cqG3AJrP8{Y@U+0T2$7k z><2hg-d(grMa61lur-~V30mp)*>9-($=LJAB(S!%*S7Ey_Ujux{cBjEKaWvZ<^ZJ9 z*msU5r#ODZ$1fE8uM{#5tR357pgd8ga&{)vEy91YX4`CV*8|YCN3ZYfu?g%?4;F4< ztB@LhUFaH0cta-r5wo21>P>un`TQxZIc{U6dH>ciw8mvsD%q{O*n z>VImlS8wva?*4Z7_5Jh1m&I}*+%S1YeZc^int%Zef4@=;y{JseXX)ELqQ}*ONjCnR zX;u#7a;H`9t+OPgeacg=X`{H!{&o;_abcXBcsDa_zROKwzJWcjJK zq|-K&mWh39yX8EsWGfcVFq(kim6-6-jH(DSTT&*4Xv)xW)L90T17X~pA2Z$4%Mb=p znWP2nf9^SZ%F^A+i~unQ$IV6NT($FYcoIu1F`8N#LZVy`_8=J26+53J=RR3*Rg7>x?D_rF7lmgZ7)ywZKzR*nd?7PCy-d_Z7?2ohV~#7=UM>^`?B&9mDZM;2^HOAa zuRNS>*CeQzGlKk~hkTqp(pP)&myci8FDkoEe=<3@fr2T?Bvc`oQcYqNp|zp!U+DJ9+i*Yj?=JACi0|^#Q&h*IfFlWQ*lH6hy)g@O+ z?>X{6MOfl!+zfoQ_hKC&EW69LLv39HZ!8|D-k$^pxJ68Atk<~Km5xfT2P9#RYFof@ ze-BXb!wfAOClDz%b=krh2-sgrC9%3e-6a{O3C?tTB|g}lIT1wlkd#xnKVpU;S8V1L zV>0c-W(vBSDKV)@^QV`I-uWaQU7@PxKaRO z4o5Oo^ggY5CL@i@pXo|*^|KB{f3(zhF%*7b1IsOU88VbbQW@|3`Yd$3K&t2fC)KOp z`4!KIsbB%X2{T_pJ;?#nV+|ZbBqqi&{m|@3Uc8H&7JCoI^^rN;GhE5zo2|~Hm91X( zRgRYCQVL1s(zSx|=$gG*EdKz^!wrECU6{kz!SB$$=`q9W zO6!>^R8|RaS(V75vyz`=e|PCrX0BU%2C$+sBr#||D^>IO;rY0qUBj;X8!yefm;1jj z5x89j7*kL#I?dV6@u^`t%EhN7B~T6DI`hUzfepl@TRM$H7U)bN;wYXmadidyAyxdH zWNNR$RF|q@A(~dQ1?`$h%BGw%&w;2REqx@bW<^4fEMTT!hND8Vf7#v(KaeGZ80Y0P zs(d7P6~S1H?uwgowp6LE5@yAtonAU;nY59Fb~SC6+yOr4+H0`z=Pi8KD(I_MV$bsc0 z{41CEeE0rJZfV64u5WRO!}afQpH9Ega+~n^Z8ZLM%Pssq==VC`5^vsW(m#sCCy;l% z2D9-Uj$g&oW1^J30Apj_c}r*kk1q-O4#y`+5d9CHtA#jqNq>Vw@EbmWT3p8~H2tFI z$kwdlk>aiq`9`#phVQT6@vje$AD({wx*QbamCra^dbWk)mxuymYK-v{y$Q3LatQPN z_%s)0=E(A9%Uz5;;JR90Uw-<$c5SD;mI>|@MoyyXPjMox)Z9RCtEvezGaD8MF)igP z+*|RQ2yt~lX@87lB5o1+3i^mOl^k$~Svf#z{BsBkS;w+yaYAlY#)@n&Q-#4Ynnw{Q zs8~G(&&ZN+)lNk1#$r7OIghSW%PR9XyCw~(;cdI)O7q48o2^e$>@dh= zDjA-${ASY_s!p)(?lKSuu7N`}0aY(fbN^Zs5*N694F%1>zD`Y-6NmvXf3!>5_jPPl z=)ffR80BXX3zlM&oj`MvV8wRJMWYa3AsP-JfeytqMD3=0)xgC~(c0K+a)RC^lh;XSabu_{aUVydIlefBGUA3dhMNWBu^kJ4Q3?^u>aoDPkL&s=8y46o7IAD2N9z za0(JQW04>=4&1KIdPLTm;VAvRBNoVjr>`n=w0cKbF9pIUB=vl`p6$O~Q4B16RWZa3 zT0R^#2OI}!RpPYWE={m=uaijnCe7Or$6@SBi{?l+fukaUTtk#pe{&mp7oYC$J^-Zi z{$YtjmGu$yh}bn*+$nA3=`WTfaR4HbAQ?0Stmf0j^wd!Jb|Jl2B)q30)f@GDCS(%9 z<-jQ-#bJ5=LIEbbs@3JBh-W@VTh}_|PNFG#7s_*C{&!ShM`^f$P>F6VE|KAIiZ-Df z;?ZjzR{}F%$VS26f3|VzT|hs}nhv^SHoa}%u3K^WwIA=C%m!cvI9H`0CHq8($0R88 zF`FPG!sdz?DR7N1A&{HH-ch+4QyBga;6{2aBl@$WVp^huBLS=`+(9RPf0Bf?blc0D*Lz%Pctd<} zJRSM6=*Dy>V)p+9$-@NGNbN^mf#<|k+sTY2;hjUpz^Xu=z!;jB*&;M9e ztS)t`(^96|FGQ|aKgwkj@qs!+4=r?&%%YxnI}x+_7=x=|f0~oRpI>$D4@bf7%u5%3DfH{8BFUvrq{2(bmY8@14VHXmdbDqxgIY$bRC@Sgn6zqW995y7g=w=3?K1}Io~u;+s!eWH4uJA ztR&(|4=lIpZlw|w^_9ju}-E@SR9Z`ixvWW5LQM~O2z?k+rX$_FbC?X^e zhcXNu4f+&{j=k*pR(o%KHvSE7;eTgemz|6O9A{qCByt%j4HoV)SQxKq5zliP`j(H#(|IS(?3|^qCy9CGTs+OB z1}Wxq){34=R7C)fK?V)k{>lS?cWtSk00Th2FJV?aUZ|Ay@`Bw5hkOrEG z*iGh2LNhDC#K6-D{89$_n$Au7H7yKY7KwMg-Ts$N69;DkR341yO0ZI6fQbj4Db=okD9ElkWphOj~7VhtmX&_HfZ=> z!;~~|^`L{|e@?bey%StIh8Ut~ge<+7Ona+w6GFX52EgIr$$;e9kkG)Z%F^%P^5(h z92BLdK?w=iSXi+c`ITNP1@sG7b}BZ8HJe#PD8}PO|E~mBb@)a#Axp<7sJx62+^L$E zSL%Z#dKgLHo4|ZI{Lms=8An9CA~SEk7vrrHbl;TFaC>{HZ+>a?DLgWz1To*) z!1f1Uc5l2IL=h)IiwSr@L@pAA1r{wK3A|HDqBmx7#7X~?ugCp|hsTv1pGk2`enWrW zb_60+p=p%yN-C2A+4}a-cQ&;NOk!>I>$EF@LIhUvY4|903)%ot1=&Z&QXFNMO;~3< z%?WSX0jx5_+Q5KWNC7X!$;(0#eI;D}S|hx>wvWEjH{TE~PfPjrE1h&{fEmUIlS=;s z$vMn0PN+&)p;A?bt_Q?Y&9Ty+DPMobfnTU#{2$>)~|)j3?60lz>TjH(l>kO=lz7eWu%_df|tSC-?2|E9*(E=V*TfqQscb zT`DG-oQ4wVSZWHvZeFYEa>Y<$==K8X<{~pRm!&SHwc*&-L-(U~28WcPF$Sp4)pcZo zw_q$~FP5^<#Cm~wwx~?D%x;5OfAR~z(+FGmZ`iwX0kO%%Syl##DY$gJG{DI|Xhd6k zDo!<|BfKfBQKgwLxQE=CH@knXAU{!xOZ5%TjvMT_#59kNirOdIG0YlC=SQCvKYA1dg1;d0JsN6{_umw1-@uc>UPyEaSKpV+~kZwG) zvNi+2UYN%?DM%$#Gjhsl_A0BKZ6Bge?AX0P$BwVf(?Mm@- zrKFt_4oEsUUaq7oT#YtQcWdnkEd0;czPpF`13>IkH@glFJiY(riU~P4;fQ<#VpoD- zw>N2s`EJ9_(z^qvL5RJsuv5c%0kCqAp*qX~Rs=gaSSM7OHI09dYX<~=Ip>wV=<=1x z)Uj8VXr6B209-($zxFg9yvVwQt%i8_^yU6>g^T)qH?Z#x4|06ycQMWQcW?_ClED~ma(r{O9Y~&#n&2;70MS)$!)T5F5A`oYPY?|dQ6r`?k=<+_? z>P8kzuWciY5UQylaSQ}$CqJhw}^tHZ>?a)!!ng9>zuku zIxfZ%IA-3|6ZLz+Ai7bg3Z`!GQ|2`5mNKWrwn)azc0vi27!Ny3h&y-h5X7DjaxCh) zODF>vyx9QH_h0WEUslqx5YpXCYXOeqg6JeGF?MUpK%8{BtZ6V0mqU~RC|ulM~@*;A%P>an*MPNt(c_I1X08a4<40Lln;IbVxQboB`PAW-%m@+4N((?Z6i+ z;!J0rb>GbMA}7(>tOi5(`itjgVndWA>FcL#3*G8igW}v^_Y{P2}eGBlcDS`by z#4RndLYFs$@^`~vIT&0#)uTbfkLqP!e^cpcsAj?-CK`e}jvA`D|I9ON+}t=XSiyfA zr>7vx3k-aC3|NZksQObVI|9KzCt3DCNYw;^N6*L^v!=>F{LYat3|aNPn@i zn~x&)J8Ydp1V=ySZP)_w(m;t#CZd?vpRVu0Gi-bD@iZhynp2>>^?(mIgl-6%5v{%1 z$1hw0$F0_1)O!@#y1wBxmNcGnfzbYU#Y#zz^^h3JOEw^?rD>i_H~E7a1#EaIDxA;(DF& z?epJPvj$KYIe3^GTcX%h5!VG+cq2K&nE(PG+GCIsyUWMRDNbTFYKLfo;*Hq@PYdK@ zVq_okWRS8fV)fYXfsP^58BW?N87m5!@w_B7sxrYG?rVRv9XR~iiM7jgij!39xwV;8 zy|D_}KZv0zvW)Fb!5?iGIUrn4vToPUcRxSguNbL#EI&X@bM|y+e>2!mBXR7ve244o zZ+f8=jQWWb*YSYy=KcKp>g)|mAMsvoNFh2dF_LyW0Moh(vkBXT`XL1U@6KytuSOEKNN)8CVI&-F4D7qQ-?vW^XdD>GK$X8Ed*j@LXVdIGn_GtIhqh37!sb2)P z4XSgNsGjwssb8taCwsPh&TRJn@ZoG~k9E%{tY36^OzcFxV=Es&a z(A@af(2w+#tmNADqc<^Zb19uKiWE*q)X8H!Y+0Q*S#soJvI^&+J{ ztGO!RF0z+607Yvgs3B$f+P5d0Lxi69gB^eSNnh=34&o$^26^@}GQeJ(3w1=#m4X9F zT(<0m7VFvc!i8>Tr==!CF--}1m+VX{lF^j$vu_zMns3pOC3a^Cg#xoksaZO~j@)%~ z`EW%#ADNm%9@asHagZv1Oz`27)N?Cf5*ax>Z-y&^Gg0a&oAUS27w^8Se1)X#l!$)_ z7HHvJdgaEGB=^zN0V(mf$T@nZEW@qHtYxg70ZS3(F!`V=q31wc?Lc$`&FYbNh24;J zveGSmWoX;%Xct2e4e^$-3(N{<(xs3D$x%`_vt0{Uaakdw)Im;#AdOpbYpXPllFEC@ z;&F2}*q|tvfg;rdGSN9$51IPSR?mN5!5YRfF5Bxv(}{RS+&do@%z~S`K`Gdnh_51p z`TF`xAwdpWj4;)4MalWlEjLE)mYLW+lSO~{*zo=w zt}dgS*l2-wpYNW3SsAN|6SQKra5Z?vbfH7@YGd5q6X$$|%VFLxJ=0HNEtDr~ooi0U z>$mdm{loM7PuDBOS=w_E>r@tW_9s_{%b$P$ig3Bh<~}mjTiM`tnQFJ*>iOkcZ49sM ziqoE`N`@FQ1`;YR0Sv}}soXK8ubj8ovbkGNe;2f9mtmU$C4Y5;-#)!Od|7p|xOtOXm3MLDE;pOQPD*A5$8qKg zoNg54_q{@8!UcG_uK>S@aZH(%kY3f`ky*o;6h*Ix zGd4C}QGDF1m+(43{zl3d^or8hnaWnsRhB0uYx+iOU#~>|x4eyxDK=Ua*_#Q~o4FPD zTW{&}-G_&7>u|54y3h$pGNe&gjduR zx?)(OGgd!Kc&Hg1PClOzCe1uOs0-sn)(2(sJwISg(Onqe*+eoyt;Tp$0qQ16qI&ym zKrP)$pSD47f|3fg+P&yg=Xw)~g~s1q)&7^+Ae}*VPE#DirAT6Ls=;1frmBCKAFQ&x z&+Di5yiQ(4O&|-TL+HbbQf0RrSaJj_A2oPTeZpSi1Dfu5Il;*U*=Wj2!DU14DukaY zyFq0;it5C`JD1;T_b?MUL%T#p1QxFvSD z%64r#`O9FJ*4H@wB-*75&BcFH;mVXXCr*vRhVcKvQDS>!Gmbz?gLPA#&3OzHYz*q$>vbDwrkTDnOShJZ`J+D!Lfe7r}%*hl#60>@<@$NqV^5N;% zCEy#;j(Uj4LIvi5x~t5B4FpJpBViL28eaSxzj^a5r|1sE5zYP}3xt1~%=5TzRbVw0 zCft#$B6_nremS%tH4P&Wr_3aq+^8g4C%YIlJk2$Ae76H56?uFI0+()q+5Q3@2vePD zJk?$j$f6Y3C3`&(XeWO3$P6^4ardFK9w4Qa)W;?R-hjmg73qlLzZF$v9Blb1#M=@u zSSVP7_!#aJD~}zeqfLKycaSIXks$&ZiEK9ByZ0aOSMWh(SdRFpAG4tTNW2cxSLK6g zaZA{F;f?-ErQp!E<6uF?FlWgtH%Z~mbwp`+ldfBsHf1K@1 zjTkp2h?!z^8=d0i;c;OM%-&0$Uoy82#x+QXI0E36@;{NAjJ$W zQMjDGjR6Db4Uzu?i8rllIJF`;FQ-IcGPMnugecOm4@MD22PF~OzjhVj$HEaqfTURF=X#} z>#&j_YZAY=BS-Rfrl=4jt1@<`ZJP8N_?Fmro8Tb+MSSiImn*0-FQ|%9bLmE_sapaz zs24Y7ke$j{M&$|amdR(l<*?lg1VH2K4tw7llhep#aff`!l4(E<`cZj z1MYCF3-6S)4JWTMqSeV9DrWnf#P(@658n7rzdS!I12#7>+cbPa=GD&rM9EEvJV3{1 z(t7|XVVoqU9%**Q%Y|q{KGN~}OlOpv#0j9NyH%p*Bs~*th&i$3lgTTgd`&nBral-J z*-bvYN+5r9jZ*&JNR8jqrlDEJnVIKo!sk&I4gve|%z!~5A{(VL(a6@_SLsdar%J7f zy<83IPS6@*KQpnP@wR&&MC=O5=o>oeQl^UXUL;fi;(w#%SiY5pf4UJrNrHaCeht_) z*m3xg&~Y{$0ZL=7veueZ9l;})oIQV1her2KvKD_(=$sLBfE{!ge`6SPBYO7t_aBzu z>H*!;=l}&HO%`#j($^L>JRnvnvAPN&UN4ip18{6dE|stuQSE4&e2ALk^X|CR)2|tj zy`p!znB^^BP124lsY*1Dpvk~cLNU?rBG@D&#Y{^R#RxJg1u^Lg=1>Tn3$F zl6cfgpR7n)6=2P~qYw{tKJhjLvs_J+keNF zd^@{!RJH|rLfb|LLFsspSTOZ2s*+k#TA+WwAR?T{%b89WN~$-tB0dYxjF_Y+5oV_W zlLh$Bx;3UqtrnZSPHcc^5!!zl~M-i=4O7v2hEuUB}RtEM^*UzqnmyCc)* z9Owp;e&}A$bp@)N`5kqXylzx{7qKelqu%f8#?M=2FunhB-L{{fR!UI>{S+qjPvn0V zQibOXQvQuRerq2hsL>Nlt;dZe=rEN%9|eqIaj_*E_^avt`YpcDs(Ns-!bN?qA?-rawFx_^FI z%@#Gy$n2)!#_-y}LjJW?`SIJQPxmkPAO1)8z82HM)C1afp2+hP4Jsj;2;Gqr5cNou z)pOGV2BQM{KE>o(qWiOy(YO}=1_m1SX#f| z56^eMuHT1vu))E?1{GDNuN^m5E;yoTy~(te&cD3~03u2GNtTGRhDa6(=tXF2C*{J& z*S!*r7ysHm`tW)6auT~yh50-xZj|J8#I^ZfU7u~8uK(F9Lv-gMW5s`mbg~~_x%N6l zj)Rw)?{Q1>Jwp-M<2LOsZxIj%*c$mlut)TE3Swt^doG{5ZjO7cExtTIy&sEfLT54U zK76F*t8mbCfr}I;u*qNhl%DUud|J$3&^B8qxT?XmXMn33AkOj4t6doaxjxuAj&{>P zI1O!mgkk=GHC%O!?^1uculFx6;}iP&U3)B2aO^2qHM_G1+HBmwb$r2}fC0c&l{<_B z?{8Lb6W`Au=&+GLc8WbX1HmXKjkszrULR9mNly=_-+FIW428ANLPTaz?kIsPk0Lmf)z zD?`rALNwrB)-XAK;Glq~cutT$Ob+HGXpv_h%quzEGK)KKSI6l+u(^)T;XNxWX-_n z;QgV)t4RY>!>TGtY=z_Hv_!WMVn9y|8GjW%hhAokQHJPsXGA(0p>%Ik zCoM*zd51JFA1`M=6-)gIMWZAK-EVq%C)po=1`vrMW`K=aE0bWjLpI&Z8uwB@PUpVr z(+}^TpT2y2+7Mywng9%7kMF3PZ^2`m{f*J^oR&LyiB((TTSH}NU6Clr@}Rja{vNr&`fz7B3#ZO+k@5ejScBtOrn&og6DXWo?Up zwBTg0rYXFH)G_Ho>I1&1>z24~%VR&}6b%~X%qB&#cQ0n9u+omoykeOWM=p~$1Zmlf z#b27S;OkwyEnqsjxvuS{{I0i8WTS8W_4CK4 zy&i)wUb?Nfp2|l2N-erK_!To-d0EYWOU3O@lrhtM$=pJ*9Z=s#!plUf%YiSs-e+`aP@`WpA|7#^S3j zRZqYSO|uQ;sKW%7Q|+TkY!6GyJ8@boy`MHtWacM^ZVGe1jVhOe!dLTy6v=AygMgrz z{atz5dVuK@^MkZ)%~%fvsG0?TqObr64MgUUtpF7W<>S13zXCrdc1H|V%#`yhA<}cj z{;-tVU;pfWySe|cnyM_JMdQevmn2iv>=3-)Y?O+1CdteR_dGz{nFeUND~xVDc+B(0 zv(RYQn@TDc4h0|TaNQR;M;ngxvHQL4{fBx`p+$@{22i&CclzC(X>2opB0_>$okmMq zo9~-?c`D5%*(DRfWqXorB6~i)TPaIYr42)l8v$p`m`IL~Hob0g$>Zc+KC-1z zv!8yb{t#q~3R~cP6p8?U6PRFndrhUdS8N5--y|zVzngB0BDO#f4@E#XtvuxjL&i2S z?NN!}`hQ3IDwtmv>R(|?v<<}i7&EjF7=g7{nY_s>saRx3i z;il&uC0+TKlPU1VqkO!7|9rQ+$Y#7~sf$6r#bbsR&r%_O$TTh5+#82W78(L;O15&u2v?36gpdsj4-VW=GtmsgJ2-l9U?Pvj z{zBKdpl@w-rN6)b^z`k+3fRK$n}Qx1o4LL=E+?1fl*5IFIhM%W#W9?qRY2}bc6h=v z30X}?)?C>WeH&B`Sf%<&+f-!LYLP&1v3AzQ%P)#24`s4{;3z_M%ObT&g_;>VMMD_t zrm4F$caaJWMqcotUtbn21RrZv-<%yx#5pS{S$3W@m;?N!u}<=k@Pw-iee1apF3}7W zWev*!UZ=p&$x=GC#3!SDeW#pOhL*@*Z(2i_U`5us7adPgvq`wyIUECH)fP-~fV(hQ+zfT( z+pag;Nz@kGypCi-fz+jSpw4$Mo#eG`0n20uSld8P4==NUa z$^bour;Dtakq&U68K8YDRFjo?$nsYPZ$P36)Mm;;>JYNtvs5aAL~T2uFYgNjX-@tH z%}vD|Y=_)s`LU?cyHhijW?3?XJvVyhCaC7`Eln}@2$rJEtOdrW?}9y9sAV9^Lzpq; zev8e2Vu#W_0eXja({opO)-%MmiRS#!4hS`Pvns_e_Fg;HNy(VFqhobbeYiXzZ;mWZ zk~RV{;d%f`*yXBCn&uYr&8E6vjjKRa<|U823wpK`&;!Jy^WmE8gxlKHjQ-*(P0+2$6F^+5nE~_5U*F2})vPRB z=Uv6XS#M=0Uhivh=8b)W2&Y@;_nXJWt@GQMw6Sj>RdD0mWIGa z3_I>N(!G!ON6%h-8spnWBvA-}S3v@nUQ3ls2DiyAOt+CAY2hNR|51}5szp;saQm@h;|AUr7)Y#oMhk>q&NFX%q@)Ad(Ys3 zxW=a30kwZ4H4S3}oA3!R(`NJ?jrui~Y^ofmL_Bv?k%z0ulO|IM(RacsV0G~zjF_!@ z-4X0u{BE$5Nble6xCbVTb_N!I_e5K0E5mKtS4AFPyNE1U&&94WUH4?#E^H1bO}A#B z#O8W~WJ_rbRE%w|OEFIxa63B<8pR9Wg00^3I%+>}jJbg`=#cH?wtKTFX|GJL7~7_B z9!O`CWVTAh_p+*`vKorJt4(wkHI;|1q;2=ncJ}>I`)H@tZo1l3hwA}<=-b!(l~cI0 zN6tYLoKH?QBQ@Yo6d#}K|03u)mk7o(3oe<`jvD|r17~5l=@VACYRJ-uzi-y)4@YK; zH~|pJVW7?P-E{Q7n_{yIWe?V}AQhHq&2)%VJdb$KIaoFHPjc$PWHa|C*YAlQEI1Ta z=q; zZ&R!FhJ+8VB%H^$Ad&bJnc*9M9-l3=K>0TTQQU(cjd2PT`L(BN1l|df$+Tdj!5)`1 z<1}oZ13`Xq{x@Eg^HPEww*r%KEWJb*T;e92ycrR2n~N9%IXwG+yYj@~`y@*VMRJx| zPt^J>Vwiukx&B0_^Wv1`y%F(!2LgmYRmVg$v~{)L@xb(KKzunuIEdt#eI}`etDGA; zT5&Huy)$6~M;QoNo19*Mcza=(yfYaLPfIRJzBCK@^0R{VoHLI~nE4n%l;&hQIpais z{K?b2ljKuQTDD?;qfdVW0QBp_f8VdvE6!d5bq(QIFD{HC$R|)fIeRKQO&_3sGS1KU zg#!oXby$WVv*HnM-g7H9P?JkDefYP6uB{Vjk3w^Rle-b8+}JgqxKm2#jZgUmHBE%D z-J$WR3}=HU^O+A zUeTSPR*vc-e|acpNi;jMhCFNO!+8}+E+@um7Yi}ApfeLSq*jx;_C@lC&yP3ANW-qBp91e5y9M|}HL$=+AR_yW)S=H0}>bZ1cluO2$N=B$LexB<@w- zZVuKawq@wpTBb+C(L4c3f^*iiRS}|0ZGzH|VUrYpi;?7>7u3}x>JhehQs2Hlyk7+< zs3?$rP?Bu9fNtxpnqhD5OACiVijmbKa!yh|;}9LsBub)R;N8ADN218cYNJqi8+$q^ zx!_t@041p~n9LKdgb_Dv-uhKP$TrW2*AhpHWv{l%wQX}(;>QN*pD1oDRFuM$c%s>I zSc_m-%C%0RiRES1}B?y`N4k54b_gj?WJp0dC~N;b~Or#k~L zp9c5PsiAZZR&P7ab_SF6k;soF^SKu$6AkQt+Ba(Q?#EBx?q8msUOuiV-&UtKRS5%t z{1`p1&zWG{nRZZ=s+4!!!_(N>%a=#?q*kADCb8R-{y7kwPCP9&M~GW+#QU{wBM~qA zn6@@i^PF&q4jl~I;TYbbnE^Kv$6}(%*!M*EKPcA@>lFRS?@noF{BRO(-}gQGIf=1< zZS)d#zo#Xy;FV}iurv5sfV=0cB{XHneL#N$UkRTLEvxv22QFHbdA+e=he)w2320I$ z*faen4J%~zundn>hHF_4J4f@4m2V0hl8?PQ|B+AV9*pFVfB5B7a&t$9LlCeAt4X@H zRKQ!1ZBe8NYicPVOz)*P1q8{Ha32PLJ(wQoB=g_%rhdHp^wYm%-6`anS^JZ&%W-#R z`esU13)4Dt=$$+3ytZ4sO>Z>I`epOe%a$%Ln;Q3&`pXvevWan|x2;^>HZ9@a7;C+~ zZgKXy#o6oDF0UK1@YCy-`s?QHb?X&+4O=N~_z6HOR(zXF5e_L6;^(=w| zB)uOQjeAn3;4?l`pq`FNcBV{hK{GfCn`U4(nlR0=vrS0!>vur4e)r}6X_aq|*MiN1 zWE5B1$hTi@3$N@4adJP^U&SOd?dhJ=#y!{Rn0mQqB4q5QHYnO)mTRZ0yKO*%EnaIMA}Tt zBIgZEB+H^!mfPjS#O<ELBGC00O95S{mWXFzWxCHyGs}uLk^kT230YgJZu@uB6+j7&X4m1wEqR6FrwNQ zT#7pXGhhAe@{(2He>dCW<>USH=clhPcP}d}LE}fMk$qmdHmRY@xkV|tVa(Q*%@W0n zCf_d3Gk}XxAduRw#L=ajW~h-UevLOvx<-zhXD>pdU+RFzLmLq)$5I}Vns1KYnMc~3 zBbyR%J!bQTDzD3C5*=h;RdEyDqcywMPSiCX?3#NKtyz_1f7N4XW2ScQZ_=L!(t^~R zjk%gkXY%?Hz5MiPsfkGY50i}%mz+Yi1mwepi+KONRFi$j#*sJ5aX1i|;v|zw6drAc z1Glw(0|XDdf+fO(N+V?f0Nah)UEzBFm*aRJ?|*%F?HZ!2KEc(X(lKwt48UGGbIuul z)tgK3Ap%@Mf7tf41JVI`-;XCH0!ebLwf}$izGX{t8%g$8;sc`M5D((9)Zr!;5!+bY zU8*Y8%IQ+2CM(sN?ytWzGY5mOELE#jnx1odlgZ!{071avZf-^k5I!$yd3qA?W-y;I z>!Uy8m!=OUzV&C~WGz|4BTQ6vqS8dhp|@9-#Q4r_f1f*r(j4GQCz19D64RAULc+^4 z5y&*jkwtC$dOW|LMb{PQ8B{b2d*+$Ur)=GMr*%L7{P6Q~1;s%38Cs;C&M2c24DF}9 ztl3y^08CW6$CWA6;6KWkBogveUAEuMj^bC5+Ae=&S8tct6?W9lzn{*fQC&uO+&029 zE>~juV1J7&0RcF{}1zJlwn*LE|IP%gTOejoXUMJ}y0bVmOGo?2;5%HZQrjY3X zI_TP)(w1PpJ@_r+$z;PQ&j^gl!9Y<%Qx!rAf0Fo804#DsU=7iTQ)oAubU95(F=w#U zHMh)6<>o7^u9J8I$a*s~*O|6DHTAT4Wz-BT?)LXzrWLTupLzWq(Tdtzoe* ze`18m(Ml1Cgk#|%31M2b?^{8)LYU980EX>*wG+$Ay^o! z-Ka)z)M9UHhS}!M7ya&arR=oOUr<1Ae<8HYWa;_ZetVphB;%O26kaCn6bJ_6O(awz zdQ3-=k}Q+YaN;8QOpIz+P0sJ?h$m@mtpEZDC(}1FNHSKsP5K+pU**4bd#$sF6e!T$ z3iD{2qf8_riyadHIwk{j&5B&Kk)?|dVl#3RS4+O8e_^>W zCl4H4)_~x`F#w4XPXRVl1Y6Ryyv5V<>FLvdJuLa&fw70vGqY#Y^pab{ z9oiDQD+AX-%6yQ{o>DS8!b`>2q@)Tkk|&8o^ifI z&Ti0HL|GU#Ok|kRT`UKVBufVpx=_OvlavNfq-`h`;n*CcWWo?`5ZT^RWOV|D*JRg` z2*++`;gg_TI;=cvqkymiiTXkV=2+%$7_t2H{NeGx)`ByR1FqvTnB%SEf1-v%vZKHP zkk$cn;W+SNy=lZ@7!#=+m#J);kZz^n7PGbCNe;YFB1S|z!VyBX4kEdHAl0wBRFr}V zI$E(!v^$-hq1qwWuHVuum$UOp#CEFlLUBW0xSVQ{#A}(@<>Da9ke-c6$wCU>&?Jz_+9meq^iuk5Smx{!oGd~`vO$Jn9 zz65job@xr8%gs^Li>tp%!m<}gIGJRnZBA{k9V(SBQDJo>X^RLP4N$!c5yF z|7IAF$ms;_mP!*Op^5c!63N`?3#Y)RPa?ZM@I&x$;x#F&f!+ito=f=EDuG9NWZ(P!hE z(HJcQF7&NNj>!n#RAfuNZ|j^6YChcSu@$6~E4Pz=C!LeTf7e7kiIiHqlbjvjO=zr= zYHMttr9+q{N5F&G-mC? z3nqAEpd z`bqeH&jLl%f64zl!)uA#qJQJXuc?N=ZK>*U5`1uRQhWelmyC(PP`mPGIrl}r#RMba z6)P_VD5z7uDlhfyCRdvnI8HRDm`7)6bSm$7lkrBqf64rjrG0Eg5}i|mAfeD=BhZ@2 zH%N6p@7G~N9Q=)Y07?|C3-tJ{RSayQ-QMu@Lj&r*|A@fU!^e*+LT-~>81EM7lx0JJ ze#+3=Yc_{ZKmW93NkQ|F(-Z8_;}+$1pu*z>FrSF2yK@!6|Lv~r;2VlP&M@e)(XZDg z&WJqSe``24__*}hxP%Q`J%~@gta2iwV#a5o<+nInnr1tZZUnl=se_g+I%14cJnzjS zQqrg7O}%Msf_v`hn>0z_qNzGv;utU2G@cQ%j8a{T>+$&P!s2WYR?;t$@sSX*!d^n1kas0hVD-e{kimkFb}bd+PGgoLfvuu12ko2X9}@ zPmeE4m^71@$Jg5Oq{*d?d?)cX$fbTHJ0*K3N0ht6g2~KGYsedCg)}$5Dks^?lX-JW zOYZr-kIxvC(qEOBC9e$=vB6ma5bV<9gYRe%4(}M$e`n2^!dT63Sa-AqT0PySFGoIrsdOEhD1Jl0 z{-PAW-2=~gA_;Tnym)@tku=&cMa(;(il{M!!da+u*4#C2FSDBhBbt;*8m*8o*W#@{ zGxnIib(lYDq%<<;xm3OUtVyFvjf7Gni)lz9UDtoBzWi48!d}nq-q4sJj5i2#XaqzDNejSU z7?j#!-JO<-M$?sFdCxHWvp<-)_rX|7ruua2;_Y+(GYa&-Gq-C5%(s5((S56a|NBSWfB2_Q^RoG5 zuv)j%%sl>nqmcbhH>lIQUs=v!Gdk`Lj`h##GW}N%c~Zx1W0*!~>)Uzuvi~oQVf}B7 zVS|!$+Mpy6;7RXTSaO zt>6Cs=kkZxz1uIU+upa^yKkM=VEbR-;zB=Ff;dG z%NJ|;<*)f}1ohW9KC(K95NY~mCez@H%Ygll_}}kCt8ad23kBeB{u2NEPkvRLj+$RqS4wv#3VCf$s(3r@}arQ4$uD!>x+8DmioAMGKd6 z`g)hq29Ow?2{Kp$&2jI4Wj7Y#fT7Y+V;hrSoiCO!+qigkT7MIet~OZnxNHZ&N9;w3lpA{yQoAc zO8W>{N;qUaN>&nTDLThlUSk25j_6WD8K{n|C$$6<<3!4YHjubJNYOY`7>Sr^3S{Aa zCr6+t9@C^Qf9r$+QLzqIR329ikgu(Z;a-F4%LfR*>h&LVjwdFS&SfRh{415oyi%E5 z9p9N0UtgZqS?}a1T&lVu`*I=l)`@@=nVGH#i?zsRNypxxKXsjvk{83I5LoFZ-Cy#; zf)9p?8PUK*pu8l6sMt>lBH_6LIwd@7)4QG@RvCpSf60(|=04>t=xyVL>BQe5HDroG z_Ds@`0(pCaSu^3j!K9o;R*?wq2@*LaFEax%lmaJLl$Rz*C9t#teJc!0p$4wwZm44) zW+mLz<^Ai!UsmJ<1mA~qA_x^47hNU8n&$n+p7;|Au zk)vqDf8t>mE8-PdYh+8Q5OW)U-Ly?v31q3d3)4WxCG*Mc74hZar=^CmSEAxYFTr21 zCj%v(q)_hD1wY3xj9fmX;O7k&fg%_nO5jFF?7k26PI+1_d<>NupJm74526ids zg(ps>`+sj#Wp@t!zfq+t)XtBfb?BHF#-9!ef5=&Rr0&A}0Y@$jh|ej7OncJFK>Eyu zz{Cfak91sYPdh6!SpndF-&_Z(cs)HOgh4~*(7}u66IriP-E@ZH5V86adtIb;7Pl8*u_o^4*h!oZd%U_qk~SY%(3(Q&-@Qm@{E5j&@E$T zIyky3R2%}6pONp+tRHHqd499Ve?n(z9JIqImd4!r3+2C%e8q{8{j^f0AP?9 zt9iDnv(`{n=!T@+$wMy96lost9ec|6*;L$Dbuc!ZIvCqc9n6D&#z%E9AJxHhoE=P8Wi7N%l&w+`aqpp6 z;l+){;o=c$k~b~_iX-^qls zbHe?(T-COF`qosF|D>4zB+*2x+1?fsW``-oxA2rs24KLuy%(*!7p+>!$_`1y^G}a| zd04u|WMzVsC_s~fy5k}iBKJVzWE+@!nrz}N%t`H;Cd%Co8JV&X1C~=LQIx+0UkY+w z=_G`iO9C0Pf4E_ht~1!kV~ff>2JZrLf1K1$vvE`us69%rQq-(0Vrp5!C^`Kgr_!q) zBh5s?j7G}9)L+{Vs1_7Ss;)xqC_k$$cItM_0TJ~ z*<_>ee;IH^l6(_=75xOZM>_*K`S3GNiAY^FgKXAX*TSjXgyJUdA?mP`AVXWMqc+j4 zY@wNup`4m7Ecn90cQkJC=kAe1=NPbrg^5SIwV)sN%+sb;h~!5*^vQ_jNuYKcsPw>L za4aJA1c5GjFUYPz${_L#nEeR5^O#QZopt#re;HnClxc59t+Qoe!_2OTD9~S*D67Ts zCz0Nv<8qOOAjb(wf3OVmynQwHD7`b%M^T+md*%E`7FTQAoj$xt)Rw|v!P*CGk~id? z!Mir6r4s|(eDy*0C}yZhc?XtpC9#5cw+OL0XDcl(tY}4pqAf#>u;3rlbJ8V=5EzVX zfA}0O)d(Q$at1(@C>iJ=mBtn&L!D$znTP_48>XP#3Qthjs7QW((+od9ynlNA`^twh zPSJ80flGl&_5}tE*Ts-{BlWoM2g}L?$`t)H{Muc6M;!l2(fo>vdFl1`(Az@U*d9UHG<4ma4 zroTb88?!6f8p@&3yEzg8P12N7lO!GU#9|_6n4(DXoZ7ZUm*^J(Qp8_5sXBr|WQ1yN zHG$Q8H?kGEr&3Wb;RV7%%;#`1e~tD*o^!g07@&(x7r`@jn(XCa_03ZMw5J7CQd589 z$7M094wPsxc)-+xo73kMAe|lM9D}kum7(+x=Ek5cNk{dv?HNDH+%5=(BvXt4QJ{uYJ1Qaf6v`T0&}Ac z$1MkP7HkRFYmd=mH%lCMNZnQAh^O;s#yt+dv3&;aHu%H7DA$&E_recRF*5 zkftqPHkJrxcY>4APP;leMbkwA4S&YuaWQ^Bh$&JFP!qc6quoUmLKv;I^ayvSedD?W z-+|*j{H1wNZQ8=6e|!>8Ao*H1s0zL_@ktSt8LNLmUBbYIumfxxuWzM$t7q)88vdt; z`~fYl*vQ<3>E?8qoiUj&5jyMR{z~&~P;Uxc$TGA_ioQ(u9%p8)2Qd>R_B9%YE;T+t ztxR3JL{59%swbfbh0GA+!Nz1(M#cU_5gYhH1iLy*ECn~ke}5{Wk%0V=4QRmmG;q$) zEm-Je6-hf-n&)3XuKQscjNCsFj1Wk$n2i=y8U~E|V)ct9^i}HUQx_5F&%20 zi&n_Ju-wB2@=N0r=M2*1=;*kj#pMrn!|Ue0o7-;gYBz27oNj4%BxE|z6=Jz?p6`)8 zyVw(U&KYlWe_h|qZEm)?SJ<9`J8|B2)J2APdIqj2LR?+^V+fTv;n8drZcn;P31reO znk%4)tpHy@puaO(WEL7CG%yfh>J0Lf7(Vx8y%takdlEm%!c|R@L&ezj<$FhO)}v<6 z_NvujM9_h;FQ&!7*=aR^VV6}cYD{N(+tZONHCk7l+;Lb;r+=zwDD1ElwIkxo;#q2~ zbw?kUqHkI(LcKPM!mE-aM&YSic86yCd0OegXMU^_fOMtO~k$)t(_P~*Z&P8x5C(1_ru`tMl z+h)%tOba^shPGak z_Jc-#wqv}@cqh5+0hIn?5q@}nUWrrwk%e#+Y*YB)i^cfy@!`X_D+Y98z}))fGJJme z@PGLI!^^vmk3YPA+qcsF)>~;sd4b^Vw?=jyKLM*Sd4(vU7UfyRUoW#Bxo0?XgP@m3CUAymcbl z0-l(=%XQa7yO)_-Pf|Q_}Z+umtLEb7M2l4cnr zw4DZ-$zt)Q73+`Tjn4G$;ltk^KD}Sf-=66s-K`0ET|ITf5X%CgGrcs7Q8JkX3LIQr zc(MbQTewmrE1X4b>#t-!@6+VmlDEfE>&-%Zm@Zwle}nx>I+k?q>~g!|wo;!yJb$c} zap~5I$6!m?Aj!FmwQFb*!a)B?;ihO)!eN@?qtt zcPl@>d=5jflgTyO5s>MNZt0}11jcuG>e%a-#bVA2km(+a7yd(4DCxucag}beOXI#U zISc!_yy;vIPcNs=f7i`%zynVjJb!|b;yPz^?h+fRgr3OXclOq>Q5!On$!(3yL9CVe(I`?3sF)KG=JA5YCyA# z)@2cMKXDP>Fa+NbQG-7-2P%k=5p3+1!>ilu)nmSs@<6+XYxmEDV|Y4!GM}r3O%~5T zU1c=GQ)xRLJw4f?XxVPEc|hGOW8E!c*G^qkQ+MBQ0%z@anS_@4=5lLk;+W%pDkBDq z=T+1dC@JKruuqpP6$9mcIDbjobnGBV+Z|u}ZCrs-gAd6KJS`aRq2#7*X*ax@egn?B z(XrRABTh{cXcjm|pW-G{!&6icAIiWFA6sMpb5@9~FTjIh8(~xarsl22 z38Zfng1@;%xyG^4Zu~VUgx*nVBAQn2VOE8m#vI%7r-x<0l}R*43V%a7b@E?xg^|zw zm9f?>KpI#r9xqlj5&Ne(OlN!AJ=gJZ}Du8`~);yUqTYq9Sy{B`RjOPHW6;JB( z11%I@$ehav@Nwe5aRm(We%=4b^c_!0I;<$iH94dC8SZnY3h4^yZyC^)_v8Okq+c`e zvGA%PQe9~ziH5sKMx?8@i*>+>eN*@2^{OuJ=?ucE29fGlrhhh$pUUN>{&$m(V5;->&e0hC(zw84bBq1>AjgE{o z0A72NDp)mJB!4MqZmzJE#r)G$!lz)j)1utEzo&hxYp z!=Q~2Y>#T#8uQIg@awonefRL`FCW+A9krqG%>t);qzi`TrB30GmB z(D+qh5)9KQhDsm2C17Y&$kOZ5eYncG@aAwQL1irSqs}zN@-$Skn+x`yPxdKNm9y$f zI@F5gM}Hz6)&;GP_yN22_^C*3;H(DICkos~1tz$)8$!4DqUS_Qiq@Y_YcLB_*p(?g(UGf%FfCZWftN1=?O*F`L4R)2X-p-uc6+aC1ukXR)OcoE=^V#Up!to7CeVbb(ef(^5J?-+hqCmYFri|_NZ`9$ zSvXVD88DWC$#T4T(&NT|vyxPz=1{^;Q11RPRV|__AT}s;kGVMjgv+7XZ`mO57`a|4 z@qdNRO|S+K+Cn@4nkjmqcd61{P9lQ2v=fm8T+a0p;SD*?@f_ti*I*uB-W==Etqw-u z78hucxHw}xy0|{Ak47O6mKAh))c|Fgp1C>Bz=sQ~yTsL5{pv33pe48OX| z`gph7z2AR)`gvvS_pmPETbUsRye#7RzJFqA4Yy?mA|LKgo1L(!K?QSK)Yc0OzH9+o zzTA=+fwn1*ysE7C+Ew>5iW_eBGou8kS0{rr^n-o`Rf|cTGqo%zz4j$_`3(p@9(yW(<3Nt6x5E1iR>ULVvz2 z{M%$nVj#ZmUi|L;)7Td_6uMZ)@rxF`|4f=9w-y5J)*_$XMhCRpXoYrf81VPPyhYrV zSR(p_$^FCM(3(8|krJh}5GKqTmqdQ{lhgI=H>bGe@wi{Pw>eNQbjnOLCE7c74WmYx zF_MVYL<(d$qM(R@JJS!7ikCV^^&EUiG&v!P0WPG zamva?x*r3OTx5j+!O)3r#zI})bY+(t-~loLEtgK<0XPA%mxtg1Gz!~c=RUNh0HrYyZz^@V`77Ye-|moC(^2TKvU%0=`~S)N=kgdk~>(zKZ{ z6c7O|eR*135}3YB54wsbCQ^`$OlfRAbjXNHJEaR=?6kKV=JyNw{UHsusNB8AtrdoO z)65#Iwc=%J*VZjy^=0k~xt)|n9*S^v zoC`8tQ%R}pupJ0!q@){9=Mnl8iI$|ZOcZ5kEYG&4%iXK7z1=$sjHf567*|Dd3rX&J zi#(6xRXvI3tcEi)dvF_#VmkSYZMoO~{<&9m{hCGEZ!Gcte>XbhAGe6zZ{Ls4@Bg|2 z5RMOAx>Lv)dYgO2R+Iol`;2S7h2PC}x3u)xK@xs-Yd($-4J-Uk)AS=M5Y6B3SuT|RAp%=yV>5w$~MQ!B^??1q1PC!FGuAYWz^5J zehKx9s2_O+;nOcL9uIcenzNA^fb*IFhUTqf6$SB4|m2OM#nT5HJOrLiTM@3 z!e{|xPWB8s#moKVop#*%Q|NfV;KM4HUWAd%NAMI{H=fW_|JJ>Br#@t*;N`0l{94fq z&-k|EDcWvJZ`gml`>n^nykBMN=Hnv!u{-A3PmD&hpK*0CGSzKjE>woQg;#X!$%xCsHZSoYJ5RM- z@*lv4) ze;mX;+4xfW6fyzKrG|-zCUNj10COL{if0e;A(=g`M@mj4v=Hp0eH@97VleC~6cMy0}7iu%loH zNpKIu`2jiZK>J40O(`_#uLxMH>6aRlz$_#S-|r$si>Z7Tp4}W4T%Tf5e@lCu(?Qw< zSvkvZcx2x?H@wyTe|UcR_2K2ie}=f<8seM-Wl|z*$SsoDj2TI8zg>TP`1F@w*1TLK zsvN&dVY2B$)_0mA34^bU2)%%hIvagqpY(lmW2 zHn{W}T)ge`Mz)CWi(^xdf6t2p7X8;6<6sG)f07o0|2fP75~5*FU#l)7(NT~`mVvl& z{FLd&v12rU%}dL}`jT~#K4tsz1w^s`0AfaazMX|4*~Niby3XV*`ZUrB=pFkmSpV6HjZQ9+Yvxoe;qN5kgQ#89D&T3@3gntN0w%Ya zDS7c0qlEN?H8AZ~m*6wxkaf#9TyLwl8~^i#edQPS@%b-1#>Y2aEXIFwu~;sbF6jXv zf6unU>UZD5IL7_*`5O*$=^K6l`Ry;D{BvJG-2VaqYXe|wY{B$K>wR9+Nd&`t+md67 zq>CZibW*g)B)LOqf&I>K>TR6~V}r(5=1Nm7!2htx%ym`mvOnnm0-^^bF8$5XSC9p`Bsf{ym+fi(~z;Xr|L|* zP%S}g(e{dCzPqnI*_O8UbmhMIWWy_^P|Huf9BsH}u%@;Ewf?|-@7~BUm{>-Ce+hBw zz_4I-O6}-yhPX3^zBdQY=U-m`^86q3Jk{5_dAI?~ZNIa+~9=GX}M<9;I( zkojR9XYcHy`k$G8XT2;qDfz$hExggLAOADuyglWlvD-G3Z@P(LT~iS03U*uc^W*F5 zI2wH33cq?r8~)Q*_xtKyO&C)>f1P?JwY1-J|Mt8}%b;*D;nDL{2~w$(jN-h^B8e3A z?G{9;a5a*yVksi#R2q02uQM;^%(dCPopbN!Ur%+I{_cOU*`a_kQ?XTN#>@38>$k>$xnmM0Gx{m&L* z5Z{OSqG#^u>1`9=uk;f!DoRATYbx**JO`6wXY$mh?(FyYc%GIcZhy3KDEZE^xvoR1un)+)tyN2R#e>loiG^*Z{|hN1RBd)wMc zITGxEngL_X73qDXXw(6>n@#kzuodfuP^jA@6tWCJN)ZedDiVs=02a!4bid|2|f_Yzr^eh63C_1FeDCQ>S09!XmmO+2yFJeoBBXel9! zzLU;OB_|%ibKD3ko*cjA$q7TSlgZ}8>p2=3>tED^2*t)fLedMVOuY&yNIgmoRt#0e zFhPAa?}KVhU_9F5f1*U-Zj~OnPJir{>5+ANI7zr=IiW4jimM#Uusv=$mIFmDg=+7S zZH{qc5IHcDtm87tIw{H8j&qb5T)S2$xM1m*%vpelu1EtS$RQ%JFG#1IwubvYh}5Q& zWfCPQXJj-!$m9>qZ-*UpsN$1g(1z%y0NE`HVjZSuUZvc^f5+2HiKAdUjJg0==c>Cf zp`LdZcsn)y*`zYy%Vn_uU~wwxeRG)aW%>dudVl=(Q~$UCeaDm3LOlUp9@pccfz+nt z?aH+NxLGad-V>~bV)X>!3CkIhoq_5qKZftAT?2% z^6|ZN*PbP!fAC#2^))&sltxY(0A|*V6S4TG`S(Hz855ELl173j$j}7CZKX;UH}i=w zx{yqyEb*;%RJ{e^05`p%;N#_9oV^x)Sg{TEtNC%B3C+Cnyb@AP3nA4WNFaZU=Ws(r zhx#s<*l0rD3P{35XqIo(bYfbeCz@!d1AJQJkZ@<*e{H;6FeFMVC=c-@L)D)epC6@M zk2};2PoK6qOZ}9y6leIt!jwZOiJLOGYJz8h$`Ow!vRH7r?xKP+&Z?5Z4|L%N3+_df z9^enoZ+m5XeE0hDxJ0#K>IJJ?z|+DR)JtQ_WeS`Feo`n~i=H;#m1Mp}Dq82AyzKUb zwKX%2e_$IMAbu4uKwOe6(%!2LF-9dY%D-N;Hj!x5SQD%akSBnp#D&0WtQ2;p{7I{~T;+a#* z>0DlWs>LPpgK;61ywMgy3dA;%05uqyVQ2KcNipxX8HToD6u?pePEGuh+k+|6M`Mui z{UkAB8AX&4_r3Awfb2s|T=*b3;UA@SlI@gaVBHw41s&;dOoBTb{IMXNOnQVJ7Eg*( zf9JLZ(+bbWYj3QPp_fo1q=KAjCiccscA$nHvf#i{!}&Mb`Y^Xm7KxkCmB1_+W-A<@ z1<=lR*wuSIY&$3i!q`LZY;wCvLak$O@`RYxAns#s8D)mT{vy(F#7%QPpkt8fYLq0v zrt}TqgT&Zhr7nxk2WBU33}xDtDQkiEe_~tc_1s{y7bj|zB2RsP9yc$UUU6v019{CJ zOyOE>$=pWPnzo=BN0E2&nRy9mI_ZuQFk7AWffM;CqE2oC>ON=_=kuy0tVL|wp66&g zNORu$t|Q;4@DSib?5%&B-GNJ^ZCRq}NzPklK9W&g7+yHVNXo>9&?#&qUY6y2e*jnE zq_hzP`+(-7^=5g>T(EzqIip549Q%-svJl2cW~@OTsIgxSjpeZ*TY*nhcBPd9TgY3* z{mHl^(FmG#(Q60HKc2%at28&E@k-A|wjQTG2#4D^;txovWTKH$HkT7aM-}GtVvpC% zfCM95g6ur8E^WVq&#%uPm$3ByC+vYv1J@~ZbXEaux0HBilbtyr%S=a87xn;&EPGLx zUL=ZH!LpT3muB$+Ab-b**v5sz5$3j-7gGvA_=t(QqX5WKuSd(2Zkgf2sx7EzxM*I6 z^!MzBfBa+3!s`0fqXL+Cm^aNSq?O3cPs4CK|Bc&>?*nTc2+tmfNADq=G(XENVE5n^ z;dzxHdn5}8{;rP!Y+s)Gbr5l+Ie?@NcO*StE;>Ru(_1`zAAcX5{oc>?ri3C6Wo-CYbi%A2S&)4`cAu zWBE##8~)yyh&~AKtxx9)FFZwfss?#%pr$#2X!@L}Ni) z_*$X+8;#c2!4f)FFmZOKUCA6dAridFI7~dilWv1f!NhPek)}Y{`~5b1P4ID?xZb`0 z@o|~%h#_>GMdZIWr*;~Db4iv!(=Fzyh;xuR(+W;S(+dUZFEf^1%szZ2`7)jRW@$D! znEB(xkAI9-#Jn2k1>2PR%_pn}5pYVJy}b~A{^MK0OB!Dfp5B||7fMac7z0D;h5F?r za0_2}(wC~D<#oqpbY%DdR9bhPg@2)nFONSxuY}o&pTYY(d&&XbCVeO}_KS%wr;8Cf zdjba}lhI!$mghoHp_9yCyhvOvGLm0{?evZ1S$}RI1}oc6-Bu^-ae`Ra%d8C7_L8ls z_Nw{$_2KntnbcSb-0;LWkg>5RD}Lo{Kpf$T1~L~vB1TRO2?g7PN1tpFW|IppMw`53 zlhNh=8x|HOTAfc4BF9ZD30|m~1mFxcV(LMSmzz_I^bsVvr3ihmHP4M4EHq*{v(j~w zynpb~P5ip2Sy9P5K|dT4Kt+m55N04&x^n#{`WFeQmwb;G2YY2VGDtE3l|g1iknh`c z^9w1IRR6)8lYuMbYS?&9bv-S9n92;yNA7NEuMn?wT-%LvJiPo-#I_daOymcdHd_(v ziBxn6dA3}qMUbmttw_Nt-l8+lJ>%)Ylz&MTVMNmTY!jjH#1EH@rM;fkK^>X{D^|}% z=pdMO+?OGHmf2dBVf5aVf#|cwsmX4OWz9`X$-?D6y8gh#b#epYmRNyKHQ9FP$F(DC zcfB%@fZI_Gn9@eJY9WV+GjaqwV`uf!mM`ZBmTjurcq71&Y2pbRC}$j{iRUjmaerIj zUp5d2#X%J;2XG4Gshc5>Z+ipfFP}HAgWPVF?N-@tmD{bdnP~ISWvTz7nf6xMem~2{ zZ_CX=T1rJfp&pIl!yWHcy}i{KyXD=nA-}3QzoA(Tz z5Z^i)%9mlMNPRyr^a3@vaJ>}LGN&HYNZJg$Fq&DY1b%e&`~4=>M8AC~d%u+foQ8z10T zS?S2Fa8HQ-(T`s315;;|-WFqs}MjCG9IdJZ6<_2AmgaZld6-=5`{8^|gP z(%B4^Yc<-c?p*&A>+kvF-+x-_7$Qvo)b07Cg#t)zXf|Vif9dpt1AiqcA=Z{58=HR! zDBf`ho`YaJ>J9_)^D>TrDSnV*E3-3t@|Z%Ii_5QZSnikfHylJl(;M|heTly){nAxW z?(Vp}Ll(D^?ojV{sCI|EVucrx*kB7SDH({G4WP)uKq|sGCobMpg*=#!ow$bKWkBQ_ zV;(r+qLy-WvS3un^u0u4FC=MQ6tjQ8ZyIVz4Z^Tn;P)I941i6C(HrQOLAOK%ocyWw zNVyC+!&<3oD<}N{y{s$MMXC`18@Jk3s~wF&hUcBt4tsRxYLBW`yQPeN4JR0C#wlIY1XD;(jl`iN(N*HlvO`5To__L7 ztWSp)YHP)3W#B?0;U#LFMcHIkIySz2+p;vl1nWhc?(87|%b`4>toGMllhaVUk-3O9enzPhN;_SwID z`mp5jqgeDM5wnudo+2@_w9YV;E;QmQG|~_u1u*4I?l{_5s3lyLqLicgK(09*66IIc zF?hTP_UG-$O?i}(&+Nl21x$Kx39Ft0Z;`C-Itl~xlI!<2g0LJYG$r=*^vI_N zJH4`Kc5vIIzpktULM?khrchG4fQdUQSVaSxL?{St^wH958Ww*|CguLyoD4jdLq%3X zPa${%xRn_BoPolm^hicYY<-Oa1BOfKaTRl*l*7I3_GRmn3VU@%Oye)BrF6d0Ujuo= zaSM42Wq|G{Ece9V7U4ZT`FtGO8EZ=63z7VXIRM~SQfD0V|9kVfYtUmshL&lsJEfxF zyCH80!ChQ7nd*O*dXr6uFa(*C%he>~s zM_#<~usEeLCcjfwE-juF6bWGVJz3S6mQ2WPH1Ozt^Y4EqwvDrCoUpO>3B>y+(BD6S zWS>A=raHI!1oH9|a6{6$`~=eU3G~w^5T{R|*C$Zy6L8Bw7ipMVp4`Sc0&_fH_& zCqOhWoFoDBqK^~A7baM2@L&H{Q*GQ5l-_A>Dvp)?nLbTr7KKJ+b!9k*GYgjoupO}` zLmKC)0PTMO;=#`1&`6^N+SJelXx+GTqALcyaOhURpe1gITGTz8mh+7#GaftlrD=caa^^vZ9$ny~9L_WvDhL^eD8sc)gUXFBLn zNK3Sm7OFf1j8la!Y+4nSI*+#54{fVZyjG$CQbjhTD=mOlhi!8cow_6srkGTw_IO=M zf|Y-jBv@TaigD;z9ru>@MF%Pz#&ztI{XAdqC=ad#toSW^!t7?Rz>-Bb`<1kuVXHcN~8N+vbCkJzQKAa1srKDKN#ElIc=S?Snwr z7u~WF2Iu50rBVr=UWM(h($MzKb}*l{7jl=gBdM~Z!MX>lHy=bZj-d4--}P9gtMus; zj2)nEm)bT=dNioF3fMpZ}IJ0cdNwnZuxc8<+rmw zjErCOJQ&7>kqUlJdHFeEYUZ+eT*H4S7X7v$pzblZSJ_SSi{4;d^s+LzCvcAp4eY4+ zop-AK{POhr_jf-&{pH84uANtlM<%8+{h-&l0}_r1Af`Ffyq62GFtkdCQOl7W*Hy%M zL)Hx7v}3-IzMkj+SZ8Eo=9**tP5U~@qtzPE0L&QNatePl%!zGKIb%NhVw7oq4@c8-jIN3jZeD~wy|ExLK4Y@n$f1%V)CZ&z1E=bIc%4#*N zy5Bjj29AxE`6@gwm+^Xfn6Q7QLy(XKPXdVlz$*nm)ctJDg~!m2e8*~&VaGf8PZuxo+wTI43=emQw7 zXUFsASLVI&S+?+XM%z!zn9f6iqLmOq->xzulpUk=pOmKUc^t>_=5T)|NOn-^0B%R+ z(`__9x#9q`0vXIaa!;a?QIvw)Qv*9H8AAa+BE}e(mJpPD@AZC4wX5p=Mm()j_v9)F zoiYc0CcXv$sB*4mzMaE`K=O2g*QELFls<5m#MLi$!V_EA=7S|+)!*PTbw8( zaJj3UJAtz-ZjcO|g6h<6K7IaiNxA_Pt^*_jqnx8dL0lqukmg$K-`?xv8m|td z9m|SPrs&v_iFkjsh)0xSr-Bna8>`2jv60Al6ap+r!Xs2M1J6)7^#vxjLh)edJ^k{J ze=JdEMp=VOWeM^Y3Z_6<#UU38ae^%cXtzTF%BT=HH|Bv`QiGog{PF|GEky8ONa!EK zSoHP@A>#$L95)E8S*Ll8ZE>S=BmIH(V2bG~PKHa++a7o)!G|9=1D!@^n*C*|dg3+2!t*~#=V=-TT~O+Fl9Jr33m2$O*2Ou|-A zk0cIr%T=b5a>3n8#VYn9>WRj1;ig%>I#9Em zRH_|OGFZQIt_sQ)Wih$b6hM#ofblfjW{`2PZD&fAre8ujE|E7>Q#6rEXqfD>jvRuZ zD|POEtOG)tIeiGRBmY_wD3Q(0r$igN7_QFM%G7_G4;VN^CIPYrOpJ6eZ;Mw&BkRfP z2l6g~`y_a4B_rCa$>86?;UQ_IbYsCe^`$^T+A^>=V00N6B~bjCE=N|A~~bT zA(O%#(n|N|J$5Iz7QnRhl-OdD+pbNyeY>{j-Ks4-?c_QUvy!MMz?A7Nivw^H1UBk; zESP^E3}_N~!GfHz5^v;q%==~fUH2PeoSq)mj#bO0h_@)hV}TULWveKm`UYhc#5LVv zZWuna-E+Ix`Vr@dTcWeXAza&Y8QR-vye+22&cJ-*x%8Z3m4@Xn%_Gs|15A4*H6 zILg_XW#R1n#%r_4Fzr^R|6tKLK5Idu&~bmQ%~kt?Zz1w*p@Yh;eri9jvQzsLJUF0baoB zql#;xFhaw$6efv?Jw|6DB}X|Dx)X)g(ouuVktFco9tD|L;2Gn;BHki9rDK+f@@juU zej>%##2{91%oOaHqoLForusG_gVKmvb%$uTjC^e5tdsb+=*gbJTpx5E(nk}23A`+= zs=M(B+?I$Jx;=v}O3v7LdD8`X=CT+p)d(nSHXrVYx z+?Q-Kq6a2V*^e0ysbn$fDl8j0l418GJ68|E*5)BZRq-LBw;Ju43l+;)rpvu1SMEib zbmn;X3oq_Z+q?EkN`Rr2^3e!A3T-MJtOz?+rz%8MCg?oXb)4cato~a!$H9TEm{dQi zXtUBCMyjr==t-5Zk|SJOot}S)ETza|kjgo$Yz#!Jz2Tt9f9S zRXv$*d=_Vr9hl5$OgdK&NqaAb?XQPqwKs($lS+5F*W{|b>J++)U2}88(t6t93<7A? zEWx^^ip$<=wNNKk<d#EqBjG=NcB7re zO*ot@`JH94#fBe>)K4XB7Y4}^w%cuCyQBSr`7KVc-FVo8&;Iu>Pw)Tw`t;K}!(~nr z$XF34ODwAiiJXZ<$*^0UQbDtjpulx5*$DlTtT0II z@h&cd<@id-F%Oj9F=VPw=B!0zl-`L%SYs7$4`HnIza4DDk<3RYbj0a8BU2)=%(Oum zYiD|_qRJQZdogN=gGA>EK-rXX6P|c^`0%j8PGi|aj3Yx5o`@I#u^GpfBESf^Xh9ImfZ-i))vfSWa$EVq5-W(W3DjPW=9A0> zni0VOhz;I#52s2se#~ltv!#?+S}KhptxLh{sx>sYBOQ~uZj_Z4)h=MnG*IEhNne*V zK+{d92WhV+Z?AvW7g*iDF9U0!5UYOVv3p&$ zrdd+Wxh-Rzk|?|ubKJzTZSL)4`qu)9pNK+ZWuUq{JSYr> zMTW;ni5P$AKz2uG0AJ)wTx8&2^$)O_lIt8XSFTu)yIdFI!wjX)aZn5CVYU16@Eg^I z@ZEE+DpIXlL3lwU54p)+MQ+p@Z=BTm9aMKY9n@#$aa zaHRW}AAig`os(v1x9RNG-HPYR)7BZg%QUce)4=Y@c<988Cg*#^@+6w%T{41%LTF`Z zQzoJ3yW%7r+bP0LW;TI0m-PQ+9!uKB^KK*r*SiZ8| zmZn`?iHUD4zi&uPFqQkKhnKbV-M>}Azh;rJQhWbx^ZfJA-#@;*{C%lKz?n*Xg`9t$ zh`d=DC-kRRdH%&xTm@=ePN5>s@|`e9@EecY^sBGv_wy|;?4h21{ob>gM8Mx}^_|D^mN56MB{$PGNe-Z8EnwS{Lkc3!Emgqzr8U`Oe)u3nF z=KK4*$4_g)-r9m*Oa^Sp9!diMvXXyEtz1B4W7%;`dP_`wq!h{=ILhVXLinM+QI2;H zFE1<1loC-b%J8o}^ozCXZ{xVL!{vyQeSUpdq7TQxW>9bvxo=*#lAu_7$w|C9(OXG- zF&*IxTqLO;7x=-r-!v@1wsBZVg6q@2^vJjCGIrHMDzvxTW!-^!AQ41rZ2Gd>;nKKhfg?dV^Z8M@A7+y`x z^%bEub@fuww&Lm9?d{BI<_>>Vs__ANLAnT=gv@)}%N0g|Hv|^X9lTwnFm{g z;txRr%vkXjW8xKcIdegfsl&)U*T!|YZ_2O;T7nHEw&9t@a)d|}NcVr~v_*iVj2b4S zx3{)=!H=UgxG@E-0XsRp92XCQPxNh@;rt^1na&KvJ$P-Pr`6nccH)6(8#EH-cBwon z$s;4E#l}@c>|AAaiaZ7y!KIyEPRwMFa!rGSy3!c$(4obe2L04TlAb`?YjGUI7bYGu z#L#-Wq?zQN>0eHWqw#;)*J6@l9_y2A$_~)p;NA|QH!)q1JDilx2|>0jR`qPsYe-r< z2ml!2chs_HJOKu&a_cBBXwSNm8-Nb#i_vW`l~c-OWYP=x`hgCN!s0i@EGo+Ynurf0 zO~Zzxh`aKM_+N5R&0--N7Es(2Rd5q>jNN&G=2GZhUOx!iO0_i~(`v>6rP)_Jer+DcR`L(lzCKpxior z!ikxl9EwPR=+j-Sg`6;4($?{-xR@Y-psvY!Uo!c z(?JXIdLresjhUZAq~OYfZ3GPa zI@f6=Hl#0eU6`5UlL4=|sytW;0PCZxfOtst-0B;+iL3oU)|;-_&O(L_VBb9o#`qY^t4)wN`c^NV$lCI1HbJjO;S<XA&<+2!p$m{6>8C%z$7Ok$wlP*_Fx;(OgY%e9qH$J zlgeaU-MZ7Qqoj4X&0<_d4+#L6lmR?i*lVa7x4NL)5MQR7`zAEeHbD}ZTiJ9Xi=0d_ zz+=*vKgvj{RBL;*eGfWOJy!#_IhHV-8>F0rygGls#(sShniBY>Xrh?pD}yAKyv-{1 zxe1hdf9lnySx$T!Bsm=>n<4e#dZJ}~vZ+kpxMnzg`kMGOAc*>(!-OVD4IZ32HKb@l z)kvdx_Ff9jk8F5OWc-pjx#8;;P##}AXF(1FS$WhpU2?q0mOMtCkD`G^lP!ju%k+q= zrhR{mdsT*>C;BycP1lqbiA^u7w{eYAJqJ5Z{}=#^LK>;aOu#@%(?NqL4GImZ?Rh&E z({ee>)D9+iG)`wqR(sB(kt6z)Fr0MIFOkgxK?5^&Y-|Lgaj97K-1cKQiuDoWZ&p zc(u2%;C=Dbu|>1VR1z*8IDS-TfkD}h66Uhm&!0pv6SU$Vhp4~ zhZ&@o0Wzn2$Yg{vY2rF#C=_X?q}ykN7o;GA>2ye_P6*rFTbVL#e&LFhp)sAC&64OOogl(d8ij67 zjiuGTO9k$C==#F86pHbq&_EiK)sRozc9i#zPd~q|iOxv$g?n5erbdBq{;Cw#>e^4K zK)5jd?)f`SzYBlY_M2G=H`^2J1f72$>~h^L*v<8Dwz8d8hi%FB_R{Pm@AKqkSV9C7G6~zB3+4OgT>OMNwLezLYYuz35Ak>MTx* zJ>Li){%-uY{6?V&@m)TNXnTr(j=NVo1;FlBdwuujx#VHkl5T?dVQ66>Awqxr2`WH} zI#o*E1p~df{-X5X{+yd6tPs8vNqab($1+MJb|ncJZ)=hRL>gSe0DHl?#83 zMi49?_6am4Z9WKIaY0A19CizGi=-np0#;(dc?s@XO9>M&cN8iA*tEjr;6?$vVLEs* zq{3L@)9_ZJ6ekK*x+s6y!_t7*j`=Vkb7#RpfmazotI&BpGBcU=oic_Yss%CtbP}XR z(5}94Rz-HKlOj+9c@6v|3HTmf+q@SAvY{qN;AplKB+dpzrU#i^5o800IE`txBb9P>mX3)yN2mzx^F zwg&wt%~L!@Ydl$HgP!K(8CXc9Ndr%frL%ZlV)gf#9Aj&jr!+#_yVK{^Hn*J(I0X(SOS zL)UlKt7HNYQ4m&(ZI%DBjHx&=&?|ph@)TlKjrxoT8kO5#DuAJ#BW8L;Rhaf_WYgg2 za_0FL7M4D3cNZCds^nRP#s~$usV1Z`1!~P;)S^jG8EN^~1E|j6=YW75Q&@OMdMU@F zM+r-^H!_p~M_*1iif)iQPdcb<5q%zsLS>QA$(!^}Shc=6Skpw7&!$k$dA8$-RCMJg zipFBMgI$|WmLAWug_qrj!yQzAd&a`*`pM(O#pvNo%^6R}`wdUE)qAED)O|EsY|7Wj{*f zr)TevlR89yvy|`nx}91)KWx`DXWE<>`3FsS#>+2w=GQVPw>HWrOj;DpZA1jqQ4arY zM3ly9BZ=;c^t@Wbcd#>}90Vq>3o~=zEDApmRpXUuB9~M#*NT(j2F|;I;}j!(`0o)y z3`*C6;)R#xJa$casUw59HX<^`hcie}RM87T)&SUlMPpGV1CF@Scb8^AJ-@EORh?i) zov|+=>JViWkF#B`+>8Wc#6$Lii(bntj@qVkE0_*Ae7K}{g()YALpaPB%OFsR!*zGf z(hBV8heB&d__~;F(o>Tofw!iOy`dbb|IU<`p2IK$2_Ozjl5FZYU?h0oGI90eVx?(a z(6LKRx1ZPH>FN98lq>YuZ>v%|QiCjjnMmUFOYCGgFM+O!IO1*zt=;iue0un4Batl^ zfa`2zXEI0uzF4%Cn3;+8PLj9Erj!Mq;%T$5N0$c~0wjMQpI@H-@%-uaVMSbTxyC{H zz7+ZM%rOQZgc6&XM9jqIz)WF?{+-`^5MU2a@0X7m%Vo*S;atbTnZLl3N(_^Z^&l7x zY7%6c5IM5*l%F4$!~o*S#|y)fq+G-f3xtP z-aoGOrX@BCD7&NeV9V)>2Pb`2NhWD>X)Br4&x>QJM%ztFl3PA{ObSjmJl1 z!K;6{^eMe0&yBH(!gzuJr#jn zi6<_A@*A%N{2}787?N>U{!j!GX9LI;s|8;xF|MGlt37~uYtInqafCY(LKTD*Uf zZGr90T&CnKe&|dWoR|dZ2UgZmW>JbpNECmFB)Y#p5a3NPRwIAC|6G7v;kj8J^yAgb z%!*a!#4533d2|O*^!e!@m`Yz?pMQGy^7NM<*M74pVTY1W^rV%u5yODTfP94hzOwcH zzSb3Eprf7z&hdtuZ4`*SkCz(gPRV|L{`7eTeUC@pwXQVAMRJ~&$}q0sToGRDj$(hH zSb=oMh1mk68#l0EJa2^n7I%Yc+fn7g@9gS(nWUMRm|QOO-D8OWJ}!VDZ}GZV(-2kV>Ai%A zCuup5kU|pIafpnHmL|waRgN^2(GVAf=c0qFx(wi3VYaqJoaElQ5Ox;_43~cgX+c2N zeYURJdpFN7YZK$1RV?4q*5MQNx?&lheL3+W?9L)`qf zJ$`*!BAAV_@WM}DdLsCL@uq)ugrEC&*%c)OimzUBvscDWa2t1AwM=dD-gS0B9*0Yl zRvLeTV3Yftl>xsuMfmagr|(xH&E}0|00WRBF82E)9m=k4jK}H9^mg(1%7|cUBhw$7{IzqJciAor*4{a?IClLa1r&?)eMIqenn17O)2Oa zo9V+;<-Hs4#vuyX3aPyjPZsHmvJG%=^;Y^R%7xE^;hPWz1Y-)Kv8X+6abb84Iv%uK z<3aEXOdC>CVz|EXxWa=>dWrFT;1{XC#W)=9uHy_5rDs$8TSV|6i zNk_~P0|dg%$!KYEhWTXFNqH3o6itDO+*u{Y|4YZ#XnphBUsD-zj#=&GnPtNZ`R1wo za&~U6wa12oDD8jVzP^3#&bP7A80BXNc_tASAW#94QB$wyye)4TtzD{$DV-z}3F5_r)R_8nN zWJzUm50~d30waH~3LT!nXk`}g5CvZmUvUTP`fDYhbT(h0Zotrj>}t=;c{VTG`iOx&SMJA_8&M;QEF1cHs?8mdH0AXo7K?Y>ef9buv;*6U3c~v=Re+5Q{BO z(RadLp6_87@hb5-$)3Fvv{jb>f&*hA4&Ybf0AYQ2YoLEUzdpP^uGKtry?%1m4jMqMD3VS7LIGnEz2e0WXS31TtJq3}7ke0}fWw$O#y^2e(wa ze0==jb+v!8BAt)B6lHVtQj+UL@Ph#|+S;;+;^*F>q6Nb(k{>uUfWzxX9NM6;kE07v zs^w55XkSUTs6}nWLMq8M%f<)*-3W*7y*a-CtvZNSx(2wkYfA(pqnNVPV1Z%z$(~*E zWxC%r5iCJ9;S6!oXp319zhcTg^v1$is;(o`K(d#IAp#G7M$@*JrWsxyrJwVG4?)=v zjPC$jjaJoNP;zAo7`WZ;^MyCJXWxx>)p;3yj!WYt?~<%6sd4;O`N>OioV-WZ;+)u1 zsc_VRyY+=e@}#t0?@p8~p^Gf5n3d4h!)knF7QSzcpi zXKm{s6~_%KW3@b2@6=CJqfFQZON4$fsGv%KQu*0sSR;z0^h#8~C+pCb=+{hH;0I;Y zU5$B!UtczeBAoK`@5qVDOP_JFPkT~F?8tr5d`ymiyn<9jn+ouyx3~|E0&Oq4065i- z^_FIx1SP&`4uUb%rHfzDJ`lGs_UnyrH177;`R75m zFP}a9Ef<{Wz%nDSF~cJ+XT(k5Q$H&i~mtz*LS+M;Ho?TWVVBoO0?+IK$&6jK=0waIM4;1)@ z3{V5}$#??!zj4(?x)-t`6XDL7m$0g~tLgqt)fU%PXV}xP!roOQxXa>|=fKf%hL21T zo*IF-VA&B=g`mPZ8}r5jvX7P@av|_vg=b87sj@wnY;?|N8W4A%9vd zvjnP&K#fnSA=IwFw8I3o&T-E09?yREOB8foAD2ud0y%%`O@|~1sOM#l6A8oK+F&-B zI=xZiFUMqxuDm&t7zVS+dy8K%1WP2p2ZZ7xYf*!IX4@ zxDeWC^Ujvvd18V(7O~$!kcg^8ji}L>s0zW=Omu--5}ZW5%6Ef&OO$WdnVXy3?|+p@ z>35Fu3;cgO(`!kl9G=5>OyIOM&M9CC>;&~lC7$qICER|Z4+Wl>?zyp1zC%Xik!g+h z*^1NXc;QZStU*CvFaEsnCIOJMl#rI=XT1)mL9*Uyj-Tbu`sSHEFiMDnu9cJFFuSjJ zng2q{`{jx?se^pS)VJx}?P&AM$JJa(i;K>Xa1u1|7H$zLNz5D}mxUuFMRN}+YYmrF zQv>c1wxQ8CS`a#HdVwOZLlTG_xZbYm3_aUx;eWB0w_=VWVi)nxuU3|*k^0Bamd{%3L0)+r@3~en{LL_`gSGEX#sI7@fe+qY%VNETSKZ6 zyqGT$u8jAqPv7a!J1X0(UunX#bNsAWJuXd8Ch7Yf0NS-7M z+%+BvNvFX;Pg&8UObJWadHspVmci}xp)0AvvE8DMI z7=9JRW6EnY?cLGXTbhRR>v7&0=U*jN5*BXww0Kg#6@mP`f@LFbne??HCg%{~@WEz` z0lk?(_+4z#D(shCCju0I1pZ8_9nm8hbS^B=-01zC4T3RW=tV-RB)kensIUBo3&F`A z{FPO3Vdl1WOvH=A|3;2DR+lT$`KvjB6w2$#gP-5VU;M_I**MeVjw`u;!`^d8H>IZ(ejmxU^6FBbTW)1ElxQis9T+z+LTe*h;PhG&6hrD*Jw02 z#zm$ER+2if2nkq!RgI7xq8akyxnz4Y&1^d{oJ4jseiA+{E{1hG9xf!RCZP&G=5*i& zKE6XxK%vK%)nn=_Q4$agBWU98lFU~eyvSmnH6tE+QRcaew$B+C^Ng$^a($atx_?MW z7CLS20*TCL?`Ce3#-+IJ5C8N0^N-J;9=|B@w-ES?vmQHtcIX>cGxjYFQdB?y;ApuH zWNkI585iv*x`i6Es)uN?1E`ne8ZgGg_` zQ_|?zn*i#62B!NaU3w*FdD7W8I4n>1?H1lQOk5G(T9m&QyzHZKJE%}}kMlxH)ldZt zL&18PW=0_EQ7@!QA>m8pLfA(O40fqWLt+~V!qJWw<%fz^McKOLa&Nk;a{LzI`=#fg zDer>)kIK7&q1wuhOSfkwikrDYE zm|-KMM|tmOUOZycnk1;Q@Ua34BTeuiOiI{(JCxVn& z7SO1FVG`0RonM&^a+&_No{QwhH76TE3&k{l+QY7Saymnc&z#hC@=^bP_TFSWZY0|h z{T2TJk_*{d88$*^j}M7pA4F~Opi zVhx4|A%uf*0Y(e(=ZQy@{63rN5F&DoaS7pIkxj0Z(R3aTmw=q&x#X1?kxgGON3xY zsChukrjZepUHTTG{Mg*=Xy@i}q zYdjI3P)R#so^`@x{8UBgICUD1;$0v_aRja=QRwSI!fi+vQ<_H{e2}Dn5ey8)j>{60 z2AO&svk2}_tLMjikTaNhJHq@Oa~C`F*4K^T)_RI%PK49&zoyBO;F2y&jq0lLb)kQa z$*GZRs3o>MsGQI8_g)HT$F=1Wp62GE-)}07JRYuzFjc~o2nzKC5+Ml~L1K4&KGaKH zTT+V%vm7$Xw!Fl(xBBgW8tQ3HIrW3V1420|P{w#3$(oMPs4T@Y`Gx{HD*(%Mezy2? zDDa9drc=jGKf_bIE%Bg0v@ZT^5C>{@Dv1vSBN)V9S9uAST6TehiR;cv`Y>_RA z8F<$X3H&ZYurrY(JV{u$So|9UL#D?IzSEOjD;Q9x&NP>ZZKvdaUf=zC|NGNVt9q0P z=}B`DG;@<}i?(cx%r=ECuNOws#vu70Q+p>A8tpWfaw?d{wT;Az z8q4uMT-UIYih3(zgPr2qjCsSmog2`nEC|vM@TGwm1{NgLtR$woan%6D3=@d-O()Ce zgjZ;C1yAZzwZTJwXL-*lsLe|=Lc&WpE@cRWl*Tb5@Cv7tIl$e*9ZA9!mZ=nfDME>a zI|GC;!w`Tct9Grd7vk!L29T}D=(3#SEHTLNdo)5)f*wH$0ytGP@gl1(`~^!Uq&cIo zim^x!>R{Kx9E$^0*PZ9(T$}^^x}!EsyIv9w{2lrbAn{~>1YS)`IZ4CX+ix}N8O$wQ zl0Q-ibCf#+>I@HhD*eGlWg?Lo7kAg+xqdA-U*6db-TVmn)%0k%3R?^nNxA|ys<-A@ z0({NeFdB~9kokXT&A%6R1LO$e`EW_l;7n*im><6df7Qvo`YmL+`yE<0l~pVmVp z^H|d|VhV|?K)Rjf>!32livbj@$VCvSRj@tX>CG2^x_|ui%ZIh=jZMQNk^#Q6jhR#O zJ<)EA=z*Doir6Jxr-80RW?K5D{;;^xS*$Qb7}d-=0kYVjz@FBtDHCfZeR3|mi;4-! z_|i<(J^F5XAj!Uw!X5Mn#uB08nrkGsKUmFJ%b9XN*FAoQzvC*S^G`72`0a$cgGS_B&L7kRfUzlkK z1W0}8Y@iY-J*aD>G8kkq7!SR^f7S3s5i>%6TfBO|X^MbHXnkQ4xFW2F#Up;VG(Nq& zeq2wCl8Pg&i$g*v6y;neLr@%pK}wMFTjO$|DRGgc>f&VtD^k>SxXB2SpmV!dH~H?% zygt4E_HN@&CC`rbKw&CpQ31qFqQCR5dvr^=O)gz4oQneY6N`+`UKxaX{SO1r;j}uIu2r*Of`wP9mg0r6rV419s6y@B%z(uJ5hlHrRWTnwT_ z&BGB=XLOYv7Z>3Yho`eIQFaBhXh&ru491O)66ho|m%c^HK&+#!wI=i6{x*B#bLW zik*JQc!>nbFB>m#M*x11e4KQ#xq3wG#F?dkoud{J9!x+u zF>-j*>yt!#w)tV>p+A54fd~8a^!4|b*S~H>i|WRQozi?rw7BCs;V7+;CH#c#)2n%| zC9Nx8iHdKs?@6S2+>r+b0PdwPq6q`TA4snjGHSe;p6EwTWT8mClIg2D0d$-jrIs!f z?n8v0ZXC{Z>10VdDB&}I@XXs%`SA2^!yv(g0cor?v^wBZ3u};eyf7sYNB~JpNV;OtI;ICqTc(;Xw*a1QC>4&$${zDxNB!OdFG7HYV zxWfi@LU76j1+)>0rUr*G0K%1(uw)S|nGBt)utvGOQE< zHTkL1;xuuXt}*q7B>xl&{IUZYw&itxTfyw>OpSHd-Zv3DvmD&SQK2G+M3CuA94-OIY30!#7$f zyLQQcXN7eJGgAR}2BO#Oq6}^uQQ!W}`nGbt8HV2~TaC7wWJ5buAj^hs({WK;?ju;mfJGLv!C{-8b4Z1AQzsHdY-=P>wqx*Skl4JmOyA_riuSpLycr(ggq$cTMVZ%V~URK6$p z&&RnH{6LRq`n*nNJU`Ik9@!{)dkV`)R~z`gAkJz=b&wATN%eKT+mq5E{YScgU@W9E z<~d|&Y`^L22^Gc60##X5mD_$CMRKjiz0Uma@4!EQ_?PtGnyb!Hi#kt}|Da!oa{E?) z8}uLiz{X!IO8C$vkSKXmSxa&SY21_T6jN_2+|#b-0FWnfM!U?kqxLiGK5xAFUYKfX z-9U(}Ckd->lKGeo4QDl%nJ&SFrn@OI0G~4r^O%9n1ic`X%Vpa}U~B!2LH#(0Fig=$ zDU2jZKR+-c7=gdqTxR=m;}Yj;9Q=BJVcQ9G0XtG%yUxqvism0Vmw`hgIi_r4jEM11 zehL{U(_c^mihA@i`X1NwGGg`SeVXpX4Q{^g3q1fBx+09OW!FS6&KyM|NE=aUic&Wk z*pjD#F3zs)coKedTj@KY4no5QT7ftbCj_mOO|HiPqFn)bE4ha(#n=2slrvF(l#?gZ z0*|U9m3U5X@-S9=+R2+kz7xo!#dX)0ot{%9a^LM5YcbiFWS$1f#R8?-^Rk{QGjyRt zpx+=gC2Gr$=40mh^C0~m(~vGq%Q_u4ZDlYcn%=G!O|7@SMT4|9igp05XhS9d zEr0+fIg=NH1`5+L#QY6R>afii&Ox|~B(F~sqG{b9h{9sD2SSgz(5j4oYaQ)&$57z% z45{TT)GhzeUx-A@+MgwN=mwQrT()P|IeZ=Fn*_B9NN~U|n3t!SQF*(TcLaIYj5_uuWyA^y~qJSqWP zu{#$;RVGuAG#>I|Jf*9Dre2AC&(Ke!Oq$qVk;&8&?ZP{vcfB_EyX60vp&12vnhSbS z_H%vA)uY;4R-vku6P)F@x^5YRD(l~K4)A8J-t@iyNtH@hW7%l>t|gNnOi_~ln1Re) z?MwYc>rC%#MvGGlc>&aA8g(J=X*#F9QG%Z~%-8>!qx@&jQU3LRJ?;NYh5leFq{3bn z|6C_?6{)Znwa8js6#lhBdi_{+E$R?A+Nq(h&!2wzvc=47>D|tH-OWxKRd3Izv%nSvqd3L_@=H(I~WVbmheh8>bYrV-%>F-n@9Uk#TK4FK@?}h$2!jv>9l4 z4RddT>rn>8yRu;L3zBLgnKX1O30A0aE^3=l$GJLm7Aq-#8U?4}UXekv%$vzP6c)o0 z7#--6BKuI>FX$5ouOafoZplax6wH+QaFxopS-!-PMS%{%M*k{jC*~-iQP_;jT1A|v z1J*%>jlq-Y1=6~`_Na!OQSt4!C)FmeXzP)#{5M3qyBY)^%9!7L*3nplQu-BnU!Nlz z8(;XOHpp^+7}Yebc%0F7O6_RoNaLC7_wm-pdSjhfMCTj(22HKXgJAEGR8TMBX3E#7 z>!QhKb)7;{jgH`Gd?{&IPbziL1doDJa<8epmlpZokLB+~m z=0B_w+Z^>j6<@N6TPEnQS1DYdk|A&%Xcr|cok%93MEfZ#|H(XcI49+i6j$c zJCuWeiSJSJscQZ=vP8fPmcT+`f5x$j&|goIelvEBfORZ)k!X_iG!mqu5RSsYN_qWH_-TVDf!{Ggz6_j^Jq33jT?&Q55FLeZ~2VFJwKSjR)%S!#UO{zhorrd_xz4pE%kkr80k91{ln-F9(QX2Yz zR!#G^$bwqX`eu?oeQocss?l+%-yHNK_dvOUhVBmQqfGofO*=W41Jk-LAo0k5jxG`M z_0BKY9#7Jbk1^RPcO73qcQgx1*ENivSt(;c?Ie` zY-bdHn7T5GT=W?Qeb@3^WpMxT+n48eTXCTk0WcreT$=s{Yr&_wEBIufCVwzn-k=BU zucQ}58Es2)Z9A8b3Z*pD#Ew9}3_Hdv(`)_q^kE}@0KidoSGkoaG2H|PmrBpW)uGJ)b zObjBMn_gk}5xf-7(F-=)Y~+VIt`Dcj#!CG(zbGa@O}yWFnoa9Z&fJ!uK^jCd9<<)_ zQkHN{uJ?GH>lOA(_y+fPTgquJp&uWnC9#mEqUETV!J=6pQFxk$3R z7Kz423c*5esF&+bp#+IGWGj^U_2bR!gE1@W0GIBb158e)I}>>Jpkb`?!a)w!(&j>) zk8AJ>n5(qV zVRY5d8JJ|ESGs-EZ$JOMkq%Z2A#^a7XH9wgE=<0U!JL8EcPa@LGq_E&RTq9QUEThD zV%B!zv^zoi7Z9$&e#vi)W>pEyv8%*6Ps6X0a9<{aUKcWd=x@Bz{rl%Hk3VgM4II5^ zE+S4jnR=cW^sHxb)5xsR>^sX|x<|$&WVXN)%rgiUV+S6KIyK6?oP=x;77Hift@{}<^uT^~q^@Tc z<*{`qA<6wp^0Ry5R^l8Ycg%voMWH|aSjW3?`_3DGf4YD7`0bW3M5$D)#410~EOmDw z?I73y=`7OAoxY4VE$0|BqB{)Ps?)wR9pAVpW0ey%o2-Wgkqpjag#l4%rZJ*4Kx$3j zsXO8*lvC;*oJ%0|acSUkLIpZ;rWl)k)Ux`DXTpni?mEI`A$r`>qQl{iUcX%va9G-iQ{r2VD~-Sqh9_QRNX;e2ydOB-1ha`rf)nK`D2&OBmc|YC5Zv84LpH87?(E#4nJuJi z(OVZ2AxuA*gVMN9r?);HO})??55DVv_y_^S={i!okh!Ka(e-H@;|!HG-=r$=z(pmD zqo$wIvFC+A7eZiE^|*bn55GOV{=SKO zR%vxiYfY*dK%sZ!ngU882QRsp0jm7X$;V=_1rb7&_FGP^t74FST^q=br5s{^6^Vs$ zIIq4^*h1#is`T1#$L(EUXR3^1UH|tUYu*!#cq$mwyc9!b*fGQxMmu0a6 zou?p)EE>5~%IXfb!bW1Li?|o&W+g=Ebq{-^w+r(A=MA6m%{L0f+j#n_6MI94A3Bgy z?1suUjrmHau&qc0o(mM}O#=3RW;xMfbETd|4iGP#)|s9dxJ3CX`cYP zS*8qCwMjg)UXDpzndN#qmLZB=EzCrL{Iuvvz{dUNpb8Dyj^`%wmeqDAD@p3!3z zGKp9R1qKpco7wbI=Yo5Jr6L_oMr}cvEN!+Ew|M?||M=nQb!!%_>r_sSjYg&W`~x(1 zr$^Wh+wI1>5w|P?LLpGeC2j^Giz{hH!`R3W%{-yul(No(7YVS8O3Zs^VKWmrOjI?o zqS)Fh1s5`1j@8@)mSJ{(pWEmE`t*h)S`uzF+r^k1HoqCh^n>LIo z7AHJ@T4OPb882*OJb-1_-o>T?X?v|`mvVO!Xy&!1W?)h!I8@(%xZ0=f3e+qH8HzZ| z_T225;77Q#sP0!WY{4eE;8*h=f+m+cXgsn$W%rzEK3-K+AWp(O;I6BZy7&iAw3oX2 z6Q2wL^-%*0r;8c|x)nPQ*tlaED#V093hgl=w}=Tf$+ty$TvSZsvo#UCvJq$N-Wz{@ zefsVBWxWuf=D2BpxMr#4$|3PWMbuqn{PJ4=@H!=rIUgCp)VsPj8tUeeexOp_&3)a? zv$@0WDXLVf3agl_*>`k@UW2O7xq9acpX}@& z+L?)tfWmQ92Oyl@MLa zk{-YW%|RG{!R)F>ip65ld!W`Y)4_{Jm{!wn!BDBu z)c{UV#9kCbTsG<7lB6sEZmE5H`Vm+JmVYbc1Zk!gNzcekTeWV)Msabzw%nPs;n)xq%m3+#fecL9}1{@w}SI9DPWAOcz6Ro8K%o(iX890a;~3W2KPmUADnnthvLgT7h1 zwG*B_b@M%JOS4nE8*@+7MIdrYDNV%p&B6;3uxO6`|7qnjYBLer+^gjeKA}x>7cl zHJEH?!W9c0jgqkLj+QCh%p}A#QEeWyr5`tcTTwBCq9z=@)NF$6_gT`nWxmy(>lW1vkn(k`#(M3wdboV1YEkSW1=%B zFxgaPHzD-_4wMQK)M;N1${~Yb!3EGLcfU$q2xmC-*7<7e&7yb#qFyZc=bwp!;C>>mJsW8XW~$@)nN=G~$R&_B zh`0essCMxLctsFIlex*e&bnxfL1ZL<(&_C-%sqg-bf%@Pk(d8~GpKtY-2mQuBIE!Z z$(%EK2E`i+h6r^GC_*w1k+En06RD(4Y)eB7q_Q)~9AA3icdDwBTreulg%h6+)-aAw zlSayC7v*PzRI3TFhm`~2F#$TpMJm>`bONy@W0b3D#)ptoP&iseGd~1!22E6duB)TG zBTeJm!$`pZGXdED#wzrPLCL(T8lwngKzKV=wRDJudjU2%(BPSfl5`j?gYqLBL76D3 zlp_x_q?JH{(&X}u*#i;Fa^|EDhuk7X6)2jlnq9aAa-3Y{rlO*|$iV%wuf!EeG9N&0qAmi3C z%+=fc8DR@)QI96|KV6gbvg~Esia7yUL=K}k!hGz!;)6g&G|3Rf2VQyw4Wfb~MW=A^ zqCF#bVdRzX)a^FNYoh&J?|=K5KRvA?C0@oQ1=5Z3Gh(bGBGi#deUq$z7}C8$;ZQa1 zWQO&_u_@Z&hCcI)ik?90bb$Fo1&2#AWJnoPFek{Z396OD?jvpkQeG@IIDyE83nPu6 zRXAyv9Oj2pb0hdfKm7Y%6FO~o^IL@u$-@_d1ONAL_VMMf8|OTwt=_x(=^qdD9*by%7aIfF{46S`Ms zfIUV*DAdzJ3P!lS%?O2)t<7+<$Kd6ILYYTSpAG>5%}g*UFc)Kb^85 z%AalPl9-ZV^)qzUDo_SLfB2$S`|B|O-L>v4I~TI zbfGH065({~oTk#x$Sdae*gKy<6oaPUYo_J$xH~#Iggp($Zrp_j{{X8s{$jD!%{JtF|u`( zx%nJ3Acmb+xb?i2<_agmxie$o3`b0>+ z&Y+DVkZqxI)nN*>b`O>#Zyfa~QS+rtBV9dkc+lKrdX0oS<;xY;E?yZUe6&L-m1;l0 z+ME}m8?-L0bq?zp;9={6X*86q1)kJy1eI2^gYKnRCte<%^NaG$QObHr1 z;RBDt=!?!|J01B_^+5tDIdlnm)sdV}RCRoZdRjDtv&k)?$`Mf`WAb5HB+-xwwROwW z-bnVE+{edHTe|Cp{Nw$Kh=tXWxR^A+!b+={)pwxr52a5$Mt}D25>;^$RjFBuJtgRW zg7pXTJc=;G=*UjAVnhh}#84TK5I~fFMe)qN5DkDn$fL6YZ&o6GrcTj(LD4cuCcy@y zi>U2^WcGOCB88m+p$8QKDY+O?y$Yxe1aYKpl_`^Tm!V3tCXe|wxr|HM+~>Q}J}6Ze z!YaPnIs&xl8jGeGX6>_$;J~fFq7!kBkVVOinqp4_t>NR4R#e{2UQBM@zRMp1>K3;!SGmk5dz8e4$K%(MkTiPL;tu2eEtapN3& zo`!2p6$aU0c>*iYk6<9yRIqT-z?tQd_=N{?Tyi#X9{h8e^AN8Tj;ptTT!~;(_7$B|Z9s(Nt|whCV46>5p?gWOYu} z2!BnA&&6Z|G+>)7joPv080gAwL_l+E-fQANKd#L)@)q7-Wl2^SdkfNiN!-&FRg>oe zv$Ez4OlN~(vt|f@y0Bt@p%PHM(X{|ij9}jtTY%KZ{_Iuxxp3hWVXvN$je~t+sV^M9`xN-ych&+42_7*T-0L}c|T{` zC*n^=6Z0welkxHN>j1n6StCS4h~Juq0`w}dTWd~uc8J+eAI_y3$rW*25Y(p51V`#c z3jRadFTyYHo<6;Q-?Fxc?si0UyDBfuLJ_K61=c(-kLv8T8LTqRJSSiF>+b#2TX+7m z8d7|_;e7h`@#%HV&n_I`N3OY~*GEhVqvweOZysfd-4sWUT7l+nMC}+7b5akH*d5zN z(Ipt-$23IIa=Kk76B$&9A6}X=(rrjK$VeA@TrHc0CTAXh)T26d6X%$0)0?mJfHf>* zrwv0zqD&`(4UGnnnz#?l&`&RVrdc?eBT^2ITZ#u@A(ffD=fWJL+<;|2XY#e!CRCF& zlW@3pq|!&`Bod6bk*j9Rm=DF2M+0A1EIH_LNE0|v6iVt=(e$CbRFN8jSygFZ3<37M z=S~W~FpF+~876EK=^E~AcQUxeKyZW1%PEf4u>&-8<+_9F9{QI1D&Nr~dR_~cOudm_ z@;3SaW9LjCHS4Db=Q3K^S1!K;2l&~oH89E+8P^UH?r*&`iC&h#8^PN$ zcV(E3kR5SUl!pN=M;kCSv-565KCi?X{aSt=o_=;C_4HvEX zvKy~yB+d^xe`nOR-;}GA!*-^<<`f`f8YybO=CeH=n;C+@WS?>-44o;|8annz(F@q9 zkEW}nSvs5AK!8NwmJpocOHMx(8bUI2jn~LpLsaVMaWqq=)StBQCKWD&05Kiu-b}sB`FTM|g$%o>qzT!=8ym zL6d8it8KPmW%Eqv54p$_Mt-XIOQUqpfF8BU%9qVoFfUzdnz_*aH}F?9>}`l%HeEGf z)M0*~f7*>%Tf+I+z8L$KT}Ucj8VLhdL zO}&jM^DxKOdDt5DOYPJe?r^=!S$4G3C*F}ie>RZdqoXt>pb5;qO_gmpK2)*5RtNj} zP9uJO_jLc$>*J?)zixR60MKO)p_N~9QjICJ?{QSIeF^>+$?z`mE?A5BWh?_ajmjkC zcIdi~snUe{0oq>(#F_{oIrEI+##MNvtfM0X6@7K0$ret(#H6VrBlAE_@>;ur^`P}6 zf3;c|JOQkZ_^PB>KRZ+k2Nr5DvprFp5Tg%ucgynrr2 zw&VyrM_|qXXfG2XjdAtEp@>#n{8^TMzx1hJA9cu9$JOuC>V&-d_4*i0a#kmRIJEq8 z>Zg}~*6q=^TGqRlj~}16QWH`l0Bpl|f5Catzw{AxVkm^JrKQZH{TKW_Cl^&x$`XtO zvc}1t6iLMc@#`i80;evzuAlQ%aOD z3!e19IIl;UfEO&LVi^;Pttgv-e=LCPmA*z2xV@6$5}Co5GiKsZVWPPxU>Kg$p~h8m z>!3s>pS}5FtkXs75}$tA?Br&8*21Q@*e|S*e6nazcKtyHd%9+i+n+z{eUMqb1A@c_ zy>Jq;p^|x-RWw0`6;{QXA+Woeo}|?jB(G*4WpgY7;}q93jp3dW@l>cjFyT`HW2ly)1a~1xZQZf@85GhA z-ZB2uxU$c#pF{jJgBGAmts3h>|3q{vio_zSMczyz;y_UYOoWNdmAE-5946{zz7+x7 zXMAu9fF%wBWV&T(RM+*if84ES`cO9l0n&}tK^z-VH;atAkO3G?V zyJp)c$5%i8{(@(Fv`~7sZhC9CPL_lBpL!!r*Y{L$Nno0YLeH#incjezK;RA2P0p-X zaii<+M7(cX(M>D){Pg(OoAmZ-lx}xh#a350gZlQk7u;|? zc}SbN#ju%sY>s=Te^29@wYiju?Y1+(BA9Ey+yzF-+Y@|XwAiWRI0CFkTWmtzrvc_J zt_2SY1rN$nsGw2s09+dW1l=07+;>zDRF;1LG`}?@C!C9}8>6&By^ssk($KB0kIrX@ z#zdm{Esa(LNMBbB2k2z(UC1qXiIGKllF)`B1Q9zdZcj!Af0Ebh+L~F&LCItTG&fPl zq!mx^H+mQ_w>{4xh;RX}%(DgGUYALAz&{w8`P>E;ZH9NOYl8!XyX{oi8>qFsRkOc8zdn7~FdfByL%6@3447CHOSOnTU4U2( z?g~ffw!mBue<2^kUxEyK(gh=8=!(;3%6-#Ni2vgX0x{$s$tCG@@g(P2AKp`cW#-

#p&@UpG3gMc8^tp5pgfnPEI+a1VcDAm>*x>b9;HG?B zWc>M2ue>b`2XS0}_@34liyhNd$hTW6l`KEnXG;jt6k8 zkg=rHU!ebqxVM3mf6g&v!!@IjsuK#y;Ob19M4Hu`#}o+IfNRkWhjw^VC3Jl;7GoHr zaSo+Fe+AXIfgcTj$j@bURiSYW?OL($ux+O6^neC$7RaV=57Exyt6uo8 zWlUzcFN+2nfyoxpYfS3JvYOB|MYtHs>kBE{B0}zkhGkwWok*)ZTjK5{7cdE?76~LMQ%?#6I8jh|f|Ou4;L6A8004_w z1}{MGp8BtDAN%F&^Ur_VctOq!UKA(cW|^g}YNI>tnKH1(qn?J?T}g=7|pKFwal zOx|aif9PqM_fvCrWS7j3ekSD?p(>&xf6bKGh^-8794rNzSt7K-N)O(6(O5SgI^Y3d z4lcb^W9Uopp#1PWK77~D7xD7zb~z0nQbHiSqdkrjw3nv3#ePFRhV)+PE0`l8aJO>Lh2>%MTj>BW;f14eI z&1Nqx2Tb@cG&{)jCC)!(^>7s3aqO5AeCum1z9AP?%(HZ27m}Do}0@SD9F?NA*88 zui6|R-mKUApPn8+uJyj0w8B-Ke@T`H9Dk}&ya`A?=|nRTA5PNZp*;g=w@SSe0WSw) zXK?yq>ShbPVz3k#L?d)yV|QUepu<4~2V7Kcp~=x+F{#6CH3N`Z4|k`m6~4ZQNzrHNV#anPIZMn z#Xvi3B&;hJdQ!q0y6P(20d8K7hEi)72Lsg*mfk)0{`u3pO~mE6T9`>^`zE|_%$q36 zWg8ON20DQK*aR|;>kt8^f1#Ic3iVjX!e|`E|AL9*u&_%N_+sZsl;(cBIU>~CW#<6y z^1t3Jr2BV|Uw&O{pH9C9Pjp%&YVL7G_NE8UsJ2H4diD{Jip>#nQotzP9^hTh;=7SA zGun10vcP(=N(4(aSBDD;1nijwYYRr0qipe}(*8 z=3R=mrV<*9pgxETh?QRL2`GniA+KX3*^lKC&2im=hVs!Iz-$Ua!BZlKIJbiUbFE(w zY(7k~r!UX5bK#R?e+Lwg9iz_}?VAC{irJlNksoaa;2C9$CIMPjt#L=~4O83c8>bUoI46l7((W$3ago=TmyOy!Umw^#cAibPe;q_f;S(V} z^T`}G$V8AT71;+q_EUw4i+!gq%5$-f5xhUyY@U%p?z}z$e{=!dk>E3^e|Q;6zz(n* z@quN25)-iA&9n`uJ&`li);Wh|~wC1@(SIC9~ee=_{MhAQfFxB%@loos4M$Mt|(3x5hx8f2B}MjxM=$xZ`}lPCR!ecx3WB zJG!w*1<;|u+fJ#zfByDyZL2aZCD9(I=6Q!SL4Xuf6q(Yx$9m`v@=(p-M;+`qGoyjt zk(k1QWyY%%XT%@`u}B(u&@y_Efu{l~f|)A!8%T$m{^$q$$^2=s^=2W)yui*v;H$CI zqYgy^e_yiW8D$h6jAKZ_Enb*nV4{#AkHnZo%LYz#0EZq!3-YQq0`81uH?@ z-k|scX|hPDZ>(dx_U~dBvUcd`z)h6J4q%Mcu2?NQSkj^2e5X2}U)TC?=rAQ^9Hf98 zILjI&sY-?r>_4V&G97onx|=9ip;i=ef!=jrf3rXqA%VWpsA!d(RZluEbD&WD)d|H` zm<{ep)$=-b<-I4^lPAp--x2qV%Q(UMs}W*=ct0`c*(lsJ2r`EUJD#N!;a%Z8QlBuSN2-`%M(nKSUPT5C1xtjMR&^In1JIZv)D*dJM&<$-p&`TDTf{0o6B z_~*LDX?%?Be!X9S=$R2F()w}j?v=OnB7rt4$tfw9THj7QrEk~8{+brs;G-K}e?5*- ztRxg)c<3)2^#9@^27CI&3Kpe$Hrfcl?OeWaF7I=fqR6I|nFKBN52G+14)3_3d=6DI4UHRd{LrI)Q>2o%vguG<_Uv z$%)F$G+Teuvs&`#q!>8;U@-BNf21uo4@udwLGwhlXKU9pOn)dHyFUQXUqrb(QIb(M zwa(-%QJ<1f>PWdBV*fG@dW~~$wfvH}6m3jT z3#(pib5;Mt^}Af}4R4;B_mqsjK0UqOn(O}A+Um^vHm(pAE|RT4mgJPyf7*>RFi;il zsG`mzsEs4O5&g70%y{22pY;GJ-SXFti3 z@6_~gT8|BMqMi?CU5CHiDZzb%0D#xHq|MOrH;MnSqmI73z`frm(`Z8t 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 XUSHlleR!ol3U>W}J!R5y)`1BCCrhD5 delta 139474 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

sHSro~(ge7a#=;L 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 IIih_D0C0=)1^@s6 diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-history.html b/homeassistant/components/frontend/www_static/panels/ha-panel-history.html index b665faaf2fd688..5d1f6163383dd6 100644 --- a/homeassistant/components/frontend/www_static/panels/ha-panel-history.html +++ b/homeassistant/components/frontend/www_static/panels/ha-panel-history.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-history.html.gz b/homeassistant/components/frontend/www_static/panels/ha-panel-history.html.gz index e8d34afeb3881be70a652a0f67c11d6162126ebd..4d7d1ec9bad4e30fc9190db079a57acc271691a8 100644 GIT binary patch delta 11878 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 literal 11873 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 bD@J)Wm^d^a!y~u8%8vgxLpoD=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,e){for(var i,o=[],s="mouseout"===e||"mouseover"===e,r=t.target||t.srcElement,a=!1;r;){if((i=this._targets[n.stamp(r)])&&("click"===e||"preclick"===e)&&!t._simulated&&this._draggableMoved(i)){a=!0;break}if(i&&i.listens(e,!0)){if(s&&!n.DomEvent._isExternalTarget(r,t))break;if(o.push(i),s)break}if(r===this._container)break;r=r.parentNode}return o.length||a||s||!n.DomEvent._isExternalTarget(r,t)||(o=[this]),o},_handleDOMEvent:function(t){if(this._loaded&&!n.DomEvent._skipped(t)){var e="keypress"===t.type&&13===t.keyCode?"click":t.type;"mousedown"===e&&n.DomUtil.preventOutline(t.target||t.srcElement),this._fireDOMEvent(t,e)}},_fireDOMEvent:function(t,e,i){if("click"===t.type){var o=n.Util.extend({},t);o.type="preclick",this._fireDOMEvent(o,o.type,i)}if(!t._stopped&&(i=(i||[]).concat(this._findEventTargets(t,e)),i.length)){var s=i[0];"contextmenu"===e&&s.listens(e,!0)&&n.DomEvent.preventDefault(t);var r={originalEvent:t};if("keypress"!==t.type){var a=s instanceof n.Marker;r.containerPoint=a?this.latLngToContainerPoint(s.getLatLng()):this.mouseEventToContainerPoint(t),r.layerPoint=this.containerPointToLayerPoint(r.containerPoint),r.latlng=a?s.getLatLng():this.layerPointToLatLng(r.layerPoint)}for(var h=0;h0?Math.round(t-e)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(e))},_limitZoom:function(t){var e=this.getMinZoom(),i=this.getMaxZoom(),o=n.Browser.any3d?this.options.zoomSnap:1;return o&&(t=Math.round(t/o)*o),Math.max(e,Math.min(i,t))},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){n.DomUtil.removeClass(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,e){var i=this._getCenterOffset(t)._floor();return!((e&&e.animate)!==!0&&!this.getSize().contains(i)||(this.panBy(i,e),0))},_createAnimProxy:function(){var t=this._proxy=n.DomUtil.create("div","leaflet-proxy leaflet-zoom-animated");this._panes.mapPane.appendChild(t),this.on("zoomanim",function(e){var i=n.DomUtil.TRANSFORM,o=t.style[i];n.DomUtil.setTransform(t,this.project(e.center,e.zoom),this.getZoomScale(e.zoom,1)),o===t.style[i]&&this._animatingZoom&&this._onZoomTransitionEnd()},this),this.on("load moveend",function(){var e=this.getCenter(),i=this.getZoom();n.DomUtil.setTransform(t,this.project(e,i),this.getZoomScale(i,1))},this)},_catchTransitionEnd:function(t){this._animatingZoom&&t.propertyName.indexOf("transform")>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,e,i){if(this._animatingZoom)return!0;if(i=i||{},!this._zoomAnimated||i.animate===!1||this._nothingToAnimate()||Math.abs(e-this._zoom)>this.options.zoomAnimationThreshold)return!1;var o=this.getZoomScale(e),s=this._getCenterOffset(t)._divideBy(1-1/o);return!(i.animate!==!0&&!this.getSize().contains(s)||(n.Util.requestAnimFrame(function(){this._moveStart(!0)._animateZoom(t,e,!0)},this),0))},_animateZoom:function(t,e,i,o){i&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=e,n.DomUtil.addClass(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:e,noUpdate:o}),setTimeout(n.bind(this._onZoomTransitionEnd,this),250)},_onZoomTransitionEnd:function(){this._animatingZoom&&(n.DomUtil.removeClass(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom),n.Util.requestAnimFrame(function(){this._moveEnd(!0)},this))}}),n.map=function(t,e){return new n.Map(t,e)},n.Layer=n.Evented.extend({options:{pane:"overlayPane",nonBubblingEvents:[],attribution:null},addTo:function(t){return t.addLayer(this),this},remove:function(){return this.removeFrom(this._map||this._mapToAdd)},removeFrom:function(t){return t&&t.removeLayer(this),this},getPane:function(t){return this._map.getPane(t?this.options[t]||t:this.options.pane)},addInteractiveTarget:function(t){return this._map._targets[n.stamp(t)]=this,this},removeInteractiveTarget:function(t){return delete this._map._targets[n.stamp(t)],this},getAttribution:function(){return this.options.attribution},_layerAdd:function(t){var e=t.target;if(e.hasLayer(this)){if(this._map=e,this._zoomAnimated=e._zoomAnimated,this.getEvents){var i=this.getEvents();e.on(i,this),this.once("remove",function(){e.off(i,this)},this)}this.onAdd(e),this.getAttribution&&e.attributionControl&&e.attributionControl.addAttribution(this.getAttribution()),this.fire("add"),e.fire("layeradd",{layer:this})}}}),n.Map.include({addLayer:function(t){var e=n.stamp(t);return this._layers[e]?this:(this._layers[e]=t,t._mapToAdd=this,t.beforeAdd&&t.beforeAdd(this),this.whenReady(t._layerAdd,t),this)},removeLayer:function(t){var e=n.stamp(t);return this._layers[e]?(this._loaded&&t.onRemove(this),t.getAttribution&&this.attributionControl&&this.attributionControl.removeAttribution(t.getAttribution()),delete this._layers[e],this._loaded&&(this.fire("layerremove",{layer:t}),t.fire("remove")),t._map=t._mapToAdd=null,this):this},hasLayer:function(t){return!!t&&n.stamp(t)in this._layers},eachLayer:function(t,e){for(var i in this._layers)t.call(e,this._layers[i]);return this},_addLayers:function(t){t=t?n.Util.isArray(t)?t:[t]:[];for(var e=0,i=t.length;ethis._layersMaxZoom&&this.setZoom(this._layersMaxZoom),this.options.minZoom===i&&this._layersMinZoom&&this.getZoom()100&&o<500||t.target._simulatedClick&&!t._simulated?void n.DomEvent.stop(t):(n.DomEvent._lastClick=i,void e(t))}},n.DomEvent.addListener=n.DomEvent.on,n.DomEvent.removeListener=n.DomEvent.off,n.PosAnimation=n.Evented.extend({run:function(t,e,i,o){this.stop(),this._el=t,this._inProgress=!0,this._duration=i||.25,this._easeOutPower=1/Math.max(o||.5,.2),this._startPos=n.DomUtil.getPosition(t),this._offset=e.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(!0),this._complete())},_animate:function(){this._animId=n.Util.requestAnimFrame(this._animate,this),this._step()},_step:function(t){var e=+new Date-this._startTime,i=1e3*this._duration;e1e-7;l++)e=r*Math.sin(h),e=Math.pow((1-e)/(1+e),r/2),u=Math.PI/2-2*Math.atan(a*e)-h,h+=u;return new n.LatLng(h*i,t.x*i/o)}},n.CRS.EPSG3395=n.extend({},n.CRS.Earth,{code:"EPSG:3395",projection:n.Projection.Mercator,transformation:function(){var t=.5/(Math.PI*n.Projection.Mercator.R);return new n.Transformation(t,.5,-t,.5)}()}),n.GridLayer=n.Layer.extend({options:{tileSize:256,opacity:1,updateWhenIdle:n.Browser.mobile,updateWhenZooming:!0,updateInterval:200,zIndex:1,bounds:null,minZoom:0,maxZoom:i,noWrap:!1,pane:"tilePane",className:"",keepBuffer:2},initialize:function(t){n.setOptions(this,t)},onAdd:function(){this._initContainer(),this._levels={},this._tiles={},this._resetView(),this._update()},beforeAdd:function(t){t._addZoomLimit(this)},onRemove:function(t){this._removeAllTiles(),n.DomUtil.remove(this._container),t._removeZoomLimit(this),this._container=null,this._tileZoom=null},bringToFront:function(){return this._map&&(n.DomUtil.toFront(this._container),this._setAutoZIndex(Math.max)),this},bringToBack:function(){return this._map&&(n.DomUtil.toBack(this._container),this._setAutoZIndex(Math.min)),this},getContainer:function(){return this._container},setOpacity:function(t){return this.options.opacity=t,this._updateOpacity(),this},setZIndex:function(t){return this.options.zIndex=t,this._updateZIndex(),this},isLoading:function(){return this._loading},redraw:function(){return this._map&&(this._removeAllTiles(),this._update()),this},getEvents:function(){var t={viewprereset:this._invalidateAll,viewreset:this._resetView,zoom:this._resetView,moveend:this._onMoveEnd};return this.options.updateWhenIdle||(this._onMove||(this._onMove=n.Util.throttle(this._onMoveEnd,this.options.updateInterval,this)),t.move=this._onMove),this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},createTile:function(){return e.createElement("div")},getTileSize:function(){var t=this.options.tileSize;return t instanceof n.Point?t:new n.Point(t,t)},_updateZIndex:function(){this._container&&this.options.zIndex!==i&&null!==this.options.zIndex&&(this._container.style.zIndex=this.options.zIndex)},_setAutoZIndex:function(t){for(var e,i=this.getPane().children,n=-t(-(1/0),1/0),o=0,s=i.length;othis.options.maxZoom||io&&this._retainParent(s,r,a,o))},_retainChildren:function(t,e,i,o){for(var s=2*t;s<2*t+2;s++)for(var r=2*e;r<2*e+2;r++){var a=new n.Point(s,r);a.z=i+1;var h=this._tileCoordsToKey(a),l=this._tiles[h];l&&l.active?l.retain=!0:(l&&l.loaded&&(l.retain=!0),i+1this.options.maxZoom||this.options.minZoom!==i&&s1)return void this._setView(t,s);for(var m=a.min.y;m<=a.max.y;m++)for(var p=a.min.x;p<=a.max.x;p++){var f=new n.Point(p,m);if(f.z=this._tileZoom,this._isValidTile(f)){var g=this._tiles[this._tileCoordsToKey(f)];g?g.current=!0:l.push(f)}}if(l.sort(function(t,e){return t.distanceTo(h)-e.distanceTo(h)}),0!==l.length){this._loading||(this._loading=!0,this.fire("loading"));var v=e.createDocumentFragment();for(p=0;pi.max.x)||!e.wrapLat&&(t.yi.max.y))return!1}if(!this.options.bounds)return!0;var o=this._tileCoordsToBounds(t);return n.latLngBounds(this.options.bounds).overlaps(o)},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToBounds:function(t){var e=this._map,i=this.getTileSize(),o=t.scaleBy(i),s=o.add(i),r=e.unproject(o,t.z),a=e.unproject(s,t.z),h=new n.LatLngBounds(r,a);return this.options.noWrap||e.wrapLatLngBounds(h),h},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var e=t.split(":"),i=new n.Point(+e[0],+e[1]);return i.z=+e[2],i},_removeTile:function(t){var e=this._tiles[t];e&&(n.DomUtil.remove(e.el),delete this._tiles[t],this.fire("tileunload",{tile:e.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){n.DomUtil.addClass(t,"leaflet-tile");var e=this.getTileSize();t.style.width=e.x+"px",t.style.height=e.y+"px",t.onselectstart=n.Util.falseFn,t.onmousemove=n.Util.falseFn,n.Browser.ielt9&&this.options.opacity<1&&n.DomUtil.setOpacity(t,this.options.opacity),n.Browser.android&&!n.Browser.android23&&(t.style.WebkitBackfaceVisibility="hidden")},_addTile:function(t,e){var i=this._getTilePos(t),o=this._tileCoordsToKey(t),s=this.createTile(this._wrapCoords(t),n.bind(this._tileReady,this,t));this._initTile(s),this.createTile.length<2&&n.Util.requestAnimFrame(n.bind(this._tileReady,this,t,null,s)),n.DomUtil.setPosition(s,i),this._tiles[o]={el:s,coords:t,current:!0},e.appendChild(s),this.fire("tileloadstart",{tile:s,coords:t})},_tileReady:function(t,e,i){if(this._map){e&&this.fire("tileerror",{error:e,tile:i,coords:t});var o=this._tileCoordsToKey(t);(i=this._tiles[o])&&(i.loaded=+new Date,this._map._fadeAnimated?(n.DomUtil.setOpacity(i.el,0),n.Util.cancelAnimFrame(this._fadeFrame),this._fadeFrame=n.Util.requestAnimFrame(this._updateOpacity,this)):(i.active=!0,this._pruneTiles()),e||(n.DomUtil.addClass(i.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:i.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),n.Browser.ielt9||!this._map._fadeAnimated?n.Util.requestAnimFrame(this._pruneTiles,this):setTimeout(n.bind(this._pruneTiles,this),250)))}},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var e=new n.Point(this._wrapX?n.Util.wrapNum(t.x,this._wrapX):t.x,this._wrapY?n.Util.wrapNum(t.y,this._wrapY):t.y);return e.z=t.z,e},_pxBoundsToTileRange:function(t){var e=this.getTileSize();return new n.Bounds(t.min.unscaleBy(e).floor(),t.max.unscaleBy(e).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}}),n.gridLayer=function(t){return new n.GridLayer(t)},n.TileLayer=n.GridLayer.extend({options:{minZoom:0,maxZoom:18,maxNativeZoom:null,minNativeZoom:null,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1},initialize:function(t,e){this._url=t,e=n.setOptions(this,e),e.detectRetina&&n.Browser.retina&&e.maxZoom>0&&(e.tileSize=Math.floor(e.tileSize/2),e.zoomReverse?(e.zoomOffset--,e.minZoom++):(e.zoomOffset++,e.maxZoom--),e.minZoom=Math.max(0,e.minZoom)),"string"==typeof e.subdomains&&(e.subdomains=e.subdomains.split("")),n.Browser.android||this.on("tileunload",this._onTileRemove)},setUrl:function(t,e){return this._url=t,e||this.redraw(),this},createTile:function(t,i){var o=e.createElement("img");return n.DomEvent.on(o,"load",n.bind(this._tileOnLoad,this,i,o)),n.DomEvent.on(o,"error",n.bind(this._tileOnError,this,i,o)),this.options.crossOrigin&&(o.crossOrigin=""),o.alt="",o.setAttribute("role","presentation"),o.src=this.getTileUrl(t),o},getTileUrl:function(t){var e={r:n.Browser.retina?"@2x":"",s:this._getSubdomain(t),x:t.x,y:t.y,z:this._getZoomForUrl()};if(this._map&&!this._map.options.crs.infinite){var i=this._globalTileRange.max.y-t.y;this.options.tms&&(e.y=i),e["-y"]=i}return n.Util.template(this._url,n.extend(e,this.options))},_tileOnLoad:function(t,e){n.Browser.ielt9?setTimeout(n.bind(t,this,null,e),0):t(null,e)},_tileOnError:function(t,e,i){var n=this.options.errorTileUrl;n&&e.src!==n&&(e.src=n),t(i,e)},getTileSize:function(){var t=this._map,e=n.GridLayer.prototype.getTileSize.call(this),i=this._tileZoom+this.options.zoomOffset,o=this.options.minNativeZoom,s=this.options.maxNativeZoom;return null!==o&&is?e.divideBy(t.getZoomScale(s,i)).round():e},_onTileRemove:function(t){t.tile.onload=null},_getZoomForUrl:function(){var t=this._tileZoom,e=this.options.maxZoom,i=this.options.zoomReverse,n=this.options.zoomOffset,o=this.options.minNativeZoom,s=this.options.maxNativeZoom;return i&&(t=e-t),t+=n,null!==o&&ts?s:t},_getSubdomain:function(t){var e=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[e]},_abortLoading:function(){var t,e;for(t in this._tiles)this._tiles[t].coords.z!==this._tileZoom&&(e=this._tiles[t].el,e.onload=n.Util.falseFn,e.onerror=n.Util.falseFn,e.complete||(e.src=n.Util.emptyImageUrl,n.DomUtil.remove(e)))}}),n.tileLayer=function(t,e){return new n.TileLayer(t,e)},n.TileLayer.WMS=n.TileLayer.extend({defaultWmsParams:{service:"WMS",request:"GetMap",layers:"",styles:"",format:"image/jpeg",transparent:!1,version:"1.1.1"},options:{crs:null,uppercase:!1},initialize:function(t,e){this._url=t;var i=n.extend({},this.defaultWmsParams);for(var o in e)o in this.options||(i[o]=e[o]);e=n.setOptions(this,e),i.width=i.height=e.tileSize*(e.detectRetina&&n.Browser.retina?2:1),this.wmsParams=i},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var e=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[e]=this._crs.code,n.TileLayer.prototype.onAdd.call(this,t)},getTileUrl:function(t){var e=this._tileCoordsToBounds(t),i=this._crs.project(e.getNorthWest()),o=this._crs.project(e.getSouthEast()),s=(this._wmsVersion>=1.3&&this._crs===n.CRS.EPSG4326?[o.y,i.x,i.y,o.x]:[i.x,o.y,o.x,i.y]).join(","),r=n.TileLayer.prototype.getTileUrl.call(this,t);return r+n.Util.getParamString(this.wmsParams,r,this.options.uppercase)+(this.options.uppercase?"&BBOX=":"&bbox=")+s},setParams:function(t,e){return n.extend(this.wmsParams,t),e||this.redraw(),this}}),n.tileLayer.wms=function(t,e){return new n.TileLayer.WMS(t,e)},n.ImageOverlay=n.Layer.extend({options:{opacity:1,alt:"",interactive:!1,crossOrigin:!1},initialize:function(t,e,i){this._url=t,this._bounds=n.latLngBounds(e),n.setOptions(this,i)},onAdd:function(){this._image||(this._initImage(),this.options.opacity<1&&this._updateOpacity()),this.options.interactive&&(n.DomUtil.addClass(this._image,"leaflet-interactive"),this.addInteractiveTarget(this._image)),this.getPane().appendChild(this._image),this._reset()},onRemove:function(){n.DomUtil.remove(this._image),this.options.interactive&&this.removeInteractiveTarget(this._image)},setOpacity:function(t){return this.options.opacity=t,this._image&&this._updateOpacity(),this},setStyle:function(t){return t.opacity&&this.setOpacity(t.opacity),this},bringToFront:function(){return this._map&&n.DomUtil.toFront(this._image),this},bringToBack:function(){return this._map&&n.DomUtil.toBack(this._image),this},setUrl:function(t){return this._url=t,this._image&&(this._image.src=t),this},setBounds:function(t){return this._bounds=t,this._map&&this._reset(),this},getEvents:function(){var t={zoom:this._reset,viewreset:this._reset};return this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},getBounds:function(){return this._bounds},getElement:function(){return this._image},_initImage:function(){var t=this._image=n.DomUtil.create("img","leaflet-image-layer "+(this._zoomAnimated?"leaflet-zoom-animated":""));t.onselectstart=n.Util.falseFn,t.onmousemove=n.Util.falseFn,t.onload=n.bind(this.fire,this,"load"),this.options.crossOrigin&&(t.crossOrigin=""),t.src=this._url,t.alt=this.options.alt},_animateZoom:function(t){ var e=this._map.getZoomScale(t.zoom),i=this._map._latLngBoundsToNewLayerBounds(this._bounds,t.zoom,t.center).min;n.DomUtil.setTransform(this._image,i,e)},_reset:function(){var t=this._image,e=new n.Bounds(this._map.latLngToLayerPoint(this._bounds.getNorthWest()),this._map.latLngToLayerPoint(this._bounds.getSouthEast())),i=e.getSize();n.DomUtil.setPosition(t,e.min),t.style.width=i.x+"px",t.style.height=i.y+"px"},_updateOpacity:function(){n.DomUtil.setOpacity(this._image,this.options.opacity)}}),n.imageOverlay=function(t,e,i){return new n.ImageOverlay(t,e,i)},n.Icon=n.Class.extend({initialize:function(t){n.setOptions(this,t)},createIcon:function(t){return this._createIcon("icon",t)},createShadow:function(t){return this._createIcon("shadow",t)},_createIcon:function(t,e){var i=this._getIconUrl(t);if(!i){if("icon"===t)throw new Error("iconUrl not set in Icon options (see the docs).");return null}var n=this._createImg(i,e&&"IMG"===e.tagName?e:null);return this._setIconStyles(n,t),n},_setIconStyles:function(t,e){var i=this.options,o=i[e+"Size"];"number"==typeof o&&(o=[o,o]);var s=n.point(o),r=n.point("shadow"===e&&i.shadowAnchor||i.iconAnchor||s&&s.divideBy(2,!0));t.className="leaflet-marker-"+e+" "+(i.className||""),r&&(t.style.marginLeft=-r.x+"px",t.style.marginTop=-r.y+"px"),s&&(t.style.width=s.x+"px",t.style.height=s.y+"px")},_createImg:function(t,i){return i=i||e.createElement("img"),i.src=t,i},_getIconUrl:function(t){return n.Browser.retina&&this.options[t+"RetinaUrl"]||this.options[t+"Url"]}}),n.icon=function(t){return new n.Icon(t)},n.Icon.Default=n.Icon.extend({options:{iconUrl:"marker-icon.png",iconRetinaUrl:"marker-icon-2x.png",shadowUrl:"marker-shadow.png",iconSize:[25,41],iconAnchor:[12,41],popupAnchor:[1,-34],tooltipAnchor:[16,-28],shadowSize:[41,41]},_getIconUrl:function(t){return n.Icon.Default.imagePath||(n.Icon.Default.imagePath=this._detectIconPath()),(this.options.imagePath||n.Icon.Default.imagePath)+n.Icon.prototype._getIconUrl.call(this,t)},_detectIconPath:function(){var t=n.DomUtil.create("div","leaflet-default-icon-path",e.body),i=n.DomUtil.getStyle(t,"background-image")||n.DomUtil.getStyle(t,"backgroundImage");return e.body.removeChild(t),0===i.indexOf("url")?i.replace(/^url\([\"\']?/,"").replace(/marker-icon\.png[\"\']?\)$/,""):""}}),n.Marker=n.Layer.extend({options:{icon:new n.Icon.Default,interactive:!0,draggable:!1,keyboard:!0,title:"",alt:"",zIndexOffset:0,opacity:1,riseOnHover:!1,riseOffset:250,pane:"markerPane",nonBubblingEvents:["click","dblclick","mouseover","mouseout","contextmenu"]},initialize:function(t,e){n.setOptions(this,e),this._latlng=n.latLng(t)},onAdd:function(t){this._zoomAnimated=this._zoomAnimated&&t.options.markerZoomAnimation,this._zoomAnimated&&t.on("zoomanim",this._animateZoom,this),this._initIcon(),this.update()},onRemove:function(t){this.dragging&&this.dragging.enabled()&&(this.options.draggable=!0,this.dragging.removeHooks()),this._zoomAnimated&&t.off("zoomanim",this._animateZoom,this),this._removeIcon(),this._removeShadow()},getEvents:function(){return{zoom:this.update,viewreset:this.update}},getLatLng:function(){return this._latlng},setLatLng:function(t){var e=this._latlng;return this._latlng=n.latLng(t),this.update(),this.fire("move",{oldLatLng:e,latlng:this._latlng})},setZIndexOffset:function(t){return this.options.zIndexOffset=t,this.update()},setIcon:function(t){return this.options.icon=t,this._map&&(this._initIcon(),this.update()),this._popup&&this.bindPopup(this._popup,this._popup.options),this},getElement:function(){return this._icon},update:function(){if(this._icon){var t=this._map.latLngToLayerPoint(this._latlng).round();this._setPos(t)}return this},_initIcon:function(){var t=this.options,e="leaflet-zoom-"+(this._zoomAnimated?"animated":"hide"),i=t.icon.createIcon(this._icon),o=!1;i!==this._icon&&(this._icon&&this._removeIcon(),o=!0,t.title&&(i.title=t.title),t.alt&&(i.alt=t.alt)),n.DomUtil.addClass(i,e),t.keyboard&&(i.tabIndex="0"),this._icon=i,t.riseOnHover&&this.on({mouseover:this._bringToFront,mouseout:this._resetZIndex});var s=t.icon.createShadow(this._shadow),r=!1;s!==this._shadow&&(this._removeShadow(),r=!0),s&&(n.DomUtil.addClass(s,e),s.alt=""),this._shadow=s,t.opacity<1&&this._updateOpacity(),o&&this.getPane().appendChild(this._icon),this._initInteraction(),s&&r&&this.getPane("shadowPane").appendChild(this._shadow)},_removeIcon:function(){this.options.riseOnHover&&this.off({mouseover:this._bringToFront,mouseout:this._resetZIndex}),n.DomUtil.remove(this._icon),this.removeInteractiveTarget(this._icon),this._icon=null},_removeShadow:function(){this._shadow&&n.DomUtil.remove(this._shadow),this._shadow=null},_setPos:function(t){n.DomUtil.setPosition(this._icon,t),this._shadow&&n.DomUtil.setPosition(this._shadow,t),this._zIndex=t.y+this.options.zIndexOffset,this._resetZIndex()},_updateZIndex:function(t){this._icon.style.zIndex=this._zIndex+t},_animateZoom:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center).round();this._setPos(e)},_initInteraction:function(){if(this.options.interactive&&(n.DomUtil.addClass(this._icon,"leaflet-interactive"),this.addInteractiveTarget(this._icon),n.Handler.MarkerDrag)){var t=this.options.draggable;this.dragging&&(t=this.dragging.enabled(),this.dragging.disable()),this.dragging=new n.Handler.MarkerDrag(this),t&&this.dragging.enable()}},setOpacity:function(t){return this.options.opacity=t,this._map&&this._updateOpacity(),this},_updateOpacity:function(){var t=this.options.opacity;n.DomUtil.setOpacity(this._icon,t),this._shadow&&n.DomUtil.setOpacity(this._shadow,t)},_bringToFront:function(){this._updateZIndex(this.options.riseOffset)},_resetZIndex:function(){this._updateZIndex(0)},_getPopupAnchor:function(){return this.options.icon.options.popupAnchor||[0,0]},_getTooltipAnchor:function(){return this.options.icon.options.tooltipAnchor||[0,0]}}),n.marker=function(t,e){return new n.Marker(t,e)},n.DivIcon=n.Icon.extend({options:{iconSize:[12,12],html:!1,bgPos:null,className:"leaflet-div-icon"},createIcon:function(t){var i=t&&"DIV"===t.tagName?t:e.createElement("div"),o=this.options;if(i.innerHTML=o.html!==!1?o.html:"",o.bgPos){var s=n.point(o.bgPos);i.style.backgroundPosition=-s.x+"px "+-s.y+"px"}return this._setIconStyles(i,"icon"),i},createShadow:function(){return null}}),n.divIcon=function(t){return new n.DivIcon(t)},n.DivOverlay=n.Layer.extend({options:{offset:[0,7],className:"",pane:"popupPane"},initialize:function(t,e){n.setOptions(this,t),this._source=e},onAdd:function(t){this._zoomAnimated=t._zoomAnimated,this._container||this._initLayout(),t._fadeAnimated&&n.DomUtil.setOpacity(this._container,0),clearTimeout(this._removeTimeout),this.getPane().appendChild(this._container),this.update(),t._fadeAnimated&&n.DomUtil.setOpacity(this._container,1),this.bringToFront()},onRemove:function(t){t._fadeAnimated?(n.DomUtil.setOpacity(this._container,0),this._removeTimeout=setTimeout(n.bind(n.DomUtil.remove,n.DomUtil,this._container),200)):n.DomUtil.remove(this._container)},getLatLng:function(){return this._latlng},setLatLng:function(t){return this._latlng=n.latLng(t),this._map&&(this._updatePosition(),this._adjustPan()),this},getContent:function(){return this._content},setContent:function(t){return this._content=t,this.update(),this},getElement:function(){return this._container},update:function(){this._map&&(this._container.style.visibility="hidden",this._updateContent(),this._updateLayout(),this._updatePosition(),this._container.style.visibility="",this._adjustPan())},getEvents:function(){var t={zoom:this._updatePosition,viewreset:this._updatePosition};return this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},isOpen:function(){return!!this._map&&this._map.hasLayer(this)},bringToFront:function(){return this._map&&n.DomUtil.toFront(this._container),this},bringToBack:function(){return this._map&&n.DomUtil.toBack(this._container),this},_updateContent:function(){if(this._content){var t=this._contentNode,e="function"==typeof this._content?this._content(this._source||this):this._content;if("string"==typeof e)t.innerHTML=e;else{for(;t.hasChildNodes();)t.removeChild(t.firstChild);t.appendChild(e)}this.fire("contentupdate")}},_updatePosition:function(){if(this._map){var t=this._map.latLngToLayerPoint(this._latlng),e=n.point(this.options.offset),i=this._getAnchor();this._zoomAnimated?n.DomUtil.setPosition(this._container,t.add(i)):e=e.add(t).add(i);var o=this._containerBottom=-e.y,s=this._containerLeft=-Math.round(this._containerWidth/2)+e.x;this._container.style.bottom=o+"px",this._container.style.left=s+"px"}},_getAnchor:function(){return[0,0]}}),n.Popup=n.DivOverlay.extend({options:{maxWidth:300,minWidth:50,maxHeight:null,autoPan:!0,autoPanPaddingTopLeft:null,autoPanPaddingBottomRight:null,autoPanPadding:[5,5],keepInView:!1,closeButton:!0,autoClose:!0,className:""},openOn:function(t){return t.openPopup(this),this},onAdd:function(t){n.DivOverlay.prototype.onAdd.call(this,t),t.fire("popupopen",{popup:this}),this._source&&(this._source.fire("popupopen",{popup:this},!0),this._source instanceof n.Path||this._source.on("preclick",n.DomEvent.stopPropagation))},onRemove:function(t){n.DivOverlay.prototype.onRemove.call(this,t),t.fire("popupclose",{popup:this}),this._source&&(this._source.fire("popupclose",{popup:this},!0),this._source instanceof n.Path||this._source.off("preclick",n.DomEvent.stopPropagation))},getEvents:function(){var t=n.DivOverlay.prototype.getEvents.call(this);return("closeOnClick"in this.options?this.options.closeOnClick:this._map.options.closePopupOnClick)&&(t.preclick=this._close),this.options.keepInView&&(t.moveend=this._adjustPan),t},_close:function(){this._map&&this._map.closePopup(this)},_initLayout:function(){var t="leaflet-popup",e=this._container=n.DomUtil.create("div",t+" "+(this.options.className||"")+" leaflet-zoom-animated");if(this.options.closeButton){var i=this._closeButton=n.DomUtil.create("a",t+"-close-button",e);i.href="#close",i.innerHTML="×",n.DomEvent.on(i,"click",this._onCloseButtonClick,this)}var o=this._wrapper=n.DomUtil.create("div",t+"-content-wrapper",e);this._contentNode=n.DomUtil.create("div",t+"-content",o),n.DomEvent.disableClickPropagation(o).disableScrollPropagation(this._contentNode).on(o,"contextmenu",n.DomEvent.stopPropagation),this._tipContainer=n.DomUtil.create("div",t+"-tip-container",e),this._tip=n.DomUtil.create("div",t+"-tip",this._tipContainer)},_updateLayout:function(){var t=this._contentNode,e=t.style;e.width="",e.whiteSpace="nowrap";var i=t.offsetWidth;i=Math.min(i,this.options.maxWidth),i=Math.max(i,this.options.minWidth),e.width=i+1+"px",e.whiteSpace="",e.height="";var o=t.offsetHeight,s=this.options.maxHeight,r="leaflet-popup-scrolled";s&&o>s?(e.height=s+"px",n.DomUtil.addClass(t,r)):n.DomUtil.removeClass(t,r),this._containerWidth=this._container.offsetWidth},_animateZoom:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center),i=this._getAnchor();n.DomUtil.setPosition(this._container,e.add(i))},_adjustPan:function(){if(!(!this.options.autoPan||this._map._panAnim&&this._map._panAnim._inProgress)){var t=this._map,e=parseInt(n.DomUtil.getStyle(this._container,"marginBottom"),10)||0,i=this._container.offsetHeight+e,o=this._containerWidth,s=new n.Point(this._containerLeft,-i-this._containerBottom);s._add(n.DomUtil.getPosition(this._container));var r=t.layerPointToContainerPoint(s),a=n.point(this.options.autoPanPadding),h=n.point(this.options.autoPanPaddingTopLeft||a),l=n.point(this.options.autoPanPaddingBottomRight||a),u=t.getSize(),c=0,d=0;r.x+o+l.x>u.x&&(c=r.x+o-u.x+l.x),r.x-c-h.x<0&&(c=r.x-h.x),r.y+i+l.y>u.y&&(d=r.y+i-u.y+l.y),r.y-d-h.y<0&&(d=r.y-h.y),(c||d)&&t.fire("autopanstart").panBy([c,d])}},_onCloseButtonClick:function(t){this._close(),n.DomEvent.stop(t)},_getAnchor:function(){return n.point(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}}),n.popup=function(t,e){return new n.Popup(t,e)},n.Map.mergeOptions({closePopupOnClick:!0}),n.Map.include({openPopup:function(t,e,i){return t instanceof n.Popup||(t=new n.Popup(i).setContent(t)),e&&t.setLatLng(e),this.hasLayer(t)?this:(this._popup&&this._popup.options.autoClose&&this.closePopup(),this._popup=t,this.addLayer(t))},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&this.removeLayer(t),this}}),n.Layer.include({bindPopup:function(t,e){return t instanceof n.Popup?(n.setOptions(t,e),this._popup=t,t._source=this):(this._popup&&!e||(this._popup=new n.Popup(e,this)),this._popup.setContent(t)),this._popupHandlersAdded||(this.on({click:this._openPopup,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t,e){if(t instanceof n.Layer||(e=t,t=this),t instanceof n.FeatureGroup)for(var i in this._layers){t=this._layers[i];break}return e||(e=t.getCenter?t.getCenter():t.getLatLng()),this._popup&&this._map&&(this._popup._source=t,this._popup.update(),this._map.openPopup(this._popup,e)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(t){return this._popup&&(this._popup._map?this.closePopup():this.openPopup(t)),this},isPopupOpen:function(){return!!this._popup&&this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var e=t.layer||t.target;if(this._popup&&this._map)return n.DomEvent.stop(t),e instanceof n.Path?void this.openPopup(t.layer||t.target,t.latlng):void(this._map.hasLayer(this._popup)&&this._popup._source===e?this.closePopup():this.openPopup(e,t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)}}),n.Tooltip=n.DivOverlay.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,interactive:!1,opacity:.9},onAdd:function(t){n.DivOverlay.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&this._source.fire("tooltipopen",{tooltip:this},!0)},onRemove:function(t){n.DivOverlay.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&this._source.fire("tooltipclose",{tooltip:this},!0)},getEvents:function(){var t=n.DivOverlay.prototype.getEvents.call(this);return n.Browser.touch&&!this.options.permanent&&(t.preclick=this._close),t},_close:function(){this._map&&this._map.closeTooltip(this)},_initLayout:function(){var t="leaflet-tooltip "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=n.DomUtil.create("div",t)},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var e=this._map,i=this._container,o=e.latLngToContainerPoint(e.getCenter()),s=e.layerPointToContainerPoint(t),r=this.options.direction,a=i.offsetWidth,h=i.offsetHeight,l=n.point(this.options.offset),u=this._getAnchor();"top"===r?t=t.add(n.point(-a/2+l.x,-h+l.y+u.y,!0)):"bottom"===r?t=t.subtract(n.point(a/2-l.x,-l.y,!0)):"center"===r?t=t.subtract(n.point(a/2+l.x,h/2-u.y+l.y,!0)):"right"===r||"auto"===r&&s.xh&&(s=r,h=a);h>i&&(e[s]=1,this._simplifyDPStep(t,e,i,n,s),this._simplifyDPStep(t,e,i,s,o))},_reducePoints:function(t,e){for(var i=[t[0]],n=1,o=0,s=t.length;ne&&(i.push(t[n]),o=n);return oe.max.x&&(i|=2),t.ye.max.y&&(i|=8),i},_sqDist:function(t,e){var i=e.x-t.x,n=e.y-t.y;return i*i+n*n},_sqClosestPointOnSegment:function(t,e,i,o){var s,r=e.x,a=e.y,h=i.x-r,l=i.y-a,u=h*h+l*l;return u>0&&(s=((t.x-r)*h+(t.y-a)*l)/u,s>1?(r=i.x,a=i.y):s>0&&(r+=h*s,a+=l*s)),h=t.x-r,l=t.y-a,o?h*h+l*l:new n.Point(r,a)}},n.Polyline=n.Path.extend({options:{smoothFactor:1,noClip:!1},initialize:function(t,e){n.setOptions(this,e),this._setLatLngs(t)},getLatLngs:function(){return this._latlngs},setLatLngs:function(t){return this._setLatLngs(t),this.redraw()},isEmpty:function(){return!this._latlngs.length},closestLayerPoint:function(t){for(var e,i,o=1/0,s=null,r=n.LineUtil._sqClosestPointOnSegment,a=0,h=this._parts.length;ae)return r=(n-e)/i,this._map.layerPointToLatLng([s.x-r*(s.x-o.x),s.y-r*(s.y-o.y)])},getBounds:function(){return this._bounds},addLatLng:function(t,e){return e=e||this._defaultShape(),t=n.latLng(t),e.push(t),this._bounds.extend(t),this.redraw()},_setLatLngs:function(t){this._bounds=new n.LatLngBounds,this._latlngs=this._convertLatLngs(t)},_defaultShape:function(){return n.Polyline._flat(this._latlngs)?this._latlngs:this._latlngs[0]},_convertLatLngs:function(t){for(var e=[],i=n.Polyline._flat(t),o=0,s=t.length;o=2&&e[0]instanceof n.LatLng&&e[0].equals(e[i-1])&&e.pop(),e},_setLatLngs:function(t){n.Polyline.prototype._setLatLngs.call(this,t),n.Polyline._flat(this._latlngs)&&(this._latlngs=[this._latlngs])},_defaultShape:function(){return n.Polyline._flat(this._latlngs[0])?this._latlngs[0]:this._latlngs[0][0]},_clipPoints:function(){var t=this._renderer._bounds,e=this.options.weight,i=new n.Point(e,e);if(t=new n.Bounds(t.min.subtract(i),t.max.add(i)),this._parts=[],this._pxBounds&&this._pxBounds.intersects(t)){if(this.options.noClip)return void(this._parts=this._rings);for(var o,s=0,r=this._rings.length;s';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(t){return!1}}(),n.SVG.include(n.Browser.vml?{_initContainer:function(){this._container=n.DomUtil.create("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(n.Renderer.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var e=t._container=n.SVG.create("shape");n.DomUtil.addClass(e,"leaflet-vml-shape "+(this.options.className||"")),e.coordsize="1 1",t._path=n.SVG.create("path"),e.appendChild(t._path),this._updateStyle(t),this._layers[n.stamp(t)]=t},_addPath:function(t){var e=t._container;this._container.appendChild(e),t.options.interactive&&t.addInteractiveTarget(e)},_removePath:function(t){var e=t._container;n.DomUtil.remove(e),t.removeInteractiveTarget(e),delete this._layers[n.stamp(t)]},_updateStyle:function(t){var e=t._stroke,i=t._fill,o=t.options,s=t._container;s.stroked=!!o.stroke,s.filled=!!o.fill,o.stroke?(e||(e=t._stroke=n.SVG.create("stroke")),s.appendChild(e),e.weight=o.weight+"px",e.color=o.color,e.opacity=o.opacity,o.dashArray?e.dashStyle=n.Util.isArray(o.dashArray)?o.dashArray.join(" "):o.dashArray.replace(/( *, *)/g," "):e.dashStyle="",e.endcap=o.lineCap.replace("butt","flat"),e.joinstyle=o.lineJoin):e&&(s.removeChild(e),t._stroke=null),o.fill?(i||(i=t._fill=n.SVG.create("fill")),s.appendChild(i),i.color=o.fillColor||o.color,i.opacity=o.fillOpacity):i&&(s.removeChild(i),t._fill=null)},_updateCircle:function(t){var e=t._point.round(),i=Math.round(t._radius),n=Math.round(t._radiusY||i);this._setPath(t,t._empty()?"M0 0":"AL "+e.x+","+e.y+" "+i+","+n+" 0,23592600")},_setPath:function(t,e){t._path.v=e},_bringToFront:function(t){n.DomUtil.toFront(t._container)},_bringToBack:function(t){n.DomUtil.toBack(t._container)}}:{}),n.Browser.vml&&(n.SVG.create=function(){try{return e.namespaces.add("lvml","urn:schemas-microsoft-com:vml"),function(t){return e.createElement("')}}catch(t){return function(t){return e.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}()),n.Canvas=n.Renderer.extend({getEvents:function(){var t=n.Renderer.prototype.getEvents.call(this);return t.viewprereset=this._onViewPreReset,t},_onViewPreReset:function(){this._postponeUpdatePaths=!0},onAdd:function(){n.Renderer.prototype.onAdd.call(this),this._draw()},_initContainer:function(){var t=this._container=e.createElement("canvas");n.DomEvent.on(t,"mousemove",n.Util.throttle(this._onMouseMove,32,this),this).on(t,"click dblclick mousedown mouseup contextmenu",this._onClick,this).on(t,"mouseout",this._handleMouseOut,this),this._ctx=t.getContext("2d")},_updatePaths:function(){if(!this._postponeUpdatePaths){var t;this._redrawBounds=null;for(var e in this._layers)t=this._layers[e],t._update();this._redraw()}},_update:function(){if(!this._map._animatingZoom||!this._bounds){this._drawnLayers={},n.Renderer.prototype._update.call(this);var t=this._bounds,e=this._container,i=t.getSize(),o=n.Browser.retina?2:1;n.DomUtil.setPosition(e,t.min),e.width=o*i.x,e.height=o*i.y,e.style.width=i.x+"px",e.style.height=i.y+"px",n.Browser.retina&&this._ctx.scale(2,2),this._ctx.translate(-t.min.x,-t.min.y),this.fire("update")}},_reset:function(){n.Renderer.prototype._reset.call(this),this._postponeUpdatePaths&&(this._postponeUpdatePaths=!1,this._updatePaths())},_initPath:function(t){this._updateDashArray(t),this._layers[n.stamp(t)]=t;var e=t._order={layer:t,prev:this._drawLast,next:null};this._drawLast&&(this._drawLast.next=e),this._drawLast=e,this._drawFirst=this._drawFirst||this._drawLast},_addPath:function(t){this._requestRedraw(t)},_removePath:function(t){var e=t._order,i=e.next,o=e.prev;i?i.prev=o:this._drawLast=o,o?o.next=i:this._drawFirst=i,delete t._order,delete this._layers[n.stamp(t)],this._requestRedraw(t)},_updatePath:function(t){this._extendRedrawBounds(t),t._project(),t._update(),this._requestRedraw(t)},_updateStyle:function(t){this._updateDashArray(t),this._requestRedraw(t)},_updateDashArray:function(t){if(t.options.dashArray){var e,i=t.options.dashArray.split(","),n=[];for(e=0;et.y!=o.y>t.y&&t.x<(o.x-i.x)*(t.y-i.y)/(o.y-i.y)+i.x&&(u=!u);return u||n.Polyline.prototype._containsPoint.call(this,t,!0)},n.CircleMarker.prototype._containsPoint=function(t){return t.distanceTo(this._point)<=this._radius+this._clickTolerance()},n.GeoJSON=n.FeatureGroup.extend({initialize:function(t,e){n.setOptions(this,e),this._layers={},t&&this.addData(t)},addData:function(t){var e,i,o,s=n.Util.isArray(t)?t:t.features;if(s){for(e=0,i=s.length;e1)return void(this._moved=!0);var o=i.touches&&1===i.touches.length?i.touches[0]:i,s=new n.Point(o.clientX,o.clientY),r=s.subtract(this._startPoint);(r.x||r.y)&&(Math.abs(r.x)+Math.abs(r.y)50&&(this._positions.shift(),this._times.shift())}this._map.fire("move",t).fire("drag",t)},_onZoomEnd:function(){var t=this._map.getSize().divideBy(2),e=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=e.subtract(t).x,this._worldWidth=this._map.getPixelWorldBounds().getSize().x},_viscousLimit:function(t,e){return t-(t-e)*this._viscosity},_onPreDragLimit:function(){if(this._viscosity&&this._offsetLimit){var t=this._draggable._newPos.subtract(this._draggable._startPos),e=this._offsetLimit;t.xe.max.x&&(t.x=this._viscousLimit(t.x,e.max.x)),t.y>e.max.y&&(t.y=this._viscousLimit(t.y,e.max.y)),this._draggable._newPos=this._draggable._startPos.add(t)}},_onPreDragWrap:function(){var t=this._worldWidth,e=Math.round(t/2),i=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-e+i)%t+e-i,s=(n+e+i)%t-e-i,r=Math.abs(o+i)0?s:-s))-e;this._delta=0,this._startTime=null,r&&("center"===t.options.scrollWheelZoom?t.setZoom(e+r):t.setZoomAround(this._lastMousePos,e+r))}}),n.Map.addInitHook("addHandler","scrollWheelZoom",n.Map.ScrollWheelZoom),n.extend(n.DomEvent,{_touchstart:n.Browser.msPointer?"MSPointerDown":n.Browser.pointer?"pointerdown":"touchstart",_touchend:n.Browser.msPointer?"MSPointerUp":n.Browser.pointer?"pointerup":"touchend",addDoubleTapListener:function(t,e,i){function o(t){var e;if(n.Browser.pointer){if(!n.Browser.edge||"mouse"===t.pointerType)return;e=n.DomEvent._pointersCount}else e=t.touches.length;if(!(e>1)){var i=Date.now(),o=i-(r||i);a=t.touches?t.touches[0]:t,h=o>0&&o<=l,r=i}}function s(t){if(h&&!a.cancelBubble){if(n.Browser.pointer){if(!n.Browser.edge||"mouse"===t.pointerType)return;var i,o,s={};for(o in a)i=a[o],s[o]=i&&i.bind?i.bind(a):i;a=s}a.type="dblclick",e(a),r=null}}var r,a,h=!1,l=250,u="_leaflet_",c=this._touchstart,d=this._touchend;return t[u+c+i]=o,t[u+d+i]=s,t[u+"dblclick"+i]=e,t.addEventListener(c,o,!1),t.addEventListener(d,s,!1),t.addEventListener("dblclick",e,!1),this},removeDoubleTapListener:function(t,e){var i="_leaflet_",o=t[i+this._touchstart+e],s=t[i+this._touchend+e],r=t[i+"dblclick"+e];return t.removeEventListener(this._touchstart,o,!1),t.removeEventListener(this._touchend,s,!1),n.Browser.edge||t.removeEventListener("dblclick",r,!1),this}}),n.extend(n.DomEvent,{POINTER_DOWN:n.Browser.msPointer?"MSPointerDown":"pointerdown",POINTER_MOVE:n.Browser.msPointer?"MSPointerMove":"pointermove",POINTER_UP:n.Browser.msPointer?"MSPointerUp":"pointerup",POINTER_CANCEL:n.Browser.msPointer?"MSPointerCancel":"pointercancel",TAG_WHITE_LIST:["INPUT","SELECT","OPTION"],_pointers:{},_pointersCount:0,addPointerListener:function(t,e,i,n){return"touchstart"===e?this._addPointerStart(t,i,n):"touchmove"===e?this._addPointerMove(t,i,n):"touchend"===e&&this._addPointerEnd(t,i,n),this},removePointerListener:function(t,e,i){var n=t["_leaflet_"+e+i];return"touchstart"===e?t.removeEventListener(this.POINTER_DOWN,n,!1):"touchmove"===e?t.removeEventListener(this.POINTER_MOVE,n,!1):"touchend"===e&&(t.removeEventListener(this.POINTER_UP,n,!1),t.removeEventListener(this.POINTER_CANCEL,n,!1)),this},_addPointerStart:function(t,i,o){var s=n.bind(function(t){if("mouse"!==t.pointerType&&t.MSPOINTER_TYPE_MOUSE&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE){if(!(this.TAG_WHITE_LIST.indexOf(t.target.tagName)<0))return;n.DomEvent.preventDefault(t)}this._handlePointer(t,i)},this);if(t["_leaflet_touchstart"+o]=s,t.addEventListener(this.POINTER_DOWN,s,!1),!this._pointerDocListener){var r=n.bind(this._globalPointerUp,this);e.documentElement.addEventListener(this.POINTER_DOWN,n.bind(this._globalPointerDown,this),!0),e.documentElement.addEventListener(this.POINTER_MOVE,n.bind(this._globalPointerMove,this),!0),e.documentElement.addEventListener(this.POINTER_UP,r,!0),e.documentElement.addEventListener(this.POINTER_CANCEL,r,!0),this._pointerDocListener=!0}},_globalPointerDown:function(t){this._pointers[t.pointerId]=t,this._pointersCount++},_globalPointerMove:function(t){this._pointers[t.pointerId]&&(this._pointers[t.pointerId]=t)},_globalPointerUp:function(t){delete this._pointers[t.pointerId],this._pointersCount--},_handlePointer:function(t,e){t.touches=[];for(var i in this._pointers)t.touches.push(this._pointers[i]);t.changedTouches=[t],e(t)},_addPointerMove:function(t,e,i){var o=n.bind(function(t){(t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&"mouse"!==t.pointerType||0!==t.buttons)&&this._handlePointer(t,e)},this);t["_leaflet_touchmove"+i]=o,t.addEventListener(this.POINTER_MOVE,o,!1)},_addPointerEnd:function(t,e,i){var o=n.bind(function(t){this._handlePointer(t,e)},this);t["_leaflet_touchend"+i]=o,t.addEventListener(this.POINTER_UP,o,!1),t.addEventListener(this.POINTER_CANCEL,o,!1)}}),n.Map.mergeOptions({touchZoom:n.Browser.touch&&!n.Browser.android23,bounceAtZoomLimits:!0}),n.Map.TouchZoom=n.Handler.extend({addHooks:function(){n.DomUtil.addClass(this._map._container,"leaflet-touch-zoom"),n.DomEvent.on(this._map._container,"touchstart",this._onTouchStart,this)},removeHooks:function(){n.DomUtil.removeClass(this._map._container,"leaflet-touch-zoom"),n.DomEvent.off(this._map._container,"touchstart",this._onTouchStart,this)},_onTouchStart:function(t){var i=this._map;if(t.touches&&2===t.touches.length&&!i._animatingZoom&&!this._zooming){var o=i.mouseEventToContainerPoint(t.touches[0]),s=i.mouseEventToContainerPoint(t.touches[1]);this._centerPoint=i.getSize()._divideBy(2),this._startLatLng=i.containerPointToLatLng(this._centerPoint),"center"!==i.options.touchZoom&&(this._pinchStartLatLng=i.containerPointToLatLng(o.add(s)._divideBy(2))),this._startDist=o.distanceTo(s),this._startZoom=i.getZoom(),this._moved=!1,this._zooming=!0,i._stop(),n.DomEvent.on(e,"touchmove",this._onTouchMove,this).on(e,"touchend",this._onTouchEnd,this),n.DomEvent.preventDefault(t)}},_onTouchMove:function(t){if(t.touches&&2===t.touches.length&&this._zooming){var e=this._map,i=e.mouseEventToContainerPoint(t.touches[0]),o=e.mouseEventToContainerPoint(t.touches[1]),s=i.distanceTo(o)/this._startDist;if(this._zoom=e.getScaleZoom(s,this._startZoom),!e.options.bounceAtZoomLimits&&(this._zoome.getMaxZoom()&&s>1)&&(this._zoom=e._limitZoom(this._zoom)),"center"===e.options.touchZoom){if(this._center=this._startLatLng,1===s)return}else{var r=i._add(o)._divideBy(2)._subtract(this._centerPoint);if(1===s&&0===r.x&&0===r.y)return;this._center=e.unproject(e.project(this._pinchStartLatLng,this._zoom).subtract(r),this._zoom)}this._moved||(e._moveStart(!0),this._moved=!0),n.Util.cancelAnimFrame(this._animRequest);var a=n.bind(e._move,e,this._center,this._zoom,{pinch:!0,round:!1});this._animRequest=n.Util.requestAnimFrame(a,this,!0),n.DomEvent.preventDefault(t)}},_onTouchEnd:function(){return this._moved&&this._zooming?(this._zooming=!1,n.Util.cancelAnimFrame(this._animRequest),n.DomEvent.off(e,"touchmove",this._onTouchMove).off(e,"touchend",this._onTouchEnd),void(this._map.options.zoomAnimation?this._map._animateZoom(this._center,this._map._limitZoom(this._zoom),!0,this._map.options.zoomSnap):this._map._resetView(this._center,this._map._limitZoom(this._zoom)))):void(this._zooming=!1)}}),n.Map.addInitHook("addHandler","touchZoom",n.Map.TouchZoom),n.Map.mergeOptions({tap:!0,tapTolerance:15}),n.Map.Tap=n.Handler.extend({addHooks:function(){n.DomEvent.on(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){n.DomEvent.off(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(t.touches){if(n.DomEvent.preventDefault(t),this._fireClick=!0,t.touches.length>1)return this._fireClick=!1,void clearTimeout(this._holdTimeout);var i=t.touches[0],o=i.target;this._startPos=this._newPos=new n.Point(i.clientX,i.clientY),o.tagName&&"a"===o.tagName.toLowerCase()&&n.DomUtil.addClass(o,"leaflet-active"),this._holdTimeout=setTimeout(n.bind(function(){this._isTapValid()&&(this._fireClick=!1,this._onUp(),this._simulateEvent("contextmenu",i))},this),1e3),this._simulateEvent("mousedown",i),n.DomEvent.on(e,{touchmove:this._onMove,touchend:this._onUp},this)}},_onUp:function(t){if(clearTimeout(this._holdTimeout),n.DomEvent.off(e,{touchmove:this._onMove,touchend:this._onUp},this), -this._fireClick&&t&&t.changedTouches){var i=t.changedTouches[0],o=i.target;o&&o.tagName&&"a"===o.tagName.toLowerCase()&&n.DomUtil.removeClass(o,"leaflet-active"),this._simulateEvent("mouseup",i),this._isTapValid()&&this._simulateEvent("click",i)}},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_onMove:function(t){var e=t.touches[0];this._newPos=new n.Point(e.clientX,e.clientY),this._simulateEvent("mousemove",e)},_simulateEvent:function(i,n){var o=e.createEvent("MouseEvents");o._simulated=!0,n.target._simulatedClick=!0,o.initMouseEvent(i,!0,!0,t,1,n.screenX,n.screenY,n.clientX,n.clientY,!1,!1,!1,!1,0,null),n.target.dispatchEvent(o)}}),n.Browser.touch&&!n.Browser.pointer&&n.Map.addInitHook("addHandler","tap",n.Map.Tap),n.Map.mergeOptions({boxZoom:!0}),n.Map.BoxZoom=n.Handler.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane},addHooks:function(){n.DomEvent.on(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){n.DomEvent.off(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_resetState:function(){this._moved=!1},_onMouseDown:function(t){return!(!t.shiftKey||1!==t.which&&1!==t.button)&&(this._resetState(),n.DomUtil.disableTextSelection(),n.DomUtil.disableImageDrag(),this._startPoint=this._map.mouseEventToContainerPoint(t),void n.DomEvent.on(e,{contextmenu:n.DomEvent.stop,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this))},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=n.DomUtil.create("div","leaflet-zoom-box",this._container),n.DomUtil.addClass(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var e=new n.Bounds(this._point,this._startPoint),i=e.getSize();n.DomUtil.setPosition(this._box,e.min),this._box.style.width=i.x+"px",this._box.style.height=i.y+"px"},_finish:function(){this._moved&&(n.DomUtil.remove(this._box),n.DomUtil.removeClass(this._container,"leaflet-crosshair")),n.DomUtil.enableTextSelection(),n.DomUtil.enableImageDrag(),n.DomEvent.off(e,{contextmenu:n.DomEvent.stop,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){if((1===t.which||1===t.button)&&(this._finish(),this._moved)){setTimeout(n.bind(this._resetState,this),0);var e=new n.LatLngBounds(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point));this._map.fitBounds(e).fire("boxzoomend",{boxZoomBounds:e})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}}),n.Map.addInitHook("addHandler","boxZoom",n.Map.BoxZoom),n.Map.mergeOptions({keyboard:!0,keyboardPanDelta:80}),n.Map.Keyboard=n.Handler.extend({keyCodes:{left:[37],right:[39],down:[40],up:[38],zoomIn:[187,107,61,171],zoomOut:[189,109,54,173]},initialize:function(t){this._map=t,this._setPanDelta(t.options.keyboardPanDelta),this._setZoomDelta(t.options.zoomDelta)},addHooks:function(){var t=this._map._container;t.tabIndex<=0&&(t.tabIndex="0"),n.DomEvent.on(t,{focus:this._onFocus,blur:this._onBlur,mousedown:this._onMouseDown},this),this._map.on({focus:this._addHooks,blur:this._removeHooks},this)},removeHooks:function(){this._removeHooks(),n.DomEvent.off(this._map._container,{focus:this._onFocus,blur:this._onBlur,mousedown:this._onMouseDown},this),this._map.off({focus:this._addHooks,blur:this._removeHooks},this)},_onMouseDown:function(){if(!this._focused){var i=e.body,n=e.documentElement,o=i.scrollTop||n.scrollTop,s=i.scrollLeft||n.scrollLeft;this._map._container.focus(),t.scrollTo(s,o)}},_onFocus:function(){this._focused=!0,this._map.fire("focus")},_onBlur:function(){this._focused=!1,this._map.fire("blur")},_setPanDelta:function(t){var e,i,n=this._panKeys={},o=this.keyCodes;for(e=0,i=o.left.length;e0&&t.screenY>0&&this._map.getContainer().focus()}}),n.control=function(t){return new n.Control(t)},n.Map.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.remove(),this},_initControlPos:function(){function t(t,s){var r=i+t+" "+i+s;e[t+s]=n.DomUtil.create("div",r,o)}var e=this._controlCorners={},i="leaflet-",o=this._controlContainer=n.DomUtil.create("div",i+"control-container",this._container);t("top","left"),t("top","right"),t("bottom","left"),t("bottom","right")},_clearControlPos:function(){n.DomUtil.remove(this._controlContainer)}}),n.Control.Zoom=n.Control.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"-",zoomOutTitle:"Zoom out"},onAdd:function(t){var e="leaflet-control-zoom",i=n.DomUtil.create("div",e+" leaflet-bar"),o=this.options;return this._zoomInButton=this._createButton(o.zoomInText,o.zoomInTitle,e+"-in",i,this._zoomIn),this._zoomOutButton=this._createButton(o.zoomOutText,o.zoomOutTitle,e+"-out",i,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),i},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoomthis._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,e,i,o,s){var r=n.DomUtil.create("a",i,o);return r.innerHTML=t,r.href="#",r.title=e,r.setAttribute("role","button"),r.setAttribute("aria-label",e),n.DomEvent.on(r,"mousedown dblclick",n.DomEvent.stopPropagation).on(r,"click",n.DomEvent.stop).on(r,"click",s,this).on(r,"click",this._refocusOnMap,this),r},_updateDisabled:function(){var t=this._map,e="leaflet-disabled";n.DomUtil.removeClass(this._zoomInButton,e),n.DomUtil.removeClass(this._zoomOutButton,e),(this._disabled||t._zoom===t.getMinZoom())&&n.DomUtil.addClass(this._zoomOutButton,e),(this._disabled||t._zoom===t.getMaxZoom())&&n.DomUtil.addClass(this._zoomInButton,e)}}),n.Map.mergeOptions({zoomControl:!0}),n.Map.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new n.Control.Zoom,this.addControl(this.zoomControl))}),n.control.zoom=function(t){return new n.Control.Zoom(t)},n.Control.Attribution=n.Control.extend({options:{position:"bottomright",prefix:'Leaflet'},initialize:function(t){n.setOptions(this,t),this._attributions={}},onAdd:function(t){t.attributionControl=this,this._container=n.DomUtil.create("div","leaflet-control-attribution"),n.DomEvent&&n.DomEvent.disableClickPropagation(this._container);for(var e in t._layers)t._layers[e].getAttribution&&this.addAttribution(t._layers[e].getAttribution());return this._update(),this._container},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t?(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update(),this):this},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):this},_update:function(){if(this._map){var t=[];for(var e in this._attributions)this._attributions[e]&&t.push(e);var i=[];this.options.prefix&&i.push(this.options.prefix),t.length&&i.push(t.join(", ")),this._container.innerHTML=i.join(" | ")}}}),n.Map.mergeOptions({attributionControl:!0}),n.Map.addInitHook(function(){this.options.attributionControl&&(new n.Control.Attribution).addTo(this)}),n.control.attribution=function(t){return new n.Control.Attribution(t)},n.Control.Scale=n.Control.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var e="leaflet-control-scale",i=n.DomUtil.create("div",e),o=this.options;return this._addScales(o,e+"-line",i),t.on(o.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,e,i){t.metric&&(this._mScale=n.DomUtil.create("div",e,i)),t.imperial&&(this._iScale=n.DomUtil.create("div",e,i))},_update:function(){var t=this._map,e=t.getSize().y/2,i=t.distance(t.containerPointToLatLng([0,e]),t.containerPointToLatLng([this.options.maxWidth,e]));this._updateScales(i)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var e=this._getRoundNum(t),i=e<1e3?e+" m":e/1e3+" km";this._updateScale(this._mScale,i,e/t)},_updateImperial:function(t){var e,i,n,o=3.2808399*t;o>5280?(e=o/5280,i=this._getRoundNum(e),this._updateScale(this._iScale,i+" mi",i/e)):(n=this._getRoundNum(o),this._updateScale(this._iScale,n+" ft",n/o))},_updateScale:function(t,e,i){t.style.width=Math.round(this.options.maxWidth*i)+"px",t.innerHTML=e},_getRoundNum:function(t){var e=Math.pow(10,(Math.floor(t)+"").length-1),i=t/e;return i=i>=10?10:i>=5?5:i>=3?3:i>=2?2:1,e*i}}),n.control.scale=function(t){return new n.Control.Scale(t)},n.Control.Layers=n.Control.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0,hideSingleBase:!1,sortLayers:!1,sortFunction:function(t,e,i,n){return i1,this._baseLayersList.style.display=t?"":"none"),this._separator.style.display=e&&t?"":"none",this},_onLayerChange:function(t){this._handlingClick||this._update();var e=this._getLayer(n.stamp(t.target)),i=e.overlay?"add"===t.type?"overlayadd":"overlayremove":"add"===t.type?"baselayerchange":null;i&&this._map.fire(i,e)},_createRadioElement:function(t,i){var n='",o=e.createElement("div");return o.innerHTML=n,o.firstChild},_addItem:function(t){var i,o=e.createElement("label"),s=this._map.hasLayer(t.layer);t.overlay?(i=e.createElement("input"),i.type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=s):i=this._createRadioElement("leaflet-base-layers",s),i.layerId=n.stamp(t.layer),n.DomEvent.on(i,"click",this._onInputClick,this);var r=e.createElement("span");r.innerHTML=" "+t.name;var a=e.createElement("div");return o.appendChild(a),a.appendChild(i),a.appendChild(r),(t.overlay?this._overlaysList:this._baseLayersList).appendChild(o),this._checkDisabledLayers(),o},_onInputClick:function(){var t,e,i,n=this._form.getElementsByTagName("input"),o=[],s=[];this._handlingClick=!0;for(var r=n.length-1;r>=0;r--)t=n[r],e=this._getLayer(t.layerId).layer,i=this._map.hasLayer(e),t.checked&&!i?o.push(e):!t.checked&&i&&s.push(e);for(r=0;r=0;s--)t=n[s],e=this._getLayer(t.layerId).layer,t.disabled=e.options.minZoom!==i&&oe.options.maxZoom},_expand:function(){return this.expand()},_collapse:function(){return this.collapse()}}),n.control.layers=function(t,e,i){return new n.Control.Layers(t,e,i)}}(window,document)