Split color temp and color into separate HomeKit services when a light supports both (#53471)

This commit is contained in:
J. Nick Koston 2021-07-27 12:10:05 -05:00 committed by GitHub
parent a1e692798f
commit 84a7a5fd32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 278 additions and 120 deletions

View File

@ -6,11 +6,13 @@ from pyhap.const import CATEGORY_LIGHTBULB
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_BRIGHTNESS_PCT,
ATTR_COLOR_MODE,
ATTR_COLOR_TEMP,
ATTR_HS_COLOR,
ATTR_MAX_MIREDS,
ATTR_MIN_MIREDS,
ATTR_SUPPORTED_COLOR_MODES,
COLOR_MODE_COLOR_TEMP,
DOMAIN,
brightness_supported,
color_supported,
@ -18,23 +20,18 @@ from homeassistant.components.light import (
)
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_SUPPORTED_FEATURES,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
STATE_ON,
)
from homeassistant.core import callback
from homeassistant.util.color import (
color_temperature_mired_to_kelvin,
color_temperature_to_hs,
)
from .accessories import TYPES, HomeAccessory
from .const import (
CHAR_BRIGHTNESS,
CHAR_COLOR_TEMPERATURE,
CHAR_HUE,
CHAR_NAME,
CHAR_ON,
CHAR_SATURATION,
PROP_MAX_VALUE,
@ -58,59 +55,99 @@ class Light(HomeAccessory):
"""Initialize a new Light accessory object."""
super().__init__(*args, category=CATEGORY_LIGHTBULB)
self.chars = []
self.chars_primary = []
self.chars_secondary = []
state = self.hass.states.get(self.entity_id)
attributes = state.attributes
color_modes = attributes.get(ATTR_SUPPORTED_COLOR_MODES)
self.is_color_supported = color_supported(color_modes)
self.is_color_temp_supported = color_temp_supported(color_modes)
self.color_and_temp_supported = (
self.is_color_supported and self.is_color_temp_supported
)
self.is_brightness_supported = brightness_supported(color_modes)
self._features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
self._color_modes = state.attributes.get(ATTR_SUPPORTED_COLOR_MODES)
if self.is_brightness_supported:
self.chars_primary.append(CHAR_BRIGHTNESS)
if brightness_supported(self._color_modes):
self.chars.append(CHAR_BRIGHTNESS)
if self.is_color_supported:
self.chars_primary.append(CHAR_HUE)
self.chars_primary.append(CHAR_SATURATION)
if color_supported(self._color_modes):
self.chars.append(CHAR_HUE)
self.chars.append(CHAR_SATURATION)
elif color_temp_supported(self._color_modes):
# ColorTemperature and Hue characteristic should not be
# exposed both. Both states are tracked separately in HomeKit,
# causing "source of truth" problems.
self.chars.append(CHAR_COLOR_TEMPERATURE)
if self.is_color_temp_supported:
if self.color_and_temp_supported:
self.chars_primary.append(CHAR_NAME)
self.chars_secondary.append(CHAR_NAME)
self.chars_secondary.append(CHAR_COLOR_TEMPERATURE)
if self.is_brightness_supported:
self.chars_secondary.append(CHAR_BRIGHTNESS)
else:
self.chars_primary.append(CHAR_COLOR_TEMPERATURE)
serv_light = self.add_preload_service(SERV_LIGHTBULB, self.chars)
serv_light_primary = self.add_preload_service(
SERV_LIGHTBULB, self.chars_primary
)
serv_light_secondary = None
self.char_on_primary = serv_light_primary.configure_char(CHAR_ON, value=0)
self.char_on = serv_light.configure_char(CHAR_ON, value=0)
if self.color_and_temp_supported:
serv_light_secondary = self.add_preload_service(
SERV_LIGHTBULB, self.chars_secondary
)
serv_light_primary.add_linked_service(serv_light_secondary)
serv_light_primary.configure_char(CHAR_NAME, value="RGB")
self.char_on_secondary = serv_light_secondary.configure_char(
CHAR_ON, value=0
)
serv_light_secondary.configure_char(CHAR_NAME, value="Temperature")
if CHAR_BRIGHTNESS in self.chars:
if self.is_brightness_supported:
# Initial value is set to 100 because 0 is a special value (off). 100 is
# an arbitrary non-zero value. It is updated immediately by async_update_state
# to set to the correct initial value.
self.char_brightness = serv_light.configure_char(CHAR_BRIGHTNESS, value=100)
self.char_brightness_primary = serv_light_primary.configure_char(
CHAR_BRIGHTNESS, value=100
)
if self.chars_secondary:
self.char_brightness_secondary = serv_light_secondary.configure_char(
CHAR_BRIGHTNESS, value=100
)
if CHAR_COLOR_TEMPERATURE in self.chars:
min_mireds = self.hass.states.get(self.entity_id).attributes.get(
ATTR_MIN_MIREDS, 153
)
max_mireds = self.hass.states.get(self.entity_id).attributes.get(
ATTR_MAX_MIREDS, 500
)
if self.is_color_temp_supported:
min_mireds = attributes.get(ATTR_MIN_MIREDS, 153)
max_mireds = attributes.get(ATTR_MAX_MIREDS, 500)
serv_light = serv_light_secondary or serv_light_primary
self.char_color_temperature = serv_light.configure_char(
CHAR_COLOR_TEMPERATURE,
value=min_mireds,
properties={PROP_MIN_VALUE: min_mireds, PROP_MAX_VALUE: max_mireds},
)
if CHAR_HUE in self.chars:
self.char_hue = serv_light.configure_char(CHAR_HUE, value=0)
if CHAR_SATURATION in self.chars:
self.char_saturation = serv_light.configure_char(CHAR_SATURATION, value=75)
if self.is_color_supported:
self.char_hue = serv_light_primary.configure_char(CHAR_HUE, value=0)
self.char_saturation = serv_light_primary.configure_char(
CHAR_SATURATION, value=75
)
self.async_update_state(state)
serv_light.setter_callback = self._set_chars
if self.color_and_temp_supported:
serv_light_primary.setter_callback = self._set_chars_primary
serv_light_secondary.setter_callback = self._set_chars_secondary
else:
serv_light_primary.setter_callback = self._set_chars
def _set_chars(self, char_values):
_LOGGER.debug("Light _set_chars: %s", char_values)
def _set_chars_primary(self, char_values):
"""Primary service is RGB or W if only color or color temp is supported."""
self._set_chars(char_values, True)
def _set_chars_secondary(self, char_values):
"""Secondary service is W if both color or color temp are supported."""
self._set_chars(char_values, False)
def _set_chars(self, char_values, is_primary=None):
_LOGGER.debug("Light _set_chars: %s, is_primary: %s", char_values, is_primary)
events = []
service = SERVICE_TURN_ON
params = {ATTR_ENTITY_ID: self.entity_id}
@ -127,16 +164,28 @@ class Light(HomeAccessory):
params[ATTR_BRIGHTNESS_PCT] = char_values[CHAR_BRIGHTNESS]
events.append(f"brightness at {char_values[CHAR_BRIGHTNESS]}%")
if CHAR_COLOR_TEMPERATURE in char_values:
params[ATTR_COLOR_TEMP] = char_values[CHAR_COLOR_TEMPERATURE]
events.append(f"color temperature at {char_values[CHAR_COLOR_TEMPERATURE]}")
if service == SERVICE_TURN_OFF:
self.async_call_service(
DOMAIN, service, {ATTR_ENTITY_ID: self.entity_id}, ", ".join(events)
)
return
if (
color_supported(self._color_modes)
and CHAR_HUE in char_values
and CHAR_SATURATION in char_values
if self.is_color_temp_supported and (
is_primary is False or CHAR_COLOR_TEMPERATURE in char_values
):
color = (char_values[CHAR_HUE], char_values[CHAR_SATURATION])
params[ATTR_COLOR_TEMP] = char_values.get(
CHAR_COLOR_TEMPERATURE, self.char_color_temperature.value
)
events.append(f"color temperature at {params[ATTR_COLOR_TEMP]}")
if self.is_color_supported and (
is_primary is True
or (CHAR_HUE in char_values and CHAR_SATURATION in char_values)
):
color = (
char_values.get(CHAR_HUE, self.char_hue.value),
char_values.get(CHAR_SATURATION, self.char_saturation.value),
)
_LOGGER.debug("%s: Set hs_color to %s", self.entity_id, color)
params[ATTR_HS_COLOR] = color
events.append(f"set color at {color}")
@ -148,14 +197,25 @@ class Light(HomeAccessory):
"""Update light after state change."""
# Handle State
state = new_state.state
if state == STATE_ON and self.char_on.value != 1:
self.char_on.set_value(1)
elif state == STATE_OFF and self.char_on.value != 0:
self.char_on.set_value(0)
attributes = new_state.attributes
char_on_value = int(state == STATE_ON)
if self.color_and_temp_supported:
color_mode = attributes.get(ATTR_COLOR_MODE)
color_temp_mode = color_mode == COLOR_MODE_COLOR_TEMP
primary_on_value = char_on_value if not color_temp_mode else 0
secondary_on_value = char_on_value if color_temp_mode else 0
if self.char_on_primary.value != primary_on_value:
self.char_on_primary.set_value(primary_on_value)
if self.char_on_secondary.value != secondary_on_value:
self.char_on_secondary.set_value(secondary_on_value)
else:
if self.char_on_primary.value != char_on_value:
self.char_on_primary.set_value(char_on_value)
# Handle Brightness
if CHAR_BRIGHTNESS in self.chars:
brightness = new_state.attributes.get(ATTR_BRIGHTNESS)
if self.is_brightness_supported:
brightness = attributes.get(ATTR_BRIGHTNESS)
if isinstance(brightness, (int, float)):
brightness = round(brightness / 255 * 100, 0)
# The homeassistant component might report its brightness as 0 but is
@ -170,29 +230,25 @@ class Light(HomeAccessory):
# order to avoid this incorrect behavior.
if brightness == 0 and state == STATE_ON:
brightness = 1
if self.char_brightness.value != brightness:
self.char_brightness.set_value(brightness)
if self.char_brightness_primary.value != brightness:
self.char_brightness_primary.set_value(brightness)
if (
self.color_and_temp_supported
and self.char_brightness_secondary.value != brightness
):
self.char_brightness_secondary.set_value(brightness)
# Handle color temperature
if CHAR_COLOR_TEMPERATURE in self.chars:
color_temperature = new_state.attributes.get(ATTR_COLOR_TEMP)
if self.is_color_temp_supported:
color_temperature = attributes.get(ATTR_COLOR_TEMP)
if isinstance(color_temperature, (int, float)):
color_temperature = round(color_temperature, 0)
if self.char_color_temperature.value != color_temperature:
self.char_color_temperature.set_value(color_temperature)
# Handle Color
if CHAR_SATURATION in self.chars and CHAR_HUE in self.chars:
if ATTR_HS_COLOR in new_state.attributes:
hue, saturation = new_state.attributes[ATTR_HS_COLOR]
elif ATTR_COLOR_TEMP in new_state.attributes:
hue, saturation = color_temperature_to_hs(
color_temperature_mired_to_kelvin(
new_state.attributes[ATTR_COLOR_TEMP]
)
)
else:
hue, saturation = None, None
if self.is_color_supported:
hue, saturation = attributes.get(ATTR_HS_COLOR, (None, None))
if isinstance(hue, (int, float)) and isinstance(saturation, (int, float)):
hue = round(hue, 0)
saturation = round(saturation, 0)

View File

@ -8,9 +8,14 @@ from homeassistant.components.homekit.type_lights import Light
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_BRIGHTNESS_PCT,
ATTR_COLOR_MODE,
ATTR_COLOR_TEMP,
ATTR_HS_COLOR,
ATTR_SUPPORTED_COLOR_MODES,
COLOR_MODE_COLOR_TEMP,
COLOR_MODE_HS,
COLOR_MODE_RGB,
COLOR_MODE_XY,
DOMAIN,
)
from homeassistant.const import (
@ -39,40 +44,44 @@ async def test_light_basic(hass, hk_driver, events):
assert acc.aid == 1
assert acc.category == 5 # Lightbulb
assert acc.char_on.value
assert acc.char_on_primary.value
await acc.run()
await hass.async_block_till_done()
assert acc.char_on.value == 1
assert acc.char_on_primary.value == 1
hass.states.async_set(entity_id, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 0})
await hass.async_block_till_done()
assert acc.char_on.value == 0
assert acc.char_on_primary.value == 0
hass.states.async_set(entity_id, STATE_UNKNOWN)
await hass.async_block_till_done()
assert acc.char_on.value == 0
assert acc.char_on_primary.value == 0
hass.states.async_remove(entity_id)
await hass.async_block_till_done()
assert acc.char_on.value == 0
assert acc.char_on_primary.value == 0
# Set from HomeKit
call_turn_on = async_mock_service(hass, DOMAIN, "turn_on")
call_turn_off = async_mock_service(hass, DOMAIN, "turn_off")
char_on_iid = acc.char_on.to_HAP()[HAP_REPR_IID]
char_on_primary_iid = acc.char_on_primary.to_HAP()[HAP_REPR_IID]
hk_driver.set_characteristics(
{
HAP_REPR_CHARS: [
{HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 1}
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_on_primary_iid,
HAP_REPR_VALUE: 1,
}
]
},
"mock_addr",
)
await hass.async_add_executor_job(acc.char_on.client_update_value, 1)
await hass.async_add_executor_job(acc.char_on_primary.client_update_value, 1)
await hass.async_block_till_done()
assert call_turn_on
assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
@ -85,7 +94,11 @@ async def test_light_basic(hass, hk_driver, events):
hk_driver.set_characteristics(
{
HAP_REPR_CHARS: [
{HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 0}
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_on_primary_iid,
HAP_REPR_VALUE: 0,
}
]
},
"mock_addr",
@ -115,17 +128,17 @@ async def test_light_brightness(hass, hk_driver, events, supported_color_modes):
# Initial value can be anything but 0. If it is 0, it might cause HomeKit to set the
# brightness to 100 when turning on a light on a freshly booted up server.
assert acc.char_brightness.value != 0
char_on_iid = acc.char_on.to_HAP()[HAP_REPR_IID]
char_brightness_iid = acc.char_brightness.to_HAP()[HAP_REPR_IID]
assert acc.char_brightness_primary.value != 0
char_on_primary_iid = acc.char_on_primary.to_HAP()[HAP_REPR_IID]
char_brightness_primary_iid = acc.char_brightness_primary.to_HAP()[HAP_REPR_IID]
await acc.run()
await hass.async_block_till_done()
assert acc.char_brightness.value == 100
assert acc.char_brightness_primary.value == 100
hass.states.async_set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 102})
await hass.async_block_till_done()
assert acc.char_brightness.value == 40
assert acc.char_brightness_primary.value == 40
# Set from HomeKit
call_turn_on = async_mock_service(hass, DOMAIN, "turn_on")
@ -134,10 +147,14 @@ async def test_light_brightness(hass, hk_driver, events, supported_color_modes):
hk_driver.set_characteristics(
{
HAP_REPR_CHARS: [
{HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 1},
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_brightness_iid,
HAP_REPR_IID: char_on_primary_iid,
HAP_REPR_VALUE: 1,
},
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_brightness_primary_iid,
HAP_REPR_VALUE: 20,
},
]
@ -156,10 +173,14 @@ async def test_light_brightness(hass, hk_driver, events, supported_color_modes):
hk_driver.set_characteristics(
{
HAP_REPR_CHARS: [
{HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 1},
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_brightness_iid,
HAP_REPR_IID: char_on_primary_iid,
HAP_REPR_VALUE: 1,
},
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_brightness_primary_iid,
HAP_REPR_VALUE: 40,
},
]
@ -178,10 +199,14 @@ async def test_light_brightness(hass, hk_driver, events, supported_color_modes):
hk_driver.set_characteristics(
{
HAP_REPR_CHARS: [
{HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 1},
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_brightness_iid,
HAP_REPR_IID: char_on_primary_iid,
HAP_REPR_VALUE: 1,
},
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_brightness_primary_iid,
HAP_REPR_VALUE: 0,
},
]
@ -198,24 +223,24 @@ async def test_light_brightness(hass, hk_driver, events, supported_color_modes):
# in update_state
hass.states.async_set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 0})
await hass.async_block_till_done()
assert acc.char_brightness.value == 1
assert acc.char_brightness_primary.value == 1
hass.states.async_set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 255})
await hass.async_block_till_done()
assert acc.char_brightness.value == 100
assert acc.char_brightness_primary.value == 100
hass.states.async_set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 0})
await hass.async_block_till_done()
assert acc.char_brightness.value == 1
assert acc.char_brightness_primary.value == 1
# Ensure floats are handled
hass.states.async_set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 55.66})
await hass.async_block_till_done()
assert acc.char_brightness.value == 22
assert acc.char_brightness_primary.value == 22
hass.states.async_set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 108.4})
await hass.async_block_till_done()
assert acc.char_brightness.value == 43
assert acc.char_brightness_primary.value == 43
hass.states.async_set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 0.0})
await hass.async_block_till_done()
assert acc.char_brightness.value == 1
assert acc.char_brightness_primary.value == 1
async def test_light_color_temperature(hass, hk_driver, events):
@ -266,7 +291,12 @@ async def test_light_color_temperature(hass, hk_driver, events):
@pytest.mark.parametrize(
"supported_color_modes", [["ct", "hs"], ["ct", "rgb"], ["ct", "xy"]]
"supported_color_modes",
[
[COLOR_MODE_COLOR_TEMP, COLOR_MODE_HS],
[COLOR_MODE_COLOR_TEMP, COLOR_MODE_RGB],
[COLOR_MODE_COLOR_TEMP, COLOR_MODE_XY],
],
)
async def test_light_color_temperature_and_rgb_color(
hass, hk_driver, events, supported_color_modes
@ -280,29 +310,93 @@ async def test_light_color_temperature_and_rgb_color(
{
ATTR_SUPPORTED_COLOR_MODES: supported_color_modes,
ATTR_COLOR_TEMP: 190,
ATTR_BRIGHTNESS: 255,
ATTR_COLOR_MODE: COLOR_MODE_RGB,
ATTR_HS_COLOR: (260, 90),
},
)
await hass.async_block_till_done()
acc = Light(hass, hk_driver, "Light", entity_id, 2, None)
acc = Light(hass, hk_driver, "Light", entity_id, 1, None)
assert acc.char_hue.value == 260
assert acc.char_saturation.value == 90
assert acc.char_on_primary.value == 1
assert acc.char_on_secondary.value == 0
assert acc.char_brightness_primary.value == 100
assert acc.char_brightness_secondary.value == 100
assert not hasattr(acc, "char_color_temperature")
assert hasattr(acc, "char_color_temperature")
hass.states.async_set(entity_id, STATE_ON, {ATTR_COLOR_TEMP: 224})
hass.states.async_set(
entity_id,
STATE_ON,
{
ATTR_COLOR_TEMP: 224,
ATTR_COLOR_MODE: COLOR_MODE_COLOR_TEMP,
ATTR_BRIGHTNESS: 127,
},
)
await hass.async_block_till_done()
await acc.run()
await hass.async_block_till_done()
assert acc.char_hue.value == 27
assert acc.char_saturation.value == 27
assert acc.char_color_temperature.value == 224
assert acc.char_on_primary.value == 0
assert acc.char_on_secondary.value == 1
assert acc.char_brightness_primary.value == 50
assert acc.char_brightness_secondary.value == 50
hass.states.async_set(entity_id, STATE_ON, {ATTR_COLOR_TEMP: 352})
hass.states.async_set(
entity_id,
STATE_ON,
{
ATTR_COLOR_TEMP: 352,
ATTR_COLOR_MODE: COLOR_MODE_COLOR_TEMP,
},
)
await hass.async_block_till_done()
await acc.run()
await hass.async_block_till_done()
assert acc.char_hue.value == 28
assert acc.char_saturation.value == 61
assert acc.char_color_temperature.value == 352
assert acc.char_on_primary.value == 0
assert acc.char_on_secondary.value == 1
hk_driver.add_accessory(acc)
char_hue_iid = acc.char_hue.to_HAP()[HAP_REPR_IID]
char_saturation_iid = acc.char_saturation.to_HAP()[HAP_REPR_IID]
char_color_temperature_iid = acc.char_color_temperature.to_HAP()[HAP_REPR_IID]
hk_driver.set_characteristics(
{
HAP_REPR_CHARS: [
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_hue_iid,
HAP_REPR_VALUE: 145,
},
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_saturation_iid,
HAP_REPR_VALUE: 75,
},
]
},
"mock_addr",
)
assert acc.char_hue.value == 145
assert acc.char_saturation.value == 75
hk_driver.set_characteristics(
{
HAP_REPR_CHARS: [
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_color_temperature_iid,
HAP_REPR_VALUE: 200,
},
]
},
"mock_addr",
)
assert acc.char_color_temperature.value == 200
@pytest.mark.parametrize("supported_color_modes", [["hs"], ["rgb"], ["xy"]])
@ -382,13 +476,13 @@ async def test_light_restore(hass, hk_driver, events):
hk_driver.add_accessory(acc)
assert acc.category == 5 # Lightbulb
assert acc.chars == []
assert acc.char_on.value == 0
assert acc.chars_primary == []
assert acc.char_on_primary.value == 0
acc = Light(hass, hk_driver, "Light", "light.all_info_set", 2, None)
assert acc.category == 5 # Lightbulb
assert acc.chars == ["Brightness"]
assert acc.char_on.value == 0
assert acc.chars_primary == ["Brightness"]
assert acc.char_on_primary.value == 0
async def test_light_set_brightness_and_color(hass, hk_driver, events):
@ -409,19 +503,19 @@ async def test_light_set_brightness_and_color(hass, hk_driver, events):
# Initial value can be anything but 0. If it is 0, it might cause HomeKit to set the
# brightness to 100 when turning on a light on a freshly booted up server.
assert acc.char_brightness.value != 0
char_on_iid = acc.char_on.to_HAP()[HAP_REPR_IID]
char_brightness_iid = acc.char_brightness.to_HAP()[HAP_REPR_IID]
assert acc.char_brightness_primary.value != 0
char_on_primary_iid = acc.char_on_primary.to_HAP()[HAP_REPR_IID]
char_brightness_primary_iid = acc.char_brightness_primary.to_HAP()[HAP_REPR_IID]
char_hue_iid = acc.char_hue.to_HAP()[HAP_REPR_IID]
char_saturation_iid = acc.char_saturation.to_HAP()[HAP_REPR_IID]
await acc.run()
await hass.async_block_till_done()
assert acc.char_brightness.value == 100
assert acc.char_brightness_primary.value == 100
hass.states.async_set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 102})
await hass.async_block_till_done()
assert acc.char_brightness.value == 40
assert acc.char_brightness_primary.value == 40
hass.states.async_set(entity_id, STATE_ON, {ATTR_HS_COLOR: (4.5, 9.2)})
await hass.async_block_till_done()
@ -434,10 +528,14 @@ async def test_light_set_brightness_and_color(hass, hk_driver, events):
hk_driver.set_characteristics(
{
HAP_REPR_CHARS: [
{HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 1},
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_brightness_iid,
HAP_REPR_IID: char_on_primary_iid,
HAP_REPR_VALUE: 1,
},
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_brightness_primary_iid,
HAP_REPR_VALUE: 20,
},
{
@ -485,18 +583,18 @@ async def test_light_set_brightness_and_color_temp(hass, hk_driver, events):
# Initial value can be anything but 0. If it is 0, it might cause HomeKit to set the
# brightness to 100 when turning on a light on a freshly booted up server.
assert acc.char_brightness.value != 0
char_on_iid = acc.char_on.to_HAP()[HAP_REPR_IID]
char_brightness_iid = acc.char_brightness.to_HAP()[HAP_REPR_IID]
assert acc.char_brightness_primary.value != 0
char_on_primary_iid = acc.char_on_primary.to_HAP()[HAP_REPR_IID]
char_brightness_primary_iid = acc.char_brightness_primary.to_HAP()[HAP_REPR_IID]
char_color_temperature_iid = acc.char_color_temperature.to_HAP()[HAP_REPR_IID]
await acc.run()
await hass.async_block_till_done()
assert acc.char_brightness.value == 100
assert acc.char_brightness_primary.value == 100
hass.states.async_set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 102})
await hass.async_block_till_done()
assert acc.char_brightness.value == 40
assert acc.char_brightness_primary.value == 40
hass.states.async_set(entity_id, STATE_ON, {ATTR_COLOR_TEMP: (224.14)})
await hass.async_block_till_done()
@ -508,10 +606,14 @@ async def test_light_set_brightness_and_color_temp(hass, hk_driver, events):
hk_driver.set_characteristics(
{
HAP_REPR_CHARS: [
{HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 1},
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_brightness_iid,
HAP_REPR_IID: char_on_primary_iid,
HAP_REPR_VALUE: 1,
},
{
HAP_REPR_AID: acc.aid,
HAP_REPR_IID: char_brightness_primary_iid,
HAP_REPR_VALUE: 20,
},
{