Fix WLED power and brightness with WLED 0.10+ (#36529)

This commit is contained in:
Franck Nijhof 2020-06-07 23:37:58 +02:00 committed by Paulus Schoutsen
parent e43a0087e4
commit 609d202c4d
5 changed files with 337 additions and 72 deletions

View File

@ -83,20 +83,78 @@ async def async_setup_entry(
update_segments()
class WLEDLight(LightEntity, WLEDDeviceEntity):
"""Defines a WLED light."""
class WLEDMasterLight(LightEntity, WLEDDeviceEntity):
"""Defines a WLED master light."""
def __init__(self, entry_id: str, coordinator: WLEDDataUpdateCoordinator):
"""Initialize WLED master light."""
super().__init__(
entry_id=entry_id,
coordinator=coordinator,
name=f"{coordinator.data.info.name} Master",
icon="mdi:led-strip-variant",
)
@property
def unique_id(self) -> str:
"""Return the unique ID for this sensor."""
return f"{self.coordinator.data.info.mac_address}"
@property
def supported_features(self) -> int:
"""Flag supported features."""
return SUPPORT_BRIGHTNESS | SUPPORT_TRANSITION
@property
def brightness(self) -> Optional[int]:
"""Return the brightness of this light between 1..255."""
return self.coordinator.data.state.brightness
@property
def is_on(self) -> bool:
"""Return the state of the light."""
return bool(self.coordinator.data.state.on)
@wled_exception_handler
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off the light."""
data = {ATTR_ON: False}
if ATTR_TRANSITION in kwargs:
# WLED uses 100ms per unit, so 10 = 1 second.
data[ATTR_TRANSITION] = round(kwargs[ATTR_TRANSITION] * 10)
await self.coordinator.wled.master(**data)
@wled_exception_handler
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on the light."""
data = {ATTR_ON: True}
if ATTR_TRANSITION in kwargs:
# WLED uses 100ms per unit, so 10 = 1 second.
data[ATTR_TRANSITION] = round(kwargs[ATTR_TRANSITION] * 10)
if ATTR_BRIGHTNESS in kwargs:
data[ATTR_BRIGHTNESS] = kwargs[ATTR_BRIGHTNESS]
await self.coordinator.wled.master(**data)
class WLEDSegmentLight(LightEntity, WLEDDeviceEntity):
"""Defines a WLED light based on a segment."""
def __init__(
self, entry_id: str, coordinator: WLEDDataUpdateCoordinator, segment: int
):
"""Initialize WLED light."""
"""Initialize WLED segment light."""
self._rgbw = coordinator.data.info.leds.rgbw
self._segment = segment
# Only apply the segment ID if it is not the first segment
name = coordinator.data.info.name
if segment != 0:
name += f" {segment}"
# If this is the one and only segment, use a simpler name
name = f"{coordinator.data.info.name} Segment {self._segment}"
if len(coordinator.data.state.segments) == 1:
name = coordinator.data.info.name
super().__init__(
entry_id=entry_id,
@ -155,7 +213,16 @@ class WLEDLight(LightEntity, WLEDDeviceEntity):
@property
def brightness(self) -> Optional[int]:
"""Return the brightness of this light between 1..255."""
return self.coordinator.data.state.brightness
state = self.coordinator.data.state
# If this is the one and only segment, calculate brightness based
# on the master and segment brightness
if len(state.segments) == 1:
return int(
(state.segments[self._segment].brightness * state.brightness) / 255
)
return state.segments[self._segment].brightness
@property
def white_value(self) -> Optional[int]:
@ -187,18 +254,30 @@ class WLEDLight(LightEntity, WLEDDeviceEntity):
@property
def is_on(self) -> bool:
"""Return the state of the light."""
return bool(self.coordinator.data.state.on)
state = self.coordinator.data.state
# If there is a single segment, take master into account
if len(state.segments) == 1 and not state.on:
return False
return bool(state.segments[self._segment].on)
@wled_exception_handler
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off the light."""
data = {ATTR_ON: False, ATTR_SEGMENT_ID: self._segment}
data = {ATTR_ON: False}
if ATTR_TRANSITION in kwargs:
# WLED uses 100ms per unit, so 10 = 1 second.
data[ATTR_TRANSITION] = round(kwargs[ATTR_TRANSITION] * 10)
await self.coordinator.wled.light(**data)
# If there is a single segment, control via the master
if len(self.coordinator.data.state.segments) == 1:
await self.coordinator.wled.master(**data)
return
data[ATTR_SEGMENT_ID] = self._segment
await self.coordinator.wled.segment(**data)
@wled_exception_handler
async def async_turn_on(self, **kwargs: Any) -> None:
@ -248,7 +327,23 @@ class WLEDLight(LightEntity, WLEDDeviceEntity):
else:
data[ATTR_COLOR_PRIMARY] += (self.white_value,)
await self.coordinator.wled.light(**data)
# When only 1 segment is present, switch along the master, and use
# the master for power/brightness control.
if len(self.coordinator.data.state.segments) == 1:
master_data = {ATTR_ON: True}
if ATTR_BRIGHTNESS in data:
master_data[ATTR_BRIGHTNESS] = data[ATTR_BRIGHTNESS]
data[ATTR_BRIGHTNESS] = 255
if ATTR_TRANSITION in data:
master_data[ATTR_TRANSITION] = data[ATTR_TRANSITION]
del data[ATTR_TRANSITION]
await self.coordinator.wled.segment(**data)
await self.coordinator.wled.master(**master_data)
return
await self.coordinator.wled.segment(**data)
@wled_exception_handler
async def async_effect(
@ -273,45 +368,59 @@ class WLEDLight(LightEntity, WLEDDeviceEntity):
if speed is not None:
data[ATTR_SPEED] = speed
await self.coordinator.wled.light(**data)
await self.coordinator.wled.segment(**data)
@callback
def async_update_segments(
entry: ConfigEntry,
coordinator: WLEDDataUpdateCoordinator,
current: Dict[int, WLEDLight],
current: Dict[int, WLEDSegmentLight],
async_add_entities,
) -> None:
"""Update segments."""
segment_ids = {light.segment_id for light in coordinator.data.state.segments}
current_ids = set(current)
# Process new segments, add them to Home Assistant
new_segments = []
for segment_id in segment_ids - current_ids:
current[segment_id] = WLEDLight(entry.entry_id, coordinator, segment_id)
new_segments.append(current[segment_id])
# Discard master (if present)
current_ids.discard(-1)
if new_segments:
async_add_entities(new_segments)
# Process new segments, add them to Home Assistant
new_entities = []
for segment_id in segment_ids - current_ids:
current[segment_id] = WLEDSegmentLight(entry.entry_id, coordinator, segment_id)
new_entities.append(current[segment_id])
# More than 1 segment now? Add master controls
if len(current_ids) < 2 and len(segment_ids) > 1:
current[-1] = WLEDMasterLight(entry.entry_id, coordinator)
new_entities.append(current[-1])
if new_entities:
async_add_entities(new_entities)
# Process deleted segments, remove them from Home Assistant
for segment_id in current_ids - segment_ids:
coordinator.hass.async_create_task(
async_remove_segment(segment_id, coordinator, current)
async_remove_entity(segment_id, coordinator, current)
)
# Remove master if there is only 1 segment left
if len(current_ids) > 1 and len(segment_ids) < 2:
coordinator.hass.async_create_task(
async_remove_entity(-1, coordinator, current)
)
async def async_remove_segment(
segment_id: int,
async def async_remove_entity(
index: int,
coordinator: WLEDDataUpdateCoordinator,
current: Dict[int, WLEDLight],
current: Dict[int, WLEDSegmentLight],
) -> None:
"""Remove WLED segment light from Home Assistant."""
entity = current[segment_id]
entity = current[index]
await entity.async_remove()
registry = await async_get_entity_registry(coordinator.hass)
if entity.entity_id in registry.entities:
registry.async_remove(entity.entity_id)
del current[segment_id]
del current[index]

View File

@ -3,7 +3,7 @@
"name": "WLED",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/wled",
"requirements": ["wled==0.4.1"],
"requirements": ["wled==0.4.2"],
"zeroconf": ["_wled._tcp.local."],
"codeowners": ["@frenck"],
"quality_scale": "platinum"

View File

@ -2195,7 +2195,7 @@ wirelesstagpy==0.4.0
withings-api==2.1.3
# homeassistant.components.wled
wled==0.4.1
wled==0.4.2
# homeassistant.components.xbee
xbee-helper==0.0.7

View File

@ -901,7 +901,7 @@ wiffi==1.0.0
withings-api==2.1.3
# homeassistant.components.wled
wled==0.4.1
wled==0.4.2
# homeassistant.components.bluesound
# homeassistant.components.rest

View File

@ -29,6 +29,7 @@ from homeassistant.const import (
ATTR_ICON,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
STATE_ON,
STATE_UNAVAILABLE,
)
@ -50,7 +51,7 @@ async def test_rgb_light_state(
entity_registry = await hass.helpers.entity_registry.async_get_registry()
# First segment of the strip
state = hass.states.get("light.wled_rgb_light")
state = hass.states.get("light.wled_rgb_light_segment_0")
assert state
assert state.attributes.get(ATTR_BRIGHTNESS) == 127
assert state.attributes.get(ATTR_EFFECT) == "Solid"
@ -64,12 +65,12 @@ async def test_rgb_light_state(
assert state.attributes.get(ATTR_SPEED) == 32
assert state.state == STATE_ON
entry = entity_registry.async_get("light.wled_rgb_light")
entry = entity_registry.async_get("light.wled_rgb_light_segment_0")
assert entry
assert entry.unique_id == "aabbccddeeff_0"
# Second segment of the strip
state = hass.states.get("light.wled_rgb_light_1")
state = hass.states.get("light.wled_rgb_light_segment_1")
assert state
assert state.attributes.get(ATTR_BRIGHTNESS) == 127
assert state.attributes.get(ATTR_EFFECT) == "Blink"
@ -83,22 +84,32 @@ async def test_rgb_light_state(
assert state.attributes.get(ATTR_SPEED) == 16
assert state.state == STATE_ON
entry = entity_registry.async_get("light.wled_rgb_light_1")
entry = entity_registry.async_get("light.wled_rgb_light_segment_1")
assert entry
assert entry.unique_id == "aabbccddeeff_1"
# Test master control of the lightstrip
state = hass.states.get("light.wled_rgb_light_master")
assert state
assert state.attributes.get(ATTR_BRIGHTNESS) == 127
assert state.state == STATE_ON
async def test_switch_change_state(
entry = entity_registry.async_get("light.wled_rgb_light_master")
assert entry
assert entry.unique_id == "aabbccddeeff"
async def test_segment_change_state(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog
) -> None:
"""Test the change of state of the WLED switches."""
"""Test the change of state of the WLED segments."""
await init_integration(hass, aioclient_mock)
with patch("wled.WLED.light") as light_mock:
with patch("wled.WLED.segment") as light_mock:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "light.wled_rgb_light", ATTR_TRANSITION: 5},
{ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", ATTR_TRANSITION: 5},
blocking=True,
)
await hass.async_block_till_done()
@ -106,14 +117,14 @@ async def test_switch_change_state(
on=False, segment_id=0, transition=50,
)
with patch("wled.WLED.light") as light_mock:
with patch("wled.WLED.segment") as light_mock:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_BRIGHTNESS: 42,
ATTR_EFFECT: "Chase",
ATTR_ENTITY_ID: "light.wled_rgb_light",
ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0",
ATTR_RGB_COLOR: [255, 0, 0],
ATTR_TRANSITION: 5,
},
@ -129,11 +140,11 @@ async def test_switch_change_state(
transition=50,
)
with patch("wled.WLED.light") as light_mock:
with patch("wled.WLED.segment") as light_mock:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "light.wled_rgb_light", ATTR_COLOR_TEMP: 400},
{ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", ATTR_COLOR_TEMP: 400},
blocking=True,
)
await hass.async_block_till_done()
@ -142,33 +153,178 @@ async def test_switch_change_state(
)
async def test_master_change_state(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog
) -> None:
"""Test the change of state of the WLED master light control."""
await init_integration(hass, aioclient_mock)
with patch("wled.WLED.master") as light_mock:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "light.wled_rgb_light_master", ATTR_TRANSITION: 5},
blocking=True,
)
await hass.async_block_till_done()
light_mock.assert_called_once_with(
on=False, transition=50,
)
with patch("wled.WLED.master") as light_mock:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_BRIGHTNESS: 42,
ATTR_ENTITY_ID: "light.wled_rgb_light_master",
ATTR_TRANSITION: 5,
},
blocking=True,
)
await hass.async_block_till_done()
light_mock.assert_called_once_with(
brightness=42, on=True, transition=50,
)
with patch("wled.WLED.master") as light_mock:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "light.wled_rgb_light_master", ATTR_TRANSITION: 5},
blocking=True,
)
await hass.async_block_till_done()
light_mock.assert_called_once_with(
on=False, transition=50,
)
with patch("wled.WLED.master") as light_mock:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_BRIGHTNESS: 42,
ATTR_ENTITY_ID: "light.wled_rgb_light_master",
ATTR_TRANSITION: 5,
},
blocking=True,
)
await hass.async_block_till_done()
light_mock.assert_called_once_with(
brightness=42, on=True, transition=50,
)
async def test_dynamically_handle_segments(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test if a new/deleted segment is dynamically added/removed."""
await init_integration(hass, aioclient_mock)
assert hass.states.get("light.wled_rgb_light")
assert hass.states.get("light.wled_rgb_light_1")
assert hass.states.get("light.wled_rgb_light_master")
assert hass.states.get("light.wled_rgb_light_segment_0")
assert hass.states.get("light.wled_rgb_light_segment_1")
data = json.loads(load_fixture("wled/rgb_single_segment.json"))
device = WLEDDevice(data)
# Test removal if segment went missing
# Test removal if segment went missing, including the master entity
with patch(
"homeassistant.components.wled.WLED.update", return_value=device,
):
async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL)
await hass.async_block_till_done()
assert hass.states.get("light.wled_rgb_light")
assert not hass.states.get("light.wled_rgb_light_1")
assert hass.states.get("light.wled_rgb_light_segment_0")
assert not hass.states.get("light.wled_rgb_light_segment_1")
assert not hass.states.get("light.wled_rgb_light_master")
# Test adding if segment shows up again
# Test adding if segment shows up again, including the master entity
async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL)
await hass.async_block_till_done()
assert hass.states.get("light.wled_rgb_light")
assert hass.states.get("light.wled_rgb_light_1")
assert hass.states.get("light.wled_rgb_light_master")
assert hass.states.get("light.wled_rgb_light_segment_0")
assert hass.states.get("light.wled_rgb_light_segment_1")
async def test_single_segment_behavior(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog
) -> None:
"""Test the behavior of the integration with a single segment."""
await init_integration(hass, aioclient_mock)
data = json.loads(load_fixture("wled/rgb_single_segment.json"))
device = WLEDDevice(data)
# Test absent master
with patch(
"homeassistant.components.wled.WLED.update", return_value=device,
):
async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL)
await hass.async_block_till_done()
assert not hass.states.get("light.wled_rgb_light_master")
state = hass.states.get("light.wled_rgb_light_segment_0")
assert state
assert state.state == STATE_ON
# Test segment brightness takes master into account
device.state.brightness = 100
device.state.segments[0].brightness = 255
with patch(
"homeassistant.components.wled.WLED.update", return_value=device,
):
async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL)
await hass.async_block_till_done()
state = hass.states.get("light.wled_rgb_light_segment_0")
assert state
assert state.attributes.get(ATTR_BRIGHTNESS) == 100
# Test segment is off when master is off
device.state.on = False
with patch(
"homeassistant.components.wled.WLED.update", return_value=device,
):
async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL)
await hass.async_block_till_done()
state = hass.states.get("light.wled_rgb_light_segment_0")
assert state
assert state.state == STATE_OFF
# Test master is turned off when turning off a single segment
with patch("wled.WLED.master") as master_mock:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", ATTR_TRANSITION: 5},
blocking=True,
)
await hass.async_block_till_done()
master_mock.assert_called_once_with(
on=False, transition=50,
)
# Test master is turned on when turning on a single segment, and segment
# brightness is set to 255.
with patch("wled.WLED.master") as master_mock, patch(
"wled.WLED.segment"
) as segment_mock:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0",
ATTR_TRANSITION: 5,
ATTR_BRIGHTNESS: 42,
},
blocking=True,
)
await hass.async_block_till_done()
master_mock.assert_called_once_with(on=True, transition=50, brightness=42)
segment_mock.assert_called_once_with(on=True, segment_id=0, brightness=255)
async def test_light_error(
@ -182,12 +338,12 @@ async def test_light_error(
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "light.wled_rgb_light"},
{ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0"},
blocking=True,
)
await hass.async_block_till_done()
state = hass.states.get("light.wled_rgb_light")
state = hass.states.get("light.wled_rgb_light_segment_0")
assert state.state == STATE_ON
assert "Invalid response from API" in caplog.text
@ -199,17 +355,17 @@ async def test_light_connection_error(
await init_integration(hass, aioclient_mock)
with patch("homeassistant.components.wled.WLED.update"), patch(
"homeassistant.components.wled.WLED.light", side_effect=WLEDConnectionError
"homeassistant.components.wled.WLED.segment", side_effect=WLEDConnectionError
):
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "light.wled_rgb_light"},
{ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0"},
blocking=True,
)
await hass.async_block_till_done()
state = hass.states.get("light.wled_rgb_light")
state = hass.states.get("light.wled_rgb_light_segment_0")
assert state.state == STATE_UNAVAILABLE
@ -224,7 +380,7 @@ async def test_rgbw_light(
assert state.attributes.get(ATTR_HS_COLOR) == (0.0, 100.0)
assert state.attributes.get(ATTR_WHITE_VALUE) == 139
with patch("wled.WLED.light") as light_mock:
with patch("wled.WLED.segment") as light_mock:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
@ -236,7 +392,7 @@ async def test_rgbw_light(
on=True, segment_id=0, color_primary=(255, 159, 70, 139),
)
with patch("wled.WLED.light") as light_mock:
with patch("wled.WLED.segment") as light_mock:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
@ -248,7 +404,7 @@ async def test_rgbw_light(
color_primary=(255, 0, 0, 100), on=True, segment_id=0,
)
with patch("wled.WLED.light") as light_mock:
with patch("wled.WLED.segment") as light_mock:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
@ -271,13 +427,13 @@ async def test_effect_service(
"""Test the effect service of a WLED light."""
await init_integration(hass, aioclient_mock)
with patch("wled.WLED.light") as light_mock:
with patch("wled.WLED.segment") as light_mock:
await hass.services.async_call(
DOMAIN,
SERVICE_EFFECT,
{
ATTR_EFFECT: "Rainbow",
ATTR_ENTITY_ID: "light.wled_rgb_light",
ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0",
ATTR_INTENSITY: 200,
ATTR_REVERSE: True,
ATTR_SPEED: 100,
@ -289,11 +445,11 @@ async def test_effect_service(
effect="Rainbow", intensity=200, reverse=True, segment_id=0, speed=100,
)
with patch("wled.WLED.light") as light_mock:
with patch("wled.WLED.segment") as light_mock:
await hass.services.async_call(
DOMAIN,
SERVICE_EFFECT,
{ATTR_ENTITY_ID: "light.wled_rgb_light", ATTR_EFFECT: 9},
{ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", ATTR_EFFECT: 9},
blocking=True,
)
await hass.async_block_till_done()
@ -301,12 +457,12 @@ async def test_effect_service(
segment_id=0, effect=9,
)
with patch("wled.WLED.light") as light_mock:
with patch("wled.WLED.segment") as light_mock:
await hass.services.async_call(
DOMAIN,
SERVICE_EFFECT,
{
ATTR_ENTITY_ID: "light.wled_rgb_light",
ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0",
ATTR_INTENSITY: 200,
ATTR_REVERSE: True,
ATTR_SPEED: 100,
@ -318,13 +474,13 @@ async def test_effect_service(
intensity=200, reverse=True, segment_id=0, speed=100,
)
with patch("wled.WLED.light") as light_mock:
with patch("wled.WLED.segment") as light_mock:
await hass.services.async_call(
DOMAIN,
SERVICE_EFFECT,
{
ATTR_EFFECT: "Rainbow",
ATTR_ENTITY_ID: "light.wled_rgb_light",
ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0",
ATTR_REVERSE: True,
ATTR_SPEED: 100,
},
@ -335,13 +491,13 @@ async def test_effect_service(
effect="Rainbow", reverse=True, segment_id=0, speed=100,
)
with patch("wled.WLED.light") as light_mock:
with patch("wled.WLED.segment") as light_mock:
await hass.services.async_call(
DOMAIN,
SERVICE_EFFECT,
{
ATTR_EFFECT: "Rainbow",
ATTR_ENTITY_ID: "light.wled_rgb_light",
ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0",
ATTR_INTENSITY: 200,
ATTR_SPEED: 100,
},
@ -352,13 +508,13 @@ async def test_effect_service(
effect="Rainbow", intensity=200, segment_id=0, speed=100,
)
with patch("wled.WLED.light") as light_mock:
with patch("wled.WLED.segment") as light_mock:
await hass.services.async_call(
DOMAIN,
SERVICE_EFFECT,
{
ATTR_EFFECT: "Rainbow",
ATTR_ENTITY_ID: "light.wled_rgb_light",
ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0",
ATTR_INTENSITY: 200,
ATTR_REVERSE: True,
},
@ -381,11 +537,11 @@ async def test_effect_service_error(
await hass.services.async_call(
DOMAIN,
SERVICE_EFFECT,
{ATTR_ENTITY_ID: "light.wled_rgb_light", ATTR_EFFECT: 9},
{ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", ATTR_EFFECT: 9},
blocking=True,
)
await hass.async_block_till_done()
state = hass.states.get("light.wled_rgb_light")
state = hass.states.get("light.wled_rgb_light_segment_0")
assert state.state == STATE_ON
assert "Invalid response from API" in caplog.text