-
-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add device AtlanticPassAPCHeatingZone #785
Changes from 2 commits
1a45060
0336ac9
2fef79d
d6fce28
524b35a
afe1dc8
4a3d81b
df639e5
d9f79a2
78356fa
3ab3c52
ec491fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,260 @@ | ||||||||||||||
"""Support for Atlantic Pass APC Heating Zone.""" | ||||||||||||||
import logging | ||||||||||||||
from typing import List, Optional | ||||||||||||||
|
||||||||||||||
from pyoverkiz.enums import OverkizState | ||||||||||||||
|
||||||||||||||
from homeassistant.components.climate import ( | ||||||||||||||
SUPPORT_PRESET_MODE, | ||||||||||||||
SUPPORT_TARGET_TEMPERATURE, | ||||||||||||||
ClimateEntity, | ||||||||||||||
) | ||||||||||||||
from homeassistant.components.climate.const import ( | ||||||||||||||
HVAC_MODE_AUTO, | ||||||||||||||
HVAC_MODE_HEAT, | ||||||||||||||
HVAC_MODE_OFF, | ||||||||||||||
PRESET_AWAY, | ||||||||||||||
PRESET_COMFORT, | ||||||||||||||
PRESET_ECO, | ||||||||||||||
) | ||||||||||||||
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS | ||||||||||||||
|
||||||||||||||
from ..coordinator import OverkizDataUpdateCoordinator | ||||||||||||||
from ..entity import OverkizEntity | ||||||||||||||
|
||||||||||||||
_LOGGER = logging.getLogger(__name__) | ||||||||||||||
|
||||||||||||||
CUSTOM_PRESET_DEROGATION = "Derogation" | ||||||||||||||
CUSTOM_PRESET_AUTO = "Auto" | ||||||||||||||
CUSTOM_PRESET_STOP = "Stop" | ||||||||||||||
|
||||||||||||||
COMMAND_REFRESH_COMFORT_HEATING_TARGET_TEMPERATURE = ( | ||||||||||||||
"refreshComfortHeatingTargetTemperature" | ||||||||||||||
) | ||||||||||||||
COMMAND_REFRESH_DEROGATION_REMAINING_TIME = "refreshDerogationRemainingTime" | ||||||||||||||
COMMAND_REFRESH_ECO_HEATING_TARGET_TEMPERATURE = "refreshEcoHeatingTargetTemperature" | ||||||||||||||
COMMAND_REFRESH_PASS_APC_HEATING_MODE = "refreshPassAPCHeatingMode" | ||||||||||||||
COMMAND_REFRESH_PASS_APC_HEATING_PROFILE = "refreshPassAPCHeatingProfile" | ||||||||||||||
COMMAND_REFRESH_TARGET_TEMPERATURE = "refreshTargetTemperature" | ||||||||||||||
COMMAND_SET_COMFORT_HEATING_TARGET_TEMPERATURE = "setComfortHeatingTargetTemperature" | ||||||||||||||
COMMAND_SET_DEROGATION_ON_OFF_STATE = "setDerogationOnOffState" | ||||||||||||||
COMMAND_SET_DEROGATED_TARGET_TEMPERATURE = "setDerogatedTargetTemperature" | ||||||||||||||
COMMAND_SET_DEROGATION_TIME = "setDerogationTime" | ||||||||||||||
COMMAND_SET_ECO_HEATING_TARGET_TEMPERATURE = "setEcoHeatingTargetTemperature" | ||||||||||||||
COMMAND_SET_OPERATING_MODE = "setOperatingMode" | ||||||||||||||
COMMAND_SET_PASS_APC_HEATING_MODE = "setPassAPCHeatingMode" | ||||||||||||||
COMMAND_SET_TARGET_TEMPERATURE = "setTargetTemperature" | ||||||||||||||
|
||||||||||||||
CORE_COMFORT_HEATING_TARGET_TEMPERATURE_STATE = ( | ||||||||||||||
"core:ComfortHeatingTargetTemperatureState" | ||||||||||||||
) | ||||||||||||||
CORE_DEROGATED_TARGET_TEMPERATURE_STATE = "core:DerogatedTargetTemperatureState" | ||||||||||||||
CORE_DEROGATION_ON_OFF_STATE = "core:DerogationOnOffState" | ||||||||||||||
CORE_ECO_HEATING_TARGET_TEMPERATURE_STATE = "core:EcoHeatingTargetTemperatureState" | ||||||||||||||
CORE_HEATING_ON_OFF_STATE = "core:HeatingOnOffState" | ||||||||||||||
CORE_TARGET_TEMPERATURE_STATE = "core:TargetTemperatureState" | ||||||||||||||
|
||||||||||||||
IO_DEROGATION_REMAINING_TIME_STATE = "io:DerogationRemainingTimeState" | ||||||||||||||
IO_PASS_APC_HEATING_MODE_STATE = "io:PassAPCHeatingModeState" | ||||||||||||||
IO_PASS_APC_HEATING_PROFILE_STATE = "io:PassAPCHeatingProfileState" | ||||||||||||||
IO_TARGET_HEATING_LEVEL_STATE = "io:TargetHeatingLevelState" | ||||||||||||||
|
||||||||||||||
PASS_APC_HEATING_MODE_STATE_ABSENCE = "absence" | ||||||||||||||
PASS_APC_HEATING_MODE_STATE_COMFORT = "comfort" | ||||||||||||||
PASS_APC_HEATING_MODE_STATE_DEROGATION = "derogation" | ||||||||||||||
PASS_APC_HEATING_MODE_STATE_INTERNAL_SCHEDULING = "internalScheduling" | ||||||||||||||
PASS_APC_HEATING_MODE_STATE_STOP = "stop" | ||||||||||||||
PASS_APC_HEATING_PROFILE_STATE_ABSENCE = "absence" | ||||||||||||||
PASS_APC_HEATING_PROFILE_STATE_COMFORT = "comfort" | ||||||||||||||
PASS_APC_HEATING_PROFILE_STATE_DEROGATION = "derogation" | ||||||||||||||
PASS_APC_HEATING_PROFILE_STATE_ECO = "eco" | ||||||||||||||
PASS_APC_HEATING_PROFILE_STATE_INTERNAL_SCHEDULING = "internalScheduling" | ||||||||||||||
PASS_APC_HEATING_PROFILE_STATE_STOP = "stop" | ||||||||||||||
|
||||||||||||||
MAP_PRESET_MODES = { | ||||||||||||||
PASS_APC_HEATING_PROFILE_STATE_ECO: PRESET_ECO, | ||||||||||||||
PASS_APC_HEATING_PROFILE_STATE_COMFORT: PRESET_COMFORT, | ||||||||||||||
PASS_APC_HEATING_PROFILE_STATE_INTERNAL_SCHEDULING: CUSTOM_PRESET_AUTO, | ||||||||||||||
PASS_APC_HEATING_PROFILE_STATE_DEROGATION: CUSTOM_PRESET_DEROGATION, | ||||||||||||||
PASS_APC_HEATING_PROFILE_STATE_STOP: CUSTOM_PRESET_STOP, | ||||||||||||||
PASS_APC_HEATING_PROFILE_STATE_ABSENCE: PRESET_AWAY, | ||||||||||||||
} | ||||||||||||||
MAP_REVERSE_PRESET_MODES = {v: k for k, v in MAP_PRESET_MODES.items()} | ||||||||||||||
|
||||||||||||||
|
||||||||||||||
class AtlanticPassAPCHeatingZone(OverkizEntity, ClimateEntity): | ||||||||||||||
"""Representation of Atlantic Pass APC Heating and Cooling Zone.""" | ||||||||||||||
|
||||||||||||||
_attr_hvac_modes = [HVAC_MODE_OFF, HVAC_MODE_HEAT, HVAC_MODE_AUTO] | ||||||||||||||
_attr_max_temp = 30 | ||||||||||||||
_attr_min_temp = 5 | ||||||||||||||
Comment on lines
+89
to
+90
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These values are not exposed by Atlantic? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not in this device (device number 7) the navilink sensor (device number 8) have 2 attributes (from 5 to 30) :
tahomalink allows to set a temperature between 7 and 35 ... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤡 And what happens if you set 35? It's applied? |
||||||||||||||
_attr_supported_features = SUPPORT_PRESET_MODE | SUPPORT_TARGET_TEMPERATURE | ||||||||||||||
_attr_temperature_unit = TEMP_CELSIUS | ||||||||||||||
|
||||||||||||||
def __init__(self, device_url: str, coordinator: OverkizDataUpdateCoordinator): | ||||||||||||||
"""Init method.""" | ||||||||||||||
super().__init__(device_url, coordinator) | ||||||||||||||
self.temperature_device = self.executor.linked_device(8) | ||||||||||||||
|
||||||||||||||
@property | ||||||||||||||
def preset_modes(self) -> Optional[List[str]]: | ||||||||||||||
"""Return preset mode list.""" | ||||||||||||||
|
||||||||||||||
if ( | ||||||||||||||
self.executor.select_state(IO_PASS_APC_HEATING_PROFILE_STATE) | ||||||||||||||
== PASS_APC_HEATING_PROFILE_STATE_DEROGATION | ||||||||||||||
): | ||||||||||||||
return [ | ||||||||||||||
PRESET_COMFORT, | ||||||||||||||
PRESET_ECO, | ||||||||||||||
CUSTOM_PRESET_AUTO, | ||||||||||||||
CUSTOM_PRESET_DEROGATION, | ||||||||||||||
CUSTOM_PRESET_STOP, | ||||||||||||||
PRESET_AWAY, | ||||||||||||||
] | ||||||||||||||
|
||||||||||||||
return [ | ||||||||||||||
PRESET_COMFORT, | ||||||||||||||
PRESET_ECO, | ||||||||||||||
CUSTOM_PRESET_AUTO, | ||||||||||||||
CUSTOM_PRESET_STOP, | ||||||||||||||
PRESET_AWAY, | ||||||||||||||
] | ||||||||||||||
jgarec marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
|
||||||||||||||
@property | ||||||||||||||
def preset_mode(self) -> Optional[str]: | ||||||||||||||
"""Return the current preset mode, e.g., home, away, temp.""" | ||||||||||||||
|
||||||||||||||
if ( | ||||||||||||||
self.executor.select_state(IO_PASS_APC_HEATING_MODE_STATE) | ||||||||||||||
== PASS_APC_HEATING_MODE_STATE_ABSENCE | ||||||||||||||
): | ||||||||||||||
return PRESET_AWAY | ||||||||||||||
|
||||||||||||||
if ( | ||||||||||||||
self.executor.select_state(IO_PASS_APC_HEATING_PROFILE_STATE) | ||||||||||||||
== PASS_APC_HEATING_PROFILE_STATE_DEROGATION | ||||||||||||||
): | ||||||||||||||
return CUSTOM_PRESET_DEROGATION | ||||||||||||||
|
||||||||||||||
if ( | ||||||||||||||
self.executor.select_state(IO_PASS_APC_HEATING_MODE_STATE) | ||||||||||||||
== PASS_APC_HEATING_MODE_STATE_INTERNAL_SCHEDULING | ||||||||||||||
): | ||||||||||||||
return MAP_PRESET_MODES[ | ||||||||||||||
self.executor.select_state(IO_PASS_APC_HEATING_PROFILE_STATE) | ||||||||||||||
] | ||||||||||||||
|
||||||||||||||
return MAP_PRESET_MODES[ | ||||||||||||||
self.executor.select_state(IO_PASS_APC_HEATING_MODE_STATE) | ||||||||||||||
] | ||||||||||||||
|
||||||||||||||
async def async_set_preset_mode(self, preset_mode: str) -> None: | ||||||||||||||
"""Set new preset mode.""" | ||||||||||||||
|
||||||||||||||
if self.preset_mode == CUSTOM_PRESET_DEROGATION: | ||||||||||||||
# revert derogation | ||||||||||||||
await self.executor.async_execute_command( | ||||||||||||||
COMMAND_SET_DEROGATION_ON_OFF_STATE, "off" | ||||||||||||||
) | ||||||||||||||
await self.executor.async_execute_command( | ||||||||||||||
COMMAND_SET_PASS_APC_HEATING_MODE, MAP_REVERSE_PRESET_MODES[preset_mode] | ||||||||||||||
) | ||||||||||||||
await self.refresh_values() | ||||||||||||||
|
||||||||||||||
@property | ||||||||||||||
def current_temperature(self) -> Optional[float]: | ||||||||||||||
"""Return the current temperature.""" | ||||||||||||||
return float( | ||||||||||||||
self.temperature_device.states.get(OverkizState.CORE_TEMPERATURE).value | ||||||||||||||
) | ||||||||||||||
|
||||||||||||||
@property | ||||||||||||||
def hvac_mode(self) -> str: | ||||||||||||||
"""Return hvac operation.""" | ||||||||||||||
|
||||||||||||||
if ( | ||||||||||||||
self.executor.select_state(IO_PASS_APC_HEATING_MODE_STATE) | ||||||||||||||
== PASS_APC_HEATING_MODE_STATE_STOP | ||||||||||||||
): | ||||||||||||||
return HVAC_MODE_OFF | ||||||||||||||
|
||||||||||||||
if self.executor.select_state(IO_PASS_APC_HEATING_MODE_STATE) in [ | ||||||||||||||
PASS_APC_HEATING_MODE_STATE_INTERNAL_SCHEDULING, | ||||||||||||||
PASS_APC_HEATING_MODE_STATE_ABSENCE, | ||||||||||||||
]: | ||||||||||||||
return HVAC_MODE_AUTO | ||||||||||||||
|
||||||||||||||
return HVAC_MODE_HEAT | ||||||||||||||
jgarec marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
|
||||||||||||||
async def async_set_hvac_mode(self, hvac_mode: str) -> None: | ||||||||||||||
"""Set new target hvac mode.""" | ||||||||||||||
|
||||||||||||||
if hvac_mode == HVAC_MODE_OFF: | ||||||||||||||
await self.executor.async_execute_command( | ||||||||||||||
COMMAND_SET_PASS_APC_HEATING_MODE, PASS_APC_HEATING_MODE_STATE_STOP | ||||||||||||||
) | ||||||||||||||
else: | ||||||||||||||
if self.hvac_mode == HVAC_MODE_OFF: | ||||||||||||||
tetienne marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
await self.executor.async_execute_command( | ||||||||||||||
COMMAND_SET_PASS_APC_HEATING_MODE, "on" | ||||||||||||||
) | ||||||||||||||
if hvac_mode == HVAC_MODE_AUTO: | ||||||||||||||
await self.executor.async_execute_command( | ||||||||||||||
COMMAND_SET_PASS_APC_HEATING_MODE, | ||||||||||||||
PASS_APC_HEATING_MODE_STATE_INTERNAL_SCHEDULING, | ||||||||||||||
) | ||||||||||||||
elif hvac_mode == HVAC_MODE_HEAT: | ||||||||||||||
await self.executor.async_execute_command( | ||||||||||||||
COMMAND_SET_PASS_APC_HEATING_MODE, | ||||||||||||||
PASS_APC_HEATING_MODE_STATE_COMFORT, | ||||||||||||||
) | ||||||||||||||
self.refresh_values() | ||||||||||||||
|
||||||||||||||
@property | ||||||||||||||
def target_temperature(self) -> None: | ||||||||||||||
"""Return the temperature.""" | ||||||||||||||
|
||||||||||||||
if self.preset_mode == PRESET_COMFORT: | ||||||||||||||
return self.executor.select_state( | ||||||||||||||
CORE_COMFORT_HEATING_TARGET_TEMPERATURE_STATE | ||||||||||||||
) | ||||||||||||||
if self.preset_mode == PRESET_ECO: | ||||||||||||||
return self.executor.select_state(CORE_ECO_HEATING_TARGET_TEMPERATURE_STATE) | ||||||||||||||
if self.preset_mode == CUSTOM_PRESET_DEROGATION: | ||||||||||||||
return self.executor.select_state(CORE_DEROGATED_TARGET_TEMPERATURE_STATE) | ||||||||||||||
|
||||||||||||||
return self.executor.select_state(CORE_TARGET_TEMPERATURE_STATE) | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here also you can ease the code with a dict. |
||||||||||||||
|
||||||||||||||
async def async_set_temperature(self, **kwargs) -> None: | ||||||||||||||
"""Set new temperature.""" | ||||||||||||||
temperature = kwargs.get(ATTR_TEMPERATURE) | ||||||||||||||
jgarec marked this conversation as resolved.
Show resolved
Hide resolved
jgarec marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
|
||||||||||||||
if self.hvac_mode == HVAC_MODE_AUTO: | ||||||||||||||
await self.executor.async_execute_command( | ||||||||||||||
COMMAND_SET_DEROGATION_ON_OFF_STATE, "on" | ||||||||||||||
) | ||||||||||||||
Comment on lines
+223
to
+225
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Would be great if you could use our enums here (and in all other executions). See https://github.com/home-assistant/core/blob/dev/homeassistant/components/overkiz/climate_entities/atlantic_electrical_heater.py. However, many of these enums are probably missing and we need to add them to PyOverkiz. |
||||||||||||||
await self.executor.async_execute_command(COMMAND_SET_DEROGATION_TIME, 24) | ||||||||||||||
await self.executor.async_execute_command( | ||||||||||||||
COMMAND_SET_DEROGATED_TARGET_TEMPERATURE, temperature | ||||||||||||||
) | ||||||||||||||
else: | ||||||||||||||
if self.preset_mode == "comfort": | ||||||||||||||
jgarec marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
await self.executor.async_execute_command( | ||||||||||||||
COMMAND_SET_COMFORT_HEATING_TARGET_TEMPERATURE, temperature | ||||||||||||||
) | ||||||||||||||
elif self.preset_mode == "eco": | ||||||||||||||
await self.executor.async_execute_command( | ||||||||||||||
COMMAND_SET_ECO_HEATING_TARGET_TEMPERATURE, temperature | ||||||||||||||
) | ||||||||||||||
|
||||||||||||||
await self.refresh_values() | ||||||||||||||
|
||||||||||||||
async def refresh_values(self) -> None: | ||||||||||||||
"""Refresh some values not always updated.""" | ||||||||||||||
|
||||||||||||||
await self.executor.async_execute_command( | ||||||||||||||
COMMAND_REFRESH_PASS_APC_HEATING_PROFILE | ||||||||||||||
) | ||||||||||||||
await self.executor.async_execute_command(COMMAND_REFRESH_PASS_APC_HEATING_MODE) | ||||||||||||||
await self.executor.async_execute_command(COMMAND_REFRESH_TARGET_TEMPERATURE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add all these states and commands to https://github.com/iMicknl/python-overkiz-api/tree/main/pyoverkiz/enums ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should i also add commands / states not used in this class ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only add the ones you need