core/homeassistant/components/peblar/number.py

131 lines
4.8 KiB
Python

"""Support for Peblar numbers."""
from __future__ import annotations
from homeassistant.components.number import (
NumberDeviceClass,
NumberEntityDescription,
RestoreNumber,
)
from homeassistant.const import (
STATE_UNAVAILABLE,
STATE_UNKNOWN,
EntityCategory,
UnitOfElectricCurrent,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import PeblarConfigEntry, PeblarDataUpdateCoordinator
from .entity import PeblarEntity
from .helpers import peblar_exception_handler
PARALLEL_UPDATES = 1
async def async_setup_entry(
hass: HomeAssistant,
entry: PeblarConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up Peblar number based on a config entry."""
async_add_entities(
[
PeblarChargeCurrentLimitNumberEntity(
entry=entry,
coordinator=entry.runtime_data.data_coordinator,
)
]
)
class PeblarChargeCurrentLimitNumberEntity(
PeblarEntity[PeblarDataUpdateCoordinator],
RestoreNumber,
):
"""Defines a Peblar charge current limit number.
This entity is a little bit different from the other entities, any value
below 6 amps is ignored. It means the Peblar is not charging.
Peblar has assigned a dual functionality to the charge current limit
number, it is used to set the current charging value and to start/stop/pauze
the charging process.
"""
_attr_device_class = NumberDeviceClass.CURRENT
_attr_entity_category = EntityCategory.CONFIG
_attr_native_min_value = 6
_attr_native_step = 1
_attr_native_unit_of_measurement = UnitOfElectricCurrent.AMPERE
_attr_translation_key = "charge_current_limit"
def __init__(
self,
entry: PeblarConfigEntry,
coordinator: PeblarDataUpdateCoordinator,
) -> None:
"""Initialize the Peblar charge current limit entity."""
super().__init__(
entry=entry,
coordinator=coordinator,
description=NumberEntityDescription(key="charge_current_limit"),
)
configuration = entry.runtime_data.user_configuration_coordinator.data
self._attr_native_max_value = configuration.user_defined_charge_limit_current
async def async_added_to_hass(self) -> None:
"""Load the last known state when adding this entity."""
if (
(last_state := await self.async_get_last_state())
and (last_number_data := await self.async_get_last_number_data())
and last_state.state not in (STATE_UNKNOWN, STATE_UNAVAILABLE)
and last_number_data.native_value
):
self._attr_native_value = last_number_data.native_value
# Set the last known charging limit in the runtime data the
# start/stop/pauze functionality needs it in order to restore
# the last known charging limits when charging is resumed.
self.coordinator.config_entry.runtime_data.last_known_charging_limit = int(
last_number_data.native_value
)
await super().async_added_to_hass()
self._handle_coordinator_update()
@callback
def _handle_coordinator_update(self) -> None:
"""Handle coordinator update.
Ignore any update that provides a ampere value that is below the
minimum value (6 amps). It means the Peblar is currently not charging.
"""
if (
current_charge_limit := round(
self.coordinator.data.ev.charge_current_limit / 1000
)
) < 6:
return
self._attr_native_value = current_charge_limit
# Update the last known charging limit in the runtime data the
# start/stop/pauze functionality needs it in order to restore
# the last known charging limits when charging is resumed.
self.coordinator.config_entry.runtime_data.last_known_charging_limit = (
current_charge_limit
)
super()._handle_coordinator_update()
@peblar_exception_handler
async def async_set_native_value(self, value: float) -> None:
"""Change the current charging value."""
# If charging is currently disabled (below 6 amps), just set the value
# as the native value and the last known charging limit in the runtime
# data. So we can pick it up once charging gets enabled again.
if self.coordinator.data.ev.charge_current_limit < 6000:
self._attr_native_value = int(value)
self.coordinator.config_entry.runtime_data.last_known_charging_limit = int(
value
)
self.async_write_ha_state()
return
await self.coordinator.api.ev_interface(charge_current_limit=int(value) * 1000)
await self.coordinator.async_request_refresh()