Esphome climate features (#28786)

* add esphome climate fan

* adds back compatibility support

* fixes, add swing mode

* revert client config

* sort import

* rebase
This commit is contained in:
Guillermo Ruffino 2019-11-17 19:14:19 -03:00 committed by Otto Winter
parent 101ab5c3fa
commit 0c48b8ec52
4 changed files with 97 additions and 5 deletions

View File

@ -2,7 +2,13 @@
import logging import logging
from typing import List, Optional from typing import List, Optional
from aioesphomeapi import ClimateInfo, ClimateMode, ClimateState from aioesphomeapi import (
ClimateInfo,
ClimateMode,
ClimateState,
ClimateFanMode,
ClimateSwingMode,
)
from homeassistant.components.climate import ClimateDevice from homeassistant.components.climate import ClimateDevice
from homeassistant.components.climate.const import ( from homeassistant.components.climate.const import (
@ -12,12 +18,29 @@ from homeassistant.components.climate.const import (
HVAC_MODE_HEAT_COOL, HVAC_MODE_HEAT_COOL,
HVAC_MODE_COOL, HVAC_MODE_COOL,
HVAC_MODE_HEAT, HVAC_MODE_HEAT,
HVAC_MODE_FAN_ONLY,
HVAC_MODE_DRY,
HVAC_MODE_OFF,
SUPPORT_TARGET_TEMPERATURE, SUPPORT_TARGET_TEMPERATURE,
SUPPORT_PRESET_MODE, SUPPORT_PRESET_MODE,
SUPPORT_TARGET_TEMPERATURE_RANGE, SUPPORT_TARGET_TEMPERATURE_RANGE,
SUPPORT_FAN_MODE,
SUPPORT_SWING_MODE,
PRESET_AWAY, PRESET_AWAY,
HVAC_MODE_OFF,
PRESET_HOME, PRESET_HOME,
FAN_ON,
FAN_OFF,
FAN_AUTO,
FAN_LOW,
FAN_MEDIUM,
FAN_HIGH,
FAN_MIDDLE,
FAN_FOCUS,
FAN_DIFFUSE,
SWING_OFF,
SWING_BOTH,
SWING_VERTICAL,
SWING_HORIZONTAL,
) )
from homeassistant.const import ( from homeassistant.const import (
ATTR_TEMPERATURE, ATTR_TEMPERATURE,
@ -57,6 +80,33 @@ def _climate_modes():
ClimateMode.AUTO: HVAC_MODE_HEAT_COOL, ClimateMode.AUTO: HVAC_MODE_HEAT_COOL,
ClimateMode.COOL: HVAC_MODE_COOL, ClimateMode.COOL: HVAC_MODE_COOL,
ClimateMode.HEAT: HVAC_MODE_HEAT, ClimateMode.HEAT: HVAC_MODE_HEAT,
ClimateMode.FAN_ONLY: HVAC_MODE_FAN_ONLY,
ClimateMode.DRY: HVAC_MODE_DRY,
}
@esphome_map_enum
def _fan_modes():
return {
ClimateFanMode.ON: FAN_ON,
ClimateFanMode.OFF: FAN_OFF,
ClimateFanMode.AUTO: FAN_AUTO,
ClimateFanMode.LOW: FAN_LOW,
ClimateFanMode.MEDIUM: FAN_MEDIUM,
ClimateFanMode.HIGH: FAN_HIGH,
ClimateFanMode.MIDDLE: FAN_MIDDLE,
ClimateFanMode.FOCUS: FAN_FOCUS,
ClimateFanMode.DIFFUSE: FAN_DIFFUSE,
}
@esphome_map_enum
def _swing_modes():
return {
ClimateSwingMode.OFF: SWING_OFF,
ClimateSwingMode.BOTH: SWING_BOTH,
ClimateSwingMode.VERTICAL: SWING_VERTICAL,
ClimateSwingMode.HORIZONTAL: SWING_HORIZONTAL,
} }
@ -94,11 +144,27 @@ class EsphomeClimateDevice(EsphomeEntity, ClimateDevice):
for mode in self._static_info.supported_modes for mode in self._static_info.supported_modes
] ]
@property
def fan_modes(self):
"""Return the list of available fan modes."""
return [
_fan_modes.from_esphome(mode)
for mode in self._static_info.supported_fan_modes
]
@property @property
def preset_modes(self): def preset_modes(self):
"""Return preset modes.""" """Return preset modes."""
return [PRESET_AWAY, PRESET_HOME] if self._static_info.supports_away else [] return [PRESET_AWAY, PRESET_HOME] if self._static_info.supports_away else []
@property
def swing_modes(self):
"""Return the list of available swing modes."""
return [
_swing_modes.from_esphome(mode)
for mode in self._static_info.supported_swing_modes
]
@property @property
def target_temperature_step(self) -> float: def target_temperature_step(self) -> float:
"""Return the supported step of target temperature.""" """Return the supported step of target temperature."""
@ -125,6 +191,10 @@ class EsphomeClimateDevice(EsphomeEntity, ClimateDevice):
features |= SUPPORT_TARGET_TEMPERATURE features |= SUPPORT_TARGET_TEMPERATURE
if self._static_info.supports_away: if self._static_info.supports_away:
features |= SUPPORT_PRESET_MODE features |= SUPPORT_PRESET_MODE
if self._static_info.supported_fan_modes:
features |= SUPPORT_FAN_MODE
if self._static_info.supported_swing_modes:
features |= SUPPORT_SWING_MODE
return features return features
# https://github.com/PyCQA/pylint/issues/3150 for all @esphome_state_property # https://github.com/PyCQA/pylint/issues/3150 for all @esphome_state_property
@ -135,11 +205,21 @@ class EsphomeClimateDevice(EsphomeEntity, ClimateDevice):
"""Return current operation ie. heat, cool, idle.""" """Return current operation ie. heat, cool, idle."""
return _climate_modes.from_esphome(self._state.mode) return _climate_modes.from_esphome(self._state.mode)
@esphome_state_property
def fan_mode(self):
"""Return current fan setting."""
return _fan_modes.from_esphome(self._state.fan_mode)
@esphome_state_property @esphome_state_property
def preset_mode(self): def preset_mode(self):
"""Return current preset mode.""" """Return current preset mode."""
return PRESET_AWAY if self._state.away else PRESET_HOME return PRESET_AWAY if self._state.away else PRESET_HOME
@esphome_state_property
def swing_mode(self):
"""Return current swing mode."""
return _swing_modes.from_esphome(self._state.swing_mode)
@esphome_state_property @esphome_state_property
def current_temperature(self) -> Optional[float]: def current_temperature(self) -> Optional[float]:
"""Return the current temperature.""" """Return the current temperature."""
@ -183,3 +263,15 @@ class EsphomeClimateDevice(EsphomeEntity, ClimateDevice):
"""Set preset mode.""" """Set preset mode."""
away = preset_mode == PRESET_AWAY away = preset_mode == PRESET_AWAY
await self._client.climate_command(key=self._static_info.key, away=away) await self._client.climate_command(key=self._static_info.key, away=away)
async def async_set_fan_mode(self, fan_mode: str) -> None:
"""Set new fan mode."""
await self._client.climate_command(
key=self._static_info.key, fan_mode=_fan_modes.from_hass(fan_mode)
)
async def async_set_swing_mode(self, swing_mode: str) -> None:
"""Set new swing mode."""
await self._client.climate_command(
key=self._static_info.key, swing_mode=_swing_modes.from_hass(swing_mode)
)

View File

@ -4,7 +4,7 @@
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/esphome", "documentation": "https://www.home-assistant.io/integrations/esphome",
"requirements": [ "requirements": [
"aioesphomeapi==2.5.0" "aioesphomeapi==2.6.0"
], ],
"dependencies": [], "dependencies": [],
"zeroconf": ["_esphomelib._tcp.local."], "zeroconf": ["_esphomelib._tcp.local."],

View File

@ -142,7 +142,7 @@ aiobotocore==0.10.4
aiodns==2.0.0 aiodns==2.0.0
# homeassistant.components.esphome # homeassistant.components.esphome
aioesphomeapi==2.5.0 aioesphomeapi==2.6.0
# homeassistant.components.freebox # homeassistant.components.freebox
aiofreepybox==0.0.8 aiofreepybox==0.0.8

View File

@ -50,7 +50,7 @@ aioautomatic==0.6.5
aiobotocore==0.10.4 aiobotocore==0.10.4
# homeassistant.components.esphome # homeassistant.components.esphome
aioesphomeapi==2.5.0 aioesphomeapi==2.6.0
# homeassistant.components.emulated_hue # homeassistant.components.emulated_hue
# homeassistant.components.http # homeassistant.components.http