mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Try to fix crashes after Hue refactoring (#11270)
* Try to fix crashes after Hue refactoring Refs #11183 * Fix usage of dispatcher_send via helper. * Address review feedback.
This commit is contained in:
parent
3cba09c6f6
commit
4dda842b16
@ -152,6 +152,7 @@ class HueBridge(object):
|
|||||||
allow_in_emulated_hue=True, allow_hue_groups=True):
|
allow_in_emulated_hue=True, allow_hue_groups=True):
|
||||||
"""Initialize the system."""
|
"""Initialize the system."""
|
||||||
self.host = host
|
self.host = host
|
||||||
|
self.bridge_id = socket.gethostbyname(host)
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.allow_unreachable = allow_unreachable
|
self.allow_unreachable = allow_unreachable
|
||||||
@ -165,7 +166,7 @@ class HueBridge(object):
|
|||||||
self.configured = False
|
self.configured = False
|
||||||
self.config_request_id = None
|
self.config_request_id = None
|
||||||
|
|
||||||
hass.data[DOMAIN][socket.gethostbyname(host)] = self
|
hass.data[DOMAIN][self.bridge_id] = self
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
"""Set up a phue bridge based on host parameter."""
|
"""Set up a phue bridge based on host parameter."""
|
||||||
@ -196,7 +197,7 @@ class HueBridge(object):
|
|||||||
|
|
||||||
discovery.load_platform(
|
discovery.load_platform(
|
||||||
self.hass, 'light', DOMAIN,
|
self.hass, 'light', DOMAIN,
|
||||||
{'bridge_id': socket.gethostbyname(self.host)})
|
{'bridge_id': self.bridge_id})
|
||||||
|
|
||||||
# create a service for calling run_scene directly on the bridge,
|
# create a service for calling run_scene directly on the bridge,
|
||||||
# used to simplify automation rules.
|
# used to simplify automation rules.
|
||||||
|
@ -4,6 +4,7 @@ This component provides light support for the Philips Hue system.
|
|||||||
For more details about this platform, please refer to the documentation at
|
For more details about this platform, please refer to the documentation at
|
||||||
https://home-assistant.io/components/light.hue/
|
https://home-assistant.io/components/light.hue/
|
||||||
"""
|
"""
|
||||||
|
import asyncio
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
@ -14,9 +15,6 @@ import voluptuous as vol
|
|||||||
|
|
||||||
import homeassistant.components.hue as hue
|
import homeassistant.components.hue as hue
|
||||||
|
|
||||||
import homeassistant.util as util
|
|
||||||
from homeassistant.util import yaml
|
|
||||||
import homeassistant.util.color as color_util
|
|
||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_EFFECT, ATTR_FLASH, ATTR_RGB_COLOR,
|
ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_EFFECT, ATTR_FLASH, ATTR_RGB_COLOR,
|
||||||
ATTR_TRANSITION, ATTR_XY_COLOR, EFFECT_COLORLOOP, EFFECT_RANDOM,
|
ATTR_TRANSITION, ATTR_XY_COLOR, EFFECT_COLORLOOP, EFFECT_RANDOM,
|
||||||
@ -24,8 +22,10 @@ from homeassistant.components.light import (
|
|||||||
SUPPORT_EFFECT, SUPPORT_FLASH, SUPPORT_RGB_COLOR, SUPPORT_TRANSITION,
|
SUPPORT_EFFECT, SUPPORT_FLASH, SUPPORT_RGB_COLOR, SUPPORT_TRANSITION,
|
||||||
SUPPORT_XY_COLOR, Light, PLATFORM_SCHEMA)
|
SUPPORT_XY_COLOR, Light, PLATFORM_SCHEMA)
|
||||||
from homeassistant.const import CONF_FILENAME, CONF_HOST, DEVICE_DEFAULT_NAME
|
from homeassistant.const import CONF_FILENAME, CONF_HOST, DEVICE_DEFAULT_NAME
|
||||||
from homeassistant.components.emulated_hue import ATTR_EMULATED_HUE_HIDDEN
|
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
import homeassistant.util as util
|
||||||
|
from homeassistant.util import yaml
|
||||||
|
import homeassistant.util.color as color_util
|
||||||
|
|
||||||
DEPENDENCIES = ['hue']
|
DEPENDENCIES = ['hue']
|
||||||
|
|
||||||
@ -49,6 +49,7 @@ SUPPORT_HUE = {
|
|||||||
'Color temperature light': SUPPORT_HUE_COLOR_TEMP
|
'Color temperature light': SUPPORT_HUE_COLOR_TEMP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ATTR_EMULATED_HUE_HIDDEN = 'emulated_hue_hidden'
|
||||||
ATTR_IS_HUE_GROUP = 'is_hue_group'
|
ATTR_IS_HUE_GROUP = 'is_hue_group'
|
||||||
|
|
||||||
# Legacy configuration, will be removed in 0.60
|
# Legacy configuration, will be removed in 0.60
|
||||||
@ -83,6 +84,8 @@ This configuration is deprecated, please check the
|
|||||||
information.
|
information.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
SIGNAL_CALLBACK = 'hue_light_callback_{}_{}'
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
"""Set up the Hue lights."""
|
"""Set up the Hue lights."""
|
||||||
@ -163,7 +166,10 @@ def process_lights(hass, api, bridge, update_lights_cb):
|
|||||||
new_lights.append(bridge.lights[light_id])
|
new_lights.append(bridge.lights[light_id])
|
||||||
else:
|
else:
|
||||||
bridge.lights[light_id].info = info
|
bridge.lights[light_id].info = info
|
||||||
bridge.lights[light_id].schedule_update_ha_state()
|
hass.helpers.dispatcher.dispatcher_send(
|
||||||
|
SIGNAL_CALLBACK.format(
|
||||||
|
bridge.bridge_id,
|
||||||
|
bridge.lights[light_id].light_id))
|
||||||
|
|
||||||
return new_lights
|
return new_lights
|
||||||
|
|
||||||
@ -193,7 +199,10 @@ def process_groups(hass, api, bridge, update_lights_cb):
|
|||||||
new_lights.append(bridge.lightgroups[lightgroup_id])
|
new_lights.append(bridge.lightgroups[lightgroup_id])
|
||||||
else:
|
else:
|
||||||
bridge.lightgroups[lightgroup_id].info = info
|
bridge.lightgroups[lightgroup_id].info = info
|
||||||
bridge.lightgroups[lightgroup_id].schedule_update_ha_state()
|
hass.helpers.dispatcher.dispatcher_send(
|
||||||
|
SIGNAL_CALLBACK.format(
|
||||||
|
bridge.bridge_id,
|
||||||
|
bridge.lightgroups[lightgroup_id].light_id))
|
||||||
|
|
||||||
return new_lights
|
return new_lights
|
||||||
|
|
||||||
@ -366,3 +375,11 @@ class HueLight(Light):
|
|||||||
if self.is_group:
|
if self.is_group:
|
||||||
attributes[ATTR_IS_HUE_GROUP] = self.is_group
|
attributes[ATTR_IS_HUE_GROUP] = self.is_group
|
||||||
return attributes
|
return attributes
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def async_added_to_hass(self):
|
||||||
|
"""Register update callback."""
|
||||||
|
dev_id = self.bridge.bridge_id, self.light_id
|
||||||
|
self.hass.helpers.dispatcher.async_dispatcher_connect(
|
||||||
|
SIGNAL_CALLBACK.format(*dev_id),
|
||||||
|
self.async_schedule_update_ha_state)
|
||||||
|
@ -12,6 +12,8 @@ from tests.common import get_test_home_assistant, MockDependency
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
HUE_LIGHT_NS = 'homeassistant.components.light.hue.'
|
||||||
|
|
||||||
|
|
||||||
class TestSetup(unittest.TestCase):
|
class TestSetup(unittest.TestCase):
|
||||||
"""Test the Hue light platform."""
|
"""Test the Hue light platform."""
|
||||||
@ -29,11 +31,10 @@ class TestSetup(unittest.TestCase):
|
|||||||
def setup_mocks_for_update_lights(self):
|
def setup_mocks_for_update_lights(self):
|
||||||
"""Set up all mocks for update_lights tests."""
|
"""Set up all mocks for update_lights tests."""
|
||||||
self.mock_bridge = MagicMock()
|
self.mock_bridge = MagicMock()
|
||||||
|
self.mock_bridge.bridge_id = 'bridge-id'
|
||||||
self.mock_bridge.allow_hue_groups = False
|
self.mock_bridge.allow_hue_groups = False
|
||||||
self.mock_api = MagicMock()
|
self.mock_api = MagicMock()
|
||||||
self.mock_bridge.get_api.return_value = self.mock_api
|
self.mock_bridge.get_api.return_value = self.mock_api
|
||||||
self.mock_lights = []
|
|
||||||
self.mock_groups = []
|
|
||||||
self.mock_add_devices = MagicMock()
|
self.mock_add_devices = MagicMock()
|
||||||
|
|
||||||
def setup_mocks_for_process_lights(self):
|
def setup_mocks_for_process_lights(self):
|
||||||
@ -56,6 +57,7 @@ class TestSetup(unittest.TestCase):
|
|||||||
def create_mock_bridge(self, host, allow_hue_groups=True):
|
def create_mock_bridge(self, host, allow_hue_groups=True):
|
||||||
"""Return a mock HueBridge with reasonable defaults."""
|
"""Return a mock HueBridge with reasonable defaults."""
|
||||||
mock_bridge = MagicMock()
|
mock_bridge = MagicMock()
|
||||||
|
mock_bridge.bridge_id = 'bridge-id'
|
||||||
mock_bridge.host = host
|
mock_bridge.host = host
|
||||||
mock_bridge.allow_hue_groups = allow_hue_groups
|
mock_bridge.allow_hue_groups = allow_hue_groups
|
||||||
mock_bridge.lights = {}
|
mock_bridge.lights = {}
|
||||||
@ -72,6 +74,14 @@ class TestSetup(unittest.TestCase):
|
|||||||
|
|
||||||
return mock_bridge_lights
|
return mock_bridge_lights
|
||||||
|
|
||||||
|
def build_mock_light(self, bridge, light_id, name):
|
||||||
|
"""Return a mock HueLight."""
|
||||||
|
light = MagicMock()
|
||||||
|
light.bridge = bridge
|
||||||
|
light.light_id = light_id
|
||||||
|
light.name = name
|
||||||
|
return light
|
||||||
|
|
||||||
def test_setup_platform_no_discovery_info(self):
|
def test_setup_platform_no_discovery_info(self):
|
||||||
"""Test setup_platform without discovery info."""
|
"""Test setup_platform without discovery info."""
|
||||||
self.hass.data[hue.DOMAIN] = {}
|
self.hass.data[hue.DOMAIN] = {}
|
||||||
@ -96,8 +106,8 @@ class TestSetup(unittest.TestCase):
|
|||||||
self.hass.data[hue.DOMAIN] = {'10.0.0.1': mock_bridge}
|
self.hass.data[hue.DOMAIN] = {'10.0.0.1': mock_bridge}
|
||||||
mock_add_devices = MagicMock()
|
mock_add_devices = MagicMock()
|
||||||
|
|
||||||
with patch('homeassistant.components.light.hue.' +
|
with patch(HUE_LIGHT_NS + 'unthrottled_update_lights') \
|
||||||
'unthrottled_update_lights') as mock_update_lights:
|
as mock_update_lights:
|
||||||
hue_light.setup_platform(
|
hue_light.setup_platform(
|
||||||
self.hass, {}, mock_add_devices,
|
self.hass, {}, mock_add_devices,
|
||||||
{'bridge_id': '10.0.0.1'})
|
{'bridge_id': '10.0.0.1'})
|
||||||
@ -114,8 +124,8 @@ class TestSetup(unittest.TestCase):
|
|||||||
}
|
}
|
||||||
mock_add_devices = MagicMock()
|
mock_add_devices = MagicMock()
|
||||||
|
|
||||||
with patch('homeassistant.components.light.hue.' +
|
with patch(HUE_LIGHT_NS + 'unthrottled_update_lights') \
|
||||||
'unthrottled_update_lights') as mock_update_lights:
|
as mock_update_lights:
|
||||||
hue_light.setup_platform(
|
hue_light.setup_platform(
|
||||||
self.hass, {}, mock_add_devices,
|
self.hass, {}, mock_add_devices,
|
||||||
{'bridge_id': '10.0.0.1'})
|
{'bridge_id': '10.0.0.1'})
|
||||||
@ -133,83 +143,105 @@ class TestSetup(unittest.TestCase):
|
|||||||
"""Test the update_lights function when no lights are found."""
|
"""Test the update_lights function when no lights are found."""
|
||||||
self.setup_mocks_for_update_lights()
|
self.setup_mocks_for_update_lights()
|
||||||
|
|
||||||
with patch('homeassistant.components.light.hue.process_lights',
|
with patch(HUE_LIGHT_NS + 'process_lights', return_value=[]) \
|
||||||
return_value=[]) as mock_process_lights:
|
as mock_process_lights:
|
||||||
with patch('homeassistant.components.light.hue.process_groups',
|
with patch(HUE_LIGHT_NS + 'process_groups', return_value=[]) \
|
||||||
return_value=self.mock_groups) \
|
|
||||||
as mock_process_groups:
|
as mock_process_groups:
|
||||||
hue_light.unthrottled_update_lights(
|
with patch.object(self.hass.helpers.dispatcher,
|
||||||
self.hass, self.mock_bridge, self.mock_add_devices)
|
'dispatcher_send') as dispatcher_send:
|
||||||
|
hue_light.unthrottled_update_lights(
|
||||||
|
self.hass, self.mock_bridge, self.mock_add_devices)
|
||||||
|
|
||||||
mock_process_lights.assert_called_once_with(
|
mock_process_lights.assert_called_once_with(
|
||||||
self.hass, self.mock_api, self.mock_bridge, mock.ANY)
|
self.hass, self.mock_api, self.mock_bridge, mock.ANY)
|
||||||
mock_process_groups.assert_not_called()
|
mock_process_groups.assert_not_called()
|
||||||
self.mock_add_devices.assert_not_called()
|
self.mock_add_devices.assert_not_called()
|
||||||
|
dispatcher_send.assert_not_called()
|
||||||
|
|
||||||
@MockDependency('phue')
|
@MockDependency('phue')
|
||||||
def test_update_lights_with_some_lights(self, mock_phue):
|
def test_update_lights_with_some_lights(self, mock_phue):
|
||||||
"""Test the update_lights function with some lights."""
|
"""Test the update_lights function with some lights."""
|
||||||
self.setup_mocks_for_update_lights()
|
self.setup_mocks_for_update_lights()
|
||||||
self.mock_lights = ['some', 'light']
|
mock_lights = [
|
||||||
|
self.build_mock_light(self.mock_bridge, 42, 'some'),
|
||||||
|
self.build_mock_light(self.mock_bridge, 84, 'light'),
|
||||||
|
]
|
||||||
|
|
||||||
with patch('homeassistant.components.light.hue.process_lights',
|
with patch(HUE_LIGHT_NS + 'process_lights',
|
||||||
return_value=self.mock_lights) as mock_process_lights:
|
return_value=mock_lights) as mock_process_lights:
|
||||||
with patch('homeassistant.components.light.hue.process_groups',
|
with patch(HUE_LIGHT_NS + 'process_groups', return_value=[]) \
|
||||||
return_value=self.mock_groups) \
|
|
||||||
as mock_process_groups:
|
as mock_process_groups:
|
||||||
hue_light.unthrottled_update_lights(
|
with patch.object(self.hass.helpers.dispatcher,
|
||||||
self.hass, self.mock_bridge, self.mock_add_devices)
|
'dispatcher_send') as dispatcher_send:
|
||||||
|
hue_light.unthrottled_update_lights(
|
||||||
|
self.hass, self.mock_bridge, self.mock_add_devices)
|
||||||
|
|
||||||
mock_process_lights.assert_called_once_with(
|
mock_process_lights.assert_called_once_with(
|
||||||
self.hass, self.mock_api, self.mock_bridge, mock.ANY)
|
self.hass, self.mock_api, self.mock_bridge, mock.ANY)
|
||||||
mock_process_groups.assert_not_called()
|
mock_process_groups.assert_not_called()
|
||||||
self.mock_add_devices.assert_called_once_with(
|
self.mock_add_devices.assert_called_once_with(
|
||||||
self.mock_lights)
|
mock_lights)
|
||||||
|
dispatcher_send.assert_not_called()
|
||||||
|
|
||||||
@MockDependency('phue')
|
@MockDependency('phue')
|
||||||
def test_update_lights_no_groups(self, mock_phue):
|
def test_update_lights_no_groups(self, mock_phue):
|
||||||
"""Test the update_lights function when no groups are found."""
|
"""Test the update_lights function when no groups are found."""
|
||||||
self.setup_mocks_for_update_lights()
|
self.setup_mocks_for_update_lights()
|
||||||
self.mock_bridge.allow_hue_groups = True
|
self.mock_bridge.allow_hue_groups = True
|
||||||
self.mock_lights = ['some', 'light']
|
mock_lights = [
|
||||||
|
self.build_mock_light(self.mock_bridge, 42, 'some'),
|
||||||
|
self.build_mock_light(self.mock_bridge, 84, 'light'),
|
||||||
|
]
|
||||||
|
|
||||||
with patch('homeassistant.components.light.hue.process_lights',
|
with patch(HUE_LIGHT_NS + 'process_lights',
|
||||||
return_value=self.mock_lights) as mock_process_lights:
|
return_value=mock_lights) as mock_process_lights:
|
||||||
with patch('homeassistant.components.light.hue.process_groups',
|
with patch(HUE_LIGHT_NS + 'process_groups', return_value=[]) \
|
||||||
return_value=self.mock_groups) \
|
|
||||||
as mock_process_groups:
|
as mock_process_groups:
|
||||||
hue_light.unthrottled_update_lights(
|
with patch.object(self.hass.helpers.dispatcher,
|
||||||
self.hass, self.mock_bridge, self.mock_add_devices)
|
'dispatcher_send') as dispatcher_send:
|
||||||
|
hue_light.unthrottled_update_lights(
|
||||||
|
self.hass, self.mock_bridge, self.mock_add_devices)
|
||||||
|
|
||||||
mock_process_lights.assert_called_once_with(
|
mock_process_lights.assert_called_once_with(
|
||||||
self.hass, self.mock_api, self.mock_bridge, mock.ANY)
|
self.hass, self.mock_api, self.mock_bridge, mock.ANY)
|
||||||
mock_process_groups.assert_called_once_with(
|
mock_process_groups.assert_called_once_with(
|
||||||
self.hass, self.mock_api, self.mock_bridge, mock.ANY)
|
self.hass, self.mock_api, self.mock_bridge, mock.ANY)
|
||||||
self.mock_add_devices.assert_called_once_with(
|
self.mock_add_devices.assert_called_once_with(
|
||||||
self.mock_lights)
|
mock_lights)
|
||||||
|
dispatcher_send.assert_not_called()
|
||||||
|
|
||||||
@MockDependency('phue')
|
@MockDependency('phue')
|
||||||
def test_update_lights_with_lights_and_groups(self, mock_phue):
|
def test_update_lights_with_lights_and_groups(self, mock_phue):
|
||||||
"""Test the update_lights function with both lights and groups."""
|
"""Test the update_lights function with both lights and groups."""
|
||||||
self.setup_mocks_for_update_lights()
|
self.setup_mocks_for_update_lights()
|
||||||
self.mock_bridge.allow_hue_groups = True
|
self.mock_bridge.allow_hue_groups = True
|
||||||
self.mock_lights = ['some', 'light']
|
mock_lights = [
|
||||||
self.mock_groups = ['and', 'groups']
|
self.build_mock_light(self.mock_bridge, 42, 'some'),
|
||||||
|
self.build_mock_light(self.mock_bridge, 84, 'light'),
|
||||||
|
]
|
||||||
|
mock_groups = [
|
||||||
|
self.build_mock_light(self.mock_bridge, 15, 'and'),
|
||||||
|
self.build_mock_light(self.mock_bridge, 72, 'groups'),
|
||||||
|
]
|
||||||
|
|
||||||
with patch('homeassistant.components.light.hue.process_lights',
|
with patch(HUE_LIGHT_NS + 'process_lights',
|
||||||
return_value=self.mock_lights) as mock_process_lights:
|
return_value=mock_lights) as mock_process_lights:
|
||||||
with patch('homeassistant.components.light.hue.process_groups',
|
with patch(HUE_LIGHT_NS + 'process_groups',
|
||||||
return_value=self.mock_groups) \
|
return_value=mock_groups) as mock_process_groups:
|
||||||
as mock_process_groups:
|
with patch.object(self.hass.helpers.dispatcher,
|
||||||
hue_light.unthrottled_update_lights(
|
'dispatcher_send') as dispatcher_send:
|
||||||
self.hass, self.mock_bridge, self.mock_add_devices)
|
hue_light.unthrottled_update_lights(
|
||||||
|
self.hass, self.mock_bridge, self.mock_add_devices)
|
||||||
|
|
||||||
mock_process_lights.assert_called_once_with(
|
mock_process_lights.assert_called_once_with(
|
||||||
self.hass, self.mock_api, self.mock_bridge, mock.ANY)
|
self.hass, self.mock_api, self.mock_bridge, mock.ANY)
|
||||||
mock_process_groups.assert_called_once_with(
|
mock_process_groups.assert_called_once_with(
|
||||||
self.hass, self.mock_api, self.mock_bridge, mock.ANY)
|
self.hass, self.mock_api, self.mock_bridge, mock.ANY)
|
||||||
self.mock_add_devices.assert_called_once_with(
|
# note that mock_lights has been modified in place and
|
||||||
self.mock_lights)
|
# now contains both lights and groups
|
||||||
|
self.mock_add_devices.assert_called_once_with(
|
||||||
|
mock_lights)
|
||||||
|
dispatcher_send.assert_not_called()
|
||||||
|
|
||||||
@MockDependency('phue')
|
@MockDependency('phue')
|
||||||
def test_update_lights_with_two_bridges(self, mock_phue):
|
def test_update_lights_with_two_bridges(self, mock_phue):
|
||||||
@ -288,36 +320,42 @@ class TestSetup(unittest.TestCase):
|
|||||||
"""Test the process_lights function when bridge returns no lights."""
|
"""Test the process_lights function when bridge returns no lights."""
|
||||||
self.setup_mocks_for_process_lights()
|
self.setup_mocks_for_process_lights()
|
||||||
|
|
||||||
ret = hue_light.process_lights(
|
with patch.object(self.hass.helpers.dispatcher, 'dispatcher_send') \
|
||||||
self.hass, self.mock_api, self.mock_bridge, None)
|
as mock_dispatcher_send:
|
||||||
|
ret = hue_light.process_lights(
|
||||||
|
self.hass, self.mock_api, self.mock_bridge, None)
|
||||||
|
|
||||||
self.assertEquals([], ret)
|
self.assertEquals([], ret)
|
||||||
self.assertEquals(self.mock_bridge.lights, {})
|
mock_dispatcher_send.assert_not_called()
|
||||||
|
self.assertEquals(self.mock_bridge.lights, {})
|
||||||
|
|
||||||
@patch('homeassistant.components.light.hue.HueLight')
|
@patch(HUE_LIGHT_NS + 'HueLight')
|
||||||
def test_process_lights_some_lights(self, mock_hue_light):
|
def test_process_lights_some_lights(self, mock_hue_light):
|
||||||
"""Test the process_lights function with multiple groups."""
|
"""Test the process_lights function with multiple groups."""
|
||||||
self.setup_mocks_for_process_lights()
|
self.setup_mocks_for_process_lights()
|
||||||
self.mock_api.get.return_value = {
|
self.mock_api.get.return_value = {
|
||||||
1: {'state': 'on'}, 2: {'state': 'off'}}
|
1: {'state': 'on'}, 2: {'state': 'off'}}
|
||||||
|
|
||||||
ret = hue_light.process_lights(
|
with patch.object(self.hass.helpers.dispatcher, 'dispatcher_send') \
|
||||||
self.hass, self.mock_api, self.mock_bridge, None)
|
as mock_dispatcher_send:
|
||||||
|
ret = hue_light.process_lights(
|
||||||
|
self.hass, self.mock_api, self.mock_bridge, None)
|
||||||
|
|
||||||
self.assertEquals(len(ret), 2)
|
self.assertEquals(len(ret), 2)
|
||||||
mock_hue_light.assert_has_calls([
|
mock_hue_light.assert_has_calls([
|
||||||
call(
|
call(
|
||||||
1, {'state': 'on'}, self.mock_bridge, mock.ANY,
|
1, {'state': 'on'}, self.mock_bridge, mock.ANY,
|
||||||
self.mock_bridge.allow_unreachable,
|
self.mock_bridge.allow_unreachable,
|
||||||
self.mock_bridge.allow_in_emulated_hue),
|
self.mock_bridge.allow_in_emulated_hue),
|
||||||
call(
|
call(
|
||||||
2, {'state': 'off'}, self.mock_bridge, mock.ANY,
|
2, {'state': 'off'}, self.mock_bridge, mock.ANY,
|
||||||
self.mock_bridge.allow_unreachable,
|
self.mock_bridge.allow_unreachable,
|
||||||
self.mock_bridge.allow_in_emulated_hue),
|
self.mock_bridge.allow_in_emulated_hue),
|
||||||
])
|
])
|
||||||
self.assertEquals(len(self.mock_bridge.lights), 2)
|
mock_dispatcher_send.assert_not_called()
|
||||||
|
self.assertEquals(len(self.mock_bridge.lights), 2)
|
||||||
|
|
||||||
@patch('homeassistant.components.light.hue.HueLight')
|
@patch(HUE_LIGHT_NS + 'HueLight')
|
||||||
def test_process_lights_new_light(self, mock_hue_light):
|
def test_process_lights_new_light(self, mock_hue_light):
|
||||||
"""
|
"""
|
||||||
Test the process_lights function with new groups.
|
Test the process_lights function with new groups.
|
||||||
@ -327,21 +365,24 @@ class TestSetup(unittest.TestCase):
|
|||||||
self.setup_mocks_for_process_lights()
|
self.setup_mocks_for_process_lights()
|
||||||
self.mock_api.get.return_value = {
|
self.mock_api.get.return_value = {
|
||||||
1: {'state': 'on'}, 2: {'state': 'off'}}
|
1: {'state': 'on'}, 2: {'state': 'off'}}
|
||||||
self.mock_bridge.lights = {1: MagicMock()}
|
self.mock_bridge.lights = {
|
||||||
|
1: self.build_mock_light(self.mock_bridge, 1, 'foo')}
|
||||||
|
|
||||||
ret = hue_light.process_lights(
|
with patch.object(self.hass.helpers.dispatcher, 'dispatcher_send') \
|
||||||
self.hass, self.mock_api, self.mock_bridge, None)
|
as mock_dispatcher_send:
|
||||||
|
ret = hue_light.process_lights(
|
||||||
|
self.hass, self.mock_api, self.mock_bridge, None)
|
||||||
|
|
||||||
self.assertEquals(len(ret), 1)
|
self.assertEquals(len(ret), 1)
|
||||||
mock_hue_light.assert_has_calls([
|
mock_hue_light.assert_has_calls([
|
||||||
call(
|
call(
|
||||||
2, {'state': 'off'}, self.mock_bridge, mock.ANY,
|
2, {'state': 'off'}, self.mock_bridge, mock.ANY,
|
||||||
self.mock_bridge.allow_unreachable,
|
self.mock_bridge.allow_unreachable,
|
||||||
self.mock_bridge.allow_in_emulated_hue),
|
self.mock_bridge.allow_in_emulated_hue),
|
||||||
])
|
])
|
||||||
self.assertEquals(len(self.mock_bridge.lights), 2)
|
mock_dispatcher_send.assert_called_once_with(
|
||||||
self.mock_bridge.lights[1]\
|
'hue_light_callback_bridge-id_1')
|
||||||
.schedule_update_ha_state.assert_called_once_with()
|
self.assertEquals(len(self.mock_bridge.lights), 2)
|
||||||
|
|
||||||
def test_process_groups_api_error(self):
|
def test_process_groups_api_error(self):
|
||||||
"""Test the process_groups function when the bridge errors out."""
|
"""Test the process_groups function when the bridge errors out."""
|
||||||
@ -359,36 +400,42 @@ class TestSetup(unittest.TestCase):
|
|||||||
self.setup_mocks_for_process_groups()
|
self.setup_mocks_for_process_groups()
|
||||||
self.mock_bridge.get_group.return_value = {'name': 'Group 0'}
|
self.mock_bridge.get_group.return_value = {'name': 'Group 0'}
|
||||||
|
|
||||||
ret = hue_light.process_groups(
|
with patch.object(self.hass.helpers.dispatcher, 'dispatcher_send') \
|
||||||
self.hass, self.mock_api, self.mock_bridge, None)
|
as mock_dispatcher_send:
|
||||||
|
ret = hue_light.process_groups(
|
||||||
|
self.hass, self.mock_api, self.mock_bridge, None)
|
||||||
|
|
||||||
self.assertEquals([], ret)
|
self.assertEquals([], ret)
|
||||||
self.assertEquals(self.mock_bridge.lightgroups, {})
|
mock_dispatcher_send.assert_not_called()
|
||||||
|
self.assertEquals(self.mock_bridge.lightgroups, {})
|
||||||
|
|
||||||
@patch('homeassistant.components.light.hue.HueLight')
|
@patch(HUE_LIGHT_NS + 'HueLight')
|
||||||
def test_process_groups_some_groups(self, mock_hue_light):
|
def test_process_groups_some_groups(self, mock_hue_light):
|
||||||
"""Test the process_groups function with multiple groups."""
|
"""Test the process_groups function with multiple groups."""
|
||||||
self.setup_mocks_for_process_groups()
|
self.setup_mocks_for_process_groups()
|
||||||
self.mock_api.get.return_value = {
|
self.mock_api.get.return_value = {
|
||||||
1: {'state': 'on'}, 2: {'state': 'off'}}
|
1: {'state': 'on'}, 2: {'state': 'off'}}
|
||||||
|
|
||||||
ret = hue_light.process_groups(
|
with patch.object(self.hass.helpers.dispatcher, 'dispatcher_send') \
|
||||||
self.hass, self.mock_api, self.mock_bridge, None)
|
as mock_dispatcher_send:
|
||||||
|
ret = hue_light.process_groups(
|
||||||
|
self.hass, self.mock_api, self.mock_bridge, None)
|
||||||
|
|
||||||
self.assertEquals(len(ret), 2)
|
self.assertEquals(len(ret), 2)
|
||||||
mock_hue_light.assert_has_calls([
|
mock_hue_light.assert_has_calls([
|
||||||
call(
|
call(
|
||||||
1, {'state': 'on'}, self.mock_bridge, mock.ANY,
|
1, {'state': 'on'}, self.mock_bridge, mock.ANY,
|
||||||
self.mock_bridge.allow_unreachable,
|
self.mock_bridge.allow_unreachable,
|
||||||
self.mock_bridge.allow_in_emulated_hue, True),
|
self.mock_bridge.allow_in_emulated_hue, True),
|
||||||
call(
|
call(
|
||||||
2, {'state': 'off'}, self.mock_bridge, mock.ANY,
|
2, {'state': 'off'}, self.mock_bridge, mock.ANY,
|
||||||
self.mock_bridge.allow_unreachable,
|
self.mock_bridge.allow_unreachable,
|
||||||
self.mock_bridge.allow_in_emulated_hue, True),
|
self.mock_bridge.allow_in_emulated_hue, True),
|
||||||
])
|
])
|
||||||
self.assertEquals(len(self.mock_bridge.lightgroups), 2)
|
mock_dispatcher_send.assert_not_called()
|
||||||
|
self.assertEquals(len(self.mock_bridge.lightgroups), 2)
|
||||||
|
|
||||||
@patch('homeassistant.components.light.hue.HueLight')
|
@patch(HUE_LIGHT_NS + 'HueLight')
|
||||||
def test_process_groups_new_group(self, mock_hue_light):
|
def test_process_groups_new_group(self, mock_hue_light):
|
||||||
"""
|
"""
|
||||||
Test the process_groups function with new groups.
|
Test the process_groups function with new groups.
|
||||||
@ -398,21 +445,24 @@ class TestSetup(unittest.TestCase):
|
|||||||
self.setup_mocks_for_process_groups()
|
self.setup_mocks_for_process_groups()
|
||||||
self.mock_api.get.return_value = {
|
self.mock_api.get.return_value = {
|
||||||
1: {'state': 'on'}, 2: {'state': 'off'}}
|
1: {'state': 'on'}, 2: {'state': 'off'}}
|
||||||
self.mock_bridge.lightgroups = {1: MagicMock()}
|
self.mock_bridge.lightgroups = {
|
||||||
|
1: self.build_mock_light(self.mock_bridge, 1, 'foo')}
|
||||||
|
|
||||||
ret = hue_light.process_groups(
|
with patch.object(self.hass.helpers.dispatcher, 'dispatcher_send') \
|
||||||
self.hass, self.mock_api, self.mock_bridge, None)
|
as mock_dispatcher_send:
|
||||||
|
ret = hue_light.process_groups(
|
||||||
|
self.hass, self.mock_api, self.mock_bridge, None)
|
||||||
|
|
||||||
self.assertEquals(len(ret), 1)
|
self.assertEquals(len(ret), 1)
|
||||||
mock_hue_light.assert_has_calls([
|
mock_hue_light.assert_has_calls([
|
||||||
call(
|
call(
|
||||||
2, {'state': 'off'}, self.mock_bridge, mock.ANY,
|
2, {'state': 'off'}, self.mock_bridge, mock.ANY,
|
||||||
self.mock_bridge.allow_unreachable,
|
self.mock_bridge.allow_unreachable,
|
||||||
self.mock_bridge.allow_in_emulated_hue, True),
|
self.mock_bridge.allow_in_emulated_hue, True),
|
||||||
])
|
])
|
||||||
self.assertEquals(len(self.mock_bridge.lightgroups), 2)
|
mock_dispatcher_send.assert_called_once_with(
|
||||||
self.mock_bridge.lightgroups[1]\
|
'hue_light_callback_bridge-id_1')
|
||||||
.schedule_update_ha_state.assert_called_once_with()
|
self.assertEquals(len(self.mock_bridge.lightgroups), 2)
|
||||||
|
|
||||||
|
|
||||||
class TestHueLight(unittest.TestCase):
|
class TestHueLight(unittest.TestCase):
|
||||||
@ -440,6 +490,10 @@ class TestHueLight(unittest.TestCase):
|
|||||||
def buildLight(
|
def buildLight(
|
||||||
self, light_id=None, info=None, update_lights=None, is_group=None):
|
self, light_id=None, info=None, update_lights=None, is_group=None):
|
||||||
"""Helper to build a HueLight object with minimal fuss."""
|
"""Helper to build a HueLight object with minimal fuss."""
|
||||||
|
if 'state' not in info:
|
||||||
|
on_key = 'any_on' if is_group is not None else 'on'
|
||||||
|
info['state'] = {on_key: False}
|
||||||
|
|
||||||
return hue_light.HueLight(
|
return hue_light.HueLight(
|
||||||
light_id if light_id is not None else self.light_id,
|
light_id if light_id is not None else self.light_id,
|
||||||
info if info is not None else self.mock_info,
|
info if info is not None else self.mock_info,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user