Skip to content

Commit

Permalink
Merge branch 'master' into fix/duplicateInstanceOnUpdate
Browse files Browse the repository at this point in the history
  • Loading branch information
KartoffelToby authored Jan 7, 2024
2 parents f3c16fd + 8333bdb commit fd3f300
Show file tree
Hide file tree
Showing 12 changed files with 69 additions and 67 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ repos:
- id: pyupgrade
args: [--py39-plus]
- repo: https://github.com/psf/black
rev: 22.6.0
rev: 23.12.1
hooks:
- id: black
args:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[![Active installations](https://badge.t-haber.de/badge/better_thermostat?kill_cache=1)](https://github.com/KartoffelToby/better_thermostat/)
[![GitHub issues](https://img.shields.io/github/issues/KartoffelToby/better_thermostat?style=for-the-badge)](https://github.com/KartoffelToby/better_thermostat/issues)
[![Version - 1.4.1](https://img.shields.io/badge/Version-1.4.1-009688?style=for-the-badge)](https://github.com/KartoffelToby/better_thermostat/releases)
[![Version - 1.5.0](https://img.shields.io/badge/Version-1.5.0-009688?style=for-the-badge)](https://github.com/KartoffelToby/better_thermostat/releases)
[![Discord](https://img.shields.io/discord/925725316540923914.svg?style=for-the-badge)](https://discord.gg/9BUegWTG3K)
[![hacs_badge](https://img.shields.io/badge/HACS-Default-41BDF5.svg?style=for-the-badge)](https://github.com/hacs/integration)

Expand All @@ -11,7 +11,7 @@
### Requirements

- Minimum required Home Assistant version: `2022.8.0`
(_Latest tested version: `2023.11.1`_)
(_Latest tested version: `2024.1.0`_)

### Companion UI

Expand Down
6 changes: 4 additions & 2 deletions custom_components/better_thermostat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
CONF_NO_SYSTEM_MODE_OFF,
CONF_WINDOW_TIMEOUT,
CONF_WINDOW_TIMEOUT_AFTER,
CalibrationMode
CalibrationMode,
)

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -76,7 +76,9 @@ async def async_migrate_entry(hass, config_entry: ConfigEntry):
CalibrationMode.AGGRESIVE_CALIBRATION in trv["advanced"]
and trv["advanced"][CalibrationMode.AGGRESIVE_CALIBRATION]
):
trv["advanced"].update({CONF_CALIBRATION_MODE: CalibrationMode.AGGRESIVE_CALIBRATION})
trv["advanced"].update(
{CONF_CALIBRATION_MODE: CalibrationMode.AGGRESIVE_CALIBRATION}
)
else:
trv["advanced"].update({CONF_CALIBRATION_MODE: CalibrationMode.DEFAULT})
config_entry.version = 4
Expand Down
10 changes: 2 additions & 8 deletions custom_components/better_thermostat/adapters/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,7 @@ async def set_temperature(self, entity_id, temperature):

async def set_hvac_mode(self, entity_id, hvac_mode):
"""Set new target hvac mode."""
_LOGGER.debug(
"better_thermostat %s: set_hvac_mode %s",
self.name,
hvac_mode,
)
_LOGGER.debug("better_thermostat %s: set_hvac_mode %s", self.name, hvac_mode)
try:
await self.hass.services.async_call(
"climate",
Expand All @@ -133,9 +129,7 @@ async def set_hvac_mode(self, entity_id, hvac_mode):
context=self.context,
)
except TypeError:
_LOGGER.debug(
"TypeError in set_hvac_mode"
)
_LOGGER.debug("TypeError in set_hvac_mode")


async def set_offset(self, entity_id, offset):
Expand Down
58 changes: 29 additions & 29 deletions custom_components/better_thermostat/calibration.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
convert_to_float,
round_down_to_half_degree,
round_by_steps,
heating_power_valve_position
heating_power_valve_position,
)

from custom_components.better_thermostat.model_fixes.model_quirks import (
Expand Down Expand Up @@ -50,23 +50,28 @@ def calculate_calibration_local(self, entity_id) -> Union[float, None]:
_cur_external_temp = self.cur_temp
_cur_target_temp = self.bt_target_temp

_cur_trv_temp_f = convert_to_float(
str(_cur_trv_temp_s), self.name, _context
)
_cur_trv_temp_f = convert_to_float(str(_cur_trv_temp_s), self.name, _context)

_current_trv_calibration = convert_to_float(
str(self.real_trvs[entity_id]["last_calibration"]), self.name, _context
)

if None in (_current_trv_calibration, _cur_external_temp, _cur_trv_temp_f, _calibration_steps):
if None in (
_current_trv_calibration,
_cur_external_temp,
_cur_trv_temp_f,
_calibration_steps,
):
_LOGGER.warning(
f"better thermostat {self.name}: {entity_id} Could not calculate local calibration in {_context}:"
f" trv_calibration: {_current_trv_calibration}, trv_temp: {_cur_trv_temp_f}, external_temp: {_cur_external_temp}"
f" calibration_steps: {_calibration_steps}"
)
return None

_new_trv_calibration = (_cur_external_temp - _cur_trv_temp_f) + _current_trv_calibration
_new_trv_calibration = (
_cur_external_temp - _cur_trv_temp_f
) + _current_trv_calibration

_calibration_mode = self.real_trvs[entity_id]["advanced"].get(
"calibration_mode", CalibrationMode.DEFAULT
Expand All @@ -90,9 +95,7 @@ def calculate_calibration_local(self, entity_id) -> Union[float, None]:
if _new_trv_calibration < 0.0:
_new_trv_calibration += self.tolerance

_new_trv_calibration = fix_local_calibration(
self, entity_id, _new_trv_calibration
)
_new_trv_calibration = fix_local_calibration(self, entity_id, _new_trv_calibration)

_overheating_protection = self.real_trvs[entity_id]["advanced"].get(
CONF_PROTECT_OVERHEATING, False
Expand All @@ -103,31 +106,24 @@ def calculate_calibration_local(self, entity_id) -> Union[float, None]:
_new_trv_calibration += (_cur_external_temp - _cur_target_temp) * 10.0

# Adjust based on the steps allowed by the local calibration entity
_new_trv_calibration = round_by_steps(
_new_trv_calibration,
_calibration_steps
)
_new_trv_calibration = round_by_steps(_new_trv_calibration, _calibration_steps)

# Compare against min/max
if _new_trv_calibration > float(
self.real_trvs[entity_id]["local_calibration_max"]
):
_new_trv_calibration = float(
self.real_trvs[entity_id]["local_calibration_max"]
)
if _new_trv_calibration > float(self.real_trvs[entity_id]["local_calibration_max"]):
_new_trv_calibration = float(self.real_trvs[entity_id]["local_calibration_max"])
elif _new_trv_calibration < float(
self.real_trvs[entity_id]["local_calibration_min"]
):
_new_trv_calibration = float(
self.real_trvs[entity_id]["local_calibration_min"]
)
_new_trv_calibration = float(self.real_trvs[entity_id]["local_calibration_min"])

_new_trv_calibration = convert_to_float(
str(_new_trv_calibration), self.name, _context
)

_logmsg = "better_thermostat %s: %s - new local calibration: %s | external_temp: %s, "\
"trv_temp: %s, calibration: %s"
_logmsg = (
"better_thermostat %s: %s - new local calibration: %s | external_temp: %s, "
"trv_temp: %s, calibration: %s"
)

_LOGGER.debug(
_logmsg,
Expand All @@ -136,11 +132,12 @@ def calculate_calibration_local(self, entity_id) -> Union[float, None]:
_new_trv_calibration,
_cur_external_temp,
_cur_trv_temp_f,
_current_trv_calibration
_current_trv_calibration,
)

return _new_trv_calibration


def calculate_calibration_setpoint(self, entity_id) -> Union[float, None]:
"""Calculate new setpoint for the TRV based on its own temperature measurement and the air temperature of the external sensor.
Expand Down Expand Up @@ -183,7 +180,8 @@ def calculate_calibration_setpoint(self, entity_id) -> Union[float, None]:
if self.attr_hvac_action == HVACAction.HEATING:
valve_position = heating_power_valve_position(self, entity_id)
_calibrated_setpoint = _cur_trv_temp_s + (
(self.real_trvs[entity_id]["max_temp"] - _cur_trv_temp_s) * valve_position
(self.real_trvs[entity_id]["max_temp"] - _cur_trv_temp_s)
* valve_position
)

if self.attr_hvac_action == HVACAction.IDLE:
Expand All @@ -210,8 +208,10 @@ def calculate_calibration_setpoint(self, entity_id) -> Union[float, None]:
if _calibrated_setpoint > self.real_trvs[entity_id]["max_temp"]:
_calibrated_setpoint = self.real_trvs[entity_id]["max_temp"]

_logmsg = "better_thermostat %s: %s - new setpoint calibration: %s | external_temp: %s, "\
"target_temp: %s, trv_temp: %s"
_logmsg = (
"better_thermostat %s: %s - new setpoint calibration: %s | external_temp: %s, "
"target_temp: %s, trv_temp: %s"
)

_LOGGER.debug(
_logmsg,
Expand All @@ -220,7 +220,7 @@ def calculate_calibration_setpoint(self, entity_id) -> Union[float, None]:
_calibrated_setpoint,
_cur_external_temp,
_cur_target_temp,
_cur_trv_temp_s
_cur_trv_temp_s,
)

return _calibrated_setpoint
4 changes: 2 additions & 2 deletions custom_components/better_thermostat/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ async def async_service_handler(self, data: ServiceCall):
entry.data.get(CONF_OUTDOOR_SENSOR, None),
entry.data.get(CONF_OFF_TEMPERATURE, None),
entry.data.get(CONF_TOLERANCE, 0.0),
entry.data.get(CONF_TARGET_TEMP_STEP, 0.0),
entry.data.get(CONF_TARGET_TEMP_STEP, "0.0"),
entry.data.get(CONF_MODEL, None),
entry.data.get(CONF_COOLER, None),
hass.config.units.temperature_unit,
Expand Down Expand Up @@ -259,7 +259,7 @@ def __init__(
self.bt_target_temp_step = float(target_temp_step) or 0.0
self.bt_min_temp = 0
self.bt_max_temp = 30
self.bt_target_temp = 5
self.bt_target_temp = 5.0
self.bt_target_cooltemp = None
self._support_flags = SUPPORT_FLAGS
self.bt_hvac_mode = None
Expand Down
5 changes: 3 additions & 2 deletions custom_components/better_thermostat/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
TEMP_STEP_SELECTOR = selector.SelectSelector(
selector.SelectSelectorConfig(
options=[
selector.SelectOptionDict(value="0.0", label="Auto"),
selector.SelectOptionDict(value="0.1", label="0.1 °C"),
selector.SelectOptionDict(value="0.2", label="0.2 °C"),
selector.SelectOptionDict(value="0.25", label="0.25 °C"),
Expand Down Expand Up @@ -375,7 +376,7 @@ async def async_step_user(self, user_input=None):
): vol.All(vol.Coerce(float), vol.Range(min=0)),
vol.Optional(
CONF_TARGET_TEMP_STEP,
default=str(user_input.get(CONF_TARGET_TEMP_STEP, 0.0)),
default=str(user_input.get(CONF_TARGET_TEMP_STEP, "0.0")),
): TEMP_STEP_SELECTOR,
}
),
Expand Down Expand Up @@ -580,7 +581,7 @@ async def async_step_user(self, user_input=None):
user_input.get(CONF_TOLERANCE, 0.0)
)
self.updated_config[CONF_TARGET_TEMP_STEP] = float(
user_input.get(CONF_TARGET_TEMP_STEP, 0.0)
user_input.get(CONF_TARGET_TEMP_STEP, "0.0")
)

for trv in self.updated_config[CONF_HEATER]:
Expand Down
10 changes: 8 additions & 2 deletions custom_components/better_thermostat/events/trv.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ async def trigger_trv_change(self, event):
return
if self.control_queue_task is None:
return
if self.bt_target_temp is None or self.cur_temp is None or self.tolerance is None:
return
asyncio.create_task(update_hvac_action(self))
_main_change = False
old_state = event.data.get("old_state")
Expand Down Expand Up @@ -320,7 +322,9 @@ def convert_outbound_states(self, entity_id, hvac_mode) -> Union[dict, None]:

try:
_calibration_type = self.real_trvs[entity_id]["advanced"].get("calibration")
_calibration_mode = self.real_trvs[entity_id]["advanced"].get("calibration_mode")
_calibration_mode = self.real_trvs[entity_id]["advanced"].get(
"calibration_mode"
)

if _calibration_type is None:
_LOGGER.warning(
Expand All @@ -343,7 +347,9 @@ def convert_outbound_states(self, entity_id, hvac_mode) -> Union[dict, None]:
if _calibration_mode == CalibrationMode.NO_CALIBRATION:
_new_heating_setpoint = self.bt_target_temp
else:
_new_heating_setpoint = calculate_calibration_setpoint(self, entity_id)
_new_heating_setpoint = calculate_calibration_setpoint(
self, entity_id
)

_system_modes = self.real_trvs[entity_id]["hvac_modes"]
_has_system_mode = False
Expand Down
2 changes: 1 addition & 1 deletion custom_components/better_thermostat/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
"iot_class": "local_push",
"issue_tracker": "https://github.com/KartoffelToby/better_thermostat/issues",
"requirements": [],
"version": "1.4.1-dev"
"version": "1.5.0-dev"
}
15 changes: 8 additions & 7 deletions custom_components/better_thermostat/model_fixes/model_quirks.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def load_model_quirks(self, model, entity_id):


def fix_local_calibration(self, entity_id, offset):
""" Modifies the input local calibration offset, based on the TRV's model quirks,
"""Modifies the input local calibration offset, based on the TRV's model quirks,
to achieve the desired heating behavior.
Returns
Expand All @@ -51,13 +51,14 @@ def fix_local_calibration(self, entity_id, offset):
self.name,
entity_id,
offset,
_new_offset
_new_offset,
)

return _new_offset


def fix_target_temperature_calibration(self, entity_id, temperature):
""" Modifies the input setpoint temperature, based on the TRV's model quirks,
"""Modifies the input setpoint temperature, based on the TRV's model quirks,
to achieve the desired heating behavior.
Returns
Expand All @@ -66,17 +67,17 @@ def fix_target_temperature_calibration(self, entity_id, temperature):
new setpoint temperature, if the TRV model has any quirks/fixes.
"""

_new_temperature = self.real_trvs[entity_id]["model_quirks"].fix_target_temperature_calibration(
self, entity_id, temperature
)
_new_temperature = self.real_trvs[entity_id][
"model_quirks"
].fix_target_temperature_calibration(self, entity_id, temperature)

if temperature != _new_temperature:
_LOGGER.debug(
"better_thermostat %s: %s - temperature offset model fix: %s to %s",
self.name,
entity_id,
temperature,
_new_temperature
_new_temperature,
)

return _new_temperature
Expand Down
4 changes: 2 additions & 2 deletions custom_components/better_thermostat/utils/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from homeassistant.helpers.config_validation import ( # noqa: F401
make_entity_service_schema,
)
from homeassistant.components.climate.const import SUPPORT_TARGET_TEMPERATURE
from homeassistant.components.climate.const import ClimateEntityFeature
from homeassistant.const import ATTR_TEMPERATURE

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -54,7 +54,7 @@
CONF_NO_SYSTEM_MODE_OFF = "no_off_system_mode"
CONF_TOLERANCE = "tolerance"
CONF_TARGET_TEMP_STEP = "target_temp_step"
SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE
SUPPORT_FLAGS = ClimateEntityFeature.TARGET_TEMPERATURE

ATTR_STATE_WINDOW_OPEN = "window_open"
ATTR_STATE_CALL_FOR_HEAT = "call_for_heat"
Expand Down
Loading

0 comments on commit fd3f300

Please sign in to comment.