Pārlūkot izejas kodu

simulation for circulation pump, heating valve and amplifier remote added

tags/v1.0.0
Dirk Alders 2 gadus atpakaļ
vecāks
revīzija
03a6f83c42
2 mainītis faili ar 235 papildinājumiem un 45 dzēšanām
  1. 220
    39
      __simulation__/devices.py
  2. 15
    6
      __simulation__/rooms.py

+ 220
- 39
__simulation__/devices.py Parādīt failu

@@ -1,6 +1,7 @@
1 1
 import colored
2 2
 import json
3 3
 import sys
4
+import task
4 5
 import time
5 6
 
6 7
 COLOR_GUI_ACTIVE = colored.fg("light_blue")
@@ -9,7 +10,9 @@ COLOR_SHELLY = colored.fg("light_magenta")
9 10
 COLOR_POWERPLUG = colored.fg("light_cyan")
10 11
 COLOR_LIGHT_ACTIVE = colored.fg("yellow")
11 12
 COLOR_LIGHT_PASSIVE = COLOR_LIGHT_ACTIVE + colored.attr("dim")
12
-COLOR_MOTION_SENSOR = colored.fg("red")
13
+COLOR_MOTION_SENSOR = colored.fg("dark_orange_3b")
14
+COLOR_RADIATOR_VALVE = colored.fg("red")
15
+COLOR_REMOTE = colored.fg("green")
13 16
 
14 17
 
15 18
 def payload_filter(payload):
@@ -19,12 +22,19 @@ def payload_filter(payload):
19 22
         return payload.decode("utf-8")
20 23
 
21 24
 
22
-def percent_print(value):
25
+def percent_bar(value):
26
+    rv = ""
23 27
     for i in range(0, 10):
24
-        if (value - 5) > 10*i:
25
-            sys.stdout.write(u"\u25ac")
26
-        else:
27
-            sys.stdout.write(u"\u25ad")
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")
28 38
 
29 39
 
30 40
 def command_int_value(value):
@@ -34,6 +44,13 @@ def command_int_value(value):
34 44
         print("You need to give a integer parameter not '%s'" % str(value))
35 45
 
36 46
 
47
+def command_float_value(value):
48
+    try:
49
+        return float(value)
50
+    except TypeError:
51
+        print("You need to give a integer parameter not '%s'" % str(value))
52
+
53
+
37 54
 class base(object):
38 55
     AUTOSEND = True
39 56
     COMMANDS = []
@@ -96,19 +113,24 @@ class shelly(base):
96 113
     COMMANDS = [
97 114
         "get_relay_0", "toggle_relay_0",
98 115
         "get_relay_1", "toggle_relay_1",
99
-        "get_input_0", "trigger_input_0",
100
-        "get_input_1", "trigger_input_1",
116
+        "get_input_0", "toggle_input_0",
117
+        "get_input_1", "toggle_input_1",
101 118
         "trigger_long_input_0", "trigger_long_input_1",
102 119
     ]
103 120
 
104
-    def __init__(self, mqtt_client, topic, input_0_func=None, input_1_func=None):
121
+    def __init__(self, mqtt_client, topic, input_0_func=None, input_1_func=None, output_0_auto_off=None):
105 122
         super().__init__(mqtt_client, topic)
106 123
         #
107 124
         self.store_data(**{self.KEY_OUTPUT_0: "off", self.KEY_OUTPUT_1: "off", self.KEY_INPUT_0: "off", self.KEY_INPUT_1: "off"})
108 125
         self.__input_0_func = input_0_func
109 126
         self.__input_1_func = input_1_func
127
+        self.__output_0_auto_off__ = output_0_auto_off
128
+        if self.__output_0_auto_off__ is not None:
129
+            self.__delayed_off__ = task.delayed(float(self.__output_0_auto_off__), self.__auto_off__, self.KEY_OUTPUT_0)
110 130
         #
111 131
         self.add_callback(self.KEY_OUTPUT_0, self.print_formatted, None)
132
+        self.add_callback(self.KEY_OUTPUT_0, self.__start_auto_off__, "on")
133
+        self.add_callback(self.KEY_OUTPUT_0, self.__stop_auto_off__, "off")
112 134
         self.add_callback(self.KEY_OUTPUT_1, self.print_formatted, None)
113 135
         #
114 136
         self.add_callback(self.KEY_INPUT_0, self.__input_function__, None)
@@ -136,14 +158,27 @@ class shelly(base):
136 158
             func = None
137 159
         if func == self.INPUT_FUNC_OUT1_FOLLOW:
138 160
             self.__set_data__(self.KEY_OUTPUT_0, data)
139
-        elif func == self.INPUT_FUNC_OUT1_TRIGGER and data == 'on':
140
-            print("Triggered Output 0 by Input 0")
161
+        elif func == self.INPUT_FUNC_OUT1_TRIGGER:
141 162
             self.__toggle_data__(self.KEY_OUTPUT_0)
142 163
         elif func == self.INPUT_FUNC_OUT2_FOLLOW:
143 164
             self.__set_data__(self.KEY_OUTPUT_1, data)
144
-        elif func == self.INPUT_FUNC_OUT2_TRIGGER and data == 'on':
165
+        elif func == self.INPUT_FUNC_OUT2_TRIGGER:
145 166
             self.__toggle_data__(self.KEY_OUTPUT_1)
146 167
 
168
+    def __start_auto_off__(self, device, key, data):
169
+        self.__stop_auto_off__(device, key, data)
170
+        if self.__output_0_auto_off__ is not None:
171
+            self.__delayed_off__.run()
172
+
173
+    def __stop_auto_off__(self, device, key, data):
174
+        if self.__output_0_auto_off__ is not None:
175
+            if not self.__delayed_off__._stopped:
176
+                self.__delayed_off__.stop()
177
+
178
+    def __auto_off__(self, key):
179
+        if key == self.KEY_OUTPUT_0:
180
+            self.__set_data__(key, 'off')
181
+
147 182
     def __set_data__(self, key, value):
148 183
         if value in ["on", "off"]:
149 184
             self.store_data(**{key: value})
@@ -167,29 +202,23 @@ class shelly(base):
167 202
             elif command == self.COMMANDS[4]:
168 203
                 self.print_formatted(self, self.KEY_INPUT_0, self.data.get(self.KEY_INPUT_0))
169 204
             elif command == self.COMMANDS[5]:
170
-                self.__set_data__(self.KEY_INPUT_0, 'on')
171
-                time.sleep(0.2)
172
-                self.__set_data__(self.KEY_INPUT_0, 'off')
205
+                self.__toggle_data__(self.KEY_INPUT_0)
173 206
             elif command == self.COMMANDS[6]:
174 207
                 self.print_formatted(self, self.KEY_INPUT_1, self.data.get(self.KEY_INPUT_1))
175 208
             elif command == self.COMMANDS[7]:
176
-                self.__set_data__(self.KEY_INPUT_1, 'on')
177
-                time.sleep(0.2)
178
-                self.__set_data__(self.KEY_INPUT_1, 'off')
209
+                self.__toggle_data__(self.KEY_INPUT_1)
179 210
             elif command == self.COMMANDS[8]:
180
-                self.__set_data__(self.KEY_INPUT_0, 'on')
211
+                self.__toggle_data__(self.KEY_INPUT_0)
181 212
                 time.sleep(0.4)
182 213
                 self.__set_data__(self.KEY_LONGPUSH_0, 'on')
183 214
                 time.sleep(0.1)
184 215
                 self.__set_data__(self.KEY_LONGPUSH_0, 'off')
185
-                self.__set_data__(self.KEY_INPUT_0, 'off')
186 216
             elif command == self.COMMANDS[9]:
187
-                self.__set_data__(self.KEY_INPUT_1, 'on')
217
+                self.__toggle_data__(self.KEY_INPUT_1)
188 218
                 time.sleep(0.4)
189 219
                 self.__set_data__(self.KEY_LONGPUSH_1, 'on')
190 220
                 time.sleep(0.1)
191 221
                 self.__set_data__(self.KEY_LONGPUSH_1, 'off')
192
-                self.__set_data__(self.KEY_INPUT_1, 'off')
193 222
             else:
194 223
                 print("%s: not yet implemented!" % command)
195 224
         else:
@@ -198,9 +227,10 @@ class shelly(base):
198 227
     def print_formatted(self, device, key, value):
199 228
         if value is not None:
200 229
             icon = u'\u2b24' if value == "on" else u'\u25ef'
201
-            channel = "(%s)" % self.names.get(key, key)
230
+            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)
202 232
             devicename = " - ".join(self.topic.split('/')[1:])
203
-            print(COLOR_SHELLY + 10 * ' ' + icon + 6 * ' ' + devicename + ' ' + channel + colored.attr("reset"))
233
+            print(COLOR_SHELLY + 10 * ' ' + icon + 9 * ' ' + devicename + ' ' + channel + colored.attr("reset"))
204 234
 
205 235
 
206 236
 class my_powerplug(base):
@@ -230,7 +260,6 @@ class my_powerplug(base):
230 260
                 channels = range(0, 4)
231 261
             for channel in channels:
232 262
                 payload = payload_filter(message.payload)
233
-                print(channel, payload)
234 263
                 if payload == "toggle":
235 264
                     payload = not self.data.get(str(channel))
236 265
                 self.store_data(**{str(channel): payload})
@@ -267,7 +296,7 @@ class my_powerplug(base):
267 296
             icon = u'\u2b24' if value else u'\u25ef'
268 297
             channel = "(%s)" % self.names.get(key, "Channel %d" % (int(key) + 1))
269 298
             devicename = " - ".join(self.topic.split('/')[1:])
270
-            print(COLOR_POWERPLUG + 10 * ' ' + icon + 6 * ' ' + devicename + ' ' + channel + colored.attr("reset"))
299
+            print(COLOR_POWERPLUG + 10 * ' ' + icon + 9 * ' ' + devicename + ' ' + channel + colored.attr("reset"))
271 300
 
272 301
 
273 302
 class silvercrest_powerplug(base):
@@ -314,7 +343,7 @@ class silvercrest_powerplug(base):
314 343
             icon = u'\u2b24' if value == "on" else u'\u25ef'
315 344
             channel = "(%s)" % self.names.get(key, key)
316 345
             devicename = " - ".join(self.topic.split('/')[1:])
317
-            print(COLOR_POWERPLUG + 10 * ' ' + icon + 6 * ' ' + devicename + ' ' + channel + colored.attr("reset"))
346
+            print(COLOR_POWERPLUG + 10 * ' ' + icon + 9 * ' ' + devicename + ' ' + channel + colored.attr("reset"))
318 347
 
319 348
 
320 349
 class silvercrest_motion_sensor(base):
@@ -344,9 +373,9 @@ class silvercrest_motion_sensor(base):
344 373
     def print_formatted(self, device, key, value):
345 374
         if value is not None:
346 375
             if value:
347
-                print(COLOR_MOTION_SENSOR + 10 * ' ' + u'\u2b24' + 6 * ' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
376
+                print(COLOR_MOTION_SENSOR + 10 * ' ' + u'\u2b24' + 9 * ' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
348 377
             else:
349
-                print(COLOR_MOTION_SENSOR + 10 * ' ' + u'\u25ef' + 6 * ' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
378
+                print(COLOR_MOTION_SENSOR + 10 * ' ' + u'\u25ef' + 9 * ' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
350 379
 
351 380
 
352 381
 class tradfri_light(base):
@@ -452,9 +481,9 @@ class tradfri_light(base):
452 481
             color = COLOR_LIGHT_ACTIVE
453 482
             if key == self.KEY_STATE:
454 483
                 if value == "on":
455
-                    print(color + 10 * ' ' + u'\u2b24' + 6 * ' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
484
+                    print(color + 10 * ' ' + u'\u2b24' + 9 * ' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
456 485
                 else:
457
-                    print(color + 10 * ' ' + u'\u25ef' + 6 * ' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
486
+                    print(color + 10 * ' ' + u'\u25ef' + 9 * ' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
458 487
                 self.print_formatted(device, self.KEY_BRIGHTNESS, self.data.get(self.KEY_BRIGHTNESS))
459 488
                 self.print_formatted(device, self.KEY_COLOR_TEMP, self.data.get(self.KEY_COLOR_TEMP))
460 489
             elif key in [self.KEY_BRIGHTNESS, self.KEY_COLOR_TEMP]:
@@ -466,8 +495,8 @@ class tradfri_light(base):
466 495
                     value = round((value - 250) * 100 / 204, 0)
467 496
                 sys.stdout.write(color)
468 497
                 sys.stdout.write('B' if key == gui_light.KEY_BRIGHTNESS else 'C')
469
-                percent_print(value)
470
-                sys.stdout.write("%3d%%  " % value)
498
+                sys.stdout.write(percent_bar(value))
499
+                sys.stdout.write("%3d%%" % value + 5 * " ")
471 500
                 print(" - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
472 501
 
473 502
 
@@ -535,9 +564,9 @@ class gui_light(tradfri_light):
535 564
             color = COLOR_GUI_ACTIVE
536 565
             if key == self.KEY_STATE:
537 566
                 if value == True:
538
-                    print(color + 10 * ' ' + u'\u25a0' + 6 * ' ' + " - ".join(self.topic.split('/')[1:-1]) + colored.attr("reset"))
567
+                    print(color + 10 * ' ' + u'\u25a0' + 9 * ' ' + " - ".join(self.topic.split('/')[1:-1]) + colored.attr("reset"))
539 568
                 else:
540
-                    print(color + 10 * ' ' + u'\u25a1' + 6*' ' + " - ".join(self.topic.split('/')[1:-1]) + colored.attr("reset"))
569
+                    print(color + 10 * ' ' + u'\u25a1' + 9*' ' + " - ".join(self.topic.split('/')[1:-1]) + colored.attr("reset"))
541 570
             elif key == self.KEY_ENABLE:
542 571
                 self.print_formatted(device, self.KEY_BRIGHTNESS, self.data.get(self.KEY_BRIGHTNESS))
543 572
                 self.print_formatted(device, self.KEY_COLOR_TEMP, self.data.get(self.KEY_COLOR_TEMP))
@@ -547,8 +576,8 @@ class gui_light(tradfri_light):
547 576
                 value = round(value * 10 if key == self.KEY_COLOR_TEMP else value, 0)
548 577
                 sys.stdout.write(color)
549 578
                 sys.stdout.write('B' if key == self.KEY_BRIGHTNESS else 'C')
550
-                percent_print(value)
551
-                sys.stdout.write("%3d%%  " % value)
579
+                sys.stdout.write(percent_bar(value))
580
+                sys.stdout.write("%3d%%" % value + 5 * " ")
552 581
                 print(" - ".join(self.topic.split('/')[1:-1]) + colored.attr("reset"))
553 582
 
554 583
 
@@ -623,7 +652,159 @@ class gui_led_array(base):
623 652
                 print("Unknown key %s in %s" % (targetkey, self.__class__.__name__))
624 653
 
625 654
     def print_formatted(self, device, key, value):
626
-        color = colored.fg('green') if value else ""
655
+        led = green_led() if value else grey_led()
627 656
         channel = '(%s)' % self.names.get(key, key)
628 657
         devicename = ' - '.join(self.topic.split('/')[1:-1])
629
-        print(color + 10 * ' ' + u"\u2b24" + 6 * ' ' + COLOR_GUI_ACTIVE + devicename + ' ' + channel + colored.attr("reset"))
658
+        print(10 * ' ' + led + 9 * ' ' + COLOR_GUI_ACTIVE + devicename + ' ' + channel + colored.attr("reset"))
659
+
660
+
661
+class remote(base):
662
+    def __rx__(self, client, userdata, message):
663
+        if message.topic == self.topic + "/VOLUP":
664
+            if payload_filter(message.payload):
665
+                icon = u'\u1403'
666
+            else:
667
+                icon = u'\u25a1'
668
+        elif message.topic == self.topic + "/VOLDOWN":
669
+            if payload_filter(message.payload):
670
+                icon = u'\u1401'
671
+            else:
672
+                icon = u'\u25a1'
673
+        else:
674
+            return
675
+        devicename = ' - '.join(self.topic.split('/')[1:-1])
676
+        print(COLOR_REMOTE + 10 * ' ' + icon + 6 * ' ' + devicename + colored.attr("reset"))
677
+
678
+
679
+class gui_timer(base):
680
+    AUTOSEND = False
681
+
682
+    def __init__(self, mqtt_client, topic):
683
+        super().__init__(mqtt_client, topic)
684
+        self.maxvalue = None
685
+        self.last_printed = None
686
+
687
+    def __rx__(self, client, userdata, message):
688
+        payload = payload_filter(message.payload)
689
+        if message.topic.startswith(self.topic) and message.topic.endswith('/feedback/set'):
690
+            if isinstance(payload, (int, float, complex)) and not isinstance(payload, bool):
691
+                if self.maxvalue is None:
692
+                    self.maxvalue = payload
693
+                perc = payload / self.maxvalue * 100
694
+                if self.last_printed is None or abs(self.last_printed - perc) >= 4.8:
695
+                    sys.stdout.write(COLOR_GUI_ACTIVE + 't' + percent_bar(perc))
696
+                    print('%3d%%' % perc + 2 * ' ' + ' - '.join(self.topic.split('/')[1:-1]) + ' (%.1f)' % payload + colored.attr('reset'))
697
+                    self.last_printed = perc
698
+            else:
699
+                self.maxvalue = None
700
+                self.last_printed = None
701
+                sys.stdout.write(COLOR_GUI_ACTIVE + 't' + percent_bar(0))
702
+                print('%3d%%' % 0 + 2 * ' ' + ' - '.join(self.topic.split('/')[1:-1]) + colored.attr('reset'))
703
+        else:
704
+            print("Unknown Message")
705
+
706
+
707
+class brennenstuhl_radiator_valve(base):
708
+    TEMP_RANGE = [10, 30]
709
+    #
710
+    KEY_TEMPERATURE_SETPOINT = "current_heating_setpoint"
711
+    KEY_TEMPERATURE = "local_temperature"
712
+    #
713
+    COMMANDS = [
714
+        "get_temperature_setpoint", "set_temperature_setpoint",
715
+    ]
716
+
717
+    def __init__(self, mqtt_client, topic):
718
+        super().__init__(mqtt_client, topic)
719
+        self.store_data(**{
720
+            self.KEY_TEMPERATURE_SETPOINT: 20,
721
+            self.KEY_TEMPERATURE: 20.7,
722
+        })
723
+        self.add_callback(self.KEY_TEMPERATURE_SETPOINT, self.print_formatted, None)
724
+
725
+    def __rx__(self, client, userdata, message):
726
+        if message.topic.startswith(self.topic) and message.topic.endswith("/set"):
727
+            payload = payload_filter(message.payload)
728
+            self.store_data(**payload)
729
+
730
+    def command(self, command):
731
+        try:
732
+            command, value = command.split(' ')
733
+        except ValueError:
734
+            value = None
735
+        if command in self.COMMANDS:
736
+            if command == self.COMMANDS[0]:
737
+                self.print_formatted(self, self.KEY_TEMPERATURE_SETPOINT, self.data.get(self.KEY_TEMPERATURE_SETPOINT))
738
+            elif command == self.COMMANDS[1]:
739
+                self.store_data(**{self.KEY_TEMPERATURE_SETPOINT: command_float_value(value)})
740
+
741
+    def print_formatted(self, device, key, value):
742
+        devicename = ' - '.join(self.topic.split('/')[1:])
743
+        if key == self.KEY_TEMPERATURE_SETPOINT:
744
+            perc = 100 * (value - self.TEMP_RANGE[0]) / (self.TEMP_RANGE[1] - self.TEMP_RANGE[0])
745
+            perc = 100 if perc > 100 else perc
746
+            perc = 0 if perc < 0 else perc
747
+            sys.stdout.write(COLOR_RADIATOR_VALVE + '\u03d1' + percent_bar(perc))
748
+            sys.stdout.write("%4.1f°C" % value + 3 * " ")
749
+            print(devicename + colored.attr("reset"))
750
+
751
+
752
+class gui_radiator_valve(base):
753
+    AUTOSEND = False
754
+    #
755
+    TEMP_RANGE = [10, 30]
756
+    #
757
+    KEY_BOOST_LED = "boost_led"
758
+    KEY_TEMPERATURE_SETPOINT = "temperature_setpoint"
759
+    #
760
+    COMMANDS = [
761
+        "get_temperature_setpoint", "set_temperature_setpoint",
762
+        "get_boost_state", "trigger_boost",
763
+    ]
764
+
765
+    def __init__(self, mqtt_client, topic):
766
+        super().__init__(mqtt_client, topic)
767
+        self.add_callback(self.KEY_TEMPERATURE_SETPOINT, self.print_formatted, None)
768
+        self.add_callback(self.KEY_BOOST_LED, self.print_formatted, None)
769
+
770
+    def __rx__(self, client, userdata, message):
771
+        if message.topic.startswith(self.topic) and message.topic.endswith("/set"):
772
+            payload = payload_filter(message.payload)
773
+            if type(payload) == bool:
774
+                self.store_data(**{self.KEY_BOOST_LED: payload})
775
+            else:
776
+                self.store_data(**{self.KEY_TEMPERATURE_SETPOINT: payload})
777
+        else:
778
+            print(message.topic)
779
+
780
+    def command(self, command):
781
+        try:
782
+            command, value = command.split(' ')
783
+        except ValueError:
784
+            value = None
785
+        if command in self.COMMANDS:
786
+            if command == self.COMMANDS[0]:
787
+                self.print_formatted(self, self.KEY_TEMPERATURE_SETPOINT, self.data.get(self.KEY_TEMPERATURE_SETPOINT))
788
+            elif command == self.COMMANDS[1]:
789
+                ###################################  TEMPORARY!!!  ###################################
790
+                self.mqtt_client.send(self.topic + "/feedback/set", command_float_value(value))
791
+                ###################################  TEMPORARY!!!  ###################################
792
+            elif command == self.COMMANDS[2]:
793
+                self.print_formatted(self, self.KEY_BOOST_LED, self.data.get(self.KEY_BOOST_LED))
794
+            elif command == self.COMMANDS[3]:
795
+                ###################################  TEMPORARY!!!  ###################################
796
+                self.mqtt_client.send(self.topic + "/state", json.dumps(True))
797
+                ###################################  TEMPORARY!!!  ###################################
798
+
799
+    def print_formatted(self, device, key, value):
800
+        devicename = ' - '.join(self.topic.split('/')[1:])
801
+        if key == self.KEY_BOOST_LED:
802
+            led = green_led() if value else grey_led()
803
+            print(10 * ' ' + led + 9 * ' ' + COLOR_GUI_ACTIVE + devicename + " (Boost)" + colored.attr("reset"))
804
+        elif key == self.KEY_TEMPERATURE_SETPOINT:
805
+            perc = 100 * (value - self.TEMP_RANGE[0]) / (self.TEMP_RANGE[1] - self.TEMP_RANGE[0])
806
+            perc = 100 if perc > 100 else perc
807
+            perc = 0 if perc < 0 else perc
808
+            sys.stdout.write(COLOR_GUI_ACTIVE + '\u03d1' + percent_bar(perc))
809
+            sys.stdout.write("%4.1f°C" % value + 3 * " ")
810
+            print(devicename + colored.attr("reset"))

+ 15
- 6
__simulation__/rooms.py Parādīt failu

@@ -1,12 +1,8 @@
1 1
 import config
2
-from __simulation__.devices import shelly, silvercrest_powerplug, gui_light, tradfri_light, tradfri_button, gui_led_array, silvercrest_motion_sensor, my_powerplug
2
+from __simulation__.devices import shelly, silvercrest_powerplug, tradfri_light, tradfri_button, silvercrest_motion_sensor, my_powerplug, remote, brennenstuhl_radiator_valve
3
+from __simulation__.devices import gui_light, gui_led_array, gui_timer, gui_radiator_valve
3 4
 import inspect
4 5
 
5
-# TODO: ffe_sleep:      Implement heating valve
6
-# TODO: gfw_dirk:       Add at least brightness amplifier remote feedback to console
7
-# TODO: ffe_diningroom: Implement garland gui_switch
8
-# TODO: ffe_kitchen:    Implement circulation pump (incl. shelly auto off function)
9
-
10 6
 
11 7
 class base(object):
12 8
     def getmembers(self, prefix=''):
@@ -84,6 +80,8 @@ class gfw_dirk(base):
84 80
         self.gui_switch_cd_player = gui_light(mqtt_client, config.TOPIC_GFW_DIRK_CD_PLAYER_GUI_SWITCH, True, False, False)
85 81
         self.gui_switch_pc_dock = gui_light(mqtt_client, config.TOPIC_GFW_DIRK_PC_DOCK_GUI_SWITCH, True, False, False)
86 82
         #
83
+        self.remote = remote(mqtt_client, config.TOPIC_GFW_DIRK_AMPLIFIER_REMOTE)
84
+        #
87 85
         self.input_device = tradfri_button(mqtt_client, config.TOPIC_GFW_DIRK_INPUT_DEVICE)
88 86
         self.led_array = gui_led_array(mqtt_client, config.TOPIC_GFW_DIRK_DEVICE_CHOOSER_LED)
89 87
         self.led_array.add_channel_name(gui_led_array.KEY_LED_0, "Main Light")
@@ -134,6 +132,12 @@ class ffe_kitchen(base):
134 132
         self.gui_switch_main_light = gui_light(mqtt_client, config.TOPIC_FFE_KITCHEN_MAIN_LIGHT_GUI_SWITCH, True, False, False)
135 133
         self.main_light = shelly(mqtt_client, config.TOPIC_FFE_KITCHEN_MAIN_LIGHT_SHELLY, input_0_func=shelly.INPUT_FUNC_OUT1_TRIGGER)
136 134
         self.main_light.add_channel_name(shelly.KEY_OUTPUT_0, "Main Light")
135
+        #
136
+        self.gui_switch_circulation_pump = gui_light(mqtt_client, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_GUI_SWITCH, True, False, False)
137
+        self.circulation_pump = shelly(mqtt_client, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_SHELLY,
138
+                                       input_0_func=shelly.INPUT_FUNC_OUT1_TRIGGER, output_0_auto_off=10*60)
139
+        self.circulation_pump.add_channel_name(shelly.KEY_OUTPUT_0, "Circulation Pump")
140
+        self.gui_timer_circulation_pump = gui_timer(mqtt_client, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_GUI_TIMER)
137 141
 
138 142
 
139 143
 class ffe_diningroom(base):
@@ -166,6 +170,11 @@ class ffe_sleep(base):
166 170
         self.led_array = gui_led_array(mqtt_client, config.TOPIC_FFE_SLEEP_DEVICE_CHOOSER_LED)
167 171
         self.led_array.add_channel_name(gui_led_array.KEY_LED_0, "Main Light")
168 172
         self.led_array.add_channel_name(gui_led_array.KEY_LED_1, "Bed Light Dirk")
173
+        #
174
+        self.heating_valve = brennenstuhl_radiator_valve(mqtt_client, config.TOPIC_FFE_SLEEP_RADIATOR_VALVE_ZIGBEE)
175
+        self.gui_heating_valve = gui_radiator_valve(mqtt_client, "gui/ffe_ts_sleep_madi")
176
+        self.gui_heating_valve_boost_led = gui_radiator_valve(mqtt_client, "gui/ffe_bl_sleep_madi")
177
+        self.gui_heating_valve_boost_button = gui_radiator_valve(mqtt_client, "gui/ffe_bo_sleep_madi")
169 178
 
170 179
 
171 180
 class ffe_livingroom(base):

Notiek ielāde…
Atcelt
Saglabāt