Add entity translations to Flux led (#95355)

This commit is contained in:
Joost Lekkerkerker 2023-06-27 16:58:57 +02:00 committed by GitHub
parent 90854df5b2
commit e19b29d6ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 104 additions and 53 deletions

View file

@ -10,7 +10,7 @@ from homeassistant.components.button import (
ButtonEntity,
ButtonEntityDescription,
)
from homeassistant.const import CONF_NAME, EntityCategory
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -22,10 +22,13 @@ _RESTART_KEY = "restart"
_UNPAIR_REMOTES_KEY = "unpair_remotes"
RESTART_BUTTON_DESCRIPTION = ButtonEntityDescription(
key=_RESTART_KEY, name="Restart", device_class=ButtonDeviceClass.RESTART
key=_RESTART_KEY,
device_class=ButtonDeviceClass.RESTART,
)
UNPAIR_REMOTES_DESCRIPTION = ButtonEntityDescription(
key=_UNPAIR_REMOTES_KEY, name="Unpair Remotes", icon="mdi:remote-off"
key=_UNPAIR_REMOTES_KEY,
translation_key="unpair_remotes",
icon="mdi:remote-off",
)
@ -62,7 +65,6 @@ class FluxButton(FluxBaseEntity, ButtonEntity):
"""Initialize the button."""
self.entity_description = description
super().__init__(device, entry)
self._attr_name = f"{entry.data.get(CONF_NAME, entry.title)} {description.name}"
base_unique_id = entry.unique_id or entry.entry_id
self._attr_unique_id = f"{base_unique_id}_{description.key}"

View file

@ -54,6 +54,7 @@ def _async_device_info(
class FluxBaseEntity(Entity):
"""Representation of a Flux entity without a coordinator."""
_attr_has_entity_name = True
_attr_should_poll = False
def __init__(
@ -70,18 +71,18 @@ class FluxBaseEntity(Entity):
class FluxEntity(CoordinatorEntity[FluxLedUpdateCoordinator]):
"""Representation of a Flux entity with a coordinator."""
_attr_has_entity_name = True
def __init__(
self,
coordinator: FluxLedUpdateCoordinator,
base_unique_id: str,
name: str,
key: str | None,
) -> None:
"""Initialize the light."""
super().__init__(coordinator)
self._device: AIOWifiLedBulb = coordinator.device
self._responding = True
self._attr_name = name
if key:
self._attr_unique_id = f"{base_unique_id}_{key}"
else:

View file

@ -22,7 +22,6 @@ from homeassistant.components.light import (
LightEntity,
LightEntityFeature,
)
from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import entity_platform
import homeassistant.helpers.config_validation as cv
@ -177,7 +176,6 @@ async def async_setup_entry(
FluxLight(
coordinator,
entry.unique_id or entry.entry_id,
entry.data.get(CONF_NAME, entry.title),
list(custom_effect_colors),
options.get(CONF_CUSTOM_EFFECT_SPEED_PCT, DEFAULT_EFFECT_SPEED),
options.get(CONF_CUSTOM_EFFECT_TRANSITION, TRANSITION_GRADUAL),
@ -191,19 +189,20 @@ class FluxLight(
):
"""Representation of a Flux light."""
_attr_name = None
_attr_supported_features = LightEntityFeature.TRANSITION | LightEntityFeature.EFFECT
def __init__(
self,
coordinator: FluxLedUpdateCoordinator,
base_unique_id: str,
name: str,
custom_effect_colors: list[tuple[int, int, int]],
custom_effect_speed_pct: int,
custom_effect_transition: str,
) -> None:
"""Initialize the light."""
super().__init__(coordinator, base_unique_id, name, None)
super().__init__(coordinator, base_unique_id, None)
self._attr_min_mireds = color_temperature_kelvin_to_mired(self._device.max_temp)
self._attr_max_mireds = color_temperature_kelvin_to_mired(self._device.min_temp)
self._attr_supported_color_modes = _hass_color_modes(self._device)

View file

@ -18,7 +18,7 @@ from flux_led.protocol import (
from homeassistant import config_entries
from homeassistant.components.light import EFFECT_RANDOM
from homeassistant.components.number import NumberEntity, NumberMode
from homeassistant.const import CONF_NAME, EntityCategory
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.debounce import Debouncer
@ -50,7 +50,6 @@ async def async_setup_entry(
| FluxMusicPixelsPerSegmentNumber
| FluxMusicSegmentsNumber
] = []
name = entry.data.get(CONF_NAME, entry.title)
base_unique_id = entry.unique_id or entry.entry_id
if device.pixels_per_segment is not None:
@ -58,35 +57,25 @@ async def async_setup_entry(
FluxPixelsPerSegmentNumber(
coordinator,
base_unique_id,
f"{name} Pixels Per Segment",
"pixels_per_segment",
)
)
if device.segments is not None:
entities.append(
FluxSegmentsNumber(
coordinator, base_unique_id, f"{name} Segments", "segments"
)
)
entities.append(FluxSegmentsNumber(coordinator, base_unique_id, "segments"))
if device.music_pixels_per_segment is not None:
entities.append(
FluxMusicPixelsPerSegmentNumber(
coordinator,
base_unique_id,
f"{name} Music Pixels Per Segment",
"music_pixels_per_segment",
)
)
if device.music_segments is not None:
entities.append(
FluxMusicSegmentsNumber(
coordinator, base_unique_id, f"{name} Music Segments", "music_segments"
)
FluxMusicSegmentsNumber(coordinator, base_unique_id, "music_segments")
)
if device.effect_list and device.effect_list != [EFFECT_RANDOM]:
entities.append(
FluxSpeedNumber(coordinator, base_unique_id, f"{name} Effect Speed", None)
)
entities.append(FluxSpeedNumber(coordinator, base_unique_id, None))
async_add_entities(entities)
@ -101,6 +90,7 @@ class FluxSpeedNumber(
_attr_native_step = 1
_attr_mode = NumberMode.SLIDER
_attr_icon = "mdi:speedometer"
_attr_translation_key = "effect_speed"
@property
def native_value(self) -> float:
@ -137,11 +127,10 @@ class FluxConfigNumber(
self,
coordinator: FluxLedUpdateCoordinator,
base_unique_id: str,
name: str,
key: str | None,
) -> None:
"""Initialize the flux number."""
super().__init__(coordinator, base_unique_id, name, key)
super().__init__(coordinator, base_unique_id, key)
self._debouncer: Debouncer[Coroutine[Any, Any, None]] | None = None
self._pending_value: int | None = None
@ -185,6 +174,7 @@ class FluxConfigNumber(
class FluxPixelsPerSegmentNumber(FluxConfigNumber):
"""Defines a flux_led pixels per segment number."""
_attr_translation_key = "pixels_per_segment"
_attr_icon = "mdi:dots-grid"
@property
@ -211,6 +201,7 @@ class FluxPixelsPerSegmentNumber(FluxConfigNumber):
class FluxSegmentsNumber(FluxConfigNumber):
"""Defines a flux_led segments number."""
_attr_translation_key = "segments"
_attr_icon = "mdi:segment"
@property
@ -245,6 +236,7 @@ class FluxMusicNumber(FluxConfigNumber):
class FluxMusicPixelsPerSegmentNumber(FluxMusicNumber):
"""Defines a flux_led music pixels per segment number."""
_attr_translation_key = "music_pixels_per_segment"
_attr_icon = "mdi:dots-grid"
@property
@ -273,6 +265,7 @@ class FluxMusicPixelsPerSegmentNumber(FluxMusicNumber):
class FluxMusicSegmentsNumber(FluxMusicNumber):
"""Defines a flux_led music segments number."""
_attr_translation_key = "music_segments"
_attr_icon = "mdi:segment"
@property

View file

@ -52,30 +52,22 @@ async def async_setup_entry(
| FluxRemoteConfigSelect
| FluxWhiteChannelSelect
] = []
name = entry.data.get(CONF_NAME, entry.title)
entry.data.get(CONF_NAME, entry.title)
base_unique_id = entry.unique_id or entry.entry_id
if device.device_type == DeviceType.Switch:
entities.append(FluxPowerStateSelect(coordinator.device, entry))
if device.operating_modes:
entities.append(
FluxOperatingModesSelect(
coordinator, base_unique_id, f"{name} Operating Mode", "operating_mode"
)
FluxOperatingModesSelect(coordinator, base_unique_id, "operating_mode")
)
if device.wirings and device.wiring is not None:
entities.append(
FluxWiringsSelect(coordinator, base_unique_id, f"{name} Wiring", "wiring")
)
entities.append(FluxWiringsSelect(coordinator, base_unique_id, "wiring"))
if device.ic_types:
entities.append(
FluxICTypeSelect(coordinator, base_unique_id, f"{name} IC Type", "ic_type")
)
entities.append(FluxICTypeSelect(coordinator, base_unique_id, "ic_type"))
if device.remote_config:
entities.append(
FluxRemoteConfigSelect(
coordinator, base_unique_id, f"{name} Remote Config", "remote_config"
)
FluxRemoteConfigSelect(coordinator, base_unique_id, "remote_config")
)
if FLUX_COLOR_MODE_RGBW in device.color_modes:
entities.append(FluxWhiteChannelSelect(coordinator.device, entry))
@ -98,6 +90,7 @@ class FluxConfigSelect(FluxEntity, SelectEntity):
class FluxPowerStateSelect(FluxConfigAtStartSelect, SelectEntity):
"""Representation of a Flux power restore state option."""
_attr_translation_key = "power_restored"
_attr_icon = "mdi:transmission-tower-off"
_attr_options = list(NAME_TO_POWER_RESTORE_STATE)
@ -108,7 +101,6 @@ class FluxPowerStateSelect(FluxConfigAtStartSelect, SelectEntity):
) -> None:
"""Initialize the power state select."""
super().__init__(device, entry)
self._attr_name = f"{entry.data.get(CONF_NAME, entry.title)} Power Restored"
base_unique_id = entry.unique_id or entry.entry_id
self._attr_unique_id = f"{base_unique_id}_power_restored"
self._async_set_current_option_from_device()
@ -134,6 +126,7 @@ class FluxICTypeSelect(FluxConfigSelect):
"""Representation of Flux ic type."""
_attr_icon = "mdi:chip"
_attr_translation_key = "ic_type"
@property
def options(self) -> list[str]:
@ -156,6 +149,7 @@ class FluxWiringsSelect(FluxConfigSelect):
"""Representation of Flux wirings."""
_attr_icon = "mdi:led-strip-variant"
_attr_translation_key = "wiring"
@property
def options(self) -> list[str]:
@ -176,6 +170,8 @@ class FluxWiringsSelect(FluxConfigSelect):
class FluxOperatingModesSelect(FluxConfigSelect):
"""Representation of Flux operating modes."""
_attr_translation_key = "operating_mode"
@property
def options(self) -> list[str]:
"""Return the current operating mode."""
@ -196,15 +192,16 @@ class FluxOperatingModesSelect(FluxConfigSelect):
class FluxRemoteConfigSelect(FluxConfigSelect):
"""Representation of Flux remote config type."""
_attr_translation_key = "remote_config"
def __init__(
self,
coordinator: FluxLedUpdateCoordinator,
base_unique_id: str,
name: str,
key: str,
) -> None:
"""Initialize the remote config type select."""
super().__init__(coordinator, base_unique_id, name, key)
super().__init__(coordinator, base_unique_id, key)
assert self._device.remote_config is not None
self._name_to_state = {
_human_readable_option(option.name): option for option in RemoteConfig
@ -226,6 +223,8 @@ class FluxRemoteConfigSelect(FluxConfigSelect):
class FluxWhiteChannelSelect(FluxConfigAtStartSelect):
"""Representation of Flux white channel."""
_attr_translation_key = "white_channel"
_attr_options = [_human_readable_option(option.name) for option in WhiteChannelType]
def __init__(
@ -235,7 +234,6 @@ class FluxWhiteChannelSelect(FluxConfigAtStartSelect):
) -> None:
"""Initialize the white channel select."""
super().__init__(device, entry)
self._attr_name = f"{entry.data.get(CONF_NAME, entry.title)} White Channel"
base_unique_id = entry.unique_id or entry.entry_id
self._attr_unique_id = f"{base_unique_id}_white_channel"

View file

@ -3,7 +3,7 @@ from __future__ import annotations
from homeassistant import config_entries
from homeassistant.components.sensor import SensorEntity
from homeassistant.const import CONF_NAME, EntityCategory
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -25,7 +25,6 @@ async def async_setup_entry(
FluxPairedRemotes(
coordinator,
entry.unique_id or entry.entry_id,
f"{entry.data.get(CONF_NAME, entry.title)} Paired Remotes",
"paired_remotes",
)
]
@ -37,6 +36,7 @@ class FluxPairedRemotes(FluxEntity, SensorEntity):
_attr_icon = "mdi:remote"
_attr_entity_category = EntityCategory.DIAGNOSTIC
_attr_translation_key = "paired_remotes"
@property
def native_value(self) -> int:

View file

@ -32,5 +32,62 @@
}
}
}
},
"entity": {
"button": {
"unpair_remotes": {
"name": "Unpair remotes"
}
},
"number": {
"pixels_per_segment": {
"name": "Pixels per segment"
},
"segments": {
"name": "Segments"
},
"music_pixels_per_segment": {
"name": "Music pixels per segment"
},
"music_segments": {
"name": "Music segments"
},
"effect_speed": {
"name": "Effect speed"
}
},
"select": {
"operating_mode": {
"name": "Operating mode"
},
"wiring": {
"name": "Wiring"
},
"ic_type": {
"name": "IC type"
},
"remote_config": {
"name": "Remote config"
},
"white_channel": {
"name": "White channel"
},
"power_restored": {
"name": "Power restored"
}
},
"sensor": {
"paired_remotes": {
"name": "Paired remotes"
}
},
"switch": {
"remote_access": {
"name": "Remote access"
},
"music": {
"name": "Music"
}
}
}
}

View file

@ -9,7 +9,7 @@ from flux_led.const import MODE_MUSIC
from homeassistant import config_entries
from homeassistant.components.switch import SwitchEntity
from homeassistant.const import CONF_NAME, EntityCategory
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
@ -34,18 +34,15 @@ async def async_setup_entry(
coordinator: FluxLedUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
entities: list[FluxSwitch | FluxRemoteAccessSwitch | FluxMusicSwitch] = []
base_unique_id = entry.unique_id or entry.entry_id
name = entry.data.get(CONF_NAME, entry.title)
if coordinator.device.device_type == DeviceType.Switch:
entities.append(FluxSwitch(coordinator, base_unique_id, name, None))
entities.append(FluxSwitch(coordinator, base_unique_id, None))
if entry.data.get(CONF_REMOTE_ACCESS_HOST):
entities.append(FluxRemoteAccessSwitch(coordinator.device, entry))
if coordinator.device.microphone:
entities.append(
FluxMusicSwitch(coordinator, base_unique_id, f"{name} Music", "music")
)
entities.append(FluxMusicSwitch(coordinator, base_unique_id, "music"))
async_add_entities(entities)
@ -55,6 +52,8 @@ class FluxSwitch(
):
"""Representation of a Flux switch."""
_attr_name = None
async def _async_turn_on(self, **kwargs: Any) -> None:
"""Turn the device on."""
if not self.is_on:
@ -65,6 +64,7 @@ class FluxRemoteAccessSwitch(FluxBaseEntity, SwitchEntity):
"""Representation of a Flux remote access switch."""
_attr_entity_category = EntityCategory.CONFIG
_attr_translation_key = "remote_access"
def __init__(
self,
@ -73,7 +73,6 @@ class FluxRemoteAccessSwitch(FluxBaseEntity, SwitchEntity):
) -> None:
"""Initialize the light."""
super().__init__(device, entry)
self._attr_name = f"{entry.data.get(CONF_NAME, entry.title)} Remote Access"
base_unique_id = entry.unique_id or entry.entry_id
self._attr_unique_id = f"{base_unique_id}_remote_access"
@ -113,6 +112,8 @@ class FluxRemoteAccessSwitch(FluxBaseEntity, SwitchEntity):
class FluxMusicSwitch(FluxEntity, SwitchEntity):
"""Representation of a Flux music switch."""
_attr_translation_key = "music"
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the microphone on."""
await self._async_ensure_device_on()