Hue Group features based on the bulbs in it (#31897)

* Computes the features of a hue group as the union of the features of the bulbs in the group

* Moved create item to a function

* Added test for hue group features
pull/31921/head
Victor Guimarães 2020-02-17 18:22:34 +00:00 committed by GitHub
parent 81701f7e4c
commit 93a844b1d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 209 additions and 5 deletions

View File

@ -72,6 +72,21 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
pass
def create_light(item_class, coordinator, bridge, is_group, api, item_id):
"""Create the light."""
if is_group:
supported_features = 0
for light_id in api[item_id].lights:
if light_id not in bridge.api.lights:
continue
light = bridge.api.lights[light_id]
supported_features |= SUPPORT_HUE.get(light.type, SUPPORT_HUE_EXTENDED)
supported_features = supported_features or SUPPORT_HUE_EXTENDED
else:
supported_features = SUPPORT_HUE.get(api[item_id].type, SUPPORT_HUE_EXTENDED)
return item_class(coordinator, bridge, is_group, api[item_id], supported_features)
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up the Hue lights from a config entry."""
bridge = hass.data[HUE_DOMAIN][config_entry.entry_id]
@ -100,7 +115,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
bridge.api.lights,
{},
async_add_entities,
partial(HueLight, light_coordinator, bridge, False),
partial(create_light, HueLight, light_coordinator, bridge, False),
)
# We add a listener after fetching the data, so manually trigger listener
@ -138,7 +153,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
bridge.api.groups,
{},
async_add_entities,
partial(HueLight, group_coordinator, bridge, True),
partial(create_light, HueLight, group_coordinator, bridge, True),
)
group_coordinator.async_add_listener(update_groups)
@ -170,7 +185,7 @@ def async_update_items(bridge, api, current, async_add_entities, create_item):
if item_id in current:
continue
current[item_id] = create_item(api[item_id])
current[item_id] = create_item(api, item_id)
new_items.append(current[item_id])
bridge.hass.async_create_task(remove_devices(bridge, api, current))
@ -182,12 +197,13 @@ def async_update_items(bridge, api, current, async_add_entities, create_item):
class HueLight(Light):
"""Representation of a Hue light."""
def __init__(self, coordinator, bridge, is_group, light):
def __init__(self, coordinator, bridge, is_group, light, supported_features):
"""Initialize the light."""
self.light = light
self.coordinator = coordinator
self.bridge = bridge
self.is_group = is_group
self._supported_features = supported_features
if is_group:
self.is_osram = False
@ -290,7 +306,7 @@ class HueLight(Light):
@property
def supported_features(self):
"""Flag supported features."""
return SUPPORT_HUE.get(self.light.type, SUPPORT_HUE_EXTENDED)
return self._supported_features
@property
def effect(self):

View File

@ -706,6 +706,7 @@ def test_available():
coordinator=Mock(last_update_success=True),
bridge=Mock(allow_unreachable=False),
is_group=False,
supported_features=hue_light.SUPPORT_HUE_EXTENDED,
)
assert light.available is False
@ -720,6 +721,7 @@ def test_available():
coordinator=Mock(last_update_success=True),
bridge=Mock(allow_unreachable=True),
is_group=False,
supported_features=hue_light.SUPPORT_HUE_EXTENDED,
)
assert light.available is True
@ -734,6 +736,7 @@ def test_available():
coordinator=Mock(last_update_success=True),
bridge=Mock(allow_unreachable=False),
is_group=True,
supported_features=hue_light.SUPPORT_HUE_EXTENDED,
)
assert light.available is True
@ -751,6 +754,7 @@ def test_hs_color():
coordinator=Mock(last_update_success=True),
bridge=Mock(),
is_group=False,
supported_features=hue_light.SUPPORT_HUE_EXTENDED,
)
assert light.hs_color is None
@ -765,6 +769,7 @@ def test_hs_color():
coordinator=Mock(last_update_success=True),
bridge=Mock(),
is_group=False,
supported_features=hue_light.SUPPORT_HUE_EXTENDED,
)
assert light.hs_color is None
@ -779,6 +784,189 @@ def test_hs_color():
coordinator=Mock(last_update_success=True),
bridge=Mock(),
is_group=False,
supported_features=hue_light.SUPPORT_HUE_EXTENDED,
)
assert light.hs_color == color.color_xy_to_hs(0.4, 0.5, LIGHT_GAMUT)
async def test_group_features(hass, mock_bridge):
"""Test group features."""
color_temp_type = "Color temperature light"
extended_color_type = "Extended color light"
group_response = {
"1": {
"name": "Group 1",
"lights": ["1", "2"],
"type": "Room",
"action": {
"on": True,
"bri": 254,
"hue": 10000,
"sat": 254,
"effect": "none",
"xy": [0.5, 0.5],
"ct": 250,
"alert": "select",
"colormode": "ct",
},
"state": {"any_on": True, "all_on": False},
},
"2": {
"name": "Group 2",
"lights": ["3", "4"],
"type": "Room",
"action": {
"on": True,
"bri": 153,
"hue": 4345,
"sat": 254,
"effect": "none",
"xy": [0.5, 0.5],
"ct": 250,
"alert": "select",
"colormode": "ct",
},
"state": {"any_on": True, "all_on": False},
},
"3": {
"name": "Group 3",
"lights": ["1", "3"],
"type": "Room",
"action": {
"on": True,
"bri": 153,
"hue": 4345,
"sat": 254,
"effect": "none",
"xy": [0.5, 0.5],
"ct": 250,
"alert": "select",
"colormode": "ct",
},
"state": {"any_on": True, "all_on": False},
},
}
light_1 = {
"state": {
"on": True,
"bri": 144,
"ct": 467,
"alert": "none",
"effect": "none",
"reachable": True,
},
"capabilities": {
"control": {
"colorgamuttype": "A",
"colorgamut": [[0.704, 0.296], [0.2151, 0.7106], [0.138, 0.08]],
}
},
"type": color_temp_type,
"name": "Hue Lamp 1",
"modelid": "LCT001",
"swversion": "66009461",
"manufacturername": "Philips",
"uniqueid": "456",
}
light_2 = {
"state": {
"on": False,
"bri": 0,
"ct": 0,
"alert": "none",
"effect": "none",
"colormode": "xy",
"reachable": True,
},
"capabilities": {
"control": {
"colorgamuttype": "A",
"colorgamut": [[0.704, 0.296], [0.2151, 0.7106], [0.138, 0.08]],
}
},
"type": color_temp_type,
"name": "Hue Lamp 2",
"modelid": "LCT001",
"swversion": "66009461",
"manufacturername": "Philips",
"uniqueid": "456",
}
light_3 = {
"state": {
"on": False,
"bri": 0,
"hue": 0,
"sat": 0,
"xy": [0, 0],
"ct": 0,
"alert": "none",
"effect": "none",
"colormode": "hs",
"reachable": True,
},
"capabilities": {
"control": {
"colorgamuttype": "A",
"colorgamut": [[0.704, 0.296], [0.2151, 0.7106], [0.138, 0.08]],
}
},
"type": extended_color_type,
"name": "Hue Lamp 3",
"modelid": "LCT001",
"swversion": "66009461",
"manufacturername": "Philips",
"uniqueid": "123",
}
light_4 = {
"state": {
"on": True,
"bri": 100,
"hue": 13088,
"sat": 210,
"xy": [0.5, 0.4],
"ct": 420,
"alert": "none",
"effect": "none",
"colormode": "hs",
"reachable": True,
},
"capabilities": {
"control": {
"colorgamuttype": "A",
"colorgamut": [[0.704, 0.296], [0.2151, 0.7106], [0.138, 0.08]],
}
},
"type": extended_color_type,
"name": "Hue Lamp 4",
"modelid": "LCT001",
"swversion": "66009461",
"manufacturername": "Philips",
"uniqueid": "123",
}
light_response = {
"1": light_1,
"2": light_2,
"3": light_3,
"4": light_4,
}
mock_bridge.allow_groups = True
mock_bridge.mock_light_responses.append(light_response)
mock_bridge.mock_group_responses.append(group_response)
await setup_bridge(hass, mock_bridge)
color_temp_feature = hue_light.SUPPORT_HUE["Color temperature light"]
extended_color_feature = hue_light.SUPPORT_HUE["Extended color light"]
group_1 = hass.states.get("light.group_1")
assert group_1.attributes["supported_features"] == color_temp_feature
group_2 = hass.states.get("light.group_2")
assert group_2.attributes["supported_features"] == extended_color_feature
group_3 = hass.states.get("light.group_3")
assert group_3.attributes["supported_features"] == extended_color_feature