Use last event as color mode in SmartThings (#139473)
* Use last event as color mode in SmartThings * Use last event as color mode in SmartThings * Fixpull/125870/merge
parent
39bc37d225
commit
455363871f
|
@ -3,12 +3,13 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from typing import Any
|
from typing import Any, cast
|
||||||
|
|
||||||
from pysmartthings import Attribute, Capability, Command, SmartThings
|
from pysmartthings import Attribute, Capability, Command, DeviceEvent, SmartThings
|
||||||
|
|
||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
ATTR_BRIGHTNESS,
|
ATTR_BRIGHTNESS,
|
||||||
|
ATTR_COLOR_MODE,
|
||||||
ATTR_COLOR_TEMP_KELVIN,
|
ATTR_COLOR_TEMP_KELVIN,
|
||||||
ATTR_HS_COLOR,
|
ATTR_HS_COLOR,
|
||||||
ATTR_TRANSITION,
|
ATTR_TRANSITION,
|
||||||
|
@ -19,6 +20,7 @@ from homeassistant.components.light import (
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
|
from homeassistant.helpers.restore_state import RestoreEntity
|
||||||
|
|
||||||
from . import FullDevice, SmartThingsConfigEntry
|
from . import FullDevice, SmartThingsConfigEntry
|
||||||
from .const import MAIN
|
from .const import MAIN
|
||||||
|
@ -53,7 +55,7 @@ def convert_scale(
|
||||||
return round(value * target_scale / value_scale, round_digits)
|
return round(value * target_scale / value_scale, round_digits)
|
||||||
|
|
||||||
|
|
||||||
class SmartThingsLight(SmartThingsEntity, LightEntity):
|
class SmartThingsLight(SmartThingsEntity, LightEntity, RestoreEntity):
|
||||||
"""Define a SmartThings Light."""
|
"""Define a SmartThings Light."""
|
||||||
|
|
||||||
_attr_name = None
|
_attr_name = None
|
||||||
|
@ -84,18 +86,28 @@ class SmartThingsLight(SmartThingsEntity, LightEntity):
|
||||||
color_modes = set()
|
color_modes = set()
|
||||||
if self.supports_capability(Capability.COLOR_TEMPERATURE):
|
if self.supports_capability(Capability.COLOR_TEMPERATURE):
|
||||||
color_modes.add(ColorMode.COLOR_TEMP)
|
color_modes.add(ColorMode.COLOR_TEMP)
|
||||||
|
self._attr_color_mode = ColorMode.COLOR_TEMP
|
||||||
if self.supports_capability(Capability.COLOR_CONTROL):
|
if self.supports_capability(Capability.COLOR_CONTROL):
|
||||||
color_modes.add(ColorMode.HS)
|
color_modes.add(ColorMode.HS)
|
||||||
|
self._attr_color_mode = ColorMode.HS
|
||||||
if not color_modes and self.supports_capability(Capability.SWITCH_LEVEL):
|
if not color_modes and self.supports_capability(Capability.SWITCH_LEVEL):
|
||||||
color_modes.add(ColorMode.BRIGHTNESS)
|
color_modes.add(ColorMode.BRIGHTNESS)
|
||||||
if not color_modes:
|
if not color_modes:
|
||||||
color_modes.add(ColorMode.ONOFF)
|
color_modes.add(ColorMode.ONOFF)
|
||||||
|
if len(color_modes) == 1:
|
||||||
|
self._attr_color_mode = list(color_modes)[0]
|
||||||
self._attr_supported_color_modes = color_modes
|
self._attr_supported_color_modes = color_modes
|
||||||
features = LightEntityFeature(0)
|
features = LightEntityFeature(0)
|
||||||
if self.supports_capability(Capability.SWITCH_LEVEL):
|
if self.supports_capability(Capability.SWITCH_LEVEL):
|
||||||
features |= LightEntityFeature.TRANSITION
|
features |= LightEntityFeature.TRANSITION
|
||||||
self._attr_supported_features = features
|
self._attr_supported_features = features
|
||||||
|
|
||||||
|
async def async_added_to_hass(self) -> None:
|
||||||
|
"""Run when entity about to be added to hass."""
|
||||||
|
await super().async_added_to_hass()
|
||||||
|
if (last_state := await self.async_get_last_extra_data()) is not None:
|
||||||
|
self._attr_color_mode = last_state.as_dict()[ATTR_COLOR_MODE]
|
||||||
|
|
||||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||||
"""Turn the light on."""
|
"""Turn the light on."""
|
||||||
tasks = []
|
tasks = []
|
||||||
|
@ -195,17 +207,14 @@ class SmartThingsLight(SmartThingsEntity, LightEntity):
|
||||||
argument=[level, duration],
|
argument=[level, duration],
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
def _update_handler(self, event: DeviceEvent) -> None:
|
||||||
def color_mode(self) -> ColorMode:
|
"""Handle device updates."""
|
||||||
"""Return the color mode of the light."""
|
if event.capability in (Capability.COLOR_CONTROL, Capability.COLOR_TEMPERATURE):
|
||||||
if len(self._attr_supported_color_modes) == 1:
|
self._attr_color_mode = {
|
||||||
# The light supports only a single color mode
|
Capability.COLOR_CONTROL: ColorMode.HS,
|
||||||
return list(self._attr_supported_color_modes)[0]
|
Capability.COLOR_TEMPERATURE: ColorMode.COLOR_TEMP,
|
||||||
|
}[cast(Capability, event.capability)]
|
||||||
# The light supports hs + color temp, determine which one it is
|
super()._update_handler(event)
|
||||||
if self._attr_hs_color and self._attr_hs_color[1]:
|
|
||||||
return ColorMode.HS
|
|
||||||
return ColorMode.COLOR_TEMP
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self) -> bool:
|
def is_on(self) -> bool:
|
||||||
|
|
|
@ -12,7 +12,12 @@ from homeassistant.components.light import (
|
||||||
ATTR_COLOR_MODE,
|
ATTR_COLOR_MODE,
|
||||||
ATTR_COLOR_TEMP_KELVIN,
|
ATTR_COLOR_TEMP_KELVIN,
|
||||||
ATTR_HS_COLOR,
|
ATTR_HS_COLOR,
|
||||||
|
ATTR_MAX_COLOR_TEMP_KELVIN,
|
||||||
|
ATTR_MIN_COLOR_TEMP_KELVIN,
|
||||||
|
ATTR_RGB_COLOR,
|
||||||
|
ATTR_SUPPORTED_COLOR_MODES,
|
||||||
ATTR_TRANSITION,
|
ATTR_TRANSITION,
|
||||||
|
ATTR_XY_COLOR,
|
||||||
DOMAIN as LIGHT_DOMAIN,
|
DOMAIN as LIGHT_DOMAIN,
|
||||||
ColorMode,
|
ColorMode,
|
||||||
)
|
)
|
||||||
|
@ -25,7 +30,7 @@ from homeassistant.const import (
|
||||||
STATE_ON,
|
STATE_ON,
|
||||||
Platform,
|
Platform,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant, State
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
|
||||||
from . import (
|
from . import (
|
||||||
|
@ -35,7 +40,7 @@ from . import (
|
||||||
trigger_update,
|
trigger_update,
|
||||||
)
|
)
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry, mock_restore_cache_with_extra_data
|
||||||
|
|
||||||
|
|
||||||
async def test_all_entities(
|
async def test_all_entities(
|
||||||
|
@ -228,6 +233,15 @@ async def test_updating_brightness(
|
||||||
set_attribute_value(devices, Capability.SWITCH, Attribute.SWITCH, "on")
|
set_attribute_value(devices, Capability.SWITCH, Attribute.SWITCH, "on")
|
||||||
await setup_integration(hass, mock_config_entry)
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
|
await trigger_update(
|
||||||
|
hass,
|
||||||
|
devices,
|
||||||
|
"cb958955-b015-498c-9e62-fc0c51abd054",
|
||||||
|
Capability.COLOR_CONTROL,
|
||||||
|
Attribute.HUE,
|
||||||
|
40,
|
||||||
|
)
|
||||||
|
|
||||||
assert hass.states.get("light.standing_light").attributes[ATTR_BRIGHTNESS] == 178
|
assert hass.states.get("light.standing_light").attributes[ATTR_BRIGHTNESS] == 178
|
||||||
|
|
||||||
await trigger_update(
|
await trigger_update(
|
||||||
|
@ -252,8 +266,17 @@ async def test_updating_hs(
|
||||||
set_attribute_value(devices, Capability.SWITCH, Attribute.SWITCH, "on")
|
set_attribute_value(devices, Capability.SWITCH, Attribute.SWITCH, "on")
|
||||||
await setup_integration(hass, mock_config_entry)
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
|
await trigger_update(
|
||||||
|
hass,
|
||||||
|
devices,
|
||||||
|
"cb958955-b015-498c-9e62-fc0c51abd054",
|
||||||
|
Capability.COLOR_CONTROL,
|
||||||
|
Attribute.HUE,
|
||||||
|
40,
|
||||||
|
)
|
||||||
|
|
||||||
assert hass.states.get("light.standing_light").attributes[ATTR_HS_COLOR] == (
|
assert hass.states.get("light.standing_light").attributes[ATTR_HS_COLOR] == (
|
||||||
218.906,
|
144.0,
|
||||||
60,
|
60,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -280,9 +303,17 @@ async def test_updating_color_temp(
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test color temperature update."""
|
"""Test color temperature update."""
|
||||||
set_attribute_value(devices, Capability.SWITCH, Attribute.SWITCH, "on")
|
set_attribute_value(devices, Capability.SWITCH, Attribute.SWITCH, "on")
|
||||||
set_attribute_value(devices, Capability.COLOR_CONTROL, Attribute.SATURATION, 0)
|
|
||||||
await setup_integration(hass, mock_config_entry)
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
|
await trigger_update(
|
||||||
|
hass,
|
||||||
|
devices,
|
||||||
|
"cb958955-b015-498c-9e62-fc0c51abd054",
|
||||||
|
Capability.COLOR_TEMPERATURE,
|
||||||
|
Attribute.COLOR_TEMPERATURE,
|
||||||
|
3000,
|
||||||
|
)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
hass.states.get("light.standing_light").attributes[ATTR_COLOR_MODE]
|
hass.states.get("light.standing_light").attributes[ATTR_COLOR_MODE]
|
||||||
is ColorMode.COLOR_TEMP
|
is ColorMode.COLOR_TEMP
|
||||||
|
@ -305,3 +336,80 @@ async def test_updating_color_temp(
|
||||||
hass.states.get("light.standing_light").attributes[ATTR_COLOR_TEMP_KELVIN]
|
hass.states.get("light.standing_light").attributes[ATTR_COLOR_TEMP_KELVIN]
|
||||||
== 2000
|
== 2000
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("device_fixture", ["hue_rgbw_color_bulb"])
|
||||||
|
async def test_color_modes(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
devices: AsyncMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test color mode changes."""
|
||||||
|
set_attribute_value(devices, Capability.SWITCH, Attribute.SWITCH, "on")
|
||||||
|
set_attribute_value(devices, Capability.COLOR_CONTROL, Attribute.SATURATION, 50)
|
||||||
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
hass.states.get("light.standing_light").attributes[ATTR_COLOR_MODE]
|
||||||
|
is ColorMode.HS
|
||||||
|
)
|
||||||
|
|
||||||
|
await trigger_update(
|
||||||
|
hass,
|
||||||
|
devices,
|
||||||
|
"cb958955-b015-498c-9e62-fc0c51abd054",
|
||||||
|
Capability.COLOR_TEMPERATURE,
|
||||||
|
Attribute.COLOR_TEMPERATURE,
|
||||||
|
2000,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
hass.states.get("light.standing_light").attributes[ATTR_COLOR_MODE]
|
||||||
|
is ColorMode.COLOR_TEMP
|
||||||
|
)
|
||||||
|
|
||||||
|
await trigger_update(
|
||||||
|
hass,
|
||||||
|
devices,
|
||||||
|
"cb958955-b015-498c-9e62-fc0c51abd054",
|
||||||
|
Capability.COLOR_CONTROL,
|
||||||
|
Attribute.HUE,
|
||||||
|
20,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
hass.states.get("light.standing_light").attributes[ATTR_COLOR_MODE]
|
||||||
|
is ColorMode.HS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("device_fixture", ["hue_rgbw_color_bulb"])
|
||||||
|
async def test_color_mode_after_startup(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
devices: AsyncMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test color mode after startup."""
|
||||||
|
set_attribute_value(devices, Capability.SWITCH, Attribute.SWITCH, "on")
|
||||||
|
|
||||||
|
RESTORE_DATA = {
|
||||||
|
ATTR_BRIGHTNESS: 178,
|
||||||
|
ATTR_COLOR_MODE: ColorMode.COLOR_TEMP,
|
||||||
|
ATTR_COLOR_TEMP_KELVIN: 3000,
|
||||||
|
ATTR_HS_COLOR: (144.0, 60),
|
||||||
|
ATTR_MAX_COLOR_TEMP_KELVIN: 9000,
|
||||||
|
ATTR_MIN_COLOR_TEMP_KELVIN: 2000,
|
||||||
|
ATTR_RGB_COLOR: (255, 128, 0),
|
||||||
|
ATTR_SUPPORTED_COLOR_MODES: [ColorMode.COLOR_TEMP, ColorMode.HS],
|
||||||
|
ATTR_XY_COLOR: (0.61, 0.35),
|
||||||
|
}
|
||||||
|
|
||||||
|
mock_restore_cache_with_extra_data(
|
||||||
|
hass, ((State("light.standing_light", STATE_ON), RESTORE_DATA),)
|
||||||
|
)
|
||||||
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
hass.states.get("light.standing_light").attributes[ATTR_COLOR_MODE]
|
||||||
|
is ColorMode.COLOR_TEMP
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue