소스 검색

timer and led status integrated in gui_light class

tags/v1.0.0
Dirk Alders 1 년 전
부모
커밋
94f089dd93
8개의 변경된 파일107개의 추가작업 그리고 81개의 파일을 삭제
  1. 38
    32
      __simulation__/devices.py
  2. 3
    2
      __simulation__/rooms.py
  3. 36
    23
      devices/__init__.py
  4. 1
    3
      function/__init__.py
  5. 5
    6
      function/common.py
  6. 2
    2
      function/modules.py
  7. 20
    11
      function/rooms.py
  8. 2
    2
      function/stairway.py

+ 38
- 32
__simulation__/devices.py 파일 보기

@@ -504,10 +504,19 @@ class gui_light(tradfri_light):
504 504
     AUTOSEND = False
505 505
     #
506 506
     KEY_ENABLE = "enable"
507
+    KEY_TIMER = "timer"
508
+    KEY_LED_X = "led%d"
507 509
 
508 510
     def __init__(self, mqtt_client, topic, enable_state=True, enable_brightness=False, enable_color_temp=False):
509 511
         super().__init__(mqtt_client, topic, enable_state, enable_brightness, enable_color_temp)
510 512
         self.add_callback(self.KEY_ENABLE, self.print_formatted, None)
513
+        self.add_callback(self.KEY_TIMER, self.print_formatted, None)
514
+        for i in range(0, 10):
515
+            self.add_callback(self.KEY_LED_X % i, self.print_formatted, None)
516
+        self.led_names = {}
517
+        #
518
+        self.maxvalue = None
519
+        self.last_printed = None
511 520
 
512 521
     def __init_data__(self, enable_state, enable_brightness, enable_color_temp):
513 522
         data = {}
@@ -518,6 +527,9 @@ class gui_light(tradfri_light):
518 527
             data[self.KEY_BRIGHTNESS] = 50
519 528
         if enable_color_temp:
520 529
             data[self.KEY_COLOR_TEMP] = 5
530
+        data[self.KEY_TIMER] = '-'
531
+        for i in range(0, 10):
532
+            data[self.KEY_LED_X % i] = False
521 533
         self.store_data(**data)
522 534
 
523 535
     def __rx__(self, client, userdata, message):
@@ -559,14 +571,18 @@ class gui_light(tradfri_light):
559 571
         else:
560 572
             print("Unknown command!")
561 573
 
574
+    def add_led_name(self, key, name):
575
+        self.led_names[key] = name
576
+
562 577
     def print_formatted(self, device, key, value):
563 578
         if value is not None:
564 579
             color = COLOR_GUI_ACTIVE
580
+            device = " - ".join(self.topic.split('/')[1:])
565 581
             if key == self.KEY_STATE:
566 582
                 if value == True:
567
-                    print(color + 10 * ' ' + u'\u25a0' + 9 * ' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
583
+                    print(color + 10 * ' ' + u'\u25a0' + 9 * ' ' + device + colored.attr("reset"))
568 584
                 else:
569
-                    print(color + 10 * ' ' + u'\u25a1' + 9*' ' + " - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
585
+                    print(color + 10 * ' ' + u'\u25a1' + 9 * ' ' + device + colored.attr("reset"))
570 586
             elif key == self.KEY_ENABLE:
571 587
                 self.print_formatted(device, self.KEY_BRIGHTNESS, self.data.get(self.KEY_BRIGHTNESS))
572 588
                 self.print_formatted(device, self.KEY_COLOR_TEMP, self.data.get(self.KEY_COLOR_TEMP))
@@ -577,8 +593,26 @@ class gui_light(tradfri_light):
577 593
                 sys.stdout.write(color)
578 594
                 sys.stdout.write('B' if key == self.KEY_BRIGHTNESS else 'C')
579 595
                 sys.stdout.write(percent_bar(value))
580
-                sys.stdout.write("%3d%%" % value + 5 * " ")
581
-                print(" - ".join(self.topic.split('/')[1:]) + colored.attr("reset"))
596
+                print("%3d%%" % value + 5 * " " + device + colored.attr("reset"))
597
+            elif key == self.KEY_TIMER:
598
+                if isinstance(value, (int, float, complex)) and not isinstance(value, bool):
599
+                    if self.maxvalue is None:
600
+                        self.maxvalue = value
601
+                    disp_value = value
602
+                    perc = disp_value / self.maxvalue * 100
603
+                else:
604
+                    disp_value = 0
605
+                    perc = 0
606
+                    self.maxvalue = None
607
+                    self.last_printed = None
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'))
610
+                    self.last_printed = perc
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"))
582 616
 
583 617
 
584 618
 class tradfri_button(base):
@@ -676,34 +710,6 @@ class remote(base):
676 710
         print(COLOR_REMOTE + 10 * ' ' + icon + 6 * ' ' + devicename + colored.attr("reset"))
677 711
 
678 712
 
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:]) + ' (%.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:]) + colored.attr('reset'))
703
-        else:
704
-            print("Unknown Message")
705
-
706
-
707 713
 class brennenstuhl_radiator_valve(base):
708 714
     TEMP_RANGE = [10, 30]
709 715
     #

+ 3
- 2
__simulation__/rooms.py 파일 보기

@@ -1,6 +1,6 @@
1 1
 import config
2 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
+from __simulation__.devices import gui_light, gui_led_array, gui_radiator_valve
4 4
 import inspect
5 5
 
6 6
 
@@ -136,7 +136,6 @@ class ffe_kitchen(base):
136 136
         self.circulation_pump = shelly(mqtt_client, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_SHELLY,
137 137
                                        input_0_func=shelly.INPUT_FUNC_OUT1_TRIGGER, output_0_auto_off=10*60)
138 138
         self.circulation_pump.add_channel_name(shelly.KEY_OUTPUT_0, "Circulation Pump")
139
-        self.gui_timer_circulation_pump = gui_timer(mqtt_client, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_GUI_TIMER)
140 139
 
141 140
 
142 141
 class ffe_diningroom(base):
@@ -206,6 +205,8 @@ class ffe(base):
206 205
 class stairway(base):
207 206
     def __init__(self, mqtt_client):
208 207
         self.gui_main_light = gui_light(mqtt_client, config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_GUI, True, False, False)
208
+        self.gui_main_light.add_led_name(self.gui_main_light.KEY_LED_X % 0, "Motion Ground Floor")
209
+        self.gui_main_light.add_led_name(self.gui_main_light.KEY_LED_X % 1, "Motion First Floor")
209 210
         self.main_light = shelly(mqtt_client, config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_SHELLY, input_0_func=shelly.INPUT_FUNC_OUT1_TRIGGER)
210 211
         self.main_light.add_channel_name(shelly.KEY_OUTPUT_0, "Main Light")
211 212
         self.motion_sensor_gf = silvercrest_motion_sensor(mqtt_client, config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_MOTION_SENSOR_GF)

+ 36
- 23
devices/__init__.py 파일 보기

@@ -186,6 +186,41 @@ 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
+
189 224
 class shelly(base):
190 225
     KEY_OUTPUT_0 = "relay/0"
191 226
     KEY_OUTPUT_1 = "relay/1"
@@ -700,7 +735,7 @@ class nodered_gui_switch(nodered_gui_button):
700 735
         self.set_state(data)
701 736
 
702 737
 
703
-class nodered_gui_light(nodered_gui_switch):
738
+class nodered_gui_light(nodered_gui_switch, nodered_gui_leds, nodered_gui_timer):
704 739
     KEY_ENABLE = "enable"
705 740
     KEY_BRIGHTNESS = "brightness"
706 741
     KEY_COLOR_TEMP = "color_temp"
@@ -755,28 +790,6 @@ class nodered_gui_light(nodered_gui_switch):
755 790
         self.set_color_temp(data)
756 791
 
757 792
 
758
-class nodered_gui_leds(base):
759
-    KEY_LED_0 = "led0"
760
-    KEY_LED_1 = "led1"
761
-    KEY_LED_2 = "led2"
762
-    KEY_LED_3 = "led3"
763
-    KEY_LED_4 = "led4"
764
-    KEY_LED_5 = "led5"
765
-    KEY_LED_6 = "led6"
766
-    KEY_LED_7 = "led7"
767
-    KEY_LED_8 = "led8"
768
-    KEY_LED_9 = "led9"
769
-    #
770
-    TX_TYPE = base.TX_VALUE
771
-    #
772
-    RX_KEYS = [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]
773
-
774
-    def set_led(self, key, data):
775
-        """data: [True, False]"""
776
-        self.logger.debug("Sending %s with content %s", key, str(data))
777
-        self.pack(key, data)
778
-
779
-
780 793
 class brennenstuhl_heatingvalve(base):
781 794
     KEY_LINKQUALITY = "linkquality"
782 795
     KEY_BATTERY = "battery"

+ 1
- 3
function/__init__.py 파일 보기

@@ -16,10 +16,8 @@ except ImportError:
16 16
     ROOT_LOGGER_NAME = 'root'
17 17
 logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
18 18
 
19
-# TODO: implement devices.nodered_gui_timer (for circulation pump)
20 19
 # TODO: implement devices.nodered_gui_heatvalve incl. setpoint, boost, ... + replace led with timer
21
-# TODO: improve heating function
22
-# TODO: implement timer and motion leds for stairwasy
20
+# TODO: improve heating function (away mode (reduced setpoint), return to default button, default values in config)
23 21
 # TODO: improve devices.brennenstuhl_heatvalve
24 22
 # TODO: implement garland (incl. day events like sunset, sunrise, ...)
25 23
 # TODO: implement warning message

+ 5
- 6
function/common.py 파일 보기

@@ -23,8 +23,7 @@ class common_circulation_pump(room_shelly):
23 23
         #
24 24
         self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.circ_pump_actions, True)
25 25
         #
26
-        self.gui_timer_view = devices.nodered_gui_heatvalve(mqtt_client, config.TOPIC_FFE_KITCHEN_CIRCULATION_PUMP_GUI_TIMER)
27
-        self.gui_timer_view.set_feedback('-')
26
+        self.gui_main_light.set_timer('-')
28 27
         #
29 28
         self.ct = task.periodic(6, self.cyclic_task)
30 29
         self.pump_timer = None
@@ -34,18 +33,18 @@ class common_circulation_pump(room_shelly):
34 33
     def circ_pump_actions(self, device, key, data):
35 34
         if data is True:
36 35
             self.pump_timer = 10
37
-            self.gui_timer_view.set_feedback(self.pump_timer)
36
+            self.gui_main_light.set_timer(self.pump_timer)
38 37
         else:
39 38
             self.pump_timer = None
40
-            self.gui_timer_view.set_feedback('-')
39
+            self.gui_main_light.set_timer('-')
41 40
 
42 41
     def cyclic_task(self, rt):
43 42
         if self.pump_timer is not None:
44 43
             if self.pump_timer <= 0:
45 44
                 self.pump_timer = None
46
-                self.gui_timer_view.set_feedback('-')
45
+                self.gui_main_light.set_timer('-')
47 46
             else:
48
-                self.gui_timer_view.set_feedback(self.pump_timer)
47
+                self.gui_main_light.set_timer(self.pump_timer)
49 48
                 self.pump_timer -= self.ct.cycle_time / 60
50 49
 
51 50
 

+ 2
- 2
function/modules.py 파일 보기

@@ -43,7 +43,7 @@ class brightness_choose_n_action(object):
43 43
         callback_device: A device for installing callback which are executed, when the device is switched on or off. It needs the following method:
44 44
         * .add_callback(key, data or None, callback, on_changes_only)
45 45
         """
46
-        if len(self.brightness_device_list) >= len(devices.nodered_gui_leds.RX_KEYS):
46
+        if len(self.brightness_device_list) >= len(devices.nodered_gui_leds.KEY_LED_LIST):
47 47
             raise ValueError("Number of devices is limited by number of leds in devices.nodered_gui_leds.")
48 48
         self.brightness_device_list.append(brightness_device)
49 49
         self.callback_device_list.append((callback_device, callback_key))
@@ -61,7 +61,7 @@ class brightness_choose_n_action(object):
61 61
 
62 62
     def update_active_device_led(self):
63 63
         for i in range(0, len(self.brightness_device_list)):
64
-            self.gui_led_active_device.set_led(devices.nodered_gui_leds.RX_KEYS[i], self.active_device_state == i)
64
+            self.gui_led_active_device.set_led(devices.nodered_gui_leds.KEY_LED_LIST[i], self.active_device_state == i)
65 65
 
66 66
     def choose_prev_device(self, device=None, key=None, data=None):
67 67
         if self.active_device_state is not None:

+ 20
- 11
function/rooms.py 파일 보기

@@ -59,9 +59,11 @@ class room_shelly(room):
59 59
 
60 60
 
61 61
 class room_shelly_motion_sensor(room_shelly):
62
-    def __init__(self, mqtt_client, topic_shelly, topic_gui, topic_motion_sensor_1, topic_motion_sensor_2=None, timer_value=config.DEFAULT_ON_TIME_LIGHT):
62
+    def __init__(self, mqtt_client, topic_shelly, topic_gui, topic_motion_sensor_1, topic_motion_sensor_2=None, timer_value=30):
63 63
         super().__init__(mqtt_client, topic_shelly, topic_gui)
64 64
         self.timer_value = timer_value
65
+        self.motion_detected_1 = False
66
+        self.motion_detected_2 = False
65 67
         #
66 68
         self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, True, self.reload_timer, True)
67 69
         self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, False, self.reset_timer, True)
@@ -79,11 +81,13 @@ class room_shelly_motion_sensor(room_shelly):
79 81
         cyclic_task.run()
80 82
 
81 83
     def set_motion_detected(self, device, key, data):
82
-        if now() < sunrise_time(60) or now() > sunset_time(-60) or data is False:
83
-            if device == self.motion_sensor_silvercrest_1:
84
-                self.motion_detected_1 = data
85
-            elif device == self.motion_sensor_silvercrest_2:
86
-                self.motion_detected_2 = data
84
+        if device == self.motion_sensor_silvercrest_1:
85
+            self.motion_detected_1 = data
86
+        elif device == self.motion_sensor_silvercrest_2:
87
+            self.motion_detected_2 = data
88
+        self.gui_main_light.set_led(devices.nodered_gui_light.KEY_LED_0, self.motion_detected_1)
89
+        self.gui_main_light.set_led(devices.nodered_gui_light.KEY_LED_1, self.motion_detected_2)
90
+        if now() < sunrise_time(60) or now() > sunset_time(-60):
87 91
             if data is True:
88 92
                 logger.info("%s: Motion detected - Switching on main light %s", device.topic, self.main_light_shelly.topic)
89 93
                 self.main_light_shelly.set_output_0(True)
@@ -99,12 +103,17 @@ class room_shelly_motion_sensor(room_shelly):
99 103
     def cyclic_task(self, cyclic_task):
100 104
         if self.main_light_timer is not None:
101 105
             if self.main_light_timer <= 0:
102
-                if not self.motion_detected_1 and not self.motion_detected_2:
103
-                    logger.info("No motion and time ran out - Switching off main light %s", self.main_light_shelly.topic)
104
-                    self.main_light_shelly.set_output_0(False)
105
-                    self.main_light_timer = None
106
+                logger.info("No motion and time ran out - Switching off main light %s", self.main_light_shelly.topic)
107
+                self.main_light_shelly.set_output_0(False)
108
+                self.main_light_timer = None
106 109
             else:
107
-                self.main_light_timer -= cyclic_task.cycle_time
110
+                self.gui_main_light.set_timer(self.main_light_timer)
111
+                if (self.motion_detected_1 or self.motion_detected_2) and self.main_light_timer <= self.timer_value / 10:
112
+                    self.main_light_timer = self.timer_value / 10
113
+                else:
114
+                    self.main_light_timer -= cyclic_task.cycle_time
115
+        else:
116
+            self.gui_main_light.set_timer('-')
108 117
 
109 118
 
110 119
 class room_shelly_tradfri_light(room_shelly):

+ 2
- 2
function/stairway.py 파일 보기

@@ -17,5 +17,5 @@ class stairway(room_shelly_motion_sensor):
17 17
     def __init__(self, mqtt_client):
18 18
         # http://shelly1-3494546A9364
19 19
         super().__init__(mqtt_client, config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_SHELLY, config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_GUI,
20
-                         config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_MOTION_SENSOR_GF,
21
-                         config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_MOTION_SENSOR_FF, config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_MIN_ON_TIME)
20
+                         config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_MOTION_SENSOR_GF, config.TOPIC_STW_STAIRWAY_MAIN_LIGHT_MOTION_SENSOR_FF,
21
+                         timer_value=config.USER_ON_TIME_STAIRWAYS)

Loading…
취소
저장