From 4b10826633e3b2615d9cbbc172a2b09957552df7 Mon Sep 17 00:00:00 2001 From: fustom Date: Sun, 27 Nov 2022 23:57:28 +0100 Subject: [PATCH] Support nuos split --- README.md | 1 + ariston/__init__.py | 8 ++ ariston/ariston_api.py | 244 ++++++++++++++++----------------- ariston/const.py | 69 +++++++++- ariston/device.py | 39 ++++-- ariston/evo_device.py | 139 ++++--------------- ariston/evo_lydos_device.py | 30 ++++ ariston/galevo_device.py | 19 +-- ariston/lydos_hybrid_device.py | 135 ++++-------------- ariston/nuos_split_device.py | 243 ++++++++++++++++++++++++++++++++ ariston/velis_device.py | 171 ++++++++++++++--------- pyproject.toml | 2 +- 12 files changed, 660 insertions(+), 440 deletions(-) create mode 100644 ariston/evo_lydos_device.py create mode 100644 ariston/nuos_split_device.py diff --git a/README.md b/README.md index 0b08c00..8a17066 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ The following devices are currently supported: - Ariston Velis Evo - Ariston Lydos Hybrid - Ariston Genus One +- Ariston Nuos Split ## Installation Use pip3 to install the latest version of this module. diff --git a/ariston/__init__.py b/ariston/__init__.py index 906a68a..a074fbd 100644 --- a/ariston/__init__.py +++ b/ariston/__init__.py @@ -17,6 +17,7 @@ MedDeviceSettings, VelisDeviceProperties, EvoDeviceProperties, + NuosSplitProperties, DeviceProperties, DeviceFeatures, ThermostatProperties, @@ -25,6 +26,8 @@ from .galevo_device import AristonGalevoDevice from .lydos_hybrid_device import AristonLydosHybridDevice from .velis_device import AristonVelisDevice +from .nuos_split_device import AristonNuosSplitDevice +from .evo_lydos_device import AristonEvoLydosDevice from .device import AristonDevice _LOGGER = logging.getLogger(__name__) @@ -103,6 +106,11 @@ def _get_device( api, device, ) + if whe_type == WheType.NuosSplit: + return AristonNuosSplitDevice( + api, + device, + ) _LOGGER.exception(f"Unsupported whe type {whe_type}") return None diff --git a/ariston/ariston_api.py b/ariston/ariston_api.py index df97979..8e7931c 100644 --- a/ariston/ariston_api.py +++ b/ariston/ariston_api.py @@ -18,12 +18,14 @@ ARISTON_REMOTE, ARISTON_REPORTS, ARISTON_SE_PLANT_DATA, + ARISTON_SLP_PLANT_DATA, ARISTON_TIME_PROGS, ARISTON_VELIS, DeviceFeatures, DeviceProperties, EvoPlantMode, LydosPlantMode, + NuosSplitOperativeMode, ThermostatProperties, ZoneAttribute, ) @@ -49,7 +51,7 @@ def connect(self) -> bool: """Login to ariston cloud and get token""" try: - response = self.post( + response = self._post( f"{ARISTON_API_URL}{ARISTON_LOGIN}", {"usr": self.__username, "pwd": self.__password}, ) @@ -66,21 +68,21 @@ def connect(self) -> bool: def get_detailed_devices(self) -> list[Any]: """Get detailed cloud devices""" - devices = self.get(f"{ARISTON_API_URL}{ARISTON_REMOTE}/{ARISTON_PLANTS}") + devices = self._get(f"{ARISTON_API_URL}{ARISTON_REMOTE}/{ARISTON_PLANTS}") if devices is not None: return list(devices) return list() def get_detailed_velis_devices(self) -> list[Any]: """Get detailed cloud devices""" - devices = self.get(f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_PLANTS}") + devices = self._get(f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_PLANTS}") if devices is not None: return list(devices) return list() def get_devices(self) -> list[Any]: """Get cloud devices""" - devices = self.get( + devices = self._get( f"{ARISTON_API_URL}{ARISTON_REMOTE}/{ARISTON_PLANTS}/{ARISTON_LITE}" ) if devices is not None: @@ -89,7 +91,7 @@ def get_devices(self) -> list[Any]: def get_features_for_device(self, gw_id: str) -> dict[str, Any]: """Get features for the device""" - features = self.get( + features = self._get( f"{ARISTON_API_URL}{ARISTON_REMOTE}/{ARISTON_PLANTS}/{gw_id}/features" ) if features is not None: @@ -98,7 +100,7 @@ def get_features_for_device(self, gw_id: str) -> dict[str, Any]: def get_energy_account(self, gw_id: str) -> dict[str, Any]: """Get energy account for the device""" - energy_account = self.get( + energy_account = self._get( f"{ARISTON_API_URL}{ARISTON_REMOTE}/{ARISTON_REPORTS}/{gw_id}/energyAccount" ) if energy_account is not None: @@ -107,7 +109,7 @@ def get_energy_account(self, gw_id: str) -> dict[str, Any]: def get_consumptions_sequences(self, gw_id: str, usages: str) -> list[Any]: """Get consumption sequences for the device""" - consumptions_sequences = self.get( + consumptions_sequences = self._get( f"{ARISTON_API_URL}{ARISTON_REMOTE}/{ARISTON_REPORTS}/{gw_id}/consSequencesApi8?usages={usages}" ) if consumptions_sequences is not None: @@ -116,7 +118,7 @@ def get_consumptions_sequences(self, gw_id: str, usages: str) -> list[Any]: def get_consumptions_settings(self, gw_id: str) -> dict[str, Any]: """Get consumption settings""" - consumptions_settings = self.post( + consumptions_settings = self._post( f"{ARISTON_API_URL}{ARISTON_REMOTE}/{ARISTON_PLANTS}/{gw_id}/getConsumptionsSettings", {}, ) @@ -130,7 +132,7 @@ def set_consumptions_settings( consumptions_settings: dict[str, Any], ) -> None: """Get consumption settings""" - self.post( + self._post( f"{ARISTON_API_URL}{ARISTON_REMOTE}/{ARISTON_PLANTS}/{gw_id}/consumptionsSettings", consumptions_settings, ) @@ -162,7 +164,7 @@ def get_properties( self, gw_id: str, features: dict[str, Any], culture: str, umsys: str ) -> dict[str, Any]: """Get device properties""" - properties = self.post( + properties = self._post( f"{ARISTON_API_URL}{ARISTON_REMOTE}/{ARISTON_DATA_ITEMS}/{gw_id}/get?umsys={umsys}", { "useCache": False, @@ -175,40 +177,20 @@ def get_properties( return properties return dict() - def get_med_plant_data(self, gw_id: str) -> dict[str, Any]: + def get_velis_plant_data(self, plant_data: str, gw_id: str) -> dict[str, Any]: """Get Velis properties""" - med_plant_data = self.get( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_MED_PLANT_DATA}/{gw_id}" - ) - if med_plant_data is not None: - return med_plant_data - return dict() - - def get_med_plant_settings(self, gw_id: str) -> dict[str, Any]: - """Get Velis settings""" - med_plant_settings = self.get( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_MED_PLANT_DATA}/{gw_id}/plantSettings" - ) - if med_plant_settings is not None: - return med_plant_settings - return dict() - - def get_se_plant_data(self, gw_id: str) -> dict[str, Any]: - """Get Velis properties""" - se_plant_data = self.get( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SE_PLANT_DATA}/{gw_id}" - ) - if se_plant_data is not None: - return se_plant_data + data = self._get(f"{ARISTON_API_URL}{ARISTON_VELIS}/{plant_data}/{gw_id}") + if data is not None: + return data return dict() - def get_se_plant_settings(self, gw_id: str) -> dict[str, Any]: + def get_velis_plant_settings(self, plant_data: str, gw_id: str) -> dict[str, Any]: """Get Velis settings""" - se_plant_settings = self.get( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SE_PLANT_DATA}/{gw_id}/plantSettings" + settings = self._get( + f"{ARISTON_API_URL}{ARISTON_VELIS}/{plant_data}/{gw_id}/plantSettings" ) - if se_plant_settings is not None: - return se_plant_settings + if settings is not None: + return settings return dict() def set_property( @@ -222,7 +204,7 @@ def set_property( umsys: str, ) -> None: """Set device properties""" - self.post( + self._post( f"{ARISTON_API_URL}{ARISTON_REMOTE}/{ARISTON_DATA_ITEMS}/{gw_id}/set?umsys={umsys}", { "items": [ @@ -239,7 +221,7 @@ def set_property( def set_evo_mode(self, gw_id: str, value: EvoPlantMode) -> None: """Set Velis Evo mode""" - self.post( + self._post( f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_MED_PLANT_DATA}/{gw_id}/mode", { "new": value.value, @@ -248,16 +230,25 @@ def set_evo_mode(self, gw_id: str, value: EvoPlantMode) -> None: def set_lydos_mode(self, gw_id: str, value: LydosPlantMode) -> None: """Set Velis Lydos mode""" - self.post( + self._post( f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SE_PLANT_DATA}/{gw_id}/mode", { "new": value.value, }, ) + def set_nuos_mode(self, gw_id: str, value: NuosSplitOperativeMode) -> None: + """Set Velis Nuos mode""" + self._post( + f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SLP_PLANT_DATA}/{gw_id}/operativeMode", + { + "new": value.value, + }, + ) + def set_evo_temperature(self, gw_id: str, value: float) -> None: """Set Velis Evo temperature""" - self.post( + self._post( f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_MED_PLANT_DATA}/{gw_id}/temperature", { "new": value, @@ -266,57 +257,57 @@ def set_evo_temperature(self, gw_id: str, value: float) -> None: def set_lydos_temperature(self, gw_id: str, value: float) -> None: """Set Velis Lydos temperature""" - self.post( + self._post( f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SE_PLANT_DATA}/{gw_id}/temperature", { "new": value, }, ) - def set_evo_eco_mode(self, gw_id: str, eco_mode: bool) -> None: - """Set Velis Evo power""" - self.post( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_MED_PLANT_DATA}/{gw_id}/switchEco", - eco_mode, + def set_nuos_temperature(self, gw_id: str, comfort: float, reduced: float) -> None: + """Set Nuos temperature""" + self._post( + f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SLP_PLANT_DATA}/{gw_id}/temperatures", + { + "new": { + "comfort": comfort, + "reduced": reduced, + } + }, ) - def set_evo_power(self, gw_id: str, power: bool) -> None: - """Set Velis Evo power""" - self.post( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_MED_PLANT_DATA}/{gw_id}/switch", - power, + def set_nous_boost(self, gw_id: str, boost: bool) -> None: + """ "Set Nous boost""" + self._post( + f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SLP_PLANT_DATA}/{gw_id}/boost", + boost, ) - def set_lydos_power(self, gw_id: str, power: bool) -> None: - """Set Velis Lydos power""" - self.post( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SE_PLANT_DATA}/{gw_id}/switch", - power, + def set_evo_eco_mode(self, gw_id: str, eco_mode: bool) -> None: + """Set Velis Evo eco mode""" + self._post( + f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_MED_PLANT_DATA}/{gw_id}/switchEco", + eco_mode, ) - def set_evo_plant_setting( - self, - gw_id: str, - setting: str, - value: float, - old_value: float, - ) -> None: - """Set Velis Evo plant setting""" - self.post( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_MED_PLANT_DATA}/{gw_id}/plantSettings", - {setting: {"new": value, "old": old_value}}, + def set_velis_power(self, plant_data: str, gw_id: str, power: bool) -> None: + """Set Velis power""" + self._post( + f"{ARISTON_API_URL}{ARISTON_VELIS}/{plant_data}/{gw_id}/switch", + power, ) - def set_lydos_plant_setting( + def set_velis_plant_setting( self, + plant_data: str, gw_id: str, setting: str, value: float, old_value: float, ) -> None: - """Set Velis Lydos plant setting""" - self.post( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SE_PLANT_DATA}/{gw_id}/plantSettings", + """Set Velis plant setting""" + self._post( + f"{ARISTON_API_URL}{ARISTON_VELIS}/{plant_data}/{gw_id}/plantSettings", {setting: {"new": value, "old": old_value}}, ) @@ -324,7 +315,7 @@ def get_thermostat_time_progs( self, gw_id: str, zone: int, umsys: str ) -> dict[str, Any]: """Get thermostat time programs""" - thermostat_time_progs = self.get( + thermostat_time_progs = self._get( f"{ARISTON_API_URL}{ARISTON_REMOTE}/{ARISTON_TIME_PROGS}/{gw_id}/ChZn{zone}?umsys={umsys}", ) if thermostat_time_progs is not None: @@ -337,7 +328,7 @@ def set_holiday( holiday_end_date: Optional[str], ) -> None: """Set holidays""" - self.post( + self._post( f"{ARISTON_API_URL}{ARISTON_REMOTE}/{ARISTON_PLANT_DATA}/{gw_id}/holiday", { "new": holiday_end_date, @@ -383,11 +374,11 @@ def __request( return None - def post(self, path: str, body: Any) -> Optional[dict[str, Any]]: + def _post(self, path: str, body: Any) -> Optional[dict[str, Any]]: """POST request""" return self.__request("POST", path, None, body) - def get( + def _get( self, path: str, params: Optional[dict[str, Any]] = None ) -> Optional[dict[str, Any]]: """GET request""" @@ -505,42 +496,28 @@ async def async_get_properties( return properties return dict() - async def async_get_med_plant_data(self, gw_id: str) -> dict[str, Any]: + async def async_get_velis_plant_data( + self, plant_data: str, gw_id: str + ) -> dict[str, Any]: """Async get Velis properties""" med_plant_data = await self._async_get( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_MED_PLANT_DATA}/{gw_id}" + f"{ARISTON_API_URL}{ARISTON_VELIS}/{plant_data}/{gw_id}" ) if med_plant_data is not None: return med_plant_data return dict() - async def async_get_med_plant_settings(self, gw_id: str) -> dict[str, Any]: + async def async_get_velis_plant_settings( + self, plant_data: str, gw_id: str + ) -> dict[str, Any]: """Async get Velis settings""" med_plant_settings = await self._async_get( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_MED_PLANT_DATA}/{gw_id}/plantSettings" + f"{ARISTON_API_URL}{ARISTON_VELIS}/{plant_data}/{gw_id}/plantSettings" ) if med_plant_settings is not None: return med_plant_settings return dict() - async def async_get_se_plant_data(self, gw_id: str) -> dict[str, Any]: - """Async get Velis properties""" - se_plant_data = await self._async_get( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SE_PLANT_DATA}/{gw_id}" - ) - if se_plant_data is not None: - return se_plant_data - return dict() - - async def async_get_se_plant_settings(self, gw_id: str) -> dict[str, Any]: - """Async get Velis settings""" - se_plant_settings = await self._async_get( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SE_PLANT_DATA}/{gw_id}/plantSettings" - ) - if se_plant_settings is not None: - return se_plant_settings - return dict() - async def async_set_property( self, gw_id: str, @@ -585,6 +562,17 @@ async def async_set_lydos_mode(self, gw_id: str, value: LydosPlantMode) -> None: }, ) + async def async_set_nuos_mode( + self, gw_id: str, value: NuosSplitOperativeMode + ) -> None: + """Async set Velis Nuos mode""" + await self._async_post( + f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SLP_PLANT_DATA}/{gw_id}/operativeMode", + { + "new": value.value, + }, + ) + async def async_set_evo_temperature(self, gw_id: str, value: float) -> None: """Async set Velis Evo temperature""" await self._async_post( @@ -603,50 +591,54 @@ async def async_set_lydos_temperature(self, gw_id: str, value: float) -> None: }, ) - async def async_set_evo_eco_mode(self, gw_id: str, eco_mode: bool) -> None: - """Async set Velis Evo power""" + async def async_set_nuos_temperature( + self, gw_id: str, comfort: float, reduced: float + ) -> None: + """Async set Velis Lydos temperature""" await self._async_post( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_MED_PLANT_DATA}/{gw_id}/switchEco", - eco_mode, + f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SLP_PLANT_DATA}/{gw_id}/temperatures", + { + "new": { + "comfort": comfort, + "reduced": reduced, + } + }, ) - async def async_set_evo_power(self, gw_id: str, power: bool) -> None: - """Async set Velis Evo power""" + async def async_set_nous_boost(self, gw_id: str, boost: bool) -> None: + """ "Set Nous boost""" await self._async_post( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_MED_PLANT_DATA}/{gw_id}/switch", - power, + f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SLP_PLANT_DATA}/{gw_id}/boost", + boost, ) - async def async_set_lydos_power(self, gw_id: str, power: bool) -> None: - """Async set Velis Lydos power""" + async def async_set_evo_eco_mode(self, gw_id: str, eco_mode: bool) -> None: + """Async set Velis Evo eco mode""" await self._async_post( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SE_PLANT_DATA}/{gw_id}/switch", - power, + f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_MED_PLANT_DATA}/{gw_id}/switchEco", + eco_mode, ) - async def async_set_evo_plant_setting( - self, - gw_id: str, - setting: str, - value: float, - old_value: float, + async def async_set_velis_power( + self, plant_data: str, gw_id: str, power: bool ) -> None: - """Async set Velis Evo plant setting""" + """Async set Velis power""" await self._async_post( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_MED_PLANT_DATA}/{gw_id}/plantSettings", - {setting: {"new": value, "old": old_value}}, + f"{ARISTON_API_URL}{ARISTON_VELIS}/{plant_data}/{gw_id}/switch", + power, ) - async def async_set_lydos_plant_setting( + async def async_set_velis_plant_setting( self, + plant_data: str, gw_id: str, setting: str, value: float, old_value: float, - ) -> Optional[dict[str, Any]]: - """Async set Velis Lydos plant setting""" - return await self._async_post( - f"{ARISTON_API_URL}{ARISTON_VELIS}/{ARISTON_SE_PLANT_DATA}/{gw_id}/plantSettings", + ) -> None: + """Async set Velis Evo plant setting""" + await self._async_post( + f"{ARISTON_API_URL}{ARISTON_VELIS}/{plant_data}/{gw_id}/plantSettings", {setting: {"new": value, "old": old_value}}, ) diff --git a/ariston/const.py b/ariston/const.py index 6328b55..7217837 100644 --- a/ariston/const.py +++ b/ariston/const.py @@ -12,6 +12,7 @@ ARISTON_PLANT_DATA: Final[str] = "plantData" ARISTON_MED_PLANT_DATA: Final[str] = "medPlantData" ARISTON_SE_PLANT_DATA: Final[str] = "sePlantData" +ARISTON_SLP_PLANT_DATA: Final[str] = "slpPlantData" ARISTON_REPORTS: Final[str] = "reports" ARISTON_TIME_PROGS: Final[str] = "timeProgs" @@ -144,8 +145,12 @@ class Brands(IntFlag): Racold = 7 +class WaterHeaterMode(Enum): + """Base class for plant modes""" + + @unique -class EvoPlantMode(Enum): +class EvoPlantMode(WaterHeaterMode): """Evo plant mode enum""" MANUAL = 1 @@ -162,7 +167,25 @@ class VelisPlantMode(Enum): @unique -class LydosPlantMode(Enum): +class NuosSplitPlantMode(Enum): + """NuosSplit plant mode enum""" + + MANUAL = 1 + PROGRAM = 2 + + +@unique +class NuosSplitOperativeMode(WaterHeaterMode): + """NuosSplit operative mode enum""" + + GREEN = 0 + COMFORT = 1 + FAST = 2 + IMEMORY = 3 + + +@unique +class LydosPlantMode(WaterHeaterMode): """Lydos hybrid plant mode enum""" IMEMORY = 1 @@ -311,18 +334,34 @@ class DeviceFeatures: class VelisDeviceProperties: """Contants for Velis device properties""" - ANTI_LEG: Final[str] = "antiLeg" - AV_SHW: Final[str] = "avShw" GW: Final[str] = "gw" - HEAT_REQ: Final[str] = "heatReq" MODE: Final[str] = "mode" ON: Final[str] = "on" PROC_REQ_TEMP: Final[str] = "procReqTemp" + + +class NuosSplitProperties(VelisDeviceProperties): + """Constants for NuosSplit device properties""" + + WATER_TEMP: Final[str] = "waterTemp" + COMFORT_TEMP: Final[str] = "comfortTemp" + REDUCED_TEMP: Final[str] = "reducedTemp" + OP_MODE: Final[str] = "opMode" + BOOST_ON: Final[str] = "boostOn" + HP_STATE: Final[str] = "hpState" + + +class EvoLydosDeviceProperties(VelisDeviceProperties): + """Constants for evo and lydos device properties""" + + ANTI_LEG: Final[str] = "antiLeg" + AV_SHW: Final[str] = "avShw" + HEAT_REQ: Final[str] = "heatReq" REQ_TEMP: Final[str] = "reqTemp" TEMP: Final[str] = "temp" -class EvoDeviceProperties(VelisDeviceProperties): +class EvoDeviceProperties(EvoLydosDeviceProperties): """Contants for Velis Evo device properties""" ECO: Final[str] = "eco" @@ -330,7 +369,7 @@ class EvoDeviceProperties(VelisDeviceProperties): RM_TM: Final[str] = "rmTm" -class LydosDeviceProperties(VelisDeviceProperties): +class LydosDeviceProperties(EvoLydosDeviceProperties): """Contants for Velis Lydos device properties""" BOOST_REQ_TEMP: Final[str] = "boostReqTemp" @@ -369,6 +408,22 @@ class SeDeviceSettings: SE_NIGHT_END_MAX_AS_MINUTES: Final[str] = "SeNightEndMaxAsMinutes" +class SlpDeviceSettings: + """Constatns for Slp device settings""" + + SLP_MAX_GREEN_TEMPERATURE: Final[str] = "SlpMaxGreenTemperature" + SLP_MAX_SETPOINT_TEMPERATURE: Final[str] = "SlpMaxSetpointTemperature" + SLP_MAX_SETPOINT_TEMPERATURE_MIN: Final[str] = "SlpMaxSetpointTemperatureMin" + SLP_MAX_SETPOINT_TEMPERATURE_MAX: Final[str] = "SlpMaxSetpointTemperatureMax" + SLP_MIN_SETPOINT_TEMPERATURE: Final[str] = "SlpMinSetpointTemperature" + SLP_MIN_SETPOINT_TEMPERATURE_MIN: Final[str] = "SlpMinSetpointTemperatureMin" + SLP_MIN_SETPOINT_TEMPERATURE_MAX: Final[str] = "SlpMinSetpointTemperatureMax" + SLP_ANTILEGIONELLA_ON_OFF: Final[str] = "SlpAntilegionellaOnOff" + SLP_PRE_HEATING_ON_OFF: Final[str] = "SlpPreHeatingOnOff" + SLP_HEATING_RATE: Final[str] = "SlpHeatingRate" + SLP_HC_HP_MODE: Final[str] = "SlpHcHpMode" + + class DeviceProperties: """Constants for device properties""" diff --git a/ariston/device.py b/ariston/device.py index 4af8405..c67175e 100644 --- a/ariston/device.py +++ b/ariston/device.py @@ -41,6 +41,25 @@ def __init__( ) self.gw: str = self.attributes.get(DeviceAttribute.GW, "") + @property + @abstractmethod + def consumption_type(self) -> str: + """String to get consumption type""" + + def _get_consumptions_sequences(self) -> None: + """Get consumption sequence""" + self.consumptions_sequences = self.api.get_consumptions_sequences( + self.gw, + self.consumption_type, + ) + + async def _async_get_consumptions_sequences(self) -> None: + """Async get consumption sequence""" + self.consumptions_sequences = await self.api.async_get_consumptions_sequences( + self.gw, + self.consumption_type, + ) + def get_system_type(self) -> SystemType: """Get device system type wrapper""" return SystemType(self.attributes.get(DeviceAttribute.SYS, SystemType.UNKNOWN)) @@ -157,6 +176,16 @@ def get_water_heater_temperature_step(self) -> int: """Abstract method for get water heater temperature step""" raise NotImplementedError + @abstractmethod + def set_water_heater_operation_mode(self, operation_mode: str) -> None: + """Abstract method for set water heater operation mode""" + raise NotImplementedError + + @abstractmethod + async def async_set_water_heater_operation_mode(self, operation_mode: str) -> None: + """Abstract method for async set water heater operation mode""" + raise NotImplementedError + def get_consumption_sequence_last_changed_utc(self) -> dt.datetime: """Get consumption sequence last changed in utc""" return self.consumption_sequence_last_changed_utc @@ -229,16 +258,6 @@ def _get_consumption_sequence_last_value( return None - @abstractmethod - def _get_consumptions_sequences(self) -> None: - """Get consumption sequence""" - raise NotImplementedError - - @abstractmethod - async def _async_get_consumptions_sequences(self) -> None: - """Async get consumption sequence""" - raise NotImplementedError - def _update_energy(self, old_consumptions_sequences: list[dict[str, Any]]) -> None: """Update the device energy settings""" if ( diff --git a/ariston/evo_device.py b/ariston/evo_device.py index f773436..dd801ce 100644 --- a/ariston/evo_device.py +++ b/ariston/evo_device.py @@ -3,50 +3,45 @@ import logging from typing import Optional +from datetime import datetime from .const import ( + ARISTON_MED_PLANT_DATA, EvoPlantMode, EvoDeviceProperties, MedDeviceSettings, - VelisDeviceProperties, ) -from .velis_device import AristonVelisDevice +from .evo_lydos_device import AristonEvoLydosDevice _LOGGER = logging.getLogger(__name__) -class AristonEvoDevice(AristonVelisDevice): +class AristonEvoDevice(AristonEvoLydosDevice): """Class representing a physical device, it's state and properties.""" - def update_state(self) -> None: - """Update the device states from the cloud""" - self.data = self.api.get_med_plant_data(self.gw) + @property + def plant_data(self) -> str: + """Final string to get plant data""" + return ARISTON_MED_PLANT_DATA - async def async_update_state(self) -> None: - """Async update the device states from the cloud""" - self.data = await self.api.async_get_med_plant_data(self.gw) + @property + def anti_legionella_on_off(self) -> str: + """Final string to get anti-legionella-on-off""" + return MedDeviceSettings.MED_ANTILEGIONELLA_ON_OFF - def update_settings(self) -> None: - """Get device settings wrapper""" - self.plant_settings = self.api.get_med_plant_settings(self.gw) + @property + def consumption_type(self) -> str: + """String to get consumption type""" + return "Dhw" - async def async_update_settings(self) -> None: - """Async get device settings wrapper""" - self.plant_settings = await self.api.async_get_med_plant_settings(self.gw) + @property + def water_heater_mode(self) -> type[EvoPlantMode]: + """Return the water heater mode class""" + return EvoPlantMode - def get_water_heater_mode_operation_texts(self) -> list[str]: - """Get water heater operation mode texts""" - return [flag.name for flag in EvoPlantMode] - - def get_water_heater_mode_options(self) -> list[int]: - """Get water heater operation options""" - return [flag.value for flag in EvoPlantMode] - - def get_water_anti_leg_value(self) -> Optional[bool]: - """Get water heater anti-legionella value""" - return self.plant_settings.get( - MedDeviceSettings.MED_ANTILEGIONELLA_ON_OFF, None - ) + @property + def max_setpoint_temp(self) -> str: + return MedDeviceSettings.MED_MAX_SETPOINT_TEMPERATURE def get_water_heater_eco_value(self) -> Optional[int]: """Get water heater eco value""" @@ -68,110 +63,32 @@ def get_water_heater_maximum_setpoint_temperature_maximum(self) -> Optional[floa MedDeviceSettings.MED_MAX_SETPOINT_TEMPERATURE_MAX, None ) - def get_water_heater_maximum_setpoint_temperature(self) -> Optional[float]: - """Get water heater maximum setpoint temperature value""" - return self.plant_settings.get( - MedDeviceSettings.MED_MAX_SETPOINT_TEMPERATURE, None - ) - - def _get_consumptions_sequences(self) -> None: - """Get consumption sequence""" - self.consumptions_sequences = self.api.get_consumptions_sequences( - self.gw, - "Dhw", - ) - - async def _async_get_consumptions_sequences(self) -> None: - """Async get consumption sequence""" - self.consumptions_sequences = await self.api.async_get_consumptions_sequences( - self.gw, - "Dhw", - ) - def set_eco_mode(self, eco_mode: bool): """Set water heater eco_mode""" self.api.set_evo_eco_mode(self.gw, eco_mode) self.data[EvoDeviceProperties.ECO] = eco_mode - async def async_set_eco_mode(self, eco_mode: bool) -> None: + async def async_set_eco_mode(self, eco_mode: bool): """Async set water heater eco_mode""" await self.api.async_set_evo_eco_mode(self.gw, eco_mode) self.data[EvoDeviceProperties.ECO] = eco_mode - def set_antilegionella(self, anti_leg: bool): - """Set water heater anti-legionella""" - self.api.set_evo_plant_setting( - self.gw, - MedDeviceSettings.MED_ANTILEGIONELLA_ON_OFF, - 1.0 if anti_leg else 0.0, - 1.0 - if self.plant_settings[MedDeviceSettings.MED_ANTILEGIONELLA_ON_OFF] - else 0.0, - ) - self.plant_settings[MedDeviceSettings.MED_ANTILEGIONELLA_ON_OFF] = anti_leg - - async def async_set_antilegionella(self, anti_leg: bool): - """Async set water heater anti-legionella""" - await self.api.async_set_evo_plant_setting( - self.gw, - MedDeviceSettings.MED_ANTILEGIONELLA_ON_OFF, - 1.0 if anti_leg else 0.0, - 1.0 - if self.plant_settings[MedDeviceSettings.MED_ANTILEGIONELLA_ON_OFF] - else 0.0, - ) - self.plant_settings[MedDeviceSettings.MED_ANTILEGIONELLA_ON_OFF] = anti_leg - def set_water_heater_operation_mode(self, operation_mode: str): """Set water heater operation mode""" self.api.set_evo_mode(self.gw, EvoPlantMode[operation_mode]) - self.data[VelisDeviceProperties.MODE] = EvoPlantMode[operation_mode].value + self.data[EvoDeviceProperties.MODE] = EvoPlantMode[operation_mode].value async def async_set_water_heater_operation_mode(self, operation_mode: str): """Async set water heater operation mode""" await self.api.async_set_evo_mode(self.gw, EvoPlantMode[operation_mode]) - self.data[VelisDeviceProperties.MODE] = EvoPlantMode[operation_mode].value + self.data[EvoDeviceProperties.MODE] = EvoPlantMode[operation_mode].value def set_water_heater_temperature(self, temperature: float): """Set water heater temperature""" self.api.set_evo_temperature(self.gw, temperature) - self.data[VelisDeviceProperties.REQ_TEMP] = temperature + self.data[EvoDeviceProperties.REQ_TEMP] = temperature async def async_set_water_heater_temperature(self, temperature: float): """Async set water heater temperature""" await self.api.async_set_evo_temperature(self.gw, temperature) - self.data[VelisDeviceProperties.REQ_TEMP] = temperature - - def set_power(self, power: bool): - """Set water heater power""" - self.api.set_evo_power(self.gw, power) - self.data[VelisDeviceProperties.ON] = power - - async def async_set_power(self, power: bool) -> None: - """Async set water heater power""" - await self.api.async_set_evo_power(self.gw, power) - self.data[VelisDeviceProperties.ON] = power - - def set_max_setpoint_temp(self, max_setpoint_temp: float): - """Set water heater maximum setpoint temperature""" - self.api.set_evo_plant_setting( - self.gw, - MedDeviceSettings.MED_MAX_SETPOINT_TEMPERATURE, - max_setpoint_temp, - self.plant_settings[MedDeviceSettings.MED_MAX_SETPOINT_TEMPERATURE], - ) - self.plant_settings[ - MedDeviceSettings.MED_MAX_SETPOINT_TEMPERATURE - ] = max_setpoint_temp - - async def async_set_max_setpoint_temp(self, max_setpoint_temp: float): - """Async set water heater maximum setpoint temperature""" - await self.api.async_set_evo_plant_setting( - self.gw, - MedDeviceSettings.MED_MAX_SETPOINT_TEMPERATURE, - max_setpoint_temp, - self.plant_settings[MedDeviceSettings.MED_MAX_SETPOINT_TEMPERATURE], - ) - self.plant_settings[ - MedDeviceSettings.MED_MAX_SETPOINT_TEMPERATURE - ] = max_setpoint_temp + self.data[EvoDeviceProperties.REQ_TEMP] = temperature diff --git a/ariston/evo_lydos_device.py b/ariston/evo_lydos_device.py new file mode 100644 index 0000000..e4b47c3 --- /dev/null +++ b/ariston/evo_lydos_device.py @@ -0,0 +1,30 @@ +"""Evo and lydos device class for Ariston module.""" +from __future__ import annotations + +import logging +from typing import Optional + +from .velis_device import AristonVelisDevice +from .const import EvoLydosDeviceProperties + +_LOGGER = logging.getLogger(__name__) + + +class AristonEvoLydosDevice(AristonVelisDevice): + """Class representing a physical device, it's state and properties.""" + + def get_water_heater_current_temperature(self) -> Optional[float]: + """Get water heater current temperature""" + return self.data.get(EvoLydosDeviceProperties.TEMP, None) + + def get_water_heater_target_temperature(self) -> Optional[float]: + """Get water heater target temperature""" + return self.data.get(EvoLydosDeviceProperties.REQ_TEMP, None) + + def get_av_shw_value(self) -> Optional[int]: + """Get average showers value""" + return self.data.get(EvoLydosDeviceProperties.AV_SHW, None) + + def get_is_heating(self) -> Optional[bool]: + """Get is the water heater heating""" + return self.data.get(EvoLydosDeviceProperties.HEAT_REQ, None) diff --git a/ariston/galevo_device.py b/ariston/galevo_device.py index 7756511..10c2bc9 100644 --- a/ariston/galevo_device.py +++ b/ariston/galevo_device.py @@ -42,6 +42,11 @@ def __init__( self.consumptions_settings: dict[str, Any] = dict() self.energy_account: dict[str, Any] = dict() + @property + def consumption_type(self) -> str: + """String to get consumption type""" + return f"Ch{'%2CDhw' if self.custom_features.get(CustomDeviceFeatures.HAS_DHW) else ''}" + def _update_state(self) -> None: """Set custom features""" if self.custom_features.get(CustomDeviceFeatures.HAS_OUTSIDE_TEMP) is None: @@ -458,20 +463,6 @@ def _get_item_by_id( None, ) - def _get_consumptions_sequences(self) -> None: - """Get consumption sequence""" - self.consumptions_sequences = self.api.get_consumptions_sequences( - self.gw, - f"Ch{'%2CDhw' if self.custom_features.get(CustomDeviceFeatures.HAS_DHW) else ''}", - ) - - async def _async_get_consumptions_sequences(self) -> None: - """Async get consumption sequence""" - self.consumptions_sequences = await self.api.async_get_consumptions_sequences( - self.gw, - f"Ch{'%2CDhw' if self.custom_features.get(CustomDeviceFeatures.HAS_DHW) else ''}", - ) - def get_elect_cost(self) -> Optional[float]: """Get electric consumption cost""" return self.consumptions_settings.get(ConsumptionProperties.ELEC_COST) diff --git a/ariston/lydos_hybrid_device.py b/ariston/lydos_hybrid_device.py index 61b71ac..bf2adf4 100644 --- a/ariston/lydos_hybrid_device.py +++ b/ariston/lydos_hybrid_device.py @@ -5,47 +5,44 @@ from typing import Optional from .const import ( + ARISTON_SE_PLANT_DATA, ConsumptionTimeInterval, ConsumptionType, LydosPlantMode, SeDeviceSettings, - VelisDeviceProperties, + LydosDeviceProperties, ) -from .velis_device import AristonVelisDevice +from .evo_lydos_device import AristonEvoLydosDevice _LOGGER = logging.getLogger(__name__) -class AristonLydosHybridDevice(AristonVelisDevice): +class AristonLydosHybridDevice(AristonEvoLydosDevice): """Class representing a physical device, it's state and properties.""" - def update_state(self) -> None: - """Update the device states from the cloud""" - self.data = self.api.get_se_plant_data(self.gw) + @property + def plant_data(self) -> str: + """Final string to get plant data""" + return ARISTON_SE_PLANT_DATA - async def async_update_state(self) -> None: - """Async update the device states from the cloud""" - self.data = await self.api.async_get_se_plant_data(self.gw) + @property + def anti_legionella_on_off(self) -> str: + """Final string to get anti-legionella-on-off""" + return SeDeviceSettings.SE_ANTILEGIONELLA_ON_OFF - def update_settings(self) -> None: - """Get device settings wrapper""" - self.plant_settings = self.api.get_se_plant_settings(self.gw) + @property + def consumption_type(self) -> str: + """String to get consumption type""" + return "DhwHeatingPumpElec%2CDhwResistorElec" - async def async_update_settings(self) -> None: - """Async get device settings wrapper""" - self.plant_settings = await self.api.async_get_se_plant_settings(self.gw) + @property + def water_heater_mode(self) -> type[LydosPlantMode]: + """Return the water heater mode class""" + return LydosPlantMode - def get_water_heater_mode_operation_texts(self) -> list[str]: - """Get water heater operation mode texts""" - return [flag.name for flag in LydosPlantMode] - - def get_water_heater_mode_options(self) -> list[int]: - """Get water heater operation options""" - return [flag.value for flag in LydosPlantMode] - - def get_water_anti_leg_value(self) -> Optional[bool]: - """Get water heater anti-legionella value""" - return self.plant_settings.get(SeDeviceSettings.SE_ANTILEGIONELLA_ON_OFF, None) + @property + def max_setpoint_temp(self) -> str: + return SeDeviceSettings.SE_MAX_SETPOINT_TEMPERATURE def get_water_heater_maximum_setpoint_temperature_minimum(self) -> Optional[float]: """Get water heater maximum setpoint temperature minimum""" @@ -59,12 +56,6 @@ def get_water_heater_maximum_setpoint_temperature_maximum(self) -> Optional[floa SeDeviceSettings.SE_MAX_SETPOINT_TEMPERATURE_MAX, None ) - def get_water_heater_maximum_setpoint_temperature(self) -> Optional[float]: - """Get water heater maximum setpoint temperature value""" - return self.plant_settings.get( - SeDeviceSettings.SE_MAX_SETPOINT_TEMPERATURE, None - ) - def get_electric_consumption_for_water_last_two_hours(self) -> int: """Get electric consumption for water last value""" return self._get_consumption_sequence_last_value( @@ -72,94 +63,22 @@ def get_electric_consumption_for_water_last_two_hours(self) -> int: ConsumptionTimeInterval.LAST_DAY, ) - def _get_consumptions_sequences(self) -> None: - """Get consumption sequence""" - self.consumptions_sequences = self.api.get_consumptions_sequences( - self.gw, - "DhwHeatingPumpElec%2CDhwResistorElec", - ) - - async def _async_get_consumptions_sequences(self) -> None: - """Async get consumption sequence""" - self.consumptions_sequences = await self.api.async_get_consumptions_sequences( - self.gw, - "DhwHeatingPumpElec%2CDhwResistorElec", - ) - - def set_antilegionella(self, anti_leg: bool): - """Set water heater anti-legionella""" - self.api.set_lydos_plant_setting( - self.gw, - SeDeviceSettings.SE_ANTILEGIONELLA_ON_OFF, - 1.0 if anti_leg else 0.0, - 1.0 - if self.plant_settings[SeDeviceSettings.SE_ANTILEGIONELLA_ON_OFF] - else 0.0, - ) - self.plant_settings[SeDeviceSettings.SE_ANTILEGIONELLA_ON_OFF] = anti_leg - - async def async_set_antilegionella(self, anti_leg: bool): - """Async set water heater anti-legionella""" - await self.api.async_set_lydos_plant_setting( - self.gw, - SeDeviceSettings.SE_ANTILEGIONELLA_ON_OFF, - 1.0 if anti_leg else 0.0, - 1.0 - if self.plant_settings[SeDeviceSettings.SE_ANTILEGIONELLA_ON_OFF] - else 0.0, - ) - self.plant_settings[SeDeviceSettings.SE_ANTILEGIONELLA_ON_OFF] = anti_leg - def set_water_heater_operation_mode(self, operation_mode: str): """Set water heater operation mode""" self.api.set_lydos_mode(self.gw, LydosPlantMode[operation_mode]) - self.data[VelisDeviceProperties.MODE] = LydosPlantMode[operation_mode].value + self.data[LydosDeviceProperties.MODE] = LydosPlantMode[operation_mode].value async def async_set_water_heater_operation_mode(self, operation_mode: str): """Async set water heater operation mode""" await self.api.async_set_lydos_mode(self.gw, LydosPlantMode[operation_mode]) - self.data[VelisDeviceProperties.MODE] = LydosPlantMode[operation_mode].value + self.data[LydosDeviceProperties.MODE] = LydosPlantMode[operation_mode].value def set_water_heater_temperature(self, temperature: float): """Set water heater temperature""" self.api.set_lydos_temperature(self.gw, temperature) - self.data[VelisDeviceProperties.REQ_TEMP] = temperature + self.data[LydosDeviceProperties.REQ_TEMP] = temperature async def async_set_water_heater_temperature(self, temperature: float): """Async set water heater temperature""" await self.api.async_set_lydos_temperature(self.gw, temperature) - self.data[VelisDeviceProperties.REQ_TEMP] = temperature - - def set_power(self, power: bool): - """Set water heater power""" - self.api.set_lydos_power(self.gw, power) - self.data[VelisDeviceProperties.ON] = power - - async def async_set_power(self, power: bool) -> None: - """Async set water heater power""" - await self.api.async_set_lydos_power(self.gw, power) - self.data[VelisDeviceProperties.ON] = power - - def set_max_setpoint_temp(self, max_setpoint_temp: float): - """Set water heater anti-legionella""" - self.api.set_lydos_plant_setting( - self.gw, - SeDeviceSettings.SE_MAX_SETPOINT_TEMPERATURE, - max_setpoint_temp, - self.plant_settings[SeDeviceSettings.SE_MAX_SETPOINT_TEMPERATURE], - ) - self.plant_settings[ - SeDeviceSettings.SE_MAX_SETPOINT_TEMPERATURE - ] = max_setpoint_temp - - async def async_set_max_setpoint_temp(self, max_setpoint_temp: float): - """Async set water heater anti-legionella""" - await self.api.async_set_lydos_plant_setting( - self.gw, - SeDeviceSettings.SE_MAX_SETPOINT_TEMPERATURE, - max_setpoint_temp, - self.plant_settings[SeDeviceSettings.SE_MAX_SETPOINT_TEMPERATURE], - ) - self.plant_settings[ - SeDeviceSettings.SE_MAX_SETPOINT_TEMPERATURE - ] = max_setpoint_temp + self.data[LydosDeviceProperties.REQ_TEMP] = temperature diff --git a/ariston/nuos_split_device.py b/ariston/nuos_split_device.py new file mode 100644 index 0000000..fa0c88e --- /dev/null +++ b/ariston/nuos_split_device.py @@ -0,0 +1,243 @@ +"""Nuos split device class for Ariston module.""" +from __future__ import annotations + +import logging +from typing import Optional + +from .velis_device import AristonVelisDevice +from .const import ( + ARISTON_SLP_PLANT_DATA, + NuosSplitOperativeMode, + NuosSplitProperties, + SlpDeviceSettings, +) + +_LOGGER = logging.getLogger(__name__) + + +class AristonNuosSplitDevice(AristonVelisDevice): + """Class representing a physical device, it's state and properties.""" + + @property + def plant_data(self) -> str: + """Final string to get plant data""" + return ARISTON_SLP_PLANT_DATA + + @property + def anti_legionella_on_off(self) -> str: + """Final string to get anti-legionella-on-off""" + return SlpDeviceSettings.SLP_ANTILEGIONELLA_ON_OFF + + @property + def consumption_type(self) -> str: + """String to get consumption type""" + return "DhwHeatingPumpElec%2CDhwResistorElec" + + @property + def water_heater_mode(self) -> type[NuosSplitOperativeMode]: + """Return the water heater mode class""" + return NuosSplitOperativeMode + + @property + def max_setpoint_temp(self) -> str: + return SlpDeviceSettings.SLP_MAX_SETPOINT_TEMPERATURE + + def get_water_heater_current_temperature(self) -> Optional[float]: + """Get water heater current temperature""" + return self.data.get(NuosSplitProperties.WATER_TEMP, None) + + def get_water_heater_target_temperature(self) -> Optional[float]: + """Get water heater target temperature""" + return self.data.get(NuosSplitProperties.PROC_REQ_TEMP, None) + + def get_water_heater_reduced_temperature(self) -> Optional[float]: + """Get water heater reduced temperature""" + return self.data.get(NuosSplitProperties.REDUCED_TEMP, None) + + def get_water_heater_maximum_setpoint_temperature_minimum(self) -> Optional[float]: + """Get water heater maximum setpoint temperature minimum""" + return self.plant_settings.get( + SlpDeviceSettings.SLP_MAX_SETPOINT_TEMPERATURE_MIN, None + ) + + def get_water_heater_maximum_setpoint_temperature_maximum(self) -> Optional[float]: + """Get water heater maximum setpoint maximum temperature""" + return self.plant_settings.get( + SlpDeviceSettings.SLP_MAX_SETPOINT_TEMPERATURE_MAX, None + ) + + def get_water_heater_minimum_setpoint_temperature(self) -> Optional[float]: + """Get water heater minimum setpoint temperature value""" + return self.plant_settings.get( + SlpDeviceSettings.SLP_MIN_SETPOINT_TEMPERATURE, None + ) + + def get_water_heater_minimum_setpoint_temperature_minimum(self) -> Optional[float]: + """Get water heater minimum setpoint temperature minimum""" + return self.plant_settings.get( + SlpDeviceSettings.SLP_MIN_SETPOINT_TEMPERATURE_MIN, None + ) + + def get_water_heater_minimum_setpoint_temperature_maximum(self) -> Optional[float]: + """Get water heater minimum setpoint maximum temperature""" + return self.plant_settings.get( + SlpDeviceSettings.SLP_MIN_SETPOINT_TEMPERATURE_MAX, None + ) + + def get_water_heater_preheating_on_off(self) -> Optional[bool]: + """Get water heater preheating on off""" + return self.plant_settings.get(SlpDeviceSettings.SLP_PRE_HEATING_ON_OFF, None) + + def get_water_heater_heating_rate(self) -> Optional[float]: + """Get water heater heating rate""" + return self.plant_settings.get(SlpDeviceSettings.SLP_HEATING_RATE, None) + + def get_water_heater_boost(self) -> Optional[bool]: + """Get water heater boost""" + return self.data.get(NuosSplitProperties.BOOST_ON, None) + + def set_water_heater_boost(self, boost: bool): + """Set water heater boost""" + self.api.set_nous_boost(self.gw, boost) + self.data[NuosSplitProperties.BOOST_ON] = boost + + async def async_set_water_heater_boost(self, boost: bool): + """Set water heater boost""" + await self.api.async_set_nous_boost(self.gw, boost) + self.data[NuosSplitProperties.BOOST_ON] = boost + + def _set_water_heater_temperature(self, temperature: float, reduced: float): + """Set water heater temperature""" + self.api.set_nuos_temperature(self.gw, temperature, reduced) + self.data[NuosSplitProperties.PROC_REQ_TEMP] = temperature + self.data[NuosSplitProperties.REDUCED_TEMP] = reduced + + def set_water_heater_temperature(self, temperature: float): + """Set water heater temperature""" + if len(self.data) == 0: + self.update_state() + reduced = self.get_water_heater_reduced_temperature() + if reduced is None: + reduced = 0 + self._set_water_heater_temperature(temperature, reduced) + + async def _async_set_water_heater_temperature( + self, temperature: float, reduced: float + ): + """Async set water heater temperature""" + await self.api.async_set_nuos_temperature(self.gw, temperature, reduced) + self.data[NuosSplitProperties.PROC_REQ_TEMP] = temperature + self.data[NuosSplitProperties.REDUCED_TEMP] = reduced + + async def async_set_water_heater_temperature(self, temperature: float): + """Async set water heater temperature""" + if len(self.data) == 0: + await self.async_update_state() + reduced = self.get_water_heater_reduced_temperature() + if reduced is None: + reduced = 0 + await self._async_set_water_heater_temperature(temperature, reduced) + + def set_water_heater_reduced_temperature(self, temperature: float): + """Set water heater reduced temperature""" + if len(self.data) == 0: + self.update_state() + current = self.get_water_heater_current_temperature() + if current is None: + current = 0 + self._set_water_heater_temperature(current, temperature) + + async def async_set_water_heater_reduced_temperature(self, temperature: float): + """Set water heater reduced temperature""" + if len(self.data) == 0: + await self.async_update_state() + current = self.get_water_heater_current_temperature() + if current is None: + current = self.get_water_heater_minimum_temperature() + await self._async_set_water_heater_temperature(current, temperature) + + def set_water_heater_operation_mode(self, operation_mode: str): + """Set water heater operation mode""" + self.api.set_nuos_mode(self.gw, NuosSplitOperativeMode[operation_mode]) + self.data[NuosSplitProperties.MODE] = NuosSplitOperativeMode[ + operation_mode + ].value + + async def async_set_water_heater_operation_mode(self, operation_mode: str): + """Async set water heater operation mode""" + await self.api.async_set_nuos_mode( + self.gw, NuosSplitOperativeMode[operation_mode] + ) + self.data[NuosSplitProperties.MODE] = NuosSplitOperativeMode[ + operation_mode + ].value + + def set_min_setpoint_temp(self, min_setpoint_temp: float): + """Set water heater minimum setpoint temperature""" + self.api.set_velis_plant_setting( + self.gw, + self.plant_data, + SlpDeviceSettings.SLP_MIN_SETPOINT_TEMPERATURE, + min_setpoint_temp, + self.plant_settings[SlpDeviceSettings.SLP_MIN_SETPOINT_TEMPERATURE], + ) + self.plant_settings[ + SlpDeviceSettings.SLP_MIN_SETPOINT_TEMPERATURE + ] = min_setpoint_temp + + async def async_set_min_setpoint_temp(self, min_setpoint_temp: float): + """Async set water heater minimum setpoint temperature""" + await self.api.async_set_velis_plant_setting( + self.gw, + self.plant_data, + SlpDeviceSettings.SLP_MIN_SETPOINT_TEMPERATURE, + min_setpoint_temp, + self.plant_settings[SlpDeviceSettings.SLP_MIN_SETPOINT_TEMPERATURE], + ) + self.plant_settings[ + SlpDeviceSettings.SLP_MIN_SETPOINT_TEMPERATURE + ] = min_setpoint_temp + + def set_preheating(self, preheating: bool): + """Set water heater preheating""" + self.api.set_velis_plant_setting( + self.gw, + self.plant_data, + SlpDeviceSettings.SLP_PRE_HEATING_ON_OFF, + preheating, + self.plant_settings[SlpDeviceSettings.SLP_PRE_HEATING_ON_OFF], + ) + self.plant_settings[SlpDeviceSettings.SLP_PRE_HEATING_ON_OFF] = preheating + + async def async_set_preheating(self, preheating: bool): + """Async set water heater preheating""" + await self.api.async_set_velis_plant_setting( + self.gw, + self.plant_data, + SlpDeviceSettings.SLP_PRE_HEATING_ON_OFF, + preheating, + self.plant_settings[SlpDeviceSettings.SLP_PRE_HEATING_ON_OFF], + ) + self.plant_settings[SlpDeviceSettings.SLP_PRE_HEATING_ON_OFF] = preheating + + def set_heating_rate(self, heating_rate: float): + """Set water heater heating rate""" + self.api.set_velis_plant_setting( + self.gw, + self.plant_data, + SlpDeviceSettings.SLP_HEATING_RATE, + heating_rate, + self.plant_settings[SlpDeviceSettings.SLP_HEATING_RATE], + ) + self.plant_settings[SlpDeviceSettings.SLP_HEATING_RATE] = heating_rate + + async def async_set_heating_rate(self, heating_rate: float): + """Async set water heater heating rate""" + await self.api.async_set_velis_plant_setting( + self.gw, + self.plant_data, + SlpDeviceSettings.SLP_HEATING_RATE, + heating_rate, + self.plant_settings[SlpDeviceSettings.SLP_HEATING_RATE], + ) + self.plant_settings[SlpDeviceSettings.SLP_HEATING_RATE] = heating_rate diff --git a/ariston/velis_device.py b/ariston/velis_device.py index 5e45a0c..ee1654f 100644 --- a/ariston/velis_device.py +++ b/ariston/velis_device.py @@ -11,6 +11,7 @@ DeviceFeatures, VelisDeviceAttribute, VelisDeviceProperties, + WaterHeaterMode, WheType, ) from .device import AristonDevice @@ -29,6 +30,112 @@ def __init__( super().__init__(api, attributes) self.plant_settings: dict[str, Any] = dict() + @property + @abstractmethod + def plant_data(self) -> str: + """Final string to get plant data""" + + @property + @abstractmethod + def anti_legionella_on_off(self) -> str: + """Final string to get anti-legionella-on-off""" + + @property + @abstractmethod + def water_heater_mode(self) -> type[WaterHeaterMode]: + """Return the water heater mode class""" + + @property + @abstractmethod + def max_setpoint_temp(self) -> str: + """Final string to get max setpoint temperature""" + + def update_state(self) -> None: + """Update the device states from the cloud""" + self.data = self.api.get_velis_plant_data(self.plant_data, self.gw) + + async def async_update_state(self) -> None: + """Async update the device states from the cloud""" + self.data = await self.api.async_get_velis_plant_data(self.plant_data, self.gw) + + def update_settings(self) -> None: + """Get device settings wrapper""" + self.plant_settings = self.api.get_velis_plant_settings( + self.plant_data, self.gw + ) + + async def async_update_settings(self) -> None: + """Get device settings wrapper""" + self.plant_settings = await self.api.async_get_velis_plant_settings( + self.plant_data, self.gw + ) + + def set_power(self, power: bool): + """Set water heater power""" + self.api.set_velis_power(self.gw, self.plant_data, power) + self.data[VelisDeviceProperties.ON] = power + + async def async_set_power(self, power: bool) -> None: + """Async set water heater power""" + await self.api.async_set_velis_power(self.gw, self.plant_data, power) + self.data[VelisDeviceProperties.ON] = power + + def get_water_anti_leg_value(self) -> Optional[bool]: + """Get water heater anti-legionella value""" + return self.plant_settings.get(self.anti_legionella_on_off, None) + + def set_antilegionella(self, anti_leg: bool): + """Set water heater anti-legionella""" + self.api.set_velis_plant_setting( + self.gw, + self.plant_data, + self.anti_legionella_on_off, + 1.0 if anti_leg else 0.0, + 1.0 if self.plant_settings[self.anti_legionella_on_off] else 0.0, + ) + self.plant_settings[self.anti_legionella_on_off] = anti_leg + + async def async_set_antilegionella(self, anti_leg: bool): + """Async set water heater anti-legionella""" + await self.api.async_set_velis_plant_setting( + self.gw, + self.plant_data, + self.anti_legionella_on_off, + 1.0 if anti_leg else 0.0, + 1.0 if self.plant_settings[self.anti_legionella_on_off] else 0.0, + ) + self.plant_settings[self.anti_legionella_on_off] = anti_leg + + def get_water_heater_mode_operation_texts(self) -> list[str]: + """Get water heater operation mode texts""" + return [flag.name for flag in self.water_heater_mode] + + def get_water_heater_mode_options(self) -> list[int]: + """Get water heater operation options""" + return [flag.value for flag in self.water_heater_mode] + + def set_max_setpoint_temp(self, max_setpoint_temp: float): + """Set water heater maximum setpoint temperature""" + self.api.set_velis_plant_setting( + self.gw, + self.plant_data, + self.max_setpoint_temp, + max_setpoint_temp, + self.plant_settings[self.max_setpoint_temp], + ) + self.plant_settings[self.max_setpoint_temp] = max_setpoint_temp + + async def async_set_max_setpoint_temp(self, max_setpoint_temp: float): + """Async set water heater maximum setpoint temperature""" + await self.api.async_set_velis_plant_setting( + self.gw, + self.plant_data, + self.max_setpoint_temp, + max_setpoint_temp, + self.plant_settings[self.max_setpoint_temp], + ) + self.plant_settings[self.max_setpoint_temp] = max_setpoint_temp + def get_whe_type(self) -> WheType: """Get device whe type wrapper""" return WheType( @@ -49,21 +156,6 @@ async def async_get_features(self) -> None: self.features[DeviceFeatures.DHW_MODE_CHANGEABLE] = True await self.async_update_settings() - @abstractmethod - def update_settings(self) -> None: - """Get device settings wrapper""" - raise NotImplementedError - - @abstractmethod - async def async_update_settings(self) -> None: - """Get device settings wrapper""" - raise NotImplementedError - - @abstractmethod - def get_water_anti_leg_value(self) -> Optional[bool]: - """Get water heater anti-legionella value""" - raise NotImplementedError - @abstractmethod def get_water_heater_maximum_setpoint_temperature_minimum(self) -> Optional[float]: """Get water heater maximum setpoint temperature minimum""" @@ -74,14 +166,9 @@ def get_water_heater_maximum_setpoint_temperature_maximum(self) -> Optional[floa """Get water heater maximum setpoint maximum temperature""" raise NotImplementedError - @abstractmethod def get_water_heater_maximum_setpoint_temperature(self) -> Optional[float]: """Get water heater maximum setpoint temperature value""" - raise NotImplementedError - - def get_water_heater_current_temperature(self) -> Optional[float]: - """Get water heater current temperature""" - return self.data.get(VelisDeviceProperties.TEMP, None) + return self.plant_settings.get(self.max_setpoint_temp, None) def get_water_heater_minimum_temperature(self) -> float: """Get water heater minimum temperature""" @@ -91,10 +178,6 @@ def get_water_heater_maximum_temperature(self) -> Optional[float]: """Get water heater maximum temperature""" return self.get_water_heater_maximum_setpoint_temperature() - def get_water_heater_target_temperature(self) -> Optional[float]: - """Get water heater target temperature""" - return self.data.get(VelisDeviceProperties.REQ_TEMP, None) - def get_water_heater_temperature_step(self) -> int: """Get water heater temperature step""" return 1 @@ -111,49 +194,11 @@ def get_water_heater_mode_value(self) -> Optional[int]: """Get water heater mode value""" return self.data.get(VelisDeviceProperties.MODE, None) - def get_av_shw_value(self) -> Optional[int]: - """Get average showers value""" - return self.data.get(VelisDeviceProperties.AV_SHW, None) - def get_water_heater_power_value(self) -> Optional[bool]: """Get water heater power value""" return self.data.get(VelisDeviceProperties.ON, None) - def get_is_heating(self) -> Optional[bool]: - """Get is the water heater heating""" - return self.data.get(VelisDeviceProperties.HEAT_REQ, None) - @staticmethod def get_empty_unit() -> str: """Get empty unit""" return "" - - @abstractmethod - def set_antilegionella(self, anti_leg: bool) -> None: - """Set water heater anti-legionella""" - raise NotImplementedError - - @abstractmethod - async def async_set_antilegionella(self, anti_leg: bool) -> None: - """Async set water heater anti-legionella""" - raise NotImplementedError - - @abstractmethod - def set_water_heater_temperature(self, temperature: float) -> None: - """Set water heater temperature""" - raise NotImplementedError - - @abstractmethod - async def async_set_water_heater_temperature(self, temperature: float) -> None: - """Async set water heater temperature""" - raise NotImplementedError - - @abstractmethod - def set_power(self, power: bool) -> None: - """Set water heater power""" - raise NotImplementedError - - @abstractmethod - async def async_set_power(self, power: bool) -> None: - """Async set water heater power""" - raise NotImplementedError diff --git a/pyproject.toml b/pyproject.toml index 0362910..9bbec16 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,5 +14,5 @@ dependencies = [ ] requires-python = ">=3.9" license = { file = "LICENSE" } -version = "0.11.7" +version = "0.12.0" dynamic = ['description']