1 """Support for Atlantic Pass APC Heating Control."""
3 from __future__
import annotations
5 from asyncio
import sleep
6 from typing
import Any, cast
8 from propcache
import cached_property
9 from pyoverkiz.enums
import OverkizCommand, OverkizCommandParam, OverkizState
12 ATTR_TARGET_TEMP_HIGH,
21 from ..coordinator
import OverkizDataUpdateCoordinator
22 from ..executor
import OverkizExecutor
23 from .atlantic_pass_apc_heating_zone
import AtlanticPassAPCHeatingZone
25 PRESET_SCHEDULE =
"schedule"
26 PRESET_MANUAL =
"manual"
28 OVERKIZ_MODE_TO_PRESET_MODES: dict[str, str] = {
29 OverkizCommandParam.MANU: PRESET_MANUAL,
30 OverkizCommandParam.INTERNAL_SCHEDULING: PRESET_SCHEDULE,
33 PRESET_MODES_TO_OVERKIZ = {v: k
for k, v
in OVERKIZ_MODE_TO_PRESET_MODES.items()}
36 OVERKIZ_TO_HVAC_ACTION: dict[str, HVACAction] = {
37 OverkizCommandParam.COOLING: HVACAction.COOLING,
38 OverkizCommandParam.DRYING: HVACAction.DRYING,
39 OverkizCommandParam.HEATING: HVACAction.HEATING,
41 OverkizCommandParam.STOP: HVACAction.OFF,
44 HVAC_ACTION_TO_OVERKIZ_PROFILE_STATE: dict[HVACAction, OverkizState] = {
45 HVACAction.COOLING: OverkizState.IO_PASS_APC_COOLING_PROFILE,
46 HVACAction.HEATING: OverkizState.IO_PASS_APC_HEATING_PROFILE,
49 HVAC_ACTION_TO_OVERKIZ_MODE_STATE: dict[HVACAction, OverkizState] = {
50 HVACAction.COOLING: OverkizState.IO_PASS_APC_COOLING_MODE,
51 HVACAction.HEATING: OverkizState.IO_PASS_APC_HEATING_MODE,
54 TEMPERATURE_ZONECONTROL_DEVICE_INDEX = 1
56 SUPPORTED_FEATURES: ClimateEntityFeature = (
57 ClimateEntityFeature.PRESET_MODE
58 | ClimateEntityFeature.TURN_OFF
59 | ClimateEntityFeature.TURN_ON
62 OVERKIZ_THERMAL_CONFIGURATION_TO_HVAC_MODE: dict[
63 OverkizCommandParam, tuple[HVACMode, ClimateEntityFeature]
65 OverkizCommandParam.COOLING: (
67 SUPPORTED_FEATURES | ClimateEntityFeature.TARGET_TEMPERATURE,
69 OverkizCommandParam.HEATING: (
71 SUPPORTED_FEATURES | ClimateEntityFeature.TARGET_TEMPERATURE,
73 OverkizCommandParam.HEATING_AND_COOLING: (
75 SUPPORTED_FEATURES | ClimateEntityFeature.TARGET_TEMPERATURE_RANGE,
82 """Representation of Atlantic Pass APC Heating And Cooling Zone Control."""
84 _attr_target_temperature_step = PRECISION_HALVES
87 self, device_url: str, coordinator: OverkizDataUpdateCoordinator
90 super().
__init__(device_url, coordinator)
103 climate_entity_feature,
104 ) = thermal_configuration
118 zone_control_device := self.
executorexecutor.linked_device(
119 TEMPERATURE_ZONECONTROL_DEVICE_INDEX
123 zone_control_device.device_url,
129 """Retrieve thermal configuration for this devices."""
133 state_thermal_configuration := cast(
134 OverkizCommandParam |
None,
135 self.
executorexecutor.select_state(OverkizState.CORE_THERMAL_CONFIGURATION),
139 and state_thermal_configuration
140 in OVERKIZ_THERMAL_CONFIGURATION_TO_HVAC_MODE
142 return OVERKIZ_THERMAL_CONFIGURATION_TO_HVAC_MODE[
143 state_thermal_configuration
150 """ZoneControlZone device has a single possible mode."""
160 """Check if the device behave like the Pass APC Heating Zone."""
162 return self.
executorexecutor.has_command(
163 OverkizCommand.SET_DEROGATED_TARGET_TEMPERATURE
168 """Return hvac operation ie. heat, cool, dry, off mode."""
173 OverkizState.IO_PASS_APC_OPERATING_MODE
178 return OVERKIZ_TO_HVAC_ACTION[cast(str, state)]
180 return HVACAction.OFF
184 """Return the current running hvac operation."""
189 )
in HVAC_ACTION_TO_OVERKIZ_PROFILE_STATE
and cast(
192 HVAC_ACTION_TO_OVERKIZ_PROFILE_STATE[hvac_action]
194 ) == OverkizCommandParam.STOP:
195 return HVACAction.IDLE
201 """Return hvac operation ie. heat, cool, dry, off mode."""
204 return super().hvac_mode
209 cooling_is_off = cast(
211 self.
executorexecutor.select_state(OverkizState.CORE_COOLING_ON_OFF),
212 )
in (OverkizCommandParam.OFF,
None)
214 heating_is_off = cast(
216 self.
executorexecutor.select_state(OverkizState.CORE_HEATING_ON_OFF),
217 )
in (OverkizCommandParam.OFF,
None)
221 (device_hvac_mode == HVACMode.COOL
and cooling_is_off)
222 or (device_hvac_mode == HVACMode.HEAT
and heating_is_off)
224 device_hvac_mode == HVACMode.HEAT_COOL
231 return device_hvac_mode
234 """Set new target hvac mode."""
243 on_off_target_command_param = (
244 OverkizCommandParam.OFF
245 if hvac_mode == HVACMode.OFF
246 else OverkizCommandParam.ON
249 await self.
executorexecutor.async_execute_command(
250 OverkizCommand.SET_COOLING_ON_OFF,
251 on_off_target_command_param,
253 await self.
executorexecutor.async_execute_command(
254 OverkizCommand.SET_HEATING_ON_OFF,
255 on_off_target_command_param,
262 """Return the current preset mode, e.g., schedule, manual."""
265 return super().preset_mode
270 mode_state := HVAC_ACTION_TO_OVERKIZ_MODE_STATE[
276 mode := OVERKIZ_MODE_TO_PRESET_MODES[
277 cast(str, self.
executorexecutor.select_state(mode_state))
288 """Set new preset mode."""
294 mode = PRESET_MODES_TO_OVERKIZ[preset_mode]
297 await self.
executorexecutor.async_execute_command(
298 OverkizCommand.SET_PASS_APC_HEATING_MODE, mode
300 await self.
executorexecutor.async_execute_command(
301 OverkizCommand.SET_PASS_APC_COOLING_MODE, mode
308 """Return hvac target temperature."""
311 return super().target_temperature
315 if device_hvac_mode == HVACMode.HEAT_COOL:
318 if device_hvac_mode == HVACMode.COOL:
322 OverkizState.CORE_COOLING_TARGET_TEMPERATURE
326 if device_hvac_mode == HVACMode.HEAT:
330 OverkizState.CORE_HEATING_TARGET_TEMPERATURE
335 float, self.
executorexecutor.select_state(OverkizState.CORE_TARGET_TEMPERATURE)
340 """Return the highbound target temperature we try to reach (cooling)."""
347 self.
executorexecutor.select_state(OverkizState.CORE_COOLING_TARGET_TEMPERATURE),
352 """Return the lowbound target temperature we try to reach (heating)."""
359 self.
executorexecutor.select_state(OverkizState.CORE_HEATING_TARGET_TEMPERATURE),
363 """Set new temperature."""
369 target_temperature = kwargs.get(ATTR_TEMPERATURE)
370 target_temp_low = kwargs.get(ATTR_TARGET_TEMP_LOW)
371 target_temp_high = kwargs.get(ATTR_TARGET_TEMP_HIGH)
374 if hvac_mode == HVACMode.HEAT_COOL:
375 if target_temp_low
is not None:
376 await self.
executorexecutor.async_execute_command(
377 OverkizCommand.SET_HEATING_TARGET_TEMPERATURE,
381 if target_temp_high
is not None:
382 await self.
executorexecutor.async_execute_command(
383 OverkizCommand.SET_COOLING_TARGET_TEMPERATURE,
387 elif target_temperature
is not None:
388 if hvac_mode == HVACMode.HEAT:
389 await self.
executorexecutor.async_execute_command(
390 OverkizCommand.SET_HEATING_TARGET_TEMPERATURE,
394 elif hvac_mode == HVACMode.COOL:
395 await self.
executorexecutor.async_execute_command(
396 OverkizCommand.SET_COOLING_TARGET_TEMPERATURE,
400 await self.
executorexecutor.async_execute_command(
401 OverkizCommand.SET_DEROGATION_ON_OFF_STATE,
402 OverkizCommandParam.ON,
408 """Refresh the device modes to have new states."""
413 await self.
executorexecutor.async_execute_command(
414 OverkizCommand.REFRESH_PASS_APC_HEATING_MODE
417 await self.
executorexecutor.async_execute_command(
418 OverkizCommand.REFRESH_PASS_APC_HEATING_PROFILE
421 await self.
executorexecutor.async_execute_command(
422 OverkizCommand.REFRESH_PASS_APC_COOLING_MODE
425 await self.
executorexecutor.async_execute_command(
426 OverkizCommand.REFRESH_PASS_APC_COOLING_PROFILE
429 await self.
executorexecutor.async_execute_command(
430 OverkizCommand.REFRESH_TARGET_TEMPERATURE
435 """Return Minimum Temperature for AC of this group."""
439 if device_hvac_mode
in (HVACMode.HEAT, HVACMode.HEAT_COOL):
443 OverkizState.CORE_MINIMUM_HEATING_TARGET_TEMPERATURE
447 if device_hvac_mode == HVACMode.COOL:
451 OverkizState.CORE_MINIMUM_COOLING_TARGET_TEMPERATURE
455 return super().min_temp
459 """Return Max Temperature for AC of this group."""
463 if device_hvac_mode == HVACMode.HEAT:
467 OverkizState.CORE_MAXIMUM_HEATING_TARGET_TEMPERATURE
471 if device_hvac_mode
in (HVACMode.COOL, HVACMode.HEAT_COOL):
475 OverkizState.CORE_MAXIMUM_COOLING_TARGET_TEMPERATURE
479 return super().max_temp
HVACMode|None hvac_mode(self)
tuple _attr_supported_features
bool is_using_derogated_temperature_fallback(self)
str|None preset_mode(self)
None async_set_hvac_mode(self, HVACMode hvac_mode)
float|None target_temperature_low(self)
HVACAction zone_control_hvac_action(self)
None async_refresh_modes(self)
tuple[HVACMode, ClimateEntityFeature]|None thermal_configuration(self)
float|None target_temperature(self)
None async_set_preset_mode(self, str preset_mode)
float|None target_temperature_high(self)
HVACAction|None hvac_action(self)
HVACMode|None device_hvac_mode(self)
None async_set_temperature(self, **Any kwargs)
None __init__(self, str device_url, OverkizDataUpdateCoordinator coordinator)