From 284ae75343a6c11e1afb3bc0b6227689fc79409a Mon Sep 17 00:00:00 2001 From: Jack Simbach Date: Sat, 7 Aug 2021 14:17:57 -0400 Subject: [PATCH] - added multiple fan mode converters for generic climate entity - added the wac climate entity --- .../ge_home/entities/ac/ge_wac_climate.py | 87 +++++++++++++++++++ .../ge_home/entities/common/ge_climate.py | 19 +++- 2 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 custom_components/ge_home/entities/ac/ge_wac_climate.py diff --git a/custom_components/ge_home/entities/ac/ge_wac_climate.py b/custom_components/ge_home/entities/ac/ge_wac_climate.py new file mode 100644 index 0000000..dbb1258 --- /dev/null +++ b/custom_components/ge_home/entities/ac/ge_wac_climate.py @@ -0,0 +1,87 @@ +import logging +from typing import Any, List, Optional + +from homeassistant.components.climate.const import ( + HVAC_MODE_AUTO, + HVAC_MODE_COOL, + HVAC_MODE_FAN_ONLY, +) +from gehomesdk import ErdAcOperationMode, ErdAcFanSetting +from ...devices import ApplianceApi +from ..common import GeClimate, OptionsConverter + +_LOGGER = logging.getLogger(__name__) + +class WacHvacModeOptionsConverter(OptionsConverter): + @property + def options(self) -> List[str]: + return [HVAC_MODE_AUTO, HVAC_MODE_COOL, HVAC_MODE_FAN_ONLY] + def from_option_string(self, value: str) -> Any: + try: + return { + HVAC_MODE_AUTO: ErdAcOperationMode.ENERGY_SAVER, + HVAC_MODE_COOL: ErdAcOperationMode.COOL, + HVAC_MODE_FAN_ONLY: ErdAcOperationMode.FAN_ONLY + }.get(value) + except: + _LOGGER.warn(f"Could not set HVAC mode to {value.upper()}") + return ErdAcOperationMode.COOL + def to_option_string(self, value: Any) -> Optional[str]: + try: + return { + ErdAcOperationMode.ENERGY_SAVER: HVAC_MODE_AUTO, + ErdAcOperationMode.AUTO: HVAC_MODE_AUTO, + ErdAcOperationMode.COOL: HVAC_MODE_COOL, + ErdAcOperationMode.FAN_ONLY: HVAC_MODE_FAN_ONLY + }.get(value) + except: + _LOGGER.warn(f"Could not determine operation mode mapping for {value}") + return HVAC_MODE_COOL + +class WacFanModeOptionsConverter(OptionsConverter): + @property + def options(self) -> List[str]: + return [i.stringify() for i in [ErdAcFanSetting.AUTO, ErdAcFanSetting.LOW, ErdAcFanSetting.MED, ErdAcFanSetting.HIGH]] + def from_option_string(self, value: str) -> Any: + try: + return ErdAcFanSetting[value.upper().replace(" ","_")] + except: + _LOGGER.warn(f"Could not set fan mode to {value}") + return ErdAcFanSetting.AUTO + def to_option_string(self, value: Any) -> Optional[str]: + try: + return { + ErdAcFanSetting.AUTO: ErdAcFanSetting.AUTO, + ErdAcFanSetting.LOW: ErdAcFanSetting.LOW, + ErdAcFanSetting.LOW_AUTO: ErdAcFanSetting.AUTO, + ErdAcFanSetting.MED: ErdAcFanSetting.MED, + ErdAcFanSetting.MED_AUTO: ErdAcFanSetting.AUTO, + ErdAcFanSetting.HIGH: ErdAcFanSetting.HIGH, + ErdAcFanSetting.HIGH_AUTO: ErdAcFanSetting.HIGH + }.get(value).stringify() + except: + pass + return ErdAcFanSetting.AUTO.stringify() + +class WacFanOnlyFanModeOptionsConverter(OptionsConverter): + @property + def options(self) -> List[str]: + return [i.stringify() for i in [ErdAcFanSetting.LOW, ErdAcFanSetting.MED, ErdAcFanSetting.HIGH]] + def from_option_string(self, value: str) -> Any: + try: + return ErdAcFanSetting[value.upper().replace(" ","_")] + except: + _LOGGER.warn(f"Could not set fan mode to {value}") + return ErdAcFanSetting.LOW + def to_option_string(self, value: Any) -> Optional[str]: + try: + if value is not None: + return value.stringify() + except: + pass + return ErdAcFanSetting.LOW.stringify() + +class GeWacClimate(GeClimate): + """Class for Window AC units""" + def __init__(self, api: ApplianceApi): + super().__init__(api, WacHvacModeOptionsConverter(), WacFanModeOptionsConverter(), WacFanOnlyFanModeOptionsConverter()) diff --git a/custom_components/ge_home/entities/common/ge_climate.py b/custom_components/ge_home/entities/common/ge_climate.py index 30fdc4b..2280e8e 100644 --- a/custom_components/ge_home/entities/common/ge_climate.py +++ b/custom_components/ge_home/entities/common/ge_climate.py @@ -8,6 +8,7 @@ from homeassistant.const import ( TEMP_CELSIUS, ) from homeassistant.components.climate.const import ( + HVAC_MODE_FAN_ONLY, SUPPORT_TARGET_TEMPERATURE, SUPPORT_FAN_MODE, HVAC_MODE_OFF @@ -29,7 +30,8 @@ class GeClimate(GeEntity, ClimateEntity): self, api: ApplianceApi, hvac_mode_converter: OptionsConverter, - fan_mode_converter: OptionsConverter, + fan_mode_converter: OptionsConverter, + fan_only_fan_mode_converter: OptionsConverter = None, power_status_erd_code: ErdCodeType = ErdCode.AC_POWER_STATUS, current_temperature_erd_code: ErdCodeType = ErdCode.AC_AMBIENT_TEMPERATURE, target_temperature_erd_code: ErdCodeType = ErdCode.AC_TARGET_TEMPERATURE, @@ -40,6 +42,10 @@ class GeClimate(GeEntity, ClimateEntity): super().__init__(api) self._hvac_mode_converter = hvac_mode_converter self._fan_mode_converter = fan_mode_converter + self._fan_only_fan_mode_converter = (fan_only_fan_mode_converter + if fan_only_fan_mode_converter is not None + else fan_mode_converter + ) self._power_status_erd_code = api.appliance.translate_erd_code(power_status_erd_code) self._current_temperature_erd_code = api.appliance.translate_erd_code(current_temperature_erd_code) self._target_temperature_erd_code = api.appliance.translate_erd_code(target_temperature_erd_code) @@ -110,10 +116,14 @@ class GeClimate(GeEntity, ClimateEntity): @property def fan_mode(self): + if self.hvac_mode == HVAC_MODE_FAN_ONLY: + return self._fan_only_fan_mode_converter.to_option_string(self.appliance.get_erd_value(self.fan_mode_erd_code)) return self._fan_mode_converter.to_option_string(self.appliance.get_erd_value(self.fan_mode_erd_code)) @property def fan_modes(self) -> List[str]: + if self.hvac_mode == HVAC_MODE_FAN_ONLY: + return self._fan_only_fan_mode_converter.options return self._fan_mode_converter.options async def async_set_hvac_mode(self, hvac_mode: str) -> None: @@ -130,9 +140,14 @@ class GeClimate(GeEntity, ClimateEntity): async def async_set_fan_mode(self, fan_mode: str) -> None: _LOGGER.debug(f"Setting Fan mode from {self.fan_mode} to {fan_mode}") if fan_mode != self.fan_mode: + converter = (self._fan_only_fan_mode_converter + if self.hvac_mode == HVAC_MODE_FAN_ONLY + else self._fan_mode_converter + ) + await self.appliance.async_set_erd_value( self.fan_mode_erd_code, - self._fan_mode_converter.from_option_string(fan_mode) + converter.from_option_string(fan_mode) ) async def async_set_temperature(self, **kwargs) -> None: