207 lines
6.3 KiB
Python
207 lines
6.3 KiB
Python
"""Number definitions."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from homeassistant.components.number import (
|
|
NumberDeviceClass,
|
|
NumberEntityDescription,
|
|
RestoreNumber,
|
|
)
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.const import (
|
|
ATTR_UNIT_OF_MEASUREMENT,
|
|
STATE_UNAVAILABLE,
|
|
STATE_UNKNOWN,
|
|
UnitOfTime,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
|
|
from . import NordpoolPlanner, NordpoolPlannerEntity
|
|
from .const import (
|
|
CONF_ACCEPT_COST_ENTITY,
|
|
CONF_ACCEPT_RATE_ENTITY,
|
|
CONF_DURATION_ENTITY,
|
|
CONF_END_TIME_ENTITY,
|
|
CONF_SEARCH_LENGTH_ENTITY,
|
|
CONF_START_TIME_ENTITY,
|
|
DOMAIN,
|
|
)
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
DURATION_ENTITY_DESCRIPTION = NumberEntityDescription(
|
|
key=CONF_DURATION_ENTITY,
|
|
device_class=NumberDeviceClass.DURATION,
|
|
native_min_value=1,
|
|
native_max_value=8,
|
|
native_step=1,
|
|
native_unit_of_measurement=UnitOfTime.HOURS,
|
|
)
|
|
ACCEPT_COST_ENTITY_DESCRIPTION = NumberEntityDescription(
|
|
key=CONF_ACCEPT_COST_ENTITY,
|
|
device_class=NumberDeviceClass.MONETARY,
|
|
native_min_value=-20.0,
|
|
native_max_value=20.0,
|
|
native_step=0.01,
|
|
)
|
|
ACCEPT_RATE_ENTITY_DESCRIPTION = NumberEntityDescription(
|
|
key=CONF_ACCEPT_RATE_ENTITY,
|
|
device_class=NumberDeviceClass.DATA_RATE,
|
|
native_min_value=0.1,
|
|
native_max_value=1.0,
|
|
native_step=0.1,
|
|
)
|
|
SEARCH_LENGTH_ENTITY_DESCRIPTION = NumberEntityDescription(
|
|
key=CONF_SEARCH_LENGTH_ENTITY,
|
|
device_class=NumberDeviceClass.DURATION,
|
|
native_min_value=3,
|
|
native_max_value=23, # Let's keep it below 24h to not risk wrapping a day.
|
|
native_step=1,
|
|
native_unit_of_measurement=UnitOfTime.HOURS,
|
|
)
|
|
END_TIME_ENTITY_DESCRIPTION = NumberEntityDescription(
|
|
key=CONF_END_TIME_ENTITY,
|
|
device_class=NumberDeviceClass.DURATION,
|
|
native_min_value=0,
|
|
native_max_value=23,
|
|
native_step=1,
|
|
native_unit_of_measurement=UnitOfTime.HOURS,
|
|
)
|
|
START_TIME_ENTITY_DESCRIPTION = NumberEntityDescription(
|
|
key=CONF_START_TIME_ENTITY,
|
|
device_class=NumberDeviceClass.DURATION,
|
|
native_min_value=0,
|
|
native_max_value=23,
|
|
native_step=1,
|
|
native_unit_of_measurement=UnitOfTime.HOURS,
|
|
)
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities
|
|
):
|
|
"""Create configuration number entities for platform."""
|
|
|
|
planner: NordpoolPlanner = hass.data[DOMAIN][config_entry.entry_id]
|
|
entities = []
|
|
|
|
if config_entry.data.get(CONF_DURATION_ENTITY):
|
|
entities.append(
|
|
NordpoolPlannerNumber(
|
|
planner,
|
|
start_val=3,
|
|
entity_description=DURATION_ENTITY_DESCRIPTION,
|
|
)
|
|
)
|
|
|
|
if config_entry.data.get(CONF_ACCEPT_COST_ENTITY):
|
|
entity_description = ACCEPT_COST_ENTITY_DESCRIPTION
|
|
# Override if currency option is set
|
|
if unit_of_measurement := config_entry.options.get(ATTR_UNIT_OF_MEASUREMENT):
|
|
entity_description = NumberEntityDescription(
|
|
key=ACCEPT_COST_ENTITY_DESCRIPTION.key,
|
|
device_class=ACCEPT_COST_ENTITY_DESCRIPTION.device_class,
|
|
native_min_value=ACCEPT_COST_ENTITY_DESCRIPTION.native_min_value,
|
|
native_max_value=ACCEPT_COST_ENTITY_DESCRIPTION.native_max_value,
|
|
native_step=ACCEPT_COST_ENTITY_DESCRIPTION.native_step,
|
|
native_unit_of_measurement=unit_of_measurement,
|
|
)
|
|
entities.append(
|
|
NordpoolPlannerNumber(
|
|
planner,
|
|
start_val=0.0,
|
|
entity_description=entity_description,
|
|
)
|
|
)
|
|
|
|
if config_entry.data.get(CONF_ACCEPT_RATE_ENTITY):
|
|
entities.append(
|
|
NordpoolPlannerNumber(
|
|
planner,
|
|
start_val=0.1,
|
|
entity_description=ACCEPT_RATE_ENTITY_DESCRIPTION,
|
|
)
|
|
)
|
|
|
|
if config_entry.data.get(CONF_SEARCH_LENGTH_ENTITY):
|
|
entities.append(
|
|
NordpoolPlannerNumber(
|
|
planner,
|
|
start_val=10,
|
|
entity_description=SEARCH_LENGTH_ENTITY_DESCRIPTION,
|
|
)
|
|
)
|
|
|
|
if config_entry.data.get(CONF_END_TIME_ENTITY):
|
|
entities.append(
|
|
NordpoolPlannerNumber(
|
|
planner,
|
|
start_val=7,
|
|
entity_description=END_TIME_ENTITY_DESCRIPTION,
|
|
)
|
|
)
|
|
|
|
if config_entry.data.get(CONF_START_TIME_ENTITY):
|
|
entities.append(
|
|
NordpoolPlannerNumber(
|
|
planner,
|
|
start_val=18,
|
|
entity_description=START_TIME_ENTITY_DESCRIPTION,
|
|
)
|
|
)
|
|
|
|
async_add_entities(entities)
|
|
return True
|
|
|
|
|
|
class NordpoolPlannerNumber(NordpoolPlannerEntity, RestoreNumber):
|
|
"""Number config entity."""
|
|
|
|
def __init__(
|
|
self,
|
|
planner,
|
|
start_val,
|
|
entity_description: NumberEntityDescription,
|
|
) -> None:
|
|
"""Initialize the entity."""
|
|
super().__init__(planner)
|
|
self.entity_description = entity_description
|
|
self._default_value = start_val
|
|
self._attr_name = (
|
|
self._planner.name
|
|
+ " "
|
|
+ entity_description.key.replace("_entity", "").replace("_", " ")
|
|
)
|
|
self._attr_unique_id = (
|
|
("nordpool_planner_" + self._attr_name)
|
|
.lower()
|
|
.replace(".", "")
|
|
.replace(" ", "_")
|
|
)
|
|
|
|
async def async_added_to_hass(self) -> None:
|
|
"""Load the last known state when added to hass."""
|
|
await super().async_added_to_hass()
|
|
if (last_state := await self.async_get_last_state()) and (
|
|
last_number_data := await self.async_get_last_number_data()
|
|
):
|
|
if last_state.state not in (STATE_UNKNOWN, STATE_UNAVAILABLE):
|
|
self._attr_native_value = last_number_data.native_value
|
|
else:
|
|
self._attr_native_value = self._default_value
|
|
self._planner.register_input_entity_id(
|
|
self.entity_id, self.entity_description.key
|
|
)
|
|
|
|
async def async_set_native_value(self, value: float) -> None:
|
|
"""Update the current value."""
|
|
self._attr_native_value = value
|
|
_LOGGER.debug(
|
|
"Got new async value %s for %s",
|
|
value,
|
|
self.name,
|
|
)
|
|
self.async_schedule_update_ha_state()
|