Browse Source

Radiator Functionality improved

tags/v1.0.0
Dirk Alders 2 years ago
parent
commit
045e270a6b
4 changed files with 178 additions and 111 deletions
  1. 95
    88
      __simulation__/devices.py
  2. 29
    1
      devices/__init__.py
  3. 3
    4
      function/ground_floor_west.py
  4. 51
    18
      function/modules.py

+ 95
- 88
__simulation__/devices.py View File

22
         return payload.decode("utf-8")
22
         return payload.decode("utf-8")
23
 
23
 
24
 
24
 
25
-def percent_bar(value):
26
-    rv = ""
27
-    for i in range(0, 10):
28
-        rv += u"\u25ac" if (value - 5) > 10*i else u"\u25ad"
29
-    return rv
30
-
31
-
32
-def green_led():
33
-    return colored.fg('green') + "\u2b24" + colored.attr("reset")
34
-
35
-
36
-def grey_led():
37
-    return colored.fg('light_gray') + "\u2b24" + colored.attr("reset")
38
-
39
-
40
 def command_int_value(value):
25
 def command_int_value(value):
41
     try:
26
     try:
42
         return int(value)
27
         return int(value)
51
         print("You need to give a integer parameter not '%s'" % str(value))
36
         print("You need to give a integer parameter not '%s'" % str(value))
52
 
37
 
53
 
38
 
39
+def devicename(topic):
40
+    return " - ".join(topic.split('/')[1:])
41
+
42
+
43
+def percent_bar(value):
44
+    rv = ""
45
+    for i in range(0, 10):
46
+        rv += u"\u25ac" if (value - 5) > 10*i else u"\u25ad"
47
+    return rv
48
+
49
+
50
+def print_light(color, state, topic, description, led=False):
51
+    if led is True:
52
+        if state is True:
53
+            icon = colored.fg('green') + "\u2b24" + color
54
+        else:
55
+            icon = colored.fg('light_gray') + "\u2b24" + color
56
+    else:
57
+        icon = u'\u2b24' if state is True else u'\u25ef'
58
+    print(color + 10 * ' ' + icon + 9 * ' ' + devicename(topic), description + colored.attr("reset"))
59
+
60
+
61
+def print_switch(color, state, topic, description):
62
+    icon = u'\u25a0' if state is True else u'\u25a1'
63
+    print(color + 10 * ' ' + icon + 9 * ' ' + devicename(topic), description + colored.attr("reset"))
64
+
65
+
66
+def print_percent(color, prefix, perc_value, value_str, topic, description):
67
+    if len(prefix) > 1 or len(value_str) > 7:
68
+        raise ValueError("Length of prefix (%d) > 1 or length of value_str (%d) > 7" % (len(prefix), len(value_str)))
69
+    print(color + prefix + percent_bar(perc_value), value_str + (8 - len(value_str)) * ' ' + devicename(topic), description + colored.attr("reset"))
70
+
71
+
54
 class base(object):
72
 class base(object):
55
     AUTOSEND = True
73
     AUTOSEND = True
56
     COMMANDS = []
74
     COMMANDS = []
226
 
244
 
227
     def print_formatted(self, device, key, value):
245
     def print_formatted(self, device, key, value):
228
         if value is not None:
246
         if value is not None:
229
-            icon = u'\u2b24' if value == "on" else u'\u25ef'
230
             info = (" - %ds" % self.__output_0_auto_off__) if self.__output_0_auto_off__ is not None and value == "on" else ""
247
             info = (" - %ds" % self.__output_0_auto_off__) if self.__output_0_auto_off__ is not None and value == "on" else ""
231
             channel = "(%s%s)" % (self.names.get(key, key), info)
248
             channel = "(%s%s)" % (self.names.get(key, key), info)
232
-            devicename = " - ".join(self.topic.split('/')[1:])
233
-            print(COLOR_SHELLY + 10 * ' ' + icon + 9 * ' ' + devicename + ' ' + channel + colored.attr("reset"))
249
+            print_light(COLOR_SHELLY, value == "on", self.topic, channel)
234
 
250
 
235
 
251
 
236
 class my_powerplug(base):
252
 class my_powerplug(base):
293
 
309
 
294
     def print_formatted(self, device, key, value):
310
     def print_formatted(self, device, key, value):
295
         if value is not None:
311
         if value is not None:
296
-            icon = u'\u2b24' if value else u'\u25ef'
297
-            channel = "(%s)" % self.names.get(key, "Channel %d" % (int(key) + 1))
298
-            devicename = " - ".join(self.topic.split('/')[1:])
299
-            print(COLOR_POWERPLUG + 10 * ' ' + icon + 9 * ' ' + devicename + ' ' + channel + colored.attr("reset"))
312
+            print_light(COLOR_POWERPLUG, value, self.topic, "(%s)" % self.names.get(key, "Channel %d" % (int(key) + 1)))
300
 
313
 
301
 
314
 
302
 class silvercrest_powerplug(base):
315
 class silvercrest_powerplug(base):
340
 
353
 
341
     def print_formatted(self, device, key, value):
354
     def print_formatted(self, device, key, value):
342
         if value is not None:
355
         if value is not None:
343
-            icon = u'\u2b24' if value == "on" else u'\u25ef'
344
-            channel = "(%s)" % self.names.get(key, key)
345
-            devicename = " - ".join(self.topic.split('/')[1:])
346
-            print(COLOR_POWERPLUG + 10 * ' ' + icon + 9 * ' ' + devicename + ' ' + channel + colored.attr("reset"))
356
+            print_light(COLOR_POWERPLUG, value == "on", self.topic, "(%s)" % self.names.get(key, key))
347
 
357
 
348
 
358
 
349
 class silvercrest_motion_sensor(base):
359
 class silvercrest_motion_sensor(base):
372
 
382
 
373
     def print_formatted(self, device, key, value):
383
     def print_formatted(self, device, key, value):
374
         if value is not None:
384
         if value is not None:
375
-            if value:
376
-                print(COLOR_MOTION_SENSOR + 10 * ' ' + u'\u2b24' + 9 * ' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
377
-            else:
378
-                print(COLOR_MOTION_SENSOR + 10 * ' ' + u'\u25ef' + 9 * ' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
385
+            print_light(COLOR_MOTION_SENSOR, value, self.topic, "")
379
 
386
 
380
 
387
 
381
 class tradfri_light(base):
388
 class tradfri_light(base):
480
         if value is not None:
487
         if value is not None:
481
             color = COLOR_LIGHT_ACTIVE
488
             color = COLOR_LIGHT_ACTIVE
482
             if key == self.KEY_STATE:
489
             if key == self.KEY_STATE:
483
-                if value == "on":
484
-                    print(color + 10 * ' ' + u'\u2b24' + 9 * ' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
485
-                else:
486
-                    print(color + 10 * ' ' + u'\u25ef' + 9 * ' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
490
+                print_light(COLOR_LIGHT_ACTIVE, value == "on", self.topic, "")
487
                 self.print_formatted(device, self.KEY_BRIGHTNESS, self.data.get(self.KEY_BRIGHTNESS))
491
                 self.print_formatted(device, self.KEY_BRIGHTNESS, self.data.get(self.KEY_BRIGHTNESS))
488
                 self.print_formatted(device, self.KEY_COLOR_TEMP, self.data.get(self.KEY_COLOR_TEMP))
492
                 self.print_formatted(device, self.KEY_COLOR_TEMP, self.data.get(self.KEY_COLOR_TEMP))
489
             elif key in [self.KEY_BRIGHTNESS, self.KEY_COLOR_TEMP]:
493
             elif key in [self.KEY_BRIGHTNESS, self.KEY_COLOR_TEMP]:
490
-                if self.data.get(self.KEY_STATE) != "on":
491
-                    color = COLOR_LIGHT_PASSIVE
492
-                if key == self.KEY_BRIGHTNESS:
493
-                    value = round(value * 100 / 256, 0)
494
-                else:
495
-                    value = round((value - 250) * 100 / 204, 0)
496
-                sys.stdout.write(color)
497
-                sys.stdout.write('B' if key == gui_light.KEY_BRIGHTNESS else 'C')
498
-                sys.stdout.write(percent_bar(value))
499
-                sys.stdout.write("%3d%%" % value + 5 * " ")
500
-                print(" - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
494
+                perc_value = round(value * 100 / 256, 0) if key == self.KEY_BRIGHTNESS else round((value - 250) * 100 / 204, 0)
495
+                print_percent(
496
+                    COLOR_LIGHT_PASSIVE if self.data.get(self.KEY_STATE) != "on" else COLOR_LIGHT_ACTIVE,
497
+                    'B' if key == gui_light.KEY_BRIGHTNESS else 'C',
498
+                    perc_value,
499
+                    "%3d%%" % perc_value,
500
+                    self.topic,
501
+                    ""
502
+                )
501
 
503
 
502
 
504
 
503
 class gui_light(tradfri_light):
505
 class gui_light(tradfri_light):
576
 
578
 
577
     def print_formatted(self, device, key, value):
579
     def print_formatted(self, device, key, value):
578
         if value is not None:
580
         if value is not None:
579
-            color = COLOR_GUI_ACTIVE
580
             device = " - ".join(self.topic.split('/')[1:])
581
             device = " - ".join(self.topic.split('/')[1:])
581
             if key == self.KEY_STATE:
582
             if key == self.KEY_STATE:
582
-                if value == True:
583
-                    print(color + 10 * ' ' + u'\u25a0' + 9 * ' ' + device + colored.attr("reset"))
584
-                else:
585
-                    print(color + 10 * ' ' + u'\u25a1' + 9 * ' ' + device + colored.attr("reset"))
583
+                print_switch(COLOR_GUI_ACTIVE, value, self.topic, "")
586
             elif key == self.KEY_ENABLE:
584
             elif key == self.KEY_ENABLE:
587
                 self.print_formatted(device, self.KEY_BRIGHTNESS, self.data.get(self.KEY_BRIGHTNESS))
585
                 self.print_formatted(device, self.KEY_BRIGHTNESS, self.data.get(self.KEY_BRIGHTNESS))
588
                 self.print_formatted(device, self.KEY_COLOR_TEMP, self.data.get(self.KEY_COLOR_TEMP))
586
                 self.print_formatted(device, self.KEY_COLOR_TEMP, self.data.get(self.KEY_COLOR_TEMP))
589
             elif key in [self.KEY_BRIGHTNESS, self.KEY_COLOR_TEMP]:
587
             elif key in [self.KEY_BRIGHTNESS, self.KEY_COLOR_TEMP]:
590
-                if not self.data.get(self.KEY_ENABLE, False):
591
-                    color = COLOR_GUI_PASSIVE
592
-                value = round(value * 10 if key == self.KEY_COLOR_TEMP else value, 0)
593
-                sys.stdout.write(color)
594
-                sys.stdout.write('B' if key == self.KEY_BRIGHTNESS else 'C')
595
-                sys.stdout.write(percent_bar(value))
596
-                print("%3d%%" % value + 5 * " " + device + colored.attr("reset"))
588
+                perc_value = round(value * 10 if key == self.KEY_COLOR_TEMP else value, 0)
589
+                print_percent(
590
+                    COLOR_GUI_PASSIVE if not self.data.get(self.KEY_ENABLE, False) else COLOR_GUI_ACTIVE,
591
+                    'B' if key == self.KEY_BRIGHTNESS else 'C',
592
+                    perc_value,
593
+                    "%3d%%" % perc_value,
594
+                    self.topic,
595
+                    ""
596
+                )
597
             elif key == self.KEY_TIMER:
597
             elif key == self.KEY_TIMER:
598
                 if isinstance(value, (int, float, complex)) and not isinstance(value, bool):
598
                 if isinstance(value, (int, float, complex)) and not isinstance(value, bool):
599
                     if self.maxvalue is None:
599
                     if self.maxvalue is None:
606
                     self.maxvalue = None
606
                     self.maxvalue = None
607
                     self.last_printed = None
607
                     self.last_printed = None
608
                 if self.last_printed is None or abs(self.last_printed - perc) >= 4.95:
608
                 if self.last_printed is None or abs(self.last_printed - perc) >= 4.95:
609
-                    print(color + 't' + percent_bar(perc) + '%3d%%' % perc + 5 * ' ' + device + ' (%.1f)' % disp_value + colored.attr('reset'))
609
+                    print_percent(COLOR_GUI_ACTIVE, 't', perc, '%3d%%' % perc, self.topic, '(%.1f)' % disp_value)
610
                     self.last_printed = perc
610
                     self.last_printed = perc
611
             elif key.startswith(self.KEY_LED_X[:-2]):
611
             elif key.startswith(self.KEY_LED_X[:-2]):
612
-                led = green_led() if value else grey_led()
613
-                ledname = '(%s)' % self.led_names.get(key, key)
614
-                devicename = ' - '.join(self.topic.split('/')[1:])
615
-                print(10 * ' ' + led + 9 * ' ' + COLOR_GUI_ACTIVE + devicename + ' ' + ledname + colored.attr("reset"))
612
+                print_light(COLOR_GUI_ACTIVE, value, self.topic, '(%s)' % self.led_names.get(key, key), True)
616
 
613
 
617
 
614
 
618
 class tradfri_button(base):
615
 class tradfri_button(base):
686
                 print("Unknown key %s in %s" % (targetkey, self.__class__.__name__))
683
                 print("Unknown key %s in %s" % (targetkey, self.__class__.__name__))
687
 
684
 
688
     def print_formatted(self, device, key, value):
685
     def print_formatted(self, device, key, value):
689
-        led = green_led() if value else grey_led()
690
-        channel = '(%s)' % self.names.get(key, key)
691
-        devicename = ' - '.join(self.topic.split('/')[1:])
692
-        print(10 * ' ' + led + 9 * ' ' + COLOR_GUI_ACTIVE + devicename + ' ' + channel + colored.attr("reset"))
686
+        print_light(COLOR_GUI_ACTIVE, value, self.topic, '(%s)' % self.names.get(key, key), True)
693
 
687
 
694
 
688
 
695
 class remote(base):
689
 class remote(base):
750
             perc = 100 * (value - self.TEMP_RANGE[0]) / (self.TEMP_RANGE[1] - self.TEMP_RANGE[0])
744
             perc = 100 * (value - self.TEMP_RANGE[0]) / (self.TEMP_RANGE[1] - self.TEMP_RANGE[0])
751
             perc = 100 if perc > 100 else perc
745
             perc = 100 if perc > 100 else perc
752
             perc = 0 if perc < 0 else perc
746
             perc = 0 if perc < 0 else perc
753
-            sys.stdout.write(COLOR_RADIATOR_VALVE + '\u03d1' + percent_bar(perc))
754
-            sys.stdout.write("%4.1f°C" % value + 3 * " ")
755
-            print(devicename + colored.attr("reset"))
747
+            print_percent(COLOR_RADIATOR_VALVE, '\u03d1', perc, "%4.1f°C" % value, self.topic, "")
756
 
748
 
757
 
749
 
758
 class gui_radiator_valve(base):
750
 class gui_radiator_valve(base):
765
     KEY_SETPOINT_TEMP = "setpoint_temp"
757
     KEY_SETPOINT_TEMP = "setpoint_temp"
766
     KEY_SETPOINT_TO_DEFAULT = "setpoint_to_default"
758
     KEY_SETPOINT_TO_DEFAULT = "setpoint_to_default"
767
     KEY_BOOST = 'boost'
759
     KEY_BOOST = 'boost'
760
+    KEY_AWAY = "away"
761
+    KEY_SUMMER = "summer"
762
+    KEY_ENABLE = "enable"
768
     #
763
     #
769
     COMMANDS = [
764
     COMMANDS = [
770
         "get_temperature",
765
         "get_temperature",
771
         "get_temperature_setpoint", "set_temperature_setpoint",
766
         "get_temperature_setpoint", "set_temperature_setpoint",
772
-        "trigger_boost", "trigger_setpoint_to_default"
767
+        "trigger_boost", "trigger_setpoint_to_default",
768
+        "toggle_away", "toggle_summer",
773
     ]
769
     ]
774
 
770
 
775
     def __init__(self, mqtt_client, topic):
771
     def __init__(self, mqtt_client, topic):
776
         super().__init__(mqtt_client, topic)
772
         super().__init__(mqtt_client, topic)
777
         self.add_callback(self.KEY_SETPOINT_TEMP, self.print_formatted, None)
773
         self.add_callback(self.KEY_SETPOINT_TEMP, self.print_formatted, None)
778
         self.add_callback(self.KEY_TIMER, self.print_formatted, None)
774
         self.add_callback(self.KEY_TIMER, self.print_formatted, None)
775
+        self.add_callback(self.KEY_AWAY, self.print_formatted, None)
776
+        self.add_callback(self.KEY_SUMMER, self.print_formatted, None)
779
         #
777
         #
780
         self.store_data(**{
778
         self.store_data(**{
781
             self.KEY_TEMPERATURE: 20.7,
779
             self.KEY_TEMPERATURE: 20.7,
782
             self.KEY_SETPOINT_TEMP: 20,
780
             self.KEY_SETPOINT_TEMP: 20,
783
             self.KEY_TIMER: 0,
781
             self.KEY_TIMER: 0,
782
+            self.KEY_AWAY: False,
783
+            self.KEY_SUMMER: False,
784
+            self.KEY_ENABLE: True
784
         })
785
         })
785
 
786
 
786
     def __rx__(self, client, userdata, message):
787
     def __rx__(self, client, userdata, message):
815
                 self.send(self.KEY_BOOST, True)
816
                 self.send(self.KEY_BOOST, True)
816
             elif command == self.COMMANDS[4]:
817
             elif command == self.COMMANDS[4]:
817
                 self.send(self.KEY_SETPOINT_TO_DEFAULT, True)
818
                 self.send(self.KEY_SETPOINT_TO_DEFAULT, True)
819
+            elif command == self.COMMANDS[5]:
820
+                self.send(self.KEY_AWAY, not self.data.get(self.KEY_AWAY))
821
+            elif command == self.COMMANDS[6]:
822
+                self.send(self.KEY_SUMMER, not self.data.get(self.KEY_SUMMER))
818
 
823
 
819
     def print_formatted(self, device, key, value):
824
     def print_formatted(self, device, key, value):
820
         devicename = ' - '.join(self.topic.split('/')[1:])
825
         devicename = ' - '.join(self.topic.split('/')[1:])
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)"
826
+        if key == self.KEY_TIMER:
827
+            try:
828
+                perc = 100 * value / 60
829
+            except TypeError:
830
+                value = 0
831
+                perc = 0
832
+            print_percent(COLOR_GUI_ACTIVE, 'T', perc, "%4.1fmin" % value, self.topic, "(Timer)")
833
+        elif key == self.KEY_TEMPERATURE:
834
+            perc = 100 * (value - self.TEMP_RANGE[0]) / (self.TEMP_RANGE[1] - self.TEMP_RANGE[0])
832
             perc = 100 if perc > 100 else perc
835
             perc = 100 if perc > 100 else perc
833
             perc = 0 if perc < 0 else perc
836
             perc = 0 if perc < 0 else perc
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"))
837
+            print_percent(COLOR_GUI_ACTIVE, '\u03d1', perc, "%4.1f°C" % value, self.topic, "(Temperature)")
838
+        elif key == self.KEY_SETPOINT_TEMP:
839
+            perc = 100 * (value - self.TEMP_RANGE[0]) / (self.TEMP_RANGE[1] - self.TEMP_RANGE[0])
840
+            perc = 100 if perc > 100 else perc
841
+            perc = 0 if perc < 0 else perc
842
+            print_percent(COLOR_GUI_ACTIVE if self.data.get(self.KEY_ENABLE) else COLOR_GUI_PASSIVE,
843
+                          '\u03d1', perc, "%4.1f°C" % value, self.topic, "(Setpoint)")
844
+        elif key == self.KEY_AWAY:
845
+            print_switch(COLOR_GUI_ACTIVE, value, self.topic, "(Away Mode)")
846
+        elif key == self.KEY_SUMMER:
847
+            print_switch(COLOR_GUI_ACTIVE, value, self.topic, "(Summer Mode)")

+ 29
- 1
devices/__init__.py View File

738
     KEY_SETPOINT_TEMP = "setpoint_temp"
738
     KEY_SETPOINT_TEMP = "setpoint_temp"
739
     KEY_SETPOINT_TO_DEFAULT = "setpoint_to_default"
739
     KEY_SETPOINT_TO_DEFAULT = "setpoint_to_default"
740
     KEY_BOOST = 'boost'
740
     KEY_BOOST = 'boost'
741
+    KEY_AWAY = "away"
742
+    KEY_SUMMER = "summer"
743
+    KEY_ENABLE = "enable"
741
     #
744
     #
742
-    RX_KEYS = [KEY_TEMPERATURE, KEY_SETPOINT_TEMP, KEY_SETPOINT_TO_DEFAULT, KEY_BOOST]
745
+    RX_KEYS = [KEY_TEMPERATURE, KEY_SETPOINT_TEMP, KEY_SETPOINT_TO_DEFAULT, KEY_BOOST, KEY_AWAY, KEY_SUMMER]
746
+
747
+    def __init__(self, mqtt_client, topic):
748
+        super().__init__(mqtt_client, topic)
749
+        self[self.KEY_ENABLE] = True
750
+        self.add_callback(self.KEY_AWAY, None, self.enable_gui)
751
+        self.add_callback(self.KEY_SUMMER, None, self.enable_gui)
752
+
753
+    def enable_gui(self, device, key, data):
754
+        self.pack(self.KEY_ENABLE, not self.get(self.KEY_AWAY) and not self.get(self.KEY_SUMMER))
743
 
755
 
744
     #
756
     #
745
     # TX
757
     # TX
760
         self.logger.debug("Sending %s with content %s", key, str(data))
772
         self.logger.debug("Sending %s with content %s", key, str(data))
761
         self.set_setpoint_temperature(data)
773
         self.set_setpoint_temperature(data)
762
 
774
 
775
+    def set_away(self, data):
776
+        """data: [True, False]"""
777
+        self.pack(self.KEY_AWAY, data)
778
+
779
+    def set_away_mcb(self, device, key, data):
780
+        self.logger.debug("Sending %s with content %s", key, str(data))
781
+        self.set_away(data)
782
+
783
+    def set_summer(self, data):
784
+        """data: [True, False]"""
785
+        self.pack(self.KEY_SUMMER, data)
786
+
787
+    def set_summer_mcb(self, device, key, data):
788
+        self.logger.debug("Sending %s with content %s", key, str(data))
789
+        self.set_summer(data)
790
+
763
 
791
 
764
 class brennenstuhl_heatingvalve(base):
792
 class brennenstuhl_heatingvalve(base):
765
     KEY_LINKQUALITY = "linkquality"
793
     KEY_LINKQUALITY = "linkquality"

+ 3
- 4
function/ground_floor_west.py View File

31
         super().send_init_message_main_light()
31
         super().send_init_message_main_light()
32
         self.main_light_tradfri_2.mqtt_client.send(self.main_light_tradfri_2.topic + "/get", '{"state": ""}')
32
         self.main_light_tradfri_2.mqtt_client.send(self.main_light_tradfri_2.topic + "/get", '{"state": ""}')
33
 
33
 
34
-        # radiator valve
35
-        self.radiator_function = radiator_function(mqtt_client, config.TOPIC_GFW_MARION_RADIATOR_VALVE_ZIGBEE,
36
-                                                   config.TOPIC_GFW_MARION_RADIATOR_VALVE_GUI, config.DEFAULT_TEMPERATURE_GFW_MARION)
37
-
38
 
34
 
39
 class ground_floor_west_marion(room_shelly):
35
 class ground_floor_west_marion(room_shelly):
40
     # http://shelly1l-E8DB84A1E067
36
     # http://shelly1l-E8DB84A1E067
41
     def __init__(self, mqtt_client):
37
     def __init__(self, mqtt_client):
42
         super().__init__(mqtt_client, config.TOPIC_GFW_MARION_MAIN_LIGHT_SHELLY, config.TOPIC_GFW_MARION_MAIN_LIGHT_GUI)
38
         super().__init__(mqtt_client, config.TOPIC_GFW_MARION_MAIN_LIGHT_SHELLY, config.TOPIC_GFW_MARION_MAIN_LIGHT_GUI)
39
+        # radiator valve
40
+        self.radiator_function = radiator_function(mqtt_client, config.TOPIC_GFW_MARION_RADIATOR_VALVE_ZIGBEE,
41
+                                                   config.TOPIC_GFW_MARION_RADIATOR_VALVE_GUI, config.DEFAULT_TEMPERATURE_GFW_MARION)
43
 
42
 
44
 
43
 
45
 class ground_floor_west_dirk(room_shelly_tradfri_light):
44
 class ground_floor_west_dirk(room_shelly_tradfri_light):

+ 51
- 18
function/modules.py View File

133
                 self.pump_timer -= self.ct.cycle_time / 60
133
                 self.pump_timer -= self.ct.cycle_time / 60
134
 
134
 
135
 
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):
136
 class radiator_function(object):
137
+    BOOST_TEMPERATURE = 30
138
+    AWAY_REDUCTION = 5
139
+    SUMMER_TEMPERATURE = 5
140
+
141
     def __init__(self, mqtt_client, topic_valve, topic_gui, default_temperature):
141
     def __init__(self, mqtt_client, topic_valve, topic_gui, default_temperature):
142
         self.default_temperature = default_temperature
142
         self.default_temperature = default_temperature
143
         self.regular_temp_setpoint = self.default_temperature
143
         self.regular_temp_setpoint = self.default_temperature
144
+        self.__away_mode__ = False
145
+        self.__summer_mode__ = False
144
         #
146
         #
145
         self.ct = task.periodic(1, self.cyclic_task)
147
         self.ct = task.periodic(1, self.cyclic_task)
146
         #
148
         #
149
         #
151
         #
150
         self.heating_valve.set_heating_setpoint(self.default_temperature)
152
         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)
153
         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
+        self.heating_valve.add_callback(devices.brennenstuhl_heatingvalve.KEY_HEATING_SETPOINT, None, self.get_radiator_setpoint)
154
         #
155
         #
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)
156
+        self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_SETPOINT_TEMP, None, self.set_heating_setpoint)
157
+        self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_BOOST, None, self.boost)
158
+        self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_SETPOINT_TO_DEFAULT, None, self.setpoint_to_default)
159
+        self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_AWAY, None, self.away_mode)
160
+        self.gui_heating.add_callback(devices.nodered_gui_radiator.KEY_SUMMER, None, self.summer_mode)
160
         #
161
         #
161
         self.boost_timer = None
162
         self.boost_timer = None
162
         #
163
         #
177
             self.boost_timer = None
178
             self.boost_timer = None
178
             self.gui_heating.set_timer('-')
179
             self.gui_heating.set_timer('-')
179
 
180
 
180
-    def store_regular_setpoint(self, device, key, data):
181
-        if self.boost_timer is None:
182
-            self.regular_temp_setpoint = data
181
+    def away_mode(self, device, key, value):
182
+        self.__away_mode__ = value
183
+        self.gui_heating.set_away(value)
184
+        if value is True:
185
+            self.__summer_mode__ = False
186
+            self.gui_heating.set_summer(False)
187
+            self.cancel_boost()
188
+            self.heating_valve.set_heating_setpoint(self.default_temperature - self.AWAY_REDUCTION)
189
+        else:
190
+            self.heating_valve.set_heating_setpoint(self.default_temperature)
191
+
192
+    def summer_mode(self, device, key, value):
193
+        self.__summer_mode__ = value
194
+        self.gui_heating.set_summer(value)
195
+        if value is True:
196
+            self.__away_mode__ = False
197
+            self.gui_heating.set_away(False)
198
+            self.cancel_boost()
199
+            self.heating_valve.set_heating_setpoint(self.SUMMER_TEMPERATURE)
200
+        else:
201
+            self.heating_valve.set_heating_setpoint(self.default_temperature)
183
 
202
 
184
-    def boost_mcb(self, device, key, data):
203
+    def boost(self, device, key, data):
204
+        self.cancel_boost()
185
         if self.boost_timer is None:
205
         if self.boost_timer is None:
186
-            self.heating_valve.logger.info('Starting boost mode with setpoint %.1f°C.', self.regular_temp_setpoint + 5)
206
+            self.heating_valve.logger.info('Starting boost mode with setpoint %.1f°C.', self.BOOST_TEMPERATURE)
187
             self.boost_timer = 15*60
207
             self.boost_timer = 15*60
188
-            self.heating_valve.set_heating_setpoint(self.regular_temp_setpoint + 5)     # TODO: Change setpoint to "on" if possible
208
+            self.heating_valve.set_heating_setpoint(self.BOOST_TEMPERATURE)
189
         else:
209
         else:
190
             self.boost_timer += 15 * 60
210
             self.boost_timer += 15 * 60
191
         if self.boost_timer > 60 * 60:
211
         if self.boost_timer > 60 * 60:
192
             self.boost_timer = 60 * 60
212
             self.boost_timer = 60 * 60
193
 
213
 
194
-    def setpoint_to_default_mcb(self, device, key, data):
214
+    def setpoint_to_default(self, device, key, data):
195
         self.heating_valve.set_heating_setpoint(self.default_temperature)
215
         self.heating_valve.set_heating_setpoint(self.default_temperature)
216
+
217
+    def set_heating_setpoint(self, device, key, data):
218
+        self.cancel_boost()
219
+        self.heating_valve.set_heating_setpoint(data)
220
+
221
+    def get_radiator_setpoint(self, device, key, data):
222
+        self.gui_heating.set_setpoint_temperature(data)
223
+        if self.__away_mode__:
224
+            self.away_mode(device, self.gui_heating.KEY_AWAY, True)
225
+        if self.__summer_mode__:
226
+            self.summer_mode(device, self.gui_heating.KEY_SUMMER, True)
227
+        if self.boost_timer is None and not self.__away_mode__ and not self.__summer_mode__:
228
+            self.regular_temp_setpoint = data

Loading…
Cancel
Save