async def test_light_restore(hass, hk_driver, events): """Test setting up an entity from state in the event registry.""" hass.state = CoreState.not_running registry = er.async_get(hass) registry.async_get_or_create("light", "hue", "1234", suggested_object_id="simple") registry.async_get_or_create( "light", "hue", "9012", suggested_object_id="all_info_set", capabilities={"supported_color_modes": ["brightness"], "max": 100}, supported_features=5, original_device_class="mock-device-class", ) hass.bus.async_fire(EVENT_HOMEASSISTANT_START, {}) await hass.async_block_till_done() acc = Light(hass, hk_driver, "Light", "light.simple", 1, None) hk_driver.add_accessory(acc) assert acc.category == 5 # Lightbulb assert acc.chars == [] assert acc.char_on.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
def test_light_rgb_color(self): """Test light with rgb_color.""" entity_id = 'light.demo' self.hass.states.set(entity_id, STATE_ON, { ATTR_SUPPORTED_FEATURES: SUPPORT_COLOR, ATTR_HS_COLOR: (260, 90) }) acc = Light(self.hass, entity_id, 'Light', aid=2) self.assertEqual(acc.char_hue.value, 0) self.assertEqual(acc.char_saturation.value, 75) acc.run() self.hass.block_till_done() self.assertEqual(acc.char_hue.value, 260) self.assertEqual(acc.char_saturation.value, 90) # Set from HomeKit acc.char_hue.set_value(145) acc.char_saturation.set_value(75) self.hass.block_till_done() self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN) self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON) self.assertEqual(self.events[0].data[ATTR_SERVICE_DATA], { ATTR_ENTITY_ID: entity_id, ATTR_HS_COLOR: (145, 75) })
async def test_light_color_temperature_and_rgb_color(hass, hk_driver, events, supported_color_modes): """Test light with color temperature and rgb color not exposing temperature.""" entity_id = "light.demo" hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_COLOR_MODES: supported_color_modes, ATTR_COLOR_TEMP: 190, ATTR_HS_COLOR: (260, 90), }, ) await hass.async_block_till_done() acc = Light(hass, hk_driver, "Light", entity_id, 2, None) assert acc.char_hue.value == 260 assert acc.char_saturation.value == 90 assert not hasattr(acc, "char_color_temperature") hass.states.async_set(entity_id, STATE_ON, {ATTR_COLOR_TEMP: 224}) 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 hass.states.async_set(entity_id, STATE_ON, {ATTR_COLOR_TEMP: 352}) 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
def test_light_brightness(self): """Test light with brightness.""" entity_id = 'light.demo' self.hass.states.set(entity_id, STATE_ON, { ATTR_SUPPORTED_FEATURES: SUPPORT_BRIGHTNESS, ATTR_BRIGHTNESS: 255 }) acc = Light(self.hass, entity_id, 'Light', aid=2) self.assertEqual(acc.char_brightness.value, 0) acc.run() self.hass.block_till_done() self.assertEqual(acc.char_brightness.value, 100) self.hass.states.set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 102}) self.hass.block_till_done() self.assertEqual(acc.char_brightness.value, 40) # Set from HomeKit acc.char_brightness.set_value(20) acc.char_on.set_value(1) self.hass.block_till_done() self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN) self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON) self.assertEqual(self.events[0].data[ATTR_SERVICE_DATA], { ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS_PCT: 20 }) acc.char_on.set_value(1) acc.char_brightness.set_value(40) self.hass.block_till_done() self.assertEqual(self.events[1].data[ATTR_DOMAIN], DOMAIN) self.assertEqual(self.events[1].data[ATTR_SERVICE], SERVICE_TURN_ON) self.assertEqual(self.events[1].data[ATTR_SERVICE_DATA], { ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS_PCT: 40 }) acc.char_on.set_value(1) acc.char_brightness.set_value(0) self.hass.block_till_done() self.assertEqual(self.events[2].data[ATTR_DOMAIN], DOMAIN) self.assertEqual(self.events[2].data[ATTR_SERVICE], SERVICE_TURN_OFF)
def test_light_basic(self): """Test light with char state.""" entity_id = 'light.demo' self.hass.states.set(entity_id, STATE_ON, {ATTR_SUPPORTED_FEATURES: 0}) acc = Light(self.hass, entity_id, 'Light', aid=2) self.assertEqual(acc.aid, 2) self.assertEqual(acc.category, 5) # Lightbulb self.assertEqual(acc.char_on.value, 0) acc.run() self.hass.block_till_done() self.assertEqual(acc.char_on.value, 1) self.hass.states.set(entity_id, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 0}) self.hass.block_till_done() self.assertEqual(acc.char_on.value, 0) self.hass.states.set(entity_id, STATE_UNKNOWN) self.hass.block_till_done() self.assertEqual(acc.char_on.value, 0) # Set from HomeKit acc.char_on.set_value(1) self.hass.block_till_done() self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN) self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON) self.hass.states.set(entity_id, STATE_ON) self.hass.block_till_done() acc.char_on.set_value(0) self.hass.block_till_done() self.assertEqual(self.events[1].data[ATTR_DOMAIN], DOMAIN) self.assertEqual(self.events[1].data[ATTR_SERVICE], SERVICE_TURN_OFF) self.hass.states.set(entity_id, STATE_OFF) self.hass.block_till_done() # Remove entity self.hass.states.remove(entity_id) self.hass.block_till_done()
def test_light_basic(self): """Test light with char state.""" entity_id = 'light.demo' self.hass.states.set(entity_id, STATE_ON, {ATTR_SUPPORTED_FEATURES: 0}) acc = Light(self.hass, entity_id, 'Light', aid=2) self.assertEqual(acc.aid, 2) self.assertEqual(acc.category, 5) # Lightbulb self.assertEqual(acc.char_on.value, 0) acc.run() self.hass.block_till_done() self.assertEqual(acc.char_on.value, 1) self.hass.states.set(entity_id, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 0}) self.hass.block_till_done() self.assertEqual(acc.char_on.value, 0) self.hass.states.set(entity_id, STATE_UNKNOWN) self.hass.block_till_done() self.assertEqual(acc.char_on.value, 0) # Set from HomeKit acc.char_on.set_value(1) self.hass.block_till_done() self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN) self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON) self.hass.states.set(entity_id, STATE_ON) self.hass.block_till_done() acc.char_on.set_value(0) self.hass.block_till_done() self.assertEqual(self.events[1].data[ATTR_DOMAIN], DOMAIN) self.assertEqual(self.events[1].data[ATTR_SERVICE], SERVICE_TURN_OFF) self.hass.states.set(entity_id, STATE_OFF) self.hass.block_till_done() # Remove entity self.hass.states.remove(entity_id) self.hass.block_till_done()
def test_light_color_temperature(self): """Test light with color temperature.""" entity_id = 'light.demo' self.hass.states.set(entity_id, STATE_ON, { ATTR_SUPPORTED_FEATURES: SUPPORT_COLOR_TEMP, ATTR_COLOR_TEMP: 190}) acc = Light(self.hass, entity_id, 'Light', aid=2) self.assertEqual(acc.char_color_temperature.value, 153) acc.run() self.hass.block_till_done() self.assertEqual(acc.char_color_temperature.value, 190) # Set from HomeKit acc.char_color_temperature.set_value(250) self.hass.block_till_done() self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN) self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON) self.assertEqual( self.events[0].data[ATTR_SERVICE_DATA], { ATTR_ENTITY_ID: entity_id, ATTR_COLOR_TEMP: 250})
async def test_light_rgb_color(hass, hk_driver, events, supported_color_modes): """Test light with rgb_color.""" entity_id = "light.demo" hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_COLOR_MODES: supported_color_modes, ATTR_HS_COLOR: (260, 90) }, ) await hass.async_block_till_done() acc = Light(hass, hk_driver, "Light", entity_id, 1, None) hk_driver.add_accessory(acc) assert acc.char_hue.value == 260 assert acc.char_saturation.value == 90 await acc.run() await hass.async_block_till_done() assert acc.char_hue.value == 260 assert acc.char_saturation.value == 90 # Set from HomeKit call_turn_on = async_mock_service(hass, DOMAIN, "turn_on") char_hue_iid = acc.char_hue.to_HAP()[HAP_REPR_IID] char_saturation_iid = acc.char_saturation.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", ) await hass.async_block_till_done() assert call_turn_on assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id assert call_turn_on[0].data[ATTR_HS_COLOR] == (145, 75) assert len(events) == 1 assert events[-1].data[ATTR_VALUE] == "set color at (145, 75)"
def test_light_brightness(self): """Test light with brightness.""" entity_id = 'light.demo' self.hass.states.set(entity_id, STATE_ON, { ATTR_SUPPORTED_FEATURES: SUPPORT_BRIGHTNESS, ATTR_BRIGHTNESS: 255}) acc = Light(self.hass, entity_id, 'Light', aid=2) self.assertEqual(acc.char_brightness.value, 0) acc.run() self.hass.block_till_done() self.assertEqual(acc.char_brightness.value, 100) self.hass.states.set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 102}) self.hass.block_till_done() self.assertEqual(acc.char_brightness.value, 40) # Set from HomeKit acc.char_brightness.set_value(20) acc.char_on.set_value(1) self.hass.block_till_done() self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN) self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON) self.assertEqual( self.events[0].data[ATTR_SERVICE_DATA], { ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS_PCT: 20}) acc.char_on.set_value(1) acc.char_brightness.set_value(40) self.hass.block_till_done() self.assertEqual(self.events[1].data[ATTR_DOMAIN], DOMAIN) self.assertEqual(self.events[1].data[ATTR_SERVICE], SERVICE_TURN_ON) self.assertEqual( self.events[1].data[ATTR_SERVICE_DATA], { ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS_PCT: 40}) acc.char_on.set_value(1) acc.char_brightness.set_value(0) self.hass.block_till_done() self.assertEqual(self.events[2].data[ATTR_DOMAIN], DOMAIN) self.assertEqual(self.events[2].data[ATTR_SERVICE], SERVICE_TURN_OFF)
def test_light_color_temperature(self): """Test light with color temperature.""" entity_id = 'light.demo' self.hass.states.set(entity_id, STATE_ON, { ATTR_SUPPORTED_FEATURES: SUPPORT_COLOR_TEMP, ATTR_COLOR_TEMP: 190 }) acc = Light(self.hass, entity_id, 'Light', aid=2) self.assertEqual(acc.char_color_temperature.value, 153) acc.run() self.hass.block_till_done() self.assertEqual(acc.char_color_temperature.value, 190) # Set from HomeKit acc.char_color_temperature.set_value(250) self.hass.block_till_done() self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN) self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON) self.assertEqual(self.events[0].data[ATTR_SERVICE_DATA], { ATTR_ENTITY_ID: entity_id, ATTR_COLOR_TEMP: 250 })
def test_light_rgb_color(self): """Test light with rgb_color.""" entity_id = 'light.demo' self.hass.states.set(entity_id, STATE_ON, { ATTR_SUPPORTED_FEATURES: SUPPORT_COLOR, ATTR_HS_COLOR: (260, 90)}) acc = Light(self.hass, entity_id, 'Light', aid=2) self.assertEqual(acc.char_hue.value, 0) self.assertEqual(acc.char_saturation.value, 75) acc.run() self.hass.block_till_done() self.assertEqual(acc.char_hue.value, 260) self.assertEqual(acc.char_saturation.value, 90) # Set from HomeKit acc.char_hue.set_value(145) acc.char_saturation.set_value(75) self.hass.block_till_done() self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN) self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON) self.assertEqual( self.events[0].data[ATTR_SERVICE_DATA], { ATTR_ENTITY_ID: entity_id, ATTR_HS_COLOR: (145, 75)})
async def test_light_color_temperature(hass, hk_driver, events): """Test light with color temperature.""" entity_id = "light.demo" hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_COLOR_MODES: ["color_temp"], ATTR_COLOR_TEMP: 190 }, ) await hass.async_block_till_done() acc = Light(hass, hk_driver, "Light", entity_id, 1, None) hk_driver.add_accessory(acc) assert acc.char_color_temperature.value == 190 await acc.run() await hass.async_block_till_done() assert acc.char_color_temperature.value == 190 # Set from HomeKit call_turn_on = async_mock_service(hass, DOMAIN, "turn_on") 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_color_temperature_iid, HAP_REPR_VALUE: 250, }] }, "mock_addr", ) await hass.async_add_executor_job( acc.char_color_temperature.client_update_value, 250) await hass.async_block_till_done() assert call_turn_on assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id assert call_turn_on[0].data[ATTR_COLOR_TEMP] == 250 assert len(events) == 1 assert events[-1].data[ATTR_VALUE] == "color temperature at 250"
async def test_light_min_max_mireds(hass, hk_driver, events): """Test mireds are forced to ints.""" entity_id = "light.demo" hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_COLOR_MODES: ["color_temp"], ATTR_BRIGHTNESS: 255, ATTR_MAX_MIREDS: 500.5, ATTR_MIN_MIREDS: 100.5, }, ) await hass.async_block_till_done() acc = Light(hass, hk_driver, "Light", entity_id, 1, None) acc.char_color_temp.properties["maxValue"] == 500 acc.char_color_temp.properties["minValue"] == 100
async def test_light_set_brightness_and_color_temp(hass, hk_driver, events): """Test light with all chars in one go.""" entity_id = "light.demo" hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_COLOR_MODES: ["color_temp"], ATTR_BRIGHTNESS: 255, }, ) await hass.async_block_till_done() acc = Light(hass, hk_driver, "Light", entity_id, 1, None) hk_driver.add_accessory(acc) # 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] 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 hass.states.async_set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 102}) await hass.async_block_till_done() assert acc.char_brightness.value == 40 hass.states.async_set(entity_id, STATE_ON, {ATTR_COLOR_TEMP: (224.14)}) await hass.async_block_till_done() assert acc.char_color_temperature.value == 224 # Set from HomeKit call_turn_on = async_mock_service(hass, DOMAIN, "turn_on") 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_VALUE: 20, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_color_temperature_iid, HAP_REPR_VALUE: 250, }, ] }, "mock_addr", ) await hass.async_block_till_done() assert call_turn_on[0] assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id assert call_turn_on[0].data[ATTR_BRIGHTNESS_PCT] == 20 assert call_turn_on[0].data[ATTR_COLOR_TEMP] == 250 assert len(events) == 1 assert ( events[-1].data[ATTR_VALUE] == f"Set state to 1, brightness at 20{PERCENTAGE}, color temperature at 250" )
async def test_light_basic(hass, hk_driver, events): """Test light with char state.""" entity_id = "light.demo" hass.states.async_set(entity_id, STATE_ON, {ATTR_SUPPORTED_FEATURES: 0}) await hass.async_block_till_done() acc = Light(hass, hk_driver, "Light", entity_id, 1, None) hk_driver.add_accessory(acc) assert acc.aid == 1 assert acc.category == 5 # Lightbulb assert acc.char_on.value await acc.run() await hass.async_block_till_done() assert acc.char_on.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 hass.states.async_set(entity_id, STATE_UNKNOWN) await hass.async_block_till_done() assert acc.char_on.value == 0 hass.states.async_remove(entity_id) await hass.async_block_till_done() assert acc.char_on.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] hk_driver.set_characteristics( { HAP_REPR_CHARS: [{ HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 1 }] }, "mock_addr", ) await hass.async_add_executor_job(acc.char_on.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 assert len(events) == 1 assert events[-1].data[ATTR_VALUE] == "Set state to 1" hass.states.async_set(entity_id, STATE_ON) await hass.async_block_till_done() hk_driver.set_characteristics( { HAP_REPR_CHARS: [{ HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 0 }] }, "mock_addr", ) await hass.async_block_till_done() assert call_turn_off assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id assert len(events) == 2 assert events[-1].data[ATTR_VALUE] == "Set state to 0"
async def test_light_rgbw_with_color_temp_conversion( hass, hk_driver, events, ): """Test lights with RGBW convert color temp as expected.""" entity_id = "light.demo" hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_COLOR_MODES: [COLOR_MODE_RGBW], ATTR_RGBWW_COLOR: (128, 50, 0, 255, 255), ATTR_RGB_COLOR: (128, 50, 0), ATTR_HS_COLOR: (23.438, 100.0), ATTR_BRIGHTNESS: 255, ATTR_COLOR_MODE: COLOR_MODE_RGBW, }, ) await hass.async_block_till_done() acc = Light(hass, hk_driver, "Light", entity_id, 1, None) hk_driver.add_accessory(acc) assert acc.char_hue.value == 23 assert acc.char_saturation.value == 100 await acc.run() await hass.async_block_till_done() assert acc.char_hue.value == 23 assert acc.char_saturation.value == 100 assert acc.char_brightness.value == 100 # Set from HomeKit call_turn_on = async_mock_service(hass, DOMAIN, "turn_on") char_hue_iid = acc.char_hue.to_HAP()[HAP_REPR_IID] char_saturation_iid = acc.char_saturation.to_HAP()[HAP_REPR_IID] char_color_temp_iid = acc.char_color_temp.to_HAP()[HAP_REPR_IID] assert (acc.char_color_temp.properties[PROP_MIN_VALUE] == acc.char_color_temp.properties[PROP_MAX_VALUE]) 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", ) await _wait_for_light_coalesce(hass) assert call_turn_on assert call_turn_on[-1].data[ATTR_ENTITY_ID] == entity_id assert call_turn_on[-1].data[ATTR_HS_COLOR] == (145, 75) assert len(events) == 1 assert events[-1].data[ATTR_VALUE] == "set color at (145, 75)" assert acc.char_brightness.value == 100 hk_driver.set_characteristics( { HAP_REPR_CHARS: [ { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_color_temp_iid, HAP_REPR_VALUE: 153, }, ] }, "mock_addr", ) await _wait_for_light_coalesce(hass) assert call_turn_on assert call_turn_on[-1].data[ATTR_ENTITY_ID] == entity_id assert call_turn_on[-1].data[ATTR_RGBW_COLOR] == (0, 0, 0, 255) assert len(events) == 2 assert events[-1].data[ATTR_VALUE] == "color temperature at 153" assert acc.char_brightness.value == 100
async def test_light_brightness(hass, hk_driver, events, supported_color_modes): """Test light with brightness.""" entity_id = "light.demo" hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_COLOR_MODES: supported_color_modes, ATTR_BRIGHTNESS: 255 }, ) await hass.async_block_till_done() acc = Light(hass, hk_driver, "Light", entity_id, 1, None) hk_driver.add_accessory(acc) # 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] await acc.run() await hass.async_block_till_done() assert acc.char_brightness.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 # Set from HomeKit call_turn_on = async_mock_service(hass, DOMAIN, "turn_on") call_turn_off = async_mock_service(hass, DOMAIN, "turn_off") 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_VALUE: 20, }, ] }, "mock_addr", ) await hass.async_block_till_done() assert call_turn_on[0] assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id assert call_turn_on[0].data[ATTR_BRIGHTNESS_PCT] == 20 assert len(events) == 1 assert (events[-1].data[ATTR_VALUE] == f"Set state to 1, brightness at 20{PERCENTAGE}") 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_VALUE: 40, }, ] }, "mock_addr", ) await hass.async_block_till_done() assert call_turn_on[1] assert call_turn_on[1].data[ATTR_ENTITY_ID] == entity_id assert call_turn_on[1].data[ATTR_BRIGHTNESS_PCT] == 40 assert len(events) == 2 assert (events[-1].data[ATTR_VALUE] == f"Set state to 1, brightness at 40{PERCENTAGE}") 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_VALUE: 0, }, ] }, "mock_addr", ) await hass.async_block_till_done() assert call_turn_off assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id assert len(events) == 3 assert events[-1].data[ ATTR_VALUE] == f"Set state to 0, brightness at 0{PERCENTAGE}" # 0 is a special case for homekit, see "Handle Brightness" # 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 hass.states.async_set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 255}) await hass.async_block_till_done() assert acc.char_brightness.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 # 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 hass.states.async_set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 108.4}) await hass.async_block_till_done() assert acc.char_brightness.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
async def test_light_rgb_or_w_lights( hass, hk_driver, events, ): """Test lights with RGB or W lights.""" entity_id = "light.demo" hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_COLOR_MODES: [COLOR_MODE_RGB, COLOR_MODE_WHITE], ATTR_RGBW_COLOR: (128, 50, 0, 255), ATTR_RGB_COLOR: (128, 50, 0), ATTR_HS_COLOR: (23.438, 100.0), ATTR_BRIGHTNESS: 255, ATTR_COLOR_MODE: COLOR_MODE_RGB, }, ) await hass.async_block_till_done() acc = Light(hass, hk_driver, "Light", entity_id, 1, None) hk_driver.add_accessory(acc) assert acc.char_hue.value == 23 assert acc.char_saturation.value == 100 await acc.run() await hass.async_block_till_done() assert acc.char_hue.value == 23 assert acc.char_saturation.value == 100 assert acc.char_brightness.value == 100 assert acc.char_color_temp.value == 153 # Set from HomeKit call_turn_on = async_mock_service(hass, DOMAIN, "turn_on") char_hue_iid = acc.char_hue.to_HAP()[HAP_REPR_IID] char_saturation_iid = acc.char_saturation.to_HAP()[HAP_REPR_IID] char_brightness_iid = acc.char_brightness.to_HAP()[HAP_REPR_IID] char_color_temp_iid = acc.char_color_temp.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", ) await _wait_for_light_coalesce(hass) assert call_turn_on assert call_turn_on[-1].data[ATTR_ENTITY_ID] == entity_id assert call_turn_on[-1].data[ATTR_HS_COLOR] == (145, 75) assert len(events) == 1 assert events[-1].data[ATTR_VALUE] == "set color at (145, 75)" assert acc.char_brightness.value == 100 hk_driver.set_characteristics( { HAP_REPR_CHARS: [ { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_color_temp_iid, HAP_REPR_VALUE: acc.min_mireds, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_brightness_iid, HAP_REPR_VALUE: 25, }, ] }, "mock_addr", ) await _wait_for_light_coalesce(hass) assert call_turn_on assert call_turn_on[-1].data[ATTR_ENTITY_ID] == entity_id assert call_turn_on[-1].data[ATTR_WHITE] == round(25 * 255 / 100) assert len(events) == 2 assert events[-1].data[ ATTR_VALUE] == "brightness at 25%, color temperature at 153" assert acc.char_brightness.value == 25 hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_COLOR_MODES: [COLOR_MODE_RGB, COLOR_MODE_WHITE], ATTR_BRIGHTNESS: 255, ATTR_COLOR_MODE: COLOR_MODE_WHITE, }, ) await hass.async_block_till_done() assert acc.char_hue.value == 0 assert acc.char_saturation.value == 0 assert acc.char_brightness.value == 100 assert acc.char_color_temp.value == 153
async def test_light_color_temperature_and_rgb_color(hass, hk_driver, events, supported_color_modes): """Test light with color temperature and rgb color not exposing temperature.""" entity_id = "light.demo" hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_COLOR_MODES: supported_color_modes, ATTR_COLOR_TEMP: 190, ATTR_HS_COLOR: (260, 90), }, ) await hass.async_block_till_done() acc = Light(hass, hk_driver, "Light", entity_id, 1, None) hk_driver.add_accessory(acc) assert acc.char_color_temp.value == 190 assert acc.char_hue.value == 27 assert acc.char_saturation.value == 16 assert hasattr(acc, "char_color_temp") hass.states.async_set(entity_id, STATE_ON, {ATTR_COLOR_TEMP: 224}) await hass.async_block_till_done() await acc.run() await hass.async_block_till_done() assert acc.char_color_temp.value == 224 assert acc.char_hue.value == 27 assert acc.char_saturation.value == 27 hass.states.async_set(entity_id, STATE_ON, {ATTR_COLOR_TEMP: 352}) await hass.async_block_till_done() await acc.run() await hass.async_block_till_done() assert acc.char_color_temp.value == 352 assert acc.char_hue.value == 28 assert acc.char_saturation.value == 61 char_on_iid = acc.char_on.to_HAP()[HAP_REPR_IID] char_brightness_iid = acc.char_brightness.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] char_color_temp_iid = acc.char_color_temp.to_HAP()[HAP_REPR_IID] # Set from HomeKit call_turn_on = async_mock_service(hass, DOMAIN, "turn_on") 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_VALUE: 20, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_color_temp_iid, HAP_REPR_VALUE: 250, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_hue_iid, HAP_REPR_VALUE: 50, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_saturation_iid, HAP_REPR_VALUE: 50, }, ] }, "mock_addr", ) await _wait_for_light_coalesce(hass) assert call_turn_on[0] assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id assert call_turn_on[0].data[ATTR_BRIGHTNESS_PCT] == 20 assert call_turn_on[0].data[ATTR_COLOR_TEMP] == 250 assert len(events) == 1 assert ( events[-1].data[ATTR_VALUE] == f"Set state to 1, brightness at 20{PERCENTAGE}, color temperature at 250" ) # Only set Hue hk_driver.set_characteristics( { HAP_REPR_CHARS: [{ HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_hue_iid, HAP_REPR_VALUE: 30, }] }, "mock_addr", ) await _wait_for_light_coalesce(hass) assert call_turn_on[1] assert call_turn_on[1].data[ATTR_HS_COLOR] == (30, 50) assert events[-1].data[ATTR_VALUE] == "set color at (30, 50)" # Only set Saturation hk_driver.set_characteristics( { HAP_REPR_CHARS: [{ HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_saturation_iid, HAP_REPR_VALUE: 20, }] }, "mock_addr", ) await _wait_for_light_coalesce(hass) assert call_turn_on[2] assert call_turn_on[2].data[ATTR_HS_COLOR] == (30, 20) assert events[-1].data[ATTR_VALUE] == "set color at (30, 20)" # Generate a conflict by setting hue and then color temp hk_driver.set_characteristics( { HAP_REPR_CHARS: [{ HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_hue_iid, HAP_REPR_VALUE: 80, }] }, "mock_addr", ) hk_driver.set_characteristics( { HAP_REPR_CHARS: [{ HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_color_temp_iid, HAP_REPR_VALUE: 320, }] }, "mock_addr", ) await _wait_for_light_coalesce(hass) assert call_turn_on[3] assert call_turn_on[3].data[ATTR_COLOR_TEMP] == 320 assert events[-1].data[ATTR_VALUE] == "color temperature at 320" # Generate a conflict by setting color temp then saturation hk_driver.set_characteristics( { HAP_REPR_CHARS: [{ HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_color_temp_iid, HAP_REPR_VALUE: 404, }] }, "mock_addr", ) hk_driver.set_characteristics( { HAP_REPR_CHARS: [{ HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_saturation_iid, HAP_REPR_VALUE: 35, }] }, "mock_addr", ) await _wait_for_light_coalesce(hass) assert call_turn_on[4] assert call_turn_on[4].data[ATTR_HS_COLOR] == (80, 35) assert events[-1].data[ATTR_VALUE] == "set color at (80, 35)" # Set from HASS hass.states.async_set(entity_id, STATE_ON, {ATTR_HS_COLOR: (100, 100)}) await hass.async_block_till_done() await acc.run() await hass.async_block_till_done() assert acc.char_color_temp.value == 404 assert acc.char_hue.value == 100 assert acc.char_saturation.value == 100
async def test_light_color_temperature_and_rgb_color(hass, hk_driver, events, supported_color_modes): """Test light with color temperature and rgb color not exposing temperature.""" entity_id = "light.demo" hass.states.async_set( entity_id, STATE_ON, { 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, 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 hasattr(acc, "char_color_temperature") 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_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, 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_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
async def test_light_rgb_with_white_switch_to_temp( hass, hk_driver, events, supported_color_modes, state_props, turn_on_props, turn_on_props_with_brightness, ): """Test lights with RGBW/RGBWW that preserves brightness when switching to color temp.""" entity_id = "light.demo" hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_COLOR_MODES: supported_color_modes, **state_props }, ) await hass.async_block_till_done() acc = Light(hass, hk_driver, "Light", entity_id, 1, None) hk_driver.add_accessory(acc) assert acc.char_hue.value == 23 assert acc.char_saturation.value == 100 await acc.run() await hass.async_block_till_done() assert acc.char_hue.value == 23 assert acc.char_saturation.value == 100 assert acc.char_brightness.value == 50 # Set from HomeKit call_turn_on = async_mock_service(hass, DOMAIN, "turn_on") char_hue_iid = acc.char_hue.to_HAP()[HAP_REPR_IID] char_saturation_iid = acc.char_saturation.to_HAP()[HAP_REPR_IID] char_color_temp_iid = acc.char_color_temp.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", ) await _wait_for_light_coalesce(hass) assert call_turn_on assert call_turn_on[-1].data[ATTR_ENTITY_ID] == entity_id for k, v in turn_on_props.items(): assert call_turn_on[-1].data[k] == v assert len(events) == 1 assert events[-1].data[ATTR_VALUE] == "set color at (145, 75)" assert acc.char_brightness.value == 50 hk_driver.set_characteristics( { HAP_REPR_CHARS: [ { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_color_temp_iid, HAP_REPR_VALUE: 2700, }, ] }, "mock_addr", ) await _wait_for_light_coalesce(hass) assert call_turn_on assert call_turn_on[-1].data[ATTR_ENTITY_ID] == entity_id for k, v in turn_on_props_with_brightness.items(): assert call_turn_on[-1].data[k] == v assert len(events) == 2 assert events[-1].data[ATTR_VALUE] == "color temperature at 2700" assert acc.char_brightness.value == 50