From 40fdc840abb409ad9c751ba8ccfa8a468dc10fff Mon Sep 17 00:00:00 2001 From: Kevin Worrel <37058192+dieselrabbit@users.noreply.github.com> Date: Wed, 22 May 2024 12:52:09 -0700 Subject: [PATCH] Add number entities for screenlogic values used in SI calc (#117812) --- .../components/screenlogic/number.py | 86 ++++++++++++++++++- .../components/screenlogic/sensor.py | 4 + 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/screenlogic/number.py b/homeassistant/components/screenlogic/number.py index 76640339040..ca75f5fadce 100644 --- a/homeassistant/components/screenlogic/number.py +++ b/homeassistant/components/screenlogic/number.py @@ -5,12 +5,14 @@ import logging from screenlogicpy.const.common import ScreenLogicCommunicationError, ScreenLogicError from screenlogicpy.const.data import ATTR, DEVICE, GROUP, VALUE +from screenlogicpy.const.msg import CODE from screenlogicpy.device_const.system import EQUIPMENT_FLAG from homeassistant.components.number import ( DOMAIN, NumberEntity, NumberEntityDescription, + NumberMode, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory @@ -20,7 +22,12 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN as SL_DOMAIN from .coordinator import ScreenlogicDataUpdateCoordinator -from .entity import ScreenLogicEntity, ScreenLogicEntityDescription +from .entity import ( + ScreenLogicEntity, + ScreenLogicEntityDescription, + ScreenLogicPushEntity, + ScreenLogicPushEntityDescription, +) from .util import cleanup_excluded_entity, get_ha_unit _LOGGER = logging.getLogger(__name__) @@ -36,6 +43,45 @@ class ScreenLogicNumberDescription( """Describes a ScreenLogic number entity.""" +@dataclass(frozen=True, kw_only=True) +class ScreenLogicPushNumberDescription( + ScreenLogicNumberDescription, + ScreenLogicPushEntityDescription, +): + """Describes a ScreenLogic push number entity.""" + + +SUPPORTED_INTELLICHEM_NUMBERS = [ + ScreenLogicPushNumberDescription( + subscription_code=CODE.CHEMISTRY_CHANGED, + data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION), + key=VALUE.CALCIUM_HARDNESS, + entity_category=EntityCategory.CONFIG, + mode=NumberMode.BOX, + ), + ScreenLogicPushNumberDescription( + subscription_code=CODE.CHEMISTRY_CHANGED, + data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION), + key=VALUE.CYA, + entity_category=EntityCategory.CONFIG, + mode=NumberMode.BOX, + ), + ScreenLogicPushNumberDescription( + subscription_code=CODE.CHEMISTRY_CHANGED, + data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION), + key=VALUE.TOTAL_ALKALINITY, + entity_category=EntityCategory.CONFIG, + mode=NumberMode.BOX, + ), + ScreenLogicPushNumberDescription( + subscription_code=CODE.CHEMISTRY_CHANGED, + data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION), + key=VALUE.SALT_TDS_PPM, + entity_category=EntityCategory.CONFIG, + mode=NumberMode.BOX, + ), +] + SUPPORTED_SCG_NUMBERS = [ ScreenLogicNumberDescription( data_root=(DEVICE.SCG, GROUP.CONFIGURATION), @@ -62,6 +108,19 @@ async def async_setup_entry( ] gateway = coordinator.gateway + for chem_number_description in SUPPORTED_INTELLICHEM_NUMBERS: + chem_number_data_path = ( + *chem_number_description.data_root, + chem_number_description.key, + ) + if EQUIPMENT_FLAG.INTELLICHEM not in gateway.equipment_flags: + cleanup_excluded_entity(coordinator, DOMAIN, chem_number_data_path) + continue + if gateway.get_data(*chem_number_data_path): + entities.append( + ScreenLogicChemistryNumber(coordinator, chem_number_description) + ) + for scg_number_description in SUPPORTED_SCG_NUMBERS: scg_number_data_path = ( *scg_number_description.data_root, @@ -115,6 +174,31 @@ class ScreenLogicNumber(ScreenLogicEntity, NumberEntity): raise NotImplementedError +class ScreenLogicPushNumber(ScreenLogicPushEntity, ScreenLogicNumber): + """Base class to preresent a ScreenLogic Push Number entity.""" + + entity_description: ScreenLogicPushNumberDescription + + +class ScreenLogicChemistryNumber(ScreenLogicPushNumber): + """Class to represent a ScreenLogic Chemistry Number entity.""" + + async def async_set_native_value(self, value: float) -> None: + """Update the current value.""" + + # Current API requires int values for the currently supported numbers. + value = int(value) + + try: + await self.gateway.async_set_chem_data(**{self._data_key: value}) + except (ScreenLogicCommunicationError, ScreenLogicError) as sle: + raise HomeAssistantError( + f"Failed to set '{self._data_key}' to {value}: {sle.msg}" + ) from sle + _LOGGER.debug("Set '%s' to %s", self._data_key, value) + await self._async_refresh() + + class ScreenLogicSCGNumber(ScreenLogicNumber): """Class to represent a ScreenLoigic SCG Number entity.""" diff --git a/homeassistant/components/screenlogic/sensor.py b/homeassistant/components/screenlogic/sensor.py index e4fc86a6b5f..1a09f3c738a 100644 --- a/homeassistant/components/screenlogic/sensor.py +++ b/homeassistant/components/screenlogic/sensor.py @@ -136,11 +136,13 @@ SUPPORTED_INTELLICHEM_SENSORS = [ subscription_code=CODE.CHEMISTRY_CHANGED, data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION), key=VALUE.CALCIUM_HARDNESS, + entity_registry_enabled_default=False, # Superseded by number entity ), ScreenLogicPushSensorDescription( subscription_code=CODE.CHEMISTRY_CHANGED, data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION), key=VALUE.CYA, + entity_registry_enabled_default=False, # Superseded by number entity ), ScreenLogicPushSensorDescription( subscription_code=CODE.CHEMISTRY_CHANGED, @@ -156,11 +158,13 @@ SUPPORTED_INTELLICHEM_SENSORS = [ subscription_code=CODE.CHEMISTRY_CHANGED, data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION), key=VALUE.TOTAL_ALKALINITY, + entity_registry_enabled_default=False, # Superseded by number entity ), ScreenLogicPushSensorDescription( subscription_code=CODE.CHEMISTRY_CHANGED, data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION), key=VALUE.SALT_TDS_PPM, + entity_registry_enabled_default=False, # Superseded by number entity ), ScreenLogicPushSensorDescription( subscription_code=CODE.CHEMISTRY_CHANGED,