Set min, max, and step for ViCare number entities (#104593)

Co-authored-by: Robert Resch <robert@resch.dev>
pull/104650/head
Christopher Fenner 2023-11-28 10:53:59 +01:00 committed by GitHub
parent d1463a81d3
commit 1ef97ab6f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 25 deletions

View File

@ -135,7 +135,7 @@ async def _entities_from_descriptions(
hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG],
description,
)
if entity is not None:
if entity:
entities.append(entity)
@ -156,7 +156,7 @@ async def async_setup_entry(
hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG],
description,
)
if entity is not None:
if entity:
entities.append(entity)
circuits = await hass.async_add_executor_job(get_circuits, api)

View File

@ -79,7 +79,7 @@ async def async_setup_entry(
hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG],
description,
)
if entity is not None:
if entity:
entities.append(entity)
async_add_entities(entities)

View File

@ -10,7 +10,7 @@ from typing import Any
from PyViCare.PyViCareDevice import Device as PyViCareDevice
from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
from PyViCare.PyViCareHeatingDevice import (
HeatingDeviceWithComponent as PyViCareHeatingDeviceWithComponent,
HeatingDeviceWithComponent as PyViCareHeatingDeviceComponent,
)
from PyViCare.PyViCareUtils import (
PyViCareInvalidDataError,
@ -38,6 +38,9 @@ class ViCareNumberEntityDescription(NumberEntityDescription, ViCareRequiredKeysM
"""Describes ViCare number entity."""
value_setter: Callable[[PyViCareDevice, float], Any] | None = None
min_value_getter: Callable[[PyViCareDevice], float | None] | None = None
max_value_getter: Callable[[PyViCareDevice], float | None] | None = None
stepping_getter: Callable[[PyViCareDevice], float | None] | None = None
CIRCUIT_ENTITY_DESCRIPTIONS: tuple[ViCareNumberEntityDescription, ...] = (
@ -46,11 +49,14 @@ CIRCUIT_ENTITY_DESCRIPTIONS: tuple[ViCareNumberEntityDescription, ...] = (
translation_key="heating_curve_shift",
icon="mdi:plus-minus-variant",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
value_getter=lambda api: api.getHeatingCurveShift(),
value_setter=lambda api, shift: (
api.setHeatingCurve(shift, api.getHeatingCurveSlope())
),
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
min_value_getter=lambda api: api.getHeatingCurveShiftMin(),
max_value_getter=lambda api: api.getHeatingCurveShiftMax(),
stepping_getter=lambda api: api.getHeatingCurveShiftStepping(),
native_min_value=-13,
native_max_value=40,
native_step=1,
@ -64,6 +70,9 @@ CIRCUIT_ENTITY_DESCRIPTIONS: tuple[ViCareNumberEntityDescription, ...] = (
value_setter=lambda api, slope: (
api.setHeatingCurve(api.getHeatingCurveShift(), slope)
),
min_value_getter=lambda api: api.getHeatingCurveSlopeMin(),
max_value_getter=lambda api: api.getHeatingCurveSlopeMax(),
stepping_getter=lambda api: api.getHeatingCurveSlopeStepping(),
native_min_value=0.2,
native_max_value=3.5,
native_step=0.1,
@ -72,7 +81,7 @@ CIRCUIT_ENTITY_DESCRIPTIONS: tuple[ViCareNumberEntityDescription, ...] = (
def _build_entity(
vicare_api: PyViCareHeatingDeviceWithComponent,
vicare_api: PyViCareHeatingDeviceComponent,
device_config: PyViCareDeviceConfig,
entity_description: ViCareNumberEntityDescription,
) -> ViCareNumber | None:
@ -92,23 +101,21 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Create the ViCare number devices."""
api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API]
circuits = await hass.async_add_executor_job(get_circuits, api)
entities: list[ViCareNumber] = []
try:
for circuit in circuits:
for description in CIRCUIT_ENTITY_DESCRIPTIONS:
entity = await hass.async_add_executor_job(
_build_entity,
circuit,
hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG],
description,
)
if entity is not None:
entities.append(entity)
except PyViCareNotSupportedFeatureError:
_LOGGER.debug("No circuits found")
api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API]
device_config = hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG]
circuits = await hass.async_add_executor_job(get_circuits, api)
for circuit in circuits:
for description in CIRCUIT_ENTITY_DESCRIPTIONS:
entity = await hass.async_add_executor_job(
_build_entity,
circuit,
device_config,
description,
)
if entity:
entities.append(entity)
async_add_entities(entities)
@ -120,7 +127,7 @@ class ViCareNumber(ViCareEntity, NumberEntity):
def __init__(
self,
api: PyViCareHeatingDeviceWithComponent,
api: PyViCareHeatingDeviceComponent,
device_config: PyViCareDeviceConfig,
description: ViCareNumberEntityDescription,
) -> None:
@ -146,6 +153,20 @@ class ViCareNumber(ViCareEntity, NumberEntity):
self._attr_native_value = self.entity_description.value_getter(
self._api
)
if min_value := _get_value(
self.entity_description.min_value_getter, self._api
):
self._attr_native_min_value = min_value
if max_value := _get_value(
self.entity_description.max_value_getter, self._api
):
self._attr_native_max_value = max_value
if stepping_value := _get_value(
self.entity_description.stepping_getter, self._api
):
self._attr_native_step = stepping_value
except RequestConnectionError:
_LOGGER.error("Unable to retrieve data from ViCare server")
except ValueError:
@ -154,3 +175,10 @@ class ViCareNumber(ViCareEntity, NumberEntity):
_LOGGER.error("Vicare API rate limit exceeded: %s", limit_exception)
except PyViCareInvalidDataError as invalid_data_exception:
_LOGGER.error("Invalid data from Vicare server: %s", invalid_data_exception)
def _get_value(
fn: Callable[[PyViCareDevice], float | None] | None,
api: PyViCareHeatingDeviceComponent,
) -> float | None:
return None if fn is None else fn(api)

View File

@ -624,7 +624,7 @@ async def _entities_from_descriptions(
hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG],
description,
)
if entity is not None:
if entity:
entities.append(entity)
@ -647,7 +647,7 @@ async def async_setup_entry(
device_config,
description,
)
if entity is not None:
if entity:
entities.append(entity)
circuits = await hass.async_add_executor_job(get_circuits, api)