-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Wallbox set maximum charging current as number (#165)
Based on the discussion in issue #47 and requested by @Wolfgang-03, This PR implements the functionality to set the maximum charging current for a wallbox via a number Entity (Which allows sliders without helpers). Under the hood, this PR brings the following features: - Introduces E3DCNumber which allows to call methods on-change. (Will be handy for setting other E3DC values in the future) - Reads & respects the hard upper and lower current limits as stored in the wallbox. These limits can only be set by the E3DC electrician during installation, so this is now more fail-safe compared to the previously hardcoded limits. For reference, see the two videos: First one shows how by changing the number, the sensor which reads back from the E3DC the set current updates. https://github.com/user-attachments/assets/595fbdda-e6d0-4a9e-b422-128d929c4a8b 2nd one shows how Number as well as Sensor update, when changing the max charging current from somewhere else (In this case i had a 2nd HA instance running on another machine and changed from there max charging current. https://github.com/user-attachments/assets/919f8ad6-c7d0-4afc-b6b9-88569befd37b
- Loading branch information
Showing
6 changed files
with
183 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
"""E3DC Number platform.""" | ||
|
||
from collections.abc import Callable, Coroutine | ||
from dataclasses import dataclass | ||
import logging | ||
from typing import Any | ||
|
||
from homeassistant.components.number import ( | ||
NumberDeviceClass, | ||
NumberEntity, | ||
NumberEntityDescription, | ||
) | ||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.core import HomeAssistant, callback | ||
from homeassistant.const import EntityCategory | ||
|
||
from homeassistant.helpers.entity import DeviceInfo | ||
from homeassistant.helpers.entity_platform import AddEntitiesCallback | ||
from homeassistant.helpers.update_coordinator import CoordinatorEntity | ||
|
||
from .const import DOMAIN | ||
from .coordinator import E3DCCoordinator | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
@dataclass | ||
class E3DCNumberEntityDescription(NumberEntityDescription): | ||
"""Derived helper for advanced configs.""" | ||
|
||
async_set_native_value_action: Callable[ | ||
[E3DCCoordinator, float, int], Coroutine[Any, Any, bool] | ||
] | None = None | ||
|
||
|
||
async def async_setup_entry( | ||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback | ||
) -> None: | ||
"""Initialize Number Platform.""" | ||
assert isinstance(entry.unique_id, str) | ||
coordinator: E3DCCoordinator = hass.data[DOMAIN][entry.unique_id] | ||
entities: list[E3DCNumber] = [] | ||
|
||
# Add Number descriptions for wallboxes | ||
for wallbox in coordinator.wallboxes: | ||
unique_id = list(wallbox["deviceInfo"]["identifiers"])[0][1] | ||
wallbox_key = wallbox["key"] | ||
|
||
wallbox_charge_current_limit_description = E3DCNumberEntityDescription( | ||
key=f"{wallbox_key}-max-charge-current", | ||
translation_key="wallbox-max-charge-current", | ||
name="Wallbox Max Charge Current", | ||
icon="mdi:current-ac", | ||
native_min_value=wallbox["lowerCurrentLimit"], | ||
native_max_value=wallbox["upperCurrentLimit"], | ||
native_step=1, | ||
device_class=NumberDeviceClass.CURRENT, | ||
entity_category=EntityCategory.CONFIG, | ||
native_unit_of_measurement="A", | ||
async_set_native_value_action=lambda coordinator, value, index=wallbox["index"]: coordinator.async_set_wallbox_max_charge_current(int(value), index), | ||
) | ||
entities.append(E3DCNumber(coordinator, wallbox_charge_current_limit_description, unique_id, wallbox["deviceInfo"])) | ||
|
||
async_add_entities(entities) | ||
|
||
|
||
class E3DCNumber(CoordinatorEntity, NumberEntity): | ||
"""Custom E3DC Number Implementation.""" | ||
|
||
_attr_has_entity_name = True | ||
|
||
def __init__( | ||
self, | ||
coordinator: E3DCCoordinator, | ||
description: E3DCNumberEntityDescription, | ||
uid: str, | ||
device_info: DeviceInfo | None = None | ||
) -> None: | ||
"""Initialize the Number.""" | ||
super().__init__(coordinator) | ||
self.coordinator: E3DCCoordinator = coordinator | ||
self.entity_description: E3DCNumberEntityDescription = description | ||
self._attr_value = self.coordinator.data.get(self.entity_description.key) | ||
self._attr_unique_id = f"{uid}_{description.key}" | ||
if device_info is not None: | ||
self._deviceInfo = device_info | ||
else: | ||
self._deviceInfo = self.coordinator.device_info() | ||
|
||
@property | ||
def native_value(self): | ||
"""Return the current value.""" | ||
return self._attr_value | ||
|
||
@callback | ||
def _handle_coordinator_update(self) -> None: | ||
"""Process coordinator updates.""" | ||
self._attr_value = self.coordinator.data.get(self.entity_description.key) | ||
self.async_write_ha_state() | ||
|
||
async def async_set_native_value(self, value: float) -> None: | ||
"""Set the number value asynchronously.""" | ||
if self.entity_description.async_set_native_value_action is not None: | ||
self._attr_value = value | ||
self.async_write_ha_state() | ||
await self.entity_description.async_set_native_value_action(self.coordinator, value) | ||
|
||
@property | ||
def device_info(self) -> DeviceInfo: | ||
"""Return the device information.""" | ||
return self._deviceInfo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters