mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 14:17:45 +00:00
Use modern naming for WLED (#100233)
This commit is contained in:
parent
ed8a372f4e
commit
9ac5bdc832
@ -13,7 +13,7 @@ from homeassistant.core import callback
|
|||||||
from homeassistant.data_entry_flow import FlowResult
|
from homeassistant.data_entry_flow import FlowResult
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
|
||||||
from .const import CONF_KEEP_MASTER_LIGHT, DEFAULT_KEEP_MASTER_LIGHT, DOMAIN
|
from .const import CONF_KEEP_MAIN_LIGHT, DEFAULT_KEEP_MAIN_LIGHT, DOMAIN
|
||||||
|
|
||||||
|
|
||||||
class WLEDFlowHandler(ConfigFlow, domain=DOMAIN):
|
class WLEDFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||||
@ -136,9 +136,9 @@ class WLEDOptionsFlowHandler(OptionsFlow):
|
|||||||
data_schema=vol.Schema(
|
data_schema=vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Optional(
|
vol.Optional(
|
||||||
CONF_KEEP_MASTER_LIGHT,
|
CONF_KEEP_MAIN_LIGHT,
|
||||||
default=self.config_entry.options.get(
|
default=self.config_entry.options.get(
|
||||||
CONF_KEEP_MASTER_LIGHT, DEFAULT_KEEP_MASTER_LIGHT
|
CONF_KEEP_MAIN_LIGHT, DEFAULT_KEEP_MAIN_LIGHT
|
||||||
),
|
),
|
||||||
): bool,
|
): bool,
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@ LOGGER = logging.getLogger(__package__)
|
|||||||
SCAN_INTERVAL = timedelta(seconds=10)
|
SCAN_INTERVAL = timedelta(seconds=10)
|
||||||
|
|
||||||
# Options
|
# Options
|
||||||
CONF_KEEP_MASTER_LIGHT = "keep_master_light"
|
CONF_KEEP_MAIN_LIGHT = "keep_master_light"
|
||||||
DEFAULT_KEEP_MASTER_LIGHT = False
|
DEFAULT_KEEP_MAIN_LIGHT = False
|
||||||
|
|
||||||
# Attributes
|
# Attributes
|
||||||
ATTR_COLOR_PRIMARY = "color_primary"
|
ATTR_COLOR_PRIMARY = "color_primary"
|
||||||
|
@ -10,8 +10,8 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
CONF_KEEP_MASTER_LIGHT,
|
CONF_KEEP_MAIN_LIGHT,
|
||||||
DEFAULT_KEEP_MASTER_LIGHT,
|
DEFAULT_KEEP_MAIN_LIGHT,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
LOGGER,
|
LOGGER,
|
||||||
SCAN_INTERVAL,
|
SCAN_INTERVAL,
|
||||||
@ -21,7 +21,7 @@ from .const import (
|
|||||||
class WLEDDataUpdateCoordinator(DataUpdateCoordinator[WLEDDevice]):
|
class WLEDDataUpdateCoordinator(DataUpdateCoordinator[WLEDDevice]):
|
||||||
"""Class to manage fetching WLED data from single endpoint."""
|
"""Class to manage fetching WLED data from single endpoint."""
|
||||||
|
|
||||||
keep_master_light: bool
|
keep_main_light: bool
|
||||||
config_entry: ConfigEntry
|
config_entry: ConfigEntry
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@ -31,8 +31,8 @@ class WLEDDataUpdateCoordinator(DataUpdateCoordinator[WLEDDevice]):
|
|||||||
entry: ConfigEntry,
|
entry: ConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize global WLED data updater."""
|
"""Initialize global WLED data updater."""
|
||||||
self.keep_master_light = entry.options.get(
|
self.keep_main_light = entry.options.get(
|
||||||
CONF_KEEP_MASTER_LIGHT, DEFAULT_KEEP_MASTER_LIGHT
|
CONF_KEEP_MAIN_LIGHT, DEFAULT_KEEP_MAIN_LIGHT
|
||||||
)
|
)
|
||||||
self.wled = WLED(entry.data[CONF_HOST], session=async_get_clientsession(hass))
|
self.wled = WLED(entry.data[CONF_HOST], session=async_get_clientsession(hass))
|
||||||
self.unsub: CALLBACK_TYPE | None = None
|
self.unsub: CALLBACK_TYPE | None = None
|
||||||
@ -45,9 +45,9 @@ class WLEDDataUpdateCoordinator(DataUpdateCoordinator[WLEDDevice]):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_master_light(self) -> bool:
|
def has_main_light(self) -> bool:
|
||||||
"""Return if the coordinated device has a master light."""
|
"""Return if the coordinated device has a main light."""
|
||||||
return self.keep_master_light or (
|
return self.keep_main_light or (
|
||||||
self.data is not None and len(self.data.state.segments) > 1
|
self.data is not None and len(self.data.state.segments) > 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ async def async_setup_entry(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Set up WLED light based on a config entry."""
|
"""Set up WLED light based on a config entry."""
|
||||||
coordinator: WLEDDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
coordinator: WLEDDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
if coordinator.keep_master_light:
|
if coordinator.keep_main_light:
|
||||||
async_add_entities([WLEDMasterLight(coordinator=coordinator)])
|
async_add_entities([WLEDMainLight(coordinator=coordinator)])
|
||||||
|
|
||||||
update_segments = partial(
|
update_segments = partial(
|
||||||
async_update_segments,
|
async_update_segments,
|
||||||
@ -47,8 +47,8 @@ async def async_setup_entry(
|
|||||||
update_segments()
|
update_segments()
|
||||||
|
|
||||||
|
|
||||||
class WLEDMasterLight(WLEDEntity, LightEntity):
|
class WLEDMainLight(WLEDEntity, LightEntity):
|
||||||
"""Defines a WLED master light."""
|
"""Defines a WLED main light."""
|
||||||
|
|
||||||
_attr_color_mode = ColorMode.BRIGHTNESS
|
_attr_color_mode = ColorMode.BRIGHTNESS
|
||||||
_attr_icon = "mdi:led-strip-variant"
|
_attr_icon = "mdi:led-strip-variant"
|
||||||
@ -57,7 +57,7 @@ class WLEDMasterLight(WLEDEntity, LightEntity):
|
|||||||
_attr_supported_color_modes = {ColorMode.BRIGHTNESS}
|
_attr_supported_color_modes = {ColorMode.BRIGHTNESS}
|
||||||
|
|
||||||
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
|
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
|
||||||
"""Initialize WLED master light."""
|
"""Initialize WLED main light."""
|
||||||
super().__init__(coordinator=coordinator)
|
super().__init__(coordinator=coordinator)
|
||||||
self._attr_unique_id = coordinator.data.info.mac_address
|
self._attr_unique_id = coordinator.data.info.mac_address
|
||||||
|
|
||||||
@ -73,8 +73,8 @@ class WLEDMasterLight(WLEDEntity, LightEntity):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self) -> bool:
|
def available(self) -> bool:
|
||||||
"""Return if this master light is available or not."""
|
"""Return if this main light is available or not."""
|
||||||
return self.coordinator.has_master_light and super().available
|
return self.coordinator.has_main_light and super().available
|
||||||
|
|
||||||
@wled_exception_handler
|
@wled_exception_handler
|
||||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||||
@ -167,8 +167,8 @@ class WLEDSegmentLight(WLEDEntity, LightEntity):
|
|||||||
state = self.coordinator.data.state
|
state = self.coordinator.data.state
|
||||||
|
|
||||||
# If this is the one and only segment, calculate brightness based
|
# If this is the one and only segment, calculate brightness based
|
||||||
# on the master and segment brightness
|
# on the main and segment brightness
|
||||||
if not self.coordinator.has_master_light:
|
if not self.coordinator.has_main_light:
|
||||||
return int(
|
return int(
|
||||||
(state.segments[self._segment].brightness * state.brightness) / 255
|
(state.segments[self._segment].brightness * state.brightness) / 255
|
||||||
)
|
)
|
||||||
@ -185,9 +185,9 @@ class WLEDSegmentLight(WLEDEntity, LightEntity):
|
|||||||
"""Return the state of the light."""
|
"""Return the state of the light."""
|
||||||
state = self.coordinator.data.state
|
state = self.coordinator.data.state
|
||||||
|
|
||||||
# If there is no master, we take the master state into account
|
# If there is no main, we take the main state into account
|
||||||
# on the segment level.
|
# on the segment level.
|
||||||
if not self.coordinator.has_master_light and not state.on:
|
if not self.coordinator.has_main_light and not state.on:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return bool(state.segments[self._segment].on)
|
return bool(state.segments[self._segment].on)
|
||||||
@ -200,8 +200,8 @@ class WLEDSegmentLight(WLEDEntity, LightEntity):
|
|||||||
# WLED uses 100ms per unit, so 10 = 1 second.
|
# WLED uses 100ms per unit, so 10 = 1 second.
|
||||||
transition = round(kwargs[ATTR_TRANSITION] * 10)
|
transition = round(kwargs[ATTR_TRANSITION] * 10)
|
||||||
|
|
||||||
# If there is no master control, and only 1 segment, handle the master
|
# If there is no main control, and only 1 segment, handle the main
|
||||||
if not self.coordinator.has_master_light:
|
if not self.coordinator.has_main_light:
|
||||||
await self.coordinator.wled.master(on=False, transition=transition)
|
await self.coordinator.wled.master(on=False, transition=transition)
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -233,19 +233,19 @@ class WLEDSegmentLight(WLEDEntity, LightEntity):
|
|||||||
if ATTR_EFFECT in kwargs:
|
if ATTR_EFFECT in kwargs:
|
||||||
data[ATTR_EFFECT] = kwargs[ATTR_EFFECT]
|
data[ATTR_EFFECT] = kwargs[ATTR_EFFECT]
|
||||||
|
|
||||||
# If there is no master control, and only 1 segment, handle the master
|
# If there is no main control, and only 1 segment, handle the main
|
||||||
if not self.coordinator.has_master_light:
|
if not self.coordinator.has_main_light:
|
||||||
master_data = {ATTR_ON: True}
|
main_data = {ATTR_ON: True}
|
||||||
if ATTR_BRIGHTNESS in data:
|
if ATTR_BRIGHTNESS in data:
|
||||||
master_data[ATTR_BRIGHTNESS] = data[ATTR_BRIGHTNESS]
|
main_data[ATTR_BRIGHTNESS] = data[ATTR_BRIGHTNESS]
|
||||||
data[ATTR_BRIGHTNESS] = 255
|
data[ATTR_BRIGHTNESS] = 255
|
||||||
|
|
||||||
if ATTR_TRANSITION in data:
|
if ATTR_TRANSITION in data:
|
||||||
master_data[ATTR_TRANSITION] = data[ATTR_TRANSITION]
|
main_data[ATTR_TRANSITION] = data[ATTR_TRANSITION]
|
||||||
del data[ATTR_TRANSITION]
|
del data[ATTR_TRANSITION]
|
||||||
|
|
||||||
await self.coordinator.wled.segment(**data)
|
await self.coordinator.wled.segment(**data)
|
||||||
await self.coordinator.wled.master(**master_data)
|
await self.coordinator.wled.master(**main_data)
|
||||||
return
|
return
|
||||||
|
|
||||||
await self.coordinator.wled.segment(**data)
|
await self.coordinator.wled.segment(**data)
|
||||||
@ -259,13 +259,13 @@ def async_update_segments(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Update segments."""
|
"""Update segments."""
|
||||||
segment_ids = {light.segment_id for light in coordinator.data.state.segments}
|
segment_ids = {light.segment_id for light in coordinator.data.state.segments}
|
||||||
new_entities: list[WLEDMasterLight | WLEDSegmentLight] = []
|
new_entities: list[WLEDMainLight | WLEDSegmentLight] = []
|
||||||
|
|
||||||
# More than 1 segment now? No master? Add master controls
|
# More than 1 segment now? No main? Add main controls
|
||||||
if not coordinator.keep_master_light and (
|
if not coordinator.keep_main_light and (
|
||||||
len(current_ids) < 2 and len(segment_ids) > 1
|
len(current_ids) < 2 and len(segment_ids) > 1
|
||||||
):
|
):
|
||||||
new_entities.append(WLEDMasterLight(coordinator))
|
new_entities.append(WLEDMainLight(coordinator))
|
||||||
|
|
||||||
# Process new segments, add them to Home Assistant
|
# Process new segments, add them to Home Assistant
|
||||||
for segment_id in segment_ids - current_ids:
|
for segment_id in segment_ids - current_ids:
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
"step": {
|
"step": {
|
||||||
"init": {
|
"init": {
|
||||||
"data": {
|
"data": {
|
||||||
"keep_master_light": "Keep master light, even with 1 LED segment."
|
"keep_master_light": "Keep main light, even with 1 LED segment."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import pytest
|
|||||||
from wled import WLEDConnectionError
|
from wled import WLEDConnectionError
|
||||||
|
|
||||||
from homeassistant.components import zeroconf
|
from homeassistant.components import zeroconf
|
||||||
from homeassistant.components.wled.const import CONF_KEEP_MASTER_LIGHT, DOMAIN
|
from homeassistant.components.wled.const import CONF_KEEP_MAIN_LIGHT, DOMAIN
|
||||||
from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
|
from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
|
||||||
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME
|
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
@ -271,10 +271,10 @@ async def test_options_flow(
|
|||||||
|
|
||||||
result2 = await hass.config_entries.options.async_configure(
|
result2 = await hass.config_entries.options.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
user_input={CONF_KEEP_MASTER_LIGHT: True},
|
user_input={CONF_KEEP_MAIN_LIGHT: True},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result2.get("type") == FlowResultType.CREATE_ENTRY
|
assert result2.get("type") == FlowResultType.CREATE_ENTRY
|
||||||
assert result2.get("data") == {
|
assert result2.get("data") == {
|
||||||
CONF_KEEP_MASTER_LIGHT: True,
|
CONF_KEEP_MAIN_LIGHT: True,
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ from homeassistant.components.light import (
|
|||||||
ATTR_TRANSITION,
|
ATTR_TRANSITION,
|
||||||
DOMAIN as LIGHT_DOMAIN,
|
DOMAIN as LIGHT_DOMAIN,
|
||||||
)
|
)
|
||||||
from homeassistant.components.wled.const import CONF_KEEP_MASTER_LIGHT, SCAN_INTERVAL
|
from homeassistant.components.wled.const import CONF_KEEP_MAIN_LIGHT, SCAN_INTERVAL
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
ATTR_ICON,
|
ATTR_ICON,
|
||||||
@ -355,7 +355,7 @@ async def test_single_segment_with_keep_main_light(
|
|||||||
assert not hass.states.get("light.wled_rgb_light_main")
|
assert not hass.states.get("light.wled_rgb_light_main")
|
||||||
|
|
||||||
hass.config_entries.async_update_entry(
|
hass.config_entries.async_update_entry(
|
||||||
init_integration, options={CONF_KEEP_MASTER_LIGHT: True}
|
init_integration, options={CONF_KEEP_MAIN_LIGHT: True}
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user