From e317e0798b3814f9adf4ac514f0b04c20b0da9ff Mon Sep 17 00:00:00 2001 From: Nolan Gilley Date: Tue, 17 Nov 2015 19:14:29 -0500 Subject: [PATCH 01/49] initial commit for ecobee thermostat component. --- homeassistant/components/sensor/ecobee.py | 101 +++++++ homeassistant/components/thermostat/ecobee.py | 263 ++++++++++++++++++ requirements_all.txt | 3 + 3 files changed, 367 insertions(+) create mode 100644 homeassistant/components/sensor/ecobee.py create mode 100644 homeassistant/components/thermostat/ecobee.py diff --git a/homeassistant/components/sensor/ecobee.py b/homeassistant/components/sensor/ecobee.py new file mode 100644 index 00000000000..ba4db55b842 --- /dev/null +++ b/homeassistant/components/sensor/ecobee.py @@ -0,0 +1,101 @@ +""" +homeassistant.components.sensor.ecobee +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This sensor component requires that the Ecobee Thermostat +component be setup first. This component shows remote +ecobee sensor data. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.ecobee/ +""" +from homeassistant.helpers.entity import Entity +import json +import logging +import os + +SENSOR_TYPES = { + 'temperature': ['Temperature', '°F'], + 'humidity': ['Humidity', '%'], + 'occupancy': ['Occupancy', ''] +} + +_LOGGER = logging.getLogger(__name__) + +ECOBEE_CONFIG_FILE = 'ecobee.conf' + + +def config_from_file(filename, config=None): + ''' Small configuration file management function ''' + if config: + # We're writing configuration + try: + with open(filename, 'w') as fdesc: + fdesc.write(json.dumps(config)) + except IOError as error: + print(error) + return False + return True + else: + # We're reading config + if os.path.isfile(filename): + try: + with open(filename, 'r') as fdesc: + return json.loads(fdesc.read()) + except IOError as error: + return False + else: + return {} + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """ Sets up the sensors. """ + config = config_from_file(hass.config.path(ECOBEE_CONFIG_FILE)) + dev = list() + for name, data in config['sensors'].items(): + if 'temp' in data: + dev.append(EcobeeSensor(name, 'temperature', hass)) + if 'humidity' in data: + dev.append(EcobeeSensor(name, 'humidity', hass)) + if 'occupancy' in data: + dev.append(EcobeeSensor(name, 'occupancy', hass)) + + add_devices(dev) + + +class EcobeeSensor(Entity): + """ An ecobee sensor. """ + + def __init__(self, sensor_name, sensor_type, hass): + self._name = sensor_name + ' ' + SENSOR_TYPES[sensor_type][0] + self.sensor_name = sensor_name + self.hass = hass + self.type = sensor_type + self._state = None + self._unit_of_measurement = SENSOR_TYPES[sensor_type][1] + self.update() + + @property + def name(self): + return self._name.rstrip() + + @property + def state(self): + """ Returns the state of the device. """ + return self._state + + @property + def unit_of_measurement(self): + return self._unit_of_measurement + + def update(self): + config = config_from_file(self.hass.config.path(ECOBEE_CONFIG_FILE)) + try: + data = config['sensors'][self.sensor_name] + if self.type == 'temperature': + self._state = data['temp'] + elif self.type == 'humidity': + self._state = data['humidity'] + elif self.type == 'occupancy': + self._state = data['occupancy'] + except KeyError: + print("Error updating ecobee sensors.") diff --git a/homeassistant/components/thermostat/ecobee.py b/homeassistant/components/thermostat/ecobee.py new file mode 100644 index 00000000000..6792c34a421 --- /dev/null +++ b/homeassistant/components/thermostat/ecobee.py @@ -0,0 +1,263 @@ +#!/usr/local/bin/python3 +""" +homeassistant.components.thermostat.ecobee +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Ecobee Thermostat Component + +This component adds support for Ecobee3 Wireless Thermostats. +You will need to setup developer access to your thermostat, +and create and API key on the ecobee website. + +The first time you run this component you will see a configuration +component card in Home Assistant. This card will contain a PIN code +that you will need to use to authorize access to your thermostat. You +can do this at https://www.ecobee.com/consumerportal/index.html +Click My Apps, Add application, Enter Pin and click Authorize. + +After authorizing the application click the button in the configuration +card. Now your thermostat should shown in home-assistant. You will need +to restart home assistant to get rid of the configuration card. Once the +thermostat has been added you can add the ecobee sensor component +to your configuration.yaml. + +thermostat: + platform: ecobee + api_key: asdfasdfasdfasdfasdfaasdfasdfasdfasdf +""" +from homeassistant.loader import get_component +from homeassistant.components.thermostat import (ThermostatDevice, STATE_COOL, + STATE_IDLE, STATE_HEAT) +from homeassistant.const import ( + CONF_API_KEY, TEMP_FAHRENHEIT, STATE_ON, STATE_OFF) +import logging +import os + +REQUIREMENTS = [ + 'https://github.com/nkgilley/home-assistant-ecobee-api/archive/' + 'c61ee6d456bb5f4ab0c9598804aa9231c3d06f8e.zip#python-ecobee==0.1.1'] + +_LOGGER = logging.getLogger(__name__) + +ECOBEE_CONFIG_FILE = 'ecobee.conf' +_CONFIGURING = {} + + +def setup_platform(hass, config, add_devices_callback, discovery_info=None): + """ Setup Platform """ + # Only act if we are not already configuring this host + if 'ecobee' in _CONFIGURING: + return + + setup_ecobee(hass, config, add_devices_callback) + + +def setup_ecobee(hass, config, add_devices_callback): + """ Setup ecobee thermostat """ + from pyecobee import Ecobee, config_from_file + # Create ecobee.conf if it doesn't exist + if not os.path.isfile(hass.config.path(ECOBEE_CONFIG_FILE)): + jsonconfig = {"API_KEY": config[CONF_API_KEY]} + config_from_file(hass.config.path(ECOBEE_CONFIG_FILE), jsonconfig) + + ecobee = Ecobee(hass.config.path(ECOBEE_CONFIG_FILE)) + + # If ecobee has a PIN then it needs to be configured. + if ecobee.pin is not None: + # ecobee.request_pin() + request_configuration(ecobee, hass, add_devices_callback) + return + + if 'ecobee' in _CONFIGURING: + _CONFIGURING.pop('ecobee') + configurator = get_component('configurator') + configurator.request_done('ecobee') + + devices = [] + for index in range(0, len(ecobee.thermostats)): + devices.append(Thermostat(ecobee, index)) + + add_devices_callback(devices) + + +def request_configuration(ecobee, hass, add_devices_callback): + """ Request configuration steps from the user. """ + configurator = get_component('configurator') + if 'ecobee' in _CONFIGURING: + configurator.notify_errors( + _CONFIGURING['ecobee'], "Failed to register, please try again.") + + return + + # pylint: disable=unused-argument + def ecobee_configuration_callback(data): + """ Actions to do when our configuration callback is called. """ + ecobee.request_tokens() + ecobee.update() + setup_ecobee(hass, None, add_devices_callback) + + _CONFIGURING['ecobee'] = configurator.request_config( + hass, "Ecobee", ecobee_configuration_callback, + description=( + 'Please authorize this app at https://www.ecobee.com/consumer' + 'portal/index.html with pin code: ' + ecobee.pin), + description_image='https://goo.gl/6tBkbH', + submit_caption="I have authorized the app." + ) + + +class Thermostat(ThermostatDevice): + """docstring for Thermostat""" + + def __init__(self, ecobee, thermostat_index): + self.ecobee = ecobee + self.thermostat_index = thermostat_index + self.thermostat_data = self.ecobee.get_thermostat( + self.thermostat_index) + self._name = self.thermostat_data['name'] + if 'away' in self.thermostat_data['program']['currentClimateRef']: + self._away = True + else: + self._away = False + + def update(self): + self.thermostat_data = self.ecobee.get_thermostat( + self.thermostat_index) + _LOGGER.info("ecobee data updated successfully.") + + @property + def name(self): + """ Returns the name of the Ecobee Thermostat. """ + return self.thermostat_data['name'] + + @property + def unit_of_measurement(self): + """ Unit of measurement this thermostat expresses itself in. """ + return TEMP_FAHRENHEIT + + @property + def current_temperature(self): + """ Returns the current temperature. """ + return self.thermostat_data['runtime']['actualTemperature'] / 10 + + @property + def target_temperature(self): + """ Returns the temperature we try to reach. """ + return (self.target_temperature_low + self.target_temperature_high) / 2 + + @property + def target_temperature_low(self): + """ Returns the lower bound temperature we try to reach. """ + return int(self.thermostat_data['runtime']['desiredHeat'] / 10) + + @property + def target_temperature_high(self): + """ Returns the upper bound temperature we try to reach. """ + return int(self.thermostat_data['runtime']['desiredCool'] / 10) + + @property + def humidity(self): + """ Returns the current humidity. """ + return self.thermostat_data['runtime']['actualHumidity'] + + @property + def desired_fan_mode(self): + """ Returns the desired fan mode of operation. """ + return self.thermostat_data['runtime']['desiredFanMode'] + + @property + def fan(self): + """ Returns the current fan state. """ + if 'fan' in self.thermostat_data['equipmentStatus']: + return STATE_ON + else: + return STATE_OFF + + @property + def operation(self): + """ Returns current operation ie. heat, cool, idle """ + status = self.thermostat_data['equipmentStatus'] + if status == '': + return STATE_IDLE + elif 'Cool' in status: + return STATE_COOL + elif 'auxHeat' in status: + return STATE_HEAT + elif 'heatPump' in status: + return STATE_HEAT + else: + return status + + @property + def mode(self): + """ Returns current mode ie. home, away, sleep """ + mode = self.thermostat_data['program']['currentClimateRef'] + if 'away' in mode: + self._away = True + else: + self._away = False + return mode + + @property + def hvac_mode(self): + """ Return current hvac mode ie. auto, auxHeatOnly, cool, heat, off """ + return self.thermostat_data['settings']['hvacMode'] + + @property + def device_state_attributes(self): + """ Returns device specific state attributes. """ + # Move these to Thermostat Device and make them global + return { + "humidity": self.humidity, + "fan": self.fan, + "mode": self.mode, + "hvac_mode": self.hvac_mode + } + + @property + def is_away_mode_on(self): + """ Returns if away mode is on. """ + return self._away + + def turn_away_mode_on(self): + """ Turns away on. """ + self._away = True + self.ecobee.set_climate_hold("away") + + def turn_away_mode_off(self): + """ Turns away off. """ + self._away = False + self.ecobee.resume_program() + + def set_temperature(self, temperature): + """ Set new target temperature """ + temperature = int(temperature) + low_temp = temperature - 1 + high_temp = temperature + 1 + self.ecobee.set_hold_temp(low_temp, high_temp) + + def set_hvac_mode(self, mode): + """ Set HVAC mode (auto, auxHeatOnly, cool, heat, off) """ + self.ecobee.set_hvac_mode(mode) + + # Home and Sleep mode aren't used in UI yet: + + # def turn_home_mode_on(self): + # """ Turns home mode on. """ + # self._away = False + # self.ecobee.set_climate_hold("home") + + # def turn_home_mode_off(self): + # """ Turns home mode off. """ + # self._away = False + # self.ecobee.resume_program() + + # def turn_sleep_mode_on(self): + # """ Turns sleep mode on. """ + # self._away = False + # self.ecobee.set_climate_hold("sleep") + + # def turn_sleep_mode_off(self): + # """ Turns sleep mode off. """ + # self._away = False + # self.ecobee.resume_program() diff --git a/requirements_all.txt b/requirements_all.txt index ce6cbfabc96..db7ca1ada2d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -159,3 +159,6 @@ pushetta==1.0.15 # Orvibo S10 orvibo==1.0.0 + +# Ecobee (*.ecobee) +https://github.com/nkgilley/home-assistant-ecobee-api/archive/e0388659a0f2fc7266485affbd398350cc0b5c58.zip#python-ecobee==0.1.1 From 22fcbc67cfa61ca8f372a4ce978c687c19d5346d Mon Sep 17 00:00:00 2001 From: Nolan Gilley Date: Tue, 17 Nov 2015 19:20:56 -0500 Subject: [PATCH 02/49] fix req --- homeassistant/components/thermostat/ecobee.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/thermostat/ecobee.py b/homeassistant/components/thermostat/ecobee.py index 6792c34a421..cbdd52ba7e9 100644 --- a/homeassistant/components/thermostat/ecobee.py +++ b/homeassistant/components/thermostat/ecobee.py @@ -35,7 +35,7 @@ import os REQUIREMENTS = [ 'https://github.com/nkgilley/home-assistant-ecobee-api/archive/' - 'c61ee6d456bb5f4ab0c9598804aa9231c3d06f8e.zip#python-ecobee==0.1.1'] + 'e0388659a0f2fc7266485affbd398350cc0b5c58.zip#python-ecobee==0.1.1'] _LOGGER = logging.getLogger(__name__) From c6d1a4bdaf572407cfbfe79dd5a259c6290a3780 Mon Sep 17 00:00:00 2001 From: "nkgilley@gmail.com" Date: Wed, 18 Nov 2015 10:13:46 -0500 Subject: [PATCH 03/49] Fix configurator, rename repo, cleanup code. --- homeassistant/components/sensor/ecobee.py | 26 ++++----- homeassistant/components/thermostat/ecobee.py | 53 ++++++++----------- requirements_all.txt | 2 +- 3 files changed, 32 insertions(+), 49 deletions(-) diff --git a/homeassistant/components/sensor/ecobee.py b/homeassistant/components/sensor/ecobee.py index ba4db55b842..a8d9e41acb1 100644 --- a/homeassistant/components/sensor/ecobee.py +++ b/homeassistant/components/sensor/ecobee.py @@ -13,6 +13,8 @@ import json import logging import os +DEPENDENCIES = ['thermostat'] + SENSOR_TYPES = { 'temperature': ['Temperature', '°F'], 'humidity': ['Humidity', '%'], @@ -24,27 +26,17 @@ _LOGGER = logging.getLogger(__name__) ECOBEE_CONFIG_FILE = 'ecobee.conf' -def config_from_file(filename, config=None): - ''' Small configuration file management function ''' - if config: - # We're writing configuration +def config_from_file(filename): + ''' Small configuration file reading function ''' + if os.path.isfile(filename): try: - with open(filename, 'w') as fdesc: - fdesc.write(json.dumps(config)) + with open(filename, 'r') as fdesc: + return json.loads(fdesc.read()) except IOError as error: - print(error) + _LOGGER.error("ecobee sensor couldn't read config file: " + error) return False - return True else: - # We're reading config - if os.path.isfile(filename): - try: - with open(filename, 'r') as fdesc: - return json.loads(fdesc.read()) - except IOError as error: - return False - else: - return {} + return {} def setup_platform(hass, config, add_devices, discovery_info=None): diff --git a/homeassistant/components/thermostat/ecobee.py b/homeassistant/components/thermostat/ecobee.py index cbdd52ba7e9..0c00fb0de46 100644 --- a/homeassistant/components/thermostat/ecobee.py +++ b/homeassistant/components/thermostat/ecobee.py @@ -16,8 +16,7 @@ can do this at https://www.ecobee.com/consumerportal/index.html Click My Apps, Add application, Enter Pin and click Authorize. After authorizing the application click the button in the configuration -card. Now your thermostat should shown in home-assistant. You will need -to restart home assistant to get rid of the configuration card. Once the +card. Now your thermostat should shown in home-assistant. Once the thermostat has been added you can add the ecobee sensor component to your configuration.yaml. @@ -34,8 +33,8 @@ import logging import os REQUIREMENTS = [ - 'https://github.com/nkgilley/home-assistant-ecobee-api/archive/' - 'e0388659a0f2fc7266485affbd398350cc0b5c58.zip#python-ecobee==0.1.1'] + 'https://github.com/nkgilley/python-ecobee-api/archive/' + '824a7dfabe7ef6975b2864f33e6ae0b48fb6ea3f.zip#python-ecobee==0.0.1'] _LOGGER = logging.getLogger(__name__) @@ -64,20 +63,15 @@ def setup_ecobee(hass, config, add_devices_callback): # If ecobee has a PIN then it needs to be configured. if ecobee.pin is not None: - # ecobee.request_pin() request_configuration(ecobee, hass, add_devices_callback) return if 'ecobee' in _CONFIGURING: - _CONFIGURING.pop('ecobee') configurator = get_component('configurator') - configurator.request_done('ecobee') + configurator.request_done(_CONFIGURING.pop('ecobee')) - devices = [] - for index in range(0, len(ecobee.thermostats)): - devices.append(Thermostat(ecobee, index)) - - add_devices_callback(devices) + add_devices_callback(Thermostat(ecobee, index) + for index in range(len(ecobee.thermostats))) def request_configuration(ecobee, hass, add_devices_callback): @@ -101,34 +95,31 @@ def request_configuration(ecobee, hass, add_devices_callback): description=( 'Please authorize this app at https://www.ecobee.com/consumer' 'portal/index.html with pin code: ' + ecobee.pin), - description_image='https://goo.gl/6tBkbH', + description_image="/static/images/config_ecobee_thermostat.png", submit_caption="I have authorized the app." ) class Thermostat(ThermostatDevice): - """docstring for Thermostat""" + """ Thermostat class for Ecobee """ def __init__(self, ecobee, thermostat_index): self.ecobee = ecobee self.thermostat_index = thermostat_index - self.thermostat_data = self.ecobee.get_thermostat( + self.thermostat = self.ecobee.get_thermostat( self.thermostat_index) - self._name = self.thermostat_data['name'] - if 'away' in self.thermostat_data['program']['currentClimateRef']: - self._away = True - else: - self._away = False + self._name = self.thermostat['name'] + self._away = 'away' in self.thermostat['program']['currentClimateRef'] def update(self): - self.thermostat_data = self.ecobee.get_thermostat( + self.thermostat = self.ecobee.get_thermostat( self.thermostat_index) _LOGGER.info("ecobee data updated successfully.") @property def name(self): """ Returns the name of the Ecobee Thermostat. """ - return self.thermostat_data['name'] + return self.thermostat['name'] @property def unit_of_measurement(self): @@ -138,7 +129,7 @@ class Thermostat(ThermostatDevice): @property def current_temperature(self): """ Returns the current temperature. """ - return self.thermostat_data['runtime']['actualTemperature'] / 10 + return self.thermostat['runtime']['actualTemperature'] / 10 @property def target_temperature(self): @@ -148,27 +139,27 @@ class Thermostat(ThermostatDevice): @property def target_temperature_low(self): """ Returns the lower bound temperature we try to reach. """ - return int(self.thermostat_data['runtime']['desiredHeat'] / 10) + return int(self.thermostat['runtime']['desiredHeat'] / 10) @property def target_temperature_high(self): """ Returns the upper bound temperature we try to reach. """ - return int(self.thermostat_data['runtime']['desiredCool'] / 10) + return int(self.thermostat['runtime']['desiredCool'] / 10) @property def humidity(self): """ Returns the current humidity. """ - return self.thermostat_data['runtime']['actualHumidity'] + return self.thermostat['runtime']['actualHumidity'] @property def desired_fan_mode(self): """ Returns the desired fan mode of operation. """ - return self.thermostat_data['runtime']['desiredFanMode'] + return self.thermostat['runtime']['desiredFanMode'] @property def fan(self): """ Returns the current fan state. """ - if 'fan' in self.thermostat_data['equipmentStatus']: + if 'fan' in self.thermostat['equipmentStatus']: return STATE_ON else: return STATE_OFF @@ -176,7 +167,7 @@ class Thermostat(ThermostatDevice): @property def operation(self): """ Returns current operation ie. heat, cool, idle """ - status = self.thermostat_data['equipmentStatus'] + status = self.thermostat['equipmentStatus'] if status == '': return STATE_IDLE elif 'Cool' in status: @@ -191,7 +182,7 @@ class Thermostat(ThermostatDevice): @property def mode(self): """ Returns current mode ie. home, away, sleep """ - mode = self.thermostat_data['program']['currentClimateRef'] + mode = self.thermostat['program']['currentClimateRef'] if 'away' in mode: self._away = True else: @@ -201,7 +192,7 @@ class Thermostat(ThermostatDevice): @property def hvac_mode(self): """ Return current hvac mode ie. auto, auxHeatOnly, cool, heat, off """ - return self.thermostat_data['settings']['hvacMode'] + return self.thermostat['settings']['hvacMode'] @property def device_state_attributes(self): diff --git a/requirements_all.txt b/requirements_all.txt index db7ca1ada2d..4e34b6029ac 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -161,4 +161,4 @@ pushetta==1.0.15 orvibo==1.0.0 # Ecobee (*.ecobee) -https://github.com/nkgilley/home-assistant-ecobee-api/archive/e0388659a0f2fc7266485affbd398350cc0b5c58.zip#python-ecobee==0.1.1 +https://github.com/nkgilley/python-ecobee-api/archive/824a7dfabe7ef6975b2864f33e6ae0b48fb6ea3f.zip#python-ecobee==0.0.1 From 18d0f4461f0fade2e919f16ae18c826932b9e749 Mon Sep 17 00:00:00 2001 From: "nkgilley@gmail.com" Date: Wed, 18 Nov 2015 10:16:16 -0500 Subject: [PATCH 04/49] add config png to images dir. --- .../images/config_ecobee_thermostat.png | Bin 0 -> 31083 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 homeassistant/components/frontend/www_static/images/config_ecobee_thermostat.png diff --git a/homeassistant/components/frontend/www_static/images/config_ecobee_thermostat.png b/homeassistant/components/frontend/www_static/images/config_ecobee_thermostat.png new file mode 100644 index 0000000000000000000000000000000000000000..e62a4165c9becb8c974faa54523cd1bad9b4ef32 GIT binary patch literal 31083 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 xU6?KYcZ>A7BL5HbU&-%mneX{5e$8K|?t}7cwC# Date: Wed, 18 Nov 2015 10:43:52 -0500 Subject: [PATCH 05/49] point to updated python-ecobee library --- homeassistant/components/thermostat/ecobee.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/thermostat/ecobee.py b/homeassistant/components/thermostat/ecobee.py index 0c00fb0de46..472c0e60b60 100644 --- a/homeassistant/components/thermostat/ecobee.py +++ b/homeassistant/components/thermostat/ecobee.py @@ -34,7 +34,7 @@ import os REQUIREMENTS = [ 'https://github.com/nkgilley/python-ecobee-api/archive/' - '824a7dfabe7ef6975b2864f33e6ae0b48fb6ea3f.zip#python-ecobee==0.0.1'] + '730009b9593899d42e98c81a0544f91e65b2bc15.zip#python-ecobee==0.0.1'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 4e34b6029ac..3a930c145dd 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -161,4 +161,4 @@ pushetta==1.0.15 orvibo==1.0.0 # Ecobee (*.ecobee) -https://github.com/nkgilley/python-ecobee-api/archive/824a7dfabe7ef6975b2864f33e6ae0b48fb6ea3f.zip#python-ecobee==0.0.1 +https://github.com/nkgilley/python-ecobee-api/archive/730009b9593899d42e98c81a0544f91e65b2bc15.zip#python-ecobee==0.0.1 From d05af626802231bf1398298a5e1cb9d0753a1820 Mon Sep 17 00:00:00 2001 From: "nkgilley@gmail.com" Date: Wed, 18 Nov 2015 14:57:27 -0500 Subject: [PATCH 06/49] use Throttle like the BitCoin component. --- .coveragerc | 1 + homeassistant/components/thermostat/ecobee.py | 82 +++++++++++-------- 2 files changed, 50 insertions(+), 33 deletions(-) diff --git a/.coveragerc b/.coveragerc index f19e37d00a1..9fafe443dcf 100644 --- a/.coveragerc +++ b/.coveragerc @@ -16,6 +16,7 @@ omit = homeassistant/components/*/tellstick.py homeassistant/components/*/vera.py + homeassistant/components/*/ecobee.py homeassistant/components/verisure.py homeassistant/components/*/verisure.py diff --git a/homeassistant/components/thermostat/ecobee.py b/homeassistant/components/thermostat/ecobee.py index 472c0e60b60..7258a3b65a1 100644 --- a/homeassistant/components/thermostat/ecobee.py +++ b/homeassistant/components/thermostat/ecobee.py @@ -29,18 +29,23 @@ from homeassistant.components.thermostat import (ThermostatDevice, STATE_COOL, STATE_IDLE, STATE_HEAT) from homeassistant.const import ( CONF_API_KEY, TEMP_FAHRENHEIT, STATE_ON, STATE_OFF) +from homeassistant.util import Throttle +from datetime import timedelta import logging import os REQUIREMENTS = [ 'https://github.com/nkgilley/python-ecobee-api/archive/' - '730009b9593899d42e98c81a0544f91e65b2bc15.zip#python-ecobee==0.0.1'] + '790c20d820dbb727af2dbfb3ef0f79231e19a503.zip#python-ecobee==0.0.1'] _LOGGER = logging.getLogger(__name__) ECOBEE_CONFIG_FILE = 'ecobee.conf' _CONFIGURING = {} +# Return cached results if last scan was less then this time ago +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=180) + def setup_platform(hass, config, add_devices_callback, discovery_info=None): """ Setup Platform """ @@ -48,33 +53,32 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): if 'ecobee' in _CONFIGURING: return - setup_ecobee(hass, config, add_devices_callback) + from pyecobee import config_from_file - -def setup_ecobee(hass, config, add_devices_callback): - """ Setup ecobee thermostat """ - from pyecobee import Ecobee, config_from_file # Create ecobee.conf if it doesn't exist if not os.path.isfile(hass.config.path(ECOBEE_CONFIG_FILE)): jsonconfig = {"API_KEY": config[CONF_API_KEY]} config_from_file(hass.config.path(ECOBEE_CONFIG_FILE), jsonconfig) + data = EcobeeData(hass.config.path(ECOBEE_CONFIG_FILE)) + setup_ecobee(hass, data, config, add_devices_callback) - ecobee = Ecobee(hass.config.path(ECOBEE_CONFIG_FILE)) +def setup_ecobee(hass, data, config, add_devices_callback): + """ Setup ecobee thermostat """ # If ecobee has a PIN then it needs to be configured. - if ecobee.pin is not None: - request_configuration(ecobee, hass, add_devices_callback) + if data.ecobee.pin is not None: + request_configuration(data, hass, add_devices_callback) return if 'ecobee' in _CONFIGURING: configurator = get_component('configurator') configurator.request_done(_CONFIGURING.pop('ecobee')) - add_devices_callback(Thermostat(ecobee, index) - for index in range(len(ecobee.thermostats))) + add_devices_callback(Thermostat(data, index) + for index in range(len(data.ecobee.thermostats))) -def request_configuration(ecobee, hass, add_devices_callback): +def request_configuration(data, hass, add_devices_callback): """ Request configuration steps from the user. """ configurator = get_component('configurator') if 'ecobee' in _CONFIGURING: @@ -84,35 +88,50 @@ def request_configuration(ecobee, hass, add_devices_callback): return # pylint: disable=unused-argument - def ecobee_configuration_callback(data): + def ecobee_configuration_callback(callback_data): """ Actions to do when our configuration callback is called. """ - ecobee.request_tokens() - ecobee.update() - setup_ecobee(hass, None, add_devices_callback) + data.ecobee.request_tokens() + data.ecobee.update() + setup_ecobee(hass, data, None, add_devices_callback) _CONFIGURING['ecobee'] = configurator.request_config( hass, "Ecobee", ecobee_configuration_callback, description=( 'Please authorize this app at https://www.ecobee.com/consumer' - 'portal/index.html with pin code: ' + ecobee.pin), + 'portal/index.html with pin code: ' + data.ecobee.pin), description_image="/static/images/config_ecobee_thermostat.png", submit_caption="I have authorized the app." ) +# pylint: disable=too-few-public-methods +class EcobeeData(object): + """ Gets the latest data and update the states. """ + + def __init__(self, config_filename): + from pyecobee import Ecobee + self.ecobee = Ecobee(config_filename) + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + def update(self): + """ Get the latest data from pyecobee. """ + self.ecobee.update() + + class Thermostat(ThermostatDevice): """ Thermostat class for Ecobee """ - def __init__(self, ecobee, thermostat_index): - self.ecobee = ecobee + def __init__(self, data, thermostat_index): + self.data = data self.thermostat_index = thermostat_index - self.thermostat = self.ecobee.get_thermostat( + self.thermostat = self.data.ecobee.get_thermostat( self.thermostat_index) self._name = self.thermostat['name'] self._away = 'away' in self.thermostat['program']['currentClimateRef'] def update(self): - self.thermostat = self.ecobee.get_thermostat( + self.data.update() + self.thermostat = self.data.ecobee.get_thermostat( self.thermostat_index) _LOGGER.info("ecobee data updated successfully.") @@ -183,10 +202,7 @@ class Thermostat(ThermostatDevice): def mode(self): """ Returns current mode ie. home, away, sleep """ mode = self.thermostat['program']['currentClimateRef'] - if 'away' in mode: - self._away = True - else: - self._away = False + self._away = 'away' in mode return mode @property @@ -213,42 +229,42 @@ class Thermostat(ThermostatDevice): def turn_away_mode_on(self): """ Turns away on. """ self._away = True - self.ecobee.set_climate_hold("away") + self.data.ecobee.set_climate_hold("away") def turn_away_mode_off(self): """ Turns away off. """ self._away = False - self.ecobee.resume_program() + self.data.ecobee.resume_program() def set_temperature(self, temperature): """ Set new target temperature """ temperature = int(temperature) low_temp = temperature - 1 high_temp = temperature + 1 - self.ecobee.set_hold_temp(low_temp, high_temp) + self.data.ecobee.set_hold_temp(low_temp, high_temp) def set_hvac_mode(self, mode): """ Set HVAC mode (auto, auxHeatOnly, cool, heat, off) """ - self.ecobee.set_hvac_mode(mode) + self.data.ecobee.set_hvac_mode(mode) # Home and Sleep mode aren't used in UI yet: # def turn_home_mode_on(self): # """ Turns home mode on. """ # self._away = False - # self.ecobee.set_climate_hold("home") + # self.data.ecobee.set_climate_hold("home") # def turn_home_mode_off(self): # """ Turns home mode off. """ # self._away = False - # self.ecobee.resume_program() + # self.data.ecobee.resume_program() # def turn_sleep_mode_on(self): # """ Turns sleep mode on. """ # self._away = False - # self.ecobee.set_climate_hold("sleep") + # self.data.ecobee.set_climate_hold("sleep") # def turn_sleep_mode_off(self): # """ Turns sleep mode off. """ # self._away = False - # self.ecobee.resume_program() + # self.data.ecobee.resume_program() From 44abc31057c174968939beb940d48e55b326895c Mon Sep 17 00:00:00 2001 From: "nkgilley@gmail.com" Date: Fri, 20 Nov 2015 17:47:25 -0500 Subject: [PATCH 07/49] work in progress: configurator is now in it's own component. configurator seems to work but the thermostat is now broken. --- .coveragerc | 2 + homeassistant/components/ecobee.py | 127 ++++++++++++++++++ homeassistant/components/thermostat/ecobee.py | 72 ++-------- requirements_all.txt | 2 +- 4 files changed, 142 insertions(+), 61 deletions(-) create mode 100644 homeassistant/components/ecobee.py diff --git a/.coveragerc b/.coveragerc index 9fafe443dcf..b8016fa7624 100644 --- a/.coveragerc +++ b/.coveragerc @@ -16,6 +16,8 @@ omit = homeassistant/components/*/tellstick.py homeassistant/components/*/vera.py + + homeassistant/components/ecobee.py homeassistant/components/*/ecobee.py homeassistant/components/verisure.py diff --git a/homeassistant/components/ecobee.py b/homeassistant/components/ecobee.py new file mode 100644 index 00000000000..99db73b6a90 --- /dev/null +++ b/homeassistant/components/ecobee.py @@ -0,0 +1,127 @@ +""" +homeassistant.components.zwave +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Connects Home Assistant to the Ecobee API and maintains tokens. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/ecobee/ + +[ecobee] +api_key: asdflaksf +""" + +from homeassistant.loader import get_component +from homeassistant import bootstrap +from homeassistant.const import ( + EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, + EVENT_PLATFORM_DISCOVERED, ATTR_SERVICE, ATTR_DISCOVERED, CONF_API_KEY) +from datetime import timedelta +import logging +import os + +DOMAIN = "ecobee" +DISCOVER_THERMOSTAT = "ecobee.thermostat" +DEPENDENCIES = [] +NETWORK = None + +REQUIREMENTS = [ + 'https://github.com/nkgilley/python-ecobee-api/archive/' + 'd35596b67c75451fa47001c493a15eebee195e93.zip#python-ecobee==0.0.1'] + +_LOGGER = logging.getLogger(__name__) + +ECOBEE_CONFIG_FILE = 'ecobee.conf' +_CONFIGURING = {} + +# Return cached results if last scan was less then this time ago +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=180) + + +def request_configuration(network, hass): + """ Request configuration steps from the user. """ + configurator = get_component('configurator') + if 'ecobee' in _CONFIGURING: + configurator.notify_errors( + _CONFIGURING['ecobee'], "Failed to register, please try again.") + + return + + # pylint: disable=unused-argument + def ecobee_configuration_callback(callback_data): + """ Actions to do when our configuration callback is called. """ + network.request_tokens() + network.update() + setup_ecobee(hass, network) + + _CONFIGURING['ecobee'] = configurator.request_config( + hass, "Ecobee", ecobee_configuration_callback, + description=( + 'Please authorize this app at https://www.ecobee.com/consumer' + 'portal/index.html with pin code: ' + NETWORK.pin), + description_image="/static/images/config_ecobee_thermostat.png", + submit_caption="I have authorized the app." + ) + + +def setup_ecobee(hass, network): + """ Setup ecobee thermostat """ + # If ecobee has a PIN then it needs to be configured. + if network.pin is not None: + request_configuration(network, hass) + return + + if 'ecobee' in _CONFIGURING: + configurator = get_component('configurator') + configurator.request_done(_CONFIGURING.pop('ecobee')) + + +def setup(hass, config): + """ + Setup Ecobee. + Will automatically load thermostat and sensor components to support + devices discovered on the network. + """ + # pylint: disable=global-statement, import-error + global NETWORK + + if 'ecobee' in _CONFIGURING: + return + + from pyecobee import Ecobee, config_from_file + + # Create ecobee.conf if it doesn't exist + if not os.path.isfile(hass.config.path(ECOBEE_CONFIG_FILE)): + if config[DOMAIN].get(CONF_API_KEY) is None: + _LOGGER.error("No ecobee api_key found in config.") + return + jsonconfig = {"API_KEY": config[DOMAIN].get(CONF_API_KEY)} + config_from_file(hass.config.path(ECOBEE_CONFIG_FILE), jsonconfig) + + NETWORK = Ecobee(hass.config.path(ECOBEE_CONFIG_FILE)) + + setup_ecobee(hass, NETWORK) + + # Ensure component is loaded + bootstrap.setup_component(hass, 'thermostat', config) + + # Fire discovery event + hass.bus.fire(EVENT_PLATFORM_DISCOVERED, { + ATTR_SERVICE: DISCOVER_THERMOSTAT, + ATTR_DISCOVERED: { + 'network': NETWORK, + } + }) + + def stop_ecobee(event): + """ Stop Ecobee. """ + + pass + + def start_ecobee(event): + """ Called when Home Assistant starts up. """ + + hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_ecobee) + + hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_ecobee) + + return True diff --git a/homeassistant/components/thermostat/ecobee.py b/homeassistant/components/thermostat/ecobee.py index 7258a3b65a1..5b377be4907 100644 --- a/homeassistant/components/thermostat/ecobee.py +++ b/homeassistant/components/thermostat/ecobee.py @@ -1,4 +1,3 @@ -#!/usr/local/bin/python3 """ homeassistant.components.thermostat.ecobee ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -24,19 +23,14 @@ thermostat: platform: ecobee api_key: asdfasdfasdfasdfasdfaasdfasdfasdfasdf """ -from homeassistant.loader import get_component from homeassistant.components.thermostat import (ThermostatDevice, STATE_COOL, STATE_IDLE, STATE_HEAT) -from homeassistant.const import ( - CONF_API_KEY, TEMP_FAHRENHEIT, STATE_ON, STATE_OFF) +from homeassistant.const import (TEMP_FAHRENHEIT, STATE_ON, STATE_OFF) from homeassistant.util import Throttle from datetime import timedelta import logging -import os -REQUIREMENTS = [ - 'https://github.com/nkgilley/python-ecobee-api/archive/' - '790c20d820dbb727af2dbfb3ef0f79231e19a503.zip#python-ecobee==0.0.1'] +DEPENDENCIES = ['ecobee'] _LOGGER = logging.getLogger(__name__) @@ -47,70 +41,28 @@ _CONFIGURING = {} MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=180) -def setup_platform(hass, config, add_devices_callback, discovery_info=None): +def setup_platform(hass, config, add_devices, discovery_info=None): """ Setup Platform """ - # Only act if we are not already configuring this host - if 'ecobee' in _CONFIGURING: + _LOGGER.error("ecobee !!!!") + if discovery_info is None: return - - from pyecobee import config_from_file - - # Create ecobee.conf if it doesn't exist - if not os.path.isfile(hass.config.path(ECOBEE_CONFIG_FILE)): - jsonconfig = {"API_KEY": config[CONF_API_KEY]} - config_from_file(hass.config.path(ECOBEE_CONFIG_FILE), jsonconfig) - data = EcobeeData(hass.config.path(ECOBEE_CONFIG_FILE)) - setup_ecobee(hass, data, config, add_devices_callback) + data = EcobeeData(discovery_info[0]) + setup_ecobee(hass, data, add_devices) -def setup_ecobee(hass, data, config, add_devices_callback): +def setup_ecobee(hass, data, add_devices): """ Setup ecobee thermostat """ - # If ecobee has a PIN then it needs to be configured. - if data.ecobee.pin is not None: - request_configuration(data, hass, add_devices_callback) - return - if 'ecobee' in _CONFIGURING: - configurator = get_component('configurator') - configurator.request_done(_CONFIGURING.pop('ecobee')) - - add_devices_callback(Thermostat(data, index) - for index in range(len(data.ecobee.thermostats))) - - -def request_configuration(data, hass, add_devices_callback): - """ Request configuration steps from the user. """ - configurator = get_component('configurator') - if 'ecobee' in _CONFIGURING: - configurator.notify_errors( - _CONFIGURING['ecobee'], "Failed to register, please try again.") - - return - - # pylint: disable=unused-argument - def ecobee_configuration_callback(callback_data): - """ Actions to do when our configuration callback is called. """ - data.ecobee.request_tokens() - data.ecobee.update() - setup_ecobee(hass, data, None, add_devices_callback) - - _CONFIGURING['ecobee'] = configurator.request_config( - hass, "Ecobee", ecobee_configuration_callback, - description=( - 'Please authorize this app at https://www.ecobee.com/consumer' - 'portal/index.html with pin code: ' + data.ecobee.pin), - description_image="/static/images/config_ecobee_thermostat.png", - submit_caption="I have authorized the app." - ) + add_devices(Thermostat(data, index) + for index in range(len(data.ecobee.thermostats))) # pylint: disable=too-few-public-methods class EcobeeData(object): """ Gets the latest data and update the states. """ - def __init__(self, config_filename): - from pyecobee import Ecobee - self.ecobee = Ecobee(config_filename) + def __init__(self, network): + self.ecobee = network @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): diff --git a/requirements_all.txt b/requirements_all.txt index 3a930c145dd..b74226f4991 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -161,4 +161,4 @@ pushetta==1.0.15 orvibo==1.0.0 # Ecobee (*.ecobee) -https://github.com/nkgilley/python-ecobee-api/archive/730009b9593899d42e98c81a0544f91e65b2bc15.zip#python-ecobee==0.0.1 +https://github.com/nkgilley/python-ecobee-api/archive/d35596b67c75451fa47001c493a15eebee195e93.zip#python-ecobee==0.0.1 From 8dc0de1d05cda0f218b882ccf4013bbfa405824d Mon Sep 17 00:00:00 2001 From: "nkgilley@gmail.com" Date: Sat, 21 Nov 2015 12:24:06 -0500 Subject: [PATCH 08/49] move EcobeeData class and Throttle to the main ecobee component, this way the sensor and thermostat will use the same throttled updating object. --- homeassistant/components/ecobee.py | 25 ++++++++++++++---- homeassistant/components/thermostat/ecobee.py | 26 +------------------ 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/homeassistant/components/ecobee.py b/homeassistant/components/ecobee.py index 99db73b6a90..ef982a15e63 100644 --- a/homeassistant/components/ecobee.py +++ b/homeassistant/components/ecobee.py @@ -1,5 +1,5 @@ """ -homeassistant.components.zwave +homeassistant.components.ecobee ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Connects Home Assistant to the Ecobee API and maintains tokens. @@ -12,6 +12,7 @@ api_key: asdflaksf from homeassistant.loader import get_component from homeassistant import bootstrap +from homeassistant.util import Throttle from homeassistant.const import ( EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, EVENT_PLATFORM_DISCOVERED, ATTR_SERVICE, ATTR_DISCOVERED, CONF_API_KEY) @@ -57,7 +58,7 @@ def request_configuration(network, hass): hass, "Ecobee", ecobee_configuration_callback, description=( 'Please authorize this app at https://www.ecobee.com/consumer' - 'portal/index.html with pin code: ' + NETWORK.pin), + 'portal/index.html with pin code: ' + network.pin), description_image="/static/images/config_ecobee_thermostat.png", submit_caption="I have authorized the app." ) @@ -75,6 +76,20 @@ def setup_ecobee(hass, network): configurator.request_done(_CONFIGURING.pop('ecobee')) +# pylint: disable=too-few-public-methods +class EcobeeData(object): + """ Gets the latest data and update the states. """ + + def __init__(self, config_file): + from pyecobee import Ecobee + self.ecobee = Ecobee(config_file) + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + def update(self): + """ Get the latest data from pyecobee. """ + self.ecobee.update() + + def setup(hass, config): """ Setup Ecobee. @@ -87,7 +102,7 @@ def setup(hass, config): if 'ecobee' in _CONFIGURING: return - from pyecobee import Ecobee, config_from_file + from pyecobee import config_from_file # Create ecobee.conf if it doesn't exist if not os.path.isfile(hass.config.path(ECOBEE_CONFIG_FILE)): @@ -97,9 +112,9 @@ def setup(hass, config): jsonconfig = {"API_KEY": config[DOMAIN].get(CONF_API_KEY)} config_from_file(hass.config.path(ECOBEE_CONFIG_FILE), jsonconfig) - NETWORK = Ecobee(hass.config.path(ECOBEE_CONFIG_FILE)) + NETWORK = EcobeeData(hass.config.path(ECOBEE_CONFIG_FILE)) - setup_ecobee(hass, NETWORK) + setup_ecobee(hass, NETWORK.ecobee) # Ensure component is loaded bootstrap.setup_component(hass, 'thermostat', config) diff --git a/homeassistant/components/thermostat/ecobee.py b/homeassistant/components/thermostat/ecobee.py index 5b377be4907..7f95aa7d1c6 100644 --- a/homeassistant/components/thermostat/ecobee.py +++ b/homeassistant/components/thermostat/ecobee.py @@ -26,8 +26,6 @@ thermostat: from homeassistant.components.thermostat import (ThermostatDevice, STATE_COOL, STATE_IDLE, STATE_HEAT) from homeassistant.const import (TEMP_FAHRENHEIT, STATE_ON, STATE_OFF) -from homeassistant.util import Throttle -from datetime import timedelta import logging DEPENDENCIES = ['ecobee'] @@ -37,39 +35,17 @@ _LOGGER = logging.getLogger(__name__) ECOBEE_CONFIG_FILE = 'ecobee.conf' _CONFIGURING = {} -# Return cached results if last scan was less then this time ago -MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=180) - def setup_platform(hass, config, add_devices, discovery_info=None): """ Setup Platform """ _LOGGER.error("ecobee !!!!") if discovery_info is None: return - data = EcobeeData(discovery_info[0]) - setup_ecobee(hass, data, add_devices) - - -def setup_ecobee(hass, data, add_devices): - """ Setup ecobee thermostat """ - + data = discovery_info[0] add_devices(Thermostat(data, index) for index in range(len(data.ecobee.thermostats))) -# pylint: disable=too-few-public-methods -class EcobeeData(object): - """ Gets the latest data and update the states. """ - - def __init__(self, network): - self.ecobee = network - - @Throttle(MIN_TIME_BETWEEN_UPDATES) - def update(self): - """ Get the latest data from pyecobee. """ - self.ecobee.update() - - class Thermostat(ThermostatDevice): """ Thermostat class for Ecobee """ From 8269e843f2a38ea9bf6da904e7a60d559ee29ba6 Mon Sep 17 00:00:00 2001 From: sfam Date: Mon, 23 Nov 2015 00:22:43 +0000 Subject: [PATCH 09/49] Initial commit for rollershutter component --- .../components/rollershutter/__init__.py | 116 +++++++++++++++++ .../components/rollershutter/mqtt.py | 119 ++++++++++++++++++ .../components/rollershutter/services.yaml | 0 tests/components/rollershutter/test_mqtt.py | 116 +++++++++++++++++ 4 files changed, 351 insertions(+) create mode 100644 homeassistant/components/rollershutter/__init__.py create mode 100644 homeassistant/components/rollershutter/mqtt.py create mode 100644 homeassistant/components/rollershutter/services.yaml create mode 100644 tests/components/rollershutter/test_mqtt.py diff --git a/homeassistant/components/rollershutter/__init__.py b/homeassistant/components/rollershutter/__init__.py new file mode 100644 index 00000000000..461a34200b2 --- /dev/null +++ b/homeassistant/components/rollershutter/__init__.py @@ -0,0 +1,116 @@ +""" +homeassistant.components.rollershutter +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Rollershutter component. + +""" +import os +import logging + +from homeassistant.config import load_yaml_config_file +from homeassistant.helpers.entity_component import EntityComponent +from homeassistant.helpers.entity import Entity +from homeassistant.components import group +from homeassistant.const import ( + SERVICE_MOVE_UP, SERVICE_MOVE_DOWN, SERVICE_MOVE_STOP, + STATE_OPEN, ATTR_ENTITY_ID) + + +DOMAIN = 'rollershutter' +DEPENDENCIES = [] +SCAN_INTERVAL = 15 + +GROUP_NAME_ALL_ROLLERSHUTTERS = 'all rollershutters' +ENTITY_ID_ALL_ROLLERSHUTTERS = group.ENTITY_ID_FORMAT.format( + 'all_rollershutters') + +ENTITY_ID_FORMAT = DOMAIN + '.{}' + +# Maps discovered services to their platforms +DISCOVERY_PLATFORMS = {} + +_LOGGER = logging.getLogger(__name__) + + +def is_open(hass, entity_id=None): + """ Returns if the rollershutter is open based on the statemachine. """ + entity_id = entity_id or ENTITY_ID_ALL_ROLLERSHUTTERS + return hass.states.is_state(entity_id, STATE_OPEN) + + +def move_up(hass, entity_id=None): + """ Moves all or specified rollershutter up. """ + data = {ATTR_ENTITY_ID: entity_id} if entity_id else None + hass.services.call(DOMAIN, SERVICE_MOVE_UP, data) + + +def move_down(hass, entity_id=None): + """ Moves all or specified rollershutter down. """ + data = {ATTR_ENTITY_ID: entity_id} if entity_id else None + hass.services.call(DOMAIN, SERVICE_MOVE_DOWN, data) + + +def move_stop(hass, entity_id=None): + """ Stops all or specified rollershutter. """ + data = {ATTR_ENTITY_ID: entity_id} if entity_id else None + hass.services.call(DOMAIN, SERVICE_MOVE_STOP, data) + + +def setup(hass, config): + """ Track states and offer events for rollershutters. """ + component = EntityComponent( + _LOGGER, DOMAIN, hass, SCAN_INTERVAL, DISCOVERY_PLATFORMS, + GROUP_NAME_ALL_ROLLERSHUTTERS) + component.setup(config) + + def handle_rollershutter_service(service): + """ Handles calls to the rollershutter services. """ + target_rollershutters = component.extract_from_service(service) + + for rollershutter in target_rollershutters: + if service.service == SERVICE_MOVE_UP: + rollershutter.move_up() + elif service.service == SERVICE_MOVE_DOWN: + rollershutter.move_down() + elif service.service == SERVICE_MOVE_STOP: + rollershutter.move_stop() + + if rollershutter.should_poll: + rollershutter.update_ha_state(True) + + descriptions = load_yaml_config_file( + os.path.join(os.path.dirname(__file__), 'services.yaml')) + + hass.services.register(DOMAIN, SERVICE_MOVE_UP, + handle_rollershutter_service, + descriptions.get(SERVICE_MOVE_UP)) + hass.services.register(DOMAIN, SERVICE_MOVE_DOWN, + handle_rollershutter_service, + descriptions.get(SERVICE_MOVE_DOWN)) + hass.services.register(DOMAIN, SERVICE_MOVE_STOP, + handle_rollershutter_service, + descriptions.get(SERVICE_MOVE_STOP)) + + return True + + +class RollershutterDevice(Entity): + """ Represents a rollershutter within Home Assistant. """ + # pylint: disable=no-self-use + + @property + def state_attributes(self): + """ Returns optional state attributes. """ + return None + + def move_up(self, **kwargs): + """ Moves the device UP. """ + raise NotImplementedError() + + def move_down(self, **kwargs): + """ Moves the device DOWN. """ + raise NotImplementedError() + + def move_stop(self, **kwargs): + """ Moves the device to STOP. """ + raise NotImplementedError() diff --git a/homeassistant/components/rollershutter/mqtt.py b/homeassistant/components/rollershutter/mqtt.py new file mode 100644 index 00000000000..ad5a4346bc9 --- /dev/null +++ b/homeassistant/components/rollershutter/mqtt.py @@ -0,0 +1,119 @@ +""" +homeassistant.components.rollershutter.mqtt +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Allows to configure a MQTT rollershutter. +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/rollershutter.mqtt/ +""" +import logging +import homeassistant.components.mqtt as mqtt +from homeassistant.components.rollershutter import RollershutterDevice +from homeassistant.const import (STATE_OPEN, STATE_CLOSED, STATE_UNKNOWN) +_LOGGER = logging.getLogger(__name__) + +DEPENDENCIES = ['mqtt'] + +DEFAULT_NAME = "MQTT Shutter" +DEFAULT_QOS = 0 +DEFAULT_PAYLOAD_UP = "UP" +DEFAULT_PAYLOAD_DOWN = "DOWN" +DEFAULT_PAYLOAD_STOP = "STOP" + +ATTR_CURRENT_POSITION = 'current_position' + + +# pylint: disable=unused-argument +def setup_platform(hass, config, add_devices_callback, discovery_info=None): + """ Add MQTT Roller Shutter """ + + if config.get('command_topic') is None: + _LOGGER.error("Missing required variable: command_topic") + return False + + add_devices_callback([MqttRollershutter( + hass, + config.get('name', DEFAULT_NAME), + config.get('state_topic'), + config.get('command_topic'), + config.get('qos', DEFAULT_QOS), + config.get('payload_up', DEFAULT_PAYLOAD_UP), + config.get('payload_down', DEFAULT_PAYLOAD_DOWN), + config.get('payload_stop', DEFAULT_PAYLOAD_STOP), + config.get('state_format'))]) + + +# pylint: disable=too-many-arguments, too-many-instance-attributes +class MqttRollershutter(RollershutterDevice): + """ Represents a rollershutter that can be togggled using MQTT """ + def __init__(self, hass, name, state_topic, command_topic, qos, + payload_up, payload_down, payload_stop, state_format): + self._state = -1 + self._hass = hass + self._name = name + self._state_topic = state_topic + self._command_topic = command_topic + self._qos = qos + self._payload_up = payload_up + self._payload_down = payload_down + self._payload_stop = payload_stop + self._parse = mqtt.FmtParser(state_format) + + if self._state_topic: + def message_received(topic, payload, qos): + """ A new MQTT message has been received. """ + value = self._parse(payload) + if value.isnumeric(): + if 0 <= int(value) <= 100: + self._state = int(value) + self.update_ha_state() + + mqtt.subscribe(hass, self._state_topic, message_received, + self._qos) + + @property + def should_poll(self): + """ No polling needed """ + return False + + @property + def name(self): + """ The name of the rollershutter """ + return self._name + + @property + def state(self): + """ Returns the state of the device. """ + if self._state == -1: + return STATE_UNKNOWN + elif self._state == 0: + return STATE_CLOSED + else: + return STATE_OPEN + + @property + def is_open(self): + """ True if device is open. """ + return self.state == STATE_OPEN + + def move_up(self, **kwargs): + """ Moves the device UP. """ + mqtt.publish(self.hass, self._command_topic, self._payload_up, + self._qos) + + def move_down(self, **kwargs): + """ Moves the device DOWN. """ + mqtt.publish(self.hass, self._command_topic, self._payload_down, + self._qos) + + def move_stop(self, **kwargs): + """ Moves the device to STOP. """ + mqtt.publish(self.hass, self._command_topic, self._payload_stop, + self._qos) + + @property + def state_attributes(self): + """ Return the state attributes. """ + state_attr = { + ATTR_CURRENT_POSITION: self._state, + } + return state_attr diff --git a/homeassistant/components/rollershutter/services.yaml b/homeassistant/components/rollershutter/services.yaml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/components/rollershutter/test_mqtt.py b/tests/components/rollershutter/test_mqtt.py new file mode 100644 index 00000000000..099d8fad1ea --- /dev/null +++ b/tests/components/rollershutter/test_mqtt.py @@ -0,0 +1,116 @@ +""" +tests.components.rollershutter.test_mqtt +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Tests mqtt rollershutter. +""" +import unittest + +from homeassistant.const import STATE_OPEN, STATE_CLOSED, STATE_UNKNOWN +import homeassistant.core as ha +import homeassistant.components.rollershutter as rollershutter +from tests.common import mock_mqtt_component, fire_mqtt_message + + +class TestRollershutterMQTT(unittest.TestCase): + """ Test the MQTT rollershutter. """ + + def setUp(self): # pylint: disable=invalid-name + self.hass = ha.HomeAssistant() + self.mock_publish = mock_mqtt_component(self.hass) + + def tearDown(self): # pylint: disable=invalid-name + """ Stop down stuff we started. """ + self.hass.stop() + + def test_controlling_state_via_topic(self): + self.assertTrue(rollershutter.setup(self.hass, { + 'rollershutter': { + 'platform': 'mqtt', + 'name': 'test', + 'state_topic': 'state-topic', + 'command_topic': 'command-topic', + 'qos': 0, + 'payload_up': 'UP', + 'payload_down': 'DOWN', + 'payload_stop': 'STOP' + } + })) + + state = self.hass.states.get('rollershutter.test') + self.assertEqual(STATE_UNKNOWN, state.state) + + fire_mqtt_message(self.hass, 'state-topic', '0') + self.hass.pool.block_till_done() + + state = self.hass.states.get('rollershutter.test') + self.assertEqual(STATE_CLOSED, state.state) + + fire_mqtt_message(self.hass, 'state-topic', '50') + self.hass.pool.block_till_done() + + state = self.hass.states.get('rollershutter.test') + self.assertEqual(STATE_OPEN, state.state) + + fire_mqtt_message(self.hass, 'state-topic', '100') + self.hass.pool.block_till_done() + + state = self.hass.states.get('rollershutter.test') + self.assertEqual(STATE_OPEN, state.state) + + def test_sending_mqtt_commands(self): + self.assertTrue(rollershutter.setup(self.hass, { + 'rollershutter': { + 'platform': 'mqtt', + 'name': 'test', + 'state_topic': 'state-topic', + 'command_topic': 'command-topic', + 'qos': 2 + } + })) + + state = self.hass.states.get('rollershutter.test') + self.assertEqual(STATE_UNKNOWN, state.state) + + rollershutter.move_up(self.hass, 'rollershutter.test') + self.hass.pool.block_till_done() + + self.assertEqual(('command-topic', 'UP', 2), + self.mock_publish.mock_calls[-1][1]) + state = self.hass.states.get('rollershutter.test') + self.assertEqual(STATE_UNKNOWN, state.state) + + def test_state_attributes_current_position(self): + self.assertTrue(rollershutter.setup(self.hass, { + 'rollershutter': { + 'platform': 'mqtt', + 'name': 'test', + 'state_topic': 'state-topic', + 'command_topic': 'command-topic', + 'payload_up': 'UP', + 'payload_down': 'DOWN', + 'payload_stop': 'STOP' + } + })) + + current_position = self.hass.states.get( + 'rollershutter.test').attributes['current_position'] + self.assertEqual(-1, current_position) + + fire_mqtt_message(self.hass, 'state-topic', '0') + self.hass.pool.block_till_done() + current_position = self.hass.states.get( + 'rollershutter.test').attributes['current_position'] + self.assertEqual(0, current_position) + + fire_mqtt_message(self.hass, 'state-topic', '50') + self.hass.pool.block_till_done() + current_position = self.hass.states.get( + 'rollershutter.test').attributes['current_position'] + self.assertEqual(50, current_position) + + fire_mqtt_message(self.hass, 'state-topic', '101') + self.hass.pool.block_till_done() + current_position = self.hass.states.get( + 'rollershutter.test').attributes['current_position'] + self.assertEqual(50, current_position) From d4b3af327d0dfab571df7c411e26f95a4612fa2f Mon Sep 17 00:00:00 2001 From: sfam Date: Mon, 23 Nov 2015 00:25:10 +0000 Subject: [PATCH 10/49] Initial commit for rollershutter component --- homeassistant/const.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 5b0b5a5e214..047f66ef924 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -53,8 +53,6 @@ STATE_ALARM_ARMED_HOME = 'armed_home' STATE_ALARM_ARMED_AWAY = 'armed_away' STATE_ALARM_PENDING = 'pending' STATE_ALARM_TRIGGERED = 'triggered' -STATE_LOCKED = 'locked' -STATE_UNLOCKED = 'unlocked' # #### STATE AND EVENT ATTRIBUTES #### # Contains current time for a TIME_CHANGED event @@ -98,9 +96,6 @@ ATTR_BATTERY_LEVEL = "battery_level" # For devices which support an armed state ATTR_ARMED = "device_armed" -# For devices which support a locked state -ATTR_LOCKED = "locked" - # For sensors that support 'tripping', eg. motion and door sensors ATTR_TRIPPED = "device_tripped" @@ -140,8 +135,9 @@ SERVICE_ALARM_ARM_HOME = "alarm_arm_home" SERVICE_ALARM_ARM_AWAY = "alarm_arm_away" SERVICE_ALARM_TRIGGER = "alarm_trigger" -SERVICE_LOCK = "lock" -SERVICE_UNLOCK = "unlock" +SERVICE_MOVE_UP = 'move_up' +SERVICE_MOVE_DOWN = 'move_down' +SERVICE_MOVE_STOP = 'move_stop' # #### API / REMOTE #### SERVER_PORT = 8123 From 68ff9dd74f61fce99adfeaba3dc4519bbc0dc997 Mon Sep 17 00:00:00 2001 From: sfam Date: Mon, 23 Nov 2015 00:35:22 +0000 Subject: [PATCH 11/49] rollershutter component - fix const --- homeassistant/const.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/homeassistant/const.py b/homeassistant/const.py index 047f66ef924..add1848b72c 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -53,6 +53,8 @@ STATE_ALARM_ARMED_HOME = 'armed_home' STATE_ALARM_ARMED_AWAY = 'armed_away' STATE_ALARM_PENDING = 'pending' STATE_ALARM_TRIGGERED = 'triggered' +STATE_LOCKED = 'locked' +STATE_UNLOCKED = 'unlocked' # #### STATE AND EVENT ATTRIBUTES #### # Contains current time for a TIME_CHANGED event @@ -96,6 +98,9 @@ ATTR_BATTERY_LEVEL = "battery_level" # For devices which support an armed state ATTR_ARMED = "device_armed" +# For devices which support a locked state +ATTR_LOCKED = "locked" + # For sensors that support 'tripping', eg. motion and door sensors ATTR_TRIPPED = "device_tripped" @@ -135,6 +140,9 @@ SERVICE_ALARM_ARM_HOME = "alarm_arm_home" SERVICE_ALARM_ARM_AWAY = "alarm_arm_away" SERVICE_ALARM_TRIGGER = "alarm_trigger" +SERVICE_LOCK = "lock" +SERVICE_UNLOCK = "unlock" + SERVICE_MOVE_UP = 'move_up' SERVICE_MOVE_DOWN = 'move_down' SERVICE_MOVE_STOP = 'move_stop' From cc196d988867fe7e7d08c062c3ca06bf3383bdcf Mon Sep 17 00:00:00 2001 From: "nkgilley@gmail.com" Date: Mon, 23 Nov 2015 11:15:19 -0500 Subject: [PATCH 12/49] fixed sensors and thermostat. discovery working for both now. --- homeassistant/components/ecobee.py | 70 ++++++++++++------ homeassistant/components/sensor/__init__.py | 5 +- homeassistant/components/sensor/ecobee.py | 73 ++++++++++--------- .../components/thermostat/__init__.py | 8 +- homeassistant/components/thermostat/ecobee.py | 35 ++++++--- 5 files changed, 118 insertions(+), 73 deletions(-) diff --git a/homeassistant/components/ecobee.py b/homeassistant/components/ecobee.py index ef982a15e63..8b73a9969ef 100644 --- a/homeassistant/components/ecobee.py +++ b/homeassistant/components/ecobee.py @@ -1,13 +1,29 @@ """ homeassistant.components.ecobee -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Connects Home Assistant to the Ecobee API and maintains tokens. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -For more details about this component, please refer to the documentation at -https://home-assistant.io/components/ecobee/ +Ecobee Component + +This component adds support for Ecobee3 Wireless Thermostats. +You will need to setup developer access to your thermostat, +and create and API key on the ecobee website. + +The first time you run this component you will see a configuration +component card in Home Assistant. This card will contain a PIN code +that you will need to use to authorize access to your thermostat. You +can do this at https://www.ecobee.com/consumerportal/index.html +Click My Apps, Add application, Enter Pin and click Authorize. + +After authorizing the application click the button in the configuration +card. Now your thermostat and sensors should shown in home-assistant. + +You can use the optional hold_temp parameter to set whether or not holds +are set indefintely or until the next scheduled event. + +ecobee: + api_key: asdfasdfasdfasdfasdfaasdfasdfasdfasdf + hold_temp: True -[ecobee] -api_key: asdflaksf """ from homeassistant.loader import get_component @@ -22,8 +38,10 @@ import os DOMAIN = "ecobee" DISCOVER_THERMOSTAT = "ecobee.thermostat" +DISCOVER_SENSORS = "ecobee.sensor" DEPENDENCIES = [] NETWORK = None +HOLD_TEMP = 'hold_temp' REQUIREMENTS = [ 'https://github.com/nkgilley/python-ecobee-api/archive/' @@ -38,7 +56,7 @@ _CONFIGURING = {} MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=180) -def request_configuration(network, hass): +def request_configuration(network, hass, config): """ Request configuration steps from the user. """ configurator = get_component('configurator') if 'ecobee' in _CONFIGURING: @@ -52,7 +70,7 @@ def request_configuration(network, hass): """ Actions to do when our configuration callback is called. """ network.request_tokens() network.update() - setup_ecobee(hass, network) + setup_ecobee(hass, network, config) _CONFIGURING['ecobee'] = configurator.request_config( hass, "Ecobee", ecobee_configuration_callback, @@ -64,17 +82,35 @@ def request_configuration(network, hass): ) -def setup_ecobee(hass, network): +def setup_ecobee(hass, network, config): """ Setup ecobee thermostat """ # If ecobee has a PIN then it needs to be configured. if network.pin is not None: - request_configuration(network, hass) + request_configuration(network, hass, config) return if 'ecobee' in _CONFIGURING: configurator = get_component('configurator') configurator.request_done(_CONFIGURING.pop('ecobee')) + # Ensure component is loaded + bootstrap.setup_component(hass, 'thermostat') + bootstrap.setup_component(hass, 'sensor') + + hold_temp = config[DOMAIN].get(HOLD_TEMP, False) + + # Fire thermostat discovery event + hass.bus.fire(EVENT_PLATFORM_DISCOVERED, { + ATTR_SERVICE: DISCOVER_THERMOSTAT, + ATTR_DISCOVERED: {'hold_temp': hold_temp} + }) + + # Fire sensor discovery event + hass.bus.fire(EVENT_PLATFORM_DISCOVERED, { + ATTR_SERVICE: DISCOVER_SENSORS, + ATTR_DISCOVERED: {} + }) + # pylint: disable=too-few-public-methods class EcobeeData(object): @@ -88,6 +124,7 @@ class EcobeeData(object): def update(self): """ Get the latest data from pyecobee. """ self.ecobee.update() + _LOGGER.info("ecobee data updated successfully.") def setup(hass, config): @@ -114,18 +151,7 @@ def setup(hass, config): NETWORK = EcobeeData(hass.config.path(ECOBEE_CONFIG_FILE)) - setup_ecobee(hass, NETWORK.ecobee) - - # Ensure component is loaded - bootstrap.setup_component(hass, 'thermostat', config) - - # Fire discovery event - hass.bus.fire(EVENT_PLATFORM_DISCOVERED, { - ATTR_SERVICE: DISCOVER_THERMOSTAT, - ATTR_DISCOVERED: { - 'network': NETWORK, - } - }) + setup_ecobee(hass, NETWORK.ecobee, config) def stop_ecobee(event): """ Stop Ecobee. """ diff --git a/homeassistant/components/sensor/__init__.py b/homeassistant/components/sensor/__init__.py index 32ee59a6fa9..0d214475358 100644 --- a/homeassistant/components/sensor/__init__.py +++ b/homeassistant/components/sensor/__init__.py @@ -9,7 +9,7 @@ https://home-assistant.io/components/sensor/ import logging from homeassistant.helpers.entity_component import EntityComponent -from homeassistant.components import wink, zwave, isy994, verisure +from homeassistant.components import wink, zwave, isy994, verisure, ecobee DOMAIN = 'sensor' DEPENDENCIES = [] @@ -22,7 +22,8 @@ DISCOVERY_PLATFORMS = { wink.DISCOVER_SENSORS: 'wink', zwave.DISCOVER_SENSORS: 'zwave', isy994.DISCOVER_SENSORS: 'isy994', - verisure.DISCOVER_SENSORS: 'verisure' + verisure.DISCOVER_SENSORS: 'verisure', + ecobee.DISCOVER_SENSORS: 'ecobee' } diff --git a/homeassistant/components/sensor/ecobee.py b/homeassistant/components/sensor/ecobee.py index a8d9e41acb1..b7663a70d6a 100644 --- a/homeassistant/components/sensor/ecobee.py +++ b/homeassistant/components/sensor/ecobee.py @@ -1,22 +1,39 @@ """ homeassistant.components.sensor.ecobee -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This sensor component requires that the Ecobee Thermostat -component be setup first. This component shows remote -ecobee sensor data. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Ecobee Thermostat Component + +This component adds support for Ecobee3 Wireless Thermostats. +You will need to setup developer access to your thermostat, +and create and API key on the ecobee website. + +The first time you run this component you will see a configuration +component card in Home Assistant. This card will contain a PIN code +that you will need to use to authorize access to your thermostat. You +can do this at https://www.ecobee.com/consumerportal/index.html +Click My Apps, Add application, Enter Pin and click Authorize. + +After authorizing the application click the button in the configuration +card. Now your thermostat and sensors should shown in home-assistant. + +You can use the optional hold_temp parameter to set whether or not holds +are set indefintely or until the next scheduled event. + +ecobee: + api_key: asdfasdfasdfasdfasdfaasdfasdfasdfasdf + hold_temp: True -For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/sensor.ecobee/ """ from homeassistant.helpers.entity import Entity -import json +from homeassistant.components.ecobee import NETWORK +from homeassistant.const import TEMP_FAHRENHEIT import logging -import os -DEPENDENCIES = ['thermostat'] +DEPENDENCIES = ['ecobee'] SENSOR_TYPES = { - 'temperature': ['Temperature', '°F'], + 'temperature': ['Temperature', TEMP_FAHRENHEIT], 'humidity': ['Humidity', '%'], 'occupancy': ['Occupancy', ''] } @@ -26,24 +43,12 @@ _LOGGER = logging.getLogger(__name__) ECOBEE_CONFIG_FILE = 'ecobee.conf' -def config_from_file(filename): - ''' Small configuration file reading function ''' - if os.path.isfile(filename): - try: - with open(filename, 'r') as fdesc: - return json.loads(fdesc.read()) - except IOError as error: - _LOGGER.error("ecobee sensor couldn't read config file: " + error) - return False - else: - return {} - - def setup_platform(hass, config, add_devices, discovery_info=None): """ Sets up the sensors. """ - config = config_from_file(hass.config.path(ECOBEE_CONFIG_FILE)) + if discovery_info is None: + return dev = list() - for name, data in config['sensors'].items(): + for name, data in NETWORK.ecobee.sensors.items(): if 'temp' in data: dev.append(EcobeeSensor(name, 'temperature', hass)) if 'humidity' in data: @@ -80,14 +85,10 @@ class EcobeeSensor(Entity): return self._unit_of_measurement def update(self): - config = config_from_file(self.hass.config.path(ECOBEE_CONFIG_FILE)) - try: - data = config['sensors'][self.sensor_name] - if self.type == 'temperature': - self._state = data['temp'] - elif self.type == 'humidity': - self._state = data['humidity'] - elif self.type == 'occupancy': - self._state = data['occupancy'] - except KeyError: - print("Error updating ecobee sensors.") + data = NETWORK.ecobee.sensors[self.sensor_name] + if self.type == 'temperature': + self._state = data['temp'] + elif self.type == 'humidity': + self._state = data['humidity'] + elif self.type == 'occupancy': + self._state = data['occupancy'] diff --git a/homeassistant/components/thermostat/__init__.py b/homeassistant/components/thermostat/__init__.py index 480e3e4805e..f1a82a4c989 100644 --- a/homeassistant/components/thermostat/__init__.py +++ b/homeassistant/components/thermostat/__init__.py @@ -15,6 +15,7 @@ from homeassistant.config import load_yaml_config_file import homeassistant.util as util from homeassistant.helpers.entity import Entity from homeassistant.helpers.temperature import convert +from homeassistant.components import ecobee from homeassistant.const import ( ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_ON, STATE_OFF, STATE_UNKNOWN, TEMP_CELCIUS) @@ -42,6 +43,10 @@ ATTR_OPERATION = "current_operation" _LOGGER = logging.getLogger(__name__) +DISCOVERY_PLATFORMS = { + ecobee.DISCOVER_THERMOSTAT: 'ecobee', +} + def set_away_mode(hass, away_mode, entity_id=None): """ Turn all or specified thermostat away mode on. """ @@ -67,7 +72,8 @@ def set_temperature(hass, temperature, entity_id=None): def setup(hass, config): """ Setup thermostats. """ - component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL) + component = EntityComponent(_LOGGER, DOMAIN, hass, + SCAN_INTERVAL, DISCOVERY_PLATFORMS) component.setup(config) def thermostat_service(service): diff --git a/homeassistant/components/thermostat/ecobee.py b/homeassistant/components/thermostat/ecobee.py index 7f95aa7d1c6..51d21cb9991 100644 --- a/homeassistant/components/thermostat/ecobee.py +++ b/homeassistant/components/thermostat/ecobee.py @@ -15,17 +15,20 @@ can do this at https://www.ecobee.com/consumerportal/index.html Click My Apps, Add application, Enter Pin and click Authorize. After authorizing the application click the button in the configuration -card. Now your thermostat should shown in home-assistant. Once the -thermostat has been added you can add the ecobee sensor component -to your configuration.yaml. +card. Now your thermostat and sensors should shown in home-assistant. -thermostat: - platform: ecobee +You can use the optional hold_temp parameter to set whether or not holds +are set indefintely or until the next scheduled event. + +ecobee: api_key: asdfasdfasdfasdfasdfaasdfasdfasdfasdf + hold_temp: True + """ from homeassistant.components.thermostat import (ThermostatDevice, STATE_COOL, STATE_IDLE, STATE_HEAT) from homeassistant.const import (TEMP_FAHRENHEIT, STATE_ON, STATE_OFF) +from homeassistant.components.ecobee import NETWORK import logging DEPENDENCIES = ['ecobee'] @@ -38,30 +41,32 @@ _CONFIGURING = {} def setup_platform(hass, config, add_devices, discovery_info=None): """ Setup Platform """ - _LOGGER.error("ecobee !!!!") if discovery_info is None: return - data = discovery_info[0] - add_devices(Thermostat(data, index) + data = NETWORK + hold_temp = discovery_info['hold_temp'] + _LOGGER.info("Loading ecobee thermostat component with hold_temp set to " + + str(hold_temp)) + add_devices(Thermostat(data, index, hold_temp) for index in range(len(data.ecobee.thermostats))) class Thermostat(ThermostatDevice): """ Thermostat class for Ecobee """ - def __init__(self, data, thermostat_index): + def __init__(self, data, thermostat_index, hold_temp): self.data = data self.thermostat_index = thermostat_index self.thermostat = self.data.ecobee.get_thermostat( self.thermostat_index) self._name = self.thermostat['name'] self._away = 'away' in self.thermostat['program']['currentClimateRef'] + self.hold_temp = hold_temp def update(self): self.data.update() self.thermostat = self.data.ecobee.get_thermostat( self.thermostat_index) - _LOGGER.info("ecobee data updated successfully.") @property def name(self): @@ -157,7 +162,10 @@ class Thermostat(ThermostatDevice): def turn_away_mode_on(self): """ Turns away on. """ self._away = True - self.data.ecobee.set_climate_hold("away") + if self.hold_temp: + self.data.ecobee.set_climate_hold("away", "indefinite") + else: + self.data.ecobee.set_climate_hold("away") def turn_away_mode_off(self): """ Turns away off. """ @@ -169,7 +177,10 @@ class Thermostat(ThermostatDevice): temperature = int(temperature) low_temp = temperature - 1 high_temp = temperature + 1 - self.data.ecobee.set_hold_temp(low_temp, high_temp) + if self.hold_temp: + self.data.ecobee.set_hold_temp(low_temp, high_temp, "indefinite") + else: + self.data.ecobee.set_hold_temp(low_temp, high_temp) def set_hvac_mode(self, mode): """ Set HVAC mode (auto, auxHeatOnly, cool, heat, off) """ From 27bc4c582bc2fa7ce3b7467f2823525879d5ee12 Mon Sep 17 00:00:00 2001 From: "nkgilley@gmail.com" Date: Mon, 23 Nov 2015 11:40:54 -0500 Subject: [PATCH 13/49] update network data before sensor setup. --- homeassistant/components/sensor/ecobee.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/sensor/ecobee.py b/homeassistant/components/sensor/ecobee.py index b7663a70d6a..1ef40bcca89 100644 --- a/homeassistant/components/sensor/ecobee.py +++ b/homeassistant/components/sensor/ecobee.py @@ -48,13 +48,14 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if discovery_info is None: return dev = list() + NETWORK.update() for name, data in NETWORK.ecobee.sensors.items(): if 'temp' in data: - dev.append(EcobeeSensor(name, 'temperature', hass)) + dev.append(EcobeeSensor(name, 'temperature')) if 'humidity' in data: - dev.append(EcobeeSensor(name, 'humidity', hass)) + dev.append(EcobeeSensor(name, 'humidity')) if 'occupancy' in data: - dev.append(EcobeeSensor(name, 'occupancy', hass)) + dev.append(EcobeeSensor(name, 'occupancy')) add_devices(dev) @@ -62,10 +63,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class EcobeeSensor(Entity): """ An ecobee sensor. """ - def __init__(self, sensor_name, sensor_type, hass): + def __init__(self, sensor_name, sensor_type): self._name = sensor_name + ' ' + SENSOR_TYPES[sensor_type][0] self.sensor_name = sensor_name - self.hass = hass self.type = sensor_type self._state = None self._unit_of_measurement = SENSOR_TYPES[sensor_type][1] @@ -85,6 +85,7 @@ class EcobeeSensor(Entity): return self._unit_of_measurement def update(self): + NETWORK.update() data = NETWORK.ecobee.sensors[self.sensor_name] if self.type == 'temperature': self._state = data['temp'] From 80e829f53a1482757be9671b3ac864e2ced0f5ab Mon Sep 17 00:00:00 2001 From: "nkgilley@gmail.com" Date: Mon, 23 Nov 2015 11:52:02 -0500 Subject: [PATCH 14/49] was getting errors for NETWORK being None. looked like it was being loaded too early, so this will wait until it's ready --- homeassistant/components/sensor/ecobee.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/sensor/ecobee.py b/homeassistant/components/sensor/ecobee.py index 1ef40bcca89..524ac912405 100644 --- a/homeassistant/components/sensor/ecobee.py +++ b/homeassistant/components/sensor/ecobee.py @@ -48,7 +48,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if discovery_info is None: return dev = list() - NETWORK.update() + while NETWORK is None: + continue for name, data in NETWORK.ecobee.sensors.items(): if 'temp' in data: dev.append(EcobeeSensor(name, 'temperature')) From e001ea913a6132571a1b79cad50e07ac6d288190 Mon Sep 17 00:00:00 2001 From: sfam Date: Tue, 24 Nov 2015 08:03:02 +0000 Subject: [PATCH 15/49] add __init__.py to test folder --- tests/components/alarm_control_panel/__init__.py | 0 tests/components/rollershutter/__init__.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/components/alarm_control_panel/__init__.py create mode 100644 tests/components/rollershutter/__init__.py diff --git a/tests/components/alarm_control_panel/__init__.py b/tests/components/alarm_control_panel/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/components/rollershutter/__init__.py b/tests/components/rollershutter/__init__.py new file mode 100644 index 00000000000..e69de29bb2d From 351430c1b38415ec790701b7c303d2a8ad1d3a04 Mon Sep 17 00:00:00 2001 From: sfam Date: Tue, 24 Nov 2015 10:41:39 +0000 Subject: [PATCH 16/49] move current_position to RollershutterDevice class --- .../components/rollershutter/__init__.py | 17 ++++++- .../components/rollershutter/mqtt.py | 46 +++++++++---------- tests/components/rollershutter/test_mqtt.py | 12 +++-- 3 files changed, 47 insertions(+), 28 deletions(-) diff --git a/homeassistant/components/rollershutter/__init__.py b/homeassistant/components/rollershutter/__init__.py index 461a34200b2..5ebcf8a3d21 100644 --- a/homeassistant/components/rollershutter/__init__.py +++ b/homeassistant/components/rollershutter/__init__.py @@ -13,7 +13,7 @@ from homeassistant.helpers.entity import Entity from homeassistant.components import group from homeassistant.const import ( SERVICE_MOVE_UP, SERVICE_MOVE_DOWN, SERVICE_MOVE_STOP, - STATE_OPEN, ATTR_ENTITY_ID) + STATE_OPEN, STATE_CLOSED, STATE_UNKNOWN, ATTR_ENTITY_ID) DOMAIN = 'rollershutter' @@ -98,6 +98,21 @@ class RollershutterDevice(Entity): """ Represents a rollershutter within Home Assistant. """ # pylint: disable=no-self-use + @property + def current_position(self): + """ Return current position of rollershutter. + None is unknown, 0 is closed, 100 is fully open. """ + raise NotImplementedError() + + @property + def state(self): + current = self.current_position + + if current is None: + return STATE_UNKNOWN + + return STATE_CLOSED if current == 0 else STATE_OPEN + @property def state_attributes(self): """ Returns optional state attributes. """ diff --git a/homeassistant/components/rollershutter/mqtt.py b/homeassistant/components/rollershutter/mqtt.py index ad5a4346bc9..6128a4d9819 100644 --- a/homeassistant/components/rollershutter/mqtt.py +++ b/homeassistant/components/rollershutter/mqtt.py @@ -8,7 +8,6 @@ https://home-assistant.io/components/rollershutter.mqtt/ import logging import homeassistant.components.mqtt as mqtt from homeassistant.components.rollershutter import RollershutterDevice -from homeassistant.const import (STATE_OPEN, STATE_CLOSED, STATE_UNKNOWN) _LOGGER = logging.getLogger(__name__) DEPENDENCIES = ['mqtt'] @@ -47,7 +46,7 @@ class MqttRollershutter(RollershutterDevice): """ Represents a rollershutter that can be togggled using MQTT """ def __init__(self, hass, name, state_topic, command_topic, qos, payload_up, payload_down, payload_stop, state_format): - self._state = -1 + self._state = None self._hass = hass self._name = name self._state_topic = state_topic @@ -58,17 +57,20 @@ class MqttRollershutter(RollershutterDevice): self._payload_stop = payload_stop self._parse = mqtt.FmtParser(state_format) - if self._state_topic: - def message_received(topic, payload, qos): - """ A new MQTT message has been received. """ - value = self._parse(payload) - if value.isnumeric(): - if 0 <= int(value) <= 100: - self._state = int(value) - self.update_ha_state() + if self._state_topic is None: + return - mqtt.subscribe(hass, self._state_topic, message_received, - self._qos) + def message_received(topic, payload, qos): + """ A new MQTT message has been received. """ + value = self._parse(payload) + if value.isnumeric() and 0 <= int(value) <= 100: + self._state = int(value) + self.update_ha_state() + else: + _LOGGER.warning( + "Payload is expected to be an integer between 0 and 100") + + mqtt.subscribe(hass, self._state_topic, message_received, self._qos) @property def should_poll(self): @@ -81,19 +83,15 @@ class MqttRollershutter(RollershutterDevice): return self._name @property - def state(self): - """ Returns the state of the device. """ - if self._state == -1: - return STATE_UNKNOWN - elif self._state == 0: - return STATE_CLOSED - else: - return STATE_OPEN + def current_position(self): + """ Return current position of rollershutter. + None is unknown, 0 is closed, 100 is fully open. """ + return self._state @property def is_open(self): """ True if device is open. """ - return self.state == STATE_OPEN + return self._state > 0 def move_up(self, **kwargs): """ Moves the device UP. """ @@ -113,7 +111,7 @@ class MqttRollershutter(RollershutterDevice): @property def state_attributes(self): """ Return the state attributes. """ - state_attr = { - ATTR_CURRENT_POSITION: self._state, - } + state_attr = {} + if self._state is not None: + state_attr[ATTR_CURRENT_POSITION] = self._state return state_attr diff --git a/tests/components/rollershutter/test_mqtt.py b/tests/components/rollershutter/test_mqtt.py index 099d8fad1ea..2a71163c50f 100644 --- a/tests/components/rollershutter/test_mqtt.py +++ b/tests/components/rollershutter/test_mqtt.py @@ -93,9 +93,9 @@ class TestRollershutterMQTT(unittest.TestCase): } })) - current_position = self.hass.states.get( - 'rollershutter.test').attributes['current_position'] - self.assertEqual(-1, current_position) + state_attributes_dict = self.hass.states.get( + 'rollershutter.test').attributes + self.assertFalse('current_position' in state_attributes_dict) fire_mqtt_message(self.hass, 'state-topic', '0') self.hass.pool.block_till_done() @@ -114,3 +114,9 @@ class TestRollershutterMQTT(unittest.TestCase): current_position = self.hass.states.get( 'rollershutter.test').attributes['current_position'] self.assertEqual(50, current_position) + + fire_mqtt_message(self.hass, 'state-topic', 'non-numeric') + self.hass.pool.block_till_done() + current_position = self.hass.states.get( + 'rollershutter.test').attributes['current_position'] + self.assertEqual(50, current_position) From 067b5862c01731df43093085bbee2a514ff96667 Mon Sep 17 00:00:00 2001 From: "nkgilley@gmail.com" Date: Tue, 24 Nov 2015 09:29:33 -0500 Subject: [PATCH 17/49] bug fixes --- homeassistant/components/ecobee.py | 13 ------------- homeassistant/components/sensor/ecobee.py | 10 ++++------ homeassistant/components/thermostat/ecobee.py | 4 ++-- 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/homeassistant/components/ecobee.py b/homeassistant/components/ecobee.py index 8b73a9969ef..03f17133501 100644 --- a/homeassistant/components/ecobee.py +++ b/homeassistant/components/ecobee.py @@ -30,7 +30,6 @@ from homeassistant.loader import get_component from homeassistant import bootstrap from homeassistant.util import Throttle from homeassistant.const import ( - EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, EVENT_PLATFORM_DISCOVERED, ATTR_SERVICE, ATTR_DISCOVERED, CONF_API_KEY) from datetime import timedelta import logging @@ -153,16 +152,4 @@ def setup(hass, config): setup_ecobee(hass, NETWORK.ecobee, config) - def stop_ecobee(event): - """ Stop Ecobee. """ - - pass - - def start_ecobee(event): - """ Called when Home Assistant starts up. """ - - hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_ecobee) - - hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_ecobee) - return True diff --git a/homeassistant/components/sensor/ecobee.py b/homeassistant/components/sensor/ecobee.py index 524ac912405..a6499949015 100644 --- a/homeassistant/components/sensor/ecobee.py +++ b/homeassistant/components/sensor/ecobee.py @@ -26,7 +26,7 @@ ecobee: """ from homeassistant.helpers.entity import Entity -from homeassistant.components.ecobee import NETWORK +from homeassistant.components import ecobee from homeassistant.const import TEMP_FAHRENHEIT import logging @@ -48,9 +48,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if discovery_info is None: return dev = list() - while NETWORK is None: - continue - for name, data in NETWORK.ecobee.sensors.items(): + for name, data in ecobee.NETWORK.ecobee.sensors.items(): if 'temp' in data: dev.append(EcobeeSensor(name, 'temperature')) if 'humidity' in data: @@ -86,8 +84,8 @@ class EcobeeSensor(Entity): return self._unit_of_measurement def update(self): - NETWORK.update() - data = NETWORK.ecobee.sensors[self.sensor_name] + ecobee.NETWORK.update() + data = ecobee.NETWORK.ecobee.sensors[self.sensor_name] if self.type == 'temperature': self._state = data['temp'] elif self.type == 'humidity': diff --git a/homeassistant/components/thermostat/ecobee.py b/homeassistant/components/thermostat/ecobee.py index 51d21cb9991..78f4d555c9c 100644 --- a/homeassistant/components/thermostat/ecobee.py +++ b/homeassistant/components/thermostat/ecobee.py @@ -28,7 +28,7 @@ ecobee: from homeassistant.components.thermostat import (ThermostatDevice, STATE_COOL, STATE_IDLE, STATE_HEAT) from homeassistant.const import (TEMP_FAHRENHEIT, STATE_ON, STATE_OFF) -from homeassistant.components.ecobee import NETWORK +from homeassistant.components import ecobee import logging DEPENDENCIES = ['ecobee'] @@ -43,7 +43,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): """ Setup Platform """ if discovery_info is None: return - data = NETWORK + data = ecobee.NETWORK hold_temp = discovery_info['hold_temp'] _LOGGER.info("Loading ecobee thermostat component with hold_temp set to " + str(hold_temp)) From 08ba71a35931f4f37ae3a094dcf3623c65c5b9da Mon Sep 17 00:00:00 2001 From: sfam Date: Wed, 25 Nov 2015 18:13:39 +0000 Subject: [PATCH 18/49] rename component to motor and services to open/close/stop --- homeassistant/components/motor/__init__.py | 130 +++++++++++++++++ .../{rollershutter => motor}/mqtt.py | 52 +++---- .../{rollershutter => motor}/services.yaml | 0 .../components/rollershutter/__init__.py | 131 ------------------ .../{rollershutter => motor}/__init__.py | 0 .../{rollershutter => motor}/test_mqtt.py | 56 ++++---- 6 files changed, 184 insertions(+), 185 deletions(-) create mode 100644 homeassistant/components/motor/__init__.py rename homeassistant/components/{rollershutter => motor}/mqtt.py (71%) rename homeassistant/components/{rollershutter => motor}/services.yaml (100%) delete mode 100644 homeassistant/components/rollershutter/__init__.py rename tests/components/{rollershutter => motor}/__init__.py (100%) rename tests/components/{rollershutter => motor}/test_mqtt.py (67%) diff --git a/homeassistant/components/motor/__init__.py b/homeassistant/components/motor/__init__.py new file mode 100644 index 00000000000..feea836a0dd --- /dev/null +++ b/homeassistant/components/motor/__init__.py @@ -0,0 +1,130 @@ +""" +homeassistant.components.motor +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Motor component. + +""" +import os +import logging + +from homeassistant.config import load_yaml_config_file +from homeassistant.helpers.entity_component import EntityComponent +from homeassistant.helpers.entity import Entity +from homeassistant.components import group +from homeassistant.const import ( + SERVICE_OPEN, SERVICE_CLOSE, SERVICE_STOP, + STATE_OPEN, STATE_CLOSED, STATE_UNKNOWN, ATTR_ENTITY_ID) + + +DOMAIN = 'motor' +DEPENDENCIES = [] +SCAN_INTERVAL = 15 + +GROUP_NAME_ALL_MOTORS = 'all motors' +ENTITY_ID_ALL_MOTORS = group.ENTITY_ID_FORMAT.format('all_motors') + +ENTITY_ID_FORMAT = DOMAIN + '.{}' + +# Maps discovered services to their platforms +DISCOVERY_PLATFORMS = {} + +_LOGGER = logging.getLogger(__name__) + + +def is_open(hass, entity_id=None): + """ Returns if the motor is open based on the statemachine. """ + entity_id = entity_id or ENTITY_ID_ALL_MOTORS + return hass.states.is_state(entity_id, STATE_OPEN) + + +def call_open(hass, entity_id=None): + """ Open all or specified motor. """ + data = {ATTR_ENTITY_ID: entity_id} if entity_id else None + hass.services.call(DOMAIN, SERVICE_OPEN, data) + + +def call_close(hass, entity_id=None): + """ Close all or specified motor. """ + data = {ATTR_ENTITY_ID: entity_id} if entity_id else None + hass.services.call(DOMAIN, SERVICE_CLOSE, data) + + +def call_stop(hass, entity_id=None): + """ Stops all or specified motor. """ + data = {ATTR_ENTITY_ID: entity_id} if entity_id else None + hass.services.call(DOMAIN, SERVICE_STOP, data) + + +def setup(hass, config): + """ Track states and offer events for motors. """ + component = EntityComponent( + _LOGGER, DOMAIN, hass, SCAN_INTERVAL, DISCOVERY_PLATFORMS, + GROUP_NAME_ALL_MOTORS) + component.setup(config) + + def handle_motor_service(service): + """ Handles calls to the motor services. """ + target_motors = component.extract_from_service(service) + + for motor in target_motors: + if service.service == SERVICE_OPEN: + motor.open() + elif service.service == SERVICE_CLOSE: + motor.close() + elif service.service == SERVICE_STOP: + motor.stop() + + if motor.should_poll: + motor.update_ha_state(True) + + descriptions = load_yaml_config_file( + os.path.join(os.path.dirname(__file__), 'services.yaml')) + + hass.services.register(DOMAIN, SERVICE_OPEN, + handle_motor_service, + descriptions.get(SERVICE_OPEN)) + hass.services.register(DOMAIN, SERVICE_CLOSE, + handle_motor_service, + descriptions.get(SERVICE_CLOSE)) + hass.services.register(DOMAIN, SERVICE_STOP, + handle_motor_service, + descriptions.get(SERVICE_STOP)) + + return True + + +class MotorDevice(Entity): + """ Represents a motor within Home Assistant. """ + # pylint: disable=no-self-use + + @property + def current_position(self): + """ Return current position of motor. + None is unknown, 0 is closed, 100 is fully open. """ + raise NotImplementedError() + + @property + def state(self): + current = self.current_position + + if current is None: + return STATE_UNKNOWN + + return STATE_CLOSED if current == 0 else STATE_OPEN + + @property + def state_attributes(self): + """ Returns optional state attributes. """ + return None + + def open(self, **kwargs): + """ Open the device. """ + raise NotImplementedError() + + def close(self, **kwargs): + """ Close the device. """ + raise NotImplementedError() + + def stop(self, **kwargs): + """ Stop the device. """ + raise NotImplementedError() diff --git a/homeassistant/components/rollershutter/mqtt.py b/homeassistant/components/motor/mqtt.py similarity index 71% rename from homeassistant/components/rollershutter/mqtt.py rename to homeassistant/components/motor/mqtt.py index 6128a4d9819..48a20d5a3b6 100644 --- a/homeassistant/components/rollershutter/mqtt.py +++ b/homeassistant/components/motor/mqtt.py @@ -1,21 +1,21 @@ """ -homeassistant.components.rollershutter.mqtt +homeassistant.components.motor.mqtt ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Allows to configure a MQTT rollershutter. +Allows to configure a MQTT motor. For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/rollershutter.mqtt/ +https://home-assistant.io/components/motor.mqtt/ """ import logging import homeassistant.components.mqtt as mqtt -from homeassistant.components.rollershutter import RollershutterDevice +from homeassistant.components.motor import MotorDevice _LOGGER = logging.getLogger(__name__) DEPENDENCIES = ['mqtt'] -DEFAULT_NAME = "MQTT Shutter" +DEFAULT_NAME = "MQTT Motor" DEFAULT_QOS = 0 -DEFAULT_PAYLOAD_UP = "UP" -DEFAULT_PAYLOAD_DOWN = "DOWN" +DEFAULT_PAYLOAD_OPEN = "OPEN" +DEFAULT_PAYLOAD_CLOSE = "CLOSE" DEFAULT_PAYLOAD_STOP = "STOP" ATTR_CURRENT_POSITION = 'current_position' @@ -23,37 +23,37 @@ ATTR_CURRENT_POSITION = 'current_position' # pylint: disable=unused-argument def setup_platform(hass, config, add_devices_callback, discovery_info=None): - """ Add MQTT Roller Shutter """ + """ Add MQTT Motor """ if config.get('command_topic') is None: _LOGGER.error("Missing required variable: command_topic") return False - add_devices_callback([MqttRollershutter( + add_devices_callback([MqttMotor( hass, config.get('name', DEFAULT_NAME), config.get('state_topic'), config.get('command_topic'), config.get('qos', DEFAULT_QOS), - config.get('payload_up', DEFAULT_PAYLOAD_UP), - config.get('payload_down', DEFAULT_PAYLOAD_DOWN), + config.get('payload_open', DEFAULT_PAYLOAD_OPEN), + config.get('payload_close', DEFAULT_PAYLOAD_CLOSE), config.get('payload_stop', DEFAULT_PAYLOAD_STOP), config.get('state_format'))]) # pylint: disable=too-many-arguments, too-many-instance-attributes -class MqttRollershutter(RollershutterDevice): - """ Represents a rollershutter that can be togggled using MQTT """ +class MqttMotor(MotorDevice): + """ Represents a motor that can be controlled using MQTT """ def __init__(self, hass, name, state_topic, command_topic, qos, - payload_up, payload_down, payload_stop, state_format): + payload_open, payload_close, payload_stop, state_format): self._state = None self._hass = hass self._name = name self._state_topic = state_topic self._command_topic = command_topic self._qos = qos - self._payload_up = payload_up - self._payload_down = payload_down + self._payload_open = payload_open + self._payload_close = payload_close self._payload_stop = payload_stop self._parse = mqtt.FmtParser(state_format) @@ -79,12 +79,12 @@ class MqttRollershutter(RollershutterDevice): @property def name(self): - """ The name of the rollershutter """ + """ The name of the motor """ return self._name @property def current_position(self): - """ Return current position of rollershutter. + """ Return current position of motor. None is unknown, 0 is closed, 100 is fully open. """ return self._state @@ -93,18 +93,18 @@ class MqttRollershutter(RollershutterDevice): """ True if device is open. """ return self._state > 0 - def move_up(self, **kwargs): - """ Moves the device UP. """ - mqtt.publish(self.hass, self._command_topic, self._payload_up, + def open(self, **kwargs): + """ Close the device. """ + mqtt.publish(self.hass, self._command_topic, self._payload_open, self._qos) - def move_down(self, **kwargs): - """ Moves the device DOWN. """ - mqtt.publish(self.hass, self._command_topic, self._payload_down, + def close(self, **kwargs): + """ Open the device. """ + mqtt.publish(self.hass, self._command_topic, self._payload_close, self._qos) - def move_stop(self, **kwargs): - """ Moves the device to STOP. """ + def stop(self, **kwargs): + """ Stop the device. """ mqtt.publish(self.hass, self._command_topic, self._payload_stop, self._qos) diff --git a/homeassistant/components/rollershutter/services.yaml b/homeassistant/components/motor/services.yaml similarity index 100% rename from homeassistant/components/rollershutter/services.yaml rename to homeassistant/components/motor/services.yaml diff --git a/homeassistant/components/rollershutter/__init__.py b/homeassistant/components/rollershutter/__init__.py deleted file mode 100644 index 5ebcf8a3d21..00000000000 --- a/homeassistant/components/rollershutter/__init__.py +++ /dev/null @@ -1,131 +0,0 @@ -""" -homeassistant.components.rollershutter -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Rollershutter component. - -""" -import os -import logging - -from homeassistant.config import load_yaml_config_file -from homeassistant.helpers.entity_component import EntityComponent -from homeassistant.helpers.entity import Entity -from homeassistant.components import group -from homeassistant.const import ( - SERVICE_MOVE_UP, SERVICE_MOVE_DOWN, SERVICE_MOVE_STOP, - STATE_OPEN, STATE_CLOSED, STATE_UNKNOWN, ATTR_ENTITY_ID) - - -DOMAIN = 'rollershutter' -DEPENDENCIES = [] -SCAN_INTERVAL = 15 - -GROUP_NAME_ALL_ROLLERSHUTTERS = 'all rollershutters' -ENTITY_ID_ALL_ROLLERSHUTTERS = group.ENTITY_ID_FORMAT.format( - 'all_rollershutters') - -ENTITY_ID_FORMAT = DOMAIN + '.{}' - -# Maps discovered services to their platforms -DISCOVERY_PLATFORMS = {} - -_LOGGER = logging.getLogger(__name__) - - -def is_open(hass, entity_id=None): - """ Returns if the rollershutter is open based on the statemachine. """ - entity_id = entity_id or ENTITY_ID_ALL_ROLLERSHUTTERS - return hass.states.is_state(entity_id, STATE_OPEN) - - -def move_up(hass, entity_id=None): - """ Moves all or specified rollershutter up. """ - data = {ATTR_ENTITY_ID: entity_id} if entity_id else None - hass.services.call(DOMAIN, SERVICE_MOVE_UP, data) - - -def move_down(hass, entity_id=None): - """ Moves all or specified rollershutter down. """ - data = {ATTR_ENTITY_ID: entity_id} if entity_id else None - hass.services.call(DOMAIN, SERVICE_MOVE_DOWN, data) - - -def move_stop(hass, entity_id=None): - """ Stops all or specified rollershutter. """ - data = {ATTR_ENTITY_ID: entity_id} if entity_id else None - hass.services.call(DOMAIN, SERVICE_MOVE_STOP, data) - - -def setup(hass, config): - """ Track states and offer events for rollershutters. """ - component = EntityComponent( - _LOGGER, DOMAIN, hass, SCAN_INTERVAL, DISCOVERY_PLATFORMS, - GROUP_NAME_ALL_ROLLERSHUTTERS) - component.setup(config) - - def handle_rollershutter_service(service): - """ Handles calls to the rollershutter services. """ - target_rollershutters = component.extract_from_service(service) - - for rollershutter in target_rollershutters: - if service.service == SERVICE_MOVE_UP: - rollershutter.move_up() - elif service.service == SERVICE_MOVE_DOWN: - rollershutter.move_down() - elif service.service == SERVICE_MOVE_STOP: - rollershutter.move_stop() - - if rollershutter.should_poll: - rollershutter.update_ha_state(True) - - descriptions = load_yaml_config_file( - os.path.join(os.path.dirname(__file__), 'services.yaml')) - - hass.services.register(DOMAIN, SERVICE_MOVE_UP, - handle_rollershutter_service, - descriptions.get(SERVICE_MOVE_UP)) - hass.services.register(DOMAIN, SERVICE_MOVE_DOWN, - handle_rollershutter_service, - descriptions.get(SERVICE_MOVE_DOWN)) - hass.services.register(DOMAIN, SERVICE_MOVE_STOP, - handle_rollershutter_service, - descriptions.get(SERVICE_MOVE_STOP)) - - return True - - -class RollershutterDevice(Entity): - """ Represents a rollershutter within Home Assistant. """ - # pylint: disable=no-self-use - - @property - def current_position(self): - """ Return current position of rollershutter. - None is unknown, 0 is closed, 100 is fully open. """ - raise NotImplementedError() - - @property - def state(self): - current = self.current_position - - if current is None: - return STATE_UNKNOWN - - return STATE_CLOSED if current == 0 else STATE_OPEN - - @property - def state_attributes(self): - """ Returns optional state attributes. """ - return None - - def move_up(self, **kwargs): - """ Moves the device UP. """ - raise NotImplementedError() - - def move_down(self, **kwargs): - """ Moves the device DOWN. """ - raise NotImplementedError() - - def move_stop(self, **kwargs): - """ Moves the device to STOP. """ - raise NotImplementedError() diff --git a/tests/components/rollershutter/__init__.py b/tests/components/motor/__init__.py similarity index 100% rename from tests/components/rollershutter/__init__.py rename to tests/components/motor/__init__.py diff --git a/tests/components/rollershutter/test_mqtt.py b/tests/components/motor/test_mqtt.py similarity index 67% rename from tests/components/rollershutter/test_mqtt.py rename to tests/components/motor/test_mqtt.py index 2a71163c50f..4d7af04ae6c 100644 --- a/tests/components/rollershutter/test_mqtt.py +++ b/tests/components/motor/test_mqtt.py @@ -1,19 +1,19 @@ """ -tests.components.rollershutter.test_mqtt +tests.components.motor.test_mqtt ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Tests mqtt rollershutter. +Tests mqtt motor. """ import unittest from homeassistant.const import STATE_OPEN, STATE_CLOSED, STATE_UNKNOWN import homeassistant.core as ha -import homeassistant.components.rollershutter as rollershutter +import homeassistant.components.motor as motor from tests.common import mock_mqtt_component, fire_mqtt_message -class TestRollershutterMQTT(unittest.TestCase): - """ Test the MQTT rollershutter. """ +class TestMotorMQTT(unittest.TestCase): + """ Test the MQTT motor. """ def setUp(self): # pylint: disable=invalid-name self.hass = ha.HomeAssistant() @@ -24,43 +24,43 @@ class TestRollershutterMQTT(unittest.TestCase): self.hass.stop() def test_controlling_state_via_topic(self): - self.assertTrue(rollershutter.setup(self.hass, { - 'rollershutter': { + self.assertTrue(motor.setup(self.hass, { + 'motor': { 'platform': 'mqtt', 'name': 'test', 'state_topic': 'state-topic', 'command_topic': 'command-topic', 'qos': 0, - 'payload_up': 'UP', - 'payload_down': 'DOWN', + 'payload_open': 'OPEN', + 'payload_close': 'CLOSE', 'payload_stop': 'STOP' } })) - state = self.hass.states.get('rollershutter.test') + state = self.hass.states.get('motor.test') self.assertEqual(STATE_UNKNOWN, state.state) fire_mqtt_message(self.hass, 'state-topic', '0') self.hass.pool.block_till_done() - state = self.hass.states.get('rollershutter.test') + state = self.hass.states.get('motor.test') self.assertEqual(STATE_CLOSED, state.state) fire_mqtt_message(self.hass, 'state-topic', '50') self.hass.pool.block_till_done() - state = self.hass.states.get('rollershutter.test') + state = self.hass.states.get('motor.test') self.assertEqual(STATE_OPEN, state.state) fire_mqtt_message(self.hass, 'state-topic', '100') self.hass.pool.block_till_done() - state = self.hass.states.get('rollershutter.test') + state = self.hass.states.get('motor.test') self.assertEqual(STATE_OPEN, state.state) def test_sending_mqtt_commands(self): - self.assertTrue(rollershutter.setup(self.hass, { - 'rollershutter': { + self.assertTrue(motor.setup(self.hass, { + 'motor': { 'platform': 'mqtt', 'name': 'test', 'state_topic': 'state-topic', @@ -69,54 +69,54 @@ class TestRollershutterMQTT(unittest.TestCase): } })) - state = self.hass.states.get('rollershutter.test') + state = self.hass.states.get('motor.test') self.assertEqual(STATE_UNKNOWN, state.state) - rollershutter.move_up(self.hass, 'rollershutter.test') + motor.call_open(self.hass, 'motor.test') self.hass.pool.block_till_done() - self.assertEqual(('command-topic', 'UP', 2), + self.assertEqual(('command-topic', 'OPEN', 2), self.mock_publish.mock_calls[-1][1]) - state = self.hass.states.get('rollershutter.test') + state = self.hass.states.get('motor.test') self.assertEqual(STATE_UNKNOWN, state.state) def test_state_attributes_current_position(self): - self.assertTrue(rollershutter.setup(self.hass, { - 'rollershutter': { + self.assertTrue(motor.setup(self.hass, { + 'motor': { 'platform': 'mqtt', 'name': 'test', 'state_topic': 'state-topic', 'command_topic': 'command-topic', - 'payload_up': 'UP', - 'payload_down': 'DOWN', + 'payload_open': 'OPEN', + 'payload_close': 'CLOSE', 'payload_stop': 'STOP' } })) state_attributes_dict = self.hass.states.get( - 'rollershutter.test').attributes + 'motor.test').attributes self.assertFalse('current_position' in state_attributes_dict) fire_mqtt_message(self.hass, 'state-topic', '0') self.hass.pool.block_till_done() current_position = self.hass.states.get( - 'rollershutter.test').attributes['current_position'] + 'motor.test').attributes['current_position'] self.assertEqual(0, current_position) fire_mqtt_message(self.hass, 'state-topic', '50') self.hass.pool.block_till_done() current_position = self.hass.states.get( - 'rollershutter.test').attributes['current_position'] + 'motor.test').attributes['current_position'] self.assertEqual(50, current_position) fire_mqtt_message(self.hass, 'state-topic', '101') self.hass.pool.block_till_done() current_position = self.hass.states.get( - 'rollershutter.test').attributes['current_position'] + 'motor.test').attributes['current_position'] self.assertEqual(50, current_position) fire_mqtt_message(self.hass, 'state-topic', 'non-numeric') self.hass.pool.block_till_done() current_position = self.hass.states.get( - 'rollershutter.test').attributes['current_position'] + 'motor.test').attributes['current_position'] self.assertEqual(50, current_position) From 0dbf4b3c10e92ec207c3e5288646186b12196b90 Mon Sep 17 00:00:00 2001 From: sfam Date: Wed, 25 Nov 2015 18:20:16 +0000 Subject: [PATCH 19/49] add const.py changes to commit --- homeassistant/const.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index add1848b72c..1513c188cc2 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -143,9 +143,9 @@ SERVICE_ALARM_TRIGGER = "alarm_trigger" SERVICE_LOCK = "lock" SERVICE_UNLOCK = "unlock" -SERVICE_MOVE_UP = 'move_up' -SERVICE_MOVE_DOWN = 'move_down' -SERVICE_MOVE_STOP = 'move_stop' +SERVICE_OPEN = 'open' +SERVICE_CLOSE = 'close' +SERVICE_STOP = 'stop' # #### API / REMOTE #### SERVER_PORT = 8123 From 4f75286f64dde2cbfa429eb19167169f88c2baa1 Mon Sep 17 00:00:00 2001 From: sfam Date: Thu, 26 Nov 2015 09:38:25 +0000 Subject: [PATCH 20/49] fix some comments --- homeassistant/components/motor/mqtt.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/motor/mqtt.py b/homeassistant/components/motor/mqtt.py index 48a20d5a3b6..2aac5e37c16 100644 --- a/homeassistant/components/motor/mqtt.py +++ b/homeassistant/components/motor/mqtt.py @@ -90,16 +90,16 @@ class MqttMotor(MotorDevice): @property def is_open(self): - """ True if device is open. """ + """ True if device is current position is not zero. """ return self._state > 0 def open(self, **kwargs): - """ Close the device. """ + """ Open the device. """ mqtt.publish(self.hass, self._command_topic, self._payload_open, self._qos) def close(self, **kwargs): - """ Open the device. """ + """ Close the device. """ mqtt.publish(self.hass, self._command_topic, self._payload_close, self._qos) From 067011af1563ee67441292c496ed7feee39e136b Mon Sep 17 00:00:00 2001 From: Pascal Bach Date: Thu, 26 Nov 2015 20:45:07 +0100 Subject: [PATCH 21/49] function support for aREST backend The implementation sends /?params=1 for turn_on and /?params=0 for turn_off It uses the return value of the function to determine the current state. 0=Off, 1=On --- homeassistant/components/switch/arest.py | 95 ++++++++++++++++++++---- 1 file changed, 82 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/switch/arest.py b/homeassistant/components/switch/arest.py index 92bd70cb734..c42295660d4 100644 --- a/homeassistant/components/switch/arest.py +++ b/homeassistant/components/switch/arest.py @@ -34,30 +34,33 @@ def setup_platform(hass, config, add_devices, discovery_info=None): return False dev = [] - pins = config.get('pins') + pins = config.get('pins', {}) for pinnum, pin in pins.items(): - dev.append(ArestSwitch(resource, - config.get('name', response.json()['name']), - pin.get('name'), - pinnum)) + dev.append(ArestSwitchPin(resource, + config.get('name', response.json()['name']), + pin.get('name'), + pinnum)) + + functions = config.get('functions', {}) + for funcname, func in functions.items(): + dev.append(ArestSwitchFunction(resource, + config.get('name', + response.json()['name']), + func.get('name'), + funcname)) + add_devices(dev) -class ArestSwitch(SwitchDevice): +class ArestSwitchBase(SwitchDevice): """ Implements an aREST switch. """ - def __init__(self, resource, location, name, pin): + def __init__(self, resource, location, name): self._resource = resource self._name = '{} {}'.format(location.title(), name.title()) \ or DEVICE_DEFAULT_NAME - self._pin = pin self._state = None - request = requests.get('{}/mode/{}/o'.format(self._resource, - self._pin), timeout=10) - if request.status_code is not 200: - _LOGGER.error("Can't set mode. Is device offline?") - @property def name(self): """ The name of the switch. """ @@ -68,6 +71,72 @@ class ArestSwitch(SwitchDevice): """ True if device is on. """ return self._state + +class ArestSwitchFunction(ArestSwitchBase): + """ Implements an aREST switch. Based on functions. """ + + def __init__(self, resource, location, name, func): + super().__init__(resource, location, name) + self._func = func + + request = requests.get('{}/{}'.format(self._resource, self._func), + timeout=10) + + if request.status_code is not 200: + _LOGGER.error("Can't find function. Is device offline?") + return + + try: + request.json()['return_value'] + except KeyError: + _LOGGER.error("No return_value received. " + "Is the function name correct.") + except ValueError: + _LOGGER.error("Response invalid. Is the function name correct.") + + def turn_on(self, **kwargs): + """ Turn the device on. """ + request = requests.get('{}/{}'.format(self._resource, self._func), + timeout=10, params={"params": "1"}) + + if request.status_code == 200: + self._state = True + else: + _LOGGER.error("Can't turn on function %s at %s. " + "Is device offline?", + self._func, self._resource) + + def turn_off(self, **kwargs): + """ Turn the device off. """ + request = requests.get('{}/{}'.format(self._resource, self._func), + timeout=10, params={"params": "0"}) + + if request.status_code == 200: + self._state = False + else: + _LOGGER.error("Can't turn off function %s at %s. " + "Is device offline?", + self._func, self._resource) + + def update(self): + """ Gets the latest data from aREST API and updates the state. """ + request = requests.get('{}/{}'.format(self._resource, + self._func), timeout=10) + self._state = request.json()['return_value'] != 0 + + +class ArestSwitchPin(ArestSwitchBase): + """ Implements an aREST switch. Based on digital I/O """ + + def __init__(self, resource, location, name, pin): + super().__init__(resource, location, name) + self._pin = pin + + request = requests.get('{}/mode/{}/o'.format(self._resource, + self._pin), timeout=10) + if request.status_code is not 200: + _LOGGER.error("Can't set mode. Is device offline?") + def turn_on(self, **kwargs): """ Turn the device on. """ request = requests.get('{}/digital/{}/1'.format(self._resource, From 69e9d39690e4ba6c35f8d905040ec0194b0fb22c Mon Sep 17 00:00:00 2001 From: Pascal Bach Date: Tue, 24 Nov 2015 21:30:06 +0100 Subject: [PATCH 22/49] Allow setting the retain flag for mqtt switch. Some devices can read the initial value on startup. If the retain flag is set they always receive the value as last set by home assistant. --- homeassistant/components/mqtt/__init__.py | 15 +++++++++++---- homeassistant/components/switch/mqtt.py | 9 ++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index b8dc8909887..65db49f8636 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -28,6 +28,7 @@ MQTT_CLIENT = None DEFAULT_PORT = 1883 DEFAULT_KEEPALIVE = 60 DEFAULT_QOS = 0 +DEFAULT_RETAIN = False SERVICE_PUBLISH = 'publish' EVENT_MQTT_MESSAGE_RECEIVED = 'MQTT_MESSAGE_RECEIVED' @@ -46,11 +47,12 @@ CONF_CERTIFICATE = 'certificate' ATTR_TOPIC = 'topic' ATTR_PAYLOAD = 'payload' ATTR_QOS = 'qos' +ATTR_RETAIN = 'retain' MAX_RECONNECT_WAIT = 300 # seconds -def publish(hass, topic, payload, qos=None): +def publish(hass, topic, payload, qos=None, retain=None): """ Send an MQTT message. """ data = { ATTR_TOPIC: topic, @@ -58,6 +60,10 @@ def publish(hass, topic, payload, qos=None): } if qos is not None: data[ATTR_QOS] = qos + + if retain is not None: + data[ATTR_RETAIN] = retain + hass.services.call(DOMAIN, SERVICE_PUBLISH, data) @@ -119,9 +125,10 @@ def setup(hass, config): msg_topic = call.data.get(ATTR_TOPIC) payload = call.data.get(ATTR_PAYLOAD) qos = call.data.get(ATTR_QOS, DEFAULT_QOS) + retain = call.data.get(ATTR_RETAIN, DEFAULT_RETAIN) if msg_topic is None or payload is None: return - MQTT_CLIENT.publish(msg_topic, payload, qos) + MQTT_CLIENT.publish(msg_topic, payload, qos, retain) hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_mqtt) @@ -190,9 +197,9 @@ class MQTT(object): self._mqttc.connect(broker, port, keepalive) - def publish(self, topic, payload, qos): + def publish(self, topic, payload, qos, retain): """ Publish a MQTT message. """ - self._mqttc.publish(topic, payload, qos) + self._mqttc.publish(topic, payload, qos, retain) def start(self): """ Run the MQTT client. """ diff --git a/homeassistant/components/switch/mqtt.py b/homeassistant/components/switch/mqtt.py index 43bceab69a5..7b973799eed 100644 --- a/homeassistant/components/switch/mqtt.py +++ b/homeassistant/components/switch/mqtt.py @@ -17,6 +17,7 @@ DEFAULT_QOS = 0 DEFAULT_PAYLOAD_ON = "ON" DEFAULT_PAYLOAD_OFF = "OFF" DEFAULT_OPTIMISTIC = False +DEFAULT_RETAIN = False DEPENDENCIES = ['mqtt'] @@ -35,6 +36,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): config.get('state_topic'), config.get('command_topic'), config.get('qos', DEFAULT_QOS), + config.get('retain', DEFAULT_RETAIN), config.get('payload_on', DEFAULT_PAYLOAD_ON), config.get('payload_off', DEFAULT_PAYLOAD_OFF), config.get('optimistic', DEFAULT_OPTIMISTIC), @@ -44,7 +46,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): # pylint: disable=too-many-arguments, too-many-instance-attributes class MqttSwitch(SwitchDevice): """ Represents a switch that can be toggled using MQTT. """ - def __init__(self, hass, name, state_topic, command_topic, qos, + def __init__(self, hass, name, state_topic, command_topic, qos, retain, payload_on, payload_off, optimistic, state_format): self._state = False self._hass = hass @@ -52,6 +54,7 @@ class MqttSwitch(SwitchDevice): self._state_topic = state_topic self._command_topic = command_topic self._qos = qos + self._retain = retain self._payload_on = payload_on self._payload_off = payload_off self._optimistic = optimistic @@ -93,7 +96,7 @@ class MqttSwitch(SwitchDevice): def turn_on(self, **kwargs): """ Turn the device on. """ mqtt.publish(self.hass, self._command_topic, self._payload_on, - self._qos) + self._qos, self._retain) if self._optimistic: # optimistically assume that switch has changed state self._state = True @@ -102,7 +105,7 @@ class MqttSwitch(SwitchDevice): def turn_off(self, **kwargs): """ Turn the device off. """ mqtt.publish(self.hass, self._command_topic, self._payload_off, - self._qos) + self._qos, self._retain) if self._optimistic: # optimistically assume that switch has changed state self._state = False From 341c3a8fcda4c514edd3ae5b3de0b0d17270109e Mon Sep 17 00:00:00 2001 From: Pascal Bach Date: Thu, 26 Nov 2015 20:55:26 +0100 Subject: [PATCH 23/49] Fix tests for mqtt publish with retain. --- tests/components/alarm_control_panel/test_mqtt.py | 6 +++--- tests/components/light/test_mqtt.py | 4 ++-- tests/components/switch/test_mqtt.py | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/components/alarm_control_panel/test_mqtt.py b/tests/components/alarm_control_panel/test_mqtt.py index 6cba26c15a6..58c55350cd2 100644 --- a/tests/components/alarm_control_panel/test_mqtt.py +++ b/tests/components/alarm_control_panel/test_mqtt.py @@ -101,7 +101,7 @@ class TestAlarmControlPanelMQTT(unittest.TestCase): alarm_control_panel.alarm_arm_home(self.hass) self.hass.pool.block_till_done() - self.assertEqual(('alarm/command', 'ARM_HOME', 0), + self.assertEqual(('alarm/command', 'ARM_HOME', 0, False), self.mock_publish.mock_calls[-1][1]) def test_arm_home_not_publishes_mqtt_with_invalid_code(self): @@ -130,7 +130,7 @@ class TestAlarmControlPanelMQTT(unittest.TestCase): alarm_control_panel.alarm_arm_away(self.hass) self.hass.pool.block_till_done() - self.assertEqual(('alarm/command', 'ARM_AWAY', 0), + self.assertEqual(('alarm/command', 'ARM_AWAY', 0, False), self.mock_publish.mock_calls[-1][1]) def test_arm_away_not_publishes_mqtt_with_invalid_code(self): @@ -159,7 +159,7 @@ class TestAlarmControlPanelMQTT(unittest.TestCase): alarm_control_panel.alarm_disarm(self.hass) self.hass.pool.block_till_done() - self.assertEqual(('alarm/command', 'DISARM', 0), + self.assertEqual(('alarm/command', 'DISARM', 0, False), self.mock_publish.mock_calls[-1][1]) def test_disarm_not_publishes_mqtt_with_invalid_code(self): diff --git a/tests/components/light/test_mqtt.py b/tests/components/light/test_mqtt.py index 39c81ee0a04..fdebb0c1ef5 100644 --- a/tests/components/light/test_mqtt.py +++ b/tests/components/light/test_mqtt.py @@ -139,7 +139,7 @@ class TestLightMQTT(unittest.TestCase): light.turn_on(self.hass, 'light.test') self.hass.pool.block_till_done() - self.assertEqual(('test_light_rgb/set', 'on', 2), + self.assertEqual(('test_light_rgb/set', 'on', 2, False), self.mock_publish.mock_calls[-1][1]) state = self.hass.states.get('light.test') self.assertEqual(STATE_ON, state.state) @@ -147,7 +147,7 @@ class TestLightMQTT(unittest.TestCase): light.turn_off(self.hass, 'light.test') self.hass.pool.block_till_done() - self.assertEqual(('test_light_rgb/set', 'off', 2), + self.assertEqual(('test_light_rgb/set', 'off', 2, False), self.mock_publish.mock_calls[-1][1]) state = self.hass.states.get('light.test') self.assertEqual(STATE_OFF, state.state) diff --git a/tests/components/switch/test_mqtt.py b/tests/components/switch/test_mqtt.py index 4754e64e575..2cfe29c2910 100644 --- a/tests/components/switch/test_mqtt.py +++ b/tests/components/switch/test_mqtt.py @@ -68,7 +68,7 @@ class TestSensorMQTT(unittest.TestCase): switch.turn_on(self.hass, 'switch.test') self.hass.pool.block_till_done() - self.assertEqual(('command-topic', 'beer on', 2), + self.assertEqual(('command-topic', 'beer on', 2, False), self.mock_publish.mock_calls[-1][1]) state = self.hass.states.get('switch.test') self.assertEqual(STATE_ON, state.state) @@ -76,7 +76,7 @@ class TestSensorMQTT(unittest.TestCase): switch.turn_off(self.hass, 'switch.test') self.hass.pool.block_till_done() - self.assertEqual(('command-topic', 'beer off', 2), + self.assertEqual(('command-topic', 'beer off', 2, False), self.mock_publish.mock_calls[-1][1]) state = self.hass.states.get('switch.test') self.assertEqual(STATE_OFF, state.state) From 2861bbb02c1c06b80473176edb7f6e85a5473806 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 26 Nov 2015 13:08:13 -0800 Subject: [PATCH 24/49] Warn if config invalid shape for script --- homeassistant/components/script.py | 5 +++-- tests/components/test_script.py | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/homeassistant/components/script.py b/homeassistant/components/script.py index 2b18a5143fd..f8240bbf7f5 100644 --- a/homeassistant/components/script.py +++ b/homeassistant/components/script.py @@ -76,8 +76,9 @@ def setup(hass, config): _LOGGER.warn("Found invalid key for script: %s. Use %s instead.", object_id, slugify(object_id)) continue - if not cfg.get(CONF_SEQUENCE): - _LOGGER.warn("Missing key 'sequence' for script %s", object_id) + if not isinstance(cfg.get(CONF_SEQUENCE), list): + _LOGGER.warn("Key 'sequence' for script %s should be a list", + object_id) continue alias = cfg.get(CONF_ALIAS, object_id) script = Script(hass, object_id, alias, cfg[CONF_SEQUENCE]) diff --git a/tests/components/test_script.py b/tests/components/test_script.py index 50cfba55ec5..30b7e4e3c8f 100644 --- a/tests/components/test_script.py +++ b/tests/components/test_script.py @@ -27,23 +27,10 @@ class TestScript(unittest.TestCase): """ Stop down stuff we started. """ self.hass.stop() - def test_setup_with_empty_sequence(self): - self.assertTrue(script.setup(self.hass, { - 'script': { - 'test': { - 'sequence': [] - } - } - })) - - self.assertIsNone(self.hass.states.get(ENTITY_ID)) - def test_setup_with_missing_sequence(self): self.assertTrue(script.setup(self.hass, { 'script': { - 'test': { - 'sequence': [] - } + 'test': {} } })) @@ -60,6 +47,19 @@ class TestScript(unittest.TestCase): self.assertEqual(0, len(self.hass.states.entity_ids('script'))) + def test_setup_with_dict_as_sequence(self): + self.assertTrue(script.setup(self.hass, { + 'script': { + 'test': { + 'sequence': { + 'event': 'test_event' + } + } + } + })) + + self.assertEqual(0, len(self.hass.states.entity_ids('script'))) + def test_firing_event(self): event = 'test_event' calls = [] From fabd0ced3fe96839b93a9f790fb498a69c996222 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 26 Nov 2015 13:11:59 -0800 Subject: [PATCH 25/49] Make DEPENDENCIES optional for components --- homeassistant/bootstrap.py | 19 +++++++++---------- .../alarm_control_panel/__init__.py | 1 - .../components/alarm_control_panel/manual.py | 2 -- homeassistant/components/arduino.py | 1 - .../components/binary_sensor/__init__.py | 1 - homeassistant/components/browser.py | 1 - homeassistant/components/configurator.py | 1 - homeassistant/components/conversation.py | 1 - homeassistant/components/discovery.py | 1 - homeassistant/components/downloader.py | 1 - homeassistant/components/group.py | 1 - homeassistant/components/http.py | 1 - homeassistant/components/ifttt.py | 2 -- homeassistant/components/introduction.py | 1 - homeassistant/components/isy994.py | 1 - homeassistant/components/keyboard.py | 1 - homeassistant/components/light/__init__.py | 1 - .../components/light/blinksticklight.py | 1 - homeassistant/components/lock/__init__.py | 1 - homeassistant/components/logger.py | 1 - .../components/media_player/__init__.py | 1 - homeassistant/components/modbus.py | 1 - homeassistant/components/mqtt/__init__.py | 1 - homeassistant/components/notify/__init__.py | 1 - homeassistant/components/recorder.py | 1 - homeassistant/components/rfxtrx.py | 1 - homeassistant/components/sensor/__init__.py | 1 - homeassistant/components/shell_command.py | 1 - homeassistant/components/sun.py | 1 - homeassistant/components/switch/__init__.py | 1 - .../components/thermostat/__init__.py | 1 - homeassistant/components/updater.py | 1 - homeassistant/components/wink.py | 1 - homeassistant/components/zone.py | 1 - homeassistant/components/zwave.py | 1 - homeassistant/loader.py | 2 +- 36 files changed, 10 insertions(+), 47 deletions(-) diff --git a/homeassistant/bootstrap.py b/homeassistant/bootstrap.py index 4d68227d4d0..41377aadebf 100644 --- a/homeassistant/bootstrap.py +++ b/homeassistant/bootstrap.py @@ -82,7 +82,7 @@ def _setup_component(hass, domain, config): return True component = loader.get_component(domain) - missing_deps = [dep for dep in component.DEPENDENCIES + missing_deps = [dep for dep in getattr(component, 'DEPENDENCIES', []) if dep not in hass.config.components] if missing_deps: @@ -106,7 +106,7 @@ def _setup_component(hass, domain, config): # Assumption: if a component does not depend on groups # it communicates with devices - if group.DOMAIN not in component.DEPENDENCIES: + if group.DOMAIN not in getattr(component, 'DEPENDENCIES', []): hass.pool.add_worker() hass.bus.fire( @@ -133,14 +133,13 @@ def prepare_setup_platform(hass, config, domain, platform_name): return platform # Load dependencies - if hasattr(platform, 'DEPENDENCIES'): - for component in platform.DEPENDENCIES: - if not setup_component(hass, component, config): - _LOGGER.error( - 'Unable to prepare setup for platform %s because ' - 'dependency %s could not be initialized', platform_path, - component) - return None + for component in getattr(platform, 'DEPENDENCIES', []): + if not setup_component(hass, component, config): + _LOGGER.error( + 'Unable to prepare setup for platform %s because ' + 'dependency %s could not be initialized', platform_path, + component) + return None if not _handle_requirements(hass, platform, platform_path): return None diff --git a/homeassistant/components/alarm_control_panel/__init__.py b/homeassistant/components/alarm_control_panel/__init__.py index d3289e08e62..3f5e6362fb6 100644 --- a/homeassistant/components/alarm_control_panel/__init__.py +++ b/homeassistant/components/alarm_control_panel/__init__.py @@ -15,7 +15,6 @@ from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_component import EntityComponent DOMAIN = 'alarm_control_panel' -DEPENDENCIES = [] SCAN_INTERVAL = 30 ENTITY_ID_FORMAT = DOMAIN + '.{}' diff --git a/homeassistant/components/alarm_control_panel/manual.py b/homeassistant/components/alarm_control_panel/manual.py index ca1816db9e6..63bc989f3df 100644 --- a/homeassistant/components/alarm_control_panel/manual.py +++ b/homeassistant/components/alarm_control_panel/manual.py @@ -18,8 +18,6 @@ from homeassistant.const import ( _LOGGER = logging.getLogger(__name__) -DEPENDENCIES = [] - DEFAULT_ALARM_NAME = 'HA Alarm' DEFAULT_PENDING_TIME = 60 DEFAULT_TRIGGER_TIME = 120 diff --git a/homeassistant/components/arduino.py b/homeassistant/components/arduino.py index 0c278ceee63..88967ec1f74 100644 --- a/homeassistant/components/arduino.py +++ b/homeassistant/components/arduino.py @@ -19,7 +19,6 @@ from homeassistant.const import (EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP) DOMAIN = "arduino" -DEPENDENCIES = [] REQUIREMENTS = ['PyMata==2.07a'] BOARD = None _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/binary_sensor/__init__.py b/homeassistant/components/binary_sensor/__init__.py index 2ef9e83cc30..ccfd57aff8c 100644 --- a/homeassistant/components/binary_sensor/__init__.py +++ b/homeassistant/components/binary_sensor/__init__.py @@ -14,7 +14,6 @@ from homeassistant.helpers.entity import Entity from homeassistant.const import (STATE_ON, STATE_OFF) DOMAIN = 'binary_sensor' -DEPENDENCIES = [] SCAN_INTERVAL = 30 ENTITY_ID_FORMAT = DOMAIN + '.{}' diff --git a/homeassistant/components/browser.py b/homeassistant/components/browser.py index db0f3710158..88548e2a1b3 100644 --- a/homeassistant/components/browser.py +++ b/homeassistant/components/browser.py @@ -8,7 +8,6 @@ https://home-assistant.io/components/browser/ """ DOMAIN = "browser" -DEPENDENCIES = [] SERVICE_BROWSE_URL = "browse_url" diff --git a/homeassistant/components/configurator.py b/homeassistant/components/configurator.py index 8bec580abf9..515daffc71c 100644 --- a/homeassistant/components/configurator.py +++ b/homeassistant/components/configurator.py @@ -15,7 +15,6 @@ from homeassistant.helpers import generate_entity_id from homeassistant.const import EVENT_TIME_CHANGED DOMAIN = "configurator" -DEPENDENCIES = [] ENTITY_ID_FORMAT = DOMAIN + ".{}" SERVICE_CONFIGURE = "configure" diff --git a/homeassistant/components/conversation.py b/homeassistant/components/conversation.py index d9cba832df7..7cd1193448c 100644 --- a/homeassistant/components/conversation.py +++ b/homeassistant/components/conversation.py @@ -14,7 +14,6 @@ from homeassistant.const import ( ATTR_ENTITY_ID, SERVICE_TURN_ON, SERVICE_TURN_OFF) DOMAIN = "conversation" -DEPENDENCIES = [] SERVICE_PROCESS = "process" diff --git a/homeassistant/components/discovery.py b/homeassistant/components/discovery.py index 3a43c86f58a..807f1fe3944 100644 --- a/homeassistant/components/discovery.py +++ b/homeassistant/components/discovery.py @@ -17,7 +17,6 @@ from homeassistant.const import ( ATTR_SERVICE, ATTR_DISCOVERED) DOMAIN = "discovery" -DEPENDENCIES = [] REQUIREMENTS = ['netdisco==0.5.1'] SCAN_INTERVAL = 300 # seconds diff --git a/homeassistant/components/downloader.py b/homeassistant/components/downloader.py index a69a6ca1517..655bf7d4eb6 100644 --- a/homeassistant/components/downloader.py +++ b/homeassistant/components/downloader.py @@ -15,7 +15,6 @@ from homeassistant.helpers import validate_config from homeassistant.util import sanitize_filename DOMAIN = "downloader" -DEPENDENCIES = [] SERVICE_DOWNLOAD_FILE = "download_file" diff --git a/homeassistant/components/group.py b/homeassistant/components/group.py index 9ae83cb734a..52ffe824e42 100644 --- a/homeassistant/components/group.py +++ b/homeassistant/components/group.py @@ -17,7 +17,6 @@ from homeassistant.const import ( STATE_UNKNOWN) DOMAIN = "group" -DEPENDENCIES = [] ENTITY_ID_FORMAT = DOMAIN + ".{}" diff --git a/homeassistant/components/http.py b/homeassistant/components/http.py index a7ae0c5af6e..88392ed3fe4 100644 --- a/homeassistant/components/http.py +++ b/homeassistant/components/http.py @@ -34,7 +34,6 @@ import homeassistant.util.dt as date_util import homeassistant.bootstrap as bootstrap DOMAIN = "http" -DEPENDENCIES = [] CONF_API_PASSWORD = "api_password" CONF_SERVER_HOST = "server_host" diff --git a/homeassistant/components/ifttt.py b/homeassistant/components/ifttt.py index 246265a5268..3721f5b1d33 100644 --- a/homeassistant/components/ifttt.py +++ b/homeassistant/components/ifttt.py @@ -22,8 +22,6 @@ ATTR_VALUE1 = 'value1' ATTR_VALUE2 = 'value2' ATTR_VALUE3 = 'value3' -DEPENDENCIES = [] - REQUIREMENTS = ['pyfttt==0.3'] diff --git a/homeassistant/components/introduction.py b/homeassistant/components/introduction.py index 08a71b27292..540d928f7f5 100644 --- a/homeassistant/components/introduction.py +++ b/homeassistant/components/introduction.py @@ -9,7 +9,6 @@ https://home-assistant.io/components/introduction/ import logging DOMAIN = 'introduction' -DEPENDENCIES = [] def setup(hass, config=None): diff --git a/homeassistant/components/isy994.py b/homeassistant/components/isy994.py index 427ef4f048e..2a36f2060fc 100644 --- a/homeassistant/components/isy994.py +++ b/homeassistant/components/isy994.py @@ -20,7 +20,6 @@ from homeassistant.const import ( ATTR_FRIENDLY_NAME) DOMAIN = "isy994" -DEPENDENCIES = [] REQUIREMENTS = ['PyISY==1.0.5'] DISCOVER_LIGHTS = "isy994.lights" DISCOVER_SWITCHES = "isy994.switches" diff --git a/homeassistant/components/keyboard.py b/homeassistant/components/keyboard.py index ea650d8b421..c772d1c6e74 100644 --- a/homeassistant/components/keyboard.py +++ b/homeassistant/components/keyboard.py @@ -15,7 +15,6 @@ from homeassistant.const import ( DOMAIN = "keyboard" -DEPENDENCIES = [] REQUIREMENTS = ['pyuserinput==0.1.9'] diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index d7f8746de5a..1b80035fb0d 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -21,7 +21,6 @@ import homeassistant.util.color as color_util DOMAIN = "light" -DEPENDENCIES = [] SCAN_INTERVAL = 30 GROUP_NAME_ALL_LIGHTS = 'all lights' diff --git a/homeassistant/components/light/blinksticklight.py b/homeassistant/components/light/blinksticklight.py index 5cc14a9034b..fae9890c93d 100644 --- a/homeassistant/components/light/blinksticklight.py +++ b/homeassistant/components/light/blinksticklight.py @@ -14,7 +14,6 @@ _LOGGER = logging.getLogger(__name__) REQUIREMENTS = ["blinkstick==1.1.7"] -DEPENDENCIES = [] # pylint: disable=unused-argument diff --git a/homeassistant/components/lock/__init__.py b/homeassistant/components/lock/__init__.py index 2cbd3a40872..fdc2da3e8d4 100644 --- a/homeassistant/components/lock/__init__.py +++ b/homeassistant/components/lock/__init__.py @@ -20,7 +20,6 @@ from homeassistant.const import ( from homeassistant.components import (group, wink) DOMAIN = 'lock' -DEPENDENCIES = [] SCAN_INTERVAL = 30 GROUP_NAME_ALL_LOCKS = 'all locks' diff --git a/homeassistant/components/logger.py b/homeassistant/components/logger.py index a6dafa56005..9a5d1c59d1a 100644 --- a/homeassistant/components/logger.py +++ b/homeassistant/components/logger.py @@ -10,7 +10,6 @@ import logging from collections import OrderedDict DOMAIN = 'logger' -DEPENDENCIES = [] LOGSEVERITY = { 'CRITICAL': 50, diff --git a/homeassistant/components/media_player/__init__.py b/homeassistant/components/media_player/__init__.py index 8140bbb2af9..8204052b4a9 100644 --- a/homeassistant/components/media_player/__init__.py +++ b/homeassistant/components/media_player/__init__.py @@ -22,7 +22,6 @@ from homeassistant.const import ( SERVICE_MEDIA_NEXT_TRACK, SERVICE_MEDIA_PREVIOUS_TRACK, SERVICE_MEDIA_SEEK) DOMAIN = 'media_player' -DEPENDENCIES = [] SCAN_INTERVAL = 10 ENTITY_ID_FORMAT = DOMAIN + '.{}' diff --git a/homeassistant/components/modbus.py b/homeassistant/components/modbus.py index 099801eb7cf..6f53c89835a 100644 --- a/homeassistant/components/modbus.py +++ b/homeassistant/components/modbus.py @@ -13,7 +13,6 @@ from homeassistant.const import (EVENT_HOMEASSISTANT_START, DOMAIN = "modbus" -DEPENDENCIES = [] REQUIREMENTS = ['https://github.com/bashwork/pymodbus/archive/' 'd7fc4f1cc975631e0a9011390e8017f64b612661.zip#pymodbus==1.2.0'] diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 9ec5169c729..7ce9340b27e 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -30,7 +30,6 @@ DEFAULT_QOS = 0 SERVICE_PUBLISH = 'publish' EVENT_MQTT_MESSAGE_RECEIVED = 'MQTT_MESSAGE_RECEIVED' -DEPENDENCIES = [] REQUIREMENTS = ['paho-mqtt==1.1', 'jsonpath-rw==1.4.0'] CONF_BROKER = 'broker' diff --git a/homeassistant/components/notify/__init__.py b/homeassistant/components/notify/__init__.py index 6cd7a2196cf..9182f1dbf3a 100644 --- a/homeassistant/components/notify/__init__.py +++ b/homeassistant/components/notify/__init__.py @@ -17,7 +17,6 @@ from homeassistant.helpers import config_per_platform from homeassistant.const import CONF_NAME DOMAIN = "notify" -DEPENDENCIES = [] # Title of notification ATTR_TITLE = "title" diff --git a/homeassistant/components/recorder.py b/homeassistant/components/recorder.py index b09e10f7d92..6b2557dd1d6 100644 --- a/homeassistant/components/recorder.py +++ b/homeassistant/components/recorder.py @@ -23,7 +23,6 @@ from homeassistant.const import ( EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP) DOMAIN = "recorder" -DEPENDENCIES = [] DB_FILE = 'home-assistant.db' diff --git a/homeassistant/components/rfxtrx.py b/homeassistant/components/rfxtrx.py index 3c4675d806d..894634c8fc2 100644 --- a/homeassistant/components/rfxtrx.py +++ b/homeassistant/components/rfxtrx.py @@ -9,7 +9,6 @@ https://home-assistant.io/components/rfxtrx/ import logging from homeassistant.util import slugify -DEPENDENCIES = [] REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/0.2.zip' + '#RFXtrx==0.2'] diff --git a/homeassistant/components/sensor/__init__.py b/homeassistant/components/sensor/__init__.py index 32ee59a6fa9..95cb331b91f 100644 --- a/homeassistant/components/sensor/__init__.py +++ b/homeassistant/components/sensor/__init__.py @@ -12,7 +12,6 @@ from homeassistant.helpers.entity_component import EntityComponent from homeassistant.components import wink, zwave, isy994, verisure DOMAIN = 'sensor' -DEPENDENCIES = [] SCAN_INTERVAL = 30 ENTITY_ID_FORMAT = DOMAIN + '.{}' diff --git a/homeassistant/components/shell_command.py b/homeassistant/components/shell_command.py index 61c9add3f23..5e12c8bfd6e 100644 --- a/homeassistant/components/shell_command.py +++ b/homeassistant/components/shell_command.py @@ -12,7 +12,6 @@ import subprocess from homeassistant.util import slugify DOMAIN = 'shell_command' -DEPENDENCIES = [] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/sun.py b/homeassistant/components/sun.py index a5b83e76929..efe0a7dec2b 100644 --- a/homeassistant/components/sun.py +++ b/homeassistant/components/sun.py @@ -15,7 +15,6 @@ import homeassistant.util.dt as dt_util from homeassistant.helpers.event import track_point_in_utc_time from homeassistant.helpers.entity import Entity -DEPENDENCIES = [] REQUIREMENTS = ['astral==0.8.1'] DOMAIN = "sun" ENTITY_ID = "sun.sun" diff --git a/homeassistant/components/switch/__init__.py b/homeassistant/components/switch/__init__.py index 9a0abb4ce7a..e7b3c629f39 100644 --- a/homeassistant/components/switch/__init__.py +++ b/homeassistant/components/switch/__init__.py @@ -20,7 +20,6 @@ from homeassistant.components import ( group, discovery, wink, isy994, verisure, zwave) DOMAIN = 'switch' -DEPENDENCIES = [] SCAN_INTERVAL = 30 GROUP_NAME_ALL_SWITCHES = 'all switches' diff --git a/homeassistant/components/thermostat/__init__.py b/homeassistant/components/thermostat/__init__.py index 480e3e4805e..b475fce39d8 100644 --- a/homeassistant/components/thermostat/__init__.py +++ b/homeassistant/components/thermostat/__init__.py @@ -20,7 +20,6 @@ from homeassistant.const import ( TEMP_CELCIUS) DOMAIN = "thermostat" -DEPENDENCIES = [] ENTITY_ID_FORMAT = DOMAIN + ".{}" SCAN_INTERVAL = 60 diff --git a/homeassistant/components/updater.py b/homeassistant/components/updater.py index 803cfa609ca..a020a6c0abb 100644 --- a/homeassistant/components/updater.py +++ b/homeassistant/components/updater.py @@ -16,7 +16,6 @@ from homeassistant.helpers import event _LOGGER = logging.getLogger(__name__) PYPI_URL = 'https://pypi.python.org/pypi/homeassistant/json' -DEPENDENCIES = [] DOMAIN = 'updater' ENTITY_ID = 'updater.updater' diff --git a/homeassistant/components/wink.py b/homeassistant/components/wink.py index bd79210bf75..1ab82236596 100644 --- a/homeassistant/components/wink.py +++ b/homeassistant/components/wink.py @@ -17,7 +17,6 @@ from homeassistant.const import ( ATTR_SERVICE, ATTR_DISCOVERED, ATTR_FRIENDLY_NAME) DOMAIN = "wink" -DEPENDENCIES = [] REQUIREMENTS = ['https://github.com/balloob/python-wink/archive/' '42fdcfa721b1bc583688e3592d8427f4c13ba6d9.zip' '#python-wink==0.2'] diff --git a/homeassistant/components/zone.py b/homeassistant/components/zone.py index a32a297caeb..da0341129f7 100644 --- a/homeassistant/components/zone.py +++ b/homeassistant/components/zone.py @@ -15,7 +15,6 @@ from homeassistant.helpers.entity import Entity from homeassistant.util.location import distance DOMAIN = "zone" -DEPENDENCIES = [] ENTITY_ID_FORMAT = 'zone.{}' ENTITY_ID_HOME = ENTITY_ID_FORMAT.format('home') STATE = 'zoning' diff --git a/homeassistant/components/zwave.py b/homeassistant/components/zwave.py index 11515e4031d..5d526293083 100644 --- a/homeassistant/components/zwave.py +++ b/homeassistant/components/zwave.py @@ -17,7 +17,6 @@ from homeassistant.const import ( EVENT_PLATFORM_DISCOVERED, ATTR_SERVICE, ATTR_DISCOVERED) DOMAIN = "zwave" -DEPENDENCIES = [] REQUIREMENTS = ['pydispatcher==2.0.5'] CONF_USB_STICK_PATH = "usb_path" diff --git a/homeassistant/loader.py b/homeassistant/loader.py index b05083b4abd..8b38f5e0966 100644 --- a/homeassistant/loader.py +++ b/homeassistant/loader.py @@ -193,7 +193,7 @@ def _load_order_component(comp_name, load_order, loading): loading.add(comp_name) - for dependency in component.DEPENDENCIES: + for dependency in getattr(component, 'DEPENDENCIES', []): # Check not already loaded if dependency in load_order: continue From 7204bc018fc127a9f2b677a1f184a25b9454b26a Mon Sep 17 00:00:00 2001 From: pavoni Date: Fri, 27 Nov 2015 11:43:43 +0000 Subject: [PATCH 26/49] Add exception handler for vera timeout --- homeassistant/components/switch/vera.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/switch/vera.py b/homeassistant/components/switch/vera.py index 80724f92757..14983919c64 100644 --- a/homeassistant/components/switch/vera.py +++ b/homeassistant/components/switch/vera.py @@ -126,5 +126,8 @@ class VeraSwitch(ToggleEntity): def update(self): # We need to debounce the status call after turning switch on or off # because the vera has some lag in updating the device status - if (self.last_command_send + 5) < time.time(): - self.is_on_status = self.vera_device.is_switched_on() + try: + if (self.last_command_send + 5) < time.time(): + self.is_on_status = self.vera_device.is_switched_on() + except RequestException: + _LOGGER.warning('Could not update status for %s', self.name) From 00f0dfb97104d465c90942fb0e2190bc99742c90 Mon Sep 17 00:00:00 2001 From: pavoni Date: Fri, 27 Nov 2015 18:21:26 +0000 Subject: [PATCH 27/49] Trap and trace error rather than throwing exception when efergy server --- homeassistant/components/sensor/efergy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/sensor/efergy.py b/homeassistant/components/sensor/efergy.py index 99140b5b2a9..447903a714e 100644 --- a/homeassistant/components/sensor/efergy.py +++ b/homeassistant/components/sensor/efergy.py @@ -97,5 +97,5 @@ class EfergySensor(Entity): self._state = response.json()['sum'] else: self._state = 'Unknown' - except RequestException: + except (RequestException, ValueError): _LOGGER.warning('Could not update status for %s', self.name) From bbf73e0bae587583bc16c0e87942e29cb4787566 Mon Sep 17 00:00:00 2001 From: pavoni Date: Fri, 27 Nov 2015 19:05:15 +0000 Subject: [PATCH 28/49] Bump pywemo version - fixed scan device = None bug --- homeassistant/components/switch/wemo.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/switch/wemo.py b/homeassistant/components/switch/wemo.py index 1d701bf88cc..bad471ce437 100644 --- a/homeassistant/components/switch/wemo.py +++ b/homeassistant/components/switch/wemo.py @@ -11,7 +11,7 @@ import logging from homeassistant.components.switch import SwitchDevice from homeassistant.const import STATE_ON, STATE_OFF, STATE_STANDBY -REQUIREMENTS = ['pywemo==0.3.2'] +REQUIREMENTS = ['pywemo==0.3.3'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index a9f24cdb65f..982cf125572 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -149,7 +149,7 @@ hikvision==0.4 orvibo==1.0.0 # homeassistant.components.switch.wemo -pywemo==0.3.2 +pywemo==0.3.3 # homeassistant.components.thermostat.honeywell evohomeclient==0.2.3 From 6809a881faf0cf2a4e2036805a1327ff39b48d29 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 28 Nov 2015 01:02:35 -0800 Subject: [PATCH 29/49] Tweak MQTT Motor component --- homeassistant/components/motor/__init__.py | 20 ++++++--- homeassistant/components/motor/mqtt.py | 16 -------- tests/components/motor/test_mqtt.py | 48 +++++++++++++++++++++- 3 files changed, 60 insertions(+), 24 deletions(-) diff --git a/homeassistant/components/motor/__init__.py b/homeassistant/components/motor/__init__.py index feea836a0dd..806dd9e0eb1 100644 --- a/homeassistant/components/motor/__init__.py +++ b/homeassistant/components/motor/__init__.py @@ -17,7 +17,6 @@ from homeassistant.const import ( DOMAIN = 'motor' -DEPENDENCIES = [] SCAN_INTERVAL = 15 GROUP_NAME_ALL_MOTORS = 'all motors' @@ -30,6 +29,8 @@ DISCOVERY_PLATFORMS = {} _LOGGER = logging.getLogger(__name__) +ATTR_CURRENT_POSITION = 'current_position' + def is_open(hass, entity_id=None): """ Returns if the motor is open based on the statemachine. """ @@ -114,17 +115,24 @@ class MotorDevice(Entity): @property def state_attributes(self): - """ Returns optional state attributes. """ - return None + """ Return the state attributes. """ + current = self.current_position + + if current is None: + return None + + return { + ATTR_CURRENT_POSITION: current + } def open(self, **kwargs): - """ Open the device. """ + """ Open the motor. """ raise NotImplementedError() def close(self, **kwargs): - """ Close the device. """ + """ Close the motor. """ raise NotImplementedError() def stop(self, **kwargs): - """ Stop the device. """ + """ Stop the motor. """ raise NotImplementedError() diff --git a/homeassistant/components/motor/mqtt.py b/homeassistant/components/motor/mqtt.py index 2aac5e37c16..1075030fc37 100644 --- a/homeassistant/components/motor/mqtt.py +++ b/homeassistant/components/motor/mqtt.py @@ -18,10 +18,7 @@ DEFAULT_PAYLOAD_OPEN = "OPEN" DEFAULT_PAYLOAD_CLOSE = "CLOSE" DEFAULT_PAYLOAD_STOP = "STOP" -ATTR_CURRENT_POSITION = 'current_position' - -# pylint: disable=unused-argument def setup_platform(hass, config, add_devices_callback, discovery_info=None): """ Add MQTT Motor """ @@ -88,11 +85,6 @@ class MqttMotor(MotorDevice): None is unknown, 0 is closed, 100 is fully open. """ return self._state - @property - def is_open(self): - """ True if device is current position is not zero. """ - return self._state > 0 - def open(self, **kwargs): """ Open the device. """ mqtt.publish(self.hass, self._command_topic, self._payload_open, @@ -107,11 +99,3 @@ class MqttMotor(MotorDevice): """ Stop the device. """ mqtt.publish(self.hass, self._command_topic, self._payload_stop, self._qos) - - @property - def state_attributes(self): - """ Return the state attributes. """ - state_attr = {} - if self._state is not None: - state_attr[ATTR_CURRENT_POSITION] = self._state - return state_attr diff --git a/tests/components/motor/test_mqtt.py b/tests/components/motor/test_mqtt.py index 4d7af04ae6c..1638e830f2d 100644 --- a/tests/components/motor/test_mqtt.py +++ b/tests/components/motor/test_mqtt.py @@ -58,7 +58,7 @@ class TestMotorMQTT(unittest.TestCase): state = self.hass.states.get('motor.test') self.assertEqual(STATE_OPEN, state.state) - def test_sending_mqtt_commands(self): + def test_send_open_command(self): self.assertTrue(motor.setup(self.hass, { 'motor': { 'platform': 'mqtt', @@ -75,7 +75,51 @@ class TestMotorMQTT(unittest.TestCase): motor.call_open(self.hass, 'motor.test') self.hass.pool.block_till_done() - self.assertEqual(('command-topic', 'OPEN', 2), + self.assertEqual(('command-topic', 'OPEN', 2, False), + self.mock_publish.mock_calls[-1][1]) + state = self.hass.states.get('motor.test') + self.assertEqual(STATE_UNKNOWN, state.state) + + def test_send_close_command(self): + self.assertTrue(motor.setup(self.hass, { + 'motor': { + 'platform': 'mqtt', + 'name': 'test', + 'state_topic': 'state-topic', + 'command_topic': 'command-topic', + 'qos': 2 + } + })) + + state = self.hass.states.get('motor.test') + self.assertEqual(STATE_UNKNOWN, state.state) + + motor.call_close(self.hass, 'motor.test') + self.hass.pool.block_till_done() + + self.assertEqual(('command-topic', 'CLOSE', 2, False), + self.mock_publish.mock_calls[-1][1]) + state = self.hass.states.get('motor.test') + self.assertEqual(STATE_UNKNOWN, state.state) + + def test_send_stop_command(self): + self.assertTrue(motor.setup(self.hass, { + 'motor': { + 'platform': 'mqtt', + 'name': 'test', + 'state_topic': 'state-topic', + 'command_topic': 'command-topic', + 'qos': 2 + } + })) + + state = self.hass.states.get('motor.test') + self.assertEqual(STATE_UNKNOWN, state.state) + + motor.call_stop(self.hass, 'motor.test') + self.hass.pool.block_till_done() + + self.assertEqual(('command-topic', 'STOP', 2, False), self.mock_publish.mock_calls[-1][1]) state = self.hass.states.get('motor.test') self.assertEqual(STATE_UNKNOWN, state.state) From 1146d6e58d4187da0300ddd08d9b3cc5459bb006 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 28 Nov 2015 01:18:02 -0800 Subject: [PATCH 30/49] Allow thermostat temperatures with decimal numbers --- homeassistant/components/frontend/version.py | 2 +- .../components/frontend/www_static/frontend.html | 6 +++--- .../frontend/www_static/home-assistant-polymer | 2 +- homeassistant/components/thermostat/__init__.py | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/frontend/version.py b/homeassistant/components/frontend/version.py index 0199b05156e..ed954909e66 100644 --- a/homeassistant/components/frontend/version.py +++ b/homeassistant/components/frontend/version.py @@ -1,2 +1,2 @@ """ DO NOT MODIFY. Auto-generated by build_frontend script """ -VERSION = "dff74f773ea8b0356b0bd8130ed6f0cf" +VERSION = "c90d40a0240cc1feec791ee820d928b3" diff --git a/homeassistant/components/frontend/www_static/frontend.html b/homeassistant/components/frontend/www_static/frontend.html index b2a2eb97b3e..73b2ac1b7dd 100644 --- a/homeassistant/components/frontend/www_static/frontend.html +++ b/homeassistant/components/frontend/www_static/frontend.html @@ -5838,7 +5838,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN .has-away_mode .away-mode-toggle { display: block; - }
- -
Initializing
+ +
diff --git a/homeassistant/components/frontend/version.py b/homeassistant/components/frontend/version.py index ed954909e66..7e957562bba 100644 --- a/homeassistant/components/frontend/version.py +++ b/homeassistant/components/frontend/version.py @@ -1,2 +1,2 @@ """ DO NOT MODIFY. Auto-generated by build_frontend script """ -VERSION = "c90d40a0240cc1feec791ee820d928b3" +VERSION = "c1df3a08faa4a9978b25639ca0fd63cd" diff --git a/homeassistant/components/frontend/www_static/favicon-384x384.png b/homeassistant/components/frontend/www_static/favicon-384x384.png new file mode 100644 index 0000000000000000000000000000000000000000..51f67770790077d5e271231ebeadf09a08feb52c GIT binary patch literal 19825 zcmeAS@N?(olHy`uVBq!ia0y~yU~B+k4mJh`h9$?h?q^_NkSuYHC<)F_D=AMbN@Z|N z$xljE@XSq2PYp^XQ2>tmIipR1P$QlnRqTfhJUHue<-iOJci zB??KY>6v-9O7C~?S5nAKu~iB;^)>Jo2Tt~skz|cV7z)0WFNY~KZ%Gk)tz(4^Clz9|8>y;bpa#8ycOYHUSrfv+#z;JjjJKqcqr>Q^Kd=o{)8=;!8w`~~)KaY;}r!Wmdq z7l%|9r0NHy7U!21C8q|ZrYR#?h2J8O!UA7kEB~U*^vt}(9GCp$(%jU%5>FRfrHb4F zy_C!ps}y4kQ)9zab6tbfltf(<3o}byOJg%5-Q+~`Br_uegH+=*QPS5KJh@ z#SO#+r*=@vw^Kl5snom_Tcsi;d%H@PTigr`p52})YH|qgQ1H_tEr*GN^i&O7aFf*-^&K3&$IqsSSvT* z`ti3jweNZ?w3JtKGf4(2Ru>h0E8ev`ul8!}-K~G>ug2evy}NZ!{yeYw_g1fdRewMK z_x||HrE?h=7#iLvwmXCJJtK%v01*rz*yuDxYb~$g{@3l(nQ==J}`1pkXhW6<}|p{Na_lfzTMsPb}?J| zTf@BlSvm1$M-;ZnIq9%2NPK%gD<}Mh{QT7+J!`$DX7!4#3SD)zWYv|d9bXt2Uhp?Q zE1q)MMC;k-XZN2vHF~w$*dIOidhW4rdd=q}IPBKE5={wX=wUwk?*eUYTmlv(T~5`wh8nc zPyPQ}pMlpees|8vqsPu(@6DakS(la9*mw3!ps1J~0|O`1=j&Sz#_xGrY#C)^;c%Gw z=pIELb1DD*R|J~0{}*KZIbL|<<%E878^$ZL`yw41t z89m$b@+WIu#@3C0PdwQ3{UEb~mL&TlxyRp9YZmbNpS$qJi8Y*;fk9K4X)d3y&*hMf z4&Lr;H;s2(eqeV_c+bHb&o*l?$VmV0+i07AEZ~?k+t2F)kJ%X%jy{NacKPw-Ejbk( zY~HQm()_&=x8pateMzqWCCT)QW%B-{Z^- z3@Jj7+XQU_zq9;1cjKJrZia&U^Zwh~?hi3oJ$iToLJwsYO{rU8sDc*OSU#!ji#9$Vl{p<9x^k;?B7#SE; zEUeDH&HrK^SbMA>%cf!VjbH9-?HL#vWI~&j)zhAPALr$bNxkzoLCU6~X6ds1Wl4FA z>Ea9w3Jft~SsVwmt3Sr>6=*0v9-$lqVJXFQ2uH~hVye;zVb6LEa+Kj zm2PMJk;!0pK;^ux5uiLMz!UegU|rBo8&;+OTjAxx3=9fOICMhF)nXaErbgu&`l&K7 zI9Qws&ps|`{w0#OV<+HO0&>3wCb^p)XQ`ZGW0uj&j84iyEKFa9N8p1t@_p9kxLptWlcWwJ0Z zWbkjEdWy4Cv?0qkzA2c4f#HH&Nvyoj8U_iyGX{Q&3=9r7fd>>BjPjDUez)V*JkU4Zzv6x2wJ6~}f4rfC2S)<~gG2h0_x^vX!uN1l z2EJ}g5_lnaK$<~;fkB{e!P6t_%l*D-z5hO8o1O^M(hCAE3?L2aVf*i?GJY&(GWnQp zeIitXQbFUiTD6Kfxq zb01Z3;9%Oz*uijt`Ckh=gG%3@+lqC+tLJUbYKW`8WWXyL#j?A?vu~S@q~SKE+P51u zXGH{jQR0~-*3}ro;Z(saz{tSF(D283!hZgb#{aVZD(ua9JmJe{eXE5&uiHL$PZwt1DbNA7ivLLgN5hjz`}I`o>vBJTt;x z>Uf{(SI0{xKT4lJ+xRUvuJN_$qx)R`piou#|LsJ4%GcW`el%@ltU9{vTezC-+aE%) z)vuDIPJCYe^4y7jZ-JUt2dw}B#s&2b92_1dKf85b|9TsrC$VUH{+pV}SKZ6Ba>pXY+N&9`<$TsDVx?<@Jo2dA5%$qGGPt>|}U7|M07i6`H#?eOIy<%Q`N=puphJc4Gg(AMtq- z%dSg4i9h9c zbS%u+a8Jv=FDC+Lt&K{Z*Q>tvXMC7T$Nvq7oX%e8&%OTkp@LFo9K*u}JxY%*cc~am z$oRBf?s3a|(b?`*--7jGjD1$OaeaCCoA1((rmga`()Y~zv;H>6UB@3)rxg{NI2df% zog5qD>@IyiH7~?_`2mcf1-?(#B>E1_1_! zC+{oXEPdVnLU*|?pY7r8w=2HQO04>R^Yqzwi+1_4%yN4AiA{mYA?8B!R|bLUXUu+P z+da|GoO-8X-A}2#rngu5t#COX6S_>>jQ{wv<$1Ps4eKo5TKxL*w_W$BQD=Lsu3VQKis&A@Pa|LSS`H|{;M;ZOX=Op7x6 zpOLHEU+xH+XZP>4b4kuVw|76|QzqM#7wu4GGP@W&!?fp!!39nMCMF@*f7A0N7KP6@ z@oAkAw==zG+RND8)2g3yayU8d+RMW6Pyw6=pFXMo_{wN+*5`sZ{0B9?*Nx7j_jaHSqo)moUW&d>NwYLe6TpAg&o`XE8ttB;F#nC$w9nzZ z7k8hNGkwnKzyfNKed1U6&+YG#cEi0bc>1)Ly|<@ba!9WA>|hXJ|B|32!SIPc^XK~Y z)2o*8o{uv2InDn0%ffh>1)Q53Wh|d@S+I3q`{AF@!In7BL9JcVhC#vm$^S#8%_~*v zxo=OK`f}Rb(@&@EUmPi811g15TK>%6yUHhg*^EEBa}2FK%;#-fbI*ZKiNS%PVa;Uw z?d3ZPZ!2j%+ax$?N5eqcf-}LnTvCPw_O8&k)z2m4XSmLH~ecYL+ zvvj+Ssx!_|NM2n zOW8&e-zGM$Zr;%-BXrn7U+|?3!(0P?h9~-dKbrpRtvEMJFv>7u0sp^0489?AKC`@f z&Az2?TU#X)gAId1=9B+Tr5pY<+ceHTf5?VWfmM!y;nViX|36=w@^aNNrgsf8>3aH? z*S2x|dE4BcX{0xgL2wUa1p~v0{kEU>zd7Pq_4wMvGwL;=g^cDCZf~9ARy9YM;|trY zzun*{3HSUVHO>Bz-NSk-xa^?O7+Z37JTV-2Lo$BS1s^p+@ikpSoQU7gxy(7om=?xqX3=aS9s{Vhz zPVaKI;J25SJFH%`$$DpM$iLwk^X4O^h_gPYNXfr-Jz=by~y_NVgv{tvco zo@TCPRpWBtDd!1ir$?Ux$~7}?_^PpKt)JfA7{M{6g-wZpk>Tfd_kZW(gO^=bd?+nF zC$Zyzb(!AchYbZ2iq|zLs60_;vE}>g!Rn~Rl3T$nDb9F?nc-)<+JA3QbjaJ=G(YDQ zdHtDX*{XY$Og!l`GZtrOJoemMIB$04pS18m>!wYA-U_UGR)05Z*5g?vXQDUQ>d)T& z;P%TazvlFu6K`N=_{8t}Z_WqSpU1_QOV2y-)p}Zx=LNGv=9X_x@xBOpy{Gq*@6(EX zPd2M8)cE;zUHf;I2aGNUoLf2*HvDOvSIwl(bCIK(>HAh2#!Zn2zi}oTd023MD!{qf`HEWM9*dnRA8**wGco&$%!!s0jvCkKW4tu61P4u7)GT#@L? z^zl0j+ly_Rr(OJAU)S&~>sn9z$2E!WA6zyIuhR`l*z-gG+LV`fE(+=DKkxZ{SN-&? zjm_+7*ArGyBKU37@p{7y$?9XbDyP2`0(~QJLlLH{#Tr} z?$z3N{AJwt6`XzZ1(%0&bcFFdd-*HaE#vs5q$j`kT>7!@?Q!v!mfGSk-re`P)M$A( z_3rK#hiAM$IvUw01B%uf7Y}8R2O@`PR1nKbM{rorqZ^xdm5Gptq3!YpKdI- z|KXK;6ZXqmPZxc;^fmk3PzSEb*N-GG>SfJWU~ss0a=y21;?L!Wg&(jL&C0zreckmV zP6;-7^>0d=f811h&tBF)EyL6B`J5fkc08+HmkvsMPwq$FV4qfBRdDWx!rj7e8GCbG z);{~d_9e>qmEfGMYp!gsjSD(;ahhsnk$=qRxd&yOSPu1RaxhHb{8XRV{O95g-B^qA zHFA7f(GL}*8@o=~-ISKl`tn^#;!O6XpwNZp3POxe3z_&C8lL*+H$0smHN&{=e9Sc= z#&+|7&lN1S>wkU{s0xtg=GywrkVWCu=k~R`qZji8Z@Fr7{^h*yrtz0czP_%%o-@sU zLf!|b&+m5|aZ2YmNV*(2! zLvnff>X(K^{iO<^Vf@`vSWm| zMy&b2dh*+_Hp~Y znx3fh=Ep8_U+24YHQM1{Zks(t3f7MF$6Y}#8DBL~snsWnN1ZP5ZX2$(yhefJ-CsmoY zy^eMGwBko2L&Kl9)Al?5yMEvkyOc%wQ-Qtd-z9j(OwvsQblMs{SYn>6+r6fC>M8l% z4nKO;IT$9GeR99SUhr7wu<(w@a}2efMolZ%IprX$J(Kg@Zuj;Sr5Sx6_*oQQKdHaj zsZj60$H%_6c=|)mC$Fyeh_!EApulu!Qs|Zc>`ZqZj9vceM_4F?D1=Vo@EkxapjE58JQ<npPwzn$%xJaPIOtxMTvd>2j~{I~ga_`DgP?_TG2<1Sgcas6!Zr^3a2|8l;1+-F_z z^5m^GmAl0iRBE$TUYvXGBlwXsi`AB&pTR@rXZ-99GyW$Fhwl2^D5*I!>c_v!+|Q03 zIprkqy!P*RX3^s6le>iW{(MrDbk23-eObo0fB(H*J)`oFg_+|6Ybj6L#x?D=Zybay zjz0PSsPyTPiT|11wZ44&y^NXjYF{
)*=#XTG%lIsERmIq&*q^1o-@c$g^87+q{t zDH^cDkd2WcDEsIBcS{bs$oB0uHm%y8=o|gk-*VzDU5-Av|88H=366lt z40nCMtmDkuwRh{*weAy^tAv>SGtvH({mvRU%sQyNm*Zrt*LBwZ3tOu5bEx(?~3F$AXy~Kd+BBaJpZ4 zO=;J=C!2oG;Fx3a?)ko=tNicf->biWKhp8h#=rg6IIe>460 z_-NVN>{;LQ1C1g=PAb>v3LX5w5ajev=38ZQQ~Hm8zZo~W)}CJZ$mUqFzs9Ub3QkuN z6>dI1tu^u99@jS;3ph9v7Z^k>us+Vep8C;9bT-vwpcVFj%kD^g2MlDWXmh*R5y(!N1s{ZYx z_u|I&Gne=GI=gKBQN=;L({W#(0CH|aRa zeBF2IkmVagn}Q`$vul0Vh%0Qo@Rh@ck%K{?`t*NZO|IW34q48xE;%P$^zgUMOfL~T zNwdScKli$cfs1{+7ZvBduXM7z-thguqvwv}z1rr}48nHVzI$`_e#zdO z;vUa@}oDBd;Z!l_Z945lK*>kO^Hy1 zM9j{GDP3|44CZ_hTX_5U#9v(TA2vN;RGIT9en;EypYGoOs(HO3oeQ|!KN zDr@(@Zxb)Ldy@If#`w}}myZiI`oEKTwMzYh?x*Kw*TTy#?444qP}3JN>SCWa%|KK0M~WB>n!Ozmg>f4L$S^Ug|hGe*Bw77W=? z@MlizgLCZZRT=RTBtc;WKuZ)avN+;TlfqQhs! zV~KZ+x0q`#uuS+rdz*{*Kc8)mPu`0)&3-pq%&+4W+l(Fi>JDy@RQt%ynJaZtv(sVu zLj}=K&;Ne89j^A&Un1#>-p|kZ50cNZ$gA||u$W8k|2;3{ixgMX_3L{@v=)k(_{llE z@^@`{Qvb7)x#a4y7rOuFZ@D=6*~gQ!G-YxU-5I~>S@;}^w&lNg%Y9zyX{EsT>`(m9 z&8=cu^(4P`Uq<}TkA9E-PVT)ga7{UBV?xZ$-yU(!HkUc3bl|gCkR;zH zQKs-njRt{$pcDUpu4aF6Ho8q|f6abH#d^N*J^9BMNN##?Th{K$!*HRS+8a1xgcO_- z4?Dh{P#>c7HayJgn#O$D&mRr;ZBl1lsBky^4yzweu*6~xM#e&g|8YnDtliM0@#Qe* zz5Vwd{;8X{K}FeR-NpW0@8UvPc0J`h()#DG%dGwL>y772bH_*?`Tg#jScJo)g1%k0 z*BB}oR&xLT()35t$U9=%l9WvoBWG?3JLma@<&n!jp2)hk^ONWP(Op>9U4G|W;CC6O z*u)i1HVO=!ivOq2i&*x$O5oeZ4>y*WuQ?EET6gl)^L1VO58vqIIMVy)uhfZ?pY&v2 z+t**Ip7+i^>g+R#ue_3)6_T3bf*cMqI{$?&9!9^*JeB2jVPA!jDtE|MWu`*qdV7}I z|Ia4Iq#avuD`>*q?|PS*o-q9K`KNCnUM%^BxwAre_t$TyLo<(hOkz>;@oT8h575ks zIWb>w%87YCcfBTa_1Qkk=y=!k=_%I5ANTg;*|pj>M#c*UDE{}Y=#S?4!*gL|Yc2Xd3`)obGAnLlkmQJu{Geboxm>L)-Wb2RG(q$1d?pX12e?H~6QI9aa=$j_N`TP1nnGv{mT3}4QE za!pz}I5p0pje+q6qQdX{WA}Cag+X!Iy^cqBGVGc^b^V)ymKg?Yj0``yqpj9U zFW85Jz-nrWCh3)gT z%Z@JHQz5fU`e5a;P5*V`6Xg_~jhhu21h4;$-@3AA*%pUzL$M9p9B#4vdNcKK$?2Qg zE2k9qd7qzkpv+L44kcRd=?z-Iu)>rX2e(>h=3$xoZmrBm1wOIU3{jWtuL>Zw7}c7Wr2V?(WKF(~#)_;(r|tX1 zr_bMVHsPt)^b?b3Fz#3U=6iY4zW;Xx8mBs!{9YGW_5M8Hg{HjsVz++mzWVEOVa%)V zJ^#15l?PPoFLayT`ONT|iMuq%@z0BjCpm1lw`LN^Jha^-JWu1WNid7>zwQ4vINZM< zEof%7IcY%Ke=d(;*<^S~ zN#+0PYtvqAl@|OQ&N}(u-Tkwte_NYaP(Qo>e^uYU%np|G4Zfe2Y(6f%x9Z2YgU43I z*i4>PFTDOv>Az1kIj77bdn#iS_dWglG;i^q`FqM(-lxkH{#&KEOL_Uljw3i_Zryl)kikv8Yw;joyM%!N6p-MfY}X`0?=hdcBLU%?^GF zXWc&K->dqS>wQljlLxbEuf6+~6#x6{ zhktjH=ggLW^R>+TX{}0B$I-e|;LdBwF{57(YTGjpDt$RtQ2OWXHP(K=jNXlTSJy;)(nqB6ZW%y6Nz9^(>~dmz4_~(WAo2* zoQ(hSd*6o}do;!V{^)%(@#DU(6Y*Q-|G8x`ue+F6u;Tf-r6GA?>^F~ZNQ&ktkIXnQ zr(r=&q|k&o#*PVp;_H$+^KJw!lR0GPHG^m4zJ{I}i<~JUpVAM`;_{s2b3p$61BtEP z|NhKP{C4%zsYe=2;%j7~(GN&&-f=QJ4$L0r5LF zd4%UkC^*Q@`7m|jnWNg=X&H^?`}>yIPf+Q3+}7W!64F0?%W`w4?-k1DFY(QL@nCP@ z<1bH{OHR)`ZtilxT3;c6#bxV%O|ixotP8HU{xgmJ74y1~87!by7AbJUN_1~~@~gtQJ1*OH z*i3#g+fU2#+S946T|ex?d0l^6-<&+@sd~hmh@Q2@pI`B=4VZXhbNB10!_WJsW-6?| zSY21RBvk2?zlE3W+S$jFCVlHtjLyv1{Ob5}n=6lcmxQvrzG6I*IxT;>agF7h&$D_J z{+B6i7JAz~v-*gmQ{Ci`WeifH#&Q1bt7qJC*|{&?H-^Dt`hs`G{OV>WktihpXIU7WR~y!KeZ zCT9m*o;P;nWe;)l!3{&skdqMJu=IYPyr(Zb9a_s!;3AWN@-Rxp{*&8uLVwL-{auhEIa!kPk&Po9H} zcs@5^iTPZU37z}2R*5fvdaUhWSEJR*oym9S|Gz7f8z1y7;`khfz3xGrn;-9p2|w2^ zSHbaRo$U6#n?L>Y{1bgt)cK$7bgTRIC-cxk3GLrv%h%Rn|;TUH+jw4u}yhJ_vDKEJ8Hfbo_zmvR!UOLg|7IyPTzjo1p0?H zepzd;*YZv3Q5$#Iw3oK&x`y5^va0iy^bhDBQ}T{aZ2Y-n`$WHW3@hXuL_ckx`+z%K z>_w{jvSiz z^F2&ae0qG}*W+DZw!3lOEKCXf_apz=Y^4L+V;GM-|8sEhz0aE#tx?VUc`~?P|Kiy; z^$R@gtZhw4loaMFPcRVlh?UHEaPXVr|LOB1OwxZI`ZT@SSThMGE$Xh0v=%y01Scv7Xjj!%?uJVQ-tkLtZsWwf`!Svvf-4hJD+jykXUo_tTR(pHCDO z7XMe6{QU;Q-95>IQ;UoQ7o0ogeArE0fgyIwzh)=<-s5pw_j%;swQ8`c7w_DgRr|r` z$~Tto$%Xk3SYF)!Uh8My`2&K5W`c=iPma8|Taj zZSi@$o1wPmgzauQhY21gS7z(}-|uuNoMYb7Q!cWtTTeatc=hh5t&?whCkT2yYBBI; ziP&T1`z*@ylb`E?=qLG=DerI0T4z{%>Z5Db?{7y#6s|5QI1w6}TO@+((utbhGJ zyY!qpSh6Z9lLOMl(UbW63KZTj1&=&%#_4@I8#F8RF8HRQq{XUA2Y z_XCb;vnWXMAGC_pj}Kq6eO}BWCZT--jUwF+>QDF!k}4YRZ7=53)ziB6ar;E>j&2VX zcZOS*6SjRfXxv*=D>!+N0#m1W;{vlY3jfa)KHH>px8N4X)0N$E4PH+c9rq}4bN{OF z?`Folds|jc*n2Eb@WG>vdkPM4s|Rn-sAn71Z#UoSJfc>eX1WxB4#|LZpR z`+ahJvd-yWOeUt*wPK7D>Z>iXBLj2e96UCOyBSpJh^<_I{kB2R zq$73R49(7N0*(JV8BXl4)zQ+DGoE_SK0< zOIzcmNVY8N8~rlPOb#rYv_TSuDf^zy6uz**zAck0 zi&ZU6Ee}|9zc(;BKksJf$L-uD&sQFl)!6LzC%&SlQO-*1+k_t<*Z@l+75p-i|$Z%2c zeRBTr+m$CRS6yNGThU_g|7mva>Dtcw%S_|VvTLs2dnxtz#mdNEHxIVnxcV+Vjv++o zK;8#0pYs2C_iFUdzq|b9+N=d(Ir=~BOy6IBU7x-7`p%^0U2l!=?X4D#-B6`c_~iYz z8|~bxOIvR$GF|LG!2j*6$9(_EPwm4^d$!l#b*@$yk5Uxhx0U1eo>IGab!YahH+`|U zGCuq6@@uua%L7}b>TmB`{(RN-#qWLBvOiE43YA`Oezs)k@3rc)wjM~S&J9*Lp~zL} z>HPW76Pa(B;`4vJZMu0ZqBTZ=>96yxLw4M4u5njSUQONX`0rcaoU_NH!}hwZHT2Zw z&8TFlng9E6#GKWu-K(c`S}(BHuxY3}{Oq6U+CP2vLD{byWBh(z|CjB!>zsBwZyWd8 z4gDN{?&;fYTX2P6W3|$O-WxYgR~76@xndgGqJ+0WCTzTETF^2k$XrRSV~GagOo zzx}KHc!SHedUH<8#)XS=I2!H-6-?gJ@!@XMf{D-fr5XR&`@OX5w$z2sY|BqSI`-~| zo$&SFax=xhP5F6pq14;j1idTepP4j*r$SDK`F zk$ctmM22dPYmRpo1@u~fVNUU8xbbuHxnrAaY;6y5hh3Kb?QnK#>#xqe#*g0DFLiVi z?|mxsdwWvDi^bMmUuMleD|zJYS0*_tsgL;=7v~0v-MOxPr##xWf8LBsQ{#RgJuZI6 zHGId%+XXE59A-)FdAZItd`{SIH38PnRQ=8WOvCrYf2^z8v--?Up)U3Fa|49#Opg!n z(^uwO_fXK&`ta$n=S#z?LwHX%eYjAe8?v|BUa;-Y+a1?GEU{S5v_(4UBFmx&QrVl1 zDBJ=1rvWP$*|k#9BAaJDe^>}$?!mj%I(jt^EX|vn2Br>HN(tCp>X~)t&p+&;G_cKl)y(oORLJ zWgg4BOnn8%t^M!n_Ixb=TqWEk1YsU&NHZ6An3S+p%4= zyYBHaCu5l-Vw&w{-_9R9Z1gupIqcs0IW7|Xo!*)D`!_$~So`q~=e>Ww1UKF&Dh;?( z7ky{J{WC>tn>O^nQ!4shd)M*JyW=_EW7`(5vs^5=OQY+81_P(k?`N-nsR+DW z!8B<~<*&Wx0##FDE!K50yGv#?-}&q1y!L$g^zLJhA7@V3rhjrKXPCJ~PvQH8TDdtU zXR4D{JzM#2W5K;mGIuMZzDw;alz2Lg{rS@S;^~3{oKLpSJ~GvIj{nXK9~q;n8ZN~J z3EekkA75WGZNHkrw*_5t_jl}1-ezDaUp#r6|2hW61#)fmHi-%sO^V!A8(%N+a_q-{!OD(W6XNHIXGQ z|6Xz43wZLL@2|(2dd-)~z7OWec01!8>mKoA6})&Qk%CGybZ(GlcLh=(@$_H{-f9hY;gh-}ee~ z4+M_7=C%YzSj6qI+SQRLS@k;CD;rm{o_Ui3`x-_0Ia?r`z-+qpm2JXv@3 zli_0l>850*(2 zB%X<0ekVGm;8UG##g=P#*4Gw){l@?4h?Q2utxm4edzTtp`ZXukFBk0AxHsFBk)t%A zH1^Mo*V{b5*(o{nK7G)l$aJ?_E3(IiBlw$c|)~^{gr; zc)npzUQ2H0f#+p>7mhuAkbM1oLBQUH(X;no{E<6->%=MNYxorp`rP+Bd0+C~*4B9* zujl+p?s-zduxjhSy7!x-e=cFKX8IPYRFc)!RdThG@mlSr;HwKahCf)h#Afohx%_PA z(aC}jlGi-pWSP@#@I0&8@zFIqzt$BDw{BG253sxQz4p_^uJ!2$=g;1kx8UHl{fAX@ zn*T)4Yn%M%FOO@gx81U9^;$L!4*Cb&w=OMa3DM)3zhwRPtt>VT-wubA3I=>+u}hth zY;VKZeP+9UptRp~sj&aRit<9 z-amA^#uf9;_wtkP(r4${yuW^AyUVug*=yZ`cdgzy<*VH0LXkuEGld)T4l4a$@W*|| z<4Gpq2ZR>Bce;zy&v_BVkQ{{alyMU43vNxO_ zS8m(>?EaJ0(s|^n* z?A98+CI!WU`nGss%kb!kNniQe#Th_tq62>yosus)bLP5=@a{V?56(RIJaIo(N-DvG zt+kfvd;m_o(Tb2L#X62}UIm5bsVsEXe zzVoBXEx}4$j4w8EXjC&#>OSeua%bI=4^7NT%1rV9Yxi8g&-$}n=693Jh7wl&gXt`j z_8&3ec`~tOLj5Oahc5OD*QGxczhz4MrTSFGndQ}wUz0;O&k=euzuah3RGvSYn1Bc)TTgy!~4f8`4I9M~6WHd6=3Nq>~|MM;QBNuz)ALpJz$3ONO zB2Rwr?5f+!ZdTR2}~;+H#Qj z#V&J!7or)nZnYRFJ?wEh^6#-elfwTkJeBjAdM3y<#2+?)>e2M7{3uJSNSxr>{mv#w zFU=D6VR_BHBmeDv<==e^o+o$IZr*kC{yg*Fk3RZ1+v+XBTu2NdkO&Ya=QW7B5lr*bcdB&y36YGHv5(&FHld7l~7y!{eRWL z4L`1yRs5ghx7{ve;r6*93%ZXz(q>xr^iCs(OV-bJh5vDp|MtYskx74lesBJrPrs5L z$HZ?@y8rDKd#vnktvE+((Wcm}?{idA$_;~jKkL5yH22@yf=81lvHy7TUhCA8{Nu}e zzIRS@?pe%{)8Y9e#c0`+|FX?L;(vEnUS<|~D{cR6srsw+KmB;LR&3eeZSw`2I0&* zC+0tQHQ2d&j(Z*N{%zNbHB)#mpRhajhWD<_`#|Z}UcGm2WqxwIn^Dv$5Rh-%yr3d` z#?_NaIf^xZPo7(2sh#uTROv;PHcP?3%wj7Ko3c9=#{YfmZSuJ~^p^Z_Q<*FIpVE!~ zU;OuhjbVTKl7OYzX2*6bD4gK_{`nKL_)ITO1%|sqY}q?cw6OfQtU3I#M({?|zOrQ7 zi>HtLKKwT{SjQzysao)^7{fZZUsL=uy1xH*|6Mw{Loa4xa8!coJEaTRpVAB8s?0h3 z-Zp=x*z2T*b$x%QDDAdv(2EqD$E~6$-o56}g_y_J6qK?Pj16O}obIWp3!XHRG)^op z-oI{tyshS0r2|XW2_5Q)_FEADME=R&jVtQDol*LG`JK?+LNCXvJyu^89B+MKn3VZ; zIfD^n#dpo5>{%x}S39_bDR(=Vhb>A{+!;FY%-e+Sd9DwXg(enF);*to!&p@Q)1&*< zfAz(aHtN57rDqqm=VN7Ix6%FQwf*6#0xe8(3=15rc3t@OUAd_2=VBLi&s4F-i0CDp z49`PTmhRQzak@C~a^V9728T-qF&A2IqKj@GU-7GJ*43pCo!pRfPp*oU1-E9O5rzi`D9 zDb|-FW((q(79_vE`RbhF!NORC+cRu$TRFBoj{Gud!lPR^d|B)6#{aAe*s1p8mZoCcgp3DYzA~g~_+L-n zx%cgoJ(d%!TUD7RbH9Dt-m#7h&*1c`*TQ}3NrCxxE=~Cm} z(?!p|9sc{Zs%GAU&FPmmoH-q3T(>uQqucynu~Yx3U5rxt@G!SE;NgO9m4z$XkMA^f zIjT~oCUbAS{M*%>-y7Fn`aI1o`*Mro{|(0%Tz^n}>K^Cw>JW9e&xZS|lJD&aW8h$z zU}PW|zs2d_pV+6nIDQBwSSuZnJCN7B$Mxv~nO8sG1s`14pnc7CcY^1v6Zh-x*cYcY z{(E@x!H)lCkGEdWIgwoH#nE7ON#NjRXPb4)-)!$*avCseI?IpXes~&pubK}wb`j4&$+su2w$k5pwc~z*9<4XG9 zXUw)d<~NEHPK!Lbzf&Nls!43+1g4Kn=S(h4oO;n;vn^2?EC#-#^9q zCU_C|-;~xrpq)J~YE0X0m*_G5*_m^(zB2sa^n(A#*Dad4x#1~4g8+lVF{J~cYKblf zxIBN<>I>~-U|?hj(qa0`a6%rmvBu4n;R(M31B1e1C5BJz3JeSr3jHA>3^0LEL582q z0t^f%7H~9xEldeuaroyjtMT+M_7lGji8)s;+U{!WJaE1(V&(Vh$~VK% zTJg#D@4pAcsju0cM7v2b=~o=j}GRA-v=7!>s$ZjNN|{e=>hyXz*!1`D1x| zY4Jh{>lu0t^20;$>3yJ;fqgnP{IrzJ=gwZqMK;wHmRW)|MFL4{q((hdB zoORgcer?pBsB_YHuC=q|#XMMd?4{a|9j94ldFQOZdBMtE=h^=sOTsVwKm3E|8&epM zLx~~-!v%)vm0c%VPyRPvZk>KO>goJBf2MXihzXjR-Phf~9(sP|mIFIy^g2H({xWxY z$*wA97KPUi92^;u>ne@f5cnDJq2VT8^CQ1XkKwxq>n*{YAR zJGJ?gF8F^6|MX_r5hgAM0fq&sntYvyE$zQ3n)`XBMY23{_*Y#s>72|fLDL7fw@G}g zXJBHuap2>lL`RL8+RZM8$#p&1mo~rRJaY7t`R)~5b@ub;^Z#?3vqWC|aTR+2E6a`z z)ia+dnySr^mS1s6``WXN>cd4(B#f>v?q1b)W7nS5r+e>2Wc*1}-^_96gG1}Rty|5F zV?$5=cU@f+o2z?pYSbbw?SFsQ?_Zzv?a#yak3T=&USC%!%fQ62!s+sf%Q|siBAgD0 z+S}WPhzeP6ulnJB^!y96HEC&eN(tXoUODb&4*gXB`dQ5N*&E)*A9RVITE(n=Qwm!cl?aj?!{Z0MFT*;VEIdpc|Mo>j4qw*?v1t}ZC>nDUzQ%j7?6KY#Ax zW4&e@ub^oX|GZ*?4a=@h z7%X_F9cl7xd;C&HkAq3Q@8{ONn{<9FG8HP;?-rF0W2v|wV!icP_w%hA@)`bXFj+D< zaPH27qCsn)72`uyy_XN33c_*(2{T0D8NefP4@b}!q6f15KZ9q4^& zR}!^Om5I?h+df>!z}`;a&*MCk6Zh}Tmy_?v?LPS@_svV2nx6FH?fdFoBaK&Y)6v)K zyuM)P`MTe0mAGbw`HMJPC@?teDp;uL^H0g(?7RcYrpq}rBLBU5QvWcc{$y)?_}-_^ zUY_eb??qkS@u`09quQ&_gSehBRFyqs3hX-2%V^2y%@R_~KyOR zDPCv4uG_5$KU)f*Wx_3ma{kr|@j=1c9vH6>> z{qVV&{Oxv|QpK#g#=~=#YsD{!$z1Sr`|i6RCcgBn`W@_Xr=qG7+of%#Tr7oa)$C^EW#6?scsi|<`{e!HzqfV&8MsNY zFfv^b^^Q;bxOxqHjyT8N)3^9OUXW&5l<9X!yt8@oN7ZH_Cx$Nu%aj#j&)RMdf5Pi= z;(lzx!`i-1O;=d;93ao#{dgFN4eQeNA!49KC!)Na+sB$ z6R*Q(cWwW($v@5(Sa2|1&^y>J$Ujqjfy1v^Q=d=eaJ>Agyk`05-=;^b8zm|jllmP5 z*o2P!Sz5_(^?ln{e#RHO$`wwr@A&uaD^tq5O|dLe^V7K+p9v|J|2iPcv}*Q$i+G3n z&Ui(ZCkmB95uY3vD$M-K|CpWWg1G)cHI}|pax=vpcEzxqcq$m-bm32**v;xmdnFhg zc--1_{wTeD^K#w8aK(Do^N01{JeD?VVqoyP*KmOQL)fnl*8{SzE=nzwiTzyH|8>q` z?Sl5kS+kh+8D6YsSMWV@s^h+>*eBKc+v%Myht2;?E@b9py1>dE|3j*p7rqsNc&MW_n#bH&LOeqwmV2MstQQhaP>ej%%GW^%IlIdC`_T%h#xNC^7_cwZux~ z99g5pB&R6QGV4vELi^SAKU?Y({xZ}Gv8*%~u+n#k+cdp{XH7kaLrJ27sJ=oA#|;1M zxWtPkpSJ&c+w?%KHs*uFog)jB^AC9cYb^Xm~dl)vlJ3I=Q(7#SgomT6tFmQ;H~6|w7HG3u+vYaB=KgXsL&!$r zg(Qow%;bG)4Sz05b1(_?ojF{=m?xMK@nBwO(vz*fOsjXx-_H)&14pwk|jEOMHZ~t@qUOWfGo`!94 zuY3-w-Re%oTSRKurZEfBt<4KCjk|<#5iV# zOtIF6=ho{Snixv>P4|}dXs`=%2r*q`UHSTL?3NY3*(YVaE&p&Y;9h>yiTLYZXCC2l z*cxT)vD2wc?_C~;qXa+0G~Nk`6FFo*`8>E`VDZHxiFHBH%0G=>%r|#8ICD8pzTd2t zQ(DD%*qY%{&dc)IAA%Dke9xYEQVb5iig=!9O?_`$9T?~%fA?YkiO!vy4C)!e zS3Fr%n$N({B5kZGXFj#Hb#Gw3`x7PuOWRWY6>AT3+hi~^#5`Z=bneH_<7#UEO<%q5 z+~ZbUmiN%wyKk|$e|X{D!>nu!4y?^>nRan2|I9y9&A?U{GjsM)Nmd4ifFpm_SpI)~ zyi>e^+yC~5Clix}_dl4V#=yXEKwh<3oA=zG`tN&ll0OwQ^hB-wHr1(AE?ta)L7`)c zc5%$p&r|2sg!k874(FG%vx;jHXJBA>ko{NQ%IMtI|Nmc4YcJhoruTbGey0$~Y=gMV z+2yZ`FIyaDU|0|%Y|JeOq)mwR{h`?p=Lho_5aU7df{ zuP<0mih+S4q3Ge6jf?O6`uSh#NqxEg{@u%&68>1sC!@#qWN)y_-7#Jpao{m?}E$iy@omndscd~d{ zkUj&i;E#2M#d{T*OzaD%1junQI7~ZW`2T0;;gXU=I^T9)dvK)wT{rus^~@JKO79xk zT6-VolV6}1!p_JrfzjZ)tYt;Rvh?RSKkYyF;E?|J?D$`|mf!#JP~JH2U(Ldxxp(&0 z%kyT6HW@Q8I7l75b4+G?{(U>YADdqOZ;Df|O;%;-aXo$f##hVu>zU{GF}G(VKH^AR z$H2gl$#ngPzE6*E@tnrvJ#Wvjeg7Ih`*q6S;b<6dD6SuDHsJ!q% zkbz-BNcVipHCY8W@74b9JbahU;(z73gO&Y96Xm%JEhCOGJ~Ub(?jv*OyVB!tn}dxv zzwYVnYPHdg+|%*tDC4Zvf}tBHDKRh@s{P%R7#1%6?8S*6EWP2gxfdEd+<*1K&i6+% z>$wZ98;&vlTBpcVGa)WFXS-g=s%SnryIWOt857t}F^8Ox-hD43Ysa$8CBiYR3=CB+ zU(Q(cF3Z^!w>WF5Q*m*ziJh(U<8#yhUAtkIlM`>cL$~a7lIWv~0%`VF?<>|2`U@d!mp10rNb~@2N4>3=9m0-$17d kHB>0K56n?Sf9e_87_J9hiu+KfsSR?9r>mdKI;Vst0L>%+F8}}l literal 0 HcmV?d00001 diff --git a/homeassistant/components/frontend/www_static/frontend.html b/homeassistant/components/frontend/www_static/frontend.html index 73b2ac1b7dd..cf19d314f24 100644 --- a/homeassistant/components/frontend/www_static/frontend.html +++ b/homeassistant/components/frontend/www_static/frontend.html @@ -1,6 +1,6 @@ -
\ No newline at end of file + } \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/home-assistant-polymer b/homeassistant/components/frontend/www_static/home-assistant-polymer index 62e494bd045..f29b1062b30 160000 --- a/homeassistant/components/frontend/www_static/home-assistant-polymer +++ b/homeassistant/components/frontend/www_static/home-assistant-polymer @@ -1 +1 @@ -Subproject commit 62e494bd04509e8d9b73354b0e17d3381955e0c8 +Subproject commit f29b1062b30c76ceeea87fd426a042d98358394a diff --git a/homeassistant/components/frontend/www_static/manifest.json b/homeassistant/components/frontend/www_static/manifest.json index 69143ce5179..3d0eb5fa443 100644 --- a/homeassistant/components/frontend/www_static/manifest.json +++ b/homeassistant/components/frontend/www_static/manifest.json @@ -5,10 +5,14 @@ "display": "standalone", "icons": [ { - "src": "\/static\/favicon-192x192.png", + "src": "/static/favicon-192x192.png", "sizes": "192x192", - "type": "image\/png", - "density": "4.0" + "type": "image/png", + }, + { + "src": "/static/favicon-384x384.png", + "sizes": "384x384", + "type": "image/png", } ] } diff --git a/homeassistant/components/frontend/www_static/webcomponents-lite.min.js b/homeassistant/components/frontend/www_static/webcomponents-lite.min.js index 3a3fd4e8564..4f8af01fd15 100644 --- a/homeassistant/components/frontend/www_static/webcomponents-lite.min.js +++ b/homeassistant/components/frontend/www_static/webcomponents-lite.min.js @@ -7,6 +7,6 @@ * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt */ -// @version 0.7.17 -!function(){window.WebComponents=window.WebComponents||{flags:{}};var e="webcomponents-lite.js",t=document.querySelector('script[src*="'+e+'"]'),n={};if(!n.noOpts){if(location.search.slice(1).split("&").forEach(function(e){var t,r=e.split("=");r[0]&&(t=r[0].match(/wc-(.+)/))&&(n[t[1]]=r[1]||!0)}),t)for(var r,o=0;r=t.attributes[o];o++)"src"!==r.name&&(n[r.name]=r.value||!0);if(n.log&&n.log.split){var i=n.log.split(",");n.log={},i.forEach(function(e){n.log[e]=!0})}else n.log={}}n.register&&(window.CustomElements=window.CustomElements||{flags:{}},window.CustomElements.flags.register=n.register),WebComponents.flags=n}(),function(e){"use strict";function t(e){return void 0!==h[e]}function n(){s.call(this),this._isInvalid=!0}function r(e){return""==e&&n.call(this),e.toLowerCase()}function o(e){var t=e.charCodeAt(0);return t>32&&127>t&&-1==[34,35,60,62,63,96].indexOf(t)?e:encodeURIComponent(e)}function i(e){var t=e.charCodeAt(0);return t>32&&127>t&&-1==[34,35,60,62,96].indexOf(t)?e:encodeURIComponent(e)}function a(e,a,s){function c(e){g.push(e)}var d=a||"scheme start",u=0,l="",_=!1,w=!1,g=[];e:for(;(e[u-1]!=p||0==u)&&!this._isInvalid;){var b=e[u];switch(d){case"scheme start":if(!b||!m.test(b)){if(a){c("Invalid scheme.");break e}l="",d="no scheme";continue}l+=b.toLowerCase(),d="scheme";break;case"scheme":if(b&&v.test(b))l+=b.toLowerCase();else{if(":"!=b){if(a){if(p==b)break e;c("Code point not allowed in scheme: "+b);break e}l="",u=0,d="no scheme";continue}if(this._scheme=l,l="",a)break e;t(this._scheme)&&(this._isRelative=!0),d="file"==this._scheme?"relative":this._isRelative&&s&&s._scheme==this._scheme?"relative or authority":this._isRelative?"authority first slash":"scheme data"}break;case"scheme data":"?"==b?(this._query="?",d="query"):"#"==b?(this._fragment="#",d="fragment"):p!=b&&" "!=b&&"\n"!=b&&"\r"!=b&&(this._schemeData+=o(b));break;case"no scheme":if(s&&t(s._scheme)){d="relative";continue}c("Missing scheme."),n.call(this);break;case"relative or authority":if("/"!=b||"/"!=e[u+1]){c("Expected /, got: "+b),d="relative";continue}d="authority ignore slashes";break;case"relative":if(this._isRelative=!0,"file"!=this._scheme&&(this._scheme=s._scheme),p==b){this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query=s._query,this._username=s._username,this._password=s._password;break e}if("/"==b||"\\"==b)"\\"==b&&c("\\ is an invalid code point."),d="relative slash";else if("?"==b)this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query="?",this._username=s._username,this._password=s._password,d="query";else{if("#"!=b){var y=e[u+1],E=e[u+2];("file"!=this._scheme||!m.test(b)||":"!=y&&"|"!=y||p!=E&&"/"!=E&&"\\"!=E&&"?"!=E&&"#"!=E)&&(this._host=s._host,this._port=s._port,this._username=s._username,this._password=s._password,this._path=s._path.slice(),this._path.pop()),d="relative path";continue}this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query=s._query,this._fragment="#",this._username=s._username,this._password=s._password,d="fragment"}break;case"relative slash":if("/"!=b&&"\\"!=b){"file"!=this._scheme&&(this._host=s._host,this._port=s._port,this._username=s._username,this._password=s._password),d="relative path";continue}"\\"==b&&c("\\ is an invalid code point."),d="file"==this._scheme?"file host":"authority ignore slashes";break;case"authority first slash":if("/"!=b){c("Expected '/', got: "+b),d="authority ignore slashes";continue}d="authority second slash";break;case"authority second slash":if(d="authority ignore slashes","/"!=b){c("Expected '/', got: "+b);continue}break;case"authority ignore slashes":if("/"!=b&&"\\"!=b){d="authority";continue}c("Expected authority, got: "+b);break;case"authority":if("@"==b){_&&(c("@ already seen."),l+="%40"),_=!0;for(var L=0;L>>0)+(t++ +"__")};n.prototype={set:function(t,n){var r=t[this.name];return r&&r[0]===t?r[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),function(e){function t(e){b.push(e),g||(g=!0,m(r))}function n(e){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(e)||e}function r(){g=!1;var e=b;b=[],e.sort(function(e,t){return e.uid_-t.uid_});var t=!1;e.forEach(function(e){var n=e.takeRecords();o(e),n.length&&(e.callback_(n,e),t=!0)}),t&&r()}function o(e){e.nodes_.forEach(function(t){var n=v.get(t);n&&n.forEach(function(t){t.observer===e&&t.removeTransientObservers()})})}function i(e,t){for(var n=e;n;n=n.parentNode){var r=v.get(n);if(r)for(var o=0;o0){var o=n[r-1],i=f(o,e);if(i)return void(n[r-1]=i)}else t(this.observer);n[r]=e},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(e){var t=this.options;t.attributes&&e.addEventListener("DOMAttrModified",this,!0),t.characterData&&e.addEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.addEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(e){var t=this.options;t.attributes&&e.removeEventListener("DOMAttrModified",this,!0),t.characterData&&e.removeEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.removeEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(e){if(e!==this.target){this.addListeners_(e),this.transientObservedNodes.push(e);var t=v.get(e);t||v.set(e,t=[]),t.push(this)}},removeTransientObservers:function(){var e=this.transientObservedNodes;this.transientObservedNodes=[],e.forEach(function(e){this.removeListeners_(e);for(var t=v.get(e),n=0;n":return">";case" ":return" "}}function t(t){return t.replace(a,e)}var n="template",r=document.implementation.createHTMLDocument("template"),o=!0;HTMLTemplateElement=function(){},HTMLTemplateElement.prototype=Object.create(HTMLElement.prototype),HTMLTemplateElement.decorate=function(e){e.content||(e.content=r.createDocumentFragment());for(var n;n=e.firstChild;)e.content.appendChild(n);if(o)try{Object.defineProperty(e,"innerHTML",{get:function(){for(var e="",n=this.content.firstChild;n;n=n.nextSibling)e+=n.outerHTML||t(n.data);return e},set:function(e){for(r.body.innerHTML=e,HTMLTemplateElement.bootstrap(r);this.content.firstChild;)this.content.removeChild(this.content.firstChild);for(;r.body.firstChild;)this.content.appendChild(r.body.firstChild)},configurable:!0})}catch(i){o=!1}},HTMLTemplateElement.bootstrap=function(e){for(var t,r=e.querySelectorAll(n),o=0,i=r.length;i>o&&(t=r[o]);o++)HTMLTemplateElement.decorate(t)},document.addEventListener("DOMContentLoaded",function(){HTMLTemplateElement.bootstrap(document)});var i=document.createElement;document.createElement=function(){"use strict";var e=i.apply(document,arguments);return"template"==e.localName&&HTMLTemplateElement.decorate(e),e};var a=/[&\u00A0<>]/g}(),function(e){"use strict";if(!window.performance){var t=Date.now();window.performance={now:function(){return Date.now()-t}}}window.requestAnimationFrame||(window.requestAnimationFrame=function(){var e=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame;return e?function(t){return e(function(){t(performance.now())})}:function(e){return window.setTimeout(e,1e3/60)}}()),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(){return window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(e){clearTimeout(e)}}());var n=function(){var e=document.createEvent("Event");return e.initEvent("foo",!0,!0),e.preventDefault(),e.defaultPrevented}();if(!n){var r=Event.prototype.preventDefault;Event.prototype.preventDefault=function(){this.cancelable&&(r.call(this),Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}}))}}var o=/Trident/.test(navigator.userAgent);if((!window.CustomEvent||o&&"function"!=typeof window.CustomEvent)&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.CustomEvent.prototype=window.Event.prototype),!window.Event||o&&"function"!=typeof window.Event){var i=window.Event;window.Event=function(e,t){t=t||{};var n=document.createEvent("Event");return n.initEvent(e,Boolean(t.bubbles),Boolean(t.cancelable)),n},window.Event.prototype=i.prototype}}(window.WebComponents),window.HTMLImports=window.HTMLImports||{flags:{}},function(e){function t(e,t){t=t||p,r(function(){i(e,t)},t)}function n(e){return"complete"===e.readyState||e.readyState===_}function r(e,t){if(n(t))e&&e();else{var o=function(){("complete"===t.readyState||t.readyState===_)&&(t.removeEventListener(w,o),r(e,t))};t.addEventListener(w,o)}}function o(e){e.target.__loaded=!0}function i(e,t){function n(){c==d&&e&&e({allImports:s,loadedImports:u,errorImports:l})}function r(e){o(e),u.push(this),c++,n()}function i(e){l.push(this),c++,n()}var s=t.querySelectorAll("link[rel=import]"),c=0,d=s.length,u=[],l=[];if(d)for(var h,f=0;d>f&&(h=s[f]);f++)a(h)?(c++,n()):(h.addEventListener("load",r),h.addEventListener("error",i));else n()}function a(e){return l?e.__loaded||e["import"]&&"loading"!==e["import"].readyState:e.__importParsed}function s(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)c(t)&&d(t)}function c(e){return"link"===e.localName&&"import"===e.rel}function d(e){var t=e["import"];t?o({target:e}):(e.addEventListener("load",o),e.addEventListener("error",o))}var u="import",l=Boolean(u in document.createElement("link")),h=Boolean(window.ShadowDOMPolyfill),f=function(e){return h?window.ShadowDOMPolyfill.wrapIfNeeded(e):e},p=f(document),m={get:function(){var e=window.HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return f(e)},configurable:!0};Object.defineProperty(document,"_currentScript",m),Object.defineProperty(p,"_currentScript",m);var v=/Trident/.test(navigator.userAgent),_=v?"complete":"interactive",w="readystatechange";l&&(new MutationObserver(function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.addedNodes&&s(t.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var e,t=document.querySelectorAll("link[rel=import]"),n=0,r=t.length;r>n&&(e=t[n]);n++)d(e)}()),t(function(e){window.HTMLImports.ready=!0,window.HTMLImports.readyTime=(new Date).getTime();var t=p.createEvent("CustomEvent");t.initCustomEvent("HTMLImportsLoaded",!0,!0,e),p.dispatchEvent(t)}),e.IMPORT_LINK_TYPE=u,e.useNative=l,e.rootDocument=p,e.whenReady=t,e.isIE=v}(window.HTMLImports),function(e){var t=[],n=function(e){t.push(e)},r=function(){t.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=r}(window.HTMLImports),window.HTMLImports.addModule(function(e){var t=/(url\()([^)]*)(\))/g,n=/(@import[\s]+(?!url\())([^;]*)(;)/g,r={resolveUrlsInStyle:function(e,t){var n=e.ownerDocument,r=n.createElement("a");return e.textContent=this.resolveUrlsInCssText(e.textContent,t,r),e},resolveUrlsInCssText:function(e,r,o){var i=this.replaceUrls(e,o,r,t);return i=this.replaceUrls(i,o,r,n)},replaceUrls:function(e,t,n,r){return e.replace(r,function(e,r,o,i){var a=o.replace(/["']/g,"");return n&&(a=new URL(a,n).href),t.href=a,a=t.href,r+"'"+a+"'"+i})}};e.path=r}),window.HTMLImports.addModule(function(e){var t={async:!0,ok:function(e){return e.status>=200&&e.status<300||304===e.status||0===e.status},load:function(n,r,o){var i=new XMLHttpRequest;return(e.flags.debug||e.flags.bust)&&(n+="?"+Math.random()),i.open("GET",n,t.async),i.addEventListener("readystatechange",function(e){if(4===i.readyState){var n=null;try{var a=i.getResponseHeader("Location");a&&(n="/"===a.substr(0,1)?location.origin+a:a)}catch(e){console.error(e.message)}r.call(o,!t.ok(i)&&i,i.response||i.responseText,n)}}),i.send(),i},loadDocument:function(e,t,n){this.load(e,t,n).responseType="document"}};e.xhr=t}),window.HTMLImports.addModule(function(e){var t=e.xhr,n=e.flags,r=function(e,t){this.cache={},this.onload=e,this.oncomplete=t,this.inflight=0,this.pending={}};r.prototype={addNodes:function(e){this.inflight+=e.length;for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)this.require(t);this.checkDone()},addNode:function(e){this.inflight++,this.require(e),this.checkDone()},require:function(e){var t=e.src||e.href;e.__nodeUrl=t,this.dedupe(t,e)||this.fetch(t,e)},dedupe:function(e,t){if(this.pending[e])return this.pending[e].push(t),!0;return this.cache[e]?(this.onload(e,t,this.cache[e]),this.tail(),!0):(this.pending[e]=[t],!1)},fetch:function(e,r){if(n.load&&console.log("fetch",e,r),e)if(e.match(/^data:/)){var o=e.split(","),i=o[0],a=o[1];a=i.indexOf(";base64")>-1?atob(a):decodeURIComponent(a),setTimeout(function(){this.receive(e,r,null,a)}.bind(this),0)}else{var s=function(t,n,o){this.receive(e,r,t,n,o)}.bind(this);t.load(e,s)}else setTimeout(function(){this.receive(e,r,{error:"href must be specified"},null)}.bind(this),0)},receive:function(e,t,n,r,o){this.cache[e]=r;for(var i,a=this.pending[e],s=0,c=a.length;c>s&&(i=a[s]);s++)this.onload(e,i,r,n,o),this.tail();this.pending[e]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},e.Loader=r}),window.HTMLImports.addModule(function(e){var t=function(e){this.addCallback=e,this.mo=new MutationObserver(this.handler.bind(this))};t.prototype={handler:function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)"childList"===t.type&&t.addedNodes.length&&this.addedNodes(t.addedNodes)},addedNodes:function(e){this.addCallback&&this.addCallback(e);for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.children&&t.children.length&&this.addedNodes(t.children)},observe:function(e){this.mo.observe(e,{childList:!0,subtree:!0})}},e.Observer=t}),window.HTMLImports.addModule(function(e){function t(e){return"link"===e.localName&&e.rel===u}function n(e){var t=r(e);return"data:text/javascript;charset=utf-8,"+encodeURIComponent(t)}function r(e){return e.textContent+o(e)}function o(e){var t=e.ownerDocument;t.__importedScripts=t.__importedScripts||0;var n=e.ownerDocument.baseURI,r=t.__importedScripts?"-"+t.__importedScripts:"";return t.__importedScripts++,"\n//# sourceURL="+n+r+".js\n"}function i(e){var t=e.ownerDocument.createElement("style");return t.textContent=e.textContent,a.resolveUrlsInStyle(t),t}var a=e.path,s=e.rootDocument,c=e.flags,d=e.isIE,u=e.IMPORT_LINK_TYPE,l="link[rel="+u+"]",h={documentSelectors:l,importsSelectors:[l,"link[rel=stylesheet]:not([type])","style:not([type])","script:not([type])",'script[type="application/javascript"]','script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},dynamicElements:[],parseNext:function(){var e=this.nextToParse();e&&this.parse(e)},parse:function(e){if(this.isParsed(e))return void(c.parse&&console.log("[%s] is already parsed",e.localName));var t=this[this.map[e.localName]];t&&(this.markParsing(e),t.call(this,e))},parseDynamic:function(e,t){this.dynamicElements.push(e),t||this.parseNext()},markParsing:function(e){c.parse&&console.log("parsing",e),this.parsingElement=e},markParsingComplete:function(e){e.__importParsed=!0,this.markDynamicParsingComplete(e),e.__importElement&&(e.__importElement.__importParsed=!0,this.markDynamicParsingComplete(e.__importElement)),this.parsingElement=null,c.parse&&console.log("completed",e)},markDynamicParsingComplete:function(e){var t=this.dynamicElements.indexOf(e);t>=0&&this.dynamicElements.splice(t,1)},parseImport:function(e){if(e["import"]=e.__doc,window.HTMLImports.__importsParsingHook&&window.HTMLImports.__importsParsingHook(e),e["import"]&&(e["import"].__importParsed=!0),this.markParsingComplete(e),e.__resource&&!e.__error?e.dispatchEvent(new CustomEvent("load",{bubbles:!1})):e.dispatchEvent(new CustomEvent("error",{bubbles:!1})),e.__pending)for(var t;e.__pending.length;)t=e.__pending.shift(),t&&t({target:e});this.parseNext()},parseLink:function(e){t(e)?this.parseImport(e):(e.href=e.href,this.parseGeneric(e))},parseStyle:function(e){var t=e;e=i(e),t.__appliedElement=e,e.__importElement=t,this.parseGeneric(e)},parseGeneric:function(e){this.trackElement(e),this.addElementToDocument(e)},rootImportForElement:function(e){for(var t=e;t.ownerDocument.__importLink;)t=t.ownerDocument.__importLink;return t},addElementToDocument:function(e){var t=this.rootImportForElement(e.__importElement||e);t.parentNode.insertBefore(e,t)},trackElement:function(e,t){var n=this,r=function(o){e.removeEventListener("load",r),e.removeEventListener("error",r),t&&t(o),n.markParsingComplete(e),n.parseNext()};if(e.addEventListener("load",r),e.addEventListener("error",r),d&&"style"===e.localName){var o=!1;if(-1==e.textContent.indexOf("@import"))o=!0;else if(e.sheet){o=!0;for(var i,a=e.sheet.cssRules,s=a?a.length:0,c=0;s>c&&(i=a[c]);c++)i.type===CSSRule.IMPORT_RULE&&(o=o&&Boolean(i.styleSheet))}o&&setTimeout(function(){e.dispatchEvent(new CustomEvent("load",{bubbles:!1}))})}},parseScript:function(t){var r=document.createElement("script");r.__importElement=t,r.src=t.src?t.src:n(t),e.currentScript=t,this.trackElement(r,function(t){r.parentNode&&r.parentNode.removeChild(r),e.currentScript=null}),this.addElementToDocument(r)},nextToParse:function(){return this._mayParse=[],!this.parsingElement&&(this.nextToParseInDoc(s)||this.nextToParseDynamic())},nextToParseInDoc:function(e,n){if(e&&this._mayParse.indexOf(e)<0){this._mayParse.push(e);for(var r,o=e.querySelectorAll(this.parseSelectorsForNode(e)),i=0,a=o.length;a>i&&(r=o[i]);i++)if(!this.isParsed(r))return this.hasResource(r)?t(r)?this.nextToParseInDoc(r.__doc,r):r:void 0}return n},nextToParseDynamic:function(){return this.dynamicElements[0]},parseSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===s?this.documentSelectors:this.importsSelectors},isParsed:function(e){return e.__importParsed},needsDynamicParsing:function(e){return this.dynamicElements.indexOf(e)>=0},hasResource:function(e){return t(e)&&void 0===e.__doc?!1:!0}};e.parser=h,e.IMPORT_SELECTOR=l}),window.HTMLImports.addModule(function(e){function t(e){return n(e,a)}function n(e,t){return"link"===e.localName&&e.getAttribute("rel")===t}function r(e){return!!Object.getOwnPropertyDescriptor(e,"baseURI")}function o(e,t){var n=document.implementation.createHTMLDocument(a);n._URL=t;var o=n.createElement("base");o.setAttribute("href",t),n.baseURI||r(n)||Object.defineProperty(n,"baseURI",{value:t});var i=n.createElement("meta");return i.setAttribute("charset","utf-8"),n.head.appendChild(i),n.head.appendChild(o),n.body.innerHTML=e,window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(n),n}var i=e.flags,a=e.IMPORT_LINK_TYPE,s=e.IMPORT_SELECTOR,c=e.rootDocument,d=e.Loader,u=e.Observer,l=e.parser,h={documents:{},documentPreloadSelectors:s,importsPreloadSelectors:[s].join(","),loadNode:function(e){f.addNode(e)},loadSubtree:function(e){var t=this.marshalNodes(e);f.addNodes(t)},marshalNodes:function(e){return e.querySelectorAll(this.loadSelectorsForNode(e))},loadSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===c?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(e,n,r,a,s){if(i.load&&console.log("loaded",e,n),n.__resource=r,n.__error=a,t(n)){var c=this.documents[e];void 0===c&&(c=a?null:o(r,s||e),c&&(c.__importLink=n,this.bootDocument(c)),this.documents[e]=c),n.__doc=c}l.parseNext()},bootDocument:function(e){this.loadSubtree(e),this.observer.observe(e),l.parseNext()},loadedAll:function(){l.parseNext()}},f=new d(h.loaded.bind(h),h.loadedAll.bind(h));if(h.observer=new u,!document.baseURI){var p={get:function(){var e=document.querySelector("base");return e?e.href:window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",p),Object.defineProperty(c,"baseURI",p)}e.importer=h,e.importLoader=f}),window.HTMLImports.addModule(function(e){var t=e.parser,n=e.importer,r={added:function(e){for(var r,o,i,a,s=0,c=e.length;c>s&&(a=e[s]);s++)r||(r=a.ownerDocument,o=t.isParsed(r)),i=this.shouldLoadNode(a),i&&n.loadNode(a),this.shouldParseNode(a)&&o&&t.parseDynamic(a,i)},shouldLoadNode:function(e){return 1===e.nodeType&&o.call(e,n.loadSelectorsForNode(e))},shouldParseNode:function(e){return 1===e.nodeType&&o.call(e,t.parseSelectorsForNode(e))}};n.observer.addCallback=r.added.bind(r);var o=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector}),function(e){function t(){window.HTMLImports.importer.bootDocument(r)}var n=e.initializeModules;e.isIE;if(!e.useNative){n();var r=e.rootDocument;"complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?t():document.addEventListener("DOMContentLoaded",t)}}(window.HTMLImports),window.CustomElements=window.CustomElements||{flags:{}},function(e){var t=e.flags,n=[],r=function(e){n.push(e)},o=function(){n.forEach(function(t){t(e)})};e.addModule=r,e.initializeModules=o,e.hasNative=Boolean(document.registerElement),e.isIE=/Trident/.test(navigator.userAgent),e.useNative=!t.register&&e.hasNative&&!window.ShadowDOMPolyfill&&(!window.HTMLImports||window.HTMLImports.useNative)}(window.CustomElements),window.CustomElements.addModule(function(e){function t(e,t){n(e,function(e){return t(e)?!0:void r(e,t)}),r(e,t)}function n(e,t,r){var o=e.firstElementChild;if(!o)for(o=e.firstChild;o&&o.nodeType!==Node.ELEMENT_NODE;)o=o.nextSibling;for(;o;)t(o,r)!==!0&&n(o,t,r),o=o.nextElementSibling;return null}function r(e,n){for(var r=e.shadowRoot;r;)t(r,n),r=r.olderShadowRoot}function o(e,t){i(e,t,[])}function i(e,t,n){if(e=window.wrap(e),!(n.indexOf(e)>=0)){n.push(e);for(var r,o=e.querySelectorAll("link[rel="+a+"]"),s=0,c=o.length;c>s&&(r=o[s]);s++)r["import"]&&i(r["import"],t,n);t(e)}}var a=window.HTMLImports?window.HTMLImports.IMPORT_LINK_TYPE:"none";e.forDocumentTree=o,e.forSubtree=t}),window.CustomElements.addModule(function(e){function t(e,t){return n(e,t)||r(e,t)}function n(t,n){return e.upgrade(t,n)?!0:void(n&&a(t))}function r(e,t){b(e,function(e){return n(e,t)?!0:void 0})}function o(e){T.push(e),L||(L=!0,setTimeout(i))}function i(){L=!1;for(var e,t=T,n=0,r=t.length;r>n&&(e=t[n]);n++)e();T=[]}function a(e){E?o(function(){s(e)}):s(e)}function s(e){e.__upgraded__&&!e.__attached&&(e.__attached=!0,e.attachedCallback&&e.attachedCallback())}function c(e){d(e),b(e,function(e){d(e)})}function d(e){E?o(function(){u(e)}):u(e)}function u(e){e.__upgraded__&&e.__attached&&(e.__attached=!1,e.detachedCallback&&e.detachedCallback())}function l(e){for(var t=e,n=window.wrap(document);t;){if(t==n)return!0;t=t.parentNode||t.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&t.host}}function h(e){if(e.shadowRoot&&!e.shadowRoot.__watched){g.dom&&console.log("watching shadow-root for: ",e.localName);for(var t=e.shadowRoot;t;)m(t),t=t.olderShadowRoot}}function f(e,n){if(g.dom){var r=n[0];if(r&&"childList"===r.type&&r.addedNodes&&r.addedNodes){for(var o=r.addedNodes[0];o&&o!==document&&!o.host;)o=o.parentNode;var i=o&&(o.URL||o._URL||o.host&&o.host.localName)||"";i=i.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",n.length,i||"")}var a=l(e);n.forEach(function(e){"childList"===e.type&&(M(e.addedNodes,function(e){e.localName&&t(e,a)}),M(e.removedNodes,function(e){e.localName&&c(e)}))}),g.dom&&console.groupEnd()}function p(e){for(e=window.wrap(e),e||(e=window.wrap(document));e.parentNode;)e=e.parentNode;var t=e.__observer;t&&(f(e,t.takeRecords()),i())}function m(e){if(!e.__observer){var t=new MutationObserver(f.bind(this,e));t.observe(e,{childList:!0,subtree:!0}),e.__observer=t}}function v(e){e=window.wrap(e),g.dom&&console.group("upgradeDocument: ",e.baseURI.split("/").pop());var n=e===window.wrap(document); -t(e,n),m(e),g.dom&&console.groupEnd()}function _(e){y(e,v)}function w(e){HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(e),t(e)}var g=e.flags,b=e.forSubtree,y=e.forDocumentTree,E=window.MutationObserver._isPolyfilled&&g["throttle-attached"];e.hasPolyfillMutations=E,e.hasThrottledAttached=E;var L=!1,T=[],M=Array.prototype.forEach.call.bind(Array.prototype.forEach),N=Element.prototype.createShadowRoot;N&&(Element.prototype.createShadowRoot=function(){var e=N.call(this);return window.CustomElements.watchShadow(this),e}),e.watchShadow=h,e.upgradeDocumentTree=_,e.upgradeDocument=v,e.upgradeSubtree=r,e.upgradeAll=w,e.attached=a,e.takeRecords=p}),window.CustomElements.addModule(function(e){function t(t,r){if(!t.__upgraded__&&t.nodeType===Node.ELEMENT_NODE){var o=t.getAttribute("is"),i=e.getRegisteredDefinition(t.localName)||e.getRegisteredDefinition(o);if(i&&(o&&i.tag==t.localName||!o&&!i["extends"]))return n(t,i,r)}}function n(t,n,o){return a.upgrade&&console.group("upgrade:",t.localName),n.is&&t.setAttribute("is",n.is),r(t,n),t.__upgraded__=!0,i(t),o&&e.attached(t),e.upgradeSubtree(t,o),a.upgrade&&console.groupEnd(),t}function r(e,t){Object.__proto__?e.__proto__=t.prototype:(o(e,t.prototype,t["native"]),e.__proto__=t.prototype)}function o(e,t,n){for(var r={},o=t;o!==n&&o!==HTMLElement.prototype;){for(var i,a=Object.getOwnPropertyNames(o),s=0;i=a[s];s++)r[i]||(Object.defineProperty(e,i,Object.getOwnPropertyDescriptor(o,i)),r[i]=1);o=Object.getPrototypeOf(o)}}function i(e){e.createdCallback&&e.createdCallback()}var a=e.flags;e.upgrade=t,e.upgradeWithDefinition=n,e.implementPrototype=r}),window.CustomElements.addModule(function(e){function t(t,r){var c=r||{};if(!t)throw new Error("document.registerElement: first argument `name` must not be empty");if(t.indexOf("-")<0)throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(t)+"'.");if(o(t))throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '"+String(t)+"'. The type name is invalid.");if(d(t))throw new Error("DuplicateDefinitionError: a type with name '"+String(t)+"' is already registered");return c.prototype||(c.prototype=Object.create(HTMLElement.prototype)),c.__name=t.toLowerCase(),c.lifecycle=c.lifecycle||{},c.ancestry=i(c["extends"]),a(c),s(c),n(c.prototype),u(c.__name,c),c.ctor=l(c),c.ctor.prototype=c.prototype,c.prototype.constructor=c.ctor,e.ready&&_(document),c.ctor}function n(e){if(!e.setAttribute._polyfilled){var t=e.setAttribute;e.setAttribute=function(e,n){r.call(this,e,n,t)};var n=e.removeAttribute;e.removeAttribute=function(e){r.call(this,e,null,n)},e.setAttribute._polyfilled=!0}}function r(e,t,n){e=e.toLowerCase();var r=this.getAttribute(e);n.apply(this,arguments);var o=this.getAttribute(e);this.attributeChangedCallback&&o!==r&&this.attributeChangedCallback(e,r,o)}function o(e){for(var t=0;t=0&&b(r,HTMLElement),r)}function p(e,t){var n=e[t];e[t]=function(){var e=n.apply(this,arguments);return w(e),e}}var m,v=e.isIE,_=e.upgradeDocumentTree,w=e.upgradeAll,g=e.upgradeWithDefinition,b=e.implementPrototype,y=e.useNative,E=["annotation-xml","color-profile","font-face","font-face-src","font-face-uri","font-face-format","font-face-name","missing-glyph"],L={},T="http://www.w3.org/1999/xhtml",M=document.createElement.bind(document),N=document.createElementNS.bind(document);m=Object.__proto__||y?function(e,t){return e instanceof t}:function(e,t){if(e instanceof t)return!0;for(var n=e;n;){if(n===t.prototype)return!0;n=n.__proto__}return!1},p(Node.prototype,"cloneNode"),p(document,"importNode"),v&&!function(){var e=document.importNode;document.importNode=function(){var t=e.apply(document,arguments);if(t.nodeType==t.DOCUMENT_FRAGMENT_NODE){var n=document.createDocumentFragment();return n.appendChild(t),n}return t}}(),document.registerElement=t,document.createElement=f,document.createElementNS=h,e.registry=L,e["instanceof"]=m,e.reservedTagList=E,e.getRegisteredDefinition=d,document.register=document.registerElement}),function(e){function t(){i(window.wrap(document)),window.CustomElements.ready=!0;var e=window.requestAnimationFrame||function(e){setTimeout(e,16)};e(function(){setTimeout(function(){window.CustomElements.readyTime=Date.now(),window.HTMLImports&&(window.CustomElements.elapsed=window.CustomElements.readyTime-window.HTMLImports.readyTime),document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})})}var n=e.useNative,r=e.initializeModules;e.isIE;if(n){var o=function(){};e.watchShadow=o,e.upgrade=o,e.upgradeAll=o,e.upgradeDocumentTree=o,e.upgradeSubtree=o,e.takeRecords=o,e["instanceof"]=function(e,t){return e instanceof t}}else r();var i=e.upgradeDocumentTree,a=e.upgradeDocument;if(window.wrap||(window.ShadowDOMPolyfill?(window.wrap=window.ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=window.ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}),window.HTMLImports&&(window.HTMLImports.__importsParsingHook=function(e){e["import"]&&a(wrap(e["import"]))}),"complete"===document.readyState||e.flags.eager)t();else if("interactive"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var s=window.HTMLImports&&!window.HTMLImports.ready?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(s,t)}else t()}(window.CustomElements),function(e){var t=document.createElement("style");t.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \n";var n=document.querySelector("head");n.insertBefore(t,n.firstChild)}(window.WebComponents); \ No newline at end of file +// @version 0.7.18 +!function(){window.WebComponents=window.WebComponents||{flags:{}};var e="webcomponents-lite.js",t=document.querySelector('script[src*="'+e+'"]'),n={};if(!n.noOpts){if(location.search.slice(1).split("&").forEach(function(e){var t,r=e.split("=");r[0]&&(t=r[0].match(/wc-(.+)/))&&(n[t[1]]=r[1]||!0)}),t)for(var r,o=0;r=t.attributes[o];o++)"src"!==r.name&&(n[r.name]=r.value||!0);if(n.log&&n.log.split){var i=n.log.split(",");n.log={},i.forEach(function(e){n.log[e]=!0})}else n.log={}}n.register&&(window.CustomElements=window.CustomElements||{flags:{}},window.CustomElements.flags.register=n.register),WebComponents.flags=n}(),function(e){"use strict";function t(e){return void 0!==h[e]}function n(){s.call(this),this._isInvalid=!0}function r(e){return""==e&&n.call(this),e.toLowerCase()}function o(e){var t=e.charCodeAt(0);return t>32&&127>t&&-1==[34,35,60,62,63,96].indexOf(t)?e:encodeURIComponent(e)}function i(e){var t=e.charCodeAt(0);return t>32&&127>t&&-1==[34,35,60,62,96].indexOf(t)?e:encodeURIComponent(e)}function a(e,a,s){function c(e){g.push(e)}var d=a||"scheme start",u=0,l="",w=!1,_=!1,g=[];e:for(;(e[u-1]!=p||0==u)&&!this._isInvalid;){var b=e[u];switch(d){case"scheme start":if(!b||!m.test(b)){if(a){c("Invalid scheme.");break e}l="",d="no scheme";continue}l+=b.toLowerCase(),d="scheme";break;case"scheme":if(b&&v.test(b))l+=b.toLowerCase();else{if(":"!=b){if(a){if(p==b)break e;c("Code point not allowed in scheme: "+b);break e}l="",u=0,d="no scheme";continue}if(this._scheme=l,l="",a)break e;t(this._scheme)&&(this._isRelative=!0),d="file"==this._scheme?"relative":this._isRelative&&s&&s._scheme==this._scheme?"relative or authority":this._isRelative?"authority first slash":"scheme data"}break;case"scheme data":"?"==b?(this._query="?",d="query"):"#"==b?(this._fragment="#",d="fragment"):p!=b&&" "!=b&&"\n"!=b&&"\r"!=b&&(this._schemeData+=o(b));break;case"no scheme":if(s&&t(s._scheme)){d="relative";continue}c("Missing scheme."),n.call(this);break;case"relative or authority":if("/"!=b||"/"!=e[u+1]){c("Expected /, got: "+b),d="relative";continue}d="authority ignore slashes";break;case"relative":if(this._isRelative=!0,"file"!=this._scheme&&(this._scheme=s._scheme),p==b){this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query=s._query,this._username=s._username,this._password=s._password;break e}if("/"==b||"\\"==b)"\\"==b&&c("\\ is an invalid code point."),d="relative slash";else if("?"==b)this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query="?",this._username=s._username,this._password=s._password,d="query";else{if("#"!=b){var y=e[u+1],E=e[u+2];("file"!=this._scheme||!m.test(b)||":"!=y&&"|"!=y||p!=E&&"/"!=E&&"\\"!=E&&"?"!=E&&"#"!=E)&&(this._host=s._host,this._port=s._port,this._username=s._username,this._password=s._password,this._path=s._path.slice(),this._path.pop()),d="relative path";continue}this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query=s._query,this._fragment="#",this._username=s._username,this._password=s._password,d="fragment"}break;case"relative slash":if("/"!=b&&"\\"!=b){"file"!=this._scheme&&(this._host=s._host,this._port=s._port,this._username=s._username,this._password=s._password),d="relative path";continue}"\\"==b&&c("\\ is an invalid code point."),d="file"==this._scheme?"file host":"authority ignore slashes";break;case"authority first slash":if("/"!=b){c("Expected '/', got: "+b),d="authority ignore slashes";continue}d="authority second slash";break;case"authority second slash":if(d="authority ignore slashes","/"!=b){c("Expected '/', got: "+b);continue}break;case"authority ignore slashes":if("/"!=b&&"\\"!=b){d="authority";continue}c("Expected authority, got: "+b);break;case"authority":if("@"==b){w&&(c("@ already seen."),l+="%40"),w=!0;for(var L=0;L>>0)+(t++ +"__")};n.prototype={set:function(t,n){var r=t[this.name];return r&&r[0]===t?r[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),function(e){function t(e){b.push(e),g||(g=!0,m(r))}function n(e){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(e)||e}function r(){g=!1;var e=b;b=[],e.sort(function(e,t){return e.uid_-t.uid_});var t=!1;e.forEach(function(e){var n=e.takeRecords();o(e),n.length&&(e.callback_(n,e),t=!0)}),t&&r()}function o(e){e.nodes_.forEach(function(t){var n=v.get(t);n&&n.forEach(function(t){t.observer===e&&t.removeTransientObservers()})})}function i(e,t){for(var n=e;n;n=n.parentNode){var r=v.get(n);if(r)for(var o=0;o0){var o=n[r-1],i=f(o,e);if(i)return void(n[r-1]=i)}else t(this.observer);n[r]=e},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(e){var t=this.options;t.attributes&&e.addEventListener("DOMAttrModified",this,!0),t.characterData&&e.addEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.addEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(e){var t=this.options;t.attributes&&e.removeEventListener("DOMAttrModified",this,!0),t.characterData&&e.removeEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.removeEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(e){if(e!==this.target){this.addListeners_(e),this.transientObservedNodes.push(e);var t=v.get(e);t||v.set(e,t=[]),t.push(this)}},removeTransientObservers:function(){var e=this.transientObservedNodes;this.transientObservedNodes=[],e.forEach(function(e){this.removeListeners_(e);for(var t=v.get(e),n=0;n":return">";case" ":return" "}}function t(t){return t.replace(a,e)}var n="template",r=document.implementation.createHTMLDocument("template"),o=!0;HTMLTemplateElement=function(){},HTMLTemplateElement.prototype=Object.create(HTMLElement.prototype),HTMLTemplateElement.decorate=function(e){if(!e.content){e.content=r.createDocumentFragment();for(var n;n=e.firstChild;)e.content.appendChild(n);if(o)try{Object.defineProperty(e,"innerHTML",{get:function(){for(var e="",n=this.content.firstChild;n;n=n.nextSibling)e+=n.outerHTML||t(n.data);return e},set:function(e){for(r.body.innerHTML=e,HTMLTemplateElement.bootstrap(r);this.content.firstChild;)this.content.removeChild(this.content.firstChild);for(;r.body.firstChild;)this.content.appendChild(r.body.firstChild)},configurable:!0})}catch(i){o=!1}HTMLTemplateElement.bootstrap(e.content)}},HTMLTemplateElement.bootstrap=function(e){for(var t,r=e.querySelectorAll(n),o=0,i=r.length;i>o&&(t=r[o]);o++)HTMLTemplateElement.decorate(t)},document.addEventListener("DOMContentLoaded",function(){HTMLTemplateElement.bootstrap(document)});var i=document.createElement;document.createElement=function(){"use strict";var e=i.apply(document,arguments);return"template"==e.localName&&HTMLTemplateElement.decorate(e),e};var a=/[&\u00A0<>]/g}(),function(e){"use strict";if(!window.performance){var t=Date.now();window.performance={now:function(){return Date.now()-t}}}window.requestAnimationFrame||(window.requestAnimationFrame=function(){var e=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame;return e?function(t){return e(function(){t(performance.now())})}:function(e){return window.setTimeout(e,1e3/60)}}()),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(){return window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(e){clearTimeout(e)}}());var n=function(){var e=document.createEvent("Event");return e.initEvent("foo",!0,!0),e.preventDefault(),e.defaultPrevented}();if(!n){var r=Event.prototype.preventDefault;Event.prototype.preventDefault=function(){this.cancelable&&(r.call(this),Object.defineProperty(this,"defaultPrevented",{get:function(){return!0},configurable:!0}))}}var o=/Trident/.test(navigator.userAgent);if((!window.CustomEvent||o&&"function"!=typeof window.CustomEvent)&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.CustomEvent.prototype=window.Event.prototype),!window.Event||o&&"function"!=typeof window.Event){var i=window.Event;window.Event=function(e,t){t=t||{};var n=document.createEvent("Event");return n.initEvent(e,Boolean(t.bubbles),Boolean(t.cancelable)),n},window.Event.prototype=i.prototype}}(window.WebComponents),window.HTMLImports=window.HTMLImports||{flags:{}},function(e){function t(e,t){t=t||p,r(function(){i(e,t)},t)}function n(e){return"complete"===e.readyState||e.readyState===w}function r(e,t){if(n(t))e&&e();else{var o=function(){("complete"===t.readyState||t.readyState===w)&&(t.removeEventListener(_,o),r(e,t))};t.addEventListener(_,o)}}function o(e){e.target.__loaded=!0}function i(e,t){function n(){c==d&&e&&e({allImports:s,loadedImports:u,errorImports:l})}function r(e){o(e),u.push(this),c++,n()}function i(e){l.push(this),c++,n()}var s=t.querySelectorAll("link[rel=import]"),c=0,d=s.length,u=[],l=[];if(d)for(var h,f=0;d>f&&(h=s[f]);f++)a(h)?(c++,n()):(h.addEventListener("load",r),h.addEventListener("error",i));else n()}function a(e){return l?e.__loaded||e["import"]&&"loading"!==e["import"].readyState:e.__importParsed}function s(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)c(t)&&d(t)}function c(e){return"link"===e.localName&&"import"===e.rel}function d(e){var t=e["import"];t?o({target:e}):(e.addEventListener("load",o),e.addEventListener("error",o))}var u="import",l=Boolean(u in document.createElement("link")),h=Boolean(window.ShadowDOMPolyfill),f=function(e){return h?window.ShadowDOMPolyfill.wrapIfNeeded(e):e},p=f(document),m={get:function(){var e=window.HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return f(e)},configurable:!0};Object.defineProperty(document,"_currentScript",m),Object.defineProperty(p,"_currentScript",m);var v=/Trident/.test(navigator.userAgent),w=v?"complete":"interactive",_="readystatechange";l&&(new MutationObserver(function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.addedNodes&&s(t.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var e,t=document.querySelectorAll("link[rel=import]"),n=0,r=t.length;r>n&&(e=t[n]);n++)d(e)}()),t(function(e){window.HTMLImports.ready=!0,window.HTMLImports.readyTime=(new Date).getTime();var t=p.createEvent("CustomEvent");t.initCustomEvent("HTMLImportsLoaded",!0,!0,e),p.dispatchEvent(t)}),e.IMPORT_LINK_TYPE=u,e.useNative=l,e.rootDocument=p,e.whenReady=t,e.isIE=v}(window.HTMLImports),function(e){var t=[],n=function(e){t.push(e)},r=function(){t.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=r}(window.HTMLImports),window.HTMLImports.addModule(function(e){var t=/(url\()([^)]*)(\))/g,n=/(@import[\s]+(?!url\())([^;]*)(;)/g,r={resolveUrlsInStyle:function(e,t){var n=e.ownerDocument,r=n.createElement("a");return e.textContent=this.resolveUrlsInCssText(e.textContent,t,r),e},resolveUrlsInCssText:function(e,r,o){var i=this.replaceUrls(e,o,r,t);return i=this.replaceUrls(i,o,r,n)},replaceUrls:function(e,t,n,r){return e.replace(r,function(e,r,o,i){var a=o.replace(/["']/g,"");return n&&(a=new URL(a,n).href),t.href=a,a=t.href,r+"'"+a+"'"+i})}};e.path=r}),window.HTMLImports.addModule(function(e){var t={async:!0,ok:function(e){return e.status>=200&&e.status<300||304===e.status||0===e.status},load:function(n,r,o){var i=new XMLHttpRequest;return(e.flags.debug||e.flags.bust)&&(n+="?"+Math.random()),i.open("GET",n,t.async),i.addEventListener("readystatechange",function(e){if(4===i.readyState){var n=null;try{var a=i.getResponseHeader("Location");a&&(n="/"===a.substr(0,1)?location.origin+a:a)}catch(e){console.error(e.message)}r.call(o,!t.ok(i)&&i,i.response||i.responseText,n)}}),i.send(),i},loadDocument:function(e,t,n){this.load(e,t,n).responseType="document"}};e.xhr=t}),window.HTMLImports.addModule(function(e){var t=e.xhr,n=e.flags,r=function(e,t){this.cache={},this.onload=e,this.oncomplete=t,this.inflight=0,this.pending={}};r.prototype={addNodes:function(e){this.inflight+=e.length;for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)this.require(t);this.checkDone()},addNode:function(e){this.inflight++,this.require(e),this.checkDone()},require:function(e){var t=e.src||e.href;e.__nodeUrl=t,this.dedupe(t,e)||this.fetch(t,e)},dedupe:function(e,t){if(this.pending[e])return this.pending[e].push(t),!0;return this.cache[e]?(this.onload(e,t,this.cache[e]),this.tail(),!0):(this.pending[e]=[t],!1)},fetch:function(e,r){if(n.load&&console.log("fetch",e,r),e)if(e.match(/^data:/)){var o=e.split(","),i=o[0],a=o[1];a=i.indexOf(";base64")>-1?atob(a):decodeURIComponent(a),setTimeout(function(){this.receive(e,r,null,a)}.bind(this),0)}else{var s=function(t,n,o){this.receive(e,r,t,n,o)}.bind(this);t.load(e,s)}else setTimeout(function(){this.receive(e,r,{error:"href must be specified"},null)}.bind(this),0)},receive:function(e,t,n,r,o){this.cache[e]=r;for(var i,a=this.pending[e],s=0,c=a.length;c>s&&(i=a[s]);s++)this.onload(e,i,r,n,o),this.tail();this.pending[e]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},e.Loader=r}),window.HTMLImports.addModule(function(e){var t=function(e){this.addCallback=e,this.mo=new MutationObserver(this.handler.bind(this))};t.prototype={handler:function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)"childList"===t.type&&t.addedNodes.length&&this.addedNodes(t.addedNodes)},addedNodes:function(e){this.addCallback&&this.addCallback(e);for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.children&&t.children.length&&this.addedNodes(t.children)},observe:function(e){this.mo.observe(e,{childList:!0,subtree:!0})}},e.Observer=t}),window.HTMLImports.addModule(function(e){function t(e){return"link"===e.localName&&e.rel===u}function n(e){var t=r(e);return"data:text/javascript;charset=utf-8,"+encodeURIComponent(t)}function r(e){return e.textContent+o(e)}function o(e){var t=e.ownerDocument;t.__importedScripts=t.__importedScripts||0;var n=e.ownerDocument.baseURI,r=t.__importedScripts?"-"+t.__importedScripts:"";return t.__importedScripts++,"\n//# sourceURL="+n+r+".js\n"}function i(e){var t=e.ownerDocument.createElement("style");return t.textContent=e.textContent,a.resolveUrlsInStyle(t),t}var a=e.path,s=e.rootDocument,c=e.flags,d=e.isIE,u=e.IMPORT_LINK_TYPE,l="link[rel="+u+"]",h={documentSelectors:l,importsSelectors:[l,"link[rel=stylesheet]:not([type])","style:not([type])","script:not([type])",'script[type="application/javascript"]','script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},dynamicElements:[],parseNext:function(){var e=this.nextToParse();e&&this.parse(e)},parse:function(e){if(this.isParsed(e))return void(c.parse&&console.log("[%s] is already parsed",e.localName));var t=this[this.map[e.localName]];t&&(this.markParsing(e),t.call(this,e))},parseDynamic:function(e,t){this.dynamicElements.push(e),t||this.parseNext()},markParsing:function(e){c.parse&&console.log("parsing",e),this.parsingElement=e},markParsingComplete:function(e){e.__importParsed=!0,this.markDynamicParsingComplete(e),e.__importElement&&(e.__importElement.__importParsed=!0,this.markDynamicParsingComplete(e.__importElement)),this.parsingElement=null,c.parse&&console.log("completed",e)},markDynamicParsingComplete:function(e){var t=this.dynamicElements.indexOf(e);t>=0&&this.dynamicElements.splice(t,1)},parseImport:function(e){if(e["import"]=e.__doc,window.HTMLImports.__importsParsingHook&&window.HTMLImports.__importsParsingHook(e),e["import"]&&(e["import"].__importParsed=!0),this.markParsingComplete(e),e.__resource&&!e.__error?e.dispatchEvent(new CustomEvent("load",{bubbles:!1})):e.dispatchEvent(new CustomEvent("error",{bubbles:!1})),e.__pending)for(var t;e.__pending.length;)t=e.__pending.shift(),t&&t({target:e});this.parseNext()},parseLink:function(e){t(e)?this.parseImport(e):(e.href=e.href,this.parseGeneric(e))},parseStyle:function(e){var t=e;e=i(e),t.__appliedElement=e,e.__importElement=t,this.parseGeneric(e)},parseGeneric:function(e){this.trackElement(e),this.addElementToDocument(e)},rootImportForElement:function(e){for(var t=e;t.ownerDocument.__importLink;)t=t.ownerDocument.__importLink;return t},addElementToDocument:function(e){var t=this.rootImportForElement(e.__importElement||e);t.parentNode.insertBefore(e,t)},trackElement:function(e,t){var n=this,r=function(o){e.removeEventListener("load",r),e.removeEventListener("error",r),t&&t(o),n.markParsingComplete(e),n.parseNext()};if(e.addEventListener("load",r),e.addEventListener("error",r),d&&"style"===e.localName){var o=!1;if(-1==e.textContent.indexOf("@import"))o=!0;else if(e.sheet){o=!0;for(var i,a=e.sheet.cssRules,s=a?a.length:0,c=0;s>c&&(i=a[c]);c++)i.type===CSSRule.IMPORT_RULE&&(o=o&&Boolean(i.styleSheet))}o&&setTimeout(function(){e.dispatchEvent(new CustomEvent("load",{bubbles:!1}))})}},parseScript:function(t){var r=document.createElement("script");r.__importElement=t,r.src=t.src?t.src:n(t),e.currentScript=t,this.trackElement(r,function(t){r.parentNode&&r.parentNode.removeChild(r),e.currentScript=null}),this.addElementToDocument(r)},nextToParse:function(){return this._mayParse=[],!this.parsingElement&&(this.nextToParseInDoc(s)||this.nextToParseDynamic())},nextToParseInDoc:function(e,n){if(e&&this._mayParse.indexOf(e)<0){this._mayParse.push(e);for(var r,o=e.querySelectorAll(this.parseSelectorsForNode(e)),i=0,a=o.length;a>i&&(r=o[i]);i++)if(!this.isParsed(r))return this.hasResource(r)?t(r)?this.nextToParseInDoc(r.__doc,r):r:void 0}return n},nextToParseDynamic:function(){return this.dynamicElements[0]},parseSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===s?this.documentSelectors:this.importsSelectors},isParsed:function(e){return e.__importParsed},needsDynamicParsing:function(e){return this.dynamicElements.indexOf(e)>=0},hasResource:function(e){return t(e)&&void 0===e.__doc?!1:!0}};e.parser=h,e.IMPORT_SELECTOR=l}),window.HTMLImports.addModule(function(e){function t(e){return n(e,a)}function n(e,t){return"link"===e.localName&&e.getAttribute("rel")===t}function r(e){return!!Object.getOwnPropertyDescriptor(e,"baseURI")}function o(e,t){var n=document.implementation.createHTMLDocument(a);n._URL=t;var o=n.createElement("base");o.setAttribute("href",t),n.baseURI||r(n)||Object.defineProperty(n,"baseURI",{value:t});var i=n.createElement("meta");return i.setAttribute("charset","utf-8"),n.head.appendChild(i),n.head.appendChild(o),n.body.innerHTML=e,window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(n),n}var i=e.flags,a=e.IMPORT_LINK_TYPE,s=e.IMPORT_SELECTOR,c=e.rootDocument,d=e.Loader,u=e.Observer,l=e.parser,h={documents:{},documentPreloadSelectors:s,importsPreloadSelectors:[s].join(","),loadNode:function(e){f.addNode(e)},loadSubtree:function(e){var t=this.marshalNodes(e);f.addNodes(t)},marshalNodes:function(e){return e.querySelectorAll(this.loadSelectorsForNode(e))},loadSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===c?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(e,n,r,a,s){if(i.load&&console.log("loaded",e,n),n.__resource=r,n.__error=a,t(n)){var c=this.documents[e];void 0===c&&(c=a?null:o(r,s||e),c&&(c.__importLink=n,this.bootDocument(c)),this.documents[e]=c),n.__doc=c}l.parseNext()},bootDocument:function(e){this.loadSubtree(e),this.observer.observe(e),l.parseNext()},loadedAll:function(){l.parseNext()}},f=new d(h.loaded.bind(h),h.loadedAll.bind(h));if(h.observer=new u,!document.baseURI){var p={get:function(){var e=document.querySelector("base");return e?e.href:window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",p),Object.defineProperty(c,"baseURI",p)}e.importer=h,e.importLoader=f}),window.HTMLImports.addModule(function(e){var t=e.parser,n=e.importer,r={added:function(e){for(var r,o,i,a,s=0,c=e.length;c>s&&(a=e[s]);s++)r||(r=a.ownerDocument,o=t.isParsed(r)),i=this.shouldLoadNode(a),i&&n.loadNode(a),this.shouldParseNode(a)&&o&&t.parseDynamic(a,i)},shouldLoadNode:function(e){return 1===e.nodeType&&o.call(e,n.loadSelectorsForNode(e))},shouldParseNode:function(e){return 1===e.nodeType&&o.call(e,t.parseSelectorsForNode(e))}};n.observer.addCallback=r.added.bind(r);var o=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector}),function(e){function t(){window.HTMLImports.importer.bootDocument(r)}var n=e.initializeModules;e.isIE;if(!e.useNative){n();var r=e.rootDocument;"complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?t():document.addEventListener("DOMContentLoaded",t)}}(window.HTMLImports),window.CustomElements=window.CustomElements||{flags:{}},function(e){var t=e.flags,n=[],r=function(e){n.push(e)},o=function(){n.forEach(function(t){t(e)})};e.addModule=r,e.initializeModules=o,e.hasNative=Boolean(document.registerElement),e.isIE=/Trident/.test(navigator.userAgent),e.useNative=!t.register&&e.hasNative&&!window.ShadowDOMPolyfill&&(!window.HTMLImports||window.HTMLImports.useNative)}(window.CustomElements),window.CustomElements.addModule(function(e){function t(e,t){n(e,function(e){return t(e)?!0:void r(e,t)}),r(e,t)}function n(e,t,r){var o=e.firstElementChild;if(!o)for(o=e.firstChild;o&&o.nodeType!==Node.ELEMENT_NODE;)o=o.nextSibling;for(;o;)t(o,r)!==!0&&n(o,t,r),o=o.nextElementSibling;return null}function r(e,n){for(var r=e.shadowRoot;r;)t(r,n),r=r.olderShadowRoot}function o(e,t){i(e,t,[])}function i(e,t,n){if(e=window.wrap(e),!(n.indexOf(e)>=0)){n.push(e);for(var r,o=e.querySelectorAll("link[rel="+a+"]"),s=0,c=o.length;c>s&&(r=o[s]);s++)r["import"]&&i(r["import"],t,n);t(e)}}var a=window.HTMLImports?window.HTMLImports.IMPORT_LINK_TYPE:"none";e.forDocumentTree=o,e.forSubtree=t}),window.CustomElements.addModule(function(e){function t(e,t){return n(e,t)||r(e,t)}function n(t,n){return e.upgrade(t,n)?!0:void(n&&a(t))}function r(e,t){g(e,function(e){return n(e,t)?!0:void 0})}function o(e){L.push(e),E||(E=!0,setTimeout(i))}function i(){E=!1;for(var e,t=L,n=0,r=t.length;r>n&&(e=t[n]);n++)e();L=[]}function a(e){y?o(function(){s(e)}):s(e)}function s(e){e.__upgraded__&&!e.__attached&&(e.__attached=!0,e.attachedCallback&&e.attachedCallback())}function c(e){d(e),g(e,function(e){d(e)})}function d(e){y?o(function(){u(e)}):u(e)}function u(e){e.__upgraded__&&e.__attached&&(e.__attached=!1,e.detachedCallback&&e.detachedCallback())}function l(e){for(var t=e,n=window.wrap(document);t;){if(t==n)return!0;t=t.parentNode||t.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&t.host}}function h(e){if(e.shadowRoot&&!e.shadowRoot.__watched){_.dom&&console.log("watching shadow-root for: ",e.localName);for(var t=e.shadowRoot;t;)m(t),t=t.olderShadowRoot}}function f(e,n){if(_.dom){var r=n[0];if(r&&"childList"===r.type&&r.addedNodes&&r.addedNodes){for(var o=r.addedNodes[0];o&&o!==document&&!o.host;)o=o.parentNode;var i=o&&(o.URL||o._URL||o.host&&o.host.localName)||"";i=i.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",n.length,i||"")}var a=l(e);n.forEach(function(e){"childList"===e.type&&(T(e.addedNodes,function(e){e.localName&&t(e,a)}),T(e.removedNodes,function(e){e.localName&&c(e)}))}),_.dom&&console.groupEnd()}function p(e){for(e=window.wrap(e),e||(e=window.wrap(document));e.parentNode;)e=e.parentNode;var t=e.__observer;t&&(f(e,t.takeRecords()),i())}function m(e){if(!e.__observer){var t=new MutationObserver(f.bind(this,e));t.observe(e,{childList:!0,subtree:!0}),e.__observer=t}}function v(e){e=window.wrap(e),_.dom&&console.group("upgradeDocument: ",e.baseURI.split("/").pop()); +var n=e===window.wrap(document);t(e,n),m(e),_.dom&&console.groupEnd()}function w(e){b(e,v)}var _=e.flags,g=e.forSubtree,b=e.forDocumentTree,y=window.MutationObserver._isPolyfilled&&_["throttle-attached"];e.hasPolyfillMutations=y,e.hasThrottledAttached=y;var E=!1,L=[],T=Array.prototype.forEach.call.bind(Array.prototype.forEach),M=Element.prototype.createShadowRoot;M&&(Element.prototype.createShadowRoot=function(){var e=M.call(this);return window.CustomElements.watchShadow(this),e}),e.watchShadow=h,e.upgradeDocumentTree=w,e.upgradeDocument=v,e.upgradeSubtree=r,e.upgradeAll=t,e.attached=a,e.takeRecords=p}),window.CustomElements.addModule(function(e){function t(t,r){if("template"===t.localName&&window.HTMLTemplateElement&&HTMLTemplateElement.decorate&&HTMLTemplateElement.decorate(t),!t.__upgraded__&&t.nodeType===Node.ELEMENT_NODE){var o=t.getAttribute("is"),i=e.getRegisteredDefinition(t.localName)||e.getRegisteredDefinition(o);if(i&&(o&&i.tag==t.localName||!o&&!i["extends"]))return n(t,i,r)}}function n(t,n,o){return a.upgrade&&console.group("upgrade:",t.localName),n.is&&t.setAttribute("is",n.is),r(t,n),t.__upgraded__=!0,i(t),o&&e.attached(t),e.upgradeSubtree(t,o),a.upgrade&&console.groupEnd(),t}function r(e,t){Object.__proto__?e.__proto__=t.prototype:(o(e,t.prototype,t["native"]),e.__proto__=t.prototype)}function o(e,t,n){for(var r={},o=t;o!==n&&o!==HTMLElement.prototype;){for(var i,a=Object.getOwnPropertyNames(o),s=0;i=a[s];s++)r[i]||(Object.defineProperty(e,i,Object.getOwnPropertyDescriptor(o,i)),r[i]=1);o=Object.getPrototypeOf(o)}}function i(e){e.createdCallback&&e.createdCallback()}var a=e.flags;e.upgrade=t,e.upgradeWithDefinition=n,e.implementPrototype=r}),window.CustomElements.addModule(function(e){function t(t,r){var c=r||{};if(!t)throw new Error("document.registerElement: first argument `name` must not be empty");if(t.indexOf("-")<0)throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(t)+"'.");if(o(t))throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '"+String(t)+"'. The type name is invalid.");if(d(t))throw new Error("DuplicateDefinitionError: a type with name '"+String(t)+"' is already registered");return c.prototype||(c.prototype=Object.create(HTMLElement.prototype)),c.__name=t.toLowerCase(),c.lifecycle=c.lifecycle||{},c.ancestry=i(c["extends"]),a(c),s(c),n(c.prototype),u(c.__name,c),c.ctor=l(c),c.ctor.prototype=c.prototype,c.prototype.constructor=c.ctor,e.ready&&w(document),c.ctor}function n(e){if(!e.setAttribute._polyfilled){var t=e.setAttribute;e.setAttribute=function(e,n){r.call(this,e,n,t)};var n=e.removeAttribute;e.removeAttribute=function(e){r.call(this,e,null,n)},e.setAttribute._polyfilled=!0}}function r(e,t,n){e=e.toLowerCase();var r=this.getAttribute(e);n.apply(this,arguments);var o=this.getAttribute(e);this.attributeChangedCallback&&o!==r&&this.attributeChangedCallback(e,r,o)}function o(e){for(var t=0;t=0&&b(r,HTMLElement),r)}function p(e,t){var n=e[t];e[t]=function(){var e=n.apply(this,arguments);return _(e),e}}var m,v=e.isIE,w=e.upgradeDocumentTree,_=e.upgradeAll,g=e.upgradeWithDefinition,b=e.implementPrototype,y=e.useNative,E=["annotation-xml","color-profile","font-face","font-face-src","font-face-uri","font-face-format","font-face-name","missing-glyph"],L={},T="http://www.w3.org/1999/xhtml",M=document.createElement.bind(document),N=document.createElementNS.bind(document);m=Object.__proto__||y?function(e,t){return e instanceof t}:function(e,t){if(e instanceof t)return!0;for(var n=e;n;){if(n===t.prototype)return!0;n=n.__proto__}return!1},p(Node.prototype,"cloneNode"),p(document,"importNode"),v&&!function(){var e=document.importNode;document.importNode=function(){var t=e.apply(document,arguments);if(t.nodeType==t.DOCUMENT_FRAGMENT_NODE){var n=document.createDocumentFragment();return n.appendChild(t),n}return t}}(),document.registerElement=t,document.createElement=f,document.createElementNS=h,e.registry=L,e["instanceof"]=m,e.reservedTagList=E,e.getRegisteredDefinition=d,document.register=document.registerElement}),function(e){function t(){i(window.wrap(document)),window.CustomElements.ready=!0;var e=window.requestAnimationFrame||function(e){setTimeout(e,16)};e(function(){setTimeout(function(){window.CustomElements.readyTime=Date.now(),window.HTMLImports&&(window.CustomElements.elapsed=window.CustomElements.readyTime-window.HTMLImports.readyTime),document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})})}var n=e.useNative,r=e.initializeModules;e.isIE;if(n){var o=function(){};e.watchShadow=o,e.upgrade=o,e.upgradeAll=o,e.upgradeDocumentTree=o,e.upgradeSubtree=o,e.takeRecords=o,e["instanceof"]=function(e,t){return e instanceof t}}else r();var i=e.upgradeDocumentTree,a=e.upgradeDocument;if(window.wrap||(window.ShadowDOMPolyfill?(window.wrap=window.ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=window.ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}),window.HTMLImports&&(window.HTMLImports.__importsParsingHook=function(e){e["import"]&&a(wrap(e["import"]))}),"complete"===document.readyState||e.flags.eager)t();else if("interactive"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var s=window.HTMLImports&&!window.HTMLImports.ready?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(s,t)}else t()}(window.CustomElements),function(e){var t=document.createElement("style");t.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \n";var n=document.querySelector("head");n.insertBefore(t,n.firstChild)}(window.WebComponents); \ No newline at end of file From 0df39b4df57be3681e041a5fd4e7f905fa567902 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 28 Nov 2015 18:32:15 -0800 Subject: [PATCH 42/49] Remove no password set boolean --- homeassistant/components/frontend/__init__.py | 2 +- homeassistant/components/http.py | 14 ++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index 9bc46f86023..dac2041fa56 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -65,7 +65,7 @@ def _handle_get_root(handler, path_match, data): app_url = "frontend-{}.html".format(version.VERSION) # auto login if no password was set, else check api_password param - auth = ('no_password_set' if handler.server.no_password_set + auth = ('no_password_set' if handler.server.api_password is None else data.get('api_password', '')) with open(INDEX_PATH) as template_file: diff --git a/homeassistant/components/http.py b/homeassistant/components/http.py index 33290a159fa..5e8332e283a 100644 --- a/homeassistant/components/http.py +++ b/homeassistant/components/http.py @@ -53,10 +53,6 @@ def setup(hass, config): conf = config[DOMAIN] api_password = util.convert(conf.get(CONF_API_PASSWORD), str) - no_password_set = api_password is None - - if no_password_set: - api_password = util.get_random_string() # If no server host is given, accept all incoming requests server_host = conf.get(CONF_SERVER_HOST, '0.0.0.0') @@ -66,7 +62,7 @@ def setup(hass, config): try: server = HomeAssistantHTTPServer( (server_host, server_port), RequestHandler, hass, api_password, - development, no_password_set) + development) except OSError: # If address already in use _LOGGER.exception("Error setting up HTTP server") @@ -93,14 +89,13 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer): # pylint: disable=too-many-arguments def __init__(self, server_address, request_handler_class, - hass, api_password, development, no_password_set): + hass, api_password, development): super().__init__(server_address, request_handler_class) self.server_address = server_address self.hass = hass self.api_password = api_password self.development = development - self.no_password_set = no_password_set self.paths = [] self.sessions = SessionStore() @@ -157,7 +152,7 @@ class RequestHandler(SimpleHTTPRequestHandler): def log_message(self, fmt, *arguments): """ Redirect built-in log to HA logging """ - if self.server.no_password_set: + if self.server.api_password is None: _LOGGER.info(fmt, *arguments) else: _LOGGER.info( @@ -192,8 +187,7 @@ class RequestHandler(SimpleHTTPRequestHandler): "Error parsing JSON", HTTP_UNPROCESSABLE_ENTITY) return - if self.server.no_password_set: - _LOGGER.warning('NO PASSWORD SET') + if self.server.api_password is None: self.authenticated = True elif HTTP_HEADER_HA_AUTH in self.headers: api_password = self.headers.get(HTTP_HEADER_HA_AUTH) From 546377e80a7104805cb94400612f6439e8a2cb83 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 28 Nov 2015 18:59:59 -0800 Subject: [PATCH 43/49] Throttle camera stream to 2fps --- homeassistant/components/camera/__init__.py | 37 ++++++++++----------- homeassistant/components/camera/demo.py | 4 +-- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/homeassistant/components/camera/__init__.py b/homeassistant/components/camera/__init__.py index ae5fe28beac..e63665230ca 100644 --- a/homeassistant/components/camera/__init__.py +++ b/homeassistant/components/camera/__init__.py @@ -19,6 +19,7 @@ from homeassistant.const import ( ) from homeassistant.helpers.entity_component import EntityComponent +import homeassistant.util.dt as dt_util DOMAIN = 'camera' @@ -80,19 +81,21 @@ def setup(hass, config): def _proxy_camera_image(handler, path_match, data): """ Proxies the camera image via the HA server. """ entity_id = path_match.group(ATTR_ENTITY_ID) + camera = component.entities.get(entity_id) - camera = None - if entity_id in component.entities.keys(): - camera = component.entities[entity_id] - - if camera: - response = camera.camera_image() - if response is not None: - handler.wfile.write(response) - else: - handler.send_response(HTTP_NOT_FOUND) - else: + if camera is None: handler.send_response(HTTP_NOT_FOUND) + handler.end_headers() + return + + response = camera.camera_image() + + if response is None: + handler.send_response(HTTP_NOT_FOUND) + handler.end_headers() + return + + handler.wfile.write(response) hass.http.register_path( 'GET', @@ -108,12 +111,9 @@ def setup(hass, config): stream even with only a still image URL available. """ entity_id = path_match.group(ATTR_ENTITY_ID) + camera = component.entities.get(entity_id) - camera = None - if entity_id in component.entities.keys(): - camera = component.entities[entity_id] - - if not camera: + if camera is None: handler.send_response(HTTP_NOT_FOUND) handler.end_headers() return @@ -131,7 +131,6 @@ def setup(hass, config): # MJPEG_START_HEADER.format() while True: - img_bytes = camera.camera_image() if img_bytes is None: continue @@ -148,12 +147,12 @@ def setup(hass, config): handler.request.sendall( bytes('--jpgboundary\r\n', 'utf-8')) + time.sleep(0.5) + except (requests.RequestException, IOError): camera.is_streaming = False camera.update_ha_state() - camera.is_streaming = False - hass.http.register_path( 'GET', re.compile( diff --git a/homeassistant/components/camera/demo.py b/homeassistant/components/camera/demo.py index fc3ec263143..fd79bc3ce82 100644 --- a/homeassistant/components/camera/demo.py +++ b/homeassistant/components/camera/demo.py @@ -24,12 +24,10 @@ class DemoCamera(Camera): def camera_image(self): """ Return a faked still image response. """ - image_path = os.path.join(os.path.dirname(__file__), 'demo_{}.png'.format(randint(1, 5))) with open(image_path, 'rb') as file: - output = file.read() - return output + return file.read() @property def name(self): From e67732b4f85820d71d9bbb14b1b6de3014bfda7a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 28 Nov 2015 19:12:42 -0800 Subject: [PATCH 44/49] Remove no longer needed image --- .../components/frontend/www_static/splash.png | Bin 51901 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 homeassistant/components/frontend/www_static/splash.png diff --git a/homeassistant/components/frontend/www_static/splash.png b/homeassistant/components/frontend/www_static/splash.png deleted file mode 100644 index 582140a2bc35f598fc227782ff06039759b39fe5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51901 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 z 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 From 733de6b3576c0c4982cb4998ef37cf255aaa6ed5 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 28 Nov 2015 22:14:40 -0800 Subject: [PATCH 45/49] Streaming API will keep session alive --- homeassistant/components/api.py | 3 +++ homeassistant/components/http.py | 43 +++++++++++++++++++------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/homeassistant/components/api.py b/homeassistant/components/api.py index a81c0f3227f..1e6e66baee0 100644 --- a/homeassistant/components/api.py +++ b/homeassistant/components/api.py @@ -106,6 +106,7 @@ def _handle_get_api_stream(handler, path_match, data): wfile = handler.wfile write_lock = threading.Lock() block = threading.Event() + session_id = None restrict = data.get('restrict') if restrict: @@ -119,6 +120,7 @@ def _handle_get_api_stream(handler, path_match, data): try: wfile.write(msg.encode("UTF-8")) wfile.flush() + handler.server.sessions.extend_validation(session_id) except IOError: block.set() @@ -138,6 +140,7 @@ def _handle_get_api_stream(handler, path_match, data): handler.send_response(HTTP_OK) handler.send_header('Content-type', 'text/event-stream') + session_id = handler.set_session_cookie_header() handler.end_headers() hass.bus.listen(MATCH_ALL, forward_events) diff --git a/homeassistant/components/http.py b/homeassistant/components/http.py index 5e8332e283a..81965179afe 100644 --- a/homeassistant/components/http.py +++ b/homeassistant/components/http.py @@ -337,26 +337,28 @@ class RequestHandler(SimpleHTTPRequestHandler): def set_cache_header(self): """ Add cache headers if not in development """ - if not self.server.development: - # 1 year in seconds - cache_time = 365 * 86400 + if self.server.development: + return - self.send_header( - HTTP_HEADER_CACHE_CONTROL, - "public, max-age={}".format(cache_time)) - self.send_header( - HTTP_HEADER_EXPIRES, - self.date_time_string(time.time()+cache_time)) + # 1 year in seconds + cache_time = 365 * 86400 + + self.send_header( + HTTP_HEADER_CACHE_CONTROL, + "public, max-age={}".format(cache_time)) + self.send_header( + HTTP_HEADER_EXPIRES, + self.date_time_string(time.time()+cache_time)) def set_session_cookie_header(self): - """ Add the header for the session cookie. """ + """ Add the header for the session cookie and return session id. """ if not self.authenticated: return - current = self.get_cookie_session_id() + session_id = self.get_cookie_session_id() - if current is not None: - self.server.sessions.extend_validation(current) + if session_id is not None: + self.server.sessions.extend_validation(session_id) return self.send_header( @@ -364,6 +366,8 @@ class RequestHandler(SimpleHTTPRequestHandler): '{}={}'.format(SESSION_KEY, self.server.sessions.create()) ) + return session_id + def verify_session(self): """ Verify that we are in a valid session. """ return self.get_cookie_session_id() is not None @@ -387,19 +391,22 @@ class RequestHandler(SimpleHTTPRequestHandler): if morsel is None: return None - current = cookie[SESSION_KEY].value + session_id = cookie[SESSION_KEY].value - return current if self.server.sessions.is_valid(current) else None + if self.server.sessions.is_valid(session_id): + return session_id + + return None def destroy_session(self): """ Destroys session. """ - current = self.get_cookie_session_id() + session_id = self.get_cookie_session_id() - if current is None: + if session_id is None: return self.send_header('Set-Cookie', '') - self.server.sessions.destroy(current) + self.server.sessions.destroy(session_id) def session_valid_time(): From f76edf0ed94469afcda4657c6aeaf772c93b6e6c Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 28 Nov 2015 22:15:11 -0800 Subject: [PATCH 46/49] Tweak manifest and frontend index --- .../components/frontend/index.html.template | 19 +++++-------------- .../frontend/www_static/manifest.json | 1 + 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/frontend/index.html.template b/homeassistant/components/frontend/index.html.template index 533fc43ac4e..87c5f6638a7 100644 --- a/homeassistant/components/frontend/index.html.template +++ b/homeassistant/components/frontend/index.html.template @@ -4,18 +4,13 @@ Home Assistant - - - - + + + href='/static/favicon-apple-180x180.png'> - + -
- -
-
+
diff --git a/homeassistant/components/frontend/www_static/manifest.json b/homeassistant/components/frontend/www_static/manifest.json index 3d0eb5fa443..3767a4b1c5b 100644 --- a/homeassistant/components/frontend/www_static/manifest.json +++ b/homeassistant/components/frontend/www_static/manifest.json @@ -3,6 +3,7 @@ "short_name": "Assistant", "start_url": "/", "display": "standalone", + "theme_color": "#03A9F4", "icons": [ { "src": "/static/favicon-192x192.png", From 286299c4c9716d41c059145b8391de714c37c68d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 28 Nov 2015 22:19:34 -0800 Subject: [PATCH 47/49] update frontend --- homeassistant/components/frontend/version.py | 2 +- .../frontend/www_static/frontend.html | 18 +++++++++--------- .../frontend/www_static/home-assistant-polymer | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/frontend/version.py b/homeassistant/components/frontend/version.py index 7e957562bba..04ccb720f6b 100644 --- a/homeassistant/components/frontend/version.py +++ b/homeassistant/components/frontend/version.py @@ -1,2 +1,2 @@ """ DO NOT MODIFY. Auto-generated by build_frontend script """ -VERSION = "c1df3a08faa4a9978b25639ca0fd63cd" +VERSION = "36df87bb6c219a2ee59adf416e3abdfa" diff --git a/homeassistant/components/frontend/www_static/frontend.html b/homeassistant/components/frontend/www_static/frontend.html index cf19d314f24..e600c4c5583 100644 --- a/homeassistant/components/frontend/www_static/frontend.html +++ b/homeassistant/components/frontend/www_static/frontend.html @@ -6052,12 +6052,12 @@ case"touchend":return this.addPointerListenerEnd(t,e,i,n);case"touchmove":return font-weight: 300; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; - } \ No newline at end of file + } \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/home-assistant-polymer b/homeassistant/components/frontend/www_static/home-assistant-polymer index f29b1062b30..33124030f6d 160000 --- a/homeassistant/components/frontend/www_static/home-assistant-polymer +++ b/homeassistant/components/frontend/www_static/home-assistant-polymer @@ -1 +1 @@ -Subproject commit f29b1062b30c76ceeea87fd426a042d98358394a +Subproject commit 33124030f6d119ad3a58cb520062f2aa58022c6d From 70698f7ab09d487ea994b76bac575aa7f80aa8bb Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 28 Nov 2015 23:16:20 -0800 Subject: [PATCH 48/49] Update demo camera images --- homeassistant/components/camera/__init__.py | 1 - homeassistant/components/camera/demo.py | 6 ++++-- homeassistant/components/camera/demo_0.jpg | Bin 0 -> 43574 bytes homeassistant/components/camera/demo_1.jpg | Bin 0 -> 44897 bytes homeassistant/components/camera/demo_1.png | Bin 9772 -> 0 bytes homeassistant/components/camera/demo_2.jpg | Bin 0 -> 44535 bytes homeassistant/components/camera/demo_2.png | Bin 9667 -> 0 bytes homeassistant/components/camera/demo_3.jpg | Bin 0 -> 44897 bytes homeassistant/components/camera/demo_3.png | Bin 9595 -> 0 bytes homeassistant/components/camera/demo_4.png | Bin 9906 -> 0 bytes homeassistant/components/camera/demo_5.png | Bin 9699 -> 0 bytes 11 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 homeassistant/components/camera/demo_0.jpg create mode 100644 homeassistant/components/camera/demo_1.jpg delete mode 100644 homeassistant/components/camera/demo_1.png create mode 100644 homeassistant/components/camera/demo_2.jpg delete mode 100644 homeassistant/components/camera/demo_2.png create mode 100644 homeassistant/components/camera/demo_3.jpg delete mode 100644 homeassistant/components/camera/demo_3.png delete mode 100644 homeassistant/components/camera/demo_4.png delete mode 100644 homeassistant/components/camera/demo_5.png diff --git a/homeassistant/components/camera/__init__.py b/homeassistant/components/camera/__init__.py index e63665230ca..169c97595af 100644 --- a/homeassistant/components/camera/__init__.py +++ b/homeassistant/components/camera/__init__.py @@ -19,7 +19,6 @@ from homeassistant.const import ( ) from homeassistant.helpers.entity_component import EntityComponent -import homeassistant.util.dt as dt_util DOMAIN = 'camera' diff --git a/homeassistant/components/camera/demo.py b/homeassistant/components/camera/demo.py index fd79bc3ce82..0ad992db86d 100644 --- a/homeassistant/components/camera/demo.py +++ b/homeassistant/components/camera/demo.py @@ -4,8 +4,8 @@ homeassistant.components.camera.demo Demo platform that has a fake camera. """ import os -from random import randint from homeassistant.components.camera import Camera +import homeassistant.util.dt as dt_util def setup_platform(hass, config, add_devices, discovery_info=None): @@ -24,8 +24,10 @@ class DemoCamera(Camera): def camera_image(self): """ Return a faked still image response. """ + now = dt_util.utcnow() + image_path = os.path.join(os.path.dirname(__file__), - 'demo_{}.png'.format(randint(1, 5))) + 'demo_{}.jpg'.format(now.second % 4)) with open(image_path, 'rb') as file: return file.read() diff --git a/homeassistant/components/camera/demo_0.jpg b/homeassistant/components/camera/demo_0.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ff87d5179f8364d86acf3a875e374741c5285bcb GIT binary patch literal 43574 zcmex=f#Lr{X6=lUk^(Dz z{k&qm#FYG`RK4WXl~0)0b01APV?`-+0Zy;bpa#8ycOYHUSr0o+)uVTGj7 z*B8Ii++0uqfJ3IZBq$Z(UaSTehg24%>IbD3=a&{Grv{~_DTAykuyQU+O)SYT3dzsU zfrVl~Mt(_taYlZDf^)E`f^TASW*&$SR`2U;<(XGpl9-pA>gi&uRFPYtmzkMjS%6mW@+YX>T2QY=4j?<0MqM|pIn-onpXnTo06GgoaJU7cHwBAZApS6N!|4xw zI|UnkP{bldG)ySS#SO#+r%6!yv{OJN{M5V@Tcsi;d%OSd82G@6l_BK-0|Nu&|Jw{L z3~VecEUYYStgLLDY^-dY+#GCd9NauyT-;n-JOVsmAi%@NFTl^oBP=W;A}lN;EiEl0 z4+o6w?CiWeyb=Ne5>ldqqEc`PVj2GrFbHxm&SHvSW)x@ci+Wc+`GVGRQVBP$~# zBO>=RFfy~SvN5r9FfuYQF{8>bfuz_47#NwE8Ch7_Ias-wnOPYbKnev}SQQN&h1dcU z3x(MmCvH?SauNwDnzTvT*hF+;QgE@@!6xTqm5>ruQ!|c>E-4=t9s1}RswUnn$jHFN z#K^+P!pz9P40Z@3lOQvTqM;D0u%nWZNT9K(a$+G{&@yf!S*}3=mCT}?Ow#7P0vh2m98740rOfzLQws?J)K391rpC_+i=eGPW=}t_Y z@h8_GExxAogKhdBn{~IPzla9xiCoabBSV9O zCX)o0aC6XYXKU}2gn}1}9APmD75=hI=3f48^2T+-{Eyd;O%IsPf6F{n$TKQwa)6^< z(t>WCk30Vy)BVqIbD3WHn2d$YOOx$Gf zM%Oe@(_(>$2E<0V)x9>bSi$|E{mi-wMv=sa5Mdc+S41zo%hK z&f~O&sq0=$+xufP_iUeQR&N+Z&aQX7u;%NGX?tGJ@MV#0kvpoDu*zX!MMKvKmlUYo zjogkR3WC>~M9-;R$}ittekzOW<;I!P^^q<95;rd`3Numb>63Kqy{~#u_{r?_3HvrF ze%rju!1Up|R;P~}mmRNYH}T~;;e71w+{Yoh;@O5f|HQd2xP8ZDPj7PJ!hr3Q4m4Q{ zS}HX_Eo*QfiLok-Lo}rQY~H(V)2)=_uC3(`Qr$0|Cc9zR?4|jy{xe(*K6Kjc#JqPL zU0Zc^%HA&YiTmKU%PV&4KR4clohtmLw_4}znNyy9zgzfbvbaUuq0HhumHg9*(W3W- zuI?90%uhbEWA~zq_sa9jcl;Hrx+kH#E>ZF3oZvhjwx?|Yu2H<1aZ@eZY`j8@os}yV zSI6C*%C;&=;H^s|1JoN#voDyMF5UB=q2fTv?Y&Nk(RM;^q1QJ3XE3}isG&dU5%a-P z!Ti^Z0W)NsqGazK`p4eem$)$W(8bhm#&eCgndB^g^ib~Qw-qzubb0HP=We+E!0=Oz z$?uzLU8{dO{au$l`^a&2^CeP?yaO6sS{z6VIRya@QLlqct0w&1IQh`?00FlTJ11LA zk19Q~yQJ`K#==)&y*hr89o356ofkgLZJAnCtlD?S!{h0je#1L=QgnSLp79)^JWowOE zZJQ|7wrqn5lQpC?d|;uXCbPG5Ay*$S1jF+xK-;AHL;q zzLIBotjg;PtJG98`_4ZrTvB6m^y9y?&lXB1oh?&8qAmH7_c!mBtJfUgh;kp<8unf6 zyI^MmDB~9U2IkBOXn@8zsJI|51#3<1XmooTB&S_};*!)Zrt4p2xz^o}&wF|O&7yQJ z?mcpT7mtY9F5a{-Grl_`|Mk;rCu+hc{(VxD`!et9`m9@$e;#?A-r@J@-h{UzE@$Kn z)#Vf>2QlwDbT+o9c*T{EHV2iJCmvd~blnxHyx>pTA5WK_7Q0sX=<&|22^l-HQ|ix2 ziJrTgzjJfcBLT}|&g#UeC*tl|)UFpV^<5$y+LtRC$vjzBVgH#p+rDJy*n8q!Su&Zw zM7NbpU6d>v`^m8{c}Dgum8S5I0dKxGt~zV2D{$OuQQ%K`ao(eAf4ht1cRf6$&b*W} za^;!B;psx^8+XU$o@77GkepJxrLWKHt>W^m7a31oXGvRZ7P^wS>Do{0a9@eVH!4yS zzkA*7cG+4MlvK5RWq^`_zyW7Q9u@;ZMV_vO6GJTommj}%&bH!cUBHD^55i8j?dXrL zv}iw3lxXQ(^UQwp?v7(+AzfSDgvET0-@kWb_nzZ-b~a=mjN0;3#7AGeZM*0r$$Xy3 zh>CK_nHxhVpOShlGq?3i;zkkcXGOlHvtoYGiPH_=AKRbUvi{%}E0O2dLXDj(nO8jUZnUxq%!>A1 zb#vXX)3GOo_Ws!^9jEc)+0-f0tTH=)CkvgAP80unMfP#h!D-HE9NzMh2|N>m98A_$ zg)aN4Ch)f4+cq=f=!osR-ZL)Ver09v%oiQzrz7%DzB#&IzEWkad>#VekbO~~@Pck#!DC}mxK)hlNw%v?0##Iwc=9@62_-Npt_KPMSo`LcFdgX8J5 zQn8;L?GifEaw<=Gccx`-DK8b?;eGI`!0s)lZ`=tmbGR;FdP_t&%UtT4f=0)Lh9E(Y z(10n9XC}HTSEOVVS8=T35KefYw(XsvT<=LGmJ9K>Lwx0{`Mw)xEff1xoL-V#UYTy# z`rr*qZ?!PD>#RBH9g^H>ZSn5+kFl>+E-7W2`sj4Fz0e2q0<(;nhRLg)4`0YwSg-t_ z;Xi}J;hN66PUllxHV%j8m&Gqy@~NT5;b8CD*)JA8Whnl~^Lulxh|L0d0fSm$5QDG& zV9@?7`xybB8voQc{oDRR#Ad=#pPy8l!*TQB{k>SWXY@g7g!^cPcX+CM(yUKGD5;FJExXWYN; zFADf1e>}qebzP^+PY0Q=P?yP7AFPl5;-zj7c)mi&e(5h&o+-uGK&k^J<&Rg$zpiTx zZZ@#*+hBj~uh0y?g#E`O4>J&*A-#W8_cOU({?i@P8a5e;Ufl zQLWwnS7?SYyW}|w^Lnp`w=T^vX7VdKXb`?v?-j3RvqAQc=ggNC|7C*BH?Y_8Ulhzf zMWlEe_tTSKyqcAN+-Cjs|Kl3*)01CJIXFH3*be<$_AjO!oKa?ZoXxfRk#$rs zoBPM<`n=m6%9>^vz1?&B^s)BGlCGSc>4)A0Z$6*%r)#YiQ?Q!C?2rY!%BBi?Ou2Tg z+4yEu441!f3i}e))tkE`b6-EbC1UpRcyjN4v9r86#it_fb?vO=PhNjK$}ynU*{EESQZcwTb-9Ja`fz->p20c$7j#7KjPx?GHasUef87=ZJ7q^ zC%c_yI(b|P^$Tv8X%NbB!da1_QKKx}uSGELV_CV>v;zC5<}QAr+1z#gD}SnP&52`pEW%tbB%Hc&)|0H9C!aMA+02o?Sym&mFV(`P`(to@(eyJj zY`XN8=H2!z{Tp)d$9x6ac1z${7ack9^y&T0R-qS8{lT)K`c ze$is~$qUO1|DN(UO8BII{E9Ax%J@9@iX?bX4ouw{!Co{ zPUtFPdEd4lL{?3zMn$0Ta+m&;BT57Hwe3J82{f6P^S`k0bpL37> zsk!fJ(69J&%GN(D_gxKA_RsYEdnkX=3?u(DDbhM>>(BbgIe)hNe#7@m$h;tXsHY5<%WKKb3=PG-LkAt^`JNGr=aUE;9T2${^MvZe8P z=UK+vbM6X;2b`a<{r67mV>Qz?y;3Z%H6Jb(?D@0ygigY)?Q^$wx$WMtplq%NxTche zQJA;*g`@p+lS9#ro3H;m(HR+Pu);yei)jVd0q(fL1WW`k(}T z@t}mFQimxHE5wUf90C~~8Wz0pVZFSNNsVz;f`|{xBG!cgDU2=$r-wSLI4k?L7`Yf} zSc$Y=UdSY1B_P7tpvLHUVKJvviKeH8Q;$M{`Qi&R7&C0;QVzw;NV1N&e2XceD0ji% z$(o;?dUWGnJT7{3dGo~0pER_7hH(U{TW`AY3{)vedv5>qr{bqP z*bLa&I(@zB=6{AMs!vplb+~UYv|&EC<6EiFfeU3?iG{wx96D9Ddlz3?w(-im zQ*zPyEap8w&5K^&%G#^X{OgWf{*xWiy#gIvMJacW-|_tHzc4H{Be}97aJszxzg3-+ zcb>Sdt*cbATHe~ZePYnJ7w1>4`uQ{K?7QMcYw}dyM8$7;S+^!p;PGcOzcoUV5@uX$ zzC77l_AyB5ne>W`+dDj#UD~F-O?73iFt>HiH@gIl2eKE!B4#9inDXJrlGH3YzAd+w zbDeI^mi8A>Ir4AXELM(FKIT6;N-BjmFEpCc@%h`H7-MF^*Eib41bt=B@^v13Ykkm} zowdBhjftgvQ#JoW;nsHD*R9+B)n9Y*I?)mUY7QZ{eMO#dPEd20$&`XbEdceS1sgg+ z6s&8+;^uWeMDayzRasG4o$Ioe)!KZIGnPyLo%T9zil<6t^{cWxj_Ee0Y@MwsVvSqg zdp6GAz5LMA+kaEt=dC_b?f-WAy07!Evak1-Q?Xv+Qp??|x2jxlfvuOAd(L`GO{MQF zi3dt2HF?)Ayk)B?d%7&>fh(W;g1h^=FBRCYJ^1WjcIb{v94j2|o`3lCXZwXk!93;q zzs2QkgT!p7e_ONv2*1aM7vZhMKW?V5FMVOOuP`?8j4 zoSfDzYBK3@?vp7WJ-#tLFJ0;6r7+v`ja`dZz0QAzg;DbJzfKg|tg*mB2|Q3iT+f4p zh2d8B_1(g$kJOkdPFDB$FSOB<_IHTB^)uvnWN}&eJH?O8lA8SwXS|e--&T0RtSfz{ z|5HJiJL1;Kn}c@UoS&%8`JnT6tm~xNuah$7Pd^=%^yYqP(L1q*3bs#S-cj1Jp@+|` zt9(2oeTJQ7G&iG-uJqB8nA~~yv@PPa+4C&_Gt5+Jah5MT&c&!|w(38_M)n@PpVjJx zlb)WLdiR3t$Lblca#VL;7oNWV$-cPN*N*>rSZTRVbotVW^Dl|p#m1=jr{`FnG=M_F>P@W%X;i=S1? zrD|~e)AxDkJlSr) zR?cut+Sm9XY>h47MK|H*w*>{O{RLif6>MIm5zbPQQ?U4!j1@;%_Ze-gM*(^prWs%P z@Im-fNu>6P8426vHZ44TD?Vwa$b=XR!}q)kUPM=If4Y2ozram{={HT!T|L(w{O9WK zxV4;ptJk>yie3Kh>W9vjEp8koEMMiFT2k$&emxK+xBPF4YFeN}2U6bga8QDDL*V(Y zlLOTM6lpY=(7^@EV2lil!j_kx{}B1dr^(>p(Wpta7ccF(^L|@Y_@AX}?;;kyxnJG%-lznQ!= z?7sSqTR#pNWVcj?D}9`Ka-!c&u~>m{z|_Wr;k)u?)pzFSE)vJDIC_6em0?Q>Wd%p*B*SXH+j12 z5(iV`>h*`cKl?9qStju>=IV5N`+utx)i?cTs7(H+P$jnS+}XLY=ksG`zI*4M;?uV2 zCST|3Um_FgA`&MpJj3$ka)^MP_`^-#mTAf;Pwju)w<}}Gsnn;(4@Y?# zt!c>S`7XoQt5`i zSh|u=clUZj`Ilw;cSnj&+2S&xKlHxIFA=TTr;h(=y1el}L!_W~NC;9UWN~TnaAsua z&|(yTjUpv%df9{Tvz3|1&r% zFH-xP%C|3gR;}ANey1LejZ#mSz3SY*WW@~O$nVYDe}-I*41Um?Gp~OA^w;|C2mWp6 zp8a!8*kgZ2hB76dyLDpFTvc@OxApw_{~1CBrp#HfW}5vY_J!HGZ*E+^^YYeC-E*0sn3-EYF+=H80+c9 z>ZodWdN=<U83Dfd~ zTU8S|44)SonXTE8y;W&(tXr3QYWR;guRrJ1zjdm-YA-YWb57;I8LV;z6&`;s9r(}S zchxY%y=C&}n$pbs+xD)iStuOMQFPP;vl*{7SIyV3Ni`HyRAqF4Coxx{ zt=0Pi)O#lVXNWxV`cl?PscfC;OMKSMs@Lj>*?K4ZJX6n|Yr462B9gYPC}ur<$7OBd z*RASHi}ig>*T?84>`rOmx_JAVw6n;Z62Yttt+J_oKD#p(J9va{{qW;I!^9`djIc5D`;k$Hi`ZoUI z-hagR>-5DB>Z6;_{JG{`xQt0ikS*^&1E={}yOt@3Wl!6emV%1pm7G)7EZ+{!<-B`m zOI6Rg<@LnByv*83_QmgP`}_4un}Ry8tZ-8K^;BnHO4kMJ6R(psU*%s5P%-$m;48mV z%iDap4YOZ3f?SdWls&C#Mn|1K>qz%#@pEdq7EUGc>KU4Tu`OM6l z93QT^KiQa@S=_|@cE;x2uSenB);z5o&{W0ZvSWw(!>7t6`Imn#bzQ#bYu}na zy=%8+`gv<{zp_vD-}Rk|`+r;bj)vAk{C-WH1x(e`g0p4~I|x^!E3;%a-eBCT%ZY21*8BTsLrO5_nLpP|dmNzI zS4d?H`Um)c9ZZUyaSO2z$5Vpwz>+_T_(8E2&yKagQNV4Yx|R7X1kM zRAwo5=+SS*QY`x*WdDe+n`nF7+ zuijPkcE;b}m$CQs)8{=ckJa6_Q$%3}sIB7S;h^v+H(~lS>sM1F-)e{Nw$EWMSj!T^ zA;Fn5?^{ z@$EEDM}}*&*7;legzi1I=d|VI+{)XWSGo6UM_)gFU*ns6i@AH|TkQ+S)8}t5=$NF$ z1#f$aczu2MX@A?3>}3%~&*c(%tN*EoeE(&?2CRva$6uIfGOjB~*~X+>>2*7Fyp zy$_z2adAfFxp2wM)R`x^rM?HAdB}JtI`*{Ksbezl-1ey6K6f*jKkw|{)l&_gM=j6V zcv@ttlU)D9O7-cRoEO#q(~kRlZ}Rmzfvdj%nqJkN|IaX~JxVB-f4%emOZyai3 zj?MbeHI?zj-v!pTnsG0-r^bo=XGkiw&(*D)^reRXb%EvlSw(lUSPeWJ&OU#r2I}Z| zeNV1Tf2UVp`JW*)BI@pCqh{~$nwhs>ME$llGc8y7yh*_G%IiaSpB8Prdbi`nxzB3s z`qK{WS2_N@@Ngtc==IjwA!m#)^;>V)y605PHffEXO?&r*$Z}1(*_&xDvv=n9^4rmt zOTM)BB}K0GXy!c@zvqI}KgBDdhT0VeecPhM**TVEN*_>+lX$;OwYKxw@7F)Ug||&R8tz!AsEtAyQ4L^lgl&;+?drPMO=#p-4vwtuChF)FVp7%P3{g>(T zcmEltrZ^qYaMXNTbNNM3%e#pG3{G3#)L#$ijGD@m0+|S7ahd9=wPyWe!~3gV+Iz&j zi_a{vsC~%vb$#hQ+n&toGv|1-%dWQ;{}Ar~&#-R2W``yB#YZu|`}MXpS@LdKBkgQ< zwaPm8#pC4FcP!n$Po4KtdE?hS3IBW5e#}u@leV3lc2zU1e$J*pnhZTp-2uV~X#se1m%KUeQO`d0bRzjW8F z>=wsB(1cOPga*em_lwofmM>U!J~L|X%@=14*}v<55q(znFX+oJYbQJ58AW9hpY!t= z%neL8o?%;awMy35Uc}is=lGO4C!TNGKEW}+Q1fAz(M^?~Avc~*+ICoUf^M<-jPGXB zFRgFPt2_DTcI*PtX?jQMj(vLf+U)x2B}wcBCT~Txr@nc6bN}IY$*TXp9j<%&pCLk5 zKK|!v^$mX%cS!#ZU)Xov+V(`CkxK|T&w^SREO!=#uP^V@Q(cx6H)+GuGnrQ!LwYC8 zk*b}#xP7fKZ`q5rpH7QzIkIR!W4Eq?ixmIKi(%6Gi!@BZHZ&oOkb z(8Tobo6F2!t=PnO?ETx~nhPr&fBfC{pW$`Y*6L}YiS;b6>h9&Q*(=Zf>keQ1vw7R4 z7K(C6?ENEi-{6;sS7P7O{vA92K5Ct`*`H^7=kes!?EZuZv$CAb*V=Uvhq^cYS$a9^ zl6UTnDywjP*|^ER#@w%aWP7Fs-`-O2{o_7c^TM~my0@Yh`kI~dgeUFWo}GKRr*Olz)}ywt9jd(<~u#&Fyjq2mNB6uU6(Zm~QsOmnXL-Ws`&Z9uvi^bIbi^7js0)bFMMo zcD|-e_Hvx9r^CXx!LdQtZts$dp8B*e>FMfckBV{&H$Q%~Y08@g)?&3)ANA7JE*jiD z?%ynHd;LFy=!MnY6|c4(tY3Vq=B&+Y6|MRI8A3v2`+hFJu)z0e@;}$~8~+*BbluE) zr8L0>HgceCv@SbsbMYJo{@R#oar^1=IlE;1KAcbeIqlr3N9Ug1d%I?m zc1&*1pXgb6aI#_HEX(B%Ke^xew4S?tII2oK{&~Chm-qH=zs{>>mnzmSImX?VrIGQV z{9^jL6O%HtzBh`_J?3zC+ugO(+l0P_-zwhwt904T-{DttPMucZu1t$-%wn|`XU_T0 za81_Yk81j<__wd^XY9U{ci#F`^xB!(tc>6cqaeT`J^!7`&;DPlHs1IoPsOt=+blL5z1A}Q zPTMw3E5=)!&MemWw&!?z7w24+WzjPvu5FoLd31}&8!ej+Yij^U02K>vFgcf*QNK@z4#Zj=$W?pe+IA1w-+sWx#_-+>UQ0{_o;8n zlN&g_U{&dl(n+Ej?Rx*Ys#?h{~q6$@k1pug~yWUG*ipNG(z>8*edf4!dyS=DM4w&)1|? zoJ&l4r=+`Q!@dW(X1lC%-$beep5=s@@#Ah4vo{Tp;$H}ex zrc=MV_LJLzoi%$WUX$y-TJY?~9OKW?$vqdMy{>({vQKU9lHR99nwjmJ{%V~sxh~Fj zIYF91S~R_OcIm@Qic-%`S<2j8Yy0K_|rLaoP(sj$WaEJX4>o$#P?)bA`x1##6!X&XPQ_nuTZBc4lSFCNb{P%O- z-<@_F!oPm}emZ&nkHf`#t2o|#{`M|psuQA9AY9ZLxA(qAfVPYAt;>@xXv{if=c&$d zd-K|$(nA;bojWpJaN=R*SsW{_tU5O%%2Ldts8XXlPEYo3vpehB-F{Zs%voKR$B*YN$z<&~?w^UM9+?rS|=cbrd~BYVZN#iurGD^U0o zdwrs6;_<`f1yvHFDIP*w`@5FS$zwjZ*6+op?VLZ<>;C1h+pEt0>t6lLpKHW!2Pg;_ z*8hp$Jmly)#$?bXlY?n~3woH6<4nyYDc@wVli!qfLGa&rCVl}6`G z+Ed}7pLy}hddG-AOE-HtclI!u+a6uR%kuGhs_5!U*Do%Ml2mr@*phqpM)qBIGqYaC z+!7VhNoC$q789q)yw`KD=6=9Zxw|MA1=}4Fk3ONb7n}fUEno| z?N;{tXM7L%a%D|)e%I5jhc180=}369H23P`H#+~WJv08c-3d%nG#eJCGdivq9 zQ)kvl&lZnaTbo+=>VA}ir2n*wd*kNj^V{!sdA;Vy);~*LJp}-2rOU6p*t7Ll zRNSPE-wvDI@i%nOm#@1gwsC>QbS{QnyMA7baGR&*E)=}+U}mVXJo_;piQ^1s*H_+PQoQ^3h>*vPhYZdf4>Rw1Nw}@3(6PP} zH?t*b!>dz4a=G`io@JdodgA`7q^R$UukO+R&ye?|zOHW7vp4VFf3WAsF|=>&-ta3- zv*b>+?f#i}-Qy$Jc6A8F@89*a`O<2&nA8~O!gXxzkCNDCAKGfYGF`&)Z|8r8N9w;` zUn;0yd+=FZHtV)494tKX|Jdqh)N;&7+$c1oF#J;3lzI-^JQHr&=K^O}%?oZ{miU%+ znbIY$fR4j+Z@u+;mb)$Wbw$*lteK&myIf>^uG@)kT-I0Y!M;_|+v)an%jRyO)85_o zTed9G%WLo8eO)%=aOeJ0+ox>*bj@5L)HjE7JS-?g3fW!=YCmf2+(-^p{o_=bfvadYa|e zx;J($PKT%Mzo-l8d`C|d5)5c?P!L(7$^NgY!!0iTk(#%vTA0O}S@HR4ks@dEme_^! zN9f94KY#0efvInr-q$tpZGX0kS(J-C<31U2-P1JVomJS<+|(4=lqqlnU+;n zbj~X}AusREQnTdd?9NiHt@`W5QrF!%T;K6@Pqd-gnMt?bs&p<3w-5iggDLDwW{-*P ziEY&z^bg&+bMLv~b#d9Zv(+AK&lG)dX;EuN?h@za$L{Ntm+JUWy7eF^J6-JLCHGz7 zb{DU{+_5_;yVcw{BGx}uWt#uHcg+rkFEgyx+}f{^@mtU4Y}&;?w(e6SzCF-sRQNkP z%iULe@kLpA>nBH^W^Fnhzte45bCyz-_9x3fcBbn}pI#~a@Rp_P=OktA>!E9J&Y6F7 zUr^`MMeZkkAMVopFzray+sj|Pk5x=QwUd*j@Xq(VvN=XvD%V1{v*%VH_7>T2TB62} zzvoSHDVM>u8OO^rdRQ3+_4Fj3J1R@Q-DPgN^3!J{+-yQSe*+^ z$4>CgF^!S^lkIcn;fu@@%am97u5@q?dE-fip`%m6{jq9vGeLBg8 z{9#F1q4!Sy*NL z>eqr^YyRY!yxtbIXLn`jmmZ@{9@tU{J?2Rldf>4GQO6uinP2xVmr5Q7MoVCy7WIo&EGF>mJd&LJwCWD zu}AJzLdeGRLZP24;?D_enQ-BkX7Jb4IeU&i`}lKO)ZL?ZPYdu>{teo)({|SEmyh{l zK5YNHck*A*k|@zbw|`pQ;XfqJQxO9h^* za4$Yy-`TNpeQA!5`h)xblDiIHQeawr^=Y@w@ME) zrnMeD9OxX{cdhN-+Mrd(p4`^?6ybCEqo8@$f~qZVBUCS3=T^`PmCU_4ZCd%f+*5r* z$$cDA&l#6iiF^0k%2nSEUn4*1mBhhP?;B=27cJ0TE`H>3>Z9$(Tl?Q-xJza-Ckeam z*K7W1y5N?D?7H`v-m(krLju6PVOIlIMU@He(o4!WOM9RH?CP}SoY>l;&pEbJ?`3QK zSTyCh@{%7bpWkBV-Ww1uopvVn&5mEmUmv~{x4C)d;&C>^iEh7FmXw~jeYe+Q+L8Ph zm*)ykE=+p!aFbbKmyvtV(Q(e!xtCv9Bu{y}KuUN0 z&9*fkC%k!EC#PO$zh_>$r23Tim3Ovm%Q;;fwqDG9?wWtnhO8e%x<2l`a#tqz#@6+G z`-RgZT6Nh49*IgHTB_SwYUUEPnO9u-zGeT;V;)(`zdf`sgjYB3J|)L~uh7ogP3lx- z*zfbl-MEj;tG9@-*FSC{(=xy6;a_R5lfIQ@w(+aCE2kNJtloY5^hGN!@H(Ym&04{u0M1+ z@|SFA(hM#pk8j7NpOmjUaVzF~?gEY(mDj3|Oh2uy^D!()zO%5+dOGit7ap&osw+k3 z_5PKK_L_R#+~Rkd+27AcWvX_*&6_pX>*Jia=3Ad7zS&VMvczT0;%Qeua=N*`eYBkW z$pwKjy_k>BZD)VnrN-Zx|F~zD^pE8WE_XC6GWGE*=)5T`QE|QN&iqMdo++P7*1c^q zd7{kQ=BSe!^b=oI26uK_$h-}domV*ZsbBJ;bI($8)V5di?eSHb7kYc$tx$?%S5wzKJ$*YSDz0NwVv`eOh!kEd6zeN@eCa(Ew`p@n zTIJ$-%1>|4czZi9eeT&u1?vuks)f#8ty|-ldgYUwj;fK{J@dBgMXnR26_xyjJ{D~3 zn|CW?)+dHX`Ci+naomiId}w)^bN22@*N#lK$$8IFa7RdY%9rW0e(X4Ku85C;;kU=P zvUT-pF@7Z_Q;)aK`t;6w-GjfO$8P^L`yqdww@#)1^v$OcIWLuN*YD8R{LNMsU}^d9 za(VpCey=%7-V;sw<^L&}n!f8UD{T2A{h#58|JUn_9{gvBZankn^0mhSO0EKKC#|L# z|5^9;NaYl-udU}*iuTqRDfT|xv-{Cbed(;j0bHa)BHI+ro+=10%A4V`N`Cw}l&xa0TkYS(Q;or_1d z?lvwHjDNK8+P5CHj7Ka|S*504@7i?d?M^B6Z#U)s>#22}Z|XcFInrpP@O+8R;d>St)r&Uf%jv zr=R5IKU42};Fjc>3wswZA^XfW%4$eormk@t`z3_Gf{8n0Pi8ka0lC2y5nnY%5Xk%ed8yRWTlcugPnKNYPmeA#x@>{dFDze&;Ibp}6X zb2w|}m$Dx@?G+~WRy1n>({a$B3> zj5YT9ktdS>FrMg~sl2r?#ctc>8(Y6+^w!Q?yZQ94`?D&ii_hp5&zGHIEkMJXR4V`HJr1vx7)a_`QgX!Qzreoy4WH1edCo~Hg)0mAM2GX`x$E= zh;ogpm{pp+%kjo;L(AfPS+B0C0sw3>e9WUoy#|W=)ZYu^{VJ!OQnzTe{YEmoA@hizUryx{+=-vF}I5D zetbFierVyh^4zNb46oZZi>~cUoyZ?0FkbwkVMRp|8c zcWd_<-Zgfrc^UU&d(y*tPWAWCe!af%p`M+2=FjD8udU!{n#7YD|Zb{H9cn>O`EL|JQJbm@yTX$sqpJylIn+xFe> zeUiej1#=gl+wwj8%x)Rqk3G^R7p`Xi*d?eE8lliWY3_&FMVB4EH~c#yyuw^b<@7tn zl#kInANXqMWt(46O1#O?Wf8jENgyow{NZPLIkVT;-l%4K;P+JP$Xe%S$I2TQJU^*8 z>D!9g$wcpZcK7=_`Bcf`gx8NsJ)?gmFYY`w=XCVUy}8q@s+$+`F0f5^*qquNlNMLa zQLXg#Y|7MQo-t+9MHg?n8++F3k>YKy}|pU%j7^YGH;n_@mS zJ=d;g*<8L?>;Ywsf^Yl&D6F%pLvN!j;0c z%U#~dD@1&Ace^fiV`_f;@)MhR_s4RQ1kn>UJ zs{`6bOCFXS8mtgQ&nBppKSB{RNoeME$l-~u}tpVPi=cT z&Q1K-Yq4VMx8E{lRsR{jrfuyye(}ZTqU+j^-dcaolxGmhc*wG2?vyCwH*1Zq?cZ|K zJ~U*`meU7PryaX=v+tWy1>=!C|NDD1JB~+8_q0jQ?%tAJ^ICMd+TB2b zxR9s!&lp=&=5;SF*|zj-NA(5+{_xYGt82nn$9?_Sv$x7yJ9ABJ$}`5iZxTDIq&Mj0 z?fr3c+S=DodHhT#MZ4?S1xM<{y?9kNO*m}oYl~=`mD8ms`$QV%ZjG^XGY+3{!EDk( zzR1$7ztYB>cPyIJ*|VR%c5$!{%xe_oU||B!Ar-40xguIowWF`!`1!YOJXg=&nYVlQ zj^E2l*598ma^cIn;FXIvCO%p_`N7jQhQ^kEip*Oq-b7k* zWzA?SKJ;zpoU4YVytye-Wov7LuU@>=|LE$J%b#2K^c3*^aAW7!y7t6RDP~@MW=uu4 zcL;tf`BZvh0zQ{kdjF(~>CX z*M1K-eAPH@w<`5j*tHAMx3_W3kQ8Q>y0Fsd{+cAg^@U>Fi#KIP@$|^(*8P%Q7&0}@ zeR9rvg?G)}3^qRML0p~dA~h>lTTVET`mt@1aVfjEiGptIth;{Z>b9y}+B4$bNqyK| z9lPlIEGxr`$;%o8Q>t$pmNItCvf7&YLXpMd`KiMmbLC}C_+2b4R&TetZ{>C0g|Y-Yos>%Dd4h|FYL2zsEYyl9%q8^LNkhUF=R;^-3p~Zk}{c_^|B(Lznus6wf4D=@UrE~ z+oB;GIEbSf#j=7h>L_T7E#9&SsTq`Yol+->xvXm457p=-Bi zsn+n+7sVdY4%}OkB$HjJE8L#)v2M+}SqYnV z7uMKBF?h!0`K|1nS>>nW6QuaUeEp2b^QJ3=e6EQ*m|I@CnB|hX{qf97+xI=+f2`gf zow70Zm{apUd(FMxCYfi;up-FS3v)UQ+Tr!P6l{cw_*GfUzKUBzvA*aPMCMjQmHVtcggewn*iH;52B_nN!@6kwNrU|%ITul`j%bicb>Sj_lxLFNz+6* z*PXF~2G{nz@pogNQ#f<^W6P#{j{;u%B+r%I`Tb1lE~c=3XA8rQt^R4lIPUkhx_a$0wvXc?cYK)jYFTRZWlf9h)7p8-yZ6t1q#ezj7HzcKVyRL? z<+OgiD$74BU)<}mvgK>Ze91l0=u+RAu)vG1XQ!W0;rqq080X{ z<%O(kw@eq7a+UThe0^uPAzzug&g`?#qJM|pzAwAeB!$;x#of?~#VZ%L&nPJPCikE? z_L5AN$e-L34_tPqx&3G0y7$B8Zlw9`-ec>y)Ov02=#*vU6p3B`c4pVMa*?2%SGKHS ziRbt2@p9mj_#kk=1v32mipSkN!6+yD(a!AHed_asrrzWa_T4%o?dNXR%z39IBPVsK z?I`$A$ZHX1J5i`R$>-C5292j{XWIPO)9n+k`)*0GDSNBwF$vwp>YHnpo{fyo&|R1B zGBJ90mqB@8bY7~*^@WW=^Ngn*+jTTzUhT8l*8j3o zzV)r$u`RixuW7+ry)ZQ^i+zXJMcwCp@_uLDr`*QR``S0?xh`H^eEs;Jhf9vs@sv&N zx_eh8I{&-w^B-lksoEB&e~15Pcz8<5yF56xW7*F{^%J72WdrlhZQy&faq=IR{|vEJ zb|Up>pZ}ac>tycMmV%hrJI7PAxR+14aQSY&XQ0lOWpRs}4o5#)6PYjUE~~BmeR_V# z%>1Aot&>(O1Wr&eQE1ZQdlIG2l`~&EIX}uHp)Ypf+lxV&yt9hZBz4wFD|RF=oBUSS z?fMtp=$H9fPoGBJ{^>h$pTUl322T^yi%CD8ZvHJ$q|+=X@$c;;O9tISS*^{Ual01< z$wq~)3r*FQ`C$4*lXEXq#6JBqv#X68w{GF%mDh^O5R0w76*Ke2#D-_5f9F&uO}c)K zzj_Y8^Bk}9&z{!^Yt3mlG5c((dh~F#h?AmBo~>)xwbORJbw+b;N_}fLJX`IzHFMQL zy}7Zhp3|IGF=)2zoceI>N(J7pCPA8;BP%2`RRS9|XB1?vSw*>WHGl(uk2oV zoSt!0#ys35FemThx3Io8^DXDT?O^M#*papAMc=BZ6J`c8a+7+x#JU2@OOLxPT`g%F z9J}f>*N;QH%{#i4*veCFL% zyY+>RZ_jxXQY>zBG{020w|%`$Y0jlBAtt@2_6h4my`Gt-EUEp{=S=4__qX%>pKyJ7 z6m|C0o3+AgeikkYw0+Z-DU~Jp?rO=7KRkY^YfpTWe91jiHOFvQ@vBX2(US>~~UPd))k;;)XnC->+@HV8*Ffx_X6%lDF#NJ$>K$lDuB#Cta0Ik8}EWF8g#YZPsPov*pGI zm78@J=Gf$#e7#l5eW_}1eTsIjofr2CefcSykN=686t%xAd&ZpXu-?Yr+-dQor%a0=t-tcKiynzv_uo{0GOJ3Q>GoTpqj{;1s;rV1l<#}scF6PIB1^NV zeaGG&S1Z2SCNK0R_igo!&eDzf`}`j5im3}pUSA&HeXes|?p6l^fRGPZhlBUpV1ZoQcu9kDoS#Usd-FTXrtzv~&KZE#E?SNvKSlytQ@h#l0rn z(dSYZ=YHE>zW7J}fqT)r1p7C?fAWx<_4i)+_49vjnbBk?d@9VkyyT(Kjmxw2?GGEj z)-=jDdL&zWJ~X_vQrMN#aT}*EC@R;fi_FW*tIdA-weqLJ?}cHhyI03aC9Jps-V5O5o57x+#HFb` zUAI=n{jV8&;D3g74;FK~EQ`H)^w^CC!AO^Tno$f(*`C@NY(Ht4yt7?j_Hlf2UuSPq z>oN!1tgpJclX>^q<{B;NNL|FZ?>fiwnOWYOJeN=I zMnC4*rBxs>J@4{XgOsC3 zSLa1UDzMGg2smvzFQ;tdCZ3wKNTr#RV%{$fS*d+}x9o&%{41^=T6^Q+qB%~R7Myte z@v&-7?wsel#Kq5KFOc;v?p?22ebc_X``XLcsBeigMZ!+8iukmxo0;|E{1MZ=7rxzj zxIriUYP7t1e`G+>)U`|gJk6ZEkG>>|b8XP@6p zdEeSletrFl#bqXMu5T>PT$dIdvp>;SP}ulx!*R#b^vbFq$>IjKf1mU#E$^8h)mm1P zwf^d%i~kue1>IJ&>y_PmBwVoFrG)u<+M&xA!v1PUl$(A^&Ph{w!I%;+8?xtR(d)R7 zlU|3MkGQT?F7*|Y-F#6aj`_yTv!}k_ea(FLqvAUDT+PsD>+?3<_*f--OzLLOdtC|1 zQo+Zazt4w;q@~tNwCqesy}GdL?bMtGNy!WErV3iP99sYB%oXO{TX(TBZ#bd#tgj(- zpXZz9J*qbz%}!I>G0oZZ^5cSW!5W{Toi+in7wW`l3SYx8m8m^2HZ+SRWJPuUsOp5&iwGPOw4m$xk~!pE@pe zGCy0!eF>xTbmo-A$-Qp#tCqbGi5xTmj=xt}Jpb53c+ ze$^D^J;#KeUsu+?uX|f|OX2RTf4OfInD~}{O}n0PsLZBwQzZAUjN=_jZ=YzK7U^yCjD~G^j*9DHXolDe$c`+qN&*ngb;bs}4_d-Sck11nop zul$Se`_J&_Kf}bR%~!T3Td;S0Tzc+)p((rPqqz1~`_BbC>t|oI)SmXk;p9Ezx3Oz< z${t?YmaCn0?UqhuP77$Io@3-0@%5XJPe1;BljTO2i(978QVRNbt?AM=i`79FU&~FG z^-`0(S9Z!yV`fjwrR>eGC+;%!zRfdh%h{##b99=_j0|_Ro_70w`a9h`GPO5rv8m|KUMho>73F@tLy`Q z#vUx6+;ZjOMAGhz5-Y4$k%tuU>R|ZvFs_85jzcEo{-L_0)8-WXV zuLjCgy3gFrZJeKTZSS3;9YWu~T)A3el6}N5DyWQgE0^V@iloFz?pu2@R?m4dM^XIo z^I5kt-@HwkInlgx*%ZFJ3nO&5DV)r=OrKRG@#4O+q)3dK`_cHwTOpbnDT?Q{N5urzTl_$@&=f?L(xI#2uCU%HOBY-5Qw`=XP7)^ZZq|UpJE9`8g?6 zZ=Z0xt#`gvx7lvn`UT&O&DZVrswmLSZd-W3a`_U`?XvUTx{vPGww!kGrVQ)f*|s|u zDb8IS+MSceCVuc;b{?~3VaJKTJ>pZcyT3e~ka={~XY(~jmu{ZEXUC3XJ}E*`K7LZo z%es`r`_@bD{>VS;L*?%d{e72rS3d6Pwa8v-)19(T%%{HxpH;{?-+A${Xl>FX6Rk;W>|(AoJ5tXHSpj_)pd^GiR} z>~{1mE1U1?<$gUrMgEy}XL=VtoH^^n!3EU}H^R5vKiGBTVY|ChbX?fZuGhS>mupwf z`+nwJyYQk%Q8UU);|;c2X&Hs`YZ~^QeV$mpO3>)6)~QJ|o3{VxOF3pVRnYRX^~S}n zLYJTTdsbyFZZ^K6#IY(t!CYhN>bsBXXGHebR8AMWc=d&{t9?^X@AgycCx&y^i2P%J zCU)0;p+Sv^{LJY83@?=GxawK{oZ@SK7ChyT=|7I5X^#tkX-yP(KJzThLUfAiov#xDjxKkE~6-^63Gm?y~YQBr!+xBm4sG_HQM*%bJiNTHPj_y#*qU7iPbSB%Vhp|n z+OaCS?9~dFMKN<~mjuWAMOAN`UUl!PyVJ>4RvY6NpIN%A_U_uJ?>B$!*GrJj;AMJ~ zxlVC$b!qO}*#|Ru;#GU)7v?+_R2Nx0X{B3?m74V}QCZfoY_^z9x7aK!*D!Sbn;I|S z=O_FutVQX``_`$8pFc3No6;rrwops$hSPJwlM|ol%q*O~vh=X??EDP|vZXO^_bf5J zc`jHU$0|!%;Fpmlp42O z(3x0c7~i_??!zg2pX^wxJn6l(^-a6=GyASC-=OpL&Zl|j|1->8y4pD6)$%QS`qgt) z{1Q_ZUzw)f6*k)=I%M~ubDfWijQ=zIEbK4L@!wv#`t2O|&wfXDt}FVLzwlYju3}A- zg{-NwcCR^Z{E1K7>_0 zB>pH1>U|V4`)Ty8w0Of}v-BD3HwQb;nRtF*>(jjl*J_xFwR&Iw;cNe?KfUc#ynWlX zTkg#prcGEam8*U3M%#4Ghugfee`jn;apvhQzH@O~@15-?1`_^J!9;*?5SR(UGKJDGb{i8qtn~YopW>h z$MERjx1j1nyI<`Ne!Vi|&Ew-*7cDb4*gT(jgt`x z)%JRmX385Ro!K64rt{uN$otqOU)$jA&KGuUyPPp^-CXmqvobPAQ+3be^tY~I+ODs{ zaM?9pGVN3I^gEZEH~05>PusQcbVQcd-jZ9@!kadne!9nL&jc%*5F6%i?_a#)Uby(` zy}!4t_qJx8i%$LgR+7!PD(>`m(@Pc^85iGNUs!7TpW*Y>?N9mCmFJrqU2FTT)Lb9+ zRmM-%G)PH#^UP|WsY`gP#Ilc7dCT}5x;!=i?6i=Z7MJdQzLxG#^{{x0Yx?4ihwje$ znyVdEH}%xvl`)z>n|zhJ%eOeGg)9t;__XIqo9WHfs~0(lUF4V@>>Ix|EcM*esOWv) z^rzjo2)uY~dh8SRo7J8#Rs^gMny{FCO7mvlU^dT-u8~obuRe#QS3X6o0c?%3+5a)$5M^`)x{)u)JVH*3gx_H(jOrQ;cS`%mAD z&b>QVKJWAX$qAQ3SJoOEPkr=q#(5FTA`4mRB?=#9SE;)^weztzvzDB7zNRERPry!r zRmP-JyV`Ay;k{S(4_~YA+AsEe*OaS=m*yp|H=5b_;oWV+>D!MTSDaKm(=_8+kF?hu zrTDZ@>-8dvo^f3lPL}ACkYHrUEj88puw?Dk3E*Oep=qAk^_kDhzTGx4KNYAwmxFzy zs=m>j=}$MUx31GX`-wqp+4byZTW;62x<8e`tBV^Qt}pa)I8_|{MrW;_e5vNN>}k`Y z9WHM?UK#l{e06lm#=i%;&RN)g_;FC)qG{Kz$BW&fZ!vBzWq%R5FoWxWgMtX#@_7=G z$F+Avm9VdM`Qmc&Uu66KJ$uf@9+U0a*4=cr@7~9^!lCD%)t!!n0m)1g#Bi9 zx#;D~IXmzFc|UD!VdTFsljwkNHXAf;UlHE?UOj{(SS9%uhSnmg?uN z{Ihdr)5pH;hGx<`+SgoQ;FDF%zwDamed+4ES--5U4!BLcJ=uRwSVhM#L+cawk0FY`P9j`8N7^( z8gjT-MrNL@y1Le5dr4T~jf>km_V@6KH~Oi)2TB7nra!xvcvHJ<*Xy{m{+jciNNetlKh1G4G^|rG zSYzhN-Ob8L?~_cXiE~Pn|5~;*tEjZnEm~?@#W}g&zWKC}9^*Tv+`a*{9d56pV`$Wtn1+P;;_H!c@Fe|OtZE8czL~ zKTMPVrtnjY$U47xqoqte$Y~P zXSdAGF6MXcGu;oezd1d#vR>$#`pZXGoE;#o}Zkf|9)0dKK~J$S60{dz7*7J zo9%Nou&`^>wBU#XYx-|4-!(BJt);mAxVVX!;F4;757#uAI`=f|4VNA~y1@9z+PlMN zF@NHJhF+Uxhi9L7wzP2Sv^4?;Vps4N+JuC+rhbY0TejM1vZ5CgBctP%S%E_5p1e2y z_A~01`~B$PYd!xNlsLETIhd>bdw1LH%JTLXT1{s+nH~_E@Ssd^71zxA&7W0_g+>&1q*TOJBsPmax=`Lx}UgXev6Nq$d;^L4q8_92p6p7sUqpDkTj zt}<=9#j_8-IdRS@3c;b9quivvZ8@_151Y! zExju!v_HGKq2P+((dAArQeRkau6aGh;N~Bd)I0vy9=SEUZFqAvdA8B(j%jHZ&zJD7 zu8@9bzItua%qm@}#m9u#YzqJ8|9JC`N$hj?ur$}1+;=38M^7UJvF5<|~!c(N(zaAKn1)M?N6?qbd@YkU^D<(_uk+Bg^gp2Nzy z%BiPgJ)Kx|1qkZ48R=u{s}8JP#>r`vpxMk4Jmo>Cl8H>&mM8so9bd0p+&tnhT;>~&8 zNbK#y45`;Hhi=9cO;gg|eZGI1;fD`h&Vg@*x8}UO_N=J8W*<=^lUx%GK!|MVo6C({jP2ZAz zXMc!*v843%+eYcP#O~g*-rMsnS1v?+nx)6OjXC>y71!kp-`u;r!qM|=n7wqanBNih z(-PO$?&apYak{*_Uh>sR?q`iFmU~3am)SLcW5DaqCGyF6-%DHVW#(^W-P>#}+PzL` zO9A7as8+*O5$Th;Ytq$I^cOTediQ*H>%&b28!k+6J34Kb)U~Ilz5AZ#_|EP=qFXcD z`wpZ1($sZ3+V=hw){c8;w!L+Y$W5=jNTm(eKhK=rd-v9Cn{z=Y{xi7ROV?$8<<6Sg z_B7pK=`*&;cjYc@)>$~&^R2(jn*g(S-#UU$vbeN3I4CeGOycF$3>6ks-jnC##E4C7 z@3Hl|CTpw3JZ|e0uTpsvc5T~6u_G*nZ}qILzJ|^|^ToIH$EKY(RiAa-P3@b#Yg6l& zdBGdsWqzv`+H1Xa=a#Ko|E@W2^zhx=9M&xt|9(DF;LX>(Fz@AUe$hI1vv!Nv7Iq;#^PIyoO7IRPqmDy**NdjySLMJytseh@;0Z3+ZuzecNAO3yywhW z^kkiXPKna9CleeiF0Gnx<2*e-F*D%N+qb%v?W(CcHzm`PMG||a-{Q5Jy481P=Few0 zr>vHlY-pkV=gYF`;*-RpP2Sqrt#*jISDbq>B5iN-VWUHbWo1>?X9)RyR@w5??^^fG zUw4h8N-O(fp52w5HFa-hwxW0LBt13D1Nn~JQa5b#^k#9VE8gYf`XCqP7;=Dvk9A3i zh2V3p>3to!d&~|+9Bk-%Vqo|1d__tBl`h%SN2={=cO9wM_dW0^ELpe1G=@9w^1awo zVHA^9swg-8(cP^d7G&|(=vWT75|12Ey*lvDwzGwT% z;+)hYzl%pV#%;W^?@o~F%dl@7q7R%F-)C-iKmGi-&0arlZ5H(s7U&N*>gaN*)`>w4{Dv3>gN=ZqGej7Z9V zE^f4`Le=i}ty1;18Rxb2<`gValz341?wa+>$8W>>ywtni?og}VY5vn`OOfc`O8qCs zz0s2%F&75^7Fd5!zx+Q#-)GA`o9p{a=HzeRRs8zOFWtT7pR(UBliRd;gNKWU3;1A@ z*N$f<9#^i2yYTQrK*-sSNkZQv&fY!tR;A^))iSY8#|_)g-ZZL+xoEnl-}ZvsYp))4 z&5C=mThm3h7jFF|9JZyG!N>8rcE;P>#Ud%b87~(2D4z;lJMYuW?H^*IXDmpLxp61c zolkgG!kOJqXY$OD78j1+$ncX_WMM{wi}T4p{+&1eB{jXXV!MCTo&Q>I`jTy1Z+4$Z zk+-o?TzH<_+Gx_FXJOxC3I$l!Tra!gWBz`**zA`tg7ydsf%;Ta8chF6t>8?xeP>s! zJEg__{p}qu9$(pF{&CN4O>OUb!NQs#W0mVsC-V>A_i(@2r|i3Wer?2yd7CfR=AV&> zp5e0X`^1yN+boyp7+%ciZ1+2tr2JLBQlRnzpJLP(#m=d9?z2Cd)hKsf+T|Z+wk5aR zX=`G4xsqw=v~BgC(d+S}-+F6;$!)HAG{bSCxz1R0_PPxq^yT#<8 zzU-go%Hpq4HJ!ibO}`fZ&%u3cohSNZ(&w?0qV!vL>hOmEN@d$K;xQ z{%&|(w8y9+BWr2&*S7PAHIyg4R=LS8oy=1$RmLuQ?&-ax7{9zVXKeWzxEk1#p56L9 zZB17DtYVS#+n?nnPRN~f%j^jIp6{8z#FKqDMoe3B{axT^(c9^>j*Ck^+H%zC+NpA@ zbgt_s!qXd%e!3~1RrFJ0%~huM%==rbIV%6O$gJRM2x4(8Z@y4JF|67vd5@8P0!>mi(>xI(C7X#DrVig<;))~Pcv;de^S%7 z{fpMe>cuy{wc0RkI&g8{;|ovLKiAp*Z$)0;)ab8op5(mS{q*uTVg73z9q)SgtO&b% zs;h;GW!b){Wky@mdCHt8uJgUJU94Pg&3Pk6NN+;K#t;KbZ7`*RdBd_Y}=>4Y1S7yLqAQMvp^{9SEVm`K>m%Q%h@YO<#NNEuTdyh< zGp$d(fnDtBp}V`S)1+e}I`@bDXE@v!dGyvNGu!WiThGVt?NJ&tOsW`dXoGUFvGx z*0)#8Hl8+VZqtyADmC53dS*{$eyrwgx(+`Dk!a?zcew*tS$d=7nZyr||6TffuJ~iCj zWM=$i3+wf(KMwC-WOt)vJhy_0u0luVnYcV9YwZjzMs`o~w@xnmE-{EgRqFIRPU)wg}S zL&8IBzH6sXJy-u?U5lxTN^5{+kf;~Kt(KiL?-=ZPzmz@mf=>7xr>pOIzs^1V@kdXX zmges6PUpnr=8AncA9pAH{H|v6E&4x0e)#JAR)ueYn?L>0KlNGk^ZLSxm&_fdz4V4C6D1+}K8Z=<8$wx-vmKD%DF&G@K&DfipF zM7;!EtHLesxox~YD)Snzd$%#ae9OHLC#-J1S}|?CR^834t1{WfdrmKNy7A@MgDpF4 z@A|PPo?8C){qE=&;g7ygzERd1+VSsZmi?zWVpji(PS?L`yPF@rdE(|>&!_j_=UcE; z@Xm>VrMstsj>U6WrJy)d^p(p`?|EXfYXhwwPBM>@nUQ<$#;uyJ$;&vN+>#4@Ja@s4 zG`(|oIObU_$)2U*+;(Wow?~uCuAgc&_rdo+y*m!>(u;of;W0}{iuv*kY1XXG*;{FtAFyXrJ z#!7VBYJJNjr$6z`{cDBq94`xZO?{YSDw{EBrKh=4l2^bzqhyJvmA zSUK5xb?5MPOIJRXz25)P$b)yujMWlv&y=NId;jaYaGcUs<@UGJA#?`GBtuVX38{e8N93*!Z;EU#_9lVo$A`TUq$b!|?Zf$Y|K{By_^Ctf~zb8Bz?s;hG> z?z}Duw`h74rEz)l#;U!gM`N^0l}}`|+>0Uj!d}H?KY;G}$(1>WUY; zCj6Y5{nJ|wbk?-lRPDUIb5?(kF8Y4o`-aFVyLBOp?jF(-;9zlZP&#PTu-<51W3a}@ z_8C8Rb02dTH~hw}l3|-1diI&S&!S|0(^C(1i+F63CI$5tJ$?PeH?=BvhJEH4nWLv> z%zFH8iRzNjhFQTIOG=9t-IcETeq^upq5PkI=R4EXXB|xO`CahTD0z!`GRsXC*8K>E9)@9(#q+!Wyw!@hHy_1)u3LzZiI zOV_t=Z4>@0laoG$H^gH?8{-0&$qr^y{Nzj@9XGl4q(~rXt%{IyR>ksyD}^OGSKG1z zTlHCfEtq#S$IRg6qKEg6=&6@=>o^4$yg41^TlCB^VmZTyx#zeFHr?@_RbA^LC40$h z;(>glxobKq1JzyE<-WZZ=2q1jP*nKy)<4bm^{q^G@pG0xx}p7RRmiLA>H7Bi=kFez zFn3v|LiWQ_%{Nm`vx=U2KH9DGZbRg9hi`jaPUOvU+fsMfwL3j@Z|uiS;c;>gK29p) zox<~=`dyNd$3s6w#VeZ2U4Pac`e-chSzolUEdA4()ylj(cI8ZnnYdhdp$Ti)N1^w> z>{8c8bpG0)*kID2<*|S{*X#Pc^Z8jv!s@^L5}vSdmW-a&p+`?2-O_NGEE4oIC+zy=cL+=>4)#e?s5~)<=%R9{#LK7j=na%%6a$sC+yy_W9oMEZD*2m zAEbNtuc*-gQe6Fgi%wO+h_EVQ^$k0FH#~nU zn{CTrv^{Lnre~7H{GLaCynXo0%S>YZt>d0=+Jm|_mBdH>XgoE&yy=!si|e}u8IPnx zw2dxqxx!?cc|~xeAJb)*Lr!xTJtr&*oK$GmXFYq%3XzH8Pd7C_T)HhR@503I{da0Q zg|$m!PdwYY^jtx<+jU_FL1BKikN(H+MLbpOmae>AT=R(eNJ%+&`IM79+x34u)VH~F zzW*3!?t{+ezQAP{*Imu}ns)uFon6%NBagmcbDw;~`>dz>(wwlhJ645M{1(f&(V+Fi zVA74p85b8+icZpMSou=RalNO@6a@j%+k1VyE^=AVl-D;n^gBY@dQC)~c6Va-HxnJ} zZ%3o%%u4k>E0J?7@6fB;k}0~bPtFR9&wnw?j9=@ZP1nYP*N;p4Rg>RroZ)}E$eiuA zVz0`nZ`N0Jth#i*+!W@qS#jpH;Mr}KJad<6OZKHqKc=atUh?IFnRD2yjc;xWys4_) z=r6N6XOGsipWdpveNqAskCgX@E#2-Ww}0Z>m7VPiZy%nYuYWq>n?zpLwK%`K>w09J z`I9c~-SjEiJT1K7eA@FG--8dfH}-a&yL-FB;p&x_5vx6CCT=^|S0vfJGG}>i3t!0| z7Ps#i*VfLBQa{NH!4hRx|4NU zxBQI$o1eR9uDK1@LFCSd@ z(=^rIc;K?+s|!!wzPvc``I~8~KP&v$;`rW(-L>5<<977M)zfo>F5mXoTB-2NXNz0k z!zsMaopzagyZANZysY7z2M@n*J5svkYVPHmVG+-rd}?m?ly8wacVS!hxkdANmbjj& zm}$Q}<85Sp+NA!z$o~w2n*;blrbL~RdATGf@8JvW;2ZDPWX&*PCTN3V|i-tdO6=PlQ2yF)Jm76h;`u@tZfxH?|ADztv*u?Y9< zqHhideEiiG?R)9rV^{G0rs(G7r7VTh<^LXc-57RN=2P^o!xLtuvz@eAaAB65?5Wg+ zC*SLuAC0cNy04V4sDH-0gh|hiuBj;ATgwC@gUj(IuvwX82g z$kiNgeeJj;nW8C+Y^E;0_fJCh-Y%iHTgvWVTD$&J@Wjh8=1!lk&9Ay|b-P`gTSxTm z;(XJoyRAaJ?3N#zp)2dPGyt@Ghl7Plg3HbP$d70Z zc}sWte%_UYWuNuBIPcduSQv+4G1iMTrx&+?zS9p_k>tkT1i>wP2hb@J_g35M-+kZe)3z1Xy0=8; zJbdi{efs>`LeZl~TEFD4d!F^E>eZJ24C%&gTXJSrJ#U?}zPR(4XEk$$ zY>91DSBAKIuVl%NtGP2LpWM=RIwywhdh34PCyi6n_X=i82b36_%{!^Kx5G-(+PwOT zCrpqtM6ao)!1=o?at(Rt3Q2QX?J2JcTld%5%*L%dD-;Z zRMV?xlEPz8eGk1o>#~Db)Vmppb1S27--?Rv<4DSuVCP^6c35;fEmB*~w&lCQ?L+a3 zjB9Vk{`H!Aw&%=hS<}Do7LssUOl~4_4%6Q2yVAqSLRI$51REz@!9s=*?wO2zt(Kj zF=)9aeSG@D5?BKrY1&piDjSk9P>5Nnqq67 z&W=0T*}UmqTD|7Z+Ov12-PpaH-76;Jx$SOl>+rev4|Yti_E);h(|h*F_3L~)cTD^= z+2PRV;6rDnRz`eybJlo9(JjW?D`i!~E>E-BIVs?j@P=7h4}{L0_;SndsbFTaK>xvF zy<3LMi%v?f>6fsUU83_nt19&M$^D4^UUc&Cnbu{Y^plGF+9{*T|GY~$3$@7v%5h#i$<9&CJv>wMN49rim91l((4s)u>x-2W%3|E==ZH?sdGaJY z?9%=w%c$>J864Jv5>_1?ESw=+4IEq|9?K`PnIGBduwg@LskvOk*2>^-=05`GPB@UZ zahZ2>F~jOx2U0U$SYH>r^;t6Qn^f|tP=+RxsL6aLU$j~TnVJ@JOz;gTdS(c^RWDmr z-(YL5LA#mKu_W(Dnd^gYuGdPOX6~c?^r=ko-6IzdUJ*N5`R3y(qj#Y*+qP}b@0zXg zNOXU#{g#=jxo56TGX0qHOonaW&8xbn&lqPvIezuU4S&JB+=nUQAHOeMG$%bXMlXEs z^Ci1u>T;ELrM~aH6x?==G4^WAjR#SeXM5M(yC0jpn0wZ|$L3{uMtqN#Zxt{OLef^zFB3)jcdO!8XwjX=4 zql)f4&YD@x61YiYrigQ!#Vx60eGPln*47!kd%aBYuGgs(US_kI6y^wC4(m4(c)p|K zZNg`z0_zU@Gy#n+!;Op2G+|=2h+$Na?7mL2Vomr;4 zPHUldSh^OAy@_pW~tVhi*3mG}p z1%jFuT@cimS>&em@oqf^tt?ReN%E|t_E@o-{%~@Hofbo*2 zS8J|U(UNmk-xXyK`y@ABJbd?r-}k~$ANP0$9RfzPLrLr;oCx2 z-Av_s$FiO?Se=?8FdVKtuJ z_LC;RTkC9B=*(jN^LT&m#4;A%$rC2O*E?a$pm6-N>Vdr{qNCh3r$3w%uYG!LzU%Oe~sZe;!{ z(|cR3=Ptz*a&}t#tl~_)XQvO88EM?Qy8C#6<>&8SJGj<l@cXi+;x5>%Lwevu9qW^~>k8wi=!Ietqld z*=5=1Jj7JFon|^2&%PJOP&;FGkkz>(CnhXpWLVDN!}oCKv}>(eV5!H8g@2(+sftc=3<{tPTXBAeZ=~JmbIwv-RC09{^y=K(D%)pSoSw^ldgT>YG3%hz?Z@wm_ATG|qq~vgeLHg}Xj4L#n`-~W zed?R8X>%x>F7=N(ac%C-9u>AN8LT3j&s7&Px`{3MTCwk|!TYUsQnROh)=ik;=EHxj z>%#Hvo3EVCpZoT%^~pukT6UPtsjt+&e=B5>$C=v2wdeHi24>itu8^{gxMkBZy+%1f zs)U8p@kV=4yVmw za-ZzocbV_Prd!3bF@EV%hBF+Kn_HbOY)OjY?D1Y20-A5`R8(N{JJ6vlciqH7mTQ7| zXZ`mU_5)9koo>}E{ZLu^xrO~;>UTeZlf3iN=GTdM8TmJ#`FBTgQjJ*t z??WomIv+*E9m-lnzu&MqsSROdqI*TD z{5qL==kFO`T3NbcM(yHT>p3=xtO^yrnGsWTE>7Am_N>D*%S-Gh95YsYow2iK-FxTP z`&Y%~=C0wfRlXE%^!H}Ut7DxdB8pP{QQ7Tv8}er;)Cvf2o#YTxv+{hbeR&Lh>UVln%MOh$**;`zN??Jv(M?|yLI{8-`vhA**m4~U412M zd1RKQ{eg9b=T4kdZ@3X<@$3Ec+Yj$M1S!?6&U^miqO8G}cNrfh{#o6)eKu39>Yfns zhTjhJGhdrTKK@>`=e^O?rq*KYW5AbiHW%s01p{5&{m zl`<8p7t>EUOE6x)c41Amew(jZx4*0Iny~Gb>W7Qh?(KGFwhKPD+Bvjl&8yGm6-_?!_uq=TJK?kMmaeCh z-84?FIvKrd%f;j;S;td8{0y!-KiQZ;!6NUG$(xwoxwrPLI^yrVS{ghm#^D;}9>g(i z?Zh(+E-sj`Rw+1{Iqxd-5~h~MEeiWT{AfJ;ZP)9=sx}KtcGyp@ZvSc9SrxvZp<&Sk z1wlm~7C#2gW`-3G4DW&)`3>Ij#6GlMWWO}%h7-Tee})A&uV-f3m5VZ+b?{>UwLE!?U99NJJLv`s+_O#h{jR((Kj&(B z#kW%*=0sn%%f=}n4JqP|J9^LYOXZnlqEw zSKphe9$ztaJMXP4SKqW*TgusP5A1zgxyb9<9J83?Y~rFPzg^pIma}u`BsuPkIT!pZ zp1qCv`}@({)b?=o)ZA~I{;YkN-hSt3XYb|5vsu6Ho9-j8u`2t1bXke=-MrP#nGeF- zubt=1ZH{q2B^p_!onO5zswQ0Z(=`qL<_&E|=51UnPkWbdx?T5aS58j;CI(q9DdWm{ zk1~>GsUOvLemtRIZ+jx=l&7D+chpQRK5cX8^=sRLpGsPMC+?YRr=EKjZm`s9)|*#B zPaZRM35s!~C^4~G3r?GRPiMmWEq@wSk5sNaqqqD<_Vb{F`);)T*!A}DTh;OecfB%c zvqH-|etLzkHP)YayX`}-Giy~w*SX_~z08h&M}l(o^i)a;b{-DrZ45bb+H%^-Sl7It ztrc5DUaY*e`pJ#!tF@-zk8*n!vnxIJ+}Wg_96sx7bKjdyU-0O|%XP+@GiGNl*k1ko zT6MdmTwU4I&Ff~odiL4ur<-tVSj^4~T3O4)KZZY#@Uwk)@4CtM^RDYp^lzOW^5aX; z_Jo(qRyWqYyje3fIf<)a!UB$lCF~9Xh8dcYwkj+6S1>gMGP;P@blVsd#{`|=6g=`h zW7iyx-*e@}pL}IJGcBrWQud}^)hf&KKKC;g&nHO524!4uyJWWD?an*JjlaDLX33g= zQHVcRcz-Kbz>74)oPEj++NXa^zl1 z*&M8VId9d$+20EyVyzd6{}NF+$7aW)JK^6Fc`MFW3(c}GuA22-@^tx8K5tFwd)Mau zv0*9~*d62g;P25thEC6qJyh9uCWk%f@q*~GIclj(4}6N#x^{lg-fbz@ue0yjHSvMe zhVy74$yFC|;8yt?H6 zq-(QUr+=47@8<6AXE%7C{;hgu#KS$Sug`2%?^v?uL$S{JL$TW&cUY#cx01*`IyL!^ z&a-bq%t-}u--S;8o~Tpy$m8Hcy^Yg$K8y8~?wM%0V8azAsjcR@pI*H#*m_p8eWFv8 zQZ8T9;xpl9ksk`OIwmyPuKZm+@z>!Ci(F=DI0`Z{EY+5aD*w;0DQW+a?O7*1UY+)M z^}SB*<6O7P``6|iF51*SVOQI>jpE^5@7VUuy0re@%F3WmU;Xl*PEXHG5b(Ye6J@v2 zZdT5X9rup+TW5A8KYrI0ZDi>@O}=IOl(YKPr3H>tZ?nx7t=N-!U2sZ~+0o~VotR#@ zZ22J4y539m^pa%TeQnv)N5yVE1_Z*Z;7IN*Vo$yO_pUB`yTZ!u*fk9`H{HU=JyGU zox8F&C9bzNR{pf}$~=eUG*+=sp~bR$E<{vaS$vP#J#p35r_pbtROiWNH|M>av`RtK z!$FC`S;^7kj^BeN=K0@!Utd+RSiqp+<~;8j*Nz5Zp&8A7d$(p>b66`f&EvY!%^#7x zQ}5n=dO0O=_O240>|L^Z%POSO)b*AN`y6@t%E0NEt4xi~SBBgSbG>)69erJ|xix;| zp1vjZLT%!0vvy0z_K4FNEa5VRTP9oIU2%7(V9UnroXl@J%l*8KSN2;lWpa-nCMcY7 ztZ{>;AAgPNiksXv2VItP?6l@c*;K9Ey2r0L+tJw}nCq74bcvbkmv)Qy_il=HF1Wq& zUYX(IWY4JG-+mkuJr;HH=A4G|{_QEfh3i+8E_&p1^t_C0<++wx-nJ=>15} z;>h3aeHy>F87cm{5}T(wnOi2cwIwo#JMMr~9QV93@el8#tF5&+RoU8vOpeuFb#2;| zlio89hVL-lee$B4pwW_pcid|yow{#&$WdnPw&Y`57TlSqaq9hlhDDt%Px`8r^M(7l z&3C*Bm}6A=F1hqh--cuIo3D5mm|R|&y0++Kl+nbZt@onRZa+?}+3{n(_eF=KWz~IKswd>`a zTMx1rY}@xXH0|tMo64KEB9?stJKCo#e744Av2ypt?Ya5)TpsT{=s#I@%h`0H-c$GF zKj#}d>%KEP@?B_0!T0voV@>l;hP7En-mi#0KTW6j>CwG!^DdnA>Xh{Ex*fCY+5?Go z5*aV%F5Yv>XpV5_^2C)vYj{H*iS?)^xfcESC+lCw%N`K6=4;&MtFO;y%jfDIm49_a z=5Xx#;vG&mI&+ThGMBvPXC^1RP1=Ajs#5paq~z5*W5XpizqF*V)Jvn|@9 zHoNGloK_TJ^oZgrDOq^s%=EI2vn+qDc1_J#a&qz1&1`d`rsnsB{m^m0ci7l^$Ng}T zk5kiQ7i#t{cDTc|=Fm>l!s>j6uXEQsxvE8KuS*Rso>!^jqIqreb^lLyt{<8icDmMP z-sO|8A{WOvFZ5$k-sLW<75Yee%EN0y8!L0#j2`%>8ZW9az3?LJ+T43OlRZ{n-kE$P z=k6cXWe(~6xA^Yu5_$5|**#zTP?Y{-oyRlXoX*)#b)Eb)=|6)P@6j`VP8@Pb=JoYh zG=Iu}20tNpt7lRcv00biP5J5ZZEAt#`Wf2C?`&?!<4R7dzr4!v`Rt3btaDXf-dTQ5 z>_3CsGW(v-HKAr_l^1nB=lIXyw%p(P$&ZZN^6^WS&-~Y0Kb_~f&DpHi4$*s9g*W_X zaN2)*_Px3j2Qy6`o$Bpuz1zN2>1WFI)7`feXFipediP=C9kW*#w+qF3q#5&PwI^tY zPhNEG&AS(me2#^S|7ZAQl*jlXOgH)E%F0XKetV>Kf8BVOfA~Lx(8ixNXYanZ@HzG& z;PGSSD;XiTkM2!g%=2;S&XYfuKRi=tVdoZe`EGWY)~h{#1%F-Ew|?d?zHy1i8P>%Q zs`t+9yih52ZJ+GYst>wa-1%aaH$QeLPu@GZct`fCn}21*A6=Vxb>q`_xjVagl25w) z)Yp@FeqP~z=={*6busUj_?KSU^R#W&)wR_s{JGY6E==8XOmyF?gs;oHBGt?v z-q*}#->f}5oMD5Hf$xjF*Yg(d5ZSqNUfTO)R>r{Anitbg&r?h^n0(@x>9bQ$AGw=X zlxi$zxwV${dr!<>Zi}^#rj^U~E*0_7HeYQz>7(gR{e42Nxxd+RH3jyTg`VvC#W^vg^9;<4_+g>MyJJNcm9==;(kzputA}3Mg-SJ!2Pi^`meqNJ~ULE%B%#3Gp zQ5(-haXiTo7o2AizxkSU*BVV8efv)(GOtgShY20Jv9np^P~rpz&WF-_y0-P~irYQ; zg<@L+6>&<-6^-q5?x$&Cbx3p=>+gihYN z>zqpEj7*)BSMEVePG5TY@Y2^a_548}>nD5&|I?a!?#_Dgf_q|~g(B{L>@OZa4}S9G zW69BPKHk<3>eY(wTl`B*oHWnv{_TR3{G8twDaT)$n73TN-K6KQbY0dHK9477=1GN} zdhYX5?z!o)T?K2tWMyx0QgfeKzU6H0smU$vZsdlk1B+W;=%ar&T2vUa7pA%6aqn_loT6^UK7m1lbL9A0Cft{4MdH z!8^dq`U;O(?z!1V?zm38rr%a_iFwl+D^2OOX73$>>%PcUKlWWPeOm52_pRBblIw%F zgk={cn^vk_3fWVA$VA_}0ZB?UMd zI=LJ=lYbs_GBSI3%j8&v=gU=3KQBt1A6v|2)i?F{yw_)Z1mE{AT35hzF(hoWhIr%* zrLU2%tqUWySEX)V-)ppL=jl71@zE_Mtn+p)lGU}547baa$%+ZfSYs9SV`@i{OjYQH zlfS-NimXp=%v>nVwdT4`bj8*g-gS8owzzq|4fzps^XuQhl)0azb{<*nT5$j3p^m;~ zC&TiN?Pv-V65!~2T^F{0)^*E_WSQ6}P3qeV`J$!Pw;NAC`nj(^>xcKZNz!>2FKnx; zD6~Jnvrb&|x7fFtU+(dzKLxU1slRdjmwUHH_OD5{*8Ghe{~64lsc+h6a8hOir=)^z z0efNiay3P(AJwL}b@t4YjkLYvbj~sM;OR8Wsbyb&%Wmyaiz?FX(JlBP_0eR@^jWV$ z7f%n<{w;gy$o)_9hK|NJMOW7F78*{x7%LV(Z!*8{u_s~KlBVJ+pM}q_&57XqwDxm$ z%FWYD!!7=~ZcofS;qmKzf|S;IwFyr?)!y&%?~d#{_E6{MK_15i)#tc*cS=_Fg>SjL zDNLud`R{boyWMgzyK{H?u3f#Aai#3}c}IR&2WcL#&RDB4&$aVs?ede0Rw>tZ{w!Vg ztlua#f8M#-i8;0hI(|OAe(-kK9;Q`dz1O@C$3!K5o+cUYdhE8R*0(L$hn)J>+$uXi zJ$%dUACpgh-njn9v&|jht+!pvwa!>gtS~Kpl&^NgH{bbmsf^MpgUTa@Hm4tL?be%F z-@J8F=8t&Zg9Qt83YH5^epY3#9vyxA(>2QtCTv!Udh<2^ZTzz0(0>M%GkRau_G$&K zddAHj6Is5o`J-9i`$fu`ythQu?5B6vpZLQ&EqrR>pWAs7dT&pp9=x=)-AiC)*6w+$ zr#}`JTK1uSzM=hp2J2Hr=W=$Q?eLVHnG0mX@xs$i z+s`~Ydq-!QxLEA%c^31`W>qg=>GZ0nEzf!no71)YP5ZkHZYEj#dWdqgO}e;8?4t1# zw}a2J*kc@6zHlu#{8Y8gUNBcL=7Y?E(^=v1Td#WDc@w}QSNS;hPr;|Hdu$w}SFgBr z|JiDT{6BHFs!un|Tu2eE-VuE*@ZjF6d0HVHEFP|3zgO&gv`DUZ`G+t68Rnd`Um-VD zuU`Ar7m*^+VMw5xJ|`^Un6u%YmYLhFNS|x7jGSaX?hx3z{j%PCwv8E;A5Pxo5AV6W zv{>E8+W7UtGt)2I1nik=xK43$JllqZz2|O)`HQ{VYuaw2RdBM0K}0EKMMKB&a3ixd zuemPF?BO_}o4M|)(BAaLOF3qW1T-|3d|o7WXMOvL`%mAxE^+C2ntfl9h0Ek>>Qc3c zwfnZd`yTb=m1%BR{MF4tm0L>Of|suRHO>8fn9TP| zq{_bx*?SJep1)Z0KZDmgA4|ne3I0iSJ@a2)nR_q%TaTT~Uv2r97s@O1r=2&dn>wvO z-KlYE#?`a7UYieXw0Y$jZRaDKoGEJ>GEeog%-*6Y^6Diq&o2J1aQEuJvg_lCYdw1F z8dpCsiTKBT=s&~e_{Hn{Grld>mF-fGz5MCgIp4o4zs-!>bk$#awbj>?(WSkmQjZSt zJrdH-Q0`pi@up5MY@V2L%lphlCw~ide*N|I;Gr9hZXZp)G%d3%I+!0C`R2hRnM>9? z=UC0z_xF)7JKP zi;}GwxRTaHTi(`}nEXX_-B&x^%9}f}t_c*t#!Un#5S{gt652DeZ^A0GwUdmsXUK5hbb8i%xM-n5d z;^Bthr{`8n=kOi-p8KugrHgmuz2o=3m;UxD6#J_1Cf7;MxcZ#TUbDJ?JO_T9FxccR zWA-FOGJeHp&E$O&XOzS?`b!r{R^o1CxK)!W}jmCdNKin{UY z=#!t})_sNIV(S)I?On7mbdu4kTIUrd%7r2x-V;MSL$m}q93Av*bXd=oHLksK<;D7l zX|}s<5?|kt=lwA0)7R<89HPr!{8(CX;mVhF^VaE4E!MO9&yd`m#98=IP4t}Yo%0DH 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 literal 0 HcmV?d00001 diff --git a/homeassistant/components/camera/demo_1.jpg b/homeassistant/components/camera/demo_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..06166fffa859d9fdccf1fc89a563cd6574319d42 GIT binary patch literal 44897 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

SRA^Sy-HeIiGTl4YPvhL`x+uUjH-c_;| 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 X#STjDOT{=W?XLf4nCiOn?*E$r*w#h! literal 0 HcmV?d00001 diff --git a/homeassistant/components/camera/demo_1.png b/homeassistant/components/camera/demo_1.png deleted file mode 100644 index fc681fccecd69fb91801a6ecad8cd28454cae278..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9772 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 NgQu&X%Q~loCIAIg5cmK9 diff --git a/homeassistant/components/camera/demo_2.jpg b/homeassistant/components/camera/demo_2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..71356479ab08c00a17ec0e09c9198714154f85d2 GIT binary patch literal 44535 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 S&b>lU|9$xLV%GQi|2F}=zPe%n literal 0 HcmV?d00001 diff --git a/homeassistant/components/camera/demo_2.png b/homeassistant/components/camera/demo_2.png deleted file mode 100644 index 255cd5c45d4510cdc5853f22080017af1fad0e68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9667 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 diff --git a/homeassistant/components/camera/demo_3.jpg b/homeassistant/components/camera/demo_3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..06166fffa859d9fdccf1fc89a563cd6574319d42 GIT binary patch literal 44897 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

SRA^Sy-HeIiGTl4YPvhL`x+uUjH-c_;| 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 X#STjDOT{=W?XLf4nCiOn?*E$r*w#h! literal 0 HcmV?d00001 diff --git a/homeassistant/components/camera/demo_3.png b/homeassistant/components/camera/demo_3.png deleted file mode 100644 index b54c1ffb57c97644426efae5950dcf47e8c70031..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9595 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

bv~b* z3&mb5r&cP(wXrSp^Fp-4LB&e`;dMv-vSc zYCfg>-1&LcKeIg9XC1rV>|!{lzkO4}9^;kWs?!|o<6m~o`m$FyuH#aOx0}q|gR!FX zELE#aSRL*&wJukGVz??=-Gp7(?Dm-h-?i4x3C(&qS<3$Qp`_bFbIoMWO_{uMnbYio zuX4S!!*>4oTA^P1$VY9yUSY|v^1vTwkJwz3`?&d6$Na@|y-u?eayGVd-qqDSZ#T=^ zqcZ8jQK<;~=X*@jT7AP7lyom%+~JV5u4H}Bb*Un$GMSQX7n?GCEn*j3n^kb}h~yl$ zLY0jZKh0>+TpIQ+tKDJak;<5^$$@9o{nNLwTUfU_l&>k3{AT^+(h>``gEgO0b~8k( z%yMu)R3s)-CYinHoKm0U{<$xooDA8rF%q;QK;O;c(W|3UVJkj7`O&A(=W@^GOvB43 zoV_{k*35}cd-`sJlm;lc`}>M7EuE}l_+yV=X<_TiLnWVTqFz7$zI%_L<}@qm^yyJM zi(Q^1tW{7rx8B+@nD@bq@W`iA<%RV^xxUn=C;G-KVfi5^9)I2WKOp{-P5 z^{{!n)a6oTW>`b=P4Jo)6OD|Tsc(ZkRCcy+^A_Boc>CxCkD>{^U2LZ}#d3A3T)!Y7 zuOWB!zuBhC4oaE)aO2Zs4*uevT!f4(eJWzrnSj{W~$-#KK(>JWS+`KDgK%Oq`% zsmC8YQF!V8{7F6Eqw_a)C%GimvFQAJu%~INfKcLsm5ohe|M`>m*Y8j0$c-+G`xno0>+4MY=`KlCd9h`62k$$@ zcX06hO~|_L%JG)%K+VoNl}Tq7E6&)RlQliQeZQdb$Lo>rP2*NA+}q(+San)$;*4ok zA%&$Cy^Dp5y$-QI7u%z%b1I{y!nQVbvd5XuhNE`AJzc8jPS)Ofwx(QKJ%ele;!JVo zz9~}!lnll59;{!bB=`5loTjU}Z||(DS-brI-;9lqHq?bL@MUvre!(xobneJ0t%)hT x;ujch=`Gyo=d2@a_TJvkVz z1_lPs0*}aI1_oAF5N6EbymmtT}V z`<;yx1A_vCr;B4q#hkZuD-%So-rX?YxZIbi(ZNGuVlA(A(~i&yzJWSfj&Ixa^X7l* z>fl(^bS3NRsw;c1y;>c+CTgo*=t}M#TZ8W05M*R@RX8!NMPSnIb2arb&z_x&-E^lk zuV~)>89SYy-P!s1jAik;_ka2pNY43nZXzGw(V}%~TMVU=Ry53WuzQem?*2p%p9by~ z*B(SSZgUiVl)V1@|8J{KzSWxbi`^xd&+75tTNk_HqZ=+PWBOL%tvzvujJeYu#ykH% z9@(QWWxd0(^4Ol}+o2k_oEQ96$visQV-urdoS2y5`^AMjtCQq}UN>)ie>JWnU_Rrm zs+I_@1@SeZ_x=F6GR#86qn(*7wE+76)(XSI(NZ zQM>P)qcH#SeJMho-xLxKx=+5P!+SgY{EnyY%U5WX`v0yWP!KB$(^>~j&4?qxc=-gZGgS3}|ZYxCA< zy;?p~d#cMMR}RBpk2@>lH5gVca((MN!9yi5U?-=8PekC|i_0~io;bnSxnyO<8YkVr zJ+q8hHTzsH$-Ig4wTu=tFuSZe(PI;DW7)E%V-I}9U6f8bv1xNurR)+B^8BV)rFmkb zY^RFcC(#2FUj})oM0)sLS&`N0a>*h{u2aQtiH(rw9FIzsNfr}7d8iaBJ)P+B$mNvs z#3P+k+?6_oHTzwJ)UWx7I|!ZBY!zGgCU^M>&4~DwpDu)%x8IFg)~(9vd@5Oq#bEjV zx!k*NHT^!Pu_@r1Uc2k-*qpUt#^Dy8ESqko39%IXWms%s)yj8p@#3NxHzMs`pJ|zL zoJE5vPp7!xAm_wKFK&oNnA|w1UvX z=tax*S57T*#$J!gpdN-i4ez}c zRzVBCC_eR6bS#`@z%a{aiNj0BQ>cR2E3a1X$gbt0bgcWpLdgPPGpEx zSS_NV>QOnVC-TTe$>@})W|{$B6F#X3Zth&H%<9D(G*2ZltgvK>!%6p3lUdH_fvnr< zQ7PmixWRz?$i<0Fs{ES%OfMeInXCHfg-7G0<|*oan?gZ0J@Tl0!^f$h6)N*xe$717kH%>J*Zeq*Q z3!0~PDd_0MnRkw!@-a}Oy;+j9P2o1#2B*Q0RODbc-e|E#Hg{Bx_m#ldMJg(Y<{S%(u3Szm2& z_0kt(>|Sc&`|Q=eGQD@#HaIljR{g$hljenkiTfrl57X_}J7=Nkw|U0Z^XIl`oVI^; zBUoV30uIgo%m9`(bu7T_@~bBk zAF1%yPF&}c>U!2>t(TnZ0VPepAWn`ce>Z16UU>Dy;%;NduE`}|YWUXbYAp_}iPrRc zb@A{l6Ja-|C0%0m=8>#Al8+L60@L=ta+~&1vOZZ~`s3rp!h0Wy`O=z+J+M%sP+{QbtJ%Pbgv|Cq%t;V=4>bAEpG)>CuzUoYxnF1WCEW5L>PfBv7s zcGH)%o=O(|uv+n4kNMSqXN7AH*Eikv`(!!ywB_XNmk!$>{L?yB*~-c}_w@3E>&YTWer`%6Au>Mz=tD8B-rOtnwZgMzi$vua6+Q=9cb?mGUx*g^s8>mE%U;>@yQbat>)8!) zxl=mgOc{AjgfEiQ@9Y;-1P9q!Wj+VHqZ(JHr(4f=k=bnfq?ThrgYYB!_!EC-?%kSo zW#;tVeJca|ryp^@c6xF5=f!@{1lbQbN>>#}6;xaDZ)mG$*v?E&@oZoE$ZENJ@bCOn6}zr-{z?=@2+`rY-7)XgmbA( z#g+5hn|||c)_%0()~U-kH>cW}zb!4i&!JvZy*SI4$}pBZ7HTaatdZlCA0_H+OHy*7Ifd&f=*n0?tgGQ#4*#B1NxjNK$s=GvIC z=E*;L@-yMFWZ-WA7_Z?_fNttIy z|0b1anFdwqJAZyV{B3x+po~k{I{IVghq9ghb4|b6-)N1^jhWvhbIw2ayGitdh(~AM z-7lzXJa!}EY5KY8dd}(2o_$XHc+0M=sBnIFUvp`g*c8i0cHzYai)|t=SNOJCT#f6U z%KrMO<=V-u?(Rxn7v`!rmt>VGveljbTU8S`@A4`O0~Xy&V21w-FEG2ckzsWvl<-O?@ASi z@8&rx&KNVDrH~=3c9!CX5{D^&vY9`L9%g>FVfWW-Hp||v@>^=b5Ig7C_s*&8e`7Ai zcHUUNnB&D8pSRqfrtW1ny?fs&?#6c6(3!h$xz3gUcGb1(^JJB!4W~A8tZ7QPY;w!m ztuo?^Q+8j7LGIbfS%nO{o@$nyUAv#f|NVyzIqUh?bLrXd*>U>x>HF93A921FeW_@3 z%+1^9{10Ec^=?g|@{yU7T?!RG6iA2&RepGtCx6@dSmzxr8C|JK>}a|;(|N>t4eVVwTeE52`2_ODwTH7^RUe*I{P(#r>}>JgFk ze{7%4@K3%bUOFc#V`;DGzBM0;4}{i-`e|;tpz40jX4%1I2j)6oR^~hKBT4)6;UfLj zj)kxCr)XE-mW-QlZ}}T=HRrxWVWkjzLe9pi8x<#W?A7}7yP>~+>TjM$TQ+k(`{wU& zZklk)G{{%AKko6Ipc(gOmz3FCbF*1#bVx9WideIj^OS!0tYKbg^<)0LV}(oakq_tiOCEr2E(uA?@??=Vjlx zuI&He(94~Y^Uuk8iNUVLt@n9~XL%_E zi@1tE-@@as&Czdia%)$M^6JeqHZKE4FC-!*Ay7;$`B6=odhc=6s zRTi#XlH%p8W76L)|LpwoPalt8{Bw-q9CNo=ph33S-06C*HztQKyIxjZSycT*WtVt) zrR1%9hjN`|O1vKZTJ*SU?T*kL`Nh9jy|SYhsdh1M_>$f4I45a&LXo)kVyg%q)3e#T z_a40Xd&=TfZ|2#}?Q)mz6<~Mx{BuRcm%uXr*=$)wi(=>hy>|L=v~6Jee5RZgpNij# zmxicRN*#Wp*I4QLa^2O-YX07$&u1^zl3x8P|D17`&Y!niV)EpkB)shOo7QL0=euW< zwe3tR?YjTfefxf<{pE8#Xqh8%ZlSZ|O8pBLx8Gaz=;Lu=yZhI&rlyxkJib@;M3YB< z!vmh5C;4}n$o;rA_ruRamdlTv`eVX9MXd76gxS;7_!3rliZFg=v*6h@=f=T9mWthW ztzFZMOnRNa-Yd)smUH{x(CWvePPpq~7lW^ml<{66>cI8sP zI5#{iwXDAS)cWF6PfnH&e>C~jAR~F{?<&UcHBZg%c)XwT`$xil{Z}7X9=f!! zIq|me(y)&?ceDQ3%UU0+wR24nNWQ+&!;o*Msq=EL-6F?t`n}G2e5-Ed+nYX}Hhipg z);7D3GOqY|@X^GMDvgY`9?U8+cQ^bo0Wj5AFFjz4CW_ zCjH{w6e+`TCiUmp0QK~C-Ohh6745sFRy1NICJ^?x1S}CWM&JW z(f7XZV0b|FZtj^^v;P#U`OeD`cXt=uP_RJRX~B7ZbDe;R!5>a&s9$e&73k5}@Zrx( zOCMXsy$5By;^gj5*H_QKvt!2b99g?*?(b`x|9a_tzP97XI!?{%!U_)Sw6hm_iOrJ{XXuJ>jvp(RB!%n zGd*3kH85lPLLTF5esf=Z{P$ZXc3aP@>2a(2bG5Y}|2}!Sa?j@@3Creq`75lw%B*hn z^6C+_t98?l?J?Cm{3XZrz|*~NWj<%+tPCq$DK&R4*K(1l85eHOy13KAxccUW3qMYu zYYXNypW5=YFzUg(#B)p7|E5aCDlqQ3?9=GeDzL@&z0Iw8^0NdoCmTR(MK=tT-9%@`P9c_UNE=roGTksyB1%*#A>zlg3!gu zHzqi=-@U2JcSXJXjllCRaVyS~!n2O=P`y0E;bCU==H51zReati`@dwDhjlNWoG$94 z=egz#=gG<0(|mX`7brH0ZBJ;lv(1rN&lStyQ?GxURTcjXg9Nk1SsT{- zB_9u*svJ1&%LPuZkV{o8MaO@1CYQcU7v9Qw?!MoP+57h$KYb&KyZLtN^J@RK@sC^I z@6oyan%nP!ki-9)*7$E*++()|?$3OqwBgW}KD~g7zLz=9;xD%G>K%3pTeyX#Fs82J z>F*;|cZ7a@ixXY<|I$&-RlEt8-jLzjWh&+( zDRG6v#Zf=*{i8$c%$~V)o)bO5o60Bf;h5ZFhllSuZhAN~aWb0omlTA}I{Ncf$E+!l zJ65r=$7ubxeZt=seAN3;_<{AT(;h~67R@T)?=3O9Gw;@{GwTm7`r6ySV*j?=-qU3S zO=ko%nDcP(ENSD~vh`L??)IqtZhcEDgB42}^J3o{v6P&9lj*3YZi&tI`*)uwN1yP$r|kc5x^1qAHEXt3$h_a@gx@s%`^=~Rykw(WthC8AhqQ#~ zt*7pnSN?pnVSch5Z+F9{GO@ZCsTnJ-O?i20xk!{mXu`wK6UuK--fR`ygDJ>GPZHzfzm`6`00?LP zUoP9+b}}(dns(~zgy__VR?`#Lo(~Cpex2u$hSG%4XU`n@^j@c$UzxX>?&w+x9Ost-;cCx+IQ*vq0)6Tex8|hbd_`6VUZ7(f8QQ-JoEo$ z>f?`-i+FsumVZ-K-?d|F(yp{+&F!Mio3zW z&8jzcemooa`72MF@UqG3vObzyKfcP7-`)S5?{mU+nILMHO%Gq zGqC%6J^WYXj%#x#sl~i_wCndPld=|9*Wac*KPA03tx!MPqiQpvZ^KD%$%fh|oLB_$ksFK&G}zn)RL|HQUfoipK|QyzFe-*VtV znV4JomJ7k}d3_Cd2dF~T4g|%!pJC4duJaA!dXKR5^*UKlF zD_=0R>NC&JX`CZgk&(hTy=1$f?)wuf_{8Q(yv+$P;H~(OUG8$?;sz$}y|+(%kdeK7 z^75ql*-Zy-c$+llc`b4%V@>$l zFZF!A>z{L~Pi8Vz>ziq`XqMrsTP3yXE8|NxB*xVJIJk5XLu}EM8K=8cgh7?TuHAJC zrO8w0AALP}{}0`i=@w~6OFpG^ohYu`>W z75Y2DcgDNfOMcHy_uhKyZr~BlrN@?UOlh`$m9+QlL2udLH@!rwFLu;9#V+_zz9416 z(ug_g+pBjZFSd4);dtUdWAm;){_n@9YaH$Q8n$|U<-ZTT$0y9r2@=;%FW>kmn7MJz zd^s+Y*;zGG^|u}-UQBTB*)KACZp|s9cMr0|9;gQ_-mGG$g`(oj^8d>c;>@S zhP3b7A7Agec%xH5?_38H_vh0xSALm1I+M@DQn&d+s%WlPf@J^4qhWXIdZ+LI&bq(Z zy>;a30w;iI`C8dM$@Mqe;PAy`_^Wydp>{9kvnYF z0{ol1kIy)iyXLTG-I1T`-(~yHvU#{>?U&+@>YW+Fb65YqF;mV*M01Aq0l%%`kDDL+ zZVPR%sR(tCsxk`heAzYsT=~2Y(<--c{QdC8%D4AK_{YyepPL?Wuq4ksDs%6d)<3^; zH@1G;Biq+JIJlx-ed4ydWyj7ObB(M@b9(-(R?ptkcf%yjGwS|Q=SAgW|J>VmV*1Ss z)3av_%_z7gvhQgy-$vsdwRYtni{;V&tFM=%GOr`x>VtV_^RBh3x}D$7`D<&a(5xsq-s$nl z&Y`uo|1Rmt7qee^UiTsM*t+jbyFDsG&5RSQDlgr=TUIJ>&3%n+(#+LS2@9`B>~*^@ z$IbJ{H1$A;>J~BKh)y4sBwj&R=k6CF9qh4lo+fU6aZ*aLgKf3~-sdTx{d!)C+!eJjHba9W(mt~$8*!UT(xFZ%L2UjLG`X0W^U{_!?my?3{s zm~{ld5cspny=;Brl4Pq&qk~)4nN8~}2%46^M~3Oey!4!BZ^})57wqdY&f4~4M?6ck%b0RttC*!H8=e;q z>dm-u^OSz|Egnzt&9a*Q60UxZff4HuOu2L*HEW$i@{U=%<%5 z;gx5V`ao^*qs_8Ewj6l0Urg|YLWbq3E6MxPqL;nxJUAr?G+kn{oAZ0H+*7W3iyhwP z-q1JUcK&I&{S)h73*&W0Gkxa-tYNaUWZIjh8z?iu)PM7gpe$C#{l9lrnqJ7L^9#J| z|Fd5DTEh9eov+S6ow7$T=JtM*cbjHJ&bij~Qg7qTr;Ia#lAa#h^ujbCIq>?t?3yTVlZA`R~^J;zqf z!C_+0%=C6$=u!){gC*0gz3(tSxWmICvg?zyN1;*YOT9|7lgu*(J<@$9n(8tynDk=C zyG`k{Z6-)I9utX-G&3mxgv9W3Yzpv}p#O@aBKknQwXKV5Q z&*z#%sZ;LFYBIj+nfu z;s3P777HsvD{^MHUpF#&sdssX|2&>spWkdg|LNQ9eD>|1KYf~En9NrE?94*{`F02Y zii(P!nP+Q#Yd*t+IT}o|ewVg9E-{_7YOhp(jwzS@ngfTv{%ZUtWvPm|lFp_Pb&2uabLJuXP#jRX&%!7qffrrFXWA z|E*10{@_ubS=_IC(x&el&3#V`+ig4Btld|0{l0AQ%8yt7@4xxC=j`U~r)%%*ww%Cq z<0*g6`4=~L&B|XkSv^>^zv1Ph-3$z@A)vJY*Iz&VeBPcvFTVcoSI0sI89sJ?yB`Sw zat*WNe$9Bq8T-g8-byF|H1QC=@4H%!@9w9XKHSyoK_fWQ)q84cYq)+d)3U#?>xp6f zW?kp!wpCv=Rz=<4@&2aqCbyS2H>)eDoH!L;tn%)2?&`3`Y1e$j&cFHaVfx(8ZsrR| zC2fs%si-ub3Y_n`%ky%_&nG7@-m$v3+;cqLTX~)jrEd~FNkkD)LP?nJ?FGY*CK<=ODgv&9`iEH zt9qsB)-QMV%uHiJrwx^#)7I^H)b-$_+3vaG>#Sz~DVvyVxADiD4fECaePp@c$S3pu zSY5`F$(Pu~ZsziV+?g}OBKEV$Gu{o8ulMBb(%1T9^VN63;RTl#7oHE#dp4c*U)yPZ z{`^wuXNGgHZ2Y=*Qm$2{QRGkkm>m<$@7DTQ9W%r`F|LI|VdlhqY^LNEZ zgkJ2@k9}ixt)_8a-=z?57n!+rxuSLTlP2%WU3_27_LGR5^POuo_21v$>Q7}J_dhS@%RLlYVUic|_R+zKe!I*KXV$Db za`EL=w}<_UizC8cru#0Puhs9i&(~njfkP|!rio45V-UB*#xUdlK3n6oGYQ9fBsHzw z7cni3l96>~2`XM%mAa>G!sQLK9kQi$JFc}{X3bi`DegO`PE){LNLsU>QzAYmwa}QQ zOZ8lkreBode4Diw<(RT>xd^{_R;qWn@OSJik>e^e{O9?ID>S&-9yD;wn9RYT?naJjo{+LHc2l`wlTHNAI%`_$gq>ylis1cj>Dp)y=J)bJyMx z3uA7*tRMgIo}k~YEt6E(=F9ulyj_%%Y*lGz`{cR4^{+TFfZt!72n#?#qR-($5V9_f6UCD*AEJpt#+4YVa5fehu#xD_X+ zD3)>w)Zg;%T=F$&?ShZ7%e)mQrpVv&b3Jg(N8DNIq?4JZRLvaFVv(C|Z9hCduK1UF z!jHLgiDgBOQ*C&p>CV{Jwu;psAFB#+GC2MD{I~OGyC{RN;P=#BHbS1;6hhuLKW<*~ zf98bWmL1{7(JGxs{%}-$T)g?yzLp6b%)X+Cf*sckaG8 z<#guVm6uf}MXXqn^o(7&==&>co{hQk^QZov&(wie^s8iM4tEHp?>wPl?H#BXLRmA7gP9#iTACfiBfpwB#$U|(G^K)6}^jv zi@grH3xAFi7faP}+B0X@CQp@TE(f~pe0e%m&wWgmdVc16U+*Q6Jg3XcnEIAX4Nx)^ z&wDU`mD0Pv=Ueue_R8K_Q?u5-YV|6I!ie*N8OejLuJv%kOXKPGBYx#QV?X76qCwFfS*Qet3WVDNPHb6Mw<&;$US*Y+I% From 7d503e3f8b668748c6db64377b9e0395a600d32e Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sun, 29 Nov 2015 15:52:44 +0100 Subject: [PATCH 49/49] Update docstrings --- homeassistant/components/motor/__init__.py | 11 ++++++++--- homeassistant/components/motor/mqtt.py | 13 ++++++++----- homeassistant/components/mqtt/__init__.py | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/motor/__init__.py b/homeassistant/components/motor/__init__.py index 806dd9e0eb1..dda7c52c05d 100644 --- a/homeassistant/components/motor/__init__.py +++ b/homeassistant/components/motor/__init__.py @@ -1,8 +1,10 @@ """ homeassistant.components.motor -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Motor component. +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/motor/ """ import os import logging @@ -100,12 +102,15 @@ class MotorDevice(Entity): @property def current_position(self): - """ Return current position of motor. - None is unknown, 0 is closed, 100 is fully open. """ + """ + Return current position of motor. + None is unknown, 0 is closed, 100 is fully open. + """ raise NotImplementedError() @property def state(self): + """ Returns the state of the motor. """ current = self.current_position if current is None: diff --git a/homeassistant/components/motor/mqtt.py b/homeassistant/components/motor/mqtt.py index 1075030fc37..7c25e382f84 100644 --- a/homeassistant/components/motor/mqtt.py +++ b/homeassistant/components/motor/mqtt.py @@ -1,7 +1,8 @@ """ homeassistant.components.motor.mqtt -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Allows to configure a MQTT motor. + For more details about this platform, please refer to the documentation at https://home-assistant.io/components/motor.mqtt/ """ @@ -40,7 +41,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): # pylint: disable=too-many-arguments, too-many-instance-attributes class MqttMotor(MotorDevice): - """ Represents a motor that can be controlled using MQTT """ + """ Represents a motor that can be controlled using MQTT. """ def __init__(self, hass, name, state_topic, command_topic, qos, payload_open, payload_close, payload_stop, state_format): self._state = None @@ -76,13 +77,15 @@ class MqttMotor(MotorDevice): @property def name(self): - """ The name of the motor """ + """ The name of the motor. """ return self._name @property def current_position(self): - """ Return current position of motor. - None is unknown, 0 is closed, 100 is fully open. """ + """ + Return current position of motor. + None is unknown, 0 is closed, 100 is fully open. + """ return self._state def open(self, **kwargs): diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 0e8506523d2..2c5dbf82923 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -138,7 +138,7 @@ def setup(hass, config): # pylint: disable=too-few-public-methods class _JsonFmtParser(object): - """ Implements a json parser on xpath. """ + """ Implements a JSON parser on xpath. """ def __init__(self, jsonpath): import jsonpath_rw self._expr = jsonpath_rw.parse(jsonpath)