Merge pull request #14199 from home-assistant/rc

0.68.1
This commit is contained in:
Paulus Schoutsen 2018-04-30 14:04:29 -04:00 committed by GitHub
commit d1460de89b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 178 additions and 95 deletions

View File

@ -1,6 +1,7 @@
"""Provide configuration end points for Automations.""" """Provide configuration end points for Automations."""
import asyncio import asyncio
from collections import OrderedDict from collections import OrderedDict
import uuid
from homeassistant.const import CONF_ID from homeassistant.const import CONF_ID
from homeassistant.components.config import EditIdBasedConfigView from homeassistant.components.config import EditIdBasedConfigView
@ -29,7 +30,12 @@ class EditAutomationConfigView(EditIdBasedConfigView):
"""Set value.""" """Set value."""
index = None index = None
for index, cur_value in enumerate(data): for index, cur_value in enumerate(data):
if cur_value[CONF_ID] == config_key: # When people copy paste their automations to the config file,
# they sometimes forget to add IDs. Fix it here.
if CONF_ID not in cur_value:
cur_value[CONF_ID] = uuid.uuid4().hex
elif cur_value[CONF_ID] == config_key:
break break
else: else:
cur_value = OrderedDict() cur_value = OrderedDict()

View File

@ -102,18 +102,23 @@ class _GoogleEntity:
if state.state == STATE_UNAVAILABLE: if state.state == STATE_UNAVAILABLE:
return None return None
entity_config = self.config.entity_config.get(state.entity_id, {})
name = (entity_config.get(CONF_NAME) or state.name).strip()
# If an empty string
if not name:
return None
traits = self.traits() traits = self.traits()
# Found no supported traits for this entity # Found no supported traits for this entity
if not traits: if not traits:
return None return None
entity_config = self.config.entity_config.get(state.entity_id, {})
device = { device = {
'id': state.entity_id, 'id': state.entity_id,
'name': { 'name': {
'name': entity_config.get(CONF_NAME) or state.name 'name': name
}, },
'attributes': {}, 'attributes': {},
'traits': [trait.name for trait in traits], 'traits': [trait.name for trait in traits],

View File

@ -3,6 +3,7 @@
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/homekit/ https://home-assistant.io/components/homekit/
""" """
import ipaddress
import logging import logging
from zlib import adler32 from zlib import adler32
@ -12,8 +13,8 @@ from homeassistant.components.cover import (
SUPPORT_CLOSE, SUPPORT_OPEN, SUPPORT_SET_POSITION) SUPPORT_CLOSE, SUPPORT_OPEN, SUPPORT_SET_POSITION)
from homeassistant.const import ( from homeassistant.const import (
ATTR_SUPPORTED_FEATURES, ATTR_UNIT_OF_MEASUREMENT, ATTR_SUPPORTED_FEATURES, ATTR_UNIT_OF_MEASUREMENT,
ATTR_DEVICE_CLASS, CONF_PORT, TEMP_CELSIUS, TEMP_FAHRENHEIT, ATTR_DEVICE_CLASS, CONF_IP_ADDRESS, CONF_PORT, TEMP_CELSIUS,
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP) TEMP_FAHRENHEIT, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entityfilter import FILTER_SCHEMA from homeassistant.helpers.entityfilter import FILTER_SCHEMA
from homeassistant.util import get_local_ip from homeassistant.util import get_local_ip
@ -35,6 +36,8 @@ REQUIREMENTS = ['HAP-python==1.1.9']
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.All({ DOMAIN: vol.All({
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_IP_ADDRESS):
vol.All(ipaddress.ip_address, cv.string),
vol.Optional(CONF_AUTO_START, default=DEFAULT_AUTO_START): cv.boolean, vol.Optional(CONF_AUTO_START, default=DEFAULT_AUTO_START): cv.boolean,
vol.Optional(CONF_FILTER, default={}): FILTER_SCHEMA, vol.Optional(CONF_FILTER, default={}): FILTER_SCHEMA,
vol.Optional(CONF_ENTITY_CONFIG, default={}): validate_entity_config, vol.Optional(CONF_ENTITY_CONFIG, default={}): validate_entity_config,
@ -48,11 +51,12 @@ async def async_setup(hass, config):
conf = config[DOMAIN] conf = config[DOMAIN]
port = conf[CONF_PORT] port = conf[CONF_PORT]
ip_address = conf.get(CONF_IP_ADDRESS)
auto_start = conf[CONF_AUTO_START] auto_start = conf[CONF_AUTO_START]
entity_filter = conf[CONF_FILTER] entity_filter = conf[CONF_FILTER]
entity_config = conf[CONF_ENTITY_CONFIG] entity_config = conf[CONF_ENTITY_CONFIG]
homekit = HomeKit(hass, port, entity_filter, entity_config) homekit = HomeKit(hass, port, ip_address, entity_filter, entity_config)
homekit.setup() homekit.setup()
if auto_start: if auto_start:
@ -151,10 +155,11 @@ def generate_aid(entity_id):
class HomeKit(): class HomeKit():
"""Class to handle all actions between HomeKit and Home Assistant.""" """Class to handle all actions between HomeKit and Home Assistant."""
def __init__(self, hass, port, entity_filter, entity_config): def __init__(self, hass, port, ip_address, entity_filter, entity_config):
"""Initialize a HomeKit object.""" """Initialize a HomeKit object."""
self.hass = hass self.hass = hass
self._port = port self._port = port
self._ip_address = ip_address
self._filter = entity_filter self._filter = entity_filter
self._config = entity_config self._config = entity_config
self.started = False self.started = False
@ -169,9 +174,10 @@ class HomeKit():
self.hass.bus.async_listen_once( self.hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_STOP, self.stop) EVENT_HOMEASSISTANT_STOP, self.stop)
ip_addr = self._ip_address or get_local_ip()
path = self.hass.config.path(HOMEKIT_FILE) path = self.hass.config.path(HOMEKIT_FILE)
self.bridge = HomeBridge(self.hass) self.bridge = HomeBridge(self.hass)
self.driver = HomeDriver(self.bridge, self._port, get_local_ip(), path) self.driver = HomeDriver(self.bridge, self._port, ip_addr, path)
def add_bridge_accessory(self, state): def add_bridge_accessory(self, state):
"""Try adding accessory to bridge if configured beforehand.""" """Try adding accessory to bridge if configured beforehand."""

View File

@ -31,7 +31,7 @@ KNOWN_DEVICES = "{}-devices".format(DOMAIN)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
def homekit_http_send(self, message_body=None): def homekit_http_send(self, message_body=None, encode_chunked=False):
r"""Send the currently buffered request and clear the buffer. r"""Send the currently buffered request and clear the buffer.
Appends an extra \r\n to the buffer. Appends an extra \r\n to the buffer.

View File

@ -242,26 +242,13 @@ class HueLight(Light):
@property @property
def hs_color(self): def hs_color(self):
"""Return the hs color value.""" """Return the hs color value."""
# pylint: disable=redefined-outer-name
mode = self._color_mode mode = self._color_mode
if mode not in ('hs', 'xy'):
return
source = self.light.action if self.is_group else self.light.state source = self.light.action if self.is_group else self.light.state
hue = source.get('hue') if mode in ('xy', 'hs'):
sat = source.get('sat') return color.color_xy_to_hs(*source['xy'])
# Sometimes the state will not include valid hue/sat values. return None
# Reported as issue 13434
if hue is not None and sat is not None:
return hue / 65535 * 360, sat / 255 * 100
if 'xy' not in source:
return None
return color.color_xy_to_hs(*source['xy'])
@property @property
def color_temp(self): def color_temp(self):

View File

@ -11,8 +11,8 @@ import voluptuous as vol
from homeassistant.const import (CONF_HOST, CONF_NAME) from homeassistant.const import (CONF_HOST, CONF_NAME)
from homeassistant.components.light import ( from homeassistant.components.light import (
Light, ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_KELVIN, ATTR_HS_COLOR, Light, ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_HS_COLOR, SUPPORT_BRIGHTNESS,
SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_COLOR, PLATFORM_SCHEMA) SUPPORT_COLOR_TEMP, SUPPORT_COLOR, PLATFORM_SCHEMA)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.util.color import \ from homeassistant.util.color import \
color_temperature_mired_to_kelvin as mired_to_kelvin color_temperature_mired_to_kelvin as mired_to_kelvin
@ -90,15 +90,15 @@ class TPLinkSmartBulb(Light):
if ATTR_COLOR_TEMP in kwargs: if ATTR_COLOR_TEMP in kwargs:
self.smartbulb.color_temp = \ self.smartbulb.color_temp = \
mired_to_kelvin(kwargs[ATTR_COLOR_TEMP]) mired_to_kelvin(kwargs[ATTR_COLOR_TEMP])
if ATTR_KELVIN in kwargs:
self.smartbulb.color_temp = kwargs[ATTR_KELVIN] brightness = brightness_to_percentage(
if ATTR_BRIGHTNESS in kwargs: kwargs.get(ATTR_BRIGHTNESS, self.brightness or 255))
brightness = kwargs.get(ATTR_BRIGHTNESS, self.brightness or 255)
self.smartbulb.brightness = brightness_to_percentage(brightness)
if ATTR_HS_COLOR in kwargs: if ATTR_HS_COLOR in kwargs:
hue, sat = kwargs.get(ATTR_HS_COLOR) hue, sat = kwargs.get(ATTR_HS_COLOR)
hsv = (hue, sat, 100) hsv = (int(hue), int(sat), brightness)
self.smartbulb.hsv = hsv self.smartbulb.hsv = hsv
elif ATTR_BRIGHTNESS in kwargs:
self.smartbulb.brightness = brightness
def turn_off(self, **kwargs): def turn_off(self, **kwargs):
"""Turn the light off.""" """Turn the light off."""

View File

@ -306,13 +306,18 @@ class CastDevice(MediaPlayerDevice):
_LOGGER.debug("Discovered chromecast with same UUID: %s", discover) _LOGGER.debug("Discovered chromecast with same UUID: %s", discover)
self.hass.async_add_job(self.async_set_cast_info(discover)) self.hass.async_add_job(self.async_set_cast_info(discover))
async def async_stop(event):
"""Disconnect socket on Home Assistant stop."""
await self._async_disconnect()
async_dispatcher_connect(self.hass, SIGNAL_CAST_DISCOVERED, async_dispatcher_connect(self.hass, SIGNAL_CAST_DISCOVERED,
async_cast_discovered) async_cast_discovered)
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, async_stop)
self.hass.async_add_job(self.async_set_cast_info(self._cast_info)) self.hass.async_add_job(self.async_set_cast_info(self._cast_info))
async def async_will_remove_from_hass(self) -> None: async def async_will_remove_from_hass(self) -> None:
"""Disconnect Chromecast object when removed.""" """Disconnect Chromecast object when removed."""
self._async_disconnect() await self._async_disconnect()
if self._cast_info.uuid is not None: if self._cast_info.uuid is not None:
# Remove the entity from the added casts so that it can dynamically # Remove the entity from the added casts so that it can dynamically
# be re-added again. # be re-added again.
@ -328,7 +333,7 @@ class CastDevice(MediaPlayerDevice):
if old_cast_info.host_port == cast_info.host_port: if old_cast_info.host_port == cast_info.host_port:
# Nothing connection-related updated # Nothing connection-related updated
return return
self._async_disconnect() await self._async_disconnect()
# Failed connection will unfortunately never raise an exception, it # Failed connection will unfortunately never raise an exception, it
# will instead just try connecting indefinitely. # will instead just try connecting indefinitely.
@ -348,22 +353,27 @@ class CastDevice(MediaPlayerDevice):
_LOGGER.debug("Connection successful!") _LOGGER.debug("Connection successful!")
self.async_schedule_update_ha_state() self.async_schedule_update_ha_state()
@callback async def _async_disconnect(self):
def _async_disconnect(self):
"""Disconnect Chromecast object if it is set.""" """Disconnect Chromecast object if it is set."""
if self._chromecast is None: if self._chromecast is None:
# Can't disconnect if not connected. # Can't disconnect if not connected.
return return
_LOGGER.debug("Disconnecting from previous chromecast socket.") _LOGGER.debug("Disconnecting from chromecast socket.")
self._available = False self._available = False
self._chromecast.disconnect(blocking=False) self.async_schedule_update_ha_state()
await self.hass.async_add_job(self._chromecast.disconnect)
# Invalidate some attributes # Invalidate some attributes
self._chromecast = None self._chromecast = None
self.cast_status = None self.cast_status = None
self.media_status = None self.media_status = None
self.media_status_received = None self.media_status_received = None
self._status_listener.invalidate() if self._status_listener is not None:
self._status_listener = None self._status_listener.invalidate()
self._status_listener = None
self.async_schedule_update_ha_state()
# ========== Callbacks ========== # ========== Callbacks ==========
def new_cast_status(self, cast_status): def new_cast_status(self, cast_status):

View File

@ -14,7 +14,8 @@ from homeassistant.const import (CONF_ACCESS_TOKEN, CONF_NAME, STATE_UNKNOWN)
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['eliqonline==1.0.13'] # pylint: disable=import-error, no-member
REQUIREMENTS = [] # ['eliqonline==1.0.13'] - package disappeared
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)

View File

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

View File

@ -276,9 +276,6 @@ dsmr_parser==0.11
# homeassistant.components.sensor.dweet # homeassistant.components.sensor.dweet
dweepy==0.3.0 dweepy==0.3.0
# homeassistant.components.sensor.eliqonline
eliqonline==1.0.13
# homeassistant.components.enocean # homeassistant.components.enocean
enocean==0.40 enocean==0.40

View File

@ -42,13 +42,13 @@ async def test_update_device_config(hass, aiohttp_client):
client = await aiohttp_client(hass.http.app) client = await aiohttp_client(hass.http.app)
orig_data = [ orig_data = [
{ {
'id': 'sun', 'id': 'sun',
}, },
{ {
'id': 'moon', 'id': 'moon',
} }
] ]
def mock_read(path): def mock_read(path):
"""Mock reading data.""" """Mock reading data."""
@ -81,3 +81,56 @@ async def test_update_device_config(hass, aiohttp_client):
'action': [], 'action': [],
} }
assert written[0] == orig_data assert written[0] == orig_data
async def test_bad_formatted_automations(hass, aiohttp_client):
"""Test that we handle automations without ID."""
with patch.object(config, 'SECTIONS', ['automation']):
await async_setup_component(hass, 'config', {})
client = await aiohttp_client(hass.http.app)
orig_data = [
{
# No ID
'action': {
'event': 'hello'
}
},
{
'id': 'moon',
}
]
def mock_read(path):
"""Mock reading data."""
return orig_data
written = []
def mock_write(path, data):
"""Mock writing data."""
written.append(data)
with patch('homeassistant.components.config._read', mock_read), \
patch('homeassistant.components.config._write', mock_write):
resp = await client.post(
'/api/config/automation/config/moon', data=json.dumps({
'trigger': [],
'action': [],
'condition': [],
}))
assert resp.status == 200
result = await resp.json()
assert result == {'result': 'ok'}
# Verify ID added to orig_data
assert 'id' in orig_data[0]
assert orig_data[1] == {
'id': 'moon',
'trigger': [],
'condition': [],
'action': [],
}

View File

@ -286,3 +286,29 @@ async def test_unavailable_state_doesnt_sync(hass):
'devices': [] 'devices': []
} }
} }
async def test_empty_name_doesnt_sync(hass):
"""Test that an entity with empty name does not sync over."""
light = DemoLight(
None, ' ',
state=False,
)
light.hass = hass
light.entity_id = 'light.demo_light'
await light.async_update_ha_state()
result = await sh.async_handle_message(hass, BASIC_CONFIG, {
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.SYNC"
}]
})
assert result == {
'requestId': REQ_ID,
'payload': {
'agentUserId': 'test-agent',
'devices': []
}
}

View File

@ -11,7 +11,8 @@ from homeassistant.components.homekit.const import (
DEFAULT_PORT, SERVICE_HOMEKIT_START) DEFAULT_PORT, SERVICE_HOMEKIT_START)
from homeassistant.helpers.entityfilter import generate_filter from homeassistant.helpers.entityfilter import generate_filter
from homeassistant.const import ( from homeassistant.const import (
CONF_PORT, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP) CONF_IP_ADDRESS, CONF_PORT,
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
from tests.common import get_test_home_assistant from tests.common import get_test_home_assistant
from tests.components.homekit.test_accessories import patch_debounce from tests.components.homekit.test_accessories import patch_debounce
@ -59,7 +60,7 @@ class TestHomeKit(unittest.TestCase):
self.hass, DOMAIN, {DOMAIN: {}})) self.hass, DOMAIN, {DOMAIN: {}}))
self.assertEqual(mock_homekit.mock_calls, [ self.assertEqual(mock_homekit.mock_calls, [
call(self.hass, DEFAULT_PORT, ANY, {}), call(self.hass, DEFAULT_PORT, None, ANY, {}),
call().setup()]) call().setup()])
# Test auto start enabled # Test auto start enabled
@ -74,7 +75,8 @@ class TestHomeKit(unittest.TestCase):
"""Test async_setup with auto start disabled and test service calls.""" """Test async_setup with auto start disabled and test service calls."""
mock_homekit.return_value = homekit = Mock() mock_homekit.return_value = homekit = Mock()
config = {DOMAIN: {CONF_AUTO_START: False, CONF_PORT: 11111}} config = {DOMAIN: {CONF_AUTO_START: False, CONF_PORT: 11111,
CONF_IP_ADDRESS: '172.0.0.0'}}
self.assertTrue(setup.setup_component( self.assertTrue(setup.setup_component(
self.hass, DOMAIN, config)) self.hass, DOMAIN, config))
@ -82,7 +84,7 @@ class TestHomeKit(unittest.TestCase):
self.hass.block_till_done() self.hass.block_till_done()
self.assertEqual(mock_homekit.mock_calls, [ self.assertEqual(mock_homekit.mock_calls, [
call(self.hass, 11111, ANY, {}), call(self.hass, 11111, '172.0.0.0', ANY, {}),
call().setup()]) call().setup()])
# Test start call with driver stopped. # Test start call with driver stopped.
@ -101,7 +103,7 @@ class TestHomeKit(unittest.TestCase):
def test_homekit_setup(self): def test_homekit_setup(self):
"""Test setup of bridge and driver.""" """Test setup of bridge and driver."""
homekit = HomeKit(self.hass, DEFAULT_PORT, {}, {}) homekit = HomeKit(self.hass, DEFAULT_PORT, None, {}, {})
with patch(PATH_HOMEKIT + '.accessories.HomeDriver') as mock_driver, \ with patch(PATH_HOMEKIT + '.accessories.HomeDriver') as mock_driver, \
patch('homeassistant.util.get_local_ip') as mock_ip: patch('homeassistant.util.get_local_ip') as mock_ip:
@ -117,9 +119,17 @@ class TestHomeKit(unittest.TestCase):
self.assertEqual( self.assertEqual(
self.hass.bus.listeners.get(EVENT_HOMEASSISTANT_STOP), 1) self.hass.bus.listeners.get(EVENT_HOMEASSISTANT_STOP), 1)
def test_homekit_setup_ip_address(self):
"""Test setup with given IP address."""
homekit = HomeKit(self.hass, DEFAULT_PORT, '172.0.0.0', {}, {})
with patch(PATH_HOMEKIT + '.accessories.HomeDriver') as mock_driver:
homekit.setup()
mock_driver.assert_called_with(ANY, DEFAULT_PORT, '172.0.0.0', ANY)
def test_homekit_add_accessory(self): def test_homekit_add_accessory(self):
"""Add accessory if config exists and get_acc returns an accessory.""" """Add accessory if config exists and get_acc returns an accessory."""
homekit = HomeKit(self.hass, None, lambda entity_id: True, {}) homekit = HomeKit(self.hass, None, None, lambda entity_id: True, {})
homekit.bridge = HomeBridge(self.hass) homekit.bridge = HomeBridge(self.hass)
with patch(PATH_HOMEKIT + '.accessories.HomeBridge.add_accessory') \ with patch(PATH_HOMEKIT + '.accessories.HomeBridge.add_accessory') \
@ -142,7 +152,7 @@ class TestHomeKit(unittest.TestCase):
def test_homekit_entity_filter(self): def test_homekit_entity_filter(self):
"""Test the entity filter.""" """Test the entity filter."""
entity_filter = generate_filter(['cover'], ['demo.test'], [], []) entity_filter = generate_filter(['cover'], ['demo.test'], [], [])
homekit = HomeKit(self.hass, None, entity_filter, {}) homekit = HomeKit(self.hass, None, None, entity_filter, {})
with patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc: with patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
mock_get_acc.return_value = None mock_get_acc.return_value = None
@ -162,7 +172,7 @@ class TestHomeKit(unittest.TestCase):
@patch(PATH_HOMEKIT + '.HomeKit.add_bridge_accessory') @patch(PATH_HOMEKIT + '.HomeKit.add_bridge_accessory')
def test_homekit_start(self, mock_add_bridge_acc, mock_show_setup_msg): def test_homekit_start(self, mock_add_bridge_acc, mock_show_setup_msg):
"""Test HomeKit start method.""" """Test HomeKit start method."""
homekit = HomeKit(self.hass, None, {}, {'cover.demo': {}}) homekit = HomeKit(self.hass, None, None, {}, {'cover.demo': {}})
homekit.bridge = HomeBridge(self.hass) homekit.bridge = HomeBridge(self.hass)
homekit.driver = Mock() homekit.driver = Mock()
@ -184,7 +194,7 @@ class TestHomeKit(unittest.TestCase):
def test_homekit_stop(self): def test_homekit_stop(self):
"""Test HomeKit stop method.""" """Test HomeKit stop method."""
homekit = HomeKit(None, None, None, None) homekit = HomeKit(None, None, None, None, None)
homekit.driver = Mock() homekit.driver = Mock()
# Test if started = False # Test if started = False

View File

@ -237,7 +237,7 @@ async def test_lights(hass, mock_bridge):
assert lamp_1 is not None assert lamp_1 is not None
assert lamp_1.state == 'on' assert lamp_1.state == 'on'
assert lamp_1.attributes['brightness'] == 144 assert lamp_1.attributes['brightness'] == 144
assert lamp_1.attributes['hs_color'] == (71.896, 83.137) assert lamp_1.attributes['hs_color'] == (36.067, 69.804)
lamp_2 = hass.states.get('light.hue_lamp_2') lamp_2 = hass.states.get('light.hue_lamp_2')
assert lamp_2 is not None assert lamp_2 is not None
@ -253,7 +253,7 @@ async def test_lights_color_mode(hass, mock_bridge):
assert lamp_1 is not None assert lamp_1 is not None
assert lamp_1.state == 'on' assert lamp_1.state == 'on'
assert lamp_1.attributes['brightness'] == 144 assert lamp_1.attributes['brightness'] == 144
assert lamp_1.attributes['hs_color'] == (71.896, 83.137) assert lamp_1.attributes['hs_color'] == (36.067, 69.804)
assert 'color_temp' not in lamp_1.attributes assert 'color_temp' not in lamp_1.attributes
new_light1_on = LIGHT_1_ON.copy() new_light1_on = LIGHT_1_ON.copy()
@ -650,37 +650,11 @@ def test_hs_color():
assert light.hs_color is None assert light.hs_color is None
light = hue_light.HueLight(
light=Mock(state={
'colormode': 'hs',
'hue': 1234,
'sat': 123,
}),
request_bridge_update=None,
bridge=Mock(),
is_group=False,
)
assert light.hs_color == (1234 / 65535 * 360, 123 / 255 * 100)
light = hue_light.HueLight( light = hue_light.HueLight(
light=Mock(state={ light=Mock(state={
'colormode': 'xy', 'colormode': 'xy',
'hue': 1234, 'hue': 1234,
'sat': 123, 'sat': 123,
}),
request_bridge_update=None,
bridge=Mock(),
is_group=False,
)
assert light.hs_color == (1234 / 65535 * 360, 123 / 255 * 100)
light = hue_light.HueLight(
light=Mock(state={
'colormode': 'xy',
'hue': None,
'sat': 123,
'xy': [0.4, 0.5] 'xy': [0.4, 0.5]
}), }),
request_bridge_update=None, request_bridge_update=None,

View File

@ -346,8 +346,16 @@ async def test_switched_host(hass: HomeAssistantType):
async_dispatcher_send(hass, cast.SIGNAL_CAST_DISCOVERED, changed) async_dispatcher_send(hass, cast.SIGNAL_CAST_DISCOVERED, changed)
await hass.async_block_till_done() await hass.async_block_till_done()
assert get_chromecast.call_count == 1 assert get_chromecast.call_count == 1
chromecast.disconnect.assert_called_once_with(blocking=False) assert chromecast.disconnect.call_count == 1
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
await hass.async_block_till_done() async def test_disconnect_on_stop(hass: HomeAssistantType):
chromecast.disconnect.assert_called_once_with(blocking=False) """Test cast device disconnects socket on stop."""
info = get_fake_chromecast_info()
with patch('pychromecast.dial.get_device_status', return_value=info):
chromecast, _ = await async_setup_media_player_cast(hass, info)
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
await hass.async_block_till_done()
assert chromecast.disconnect.call_count == 1