Add select platform to the Lektrico integration (#126490)

* Add select for Lektrico integration.

* Rename lb_mode to load_balancing_mode.

* Update homeassistant/components/lektrico/strings.json

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
Lektri.co 2024-09-24 13:08:28 +03:00 committed by GitHub
parent f2092ef083
commit 4ac9b339a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 200 additions and 2 deletions

View File

@ -18,7 +18,11 @@ CHARGERS_PLATFORMS: list[Platform] = [
]
# List the platforms that load balancer device supports.
LB_DEVICES_PLATFORMS: list[Platform] = [Platform.BUTTON, Platform.SENSOR]
LB_DEVICES_PLATFORMS: list[Platform] = [
Platform.BUTTON,
Platform.SELECT,
Platform.SENSOR,
]
type LektricoConfigEntry = ConfigEntry[LektricoDeviceDataUpdateCoordinator]

View File

@ -0,0 +1,91 @@
"""Support for Lektrico select entities."""
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from typing import Any
from lektricowifi import Device
from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.const import ATTR_SERIAL_NUMBER, CONF_TYPE, EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import LektricoConfigEntry, LektricoDeviceDataUpdateCoordinator
from .entity import LektricoEntity
@dataclass(frozen=True, kw_only=True)
class LektricoSelectEntityDescription(SelectEntityDescription):
"""Describes Lektrico select entity."""
value_fn: Callable[[dict[str, Any]], str]
set_value_fn: Callable[[Device, int], Coroutine[Any, Any, dict[Any, Any]]]
LB_MODE_OPTIONS = [
"disabled",
"power",
"hybrid",
"green",
]
SELECTS: tuple[LektricoSelectEntityDescription, ...] = (
LektricoSelectEntityDescription(
key="load_balancing_mode",
translation_key="load_balancing_mode",
options=LB_MODE_OPTIONS,
entity_category=EntityCategory.CONFIG,
value_fn=lambda data: LB_MODE_OPTIONS[data["lb_mode"]],
set_value_fn=lambda device, value: device.set_load_balancing_mode(value),
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: LektricoConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up Lektrico select entities based on a config entry."""
coordinator = entry.runtime_data
async_add_entities(
LektricoSelect(
description,
coordinator,
f"{entry.data[CONF_TYPE]}_{entry.data[ATTR_SERIAL_NUMBER]}",
)
for description in SELECTS
)
class LektricoSelect(LektricoEntity, SelectEntity):
"""Defines a Lektrico select entity."""
entity_description: LektricoSelectEntityDescription
def __init__(
self,
description: LektricoSelectEntityDescription,
coordinator: LektricoDeviceDataUpdateCoordinator,
device_name: str,
) -> None:
"""Initialize Lektrico select."""
super().__init__(coordinator, device_name)
self.entity_description = description
self._attr_unique_id = f"{coordinator.serial_number}_{description.key}"
@property
def current_option(self) -> str | None:
"""Return the state of the select."""
return self.entity_description.value_fn(self.coordinator.data)
async def async_select_option(self, option: str) -> None:
"""Change the selected option."""
await self.entity_description.set_value_fn(
self.coordinator.device, LB_MODE_OPTIONS.index(option)
)
await self.coordinator.async_request_refresh()

View File

@ -38,6 +38,17 @@
"name": "Dynamic limit"
}
},
"select": {
"load_balancing_mode": {
"name": "Load balancing mode",
"state": {
"disabled": "[%key:common::state::disabled%]",
"power": "Power",
"hybrid": "Hybrid",
"green": "Green"
}
}
},
"sensor": {
"state": {
"name": "State",

View File

@ -12,5 +12,6 @@
"fw_version": "1.44",
"led_max_brightness": 20,
"dynamic_current": 32,
"user_current": 32
"user_current": 32,
"lb_mode": 0
}

View File

@ -0,0 +1,60 @@
# serializer version: 1
# name: test_all_entities[select.1p7k_500006_load_balancing_mode-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'disabled',
'power',
'hybrid',
'green',
]),
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'select',
'entity_category': <EntityCategory.CONFIG: 'config'>,
'entity_id': 'select.1p7k_500006_load_balancing_mode',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Load balancing mode',
'platform': 'lektrico',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'load_balancing_mode',
'unique_id': '500006_load_balancing_mode',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[select.1p7k_500006_load_balancing_mode-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': '1p7k_500006 Load balancing mode',
'options': list([
'disabled',
'power',
'hybrid',
'green',
]),
}),
'context': <ANY>,
'entity_id': 'select.1p7k_500006_load_balancing_mode',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'disabled',
})
# ---

View File

@ -0,0 +1,31 @@
"""Tests for the Lektrico select platform."""
from unittest.mock import AsyncMock, patch
from syrupy import SnapshotAssertion
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import setup_integration
from tests.common import MockConfigEntry, snapshot_platform
async def test_all_entities(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
mock_device: AsyncMock,
mock_config_entry: MockConfigEntry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test all entities."""
with patch.multiple(
"homeassistant.components.lektrico",
CHARGERS_PLATFORMS=[Platform.SELECT],
LB_DEVICES_PLATFORMS=[Platform.SELECT],
):
await setup_integration(hass, mock_config_entry)
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)