From 6541e789fb329a19b58f3001dad11f849934159b Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 5 Oct 2017 09:18:01 -0700 Subject: [PATCH 01/17] Version bump to 0.55 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 01a28493e5e..33c91eeb067 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 55 -PATCH_VERSION = '0.dev0' +PATCH_VERSION = '0' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 4, 2) From 1ab942e0a2a1ede1a8c3c44268fb6d00ecc1c83b Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 5 Oct 2017 21:47:51 -0700 Subject: [PATCH 02/17] Deprecate Python 3.4 support (#9684) * Deprecate Python 3.4 support * Update text --- homeassistant/bootstrap.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/homeassistant/bootstrap.py b/homeassistant/bootstrap.py index 3ff4d99fb98..b62b86b30d2 100644 --- a/homeassistant/bootstrap.py +++ b/homeassistant/bootstrap.py @@ -83,6 +83,18 @@ def async_from_config_dict(config: Dict[str, Any], This method is a coroutine. """ start = time() + + if enable_log: + async_enable_logging(hass, verbose, log_rotate_days, log_file) + + if sys.version_info[:2] < (3, 5): + _LOGGER.warning( + 'Python 3.4 support has been deprecated and will be removed in ' + 'the begining of 2018. Please upgrade Python or your operating ' + 'system. More info: https://home-assistant.io/blog/2017/10/06/' + 'deprecating-python-3.4-support/' + ) + core_config = config.get(core.DOMAIN, {}) try: @@ -93,9 +105,6 @@ def async_from_config_dict(config: Dict[str, Any], yield from hass.async_add_job(conf_util.process_ha_config_upgrade, hass) - if enable_log: - async_enable_logging(hass, verbose, log_rotate_days, log_file) - hass.config.skip_pip = skip_pip if skip_pip: _LOGGER.warning("Skipping pip installation of required modules. " From 770f8bd1c39ac78b0c91e3a665586e7075319a3b Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 5 Oct 2017 21:12:49 -0700 Subject: [PATCH 03/17] Fix coap commit (#9712) --- virtualization/Docker/scripts/aiocoap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virtualization/Docker/scripts/aiocoap b/virtualization/Docker/scripts/aiocoap index 8e36c616cb4..275b641806d 100755 --- a/virtualization/Docker/scripts/aiocoap +++ b/virtualization/Docker/scripts/aiocoap @@ -19,5 +19,5 @@ python3 setup.py install cd ../.. git clone --depth 1 https://github.com/chrysn/aiocoap/ cd aiocoap -git reset --hard 0df6a1e44582de99ae944b6a7536d08e2a612e8f +git reset --hard 3286f48f0b949901c8b5c04c0719dc54ab63d431 python3 -m pip install . From de4f610540f3f149ff9d942ba5aab7c0bb425d42 Mon Sep 17 00:00:00 2001 From: Lewis Juggins Date: Sat, 7 Oct 2017 16:54:51 +0100 Subject: [PATCH 04/17] [light.tradfri] Clone all of aiocoap to ensure pinned commit will be present (#9713) --- virtualization/Docker/scripts/aiocoap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virtualization/Docker/scripts/aiocoap b/virtualization/Docker/scripts/aiocoap index 275b641806d..e234aa31236 100755 --- a/virtualization/Docker/scripts/aiocoap +++ b/virtualization/Docker/scripts/aiocoap @@ -17,7 +17,7 @@ cd cython python3 setup.py install cd ../.. -git clone --depth 1 https://github.com/chrysn/aiocoap/ +git clone https://github.com/chrysn/aiocoap cd aiocoap git reset --hard 3286f48f0b949901c8b5c04c0719dc54ab63d431 python3 -m pip install . From 7ed21d90aac75551c8aa1e43dded621e12ae72ab Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 15 Oct 2017 11:51:21 -0700 Subject: [PATCH 05/17] Version bump to 0.55.1 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 33c91eeb067..30b81385877 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 55 -PATCH_VERSION = '0' +PATCH_VERSION = '1' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 4, 2) From 45620d68922b856b0f24eab11c5e8346a59e76ee Mon Sep 17 00:00:00 2001 From: Joe Lu Date: Sun, 8 Oct 2017 03:31:00 -0700 Subject: [PATCH 06/17] Fix for TypeError in synology camera (#9754) --- homeassistant/components/camera/synology.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/camera/synology.py b/homeassistant/components/camera/synology.py index be01a7fc90d..0b97f55397c 100644 --- a/homeassistant/components/camera/synology.py +++ b/homeassistant/components/camera/synology.py @@ -20,7 +20,7 @@ from homeassistant.helpers.aiohttp_client import ( async_aiohttp_proxy_web) import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['py-synology==0.1.1'] +REQUIREMENTS = ['py-synology==0.1.3'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index a04a4240ae4..4838cb12ded 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -540,7 +540,7 @@ pwmled==1.2.1 py-cpuinfo==3.3.0 # homeassistant.components.camera.synology -py-synology==0.1.1 +py-synology==0.1.3 # homeassistant.components.hdmi_cec pyCEC==0.4.13 From 9b43388093479c6aab4ea191322a7414a7857f4b Mon Sep 17 00:00:00 2001 From: pascal Date: Mon, 9 Oct 2017 16:57:44 +0200 Subject: [PATCH 07/17] missing is_closed ( rflink cover fix ) (#9776) * Added is_closed * whitespaces -- * removed whitespace --- homeassistant/components/cover/rflink.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/homeassistant/components/cover/rflink.py b/homeassistant/components/cover/rflink.py index 45a0b27aa07..a9b7598159f 100644 --- a/homeassistant/components/cover/rflink.py +++ b/homeassistant/components/cover/rflink.py @@ -103,6 +103,11 @@ class RflinkCover(RflinkCommand, CoverDevice): """No polling available in RFlink cover.""" return False + @property + def is_closed(self): + """Return if the cover is closed.""" + return None + def async_close_cover(self, **kwargs): """Turn the device close.""" return self._async_handle_command("close_cover") From 431201cb9ba173708403ece5d45e0aaeb5c3c2d4 Mon Sep 17 00:00:00 2001 From: Lewis Juggins Date: Tue, 10 Oct 2017 08:35:28 +0100 Subject: [PATCH 08/17] [light.tradfri] Fix transition time (#9785) * Fix transition time, set a default * Wrong default * Use int for safety * Revert default. --- homeassistant/components/light/tradfri.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/light/tradfri.py b/homeassistant/components/light/tradfri.py index 3efab8309fc..f4feb4b7adf 100644 --- a/homeassistant/components/light/tradfri.py +++ b/homeassistant/components/light/tradfri.py @@ -105,7 +105,7 @@ class TradfriGroup(Light): """Instruct the group lights to turn on, or dim.""" keys = {} if ATTR_TRANSITION in kwargs: - keys['transition_time'] = int(kwargs[ATTR_TRANSITION]) + keys['transition_time'] = int(kwargs[ATTR_TRANSITION]) * 10 if ATTR_BRIGHTNESS in kwargs: self.hass.async_add_job(self._api( @@ -259,7 +259,7 @@ class TradfriLight(Light): keys = {} if ATTR_TRANSITION in kwargs: - keys['transition_time'] = int(kwargs[ATTR_TRANSITION]) + keys['transition_time'] = int(kwargs[ATTR_TRANSITION]) * 10 if ATTR_BRIGHTNESS in kwargs: self.hass.async_add_job(self._api( From 586e54f8bf3bcf58476dba619fa6cecf65d94d1b Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 10 Oct 2017 01:39:25 -0700 Subject: [PATCH 09/17] OwnTracks: Fix handler is None checking (#9794) * OwnTracks: Fix handler is None checking * Update owntracks.py --- homeassistant/components/device_tracker/owntracks.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/device_tracker/owntracks.py b/homeassistant/components/device_tracker/owntracks.py index 07dc9f1ab5c..f301b2f454e 100644 --- a/homeassistant/components/device_tracker/owntracks.py +++ b/homeassistant/components/device_tracker/owntracks.py @@ -407,7 +407,8 @@ def async_handle_message(hass, context, message): handler = HANDLERS.get(msgtype) if handler is None: - error = 'Received unsupported message type: {}.'.format(msgtype) - _LOGGER.warning(error) + _LOGGER.warning( + 'Received unsupported message type: %s.', msgtype) + return yield from handler(hass, context, message) From fdb698bef071e87a6ef6cac4bcd8290ed022cfde Mon Sep 17 00:00:00 2001 From: Adam Cooper Date: Fri, 13 Oct 2017 06:05:33 +0100 Subject: [PATCH 10/17] Changed yaml.load into yaml.safe_load (#9841) --- homeassistant/components/google.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/google.py b/homeassistant/components/google.py index 889c905613f..efb2b12bfca 100644 --- a/homeassistant/components/google.py +++ b/homeassistant/components/google.py @@ -269,7 +269,7 @@ def load_config(path): calendars = {} try: with open(path) as file: - data = yaml.load(file) + data = yaml.safe_load(file) for calendar in data: try: calendars.update({calendar[CONF_CAL_ID]: From 2547a235c18548adcc8b281180cc01ef3b92b591 Mon Sep 17 00:00:00 2001 From: Adam Cooper Date: Fri, 13 Oct 2017 06:01:29 +0100 Subject: [PATCH 11/17] Bugfix/9811 jinja autoescape (#9842) * Added autoescape kwarg to Jinja environment * Removed extra comma --- homeassistant/components/frontend/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index 112c93403b0..1820dcdc3f6 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -329,6 +329,7 @@ class IndexView(HomeAssistantView): from jinja2 import FileSystemLoader, Environment self.templates = Environment( + autoescape=True, loader=FileSystemLoader( os.path.join(os.path.dirname(__file__), 'templates/') ) From ff6f5cc1166a6fecb791e259c27f7771d6eb2697 Mon Sep 17 00:00:00 2001 From: Philipp Schmitt Date: Sun, 15 Oct 2017 21:16:23 +0200 Subject: [PATCH 12/17] Fix #9839 (#9880) * Fix #9839 * Update requirements * Default state: STATE_UNKNOWN -> None * Default the state to None in the constructor as well --- homeassistant/components/media_player/liveboxplaytv.py | 8 ++++---- requirements_all.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/media_player/liveboxplaytv.py b/homeassistant/components/media_player/liveboxplaytv.py index 43678d90829..594e9b20432 100644 --- a/homeassistant/components/media_player/liveboxplaytv.py +++ b/homeassistant/components/media_player/liveboxplaytv.py @@ -18,10 +18,10 @@ from homeassistant.components.media_player import ( MEDIA_TYPE_CHANNEL, MediaPlayerDevice, PLATFORM_SCHEMA) from homeassistant.const import ( CONF_HOST, CONF_PORT, STATE_ON, STATE_OFF, STATE_PLAYING, - STATE_PAUSED, STATE_UNKNOWN, CONF_NAME) + STATE_PAUSED, CONF_NAME) import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['liveboxplaytv==1.4.9'] +REQUIREMENTS = ['liveboxplaytv==1.5.0'] _LOGGER = logging.getLogger(__name__) @@ -72,7 +72,7 @@ class LiveboxPlayTvDevice(MediaPlayerDevice): self._muted = False self._name = name self._current_source = None - self._state = STATE_UNKNOWN + self._state = None self._channel_list = {} self._current_channel = None self._current_program = None @@ -92,7 +92,7 @@ class LiveboxPlayTvDevice(MediaPlayerDevice): self._client.get_current_channel_image(img_size=300) self.refresh_channel_list() except requests.ConnectionError: - self._state = STATE_OFF + self._state = None @property def name(self): diff --git a/requirements_all.txt b/requirements_all.txt index 4838cb12ded..6bbc87aed06 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -398,7 +398,7 @@ lightify==1.0.6 limitlessled==1.0.8 # homeassistant.components.media_player.liveboxplaytv -liveboxplaytv==1.4.9 +liveboxplaytv==1.5.0 # homeassistant.components.lametric # homeassistant.components.notify.lametric From 1f25aa74ddd2aff158d2f08cd6babafdb5ab276a Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Mon, 16 Oct 2017 21:01:25 +0200 Subject: [PATCH 13/17] Release 0.55.2 (#9904) * Do not auto-install credstash (#9844) * Pump release to 0.55.2 --- homeassistant/const.py | 2 +- homeassistant/scripts/credstash.py | 1 + homeassistant/util/yaml.py | 2 +- requirements_all.txt | 2 +- script/gen_requirements_all.py | 3 ++- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 30b81385877..95a3c63bb8f 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 55 -PATCH_VERSION = '1' +PATCH_VERSION = '2' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 4, 2) diff --git a/homeassistant/scripts/credstash.py b/homeassistant/scripts/credstash.py index f17105d83de..4c9273b8299 100644 --- a/homeassistant/scripts/credstash.py +++ b/homeassistant/scripts/credstash.py @@ -24,6 +24,7 @@ def run(args): 'value', help="The value to save when putting a secret", nargs='?', default=None) + # pylint: disable=import-error import credstash import botocore diff --git a/homeassistant/util/yaml.py b/homeassistant/util/yaml.py index c484fe3372a..da97ed5662e 100644 --- a/homeassistant/util/yaml.py +++ b/homeassistant/util/yaml.py @@ -13,7 +13,7 @@ except ImportError: keyring = None try: - import credstash + import credstash # pylint: disable=import-error except ImportError: credstash = None diff --git a/requirements_all.txt b/requirements_all.txt index 6bbc87aed06..d7f53c75dc1 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -156,7 +156,7 @@ colorlog==3.0.1 concord232==0.14 # homeassistant.scripts.credstash -credstash==1.13.3 +# credstash==1.13.3 # homeassistant.components.sensor.crimereports crimereports==1.0.0 diff --git a/script/gen_requirements_all.py b/script/gen_requirements_all.py index dd1602fba6f..ba9cecb6684 100755 --- a/script/gen_requirements_all.py +++ b/script/gen_requirements_all.py @@ -29,7 +29,8 @@ COMMENT_REQUIREMENTS = ( 'blinkt', 'smbus-cffi', 'envirophat', - 'i2csense' + 'i2csense', + 'credstash' ) TEST_REQUIREMENTS = ( From 9722125234466427b6ff67e857f69213109c20cf Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 19 Oct 2017 09:01:03 -0700 Subject: [PATCH 14/17] Version bump to 0.56 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index fa2b2ad707b..ddb7114dbca 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 56 -PATCH_VERSION = '0.dev0' +PATCH_VERSION = '0' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 4, 2) From d9f5398c560c1326a481ff7715ca17606a32f80f Mon Sep 17 00:00:00 2001 From: Lewis Juggins Date: Fri, 20 Oct 2017 07:20:33 +0100 Subject: [PATCH 15/17] [tradfri] Update pytradfri, simplify dependencies. (#9875) * Update pytradfri * Process dep links * Process dep links * Process dep links * Install all deps * Update requirements * Exclude aiocoap * Install cython * Remove cython * Exclude DTLSSocket * Add cython --- Dockerfile | 6 ++---- homeassistant/components/light/tradfri.py | 4 ++-- homeassistant/components/sensor/tradfri.py | 2 +- homeassistant/components/tradfri.py | 6 +++++- requirements_all.txt | 8 +++++++- script/gen_requirements_all.py | 4 +++- virtualization/Docker/Dockerfile.dev | 4 ++-- virtualization/Docker/scripts/aiocoap | 23 ---------------------- virtualization/Docker/setup_docker_prereqs | 5 ----- 9 files changed, 22 insertions(+), 40 deletions(-) delete mode 100755 virtualization/Docker/scripts/aiocoap diff --git a/Dockerfile b/Dockerfile index 908e8481eee..3eadc8e7b03 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,10 +11,8 @@ MAINTAINER Paulus Schoutsen #ENV INSTALL_FFMPEG no #ENV INSTALL_LIBCEC no #ENV INSTALL_PHANTOMJS no -#ENV INSTALL_COAP no #ENV INSTALL_SSOCR no - VOLUME /config RUN mkdir -p /usr/src/app @@ -26,10 +24,10 @@ RUN virtualization/Docker/setup_docker_prereqs # Install hass component dependencies COPY requirements_all.txt requirements_all.txt -# Uninstall enum34 because some depenndecies install it but breaks Python 3.4+. +# Uninstall enum34 because some dependencies install it but breaks Python 3.4+. # See PR #8103 for more info. RUN pip3 install --no-cache-dir -r requirements_all.txt && \ - pip3 install --no-cache-dir mysqlclient psycopg2 uvloop cchardet + pip3 install --no-cache-dir mysqlclient psycopg2 uvloop cchardet cython # Copy source COPY . . diff --git a/homeassistant/components/light/tradfri.py b/homeassistant/components/light/tradfri.py index f4feb4b7adf..ff9201d49b9 100644 --- a/homeassistant/components/light/tradfri.py +++ b/homeassistant/components/light/tradfri.py @@ -40,7 +40,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): devices_command = gateway.get_devices() devices_commands = yield from api(devices_command) - devices = yield from api(*devices_commands) + devices = yield from api(devices_commands) lights = [dev for dev in devices if dev.has_light_control] if lights: async_add_devices(TradfriLight(light, api) for light in lights) @@ -49,7 +49,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): if allow_tradfri_groups: groups_command = gateway.get_groups() groups_commands = yield from api(groups_command) - groups = yield from api(*groups_commands) + groups = yield from api(groups_commands) if groups: async_add_devices(TradfriGroup(group, api) for group in groups) diff --git a/homeassistant/components/sensor/tradfri.py b/homeassistant/components/sensor/tradfri.py index 314c18b7636..88a33cb2f8a 100644 --- a/homeassistant/components/sensor/tradfri.py +++ b/homeassistant/components/sensor/tradfri.py @@ -32,7 +32,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): devices_command = gateway.get_devices() devices_commands = yield from api(devices_command) - all_devices = yield from api(*devices_commands) + all_devices = yield from api(devices_commands) devices = [dev for dev in all_devices if not dev.has_light_control] async_add_devices(TradfriDevice(device, api) for device in devices) diff --git a/homeassistant/components/tradfri.py b/homeassistant/components/tradfri.py index ef4d7fceed8..a24305c7fd4 100644 --- a/homeassistant/components/tradfri.py +++ b/homeassistant/components/tradfri.py @@ -16,7 +16,11 @@ from homeassistant.helpers import discovery from homeassistant.const import CONF_HOST, CONF_API_KEY from homeassistant.components.discovery import SERVICE_IKEA_TRADFRI -REQUIREMENTS = ['pytradfri==2.2.2'] +REQUIREMENTS = ['pytradfri==3.0', + 'DTLSSocket==0.1.3', + 'https://github.com/chrysn/aiocoap/archive/' + '3286f48f0b949901c8b5c04c0719dc54ab63d431.zip' + '#aiocoap==0.3'] DOMAIN = 'tradfri' CONFIG_FILE = 'tradfri.conf' diff --git a/requirements_all.txt b/requirements_all.txt index 98abf7b57e8..985d9d539cd 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -18,6 +18,9 @@ certifi>=2017.4.17 # homeassistant.components.bbb_gpio # Adafruit_BBIO==1.0.0 +# homeassistant.components.tradfri +# DTLSSocket==0.1.3 + # homeassistant.components.doorbird DoorBirdPy==0.0.4 @@ -324,6 +327,9 @@ http://github.com/tgaugry/suds-passworddigest-py3/archive/86fc50e39b4d2b89974819 # homeassistant.components.media_player.braviatv https://github.com/aparraga/braviarc/archive/0.3.7.zip#braviarc==0.3.7 +# homeassistant.components.tradfri +# https://github.com/chrysn/aiocoap/archive/3286f48f0b949901c8b5c04c0719dc54ab63d431.zip#aiocoap==0.3 + # homeassistant.components.media_player.spotify https://github.com/happyleavesaoc/spotipy/archive/544614f4b1d508201d363e84e871f86c90aa26b2.zip#spotipy==2.4.4 @@ -843,7 +849,7 @@ pythonegardia==1.0.22 pytrackr==0.0.5 # homeassistant.components.tradfri -pytradfri==2.2.2 +pytradfri==3.0 # homeassistant.components.device_tracker.unifi pyunifi==2.13 diff --git a/script/gen_requirements_all.py b/script/gen_requirements_all.py index 314acc4b4f7..ddac210bc26 100755 --- a/script/gen_requirements_all.py +++ b/script/gen_requirements_all.py @@ -30,7 +30,9 @@ COMMENT_REQUIREMENTS = ( 'smbus-cffi', 'envirophat', 'i2csense', - 'credstash' + 'credstash', + 'aiocoap', # Temp, will be removed when Python 3.4 is no longer supported. + 'DTLSSocket' # Requires cython. ) TEST_REQUIREMENTS = ( diff --git a/virtualization/Docker/Dockerfile.dev b/virtualization/Docker/Dockerfile.dev index 70b1a19f46d..131819a6ca0 100644 --- a/virtualization/Docker/Dockerfile.dev +++ b/virtualization/Docker/Dockerfile.dev @@ -26,10 +26,10 @@ RUN virtualization/Docker/setup_docker_prereqs # Install hass component dependencies COPY requirements_all.txt requirements_all.txt -# Uninstall enum34 because some depenndecies install it but breaks Python 3.4+. +# Uninstall enum34 because some dependencies install it but breaks Python 3.4+. # See PR #8103 for more info. RUN pip3 install --no-cache-dir -r requirements_all.txt && \ - pip3 install --no-cache-dir mysqlclient psycopg2 uvloop cchardet + pip3 install --no-cache-dir mysqlclient psycopg2 uvloop cchardet cython # BEGIN: Development additions diff --git a/virtualization/Docker/scripts/aiocoap b/virtualization/Docker/scripts/aiocoap deleted file mode 100755 index e234aa31236..00000000000 --- a/virtualization/Docker/scripts/aiocoap +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -# Installs a modified coap client with support for dtls for use with IKEA Tradfri - -# Stop on errors -set -e - -python3 -m pip install cython - -cd /usr/src/app/ -mkdir -p build && cd build - -git clone --depth 1 https://git.fslab.de/jkonra2m/tinydtls -cd tinydtls -autoreconf -./configure --with-ecc --without-debug -cd cython -python3 setup.py install - -cd ../.. -git clone https://github.com/chrysn/aiocoap -cd aiocoap -git reset --hard 3286f48f0b949901c8b5c04c0719dc54ab63d431 -python3 -m pip install . diff --git a/virtualization/Docker/setup_docker_prereqs b/virtualization/Docker/setup_docker_prereqs index 95c8cd3f2e7..bd70af28dce 100755 --- a/virtualization/Docker/setup_docker_prereqs +++ b/virtualization/Docker/setup_docker_prereqs @@ -9,7 +9,6 @@ INSTALL_OPENALPR="${INSTALL_OPENALPR:-yes}" INSTALL_FFMPEG="${INSTALL_FFMPEG:-yes}" INSTALL_LIBCEC="${INSTALL_LIBCEC:-yes}" INSTALL_PHANTOMJS="${INSTALL_PHANTOMJS:-yes}" -INSTALL_COAP="${INSTALL_COAP:-yes}" INSTALL_SSOCR="${INSTALL_SSOCR:-yes}" # Required debian packages for running hass or components @@ -59,10 +58,6 @@ if [ "$INSTALL_PHANTOMJS" == "yes" ]; then virtualization/Docker/scripts/phantomjs fi -if [ "$INSTALL_COAP" == "yes" ]; then - virtualization/Docker/scripts/aiocoap -fi - if [ "$INSTALL_SSOCR" == "yes" ]; then virtualization/Docker/scripts/ssocr fi From 60053a642c968251f3c7d4edc83abed112bf15ef Mon Sep 17 00:00:00 2001 From: William Scanlon Date: Fri, 20 Oct 2017 10:18:32 -0400 Subject: [PATCH 16/17] Moved siren to Wink from switch (#9879) --- .coveragerc | 2 +- homeassistant/components/services.yaml | 42 +--- homeassistant/components/switch/services.yaml | 76 ------- homeassistant/components/switch/wink.py | 189 ---------------- .../components/{wink.py => wink/__init__.py} | 212 +++++++++++++++++- homeassistant/components/wink/services.yaml | 122 ++++++++++ 6 files changed, 334 insertions(+), 309 deletions(-) rename homeassistant/components/{wink.py => wink/__init__.py} (73%) create mode 100644 homeassistant/components/wink/services.yaml diff --git a/.coveragerc b/.coveragerc index e16b8d96600..b47616973f6 100644 --- a/.coveragerc +++ b/.coveragerc @@ -223,7 +223,7 @@ omit = homeassistant/components/wemo.py homeassistant/components/*/wemo.py - homeassistant/components/wink.py + homeassistant/components/wink/* homeassistant/components/*/wink.py homeassistant/components/xiaomi_aqara.py diff --git a/homeassistant/components/services.yaml b/homeassistant/components/services.yaml index 2c743f04471..1c7b3123c64 100644 --- a/homeassistant/components/services.yaml +++ b/homeassistant/components/services.yaml @@ -1,4 +1,5 @@ + foursquare: checkin: description: Check a user into a Foursquare venue @@ -542,45 +543,6 @@ input_boolean: description: Entity id of the input boolean to turn on example: 'input_boolean.notify_alerts' -wink: - pair_new_device: - description: Pair a new device to a Wink Hub. - - fields: - hub_name: - description: The name of the hub to pair a new device to. - example: 'My hub' - pairing_mode: - description: One of ["zigbee", "zwave", "zwave_exclusion", "zwave_network_rediscovery", "lutron", "bluetooth", "kidde"] - example: 'zigbee' - kidde_radio_code: - description: A string of 8 1s and 0s one for each dip switch on the kidde device left --> right = 1 --> 8 - example: '10101010' - - rename_wink_device: - description: Rename the provided device. - - fields: - entity_id: - description: The entity_id of the device to rename. - example: binary_sensor.front_door_opened - name: - description: The name to change it to. - example: back_door - - delete_wink_device: - description: Remove/unpair device from Wink. - - fields: - entity_id: - description: The entity_id of the device to delete. - - pull_newly_added_devices_from_wink: - description: Pull newly pair devices from Wink. - - refresh_state_from_wink: - description: Pull the latest states for every device. - homeassistant: check_config: description: Check the Home Assistant configuration files for errors. Errors will be displayed in the Home Assistant log. @@ -607,4 +569,4 @@ homeassistant: fields: entity_id: description: The entity_id of the device to turn off - example: light.living_room \ No newline at end of file + example: light.living_room diff --git a/homeassistant/components/switch/services.yaml b/homeassistant/components/switch/services.yaml index 27461927fe8..5fdd8142ffc 100644 --- a/homeassistant/components/switch/services.yaml +++ b/homeassistant/components/switch/services.yaml @@ -35,79 +35,3 @@ mysensors_send_ir_code: V_IR_SEND: description: IR code to send example: '0xC284' - -wink_set_chime_volume: - description: Set the volume of the chime for a Dome siren/chime. - - fields: - entity_id: - description: Name(s) of the entities to set - example: 'switch.dome_siren' - volume: - description: Volume level. One of ["low", "medium", "high"] - example: "low" - - -wink_set_siren_volume: - description: Set the volume of the siren for a Dome siren/chime. - - fields: - entity_id: - description: Name(s) of the entities to set - example: 'switch.dome_siren' - volume: - description: Volume level. One of ["low", "medium", "high"] - example: "high" - -wink_enable_chime: - description: Enable the chime of a Dome siren with the provided sound. - - fields: - entity_id: - description: Name(s) of the entities to set - example: 'switch.dome_siren' - tone: - description: The tone to use for the chime. One of ["doorbell", "fur_elise", "doorbell_extended", "alert", "william_tell", "rondo_alla_turca", "police_siren", "evacuation", "beep_beep", "beep", "inactive"] - example: "doorbell" - -wink_set_siren_tone: - description: Set the sound to use when the siren is enabled. (This doesn't enable the siren) - - fields: - entity_id: - description: Name(s) of the entities to set - example: 'switch.dome_siren' - tone: - description: The tone to use for the chime. One of ["doorbell", "fur_elise", "doorbell_extended", "alert", "william_tell", "rondo_alla_turca", "police_siren", "evacuation", "beep_beep", "beep", "inactive"] - example: "alert" - -wink_siren_set_auto_shutoff: - description: How long to sound the siren before turning off. - - fields: - entity_id: - description: Name(s) of the entities to set - example: 'switch.dome_siren' - auto_shutoff: - description: The time in seconds to sound the siren. One of [None, -1, 30, 60, 120] (None and -1 are forever. Use None for gocontrol, and -1 for Dome) - example: 60 - -wink_set_siren_strobe_enabled: - description: Enable or disable the strobe light when the siren is sounding. - - fields: - entity_id: - description: Name(s) of the entities to set - example: 'switch.dome_siren' - enabled: - description: "True or False" - -wink_set_chime_strobe_enabled: - description: Enable or disable the strobe light when the chime is sounding. - - fields: - entity_id: - description: Name(s) of the entities to set - example: 'switch.dome_siren' - enabled: - description: "True or False" diff --git a/homeassistant/components/switch/wink.py b/homeassistant/components/switch/wink.py index 6aa55b8b975..8bd4c9fa53b 100644 --- a/homeassistant/components/switch/wink.py +++ b/homeassistant/components/switch/wink.py @@ -6,109 +6,19 @@ https://home-assistant.io/components/switch.wink/ """ import asyncio import logging -from os import path - -import voluptuous as vol from homeassistant.components.wink import WinkDevice, DOMAIN from homeassistant.helpers.entity import ToggleEntity -import homeassistant.helpers.config_validation as cv -from homeassistant.const import ATTR_ENTITY_ID -from homeassistant.config import load_yaml_config_file DEPENDENCIES = ['wink'] _LOGGER = logging.getLogger(__name__) -SERVICE_SET_CHIME_VOLUME = "wink_set_chime_volume" -SERVICE_SET_SIREN_VOLUME = "wink_set_siren_volume" -SERVICE_ENABLE_CHIME = "wink_enable_chime" -SERVICE_SET_SIREN_TONE = "wink_set_siren_tone" -SERVICE_SET_SIREN_AUTO_SHUTOFF = "wink_siren_set_auto_shutoff" -SERVICE_SET_SIREN_STROBE_ENABLED = "wink_set_siren_strobe_enabled" -SERVICE_SET_CHIME_STROBE_ENABLED = "wink_set_chime_strobe_enabled" - -ATTR_VOLUME = "volume" -ATTR_TONE = "tone" -ATTR_ENABLED = "enabled" -ATTR_AUTO_SHUTOFF = "auto_shutoff" - -VOLUMES = ["low", "medium", "high"] -TONES = ["doorbell", "fur_elise", "doorbell_extended", "alert", - "william_tell", "rondo_alla_turca", "police_siren", - "evacuation", "beep_beep", "beep"] -CHIME_TONES = TONES + ["inactive"] -AUTO_SHUTOFF_TIMES = [None, -1, 30, 60, 120] - - -SET_VOLUME_SCHEMA = vol.Schema({ - vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, - vol.Required(ATTR_VOLUME): vol.In(VOLUMES) -}) - -SET_SIREN_TONE_SCHEMA = vol.Schema({ - vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, - vol.Required(ATTR_TONE): vol.In(TONES) -}) - -SET_CHIME_MODE_SCHEMA = vol.Schema({ - vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, - vol.Required(ATTR_TONE): vol.In(CHIME_TONES) -}) - -SET_AUTO_SHUTOFF_SCHEMA = vol.Schema({ - vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, - vol.Required(ATTR_AUTO_SHUTOFF): vol.In(AUTO_SHUTOFF_TIMES) -}) - -SET_STROBE_ENABLED_SCHEMA = vol.Schema({ - vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, - vol.Required(ATTR_ENABLED): cv.boolean -}) - def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Wink platform.""" import pywink - def service_handle(service): - """Handler for services.""" - entity_ids = service.data.get('entity_id') - all_sirens = [] - for switch in hass.data[DOMAIN]['entities']['switch']: - if isinstance(switch, WinkSirenDevice): - all_sirens.append(switch) - sirens_to_set = [] - if entity_ids is None: - sirens_to_set = all_sirens - else: - for siren in all_sirens: - if siren.entity_id in entity_ids: - sirens_to_set.append(siren) - - for siren in sirens_to_set: - if service.service != SERVICE_SET_SIREN_AUTO_SHUTOFF: - if siren.wink.device_manufacturer() != 'dome': - _LOGGER.error("Service only valid for Dome sirens.") - return - if service.service == SERVICE_SET_CHIME_VOLUME: - siren.wink.set_chime_volume(service.data.get(ATTR_VOLUME)) - elif service.service == SERVICE_SET_SIREN_VOLUME: - siren.wink.set_siren_volume(service.data.get(ATTR_VOLUME)) - elif service.service == SERVICE_SET_SIREN_TONE: - siren.wink.set_siren_sound(service.data.get(ATTR_TONE)) - elif service.service == SERVICE_ENABLE_CHIME: - siren.wink.set_chime(service.data.get(ATTR_TONE)) - elif service.service == SERVICE_SET_SIREN_STROBE_ENABLED: - siren.wink.set_siren_strobe_enabled( - service.data.get(ATTR_ENABLED)) - elif service.service == SERVICE_SET_CHIME_STROBE_ENABLED: - siren.wink.set_chime_strobe_enabled( - service.data.get(ATTR_ENABLED)) - else: - siren.wink.set_auto_shutoff( - service.data.get(ATTR_AUTO_SHUTOFF)) - for switch in pywink.get_switches(): _id = switch.object_id() + switch.name() if _id not in hass.data[DOMAIN]['unique_ids']: @@ -117,10 +27,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): _id = switch.object_id() + switch.name() if _id not in hass.data[DOMAIN]['unique_ids']: add_devices([WinkToggleDevice(switch, hass)]) - for siren in pywink.get_sirens(): - _id = siren.object_id() + siren.name() - if _id not in hass.data[DOMAIN]['unique_ids']: - add_devices([WinkSirenDevice(siren, hass)]) for sprinkler in pywink.get_sprinklers(): _id = sprinkler.object_id() + sprinkler.name() if _id not in hass.data[DOMAIN]['unique_ids']: @@ -130,44 +36,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): if _id not in hass.data[DOMAIN]['unique_ids']: add_devices([WinkToggleDevice(switch, hass)]) - descriptions = load_yaml_config_file( - path.join(path.dirname(__file__), 'services.yaml')) - - hass.services.register(DOMAIN, SERVICE_SET_SIREN_TONE, - service_handle, - descriptions.get(SERVICE_SET_SIREN_TONE), - schema=SET_SIREN_TONE_SCHEMA) - - hass.services.register(DOMAIN, SERVICE_ENABLE_CHIME, - service_handle, - descriptions.get(SERVICE_ENABLE_CHIME), - schema=SET_CHIME_MODE_SCHEMA) - - hass.services.register(DOMAIN, SERVICE_SET_SIREN_VOLUME, - service_handle, - descriptions.get(SERVICE_SET_SIREN_VOLUME), - schema=SET_VOLUME_SCHEMA) - - hass.services.register(DOMAIN, SERVICE_SET_CHIME_VOLUME, - service_handle, - descriptions.get(SERVICE_SET_CHIME_VOLUME), - schema=SET_VOLUME_SCHEMA) - - hass.services.register(DOMAIN, SERVICE_SET_SIREN_STROBE_ENABLED, - service_handle, - descriptions.get(SERVICE_SET_SIREN_STROBE_ENABLED), - schema=SET_STROBE_ENABLED_SCHEMA) - - hass.services.register(DOMAIN, SERVICE_SET_CHIME_STROBE_ENABLED, - service_handle, - descriptions.get(SERVICE_SET_CHIME_STROBE_ENABLED), - schema=SET_STROBE_ENABLED_SCHEMA) - - hass.services.register(DOMAIN, SERVICE_SET_SIREN_AUTO_SHUTOFF, - service_handle, - descriptions.get(SERVICE_SET_SIREN_AUTO_SHUTOFF), - schema=SET_AUTO_SHUTOFF_SCHEMA) - class WinkToggleDevice(WinkDevice, ToggleEntity): """Representation of a Wink toggle device.""" @@ -201,60 +69,3 @@ class WinkToggleDevice(WinkDevice, ToggleEntity): except AttributeError: pass return attributes - - -class WinkSirenDevice(WinkDevice, ToggleEntity): - """Representation of a Wink siren device.""" - - @asyncio.coroutine - def async_added_to_hass(self): - """Callback when entity is added to hass.""" - self.hass.data[DOMAIN]['entities']['switch'].append(self) - - @property - def is_on(self): - """Return true if device is on.""" - return self.wink.state() - - def turn_on(self, **kwargs): - """Turn the device on.""" - self.wink.set_state(True) - - def turn_off(self): - """Turn the device off.""" - self.wink.set_state(False) - - @property - def device_state_attributes(self): - """Return the state attributes.""" - attributes = super(WinkSirenDevice, self).device_state_attributes - - auto_shutoff = self.wink.auto_shutoff() - if auto_shutoff is not None: - attributes["auto_shutoff"] = auto_shutoff - - siren_volume = self.wink.siren_volume() - if siren_volume is not None: - attributes["siren_volume"] = siren_volume - - chime_volume = self.wink.chime_volume() - if chime_volume is not None: - attributes["chime_volume"] = chime_volume - - strobe_enabled = self.wink.strobe_enabled() - if strobe_enabled is not None: - attributes["siren_strobe_enabled"] = strobe_enabled - - chime_strobe_enabled = self.wink.chime_strobe_enabled() - if chime_strobe_enabled is not None: - attributes["chime_strobe_enabled"] = chime_strobe_enabled - - siren_sound = self.wink.siren_sound() - if siren_sound is not None: - attributes["siren_sound"] = siren_sound - - chime_mode = self.wink.chime_mode() - if chime_mode is not None: - attributes["chime_mode"] = chime_mode - - return attributes diff --git a/homeassistant/components/wink.py b/homeassistant/components/wink/__init__.py similarity index 73% rename from homeassistant/components/wink.py rename to homeassistant/components/wink/__init__.py index 8a0e2e02874..2defe73a6bf 100644 --- a/homeassistant/components/wink.py +++ b/homeassistant/components/wink/__init__.py @@ -4,6 +4,7 @@ Support for Wink hubs. For more details about this component, please refer to the documentation at https://home-assistant.io/components/wink/ """ +import asyncio import logging import time import json @@ -20,8 +21,10 @@ from homeassistant.helpers.event import track_time_interval from homeassistant.const import ( ATTR_BATTERY_LEVEL, CONF_EMAIL, CONF_PASSWORD, EVENT_HOMEASSISTANT_START, - EVENT_HOMEASSISTANT_STOP, __version__, ATTR_ENTITY_ID) + EVENT_HOMEASSISTANT_STOP, __version__, ATTR_ENTITY_ID, + STATE_ON, STATE_OFF) from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity_component import EntityComponent import homeassistant.helpers.config_validation as cv from homeassistant.config import load_yaml_config_file @@ -66,7 +69,26 @@ SERVICE_REFRESH_STATES = 'refresh_state_from_wink' SERVICE_RENAME_DEVICE = 'rename_wink_device' SERVICE_DELETE_DEVICE = 'delete_wink_device' SERVICE_SET_PAIRING_MODE = 'pair_new_device' +SERVICE_SET_CHIME_VOLUME = "set_chime_volume" +SERVICE_SET_SIREN_VOLUME = "set_siren_volume" +SERVICE_ENABLE_CHIME = "enable_chime" +SERVICE_SET_SIREN_TONE = "set_siren_tone" +SERVICE_SET_AUTO_SHUTOFF = "siren_set_auto_shutoff" +SERVICE_SIREN_STROBE_ENABLED = "set_siren_strobe_enabled" +SERVICE_CHIME_STROBE_ENABLED = "set_chime_strobe_enabled" +SERVICE_ENABLE_SIREN = "enable_siren" +ATTR_VOLUME = "volume" +ATTR_TONE = "tone" +ATTR_ENABLED = "enabled" +ATTR_AUTO_SHUTOFF = "auto_shutoff" + +VOLUMES = ["low", "medium", "high"] +TONES = ["doorbell", "fur_elise", "doorbell_extended", "alert", + "william_tell", "rondo_alla_turca", "police_siren", + "evacuation", "beep_beep", "beep"] +CHIME_TONES = TONES + ["inactive"] +AUTO_SHUTOFF_TIMES = [None, -1, 30, 60, 120] CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ @@ -82,7 +104,6 @@ CONFIG_SCHEMA = vol.Schema({ }) }, extra=vol.ALLOW_EXTRA) - RENAME_DEVICE_SCHEMA = vol.Schema({ vol.Required(ATTR_ENTITY_ID): cv.entity_ids, vol.Required(ATTR_NAME): cv.string @@ -98,6 +119,36 @@ SET_PAIRING_MODE_SCHEMA = vol.Schema({ vol.Optional(ATTR_KIDDE_RADIO_CODE): cv.string }, extra=vol.ALLOW_EXTRA) +SET_VOLUME_SCHEMA = vol.Schema({ + vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, + vol.Required(ATTR_VOLUME): vol.In(VOLUMES) +}) + +SET_SIREN_TONE_SCHEMA = vol.Schema({ + vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, + vol.Required(ATTR_TONE): vol.In(TONES) +}) + +SET_CHIME_MODE_SCHEMA = vol.Schema({ + vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, + vol.Required(ATTR_TONE): vol.In(CHIME_TONES) +}) + +SET_AUTO_SHUTOFF_SCHEMA = vol.Schema({ + vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, + vol.Required(ATTR_AUTO_SHUTOFF): vol.In(AUTO_SHUTOFF_TIMES) +}) + +SET_STROBE_ENABLED_SCHEMA = vol.Schema({ + vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, + vol.Required(ATTR_ENABLED): cv.boolean +}) + +ENABLED_SIREN_SCHEMA = vol.Schema({ + vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, + vol.Required(ATTR_ENABLED): cv.boolean +}) + WINK_COMPONENTS = [ 'binary_sensor', 'sensor', 'light', 'switch', 'lock', 'cover', 'climate', 'fan', 'alarm_control_panel', 'scene' @@ -204,7 +255,7 @@ def setup(hass, config): from pubnubsubhandler import PubNubSubscriptionHandler descriptions = load_yaml_config_file( - os.path.join(os.path.dirname(__file__), 'services.yaml')).get(DOMAIN) + os.path.join(os.path.dirname(__file__), 'services.yaml')) if hass.data.get(DOMAIN) is None: hass.data[DOMAIN] = { @@ -434,11 +485,110 @@ def setup(hass, config): descriptions.get(SERVICE_SET_PAIRING_MODE), schema=SET_PAIRING_MODE_SCHEMA) + def service_handle(service): + """Handler for services.""" + entity_ids = service.data.get('entity_id') + all_sirens = [] + for switch in hass.data[DOMAIN]['entities']['switch']: + if isinstance(switch, WinkSirenDevice): + all_sirens.append(switch) + sirens_to_set = [] + if entity_ids is None: + sirens_to_set = all_sirens + else: + for siren in all_sirens: + if siren.entity_id in entity_ids: + sirens_to_set.append(siren) + + for siren in sirens_to_set: + if (service.service != SERVICE_SET_AUTO_SHUTOFF and + service.service != SERVICE_ENABLE_SIREN and + siren.wink.device_manufacturer() != 'dome'): + _LOGGER.error("Service only valid for Dome sirens.") + return + + if service.service == SERVICE_ENABLE_SIREN: + siren.wink.set_state(service.data.get(ATTR_ENABLED)) + elif service.service == SERVICE_SET_AUTO_SHUTOFF: + siren.wink.set_auto_shutoff( + service.data.get(ATTR_AUTO_SHUTOFF)) + elif service.service == SERVICE_SET_CHIME_VOLUME: + siren.wink.set_chime_volume(service.data.get(ATTR_VOLUME)) + elif service.service == SERVICE_SET_SIREN_VOLUME: + siren.wink.set_siren_volume(service.data.get(ATTR_VOLUME)) + elif service.service == SERVICE_SET_SIREN_TONE: + siren.wink.set_siren_sound(service.data.get(ATTR_TONE)) + elif service.service == SERVICE_ENABLE_CHIME: + siren.wink.set_chime(service.data.get(ATTR_TONE)) + elif service.service == SERVICE_SIREN_STROBE_ENABLED: + siren.wink.set_siren_strobe_enabled( + service.data.get(ATTR_ENABLED)) + elif service.service == SERVICE_CHIME_STROBE_ENABLED: + siren.wink.set_chime_strobe_enabled( + service.data.get(ATTR_ENABLED)) + # Load components for the devices in Wink that we support for wink_component in WINK_COMPONENTS: hass.data[DOMAIN]['entities'][wink_component] = [] discovery.load_platform(hass, wink_component, DOMAIN, {}, config) + component = EntityComponent(_LOGGER, DOMAIN, hass) + + sirens = [] + has_dome_siren = False + for siren in pywink.get_sirens(): + if siren.device_manufacturer() == "dome": + has_dome_siren = True + _id = siren.object_id() + siren.name() + if _id not in hass.data[DOMAIN]['unique_ids']: + sirens.append(WinkSirenDevice(siren, hass)) + + if sirens: + + hass.services.register(DOMAIN, SERVICE_SET_AUTO_SHUTOFF, + service_handle, + descriptions.get(SERVICE_SET_AUTO_SHUTOFF), + schema=SET_AUTO_SHUTOFF_SCHEMA) + + hass.services.register(DOMAIN, SERVICE_ENABLE_SIREN, + service_handle, + descriptions.get(SERVICE_ENABLE_SIREN), + schema=ENABLED_SIREN_SCHEMA) + + if has_dome_siren: + + hass.services.register(DOMAIN, SERVICE_SET_SIREN_TONE, + service_handle, + descriptions.get(SERVICE_SET_SIREN_TONE), + schema=SET_SIREN_TONE_SCHEMA) + + hass.services.register(DOMAIN, SERVICE_ENABLE_CHIME, + service_handle, + descriptions.get(SERVICE_ENABLE_CHIME), + schema=SET_CHIME_MODE_SCHEMA) + + hass.services.register(DOMAIN, SERVICE_SET_SIREN_VOLUME, + service_handle, + descriptions.get(SERVICE_SET_SIREN_VOLUME), + schema=SET_VOLUME_SCHEMA) + + hass.services.register(DOMAIN, SERVICE_SET_CHIME_VOLUME, + service_handle, + descriptions.get(SERVICE_SET_CHIME_VOLUME), + schema=SET_VOLUME_SCHEMA) + + hass.services.register(DOMAIN, SERVICE_SIREN_STROBE_ENABLED, + service_handle, + descriptions.get(SERVICE_SIREN_STROBE_ENABLED), + schema=SET_STROBE_ENABLED_SCHEMA) + + hass.services.register(DOMAIN, SERVICE_CHIME_STROBE_ENABLED, + service_handle, + descriptions.get(SERVICE_CHIME_STROBE_ENABLED), + schema=SET_STROBE_ENABLED_SCHEMA) + + component.add_entities(sirens) + return True @@ -594,3 +744,59 @@ class WinkDevice(Entity): if hasattr(self.wink, 'tamper_detected'): return self.wink.tamper_detected() return None + + +class WinkSirenDevice(WinkDevice): + """Representation of a Wink siren device.""" + + @asyncio.coroutine + def async_added_to_hass(self): + """Callback when entity is added to hass.""" + self.hass.data[DOMAIN]['entities']['switch'].append(self) + + @property + def state(self): + """Return sirens state.""" + if self.wink.state(): + return STATE_ON + return STATE_OFF + + @property + def icon(self): + """Return the icon to use in the frontend, if any.""" + return "mdi:bell-ring" + + @property + def device_state_attributes(self): + """Return the state attributes.""" + attributes = super(WinkSirenDevice, self).device_state_attributes + + auto_shutoff = self.wink.auto_shutoff() + if auto_shutoff is not None: + attributes["auto_shutoff"] = auto_shutoff + + siren_volume = self.wink.siren_volume() + if siren_volume is not None: + attributes["siren_volume"] = siren_volume + + chime_volume = self.wink.chime_volume() + if chime_volume is not None: + attributes["chime_volume"] = chime_volume + + strobe_enabled = self.wink.strobe_enabled() + if strobe_enabled is not None: + attributes["siren_strobe_enabled"] = strobe_enabled + + chime_strobe_enabled = self.wink.chime_strobe_enabled() + if chime_strobe_enabled is not None: + attributes["chime_strobe_enabled"] = chime_strobe_enabled + + siren_sound = self.wink.siren_sound() + if siren_sound is not None: + attributes["siren_sound"] = siren_sound + + chime_mode = self.wink.chime_mode() + if chime_mode is not None: + attributes["chime_mode"] = chime_mode + + return attributes diff --git a/homeassistant/components/wink/services.yaml b/homeassistant/components/wink/services.yaml new file mode 100644 index 00000000000..29952af4c81 --- /dev/null +++ b/homeassistant/components/wink/services.yaml @@ -0,0 +1,122 @@ +pair_new_device: + description: Pair a new device to a Wink Hub. + + fields: + hub_name: + description: The name of the hub to pair a new device to. + example: 'My hub' + pairing_mode: + description: One of ["zigbee", "zwave", "zwave_exclusion", "zwave_network_rediscovery", "lutron", "bluetooth", "kidde"] + example: 'zigbee' + kidde_radio_code: + description: 'A string of 8 1s and 0s one for each dip switch on the kidde device left --> right = 1 --> 8' + example: '10101010' + +rename_wink_device: + description: Rename the provided device. + + fields: + entity_id: + description: The entity_id of the device to rename. + example: binary_sensor.front_door_opened + name: + description: The name to change it to. + example: back_door + +delete_wink_device: + description: Remove/unpair device from Wink. + + fields: + entity_id: + description: The entity_id of the device to delete. + +pull_newly_added_devices_from_wink: + description: Pull newly pair devices from Wink. + +refresh_state_from_wink: + description: Pull the latest states for every device. + +set_siren_volume: + description: Set the volume of the siren for a Dome siren/chime. + + fields: + entity_id: + description: Name(s) of the entities to set + example: 'switch.dome_siren' + volume: + description: Volume level. One of ["low", "medium", "high"] + example: "high" + +enable_chime: + description: Enable the chime of a Dome siren with the provided sound. + + fields: + entity_id: + description: Name(s) of the entities to set + example: 'switch.dome_siren' + tone: + description: The tone to use for the chime. One of ["doorbell", "fur_elise", "doorbell_extended", "alert", "william_tell", "rondo_alla_turca", "police_siren", "evacuation", "beep_beep", "beep", "inactive"] + example: "doorbell" + +set_siren_tone: + description: Set the sound to use when the siren is enabled. (This doesn't enable the siren) + + fields: + entity_id: + description: Name(s) of the entities to set + example: 'switch.dome_siren' + tone: + description: The tone to use for the chime. One of ["doorbell", "fur_elise", "doorbell_extended", "alert", "william_tell", "rondo_alla_turca", "police_siren", "evacuation", "beep_beep", "beep", "inactive"] + example: "alert" + +siren_set_auto_shutoff: + description: How long to sound the siren before turning off. + + fields: + entity_id: + description: Name(s) of the entities to set + example: 'switch.dome_siren' + auto_shutoff: + description: The time in seconds to sound the siren. One of [None, -1, 30, 60, 120] (None and -1 are forever. Use None for gocontrol, and -1 for Dome) + example: 60 + +set_siren_strobe_enabled: + description: Enable or disable the strobe light when the siren is sounding. + + fields: + entity_id: + description: Name(s) of the entities to set + example: 'switch.dome_siren' + enabled: + description: "True or False" + +set_chime_strobe_enabled: + description: Enable or disable the strobe light when the chime is sounding. + + fields: + entity_id: + description: Name(s) of the entities to set + example: 'switch.dome_siren' + enabled: + description: "True or False" + +enable_siren: + description: Enable/disable the siren. + + fields: + entity_id: + description: Name(s) of the entities to set + example: 'switch.dome_siren' + enabled: + description: "True or False" + +set_chime_volume: + description: Set the volume of the chime for a Dome siren/chime. + + fields: + entity_id: + description: Name(s) of the entities to set + example: 'switch.dome_siren' + volume: + description: Volume level. One of ["low", "medium", "high"] + example: "low" From f27ad76230ae67e80f95f14edaed8946d0454e68 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Sat, 21 Oct 2017 09:45:05 +0200 Subject: [PATCH 17/17] Remove async_update (#9997) --- homeassistant/components/vacuum/xiaomi_miio.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/vacuum/xiaomi_miio.py b/homeassistant/components/vacuum/xiaomi_miio.py index 5747dd1dc9e..37d7be38f9d 100644 --- a/homeassistant/components/vacuum/xiaomi_miio.py +++ b/homeassistant/components/vacuum/xiaomi_miio.py @@ -363,23 +363,17 @@ class MiroboVacuum(VacuumDevice): self._vacuum.manual_control_once, velocity=velocity, rotation=rotation, duration=duration) - @asyncio.coroutine - def async_update(self): + def update(self): """Fetch state from the device.""" from mirobo import DeviceException try: - state = yield from self.hass.async_add_job(self._vacuum.status) - _LOGGER.debug("Got new state from the vacuum: %s", state.data) + state = self._vacuum.status() self.vacuum_state = state - self.consumable_state = yield from self.hass.async_add_job( - self._vacuum.consumable_status) - self.clean_history = yield from self.hass.async_add_job( - self._vacuum.clean_history) + self.consumable_state = self._vacuum.consumable_status() + self.clean_history = self._vacuum.clean_history() self._is_on = state.is_on self._available = True except OSError as exc: _LOGGER.error("Got OSError while fetching the state: %s", exc) - # self._available = False except DeviceException as exc: _LOGGER.warning("Got exception while fetching the state: %s", exc) - # self._available = False