Compare commits

..

16 Commits
0.42 ... 0.42.3

Author SHA1 Message Date
Paulus Schoutsen
bf6c4604f4 Merge pull request #7050 from home-assistant/release-0-42-3
0.42.3
2017-04-11 09:30:04 -07:00
Pascal Vizeli
c91cf66dec Bugfix slider (#7047)
* Bugfix slider

* Update input_slider.py

* Update input_slider.py
2017-04-11 09:24:25 -07:00
Pascal Vizeli
7377ce2640 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
2017-04-11 09:15:31 -07:00
Anders Melchiorsen
0013139591 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.
2017-04-11 09:15:30 -07:00
Fabian Affolter
e3c2d27f4a Fix US states check (fixes #7015) (#7017) 2017-04-11 09:15:30 -07:00
Xorso
f00d721293 Bump pyalarmdotcom to support new version of aiohttp (#7021)
Add an optional extended description…
2017-04-11 09:15:30 -07:00
Paulus Schoutsen
b295451d46 Fix two more instances of JSON parsing synology (#7014)
Add an optional extended description…
2017-04-11 09:15:30 -07:00
Paulus Schoutsen
7a3df037ba Fix Synology camera content type (#7010) 2017-04-11 09:15:30 -07:00
Paulus Schoutsen
a60e8b16c0 Version bump to 0.42.3 2017-04-11 09:14:37 -07:00
Paulus Schoutsen
6cc5bb0713 Merge pull request #6995 from home-assistant/release-0-42-2
0.42.2
2017-04-09 01:37:18 -07:00
Paulus Schoutsen
f6e819e799 Downgrade aiohttp to 205 (#6994) 2017-04-09 01:36:36 -07:00
Paulus Schoutsen
a6dc86fa75 version bump to 0.42.2 2017-04-09 01:31:46 -07:00
Paulus Schoutsen
9c386c68dd Merge pull request #6993 from home-assistant/release-0-42-1
0.42.1
2017-04-09 01:06:10 -07:00
Paulus Schoutsen
f51d705ac7 Make discovery not block start (#6991)
* Make discovery not block start

* Fix tests
2017-04-09 01:06:16 -07:00
Paulus Schoutsen
62d0df4f73 Upgrade to aiohttp 2.0.6 (#6992) 2017-04-08 18:30:02 -07:00
Paulus Schoutsen
d675804119 Version bump to 0.42.1 2017-04-08 18:29:39 -07:00
13 changed files with 91 additions and 76 deletions

View File

@@ -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__)

View File

@@ -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:

View File

@@ -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']
@@ -127,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
@@ -172,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):

View File

@@ -13,6 +13,7 @@ import logging
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.const import EVENT_HOMEASSISTANT_START
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.event import async_track_point_in_utc_time
@@ -105,7 +106,7 @@ def async_setup(hass, config):
hass, component, platform, info, config)
@asyncio.coroutine
def scan_devices(_):
def scan_devices(now):
"""Scan for devices."""
results = yield from hass.loop.run_in_executor(
None, _discover, netdisco)
@@ -116,7 +117,12 @@ def async_setup(hass, config):
async_track_point_in_utc_time(hass, scan_devices,
dt_util.utcnow() + SCAN_INTERVAL)
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, scan_devices)
@callback
def schedule_first(event):
"""Schedule the first discovery when Home Assistant starts up."""
async_track_point_in_utc_time(hass, scan_devices, dt_util.utcnow())
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, schedule_first)
return True

View File

@@ -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

View File

@@ -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)

View File

@@ -2,7 +2,7 @@
"""Constants used by Home Assistant components."""
MAJOR_VERSION = 0
MINOR_VERSION = 42
PATCH_VERSION = '0'
PATCH_VERSION = '3'
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
REQUIRED_PYTHON_VER = (3, 4, 2)

View File

@@ -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)

View File

@@ -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
@@ -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

View File

@@ -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

View File

@@ -5,9 +5,9 @@ from unittest.mock import patch
from homeassistant.bootstrap import async_setup_component
from homeassistant.components import discovery
from homeassistant.const import EVENT_HOMEASSISTANT_START
from homeassistant.util.dt import utcnow
from tests.common import mock_coro
from tests.common import mock_coro, fire_time_changed
# One might consider to "mock" services, but it's easy enough to just use
# what is already available.
@@ -34,24 +34,34 @@ IGNORE_CONFIG = {
@asyncio.coroutine
def test_unknown_service(hass):
"""Test that unknown service is ignored."""
result = yield from async_setup_component(hass, 'discovery', {
'discovery': {},
})
def mock_discovery(hass, discoveries, config=BASE_CONFIG):
"""Helper to mock discoveries."""
result = yield from async_setup_component(hass, 'discovery', config)
assert result
def discover(netdisco):
"""Fake discovery."""
return [('this_service_will_never_be_supported', {'info': 'some'})]
yield from hass.async_start()
with patch.object(discovery, '_discover', discover), \
with patch.object(discovery, '_discover', discoveries), \
patch('homeassistant.components.discovery.async_discover',
return_value=mock_coro()) as mock_discover, \
patch('homeassistant.components.discovery.async_load_platform',
return_value=mock_coro()) as mock_platform:
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
fire_time_changed(hass, utcnow())
# Work around an issue where our loop.call_soon not get caught
yield from hass.async_block_till_done()
yield from hass.async_block_till_done()
return mock_discover, mock_platform
@asyncio.coroutine
def test_unknown_service(hass):
"""Test that unknown service is ignored."""
def discover(netdisco):
"""Fake discovery."""
return [('this_service_will_never_be_supported', {'info': 'some'})]
mock_discover, mock_platform = yield from mock_discovery(hass, discover)
assert not mock_discover.called
assert not mock_platform.called
@@ -60,20 +70,11 @@ def test_unknown_service(hass):
@asyncio.coroutine
def test_load_platform(hass):
"""Test load a platform."""
result = yield from async_setup_component(hass, 'discovery', BASE_CONFIG)
assert result
def discover(netdisco):
"""Fake discovery."""
return [(SERVICE, SERVICE_INFO)]
with patch.object(discovery, '_discover', discover), \
patch('homeassistant.components.discovery.async_discover',
return_value=mock_coro()) as mock_discover, \
patch('homeassistant.components.discovery.async_load_platform',
return_value=mock_coro()) as mock_platform:
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
yield from hass.async_block_till_done()
mock_discover, mock_platform = yield from mock_discovery(hass, discover)
assert not mock_discover.called
assert mock_platform.called
@@ -84,20 +85,11 @@ def test_load_platform(hass):
@asyncio.coroutine
def test_load_component(hass):
"""Test load a component."""
result = yield from async_setup_component(hass, 'discovery', BASE_CONFIG)
assert result
def discover(netdisco):
"""Fake discovery."""
return [(SERVICE_NO_PLATFORM, SERVICE_INFO)]
with patch.object(discovery, '_discover', discover), \
patch('homeassistant.components.discovery.async_discover',
return_value=mock_coro()) as mock_discover, \
patch('homeassistant.components.discovery.async_load_platform',
return_value=mock_coro()) as mock_platform:
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
yield from hass.async_block_till_done()
mock_discover, mock_platform = yield from mock_discovery(hass, discover)
assert mock_discover.called
assert not mock_platform.called
@@ -109,20 +101,12 @@ def test_load_component(hass):
@asyncio.coroutine
def test_ignore_service(hass):
"""Test ignore service."""
result = yield from async_setup_component(hass, 'discovery', IGNORE_CONFIG)
assert result
def discover(netdisco):
"""Fake discovery."""
return [(SERVICE_NO_PLATFORM, SERVICE_INFO)]
with patch.object(discovery, '_discover', discover), \
patch('homeassistant.components.discovery.async_discover',
return_value=mock_coro()) as mock_discover, \
patch('homeassistant.components.discovery.async_load_platform',
return_value=mock_coro()) as mock_platform:
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
yield from hass.async_block_till_done()
mock_discover, mock_platform = yield from mock_discovery(hass, discover,
IGNORE_CONFIG)
assert not mock_discover.called
assert not mock_platform.called
@@ -131,21 +115,12 @@ def test_ignore_service(hass):
@asyncio.coroutine
def test_discover_duplicates(hass):
"""Test load a component."""
result = yield from async_setup_component(hass, 'discovery', BASE_CONFIG)
assert result
def discover(netdisco):
"""Fake discovery."""
return [(SERVICE_NO_PLATFORM, SERVICE_INFO),
(SERVICE_NO_PLATFORM, SERVICE_INFO)]
with patch.object(discovery, '_discover', discover), \
patch('homeassistant.components.discovery.async_discover',
return_value=mock_coro()) as mock_discover, \
patch('homeassistant.components.discovery.async_load_platform',
return_value=mock_coro()) as mock_platform:
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
yield from hass.async_block_till_done()
mock_discover, mock_platform = yield from mock_discovery(hass, discover)
assert mock_discover.called
assert mock_discover.call_count == 1

View File

@@ -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

View File

@@ -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()