655 lines
21 KiB
Python
655 lines
21 KiB
Python
|
"""Tests for light platform."""
|
||
|
from datetime import timedelta
|
||
|
|
||
|
import pytest
|
||
|
|
||
|
from homeassistant.components import flux_led
|
||
|
from homeassistant.components.flux_led.const import (
|
||
|
CONF_COLORS,
|
||
|
CONF_CUSTOM_EFFECT,
|
||
|
CONF_CUSTOM_EFFECT_COLORS,
|
||
|
CONF_CUSTOM_EFFECT_SPEED_PCT,
|
||
|
CONF_CUSTOM_EFFECT_TRANSITION,
|
||
|
CONF_DEVICES,
|
||
|
CONF_SPEED_PCT,
|
||
|
CONF_TRANSITION,
|
||
|
DOMAIN,
|
||
|
MODE_AUTO,
|
||
|
TRANSITION_JUMP,
|
||
|
)
|
||
|
from homeassistant.components.flux_led.light import EFFECT_CUSTOM_CODE, FLUX_EFFECT_LIST
|
||
|
from homeassistant.components.light import (
|
||
|
ATTR_BRIGHTNESS,
|
||
|
ATTR_COLOR_MODE,
|
||
|
ATTR_COLOR_TEMP,
|
||
|
ATTR_EFFECT,
|
||
|
ATTR_EFFECT_LIST,
|
||
|
ATTR_HS_COLOR,
|
||
|
ATTR_SUPPORTED_COLOR_MODES,
|
||
|
DOMAIN as LIGHT_DOMAIN,
|
||
|
)
|
||
|
from homeassistant.const import (
|
||
|
ATTR_ENTITY_ID,
|
||
|
CONF_HOST,
|
||
|
CONF_MODE,
|
||
|
CONF_NAME,
|
||
|
CONF_PLATFORM,
|
||
|
CONF_PROTOCOL,
|
||
|
STATE_OFF,
|
||
|
STATE_ON,
|
||
|
)
|
||
|
from homeassistant.core import HomeAssistant
|
||
|
from homeassistant.helpers import entity_registry as er
|
||
|
from homeassistant.setup import async_setup_component
|
||
|
from homeassistant.util.dt import utcnow
|
||
|
|
||
|
from . import (
|
||
|
DEFAULT_ENTRY_TITLE,
|
||
|
IP_ADDRESS,
|
||
|
MAC_ADDRESS,
|
||
|
_mocked_bulb,
|
||
|
_patch_discovery,
|
||
|
_patch_wifibulb,
|
||
|
)
|
||
|
|
||
|
from tests.common import MockConfigEntry, async_fire_time_changed
|
||
|
|
||
|
|
||
|
async def test_light_unique_id(hass: HomeAssistant) -> None:
|
||
|
"""Test a light unique id."""
|
||
|
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()
|
||
|
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"
|
||
|
entity_registry = er.async_get(hass)
|
||
|
assert entity_registry.async_get(entity_id).unique_id == MAC_ADDRESS
|
||
|
state = hass.states.get(entity_id)
|
||
|
assert state.state == STATE_ON
|
||
|
|
||
|
|
||
|
async def test_light_no_unique_id(hass: HomeAssistant) -> None:
|
||
|
"""Test a light without a unique id."""
|
||
|
config_entry = MockConfigEntry(
|
||
|
domain=DOMAIN, data={CONF_HOST: IP_ADDRESS, CONF_NAME: DEFAULT_ENTRY_TITLE}
|
||
|
)
|
||
|
config_entry.add_to_hass(hass)
|
||
|
bulb = _mocked_bulb()
|
||
|
with _patch_discovery(no_device=True), _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"
|
||
|
entity_registry = er.async_get(hass)
|
||
|
assert entity_registry.async_get(entity_id) is None
|
||
|
state = hass.states.get(entity_id)
|
||
|
assert state.state == STATE_ON
|
||
|
|
||
|
|
||
|
async def test_rgb_light(hass: HomeAssistant) -> None:
|
||
|
"""Test an rgb 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.rgbwcapable = False
|
||
|
bulb.protocol = None
|
||
|
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] == "hs"
|
||
|
assert attributes[ATTR_EFFECT_LIST] == FLUX_EFFECT_LIST
|
||
|
assert attributes[ATTR_SUPPORTED_COLOR_MODES] == ["hs"]
|
||
|
assert attributes[ATTR_HS_COLOR] == (0, 100)
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN, "turn_off", {ATTR_ENTITY_ID: entity_id}, blocking=True
|
||
|
)
|
||
|
bulb.turnOff.assert_called_once()
|
||
|
|
||
|
bulb.is_on = False
|
||
|
async_fire_time_changed(hass, utcnow() + timedelta(seconds=10))
|
||
|
await hass.async_block_till_done()
|
||
|
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.turnOn.assert_called_once()
|
||
|
bulb.turnOn.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 100},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setRgb.assert_called_with(255, 0, 0, brightness=100)
|
||
|
bulb.setRgb.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_HS_COLOR: (10, 30)},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setRgb.assert_called_with(255, 191, 178, brightness=128)
|
||
|
bulb.setRgb.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_EFFECT: "random"},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setRgb.assert_called_once()
|
||
|
bulb.setRgb.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_EFFECT: "purple_fade"},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setPresetPattern.assert_called_with(43, 50)
|
||
|
bulb.setPresetPattern.reset_mock()
|
||
|
|
||
|
|
||
|
async def test_rgbw_light(hass: HomeAssistant) -> None:
|
||
|
"""Test an rgbw 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()
|
||
|
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] == "rgbw"
|
||
|
assert attributes[ATTR_EFFECT_LIST] == FLUX_EFFECT_LIST
|
||
|
assert attributes[ATTR_SUPPORTED_COLOR_MODES] == ["color_temp", "hs", "rgbw"]
|
||
|
assert attributes[ATTR_HS_COLOR] == (0, 100)
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN, "turn_off", {ATTR_ENTITY_ID: entity_id}, blocking=True
|
||
|
)
|
||
|
bulb.turnOff.assert_called_once()
|
||
|
|
||
|
bulb.is_on = False
|
||
|
async_fire_time_changed(hass, utcnow() + timedelta(seconds=10))
|
||
|
await hass.async_block_till_done()
|
||
|
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.turnOn.assert_called_once()
|
||
|
bulb.turnOn.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 100},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setRgbw.assert_called_with(255, 0, 0, w=50, brightness=100)
|
||
|
bulb.setRgbw.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_COLOR_TEMP: 150},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setRgbw.assert_called_with(w2=128)
|
||
|
bulb.setRgbw.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_COLOR_TEMP: 290},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setRgbw.assert_called_with(w=128)
|
||
|
bulb.setRgbw.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_HS_COLOR: (10, 30)},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setRgbw.assert_called_with(255, 191, 178, w=50, brightness=128)
|
||
|
bulb.setRgbw.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_EFFECT: "random"},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setRgb.assert_called_once()
|
||
|
bulb.setRgb.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_EFFECT: "purple_fade"},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setPresetPattern.assert_called_with(43, 50)
|
||
|
bulb.setPresetPattern.reset_mock()
|
||
|
|
||
|
|
||
|
async def test_rgbcw_light(hass: HomeAssistant) -> None:
|
||
|
"""Test an rgbcw 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.raw_state = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||
|
bulb.raw_state[9] = 1
|
||
|
bulb.raw_state[11] = 2
|
||
|
|
||
|
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] == "rgbw"
|
||
|
assert attributes[ATTR_EFFECT_LIST] == FLUX_EFFECT_LIST
|
||
|
assert attributes[ATTR_SUPPORTED_COLOR_MODES] == ["color_temp", "hs", "rgbw"]
|
||
|
assert attributes[ATTR_HS_COLOR] == (0, 100)
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN, "turn_off", {ATTR_ENTITY_ID: entity_id}, blocking=True
|
||
|
)
|
||
|
bulb.turnOff.assert_called_once()
|
||
|
|
||
|
bulb.is_on = False
|
||
|
async_fire_time_changed(hass, utcnow() + timedelta(seconds=10))
|
||
|
await hass.async_block_till_done()
|
||
|
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.turnOn.assert_called_once()
|
||
|
bulb.turnOn.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 100},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setRgbw.assert_called_with(255, 0, 0, w=50, brightness=100)
|
||
|
bulb.setRgbw.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_COLOR_TEMP: 150},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setRgbw.assert_called_with(w2=128)
|
||
|
bulb.setRgbw.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_COLOR_TEMP: 290},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setRgbw.assert_called_with(w=128)
|
||
|
bulb.setRgbw.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_HS_COLOR: (10, 30)},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setRgbw.assert_called_with(255, 191, 178, w=50, brightness=128)
|
||
|
bulb.setRgbw.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_EFFECT: "random"},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setRgb.assert_called_once()
|
||
|
bulb.setRgb.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_EFFECT: "purple_fade"},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setPresetPattern.assert_called_with(43, 50)
|
||
|
bulb.setPresetPattern.reset_mock()
|
||
|
|
||
|
|
||
|
async def test_white_light(hass: HomeAssistant) -> None:
|
||
|
"""Test a white 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.mode = "ww"
|
||
|
bulb.protocol = None
|
||
|
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] == 50
|
||
|
assert attributes[ATTR_COLOR_MODE] == "brightness"
|
||
|
assert attributes[ATTR_SUPPORTED_COLOR_MODES] == ["brightness"]
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN, "turn_off", {ATTR_ENTITY_ID: entity_id}, blocking=True
|
||
|
)
|
||
|
bulb.turnOff.assert_called_once()
|
||
|
|
||
|
bulb.is_on = False
|
||
|
async_fire_time_changed(hass, utcnow() + timedelta(seconds=10))
|
||
|
await hass.async_block_till_done()
|
||
|
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.turnOn.assert_called_once()
|
||
|
bulb.turnOn.reset_mock()
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 100},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setRgbw.assert_called_with(0, 0, 0, w=100)
|
||
|
bulb.setRgbw.reset_mock()
|
||
|
|
||
|
|
||
|
async def test_rgb_light_custom_effects(
|
||
|
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||
|
) -> None:
|
||
|
"""Test an rgb light with a custom effect."""
|
||
|
config_entry = MockConfigEntry(
|
||
|
domain=DOMAIN,
|
||
|
data={CONF_HOST: IP_ADDRESS, CONF_NAME: DEFAULT_ENTRY_TITLE},
|
||
|
unique_id=MAC_ADDRESS,
|
||
|
options={
|
||
|
CONF_MODE: MODE_AUTO,
|
||
|
CONF_CUSTOM_EFFECT_COLORS: "[0,0,255], [255,0,0]",
|
||
|
CONF_CUSTOM_EFFECT_SPEED_PCT: 88,
|
||
|
CONF_CUSTOM_EFFECT_TRANSITION: TRANSITION_JUMP,
|
||
|
},
|
||
|
)
|
||
|
config_entry.add_to_hass(hass)
|
||
|
bulb = _mocked_bulb()
|
||
|
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] == "rgbw"
|
||
|
assert attributes[ATTR_EFFECT_LIST] == [*FLUX_EFFECT_LIST, "custom"]
|
||
|
assert attributes[ATTR_SUPPORTED_COLOR_MODES] == ["color_temp", "hs", "rgbw"]
|
||
|
assert attributes[ATTR_HS_COLOR] == (0, 100)
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN, "turn_off", {ATTR_ENTITY_ID: entity_id}, blocking=True
|
||
|
)
|
||
|
bulb.turnOff.assert_called_once()
|
||
|
|
||
|
bulb.is_on = False
|
||
|
async_fire_time_changed(hass, utcnow() + timedelta(seconds=10))
|
||
|
await hass.async_block_till_done()
|
||
|
assert hass.states.get(entity_id).state == STATE_OFF
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_EFFECT: "custom"},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setCustomPattern.assert_called_with([[0, 0, 255], [255, 0, 0]], 88, "jump")
|
||
|
bulb.setCustomPattern.reset_mock()
|
||
|
bulb.raw_state = [0, 0, 0, EFFECT_CUSTOM_CODE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||
|
bulb.is_on = True
|
||
|
async_fire_time_changed(hass, utcnow() + timedelta(seconds=20))
|
||
|
await hass.async_block_till_done()
|
||
|
state = hass.states.get(entity_id)
|
||
|
assert state.state == STATE_ON
|
||
|
attributes = state.attributes
|
||
|
assert attributes[ATTR_EFFECT] == "custom"
|
||
|
|
||
|
caplog.clear()
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN,
|
||
|
"turn_on",
|
||
|
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 55, ATTR_EFFECT: "custom"},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setCustomPattern.assert_called_with([[0, 0, 255], [255, 0, 0]], 88, "jump")
|
||
|
bulb.setCustomPattern.reset_mock()
|
||
|
bulb.raw_state = [0, 0, 0, EFFECT_CUSTOM_CODE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||
|
bulb.is_on = True
|
||
|
async_fire_time_changed(hass, utcnow() + timedelta(seconds=20))
|
||
|
await hass.async_block_till_done()
|
||
|
state = hass.states.get(entity_id)
|
||
|
assert state.state == STATE_ON
|
||
|
attributes = state.attributes
|
||
|
assert attributes[ATTR_EFFECT] == "custom"
|
||
|
assert "RGB, brightness and white level are ignored when" in caplog.text
|
||
|
|
||
|
|
||
|
async def test_rgb_light_custom_effects_invalid_colors(hass: HomeAssistant) -> None:
|
||
|
"""Test an rgb light with a invalid effect."""
|
||
|
config_entry = MockConfigEntry(
|
||
|
domain=DOMAIN,
|
||
|
data={CONF_HOST: IP_ADDRESS, CONF_NAME: DEFAULT_ENTRY_TITLE},
|
||
|
unique_id=MAC_ADDRESS,
|
||
|
options={
|
||
|
CONF_MODE: MODE_AUTO,
|
||
|
CONF_CUSTOM_EFFECT_COLORS: ":: CANNOT BE PARSED ::",
|
||
|
CONF_CUSTOM_EFFECT_SPEED_PCT: 88,
|
||
|
CONF_CUSTOM_EFFECT_TRANSITION: TRANSITION_JUMP,
|
||
|
},
|
||
|
)
|
||
|
config_entry.add_to_hass(hass)
|
||
|
bulb = _mocked_bulb()
|
||
|
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] == "rgbw"
|
||
|
assert attributes[ATTR_EFFECT_LIST] == FLUX_EFFECT_LIST
|
||
|
assert attributes[ATTR_SUPPORTED_COLOR_MODES] == ["color_temp", "hs", "rgbw"]
|
||
|
assert attributes[ATTR_HS_COLOR] == (0, 100)
|
||
|
|
||
|
|
||
|
async def test_rgb_light_custom_effect_via_service(
|
||
|
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||
|
) -> None:
|
||
|
"""Test an rgb light with a custom effect set via the service."""
|
||
|
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()
|
||
|
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] == "rgbw"
|
||
|
assert attributes[ATTR_EFFECT_LIST] == [*FLUX_EFFECT_LIST]
|
||
|
assert attributes[ATTR_SUPPORTED_COLOR_MODES] == ["color_temp", "hs", "rgbw"]
|
||
|
assert attributes[ATTR_HS_COLOR] == (0, 100)
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
LIGHT_DOMAIN, "turn_off", {ATTR_ENTITY_ID: entity_id}, blocking=True
|
||
|
)
|
||
|
bulb.turnOff.assert_called_once()
|
||
|
|
||
|
bulb.is_on = False
|
||
|
async_fire_time_changed(hass, utcnow() + timedelta(seconds=10))
|
||
|
await hass.async_block_till_done()
|
||
|
assert hass.states.get(entity_id).state == STATE_OFF
|
||
|
|
||
|
await hass.services.async_call(
|
||
|
DOMAIN,
|
||
|
"set_custom_effect",
|
||
|
{
|
||
|
ATTR_ENTITY_ID: entity_id,
|
||
|
CONF_COLORS: [[0, 0, 255], [255, 0, 0]],
|
||
|
CONF_SPEED_PCT: 30,
|
||
|
CONF_TRANSITION: "jump",
|
||
|
},
|
||
|
blocking=True,
|
||
|
)
|
||
|
bulb.setCustomPattern.assert_called_with([(0, 0, 255), (255, 0, 0)], 30, "jump")
|
||
|
bulb.setCustomPattern.reset_mock()
|
||
|
|
||
|
|
||
|
async def test_rgbw_detection_without_protocol(hass: HomeAssistant) -> None:
|
||
|
"""Test an rgbw detection without protocol."""
|
||
|
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.protocol = None
|
||
|
bulb.rgbwprotocol = None
|
||
|
bulb.rgbwcapable = True
|
||
|
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] == "rgbw"
|
||
|
assert attributes[ATTR_EFFECT_LIST] == FLUX_EFFECT_LIST
|
||
|
assert attributes[ATTR_SUPPORTED_COLOR_MODES] == ["color_temp", "hs", "rgbw"]
|
||
|
assert attributes[ATTR_HS_COLOR] == (0, 100)
|
||
|
|
||
|
|
||
|
async def test_migrate_from_yaml(hass: HomeAssistant) -> None:
|
||
|
"""Test migrate from yaml."""
|
||
|
config = {
|
||
|
LIGHT_DOMAIN: [
|
||
|
{
|
||
|
CONF_PLATFORM: DOMAIN,
|
||
|
CONF_DEVICES: {
|
||
|
IP_ADDRESS: {
|
||
|
CONF_NAME: "flux_lamppost",
|
||
|
CONF_PROTOCOL: "ledenet",
|
||
|
CONF_CUSTOM_EFFECT: {
|
||
|
CONF_SPEED_PCT: 30,
|
||
|
CONF_TRANSITION: "strobe",
|
||
|
CONF_COLORS: [[255, 0, 0], [255, 255, 0], [0, 255, 0]],
|
||
|
},
|
||
|
}
|
||
|
},
|
||
|
}
|
||
|
],
|
||
|
}
|
||
|
with _patch_discovery(), _patch_wifibulb():
|
||
|
await async_setup_component(hass, LIGHT_DOMAIN, config)
|
||
|
await hass.async_block_till_done()
|
||
|
await hass.async_block_till_done()
|
||
|
await hass.async_block_till_done()
|
||
|
|
||
|
entries = hass.config_entries.async_entries(DOMAIN)
|
||
|
assert entries
|
||
|
|
||
|
migrated_entry = None
|
||
|
for entry in entries:
|
||
|
if entry.unique_id == MAC_ADDRESS:
|
||
|
migrated_entry = entry
|
||
|
break
|
||
|
|
||
|
assert migrated_entry is not None
|
||
|
assert migrated_entry.data == {
|
||
|
CONF_HOST: IP_ADDRESS,
|
||
|
CONF_NAME: "flux_lamppost",
|
||
|
CONF_PROTOCOL: "ledenet",
|
||
|
}
|
||
|
assert migrated_entry.options == {
|
||
|
CONF_MODE: "auto",
|
||
|
CONF_CUSTOM_EFFECT_COLORS: "[(255, 0, 0), (255, 255, 0), (0, 255, 0)]",
|
||
|
CONF_CUSTOM_EFFECT_SPEED_PCT: 30,
|
||
|
CONF_CUSTOM_EFFECT_TRANSITION: "strobe",
|
||
|
}
|