Improve temperature controls (#872)

This improves the temperature control features to allow implementing
climate platform support for homeassistant.

Also adds frostprotection module, which is also used to turn
the thermostat on and off.
This commit is contained in:
Teemu R
2024-05-02 15:05:26 +02:00
committed by GitHub
parent 28d41092e5
commit 9dcd8ec91b
6 changed files with 252 additions and 3 deletions

View File

@@ -2,6 +2,8 @@
from __future__ import annotations
import logging
from enum import Enum
from typing import TYPE_CHECKING
from ...feature import Feature
@@ -11,6 +13,19 @@ if TYPE_CHECKING:
from ..smartdevice import SmartDevice
_LOGGER = logging.getLogger(__name__)
class ThermostatState(Enum):
"""Thermostat state."""
Heating = "heating"
Calibrating = "progress_calibration"
Idle = "idle"
Off = "off"
Unknown = "unknown"
class TemperatureControl(SmartModule):
"""Implementation of temperature module."""
@@ -25,8 +40,10 @@ class TemperatureControl(SmartModule):
container=self,
attribute_getter="target_temperature",
attribute_setter="set_target_temperature",
range_getter="allowed_temperature_range",
icon="mdi:thermometer",
type=Feature.Type.Number,
category=Feature.Category.Primary,
)
)
# TODO: this might belong into its own module, temperature_correction?
@@ -40,6 +57,29 @@ class TemperatureControl(SmartModule):
minimum_value=-10,
maximum_value=10,
type=Feature.Type.Number,
category=Feature.Category.Config,
)
)
self._add_feature(
Feature(
device,
"State",
container=self,
attribute_getter="state",
attribute_setter="set_state",
category=Feature.Category.Primary,
type=Feature.Type.Switch,
)
)
self._add_feature(
Feature(
device,
"Mode",
container=self,
attribute_getter="mode",
category=Feature.Category.Primary,
)
)
@@ -48,6 +88,45 @@ class TemperatureControl(SmartModule):
# Target temperature is contained in the main device info response.
return {}
@property
def state(self) -> bool:
"""Return thermostat state."""
return self._device.sys_info["frost_protection_on"] is False
async def set_state(self, enabled: bool):
"""Set thermostat state."""
return await self.call("set_device_info", {"frost_protection_on": not enabled})
@property
def mode(self) -> ThermostatState:
"""Return thermostat state."""
# If frost protection is enabled, the thermostat is off.
if self._device.sys_info.get("frost_protection_on", False):
return ThermostatState.Off
states = self._device.sys_info["trv_states"]
# If the states is empty, the device is idling
if not states:
return ThermostatState.Idle
if len(states) > 1:
_LOGGER.warning(
"Got multiple states (%s), using the first one: %s", states, states[0]
)
state = states[0]
try:
return ThermostatState(state)
except: # noqa: E722
_LOGGER.warning("Got unknown state: %s", state)
return ThermostatState.Unknown
@property
def allowed_temperature_range(self) -> tuple[int, int]:
"""Return allowed temperature range."""
return self.minimum_target_temperature, self.maximum_target_temperature
@property
def minimum_target_temperature(self) -> int:
"""Minimum available target temperature."""
@@ -74,7 +153,12 @@ class TemperatureControl(SmartModule):
f"[{self.minimum_target_temperature},{self.maximum_target_temperature}]"
)
return await self.call("set_device_info", {"target_temp": target})
payload = {"target_temp": target}
# If the device has frost protection, we set it off to enable heating
if "frost_protection_on" in self._device.sys_info:
payload["frost_protection_on"] = False
return await self.call("set_device_info", payload)
@property
def temperature_offset(self) -> int: