Skip to content

Commit

Permalink
Calculate offset_calibration as room_temp - local_temp
Browse files Browse the repository at this point in the history
Fix hvac_action calculation
  • Loading branch information
Jean-Marc Collin committed Nov 19, 2024
1 parent 5b64a8f commit 9102b09
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 15 deletions.
2 changes: 1 addition & 1 deletion custom_components/versatile_thermostat/base_thermostat.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ def post_init(self, config_entry: ConfigData):
entry_infos.get(CONF_WINDOW_ACTION) or CONF_WINDOW_TURN_OFF
)

self._max_on_percent = api._max_on_percent
self._max_on_percent = api.max_on_percent

_LOGGER.debug(
"%s - Creation of a new VersatileThermostat entity: unique_id=%s",
Expand Down
4 changes: 2 additions & 2 deletions custom_components/versatile_thermostat/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,9 +464,9 @@ class RegulationParamVeryStrong:
kp: float = 0.6
ki: float = 0.1
k_ext: float = 0.2
offset_max: float = 4
offset_max: float = 8
stabilization_threshold: float = 0.1
accumulated_error_threshold: float = 30
accumulated_error_threshold: float = 80


class EventType(Enum):
Expand Down
13 changes: 8 additions & 5 deletions custom_components/versatile_thermostat/thermostat_climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,13 @@ def is_over_climate(self) -> bool:
"""True if the Thermostat is over_climate"""
return True

@property
def hvac_action(self) -> HVACAction | None:
"""Returns the current hvac_action by checking all hvac_action of the underlyings"""

def calculate_hvac_action(self, under_list: list) -> HVACAction | None:
"""Calculate an hvac action based on the hvac_action of the list in argument"""
# if one not IDLE or OFF -> return it
# else if one IDLE -> IDLE
# else OFF
one_idle = False
for under in self._underlyings:
for under in under_list:
if (action := under.hvac_action) not in [
HVACAction.IDLE,
HVACAction.OFF,
Expand All @@ -171,6 +169,11 @@ def hvac_action(self) -> HVACAction | None:
return HVACAction.IDLE
return HVACAction.OFF

@property
def hvac_action(self) -> HVACAction | None:
"""Returns the current hvac_action by checking all hvac_action of the underlyings"""
return self.calculate_hvac_action(self._underlyings)

@overrides
async def _async_internal_set_temperature(self, temperature: float):
"""Set the target temperature and the target temperature of underlying climate if any"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from datetime import datetime

from homeassistant.core import HomeAssistant
from homeassistant.components.climate import HVACMode
from homeassistant.components.climate import HVACMode, HVACAction

from .underlyings import UnderlyingSonoffTRVZB

Expand Down Expand Up @@ -96,6 +96,7 @@ def post_init(self, config_entry: ConfigData):
offset_calibration_entity_id=offset,
opening_degree_entity_id=opening,
closing_degree_entity_id=closing,
climate_underlying=self._underlyings[idx],
)
self._underlyings_sonoff_trvzb.append(under)

Expand Down Expand Up @@ -240,3 +241,9 @@ def valve_open_percent(self) -> int:
return 0
else:
return self._valve_open_percent

@property
def hvac_action(self) -> HVACAction | None:
"""Returns the current hvac_action by checking all hvac_action of the _underlyings_sonoff_trvzb"""

return self.calculate_hvac_action(self._underlyings_sonoff_trvzb)
33 changes: 28 additions & 5 deletions custom_components/versatile_thermostat/underlyings.py
Original file line number Diff line number Diff line change
Expand Up @@ -1030,15 +1030,18 @@ def __init__(
offset_calibration_entity_id: str,
opening_degree_entity_id: str,
closing_degree_entity_id: str,
climate_underlying: UnderlyingClimate,
) -> None:
"""Initialize the underlying Sonoff TRV"""
super().__init__(hass, thermostat, opening_degree_entity_id)
self._offset_calibration_entity_id = offset_calibration_entity_id
self._opening_degree_entity_id = opening_degree_entity_id
self._closing_degree_entity_id = closing_degree_entity_id
self._climate_underlying = climate_underlying
self._is_min_max_initialized = False
self._max_opening_degree = None
self._min_offset_calibration = None
self._max_offset_calibration = None

async def send_percent_open(self):
"""Send the percent open to the underlying valve"""
Expand All @@ -1052,6 +1055,9 @@ async def send_percent_open(self):
self._min_offset_calibration = self._hass.states.get(
self._offset_calibration_entity_id
).attributes.get("min")
self._max_offset_calibration = self._hass.states.get(
self._offset_calibration_entity_id
).attributes.get("max")

self._is_min_max_initialized = (
self._max_opening_degree is not None
Expand All @@ -1067,15 +1073,32 @@ async def send_percent_open(self):
# Send opening_degree
await super().send_percent_open()

# Send closing_degree. TODO 100 hard-coded or take the max of the _closing_degree_entity_id ?
# Send closing_degree.
await self._send_value_to_number(
self._closing_degree_entity_id,
self._max_opening_degree - self._percent_open,
closing_degree := self._max_opening_degree - self._percent_open,
)

# send offset_calibration to the min value
await self._send_value_to_number(
self._offset_calibration_entity_id, self._min_offset_calibration
# send offset_calibration to the difference between target temp and local temp
offset = 0
if (
local_temp := self._climate_underlying.underlying_current_temperature
) is not None and (
room_temp := self._thermostat.current_temperature
) is not None:
offset = min(
self._max_offset_calibration,
max(self._min_offset_calibration, room_temp - local_temp),
)

await self._send_value_to_number(self._offset_calibration_entity_id, offset)

_LOGGER.debug(
"%s - SonoffTRVZB - I have sent offset_calibration=%s opening_degree=%s closing_degree=%s",
self,
offset,
self._percent_open,
closing_degree,
)

@property
Expand Down
8 changes: 7 additions & 1 deletion custom_components/versatile_thermostat/vtherm_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ async def init_vtherm_links(self, entry_id=None):
# ):
# await entity.init_presets(self.find_central_configuration())

# A little hack to test if the climate is a VTherm. Cannot use isinstance due to circular dependency of BaseThermostat
# A little hack to test if the climate is a VTherm. Cannot use isinstance
# due to circular dependency of BaseThermostat
if (
entity.device_info
and entity.device_info.get("model", None) == DOMAIN
Expand Down Expand Up @@ -249,6 +250,11 @@ def safety_mode(self):
"""Get the safety_mode params"""
return self._safety_mode

@property
def max_on_percent(self):
"""Get the max_open_percent params"""
return self._max_on_percent

@property
def central_boiler_entity(self):
"""Get the central boiler binary_sensor entity"""
Expand Down

0 comments on commit 9102b09

Please sign in to comment.