Radiator valve function restructured

This commit is contained in:
Dirk Alders 2023-01-09 16:42:18 +01:00
parent 94f089dd93
commit 837d77900d
8 changed files with 209 additions and 254 deletions

View File

@ -760,28 +760,44 @@ class gui_radiator_valve(base):
# #
TEMP_RANGE = [10, 30] TEMP_RANGE = [10, 30]
# #
KEY_BOOST_LED = "boost_led" KEY_TIMER = "timer"
KEY_TEMPERATURE_SETPOINT = "temperature_setpoint" KEY_TEMPERATURE = "temperature"
KEY_SETPOINT_TEMP = "setpoint_temp"
KEY_SETPOINT_TO_DEFAULT = "setpoint_to_default"
KEY_BOOST = 'boost'
# #
COMMANDS = [ COMMANDS = [
"get_temperature",
"get_temperature_setpoint", "set_temperature_setpoint", "get_temperature_setpoint", "set_temperature_setpoint",
"get_boost_state", "trigger_boost", "trigger_boost", "trigger_setpoint_to_default"
] ]
def __init__(self, mqtt_client, topic): def __init__(self, mqtt_client, topic):
super().__init__(mqtt_client, topic) super().__init__(mqtt_client, topic)
self.add_callback(self.KEY_TEMPERATURE_SETPOINT, self.print_formatted, None) self.add_callback(self.KEY_SETPOINT_TEMP, self.print_formatted, None)
self.add_callback(self.KEY_BOOST_LED, self.print_formatted, None) self.add_callback(self.KEY_TIMER, self.print_formatted, None)
#
self.store_data(**{
self.KEY_TEMPERATURE: 20.7,
self.KEY_SETPOINT_TEMP: 20,
self.KEY_TIMER: 0,
})
def __rx__(self, client, userdata, message): def __rx__(self, client, userdata, message):
if message.topic.startswith(self.topic) and message.topic.endswith("/set"): value = payload_filter(message.payload)
payload = payload_filter(message.payload) if message.topic.startswith(self.topic) and message.topic.endswith('/set'):
if type(payload) == bool: targetkey = message.topic.split('/')[-2]
self.store_data(**{self.KEY_BOOST_LED: payload}) if targetkey in self.data.keys():
self.store_data(**{targetkey: value})
else: else:
self.store_data(**{self.KEY_TEMPERATURE_SETPOINT: payload}) print("Unknown key %s in %s::%s" % (targetkey, message.topic, self.__class__.__name__))
else: elif message.topic == self.topic + '/get':
print(message.topic) self.__tx__(None)
def send(self, key, data):
if data is not None:
topic = self.topic + '/' + key
self.mqtt_client.send(topic, json.dumps(data))
def command(self, command): def command(self, command):
try: try:
@ -790,27 +806,35 @@ class gui_radiator_valve(base):
value = None value = None
if command in self.COMMANDS: if command in self.COMMANDS:
if command == self.COMMANDS[0]: if command == self.COMMANDS[0]:
self.print_formatted(self, self.KEY_TEMPERATURE_SETPOINT, self.data.get(self.KEY_TEMPERATURE_SETPOINT)) self.print_formatted(self, self.KEY_TEMPERATURE, self.data.get(self.KEY_TEMPERATURE))
elif command == self.COMMANDS[1]: elif command == self.COMMANDS[1]:
################################### TEMPORARY!!! ################################### self.print_formatted(self, self.KEY_SETPOINT_TEMP, self.data.get(self.KEY_SETPOINT_TEMP))
self.mqtt_client.send(self.topic + "/feedback/set", command_float_value(value))
################################### TEMPORARY!!! ###################################
elif command == self.COMMANDS[2]: elif command == self.COMMANDS[2]:
self.print_formatted(self, self.KEY_BOOST_LED, self.data.get(self.KEY_BOOST_LED)) self.send(self.KEY_SETPOINT_TEMP, command_float_value(value))
elif command == self.COMMANDS[3]: elif command == self.COMMANDS[3]:
################################### TEMPORARY!!! ################################### self.send(self.KEY_BOOST, True)
self.mqtt_client.send(self.topic + "/state", json.dumps(True)) elif command == self.COMMANDS[4]:
################################### TEMPORARY!!! ################################### self.send(self.KEY_SETPOINT_TO_DEFAULT, True)
def print_formatted(self, device, key, value): def print_formatted(self, device, key, value):
devicename = ' - '.join(self.topic.split('/')[1:]) devicename = ' - '.join(self.topic.split('/')[1:])
if key == self.KEY_BOOST_LED: if key in [self.KEY_TEMPERATURE, self.KEY_SETPOINT_TEMP, self.KEY_TIMER]:
led = green_led() if value else grey_led() if key in [self.KEY_TEMPERATURE, self.KEY_SETPOINT_TEMP]:
print(10 * ' ' + led + 9 * ' ' + COLOR_GUI_ACTIVE + devicename + " (Boost)" + colored.attr("reset")) perc = 100 * (value - self.TEMP_RANGE[0]) / (self.TEMP_RANGE[1] - self.TEMP_RANGE[0])
elif key == self.KEY_TEMPERATURE_SETPOINT: info = " (Temperature)" if key == self.KEY_TEMPERATURE else " (Setpoint)"
perc = 100 * (value - self.TEMP_RANGE[0]) / (self.TEMP_RANGE[1] - self.TEMP_RANGE[0]) else:
try:
perc = 100 * value / 60
except TypeError:
value = 0
perc = 0
info = " (Timer)"
perc = 100 if perc > 100 else perc perc = 100 if perc > 100 else perc
perc = 0 if perc < 0 else perc perc = 0 if perc < 0 else perc
sys.stdout.write(COLOR_GUI_ACTIVE + '\u03d1' + percent_bar(perc))
sys.stdout.write("%4.1f°C" % value + 3 * " ") sys.stdout.write(COLOR_GUI_ACTIVE)
print(devicename + colored.attr("reset")) if key == self.KEY_TIMER:
sys.stdout.write('T' + percent_bar(perc) + "%4.1fmin" % value + 2 * " ")
else:
sys.stdout.write('\u03d1' + percent_bar(perc) + "%4.1f°C" % value + 3 * " ")
print(devicename + info + colored.attr("reset"))

View File

@ -168,10 +168,8 @@ class ffe_sleep(base):
self.led_array.add_channel_name(gui_led_array.KEY_LED_0, "Main Light") self.led_array.add_channel_name(gui_led_array.KEY_LED_0, "Main Light")
self.led_array.add_channel_name(gui_led_array.KEY_LED_1, "Bed Light Dirk") self.led_array.add_channel_name(gui_led_array.KEY_LED_1, "Bed Light Dirk")
# #
self.heating_valve = brennenstuhl_radiator_valve(mqtt_client, config.TOPIC_FFE_SLEEP_RADIATOR_VALVE_ZIGBEE) self.radiator_valve = brennenstuhl_radiator_valve(mqtt_client, config.TOPIC_FFE_SLEEP_RADIATOR_VALVE_ZIGBEE)
self.gui_heating_valve = gui_radiator_valve(mqtt_client, "gui/ffe_ts_sleep_madi") self.gui_radiator_valve = gui_radiator_valve(mqtt_client, config.TOPIC_FFE_SLEEP_RADIATOR_VALVE_GUI)
self.gui_heating_valve_boost_led = gui_radiator_valve(mqtt_client, "gui/ffe_bl_sleep_madi")
self.gui_heating_valve_boost_button = gui_radiator_valve(mqtt_client, "gui/ffe_bo_sleep_madi")
class ffe_livingroom(base): class ffe_livingroom(base):

View File

@ -186,41 +186,6 @@ class base(dict):
return self.__previous__.get(key) return self.__previous__.get(key)
class nodered_gui_leds(base):
KEY_LED_0 = "led0"
KEY_LED_1 = "led1"
KEY_LED_2 = "led2"
KEY_LED_3 = "led3"
KEY_LED_4 = "led4"
KEY_LED_5 = "led5"
KEY_LED_6 = "led6"
KEY_LED_7 = "led7"
KEY_LED_8 = "led8"
KEY_LED_9 = "led9"
KEY_LED_LIST = [KEY_LED_0, KEY_LED_1, KEY_LED_2, KEY_LED_3, KEY_LED_4, KEY_LED_5, KEY_LED_6, KEY_LED_7, KEY_LED_8, KEY_LED_9]
#
TX_TYPE = base.TX_VALUE
def set_led(self, key, data):
"""data: [True, False]"""
self.logger.debug("Sending %s with content %s", key, str(data))
self.pack(key, data)
class nodered_gui_timer(base):
KEY_TIMER = "timer"
#
TX_TYPE = base.TX_VALUE
def set_timer(self, data):
"""data: numeric"""
self.pack(self.KEY_TIMER, data)
def set_timer_mcb(self, device, key, data):
self.logger.debug("Sending %s with content %s", key, str(data))
self.set_timer(data)
class shelly(base): class shelly(base):
KEY_OUTPUT_0 = "relay/0" KEY_OUTPUT_0 = "relay/0"
KEY_OUTPUT_1 = "relay/1" KEY_OUTPUT_1 = "relay/1"
@ -649,61 +614,39 @@ class tradfri_button(base):
return "Low battery level detected for %s. Battery level was %.0f%%." % (self.topic, self.get(self.KEY_BATTERY)) return "Low battery level detected for %s. Battery level was %.0f%%." % (self.topic, self.get(self.KEY_BATTERY))
class nodered_gui_heatvalve(base): class nodered_gui_leds(base):
KEY_FEEDBACK = "feedback" KEY_LED_0 = "led0"
KEY_ENABLE = "enable" KEY_LED_1 = "led1"
KEY_STATE = "state" KEY_LED_2 = "led2"
KEY_BRIGHTNESS = "brightness" KEY_LED_3 = "led3"
KEY_COLOR_TEMP = "color_temp" KEY_LED_4 = "led4"
KEY_HEATING_BOOST = "heating_boost" KEY_LED_5 = "led5"
KEY_HEATING_SETPOINT = "heating_setpoint" KEY_LED_6 = "led6"
KEY_OFF_BUTTON = "off_button" KEY_LED_7 = "led7"
KEY_LED_8 = "led8"
KEY_LED_9 = "led9"
KEY_LED_LIST = [KEY_LED_0, KEY_LED_1, KEY_LED_2, KEY_LED_3, KEY_LED_4, KEY_LED_5, KEY_LED_6, KEY_LED_7, KEY_LED_8, KEY_LED_9]
# #
TX_TYPE = base.TX_VALUE TX_TYPE = base.TX_VALUE
def set_led(self, key, data):
"""data: [True, False]"""
self.logger.debug("Sending %s with content %s", key, str(data))
self.pack(key, data)
class nodered_gui_timer(base):
KEY_TIMER = "timer"
# #
RX_KEYS = [KEY_STATE, KEY_BRIGHTNESS, KEY_COLOR_TEMP, KEY_HEATING_BOOST, KEY_HEATING_SETPOINT, KEY_OFF_BUTTON] TX_TYPE = base.TX_VALUE
def __init__(self, mqtt_client, topic): def set_timer(self, data):
super().__init__(mqtt_client, topic) """data: numeric"""
self.pack(self.KEY_TIMER, data)
# def set_timer_mcb(self, device, key, data):
# RX self.logger.debug("Sending %s with content %s", key, str(data))
# self.set_timer(data)
@property
def state(self):
"""rv: [True, False]"""
return self.get(self.KEY_STATE)
@property
def brightness(self):
"""rv: [0, ..., 100]"""
return self.get(self.KEY_BRIGHTNESS)
@property
def color_temp(self):
"""rv: [0, ..., 100]"""
return self.get(self.KEY_COLOR_TEMP)
@property
def heating_boost(self):
"""rv: [True, False]"""
return self.get(self.KEY_HEATING_BOOST)
@property
def heating_(self):
"""rv: [5, ..., 30]"""
return self.get(self.KEY_HEATING_SETPOINT)
@property
def off_button(self):
"""rv: [True, False]"""
return self.get(self.KEY_OFF_BUTTON)
#
# TX
#
def set_feedback(self, data):
self.pack(self.KEY_FEEDBACK, data)
class nodered_gui_button(base): class nodered_gui_button(base):
@ -790,6 +733,34 @@ class nodered_gui_light(nodered_gui_switch, nodered_gui_leds, nodered_gui_timer)
self.set_color_temp(data) self.set_color_temp(data)
class nodered_gui_radiator(nodered_gui_timer):
KEY_TEMPERATURE = "temperature"
KEY_SETPOINT_TEMP = "setpoint_temp"
KEY_SETPOINT_TO_DEFAULT = "setpoint_to_default"
KEY_BOOST = 'boost'
#
RX_KEYS = [KEY_TEMPERATURE, KEY_SETPOINT_TEMP, KEY_SETPOINT_TO_DEFAULT, KEY_BOOST]
#
# TX
#
def set_temperature(self, data):
"""data: [True, False]"""
self.pack(self.KEY_TEMPERATURE, data)
def set_temperature_mcb(self, device, key, data):
self.logger.debug("Sending %s with content %s", key, str(data))
self.set_temperature(data)
def set_setpoint_temperature(self, data):
"""data: [True, False]"""
self.pack(self.KEY_SETPOINT_TEMP, data)
def set_setpoint_temperature_mcb(self, device, key, data):
self.logger.debug("Sending %s with content %s", key, str(data))
self.set_setpoint_temperature(data)
class brennenstuhl_heatingvalve(base): class brennenstuhl_heatingvalve(base):
KEY_LINKQUALITY = "linkquality" KEY_LINKQUALITY = "linkquality"
KEY_BATTERY = "battery" KEY_BATTERY = "battery"

View File

@ -6,7 +6,6 @@ from function.stairway import stairway
from function.ground_floor_west import ground_floor_west_floor, ground_floor_west_marion, ground_floor_west_dirk from function.ground_floor_west import ground_floor_west_floor, ground_floor_west_marion, ground_floor_west_dirk
from function.first_floor_west import first_floor_west_julian, first_floor_west_living from function.first_floor_west import first_floor_west_julian, first_floor_west_living
from function.first_floor_east import first_floor_east_floor, first_floor_east_kitchen, first_floor_east_dining, first_floor_east_sleep, first_floor_east_living from function.first_floor_east import first_floor_east_floor, first_floor_east_kitchen, first_floor_east_dining, first_floor_east_sleep, first_floor_east_living
from function.common import common_heating, common_circulation_pump
import inspect import inspect
import logging import logging
@ -16,9 +15,6 @@ except ImportError:
ROOT_LOGGER_NAME = 'root' ROOT_LOGGER_NAME = 'root'
logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__) logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
# TODO: implement devices.nodered_gui_heatvalve incl. setpoint, boost, ... + replace led with timer
# TODO: improve heating function (away mode (reduced setpoint), return to default button, default values in config)
# TODO: improve devices.brennenstuhl_heatvalve
# TODO: implement garland (incl. day events like sunset, sunrise, ...) # TODO: implement garland (incl. day events like sunset, sunrise, ...)
# TODO: implement warning message # TODO: implement warning message
@ -28,9 +24,6 @@ class all_functions(object):
self.mqtt_client = mqtt_client self.mqtt_client = mqtt_client
# #
self.__devices__ = None self.__devices__ = None
# heating and warm water
self.common_ffe_heat_sleep = common_heating(self.mqtt_client)
self.common_circulation_pump = common_circulation_pump(self.mqtt_client)
# stairway # stairway
self.stw_stairway = stairway(self.mqtt_client) self.stw_stairway = stairway(self.mqtt_client)
# ground floor west # ground floor west
@ -51,8 +44,6 @@ class all_functions(object):
# #
# cross_room_interactions # cross_room_interactions
self.init_cross_room_interactions() self.init_cross_room_interactions()
# Circulation pump
self.init_circulation_pump()
# Off Buttons # Off Buttons
self.init_off_functionality() self.init_off_functionality()
@ -117,9 +108,6 @@ class all_functions(object):
self.ffe_sleep.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION, self.ffe_sleep.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION,
devices.tradfri_button.ACTION_RIGHT, self.ffe_floor.main_light_shelly.toggle_output_0_mcb) devices.tradfri_button.ACTION_RIGHT, self.ffe_floor.main_light_shelly.toggle_output_0_mcb)
def init_circulation_pump(self):
self.common_circulation_pump.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.ffe_kitchen.flash_main_light)
def gfw_dirk_input_1(self, device, key, data): def gfw_dirk_input_1(self, device, key, data):
if self.last_gfw_dirk_input_1 is not None: if self.last_gfw_dirk_input_1 is not None:
if self.last_gfw_dirk_input_1 != data: if self.last_gfw_dirk_input_1 != data:

View File

@ -1,57 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import config
import devices
from function.rooms import room_shelly
from function.modules import heating_function_brennenstuhl
import logging
import task
try:
from config import APP_NAME as ROOT_LOGGER_NAME
except ImportError:
ROOT_LOGGER_NAME = 'root'
logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
class common_circulation_pump(room_shelly):
def __init__(self, mqtt_client):
# http://shelly1-E89F6D85A466
super().__init__(mqtt_client, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_SHELLY, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_GUI)
#
self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.circ_pump_actions, True)
#
self.gui_main_light.set_timer('-')
#
self.ct = task.periodic(6, self.cyclic_task)
self.pump_timer = None
#
self.ct.run()
def circ_pump_actions(self, device, key, data):
if data is True:
self.pump_timer = 10
self.gui_main_light.set_timer(self.pump_timer)
else:
self.pump_timer = None
self.gui_main_light.set_timer('-')
def cyclic_task(self, rt):
if self.pump_timer is not None:
if self.pump_timer <= 0:
self.pump_timer = None
self.gui_main_light.set_timer('-')
else:
self.gui_main_light.set_timer(self.pump_timer)
self.pump_timer -= self.ct.cycle_time / 60
class common_heating(object):
def __init__(self, mqtt_client):
self.ffe_heating_sleep_madi = heating_function_brennenstuhl(
mqtt_client, "zigbee/ffe/sleep/radiator_valve", 20, "gui/ffe_bo_sleep_madi", "gui/ffe_ts_sleep_madi", "gui/ffe_bl_sleep_madi")
def all_off(self):
pass # dummy method for compatibility reasons

View File

@ -4,7 +4,7 @@
import config import config
import devices import devices
from function.modules import brightness_choose_n_action from function.modules import brightness_choose_n_action, circulation_pump, radiator_function
import logging import logging
from function.rooms import room_shelly, room_shelly_motion_sensor, room_shelly_tradfri_light from function.rooms import room_shelly, room_shelly_motion_sensor, room_shelly_tradfri_light
try: try:
@ -24,6 +24,13 @@ class first_floor_east_kitchen(room_shelly):
def __init__(self, mqtt_client): def __init__(self, mqtt_client):
# http://shelly1l-8CAAB5616C01 # http://shelly1l-8CAAB5616C01
super().__init__(mqtt_client, config.TOPIC_FFE_KITCHEN_MAIN_LIGHT_SHELLY, config.TOPIC_FFE_KITCHEN_MAIN_LIGHT_GUI) super().__init__(mqtt_client, config.TOPIC_FFE_KITCHEN_MAIN_LIGHT_SHELLY, config.TOPIC_FFE_KITCHEN_MAIN_LIGHT_GUI)
#
self.circulation_pump = circulation_pump(mqtt_client)
self.circulation_pump.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.flash_main_light)
def all_off(self, device=None, key=None, data=None):
self.circulation_pump.all_off(device, key, data)
return super().all_off(device, key, data)
class first_floor_east_dining(room_shelly): class first_floor_east_dining(room_shelly):
@ -53,16 +60,18 @@ class first_floor_east_sleep(room_shelly_tradfri_light):
def __init__(self, mqtt_client): def __init__(self, mqtt_client):
# http://shelly1l-E8DB84A254C7 # http://shelly1l-E8DB84A254C7
super().__init__(mqtt_client, config.TOPIC_FFE_SLEEP_MAIN_LIGHT_SHELLY, config.TOPIC_FFE_SLEEP_MAIN_LIGHT_GUI, config.TOPIC_FFE_SLEEP_MAIN_LIGHT_ZIGBEE) super().__init__(mqtt_client, config.TOPIC_FFE_SLEEP_MAIN_LIGHT_SHELLY, config.TOPIC_FFE_SLEEP_MAIN_LIGHT_GUI, config.TOPIC_FFE_SLEEP_MAIN_LIGHT_ZIGBEE)
# # bed light
self.bed_light_di_tradfri = devices.tradfri_light(mqtt_client, config.TOPIC_FFE_SLEEP_BED_LIGHT_DI_ZIGBEE) self.bed_light_di_tradfri = devices.tradfri_light(mqtt_client, config.TOPIC_FFE_SLEEP_BED_LIGHT_DI_ZIGBEE)
#
self.gui_bed_light_di = devices.nodered_gui_light(mqtt_client, config.TOPIC_FFE_SLEEP_BED_LIGHT_DI_GUI) self.gui_bed_light_di = devices.nodered_gui_light(mqtt_client, config.TOPIC_FFE_SLEEP_BED_LIGHT_DI_GUI)
# #
self.button_tradfri = devices.tradfri_button(mqtt_client, config.TOPIC_FFE_SLEEP_INPUT_DEVICE) self.button_tradfri = devices.tradfri_button(mqtt_client, config.TOPIC_FFE_SLEEP_INPUT_DEVICE)
# # button / brightness function
self.brightness_functions = brightness_choose_n_action(mqtt_client, self.button_tradfri, config.TOPIC_FFE_SLEEP_DEVICE_CHOOSER_LED) self.brightness_functions = brightness_choose_n_action(mqtt_client, self.button_tradfri, config.TOPIC_FFE_SLEEP_DEVICE_CHOOSER_LED)
self.brightness_functions.add(self.main_light_tradfri, self.main_light_shelly, devices.shelly.KEY_OUTPUT_0) self.brightness_functions.add(self.main_light_tradfri, self.main_light_shelly, devices.shelly.KEY_OUTPUT_0)
self.brightness_functions.add(self.bed_light_di_tradfri, self.bed_light_di_tradfri, devices.tradfri_light.KEY_OUTPUT_0) self.brightness_functions.add(self.bed_light_di_tradfri, self.bed_light_di_tradfri, devices.tradfri_light.KEY_OUTPUT_0)
# radiator valve
self.radiator_function = radiator_function(mqtt_client, config.TOPIC_FFE_SLEEP_RADIATOR_VALVE_ZIGBEE,
config.TOPIC_FFE_SLEEP_RADIATOR_VALVE_GUI, config.DEFAULT_TEMPERATURE_FFE_SLEEP)
# #
# Callback initialisation # Callback initialisation
# #

View File

@ -2,7 +2,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import config
import devices import devices
from function.rooms import room_shelly
import logging import logging
import task import task
@ -100,73 +102,94 @@ class brightness_choose_n_action(object):
target.default_stop() target.default_stop()
class heating_function_brennenstuhl(object): class circulation_pump(room_shelly):
RETURN_TO_DEFAULT_TIME = 45 * 60 def __init__(self, mqtt_client):
BOOST_TEMP_OFFSET = 5 super().__init__(mqtt_client, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_SHELLY, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_GUI)
def __init__(self, mqtt_client, topic_valve, default_temperature, topic_boost, topic_setpoint, topic_led):
self.ct = task.periodic(1, self.cyclic_task)
# #
self.topic = topic_valve self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.circ_pump_actions, True)
self.default_temperature = default_temperature
# #
self.heating_valve = devices.brennenstuhl_heatingvalve(mqtt_client, topic_valve) self.gui_main_light.set_timer('-')
self.heating_valve.set_heating_setpoint(self.default_temperature)
self.heating_valve.add_callback(
devices.brennenstuhl_heatingvalve.KEY_HEATING_SETPOINT, None, self.heating_setpoint_actions)
self.gui_value_temp_setp = devices.nodered_gui_heatvalve(mqtt_client, topic_setpoint)
self.gui_value_temp_setp.add_callback(
devices.nodered_gui_heatvalve.KEY_HEATING_SETPOINT, None, self.heating_setpoint_actions)
self.gui_button_boost = devices.nodered_gui_heatvalve(mqtt_client, topic_boost)
self.gui_button_boost.add_callback(None, None, self.boost_actions)
self.gui_led_boost = devices.nodered_gui_heatvalve(mqtt_client, topic_led)
# #
self.return_to_default_timer = None self.ct = task.periodic(6, self.cyclic_task)
self.return_to_default_setpoint = None self.pump_timer = None
self.gui_led_boost.set_feedback(False)
# #
self.ct.run() self.ct.run()
def heating_setpoint_actions(self, device, key, data): def circ_pump_actions(self, device, key, data):
if device.topic == self.heating_valve.topic: if data is True:
# valve setpoint action self.pump_timer = 10
self.gui_value_temp_setp.set_feedback(data) self.gui_main_light.set_timer(self.pump_timer)
if data > self.default_temperature: else:
if data != self.return_to_default_setpoint: self.pump_timer = None
logger.info('Got heating setpoint (%.1f°C) \"%s\" with deviation to the default value (%.1f°C). Starting timer for returning to default.', self.gui_main_light.set_timer('-')
data, self.topic, self.default_temperature)
self.return_to_default_timer = self.RETURN_TO_DEFAULT_TIME
self.return_to_default_setpoint = data
self.gui_led_boost.set_feedback(True)
else:
if self.return_to_default_timer is not None:
logger.info('Deleting timer \"%s\" for returning to default.', self.topic)
self.return_to_default_timer = None
self.return_to_default_setpoint = None
self.gui_led_boost.set_feedback(False)
elif device.topic == self.gui_value_temp_setp.topic:
# user setpoint action
logger.info('Setpoint change \"%s\" to %.1f°C', self.topic, data)
self.default_temperature = data
self.heating_valve.set_heating_setpoint(self.default_temperature)
self.return_to_default_timer = None
self.return_to_default_setpoint = None
self.gui_led_boost.set_feedback(False)
def boost_actions(self, davice, key, data):
logger.info('Starting boost mode \"%s\" with setpoint %.1f°C.', self.topic, self.default_temperature + self.BOOST_TEMP_OFFSET)
self.heating_valve.set_heating_setpoint(self.default_temperature + self.BOOST_TEMP_OFFSET)
def cyclic_task(self, rt): def cyclic_task(self, rt):
if self.return_to_default_timer is not None: if self.pump_timer is not None:
self.return_to_default_timer -= self.ct.cycle_time if self.pump_timer <= 0:
if self.return_to_default_timer <= 0: self.pump_timer = None
logger.info('Return to default timer expired \"%s\".', self.topic) self.gui_main_light.set_timer('-')
self.heating_valve.set_heating_setpoint(self.default_temperature) else:
self.return_to_default_timer = None self.gui_main_light.set_timer(self.pump_timer)
self.return_to_default_setpoint = None self.pump_timer -= self.ct.cycle_time / 60
self.gui_led_boost.set_feedback(False)
# TODO:
# - improve devices.brennenstuhl_heatingvalve (at least switch on for boost) and use boost in heating_function.boost_mcb
# - implement modules.heating_function
# * Central switch incl. central parameter storage for state (summer mode, away_mode - each switch activation disables the other switch)
class radiator_function(object):
def __init__(self, mqtt_client, topic_valve, topic_gui, default_temperature):
self.default_temperature = default_temperature
self.regular_temp_setpoint = self.default_temperature
#
self.ct = task.periodic(1, self.cyclic_task)
#
self.heating_valve = devices.brennenstuhl_heatingvalve(mqtt_client, topic_valve)
self.gui_heating = devices.nodered_gui_radiator(mqtt_client, topic_gui)
#
self.heating_valve.set_heating_setpoint(self.default_temperature)
self.heating_valve.add_callback(devices.brennenstuhl_heatingvalve.KEY_TEMPERATURE, None, self.gui_heating.set_temperature_mcb)
self.heating_valve.add_callback(devices.brennenstuhl_heatingvalve.KEY_HEATING_SETPOINT, None, self.gui_heating.set_setpoint_temperature_mcb)
self.heating_valve.add_callback(devices.brennenstuhl_heatingvalve.KEY_HEATING_SETPOINT, None, self.store_regular_setpoint)
#
self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_SETPOINT_TEMP, None, self.heating_valve.set_heating_setpoint_mcb)
self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_BOOST, None, self.boost_mcb)
self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_SETPOINT_TO_DEFAULT, None, self.setpoint_to_default_mcb)
self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_SETPOINT_TEMP, None, self.cancel_boost)
self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_SETPOINT_TO_DEFAULT, None, self.cancel_boost)
#
self.boost_timer = None
#
self.ct.run()
def cyclic_task(self, rt):
if self.boost_timer is not None:
self.gui_heating.set_timer(round(self.boost_timer / 60, 1))
#
self.boost_timer -= self.ct.cycle_time
if self.boost_timer <= 0:
self.cancel_boost()
self.heating_valve.set_heating_setpoint(self.regular_temp_setpoint)
def cancel_boost(self, device=None, key=None, data=None):
if self.boost_timer is not None:
self.heating_valve.logger.info('Timer expired. returning to regular temperature setpoint %.1f°C.', self.regular_temp_setpoint)
self.boost_timer = None
self.gui_heating.set_timer('-')
def store_regular_setpoint(self, device, key, data):
if self.boost_timer is None:
self.regular_temp_setpoint = data
def boost_mcb(self, device, key, data):
if self.boost_timer is None:
self.heating_valve.logger.info('Starting boost mode with setpoint %.1f°C.', self.regular_temp_setpoint + 5)
self.boost_timer = 15*60
self.heating_valve.set_heating_setpoint(self.regular_temp_setpoint + 5) # TODO: Change setpoint to "on" if possible
else:
self.boost_timer += 15 * 60
if self.boost_timer > 60 * 60:
self.boost_timer = 60 * 60
def setpoint_to_default_mcb(self, device, key, data):
self.heating_valve.set_heating_setpoint(self.default_temperature)

View File

@ -106,14 +106,13 @@ class room_shelly_motion_sensor(room_shelly):
logger.info("No motion and time ran out - Switching off main light %s", self.main_light_shelly.topic) logger.info("No motion and time ran out - Switching off main light %s", self.main_light_shelly.topic)
self.main_light_shelly.set_output_0(False) self.main_light_shelly.set_output_0(False)
self.main_light_timer = None self.main_light_timer = None
self.gui_main_light.set_timer('-')
else: else:
self.gui_main_light.set_timer(self.main_light_timer) self.gui_main_light.set_timer(self.main_light_timer)
if (self.motion_detected_1 or self.motion_detected_2) and self.main_light_timer <= self.timer_value / 10: if (self.motion_detected_1 or self.motion_detected_2) and self.main_light_timer <= self.timer_value / 10:
self.main_light_timer = self.timer_value / 10 self.main_light_timer = self.timer_value / 10
else: else:
self.main_light_timer -= cyclic_task.cycle_time self.main_light_timer -= cyclic_task.cycle_time
else:
self.gui_main_light.set_timer('-')
class room_shelly_tradfri_light(room_shelly): class room_shelly_tradfri_light(room_shelly):