mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Add entity translations to WLED (#99056)
This commit is contained in:
parent
70c6bceaee
commit
9672cdf3a9
@ -28,7 +28,6 @@ class WLEDRestartButton(WLEDEntity, ButtonEntity):
|
||||
|
||||
_attr_device_class = ButtonDeviceClass.RESTART
|
||||
_attr_entity_category = EntityCategory.CONFIG
|
||||
_attr_name = "Restart"
|
||||
|
||||
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
|
||||
"""Initialize the button entity."""
|
||||
|
@ -46,7 +46,7 @@ class WLEDDataUpdateCoordinator(DataUpdateCoordinator[WLEDDevice]):
|
||||
|
||||
@property
|
||||
def has_master_light(self) -> bool:
|
||||
"""Return if the coordinated device has an master light."""
|
||||
"""Return if the coordinated device has a master light."""
|
||||
return self.keep_master_light or (
|
||||
self.data is not None and len(self.data.state.segments) > 1
|
||||
)
|
||||
|
@ -52,7 +52,7 @@ class WLEDMasterLight(WLEDEntity, LightEntity):
|
||||
|
||||
_attr_color_mode = ColorMode.BRIGHTNESS
|
||||
_attr_icon = "mdi:led-strip-variant"
|
||||
_attr_name = "Master"
|
||||
_attr_translation_key = "main"
|
||||
_attr_supported_features = LightEntityFeature.TRANSITION
|
||||
_attr_supported_color_modes = {ColorMode.BRIGHTNESS}
|
||||
|
||||
@ -200,7 +200,7 @@ class WLEDSegmentLight(WLEDEntity, LightEntity):
|
||||
# WLED uses 100ms per unit, so 10 = 1 second.
|
||||
transition = round(kwargs[ATTR_TRANSITION] * 10)
|
||||
|
||||
# If there is no master control, and only 1 segment, handle the
|
||||
# If there is no master control, and only 1 segment, handle the master
|
||||
if not self.coordinator.has_master_light:
|
||||
await self.coordinator.wled.master(on=False, transition=transition)
|
||||
return
|
||||
|
@ -50,7 +50,6 @@ class WLEDLiveOverrideSelect(WLEDEntity, SelectEntity):
|
||||
|
||||
_attr_entity_category = EntityCategory.CONFIG
|
||||
_attr_icon = "mdi:theater"
|
||||
_attr_name = "Live override"
|
||||
_attr_translation_key = "live_override"
|
||||
|
||||
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
|
||||
@ -75,7 +74,7 @@ class WLEDPresetSelect(WLEDEntity, SelectEntity):
|
||||
"""Defined a WLED Preset select."""
|
||||
|
||||
_attr_icon = "mdi:playlist-play"
|
||||
_attr_name = "Preset"
|
||||
_attr_translation_key = "preset"
|
||||
|
||||
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
|
||||
"""Initialize WLED ."""
|
||||
@ -106,7 +105,7 @@ class WLEDPlaylistSelect(WLEDEntity, SelectEntity):
|
||||
"""Define a WLED Playlist select."""
|
||||
|
||||
_attr_icon = "mdi:play-speed"
|
||||
_attr_name = "Playlist"
|
||||
_attr_translation_key = "playlist"
|
||||
|
||||
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
|
||||
"""Initialize WLED playlist."""
|
||||
|
@ -50,7 +50,7 @@ class WLEDSensorEntityDescription(
|
||||
SENSORS: tuple[WLEDSensorEntityDescription, ...] = (
|
||||
WLEDSensorEntityDescription(
|
||||
key="estimated_current",
|
||||
name="Estimated current",
|
||||
translation_key="estimated_current",
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.MILLIAMPERE,
|
||||
device_class=SensorDeviceClass.CURRENT,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
@ -60,13 +60,13 @@ SENSORS: tuple[WLEDSensorEntityDescription, ...] = (
|
||||
),
|
||||
WLEDSensorEntityDescription(
|
||||
key="info_leds_count",
|
||||
name="LED count",
|
||||
translation_key="info_leds_count",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda device: device.info.leds.count,
|
||||
),
|
||||
WLEDSensorEntityDescription(
|
||||
key="info_leds_max_power",
|
||||
name="Max current",
|
||||
translation_key="info_leds_max_power",
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.MILLIAMPERE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
device_class=SensorDeviceClass.CURRENT,
|
||||
@ -75,7 +75,7 @@ SENSORS: tuple[WLEDSensorEntityDescription, ...] = (
|
||||
),
|
||||
WLEDSensorEntityDescription(
|
||||
key="uptime",
|
||||
name="Uptime",
|
||||
translation_key="uptime",
|
||||
device_class=SensorDeviceClass.TIMESTAMP,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
@ -83,7 +83,7 @@ SENSORS: tuple[WLEDSensorEntityDescription, ...] = (
|
||||
),
|
||||
WLEDSensorEntityDescription(
|
||||
key="free_heap",
|
||||
name="Free memory",
|
||||
translation_key="free_heap",
|
||||
icon="mdi:memory",
|
||||
native_unit_of_measurement=UnitOfInformation.BYTES,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
@ -94,7 +94,7 @@ SENSORS: tuple[WLEDSensorEntityDescription, ...] = (
|
||||
),
|
||||
WLEDSensorEntityDescription(
|
||||
key="wifi_signal",
|
||||
name="Wi-Fi signal",
|
||||
translation_key="wifi_signal",
|
||||
icon="mdi:wifi",
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
@ -104,7 +104,7 @@ SENSORS: tuple[WLEDSensorEntityDescription, ...] = (
|
||||
),
|
||||
WLEDSensorEntityDescription(
|
||||
key="wifi_rssi",
|
||||
name="Wi-Fi RSSI",
|
||||
translation_key="wifi_rssi",
|
||||
native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
|
||||
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
@ -114,7 +114,7 @@ SENSORS: tuple[WLEDSensorEntityDescription, ...] = (
|
||||
),
|
||||
WLEDSensorEntityDescription(
|
||||
key="wifi_channel",
|
||||
name="Wi-Fi channel",
|
||||
translation_key="wifi_channel",
|
||||
icon="mdi:wifi",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
@ -122,7 +122,7 @@ SENSORS: tuple[WLEDSensorEntityDescription, ...] = (
|
||||
),
|
||||
WLEDSensorEntityDescription(
|
||||
key="wifi_bssid",
|
||||
name="Wi-Fi BSSID",
|
||||
translation_key="wifi_bssid",
|
||||
icon="mdi:wifi",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
@ -130,7 +130,7 @@ SENSORS: tuple[WLEDSensorEntityDescription, ...] = (
|
||||
),
|
||||
WLEDSensorEntityDescription(
|
||||
key="ip",
|
||||
name="IP",
|
||||
translation_key="ip",
|
||||
icon="mdi:ip-network",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda device: device.info.ip,
|
||||
|
@ -32,13 +32,68 @@
|
||||
}
|
||||
},
|
||||
"entity": {
|
||||
"light": {
|
||||
"main": {
|
||||
"name": "Main"
|
||||
}
|
||||
},
|
||||
"select": {
|
||||
"live_override": {
|
||||
"name": "Live override",
|
||||
"state": {
|
||||
"0": "[%key:common::state::off%]",
|
||||
"1": "[%key:common::state::on%]",
|
||||
"2": "Until device restarts"
|
||||
}
|
||||
},
|
||||
"preset": {
|
||||
"name": "Preset"
|
||||
},
|
||||
"playlist": {
|
||||
"name": "Playlist"
|
||||
}
|
||||
},
|
||||
"sensor": {
|
||||
"estimated_current": {
|
||||
"name": "Estimated current"
|
||||
},
|
||||
"info_leds_count": {
|
||||
"name": "LED count"
|
||||
},
|
||||
"info_leds_max_power": {
|
||||
"name": "Max current"
|
||||
},
|
||||
"uptime": {
|
||||
"name": "Uptime"
|
||||
},
|
||||
"free_heap": {
|
||||
"name": "Free memory"
|
||||
},
|
||||
"wifi_signal": {
|
||||
"name": "Wi-Fi signal"
|
||||
},
|
||||
"wifi_rssi": {
|
||||
"name": "Wi-Fi RSSI"
|
||||
},
|
||||
"wifi_channel": {
|
||||
"name": "Wi-Fi channel"
|
||||
},
|
||||
"wifi_bssid": {
|
||||
"name": "Wi-Fi BSSID"
|
||||
},
|
||||
"ip": {
|
||||
"name": "IP"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"nightlight": {
|
||||
"name": "Nightlight"
|
||||
},
|
||||
"sync_send": {
|
||||
"name": "Sync send"
|
||||
},
|
||||
"sync_receive": {
|
||||
"name": "Sync receive"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -55,7 +55,7 @@ class WLEDNightlightSwitch(WLEDEntity, SwitchEntity):
|
||||
|
||||
_attr_icon = "mdi:weather-night"
|
||||
_attr_entity_category = EntityCategory.CONFIG
|
||||
_attr_name = "Nightlight"
|
||||
_attr_translation_key = "nightlight"
|
||||
|
||||
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
|
||||
"""Initialize WLED nightlight switch."""
|
||||
@ -93,7 +93,7 @@ class WLEDSyncSendSwitch(WLEDEntity, SwitchEntity):
|
||||
|
||||
_attr_icon = "mdi:upload-network-outline"
|
||||
_attr_entity_category = EntityCategory.CONFIG
|
||||
_attr_name = "Sync send"
|
||||
_attr_translation_key = "sync_send"
|
||||
|
||||
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
|
||||
"""Initialize WLED sync send switch."""
|
||||
@ -126,7 +126,7 @@ class WLEDSyncReceiveSwitch(WLEDEntity, SwitchEntity):
|
||||
|
||||
_attr_icon = "mdi:download-network-outline"
|
||||
_attr_entity_category = EntityCategory.CONFIG
|
||||
_attr_name = "Sync receive"
|
||||
_attr_translation_key = "sync_receive"
|
||||
|
||||
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
|
||||
"""Initialize WLED sync receive switch."""
|
||||
|
@ -36,7 +36,6 @@ class WLEDUpdateEntity(WLEDEntity, UpdateEntity):
|
||||
UpdateEntityFeature.INSTALL | UpdateEntityFeature.SPECIFIC_VERSION
|
||||
)
|
||||
_attr_title = "WLED"
|
||||
_attr_name = "Firmware"
|
||||
|
||||
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
|
||||
"""Initialize the update entity."""
|
||||
|
@ -310,7 +310,7 @@
|
||||
'original_name': 'Playlist',
|
||||
'platform': 'wled',
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'translation_key': 'playlist',
|
||||
'unique_id': 'aabbccddee11_playlist',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
@ -393,7 +393,7 @@
|
||||
'original_name': 'Preset',
|
||||
'platform': 'wled',
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'translation_key': 'preset',
|
||||
'unique_id': 'aabbccddee11_preset',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
|
@ -40,7 +40,7 @@
|
||||
'original_name': 'Nightlight',
|
||||
'platform': 'wled',
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'translation_key': 'nightlight',
|
||||
'unique_id': 'aabbccddeeff_nightlight',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
@ -189,7 +189,7 @@
|
||||
'original_name': 'Sync receive',
|
||||
'platform': 'wled',
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'translation_key': 'sync_receive',
|
||||
'unique_id': 'aabbccddeeff_sync_receive',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
@ -264,7 +264,7 @@
|
||||
'original_name': 'Sync send',
|
||||
'platform': 'wled',
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'translation_key': 'sync_send',
|
||||
'unique_id': 'aabbccddeeff_sync_send',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
|
@ -60,12 +60,12 @@ async def test_rgb_light_state(
|
||||
assert (entry := entity_registry.async_get("light.wled_rgb_light_segment_1"))
|
||||
assert entry.unique_id == "aabbccddeeff_1"
|
||||
|
||||
# Test master control of the lightstrip
|
||||
assert (state := hass.states.get("light.wled_rgb_light_master"))
|
||||
# Test main control of the lightstrip
|
||||
assert (state := hass.states.get("light.wled_rgb_light_main"))
|
||||
assert state.attributes.get(ATTR_BRIGHTNESS) == 127
|
||||
assert state.state == STATE_ON
|
||||
|
||||
assert (entry := entity_registry.async_get("light.wled_rgb_light_master"))
|
||||
assert (entry := entity_registry.async_get("light.wled_rgb_light_main"))
|
||||
assert entry.unique_id == "aabbccddeeff"
|
||||
|
||||
|
||||
@ -110,15 +110,15 @@ async def test_segment_change_state(
|
||||
)
|
||||
|
||||
|
||||
async def test_master_change_state(
|
||||
async def test_main_change_state(
|
||||
hass: HomeAssistant,
|
||||
mock_wled: MagicMock,
|
||||
) -> None:
|
||||
"""Test the change of state of the WLED master light control."""
|
||||
"""Test the change of state of the WLED main light control."""
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: "light.wled_rgb_light_master", ATTR_TRANSITION: 5},
|
||||
{ATTR_ENTITY_ID: "light.wled_rgb_light_main", ATTR_TRANSITION: 5},
|
||||
blocking=True,
|
||||
)
|
||||
assert mock_wled.master.call_count == 1
|
||||
@ -132,7 +132,7 @@ async def test_master_change_state(
|
||||
SERVICE_TURN_ON,
|
||||
{
|
||||
ATTR_BRIGHTNESS: 42,
|
||||
ATTR_ENTITY_ID: "light.wled_rgb_light_master",
|
||||
ATTR_ENTITY_ID: "light.wled_rgb_light_main",
|
||||
ATTR_TRANSITION: 5,
|
||||
},
|
||||
blocking=True,
|
||||
@ -147,7 +147,7 @@ async def test_master_change_state(
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: "light.wled_rgb_light_master", ATTR_TRANSITION: 5},
|
||||
{ATTR_ENTITY_ID: "light.wled_rgb_light_main", ATTR_TRANSITION: 5},
|
||||
blocking=True,
|
||||
)
|
||||
assert mock_wled.master.call_count == 3
|
||||
@ -161,7 +161,7 @@ async def test_master_change_state(
|
||||
SERVICE_TURN_ON,
|
||||
{
|
||||
ATTR_BRIGHTNESS: 42,
|
||||
ATTR_ENTITY_ID: "light.wled_rgb_light_master",
|
||||
ATTR_ENTITY_ID: "light.wled_rgb_light_main",
|
||||
ATTR_TRANSITION: 5,
|
||||
},
|
||||
blocking=True,
|
||||
@ -183,7 +183,7 @@ async def test_dynamically_handle_segments(
|
||||
"""Test if a new/deleted segment is dynamically added/removed."""
|
||||
assert (segment0 := hass.states.get("light.wled_rgb_light"))
|
||||
assert segment0.state == STATE_ON
|
||||
assert not hass.states.get("light.wled_rgb_light_master")
|
||||
assert not hass.states.get("light.wled_rgb_light_main")
|
||||
assert not hass.states.get("light.wled_rgb_light_segment_1")
|
||||
|
||||
return_value = mock_wled.update.return_value
|
||||
@ -195,21 +195,21 @@ async def test_dynamically_handle_segments(
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert (master := hass.states.get("light.wled_rgb_light_master"))
|
||||
assert master.state == STATE_ON
|
||||
assert (main := hass.states.get("light.wled_rgb_light_main"))
|
||||
assert main.state == STATE_ON
|
||||
assert (segment0 := hass.states.get("light.wled_rgb_light"))
|
||||
assert segment0.state == STATE_ON
|
||||
assert (segment1 := hass.states.get("light.wled_rgb_light_segment_1"))
|
||||
assert segment1.state == STATE_ON
|
||||
|
||||
# Test adding if segment shows up again, including the master entity
|
||||
# Test adding if segment shows up again, including the main entity
|
||||
mock_wled.update.return_value = return_value
|
||||
freezer.tick(SCAN_INTERVAL)
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert (master := hass.states.get("light.wled_rgb_light_master"))
|
||||
assert master.state == STATE_UNAVAILABLE
|
||||
assert (main := hass.states.get("light.wled_rgb_light_main"))
|
||||
assert main.state == STATE_UNAVAILABLE
|
||||
assert (segment0 := hass.states.get("light.wled_rgb_light"))
|
||||
assert segment0.state == STATE_ON
|
||||
assert (segment1 := hass.states.get("light.wled_rgb_light_segment_1"))
|
||||
@ -225,11 +225,11 @@ async def test_single_segment_behavior(
|
||||
"""Test the behavior of the integration with a single segment."""
|
||||
device = mock_wled.update.return_value
|
||||
|
||||
assert not hass.states.get("light.wled_rgb_light_master")
|
||||
assert not hass.states.get("light.wled_rgb_light_main")
|
||||
assert (state := hass.states.get("light.wled_rgb_light"))
|
||||
assert state.state == STATE_ON
|
||||
|
||||
# Test segment brightness takes master into account
|
||||
# Test segment brightness takes main into account
|
||||
device.state.brightness = 100
|
||||
device.state.segments[0].brightness = 255
|
||||
freezer.tick(SCAN_INTERVAL)
|
||||
@ -239,7 +239,7 @@ async def test_single_segment_behavior(
|
||||
assert (state := hass.states.get("light.wled_rgb_light"))
|
||||
assert state.attributes.get(ATTR_BRIGHTNESS) == 100
|
||||
|
||||
# Test segment is off when master is off
|
||||
# Test segment is off when main is off
|
||||
device.state.on = False
|
||||
freezer.tick(SCAN_INTERVAL)
|
||||
async_fire_time_changed(hass)
|
||||
@ -248,7 +248,7 @@ async def test_single_segment_behavior(
|
||||
assert state
|
||||
assert state.state == STATE_OFF
|
||||
|
||||
# Test master is turned off when turning off a single segment
|
||||
# Test main is turned off when turning off a single segment
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
@ -261,7 +261,7 @@ async def test_single_segment_behavior(
|
||||
transition=50,
|
||||
)
|
||||
|
||||
# Test master is turned on when turning on a single segment, and segment
|
||||
# Test main is turned on when turning on a single segment, and segment
|
||||
# brightness is set to 255.
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
@ -346,18 +346,18 @@ async def test_rgbw_light(hass: HomeAssistant, mock_wled: MagicMock) -> None:
|
||||
|
||||
|
||||
@pytest.mark.parametrize("device_fixture", ["rgb_single_segment"])
|
||||
async def test_single_segment_with_keep_master_light(
|
||||
async def test_single_segment_with_keep_main_light(
|
||||
hass: HomeAssistant,
|
||||
init_integration: MockConfigEntry,
|
||||
mock_wled: MagicMock,
|
||||
) -> None:
|
||||
"""Test the behavior of the integration with a single segment."""
|
||||
assert not hass.states.get("light.wled_rgb_light_master")
|
||||
assert not hass.states.get("light.wled_rgb_light_main")
|
||||
|
||||
hass.config_entries.async_update_entry(
|
||||
init_integration, options={CONF_KEEP_MASTER_LIGHT: True}
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert (state := hass.states.get("light.wled_rgb_light_master"))
|
||||
assert (state := hass.states.get("light.wled_rgb_light_main"))
|
||||
assert state.state == STATE_ON
|
||||
|
Loading…
x
Reference in New Issue
Block a user