Compare commits

...

25 Commits

Author SHA1 Message Date
Paulus Schoutsen
8d52eba484 Merge pull request #13223 from home-assistant/release-0-65-5
0.65.5
2018-03-14 15:55:50 -07:00
Paulus Schoutsen
8e05a5c12b Version bump to 0.65.6 2018-03-14 15:08:34 -07:00
Paulus Schoutsen
25fe6ec536 Fix input_boolean Google Assistant serialize error (#13220) 2018-03-14 15:08:23 -07:00
Anders Melchiorsen
30a1fedce8 Avoid Sonos error when joining with self (#13196) 2018-03-14 15:08:23 -07:00
Anders Melchiorsen
4e569ac0c3 Ignore unsupported Sonos favorites (#13195) 2018-03-14 15:08:22 -07:00
Alok Saboo
8a6370f7c9 Revert throttle Arlo api calls (#13174) 2018-03-14 15:08:21 -07:00
cdce8p
874cccd530 Bugfix HomeKit: Error string values for temperature (#13162) 2018-03-14 15:08:21 -07:00
Paulus Schoutsen
1bea8747ac Merge pull request #13149 from home-assistant/release-0-65-4
0.65.4
2018-03-12 14:52:01 -07:00
Alok Saboo
e54394e906 Throttle Arlo api calls (#13143) 2018-03-12 14:14:43 -07:00
Jeroen ter Heerdt
c384fd9653 Adding check for empty discovery info in alarm control panel Egardia. (#13114) 2018-03-12 14:14:42 -07:00
Paulus Schoutsen
3560fa754c Catch if bridge goes unavailable (#13109) 2018-03-12 14:14:42 -07:00
Paulus Schoutsen
101a6ab07c Fix unavailable property for wemo switch (#13106)
* Fix unavailable property for wemo switch

* Have subscriptions respect the lock

* Move subscription callback to added to hass section
2018-03-12 14:14:42 -07:00
Paulus Schoutsen
eb1ca20cfc Version bump to 0.65.4 2018-03-12 14:14:36 -07:00
Paulus Schoutsen
49d51e5040 Merge pull request #13098 from home-assistant/release-0-65-3
0.65.3
2018-03-11 13:14:18 -07:00
tadly
31130f902b Updated jsonrpc-websocket to 0.6 (#13096)
Fix Kodi by updating jsonrpc-websocket to 0.6
2018-03-11 12:52:02 -07:00
Greg Dowling
8603f1a047 Bump pyvera to 0.2.42. Improve event loop robustness. (#13095) 2018-03-11 12:52:01 -07:00
Otto Winter
a34786fb2d Revert "Cast automatically drop connection (#12635)" (#13094)
This reverts commit e14893416f.
2018-03-11 12:52:00 -07:00
Joe Lu
8e51c12010 Integrated with py-synology:0.2.0 which has fix to auto-renew session when it's expired (#13079) 2018-03-11 12:52:00 -07:00
Paulus Schoutsen
e3d176f479 Fix Tado doing async wrong (#13078)
* Fix Tado doing async wrong

* Remove last coroutine decorator
2018-03-11 12:51:59 -07:00
Diogo Gomes
e37619acc1 Convert decimals from SQL results 2018-03-11 12:51:59 -07:00
Jesse Hills
85fa88c8b3 - Bump iGlo Version (#13063)
- Use effect list as a method
2018-03-11 12:51:58 -07:00
Julius Mittenzwei
7935c2504e Fixes KNX fire event problem, issue https://github.com/home-assistant/home-assistant/issues/13049 (#13062) 2018-03-11 12:51:58 -07:00
Paulus Schoutsen
7018806802 Run asyncio event loop in debug mode during tests (#13058)
* Run asyncio event loop in debug mode during tests

* Remove debug mode again
2018-03-11 12:51:57 -07:00
Paulus Schoutsen
a7f34bbce9 Implement Hue available property (#12939) 2018-03-11 12:51:57 -07:00
Paulus Schoutsen
e6683b4c84 Bump version to 0.65.3 2018-03-11 12:51:40 -07:00
24 changed files with 203 additions and 88 deletions

View File

@@ -33,6 +33,8 @@ STATES = {
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Egardia platform."""
if discovery_info is None:
return
device = EgardiaAlarm(
discovery_info['name'],
hass.data[EGARDIA_DEVICE],

View File

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

View File

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

View File

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

View File

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

View File

@@ -17,7 +17,16 @@ from homeassistant.core import callback
from homeassistant.const import (
CONF_NAME, STATE_UNAVAILABLE, ATTR_SUPPORTED_FEATURES)
from homeassistant.components import (
switch, light, cover, media_player, group, fan, scene, script, climate,
climate,
cover,
fan,
group,
input_boolean,
light,
media_player,
scene,
script,
switch,
)
from . import trait
@@ -33,15 +42,16 @@ HANDLERS = Registry()
_LOGGER = logging.getLogger(__name__)
DOMAIN_TO_GOOGLE_TYPES = {
climate.DOMAIN: TYPE_THERMOSTAT,
cover.DOMAIN: TYPE_SWITCH,
fan.DOMAIN: TYPE_SWITCH,
group.DOMAIN: TYPE_SWITCH,
input_boolean.DOMAIN: TYPE_SWITCH,
light.DOMAIN: TYPE_LIGHT,
media_player.DOMAIN: TYPE_SWITCH,
scene.DOMAIN: TYPE_SCENE,
script.DOMAIN: TYPE_SCENE,
switch.DOMAIN: TYPE_SWITCH,
fan.DOMAIN: TYPE_SWITCH,
light.DOMAIN: TYPE_LIGHT,
cover.DOMAIN: TYPE_SWITCH,
media_player.DOMAIN: TYPE_SWITCH,
climate.DOMAIN: TYPE_THERMOSTAT,
}

View File

@@ -157,12 +157,12 @@ class Thermostat(HomeAccessory):
# Update current temperature
current_temp = new_state.attributes.get(ATTR_CURRENT_TEMPERATURE)
if current_temp is not None:
if isinstance(current_temp, (int, float)):
self.char_current_temp.set_value(current_temp)
# Update target temperature
target_temp = new_state.attributes.get(ATTR_TEMPERATURE)
if target_temp is not None:
if isinstance(target_temp, (int, float)):
if not self.temperature_flag_target_state:
self.char_target_temp.set_value(target_temp,
should_callback=False)

View File

@@ -181,6 +181,7 @@ class HueBridge(object):
self.allow_in_emulated_hue = allow_in_emulated_hue
self.allow_hue_groups = allow_hue_groups
self.available = True
self.bridge = None
self.lights = {}
self.lightgroups = {}

View File

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

View File

@@ -123,15 +123,20 @@ def unthrottled_update_lights(hass, bridge, add_devices):
api = bridge.get_api()
except phue.PhueRequestTimeout:
_LOGGER.warning("Timeout trying to reach the bridge")
bridge.available = False
return
except ConnectionRefusedError:
_LOGGER.error("The bridge refused the connection")
bridge.available = False
return
except socket.error:
# socket.error when we cannot reach Hue
_LOGGER.exception("Cannot reach the bridge")
bridge.available = False
return
bridge.available = True
new_lights = process_lights(
hass, api, bridge,
lambda **kw: update_lights(hass, bridge, add_devices, **kw))
@@ -261,10 +266,14 @@ 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.bridge.available and (self.is_group or
self.allow_unreachable or
self.info['state']['reachable'])
@property
def supported_features(self):

View File

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

View File

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

View File

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

View File

@@ -426,7 +426,17 @@ class SonosDevice(MediaPlayerDevice):
self._play_mode = self.soco.play_mode
self._night_sound = self.soco.night_mode
self._speech_enhance = self.soco.dialog_mode
self._favorites = self.soco.music_library.get_sonos_favorites()
self._favorites = []
for fav in self.soco.music_library.get_sonos_favorites():
# SoCo 0.14 raises a generic Exception on invalid xml in favorites.
# Filter those out now so our list is safe to use.
try:
if fav.reference.get_uri():
self._favorites.append(fav)
# pylint: disable=broad-except
except Exception:
_LOGGER.debug("Ignoring invalid favorite '%s'", fav.title)
def _subscribe_to_player_events(self):
"""Add event subscriptions."""
@@ -886,7 +896,8 @@ class SonosDevice(MediaPlayerDevice):
self.soco.unjoin()
for slave in slaves:
slave.soco.join(self.soco)
if slave.unique_id != self.unique_id:
slave.soco.join(self.soco)
@soco_error()
def unjoin(self):

View File

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

View File

@@ -4,16 +4,19 @@ Support for WeMo switches.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/switch.wemo/
"""
import asyncio
import logging
from datetime import datetime, timedelta
import async_timeout
from homeassistant.components.switch import SwitchDevice
from homeassistant.util import convert
from homeassistant.const import (
STATE_OFF, STATE_ON, STATE_STANDBY, STATE_UNKNOWN)
from homeassistant.loader import get_component
DEPENDENCIES = ['wemo']
SCAN_INTERVAL = timedelta(seconds=10)
_LOGGER = logging.getLogger(__name__)
@@ -54,29 +57,35 @@ class WemoSwitch(SwitchDevice):
self.maker_params = None
self.coffeemaker_mode = None
self._state = None
self._available = True
self._update_lock = None
# look up model name once as it incurs network traffic
self._model_name = self.wemo.model_name
wemo = get_component('wemo')
wemo.SUBSCRIPTION_REGISTRY.register(self.wemo)
wemo.SUBSCRIPTION_REGISTRY.on(self.wemo, None, self._update_callback)
def _update_callback(self, _device, _type, _params):
def _subscription_callback(self, _device, _type, _params):
"""Update the state by the Wemo device."""
_LOGGER.info("Subscription update for %s", _device)
_LOGGER.info("Subscription update for %s", self.name)
updated = self.wemo.subscription_update(_type, _params)
self._update(force_update=(not updated))
self.hass.add_job(
self._async_locked_subscription_callback(not updated))
if not hasattr(self, 'hass'):
async def _async_locked_subscription_callback(self, force_update):
"""Helper to handle an update from a subscription."""
# If an update is in progress, we don't do anything
if self._update_lock.locked():
return
self.schedule_update_ha_state()
await self._async_locked_update(force_update)
self.async_schedule_update_ha_state()
@property
def should_poll(self):
"""No polling needed with subscriptions."""
if self._model_name == 'Insight':
return True
return False
"""Device should poll.
Subscriptions push the state, however it won't detect if a device
is no longer available. Use polling to detect if a device is available.
"""
return True
@property
def unique_id(self):
@@ -172,13 +181,7 @@ class WemoSwitch(SwitchDevice):
@property
def available(self):
"""Return true if switch is available."""
if self._model_name == 'Insight' and self.insight_params is None:
return False
if self._model_name == 'Maker' and self.maker_params is None:
return False
if self._model_name == 'CoffeeMaker' and self.coffeemaker_mode is None:
return False
return True
return self._available
@property
def icon(self):
@@ -189,21 +192,46 @@ class WemoSwitch(SwitchDevice):
def turn_on(self, **kwargs):
"""Turn the switch on."""
self._state = WEMO_ON
self.wemo.on()
self.schedule_update_ha_state()
def turn_off(self, **kwargs):
"""Turn the switch off."""
self._state = WEMO_OFF
self.wemo.off()
self.schedule_update_ha_state()
def update(self):
"""Update WeMo state."""
self._update(force_update=True)
async def async_added_to_hass(self):
"""Wemo switch added to HASS."""
# Define inside async context so we know our event loop
self._update_lock = asyncio.Lock()
def _update(self, force_update=True):
registry = self.hass.components.wemo.SUBSCRIPTION_REGISTRY
await self.hass.async_add_job(registry.register, self.wemo)
registry.on(self.wemo, None, self._subscription_callback)
async def async_update(self):
"""Update WeMo state.
Wemo has an aggressive retry logic that sometimes can take over a
minute to return. If we don't get a state after 5 seconds, assume the
Wemo switch is unreachable. If update goes through, it will be made
available again.
"""
# If an update is in progress, we don't do anything
if self._update_lock.locked():
return
try:
with async_timeout.timeout(5):
await asyncio.shield(self._async_locked_update(True))
except asyncio.TimeoutError:
_LOGGER.warning('Lost connection to %s', self.name)
self._available = False
async def _async_locked_update(self, force_update):
"""Try updating within an async lock."""
async with self._update_lock:
await self.hass.async_add_job(self._update, force_update)
def _update(self, force_update):
"""Update the device state."""
try:
self._state = self.wemo.get_state(force_update)
@@ -215,6 +243,11 @@ class WemoSwitch(SwitchDevice):
self.maker_params = self.wemo.maker_params
elif self._model_name == 'CoffeeMaker':
self.coffeemaker_mode = self.wemo.mode
if not self._available:
_LOGGER.info('Reconnected to %s', self.name)
self._available = True
except AttributeError as err:
_LOGGER.warning("Could not update status for %s (%s)",
self.name, err)
self._available = False

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,5 @@
"""Test Google Smart Home."""
from homeassistant.core import State
from homeassistant.const import (
ATTR_SUPPORTED_FEATURES, ATTR_UNIT_OF_MEASUREMENT, TEMP_CELSIUS)
from homeassistant.setup import async_setup_component
@@ -244,3 +245,17 @@ async def test_raising_error_trait(hass):
}]
}
}
def test_serialize_input_boolean():
"""Test serializing an input boolean entity."""
state = State('input_boolean.bla', 'on')
entity = sh._GoogleEntity(None, BASIC_CONFIG, state)
assert entity.sync_serialize() == {
'id': 'input_boolean.bla',
'attributes': {},
'name': {'name': 'bla'},
'traits': ['action.devices.traits.OnOff'],
'type': 'action.devices.types.SWITCH',
'willReportState': False,
}

View File

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

View File

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

View File

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