From f8150e9afe5efddeadaf4398c92731f2c466fa61 Mon Sep 17 00:00:00 2001 From: Philipp Date: Fri, 5 Jul 2024 17:11:06 +0200 Subject: [PATCH] Added Manual Cooling Duration on all controllers, Added option for default Manual Cooling Duration in Days, Refactored some constants --- custom_components/mypyllant/calendar.py | 6 +- custom_components/mypyllant/climate.py | 85 +++++++++++-------- custom_components/mypyllant/config_flow.py | 9 ++ custom_components/mypyllant/const.py | 5 ++ custom_components/mypyllant/manifest.json | 4 +- custom_components/mypyllant/number.py | 33 +++++++ custom_components/mypyllant/switch.py | 8 +- .../mypyllant/translations/cs.json | 1 + .../mypyllant/translations/de.json | 5 +- .../mypyllant/translations/en.json | 1 + .../mypyllant/translations/it.json | 1 + .../mypyllant/translations/pl.json | 1 + .../mypyllant/translations/sk.json | 1 + custom_components/mypyllant/utils.py | 10 ++- dev-requirements.txt | 2 +- tests/test_climate.py | 4 +- tests/test_number.py | 21 +++++ 17 files changed, 142 insertions(+), 55 deletions(-) create mode 100644 tests/test_number.py diff --git a/custom_components/mypyllant/calendar.py b/custom_components/mypyllant/calendar.py index 8a3a4a8..44e9bb7 100644 --- a/custom_components/mypyllant/calendar.py +++ b/custom_components/mypyllant/calendar.py @@ -28,7 +28,7 @@ RoomTimeProgram, System, ) -from myPyllant.enums import ZoneTimeProgramType +from myPyllant.enums import ZoneOperatingType from . import SystemCoordinator from .const import DOMAIN, WEEKDAYS_TO_RFC5545, RFC5545_TO_WEEKDAYS @@ -309,7 +309,7 @@ def build_event( async def update_time_program(self): await self.coordinator.api.set_zone_time_program( - self.zone, str(ZoneTimeProgramType.HEATING), self.time_program + self.zone, str(ZoneOperatingType.HEATING), self.time_program ) await self.coordinator.async_request_refresh_delayed() @@ -348,7 +348,7 @@ def build_event( async def update_time_program(self): await self.coordinator.api.set_zone_time_program( - self.zone, str(ZoneTimeProgramType.COOLING), self.time_program + self.zone, str(ZoneOperatingType.COOLING), self.time_program ) await self.coordinator.async_request_refresh_delayed() diff --git a/custom_components/mypyllant/climate.py b/custom_components/mypyllant/climate.py index 1fa82c8..ba5e591 100644 --- a/custom_components/mypyllant/climate.py +++ b/custom_components/mypyllant/climate.py @@ -30,11 +30,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.template import as_datetime from homeassistant.helpers.update_coordinator import CoordinatorEntity -from myPyllant.const import ( - DEFAULT_MANUAL_SETPOINT_TYPE, - DEFAULT_QUICK_VETO_DURATION, - ZONE_MANUAL_SETPOINT_TYPES, -) +from myPyllant.const import DEFAULT_QUICK_VETO_DURATION from myPyllant.models import ( System, Zone, @@ -47,6 +43,7 @@ ZoneCurrentSpecialFunction, CircuitState, AmbisenseRoomOperationMode, + ZoneOperatingType, ) from custom_components.mypyllant.utils import ( @@ -78,14 +75,15 @@ SERVICE_SET_TIME_CONTROLLED_COOLING_SETPOINT, SERVICE_SET_VENTILATION_BOOST, SERVICE_CANCEL_VENTILATION_BOOST, + DEFAULT_MANUAL_SETPOINT_TYPE, ) from .ventilation_climate import _FAN_STAGE_TYPE_OPTIONS, VentilationClimate _LOGGER = logging.getLogger(__name__) _ZONE_MANUAL_SETPOINT_TYPES_OPTIONS = [ - selector.SelectOptionDict(value=k, label=v) - for k, v in ZONE_MANUAL_SETPOINT_TYPES.items() + selector.SelectOptionDict(value=v.value, label=v.title()) + for v in list(ZoneOperatingType) ] _ZONE_OPERATING_MODE_OPTIONS = [ @@ -95,22 +93,6 @@ ) ] -ZONE_PRESET_MAP = { - PRESET_BOOST: ZoneCurrentSpecialFunction.QUICK_VETO, - PRESET_ECO: ZoneCurrentSpecialFunction.NONE, - PRESET_NONE: ZoneCurrentSpecialFunction.NONE, - PRESET_AWAY: ZoneCurrentSpecialFunction.HOLIDAY, - "system_off": ZoneCurrentSpecialFunction.SYSTEM_OFF, - "ventilation_boost": ZoneCurrentSpecialFunction.VENTILATION_BOOST, -} - -ZONE_PRESET_MAP_VRC700 = { - ZoneOperatingModeVRC700.OFF: PRESET_NONE, - ZoneOperatingModeVRC700.DAY: PRESET_COMFORT, - ZoneOperatingModeVRC700.AUTO: PRESET_NONE, - ZoneOperatingModeVRC700.SET_BACK: PRESET_ECO, -} - ZONE_HVAC_ACTION_MAP = { CircuitState.STANDBY: HVACAction.IDLE, CircuitState.HEATING: HVACAction.HEATING, @@ -420,6 +402,27 @@ def hvac_mode_map(self): mode_map[HVAC_MODE_COOLING_FOR_DAYS] = HVACMode.COOL return mode_map + @property + def preset_mode_map(self): + if self.zone.control_identifier.is_vrc700: + return { + ZoneOperatingModeVRC700.OFF: PRESET_NONE, + ZoneOperatingModeVRC700.DAY: PRESET_COMFORT, + ZoneOperatingModeVRC700.AUTO: PRESET_NONE, + ZoneOperatingModeVRC700.SET_BACK: PRESET_ECO, + } + else: + preset_modes = { + PRESET_BOOST: ZoneCurrentSpecialFunction.QUICK_VETO, + PRESET_NONE: ZoneCurrentSpecialFunction.NONE, + PRESET_AWAY: ZoneCurrentSpecialFunction.HOLIDAY, + "system_off": ZoneCurrentSpecialFunction.SYSTEM_OFF, + "ventilation_boost": ZoneCurrentSpecialFunction.VENTILATION_BOOST, + } + if self.zone.is_eco_mode: + preset_modes[PRESET_ECO] = ZoneCurrentSpecialFunction.NONE + return preset_modes + @property def default_quick_veto_duration(self): return self.config.options.get( @@ -634,8 +637,6 @@ def supported_features(self) -> ClimateEntityFeature: @property def target_temperature(self) -> float | None: - if self.zone.is_eco_mode: - return self.zone.heating.set_back_temperature return self.zone.desired_room_temperature_setpoint @property @@ -664,17 +665,21 @@ def current_humidity(self) -> float | None: def hvac_mode(self) -> HVACMode: if self.system.manual_cooling_ongoing: return self.hvac_mode_map.get(HVAC_MODE_COOLING_FOR_DAYS) - return self.hvac_mode_map.get(self.zone.heating.operation_mode_heating) + return self.hvac_mode_map.get(self.zone.active_operation_mode) async def async_set_hvac_mode(self, hvac_mode: HVACMode): if hvac_mode == HVACMode.COOL: if not self.system.manual_cooling_ongoing: await self.set_cooling_for_days() else: + refresh_delay = 10 if self.system.manual_cooling_ongoing: await self.coordinator.api.cancel_cooling_for_days(self.system) + refresh_delay = 20 mode = [k for k, v in self.hvac_mode_map.items() if v == hvac_mode][0] - await self.set_zone_operating_mode(mode, refresh_delay=20) + await self.set_zone_operating_mode( + mode, self.zone.active_operating_type, refresh_delay=refresh_delay + ) async def set_zone_operating_mode( self, @@ -701,6 +706,12 @@ async def set_zone_operating_mode( raise ValueError( f"Invalid mode, use one of {', '.join(ZoneOperatingMode)}" ) + _LOGGER.debug( + "Setting %s on %s to %s", + operating_type, + self.zone.name, + mode, + ) await self.coordinator.api.set_zone_operating_mode( self.zone, mode, @@ -781,20 +792,20 @@ async def async_set_temperature(self, **kwargs: Any) -> None: @property def preset_modes(self) -> list[str]: if self.zone.control_identifier.is_vrc700: - return list({v for v in ZONE_PRESET_MAP_VRC700.values()}) + return list({v for v in self.preset_mode_map.values()}) else: - return [k for k in ZONE_PRESET_MAP.keys()] + return list(self.preset_mode_map.keys()) @property def preset_mode(self) -> str: if self.zone.control_identifier.is_vrc700: - return ZONE_PRESET_MAP_VRC700[self.zone.heating.operation_mode_heating] # type: ignore + return self.preset_mode_map[self.zone.active_operation_mode] # type: ignore else: if self.zone.is_eco_mode: return PRESET_ECO return [ k - for k, v in ZONE_PRESET_MAP.items() + for k, v in self.preset_mode_map.items() if v == self.zone.current_special_function ][0] @@ -810,21 +821,21 @@ async def async_set_preset_mode(self, preset_mode): if preset_mode == PRESET_NONE: # None can map to off or auto mode, if it's selected by the user we want auto requested_mode = ZoneOperatingModeVRC700.AUTO - elif preset_mode in ZONE_PRESET_MAP_VRC700.values(): + elif preset_mode in self.preset_mode_map.values(): requested_mode = [ - k for k, v in ZONE_PRESET_MAP_VRC700.items() if v == preset_mode + k for k, v in self.preset_mode_map.items() if v == preset_mode ][0] else: raise ValueError( - f'Invalid preset mode, use one of {", ".join(set(ZONE_PRESET_MAP_VRC700.values()))}' + f'Invalid preset mode, use one of {", ".join(set(self.preset_mode_map.values()))}' ) await self.set_zone_operating_mode(requested_mode) else: - if preset_mode not in ZONE_PRESET_MAP: + if preset_mode not in self.preset_mode_map: raise ValueError( - f'Invalid preset mode, use one of {", ".join(ZONE_PRESET_MAP.keys())}' + f'Invalid preset mode {preset_mode}, use one of {", ".join(self.preset_mode_map.keys())}' ) - requested_mode = ZONE_PRESET_MAP[preset_mode] + requested_mode = self.preset_mode_map[preset_mode] if requested_mode != self.zone.current_special_function: # Cancel previous special function if ( diff --git a/custom_components/mypyllant/config_flow.py b/custom_components/mypyllant/config_flow.py index 6faaf19..345b8b3 100644 --- a/custom_components/mypyllant/config_flow.py +++ b/custom_components/mypyllant/config_flow.py @@ -51,6 +51,8 @@ DEFAULT_FETCH_ENERGY_MANAGEMENT, OPTION_FETCH_EEBUS, DEFAULT_FETCH_EEBUS, + OPTION_DEFAULT_MANUAL_COOLING_DURATION, + DEFAULT_MANUAL_COOLING_DURATION, ) _LOGGER = logging.getLogger(__name__) @@ -162,6 +164,13 @@ async def async_step_init( DEFAULT_HOLIDAY_SETPOINT, ), ): vol.All(vol.Coerce(float), vol.Clamp(min=0, max=30)), + vol.Required( + OPTION_DEFAULT_MANUAL_COOLING_DURATION, + default=self.config_entry.options.get( + OPTION_DEFAULT_MANUAL_COOLING_DURATION, + DEFAULT_MANUAL_COOLING_DURATION, + ), + ): positive_int, vol.Required( OPTION_TIME_PROGRAM_OVERWRITE, default=self.config_entry.options.get( diff --git a/custom_components/mypyllant/const.py b/custom_components/mypyllant/const.py index 5e71080..4731862 100644 --- a/custom_components/mypyllant/const.py +++ b/custom_components/mypyllant/const.py @@ -1,9 +1,12 @@ +from myPyllant.enums import ZoneOperatingType + DOMAIN = "mypyllant" OPTION_UPDATE_INTERVAL = "update_interval" OPTION_UPDATE_INTERVAL_DAILY = "update_interval_daily" OPTION_REFRESH_DELAY = "refresh_delay" OPTION_DEFAULT_QUICK_VETO_DURATION = "quick_veto_duration" OPTION_DEFAULT_HOLIDAY_DURATION = "holiday_duration" +OPTION_DEFAULT_MANUAL_COOLING_DURATION = "manual_cooling_duration" OPTION_COUNTRY = "country" OPTION_BRAND = "brand" OPTION_TIME_PROGRAM_OVERWRITE = "time_program_overwrite" @@ -16,6 +19,7 @@ DEFAULT_UPDATE_INTERVAL = 60 # in seconds DEFAULT_UPDATE_INTERVAL_DAILY = 3600 # in seconds DEFAULT_REFRESH_DELAY = 5 # in seconds +DEFAULT_MANUAL_COOLING_DURATION = 30 # in days DEFAULT_COUNTRY = "germany" DEFAULT_TIME_PROGRAM_OVERWRITE = False DEFAULT_HOLIDAY_SETPOINT = 10.0 # in °C @@ -24,6 +28,7 @@ DEFAULT_FETCH_AMBISENSE_ROOMS = True DEFAULT_FETCH_ENERGY_MANAGEMENT = True DEFAULT_FETCH_EEBUS = True +DEFAULT_MANUAL_SETPOINT_TYPE = ZoneOperatingType.HEATING QUOTA_PAUSE_INTERVAL = 3 * 3600 # in seconds API_DOWN_PAUSE_INTERVAL = 15 * 60 # in seconds HVAC_MODE_COOLING_FOR_DAYS = "COOLING_FOR_DAYS" diff --git a/custom_components/mypyllant/manifest.json b/custom_components/mypyllant/manifest.json index b87b818..03da413 100644 --- a/custom_components/mypyllant/manifest.json +++ b/custom_components/mypyllant/manifest.json @@ -10,7 +10,7 @@ "iot_class": "cloud_polling", "issue_tracker": "https://github.com/signalkraft/mypyllant-component/issues", "requirements": [ - "myPyllant==0.8.21" + "myPyllant==0.8.23" ], - "version": "v0.8.9" + "version": "v0.8.11" } diff --git a/custom_components/mypyllant/number.py b/custom_components/mypyllant/number.py index f488f12..f5a5dc6 100644 --- a/custom_components/mypyllant/number.py +++ b/custom_components/mypyllant/number.py @@ -35,6 +35,8 @@ async def async_setup_entry( sensors: EntityList[NumberEntity] = EntityList() for index, system in enumerate(coordinator.data): sensors.append(lambda: SystemHolidayDurationNumber(index, coordinator)) + if system.is_cooling_allowed: + sensors.append(lambda: SystemManualCoolingDays(index, coordinator)) for zone_index, zone in enumerate(system.zones): sensors.append( @@ -116,6 +118,37 @@ def unique_id(self) -> str: return f"{DOMAIN}_{self.id_infix}_holiday_duration_remaining" +class SystemManualCoolingDays(SystemCoordinatorEntity, NumberEntity): + _attr_native_unit_of_measurement = UnitOfTime.DAYS + _attr_icon = "mdi:snowflake" + _attr_step = 1 # type: ignore + + @property + def name(self): + return f"{self.name_prefix} Manual Cooling Duration" + + @property + def native_value(self): + return self.system.manual_cooling_days or 0 + + async def async_set_native_value(self, value: float) -> None: + if value == 0: + await self.coordinator.api.cancel_cooling_for_days(self.system) + else: + await self.coordinator.api.set_cooling_for_days( + self.system, duration_days=int(value) + ) + await self.coordinator.async_request_refresh_delayed(20) + + @property + def unique_id(self) -> str: + return f"{DOMAIN}_{self.id_infix}_manual_cooling_days" + + @property + def available(self) -> bool: + return self.system.is_cooling_allowed + + class ZoneQuickVetoDurationNumber(ZoneCoordinatorEntity, NumberEntity): _attr_native_unit_of_measurement = UnitOfTime.HOURS _attr_icon = "mdi:rocket-launch" diff --git a/custom_components/mypyllant/switch.py b/custom_components/mypyllant/switch.py index e5366a2..d898714 100644 --- a/custom_components/mypyllant/switch.py +++ b/custom_components/mypyllant/switch.py @@ -102,13 +102,9 @@ def is_on(self): return self.system.manual_cooling_planned async def async_turn_on(self, **kwargs): - _, end = get_default_holiday_dates( - self.manual_cooling_start, - self.manual_cooling_end, - self.system.timezone, - self.default_manual_cooling_duration, + await self.coordinator.api.set_cooling_for_days( + self.system, duration_days=self.default_manual_cooling_duration ) - await self.coordinator.api.set_cooling_for_days(self.system, end=end) await self.coordinator.async_request_refresh_delayed(20) async def async_turn_off(self, **kwargs): diff --git a/custom_components/mypyllant/translations/cs.json b/custom_components/mypyllant/translations/cs.json index 26741ad..04931bc 100644 --- a/custom_components/mypyllant/translations/cs.json +++ b/custom_components/mypyllant/translations/cs.json @@ -46,6 +46,7 @@ "holiday_duration": "Nastavená doba trvání dovolené ve dnech", "time_program_overwrite": "Regulátory teploty přepisují časový program namísto nastavení rychlého veta", "default_holiday_setpoint": "Výchozí teplota pro dovolenou", + "manual_cooling_duration": "Doba trvání manuálního chlazení v dnech", "country": "Země", "brand": "Značka", "fetch_rts": "Načíst statistiky v reálném čase (není podporováno na každém systému)", diff --git a/custom_components/mypyllant/translations/de.json b/custom_components/mypyllant/translations/de.json index c0489d1..a04e95f 100644 --- a/custom_components/mypyllant/translations/de.json +++ b/custom_components/mypyllant/translations/de.json @@ -26,9 +26,9 @@ "preset_mode": { "state": { "system_off": "System aus", - "ventilation_boost": "Lüftungs-Boost", + "ventilation_boost": "Stoßlüften", "boost": "Quick Veto", - "away": "Abwesenheit" + "away": "Abwesenheitsmodus" } } } @@ -46,6 +46,7 @@ "holiday_duration": "Standard Dauer in Tagen für Abwesenheitsmodus", "time_program_overwrite": "Temperaturänderungen in der Zeitsteuerung speichern, statt Quick Veto", "default_holiday_setpoint": "Standardtemperatur während Abwesenheitsmodus", + "manual_cooling_duration": "Standard Dauer in Tagen für manuelle Kühlung", "country": "Land", "brand": "Hersteller", "fetch_rts": "Echtzeit-Statistiken abrufen (nicht auf jedem System unterstützt)", diff --git a/custom_components/mypyllant/translations/en.json b/custom_components/mypyllant/translations/en.json index 2454ade..a73db9a 100644 --- a/custom_components/mypyllant/translations/en.json +++ b/custom_components/mypyllant/translations/en.json @@ -46,6 +46,7 @@ "holiday_duration": "Default duration in days for away mode", "time_program_overwrite": "Temperature controls overwrite time program instead of setting quick veto", "default_holiday_setpoint": "Default temperature setpoint for away mode", + "manual_cooling_duration": "Default duration for manual cooling in days", "country": "Country", "brand": "Brand", "fetch_rts": "Fetch real-time statistics (not supported on every system)", diff --git a/custom_components/mypyllant/translations/it.json b/custom_components/mypyllant/translations/it.json index 9e88f21..fe22744 100644 --- a/custom_components/mypyllant/translations/it.json +++ b/custom_components/mypyllant/translations/it.json @@ -46,6 +46,7 @@ "holiday_duration": "Durata di default in giorni per le vacanze", "time_program_overwrite": "Controlla la temperatura sovrascrivendo la programmazione oraria invece di attivare acqua calda rapida", "default_holiday_setpoint": "Temperatura di default per le vacanze", + "manual_cooling_duration": "Durata di default in giorni per il raffreddamento manuale", "country": "Stato", "brand": "Marca", "fetch_rts": "Recupera le statistiche in tempo reale (non supportato su tutti i sistemi)", diff --git a/custom_components/mypyllant/translations/pl.json b/custom_components/mypyllant/translations/pl.json index 9336b61..146fa55 100644 --- a/custom_components/mypyllant/translations/pl.json +++ b/custom_components/mypyllant/translations/pl.json @@ -46,6 +46,7 @@ "holiday_duration": "Domyślny czas trwania wakacji w dniach", "time_program_overwrite": "Kontrola temperatury nadpisuje program czasowy zamiast ustawiać szybkie weto", "default_holiday_setpoint": "Domyślna temperatura wakacyjna", + "manual_cooling_duration": "Domyślny czas trwania ręcznego chłodzenia w dniach", "country": "Kraj", "brand": "Marka", "fetch_rts": "Pobierz statystyki w czasie rzeczywistym (nie jest obsługiwane na każdym systemie)", diff --git a/custom_components/mypyllant/translations/sk.json b/custom_components/mypyllant/translations/sk.json index 6a213b6..b1bdaa7 100644 --- a/custom_components/mypyllant/translations/sk.json +++ b/custom_components/mypyllant/translations/sk.json @@ -46,6 +46,7 @@ "holiday_duration": "Predvolená doba trvania dovolenky v dňoch", "time_program_overwrite": "Regulátory teploty prepisujú časový program namiesto nastavenia rýchleho veta", "default_holiday_setpoint": "Predvolená teplota počas dovolenky", + "manual_cooling_duration": "Predvolená doba trvania manuálneho chladenia v dňoch", "country": "Krajina", "brand": "Značka", "fetch_rts": "Načítať štatistiky v reálnom čase (nie je podporované na každom systéme)", diff --git a/custom_components/mypyllant/utils.py b/custom_components/mypyllant/utils.py index 1208df7..758227e 100644 --- a/custom_components/mypyllant/utils.py +++ b/custom_components/mypyllant/utils.py @@ -11,7 +11,12 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.update_coordinator import CoordinatorEntity -from custom_components.mypyllant.const import DOMAIN, OPTION_DEFAULT_HOLIDAY_DURATION +from custom_components.mypyllant.const import ( + DOMAIN, + OPTION_DEFAULT_HOLIDAY_DURATION, + OPTION_DEFAULT_MANUAL_COOLING_DURATION, + DEFAULT_MANUAL_COOLING_DURATION, +) from myPyllant.const import DEFAULT_HOLIDAY_DURATION if typing.TYPE_CHECKING: @@ -165,7 +170,7 @@ def __init__( @property def default_manual_cooling_duration(self): return self.config.options.get( - OPTION_DEFAULT_HOLIDAY_DURATION, DEFAULT_HOLIDAY_DURATION + OPTION_DEFAULT_MANUAL_COOLING_DURATION, DEFAULT_MANUAL_COOLING_DURATION ) @property @@ -177,6 +182,7 @@ def extra_state_attributes(self) -> typing.Mapping[str, typing.Any] | None: else None, "manual_cooling_start_date_time": self.manual_cooling_start, "manual_cooling_end_date_time": self.manual_cooling_end, + "manual_cooling_days_remaining": self.system.manual_cooling_days, } @property diff --git a/dev-requirements.txt b/dev-requirements.txt index 026cc63..4089182 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -11,7 +11,7 @@ types-PyYAML~=6.0.12.20240311 # Need specific versions pytest-homeassistant-custom-component==0.13.142 -myPyllant==0.8.21 +myPyllant==0.8.23 # Versions handled by pytest-homeassistant-custom-component freezegun diff --git a/tests/test_climate.py b/tests/test_climate.py index 602226c..28aa1f6 100644 --- a/tests/test_climate.py +++ b/tests/test_climate.py @@ -2,7 +2,7 @@ import pytest as pytest from homeassistant.components.climate import HVACMode, PRESET_NONE -from homeassistant.components.climate.const import FAN_OFF, PRESET_ECO, PRESET_BOOST +from homeassistant.components.climate.const import FAN_OFF, PRESET_BOOST from homeassistant.const import ATTR_TEMPERATURE from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers.entity_registry import DATA_REGISTRY, EntityRegistry @@ -90,7 +90,7 @@ async def test_zone_climate( await climate.async_set_hvac_mode(HVACMode.AUTO) await climate.async_set_temperature(**{ATTR_TEMPERATURE: 20}) # TODO: Test logic of different calls depending on current new preset mode - await climate.async_set_preset_mode(preset_mode=PRESET_ECO) + await climate.async_set_preset_mode(preset_mode=PRESET_NONE) system_coordinator_mock._debounced_refresh.async_cancel() print(system_coordinator_mock.data[0].state["zones"]) diff --git a/tests/test_number.py b/tests/test_number.py new file mode 100644 index 0000000..a8680d3 --- /dev/null +++ b/tests/test_number.py @@ -0,0 +1,21 @@ +from custom_components.mypyllant import SystemCoordinator +from custom_components.mypyllant.number import SystemManualCoolingDays +from myPyllant.api import MyPyllantAPI +from myPyllant.tests.generate_test_data import DATA_DIR +from myPyllant.tests.utils import load_test_data + + +async def test_manual_cooling_days( + mypyllant_aioresponses, + mocked_api: MyPyllantAPI, + system_coordinator_mock: SystemCoordinator, +): + test_data = load_test_data(DATA_DIR / "ventilation") + with mypyllant_aioresponses(test_data) as _: + system_coordinator_mock.data = ( + await system_coordinator_mock._async_update_data() + ) + assert system_coordinator_mock.data[0].is_cooling_allowed is True + manual_cooling = SystemManualCoolingDays(0, system_coordinator_mock) + assert manual_cooling.native_value == 0 + await mocked_api.aiohttp_session.close()