diff --git a/homeassistant/components/camera/arlo.py b/homeassistant/components/camera/arlo.py index 4d461b0e0b5..f3e70c2bdd7 100644 --- a/homeassistant/components/camera/arlo.py +++ b/homeassistant/components/camera/arlo.py @@ -49,8 +49,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ }) -@asyncio.coroutine -def async_setup_platform(hass, config, async_add_devices, discovery_info=None): +def setup_platform(hass, config, add_devices, discovery_info=None): """Set up an Arlo IP Camera.""" arlo = hass.data.get(DATA_ARLO) if not arlo: @@ -60,7 +59,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): for camera in arlo.cameras: cameras.append(ArloCam(hass, camera, config)) - async_add_devices(cameras, True) + add_devices(cameras, True) class ArloCam(Camera): diff --git a/homeassistant/components/camera/synology.py b/homeassistant/components/camera/synology.py index fca9cbbc7a5..8bbb3e8c632 100644 --- a/homeassistant/components/camera/synology.py +++ b/homeassistant/components/camera/synology.py @@ -20,7 +20,7 @@ from homeassistant.helpers.aiohttp_client import ( async_get_clientsession) import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['py-synology==0.1.5'] +REQUIREMENTS = ['py-synology==0.2.0'] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/climate/generic_thermostat.py b/homeassistant/components/climate/generic_thermostat.py index b97dc221298..b5d3c3f7c25 100644 --- a/homeassistant/components/climate/generic_thermostat.py +++ b/homeassistant/components/climate/generic_thermostat.py @@ -229,7 +229,7 @@ class GenericThermostat(ClimateDevice): """List of available operation modes.""" return self._operation_list - def set_operation_mode(self, operation_mode): + async def async_set_operation_mode(self, operation_mode): """Set operation mode.""" if operation_mode == STATE_HEAT: self._current_operation = STATE_HEAT diff --git a/homeassistant/components/device_tracker/tado.py b/homeassistant/components/device_tracker/tado.py index dcf06036ea0..11d12322ff5 100644 --- a/homeassistant/components/device_tracker/tado.py +++ b/homeassistant/components/device_tracker/tado.py @@ -68,22 +68,18 @@ class TadoDeviceScanner(DeviceScanner): self.websession = async_create_clientsession( hass, cookie_jar=aiohttp.CookieJar(unsafe=True, loop=hass.loop)) - self.success_init = self._update_info() + self.success_init = asyncio.run_coroutine_threadsafe( + self._async_update_info(), hass.loop + ).result() + _LOGGER.info("Scanner initialized") - @asyncio.coroutine - def async_scan_devices(self): + async def async_scan_devices(self): """Scan for devices and return a list containing found device ids.""" - info = self._update_info() - - # Don't yield if we got None - if info is not None: - yield from info - + await self._async_update_info() return [device.mac for device in self.last_results] - @asyncio.coroutine - def async_get_device_name(self, device): + async def async_get_device_name(self, device): """Return the name of the given device or None if we don't know.""" filter_named = [result.name for result in self.last_results if result.mac == device] @@ -93,7 +89,7 @@ class TadoDeviceScanner(DeviceScanner): return None @Throttle(MIN_TIME_BETWEEN_SCANS) - def _update_info(self): + async def _async_update_info(self): """ Query Tado for device marked as at home. @@ -111,14 +107,14 @@ class TadoDeviceScanner(DeviceScanner): home_id=self.home_id, username=self.username, password=self.password) - response = yield from self.websession.get(url) + response = await self.websession.get(url) if response.status != 200: _LOGGER.warning( "Error %d on %s.", response.status, self.tadoapiurl) - return + return False - tado_json = yield from response.json() + tado_json = await response.json() except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.error("Cannot load Tado data") @@ -139,7 +135,7 @@ class TadoDeviceScanner(DeviceScanner): self.last_results = last_results - _LOGGER.info( + _LOGGER.debug( "Tado presence query successful, %d device(s) at home", len(self.last_results) ) diff --git a/homeassistant/components/knx.py b/homeassistant/components/knx.py index f6f41619ca8..61f8ca90137 100644 --- a/homeassistant/components/knx.py +++ b/homeassistant/components/knx.py @@ -17,7 +17,7 @@ import homeassistant.helpers.config_validation as cv from homeassistant.helpers.event import async_track_state_change from homeassistant.helpers.script import Script -REQUIREMENTS = ['xknx==0.8.4'] +REQUIREMENTS = ['xknx==0.8.5'] DOMAIN = "knx" DATA_KNX = "data_knx" @@ -241,7 +241,7 @@ class KNXModule(object): async def telegram_received_cb(self, telegram): """Call invoked after a KNX telegram was received.""" self.hass.bus.fire('knx_event', { - 'address': telegram.group_address.str(), + 'address': str(telegram.group_address), 'data': telegram.payload.value }) # False signals XKNX to proceed with processing telegrams. diff --git a/homeassistant/components/light/hue.py b/homeassistant/components/light/hue.py index bee6840f346..75825683928 100644 --- a/homeassistant/components/light/hue.py +++ b/homeassistant/components/light/hue.py @@ -261,10 +261,13 @@ class HueLight(Light): """Return true if device is on.""" if self.is_group: return self.info['state']['any_on'] - elif self.allow_unreachable: - return self.info['state']['on'] - return self.info['state']['reachable'] and \ - self.info['state']['on'] + return self.info['state']['on'] + + @property + def available(self): + """Return if light is available.""" + return (self.is_group or self.allow_unreachable or + self.info['state']['reachable']) @property def supported_features(self): diff --git a/homeassistant/components/light/iglo.py b/homeassistant/components/light/iglo.py index 1e110b5c397..9717993f77d 100644 --- a/homeassistant/components/light/iglo.py +++ b/homeassistant/components/light/iglo.py @@ -17,7 +17,7 @@ from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT import homeassistant.helpers.config_validation as cv import homeassistant.util.color as color_util -REQUIREMENTS = ['iglo==1.2.6'] +REQUIREMENTS = ['iglo==1.2.7'] _LOGGER = logging.getLogger(__name__) @@ -89,7 +89,7 @@ class IGloLamp(Light): @property def effect_list(self): """Return the list of supported effects.""" - return self._lamp.effect_list + return self._lamp.effect_list() @property def supported_features(self): diff --git a/homeassistant/components/media_player/cast.py b/homeassistant/components/media_player/cast.py index dbcb53ec185..579f9b62864 100644 --- a/homeassistant/components/media_player/cast.py +++ b/homeassistant/components/media_player/cast.py @@ -7,7 +7,6 @@ https://home-assistant.io/components/media_player.cast/ # pylint: disable=import-error import logging import threading -import functools import voluptuous as vol @@ -35,7 +34,6 @@ CONF_IGNORE_CEC = 'ignore_cec' CAST_SPLASH = 'https://home-assistant.io/images/cast/splash.png' DEFAULT_PORT = 8009 -SOCKET_CLIENT_RETRIES = 10 SUPPORT_CAST = SUPPORT_PAUSE | SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE | \ SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_PREVIOUS_TRACK | \ @@ -78,7 +76,7 @@ def _setup_internal_discovery(hass: HomeAssistantType) -> None: try: # pylint: disable=protected-access chromecast = pychromecast._get_chromecast_from_host( - mdns, blocking=True, tries=SOCKET_CLIENT_RETRIES) + mdns, blocking=True) except pychromecast.ChromecastConnectionError: _LOGGER.debug("Can't set up cast with mDNS info %s. " "Assuming it's not a Chromecast", mdns) @@ -183,9 +181,8 @@ async def async_setup_platform(hass: HomeAssistantType, config: ConfigType, else: # Manually add a "normal" Chromecast, we can do that without discovery. try: - func = functools.partial(pychromecast.Chromecast, *want_host, - tries=SOCKET_CLIENT_RETRIES) - chromecast = await hass.async_add_job(func) + chromecast = await hass.async_add_job( + pychromecast.Chromecast, *want_host) except pychromecast.ChromecastConnectionError as err: _LOGGER.warning("Can't set up chromecast on %s: %s", want_host[0], err) diff --git a/homeassistant/components/media_player/kodi.py b/homeassistant/components/media_player/kodi.py index d14bf0fadaf..6450b2f5b35 100644 --- a/homeassistant/components/media_player/kodi.py +++ b/homeassistant/components/media_player/kodi.py @@ -31,7 +31,7 @@ from homeassistant.helpers import script, config_validation as cv from homeassistant.helpers.template import Template from homeassistant.util.yaml import dump -REQUIREMENTS = ['jsonrpc-async==0.6', 'jsonrpc-websocket==0.5'] +REQUIREMENTS = ['jsonrpc-async==0.6', 'jsonrpc-websocket==0.6'] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/sensor/sql.py b/homeassistant/components/sensor/sql.py index 402076c6fd8..5d5d61ff822 100644 --- a/homeassistant/components/sensor/sql.py +++ b/homeassistant/components/sensor/sql.py @@ -144,7 +144,7 @@ class SQLSensor(Entity): data = res[self._column_name] for key, value in res.items(): if isinstance(value, decimal.Decimal): - value = float(decimal) + value = float(value) self._attributes[key] = value except sqlalchemy.exc.SQLAlchemyError as err: _LOGGER.error("Error executing query %s: %s", self._query, err) diff --git a/homeassistant/components/vera.py b/homeassistant/components/vera.py index a7c10462e0d..5cc4de0d5ca 100644 --- a/homeassistant/components/vera.py +++ b/homeassistant/components/vera.py @@ -19,7 +19,7 @@ from homeassistant.const import ( EVENT_HOMEASSISTANT_STOP, CONF_LIGHTS, CONF_EXCLUDE) from homeassistant.helpers.entity import Entity -REQUIREMENTS = ['pyvera==0.2.41'] +REQUIREMENTS = ['pyvera==0.2.42'] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/const.py b/homeassistant/const.py index 2fee845f70a..203a9c63d95 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 65 -PATCH_VERSION = '2' +PATCH_VERSION = '3' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 5, 3) diff --git a/requirements_all.txt b/requirements_all.txt index 03560ac79b0..cc4e7dbd708 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -398,7 +398,7 @@ https://github.com/wokar/pylgnetcast/archive/v0.2.0.zip#pylgnetcast==0.2.0 # i2csense==0.0.4 # homeassistant.components.light.iglo -iglo==1.2.6 +iglo==1.2.7 # homeassistant.components.ihc ihcsdk==2.2.0 @@ -421,7 +421,7 @@ jsonpath==0.75 jsonrpc-async==0.6 # homeassistant.components.media_player.kodi -jsonrpc-websocket==0.5 +jsonrpc-websocket==0.6 # homeassistant.scripts.keyring keyring==11.0.0 @@ -632,7 +632,7 @@ py-cpuinfo==3.3.0 py-melissa-climate==1.0.6 # homeassistant.components.camera.synology -py-synology==0.1.5 +py-synology==0.2.0 # homeassistant.components.hdmi_cec pyCEC==0.4.13 @@ -1021,7 +1021,7 @@ pyunifi==2.13 # pyuserinput==0.1.11 # homeassistant.components.vera -pyvera==0.2.41 +pyvera==0.2.42 # homeassistant.components.media_player.vizio pyvizio==0.0.2 @@ -1274,7 +1274,7 @@ xbee-helper==0.0.7 xboxapi==0.1.1 # homeassistant.components.knx -xknx==0.8.4 +xknx==0.8.5 # homeassistant.components.media_player.bluesound # homeassistant.components.sensor.startca diff --git a/tests/components/cover/test_template.py b/tests/components/cover/test_template.py index 3d7aa3ce618..b786b463dad 100644 --- a/tests/components/cover/test_template.py +++ b/tests/components/cover/test_template.py @@ -135,7 +135,7 @@ class TestTemplateCover(unittest.TestCase): entity = self.hass.states.get('cover.test') attrs = dict() attrs['position'] = 42 - self.hass.states.async_set( + self.hass.states.set( entity.entity_id, entity.state, attributes=attrs) self.hass.block_till_done() @@ -148,7 +148,7 @@ class TestTemplateCover(unittest.TestCase): self.hass.block_till_done() entity = self.hass.states.get('cover.test') attrs['position'] = 0.0 - self.hass.states.async_set( + self.hass.states.set( entity.entity_id, entity.state, attributes=attrs) self.hass.block_till_done() diff --git a/tests/components/light/test_hue.py b/tests/components/light/test_hue.py index 5c28ea9988f..559467d5e9a 100644 --- a/tests/components/light/test_hue.py +++ b/tests/components/light/test_hue.py @@ -501,3 +501,45 @@ class TestHueLight(unittest.TestCase): light = self.buildLight(info={}, is_group=True) self.assertIsNone(light.unique_id) + + +def test_available(): + """Test available property.""" + light = hue_light.HueLight( + info={'state': {'reachable': False}}, + allow_unreachable=False, + is_group=False, + + light_id=None, + bridge=mock.Mock(), + update_lights_cb=None, + allow_in_emulated_hue=False, + ) + + assert light.available is False + + light = hue_light.HueLight( + info={'state': {'reachable': False}}, + allow_unreachable=True, + is_group=False, + + light_id=None, + bridge=mock.Mock(), + update_lights_cb=None, + allow_in_emulated_hue=False, + ) + + assert light.available is True + + light = hue_light.HueLight( + info={'state': {'reachable': False}}, + allow_unreachable=False, + is_group=True, + + light_id=None, + bridge=mock.Mock(), + update_lights_cb=None, + allow_in_emulated_hue=False, + ) + + assert light.available is True diff --git a/tests/components/media_player/test_cast.py b/tests/components/media_player/test_cast.py index aaaad47d8dc..2075b4cf6e6 100644 --- a/tests/components/media_player/test_cast.py +++ b/tests/components/media_player/test_cast.py @@ -123,7 +123,7 @@ def test_internal_discovery_callback_only_generates_once(hass): return_value=chromecast) as gen_chromecast: discover_cast('the-service', chromecast) mdns = (chromecast.host, chromecast.port, chromecast.uuid, None, None) - gen_chromecast.assert_called_once_with(mdns, blocking=True, tries=10) + gen_chromecast.assert_called_once_with(mdns, blocking=True) discover_cast('the-service', chromecast) gen_chromecast.reset_mock() diff --git a/tests/components/zwave/test_init.py b/tests/components/zwave/test_init.py index 828385b9ded..527101f6c61 100644 --- a/tests/components/zwave/test_init.py +++ b/tests/components/zwave/test_init.py @@ -309,7 +309,7 @@ def test_value_discovery_existing_entity(hass, mock_openzwave): 'current_temperature'] is None def mock_update(self): - self.hass.async_add_job(self.async_update_ha_state) + self.hass.add_job(self.async_update_ha_state) with patch.object(zwave.node_entity.ZWaveBaseEntity, 'maybe_schedule_update', new=mock_update): @@ -356,7 +356,7 @@ def test_power_schemes(hass, mock_openzwave): 'switch.mock_node_mock_value').attributes def mock_update(self): - self.hass.async_add_job(self.async_update_ha_state) + self.hass.add_job(self.async_update_ha_state) with patch.object(zwave.node_entity.ZWaveBaseEntity, 'maybe_schedule_update', new=mock_update):