mirror of
https://github.com/home-assistant/core.git
synced 2025-04-26 02:07:54 +00:00
Fix flux_led with RGB/W bulbs (model 0x44) (#58438)
This commit is contained in:
parent
207a5029e8
commit
3732ae738e
@ -30,12 +30,14 @@ from homeassistant.components.light import (
|
|||||||
ATTR_RGB_COLOR,
|
ATTR_RGB_COLOR,
|
||||||
ATTR_RGBW_COLOR,
|
ATTR_RGBW_COLOR,
|
||||||
ATTR_RGBWW_COLOR,
|
ATTR_RGBWW_COLOR,
|
||||||
|
ATTR_WHITE,
|
||||||
COLOR_MODE_BRIGHTNESS,
|
COLOR_MODE_BRIGHTNESS,
|
||||||
COLOR_MODE_COLOR_TEMP,
|
COLOR_MODE_COLOR_TEMP,
|
||||||
COLOR_MODE_ONOFF,
|
COLOR_MODE_ONOFF,
|
||||||
COLOR_MODE_RGB,
|
COLOR_MODE_RGB,
|
||||||
COLOR_MODE_RGBW,
|
COLOR_MODE_RGBW,
|
||||||
COLOR_MODE_RGBWW,
|
COLOR_MODE_RGBWW,
|
||||||
|
COLOR_MODE_WHITE,
|
||||||
EFFECT_COLORLOOP,
|
EFFECT_COLORLOOP,
|
||||||
EFFECT_RANDOM,
|
EFFECT_RANDOM,
|
||||||
PLATFORM_SCHEMA,
|
PLATFORM_SCHEMA,
|
||||||
@ -100,7 +102,6 @@ FLUX_COLOR_MODE_TO_HASS: Final = {
|
|||||||
FLUX_COLOR_MODE_RGBW: COLOR_MODE_RGBW,
|
FLUX_COLOR_MODE_RGBW: COLOR_MODE_RGBW,
|
||||||
FLUX_COLOR_MODE_RGBWW: COLOR_MODE_RGBWW,
|
FLUX_COLOR_MODE_RGBWW: COLOR_MODE_RGBWW,
|
||||||
FLUX_COLOR_MODE_CCT: COLOR_MODE_COLOR_TEMP,
|
FLUX_COLOR_MODE_CCT: COLOR_MODE_COLOR_TEMP,
|
||||||
FLUX_COLOR_MODE_DIM: COLOR_MODE_BRIGHTNESS,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EFFECT_SUPPORT_MODES = {COLOR_MODE_RGB, COLOR_MODE_RGBW, COLOR_MODE_RGBWW}
|
EFFECT_SUPPORT_MODES = {COLOR_MODE_RGB, COLOR_MODE_RGBW, COLOR_MODE_RGBWW}
|
||||||
@ -195,6 +196,15 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _flux_color_mode_to_hass(flux_color_mode: str, flux_color_modes: set[str]) -> str:
|
||||||
|
"""Map the flux color mode to Home Assistant color mode."""
|
||||||
|
if flux_color_mode == FLUX_COLOR_MODE_DIM:
|
||||||
|
if len(flux_color_modes) > 1:
|
||||||
|
return COLOR_MODE_WHITE
|
||||||
|
return COLOR_MODE_BRIGHTNESS
|
||||||
|
return FLUX_COLOR_MODE_TO_HASS.get(flux_color_mode, COLOR_MODE_ONOFF)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
@ -300,7 +310,7 @@ class FluxLight(FluxEntity, CoordinatorEntity, LightEntity):
|
|||||||
) # for rounding
|
) # for rounding
|
||||||
self._attr_max_mireds = color_temperature_kelvin_to_mired(self._device.min_temp)
|
self._attr_max_mireds = color_temperature_kelvin_to_mired(self._device.min_temp)
|
||||||
self._attr_supported_color_modes = {
|
self._attr_supported_color_modes = {
|
||||||
FLUX_COLOR_MODE_TO_HASS.get(mode, COLOR_MODE_ONOFF)
|
_flux_color_mode_to_hass(mode, self._device.color_modes)
|
||||||
for mode in self._device.color_modes
|
for mode in self._device.color_modes
|
||||||
}
|
}
|
||||||
if self._attr_supported_color_modes.intersection(EFFECT_SUPPORT_MODES):
|
if self._attr_supported_color_modes.intersection(EFFECT_SUPPORT_MODES):
|
||||||
@ -352,7 +362,9 @@ class FluxLight(FluxEntity, CoordinatorEntity, LightEntity):
|
|||||||
@property
|
@property
|
||||||
def color_mode(self) -> str:
|
def color_mode(self) -> str:
|
||||||
"""Return the color mode of the light."""
|
"""Return the color mode of the light."""
|
||||||
return FLUX_COLOR_MODE_TO_HASS.get(self._device.color_mode, COLOR_MODE_ONOFF)
|
return _flux_color_mode_to_hass(
|
||||||
|
self._device.color_mode, self._device.color_modes
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def effect(self) -> str | None:
|
def effect(self) -> str | None:
|
||||||
@ -410,6 +422,9 @@ class FluxLight(FluxEntity, CoordinatorEntity, LightEntity):
|
|||||||
rgbcw = kwargs[ATTR_RGBWW_COLOR]
|
rgbcw = kwargs[ATTR_RGBWW_COLOR]
|
||||||
await self._device.async_set_levels(*rgbcw_to_rgbwc(rgbcw))
|
await self._device.async_set_levels(*rgbcw_to_rgbwc(rgbcw))
|
||||||
return
|
return
|
||||||
|
if ATTR_WHITE in kwargs:
|
||||||
|
await self._device.async_set_levels(w=kwargs[ATTR_WHITE])
|
||||||
|
return
|
||||||
if ATTR_EFFECT in kwargs:
|
if ATTR_EFFECT in kwargs:
|
||||||
effect = kwargs[ATTR_EFFECT]
|
effect = kwargs[ATTR_EFFECT]
|
||||||
# Random color effect
|
# Random color effect
|
||||||
@ -456,7 +471,7 @@ class FluxLight(FluxEntity, CoordinatorEntity, LightEntity):
|
|||||||
await self._device.async_set_levels(*rgbww_brightness(rgbwc, brightness))
|
await self._device.async_set_levels(*rgbww_brightness(rgbwc, brightness))
|
||||||
return
|
return
|
||||||
# Handle Brightness Only Color Mode
|
# Handle Brightness Only Color Mode
|
||||||
if self.color_mode == COLOR_MODE_BRIGHTNESS:
|
if self.color_mode in {COLOR_MODE_WHITE, COLOR_MODE_BRIGHTNESS}:
|
||||||
await self._device.async_set_levels(w=brightness)
|
await self._device.async_set_levels(w=brightness)
|
||||||
return
|
return
|
||||||
raise ValueError(f"Unsupported color mode {self.color_mode}")
|
raise ValueError(f"Unsupported color mode {self.color_mode}")
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Flux LED/MagicHome",
|
"name": "Flux LED/MagicHome",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/flux_led",
|
"documentation": "https://www.home-assistant.io/integrations/flux_led",
|
||||||
"requirements": ["flux_led==0.24.12"],
|
"requirements": ["flux_led==0.24.13"],
|
||||||
"quality_scale": "platinum",
|
"quality_scale": "platinum",
|
||||||
"codeowners": ["@icemanch"],
|
"codeowners": ["@icemanch"],
|
||||||
"iot_class": "local_push",
|
"iot_class": "local_push",
|
||||||
|
@ -655,7 +655,7 @@ fjaraskupan==1.0.2
|
|||||||
flipr-api==1.4.1
|
flipr-api==1.4.1
|
||||||
|
|
||||||
# homeassistant.components.flux_led
|
# homeassistant.components.flux_led
|
||||||
flux_led==0.24.12
|
flux_led==0.24.13
|
||||||
|
|
||||||
# homeassistant.components.homekit
|
# homeassistant.components.homekit
|
||||||
fnvhash==0.1.0
|
fnvhash==0.1.0
|
||||||
|
@ -390,7 +390,7 @@ fjaraskupan==1.0.2
|
|||||||
flipr-api==1.4.1
|
flipr-api==1.4.1
|
||||||
|
|
||||||
# homeassistant.components.flux_led
|
# homeassistant.components.flux_led
|
||||||
flux_led==0.24.12
|
flux_led==0.24.13
|
||||||
|
|
||||||
# homeassistant.components.homekit
|
# homeassistant.components.homekit
|
||||||
fnvhash==0.1.0
|
fnvhash==0.1.0
|
||||||
|
@ -9,6 +9,7 @@ from flux_led.const import (
|
|||||||
COLOR_MODE_RGB as FLUX_COLOR_MODE_RGB,
|
COLOR_MODE_RGB as FLUX_COLOR_MODE_RGB,
|
||||||
COLOR_MODE_RGBW as FLUX_COLOR_MODE_RGBW,
|
COLOR_MODE_RGBW as FLUX_COLOR_MODE_RGBW,
|
||||||
COLOR_MODE_RGBWW as FLUX_COLOR_MODE_RGBWW,
|
COLOR_MODE_RGBWW as FLUX_COLOR_MODE_RGBWW,
|
||||||
|
COLOR_MODES_RGB_W as FLUX_COLOR_MODES_RGB_W,
|
||||||
)
|
)
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@ -38,6 +39,7 @@ from homeassistant.components.light import (
|
|||||||
ATTR_RGBW_COLOR,
|
ATTR_RGBW_COLOR,
|
||||||
ATTR_RGBWW_COLOR,
|
ATTR_RGBWW_COLOR,
|
||||||
ATTR_SUPPORTED_COLOR_MODES,
|
ATTR_SUPPORTED_COLOR_MODES,
|
||||||
|
ATTR_WHITE,
|
||||||
DOMAIN as LIGHT_DOMAIN,
|
DOMAIN as LIGHT_DOMAIN,
|
||||||
)
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
@ -485,6 +487,116 @@ async def test_rgbw_light(hass: HomeAssistant) -> None:
|
|||||||
bulb.async_set_preset_pattern.reset_mock()
|
bulb.async_set_preset_pattern.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
async def test_rgb_or_w_light(hass: HomeAssistant) -> None:
|
||||||
|
"""Test an rgb or w light."""
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
data={CONF_HOST: IP_ADDRESS, CONF_NAME: DEFAULT_ENTRY_TITLE},
|
||||||
|
unique_id=MAC_ADDRESS,
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
bulb = _mocked_bulb()
|
||||||
|
bulb.color_modes = FLUX_COLOR_MODES_RGB_W
|
||||||
|
bulb.color_mode = FLUX_COLOR_MODE_RGB
|
||||||
|
with _patch_discovery(device=bulb), _patch_wifibulb(device=bulb):
|
||||||
|
await async_setup_component(hass, flux_led.DOMAIN, {flux_led.DOMAIN: {}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
entity_id = "light.az120444_aabbccddeeff"
|
||||||
|
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
attributes = state.attributes
|
||||||
|
assert attributes[ATTR_BRIGHTNESS] == 128
|
||||||
|
assert attributes[ATTR_COLOR_MODE] == "rgb"
|
||||||
|
assert attributes[ATTR_EFFECT_LIST] == FLUX_EFFECT_LIST
|
||||||
|
assert attributes[ATTR_SUPPORTED_COLOR_MODES] == ["rgb", "white"]
|
||||||
|
assert attributes[ATTR_RGB_COLOR] == (255, 0, 0)
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
LIGHT_DOMAIN, "turn_off", {ATTR_ENTITY_ID: entity_id}, blocking=True
|
||||||
|
)
|
||||||
|
bulb.async_turn_off.assert_called_once()
|
||||||
|
await async_mock_device_turn_off(hass, bulb)
|
||||||
|
|
||||||
|
assert hass.states.get(entity_id).state == STATE_OFF
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
LIGHT_DOMAIN, "turn_on", {ATTR_ENTITY_ID: entity_id}, blocking=True
|
||||||
|
)
|
||||||
|
bulb.async_turn_on.assert_called_once()
|
||||||
|
bulb.async_turn_on.reset_mock()
|
||||||
|
bulb.is_on = True
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
LIGHT_DOMAIN,
|
||||||
|
"turn_on",
|
||||||
|
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 100},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
bulb.async_set_levels.assert_called_with(255, 0, 0, brightness=100)
|
||||||
|
bulb.async_set_levels.reset_mock()
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
LIGHT_DOMAIN,
|
||||||
|
"turn_on",
|
||||||
|
{
|
||||||
|
ATTR_ENTITY_ID: entity_id,
|
||||||
|
ATTR_RGB_COLOR: (255, 255, 255),
|
||||||
|
ATTR_BRIGHTNESS: 128,
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
bulb.async_set_levels.assert_called_with(255, 255, 255, brightness=128)
|
||||||
|
bulb.async_set_levels.reset_mock()
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
LIGHT_DOMAIN,
|
||||||
|
"turn_on",
|
||||||
|
{ATTR_ENTITY_ID: entity_id, ATTR_EFFECT: "random"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
bulb.async_set_levels.assert_called_once()
|
||||||
|
bulb.async_set_levels.reset_mock()
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
LIGHT_DOMAIN,
|
||||||
|
"turn_on",
|
||||||
|
{ATTR_ENTITY_ID: entity_id, ATTR_EFFECT: "purple_fade"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
bulb.async_set_preset_pattern.assert_called_with(43, 50)
|
||||||
|
bulb.async_set_preset_pattern.reset_mock()
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
LIGHT_DOMAIN,
|
||||||
|
"turn_on",
|
||||||
|
{
|
||||||
|
ATTR_ENTITY_ID: entity_id,
|
||||||
|
ATTR_WHITE: 128,
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
bulb.async_set_levels.assert_called_with(w=128)
|
||||||
|
bulb.async_set_levels.reset_mock()
|
||||||
|
|
||||||
|
bulb.color_mode = FLUX_COLOR_MODE_DIM
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
LIGHT_DOMAIN,
|
||||||
|
"turn_on",
|
||||||
|
{
|
||||||
|
ATTR_ENTITY_ID: entity_id,
|
||||||
|
ATTR_BRIGHTNESS: 100,
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
bulb.async_set_levels.assert_called_with(w=100)
|
||||||
|
bulb.async_set_levels.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
async def test_rgbcw_light(hass: HomeAssistant) -> None:
|
async def test_rgbcw_light(hass: HomeAssistant) -> None:
|
||||||
"""Test an rgbcw light."""
|
"""Test an rgbcw light."""
|
||||||
config_entry = MockConfigEntry(
|
config_entry = MockConfigEntry(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user