Migrate homekit_controller light to color_mode (#69261)

pull/70109/head
Erik Montnemery 2022-04-20 21:26:15 +02:00 committed by GitHub
parent 2abe551eef
commit 7c0b0f7cc1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 128 additions and 30 deletions

View File

@ -10,9 +10,10 @@ from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_COLOR_TEMP,
ATTR_HS_COLOR,
SUPPORT_BRIGHTNESS,
SUPPORT_COLOR,
SUPPORT_COLOR_TEMP,
COLOR_MODE_BRIGHTNESS,
COLOR_MODE_COLOR_TEMP,
COLOR_MODE_HS,
COLOR_MODE_ONOFF,
LightEntity,
)
from homeassistant.config_entries import ConfigEntry
@ -79,23 +80,43 @@ class HomeKitLight(HomeKitEntity, LightEntity):
return self.service.value(CharacteristicsTypes.COLOR_TEMPERATURE)
@property
def supported_features(self) -> int:
"""Flag supported features."""
features = 0
if self.service.has(CharacteristicsTypes.BRIGHTNESS):
features |= SUPPORT_BRIGHTNESS
def color_mode(self) -> str:
"""Return the color mode of the light."""
# aiohomekit does not keep track of the light's color mode, report
# hs for light supporting both hs and ct
if self.service.has(CharacteristicsTypes.HUE) or self.service.has(
CharacteristicsTypes.SATURATION
):
return COLOR_MODE_HS
if self.service.has(CharacteristicsTypes.COLOR_TEMPERATURE):
features |= SUPPORT_COLOR_TEMP
return COLOR_MODE_COLOR_TEMP
if self.service.has(CharacteristicsTypes.HUE):
features |= SUPPORT_COLOR
if self.service.has(CharacteristicsTypes.BRIGHTNESS):
return COLOR_MODE_BRIGHTNESS
if self.service.has(CharacteristicsTypes.SATURATION):
features |= SUPPORT_COLOR
return COLOR_MODE_ONOFF
return features
@property
def supported_color_modes(self) -> set[str] | None:
"""Flag supported color modes."""
color_modes = set()
if self.service.has(CharacteristicsTypes.HUE) or self.service.has(
CharacteristicsTypes.SATURATION
):
color_modes.add(COLOR_MODE_HS)
if self.service.has(CharacteristicsTypes.COLOR_TEMPERATURE):
color_modes.add(COLOR_MODE_COLOR_TEMP)
if not color_modes and self.service.has(CharacteristicsTypes.BRIGHTNESS):
color_modes.add(COLOR_MODE_BRIGHTNESS)
if not color_modes:
color_modes.add(COLOR_MODE_ONOFF)
return color_modes
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the specified light on."""

View File

@ -8,7 +8,6 @@ from homeassistant.components.alarm_control_panel import (
SUPPORT_ALARM_ARM_HOME,
SUPPORT_ALARM_ARM_NIGHT,
)
from homeassistant.components.light import SUPPORT_BRIGHTNESS, SUPPORT_COLOR
from homeassistant.components.number import NumberMode
from homeassistant.helpers.entity import EntityCategory
@ -52,7 +51,7 @@ async def test_aqara_gateway_setup(hass):
"light.aqara_hub_1563",
friendly_name="Aqara Hub-1563",
unique_id="homekit-0000000123456789-65792",
supported_features=SUPPORT_BRIGHTNESS | SUPPORT_COLOR,
supported_features=0,
capabilities={"supported_color_modes": ["hs"]},
state="off",
),

View File

@ -1,6 +1,5 @@
"""Make sure that an Arlo Baby can be setup."""
from homeassistant.components.light import SUPPORT_BRIGHTNESS, SUPPORT_COLOR
from homeassistant.components.sensor import SensorStateClass
from homeassistant.const import PERCENTAGE, TEMP_CELSIUS
@ -75,7 +74,7 @@ async def test_arlo_baby_setup(hass):
entity_id="light.arlobabya0",
unique_id="homekit-00A0000000000-1100",
friendly_name="ArloBabyA0",
supported_features=SUPPORT_BRIGHTNESS | SUPPORT_COLOR,
supported_features=0,
capabilities={"supported_color_modes": ["hs"]},
state="off",
),

View File

@ -8,7 +8,6 @@ from aiohomekit.model import CharacteristicsTypes, ServicesTypes
from aiohomekit.testing import FakePairing
import pytest
from homeassistant.components.light import SUPPORT_BRIGHTNESS, SUPPORT_COLOR
from homeassistant.helpers.entity import EntityCategory
import homeassistant.util.dt as dt_util
@ -47,7 +46,7 @@ async def test_koogeek_ls1_setup(hass):
entity_id="light.koogeek_ls1_20833f",
friendly_name="Koogeek-LS1-20833F",
unique_id="homekit-AAAA011111111111-7",
supported_features=SUPPORT_BRIGHTNESS | SUPPORT_COLOR,
supported_features=0,
capabilities={"supported_color_modes": ["hs"]},
state="off",
),

View File

@ -1,7 +1,6 @@
"""Make sure that Mysa Living is enumerated properly."""
from homeassistant.components.climate import SUPPORT_TARGET_TEMPERATURE
from homeassistant.components.light import SUPPORT_BRIGHTNESS
from homeassistant.components.sensor import SensorStateClass
from homeassistant.const import PERCENTAGE, TEMP_CELSIUS
@ -64,7 +63,7 @@ async def test_mysa_living_setup(hass):
entity_id="light.mysa_85dda9",
friendly_name="Mysa-85dda9",
unique_id="homekit-AAAAAAA000-40",
supported_features=SUPPORT_BRIGHTNESS,
supported_features=0,
capabilities={"supported_color_modes": ["brightness"]},
state="off",
),

View File

@ -1,7 +1,6 @@
"""Make sure that Vocolinc Flowerbud is enumerated properly."""
from homeassistant.components.humidifier.const import SUPPORT_MODES
from homeassistant.components.light import SUPPORT_BRIGHTNESS, SUPPORT_COLOR
from homeassistant.components.number import NumberMode
from homeassistant.components.sensor import SensorStateClass
from homeassistant.const import PERCENTAGE
@ -50,7 +49,7 @@ async def test_vocolinc_flowerbud_setup(hass):
entity_id="light.vocolinc_flowerbud_0d324b",
friendly_name="VOCOlinc-Flowerbud-0d324b",
unique_id="homekit-AM01121849000327-9",
supported_features=SUPPORT_BRIGHTNESS | SUPPORT_COLOR,
supported_features=0,
capabilities={"supported_color_modes": ["hs"]},
state="on",
),

View File

@ -250,7 +250,7 @@ async def test_config_entry(hass: HomeAssistant, hass_client: ClientSession, utc
"attributes": {
"supported_color_modes": ["hs"],
"friendly_name": "Koogeek-LS1-20833F",
"supported_features": 17,
"supported_features": 0,
},
"last_changed": "2023-01-01T00:00:00+00:00",
"last_updated": "2023-01-01T00:00:00+00:00",
@ -520,7 +520,7 @@ async def test_device(hass: HomeAssistant, hass_client: ClientSession, utcnow):
"attributes": {
"supported_color_modes": ["hs"],
"friendly_name": "Koogeek-LS1-20833F",
"supported_features": 17,
"supported_features": 0,
},
"last_changed": "2023-01-01T00:00:00+00:00",
"last_updated": "2023-01-01T00:00:00+00:00",

View File

@ -3,7 +3,14 @@ from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.services import ServicesTypes
from homeassistant.components.homekit_controller.const import KNOWN_DEVICES
from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.components.light import (
ATTR_COLOR_MODE,
ATTR_SUPPORTED_COLOR_MODES,
COLOR_MODE_BRIGHTNESS,
COLOR_MODE_COLOR_TEMP,
COLOR_MODE_HS,
)
from homeassistant.const import ATTR_SUPPORTED_FEATURES, STATE_UNAVAILABLE
from tests.components.homekit_controller.common import setup_test_component
@ -98,13 +105,79 @@ async def test_switch_change_light_state_color_temp(hass, utcnow):
)
async def test_switch_read_light_state(hass, utcnow):
async def test_switch_read_light_state_dimmer(hass, utcnow):
"""Test that we can read the state of a HomeKit light accessory."""
helper = await setup_test_component(hass, create_lightbulb_service)
# Initial state is that the light is off
state = await helper.poll_and_get_state()
assert state.state == "off"
assert ATTR_COLOR_MODE not in state.attributes
assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == [COLOR_MODE_BRIGHTNESS]
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 0
# Simulate that someone switched on the device in the real world not via HA
state = await helper.async_update(
ServicesTypes.LIGHTBULB,
{
CharacteristicsTypes.ON: True,
CharacteristicsTypes.BRIGHTNESS: 100,
},
)
assert state.state == "on"
assert state.attributes["brightness"] == 255
assert state.attributes[ATTR_COLOR_MODE] == COLOR_MODE_BRIGHTNESS
assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == [COLOR_MODE_BRIGHTNESS]
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 0
# Simulate that device switched off in the real world not via HA
state = await helper.async_update(
ServicesTypes.LIGHTBULB,
{
CharacteristicsTypes.ON: False,
},
)
assert state.state == "off"
async def test_switch_push_light_state_dimmer(hass, utcnow):
"""Test that we can read the state of a HomeKit light accessory."""
helper = await setup_test_component(hass, create_lightbulb_service)
# Initial state is that the light is off
state = hass.states.get(LIGHT_BULB_ENTITY_ID)
assert state.state == "off"
state = await helper.async_update(
ServicesTypes.LIGHTBULB,
{
CharacteristicsTypes.ON: True,
CharacteristicsTypes.BRIGHTNESS: 100,
},
)
assert state.state == "on"
assert state.attributes["brightness"] == 255
# Simulate that device switched off in the real world not via HA
state = await helper.async_update(
ServicesTypes.LIGHTBULB,
{
CharacteristicsTypes.ON: False,
},
)
assert state.state == "off"
async def test_switch_read_light_state_hs(hass, utcnow):
"""Test that we can read the state of a HomeKit light accessory."""
helper = await setup_test_component(hass, create_lightbulb_service_with_hs)
# Initial state is that the light is off
state = await helper.poll_and_get_state()
assert state.state == "off"
assert ATTR_COLOR_MODE not in state.attributes
assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == [COLOR_MODE_HS]
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 0
# Simulate that someone switched on the device in the real world not via HA
state = await helper.async_update(
@ -119,6 +192,9 @@ async def test_switch_read_light_state(hass, utcnow):
assert state.state == "on"
assert state.attributes["brightness"] == 255
assert state.attributes["hs_color"] == (4, 5)
assert state.attributes[ATTR_COLOR_MODE] == COLOR_MODE_HS
assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == [COLOR_MODE_HS]
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 0
# Simulate that device switched off in the real world not via HA
state = await helper.async_update(
@ -130,7 +206,7 @@ async def test_switch_read_light_state(hass, utcnow):
assert state.state == "off"
async def test_switch_push_light_state(hass, utcnow):
async def test_switch_push_light_state_hs(hass, utcnow):
"""Test that we can read the state of a HomeKit light accessory."""
helper = await setup_test_component(hass, create_lightbulb_service_with_hs)
@ -168,6 +244,9 @@ async def test_switch_read_light_state_color_temp(hass, utcnow):
# Initial state is that the light is off
state = await helper.poll_and_get_state()
assert state.state == "off"
assert ATTR_COLOR_MODE not in state.attributes
assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == [COLOR_MODE_COLOR_TEMP]
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 0
# Simulate that someone switched on the device in the real world not via HA
state = await helper.async_update(
@ -181,6 +260,9 @@ async def test_switch_read_light_state_color_temp(hass, utcnow):
assert state.state == "on"
assert state.attributes["brightness"] == 255
assert state.attributes["color_temp"] == 400
assert state.attributes[ATTR_COLOR_MODE] == COLOR_MODE_COLOR_TEMP
assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == [COLOR_MODE_COLOR_TEMP]
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 0
async def test_switch_push_light_state_color_temp(hass, utcnow):