From ed20f7e3593f62c6d26331fb2c3f49178a1b4b6c Mon Sep 17 00:00:00 2001 From: viswa-swami Date: Sat, 1 Jul 2017 00:06:56 -0400 Subject: [PATCH 001/131] Camera services arm disarm including Netgear Arlo (#7961) * Added camera service calls to arm/disarm the cameras. Entity id is optional so that with a single call we can arm all the cameras or specify a particular entity id to arm if applicable and possible in that camera type. * Added camera service calls to arm/disarm the cameras. Entity id is optional so that with a single call we can arm all the cameras or specify a particular entity id to arm if applicable and possible in that camera type. * Added camera service calls to arm/disarm the cameras. Entity id is optional so that with a single call we can arm all the cameras or specify a particular entity id to arm if applicable and possible in that camera type. * Fixed the spaces and indentation related issues that houndci found * Fixed the spaces and indentation related issues that houndci found * Missed the const file which has the macros defined. * Fixed the CI build error * Fixed the CI build error because of unused variable in exception case * Updating the arlo code based on comment from @balloob. Changed the arm and disarm to enable_motion_detection and disable_motion_detection respectively. Similarly fixed the AttributeError handling. Added dummy code to the demo camera also. Moved out the definitions in const.py into the camera __init__ file * Fixed the comments posted by houndci-bot * Fixed the comments posted by houndci-bot * Fixed the comments posted by houndci-bot * Fixed the comments posted by travis-ci integration bot * Fixed the comments posted by travis-ci integration bot * Fixed the comments posted by travis-ci integration bot for demo.py: expected 2 lines, found 1 * Updated code in camera __init__.py to use the get function instead of directly calling the member in the structure. * Updated code in camera __init__.py * Posting the updated code for PR based on @balloob's suggestions/recommendations * Removed the arlo reference from demo code. Copy-paste error * Removed the unused import found by hound bot * Expected 2 lines before function, but found only 1. * Based on @balloob's comments, moved these constants to the camera/arlo.py * Added test_demo.py to test the motion enabled and motion disabled in camera component * Fixing issues found by houndci-bot * Fixing issues found by houndci-bot * Fixing the code as per @balloob's suggestions * Fixing the code as per @balloob's suggestions * Fixing the test_demo failure. Tried to rewrite a base function to enable the motion in __init__.py and missed to add it to as a job. * Fixing the hound bot comment * Update arlo.py * Update arlo.py --- homeassistant/components/camera/__init__.py | 88 ++++++++++++++++++- homeassistant/components/camera/arlo.py | 33 ++++++- homeassistant/components/camera/demo.py | 28 +++++- homeassistant/components/camera/services.yaml | 17 ++++ tests/components/camera/test_demo.py | 27 ++++++ 5 files changed, 186 insertions(+), 7 deletions(-) create mode 100644 homeassistant/components/camera/services.yaml create mode 100644 tests/components/camera/test_demo.py diff --git a/homeassistant/components/camera/__init__.py b/homeassistant/components/camera/__init__.py index 952f4378598..c84421f50ea 100644 --- a/homeassistant/components/camera/__init__.py +++ b/homeassistant/components/camera/__init__.py @@ -12,13 +12,16 @@ from datetime import timedelta import logging import hashlib from random import SystemRandom +import os import aiohttp from aiohttp import web import async_timeout +import voluptuous as vol from homeassistant.core import callback -from homeassistant.const import ATTR_ENTITY_PICTURE +from homeassistant.const import (ATTR_ENTITY_ID, ATTR_ENTITY_PICTURE) +from homeassistant.config import load_yaml_config_file from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.entity import Entity @@ -26,9 +29,12 @@ from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa from homeassistant.components.http import HomeAssistantView, KEY_AUTHENTICATED from homeassistant.helpers.event import async_track_time_interval +import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) +SERVICE_EN_MOTION = 'enable_motion_detection' +SERVICE_DISEN_MOTION = 'disable_motion_detection' DOMAIN = 'camera' DEPENDENCIES = ['http'] SCAN_INTERVAL = timedelta(seconds=30) @@ -44,6 +50,24 @@ ENTITY_IMAGE_URL = '/api/camera_proxy/{0}?token={1}' TOKEN_CHANGE_INTERVAL = timedelta(minutes=5) _RND = SystemRandom() +CAMERA_SERVICE_SCHEMA = vol.Schema({ + vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, +}) + + +def enable_motion_detection(hass, entity_id=None): + """Enable Motion Detection.""" + data = {ATTR_ENTITY_ID: entity_id} if entity_id else None + hass.async_add_job(hass.services.async_call( + DOMAIN, SERVICE_EN_MOTION, data)) + + +def disable_motion_detection(hass, entity_id=None): + """Disable Motion Detection.""" + data = {ATTR_ENTITY_ID: entity_id} if entity_id else None + hass.async_add_job(hass.services.async_call( + DOMAIN, SERVICE_DISEN_MOTION, data)) + @asyncio.coroutine def async_get_image(hass, entity_id, timeout=10): @@ -93,6 +117,44 @@ def async_setup(hass, config): hass.async_add_job(entity.async_update_ha_state()) async_track_time_interval(hass, update_tokens, TOKEN_CHANGE_INTERVAL) + + @asyncio.coroutine + def async_handle_camera_service(service): + """Handle calls to the camera services.""" + target_cameras = component.async_extract_from_service(service) + + for camera in target_cameras: + if service.service == SERVICE_EN_MOTION: + yield from camera.async_enable_motion_detection() + elif service.service == SERVICE_DISEN_MOTION: + yield from camera.async_disable_motion_detection() + + update_tasks = [] + for camera in target_cameras: + if not camera.should_poll: + continue + + update_coro = hass.async_add_job( + camera.async_update_ha_state(True)) + if hasattr(camera, 'async_update'): + update_tasks.append(update_coro) + else: + yield from update_coro + + if update_tasks: + yield from asyncio.wait(update_tasks, loop=hass.loop) + + descriptions = yield from hass.async_add_job( + load_yaml_config_file, os.path.join( + os.path.dirname(__file__), 'services.yaml')) + + hass.services.async_register( + DOMAIN, SERVICE_EN_MOTION, async_handle_camera_service, + descriptions.get(SERVICE_EN_MOTION), schema=CAMERA_SERVICE_SCHEMA) + hass.services.async_register( + DOMAIN, SERVICE_DISEN_MOTION, async_handle_camera_service, + descriptions.get(SERVICE_DISEN_MOTION), schema=CAMERA_SERVICE_SCHEMA) + return True @@ -126,6 +188,11 @@ class Camera(Entity): """Return the camera brand.""" return None + @property + def motion_detection_enabled(self): + """Return the camera motion detection status.""" + return None + @property def model(self): """Return the camera model.""" @@ -202,6 +269,22 @@ class Camera(Entity): else: return STATE_IDLE + def enable_motion_detection(self): + """Enable motion detection in the camera.""" + raise NotImplementedError() + + def async_enable_motion_detection(self): + """Call the job and enable motion detection.""" + return self.hass.async_add_job(self.enable_motion_detection) + + def disable_motion_detection(self): + """Disable motion detection in camera.""" + raise NotImplementedError() + + def async_disable_motion_detection(self): + """Call the job and disable motion detection.""" + return self.hass.async_add_job(self.disable_motion_detection) + @property def state_attributes(self): """Return the camera state attributes.""" @@ -215,6 +298,9 @@ class Camera(Entity): if self.brand: attr['brand'] = self.brand + if self.motion_detection_enabled: + attr['motion_detection'] = self.motion_detection_enabled + return attr @callback diff --git a/homeassistant/components/camera/arlo.py b/homeassistant/components/camera/arlo.py index 2fd7d372eb5..be6aab30af5 100644 --- a/homeassistant/components/camera/arlo.py +++ b/homeassistant/components/camera/arlo.py @@ -9,17 +9,19 @@ import logging import voluptuous as vol +from homeassistant.helpers import config_validation as cv +from homeassistant.helpers.aiohttp_client import async_aiohttp_proxy_stream from homeassistant.components.arlo import DEFAULT_BRAND, DATA_ARLO from homeassistant.components.camera import Camera, PLATFORM_SCHEMA from homeassistant.components.ffmpeg import DATA_FFMPEG -from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.aiohttp_client import async_aiohttp_proxy_stream DEPENDENCIES = ['arlo', 'ffmpeg'] _LOGGER = logging.getLogger(__name__) CONF_FFMPEG_ARGUMENTS = 'ffmpeg_arguments' +ARLO_MODE_ARMED = 'armed' +ARLO_MODE_DISARMED = 'disarmed' PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_FFMPEG_ARGUMENTS): cv.string, @@ -46,9 +48,10 @@ class ArloCam(Camera): def __init__(self, hass, camera, device_info): """Initialize an Arlo camera.""" super().__init__() - self._camera = camera + self._base_stn = hass.data['arlo'].base_stations[0] self._name = self._camera.name + self._motion_status = False self._ffmpeg = hass.data[DATA_FFMPEG] self._ffmpeg_arguments = device_info.get(CONF_FFMPEG_ARGUMENTS) @@ -87,3 +90,27 @@ class ArloCam(Camera): def brand(self): """Camera brand.""" return DEFAULT_BRAND + + @property + def should_poll(self): + """Camera should poll periodically.""" + return True + + @property + def motion_detection_enabled(self): + """Camera Motion Detection Status.""" + return self._motion_status + + def set_base_station_mode(self, mode): + """Set the mode in the base station.""" + self._base_stn.mode = mode + + def enable_motion_detection(self): + """Enable the Motion detection in base station (Arm).""" + self._motion_status = True + self.set_base_station_mode(ARLO_MODE_ARMED) + + def disable_motion_detection(self): + """Disable the motion detection in base station (Disarm).""" + self._motion_status = False + self.set_base_station_mode(ARLO_MODE_DISARMED) diff --git a/homeassistant/components/camera/demo.py b/homeassistant/components/camera/demo.py index 158f6c11751..d009f156e9d 100644 --- a/homeassistant/components/camera/demo.py +++ b/homeassistant/components/camera/demo.py @@ -5,25 +5,29 @@ For more details about this platform, please refer to the documentation https://home-assistant.io/components/demo/ """ import os - +import logging import homeassistant.util.dt as dt_util from homeassistant.components.camera import Camera +_LOGGER = logging.getLogger(__name__) + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Demo camera platform.""" add_devices([ - DemoCamera('Demo camera') + DemoCamera(hass, config, 'Demo camera') ]) class DemoCamera(Camera): """The representation of a Demo camera.""" - def __init__(self, name): + def __init__(self, hass, config, name): """Initialize demo camera component.""" super().__init__() + self._parent = hass self._name = name + self._motion_status = False def camera_image(self): """Return a faked still image response.""" @@ -38,3 +42,21 @@ class DemoCamera(Camera): def name(self): """Return the name of this camera.""" return self._name + + @property + def should_poll(self): + """Camera should poll periodically.""" + return True + + @property + def motion_detection_enabled(self): + """Camera Motion Detection Status.""" + return self._motion_status + + def enable_motion_detection(self): + """Enable the Motion detection in base station (Arm).""" + self._motion_status = True + + def disable_motion_detection(self): + """Disable the motion detection in base station (Disarm).""" + self._motion_status = False diff --git a/homeassistant/components/camera/services.yaml b/homeassistant/components/camera/services.yaml new file mode 100644 index 00000000000..b6ed22f708a --- /dev/null +++ b/homeassistant/components/camera/services.yaml @@ -0,0 +1,17 @@ +# Describes the format for available camera services + +enable_motion_detection: + description: Enable the motion detection in a camera + + fields: + entity_id: + description: Name(s) of entities to enable motion detection + example: 'camera.living_room_camera' + +disable_motion_detection: + description: Disable the motion detection in a camera + + fields: + entity_id: + description: Name(s) of entities to disable motion detection + example: 'camera.living_room_camera' diff --git a/tests/components/camera/test_demo.py b/tests/components/camera/test_demo.py new file mode 100644 index 00000000000..51e04fca351 --- /dev/null +++ b/tests/components/camera/test_demo.py @@ -0,0 +1,27 @@ +"""The tests for local file camera component.""" +import asyncio +from homeassistant.components import camera +from homeassistant.setup import async_setup_component + + +@asyncio.coroutine +def test_motion_detection(hass): + """Test motion detection services.""" + # Setup platform + yield from async_setup_component(hass, 'camera', { + 'camera': { + 'platform': 'demo' + } + }) + + # Fetch state and check motion detection attribute + state = hass.states.get('camera.demo_camera') + assert not state.attributes.get('motion_detection') + + # Call service to turn on motion detection + camera.enable_motion_detection(hass, 'camera.demo_camera') + yield from hass.async_block_till_done() + + # Check if state has been updated. + state = hass.states.get('camera.demo_camera') + assert state.attributes.get('motion_detection') From 5e56bc746450c0861cdcafc9bdb000e871701a03 Mon Sep 17 00:00:00 2001 From: Josh Date: Fri, 30 Jun 2017 21:07:12 -0700 Subject: [PATCH 002/131] Adding done_message to alert (#8116) * Adding done_message to alert Adding an optional entry to the config that will send a notification when an alarm goes from on to off. * Update test_alert.py * Update test_alert.py --- homeassistant/components/alert.py | 28 +++++++++++++++----- tests/components/test_alert.py | 43 ++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/alert.py b/homeassistant/components/alert.py index 09db0f84346..b4de3c4a0f5 100644 --- a/homeassistant/components/alert.py +++ b/homeassistant/components/alert.py @@ -25,6 +25,7 @@ _LOGGER = logging.getLogger(__name__) DOMAIN = 'alert' ENTITY_ID_FORMAT = DOMAIN + '.{}' +CONF_DONE_MESSAGE = 'done_message' CONF_CAN_ACK = 'can_acknowledge' CONF_NOTIFIERS = 'notifiers' CONF_REPEAT = 'repeat' @@ -35,6 +36,7 @@ DEFAULT_SKIP_FIRST = False ALERT_SCHEMA = vol.Schema({ vol.Required(CONF_NAME): cv.string, + vol.Optional(CONF_DONE_MESSAGE, default=None): cv.string, vol.Required(CONF_ENTITY_ID): cv.entity_id, vol.Required(CONF_STATE, default=STATE_ON): cv.string, vol.Required(CONF_REPEAT): vol.All(cv.ensure_list, [vol.Coerce(float)]), @@ -121,10 +123,10 @@ def async_setup(hass, config): # Setup alerts for entity_id, alert in alerts.items(): entity = Alert(hass, entity_id, - alert[CONF_NAME], alert[CONF_ENTITY_ID], - alert[CONF_STATE], alert[CONF_REPEAT], - alert[CONF_SKIP_FIRST], alert[CONF_NOTIFIERS], - alert[CONF_CAN_ACK]) + alert[CONF_NAME], alert[CONF_DONE_MESSAGE], + alert[CONF_ENTITY_ID], alert[CONF_STATE], + alert[CONF_REPEAT], alert[CONF_SKIP_FIRST], + alert[CONF_NOTIFIERS], alert[CONF_CAN_ACK]) all_alerts[entity.entity_id] = entity # Read descriptions @@ -154,8 +156,8 @@ def async_setup(hass, config): class Alert(ToggleEntity): """Representation of an alert.""" - def __init__(self, hass, entity_id, name, watched_entity_id, state, - repeat, skip_first, notifiers, can_ack): + def __init__(self, hass, entity_id, name, done_message, watched_entity_id, + state, repeat, skip_first, notifiers, can_ack): """Initialize the alert.""" self.hass = hass self._name = name @@ -163,6 +165,7 @@ class Alert(ToggleEntity): self._skip_first = skip_first self._notifiers = notifiers self._can_ack = can_ack + self._done_message = done_message self._delay = [timedelta(minutes=val) for val in repeat] self._next_delay = 0 @@ -170,6 +173,7 @@ class Alert(ToggleEntity): self._firing = False self._ack = False self._cancel = None + self._send_done_message = False self.entity_id = ENTITY_ID_FORMAT.format(entity_id) event.async_track_state_change( @@ -230,6 +234,8 @@ class Alert(ToggleEntity): self._cancel() self._ack = False self._firing = False + if self._done_message and self._send_done_message: + yield from self._notify_done_message() self.hass.async_add_job(self.async_update_ha_state) @asyncio.coroutine @@ -249,11 +255,21 @@ class Alert(ToggleEntity): if not self._ack: _LOGGER.info("Alerting: %s", self._name) + self._send_done_message = True for target in self._notifiers: yield from self.hass.services.async_call( 'notify', target, {'message': self._name}) yield from self._schedule_notify() + @asyncio.coroutine + def _notify_done_message(self, *args): + """Send notification of complete alert.""" + _LOGGER.info("Alerting: %s", self._done_message) + self._send_done_message = False + for target in self._notifiers: + yield from self.hass.services.async_call( + 'notify', target, {'message': self._done_message}) + @asyncio.coroutine def async_turn_on(self): """Async Unacknowledge alert.""" diff --git a/tests/components/test_alert.py b/tests/components/test_alert.py index 8150d08ff72..a94e5747483 100644 --- a/tests/components/test_alert.py +++ b/tests/components/test_alert.py @@ -13,19 +13,21 @@ from homeassistant.const import (CONF_ENTITY_ID, STATE_IDLE, CONF_NAME, from tests.common import get_test_home_assistant NAME = "alert_test" +DONE_MESSAGE = "alert_gone" NOTIFIER = 'test' TEST_CONFIG = \ {alert.DOMAIN: { NAME: { CONF_NAME: NAME, + alert.CONF_DONE_MESSAGE: DONE_MESSAGE, CONF_ENTITY_ID: "sensor.test", CONF_STATE: STATE_ON, alert.CONF_REPEAT: 30, alert.CONF_SKIP_FIRST: False, alert.CONF_NOTIFIERS: [NOTIFIER]} }} -TEST_NOACK = [NAME, NAME, "sensor.test", STATE_ON, - [30], False, NOTIFIER, False] +TEST_NOACK = [NAME, NAME, DONE_MESSAGE, "sensor.test", + STATE_ON, [30], False, NOTIFIER, False] ENTITY_ID = alert.ENTITY_ID_FORMAT.format(NAME) @@ -119,6 +121,31 @@ class TestAlert(unittest.TestCase): hidden = self.hass.states.get(ENTITY_ID).attributes.get('hidden') self.assertFalse(hidden) + def test_notification_no_done_message(self): + """Test notifications.""" + events = [] + config = deepcopy(TEST_CONFIG) + del(config[alert.DOMAIN][NAME][alert.CONF_DONE_MESSAGE]) + + @callback + def record_event(event): + """Add recorded event to set.""" + events.append(event) + + self.hass.services.register( + notify.DOMAIN, NOTIFIER, record_event) + + assert setup_component(self.hass, alert.DOMAIN, config) + self.assertEqual(0, len(events)) + + self.hass.states.set("sensor.test", STATE_ON) + self.hass.block_till_done() + self.assertEqual(1, len(events)) + + self.hass.states.set("sensor.test", STATE_OFF) + self.hass.block_till_done() + self.assertEqual(1, len(events)) + def test_notification(self): """Test notifications.""" events = [] @@ -140,7 +167,7 @@ class TestAlert(unittest.TestCase): self.hass.states.set("sensor.test", STATE_OFF) self.hass.block_till_done() - self.assertEqual(1, len(events)) + self.assertEqual(2, len(events)) def test_skipfirst(self): """Test skipping first notification.""" @@ -170,3 +197,13 @@ class TestAlert(unittest.TestCase): self.hass.block_till_done() self.assertEqual(True, entity.hidden) + + def test_done_message_state_tracker_reset_on_cancel(self): + """Test that the done message is reset when cancelled.""" + entity = alert.Alert(self.hass, *TEST_NOACK) + entity._cancel = lambda *args: None + assert entity._send_done_message is False + entity._send_done_message = True + self.hass.add_job(entity.end_alerting) + self.hass.block_till_done() + assert entity._send_done_message is False From 8e4394f17371dd75c550136d3a91483b3e4d39a1 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sat, 1 Jul 2017 06:07:50 +0200 Subject: [PATCH 003/131] Version bump to 0.49.0.dev0 (#8266) --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index c6a01ddce24..510f7daf12e 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ # coding: utf-8 """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 -MINOR_VERSION = 48 +MINOR_VERSION = 49 PATCH_VERSION = '0.dev0' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) From 7123ec14be852ab6aef0a8fbc3a28b1f096b3315 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 30 Jun 2017 21:57:38 -0700 Subject: [PATCH 004/131] Revert "Make Android app shortcut use 'Home Assistant' as name." (#8271) * Revert "Version bump to 0.49.0.dev0 (#8266)" This reverts commit 8e4394f17371dd75c550136d3a91483b3e4d39a1. * Revert "Adding done_message to alert (#8116)" This reverts commit 5e56bc746450c0861cdcafc9bdb000e871701a03. * Revert "Camera services arm disarm including Netgear Arlo (#7961)" This reverts commit ed20f7e3593f62c6d26331fb2c3f49178a1b4b6c. * Revert "Make Android app shortcut use 'Home Assistant' as name instead of just 'Assistant'. (#8261)" This reverts commit 0bcb7839fbffc70ac90400effb99558b6d0214b5. --- homeassistant/components/frontend/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index ade3dd7d18b..8d55ad879fa 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -31,7 +31,7 @@ MANIFEST_JSON = { 'icons': [], 'lang': 'en-US', 'name': 'Home Assistant', - 'short_name': 'Home Assistant', + 'short_name': 'Assistant', 'start_url': '/', 'theme_color': '#03A9F4' } From e077998d38e2bca07c112fa9d45909fd1cc3961e Mon Sep 17 00:00:00 2001 From: lrmate Date: Sat, 1 Jul 2017 08:32:10 +0200 Subject: [PATCH 005/131] Update modbus.py (#8256) * Update modbus.py Prevents Modbus binary sensors showing up as "unnamed_device". Originally proposed here https://community.home-assistant.io/t/modbus-sensor/6751/11 by user Pjeter * Update modbus.py --- homeassistant/components/binary_sensor/modbus.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/homeassistant/components/binary_sensor/modbus.py b/homeassistant/components/binary_sensor/modbus.py index 54e4cefb230..3a9b57ba6de 100644 --- a/homeassistant/components/binary_sensor/modbus.py +++ b/homeassistant/components/binary_sensor/modbus.py @@ -50,6 +50,10 @@ class ModbusCoilSensor(BinarySensorDevice): self._coil = int(coil) self._value = None + def name(self): + """Return the name of the sensor.""" + return self._name + @property def is_on(self): """Return the state of the sensor.""" From 0981956caa8ba9f19a7aae1434b8c98b631bee60 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sat, 1 Jul 2017 12:53:29 +0200 Subject: [PATCH 006/131] Upgrade pyowm to 2.7.1 (#8274) --- homeassistant/components/sensor/openweathermap.py | 2 +- homeassistant/components/weather/openweathermap.py | 2 +- requirements_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/sensor/openweathermap.py b/homeassistant/components/sensor/openweathermap.py index 8d55b343781..d53c54b78b6 100755 --- a/homeassistant/components/sensor/openweathermap.py +++ b/homeassistant/components/sensor/openweathermap.py @@ -17,7 +17,7 @@ import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity from homeassistant.util import Throttle -REQUIREMENTS = ['pyowm==2.6.1'] +REQUIREMENTS = ['pyowm==2.7.1'] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/weather/openweathermap.py b/homeassistant/components/weather/openweathermap.py index 088ca359cc1..6442a0342a5 100644 --- a/homeassistant/components/weather/openweathermap.py +++ b/homeassistant/components/weather/openweathermap.py @@ -16,7 +16,7 @@ from homeassistant.const import (CONF_API_KEY, CONF_NAME, CONF_LATITUDE, import homeassistant.helpers.config_validation as cv from homeassistant.util import Throttle -REQUIREMENTS = ['pyowm==2.6.1'] +REQUIREMENTS = ['pyowm==2.7.1'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 6f596cc53ae..c0ae35d7eed 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -648,7 +648,7 @@ pynx584==0.4 # homeassistant.components.sensor.openweathermap # homeassistant.components.weather.openweathermap -pyowm==2.6.1 +pyowm==2.7.1 # homeassistant.components.qwikswitch pyqwikswitch==0.4 From e6e0e5263af9429ee7ec135530ad08a2596a0dce Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sat, 1 Jul 2017 16:14:18 +0200 Subject: [PATCH 007/131] Don't call update() in constructor (#8276) --- homeassistant/components/sensor/openweathermap.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/sensor/openweathermap.py b/homeassistant/components/sensor/openweathermap.py index d53c54b78b6..944ee101d13 100755 --- a/homeassistant/components/sensor/openweathermap.py +++ b/homeassistant/components/sensor/openweathermap.py @@ -38,7 +38,7 @@ SENSOR_TYPES = { 'pressure': ['Pressure', 'mbar'], 'clouds': ['Cloud coverage', '%'], 'rain': ['Rain', 'mm'], - 'snow': ['Snow', 'mm'] + 'snow': ['Snow', 'mm'], } PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ @@ -85,7 +85,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): dev.append(OpenWeatherMapSensor( name, data, 'forecast', SENSOR_TYPES['temperature'][1])) - add_devices(dev) + add_devices(dev, True) class OpenWeatherMapSensor(Entity): @@ -100,7 +100,6 @@ class OpenWeatherMapSensor(Entity): self.type = sensor_type self._state = None self._unit_of_measurement = SENSOR_TYPES[sensor_type][1] - self.update() @property def name(self): @@ -130,6 +129,9 @@ class OpenWeatherMapSensor(Entity): data = self.owa_client.data fc_data = self.owa_client.fc_data + if data is None or fc_data is None: + return + if self.type == 'weather': self._state = data.get_detailed_status() elif self.type == 'temperature': @@ -188,7 +190,7 @@ class WeatherData(object): except TypeError: obs = None if obs is None: - _LOGGER.warning("Failed to fetch data from OpenWeatherMap") + _LOGGER.warning("Failed to fetch data") return self.data = obs.get_weather() @@ -199,4 +201,4 @@ class WeatherData(object): self.latitude, self.longitude) self.fc_data = obs.get_forecast() except TypeError: - _LOGGER.warning("Failed to fetch forecast from OpenWeatherMap") + _LOGGER.warning("Failed to fetch forecast") From c13fdd23c1d221cd887422e6b71df1419a7e6e8e Mon Sep 17 00:00:00 2001 From: Will W Date: Sun, 2 Jul 2017 05:30:39 +0900 Subject: [PATCH 008/131] components.knx - KNXMultiAddressDevice corrections (#8275) 1. The has_attributes was comparing names to addresses 2. Some errors outside of an except block were using _LOGGER.except. This will cause an exception itself because there is no trance context available to the logger 3. Added alias names for the address and state addresses so that they can be accessed with the same 4. Added return values for the set_int_value and set_percentage methods to allow error checking similar to the set_value method 5. Added the name of the configured object to the log messages to make them more meaningful (otherwise multiple similar log messages are received without any hint as to the target device) --- homeassistant/components/knx.py | 91 ++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 19 deletions(-) diff --git a/homeassistant/components/knx.py b/homeassistant/components/knx.py index 10286f84b3a..9155304def7 100644 --- a/homeassistant/components/knx.py +++ b/homeassistant/components/knx.py @@ -51,7 +51,7 @@ def setup(hass, config): res = KNXTUNNEL.connect() _LOGGER.debug("Res = %s", res) if not res: - _LOGGER.exception("Could not connect to KNX/IP interface %s", host) + _LOGGER.error("Could not connect to KNX/IP interface %s", host) return False except KNXException as ex: @@ -127,7 +127,10 @@ class KNXGroupAddress(Entity): self._config = config self._state = False self._data = None - _LOGGER.debug("Initalizing KNX group address %s", self.address) + _LOGGER.debug( + "Initalizing KNX group address for %s (%s)", + self.name, self.address + ) def handle_knx_message(addr, data): """Handle an incoming KNX frame. @@ -198,11 +201,15 @@ class KNXGroupAddress(Entity): self._data = res else: _LOGGER.debug( - "Unable to read from KNX address: %s (None)", self.address) + "%s: unable to read from KNX address: %s (None)", + self.name, self.address + ) except KNXException: _LOGGER.exception( - "Unable to read from KNX address: %s", self.address) + "%s: unable to read from KNX address: %s", + self.name, self.address + ) return False @@ -229,20 +236,44 @@ class KNXMultiAddressDevice(Entity): self._config = config self._state = False self._data = None - _LOGGER.debug("Initalizing KNX multi address device") + _LOGGER.debug( + "%s: initalizing KNX multi address device", + self.name + ) settings = self._config.config + if config.address: + _LOGGER.debug( + "%s: base address: address=%s", + self.name, settings.get('address') + ) + self.names[config.address] = 'base' + if config.state_address: + _LOGGER.debug( + "%s, state address: state_address=%s", + self.name, settings.get('state_address') + ) + self.names[config.state_address] = 'state' + # parse required addresses for name in required: - _LOGGER.info(name) paramname = '{}{}'.format(name, '_address') addr = settings.get(paramname) if addr is None: - _LOGGER.exception( - "Required KNX group address %s missing", paramname) + _LOGGER.error( + "%s: Required KNX group address %s missing", + self.name, paramname + ) raise KNXException( - "Group address for %s missing in configuration", paramname) - _LOGGER.debug("%s: %s=%s", settings.get('name'), paramname, addr) + "%s: Group address for {} missing in " + "configuration for {}".format( + self.name, paramname + ) + ) + _LOGGER.debug( + "%s: (required parameter) %s=%s", + self.name, paramname, addr + ) addr = parse_group_address(addr) self.names[addr] = name @@ -250,12 +281,18 @@ class KNXMultiAddressDevice(Entity): for name in optional: paramname = '{}{}'.format(name, '_address') addr = settings.get(paramname) - _LOGGER.debug("%s: %s=%s", settings.get('name'), paramname, addr) + _LOGGER.debug( + "%s: (optional parameter) %s=%s", + self.name, paramname, addr + ) if addr: try: addr = parse_group_address(addr) except KNXException: - _LOGGER.exception("Cannot parse group address %s", addr) + _LOGGER.exception( + "%s: cannot parse group address %s", + self.name, addr + ) self.names[addr] = name @property @@ -283,7 +320,7 @@ class KNXMultiAddressDevice(Entity): This is mostly important for optional addresses. """ - for attributename, dummy_attribute in self.names.items(): + for attributename in self.names.values(): if attributename == name: return True return False @@ -296,7 +333,7 @@ class KNXMultiAddressDevice(Entity): percentage = abs(percentage) # only accept positive values scaled_value = percentage * 255 / 100 value = min(255, scaled_value) - self.set_int_value(name, value) + return self.set_int_value(name, value) def get_percentage(self, name): """Get a percentage from knx for a given attribute. @@ -312,7 +349,7 @@ class KNXMultiAddressDevice(Entity): # KNX packets are big endian value = round(value) # only accept integers b_value = value.to_bytes(num_bytes, byteorder='big') - self.set_value(name, list(b_value)) + return self.set_value(name, list(b_value)) def get_int_value(self, name): """Get an integer value for a given attribute.""" @@ -340,13 +377,21 @@ class KNXMultiAddressDevice(Entity): addr = attributeaddress if addr is None: - _LOGGER.exception("Attribute %s undefined", name) + _LOGGER.error("%s: attribute '%s' undefined", + self.name, name) + _LOGGER.debug( + "%s: defined attributes: %s", + self.name, str(self.names) + ) return False try: res = KNXTUNNEL.group_read(addr, use_cache=self.cache) except KNXException: - _LOGGER.exception("Unable to read from KNX address: %s", addr) + _LOGGER.exception( + "%s: unable to read from KNX address: %s", + self.name, addr + ) return False return res @@ -361,13 +406,21 @@ class KNXMultiAddressDevice(Entity): addr = attributeaddress if addr is None: - _LOGGER.exception("Attribute %s undefined", name) + _LOGGER.error("%s: attribute '%s' undefined", + self.name, name) + _LOGGER.debug( + "%s: defined attributes: %s", + self.name, str(self.names) + ) return False try: KNXTUNNEL.group_write(addr, value) except KNXException: - _LOGGER.exception("Unable to write to KNX address: %s", addr) + _LOGGER.exception( + "%s: unable to write to KNX address: %s", + self.name, addr + ) return False return True From b82003ae086d0de26432115cb620c202c1ff1369 Mon Sep 17 00:00:00 2001 From: Michael Fester Date: Sat, 1 Jul 2017 22:58:12 +0200 Subject: [PATCH 009/131] Snips ASR and NLU component (#8156) * Snips ASR and NLU component * Fix warning * Fix warnings * Fix lint issues * Add tests * Fix tabs * Fix newline * Fix quotes * Fix docstrings * Update tests * Remove logs * Fix lint warning * Update API * Fix Snips --- homeassistant/components/snips.py | 138 ++++++++++++++++++++++++++++++ tests/components/test_snips.py | 53 ++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 homeassistant/components/snips.py create mode 100644 tests/components/test_snips.py diff --git a/homeassistant/components/snips.py b/homeassistant/components/snips.py new file mode 100644 index 00000000000..aa42833daf3 --- /dev/null +++ b/homeassistant/components/snips.py @@ -0,0 +1,138 @@ +""" +Support for Snips on-device ASR and NLU. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/snips/ +""" +import asyncio +import copy +import json +import logging +import voluptuous as vol +from homeassistant.helpers import template, script, config_validation as cv +import homeassistant.loader as loader + +DOMAIN = 'snips' +DEPENDENCIES = ['mqtt'] +CONF_INTENTS = 'intents' +CONF_ACTION = 'action' + +INTENT_TOPIC = 'hermes/nlu/intentParsed' + +LOGGER = logging.getLogger(__name__) + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: { + CONF_INTENTS: { + cv.string: { + vol.Optional(CONF_ACTION): cv.SCRIPT_SCHEMA, + } + } + } +}, extra=vol.ALLOW_EXTRA) + +INTENT_SCHEMA = vol.Schema({ + vol.Required('text'): str, + vol.Required('intent'): { + vol.Required('intent_name'): str + }, + vol.Optional('slots'): [{ + vol.Required('slot_name'): str, + vol.Required('value'): { + vol.Required('kind'): str, + vol.Required('value'): cv.match_all + } + }] +}, extra=vol.ALLOW_EXTRA) + + +@asyncio.coroutine +def async_setup(hass, config): + """Activate Snips component.""" + mqtt = loader.get_component('mqtt') + intents = config[DOMAIN].get(CONF_INTENTS, {}) + handler = IntentHandler(hass, intents) + + @asyncio.coroutine + def message_received(topic, payload, qos): + """Handle new messages on MQTT.""" + LOGGER.debug("New intent: %s", payload) + yield from handler.handle_intent(payload) + + yield from mqtt.async_subscribe(hass, INTENT_TOPIC, message_received) + + return True + + +class IntentHandler(object): + """Help handling intents.""" + + def __init__(self, hass, intents): + """Initialize the intent handler.""" + self.hass = hass + intents = copy.deepcopy(intents) + template.attach(hass, intents) + + for name, intent in intents.items(): + if CONF_ACTION in intent: + intent[CONF_ACTION] = script.Script( + hass, intent[CONF_ACTION], "Snips intent {}".format(name)) + + self.intents = intents + + @asyncio.coroutine + def handle_intent(self, payload): + """Handle an intent.""" + try: + response = json.loads(payload) + except TypeError: + LOGGER.error('Received invalid JSON: %s', payload) + return + + try: + response = INTENT_SCHEMA(response) + except vol.Invalid as err: + LOGGER.error('Intent has invalid schema: %s. %s', err, response) + return + + intent = response['intent']['intent_name'].split('__')[-1] + config = self.intents.get(intent) + + if config is None: + LOGGER.warning("Received unknown intent %s. %s", intent, response) + return + + action = config.get(CONF_ACTION) + + if action is not None: + slots = self.parse_slots(response) + yield from action.async_run(slots) + + def parse_slots(self, response): + """Parse the intent slots.""" + parameters = {} + + for slot in response.get('slots', []): + key = slot['slot_name'] + value = self.get_value(slot['value']) + if value is not None: + parameters[key] = value + + return parameters + + @staticmethod + def get_value(value): + """Return the value of a given slot.""" + kind = value['kind'] + + if kind == "Custom": + return value["value"] + elif kind == "Builtin": + try: + return value["value"]["value"] + except KeyError: + return None + else: + LOGGER.warning('Received unknown slot type: %s', kind) + + return None diff --git a/tests/components/test_snips.py b/tests/components/test_snips.py new file mode 100644 index 00000000000..09a33dae2be --- /dev/null +++ b/tests/components/test_snips.py @@ -0,0 +1,53 @@ +"""Test the Snips component.""" +import asyncio + +from homeassistant.bootstrap import async_setup_component +from tests.common import async_fire_mqtt_message, async_mock_service + +EXAMPLE_MSG = """ +{ + "text": "turn the lights green", + "intent": { + "intent_name": "Lights", + "probability": 1 + }, + "slots": [ + { + "slot_name": "light_color", + "value": { + "kind": "Custom", + "value": "blue" + } + } + ] +} +""" + + +@asyncio.coroutine +def test_snips_call_action(hass, mqtt_mock): + """Test calling action via Snips.""" + calls = async_mock_service(hass, 'test', 'service') + + result = yield from async_setup_component(hass, "snips", { + "snips": { + "intents": { + "Lights": { + "action": { + "service": "test.service", + "data_template": { + "color": "{{ light_color }}" + } + } + } + } + } + }) + assert result + + async_fire_mqtt_message(hass, 'hermes/nlu/intentParsed', + EXAMPLE_MSG) + yield from hass.async_block_till_done() + assert len(calls) == 1 + call = calls[0] + assert call.data.get('color') == 'blue' From 0bf5021c2c2e0d04b84a5cba5064ab5754d8f5dc Mon Sep 17 00:00:00 2001 From: Mike Megally Date: Sat, 1 Jul 2017 14:10:17 -0700 Subject: [PATCH 010/131] Create an index on the states table to help hass startup time (#8255) --- homeassistant/components/recorder/migration.py | 2 ++ homeassistant/components/recorder/models.py | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/recorder/migration.py b/homeassistant/components/recorder/migration.py index 0fac32bdec7..043887b7cab 100644 --- a/homeassistant/components/recorder/migration.py +++ b/homeassistant/components/recorder/migration.py @@ -64,6 +64,8 @@ def _apply_update(engine, new_version): # Create indexes for states _create_index(engine, "states", "ix_states_last_updated") _create_index(engine, "states", "ix_states_entity_id_created") + elif new_version == 3: + _create_index(engine, "states", "ix_states_created_domain") else: raise ValueError("No schema migration defined for version {}" .format(new_version)) diff --git a/homeassistant/components/recorder/models.py b/homeassistant/components/recorder/models.py index 6dcb5dbd051..65c7dc6abb6 100644 --- a/homeassistant/components/recorder/models.py +++ b/homeassistant/components/recorder/models.py @@ -16,7 +16,7 @@ from homeassistant.remote import JSONEncoder # pylint: disable=invalid-name Base = declarative_base() -SCHEMA_VERSION = 2 +SCHEMA_VERSION = 3 _LOGGER = logging.getLogger(__name__) @@ -75,7 +75,9 @@ class States(Base): # type: ignore Index('states__significant_changes', 'domain', 'last_updated', 'entity_id'), Index('ix_states_entity_id_created', - 'entity_id', 'created'),) + 'entity_id', 'created'), + Index('ix_states_created_domain', + 'created', 'domain'),) @staticmethod def from_event(event): From 47aa8c387a0770eb5660748bf70f19881977dae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Arnauts?= Date: Sun, 2 Jul 2017 11:24:07 +0200 Subject: [PATCH 011/131] Update apcaccess to 0.0.13. Add "Percent Load Capacity" to INFERRED_UNITS. (#8277) --- homeassistant/components/apcupsd.py | 2 +- homeassistant/components/sensor/apcupsd.py | 1 + requirements_all.txt | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/apcupsd.py b/homeassistant/components/apcupsd.py index b2423d44623..dd29e7d602f 100644 --- a/homeassistant/components/apcupsd.py +++ b/homeassistant/components/apcupsd.py @@ -13,7 +13,7 @@ from homeassistant.const import (CONF_HOST, CONF_PORT) import homeassistant.helpers.config_validation as cv from homeassistant.util import Throttle -REQUIREMENTS = ['apcaccess==0.0.10'] +REQUIREMENTS = ['apcaccess==0.0.13'] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/sensor/apcupsd.py b/homeassistant/components/sensor/apcupsd.py index ec4db5e2934..0ddf6f160ae 100644 --- a/homeassistant/components/sensor/apcupsd.py +++ b/homeassistant/components/sensor/apcupsd.py @@ -96,6 +96,7 @@ INFERRED_UNITS = { ' Watts': 'W', ' Hz': 'Hz', ' C': TEMP_CELSIUS, + ' Percent Load Capacity': '%', } PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ diff --git a/requirements_all.txt b/requirements_all.txt index c0ae35d7eed..6794ea1585e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -68,7 +68,7 @@ amcrest==1.2.0 anthemav==1.1.8 # homeassistant.components.apcupsd -apcaccess==0.0.10 +apcaccess==0.0.13 # homeassistant.components.notify.apns apns2==0.1.1 From b4165fe9f325e7e5d257d2406cc62618c89def0b Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sun, 2 Jul 2017 12:02:41 +0200 Subject: [PATCH 012/131] Fix hass.data (fixes #8288) (#8290) --- homeassistant/components/camera/arlo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/camera/arlo.py b/homeassistant/components/camera/arlo.py index be6aab30af5..637b0dfc2e6 100644 --- a/homeassistant/components/camera/arlo.py +++ b/homeassistant/components/camera/arlo.py @@ -49,7 +49,7 @@ class ArloCam(Camera): """Initialize an Arlo camera.""" super().__init__() self._camera = camera - self._base_stn = hass.data['arlo'].base_stations[0] + self._base_stn = hass.data[DATA_ARLO].base_stations[0] self._name = self._camera.name self._motion_status = False self._ffmpeg = hass.data[DATA_FFMPEG] From 05ced33648fbac4bd767ca0367a87dfc203cf9d3 Mon Sep 17 00:00:00 2001 From: Open Home Automation Date: Sun, 2 Jul 2017 12:59:45 +0200 Subject: [PATCH 013/131] Update knxip to 0.4 (better handling of reconnects) (#8289) --- homeassistant/components/knx.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/knx.py b/homeassistant/components/knx.py index 9155304def7..2cb8562ad9c 100644 --- a/homeassistant/components/knx.py +++ b/homeassistant/components/knx.py @@ -13,7 +13,7 @@ from homeassistant.const import ( EVENT_HOMEASSISTANT_STOP, CONF_HOST, CONF_PORT) from homeassistant.helpers.entity import Entity -REQUIREMENTS = ['knxip==0.3.3'] +REQUIREMENTS = ['knxip==0.4'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 6794ea1585e..bd946ba9dc6 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -344,7 +344,7 @@ jsonrpc-websocket==0.5 keyring>=9.3,<10.0 # homeassistant.components.knx -knxip==0.3.3 +knxip==0.4 # homeassistant.components.device_tracker.owntracks libnacl==1.5.1 From 865865ca0f5166b03bec0be9317ca6b65644328b Mon Sep 17 00:00:00 2001 From: Robin Date: Sun, 2 Jul 2017 18:32:39 +0000 Subject: [PATCH 014/131] Add london_underground (#8272) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add tube_state Add tube_state sensor * Final cleanup * Make corrections Correct PLATFORM_SCHEMA * Fix space * Make test pass * Correct format of test Test still failing, don’t understand why * correct description * Make test pass Preferred method below returns None state = self.hass.states.get('sensor.london_overground') * Format for hound * indent * Make requested changes to test, not working Test fails with: AssertionError: assert 0 > 0 where 0 = len([]) Surely I need tube_state.setup_platform ? * Fixed test Config was wrong * Change component name to london_tube * Update name to london_underground Make consistent * cleanup --- .../components/sensor/london_underground.py | 135 +++++ .../sensor/test_london_underground.py | 38 ++ tests/fixtures/london_underground.json | 465 ++++++++++++++++++ 3 files changed, 638 insertions(+) create mode 100644 homeassistant/components/sensor/london_underground.py create mode 100644 tests/components/sensor/test_london_underground.py create mode 100644 tests/fixtures/london_underground.json diff --git a/homeassistant/components/sensor/london_underground.py b/homeassistant/components/sensor/london_underground.py new file mode 100644 index 00000000000..c8ade9b6b6f --- /dev/null +++ b/homeassistant/components/sensor/london_underground.py @@ -0,0 +1,135 @@ +""" +Sensor for checking the status of London Underground tube lines. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/sensor.tube-state +""" +import logging +from datetime import timedelta + +import voluptuous as vol +import requests + +import homeassistant.helpers.config_validation as cv +from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.helpers.entity import Entity +from homeassistant.util import Throttle + +_LOGGER = logging.getLogger(__name__) + +ATTRIBUTION = "Powered by TfL Open Data" +CONF_LINE = 'line' +SCAN_INTERVAL = timedelta(seconds=30) +TUBE_LINES = [ + 'Bakerloo', + 'Central', + 'Circle', + 'District', + 'DLR', + 'Hammersmith & City', + 'Jubilee', + 'London Overground', + 'Metropolitan', + 'Northern', + 'Piccadilly', + 'TfL Rail', + 'Victoria', + 'Waterloo & City'] +URL = 'https://api.tfl.gov.uk/line/mode/tube,overground,dlr,tflrail/status' + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_LINE): + vol.All(cv.ensure_list, [vol.In(list(TUBE_LINES))]), +}) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Set up the Tube sensor.""" + data = TubeData() + data.update() + sensors = [] + for line in config.get(CONF_LINE): + sensors.append(LondonTubeSensor(line, data)) + + add_devices(sensors, True) + + +class LondonTubeSensor(Entity): + """Sensor that reads the status of a line from TubeData.""" + + ICON = 'mdi:subway' + + def __init__(self, name, data): + """Initialize the sensor.""" + self._name = name + self._data = data + self._state = None + self._description = None + + @property + def name(self): + """Return the name of the sensor.""" + return self._name + + @property + def state(self): + """Return the state of the sensor.""" + return self._state + + @property + def icon(self): + """Icon to use in the frontend, if any.""" + return self.ICON + + @property + def device_state_attributes(self): + """Return other details about the sensor state.""" + attrs = {} + attrs['Description'] = self._description + return attrs + + def update(self): + """Update the sensor.""" + self._data.update() + self._state = self._data.data[self.name]['State'] + self._description = self._data.data[self.name]['Description'] + + +class TubeData(object): + """Get the latest tube data from TFL.""" + + def __init__(self): + """Initialize the TubeData object.""" + self.data = None + + # Update only once in scan interval. + @Throttle(SCAN_INTERVAL) + def update(self): + """Get the latest data from TFL.""" + response = requests.get(URL) + if response.status_code != 200: + _LOGGER.warning("Invalid response from API") + else: + self.data = parse_api_response(response.json()) + + +def parse_api_response(response): + """Take in the TFL API json response.""" + lines = [line['name'] for line in response] + data_dict = dict.fromkeys(lines) + + for line in response: + statuses = [status['statusSeverityDescription'] + for status in line['lineStatuses']] + state = ' + '.join(sorted(set(statuses))) + + if state == 'Good Service': + reason = 'Nothing to report' + else: + reason = ' *** '.join( + [status['reason'] for status in line['lineStatuses']]) + + attr = {'State': state, 'Description': reason} + data_dict[line['name']] = attr + + return data_dict diff --git a/tests/components/sensor/test_london_underground.py b/tests/components/sensor/test_london_underground.py new file mode 100644 index 00000000000..fbffcbd1d8f --- /dev/null +++ b/tests/components/sensor/test_london_underground.py @@ -0,0 +1,38 @@ +"""The tests for the tube_state platform.""" +import unittest +import requests_mock + +from homeassistant.components.sensor.london_underground import CONF_LINE, URL +from homeassistant.setup import setup_component +from tests.common import load_fixture, get_test_home_assistant + +VALID_CONFIG = { + 'platform': 'london_underground', + CONF_LINE: [ + 'London Overground', + ] +} + + +class TestLondonTubeSensor(unittest.TestCase): + """Test the tube_state platform.""" + + def setUp(self): + """Initialize values for this testcase class.""" + self.hass = get_test_home_assistant() + self.config = VALID_CONFIG + + def tearDown(self): + """Stop everything that was started.""" + self.hass.stop() + + @requests_mock.Mocker() + def test_setup(self, mock_req): + """Test for operational tube_state sensor with proper attributes.""" + mock_req.get(URL, text=load_fixture('london_underground.json')) + self.assertTrue( + setup_component(self.hass, 'sensor', {'sensor': self.config})) + + state = self.hass.states.get('sensor.london_overground') + assert state.state == 'Minor Delays' + assert state.attributes.get('Description') == 'something' diff --git a/tests/fixtures/london_underground.json b/tests/fixtures/london_underground.json new file mode 100644 index 00000000000..fddae7e89e2 --- /dev/null +++ b/tests/fixtures/london_underground.json @@ -0,0 +1,465 @@ +[ + { + "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", + "id": "bakerloo", + "name": "Bakerloo", + "modeName": "tube", + "disruptions": [], + "created": "2017-06-28T11:43:10.703Z", + "modified": "2017-06-28T11:43:10.703Z", + "lineStatuses": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", + "id": 0, + "statusSeverity": 10, + "statusSeverityDescription": "Good Service", + "created": "0001-01-01T00:00:00", + "validityPeriods": [] + } + ], + "routeSections": [], + "serviceTypes": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Regular", + "uri": "/Line/Route?ids=Bakerloo&serviceTypes=Regular" + } + ], + "crowding": { + "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities" + } + }, + { + "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", + "id": "central", + "name": "Central", + "modeName": "tube", + "disruptions": [], + "created": "2017-06-28T11:43:10.623Z", + "modified": "2017-06-28T11:43:10.623Z", + "lineStatuses": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", + "id": 0, + "statusSeverity": 10, + "statusSeverityDescription": "Good Service", + "created": "0001-01-01T00:00:00", + "validityPeriods": [] + } + ], + "routeSections": [], + "serviceTypes": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Regular", + "uri": "/Line/Route?ids=Central&serviceTypes=Regular" + }, + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Night", + "uri": "/Line/Route?ids=Central&serviceTypes=Night" + } + ], + "crowding": { + "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities" + } + }, + { + "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", + "id": "circle", + "name": "Circle", + "modeName": "tube", + "disruptions": [], + "created": "2017-06-28T11:43:10.733Z", + "modified": "2017-06-28T11:43:10.733Z", + "lineStatuses": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", + "id": 0, + "statusSeverity": 10, + "statusSeverityDescription": "Good Service", + "created": "0001-01-01T00:00:00", + "validityPeriods": [] + } + ], + "routeSections": [], + "serviceTypes": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Regular", + "uri": "/Line/Route?ids=Circle&serviceTypes=Regular" + } + ], + "crowding": { + "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities" + } + }, + { + "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", + "id": "district", + "name": "District", + "modeName": "tube", + "disruptions": [], + "created": "2017-06-28T11:43:10.623Z", + "modified": "2017-06-28T11:43:10.623Z", + "lineStatuses": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", + "id": 0, + "statusSeverity": 10, + "statusSeverityDescription": "Good Service", + "created": "0001-01-01T00:00:00", + "validityPeriods": [] + } + ], + "routeSections": [], + "serviceTypes": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Regular", + "uri": "/Line/Route?ids=District&serviceTypes=Regular" + } + ], + "crowding": { + "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities" + } + }, + { + "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", + "id": "dlr", + "name": "DLR", + "modeName": "dlr", + "disruptions": [], + "created": "2017-06-28T11:43:10.703Z", + "modified": "2017-06-28T11:43:10.703Z", + "lineStatuses": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", + "id": 0, + "statusSeverity": 10, + "statusSeverityDescription": "Good Service", + "created": "0001-01-01T00:00:00", + "validityPeriods": [] + } + ], + "routeSections": [], + "serviceTypes": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Regular", + "uri": "/Line/Route?ids=DLR&serviceTypes=Regular" + } + ], + "crowding": { + "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities" + } + }, + { + "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", + "id": "hammersmith-city", + "name": "Hammersmith & City", + "modeName": "tube", + "disruptions": [], + "created": "2017-06-28T11:43:10.67Z", + "modified": "2017-06-28T11:43:10.67Z", + "lineStatuses": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", + "id": 0, + "statusSeverity": 10, + "statusSeverityDescription": "Good Service", + "created": "0001-01-01T00:00:00", + "validityPeriods": [] + } + ], + "routeSections": [], + "serviceTypes": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Regular", + "uri": "/Line/Route?ids=Hammersmith & City&serviceTypes=Regular" + } + ], + "crowding": { + "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities" + } + }, + { + "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", + "id": "jubilee", + "name": "Jubilee", + "modeName": "tube", + "disruptions": [], + "created": "2017-06-28T11:43:10.623Z", + "modified": "2017-06-28T11:43:10.623Z", + "lineStatuses": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", + "id": 0, + "statusSeverity": 10, + "statusSeverityDescription": "Good Service", + "created": "0001-01-01T00:00:00", + "validityPeriods": [] + } + ], + "routeSections": [], + "serviceTypes": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Regular", + "uri": "/Line/Route?ids=Jubilee&serviceTypes=Regular" + }, + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Night", + "uri": "/Line/Route?ids=Jubilee&serviceTypes=Night" + } + ], + "crowding": { + "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities" + } + }, + { + "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", + "id": "london-overground", + "name": "London Overground", + "modeName": "overground", + "disruptions": [], + "created": "2017-06-28T11:43:10.607Z", + "modified": "2017-06-28T11:43:10.607Z", + "lineStatuses": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", + "id": 0, + "lineId": "london-overground", + "statusSeverity": 9, + "statusSeverityDescription": "Minor Delays", + "reason": "something", + "created": "0001-01-01T00:00:00", + "validityPeriods": [ + { + "$type": "Tfl.Api.Presentation.Entities.ValidityPeriod, Tfl.Api.Presentation.Entities", + "fromDate": "2017-06-29T06:27:21Z", + "toDate": "2017-06-30T01:29:00Z", + "isNow": true + } + ], + "disruption": { + "$type": "Tfl.Api.Presentation.Entities.Disruption, Tfl.Api.Presentation.Entities", + "category": "RealTime", + "categoryDescription": "RealTime", + "description": "London Overground: Minor delays Richmond to Stratford and Willesden Junction to Clapham Junction while we fix a faulty train at Richmond, GOOD SERVICE all other routes. ", + "affectedRoutes": [], + "affectedStops": [], + "closureText": "minorDelays" + } + } + ], + "routeSections": [], + "serviceTypes": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Regular", + "uri": "/Line/Route?ids=London Overground&serviceTypes=Regular" + } + ], + "crowding": { + "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities" + } + }, + { + "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", + "id": "metropolitan", + "name": "Metropolitan", + "modeName": "tube", + "disruptions": [], + "created": "2017-06-28T11:43:10.703Z", + "modified": "2017-06-28T11:43:10.703Z", + "lineStatuses": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", + "id": 0, + "statusSeverity": 10, + "statusSeverityDescription": "Good Service", + "created": "0001-01-01T00:00:00", + "validityPeriods": [] + } + ], + "routeSections": [], + "serviceTypes": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Regular", + "uri": "/Line/Route?ids=Metropolitan&serviceTypes=Regular" + } + ], + "crowding": { + "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities" + } + }, + { + "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", + "id": "northern", + "name": "Northern", + "modeName": "tube", + "disruptions": [], + "created": "2017-06-28T11:43:10.67Z", + "modified": "2017-06-28T11:43:10.67Z", + "lineStatuses": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", + "id": 0, + "statusSeverity": 10, + "statusSeverityDescription": "Good Service", + "created": "0001-01-01T00:00:00", + "validityPeriods": [] + } + ], + "routeSections": [], + "serviceTypes": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Regular", + "uri": "/Line/Route?ids=Northern&serviceTypes=Regular" + }, + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Night", + "uri": "/Line/Route?ids=Northern&serviceTypes=Night" + } + ], + "crowding": { + "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities" + } + }, + { + "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", + "id": "piccadilly", + "name": "Piccadilly", + "modeName": "tube", + "disruptions": [], + "created": "2017-06-28T11:43:10.67Z", + "modified": "2017-06-28T11:43:10.67Z", + "lineStatuses": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", + "id": 0, + "statusSeverity": 10, + "statusSeverityDescription": "Good Service", + "created": "0001-01-01T00:00:00", + "validityPeriods": [] + } + ], + "routeSections": [], + "serviceTypes": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Regular", + "uri": "/Line/Route?ids=Piccadilly&serviceTypes=Regular" + }, + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Night", + "uri": "/Line/Route?ids=Piccadilly&serviceTypes=Night" + } + ], + "crowding": { + "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities" + } + }, + { + "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", + "id": "tfl-rail", + "name": "TfL Rail", + "modeName": "tflrail", + "disruptions": [], + "created": "2017-06-28T11:43:10.657Z", + "modified": "2017-06-28T11:43:10.657Z", + "lineStatuses": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", + "id": 0, + "statusSeverity": 10, + "statusSeverityDescription": "Good Service", + "created": "0001-01-01T00:00:00", + "validityPeriods": [] + } + ], + "routeSections": [], + "serviceTypes": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Regular", + "uri": "/Line/Route?ids=TfL Rail&serviceTypes=Regular" + } + ], + "crowding": { + "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities" + } + }, + { + "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", + "id": "victoria", + "name": "Victoria", + "modeName": "tube", + "disruptions": [], + "created": "2017-06-28T11:43:10.607Z", + "modified": "2017-06-28T11:43:10.607Z", + "lineStatuses": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", + "id": 0, + "statusSeverity": 10, + "statusSeverityDescription": "Good Service", + "created": "0001-01-01T00:00:00", + "validityPeriods": [] + } + ], + "routeSections": [], + "serviceTypes": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Regular", + "uri": "/Line/Route?ids=Victoria&serviceTypes=Regular" + }, + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Night", + "uri": "/Line/Route?ids=Victoria&serviceTypes=Night" + } + ], + "crowding": { + "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities" + } + }, + { + "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities", + "id": "waterloo-city", + "name": "Waterloo & City", + "modeName": "tube", + "disruptions": [], + "created": "2017-06-28T11:43:10.703Z", + "modified": "2017-06-28T11:43:10.703Z", + "lineStatuses": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities", + "id": 0, + "statusSeverity": 10, + "statusSeverityDescription": "Good Service", + "created": "0001-01-01T00:00:00", + "validityPeriods": [] + } + ], + "routeSections": [], + "serviceTypes": [ + { + "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities", + "name": "Regular", + "uri": "/Line/Route?ids=Waterloo & City&serviceTypes=Regular" + } + ], + "crowding": { + "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities" + } + } +] From 3f2fa0ed5af4d3da936fe1e226f062938924a496 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 2 Jul 2017 11:52:24 -0700 Subject: [PATCH 015/131] Disable Python 3.6-dev while it's broken --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0bdde06bb35..fdc5650db22 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,8 +16,8 @@ matrix: env: TOXENV=py35 - python: "3.6" env: TOXENV=py36 - - python: "3.6-dev" - env: TOXENV=py36 + # - python: "3.6-dev" + # env: TOXENV=py36 - python: "3.4.2" env: TOXENV=requirements # allow_failures: From a2f5b630d64dc92cfbc63bfe742a6f5a066f8c63 Mon Sep 17 00:00:00 2001 From: Wolfgang Malgadey Date: Sun, 2 Jul 2017 21:54:59 +0200 Subject: [PATCH 016/131] pytado moved to pypi (#8298) --- homeassistant/components/tado.py | 4 +--- requirements_all.txt | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/tado.py b/homeassistant/components/tado.py index 24712fa2fbe..1f5125d724e 100644 --- a/homeassistant/components/tado.py +++ b/homeassistant/components/tado.py @@ -15,9 +15,7 @@ from homeassistant.helpers import config_validation as cv from homeassistant.const import CONF_USERNAME, CONF_PASSWORD from homeassistant.util import Throttle -REQUIREMENTS = ['https://github.com/wmalgadey/PyTado/archive/' - '0.2.1.zip#' - 'PyTado==0.2.1'] +REQUIREMENTS = ['python-tado==0.2.2'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index bd946ba9dc6..d6edd705a8c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -309,9 +309,6 @@ https://github.com/soldag/pyflic/archive/0.4.zip#pyflic==0.4 # homeassistant.components.light.osramlightify https://github.com/tfriedel/python-lightify/archive/1bb1db0e7bd5b14304d7bb267e2398cd5160df46.zip#lightify==1.0.5 -# homeassistant.components.tado -https://github.com/wmalgadey/PyTado/archive/0.2.1.zip#PyTado==0.2.1 - # homeassistant.components.media_player.lg_netcast https://github.com/wokar/pylgnetcast/archive/v0.2.0.zip#pylgnetcast==0.2.0 @@ -732,6 +729,9 @@ python-roku==3.1.3 # homeassistant.components.sensor.synologydsm python-synology==0.1.0 +# homeassistant.components.tado +python-tado==0.2.2 + # homeassistant.components.telegram_bot python-telegram-bot==6.1.0 From 3a6434f566be7376813db712d1b3ec784d1cc26d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 2 Jul 2017 13:05:07 -0700 Subject: [PATCH 017/131] Fix harmony (#8302) * Fix harmony * Fix 1 reference --- homeassistant/components/remote/harmony.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/remote/harmony.py b/homeassistant/components/remote/harmony.py index 9c6bad77b31..165bd0b9114 100755 --- a/homeassistant/components/remote/harmony.py +++ b/homeassistant/components/remote/harmony.py @@ -26,7 +26,7 @@ _LOGGER = logging.getLogger(__name__) DEFAULT_PORT = 5222 DEVICES = [] -CONF_DEVICE_CACHE = 'device_cache' +CONF_DEVICE_CACHE = 'harmony_device_cache' SERVICE_SYNC = 'harmony_sync' @@ -69,7 +69,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): port) # Ignore hub name when checking if this hub is known - ip and port only - if host and host[1:] in set([h[1:] for h in DEVICES]): + if host and host[1:] in (h.host for h in DEVICES): _LOGGER.debug("Discovered host already known: %s", host) return elif CONF_HOST in config: @@ -147,7 +147,7 @@ class HarmonyRemote(remote.RemoteDevice): _LOGGER.debug("HarmonyRemote device init started for: %s", name) self._name = name - self._ip = host + self.host = host self._port = port self._state = None self._current_activity = None @@ -182,7 +182,7 @@ class HarmonyRemote(remote.RemoteDevice): name = self._name _LOGGER.debug("Polling %s for current activity", name) state = pyharmony.ha_get_current_activity( - self._token, self._config, self._ip, self._port) + self._token, self._config, self.host, self._port) _LOGGER.debug("%s current activity reported as: %s", name, state) self._current_activity = state self._state = bool(state != 'PowerOff') @@ -197,7 +197,7 @@ class HarmonyRemote(remote.RemoteDevice): if activity: pyharmony.ha_start_activity( - self._token, self._ip, self._port, self._config, activity) + self._token, self.host, self._port, self._config, activity) self._state = True else: _LOGGER.error("No activity specified with turn_on service") @@ -205,13 +205,13 @@ class HarmonyRemote(remote.RemoteDevice): def turn_off(self): """Start the PowerOff activity.""" import pyharmony - pyharmony.ha_power_off(self._token, self._ip, self._port) + pyharmony.ha_power_off(self._token, self.host, self._port) def send_command(self, **kwargs): """Send a set of commands to one device.""" import pyharmony pyharmony.ha_send_commands( - self._token, self._ip, self._port, kwargs[ATTR_DEVICE], + self._token, self.host, self._port, kwargs[ATTR_DEVICE], kwargs[ATTR_COMMAND], int(kwargs[ATTR_NUM_REPEATS]), float(kwargs[ATTR_DELAY_SECS])) @@ -219,8 +219,8 @@ class HarmonyRemote(remote.RemoteDevice): """Sync the Harmony device with the web service.""" import pyharmony _LOGGER.debug("Syncing hub with Harmony servers") - pyharmony.ha_sync(self._token, self._ip, self._port) + pyharmony.ha_sync(self._token, self.host, self._port) self._config = pyharmony.ha_get_config( - self._token, self._ip, self._port) + self._token, self.host, self._port) _LOGGER.debug("Writing hub config to file: %s", self._config_path) pyharmony.ha_write_config_file(self._config, self._config_path) From ee7d4710c4bb25b75468dfa5cea725f818fed3b4 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Mon, 3 Jul 2017 07:24:08 +0200 Subject: [PATCH 018/131] Fix pathlib resolve (#8311) * Fix pathlib resolve * fix test --- homeassistant/core.py | 2 +- tests/test_core.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/core.py b/homeassistant/core.py index 4fcd938335c..c65566b42fa 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -1079,7 +1079,7 @@ class Config(object): """Check if the path is valid for access from outside.""" parent = pathlib.Path(path).parent try: - parent.resolve() # pylint: disable=no-member + parent = parent.resolve() # pylint: disable=no-member except (FileNotFoundError, RuntimeError, PermissionError): return False diff --git a/tests/test_core.py b/tests/test_core.py index f173ad65c41..1d22d17f996 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -821,13 +821,13 @@ class TestConfig(unittest.TestCase): for path in valid: assert self.config.is_allowed_path(path) - self.config.whitelist_external_dirs = set(('/home',)) + self.config.whitelist_external_dirs = set(('/home', '/var')) unvalid = [ "/hass/config/secure", "/etc/passwd", "/root/secure_file", - "/hass/config/test/../../../etc/passwd", + "/var/../etc/passwd", test_file, ] for path in unvalid: From 4ab778fd974d0a114bd2bd5259ccf45a0bdb9a42 Mon Sep 17 00:00:00 2001 From: Robin Date: Mon, 3 Jul 2017 06:30:42 +0000 Subject: [PATCH 019/131] Fix doc link in header (#8305) * Fix doc link in header * Add missing `/` --- homeassistant/components/sensor/london_underground.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/sensor/london_underground.py b/homeassistant/components/sensor/london_underground.py index c8ade9b6b6f..fe13c0db8a7 100644 --- a/homeassistant/components/sensor/london_underground.py +++ b/homeassistant/components/sensor/london_underground.py @@ -1,8 +1,8 @@ """ Sensor for checking the status of London Underground tube lines. -For more details about this component, please refer to the documentation at -https://home-assistant.io/components/sensor.tube-state +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.london_underground/ """ import logging from datetime import timedelta From 407a419c83810cc3916120168f5de08d7e6e4973 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Mon, 3 Jul 2017 08:30:54 +0200 Subject: [PATCH 020/131] Upgrade discord.py to 0.16.8 (#8304) --- homeassistant/components/notify/discord.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/notify/discord.py b/homeassistant/components/notify/discord.py index 189aa0d02bb..691ff158012 100644 --- a/homeassistant/components/notify/discord.py +++ b/homeassistant/components/notify/discord.py @@ -13,7 +13,7 @@ from homeassistant.components.notify import ( _LOGGER = logging.getLogger(__name__) -REQUIREMENTS = ['discord.py==0.16.0'] +REQUIREMENTS = ['discord.py==0.16.8'] CONF_TOKEN = 'token' diff --git a/requirements_all.txt b/requirements_all.txt index d6edd705a8c..3dd279cca7f 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -153,7 +153,7 @@ denonavr==0.5.1 directpy==0.1 # homeassistant.components.notify.discord -discord.py==0.16.0 +discord.py==0.16.8 # homeassistant.components.updater distro==1.0.4 From 5cba3085b4ad48c391b208fc5c70312907df3cc6 Mon Sep 17 00:00:00 2001 From: Russell Cloran Date: Sun, 2 Jul 2017 23:31:16 -0700 Subject: [PATCH 021/131] zha: Strip whitespace from device names (#8306) --- homeassistant/components/zha/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/zha/__init__.py b/homeassistant/components/zha/__init__.py index 8c84fe166f0..183ced37825 100644 --- a/homeassistant/components/zha/__init__.py +++ b/homeassistant/components/zha/__init__.py @@ -273,7 +273,7 @@ def _discover_endpoint_info(endpoint): for key, value in extra_info.items(): if isinstance(value, bytes): try: - extra_info[key] = value.decode('ascii') + extra_info[key] = value.decode('ascii').strip() except UnicodeDecodeError: # Unsure what the best behaviour here is. Unset the key? pass From bf96f28e953a61ce871d81ea3058a4b2195838fd Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Mon, 3 Jul 2017 11:49:23 +0200 Subject: [PATCH 022/131] Upgrade chardet to 3.0.4 (#8313) --- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index f4230db153e..dd7b514f3a8 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -7,5 +7,5 @@ voluptuous==0.10.5 typing>=3,<4 aiohttp==2.2.0 async_timeout==1.2.1 -chardet==3.0.2 +chardet==3.0.4 astral==1.4 diff --git a/requirements_all.txt b/requirements_all.txt index 3dd279cca7f..c3793d5eff4 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -8,7 +8,7 @@ voluptuous==0.10.5 typing>=3,<4 aiohttp==2.2.0 async_timeout==1.2.1 -chardet==3.0.2 +chardet==3.0.4 astral==1.4 # homeassistant.components.nuimo_controller diff --git a/setup.py b/setup.py index 3a37874a08f..77746cdcc23 100755 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ REQUIRES = [ 'typing>=3,<4', 'aiohttp==2.2.0', 'async_timeout==1.2.1', - 'chardet==3.0.2', + 'chardet==3.0.4', 'astral==1.4', ] From afe3dd8dbb62500e62c02cdd4203e424255718b6 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Mon, 3 Jul 2017 13:48:53 +0200 Subject: [PATCH 023/131] Upgrade aiohttp to 2.2.2 (#8314) * Upgrade aiohttp to 2.2.1 * Upgrade to aiohttp to 2.2.2 --- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index dd7b514f3a8..706836ea324 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -5,7 +5,7 @@ pip>=7.1.0 jinja2>=2.9.5 voluptuous==0.10.5 typing>=3,<4 -aiohttp==2.2.0 +aiohttp==2.2.2 async_timeout==1.2.1 chardet==3.0.4 astral==1.4 diff --git a/requirements_all.txt b/requirements_all.txt index c3793d5eff4..08efa45a179 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -6,7 +6,7 @@ pip>=7.1.0 jinja2>=2.9.5 voluptuous==0.10.5 typing>=3,<4 -aiohttp==2.2.0 +aiohttp==2.2.2 async_timeout==1.2.1 chardet==3.0.4 astral==1.4 diff --git a/setup.py b/setup.py index 77746cdcc23..22423952669 100755 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ REQUIRES = [ 'jinja2>=2.9.5', 'voluptuous==0.10.5', 'typing>=3,<4', - 'aiohttp==2.2.0', + 'aiohttp==2.2.2', 'async_timeout==1.2.1', 'chardet==3.0.4', 'astral==1.4', From 8d940fb585de9a3a360801d163848828104caa64 Mon Sep 17 00:00:00 2001 From: Adrien Ball Date: Mon, 3 Jul 2017 15:07:59 +0200 Subject: [PATCH 024/131] Fix Snips json schema (#8317) * Fix Snips json schema * Fix test --- homeassistant/components/snips.py | 29 ++++++----------------------- tests/components/test_snips.py | 6 +++--- 2 files changed, 9 insertions(+), 26 deletions(-) diff --git a/homeassistant/components/snips.py b/homeassistant/components/snips.py index aa42833daf3..de54c0239c7 100644 --- a/homeassistant/components/snips.py +++ b/homeassistant/components/snips.py @@ -32,12 +32,12 @@ CONFIG_SCHEMA = vol.Schema({ }, extra=vol.ALLOW_EXTRA) INTENT_SCHEMA = vol.Schema({ - vol.Required('text'): str, + vol.Required('input'): str, vol.Required('intent'): { - vol.Required('intent_name'): str + vol.Required('intentName'): str }, vol.Optional('slots'): [{ - vol.Required('slot_name'): str, + vol.Required('slotName'): str, vol.Required('value'): { vol.Required('kind'): str, vol.Required('value'): cv.match_all @@ -95,7 +95,7 @@ class IntentHandler(object): LOGGER.error('Intent has invalid schema: %s. %s', err, response) return - intent = response['intent']['intent_name'].split('__')[-1] + intent = response['intent']['intentName'].split('__')[-1] config = self.intents.get(intent) if config is None: @@ -113,26 +113,9 @@ class IntentHandler(object): parameters = {} for slot in response.get('slots', []): - key = slot['slot_name'] - value = self.get_value(slot['value']) + key = slot['slotName'] + value = slot['value']['value'] if value is not None: parameters[key] = value return parameters - - @staticmethod - def get_value(value): - """Return the value of a given slot.""" - kind = value['kind'] - - if kind == "Custom": - return value["value"] - elif kind == "Builtin": - try: - return value["value"]["value"] - except KeyError: - return None - else: - LOGGER.warning('Received unknown slot type: %s', kind) - - return None diff --git a/tests/components/test_snips.py b/tests/components/test_snips.py index 09a33dae2be..5687723e17a 100644 --- a/tests/components/test_snips.py +++ b/tests/components/test_snips.py @@ -6,14 +6,14 @@ from tests.common import async_fire_mqtt_message, async_mock_service EXAMPLE_MSG = """ { - "text": "turn the lights green", + "input": "turn the lights green", "intent": { - "intent_name": "Lights", + "intentName": "Lights", "probability": 1 }, "slots": [ { - "slot_name": "light_color", + "slotName": "light_color", "value": { "kind": "Custom", "value": "blue" From 1e655eea74e8074cb169060b09bc30229f45fe1b Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Mon, 3 Jul 2017 22:02:43 +0200 Subject: [PATCH 025/131] Fix pylint issue (#8325) --- homeassistant/components/snips.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/snips.py b/homeassistant/components/snips.py index de54c0239c7..d820396bf53 100644 --- a/homeassistant/components/snips.py +++ b/homeassistant/components/snips.py @@ -86,13 +86,13 @@ class IntentHandler(object): try: response = json.loads(payload) except TypeError: - LOGGER.error('Received invalid JSON: %s', payload) + LOGGER.error("Received invalid JSON: %s", payload) return try: response = INTENT_SCHEMA(response) except vol.Invalid as err: - LOGGER.error('Intent has invalid schema: %s. %s', err, response) + LOGGER.error("Intent has invalid schema: %s. %s", err, response) return intent = response['intent']['intentName'].split('__')[-1] @@ -108,6 +108,7 @@ class IntentHandler(object): slots = self.parse_slots(response) yield from action.async_run(slots) + # pylint: disable=no-self-use def parse_slots(self, response): """Parse the intent slots.""" parameters = {} From 22681fbe08224364056ecf8ee513912810c4ab91 Mon Sep 17 00:00:00 2001 From: Eugenio Panadero Date: Mon, 3 Jul 2017 23:35:57 +0200 Subject: [PATCH 026/131] API POST has new state validation (fix for state = 0) (#8324) * Fix validation of get new state * Add unittest to check posting a state with zero value --- homeassistant/components/api.py | 2 +- tests/components/test_api.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/api.py b/homeassistant/components/api.py index b722fc6ebb4..8205029bd21 100644 --- a/homeassistant/components/api.py +++ b/homeassistant/components/api.py @@ -213,7 +213,7 @@ class APIEntityStateView(HomeAssistantView): new_state = data.get('state') - if not new_state: + if new_state is None: return self.json_message('No state specified', HTTP_BAD_REQUEST) attributes = data.get('attributes') diff --git a/tests/components/test_api.py b/tests/components/test_api.py index 2d4842d7290..69b9bfa69de 100644 --- a/tests/components/test_api.py +++ b/tests/components/test_api.py @@ -96,6 +96,23 @@ def test_api_state_change_with_bad_data(hass, mock_api_client): assert resp.status == 400 +# pylint: disable=invalid-name +@asyncio.coroutine +def test_api_state_change_to_zero_value(hass, mock_api_client): + """Test if changing a state to a zero value is possible.""" + resp = yield from mock_api_client.post( + const.URL_API_STATES_ENTITY.format("test_entity.with_zero_state"), + json={'state': 0}) + + assert resp.status == 201 + + resp = yield from mock_api_client.post( + const.URL_API_STATES_ENTITY.format("test_entity.with_zero_state"), + json={'state': 0.}) + + assert resp.status == 200 + + # pylint: disable=invalid-name @asyncio.coroutine def test_api_state_change_push(hass, mock_api_client): From 7977996c0d5f6ddaa39faa5d4d2f9dd43f75fa3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Sandstr=C3=B6m?= Date: Tue, 4 Jul 2017 06:26:55 +0200 Subject: [PATCH 027/131] vsure 1.3.7 (#8321) --- homeassistant/components/verisure.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/verisure.py b/homeassistant/components/verisure.py index 1ec1f9e537d..3ed6efc25d7 100644 --- a/homeassistant/components/verisure.py +++ b/homeassistant/components/verisure.py @@ -18,7 +18,7 @@ from homeassistant.util import Throttle import homeassistant.config as conf_util import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['vsure==1.3.6', 'jsonpath==0.75'] +REQUIREMENTS = ['vsure==1.3.7', 'jsonpath==0.75'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 08efa45a179..32eade5623d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -902,7 +902,7 @@ uvcclient==0.10.0 volvooncall==0.3.3 # homeassistant.components.verisure -vsure==1.3.6 +vsure==1.3.7 # homeassistant.components.sensor.vasttrafik vtjp==0.1.14 From f8527e97733807fc190132b0387cf9fa405d3fe2 Mon Sep 17 00:00:00 2001 From: John Mihalic Date: Tue, 4 Jul 2017 02:02:29 -0400 Subject: [PATCH 028/131] Update pyEmby to fix media images (#8331) --- homeassistant/components/media_player/emby.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/media_player/emby.py b/homeassistant/components/media_player/emby.py index 9f9e9e19dfe..af7bbeed201 100644 --- a/homeassistant/components/media_player/emby.py +++ b/homeassistant/components/media_player/emby.py @@ -21,7 +21,7 @@ from homeassistant.core import callback import homeassistant.helpers.config_validation as cv import homeassistant.util.dt as dt_util -REQUIREMENTS = ['pyemby==1.3'] +REQUIREMENTS = ['pyemby==1.4'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 32eade5623d..d99f128f180 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -549,7 +549,7 @@ pyebox==0.1.0 pyeight==0.0.7 # homeassistant.components.media_player.emby -pyemby==1.3 +pyemby==1.4 # homeassistant.components.envisalink pyenvisalink==2.1 From 8a88af20dae3c69155c1910290e564f9ec3b0d8b Mon Sep 17 00:00:00 2001 From: bergemalm Date: Tue, 4 Jul 2017 10:06:46 +0200 Subject: [PATCH 029/131] Fix arlo sensors. (#8333) --- homeassistant/components/sensor/arlo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/sensor/arlo.py b/homeassistant/components/sensor/arlo.py index e4e0d0330f6..dd36dac7eec 100644 --- a/homeassistant/components/sensor/arlo.py +++ b/homeassistant/components/sensor/arlo.py @@ -11,7 +11,7 @@ import voluptuous as vol from homeassistant.helpers import config_validation as cv from homeassistant.components.arlo import ( - CONF_ATTRIBUTION, DEFAULT_BRAND) + CONF_ATTRIBUTION, DEFAULT_BRAND, DATA_ARLO) from homeassistant.const import ( ATTR_ATTRIBUTION, CONF_MONITORED_CONDITIONS, STATE_UNKNOWN) @@ -40,7 +40,7 @@ SCAN_INTERVAL = timedelta(seconds=90) @asyncio.coroutine def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Set up an Arlo IP sensor.""" - arlo = hass.data.get('arlo') + arlo = hass.data.get(DATA_ARLO) if not arlo: return False From da61b18392d37bf0800280ad90e9a0dded36e006 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 4 Jul 2017 10:07:06 +0200 Subject: [PATCH 030/131] Partially revert #7931 (#8326) --- homeassistant/components/sensor/yweather.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/sensor/yweather.py b/homeassistant/components/sensor/yweather.py index 4919d75e8da..2883a396b77 100644 --- a/homeassistant/components/sensor/yweather.py +++ b/homeassistant/components/sensor/yweather.py @@ -15,6 +15,7 @@ from homeassistant.const import ( TEMP_CELSIUS, CONF_MONITORED_CONDITIONS, CONF_NAME, STATE_UNKNOWN, ATTR_ATTRIBUTION) from homeassistant.helpers.entity import Entity +from homeassistant.util import Throttle REQUIREMENTS = ['yahooweather==0.8'] @@ -26,7 +27,7 @@ CONF_WOEID = 'woeid' DEFAULT_NAME = 'Yweather' -SCAN_INTERVAL = timedelta(minutes=10) +MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=10) SENSOR_TYPES = { 'weather_current': ['Current', None], @@ -181,6 +182,7 @@ class YahooWeatherData(object): """Return Yahoo! API object.""" return self._yahoo + @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): """Get the latest data from Yahoo!.""" return self._yahoo.updateWeather() From 85ac50cc7753ee15b92ff362d6b43114276825e3 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 4 Jul 2017 13:40:38 +0200 Subject: [PATCH 031/131] Only allow 'tls_insecure_set()' if cert is present (fixes #8329) --- homeassistant/components/mqtt/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 6be47581a50..90c89b3193d 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -452,8 +452,8 @@ class MQTT(object): certificate, certfile=client_cert, keyfile=client_key, tls_version=tls_version) - if tls_insecure is not None: - self._mqttc.tls_insecure_set(tls_insecure) + if tls_insecure is not None: + self._mqttc.tls_insecure_set(tls_insecure) self._mqttc.on_subscribe = self._mqtt_on_subscribe self._mqttc.on_unsubscribe = self._mqtt_on_unsubscribe From 2e17d0926a52d3e57a7dc8cc5bffca1af8e35561 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 4 Jul 2017 13:46:38 +0200 Subject: [PATCH 032/131] Revert "Only allow 'tls_insecure_set()' if cert is present (fixes #8329)" This reverts commit 85ac50cc7753ee15b92ff362d6b43114276825e3. --- homeassistant/components/mqtt/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 90c89b3193d..6be47581a50 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -452,8 +452,8 @@ class MQTT(object): certificate, certfile=client_cert, keyfile=client_key, tls_version=tls_version) - if tls_insecure is not None: - self._mqttc.tls_insecure_set(tls_insecure) + if tls_insecure is not None: + self._mqttc.tls_insecure_set(tls_insecure) self._mqttc.on_subscribe = self._mqtt_on_subscribe self._mqttc.on_unsubscribe = self._mqtt_on_unsubscribe From 3363b88a73fedc965504524e6cb442e78da22531 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 4 Jul 2017 15:22:05 +0200 Subject: [PATCH 033/131] Only allow 'tls_insecure_set()' if cert is present (fixes #8329) (#8337) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an optional extended description… --- homeassistant/components/mqtt/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 6be47581a50..90c89b3193d 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -452,8 +452,8 @@ class MQTT(object): certificate, certfile=client_cert, keyfile=client_key, tls_version=tls_version) - if tls_insecure is not None: - self._mqttc.tls_insecure_set(tls_insecure) + if tls_insecure is not None: + self._mqttc.tls_insecure_set(tls_insecure) self._mqttc.on_subscribe = self._mqtt_on_subscribe self._mqttc.on_unsubscribe = self._mqtt_on_unsubscribe From 6496c38ce65bbef44586d98e88f93013b91f2cd9 Mon Sep 17 00:00:00 2001 From: Sabesto Date: Tue, 4 Jul 2017 17:01:35 +0200 Subject: [PATCH 034/131] Fix issue #8285 (#8340) * Fixed a bug where changing fan speed was not possible * Bump pymodbus version to 1.3.1 to fix issue #8285 * Changed all modbus components so that they use CONF_SLAVE from const.py --- homeassistant/components/binary_sensor/modbus.py | 3 +-- homeassistant/components/climate/flexit.py | 2 +- homeassistant/components/modbus.py | 2 +- homeassistant/components/sensor/modbus.py | 3 +-- homeassistant/components/switch/modbus.py | 3 +-- requirements_all.txt | 2 +- 6 files changed, 6 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/binary_sensor/modbus.py b/homeassistant/components/binary_sensor/modbus.py index 3a9b57ba6de..fb6f84c318d 100644 --- a/homeassistant/components/binary_sensor/modbus.py +++ b/homeassistant/components/binary_sensor/modbus.py @@ -8,7 +8,7 @@ import logging import voluptuous as vol import homeassistant.components.modbus as modbus -from homeassistant.const import CONF_NAME +from homeassistant.const import CONF_NAME, CONF_SLAVE from homeassistant.components.binary_sensor import BinarySensorDevice from homeassistant.helpers import config_validation as cv from homeassistant.components.sensor import PLATFORM_SCHEMA @@ -18,7 +18,6 @@ DEPENDENCIES = ['modbus'] CONF_COIL = 'coil' CONF_COILS = 'coils' -CONF_SLAVE = 'slave' PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_COILS): [{ diff --git a/homeassistant/components/climate/flexit.py b/homeassistant/components/climate/flexit.py index 5911486c761..c3ba2224b06 100644 --- a/homeassistant/components/climate/flexit.py +++ b/homeassistant/components/climate/flexit.py @@ -145,4 +145,4 @@ class Flexit(ClimateDevice): def set_fan_mode(self, fan): """Set new fan mode.""" - self.unit.set_fan_speed(fan) + self.unit.set_fan_speed(self._fan_list.index(fan)) diff --git a/homeassistant/components/modbus.py b/homeassistant/components/modbus.py index 0315682bae0..aa958715a48 100644 --- a/homeassistant/components/modbus.py +++ b/homeassistant/components/modbus.py @@ -16,7 +16,7 @@ from homeassistant.const import ( DOMAIN = 'modbus' -REQUIREMENTS = ['pymodbus==1.3.0rc1'] +REQUIREMENTS = ['pymodbus==1.3.1'] # Type of network CONF_BAUDRATE = 'baudrate' diff --git a/homeassistant/components/sensor/modbus.py b/homeassistant/components/sensor/modbus.py index 3ee59e5ae54..d8a5be9ab49 100644 --- a/homeassistant/components/sensor/modbus.py +++ b/homeassistant/components/sensor/modbus.py @@ -11,7 +11,7 @@ import voluptuous as vol import homeassistant.components.modbus as modbus from homeassistant.const import ( - CONF_NAME, CONF_OFFSET, CONF_UNIT_OF_MEASUREMENT) + CONF_NAME, CONF_OFFSET, CONF_UNIT_OF_MEASUREMENT, CONF_SLAVE) from homeassistant.helpers.entity import Entity from homeassistant.helpers import config_validation as cv from homeassistant.components.sensor import PLATFORM_SCHEMA @@ -25,7 +25,6 @@ CONF_PRECISION = 'precision' CONF_REGISTER = 'register' CONF_REGISTERS = 'registers' CONF_SCALE = 'scale' -CONF_SLAVE = 'slave' CONF_DATA_TYPE = 'data_type' CONF_REGISTER_TYPE = 'register_type' diff --git a/homeassistant/components/switch/modbus.py b/homeassistant/components/switch/modbus.py index 93406c869d4..95168d5b830 100644 --- a/homeassistant/components/switch/modbus.py +++ b/homeassistant/components/switch/modbus.py @@ -8,7 +8,7 @@ import logging import voluptuous as vol import homeassistant.components.modbus as modbus -from homeassistant.const import CONF_NAME +from homeassistant.const import CONF_NAME, CONF_SLAVE from homeassistant.helpers.entity import ToggleEntity from homeassistant.helpers import config_validation as cv from homeassistant.components.sensor import PLATFORM_SCHEMA @@ -18,7 +18,6 @@ DEPENDENCIES = ['modbus'] CONF_COIL = "coil" CONF_COILS = "coils" -CONF_SLAVE = "slave" PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_COILS): [{ diff --git a/requirements_all.txt b/requirements_all.txt index d99f128f180..bd8197fba2c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -619,7 +619,7 @@ pymailgunner==1.4 pymochad==0.1.1 # homeassistant.components.modbus -pymodbus==1.3.0rc1 +pymodbus==1.3.1 # homeassistant.components.cover.myq pymyq==0.0.8 From 23fc5e2c9f95b3539fc191d8382b84f8c8561f76 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 4 Jul 2017 23:07:53 +0200 Subject: [PATCH 035/131] Bump dlib face_recognition to 0.2.0 (#8345) * Update dlib_face_detect.py * Update dlib_face_identify.py * Update requirements_all.txt --- homeassistant/components/image_processing/dlib_face_detect.py | 2 +- homeassistant/components/image_processing/dlib_face_identify.py | 2 +- requirements_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/image_processing/dlib_face_detect.py b/homeassistant/components/image_processing/dlib_face_detect.py index 3308edf53b5..7c0c0e26649 100644 --- a/homeassistant/components/image_processing/dlib_face_detect.py +++ b/homeassistant/components/image_processing/dlib_face_detect.py @@ -15,7 +15,7 @@ from homeassistant.components.image_processing import ( from homeassistant.components.image_processing.microsoft_face_identify import ( ImageProcessingFaceEntity) -REQUIREMENTS = ['face_recognition==0.1.14'] +REQUIREMENTS = ['face_recognition==0.2.0'] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/image_processing/dlib_face_identify.py b/homeassistant/components/image_processing/dlib_face_identify.py index 8baa7ac7ec3..0930e42ba7d 100644 --- a/homeassistant/components/image_processing/dlib_face_identify.py +++ b/homeassistant/components/image_processing/dlib_face_identify.py @@ -16,7 +16,7 @@ from homeassistant.components.image_processing.microsoft_face_identify import ( ImageProcessingFaceEntity) import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['face_recognition==0.1.14'] +REQUIREMENTS = ['face_recognition==0.2.0'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index bd8197fba2c..fe0cea803da 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -191,7 +191,7 @@ evohomeclient==0.2.5 # homeassistant.components.image_processing.dlib_face_detect # homeassistant.components.image_processing.dlib_face_identify -# face_recognition==0.1.14 +# face_recognition==0.2.0 # homeassistant.components.sensor.fastdotcom fastdotcom==0.0.1 From 061a38cc3b09a4ca72e5b1bb4af306b611ef1d25 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 4 Jul 2017 15:39:51 -0700 Subject: [PATCH 036/131] Update Avion and Decora switches to match upstream changes (#7903) The upstream Avion and Decora code has changed to punt retry logic out to consumers, so update to match. As a bonus, Avion also gains support for pulling switch configuration off the web rather than requiring manual configuration. --- homeassistant/components/light/avion.py | 52 ++++++++++++++--- homeassistant/components/light/decora.py | 72 +++++++++++++++++++----- requirements_all.txt | 2 +- 3 files changed, 101 insertions(+), 25 deletions(-) diff --git a/homeassistant/components/light/avion.py b/homeassistant/components/light/avion.py index 9b717c64c86..100ad860faa 100644 --- a/homeassistant/components/light/avion.py +++ b/homeassistant/components/light/avion.py @@ -5,16 +5,23 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/light.avion/ """ import logging +import time import voluptuous as vol -from homeassistant.const import CONF_API_KEY, CONF_DEVICES, CONF_NAME +from homeassistant.const import CONF_API_KEY, CONF_DEVICES, CONF_NAME, \ + CONF_USERNAME, CONF_PASSWORD + from homeassistant.components.light import ( ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, Light, PLATFORM_SCHEMA) import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['avion==0.6'] +# pylint: disable=import-error + +AVION_EXCEPTION = None + +REQUIREMENTS = ['avion==0.7'] _LOGGER = logging.getLogger(__name__) @@ -27,20 +34,40 @@ DEVICE_SCHEMA = vol.Schema({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_DEVICES, default={}): {cv.string: DEVICE_SCHEMA}, + vol.Optional(CONF_USERNAME): cv.string, + vol.Optional(CONF_PASSWORD): cv.string, }) def setup_platform(hass, config, add_devices, discovery_info=None): """Set up an Avion switch.""" + global AVION_EXCEPTION + + import avion + + AVION_EXCEPTION = avion.avionException + lights = [] + if CONF_USERNAME in config and CONF_PASSWORD in config: + data = avion.avion_info(config[CONF_USERNAME], config[CONF_PASSWORD]) + for location in data['locations']: + for avion_device in location['location']['devices']: + device = {} + mac = avion_device['device']['mac_address'] + device['name'] = avion_device['device']['name'] + device['key'] = location['location']['passphrase'] + device['address'] = '%s%s:%s%s:%s%s:%s%s:%s%s:%s%s' % \ + (mac[8], mac[9], mac[10], mac[11], mac[4], + mac[5], mac[6], mac[7], mac[0], mac[1], + mac[2], mac[3]) + lights.append(AvionLight(device)) + for address, device_config in config[CONF_DEVICES].items(): device = {} device['name'] = device_config[CONF_NAME] device['key'] = device_config[CONF_API_KEY] device['address'] = address - light = AvionLight(device) - if light.is_valid: - lights.append(light) + lights.append(AvionLight(device)) add_devices(lights) @@ -50,7 +77,6 @@ class AvionLight(Light): def __init__(self, device): """Initialize the light.""" - # pylint: disable=import-error import avion self._name = device['name'] @@ -59,8 +85,6 @@ class AvionLight(Light): self._brightness = 255 self._state = False self._switch = avion.avion(self._address, self._key) - self._switch.connect() - self.is_valid = True @property def unique_id(self): @@ -99,7 +123,17 @@ class AvionLight(Light): def set_state(self, brightness): """Set the state of this lamp to the provided brightness.""" - self._switch.set_brightness(brightness) + # Bluetooth LE is unreliable, and the connection may drop at any + # time. Make an effort to re-establish the link. + initial = time.monotonic() + while True: + if time.monotonic() - initial >= 10: + return False + try: + self._switch.set_brightness(brightness) + break + except AVION_EXCEPTION: + self._switch.connect() return True def turn_on(self, **kwargs): diff --git a/homeassistant/components/light/decora.py b/homeassistant/components/light/decora.py index c653f4b1ed4..26c7368b648 100644 --- a/homeassistant/components/light/decora.py +++ b/homeassistant/components/light/decora.py @@ -5,6 +5,7 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/light.decora/ """ import logging +import time import voluptuous as vol @@ -14,6 +15,10 @@ from homeassistant.components.light import ( PLATFORM_SCHEMA) import homeassistant.helpers.config_validation as cv +# pylint: disable=import-error + +DECORA_EXCEPTION = None + REQUIREMENTS = ['decora==0.6'] _LOGGER = logging.getLogger(__name__) @@ -32,6 +37,12 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ def setup_platform(hass, config, add_devices, discovery_info=None): """Set up an Decora switch.""" + global DECORA_EXCEPTION + + import decora + + DECORA_EXCEPTION = decora.decoraException + lights = [] for address, device_config in config[CONF_DEVICES].items(): device = {} @@ -39,8 +50,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): device['key'] = device_config[CONF_API_KEY] device['address'] = address light = DecoraLight(device) - if light.is_valid: - lights.append(light) + lights.append(light) add_devices(lights) @@ -50,17 +60,14 @@ class DecoraLight(Light): def __init__(self, device): """Initialize the light.""" - # pylint: disable=import-error import decora self._name = device['name'] self._address = device['address'] self._key = device["key"] self._switch = decora.decora(self._address, self._key) - self._switch.connect() - self._state = self._switch.get_on() - self._brightness = self._switch.get_brightness() * 2.55 - self.is_valid = True + self._brightness = 0 + self._state = False @property def unique_id(self): @@ -75,11 +82,13 @@ class DecoraLight(Light): @property def is_on(self): """Return true if device is on.""" + self.update() return self._state @property def brightness(self): """Return the brightness of this light between 0..255.""" + self.update() return self._brightness @property @@ -99,7 +108,16 @@ class DecoraLight(Light): def set_state(self, brightness): """Set the state of this lamp to the provided brightness.""" - self._switch.set_brightness(int(brightness / 2.55)) + initial = time.monotonic() + while True: + if time.monotonic() - initial >= 10: + return None + try: + self._switch.set_brightness(brightness / 2.55) + break + except (DECORA_EXCEPTION, AttributeError): + self._switch.connect() + self._brightness = brightness return True @@ -107,18 +125,42 @@ class DecoraLight(Light): """Turn the specified or all lights on.""" brightness = kwargs.get(ATTR_BRIGHTNESS) - self._switch.on() + initial = time.monotonic() + while True: + if time.monotonic() - initial >= 10: + return None + try: + self._switch.on() + self._state = True + break + except (DECORA_EXCEPTION, AttributeError): + self._switch.connect() + if brightness is not None: self.set_state(brightness) - self._state = True - def turn_off(self, **kwargs): """Turn the specified or all lights off.""" - self._switch.off() - self._state = False + initial = time.monotonic() + while True: + if time.monotonic() - initial >= 10: + return None + try: + self._switch.off() + self._state = False + break + except (DECORA_EXCEPTION, AttributeError): + self._switch.connect() def update(self): """Synchronise internal state with the actual light state.""" - self._brightness = self._switch.get_brightness() * 2.55 - self._state = self._switch.get_on() + initial = time.monotonic() + while True: + if time.monotonic() - initial >= 10: + return None + try: + self._brightness = self._switch.get_brightness() * 2.55 + self._state = self._switch.get_on() + break + except (DECORA_EXCEPTION, AttributeError): + self._switch.connect() diff --git a/requirements_all.txt b/requirements_all.txt index fe0cea803da..fc71a3ab3ff 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -74,7 +74,7 @@ apcaccess==0.0.13 apns2==0.1.1 # homeassistant.components.light.avion -# avion==0.6 +# avion==0.7 # homeassistant.components.axis axis==8 From 8185587100d6e6f10701998c9f253254ac8f7e5c Mon Sep 17 00:00:00 2001 From: Flavien Charlon Date: Wed, 5 Jul 2017 05:06:24 +0100 Subject: [PATCH 037/131] Fix the "302" error in the UPC Connect component and remove the need to specify the router password (#8335) * Remove the need to login on the UPC Connect component * Remove unnecessary imports * Update the unit tests for the UPC Connect component * Fix the "302" error with the UPC Connect component * Fix a flake8 error * Update the unit tests for the UPC Connect component --- .../components/device_tracker/upc_connect.py | 57 +++-------- .../device_tracker/test_upc_connect.py | 94 ++++--------------- 2 files changed, 35 insertions(+), 116 deletions(-) diff --git a/homeassistant/components/device_tracker/upc_connect.py b/homeassistant/components/device_tracker/upc_connect.py index ace7c4455a9..a6646c8d0a1 100644 --- a/homeassistant/components/device_tracker/upc_connect.py +++ b/homeassistant/components/device_tracker/upc_connect.py @@ -12,11 +12,10 @@ import aiohttp import async_timeout import voluptuous as vol -from homeassistant.const import EVENT_HOMEASSISTANT_STOP import homeassistant.helpers.config_validation as cv from homeassistant.components.device_tracker import ( DOMAIN, PLATFORM_SCHEMA, DeviceScanner) -from homeassistant.const import CONF_HOST, CONF_PASSWORD +from homeassistant.const import CONF_HOST from homeassistant.helpers.aiohttp_client import async_get_clientsession @@ -25,12 +24,9 @@ _LOGGER = logging.getLogger(__name__) DEFAULT_IP = '192.168.0.1' PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ - vol.Required(CONF_PASSWORD): cv.string, vol.Optional(CONF_HOST, default=DEFAULT_IP): cv.string, }) -CMD_LOGIN = 15 -CMD_LOGOUT = 16 CMD_DEVICES = 123 @@ -38,7 +34,7 @@ CMD_DEVICES = 123 def async_get_scanner(hass, config): """Return the UPC device scanner.""" scanner = UPCDeviceScanner(hass, config[DOMAIN]) - success_init = yield from scanner.async_login() + success_init = yield from scanner.async_initialize_token() return scanner if success_init else None @@ -50,7 +46,6 @@ class UPCDeviceScanner(DeviceScanner): """Initialize the scanner.""" self.hass = hass self.host = config[CONF_HOST] - self.password = config[CONF_PASSWORD] self.data = {} self.token = None @@ -65,21 +60,12 @@ class UPCDeviceScanner(DeviceScanner): self.websession = async_get_clientsession(hass) - @asyncio.coroutine - def async_logout(event): - """Logout from upc connect box.""" - yield from self._async_ws_function(CMD_LOGOUT) - self.token = None - - hass.bus.async_listen_once( - EVENT_HOMEASSISTANT_STOP, async_logout) - @asyncio.coroutine def async_scan_devices(self): """Scan for new devices and return a list with found device IDs.""" if self.token is None: - reconnect = yield from self.async_login() - if not reconnect: + token_initialized = yield from self.async_initialize_token() + if not token_initialized: _LOGGER.error("Not connected to %s", self.host) return [] @@ -95,55 +81,42 @@ class UPCDeviceScanner(DeviceScanner): @asyncio.coroutine def async_get_device_name(self, device): - """Ge the firmware doesn't save the name of the wireless device.""" + """The firmware doesn't save the name of the wireless device.""" return None @asyncio.coroutine - def async_login(self): - """Login into firmware and get first token.""" + def async_initialize_token(self): + """Get first token.""" try: # get first token with async_timeout.timeout(10, loop=self.hass.loop): response = yield from self.websession.get( - "http://{}/common_page/login.html".format(self.host) + "http://{}/common_page/login.html".format(self.host), + headers=self.headers ) yield from response.text() self.token = response.cookies['sessionToken'].value - # login - data = yield from self._async_ws_function(CMD_LOGIN, { - 'Username': 'NULL', - 'Password': self.password, - }) - - # Successful? - return data is not None + return True except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.error("Can not load login page from %s", self.host) return False @asyncio.coroutine - def _async_ws_function(self, function, additional_form=None): + def _async_ws_function(self, function): """Execute a command on UPC firmware webservice.""" - form_data = { - 'token': self.token, - 'fun': function - } - - if additional_form: - form_data.update(additional_form) - - redirects = function != CMD_DEVICES try: with async_timeout.timeout(10, loop=self.hass.loop): + # The 'token' parameter has to be first, and 'fun' second + # or the UPC firmware will return an error response = yield from self.websession.post( "http://{}/xml/getter.xml".format(self.host), - data=form_data, + data="token={}&fun={}".format(self.token, function), headers=self.headers, - allow_redirects=redirects + allow_redirects=False ) # error? diff --git a/tests/components/device_tracker/test_upc_connect.py b/tests/components/device_tracker/test_upc_connect.py index dea53b16559..1ef3aefa6a4 100644 --- a/tests/components/device_tracker/test_upc_connect.py +++ b/tests/components/device_tracker/test_upc_connect.py @@ -7,7 +7,7 @@ import logging from homeassistant.setup import setup_component from homeassistant.components import device_tracker from homeassistant.const import ( - CONF_PLATFORM, CONF_HOST, CONF_PASSWORD) + CONF_PLATFORM, CONF_HOST) from homeassistant.components.device_tracker import DOMAIN import homeassistant.components.device_tracker.upc_connect as platform from homeassistant.util.async import run_coroutine_threadsafe @@ -62,43 +62,10 @@ class TestUPCConnect(object): assert setup_component( self.hass, DOMAIN, {DOMAIN: { CONF_PLATFORM: 'upc_connect', - CONF_HOST: self.host, - CONF_PASSWORD: '123456' + CONF_HOST: self.host }}) - assert len(aioclient_mock.mock_calls) == 2 - assert aioclient_mock.mock_calls[1][2]['Password'] == '123456' - assert aioclient_mock.mock_calls[1][2]['fun'] == 15 - assert aioclient_mock.mock_calls[1][2]['token'] == '654321' - - @patch('homeassistant.components.device_tracker._LOGGER.error') - def test_setup_platform_error_webservice(self, mock_error, aioclient_mock): - """Setup a platform with api error.""" - aioclient_mock.get( - "http://{}/common_page/login.html".format(self.host), - cookies={'sessionToken': '654321'} - ) - aioclient_mock.post( - "http://{}/xml/getter.xml".format(self.host), - content=b'successful', - status=404 - ) - - with assert_setup_component(1, DOMAIN): - assert setup_component( - self.hass, DOMAIN, {DOMAIN: { - CONF_PLATFORM: 'upc_connect', - CONF_HOST: self.host, - CONF_PASSWORD: '123456' - }}) - - assert len(aioclient_mock.mock_calls) == 2 - assert aioclient_mock.mock_calls[1][2]['Password'] == '123456' - assert aioclient_mock.mock_calls[1][2]['fun'] == 15 - assert aioclient_mock.mock_calls[1][2]['token'] == '654321' - - assert 'Error setting up platform' in \ - str(mock_error.call_args_list[-1]) + assert len(aioclient_mock.mock_calls) == 1 @patch('homeassistant.components.device_tracker._LOGGER.error') def test_setup_platform_timeout_webservice(self, mock_error, @@ -106,10 +73,7 @@ class TestUPCConnect(object): """Setup a platform with api timeout.""" aioclient_mock.get( "http://{}/common_page/login.html".format(self.host), - cookies={'sessionToken': '654321'} - ) - aioclient_mock.post( - "http://{}/xml/getter.xml".format(self.host), + cookies={'sessionToken': '654321'}, content=b'successful', exc=asyncio.TimeoutError() ) @@ -118,14 +82,10 @@ class TestUPCConnect(object): assert setup_component( self.hass, DOMAIN, {DOMAIN: { CONF_PLATFORM: 'upc_connect', - CONF_HOST: self.host, - CONF_PASSWORD: '123456' + CONF_HOST: self.host }}) - assert len(aioclient_mock.mock_calls) == 2 - assert aioclient_mock.mock_calls[1][2]['Password'] == '123456' - assert aioclient_mock.mock_calls[1][2]['fun'] == 15 - assert aioclient_mock.mock_calls[1][2]['token'] == '654321' + assert len(aioclient_mock.mock_calls) == 1 assert 'Error setting up platform' in \ str(mock_error.call_args_list[-1]) @@ -147,8 +107,7 @@ class TestUPCConnect(object): assert setup_component( self.hass, DOMAIN, {DOMAIN: { CONF_PLATFORM: 'upc_connect', - CONF_HOST: self.host, - CONF_PASSWORD: '123456' + CONF_HOST: self.host }}) assert len(aioclient_mock.mock_calls) == 1 @@ -171,14 +130,11 @@ class TestUPCConnect(object): scanner = run_coroutine_threadsafe(platform.async_get_scanner( self.hass, {DOMAIN: { CONF_PLATFORM: 'upc_connect', - CONF_HOST: self.host, - CONF_PASSWORD: '123456' + CONF_HOST: self.host }} ), self.hass.loop).result() - assert aioclient_mock.mock_calls[1][2]['Password'] == '123456' - assert aioclient_mock.mock_calls[1][2]['fun'] == 15 - assert aioclient_mock.mock_calls[1][2]['token'] == '654321' + assert len(aioclient_mock.mock_calls) == 1 aioclient_mock.clear_requests() aioclient_mock.post( @@ -191,8 +147,7 @@ class TestUPCConnect(object): scanner.async_scan_devices(), self.hass.loop).result() assert len(aioclient_mock.mock_calls) == 1 - assert aioclient_mock.mock_calls[0][2]['fun'] == 123 - assert scanner.token == '1235678' + assert aioclient_mock.mock_calls[0][2] == 'token=654321&fun=123' assert mac_list == ['30:D3:2D:0:69:21', '5C:AA:FD:25:32:02', '70:EE:50:27:A1:38'] @@ -211,14 +166,11 @@ class TestUPCConnect(object): scanner = run_coroutine_threadsafe(platform.async_get_scanner( self.hass, {DOMAIN: { CONF_PLATFORM: 'upc_connect', - CONF_HOST: self.host, - CONF_PASSWORD: '123456' + CONF_HOST: self.host }} ), self.hass.loop).result() - assert aioclient_mock.mock_calls[1][2]['Password'] == '123456' - assert aioclient_mock.mock_calls[1][2]['fun'] == 15 - assert aioclient_mock.mock_calls[1][2]['token'] == '654321' + assert len(aioclient_mock.mock_calls) == 1 aioclient_mock.clear_requests() aioclient_mock.get( @@ -235,8 +187,8 @@ class TestUPCConnect(object): mac_list = run_coroutine_threadsafe( scanner.async_scan_devices(), self.hass.loop).result() - assert len(aioclient_mock.mock_calls) == 3 - assert aioclient_mock.mock_calls[1][2]['fun'] == 15 + assert len(aioclient_mock.mock_calls) == 2 + assert aioclient_mock.mock_calls[1][2] == 'token=654321&fun=123' assert mac_list == ['30:D3:2D:0:69:21', '5C:AA:FD:25:32:02', '70:EE:50:27:A1:38'] @@ -255,14 +207,11 @@ class TestUPCConnect(object): scanner = run_coroutine_threadsafe(platform.async_get_scanner( self.hass, {DOMAIN: { CONF_PLATFORM: 'upc_connect', - CONF_HOST: self.host, - CONF_PASSWORD: '123456' + CONF_HOST: self.host }} ), self.hass.loop).result() - assert aioclient_mock.mock_calls[1][2]['Password'] == '123456' - assert aioclient_mock.mock_calls[1][2]['fun'] == 15 - assert aioclient_mock.mock_calls[1][2]['token'] == '654321' + assert len(aioclient_mock.mock_calls) == 1 aioclient_mock.clear_requests() aioclient_mock.get( @@ -280,7 +229,7 @@ class TestUPCConnect(object): scanner.async_scan_devices(), self.hass.loop).result() assert len(aioclient_mock.mock_calls) == 2 - assert aioclient_mock.mock_calls[1][2]['fun'] == 15 + assert aioclient_mock.mock_calls[1][2] == 'token=654321&fun=123' assert mac_list == [] def test_scan_devices_parse_error(self, aioclient_mock): @@ -298,14 +247,11 @@ class TestUPCConnect(object): scanner = run_coroutine_threadsafe(platform.async_get_scanner( self.hass, {DOMAIN: { CONF_PLATFORM: 'upc_connect', - CONF_HOST: self.host, - CONF_PASSWORD: '123456' + CONF_HOST: self.host }} ), self.hass.loop).result() - assert aioclient_mock.mock_calls[1][2]['Password'] == '123456' - assert aioclient_mock.mock_calls[1][2]['fun'] == 15 - assert aioclient_mock.mock_calls[1][2]['token'] == '654321' + assert len(aioclient_mock.mock_calls) == 1 aioclient_mock.clear_requests() aioclient_mock.post( @@ -318,6 +264,6 @@ class TestUPCConnect(object): scanner.async_scan_devices(), self.hass.loop).result() assert len(aioclient_mock.mock_calls) == 1 - assert aioclient_mock.mock_calls[0][2]['fun'] == 123 + assert aioclient_mock.mock_calls[0][2] == 'token=654321&fun=123' assert scanner.token is None assert mac_list == [] From ea5bec3ef46557797b389dff6335bef79eaa3cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre=20St=C3=A5hl?= Date: Wed, 5 Jul 2017 06:37:18 +0200 Subject: [PATCH 038/131] Add new feature to Apple TV platform (#8122) * Lift Apple TV to pyatv 0.3.2 Update code to use basic new features. * Support button presses in Apple TV * Support device authentication * Convert Apple TV to a component A media_player platform and a remote platform will be loaded for each manually configured or discovered device. * Move device auth to apple_tv component * Update requirements and coverage config * Add scan support to apple_tv --- .coveragerc | 4 +- homeassistant/components/apple_tv.py | 259 ++++++++++++++++++ homeassistant/components/discovery.py | 3 +- .../components/media_player/apple_tv.py | 154 ++++------- homeassistant/components/remote/apple_tv.py | 87 ++++++ homeassistant/components/services.yaml | 13 + requirements_all.txt | 4 +- 7 files changed, 422 insertions(+), 102 deletions(-) create mode 100644 homeassistant/components/apple_tv.py create mode 100644 homeassistant/components/remote/apple_tv.py diff --git a/.coveragerc b/.coveragerc index c74de0026b1..9f538911a6e 100644 --- a/.coveragerc +++ b/.coveragerc @@ -14,6 +14,9 @@ omit = homeassistant/components/apcupsd.py homeassistant/components/*/apcupsd.py + homeassistant/components/apple_tv.py + homeassistant/components/*/apple_tv.py + homeassistant/components/arduino.py homeassistant/components/*/arduino.py @@ -302,7 +305,6 @@ omit = homeassistant/components/lock/lockitron.py homeassistant/components/lock/sesame.py homeassistant/components/media_player/anthemav.py - homeassistant/components/media_player/apple_tv.py homeassistant/components/media_player/aquostv.py homeassistant/components/media_player/braviatv.py homeassistant/components/media_player/cast.py diff --git a/homeassistant/components/apple_tv.py b/homeassistant/components/apple_tv.py new file mode 100644 index 00000000000..17cc46f3318 --- /dev/null +++ b/homeassistant/components/apple_tv.py @@ -0,0 +1,259 @@ +""" +Support for Apple TV. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/apple_tv/ +""" +import os +import asyncio +import logging + +import voluptuous as vol + +from homeassistant.const import (CONF_HOST, CONF_NAME, ATTR_ENTITY_ID) +from homeassistant.config import load_yaml_config_file +from homeassistant.helpers.aiohttp_client import async_get_clientsession +from homeassistant.helpers import discovery +from homeassistant.components.discovery import SERVICE_APPLE_TV +from homeassistant.loader import get_component +import homeassistant.helpers.config_validation as cv + +REQUIREMENTS = ['pyatv==0.3.2'] + +_LOGGER = logging.getLogger(__name__) + +DOMAIN = 'apple_tv' + +SERVICE_SCAN = 'apple_tv_scan' +SERVICE_AUTHENTICATE = 'apple_tv_authenticate' + +ATTR_ATV = 'atv' +ATTR_POWER = 'power' + +CONF_LOGIN_ID = 'login_id' +CONF_START_OFF = 'start_off' +CONF_CREDENTIALS = 'credentials' + +DEFAULT_NAME = 'Apple TV' + +DATA_APPLE_TV = 'data_apple_tv' +DATA_ENTITIES = 'data_apple_tv_entities' + +KEY_CONFIG = 'apple_tv_configuring' + +NOTIFICATION_AUTH_ID = 'apple_tv_auth_notification' +NOTIFICATION_AUTH_TITLE = 'Apple TV Authentication' +NOTIFICATION_SCAN_ID = 'apple_tv_scan_notification' +NOTIFICATION_SCAN_TITLE = 'Apple TV Scan' + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.All(cv.ensure_list, [vol.Schema({ + vol.Required(CONF_HOST): cv.string, + vol.Required(CONF_LOGIN_ID): cv.string, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_CREDENTIALS, default=None): cv.string, + vol.Optional(CONF_START_OFF, default=False): cv.boolean + })]) +}, extra=vol.ALLOW_EXTRA) + +# Currently no attributes but it might change later +APPLE_TV_SCAN_SCHEMA = vol.Schema({}) + +APPLE_TV_AUTHENTICATE_SCHEMA = vol.Schema({ + ATTR_ENTITY_ID: cv.entity_ids, +}) + + +def request_configuration(hass, config, atv, credentials): + """Request configuration steps from the user.""" + configurator = get_component('configurator') + + @asyncio.coroutine + def configuration_callback(callback_data): + """Handle the submitted configuration.""" + from pyatv import exceptions + pin = callback_data.get('pin') + notification = get_component('persistent_notification') + + try: + yield from atv.airplay.finish_authentication(pin) + notification.async_create( + hass, + 'Authentication succeeded!

Add the following ' + 'to credentials: in your apple_tv configuration:

' + '{0}'.format(credentials), + title=NOTIFICATION_AUTH_TITLE, + notification_id=NOTIFICATION_AUTH_ID) + except exceptions.DeviceAuthenticationError as ex: + notification.async_create( + hass, + 'Authentication failed! Did you enter correct PIN?

' + 'Details: {0}'.format(ex), + title=NOTIFICATION_AUTH_TITLE, + notification_id=NOTIFICATION_AUTH_ID) + + hass.async_add_job(configurator.request_done, instance) + + instance = configurator.request_config( + hass, 'Apple TV Authentication', configuration_callback, + description='Please enter PIN code shown on screen.', + submit_caption='Confirm', + fields=[{'id': 'pin', 'name': 'PIN Code', 'type': 'password'}] + ) + + +@asyncio.coroutine +def scan_for_apple_tvs(hass): + """Scan for devices and present a notification of the ones found.""" + import pyatv + atvs = yield from pyatv.scan_for_apple_tvs(hass.loop, timeout=3) + + devices = [] + for atv in atvs: + login_id = atv.login_id + if login_id is None: + login_id = 'Home Sharing disabled' + devices.append('Name: {0}
Host: {1}
Login ID: {2}'.format( + atv.name, atv.address, login_id)) + + if not devices: + devices = ['No device(s) found'] + + notification = get_component('persistent_notification') + notification.async_create( + hass, + 'The following devices were found:

' + + '

'.join(devices), + title=NOTIFICATION_SCAN_TITLE, + notification_id=NOTIFICATION_SCAN_ID) + + +@asyncio.coroutine +def async_setup(hass, config): + """Set up the Apple TV component.""" + if DATA_APPLE_TV not in hass.data: + hass.data[DATA_APPLE_TV] = {} + + @asyncio.coroutine + def async_service_handler(service): + """Handler for service calls.""" + entity_ids = service.data.get(ATTR_ENTITY_ID) + + if entity_ids: + devices = [device for device in hass.data[DATA_ENTITIES] + if device.entity_id in entity_ids] + else: + devices = hass.data[DATA_ENTITIES] + + for device in devices: + atv = device.atv + if service.service == SERVICE_AUTHENTICATE: + credentials = yield from atv.airplay.generate_credentials() + yield from atv.airplay.load_credentials(credentials) + _LOGGER.debug('Generated new credentials: %s', credentials) + yield from atv.airplay.start_authentication() + hass.async_add_job(request_configuration, + hass, config, atv, credentials) + elif service.service == SERVICE_SCAN: + hass.async_add_job(scan_for_apple_tvs, hass) + + @asyncio.coroutine + def atv_discovered(service, info): + """Setup an Apple TV that was auto discovered.""" + yield from _setup_atv(hass, { + CONF_NAME: info['name'], + CONF_HOST: info['host'], + CONF_LOGIN_ID: info['properties']['hG'], + CONF_START_OFF: False + }) + + discovery.async_listen(hass, SERVICE_APPLE_TV, atv_discovered) + + tasks = [_setup_atv(hass, conf) for conf in config.get(DOMAIN, [])] + if tasks: + yield from asyncio.wait(tasks, loop=hass.loop) + + descriptions = yield from hass.async_add_job( + load_yaml_config_file, os.path.join( + os.path.dirname(__file__), 'services.yaml')) + + hass.services.async_register( + DOMAIN, SERVICE_SCAN, async_service_handler, + descriptions.get(SERVICE_SCAN), + schema=APPLE_TV_SCAN_SCHEMA) + + hass.services.async_register( + DOMAIN, SERVICE_AUTHENTICATE, async_service_handler, + descriptions.get(SERVICE_AUTHENTICATE), + schema=APPLE_TV_AUTHENTICATE_SCHEMA) + + return True + + +@asyncio.coroutine +def _setup_atv(hass, atv_config): + """Setup an Apple TV.""" + import pyatv + name = atv_config.get(CONF_NAME) + host = atv_config.get(CONF_HOST) + login_id = atv_config.get(CONF_LOGIN_ID) + start_off = atv_config.get(CONF_START_OFF) + credentials = atv_config.get(CONF_CREDENTIALS) + + if host in hass.data[DATA_APPLE_TV]: + return + + details = pyatv.AppleTVDevice(name, host, login_id) + session = async_get_clientsession(hass) + atv = pyatv.connect_to_apple_tv(details, hass.loop, session=session) + if credentials: + yield from atv.airplay.load_credentials(credentials) + + power = AppleTVPowerManager(hass, atv, start_off) + hass.data[DATA_APPLE_TV][host] = { + ATTR_ATV: atv, + ATTR_POWER: power + } + + hass.async_add_job(discovery.async_load_platform( + hass, 'media_player', DOMAIN, atv_config)) + + hass.async_add_job(discovery.async_load_platform( + hass, 'remote', DOMAIN, atv_config)) + + +class AppleTVPowerManager: + """Manager for global power management of an Apple TV. + + An instance is used per device to share the same power state between + several platforms. + """ + + def __init__(self, hass, atv, is_off): + """Initialize power manager.""" + self.hass = hass + self.atv = atv + self.listeners = [] + self._is_on = not is_off + + def init(self): + """Initialize power management.""" + if self._is_on: + self.atv.push_updater.start() + + @property + def turned_on(self): + """If device is on or off.""" + return self._is_on + + def set_power_on(self, value): + """Change if a device is on or off.""" + if value != self._is_on: + self._is_on = value + if not self._is_on: + self.atv.push_updater.stop() + else: + self.atv.push_updater.start() + + for listener in self.listeners: + self.hass.async_add_job(listener.async_update_ha_state()) diff --git a/homeassistant/components/discovery.py b/homeassistant/components/discovery.py index fc239bf70c5..3dfe4b9731c 100644 --- a/homeassistant/components/discovery.py +++ b/homeassistant/components/discovery.py @@ -32,6 +32,7 @@ SERVICE_HASS_IOS_APP = 'hass_ios' SERVICE_IKEA_TRADFRI = 'ikea_tradfri' SERVICE_HASSIO = 'hassio' SERVICE_AXIS = 'axis' +SERVICE_APPLE_TV = 'apple_tv' SERVICE_HANDLERS = { SERVICE_HASS_IOS_APP: ('ios', None), @@ -40,6 +41,7 @@ SERVICE_HANDLERS = { SERVICE_IKEA_TRADFRI: ('tradfri', None), SERVICE_HASSIO: ('hassio', None), SERVICE_AXIS: ('axis', None), + SERVICE_APPLE_TV: ('apple_tv', None), 'philips_hue': ('light', 'hue'), 'google_cast': ('media_player', 'cast'), 'panasonic_viera': ('media_player', 'panasonic_viera'), @@ -52,7 +54,6 @@ SERVICE_HANDLERS = { 'denonavr': ('media_player', 'denonavr'), 'samsung_tv': ('media_player', 'samsungtv'), 'yeelight': ('light', 'yeelight'), - 'apple_tv': ('media_player', 'apple_tv'), 'frontier_silicon': ('media_player', 'frontier_silicon'), 'openhome': ('media_player', 'openhome'), 'harmony': ('remote', 'harmony'), diff --git a/homeassistant/components/media_player/apple_tv.py b/homeassistant/components/media_player/apple_tv.py index 97114a6bc84..a7017f73fc4 100644 --- a/homeassistant/components/media_player/apple_tv.py +++ b/homeassistant/components/media_player/apple_tv.py @@ -6,70 +6,41 @@ https://home-assistant.io/components/media_player.apple_tv/ """ import asyncio import logging -import hashlib - -import voluptuous as vol from homeassistant.core import callback +from homeassistant.components.apple_tv import ( + ATTR_ATV, ATTR_POWER, DATA_APPLE_TV, DATA_ENTITIES) from homeassistant.components.media_player import ( SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK, SUPPORT_STOP, SUPPORT_PLAY, SUPPORT_PLAY_MEDIA, SUPPORT_TURN_ON, - SUPPORT_TURN_OFF, MediaPlayerDevice, PLATFORM_SCHEMA, MEDIA_TYPE_MUSIC, + SUPPORT_TURN_OFF, MediaPlayerDevice, MEDIA_TYPE_MUSIC, MEDIA_TYPE_VIDEO, MEDIA_TYPE_TVSHOW) from homeassistant.const import ( STATE_IDLE, STATE_PAUSED, STATE_PLAYING, STATE_STANDBY, CONF_HOST, STATE_OFF, CONF_NAME, EVENT_HOMEASSISTANT_STOP) -from homeassistant.helpers.aiohttp_client import async_get_clientsession -import homeassistant.helpers.config_validation as cv import homeassistant.util.dt as dt_util -REQUIREMENTS = ['pyatv==0.2.1'] +DEPENDENCIES = ['apple_tv'] _LOGGER = logging.getLogger(__name__) -CONF_LOGIN_ID = 'login_id' -CONF_START_OFF = 'start_off' - -DEFAULT_NAME = 'Apple TV' - -DATA_APPLE_TV = 'apple_tv' - -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ - vol.Required(CONF_HOST): cv.string, - vol.Required(CONF_LOGIN_ID): cv.string, - vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, - vol.Optional(CONF_START_OFF, default=False): cv.boolean -}) - @asyncio.coroutine def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Set up the Apple TV platform.""" - import pyatv + if not discovery_info: + return - if discovery_info is not None: - name = discovery_info['name'] - host = discovery_info['host'] - login_id = discovery_info['properties']['hG'] - start_off = False - else: - name = config.get(CONF_NAME) - host = config.get(CONF_HOST) - login_id = config.get(CONF_LOGIN_ID) - start_off = config.get(CONF_START_OFF) + # Manage entity cache for service handler + if DATA_ENTITIES not in hass.data: + hass.data[DATA_ENTITIES] = [] - if DATA_APPLE_TV not in hass.data: - hass.data[DATA_APPLE_TV] = [] - - if host in hass.data[DATA_APPLE_TV]: - return False - hass.data[DATA_APPLE_TV].append(host) - - details = pyatv.AppleTVDevice(name, host, login_id) - session = async_get_clientsession(hass) - atv = pyatv.connect_to_apple_tv(details, hass.loop, session=session) - entity = AppleTvDevice(atv, name, start_off) + name = discovery_info[CONF_NAME] + host = discovery_info[CONF_HOST] + atv = hass.data[DATA_APPLE_TV][host][ATTR_ATV] + power = hass.data[DATA_APPLE_TV][host][ATTR_POWER] + entity = AppleTvDevice(atv, name, power) @callback def on_hass_stop(event): @@ -78,44 +49,39 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, on_hass_stop) + if entity not in hass.data[DATA_ENTITIES]: + hass.data[DATA_ENTITIES].append(entity) + async_add_devices([entity]) class AppleTvDevice(MediaPlayerDevice): """Representation of an Apple TV device.""" - def __init__(self, atv, name, is_off): + def __init__(self, atv, name, power): """Initialize the Apple TV device.""" - self._atv = atv + self.atv = atv self._name = name - self._is_off = is_off self._playing = None - self._artwork_hash = None - self._atv.push_updater.listener = self + self._power = power + self._power.listeners.append(self) + self.atv.push_updater.listener = self @asyncio.coroutine def async_added_to_hass(self): """Handle when an entity is about to be added to Home Assistant.""" - if not self._is_off: - self._atv.push_updater.start() - - @callback - def _set_power_off(self, is_off): - """Set the power to off.""" - self._playing = None - self._artwork_hash = None - self._is_off = is_off - if is_off: - self._atv.push_updater.stop() - else: - self._atv.push_updater.start() - self.hass.async_add_job(self.async_update_ha_state()) + self._power.init() @property def name(self): """Return the name of the device.""" return self._name + @property + def unique_id(self): + """Return an unique ID.""" + return self.atv.metadata.device_id + @property def should_poll(self): """No polling needed.""" @@ -124,16 +90,16 @@ class AppleTvDevice(MediaPlayerDevice): @property def state(self): """Return the state of the device.""" - if self._is_off: + if not self._power.turned_on: return STATE_OFF if self._playing is not None: from pyatv import const state = self._playing.play_state - if state == const.PLAY_STATE_NO_MEDIA: - return STATE_IDLE - elif state == const.PLAY_STATE_PLAYING or \ + if state == const.PLAY_STATE_NO_MEDIA or \ state == const.PLAY_STATE_LOADING: + return STATE_IDLE + elif state == const.PLAY_STATE_PLAYING: return STATE_PLAYING elif state == const.PLAY_STATE_PAUSED or \ state == const.PLAY_STATE_FAST_FORWARD or \ @@ -147,24 +113,8 @@ class AppleTvDevice(MediaPlayerDevice): def playstatus_update(self, updater, playing): """Print what is currently playing when it changes.""" self._playing = playing - - if self.state == STATE_IDLE: - self._artwork_hash = None - elif self._has_playing_media_changed(playing): - base = str(playing.title) + str(playing.artist) + \ - str(playing.album) + str(playing.total_time) - self._artwork_hash = hashlib.md5( - base.encode('utf-8')).hexdigest() - self.hass.async_add_job(self.async_update_ha_state()) - def _has_playing_media_changed(self, new_playing): - if self._playing is None: - return True - old_playing = self._playing - return new_playing.media_type != old_playing.media_type or \ - new_playing.title != old_playing.title - @callback def playstatus_error(self, updater, exception): """Inform about an error and restart push updates.""" @@ -177,7 +127,6 @@ class AppleTvDevice(MediaPlayerDevice): # implemented here later. updater.start(initial_delay=10) self._playing = None - self._artwork_hash = None self.hass.async_add_job(self.async_update_ha_state()) @property @@ -215,18 +164,18 @@ class AppleTvDevice(MediaPlayerDevice): @asyncio.coroutine def async_play_media(self, media_type, media_id, **kwargs): """Send the play_media command to the media player.""" - yield from self._atv.remote_control.play_url(media_id, 0) + yield from self.atv.airplay.play_url(media_id) @property def media_image_hash(self): """Hash value for media image.""" - if self.state != STATE_IDLE: - return self._artwork_hash + if self._playing is not None and self.state != STATE_IDLE: + return self._playing.hash @asyncio.coroutine def async_get_media_image(self): """Fetch media image of current playing image.""" - return (yield from self._atv.metadata.artwork()), 'image/png' + return (yield from self.atv.metadata.artwork()), 'image/png' @property def media_title(self): @@ -235,9 +184,9 @@ class AppleTvDevice(MediaPlayerDevice): if self.state == STATE_IDLE: return 'Nothing playing' title = self._playing.title - return title if title else "No title" + return title if title else 'No title' - return 'Not connected to Apple TV' + return 'Establishing a connection to {0}...'.format(self._name) @property def supported_features(self): @@ -254,12 +203,13 @@ class AppleTvDevice(MediaPlayerDevice): @asyncio.coroutine def async_turn_on(self): """Turn the media player on.""" - self._set_power_off(False) + self._power.set_power_on(True) @asyncio.coroutine def async_turn_off(self): """Turn the media player off.""" - self._set_power_off(True) + self._playing = None + self._power.set_power_on(False) def async_media_play_pause(self): """Pause media on media player. @@ -269,9 +219,9 @@ class AppleTvDevice(MediaPlayerDevice): if self._playing is not None: state = self.state if state == STATE_PAUSED: - return self._atv.remote_control.play() + return self.atv.remote_control.play() elif state == STATE_PLAYING: - return self._atv.remote_control.pause() + return self.atv.remote_control.pause() def async_media_play(self): """Play media. @@ -279,7 +229,15 @@ class AppleTvDevice(MediaPlayerDevice): This method must be run in the event loop and returns a coroutine. """ if self._playing is not None: - return self._atv.remote_control.play() + return self.atv.remote_control.play() + + def async_media_stop(self): + """Stop the media player. + + This method must be run in the event loop and returns a coroutine. + """ + if self._playing is not None: + return self.atv.remote_control.stop() def async_media_pause(self): """Pause the media player. @@ -287,7 +245,7 @@ class AppleTvDevice(MediaPlayerDevice): This method must be run in the event loop and returns a coroutine. """ if self._playing is not None: - return self._atv.remote_control.pause() + return self.atv.remote_control.pause() def async_media_next_track(self): """Send next track command. @@ -295,7 +253,7 @@ class AppleTvDevice(MediaPlayerDevice): This method must be run in the event loop and returns a coroutine. """ if self._playing is not None: - return self._atv.remote_control.next() + return self.atv.remote_control.next() def async_media_previous_track(self): """Send previous track command. @@ -303,7 +261,7 @@ class AppleTvDevice(MediaPlayerDevice): This method must be run in the event loop and returns a coroutine. """ if self._playing is not None: - return self._atv.remote_control.previous() + return self.atv.remote_control.previous() def async_media_seek(self, position): """Send seek command. @@ -311,4 +269,4 @@ class AppleTvDevice(MediaPlayerDevice): This method must be run in the event loop and returns a coroutine. """ if self._playing is not None: - return self._atv.remote_control.set_position(position) + return self.atv.remote_control.set_position(position) diff --git a/homeassistant/components/remote/apple_tv.py b/homeassistant/components/remote/apple_tv.py new file mode 100644 index 00000000000..a7ea113c2db --- /dev/null +++ b/homeassistant/components/remote/apple_tv.py @@ -0,0 +1,87 @@ +""" +Remote control support for Apple TV. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/remote.apple_tv/ +""" +import asyncio + +from homeassistant.components.apple_tv import ( + ATTR_ATV, ATTR_POWER, DATA_APPLE_TV) +from homeassistant.components.remote import ATTR_COMMAND +from homeassistant.components import remote +from homeassistant.const import (CONF_NAME, CONF_HOST) + + +DEPENDENCIES = ['apple_tv'] + + +@asyncio.coroutine +def async_setup_platform(hass, config, async_add_devices, discovery_info=None): + """Set up the Apple TV remote platform.""" + if not discovery_info: + return + + name = discovery_info[CONF_NAME] + host = discovery_info[CONF_HOST] + atv = hass.data[DATA_APPLE_TV][host][ATTR_ATV] + power = hass.data[DATA_APPLE_TV][host][ATTR_POWER] + async_add_devices([AppleTVRemote(atv, power, name)]) + + +class AppleTVRemote(remote.RemoteDevice): + """Device that sends commands to an Apple TV.""" + + def __init__(self, atv, power, name): + """Initialize device.""" + self._atv = atv + self._name = name + self._power = power + self._power.listeners.append(self) + + @property + def name(self): + """Return the name of the device.""" + return self._name + + @property + def is_on(self): + """Return true if device is on.""" + return self._power.turned_on + + @property + def should_poll(self): + """No polling needed for Apple TV.""" + return False + + @asyncio.coroutine + def async_turn_on(self, **kwargs): + """Turn the device on. + + This method is a coroutine. + """ + self._power.set_power_on(True) + + @asyncio.coroutine + def async_turn_off(self): + """Turn the device off. + + This method is a coroutine. + """ + self._power.set_power_on(False) + + def async_send_command(self, **kwargs): + """Send a command to one device. + + This method must be run in the event loop and returns a coroutine. + """ + # Send commands in specified order but schedule only one coroutine + @asyncio.coroutine + def _send_commads(): + for command in kwargs[ATTR_COMMAND]: + if not hasattr(self._atv.remote_control, command): + continue + + yield from getattr(self._atv.remote_control, command)() + + return _send_commads() diff --git a/homeassistant/components/services.yaml b/homeassistant/components/services.yaml index d81d14fc991..db71b2322fa 100644 --- a/homeassistant/components/services.yaml +++ b/homeassistant/components/services.yaml @@ -470,3 +470,16 @@ axis: param: description: What parameter to operate on. [Required] example: 'package=VideoMotionDetection' + +apple_tv: + apple_tv_authenticate: + description: Start AirPlay device authentication. + + fields: + entity_id: + description: Name(s) of entities to authenticate with. + example: 'media_player.apple_tv' + + apple_tv_scan: + description: Scan for Apple TV devices. + diff --git a/requirements_all.txt b/requirements_all.txt index fc71a3ab3ff..d3f24dad542 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -514,8 +514,8 @@ pyasn1-modules==0.0.9 # homeassistant.components.notify.xmpp pyasn1==0.2.3 -# homeassistant.components.media_player.apple_tv -pyatv==0.2.1 +# homeassistant.components.apple_tv +pyatv==0.3.2 # homeassistant.components.device_tracker.bbox # homeassistant.components.sensor.bbox From 0ecceb601b7819745cb4f58f07dd4fd21b9ef52a Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Wed, 5 Jul 2017 06:47:30 +0200 Subject: [PATCH 039/131] Temporary fix for the client_id generation (fixes #8315) (#8336) * Temporary fix for the client_id generation (fixes #8315) * Fix comment * Move client id setting. * Lint --- homeassistant/components/mqtt/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 90c89b3193d..64e804d7715 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -315,6 +315,10 @@ def async_setup(hass, config): client_cert = conf.get(CONF_CLIENT_CERT) tls_insecure = conf.get(CONF_TLS_INSECURE) protocol = conf[CONF_PROTOCOL] + + # hbmqtt requires a client id to be set. + if client_id is None: + client_id = 'home-assistant' elif broker_config: # If no broker passed in, auto config to internal server broker, port, username, password, certificate, protocol = broker_config From 83a5f932d1bec13720b5f9a1b07e49ae8f83e0b9 Mon Sep 17 00:00:00 2001 From: Lev Aronsky Date: Wed, 5 Jul 2017 08:55:21 +0300 Subject: [PATCH 040/131] Add citybikes platform (#8202) * Initial commit - new CityBikes platform * Several syntax fixes. * Added imperial unit support. * Added station list lenght validation. * Style fixes. * Updated requirements. * Updated .coveragerc. * Fixed style problems according to pylint output. * Updated SCAN_INTERVAL value. * Fixed station names. Removed unnecessary calls to `slugify`. Changed the base name to reflect the name of the bike sharing network, instead of the more generic `citybikes`. * Small style fix. * Use async version of python-citybikes * Made platform setup async. * Made some more things async. * Switched to constants. * WIP: different approach to async. * Removed python-citybikes depnedency to fix async issues. * Removed unnecessary hidden property. * Style fixes. * Retry network detection. * Style fixes, and base name usage. * Fixes according to comments. * Use cv.latitude instead of coercing to float. * Updated requirements. * Several fixes and improvements. * Started using PlatformNotReady exception. * Cached the networks list result to avoid unnecessary API requests. * Switched the asyncio.timeout to use a constant. * Refactored CityBikes API requests into a separate function * Fixed linting errors. * Removed unnecessary requirement. --- .coveragerc | 3 +- homeassistant/components/sensor/citybikes.py | 293 +++++++++++++++++++ 2 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 homeassistant/components/sensor/citybikes.py diff --git a/.coveragerc b/.coveragerc index 9f538911a6e..1f2454fc292 100644 --- a/.coveragerc +++ b/.coveragerc @@ -392,7 +392,7 @@ omit = homeassistant/components/sensor/bom.py homeassistant/components/sensor/broadlink.py homeassistant/components/sensor/buienradar.py - homeassistant/components/sensor/dublin_bus_transport.py + homeassistant/components/sensor/citybikes.py homeassistant/components/sensor/coinmarketcap.py homeassistant/components/sensor/cert_expiry.py homeassistant/components/sensor/comed_hourly_pricing.py @@ -406,6 +406,7 @@ omit = homeassistant/components/sensor/dnsip.py homeassistant/components/sensor/dovado.py homeassistant/components/sensor/dte_energy_bridge.py + homeassistant/components/sensor/dublin_bus_transport.py homeassistant/components/sensor/ebox.py homeassistant/components/sensor/eddystone_temperature.py homeassistant/components/sensor/eliqonline.py diff --git a/homeassistant/components/sensor/citybikes.py b/homeassistant/components/sensor/citybikes.py new file mode 100644 index 00000000000..15046897732 --- /dev/null +++ b/homeassistant/components/sensor/citybikes.py @@ -0,0 +1,293 @@ +""" +Sensor for the CityBikes data. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.citybikes/ +""" +import logging +from datetime import timedelta + +import asyncio +import aiohttp +import async_timeout +import voluptuous as vol + +from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.const import ( + CONF_NAME, CONF_LATITUDE, CONF_LONGITUDE, + ATTR_ATTRIBUTION, ATTR_LOCATION, ATTR_LATITUDE, ATTR_LONGITUDE, + ATTR_FRIENDLY_NAME, STATE_UNKNOWN, LENGTH_METERS, LENGTH_FEET) +from homeassistant.exceptions import PlatformNotReady +from homeassistant.helpers.event import async_track_time_interval +from homeassistant.helpers.entity import Entity +from homeassistant.helpers.aiohttp_client import async_get_clientsession +from homeassistant.util import location, distance +import homeassistant.helpers.config_validation as cv + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_ENDPOINT = 'https://api.citybik.es/{uri}' +NETWORKS_URI = 'v2/networks' +STATIONS_URI = 'v2/networks/{uid}?fields=network.stations' + +REQUEST_TIMEOUT = 5 # In seconds; argument to asyncio.timeout +SCAN_INTERVAL = timedelta(minutes=5) # Timely, and doesn't suffocate the API +DOMAIN = 'citybikes' +MONITORED_NETWORKS = 'monitored-networks' +CONF_NETWORK = 'network' +CONF_RADIUS = 'radius' +CONF_STATIONS_LIST = 'stations' +ATTR_NETWORKS_LIST = 'networks' +ATTR_NETWORK = 'network' +ATTR_STATIONS_LIST = 'stations' +ATTR_ID = 'id' +ATTR_UID = 'uid' +ATTR_NAME = 'name' +ATTR_EXTRA = 'extra' +ATTR_TIMESTAMP = 'timestamp' +ATTR_EMPTY_SLOTS = 'empty_slots' +ATTR_FREE_BIKES = 'free_bikes' +ATTR_TIMESTAMP = 'timestamp' +CITYBIKES_ATTRIBUTION = "Information provided by the CityBikes Project "\ + "(https://citybik.es/#about)" + + +PLATFORM_SCHEMA = vol.All( + cv.has_at_least_one_key(CONF_RADIUS, CONF_STATIONS_LIST), + PLATFORM_SCHEMA.extend({ + vol.Optional(CONF_NAME, default=''): cv.string, + vol.Optional(CONF_NETWORK): cv.string, + vol.Inclusive(CONF_LATITUDE, 'coordinates'): cv.latitude, + vol.Inclusive(CONF_LONGITUDE, 'coordinates'): cv.longitude, + vol.Optional(CONF_RADIUS, 'station_filter'): cv.positive_int, + vol.Optional(CONF_STATIONS_LIST, 'station_filter'): + vol.All( + cv.ensure_list, + vol.Length(min=1), + [cv.string]) + })) + +NETWORK_SCHEMA = vol.Schema({ + vol.Required(ATTR_ID): cv.string, + vol.Required(ATTR_NAME): cv.string, + vol.Required(ATTR_LOCATION): vol.Schema({ + vol.Required(ATTR_LATITUDE): cv.latitude, + vol.Required(ATTR_LONGITUDE): cv.longitude, + }, extra=vol.REMOVE_EXTRA), + }, extra=vol.REMOVE_EXTRA) + +NETWORKS_RESPONSE_SCHEMA = vol.Schema({ + vol.Required(ATTR_NETWORKS_LIST): [NETWORK_SCHEMA], + }) + +STATION_SCHEMA = vol.Schema({ + vol.Required(ATTR_FREE_BIKES): cv.positive_int, + vol.Required(ATTR_EMPTY_SLOTS): cv.positive_int, + vol.Required(ATTR_LATITUDE): cv.latitude, + vol.Required(ATTR_LONGITUDE): cv.latitude, + vol.Required(ATTR_ID): cv.string, + vol.Required(ATTR_NAME): cv.string, + vol.Required(ATTR_TIMESTAMP): cv.string, + vol.Optional(ATTR_EXTRA): vol.Schema({ + vol.Optional(ATTR_UID): cv.string + }, extra=vol.REMOVE_EXTRA) + }, extra=vol.REMOVE_EXTRA) + +STATIONS_RESPONSE_SCHEMA = vol.Schema({ + vol.Required(ATTR_NETWORK): vol.Schema({ + vol.Required(ATTR_STATIONS_LIST): [STATION_SCHEMA] + }, extra=vol.REMOVE_EXTRA) + }) + + +class CityBikesRequestError(Exception): + """Error to indicate a CityBikes API request has failed.""" + + pass + + +@asyncio.coroutine +def async_citybikes_request(hass, uri, schema): + """Perform a request to CityBikes API endpoint, and parse the response.""" + try: + session = async_get_clientsession(hass) + + with async_timeout.timeout(REQUEST_TIMEOUT, loop=hass.loop): + req = yield from session.get(DEFAULT_ENDPOINT.format(uri=uri)) + + json_response = yield from req.json() + return schema(json_response) + except (asyncio.TimeoutError, aiohttp.ClientError): + _LOGGER.error("Could not connect to CityBikes API endpoint") + except ValueError: + _LOGGER.error("Received non-JSON data from CityBikes API endpoint") + except vol.Invalid as err: + _LOGGER.error("Received unexpected JSON from CityBikes" + " API endpoint: %s", err) + raise CityBikesRequestError + + +# pylint: disable=unused-argument +@asyncio.coroutine +def async_setup_platform(hass, config, async_add_entities, + discovery_info=None): + """Set up the CityBikes platform.""" + if DOMAIN not in hass.data: + hass.data[DOMAIN] = {MONITORED_NETWORKS: {}} + + latitude = config.get(CONF_LATITUDE, hass.config.latitude) + longitude = config.get(CONF_LONGITUDE, hass.config.longitude) + network_id = config.get(CONF_NETWORK) + stations_list = set(config.get(CONF_STATIONS_LIST, [])) + radius = config.get(CONF_RADIUS, 0) + name = config.get(CONF_NAME) + if not hass.config.units.is_metric: + radius = distance.convert(radius, LENGTH_FEET, LENGTH_METERS) + + if not network_id: + network_id = yield from CityBikesNetwork.get_closest_network_id( + hass, latitude, longitude) + + if network_id not in hass.data[DOMAIN][MONITORED_NETWORKS]: + network = CityBikesNetwork(hass, network_id) + hass.data[DOMAIN][MONITORED_NETWORKS][network_id] = network + hass.async_add_job(network.async_refresh) + async_track_time_interval(hass, network.async_refresh, + SCAN_INTERVAL) + else: + network = hass.data[DOMAIN][MONITORED_NETWORKS][network_id] + + yield from network.ready.wait() + + entities = [] + for station in network.stations: + dist = location.distance(latitude, longitude, + station[ATTR_LATITUDE], + station[ATTR_LONGITUDE]) + station_id = station[ATTR_ID] + station_uid = str(station.get(ATTR_EXTRA, {}).get(ATTR_UID, '')) + + if radius > dist or stations_list.intersection((station_id, + station_uid)): + entities.append(CityBikesStation(network, station_id, name)) + + async_add_entities(entities, True) + + +class CityBikesNetwork: + """Thin wrapper around a CityBikes network object.""" + + NETWORKS_LIST = None + NETWORKS_LIST_LOADING = asyncio.Condition() + + @classmethod + @asyncio.coroutine + def get_closest_network_id(cls, hass, latitude, longitude): + """Return the id of the network closest to provided location.""" + try: + yield from cls.NETWORKS_LIST_LOADING.acquire() + if cls.NETWORKS_LIST is None: + networks = yield from async_citybikes_request( + hass, NETWORKS_URI, NETWORKS_RESPONSE_SCHEMA) + cls.NETWORKS_LIST = networks[ATTR_NETWORKS_LIST] + networks_list = cls.NETWORKS_LIST + network = networks_list[0] + result = network[ATTR_ID] + minimum_dist = location.distance( + latitude, longitude, + network[ATTR_LOCATION][ATTR_LATITUDE], + network[ATTR_LOCATION][ATTR_LONGITUDE]) + for network in networks_list[1:]: + network_latitude = network[ATTR_LOCATION][ATTR_LATITUDE] + network_longitude = network[ATTR_LOCATION][ATTR_LONGITUDE] + dist = location.distance(latitude, longitude, + network_latitude, network_longitude) + if dist < minimum_dist: + minimum_dist = dist + result = network[ATTR_ID] + + return result + except CityBikesRequestError: + raise PlatformNotReady + finally: + cls.NETWORKS_LIST_LOADING.release() + + def __init__(self, hass, network_id): + """Initialize the network object.""" + self.hass = hass + self.network_id = network_id + self.stations = [] + self.ready = asyncio.Event() + + @asyncio.coroutine + def async_refresh(self, now=None): + """Refresh the state of the network.""" + try: + network = yield from async_citybikes_request( + self.hass, STATIONS_URI.format(uid=self.network_id), + STATIONS_RESPONSE_SCHEMA) + self.stations = network[ATTR_NETWORK][ATTR_STATIONS_LIST] + self.ready.set() + except CityBikesRequestError: + if now is not None: + self.ready.clear() + else: + raise PlatformNotReady + + +class CityBikesStation(Entity): + """CityBikes API Sensor.""" + + def __init__(self, network, station_id, base_name=''): + """Initialize the sensor.""" + self._network = network + self._station_id = station_id + self._station_data = {} + self._base_name = base_name + + @property + def state(self): + """Return the state of the sensor.""" + return self._station_data.get(ATTR_FREE_BIKES, STATE_UNKNOWN) + + @property + def name(self): + """Return the name of the sensor.""" + if self._base_name: + return "{} {} {}".format(self._network.network_id, self._base_name, + self._station_id) + return "{} {}".format(self._network.network_id, self._station_id) + + @asyncio.coroutine + def async_update(self): + """Update station state.""" + if self._network.ready.is_set(): + for station in self._network.stations: + if station[ATTR_ID] == self._station_id: + self._station_data = station + break + + @property + def device_state_attributes(self): + """Return the state attributes.""" + if self._station_data: + return { + ATTR_ATTRIBUTION: CITYBIKES_ATTRIBUTION, + ATTR_UID: self._station_data.get(ATTR_EXTRA, {}).get(ATTR_UID), + ATTR_LATITUDE: self._station_data[ATTR_LATITUDE], + ATTR_LONGITUDE: self._station_data[ATTR_LONGITUDE], + ATTR_EMPTY_SLOTS: self._station_data[ATTR_EMPTY_SLOTS], + ATTR_FRIENDLY_NAME: self._station_data[ATTR_NAME], + ATTR_TIMESTAMP: self._station_data[ATTR_TIMESTAMP], + } + return {ATTR_ATTRIBUTION: CITYBIKES_ATTRIBUTION} + + @property + def unit_of_measurement(self): + """Return the unit of measurement.""" + return 'bikes' + + @property + def icon(self): + """Return the icon.""" + return 'mdi:bike' From 5779d64e98961f32ab03915b49087155bdedc9c4 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 5 Jul 2017 20:02:16 -0700 Subject: [PATCH 041/131] Fix some issues for PyLint 1.7.2 (#8356) * Fix some issues for PyLint 1.7.2 * More fixes * Revert position change for cover --- homeassistant/__main__.py | 4 +-- homeassistant/components/__init__.py | 8 ++--- .../components/alarm_control_panel/wink.py | 4 --- homeassistant/components/alert.py | 4 +-- homeassistant/components/api.py | 6 ++-- homeassistant/components/automation/sun.py | 4 +-- .../components/binary_sensor/arest.py | 2 +- .../components/binary_sensor/wink.py | 20 ------------- homeassistant/components/camera/uvc.py | 2 +- homeassistant/components/climate/homematic.py | 4 +-- homeassistant/components/climate/netatmo.py | 4 +-- homeassistant/components/cover/wink.py | 8 ++--- .../components/device_tracker/cisco_ios.py | 25 ++++++++-------- homeassistant/components/fan/insteon_local.py | 2 +- homeassistant/components/history.py | 4 +-- homeassistant/components/insteon_local.py | 3 +- homeassistant/components/knx.py | 2 +- homeassistant/components/light/homematic.py | 11 ++++--- homeassistant/components/light/hue.py | 19 +++++------- homeassistant/components/lock/zwave.py | 4 +-- homeassistant/components/logbook.py | 6 ++-- .../components/media_player/__init__.py | 6 ++-- homeassistant/components/media_player/cast.py | 3 +- .../components/media_player/denonavr.py | 29 +++++-------------- .../components/media_player/directv.py | 23 +++++---------- .../components/media_player/philips_js.py | 13 +++------ .../components/media_player/spotify.py | 5 ++-- homeassistant/components/notify/sendgrid.py | 2 +- homeassistant/components/octoprint.py | 20 +++++++------ homeassistant/components/plant.py | 8 ++--- homeassistant/components/qwikswitch.py | 8 ++--- homeassistant/components/rflink.py | 3 +- homeassistant/components/sensor/arest.py | 2 +- .../components/sensor/dublin_bus_transport.py | 2 +- homeassistant/components/sensor/homematic.py | 4 +-- homeassistant/components/sensor/mfi.py | 9 +++--- .../components/sensor/mold_indicator.py | 13 ++++----- .../components/sensor/openhardwaremonitor.py | 4 +-- homeassistant/components/sensor/uber.py | 2 +- homeassistant/components/sensor/zha.py | 4 --- homeassistant/components/switch/arest.py | 4 +-- homeassistant/components/switch/bbb_gpio.py | 4 +-- homeassistant/components/switch/broadlink.py | 4 --- homeassistant/components/switch/homematic.py | 4 +-- homeassistant/components/switch/hook.py | 4 +-- homeassistant/components/switch/mfi.py | 6 ++-- homeassistant/components/switch/mysensors.py | 6 ++-- .../components/switch/pulseaudio_loopback.py | 3 +- homeassistant/components/switch/rachio.py | 16 +++++----- homeassistant/components/switch/rpi_gpio.py | 4 +-- homeassistant/components/switch/wemo.py | 2 +- homeassistant/components/switch/wink.py | 4 --- homeassistant/components/tellduslive.py | 7 ++--- homeassistant/components/vera.py | 3 +- homeassistant/components/weather/__init__.py | 5 ++-- homeassistant/components/websocket_api.py | 2 +- homeassistant/components/wink.py | 3 +- homeassistant/components/zwave/__init__.py | 11 ++++--- homeassistant/core.py | 10 +++---- homeassistant/helpers/entity.py | 4 +-- homeassistant/helpers/event.py | 6 ++-- homeassistant/helpers/template.py | 2 +- homeassistant/remote.py | 15 +++++----- homeassistant/scripts/check_config.py | 2 +- homeassistant/util/__init__.py | 8 ++--- homeassistant/util/temperature.py | 3 +- 66 files changed, 176 insertions(+), 272 deletions(-) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index 75aaeaa1fd1..2ce574ca15e 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -229,8 +229,8 @@ def cmdline() -> List[str]: os.environ['PYTHONPATH'] = os.path.dirname(modulepath) return [sys.executable] + [arg for arg in sys.argv if arg != '--daemon'] - else: - return [arg for arg in sys.argv if arg != '--daemon'] + + return [arg for arg in sys.argv if arg != '--daemon'] def setup_and_run_hass(config_dir: str, diff --git a/homeassistant/components/__init__.py b/homeassistant/components/__init__.py index c372004e310..ecbb8036464 100644 --- a/homeassistant/components/__init__.py +++ b/homeassistant/components/__init__.py @@ -39,19 +39,19 @@ def is_on(hass, entity_id=None): else: entity_ids = hass.states.entity_ids() - for entity_id in entity_ids: - domain = ha.split_entity_id(entity_id)[0] + for ent_id in entity_ids: + domain = ha.split_entity_id(ent_id)[0] module = get_component(domain) try: - if module.is_on(hass, entity_id): + if module.is_on(hass, ent_id): return True except AttributeError: # module is None or method is_on does not exist _LOGGER.exception("Failed to call %s.is_on for %s", - module, entity_id) + module, ent_id) return False diff --git a/homeassistant/components/alarm_control_panel/wink.py b/homeassistant/components/alarm_control_panel/wink.py index a8cad115883..8bc2539f772 100644 --- a/homeassistant/components/alarm_control_panel/wink.py +++ b/homeassistant/components/alarm_control_panel/wink.py @@ -39,10 +39,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class WinkCameraDevice(WinkDevice, alarm.AlarmControlPanel): """Representation a Wink camera alarm.""" - def __init__(self, wink, hass): - """Initialize the Wink alarm.""" - super().__init__(wink, hass) - @asyncio.coroutine def async_added_to_hass(self): """Callback when entity is added to hass.""" diff --git a/homeassistant/components/alert.py b/homeassistant/components/alert.py index b4de3c4a0f5..6356f429bed 100644 --- a/homeassistant/components/alert.py +++ b/homeassistant/components/alert.py @@ -271,14 +271,14 @@ class Alert(ToggleEntity): 'notify', target, {'message': self._done_message}) @asyncio.coroutine - def async_turn_on(self): + def async_turn_on(self, **kwargs): """Async Unacknowledge alert.""" _LOGGER.debug("Reset Alert: %s", self._name) self._ack = False yield from self.async_update_ha_state() @asyncio.coroutine - def async_turn_off(self): + def async_turn_off(self, **kwargs): """Async Acknowledge alert.""" _LOGGER.debug("Acknowledged Alert: %s", self._name) self._ack = True diff --git a/homeassistant/components/api.py b/homeassistant/components/api.py index 8205029bd21..c22683970bf 100644 --- a/homeassistant/components/api.py +++ b/homeassistant/components/api.py @@ -198,8 +198,7 @@ class APIEntityStateView(HomeAssistantView): state = request.app['hass'].states.get(entity_id) if state: return self.json(state) - else: - return self.json_message('Entity not found', HTTP_NOT_FOUND) + return self.json_message('Entity not found', HTTP_NOT_FOUND) @asyncio.coroutine def post(self, request, entity_id): @@ -237,8 +236,7 @@ class APIEntityStateView(HomeAssistantView): """Remove entity.""" if request.app['hass'].states.async_remove(entity_id): return self.json_message('Entity removed') - else: - return self.json_message('Entity not found', HTTP_NOT_FOUND) + return self.json_message('Entity not found', HTTP_NOT_FOUND) class APIEventListenersView(HomeAssistantView): diff --git a/homeassistant/components/automation/sun.py b/homeassistant/components/automation/sun.py index dfed411745f..497b8453267 100644 --- a/homeassistant/components/automation/sun.py +++ b/homeassistant/components/automation/sun.py @@ -42,8 +42,6 @@ def async_trigger(hass, config, action): }, }) - # Do something to call action if event == SUN_EVENT_SUNRISE: return async_track_sunrise(hass, call_action, offset) - else: - return async_track_sunset(hass, call_action, offset) + return async_track_sunset(hass, call_action, offset) diff --git a/homeassistant/components/binary_sensor/arest.py b/homeassistant/components/binary_sensor/arest.py index 972d9ca835c..5b58a6cbf6a 100644 --- a/homeassistant/components/binary_sensor/arest.py +++ b/homeassistant/components/binary_sensor/arest.py @@ -68,7 +68,7 @@ class ArestBinarySensor(BinarySensorDevice): if self._pin is not None: request = requests.get( '{}/mode/{}/i'.format(self._resource, self._pin), timeout=10) - if request.status_code is not 200: + if request.status_code != 200: _LOGGER.error("Can't set mode of %s", self._resource) @property diff --git a/homeassistant/components/binary_sensor/wink.py b/homeassistant/components/binary_sensor/wink.py index c16c62a5f81..b4910687da7 100644 --- a/homeassistant/components/binary_sensor/wink.py +++ b/homeassistant/components/binary_sensor/wink.py @@ -121,10 +121,6 @@ class WinkBinarySensorDevice(WinkDevice, BinarySensorDevice, Entity): class WinkSmokeDetector(WinkBinarySensorDevice): """Representation of a Wink Smoke detector.""" - def __init__(self, wink, hass): - """Initialize the Wink binary sensor.""" - super().__init__(wink, hass) - @property def device_state_attributes(self): """Return the state attributes.""" @@ -136,10 +132,6 @@ class WinkSmokeDetector(WinkBinarySensorDevice): class WinkHub(WinkBinarySensorDevice): """Representation of a Wink Hub.""" - def __init__(self, wink, hass): - """Initialize the Wink binary sensor.""" - super().__init__(wink, hass) - @property def device_state_attributes(self): """Return the state attributes.""" @@ -152,10 +144,6 @@ class WinkHub(WinkBinarySensorDevice): class WinkRemote(WinkBinarySensorDevice): """Representation of a Wink Lutron Connected bulb remote.""" - def __init__(self, wink, hass): - """Initialize the Wink binary sensor.""" - super().__init__(wink, hass) - @property def device_state_attributes(self): """Return the state attributes.""" @@ -175,10 +163,6 @@ class WinkRemote(WinkBinarySensorDevice): class WinkButton(WinkBinarySensorDevice): """Representation of a Wink Relay button.""" - def __init__(self, wink, hass): - """Initialize the Wink binary sensor.""" - super().__init__(wink, hass) - @property def device_state_attributes(self): """Return the state attributes.""" @@ -191,10 +175,6 @@ class WinkButton(WinkBinarySensorDevice): class WinkGang(WinkBinarySensorDevice): """Representation of a Wink Relay gang.""" - def __init__(self, wink, hass): - """Initialize the Wink binary sensor.""" - super().__init__(wink, hass) - @property def is_on(self): """Return true if the gang is connected.""" diff --git a/homeassistant/components/camera/uvc.py b/homeassistant/components/camera/uvc.py index c0a8039ee64..3203a10b391 100644 --- a/homeassistant/components/camera/uvc.py +++ b/homeassistant/components/camera/uvc.py @@ -54,7 +54,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): _LOGGER.error("Unable to connect to NVR: %s", str(ex)) return False - identifier = nvrconn.server_version >= (3, 2, 0) and 'id' or 'uuid' + identifier = 'id' if nvrconn.server_version >= (3, 2, 0) else 'uuid' # Filter out airCam models, which are not supported in the latest # version of UnifiVideo and which are EOL by Ubiquiti cameras = [ diff --git a/homeassistant/components/climate/homematic.py b/homeassistant/components/climate/homematic.py index 1f9ca7c1abf..60cda24eef9 100644 --- a/homeassistant/components/climate/homematic.py +++ b/homeassistant/components/climate/homematic.py @@ -46,8 +46,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): return devices = [] - for config in discovery_info[ATTR_DISCOVER_DEVICES]: - new_device = HMThermostat(hass, config) + for conf in discovery_info[ATTR_DISCOVER_DEVICES]: + new_device = HMThermostat(hass, conf) new_device.link_homematic() devices.append(new_device) diff --git a/homeassistant/components/climate/netatmo.py b/homeassistant/components/climate/netatmo.py index cea1a41ec9f..3706a24bb52 100755 --- a/homeassistant/components/climate/netatmo.py +++ b/homeassistant/components/climate/netatmo.py @@ -119,14 +119,14 @@ class NetatmoThermostat(ClimateDevice): self._data.thermostatdata.setthermpoint(mode, temp, endTimeOffset=None) self._away = False - def set_temperature(self, endTimeOffset=DEFAULT_TIME_OFFSET, **kwargs): + def set_temperature(self, **kwargs): """Set new target temperature for 2 hours.""" temperature = kwargs.get(ATTR_TEMPERATURE) if temperature is None: return mode = "manual" self._data.thermostatdata.setthermpoint( - mode, temperature, endTimeOffset) + mode, temperature, DEFAULT_TIME_OFFSET) self._target_temperature = temperature self._away = False diff --git a/homeassistant/components/cover/wink.py b/homeassistant/components/cover/wink.py index d5908c35ca2..ce96b4d75e0 100644 --- a/homeassistant/components/cover/wink.py +++ b/homeassistant/components/cover/wink.py @@ -29,20 +29,16 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class WinkCoverDevice(WinkDevice, CoverDevice): """Representation of a Wink cover device.""" - def __init__(self, wink, hass): - """Initialize the cover.""" - super().__init__(wink, hass) - @asyncio.coroutine def async_added_to_hass(self): """Callback when entity is added to hass.""" self.hass.data[DOMAIN]['entities']['cover'].append(self) - def close_cover(self): + def close_cover(self, **kwargs): """Close the shade.""" self.wink.set_state(0) - def open_cover(self): + def open_cover(self, **kwargs): """Open the shade.""" self.wink.set_state(1) diff --git a/homeassistant/components/device_tracker/cisco_ios.py b/homeassistant/components/device_tracker/cisco_ios.py index 35ffa754348..99ed06de486 100644 --- a/homeassistant/components/device_tracker/cisco_ios.py +++ b/homeassistant/components/device_tracker/cisco_ios.py @@ -87,21 +87,20 @@ class CiscoDeviceScanner(DeviceScanner): lines_result = lines_result[2:] for line in lines_result: - if len(line.split()) is 6: - parts = line.split() - if len(parts) != 6: - continue + parts = line.split() + if len(parts) != 6: + continue - # ['Internet', '10.10.11.1', '-', '0027.d32d.0123', 'ARPA', - # 'GigabitEthernet0'] - age = parts[2] - hw_addr = parts[3] + # ['Internet', '10.10.11.1', '-', '0027.d32d.0123', 'ARPA', + # 'GigabitEthernet0'] + age = parts[2] + hw_addr = parts[3] - if age != "-": - mac = _parse_cisco_mac_address(hw_addr) - age = int(age) - if age < 1: - last_results.append(mac) + if age != "-": + mac = _parse_cisco_mac_address(hw_addr) + age = int(age) + if age < 1: + last_results.append(mac) self.last_results = last_results return True diff --git a/homeassistant/components/fan/insteon_local.py b/homeassistant/components/fan/insteon_local.py index 24039f94c00..a18c173ecca 100644 --- a/homeassistant/components/fan/insteon_local.py +++ b/homeassistant/components/fan/insteon_local.py @@ -35,7 +35,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): insteonhub = hass.data['insteon_local'] conf_fans = config_from_file(hass.config.path(INSTEON_LOCAL_FANS_CONF)) - if len(conf_fans): + if conf_fans: for device_id in conf_fans: setup_fan(device_id, conf_fans[device_id], insteonhub, hass, add_devices) diff --git a/homeassistant/components/history.py b/homeassistant/components/history.py index 8faf8f30b1d..9800a15c16b 100644 --- a/homeassistant/components/history.py +++ b/homeassistant/components/history.py @@ -161,8 +161,8 @@ def states_to_json(hass, states, start_time, entity_id, filters=None): result[state.entity_id].append(state) # Append all changes to it - for entity_id, group in groupby(states, lambda state: state.entity_id): - result[entity_id].extend(group) + for ent_id, group in groupby(states, lambda state: state.entity_id): + result[ent_id].extend(group) return result diff --git a/homeassistant/components/insteon_local.py b/homeassistant/components/insteon_local.py index 90e146d0e4f..711dafb6b73 100644 --- a/homeassistant/components/insteon_local.py +++ b/homeassistant/components/insteon_local.py @@ -67,10 +67,9 @@ def setup(hass, config): except requests.exceptions.RequestException: if insteonhub.http_code == 401: _LOGGER.error("Bad user/pass for insteon_local hub") - return False else: _LOGGER.error("Error on insteon_local hub check", exc_info=True) - return False + return False hass.data['insteon_local'] = insteonhub diff --git a/homeassistant/components/knx.py b/homeassistant/components/knx.py index 2cb8562ad9c..3a4b7c54400 100644 --- a/homeassistant/components/knx.py +++ b/homeassistant/components/knx.py @@ -43,7 +43,7 @@ def setup(hass, config): host = config[DOMAIN].get(CONF_HOST) port = config[DOMAIN].get(CONF_PORT) - if host is '0.0.0.0': + if host == '0.0.0.0': _LOGGER.debug("Will try to auto-detect KNX/IP gateway") KNXTUNNEL = KNXIPTunnel(host, port) diff --git a/homeassistant/components/light/homematic.py b/homeassistant/components/light/homematic.py index 11bba4260d5..60865dd223e 100644 --- a/homeassistant/components/light/homematic.py +++ b/homeassistant/components/light/homematic.py @@ -23,8 +23,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): return devices = [] - for config in discovery_info[ATTR_DISCOVER_DEVICES]: - new_device = HMLight(hass, config) + for conf in discovery_info[ATTR_DISCOVER_DEVICES]: + new_device = HMLight(hass, conf) new_device.link_homematic() devices.append(new_device) @@ -38,10 +38,9 @@ class HMLight(HMDevice, Light): def brightness(self): """Return the brightness of this light between 0..255.""" # Is dimmer? - if self._state is "LEVEL": + if self._state == "LEVEL": return int(self._hm_get_state() * 255) - else: - return None + return None @property def is_on(self): @@ -58,7 +57,7 @@ class HMLight(HMDevice, Light): def turn_on(self, **kwargs): """Turn the light on.""" - if ATTR_BRIGHTNESS in kwargs and self._state is "LEVEL": + if ATTR_BRIGHTNESS in kwargs and self._state == "LEVEL": percent_bright = float(kwargs[ATTR_BRIGHTNESS]) / 255 self._hmdevice.set_level(percent_bright, self._channel) else: diff --git a/homeassistant/components/light/hue.py b/homeassistant/components/light/hue.py index 0f00519ab91..73d19d21272 100644 --- a/homeassistant/components/light/hue.py +++ b/homeassistant/components/light/hue.py @@ -330,36 +330,31 @@ class HueLight(Light): """Return the brightness of this light between 0..255.""" if self.is_group: return self.info['action'].get('bri') - else: - return self.info['state'].get('bri') + return self.info['state'].get('bri') @property def xy_color(self): """Return the XY color value.""" if self.is_group: return self.info['action'].get('xy') - else: - return self.info['state'].get('xy') + return self.info['state'].get('xy') @property def color_temp(self): """Return the CT color value.""" if self.is_group: return self.info['action'].get('ct') - else: - return self.info['state'].get('ct') + return self.info['state'].get('ct') @property def is_on(self): """Return true if device is on.""" if self.is_group: return self.info['state']['any_on'] - else: - if self.allow_unreachable: - return self.info['state']['on'] - else: - return self.info['state']['reachable'] and \ - self.info['state']['on'] + elif self.allow_unreachable: + return self.info['state']['on'] + return self.info['state']['reachable'] and \ + self.info['state']['on'] @property def supported_features(self): diff --git a/homeassistant/components/lock/zwave.py b/homeassistant/components/lock/zwave.py index e9199290e30..009d4cf1069 100644 --- a/homeassistant/components/lock/zwave.py +++ b/homeassistant/components/lock/zwave.py @@ -251,7 +251,7 @@ class ZwaveLock(zwave.ZWaveDeviceEntity, LockDevice): if not alarm_type: return - if alarm_type is 21: + if alarm_type == 21: self._lock_status = '{}{}'.format( LOCK_ALARM_TYPE.get(str(alarm_type)), MANUAL_LOCK_ALARM_LEVEL.get(str(alarm_level))) @@ -260,7 +260,7 @@ class ZwaveLock(zwave.ZWaveDeviceEntity, LockDevice): self._lock_status = '{}{}'.format( LOCK_ALARM_TYPE.get(str(alarm_type)), str(alarm_level)) return - if alarm_type is 161: + if alarm_type == 161: self._lock_status = '{}{}'.format( LOCK_ALARM_TYPE.get(str(alarm_type)), TAMPER_ALARM_LEVEL.get(str(alarm_level))) diff --git a/homeassistant/components/logbook.py b/homeassistant/components/logbook.py index 29c69409774..4facf1334c6 100644 --- a/homeassistant/components/logbook.py +++ b/homeassistant/components/logbook.py @@ -367,14 +367,12 @@ def _entry_message_from_state(domain, state): if domain == 'device_tracker': if state.state == STATE_NOT_HOME: return 'is away' - else: - return 'is at {}'.format(state.state) + return 'is at {}'.format(state.state) elif domain == 'sun': if state.state == sun.STATE_ABOVE_HORIZON: return 'has risen' - else: - return 'has set' + return 'has set' elif state.state == STATE_ON: # Future: combine groups and its entity entries ? diff --git a/homeassistant/components/media_player/__init__.py b/homeassistant/components/media_player/__init__.py index e17935814cc..35981d89d6d 100644 --- a/homeassistant/components/media_player/__init__.py +++ b/homeassistant/components/media_player/__init__.py @@ -801,8 +801,7 @@ class MediaPlayerDevice(Entity): if self.state in [STATE_OFF, STATE_IDLE]: return self.async_turn_on() - else: - return self.async_turn_off() + return self.async_turn_off() @asyncio.coroutine def async_volume_up(self): @@ -845,8 +844,7 @@ class MediaPlayerDevice(Entity): if self.state == STATE_PLAYING: return self.async_media_pause() - else: - return self.async_media_play() + return self.async_media_play() @property def entity_picture(self): diff --git a/homeassistant/components/media_player/cast.py b/homeassistant/components/media_player/cast.py index e4ecd1bd37d..418d3576750 100644 --- a/homeassistant/components/media_player/cast.py +++ b/homeassistant/components/media_player/cast.py @@ -131,8 +131,7 @@ class CastDevice(MediaPlayerDevice): return STATE_IDLE elif self.cast.is_idle: return STATE_OFF - else: - return STATE_UNKNOWN + return STATE_UNKNOWN @property def volume_level(self): diff --git a/homeassistant/components/media_player/denonavr.py b/homeassistant/components/media_player/denonavr.py index 5f3b88ccf52..2bdc03c20ab 100644 --- a/homeassistant/components/media_player/denonavr.py +++ b/homeassistant/components/media_player/denonavr.py @@ -197,8 +197,7 @@ class DenonDevice(MediaPlayerDevice): """Flag media player features that are supported.""" if self._current_source in self._receiver.netaudio_func_list: return SUPPORT_DENON | SUPPORT_MEDIA_MODES - else: - return SUPPORT_DENON + return SUPPORT_DENON @property def media_content_id(self): @@ -210,8 +209,7 @@ class DenonDevice(MediaPlayerDevice): """Content type of current playing media.""" if self._state == STATE_PLAYING or self._state == STATE_PAUSED: return MEDIA_TYPE_MUSIC - else: - return MEDIA_TYPE_CHANNEL + return MEDIA_TYPE_CHANNEL @property def media_duration(self): @@ -223,8 +221,7 @@ class DenonDevice(MediaPlayerDevice): """Image url of current playing media.""" if self._current_source in self._receiver.playing_func_list: return self._media_image_url - else: - return None + return None @property def media_title(self): @@ -233,24 +230,21 @@ class DenonDevice(MediaPlayerDevice): return self._current_source elif self._title is not None: return self._title - else: - return self._frequency + return self._frequency @property def media_artist(self): """Artist of current playing media, music track only.""" if self._artist is not None: return self._artist - else: - return self._band + return self._band @property def media_album_name(self): """Album name of current playing media, music track only.""" if self._album is not None: return self._album - else: - return self._station + return self._station @property def media_album_artist(self): @@ -297,17 +291,11 @@ class DenonDevice(MediaPlayerDevice): """Turn on media player.""" if self._receiver.power_on(): self._state = STATE_ON - return True - else: - return False def turn_off(self): """Turn off media player.""" if self._receiver.power_off(): self._state = STATE_OFF - return True - else: - return False def volume_up(self): """Volume up the media player.""" @@ -327,11 +315,8 @@ class DenonDevice(MediaPlayerDevice): try: if self._receiver.set_volume(volume_denon): self._volume = volume_denon - return True - else: - return False except ValueError: - return False + pass def mute_volume(self, mute): """Send mute command.""" diff --git a/homeassistant/components/media_player/directv.py b/homeassistant/components/media_player/directv.py index c1b690bc370..75a828696d9 100644 --- a/homeassistant/components/media_player/directv.py +++ b/homeassistant/components/media_player/directv.py @@ -95,43 +95,37 @@ class DirecTvDevice(MediaPlayerDevice): if self._is_standby: return STATE_OFF # Haven't determined a way to see if the content is paused - else: - return STATE_PLAYING + return STATE_PLAYING @property def media_content_id(self): """Return the content ID of current playing media.""" if self._is_standby: return None - else: - return self._current['programId'] + return self._current['programId'] @property def media_duration(self): """Return the duration of current playing media in seconds.""" if self._is_standby: return None - else: - return self._current['duration'] + return self._current['duration'] @property def media_title(self): """Return the title of current playing media.""" if self._is_standby: return None - else: - return self._current['title'] + return self._current['title'] @property def media_series_title(self): """Return the title of current episode of TV show.""" if self._is_standby: return None - else: - if 'episodeTitle' in self._current: - return self._current['episodeTitle'] - else: - return None + elif 'episodeTitle' in self._current: + return self._current['episodeTitle'] + return None @property def supported_features(self): @@ -143,8 +137,7 @@ class DirecTvDevice(MediaPlayerDevice): """Return the content type of current playing media.""" if 'episodeTitle' in self._current: return MEDIA_TYPE_TVSHOW - else: - return MEDIA_TYPE_VIDEO + return MEDIA_TYPE_VIDEO @property def media_channel(self): diff --git a/homeassistant/components/media_player/philips_js.py b/homeassistant/components/media_player/philips_js.py index b79f3eeeb89..da572896ee0 100644 --- a/homeassistant/components/media_player/philips_js.py +++ b/homeassistant/components/media_player/philips_js.py @@ -90,8 +90,7 @@ class PhilipsTV(MediaPlayerDevice): """Flag media player features that are supported.""" if self._watching_tv: return SUPPORT_PHILIPS_JS_TV - else: - return SUPPORT_PHILIPS_JS + return SUPPORT_PHILIPS_JS @property def state(self): @@ -162,13 +161,9 @@ class PhilipsTV(MediaPlayerDevice): @property def media_title(self): """Title of current playing media.""" - if self._watching_tv: - if self._channel_name: - return '{} - {}'.format(self._source, self._channel_name) - else: - return self._source - else: - return self._source + if self._watching_tv and self._channel_name: + return '{} - {}'.format(self._source, self._channel_name) + return self._source @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): diff --git a/homeassistant/components/media_player/spotify.py b/homeassistant/components/media_player/spotify.py index b3405707877..e6604297fa1 100644 --- a/homeassistant/components/media_player/spotify.py +++ b/homeassistant/components/media_player/spotify.py @@ -171,7 +171,7 @@ class SpotifyMediaPlayer(MediaPlayerDevice): for device in devices} device_diff = {name: id for name, id in self._devices.items() if old_devices.get(name, None) is None} - if len(device_diff) > 0: + if device_diff: _LOGGER.info("New Devices: %s", str(device_diff)) # Current playback state current = self._player.current_playback() @@ -312,5 +312,4 @@ class SpotifyMediaPlayer(MediaPlayerDevice): """Return the media player features that are supported.""" if self._user is not None and self._user['product'] == 'premium': return SUPPORT_SPOTIFY - else: - return None + return None diff --git a/homeassistant/components/notify/sendgrid.py b/homeassistant/components/notify/sendgrid.py index a3d42f2be7d..6258f6272c0 100644 --- a/homeassistant/components/notify/sendgrid.py +++ b/homeassistant/components/notify/sendgrid.py @@ -74,5 +74,5 @@ class SendgridNotificationService(BaseNotificationService): } response = self._sg.client.mail.send.post(request_body=data) - if response.status_code is not 202: + if response.status_code != 202: _LOGGER.error("Unable to send notification") diff --git a/homeassistant/components/octoprint.py b/homeassistant/components/octoprint.py index b06b15c7973..0a099fc7349 100644 --- a/homeassistant/components/octoprint.py +++ b/homeassistant/components/octoprint.py @@ -100,12 +100,14 @@ class OctoPrintAPI(object): # pylint: disable=unused-variable def get_value_from_json(json_dict, sensor_type, group, tool): """Return the value for sensor_type from the JSON.""" - if group in json_dict: - if sensor_type in json_dict[group]: - if sensor_type == "target" and json_dict[sensor_type] is None: - return 0 - else: - return json_dict[group][sensor_type] - elif tool is not None: - if sensor_type in json_dict[group][tool]: - return json_dict[group][tool][sensor_type] + if group not in json_dict: + return None + + if sensor_type in json_dict[group]: + if sensor_type == "target" and json_dict[sensor_type] is None: + return 0 + return json_dict[group][sensor_type] + + elif tool is not None: + if sensor_type in json_dict[group][tool]: + return json_dict[group][tool][sensor_type] diff --git a/homeassistant/components/plant.py b/homeassistant/components/plant.py index cd43fbf715c..9b9e11e0fbb 100644 --- a/homeassistant/components/plant.py +++ b/homeassistant/components/plant.py @@ -204,13 +204,13 @@ class Plant(Entity): result.append('{} high'.format(sensor_name)) self._icon = params['icon'] - if len(result) == 0: + if result: + self._state = STATE_PROBLEM + self._problems = ','.join(result) + else: self._state = STATE_OK self._icon = 'mdi:thumb-up' self._problems = PROBLEM_NONE - else: - self._state = STATE_PROBLEM - self._problems = ','.join(result) _LOGGER.debug("New data processed") self.hass.async_add_job(self.async_update_ha_state()) diff --git a/homeassistant/components/qwikswitch.py b/homeassistant/components/qwikswitch.py index dd8ceefb169..d5d6f657bc6 100644 --- a/homeassistant/components/qwikswitch.py +++ b/homeassistant/components/qwikswitch.py @@ -183,10 +183,10 @@ def setup(hass, config): qsreply = qsusb.devices() if qsreply is False: return - for item in qsreply: - if item[QS_ID] in QSUSB: - QSUSB[item[QS_ID]].update_value( - round(min(item[PQS_VALUE], 100) * 2.55)) + for itm in qsreply: + if itm[QS_ID] in QSUSB: + QSUSB[itm[QS_ID]].update_value( + round(min(itm[PQS_VALUE], 100) * 2.55)) def _start(event): """Start listening.""" diff --git a/homeassistant/components/rflink.py b/homeassistant/components/rflink.py index 74772943691..6de5788b1dc 100644 --- a/homeassistant/components/rflink.py +++ b/homeassistant/components/rflink.py @@ -85,8 +85,7 @@ def identify_event_type(event): return EVENT_KEY_COMMAND elif EVENT_KEY_SENSOR in event: return EVENT_KEY_SENSOR - else: - return 'unknown' + return 'unknown' @asyncio.coroutine diff --git a/homeassistant/components/sensor/arest.py b/homeassistant/components/sensor/arest.py index b7e224a7447..19860ba84fd 100644 --- a/homeassistant/components/sensor/arest.py +++ b/homeassistant/components/sensor/arest.py @@ -123,7 +123,7 @@ class ArestSensor(Entity): if self._pin is not None: request = requests.get( '{}/mode/{}/i'.format(self._resource, self._pin), timeout=10) - if request.status_code is not 200: + if request.status_code != 200: _LOGGER.error("Can't set mode of %s", self._resource) @property diff --git a/homeassistant/components/sensor/dublin_bus_transport.py b/homeassistant/components/sensor/dublin_bus_transport.py index f1dda41c05f..f6d791f9fd6 100644 --- a/homeassistant/components/sensor/dublin_bus_transport.py +++ b/homeassistant/components/sensor/dublin_bus_transport.py @@ -141,7 +141,7 @@ class PublicTransportData(object): params = {} params['stopid'] = self.stop - if len(self.route) > 0: + if self.route: params['routeid'] = self.route params['maxresults'] = 2 diff --git a/homeassistant/components/sensor/homematic.py b/homeassistant/components/sensor/homematic.py index 30db91bc8b0..771b4a94bd4 100644 --- a/homeassistant/components/sensor/homematic.py +++ b/homeassistant/components/sensor/homematic.py @@ -56,8 +56,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): return devices = [] - for config in discovery_info[ATTR_DISCOVER_DEVICES]: - new_device = HMSensor(hass, config) + for conf in discovery_info[ATTR_DISCOVER_DEVICES]: + new_device = HMSensor(hass, conf) new_device.link_homematic() devices.append(new_device) diff --git a/homeassistant/components/sensor/mfi.py b/homeassistant/components/sensor/mfi.py index 9d78ffd3f1a..ecea0815e79 100644 --- a/homeassistant/components/sensor/mfi.py +++ b/homeassistant/components/sensor/mfi.py @@ -56,7 +56,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): password = config.get(CONF_PASSWORD) use_tls = config.get(CONF_SSL) verify_tls = config.get(CONF_VERIFY_SSL) - default_port = use_tls and 6443 or 6080 + default_port = 6443 if use_tls else 6080 port = int(config.get(CONF_PORT, default_port)) from mficlient.client import FailedToLogin, MFiClient @@ -97,10 +97,9 @@ class MfiSensor(Entity): if tag is None: return STATE_OFF elif self._port.model == 'Input Digital': - return self._port.value > 0 and STATE_ON or STATE_OFF - else: - digits = DIGITS.get(self._port.tag, 0) - return round(self._port.value, digits) + return STATE_ON if self._port.value > 0 else STATE_OFF + digits = DIGITS.get(self._port.tag, 0) + return round(self._port.value, digits) @property def unit_of_measurement(self): diff --git a/homeassistant/components/sensor/mold_indicator.py b/homeassistant/components/sensor/mold_indicator.py index 4b1b740093e..ccebd93dbec 100644 --- a/homeassistant/components/sensor/mold_indicator.py +++ b/homeassistant/components/sensor/mold_indicator.py @@ -242,10 +242,9 @@ class MoldIndicator(Entity): ATTR_DEWPOINT: self._dewpoint, ATTR_CRITICAL_TEMP: self._crit_temp, } - else: - return { - ATTR_DEWPOINT: - util.temperature.celsius_to_fahrenheit(self._dewpoint), - ATTR_CRITICAL_TEMP: - util.temperature.celsius_to_fahrenheit(self._crit_temp), - } + return { + ATTR_DEWPOINT: + util.temperature.celsius_to_fahrenheit(self._dewpoint), + ATTR_CRITICAL_TEMP: + util.temperature.celsius_to_fahrenheit(self._crit_temp), + } diff --git a/homeassistant/components/sensor/openhardwaremonitor.py b/homeassistant/components/sensor/openhardwaremonitor.py index 1d805916d97..54ce5dbd6da 100644 --- a/homeassistant/components/sensor/openhardwaremonitor.py +++ b/homeassistant/components/sensor/openhardwaremonitor.py @@ -147,13 +147,13 @@ class OpenHardwareMonitorData(object): """Recursively loop through child objects, finding the values.""" result = devices.copy() - if len(json[OHM_CHILDREN]) > 0: + if json[OHM_CHILDREN]: for child_index in range(0, len(json[OHM_CHILDREN])): child_path = path.copy() child_path.append(child_index) child_names = names.copy() - if len(path) > 0: + if path: child_names.append(json[OHM_NAME]) obj = json[OHM_CHILDREN][child_index] diff --git a/homeassistant/components/sensor/uber.py b/homeassistant/components/sensor/uber.py index 2830b8c98e9..42d6cad43f2 100644 --- a/homeassistant/components/sensor/uber.py +++ b/homeassistant/components/sensor/uber.py @@ -58,7 +58,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): continue dev.append(UberSensor('time', timeandpriceest, product_id, product)) if (product.get('price_details') is not None) and \ - product['price_details']['estimate'] is not 'Metered': + product['price_details']['estimate'] != 'Metered': dev.append(UberSensor( 'price', timeandpriceest, product_id, product)) add_devices(dev) diff --git a/homeassistant/components/sensor/zha.py b/homeassistant/components/sensor/zha.py index 78627674c55..7ac76a35b79 100644 --- a/homeassistant/components/sensor/zha.py +++ b/homeassistant/components/sensor/zha.py @@ -57,10 +57,6 @@ class Sensor(zha.Entity): value_attribute = 0 min_reportable_change = 1 - def __init__(self, **kwargs): - """Initialize ZHA sensor.""" - super().__init__(**kwargs) - @property def state(self) -> str: """Return the state of the entity.""" diff --git a/homeassistant/components/switch/arest.py b/homeassistant/components/switch/arest.py index eba05c64555..6e31694fd2d 100644 --- a/homeassistant/components/switch/arest.py +++ b/homeassistant/components/switch/arest.py @@ -102,7 +102,7 @@ class ArestSwitchFunction(ArestSwitchBase): request = requests.get( '{}/{}'.format(self._resource, self._func), timeout=10) - if request.status_code is not 200: + if request.status_code != 200: _LOGGER.error("Can't find function") return @@ -159,7 +159,7 @@ class ArestSwitchPin(ArestSwitchBase): request = requests.get( '{}/mode/{}/o'.format(self._resource, self._pin), timeout=10) - if request.status_code is not 200: + if request.status_code != 200: _LOGGER.error("Can't set mode") self._available = False diff --git a/homeassistant/components/switch/bbb_gpio.py b/homeassistant/components/switch/bbb_gpio.py index ce2d91273f9..6dc5df4ffe3 100644 --- a/homeassistant/components/switch/bbb_gpio.py +++ b/homeassistant/components/switch/bbb_gpio.py @@ -77,13 +77,13 @@ class BBBGPIOSwitch(ToggleEntity): """Return true if device is on.""" return self._state - def turn_on(self): + def turn_on(self, **kwargs): """Turn the device on.""" bbb_gpio.write_output(self._pin, 0 if self._invert_logic else 1) self._state = True self.schedule_update_ha_state() - def turn_off(self): + def turn_off(self, **kwargs): """Turn the device off.""" bbb_gpio.write_output(self._pin, 1 if self._invert_logic else 0) self._state = False diff --git a/homeassistant/components/switch/broadlink.py b/homeassistant/components/switch/broadlink.py index ffa4aaea615..191718a31b3 100644 --- a/homeassistant/components/switch/broadlink.py +++ b/homeassistant/components/switch/broadlink.py @@ -244,10 +244,6 @@ class BroadlinkSP1Switch(BroadlinkRMSwitch): class BroadlinkSP2Switch(BroadlinkSP1Switch): """Representation of an Broadlink switch.""" - def __init__(self, friendly_name, device): - """Initialize the switch.""" - super().__init__(friendly_name, device) - @property def assumed_state(self): """Return true if unable to access real state of entity.""" diff --git a/homeassistant/components/switch/homematic.py b/homeassistant/components/switch/homematic.py index e67f293525c..566eff99828 100644 --- a/homeassistant/components/switch/homematic.py +++ b/homeassistant/components/switch/homematic.py @@ -20,8 +20,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): return devices = [] - for config in discovery_info[ATTR_DISCOVER_DEVICES]: - new_device = HMSwitch(hass, config) + for conf in discovery_info[ATTR_DISCOVER_DEVICES]: + new_device = HMSwitch(hass, conf) new_device.link_homematic() devices.append(new_device) diff --git a/homeassistant/components/switch/hook.py b/homeassistant/components/switch/hook.py index 00fb7fdd909..07425840b9a 100644 --- a/homeassistant/components/switch/hook.py +++ b/homeassistant/components/switch/hook.py @@ -122,7 +122,7 @@ class HookSmartHome(SwitchDevice): return data['return_value'] == '1' @asyncio.coroutine - def async_turn_on(self): + def async_turn_on(self, **kwargs): """Turn the device on asynchronously.""" _LOGGER.debug("Turning on: %s", self._name) url = '{}{}{}{}'.format( @@ -131,7 +131,7 @@ class HookSmartHome(SwitchDevice): self._state = success @asyncio.coroutine - def async_turn_off(self): + def async_turn_off(self, **kwargs): """Turn the device off asynchronously.""" _LOGGER.debug("Turning off: %s", self._name) url = '{}{}{}{}'.format( diff --git a/homeassistant/components/switch/mfi.py b/homeassistant/components/switch/mfi.py index 6f5dd655ba4..c0dc72440d3 100644 --- a/homeassistant/components/switch/mfi.py +++ b/homeassistant/components/switch/mfi.py @@ -47,7 +47,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): password = config.get(CONF_PASSWORD) use_tls = config.get(CONF_SSL) verify_tls = config.get(CONF_VERIFY_SSL) - default_port = use_tls and 6443 or 6080 + default_port = 6443 if use_tls else 6080 port = int(config.get(CONF_PORT, default_port)) from mficlient.client import FailedToLogin, MFiClient @@ -100,12 +100,12 @@ class MfiSwitch(SwitchDevice): self._port.data['output'] = float(self._target_state) self._target_state = None - def turn_on(self): + def turn_on(self, **kwargs): """Turn the switch on.""" self._port.control(True) self._target_state = True - def turn_off(self): + def turn_off(self, **kwargs): """Turn the switch off.""" self._port.control(False) self._target_state = False diff --git a/homeassistant/components/switch/mysensors.py b/homeassistant/components/switch/mysensors.py index c72ea1e4cfe..38f67ee3ee9 100644 --- a/homeassistant/components/switch/mysensors.py +++ b/homeassistant/components/switch/mysensors.py @@ -135,7 +135,7 @@ class MySensorsSwitch(mysensors.MySensorsDeviceEntity, SwitchDevice): return self._values[self.value_type] == STATE_ON return False - def turn_on(self): + def turn_on(self, **kwargs): """Turn the switch on.""" self.gateway.set_child_value( self.node_id, self.child_id, self.value_type, 1) @@ -144,7 +144,7 @@ class MySensorsSwitch(mysensors.MySensorsDeviceEntity, SwitchDevice): self._values[self.value_type] = STATE_ON self.schedule_update_ha_state() - def turn_off(self): + def turn_off(self, **kwargs): """Turn the switch off.""" self.gateway.set_child_value( self.node_id, self.child_id, self.value_type, 0) @@ -191,7 +191,7 @@ class MySensorsIRSwitch(MySensorsSwitch): # turn off switch after switch was turned on self.turn_off() - def turn_off(self): + def turn_off(self, **kwargs): """Turn the IR switch off.""" set_req = self.gateway.const.SetReq if set_req.V_LIGHT not in self._values: diff --git a/homeassistant/components/switch/pulseaudio_loopback.py b/homeassistant/components/switch/pulseaudio_loopback.py index 69b932ecf71..03f9e84b3c8 100644 --- a/homeassistant/components/switch/pulseaudio_loopback.py +++ b/homeassistant/components/switch/pulseaudio_loopback.py @@ -137,8 +137,7 @@ class PAServer(): self._current_module_state) if result and result.group(1).isdigit(): return int(result.group(1)) - else: - return -1 + return -1 class PALoopbackSwitch(SwitchDevice): diff --git a/homeassistant/components/switch/rachio.py b/homeassistant/components/switch/rachio.py index 63809fd4456..b86523ad959 100644 --- a/homeassistant/components/switch/rachio.py +++ b/homeassistant/components/switch/rachio.py @@ -52,18 +52,18 @@ def setup_platform(hass, config, add_devices, discovery_info=None): # Get and persist devices devices = _list_devices(rachio, manual_run_mins) - if len(devices) == 0: + if not devices: _LOGGER.error("No Rachio devices found in account " + person['username']) return False - else: - hass.data[DATA_RACHIO] = devices[0] - if len(devices) > 1: - _LOGGER.warning("Multiple Rachio devices found in account, " - "using " + hass.data[DATA_RACHIO].device_id) - else: - _LOGGER.info("Found Rachio device") + hass.data[DATA_RACHIO] = devices[0] + + if len(devices) > 1: + _LOGGER.warning("Multiple Rachio devices found in account, " + "using " + hass.data[DATA_RACHIO].device_id) + else: + _LOGGER.info("Found Rachio device") hass.data[DATA_RACHIO].update() add_devices(hass.data[DATA_RACHIO].list_zones()) diff --git a/homeassistant/components/switch/rpi_gpio.py b/homeassistant/components/switch/rpi_gpio.py index 18d05db2f28..ac38da1c6a7 100644 --- a/homeassistant/components/switch/rpi_gpio.py +++ b/homeassistant/components/switch/rpi_gpio.py @@ -73,13 +73,13 @@ class RPiGPIOSwitch(ToggleEntity): """Return true if device is on.""" return self._state - def turn_on(self): + def turn_on(self, **kwargs): """Turn the device on.""" rpi_gpio.write_output(self._port, 0 if self._invert_logic else 1) self._state = True self.schedule_update_ha_state() - def turn_off(self): + def turn_off(self, **kwargs): """Turn the device off.""" rpi_gpio.write_output(self._port, 1 if self._invert_logic else 0) self._state = False diff --git a/homeassistant/components/switch/wemo.py b/homeassistant/components/switch/wemo.py index 1c6ad76ceba..972eb2d523e 100644 --- a/homeassistant/components/switch/wemo.py +++ b/homeassistant/components/switch/wemo.py @@ -195,7 +195,7 @@ class WemoSwitch(SwitchDevice): self.wemo.on() self.schedule_update_ha_state() - def turn_off(self): + def turn_off(self, **kwargs): """Turn the switch off.""" self._state = WEMO_OFF self.wemo.off() diff --git a/homeassistant/components/switch/wink.py b/homeassistant/components/switch/wink.py index b5feac5fc43..0076355665c 100644 --- a/homeassistant/components/switch/wink.py +++ b/homeassistant/components/switch/wink.py @@ -37,10 +37,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class WinkToggleDevice(WinkDevice, ToggleEntity): """Representation of a Wink toggle device.""" - def __init__(self, wink, hass): - """Initialize the Wink device.""" - super().__init__(wink, hass) - @asyncio.coroutine def async_added_to_hass(self): """Callback when entity is added to hass.""" diff --git a/homeassistant/components/tellduslive.py b/homeassistant/components/tellduslive.py index f923e09323c..01ccb981cfa 100644 --- a/homeassistant/components/tellduslive.py +++ b/homeassistant/components/tellduslive.py @@ -116,10 +116,9 @@ class TelldusLiveClient(object): return 'cover' elif device.methods & TURNON: return 'switch' - else: - _LOGGER.warning( - "Unidentified device type (methods: %d)", device.methods) - return 'switch' + _LOGGER.warning( + "Unidentified device type (methods: %d)", device.methods) + return 'switch' def discover(device_id, component): """Discover the component.""" diff --git a/homeassistant/components/vera.py b/homeassistant/components/vera.py index cef185bc21f..a156d87187c 100644 --- a/homeassistant/components/vera.py +++ b/homeassistant/components/vera.py @@ -122,8 +122,7 @@ def map_vera_device(vera_device, remap): if isinstance(vera_device, veraApi.VeraSwitch): if vera_device.device_id in remap: return 'light' - else: - return 'switch' + return 'switch' return None diff --git a/homeassistant/components/weather/__init__.py b/homeassistant/components/weather/__init__.py index 17a47fbc522..9e927da893e 100644 --- a/homeassistant/components/weather/__init__.py +++ b/homeassistant/components/weather/__init__.py @@ -165,6 +165,5 @@ class WeatherEntity(Entity): if hass_unit == TEMP_CELSIUS: return round(value, 1) - else: - # Users of fahrenheit generally expect integer units. - return round(value) + # Users of fahrenheit generally expect integer units. + return round(value) diff --git a/homeassistant/components/websocket_api.py b/homeassistant/components/websocket_api.py index 6566a20814b..e9f567c04d3 100644 --- a/homeassistant/components/websocket_api.py +++ b/homeassistant/components/websocket_api.py @@ -29,7 +29,7 @@ from homeassistant.components.http.ban import process_wrong_login DOMAIN = 'websocket_api' URL = '/api/websocket' -DEPENDENCIES = 'http', +DEPENDENCIES = ('http',) MAX_PENDING_MSG = 512 diff --git a/homeassistant/components/wink.py b/homeassistant/components/wink.py index c33e3b14502..1c0410a4aa0 100644 --- a/homeassistant/components/wink.py +++ b/homeassistant/components/wink.py @@ -277,5 +277,4 @@ class WinkDevice(Entity): """Return the devices tamper status.""" if hasattr(self.wink, 'tamper_detected'): return self.wink.tamper_detected() - else: - return None + return None diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py index ba970f94e95..8670ae7b9e7 100755 --- a/homeassistant/components/zwave/__init__.py +++ b/homeassistant/components/zwave/__init__.py @@ -450,12 +450,11 @@ def setup(hass, config): "with selection %s", param, node_id, selection) return - else: - value.data = int(selection) - _LOGGER.info("Setting config parameter %s on Node %s " - "with selection %s", param, node_id, - selection) - return + value.data = int(selection) + _LOGGER.info("Setting config parameter %s on Node %s " + "with selection %s", param, node_id, + selection) + return node.set_config_param(param, selection, size) _LOGGER.info("Setting unknown config parameter %s on Node %s " "with selection %s", param, node_id, diff --git a/homeassistant/core.py b/homeassistant/core.py index c65566b42fa..d1779fe420d 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -335,9 +335,9 @@ class Event(object): return "".format( self.event_type, str(self.origin)[0], util.repr_helper(self.data)) - else: - return "".format(self.event_type, - str(self.origin)[0]) + + return "".format(self.event_type, + str(self.origin)[0]) def __eq__(self, other): """Return the comparison.""" @@ -783,8 +783,8 @@ class ServiceCall(object): if self.data: return "".format( self.domain, self.service, util.repr_helper(self.data)) - else: - return "".format(self.domain, self.service) + + return "".format(self.domain, self.service) class ServiceRegistry(object): diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index dc6c29ce735..da177bc4331 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -172,6 +172,7 @@ class Entity(object): if async_update is None: return + # pylint: disable=not-callable run_coroutine_threadsafe(async_update(), self.hass.loop).result() # DO NOT OVERWRITE @@ -391,5 +392,4 @@ class ToggleEntity(Entity): """ if self.is_on: return self.async_turn_off() - else: - return self.async_turn_on() + return self.async_turn_on() diff --git a/homeassistant/helpers/event.py b/homeassistant/helpers/event.py index d3ad93d3646..9b64c08af18 100644 --- a/homeassistant/helpers/event.py +++ b/homeassistant/helpers/event.py @@ -312,8 +312,7 @@ def _process_state_match(parameter): return MATCH_ALL elif isinstance(parameter, str) or not hasattr(parameter, '__iter__'): return (parameter,) - else: - return tuple(parameter) + return tuple(parameter) def _process_time_match(parameter): @@ -324,8 +323,7 @@ def _process_time_match(parameter): return parameter elif isinstance(parameter, str) or not hasattr(parameter, '__iter__'): return (parameter,) - else: - return tuple(parameter) + return tuple(parameter) def _matcher(subject, pattern): diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index 77d0819e10d..6c74c49424e 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -47,7 +47,7 @@ def extract_entities(template): return MATCH_ALL extraction = _RE_GET_ENTITIES.findall(template) - if len(extraction) > 0: + if extraction: return list(set(extraction)) return MATCH_ALL diff --git a/homeassistant/remote.py b/homeassistant/remote.py index b65b3f3de22..9d026eddeff 100644 --- a/homeassistant/remote.py +++ b/homeassistant/remote.py @@ -92,10 +92,10 @@ class API(object): if method == METHOD_GET: return requests.get( url, params=data, timeout=timeout, headers=self._headers) - else: - return requests.request( - method, url, data=data, timeout=timeout, - headers=self._headers) + + return requests.request( + method, url, data=data, timeout=timeout, + headers=self._headers) except requests.exceptions.ConnectionError: _LOGGER.exception("Error connecting to server") @@ -152,8 +152,7 @@ def validate_api(api): elif req.status_code == 401: return APIStatus.INVALID_PASSWORD - else: - return APIStatus.UNKNOWN + return APIStatus.UNKNOWN except HomeAssistantError: return APIStatus.CANNOT_CONNECT @@ -259,8 +258,8 @@ def set_state(api, entity_id, new_state, attributes=None, force_update=False): _LOGGER.error("Error changing state: %d - %s", req.status_code, req.text) return False - else: - return True + + return True except HomeAssistantError: _LOGGER.exception("Error setting state") diff --git a/homeassistant/scripts/check_config.py b/homeassistant/scripts/check_config.py index 1e06f96b3e4..05cf4d646f6 100644 --- a/homeassistant/scripts/check_config.py +++ b/homeassistant/scripts/check_config.py @@ -288,7 +288,7 @@ def dump_dict(layer, indent_count=3, listi=False, **kwargs): indent_str = indent_str[:-1] + '-' if isinstance(layer, Dict): for key, value in sorted(layer.items(), key=sort_dict_key): - if isinstance(value, dict) or isinstance(value, list): + if isinstance(value, (dict, list)): print(indent_str, key + ':', line_info(value, **kwargs)) dump_dict(value, indent_count + 2) else: diff --git a/homeassistant/util/__init__.py b/homeassistant/util/__init__.py index 616b9100815..fc9116dda52 100644 --- a/homeassistant/util/__init__.py +++ b/homeassistant/util/__init__.py @@ -56,8 +56,8 @@ def repr_helper(inp: Any) -> str: in inp.items()) elif isinstance(inp, datetime): return as_local(inp).isoformat() - else: - return str(inp) + + return str(inp) def convert(value: T, to_type: Callable[[T], U], @@ -303,8 +303,8 @@ class Throttle(object): result = method(*args, **kwargs) throttle[1] = utcnow() return result - else: - return None + + return None finally: throttle[0].release() diff --git a/homeassistant/util/temperature.py b/homeassistant/util/temperature.py index adaa8afcb57..b7e2412f293 100644 --- a/homeassistant/util/temperature.py +++ b/homeassistant/util/temperature.py @@ -26,5 +26,4 @@ def convert(temperature: float, from_unit: str, to_unit: str) -> float: return temperature elif from_unit == TEMP_CELSIUS: return celsius_to_fahrenheit(temperature) - else: - return fahrenheit_to_celsius(temperature) + return fahrenheit_to_celsius(temperature) From 46e030662da4ab7c653a23e1f34e527c9a0e7a8f Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 5 Jul 2017 23:30:01 -0700 Subject: [PATCH 042/131] Fix pylint 1.7.2 no-else-return issues (#8361) * Fix pylint 1.7.2 no-else-return issues * Update tomato.py --- .../alarm_control_panel/alarmdotcom.py | 3 +- .../alarm_control_panel/envisalink.py | 3 +- .../components/alarm_control_panel/manual.py | 3 +- .../alarm_control_panel/simplisafe.py | 3 +- .../components/binary_sensor/flic.py | 9 ++-- .../components/binary_sensor/homematic.py | 4 +- .../components/binary_sensor/netatmo.py | 3 +- .../components/binary_sensor/ping.py | 16 +++---- .../components/binary_sensor/volvooncall.py | 3 +- homeassistant/components/calendar/__init__.py | 3 +- homeassistant/components/camera/__init__.py | 3 +- homeassistant/components/camera/netatmo.py | 3 +- homeassistant/components/climate/__init__.py | 11 ++--- homeassistant/components/climate/ecobee.py | 28 +++++-------- .../components/climate/generic_thermostat.py | 18 ++++---- homeassistant/components/climate/honeywell.py | 7 ++-- homeassistant/components/climate/nest.py | 17 +++----- homeassistant/components/climate/oem.py | 3 +- homeassistant/components/climate/sensibo.py | 5 +-- homeassistant/components/climate/tado.py | 24 ++++------- homeassistant/components/climate/wink.py | 20 ++++----- homeassistant/components/climate/zwave.py | 3 +- .../components/cover/command_line.py | 5 +-- homeassistant/components/cover/demo.py | 3 +- homeassistant/components/cover/garadget.py | 3 +- homeassistant/components/cover/homematic.py | 9 ++-- homeassistant/components/cover/mqtt.py | 3 +- homeassistant/components/cover/mysensors.py | 3 +- homeassistant/components/cover/opengarage.py | 3 +- homeassistant/components/cover/vera.py | 5 +-- homeassistant/components/cover/zwave.py | 6 +-- .../components/device_tracker/bbox.py | 3 +- .../components/device_tracker/locative.py | 23 +++++----- .../components/device_tracker/nmap_tracker.py | 3 +- .../components/device_tracker/owntracks.py | 3 +- .../components/device_tracker/tado.py | 3 +- .../components/device_tracker/tomato.py | 4 +- .../components/device_tracker/tplink.py | 7 ++-- .../components/device_tracker/xiaomi.py | 8 ++-- homeassistant/components/fan/dyson.py | 3 +- homeassistant/components/fan/wink.py | 4 -- .../image_processing/dlib_face_identify.py | 4 +- homeassistant/components/light/tellstick.py | 3 +- homeassistant/components/light/vera.py | 3 +- homeassistant/components/light/wink.py | 7 +--- homeassistant/components/light/zwave.py | 6 +-- homeassistant/components/lock/lockitron.py | 8 ++-- homeassistant/components/lock/wink.py | 4 -- .../components/media_player/anthemav.py | 3 +- .../components/media_player/apple_tv.py | 3 +- .../components/media_player/braviatv.py | 6 +-- homeassistant/components/media_player/cmus.py | 3 +- .../components/media_player/denon.py | 6 +-- .../components/media_player/directv.py | 7 ++-- homeassistant/components/media_player/emby.py | 3 +- .../components/media_player/itunes.py | 22 +++++----- homeassistant/components/media_player/kodi.py | 34 +++++++-------- .../components/media_player/liveboxplaytv.py | 5 +-- .../components/media_player/mpchc.py | 4 +- homeassistant/components/media_player/mpd.py | 8 ++-- .../components/media_player/pandora.py | 12 +++--- .../components/media_player/pioneer.py | 3 -- homeassistant/components/media_player/plex.py | 16 +++---- .../components/media_player/sonos.py | 42 +++++++++---------- .../components/media_player/soundtouch.py | 8 ++-- .../components/media_player/universal.py | 4 +- .../components/media_player/volumio.py | 10 ++--- .../components/media_player/yamaha.py | 4 +- homeassistant/components/notify/mailgun.py | 4 +- homeassistant/components/notify/smtp.py | 4 +- homeassistant/components/recorder/models.py | 4 +- homeassistant/components/scene/lifx_cloud.py | 6 +-- homeassistant/components/sensor/arwn.py | 5 +-- homeassistant/components/sensor/bom.py | 10 ++--- homeassistant/components/sensor/buienradar.py | 4 +- homeassistant/components/sensor/darksky.py | 10 ++--- homeassistant/components/sensor/dsmr.py | 14 +++---- homeassistant/components/sensor/dyson.py | 3 +- .../sensor/eddystone_temperature.py | 3 +- .../components/sensor/eight_sleep.py | 7 ++-- .../components/sensor/fritzbox_callmonitor.py | 13 ++---- homeassistant/components/sensor/glances.py | 3 +- homeassistant/components/sensor/gpsd.py | 3 +- homeassistant/components/sensor/hddtemp.py | 3 +- .../components/sensor/history_stats.py | 3 +- homeassistant/components/sensor/ios.py | 3 +- homeassistant/components/sensor/isy994.py | 3 +- homeassistant/components/sensor/kwb.py | 3 +- homeassistant/components/sensor/metoffice.py | 6 +-- homeassistant/components/sensor/moon.py | 3 +- homeassistant/components/sensor/mvglive.py | 3 +- homeassistant/components/sensor/neato.py | 5 +-- homeassistant/components/sensor/netdata.py | 5 +-- homeassistant/components/sensor/ohmconnect.py | 3 +- homeassistant/components/sensor/pvoutput.py | 6 +-- homeassistant/components/sensor/qnap.py | 3 +- .../sensor/swiss_hydrological_data.py | 3 +- .../components/sensor/synologydsm.py | 16 ++++--- homeassistant/components/sensor/tado.py | 5 +-- .../components/sensor/tellduslive.py | 3 +- homeassistant/components/sensor/time_date.py | 3 +- .../components/sensor/volvooncall.py | 3 +- homeassistant/components/sensor/waqi.py | 5 +-- .../components/sensor/wunderground.py | 3 +- homeassistant/components/sensor/zwave.py | 3 +- homeassistant/components/switch/neato.py | 5 +-- homeassistant/components/switch/rachio.py | 6 +-- homeassistant/components/switch/wemo.py | 6 +-- .../components/telegram_bot/webhooks.py | 3 +- homeassistant/components/tts/google.py | 3 +- homeassistant/remote.py | 20 ++++----- 111 files changed, 305 insertions(+), 455 deletions(-) diff --git a/homeassistant/components/alarm_control_panel/alarmdotcom.py b/homeassistant/components/alarm_control_panel/alarmdotcom.py index 75d3bc9922d..d5c15d82396 100644 --- a/homeassistant/components/alarm_control_panel/alarmdotcom.py +++ b/homeassistant/components/alarm_control_panel/alarmdotcom.py @@ -92,8 +92,7 @@ class AlarmDotCom(alarm.AlarmControlPanel): return STATE_ALARM_ARMED_HOME elif self._alarm.state.lower() == 'armed away': return STATE_ALARM_ARMED_AWAY - else: - return STATE_UNKNOWN + return STATE_UNKNOWN @asyncio.coroutine def async_alarm_disarm(self, code=None): diff --git a/homeassistant/components/alarm_control_panel/envisalink.py b/homeassistant/components/alarm_control_panel/envisalink.py index 6029816ba76..f6d388a6c5b 100644 --- a/homeassistant/components/alarm_control_panel/envisalink.py +++ b/homeassistant/components/alarm_control_panel/envisalink.py @@ -113,8 +113,7 @@ class EnvisalinkAlarm(EnvisalinkDevice, alarm.AlarmControlPanel): """Regex for code format or None if no code is required.""" if self._code: return None - else: - return '^\\d{4,6}$' + return '^\\d{4,6}$' @property def state(self): diff --git a/homeassistant/components/alarm_control_panel/manual.py b/homeassistant/components/alarm_control_panel/manual.py index ba932a1c372..c87aea862d5 100644 --- a/homeassistant/components/alarm_control_panel/manual.py +++ b/homeassistant/components/alarm_control_panel/manual.py @@ -99,8 +99,7 @@ class ManualAlarm(alarm.AlarmControlPanel): self._trigger_time) < dt_util.utcnow(): if self._disarm_after_trigger: return STATE_ALARM_DISARMED - else: - return self._pre_trigger_state + return self._pre_trigger_state return self._state diff --git a/homeassistant/components/alarm_control_panel/simplisafe.py b/homeassistant/components/alarm_control_panel/simplisafe.py index 985d219865d..fadfbc41a6f 100644 --- a/homeassistant/components/alarm_control_panel/simplisafe.py +++ b/homeassistant/components/alarm_control_panel/simplisafe.py @@ -80,8 +80,7 @@ class SimpliSafeAlarm(alarm.AlarmControlPanel): """Return the name of the device.""" if self._name is not None: return self._name - else: - return 'Alarm {}'.format(self.simplisafe.location_id()) + return 'Alarm {}'.format(self.simplisafe.location_id()) @property def code_format(self): diff --git a/homeassistant/components/binary_sensor/flic.py b/homeassistant/components/binary_sensor/flic.py index f78ee75ae25..51fffae5cc0 100644 --- a/homeassistant/components/binary_sensor/flic.py +++ b/homeassistant/components/binary_sensor/flic.py @@ -199,11 +199,10 @@ class FlicButton(BinarySensorDevice): "Queued %s dropped for %s. Time in queue was %s", click_type, self.address, time_string) return True - else: - _LOGGER.info( - "Queued %s allowed for %s. Time in queue was %s", - click_type, self.address, time_string) - return False + _LOGGER.info( + "Queued %s allowed for %s. Time in queue was %s", + click_type, self.address, time_string) + return False def _on_up_down(self, channel, click_type, was_queued, time_diff): """Update device state, if event was not queued.""" diff --git a/homeassistant/components/binary_sensor/homematic.py b/homeassistant/components/binary_sensor/homematic.py index 29ad5847b32..a82431a5ab8 100644 --- a/homeassistant/components/binary_sensor/homematic.py +++ b/homeassistant/components/binary_sensor/homematic.py @@ -34,8 +34,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): return devices = [] - for config in discovery_info[ATTR_DISCOVER_DEVICES]: - new_device = HMBinarySensor(hass, config) + for conf in discovery_info[ATTR_DISCOVER_DEVICES]: + new_device = HMBinarySensor(hass, conf) new_device.link_homematic() devices.append(new_device) diff --git a/homeassistant/components/binary_sensor/netatmo.py b/homeassistant/components/binary_sensor/netatmo.py index 70887e9391d..ac479ef4277 100644 --- a/homeassistant/components/binary_sensor/netatmo.py +++ b/homeassistant/components/binary_sensor/netatmo.py @@ -156,8 +156,7 @@ class NetatmoBinarySensor(BinarySensorDevice): return WELCOME_SENSOR_TYPES.get(self._sensor_name) elif self._cameratype == 'NOC': return PRESENCE_SENSOR_TYPES.get(self._sensor_name) - else: - return TAG_SENSOR_TYPES.get(self._sensor_name) + return TAG_SENSOR_TYPES.get(self._sensor_name) @property def is_on(self): diff --git a/homeassistant/components/binary_sensor/ping.py b/homeassistant/components/binary_sensor/ping.py index 4a23b2e42ca..cb5bc4333a2 100644 --- a/homeassistant/components/binary_sensor/ping.py +++ b/homeassistant/components/binary_sensor/ping.py @@ -126,14 +126,14 @@ class PingData(object): 'avg': rtt_avg, 'max': rtt_max, 'mdev': ''} - else: - match = PING_MATCHER.search(str(out).split('\n')[-1]) - rtt_min, rtt_avg, rtt_max, rtt_mdev = match.groups() - return { - 'min': rtt_min, - 'avg': rtt_avg, - 'max': rtt_max, - 'mdev': rtt_mdev} + + match = PING_MATCHER.search(str(out).split('\n')[-1]) + rtt_min, rtt_avg, rtt_max, rtt_mdev = match.groups() + return { + 'min': rtt_min, + 'avg': rtt_avg, + 'max': rtt_max, + 'mdev': rtt_mdev} except (subprocess.CalledProcessError, AttributeError): return False diff --git a/homeassistant/components/binary_sensor/volvooncall.py b/homeassistant/components/binary_sensor/volvooncall.py index 2c7c398d91a..471b3917054 100644 --- a/homeassistant/components/binary_sensor/volvooncall.py +++ b/homeassistant/components/binary_sensor/volvooncall.py @@ -30,8 +30,7 @@ class VolvoSensor(VolvoEntity, BinarySensorDevice): return bool(val) elif self._attribute in ['doors', 'windows']: return any([val[key] for key in val if 'Open' in key]) - else: - return val != 'Normal' + return val != 'Normal' @property def device_class(self): diff --git a/homeassistant/components/calendar/__init__.py b/homeassistant/components/calendar/__init__.py index 2ccd591db2c..4e088c8a640 100644 --- a/homeassistant/components/calendar/__init__.py +++ b/homeassistant/components/calendar/__init__.py @@ -148,8 +148,7 @@ class CalendarEventDevice(Entity): if 'date' in date: return dt.start_of_local_day(dt.dt.datetime.combine( dt.parse_date(date['date']), dt.dt.time.min)) - else: - return dt.as_local(dt.parse_datetime(date['dateTime'])) + return dt.as_local(dt.parse_datetime(date['dateTime'])) start = _get_date(self.data.event['start']) end = _get_date(self.data.event['end']) diff --git a/homeassistant/components/camera/__init__.py b/homeassistant/components/camera/__init__.py index c84421f50ea..5b97e102d8d 100644 --- a/homeassistant/components/camera/__init__.py +++ b/homeassistant/components/camera/__init__.py @@ -266,8 +266,7 @@ class Camera(Entity): return STATE_RECORDING elif self.is_streaming: return STATE_STREAMING - else: - return STATE_IDLE + return STATE_IDLE def enable_motion_detection(self): """Enable motion detection in the camera.""" diff --git a/homeassistant/components/camera/netatmo.py b/homeassistant/components/camera/netatmo.py index e5f22cced16..c1ec2db0a08 100644 --- a/homeassistant/components/camera/netatmo.py +++ b/homeassistant/components/camera/netatmo.py @@ -113,8 +113,7 @@ class NetatmoCamera(Camera): return "Presence" elif self._cameratype == "NACamera": return "Welcome" - else: - return None + return None @property def unique_id(self): diff --git a/homeassistant/components/climate/__init__.py b/homeassistant/components/climate/__init__.py index d00d30c3b19..5b6c025b3e3 100644 --- a/homeassistant/components/climate/__init__.py +++ b/homeassistant/components/climate/__init__.py @@ -398,16 +398,14 @@ class ClimateDevice(Entity): """Return the current state.""" if self.current_operation: return self.current_operation - else: - return STATE_UNKNOWN + return STATE_UNKNOWN @property def precision(self): """Return the precision of the system.""" if self.unit_of_measurement == TEMP_CELSIUS: return PRECISION_TENTHS - else: - return PRECISION_WHOLE + return PRECISION_WHOLE @property def state_attributes(self): @@ -709,6 +707,5 @@ class ClimateDevice(Entity): return round(temp * 2) / 2.0 elif self.precision == PRECISION_TENTHS: return round(temp, 1) - else: - # PRECISION_WHOLE as a fall back - return round(temp) + # PRECISION_WHOLE as a fall back + return round(temp) diff --git a/homeassistant/components/climate/ecobee.py b/homeassistant/components/climate/ecobee.py index 9e04013d53f..6780d3745f0 100644 --- a/homeassistant/components/climate/ecobee.py +++ b/homeassistant/components/climate/ecobee.py @@ -151,16 +151,14 @@ class Thermostat(ClimateDevice): """Return the lower bound temperature we try to reach.""" if self.current_operation == STATE_AUTO: return int(self.thermostat['runtime']['desiredHeat'] / 10) - else: - return None + return None @property def target_temperature_high(self): """Return the upper bound temperature we try to reach.""" if self.current_operation == STATE_AUTO: return int(self.thermostat['runtime']['desiredCool'] / 10) - else: - return None + return None @property def target_temperature(self): @@ -171,8 +169,7 @@ class Thermostat(ClimateDevice): return int(self.thermostat['runtime']['desiredHeat'] / 10) elif self.current_operation == STATE_COOL: return int(self.thermostat['runtime']['desiredCool'] / 10) - else: - return None + return None @property def desired_fan_mode(self): @@ -184,8 +181,7 @@ class Thermostat(ClimateDevice): """Return the current fan state.""" if 'fan' in self.thermostat['equipmentStatus']: return STATE_ON - else: - return STATE_OFF + return STATE_OFF @property def current_hold_mode(self): @@ -199,15 +195,13 @@ class Thermostat(ClimateDevice): int(event['startDate'][0:4]) <= 1: # A temporary hold from away climate is a hold return 'away' - else: - # A permanent hold from away climate is away_mode - return None + # A permanent hold from away climate is away_mode + return None elif event['holdClimateRef'] != "": # Any other hold based on climate return event['holdClimateRef'] - else: - # Any hold not based on a climate is a temp hold - return TEMPERATURE_HOLD + # Any hold not based on a climate is a temp hold + return TEMPERATURE_HOLD elif event['type'].startswith('auto'): # All auto modes are treated as holds return event['type'][4:].lower() @@ -222,8 +216,7 @@ class Thermostat(ClimateDevice): if self.operation_mode == 'auxHeatOnly' or \ self.operation_mode == 'heatPump': return STATE_HEAT - else: - return self.operation_mode + return self.operation_mode @property def operation_list(self): @@ -384,8 +377,7 @@ class Thermostat(ClimateDevice): # add further conditions if other hold durations should be # supported; note that this should not include 'indefinite' # as an indefinite away hold is interpreted as away_mode - else: - return 'nextTransition' + return 'nextTransition' @property def climate_list(self): diff --git a/homeassistant/components/climate/generic_thermostat.py b/homeassistant/components/climate/generic_thermostat.py index 11400466c4f..6e7ba3cffed 100644 --- a/homeassistant/components/climate/generic_thermostat.py +++ b/homeassistant/components/climate/generic_thermostat.py @@ -134,9 +134,9 @@ class GenericThermostat(ClimateDevice): if self.ac_mode: cooling = self._active and self._is_device_active return STATE_COOL if cooling else STATE_IDLE - else: - heating = self._active and self._is_device_active - return STATE_HEAT if heating else STATE_IDLE + + heating = self._active and self._is_device_active + return STATE_HEAT if heating else STATE_IDLE @property def target_temperature(self): @@ -159,9 +159,9 @@ class GenericThermostat(ClimateDevice): # pylint: disable=no-member if self._min_temp: return self._min_temp - else: - # get default temp from super class - return ClimateDevice.min_temp.fget(self) + + # get default temp from super class + return ClimateDevice.min_temp.fget(self) @property def max_temp(self): @@ -169,9 +169,9 @@ class GenericThermostat(ClimateDevice): # pylint: disable=no-member if self._max_temp: return self._max_temp - else: - # Get default temp from super class - return ClimateDevice.max_temp.fget(self) + + # Get default temp from super class + return ClimateDevice.max_temp.fget(self) @asyncio.coroutine def _async_sensor_changed(self, entity_id, old_state, new_state): diff --git a/homeassistant/components/climate/honeywell.py b/homeassistant/components/climate/honeywell.py index 94c48258bf5..65e30e3cb26 100644 --- a/homeassistant/components/climate/honeywell.py +++ b/homeassistant/components/climate/honeywell.py @@ -60,8 +60,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if region == 'us': return _setup_us(username, password, config, add_devices) - else: - return _setup_round(username, password, config, add_devices) + + return _setup_round(username, password, config, add_devices) def _setup_round(username, password, config, add_devices): @@ -251,8 +251,7 @@ class HoneywellUSThermostat(ClimateDevice): """Return the temperature we try to reach.""" if self._device.system_mode == 'cool': return self._device.setpoint_cool - else: - return self._device.setpoint_heat + return self._device.setpoint_heat @property def current_operation(self: ClimateDevice) -> str: diff --git a/homeassistant/components/climate/nest.py b/homeassistant/components/climate/nest.py index 522a1bebb16..ac4f64f4ec8 100644 --- a/homeassistant/components/climate/nest.py +++ b/homeassistant/components/climate/nest.py @@ -109,16 +109,14 @@ class NestThermostat(ClimateDevice): return self._mode elif self._mode == STATE_HEAT_COOL: return STATE_AUTO - else: - return STATE_UNKNOWN + return STATE_UNKNOWN @property def target_temperature(self): """Return the temperature we try to reach.""" if self._mode != STATE_HEAT_COOL and not self.is_away_mode_on: return self._target_temperature - else: - return None + return None @property def target_temperature_low(self): @@ -129,8 +127,7 @@ class NestThermostat(ClimateDevice): return self._eco_temperature[0] if self._mode == STATE_HEAT_COOL: return self._target_temperature[0] - else: - return None + return None @property def target_temperature_high(self): @@ -141,8 +138,7 @@ class NestThermostat(ClimateDevice): return self._eco_temperature[1] if self._mode == STATE_HEAT_COOL: return self._target_temperature[1] - else: - return None + return None @property def is_away_mode_on(self): @@ -188,9 +184,8 @@ class NestThermostat(ClimateDevice): if self._has_fan: # Return whether the fan is on return STATE_ON if self._fan else STATE_AUTO - else: - # No Fan available so disable slider - return None + # No Fan available so disable slider + return None @property def fan_list(self): diff --git a/homeassistant/components/climate/oem.py b/homeassistant/components/climate/oem.py index fd43ff799db..5909f26eb4f 100644 --- a/homeassistant/components/climate/oem.py +++ b/homeassistant/components/climate/oem.py @@ -92,8 +92,7 @@ class ThermostatDevice(ClimateDevice): """Return current operation i.e. heat, cool, idle.""" if self._state: return STATE_HEAT - else: - return STATE_IDLE + return STATE_IDLE @property def current_temperature(self): diff --git a/homeassistant/components/climate/sensibo.py b/homeassistant/components/climate/sensibo.py index 501a346d8c5..c55b4c9ce0d 100644 --- a/homeassistant/components/climate/sensibo.py +++ b/homeassistant/components/climate/sensibo.py @@ -117,9 +117,8 @@ class SensiboClimate(ClimateDevice): # We are working in same units as the a/c unit. Use whole degrees # like the API supports. return 1 - else: - # Unit conversion is going on. No point to stick to specific steps. - return None + # Unit conversion is going on. No point to stick to specific steps. + return None @property def current_operation(self): diff --git a/homeassistant/components/climate/tado.py b/homeassistant/components/climate/tado.py index 832bca6f9b6..8a2e6621af3 100644 --- a/homeassistant/components/climate/tado.py +++ b/homeassistant/components/climate/tado.py @@ -52,7 +52,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): zones = tado.get_zones() except RuntimeError: _LOGGER.error("Unable to get zone info from mytado") - return False + return climate_devices = [] for zone in zones: @@ -61,9 +61,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if climate_devices: add_devices(climate_devices, True) - return True - else: - return False def create_climate_device(tado, hass, zone, name, zone_id): @@ -150,8 +147,7 @@ class TadoClimate(ClimateDevice): """Return current readable operation mode.""" if self._cooling: return "Cooling" - else: - return OPERATION_LIST.get(self._current_operation) + return OPERATION_LIST.get(self._current_operation) @property def operation_list(self): @@ -163,16 +159,14 @@ class TadoClimate(ClimateDevice): """Return the fan setting.""" if self.ac_mode: return FAN_MODES_LIST.get(self._current_fan) - else: - return None + return None @property def fan_list(self): """List of available fan modes.""" if self.ac_mode: return list(FAN_MODES_LIST.values()) - else: - return None + return None @property def temperature_unit(self): @@ -218,18 +212,16 @@ class TadoClimate(ClimateDevice): """Return the minimum temperature.""" if self._min_temp: return self._min_temp - else: - # get default temp from super class - return super().min_temp + # get default temp from super class + return super().min_temp @property def max_temp(self): """Return the maximum temperature.""" if self._max_temp: return self._max_temp - else: - # Get default temp from super class - return super().max_temp + # Get default temp from super class + return super().max_temp def update(self): """Update the state of this climate device.""" diff --git a/homeassistant/components/climate/wink.py b/homeassistant/components/climate/wink.py index e3439bdfc74..f52340dc627 100644 --- a/homeassistant/components/climate/wink.py +++ b/homeassistant/components/climate/wink.py @@ -111,8 +111,8 @@ class WinkThermostat(WinkDevice, ClimateDevice): # This will address both possibilities if self.wink.current_humidity() < 1: return self.wink.current_humidity() * 100 - else: - return self.wink.current_humidity() + return self.wink.current_humidity() + return None @property def external_temperature(self): @@ -175,10 +175,7 @@ class WinkThermostat(WinkDevice, ClimateDevice): return self.wink.current_max_set_point() elif self.current_operation == STATE_HEAT: return self.wink.current_min_set_point() - else: - return None - else: - return None + return None @property def target_temperature_low(self): @@ -206,8 +203,7 @@ class WinkThermostat(WinkDevice, ClimateDevice): return True elif self.wink.current_hvac_mode() == 'aux' and not self.wink.is_on(): return False - else: - return None + return None def set_temperature(self, **kwargs): """Set new target temperature.""" @@ -270,9 +266,8 @@ class WinkThermostat(WinkDevice, ClimateDevice): return STATE_ON elif self.wink.current_fan_mode() == 'auto': return STATE_AUTO - else: - # No Fan available so disable slider - return None + # No Fan available so disable slider + return None @property def fan_list(self): @@ -451,8 +446,7 @@ class WinkAC(WinkDevice, ClimateDevice): return SPEED_MEDIUM elif speed <= 1.0 and speed > 0.8: return SPEED_HIGH - else: - return STATE_UNKNOWN + return STATE_UNKNOWN @property def fan_list(self): diff --git a/homeassistant/components/climate/zwave.py b/homeassistant/components/climate/zwave.py index 949bd10e0c2..497916a3e4d 100755 --- a/homeassistant/components/climate/zwave.py +++ b/homeassistant/components/climate/zwave.py @@ -154,8 +154,7 @@ class ZWaveClimate(ZWaveDeviceEntity, ClimateDevice): return TEMP_CELSIUS elif self._unit == 'F': return TEMP_FAHRENHEIT - else: - return self._unit + return self._unit @property def current_temperature(self): diff --git a/homeassistant/components/cover/command_line.py b/homeassistant/components/cover/command_line.py index cd48238cae9..6d43b1d2166 100644 --- a/homeassistant/components/cover/command_line.py +++ b/homeassistant/components/cover/command_line.py @@ -112,10 +112,7 @@ class CommandCover(CoverDevice): def is_closed(self): """Return if the cover is closed.""" if self.current_cover_position is not None: - if self.current_cover_position > 0: - return False - else: - return True + return self.current_cover_position == 0 @property def current_cover_position(self): diff --git a/homeassistant/components/cover/demo.py b/homeassistant/components/cover/demo.py index 35574150596..ed060659746 100644 --- a/homeassistant/components/cover/demo.py +++ b/homeassistant/components/cover/demo.py @@ -79,8 +79,7 @@ class DemoCover(CoverDevice): """Flag supported features.""" if self._supported_features is not None: return self._supported_features - else: - return super().supported_features + return super().supported_features def close_cover(self, **kwargs): """Close the cover.""" diff --git a/homeassistant/components/cover/garadget.py b/homeassistant/components/cover/garadget.py index 457312c8a4a..02e970a0d0b 100644 --- a/homeassistant/components/cover/garadget.py +++ b/homeassistant/components/cover/garadget.py @@ -159,8 +159,7 @@ class GaradgetCover(CoverDevice): """Return if the cover is closed.""" if self._state == STATE_UNKNOWN: return None - else: - return self._state == STATE_CLOSED + return self._state == STATE_CLOSED @property def device_class(self): diff --git a/homeassistant/components/cover/homematic.py b/homeassistant/components/cover/homematic.py index 8fb003c6649..e8372b84ce4 100644 --- a/homeassistant/components/cover/homematic.py +++ b/homeassistant/components/cover/homematic.py @@ -20,8 +20,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): return devices = [] - for config in discovery_info[ATTR_DISCOVER_DEVICES]: - new_device = HMCover(hass, config) + for conf in discovery_info[ATTR_DISCOVER_DEVICES]: + new_device = HMCover(hass, conf) new_device.link_homematic() devices.append(new_device) @@ -52,10 +52,7 @@ class HMCover(HMDevice, CoverDevice): def is_closed(self): """Return if the cover is closed.""" if self.current_cover_position is not None: - if self.current_cover_position > 0: - return False - else: - return True + return self.current_cover_position == 0 def open_cover(self, **kwargs): """Open the cover.""" diff --git a/homeassistant/components/cover/mqtt.py b/homeassistant/components/cover/mqtt.py index a53e659c448..eab64fd7abb 100644 --- a/homeassistant/components/cover/mqtt.py +++ b/homeassistant/components/cover/mqtt.py @@ -361,8 +361,7 @@ class MqttCover(CoverDevice): position_percentage = float(offset_position) / tilt_range * 100.0 if self._tilt_invert: return 100 - position_percentage - else: - return position_percentage + return position_percentage def find_in_range_from_percent(self, percentage): """ diff --git a/homeassistant/components/cover/mysensors.py b/homeassistant/components/cover/mysensors.py index 43942dacd05..f48a2110eca 100644 --- a/homeassistant/components/cover/mysensors.py +++ b/homeassistant/components/cover/mysensors.py @@ -53,8 +53,7 @@ class MySensorsCover(mysensors.MySensorsDeviceEntity, CoverDevice): set_req = self.gateway.const.SetReq if set_req.V_DIMMER in self._values: return self._values.get(set_req.V_DIMMER) == 0 - else: - return self._values.get(set_req.V_LIGHT) == STATE_OFF + return self._values.get(set_req.V_LIGHT) == STATE_OFF @property def current_cover_position(self): diff --git a/homeassistant/components/cover/opengarage.py b/homeassistant/components/cover/opengarage.py index d22e8f9104c..d98c71e25fb 100644 --- a/homeassistant/components/cover/opengarage.py +++ b/homeassistant/components/cover/opengarage.py @@ -117,8 +117,7 @@ class OpenGarageCover(CoverDevice): """Return if the cover is closed.""" if self._state == STATE_UNKNOWN: return None - else: - return self._state in [STATE_CLOSED, STATE_OPENING] + return self._state in [STATE_CLOSED, STATE_OPENING] def close_cover(self): """Close the cover.""" diff --git a/homeassistant/components/cover/vera.py b/homeassistant/components/cover/vera.py index bcccf17da8a..05be125ec6f 100644 --- a/homeassistant/components/cover/vera.py +++ b/homeassistant/components/cover/vera.py @@ -53,10 +53,7 @@ class VeraCover(VeraDevice, CoverDevice): def is_closed(self): """Return if the cover is closed.""" if self.current_cover_position is not None: - if self.current_cover_position > 0: - return False - else: - return True + return self.current_cover_position == 0 def open_cover(self, **kwargs): """Open the cover.""" diff --git a/homeassistant/components/cover/zwave.py b/homeassistant/components/cover/zwave.py index b682bee3e20..6ec70d9a85a 100644 --- a/homeassistant/components/cover/zwave.py +++ b/homeassistant/components/cover/zwave.py @@ -73,8 +73,7 @@ class ZwaveRollershutter(zwave.ZWaveDeviceEntity, CoverDevice): return None if self.current_cover_position > 0: return False - else: - return True + return True @property def current_cover_position(self): @@ -86,8 +85,7 @@ class ZwaveRollershutter(zwave.ZWaveDeviceEntity, CoverDevice): return 0 elif self._current_position >= 95: return 100 - else: - return self._current_position + return self._current_position def open_cover(self, **kwargs): """Move the roller shutter up.""" diff --git a/homeassistant/components/device_tracker/bbox.py b/homeassistant/components/device_tracker/bbox.py index 0d0cdd7b1d5..23a94d093e2 100644 --- a/homeassistant/components/device_tracker/bbox.py +++ b/homeassistant/components/device_tracker/bbox.py @@ -52,8 +52,7 @@ class BboxDeviceScanner(DeviceScanner): if filter_named: return filter_named[0] - else: - return None + return None @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): diff --git a/homeassistant/components/device_tracker/locative.py b/homeassistant/components/device_tracker/locative.py index ced24edde48..aee584aa953 100644 --- a/homeassistant/components/device_tracker/locative.py +++ b/homeassistant/components/device_tracker/locative.py @@ -94,21 +94,20 @@ class LocativeView(HomeAssistantView): partial(self.see, dev_id=device, location_name=location_name, gps=gps_location)) return 'Setting location to not home' - else: - # Ignore the message if it is telling us to exit a zone that we - # aren't currently in. This occurs when a zone is entered - # before the previous zone was exited. The enter message will - # be sent first, then the exit message will be sent second. - return 'Ignoring exit from {} (already in {})'.format( - location_name, current_state) + + # Ignore the message if it is telling us to exit a zone that we + # aren't currently in. This occurs when a zone is entered + # before the previous zone was exited. The enter message will + # be sent first, then the exit message will be sent second. + return 'Ignoring exit from {} (already in {})'.format( + location_name, current_state) elif direction == 'test': # In the app, a test message can be sent. Just return something to # the user to let them know that it works. return 'Received test message.' - else: - _LOGGER.error('Received unidentified message from Locative: %s', - direction) - return ('Received unidentified message: {}'.format(direction), - HTTP_UNPROCESSABLE_ENTITY) + _LOGGER.error('Received unidentified message from Locative: %s', + direction) + return ('Received unidentified message: {}'.format(direction), + HTTP_UNPROCESSABLE_ENTITY) diff --git a/homeassistant/components/device_tracker/nmap_tracker.py b/homeassistant/components/device_tracker/nmap_tracker.py index 99dfc3829d7..8a845adf0b8 100644 --- a/homeassistant/components/device_tracker/nmap_tracker.py +++ b/homeassistant/components/device_tracker/nmap_tracker.py @@ -95,8 +95,7 @@ class NmapDeviceScanner(DeviceScanner): if filter_named: return filter_named[0] - else: - return None + return None @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): diff --git a/homeassistant/components/device_tracker/owntracks.py b/homeassistant/components/device_tracker/owntracks.py index 6aa44c17c9a..f88fda03cf7 100644 --- a/homeassistant/components/device_tracker/owntracks.py +++ b/homeassistant/components/device_tracker/owntracks.py @@ -131,8 +131,7 @@ def async_setup_scanner(hass, config, async_see, discovery_info=None): plaintext_payload = decrypt_payload(topic, data['data']) if plaintext_payload is None: return None - else: - return validate_payload(topic, plaintext_payload, data_type) + return validate_payload(topic, plaintext_payload, data_type) if not isinstance(data, dict) or data.get('_type') != data_type: _LOGGER.debug("Skipping %s update for following data " diff --git a/homeassistant/components/device_tracker/tado.py b/homeassistant/components/device_tracker/tado.py index 46096e62fbb..fca4998f7b5 100644 --- a/homeassistant/components/device_tracker/tado.py +++ b/homeassistant/components/device_tracker/tado.py @@ -90,8 +90,7 @@ class TadoDeviceScanner(DeviceScanner): if filter_named: return filter_named[0] - else: - return None + return None @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): diff --git a/homeassistant/components/device_tracker/tomato.py b/homeassistant/components/device_tracker/tomato.py index 51394ae64fe..0b330c933d8 100644 --- a/homeassistant/components/device_tracker/tomato.py +++ b/homeassistant/components/device_tracker/tomato.py @@ -73,8 +73,8 @@ class TomatoDeviceScanner(DeviceScanner): if not filter_named or not filter_named[0]: return None - else: - return filter_named[0] + + return filter_named[0] @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_tomato_info(self): diff --git a/homeassistant/components/device_tracker/tplink.py b/homeassistant/components/device_tracker/tplink.py index b34f16ebb5a..76744d56fcc 100755 --- a/homeassistant/components/device_tracker/tplink.py +++ b/homeassistant/components/device_tracker/tplink.py @@ -234,10 +234,9 @@ class Tplink3DeviceScanner(TplinkDeviceScanner): self.stok = '' self.sysauth = '' return False - else: - _LOGGER.error( - "An unknown error happened while fetching data") - return False + _LOGGER.error( + "An unknown error happened while fetching data") + return False except ValueError: _LOGGER.error("Router didn't respond with JSON. " "Check if credentials are correct") diff --git a/homeassistant/components/device_tracker/xiaomi.py b/homeassistant/components/device_tracker/xiaomi.py index e87cae3d50b..a7b0a1ad326 100644 --- a/homeassistant/components/device_tracker/xiaomi.py +++ b/homeassistant/components/device_tracker/xiaomi.py @@ -101,10 +101,10 @@ class XiaomiDeviceScanner(DeviceScanner): result = _retrieve_list(self.host, self.token) if result: return result - else: - _LOGGER.info("Refreshing token and retrying device list refresh") - self.token = _get_token(self.host, self.username, self.password) - return _retrieve_list(self.host, self.token) + + _LOGGER.info("Refreshing token and retrying device list refresh") + self.token = _get_token(self.host, self.username, self.password) + return _retrieve_list(self.host, self.token) def _store_result(self, result): """Extract and store the device list in self.last_results.""" diff --git a/homeassistant/components/fan/dyson.py b/homeassistant/components/fan/dyson.py index b8f330fd1f4..a2fb2b95ec4 100644 --- a/homeassistant/components/fan/dyson.py +++ b/homeassistant/components/fan/dyson.py @@ -157,8 +157,7 @@ class DysonPureCoolLinkDevice(FanEntity): from libpurecoollink.const import FanSpeed if self._device.state.speed == FanSpeed.FAN_SPEED_AUTO.value: return self._device.state.speed - else: - return int(self._device.state.speed) + return int(self._device.state.speed) return None @property diff --git a/homeassistant/components/fan/wink.py b/homeassistant/components/fan/wink.py index 13f755bcdf3..c649009b230 100644 --- a/homeassistant/components/fan/wink.py +++ b/homeassistant/components/fan/wink.py @@ -33,10 +33,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class WinkFanDevice(WinkDevice, FanEntity): """Representation of a Wink fan.""" - def __init__(self, wink, hass): - """Initialize the fan.""" - super().__init__(wink, hass) - @asyncio.coroutine def async_added_to_hass(self): """Callback when entity is added to hass.""" diff --git a/homeassistant/components/image_processing/dlib_face_identify.py b/homeassistant/components/image_processing/dlib_face_identify.py index 0930e42ba7d..8df6de91da4 100644 --- a/homeassistant/components/image_processing/dlib_face_identify.py +++ b/homeassistant/components/image_processing/dlib_face_identify.py @@ -57,9 +57,9 @@ class DlibFaceIdentifyEntity(ImageProcessingFaceEntity): split_entity_id(camera_entity)[1]) self._faces = {} - for name, face_file in faces.items(): + for face_name, face_file in faces.items(): image = face_recognition.load_image_file(face_file) - self._faces[name] = face_recognition.face_encodings(image)[0] + self._faces[face_name] = face_recognition.face_encodings(image)[0] @property def camera_entity(self): diff --git a/homeassistant/components/light/tellstick.py b/homeassistant/components/light/tellstick.py index d2a6dadd9da..98af61ffb7d 100644 --- a/homeassistant/components/light/tellstick.py +++ b/homeassistant/components/light/tellstick.py @@ -60,8 +60,7 @@ class TellstickLight(TellstickDevice, Light): if tellcore_data is not None: brightness = int(tellcore_data) return brightness - else: - return None + return None def _update_model(self, new_state, data): """Update the device entity state to match the arguments.""" diff --git a/homeassistant/components/light/vera.py b/homeassistant/components/light/vera.py index 3d19c3fcea2..b3be93d82e2 100644 --- a/homeassistant/components/light/vera.py +++ b/homeassistant/components/light/vera.py @@ -50,8 +50,7 @@ class VeraLight(VeraDevice, Light): """Flag supported features.""" if self._color: return SUPPORT_BRIGHTNESS | SUPPORT_RGB_COLOR - else: - return SUPPORT_BRIGHTNESS + return SUPPORT_BRIGHTNESS def turn_on(self, **kwargs): """Turn the light on.""" diff --git a/homeassistant/components/light/wink.py b/homeassistant/components/light/wink.py index b936e9addd6..93b23a9d7ba 100644 --- a/homeassistant/components/light/wink.py +++ b/homeassistant/components/light/wink.py @@ -33,10 +33,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class WinkLight(WinkDevice, Light): """Representation of a Wink light.""" - def __init__(self, wink, hass): - """Initialize the Wink device.""" - super().__init__(wink, hass) - @asyncio.coroutine def async_added_to_hass(self): """Callback when entity is added to hass.""" @@ -52,8 +48,7 @@ class WinkLight(WinkDevice, Light): """Return the brightness of the light.""" if self.wink.brightness() is not None: return int(self.wink.brightness() * 255) - else: - return None + return None @property def rgb_color(self): diff --git a/homeassistant/components/light/zwave.py b/homeassistant/components/light/zwave.py index 752928f71a4..64c6530dd2b 100644 --- a/homeassistant/components/light/zwave.py +++ b/homeassistant/components/light/zwave.py @@ -55,16 +55,14 @@ def get_device(node, values, node_config, **kwargs): if node.has_command_class(zwave.const.COMMAND_CLASS_SWITCH_COLOR): return ZwaveColorLight(values, refresh, delay) - else: - return ZwaveDimmer(values, refresh, delay) + return ZwaveDimmer(values, refresh, delay) def brightness_state(value): """Return the brightness and state.""" if value.data > 0: return round((value.data / 99) * 255, 0), STATE_ON - else: - return 0, STATE_OFF + return 0, STATE_OFF def ct_to_rgb(temp): diff --git a/homeassistant/components/lock/lockitron.py b/homeassistant/components/lock/lockitron.py index eb301eeb013..ea79848f60c 100644 --- a/homeassistant/components/lock/lockitron.py +++ b/homeassistant/components/lock/lockitron.py @@ -86,7 +86,7 @@ class Lockitron(LockDevice): self.device_id, self.access_token, requested_state), timeout=5) if response.status_code == 200: return response.json()['state'] - else: - _LOGGER.error("Error setting lock state: %s\n%s", - requested_state, response.text) - return self._state + + _LOGGER.error("Error setting lock state: %s\n%s", + requested_state, response.text) + return self._state diff --git a/homeassistant/components/lock/wink.py b/homeassistant/components/lock/wink.py index 6fbf9edf954..020fc00ab9a 100644 --- a/homeassistant/components/lock/wink.py +++ b/homeassistant/components/lock/wink.py @@ -119,10 +119,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class WinkLockDevice(WinkDevice, LockDevice): """Representation of a Wink lock.""" - def __init__(self, wink, hass): - """Initialize the lock.""" - super().__init__(wink, hass) - @asyncio.coroutine def async_added_to_hass(self): """Callback when entity is added to hass.""" diff --git a/homeassistant/components/media_player/anthemav.py b/homeassistant/components/media_player/anthemav.py index 64b8e826cfb..293c6e51d52 100644 --- a/homeassistant/components/media_player/anthemav.py +++ b/homeassistant/components/media_player/anthemav.py @@ -102,8 +102,7 @@ class AnthemAVR(MediaPlayerDevice): return STATE_ON elif pwrstate is False: return STATE_OFF - else: - return STATE_UNKNOWN + return STATE_UNKNOWN @property def is_volume_muted(self): diff --git a/homeassistant/components/media_player/apple_tv.py b/homeassistant/components/media_player/apple_tv.py index a7017f73fc4..3ecb1c0922e 100644 --- a/homeassistant/components/media_player/apple_tv.py +++ b/homeassistant/components/media_player/apple_tv.py @@ -106,8 +106,7 @@ class AppleTvDevice(MediaPlayerDevice): state == const.PLAY_STATE_FAST_BACKWARD: # Catch fast forward/backward here so "play" is default action return STATE_PAUSED - else: - return STATE_STANDBY # Bad or unknown state? + return STATE_STANDBY # Bad or unknown state? @callback def playstatus_update(self, updater, playing): diff --git a/homeassistant/components/media_player/braviatv.py b/homeassistant/components/media_player/braviatv.py index 1c8419ba144..93071b9840f 100644 --- a/homeassistant/components/media_player/braviatv.py +++ b/homeassistant/components/media_player/braviatv.py @@ -59,8 +59,7 @@ def _get_mac_address(ip_address): pid_component) if match is not None: return match.groups()[0] - else: - return None + return None def _config_from_file(filename, config=None): @@ -307,8 +306,7 @@ class BraviaTVDevice(MediaPlayerDevice): """Volume level of the media player (0..1).""" if self._volume is not None: return self._volume / 100 - else: - return None + return None @property def is_volume_muted(self): diff --git a/homeassistant/components/media_player/cmus.py b/homeassistant/components/media_player/cmus.py index aefe5bced18..949965200aa 100644 --- a/homeassistant/components/media_player/cmus.py +++ b/homeassistant/components/media_player/cmus.py @@ -94,8 +94,7 @@ class CmusDevice(MediaPlayerDevice): return STATE_PLAYING elif self.status.get('status') == 'paused': return STATE_PAUSED - else: - return STATE_OFF + return STATE_OFF @property def media_content_id(self): diff --git a/homeassistant/components/media_player/denon.py b/homeassistant/components/media_player/denon.py index 08e08dd1650..68fb629e5ea 100755 --- a/homeassistant/components/media_player/denon.py +++ b/homeassistant/components/media_player/denon.py @@ -55,9 +55,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if denon.update(): add_devices([denon]) - return True - else: - return False class DenonDevice(MediaPlayerDevice): @@ -197,8 +194,7 @@ class DenonDevice(MediaPlayerDevice): """Flag media player features that are supported.""" if self._mediasource in MEDIA_MODES.values(): return SUPPORT_DENON | SUPPORT_MEDIA_MODES - else: - return SUPPORT_DENON + return SUPPORT_DENON @property def source(self): diff --git a/homeassistant/components/media_player/directv.py b/homeassistant/components/media_player/directv.py index 75a828696d9..b46e256bab3 100644 --- a/homeassistant/components/media_player/directv.py +++ b/homeassistant/components/media_player/directv.py @@ -144,10 +144,9 @@ class DirecTvDevice(MediaPlayerDevice): """Return the channel current playing media.""" if self._is_standby: return None - else: - chan = "{} ({})".format( - self._current['callsign'], self._current['major']) - return chan + + return "{} ({})".format( + self._current['callsign'], self._current['major']) def turn_on(self): """Turn on the receiver.""" diff --git a/homeassistant/components/media_player/emby.py b/homeassistant/components/media_player/emby.py index af7bbeed201..8df6bc4fd1b 100644 --- a/homeassistant/components/media_player/emby.py +++ b/homeassistant/components/media_player/emby.py @@ -306,8 +306,7 @@ class EmbyDevice(MediaPlayerDevice): """Flag media player features that are supported.""" if self.supports_remote_control: return SUPPORT_EMBY - else: - return None + return None def async_media_play(self): """Play media. diff --git a/homeassistant/components/media_player/itunes.py b/homeassistant/components/media_player/itunes.py index 514bf24a21a..575ea414fa3 100644 --- a/homeassistant/components/media_player/itunes.py +++ b/homeassistant/components/media_player/itunes.py @@ -60,8 +60,8 @@ class Itunes(object): if self.port: return '{}{}:{}'.format(uri_scheme, self.host, self.port) - else: - return '{}{}'.format(uri_scheme, self.host) + + return '{}{}'.format(uri_scheme, self.host) def _request(self, method, path, params=None): """Make the actual request and return the parsed response.""" @@ -225,8 +225,8 @@ class ItunesDevice(MediaPlayerDevice): if self.player_state == 'paused': return STATE_PAUSED - else: - return STATE_PLAYING + + return STATE_PLAYING def update(self): """Retrieve latest state.""" @@ -281,9 +281,9 @@ class ItunesDevice(MediaPlayerDevice): if self.player_state in (STATE_PLAYING, STATE_IDLE, STATE_PAUSED) and \ self.current_title is not None: return self.client.artwork_url() - else: - return 'https://cloud.githubusercontent.com/assets/260/9829355' \ - '/33fab972-58cf-11e5-8ea2-2ca74bdaae40.png' + + return 'https://cloud.githubusercontent.com/assets/260/9829355' \ + '/33fab972-58cf-11e5-8ea2-2ca74bdaae40.png' @property def media_title(self): @@ -400,16 +400,16 @@ class AirPlayDevice(MediaPlayerDevice): """Return the icon to use in the frontend, if any.""" if self.selected is True: return 'mdi:volume-high' - else: - return 'mdi:volume-off' + + return 'mdi:volume-off' @property def state(self): """Return the state of the device.""" if self.selected is True: return STATE_ON - else: - return STATE_OFF + + return STATE_OFF def update(self): """Retrieve latest state.""" diff --git a/homeassistant/components/media_player/kodi.py b/homeassistant/components/media_player/kodi.py index 18860acb9a6..f484c04a058 100644 --- a/homeassistant/components/media_player/kodi.py +++ b/homeassistant/components/media_player/kodi.py @@ -334,8 +334,8 @@ class KodiDevice(MediaPlayerDevice): if self._properties['speed'] == 0 and not self._properties['live']: return STATE_PAUSED - else: - return STATE_PLAYING + + return STATE_PLAYING @asyncio.coroutine def async_ws_connect(self): @@ -407,8 +407,8 @@ class KodiDevice(MediaPlayerDevice): """Active server for json-rpc requests.""" if self._enable_websocket and self._ws_server.connected: return self._ws_server - else: - return self._http_server + + return self._http_server @property def name(self): @@ -503,8 +503,8 @@ class KodiDevice(MediaPlayerDevice): artists = self._item.get('artist', []) if artists: return artists[0] - else: - return None + + return None @property def media_album_artist(self): @@ -512,8 +512,8 @@ class KodiDevice(MediaPlayerDevice): artists = self._item.get('albumartist', []) if artists: return artists[0] - else: - return None + + return None @property def supported_features(self): @@ -678,9 +678,9 @@ class KodiDevice(MediaPlayerDevice): elif media_type == "PLAYLIST": return self.server.Player.Open( {"item": {"playlistid": int(media_id)}}) - else: - return self.server.Player.Open( - {"item": {"file": str(media_id)}}) + + return self.server.Player.Open( + {"item": {"file": str(media_id)}}) @asyncio.coroutine def async_set_shuffle(self, shuffle): @@ -794,9 +794,9 @@ class KodiDevice(MediaPlayerDevice): """Get albums list.""" if artist_id is None: return (yield from self.server.AudioLibrary.GetAlbums()) - else: - return (yield from self.server.AudioLibrary.GetAlbums( - {"filter": {"artistid": int(artist_id)}})) + + return (yield from self.server.AudioLibrary.GetAlbums( + {"filter": {"artistid": int(artist_id)}})) @asyncio.coroutine def async_find_artist(self, artist_name): @@ -815,9 +815,9 @@ class KodiDevice(MediaPlayerDevice): """Get songs list.""" if artist_id is None: return (yield from self.server.AudioLibrary.GetSongs()) - else: - return (yield from self.server.AudioLibrary.GetSongs( - {"filter": {"artistid": int(artist_id)}})) + + return (yield from self.server.AudioLibrary.GetSongs( + {"filter": {"artistid": int(artist_id)}})) @asyncio.coroutine def async_find_song(self, song_name, artist_name=''): diff --git a/homeassistant/components/media_player/liveboxplaytv.py b/homeassistant/components/media_player/liveboxplaytv.py index eef5a890e8e..43678d90829 100644 --- a/homeassistant/components/media_player/liveboxplaytv.py +++ b/homeassistant/components/media_player/liveboxplaytv.py @@ -159,9 +159,8 @@ class LiveboxPlayTvDevice(MediaPlayerDevice): return STATE_PLAYING elif state == 'PAUSE': return STATE_PAUSED - else: - return STATE_ON if self._client.is_on else STATE_OFF - return STATE_UNKNOWN + + return STATE_ON if self._client.is_on else STATE_OFF def turn_off(self): """Turn off media player.""" diff --git a/homeassistant/components/media_player/mpchc.py b/homeassistant/components/media_player/mpchc.py index 964c2b5d009..3f7ab5a6e5e 100644 --- a/homeassistant/components/media_player/mpchc.py +++ b/homeassistant/components/media_player/mpchc.py @@ -97,8 +97,8 @@ class MpcHcDevice(MediaPlayerDevice): return STATE_PLAYING elif state == 'paused': return STATE_PAUSED - else: - return STATE_IDLE + + return STATE_IDLE @property def media_title(self): diff --git a/homeassistant/components/media_player/mpd.py b/homeassistant/components/media_player/mpd.py index f4dad2d001b..d8dafc2be10 100644 --- a/homeassistant/components/media_player/mpd.py +++ b/homeassistant/components/media_player/mpd.py @@ -133,8 +133,8 @@ class MpdDevice(MediaPlayerDevice): return STATE_PLAYING elif self.status['state'] == 'pause': return STATE_PAUSED - else: - return STATE_OFF + + return STATE_OFF @property def media_content_id(self): @@ -164,8 +164,8 @@ class MpdDevice(MediaPlayerDevice): return title elif title is None: return name - else: - return '{}: {}'.format(name, title) + + return '{}: {}'.format(name, title) @property def media_artist(self): diff --git a/homeassistant/components/media_player/pandora.py b/homeassistant/components/media_player/pandora.py index 4e36fdab5a2..d66811eed66 100644 --- a/homeassistant/components/media_player/pandora.py +++ b/homeassistant/components/media_player/pandora.py @@ -358,9 +358,9 @@ def _pianobar_exists(): pianobar_exe = shutil.which('pianobar') if pianobar_exe: return True - else: - _LOGGER.warning( - "The Pandora component depends on the Pianobar client, which " - "cannot be found. Please install using instructions at " - "https://home-assistant.io/components/media_player.pandora/") - return False + + _LOGGER.warning( + "The Pandora component depends on the Pianobar client, which " + "cannot be found. Please install using instructions at " + "https://home-assistant.io/components/media_player.pandora/") + return False diff --git a/homeassistant/components/media_player/pioneer.py b/homeassistant/components/media_player/pioneer.py index eb346502d95..ba08003b9bf 100644 --- a/homeassistant/components/media_player/pioneer.py +++ b/homeassistant/components/media_player/pioneer.py @@ -47,9 +47,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if pioneer.update(): add_devices([pioneer]) - return True - else: - return False class PioneerDevice(MediaPlayerDevice): diff --git a/homeassistant/components/media_player/plex.py b/homeassistant/components/media_player/plex.py index d54b8f2ca77..2bfa97e7e79 100644 --- a/homeassistant/components/media_player/plex.py +++ b/homeassistant/components/media_player/plex.py @@ -531,16 +531,16 @@ class PlexClient(MediaPlayerDevice): # type so that lower layers don't think it's a URL and choke on it if value is self.na_type: return None - else: - return value + + return value @property def _active_media_plexapi_type(self): """Get the active media type required by PlexAPI commands.""" if self.media_content_type is MEDIA_TYPE_MUSIC: return 'music' - else: - return 'video' + + return 'video' @property def media_content_id(self): @@ -560,8 +560,8 @@ class PlexClient(MediaPlayerDevice): return MEDIA_TYPE_VIDEO elif self._session_type == 'track': return MEDIA_TYPE_MUSIC - else: - return None + + return None @property def media_artist(self): @@ -657,8 +657,8 @@ class PlexClient(MediaPlayerDevice): SUPPORT_NEXT_TRACK | SUPPORT_STOP | SUPPORT_VOLUME_SET | SUPPORT_PLAY | SUPPORT_TURN_OFF | SUPPORT_VOLUME_MUTE) - else: - return None + + return None def _local_client_control_fix(self): """Detect if local client and adjust url to allow control.""" diff --git a/homeassistant/components/media_player/sonos.py b/homeassistant/components/media_player/sonos.py index b26f0f48a77..33decf35f89 100644 --- a/homeassistant/components/media_player/sonos.py +++ b/homeassistant/components/media_player/sonos.py @@ -220,9 +220,9 @@ def _parse_timespan(timespan): """Parse a time-span into number of seconds.""" if timespan in ('', 'NOT_IMPLEMENTED', None): return None - else: - return sum(60 ** x[0] * int(x[1]) for x in enumerate( - reversed(timespan.split(':')))) + + return sum(60 ** x[0] * int(x[1]) for x in enumerate( + reversed(timespan.split(':')))) class _ProcessSonosEventQueue(): @@ -765,8 +765,8 @@ class SonosDevice(MediaPlayerDevice): """Content ID of current playing media.""" if self._coordinator: return self._coordinator.media_content_id - else: - return self._media_content_id + + return self._media_content_id @property def media_content_type(self): @@ -778,16 +778,16 @@ class SonosDevice(MediaPlayerDevice): """Duration of current playing media in seconds.""" if self._coordinator: return self._coordinator.media_duration - else: - return self._media_duration + + return self._media_duration @property def media_position(self): """Position of current playing media in seconds.""" if self._coordinator: return self._coordinator.media_position - else: - return self._media_position + + return self._media_position @property def media_position_updated_at(self): @@ -797,40 +797,40 @@ class SonosDevice(MediaPlayerDevice): """ if self._coordinator: return self._coordinator.media_position_updated_at - else: - return self._media_position_updated_at + + return self._media_position_updated_at @property def media_image_url(self): """Image url of current playing media.""" if self._coordinator: return self._coordinator.media_image_url - else: - return self._media_image_url + + return self._media_image_url @property def media_artist(self): """Artist of current playing media, music track only.""" if self._coordinator: return self._coordinator.media_artist - else: - return self._media_artist + + return self._media_artist @property def media_album_name(self): """Album name of current playing media, music track only.""" if self._coordinator: return self._coordinator.media_album_name - else: - return self._media_album_name + + return self._media_album_name @property def media_title(self): """Title of current playing media.""" if self._coordinator: return self._coordinator.media_title - else: - return self._media_title + + return self._media_title @property def supported_features(self): @@ -919,8 +919,8 @@ class SonosDevice(MediaPlayerDevice): """Name of the current input source.""" if self._coordinator: return self._coordinator.source - else: - return self._source_name + + return self._source_name @soco_error def turn_off(self): diff --git a/homeassistant/components/media_player/soundtouch.py b/homeassistant/components/media_player/soundtouch.py index 3890e52bd73..236208eb332 100644 --- a/homeassistant/components/media_player/soundtouch.py +++ b/homeassistant/components/media_player/soundtouch.py @@ -200,8 +200,8 @@ class SoundTouchDevice(MediaPlayerDevice): """Return the state of the device.""" if self._status.source == 'STANDBY': return STATE_OFF - else: - return MAP_STATUS.get(self._status.play_status, STATE_UNAVAILABLE) + + return MAP_STATUS.get(self._status.play_status, STATE_UNAVAILABLE) @property def is_volume_muted(self): @@ -280,8 +280,8 @@ class SoundTouchDevice(MediaPlayerDevice): return self._status.station_name elif self._status.artist is not None: return self._status.artist + " - " + self._status.track - else: - return None + + return None @property def media_duration(self): diff --git a/homeassistant/components/media_player/universal.py b/homeassistant/components/media_player/universal.py index 68c2a06cf23..daf874a31dd 100644 --- a/homeassistant/components/media_player/universal.py +++ b/homeassistant/components/media_player/universal.py @@ -215,8 +215,8 @@ class UniversalMediaPlayer(MediaPlayerDevice): master_state = self._entity_lkp( self._attrs[CONF_STATE][0], self._attrs[CONF_STATE][1]) return master_state if master_state else STATE_OFF - else: - return None + + return None @property def name(self): diff --git a/homeassistant/components/media_player/volumio.py b/homeassistant/components/media_player/volumio.py index ade49b8116e..eda0bc2b326 100755 --- a/homeassistant/components/media_player/volumio.py +++ b/homeassistant/components/media_player/volumio.py @@ -113,8 +113,8 @@ class Volumio(MediaPlayerDevice): return STATE_PAUSED elif status == 'play': return STATE_PLAYING - else: - return STATE_IDLE + + return STATE_IDLE @property def media_title(self): @@ -207,6 +207,6 @@ class Volumio(MediaPlayerDevice): self._lastvol = self._state['volume'] return self.send_volumio_msg( 'commands', params={'cmd': 'volume', 'volume': mutecmd}) - else: - return self.send_volumio_msg( - 'commands', params={'cmd': 'volume', 'volume': self._lastvol}) + + return self.send_volumio_msg( + 'commands', params={'cmd': 'volume', 'volume': self._lastvol}) diff --git a/homeassistant/components/media_player/yamaha.py b/homeassistant/components/media_player/yamaha.py index de19ab238b5..4d10c722800 100644 --- a/homeassistant/components/media_player/yamaha.py +++ b/homeassistant/components/media_player/yamaha.py @@ -289,5 +289,5 @@ class YamahaDevice(MediaPlayerDevice): # just the one we have. if song and station: return '{}: {}'.format(station, song) - else: - return song or station + + return song or station diff --git a/homeassistant/components/notify/mailgun.py b/homeassistant/components/notify/mailgun.py index 59c6a50ffc9..1aa403f0ba8 100644 --- a/homeassistant/components/notify/mailgun.py +++ b/homeassistant/components/notify/mailgun.py @@ -42,8 +42,8 @@ def get_service(hass, config, discovery_info=None): config.get(CONF_RECIPIENT)) if mailgun_service.connection_is_valid(): return mailgun_service - else: - return None + + return None class MailgunNotificationService(BaseNotificationService): diff --git a/homeassistant/components/notify/smtp.py b/homeassistant/components/notify/smtp.py index aaf1a729f2d..fc38647a065 100644 --- a/homeassistant/components/notify/smtp.py +++ b/homeassistant/components/notify/smtp.py @@ -74,8 +74,8 @@ def get_service(hass, config, discovery_info=None): if mail_service.connection_is_valid(): return mail_service - else: - return None + + return None class MailNotificationService(BaseNotificationService): diff --git a/homeassistant/components/recorder/models.py b/homeassistant/components/recorder/models.py index 65c7dc6abb6..a87eabc44e6 100644 --- a/homeassistant/components/recorder/models.py +++ b/homeassistant/components/recorder/models.py @@ -173,5 +173,5 @@ def _process_timestamp(ts): return None elif ts.tzinfo is None: return dt_util.UTC.localize(ts) - else: - return dt_util.as_utc(ts) + + return dt_util.as_utc(ts) diff --git a/homeassistant/components/scene/lifx_cloud.py b/homeassistant/components/scene/lifx_cloud.py index b96a56ca2bd..e6f5be71a80 100644 --- a/homeassistant/components/scene/lifx_cloud.py +++ b/homeassistant/components/scene/lifx_cloud.py @@ -62,9 +62,9 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): elif status == 401: _LOGGER.error("Unauthorized (bad token?) on %s", url) return False - else: - _LOGGER.error("HTTP error %d on %s", scenes_resp.status, url) - return False + + _LOGGER.error("HTTP error %d on %s", scenes_resp.status, url) + return False class LifxCloudScene(Scene): diff --git a/homeassistant/components/sensor/arwn.py b/homeassistant/components/sensor/arwn.py index a63451771d6..d49afb8b71a 100644 --- a/homeassistant/components/sensor/arwn.py +++ b/homeassistant/components/sensor/arwn.py @@ -146,7 +146,4 @@ class ArwnSensor(Entity): @property def icon(self): """Return the icon of device based on its type.""" - if self._icon: - return self._icon - else: - return super().icon + return self._icon diff --git a/homeassistant/components/sensor/bom.py b/homeassistant/components/sensor/bom.py index 4033211e461..545bef12d83 100644 --- a/homeassistant/components/sensor/bom.py +++ b/homeassistant/components/sensor/bom.py @@ -139,17 +139,17 @@ class BOMCurrentSensor(Entity): """Return the name of the sensor.""" if self.stationname is None: return 'BOM {}'.format(SENSOR_TYPES[self._condition][0]) - else: - return 'BOM {} {}'.format( - self.stationname, SENSOR_TYPES[self._condition][0]) + + return 'BOM {} {}'.format( + self.stationname, SENSOR_TYPES[self._condition][0]) @property def state(self): """Return the state of the sensor.""" if self.rest.data and self._condition in self.rest.data: return self.rest.data[self._condition] - else: - return STATE_UNKNOWN + + return STATE_UNKNOWN @property def device_state_attributes(self): diff --git a/homeassistant/components/sensor/buienradar.py b/homeassistant/components/sensor/buienradar.py index 2d1e716fd1b..e65353daadb 100755 --- a/homeassistant/components/sensor/buienradar.py +++ b/homeassistant/components/sensor/buienradar.py @@ -167,8 +167,8 @@ class BrSensor(Entity): if self.type != SYMBOL: return None - else: - return self._entity_picture + + return self._entity_picture @property def device_state_attributes(self): diff --git a/homeassistant/components/sensor/darksky.py b/homeassistant/components/sensor/darksky.py index eaf0c474994..a10a276bf0f 100644 --- a/homeassistant/components/sensor/darksky.py +++ b/homeassistant/components/sensor/darksky.py @@ -187,9 +187,9 @@ class DarkSkySensor(Entity): """Return the name of the sensor.""" if self.forecast_day == 0: return '{} {}'.format(self.client_name, self._name) - else: - return '{} {} {}'.format( - self.client_name, self._name, self.forecast_day) + + return '{} {} {}'.format( + self.client_name, self._name, self.forecast_day) @property def state(self): @@ -214,8 +214,8 @@ class DarkSkySensor(Entity): if self._icon in CONDITION_PICTURES: return CONDITION_PICTURES[self._icon] - else: - return None + + return None def update_unit_of_measurement(self): """Update units based on unit system.""" diff --git a/homeassistant/components/sensor/dsmr.py b/homeassistant/components/sensor/dsmr.py index 23324fe7360..76fde35410d 100644 --- a/homeassistant/components/sensor/dsmr.py +++ b/homeassistant/components/sensor/dsmr.py @@ -207,11 +207,11 @@ class DSMREntity(Entity): if self._obis == obis.ELECTRICITY_ACTIVE_TARIFF: return self.translate_tariff(value) - else: - if value is not None: - return value - else: - return STATE_UNKNOWN + + if value is not None: + return value + + return STATE_UNKNOWN @property def unit_of_measurement(self): @@ -227,8 +227,8 @@ class DSMREntity(Entity): return 'normal' elif value == '0001': return 'low' - else: - return STATE_UNKNOWN + + return STATE_UNKNOWN class DerivativeDSMREntity(DSMREntity): diff --git a/homeassistant/components/sensor/dyson.py b/homeassistant/components/sensor/dyson.py index 2f324519566..e68909a1d6c 100644 --- a/homeassistant/components/sensor/dyson.py +++ b/homeassistant/components/sensor/dyson.py @@ -59,8 +59,7 @@ class DysonFilterLifeSensor(Entity): """Return filter life in hours..""" if self._device.state: return self._device.state.filter_life - else: - return STATE_UNKNOWN + return STATE_UNKNOWN @property def name(self): diff --git a/homeassistant/components/sensor/eddystone_temperature.py b/homeassistant/components/sensor/eddystone_temperature.py index 7fd5f14e1af..fe05da3ccdd 100644 --- a/homeassistant/components/sensor/eddystone_temperature.py +++ b/homeassistant/components/sensor/eddystone_temperature.py @@ -86,8 +86,7 @@ def get_from_conf(config, config_key, length): _LOGGER.error("Error in config parameter %s: Must be exactly %d " "bytes. Device will not be added", config_key, length/2) return None - else: - return string + return string class EddystoneTemp(Entity): diff --git a/homeassistant/components/sensor/eight_sleep.py b/homeassistant/components/sensor/eight_sleep.py index e3b2f92d4e1..f7d42a9f5bd 100644 --- a/homeassistant/components/sensor/eight_sleep.py +++ b/homeassistant/components/sensor/eight_sleep.py @@ -155,8 +155,8 @@ class EightUserSensor(EightSleepUserEntity): elif 'bed_temp' in self._sensor: if self._units == 'si': return '°C' - else: - return '°F' + return '°F' + return None @property def icon(self): @@ -264,8 +264,7 @@ class EightRoomSensor(EightSleepUserEntity): """Return the unit the value is expressed in.""" if self._units == 'si': return '°C' - else: - return '°F' + return '°F' @property def icon(self): diff --git a/homeassistant/components/sensor/fritzbox_callmonitor.py b/homeassistant/components/sensor/fritzbox_callmonitor.py index ea2fcd026b3..a780d999b7e 100644 --- a/homeassistant/components/sensor/fritzbox_callmonitor.py +++ b/homeassistant/components/sensor/fritzbox_callmonitor.py @@ -91,10 +91,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): _stop_listener ) - if monitor.sock is None: - return False - else: - return True + return monitor.sock is not None class FritzBoxCallSensor(Entity): @@ -118,10 +115,7 @@ class FritzBoxCallSensor(Entity): @property def should_poll(self): """Only poll to update phonebook, if defined.""" - if self.phonebook is None: - return False - else: - return True + return self.phonebook is not None @property def state(self): @@ -142,8 +136,7 @@ class FritzBoxCallSensor(Entity): """Return a name for a given phone number.""" if self.phonebook is None: return 'unknown' - else: - return self.phonebook.get_name(number) + return self.phonebook.get_name(number) def update(self): """Update the phonebook if it is defined.""" diff --git a/homeassistant/components/sensor/glances.py b/homeassistant/components/sensor/glances.py index 09738454bcb..58ac363b98e 100644 --- a/homeassistant/components/sensor/glances.py +++ b/homeassistant/components/sensor/glances.py @@ -89,8 +89,7 @@ class GlancesSensor(Entity): """Return the name of the sensor.""" if self._name is None: return SENSOR_TYPES[self.type][0] - else: - return '{} {}'.format(self._name, SENSOR_TYPES[self.type][0]) + return '{} {}'.format(self._name, SENSOR_TYPES[self.type][0]) @property def unit_of_measurement(self): diff --git a/homeassistant/components/sensor/gpsd.py b/homeassistant/components/sensor/gpsd.py index 9027802c295..472dd1d70f6 100644 --- a/homeassistant/components/sensor/gpsd.py +++ b/homeassistant/components/sensor/gpsd.py @@ -94,8 +94,7 @@ class GpsdSensor(Entity): return "3D Fix" elif self.agps_thread.data_stream.mode == 2: return "2D Fix" - else: - return STATE_UNKNOWN + return STATE_UNKNOWN @property def device_state_attributes(self): diff --git a/homeassistant/components/sensor/hddtemp.py b/homeassistant/components/sensor/hddtemp.py index 87647f4d16c..cd84bd8f9a8 100644 --- a/homeassistant/components/sensor/hddtemp.py +++ b/homeassistant/components/sensor/hddtemp.py @@ -77,8 +77,7 @@ class HddTempSensor(Entity): """Return the unit the value is expressed in.""" if self._details[4] == 'C': return TEMP_CELSIUS - else: - return TEMP_FAHRENHEIT + return TEMP_FAHRENHEIT @property def device_state_attributes(self): diff --git a/homeassistant/components/sensor/history_stats.py b/homeassistant/components/sensor/history_stats.py index fa000a75875..175bdafd4a9 100644 --- a/homeassistant/components/sensor/history_stats.py +++ b/homeassistant/components/sensor/history_stats.py @@ -296,8 +296,7 @@ class HistoryStatsHelper: return '%dd %dh %dm' % (days, hours, minutes) elif hours > 0: return '%dh %dm' % (hours, minutes) - else: - return '%dm' % minutes + return '%dm' % minutes @staticmethod def pretty_ratio(value, period): diff --git a/homeassistant/components/sensor/ios.py b/homeassistant/components/sensor/ios.py index c3bcbf60828..7bfe2dbd62a 100644 --- a/homeassistant/components/sensor/ios.py +++ b/homeassistant/components/sensor/ios.py @@ -121,8 +121,7 @@ class IOSSensor(Entity): if self.type == "state": return returning_icon_state - else: - return returning_icon_level + return returning_icon_level def update(self): """Get the latest state of the sensor.""" diff --git a/homeassistant/components/sensor/isy994.py b/homeassistant/components/sensor/isy994.py index 2f6d7346283..57995a831f3 100644 --- a/homeassistant/components/sensor/isy994.py +++ b/homeassistant/components/sensor/isy994.py @@ -310,8 +310,7 @@ class ISYSensorDevice(isy.ISYDevice): raw_units = self.raw_unit_of_measurement if raw_units in (TEMP_FAHRENHEIT, TEMP_CELSIUS): return self.hass.config.units.temperature_unit - else: - return raw_units + return raw_units class ISYWeatherDevice(isy.ISYDevice): diff --git a/homeassistant/components/sensor/kwb.py b/homeassistant/components/sensor/kwb.py index 0641917145b..f307b0f6102 100644 --- a/homeassistant/components/sensor/kwb.py +++ b/homeassistant/components/sensor/kwb.py @@ -105,8 +105,7 @@ class KWBSensor(Entity): """Return the state of value.""" if self._sensor.value is not None and self._sensor.available: return self._sensor.value - else: - return STATE_UNKNOWN + return STATE_UNKNOWN @property def unit_of_measurement(self): diff --git a/homeassistant/components/sensor/metoffice.py b/homeassistant/components/sensor/metoffice.py index 961b4692e93..a20ec8fdd5a 100644 --- a/homeassistant/components/sensor/metoffice.py +++ b/homeassistant/components/sensor/metoffice.py @@ -124,10 +124,8 @@ class MetOfficeCurrentSensor(Entity): if self._condition == "weather": return [k for k, v in CONDITION_CLASSES.items() if self.data.data.weather.value in v][0] - else: - return variable.value - else: - return STATE_UNKNOWN + return variable.value + return STATE_UNKNOWN @property def unit_of_measurement(self): diff --git a/homeassistant/components/sensor/moon.py b/homeassistant/components/sensor/moon.py index 9d844292e18..75b8a1f72bd 100644 --- a/homeassistant/components/sensor/moon.py +++ b/homeassistant/components/sensor/moon.py @@ -64,8 +64,7 @@ class MoonSensor(Entity): return 'Waning gibbous' elif self._state == 21: return 'Last quarter' - else: - return 'Waning crescent' + return 'Waning crescent' @property def icon(self): diff --git a/homeassistant/components/sensor/mvglive.py b/homeassistant/components/sensor/mvglive.py index d1f101fc02f..46d79c1121b 100644 --- a/homeassistant/components/sensor/mvglive.py +++ b/homeassistant/components/sensor/mvglive.py @@ -91,8 +91,7 @@ class MVGLiveSensor(Entity): """Return the name of the sensor.""" if self._name: return self._name - else: - return self._station + return self._station @property def state(self): diff --git a/homeassistant/components/sensor/neato.py b/homeassistant/components/sensor/neato.py index 39d77e736c5..eb1524e1748 100644 --- a/homeassistant/components/sensor/neato.py +++ b/homeassistant/components/sensor/neato.py @@ -136,10 +136,7 @@ class NeatoConnectedSensor(Entity): @property def available(self): """Return True if sensor data is available.""" - if not self._state: - return False - else: - return True + return self._state @property def state(self): diff --git a/homeassistant/components/sensor/netdata.py b/homeassistant/components/sensor/netdata.py index ad7426eb1d3..6cb6ef9a14d 100644 --- a/homeassistant/components/sensor/netdata.py +++ b/homeassistant/components/sensor/netdata.py @@ -14,7 +14,7 @@ import voluptuous as vol import homeassistant.helpers.config_validation as cv from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( - CONF_HOST, CONF_PORT, STATE_UNKNOWN, CONF_NAME, CONF_RESOURCES) + CONF_HOST, CONF_PORT, CONF_NAME, CONF_RESOURCES) from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) @@ -110,8 +110,7 @@ class NetdataSensor(Entity): netdata_id = SENSOR_TYPES[self.type][3] if netdata_id in value: return "{0:.{1}f}".format(value[netdata_id], self._precision) - else: - return STATE_UNKNOWN + return None @property def available(self): diff --git a/homeassistant/components/sensor/ohmconnect.py b/homeassistant/components/sensor/ohmconnect.py index 9808e6ecef7..cb1a1d3d260 100644 --- a/homeassistant/components/sensor/ohmconnect.py +++ b/homeassistant/components/sensor/ohmconnect.py @@ -60,8 +60,7 @@ class OhmconnectSensor(Entity): """Return the state of the sensor.""" if self._data.get("active") == "True": return "Active" - else: - return "Inactive" + return "Inactive" @property def device_state_attributes(self): diff --git a/homeassistant/components/sensor/pvoutput.py b/homeassistant/components/sensor/pvoutput.py index cb3d2d1427a..baad452b629 100644 --- a/homeassistant/components/sensor/pvoutput.py +++ b/homeassistant/components/sensor/pvoutput.py @@ -15,8 +15,7 @@ from homeassistant.helpers.entity import Entity from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.components.sensor.rest import RestData from homeassistant.const import ( - ATTR_TEMPERATURE, CONF_API_KEY, CONF_NAME, STATE_UNKNOWN, ATTR_DATE, - ATTR_TIME) + ATTR_TEMPERATURE, CONF_API_KEY, CONF_NAME, ATTR_DATE, ATTR_TIME) _LOGGER = logging.getLogger(__name__) _ENDPOINT = 'http://pvoutput.org/service/r2/getstatus.jsp' @@ -90,8 +89,7 @@ class PvoutputSensor(Entity): """Return the state of the device.""" if self.pvcoutput is not None: return self.pvcoutput.energy_generation - else: - return STATE_UNKNOWN + return None @property def device_state_attributes(self): diff --git a/homeassistant/components/sensor/qnap.py b/homeassistant/components/sensor/qnap.py index c72d2d65c6d..42f68a1967a 100644 --- a/homeassistant/components/sensor/qnap.py +++ b/homeassistant/components/sensor/qnap.py @@ -232,8 +232,7 @@ class QNAPSensor(Entity): if self.monitor_device is not None: return "{} {} ({})".format( server_name, self.var_name, self.monitor_device) - else: - return "{} {}".format(server_name, self.var_name) + return "{} {}".format(server_name, self.var_name) @property def icon(self): diff --git a/homeassistant/components/sensor/swiss_hydrological_data.py b/homeassistant/components/sensor/swiss_hydrological_data.py index 0df63956f2e..3e2f228423b 100644 --- a/homeassistant/components/sensor/swiss_hydrological_data.py +++ b/homeassistant/components/sensor/swiss_hydrological_data.py @@ -90,8 +90,7 @@ class SwissHydrologicalDataSensor(Entity): """Return the unit of measurement of this entity, if any.""" if self._state is not STATE_UNKNOWN: return self._unit_of_measurement - else: - return None + return None @property def state(self): diff --git a/homeassistant/components/sensor/synologydsm.py b/homeassistant/components/sensor/synologydsm.py index eb31381ccef..b52d01a0112 100644 --- a/homeassistant/components/sensor/synologydsm.py +++ b/homeassistant/components/sensor/synologydsm.py @@ -177,8 +177,7 @@ class SynoNasSensor(Entity): """Return the name of the sensor, if any.""" if self.monitor_device is not None: return "{} ({})".format(self.var_name, self.monitor_device) - else: - return self.var_name + return self.var_name @property def icon(self): @@ -191,8 +190,7 @@ class SynoNasSensor(Entity): if self.var_id in ['volume_disk_temp_avg', 'volume_disk_temp_max', 'disk_temp']: return self._api.temp_unit - else: - return self.var_units + return self.var_units def update(self): """Get the latest data for the states.""" @@ -238,8 +236,8 @@ class SynoNasStorageSensor(SynoNasSensor): if self._api.temp_unit == TEMP_CELSIUS: return attr - else: - return round(attr * 1.8 + 32.0, 1) - else: - return getattr(self._api.storage, - self.var_id)(self.monitor_device) + + return round(attr * 1.8 + 32.0, 1) + + return getattr(self._api.storage, + self.var_id)(self.monitor_device) diff --git a/homeassistant/components/sensor/tado.py b/homeassistant/components/sensor/tado.py index b654a4444c4..1d40e4ceb50 100644 --- a/homeassistant/components/sensor/tado.py +++ b/homeassistant/components/sensor/tado.py @@ -30,7 +30,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): zones = tado.get_zones() except RuntimeError: _LOGGER.error("Unable to get zone info from mytado") - return False + return sensor_items = [] for zone in zones: @@ -47,9 +47,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if sensor_items: add_devices(sensor_items, True) - return True - else: - return False def create_zone_sensor(tado, zone, name, zone_id, variable): diff --git a/homeassistant/components/sensor/tellduslive.py b/homeassistant/components/sensor/tellduslive.py index 68d0bb6535f..c14b20e1099 100644 --- a/homeassistant/components/sensor/tellduslive.py +++ b/homeassistant/components/sensor/tellduslive.py @@ -92,8 +92,7 @@ class TelldusLiveSensor(TelldusLiveEntity): return self._value_as_humidity elif self._type == SENSOR_TYPE_LUMINANCE: return self._value_as_luminance - else: - return self._value + return self._value @property def quantity_name(self): diff --git a/homeassistant/components/sensor/time_date.py b/homeassistant/components/sensor/time_date.py index c1c4d62dbcb..a59ee01bac2 100644 --- a/homeassistant/components/sensor/time_date.py +++ b/homeassistant/components/sensor/time_date.py @@ -83,8 +83,7 @@ class TimeDateSensor(Entity): return 'mdi:calendar-clock' elif 'date' in self.type: return 'mdi:calendar' - else: - return 'mdi:clock' + return 'mdi:clock' def get_next_interval(self, now=None): """Compute next time an update should occur.""" diff --git a/homeassistant/components/sensor/volvooncall.py b/homeassistant/components/sensor/volvooncall.py index 703315c478c..622261941d6 100644 --- a/homeassistant/components/sensor/volvooncall.py +++ b/homeassistant/components/sensor/volvooncall.py @@ -28,8 +28,7 @@ class VolvoSensor(VolvoEntity): val = getattr(self.vehicle, self._attribute) if self._attribute == 'odometer': return round(val / 1000) # km - else: - return val + return val @property def unit_of_measurement(self): diff --git a/homeassistant/components/sensor/waqi.py b/homeassistant/components/sensor/waqi.py index 01bdab24af9..f762caf58ae 100644 --- a/homeassistant/components/sensor/waqi.py +++ b/homeassistant/components/sensor/waqi.py @@ -11,7 +11,7 @@ import voluptuous as vol import homeassistant.helpers.config_validation as cv from homeassistant.const import ( - ATTR_ATTRIBUTION, ATTR_TIME, ATTR_TEMPERATURE, STATE_UNKNOWN, CONF_TOKEN) + ATTR_ATTRIBUTION, ATTR_TIME, ATTR_TEMPERATURE, CONF_TOKEN) from homeassistant.helpers.config_validation import PLATFORM_SCHEMA from homeassistant.helpers.entity import Entity @@ -101,8 +101,7 @@ class WaqiSensor(Entity): """Return the state of the device.""" if self._details is not None: return self._details.get('aqi') - else: - return STATE_UNKNOWN + return None @property def unit_of_measurement(self): diff --git a/homeassistant/components/sensor/wunderground.py b/homeassistant/components/sensor/wunderground.py index 84f6d2d2ac0..3a72432610c 100644 --- a/homeassistant/components/sensor/wunderground.py +++ b/homeassistant/components/sensor/wunderground.py @@ -254,8 +254,7 @@ class WUAlertsSensorConfig(WUSensorConfig): feature="alerts", value=lambda wu: len(wu.data['alerts']), icon=lambda wu: "mdi:alert-circle-outline" - if len(wu.data['alerts']) > 0 - else "mdi:check-circle-outline", + if wu.data['alerts'] else "mdi:check-circle-outline", device_state_attributes=self._get_attributes ) diff --git a/homeassistant/components/sensor/zwave.py b/homeassistant/components/sensor/zwave.py index e9ea0e7512d..fe295d84d49 100644 --- a/homeassistant/components/sensor/zwave.py +++ b/homeassistant/components/sensor/zwave.py @@ -78,8 +78,7 @@ class ZWaveMultilevelSensor(ZWaveSensor): return TEMP_CELSIUS elif self._units == 'F': return TEMP_FAHRENHEIT - else: - return self._units + return self._units class ZWaveAlarmSensor(ZWaveSensor): diff --git a/homeassistant/components/switch/neato.py b/homeassistant/components/switch/neato.py index e61a46f78a6..739e4e03fed 100644 --- a/homeassistant/components/switch/neato.py +++ b/homeassistant/components/switch/neato.py @@ -89,10 +89,7 @@ class NeatoConnectedSwitch(ToggleEntity): @property def available(self): """Return True if entity is available.""" - if not self._state: - return False - else: - return True + return self._state @property def is_on(self): diff --git a/homeassistant/components/switch/rachio.py b/homeassistant/components/switch/rachio.py index b86523ad959..b60aafdf483 100644 --- a/homeassistant/components/switch/rachio.py +++ b/homeassistant/components/switch/rachio.py @@ -137,9 +137,9 @@ class RachioIro(object): if include_disabled: return self._zones - else: - self.update(no_throttle=True) - return [z for z in self._zones if z.is_enabled] + + self.update(no_throttle=True) + return [z for z in self._zones if z.is_enabled] @util.Throttle(MIN_UPDATE_INTERVAL, MIN_FORCED_UPDATE_INTERVAL) def update(self, **kwargs): diff --git a/homeassistant/components/switch/wemo.py b/homeassistant/components/switch/wemo.py index 972eb2d523e..7b97ece337b 100644 --- a/homeassistant/components/switch/wemo.py +++ b/homeassistant/components/switch/wemo.py @@ -162,8 +162,7 @@ class WemoSwitch(SwitchDevice): return STATE_OFF elif standby_state == WEMO_STANDBY: return STATE_STANDBY - else: - return STATE_UNKNOWN + return STATE_UNKNOWN @property def is_on(self): @@ -186,8 +185,7 @@ class WemoSwitch(SwitchDevice): """Return the icon of device based on its type.""" if self._model_name == 'CoffeeMaker': return 'mdi:coffee' - else: - return super().icon + return None def turn_on(self, **kwargs): """Turn the switch on.""" diff --git a/homeassistant/components/telegram_bot/webhooks.py b/homeassistant/components/telegram_bot/webhooks.py index 488fbdfec2b..30d81930b44 100644 --- a/homeassistant/components/telegram_bot/webhooks.py +++ b/homeassistant/components/telegram_bot/webhooks.py @@ -114,5 +114,4 @@ class BotPushReceiver(HomeAssistantView, BaseTelegramBotEntity): if not self.process_message(data): return self.json_message('Invalid message', HTTP_BAD_REQUEST) - else: - return self.json({}) + return self.json({}) diff --git a/homeassistant/components/tts/google.py b/homeassistant/components/tts/google.py index 9b12507de36..3ddcc5c716a 100644 --- a/homeassistant/components/tts/google.py +++ b/homeassistant/components/tts/google.py @@ -129,8 +129,7 @@ class GoogleProvider(Provider): if len(fullstring) > MESSAGE_SIZE: idx = fullstring.rfind(' ', 0, MESSAGE_SIZE) return [fullstring[:idx]] + split_by_space(fullstring[idx:]) - else: - return [fullstring] + return [fullstring] msg_parts = [] for part in parts: diff --git a/homeassistant/remote.py b/homeassistant/remote.py index 9d026eddeff..c8fe62f64d9 100644 --- a/homeassistant/remote.py +++ b/homeassistant/remote.py @@ -116,29 +116,29 @@ class JSONEncoder(json.JSONEncoder): """JSONEncoder that supports Home Assistant objects.""" # pylint: disable=method-hidden - def default(self, obj): + def default(self, o): """Convert Home Assistant objects. Hand other objects to the original method. """ - if isinstance(obj, datetime): - return obj.isoformat() - elif isinstance(obj, set): - return list(obj) - elif hasattr(obj, 'as_dict'): - return obj.as_dict() + if isinstance(o, datetime): + return o.isoformat() + elif isinstance(o, set): + return list(o) + elif hasattr(o, 'as_dict'): + return o.as_dict() try: - return json.JSONEncoder.default(self, obj) + return json.JSONEncoder.default(self, o) except TypeError: # If the JSON serializer couldn't serialize it # it might be a generator, convert it to a list try: return [self.default(child_obj) - for child_obj in obj] + for child_obj in o] except TypeError: # Ok, we're lost, cause the original error - return json.JSONEncoder.default(self, obj) + return json.JSONEncoder.default(self, o) def validate_api(api): From d655c0e35816b76502282d78fda4242d6d59763a Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Thu, 6 Jul 2017 13:56:50 +0200 Subject: [PATCH 043/131] Upgrade aiohttp to 2.2.3 (#8363) --- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 706836ea324..1de3671a296 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -5,7 +5,7 @@ pip>=7.1.0 jinja2>=2.9.5 voluptuous==0.10.5 typing>=3,<4 -aiohttp==2.2.2 +aiohttp==2.2.3 async_timeout==1.2.1 chardet==3.0.4 astral==1.4 diff --git a/requirements_all.txt b/requirements_all.txt index d3f24dad542..f2dd1789c0a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -6,7 +6,7 @@ pip>=7.1.0 jinja2>=2.9.5 voluptuous==0.10.5 typing>=3,<4 -aiohttp==2.2.2 +aiohttp==2.2.3 async_timeout==1.2.1 chardet==3.0.4 astral==1.4 diff --git a/setup.py b/setup.py index 22423952669..4476bc2f9f0 100755 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ REQUIRES = [ 'jinja2>=2.9.5', 'voluptuous==0.10.5', 'typing>=3,<4', - 'aiohttp==2.2.2', + 'aiohttp==2.2.3', 'async_timeout==1.2.1', 'chardet==3.0.4', 'astral==1.4', From 143044f8f133f0e8b93a992f0a29b703c8abea02 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 6 Jul 2017 05:08:32 -0700 Subject: [PATCH 044/131] Remove some more usage of run_in_executor (#8352) * Remove usage of run_in_executor * Lint --- tests/components/binary_sensor/test_zwave.py | 6 +-- tests/components/camera/test_generic.py | 42 ++++++++------------ tests/components/camera/test_local_file.py | 35 +++++----------- 3 files changed, 29 insertions(+), 54 deletions(-) diff --git a/tests/components/binary_sensor/test_zwave.py b/tests/components/binary_sensor/test_zwave.py index 13f3934f964..eb52dc0c825 100644 --- a/tests/components/binary_sensor/test_zwave.py +++ b/tests/components/binary_sensor/test_zwave.py @@ -83,15 +83,13 @@ def test_trigger_sensor_value_changed(hass, mock_openzwave): assert not device.is_on value.data = True - yield from hass.loop.run_in_executor(None, value_changed, value) - yield from hass.async_block_till_done() + yield from hass.async_add_job(value_changed, value) assert device.invalidate_after is None device.hass = hass value.data = True - yield from hass.loop.run_in_executor(None, value_changed, value) - yield from hass.async_block_till_done() + yield from hass.async_add_job(value_changed, value) assert device.is_on test_time = device.invalidate_after - datetime.timedelta(seconds=1) diff --git a/tests/components/camera/test_generic.py b/tests/components/camera/test_generic.py index 52bc3d9e048..84eaf107d70 100644 --- a/tests/components/camera/test_generic.py +++ b/tests/components/camera/test_generic.py @@ -2,7 +2,7 @@ import asyncio from unittest import mock -from homeassistant.setup import setup_component, async_setup_component +from homeassistant.setup import async_setup_component @asyncio.coroutine @@ -10,18 +10,14 @@ def test_fetching_url(aioclient_mock, hass, test_client): """Test that it fetches the given url.""" aioclient_mock.get('http://example.com', text='hello world') - def setup_platform(): - """Setup the platform.""" - assert setup_component(hass, 'camera', { - 'camera': { - 'name': 'config_test', - 'platform': 'generic', - 'still_image_url': 'http://example.com', - 'username': 'user', - 'password': 'pass' - }}) - - yield from hass.loop.run_in_executor(None, setup_platform) + yield from async_setup_component(hass, 'camera', { + 'camera': { + 'name': 'config_test', + 'platform': 'generic', + 'still_image_url': 'http://example.com', + 'username': 'user', + 'password': 'pass' + }}) client = yield from test_client(hass.http.app) @@ -44,18 +40,14 @@ def test_limit_refetch(aioclient_mock, hass, test_client): aioclient_mock.get('http://example.com/15a', text='hello planet') aioclient_mock.get('http://example.com/20a', status=404) - def setup_platform(): - """Setup the platform.""" - assert setup_component(hass, 'camera', { - 'camera': { - 'name': 'config_test', - 'platform': 'generic', - 'still_image_url': - 'http://example.com/{{ states.sensor.temp.state + "a" }}', - 'limit_refetch_to_url_change': True, - }}) - - yield from hass.loop.run_in_executor(None, setup_platform) + yield from async_setup_component(hass, 'camera', { + 'camera': { + 'name': 'config_test', + 'platform': 'generic', + 'still_image_url': + 'http://example.com/{{ states.sensor.temp.state + "a" }}', + 'limit_refetch_to_url_change': True, + }}) client = yield from test_client(hass.http.app) diff --git a/tests/components/camera/test_local_file.py b/tests/components/camera/test_local_file.py index 06e7e5e3515..812dd399a48 100644 --- a/tests/components/camera/test_local_file.py +++ b/tests/components/camera/test_local_file.py @@ -6,28 +6,21 @@ from unittest import mock # https://bugs.python.org/issue23004 from mock_open import MockOpen -from homeassistant.setup import setup_component, async_setup_component - -from tests.common import mock_http_component -import logging +from homeassistant.setup import async_setup_component @asyncio.coroutine def test_loading_file(hass, test_client): """Test that it loads image from disk.""" - @mock.patch('os.path.isfile', mock.Mock(return_value=True)) - @mock.patch('os.access', mock.Mock(return_value=True)) - def setup_platform(): - """Setup platform inside callback.""" - assert setup_component(hass, 'camera', { + with mock.patch('os.path.isfile', mock.Mock(return_value=True)), \ + mock.patch('os.access', mock.Mock(return_value=True)): + yield from async_setup_component(hass, 'camera', { 'camera': { 'name': 'config_test', 'platform': 'local_file', 'file_path': 'mock.file', }}) - yield from hass.loop.run_in_executor(None, setup_platform) - client = yield from test_client(hass.http.app) m_open = MockOpen(read_data=b'hello') @@ -45,26 +38,18 @@ def test_loading_file(hass, test_client): @asyncio.coroutine def test_file_not_readable(hass, caplog): """Test a warning is shown setup when file is not readable.""" - mock_http_component(hass) - - @mock.patch('os.path.isfile', mock.Mock(return_value=True)) - @mock.patch('os.access', mock.Mock(return_value=False)) - def run_test(): - - caplog.set_level( - logging.WARNING, logger='requests.packages.urllib3.connectionpool') - - assert setup_component(hass, 'camera', { + with mock.patch('os.path.isfile', mock.Mock(return_value=True)), \ + mock.patch('os.access', mock.Mock(return_value=False)): + yield from async_setup_component(hass, 'camera', { 'camera': { 'name': 'config_test', 'platform': 'local_file', 'file_path': 'mock.file', }}) - assert 'Could not read' in caplog.text - assert 'config_test' in caplog.text - assert 'mock.file' in caplog.text - yield from hass.loop.run_in_executor(None, run_test) + assert 'Could not read' in caplog.text + assert 'config_test' in caplog.text + assert 'mock.file' in caplog.text @asyncio.coroutine From fe6a4b8ae5953c8d565dc93acc9d34c715a80aee Mon Sep 17 00:00:00 2001 From: Johan Bloemberg Date: Thu, 6 Jul 2017 15:59:54 +0200 Subject: [PATCH 045/131] Correct spelling of aliases, deprecate old config options. (#8348) * correct spelling of aliases * add deprecation * Fix style. --- homeassistant/components/light/rflink.py | 39 ++++++++++++++------- homeassistant/components/rflink.py | 32 ++++++++++++++--- homeassistant/components/sensor/rflink.py | 12 ++++--- homeassistant/components/switch/rflink.py | 42 +++++++++++++++-------- tests/components/light/test_rflink.py | 12 +++---- tests/components/switch/test_rflink.py | 10 +++--- tests/components/test_rflink.py | 4 +-- 7 files changed, 102 insertions(+), 49 deletions(-) diff --git a/homeassistant/components/light/rflink.py b/homeassistant/components/light/rflink.py index fb054407dff..0b56f1de0ac 100644 --- a/homeassistant/components/light/rflink.py +++ b/homeassistant/components/light/rflink.py @@ -10,13 +10,16 @@ import logging from homeassistant.components.light import ( ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, Light) from homeassistant.components.rflink import ( - CONF_ALIASSES, CONF_AUTOMATIC_ADD, CONF_DEVICE_DEFAULTS, CONF_DEVICES, - CONF_FIRE_EVENT, CONF_GROUP, CONF_GROUP_ALIASSES, CONF_IGNORE_DEVICES, + CONF_ALIASES, CONF_ALIASSES, CONF_AUTOMATIC_ADD, CONF_DEVICE_DEFAULTS, + CONF_DEVICES, CONF_FIRE_EVENT, CONF_GROUP, CONF_GROUP_ALIASES, + CONF_GROUP_ALIASSES, CONF_IGNORE_DEVICES, CONF_NOGROUP_ALIASES, CONF_NOGROUP_ALIASSES, CONF_SIGNAL_REPETITIONS, DATA_DEVICE_REGISTER, DATA_ENTITY_GROUP_LOOKUP, DATA_ENTITY_LOOKUP, DEVICE_DEFAULTS_SCHEMA, - DOMAIN, EVENT_KEY_COMMAND, EVENT_KEY_ID, SwitchableRflinkDevice, cv, vol) + DOMAIN, EVENT_KEY_COMMAND, EVENT_KEY_ID, SwitchableRflinkDevice, cv, + remove_deprecated, vol) from homeassistant.const import ( CONF_NAME, CONF_PLATFORM, CONF_TYPE, STATE_UNKNOWN) +from homeassistant.helpers.deprecation import get_deprecated DEPENDENCIES = ['rflink'] @@ -39,15 +42,22 @@ PLATFORM_SCHEMA = vol.Schema({ vol.Optional(CONF_TYPE): vol.Any(TYPE_DIMMABLE, TYPE_SWITCHABLE, TYPE_HYBRID, TYPE_TOGGLE), - vol.Optional(CONF_ALIASSES, default=[]): + vol.Optional(CONF_ALIASES, default=[]): vol.All(cv.ensure_list, [cv.string]), - vol.Optional(CONF_GROUP_ALIASSES, default=[]): + vol.Optional(CONF_GROUP_ALIASES, default=[]): vol.All(cv.ensure_list, [cv.string]), - vol.Optional(CONF_NOGROUP_ALIASSES, default=[]): + vol.Optional(CONF_NOGROUP_ALIASES, default=[]): vol.All(cv.ensure_list, [cv.string]), vol.Optional(CONF_FIRE_EVENT, default=False): cv.boolean, vol.Optional(CONF_SIGNAL_REPETITIONS): vol.Coerce(int), vol.Optional(CONF_GROUP, default=True): cv.boolean, + # deprecated config options + vol.Optional(CONF_ALIASSES): + vol.All(cv.ensure_list, [cv.string]), + vol.Optional(CONF_GROUP_ALIASSES): + vol.All(cv.ensure_list, [cv.string]), + vol.Optional(CONF_NOGROUP_ALIASSES): + vol.All(cv.ensure_list, [cv.string]), }, }), }) @@ -103,6 +113,7 @@ def devices_from_config(domain_config, hass=None): entity_class = entity_class_for_type(entity_type) device_config = dict(domain_config[CONF_DEVICE_DEFAULTS], **config) + remove_deprecated(device_config) is_hybrid = entity_class is HybridRflinkLight @@ -117,25 +128,27 @@ def devices_from_config(domain_config, hass=None): device = entity_class(device_id, hass, **device_config) devices.append(device) - # Register entity (and aliasses) to listen to incoming rflink events + # Register entity (and aliases) to listen to incoming rflink events - # Device id and normal aliasses respond to normal and group command + # Device id and normal aliases respond to normal and group command hass.data[DATA_ENTITY_LOOKUP][ EVENT_KEY_COMMAND][device_id].append(device) if config[CONF_GROUP]: hass.data[DATA_ENTITY_GROUP_LOOKUP][ EVENT_KEY_COMMAND][device_id].append(device) - for _id in config[CONF_ALIASSES]: + for _id in get_deprecated(config, CONF_ALIASES, CONF_ALIASSES): hass.data[DATA_ENTITY_LOOKUP][ EVENT_KEY_COMMAND][_id].append(device) hass.data[DATA_ENTITY_GROUP_LOOKUP][ EVENT_KEY_COMMAND][_id].append(device) - # group_aliasses only respond to group commands - for _id in config[CONF_GROUP_ALIASSES]: + # group_aliases only respond to group commands + for _id in get_deprecated( + config, CONF_GROUP_ALIASES, CONF_GROUP_ALIASSES): hass.data[DATA_ENTITY_GROUP_LOOKUP][ EVENT_KEY_COMMAND][_id].append(device) - # nogroup_aliasses only respond to normal commands - for _id in config[CONF_NOGROUP_ALIASSES]: + # nogroup_aliases only respond to normal commands + for _id in get_deprecated( + config, CONF_NOGROUP_ALIASES, CONF_NOGROUP_ALIASSES): hass.data[DATA_ENTITY_LOOKUP][ EVENT_KEY_COMMAND][_id].append(device) diff --git a/homeassistant/components/rflink.py b/homeassistant/components/rflink.py index 6de5788b1dc..2cdce927cd8 100644 --- a/homeassistant/components/rflink.py +++ b/homeassistant/components/rflink.py @@ -10,15 +10,15 @@ import functools as ft import logging import async_timeout -import voluptuous as vol - from homeassistant.const import ( ATTR_ENTITY_ID, CONF_HOST, CONF_PORT, EVENT_HOMEASSISTANT_STOP, STATE_UNKNOWN) from homeassistant.core import CoreState, callback from homeassistant.exceptions import HomeAssistantError import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.deprecation import get_deprecated from homeassistant.helpers.entity import Entity +import voluptuous as vol REQUIREMENTS = ['rflink==0.0.34'] @@ -27,9 +27,12 @@ _LOGGER = logging.getLogger(__name__) ATTR_EVENT = 'event' ATTR_STATE = 'state' +CONF_ALIASES = 'aliases' CONF_ALIASSES = 'aliasses' +CONF_GROUP_ALIASES = 'group_aliases' CONF_GROUP_ALIASSES = 'group_aliasses' CONF_GROUP = 'group' +CONF_NOGROUP_ALIASES = 'nogroup_aliases' CONF_NOGROUP_ALIASSES = 'nogroup_aliasses' CONF_DEVICE_DEFAULTS = 'device_defaults' CONF_DEVICES = 'devices' @@ -219,8 +222,8 @@ class RflinkDevice(Entity): platform = None _state = STATE_UNKNOWN - def __init__(self, device_id, hass, name=None, aliasses=None, group=True, - group_aliasses=None, nogroup_aliasses=None, fire_event=False, + def __init__(self, device_id, hass, name=None, aliases=None, group=True, + group_aliases=None, nogroup_aliases=None, fire_event=False, signal_repetitions=DEFAULT_SIGNAL_REPETITIONS): """Initialize the device.""" self.hass = hass @@ -398,3 +401,24 @@ class SwitchableRflinkDevice(RflinkCommand): def async_turn_off(self, **kwargs): """Turn the device off.""" return self._async_handle_command("turn_off") + + +DEPRECATED_CONFIG_OPTIONS = [ + CONF_ALIASSES, + CONF_GROUP_ALIASSES, + CONF_NOGROUP_ALIASSES] +REPLACEMENT_CONFIG_OPTIONS = [ + CONF_ALIASES, + CONF_GROUP_ALIASES, + CONF_NOGROUP_ALIASES] + + +def remove_deprecated(config): + """Remove deprecated config options from device config.""" + for index, deprecated_option in enumerate(DEPRECATED_CONFIG_OPTIONS): + if deprecated_option in config: + replacement_option = REPLACEMENT_CONFIG_OPTIONS[index] + # generate deprecation warning + get_deprecated(config, replacement_option, deprecated_option) + # remove old config value replacing new one + config[replacement_option] = config.pop(deprecated_option) diff --git a/homeassistant/components/sensor/rflink.py b/homeassistant/components/sensor/rflink.py index c6660701c21..0d5fc283e32 100644 --- a/homeassistant/components/sensor/rflink.py +++ b/homeassistant/components/sensor/rflink.py @@ -9,9 +9,9 @@ from functools import partial import logging from homeassistant.components.rflink import ( - CONF_ALIASSES, CONF_AUTOMATIC_ADD, CONF_DEVICES, DATA_DEVICE_REGISTER, - DATA_ENTITY_LOOKUP, DOMAIN, EVENT_KEY_ID, EVENT_KEY_SENSOR, EVENT_KEY_UNIT, - RflinkDevice, cv, vol) + CONF_ALIASES, CONF_ALIASSES, CONF_AUTOMATIC_ADD, CONF_DEVICES, + DATA_DEVICE_REGISTER, DATA_ENTITY_LOOKUP, DOMAIN, EVENT_KEY_ID, + EVENT_KEY_SENSOR, EVENT_KEY_UNIT, RflinkDevice, cv, remove_deprecated, vol) from homeassistant.const import ( ATTR_UNIT_OF_MEASUREMENT, CONF_NAME, CONF_PLATFORM, CONF_UNIT_OF_MEASUREMENT) @@ -36,7 +36,10 @@ PLATFORM_SCHEMA = vol.Schema({ vol.Optional(CONF_NAME): cv.string, vol.Required(CONF_SENSOR_TYPE): cv.string, vol.Optional(CONF_UNIT_OF_MEASUREMENT, default=None): cv.string, - vol.Optional(CONF_ALIASSES, default=[]): + vol.Optional(CONF_ALIASES, default=[]): + vol.All(cv.ensure_list, [cv.string]), + # deprecated config options + vol.Optional(CONF_ALIASSES): vol.All(cv.ensure_list, [cv.string]), }, }), @@ -61,6 +64,7 @@ def devices_from_config(domain_config, hass=None): if not config[ATTR_UNIT_OF_MEASUREMENT]: config[ATTR_UNIT_OF_MEASUREMENT] = lookup_unit_for_sensor_type( config[CONF_SENSOR_TYPE]) + remove_deprecated(config) device = RflinkSensor(device_id, hass, **config) devices.append(device) diff --git a/homeassistant/components/switch/rflink.py b/homeassistant/components/switch/rflink.py index 58b1e0959af..29e93342f66 100644 --- a/homeassistant/components/switch/rflink.py +++ b/homeassistant/components/switch/rflink.py @@ -8,13 +8,15 @@ import asyncio import logging from homeassistant.components.rflink import ( - CONF_ALIASSES, CONF_DEVICE_DEFAULTS, CONF_DEVICES, CONF_FIRE_EVENT, - CONF_GROUP, CONF_GROUP_ALIASSES, CONF_NOGROUP_ALIASSES, - CONF_SIGNAL_REPETITIONS, DATA_ENTITY_GROUP_LOOKUP, DATA_ENTITY_LOOKUP, - DEVICE_DEFAULTS_SCHEMA, DOMAIN, EVENT_KEY_COMMAND, SwitchableRflinkDevice, - cv, vol) + CONF_ALIASES, CONF_ALIASSES, CONF_DEVICE_DEFAULTS, CONF_DEVICES, + CONF_FIRE_EVENT, CONF_GROUP, CONF_GROUP_ALIASES, CONF_GROUP_ALIASSES, + CONF_NOGROUP_ALIASES, CONF_NOGROUP_ALIASSES, CONF_SIGNAL_REPETITIONS, + DATA_ENTITY_GROUP_LOOKUP, DATA_ENTITY_LOOKUP, DEVICE_DEFAULTS_SCHEMA, + DOMAIN, EVENT_KEY_COMMAND, SwitchableRflinkDevice, cv, remove_deprecated, + vol) from homeassistant.components.switch import SwitchDevice from homeassistant.const import CONF_NAME, CONF_PLATFORM +from homeassistant.helpers.deprecation import get_deprecated DEPENDENCIES = ['rflink'] @@ -27,15 +29,22 @@ PLATFORM_SCHEMA = vol.Schema({ vol.Optional(CONF_DEVICES, default={}): vol.Schema({ cv.string: { vol.Optional(CONF_NAME): cv.string, - vol.Optional(CONF_ALIASSES, default=[]): + vol.Optional(CONF_ALIASES, default=[]): vol.All(cv.ensure_list, [cv.string]), - vol.Optional(CONF_GROUP_ALIASSES, default=[]): + vol.Optional(CONF_GROUP_ALIASES, default=[]): vol.All(cv.ensure_list, [cv.string]), - vol.Optional(CONF_NOGROUP_ALIASSES, default=[]): + vol.Optional(CONF_NOGROUP_ALIASES, default=[]): vol.All(cv.ensure_list, [cv.string]), vol.Optional(CONF_FIRE_EVENT, default=False): cv.boolean, vol.Optional(CONF_SIGNAL_REPETITIONS): vol.Coerce(int), vol.Optional(CONF_GROUP, default=True): cv.boolean, + # deprecated config options + vol.Optional(CONF_ALIASSES): + vol.All(cv.ensure_list, [cv.string]), + vol.Optional(CONF_GROUP_ALIASSES): + vol.All(cv.ensure_list, [cv.string]), + vol.Optional(CONF_NOGROUP_ALIASSES): + vol.All(cv.ensure_list, [cv.string]), }, }), }) @@ -46,27 +55,30 @@ def devices_from_config(domain_config, hass=None): devices = [] for device_id, config in domain_config[CONF_DEVICES].items(): device_config = dict(domain_config[CONF_DEVICE_DEFAULTS], **config) + remove_deprecated(device_config) device = RflinkSwitch(device_id, hass, **device_config) devices.append(device) - # Register entity (and aliasses) to listen to incoming rflink events - # Device id and normal aliasses respond to normal and group command + # Register entity (and aliases) to listen to incoming rflink events + # Device id and normal aliases respond to normal and group command hass.data[DATA_ENTITY_LOOKUP][ EVENT_KEY_COMMAND][device_id].append(device) if config[CONF_GROUP]: hass.data[DATA_ENTITY_GROUP_LOOKUP][ EVENT_KEY_COMMAND][device_id].append(device) - for _id in config[CONF_ALIASSES]: + for _id in get_deprecated(config, CONF_ALIASES, CONF_ALIASSES): hass.data[DATA_ENTITY_LOOKUP][ EVENT_KEY_COMMAND][_id].append(device) hass.data[DATA_ENTITY_GROUP_LOOKUP][ EVENT_KEY_COMMAND][_id].append(device) - # group_aliasses only respond to group commands - for _id in config[CONF_GROUP_ALIASSES]: + # group_aliases only respond to group commands + for _id in get_deprecated( + config, CONF_GROUP_ALIASES, CONF_GROUP_ALIASSES): hass.data[DATA_ENTITY_GROUP_LOOKUP][ EVENT_KEY_COMMAND][_id].append(device) - # nogroup_aliasses only respond to normal commands - for _id in config[CONF_NOGROUP_ALIASSES]: + # nogroup_aliases only respond to normal commands + for _id in get_deprecated( + config, CONF_NOGROUP_ALIASES, CONF_NOGROUP_ALIASSES): hass.data[DATA_ENTITY_LOOKUP][ EVENT_KEY_COMMAND][_id].append(device) diff --git a/tests/components/light/test_rflink.py b/tests/components/light/test_rflink.py index 03180c47a4a..25f83b1d123 100644 --- a/tests/components/light/test_rflink.py +++ b/tests/components/light/test_rflink.py @@ -27,7 +27,7 @@ CONFIG = { 'devices': { 'protocol_0_0': { 'name': 'test', - 'aliasses': ['test_alias_0_0'], + 'aliases': ['test_alias_0_0'], }, 'dimmable_0_0': { 'name': 'dim_test', @@ -58,7 +58,7 @@ def test_default_setup(hass, monkeypatch): assert light_initial.attributes['assumed_state'] # light should follow state of the hardware device by interpreting - # incoming events for its name and aliasses + # incoming events for its name and aliases # mock incoming command event for this device event_callback({ @@ -100,7 +100,7 @@ def test_default_setup(hass, monkeypatch): assert hass.states.get(DOMAIN + '.test').state == 'off' - # test following aliasses + # test following aliases # mock incoming command event for this device alias event_callback({ 'id': 'test_alias_0_0', @@ -185,7 +185,7 @@ def test_firing_bus_event(hass, monkeypatch): 'devices': { 'protocol_0_0': { 'name': 'test', - 'aliasses': ['test_alias_0_0'], + 'aliases': ['test_alias_0_0'], 'fire_event': True, }, }, @@ -418,7 +418,7 @@ def test_group_alias(hass, monkeypatch): 'devices': { 'protocol_0_0': { 'name': 'test', - 'group_aliasses': ['test_group_0_0'], + 'group_aliases': ['test_group_0_0'], }, }, }, @@ -461,7 +461,7 @@ def test_nogroup_alias(hass, monkeypatch): 'devices': { 'protocol_0_0': { 'name': 'test', - 'nogroup_aliasses': ['test_nogroup_0_0'], + 'nogroup_aliases': ['test_nogroup_0_0'], }, }, }, diff --git a/tests/components/switch/test_rflink.py b/tests/components/switch/test_rflink.py index d48c9aca7a4..b261d9c9b49 100644 --- a/tests/components/switch/test_rflink.py +++ b/tests/components/switch/test_rflink.py @@ -24,7 +24,7 @@ CONFIG = { 'devices': { 'protocol_0_0': { 'name': 'test', - 'aliasses': ['test_alias_0_0'], + 'aliases': ['test_alias_0_0'], }, }, }, @@ -47,7 +47,7 @@ def test_default_setup(hass, monkeypatch): assert switch_initial.attributes['assumed_state'] # switch should follow state of the hardware device by interpreting - # incoming events for its name and aliasses + # incoming events for its name and aliases # mock incoming command event for this device event_callback({ @@ -70,7 +70,7 @@ def test_default_setup(hass, monkeypatch): assert hass.states.get('switch.test').state == 'off' - # test following aliasses + # test following aliases # mock incoming command event for this device alias event_callback({ 'id': 'test_alias_0_0', @@ -112,7 +112,7 @@ def test_group_alias(hass, monkeypatch): 'devices': { 'protocol_0_0': { 'name': 'test', - 'group_aliasses': ['test_group_0_0'], + 'group_aliases': ['test_group_0_0'], }, }, }, @@ -155,7 +155,7 @@ def test_nogroup_alias(hass, monkeypatch): 'devices': { 'protocol_0_0': { 'name': 'test', - 'nogroup_aliasses': ['test_nogroup_0_0'], + 'nogroup_aliases': ['test_nogroup_0_0'], }, }, }, diff --git a/tests/components/test_rflink.py b/tests/components/test_rflink.py index 9a83644dcfd..ce6b473b465 100644 --- a/tests/components/test_rflink.py +++ b/tests/components/test_rflink.py @@ -99,7 +99,7 @@ def test_send_no_wait(hass, monkeypatch): 'devices': { 'protocol_0_0': { 'name': 'test', - 'aliasses': ['test_alias_0_0'], + 'aliases': ['test_alias_0_0'], }, }, }, @@ -192,7 +192,7 @@ def test_error_when_not_connected(hass, monkeypatch): 'devices': { 'protocol_0_0': { 'name': 'test', - 'aliasses': ['test_alias_0_0'], + 'aliases': ['test_alias_0_0'], }, }, }, From 20a989935451e179fd584fea8eab9c0e8317fbd3 Mon Sep 17 00:00:00 2001 From: clarkewd Date: Thu, 6 Jul 2017 15:09:31 -0400 Subject: [PATCH 046/131] Allow Pilight Binary Sensor to control reset_delay_sec through configuration (#8358) * Allow Pilight Binary Sensor to control reset_delay_sec through configuration * Define constant in platform * Don't define constant twice --- homeassistant/components/binary_sensor/pilight.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/binary_sensor/pilight.py b/homeassistant/components/binary_sensor/pilight.py index d0774ae12e6..c4c26d3a122 100644 --- a/homeassistant/components/binary_sensor/pilight.py +++ b/homeassistant/components/binary_sensor/pilight.py @@ -28,6 +28,7 @@ from homeassistant.util import dt as dt_util _LOGGER = logging.getLogger(__name__) CONF_VARIABLE = 'variable' +CONF_RESET_DELAY_SEC = 'reset_delay_sec' DEFAULT_NAME = 'Pilight Binary Sensor' DEPENDENCIES = ['pilight'] @@ -38,7 +39,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_PAYLOAD_ON, default='on'): cv.string, vol.Optional(CONF_PAYLOAD_OFF, default='off'): cv.string, - vol.Optional(CONF_DISARM_AFTER_TRIGGER, default=False): cv.boolean + vol.Optional(CONF_DISARM_AFTER_TRIGGER, default=False): cv.boolean, + vol.Optional(CONF_RESET_DELAY_SEC, default=30): cv.positive_int }) @@ -54,6 +56,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): payload=config.get(CONF_PAYLOAD), on_value=config.get(CONF_PAYLOAD_ON), off_value=config.get(CONF_PAYLOAD_OFF), + rst_dly_sec=config.get(CONF_RESET_DELAY_SEC), )]) else: add_devices([PilightBinarySensor( From c63bdd5afe9e0e158c420c09732bcff1bc88f327 Mon Sep 17 00:00:00 2001 From: Michael Heinemann Date: Thu, 6 Jul 2017 23:47:30 +0200 Subject: [PATCH 047/131] Mqtt client_id fix for #8315 (#8366) This applies what was the intended fix in #8336. moves the fallback for setting client_id to the case when no mqtt config was provided at all. This should reflect the most common use case that fails. This commit is a workaround and should be reverted when hbmqtt is fixed to allow empty client_id again. --- homeassistant/components/mqtt/__init__.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 64e804d7715..f5a66412962 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -315,15 +315,14 @@ def async_setup(hass, config): client_cert = conf.get(CONF_CLIENT_CERT) tls_insecure = conf.get(CONF_TLS_INSECURE) protocol = conf[CONF_PROTOCOL] - - # hbmqtt requires a client id to be set. - if client_id is None: - client_id = 'home-assistant' elif broker_config: # If no broker passed in, auto config to internal server broker, port, username, password, certificate, protocol = broker_config # Embedded broker doesn't have some ssl variables client_key, client_cert, tls_insecure = None, None, None + # hbmqtt requires a client id to be set. + if client_id is None: + client_id = 'home-assistant' else: err = "Unable to start MQTT broker." if conf.get(CONF_EMBEDDED) is not None: From fa4aa2244ebdafa8e4c655335e8ab3761eb880b9 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 6 Jul 2017 20:58:21 -0700 Subject: [PATCH 048/131] Allow all panel urls (#8368) * Allow all panel urls * Lint --- homeassistant/components/frontend/__init__.py | 22 ++++++++----------- tests/components/test_frontend.py | 4 ---- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index 8d55ad879fa..7fd65d44227 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -8,8 +8,7 @@ import os from aiohttp import web from homeassistant.core import callback -from homeassistant.const import HTTP_NOT_FOUND -from homeassistant.components import api, group +from homeassistant.components import api from homeassistant.components.http import HomeAssistantView from homeassistant.components.http.auth import is_trusted_ip from homeassistant.components.http.const import KEY_DEVELOPMENT @@ -138,6 +137,8 @@ def register_panel(hass, component_name, path, md5=None, sidebar_title=None, if index_view: hass.http.app.router.add_route( 'get', '/{}'.format(url_path), index_view.get) + hass.http.app.router.add_route( + 'get', '/{}/{{extra:.+}}'.format(url_path), index_view.get) def add_manifest_json_key(key, val): @@ -172,8 +173,10 @@ def setup(hass, config): # Now register their urls. if DATA_PANELS in hass.data: for url_path in hass.data[DATA_PANELS]: - hass.http.app.router.add_route('get', '/{}'.format(url_path), - index_view.get) + hass.http.app.router.add_route( + 'get', '/{}'.format(url_path), index_view.get) + hass.http.app.router.add_route( + 'get', '/{}/{{extra:.+}}'.format(url_path), index_view.get) else: hass.data[DATA_PANELS] = {} @@ -212,7 +215,7 @@ class IndexView(HomeAssistantView): url = '/' name = 'frontend:index' requires_auth = False - extra_urls = ['/states', '/states/{entity_id}'] + extra_urls = ['/states', '/states/{extra}'] def __init__(self): """Initialize the frontend view.""" @@ -225,17 +228,10 @@ class IndexView(HomeAssistantView): ) @asyncio.coroutine - def get(self, request, entity_id=None): + def get(self, request, extra=None): """Serve the index view.""" hass = request.app['hass'] - if entity_id is not None: - state = hass.states.get(entity_id) - - if (not state or state.domain != 'group' or - not state.attributes.get(group.ATTR_VIEW)): - return self.json_message('Entity not found', HTTP_NOT_FOUND) - if request.app[KEY_DEVELOPMENT]: core_url = '/static/home-assistant-polymer/build/core.js' compatibility_url = \ diff --git a/tests/components/test_frontend.py b/tests/components/test_frontend.py index ce6fce03e83..3d9798800d7 100644 --- a/tests/components/test_frontend.py +++ b/tests/components/test_frontend.py @@ -61,9 +61,5 @@ def test_states_routes(hass, mock_http_client): resp = yield from mock_http_client.get('/states') assert resp.status == 200 - resp = yield from mock_http_client.get('/states/group.non_existing') - assert resp.status == 404 - - hass.states.async_set('group.existing', 'on', {'view': True}) resp = yield from mock_http_client.get('/states/group.existing') assert resp.status == 200 From da37380410fd6d037310c153fb591c3849b0f566 Mon Sep 17 00:00:00 2001 From: John Mihalic Date: Fri, 7 Jul 2017 00:23:47 -0400 Subject: [PATCH 049/131] Update pyHik to catch XML errors (#8384) --- homeassistant/components/binary_sensor/hikvision.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/binary_sensor/hikvision.py b/homeassistant/components/binary_sensor/hikvision.py index 61e69e991b3..7f2127fcad5 100644 --- a/homeassistant/components/binary_sensor/hikvision.py +++ b/homeassistant/components/binary_sensor/hikvision.py @@ -18,7 +18,7 @@ from homeassistant.const import ( CONF_SSL, EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_START, ATTR_LAST_TRIP_TIME, CONF_CUSTOMIZE) -REQUIREMENTS = ['pyhik==0.1.2'] +REQUIREMENTS = ['pyhik==0.1.3'] _LOGGER = logging.getLogger(__name__) CONF_IGNORED = 'ignored' diff --git a/requirements_all.txt b/requirements_all.txt index f2dd1789c0a..4ab1a63a872 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -570,7 +570,7 @@ pygatt==3.1.1 pyharmony==1.0.16 # homeassistant.components.binary_sensor.hikvision -pyhik==0.1.2 +pyhik==0.1.3 # homeassistant.components.homematic pyhomematic==0.1.28 From 692f4c293b9334db0d5d1730826437a69c6d5435 Mon Sep 17 00:00:00 2001 From: "Craig J. Ward" Date: Thu, 6 Jul 2017 23:24:04 -0500 Subject: [PATCH 050/131] update version (#8380) --- homeassistant/components/alarm_control_panel/totalconnect.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/alarm_control_panel/totalconnect.py b/homeassistant/components/alarm_control_panel/totalconnect.py index 13925d7bd02..9c0b5108fee 100644 --- a/homeassistant/components/alarm_control_panel/totalconnect.py +++ b/homeassistant/components/alarm_control_panel/totalconnect.py @@ -16,7 +16,7 @@ from homeassistant.const import ( STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_UNKNOWN, CONF_NAME) -REQUIREMENTS = ['total_connect_client==0.7'] +REQUIREMENTS = ['total_connect_client==0.11'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 4ab1a63a872..cca647238fc 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -880,7 +880,7 @@ thingspeak==0.4.1 tikteck==0.4 # homeassistant.components.alarm_control_panel.totalconnect -total_connect_client==0.7 +total_connect_client==0.11 # homeassistant.components.sensor.transmission # homeassistant.components.switch.transmission From db8bb53984b964c62b66d14b2f301cd0de77508f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre=20St=C3=A5hl?= Date: Fri, 7 Jul 2017 06:25:54 +0200 Subject: [PATCH 051/131] Add One-Time Password sensor (OTP) (#8332) --- .coveragerc | 1 + homeassistant/components/sensor/otp.py | 90 ++++++++++++++++++++++++++ requirements_all.txt | 3 + 3 files changed, 94 insertions(+) create mode 100644 homeassistant/components/sensor/otp.py diff --git a/.coveragerc b/.coveragerc index 1f2454fc292..bdab049329a 100644 --- a/.coveragerc +++ b/.coveragerc @@ -453,6 +453,7 @@ omit = homeassistant/components/sensor/openexchangerates.py homeassistant/components/sensor/opensky.py homeassistant/components/sensor/openweathermap.py + homeassistant/components/sensor/otp.py homeassistant/components/sensor/pi_hole.py homeassistant/components/sensor/plex.py homeassistant/components/sensor/pocketcasts.py diff --git a/homeassistant/components/sensor/otp.py b/homeassistant/components/sensor/otp.py new file mode 100644 index 00000000000..5d7808ea4c7 --- /dev/null +++ b/homeassistant/components/sensor/otp.py @@ -0,0 +1,90 @@ +""" +Support for One-Time Password (OTP). + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.otp/ +""" +import time +import asyncio +import logging + +import voluptuous as vol + +from homeassistant.core import callback +import homeassistant.helpers.config_validation as cv +from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.const import (CONF_NAME, CONF_TOKEN) +from homeassistant.helpers.entity import Entity + +REQUIREMENTS = ['pyotp==2.2.6'] + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_NAME = 'OTP Sensor' + +TIME_STEP = 30 # Default time step assumed by Google Authenticator + +ICON = 'mdi:update' + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_TOKEN): cv.string, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, +}) + + +@asyncio.coroutine +def async_setup_platform(hass, config, async_add_devices, discovery_info=None): + """Set up the OTP sensor.""" + name = config.get(CONF_NAME) + token = config.get(CONF_TOKEN) + + async_add_devices([TOTPSensor(name, token)], True) + return True + + +# Only TOTP supported at the moment, HOTP might be added later +class TOTPSensor(Entity): + """Representation of a TOTP sensor.""" + + def __init__(self, name, token): + """Initialize the sensor.""" + import pyotp + self._name = name + self._otp = pyotp.TOTP(token) + self._state = None + self._next_expiration = None + + @asyncio.coroutine + def async_added_to_hass(self): + """Handle when an entity is about to be added to Home Assistant.""" + self._call_loop() + + @callback + def _call_loop(self): + self._state = self._otp.now() + self.hass.async_add_job(self.async_update_ha_state()) + + # Update must occur at even TIME_STEP, e.g. 12:00:00, 12:00:30, + # 12:01:00, etc. in order to have synced time (see RFC6238) + self._next_expiration = TIME_STEP - (time.time() % TIME_STEP) + self.hass.loop.call_later(self._next_expiration, self._call_loop) + + @property + def name(self): + """Return the name of the sensor.""" + return self._name + + @property + def state(self): + """Return the state of the sensor.""" + return self._state + + @property + def should_poll(self): + """No polling needed.""" + return False + + @property + def icon(self): + """Return the icon to use in the frontend.""" + return ICON diff --git a/requirements_all.txt b/requirements_all.txt index cca647238fc..814b61a3e58 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -643,6 +643,9 @@ pynut2==2.1.2 # homeassistant.components.binary_sensor.nx584 pynx584==0.4 +# homeassistant.components.sensor.otp +pyotp==2.2.6 + # homeassistant.components.sensor.openweathermap # homeassistant.components.weather.openweathermap pyowm==2.7.1 From 5e71e9b826a076da3827810f2165adf6ffd7fcbe Mon Sep 17 00:00:00 2001 From: mjj4791 Date: Fri, 7 Jul 2017 06:39:28 +0200 Subject: [PATCH 052/131] buienradar==0.7, fix winddirection/azimuth, logging (#8281) * buienradar==0.7, fix winddirection/azimuth, logging * prevent multiple update cycles * prevent multiple update cycles * prevent multiple sensor updates for precipitation forecast * prevent multiple sensor updates for precipitation forecast * Update comments * Adapted logging * Adapted logging --- homeassistant/components/sensor/buienradar.py | 125 +++++++++++++----- .../components/weather/buienradar.py | 12 +- requirements_all.txt | 3 +- 3 files changed, 96 insertions(+), 44 deletions(-) diff --git a/homeassistant/components/sensor/buienradar.py b/homeassistant/components/sensor/buienradar.py index e65353daadb..753782786d7 100755 --- a/homeassistant/components/sensor/buienradar.py +++ b/homeassistant/components/sensor/buienradar.py @@ -23,11 +23,18 @@ from homeassistant.helpers.event import ( async_track_point_in_utc_time) from homeassistant.util import dt as dt_util -REQUIREMENTS = ['buienradar==0.6'] +REQUIREMENTS = ['buienradar==0.7'] _LOGGER = logging.getLogger(__name__) +TIMEFRAME_LABEL = 'Timeframe' +# Schedule next call after (minutes): +SCHEDULE_OK = 10 +# When an error occurred, new call after (minutes): +SCHEDULE_NOK = 2 + # Supported sensor types: +# Key: ['label', unit, icon] SENSOR_TYPES = { 'stationname': ['Stationname', None, None], 'symbol': ['Symbol', None, None], @@ -47,7 +54,7 @@ SENSOR_TYPES = { 'precipitation_forecast_average': ['Precipitation forecast average', 'mm/h', 'mdi:weather-pouring'], 'precipitation_forecast_total': ['Precipitation forecast total', - 'mm/h', 'mdi:weather-pouring'] + 'mm', 'mdi:weather-pouring'] } CONF_TIMEFRAME = 'timeframe' @@ -61,13 +68,14 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ 'Latitude and longitude must exist together'): cv.latitude, vol.Inclusive(CONF_LONGITUDE, 'coordinates', 'Latitude and longitude must exist together'): cv.longitude, - vol.Optional(CONF_TIMEFRAME): cv.positive_int + vol.Optional(CONF_TIMEFRAME, default=60): + vol.All(vol.Coerce(int), vol.Range(min=5, max=120)), }) @asyncio.coroutine def async_setup_platform(hass, config, async_add_devices, discovery_info=None): - """Setup the buienradar sensor.""" + """Create the buienradar sensor.""" from homeassistant.components.weather.buienradar import DEFAULT_TIMEFRAME latitude = config.get(CONF_LATITUDE, hass.config.latitude) @@ -81,6 +89,9 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): coordinates = {CONF_LATITUDE: float(latitude), CONF_LONGITUDE: float(longitude)} + _LOGGER.debug("Initializing buienradar sensor coordinate %s, timeframe %s", + coordinates, timeframe) + dev = [] for sensor_type in config[CONF_MONITORED_CONDITIONS]: dev.append(BrSensor(sensor_type, config.get(CONF_NAME, 'br'))) @@ -88,7 +99,6 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): data = BrData(hass, coordinates, timeframe, dev) # schedule the first update in 1 minute from now: - _LOGGER.debug("Start running....") yield from data.schedule_update(1) @@ -97,6 +107,8 @@ class BrSensor(Entity): def __init__(self, sensor_type, client_name): """Initialize the sensor.""" + from buienradar.buienradar import (PRECIPITATION_FORECAST) + self.client_name = client_name self._name = SENSOR_TYPES[sensor_type][0] self.type = sensor_type @@ -104,16 +116,22 @@ class BrSensor(Entity): self._unit_of_measurement = SENSOR_TYPES[self.type][1] self._entity_picture = None self._attribution = None + self._measured = None self._stationname = None + if self.type.startswith(PRECIPITATION_FORECAST): + self._timeframe = None + def load_data(self, data): """Load the sensor with relevant data.""" # Find sensor - from buienradar.buienradar import (ATTRIBUTION, IMAGE, STATIONNAME, - SYMBOL, PRECIPITATION_FORECAST) + from buienradar.buienradar import (ATTRIBUTION, IMAGE, MEASURED, + PRECIPITATION_FORECAST, STATIONNAME, + SYMBOL, TIMEFRAME) self._attribution = data.get(ATTRIBUTION) self._stationname = data.get(STATIONNAME) + self._measured = data.get(MEASURED) if self.type == SYMBOL: # update weather symbol & status text new_state = data.get(self.type) @@ -124,21 +142,26 @@ class BrSensor(Entity): self._state = new_state self._entity_picture = img return True - elif self.type.startswith(PRECIPITATION_FORECAST): + return False + + if self.type.startswith(PRECIPITATION_FORECAST): # update nested precipitation forecast sensors nested = data.get(PRECIPITATION_FORECAST) new_state = nested.get(self.type[len(PRECIPITATION_FORECAST)+1:]) + self._timeframe = nested.get(TIMEFRAME) # pylint: disable=protected-access if new_state != self._state: self._state = new_state return True - else: - # update all other sensors - new_state = data.get(self.type) - # pylint: disable=protected-access - if new_state != self._state: - self._state = new_state - return True + return False + + # update all other sensors + new_state = data.get(self.type) + # pylint: disable=protected-access + if new_state != self._state: + self._state = new_state + return True + return False @property def attribution(self): @@ -173,6 +196,15 @@ class BrSensor(Entity): @property def device_state_attributes(self): """Return the state attributes.""" + from buienradar.buienradar import (PRECIPITATION_FORECAST) + + if self.type.startswith(PRECIPITATION_FORECAST): + result = {ATTR_ATTRIBUTION: self._attribution} + if self._timeframe is not None: + result[TIMEFRAME_LABEL] = "%d min" % (self._timeframe) + + return result + return { ATTR_ATTRIBUTION: self._attribution, SENSOR_TYPES['stationname'][0]: self._stationname, @@ -223,7 +255,7 @@ class BrData(object): @asyncio.coroutine def get_data(self, url): - """Load xmpl data from specified url.""" + """Load data from specified url.""" from buienradar.buienradar import (CONTENT, MESSAGE, STATUS_CODE, SUCCESS) @@ -235,14 +267,20 @@ class BrData(object): with async_timeout.timeout(10, loop=self.hass.loop): resp = yield from websession.get(url) - result[SUCCESS] = (resp.status == 200) result[STATUS_CODE] = resp.status result[CONTENT] = yield from resp.text() + if resp.status == 200: + result[SUCCESS] = True + else: + result[MESSAGE] = "Got http statuscode: %d" % (resp.status) return result except (asyncio.TimeoutError, aiohttp.ClientError) as err: result[MESSAGE] = "%s" % err return result + finally: + if resp is not None: + yield from resp.release() @asyncio.coroutine def async_update(self, *_): @@ -254,6 +292,16 @@ class BrData(object): if not content.get(SUCCESS, False): content = yield from self.get_data('http://api.buienradar.nl') + if content.get(SUCCESS) is not True: + # unable to get the data + _LOGGER.warning("Unable to retrieve xml data from Buienradar." + "(Msg: %s, status: %s,)", + content.get(MESSAGE), + content.get(STATUS_CODE),) + # schedule new call + yield from self.schedule_update(SCHEDULE_NOK) + return + # rounding coordinates prevents unnecessary redirects/calls rainurl = 'http://gadgets.buienradar.nl/data/raintext/?lat={}&lon={}' rainurl = rainurl.format( @@ -262,28 +310,33 @@ class BrData(object): ) raincontent = yield from self.get_data(rainurl) - if content.get(SUCCESS) and raincontent.get(SUCCESS): - result = parse_data(content.get(CONTENT), - raincontent.get(CONTENT), - self.coordinates[CONF_LATITUDE], - self.coordinates[CONF_LONGITUDE], - self.timeframe) - if result.get(SUCCESS): - self.data = result.get(DATA) - - yield from self.update_devices() - - yield from self.schedule_update(10) - else: - yield from self.schedule_update(2) - else: + if raincontent.get(SUCCESS) is not True: # unable to get the data - _LOGGER.warning("Unable to retrieve data from Buienradar." + _LOGGER.warning("Unable to retrieve raindata from Buienradar." "(Msg: %s, status: %s,)", - result.get(MESSAGE), - result.get(STATUS_CODE),) + raincontent.get(MESSAGE), + raincontent.get(STATUS_CODE),) # schedule new call - yield from self.schedule_update(2) + yield from self.schedule_update(SCHEDULE_NOK) + return + + result = parse_data(content.get(CONTENT), + raincontent.get(CONTENT), + self.coordinates[CONF_LATITUDE], + self.coordinates[CONF_LONGITUDE], + self.timeframe) + + _LOGGER.debug("Buienradar parsed data: %s", result) + if result.get(SUCCESS) is not True: + _LOGGER.warning("Unable to parse data from Buienradar." + "(Msg: %s)", + result.get(MESSAGE),) + yield from self.schedule_update(SCHEDULE_NOK) + return + + self.data = result.get(DATA) + yield from self.update_devices() + yield from self.schedule_update(SCHEDULE_OK) @property def attribution(self): diff --git a/homeassistant/components/weather/buienradar.py b/homeassistant/components/weather/buienradar.py index 5b425c0a42b..c6563509e71 100755 --- a/homeassistant/components/weather/buienradar.py +++ b/homeassistant/components/weather/buienradar.py @@ -6,7 +6,6 @@ https://home-assistant.io/components/weather.buienradar/ """ import logging import asyncio -from datetime import timedelta from homeassistant.components.weather import ( WeatherEntity, PLATFORM_SCHEMA) from homeassistant.const import \ @@ -15,10 +14,10 @@ from homeassistant.helpers import config_validation as cv # Reuse data and API logic from the sensor implementation from homeassistant.components.sensor.buienradar import ( BrData) -from homeassistant.helpers.event import ( - async_track_time_interval) import voluptuous as vol +REQUIREMENTS = ['buienradar==0.7'] + _LOGGER = logging.getLogger(__name__) DEFAULT_TIMEFRAME = 60 @@ -49,14 +48,13 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): # create weather data: data = BrData(hass, coordinates, DEFAULT_TIMEFRAME, None) # create weather device: + _LOGGER.debug("Initializing buienradar weather: coordinates %s", + coordinates) async_add_devices([BrWeather(data, config.get(CONF_FORECAST, True), config.get(CONF_NAME, None))]) - # Update weather every 10 minutes, since - # the data gets updated every 10 minutes - async_track_time_interval(hass, data.async_update, timedelta(minutes=10)) # schedule the first update in 1 minute from now: - data.schedule_update(1) + yield from data.schedule_update(1) class BrWeather(WeatherEntity): diff --git a/requirements_all.txt b/requirements_all.txt index 814b61a3e58..c6a868f7d38 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -118,7 +118,8 @@ boto3==1.4.3 broadlink==0.3 # homeassistant.components.sensor.buienradar -buienradar==0.6 +# homeassistant.components.weather.buienradar +buienradar==0.7 # homeassistant.components.notify.ciscospark ciscosparkapi==0.4.2 From 8a7cfce67b34b374445c872ac034477e266e4746 Mon Sep 17 00:00:00 2001 From: Teemu R Date: Fri, 7 Jul 2017 06:44:34 +0200 Subject: [PATCH 053/131] Add component for xiaomi robot vacuum (switch.xiaomi_vacuum) (#7913) * add component for xiaomi robot vacuum (switch.xiaomi_vacuum) * enforce token length, update requirements_all.txt and .coveragerc * bump version to avoid catching generic exception --- .coveragerc | 1 + .../components/switch/xiaomi_vacuum.py | 124 ++++++++++++++++++ requirements_all.txt | 3 + 3 files changed, 128 insertions(+) create mode 100644 homeassistant/components/switch/xiaomi_vacuum.py diff --git a/.coveragerc b/.coveragerc index bdab049329a..f1150512225 100644 --- a/.coveragerc +++ b/.coveragerc @@ -515,6 +515,7 @@ omit = homeassistant/components/switch/tplink.py homeassistant/components/switch/transmission.py homeassistant/components/switch/wake_on_lan.py + homeassistant/components/switch/xiaomi_vacuum.py homeassistant/components/telegram_bot/* homeassistant/components/thingspeak.py homeassistant/components/tts/amazon_polly.py diff --git a/homeassistant/components/switch/xiaomi_vacuum.py b/homeassistant/components/switch/xiaomi_vacuum.py new file mode 100644 index 00000000000..cf18a673ccb --- /dev/null +++ b/homeassistant/components/switch/xiaomi_vacuum.py @@ -0,0 +1,124 @@ +""" +Support for Xiaomi Vacuum cleaner robot. + +For more details about this platform, please refer to the documentation +https://home-assistant.io/components/switch.xiaomi_vacuum/ +""" +import logging + +import voluptuous as vol + +import homeassistant.helpers.config_validation as cv +from homeassistant.components.switch import SwitchDevice, PLATFORM_SCHEMA +from homeassistant.const import (DEVICE_DEFAULT_NAME, + CONF_NAME, CONF_HOST, CONF_TOKEN) + +_LOGGER = logging.getLogger(__name__) + + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_HOST): cv.string, + vol.Required(CONF_TOKEN): vol.All(str, vol.Length(min=32, max=32)), + vol.Optional(CONF_NAME): cv.string, +}) + +REQUIREMENTS = ['python-mirobo==0.0.8'] + + +# pylint: disable=unused-argument +def setup_platform(hass, config, add_devices_callback, discovery_info=None): + """Set up the vacuum from config.""" + host = config.get(CONF_HOST) + name = config.get(CONF_NAME) + token = config.get(CONF_TOKEN) + + add_devices_callback([MiroboSwitch(name, host, token)]) + + +class MiroboSwitch(SwitchDevice): + """Representation of a Xiaomi Vacuum.""" + + def __init__(self, name, host, token): + """Initialize the vacuum switch.""" + self._name = name or DEVICE_DEFAULT_NAME + self._icon = 'mdi:broom' + self.host = host + self.token = token + + self._vacuum = None + self._state = None + self._state_attrs = {} + self._is_on = False + + @property + def name(self): + """Return the name of the device if any.""" + return self._name + + @property + def icon(self): + """Return the icon to use for device if any.""" + return self._icon + + @property + def available(self): + """Return true when state is known.""" + return self._state is not None + + @property + def device_state_attributes(self): + """Return the state attributes of the device.""" + return self._state_attrs + + @property + def is_on(self): + """Return true if switch is on.""" + return self._is_on + + @property + def vacuum(self): + """Property accessor for vacuum object.""" + if not self._vacuum: + from mirobo import Vacuum + _LOGGER.info("initializing with host %s token %s", + self.host, self.token) + self._vacuum = Vacuum(self.host, self.token) + + return self._vacuum + + def turn_on(self, **kwargs): + """Turn the vacuum on.""" + from mirobo import VacuumException + try: + self.vacuum.start() + self._is_on = True + except VacuumException as ex: + _LOGGER.error("Unable to start the vacuum: %s", ex) + + def turn_off(self, **kwargs): + """Turn the vacuum off and return to home.""" + from mirobo import VacuumException + try: + self.vacuum.stop() + self.vacuum.home() + self._is_on = False + except VacuumException as ex: + _LOGGER.error("Unable to turn off and return home: %s", ex) + + def update(self): + """Fetch state from the device.""" + from mirobo import VacuumException + try: + state = self.vacuum.status() + _LOGGER.debug("got state from the vacuum: %s", state) + + self._state_attrs = { + 'Status': state.state, 'Error': state.error, + 'Battery': state.battery, 'Fan': state.fanspeed, + 'Cleaning time': str(state.clean_time), + 'Cleaned area': state.clean_area} + + self._state = state.state_code + self._is_on = state.is_on + except VacuumException as ex: + _LOGGER.error("Got exception while fetching the state: %s", ex) diff --git a/requirements_all.txt b/requirements_all.txt index c6a868f7d38..e4598d72711 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -708,6 +708,9 @@ python-juicenet==0.0.5 # homeassistant.components.lirc # python-lirc==1.2.3 +# homeassistant.components.switch.xiaomi_vacuum +python-mirobo==0.0.8 + # homeassistant.components.media_player.mpd python-mpd2==0.5.5 From 12129f0e6a7d02f9ab44a291d8ee1d48d4ca02ab Mon Sep 17 00:00:00 2001 From: Sean Date: Fri, 7 Jul 2017 06:46:50 +0200 Subject: [PATCH 054/131] Try catch around database updates in recorder. Resolves 6919 (#8349) * Try catch around database updates in recorder. Resolves 6919 * Fixing failed test for line length * Catch only OperationalError and retry connections before giving up * Including alchemy exceptions in single function --- homeassistant/components/recorder/__init__.py | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/recorder/__init__.py b/homeassistant/components/recorder/__init__.py index 49af353aab8..63dbf9fc1b1 100644 --- a/homeassistant/components/recorder/__init__.py +++ b/homeassistant/components/recorder/__init__.py @@ -158,6 +158,7 @@ class Recorder(threading.Thread): """Start processing events to save.""" from .models import States, Events from homeassistant.components import persistent_notification + from sqlalchemy import exc tries = 1 connected = False @@ -273,14 +274,31 @@ class Recorder(threading.Thread): self.queue.task_done() continue - with session_scope(session=self.get_session()) as session: - dbevent = Events.from_event(event) - session.add(dbevent) + tries = 1 + updated = False + while not updated and tries <= 10: + if tries != 1: + time.sleep(CONNECT_RETRY_WAIT) + try: + with session_scope(session=self.get_session()) as session: + dbevent = Events.from_event(event) + session.add(dbevent) - if event.event_type == EVENT_STATE_CHANGED: - dbstate = States.from_event(event) - dbstate.event_id = dbevent.event_id - session.add(dbstate) + if event.event_type == EVENT_STATE_CHANGED: + dbstate = States.from_event(event) + dbstate.event_id = dbevent.event_id + session.add(dbstate) + updated = True + + except exc.OperationalError as err: + _LOGGER.error("Error in database connectivity: %s. " + "(retrying in %s seconds)", err, + CONNECT_RETRY_WAIT) + tries += 1 + + if not updated: + _LOGGER.error("Error in database update. Could not save " + "after %d tries. Giving up", tries) self.queue.task_done() From aa28e6727da82ab319817d550d2c65bbe3701514 Mon Sep 17 00:00:00 2001 From: Charles Blonde Date: Fri, 7 Jul 2017 07:19:05 +0200 Subject: [PATCH 055/131] Fix Amazon Polly with non english voices. #8377 (#8378) --- homeassistant/components/tts/amazon_polly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/tts/amazon_polly.py b/homeassistant/components/tts/amazon_polly.py index 9be882a4cb3..a75f71c3463 100644 --- a/homeassistant/components/tts/amazon_polly.py +++ b/homeassistant/components/tts/amazon_polly.py @@ -164,7 +164,7 @@ class AmazonPollyProvider(Provider): """Request TTS file from Polly.""" voice_id = options.get(CONF_VOICE, self.default_voice) voice_in_dict = self.all_voices.get(voice_id) - if language is not voice_in_dict.get('LanguageCode'): + if language != voice_in_dict.get('LanguageCode'): _LOGGER.error("%s does not support the %s language", voice_id, language) return (None, None) From 8682f21fc5797fdf9951863110f042e510d02333 Mon Sep 17 00:00:00 2001 From: Charles Blonde Date: Fri, 7 Jul 2017 07:20:49 +0200 Subject: [PATCH 056/131] Fix TTS options. #8375 (#8376) --- homeassistant/components/tts/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/tts/__init__.py b/homeassistant/components/tts/__init__.py index 888a1773189..9f36b2fb78f 100644 --- a/homeassistant/components/tts/__init__.py +++ b/homeassistant/components/tts/__init__.py @@ -280,7 +280,9 @@ class SpeechManager(object): # Options if provider.default_options and options: - options = provider.default_options.copy().update(options) + merged_options = provider.default_options.copy() + merged_options.update(options) + options = merged_options options = options or provider.default_options if options is not None: invalid_opts = [opt_name for opt_name in options.keys() From 63cc658010ff31e9051161cc0086d303512ec383 Mon Sep 17 00:00:00 2001 From: Open Home Automation Date: Fri, 7 Jul 2017 07:21:40 +0200 Subject: [PATCH 057/131] Add address-specific KNX listeners that fire events on the HASS bus (#8374) * Add address-specific KNX listeners that fire events on the HASS bus * Added docstring 1-byte messages will be converted from a list to the value * Formating --- homeassistant/components/knx.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/knx.py b/homeassistant/components/knx.py index 3a4b7c54400..30488113d7e 100644 --- a/homeassistant/components/knx.py +++ b/homeassistant/components/knx.py @@ -24,11 +24,14 @@ DOMAIN = 'knx' EVENT_KNX_FRAME_RECEIVED = 'knx_frame_received' KNXTUNNEL = None +CONF_LISTEN = "listen" CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string, vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, + vol.Optional(CONF_LISTEN, default=[]): + vol.All(cv.ensure_list, [cv.string]), }), }, extra=vol.ALLOW_EXTRA) @@ -38,7 +41,7 @@ def setup(hass, config): global KNXTUNNEL from knxip.ip import KNXIPTunnel - from knxip.core import KNXException + from knxip.core import KNXException, parse_group_address host = config[DOMAIN].get(CONF_HOST) port = config[DOMAIN].get(CONF_PORT) @@ -61,6 +64,24 @@ def setup(hass, config): _LOGGER.info("KNX IP tunnel to %s:%i established", host, port) + def received_knx_event(address, data): + """Process received KNX message.""" + if len(data) == 1: + data = data[0] + hass.bus.fire('knx_event', { + 'address': address, + 'data': data + }) + + for listen in config[DOMAIN].get(CONF_LISTEN): + _LOGGER.debug("Registering listener for %s", listen) + try: + KNXTUNNEL.register_listener(parse_group_address(listen), + received_knx_event) + except KNXException as knxexception: + _LOGGER.error("Can't register KNX listener for address %s (%s)", + listen, knxexception) + hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, close_tunnel) return True From 074e31bcf97ad3861fd4538a81e902a29a0982a0 Mon Sep 17 00:00:00 2001 From: Marc Plano-Lesay Date: Fri, 7 Jul 2017 07:22:31 +0200 Subject: [PATCH 058/131] GTFS: check start/end date on services (#8373) Fixes #8372 --- homeassistant/components/sensor/gtfs.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/sensor/gtfs.py b/homeassistant/components/sensor/gtfs.py index c5313a7c215..9aa9f14663c 100644 --- a/homeassistant/components/sensor/gtfs.py +++ b/homeassistant/components/sensor/gtfs.py @@ -52,6 +52,7 @@ def get_next_departure(sched, start_station_id, end_station_id, offset): now = datetime.datetime.now() + offset day_name = now.strftime('%A').lower() now_str = now.strftime('%H:%M:%S') + today = now.strftime('%Y-%m-%d') from sqlalchemy.sql import text @@ -89,11 +90,14 @@ def get_next_departure(sched, start_station_id, end_station_id, offset): AND start_station.stop_id = :origin_station_id AND end_station.stop_id = :end_station_id AND origin_stop_time.stop_sequence < destination_stop_time.stop_sequence + AND calendar.start_date <= :today + AND calendar.end_date >= :today ORDER BY origin_stop_time.departure_time LIMIT 1; """.format(day_name=day_name)) result = sched.engine.execute(sql_query, now_str=now_str, origin_station_id=origin_station.id, - end_station_id=destination_station.id) + end_station_id=destination_station.id, + today=today) item = {} for row in result: item = row @@ -101,7 +105,6 @@ def get_next_departure(sched, start_station_id, end_station_id, offset): if item == {}: return None - today = now.strftime('%Y-%m-%d') departure_time_string = '{} {}'.format(today, item[2]) arrival_time_string = '{} {}'.format(today, item[3]) departure_time = datetime.datetime.strptime(departure_time_string, From ecf3a9cb3677df3b84aefc3005f770e9b39fdf52 Mon Sep 17 00:00:00 2001 From: Open Home Automation Date: Fri, 7 Jul 2017 07:24:25 +0200 Subject: [PATCH 059/131] Implement KNX dimming functionality (#8371) * Implement KNX dimming functionality * Formatting * Formatting * Formatting --- homeassistant/components/light/knx.py | 77 ++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/light/knx.py b/homeassistant/components/light/knx.py index 6d5cd12c23e..d89d45e99a7 100644 --- a/homeassistant/components/light/knx.py +++ b/homeassistant/components/light/knx.py @@ -4,15 +4,22 @@ Support KNX Lighting actuators. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/Light.knx/ """ +import logging import voluptuous as vol -from homeassistant.components.knx import (KNXConfig, KNXGroupAddress) -from homeassistant.components.light import (Light, PLATFORM_SCHEMA) +from homeassistant.components.knx import (KNXConfig, KNXMultiAddressDevice) +from homeassistant.components.light import (Light, PLATFORM_SCHEMA, + SUPPORT_BRIGHTNESS, + ATTR_BRIGHTNESS) from homeassistant.const import CONF_NAME import homeassistant.helpers.config_validation as cv CONF_ADDRESS = 'address' CONF_STATE_ADDRESS = 'state_address' +CONF_BRIGHTNESS_ADDRESS = 'brightness_address' +CONF_BRIGHTNESS_STATE_ADDRESS = 'brightness_state_address' + +_LOGGER = logging.getLogger(__name__) DEFAULT_NAME = 'KNX Light' DEPENDENCIES = ['knx'] @@ -21,6 +28,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_ADDRESS): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_STATE_ADDRESS): cv.string, + vol.Optional(CONF_BRIGHTNESS_ADDRESS): cv.string, + vol.Optional(CONF_BRIGHTNESS_STATE_ADDRESS): cv.string, }) @@ -29,16 +38,41 @@ def setup_platform(hass, config, add_devices, discovery_info=None): add_devices([KNXLight(hass, KNXConfig(config))]) -class KNXLight(KNXGroupAddress, Light): +class KNXLight(KNXMultiAddressDevice, Light): """Representation of a KNX Light device.""" + def __init__(self, hass, config): + """Initialize the cover.""" + KNXMultiAddressDevice.__init__( + self, hass, config, + [], # required + optional=['state', 'brightness', 'brightness_state'] + ) + self._hass = hass + self._supported_features = 0 + + if CONF_BRIGHTNESS_ADDRESS in config.config: + _LOGGER.debug("%s is dimmable", self.name) + self._supported_features = self._supported_features | \ + SUPPORT_BRIGHTNESS + self._brightness = None + def turn_on(self, **kwargs): """Turn the switch on. This sends a value 1 to the group address of the device """ - self.group_write(1) - self._state = [1] + _LOGGER.debug("%s: turn on", self.name) + self.set_value('base', [1]) + self._state = 1 + + if ATTR_BRIGHTNESS in kwargs: + self._brightness = kwargs[ATTR_BRIGHTNESS] + _LOGGER.debug("turn_on requested brightness for light: %s is: %s ", + self.name, self._brightness) + assert self._brightness <= 255 + self.set_value("brightness", [self._brightness]) + if not self.should_poll: self.schedule_update_ha_state() @@ -47,7 +81,36 @@ class KNXLight(KNXGroupAddress, Light): This sends a value 1 to the group address of the device """ - self.group_write(0) - self._state = [0] + _LOGGER.debug("%s: turn off", self.name) + self.set_value('base', [0]) + self._state = 0 if not self.should_poll: self.schedule_update_ha_state() + + @property + def is_on(self): + """Return True if the value is not 0 is on, else False.""" + return self._state != 0 + + @property + def supported_features(self): + """Flag supported features.""" + return self._supported_features + + def update(self): + """Update device state.""" + super().update() + if self.has_attribute('brightness_state'): + value = self.value('brightness_state') + if value is not None: + self._brightness = int.from_bytes(value, byteorder='little') + _LOGGER.debug("%s: brightness = %d", + self.name, self._brightness) + + if self.has_attribute('state'): + self._state = self.value("state")[0] + _LOGGER.debug("%s: state = %d", self.name, self._state) + + def should_poll(self): + """No polling needed for a KNX light.""" + return False From 9bc5cd2d4ba6281f85aa35413d4d282564b784c5 Mon Sep 17 00:00:00 2001 From: Charles Blonde Date: Fri, 7 Jul 2017 07:28:09 +0200 Subject: [PATCH 060/131] Add Soundtouch support for playing an HTTP url (#8370) --- .../components/media_player/soundtouch.py | 26 ++++++++++++------- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- .../media_player/test_soundtouch.py | 18 +++++++++++++ 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/media_player/soundtouch.py b/homeassistant/components/media_player/soundtouch.py index 236208eb332..c04d3b4d77f 100644 --- a/homeassistant/components/media_player/soundtouch.py +++ b/homeassistant/components/media_player/soundtouch.py @@ -7,6 +7,7 @@ https://home-assistant.io/components/media_player.soundtouch/ import logging from os import path +import re import voluptuous as vol import homeassistant.helpers.config_validation as cv @@ -20,7 +21,7 @@ from homeassistant.const import (CONF_HOST, CONF_NAME, STATE_OFF, CONF_PORT, STATE_PAUSED, STATE_PLAYING, STATE_UNAVAILABLE) -REQUIREMENTS = ['libsoundtouch==0.6.2'] +REQUIREMENTS = ['libsoundtouch==0.7.2'] _LOGGER = logging.getLogger(__name__) @@ -305,15 +306,22 @@ class SoundTouchDevice(MediaPlayerDevice): def play_media(self, media_type, media_id, **kwargs): """Play a piece of media.""" - _LOGGER.info("Starting media with media_id:" + str(media_id)) - presets = self._device.presets() - preset = next([preset for preset in presets if - preset.preset_id == str(media_id)].__iter__(), None) - if preset is not None: - _LOGGER.info("Playing preset: " + preset.name) - self._device.select_preset(preset) + _LOGGER.debug("Starting media with media_id: " + str(media_id)) + if re.match(r'http://', str(media_id)): + # URL + _LOGGER.debug("Playing URL %s", str(media_id)) + self._device.play_url(str(media_id)) else: - _LOGGER.warning("Unable to find preset with id " + str(media_id)) + # Preset + presets = self._device.presets() + preset = next([preset for preset in presets if + preset.preset_id == str(media_id)].__iter__(), None) + if preset is not None: + _LOGGER.debug("Playing preset: " + preset.name) + self._device.select_preset(preset) + else: + _LOGGER.warning( + "Unable to find preset with id " + str(media_id)) def create_zone(self, slaves): """ diff --git a/requirements_all.txt b/requirements_all.txt index e4598d72711..d00629c6a64 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -354,7 +354,7 @@ libpurecoollink==0.1.5 librouteros==1.0.2 # homeassistant.components.media_player.soundtouch -libsoundtouch==0.6.2 +libsoundtouch==0.7.2 # homeassistant.components.light.lifx_legacy liffylights==0.9.4 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index f7b74c3b9d8..07a3ad8a681 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -65,7 +65,7 @@ influxdb==3.0.0 libpurecoollink==0.1.5 # homeassistant.components.media_player.soundtouch -libsoundtouch==0.6.2 +libsoundtouch==0.7.2 # homeassistant.components.sensor.mfi # homeassistant.components.switch.mfi diff --git a/tests/components/media_player/test_soundtouch.py b/tests/components/media_player/test_soundtouch.py index 4958f5ee263..a8242b39f7f 100644 --- a/tests/components/media_player/test_soundtouch.py +++ b/tests/components/media_player/test_soundtouch.py @@ -584,6 +584,24 @@ class TestSoundtouchMediaPlayer(unittest.TestCase): self.assertEqual(mocked_presets.call_count, 2) self.assertEqual(mocked_select_preset.call_count, 1) + @mock.patch('libsoundtouch.device.SoundTouchDevice.play_url') + @mock.patch('libsoundtouch.device.SoundTouchDevice.volume') + @mock.patch('libsoundtouch.device.SoundTouchDevice.status') + @mock.patch('libsoundtouch.soundtouch_device', + side_effect=_mock_soundtouch_device) + def test_play_media_url(self, mocked_sountouch_device, mocked_status, + mocked_volume, mocked_play_url): + """Test play preset 1.""" + soundtouch.setup_platform(self.hass, + default_component(), + mock.MagicMock()) + all_devices = self.hass.data[soundtouch.DATA_SOUNDTOUCH] + self.assertEqual(mocked_sountouch_device.call_count, 1) + self.assertEqual(mocked_status.call_count, 1) + self.assertEqual(mocked_volume.call_count, 1) + all_devices[0].play_media('MUSIC', "http://fqdn/file.mp3") + mocked_play_url.assert_called_with("http://fqdn/file.mp3") + @mock.patch('libsoundtouch.device.SoundTouchDevice.create_zone') @mock.patch('libsoundtouch.device.SoundTouchDevice.volume') @mock.patch('libsoundtouch.device.SoundTouchDevice.status') From c48c2b00a8a1e0d4f144febdb1ae079bef9807fd Mon Sep 17 00:00:00 2001 From: Sabesto Date: Fri, 7 Jul 2017 07:30:23 +0200 Subject: [PATCH 061/131] Modbus fixes to work with pymodbus 1.3.1 (#8365) * Fixed a bug where changing fan speed was not possible * Bump pymodbus version to 1.3.1 to fix issue #8285 * Changed all modbus components so that they use CONF_SLAVE from const.py * Fix checking result from a modbus transaction * Add missing decorator * Added modbus write coil service and added descriptions * Removed a hiding debug print --- .../components/binary_sensor/modbus.py | 9 +++++- homeassistant/components/modbus.py | 30 +++++++++++++++++-- homeassistant/components/sensor/modbus.py | 9 ++++-- homeassistant/components/services.yaml | 25 ++++++++++++++++ homeassistant/components/switch/modbus.py | 6 ++-- 5 files changed, 69 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/binary_sensor/modbus.py b/homeassistant/components/binary_sensor/modbus.py index fb6f84c318d..00dc588a468 100644 --- a/homeassistant/components/binary_sensor/modbus.py +++ b/homeassistant/components/binary_sensor/modbus.py @@ -49,6 +49,7 @@ class ModbusCoilSensor(BinarySensorDevice): self._coil = int(coil) self._value = None + @property def name(self): """Return the name of the sensor.""" return self._name @@ -61,4 +62,10 @@ class ModbusCoilSensor(BinarySensorDevice): def update(self): """Update the state of the sensor.""" result = modbus.HUB.read_coils(self._slave, self._coil, 1) - self._value = result.bits[0] + try: + self._value = result.bits[0] + except AttributeError: + _LOGGER.error( + 'No response from modbus slave %s coil %s', + self._slave, + self._coil) diff --git a/homeassistant/components/modbus.py b/homeassistant/components/modbus.py index aa958715a48..9075eab2cdd 100644 --- a/homeassistant/components/modbus.py +++ b/homeassistant/components/modbus.py @@ -6,13 +6,15 @@ https://home-assistant.io/components/modbus/ """ import logging import threading +import os import voluptuous as vol import homeassistant.helpers.config_validation as cv +from homeassistant.config import load_yaml_config_file from homeassistant.const import ( EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, - CONF_HOST, CONF_METHOD, CONF_PORT) + CONF_HOST, CONF_METHOD, CONF_PORT, ATTR_STATE) DOMAIN = 'modbus' @@ -50,6 +52,7 @@ CONFIG_SCHEMA = vol.Schema({ _LOGGER = logging.getLogger(__name__) SERVICE_WRITE_REGISTER = 'write_register' +SERVICE_WRITE_COIL = 'write_coil' ATTR_ADDRESS = 'address' ATTR_UNIT = 'unit' @@ -61,6 +64,11 @@ SERVICE_WRITE_REGISTER_SCHEMA = vol.Schema({ vol.Required(ATTR_VALUE): vol.All(cv.ensure_list, [cv.positive_int]) }) +SERVICE_WRITE_COIL_SCHEMA = vol.Schema({ + vol.Required(ATTR_UNIT): cv.positive_int, + vol.Required(ATTR_ADDRESS): cv.positive_int, + vol.Required(ATTR_STATE): cv.boolean +}) HUB = None @@ -105,9 +113,18 @@ def setup(hass, config): HUB.connect() hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_modbus) + descriptions = load_yaml_config_file(os.path.join( + os.path.dirname(__file__), 'services.yaml')).get(DOMAIN) + # Register services for modbus - hass.services.register(DOMAIN, SERVICE_WRITE_REGISTER, write_register, - schema=SERVICE_WRITE_REGISTER_SCHEMA) + hass.services.register( + DOMAIN, SERVICE_WRITE_REGISTER, write_register, + descriptions.get(SERVICE_WRITE_REGISTER), + schema=SERVICE_WRITE_REGISTER_SCHEMA) + hass.services.register( + DOMAIN, SERVICE_WRITE_COIL, write_coil, + descriptions.get(SERVICE_WRITE_COIL), + schema=SERVICE_WRITE_COIL_SCHEMA) def write_register(service): """Write modbus registers.""" @@ -125,6 +142,13 @@ def setup(hass, config): address, int(float(value))) + def write_coil(service): + """Write modbus coil.""" + unit = service.data.get(ATTR_UNIT) + address = service.data.get(ATTR_ADDRESS) + state = service.data.get(ATTR_STATE) + HUB.write_coil(unit, address, state) + hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_modbus) return True diff --git a/homeassistant/components/sensor/modbus.py b/homeassistant/components/sensor/modbus.py index d8a5be9ab49..9453daea413 100644 --- a/homeassistant/components/sensor/modbus.py +++ b/homeassistant/components/sensor/modbus.py @@ -117,17 +117,20 @@ class ModbusRegisterSensor(Entity): self._register, self._count) val = 0 - if not result: + + try: + registers = result.registers + except AttributeError: _LOGGER.error("No response from modbus slave %s register %s", self._slave, self._register) return if self._data_type == DATA_TYPE_FLOAT: byte_string = b''.join( - [x.to_bytes(2, byteorder='big') for x in result.registers] + [x.to_bytes(2, byteorder='big') for x in registers] ) val = struct.unpack(">f", byte_string)[0] elif self._data_type == DATA_TYPE_INT: - for i, res in enumerate(result.registers): + for i, res in enumerate(registers): val += res * (2**(i*16)) self._value = format( self._scale * val + self._offset, '.{}f'.format(self._precision)) diff --git a/homeassistant/components/services.yaml b/homeassistant/components/services.yaml index db71b2322fa..97e947fff06 100644 --- a/homeassistant/components/services.yaml +++ b/homeassistant/components/services.yaml @@ -483,3 +483,28 @@ apple_tv: apple_tv_scan: description: Scan for Apple TV devices. +modbus: + write_register: + description: Write to a modbus holding register + fields: + unit: + description: Address of the modbus unit + example: 21 + address: + description: Address of the holding register to write to + example: 0 + value: + description: Value to write + example: 0 + write_coil: + description: Write to a modbus coil + fields: + unit: + description: Address of the modbus unit + example: 21 + address: + description: Address of the register to read + example: 0 + state: + description: State to write + example: false diff --git a/homeassistant/components/switch/modbus.py b/homeassistant/components/switch/modbus.py index 95168d5b830..e6342617f28 100644 --- a/homeassistant/components/switch/modbus.py +++ b/homeassistant/components/switch/modbus.py @@ -70,10 +70,10 @@ class ModbusCoilSwitch(ToggleEntity): def update(self): """Update the state of the switch.""" result = modbus.HUB.read_coils(self._slave, self._coil, 1) - if not result: + try: + self._is_on = bool(result.bits[0]) + except AttributeError: _LOGGER.error( 'No response from modbus slave %s coil %s', self._slave, self._coil) - return - self._is_on = bool(result.bits[0]) From a7d5a8d93e9013d4e53d288525cadfd70eb5a9f7 Mon Sep 17 00:00:00 2001 From: Matthew Schick Date: Fri, 7 Jul 2017 01:34:21 -0400 Subject: [PATCH 062/131] Cleanup the asuswrt component (#8359) * Get the list of wireless interfaces from nvram so tri-band routers work * ARP checks don't work reliably for ap mode so remove it, associated list seems pretty solid * Match on 'mac' instead of 'ip' since we can't use it for ap mode * The `client_info_tmp` nvram reference, Asus removed it some time ago * Update AsusWrtResult --- .../components/device_tracker/asuswrt.py | 115 ++++-------------- 1 file changed, 27 insertions(+), 88 deletions(-) diff --git a/homeassistant/components/device_tracker/asuswrt.py b/homeassistant/components/device_tracker/asuswrt.py index bdd28d1d168..b28d16cc4a1 100644 --- a/homeassistant/components/device_tracker/asuswrt.py +++ b/homeassistant/components/device_tracker/asuswrt.py @@ -60,20 +60,11 @@ _LEASES_REGEX = re.compile( r'(?P([^\s]+))') # Command to get both 5GHz and 2.4GHz clients -_WL_CMD = '{ wl -i eth2 assoclist & wl -i eth1 assoclist ; }' +_WL_CMD = 'for dev in `nvram get wl_ifnames`; do wl -i $dev assoclist; done' _WL_REGEX = re.compile( r'\w+\s' + r'(?P(([0-9A-F]{2}[:-]){5}([0-9A-F]{2})))') -_ARP_CMD = 'arp -n' -_ARP_REGEX = re.compile( - r'.+\s' + - r'\((?P([0-9]{1,3}[\.]){3}[0-9]{1,3})\)\s' + - r'.+\s' + - r'(?P(([0-9a-f]{2}[:-]){5}([0-9a-f]{2})))' + - r'\s' + - r'.*') - _IP_NEIGH_CMD = 'ip neigh' _IP_NEIGH_REGEX = re.compile( r'(?P([0-9]{1,3}[\.]){3}[0-9]{1,3}|' @@ -84,15 +75,6 @@ _IP_NEIGH_REGEX = re.compile( r'\s?(router)?' r'(?P(\w+))') -_NVRAM_CMD = 'nvram get client_info_tmp' -_NVRAM_REGEX = re.compile( - r'.*>.*>' + - r'(?P([0-9]{1,3}[\.]){3}[0-9]{1,3})' + - r'>' + - r'(?P(([0-9a-fA-F]{2}[:-]){5}([0-9a-fA-F]{2})))' + - r'>' + - r'.*') - # pylint: disable=unused-argument def get_scanner(hass, config): @@ -102,7 +84,7 @@ def get_scanner(hass, config): return scanner if scanner.success_init else None -AsusWrtResult = namedtuple('AsusWrtResult', 'neighbors leases arp nvram') +AsusWrtResult = namedtuple('AsusWrtResult', 'neighbors leases') class AsusWrtDeviceScanner(DeviceScanner): @@ -173,7 +155,7 @@ class AsusWrtDeviceScanner(DeviceScanner): return False with self.lock: - _LOGGER.info('Checking ARP') + _LOGGER.info('Checking Devices') data = self.get_asuswrt_data() if not data: return False @@ -182,7 +164,7 @@ class AsusWrtDeviceScanner(DeviceScanner): client['status'] == 'REACHABLE' or client['status'] == 'DELAY' or client['status'] == 'STALE' or - client['status'] == 'IN_NVRAM'] + client['status'] == 'IN_ASSOCLIST'] self.last_results = active_clients return True @@ -204,41 +186,12 @@ class AsusWrtDeviceScanner(DeviceScanner): host = '' - # match mac addresses to IP addresses in ARP table - for arp in result.arp: - if match.group('mac').lower() in \ - arp.decode('utf-8').lower(): - arp_match = _ARP_REGEX.search( - arp.decode('utf-8').lower()) - if not arp_match: - _LOGGER.warning("Could not parse arp row: %s", arp) - continue - - devices[arp_match.group('ip')] = { - 'host': host, - 'status': '', - 'ip': arp_match.group('ip'), - 'mac': match.group('mac').upper(), - } - - # match mac addresses to IP addresses in NVRAM table - for nvr in result.nvram: - if match.group('mac').upper() in nvr.decode('utf-8'): - nvram_match = _NVRAM_REGEX.search(nvr.decode('utf-8')) - if not nvram_match: - _LOGGER.warning("Could not parse nvr row: %s", nvr) - continue - - # skip current check if already in ARP table - if nvram_match.group('ip') in devices.keys(): - continue - - devices[nvram_match.group('ip')] = { - 'host': host, - 'status': 'IN_NVRAM', - 'ip': nvram_match.group('ip'), - 'mac': match.group('mac').upper(), - } + devices[match.group('mac').upper()] = { + 'host': host, + 'status': 'IN_ASSOCLIST', + 'ip': '', + 'mac': match.group('mac').upper(), + } else: for lease in result.leases: @@ -256,20 +209,23 @@ class AsusWrtDeviceScanner(DeviceScanner): if host == '*': host = '' - devices[match.group('ip')] = { + devices[match.group('mac')] = { 'host': host, 'status': '', 'ip': match.group('ip'), 'mac': match.group('mac').upper(), } - for neighbor in result.neighbors: - match = _IP_NEIGH_REGEX.search(neighbor.decode('utf-8')) - if not match: - _LOGGER.warning("Could not parse neighbor row: %s", neighbor) - continue - if match.group('ip') in devices: - devices[match.group('ip')]['status'] = match.group('status') + for neighbor in result.neighbors: + match = _IP_NEIGH_REGEX.search(neighbor.decode('utf-8')) + if not match: + _LOGGER.warning("Could not parse neighbor row: %s", + neighbor) + continue + if match.group('mac') in devices: + devices[match.group('mac')]['status'] = ( + match.group('status')) + return devices @@ -317,27 +273,19 @@ class SshConnection(_Connection): try: if not self.connected: self.connect() - self._ssh.sendline(_IP_NEIGH_CMD) - self._ssh.prompt() - neighbors = self._ssh.before.split(b'\n')[1:-1] if self._ap: - self._ssh.sendline(_ARP_CMD) - self._ssh.prompt() - arp_result = self._ssh.before.split(b'\n')[1:-1] + neighbors = [''] self._ssh.sendline(_WL_CMD) self._ssh.prompt() leases_result = self._ssh.before.split(b'\n')[1:-1] - self._ssh.sendline(_NVRAM_CMD) - self._ssh.prompt() - nvram_result = self._ssh.before.split(b'\n')[1].split(b'<')[1:] else: - arp_result = [''] - nvram_result = [''] + self._ssh.sendline(_IP_NEIGH_CMD) + self._ssh.prompt() + neighbors = self._ssh.before.split(b'\n')[1:-1] self._ssh.sendline(_LEASES_CMD) self._ssh.prompt() leases_result = self._ssh.before.split(b'\n')[1:-1] - return AsusWrtResult(neighbors, leases_result, arp_result, - nvram_result) + return AsusWrtResult(neighbors, leases_result) except exceptions.EOF as err: _LOGGER.error("Connection refused. SSH enabled?") self.disconnect() @@ -407,23 +355,14 @@ class TelnetConnection(_Connection): neighbors = (self._telnet.read_until(self._prompt_string). split(b'\n')[1:-1]) if self._ap: - self._telnet.write('{}\n'.format(_ARP_CMD).encode('ascii')) - arp_result = (self._telnet.read_until(self._prompt_string). - split(b'\n')[1:-1]) self._telnet.write('{}\n'.format(_WL_CMD).encode('ascii')) leases_result = (self._telnet.read_until(self._prompt_string). split(b'\n')[1:-1]) - self._telnet.write('{}\n'.format(_NVRAM_CMD).encode('ascii')) - nvram_result = (self._telnet.read_until(self._prompt_string). - split(b'\n')[1].split(b'<')[1:]) else: - arp_result = [''] - nvram_result = [''] self._telnet.write('{}\n'.format(_LEASES_CMD).encode('ascii')) leases_result = (self._telnet.read_until(self._prompt_string). split(b'\n')[1:-1]) - return AsusWrtResult(neighbors, leases_result, arp_result, - nvram_result) + return AsusWrtResult(neighbors, leases_result) except EOFError: _LOGGER.error("Unexpected response from router") self.disconnect() From b67c5df5257d58a172ea9f00d8229700f2d0532f Mon Sep 17 00:00:00 2001 From: PhracturedBlue Date: Thu, 6 Jul 2017 22:35:59 -0700 Subject: [PATCH 063/131] cover_template:i open/close/stop actions no longer required. Improve tests (#8344) --- homeassistant/components/cover/template.py | 55 ++++--- tests/components/cover/test_template.py | 169 +++++++++++---------- 2 files changed, 122 insertions(+), 102 deletions(-) diff --git a/homeassistant/components/cover/template.py b/homeassistant/components/cover/template.py index fd746131288..769c2fc4ed6 100644 --- a/homeassistant/components/cover/template.py +++ b/homeassistant/components/cover/template.py @@ -40,14 +40,15 @@ STOP_ACTION = 'stop_cover' POSITION_ACTION = 'set_cover_position' TILT_ACTION = 'set_cover_tilt_position' CONF_VALUE_OR_POSITION_TEMPLATE = 'value_or_position' +CONF_OPEN_OR_CLOSE = 'open_or_close' TILT_FEATURES = (SUPPORT_OPEN_TILT | SUPPORT_CLOSE_TILT | SUPPORT_STOP_TILT | SUPPORT_SET_TILT_POSITION) COVER_SCHEMA = vol.Schema({ - vol.Required(OPEN_ACTION): cv.SCRIPT_SCHEMA, - vol.Required(CLOSE_ACTION): cv.SCRIPT_SCHEMA, - vol.Required(STOP_ACTION): cv.SCRIPT_SCHEMA, + vol.Inclusive(OPEN_ACTION, CONF_OPEN_OR_CLOSE): cv.SCRIPT_SCHEMA, + vol.Inclusive(CLOSE_ACTION, CONF_OPEN_OR_CLOSE): cv.SCRIPT_SCHEMA, + vol.Optional(STOP_ACTION): cv.SCRIPT_SCHEMA, vol.Exclusive(CONF_POSITION_TEMPLATE, CONF_VALUE_OR_POSITION_TEMPLATE): cv.template, vol.Exclusive(CONF_VALUE_TEMPLATE, @@ -77,9 +78,9 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): position_template = device_config.get(CONF_POSITION_TEMPLATE) tilt_template = device_config.get(CONF_TILT_TEMPLATE) icon_template = device_config.get(CONF_ICON_TEMPLATE) - open_action = device_config[OPEN_ACTION] - close_action = device_config[CLOSE_ACTION] - stop_action = device_config[STOP_ACTION] + open_action = device_config.get(OPEN_ACTION) + close_action = device_config.get(CLOSE_ACTION) + stop_action = device_config.get(STOP_ACTION) position_action = device_config.get(POSITION_ACTION) tilt_action = device_config.get(TILT_ACTION) @@ -88,6 +89,10 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): CONF_VALUE_TEMPLATE, CONF_VALUE_TEMPLATE) continue + if position_action is None and open_action is None: + _LOGGER.error('Must specify at least one of %s' or '%s', + OPEN_ACTION, POSITION_ACTION) + continue template_entity_ids = set() if state_template is not None: temp_ids = state_template.extract_entities() @@ -147,9 +152,15 @@ class CoverTemplate(CoverDevice): self._position_template = position_template self._tilt_template = tilt_template self._icon_template = icon_template - self._open_script = Script(hass, open_action) - self._close_script = Script(hass, close_action) - self._stop_script = Script(hass, stop_action) + self._open_script = None + if open_action is not None: + self._open_script = Script(hass, open_action) + self._close_script = None + if close_action is not None: + self._close_script = Script(hass, close_action) + self._stop_script = None + if stop_action is not None: + self._stop_script = Script(hass, stop_action) self._position_script = None if position_action is not None: self._position_script = Script(hass, position_action) @@ -227,9 +238,12 @@ class CoverTemplate(CoverDevice): @property def supported_features(self): """Flag supported features.""" - supported_features = SUPPORT_OPEN | SUPPORT_CLOSE | SUPPORT_STOP + supported_features = SUPPORT_OPEN | SUPPORT_CLOSE - if self.current_cover_position is not None: + if self._stop_script is not None: + supported_features |= SUPPORT_STOP + + if self._position_script is not None: supported_features |= SUPPORT_SET_POSITION if self.current_cover_tilt_position is not None: @@ -245,23 +259,30 @@ class CoverTemplate(CoverDevice): @asyncio.coroutine def async_open_cover(self, **kwargs): """Move the cover up.""" - self.hass.async_add_job(self._open_script.async_run()) + if self._open_script: + self.hass.async_add_job(self._open_script.async_run()) + elif self._position_script: + self.hass.async_add_job(self._position_script.async_run( + {"position": 100})) @asyncio.coroutine def async_close_cover(self, **kwargs): """Move the cover down.""" - self.hass.async_add_job(self._close_script.async_run()) + if self._close_script: + self.hass.async_add_job(self._close_script.async_run()) + elif self._position_script: + self.hass.async_add_job(self._position_script.async_run( + {"position": 0})) @asyncio.coroutine def async_stop_cover(self, **kwargs): """Fire the stop action.""" - self.hass.async_add_job(self._stop_script.async_run()) + if self._stop_script: + self.hass.async_add_job(self._stop_script.async_run()) @asyncio.coroutine def async_set_cover_position(self, **kwargs): """Set cover position.""" - if ATTR_POSITION not in kwargs: - return self._position = kwargs[ATTR_POSITION] self.hass.async_add_job(self._position_script.async_run( {"position": self._position})) @@ -283,8 +304,6 @@ class CoverTemplate(CoverDevice): @asyncio.coroutine def async_set_cover_tilt_position(self, **kwargs): """Move the cover tilt to a specific position.""" - if ATTR_TILT_POSITION not in kwargs: - return self._tilt_value = kwargs[ATTR_TILT_POSITION] self.hass.async_add_job(self._tilt_script.async_run( {"tilt": self._tilt_value})) diff --git a/tests/components/cover/test_template.py b/tests/components/cover/test_template.py index 35ec21bfbdf..cd2120e71e6 100644 --- a/tests/components/cover/test_template.py +++ b/tests/components/cover/test_template.py @@ -54,10 +54,6 @@ class TestTemplateCover(unittest.TestCase): 'service': 'cover.close_cover', 'entity_id': 'cover.test_state' }, - 'stop_cover': { - 'service': 'cover.close_cover', - 'entity_id': 'cover.test_state' - }, } } } @@ -79,7 +75,7 @@ class TestTemplateCover(unittest.TestCase): assert state.state == STATE_CLOSED def test_template_state_boolean(self): - """Test the state text of a template.""" + """Test the value_template attribute.""" with assert_setup_component(1, 'cover'): assert setup.setup_component(self.hass, 'cover', { 'cover': { @@ -96,10 +92,6 @@ class TestTemplateCover(unittest.TestCase): 'service': 'cover.close_cover', 'entity_id': 'cover.test_state' }, - 'stop_cover': { - 'service': 'cover.close_cover', - 'entity_id': 'cover.test_state' - }, } } } @@ -112,7 +104,7 @@ class TestTemplateCover(unittest.TestCase): assert state.state == STATE_OPEN def test_template_position(self): - """Test the state text of a template.""" + """Test the position_template attribute.""" with assert_setup_component(1, 'cover'): assert setup.setup_component(self.hass, 'cover', { 'cover': { @@ -129,10 +121,6 @@ class TestTemplateCover(unittest.TestCase): 'service': 'cover.close_cover', 'entity_id': 'cover.test' }, - 'stop_cover': { - 'service': 'cover.close_cover', - 'entity_id': 'cover.test' - }, } } } @@ -170,7 +158,7 @@ class TestTemplateCover(unittest.TestCase): assert state.state == STATE_CLOSED def test_template_tilt(self): - """Test the state text of a template.""" + """Test the tilt_template attribute.""" with assert_setup_component(1, 'cover'): assert setup.setup_component(self.hass, 'cover', { 'cover': { @@ -189,10 +177,6 @@ class TestTemplateCover(unittest.TestCase): 'service': 'cover.close_cover', 'entity_id': 'cover.test_state' }, - 'stop_cover': { - 'service': 'cover.close_cover', - 'entity_id': 'cover.test_state' - }, } } } @@ -205,7 +189,7 @@ class TestTemplateCover(unittest.TestCase): assert state.attributes.get('current_tilt_position') == 42.0 def test_template_out_of_bounds(self): - """Test the state text of a template.""" + """Test template out-of-bounds condition.""" with assert_setup_component(1, 'cover'): assert setup.setup_component(self.hass, 'cover', { 'cover': { @@ -224,10 +208,6 @@ class TestTemplateCover(unittest.TestCase): 'service': 'cover.close_cover', 'entity_id': 'cover.test_state' }, - 'stop_cover': { - 'service': 'cover.close_cover', - 'entity_id': 'cover.test_state' - }, } } } @@ -260,10 +240,6 @@ class TestTemplateCover(unittest.TestCase): 'service': 'cover.close_cover', 'entity_id': 'cover.test_state' }, - 'stop_cover': { - 'service': 'cover.close_cover', - 'entity_id': 'cover.test_state' - }, 'icon_template': "{% if states.cover.test_state.state %}" "mdi:check" @@ -294,14 +270,26 @@ class TestTemplateCover(unittest.TestCase): 'service': 'cover.close_cover', 'entity_id': 'cover.test_state' }, - 'stop_cover': { - 'service': 'cover.close_cover', - 'entity_id': 'cover.test_state' - }, - 'icon_template': - "{% if states.cover.test_state.state %}" - "mdi:check" - "{% endif %}" + }, + } + } + }) + + self.hass.start() + self.hass.block_till_done() + + assert self.hass.states.all() == [] + + def test_template_open_or_position(self): + """Test that at least one of open_cover or set_position is used.""" + with assert_setup_component(1, 'cover'): + assert setup.setup_component(self.hass, 'cover', { + 'cover': { + 'platform': 'template', + 'covers': { + 'test_template_cover': { + 'value_template': + "{{ 1 == 1 }}", } } } @@ -312,8 +300,32 @@ class TestTemplateCover(unittest.TestCase): assert self.hass.states.all() == [] + def test_template_open_and_close(self): + """Test that if open_cover is specified, cose_cover is too.""" + with assert_setup_component(0, 'cover'): + assert setup.setup_component(self.hass, 'cover', { + 'cover': { + 'platform': 'template', + 'covers': { + 'test_template_cover': { + 'value_template': + "{{ 1 == 1 }}", + 'open_cover': { + 'service': 'cover.open_cover', + 'entity_id': 'cover.test_state' + }, + }, + } + } + }) + + self.hass.start() + self.hass.block_till_done() + + assert self.hass.states.all() == [] + def test_template_non_numeric(self): - """Test the state text of a template.""" + """Test that tilt_template values are numeric.""" with assert_setup_component(1, 'cover'): assert setup.setup_component(self.hass, 'cover', { 'cover': { @@ -336,10 +348,6 @@ class TestTemplateCover(unittest.TestCase): 'service': 'cover.close_cover', 'entity_id': 'cover.test_state' }, - 'stop_cover': { - 'service': 'cover.close_cover', - 'entity_id': 'cover.test_state' - }, } } } @@ -353,7 +361,7 @@ class TestTemplateCover(unittest.TestCase): assert state.attributes.get('current_position') is None def test_open_action(self): - """Test the state text of a template.""" + """Test the open_cover command.""" with assert_setup_component(1, 'cover'): assert setup.setup_component(self.hass, 'cover', { 'cover': { @@ -369,10 +377,6 @@ class TestTemplateCover(unittest.TestCase): 'service': 'cover.close_cover', 'entity_id': 'cover.test_state' }, - 'stop_cover': { - 'service': 'cover.close_cover', - 'entity_id': 'cover.test_state' - }, } } } @@ -390,7 +394,7 @@ class TestTemplateCover(unittest.TestCase): assert len(self.calls) == 1 def test_close_stop_action(self): - """Test the state text of a template.""" + """Test the close-cover and stop_cover commands.""" with assert_setup_component(1, 'cover'): assert setup.setup_component(self.hass, 'cover', { 'cover': { @@ -429,29 +433,30 @@ class TestTemplateCover(unittest.TestCase): assert len(self.calls) == 2 def test_set_position(self): - """Test the state text of a template.""" + """Test the set_position command.""" with assert_setup_component(1, 'cover'): + assert setup.setup_component(self.hass, 'input_slider', { + 'input_slider': { + 'test': { + 'min': '0', + 'max': '100', + 'initial': '42', + } + } + }) assert setup.setup_component(self.hass, 'cover', { 'cover': { 'platform': 'template', 'covers': { 'test_template_cover': { 'position_template': - "{{ 100 }}", - 'open_cover': { - 'service': 'cover.open_cover', - 'entity_id': 'cover.test_state' - }, - 'close_cover': { - 'service': 'cover.close_cover', - 'entity_id': 'cover.test_state' - }, - 'stop_cover': { - 'service': 'cover.stop_cover', - 'entity_id': 'cover.test_state' - }, + "{{ states.input_slider.test.state | int }}", 'set_cover_position': { - 'service': 'test.automation', + 'service': 'input_slider.select_value', + 'entity_id': 'input_slider.test', + 'data_template': { + 'value': '{{ position }}' + }, }, } } @@ -461,17 +466,29 @@ class TestTemplateCover(unittest.TestCase): self.hass.start() self.hass.block_till_done() + state = self.hass.states.set('input_slider.test', 42) + self.hass.block_till_done() state = self.hass.states.get('cover.test_template_cover') assert state.state == STATE_OPEN - cover.set_cover_position(self.hass, 42, + cover.open_cover(self.hass, 'cover.test_template_cover') + self.hass.block_till_done() + state = self.hass.states.get('cover.test_template_cover') + assert state.attributes.get('current_position') == 100.0 + + cover.close_cover(self.hass, 'cover.test_template_cover') + self.hass.block_till_done() + state = self.hass.states.get('cover.test_template_cover') + assert state.attributes.get('current_position') == 0.0 + + cover.set_cover_position(self.hass, 25, 'cover.test_template_cover') self.hass.block_till_done() - - assert len(self.calls) == 1 + state = self.hass.states.get('cover.test_template_cover') + assert state.attributes.get('current_position') == 25.0 def test_set_tilt_position(self): - """Test the state text of a template.""" + """Test the set_tilt_position command.""" with assert_setup_component(1, 'cover'): assert setup.setup_component(self.hass, 'cover', { 'cover': { @@ -488,10 +505,6 @@ class TestTemplateCover(unittest.TestCase): 'service': 'cover.close_cover', 'entity_id': 'cover.test_state' }, - 'stop_cover': { - 'service': 'cover.stop_cover', - 'entity_id': 'cover.test_state' - }, 'set_cover_tilt_position': { 'service': 'test.automation', }, @@ -510,7 +523,7 @@ class TestTemplateCover(unittest.TestCase): assert len(self.calls) == 1 def test_open_tilt_action(self): - """Test the state text of a template.""" + """Test the open_cover_tilt command.""" with assert_setup_component(1, 'cover'): assert setup.setup_component(self.hass, 'cover', { 'cover': { @@ -527,10 +540,6 @@ class TestTemplateCover(unittest.TestCase): 'service': 'cover.close_cover', 'entity_id': 'cover.test_state' }, - 'stop_cover': { - 'service': 'cover.stop_cover', - 'entity_id': 'cover.test_state' - }, 'set_cover_tilt_position': { 'service': 'test.automation', }, @@ -548,7 +557,7 @@ class TestTemplateCover(unittest.TestCase): assert len(self.calls) == 1 def test_close_tilt_action(self): - """Test the state text of a template.""" + """Test the close_cover_tilt command.""" with assert_setup_component(1, 'cover'): assert setup.setup_component(self.hass, 'cover', { 'cover': { @@ -565,10 +574,6 @@ class TestTemplateCover(unittest.TestCase): 'service': 'cover.close_cover', 'entity_id': 'cover.test_state' }, - 'stop_cover': { - 'service': 'cover.stop_cover', - 'entity_id': 'cover.test_state' - }, 'set_cover_tilt_position': { 'service': 'test.automation', }, @@ -603,10 +608,6 @@ class TestTemplateCover(unittest.TestCase): 'service': 'cover.close_cover', 'entity_id': 'cover.test_state' }, - 'stop_cover': { - 'service': 'cover.close_cover', - 'entity_id': 'cover.test_state' - }, 'icon_template': "{% if states.cover.test_state.state %}" "mdi:check" From 652c006cbce4302be0196a726ad988c29dbb9675 Mon Sep 17 00:00:00 2001 From: William Scanlon Date: Fri, 7 Jul 2017 01:39:11 -0400 Subject: [PATCH 064/131] Prevent errors on Octoprint sensors and binary_sensors when Octoprint and/or Printer are off (#8343) * Added platformnotready * Only log the first failure if octoprint/printer isn't up Remove blank line --- .../components/binary_sensor/octoprint.py | 10 ++-- homeassistant/components/octoprint.py | 53 +++++++++++++++---- homeassistant/components/sensor/octoprint.py | 15 ++---- 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/homeassistant/components/binary_sensor/octoprint.py b/homeassistant/components/binary_sensor/octoprint.py index 6e278ccfccf..f4e4e04717d 100644 --- a/homeassistant/components/binary_sensor/octoprint.py +++ b/homeassistant/components/binary_sensor/octoprint.py @@ -12,13 +12,12 @@ import voluptuous as vol from homeassistant.const import CONF_NAME, CONF_MONITORED_CONDITIONS from homeassistant.components.binary_sensor import ( BinarySensorDevice, PLATFORM_SCHEMA) -from homeassistant.loader import get_component import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) DEPENDENCIES = ['octoprint'] - +DOMAIN = "octoprint" DEFAULT_NAME = 'OctoPrint' SENSOR_TYPES = { @@ -37,7 +36,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ # pylint: disable=unused-argument def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the available OctoPrint binary sensors.""" - octoprint = get_component('octoprint') + octoprint_api = hass.data[DOMAIN]["api"] name = config.get(CONF_NAME) monitored_conditions = config.get( CONF_MONITORED_CONDITIONS, SENSOR_TYPES.keys()) @@ -45,7 +44,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): devices = [] for octo_type in monitored_conditions: new_sensor = OctoPrintBinarySensor( - octoprint.OCTOPRINT, octo_type, SENSOR_TYPES[octo_type][2], + octoprint_api, octo_type, SENSOR_TYPES[octo_type][2], name, SENSOR_TYPES[octo_type][3], SENSOR_TYPES[octo_type][0], SENSOR_TYPES[octo_type][1], 'flags') devices.append(new_sensor) @@ -98,6 +97,3 @@ class OctoPrintBinarySensor(BinarySensorDevice): except requests.exceptions.ConnectionError: # Error calling the api, already logged in api.update() return - - if self._state is None: - _LOGGER.warning("Unable to locate value for %s", self.sensor_type) diff --git a/homeassistant/components/octoprint.py b/homeassistant/components/octoprint.py index 0a099fc7349..204490ce36c 100644 --- a/homeassistant/components/octoprint.py +++ b/homeassistant/components/octoprint.py @@ -17,8 +17,6 @@ _LOGGER = logging.getLogger(__name__) DOMAIN = 'octoprint' -OCTOPRINT = None - CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ vol.Required(CONF_API_KEY): cv.string, @@ -32,14 +30,15 @@ def setup(hass, config): base_url = 'http://{}/api/'.format(config[DOMAIN][CONF_HOST]) api_key = config[DOMAIN][CONF_API_KEY] - global OCTOPRINT + hass.data[DOMAIN] = {"api": None} + try: - OCTOPRINT = OctoPrintAPI(base_url, api_key) - OCTOPRINT.get('printer') - OCTOPRINT.get('job') + octoprint_api = OctoPrintAPI(base_url, api_key) + hass.data[DOMAIN]["api"] = octoprint_api + octoprint_api.get('printer') + octoprint_api.get('job') except requests.exceptions.RequestException as conn_err: _LOGGER.error("Error setting up OctoPrint API: %r", conn_err) - return False return True @@ -54,6 +53,11 @@ class OctoPrintAPI(object): 'X-Api-Key': key} self.printer_last_reading = [{}, None] self.job_last_reading = [{}, None] + self.job_available = False + self.printer_available = False + self.available = False + self.printer_error_logged = False + self.job_error_logged = False def get_tools(self): """Get the dynamic list of tools that temperature is monitored on.""" @@ -62,6 +66,7 @@ class OctoPrintAPI(object): def get(self, endpoint): """Send a get request, and return the response as a dict.""" + # Only query the API at most every 30 seconds now = time.time() if endpoint == "job": last_time = self.job_last_reading[1] @@ -73,28 +78,52 @@ class OctoPrintAPI(object): if last_time is not None: if now - last_time < 30.0: return self.printer_last_reading[0] + url = self.api_url + endpoint try: response = requests.get( - url, headers=self.headers, timeout=30) + url, headers=self.headers, timeout=9) response.raise_for_status() if endpoint == "job": self.job_last_reading[0] = response.json() self.job_last_reading[1] = time.time() + self.job_available = True elif endpoint == "printer": self.printer_last_reading[0] = response.json() self.printer_last_reading[1] = time.time() + self.printer_available = True + self.available = self.printer_available and self.job_available + if self.available: + self.job_error_logged = False + self.printer_error_logged = False return response.json() except (requests.exceptions.ConnectionError, - requests.exceptions.HTTPError) as conn_exc: - _LOGGER.error("Failed to update OctoPrint status. Error: %s", - conn_exc) + requests.exceptions.HTTPError, + requests.exceptions.ReadTimeout) as conn_exc: + log_string = "Failed to update OctoPrint status. " + \ + " Error: %s" % (conn_exc) + # Only log the first failure + if endpoint == "job": + log_string = "Endpoint: job " + log_string + if not self.job_error_logged: + _LOGGER.error(log_string) + self.job_error_logged = True + self.job_available = False + elif endpoint == "printer": + log_string = "Endpoint: printer " + log_string + if not self.printer_error_logged: + _LOGGER.error(log_string) + self.printer_error_logged = True + self.printer_available = False + self.available = False + return None def update(self, sensor_type, end_point, group, tool=None): """Return the value for sensor_type from the provided endpoint.""" response = self.get(end_point) if response is not None: return get_value_from_json(response, sensor_type, group, tool) + return response # pylint: disable=unused-variable @@ -111,3 +140,5 @@ def get_value_from_json(json_dict, sensor_type, group, tool): elif tool is not None: if sensor_type in json_dict[group][tool]: return json_dict[group][tool][sensor_type] + + return None diff --git a/homeassistant/components/sensor/octoprint.py b/homeassistant/components/sensor/octoprint.py index b029451bd5e..150a97288cc 100644 --- a/homeassistant/components/sensor/octoprint.py +++ b/homeassistant/components/sensor/octoprint.py @@ -13,13 +13,12 @@ from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( TEMP_CELSIUS, CONF_NAME, CONF_MONITORED_CONDITIONS) from homeassistant.helpers.entity import Entity -from homeassistant.loader import get_component import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) DEPENDENCIES = ['octoprint'] - +DOMAIN = "octoprint" DEFAULT_NAME = 'OctoPrint' SENSOR_TYPES = { @@ -38,7 +37,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ # pylint: disable=unused-argument def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the available OctoPrint sensors.""" - octoprint = get_component('octoprint') + octoprint_api = hass.data[DOMAIN]["api"] name = config.get(CONF_NAME) monitored_conditions = config.get(CONF_MONITORED_CONDITIONS) @@ -46,16 +45,16 @@ def setup_platform(hass, config, add_devices, discovery_info=None): types = ["actual", "target"] for octo_type in monitored_conditions: if octo_type == "Temperatures": - for tool in octoprint.OCTOPRINT.get_tools(): + for tool in octoprint_api.get_tools(): for temp_type in types: new_sensor = OctoPrintSensor( - octoprint.OCTOPRINT, temp_type, temp_type, name, + octoprint_api, temp_type, temp_type, name, SENSOR_TYPES[octo_type][3], SENSOR_TYPES[octo_type][0], SENSOR_TYPES[octo_type][1], tool) devices.append(new_sensor) else: new_sensor = OctoPrintSensor( - octoprint.OCTOPRINT, octo_type, SENSOR_TYPES[octo_type][2], + octoprint_api, octo_type, SENSOR_TYPES[octo_type][2], name, SENSOR_TYPES[octo_type][3], SENSOR_TYPES[octo_type][0], SENSOR_TYPES[octo_type][1]) devices.append(new_sensor) @@ -116,7 +115,3 @@ class OctoPrintSensor(Entity): except requests.exceptions.ConnectionError: # Error calling the api, already logged in api.update() return - - if self._state is None and self.sensor_type != "completion": - _LOGGER.warning("Unable to locate value for %s", self.sensor_type) - return From ed5d10448ee39937cbd32bff4696223e68b49cd6 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 7 Jul 2017 07:52:40 +0200 Subject: [PATCH 065/131] Presence detection for tp link eap225 (#8322) * Added support for TP-Link EAP 225 * code style changes * more code style changes * more understandable variable name * Added support for TP-Link EAP 225 * code style changes * more code style changes * more understandable variable name * Fix pylint issue (#8325) * Added support for TP-Link EAP 225 * code style changes * more code style changes * more understandable variable name * Added support for TP-Link EAP 225 * code style changes * Update snips.py --- .../components/device_tracker/tplink.py | 87 ++++++++++++++++++- homeassistant/components/snips.py | 5 +- 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/device_tracker/tplink.py b/homeassistant/components/device_tracker/tplink.py index 76744d56fcc..88b0abe8ce4 100755 --- a/homeassistant/components/device_tracker/tplink.py +++ b/homeassistant/components/device_tracker/tplink.py @@ -9,7 +9,7 @@ import hashlib import logging import re import threading -from datetime import timedelta +from datetime import timedelta, datetime import requests import voluptuous as vol @@ -33,8 +33,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ def get_scanner(hass, config): """Validate the configuration and return a TP-Link scanner.""" - for cls in [Tplink4DeviceScanner, Tplink3DeviceScanner, - Tplink2DeviceScanner, TplinkDeviceScanner]: + for cls in [Tplink5DeviceScanner, Tplink4DeviceScanner, + Tplink3DeviceScanner, Tplink2DeviceScanner, + TplinkDeviceScanner]: scanner = cls(config[DOMAIN]) if scanner.success_init: return scanner @@ -349,3 +350,83 @@ class Tplink4DeviceScanner(TplinkDeviceScanner): self.last_results = [mac.replace("-", ":") for mac in mac_results] return True + + +class Tplink5DeviceScanner(TplinkDeviceScanner): + """This class queries a TP-Link EAP-225 AP with newer TP-Link FW.""" + + def scan_devices(self): + """Scan for new devices and return a list with found MAC IDs.""" + self._update_info() + return self.last_results.keys() + + # pylint: disable=no-self-use + def get_device_name(self, device): + """Get firmware doesn't save the name of the wireless device.""" + return None + + @Throttle(MIN_TIME_BETWEEN_SCANS) + def _update_info(self): + """Ensure the information from the TP-Link AP is up to date. + + Return boolean if scanning successful. + """ + with self.lock: + _LOGGER.info("Loading wireless clients...") + + base_url = 'http://{}'.format(self.host) + + header = { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12;" + " rv:53.0) Gecko/20100101 Firefox/53.0", + "Accept": "application/json, text/javascript, */*; q=0.01", + "Accept-Language": "Accept-Language: en-US,en;q=0.5", + "Accept-Encoding": "gzip, deflate", + "Content-Type": "application/x-www-form-urlencoded; " + "charset=UTF-8", + "X-Requested-With": "XMLHttpRequest", + "Referer": "http://" + self.host + "/", + "Connection": "keep-alive", + "Pragma": "no-cache", + "Cache-Control": "no-cache" + } + + password_md5 = hashlib.md5(self.password).hexdigest().upper() + + # create a session to handle cookie easier + session = requests.session() + session.get(base_url, headers=header) + + login_data = {"username": self.username, "password": password_md5} + session.post(base_url, login_data, headers=header) + + # a timestamp is required to be sent as get parameter + timestamp = int(datetime.now().timestamp() * 1e3) + + client_list_url = '{}/data/monitor.client.client.json'.format( + base_url) + + get_params = { + 'operation': 'load', + '_': timestamp + } + + response = session.get(client_list_url, + headers=header, + params=get_params) + session.close() + try: + list_of_devices = response.json() + except ValueError: + _LOGGER.error("AP didn't respond with JSON. " + "Check if credentials are correct.") + return False + + if list_of_devices: + self.last_results = { + device['MAC'].replace('-', ':'): device['DeviceName'] + for device in list_of_devices['data'] + } + return True + + return False diff --git a/homeassistant/components/snips.py b/homeassistant/components/snips.py index d820396bf53..de54c0239c7 100644 --- a/homeassistant/components/snips.py +++ b/homeassistant/components/snips.py @@ -86,13 +86,13 @@ class IntentHandler(object): try: response = json.loads(payload) except TypeError: - LOGGER.error("Received invalid JSON: %s", payload) + LOGGER.error('Received invalid JSON: %s', payload) return try: response = INTENT_SCHEMA(response) except vol.Invalid as err: - LOGGER.error("Intent has invalid schema: %s. %s", err, response) + LOGGER.error('Intent has invalid schema: %s. %s', err, response) return intent = response['intent']['intentName'].split('__')[-1] @@ -108,7 +108,6 @@ class IntentHandler(object): slots = self.parse_slots(response) yield from action.async_run(slots) - # pylint: disable=no-self-use def parse_slots(self, response): """Parse the intent slots.""" parameters = {} From b1bba3675d65141a948e5ed21b234b6d6f1aba22 Mon Sep 17 00:00:00 2001 From: Russell Cloran Date: Thu, 6 Jul 2017 22:59:17 -0700 Subject: [PATCH 066/131] zha light: Refresh at startup (#8310) * zha light: Refresh at startup * Add asyncio.coroutine annotation --- homeassistant/components/light/zha.py | 54 ++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/light/zha.py b/homeassistant/components/light/zha.py index 0c230877625..650d9f909b1 100644 --- a/homeassistant/components/light/zha.py +++ b/homeassistant/components/light/zha.py @@ -29,7 +29,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): except (AttributeError, KeyError): pass - async_add_devices([Light(**discovery_info)]) + async_add_devices([Light(**discovery_info)], update_before_add=True) class Light(zha.Entity, light.Light): @@ -99,16 +99,19 @@ class Light(zha.Entity, light.Light): duration ) self._state = 1 + self.hass.async_add_job(self.async_update_ha_state()) return yield from self._endpoint.on_off.on() self._state = 1 + self.hass.async_add_job(self.async_update_ha_state()) @asyncio.coroutine def async_turn_off(self, **kwargs): """Turn the entity off.""" yield from self._endpoint.on_off.off() self._state = 0 + self.hass.async_add_job(self.async_update_ha_state()) @property def brightness(self): @@ -129,3 +132,52 @@ class Light(zha.Entity, light.Light): def supported_features(self): """Flag supported features.""" return self._supported_features + + @asyncio.coroutine + def async_update(self): + """Retrieve latest state.""" + _LOGGER.debug("%s async_update", self.entity_id) + + @asyncio.coroutine + def safe_read(cluster, attributes): + """Swallow all exceptions from network read. + + If we throw during initialization, setup fails. Rather have an + entity that exists, but is in a maybe wrong state, than no entity. + """ + try: + result, _ = yield from cluster.read_attributes( + attributes, + allow_cache=False, + ) + return result + except Exception: # pylint: disable=broad-except + return {} + + result = yield from safe_read(self._endpoint.on_off, ['on_off']) + self._state = result.get('on_off', self._state) + + if self._supported_features & light.SUPPORT_BRIGHTNESS: + result = yield from safe_read(self._endpoint.level, + ['current_level']) + self._brightness = result.get('current_level', self._brightness) + + if self._supported_features & light.SUPPORT_COLOR_TEMP: + result = yield from safe_read(self._endpoint.light_color, + ['color_temperature']) + self._color_temp = result.get('color_temperature', + self._color_temp) + + if self._supported_features & light.SUPPORT_XY_COLOR: + result = yield from safe_read(self._endpoint.light_color, + ['current_x', 'current_y']) + if 'current_x' in result and 'current_y' in result: + self._xy_color = (result['current_x'], result['current_y']) + + @property + def should_poll(self) -> bool: + """Return True if entity has to be polled for state. + + False if entity pushes its state to HA. + """ + return False From 46ce26eb7a879c85357c41fb784acc27f1527b29 Mon Sep 17 00:00:00 2001 From: Russell Cloran Date: Thu, 6 Jul 2017 23:02:22 -0700 Subject: [PATCH 067/131] zha: Try multiple reads to get manufacturer/model (#8308) Some devices don't seem to return the information properly when asked for multiple attributes in one read. This separates out the reads if it didn't work as expected the first time. Because this data is cached in bellows, I don't expect any extra reads in the "happy" case. --- homeassistant/components/zha/__init__.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/zha/__init__.py b/homeassistant/components/zha/__init__.py index 183ced37825..5937f1865f5 100644 --- a/homeassistant/components/zha/__init__.py +++ b/homeassistant/components/zha/__init__.py @@ -264,11 +264,20 @@ def _discover_endpoint_info(endpoint): if 0 not in endpoint.clusters: return extra_info - result, _ = yield from endpoint.clusters[0].read_attributes( - ['manufacturer', 'model'], - allow_cache=True, - ) - extra_info.update(result) + @asyncio.coroutine + def read(attributes): + """Read attributes and update extra_info convenience function.""" + result, _ = yield from endpoint.clusters[0].read_attributes( + attributes, + allow_cache=True, + ) + extra_info.update(result) + + yield from read(['manufacturer', 'model']) + if extra_info['manufacturer'] is None or extra_info['model'] is None: + # Some devices fail at returning multiple results. Attempt separately. + yield from read(['manufacturer']) + yield from read(['model']) for key, value in extra_info.items(): if isinstance(value, bytes): From 903e6b5aee0052d4c676a4eb1dfaac0cad99b114 Mon Sep 17 00:00:00 2001 From: Diogo Gomes Date: Fri, 7 Jul 2017 07:05:09 +0100 Subject: [PATCH 068/131] Upnp mapping notification (#8303) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * make port mapping optional * dependencies + improvements * Added bytes and packets sensors from IGD * flake8 check * new sensor with upnp counters * checks * whitespaces in blank line * requirements update * added sensor.upnp to .coveragerc * downgrade miniupnpc Latest version of miniupnpc is 2.0, but pypi only has 1.9 Fortunately it is enough * revert to non async miniupnpc will do network calls, so this component can’t be moved to coroutine * hof hof forgot to remove import ot asyncio * UPnP mapping overlap Addressing: https://community.home-assistant.io/t/upnp-new-module/20839 * removed whitespaces --- homeassistant/components/upnp.py | 39 ++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/upnp.py b/homeassistant/components/upnp.py index a058fdae85e..355a6d0a648 100644 --- a/homeassistant/components/upnp.py +++ b/homeassistant/components/upnp.py @@ -9,6 +9,8 @@ from urllib.parse import urlsplit import voluptuous as vol +import homeassistant.loader as loader + from homeassistant.const import (EVENT_HOMEASSISTANT_STOP) from homeassistant.helpers import config_validation as cv from homeassistant.helpers import discovery @@ -23,8 +25,12 @@ DOMAIN = 'upnp' DATA_UPNP = 'UPNP' CONF_ENABLE_PORT_MAPPING = 'port_mapping' +CONF_EXTERNAL_PORT = 'external_port' CONF_UNITS = 'unit' +NOTIFICATION_ID = 'upnp_notification' +NOTIFICATION_TITLE = 'UPnP Setup' + UNITS = { "Bytes": 1, "KBytes": 1024, @@ -35,6 +41,7 @@ UNITS = { CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ vol.Optional(CONF_ENABLE_PORT_MAPPING, default=True): cv.boolean, + vol.Optional(CONF_EXTERNAL_PORT, default=0): cv.positive_int, vol.Optional(CONF_UNITS, default="MBytes"): vol.In(UNITS), }), }, extra=vol.ALLOW_EXTRA) @@ -65,15 +72,33 @@ def setup(hass, config): base_url = urlsplit(hass.config.api.base_url) host = base_url.hostname - external_port = internal_port = base_url.port + internal_port = base_url.port + external_port = int(config[DOMAIN].get(CONF_EXTERNAL_PORT)) - upnp.addportmapping( - external_port, 'TCP', host, internal_port, 'Home Assistant', '') + if external_port == 0: + external_port = internal_port - def deregister_port(event): - """De-register the UPnP port mapping.""" - upnp.deleteportmapping(hass.config.api.port, 'TCP') + persistent_notification = loader.get_component('persistent_notification') - hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, deregister_port) + try: + upnp.addportmapping( + external_port, 'TCP', host, internal_port, 'Home Assistant', '') + def deregister_port(event): + """De-register the UPnP port mapping.""" + upnp.deleteportmapping(external_port, 'TCP') + + hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, deregister_port) + + except Exception as ex: + _LOGGER.error("UPnP failed to configure port mapping: %s", str(ex)) + persistent_notification.create( + hass, 'ERROR: tcp port {} is already mapped in your router.' + '
Please disable port_mapping in the upnp ' + 'configuration section.
' + 'You will need to restart hass after fixing.' + ''.format(external_port), + title=NOTIFICATION_TITLE, + notification_id=NOTIFICATION_ID) + return False return True From 63ff173305f98d09d20823fd86137fa0efb9676a Mon Sep 17 00:00:00 2001 From: Andy Castille Date: Fri, 7 Jul 2017 01:07:12 -0500 Subject: [PATCH 069/131] Use user-set device names for Linksys Smart Wi-Fi routers (3) (#8300) * Use user-set device names for Linksys Smart Wi-Fi routers (3) * Newline at end of linksys_smart.py * Remove spaces in last line of linksys_smart.py * Update linksys_smart.py --- homeassistant/components/device_tracker/linksys_smart.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/device_tracker/linksys_smart.py b/homeassistant/components/device_tracker/linksys_smart.py index 2d7fbfea33c..e71502ba5ee 100644 --- a/homeassistant/components/device_tracker/linksys_smart.py +++ b/homeassistant/components/device_tracker/linksys_smart.py @@ -83,11 +83,14 @@ class LinksysSmartWifiDeviceScanner(DeviceScanner): if not connections: _LOGGER.debug("Device %s is not connected", mac) continue - name = device["friendlyName"] - properties = device["properties"] - for prop in properties: + + name = None + for prop in device["properties"]: if prop["name"] == "userDeviceName": name = prop["value"] + if not name: + name = device.get("friendlyName", device["deviceID"]) + _LOGGER.debug("Device %s is connected", mac) self.last_results[mac] = name except (KeyError, IndexError): From fb184b4b6fc66deea724eeeb9853d4c3f9ee5e93 Mon Sep 17 00:00:00 2001 From: Simao Date: Fri, 7 Jul 2017 08:14:24 +0200 Subject: [PATCH 070/131] Added support for upload of remote or local files to slack (#8278) * Added support for upload of remote or local files to slack * Checking local file with hass.config.is_allowed_path prior to posting it --- homeassistant/components/notify/slack.py | 104 +++++++++++++++++++++-- 1 file changed, 95 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/notify/slack.py b/homeassistant/components/notify/slack.py index fa7332326da..a6257970566 100644 --- a/homeassistant/components/notify/slack.py +++ b/homeassistant/components/notify/slack.py @@ -5,11 +5,15 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/notify.slack/ """ import logging +import requests +from requests.auth import HTTPDigestAuth +from requests.auth import HTTPBasicAuth import voluptuous as vol from homeassistant.components.notify import ( - ATTR_TARGET, PLATFORM_SCHEMA, BaseNotificationService) + ATTR_TARGET, ATTR_TITLE, ATTR_DATA, + PLATFORM_SCHEMA, BaseNotificationService) from homeassistant.const import ( CONF_API_KEY, CONF_USERNAME, CONF_ICON) import homeassistant.helpers.config_validation as cv @@ -19,6 +23,19 @@ REQUIREMENTS = ['slacker==0.9.50'] _LOGGER = logging.getLogger(__name__) CONF_CHANNEL = 'default_channel' +CONF_TIMEOUT = 15 + +# Top level attributes in 'data' +ATTR_ATTACHMENTS = 'attachments' +ATTR_FILE = 'file' +# Attributes contained in file +ATTR_FILE_URL = 'url' +ATTR_FILE_PATH = 'path' +ATTR_FILE_USERNAME = 'username' +ATTR_FILE_PASSWORD = 'password' +ATTR_FILE_AUTH = 'auth' +# Any other value or absense of 'auth' lead to basic authentication being used +ATTR_FILE_AUTH_DIGEST = 'digest' PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_API_KEY): cv.string, @@ -38,7 +55,8 @@ def get_service(hass, config, discovery_info=None): config[CONF_CHANNEL], config[CONF_API_KEY], config.get(CONF_USERNAME, None), - config.get(CONF_ICON, None)) + config.get(CONF_ICON, None), + hass.config.is_allowed_path) except slacker.Error: _LOGGER.exception("Authentication failed") @@ -48,7 +66,9 @@ def get_service(hass, config, discovery_info=None): class SlackNotificationService(BaseNotificationService): """Implement the notification service for Slack.""" - def __init__(self, default_channel, api_token, username, icon): + def __init__(self, default_channel, + api_token, username, + icon, is_allowed_path): """Initialize the service.""" from slacker import Slacker self._default_channel = default_channel @@ -60,6 +80,7 @@ class SlackNotificationService(BaseNotificationService): else: self._as_user = True + self.is_allowed_path = is_allowed_path self.slack = Slacker(self._api_token) self.slack.auth.test() @@ -72,14 +93,79 @@ class SlackNotificationService(BaseNotificationService): else: targets = kwargs.get(ATTR_TARGET) - data = kwargs.get('data') - attachments = data.get('attachments') if data else None + data = kwargs.get(ATTR_DATA) + attachments = data.get(ATTR_ATTACHMENTS) if data else None + file = data.get(ATTR_FILE) if data else None + title = kwargs.get(ATTR_TITLE) for target in targets: try: - self.slack.chat.post_message( - target, message, as_user=self._as_user, - username=self._username, icon_emoji=self._icon, - attachments=attachments, link_names=True) + if file is not None: + # Load from file or url + file_as_bytes = self.load_file( + url=file.get(ATTR_FILE_URL), + local_path=file.get(ATTR_FILE_PATH), + username=file.get(ATTR_FILE_USERNAME), + password=file.get(ATTR_FILE_PASSWORD), + auth=file.get(ATTR_FILE_AUTH)) + # Choose filename + if file.get(ATTR_FILE_URL): + filename = file.get(ATTR_FILE_URL) + else: + filename = file.get(ATTR_FILE_PATH) + # Prepare structure for slack API + data = { + 'content': None, + 'filetype': None, + 'filename': filename, + # if optional title is none use the filename + 'title': title if title else filename, + 'initial_comment': message, + 'channels': target + } + # Post to slack + self.slack.files.post('files.upload', + data=data, + files={'file': file_as_bytes}) + else: + self.slack.chat.post_message( + target, message, as_user=self._as_user, + username=self._username, icon_emoji=self._icon, + attachments=attachments, link_names=True) except slacker.Error as err: _LOGGER.error("Could not send notification. Error: %s", err) + + def load_file(self, url=None, local_path=None, + username=None, password=None, auth=None): + """Load image/document/etc from a local path or url.""" + try: + if url is not None: + # check whether authentication parameters are provided + if username is not None and password is not None: + # Use digest or basic authentication + if ATTR_FILE_AUTH_DIGEST == auth: + auth_ = HTTPDigestAuth(username, password) + else: + auth_ = HTTPBasicAuth(username, password) + # load file from url with authentication + req = requests.get(url, auth=auth_, timeout=CONF_TIMEOUT) + else: + # load file from url without authentication + req = requests.get(url, timeout=CONF_TIMEOUT) + return req.content + + elif local_path is not None: + # Check whether path is whitelisted in configuration.yaml + if self.is_allowed_path(local_path): + # load file from local path on server + return open(local_path, "rb") + _LOGGER.warning("'%s' is not secure to load data from!", + local_path) + else: + # neither url nor path provided + _LOGGER.warning("Neither url nor local path found in params!") + + except OSError as error: + _LOGGER.error("Can't load from url or local path: %s", error) + + return None From e12a9eaaddf384fee3c94c7772646fd8b31fca10 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Fri, 7 Jul 2017 08:20:39 +0200 Subject: [PATCH 071/131] Update avion.py (#8364) * Update avion.py * Update decora.py * Update decora.py * Update decora.py * Update avion.py * Update decora.py * Update decora.py * Update decora.py * Update decora.py --- homeassistant/components/light/avion.py | 15 ++-- homeassistant/components/light/decora.py | 87 +++++++++--------------- 2 files changed, 39 insertions(+), 63 deletions(-) diff --git a/homeassistant/components/light/avion.py b/homeassistant/components/light/avion.py index 100ad860faa..f214d47fa1b 100644 --- a/homeassistant/components/light/avion.py +++ b/homeassistant/components/light/avion.py @@ -17,10 +17,6 @@ from homeassistant.components.light import ( PLATFORM_SCHEMA) import homeassistant.helpers.config_validation as cv -# pylint: disable=import-error - -AVION_EXCEPTION = None - REQUIREMENTS = ['avion==0.7'] _LOGGER = logging.getLogger(__name__) @@ -41,12 +37,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ def setup_platform(hass, config, add_devices, discovery_info=None): """Set up an Avion switch.""" - global AVION_EXCEPTION - + # pylint: disable=import-error import avion - AVION_EXCEPTION = avion.avionException - lights = [] if CONF_USERNAME in config and CONF_PASSWORD in config: data = avion.avion_info(config[CONF_USERNAME], config[CONF_PASSWORD]) @@ -77,6 +70,7 @@ class AvionLight(Light): def __init__(self, device): """Initialize the light.""" + # pylint: disable=import-error import avion self._name = device['name'] @@ -123,6 +117,9 @@ class AvionLight(Light): def set_state(self, brightness): """Set the state of this lamp to the provided brightness.""" + # pylint: disable=import-error + import avion + # Bluetooth LE is unreliable, and the connection may drop at any # time. Make an effort to re-establish the link. initial = time.monotonic() @@ -132,7 +129,7 @@ class AvionLight(Light): try: self._switch.set_brightness(brightness) break - except AVION_EXCEPTION: + except avion.avionException: self._switch.connect() return True diff --git a/homeassistant/components/light/decora.py b/homeassistant/components/light/decora.py index 26c7368b648..bc45870f5f2 100644 --- a/homeassistant/components/light/decora.py +++ b/homeassistant/components/light/decora.py @@ -5,6 +5,7 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/light.decora/ """ import logging +from functools import wraps import time import voluptuous as vol @@ -15,10 +16,6 @@ from homeassistant.components.light import ( PLATFORM_SCHEMA) import homeassistant.helpers.config_validation as cv -# pylint: disable=import-error - -DECORA_EXCEPTION = None - REQUIREMENTS = ['decora==0.6'] _LOGGER = logging.getLogger(__name__) @@ -35,14 +32,28 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) +def retry(method): + """Retry bluetooth commands.""" + @wraps(method) + def wrapper_retry(device, *args, **kwds): + """Try send command and retry on error.""" + # pylint: disable=import-error + import decora + + initial = time.monotonic() + while True: + if time.monotonic() - initial >= 10: + return None + try: + return method(device, *args, **kwds) + except (decora.decoraException, AttributeError): + # pylint: disable=protected-access + device._switch.connect() + return wrapper_retry + + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up an Decora switch.""" - global DECORA_EXCEPTION - - import decora - - DECORA_EXCEPTION = decora.decoraException - lights = [] for address, device_config in config[CONF_DEVICES].items(): device = {} @@ -60,6 +71,7 @@ class DecoraLight(Light): def __init__(self, device): """Initialize the light.""" + # pylint: disable=import-error import decora self._name = device['name'] @@ -82,13 +94,11 @@ class DecoraLight(Light): @property def is_on(self): """Return true if device is on.""" - self.update() return self._state @property def brightness(self): """Return the brightness of this light between 0..255.""" - self.update() return self._brightness @property @@ -106,61 +116,30 @@ class DecoraLight(Light): """We can read the actual state.""" return False + @retry def set_state(self, brightness): """Set the state of this lamp to the provided brightness.""" - initial = time.monotonic() - while True: - if time.monotonic() - initial >= 10: - return None - try: - self._switch.set_brightness(brightness / 2.55) - break - except (DECORA_EXCEPTION, AttributeError): - self._switch.connect() - + self._switch.set_brightness(brightness / 2.55) self._brightness = brightness - return True + @retry def turn_on(self, **kwargs): """Turn the specified or all lights on.""" brightness = kwargs.get(ATTR_BRIGHTNESS) - - initial = time.monotonic() - while True: - if time.monotonic() - initial >= 10: - return None - try: - self._switch.on() - self._state = True - break - except (DECORA_EXCEPTION, AttributeError): - self._switch.connect() + self._switch.on() + self._state = True if brightness is not None: self.set_state(brightness) + @retry def turn_off(self, **kwargs): """Turn the specified or all lights off.""" - initial = time.monotonic() - while True: - if time.monotonic() - initial >= 10: - return None - try: - self._switch.off() - self._state = False - break - except (DECORA_EXCEPTION, AttributeError): - self._switch.connect() + self._switch.off() + self._state = False + @retry def update(self): """Synchronise internal state with the actual light state.""" - initial = time.monotonic() - while True: - if time.monotonic() - initial >= 10: - return None - try: - self._brightness = self._switch.get_brightness() * 2.55 - self._state = self._switch.get_on() - break - except (DECORA_EXCEPTION, AttributeError): - self._switch.connect() + self._brightness = self._switch.get_brightness() * 2.55 + self._state = self._switch.get_on() From 7536e825fa8e717366ccadd91da30a81859bda2b Mon Sep 17 00:00:00 2001 From: Open Home Automation Date: Fri, 7 Jul 2017 08:21:06 +0200 Subject: [PATCH 072/131] LaMetric platform and notify module (#8230) * First version of a LaMetrci platform with a Notify module * Cleanup, fix formatting bugs * More formatting * Formatting * Updated requirements * formatting * Formatting * More formatting * Dummy commit for new Travis CI run * Refactoring class methods to instance methods * Cleanup unused classed * Removed Eddystone_weatherurl that had nothing to do with this component * Cleanup class methods * Cleanup requirements * Removed broad excepts Removed storage of LaMetric devices * Removed unused import --- .coveragerc | 3 + homeassistant/components/lametric.py | 83 +++++++++++++++++++ homeassistant/components/notify/lametric.py | 91 +++++++++++++++++++++ requirements_all.txt | 4 + 4 files changed, 181 insertions(+) create mode 100644 homeassistant/components/lametric.py create mode 100644 homeassistant/components/notify/lametric.py diff --git a/.coveragerc b/.coveragerc index f1150512225..67b1225797d 100644 --- a/.coveragerc +++ b/.coveragerc @@ -92,6 +92,9 @@ omit = homeassistant/components/knx.py homeassistant/components/*/knx.py + homeassistant/components/lametric.py + homeassistant/components/*/lametric.py + homeassistant/components/lutron.py homeassistant/components/*/lutron.py diff --git a/homeassistant/components/lametric.py b/homeassistant/components/lametric.py new file mode 100644 index 00000000000..b11d874127f --- /dev/null +++ b/homeassistant/components/lametric.py @@ -0,0 +1,83 @@ +""" +Support for LaMetric time. + +This is the base platform to support LaMetric components: +Notify, Light, Mediaplayer + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/lametric/ +""" +import logging + +import voluptuous as vol + +import homeassistant.helpers.config_validation as cv + +REQUIREMENTS = ['lmnotify==0.0.4'] + +_LOGGER = logging.getLogger(__name__) + +CONF_CLIENT_ID = 'client_id' +CONF_CLIENT_SECRET = 'client_secret' + +DOMAIN = 'lametric' +LAMETRIC_DEVICES = 'LAMETRIC_DEVICES' + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({ + vol.Required(CONF_CLIENT_ID): cv.string, + vol.Required(CONF_CLIENT_SECRET): cv.string, + }), +}, extra=vol.ALLOW_EXTRA) + + +# pylint: disable=broad-except +def setup(hass, config): + """Set up the LaMetricManager.""" + _LOGGER.debug("Setting up LaMetric platform") + conf = config[DOMAIN] + hlmn = HassLaMetricManager(client_id=conf[CONF_CLIENT_ID], + client_secret=conf[CONF_CLIENT_SECRET]) + devices = hlmn.manager().get_devices() + + found = False + hass.data[DOMAIN] = hlmn + for dev in devices: + _LOGGER.debug("Discovered LaMetric device: %s", dev) + found = True + + return found + + +class HassLaMetricManager(): + """ + A class that encapsulated requests to the LaMetric manager. + + As the original class does not have a re-connect feature that is needed + for applications running for a long time as the OAuth tokens expire. This + class implements this reconnect() feature. + """ + + def __init__(self, client_id, client_secret): + """Initialize HassLaMetricManager and connect to LaMetric.""" + from lmnotify import LaMetricManager + + _LOGGER.debug("Connecting to LaMetric") + self.lmn = LaMetricManager(client_id, client_secret) + self._client_id = client_id + self._client_secret = client_secret + + def reconnect(self): + """ + Reconnect to LaMetric. + + This is usually necessary when the OAuth token is expired. + """ + from lmnotify import LaMetricManager + _LOGGER.debug("Reconnecting to LaMetric") + self.lmn = LaMetricManager(self._client_id, + self._client_secret) + + def manager(self): + """Return the global LaMetricManager instance.""" + return self.lmn diff --git a/homeassistant/components/notify/lametric.py b/homeassistant/components/notify/lametric.py new file mode 100644 index 00000000000..a3af1eb1914 --- /dev/null +++ b/homeassistant/components/notify/lametric.py @@ -0,0 +1,91 @@ +""" +Notifier for LaMetric time. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/notify.lametric/ +""" +import logging + +import voluptuous as vol + +from homeassistant.components.notify import ( + ATTR_TARGET, ATTR_DATA, PLATFORM_SCHEMA, BaseNotificationService) +from homeassistant.const import CONF_ICON +import homeassistant.helpers.config_validation as cv + +from homeassistant.components.lametric import DOMAIN + +REQUIREMENTS = ['lmnotify==0.0.4'] + +_LOGGER = logging.getLogger(__name__) + +CONF_DISPLAY_TIME = "display_time" + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Optional(CONF_ICON, default="i555"): cv.string, + vol.Optional(CONF_DISPLAY_TIME, default=10): cv.positive_int, +}) + + +# pylint: disable=unused-variable +def get_service(hass, config, discovery_info=None): + """Get the Slack notification service.""" + hlmn = hass.data.get(DOMAIN) + return LaMetricNotificationService(hlmn, + config[CONF_ICON], + config[CONF_DISPLAY_TIME] * 1000) + + +class LaMetricNotificationService(BaseNotificationService): + """Implement the notification service for LaMetric.""" + + def __init__(self, hasslametricmanager, icon, display_time): + """Initialize the service.""" + self.hasslametricmanager = hasslametricmanager + self._icon = icon + self._display_time = display_time + + # pylint: disable=broad-except + def send_message(self, message="", **kwargs): + """Send a message to some LaMetric deviced.""" + from lmnotify import SimpleFrame, Sound, Model + + targets = kwargs.get(ATTR_TARGET) + data = kwargs.get(ATTR_DATA) + _LOGGER.debug("Targets/Data: %s/%s", targets, data) + icon = self._icon + sound = None + + # User-defined icon? + if data is not None: + if "icon" in data: + icon = data["icon"] + if "sound" in data: + try: + sound = Sound(category="notifications", + sound_id=data["sound"]) + _LOGGER.debug("Adding notification sound %s", + data["sound"]) + except AssertionError: + _LOGGER.error("Sound ID %s unknown, ignoring", + data["sound"]) + + text_frame = SimpleFrame(icon, message) + _LOGGER.debug("Icon/Message/Duration: %s, %s, %d", + icon, message, self._display_time) + + frames = [text_frame] + + if sound is not None: + frames.append(sound) + + _LOGGER.debug(frames) + + model = Model(frames=frames) + lmn = self.hasslametricmanager.manager() + devices = lmn.get_devices() + for dev in devices: + if (targets is None) or (dev["name"] in targets): + lmn.set_device(dev) + lmn.send_notification(model, lifetime=self._display_time) + _LOGGER.debug("Sent notification to LaMetric %s", dev["name"]) diff --git a/requirements_all.txt b/requirements_all.txt index d00629c6a64..a459c65689d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -365,6 +365,10 @@ limitlessled==1.0.8 # homeassistant.components.media_player.liveboxplaytv liveboxplaytv==1.4.9 +# homeassistant.components.lametric +# homeassistant.components.notify.lametric +lmnotify==0.0.4 + # homeassistant.components.sensor.lyft lyft_rides==0.1.0b0 From 233920f22cf257bf545bea59646e3482bdc9458d Mon Sep 17 00:00:00 2001 From: Tom Matheussen Date: Fri, 7 Jul 2017 16:52:11 +0200 Subject: [PATCH 073/131] Sets spotify media_type to music (#8387) * Sets spotify media_type to music * Removed whitespace * Update spotify.py --- homeassistant/components/media_player/spotify.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/homeassistant/components/media_player/spotify.py b/homeassistant/components/media_player/spotify.py index e6604297fa1..bc0728c7ff2 100644 --- a/homeassistant/components/media_player/spotify.py +++ b/homeassistant/components/media_player/spotify.py @@ -313,3 +313,8 @@ class SpotifyMediaPlayer(MediaPlayerDevice): if self._user is not None and self._user['product'] == 'premium': return SUPPORT_SPOTIFY return None + + @property + def media_content_type(self): + """Return the media type.""" + return MEDIA_TYPE_MUSIC From f2267437dffb9be29e294e10cb502ca02b1dec47 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 7 Jul 2017 07:53:04 -0700 Subject: [PATCH 074/131] Update snips.py --- homeassistant/components/snips.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/snips.py b/homeassistant/components/snips.py index de54c0239c7..b123de48158 100644 --- a/homeassistant/components/snips.py +++ b/homeassistant/components/snips.py @@ -108,6 +108,7 @@ class IntentHandler(object): slots = self.parse_slots(response) yield from action.async_run(slots) + # pylint: disable=no-self-use def parse_slots(self, response): """Parse the intent slots.""" parameters = {} From cf924cd14dfd1a47ec5f5e56c60e3a40c974fe69 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 7 Jul 2017 17:55:58 +0300 Subject: [PATCH 075/131] Update waqi sensor (#8385) --- homeassistant/components/sensor/waqi.py | 162 +++++++++++++----------- requirements_all.txt | 6 +- 2 files changed, 88 insertions(+), 80 deletions(-) diff --git a/homeassistant/components/sensor/waqi.py b/homeassistant/components/sensor/waqi.py index f762caf58ae..318a22cfa2a 100644 --- a/homeassistant/components/sensor/waqi.py +++ b/homeassistant/components/sensor/waqi.py @@ -4,18 +4,22 @@ Support for the World Air Quality Index service. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.waqi/ """ +import asyncio import logging from datetime import timedelta +import aiohttp import voluptuous as vol +from homeassistant.exceptions import PlatformNotReady import homeassistant.helpers.config_validation as cv from homeassistant.const import ( ATTR_ATTRIBUTION, ATTR_TIME, ATTR_TEMPERATURE, CONF_TOKEN) +from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.config_validation import PLATFORM_SCHEMA from homeassistant.helpers.entity import Entity -REQUIREMENTS = ['pwaqi==3.0'] +REQUIREMENTS = ['waqiasync==1.0.0'] _LOGGER = logging.getLogger(__name__) @@ -27,6 +31,18 @@ ATTR_PM10 = 'pm_10' ATTR_PM2_5 = 'pm_2_5' ATTR_PRESSURE = 'pressure' ATTR_SULFUR_DIOXIDE = 'sulfur_dioxide' + +KEY_TO_ATTR = { + 'pm25': ATTR_PM2_5, + 'pm10': ATTR_PM10, + 'h': ATTR_HUMIDITY, + 'p': ATTR_PRESSURE, + 't': ATTR_TEMPERATURE, + 'o3': ATTR_OZONE, + 'no2': ATTR_NITROGEN_DIOXIDE, + 'so2': ATTR_SULFUR_DIOXIDE, +} + ATTRIBUTION = 'Data provided by the World Air Quality Index project' CONF_LOCATIONS = 'locations' @@ -34,9 +50,7 @@ CONF_STATIONS = 'stations' SCAN_INTERVAL = timedelta(minutes=5) -SENSOR_TYPES = { - 'aqi': ['AQI', '0-300+', 'mdi:cloud'] -} +TIMEOUT = 10 PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_STATIONS): cv.ensure_list, @@ -45,51 +59,65 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -def setup_platform(hass, config, add_devices, discovery_info=None): +@asyncio.coroutine +def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Set up the requested World Air Quality Index locations.""" - import pwaqi + import waqiasync token = config.get(CONF_TOKEN) station_filter = config.get(CONF_STATIONS) locations = config.get(CONF_LOCATIONS) + client = waqiasync.WaqiClient( + token, async_get_clientsession(hass), timeout=TIMEOUT) dev = [] - for location_name in locations: - station_ids = pwaqi.findStationCodesByCity(location_name, token) - _LOGGER.info("The following stations were returned: %s", station_ids) - for station in station_ids: - waqi_sensor = WaqiSensor(WaqiData(station, token), station) - if (not station_filter) or \ - (waqi_sensor.station_name in station_filter): - dev.append(WaqiSensor(WaqiData(station, token), station)) - - add_devices(dev, True) + try: + for location_name in locations: + stations = yield from client.search(location_name) + _LOGGER.debug("The following stations were returned: %s", stations) + for station in stations: + waqi_sensor = WaqiSensor(client, station) + if not station_filter or \ + {waqi_sensor.uid, + waqi_sensor.url, + waqi_sensor.station_name} & set(station_filter): + dev.append(waqi_sensor) + except (aiohttp.client_exceptions.ClientConnectorError, + asyncio.TimeoutError): + _LOGGER.exception('Failed to connct to WAQI servers.') + raise PlatformNotReady + async_add_devices(dev, True) class WaqiSensor(Entity): """Implementation of a WAQI sensor.""" - def __init__(self, data, station_id): + def __init__(self, client, station): """Initialize the sensor.""" - self.data = data - self._station_id = station_id - self._details = None + self._client = client + try: + self.uid = station['uid'] + except (KeyError, TypeError): + self.uid = None + + try: + self.url = station['station']['url'] + except (KeyError, TypeError): + self.url = None + + try: + self.station_name = station['station']['name'] + except (KeyError, TypeError): + self.station_name = None + + self._data = None @property def name(self): """Return the name of the sensor.""" - try: - return 'WAQI {}'.format(self._details['city']['name']) - except (KeyError, TypeError): - return 'WAQI {}'.format(self._station_id) - - @property - def station_name(self): - """Return the name of the station.""" - try: - return self._details['city']['name'] - except (KeyError, TypeError): - return None + if self.station_name: + return 'WAQI {}'.format(self.station_name) + return 'WAQI {}'.format(self.url if self.url else self.uid) @property def icon(self): @@ -99,8 +127,8 @@ class WaqiSensor(Entity): @property def state(self): """Return the state of the device.""" - if self._details is not None: - return self._details.get('aqi') + if self._data is not None: + return self._data.get('aqi') return None @property @@ -113,52 +141,32 @@ class WaqiSensor(Entity): """Return the state attributes of the last update.""" attrs = {} - if self.data is not None: + if self._data is not None: try: - attrs[ATTR_ATTRIBUTION] = ATTRIBUTION - attrs[ATTR_TIME] = self._details.get('time') - attrs[ATTR_DOMINENTPOL] = self._details.get('dominentpol') - for values in self._details['iaqi']: - if values['p'] == 'pm25': - attrs[ATTR_PM2_5] = values['cur'] - elif values['p'] == 'pm10': - attrs[ATTR_PM10] = values['cur'] - elif values['p'] == 'h': - attrs[ATTR_HUMIDITY] = values['cur'] - elif values['p'] == 'p': - attrs[ATTR_PRESSURE] = values['cur'] - elif values['p'] == 't': - attrs[ATTR_TEMPERATURE] = values['cur'] - elif values['p'] == 'o3': - attrs[ATTR_OZONE] = values['cur'] - elif values['p'] == 'no2': - attrs[ATTR_NITROGEN_DIOXIDE] = values['cur'] - elif values['p'] == 'so2': - attrs[ATTR_SULFUR_DIOXIDE] = values['cur'] + attrs[ATTR_ATTRIBUTION] = ' and '.join( + [ATTRIBUTION] + [ + v['name'] for v in self._data.get('attributions', [])]) + + attrs[ATTR_TIME] = self._data['time']['s'] + attrs[ATTR_DOMINENTPOL] = self._data.get('dominentpol') + + iaqi = self._data['iaqi'] + for key in iaqi: + if key in KEY_TO_ATTR: + attrs[KEY_TO_ATTR[key]] = iaqi[key]['v'] + else: + attrs[key] = iaqi[key]['v'] return attrs except (IndexError, KeyError): return {ATTR_ATTRIBUTION: ATTRIBUTION} - def update(self): + @asyncio.coroutine + def async_update(self): """Get the latest data and updates the states.""" - self.data.update() - self._details = self.data.data - - -class WaqiData(object): - """Get the latest data and update the states.""" - - def __init__(self, station_id, token): - """Initialize the data object.""" - self._station_id = station_id - self._token = token - self.data = None - - def update(self): - """Get the data from World Air Quality Index and updates the states.""" - import pwaqi - try: - self.data = pwaqi.get_station_observation( - self._station_id, self._token) - except AttributeError: - _LOGGER.exception("Unable to fetch data from WAQI") + if self.uid: + result = yield from self._client.get_station_by_number(self.uid) + elif self.url: + result = yield from self._client.get_station_by_name(self.url) + else: + result = None + self._data = result diff --git a/requirements_all.txt b/requirements_all.txt index a459c65689d..5ac177c7b13 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -489,9 +489,6 @@ pushbullet.py==0.10.0 # homeassistant.components.notify.pushetta pushetta==1.0.15 -# homeassistant.components.sensor.waqi -pwaqi==3.0 - # homeassistant.components.light.rpi_gpio_pwm pwmled==1.1.1 @@ -924,6 +921,9 @@ vtjp==0.1.14 # homeassistant.components.switch.wake_on_lan wakeonlan==0.2.2 +# homeassistant.components.sensor.waqi +waqiasync==1.0.0 + # homeassistant.components.media_player.gpmdp websocket-client==0.37.0 From 6c9742afc49b4b9702bc1af747252603f3901357 Mon Sep 17 00:00:00 2001 From: Anders Melchiorsen Date: Fri, 7 Jul 2017 19:57:14 +0200 Subject: [PATCH 076/131] Update aiolifx (#8396) --- homeassistant/components/light/lifx.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/light/lifx.py b/homeassistant/components/light/lifx.py index f1784618d94..fd713989f52 100644 --- a/homeassistant/components/light/lifx.py +++ b/homeassistant/components/light/lifx.py @@ -33,7 +33,7 @@ import homeassistant.util.color as color_util _LOGGER = logging.getLogger(__name__) -REQUIREMENTS = ['aiolifx==0.5.0', 'aiolifx_effects==0.1.0'] +REQUIREMENTS = ['aiolifx==0.5.2', 'aiolifx_effects==0.1.0'] UDP_BROADCAST_PORT = 56700 diff --git a/requirements_all.txt b/requirements_all.txt index 5ac177c7b13..e9581962fa4 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -49,7 +49,7 @@ aiodns==1.1.1 aiohttp_cors==0.5.3 # homeassistant.components.light.lifx -aiolifx==0.5.0 +aiolifx==0.5.2 # homeassistant.components.light.lifx aiolifx_effects==0.1.0 From 5ae2bcdbb782ff3f5c6502c44d144dceb6a529e7 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 7 Jul 2017 11:40:04 -0700 Subject: [PATCH 077/131] Code owners (#8393) * Add initial code owners file * Add component author owners * Add link to blog * Sort * Add setup.py * Update CODEOWNERS --- CODEOWNERS | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 00000000000..10a0f0f9973 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,41 @@ +# People marked here will be automatically requested for a review +# when the code that they own is touched. +# https://github.com/blog/2392-introducing-code-owners + +setup.py @home-assistant/core +homeassistant/*.py @home-assistant/core +homeassistant/helpers/* @home-assistant/core +homeassistant/util/* @home-assistant/core +homeassistant/components/api.py @home-assistant/core +homeassistant/components/automation/* @home-assistant/core +homeassistant/components/configurator.py @home-assistant/core +homeassistant/components/group.py @home-assistant/core +homeassistant/components/history.py @home-assistant/core +homeassistant/components/http/* @home-assistant/core +homeassistant/components/input_*.py @home-assistant/core +homeassistant/components/introduction.py @home-assistant/core +homeassistant/components/logger.py @home-assistant/core +homeassistant/components/mqtt/* @home-assistant/core +homeassistant/components/panel_custom.py @home-assistant/core +homeassistant/components/panel_iframe.py @home-assistant/core +homeassistant/components/persistent_notification.py @home-assistant/core +homeassistant/components/scene/__init__.py @home-assistant/core +homeassistant/components/scene/hass.py @home-assistant/core +homeassistant/components/script.py @home-assistant/core +homeassistant/components/shell_command.py @home-assistant/core +homeassistant/components/sun.py @home-assistant/core +homeassistant/components/updater.py @home-assistant/core +homeassistant/components/weblink.py @home-assistant/core +homeassistant/components/websocket_api.py @home-assistant/core +homeassistant/components/zone.py @home-assistant/core + +Dockerfile @home-assistant/docker +virtualization/Docker/* @home-assistant/docker + +homeassistant/components/zwave/* @home-assistant/zwave +homeassistant/components/*/zwave.py @home-assistant/zwave + +# Indiviudal components +homeassistant/components/cover/template.py @PhracturedBlue +homeassistant/components/device_tracker/automatic.py @armills +homeassistant/components/media_player/kodi.py @armills From 222ad3ab6d077cb219295213881d0723f94fd31f Mon Sep 17 00:00:00 2001 From: Charles Blonde Date: Sat, 8 Jul 2017 01:59:41 +0200 Subject: [PATCH 078/131] Add new Dyson sensors (#8199) * Add new Dyson sensors * Add unit of measurement for dust and air quality * Code review --- homeassistant/components/dyson.py | 8 +- homeassistant/components/fan/dyson.py | 14 ++- homeassistant/components/sensor/dyson.py | 141 ++++++++++++++++++++--- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/fan/test_dyson.py | 11 +- tests/components/sensor/test_dyson.py | 118 ++++++++++++++++++- 7 files changed, 267 insertions(+), 29 deletions(-) diff --git a/homeassistant/components/dyson.py b/homeassistant/components/dyson.py index eb430582ba7..c5aaba6152b 100644 --- a/homeassistant/components/dyson.py +++ b/homeassistant/components/dyson.py @@ -1,4 +1,8 @@ -"""Parent component for Dyson Pure Cool Link devices.""" +"""Parent component for Dyson Pure Cool Link devices. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/dyson/ +""" import logging @@ -9,7 +13,7 @@ from homeassistant.helpers import discovery from homeassistant.const import CONF_USERNAME, CONF_PASSWORD, CONF_TIMEOUT, \ CONF_DEVICES -REQUIREMENTS = ['libpurecoollink==0.1.5'] +REQUIREMENTS = ['libpurecoollink==0.2.0'] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/fan/dyson.py b/homeassistant/components/fan/dyson.py index a2fb2b95ec4..de70c35739d 100644 --- a/homeassistant/components/fan/dyson.py +++ b/homeassistant/components/fan/dyson.py @@ -1,4 +1,8 @@ -"""Support for Dyson Pure Cool link fan.""" +"""Support for Dyson Pure Cool link fan. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/fan.dyson/ +""" import logging import asyncio from os import path @@ -79,9 +83,11 @@ class DysonPureCoolLinkDevice(FanEntity): def on_message(self, message): """Called when new messages received from the fan.""" - _LOGGER.debug( - "Message received for fan device %s : %s", self.name, message) - self.schedule_update_ha_state() + from libpurecoollink.dyson import DysonState + if isinstance(message, DysonState): + _LOGGER.debug("Message received for fan device %s : %s", self.name, + message) + self.schedule_update_ha_state() @property def should_poll(self): diff --git a/homeassistant/components/sensor/dyson.py b/homeassistant/components/sensor/dyson.py index e68909a1d6c..d3839f847ea 100644 --- a/homeassistant/components/sensor/dyson.py +++ b/homeassistant/components/sensor/dyson.py @@ -1,15 +1,24 @@ -"""Support for Dyson Pure Cool Link Sensors.""" +"""Support for Dyson Pure Cool Link Sensors. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.dyson/ +""" import logging import asyncio -from homeassistant.const import STATE_UNKNOWN +from homeassistant.const import TEMP_CELSIUS from homeassistant.components.dyson import DYSON_DEVICES from homeassistant.helpers.entity import Entity DEPENDENCIES = ['dyson'] -SENSOR_UNITS = {'filter_life': 'hours'} +SENSOR_UNITS = { + "filter_life": "hours", + "humidity": "%", + "dust": "level", + "air_quality": "level" +} _LOGGER = logging.getLogger(__name__) @@ -18,21 +27,26 @@ def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Dyson Sensors.""" _LOGGER.info("Creating new Dyson fans") devices = [] + unit = hass.config.units.temperature_unit # Get Dyson Devices from parent component for device in hass.data[DYSON_DEVICES]: devices.append(DysonFilterLifeSensor(hass, device)) + devices.append(DysonDustSensor(hass, device)) + devices.append(DysonHumiditySensor(hass, device)) + devices.append(DysonTemperatureSensor(hass, device, unit)) + devices.append(DysonAirQualitySensor(hass, device)) add_devices(devices) -class DysonFilterLifeSensor(Entity): - """Representation of Dyson filter life sensor (in hours).""" +class DysonSensor(Entity): + """Representation of Dyson sensor.""" def __init__(self, hass, device): """Create a new Dyson filter life sensor.""" self.hass = hass self._device = device - self._name = "{} filter life".format(self._device.name) self._old_value = None + self._name = None @asyncio.coroutine def async_added_to_hass(self): @@ -42,10 +56,10 @@ class DysonFilterLifeSensor(Entity): def on_message(self, message): """Called when new messages received from the fan.""" - _LOGGER.debug( - "Message received for %s device: %s", self.name, message) # Prevent refreshing if not needed if self._old_value is None or self._old_value != self.state: + _LOGGER.debug("Message received for %s device: %s", self.name, + message) self._old_value = self.state self.schedule_update_ha_state() @@ -54,19 +68,116 @@ class DysonFilterLifeSensor(Entity): """No polling needed.""" return False - @property - def state(self): - """Return filter life in hours..""" - if self._device.state: - return self._device.state.filter_life - return STATE_UNKNOWN - @property def name(self): """Return the name of the dyson sensor name.""" return self._name + +class DysonFilterLifeSensor(DysonSensor): + """Representation of Dyson filter life sensor (in hours).""" + + def __init__(self, hass, device): + """Create a new Dyson filter life sensor.""" + DysonSensor.__init__(self, hass, device) + self._name = "{} filter life".format(self._device.name) + + @property + def state(self): + """Return filter life in hours.""" + if self._device.state: + return int(self._device.state.filter_life) + return None + @property def unit_of_measurement(self): """Return the unit the value is expressed in.""" return SENSOR_UNITS['filter_life'] + + +class DysonDustSensor(DysonSensor): + """Representation of Dyson Dust sensor (lower is better).""" + + def __init__(self, hass, device): + """Create a new Dyson Dust sensor.""" + DysonSensor.__init__(self, hass, device) + self._name = "{} dust".format(self._device.name) + + @property + def state(self): + """Return Dust value.""" + if self._device.environmental_state: + return self._device.environmental_state.dust + return None + + @property + def unit_of_measurement(self): + """Return the unit the value is expressed in.""" + return SENSOR_UNITS['dust'] + + +class DysonHumiditySensor(DysonSensor): + """Representation of Dyson Humidity sensor.""" + + def __init__(self, hass, device): + """Create a new Dyson Humidity sensor.""" + DysonSensor.__init__(self, hass, device) + self._name = "{} humidity".format(self._device.name) + + @property + def state(self): + """Return Dust value.""" + if self._device.environmental_state: + return self._device.environmental_state.humidity + return None + + @property + def unit_of_measurement(self): + """Return the unit the value is expressed in.""" + return SENSOR_UNITS['humidity'] + + +class DysonTemperatureSensor(DysonSensor): + """Representation of Dyson Temperature sensor.""" + + def __init__(self, hass, device, unit): + """Create a new Dyson Temperature sensor.""" + DysonSensor.__init__(self, hass, device) + self._name = "{} temperature".format(self._device.name) + self._unit = unit + + @property + def state(self): + """Return Dust value.""" + if self._device.environmental_state: + temperature_kelvin = self._device.environmental_state.temperature + if self._unit == TEMP_CELSIUS: + return float("{0:.1f}".format(temperature_kelvin - 273.15)) + return float("{0:.1f}".format(temperature_kelvin * 9 / 5 - 459.67)) + return None + + @property + def unit_of_measurement(self): + """Return the unit the value is expressed in.""" + return self._unit + + +class DysonAirQualitySensor(DysonSensor): + """Representation of Dyson Air Quality sensor (lower is better).""" + + def __init__(self, hass, device): + """Create a new Dyson Air Quality sensor.""" + DysonSensor.__init__(self, hass, device) + self._name = "{} air quality".format(self._device.name) + + @property + def state(self): + """Return Air QUality value.""" + if self._device.environmental_state: + return self._device.environmental_state.volatil_organic_compounds + return None + + @property + def unit_of_measurement(self): + """Return the unit the value is expressed in.""" + return SENSOR_UNITS['air_quality'] diff --git a/requirements_all.txt b/requirements_all.txt index e9581962fa4..5458b3459f8 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -348,7 +348,7 @@ knxip==0.4 libnacl==1.5.1 # homeassistant.components.dyson -libpurecoollink==0.1.5 +libpurecoollink==0.2.0 # homeassistant.components.device_tracker.mikrotik librouteros==1.0.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 07a3ad8a681..8ea6c98042b 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -62,7 +62,7 @@ holidays==0.8.1 influxdb==3.0.0 # homeassistant.components.dyson -libpurecoollink==0.1.5 +libpurecoollink==0.2.0 # homeassistant.components.media_player.soundtouch libsoundtouch==0.7.2 diff --git a/tests/components/fan/test_dyson.py b/tests/components/fan/test_dyson.py index 4548b12434b..e388f31e664 100644 --- a/tests/components/fan/test_dyson.py +++ b/tests/components/fan/test_dyson.py @@ -6,6 +6,15 @@ from homeassistant.components.dyson import DYSON_DEVICES from homeassistant.components.fan import dyson from tests.common import get_test_home_assistant from libpurecoollink.const import FanSpeed, FanMode, NightMode, Oscillation +from libpurecoollink.dyson import DysonState + + +class MockDysonState(DysonState): + """Mock Dyson state.""" + + def __init__(self): + """Create new Mock Dyson State.""" + pass def _get_device_with_no_state(): @@ -257,7 +266,7 @@ class DysonTest(unittest.TestCase): component = dyson.DysonPureCoolLinkDevice(self.hass, device) component.entity_id = "entity_id" component.schedule_update_ha_state = mock.Mock() - component.on_message("Message") + component.on_message(MockDysonState()) component.schedule_update_ha_state.assert_called_with() def test_service_set_night_mode(self): diff --git a/tests/components/sensor/test_dyson.py b/tests/components/sensor/test_dyson.py index 8dc76c70147..8599346f769 100644 --- a/tests/components/sensor/test_dyson.py +++ b/tests/components/sensor/test_dyson.py @@ -2,7 +2,7 @@ import unittest from unittest import mock -from homeassistant.const import STATE_UNKNOWN +from homeassistant.const import TEMP_CELSIUS, TEMP_FAHRENHEIT from homeassistant.components.sensor import dyson from tests.common import get_test_home_assistant @@ -12,6 +12,7 @@ def _get_device_without_state(): device = mock.Mock() device.name = "Device_name" device.state = None + device.environmental_state = None return device @@ -21,6 +22,12 @@ def _get_with_state(): device.name = "Device_name" device.state = mock.Mock() device.state.filter_life = 100 + device.environmental_state = mock.Mock() + device.environmental_state.dust = 5 + device.environmental_state.humidity = 45 + device.environmental_state.temperature = 295 + device.environmental_state.volatil_organic_compounds = 2 + return device @@ -45,27 +52,31 @@ class DysonTest(unittest.TestCase): def test_setup_component(self): """Test setup component with devices.""" def _add_device(devices): - assert len(devices) == 1 + assert len(devices) == 5 assert devices[0].name == "Device_name filter life" + assert devices[1].name == "Device_name dust" + assert devices[2].name == "Device_name humidity" + assert devices[3].name == "Device_name temperature" + assert devices[4].name == "Device_name air quality" device = _get_device_without_state() self.hass.data[dyson.DYSON_DEVICES] = [device] dyson.setup_platform(self.hass, None, _add_device) def test_dyson_filter_life_sensor(self): - """Test sensor with no value.""" + """Test filter life sensor with no value.""" sensor = dyson.DysonFilterLifeSensor(self.hass, _get_device_without_state()) sensor.entity_id = "sensor.dyson_1" self.assertFalse(sensor.should_poll) - self.assertEqual(sensor.state, STATE_UNKNOWN) + self.assertIsNone(sensor.state) self.assertEqual(sensor.unit_of_measurement, "hours") self.assertEqual(sensor.name, "Device_name filter life") self.assertEqual(sensor.entity_id, "sensor.dyson_1") sensor.on_message('message') def test_dyson_filter_life_sensor_with_values(self): - """Test sensor with values.""" + """Test filter sensor with values.""" sensor = dyson.DysonFilterLifeSensor(self.hass, _get_with_state()) sensor.entity_id = "sensor.dyson_1" self.assertFalse(sensor.should_poll) @@ -74,3 +85,100 @@ class DysonTest(unittest.TestCase): self.assertEqual(sensor.name, "Device_name filter life") self.assertEqual(sensor.entity_id, "sensor.dyson_1") sensor.on_message('message') + + def test_dyson_dust_sensor(self): + """Test dust sensor with no value.""" + sensor = dyson.DysonDustSensor(self.hass, + _get_device_without_state()) + sensor.entity_id = "sensor.dyson_1" + self.assertFalse(sensor.should_poll) + self.assertIsNone(sensor.state) + self.assertEqual(sensor.unit_of_measurement, 'level') + self.assertEqual(sensor.name, "Device_name dust") + self.assertEqual(sensor.entity_id, "sensor.dyson_1") + + def test_dyson_dust_sensor_with_values(self): + """Test dust sensor with values.""" + sensor = dyson.DysonDustSensor(self.hass, _get_with_state()) + sensor.entity_id = "sensor.dyson_1" + self.assertFalse(sensor.should_poll) + self.assertEqual(sensor.state, 5) + self.assertEqual(sensor.unit_of_measurement, 'level') + self.assertEqual(sensor.name, "Device_name dust") + self.assertEqual(sensor.entity_id, "sensor.dyson_1") + + def test_dyson_humidity_sensor(self): + """Test humidity sensor with no value.""" + sensor = dyson.DysonHumiditySensor(self.hass, + _get_device_without_state()) + sensor.entity_id = "sensor.dyson_1" + self.assertFalse(sensor.should_poll) + self.assertIsNone(sensor.state) + self.assertEqual(sensor.unit_of_measurement, '%') + self.assertEqual(sensor.name, "Device_name humidity") + self.assertEqual(sensor.entity_id, "sensor.dyson_1") + + def test_dyson_humidity_sensor_with_values(self): + """Test humidity sensor with values.""" + sensor = dyson.DysonHumiditySensor(self.hass, _get_with_state()) + sensor.entity_id = "sensor.dyson_1" + self.assertFalse(sensor.should_poll) + self.assertEqual(sensor.state, 45) + self.assertEqual(sensor.unit_of_measurement, '%') + self.assertEqual(sensor.name, "Device_name humidity") + self.assertEqual(sensor.entity_id, "sensor.dyson_1") + + def test_dyson_temperature_sensor(self): + """Test temperature sensor with no value.""" + sensor = dyson.DysonTemperatureSensor(self.hass, + _get_device_without_state(), + TEMP_CELSIUS) + sensor.entity_id = "sensor.dyson_1" + self.assertFalse(sensor.should_poll) + self.assertIsNone(sensor.state) + self.assertEqual(sensor.unit_of_measurement, '°C') + self.assertEqual(sensor.name, "Device_name temperature") + self.assertEqual(sensor.entity_id, "sensor.dyson_1") + + def test_dyson_temperature_sensor_with_values(self): + """Test temperature sensor with values.""" + sensor = dyson.DysonTemperatureSensor(self.hass, + _get_with_state(), + TEMP_CELSIUS) + sensor.entity_id = "sensor.dyson_1" + self.assertFalse(sensor.should_poll) + self.assertEqual(sensor.state, 21.9) + self.assertEqual(sensor.unit_of_measurement, '°C') + self.assertEqual(sensor.name, "Device_name temperature") + self.assertEqual(sensor.entity_id, "sensor.dyson_1") + + sensor = dyson.DysonTemperatureSensor(self.hass, + _get_with_state(), + TEMP_FAHRENHEIT) + sensor.entity_id = "sensor.dyson_1" + self.assertFalse(sensor.should_poll) + self.assertEqual(sensor.state, 71.3) + self.assertEqual(sensor.unit_of_measurement, '°F') + self.assertEqual(sensor.name, "Device_name temperature") + self.assertEqual(sensor.entity_id, "sensor.dyson_1") + + def test_dyson_air_quality_sensor(self): + """Test air quality sensor with no value.""" + sensor = dyson.DysonAirQualitySensor(self.hass, + _get_device_without_state()) + sensor.entity_id = "sensor.dyson_1" + self.assertFalse(sensor.should_poll) + self.assertIsNone(sensor.state) + self.assertEqual(sensor.unit_of_measurement, 'level') + self.assertEqual(sensor.name, "Device_name air quality") + self.assertEqual(sensor.entity_id, "sensor.dyson_1") + + def test_dyson_air_quality_sensor_with_values(self): + """Test air quality sensor with values.""" + sensor = dyson.DysonAirQualitySensor(self.hass, _get_with_state()) + sensor.entity_id = "sensor.dyson_1" + self.assertFalse(sensor.should_poll) + self.assertEqual(sensor.state, 2) + self.assertEqual(sensor.unit_of_measurement, 'level') + self.assertEqual(sensor.name, "Device_name air quality") + self.assertEqual(sensor.entity_id, "sensor.dyson_1") From d3acb25070a379f9b9b2c8b7b3ca2641dd5bd14a Mon Sep 17 00:00:00 2001 From: Adam Mills Date: Fri, 7 Jul 2017 20:00:14 -0400 Subject: [PATCH 079/131] Fix CODEOWNERS z-wave team name (#8400) --- CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 10a0f0f9973..3c975ca3862 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -32,8 +32,8 @@ homeassistant/components/zone.py @home-assistant/core Dockerfile @home-assistant/docker virtualization/Docker/* @home-assistant/docker -homeassistant/components/zwave/* @home-assistant/zwave -homeassistant/components/*/zwave.py @home-assistant/zwave +homeassistant/components/zwave/* @home-assistant/z-wave +homeassistant/components/*/zwave.py @home-assistant/z-wave # Indiviudal components homeassistant/components/cover/template.py @PhracturedBlue From acf6d4ab8264e9066abb5f6e9804e77e2420565d Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sat, 8 Jul 2017 10:57:24 +0200 Subject: [PATCH 080/131] Upgrade Sphinx to 1.6.3 (#8405) --- requirements_docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_docs.txt b/requirements_docs.txt index eb217ec94ec..da5e4159de9 100644 --- a/requirements_docs.txt +++ b/requirements_docs.txt @@ -1,3 +1,3 @@ -Sphinx==1.6.2 +Sphinx==1.6.3 sphinx-autodoc-typehints==1.2.0 sphinx-autodoc-annotation==1.0.post1 From 614b5da170225fa9dffe5aa5bf1bce38e9eee592 Mon Sep 17 00:00:00 2001 From: Andy Castille Date: Sat, 8 Jul 2017 04:34:34 -0500 Subject: [PATCH 081/131] Use upstream RachioPy, fix manual run switches (#8286) * use upstream RachioPy, fix manual run switches * Update requirements for PyPi version of rachiopy * Use upstream RachioPy 0.1.2 (partial revert of https://github.com/Klikini/home-assistant/commit/39c6484d89337240918ffe60c35705b5b3405705) * Revert rachiopy downgrade --- homeassistant/components/switch/rachio.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/switch/rachio.py b/homeassistant/components/switch/rachio.py index b60aafdf483..547442a4233 100644 --- a/homeassistant/components/switch/rachio.py +++ b/homeassistant/components/switch/rachio.py @@ -17,7 +17,7 @@ DATA_RACHIO = 'rachio' CONF_MANUAL_RUN_MINS = 'manual_run_mins' DEFAULT_MANUAL_RUN_MINS = 10 -MIN_UPDATE_INTERVAL = timedelta(minutes=5) +MIN_UPDATE_INTERVAL = timedelta(seconds=30) MIN_FORCED_UPDATE_INTERVAL = timedelta(seconds=1) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ @@ -27,7 +27,6 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -# noinspection PyUnusedLocal def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the component.""" # Get options @@ -215,14 +214,11 @@ class RachioZone(SwitchDevice): def turn_on(self): """Start the zone.""" - # Convert minutes to seconds - seconds = self._manual_run_secs * 60 - # Stop other zones first self.turn_off() - _LOGGER.info("Watering %s for %d sec", self.name, seconds) - self.rachio.zone.start(self.zone_id, seconds) + _LOGGER.info("Watering %s for %d s", self.name, self._manual_run_secs) + self.rachio.zone.start(self.zone_id, self._manual_run_secs) def turn_off(self): """Stop all zones.""" From 3be01032598241020aaf80ea103734edf64d272b Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 8 Jul 2017 16:02:59 +0200 Subject: [PATCH 082/131] Marrantz SR5006 & SR5006 treated as AVR-X device | Fixed Mapping of Media Player and AUX input functions (#8409) --- homeassistant/components/media_player/denonavr.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/media_player/denonavr.py b/homeassistant/components/media_player/denonavr.py index 2bdc03c20ab..06f95a7d3a7 100644 --- a/homeassistant/components/media_player/denonavr.py +++ b/homeassistant/components/media_player/denonavr.py @@ -20,7 +20,7 @@ from homeassistant.const import ( CONF_NAME, STATE_ON, CONF_ZONE) import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['denonavr==0.5.1'] +REQUIREMENTS = ['denonavr==0.5.2'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 5458b3459f8..1257da77a10 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -148,7 +148,7 @@ datapoint==0.4.3 # decora==0.6 # homeassistant.components.media_player.denonavr -denonavr==0.5.1 +denonavr==0.5.2 # homeassistant.components.media_player.directv directpy==0.1 From 57c5ed33ee46acedd2480c59794e3a384ea760f7 Mon Sep 17 00:00:00 2001 From: Julius Mittenzwei Date: Sat, 8 Jul 2017 16:12:19 +0200 Subject: [PATCH 083/131] New component to connect to VELUX KLF 200 Interface (#8203) * New component to connect to VELUX KLF 200 Interface * Issue #8203: modifications as suggested by hound * Issue #8203: added entries to .coveragerc * moving velux/__init__p.y to velux.py * Issue #8203: Using hass.data for storing global object, updated docstrings * Issue #8203: validation of config, using standard approach for getting config values * Issue #8203: Exception handling if connection to velux component fails * Issue #8203: removed unused import * Issue #8203: Some minor changes within docstrings * Issue #8203: Some minor changes within docstrings * Issue #8203: added dependency for pyvlx to requirements_all.txt * Issue #8203: less broad exception * Issue #8203: increased version * Issue #8203: changed position of pyvlx within requirements_all.txt * Issue #8203: bumped version of pyvlx to 0.1.3 (better handling of retries when token expires) * reset pointer to home-assistant-polymer * Issue #8203: modifications as suggested by fabaff * hound *sigh* --- .coveragerc | 3 ++ homeassistant/components/scene/velux.py | 55 ++++++++++++++++++++ homeassistant/components/velux.py | 69 +++++++++++++++++++++++++ requirements_all.txt | 3 ++ 4 files changed, 130 insertions(+) create mode 100644 homeassistant/components/scene/velux.py create mode 100644 homeassistant/components/velux.py diff --git a/.coveragerc b/.coveragerc index 67b1225797d..8d2c85627ed 100644 --- a/.coveragerc +++ b/.coveragerc @@ -170,6 +170,9 @@ omit = homeassistant/components/notify/twilio_sms.py homeassistant/components/notify/twilio_call.py + homeassistant/components/velux.py + homeassistant/components/*/velux.py + homeassistant/components/vera.py homeassistant/components/*/vera.py diff --git a/homeassistant/components/scene/velux.py b/homeassistant/components/scene/velux.py new file mode 100644 index 00000000000..0dca7ce76c7 --- /dev/null +++ b/homeassistant/components/scene/velux.py @@ -0,0 +1,55 @@ +""" +Support for VELUX scenes. + +Connects to VELUX KLF 200 interface + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/scene.velux/ +""" +from homeassistant.components.scene import Scene +from homeassistant.components.velux import _LOGGER, DATA_VELUX + + +DEPENDENCIES = ['velux'] + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Set up the scenes for velux platform.""" + if DATA_VELUX not in hass.data \ + or not hass.data[DATA_VELUX].initialized: + return False + + entities = [] + for scene in hass.data[DATA_VELUX].pyvlx.scenes: + entities.append(VeluxScene(hass, scene)) + add_devices(entities) + return True + + +class VeluxScene(Scene): + """Representation of a velux scene.""" + + def __init__(self, hass, scene): + """Init velux scene.""" + _LOGGER.info("Adding VELUX scene: %s", scene) + self.hass = hass + self.scene = scene + + @property + def name(self): + """Return the name of the scene.""" + return self.scene.name + + @property + def should_poll(self): + """Return that polling is not necessary.""" + return False + + @property + def is_on(self): + """There is no way of detecting if a scene is active (yet).""" + return False + + def activate(self, **kwargs): + """Activate the scene.""" + self.hass.async_add_job(self.scene.run()) diff --git a/homeassistant/components/velux.py b/homeassistant/components/velux.py new file mode 100644 index 00000000000..caf29d361dc --- /dev/null +++ b/homeassistant/components/velux.py @@ -0,0 +1,69 @@ +""" +Connects to VELUX KLF 200 interface. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/scene.velux/ + +""" + +import logging +import asyncio + +import voluptuous as vol + +from homeassistant.helpers import discovery +import homeassistant.helpers.config_validation as cv +from homeassistant.const import (CONF_HOST, CONF_PASSWORD) + +DOMAIN = "velux" +DATA_VELUX = "data_velux" +SUPPORTED_DOMAINS = ['scene'] +_LOGGER = logging.getLogger(__name__) + +REQUIREMENTS = ['pyvlx==0.1.3'] + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({ + vol.Required(CONF_HOST): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + }) +}, extra=vol.ALLOW_EXTRA) + + +@asyncio.coroutine +def async_setup(hass, config): + """Set up the velux component.""" + from pyvlx import PyVLXException + try: + hass.data[DATA_VELUX] = VeluxModule(hass, config) + yield from hass.data[DATA_VELUX].async_start() + + except PyVLXException as ex: + _LOGGER.exception("Can't connect to velux interface: %s", ex) + return False + + for component in SUPPORTED_DOMAINS: + hass.async_add_job( + discovery.async_load_platform(hass, component, DOMAIN, {}, config)) + return True + + +class VeluxModule: + """Abstraction for velux component.""" + + def __init__(self, hass, config): + """Initialize for velux component.""" + from pyvlx import PyVLX + self.initialized = False + host = config[DOMAIN].get(CONF_HOST) + password = config[DOMAIN].get(CONF_PASSWORD) + self.pyvlx = PyVLX( + host=host, + password=password) + self.hass = hass + + @asyncio.coroutine + def async_start(self): + """Start velux component.""" + yield from self.pyvlx.load_scenes() + self.initialized = True diff --git a/requirements_all.txt b/requirements_all.txt index 1257da77a10..cf950f03ab5 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -770,6 +770,9 @@ pyunifi==2.13 # homeassistant.components.vera pyvera==0.2.33 +# homeassistant.components.velux +pyvlx==0.1.3 + # homeassistant.components.notify.html5 pywebpush==1.0.5 From c5bf4fe3394a4dbbc86d74d32a5c8cad8aa2c089 Mon Sep 17 00:00:00 2001 From: Andrey Date: Sat, 8 Jul 2017 19:20:11 +0300 Subject: [PATCH 084/131] Properly handle the case when a group includes itself. (#8398) * Properly handle the case when a group includes itself. * Fix lint --- homeassistant/components/group.py | 8 +++-- tests/components/test_group.py | 58 +++++++++++++++++++------------ 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/homeassistant/components/group.py b/homeassistant/components/group.py index c628d04679f..d07e506e897 100644 --- a/homeassistant/components/group.py +++ b/homeassistant/components/group.py @@ -184,7 +184,6 @@ def expand_entity_ids(hass, entity_ids): Async friendly. """ found_ids = [] - for entity_id in entity_ids: if not isinstance(entity_id, str): continue @@ -196,9 +195,13 @@ def expand_entity_ids(hass, entity_ids): domain, _ = ha.split_entity_id(entity_id) if domain == DOMAIN: + child_entities = get_entity_ids(hass, entity_id) + if entity_id in child_entities: + child_entities = list(child_entities) + child_entities.remove(entity_id) found_ids.extend( ent_id for ent_id - in expand_entity_ids(hass, get_entity_ids(hass, entity_id)) + in expand_entity_ids(hass, child_entities) if ent_id not in found_ids) else: @@ -223,7 +226,6 @@ def get_entity_ids(hass, entity_id, domain_filter=None): return [] entity_ids = group.attributes[ATTR_ENTITY_ID] - if not domain_filter: return entity_ids diff --git a/tests/components/test_group.py b/tests/components/test_group.py index d94ccaa385c..7371ecf6e56 100644 --- a/tests/components/test_group.py +++ b/tests/components/test_group.py @@ -150,6 +150,20 @@ class TestComponentsGroup(unittest.TestCase): sorted(group.expand_entity_ids( self.hass, ['light.bowl', test_group.entity_id]))) + def test_expand_entity_ids_recursive(self): + """Test expand_entity_ids method with a group that contains itself.""" + self.hass.states.set('light.Bowl', STATE_ON) + self.hass.states.set('light.Ceiling', STATE_OFF) + test_group = group.Group.create_group( + self.hass, + 'init_group', + ['light.Bowl', 'light.Ceiling', 'group.init_group'], + False) + + self.assertEqual(sorted(['light.ceiling', 'light.bowl']), + sorted(group.expand_entity_ids( + self.hass, [test_group.entity_id]))) + def test_expand_entity_ids_ignores_non_strings(self): """Test that non string elements in lists are ignored.""" self.assertEqual([], group.expand_entity_ids(self.hass, [5, True])) @@ -226,11 +240,11 @@ class TestComponentsGroup(unittest.TestCase): group_conf = OrderedDict() group_conf['second_group'] = { - 'entities': 'light.Bowl, ' + test_group.entity_id, - 'icon': 'mdi:work', - 'view': True, - 'control': 'hidden', - } + 'entities': 'light.Bowl, ' + test_group.entity_id, + 'icon': 'mdi:work', + 'view': True, + 'control': 'hidden', + } group_conf['test_group'] = 'hello.world,sensor.happy' group_conf['empty_group'] = {'name': 'Empty Group', 'entities': None} @@ -275,8 +289,8 @@ class TestComponentsGroup(unittest.TestCase): self.hass, 'light', ['light.test_1', 'light.test_2']) group.Group.create_group( self.hass, 'switch', ['switch.test_1', 'switch.test_2']) - group.Group.create_group(self.hass, 'group_of_groups', ['group.light', - 'group.switch']) + group.Group.create_group( + self.hass, 'group_of_groups', ['group.light', 'group.switch']) self.assertEqual( ['light.test_1', 'light.test_2', 'switch.test_1', 'switch.test_2'], @@ -325,27 +339,26 @@ class TestComponentsGroup(unittest.TestCase): def test_reloading_groups(self): """Test reloading the group config.""" assert setup_component(self.hass, 'group', {'group': { - 'second_group': { - 'entities': 'light.Bowl', - 'icon': 'mdi:work', - 'view': True, - }, - 'test_group': 'hello.world,sensor.happy', - 'empty_group': {'name': 'Empty Group', 'entities': None}, - } - }) + 'second_group': { + 'entities': 'light.Bowl', + 'icon': 'mdi:work', + 'view': True, + }, + 'test_group': 'hello.world,sensor.happy', + 'empty_group': {'name': 'Empty Group', 'entities': None}, + }}) assert sorted(self.hass.states.entity_ids()) == \ ['group.empty_group', 'group.second_group', 'group.test_group'] assert self.hass.bus.listeners['state_changed'] == 3 with patch('homeassistant.config.load_yaml_config_file', return_value={ - 'group': { - 'hello': { - 'entities': 'light.Bowl', - 'icon': 'mdi:work', - 'view': True, - }}}): + 'group': { + 'hello': { + 'entities': 'light.Bowl', + 'icon': 'mdi:work', + 'view': True, + }}}): group.reload(self.hass) self.hass.block_till_done() @@ -395,6 +408,7 @@ def test_service_group_services(hass): assert hass.services.has_service('group', group.SERVICE_REMOVE) +# pylint: disable=invalid-name @asyncio.coroutine def test_service_group_set_group_remove_group(hass): """Check if service are available.""" From cb298123d400c8c7d4db26103a42aa4863a5a554 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sat, 8 Jul 2017 12:21:10 -0400 Subject: [PATCH 085/131] Add set_operation_mode support to generic_thermostat (#8392) This commit adds support for the set_operation_mode system call to the generic thermostat component. This enables users to set whether the thermostat is enabled or not by either setting it to auto or off. --- .../components/climate/generic_thermostat.py | 28 +++++++++- .../climate/test_generic_thermostat.py | 54 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/climate/generic_thermostat.py b/homeassistant/components/climate/generic_thermostat.py index 6e7ba3cffed..9442b7da194 100644 --- a/homeassistant/components/climate/generic_thermostat.py +++ b/homeassistant/components/climate/generic_thermostat.py @@ -12,7 +12,8 @@ import voluptuous as vol from homeassistant.core import callback from homeassistant.components import switch from homeassistant.components.climate import ( - STATE_HEAT, STATE_COOL, STATE_IDLE, ClimateDevice, PLATFORM_SCHEMA) + STATE_HEAT, STATE_COOL, STATE_IDLE, ClimateDevice, PLATFORM_SCHEMA, + STATE_AUTO) from homeassistant.const import ( ATTR_UNIT_OF_MEASUREMENT, STATE_ON, STATE_OFF, ATTR_TEMPERATURE, CONF_NAME) @@ -87,6 +88,7 @@ class GenericThermostat(ClimateDevice): self.min_cycle_duration = min_cycle_duration self._tolerance = tolerance self._keep_alive = keep_alive + self._enabled = True self._active = False self._cur_temp = None @@ -131,6 +133,8 @@ class GenericThermostat(ClimateDevice): @property def current_operation(self): """Return current operation ie. heat, cool, idle.""" + if not self._enabled: + return STATE_OFF if self.ac_mode: cooling = self._active and self._is_device_active return STATE_COOL if cooling else STATE_IDLE @@ -143,6 +147,25 @@ class GenericThermostat(ClimateDevice): """Return the temperature we try to reach.""" return self._target_temp + @property + def operation_list(self): + """List of available operation modes.""" + return [STATE_AUTO, STATE_OFF] + + def set_operation_mode(self, operation_mode): + """Set operation mode.""" + if operation_mode == STATE_AUTO: + self._enabled = True + elif operation_mode == STATE_OFF: + self._enabled = False + if self._is_device_active: + switch.async_turn_off(self.hass, self.heater_entity_id) + else: + _LOGGER.error('Unrecognized operation mode: %s', operation_mode) + return + # Ensure we updae the current operation after changing the mode + self.schedule_update_ha_state() + @asyncio.coroutine def async_set_temperature(self, **kwargs): """Set new target temperature.""" @@ -221,6 +244,9 @@ class GenericThermostat(ClimateDevice): if not self._active: return + if not self._enabled: + return + if self.min_cycle_duration: if self._is_device_active: current_state = STATE_ON diff --git a/tests/components/climate/test_generic_thermostat.py b/tests/components/climate/test_generic_thermostat.py index 16dbe5ae895..15fc3f6a982 100644 --- a/tests/components/climate/test_generic_thermostat.py +++ b/tests/components/climate/test_generic_thermostat.py @@ -108,6 +108,12 @@ class TestClimateGenericThermostat(unittest.TestCase): self.assertEqual(35, state.attributes.get('max_temp')) self.assertEqual(None, state.attributes.get('temperature')) + def test_get_operation_modes(self): + """Test that the operation list returns the correct modes.""" + state = self.hass.states.get(ENTITY) + modes = state.attributes.get('operation_list') + self.assertEqual([climate.STATE_AUTO, STATE_OFF], modes) + def test_set_target_temp(self): """Test the setting of the target temperature.""" climate.set_temperature(self.hass, 30) @@ -211,6 +217,30 @@ class TestClimateGenericThermostat(unittest.TestCase): self.assertEqual(SERVICE_TURN_OFF, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) + def test_running_when_operating_mode_is_off(self): + """Test that the switch turns off when enabled is set False.""" + self._setup_switch(True) + climate.set_temperature(self.hass, 30) + self.hass.block_till_done() + climate.set_operation_mode(self.hass, STATE_OFF) + self.hass.block_till_done() + self.assertEqual(1, len(self.calls)) + call = self.calls[0] + self.assertEqual('switch', call.domain) + self.assertEqual(SERVICE_TURN_OFF, call.service) + self.assertEqual(ENT_SWITCH, call.data['entity_id']) + + def test_no_state_change_when_operation_mode_off(self): + """Test that the switch doesn't turn on when enabled is False.""" + self._setup_switch(False) + climate.set_temperature(self.hass, 30) + self.hass.block_till_done() + climate.set_operation_mode(self.hass, STATE_OFF) + self.hass.block_till_done() + self._setup_sensor(25) + self.hass.block_till_done() + self.assertEqual(0, len(self.calls)) + def _setup_sensor(self, temp, unit=TEMP_CELSIUS): """Setup the test sensor.""" self.hass.states.set(ENT_SENSOR, temp, { @@ -321,6 +351,30 @@ class TestClimateGenericThermostatACMode(unittest.TestCase): self.assertEqual(SERVICE_TURN_ON, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) + def test_running_when_operating_mode_is_off(self): + """Test that the switch turns off when enabled is set False.""" + self._setup_switch(True) + climate.set_temperature(self.hass, 30) + self.hass.block_till_done() + climate.set_operation_mode(self.hass, STATE_OFF) + self.hass.block_till_done() + self.assertEqual(1, len(self.calls)) + call = self.calls[0] + self.assertEqual('switch', call.domain) + self.assertEqual(SERVICE_TURN_OFF, call.service) + self.assertEqual(ENT_SWITCH, call.data['entity_id']) + + def test_no_state_change_when_operation_mode_off(self): + """Test that the switch doesn't turn on when enabled is False.""" + self._setup_switch(False) + climate.set_temperature(self.hass, 30) + self.hass.block_till_done() + climate.set_operation_mode(self.hass, STATE_OFF) + self.hass.block_till_done() + self._setup_sensor(35) + self.hass.block_till_done() + self.assertEqual(0, len(self.calls)) + def _setup_sensor(self, temp, unit=TEMP_CELSIUS): """Setup the test sensor.""" self.hass.states.set(ENT_SENSOR, temp, { From ec7ca9a560a9c8f8adcabc79b597deb2ec61fa68 Mon Sep 17 00:00:00 2001 From: Adam Mills Date: Sun, 9 Jul 2017 16:21:17 -0400 Subject: [PATCH 086/131] Make gzips reproducible by excluding timestamp (#8420) --- script/build_frontend | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/build_frontend b/script/build_frontend index a81d3ca9eb0..f687c10a31c 100755 --- a/script/build_frontend +++ b/script/build_frontend @@ -24,7 +24,7 @@ cp build/service_worker.js .. cd .. # Pack frontend -gzip -f -k -9 *.html *.js ./panels/*.html +gzip -f -n -k -9 *.html *.js ./panels/*.html cd ../../../.. # Generate the MD5 hash of the new frontend From 2ac423bd9d464d705e4375981de39afdf4d1df8d Mon Sep 17 00:00:00 2001 From: James Marsh Date: Sun, 9 Jul 2017 23:06:31 +0100 Subject: [PATCH 087/131] Do not overwrite a custom hyperion light name with the hostname of the server. (#8391) Do not overwrite a custom name with the hostname of the hyperion server. Correct comment in name() method. Fixes #8390 --- homeassistant/components/light/hyperion.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/light/hyperion.py b/homeassistant/components/light/hyperion.py index 99fc557af20..ec91ba582fb 100644 --- a/homeassistant/components/light/hyperion.py +++ b/homeassistant/components/light/hyperion.py @@ -62,7 +62,7 @@ class Hyperion(Light): @property def name(self): - """Return the hostname of the server.""" + """Return the name of the light.""" return self._name @property @@ -114,7 +114,8 @@ class Hyperion(Light): """Get the hostname of the remote.""" response = self.json_request({'command': 'serverinfo'}) if response: - self._name = response['info']['hostname'] + if self._name == self._host: + self._name = response['info']['hostname'] return True return False From e7b5c5812cfa0e5774dbf82395a977f04c4043b7 Mon Sep 17 00:00:00 2001 From: Julius Mittenzwei Date: Mon, 10 Jul 2017 12:11:16 +0200 Subject: [PATCH 088/131] Fixed link to documentation (#8424) * Issue #8203: fixed link to documentation * Revert URL change * Minor changes to docstring --- homeassistant/components/scene/velux.py | 2 -- homeassistant/components/velux.py | 6 ++---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/scene/velux.py b/homeassistant/components/scene/velux.py index 0dca7ce76c7..9da7a662117 100644 --- a/homeassistant/components/scene/velux.py +++ b/homeassistant/components/scene/velux.py @@ -1,8 +1,6 @@ """ Support for VELUX scenes. -Connects to VELUX KLF 200 interface - For more details about this platform, please refer to the documentation at https://home-assistant.io/components/scene.velux/ """ diff --git a/homeassistant/components/velux.py b/homeassistant/components/velux.py index caf29d361dc..b0c902aa83e 100644 --- a/homeassistant/components/velux.py +++ b/homeassistant/components/velux.py @@ -1,11 +1,9 @@ """ Connects to VELUX KLF 200 interface. -For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/scene.velux/ - +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/velux/ """ - import logging import asyncio From 4fb25cf16d08c80ccda52519c90a9b9c4dfb9a00 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Mon, 10 Jul 2017 23:15:59 +0200 Subject: [PATCH 089/131] Fix KeyError (fixes #3721, fixes #7241) (#8428) --- homeassistant/components/sensor/uber.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/sensor/uber.py b/homeassistant/components/sensor/uber.py index 42d6cad43f2..eb671bf2fce 100644 --- a/homeassistant/components/sensor/uber.py +++ b/homeassistant/components/sensor/uber.py @@ -9,10 +9,10 @@ from datetime import timedelta import voluptuous as vol +import homeassistant.helpers.config_validation as cv from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.helpers.entity import Entity from homeassistant.util import Throttle -import homeassistant.helpers.config_validation as cv REQUIREMENTS = ['uber_rides==0.4.1'] @@ -35,8 +35,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_START_LONGITUDE): cv.longitude, vol.Optional(CONF_END_LATITUDE): cv.latitude, vol.Optional(CONF_END_LONGITUDE): cv.longitude, - vol.Optional(CONF_PRODUCT_IDS): - vol.All(cv.ensure_list, [cv.string]), + vol.Optional(CONF_PRODUCT_IDS): vol.All(cv.ensure_list, [cv.string]), }) @@ -57,11 +56,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None): (product_id not in wanted_product_ids): continue dev.append(UberSensor('time', timeandpriceest, product_id, product)) - if (product.get('price_details') is not None) and \ - product['price_details']['estimate'] != 'Metered': + if product.get('price_details') is not None: dev.append(UberSensor( 'price', timeandpriceest, product_id, product)) - add_devices(dev) + + add_devices(dev, True) class UberSensor(Entity): @@ -73,8 +72,8 @@ class UberSensor(Entity): self._product_id = product_id self._product = product self._sensortype = sensorType - self._name = '{} {}'.format(self._product['display_name'], - self._sensortype) + self._name = '{} {}'.format( + self._product['display_name'], self._sensortype) if self._sensortype == 'time': self._unit_of_measurement = 'min' time_estimate = self._product.get('time_estimate_seconds', 0) @@ -90,7 +89,6 @@ class UberSensor(Entity): self._state = int(price_details.get(statekey, 0)) else: self._state = 0 - self.update() @property def name(self): @@ -214,8 +212,8 @@ class UberEstimate(object): if product.get('price_details') is None: price_details = {} price_details['estimate'] = price.get('estimate', '0') - price_details['high_estimate'] = price.get('high_estimate', - '0') + price_details['high_estimate'] = price.get( + 'high_estimate', '0') price_details['low_estimate'] = price.get('low_estimate', '0') price_details['currency_code'] = price.get('currency_code') surge_multiplier = price.get('surge_multiplier', '0') From 97f14015ea4b3af792e5cea3733d997ad0c88c4a Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Mon, 10 Jul 2017 23:16:37 +0200 Subject: [PATCH 090/131] Use HA lat/long for the start (fixes #3971) (#8429) --- homeassistant/components/sensor/uber.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/sensor/uber.py b/homeassistant/components/sensor/uber.py index eb671bf2fce..a971ca94287 100644 --- a/homeassistant/components/sensor/uber.py +++ b/homeassistant/components/sensor/uber.py @@ -31,8 +31,8 @@ MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_SERVER_TOKEN): cv.string, - vol.Required(CONF_START_LATITUDE): cv.latitude, - vol.Required(CONF_START_LONGITUDE): cv.longitude, + vol.Optional(CONF_START_LATITUDE): cv.latitude, + vol.Optional(CONF_START_LONGITUDE): cv.longitude, vol.Optional(CONF_END_LATITUDE): cv.latitude, vol.Optional(CONF_END_LONGITUDE): cv.longitude, vol.Optional(CONF_PRODUCT_IDS): vol.All(cv.ensure_list, [cv.string]), @@ -44,13 +44,16 @@ def setup_platform(hass, config, add_devices, discovery_info=None): from uber_rides.session import Session session = Session(server_token=config.get(CONF_SERVER_TOKEN)) - + start_latitude = config.get(CONF_START_LATITUDE, hass.config.latitude) + start_longitude = config.get(CONF_START_LONGITUDE, hass.config.longitude) + end_latitude = config.get(CONF_END_LATITUDE) + end_longitude = config.get(CONF_END_LONGITUDE) wanted_product_ids = config.get(CONF_PRODUCT_IDS) dev = [] timeandpriceest = UberEstimate( - session, config[CONF_START_LATITUDE], config[CONF_START_LONGITUDE], - config.get(CONF_END_LATITUDE), config.get(CONF_END_LONGITUDE)) + session, start_latitude, start_longitude, end_latitude, end_longitude) + for product_id, product in timeandpriceest.products.items(): if (wanted_product_ids is not None) and \ (product_id not in wanted_product_ids): From b453834b2fc474bc3438ec670098ef50ac3a5cfc Mon Sep 17 00:00:00 2001 From: Teemu R Date: Mon, 10 Jul 2017 23:18:58 +0200 Subject: [PATCH 091/131] bump python-mirobo requirement to support newer firmwares and more (#8431) --- homeassistant/components/switch/xiaomi_vacuum.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/switch/xiaomi_vacuum.py b/homeassistant/components/switch/xiaomi_vacuum.py index cf18a673ccb..20906dd8df1 100644 --- a/homeassistant/components/switch/xiaomi_vacuum.py +++ b/homeassistant/components/switch/xiaomi_vacuum.py @@ -22,7 +22,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_NAME): cv.string, }) -REQUIREMENTS = ['python-mirobo==0.0.8'] +REQUIREMENTS = ['python-mirobo==0.1.1'] # pylint: disable=unused-argument diff --git a/requirements_all.txt b/requirements_all.txt index cf950f03ab5..f37c5f5b48a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -710,7 +710,7 @@ python-juicenet==0.0.5 # python-lirc==1.2.3 # homeassistant.components.switch.xiaomi_vacuum -python-mirobo==0.0.8 +python-mirobo==0.1.1 # homeassistant.components.media_player.mpd python-mpd2==0.5.5 From 821d01f82c01f453b5a9b3e2855cbbc2eb778b20 Mon Sep 17 00:00:00 2001 From: Eugenio Panadero Date: Tue, 11 Jul 2017 03:37:51 +0200 Subject: [PATCH 092/131] New service `send_magic_packet` with new component `wake_on_lan` (#8397) * New service `send_magic_packet` in new component `wake_on_lan` * fix * Unit tests for new component wake_on_lan * Add wakeonlan to tests requirements * remove wakeonlan from tests requirements and remake the component tests * remove wakeonlan from tests requirements * link domain and service names to component * fix mocking in test_setup_component * send_magic_packet as coroutine, better use of mock_calls in tests * fix imports * review changes * better async calls * Update test_wake_on_lan.py --- homeassistant/components/services.yaml | 12 +++++ homeassistant/components/wake_on_lan.py | 62 +++++++++++++++++++++++++ requirements_all.txt | 1 + tests/components/test_wake_on_lan.py | 47 +++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 homeassistant/components/wake_on_lan.py create mode 100644 tests/components/test_wake_on_lan.py diff --git a/homeassistant/components/services.yaml b/homeassistant/components/services.yaml index 97e947fff06..eefcff5bd17 100644 --- a/homeassistant/components/services.yaml +++ b/homeassistant/components/services.yaml @@ -508,3 +508,15 @@ modbus: state: description: State to write example: false + +wake_on_lan: + send_magic_packet: + description: Send a 'magic packet' to wake up a device with 'Wake-On-LAN' capabilities. + + fields: + mac: + description: MAC address of the device to wake up. + example: 'aa:bb:cc:dd:ee:ff' + broadcast_address: + description: Optional broadcast IP where to send the magic packet. + example: '192.168.255.255' diff --git a/homeassistant/components/wake_on_lan.py b/homeassistant/components/wake_on_lan.py new file mode 100644 index 00000000000..ab72aa989d7 --- /dev/null +++ b/homeassistant/components/wake_on_lan.py @@ -0,0 +1,62 @@ +""" +Component to wake up devices sending Wake-On-LAN magic packets. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/wake_on_lan/ +""" +import asyncio +from functools import partial +import logging +import os + +import voluptuous as vol + +from homeassistant.config import load_yaml_config_file +from homeassistant.const import CONF_MAC +import homeassistant.helpers.config_validation as cv + +REQUIREMENTS = ['wakeonlan==0.2.2'] + +DOMAIN = "wake_on_lan" +_LOGGER = logging.getLogger(__name__) + +CONF_BROADCAST_ADDRESS = 'broadcast_address' + +SERVICE_SEND_MAGIC_PACKET = 'send_magic_packet' + +WAKE_ON_LAN_SEND_MAGIC_PACKET_SCHEMA = vol.Schema({ + vol.Required(CONF_MAC): cv.string, + vol.Optional(CONF_BROADCAST_ADDRESS): cv.string, +}) + + +@asyncio.coroutine +def async_setup(hass, config): + """Set up the wake on LAN component.""" + from wakeonlan import wol + + @asyncio.coroutine + def send_magic_packet(call): + """Send magic packet to wake up a device.""" + mac_address = call.data.get(CONF_MAC) + broadcast_address = call.data.get(CONF_BROADCAST_ADDRESS) + _LOGGER.info("Send magic packet to mac %s (broadcast: %s)", + mac_address, broadcast_address) + if broadcast_address is not None: + yield from hass.async_add_job( + partial(wol.send_magic_packet, mac_address, + ip_address=broadcast_address)) + else: + yield from hass.async_add_job( + partial(wol.send_magic_packet, mac_address)) + + descriptions = yield from hass.async_add_job( + load_yaml_config_file, os.path.join( + os.path.dirname(__file__), 'services.yaml')) + + hass.services.async_register( + DOMAIN, SERVICE_SEND_MAGIC_PACKET, send_magic_packet, + description=descriptions.get(DOMAIN).get(SERVICE_SEND_MAGIC_PACKET), + schema=WAKE_ON_LAN_SEND_MAGIC_PACKET_SCHEMA) + + return True diff --git a/requirements_all.txt b/requirements_all.txt index f37c5f5b48a..d4e3add1774 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -918,6 +918,7 @@ vsure==1.3.7 # homeassistant.components.sensor.vasttrafik vtjp==0.1.14 +# homeassistant.components.wake_on_lan # homeassistant.components.media_player.panasonic_viera # homeassistant.components.media_player.samsungtv # homeassistant.components.media_player.webostv diff --git a/tests/components/test_wake_on_lan.py b/tests/components/test_wake_on_lan.py new file mode 100644 index 00000000000..abaf7dd6d14 --- /dev/null +++ b/tests/components/test_wake_on_lan.py @@ -0,0 +1,47 @@ +"""Tests for Wake On LAN component.""" +import asyncio +from unittest import mock + +import pytest + +from homeassistant.setup import async_setup_component +from homeassistant.components.wake_on_lan import ( + DOMAIN, SERVICE_SEND_MAGIC_PACKET) + + +@pytest.fixture +def mock_wakeonlan(): + """Mock mock_wakeonlan.""" + module = mock.MagicMock() + with mock.patch.dict('sys.modules', { + 'wakeonlan': module, + }): + yield module + + +@asyncio.coroutine +def test_send_magic_packet(hass, caplog, mock_wakeonlan): + """Test of send magic packet service call.""" + mac = "aa:bb:cc:dd:ee:ff" + bc_ip = "192.168.255.255" + + yield from async_setup_component(hass, DOMAIN, {}) + + yield from hass.services.async_call( + DOMAIN, SERVICE_SEND_MAGIC_PACKET, + {"mac": mac, "broadcast_address": bc_ip}, blocking=True) + assert len(mock_wakeonlan.mock_calls) == 1 + assert mock_wakeonlan.mock_calls[-1][1][0] == mac + assert mock_wakeonlan.mock_calls[-1][2]['ip_address'] == bc_ip + + yield from hass.services.async_call( + DOMAIN, SERVICE_SEND_MAGIC_PACKET, + {"broadcast_address": bc_ip}, blocking=True) + assert 'ERROR' in caplog.text + assert len(mock_wakeonlan.mock_calls) == 1 + + yield from hass.services.async_call( + DOMAIN, SERVICE_SEND_MAGIC_PACKET, {"mac": mac}, blocking=True) + assert len(mock_wakeonlan.mock_calls) == 2 + assert mock_wakeonlan.mock_calls[-1][1][0] == mac + assert not mock_wakeonlan.mock_calls[-1][2] From fe4abc845469c9b6cf194f16de26495e5298df02 Mon Sep 17 00:00:00 2001 From: Open Home Automation Date: Tue, 11 Jul 2017 03:42:42 +0200 Subject: [PATCH 093/131] Integrate utility functions into restricted Python environment (#8427) --- homeassistant/components/python_script.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/python_script.py b/homeassistant/components/python_script.py index cfb7098bbdf..c159bec0f75 100644 --- a/homeassistant/components/python_script.py +++ b/homeassistant/components/python_script.py @@ -61,6 +61,7 @@ def execute(hass, filename, source, data=None): """Execute Python source.""" from RestrictedPython import compile_restricted_exec from RestrictedPython.Guards import safe_builtins, full_write_guard + from RestrictedPython.Utilities import utility_builtins compiled = compile_restricted_exec(source, filename=filename) @@ -87,8 +88,10 @@ def execute(hass, filename, source, data=None): return getattr(obj, name, default) + builtins = safe_builtins.copy() + builtins.update(utility_builtins) restricted_globals = { - '__builtins__': safe_builtins, + '__builtins__': builtins, '_print_': StubPrinter, '_getattr_': protected_getattr, '_write_': full_write_guard, From 92dc76773af08f84806611444210c6ea91dc5030 Mon Sep 17 00:00:00 2001 From: Mike Christianson Date: Mon, 10 Jul 2017 19:58:01 -0700 Subject: [PATCH 094/131] Allow Twitter notifications to include media (#8282) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Allow notifications to include media, with Twitter as the first implementation. The Twitter notifier uses the Twitter-recommended async chunked media/upload approach and tries to convey the correct mime type of the media. Twitter implementation based on https://github.com/geduldig/TwitterAPI/blob/master/examples/upload_video.py. * Changes based on balloob's review: balloob: "Please remove this file. We fixed the issue in our tests that left this artifact." balloob: "…prefer a guard clause" balloob: "This is very inefficient. You are now generating up to 99 values." balloob: "Since media_id is going to be None, why not just return None and you can remove the else." * balloob: "Other notify platforms are using ATTR_DATA for it. That way if a platform requires extra metadata, we don't need to add extra fields. So please add it to Twitter via ATTR_DATA." --- homeassistant/components/notify/twitter.py | 117 ++++++++++++++++++--- 1 file changed, 105 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/notify/twitter.py b/homeassistant/components/notify/twitter.py index 4bbe8a5d9e1..6d74f86132a 100644 --- a/homeassistant/components/notify/twitter.py +++ b/homeassistant/components/notify/twitter.py @@ -4,13 +4,16 @@ Twitter platform for notify component. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/notify.twitter/ """ +import json import logging +import mimetypes +import os import voluptuous as vol import homeassistant.helpers.config_validation as cv from homeassistant.components.notify import ( - PLATFORM_SCHEMA, BaseNotificationService) + ATTR_DATA, PLATFORM_SCHEMA, BaseNotificationService) from homeassistant.const import CONF_ACCESS_TOKEN, CONF_USERNAME REQUIREMENTS = ['TwitterAPI==2.4.5'] @@ -21,6 +24,8 @@ CONF_CONSUMER_KEY = 'consumer_key' CONF_CONSUMER_SECRET = 'consumer_secret' CONF_ACCESS_TOKEN_SECRET = 'access_token_secret' +ATTR_MEDIA = 'media' + PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_ACCESS_TOKEN): cv.string, vol.Required(CONF_ACCESS_TOKEN_SECRET): cv.string, @@ -33,6 +38,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ def get_service(hass, config, discovery_info=None): """Get the Twitter notification service.""" return TwitterNotificationService( + hass, config[CONF_CONSUMER_KEY], config[CONF_CONSUMER_SECRET], config[CONF_ACCESS_TOKEN], config[CONF_ACCESS_TOKEN_SECRET], config.get(CONF_USERNAME) @@ -42,26 +48,113 @@ def get_service(hass, config, discovery_info=None): class TwitterNotificationService(BaseNotificationService): """Implementation of a notification service for the Twitter service.""" - def __init__(self, consumer_key, consumer_secret, access_token_key, + def __init__(self, hass, consumer_key, consumer_secret, access_token_key, access_token_secret, username): """Initialize the service.""" from TwitterAPI import TwitterAPI self.user = username + self.hass = hass self.api = TwitterAPI(consumer_key, consumer_secret, access_token_key, access_token_secret) def send_message(self, message="", **kwargs): - """Tweet a message.""" + """Tweet a message, optionally with media.""" + data = kwargs.get(ATTR_DATA) + media = data.get(ATTR_MEDIA) + if not self.hass.config.is_allowed_path(media): + _LOGGER.warning("'%s' is not in a whitelisted area.", media) + return + + media_id = self.upload_media(media) + if self.user: - resp = self.api.request( - 'direct_messages/new', {'text': message, 'user': self.user}) + resp = self.api.request('direct_messages/new', + {'text': message, 'user': self.user, + 'media_ids': media_id}) else: - resp = self.api.request('statuses/update', {'status': message}) + resp = self.api.request('statuses/update', + {'status': message, 'media_ids': media_id}) if resp.status_code != 200: - import json - obj = json.loads(resp.text) - error_message = obj['errors'][0]['message'] - error_code = obj['errors'][0]['code'] - _LOGGER.error("Error %s : %s (Code %s)", resp.status_code, - error_message, error_code) + self.log_error_resp(resp) + + def upload_media(self, media_path=None): + """Upload media.""" + if not media_path: + return None + + (media_type, _) = mimetypes.guess_type(media_path) + total_bytes = os.path.getsize(media_path) + + file = open(media_path, 'rb') + resp = self.upload_media_init(media_type, total_bytes) + + if 199 > resp.status_code < 300: + self.log_error_resp(resp) + return None + + media_id = resp.json()['media_id'] + media_id = self.upload_media_chunked(file, total_bytes, + media_id) + + resp = self.upload_media_finalize(media_id) + if 199 > resp.status_code < 300: + self.log_error_resp(resp) + + return media_id + + def upload_media_init(self, media_type, total_bytes): + """Upload media, INIT phase.""" + resp = self.api.request('media/upload', + {'command': 'INIT', 'media_type': media_type, + 'total_bytes': total_bytes}) + return resp + + def upload_media_chunked(self, file, total_bytes, media_id): + """Upload media, chunked append.""" + segment_id = 0 + bytes_sent = 0 + while bytes_sent < total_bytes: + chunk = file.read(4 * 1024 * 1024) + resp = self.upload_media_append(chunk, media_id, segment_id) + if resp.status_code not in range(200, 299): + self.log_error_resp_append(resp) + return None + segment_id = segment_id + 1 + bytes_sent = file.tell() + self.log_bytes_sent(bytes_sent, total_bytes) + return media_id + + def upload_media_append(self, chunk, media_id, segment_id): + """Upload media, append phase.""" + return self.api.request('media/upload', + {'command': 'APPEND', 'media_id': media_id, + 'segment_index': segment_id}, + {'media': chunk}) + + def upload_media_finalize(self, media_id): + """Upload media, finalize phase.""" + return self.api.request('media/upload', + {'command': 'FINALIZE', 'media_id': media_id}) + + @staticmethod + def log_bytes_sent(bytes_sent, total_bytes): + """Log upload progress.""" + _LOGGER.debug("%s of %s bytes uploaded", str(bytes_sent), + str(total_bytes)) + + @staticmethod + def log_error_resp(resp): + """Log error response.""" + obj = json.loads(resp.text) + error_message = obj['error'] + _LOGGER.error("Error %s : %s", resp.status_code, error_message) + + @staticmethod + def log_error_resp_append(resp): + """Log error response, during upload append phase.""" + obj = json.loads(resp.text) + error_message = obj['errors'][0]['message'] + error_code = obj['errors'][0]['code'] + _LOGGER.error("Error %s : %s (Code %s)", resp.status_code, + error_message, error_code) From 7a4cc8e082405fbbeaca31b6abac3e4a0441b16f Mon Sep 17 00:00:00 2001 From: thecynic Date: Mon, 10 Jul 2017 20:52:37 -0700 Subject: [PATCH 095/131] Fix typo (sending USERNAME instead of PASSWORD) introduced in #7963 (#8433) --- homeassistant/components/lutron.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/lutron.py b/homeassistant/components/lutron.py index d9b943762dc..819844325d1 100644 --- a/homeassistant/components/lutron.py +++ b/homeassistant/components/lutron.py @@ -41,7 +41,7 @@ def setup(hass, base_config): config = base_config.get(DOMAIN) hass.data[LUTRON_CONTROLLER] = Lutron( - config[CONF_HOST], config[CONF_USERNAME], config[CONF_USERNAME]) + config[CONF_HOST], config[CONF_USERNAME], config[CONF_PASSWORD]) hass.data[LUTRON_CONTROLLER].load_xml_db() hass.data[LUTRON_CONTROLLER].connect() From 2f474a0ed8350885d3761b4fe4d7e7e3c4aeb7b2 Mon Sep 17 00:00:00 2001 From: Russell Cloran Date: Mon, 10 Jul 2017 21:16:44 -0700 Subject: [PATCH 096/131] zha: Handle both input and output clusters (#8410) bellows 0.3.0 changes the API to have both, renaming the attribute which used to be for input clusters in the process. This is in preparation for remotes. --- homeassistant/components/binary_sensor/zha.py | 6 +-- homeassistant/components/light/zha.py | 4 +- homeassistant/components/sensor/zha.py | 9 ++-- homeassistant/components/zha/__init__.py | 44 ++++++++++++------- homeassistant/components/zha/const.py | 5 ++- requirements_all.txt | 2 +- 6 files changed, 42 insertions(+), 28 deletions(-) diff --git a/homeassistant/components/binary_sensor/zha.py b/homeassistant/components/binary_sensor/zha.py index 1d895fbf3a7..ad7c29badf9 100644 --- a/homeassistant/components/binary_sensor/zha.py +++ b/homeassistant/components/binary_sensor/zha.py @@ -34,10 +34,10 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): from bellows.zigbee.zcl.clusters.security import IasZone - clusters = discovery_info['clusters'] + in_clusters = discovery_info['in_clusters'] device_class = None - cluster = [c for c in clusters if isinstance(c, IasZone)][0] + cluster = in_clusters[IasZone.cluster_id] if discovery_info['new_join']: yield from cluster.bind() ieee = cluster.endpoint.device.application.ieee @@ -64,7 +64,7 @@ class BinarySensor(zha.Entity, BinarySensorDevice): super().__init__(**kwargs) self._device_class = device_class from bellows.zigbee.zcl.clusters.security import IasZone - self._ias_zone_cluster = self._clusters[IasZone.cluster_id] + self._ias_zone_cluster = self._in_clusters[IasZone.cluster_id] @property def is_on(self) -> bool: diff --git a/homeassistant/components/light/zha.py b/homeassistant/components/light/zha.py index 650d9f909b1..619723d3168 100644 --- a/homeassistant/components/light/zha.py +++ b/homeassistant/components/light/zha.py @@ -46,10 +46,10 @@ class Light(zha.Entity, light.Light): self._brightness = None import bellows.zigbee.zcl.clusters as zcl_clusters - if zcl_clusters.general.LevelControl.cluster_id in self._clusters: + if zcl_clusters.general.LevelControl.cluster_id in self._in_clusters: self._supported_features |= light.SUPPORT_BRIGHTNESS self._brightness = 0 - if zcl_clusters.lighting.Color.cluster_id in self._clusters: + if zcl_clusters.lighting.Color.cluster_id in self._in_clusters: # Not sure all color lights necessarily support this directly # Should we emulate it? self._supported_features |= light.SUPPORT_COLOR_TEMP diff --git a/homeassistant/components/sensor/zha.py b/homeassistant/components/sensor/zha.py index 7ac76a35b79..ca4ab6bbff3 100644 --- a/homeassistant/components/sensor/zha.py +++ b/homeassistant/components/sensor/zha.py @@ -31,17 +31,16 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): @asyncio.coroutine def make_sensor(discovery_info): """Create ZHA sensors factory.""" - from bellows.zigbee import zcl - if isinstance(discovery_info['clusters'][0], - zcl.clusters.measurement.TemperatureMeasurement): + from bellows.zigbee.zcl.clusters.measurement import TemperatureMeasurement + in_clusters = discovery_info['in_clusters'] + if TemperatureMeasurement.cluster_id in in_clusters: sensor = TemperatureSensor(**discovery_info) else: sensor = Sensor(**discovery_info) - clusters = discovery_info['clusters'] attr = sensor.value_attribute if discovery_info['new_join']: - cluster = clusters[0] + cluster = list(in_clusters.values())[0] yield from cluster.bind() yield from cluster.configure_reporting( attr, 300, 600, sensor.min_reportable_change, diff --git a/homeassistant/components/zha/__init__.py b/homeassistant/components/zha/__init__.py index 5937f1865f5..e397b7d042a 100644 --- a/homeassistant/components/zha/__init__.py +++ b/homeassistant/components/zha/__init__.py @@ -14,7 +14,7 @@ from homeassistant import const as ha_const from homeassistant.helpers import discovery, entity from homeassistant.util import slugify -REQUIREMENTS = ['bellows==0.2.7'] +REQUIREMENTS = ['bellows==0.3.2'] DOMAIN = 'zha' @@ -128,6 +128,10 @@ class ApplicationListener: """Handle device joined and basic information discovered.""" self._hass.async_add_job(self.async_device_initialized(device, True)) + def device_left(self, device): + """Handle device leaving the network.""" + pass + @asyncio.coroutine def async_device_initialized(self, device, join): """Handle device joined and basic information discovered (async).""" @@ -142,7 +146,7 @@ class ApplicationListener: discovered_info = yield from _discover_endpoint_info(endpoint) component = None - used_clusters = [] + profile_clusters = ([], []) device_key = '%s-%s' % (str(device.ieee), endpoint_id) node_config = self._config[DOMAIN][CONF_DEVICE_CONFIG].get( device_key, {}) @@ -152,20 +156,25 @@ class ApplicationListener: if zha_const.DEVICE_CLASS.get(endpoint.profile_id, {}).get(endpoint.device_type, None): - used_clusters = profile.CLUSTERS[endpoint.device_type] + profile_clusters = profile.CLUSTERS[endpoint.device_type] profile_info = zha_const.DEVICE_CLASS[endpoint.profile_id] component = profile_info[endpoint.device_type] if ha_const.CONF_TYPE in node_config: component = node_config[ha_const.CONF_TYPE] - used_clusters = zha_const.COMPONENT_CLUSTERS[component] + profile_clusters = zha_const.COMPONENT_CLUSTERS[component] if component: - clusters = [endpoint.clusters[c] for c in used_clusters if c in - endpoint.clusters] + in_clusters = [endpoint.in_clusters[c] + for c in profile_clusters[0] + if c in endpoint.in_clusters] + out_clusters = [endpoint.out_clusters[c] + for c in profile_clusters[1] + if c in endpoint.out_clusters] discovery_info = { 'endpoint': endpoint, - 'clusters': clusters, + 'in_clusters': {c.cluster_id: c for c in in_clusters}, + 'out_clusters': {c.cluster_id: c for c in out_clusters}, 'new_join': join, } discovery_info.update(discovered_info) @@ -179,9 +188,9 @@ class ApplicationListener: self._config, ) - for cluster_id, cluster in endpoint.clusters.items(): + for cluster_id, cluster in endpoint.in_clusters.items(): cluster_type = type(cluster) - if cluster_id in used_clusters: + if cluster_id in profile_clusters[0]: continue if cluster_type not in zha_const.SINGLE_CLUSTER_DEVICE_CLASS: continue @@ -189,7 +198,8 @@ class ApplicationListener: component = zha_const.SINGLE_CLUSTER_DEVICE_CLASS[cluster_type] discovery_info = { 'endpoint': endpoint, - 'clusters': [cluster], + 'in_clusters': {cluster.cluster_id: cluster}, + 'out_clusters': {}, 'new_join': join, } discovery_info.update(discovered_info) @@ -210,7 +220,8 @@ class Entity(entity.Entity): _domain = None # Must be overriden by subclasses - def __init__(self, endpoint, clusters, manufacturer, model, **kwargs): + def __init__(self, endpoint, in_clusters, out_clusters, manufacturer, + model, **kwargs): """Init ZHA entity.""" self._device_state_attributes = {} ieeetail = ''.join([ @@ -234,10 +245,13 @@ class Entity(entity.Entity): ieeetail, endpoint.endpoint_id, ) - for cluster in clusters: + for cluster in in_clusters.values(): + cluster.add_listener(self) + for cluster in out_clusters.values(): cluster.add_listener(self) self._endpoint = endpoint - self._clusters = {c.cluster_id: c for c in clusters} + self._in_clusters = in_clusters + self._out_clusters = out_clusters self._state = ha_const.STATE_UNKNOWN def attribute_updated(self, attribute, value): @@ -261,13 +275,13 @@ def _discover_endpoint_info(endpoint): 'manufacturer': None, 'model': None, } - if 0 not in endpoint.clusters: + if 0 not in endpoint.in_clusters: return extra_info @asyncio.coroutine def read(attributes): """Read attributes and update extra_info convenience function.""" - result, _ = yield from endpoint.clusters[0].read_attributes( + result, _ = yield from endpoint.in_clusters[0].read_attributes( attributes, allow_cache=True, ) diff --git a/homeassistant/components/zha/const.py b/homeassistant/components/zha/const.py index ed06f18c1f5..b1659536e32 100644 --- a/homeassistant/components/zha/const.py +++ b/homeassistant/components/zha/const.py @@ -46,6 +46,7 @@ def populate_data(): profile = PROFILES[profile_id] for device_type, component in classes.items(): if component not in COMPONENT_CLUSTERS: - COMPONENT_CLUSTERS[component] = set() + COMPONENT_CLUSTERS[component] = (set(), set()) clusters = profile.CLUSTERS[device_type] - COMPONENT_CLUSTERS[component].update(clusters) + COMPONENT_CLUSTERS[component][0].update(clusters[0]) + COMPONENT_CLUSTERS[component][1].update(clusters[1]) diff --git a/requirements_all.txt b/requirements_all.txt index d4e3add1774..37e3f8502f9 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -93,7 +93,7 @@ batinfo==0.4.2 beautifulsoup4==4.6.0 # homeassistant.components.zha -bellows==0.2.7 +bellows==0.3.2 # homeassistant.components.blink blinkpy==0.6.0 From ac72dea09a98c37172626787466d34d59feec5bc Mon Sep 17 00:00:00 2001 From: Russell Cloran Date: Mon, 10 Jul 2017 21:20:17 -0700 Subject: [PATCH 097/131] Add support for Prometheus (#8211) Prometheus (https://prometheus.io/) is an open source metric and alerting system. This adds support for exporting some metrics to Prometheus, using its Python client library. --- .coveragerc | 1 + homeassistant/components/prometheus.py | 234 +++++++++++++++++++++++++ homeassistant/helpers/state.py | 13 +- requirements_all.txt | 3 + requirements_test_all.txt | 3 + script/gen_requirements_all.py | 1 + tests/components/test_prometheus.py | 33 ++++ tests/helpers/test_state.py | 8 +- 8 files changed, 287 insertions(+), 9 deletions(-) create mode 100644 homeassistant/components/prometheus.py create mode 100644 tests/components/test_prometheus.py diff --git a/.coveragerc b/.coveragerc index 8d2c85627ed..0defebb7e7a 100644 --- a/.coveragerc +++ b/.coveragerc @@ -383,6 +383,7 @@ omit = homeassistant/components/notify/twitter.py homeassistant/components/notify/xmpp.py homeassistant/components/nuimo_controller.py + homeassistant/components/prometheus.py homeassistant/components/remote/harmony.py homeassistant/components/remote/itach.py homeassistant/components/scene/hunterdouglas_powerview.py diff --git a/homeassistant/components/prometheus.py b/homeassistant/components/prometheus.py new file mode 100644 index 00000000000..4ed6028ac56 --- /dev/null +++ b/homeassistant/components/prometheus.py @@ -0,0 +1,234 @@ +""" +Support for Prometheus metrics export. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/prometheus/ +""" +import asyncio +import logging + +import voluptuous as vol +from aiohttp import web + +from homeassistant.components.http import HomeAssistantView +from homeassistant.components import recorder +from homeassistant.const import (CONF_DOMAINS, CONF_ENTITIES, CONF_EXCLUDE, + CONF_INCLUDE, EVENT_STATE_CHANGED, + TEMP_CELSIUS, TEMP_FAHRENHEIT) +from homeassistant import core as hacore +from homeassistant.helpers import state as state_helper + +_LOGGER = logging.getLogger(__name__) + +REQUIREMENTS = ['prometheus_client==0.0.19'] + +DOMAIN = 'prometheus' +DEPENDENCIES = ['http'] + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: recorder.FILTER_SCHEMA, +}, extra=vol.ALLOW_EXTRA) + +API_ENDPOINT = '/api/prometheus' + + +def setup(hass, config): + """Activate Prometheus component.""" + import prometheus_client + + hass.http.register_view(PrometheusView(prometheus_client)) + + conf = config.get(DOMAIN, {}) + exclude = conf.get(CONF_EXCLUDE, {}) + include = conf.get(CONF_INCLUDE, {}) + metrics = Metrics(prometheus_client, exclude, include) + + hass.bus.listen(EVENT_STATE_CHANGED, metrics.handle_event) + + return True + + +class Metrics: + """Model all of the metrics which should be exposed to Prometheus.""" + + def __init__(self, prometheus_client, exclude, include): + """Initialize Prometheus Metrics.""" + self.prometheus_client = prometheus_client + self.exclude = exclude.get(CONF_ENTITIES, []) + \ + exclude.get(CONF_DOMAINS, []) + self.include_domains = include.get(CONF_DOMAINS, []) + self.include_entities = include.get(CONF_ENTITIES, []) + self._metrics = {} + + def handle_event(self, event): + """Listen for new messages on the bus, and add them to Prometheus.""" + state = event.data.get('new_state') + if state is None: + return + + entity_id = state.entity_id + _LOGGER.debug("Handling state update for %s", entity_id) + domain, _ = hacore.split_entity_id(entity_id) + + if entity_id in self.exclude: + return + if domain in self.exclude and entity_id not in self.include_entities: + return + if self.include_domains and domain not in self.include_domains: + return + if not self.exclude and (self.include_entities and + entity_id not in self.include_entities): + return + + handler = '_handle_' + domain + + if hasattr(self, handler): + getattr(self, handler)(state) + + def _metric(self, metric, factory, documentation, labels=None): + if labels is None: + labels = ['entity', 'friendly_name'] + + try: + return self._metrics[metric] + except KeyError: + self._metrics[metric] = factory(metric, documentation, labels) + return self._metrics[metric] + + @staticmethod + def _labels(state): + return { + 'entity': state.entity_id, + 'friendly_name': state.attributes.get('friendly_name'), + } + + def _battery(self, state): + if 'battery_level' in state.attributes: + metric = self._metric( + 'battery_level_percent', + self.prometheus_client.Gauge, + 'Battery level as a percentage of its capacity', + ) + try: + value = float(state.attributes['battery_level']) + metric.labels(**self._labels(state)).set(value) + except ValueError: + pass + + def _handle_binary_sensor(self, state): + metric = self._metric( + 'binary_sensor_state', + self.prometheus_client.Gauge, + 'State of the binary sensor (0/1)', + ) + value = state_helper.state_as_number(state) + metric.labels(**self._labels(state)).set(value) + + def _handle_device_tracker(self, state): + metric = self._metric( + 'device_tracker_state', + self.prometheus_client.Gauge, + 'State of the device tracker (0/1)', + ) + value = state_helper.state_as_number(state) + metric.labels(**self._labels(state)).set(value) + + def _handle_light(self, state): + metric = self._metric( + 'light_state', + self.prometheus_client.Gauge, + 'Load level of a light (0..1)', + ) + + try: + if 'brightness' in state.attributes: + value = state.attributes['brightness'] / 255.0 + else: + value = state_helper.state_as_number(state) + value = value * 100 + metric.labels(**self._labels(state)).set(value) + except ValueError: + pass + + def _handle_lock(self, state): + metric = self._metric( + 'lock_state', + self.prometheus_client.Gauge, + 'State of the lock (0/1)', + ) + value = state_helper.state_as_number(state) + metric.labels(**self._labels(state)).set(value) + + def _handle_sensor(self, state): + _sensor_types = { + TEMP_CELSIUS: ( + 'temperature_c', self.prometheus_client.Gauge, + 'Temperature in degrees Celsius', + ), + TEMP_FAHRENHEIT: ( + 'temperature_c', self.prometheus_client.Gauge, + 'Temperature in degrees Celsius', + ), + '%': ( + 'relative_humidity', self.prometheus_client.Gauge, + 'Relative humidity (0..100)', + ), + 'lux': ( + 'light_lux', self.prometheus_client.Gauge, + 'Light level in lux', + ), + 'kWh': ( + 'electricity_used_kwh', self.prometheus_client.Gauge, + 'Electricity used by this device in KWh', + ), + 'V': ( + 'voltage', self.prometheus_client.Gauge, + 'Currently reported voltage in Volts', + ), + 'W': ( + 'electricity_usage_w', self.prometheus_client.Gauge, + 'Currently reported electricity draw in Watts', + ), + } + + unit = state.attributes.get('unit_of_measurement') + metric = _sensor_types.get(unit) + + if metric is not None: + metric = self._metric(*metric) + try: + value = state_helper.state_as_number(state) + metric.labels(**self._labels(state)).set(value) + except ValueError: + pass + + self._battery(state) + + def _handle_switch(self, state): + metric = self._metric( + 'switch_state', + self.prometheus_client.Gauge, + 'State of the switch (0/1)', + ) + value = state_helper.state_as_number(state) + metric.labels(**self._labels(state)).set(value) + + +class PrometheusView(HomeAssistantView): + """Handle Prometheus requests.""" + + url = API_ENDPOINT + name = 'api:prometheus' + + def __init__(self, prometheus_client): + """Initialize Prometheus view.""" + self.prometheus_client = prometheus_client + + @asyncio.coroutine + def get(self, request): + """Handle request for Prometheus metrics.""" + _LOGGER.debug('Received Prometheus metrics request') + + return web.Response( + body=self.prometheus_client.generate_latest(), + content_type="text/plain") diff --git a/homeassistant/helpers/state.py b/homeassistant/helpers/state.py index 7715e49880d..19113f243d2 100644 --- a/homeassistant/helpers/state.py +++ b/homeassistant/helpers/state.py @@ -25,15 +25,16 @@ from homeassistant.components.climate.ecobee import ( ATTR_FAN_MIN_ON_TIME, SERVICE_SET_FAN_MIN_ON_TIME, ATTR_RESUME_ALL, SERVICE_RESUME_PROGRAM) from homeassistant.const import ( - ATTR_ENTITY_ID, ATTR_TEMPERATURE, SERVICE_ALARM_ARM_AWAY, + ATTR_ENTITY_ID, ATTR_OPTION, ATTR_TEMPERATURE, SERVICE_ALARM_ARM_AWAY, SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_DISARM, SERVICE_ALARM_TRIGGER, SERVICE_LOCK, SERVICE_MEDIA_PAUSE, SERVICE_MEDIA_PLAY, SERVICE_MEDIA_SEEK, SERVICE_TURN_OFF, SERVICE_TURN_ON, SERVICE_UNLOCK, SERVICE_VOLUME_MUTE, SERVICE_VOLUME_SET, SERVICE_OPEN_COVER, SERVICE_CLOSE_COVER, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, - STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED, STATE_CLOSED, STATE_LOCKED, - STATE_OFF, STATE_ON, STATE_OPEN, STATE_PAUSED, STATE_PLAYING, - STATE_UNKNOWN, STATE_UNLOCKED, SERVICE_SELECT_OPTION, ATTR_OPTION) + STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED, STATE_CLOSED, STATE_HOME, + STATE_LOCKED, STATE_NOT_HOME, STATE_OFF, STATE_ON, STATE_OPEN, + STATE_PAUSED, STATE_PLAYING, STATE_UNKNOWN, STATE_UNLOCKED, + SERVICE_SELECT_OPTION) from homeassistant.core import State from homeassistant.util.async import run_coroutine_threadsafe @@ -203,10 +204,10 @@ def state_as_number(state): Raises ValueError if this is not possible. """ if state.state in (STATE_ON, STATE_LOCKED, STATE_ABOVE_HORIZON, - STATE_OPEN): + STATE_OPEN, STATE_HOME): return 1 elif state.state in (STATE_OFF, STATE_UNLOCKED, STATE_UNKNOWN, - STATE_BELOW_HORIZON, STATE_CLOSED): + STATE_BELOW_HORIZON, STATE_CLOSED, STATE_NOT_HOME): return 0 return float(state.state) diff --git a/requirements_all.txt b/requirements_all.txt index 37e3f8502f9..80eb6987ce8 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -476,6 +476,9 @@ pocketcasts==0.1 # homeassistant.components.climate.proliphix proliphix==0.4.1 +# homeassistant.components.prometheus +prometheus_client==0.0.19 + # homeassistant.components.sensor.systemmonitor psutil==5.2.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 8ea6c98042b..58fdcecf63c 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -88,6 +88,9 @@ pilight==0.1.1 # homeassistant.components.sensor.serial_pm pmsensor==0.4 +# homeassistant.components.prometheus +prometheus_client==0.0.19 + # homeassistant.components.zwave pydispatcher==2.0.5 diff --git a/script/gen_requirements_all.py b/script/gen_requirements_all.py index f1f0678c60f..7e2f1d99f2a 100755 --- a/script/gen_requirements_all.py +++ b/script/gen_requirements_all.py @@ -69,6 +69,7 @@ TEST_REQUIREMENTS = ( 'PyJWT', 'restrictedpython', 'pyunifi', + 'prometheus_client', ) IGNORE_PACKAGES = ( diff --git a/tests/components/test_prometheus.py b/tests/components/test_prometheus.py new file mode 100644 index 00000000000..dd8cbfe55e0 --- /dev/null +++ b/tests/components/test_prometheus.py @@ -0,0 +1,33 @@ +"""The tests for the Prometheus exporter.""" +import asyncio +import pytest + +from homeassistant.setup import async_setup_component +import homeassistant.components.prometheus as prometheus + + +@pytest.fixture +def prometheus_client(loop, hass, test_client): + """Initialize a test_client with Prometheus component.""" + assert loop.run_until_complete(async_setup_component( + hass, + prometheus.DOMAIN, + {}, + )) + return loop.run_until_complete(test_client(hass.http.app)) + + +@asyncio.coroutine +def test_view(prometheus_client): # pylint: disable=redefined-outer-name + """Test prometheus metrics view.""" + resp = yield from prometheus_client.get(prometheus.API_ENDPOINT) + + assert resp.status == 200 + assert resp.headers['content-type'] == 'text/plain' + body = yield from resp.text() + body = body.split("\n") + + assert len(body) > 3 # At least two comment lines and a metric + for line in body: + if line: + assert line.startswith('# ') or line.startswith('process_') diff --git a/tests/helpers/test_state.py b/tests/helpers/test_state.py index e9d163ad471..cc42bc8d7f8 100644 --- a/tests/helpers/test_state.py +++ b/tests/helpers/test_state.py @@ -13,7 +13,8 @@ from homeassistant.helpers import state from homeassistant.const import ( STATE_OPEN, STATE_CLOSED, STATE_LOCKED, STATE_UNLOCKED, - STATE_ON, STATE_OFF) + STATE_ON, STATE_OFF, + STATE_HOME, STATE_NOT_HOME) from homeassistant.components.media_player import ( SERVICE_PLAY_MEDIA, SERVICE_MEDIA_PLAY, SERVICE_MEDIA_PAUSE) from homeassistant.components.sun import (STATE_ABOVE_HORIZON, @@ -258,8 +259,9 @@ class TestStateHelpers(unittest.TestCase): def test_as_number_states(self): """Test state_as_number with states.""" zero_states = (STATE_OFF, STATE_CLOSED, STATE_UNLOCKED, - STATE_BELOW_HORIZON) - one_states = (STATE_ON, STATE_OPEN, STATE_LOCKED, STATE_ABOVE_HORIZON) + STATE_BELOW_HORIZON, STATE_NOT_HOME) + one_states = (STATE_ON, STATE_OPEN, STATE_LOCKED, STATE_ABOVE_HORIZON, + STATE_HOME) for _state in zero_states: self.assertEqual(0, state.state_as_number( ha.State('domain.test', _state, {}))) From f5e24cb0bbaf9b18c199302687f5e96b623f8755 Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Tue, 11 Jul 2017 04:10:10 -0400 Subject: [PATCH 098/131] Refactored Amcrest to use central hub component (#8184) * Refactored Amcrest to use central hub component * Set default streaming source to snapshot * Simplified code by using discovery platforms * Makes lint happy * Update authentication method to basic * Fixed lint issues * Makes Amcrest hub async * Make Amcrest hub IO synchronous and disabled ffmpeg dependency on sensor/amcrest. * Removed async to load component * Organized import order * Update amcrest.py --- .coveragerc | 5 +- homeassistant/components/amcrest.py | 149 +++++++++++++++++++++ homeassistant/components/camera/amcrest.py | 109 +++++---------- homeassistant/components/sensor/amcrest.py | 82 +++--------- requirements_all.txt | 3 +- 5 files changed, 203 insertions(+), 145 deletions(-) create mode 100644 homeassistant/components/amcrest.py diff --git a/.coveragerc b/.coveragerc index 0defebb7e7a..e4d896e444b 100644 --- a/.coveragerc +++ b/.coveragerc @@ -11,6 +11,9 @@ omit = homeassistant/components/alarmdecoder.py homeassistant/components/*/alarmdecoder.py + homeassistant/components/amcrest.py + homeassistant/components/*/amcrest.py + homeassistant/components/apcupsd.py homeassistant/components/*/apcupsd.py @@ -220,7 +223,6 @@ omit = homeassistant/components/binary_sensor/rest.py homeassistant/components/binary_sensor/tapsaff.py homeassistant/components/browser.py - homeassistant/components/camera/amcrest.py homeassistant/components/camera/bloomsky.py homeassistant/components/camera/ffmpeg.py homeassistant/components/camera/foscam.py @@ -388,7 +390,6 @@ omit = homeassistant/components/remote/itach.py homeassistant/components/scene/hunterdouglas_powerview.py homeassistant/components/scene/lifx_cloud.py - homeassistant/components/sensor/amcrest.py homeassistant/components/sensor/arest.py homeassistant/components/sensor/arwn.py homeassistant/components/sensor/bbox.py diff --git a/homeassistant/components/amcrest.py b/homeassistant/components/amcrest.py new file mode 100644 index 00000000000..8a40c790c12 --- /dev/null +++ b/homeassistant/components/amcrest.py @@ -0,0 +1,149 @@ +""" +This component provides basic support for Amcrest IP cameras. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/amcrest/ +""" +import logging +from datetime import timedelta + +import aiohttp +import voluptuous as vol +from requests.exceptions import HTTPError, ConnectTimeout + +import homeassistant.loader as loader +from homeassistant.const import ( + CONF_NAME, CONF_HOST, CONF_PORT, CONF_USERNAME, CONF_PASSWORD, + CONF_SENSORS, CONF_SCAN_INTERVAL, HTTP_BASIC_AUTHENTICATION) +from homeassistant.helpers import discovery +import homeassistant.helpers.config_validation as cv + +REQUIREMENTS = ['amcrest==1.2.0'] +DEPENDENCIES = ['ffmpeg'] + +_LOGGER = logging.getLogger(__name__) + +CONF_AUTHENTICATION = 'authentication' +CONF_RESOLUTION = 'resolution' +CONF_STREAM_SOURCE = 'stream_source' +CONF_FFMPEG_ARGUMENTS = 'ffmpeg_arguments' + +DEFAULT_NAME = 'Amcrest Camera' +DEFAULT_PORT = 80 +DEFAULT_RESOLUTION = 'high' +DEFAULT_STREAM_SOURCE = 'snapshot' +TIMEOUT = 10 + +DATA_AMCREST = 'amcrest' +DOMAIN = 'amcrest' + +NOTIFICATION_ID = 'amcrest_notification' +NOTIFICATION_TITLE = 'Amcrest Camera Setup' + +RESOLUTION_LIST = { + 'high': 0, + 'low': 1, +} + +SCAN_INTERVAL = timedelta(seconds=10) + +AUTHENTICATION_LIST = { + 'basic': 'basic' +} + +STREAM_SOURCE_LIST = { + 'mjpeg': 0, + 'snapshot': 1, + 'rtsp': 2, +} + +# Sensor types are defined like: Name, units, icon +SENSORS = { + 'motion_detector': ['Motion Detected', None, 'mdi:run'], + 'sdcard': ['SD Used', '%', 'mdi:sd'], + 'ptz_preset': ['PTZ Preset', None, 'mdi:camera-iris'], +} + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.All(cv.ensure_list, [vol.Schema({ + vol.Required(CONF_HOST): cv.string, + vol.Required(CONF_USERNAME): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, + vol.Optional(CONF_AUTHENTICATION, default=HTTP_BASIC_AUTHENTICATION): + vol.All(vol.In(AUTHENTICATION_LIST)), + vol.Optional(CONF_RESOLUTION, default=DEFAULT_RESOLUTION): + vol.All(vol.In(RESOLUTION_LIST)), + vol.Optional(CONF_STREAM_SOURCE, default=DEFAULT_STREAM_SOURCE): + vol.All(vol.In(STREAM_SOURCE_LIST)), + vol.Optional(CONF_FFMPEG_ARGUMENTS): cv.string, + vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): + cv.time_period, + vol.Optional(CONF_SENSORS, default=None): + vol.All(cv.ensure_list, [vol.In(SENSORS)]), + })]) +}, extra=vol.ALLOW_EXTRA) + + +def setup(hass, config): + """Set up the Amcrest IP Camera component.""" + from amcrest import AmcrestCamera + + amcrest_cams = config[DOMAIN] + + persistent_notification = loader.get_component('persistent_notification') + for device in amcrest_cams: + camera = AmcrestCamera(device.get(CONF_HOST), + device.get(CONF_PORT), + device.get(CONF_USERNAME), + device.get(CONF_PASSWORD)).camera + try: + camera.current_time + + except (ConnectTimeout, HTTPError) as ex: + _LOGGER.error("Unable to connect to Amcrest camera: %s", str(ex)) + persistent_notification.create( + hass, 'Error: {}
' + 'You will need to restart hass after fixing.' + ''.format(ex), + title=NOTIFICATION_TITLE, + notification_id=NOTIFICATION_ID) + return False + + ffmpeg_arguments = device.get(CONF_FFMPEG_ARGUMENTS) + name = device.get(CONF_NAME) + resolution = RESOLUTION_LIST[device.get(CONF_RESOLUTION)] + sensors = device.get(CONF_SENSORS) + stream_source = STREAM_SOURCE_LIST[device.get(CONF_STREAM_SOURCE)] + + username = device.get(CONF_USERNAME) + password = device.get(CONF_PASSWORD) + + # currently aiohttp only works with basic authentication + # only valid for mjpeg streaming + if username is not None and password is not None: + if device.get(CONF_AUTHENTICATION) == HTTP_BASIC_AUTHENTICATION: + authentication = aiohttp.BasicAuth(username, password) + else: + authentication = None + + discovery.load_platform( + hass, 'camera', DOMAIN, { + 'device': camera, + CONF_AUTHENTICATION: authentication, + CONF_FFMPEG_ARGUMENTS: ffmpeg_arguments, + CONF_NAME: name, + CONF_RESOLUTION: resolution, + CONF_STREAM_SOURCE: stream_source, + }, config) + + if sensors: + discovery.load_platform( + hass, 'sensor', DOMAIN, { + 'device': camera, + CONF_NAME: name, + CONF_SENSORS: sensors, + }, config) + + return True diff --git a/homeassistant/components/camera/amcrest.py b/homeassistant/components/camera/amcrest.py index 8f8b7e5f9f5..51b8ff13906 100644 --- a/homeassistant/components/camera/amcrest.py +++ b/homeassistant/components/camera/amcrest.py @@ -7,108 +7,59 @@ https://home-assistant.io/components/camera.amcrest/ import asyncio import logging -import aiohttp -import voluptuous as vol - -import homeassistant.loader as loader -from homeassistant.components.camera import (Camera, PLATFORM_SCHEMA) +from homeassistant.components.amcrest import ( + STREAM_SOURCE_LIST, TIMEOUT) +from homeassistant.components.camera import Camera from homeassistant.components.ffmpeg import DATA_FFMPEG -from homeassistant.const import ( - CONF_HOST, CONF_NAME, CONF_USERNAME, CONF_PASSWORD, CONF_PORT) -from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import ( async_get_clientsession, async_aiohttp_proxy_web, async_aiohttp_proxy_stream) -REQUIREMENTS = ['amcrest==1.2.0'] -DEPENDENCIES = ['ffmpeg'] +DEPENDENCIES = ['amcrest', 'ffmpeg'] _LOGGER = logging.getLogger(__name__) -CONF_RESOLUTION = 'resolution' -CONF_STREAM_SOURCE = 'stream_source' -CONF_FFMPEG_ARGUMENTS = 'ffmpeg_arguments' -DEFAULT_NAME = 'Amcrest Camera' -DEFAULT_PORT = 80 -DEFAULT_RESOLUTION = 'high' -DEFAULT_STREAM_SOURCE = 'mjpeg' - -NOTIFICATION_ID = 'amcrest_notification' -NOTIFICATION_TITLE = 'Amcrest Camera Setup' - -RESOLUTION_LIST = { - 'high': 0, - 'low': 1, -} - -STREAM_SOURCE_LIST = { - 'mjpeg': 0, - 'snapshot': 1, - 'rtsp': 2, -} - -CONTENT_TYPE_HEADER = 'Content-Type' -TIMEOUT = 5 - -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ - vol.Required(CONF_HOST): cv.string, - vol.Required(CONF_USERNAME): cv.string, - vol.Required(CONF_PASSWORD): cv.string, - vol.Optional(CONF_RESOLUTION, default=DEFAULT_RESOLUTION): - vol.All(vol.In(RESOLUTION_LIST)), - vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, - vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, - vol.Optional(CONF_STREAM_SOURCE, default=DEFAULT_STREAM_SOURCE): - vol.All(vol.In(STREAM_SOURCE_LIST)), - vol.Optional(CONF_FFMPEG_ARGUMENTS): cv.string, -}) - - -def setup_platform(hass, config, add_devices, discovery_info=None): +@asyncio.coroutine +def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Set up an Amcrest IP Camera.""" - from amcrest import AmcrestCamera - camera = AmcrestCamera( - config.get(CONF_HOST), config.get(CONF_PORT), - config.get(CONF_USERNAME), config.get(CONF_PASSWORD)).camera + if discovery_info is None: + return - persistent_notification = loader.get_component('persistent_notification') - try: - camera.current_time - # pylint: disable=broad-except - except Exception as ex: - _LOGGER.error("Unable to connect to Amcrest camera: %s", str(ex)) - persistent_notification.create( - hass, 'Error: {}
' - 'You will need to restart hass after fixing.' - ''.format(ex), - title=NOTIFICATION_TITLE, - notification_id=NOTIFICATION_ID) - return False + device = discovery_info['device'] + authentication = discovery_info['authentication'] + ffmpeg_arguments = discovery_info['ffmpeg_arguments'] + name = discovery_info['name'] + resolution = discovery_info['resolution'] + stream_source = discovery_info['stream_source'] + + async_add_devices([ + AmcrestCam(hass, + name, + device, + authentication, + ffmpeg_arguments, + stream_source, + resolution)], True) - add_devices([AmcrestCam(hass, config, camera)]) return True class AmcrestCam(Camera): """An implementation of an Amcrest IP camera.""" - def __init__(self, hass, device_info, camera): + def __init__(self, hass, name, camera, authentication, + ffmpeg_arguments, stream_source, resolution): """Initialize an Amcrest camera.""" super(AmcrestCam, self).__init__() + self._name = name self._camera = camera self._base_url = self._camera.get_base_url() - self._name = device_info.get(CONF_NAME) self._ffmpeg = hass.data[DATA_FFMPEG] - self._ffmpeg_arguments = device_info.get(CONF_FFMPEG_ARGUMENTS) - self._resolution = RESOLUTION_LIST[device_info.get(CONF_RESOLUTION)] - self._stream_source = STREAM_SOURCE_LIST[ - device_info.get(CONF_STREAM_SOURCE) - ] - self._token = self._auth = aiohttp.BasicAuth( - device_info.get(CONF_USERNAME), - password=device_info.get(CONF_PASSWORD) - ) + self._ffmpeg_arguments = ffmpeg_arguments + self._stream_source = stream_source + self._resolution = resolution + self._token = self._auth = authentication def camera_image(self): """Return a still image reponse from the camera.""" diff --git a/homeassistant/components/sensor/amcrest.py b/homeassistant/components/sensor/amcrest.py index 23f7fc4dfbe..e7bf309c33a 100644 --- a/homeassistant/components/sensor/amcrest.py +++ b/homeassistant/components/sensor/amcrest.py @@ -4,92 +4,50 @@ This component provides HA sensor support for Amcrest IP cameras. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.amcrest/ """ +import asyncio from datetime import timedelta import logging -import voluptuous as vol -import homeassistant.helpers.config_validation as cv - -from homeassistant.components.sensor import PLATFORM_SCHEMA -from homeassistant.const import ( - CONF_HOST, CONF_NAME, CONF_MONITORED_CONDITIONS, - CONF_USERNAME, CONF_PASSWORD, CONF_PORT, STATE_UNKNOWN) +from homeassistant.components.amcrest import SENSORS from homeassistant.helpers.entity import Entity -import homeassistant.loader as loader +from homeassistant.const import STATE_UNKNOWN -from requests.exceptions import HTTPError, ConnectTimeout - -REQUIREMENTS = ['amcrest==1.2.0'] +DEPENDENCIES = ['amcrest'] _LOGGER = logging.getLogger(__name__) -NOTIFICATION_ID = 'amcrest_notification' -NOTIFICATION_TITLE = 'Amcrest Sensor Setup' - -DEFAULT_NAME = 'Amcrest' -DEFAULT_PORT = 80 SCAN_INTERVAL = timedelta(seconds=10) -# Sensor types are defined like: Name, units, icon -SENSOR_TYPES = { - 'motion_detector': ['Motion Detected', None, 'run'], - 'sdcard': ['SD Used', '%', 'sd'], - 'ptz_preset': ['PTZ Preset', None, 'camera-iris'], -} -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ - vol.Required(CONF_HOST): cv.string, - vol.Required(CONF_USERNAME): cv.string, - vol.Required(CONF_PASSWORD): cv.string, - vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, - vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, - vol.Required(CONF_MONITORED_CONDITIONS, default=[]): - vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]), -}) - - -def setup_platform(hass, config, add_devices, discovery_info=None): +@asyncio.coroutine +def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Set up a sensor for an Amcrest IP Camera.""" - from amcrest import AmcrestCamera + if discovery_info is None: + return - camera = AmcrestCamera( - config.get(CONF_HOST), config.get(CONF_PORT), - config.get(CONF_USERNAME), config.get(CONF_PASSWORD)).camera + device = discovery_info['device'] + name = discovery_info['name'] + sensors = discovery_info['sensors'] - persistent_notification = loader.get_component('persistent_notification') - try: - camera.current_time - except (ConnectTimeout, HTTPError) as ex: - _LOGGER.error("Unable to connect to Amcrest camera: %s", str(ex)) - persistent_notification.create( - hass, 'Error: {}
' - 'You will need to restart hass after fixing.' - ''.format(ex), - title=NOTIFICATION_TITLE, - notification_id=NOTIFICATION_ID) - return False - - sensors = [] - for sensor_type in config.get(CONF_MONITORED_CONDITIONS): - sensors.append(AmcrestSensor(config, camera, sensor_type)) - - add_devices(sensors, True) + amcrest_sensors = [] + for sensor_type in sensors: + amcrest_sensors.append(AmcrestSensor(name, device, sensor_type)) + async_add_devices(amcrest_sensors, True) return True class AmcrestSensor(Entity): """A sensor implementation for Amcrest IP camera.""" - def __init__(self, device_info, camera, sensor_type): + def __init__(self, name, camera, sensor_type): """Initialize a sensor for Amcrest camera.""" - super(AmcrestSensor, self).__init__() self._attrs = {} self._camera = camera self._sensor_type = sensor_type - self._name = '{0}_{1}'.format(device_info.get(CONF_NAME), - SENSOR_TYPES.get(self._sensor_type)[0]) - self._icon = 'mdi:{}'.format(SENSOR_TYPES.get(self._sensor_type)[2]) + self._name = '{0}_{1}'.format(name, + SENSORS.get(self._sensor_type)[0]) + self._icon = 'mdi:{}'.format(SENSORS.get(self._sensor_type)[2]) self._state = STATE_UNKNOWN @property @@ -115,7 +73,7 @@ class AmcrestSensor(Entity): @property def unit_of_measurement(self): """Return the units of measurement.""" - return SENSOR_TYPES.get(self._sensor_type)[1] + return SENSORS.get(self._sensor_type)[1] def update(self): """Get the latest data and updates the state.""" diff --git a/requirements_all.txt b/requirements_all.txt index 80eb6987ce8..5d09b63df80 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -60,8 +60,7 @@ aiopvapi==1.4 # homeassistant.components.alarmdecoder alarmdecoder==0.12.1.0 -# homeassistant.components.camera.amcrest -# homeassistant.components.sensor.amcrest +# homeassistant.components.amcrest amcrest==1.2.0 # homeassistant.components.media_player.anthemav From 04b1621b655e772dcdcd588dc3a0f051d951107f Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 11 Jul 2017 03:12:51 -0500 Subject: [PATCH 099/131] Fix radiothermostat -1 value issue (#8395) * Fix -1 value issue Fixed issue where thermostat will sometimes return a current temperature or set temperature value of -1 * Update radiotherm.py * Update radiotherm.py * Update radiotherm.py Added retry limit * Update radiotherm.py * Update radiotherm.py --- .../components/climate/radiotherm.py | 47 +++++++++++++++---- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/climate/radiotherm.py b/homeassistant/components/climate/radiotherm.py index 8011f53f375..22e09ad0161 100644 --- a/homeassistant/components/climate/radiotherm.py +++ b/homeassistant/components/climate/radiotherm.py @@ -136,24 +136,53 @@ class RadioThermostat(ClimateDevice): return self._away def update(self): - """Update the data from the thermostat.""" - self._current_temperature = self.device.temp['raw'] + """Update and validate the data from the thermostat.""" + current_temp = self.device.temp['raw'] + if current_temp == -1: + _LOGGER.error("Couldn't get valid temperature reading") + return + self._current_temperature = current_temp self._name = self.device.name['raw'] - self._fmode = self.device.fmode['human'] - self._tmode = self.device.tmode['human'] - self._tstate = self.device.tstate['human'] + try: + self._fmode = self.device.fmode['human'] + except AttributeError: + _LOGGER.error("Couldn't get valid fan mode reading") + try: + self._tmode = self.device.tmode['human'] + except AttributeError: + _LOGGER.error("Couldn't get valid thermostat mode reading") + try: + self._tstate = self.device.tstate['human'] + except AttributeError: + _LOGGER.error("Couldn't get valid thermostat state reading") if self._tmode == 'Cool': - self._target_temperature = self.device.t_cool['raw'] + target_temp = self.device.t_cool['raw'] + if target_temp == -1: + _LOGGER.error("Couldn't get target reading") + return + self._target_temperature = target_temp self._current_operation = STATE_COOL elif self._tmode == 'Heat': - self._target_temperature = self.device.t_heat['raw'] + target_temp = self.device.t_heat['raw'] + if target_temp == -1: + _LOGGER.error("Couldn't get valid target reading") + return + self._target_temperature = target_temp self._current_operation = STATE_HEAT elif self._tmode == 'Auto': if self._tstate == 'Cool': - self._target_temperature = self.device.t_cool['raw'] + target_temp = self.device.t_cool['raw'] + if target_temp == -1: + _LOGGER.error("Couldn't get valid target reading") + return + self._target_temperature = target_temp elif self._tstate == 'Heat': - self._target_temperature = self.device.t_heat['raw'] + target_temp = self.device.t_heat['raw'] + if target_temp == -1: + _LOGGER.error("Couldn't get valid target reading") + return + self._target_temperature = target_temp self._current_operation = STATE_AUTO else: self._current_operation = STATE_IDLE From ee57a823af3eeb6b23b11f501358c1aba5d18ef5 Mon Sep 17 00:00:00 2001 From: Aliaksandr Date: Tue, 11 Jul 2017 11:16:34 +0300 Subject: [PATCH 100/131] Added media_helper service (#8369) * Added media_helper service * Fixed lint warning * media_helper renamed to media_extractor --- .coveragerc | 1 + homeassistant/components/media_extractor.py | 101 ++++++++++++++++++++ requirements_all.txt | 3 + 3 files changed, 105 insertions(+) create mode 100644 homeassistant/components/media_extractor.py diff --git a/.coveragerc b/.coveragerc index e4d896e444b..fcb09069267 100644 --- a/.coveragerc +++ b/.coveragerc @@ -312,6 +312,7 @@ omit = homeassistant/components/lock/nuki.py homeassistant/components/lock/lockitron.py homeassistant/components/lock/sesame.py + homeassistant/components/media_extractor.py homeassistant/components/media_player/anthemav.py homeassistant/components/media_player/aquostv.py homeassistant/components/media_player/braviatv.py diff --git a/homeassistant/components/media_extractor.py b/homeassistant/components/media_extractor.py new file mode 100644 index 00000000000..5d1ffb6a0ce --- /dev/null +++ b/homeassistant/components/media_extractor.py @@ -0,0 +1,101 @@ +""" +Decorator service for the media_player.play_media service. + +Extracts stream url and sends it to the media_player.play_media +service. +""" +import logging +import os + +from homeassistant.components.media_player import ( + ATTR_MEDIA_CONTENT_ID, DOMAIN as MEDIA_PLAYER_DOMAIN, + MEDIA_PLAYER_PLAY_MEDIA_SCHEMA, SERVICE_PLAY_MEDIA) +from homeassistant.config import load_yaml_config_file + + +DOMAIN = 'media_extractor' +DEPENDENCIES = ['media_player'] +REQUIREMENTS = ['youtube_dl==2017.7.2'] + +_LOGGER = logging.getLogger(__name__) + + +def setup(hass, config): + """Set up the media_extractor service.""" + descriptions = load_yaml_config_file( + os.path.join(os.path.dirname(__file__), + 'media_player', 'services.yaml')) + + def play_media(call): + """Get stream url and send it to the media_player.play_media.""" + media_url = call.data.get(ATTR_MEDIA_CONTENT_ID) + + try: + stream_url = get_media_stream_url(media_url) + except YDException: + _LOGGER.error("Could not retrieve data for the url: %s", + media_url) + return + else: + data = {k: v for k, v in call.data.items() + if k != ATTR_MEDIA_CONTENT_ID} + data[ATTR_MEDIA_CONTENT_ID] = stream_url + + hass.async_add_job( + hass.services.async_call( + MEDIA_PLAYER_DOMAIN, SERVICE_PLAY_MEDIA, data) + ) + + hass.services.register(DOMAIN, + SERVICE_PLAY_MEDIA, + play_media, + description=descriptions[SERVICE_PLAY_MEDIA], + schema=MEDIA_PLAYER_PLAY_MEDIA_SCHEMA) + + return True + + +class YDException(Exception): + """General service exception.""" + + pass + + +def get_media_stream_url(media_url): + """Extract stream url from the media url.""" + from youtube_dl import YoutubeDL + from youtube_dl.utils import DownloadError, ExtractorError + + ydl = YoutubeDL({'quiet': True, 'logger': _LOGGER}) + + try: + all_media_streams = ydl.extract_info(media_url, process=False) + except DownloadError: + # This exception will be logged by youtube-dl itself + raise YDException() + + if 'entries' in all_media_streams: + _LOGGER.warning("Playlists are not supported, " + "looking for the first video") + try: + selected_stream = next(all_media_streams['entries']) + except StopIteration: + _LOGGER.error("Playlist is empty") + raise YDException() + else: + selected_stream = all_media_streams + + try: + media_info = ydl.process_ie_result(selected_stream, download=False) + except (ExtractorError, DownloadError): + # This exception will be logged by youtube-dl itself + raise YDException() + + format_selector = ydl.build_format_selector('best') + + try: + best_quality_stream = next(format_selector(media_info)) + except (KeyError, StopIteration): + best_quality_stream = media_info + + return best_quality_stream['url'] diff --git a/requirements_all.txt b/requirements_all.txt index 5d09b63df80..81a9b74c0aa 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -961,6 +961,9 @@ yeelight==0.3.0 # homeassistant.components.light.yeelightsunflower yeelightsunflower==0.0.8 +# homeassistant.components.media_extractor +youtube_dl==2017.7.2 + # homeassistant.components.light.zengge zengge==0.2 From 7b105a215082923419f2398ba41bc27cf98636ed Mon Sep 17 00:00:00 2001 From: Alan Fischer Date: Tue, 11 Jul 2017 07:14:46 -0600 Subject: [PATCH 101/131] Updated pyvera (#8437) --- homeassistant/components/vera.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/vera.py b/homeassistant/components/vera.py index a156d87187c..b43cea3fcea 100644 --- a/homeassistant/components/vera.py +++ b/homeassistant/components/vera.py @@ -20,7 +20,7 @@ from homeassistant.const import ( EVENT_HOMEASSISTANT_STOP) from homeassistant.helpers.entity import Entity -REQUIREMENTS = ['pyvera==0.2.33'] +REQUIREMENTS = ['pyvera==0.2.34'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 81a9b74c0aa..cd8b1789e9e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -770,7 +770,7 @@ pyunifi==2.13 # pyuserinput==0.1.11 # homeassistant.components.vera -pyvera==0.2.33 +pyvera==0.2.34 # homeassistant.components.velux pyvlx==0.1.3 From 6e77877743500754a9e0262f7a4cf43333234433 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 11 Jul 2017 09:11:36 -0700 Subject: [PATCH 102/131] Update frontend --- homeassistant/components/frontend/version.py | 15 +-- .../frontend/www_static/frontend.html | 2 +- .../frontend/www_static/frontend.html.gz | Bin 135270 -> 137906 bytes .../www_static/home-assistant-polymer | 2 +- .../panels/ha-panel-automation.html | 2 +- .../panels/ha-panel-automation.html.gz | Bin 28488 -> 28564 bytes .../panels/ha-panel-dev-service.html | 2 +- .../panels/ha-panel-dev-service.html.gz | Bin 23752 -> 23716 bytes .../panels/ha-panel-dev-template.html | 2 +- .../panels/ha-panel-dev-template.html.gz | Bin 11472 -> 11433 bytes .../www_static/panels/ha-panel-hassio.html | 2 +- .../www_static/panels/ha-panel-hassio.html.gz | Bin 392 -> 378 bytes .../www_static/panels/ha-panel-map.html | 10 +- .../www_static/panels/ha-panel-map.html.gz | Bin 43670 -> 44245 bytes .../frontend/www_static/service_worker.js | 2 +- .../frontend/www_static/service_worker.js.gz | Bin 2507 -> 2488 bytes .../frontend/www_static/websocket_test.html | 125 ------------------ .../www_static/websocket_test.html.gz | Bin 1117 -> 0 bytes 18 files changed, 19 insertions(+), 145 deletions(-) delete mode 100644 homeassistant/components/frontend/www_static/websocket_test.html delete mode 100644 homeassistant/components/frontend/www_static/websocket_test.html.gz diff --git a/homeassistant/components/frontend/version.py b/homeassistant/components/frontend/version.py index 8a90f4bd584..beaf7856459 100644 --- a/homeassistant/components/frontend/version.py +++ b/homeassistant/components/frontend/version.py @@ -3,21 +3,20 @@ FINGERPRINTS = { "compatibility.js": "8e4c44b5f4288cc48ec1ba94a9bec812", "core.js": "d4a7cb8c80c62b536764e0e81385f6aa", - "frontend.html": "bdcde4695ce32595a9e1d813b9d7c5f9", + "frontend.html": "157fcf3c30a67a0501852ae8933f900b", "mdi.html": "c92bd28c434865d6cabb34cd3c0a3e4c", "micromarkdown-js.html": "93b5ec4016f0bba585521cf4d18dec1a", - "panels/ha-panel-automation.html": "4f98839bb082885657bbcd0ac04fc680", + "panels/ha-panel-automation.html": "72a5c1856cece8d9246328e84185ab0b", "panels/ha-panel-config.html": "76853de505d173e82249bf605eb73505", "panels/ha-panel-dev-event.html": "4886c821235492b1b92739b580d21c61", "panels/ha-panel-dev-info.html": "24e888ec7a8acd0c395b34396e9001bc", - "panels/ha-panel-dev-service.html": "92c6be30b1af95791d5a6429df505852", + "panels/ha-panel-dev-service.html": "5e5efba829b62a4f66dc0076475a9496", "panels/ha-panel-dev-state.html": "8f1a27c04db6329d31cfcc7d0d6a0869", - "panels/ha-panel-dev-template.html": "d33a55b937b50cdfe8b6fae81f70a139", - "panels/ha-panel-hassio.html": "9474ba65077371622f21ed9a30cf5229", + "panels/ha-panel-dev-template.html": "82cd543177c417e5c6612e07df851e6b", + "panels/ha-panel-hassio.html": "262d31efd9add719e0325da5cf79a096", "panels/ha-panel-history.html": "35177e2046c9a4191c8f51f8160255ce", "panels/ha-panel-iframe.html": "d920f0aa3c903680f2f8795e2255daab", "panels/ha-panel-logbook.html": "7c45bd41c146ec38b9938b8a5188bb0d", - "panels/ha-panel-map.html": "0ba605729197c4724ecc7310b08f7050", - "panels/ha-panel-zwave.html": "2ea2223339d1d2faff478751c2927d11", - "websocket_test.html": "575de64b431fe11c3785bf96d7813450" + "panels/ha-panel-map.html": "d3dae1400ec4e4cd7681d2aa79131d55", + "panels/ha-panel-zwave.html": "2ea2223339d1d2faff478751c2927d11" } diff --git a/homeassistant/components/frontend/www_static/frontend.html b/homeassistant/components/frontend/www_static/frontend.html index da6b5e0163a..69d66292561 100644 --- a/homeassistant/components/frontend/www_static/frontend.html +++ b/homeassistant/components/frontend/www_static/frontend.html @@ -2,4 +2,4 @@ this._useContent&&u.Logical.saveChildNodes(this)},_setupRoot:function(){this._useContent&&(this._createLocalRoot(),this.dataHost||l(u.Logical.getChildNodes(this)))},_createLocalRoot:function(){this.shadyRoot=this.root,this.shadyRoot._distributionClean=!1,this.shadyRoot._hasDistributed=!1,this.shadyRoot._isShadyRoot=!0,this.shadyRoot._dirtyRoots=[];var e=this.shadyRoot._insertionPoints=!this._notes||this._notes._hasContent?this.shadyRoot.querySelectorAll("content"):[];u.Logical.saveChildNodes(this.shadyRoot);for(var t,o=0;o0?~setTimeout(e,t):(this._twiddle.textContent=this._twiddleContent++,this._callbacks.push(e),this._currVal++)},cancel:function(e){if(e<0)clearTimeout(~e);else{var t=e-this._lastVal;if(t>=0){if(!this._callbacks[t])throw"invalid async handle: "+e;this._callbacks[t]=null}}},_atEndOfMicrotask:function(){for(var e=this._callbacks.length,t=0;t \ No newline at end of file +return performance.now()};else var t=function(){return Date.now()};var e=function(t,e,i){this.target=t,this.currentTime=e,this.timelineTime=i,this.type="cancel",this.bubbles=!1,this.cancelable=!1,this.currentTarget=t,this.defaultPrevented=!1,this.eventPhase=Event.AT_TARGET,this.timeStamp=Date.now()},i=window.Element.prototype.animate;window.Element.prototype.animate=function(n,r){var o=i.call(this,n,r);o._cancelHandlers=[],o.oncancel=null;var a=o.cancel;o.cancel=function(){a.call(this);var i=new e(this,null,t()),n=this._cancelHandlers.concat(this.oncancel?[this.oncancel]:[]);setTimeout(function(){n.forEach(function(t){t.call(i.target,i)})},0)};var s=o.addEventListener;o.addEventListener=function(t,e){"function"==typeof e&&"cancel"==t?this._cancelHandlers.push(e):s.call(this,t,e)};var u=o.removeEventListener;return o.removeEventListener=function(t,e){if("cancel"==t){var i=this._cancelHandlers.indexOf(e);i>=0&&this._cancelHandlers.splice(i,1)}else u.call(this,t,e)},o}}}(),function(t){var e=document.documentElement,i=null,n=!1;try{var r=getComputedStyle(e).getPropertyValue("opacity"),o="0"==r?"1":"0";i=e.animate({opacity:[o,o]},{duration:1}),i.currentTime=0,n=getComputedStyle(e).getPropertyValue("opacity")==o}catch(t){}finally{i&&i.cancel()}if(!n){var a=window.Element.prototype.animate;window.Element.prototype.animate=function(e,i){return window.Symbol&&Symbol.iterator&&Array.prototype.from&&e[Symbol.iterator]&&(e=Array.from(e)),Array.isArray(e)||null===e||(e=t.convertToArrayForm(e)),a.call(this,e,i)}}}(c),function(t,e,i){function n(t){var i=e.timeline;i.currentTime=t,i._discardAnimations(),0==i._animations.length?o=!1:requestAnimationFrame(n)}var r=window.requestAnimationFrame;window.requestAnimationFrame=function(t){return r(function(i){e.timeline._updateAnimationsPromises(),t(i),e.timeline._updateAnimationsPromises()})},e.AnimationTimeline=function(){this._animations=[],this.currentTime=void 0},e.AnimationTimeline.prototype={getAnimations:function(){return this._discardAnimations(),this._animations.slice()},_updateAnimationsPromises:function(){e.animationsWithPromises=e.animationsWithPromises.filter(function(t){return t._updatePromises()})},_discardAnimations:function(){this._updateAnimationsPromises(),this._animations=this._animations.filter(function(t){return"finished"!=t.playState&&"idle"!=t.playState})},_play:function(t){var i=new e.Animation(t,this);return this._animations.push(i),e.restartWebAnimationsNextTick(),i._updatePromises(),i._animation.play(),i._updatePromises(),i},play:function(t){return t&&t.remove(),this._play(t)}};var o=!1;e.restartWebAnimationsNextTick=function(){o||(o=!0,requestAnimationFrame(n))};var a=new e.AnimationTimeline;e.timeline=a;try{Object.defineProperty(window.document,"timeline",{configurable:!0,get:function(){return a}})}catch(t){}try{window.document.timeline=a}catch(t){}}(0,e),function(t,e,i){e.animationsWithPromises=[],e.Animation=function(e,i){if(this.id="",e&&e._id&&(this.id=e._id),this.effect=e,e&&(e._animation=this),!i)throw new Error("Animation with null timeline is not supported");this._timeline=i,this._sequenceNumber=t.sequenceNumber++,this._holdTime=0,this._paused=!1,this._isGroup=!1,this._animation=null,this._childAnimations=[],this._callback=null,this._oldPlayState="idle",this._rebuildUnderlyingAnimation(),this._animation.cancel(),this._updatePromises()},e.Animation.prototype={_updatePromises:function(){var t=this._oldPlayState,e=this.playState;return this._readyPromise&&e!==t&&("idle"==e?(this._rejectReadyPromise(),this._readyPromise=void 0):"pending"==t?this._resolveReadyPromise():"pending"==e&&(this._readyPromise=void 0)),this._finishedPromise&&e!==t&&("idle"==e?(this._rejectFinishedPromise(),this._finishedPromise=void 0):"finished"==e?this._resolveFinishedPromise():"finished"==t&&(this._finishedPromise=void 0)),this._oldPlayState=this.playState,this._readyPromise||this._finishedPromise},_rebuildUnderlyingAnimation:function(){this._updatePromises();var t,i,n,r,o=!!this._animation;o&&(t=this.playbackRate,i=this._paused,n=this.startTime,r=this.currentTime,this._animation.cancel(),this._animation._wrapper=null,this._animation=null),(!this.effect||this.effect instanceof window.KeyframeEffect)&&(this._animation=e.newUnderlyingAnimationForKeyframeEffect(this.effect),e.bindAnimationForKeyframeEffect(this)),(this.effect instanceof window.SequenceEffect||this.effect instanceof window.GroupEffect)&&(this._animation=e.newUnderlyingAnimationForGroup(this.effect),e.bindAnimationForGroup(this)),this.effect&&this.effect._onsample&&e.bindAnimationForCustomEffect(this),o&&(1!=t&&(this.playbackRate=t),null!==n?this.startTime=n:null!==r?this.currentTime=r:null!==this._holdTime&&(this.currentTime=this._holdTime),i&&this.pause()),this._updatePromises()},_updateChildren:function(){if(this.effect&&"idle"!=this.playState){var t=this.effect._timing.delay;this._childAnimations.forEach(function(i){this._arrangeChildren(i,t),this.effect instanceof window.SequenceEffect&&(t+=e.groupChildDuration(i.effect))}.bind(this))}},_setExternalAnimation:function(t){if(this.effect&&this._isGroup)for(var e=0;e \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/frontend.html.gz b/homeassistant/components/frontend/www_static/frontend.html.gz index acaa25d4521629ef498605b3b268fc9b1a5cea38..731cf9d71b744aed1b2198743a71a04aea5bb0bf 100644 GIT binary patch delta 83885 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 z

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 L)hn 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

    ^0qM^VJo?jxp z*5w<#`Pg_-d*9%Fdr^K0ql5nFQ2iQ*v#S-{?;)(1Z61H}^SfiT58>@NxT>!g`{>?g z5W%>P&sXI~7#Ks_IstnMViAYI|zYmEh^YzEaOHyrrdg)m^(SX zm7YfETV#JvaD)@=BD3F-kQ%$wM>Eu;0mP*XKpQ|(JGQF!nuH{}LQ78?FTnQjR@`o-!q>FWfd&=r?twn2o4~r(2AH*a zlSZe?=h=CBhrE(odh+l$soB7g9pZ)AmqYeRqGf-@&y0 zh@bGXgttVwfZ5%ea6bmPH_cOwBNI1u4m2^+y88Nci=(v_;L6PsHC#K-&fCW8eC&qq zoHT#l&tv5c0khpMo2}i6j0xtai48NSZZ22Z=lxnzL0a2zL?6!3t-r+m? z4ao0=)>LpWJ)72}Zb;1bdKkCKqP#415LSxXN;$p+f!qouBhXJ1RkSifI|+Ly@Gg_2 zG$Z9O`(w0CY9P2h7~Ee&CRCP?W*=yiR4RWA?J#({bpm9?q#1jSIX2Y&_bFX5TCLe^ zzTm{Vf}6n;>;o?g{m~3L%Iw11thi|ler5q@N5n%X0N|2WeH{XiYz9df zWCq4#i!MvzA%HN*24Dv;I5>qJsgX!hLX4GOEJThUJzOHCuckVeL-uKI*1!==t8#x7 zx0XUw(r?^#5-O`4&C&BWB%rRJWrfAA6V-J>XD{Cnu~VPyl~Zf`Vk; z8VdRI+dx4%;yzt3njlD05>T9opBfP3%eR3ARUGJJ3-sLw`a=J(CRn5gVUUjKPXP`8 z*dCDkI*l9L%qBw>x-_pa=!;_ztZ&n7?zp1yJHTzg*Od7Be6>nHH!Vcy?yi){ZkO!P zkc+jsnNBf5%$$8fDOs&hgWP`@Uo0)T1%)TTOD2P)@LbT>?>dEdWeiu%d0D<6@5Mr+ zGJdpShB81)DQg|?8e4=#}mmGJc8JnaekOU7pMIj|}%SD_f zweP!xrrh044~tW`?ODG#b=#ed%ftR?oF0zG8AJE1=Ktbn@##Q*8UcTY1mK#~F>V@e za^9X^Xs(0Mel?dY9!1=p*b3INXe$jFa0k|89}{AuY~;E0BJG(E$7oXQ?(US6sD@h0 z6rYU3#(6`#xajw>t?Ub zYP@WzSiWrxuRb!*4UB)-M({p?=Sig3 z(-Do#`C^d4$kFJGBqwp>?vPbp;3u;VndI@2qbeQaw_kthQ;S7cCgVLCbEa6ewi#Ei zQOT*o_XOipT$A4oc)14z{Y(0r9H?E`>?~aajBolgtZaIjn&yWXVo)8h1KX&vr+Sr` zYurW*+Mx{@VqO9^b}ublYyDQf#hACA} zAv-Ga`fY!8X;@_%2fG>EuCSuF7KTHYN!;GxtrqmQNu)od*#T;nT%T=A61_hh|KTFV zexma+I0s_0sHHfuIT>|6`_Y)NjFTS7eKh;H_ zv&8~l2UK?P`1~>N5xEJV)nhDq^5p#diQe5b(qkSe-M`ReQLgZE;-ZU-^v`=wCVq9x zcnB1(%fvR(g^!+2+H@mOy8qZcPjuPSKdXOZqh(B4*c?<9`Ud@T<2X{Vq?H-ODS{*>gXa&(vm$~SCT$FY1RIY#M zSrq#l2odjgjm*@sZq?f@u>-qmBkY5Z>59BM?lXri8=G@!YhumGK57hYWZQ$^Yvfy( zX;p7&;7fJew}Wl{U^|j_>&mI)#ukYG@MsVJi6(6=M74_%{u7yAy6kS73v1gkJYnFs zsrwBmZVVpf@LrAiinxQpqbe5X7yfN#V{Nab4#P>KLvDo&_iyO*iw4MD zWjEVF7jH~cSN_QBeGhbp@U3i8Zdv9U6{*` z{6wVf61pckY?-9FV@Usqdx8?1g$K9f;ig<|H(5=a4ocw-n$H0rJFCM9hpa>1c;d0F z=B?+msy+gq{v9yVu$z=!wZ(=5LXV2N^l{?MtQfrbv@Bk8bY}U0qD!&^(cRPw2s-z%AdchC|{(-EL*%Q-rdy5nvpcRO(g-aW5P&*O_xc2|f&g@WDz~JdT6dWmk=251zv_SBQw{^0VNF*K%r5}Ht_^^{Cqld!| zT}&!_B#MhoVtPIreSTgPBzi^zNOIAB{vpkQ;PVCSBI)2~@uOiyixegaBDlN=F!)=R zu={7W<{h6eklW+L5qe(jF<{VOn4*$@C&G^6Kgrvci2w1yV|4717GhNwPEL_6;dh zbc+iw^%|NUbnXV+V9zPohf_ty7_@1~BHhCtPIgDmGLtBZIXQnt?B+m91-(gsVNMu; z=c*jc+yxRw0|Fy7iC&V}+7svim?^~fB-9<}=n(@e$>(=U?s^n0dZ)OmFwt$1xqb`xTkkhs3>1rCrpN!>)h4#2sEul`q#o2#ELx4 z-#P*Y61=x6f}ejI|AUG-e<(jSkpw6p8~%Z!@1pE8W%gO4kB5JMhNnMOn|ZDU+XDx> zZH@-aVR6DEN@^ip3J?DRN?8pN!0Ob406nq!Q*rsf|L6bGF-a)02i#U!dhLYu5Ch*u zzV1c$CIbOu_|5UaR8^(o_ad-8%vJM_HhhRs3yVRP7aD&`_aZkUMQN~`*76u03N_(` zbG#SZt~Hhd|3_eKbUDQWHgL;6sXevgvl^(-ym{`cRb7SL{lyIOgWwhY)J zE^evaGrPygOj%1)2>~AqTL97g*z_{~Za^z%oH{H{ME4c>I7dHSp#)Xh0JV*_ZpjY` z)97vN4Q_u+l%}HFO8BsC&(>fI6SFQowskn6CEO~z=%bkkY%s4DS(Hh`Iivc)Gv6j{ z9F~<&J?d+@G34djG%wsRmmWPF8ZFs=-qK%D##j$k6={DUYy2eb5mXIR0U~RmV&Yi3 zV5qK)DXH#Ee-KrZtq)|KH^NfXqeE`a%{oLo(6xWlhA+-2PW-UD+B0?1!!nZ(4J!Ec zSK(NLfjvnFt3rD!#XUvc5Mh@a?P3}*Ci^sz30fpm(Ja#+Mg%c(ui$#JVFLyJAbUA8C8j~IRu8dua$`OLBhkRCc}IqS#LSMOKll^l zQR8Mfnt5F8ie`i%Jr^ew5_4M|N$y8DX?uSmg{aME53lEWKYXB@KM2W1E{uz~(Y?R9 zs$ZacS=?B02ZiX%D>)5vThlZqHOJ0p!BOlK%@~bz(onG(pXs}SbxjEFNQYQ*6G9ji zUBv1=gkIXbC`{D6D*U%?9f7e_O-l-C^Aa0TD7c*)V?^}qOU+itrIE9=uyb!>8Rma$ zYdRouB8=2bj7h3>Vtk1!R5N(TyDVY$0&lplte zS~;7;g%yMkdg+%hMqvb`XJ!!XXnk?f+FYP0kYR($2XOxY>c|^5AGq%#I(wTT-#rzj zt7TnMe?jFA1U#>D5JmFp@pfQGRC9k_a~UfI;qs%4{A}S*AZrSc67iNQljgI!@}*Q! z8DwtF9kjN>l1&OvXc+PZ4&#!?tG;Ty(H7&)^GdY{VT*B^g^9q{kI#QQ*1mu1v`^t` z?HQ+Gu`OKk@UUTWw=8s*CQygKnEAnYK}XNMfRLxwMj&Pgg#Y|CrCZ|R(zb?iO9dC{ zaSDh1tfx(D8!wHq2^{A4koM{9Sl*m~VrA*duy(asB)U&HERz~vzTmB4i#8Ljjc9Kk z^aErz;WU+Tp|p9GWDPbAJ>h@(w+|al*zOU7a>()Usy$IKawq|q!n)AHaepX`bM \ No newline at end of file + \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-automation.html.gz b/homeassistant/components/frontend/www_static/panels/ha-panel-automation.html.gz index 804850c2558c6acd2a9a7a1f6e989638511c1ce7..7d3cf0d815209a9b2ba44eb7514f268b69e3c4d1 100644 GIT binary patch literal 28564 zcmV()K;OR~iwFP!000021MIyEd)r2`Ao^D*OpZcCAWiBm(y*>$J2O5L#~ItnOh&8q z2a-(*V+!B^kYz>Uf4}wUC(xj%Bxld=etUApBD(rfU0q#W-Cb4v^s>5IJbQX6lG(GT zSE5Qf)61kNMHL4>efX|-96Wpagn^TMcKhtyIER7>g_1a7HKAWlSMxLG|oSZV!p_4MvU2bnU`sm z=GmwaP(%7zto}4fO7YXX*Uz)*WnSo7GH7}ArxLKAy}r75nSQ?0MUzRHFRm*wuJYw* zFfP)I%L@KZ@~XKthyY1PKs`?XZqKpV5YNP))Oo^RVL}?KIiUYGcKC!q2I=%oj6JJi5n|Wcul%$gi_mZ<;Ui0*2yJ z6lpcim&r7(Zb!rM|CcP6i`$OV8>>mD{r)_eiCHhduI{QL$s{hau1^1;?BGBrg|2?E zdisPp;%P!m<_vAnxh%vy4*rCUn=rp(CW~A_r^pw;u0WPR^72=4aCSzl2>s_=e<47Z zsTiK00|OUn(reBC959e&l0{_-ERu;>wB-LDVVFJYl*JUw0MdZ*v!{R?Pawn*GEfEZ z7pwK7(8PCI34cD-1vB8#x?nE?CG zAmxzEGSjy?uwjzPTwB9c#DmvXM+A($5Yy^I{=5R%1n4x{8bHlz0{d{ELYpvF)c#^! z+t$doB9Ko?QGl!+1s|>KFD{epLd>8I9GKPyc$h|aSze{{TfiLplg!>`3;MmL5Rv3j zrHF+eS%wAmoz+E3QJv#rKU`l;MB$99l-_nhPI{>1N|Uo3odq9B_|5a;N|uu|IqIn4 z4TC87i1c`00cXFJWxK$%kjF4r7@Pw`3dk}W&9Ad57VU<2)n!`tKNbQ+{AV$HUrb|U zYcus5dB5rdtPi!vaqJX^vRz6*k+r?ezdyp-{ymRXcWW3%P9k(>Yhb03P{C}W!hlkK zCkmXq5LciL=n2vdAWIQI{`w7XY`>bl6b zr~)}L@9+5&=g{^x|CZdpy{*5*%-ez%lFddsb|bQ;huSy|^r9S)`137|ZT(@st(P&& zW3yZkr~w8sdm2>5wFpL^^K{l3_^P2*)6-F$Ra;g?>c_~`56o~H1fzCl0{$V%)_rnz zdjF^M{x?r9q96$Spgg5jH+TX+m-(_AI(W6xqec*0pfs4B*^#ouDU9V0j1(n=r{?#_ z{M-qaUvO|7dDBuc=do+%6j`;DV%Bd}c|+ou21Hbacc8X*(&qFO;W*u@O!S)oJ%PPh5~hqi$0|rcq4{HL`4u>DSlAq8og@)2L$S>mdBvBXb5DqmInjT#h}` z)YiKFShB1z*-jm_EdXK7qM^QU*$pFe$XY!_imJE`v$2iad)!@CjRZ5dB0Kkwa=mm) zm_$>GIbUl}z)N;D@5B-oQKu4>WK|Jld9R>kDJabpu;vL9qKc&!+JDEHekvCILjT0+ z#ME#$G=1F9gkvcwpO7d!8=T`jio3AiOR$MPYoGV`Isx?BDu?~qPVnSOu%nZ4YZ&fS zz(=c92>U43jzMkK`}Su~r`IKH_%D|<#@wt;9?;@Q&)Psv!#=9 z(Aiynq5lm!#l46xu4Vz9p<22Ju)~b_uNKDwNt<50pz$|#2(zyojx)1iMh3fch?o( zf1vQ*y26JK6y9G~`1pas2kQzCsp(bUEgkW}W-T=|^|*j~@iSe291LNT?5(YqskL$& z*>w%=Zqm^1W)1DGYiMtihW0jVXm4FZ`l!-Pq@jb&8al9KiJ8{FUF*5X z^NWQ5&2QEl4hEw?&G)BA)4j0+*h7FgJenTW00#(|P4@Tqj$FVI0;UIhC%Y#GFj-s+ zZe)5mOXkxWgjzY8B+2}!2BBv5caIO|`!xu)v$uD6G&?kqi$aKu8=4%6;dE99QA-C$ zlgV*X2T@al`N{0yxDKMW29x8#zD0#wu~@)_XVOi@@np9Fqt@m})5-p<0XtxlPxc3c z28`O94^H-M7@%@1TRXu2Y7ic&0sdEmP)jEQ|Eoc$ox>sir^Or(E;KS16Cs>rZhStS z&32viU21xMlAI(?I-_)Ov`5Ti()T(4!QR23)+~`^A4b(lKjeD$PWBF*bV7f&w>#gR zJL$*FXuHR|$4>eQ^TlvFoI2@=?AUQ~>>`xxGT>nM!0mCe&w%04{=N%foS-KIQ`Iuf zJ~2(FVqZ+%bZ+~2GMUv1aNGOG^U2T!Fjox@cTaX*0Mm84KR8P2Z6n}hC=T~r08w^! zJe(ZX8s}NOJ3Ky^xB#MUG8^t69Jv4@?(y+J?9W|*rtToA)uqV0KRB*+QPLOit~ZlN z`7#_HTD`w6mJ7io-V;1G90;KxhQQEAbr9h&6(@VM<2r~4JxLCarwtI{mrVALCetPs zINheZN0UJvMC3jeyZcE}2OY5p9L|$Qw}|A2$#8PgC`ClyPlo%)4K$eS0$6(9gz=0W z><{LX25et(@cg6!BP^2yU}lhKLM-hO5HoQ!KlFkLrP*-0FHXF0LTj>jGMi1ja2k-4 zgQEiy>`geKegqO{y4!*tQu1gonH+iHG(HDn@4%XJHk`VD02`^~*bAqT+CSJmN(Npy z4cFcfM$(TTkJ)7J__&3>Ja9+T{aITEBEjLoaNd@IWj@p+3^%3OEWOBi^o~Vhjh=+? z(tR*Ztbvmt!suk49M2l{@v?q$d^nxdL4@YP^l&mAG_gP;%@2l?gF1-DXYXYHBxzL0 z>cC)celo9vXjFEO_YO|>>L41BVY0h-BE7LP{9+8v%8 z&i7mZk$WhPk43Enbz^vPbZ9981Rzom4-OBkVI=?&dNA8RN`@{#l6e;--@FE)F7EFi zCk+U7W%uOhqyaf%$lR28Mdl%BPr?V4vkw-KsSix}91myv^TY=x!tc+gd-Ee7 zSmHc6w8q833<z^tI|9v{z!KJYPvkB%lYAD9PccyM$w@qy(K z4Q9uFqRN39O!r&h)b+t&GH8J__5;vQ3}L6YNyfu9m>PsbHb14bDJ0H5~lEAaMwGb0P5_me9)@qUjo*X7q z7a$3o99r6oY@5k-czo;vB!Q1lj%tm|ZXBH))&P>ghbITM#wCIGXZr&ezywZ?aFJhZCTG0|6WuSSPH_7DI^6`+Lb?zupcnQy};ErZot!rQ!&7T{Q?VrIQ1( zTW?2dH7E1KX&pI9?34K*5p|Ga=fk7JI!KaxdVH`~6DWr0^Wps1BDxJ`HFPRwmR@he zc}s90hRJ~!PQ#Fh*}?J93*YA*z;t?e(1IQg<7B$GpLpSitmIAh_IJH-R^g6M=6inp zX^;*MjwicwFZ@Ivoq)jg!g;`^)A{^l;LpH{IxMmWehTy89Uac+1OEs~H54TB&|WRC zFpXQqWg8oJ|A@eod-1t zV+ISM1<^-Oxa*$JED}41SupOFc$Xl#SBDXw)j@j_G_+=_1j%y}Ar6k4SjbbRy-6KJ zVZ!X%#`HX(}Quurd}tq49l+HaInUD|I}sPLOupu9js4n^-h z(SRr{29w=7NMbRa9ydx!l24BIXLXQ7Fge;iY+^y6ljA0WO!dj}vkDay}=&5kM3CzJgqOm^+WSEnTY;lZGG=wXk*M4X5tFIXKaPpy+Q8?Mnh z8G7M+>g?89Y;Cwi{fN)*edzHK@6qnA7tZ6ee=xKbOB;T~ zq4a$3aNzI18nY8|?5D39xI?kul0lMSZ`LwG^3Zy=Yje}2$Zw?jiZ=l#H2~{SN1)^! z*C4DLOp_$puR&OE8Xg~8^PVAu;qmOyKA=_z&>7Of!G66R8kob`{?u9&8N$bOp!4q? z)gXL8CqS_hH3;iOV)tlw&(=0?nSB%d&rNr4Vl04MtnvR`fO|t@0jT$r8U9yq+rGK6 z0IVS%;D0W_ccVi9?)fhM=K@an^auZQ&r)>n#S}CTACT3=`RsT$^+1^q1`{zo@Id(} zcaZES!UJXX@%UtLGW8;bog5s^jwc={AL8yG3hNfcK#%x{_8_sg+y+Wi+B@1m+Mj!% zOsd1ZUDCT}N%5&SOFySG6o$&Lr$5{^uriq}&;nTlO~F!3^9+97TF`@i1zi^Dl?yvY zR%Q*lrA-BFHmZTXMoqo-Mu+`DtM$sGE}B)vmH1LgcPsW2<94e{0Sc=DhGSEt;iuIs zSkHpRO-I+ZX|m~(ntp2w>ReVi9+dVH790zZdxw+VFPLp=G;^CX^RO|Ft+|Js+u^j< z%o2rUicUD5Z2Bh8An-t5yZHyQ?%UP+hnw|tI`VR}l|p404CHmJpWmEz)kLp1TVoZF zPJ8lRyPYpUz)kSK@fub@BMSUa5u~M)Z74crOpi55EV$KSFTByi$#lX>nU$&D!NYz0 zub#*0-`*7egDixAkKepVQt!k(xn8tzw4D|{&dhF_6tm53>oB*+l&+Iz)5Y~nwAt>h z^Yv|*){V&|kv-=od4c4El<`_VK)f2961miA2*+?Nt1psSdR>lomtV#;)1!G#GxF*x z&xon&aBO#V#(tCMj!*7Z3ZyHlB&$|^^tZMhbFH3I`&GW|p);;RL^SG<(ekByl%K(rPYF&`fi!b$O#ZF zUdKdYbR`&}^(lYeu=fgXZ(GJ%w!!0!QY~DE3byLQq>mJoB0Ye(saI?44Dk9S6+ zaslPUtlOu2AV?}8SLk-S$qK$UWZ9OQ6LLlCLmVGhKo5@TPx}!Qr?3v)<|3TD}~oZ&|b7@jG(7dKowE z?M(P>>M*VyuwPrHnqJ77rknU_zivZ-J(D%V$t;cw^03XDJjqgI+1YzG@^3>!WvgZI zR_eH4%aNV|Mdi=uvZ}7zbQrAAJ-DoUR|@U$DbP=KQHo&1KBMFcX%CXe1&ds)E<|Pd z9Lh357$rWiiQ*81I!8UPMc(EArCpy@mnvqlDB zt1n98RyTPMH9`=!S83LB;-}O))>CQXfDA()nYW7Sn|YJ9c|@5Hew<0L{0i4&Ny5wS$oU!i4Lwy(ZOY8S_Na3-l@8k^wXA(XmJ%8 zPk&yQCWr`d%R5+MIX$u*_C0x|cv23_B7Or?rhk=uv0@9@RfH>zPuhkL35fV6&0vYf zmGXsL&)*~Epb%$}xC4#iSw6kS3i=$C56)D(cpWxALdxNNBqAhcfN?Bm@MMOEmA zD|V7cSp?hvsTIPbiqc3#8LKX3T=hhh$7wH<&fpyy&GO$x)h)j%ck*v?P%&Wn7|Fo_ z0f^!P>)hUMru8A~sXw_tf#hxz7LHy5%9vv{uGqyK)u8we_@HBRUM>2FWFcgiZ)L6* zixg5gFQ~oOMRh4kV5S1d_)=2hy8;BLO%0|*7K^?j7SRYLU{uyqEfxoG-YjG@KB#`} z#qEp^?Qte$Q5oe?5`wat_TN1J$H#ZiU%vk7eY`gqKthd1g8w2(Z zLFOAoG^B>PUE681Z3%IzvikI%6pzwZr->PBtLTsxksC5UTJ zGgxku#amu3TZY%o#0BL7`%+Ak+n-@Kxu&=;D_6qHW7pXbX%Y8E;KC#s|C=?iNVJsX zdGgIVV3ftf{_q=~LTT1Da;(|`VQEjJaOVJKHstPQPwez>`nxct4WXN3^`wM3oqf|C z_Ne+LFx&AU>gAz3g+b-%!sNBdyN+x1w3p(;9i?9T$TLBFqY{ohHA#eEVJ!@s@PPIA zzG-hJlA(BHLk(#)h&0tvp307=rEKK8>&1exYfN5Q7lPXy`l1 zkftGx@G!DE^29$^P+|LK_lcPtyK1<;{D6|v!T!suY{poBp&qad@*wj~SLg3p`6Uzb z2e)$DY~@zBa=TG0x4M;EyOmq3m9%`Lq-dLTm8;KIW0+QvSEXu1KGK{K4EjzWQ3q->(fMEkxdQM|zsjE(C zv{u??@p_7m*KHlV+$ef(^~Ba2HK~QGV0ARpQ){OGp+t*nLduV0`xdFK zwQ$We%9n9>9W8q8vLk%5OR)jlYsYbHtDXk(chznkhHDd$p9W;M5hS)OK}TD$YH1wVk0 ztdh4o68N3$Vq1?{QIgkYd}xCyz#CE-O$zu^%l=8+zQV)b4+LCA@cnH{QWB^f@Mu69 zu4w`EFwb6L(qCmt6!0~LljA)md2(DYT{wKh2vt=wy>#P54u>*SsF?sTiDu#hP~p^r zbzGlEA)YP0y@84GF3+LI6zFi|D_Lu1Z0&;GoV@ZbK+p=@ECql({FDA9<$^jtG#O;? zuhW-W9SBgT6V3io$?Hs&Z8qN8-1$Y@t$2&m*btCDop3yEgN=Lo%cOktx(3p9mxGC$2z~dM(u6(j*2#@V|1!6 z;wpQQl(*Tm+n}T*5*{TE;eU4joAR4xsJySWS|R=0Uktk`gXYTlu6CjhNuCWt*+epv z-2zT@nvn5ZwG_C&@77Y{ExBWm(;62N?9orlP5PrLfxT&8!c;d@^Qs>(>aT!V4S`eW zyi;kT2R?iwSZV4!&PieNdw^HvRjheR>fq}>Yye!Ff&P!E)$%wgoi)C*bylCcW$9-GHp4UxfOOnkNPNa0B`J)>C zt!d>oa6#WL)So7c1r2MYE)JKl{cmXzt%~dfr%Am!UnZr(P`?C0-!h^(U$m+$k)4BA zm)I;cV<+IdOHL_63Q)nu&^YjbEnid5^{A{NjD)(|Ye-~&BY>ro6*o-KtW@2yKKg>l zA|=R1NjudkX9ftRFE`f>=VrwjX@^L#Wl$9Ml$LDib{Gx1EUJ5owOxZd8$GPY=5c5I z>tnAU>u`n^yT5+^F}teyhaBt9!4^Zq2WTkk=a3ol_AHSSE6}rk!nZ z=yboyBvpQK0aJ`<6MT|+dqjL`xmd~t;^l71we=tjsIOsw@%AJX_{Qhe5eMr5a>6ayA?0iJa+dSK3;n@R4qt(zy4%?;}yvu#yJ z_Dstj*)bCJ=rO>@`1(B7Qk4H#UOtY|BcNyb??_8W+hMNZ%yTgKj}}KF+oZDThZT;e z*F^~#q+y*hkvl-&2{aL9>$$-ga7VLIGzeVp*#RT-YY&88(JKYYPqxwPU6r0hX*1XW zG!hsKLh9EZ%ddehUM0)kC1A~-cHCduSMf2)#`)@IsmbI)Ungk@34}_|!#l=ue*jos zDwiIlktEo$$KeVF8Vjq6lw5_%nx?Rr*>O^h8oq((4H~ZFDqX(8Uaq@((}dP8y<%sH zX`bDAa%tcSD4X3`_LogV;qith#+01E$YmorbvzA|sk$=!OR1xY+nEDLiY}`KE6)B3^AUlo4&m`7Mqx)GfC@Yhy`J zy|Ki1vaE#W8(gh!A$*36zwI~06s>D-Z7DYoeclM_qW-ac|3dzpg{;2z8iBtTp8bkJ9p7uX{I!8o%8gIn2qhK*|L9Vuc1Rz@+>W} zf8zX3mLd04E`vW;$=xPC*dP^@uP7@#9nds;FswO9^6UaSb3rmBu(Nj1^+J0Pb_jKy zr2>ARB*n9*FmSMgyzcQ%rjsQ_k>8*k;9ul6c$wc&CXyEL@dkdgh;U1@9sCvSu6yLj zhpj!=OjUMX&C)6_lySU+#uJ0LTzn82k-17ffyRDa2q0Ke5sDyc zMF)B`PcI;S*7*xk^toykAVBOX5W8V}7s*viiZd zUS?oy^X7gnp{hMc-myo-mcE!HE|O)PE0u!bG%F8x z(e$K9f5l_##dF%Lxh~}DP{aqD-Db&EI<-N%O;hXJ`MlJvI@UUaNI#ct8rm>BvJp`E zZT6gOJKC*Zh;Z|~e(i#02nhQ->W8&scS-9wmOf{vb}CGkOcZ}N@8YWT7EdEK9y1O8 zg-#hB-{N1a=W-uvl20;Bo8OE1gDnm=s~QdMOvNAYVd6ie-YQ?pYGoLqA04Lc*55NV zRydYnjY4F5yVABifC<_5ynOrOr#G*D`0(+&chCP!KYn=o@)f;lTJamDk?I(Vp@sO1 zJ1^`T=(K$I;d}ZHNZZzrJ=f-vG(riGXaQbN@vjGRbCoNbszG)jHNpPMW&N_YPg8mmO=q0$u^0%LVbn*wB{l6okTu z^h&_$-mt|1-s*-c%NQ*jDNjO->u~$>?VIgw^{YQ$pfQAAcc5sv&SdH%_DX;*Is^0p z?I{SDLSfR(p{_;jG_oKGNrpG7SA^8o(>ZF-u*q@FsrjBaEvI zSxea{T?_BqOO-TNQ1!=m93P8vgJe}!&f3!V{yqpIV_R)(bP1q0ycSTUVFt9+`W3rr zwE=s1OXk|R$qG~kY5_iMdFjv2IVk@m|MH$s;oI`-9E_ksSIoY>9o?z5YjHawEj~aC z4y40r0RIGbBJb2s1O6LO+!SlEbZbD0owCfZlSx3FN;x4Tuh2`^h>JYM=Glc-5vHpV zABMOfA{ri6F?m6nl51Nx?W?qCI0*0W2bf0^)y*U;=Ul5up0W^E=!~FgQZg(Us=C6h zO67QGRTjx}jYg(#DP83vMr-83MNc7xx9#N6@SQsaElW(r+xPc(tFbagOkp#NI$w<) z!xk<%OV8tGZb+?Hm^SJ%#Z$MWJMnn1VYlAe4;L#s#34$gtzZ}v%jM%cl!%sajMmi} zSJ9eUPgPlOs6dfX<+T=)oBr2j;3Rh-v~V4hBm%6&)8S zaqNck@u@M2${#;Mh9A&{eS!0mfSz?TRDMpa`K8(vDyJRA2$IJm5XC&HWpsv}jCuio zXnI9b8mPDokPh8}e|chonr^kPmTkGJd9|RZIYd#8-eTwtf2rEWKhXldxiR=RDvax- zVBC5N$8tv^k1p|6F2=E^kc}2Qm3E0QOMIk~}99(zPE270j8*S=X^m96R8sqfBOG(vT1vlrXV>oc+;e58c2t=C$_ z#<Ml&LbGvoX#hLojjUR^Jf?5y#_--;7e@pG7A z^Ip=MN#`%=l=NReyPRPjQzOm{+p3(gSJ#OxGo*ELIuo#c&RO$ngNd^7dfDigiQ|H? zYEu$zUFDhw-*RD5-mj()8IKRw=Mn~M#2_ye7&m26+Lhjd@Xc$QTO)NhmqHb%PqQQ5 zV@KdmZJeoo$P+x6(B`y-v~H;p52U^?cX{UAN@)c)Kq~P?1HdJuBHk>q8m)=3L%n-Z z<@HDp6$aRGN@AyLMOo44%4JRsNi!Tr7Jegv zJ31}LG8kd_C~ES z!G!HI`*5>r%~{(`If}yZ_Wk``Zf)D?^&=YJgaYSdwT01V?#6u$Lq04>7bfSE^66q+ z?(8sw6tT6rOmHuFc~+i>#aVJ5<1hF-zGQEmB3xab4bDjhU7ii;$4;E7HS6+hSHbq^ zN6&`spR=U7JUirHSdxS2T%H|h;1U1oDc~yQTS#0d(^K4QjzBLkX%(kcx(jnyg9p$> z(_7Wk3+m5UuVMCGfm*;c@wT@w+|?{5Z;p%l%7-Wbq2r731fT23y;C`la>vjJZds}yVs(Gt@K;(F!-1XcoFQ@C5`X}p=hNCFNn)Ar__Ba)DQOgy3d4G#;Q@|(^ z7uY){pa&McUbNK}&*CCZ~>F#ZSjuQ8d<%&sz^z7s$x^9UMsis!Y)dF zgC^611EV7l2-f7E#e>kD2CajRQ4q*bLd6lBe)?82wLC6s8E4NZ_kcw8;o>n!8l$8_ zhccY;etENgT_;+xJs;{d{R3)_7gZqu7 zcGC;itgyA=Qt9LhORL!WuGQNflU~OoO3NLNj6=2uX!Q5Ay0m6SSNRFo*8uI}T}zh- zp1;!Mb9uifb%}Zjr6g|&KU^!A9F$aHSK2)>3lAzWCL~CG=*QL0PF)IC=lvV2*GNDP zoKnvgS__OqauWve(-!D~8g>)p@7Dk%xW7vvu0w63X7RGqtFWEp3DedIt2lB@8oyi; z*+8=^oYB6&Z`1l=f5KUSg0R~t$o#GdwXGZ8C%HJF50a?y62>&MB~>lE_De?*R_*MD zhPtn_A7PrgD^(1feP%2)m}i8|CfH$Qj*nNYjmdqIq9np-lV$6uZDefB(@Jk@Z4|q; zKofYH6S8ou>gq6i-Mh-|qnfX4#HHJ~>H*!p zv3YAf`C%boM55eDL>L6}ihF*4uYbNLhwQwdr2N-6p48Hln0wOLBfAC|J67+=Jm_9i z{zWX7&~bc#0BAkIG(4T~u_a7BM|+*naxxGn7F1p}Phkj3o0efX<73PXKj9=c-7|G zThd(n)%UNokv85*H@c(({0*hjF0_K)>}j_^%dF(tV4T2K0cj|&Sg33U%CdF^#8s(J zrcdZSa(^G-Ic+WV)E3SK#eu}&xJ;ZGbF2|ql!IEl<1t))+sRbv; z1t(rJ7qYV)G#em%stBLbqji!ro+&2RPnkVnPisDR`;3Ls1qHg-cA=Frx~Ap1eJzh3 zQ56YWXX<(pl|(>pe7dU_SUJR`B2PuS=u+ThHQqIeATUPq6ko7{EwwhtYsplY%V4SH zh~h%LcQYqZis*YlHBMGTTA)-jF4M?x>bKf@Unb@Ecq;=ny+uiSLr%6TaW2m%RwKW7SI!c>2*%5rNCb9M)HbAw7msJH{VkM`^ zvtm>{OI9o2$>T%U7WOLG9^*;fS+w3mwA@=*UP65ETdPDR>T2vjy)AA;wg&A~W&^x< zp{xiA(2{q$Jn zdz-zWdy7`TMWgF9q6kZ^*yozouJxd276;m*tBSgNmUX|xXOe&{NOX?vi?zMu@6{%U zq7uQr_waH7<(i*^APkj7XIM)^MZLv~4GarGx zhc46U(C@zDQ%6#A4thMoB*>5rRe$>8`dZw5niXAVzN%!y4Mb`L+U)wNur8ho_sU80 zt$S7~`GD_;nv4MZ-WO89VJy|ixqh@hT5dAemv6n_TwiRcBysZqj2(ZSYX>EtgGfYo z{6QKrv>x`Ai&;T8@OWL?^&l{)BY?Vg1~Ms~C6!R~s`N~w$Ib|lV-|yt+V0c{s&Taw zbueQYbe3aw#jHWu5UEH>$oflJ8Nr+xryd4IDsA#0-V-NAW{CKSV@XQiRjVU&2Kp*A z`vJC9>uy^m%CrNot;P)sIxAS*OhSL1sF~bX^~xgh3mWvS*o{WrV?Z6z)Vl+cFP)VB z4N`>LvT(gP9>}5a!xgz3gK1EBK-xQ#K?+!VI9+MeIM4qm&t2aMsIPd-T3K`EG}ZvO z+Qu!RL|Rs^Y%3`gym}MGazKKKnWg2WC!3{SZEyQ;8?{fYUh6dv>y-Xvab0x7wiS(I z@Y2yUz}69h5w(fcHHApadY};Jp+e2N8bw*#Wp&7)@6!f6qE^}#)SGI-(kF*(2_?^G zgCP3-n9(w$tR9@1ZE>W<4K2tTyOP*SwO(bC=Io8Wm^YaG<@kA~b|D>Tl0J;2m!fO! zO&-^|-_Ws^POZmHoy*rwpv~cu)ZpsVR^2Sk>ywQQiPlb3TS>PxFwfpb$+^bVZUrbb z)@r$9`|eB$JKt>_=Gcm3&%NCG%L7R*-?mR#MG@%1YXCJ0&TWt`N4@-*VaWje5|K^hYH^J zwk}s{KN)$x0*&Ii(P^tnIBHV~(Ix4$4LEA8FUmm_QuuP9cp1Xiz}V1b4=tqQJSKzb z`}<5TbgLX=G~<0KD#ZKNM@V;fH9>b)b(s?R|9Eb=W(=lWshq_o>n(? zdZQNDs}DJ&v@(D{n1W}Z^htDcblppIcgsI+-(2vqU)v5toC$5JKvSnp=XXdZHBz76 z)~)X?Ez=wsN#A!1A%XD`%qHhR9!#PbKCp82q=bdOUL^9%^a+^Zc1f}ALB zH7T4UP8Z}Ja;i{J;!9e!l(r$>!nB3#(HKD!E<$#jHGHP|^7cnFoaVWtD6^iC||8J5Ut` zu$}>@eJyW_DcU7Q(S+%13lt@24HW0-HkL?36PhY+Abde3>#j3dtT=PPSk+#spyK8iYb#Jjg>aeCdn>AxI^{CbvnF(j+ zDK|5)6%8y-VX{DyuEs4^+oF#mgiK0v7#RmWE}HOG1;pK566bx59$n(<$+o2?TOwCh zP_q)#Xq8?GJe%y}Z0aVkY){b`1pCAFQ;>)px05*kf)^Biwd!DYm~-7AVnm}L><1vV zR>}5u%A~)`Y@A1V#2Ai5r02ybfrXd&!)ZkxX6*zcQ$47DojH1wZ3Wu2EY-$7&DY^9 z0h;1DCfnF$HM6>axAU-iZ6Q~mn<+~Kp@@?p*-(>b4?e5q>H0PYc7 zJRABxpMC=Ex8=%u;XunXZ>qI5j0C5>F1baly>=(mG}&}fz?o!1NV?`#3-yZXmbPAb zL6-;Ij$VjDy+PJFe##cLJiz^n7;4(yuJ}A`%S;B`5Pm3xFz=|LpTXkP^k3IR)hks& zo~>MG?O7rW!ALQQHHAF;%Q}gTcfzw6pSm>hHT{F3jz18}4ZTK(;e^AX>kV+du)?ve zpT;H6*F}J8zl)aM*^;!qk97}>dd`L;#&1D2+LVS|-bY0|F{qUtLB$?yIKZM86$$e5 za;rV2j|nX%A*07O=5Mdm%eeJweG|lE;I+VjBvC<2wR&$JA0#wSBBR`2)X#h!bC&0e zMOWEGMq~ns9!$6dF3hW{yc2QXPh6l9?YD@8-N0a67$s$Ar$D_bJ1fo`(Ryw3PsI*i z`GBP(yKm;X=Z|Hba~jXG$vtY{SQ)r3S<=kly?P6SpLO&ctV$2+54aqNQjSAhOFkQ* zRUj=x@q+(G{QZmk{$(W@yUFy;J41Txl{3nY#ccrn(rybyERA7od79t~skPvz6=}ll zZnCHpM{O9OB?leZqmkVbAD8${mSs4T+va(T|I1peSP1?>i20eIAy>0C&w}E{!6*s1 z-qB8**S?GlY%|b6^wyPIF;-tbKaeomTDbZy@V#z`Rg+k??oqk6%JQ3##Gk(8jpbfNWmG!nsQFDVWqNO}{e46U?bc8nOB_xFI z?-%+2KzeUt7^(#*9{QtFQdrm<5qUr(K=jgq!s+7a;IuIJvd;!1>+7ld%>lf6MSn^` zyHvnrt1O0iwF={>E=_U4bYYHNsf?0WcAwp7)oP83@0g!Pm0~PrEA{=$ia45K0d7ys zsT3>fFD=kQRucEBz6FeA`Y&$!FQ%sCOIp^d;9E}woFXo;%q%dXnyP8n2i6sO7lO>U z5a{;giqOmCilAGPOM?Xbq8MsXv$^)g1e(e1$HuXMRDn%n0ImKcm4m+*7$c?Vj7F#> zz_jUp6W-~!0O_HvTGqaPzrCdpo1dA0IrzK{_ROs&;7B?)B%&xE+2l zrtw_dBjW66()!+#YkfS`=e4%(#%GgVu=`5gx@SDpt8^TXt>y8#_Ln|XaSAWjQW|d_ zpRc`PB8#5&S?Jc(^Ee9G(3_Lgb|ZCQA88-KvZwu75K;u*Dmwxv_ji&P);`H%c@uJB z=g`G9VE3QfkSV(}yx%dP_C)pd67RPqf9M#^ZXoHXFm1}0wA21W*wF#1(-+ek+l2Q<4Sce}*W_0whjqIjZ^`my#n zhB9wh6RKwu%CMH(lolrZOgqio10?<2$ba8(g%24H)O;!WWRAfviv!OR*5z8WRu!z# zNMJek_3Kz{=d>mm)S^$%7$QX|G*qB<0A;-FTuN}zs~`+V5BAMQ+TXP`wznJijMlC{ zsB2W$Bl^Z@xAx7uhBW5v8l;)6Jb2p?e7si8qqVlnwe_)SJJFbb%5JGHuQ##xsh0`c zWdB;@A7h^81XvrXy2$>sE}QV6pdqsC?rPzn-&Byt^0hbB zPMbzcZDY`0d5x$|-0|$qw-oyh-g3WgLzWlH30aGc=XDdPv-8l&em!jibR_@xr zTK4j%xw1@ucnvWKwX7hu*pX{qOLh064;UGKNU!jybdx78?`AUO=jdQCh(v;}9;0A- zJxQm%iTE`I4QkNek2(YR|Nd^&8HPbLPhmyD;NO=VN55wEf@is&sI%_OU|hxhy=%7e zL*BU&la9IC?tt13=))S^`2fW0$g9@Q4dBorTNBwr2hGm${p_S(!xAWnDEHCTrXtdO zSL9b7izYMz?{kjOxt`al?hIf$qpgC<0KXkezFO8*1iQT-agF;TX3`Yvwqd!aXMH5% zJMA(8+tHe*2<#d)^lg#i!(V5?RsQP-H!+Cn1!X$!?D*ssP1*9e(57qwbT5n0^0kZ{ zjWE;)T4eYG=(byH@zKpZnTcL%?ZUmsH(mxmkF@1U!}d%7)ie9$N%nZ2&w*bk?9X4t zEyaR)MM+%|o#~L%!2ovp=4%+N-!{l)XU93hDI`QdiG>jJ_e&x`1=u* ziq=wwA2s;zA`G?u7`kw5d5bJE;g6$Ad0C{{r~gCgQlm-_2sQY_N%OzQWTLlU91?j} zF`!LQH5Q&hXAro(erOuX_t5mJ$CcuR!7trGXirbcnJsyHyMyJI@HYy&+O>`~FdV9E zldGLZq4w(?>Ek)#*C%@uypbR4JD);8iS)A=FOwM#)985lWh_G#j0WZfghqq%y#*_J z+8x?r=LJ8VU_T9^vh*-08@~e)uBln)Updz@ck4>XJga{FhRBpEFB1UtK*#&cr}ewD zrH2mkeYYZ+rJ(BX0ySD5ylBV5di5fbc?+09#cks`jBqU-WET{r)j@wRp%+tN+MI`- zW{3G*vz~m{2^n=Plkjzq-VhV;7yf9en#+1?m(>ofYGqPySZfNKUj3%7`JsoeV#J! zIX@3NHS$0v=TZi<$meEE4*UHX%wRRe56!u4@m-D6n91f|@nEJbm;UrigzM*a5QM$6 z?xa{!V=m7I8uQb}*;~N3rIw9b=E2myIcLQTw1@4(QD23kbywk z>5%k~^zGm)dB!vosJRRWgGiqw?E>dxy>K00`~ zC3FIR(2!yyQr3oE1o|uP;oKq(1p_*k-3FY88#sFbLz*S3E5>!th`50R){bJR%U*S|cr*Fsuh z0(&~v(wS|C9m!#rJA!ar%Zb})W1fuu7WDc<&CVY-=wqJa7;zrm5Bo5uUM17Zu5I9o zZo4tP3Sf*genb+#0kQTisY!9R>8*=pdYIxxg{XSv=L`3BKN6jeUSg?32sFwNg>&(! z4ZHgw0jtHEv?%hz+}t$8q7J#AD|hu9nQP)`bT3g~=ir z_Zn)%h}>nXl^(UJJV*(1Eb}H=f=siA(#jq7uK?WUs)OW2Z{r=oj;@F|@;6rNdx(O~ zD-eoi_I5xY@|7omWKWy^$`6INN3Y9wAHK))BC_vRM`+D=un>HQ|w8G^nk&w)0Dq0?BQs`p9-CBj@$l`E*^Wh&k z5ja=*g3to16a4UOz7` zo`6<5ctWx|z<<$oBdxuo@HrJX-{$m;0-jTMf}Lt7z<;AM4r*`BcIbKAjykCA@DXi? z5C1##=x#@zOY>Kt#xTP;3vT$*E0Qy~pTb#yF1h7S9Q62-wr7sBOW13QZf_V3!?8aV z`c>3|pQ>I(c@qZYrxdaA!hx$9v=gXUP_6z*4b0tK@HIm4mmgNWWrHV^PvEO1% z!)7?tbcO{TIcA@y*H=(^{!&wYaN`klkXzzlcOTDfK3_b0IurBq+0zR;zex(*+0o0s zbYl4IDe4X#fV?>Zx-Sko@L%uXS3Jl;2>iLg1)i#SLe)K~&Q5!|jng%7>J3?ew{R>h6%z zbF;B7ySc8ANY8>uq{3LtG%b*8plQ%)uz^-6I<{(~r z<@MxJB(t#(27`J9Tqq?A2}bqCeg9yr>Bx6oK%O#Rz#7)xIey%p;iUk^oZ)q!#meEh zd3V@eg}N_vDtJ)H>0t!{(ZSm{7~4VnWv*{-N_GVGxC`n-7hG8%@GOVcc_rs+*;z}vGcR)~-&%>2j0CKZ@wD?0>G`JBCzM*J*l%d+p&3S% zjgmPmH+O68Fdm7#nkh#>VtLRy`ugj!Tm!U%wSVv*o>}$>PJqS$%DIS)^J|ZeEn!}^ zkor+{`K_|dX-N~U&S&+P6y0)C8d;tF%um``lE+dDn-o`b&{B8T3DQ46uWZN+jb6Ll zFg zJM8bW4qlW5dC-~$}+hSh!-;}H@UGTP@9#J zu@Gu-|8I|N(Z1ttGw9(7)(msujekMcU+?Hx!D|5YU0z(t!&EQ)XAbjk2a0s^1bCxWv5=GloLeV~^+xV@kOu6fFh#!s_9w?F%?6V{YIU4eTf+>r`Cki@iv}Qrok!c8_mNhqmNB z{lBl%LYoq)&+Tm)^Oi)(y4Wbzgp$TgJYUh?Zc*a9Uf$V;5oUakFp4jrGti~3un1vv zq{hW1I~fP+)^7`=tcug@G^ia107Aj2+s&Zk9O-v^yPNOCL8q}L$16*0+g`vtGlR4& z$x-sl9)B4wN4@RPZOdonviRaJT4;CefmrXi>HJ<8YO@CEgJ7< z_wm49o+6v$V|_l0#|zMlUwe4*nG|RMHBuPp`!pY{9!RY(FMBb=o#!Y45a{8#;fTW4 z_waiK(!)9~hc2PHD5R}aD|gLanImM`Cpz-yhnxAgIfDQSU5X;Dj zs-Fk|$r&~LfeBY2Pe=ozRQ*MuYp1$b?QUKk+eQLNM|R-Q9(GAH|X6!-FGd;25XAh?C0H{bNi6*(bVr2vj)e4DQfCdfrnxUMn9h^*$L{IqEKkm7_m{9{hEGDHGnqEXI*QMNDYQ?}+gpA?lWp}LVvA;K)$v(s z$oxauiV5@Fv{HbBAhuPwQxR_sN9svzIqzYQ7n05812Unn@RP6UX-h}e>XbvYJRXj> zMB{;AUbIv-0h<-pr+srL#g>(#RhxC6NYJ_zJ%zx9`K=1|6^r|O*05m$EB|thMl6)U zIj@4yA($n9`S9j@Y1T+}e3ut&@5>Jw$eH88$@e;|)vM|hUsmOhk&vN=^@at_%&Gzw z(q_dJ>z%rC7GNY7Mox;kX9GM3kZ)7j0N4PQ^bCZIuPKwmkxrM-!xXX>70l_WP93W^ zw}5ootH1xRJk7en(@F8 zn4Dy1_sRB?i>oNuPOg^YAT-GVC;$68ublL+IsH$2CrVXAW)WUK;HPiqB%V&4uQMRbClF4Spm37}SW4WOzGeQ~2&FT->UH-XW_^cOyhSE;kL zpQ0k>7qX&M{Ycc0h5R8O*U^q{>g;;a>vf*(j>G4?@M-wj;+)@H0ab&2^D6e!DFk}i zJeTF~?`1&)HBZKwq_N6B#zXRM8bhgk3HrtMHlqhxOo~Y%qnTRhY1~r637<6BqWs(2 zTlg$gdVdcU(g}3bO=8cxks0cM?6#Ahrg4Bb8MIX}@3>+*Z$r9iI0{PoX=+I6$;quD zD1yoMc5#}Y<>r;Moj4ukpmY6nn#cHXYA(@5$Bcwrt4i`e)A7klx*S123ZkrPL z49ndXxlb0=Ej{4QKjW-C59O27mOyG3ZK zF0`g3nKg@lC7$~g-yj9zFq4c!)A|>De^pnIVsDI}jv6*Ss@eU0W2CcFO)J4_54v)U znq~DMonr6x>FW#9VXo23XnQ+B1a!u5guZ6}yucqOqv=7ygo$x_7HcSj-iUGsAa6|CEpMSgp<2$rNK*mF6iv zAf9>ew?HP!L;Xk}zI}xg4*tYB{G(Or%-~jXzj+^#o&GleB_Md))3cWP?jb2`gA6K5 zb|GX>j~{66*k7*aphezmW*=VfRytbI1 z2G=l&=NJVx82tqw9paug>ejrF(vzJb{mD&>AQofXQ>knTvy6f!0Ikncd_5W^JmB$n z*hH08HwjNMkwTk|@Yiak$uz@#bCF+{i`)02dad>yOs1Tqmf4Kt{f{3ntE&a|-jF&E zkaq{rYLL;-;kkMhD1!lj;mpkLNd^)B>PZyfi`rRz8umd=XEJqnfx@RG8JcgCMYCvu zJ5=xcU<8a%;OYY{BB}X|?^a=m@ket*3IqoHidTTNl)tw?Tv5bU5l)G7c^!c<24aR0 zukpEDQ**?&?#d>4_l{RItgb;<@lXF_bgIb0ZQS3}IOeCgNv~DwpX9@nlanV@ zSrFAIYsh7zHu9|dIPP>TU|nNAy16K)69oGvG=ntx=(FhSSgW z%ojfIDf)WJdYR5-CQqWhy3CFE!xx(Wy0Zhk`L~$)sIc_9qMzSDXWsw(XB7?NA2Jud zvD*EXd6Iq5llVecn`#-33#}!Qu})CJ9M8)njC#Gl0tWv8EiD3-5C{UgnnCx%me$gZ z7L?<^k>@&bsg&3#tQ)#OXpSL$+Jn1dKs}DefP(v!m(-v6#4aO&q!U0yjX;I1tz}p- zx%g%jl%l(KiK6)@olx;<+AHWT=x0EK^z7Snd_6p+hs*RN@#s0KlRqd@kz4=YVsaC9 z^cP@sbly)dGTzCNh|$pP?Y~7p0hsit-AJw4Y6i7_=x*6IyPW?HNG7!SrDpU%b~)vJOxadP(YJo*&hz(7S`;`#RW zr_&p2&N&~j++%2uPkj~OW6YHKa@xJ#*@?=tFX!^R0r39e>3sYH;ynS4;)iqSC1HTzxA6o~QX*(8ej8p}tWuu6 z#le3;KO+1`QR=$aGkVL`3t)w(m)vMP9e;j$IsVMnXu7J!*=MLK?cUO_Xaa*7-o1!# zBm7jgeg=-d#0WE&y&ioakL~P?$^K#mcwBT}Kv5J7(C-)W;^Bv9@eHJ!Jvm>5BZMZ< zUBaJ!?hMaQmt9Q5_0)+0@*=`y=2wsoNXKhU!}qv8l%YkH_fYFq7ym}EBPX45JbfBp zj!hE<$w;|RPO1e zz_+65^AtnmkFcq***F%5rcKXY*kO~VX46c8NXFe?KzV|xiGT1(@lc&NmmSoZq>%KKlHi(P_8fV;VYJi{A59U_tc)PcZO30}C5VP$UXj2S|a) zY>ZR$!d!~ySoFMHdhV2kNd(#-tpMMGz8O;n^%dpnY4a5Qt#~5p*G$d(4(>5XN7?hK zMktnv$^J=-bkf^QTrA#N$Pd&Q@Dm>@A_adAGfAH7(I-RcJPKu)4aM^)P=F@Tf&2UP z)Y2pWo-P(m?NX<9Q8GBm@5EH3p9P&hG|JdO7?uKt1=K>)%%p!4YfUh@Uhp?{(fT$y zSqJ9C0zWVp)vU|V7fn|9%ULiXi)^Y5BQz|;SU~vqmE6GotB(P5UMS>$qRTVt5EAJW zcl@I-Fe3s}pzzeNOM;{d7Us{Cs zsQ>SoZGMawuxyWSKqa`@-oB}csQ263KhoJVXhk&XPd{~Uq91`@OI%t<-4F3iWOG4$ z6MyW!ha7 z#9={o7w{RDKtTQ#DrrC9|C)JT#`EqE(Fu}jNOc1MlbQ$#%%0= z0{Z+Mi}BC#&kfRz!|qS<&!H?ierdP#Q}nXsQ2Hl(pjU{)7R>4V^w0h4th`L;cseke z0OqiruALHiCX!C=E~D#c8b6rnkJLxwCVZ}vb+%l9KzvDG9k*!;qhUuj&R=#1!uYm>u#5UH?ng87q$V<@t-M4t<1fojvb^%k+ z!txsR78IOD*+4|i#y~*;c_;lDq`hBML`^?qvZRs5?@f79-YxkLNjb;xR z-Szjp$B+?H<#kzP94%mV$mBDeyoktnaI}h;pZE9nN#Tc@o;UASk%(Yrz>wqa9_OXe zsK3Lt!!%`Ljk+dTr`efKAl*53;UlHr)w0=D=NTKYb*(gVFauf`+fOu%J?o?M*)LnQ$F1ct4p+=!3_@jt-T`SKNyV+pOHg}+DX`Wq?5q^>xbpg zu=77-`%y+?t>9iW#{+bd)BbYm7$@gT=e#en>norh&UyO-?+suNq~7aMGC^)T@d^o@ zg!(r{T1l9Wp32u&`UxJ~O5wgFhxI_s9)-7D64X!uX+dsknxfduDGj9|?8iaIymM%3 z%}BmrIc>usi=pe2F&jGGAZBQWU3d^Ko)3$N<6)ThnxJBHXMk)YBHS9 zCPST7;QgnM``%wedmZrwBQutCY;#>!9g&i`%|uWn#ZF#W>=@Cjhry0Mv>#iW{CY4^ zXxc$)X&9w{M z(vWren-KjSFrWKgBr8MzjGc*XS?`2*ucdjqQk(wG-`&da(*3>UxeJ%)sxY(+-0{*) z$t@m?e#(aPC}dR<+j9Ts`?o*z`HmxG&vg4SKqommdOFc+@yHC(9|+K98d za-L_A?DZ&Lk*N17G$FnPLFl%gL9N4|AY*U)HPU99pb9Nq19a=mGtH*V;isY!%rZ5e zu&KGbO0&O{f$QD?)))E}pzUz5(mM~l`0BHhWE_~lfdz_-DC@TRUdfK+5m|GL(kLJ& zi)+zS?oRT}1W8To&N)ozRrft;(xQ#m>#Qz*Gpid$7luh+GH=rLH^T-+D9^Fw3AJKbd1Y~@eEzC8Cssb5=YauyZ=ufOv%Y$w(OFsw9ikW(e zf#cRhcN{7tAZry`vLPeAl49yrnBfSsuv+<-7k>Y*f^W)QL*n*6fr0Z@@n7 z4DrZe$*Q!v{Rs0FN2SVP+E)E}kzc{iyuvu~~G&YLUExR3j2dY{ph-%_9QR36#lIs5=E}>i>m0dnhV9hwl zF+kn?hFB(<|RVw!e&QqbRxOAg21J6OWG8%kz^oQ za@g+c{-1+@DTIET$N)m)av}$45vQkq;p2_#rq>6?LMj-66OS<9X9QI}XfR1ptM1T` zY1E8Orz5I?!~yC%kCd@1qG1`FByCUa7@-8rB6}mk6`p%%-88!6Xj)YyDQK^-#R^}! zvdIwql)(ml3DXZY>zYqsNi)QZoF%We)a7QWGo+X%#mtbI8oQ&TJJ`4Yh+mShNawtf zdDohR#u+pW@|-Km%s#6!W$YqYRnpY3{14re9BH&0nC!E-m1bZ^qwG`(w!U!@KL(fJyb6n=V z%__t6I6JMBg^h@Y;ix(j=g!59_XOY}S&GH$T9;xFiAfo(4Ebx)#yX4!p(2!2$+c7w zmTFNOF??8Qb77EBi)9DKkn>uTMbA!a5}2`uY4ChD>!=wSy6X1gzf0W~wSy;Oa(Tz( zZtt6kn=t#jqpIJuvF8zp-m!m{b*~n=XI`PT*KeZ!N27E1TMigxS=^$)I+2vLGm*H` zzU0vd49~F|y>H-;-@J2G*NU<_b@BM{u11yACl$_iK_6SxcOT7Bay9=FH2>O#=R!m; z>6uzq4?akBe%7H>z7UOGu=+^J_w$RqsADD8FZ$)wQBR2)622?&c zau4kcc#nYl0(IPoHx|?XzqTvuZQBUKe`U=FgG8t!y(>pH3?x7U^a7GR6oOFD(mEm{ zXaAkKxSh?93kXIqw#n5I0(m#SA_9h7L(tV;(1PrVR}b zM7Z#Ci%q_S$4NTxqTER^Vm{Pb1>$S;(XMdfMz5_>xInMq3vTr=dBza#o73Vbh0;g# zMLfp?6g!Q5IXB!&Yn?pK7FSdi;K1%zMWbp=LJ9m?X$4BNz{6U=C3CHctze+4c56LU zZyQzC>c-RrrGrdGyj^gH)MmGC${T#8m){8Dg)CX(MAQ9FIS#q767I;XL z>O&A6o0^uFDjmkNJ-Ak&-IxAT-hk{(HH~l|f=m29-KI-AM6C(6!B*e#eT_fq)PC#G z>-$uMArdz|$Jh4}zCt%$XyEZc6J>G6&<8Vxiu|Ail~srIpqMj~(n{`mhyTa%I6|)b zXw1j89w0jM_v3MP-%cqr zmTh*>;wn&kUH+?=4($(FVF{*R1I?CS4i)gHafE(4iC(MWw{_@hW=+f7K}=FYREt6T zofkKjq?amx+gT6SX;`=%zpwD;vZ>OwNN%P!9IM zr4fxt83o#-#H0a9&L7k%5yKD0czK<`^oQ9|d0@7)q4HCYaaV_)!(exS5S1~6R!8r> zY?PHEBP>vy!e|H}F$;x&vO_Qi&o@i(pe}B8qAVZY(I1YD_$u%vuo8Mam&}Qz{_MP~ zU8DCurCw$3#+Y>W7&TdFV$#vtJS!is9X=y26F>|?i2x)=S2|#H{H|NyBkGAVp(2G@ z5%Ph}_`2j%-k2^7ilm{_EIE>WHuS`=eJ7T@o-EnS47Y;OeZ-3xw0@Gydj(L~@>)0j z`L}(+)6>4`HjN8qPA;9~^G$ZJcXZm#rh?pQ!{o7Q@O4lNWhJjYx|HGW^gJ#RNr`uR z$Mh5>E+xsd7O2XU!4t2&mLhl25Qg>?*9_zni<*U%XgTWgrc4v?laf5KiNi(Y=2D5j zXf=`z!FSuHk}Wg0jKdAF_ln4P>>tkYuMJD80jg4=D;s6$vwo!1bs+0DGVy{iYN;TAXb@B%$}?xwn|>|I;JRx&!XOnJ_;Ht1GzH3JD?;;cOs-V$kpRdB>{6 zQ(t>;!NJZ2Rl7)%7q9Wk5k${vHfgDAJSNY2#x;0+j}2_8sO@1b6{a-u(Ga66f6}ft!z;7A8*UiA7lJW4*nO^YoUfv>8g8{(T|l0FXv+1_)}Zg8 zX|9P=liR%UodAn6#|w|62X(H`Bgx~3H|64!t_}iDE%t&duvl8rPllY@F-R7KaS$AU z|HV9>2s#uVFhMlwzo|5yyg)>00+QDB9IK!-FPBTRg?HBXqT)~OcB}VMn?gf6Ez-X9 z26`<9|Lky0ihfR$bOUZPpBq;UF_9(wZa{E5y2hr_8|5b3?L4vNZ+`yac+2nLA9&-( zI(WbXKS3{%4GFp7eS(#1=MK$GV24{@J94#wjJ}p4U-$v4BBE5KVQSgjP#DywjTl!E zVfeoTU*i%nxyPtgPVNIx2!;y}iqQ8p+;8mJKhMeU47{$7?@*%Ixp&T~_v$^eFsi33 z97aq0S|5%9II?Ckbbp7ivKh!CHL6#hk0v@O=T=Y6uF;Vch|3YjY zMd=9@Bf&rGb?`f#zok;C<87`)Q~U>Z7PRuQ_TKrDX@`En`78+l7fgcmm`yHnPF$FY z_GSAfVp|?BnKz$5pO{Q6wuMyP)A3pH%3&p)6`WbJnHBSn^DVdgyweT^&!R=VuH>T$ zi!ZUxd?k65t>HV#b=LK-waZTG%77bvCc;I`N_b=jd~I+UBQ3xKPs$~xl_0H*-}9FdTX literal 28488 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 \ No newline at end of file + \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-service.html.gz b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-service.html.gz index 1cb7353dd333632d705c042518c9c80cdc99da34..2e9dd6b4bcfe3d558d99c7b91b8a8902937fe5d0 100644 GIT binary patch literal 23716 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 D9>b`p diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-template.html b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-template.html index c6005c3b639..bb27f9a2d7d 100644 --- a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-template.html +++ b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-template.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-template.html.gz b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-template.html.gz index 32190ba8cecce916739d3adeeb798294741a03f4..9c3063c0d6c27794f6ee9a0f5f60e4524a3f7b9b 100644 GIT binary patch delta 6163 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 diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-hassio.html b/homeassistant/components/frontend/www_static/panels/ha-panel-hassio.html index 906a7294b1f..f339403019b 100644 --- a/homeassistant/components/frontend/www_static/panels/ha-panel-hassio.html +++ b/homeassistant/components/frontend/www_static/panels/ha-panel-hassio.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-hassio.html.gz b/homeassistant/components/frontend/www_static/panels/ha-panel-hassio.html.gz index 4e2422b0c61cad8a13d195353777398e5643119e..6a1c2905cf0087ed1d383c04a1cd8ff53c21f228 100644 GIT binary patch literal 378 zcmV-=0fqh_iwFP!0000217%XdYTPgo{S`&0U9i{W7L3=>(uTc+1k(1hEM;QNA_Ylf zq;VGG_}?qpO}5aJX5PFR-WyG$+1a+y2&!!yGKfw?h{${S^T&O8C)=i4i!Y?cwo&9t zM{2MrjM_^LWe*;0sUb!~iOuMG3yf_Od9>IbwNVQFX;LPp!dQFqcw<~ofx+|KR4cDp zCzKA17dhU`<1xRdlN268pi4&9C}UC6rF7_r4Cmw_#kmk@V9ekWBqUq74o}%tV|DeD z1b4yo+&+;V9fr+hV*Q`Nq7T$#V1u!qGFCsnykf`2Dy;rWWD$JvA?OoW#C(t~fkIVJ zJofm>cmq3NeRDg{1u#RW6XQJijt%+EcDfj^=(0O}d4B%=?fb9ych)BE)9f`yHPw0!)p9<60L~?vHbnve055p9ga7~l literal 392 zcmV;30eAi%iwFognHpIF1889_aA9s`Y%OSEb8~5LE@*UZYyfpq!HU~35d9UcP6^mC zdn-mUw6seurG;&K38Bnd6Qo7b7-_u0c>V8{;w@<@J!$5>nc=c+@ z;WTTTGBLG*0^V6aP-Fx9~a4Wh(*c|4Z)bdn-KjC3i;8Wk)Vy3`)SSm2U; z&T%G+;M=I2-4r!9^;upY?ZDkva+AlnnQdzSu~Q9^28?VmwR6GRnWq8UFHg_d^HQy9 z-oOt;4k0YnZ!v%4)eE>0+q?Uvas(Rn|LCOxX6Q|>IFF%cOJTE}FE(hp><;fAAAf%Q z^yBrFjZM3CkB5lojcj1BZ`PZu3t5HHx$2K0;If&Gd;sfE3no#N2sS7Vxo>AlTpPtX mk{4;r)?aL*xRcvuyDZ!MSL@PLvtC1Uy`EoeA{|mh0ssI`D!+69 diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-map.html b/homeassistant/components/frontend/www_static/panels/ha-panel-map.html index 345b2140db8..500f812a738 100644 --- a/homeassistant/components/frontend/www_static/panels/ha-panel-map.html +++ b/homeassistant/components/frontend/www_static/panels/ha-panel-map.html @@ -1,5 +1,5 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-map.html.gz b/homeassistant/components/frontend/www_static/panels/ha-panel-map.html.gz index 9e633a1d0cc19a0679413391f308110c5525653a..a5e2b5e4fffcc75f69471635ef30940c2c52c673 100644 GIT binary patch literal 44245 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 Ne*wNr$LO120stw)@G}4a literal 43670 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

    ;A>A% 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 s0C8lu9|(4h+uVXIopU z+7!Bw+&(pUS#I zPpqY>o9%+LvpsRX1|t`)GvTXZ(wTQ1EX=Y@CUUUB@o$!37PY!?-n@SI-tiZ}6*TRI zMfdOh*u8O{)|Ejl$M12o&V|EQt8&=r60^Yd`E-K36UxAP%(*5lqGo_M>=IX zQ(^3U_VGjAbY`i^idRs!69t!Jus$EhjHQxAB%(>2M}mkv%4jYU7ODuvk`4vb6Kaww z9p^k#d73CCiB?IXGoh%~_;*@QQR#Xd#lRQ?nQ_LY3MI`GL1UVykcS}=a-${_f{>IE z3QP$uG9fh=s8<06$sSVELUUP27$=Z`7Mw-7NFyHWG*vPTvoy{Up2vB*(Ug-cigZjF zMVNS=#*h-481*nh{Sua;O5Jg#->oG&QaV!!YM~q1sBN>Q5kMLZeXGs)%ZBap-g*d|! zuA(Fd8pV<-#zP*5I#oH%?kQ+stYV%?!6XZ18i|Ca=xPW7DZ~<;a^B0O8PFIcK8Ko< zBtb_dA)qBx0KwqhledlET>c>Z@0iFsg6U60LC)ckRW0z z%Hk{|kxCV(Y)|@96=R8^rXnU|8Z&fGD!IULkc!HXQv_-o4iLqtm&J-ul&rG^U6V1e zHVGtACwOBu8r@EsTGXbVyzPF*ztyD*jL|4cAxWiVs3t`w5`r)%afCkRiij|!KNIz$ zm@mvAD?>L5h7k~TzKf|w=0q6AG>R~l#6Oeu5>&BX4#G5Gv?H&>jN~%XGC@Q_0$GN+ z1tI;ZVQ*o+E_pLZ*9pl}%pU}!k11dnLULDHVGF}V^GiDzlRWy4f5EDn zTOyJ?52;`X5gNqN5iG|@NRLh%f>g54Gff>9F*ndT{m=HB`x zpF@k4rcqy(2o3*&aeocX7cn2K;S{5WC?W~NsH2qeG>*`eoQ9aTINz0a1;R#NU154} z#~6FqITY0p1{fh2a2Z#er8JDueW{2k=I@B)u@0TjpZ%`Lyy8okIqlVWQ+39dbUb#> z-4;q6G%zo)LUkqV$-zv}${H)Z<9L2CuP{cj)p^4klxVOQ~Kdo&E6k1s23<-`8OM!*X5)m}C|eN)K8rwcw74 zcXsC9O`p$<=VJ#_zw2tM>)raY1YW&`7C~xZcC@Ez&=1xmP)}UP)@7%_=_hZRdResg zbz7I0fE|Z@=Uw1$Sqs;@--MaHCTye9HU7<}eSlyX`PP4HJJAn@=lAg4Z0GEQZS^h= z?6A9P0INmUUH%iU_b~J;pZ7S*LmWr^>`dOFxU>#(x%cCTD}xr>6S+8_ZHG^sGsn92 z94c8W`0)1m(+$~hv**stIrgUVJYVj)plIKq!jB82XNk-Kb@?Ul&JaGhbF*2t+_tJs7IKMp~bHLQ~25I`u~%(s2iRIH-Fs*Tm%Lm(wfK?X-=w^h$Mor z+Mr>iYkN4U&Ye*&4Ah9@u+L+otHLZseQL5tm?2AT74PL)8>^>)f?&0_yD=S+Z_%4a z4zxQSKu5RViq%K-VNYMXz&}9%dtALlV(l}a=jP^Ue9|S;|AQ$f&h*t$epC-R-yZQj zZ!5Mxy5cu~1SnY+wiCc#UMznCRmYTloX`sAZ_nO4T{3QZRs{V?cmNS&`(!S4@7CZJ z9_k0YshQpPLQnju!BSMs4!Q*73kEk1`fl0tPYLj*kMO+jRM?=+Ef4m$g0<@G?4TUE zpPb)a_sJu-@2YLmJ+8Fb9 z6T^`ncu`-y+PUU(v04|Vv>nAE%!hYv-Cdc3Y=`0!lrvnZ*;};X*3JIdtF*h@Gw-3m z-o0_dgkZ0;4!3&xM$qZjSVO>WeDD5FmNh2#gXtc%Ba_xW1Dr?Sd3M!K&K=TM$J}2r zQ4ZK#Vd&Ra&arFHu4D806sdwi7f!3cY}&|ab$;$4sX2Bd6?P+5A7%ra9ds?%t!?u8 zhVVS-=3H-zD>i1>Q2W@a_O?at{u|dkoMrc&f#~f!<3Tsz*PR!zy8jo1FES`&761TQ CXw1X_ literal 2507 zcmV;+2{iT}iwFp%ZCqIb19N3^c4=c}Uw3bEYh`jSYI6XkSZ#CLxDoy<3a95IYl6Hs73u+y#TR5`JpLW8=cz*^}4A>=zYbT)^6<*-Idt{0CwFVZC|%?!DzM5F|G3g+cf4{n);>UeuK)EXVI@v(|+Lt5rE{bn>OGE6e?9O+uRD zKi%Ag^)o_)&B!{}_m0bJd2{iPcdvi*40EbEST0+h)7ELAd8K14poX&9w3vo2lwP&J)daJ3db5#f&=YdE#hCXMY@;J?z zj3J4FT&mcQvpCpj!oUw=6|yWq$ zLJ5&dUnbyZNxlWn4-oPgc#^7E_=(CH3w)ov#>hvEpVp&sxhjn+8HNzYJP%VI`$8(r zc%lF^rcxhRxK)+#O!0ur6d?9l93+vH02mPn5mN~qS4C-M>~l!`I1O@^ry@$pTeOvs z`P|P)N9=Dj01%ELkGKl*oGbJ*7RLc?EFhF)f7pxxs1OrTFIP0+MOo;ZafXqIA|9(K z$TA@aYQZ?<5#*da%L4C9OA4aYr11F@iacf&c&{<9-r;Pt-5Pe4z(f#6!h1ih!W=T|_B|z@#t^DTr7QeNWb} zD2w%S5T=l#Jz}Y!vRnj8#Ds{?Fik19Aj$rou(vp0m(UE-K!hsIa~X3EDrPwa3TG63 znZzuj7~Pdtn8GkoaAgK#mIvSH&s$Y@he)KnvX1uC>u+h(68zpwT3^W@S6DgR0p-_+-uSCzzXvxg?e6n<0vU}oyr-e$(4I^I%%Nivv5%t{S9j(RG*q#G5?~U2v-&M{$Vbs5(0n4=65; zgY3$=yR(JYQhOp6=db_9AVTm%Es7ISO3Ys zbh`fkq^>V@QEgQ9V>0bgOe~;XbQtuZ|9L0&EtgIh?fZH|t+qqsSJJlMlO7mgpwlyB zpbPZFF5T+Eb8eS7%DV54i666l0^8NTO~m16Y=i!%YR7n2T;4m*w3A1i~n95--CNgph?XLEOv%>37!UKpD+b46W{ji3%@KitGO!e%s7kc7PHI*Wm9drrA7Yc3~^xd-Ko)X|p zpV4{Ws;EJm8y@U$g=*E=*+Dt7KUu%q_VZ_U-&Nhgs<<<`s=ONxnxC)h<|{VTSKTe4 zDwL6BPWTkX&Y%B84cXq#yOv~|`^?FGKl|-wvy(EHyB*%!da^5@u< z=)-m7eB9D*+9!!2LA+n!s8cB)(t%!p9$iB_!f>cN!J#h#20|#yqR1s^}~@k^@W= zU6&@@n#%t1MZGR%^{*fG$l#3+I=Y1PLu-vpD(x+}82#}2$9=phlMGin+v$$^r>VbM zw~HegV%pyik^88S4L47%i7|IKF&ycE7xndTJJ(z`RqH~RrlUB7`S7l-yDPJZ?O0r) zw1z7+bBi|Ix|ttymG*FZ<~$YHyEkr>5X^Pf;Z{%I2wL45V+fj!@7>>tvZmyIFx{he zWYV~2fb-}($E@1PxkLKunEMkY$^n~e3jO-pI(F^Zb!=`mC8|)+`BV7Irj4A!`ME=+ zuBaOU>PCz{$_6Gos9LOB)8tnh!dG55XFF3`u`$Dh+Q&|{vn_Iu-`M);EW7UvLT}$0 VPr8A=?z}+N{lDb)&*Nhj0027) - - - - WebSocket debug - - - -

    - -
    -Examples:
    -{
    -  "id": 2, "type": "subscribe_events", "event_type": "state_changed"
    -}
    -
    -{
    -  "id": 3, "type": "call_service", "domain": "light", "service": "turn_off"
    -}
    -
    -{
    -  "id": 4, "type": "unsubscribe_events", "subscription": 2
    -}
    -
    -{
    -  "id": 5, "type": "get_states"
    -}
    -
    -{
    -  "id": 6, "type": "get_config"
    -}
    -
    -{
    -  "id": 7, "type": "get_services"
    -}
    -
    -{
    -  "id": 8, "type": "get_panels"
    -}
    -      
    -
    -
    - - - -
    - -
    
    -
    -    
    -    
    -  
    -
    diff --git a/homeassistant/components/frontend/www_static/websocket_test.html.gz b/homeassistant/components/frontend/www_static/websocket_test.html.gz
    deleted file mode 100644
    index 8c526d1dfd230d8bdbc99f591a247a508b3c8204..0000000000000000000000000000000000000000
    GIT binary patch
    literal 0
    HcmV?d00001
    
    literal 1117
    zcmV-j1fu&NiwFq*|9n^i19xR&b8lm7WprP3Wpi{cXmo9C0Hs!4Z`(E$eb2AB(L-aW
    zwbZ6r7uZ%Fnx<%h3>lUT!+-$>EneANWl|t1J4TWJzDw$haH=yALErV>$v_YFjzu$kHTtv;16}G_3KX7@cvM*?X
    z;j#mA#3
    za26jd)5rqcHHy{RPT|eF*JXga5puE<+^(l^{(88=^okaBZFY9vuRYeTB%Lqwq}6A>
    zRD9pK%EcD4f*F&Zw8TzY&*vRO!P97i#;_F%Sync>>=^Xq0V2U8BL4~^yDyQ3k*Ss@
    z(_)DW+@iE5qBTESbUQ4wxS&wU74oP9du%x*Es2g*smY(~2ev5-G}9wTpg#EQM-HX{
    z^+<06q>L5C!l2%Y3>^wr8z!V%DV*wVs$HcyTWPsad42$R9spMIIdaWh=`zRpGPM6G
    zuwS8Fc=G1pkaq{0D4@Am9c=pf5UJ*Vh;?zWtz;4lzp0Ij4?{hqB`NM{5@lV1qwy?)%Uk-MC-t`f31Lw3+W3w}-)Wo`%3w&~%1sPGLeGvT
    z6SyO-P=iKODrwLFDFZt#tVKz+s}UxXW;>}9R*i`+8^r=NA8xP;Dk}!p5(%VzcmpXMZLU4gB2dh(?K3P
    z?|Vayu9jy{I+FMAiVW#=1`>B5B$cDg5LE6%NJNc4qqFF}O1(wLVifJnG)W3YU1qI}
    zonE{-dz-LQBppZ)6FU0zw5NCq?}g;13zc!X6A!_+g2I@ZsW77Mha%IPibMiA}OrE%l
    z+oGnc5nn;Wn$p^U>(`Vpc1K-p2*M=yV&p;_>oX6$b1`T1TA+OB(k&hu-XPn$U}tLM
    zYQ_n$R~3AbYUcr&G&|JsK%!9qorbAA9;ni0*}rCN4-@F~7#M`HYwGyh;rju6-!#7m
    zJqp6?jd?UY=HPV{
    Date: Tue, 11 Jul 2017 21:21:17 +0200
    Subject: [PATCH 103/131] Upgrade phue to 1.0 (fixes #7749) (#8444)
    
    ---
     homeassistant/components/light/hue.py | 2 +-
     requirements_all.txt                  | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/homeassistant/components/light/hue.py b/homeassistant/components/light/hue.py
    index 73d19d21272..3344de02e75 100644
    --- a/homeassistant/components/light/hue.py
    +++ b/homeassistant/components/light/hue.py
    @@ -27,7 +27,7 @@ from homeassistant.loader import get_component
     from homeassistant.components.emulated_hue import ATTR_EMULATED_HUE
     import homeassistant.helpers.config_validation as cv
     
    -REQUIREMENTS = ['phue==0.9']
    +REQUIREMENTS = ['phue==1.0']
     
     # Track previously setup bridges
     _CONFIGURED_BRIDGES = {}
    diff --git a/requirements_all.txt b/requirements_all.txt
    index cd8b1789e9e..3fd62291f3e 100644
    --- a/requirements_all.txt
    +++ b/requirements_all.txt
    @@ -447,7 +447,7 @@ pdunehd==1.3
     pexpect==4.0.1
     
     # homeassistant.components.light.hue
    -phue==0.9
    +phue==1.0
     
     # homeassistant.components.rpi_pfio
     pifacecommon==4.1.2
    
    From fbf945c18ba539af5dba77ca97299ac25176cc9f Mon Sep 17 00:00:00 2001
    From: Fabian Affolter 
    Date: Tue, 11 Jul 2017 21:22:00 +0200
    Subject: [PATCH 104/131] Add effects (#8442)
    
    ---
     homeassistant/components/light/mystrom.py | 28 +++++++++++++++++++----
     1 file changed, 23 insertions(+), 5 deletions(-)
    
    diff --git a/homeassistant/components/light/mystrom.py b/homeassistant/components/light/mystrom.py
    index 2eb7c106bf2..ecb120e3079 100644
    --- a/homeassistant/components/light/mystrom.py
    +++ b/homeassistant/components/light/mystrom.py
    @@ -8,10 +8,11 @@ import logging
     
     import voluptuous as vol
     
    -from homeassistant.components.light import (
    -    Light, PLATFORM_SCHEMA, ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS)
    -from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME, STATE_UNKNOWN
     import homeassistant.helpers.config_validation as cv
    +from homeassistant.components.light import (
    +    Light, PLATFORM_SCHEMA, ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS,
    +    SUPPORT_EFFECT, ATTR_EFFECT, SUPPORT_FLASH)
    +from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME, STATE_UNKNOWN
     
     REQUIREMENTS = ['python-mystrom==0.3.8']
     
    @@ -19,7 +20,15 @@ _LOGGER = logging.getLogger(__name__)
     
     DEFAULT_NAME = 'myStrom bulb'
     
    -SUPPORT_MYSTROM = (SUPPORT_BRIGHTNESS)
    +SUPPORT_MYSTROM = (SUPPORT_BRIGHTNESS | SUPPORT_EFFECT | SUPPORT_FLASH)
    +
    +EFFECT_RAINBOW = 'rainbow'
    +EFFECT_SUNRISE = 'sunrise'
    +
    +MYSTROM_EFFECT_LIST = [
    +    EFFECT_RAINBOW,
    +    EFFECT_SUNRISE,
    +]
     
     PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
         vol.Required(CONF_HOST): cv.string,
    @@ -58,7 +67,6 @@ class MyStromLight(Light):
             self._state = None
             self._available = False
             self._brightness = 0
    -        self._rgb_color = [0, 0, 0]
     
         @property
         def name(self):
    @@ -80,6 +88,11 @@ class MyStromLight(Light):
             """Return True if entity is available."""
             return self._available
     
    +    @property
    +    def effect_list(self):
    +        """Return the list of supported effects."""
    +        return MYSTROM_EFFECT_LIST
    +
         @property
         def is_on(self):
             """Return true if light is on."""
    @@ -90,12 +103,17 @@ class MyStromLight(Light):
             from pymystrom.exceptions import MyStromConnectionError
     
             brightness = kwargs.get(ATTR_BRIGHTNESS, 255)
    +        effect = kwargs.get(ATTR_EFFECT)
     
             try:
                 if not self.is_on:
                     self._bulb.set_on()
                 if brightness is not None:
                     self._bulb.set_color_hsv(0, 0, round(brightness * 100 / 255))
    +            if effect == EFFECT_SUNRISE:
    +                self._bulb.set_sunrise(30)
    +            if effect == EFFECT_RAINBOW:
    +                self._bulb.set_rainbow(30)
             except MyStromConnectionError:
                 _LOGGER.warning("myStrom bulb not online")
     
    
    From 5b4862cc3c07d82f9333dfdff8b90b13dce3a82e Mon Sep 17 00:00:00 2001
    From: Fabian Affolter 
    Date: Tue, 11 Jul 2017 21:23:23 +0200
    Subject: [PATCH 105/131] Exclude 'TAXI' product (fixes #8401) (#8438)
    
    ---
     homeassistant/components/sensor/uber.py | 4 +++-
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/homeassistant/components/sensor/uber.py b/homeassistant/components/sensor/uber.py
    index a971ca94287..17ce1036244 100644
    --- a/homeassistant/components/sensor/uber.py
    +++ b/homeassistant/components/sensor/uber.py
    @@ -59,7 +59,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
                (product_id not in wanted_product_ids):
                 continue
             dev.append(UberSensor('time', timeandpriceest, product_id, product))
    -        if product.get('price_details') is not None:
    +
    +        if product.get('price_details') is not None \
    +                and product['display_name'] != 'TAXI':
                 dev.append(UberSensor(
                     'price', timeandpriceest, product_id, product))
     
    
    From 60dcc9a5c02e6fa1ae707bc0513ffc1ed55994c6 Mon Sep 17 00:00:00 2001
    From: Andrey 
    Date: Tue, 11 Jul 2017 23:44:01 +0300
    Subject: [PATCH 106/131] Switch pyW215 to pypi (#8445)
    
    ---
     homeassistant/components/switch/dlink.py | 3 +--
     requirements_all.txt                     | 6 +++---
     2 files changed, 4 insertions(+), 5 deletions(-)
    
    diff --git a/homeassistant/components/switch/dlink.py b/homeassistant/components/switch/dlink.py
    index d5036f9cb06..b24693da616 100644
    --- a/homeassistant/components/switch/dlink.py
    +++ b/homeassistant/components/switch/dlink.py
    @@ -14,8 +14,7 @@ from homeassistant.const import (
     import homeassistant.helpers.config_validation as cv
     from homeassistant.const import TEMP_CELSIUS, STATE_UNKNOWN
     
    -REQUIREMENTS = ['https://github.com/LinuxChristian/pyW215/archive/'
    -                'v0.4.zip#pyW215==0.4']
    +REQUIREMENTS = ['pyW215==0.5.1']
     
     _LOGGER = logging.getLogger(__name__)
     
    diff --git a/requirements_all.txt b/requirements_all.txt
    index 3fd62291f3e..7c7f35a7fb8 100644
    --- a/requirements_all.txt
    +++ b/requirements_all.txt
    @@ -273,9 +273,6 @@ holidays==0.8.1
     # homeassistant.components.camera.onvif
     http://github.com/tgaugry/suds-passworddigest-py3/archive/86fc50e39b4d2b8997481967d6a7fe1c57118999.zip#suds-passworddigest-py3==0.1.2a
     
    -# homeassistant.components.switch.dlink
    -https://github.com/LinuxChristian/pyW215/archive/v0.4.zip#pyW215==0.4
    -
     # homeassistant.components.sensor.dht
     # https://github.com/adafruit/Adafruit_Python_DHT/archive/da8cddf7fb629c1ef4f046ca44f42523c9cf2d11.zip#Adafruit_DHT==1.3.0
     
    @@ -506,6 +503,9 @@ pyHS100==0.2.4.2
     # homeassistant.components.rfxtrx
     pyRFXtrx==0.18.0
     
    +# homeassistant.components.switch.dlink
    +pyW215==0.5.1
    +
     # homeassistant.components.alarm_control_panel.alarmdotcom
     pyalarmdotcom==0.3.0
     
    
    From ef94b5c77af4ea3e69c6ac87da88fb1952ca8b10 Mon Sep 17 00:00:00 2001
    From: Vlad Korniev 
    Date: Tue, 11 Jul 2017 13:55:46 -0700
    Subject: [PATCH 107/131] Vizio SmartCast support (#8260)
    
    * Vizio SmartCast support
    
    * Requested changes
    Added new config params
    
    * Vizio SmartCast support
    
    * Requested changes
    Added new config params
    ---
     .coveragerc                                   |   1 +
     .../components/media_player/vizio.py          | 189 ++++++++++++++++++
     requirements_all.txt                          |   3 +
     3 files changed, 193 insertions(+)
     create mode 100644 homeassistant/components/media_player/vizio.py
    
    diff --git a/.coveragerc b/.coveragerc
    index fcb09069267..2d1bff462b9 100644
    --- a/.coveragerc
    +++ b/.coveragerc
    @@ -350,6 +350,7 @@ omit =
         homeassistant/components/media_player/sonos.py
         homeassistant/components/media_player/spotify.py
         homeassistant/components/media_player/squeezebox.py
    +    homeassistant/components/media_player/vizio.py
         homeassistant/components/media_player/vlc.py
         homeassistant/components/media_player/volumio.py
         homeassistant/components/media_player/yamaha.py
    diff --git a/homeassistant/components/media_player/vizio.py b/homeassistant/components/media_player/vizio.py
    new file mode 100644
    index 00000000000..4ae8f037a4f
    --- /dev/null
    +++ b/homeassistant/components/media_player/vizio.py
    @@ -0,0 +1,189 @@
    +"""
    +Vizio SmartCast TV support.
    +
    +Usually only 2016+ models come with SmartCast capabilities.
    +For more details about this platform, please refer to the documentation at
    +https://home-assistant.io/components/media_player.vizio/
    +"""
    +import logging
    +from datetime import timedelta
    +
    +import voluptuous as vol
    +
    +import homeassistant.util as util
    +from homeassistant.components.media_player import (
    +    PLATFORM_SCHEMA,
    +    SUPPORT_TURN_ON,
    +    SUPPORT_TURN_OFF,
    +    SUPPORT_SELECT_SOURCE,
    +    SUPPORT_PREVIOUS_TRACK,
    +    SUPPORT_NEXT_TRACK,
    +    SUPPORT_VOLUME_MUTE,
    +    SUPPORT_VOLUME_STEP,
    +    MediaPlayerDevice
    +)
    +from homeassistant.const import (
    +    STATE_UNKNOWN,
    +    STATE_OFF,
    +    STATE_ON,
    +    CONF_NAME,
    +    CONF_HOST,
    +    CONF_ACCESS_TOKEN
    +)
    +from homeassistant.helpers import config_validation as cv
    +
    +REQUIREMENTS = ['pyvizio==0.0.2']
    +
    +_LOGGER = logging.getLogger(__name__)
    +
    +CONF_SUPPRESS_WARNING = 'suppress_warning'
    +CONF_VOLUME_STEP = 'volume_step'
    +
    +ICON = 'mdi:television'
    +DEFAULT_NAME = 'Vizio SmartCast'
    +DEFAULT_VOLUME_STEP = 1
    +DEVICE_NAME = 'Python Vizio'
    +DEVICE_ID = 'pyvizio'
    +MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
    +MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(seconds=1)
    +SUPPORTED_COMMANDS = SUPPORT_TURN_ON | SUPPORT_TURN_OFF \
    +                     | SUPPORT_SELECT_SOURCE \
    +                     | SUPPORT_NEXT_TRACK | SUPPORT_PREVIOUS_TRACK \
    +                     | SUPPORT_VOLUME_MUTE | SUPPORT_VOLUME_STEP
    +
    +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    +    vol.Required(CONF_HOST): cv.string,
    +    vol.Required(CONF_ACCESS_TOKEN): cv.string,
    +    vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
    +    vol.Optional(CONF_SUPPRESS_WARNING, default=False): cv.boolean,
    +    vol.Optional(CONF_VOLUME_STEP, default=DEFAULT_VOLUME_STEP):
    +        vol.All(vol.Coerce(int), vol.Range(min=1, max=10)),
    +})
    +
    +
    +def setup_platform(hass, config, add_devices, discovery_info=None):
    +    """Set up the VizioTV media player platform."""
    +    host = config.get(CONF_HOST)
    +    token = config.get(CONF_ACCESS_TOKEN)
    +    name = config.get(CONF_NAME)
    +    volume_step = config.get(CONF_VOLUME_STEP)
    +
    +    device = VizioDevice(host, token, name, volume_step)
    +    if device.validate_setup() is False:
    +        _LOGGER.error('Failed to setup Vizio TV platform, '
    +                      'please check if host and API key are correct.')
    +        return False
    +
    +    if config.get(CONF_SUPPRESS_WARNING):
    +        import requests
    +        from requests.packages.urllib3.exceptions import InsecureRequestWarning
    +        _LOGGER.warning('InsecureRequestWarning is disabled '
    +                        'because of Vizio platform configuration.')
    +        requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
    +    add_devices([device], True)
    +
    +
    +class VizioDevice(MediaPlayerDevice):
    +    """Media Player implementation which performs REST requests to TV."""
    +
    +    def __init__(self, host, token, name, volume_step):
    +        """Initialize Vizio device."""
    +        import pyvizio
    +        self._device = pyvizio.Vizio(DEVICE_ID, host, DEFAULT_NAME, token)
    +        self._name = name
    +        self._state = STATE_UNKNOWN
    +        self._volume_level = None
    +        self._volume_step = volume_step
    +        self._current_input = None
    +        self._available_inputs = None
    +
    +    @util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS)
    +    def update(self):
    +        """Retrieve latest state of the TV."""
    +        is_on = self._device.get_power_state()
    +        if is_on is None:
    +            self._state = STATE_UNKNOWN
    +            return
    +        elif is_on is False:
    +            self._state = STATE_OFF
    +        else:
    +            self._state = STATE_ON
    +
    +        self._volume_level = self._device.get_current_volume()
    +        input_ = self._device.get_current_input()
    +        if input_ is not None:
    +            self._current_input = input_.meta_name
    +        inputs = self._device.get_inputs()
    +        if inputs is not None:
    +            self._available_inputs = []
    +            for input_ in inputs:
    +                self._available_inputs.append(input_.name)
    +
    +    @property
    +    def state(self):
    +        """Return the state of the TV."""
    +        return self._state
    +
    +    @property
    +    def name(self):
    +        """Return the name of the TV."""
    +        return self._name
    +
    +    @property
    +    def volume_level(self):
    +        """Return the volume level of the TV."""
    +        return self._volume_level
    +
    +    @property
    +    def source(self):
    +        """Return current input of the TV."""
    +        return self._current_input
    +
    +    @property
    +    def source_list(self):
    +        """Return list of available inputs of the TV."""
    +        return self._available_inputs
    +
    +    @property
    +    def supported_features(self):
    +        """Flag TV features that are supported."""
    +        return SUPPORTED_COMMANDS
    +
    +    def turn_on(self):
    +        """Turn the TV player on."""
    +        self._device.pow_on()
    +
    +    def turn_off(self):
    +        """Turn the TV player off."""
    +        self._device.pow_off()
    +
    +    def mute_volume(self, mute):
    +        """Mute the volume."""
    +        if mute:
    +            self._device.mute_on()
    +        else:
    +            self._device.mute_off()
    +
    +    def media_previous_track(self):
    +        """Send previous channel command."""
    +        self._device.ch_down()
    +
    +    def media_next_track(self):
    +        """Send next channel command."""
    +        self._device.ch_up()
    +
    +    def select_source(self, source):
    +        """Select input source."""
    +        self._device.input_switch(source)
    +
    +    def volume_up(self):
    +        """Increasing volume of the TV."""
    +        self._device.vol_up(num=self._volume_step)
    +
    +    def volume_down(self):
    +        """Decreasing volume of the TV."""
    +        self._device.vol_down(num=self._volume_step)
    +
    +    def validate_setup(self):
    +        """Validating if host is available and key is correct."""
    +        return self._device.get_current_volume() is not None
    diff --git a/requirements_all.txt b/requirements_all.txt
    index 7c7f35a7fb8..e553a6aa2ab 100644
    --- a/requirements_all.txt
    +++ b/requirements_all.txt
    @@ -772,6 +772,9 @@ pyunifi==2.13
     # homeassistant.components.vera
     pyvera==0.2.34
     
    +# homeassistant.components.media_player.vizio
    +pyvizio==0.0.2
    +
     # homeassistant.components.velux
     pyvlx==0.1.3
     
    
    From 471501d3861fbf7539de5969d708c77f1ff13a4f Mon Sep 17 00:00:00 2001
    From: gitmopp 
    Date: Tue, 11 Jul 2017 23:04:00 +0200
    Subject: [PATCH 108/131] DHT support for humidity and temperature offset
     (#8238)
    
    * Added support for temperature_offset and humidity_offset
    
    Some DHT sensors require some offsets to work.
    
    * Support for temperature and humidity offset
    
    * Changed lines with 79 characters
    
    * Moved const to dht.py from const.py
    
    * Changed temperature_offset range
    
    * Removed the const
    
    const.py is at original state.
    
    * Fixed continuation line under-indented
    
    * Removed first round and added debug info
    ---
     homeassistant/components/sensor/dht.py | 30 ++++++++++++++++++++------
     1 file changed, 24 insertions(+), 6 deletions(-)
    
    diff --git a/homeassistant/components/sensor/dht.py b/homeassistant/components/sensor/dht.py
    index a6fc9b10bee..1f24a0ee667 100644
    --- a/homeassistant/components/sensor/dht.py
    +++ b/homeassistant/components/sensor/dht.py
    @@ -26,6 +26,8 @@ _LOGGER = logging.getLogger(__name__)
     
     CONF_PIN = 'pin'
     CONF_SENSOR = 'sensor'
    +CONF_HUMIDITY_OFFSET = 'humidity_offset'
    +CONF_TEMPERATURE_OFFSET = 'temperature_offset'
     
     DEFAULT_NAME = 'DHT Sensor'
     
    @@ -45,6 +47,10 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
         vol.Optional(CONF_MONITORED_CONDITIONS, default=[]):
             vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]),
         vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
    +    vol.Optional(CONF_TEMPERATURE_OFFSET, default=0):
    +        vol.All(vol.Coerce(float), vol.Range(min=-100, max=100)),
    +    vol.Optional(CONF_HUMIDITY_OFFSET, default=0):
    +        vol.All(vol.Coerce(float), vol.Range(min=-100, max=100))
     })
     
     
    @@ -61,6 +67,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
         }
         sensor = available_sensors.get(config.get(CONF_SENSOR))
         pin = config.get(CONF_PIN)
    +    temperature_offset = config.get(CONF_TEMPERATURE_OFFSET)
    +    humidity_offset = config.get(CONF_HUMIDITY_OFFSET)
     
         if not sensor:
             _LOGGER.error("DHT sensor type is not supported")
    @@ -73,7 +81,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
         try:
             for variable in config[CONF_MONITORED_CONDITIONS]:
                 dev.append(DHTSensor(
    -                data, variable, SENSOR_TYPES[variable][1], name))
    +                data, variable, SENSOR_TYPES[variable][1], name,
    +                temperature_offset, humidity_offset))
         except KeyError:
             pass
     
    @@ -83,13 +92,16 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
     class DHTSensor(Entity):
         """Implementation of the DHT sensor."""
     
    -    def __init__(self, dht_client, sensor_type, temp_unit, name):
    +    def __init__(self, dht_client, sensor_type, temp_unit, name,
    +                 temperature_offset, humidity_offset):
             """Initialize the sensor."""
             self.client_name = name
             self._name = SENSOR_TYPES[sensor_type][0]
             self.dht_client = dht_client
             self.temp_unit = temp_unit
             self.type = sensor_type
    +        self.temperature_offset = temperature_offset
    +        self.humidity_offset = humidity_offset
             self._state = None
             self._unit_of_measurement = SENSOR_TYPES[sensor_type][1]
             self.update()
    @@ -112,18 +124,24 @@ class DHTSensor(Entity):
         def update(self):
             """Get the latest data from the DHT and updates the states."""
             self.dht_client.update()
    +        temperature_offset = self.temperature_offset
    +        humidity_offset = self.humidity_offset
             data = self.dht_client.data
     
             if self.type == SENSOR_TEMPERATURE:
    -            temperature = round(data[SENSOR_TEMPERATURE], 1)
    +            temperature = data[SENSOR_TEMPERATURE]
    +            _LOGGER.debug("Temperature %.1f \u00b0C + offset %.1f",
    +                          temperature, temperature_offset)
                 if (temperature >= -20) and (temperature < 80):
    -                self._state = temperature
    +                self._state = round(temperature + temperature_offset, 1)
                     if self.temp_unit == TEMP_FAHRENHEIT:
                         self._state = round(celsius_to_fahrenheit(temperature), 1)
             elif self.type == SENSOR_HUMIDITY:
    -            humidity = round(data[SENSOR_HUMIDITY], 1)
    +            humidity = data[SENSOR_HUMIDITY]
    +            _LOGGER.debug("Humidity %.1f%% + offset %.1f",
    +                          humidity, humidity_offset)
                 if (humidity >= 0) and (humidity <= 100):
    -                self._state = humidity
    +                self._state = round(humidity + humidity_offset, 1)
     
     
     class DHTClient(object):
    
    From effbb3bd4c99e90550b5b7e09bc8c6477910f763 Mon Sep 17 00:00:00 2001
    From: Sean Dague 
    Date: Tue, 11 Jul 2017 17:09:05 -0400
    Subject: [PATCH 109/131] Add support for rain and moisture sensors (#8440)
    
    ---
     homeassistant/components/sensor/arwn.py | 7 +++++++
     1 file changed, 7 insertions(+)
    
    diff --git a/homeassistant/components/sensor/arwn.py b/homeassistant/components/sensor/arwn.py
    index d49afb8b71a..4aa8e20cb75 100644
    --- a/homeassistant/components/sensor/arwn.py
    +++ b/homeassistant/components/sensor/arwn.py
    @@ -38,6 +38,13 @@ def discover_sensors(topic, payload):
             else:
                 unit = TEMP_CELSIUS
             return ArwnSensor(name, 'temp', unit)
    +    if domain == "moisture":
    +        name = parts[2] + " Moisture"
    +        return ArwnSensor(name, 'moisture', unit, "mdi:water-percent")
    +    if domain == "rain":
    +        if len(parts) >= 2 and parts[2] == "today":
    +            return ArwnSensor("Rain Since Midnight", 'since_midnight',
    +                              "in", "mdi:water")
         if domain == 'barometer':
             return ArwnSensor('Barometer', 'pressure', unit,
                               "mdi:thermometer-lines")
    
    From effb9e9d2372214bc4dd89ad04a514279d679bcc Mon Sep 17 00:00:00 2001
    From: Paulus Schoutsen 
    Date: Tue, 11 Jul 2017 23:24:35 -0700
    Subject: [PATCH 110/131] Hass.io: Disable timeout when updating
     OS/supervisor/hass (#8447)
    
    ---
     homeassistant/components/hassio.py | 16 ++++------------
     1 file changed, 4 insertions(+), 12 deletions(-)
    
    diff --git a/homeassistant/components/hassio.py b/homeassistant/components/hassio.py
    index e33a387eada..4ce60fed014 100644
    --- a/homeassistant/components/hassio.py
    +++ b/homeassistant/components/hassio.py
    @@ -26,17 +26,7 @@ DOMAIN = 'hassio'
     DEPENDENCIES = ['http']
     
     TIMEOUT = 10
    -
    -ADDON_REST_COMMANDS = {
    -    'install': ['POST'],
    -    'uninstall': ['POST'],
    -    'start': ['POST'],
    -    'stop': ['POST'],
    -    'update': ['POST'],
    -    'options': ['POST'],
    -    'info': ['GET'],
    -    'logs': ['GET'],
    -}
    +NO_TIMEOUT = set(['homeassistant/update', 'host/update', 'supervisor/update'])
     
     
     @asyncio.coroutine
    @@ -107,6 +97,8 @@ class HassIO(object):
     
             This method is a coroutine.
             """
    +        read_timeout = 0 if path in NO_TIMEOUT else 300
    +
             try:
                 data = None
                 headers = None
    @@ -120,7 +112,7 @@ class HassIO(object):
                 method = getattr(self.websession, request.method.lower())
                 client = yield from method(
                     "http://{}/{}".format(self._ip, path), data=data,
    -                headers=headers
    +                headers=headers, timeout=read_timeout
                 )
     
                 return client
    
    From 970405795999248fc1ca0db28f3ad9c2e393d914 Mon Sep 17 00:00:00 2001
    From: viswa-swami 
    Date: Wed, 12 Jul 2017 02:25:55 -0400
    Subject: [PATCH 111/131] Fix Arlo Q not working with 0.48.1 (#8446)
    
    * This change will enable the functionality for Arlo Q cameras. When we added the code to enable/disable motion detection, we assumed that base station will be present for all arlo type of cameras. But found recently that Arlo Q cameras does not have base station. So, removed the base_station dependency in the init code. Also added code in enable/disable motion detection code to first check if base station is detected by library. If base station is detected then it will use it to enable the motion detection. If not detected, even if service was called, it will not do anything.  Enabling/disabling the motion detection for Arlo Q cameras have to added by someone who has that camera.  I don't have the Arlo Q cameras.
    
    * Fixed a typo in the code.
    ---
     homeassistant/components/camera/arlo.py | 12 ++++++++++--
     1 file changed, 10 insertions(+), 2 deletions(-)
    
    diff --git a/homeassistant/components/camera/arlo.py b/homeassistant/components/camera/arlo.py
    index 637b0dfc2e6..80833e34b20 100644
    --- a/homeassistant/components/camera/arlo.py
    +++ b/homeassistant/components/camera/arlo.py
    @@ -49,7 +49,6 @@ class ArloCam(Camera):
             """Initialize an Arlo camera."""
             super().__init__()
             self._camera = camera
    -        self._base_stn = hass.data[DATA_ARLO].base_stations[0]
             self._name = self._camera.name
             self._motion_status = False
             self._ffmpeg = hass.data[DATA_FFMPEG]
    @@ -103,7 +102,16 @@ class ArloCam(Camera):
     
         def set_base_station_mode(self, mode):
             """Set the mode in the base station."""
    -        self._base_stn.mode = mode
    +        # Get the list of base stations identified by library
    +        base_stations = self.hass.data[DATA_ARLO].base_stations
    +
    +        # Some Arlo cameras does not have basestation
    +        # So check if there is base station detected first
    +        # if yes, then choose the primary base station
    +        # Set the mode on the chosen base station
    +        if base_stations:
    +            primary_base_station = base_stations[0]
    +            primary_base_station.mode = mode
     
         def enable_motion_detection(self):
             """Enable the Motion detection in base station (Arm)."""
    
    From 229000b8345878e3024c635ff44189ca5c2eab44 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Niccol=C3=B2=20Maggioni?= 
    Date: Wed, 12 Jul 2017 08:26:29 +0200
    Subject: [PATCH 112/131] Support for Plex servers with enforced SSL (#8341)
    
    * Support for Plex servers with enforced SSL
    
    * Fixed HoundCI warnings
    
    * Fixed HoundCI warnings (2nd)
    
    * Configurator data validation
    
    * Travis linting
    ---
     homeassistant/components/media_player/plex.py | 54 ++++++++++++++++---
     1 file changed, 46 insertions(+), 8 deletions(-)
    
    diff --git a/homeassistant/components/media_player/plex.py b/homeassistant/components/media_player/plex.py
    index 2bfa97e7e79..a36eb08f851 100644
    --- a/homeassistant/components/media_player/plex.py
    +++ b/homeassistant/components/media_player/plex.py
    @@ -82,8 +82,17 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
     
         if file_config:
             # Setup a configured PlexServer
    -        host, token = file_config.popitem()
    -        token = token['token']
    +        host, host_config = file_config.popitem()
    +        token = host_config['token']
    +        try:
    +            has_ssl = host_config['ssl']
    +        except KeyError:
    +            has_ssl = False
    +        try:
    +            verify_ssl = host_config['verify']
    +        except KeyError:
    +            verify_ssl = True
    +
         # Via discovery
         elif discovery_info is not None:
             # Parse discovery data
    @@ -95,19 +104,34 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
             if host in _CONFIGURING:
                 return
             token = None
    +        has_ssl = False
    +        verify_ssl = True
         else:
             return
     
    -    setup_plexserver(host, token, hass, config, add_devices_callback)
    +    setup_plexserver(
    +        host, token, has_ssl, verify_ssl,
    +        hass, config, add_devices_callback
    +    )
     
     
    -def setup_plexserver(host, token, hass, config, add_devices_callback):
    +def setup_plexserver(
    +        host, token, has_ssl, verify_ssl, hass, config, add_devices_callback):
         """Set up a plexserver based on host parameter."""
         import plexapi.server
         import plexapi.exceptions
     
    +    cert_session = None
    +    http_prefix = 'https' if has_ssl else 'http'
    +    if has_ssl and (verify_ssl is False):
    +        _LOGGER.info("Ignoring SSL verification")
    +        cert_session = requests.Session()
    +        cert_session.verify = False
         try:
    -        plexserver = plexapi.server.PlexServer('http://%s' % host, token)
    +        plexserver = plexapi.server.PlexServer(
    +            '%s://%s' % (http_prefix, host),
    +            token, cert_session
    +        )
             _LOGGER.info("Discovery configuration done (no token needed)")
         except (plexapi.exceptions.BadRequest, plexapi.exceptions.Unauthorized,
                 plexapi.exceptions.NotFound) as error:
    @@ -126,11 +150,13 @@ def setup_plexserver(host, token, hass, config, add_devices_callback):
         # Save config
         if not config_from_file(
                 hass.config.path(PLEX_CONFIG_FILE), {host: {
    -                'token': token
    +                'token': token,
    +                'ssl': has_ssl,
    +                'verify': verify_ssl,
                 }}):
             _LOGGER.error("Failed to save configuration file")
     
    -    _LOGGER.info('Connected to: http://%s', host)
    +    _LOGGER.info('Connected to: %s://%s', http_prefix, host)
     
         plex_clients = {}
         plex_sessions = {}
    @@ -217,7 +243,11 @@ def request_configuration(host, hass, config, add_devices_callback):
         def plex_configuration_callback(data):
             """Handle configuration changes."""
             setup_plexserver(
    -            host, data.get('token'), hass, config, add_devices_callback)
    +            host, data.get('token'),
    +            cv.boolean(data.get('has_ssl')),
    +            cv.boolean(data.get('do_not_verify')),
    +            hass, config, add_devices_callback
    +        )
     
         _CONFIGURING[host] = configurator.request_config(
             hass,
    @@ -230,6 +260,14 @@ def request_configuration(host, hass, config, add_devices_callback):
                 'id': 'token',
                 'name': 'X-Plex-Token',
                 'type': ''
    +        }, {
    +            'id': 'has_ssl',
    +            'name': 'Use SSL',
    +            'type': ''
    +        }, {
    +            'id': 'do_not_verify_ssl',
    +            'name': 'Do not verify SSL',
    +            'type': ''
             }])
     
     
    
    From 4451d2e847c2eaa20b7fc720ae7c137df046780f Mon Sep 17 00:00:00 2001
    From: Fabian Affolter 
    Date: Wed, 12 Jul 2017 10:38:08 +0200
    Subject: [PATCH 113/131] Upgrade youtube_dl to 2017.7.9 (#8450)
    
    ---
     homeassistant/components/media_extractor.py | 20 ++++++++++----------
     requirements_all.txt                        |  2 +-
     2 files changed, 11 insertions(+), 11 deletions(-)
    
    diff --git a/homeassistant/components/media_extractor.py b/homeassistant/components/media_extractor.py
    index 5d1ffb6a0ce..c7d019973a3 100644
    --- a/homeassistant/components/media_extractor.py
    +++ b/homeassistant/components/media_extractor.py
    @@ -1,8 +1,8 @@
     """
     Decorator service for the media_player.play_media service.
     
    -Extracts stream url and sends it to the media_player.play_media
    -service.
    +For more details about this component, please refer to the documentation at
    +https://home-assistant.io/components/media_extractor/
     """
     import logging
     import os
    @@ -12,28 +12,28 @@ from homeassistant.components.media_player import (
         MEDIA_PLAYER_PLAY_MEDIA_SCHEMA, SERVICE_PLAY_MEDIA)
     from homeassistant.config import load_yaml_config_file
     
    -
    -DOMAIN = 'media_extractor'
    -DEPENDENCIES = ['media_player']
    -REQUIREMENTS = ['youtube_dl==2017.7.2']
    +REQUIREMENTS = ['youtube_dl==2017.7.9']
     
     _LOGGER = logging.getLogger(__name__)
     
    +DOMAIN = 'media_extractor'
    +DEPENDENCIES = ['media_player']
    +
     
     def setup(hass, config):
    -    """Set up the media_extractor service."""
    +    """Set up the media extractor service."""
         descriptions = load_yaml_config_file(
             os.path.join(os.path.dirname(__file__),
                          'media_player', 'services.yaml'))
     
         def play_media(call):
    -        """Get stream url and send it to the media_player.play_media."""
    +        """Get stream URL and send it to the media_player.play_media."""
             media_url = call.data.get(ATTR_MEDIA_CONTENT_ID)
     
             try:
                 stream_url = get_media_stream_url(media_url)
             except YDException:
    -            _LOGGER.error("Could not retrieve data for the url: %s",
    +            _LOGGER.error("Could not retrieve data for the URL: %s",
                               media_url)
                 return
             else:
    @@ -62,7 +62,7 @@ class YDException(Exception):
     
     
     def get_media_stream_url(media_url):
    -    """Extract stream url from the media url."""
    +    """Extract stream URL from the media URL."""
         from youtube_dl import YoutubeDL
         from youtube_dl.utils import DownloadError, ExtractorError
     
    diff --git a/requirements_all.txt b/requirements_all.txt
    index e553a6aa2ab..20a6b8b4df4 100644
    --- a/requirements_all.txt
    +++ b/requirements_all.txt
    @@ -965,7 +965,7 @@ yeelight==0.3.0
     yeelightsunflower==0.0.8
     
     # homeassistant.components.media_extractor
    -youtube_dl==2017.7.2
    +youtube_dl==2017.7.9
     
     # homeassistant.components.light.zengge
     zengge==0.2
    
    From b6e0286d71a02f19304b7ac48663a7a2a151c11c Mon Sep 17 00:00:00 2001
    From: Open Home Automation 
    Date: Wed, 12 Jul 2017 12:21:15 +0200
    Subject: [PATCH 114/131] Implement a bridge between HASS event bus and KNX bus
     to send events (#8449)
    
    * Implement a bridge between HASS event bus and KNX bus to send events as KNX messages
    
    * Formatting
    ---
     homeassistant/components/knx.py | 45 +++++++++++++++++++++++++++++++++
     1 file changed, 45 insertions(+)
    
    diff --git a/homeassistant/components/knx.py b/homeassistant/components/knx.py
    index 30488113d7e..ec533a7850b 100644
    --- a/homeassistant/components/knx.py
    +++ b/homeassistant/components/knx.py
    @@ -22,6 +22,7 @@ DEFAULT_PORT = 3671
     DOMAIN = 'knx'
     
     EVENT_KNX_FRAME_RECEIVED = 'knx_frame_received'
    +EVENT_KNX_FRAME_SEND = 'knx_frame_send'
     
     KNXTUNNEL = None
     CONF_LISTEN = "listen"
    @@ -83,6 +84,50 @@ def setup(hass, config):
                               listen, knxexception)
     
         hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, close_tunnel)
    +
    +    # Listen to KNX events and send them to the bus
    +    def handle_knx_send(event):
    +        """Bridge knx_frame_send events to the KNX bus."""
    +        try:
    +            addr = event.data["address"]
    +        except KeyError:
    +            _LOGGER.error("KNX group address is missing")
    +            return
    +
    +        try:
    +            data = event.data["data"]
    +        except KeyError:
    +            _LOGGER.error("KNX data block missing")
    +            return
    +
    +        knxaddr = None
    +        try:
    +            addr = int(addr)
    +        except ValueError:
    +            pass
    +
    +        if knxaddr is None:
    +            try:
    +                knxaddr = parse_group_address(addr)
    +            except KNXException:
    +                _LOGGER.error("KNX address format incorrect")
    +                return
    +
    +        knxdata = None
    +        if isinstance(data, list):
    +            knxdata = data
    +        else:
    +            try:
    +                knxdata = [int(data) & 0xff]
    +            except ValueError:
    +                _LOGGER.error("KNX data format incorrect")
    +                return
    +
    +        KNXTUNNEL.group_write(knxaddr, knxdata)
    +
    +    # Listen for when knx_frame_send event is fired
    +    hass.bus.listen(EVENT_KNX_FRAME_SEND, handle_knx_send)
    +
         return True
     
     
    
    From d10f017441b1e336ce41241c742cd31aaa71ea6b Mon Sep 17 00:00:00 2001
    From: Anders Melchiorsen 
    Date: Wed, 12 Jul 2017 19:24:24 +0200
    Subject: [PATCH 115/131] LIFX: improve light availability (#8451)
    
    The default aiolifx timers are tuned for a network with few lost packets.
    This means that lights can become "unavailable" from just a two second
    dropout. An unavailable light is completely useless for HA until it is
    rediscovered so this is an undesirable state to be in.
    
    These tweaks make aiolifx try harder to get its messages through to the
    bulbs, at the cost of some latency in detecting lights that actually are
    unavailable.
    ---
     homeassistant/components/light/lifx.py | 13 ++++++++++++-
     1 file changed, 12 insertions(+), 1 deletion(-)
    
    diff --git a/homeassistant/components/light/lifx.py b/homeassistant/components/light/lifx.py
    index fd713989f52..e09e30e0901 100644
    --- a/homeassistant/components/light/lifx.py
    +++ b/homeassistant/components/light/lifx.py
    @@ -37,6 +37,11 @@ REQUIREMENTS = ['aiolifx==0.5.2', 'aiolifx_effects==0.1.0']
     
     UDP_BROADCAST_PORT = 56700
     
    +DISCOVERY_INTERVAL = 60
    +MESSAGE_TIMEOUT = 1.0
    +MESSAGE_RETRIES = 8
    +UNAVAILABLE_GRACE = 90
    +
     CONF_SERVER = 'server'
     
     PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    @@ -117,7 +122,10 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
         server_addr = config.get(CONF_SERVER)
     
         lifx_manager = LIFXManager(hass, async_add_devices)
    -    lifx_discovery = aiolifx.LifxDiscovery(hass.loop, lifx_manager)
    +    lifx_discovery = aiolifx.LifxDiscovery(
    +        hass.loop,
    +        lifx_manager,
    +        discovery_interval=DISCOVERY_INTERVAL)
     
         coro = hass.loop.create_datagram_endpoint(
             lambda: lifx_discovery, local_addr=(server_addr, UDP_BROADCAST_PORT))
    @@ -287,6 +295,9 @@ class LIFXManager(object):
                 self.hass.async_add_job(entity.async_update_ha_state())
             else:
                 _LOGGER.debug("%s register NEW", device.ip_addr)
    +            device.timeout = MESSAGE_TIMEOUT
    +            device.retry_count = MESSAGE_RETRIES
    +            device.unregister_timeout = UNAVAILABLE_GRACE
                 device.get_version(self.got_version)
     
         @callback
    
    From bb9db28c950848e0be0eb11f2b95c7ac6ac28d83 Mon Sep 17 00:00:00 2001
    From: Anders Melchiorsen 
    Date: Wed, 12 Jul 2017 23:08:18 +0200
    Subject: [PATCH 116/131] LIFX: make broadcast address configurable (#8453)
    
    ---
     homeassistant/components/light/lifx.py | 5 ++++-
     1 file changed, 4 insertions(+), 1 deletion(-)
    
    diff --git a/homeassistant/components/light/lifx.py b/homeassistant/components/light/lifx.py
    index e09e30e0901..0c5535ea8ea 100644
    --- a/homeassistant/components/light/lifx.py
    +++ b/homeassistant/components/light/lifx.py
    @@ -43,9 +43,11 @@ MESSAGE_RETRIES = 8
     UNAVAILABLE_GRACE = 90
     
     CONF_SERVER = 'server'
    +CONF_BROADCAST = 'broadcast'
     
     PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
         vol.Optional(CONF_SERVER, default='0.0.0.0'): cv.string,
    +    vol.Optional(CONF_BROADCAST, default='255.255.255.255'): cv.string,
     })
     
     SERVICE_LIFX_SET_STATE = 'lifx_set_state'
    @@ -125,7 +127,8 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
         lifx_discovery = aiolifx.LifxDiscovery(
             hass.loop,
             lifx_manager,
    -        discovery_interval=DISCOVERY_INTERVAL)
    +        discovery_interval=DISCOVERY_INTERVAL,
    +        broadcast_ip=config.get(CONF_BROADCAST))
     
         coro = hass.loop.create_datagram_endpoint(
             lambda: lifx_discovery, local_addr=(server_addr, UDP_BROADCAST_PORT))
    
    From a65f22378e8953837fd7ca5cce37802bebd0b4a3 Mon Sep 17 00:00:00 2001
    From: Andrey 
    Date: Thu, 13 Jul 2017 04:08:13 +0300
    Subject: [PATCH 117/131] Backend support for themes (#8419)
    
    * Backend support for themes
    
    * Fix test
    
    * Add theme_updated event
    
    * Shorten name
    
    * Add tests
    ---
     homeassistant/components/frontend/__init__.py | 101 +++++++++++++++++-
     .../components/frontend/services.yaml         |  11 ++
     homeassistant/const.py                        |   1 +
     tests/components/test_frontend.py             |  72 ++++++++++++-
     4 files changed, 183 insertions(+), 2 deletions(-)
     create mode 100644 homeassistant/components/frontend/services.yaml
    
    diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py
    index 7fd65d44227..4dd0ad329fc 100644
    --- a/homeassistant/components/frontend/__init__.py
    +++ b/homeassistant/components/frontend/__init__.py
    @@ -6,7 +6,11 @@ import logging
     import os
     
     from aiohttp import web
    +import voluptuous as vol
    +import homeassistant.helpers.config_validation as cv
     
    +from homeassistant.config import find_config_file, load_yaml_config_file
    +from homeassistant.const import CONF_NAME, EVENT_THEMES_UPDATED
     from homeassistant.core import callback
     from homeassistant.components import api
     from homeassistant.components.http import HomeAssistantView
    @@ -22,6 +26,8 @@ URL_PANEL_COMPONENT_FP = '/frontend/panels/{}-{}.html'
     
     STATIC_PATH = os.path.join(os.path.dirname(__file__), 'www_static/')
     
    +ATTR_THEMES = 'themes'
    +DEFAULT_THEME_COLOR = '#03A9F4'
     MANIFEST_JSON = {
         'background_color': '#FFFFFF',
         'description': 'Open-source home automation platform running on Python 3.',
    @@ -32,7 +38,7 @@ MANIFEST_JSON = {
         'name': 'Home Assistant',
         'short_name': 'Assistant',
         'start_url': '/',
    -    'theme_color': '#03A9F4'
    +    'theme_color': DEFAULT_THEME_COLOR
     }
     
     for size in (192, 384, 512, 1024):
    @@ -44,11 +50,30 @@ for size in (192, 384, 512, 1024):
     
     DATA_PANELS = 'frontend_panels'
     DATA_INDEX_VIEW = 'frontend_index_view'
    +DATA_THEMES = 'frontend_themes'
    +DATA_DEFAULT_THEME = 'frontend_default_theme'
    +DEFAULT_THEME = 'default'
    +
    +PRIMARY_COLOR = 'primary-color'
     
     # To keep track we don't register a component twice (gives a warning)
     _REGISTERED_COMPONENTS = set()
     _LOGGER = logging.getLogger(__name__)
     
    +CONFIG_SCHEMA = vol.Schema({
    +    DOMAIN: vol.Schema({
    +        vol.Optional(ATTR_THEMES): vol.Schema({
    +            cv.string: {cv.string: cv.string}
    +        }),
    +    }),
    +}, extra=vol.ALLOW_EXTRA)
    +
    +SERVICE_SET_THEME = 'set_theme'
    +SERVICE_RELOAD_THEMES = 'reload_themes'
    +SERVICE_SET_THEME_SCHEMA = vol.Schema({
    +    vol.Required(CONF_NAME): cv.string,
    +})
    +
     
     def register_built_in_panel(hass, component_name, sidebar_title=None,
                                 sidebar_icon=None, url_path=None, config=None):
    @@ -186,9 +211,65 @@ def setup(hass, config):
                       'dev-template'):
             register_built_in_panel(hass, panel)
     
    +    themes = config.get(DOMAIN, {}).get(ATTR_THEMES)
    +    if themes:
    +        setup_themes(hass, themes)
    +
         return True
     
     
    +def setup_themes(hass, themes):
    +    """Set up themes data and services."""
    +    hass.data[DATA_THEMES] = themes
    +    hass.data[DATA_DEFAULT_THEME] = DEFAULT_THEME
    +    hass.http.register_view(ThemesView)
    +
    +    @callback
    +    def update_theme_and_fire_event():
    +        """Update theme_color in manifest."""
    +        name = hass.data[DATA_DEFAULT_THEME]
    +        themes = hass.data[DATA_THEMES]
    +        if name != DEFAULT_THEME and PRIMARY_COLOR in themes[name]:
    +            MANIFEST_JSON['theme_color'] = themes[name][PRIMARY_COLOR]
    +        else:
    +            MANIFEST_JSON['theme_color'] = DEFAULT_THEME_COLOR
    +        hass.bus.async_fire(EVENT_THEMES_UPDATED, {
    +            'themes': themes,
    +            'default_theme': name,
    +        })
    +
    +    @callback
    +    def set_theme(call):
    +        """Set backend-prefered theme."""
    +        data = call.data
    +        name = data[CONF_NAME]
    +        if name == DEFAULT_THEME or name in hass.data[DATA_THEMES]:
    +            _LOGGER.info("Theme %s set as default", name)
    +            hass.data[DATA_DEFAULT_THEME] = name
    +            update_theme_and_fire_event()
    +        else:
    +            _LOGGER.warning("Theme %s is not defined.", name)
    +
    +    @callback
    +    def reload_themes(_):
    +        """Reload themes."""
    +        path = find_config_file(hass.config.config_dir)
    +        new_themes = load_yaml_config_file(path)[DOMAIN].get(ATTR_THEMES, {})
    +        hass.data[DATA_THEMES] = new_themes
    +        if hass.data[DATA_DEFAULT_THEME] not in new_themes:
    +            hass.data[DATA_DEFAULT_THEME] = DEFAULT_THEME
    +        update_theme_and_fire_event()
    +
    +    descriptions = load_yaml_config_file(
    +        os.path.join(os.path.dirname(__file__), 'services.yaml'))
    +    hass.services.register(DOMAIN, SERVICE_SET_THEME,
    +                           set_theme,
    +                           descriptions[SERVICE_SET_THEME],
    +                           SERVICE_SET_THEME_SCHEMA)
    +    hass.services.register(DOMAIN, SERVICE_RELOAD_THEMES, reload_themes,
    +                           descriptions[SERVICE_RELOAD_THEMES])
    +
    +
     class BootstrapView(HomeAssistantView):
         """View to bootstrap frontend with all needed data."""
     
    @@ -291,3 +372,21 @@ class ManifestJSONView(HomeAssistantView):
             """Return the manifest.json."""
             msg = json.dumps(MANIFEST_JSON, sort_keys=True).encode('UTF-8')
             return web.Response(body=msg, content_type="application/manifest+json")
    +
    +
    +class ThemesView(HomeAssistantView):
    +    """View to return defined themes."""
    +
    +    requires_auth = False
    +    url = '/api/themes'
    +    name = 'api:themes'
    +
    +    @callback
    +    def get(self, request):
    +        """Return themes."""
    +        hass = request.app['hass']
    +
    +        return self.json({
    +            'themes': hass.data[DATA_THEMES],
    +            'default_theme': hass.data[DATA_DEFAULT_THEME],
    +        })
    diff --git a/homeassistant/components/frontend/services.yaml b/homeassistant/components/frontend/services.yaml
    new file mode 100644
    index 00000000000..7d56cbb7693
    --- /dev/null
    +++ b/homeassistant/components/frontend/services.yaml
    @@ -0,0 +1,11 @@
    +# Describes the format for available frontend services
    +
    +set_theme:
    +  description: Set a theme unless the client selected per-device theme.
    +  fields:
    +    name:
    +      description: Name of a predefined theme or 'default'.
    +      example: 'light'
    +
    +reload_themes:
    +  description: Reload themes from yaml config.
    diff --git a/homeassistant/const.py b/homeassistant/const.py
    index 510f7daf12e..f7df04be7f1 100644
    --- a/homeassistant/const.py
    +++ b/homeassistant/const.py
    @@ -179,6 +179,7 @@ EVENT_COMPONENT_LOADED = 'component_loaded'
     EVENT_SERVICE_REGISTERED = 'service_registered'
     EVENT_SERVICE_REMOVED = 'service_removed'
     EVENT_LOGBOOK_ENTRY = 'logbook_entry'
    +EVENT_THEMES_UPDATED = 'themes_updated'
     
     # #### STATES ####
     STATE_ON = 'on'
    diff --git a/tests/components/test_frontend.py b/tests/components/test_frontend.py
    index 3d9798800d7..d1e2e5d4346 100644
    --- a/tests/components/test_frontend.py
    +++ b/tests/components/test_frontend.py
    @@ -1,10 +1,12 @@
     """The tests for Home Assistant frontend."""
     import asyncio
     import re
    +from unittest.mock import patch
     
     import pytest
     
     from homeassistant.setup import async_setup_component
    +from homeassistant.components.frontend import DOMAIN, ATTR_THEMES
     
     
     @pytest.fixture
    @@ -14,6 +16,20 @@ def mock_http_client(hass, test_client):
         return hass.loop.run_until_complete(test_client(hass.http.app))
     
     
    +@pytest.fixture
    +def mock_http_client_with_themes(hass, test_client):
    +    """Start the Hass HTTP component."""
    +    hass.loop.run_until_complete(async_setup_component(hass, 'frontend', {
    +        DOMAIN: {
    +            ATTR_THEMES: {
    +                'happy': {
    +                    'primary-color': 'red'
    +                }
    +            }
    +        }}))
    +    return hass.loop.run_until_complete(test_client(hass.http.app))
    +
    +
     @asyncio.coroutine
     def test_frontend_and_static(mock_http_client):
         """Test if we can get the frontend."""
    @@ -56,10 +72,64 @@ def test_we_cannot_POST_to_root(mock_http_client):
     
     
     @asyncio.coroutine
    -def test_states_routes(hass, mock_http_client):
    +def test_states_routes(mock_http_client):
         """All served by index."""
         resp = yield from mock_http_client.get('/states')
         assert resp.status == 200
     
         resp = yield from mock_http_client.get('/states/group.existing')
         assert resp.status == 200
    +
    +
    +@asyncio.coroutine
    +def test_themes_api(mock_http_client_with_themes):
    +    """Test that /api/themes returns correct data."""
    +    resp = yield from mock_http_client_with_themes.get('/api/themes')
    +    json = yield from resp.json()
    +    assert json['default_theme'] == 'default'
    +    assert json['themes'] == {'happy': {'primary-color': 'red'}}
    +
    +
    +@asyncio.coroutine
    +def test_themes_set_theme(hass, mock_http_client_with_themes):
    +    """Test frontend.set_theme service."""
    +    yield from hass.services.async_call(DOMAIN, 'set_theme', {'name': 'happy'})
    +    yield from hass.async_block_till_done()
    +    resp = yield from mock_http_client_with_themes.get('/api/themes')
    +    json = yield from resp.json()
    +    assert json['default_theme'] == 'happy'
    +
    +    yield from hass.services.async_call(
    +        DOMAIN, 'set_theme', {'name': 'default'})
    +    yield from hass.async_block_till_done()
    +    resp = yield from mock_http_client_with_themes.get('/api/themes')
    +    json = yield from resp.json()
    +    assert json['default_theme'] == 'default'
    +
    +
    +@asyncio.coroutine
    +def test_themes_set_theme_wrong_name(hass, mock_http_client_with_themes):
    +    """Test frontend.set_theme service called with wrong name."""
    +    yield from hass.services.async_call(DOMAIN, 'set_theme', {'name': 'wrong'})
    +    yield from hass.async_block_till_done()
    +    resp = yield from mock_http_client_with_themes.get('/api/themes')
    +    json = yield from resp.json()
    +    assert json['default_theme'] == 'default'
    +
    +
    +@asyncio.coroutine
    +def test_themes_reload_themes(hass, mock_http_client_with_themes):
    +    """Test frontend.reload_themes service."""
    +    with patch('homeassistant.components.frontend.load_yaml_config_file',
    +               return_value={DOMAIN: {
    +                   ATTR_THEMES: {
    +                       'sad': {'primary-color': 'blue'}
    +                   }}}):
    +        yield from hass.services.async_call(DOMAIN, 'set_theme',
    +                                            {'name': 'happy'})
    +        yield from hass.services.async_call(DOMAIN, 'reload_themes')
    +        yield from hass.async_block_till_done()
    +        resp = yield from mock_http_client_with_themes.get('/api/themes')
    +        json = yield from resp.json()
    +        assert json['themes'] == {'sad': {'primary-color': 'blue'}}
    +        assert json['default_theme'] == 'default'
    
    From 7aad93e90d5d396dc05efc8726758bfa640e87cf Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Daniel=20H=C3=B8yer=20Iversen?= 
    Date: Thu, 13 Jul 2017 14:42:30 +0200
    Subject: [PATCH 118/131] upgrade broadlink (#8462)
    
    ---
     homeassistant/components/sensor/broadlink.py | 2 +-
     homeassistant/components/switch/broadlink.py | 2 +-
     requirements_all.txt                         | 2 +-
     3 files changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/homeassistant/components/sensor/broadlink.py b/homeassistant/components/sensor/broadlink.py
    index 7d5018e054c..97b34b0c881 100644
    --- a/homeassistant/components/sensor/broadlink.py
    +++ b/homeassistant/components/sensor/broadlink.py
    @@ -19,7 +19,7 @@ from homeassistant.helpers.entity import Entity
     from homeassistant.util import Throttle
     import homeassistant.helpers.config_validation as cv
     
    -REQUIREMENTS = ['broadlink==0.3']
    +REQUIREMENTS = ['broadlink==0.5']
     
     _LOGGER = logging.getLogger(__name__)
     
    diff --git a/homeassistant/components/switch/broadlink.py b/homeassistant/components/switch/broadlink.py
    index 191718a31b3..3a7f3ee0c80 100644
    --- a/homeassistant/components/switch/broadlink.py
    +++ b/homeassistant/components/switch/broadlink.py
    @@ -21,7 +21,7 @@ from homeassistant.const import (
         CONF_TIMEOUT, CONF_HOST, CONF_MAC, CONF_TYPE)
     import homeassistant.helpers.config_validation as cv
     
    -REQUIREMENTS = ['broadlink==0.3']
    +REQUIREMENTS = ['broadlink==0.5']
     
     _LOGGER = logging.getLogger(__name__)
     
    diff --git a/requirements_all.txt b/requirements_all.txt
    index 20a6b8b4df4..ef91767cdc3 100644
    --- a/requirements_all.txt
    +++ b/requirements_all.txt
    @@ -114,7 +114,7 @@ boto3==1.4.3
     
     # homeassistant.components.sensor.broadlink
     # homeassistant.components.switch.broadlink
    -broadlink==0.3
    +broadlink==0.5
     
     # homeassistant.components.sensor.buienradar
     # homeassistant.components.weather.buienradar
    
    From 71ee290bfdd4466eab5ad80c0fefdc673142335e Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Daniel=20H=C3=B8yer=20Iversen?= 
    Date: Thu, 13 Jul 2017 14:57:44 +0200
    Subject: [PATCH 119/131] upgrade rfxtrx lib (#8463)
    
    ---
     homeassistant/components/rfxtrx.py | 2 +-
     requirements_all.txt               | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/homeassistant/components/rfxtrx.py b/homeassistant/components/rfxtrx.py
    index fd34eddf916..b6e4d3415f4 100644
    --- a/homeassistant/components/rfxtrx.py
    +++ b/homeassistant/components/rfxtrx.py
    @@ -17,7 +17,7 @@ from homeassistant.const import (
     )
     from homeassistant.helpers.entity import Entity
     
    -REQUIREMENTS = ['pyRFXtrx==0.18.0']
    +REQUIREMENTS = ['pyRFXtrx==0.19.0']
     
     DOMAIN = 'rfxtrx'
     
    diff --git a/requirements_all.txt b/requirements_all.txt
    index ef91767cdc3..b9013d20bb7 100644
    --- a/requirements_all.txt
    +++ b/requirements_all.txt
    @@ -501,7 +501,7 @@ pyCEC==0.4.13
     pyHS100==0.2.4.2
     
     # homeassistant.components.rfxtrx
    -pyRFXtrx==0.18.0
    +pyRFXtrx==0.19.0
     
     # homeassistant.components.switch.dlink
     pyW215==0.5.1
    
    From 2eeeb9075a4972024954f1a2616e77e7ed84f68d Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Ab=C3=ADlio=20Costa?= 
    Date: Thu, 13 Jul 2017 16:01:12 +0100
    Subject: [PATCH 120/131] Plex: Add exception handler when connection fails
     (#8179)
    
    * add exception handler when connection fails
    
    * plex: improve exception handling
    
    * remove uneeded exception handler
    ---
     homeassistant/components/media_player/plex.py | 10 +++++++---
     1 file changed, 7 insertions(+), 3 deletions(-)
    
    diff --git a/homeassistant/components/media_player/plex.py b/homeassistant/components/media_player/plex.py
    index a36eb08f851..f4c69ba1fe6 100644
    --- a/homeassistant/components/media_player/plex.py
    +++ b/homeassistant/components/media_player/plex.py
    @@ -170,9 +170,9 @@ def setup_plexserver(
             except plexapi.exceptions.BadRequest:
                 _LOGGER.exception("Error listing plex devices")
                 return
    -        except OSError:
    -            _LOGGER.error("Could not connect to plex server at http://%s",
    -                          host)
    +        except requests.exceptions.RequestException as ex:
    +            _LOGGER.error("Could not connect to plex server at http://%s (%s)",
    +                          host, ex)
                 return
     
             new_plex_clients = []
    @@ -219,6 +219,10 @@ def setup_plexserver(
             except plexapi.exceptions.BadRequest:
                 _LOGGER.exception("Error listing plex sessions")
                 return
    +        except requests.exceptions.RequestException as ex:
    +            _LOGGER.error("Could not connect to plex server at http://%s (%s)",
    +                          host, ex)
    +            return
     
             plex_sessions.clear()
             for session in sessions:
    
    From e0f35c02797a01897beec0615b8fde2f5db2b953 Mon Sep 17 00:00:00 2001
    From: Daniel Perna 
    Date: Thu, 13 Jul 2017 17:55:30 +0200
    Subject: [PATCH 121/131] HomeMatic dependency upgrade + IP Wall Thermostat
     support (#8465)
    
    * Upgrade dependency + added IP Wall Thermostat
    ---
     homeassistant/components/homematic.py | 4 ++--
     requirements_all.txt                  | 2 +-
     2 files changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/homeassistant/components/homematic.py b/homeassistant/components/homematic.py
    index aca3fd9a949..a8fc645ee4c 100644
    --- a/homeassistant/components/homematic.py
    +++ b/homeassistant/components/homematic.py
    @@ -21,7 +21,7 @@ from homeassistant.helpers.entity import Entity
     from homeassistant.helpers.event import track_time_interval
     from homeassistant.config import load_yaml_config_file
     
    -REQUIREMENTS = ['pyhomematic==0.1.28']
    +REQUIREMENTS = ['pyhomematic==0.1.29']
     
     DOMAIN = 'homematic'
     
    @@ -68,7 +68,7 @@ HM_DEVICE_TYPES = {
             'FillingLevel', 'ValveDrive', 'EcoLogic'],
         DISCOVER_CLIMATE: [
             'Thermostat', 'ThermostatWall', 'MAXThermostat', 'ThermostatWall2',
    -        'MAXWallThermostat', 'IPThermostat'],
    +        'MAXWallThermostat', 'IPThermostat', 'IPThermostatWall'],
         DISCOVER_BINARY_SENSORS: [
             'ShutterContact', 'Smoke', 'SmokeV2', 'Motion', 'MotionV2',
             'RemoteMotion', 'WeatherSensor', 'TiltSensor', 'IPShutterContact',
    diff --git a/requirements_all.txt b/requirements_all.txt
    index b9013d20bb7..d4e4a30add7 100644
    --- a/requirements_all.txt
    +++ b/requirements_all.txt
    @@ -577,7 +577,7 @@ pyharmony==1.0.16
     pyhik==0.1.3
     
     # homeassistant.components.homematic
    -pyhomematic==0.1.28
    +pyhomematic==0.1.29
     
     # homeassistant.components.sensor.hydroquebec
     pyhydroquebec==1.2.0
    
    From b8eaec565a7c3e922a59cb07755477d430bf2ac9 Mon Sep 17 00:00:00 2001
    From: Andrey 
    Date: Thu, 13 Jul 2017 19:11:49 +0300
    Subject: [PATCH 122/131] Add kiosk-mode panel (#8457)
    
    ---
     homeassistant/components/frontend/__init__.py | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py
    index 4dd0ad329fc..4184feabaeb 100644
    --- a/homeassistant/components/frontend/__init__.py
    +++ b/homeassistant/components/frontend/__init__.py
    @@ -208,7 +208,7 @@ def setup(hass, config):
         register_built_in_panel(hass, 'map', 'Map', 'mdi:account-location')
     
         for panel in ('dev-event', 'dev-info', 'dev-service', 'dev-state',
    -                  'dev-template'):
    +                  'dev-template', 'kiosk'):
             register_built_in_panel(hass, panel)
     
         themes = config.get(DOMAIN, {}).get(ATTR_THEMES)
    
    From 192db5bec30005de94937e494311def5df005ccf Mon Sep 17 00:00:00 2001
    From: Paulus Schoutsen 
    Date: Thu, 13 Jul 2017 09:22:15 -0700
    Subject: [PATCH 123/131] Update frontend
    
    ---
     homeassistant/components/frontend/version.py  |   7 ++++---
     .../frontend/www_static/frontend.html         |   2 +-
     .../frontend/www_static/frontend.html.gz      | Bin 137906 -> 138122 bytes
     .../www_static/home-assistant-polymer         |   2 +-
     .../components/frontend/www_static/mdi.html   |   2 +-
     .../frontend/www_static/mdi.html.gz           | Bin 207119 -> 207801 bytes
     .../panels/ha-panel-dev-service.html          |   2 +-
     .../panels/ha-panel-dev-service.html.gz       | Bin 23716 -> 23776 bytes
     .../www_static/panels/ha-panel-kiosk.html     |   1 +
     .../www_static/panels/ha-panel-kiosk.html.gz  | Bin 0 -> 226 bytes
     .../frontend/www_static/service_worker.js     |   2 +-
     .../frontend/www_static/service_worker.js.gz  | Bin 2488 -> 2484 bytes
     12 files changed, 10 insertions(+), 8 deletions(-)
     create mode 100644 homeassistant/components/frontend/www_static/panels/ha-panel-kiosk.html
     create mode 100644 homeassistant/components/frontend/www_static/panels/ha-panel-kiosk.html.gz
    
    diff --git a/homeassistant/components/frontend/version.py b/homeassistant/components/frontend/version.py
    index beaf7856459..67c8bbac817 100644
    --- a/homeassistant/components/frontend/version.py
    +++ b/homeassistant/components/frontend/version.py
    @@ -3,19 +3,20 @@
     FINGERPRINTS = {
         "compatibility.js": "8e4c44b5f4288cc48ec1ba94a9bec812",
         "core.js": "d4a7cb8c80c62b536764e0e81385f6aa",
    -    "frontend.html": "157fcf3c30a67a0501852ae8933f900b",
    -    "mdi.html": "c92bd28c434865d6cabb34cd3c0a3e4c",
    +    "frontend.html": "a7d4cb8260e8094342b5bd8c36c4bf5b",
    +    "mdi.html": "e91f61a039ed0a9936e7ee5360da3870",
         "micromarkdown-js.html": "93b5ec4016f0bba585521cf4d18dec1a",
         "panels/ha-panel-automation.html": "72a5c1856cece8d9246328e84185ab0b",
         "panels/ha-panel-config.html": "76853de505d173e82249bf605eb73505",
         "panels/ha-panel-dev-event.html": "4886c821235492b1b92739b580d21c61",
         "panels/ha-panel-dev-info.html": "24e888ec7a8acd0c395b34396e9001bc",
    -    "panels/ha-panel-dev-service.html": "5e5efba829b62a4f66dc0076475a9496",
    +    "panels/ha-panel-dev-service.html": "ac2c50e486927dc4443e93d79f08c06e",
         "panels/ha-panel-dev-state.html": "8f1a27c04db6329d31cfcc7d0d6a0869",
         "panels/ha-panel-dev-template.html": "82cd543177c417e5c6612e07df851e6b",
         "panels/ha-panel-hassio.html": "262d31efd9add719e0325da5cf79a096",
         "panels/ha-panel-history.html": "35177e2046c9a4191c8f51f8160255ce",
         "panels/ha-panel-iframe.html": "d920f0aa3c903680f2f8795e2255daab",
    +    "panels/ha-panel-kiosk.html": "2ac2df41bd447600692a0054892fc094",
         "panels/ha-panel-logbook.html": "7c45bd41c146ec38b9938b8a5188bb0d",
         "panels/ha-panel-map.html": "d3dae1400ec4e4cd7681d2aa79131d55",
         "panels/ha-panel-zwave.html": "2ea2223339d1d2faff478751c2927d11"
    diff --git a/homeassistant/components/frontend/www_static/frontend.html b/homeassistant/components/frontend/www_static/frontend.html
    index 69d66292561..41e9975e8b3 100644
    --- a/homeassistant/components/frontend/www_static/frontend.html
    +++ b/homeassistant/components/frontend/www_static/frontend.html
    @@ -2,4 +2,4 @@
     this._useContent&&u.Logical.saveChildNodes(this)},_setupRoot:function(){this._useContent&&(this._createLocalRoot(),this.dataHost||l(u.Logical.getChildNodes(this)))},_createLocalRoot:function(){this.shadyRoot=this.root,this.shadyRoot._distributionClean=!1,this.shadyRoot._hasDistributed=!1,this.shadyRoot._isShadyRoot=!0,this.shadyRoot._dirtyRoots=[];var e=this.shadyRoot._insertionPoints=!this._notes||this._notes._hasContent?this.shadyRoot.querySelectorAll("content"):[];u.Logical.saveChildNodes(this.shadyRoot);for(var t,o=0;o0?~setTimeout(e,t):(this._twiddle.textContent=this._twiddleContent++,this._callbacks.push(e),this._currVal++)},cancel:function(e){if(e<0)clearTimeout(~e);else{var t=e-this._lastVal;if(t>=0){if(!this._callbacks[t])throw"invalid async handle: "+e;this._callbacks[t]=null}}},_atEndOfMicrotask:function(){for(var e=this._callbacks.length,t=0;t
    \ No newline at end of file
    +return performance.now()};else var t=function(){return Date.now()};var e=function(t,e,i){this.target=t,this.currentTime=e,this.timelineTime=i,this.type="cancel",this.bubbles=!1,this.cancelable=!1,this.currentTarget=t,this.defaultPrevented=!1,this.eventPhase=Event.AT_TARGET,this.timeStamp=Date.now()},i=window.Element.prototype.animate;window.Element.prototype.animate=function(n,r){var o=i.call(this,n,r);o._cancelHandlers=[],o.oncancel=null;var a=o.cancel;o.cancel=function(){a.call(this);var i=new e(this,null,t()),n=this._cancelHandlers.concat(this.oncancel?[this.oncancel]:[]);setTimeout(function(){n.forEach(function(t){t.call(i.target,i)})},0)};var s=o.addEventListener;o.addEventListener=function(t,e){"function"==typeof e&&"cancel"==t?this._cancelHandlers.push(e):s.call(this,t,e)};var u=o.removeEventListener;return o.removeEventListener=function(t,e){if("cancel"==t){var i=this._cancelHandlers.indexOf(e);i>=0&&this._cancelHandlers.splice(i,1)}else u.call(this,t,e)},o}}}(),function(t){var e=document.documentElement,i=null,n=!1;try{var r=getComputedStyle(e).getPropertyValue("opacity"),o="0"==r?"1":"0";i=e.animate({opacity:[o,o]},{duration:1}),i.currentTime=0,n=getComputedStyle(e).getPropertyValue("opacity")==o}catch(t){}finally{i&&i.cancel()}if(!n){var a=window.Element.prototype.animate;window.Element.prototype.animate=function(e,i){return window.Symbol&&Symbol.iterator&&Array.prototype.from&&e[Symbol.iterator]&&(e=Array.from(e)),Array.isArray(e)||null===e||(e=t.convertToArrayForm(e)),a.call(this,e,i)}}}(c),function(t,e,i){function n(t){var i=e.timeline;i.currentTime=t,i._discardAnimations(),0==i._animations.length?o=!1:requestAnimationFrame(n)}var r=window.requestAnimationFrame;window.requestAnimationFrame=function(t){return r(function(i){e.timeline._updateAnimationsPromises(),t(i),e.timeline._updateAnimationsPromises()})},e.AnimationTimeline=function(){this._animations=[],this.currentTime=void 0},e.AnimationTimeline.prototype={getAnimations:function(){return this._discardAnimations(),this._animations.slice()},_updateAnimationsPromises:function(){e.animationsWithPromises=e.animationsWithPromises.filter(function(t){return t._updatePromises()})},_discardAnimations:function(){this._updateAnimationsPromises(),this._animations=this._animations.filter(function(t){return"finished"!=t.playState&&"idle"!=t.playState})},_play:function(t){var i=new e.Animation(t,this);return this._animations.push(i),e.restartWebAnimationsNextTick(),i._updatePromises(),i._animation.play(),i._updatePromises(),i},play:function(t){return t&&t.remove(),this._play(t)}};var o=!1;e.restartWebAnimationsNextTick=function(){o||(o=!0,requestAnimationFrame(n))};var a=new e.AnimationTimeline;e.timeline=a;try{Object.defineProperty(window.document,"timeline",{configurable:!0,get:function(){return a}})}catch(t){}try{window.document.timeline=a}catch(t){}}(0,e),function(t,e,i){e.animationsWithPromises=[],e.Animation=function(e,i){if(this.id="",e&&e._id&&(this.id=e._id),this.effect=e,e&&(e._animation=this),!i)throw new Error("Animation with null timeline is not supported");this._timeline=i,this._sequenceNumber=t.sequenceNumber++,this._holdTime=0,this._paused=!1,this._isGroup=!1,this._animation=null,this._childAnimations=[],this._callback=null,this._oldPlayState="idle",this._rebuildUnderlyingAnimation(),this._animation.cancel(),this._updatePromises()},e.Animation.prototype={_updatePromises:function(){var t=this._oldPlayState,e=this.playState;return this._readyPromise&&e!==t&&("idle"==e?(this._rejectReadyPromise(),this._readyPromise=void 0):"pending"==t?this._resolveReadyPromise():"pending"==e&&(this._readyPromise=void 0)),this._finishedPromise&&e!==t&&("idle"==e?(this._rejectFinishedPromise(),this._finishedPromise=void 0):"finished"==e?this._resolveFinishedPromise():"finished"==t&&(this._finishedPromise=void 0)),this._oldPlayState=this.playState,this._readyPromise||this._finishedPromise},_rebuildUnderlyingAnimation:function(){this._updatePromises();var t,i,n,r,o=!!this._animation;o&&(t=this.playbackRate,i=this._paused,n=this.startTime,r=this.currentTime,this._animation.cancel(),this._animation._wrapper=null,this._animation=null),(!this.effect||this.effect instanceof window.KeyframeEffect)&&(this._animation=e.newUnderlyingAnimationForKeyframeEffect(this.effect),e.bindAnimationForKeyframeEffect(this)),(this.effect instanceof window.SequenceEffect||this.effect instanceof window.GroupEffect)&&(this._animation=e.newUnderlyingAnimationForGroup(this.effect),e.bindAnimationForGroup(this)),this.effect&&this.effect._onsample&&e.bindAnimationForCustomEffect(this),o&&(1!=t&&(this.playbackRate=t),null!==n?this.startTime=n:null!==r?this.currentTime=r:null!==this._holdTime&&(this.currentTime=this._holdTime),i&&this.pause()),this._updatePromises()},_updateChildren:function(){if(this.effect&&"idle"!=this.playState){var t=this.effect._timing.delay;this._childAnimations.forEach(function(i){this._arrangeChildren(i,t),this.effect instanceof window.SequenceEffect&&(t+=e.groupChildDuration(i.effect))}.bind(this))}},_setExternalAnimation:function(t){if(this.effect&&this._isGroup)for(var e=0;e
    \ No newline at end of file
    diff --git a/homeassistant/components/frontend/www_static/frontend.html.gz b/homeassistant/components/frontend/www_static/frontend.html.gz
    index 731cf9d71b744aed1b2198743a71a04aea5bb0bf..c04830c01a9ce36c9f3097e754d9c329a70302df 100644
    GIT binary patch
    delta 54191
    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 delta 53934 zcmV(vKn+Fde|gk`Fv15*VeKu4 zbekSK3$X_b-rk&^Opg5+Sp1O~=s`WJKg%^6*F>0vW7@d;Uw5YK@w_%}RP`OZy@}eS=q4xf)aZ;FMLyj25wm&TTKXVof-moBG)mkgCw_S*xgR zIYVnLr+lQfa9k)ke+X8}=XB4{bs5SI;e)M%;nT}!p(iZf;a}grd#{DVJ3IsVg!y4b ziwGSjV}swbd=huFiY-8h#-SO-Qpr#PkUbP{^D688d-^FonpOF-5qUjH)zE3Ih|7U% zPaNc?g*VyEKWWtsUVh6Z*JXr_>)lrP_b;{(O?Eacwkgv1e8&-U$=A0onG|S;5+^4Z#RE+^&Zt8X6B z-46CUFfMEJuJ3POvdArS#2K39*HRGkN>N!m1pE%jTb9yR&^an)Jc6u92wwkq+z)Ge zNzXAP*B{QV&uQKqDGbz^6felM*LKDth;f@tXV!r+e=R=G{Q&btEssiTHZgB- zn-!8p)z)pi3Xt~UZ*Y0eZ(}EZGlwuw%mL|#ZKm4?7>6yom=#*S++87iNMsGUjq`LD zl1>dQe@J&8y#L!6;+1rZU|uf6NSOk}#&V8*Z)Z#egj5qqvkY(d zT{;z6vqk$MF>Rw3sv)L8v--&IEcxfV=wOtMGc_VGMy-suPp4M+bTA&p^F(M6DUfex zFvs@TkVO<%=s7dy?%n}ySm2*3ij)}Or5o$DfAk7`sA*~CZ*b8qKd(Pq*?^YE1>!iusYrs(i+L zV81Wf#Xfp%mQ17Yjg6FHQ5J@~Y^z+Ge^+f$OqRmeM65tq#hlGG%E*|3L`8kROQ#{) zAE@Z(>`uj6PZs(7VSo5YMLsu648%Q+ii0lZB&RZ$LC#~Vhjf1$)t z)}T`!*;WtVrLlG9$EgVj$9Q5OttUhiQs&c0iF3c&wOhF`OWVka4o9iLdE-8@ZcM%k z0MDQy1b{K=+B;1Za>jQd%guSwX2adZ&Q@1Ar`%5YQN9%!kb(VZ75k_%1+QvavuTG_ zNS4ee!sIDU+O0viFavG2i!$t7eCOMVG#pI}1H!|4sCc;BfnKOFc#Z5mwvwR~uhC3P(QCJJ*c9+M(Nr}o7O9ZuaB z{+2K#uZBIFLo%)&?Am;(F3rS`PbRh^!x)6P9UEvt`x<$h32+)F$x4a|e|{6XO1c7X z1WL?=#jI^CJ?XNYivzp3$8;{EGh2LpLThVt8*O7E%SG)OUqQlY86jE)l@7^*qOI7r z_PBAg2Jzc#Y?9d9D{eLJHq2~2&t4o8!GRT%qQm-Cs0P%Xwm?75KM@JDE?zgvC4}Qr ze?q~qjBivFr2=tcjMY@Pf7@wRk>f3v?aOqMGJ{46xZ(9NzfBM!bgz~9K-4Jhs&Tp6 zb+alSUWyo$JE$<#ILj@b?ktc!>15 zi`pcPjsjTg%tW9#_1(nCLK+t^$&+;I%NS>laS=a#R9{TSU$Hkxe{~x_UJDO?mR)24 z8(mxBS<9sgnH34G0f}5+t2F?ozlh-54T!b@e9!;*X$@JP|bgCM6pBX6eQSkO6 zWlJiewy|zWvuo>ze|A*?*lEwPjN?IEh3ZQRk4(svLtHAy*DKP@x5_xvYZRdnF=7Jmee!!HGKrgGQxB`l6IzTTkGiWNEeqcWOv*k5oU>HWR*0W$8azu2l*CX` zUd($bu*7^(dhq{swm1*QqRbKo*;a@uT!*|bK z{c`&5#eaNwe{rN6aJv!zPWVReJ94vKuk&ScZ_QW$3Zr?4Hb&O-dv5d`( zRl$^}lsB>IMr1w#pt}_UoF_6fhkYnF0Qn$|IS{w2FxpC3XC`1(&Fh<`EH$eMhvVT1 zk4J)Spc|&UH{mPNABlDyMS`}yx02&EPxro_7^10Le_%DP;)JyyM#f7iT}!ReuPF-3 z+INUCX2zIkl1ECvgX|xBiL6EkxiG~TyHKN$QQY}PsjWdcAq+YN;+HpC>2Ts*VxP~2 z24i|qWJfLX1K_ffh%~_c0aNp~_Gip1(dL6GbPbNv+GJs$IA**tf6Gw1taPH@J5b~y zLyX9Ee_JzYn{7A%%UI~Py!HBNJS1z5+%WY(AH`usE~{E2MH)PJ!~)fR6&GBgK?er< zWNff{J&eAj^UmvS{R+E}ueCQ!Rt8#%(~j$pSjNf3Uz!#$mFn`Oj6KHJsaFMLEjp8m zJd%Gak+^8KhszErZBu&$Nm?*Yk=O9y_zfzpFZJ# zcXY3q!K%)BFtmKu1QW@3H)Q^8Ubt1s5JeOjRPV`(0_%x8wBzbTli}YRe}_#tj7;}~ zyE2^N$aWq-`M*}g%w3g5bD69nBN~yMQ;~3&*o>#Uz1^P_^2U7<73g?iw~#@OcpzGU za+&PSZ$|Nh_3az>=a*l?>G+plqUr4sBpj@7pO?4)`JcDp@vF->_4BKf=-1Ko_BcH} zxebp0D>%6y-2UbGzy5M^fB!Fg7l6%szs`T1Pxs)&+dCfie>k~+{Fk)<+pnwP@Nn3N zKM!BNgnz#u;>Yvv@#EzW^zrifGyHh|l0II(czLpWdkjS%QSR^&6x}=74S%igPtD|$ z-3Z3HzuwDZLmh<(Y+i`p?=M#sfB*Ti%Gr;j6o7?4 z$$ePx?`g40D=LwlRs820h|q^leRNq?aCXGvdwdlW zj%b-PEoD59)2pAaf5yi_N!*%@JTLh3;6~a=bRw~xTZydH&c;3ZPBMl8!kSny3-_ZC7N z>vd14<`z}$TEG0_8nEfAX){2| zg>oMMH3BR=yklMSz*Q}o>FfAE|8s2n*lrSP6`7ykKp1;V9@Im@4}{Ir;WX$6<6t+4 zcHsmc4(}7dFt!bcU3!LYV)q^mqh0O$yGO(L0m@ekf25knTI3d*QGwJWY1T-m$H!VM z2^p*<=RYEEP4ajA8b$sXRtTDT*GXd2qhVYe9G9f;pp+An)8r=srjz^R8Gq|>c>G@{ z_ovaXCwmuHvG>SOcfY}O8myU8T(nSn-Q(goFQ=Cu8+f6|-<34!uo-pmjNRQgcSNMDfWEIv34}>fO7??rU;7nC{&h?e8SJ>|@IQ zh|k^8{&;7kRUGXnA`fkQSm7bN=e?R3Rt~vE=TOJQkGfs?^Y(Ta^?!Hmq9EDItx3K& zKfHeiRq%Yfy{*lYInLP$4=uq@U<-g1j@iIilI#e6v$IL0%fkvs5k+II*FU+l_-Y*o zz-^Ldb*?b{s+_OTmk0Yh$iATAT|G5FlhxRB$IsfjcaQyrlWsm`KSOs%uGVPgOgkl6 zt(l>TqjOT4B{*QwWq&fGeMih1uztJb+OQjRpA`zoG3|~j9tL?Jd~GS$@9)r$0J|Ha za~Us>)a9VlGd6t3-c^-9WCZWY7wnxzpsIY$2)LI0GOg}G;!}l+al7Hi%!~m(mY*E%3szO%9 zqMUt%pC@h?Z{Hlg{^{uSAFtoPI(>Hd?s-B{YS0XlVqbpBSPV>VO4d*u%N#Y?r**bq zrqcWq$Tk(mV?QOmE`8RsjC4y33o$}dcDA4ZyxoI&^Y-0~)7L+}dG-@f|=p(zJu4u`?TZRyqP=P!)OThMmkX@K8t@5jTR{?~`Y|Mem%(ogvX zc0O1DrmoV9te$$(=yuXczP(jxt2(QG04 zdCZU5H44mau_=c;NtoZuqA3Qcv?k@wXqFc5%Zm#n!Iqa=>8;YK!i+(m!v@I_w8F5C zp*=DH(|>?Y8)m_ZM;uWNl`w7{1#gu6&c+)``34)O3Avny-2i85^$8ds`Gr8n4#euG=-r^f%@Wuf*DGS&|!Z<*2Gr%hcEeqK@y(IB?<6yr( z&wnrS20fLG?>~~y#(K~95^QmO#}+?l8Bl#}4u92~V8~{c96uTY;7KS8V*JfkH;DHi zz($0H5906RfL)N<&C!|nEUo76(TK+37=VXPKczW^r_c^b!6eM{8hJ*+D{Ofh_kTw_ zNwSe6mzVK*G|k7|yaA2(-o4;5pU<;`JS*vJ3+JGxK|@slam2vaet^6wtL$}gURppA zw+!9$%(kDWpXJpIUsh1dNG6MUS{Xx-iJ}Y% zEP9DgAX}6oo6A>vegWIB-&|(ZRf%XLO6mfSUc6@SGiy~2oo%?Vp@6?l*?+H>8BkYQ znixMFD8S)pP+=?Hr_`~Y!sTJs%sfNB^R%f_kc`dYrL$SND#R>MT-0;%o8>TGTF<*E zOW0N%zwfQdO8LpDZL%;AM7F!t%PDuFMqQDLf=V^Oo&bDKVU z)h4Qu9C%iii_9AGyh=Y~JAZmPE>9XWqruF zS}#H=(B7FSK^(odeo{T5)({i)6{I?>x*?(4dxN=Y5gubjYf!I&#V87xF?2JQiM+|8 zZ1VGKb5Fq10TM|VAQKIHCXG^?0gnX#GM*PFw?!@hXVP4 zUQ?nI(0LEL#T$zrJ6wPTLSacnnT|U3dTaNHV&wmb7S=kb#KD`f<5`^uJYgbEG5yr% zq;7@^5q`Sy&5(c6u(`)~3yS1GTZ*jtTvi`3>O0>tW`=LSi+?80D5^W03U&XXI0;qK z_hKiPKxtN0X4n3VXr%Q^-?EN=N~jtOar{*)L7vOmYz61`%$XpO+Ohm8k8EBIa8V<= zqSCA?m;L%*tF#hzvoATFPCx*}20?=pyW-WV&S!lfF_|_cmB_1p%Fn9QH#O=P1*9qk z@np=8V=OGHUVo%@FlGb_@6GvdAV?XmE&I4CKRRHBwam|RNe?-tv+({aI1LX*)0w>) zmH9b-M_j&0D{zOPhVXJNGu*^AtXnu_XI7+Mj7;IsyYpG(Uu|wkMj|QIS{V}o zEiD~+i_`M_6nP5RM?CJ=My4EzDuA1x90`TuMiJ-#`G3Ek(Gh%m3qN1dPn}RQ{_ZNH z&4}gSz)Co!uF6%N^JRXwPzCN%+Qmna~WI` z+F{K;XMb`W3npVEnJ9B!<-qGNu21oH>h{(%UZ!?@JvTnVEZ`ulOW4j5eCpOiKVi#FA?Wri*l31xT&z`6{$&K`BFt31& z1KR||nW8@1R9_s4_MxX!e*Ji|&zr3W0>m99M}H8V8pcTLcw3A%xmWTg!$ib zb~51}|EYuH>LmI1qqjc|nDG$EX{t@gi`IHLFMLpm14Ab$)>u^6H*0)HGpSVnmFPc( z{;QKoiuXwRAdr+Cr+gq}iWC}SOivEHt9eX(0AaXyg*ZfwmLjpuL0lyU|hG=ppE#7mEqL{A697gP+kZ2v=@shT7UJ8 zVW#{gGP$w>KmyM@r|{I!724Zmg8&WFx*IHo;|k3G=bIm2HO-Q@J1GW8kit5ynB#y! zx@s=p0~sanfpymKg0Dc%giRLwv;XR_pUzNO6X>PUGPEpE@=csQi+6%GkdQii563RC zH>gL*+1B6t@0#7sk{#kZUQ+ZoV}I9}ecYdL4&%ORbj&o{cI;Fb^H7F28Jen$HCdLb z_pqg&Xd#Gk;a2tO3;;VO7vb;~pOy3LaRX2mDNjc~{6Ns5uO|n?;S`_Uja4^d7CrWj z*94-q?k)(5RLKZVs5Q*cA!9Go+Z!|Cf-R@h(6^xcp16-nZ!|Np7G{D^;(yT2_rv>_ z{l^$E0NN<#p+%+Ah`9zRc16%Rq#>j1wDdjt!Nj)>g)n#W1p&+tcf~tz@>S2MOjL# zhYIGZqlT7`6=#4yw156Q%a;9;g4*=c?}tMj8g6MIQ~5>Nf5^(Q4mXw_vC=T{ zkDCkgAs}%m8c(rhUVQAQ`}zPjl-0Z6Q1pS`tbe)3-<;F`ImJMP;{}HFf0H(RGy1)# zvg`g2ZnqYyjKBH*0RNkG;l=oyAI|W7t!~e`e_5>e2!2j$r#{3RulYa9Tf6pRKF3YJsBo^M2$?E{Q{>ERoxAO9hx$XFv zU9(*H5eLLb;&rw3xKAm-U(?@c&049EOS6L|_o#>&i<6uba8EnX0oQG4Y7}bixH%Ey z!{5in33E2e8f*-|*VJOJT7*+Sr^f}NesQAxB)d&!decnj8Qz)nisSrbjQ=DJfA=JU zS1KAmOx_qg_F{5`qR>gJ0a>FJLi?YXNA5Yh{#$lE_EnH;5i76*$1JR!URP!DCTr3p zIe}Mb|Wb?1t zW%?;ED?(CoII*E%a--wqCsqJRpow-ldvG$ok;oQySGK5e*xi{#6Q*zKD18jzsr?$A40H~Dh$bGHKHx}Q&R}!t}Yd* zyxfcm@25Hx6CTGGW>2HYn`>>0aM*Q}&7*inF9XY`WqU@qBXk{qSD+RVi{<z13E7c@mJ0oh74C~&hG;p@?$V+*G(j0vN^5_sLiQNnFfX07@as*$e}?yE z+1!Hv>#OC$T!R@a*8q3+3}3&HO+|!)vWSO4SIU$g0Q3 z!KuI$o*#6WAz*YoR7N!uo#$q`=Ge=yBKHk{g7c;6$t?5f)`0H{>oOnK{C85V*b@byhM;5Qx zvLeSDsLiHBJKk=?oOJ5N{SK8f^#p<3x#RV#48vr-IuCkuf6;h*`-x0T(ex7P)XQ|1 z1>zOx)VjT;+I_@LE{r(=(eImm?^@&}$hO&&c2N$g4T!*J^B^I(4$ zj!`H!8tqfL(f+|SI1hHitPe?)_24n(Jp7)w09g+nQ_c^MSe@ZRmG#4;XgtTLHu_NW zFh_@1!YCQ#qA9)+MKPd?#`yrxk$i#P-PkW#LVeOJe`;3e^&Brk&-1K87i=sIrvqO> zV0zM3kDPLJyM;&ln{rNd>xizlpf12_$IJq{wbQU?*T5Df$qwX;FTgj*n>E!!X7LY} zlP**p_M4@n3?MW3hvq4~)@bO6M#d5R1_Yq9l1nmKoM8~KaR49l@^cZa$CHT2LxNd?xA`;{ zj3Fh56Jg8+$#mBeUmMOY#Hx2?LS+H7CE7^;RRsf9qI>@d7^OZ+!A1TwfiU;D~$9aFH?lsCVBc z(Q?)qP8V&o3sh7bD;(>Hfav`iR^1 z-@{%QN~g3&*R?xzZ^x+Q{Mv3m>e%=OulTYWQQw-j^3I%wq?~+fj=g8)0)>K>>1pwE&-kvZ+bAUwYSGAAy$(tA;BZ1wDaxrBaZV1>b{ljq z=s)@Z?oKN7Ke3cP%;`-s4@C*MrfT9jj*q6e4putE&ZHHAfAzg>iFj*mh^m@zRP!I5 zMzs_enib(gJA=`ciE*Mzmmg@?e`jY-hvQ<}AB{((crpfVp&cHje(%4|@c5~HlC)=O z(FA zPIf%w$H=fC)sUkeMDh{Fs?5+~SK|#`ThLQ>7g}TI9iTA#Y2^km1Q6zHNg-6P!ZLegR`l#5$)pe!^`#aA+4cgThOgGwO_aF{ zw7{ZmeYQF~L#1;z;Jln9OHtBeU9868rENQI5x~D<2lNztOfQo3Sy0*mf8vjFn=f>$dfS46H%4E2 z38oZwwuQ^W%(Pq%H7zo^ofU4nr}*otY084CxR(=43`*coJe^ixoet zp=6rzZ3w!zI!B4;<>z9HS)sr;%b-6-5nfj1m0$(hYr_};M_Kp=)w%CNg>ad}#kgAW zG@xCyEF?R1e}ifoJZ0byr%6G)T0+WdDZiT(6X0KwVi9AaC<0wL6^?=!MnNMGIqWO$ zdB*1G4w#;5Ec9|Xqx!m-JzM1DcZ>8pdM+gZWS{HvP{r`!wJP*Mo5(4>K;qPHy!T)9 zxfg4*bv6)3J083k-CNOY@Ce$`?q2v+4!?*Y*;ohEf7q3C*h>k4AA~TF8E4`O7f8v^ zY^_6zI^?V1X_ib@Tab{CSVL-%pNRw4rscNDCbg3!(&~dxGt)1b#QhQtRV|Evh(D_# zgz}^{rmQD+Oo$+}YF$02uaU1WYQ%$7W8aHJrR7(gE=UmiQQ2&DRMHJl8axQb z4@T{*BJsPOOxk<|%!cBL3JVLxP@r_>y|itp2b~1^m=lAV7@P{5y*omeW$|Acx78P` z&;k<=58$kcV4tSG^&EFM?zU?>bM_bFV$U@LurrNs~d_=#7cl@jo4->EI3b zsxv-AzZH{ZS?6?7ke=1$0@iDCR#s@_i?6DIz~{wfR^`nEU$34o%FknFZa4u7F&<9v ze@+Je&_xXVJu6{aSMY;V_&!mVdW?MRntBh9d5omu;v~B1f6mT6;zRW+Eo!u58PhKu zb2!8pwVsTFIc8z7v2TCNXK36pT!15z4790fqJ;Rb^3^GIdYk*PcS#I~YAQp&(1#d`aAN5cIj;9tQ&0@(wjUl+KE< zRq>Qz8C4;CRPTQ*M1r6BaPAd3=P&f zp1wPL{`$jFaxg^q;}(oiBt-ThEd;>9jmktOG-g`qo3%>yfZ-W2xz_7iTRs**>}7l^GYwXfR@-jIQz`RCKJ_#m5oa zHi~v1!p?@${bEl~zdzWAEv*3UuGLbsXogC|0dwUuo5-GjuOP#Ae}7MHj(xFQUw%T$ zX^j5Mi-L=UUuXu5e+GF5b3c^j`&xO9gzSU$a_#nVEql4%s+Vio%eCIiwbn~szY$cl zjk@yFXUAD4RPlOPDo3i7n2`))Pt!&!Z(5{%F}|+NJeZx#(SDQnMZv>}M0IzdfAu>E{ocMH_1Ens8C{2> z9+sMomr1wpg$$bnO1cep^W9+iC1&pUmS3Wvy_v?-07$`h6LD{-x6(F-8a=8q_kS^W z0_ap~tm4$0tPqbPwEF~9I;1rl>roQe&3rd(i=-Q(lP=N0i_M&|;%G-qBEK=?$ebI< zT=^Gf4!dC0%`+9(b(t+=%~%R+t08u(2OaJ2B`QQ`)XRC1()gScL(Y_exUGYH=&6&)=orv_tvLzSaxz z-~MViP43N(?{^`I8X$Q(jFgodn-*ZA(FMN%lvF_6+^Q6OJf&}IJV4C;5}1y`cCi4*1bL9!1ime_F@}Ch}^gF4}m=Mu4xZ&ts%oL@BIlacf%1 zMq&{SjOhuYZ`cl5A@Ak`T`3mlel5+tdpo&TNn;oc@GY8i`+5%{yuFnsf#x*C#Yx3H z(n)N8iGdzM%^Z~<=v?#R*%x$+Zk@93QK1pE&>)38TTlmPlwqF88(K5Uua=(De;+jR zYI8jH{fsc9L|05)kERho4hBW9qYb`genzgAty7C13=g}d@n@8+c^qP^D0i~$=)z;= z;JUY9W_BEtvI5-^3u514Zq;G(FwiS$X7=LZ&@}5YdPIvcJ;63>mVQaZ2nF$FfZ(>Q z?4nf^iS-ifbV<}fGtp>}4Ngu&e=1}il9%PWd=AP?O-a;fIQ5Ozp*U||-8?h{+ zv0Ki%6$A7z$g9-KP)JP5*a4Z~m)xLGk)+5i%{yJ@Y>(bAkS+T&*C`zGpjdTp}3Z)y3ddnD?zk3wF=wLf2>-e-7ytG zm6A@#vYYk}+G1}7>A7KmCLb6L1zph_M(s2Ht~(%4=a&5dkF66W zJdYYVac}f^`6cRX0iC$Ew<2=mUVnrw{TsR|zV3-~=OuZDy}Bw3e{ya*p^0%jyWvDy z1*XgXC8RMItIS0xi9Sq|Aq)zc9otDH0fqK`JNXsHrAcM6G11@XhR4$x57z@$(Wtim zM$ADTy?*#h^Fa~mky{KhaCAdH5+;S)6~4-g{#_cs0(KxT{0qbKVy^UzCKw$phX(s8 z0J)`(Sth;$sKHr2f9dpOD=Pyd;^8Lhtol)3TSWa50o;qptb-wQWEKp_D@TlFGm#hS#Qg}Si ztE6fcCsB_UlGy|QPc0k43u~C~yEMN^s-ue|0_z)M#`2TS(Cjg}D*+ z7|z6PgIMRRk{=42|08(p)e@2%?APz|CAlB~gblQG6{0=sm zr&FGxaPPvdEM=~tA|~aX5d$x*h7uZ3)kR9iEn*aztPQR z&}h*~_yDz(C~}_zIRa7O<^?^{0ezbU$H&42{WDPyb3)-1w#UaEot)V1AQ@_H2s4eA zSOfealJ>7XG=d>Y)Qb|N_&xr|e!pZYgLLB(e>p{;c}a)*;KcFMUzKo>O@5p2WZ2NCyPDO8i>0`}#iOu1#~SF~-m8#l~K`g~EARrq-C;66x3&3F4d ze@XV;{=Iw6?k+bgpqS9qM;+b-ty+v=+%Wqny10qG2tIZlm{pb++-f%w8aRv)+3+Ok zw?3|{wk6K{JV$5KAQ%UXj0T$(>)u<1gkL;5TYL*ms;M>B^nU;&r8P6&1>PyN6dVe` z&yVE+(Z8zu=ZowM3R*Ia^DLMy6Y*m`e-RDz8Pj35!x@pb=Co{^cd;731Xk!b1lnSJ zBhOrxHxUEw!?~I$cSZ;9OZ< z6>WX65guMmH+i{InWU({da1kKfJqeuTSwa-dZ?FsmG}DhGCz2U?W}W|ar5$^*N~L#@g~v&utO<)K~W zkyhoAS>+L{^2o08y;kLWvZf6DiEmB(6@$7Yqstjc4%$`4wVAIvI0uqr>;RYpS{ zC59Ff3^^7IooXY!+Q_OVkZ0sn)6rmL;lYR_!br!2nx1K@4a&q;N|m)Ktq;QJRZYhb zt2FT^Yi$d2V5@PK>}{QAxk*~9z{)vILR$N1G1Hf*wTZVi>^!v^78%~we`TgG(S~vV zzkwY>in z*|fDEe51kShSu&#eZm`>bY*JYw)V&CZ|LkSYd&XLG3m^8S4`{{iv{566MwQAtB!Bk z;#}X@3_U5Dn}$s$M%%gGe^k2Qiyc=B4aZ>Dt7YWD_}KK!WXQ0e@;XO{q&M^3kDOW%Zq{ks!j94ueFezLGZnH4d?odBn8bkepk(*&; zYQU7{^+V-UWa<8@fA&P3$~?oay%|8PIwkwNcB*a)c5A3*n7Legq_%94ebQrq@ONtd zhhVxtP}}*jP`kYl4Z6OMuJW!0?)t45+( z^jmg@=1%%EjZ)n`tC<+yNk7W`m+Q72H@e9ND#fWpZ?ONk?#)(b`3z3O-}0;q2M^+5 zJlMx)6BF4Ge^ckEdQxe_^CdOu@6VS;!6DkW(Eof$VA?)l=u=s^?@dm~7H=;rNX z-T|azejh9A+53^V=L4r_Y~evi&yPELKJfMYz~A!&r{@R$dC8tf!|`?fM_NxHiI;M~_-ZK%MXN z<#k7Z6~D(3JlJvsF8HbQeeWb6h%OF>e5URQBn0~pw;RH~i+t4k!DHVnX$U_cjy>Y| z?+#%^NJ0zoy=M%qT!_~O8c*6PPZz9Ey`?EME4(Md*7DCbpQSM;dS;K~Hdm%PuWJob zTUkwmf8e8Wot5{yDnHmz`Jk)vqYafGbX9)5q4LA7$|LG}Juqtvx1(libYq#Ahzz^> zv1~sHM!>~+TeAwaHm(o0tE2sGI@;f^qy4Uq4z}s&V7rbEx;lEWO-B#5>*zsOM-R8@ z=;3x9J=6$Ei>p{KMd3XCc7%i#-tt97FE3_`f7Lu|qh0*Pg{?wlm%nYAMXn9m)=F5J z^FIV?om~lg{ULB_KftH5HG-tAA46mbAJuRmPx1@EtJ;&uhvsBB3Dy&q-}>AfMi`Tg2j6E`y}?8HcjKE9E1%(s zf3UXt8iM0i-I|2BRktPzZq==~xm$JXjeDo3HOEz&gIIhrFhx}KrvYp7Sy=QA{Y%nk zwfkme@oERn+eG`(S9Wj?`_bRLW_738_>I5GQv8pbjDC|o#{UFz(#^Qf+}_{0=)rV< zPCeR3v6A1``g>Q8gbJn2zRi?bP47u;WgNFdU9N`om+G!+ z2F=zsXl%H$)nXS^;qn{aeSTI?~6@|4=N2BY0S`>gev#i>9YI*8x zcGd5Hdd5_VvqiofqrD1e;fIzDCm97U;5;IuN*H~HmXpWFr%3!yPFigtTiv(Yf4;R2 z#XJ%NxqQGea0iFtHDg?s3pl#bs11kcErMvm?9W;s;u=F60l)a>6;tCulciHx{q}q;HT}$rS5`w0qUmA*P?`UnHgJ>{RzrBq@=>%!PqQy7WaGjie}hbjd#5yC z5$F(v94#mrWs%Re*9<7YE0C(6(*DLjf;&xwKHf3&-C?khnysWPPi?3OK z&YKwzN={)nZ&0iY3c3Oe##yp=Jna84h_n95-db3cqf-cL3%PNre?sQ%2m^Xf`7~+y z#u%T?0+0)lM8HJf-W<@M_-AN<4M)_cy8W4mNqfU605w3$zd*K*_&I2=z8`qPowk3A zsn}ic$!pLEY2#`>>(~Z=&CK=zPUxN(*#VwHd{S}IE6;l~ky-aZj_Hw}Ae#?_cR~+% z+Q>t+_FLN80mSV(MZo6?LQDc8N=rGmd1lig_-y6 zsbJge46vL_dGPA?R%|TsJceyKJp{V3$!T)~Hip^Y3dk#Tg`=G{)t5vU0TTpyRbD-p zTNeR44DK#D>&)0hTS^}{CzqlZ0V#i9E1-V!d-no~Q*!T5F}&wkTz7LK3UHxyOg3O4f3WiKfWaQ{0Lwu3dxHk`kY8NZ8Bt7gm2aJpgNupV~!qzb`Ln z?NzpbpUI8mlS<|d@C6*b7kvFZ8Fd#soX_Fh@fT}1$)RVmevVm10yc6t1aW^~$KoC6 zrU1hm*lqeSlaNEUl9t}O0$W?hNH0v^05MH3>`oY!T6Ma^E=pPydLr0bC|!I`uWKsv zqXuP9!7T&}vH8o&BbCgAb61~YqC7tjSTWKwwmWH*MUEUly>y|RCM1|f2mp_{p^YEi?G;aG`=V{M=$FHzB&jq|IRBvqncb$I99K5XID68$xXR~Z+BlZ;(%<<)&yJS*#&xTc_PQ;_vwEbnpy>G$52jx zRlGsM`j#D2TreT@MC#)&Y)WGu*_dms021~4%d~j~EA$>!SjPdK8ZrH8@+2~4n-o5@vIKFj9t$YqUr#W$Z zGBUMAhk#9^z`Ue#VhDfnkG#1g-?Nrq9??DZr^w7LO z3VIL-$-o+pbZ%bztHnWo6m+_#Z>y;Mf7?Bdcx3HMg5jZlL^}bxyEF&r{~do3=XhAm zu>(ADpQV5UCL>y1>mV}Ff?Y|okV6%ZiNMtt@ut!uWURjk#?fikvy_xGd_uhCwc>jZ zZC=JpCqQ(~DE5E6OYqwLze*3oNF<`czgAgweMF-J2_hi=6!1cqx_YSa(RQ5bB?+J? z3%QBDVy74d1~}2MF{uLc4YPqLaJGAQHzv2UDrkV&Bcq3mWpd>Tc8`j|FgRk6ppg-Q zj&JI6Rn0QG!vQfPzQI@pNkBE5ahqW!i66Xz@NnNsL)PmK3C1*q_L@9* zhC27lL?@d(FGG1cB$W5_E>9+a(u4B_#uqRYhZcJ!NrMqvK=%UewMAkmj8aN}#>A8@ z?UKIYYG;3PP7)41Eb*JSq)QyQo#&46PWBrf4^TI3B={^vyKh>i1>PHLA{(5`c!Nwi zo5F#6EDt=uZM8yhvBJENvWDg5z=z0!d$53UNxDksMk-|4-`m?D5ZWBBWNJ#*co=bg zla?|un?pT~b|6Z*Eg+T6ZW8PPuV>aUk8G`mAdG+Jbn*DmRU%!uEd4nBp@__F6S$og z8K6%r1Qi{ly-P(NIF~DK`s;b9Hj$osC)TS3*~^eS4kVA80HeP4X_?V+f1J$9%(17j z2PnQbc=3|Y|A0wND~e-I9Z(_mE?!vLS?=!G%P;RHuUBW6AXBefcDWd%*y4NPbEZuc#_Q-!%O4P>!Dn*BC1?tVn+^)N9<0z$6;AYqzZhgr zP;CQn!Fto{PRFkE92Um#^@y$Xn9tTO^q@vNeP*_LQ)I@XJjnTELw1X^(Svz7jL{3| zq%~v1DoW^aYd8hYL0&8K(QMu`0q72h;k$qN>G3=3RO}7*9~w?(tsH9ts$f4$YgE~o zL*`mgYq+i6@Z9}Q)!W_TP5!?%^E+boXe+GNCtp)!?M)sqThYqn)X*NaJHmNd1EV(C zdeQ#C@hY;$PGNGSwA5*k6`DfE|)KdMqd@R@a>tzq2|=2ba#tkkh|}{qG-s7xkDI>cRI9_4B8z6vv%| zgYUM2iX2_LgWBH-mOr9h4liwAwBmmnZ6!al$*k6u)(_*aTWo&|eEggD?`CFayG3P; zhB-#<%nSo7`Y#>RZQ z)`#=#0=-A#4ugTD9TjAeyH9Bo>ap9b4O1Cwjz6iJWnS<{5%JblDL|uM^=5yYp^4g9 z4`n(FbvVOxrimDaZ`S9geR!i@Mh@3oP>U)f(*p8SG2mB^g30!9;bsZ{ zg5Ljwjt{pl{~>(;4>^F%_db8*Ks^as^(p~-5yXy~BxtHt7WBl|@v&}fgAax76=(Hw zqB&RR?Hh7Zz_i06kKr13y52*(5-m-+&0X)9ZTye!4jrvaMnoHO?9adF( zy>`&Qb-1jcxc~LSfJ%SFit&sE0gm0n84aN*0QB49rDpy1l3%s(Cfl6Tm#mWZ{A8`# zLj#MuHivcmt+59KcWjO-`PwrcOx&?iy{^&rU2Vl;uVpTK)l~7p3-k@Rf!8OkbGjF| z#;0$P-9Wy-5bsvl#=I6KRAq5-_bjcmH|cVKn!WesGoTX-ObUOU#>G<@ziFELy2vzJ z(BArpG+%?(Al(;2$Kp|iIj<9Ohwj>rGxNu5*9wj8O7&=jK9l1UVK(EuCFM@tv>@ty z55+sf)=Fo9;8q>P`It=3T2171z)w9hbNXRr9Awcu*3p>1s`k8>Wv}au{Uok4orOZv z_no9AlMkC&3kiQ)AKhvwbSsL--dZJJsV;-NX5;csSUm4$&@lVE{z#bb^Fq>$uu$Qg zdCn3|7z$y0uLaEAYTRt#jO;q-SZB>kcD#f;{OvFi)XstNm z|06Uso1y1t^wx}(7f;Ua)PYvaY@IEiAL}LsJr+u=2S0ygUPSL{tY;ni=2C}ovcp|V zx)~!qE)C&e9p31}7&rVtDI}+%Kh;=UQ?nr8*gSa5={N``MWU=Dr<$Q;3us_-*|WDE zkrZnW8mnjQ#`)wTj%db1uEgA9i_vN$${bT{Ap4=Imoi2r9wHTSmJBC_vB!_IlS#I_ z8x_10HqU=H(MD@FhSuUdPT3-?gpeiPcat@5lmgvY?IuCbQY;2hoQo_a+yeje{r}hYLX%x9&~| z`E4MG*4hIr%H_;9R9LB{F~u%pU4*$_Ag>H%Xs3T-n%Q$~xLHrno*liDY7?>i9h$0y zukCe9+aOY7{D}r`j;ed|N8HWd*;J0IPu!bN%Zs$Mu%Q8*7@B(SkbAS=ojZxW4E|qj z11F_VU4-;|<1wDOxJGfA#t`uLd|@UCW3(kY{RswUVomt|J<;R2Z)uT4-TnX5+)Puj z{+@rkYj&%`yk>OVomd6_m>UwS(HY=x^)>BLMRyLQDc5Y!{s{91-U~U*`;*%Kvm37& zyf#5tl#?^A|16L$c&K4FFuf$m-nON`9Bu(yl)BA=c;qySVGt$QKqz@LIpNwf+2rdoJl8MC3_E(T$MYGo~!z)@f}K`QMp$F zz~KswH*b$C#*dGAwI_S@gR8)CV1j}h_YG3z?JC82!?ucCdh$f?=Xk#4=P>(o9J2nD zm}c)BpUUAGFi&v)RKywbo`ja#Zs^IL(~fb9cZ^6g#C8Uxo3>jcFniPsn(TuYjaz@l z1}pGs2u)LI8mjJ)iX2qw>nRRtf){^db9T+{0nB$d5=G|Xxt(54dxO`BzfImO7|PQx zOi~*5B)DO2UDj(2({BV%gQ?s_h2#ix<~Zs2m}hWCg}5ZPb?L!-pTAnCy=J_D$3pU@ zH)hKZ8ZNL%Y_#wL6L>q6wp1;M=kI@%ExCTo4#%z?3NbFAn`92I*kiUOCWUH8- zy~YpG8a^18P2mTd20a<)v!LHpp5BbJ()5!+$lr`JIPwn`mAY+nj&O6zE!m3wEgQ9C zb+aO*Z=zo#{b!r|7TNv<)%~{@2ds$4Wha8{t-2sFU#u6i4A|2 z0eh9b%P#P8q;j9@cDlD@L&1MA=YgmgBnfVa^1PS1KK-Uhc*e*Y#D#na{Jgw+Lz5mb z(Ks~cDOowxsolBKH^FWb#br_qgb9qLbo|E4DMpj>-o0|bJe8y4z(JK!K6BNXi`L>Y z+UTOf^7k-xA7!7KnswKug?<6+c<(cBR^L&Ysm*@py&C*lj}zYxG#Y=r+2w@i5xVs7 z#5LgG4kSOh`HsiD;_1-;EXoUz@X^NEQ2#JPF<*oaH^hV2`@;hDT78mn~OJIx(sYp*^3u7lUt4=zV&| zLo)t0rFWjA^-_Ly(W|Rj66`TG{ay}uQ16`sX_}#<`yckd!2bqI0CJDbBMBfOc-niC z_AWuDOoDG1lL7*x3}MEvt8raY%TSELgxf4h9APM;Nu%{;`T2i{sd;Qcifb0@`g2*$ zITylZ@t=7rV+~X(LtM6`#vaojbNKoSNTy6Q2b_{AjQOCiUI%f&%UKAFVp27OUIhz` zmxwVB`vRWRH8nE<)L0KwDkhUuBnuDFH7IH=UNE)Ut3e zW}2X0{Y#g_DFGq}{YzM4UHuD}>?r{!8r$0-L?f^4czAMq8v;It!EUx2M1j^H$M`Fk zEh+&g3rE81SmJuhl3B+mmtQIY6$0iWmv$-vE`Od3Mf6`ZUjQDG4If_*#XIO{j%^+| z$wh|G$*?s7(R>y?O@I(sEn6?9~`3lU#+2aPZbyvXW=Y(O*3W-CuxhcU@v zAab4(P)mYTj{fvK3u}}Yi8SUl&WS>?Im@7}CJRX&W_%R^1;PmCCpV1)a9Jvr2BmhH z41W!laaE{o9~L;}J@C|Bd9`i^-4(X!nweWg%k}iIxs0yV-V)joAqwD_O~In&Od$aa zwS1q{TMd)HMo!sq9<0|;2Tm>LDC&!`FatC1`wl!QMX^AQURevZLgJjGk0cK5MRS0K z@kqrFi?-(y$0vBwWnV}wH2)FVubY+A7}&A#yy5>FyTK&p>?S=kjNjErDr- z&-L04EyL|VO&kd=oT0$>tfVYb>v_ayz7(6z0Uw5?X?3HEgMOJWnyf;+;yS}~nV>WM z;@l7<9wUZ$iFqh}tS+tU?A_75oW$Jz>JS?u)F63wSV;l zAk@{!ZabM2YmJ8|`~5SI&(RX=fHlpogW@I$nTu-uy~X>Iu17+n{V3{>cC+ZaY+`mR zjH98#`%+n0vwU>2=?-K2E_X-Kcg~nDkDRPK$ zmyTEM6HRzo*GR^_doqBO-4?NlemJ^kB{Br+`14S2?rYm+8jiEULVSSep+mxV2;iQ^ zU{@66N=@h3Lo%~SZ_lB3GJkrE%{TC#I4uUwUWU1ea}0E&ofgOW$s}iSZF~q8!AM1O zIX#I{1ocj1$tJpUZ0b2X5swc9f>?cz*~$tK@C>J0IY5Lc?pEH#C}Hc4K5uIs$;d|ef)Q%5vS0*Kk3Pq#_RdEj1`YyLkL3SoQ?fwq8ot- zi>rumS$rd$c<+pK@7+5in7e+K`4lZGs#M0`2*$aF`ICl(cv8_aB3dW8rf$G@SvAPw z_VYoFm#HHIQ+Ww!{C|)SD=bh1hyA8mKOl+I%lL3q52eJ51@VoPQ8SXfFpR{F4wT_K z8qAp@|7WJw&*uErf|L4elRW(fbpozX?Z!MJssGG6_l*q>BTgbFC|u$5oQ!QS3_mnAO& zApt6vM=t?A0zToFhA#mif0ITCnhW50T&~p8H6AZcP?acSr+WC&9q*yWdl6g8;f-DP z(?HI!gGcQ+b@ix+)_^A3T8G}#xehf3!92G`0K_TYT95(`P}8>#txW^3*V;Hf(QT{N zT8j+=Bf1;(t}S4VMNl-Ick^V(ke@W=fmsmv06{;Q7Tn2iSeO|De~C9T{aH5+(Xl0y zmkZ|oNy}+z#@BH3<1J6zlPzvTYi@km8uPoQ{gVy1Oz+SQTf1KUl<_mNl&P}SblO%q z#R{CVLpm=m&~7{{=4rb}BahK0kHg((?&A8?SUyW}DQjiL`Hq#M?txR)%XGvxBilBp zmd)k3Yk8x_E-0z3e{0q*L+(OL(eH9QbgfnE=(=xfEtpQdse`&Hm!76ya@RW1*s#5^ zoVqZu25nQ85zoy&`5mne3fEFrbAb}J!`r&T6IJm4;vIkzGZE(z7)B@?-W)Q5oC{V21$aNyki$yTAUZe;X{?MPO{|{IXc=47PN* z2NWFSp3cy5LhJ#ePuVgg+h<=ZUWJrzPwVlfdJHRn211fvqzo%2g6bS)4VtaMjOy%& z-f7DyN7|B+en@;e$fe0m0t|?fzNk>23Kvr-5yKRGw~%X{~J4`q=jgLW)9+tEWrJgA3uR+&MV zLvzYj=@HYhZ$<@81uF-Fy1QV(ED+JQM85T)hXoW}%j6B)JJODiiHaoVINqX$(bzj< z3X?z@gY|M4qBa2UGT4=I(L>a#pp`<;-A*0nZTlu0f5w)A!hdkw-i91!eAC?KC^A<$ z+86XZ#J~1H=#UN z@R%FloS&ah$e{o^!pMI^Q)3yf41;8GxkH4)>%I<(1%2C za3CT)f7q$YJqv#N14MjHOX~rGjSuvx0CCrZwetF`=^csP4lN1A{}3TJx?0wo(3<|{ z3jS`4<-uRNboYQQ`IqV`>qUbr#mcaO$K9pa>Gt%gEryR~R%eeaV8XUtQuU{Xzhw>e z#ct^+fRy2Cd${uL<+?c%5w?apR`Nt^)Q=7Hf3x%4?OI)&rQtBf{{{z9=hD(_)`KFg z(APP8v?B5FbG}$`g}T}=Erkb$)zFRRFb4x@;r|}M|MZcK9!AzG-?8C-XUpEk%ys21 zd4|Sr_E#Lk84;R8@q}rZbi_*eC$M#ZK;8%`B5xabct@fr#vRAhF(f`B9W?Og;sSP6 zf7e)IqsB7JK5ndFOnSRMj4E4n;&aqx!YyvvtB(ww9V{^ZMymwJ^iMHKDSjC zH+A$9TsLPHYMvey*Inz7B{dZd$q48tf0|>Aufc)as`F3TKk)31w8!1rNch-<(yNCT z!1y>!u0Rsx(5uJwyi~-M6?Z+)J3dvUJMM|qhw&g3pVRupJ&v3afBvp&faE}Pe=k#B z6!V}b?(CQgBYYXC#&>)yeoKe%1YTHN^bK&$AGu3-LHZG<$^jcAV;H1?O!LM=e@#m7 zJE9{(Gd7KMnFO;%S!b-Z!2iCGb>SNutHws>ABd`tFV_P;u(|Bca4K&st?^2bbMiZy z02Zu3NI?stSrbg8+>F~-`bETXp+6Ncm$i(*kwfA7M4|L8F- zj7CG+pPNc-^iN4$vbULsGc=+1eO+QpktFDkf|Dr5pafm{%qbmZ zskoH>qWtE5tFj^|F zyeJyZRp6l^OB8)fZG zMuoR3U{WMf$Q>5>6=~sKB33!?l6Awjz){Zxu>jV$1D0Z$xyiG7ZN4ASM)<#BOzbE$ zM`SZ$_WgvVv?o(hrnMJ(dePmzdtrdAbbxp10}(a?%}Vdx3y5&KIsB%=QZ;LbPvW)} z{z1?hSJ<^2%C%1KR4zxf3XV-OaqY_#g*2blzc3U zKLIGL7lg_KaWB|y@J*^}f_SO7KwbfSuShfCZ3-VwHeyTYZxe)tFhf^FiKzaZgTxkQ z1H5j|7lWEzRLp?Rp}+SE*GN#<*~cSH!Hdc>pu-<0REjc;Qvb9{WcV;k%ZKermWX)S zB6t?tjz)hdf6LB`(6+(l_wJO*NU6<7)3t0%KWwyBKMSA*?~JChsE^=TvFw~8KV*fTkM{%RdQ@c=rWL)2$TU^T!84J5-xK)nVK}Vj0!gf`2_-di*>%<_pHBhvv5 z8lHj4&G%)ZKQ^&NZUI`8bO^BOXx2Ps_^Y997v?=l+L4cO^PB?v$fPqEYD}T*bB-{f zbR*Y_GkR$qhh@Yp1E+Xv3L(QgY+s#kA4QRne_71^+h$MbOkkqZEPWw>++7afWDS9} zoT}mNX5%axv&_7p%&f1n$C(8CKfU%YV$Kc%&A&)%RiQh?O4L(&R--e6js%1OZvJT3Z9(8fqrN zhGRao{WaC`xZAECqB)Z(Squ*L`}9;F0AEVm4~%`m zpp@sDHXnAb))YPF>hcG9%5GuXe|Wh!StaL(;ux-U6q>*v1cAq=T9&(fRPG*)msfOK-y5y3|Gl#PRptP zwwK3P9WRzq*hmi^yWug}fBMPSZJrtUItz9iwzV6jL_!S_$PtP_`(BCDgXB!tN-+8& zkIAWNvb~yDOe?XUCT(*#Az!Vi6}r#8j0mIA=bnFZ1(;e{pU*D_&-`-6)|- z#ViR{Q4Ep;`e4NvK!;5@jH3EjIJ_H0C&`Mu!S&Fk+}0he&2_1`kpfJeMt=%3pBOto zJmo)W8)BK#SQs zh^4k2hRVO4wic(tQ|>92Wsh}FDZsmPMEV2tQtJ#UVRH!21Y#8?7!MYJ4XBYS6oRyr zmH?<)zMG^`Y;S*rD4O!qIQ*x1>)z$7rjJaBHYk|<2uEOee}j*FWpD$TY(YD6=@J`Q z!v@ByIWd~y3?gof2##sK!^BAF0M4WQB$1!!ImIl<3t)!!+=5dclUi6$K&5a*TektR zjPz*faijJvfSkW46UwHPZ-i9gJ6;KC`v!VTa2;j7TG1(|7kZ}XD;m3*5e!@HPK2ev zK5rc3ltF~Qf4Sh-kND6E*!MJUj#G?nu0n4kK&5&ZyL)kd&O>{UPwiN(g7J=qvx%$_ z3{h)RoMGNZStf6m{R4E!Pr?6D+h@p6E+FQ|wI zJmT4(KYt!vl;y=D8-S?2H$5*)D1Mfbjzo6YUbu%vBWid(BY^<6`+6!e1$S;m&H36op_`Y=7beuysX`pu73! zY_WKsUu8ZszWwZA9mC=uVW5_G*+urHEo8!}e^%I-?+UEw?+?}Ol3ERAlch%2`NUm5YTg=* zPL1sV=~U|mr7V6oU>cx6&5bqzXYQDn+;xkt&T86YA-hCVBX=ded08|c1ahmD(S{^m z$r9`S71U1ijGnYnFm1rGcU&XG;Sugbe|{|jKV5e#yqm1xqYUK)B6VE+`VBiT4gx)K zN{I(AS?IN3q6SagUoZ`JRg$+cCRr7l!H`@?XrjQtO1u665;XxacDLCrq>~_Pg3_m- z2_bpGuW(B+Lpbf79yYNvWON2Pe=8Te z!QP&Pu4)~KJY#Tx4QV4@F_(o+TDNObw5R#RM-YL>nDTZZ7kEyI8T8T{3G6hehm3KdeC6vrj0kb*-Y*Ih7^&XfRy3e1%2FAW8z9AI#Iwn&SQ zSUcyg3GE^wnnEx261TU)n~qUWdRu_va-|$!oOsd580pDn!kk8_BMi85f7q+jEUaQX zF&aZEqi>7J!oh=*)@bTa9^ZY>(#$VKv*O42(yDsNHaJXo;mmZNDA5WEGLnTgfZ%ZQ z%=9XACg0CVp)!vYgQ78}Quk^m4}f!Q!g<6UNrm&+w?Vjs6>A)=&nSWOx>=hb+J5&& zat(Wsx8%xYQ?|i0#(TGkUSTxmzBQT1u*D1w-SB-}3-c!OQ;pkP4F;h;sO<6{CPhuh|}yB%gdGJv6&S zbXtYBURZq7An750tBM?4P?4oOHAw}07fKLZWN(e+QzTPD!7}@*V1cN^n?qG{>5jSn z6&)9~#Vp_=n|PJ_MC-_pSY%0ls7Ihaj5a;US5hHNv-n^tbeFTD+FZkC_vR(@Zj|0W4 z8@!{c;{^K^Tpv2L2@ditPK~R-BqGLn;Wwj61&FQbzm+8tMm)abE>60sBs%PN$x#U; zzkxW)kN%=vjM$K<-8uY=DO&&gm?~lXBH0~jvT;U#SU);>et!BZY+=dts0Z|~VS0E) zf2S?JimfTEyBOn|J6pgQ;#MA!l(5OQyy=d{8vloG>D#2u7-_R%^?xx*qM~NVuA%L9 zoql1Q%tR_^>dKv5Jvg^Ct&0o%FGJzBwT@2%SUVfQv1O z=?5QwU=8>>;ky3xGC04>@f9AP|DNOfU;KD|;{)=wpTu;SHRQ1|9b5- z<&gSH`KN)}*NQ3wS0owKZ@5jA*y}fv&~7Ke?IOMY&LYh82X-QTbVpay1hFf&IpQd! zB_O09H7l{7?I#c3TykB%4Z(9wsiY;m)h0uIygra>5vR!Jc^H4 zEr`VClf~p&AwOkoctO# zXe-=@^O;QdnYxdb*}gH!aIf48JGbTCG>py2Q05OA>5I%CTj5LmPcVgnF&g3SPgZ!}&Ba|pq#XH>yv8E?%fFCEZFjy)m_xJ8@D_qW!4@pM35;zfr(4~iJun~P3 z;b0h)-c+w0w~C>qZu2#g0YyBhZDFL^V(4ySYWp0Tq5&HxTXL%iJ4Rtg^$W$yW4&A) zlGNRPe)97RSb?Hb=D%Qk(dP*orp3H}$x6L%QoY9#%v07t+2s`lo0V{H(RKV#JoNIf zT=a~C;$E0o$Z!>GXTjPqX?^i{{)y}_TtA!+KIx_l@2!DFNZO++fnTTAlEY%43>r5; zpBXt?u<1=D8=%Ew0^5q))$7dGb3UR&Sg-~2Bel=1&=;VMvoZS-r_q`qKLKmT!tBh;Tha%$ zHMZdlDs*Apt;Q%3A1RscDmE5>#J$VRePohz)4X#nBalY@nmRA&1h&eH?q$@0(<-suf9{wqR9f~H$;=g3d z+;JpNqaR&l`bp#J7*=JQ;`J0e^uXB<*>!8D1nAQ*UqZHp3pq86aYwVgB2=L4 zy2Dak`T6y=@j>TkGSZF4oYOT`N%3}Cm0gw07&O{@EhVGJ=|y%K?e6aF7QO`C3iw=9NRQ_4gcD)DX(^s zYPfYssWM6LawMVWc_2Wh{(_UDfD@F=$~agoXZ>eai=$^_*zt0I1W`FWnrHJzs_88> zO=L@KgJT43iUiPJX3zGq3zP7^P8VsA!2b#ybdeVMaxqSepv(jGrU2>^P+GBc(s{O= zZa$r7(@YAOu(!%`UiA0(5xTYluao8bFb2k+Z;LTtd)br6h`I$FaTX-8&xiJV$`~R- zLg-rXMlZg$YdAB1OH9Fgo9Fl)hB~*ua5DMK7+()*+<*@oUB+6Ze)lV4`_Xezj&Rth z-FDuFnPqjD6Di*Wy4p8JYu52MY1z-VDc2@`c{hUKFjHNRf?w z&F`q7(%7_PqPKr>FOP6}WvA!Ap26Pp^;&+wUHPDHVGqz=5soXK-YMa-$7&%Cm$UaX z^yj>^(`GuhP&^K=(is^({mSM})n)E=yML~ofmr8%Y5F0Za-TS9I3_p14HTa4S|TZe zSWV%uCN~E#pP{g`5dIBeR=?3Il|@R1$q2;ThIS07a9(JDHCVH7a@f7r3k+ifXm3Sr zG^==_*y{C-4Va^7zn4A|Xk5-wg~@pF!PeawwtBm@gNXLf?==Yf=u;Wl9skN}pO$r< zKmO`}&XID|_5SoLddJMVS-vdJ7s>d2EpDEC#Rxy9pUTGGA02!}@8{6VyIC#Z2T#AY zZ|^NZogW;24O;Nf5@D+A{;+rO)w_nh_=;NebPpbXD#bqdjJ(FQET(% zOOtxYkki#;h?tgX5oZmaT}x6+_g=IaFu**20|z_Mjro3)PSk5!7wG~xG@j95vjGc` zICDy9y*CVlvv6;t`th1t={zfdKNa1+T-&RtkFnKP>)=l2^AYNgkJr}dhas$zU?5R8 zxS4IjINsmMLL&a2#E*t0g|5ABqmpP{#P)~i;3qhb?Z=**w0Wa{ z=Away0bT5g5>(&ytoDNUDDVoqHyM$Bi5A$bV*Clc{5(mSfJX8HmPCwY@W_(MC&m>J ze>Ts7?N@-_$_BGd>d&w`L;M1GwdN*bW)!4DHN&gbLJz4GX+u`7;HbP^CbuBxgr%{JRSA==)dm?LVDCDWkMc!95mQP6o>$lig;22f#w_Xg~0V&Wx3_|Y0Q;C{YI`^&|&MQ=^nc%Qx$ z`?#PZbInIrH=X(HCNf*|gIOPj=D%uFH`sb<39^`b8;N_HWKD@9bN+~s$}D{qpFY*d zKI$+s6b6#30*+Xjk~wHs#z~Za!4ZXGy8FN-9&Ckk+MfiTxvs+h8`o61iTBjJvjQXR z$yv$rt})$&d;$H>*IX72s@SN-gS(K6o2#VNjqxAj!9n{ZNcZ)~iX%dg`}$D!9?PGG zeXeo940N~v1f9d8iVZR83bfe_dP$}g^aLGZ!8S2RGobDqs22^6juJe7rkD{zK)yE) zuIy2kaU{XiIt|Gf_k=V`sI<^APz7dQy?V8hPhW+HSTz{VnMr0;*i&5My4@{Gn>M&! zFAY^td59E9dHh&gUgO`ZYDG^>1W7OCrmD8m0VnRgF%?8uiTVztw~c`F5H_lgwILyP zzHUU_2Gt8g;PFrsc3O~sb-TS5W@GXjp3@3Kq7_Df%!&-YUf$Cm*%YzJSECVjq-vFG zTAchq=Zl`!)1sxEbRySgg6LK#;v#GWEJ@CX$8^^^>NXjaXD z7VoopTZ%?5RHmn$PbKDtoYmDy?lJA87z46(4YXB2)xyyx3NM&?$(hc~3*T(3IQuJ!ZkezOC0ct@(=p+=V~AGGa*uhPVM9rtUZmacqx ziAm<=w}YRYF^3IhMvi&|zrJ7|WXl!j(%8tk7KHFU&&H^K2_59etyJffXK-Z{&G7W? zU&AO)JNXRFriaz=lyp~ezTS?$>QC<|kTObb;a`eH01MbD=3)k39X#CliuLrk=fNUDCstXCD zK9%T`m8waatfR-bW(P($UYqS^nqBjUJYp3vc458B_1!NZ|1~(&nd3u! zYJij{NJB-B0>{kGlGeS?tO|yY?w9H*ombjka-$RIR`h`nVwB_upDVtdOOs}8Hggiy zTV6eXU$j&=CLgm|ck4`b8$!2una6D>VZY(%nMhW9+y1O~72Vyr?~!A(9*y^rRA4p7f+U)DvQ7ab5O_IKd~92Xt_ zvY1M5GyR49%PJK#S{E{|byoZgBYYO|gmepk8EPDFdw~)PP;Fq~c`}_|SubOYID>5^B*T1GVZ7*wBojsi>NizHwRF9x-)gK$fw?Q42@kNH zt|(#zzr=W*W->6h4CX_V)=01t3(DZsEeCmGcn_{BEYesMAgzg3wA`O77pq*Qp=8v5 z)~(Zu@}I)yP3GBKOn`|!6R755srRXbZ)$w!#q`|JZEGRk&bWh%H}pF&ss^m zh*ctQRY;ggi}FXpB@t1hcWWOCLcGwJlHtXFWxONa6I+>WLniV5HW@GS=m^*xX;ttc&v=E{ zOLAzuHP#V{APN5XN7>^a{}=%O43kBfG%Erbz#NTL^}2--Ab7Zd`AlhRhA^Q_p`Z#P zx?5H@%&-)$iWillOYy+C9FO5(RJL6*nQ+vDRu-)WnSQY!-dn@=Lvvzb%)lall~X-f zi^;j|>x3r}Dj|Xak^P2sQ<8;v_QZRDkZnLbV0#VKDQv98XO01hiy}My@vc(ptOp2FMkrd!Mm(y}c{$YAM zbc$&~nv;o4iPQvI5Cifl(yvI;s2P+Ohf$pz~#M3mvUi)+4=7%S12d|3I?R7WAPuu)U9e_}F=QG=))m z9|OsD4jsDUWZs)~?({c#j$Url^d=d9ZWCq}-v&-!{ut?s@bTlv4v&nS`Tjo&p#H~l zMnj7>t*lx3I)%0bI9?y<(*wV?WgCyO#xYFGg|;b$;SusX#$)MVMkaLr1UkU+8}D_> z#Dgxy@RJZ`PQ)c|biQhTP(oio7x6@)^s<|{;Yw#uHk{DO5!93zKDGsD6`s(^Q36tJ-t-a%SN}x zs#woT^0DAVm)oJL6((zHY!fiBRtDnx^&+%2BVim~FR~Oasn2A80f=dr#~9uyL|30t zemz1DJE%x|H4f9e<&=!SZ_)PN`YGGrCQ0!=83|WW^;?$acj?t4o7|*E4gF2js#>mM zekKFIu|JqZ98OX+r5e$agqH(X({G$@JJXq8pARQzk-XwP?4>p#2A9%X-1NV$>f&D+ zHCtxaW)MWPk~f`y&Rz?X0>P2XfZ2+}sDE*(6*ZN!=-2#|$7YgW)0a2u@O)ZTHA=fT z#AqHmhwuu=1_aor$gddkIDz|4pU19lVfh+gq?b}d$XrY&@VSVN7oC6P8Azcqbl(>~ zh_i8;Uk5zfCA|^Tf04gg48b@$#Rwu6%ryllSOQFa;;`jOA;*v3!lH9>czH6@DWG={}4f$rj-@S)exGrlUU1E%N%~ zq$oKq15rrpnAgXRq663#r*|02jzr)J-NV-2ftzK1bhpHVUL1|r!trf7e*ZIzp~S$4 z^_V1NK=K$gFh`RWVl znN)8)j|-75=!UqY{B?u!S)%gS?d?TwSFHpy+2KP6J{d(Z{j_>fK_vitE=sF1qku_; zwBmyypRZ^ezXW14OQmMT_%t;1?}GjPkQGY|PQxCqZ=lk1f2^+_!^E+OqPX70Y%Q`y zmB}Lc$i1WbOZ}=W^;$4-mz<;V0BnkTAPKOE`q~^$WQnABIrAJ(&5uBI3sifOm5_R9 z5@{G|jwg#W0r3HiAP){>vbK$d?N^BQd|}M|aQHp`EvzFC4q?fba2hbiQ$LjR2v>s= zRUyyOlpAgbf4TT@cjD6{O4nxbj2^hLQ11#^=jZ%m!E0e2j+R^wV{Hk$;tj>2pC*EB zv?3jCg%)xFj$RnU4KRL>=D+<5AeOL-I8b=0q`s;RySsB+mYBTSz^)wTUQiUda>VlP zIQiC*GMX;9LHn*~1MyslL|4*uR3)(Ymfhw5^cAeEe;Bn!>)V;`Hq8>DgH&s_H{M(;HXufkrMoRO9oA^NJyGC$M8k zSY}uFnz7Y=wSga+dfdaKRn_}3ee){<-$>1wZJRNy5486-8!vL$T<_8ICHR;We}ihIKVjQ{XSQtrLx6Lr~d6gu$rNjuz2 zI%5%g(2gCr7gA8cFizG*2_!1}`{|>u6V$WUrG)b)BvnC#x$HHJr_#T7_%g(LpDNqZHH2(}CUEd$@~yTA2bffDYY zZ#zDS9*F$Gm5rv&nz6bNZf(;HdINnU0mY~?<*0fQ1DPgQdnAxm8U|{9Le^=@K%sUc{5S{chq5oJN~x_TLaTjP zyYh28Re$Qr#vL>pw(4a`H0aU994O!$wBZoZQ;VUUUdd^h*0z*_+U!|z-0t;fN5yfk zZ%hR^^|(;sa9Gh5b?%aR%coVlNH14Wr+}*&zE&TggoR2%ZuMAc29T2qY{geFf7~)~ z8zue6v1v@)e-zhnVEt|^#Q*+dV3vmWI=E53=(i8LwGG?7Lt(48fKH0#tlx`;){{Jv z;qyV9Oq0dkNH`#j=E*Fb0xU&3!|0`lF>o}=;`2!Segc>MurZS3z<1jg8$~%fHDV*x zhFlhB+Gk^Y;Ka66rq(#8U)jRlf9`h`f5_60-Xe2IoIz8FXT~wc3@%y%J{cVq{_D&v z4orCBz<>bxTB9$Efs1Exf#x(Iwr5f-Pp@*Qk+w_#tUw8D7G(@4S{h?21q3#hiO`vi zr1{X$ktGwxy{^G*+K?igxe;k9(Po=n(%6jQzvE|9sd*Xi?U6yo^kRJZf9x>2Plw~d z74VbqSM+5HhYjs3hvP^FFThWGLjX&k-=%<(ovY(KUdH1=mjX)5NRchF{>brP%V9T8 zz2}zU1a>SMpxbkh9k;~8Z5hSOyEKJde{rb}9qRC>L!o=)l}u>~)%Ze*b{WM}{<9kmauWeb>oBUtff*ew^hQ3L zb&yF!obCuR^!nuNZ1m#g+jlFr47nYug5S>g@#BZj6tlEIQhYtUe_zFS_^;3KFL^VV zr2n?FoDt?h(5xa`-C{;H*cNa(EueeUVTK7>4;PmG(1chn5D^*141Et;1ympA&$`EV z{rp+4dwkvh92d0jzIfAB)y?Z0`k3xAE#e+CbXCXGKct8Fe~(asmC03M$2mtYVyT?N zQqeyuiLMgU*V#?!u|zR;46K+IdJr5K8yIc+H>ORcKQL`7;1HH)He{s-i2HrKufl*C zXHgMlZmi7S+3NG#q#WPEcVKpIc|1n38O2GSvt>DQ!>Ahws;q0ONKqqWG$%L#W0p!57ZpErxqI}=t{2>=1{ zCXx}y8|Bw>dfBk56_0Yv@ll`A{P9;nyWu-;8g-)+c2yO=t?N49SG{kXIc!arYk{+* z*h=zre^|p!WOdqn_O3IR{yQ0}UtdI~2kXYWfx39`qF`%lHEO$iz%tbJRS!oUw!NSA zleeaoV%l?jg{nQdOwk*Tye!hs>%$NmwS}v))~*zR>XFC@5>S(oG?DJeVl87(Ov|H7 zSf|g@*_q07VW_=y0r|-b9s>$ShSteV8$qI&f1CmNPaCqCrTZzi+ul`F)a>nlGc_4MU$qnAIPpPv71bo!zn5<}V%BxFRpD?WMi+sWU~ zMrW_z{Wf~>?(NCxkC+VCuPZ?_F+;5)QsmkkUb7Cv^w-fZ23SoyW%D&(pH50#_f7?~ ze>c3E z`fcZ`-Mul|sE&-|T<7dQl6nhWwWX&Y2MRaXA003|Q;Km*Icg?-pw_tb|Een5^oJe% z&1*1h@Q<(Vg<;M2inqtze@=_x#iMRFe|`f0`yT$+JLq;VD^iyw%H1J;$oaDsw(fxI zbLE7p#sT_4TQ)%RUJ z+#-donzsBVk$Wj)BP~{OS2#w=^D=~ebPL6wTD`bz3xg&;_tM}-oN~&iqFIa@e`vnz zFo~2It3(Tmyl=iSvx+d&K<*E-xIO!G`R7*IK8W^Gpgs&6h-E-wTTz@1b!=x2h9IDs z$H}nU&gH~-kDko3J34Wvli@5jbm!9c(&%hCT(q;n@(6a-vC-|Y+pq0%IHX9aM&-1% zjPp2&p_52@W~dgg78Fy++(Bq1e}aA~A^=2H0`Rz!WAOVj$wamsK&dtiw^RwntjZ1j^i4gub<-$CX>CF)+nU7F#};nq_RzY!>Rq}? zr&;k_8Ulz5xQuO;D;*ofu=JbNdSn$lrrlVyl*(<88hY>a0&bO!mzCc%)a{4qAaAql zQpT?}i*$erx}t}AtLn?Of3iu1<`qav5if?8#!*2}HmJM1J5U{U+yyF%IqTFyK3QPy zsC>A%$k3`)w!FyUm${!<2lC}h3yX${x*UrY_gfx2DpCYoX-H+avFg9PR6B0d7WKHk zj5eMWWn-YOs_e8f@NdrTmP8Rgz_@s5v|=fWw#Y+@YPvL?eT9Bif2&hFVD=cZ|wN$HM-T1@dZr4WZ3ZM35cKH-B8C(1x!UCn5JZ^ zgDqJ0vF3K0sb?=9hBq^t4VWZ*IC~Yc@CDKqSYd-eM*axwR*S%unC&%GFk4 z6Od*RR&b&}VO0^B&Jdi<$aGl4G?%QlH;o5Miz@Oe|^S(T=v;t-t5`(e#0v~ ztwwM7j++CeFG_OA7vh-wUUAj0G>C+#C(%5F71rM00J>rWkZOEQ_t6DOs*n~VSx#PqRpoC5Kd~FM7S5CLlVAtKz zal?EbhmyaPe@^2lpqkT<^eT{Om5N+qI=!cu=g^#Us^&SgXPxq7hxWW57Afc_yd^n@ zw{&ek1#&jL$ERCku0XuumI^0SGmOjRinynK*zTbc&!AsG|B`9#@f?lN+&bITpngQX z$%sJoBMwv_XmKk!`7|594{L+ae^7dhAM@wvI5~Ycdk6PqHc6?G zSOsrc>}~zB82^v-v)hipnk|0I%G)23@%stji)(*0zQ~$lcDM;+3jul-8Op(A1urA` z{g<7Oe_R!*!|h%bm_4ECNx#+9T|=1+D%60X8c@7nYq~R$^RW>vRtF{qDLRudhMVRE z(4n6xf2R&5`&`^v>o5JE%zDG>Crs24S3mRJgk55^82iXrgUIy7Hf_tI4lH? zD>NG(86Fc>QyJf+-igh2fDjI32OvWRkGobBei?e+>fSNQiS6+8ZgC_-)qA?~wKv?n zBaw3;sCwJ!5;Kr(o*aF(J4ldRdk&SqJ0 z8xlWe_3?@e;MM^VYLYH6fT-uyY)sdxYGnq=)E`3%qJw&0(HY(V5AW<#R#IPHh%24u z1UTz`M?Br1jTuS3uT{kGwW77AndU}OW@g(Fd);nRa_^oYd8(NLv@q)pcM2$;f90i3 zW}?1Ki6k>h{pnAG4YMCfU8e7bnPeX@39d}tBtU@`6|fK_9SIjuIYGN32GO8x0AX?s zl4&!5Dg)8OVeDws-`lrF1;t#mhPdl)R-NlidYJ3R@Xglj;@&a0i%ctEe99%>hC&5% zM!)FIA#|zF*2>bljcW;rTr9#Uf4Yt-7|G0hBzBT@erMpeRpOiIk_ik7IcU&XLxq(gFJfKos8Ow@hZydEyMO#!z(a+3BG6byETAvPI zsK{&D&(G@m=3-yx)uYx3;a)QUN5eG`06jJrp@KGRHw~+wM7%>Qe+fWbttOq4 z%x@iaS2mX_`DYD}kAYc*xNi4UWdDSn$P=vM!-HMDn_2JI3a|0*l247EiPbcx!$56q z?Ge!wIQ|^!qoBu`GMnH3v(0LsgKpRNSm2`x9G6Jg5VWbkHijjcW;2&CH2AJhOuzLw zLwSym>{{LR#PN8qF-YQUe+lA39ENlwh7F`agFt$kiO-2%Zc!b8rY8Q3>AOmnFcTT^ zAgu-z8zdq`OY5SHGpu~cu25;5;I9~8iKp>xMI8zBOB@gY*2p9*C&J?X;1)!gNouGp zBk{%5F}szb!D4q8oz@oGX>EPrpL4Mf1bE37A$SramJRQLkOQ8De{nYHhwOKTS$@}4 zYQMcAY1m z?9QcqL%Zi01-n0zm0(5_H8f; z`|yE(zkK;J4%Ek9f2Ri>TA$;9I;6+^cv0)ChI=|^lZh$)$Mua&hHGtE5UG*RZ4$=7 zE}_GGcUKq=;E&^$v52XSskm$L{p};J!rg?%c`=aVj zR{WU!2n(~jn-wT}A=;v2Hceiwy;;8IR>4T1);i<}oag^vjvRGJawjR|&-0&C zN~JC;{FKbX%lLho&QE7Q;6w@HO7P zOg8Dzbn!M~yB(syNk>hsgEJdG?poiNE)Bz{7_QDN08|eTkpWS(P+oq*qn8PMo$IV> zRaUM?pkvmREAPE+`z`BkMjpVt7iZSJ*qXH$@;c1OMLnn1HoNzF#J}}bytoP!(lnOJT95?A`5`|2sX#z+%k?^cbwg49`YF)dqsj$5@YxPP-jfMA3TgLs+%WFhY63%IO+oa}Tl)P!q7yBMZ+_!|N3$mj_Vqf^Vp z5N_UvDgX)yIYungk`E;7P=HaQ>*q4gF);HscrhmUEoWzxt^=Eaj!VUfEVuOYq~p-U*&-6s6Yv?m#8+qxah`kTY`Aj z1Az?IkzEMiT{D^riiHbhiN6fk=Zs`de}BB(C4d&Kdj;}{H=6}U1R3akaJxvahbr?( z@(*B$c=pMhokQrG3d~8v7W+3JvVZRPI^BJYzPm59ew}dv1257k!i3M2w`qz2CTd@j zRvl?yi%%_Z-=~ZFN>D`etyndXChT1m8c_yD+#-(qXyZWc4R*()tPsY4ZlJ=-f86TL z(1TO{?!HF_NAVaPYQ7S+CVARxzZS`I|8xB{SyZyR%5ze{Wueq2w;u^2{|-3mJV zrsC>38qqfbSs!?a2!!tSKFT8iPi<9YCbsfu3^~Hf8^GqC}=hV z90XI;UgG^Wflg@)qWcKl8Y%E86WjR&<6}(HS0pLpsiwq#;T%T#m@g)7h9V5e24m=; z4*^_VC^=5-3NL5$kq^27+)*{nQvGzC0O;)0`vS&W++h@S3$zJ+=ETTN(ESSgm%!qF z+z9Fo1EYs*WmxC}zi%<_f63x5z$ROaeDX2*>>C-sZ#gnHsYH$6+EAhS418^h5?QX* zyvE+GORwZv|5{?~TePOi6+AZtD76pB`ikP9G*;xpSvPaF# zce+x{iVnHu)UYU%{G8sr{50234uN>K0l^wLm$bmhxO$PRPCD3|e~vt=0I;QQ{61p! zU92jam>r6TC#M&uvcT>zOwg8jgc-y_BK8E{moMUb0t;+^=j{ZW&-yw~XJqtZeFT_q zZV;u$XK5l)*^}EtvgMe*y*>0zM^&%vZf|vv#e^+HQhc6`Tkc)X5e(?&TBPXtAKGDK z54&9zmqC$mkE!8we|iRF0ASO(3O!Lplmg^V8`%|A(7!bg7r$yf15^P@LOQ3mQ@fArA}Tbf{!xD-eYwwd9} zq&cKzQ5`66Y^xLGW*YD6b8ZitW{#rs`Ol|+{p-u0D_8ErE?bT5hvj6E+u8!s6I`gW zt&D*s?SXx+wqw6$o31w8MjRARuLXQu>u*gg>GdSG52 z1$~`73sv+?`kN5?h8QpDx-ch(nTZ)#+*|;QR+h#J0MLN9}u_pv|r=%|j6of;dLy$-_DGZiZGgAtoa*P3p`6?0j z!eh+#f5L|!|MW)hr~->&HRuFfUIrHzsP`&-Ie{H0S+%LeZw-uy=Xp2D`s3U51Fp$( zuA_^>x^c#}UpdFHl96=}hNQe%|Cp>vk1$C$9-$)t)um2yHm*f~n0i?80<}a(g|?+o z;g|~DWizYw3JoxvFGZQo{UHg_48@#p)w!JGe+6NgOdplb+04d#TruOArO!l2xa8BZ zZaoy79siIOFo4~rJUsT$W#mY+tqDM+a1H;@<5MLjh?UMI5=x`vtGZkKo2 z1g#-grdS_JIS6XShZF@!oVH?xI8_sZj%+s&YtXuyS%-LI%BP zPR(68QlZ_U1~Lx(0=Pa)NKw=nhSpn#wIucpGw;5pG8-^14UELRI_rVM!^r0mKRjl_ zXAty=ZKbeAURZiSoxhulu*Cg6X%$1^B71MFL{2XL3yjQ~Yt%0ktWPqo#O zPpX;YuiKyK+UToITyU=oz+Z#bIvS5wHV!Rf$tpvBc$yN40+2J}Q$ch^v z!mOCa2X#*1R(mb8eyFqmhQC!}%Hm<=oVmuNVnnHx)BB4h*P+qX{W6HyBFjAnmb zC;U1H>`;z|v7vk{d?!0pt+3;({F6v&qWX}jijDC7_xB2%Q*>{m_;l;d5}GLh4sRrH zz*bswBPkaOZCHYmny%+dS0HAiep@)%0O67e*b1qyl3DN;Utu4DQyB4Uu_=Le@c3H@r!c zeK6y}y9D8hSPbpc2%>#x>h z8HB~yBEyFI{;_R_T|nS;>cXMvE5o3-#;~TIe{3!{#x**EG1G7GT3yey`(xPG7{nv{ zc-&ap=Rn(QrRZvX`YX6r-!6&9)GN)dm?_r|Y2**8?c zGxkCgq{36<+yMA(Hj9&*qU6&c9X3tJ-Brn^wQ-Y)kSCjAz#gfe#%^!@L?gy4{e9)q z$$iwkZhE)f%RhO=DomXR9C@47fuL{0M1w9^E&@Jj2F^Gy_v&xPo6C+p1Uh-|J`gx{ zfbZp>44RMAse(5MDGz_i?k-b!3hPk|syz3Y@1beU<(1zIxvT|{%Rl>uX_JrB`%3t2 zLbh%eHuKOt7rQRZ$o^o?%jF!ua!#56ubYo%NSf!O>%lzqkG^Xm#%&xXHGQ~kn36QG zBfmYE!yvb;kI@6{!>qJ=zw=|>Tt2C=>U(~a-Q5@_Li~WzVIhCB>Q4nl6vAA*2L56E zEJ1mNHxm9aSsprz^|t&PDc=Z7@0_%OOq+dv_zP%{Fg@ z<3CUbn5EN+nFiPL5fL6;jK(m)|EiCiGnCyy#3%gWC`_pTin2uddgz0#u*c`g_3>CF zS-~l^P5%YGk=apCXXm9(D87f0+}U*?^mM>$#@TV*GBSVJGrm=Q3<1SFa3YRC#jbPi z=z+dMF=UcXOFL9!*T<1iyj}u=yin*jlQgVN+iBI-FI84YP3c4|bk$|$l!kz2U281b zW2eH}qT;D%Tw*M|-BYM>?-YEZoX|V>--OEKtbhLr~2id9Nl`wa~RZEp#o0O(YZ1L$72!B4f!_ zq5%)1VeMQ4zj0Z^cQ`%w8Z(VFRo<8_adSQW4*ZCUKOkcR#ho&nvej~}pEg;mxD5kO zS7trz)~Jj>g>g*kEi^&+p7@Y#Cek`z-qRo16eWK|hRGMH^5KR8&P2p3v5Xbvdmg6O z;I4S;1uo9;X{2?OZCR=&^E-5KbRTUkzc^-=@gx+>InJ(tlPWuMZaB{%YaVV*LsLMv zd^yO5RMRh zGo*i;o%s-79c-gl^M~HK>+^{{(0`FZ)rz3&}7rL2Ti+8A!8 z8ot<64O}60ap(mzyo_SE&kEoz;n`Rzh%SFQ_zH%$^=^{dl`)QET0S=$wrmAtRJ*IT z=-X^u>3^e3Tcm*9=-LKqr+3F1vZyOQlx#@IHsI1Xo9cBk`~A5S^%_6P7U`I|3d6#v z7-!Qd1zxdCS?6gwA$6F?hFEnJ_IFc4mJq z*z92zE!gs_Em{=R|9XoSV_m$r{n0rig@rDXSmSFy2vR_Ib{u%oLBx4oV9ns?>v;jz@(e%RfGnWXU z#IHuEsLlppeJlGLB(>k3;nU}Kt-XH>RW+=3YIf{Hj9KdXatu8T(p&oJhOpF7lN#34 ztFhF;a%rTY`}np-8k;`n!+LM=ly8!+I5fzAY#e2Lm^WAPYhRqyC~IGwu%J-x#o;(JXB0xPgDCI}eMp zfnMKDhE}!vArWY2bfRkin&FukuOdSOYEpdP=^%(*do|Uirz2-Nx+fmIzN?M6UyMIK z-y#@5hZ0n^$H`*iB;cdih`Q8BXXRAvRx?2n6c`(WG$k)mOv6r@=IFB7kP{=VOj3ww zlnw`^;8NlE@P}jsJyMHD<)eSX=$TD@H{ydXM_!2s#u;D)h>s_WMe^CB^QSs39a;gq zr%*&@8e{HBK1%D#{2kL6TirQVp-jSBU@Yv!-kJIYWy9_udzOd*aDz-{U{#4Iii_kT zySyCaySoJk^3J1`P>~dJw*JeQMvoK9EVCHy^e}l$iU~7BdWmjyUkraS$p(}%_TWY= zvYT1!9y+$pzX7qHM!(v~m}Iny2AoT_IjA`KuY=O~iCE{?a#ckVrParpM#&oA4jKfZd`uHM~*`M0oVPhrcR!)Ak-bjtjfIqccz z2_>b~!uTS#v!!DQ;@nr4dE5&~6z66N`P|Cslbgxn*TjGz!4UITk{V_65D?zPgTm!c z(lT@=U2)a{hst5eAfG2=RPKx1d&%Oxa(Wg;(Mo%%k|^893u0g-LVfJ-M|)VQo;sHi z@c|@%$NG(yh@qO3kY7Od9kZ#!vwc-&`?5Kphdw>|#RdGw@I-_E;4h^y{~%Q3b=vAJ z=yG-6Sd@9}d1YP2II9PQTJVH(nB`@5{h0#9tO;;}7BuZSK1*)1wa3ZqLsCff&3KU) z#ch%q3LLHwkaZ2Bn*N|WQKZd)Tao^v;ItEebQHq|hP_i&jn$F~LM(!$T@_=_`ZaS5hp zk>4qoR&4ZG)zON=x0nD=rYZzV^6~>L&>I0@D9P#J>`z)s{JYT-3FGoXv{cV`iu`)7rsDMKIFn~JfGQ1 zCwgvk$FXYOrq;9){wc+|C1De9|Ea`TQCuvH35}KFUfhd}tWosf0{yk_7k%O>Z{R<@ z%lHcZb8v}rp{(J1tb@-(`P9TwUhtDtNrNo9xVh@Nv;IE5hf;g9Hx#aJP%?w~O1%^9gOwtaJ3JS5rt#U}? zupD!S7n4k;B{rYfHCzQ8VyVzHF6GoucFqDqCm-kiq_gL@|nHIZ)I1z54N z$UOo32X+&D4`G2?2Zx7Hp&NyNl?t8S6SE5Z+gIt)0axnQS9$zYR>7WXDm{5@R`SC0 zRD)Ajr&pPjg`n#Ua{|Lc42x<39eKu9ig`;mLv5ET`%s%GNb!F?1jeb?IrLQQHdW*i zeN}o^jb6jlvo%xSO!G2j1^w^*@|a#<18Dq;=apTqNR2cDVjnY^A$OX8*lZYgKHg?! zIwC%`(WGiXAx}6Hovs&j4vQcK=@2HjG6uQ#%NqUm$Moub#`y^n3=t!C3qcwOa(@QB zC*3&cMnU(FaX=6ThxjL!_nth7gM;q(@Gm$m0otQSD~HK+Bs=CP4-UIzJ-+=M4~#kD zqpC)1U?G`|$rKI(3+Y&YW*|PWR{=|nl?dvV4ZdXZ$zt5wt zF^jF&9<#tW@m$BtfO1LS>}l^eQw21I(z$U){rIMv-LjB3Rh#x=H11-xo0oox7)Q!o4inaWS zE&rA1e}HC+LNfsLQdvCeo;EcK3gG@+ByE^6th2TGV}mRj2#rmG$bZL*$i<&Ni$C

    ogxBpPpPecEM{8xFSZmW#OlC(yT@%prtn*W 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 WKit2(`G{GLHvJ!B(nSw7B?

    \ No newline at end of file + \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-dev-service.html.gz b/homeassistant/components/frontend/www_static/panels/ha-panel-dev-service.html.gz index 2e9dd6b4bcfe3d558d99c7b91b8a8902937fe5d0..c76c9bc6de1a339afa24abd6beaa2b5f3af5bb4c 100644 GIT binary patch delta 22421 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 P?Bag`E)LVUX?p \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/panels/ha-panel-kiosk.html.gz b/homeassistant/components/frontend/www_static/panels/ha-panel-kiosk.html.gz new file mode 100644 index 0000000000000000000000000000000000000000..c2d53ec9d4a5f707e9f8b94590c009440d3b5fa0 GIT binary patch literal 226 zcmV<803H7yiwFP!0000216`0YYXdP1h5w52)IiLwc9ITM zhBF3r@`+AW%ouY3Mx!$n_7Kzp#Znh{jUuj?q;Nnq$-|+|<53E7>7pW@*GWoI(#qIq zUmD(Qemwa(RMK+&aj5sxdw9k)nwH`-n~xN(5zEWX)A&F4K9`iSenT2>EztNrf8)aY cZvQy$_njUd&-Ad>G4%R=0d(@hLPY@p0QE_35dZ)H literal 0 HcmV?d00001 diff --git a/homeassistant/components/frontend/www_static/service_worker.js b/homeassistant/components/frontend/www_static/service_worker.js index abcb29b5181..2a123e7a0ab 100644 --- a/homeassistant/components/frontend/www_static/service_worker.js +++ b/homeassistant/components/frontend/www_static/service_worker.js @@ -1 +1 @@ -"use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}function notificationEventCallback(e,t){firePushCallback({action:t.action,data:t.notification.data,tag:t.notification.tag,type:e},t.notification.data.jwt)}function firePushCallback(e,t){delete e.data.jwt,0===Object.keys(e.data).length&&e.data.constructor===Object&&delete e.data,fetch("/api/notify.html5/callback",{method:"POST",headers:new Headers({"Content-Type":"application/json",Authorization:"Bearer "+t}),body:JSON.stringify(e)})}var precacheConfig=[["/","fec911c6ea0d8cfec3859442f68f7d04"],["/frontend/panels/dev-event-4886c821235492b1b92739b580d21c61.html","0f16df49a7d965ddc1fd55f7bd3ffd3f"],["/frontend/panels/dev-info-24e888ec7a8acd0c395b34396e9001bc.html","7bb116813e8dbab7bcfabdf4de3ec83f"],["/frontend/panels/dev-service-5e5efba829b62a4f66dc0076475a9496.html","91722f43837d0a964e61379840db2c95"],["/frontend/panels/dev-state-8f1a27c04db6329d31cfcc7d0d6a0869.html","002ea95ab67f5c06f9112008a81e571b"],["/frontend/panels/dev-template-82cd543177c417e5c6612e07df851e6b.html","81c4dbc540739dcf49c351cf565db71b"],["/frontend/panels/map-d3dae1400ec4e4cd7681d2aa79131d55.html","19102e8bcbe3735db7358068b17f323a"],["/static/compatibility-8e4c44b5f4288cc48ec1ba94a9bec812.js","4704a985ad259e324c3d8a0a40f6d937"],["/static/core-d4a7cb8c80c62b536764e0e81385f6aa.js","37e34ec6aa0fa155c7d50e2883be1ead"],["/static/frontend-157fcf3c30a67a0501852ae8933f900b.html","56f403e144c9fe51d5d2747712d6da38"],["/static/mdi-c92bd28c434865d6cabb34cd3c0a3e4c.html","7e24a0584d139fef75d7678ef3c3b008"],["static/fonts/roboto/Roboto-Bold.ttf","d329cc8b34667f114a95422aaad1b063"],["static/fonts/roboto/Roboto-Light.ttf","7b5fb88f12bec8143f00e21bc3222124"],["static/fonts/roboto/Roboto-Medium.ttf","fe13e4170719c2fc586501e777bde143"],["static/fonts/roboto/Roboto-Regular.ttf","ac3f799d5bbaf5196fab15ab8de8431c"],["static/icons/favicon-192x192.png","419903b8422586a7e28021bbe9011175"],["static/icons/favicon.ico","04235bda7843ec2fceb1cbe2bc696cf4"],["static/images/card_media_player_bg.png","a34281d1c1835d338a642e90930e61aa"],["static/webcomponents-lite.min.js","32b5a9b7ada86304bec6b43d3f2194f0"]],cacheName="sw-precache-v3--"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(e){return e.redirected?("body"in e?Promise.resolve(e.body):e.blob()).then(function(t){return new Response(t,{headers:e.headers,status:e.status,statusText:e.statusText})}):Promise.resolve(e)},createCacheKey=function(e,t,n,a){var c=new URL(e);return a&&c.pathname.match(a)||(c.search+=(c.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),c.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,t){var n=new URL(e);return n.search=n.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),n.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],a=new URL(t,self.location),c=createCacheKey(a,hashParamName,n,!1);return[a.toString(),c]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(n){if(!t.has(n)){var a=new Request(n,{credentials:"same-origin"});return fetch(a).then(function(t){if(!t.ok)throw new Error("Request for "+n+" returned a response with status "+t.status);return cleanResponse(t).then(function(t){return e.put(n,t)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(n){return Promise.all(n.map(function(n){if(!t.has(n.url))return e.delete(n)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,n=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);t=urlsToCacheKeys.has(n);t||(n=addDirectoryIndex(n,"index.html"),t=urlsToCacheKeys.has(n));!t&&"navigate"===e.request.mode&&isPathWhitelisted(["^((?!(static|api|local|service_worker.js|manifest.json)).)*$"],e.request.url)&&(n=new URL("/",self.location).toString(),t=urlsToCacheKeys.has(n)),t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}),self.addEventListener("push",function(e){var t;e.data&&(t=e.data.json(),e.waitUntil(self.registration.showNotification(t.title,t).then(function(e){firePushCallback({type:"received",tag:t.tag,data:t.data},t.data.jwt)})))}),self.addEventListener("notificationclick",function(e){var t;notificationEventCallback("clicked",e),e.notification.close(),e.notification.data&&e.notification.data.url&&(t=e.notification.data.url)&&e.waitUntil(clients.matchAll({type:"window"}).then(function(e){var n,a;for(n=0;n$Ij@LDp z1_>Jk7+@$_k@fF61CSIclJchVAaO9jboZP-eVMUV9gRBOmQq`jVpU6BHub0@{jzw* z<($;Jw(4whZd=l;wjPo9g>E|A@${T(d$VBgg9Tq6f3a$-JLm57(weSEZ%AVXpKWca z8(kKqn^o73|z%E$J4GH&&;`+&mPWW z%GEbZx}-bz$P(}Kwcau9KzDDEqKY(Oznc}VKb=lriq9nVfZp)R@hYlkdVY4c{!}(K zJh76xX}1f`&i2H)1!+0AtqZ;^FM9KCyt!Uf@r7L5V7a#o((^`LTCZNdd26|I;)>et z(xChIVQk-8&zf2T%kf)m*1EL#a#^i6dhxkyYRmm;1tD$upMLJr`k8o3?Z`UUcaAF> zb#wWTH!pwl40GxktQeej#oN)cC25!g4MjPde)wQrSgw_3#3SaXF)_(SAe2l4iqc5P z+>e8tSsz_|ShT%a>SD=js=5nBS7S0hA4gf1$Shz%7)N;^n8<@P%tf5}Dqu2UJqpm{ z7c5all=D>ONvxD)g^J@M6)G$W{GHZQ)fGR&v?ctPMJ8ZN7G_i^{N7?;wWTkDkGLsER%!<MlYCU_q4T)?v|@IH4? z5T!n5vY4wN&M6Ec8LEu?Jo1Y~k*VfhD0JhTz?kyFq9SvPX~|B#;Mkgb@@7mB}!XktpIV@M#Dx;}xl- z@L7T|OKKF4{&ky197W|BQcbD&=WiK$HSWrOcov0TUSm%yAUJ$6PVt zC*k)*Juhc-y_S{2jUqz?1ikN~umE!cgmD-INF~wtWW69&t`=)y1tHqOYd>YV3RW5Orag@gxdhN*?-@FwS?SU6U}8 z*VIVw-59Zl&Y`T=VE_Un;8L!5mV|x;_a!0p!y-BDF|EzL?)sJ?_fJ(%%2*`U%}mgAPQ8ZnAi=M`@uQKLq_;3%}HZPO1IzpwP- z)5S-ZEA>}Yd{duqeytUKo!&Pwrtq8US5HlyefRn~3gTqwYf%4C&T9`zW?nS%hjr)uE`V-l&Swq@$FRbu+-tF~E` zoq63g)fJ)RFz=j8{8o*yorg`B-fO}(DsAoFZrTSFq+#S5|Em}pIT>@ zaqT(PvQhNz^{>x1WW#39t*LeFP3<_Y+;c(My@JB`bI`K_b4We#d0E(|yQ6h4=M1Jk z@hAIa(9YKI$<}vWv!J7W@Op23OXZptYx!$WP_@Ut8xWap25bH?$LrAaX&Xp6 zr|JCg!}G z_ZSSJ|7j=oEf*(@?rpQ7R@bBP0^0U_(gOnwbb4wGbZh)Dg!;Yb+&*zs&Cnf#AJcsT z+kD?9aQF$^p#OpI81KrDcaAgZ@wpW2q+cxWva_5(D%D_*UrGs$BQz`BnDxEU~*2HZQB5~ zwT4mAn8QhZZjA&$+crVYISUm+4dCQgAjqZtj2X7uZ z(C&Buj_$sc%lGi%Kwq=KJwX6-T)hIZ_8Bm6b8|F4>5|F+!ITqc`uZq8>c^aKj`)tV z6+0YV@y#CrN>-)m1n|qt#do0UnX-=)tg!y}%Ui2Y#_hlgZ#W6BK}2ky%%%4I8f@XQ ze!!XN=|e9J#Gh!CqI!DJC4esoZVZNQ*>O(^a3)W1-nVKrXfwlu{jH!@ot+(&Bm0B( zyKO&xVh>%_H@+;tnOs$UTOTw(T{rC)YSCAHTkyIpj4X4)M-)4M{u3Iqy`A?h$u{?y zlly-5+s$Stx8Z7Yr7;AbdXLci-w8Psz=!f@)R*YPb#OjyX*U^?#5zH|oztjSsqWK( zo^w6A=G}_zddsv3+&w+ zHzWjeoprd?(>H=vzs49sX5)MJcd}}b+z+M))Q(IV_pISO`pz+{c5?1Ief7-!35jxz z%{4;5xwej7d-ffh%O{`;g3h1Rf7!H=lluJJ0jW8i%C2{=^z%761TYgXgUP literal 2488 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 CXw1X_ From abc5c3e1284b080caa20a91d0a18e9e02278c6fa Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 13 Jul 2017 10:19:59 -0700 Subject: [PATCH 124/131] Fix iFrame panel test --- tests/components/test_panel_iframe.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/components/test_panel_iframe.py b/tests/components/test_panel_iframe.py index ec1e5bf3650..5f9cdcfa57c 100644 --- a/tests/components/test_panel_iframe.py +++ b/tests/components/test_panel_iframe.py @@ -53,9 +53,7 @@ class TestPanelIframe(unittest.TestCase): }, }) - # 5 dev tools + map are automatically loaded + 2 iframe panels - assert len(self.hass.data[frontend.DATA_PANELS]) == 8 - assert self.hass.data[frontend.DATA_PANELS]['router'] == { + assert self.hass.data[frontend.DATA_PANELS].get('router') == { 'component_name': 'iframe', 'config': {'url': 'http://192.168.1.1'}, 'icon': 'mdi:network-wireless', @@ -64,7 +62,7 @@ class TestPanelIframe(unittest.TestCase): 'url_path': 'router' } - assert self.hass.data[frontend.DATA_PANELS]['weather'] == { + assert self.hass.data[frontend.DATA_PANELS].get('weather') == { 'component_name': 'iframe', 'config': {'url': 'https://www.wunderground.com/us/ca/san-diego'}, 'icon': 'mdi:weather', From af9a0e8fea6ed9350a900372a6ea2ea850f95ebc Mon Sep 17 00:00:00 2001 From: Anders Melchiorsen Date: Fri, 14 Jul 2017 04:38:36 +0200 Subject: [PATCH 125/131] LIFX: support for multizone (#8399) * Make aiolifx modules easily available * Use aiolifx features_map for deciding bulb features Also move the feature detection out of Light so it is available even during the initial detection. * Move each LIFX light type to a separate class * Simplify AwaitAioLIFX This has become possible with recent aiolifx that calls the callback even when a message is lost. Now the wrapper can be used also before a Light is added though the register callback then has to become a coroutine. * Refactor send_color * Add support for multizone This lets lifx_set_state work on individual zones. Also update to aiolifx_effects 0.1.1 that restores the state for individual zones. --- homeassistant/components/light/lifx.py | 269 ++++++++++++------- homeassistant/components/light/services.yaml | 4 + requirements_all.txt | 2 +- 3 files changed, 181 insertions(+), 94 deletions(-) diff --git a/homeassistant/components/light/lifx.py b/homeassistant/components/light/lifx.py index 0c5535ea8ea..a32aa0c4a6b 100644 --- a/homeassistant/components/light/lifx.py +++ b/homeassistant/components/light/lifx.py @@ -33,7 +33,7 @@ import homeassistant.util.color as color_util _LOGGER = logging.getLogger(__name__) -REQUIREMENTS = ['aiolifx==0.5.2', 'aiolifx_effects==0.1.0'] +REQUIREMENTS = ['aiolifx==0.5.2', 'aiolifx_effects==0.1.1'] UDP_BROADCAST_PORT = 56700 @@ -53,10 +53,12 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ SERVICE_LIFX_SET_STATE = 'lifx_set_state' ATTR_INFRARED = 'infrared' +ATTR_ZONES = 'zones' ATTR_POWER = 'power' LIFX_SET_STATE_SCHEMA = LIGHT_TURN_ON_SCHEMA.extend({ ATTR_INFRARED: vol.All(vol.Coerce(int), vol.Clamp(min=0, max=255)), + ATTR_ZONES: vol.All(cv.ensure_list, [cv.positive_int]), ATTR_POWER: cv.boolean, }) @@ -112,11 +114,21 @@ LIFX_EFFECT_STOP_SCHEMA = vol.Schema({ }) +def aiolifx(): + """Return the aiolifx module.""" + import aiolifx as aiolifx_module + return aiolifx_module + + +def aiolifx_effects(): + """Return the aiolifx_effects module.""" + import aiolifx_effects as aiolifx_effects_module + return aiolifx_effects_module + + @asyncio.coroutine def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Set up the LIFX platform.""" - import aiolifx - if sys.platform == 'win32': _LOGGER.warning("The lifx platform is known to not work on Windows. " "Consider using the lifx_legacy platform instead") @@ -124,7 +136,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): server_addr = config.get(CONF_SERVER) lifx_manager = LIFXManager(hass, async_add_devices) - lifx_discovery = aiolifx.LifxDiscovery( + lifx_discovery = aiolifx().LifxDiscovery( hass.loop, lifx_manager, discovery_interval=DISCOVERY_INTERVAL, @@ -145,6 +157,16 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): return True +def lifxwhite(device): + """Return whether this is a white-only bulb.""" + return not aiolifx().products.features_map[device.product]["color"] + + +def lifxmultizone(device): + """Return whether this is a multizone bulb/strip.""" + return aiolifx().products.features_map[device.product]["multizone"] + + def find_hsbk(**kwargs): """Find the desired color from a number of possible inputs.""" hue, saturation, brightness, kelvin = [None]*4 @@ -187,11 +209,10 @@ class LIFXManager(object): def __init__(self, hass, async_add_devices): """Initialize the light.""" - import aiolifx_effects self.entities = {} self.hass = hass self.async_add_devices = async_add_devices - self.effects_conductor = aiolifx_effects.Conductor(loop=hass.loop) + self.effects_conductor = aiolifx_effects().Conductor(loop=hass.loop) descriptions = load_yaml_config_file( path.join(path.dirname(__file__), 'services.yaml')) @@ -245,11 +266,10 @@ class LIFXManager(object): @asyncio.coroutine def start_effect(self, entities, service, **kwargs): """Start a light effect on entities.""" - import aiolifx_effects devices = list(map(lambda l: l.device, entities)) if service == SERVICE_EFFECT_PULSE: - effect = aiolifx_effects.EffectPulse( + effect = aiolifx_effects().EffectPulse( power_on=kwargs.get(ATTR_POWER_ON), period=kwargs.get(ATTR_PERIOD), cycles=kwargs.get(ATTR_CYCLES), @@ -264,7 +284,7 @@ class LIFXManager(object): if ATTR_BRIGHTNESS in kwargs: brightness = convert_8_to_16(kwargs[ATTR_BRIGHTNESS]) - effect = aiolifx_effects.EffectColorloop( + effect = aiolifx_effects().EffectColorloop( power_on=kwargs.get(ATTR_POWER_ON), period=kwargs.get(ATTR_PERIOD), change=kwargs.get(ATTR_CHANGE), @@ -289,32 +309,39 @@ class LIFXManager(object): @callback def register(self, device): - """Handle for newly detected bulb.""" + """Handler for newly detected bulb.""" + self.hass.async_add_job(self.async_register(device)) + + @asyncio.coroutine + def async_register(self, device): + """Handler for newly detected bulb.""" if device.mac_addr in self.entities: entity = self.entities[device.mac_addr] - entity.device = device entity.registered = True _LOGGER.debug("%s register AGAIN", entity.who) - self.hass.async_add_job(entity.async_update_ha_state()) + yield from entity.async_update() + yield from entity.async_update_ha_state() else: _LOGGER.debug("%s register NEW", device.ip_addr) device.timeout = MESSAGE_TIMEOUT device.retry_count = MESSAGE_RETRIES device.unregister_timeout = UNAVAILABLE_GRACE - device.get_version(self.got_version) - @callback - def got_version(self, device, msg): - """Request current color setting once we have the product version.""" - device.get_color(self.ready) + ack = AwaitAioLIFX().wait + yield from ack(device.get_version) + yield from ack(device.get_color) - @callback - def ready(self, device, msg): - """Handle the device once all data is retrieved.""" - entity = LIFXLight(device, self.effects_conductor) - _LOGGER.debug("%s register READY", entity.who) - self.entities[device.mac_addr] = entity - self.async_add_devices([entity]) + if lifxwhite(device): + entity = LIFXWhite(device, self.effects_conductor) + elif lifxmultizone(device): + yield from ack(partial(device.get_color_zones, start_index=0)) + entity = LIFXStrip(device, self.effects_conductor) + else: + entity = LIFXColor(device, self.effects_conductor) + + _LOGGER.debug("%s register READY", entity.who) + self.entities[device.mac_addr] = entity + self.async_add_devices([entity]) @callback def unregister(self, device): @@ -329,9 +356,8 @@ class LIFXManager(object): class AwaitAioLIFX: """Wait for an aiolifx callback and return the message.""" - def __init__(self, light): + def __init__(self): """Initialize the wrapper.""" - self.light = light self.device = None self.message = None self.event = asyncio.Event() @@ -373,15 +399,8 @@ class LIFXLight(Light): self.device = device self.effects_conductor = effects_conductor self.registered = True - self.product = device.product self.postponed_update = None - @property - def lifxwhite(self): - """Return whether this is a white-only bulb.""" - # https://lan.developer.lifx.com/docs/lifx-products - return self.product in [10, 11, 18] - @property def available(self): """Return the availability of the device.""" @@ -397,14 +416,6 @@ class LIFXLight(Light): """Return a string identifying the device.""" return "%s (%s)" % (self.device.ip_addr, self.name) - @property - def rgb_color(self): - """Return the RGB value.""" - hue, sat, bri, _ = self.device.color - - return color_util.color_hsv_to_RGB( - hue, convert_16_to_8(sat), convert_16_to_8(bri)) - @property def brightness(self): """Return the brightness of this light between 0..255.""" @@ -421,26 +432,6 @@ class LIFXLight(Light): _LOGGER.debug("color_temp: %d", temperature) return temperature - @property - def min_mireds(self): - """Return the coldest color_temp that this light supports.""" - # The 3 LIFX "White" products supported a limited temperature range - if self.lifxwhite: - kelvin = 6500 - else: - kelvin = 9000 - return math.floor(color_util.color_temperature_kelvin_to_mired(kelvin)) - - @property - def max_mireds(self): - """Return the warmest color_temp that this light supports.""" - # The 3 LIFX "White" products supported a limited temperature range - if self.lifxwhite: - kelvin = 2700 - else: - kelvin = 2500 - return math.ceil(color_util.color_temperature_kelvin_to_mired(kelvin)) - @property def is_on(self): """Return true if device is on.""" @@ -454,32 +445,6 @@ class LIFXLight(Light): return 'lifx_effect_' + effect.name return None - @property - def supported_features(self): - """Flag supported features.""" - features = (SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP | - SUPPORT_TRANSITION | SUPPORT_EFFECT) - - if not self.lifxwhite: - features |= SUPPORT_RGB_COLOR | SUPPORT_XY_COLOR - - return features - - @property - def effect_list(self): - """Return the list of supported effects for this light.""" - if self.lifxwhite: - return [ - SERVICE_EFFECT_PULSE, - SERVICE_EFFECT_STOP, - ] - - return [ - SERVICE_EFFECT_COLORLOOP, - SERVICE_EFFECT_PULSE, - SERVICE_EFFECT_STOP, - ] - @asyncio.coroutine def update_after_transition(self, now): """Request new status after completion of the last transition.""" @@ -530,30 +495,36 @@ class LIFXLight(Light): power_on = kwargs.get(ATTR_POWER, False) power_off = not kwargs.get(ATTR_POWER, True) - hsbk = merge_hsbk(self.device.color, find_hsbk(**kwargs)) + hsbk = find_hsbk(**kwargs) # Send messages, waiting for ACK each time - ack = AwaitAioLIFX(self).wait + ack = AwaitAioLIFX().wait bulb = self.device if not self.is_on: if power_off: yield from ack(partial(bulb.set_power, False)) if hsbk: - yield from ack(partial(bulb.set_color, hsbk)) + yield from self.send_color(ack, hsbk, kwargs, duration=0) if power_on: yield from ack(partial(bulb.set_power, True, duration=fade)) else: if power_on: yield from ack(partial(bulb.set_power, True)) if hsbk: - yield from ack(partial(bulb.set_color, hsbk, duration=fade)) + yield from self.send_color(ack, hsbk, kwargs, duration=fade) if power_off: yield from ack(partial(bulb.set_power, False, duration=fade)) # Schedule an update when the transition is complete self.update_later(fade) + @asyncio.coroutine + def send_color(self, ack, hsbk, kwargs, duration): + """Send a color change to the device.""" + hsbk = merge_hsbk(self.device.color, hsbk) + yield from ack(partial(self.device.set_color, hsbk, duration=duration)) + @asyncio.coroutine def default_effect(self, **kwargs): """Start an effect with default parameters.""" @@ -569,5 +540,117 @@ class LIFXLight(Light): _LOGGER.debug("%s async_update", self.who) if self.available: # Avoid state ping-pong by holding off updates as the state settles - yield from asyncio.sleep(0.25) - yield from AwaitAioLIFX(self).wait(self.device.get_color) + yield from asyncio.sleep(0.3) + yield from AwaitAioLIFX().wait(self.device.get_color) + + +class LIFXWhite(LIFXLight): + """Representation of a white-only LIFX light.""" + + @property + def min_mireds(self): + """Return the coldest color_temp that this light supports.""" + return math.floor(color_util.color_temperature_kelvin_to_mired(6500)) + + @property + def max_mireds(self): + """Return the warmest color_temp that this light supports.""" + return math.ceil(color_util.color_temperature_kelvin_to_mired(2700)) + + @property + def supported_features(self): + """Flag supported features.""" + return (SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP | SUPPORT_TRANSITION | + SUPPORT_EFFECT) + + @property + def effect_list(self): + """Return the list of supported effects for this light.""" + return [ + SERVICE_EFFECT_PULSE, + SERVICE_EFFECT_STOP, + ] + + +class LIFXColor(LIFXLight): + """Representation of a color LIFX light.""" + + @property + def min_mireds(self): + """Return the coldest color_temp that this light supports.""" + return math.floor(color_util.color_temperature_kelvin_to_mired(9000)) + + @property + def max_mireds(self): + """Return the warmest color_temp that this light supports.""" + return math.ceil(color_util.color_temperature_kelvin_to_mired(2500)) + + @property + def supported_features(self): + """Flag supported features.""" + return (SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP | SUPPORT_TRANSITION | + SUPPORT_EFFECT | SUPPORT_RGB_COLOR | SUPPORT_XY_COLOR) + + @property + def effect_list(self): + """Return the list of supported effects for this light.""" + return [ + SERVICE_EFFECT_COLORLOOP, + SERVICE_EFFECT_PULSE, + SERVICE_EFFECT_STOP, + ] + + @property + def rgb_color(self): + """Return the RGB value.""" + hue, sat, bri, _ = self.device.color + + return color_util.color_hsv_to_RGB( + hue, convert_16_to_8(sat), convert_16_to_8(bri)) + + +class LIFXStrip(LIFXColor): + """Representation of a LIFX light strip with multiple zones.""" + + @asyncio.coroutine + def send_color(self, ack, hsbk, kwargs, duration): + """Send a color change to the device.""" + bulb = self.device + num_zones = len(bulb.color_zones) + + # Zone brightness is not reported when powered off + if not self.is_on and hsbk[2] is None: + yield from ack(partial(bulb.set_power, True)) + yield from self.async_update() + yield from ack(partial(bulb.set_power, False)) + + zones = kwargs.get(ATTR_ZONES, None) + if zones is None: + zones = list(range(0, num_zones)) + else: + zones = list(filter(lambda x: x < num_zones, set(zones))) + + # Send new color to each zone + for index, zone in enumerate(zones): + zone_hsbk = merge_hsbk(bulb.color_zones[zone], hsbk) + apply = 1 if (index == len(zones)-1) else 0 + set_zone = partial(bulb.set_color_zones, + start_index=zone, + end_index=zone, + color=zone_hsbk, + duration=duration, + apply=apply) + yield from ack(set_zone) + + @asyncio.coroutine + def async_update(self): + """Update strip status.""" + if self.available: + yield from super().async_update() + + ack = AwaitAioLIFX().wait + bulb = self.device + + # Each get_color_zones returns the next 8 zones + for zone in range(0, len(bulb.color_zones), 8): + yield from ack(partial(bulb.get_color_zones, start_index=zone)) diff --git a/homeassistant/components/light/services.yaml b/homeassistant/components/light/services.yaml index ef99f18fb42..782d4496442 100644 --- a/homeassistant/components/light/services.yaml +++ b/homeassistant/components/light/services.yaml @@ -117,6 +117,10 @@ lifx_set_state: description: Automatic infrared level (0..255) when light brightness is low example: 255 + zones: + description: List of zone numbers to affect (8 per LIFX Z, starts at 0) + example: '[0,5]' + transition: description: Duration in seconds it takes to get to the final state example: 10 diff --git a/requirements_all.txt b/requirements_all.txt index d4e4a30add7..58ef8d070d0 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -52,7 +52,7 @@ aiohttp_cors==0.5.3 aiolifx==0.5.2 # homeassistant.components.light.lifx -aiolifx_effects==0.1.0 +aiolifx_effects==0.1.1 # homeassistant.components.scene.hunterdouglas_powerview aiopvapi==1.4 From 21e82bd0371aa7419e24c66a78e08ff7f62c73b5 Mon Sep 17 00:00:00 2001 From: Dougal Matthews Date: Fri, 14 Jul 2017 04:53:19 +0200 Subject: [PATCH 126/131] Add RGB support to switch.flux (#8417) --- homeassistant/components/switch/flux.py | 20 +++++++++-- tests/components/switch/test_flux.py | 47 +++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/switch/flux.py b/homeassistant/components/switch/flux.py index daa4d1f8cd1..dea4285e3a9 100644 --- a/homeassistant/components/switch/flux.py +++ b/homeassistant/components/switch/flux.py @@ -37,6 +37,7 @@ CONF_MODE = 'mode' MODE_XY = 'xy' MODE_MIRED = 'mired' +MODE_RGB = 'rgb' DEFAULT_MODE = MODE_XY PLATFORM_SCHEMA = vol.Schema({ @@ -55,7 +56,7 @@ PLATFORM_SCHEMA = vol.Schema({ vol.All(vol.Coerce(int), vol.Range(min=0, max=255)), vol.Optional(CONF_DISABLE_BRIGTNESS_ADJUST): cv.boolean, vol.Optional(CONF_MODE, default=DEFAULT_MODE): - vol.Any(MODE_XY, MODE_MIRED) + vol.Any(MODE_XY, MODE_MIRED, MODE_RGB) }) @@ -79,6 +80,15 @@ def set_lights_temp(hass, lights, mired, brightness): transition=30) +def set_lights_rgb(hass, lights, rgb): + """Set color of array of lights.""" + for light in lights: + if is_on(hass, light): + turn_on(hass, light, + rgb_color=rgb, + transition=30) + + # pylint: disable=unused-argument def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Flux switches.""" @@ -194,7 +204,8 @@ class FluxSwitch(SwitchDevice): temp = self._sunset_colortemp - temp_offset else: temp = self._sunset_colortemp + temp_offset - x_val, y_val, b_val = color_RGB_to_xy(*color_temperature_to_rgb(temp)) + rgb = color_temperature_to_rgb(temp) + x_val, y_val, b_val = color_RGB_to_xy(*rgb) brightness = self._brightness if self._brightness else b_val if self._disable_brightness_adjust: brightness = None @@ -205,6 +216,11 @@ class FluxSwitch(SwitchDevice): "of %s cycle complete at %s", x_val, y_val, brightness, round( percentage_complete * 100), time_state, now) + elif self._mode == MODE_RGB: + set_lights_rgb(self.hass, self._lights, rgb) + _LOGGER.info("Lights updated to rgb:%s, %s%% " + "of %s cycle complete at %s", rgb, + round(percentage_complete * 100), time_state, now) else: # Convert to mired and clamp to allowed values mired = color_temperature_kelvin_to_mired(temp) diff --git a/tests/components/switch/test_flux.py b/tests/components/switch/test_flux.py index 2422f0ea334..d529e8c3f56 100644 --- a/tests/components/switch/test_flux.py +++ b/tests/components/switch/test_flux.py @@ -557,3 +557,50 @@ class TestSwitchFlux(unittest.TestCase): self.hass.block_till_done() call = turn_on_calls[-1] self.assertEqual(call.data[light.ATTR_COLOR_TEMP], 269) + + def test_flux_with_rgb(self): + """Test the flux switch´s mode rgb.""" + platform = loader.get_component('light.test') + platform.init() + self.assertTrue( + setup_component(self.hass, light.DOMAIN, + {light.DOMAIN: {CONF_PLATFORM: 'test'}})) + + dev1 = platform.DEVICES[0] + + # Verify initial state of light + state = self.hass.states.get(dev1.entity_id) + self.assertEqual(STATE_ON, state.state) + self.assertIsNone(state.attributes.get('color_temp')) + + test_time = dt_util.now().replace(hour=8, minute=30, second=0) + sunset_time = test_time.replace(hour=17, minute=0, second=0) + sunrise_time = test_time.replace(hour=5, minute=0, second=0) + + def event_date(hass, event, now=None): + if event == 'sunrise': + return sunrise_time + else: + return sunset_time + + with patch('homeassistant.util.dt.now', return_value=test_time): + with patch('homeassistant.helpers.sun.get_astral_event_date', + side_effect=event_date): + assert setup_component(self.hass, switch.DOMAIN, { + switch.DOMAIN: { + 'platform': 'flux', + 'name': 'flux', + 'lights': [dev1.entity_id], + 'mode': 'rgb' + } + }) + turn_on_calls = mock_service( + self.hass, light.DOMAIN, SERVICE_TURN_ON) + switch.turn_on(self.hass, 'switch.flux') + self.hass.block_till_done() + fire_time_changed(self.hass, test_time) + self.hass.block_till_done() + call = turn_on_calls[-1] + rgb = (255, 198, 152) + rounded_call = tuple(map(round, call.data[light.ATTR_RGB_COLOR])) + self.assertEqual(rounded_call, rgb) From bd1e533409a6651c867725699751bb68bd7a87f8 Mon Sep 17 00:00:00 2001 From: dersger Date: Fri, 14 Jul 2017 05:00:23 +0200 Subject: [PATCH 127/131] Fix media_position for cast component (#8452) * Make it available during state paused. * Don't adjust for media_position_updated_at. I.e. do as vlc, sonos etc so that returned position is the position at the time of media_position_updated_at, not now. --- homeassistant/components/media_player/cast.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/media_player/cast.py b/homeassistant/components/media_player/cast.py index 418d3576750..51acf68d819 100644 --- a/homeassistant/components/media_player/cast.py +++ b/homeassistant/components/media_player/cast.py @@ -234,18 +234,13 @@ class CastDevice(MediaPlayerDevice): @property def media_position(self): """Position of current playing media in seconds.""" - if self.media_status is None or self.media_status_received is None or \ + if self.media_status is None or \ not (self.media_status.player_is_playing or + self.media_status.player_is_paused or self.media_status.player_is_idle): return None - position = self.media_status.current_time - - if self.media_status.player_is_playing: - position += (dt_util.utcnow() - - self.media_status_received).total_seconds() - - return position + return self.media_status.current_time @property def media_position_updated_at(self): From e5e2a151aa5d31e28e46f0bd2b2c86ba036e8f6a Mon Sep 17 00:00:00 2001 From: Sean Gollschewsky Date: Fri, 14 Jul 2017 04:01:25 +0100 Subject: [PATCH 128/131] Remove km from visibility, add visibility_distance (#8454) * Remove km from visibility, add visibility_distance * Fix line length * Fix trailing space and line break indentation * Indentation * More whitespace --- homeassistant/components/sensor/metoffice.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/sensor/metoffice.py b/homeassistant/components/sensor/metoffice.py index a20ec8fdd5a..25516eda5b1 100644 --- a/homeassistant/components/sensor/metoffice.py +++ b/homeassistant/components/sensor/metoffice.py @@ -40,6 +40,15 @@ CONDITION_CLASSES = { 'exceptional': [], } +VISIBILTY_CLASSES = { + 'VP': '<1', + 'PO': '1-4', + 'MO': '4-10', + 'GO': '10-20', + 'VG': '20-40', + 'EX': '>40' +} + SCAN_INTERVAL = timedelta(minutes=35) # Sensor types are defined like: Name, units @@ -51,7 +60,8 @@ SENSOR_TYPES = { 'wind_speed': ['Wind Speed', 'm/s'], 'wind_direction': ['Wind Direction', None], 'wind_gust': ['Wind Gust', 'm/s'], - 'visibility': ['Visibility', 'km'], + 'visibility': ['Visibility', None], + 'visibility_distance': ['Visibility Distance', 'km'], 'uv': ['UV', None], 'precipitation': ['Probability of Precipitation', '%'], 'humidity': ['Humidity', '%'] @@ -119,6 +129,9 @@ class MetOfficeCurrentSensor(Entity): @property def state(self): """Return the state of the sensor.""" + if (self._condition == 'visibility_distance' and + 'visibility' in self.data.data.__dict__.keys()): + return VISIBILTY_CLASSES.get(self.data.data.visibility.value) if self._condition in self.data.data.__dict__.keys(): variable = getattr(self.data.data, self._condition) if self._condition == "weather": From 1366c93c83f3cd2f55bdfa4f2ea2f526d497ac47 Mon Sep 17 00:00:00 2001 From: Bryce Edwards Date: Thu, 13 Jul 2017 22:02:07 -0500 Subject: [PATCH 129/131] Radarr sensor fix for issue #8250 (#8456) * Radarr sensor fix for issue #8250 * Radarr sensor fix for issue #8250 --- homeassistant/components/sensor/radarr.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/sensor/radarr.py b/homeassistant/components/sensor/radarr.py index f5efe12c449..59408b4f96b 100644 --- a/homeassistant/components/sensor/radarr.py +++ b/homeassistant/components/sensor/radarr.py @@ -216,9 +216,9 @@ def get_date(zone, offset=0): def get_release_date(data): """Get release date.""" - date = data['physicalRelease'] + date = data.get('physicalRelease') if not date: - date = data['inCinemas'] + date = data.get('inCinemas') return date From 84ca4d2a21831701dd9e5c10811e07ceccde4bee Mon Sep 17 00:00:00 2001 From: Anders Melchiorsen Date: Fri, 14 Jul 2017 05:04:23 +0200 Subject: [PATCH 130/131] Accept transition for light.toggle (#8466) --- homeassistant/helpers/entity.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index da177bc4331..49f250c65fa 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -378,18 +378,18 @@ class ToggleEntity(Entity): return self.hass.async_add_job( ft.partial(self.turn_off, **kwargs)) - def toggle(self) -> None: + def toggle(self, **kwargs) -> None: """Toggle the entity.""" if self.is_on: - self.turn_off() + self.turn_off(**kwargs) else: - self.turn_on() + self.turn_on(**kwargs) - def async_toggle(self): + def async_toggle(self, **kwargs): """Toggle the entity. This method must be run in the event loop and returns a coroutine. """ if self.is_on: - return self.async_turn_off() - return self.async_turn_on() + return self.async_turn_off(**kwargs) + return self.async_turn_on(**kwargs) From 3377f3061331b22733d4314423f41f0bc7accfa8 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 14 Jul 2017 21:26:26 +0300 Subject: [PATCH 131/131] Make themes API work even when themes are not defined. (#8473) --- homeassistant/components/frontend/__init__.py | 11 +++++++---- tests/components/test_frontend.py | 10 ++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index 4184feabaeb..443ff6f3852 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -212,17 +212,20 @@ def setup(hass, config): register_built_in_panel(hass, panel) themes = config.get(DOMAIN, {}).get(ATTR_THEMES) - if themes: - setup_themes(hass, themes) + setup_themes(hass, themes) return True def setup_themes(hass, themes): """Set up themes data and services.""" - hass.data[DATA_THEMES] = themes - hass.data[DATA_DEFAULT_THEME] = DEFAULT_THEME hass.http.register_view(ThemesView) + hass.data[DATA_DEFAULT_THEME] = DEFAULT_THEME + if themes is None: + hass.data[DATA_THEMES] = {} + return + + hass.data[DATA_THEMES] = themes @callback def update_theme_and_fire_event(): diff --git a/tests/components/test_frontend.py b/tests/components/test_frontend.py index d1e2e5d4346..3682e0a2c14 100644 --- a/tests/components/test_frontend.py +++ b/tests/components/test_frontend.py @@ -133,3 +133,13 @@ def test_themes_reload_themes(hass, mock_http_client_with_themes): json = yield from resp.json() assert json['themes'] == {'sad': {'primary-color': 'blue'}} assert json['default_theme'] == 'default' + + +@asyncio.coroutine +def test_missing_themes(mock_http_client): + """Test that themes API works when themes are not defined.""" + resp = yield from mock_http_client.get('/api/themes') + assert resp.status == 200 + json = yield from resp.json() + assert json['default_theme'] == 'default' + assert json['themes'] == {}

    *ID~GzPqa;G*HcB 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 j*vgPXt6#H&TmD9lK#WEPC~E \ No newline at end of file + \ No newline at end of file diff --git a/homeassistant/components/frontend/www_static/mdi.html.gz b/homeassistant/components/frontend/www_static/mdi.html.gz index 99be72e33ea84ec7ee01a9b66e49adae404b63c5..d983d4a89f84457199beabc8d49dac7fb36534c2 100644 GIT binary patch delta 175377 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�-1a`ULZd#sJGVlx53m(cAfF0<#F{(7XTb{$Byh? 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%0DpY$lg%xod<63(A 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 delta 174630 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%0Aa(RQ6+}fmKlVc%;ZOCHOi)2gF!b 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