Browse Source

Radiator valve function restructured

tags/v1.0.0
Dirk Alders 1 year ago
parent
commit
837d77900d

+ 52
- 28
__simulation__/devices.py View File

@@ -760,28 +760,44 @@ class gui_radiator_valve(base):
760 760
     #
761 761
     TEMP_RANGE = [10, 30]
762 762
     #
763
-    KEY_BOOST_LED = "boost_led"
764
-    KEY_TEMPERATURE_SETPOINT = "temperature_setpoint"
763
+    KEY_TIMER = "timer"
764
+    KEY_TEMPERATURE = "temperature"
765
+    KEY_SETPOINT_TEMP = "setpoint_temp"
766
+    KEY_SETPOINT_TO_DEFAULT = "setpoint_to_default"
767
+    KEY_BOOST = 'boost'
765 768
     #
766 769
     COMMANDS = [
770
+        "get_temperature",
767 771
         "get_temperature_setpoint", "set_temperature_setpoint",
768
-        "get_boost_state", "trigger_boost",
772
+        "trigger_boost", "trigger_setpoint_to_default"
769 773
     ]
770 774
 
771 775
     def __init__(self, mqtt_client, topic):
772 776
         super().__init__(mqtt_client, topic)
773
-        self.add_callback(self.KEY_TEMPERATURE_SETPOINT, self.print_formatted, None)
774
-        self.add_callback(self.KEY_BOOST_LED, self.print_formatted, None)
777
+        self.add_callback(self.KEY_SETPOINT_TEMP, self.print_formatted, None)
778
+        self.add_callback(self.KEY_TIMER, self.print_formatted, None)
779
+        #
780
+        self.store_data(**{
781
+            self.KEY_TEMPERATURE: 20.7,
782
+            self.KEY_SETPOINT_TEMP: 20,
783
+            self.KEY_TIMER: 0,
784
+        })
775 785
 
776 786
     def __rx__(self, client, userdata, message):
777
-        if message.topic.startswith(self.topic) and message.topic.endswith("/set"):
778
-            payload = payload_filter(message.payload)
779
-            if type(payload) == bool:
780
-                self.store_data(**{self.KEY_BOOST_LED: payload})
787
+        value = payload_filter(message.payload)
788
+        if message.topic.startswith(self.topic) and message.topic.endswith('/set'):
789
+            targetkey = message.topic.split('/')[-2]
790
+            if targetkey in self.data.keys():
791
+                self.store_data(**{targetkey: value})
781 792
             else:
782
-                self.store_data(**{self.KEY_TEMPERATURE_SETPOINT: payload})
783
-        else:
784
-            print(message.topic)
793
+                print("Unknown key %s in %s::%s" % (targetkey, message.topic, self.__class__.__name__))
794
+        elif message.topic == self.topic + '/get':
795
+            self.__tx__(None)
796
+
797
+    def send(self, key, data):
798
+        if data is not None:
799
+            topic = self.topic + '/' + key
800
+            self.mqtt_client.send(topic, json.dumps(data))
785 801
 
786 802
     def command(self, command):
787 803
         try:
@@ -790,27 +806,35 @@ class gui_radiator_valve(base):
790 806
             value = None
791 807
         if command in self.COMMANDS:
792 808
             if command == self.COMMANDS[0]:
793
-                self.print_formatted(self, self.KEY_TEMPERATURE_SETPOINT, self.data.get(self.KEY_TEMPERATURE_SETPOINT))
809
+                self.print_formatted(self, self.KEY_TEMPERATURE, self.data.get(self.KEY_TEMPERATURE))
794 810
             elif command == self.COMMANDS[1]:
795
-                ###################################  TEMPORARY!!!  ###################################
796
-                self.mqtt_client.send(self.topic + "/feedback/set", command_float_value(value))
797
-                ###################################  TEMPORARY!!!  ###################################
811
+                self.print_formatted(self, self.KEY_SETPOINT_TEMP, self.data.get(self.KEY_SETPOINT_TEMP))
798 812
             elif command == self.COMMANDS[2]:
799
-                self.print_formatted(self, self.KEY_BOOST_LED, self.data.get(self.KEY_BOOST_LED))
813
+                self.send(self.KEY_SETPOINT_TEMP, command_float_value(value))
800 814
             elif command == self.COMMANDS[3]:
801
-                ###################################  TEMPORARY!!!  ###################################
802
-                self.mqtt_client.send(self.topic + "/state", json.dumps(True))
803
-                ###################################  TEMPORARY!!!  ###################################
815
+                self.send(self.KEY_BOOST, True)
816
+            elif command == self.COMMANDS[4]:
817
+                self.send(self.KEY_SETPOINT_TO_DEFAULT, True)
804 818
 
805 819
     def print_formatted(self, device, key, value):
806 820
         devicename = ' - '.join(self.topic.split('/')[1:])
807
-        if key == self.KEY_BOOST_LED:
808
-            led = green_led() if value else grey_led()
809
-            print(10 * ' ' + led + 9 * ' ' + COLOR_GUI_ACTIVE + devicename + " (Boost)" + colored.attr("reset"))
810
-        elif key == self.KEY_TEMPERATURE_SETPOINT:
811
-            perc = 100 * (value - self.TEMP_RANGE[0]) / (self.TEMP_RANGE[1] - self.TEMP_RANGE[0])
821
+        if key in [self.KEY_TEMPERATURE, self.KEY_SETPOINT_TEMP, self.KEY_TIMER]:
822
+            if key in [self.KEY_TEMPERATURE, self.KEY_SETPOINT_TEMP]:
823
+                perc = 100 * (value - self.TEMP_RANGE[0]) / (self.TEMP_RANGE[1] - self.TEMP_RANGE[0])
824
+                info = " (Temperature)" if key == self.KEY_TEMPERATURE else " (Setpoint)"
825
+            else:
826
+                try:
827
+                    perc = 100 * value / 60
828
+                except TypeError:
829
+                    value = 0
830
+                    perc = 0
831
+                info = " (Timer)"
812 832
             perc = 100 if perc > 100 else perc
813 833
             perc = 0 if perc < 0 else perc
814
-            sys.stdout.write(COLOR_GUI_ACTIVE + '\u03d1' + percent_bar(perc))
815
-            sys.stdout.write("%4.1f°C" % value + 3 * " ")
816
-            print(devicename + colored.attr("reset"))
834
+
835
+            sys.stdout.write(COLOR_GUI_ACTIVE)
836
+            if key == self.KEY_TIMER:
837
+                sys.stdout.write('T' + percent_bar(perc) + "%4.1fmin" % value + 2 * " ")
838
+            else:
839
+                sys.stdout.write('\u03d1' + percent_bar(perc) + "%4.1f°C" % value + 3 * " ")
840
+            print(devicename + info + colored.attr("reset"))

+ 2
- 4
__simulation__/rooms.py View File

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

+ 54
- 83
devices/__init__.py View File

@@ -186,41 +186,6 @@ class base(dict):
186 186
         return self.__previous__.get(key)
187 187
 
188 188
 
189
-class nodered_gui_leds(base):
190
-    KEY_LED_0 = "led0"
191
-    KEY_LED_1 = "led1"
192
-    KEY_LED_2 = "led2"
193
-    KEY_LED_3 = "led3"
194
-    KEY_LED_4 = "led4"
195
-    KEY_LED_5 = "led5"
196
-    KEY_LED_6 = "led6"
197
-    KEY_LED_7 = "led7"
198
-    KEY_LED_8 = "led8"
199
-    KEY_LED_9 = "led9"
200
-    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]
201
-    #
202
-    TX_TYPE = base.TX_VALUE
203
-
204
-    def set_led(self, key, data):
205
-        """data: [True, False]"""
206
-        self.logger.debug("Sending %s with content %s", key, str(data))
207
-        self.pack(key, data)
208
-
209
-
210
-class nodered_gui_timer(base):
211
-    KEY_TIMER = "timer"
212
-    #
213
-    TX_TYPE = base.TX_VALUE
214
-
215
-    def set_timer(self, data):
216
-        """data: numeric"""
217
-        self.pack(self.KEY_TIMER, data)
218
-
219
-    def set_timer_mcb(self, device, key, data):
220
-        self.logger.debug("Sending %s with content %s", key, str(data))
221
-        self.set_timer(data)
222
-
223
-
224 189
 class shelly(base):
225 190
     KEY_OUTPUT_0 = "relay/0"
226 191
     KEY_OUTPUT_1 = "relay/1"
@@ -649,61 +614,39 @@ class tradfri_button(base):
649 614
         return "Low battery level detected for %s. Battery level was %.0f%%." % (self.topic, self.get(self.KEY_BATTERY))
650 615
 
651 616
 
652
-class nodered_gui_heatvalve(base):
653
-    KEY_FEEDBACK = "feedback"
654
-    KEY_ENABLE = "enable"
655
-    KEY_STATE = "state"
656
-    KEY_BRIGHTNESS = "brightness"
657
-    KEY_COLOR_TEMP = "color_temp"
658
-    KEY_HEATING_BOOST = "heating_boost"
659
-    KEY_HEATING_SETPOINT = "heating_setpoint"
660
-    KEY_OFF_BUTTON = "off_button"
617
+class nodered_gui_leds(base):
618
+    KEY_LED_0 = "led0"
619
+    KEY_LED_1 = "led1"
620
+    KEY_LED_2 = "led2"
621
+    KEY_LED_3 = "led3"
622
+    KEY_LED_4 = "led4"
623
+    KEY_LED_5 = "led5"
624
+    KEY_LED_6 = "led6"
625
+    KEY_LED_7 = "led7"
626
+    KEY_LED_8 = "led8"
627
+    KEY_LED_9 = "led9"
628
+    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]
661 629
     #
662 630
     TX_TYPE = base.TX_VALUE
663
-    #
664
-    RX_KEYS = [KEY_STATE, KEY_BRIGHTNESS, KEY_COLOR_TEMP, KEY_HEATING_BOOST, KEY_HEATING_SETPOINT, KEY_OFF_BUTTON]
665
-
666
-    def __init__(self, mqtt_client, topic):
667
-        super().__init__(mqtt_client, topic)
668
-
669
-    #
670
-    # RX
671
-    #
672
-    @property
673
-    def state(self):
674
-        """rv: [True, False]"""
675
-        return self.get(self.KEY_STATE)
676 631
 
677
-    @property
678
-    def brightness(self):
679
-        """rv: [0, ..., 100]"""
680
-        return self.get(self.KEY_BRIGHTNESS)
681
-
682
-    @property
683
-    def color_temp(self):
684
-        """rv: [0, ..., 100]"""
685
-        return self.get(self.KEY_COLOR_TEMP)
632
+    def set_led(self, key, data):
633
+        """data: [True, False]"""
634
+        self.logger.debug("Sending %s with content %s", key, str(data))
635
+        self.pack(key, data)
686 636
 
687
-    @property
688
-    def heating_boost(self):
689
-        """rv: [True, False]"""
690
-        return self.get(self.KEY_HEATING_BOOST)
691 637
 
692
-    @property
693
-    def heating_(self):
694
-        """rv: [5, ..., 30]"""
695
-        return self.get(self.KEY_HEATING_SETPOINT)
638
+class nodered_gui_timer(base):
639
+    KEY_TIMER = "timer"
640
+    #
641
+    TX_TYPE = base.TX_VALUE
696 642
 
697
-    @property
698
-    def off_button(self):
699
-        """rv: [True, False]"""
700
-        return self.get(self.KEY_OFF_BUTTON)
643
+    def set_timer(self, data):
644
+        """data: numeric"""
645
+        self.pack(self.KEY_TIMER, data)
701 646
 
702
-    #
703
-    # TX
704
-    #
705
-    def set_feedback(self, data):
706
-        self.pack(self.KEY_FEEDBACK, data)
647
+    def set_timer_mcb(self, device, key, data):
648
+        self.logger.debug("Sending %s with content %s", key, str(data))
649
+        self.set_timer(data)
707 650
 
708 651
 
709 652
 class nodered_gui_button(base):
@@ -790,6 +733,34 @@ class nodered_gui_light(nodered_gui_switch, nodered_gui_leds, nodered_gui_timer)
790 733
         self.set_color_temp(data)
791 734
 
792 735
 
736
+class nodered_gui_radiator(nodered_gui_timer):
737
+    KEY_TEMPERATURE = "temperature"
738
+    KEY_SETPOINT_TEMP = "setpoint_temp"
739
+    KEY_SETPOINT_TO_DEFAULT = "setpoint_to_default"
740
+    KEY_BOOST = 'boost'
741
+    #
742
+    RX_KEYS = [KEY_TEMPERATURE, KEY_SETPOINT_TEMP, KEY_SETPOINT_TO_DEFAULT, KEY_BOOST]
743
+
744
+    #
745
+    # TX
746
+    #
747
+    def set_temperature(self, data):
748
+        """data: [True, False]"""
749
+        self.pack(self.KEY_TEMPERATURE, data)
750
+
751
+    def set_temperature_mcb(self, device, key, data):
752
+        self.logger.debug("Sending %s with content %s", key, str(data))
753
+        self.set_temperature(data)
754
+
755
+    def set_setpoint_temperature(self, data):
756
+        """data: [True, False]"""
757
+        self.pack(self.KEY_SETPOINT_TEMP, data)
758
+
759
+    def set_setpoint_temperature_mcb(self, device, key, data):
760
+        self.logger.debug("Sending %s with content %s", key, str(data))
761
+        self.set_setpoint_temperature(data)
762
+
763
+
793 764
 class brennenstuhl_heatingvalve(base):
794 765
     KEY_LINKQUALITY = "linkquality"
795 766
     KEY_BATTERY = "battery"

+ 0
- 12
function/__init__.py View File

@@ -6,7 +6,6 @@ from function.stairway import stairway
6 6
 from function.ground_floor_west import ground_floor_west_floor, ground_floor_west_marion, ground_floor_west_dirk
7 7
 from function.first_floor_west import first_floor_west_julian, first_floor_west_living
8 8
 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
9
-from function.common import common_heating, common_circulation_pump
10 9
 import inspect
11 10
 import logging
12 11
 
@@ -16,9 +15,6 @@ except ImportError:
16 15
     ROOT_LOGGER_NAME = 'root'
17 16
 logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
18 17
 
19
-# TODO: implement devices.nodered_gui_heatvalve incl. setpoint, boost, ... + replace led with timer
20
-# TODO: improve heating function (away mode (reduced setpoint), return to default button, default values in config)
21
-# TODO: improve devices.brennenstuhl_heatvalve
22 18
 # TODO: implement garland (incl. day events like sunset, sunrise, ...)
23 19
 # TODO: implement warning message
24 20
 
@@ -28,9 +24,6 @@ class all_functions(object):
28 24
         self.mqtt_client = mqtt_client
29 25
         #
30 26
         self.__devices__ = None
31
-        # heating and warm water
32
-        self.common_ffe_heat_sleep = common_heating(self.mqtt_client)
33
-        self.common_circulation_pump = common_circulation_pump(self.mqtt_client)
34 27
         # stairway
35 28
         self.stw_stairway = stairway(self.mqtt_client)
36 29
         # ground floor west
@@ -51,8 +44,6 @@ class all_functions(object):
51 44
         #
52 45
         # cross_room_interactions
53 46
         self.init_cross_room_interactions()
54
-        # Circulation pump
55
-        self.init_circulation_pump()
56 47
         # Off Buttons
57 48
         self.init_off_functionality()
58 49
 
@@ -117,9 +108,6 @@ class all_functions(object):
117 108
         self.ffe_sleep.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION,
118 109
                                                    devices.tradfri_button.ACTION_RIGHT, self.ffe_floor.main_light_shelly.toggle_output_0_mcb)
119 110
 
120
-    def init_circulation_pump(self):
121
-        self.common_circulation_pump.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.ffe_kitchen.flash_main_light)
122
-
123 111
     def gfw_dirk_input_1(self, device, key, data):
124 112
         if self.last_gfw_dirk_input_1 is not None:
125 113
             if self.last_gfw_dirk_input_1 != data:

+ 0
- 57
function/common.py View File

@@ -1,57 +0,0 @@
1
-#!/usr/bin/env python
2
-# -*- coding: utf-8 -*-
3
-#
4
-
5
-import config
6
-import devices
7
-from function.rooms import room_shelly
8
-from function.modules import heating_function_brennenstuhl
9
-import logging
10
-import task
11
-
12
-try:
13
-    from config import APP_NAME as ROOT_LOGGER_NAME
14
-except ImportError:
15
-    ROOT_LOGGER_NAME = 'root'
16
-logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
17
-
18
-
19
-class common_circulation_pump(room_shelly):
20
-    def __init__(self, mqtt_client):
21
-        # http://shelly1-E89F6D85A466
22
-        super().__init__(mqtt_client, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_SHELLY, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_GUI)
23
-        #
24
-        self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.circ_pump_actions, True)
25
-        #
26
-        self.gui_main_light.set_timer('-')
27
-        #
28
-        self.ct = task.periodic(6, self.cyclic_task)
29
-        self.pump_timer = None
30
-        #
31
-        self.ct.run()
32
-
33
-    def circ_pump_actions(self, device, key, data):
34
-        if data is True:
35
-            self.pump_timer = 10
36
-            self.gui_main_light.set_timer(self.pump_timer)
37
-        else:
38
-            self.pump_timer = None
39
-            self.gui_main_light.set_timer('-')
40
-
41
-    def cyclic_task(self, rt):
42
-        if self.pump_timer is not None:
43
-            if self.pump_timer <= 0:
44
-                self.pump_timer = None
45
-                self.gui_main_light.set_timer('-')
46
-            else:
47
-                self.gui_main_light.set_timer(self.pump_timer)
48
-                self.pump_timer -= self.ct.cycle_time / 60
49
-
50
-
51
-class common_heating(object):
52
-    def __init__(self, mqtt_client):
53
-        self.ffe_heating_sleep_madi = heating_function_brennenstuhl(
54
-            mqtt_client, "zigbee/ffe/sleep/radiator_valve", 20, "gui/ffe_bo_sleep_madi", "gui/ffe_ts_sleep_madi", "gui/ffe_bl_sleep_madi")
55
-
56
-    def all_off(self):
57
-        pass    # dummy method for compatibility reasons

+ 13
- 4
function/first_floor_east.py View File

@@ -4,7 +4,7 @@
4 4
 
5 5
 import config
6 6
 import devices
7
-from function.modules import brightness_choose_n_action
7
+from function.modules import brightness_choose_n_action, circulation_pump, radiator_function
8 8
 import logging
9 9
 from function.rooms import room_shelly, room_shelly_motion_sensor, room_shelly_tradfri_light
10 10
 try:
@@ -24,6 +24,13 @@ class first_floor_east_kitchen(room_shelly):
24 24
     def __init__(self, mqtt_client):
25 25
         # http://shelly1l-8CAAB5616C01
26 26
         super().__init__(mqtt_client, config.TOPIC_FFE_KITCHEN_MAIN_LIGHT_SHELLY, config.TOPIC_FFE_KITCHEN_MAIN_LIGHT_GUI)
27
+        #
28
+        self.circulation_pump = circulation_pump(mqtt_client)
29
+        self.circulation_pump.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.flash_main_light)
30
+
31
+    def all_off(self, device=None, key=None, data=None):
32
+        self.circulation_pump.all_off(device, key, data)
33
+        return super().all_off(device, key, data)
27 34
 
28 35
 
29 36
 class first_floor_east_dining(room_shelly):
@@ -53,16 +60,18 @@ class first_floor_east_sleep(room_shelly_tradfri_light):
53 60
     def __init__(self, mqtt_client):
54 61
         # http://shelly1l-E8DB84A254C7
55 62
         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)
56
-        #
63
+        # bed light
57 64
         self.bed_light_di_tradfri = devices.tradfri_light(mqtt_client, config.TOPIC_FFE_SLEEP_BED_LIGHT_DI_ZIGBEE)
58
-        #
59 65
         self.gui_bed_light_di = devices.nodered_gui_light(mqtt_client, config.TOPIC_FFE_SLEEP_BED_LIGHT_DI_GUI)
60 66
         #
61 67
         self.button_tradfri = devices.tradfri_button(mqtt_client, config.TOPIC_FFE_SLEEP_INPUT_DEVICE)
62
-        #
68
+        # button / brightness function
63 69
         self.brightness_functions = brightness_choose_n_action(mqtt_client, self.button_tradfri, config.TOPIC_FFE_SLEEP_DEVICE_CHOOSER_LED)
64 70
         self.brightness_functions.add(self.main_light_tradfri, self.main_light_shelly, devices.shelly.KEY_OUTPUT_0)
65 71
         self.brightness_functions.add(self.bed_light_di_tradfri, self.bed_light_di_tradfri, devices.tradfri_light.KEY_OUTPUT_0)
72
+        # radiator valve
73
+        self.radiator_function = radiator_function(mqtt_client, config.TOPIC_FFE_SLEEP_RADIATOR_VALVE_ZIGBEE,
74
+                                                   config.TOPIC_FFE_SLEEP_RADIATOR_VALVE_GUI, config.DEFAULT_TEMPERATURE_FFE_SLEEP)
66 75
         #
67 76
         # Callback initialisation
68 77
         #

+ 82
- 59
function/modules.py View File

@@ -2,7 +2,9 @@
2 2
 # -*- coding: utf-8 -*-
3 3
 #
4 4
 
5
+import config
5 6
 import devices
7
+from function.rooms import room_shelly
6 8
 import logging
7 9
 import task
8 10
 
@@ -100,73 +102,94 @@ class brightness_choose_n_action(object):
100 102
                 target.default_stop()
101 103
 
102 104
 
103
-class heating_function_brennenstuhl(object):
104
-    RETURN_TO_DEFAULT_TIME = 45 * 60
105
-    BOOST_TEMP_OFFSET = 5
106
-
107
-    def __init__(self, mqtt_client, topic_valve, default_temperature, topic_boost, topic_setpoint, topic_led):
108
-        self.ct = task.periodic(1, self.cyclic_task)
105
+class circulation_pump(room_shelly):
106
+    def __init__(self, mqtt_client):
107
+        super().__init__(mqtt_client, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_SHELLY, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_GUI)
109 108
         #
110
-        self.topic = topic_valve
111
-        self.default_temperature = default_temperature
109
+        self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.circ_pump_actions, True)
112 110
         #
113
-        self.heating_valve = devices.brennenstuhl_heatingvalve(mqtt_client, topic_valve)
114
-        self.heating_valve.set_heating_setpoint(self.default_temperature)
115
-        self.heating_valve.add_callback(
116
-            devices.brennenstuhl_heatingvalve.KEY_HEATING_SETPOINT, None, self.heating_setpoint_actions)
111
+        self.gui_main_light.set_timer('-')
112
+        #
113
+        self.ct = task.periodic(6, self.cyclic_task)
114
+        self.pump_timer = None
115
+        #
116
+        self.ct.run()
117 117
 
118
-        self.gui_value_temp_setp = devices.nodered_gui_heatvalve(mqtt_client, topic_setpoint)
119
-        self.gui_value_temp_setp.add_callback(
120
-            devices.nodered_gui_heatvalve.KEY_HEATING_SETPOINT, None, self.heating_setpoint_actions)
118
+    def circ_pump_actions(self, device, key, data):
119
+        if data is True:
120
+            self.pump_timer = 10
121
+            self.gui_main_light.set_timer(self.pump_timer)
122
+        else:
123
+            self.pump_timer = None
124
+            self.gui_main_light.set_timer('-')
121 125
 
122
-        self.gui_button_boost = devices.nodered_gui_heatvalve(mqtt_client, topic_boost)
123
-        self.gui_button_boost.add_callback(None, None, self.boost_actions)
126
+    def cyclic_task(self, rt):
127
+        if self.pump_timer is not None:
128
+            if self.pump_timer <= 0:
129
+                self.pump_timer = None
130
+                self.gui_main_light.set_timer('-')
131
+            else:
132
+                self.gui_main_light.set_timer(self.pump_timer)
133
+                self.pump_timer -= self.ct.cycle_time / 60
124 134
 
125
-        self.gui_led_boost = devices.nodered_gui_heatvalve(mqtt_client, topic_led)
126 135
 
136
+# TODO:
137
+# - improve devices.brennenstuhl_heatingvalve (at least switch on for boost) and use boost in heating_function.boost_mcb
138
+# - implement modules.heating_function
139
+#         * Central switch incl. central parameter storage for state (summer mode, away_mode - each switch activation disables the other switch)
140
+class radiator_function(object):
141
+    def __init__(self, mqtt_client, topic_valve, topic_gui, default_temperature):
142
+        self.default_temperature = default_temperature
143
+        self.regular_temp_setpoint = self.default_temperature
127 144
         #
128
-        self.return_to_default_timer = None
129
-        self.return_to_default_setpoint = None
130
-        self.gui_led_boost.set_feedback(False)
145
+        self.ct = task.periodic(1, self.cyclic_task)
146
+        #
147
+        self.heating_valve = devices.brennenstuhl_heatingvalve(mqtt_client, topic_valve)
148
+        self.gui_heating = devices.nodered_gui_radiator(mqtt_client, topic_gui)
149
+        #
150
+        self.heating_valve.set_heating_setpoint(self.default_temperature)
151
+        self.heating_valve.add_callback(devices.brennenstuhl_heatingvalve.KEY_TEMPERATURE, None, self.gui_heating.set_temperature_mcb)
152
+        self.heating_valve.add_callback(devices.brennenstuhl_heatingvalve.KEY_HEATING_SETPOINT, None, self.gui_heating.set_setpoint_temperature_mcb)
153
+        self.heating_valve.add_callback(devices.brennenstuhl_heatingvalve.KEY_HEATING_SETPOINT, None, self.store_regular_setpoint)
154
+        #
155
+        self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_SETPOINT_TEMP, None, self.heating_valve.set_heating_setpoint_mcb)
156
+        self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_BOOST, None, self.boost_mcb)
157
+        self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_SETPOINT_TO_DEFAULT, None, self.setpoint_to_default_mcb)
158
+        self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_SETPOINT_TEMP, None, self.cancel_boost)
159
+        self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_SETPOINT_TO_DEFAULT, None, self.cancel_boost)
160
+        #
161
+        self.boost_timer = None
131 162
         #
132 163
         self.ct.run()
133 164
 
134
-    def heating_setpoint_actions(self, device, key, data):
135
-        if device.topic == self.heating_valve.topic:
136
-            # valve setpoint action
137
-            self.gui_value_temp_setp.set_feedback(data)
138
-            if data > self.default_temperature:
139
-                if data != self.return_to_default_setpoint:
140
-                    logger.info('Got heating setpoint (%.1f°C) \"%s\" with deviation to the default value (%.1f°C). Starting timer for returning to default.',
141
-                                data, self.topic, self.default_temperature)
142
-                    self.return_to_default_timer = self.RETURN_TO_DEFAULT_TIME
143
-                    self.return_to_default_setpoint = data
144
-                    self.gui_led_boost.set_feedback(True)
145
-            else:
146
-                if self.return_to_default_timer is not None:
147
-                    logger.info('Deleting timer \"%s\" for returning to default.', self.topic)
148
-                self.return_to_default_timer = None
149
-                self.return_to_default_setpoint = None
150
-                self.gui_led_boost.set_feedback(False)
151
-        elif device.topic == self.gui_value_temp_setp.topic:
152
-            # user setpoint action
153
-            logger.info('Setpoint change \"%s\" to %.1f°C', self.topic, data)
154
-            self.default_temperature = data
155
-            self.heating_valve.set_heating_setpoint(self.default_temperature)
156
-            self.return_to_default_timer = None
157
-            self.return_to_default_setpoint = None
158
-            self.gui_led_boost.set_feedback(False)
159
-
160
-    def boost_actions(self, davice, key, data):
161
-        logger.info('Starting boost mode \"%s\" with setpoint %.1f°C.', self.topic, self.default_temperature + self.BOOST_TEMP_OFFSET)
162
-        self.heating_valve.set_heating_setpoint(self.default_temperature + self.BOOST_TEMP_OFFSET)
163
-
164 165
     def cyclic_task(self, rt):
165
-        if self.return_to_default_timer is not None:
166
-            self.return_to_default_timer -= self.ct.cycle_time
167
-            if self.return_to_default_timer <= 0:
168
-                logger.info('Return to default timer expired \"%s\".', self.topic)
169
-                self.heating_valve.set_heating_setpoint(self.default_temperature)
170
-                self.return_to_default_timer = None
171
-                self.return_to_default_setpoint = None
172
-                self.gui_led_boost.set_feedback(False)
166
+        if self.boost_timer is not None:
167
+            self.gui_heating.set_timer(round(self.boost_timer / 60, 1))
168
+            #
169
+            self.boost_timer -= self.ct.cycle_time
170
+            if self.boost_timer <= 0:
171
+                self.cancel_boost()
172
+                self.heating_valve.set_heating_setpoint(self.regular_temp_setpoint)
173
+
174
+    def cancel_boost(self, device=None, key=None, data=None):
175
+        if self.boost_timer is not None:
176
+            self.heating_valve.logger.info('Timer expired. returning to regular temperature setpoint %.1f°C.', self.regular_temp_setpoint)
177
+            self.boost_timer = None
178
+            self.gui_heating.set_timer('-')
179
+
180
+    def store_regular_setpoint(self, device, key, data):
181
+        if self.boost_timer is None:
182
+            self.regular_temp_setpoint = data
183
+
184
+    def boost_mcb(self, device, key, data):
185
+        if self.boost_timer is None:
186
+            self.heating_valve.logger.info('Starting boost mode with setpoint %.1f°C.', self.regular_temp_setpoint + 5)
187
+            self.boost_timer = 15*60
188
+            self.heating_valve.set_heating_setpoint(self.regular_temp_setpoint + 5)     # TODO: Change setpoint to "on" if possible
189
+        else:
190
+            self.boost_timer += 15 * 60
191
+        if self.boost_timer > 60 * 60:
192
+            self.boost_timer = 60 * 60
193
+
194
+    def setpoint_to_default_mcb(self, device, key, data):
195
+        self.heating_valve.set_heating_setpoint(self.default_temperature)

+ 1
- 2
function/rooms.py View File

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

Loading…
Cancel
Save