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
|
||||
|
||||
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 (
|
||||
ATTR_BRIGHTNESS,
|
||||
ATTR_COLOR_MODE,
|
||||
ATTR_COLOR_TEMP_KELVIN,
|
||||
ATTR_HS_COLOR,
|
||||
ATTR_TRANSITION,
|
||||
|
@ -19,6 +20,7 @@ from homeassistant.components.light import (
|
|||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.helpers.restore_state import RestoreEntity
|
||||
|
||||
from . import FullDevice, SmartThingsConfigEntry
|
||||
from .const import MAIN
|
||||
|
@ -53,7 +55,7 @@ def convert_scale(
|
|||
return round(value * target_scale / value_scale, round_digits)
|
||||
|
||||
|
||||
class SmartThingsLight(SmartThingsEntity, LightEntity):
|
||||
class SmartThingsLight(SmartThingsEntity, LightEntity, RestoreEntity):
|
||||
"""Define a SmartThings Light."""
|
||||
|
||||
_attr_name = None
|
||||
|
@ -84,18 +86,28 @@ class SmartThingsLight(SmartThingsEntity, LightEntity):
|
|||
color_modes = set()
|
||||
if self.supports_capability(Capability.COLOR_TEMPERATURE):
|
||||
color_modes.add(ColorMode.COLOR_TEMP)
|
||||
self._attr_color_mode = ColorMode.COLOR_TEMP
|
||||
if self.supports_capability(Capability.COLOR_CONTROL):
|
||||
color_modes.add(ColorMode.HS)
|
||||
self._attr_color_mode = ColorMode.HS
|
||||
if not color_modes and self.supports_capability(Capability.SWITCH_LEVEL):
|
||||
color_modes.add(ColorMode.BRIGHTNESS)
|
||||
if not color_modes:
|
||||
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
|
||||
features = LightEntityFeature(0)
|
||||
if self.supports_capability(Capability.SWITCH_LEVEL):
|
||||
features |= LightEntityFeature.TRANSITION
|
||||
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:
|
||||
"""Turn the light on."""
|
||||
tasks = []
|
||||
|
@ -195,17 +207,14 @@ class SmartThingsLight(SmartThingsEntity, LightEntity):
|
|||
argument=[level, duration],
|
||||
)
|
||||
|
||||
@property
|
||||
def color_mode(self) -> ColorMode:
|
||||
"""Return the color mode of the light."""
|
||||
if len(self._attr_supported_color_modes) == 1:
|
||||
# The light supports only a single color mode
|
||||
return list(self._attr_supported_color_modes)[0]
|
||||
|
||||
# The light supports hs + color temp, determine which one it is
|
||||
if self._attr_hs_color and self._attr_hs_color[1]:
|
||||
return ColorMode.HS
|
||||
return ColorMode.COLOR_TEMP
|
||||
def _update_handler(self, event: DeviceEvent) -> None:
|
||||
"""Handle device updates."""
|
||||
if event.capability in (Capability.COLOR_CONTROL, Capability.COLOR_TEMPERATURE):
|
||||
self._attr_color_mode = {
|
||||
Capability.COLOR_CONTROL: ColorMode.HS,
|
||||
Capability.COLOR_TEMPERATURE: ColorMode.COLOR_TEMP,
|
||||
}[cast(Capability, event.capability)]
|
||||
super()._update_handler(event)
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
|
|
|
@ -12,7 +12,12 @@ from homeassistant.components.light import (
|
|||
ATTR_COLOR_MODE,
|
||||
ATTR_COLOR_TEMP_KELVIN,
|
||||
ATTR_HS_COLOR,
|
||||
ATTR_MAX_COLOR_TEMP_KELVIN,
|
||||
ATTR_MIN_COLOR_TEMP_KELVIN,
|
||||
ATTR_RGB_COLOR,
|
||||
ATTR_SUPPORTED_COLOR_MODES,
|
||||
ATTR_TRANSITION,
|
||||
ATTR_XY_COLOR,
|
||||
DOMAIN as LIGHT_DOMAIN,
|
||||
ColorMode,
|
||||
)
|
||||
|
@ -25,7 +30,7 @@ from homeassistant.const import (
|
|||
STATE_ON,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, State
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from . import (
|
||||
|
@ -35,7 +40,7 @@ from . import (
|
|||
trigger_update,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.common import MockConfigEntry, mock_restore_cache_with_extra_data
|
||||
|
||||
|
||||
async def test_all_entities(
|
||||
|
@ -228,6 +233,15 @@ async def test_updating_brightness(
|
|||
set_attribute_value(devices, Capability.SWITCH, Attribute.SWITCH, "on")
|
||||
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
|
||||
|
||||
await trigger_update(
|
||||
|
@ -252,8 +266,17 @@ async def test_updating_hs(
|
|||
set_attribute_value(devices, Capability.SWITCH, Attribute.SWITCH, "on")
|
||||
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] == (
|
||||
218.906,
|
||||
144.0,
|
||||
60,
|
||||
)
|
||||
|
||||
|
@ -280,9 +303,17 @@ async def test_updating_color_temp(
|
|||
) -> None:
|
||||
"""Test color temperature update."""
|
||||
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 trigger_update(
|
||||
hass,
|
||||
devices,
|
||||
"cb958955-b015-498c-9e62-fc0c51abd054",
|
||||
Capability.COLOR_TEMPERATURE,
|
||||
Attribute.COLOR_TEMPERATURE,
|
||||
3000,
|
||||
)
|
||||
|
||||
assert (
|
||||
hass.states.get("light.standing_light").attributes[ATTR_COLOR_MODE]
|
||||
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]
|
||||
== 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