From a60e8b16c030bcb0c87a3248d6a2f0e2c1e5302e Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 11 Apr 2017 09:14:37 -0700 Subject: [PATCH 1/8] Version bump to 0.42.3 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 85c3ba2260d..e75dd5a2125 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 42 -PATCH_VERSION = '2' +PATCH_VERSION = '3' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 4, 2) From 7a3df037bad6d0e2d447f4b445e57c8f94a92705 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 9 Apr 2017 23:19:22 -0700 Subject: [PATCH 2/8] Fix Synology camera content type (#7010) --- homeassistant/components/camera/synology.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/camera/synology.py b/homeassistant/components/camera/synology.py index e986d81887b..dd6061dcacf 100644 --- a/homeassistant/components/camera/synology.py +++ b/homeassistant/components/camera/synology.py @@ -81,7 +81,9 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): params=query_payload ) - query_resp = yield from query_req.json() + # Skip content type check because Synology doesn't return JSON with + # right content type + query_resp = yield from query_req.json(content_type=None) auth_path = query_resp['data'][AUTH_API]['path'] camera_api = query_resp['data'][CAMERA_API]['path'] camera_path = query_resp['data'][CAMERA_API]['path'] From b295451d46121b60faa7e73cbfe15c11f24116f8 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 10 Apr 2017 01:18:37 -0700 Subject: [PATCH 3/8] Fix two more instances of JSON parsing synology (#7014) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an optional extended description… --- homeassistant/components/camera/synology.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/camera/synology.py b/homeassistant/components/camera/synology.py index dd6061dcacf..378d75ac26d 100644 --- a/homeassistant/components/camera/synology.py +++ b/homeassistant/components/camera/synology.py @@ -129,7 +129,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): _LOGGER.exception("Error on %s", syno_camera_url) return False - camera_resp = yield from camera_req.json() + camera_resp = yield from camera_req.json(content_type=None) cameras = camera_resp['data']['cameras'] # add cameras @@ -174,7 +174,7 @@ def get_session_id(hass, websession, username, password, login_url, timeout): login_url, params=auth_payload ) - auth_resp = yield from auth_req.json() + auth_resp = yield from auth_req.json(content_type=None) return auth_resp['data']['sid'] except (asyncio.TimeoutError, aiohttp.ClientError): From f00d7212936e43472e1c223b6735b9227e3014ac Mon Sep 17 00:00:00 2001 From: Xorso Date: Mon, 10 Apr 2017 08:13:07 -0600 Subject: [PATCH 4/8] Bump pyalarmdotcom to support new version of aiohttp (#7021) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an optional extended description… --- homeassistant/components/alarm_control_panel/alarmdotcom.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/alarm_control_panel/alarmdotcom.py b/homeassistant/components/alarm_control_panel/alarmdotcom.py index 22cbdefd403..6e99ba67257 100644 --- a/homeassistant/components/alarm_control_panel/alarmdotcom.py +++ b/homeassistant/components/alarm_control_panel/alarmdotcom.py @@ -17,7 +17,7 @@ from homeassistant.const import ( import homeassistant.helpers.config_validation as cv from homeassistant.helpers.aiohttp_client import async_get_clientsession -REQUIREMENTS = ['pyalarmdotcom==0.2.9'] +REQUIREMENTS = ['pyalarmdotcom==0.3.0'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 7e800d62548..ee76e53c68e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -475,7 +475,7 @@ pyHS100==0.2.4.2 pyRFXtrx==0.17.0 # homeassistant.components.alarm_control_panel.alarmdotcom -pyalarmdotcom==0.2.9 +pyalarmdotcom==0.3.0 # homeassistant.components.notify.xmpp pyasn1-modules==0.0.8 From e3c2d27f4abdbe7da0214d4b796f57895b11e861 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Mon, 10 Apr 2017 16:13:43 +0200 Subject: [PATCH 5/8] Fix US states check (fixes #7015) (#7017) --- homeassistant/components/binary_sensor/workday.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/binary_sensor/workday.py b/homeassistant/components/binary_sensor/workday.py index c2590925df7..c25ea81922b 100644 --- a/homeassistant/components/binary_sensor/workday.py +++ b/homeassistant/components/binary_sensor/workday.py @@ -66,8 +66,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None): obj_holidays = getattr(holidays, country)(years=year) if province: - if province not in obj_holidays.PROVINCES: - _LOGGER.error('There is no province/state %s in country %s', + if province not in obj_holidays.PROVINCES and \ + province not in obj_holidays.STATES: + _LOGGER.error("There is no province/state %s in country %s", province, country) return False else: From 00131395914ae2b845315824aa97221c0732f9c0 Mon Sep 17 00:00:00 2001 From: Anders Melchiorsen Date: Tue, 11 Apr 2017 17:58:51 +0200 Subject: [PATCH 6/8] Plug file leak on LIFX unregister (#7031) * Plug file leak on LIFX unregister The aiolifx 0.4.4 release closes its socket when the unregister callback is called. This plugs a file descriptor leak but also means that we must be careful to not use the device after it goes unavailable. Also, when a light reappears, it has a new device that must be used. * Do not test self.available in service calls The core will learn to handle that. --- homeassistant/components/light/lifx.py | 3 ++- requirements_all.txt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/light/lifx.py b/homeassistant/components/light/lifx.py index 76a2a9e907d..da09601c1bb 100644 --- a/homeassistant/components/light/lifx.py +++ b/homeassistant/components/light/lifx.py @@ -26,7 +26,7 @@ import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) -REQUIREMENTS = ['aiolifx==0.4.2'] +REQUIREMENTS = ['aiolifx==0.4.4'] UDP_BROADCAST_PORT = 56700 @@ -84,6 +84,7 @@ class LIFXManager(object): entity = self.entities[device.mac_addr] _LOGGER.debug("%s register AGAIN", entity.ipaddr) entity.available = True + entity.device = device self.hass.async_add_job(entity.async_update_ha_state()) else: _LOGGER.debug("%s register NEW", device.ip_addr) diff --git a/requirements_all.txt b/requirements_all.txt index ee76e53c68e..07712308235 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -44,7 +44,7 @@ aiodns==1.1.1 aiohttp_cors==0.5.2 # homeassistant.components.light.lifx -aiolifx==0.4.2 +aiolifx==0.4.4 # homeassistant.components.camera.amcrest # homeassistant.components.sensor.amcrest From 7377ce2640fdd48695296a24ac7a58a09def4bc2 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 11 Apr 2017 18:09:31 +0200 Subject: [PATCH 7/8] Bugfix wait on start event (#7013) * Bugfix wait on start event * Paulus sugestion * Change handling with stop_track_task * Add new unittests * Update test_core.py --- homeassistant/core.py | 12 +++++------- tests/common.py | 3 +-- tests/test_core.py | 17 ++++++++++++++++- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/homeassistant/core.py b/homeassistant/core.py index 899bed064ed..320e857ac9e 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -164,15 +164,16 @@ class HomeAssistant(object): self.bus.async_fire(EVENT_HOMEASSISTANT_START) try: + # only block for EVENT_HOMEASSISTANT_START listener + self.async_stop_track_tasks() with timeout(TIMEOUT_EVENT_START, loop=self.loop): - yield from self.async_stop_track_tasks() + yield from self.async_block_till_done() except asyncio.TimeoutError: _LOGGER.warning( 'Something is blocking Home Assistant from wrapping up the ' 'start up phase. We\'re going to continue anyway. Please ' 'report the following info at http://bit.ly/2ogP58T : %s', ', '.join(self.config.components)) - self._track_task = False self.state = CoreState.running _async_create_timer(self) @@ -218,10 +219,9 @@ class HomeAssistant(object): """Track tasks so you can wait for all tasks to be done.""" self._track_task = True - @asyncio.coroutine + @callback def async_stop_track_tasks(self): - """Track tasks so you can wait for all tasks to be done.""" - yield from self.async_block_till_done() + """Stop track tasks so you can't wait for all tasks to be done.""" self._track_task = False @callback @@ -246,8 +246,6 @@ class HomeAssistant(object): @asyncio.coroutine def async_block_till_done(self): """Block till all pending work is done.""" - assert self._track_task, 'Not tracking tasks' - # To flush out any call_soon_threadsafe yield from asyncio.sleep(0, loop=self.loop) diff --git a/tests/common.py b/tests/common.py index 9dc077dc3f7..03a4de235d7 100644 --- a/tests/common.py +++ b/tests/common.py @@ -122,8 +122,7 @@ def async_test_home_assistant(loop): # 1. We only mock time during tests # 2. We want block_till_done that is called inside stop_track_tasks with patch('homeassistant.core._async_create_timer'), \ - patch.object(hass, 'async_stop_track_tasks', - hass.async_block_till_done): + patch.object(hass, 'async_stop_track_tasks'): yield from orig_start() hass.async_start = mock_async_start diff --git a/tests/test_core.py b/tests/test_core.py index b2fca047292..89ae6c5f651 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -901,7 +901,6 @@ def test_start_taking_too_long(loop, caplog): patch('homeassistant.core._async_create_timer') as mock_timer: yield from hass.async_start() - assert not hass._track_task assert hass.state == ha.CoreState.running assert len(mock_timer.mock_calls) == 1 assert mock_timer.mock_calls[0][1][0] is hass @@ -910,3 +909,19 @@ def test_start_taking_too_long(loop, caplog): finally: yield from hass.async_stop() assert hass.state == ha.CoreState.not_running + + +@asyncio.coroutine +def test_track_task_functions(loop): + """Test function to start/stop track task and initial state.""" + hass = ha.HomeAssistant(loop=loop) + try: + assert hass._track_task + + hass.async_stop_track_tasks() + assert not hass._track_task + + hass.async_track_tasks() + assert hass._track_task + finally: + yield from hass.async_stop() From c91cf66dec9f91f5e1ab5d9fd3b5bf1f929e50b6 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 11 Apr 2017 18:23:41 +0200 Subject: [PATCH 8/8] Bugfix slider (#7047) * Bugfix slider * Update input_slider.py * Update input_slider.py --- homeassistant/components/input_slider.py | 4 ++-- tests/components/test_input_slider.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/input_slider.py b/homeassistant/components/input_slider.py index d10120e673b..c4976bb43e8 100644 --- a/homeassistant/components/input_slider.py +++ b/homeassistant/components/input_slider.py @@ -174,8 +174,8 @@ class InputSlider(Entity): state = yield from async_get_last_state(self.hass, self.entity_id) value = state and float(state.state) - # Check against False because value can be 0 - if value is not False and self._minimum < value < self._maximum: + # Check against None because value can be 0 + if value is not None and self._minimum <= value <= self._maximum: self._current_value = value else: self._current_value = self._minimum diff --git a/tests/components/test_input_slider.py b/tests/components/test_input_slider.py index 7097e87e646..f550091e31f 100644 --- a/tests/components/test_input_slider.py +++ b/tests/components/test_input_slider.py @@ -133,3 +133,21 @@ def test_initial_state_overrules_restore_state(hass): state = hass.states.get('input_slider.b2') assert state assert float(state.state) == 60 + + +@asyncio.coroutine +def test_no_initial_state_and_no_restore_state(hass): + """Ensure that entity is create without initial and restore feature.""" + hass.state = CoreState.starting + + yield from async_setup_component(hass, DOMAIN, { + DOMAIN: { + 'b1': { + 'min': 0, + 'max': 100, + }, + }}) + + state = hass.states.get('input_slider.b1') + assert state + assert float(state.state) == 0