Added a smart condition to the boiler
This commit is contained in:
1 parent
6447d754ca
commit
79dd13f31d
4 files changed
+215
-6
No files matched your search
+40
-5
@@ -5,6 +5,7 @@ from pathlib import Path
|
||||
import time
|
||||
|
||||
import appdaemon.plugins.hass.hassapi as hass
|
||||
import ad_toolbox.smartcondition as SmartCondition
|
||||
from boilerregulator import BoilerRegulator, finite, setmode
|
||||
from logger_interface import LoggerInterface
|
||||
|
||||
@@ -19,6 +20,7 @@ class BoilerClimate(hass.Hass, LoggerInterface):
|
||||
self.boiler = self.args.get('boiler_topic', 'themaplus-condens').rstrip('/')
|
||||
self.connection_topic = self.args.get('mqtt_connection_topic', self.base + '/connection')
|
||||
self.uid = self.args.get('unique_id', 'appdaemon_radiator_heating')
|
||||
self.entity_id = self.args.get('entity', 'climate.radiator_heating')
|
||||
self.title = self.args.get('display_name', 'Chauffage radiateurs')
|
||||
self.indoor = self.args['indoor_sensor']
|
||||
outdoors = self.args.get('outdoor_sensors')
|
||||
@@ -54,10 +56,40 @@ class BoilerClimate(hass.Hass, LoggerInterface):
|
||||
for entity in self.outdoors:
|
||||
self.listen_state(self._sensor_changed, entity, attribute='all')
|
||||
self._discovery()
|
||||
self._initialize_smart_conditions()
|
||||
self.run_every(self._tick, 'now', self.interval)
|
||||
self._control()
|
||||
self.log_info(f'Boiler climate ready: MQTT writes={self.send_commands}, room target={self.target} °C')
|
||||
|
||||
def _initialize_smart_conditions(self, kwargs=None):
|
||||
if getattr(self, 'smart_conditions_evaluator', None) is not None:
|
||||
return
|
||||
self.smart_conditions_evaluator = None
|
||||
if 'smart_conditions' in self.args:
|
||||
if not self.entity_exists(self.entity_id) or self.get_state(self.entity_id, attribute='temperature') is None:
|
||||
self.mode = 'off'
|
||||
self.run_in(self._initialize_smart_conditions, 1)
|
||||
return
|
||||
constants = {**self.args.get('constants', {}), 'self': self.entity_id}
|
||||
self.smart_conditions_evaluator = SmartCondition.Evaluator(
|
||||
self, self.args['smart_conditions'], condition_name='smart_conditions',
|
||||
on_change_cb=self.on_smart_conditions_change,
|
||||
constants=constants)
|
||||
|
||||
def on_smart_conditions_change(self, previous, result):
|
||||
if result == SmartCondition.Result.Disabled:
|
||||
return
|
||||
mode = 'heat' if result == SmartCondition.Result.Succeeded else 'off'
|
||||
if mode != self.mode:
|
||||
self._set_mode(mode, 'SmartCondition')
|
||||
|
||||
def _set_mode(self, mode, source):
|
||||
self.log_info(f'Climate mode: {self.mode} -> {mode} ({source})')
|
||||
self.mode = mode
|
||||
self.controller.reset()
|
||||
self._control(force=True)
|
||||
self._save_safely()
|
||||
|
||||
def _publish(self, topic, payload, retain=False):
|
||||
if not isinstance(payload, str):
|
||||
payload = json.dumps(payload, allow_nan=False, ensure_ascii=False)
|
||||
@@ -71,7 +103,7 @@ class BoilerClimate(hass.Hass, LoggerInterface):
|
||||
{'topic': self.connection_topic}],
|
||||
availability_mode='all')
|
||||
config = dict(common, name=None, unique_id=self.uid,
|
||||
default_entity_id='climate.radiator_heating',
|
||||
default_entity_id=self.entity_id,
|
||||
modes=['off', 'heat'], temperature_unit='C', precision=0.1,
|
||||
temp_step=0.5, min_temp=self.min_target, max_temp=self.max_target,
|
||||
mode_command_topic=self.base + '/command/mode',
|
||||
@@ -170,10 +202,7 @@ class BoilerClimate(hass.Hass, LoggerInterface):
|
||||
if payload not in ('off', 'heat'):
|
||||
self.log_warning('Rejected invalid climate mode')
|
||||
return
|
||||
self.mode = payload
|
||||
self.controller.reset()
|
||||
self._control(force=True)
|
||||
self._save_safely()
|
||||
self._set_mode(payload, 'MQTT')
|
||||
elif topic == self.base + '/command/temperature':
|
||||
try:
|
||||
target = finite(payload)
|
||||
@@ -286,11 +315,17 @@ class BoilerClimate(hass.Hass, LoggerInterface):
|
||||
# on boiler command expiration. No retained actuator command, ever.
|
||||
if not hasattr(self, 'base'):
|
||||
return
|
||||
evaluator = getattr(self, 'smart_conditions_evaluator', None)
|
||||
try:
|
||||
if self.send_commands:
|
||||
self._publish(self.boiler + '/bai/SetMode/set', setmode(0, False))
|
||||
except Exception as exc:
|
||||
self.log_error(f'Could not publish shutdown; boiler expiration remains the fallback: {exc}')
|
||||
if evaluator is not None:
|
||||
try:
|
||||
evaluator.deactivate()
|
||||
except Exception as exc:
|
||||
self.log_warning(f'Could not deactivate SmartCondition: {exc}')
|
||||
try:
|
||||
self._publish(self.base + '/availability', 'offline', True)
|
||||
except Exception as exc:
|
||||
|
||||
Reference in new issue
Block a user