mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
Add support for SmartTub heat modes (#46876)
This commit is contained in:
parent
0e44d61225
commit
d32dbc4cdd
@ -6,6 +6,9 @@ from homeassistant.components.climate.const import (
|
|||||||
CURRENT_HVAC_HEAT,
|
CURRENT_HVAC_HEAT,
|
||||||
CURRENT_HVAC_IDLE,
|
CURRENT_HVAC_IDLE,
|
||||||
HVAC_MODE_HEAT,
|
HVAC_MODE_HEAT,
|
||||||
|
PRESET_ECO,
|
||||||
|
PRESET_NONE,
|
||||||
|
SUPPORT_PRESET_MODE,
|
||||||
SUPPORT_TARGET_TEMPERATURE,
|
SUPPORT_TARGET_TEMPERATURE,
|
||||||
)
|
)
|
||||||
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
|
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
|
||||||
@ -16,6 +19,8 @@ from .entity import SmartTubEntity
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
PRESET_DAY = "day"
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, entry, async_add_entities):
|
async def async_setup_entry(hass, entry, async_add_entities):
|
||||||
"""Set up climate entity for the thermostat in the tub."""
|
"""Set up climate entity for the thermostat in the tub."""
|
||||||
@ -32,6 +37,19 @@ async def async_setup_entry(hass, entry, async_add_entities):
|
|||||||
class SmartTubThermostat(SmartTubEntity, ClimateEntity):
|
class SmartTubThermostat(SmartTubEntity, ClimateEntity):
|
||||||
"""The target water temperature for the spa."""
|
"""The target water temperature for the spa."""
|
||||||
|
|
||||||
|
PRESET_MODES = {
|
||||||
|
"AUTO": PRESET_NONE,
|
||||||
|
"ECO": PRESET_ECO,
|
||||||
|
"DAY": PRESET_DAY,
|
||||||
|
}
|
||||||
|
|
||||||
|
HEAT_MODES = {v: k for k, v in PRESET_MODES.items()}
|
||||||
|
|
||||||
|
HVAC_ACTIONS = {
|
||||||
|
"OFF": CURRENT_HVAC_IDLE,
|
||||||
|
"ON": CURRENT_HVAC_HEAT,
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, coordinator, spa):
|
def __init__(self, coordinator, spa):
|
||||||
"""Initialize the entity."""
|
"""Initialize the entity."""
|
||||||
super().__init__(coordinator, spa, "thermostat")
|
super().__init__(coordinator, spa, "thermostat")
|
||||||
@ -44,12 +62,7 @@ class SmartTubThermostat(SmartTubEntity, ClimateEntity):
|
|||||||
@property
|
@property
|
||||||
def hvac_action(self):
|
def hvac_action(self):
|
||||||
"""Return the current running hvac operation."""
|
"""Return the current running hvac operation."""
|
||||||
heater_status = self.get_spa_status("heater")
|
return self.HVAC_ACTIONS.get(self.get_spa_status("heater"))
|
||||||
if heater_status == "ON":
|
|
||||||
return CURRENT_HVAC_HEAT
|
|
||||||
if heater_status == "OFF":
|
|
||||||
return CURRENT_HVAC_IDLE
|
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hvac_modes(self):
|
def hvac_modes(self):
|
||||||
@ -92,7 +105,17 @@ class SmartTubThermostat(SmartTubEntity, ClimateEntity):
|
|||||||
|
|
||||||
Only target temperature is supported.
|
Only target temperature is supported.
|
||||||
"""
|
"""
|
||||||
return SUPPORT_TARGET_TEMPERATURE
|
return SUPPORT_PRESET_MODE | SUPPORT_TARGET_TEMPERATURE
|
||||||
|
|
||||||
|
@property
|
||||||
|
def preset_mode(self):
|
||||||
|
"""Return the current preset mode."""
|
||||||
|
return self.PRESET_MODES[self.get_spa_status("heatMode")]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def preset_modes(self):
|
||||||
|
"""Return the available preset modes."""
|
||||||
|
return list(self.PRESET_MODES.values())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_temperature(self):
|
def current_temperature(self):
|
||||||
@ -109,3 +132,9 @@ class SmartTubThermostat(SmartTubEntity, ClimateEntity):
|
|||||||
temperature = kwargs[ATTR_TEMPERATURE]
|
temperature = kwargs[ATTR_TEMPERATURE]
|
||||||
await self.spa.set_temperature(temperature)
|
await self.spa.set_temperature(temperature)
|
||||||
await self.coordinator.async_refresh()
|
await self.coordinator.async_refresh()
|
||||||
|
|
||||||
|
async def async_set_preset_mode(self, preset_mode: str):
|
||||||
|
"""Activate the specified preset mode."""
|
||||||
|
heat_mode = self.HEAT_MODES[preset_mode]
|
||||||
|
await self.spa.set_heat_mode(heat_mode)
|
||||||
|
await self.coordinator.async_refresh()
|
||||||
|
@ -46,6 +46,7 @@ def mock_spa():
|
|||||||
"setTemperature": 39,
|
"setTemperature": 39,
|
||||||
"water": {"temperature": 38},
|
"water": {"temperature": 38},
|
||||||
"heater": "ON",
|
"heater": "ON",
|
||||||
|
"heatMode": "AUTO",
|
||||||
"state": "NORMAL",
|
"state": "NORMAL",
|
||||||
"primaryFiltration": {
|
"primaryFiltration": {
|
||||||
"cycle": 1,
|
"cycle": 1,
|
||||||
|
@ -9,12 +9,18 @@ from homeassistant.components.climate.const import (
|
|||||||
ATTR_HVAC_MODES,
|
ATTR_HVAC_MODES,
|
||||||
ATTR_MAX_TEMP,
|
ATTR_MAX_TEMP,
|
||||||
ATTR_MIN_TEMP,
|
ATTR_MIN_TEMP,
|
||||||
|
ATTR_PRESET_MODE,
|
||||||
|
ATTR_PRESET_MODES,
|
||||||
CURRENT_HVAC_HEAT,
|
CURRENT_HVAC_HEAT,
|
||||||
CURRENT_HVAC_IDLE,
|
CURRENT_HVAC_IDLE,
|
||||||
DOMAIN as CLIMATE_DOMAIN,
|
DOMAIN as CLIMATE_DOMAIN,
|
||||||
HVAC_MODE_HEAT,
|
HVAC_MODE_HEAT,
|
||||||
|
PRESET_ECO,
|
||||||
|
PRESET_NONE,
|
||||||
SERVICE_SET_HVAC_MODE,
|
SERVICE_SET_HVAC_MODE,
|
||||||
|
SERVICE_SET_PRESET_MODE,
|
||||||
SERVICE_SET_TEMPERATURE,
|
SERVICE_SET_TEMPERATURE,
|
||||||
|
SUPPORT_PRESET_MODE,
|
||||||
SUPPORT_TARGET_TEMPERATURE,
|
SUPPORT_TARGET_TEMPERATURE,
|
||||||
)
|
)
|
||||||
from homeassistant.components.smarttub.const import DEFAULT_MAX_TEMP, DEFAULT_MIN_TEMP
|
from homeassistant.components.smarttub.const import DEFAULT_MAX_TEMP, DEFAULT_MIN_TEMP
|
||||||
@ -44,11 +50,15 @@ async def test_thermostat_update(spa, setup_entry, hass):
|
|||||||
|
|
||||||
assert set(state.attributes[ATTR_HVAC_MODES]) == {HVAC_MODE_HEAT}
|
assert set(state.attributes[ATTR_HVAC_MODES]) == {HVAC_MODE_HEAT}
|
||||||
assert state.state == HVAC_MODE_HEAT
|
assert state.state == HVAC_MODE_HEAT
|
||||||
assert state.attributes[ATTR_SUPPORTED_FEATURES] == SUPPORT_TARGET_TEMPERATURE
|
assert (
|
||||||
|
state.attributes[ATTR_SUPPORTED_FEATURES]
|
||||||
|
== SUPPORT_PRESET_MODE | SUPPORT_TARGET_TEMPERATURE
|
||||||
|
)
|
||||||
assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 38
|
assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 38
|
||||||
assert state.attributes[ATTR_TEMPERATURE] == 39
|
assert state.attributes[ATTR_TEMPERATURE] == 39
|
||||||
assert state.attributes[ATTR_MAX_TEMP] == DEFAULT_MAX_TEMP
|
assert state.attributes[ATTR_MAX_TEMP] == DEFAULT_MAX_TEMP
|
||||||
assert state.attributes[ATTR_MIN_TEMP] == DEFAULT_MIN_TEMP
|
assert state.attributes[ATTR_MIN_TEMP] == DEFAULT_MIN_TEMP
|
||||||
|
assert state.attributes[ATTR_PRESET_MODES] == ["none", "eco", "day"]
|
||||||
|
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
CLIMATE_DOMAIN,
|
CLIMATE_DOMAIN,
|
||||||
@ -66,6 +76,20 @@ async def test_thermostat_update(spa, setup_entry, hass):
|
|||||||
)
|
)
|
||||||
# does nothing
|
# does nothing
|
||||||
|
|
||||||
|
assert state.attributes.get(ATTR_PRESET_MODE) == PRESET_NONE
|
||||||
|
await hass.services.async_call(
|
||||||
|
CLIMATE_DOMAIN,
|
||||||
|
SERVICE_SET_PRESET_MODE,
|
||||||
|
{ATTR_ENTITY_ID: entity_id, ATTR_PRESET_MODE: PRESET_ECO},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
spa.set_heat_mode.assert_called_with("ECO")
|
||||||
|
|
||||||
|
spa.get_status.return_value["heatMode"] = "ECO"
|
||||||
|
await trigger_update(hass)
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state.attributes.get(ATTR_PRESET_MODE) == PRESET_ECO
|
||||||
|
|
||||||
spa.get_status.side_effect = smarttub.APIError
|
spa.get_status.side_effect = smarttub.APIError
|
||||||
await trigger_update(hass)
|
await trigger_update(hass)
|
||||||
# should not fail
|
# should not fail
|
||||||
|
Loading…
x
Reference in New Issue
Block a user