Browse Source

all/zone off implemented

tags/v1.0.0
Dirk Alders 2 years ago
parent
commit
da53b3638f
5 changed files with 146 additions and 37 deletions
  1. 39
    5
      devices/__init__.py
  2. 73
    25
      function/__init__.py
  3. 3
    0
      function/common.py
  4. 18
    3
      function/first_floor_east.py
  5. 13
    4
      function/rooms.py

+ 39
- 5
devices/__init__.py View File

@@ -191,6 +191,8 @@ class shelly(base):
191 191
     KEY_OUTPUT_1 = "relay/1"
192 192
     KEY_INPUT_0 = "input/0"
193 193
     KEY_INPUT_1 = "input/1"
194
+    KEY_LONGPUSH_0 = "longpush/0"
195
+    KEY_LONGPUSH_1 = "longpush/1"
194 196
     KEY_TEMPERATURE = "temperature"
195 197
     KEY_OVERTEMPERATURE = "overtemperature"
196 198
     #
@@ -198,13 +200,14 @@ class shelly(base):
198 200
     TX_TYPE = base.TX_VALUE
199 201
     TX_FILTER_DATA_KEYS = [KEY_OUTPUT_0, KEY_OUTPUT_1]
200 202
     #
201
-    RX_KEYS = [KEY_OUTPUT_0, KEY_OUTPUT_1, KEY_INPUT_0,
202
-               KEY_INPUT_1, KEY_OVERTEMPERATURE, KEY_TEMPERATURE]
203
+    RX_KEYS = [KEY_OUTPUT_0, KEY_OUTPUT_1,
204
+               KEY_INPUT_0, KEY_INPUT_1, KEY_LONGPUSH_0, KEY_LONGPUSH_1,
205
+               KEY_OVERTEMPERATURE, KEY_TEMPERATURE]
203 206
     RX_IGNORE_TOPICS = [KEY_OUTPUT_0 + '/' + TX_TOPIC, KEY_OUTPUT_1 + '/' + TX_TOPIC,
204 207
                         KEY_OUTPUT_0 + '/' + "energy", KEY_OUTPUT_1 + '/' + "energy",
205 208
                         'input_event/0', 'input_event/1']
206 209
     RX_IGNORE_KEYS = ['temperature_f']
207
-    RX_FILTER_DATA_KEYS = [KEY_INPUT_0, KEY_INPUT_1,
210
+    RX_FILTER_DATA_KEYS = [KEY_INPUT_0, KEY_INPUT_1, KEY_LONGPUSH_0, KEY_LONGPUSH_1,
208 211
                            KEY_OUTPUT_0, KEY_OUTPUT_1, KEY_OVERTEMPERATURE]
209 212
 
210 213
     def __init__(self, mqtt_client, topic):
@@ -246,6 +249,16 @@ class shelly(base):
246 249
         """rv: [True, False]"""
247 250
         return self.get(self.KEY_INPUT_1)
248 251
 
252
+    @property
253
+    def longpush_0(self):
254
+        """rv: [True, False]"""
255
+        return self.get(self.KEY_LONGPUSH_0)
256
+
257
+    @property
258
+    def longpush_1(self):
259
+        """rv: [True, False]"""
260
+        return self.get(self.KEY_LONGPUSH_1)
261
+
249 262
     @property
250 263
     def temperature(self):
251 264
         """rv: numeric value"""
@@ -450,13 +463,28 @@ class tradfri_light(base):
450 463
 
451 464
 
452 465
 class tradfri_button(base):
466
+    ACTION_TOGGLE = "toggle"
467
+    ACTION_BRIGHTNESS_UP = "brightness_up_click"
468
+    ACTION_BRIGHTNESS_DOWN = "brightness_down_click"
469
+    ACTION_RIGHT = "arrow_right_click"
470
+    ACTION_LEFT = "arrow_left_click"
471
+    ACTION_BRIGHTNESS_UP_LONG = "brightness_up_hold"
472
+    ACTION_BRIGHTNESS_UP_RELEASE = "brightness_up_release"
473
+    ACTION_BRIGHTNESS_DOWN_LONG = "brightness_down_hold"
474
+    ACTION_BRIGHTNESS_DOWN_RELEASE = "brightness_down_release"
475
+    ACTION_RIGHT_LONG = "arrow_right_hold"
476
+    ACTION_RIGHT_RELEASE = "arrow_right_release"
477
+    ACTION_LEFT_LONG = "arrow_left_hold"
478
+    ACTION_LEFT_RELEASE = "arrow_left_release"
479
+    #
453 480
     KEY_LINKQUALITY = "linkquality"
454 481
     KEY_BATTERY = "battery"
455 482
     KEY_ACTION = "action"
483
+    KEY_ACTION_DURATION = "action_duration"
456 484
     #
457 485
     RX_KEYS = [KEY_LINKQUALITY, KEY_BATTERY, KEY_ACTION]
458 486
     RX_IGNORE_TOPICS = []
459
-    RX_IGNORE_KEYS = ['update']
487
+    RX_IGNORE_KEYS = ['update', KEY_ACTION_DURATION]
460 488
     RX_FILTER_DATA_KEYS = []
461 489
 
462 490
     def __init__(self, mqtt_client, topic):
@@ -488,12 +516,13 @@ class nodered_gui(base):
488 516
     KEY_COLOR_TEMP = "color_temp"
489 517
     KEY_HEATING_BOOST = "heating_boost"
490 518
     KEY_HEATING_SETPOINT = "heating_setpoint"
519
+    KEY_OFF_BUTTON = "off_button"
491 520
     #
492 521
     TX_TOPIC = 'set'
493 522
     TX_TYPE = base.TX_VALUE
494 523
     TX_FILTER_DATA_KEYS = []
495 524
     #
496
-    RX_KEYS = [KEY_STATE, KEY_BRIGHTNESS, KEY_COLOR_TEMP, KEY_HEATING_BOOST, KEY_HEATING_SETPOINT]
525
+    RX_KEYS = [KEY_STATE, KEY_BRIGHTNESS, KEY_COLOR_TEMP, KEY_HEATING_BOOST, KEY_HEATING_SETPOINT, KEY_OFF_BUTTON]
497 526
     RX_IGNORE_TOPICS = [KEY_FEEDBACK + '/' + TX_TOPIC, KEY_ENABLE + '/' + TX_TOPIC]
498 527
     RX_FILTER_DATA_KEYS = []
499 528
 
@@ -528,6 +557,11 @@ class nodered_gui(base):
528 557
         """rv: [5, ..., 30]"""
529 558
         return self.get(self.KEY_HEATING_SETPOINT)
530 559
 
560
+    @property
561
+    def off_button(self):
562
+        """rv: [True, False]"""
563
+        return self.get(self.KEY_OFF_BUTTON)
564
+
531 565
     #
532 566
     # TX
533 567
     #

+ 73
- 25
function/__init__.py View File

@@ -7,11 +7,16 @@ from function.first_floor_west import first_floor_west_julian, first_floor_west_
7 7
 from function.first_floor_east import first_floor_east_floor, first_floor_east_kitchen, first_floor_east_dining, first_floor_east_sleep_madi, first_floor_east_living
8 8
 from function.common import common_heating, common_circulation_pump
9 9
 import inspect
10
-from function import modules
10
+import logging
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__)
11 17
 
12
-# TODO: implement switch off functionality (except of switch off button transportation)
13
-# TODO: implement garland (incl. day events like sunset, sunrise, ...)
14 18
 # TODO: implement existing nodered functionality "dirk" (ground floor west)
19
+# TODO: implement garland (incl. day events like sunset, sunrise, ...)
15 20
 # TODO: implement warning message
16 21
 
17 22
 
@@ -20,6 +25,9 @@ class all_functions(object):
20 25
         self.mqtt_client = mqtt_client
21 26
         #
22 27
         self.__devices__ = None
28
+        # heating and warm water
29
+        self.common_heat_sleep_madi = common_heating(self.mqtt_client)
30
+        self.common_circulation_pump = common_circulation_pump(self.mqtt_client)
23 31
         # ground floor west
24 32
         self.gfw_floor = ground_floor_west_floor(self.mqtt_client)
25 33
         self.gfw_marion = ground_floor_west_marion(self.mqtt_client)
@@ -33,35 +41,75 @@ class all_functions(object):
33 41
         self.ffe_dining = first_floor_east_dining(self.mqtt_client)
34 42
         self.ffe_sleep_madi = first_floor_east_sleep_madi(self.mqtt_client)
35 43
         self.ffe_living = first_floor_east_living(self.mqtt_client)
36
-        # heating and warm water
37
-        self.common_heat_sleep_madi = common_heating(self.mqtt_client)
38
-        self.common_circulation_pump = common_circulation_pump(self.mqtt_client)
39 44
         #
40 45
         # Interactions
41 46
         #
42
-        # shelly dirk input 1
43
-        self.last_gfw_dirk_input_1 = None
44
-        self.gfw_dirk.main_light_shelly.add_callback(devices.shelly.KEY_INPUT_1, None, self.gfw_dirk_input_1)
45
-        # input device
46
-        self.init_input_device_sleep_madi_functionality()
47
+        # cross_room_interactions
48
+        self.init_cross_room_interactions()
47 49
         # Circulation pump
48 50
         self.init_circulation_pump()
51
+        # Off Buttons
52
+        self.init_off_functionality()
49 53
 
50
-    def init_input_device_sleep_madi_functionality(self):
54
+    def init_off_functionality(self):
55
+        # Off Buttons
56
+        self.gui_button_all_off = devices.nodered_gui(self.mqtt_client, topic="gui/button_all_off")
57
+        self.gui_button_gfw_off = devices.nodered_gui(self.mqtt_client, topic="gui/button_gfw_off")
58
+        self.gui_button_ffw_off = devices.nodered_gui(self.mqtt_client, topic="gui/button_ffw_off")
59
+        self.gui_button_ffe_off = devices.nodered_gui(self.mqtt_client, topic="gui/button_ffe_off")
51 60
         #
52
-        self.ffe_button_tradfri_sleep = devices.tradfri_button(
53
-            self.mqtt_client, topic="zigbee_og_e/input_device/og_east")
54
-        #
55
-        self.ffe_button_tradfri_sleep.add_callback(devices.tradfri_button.KEY_ACTION, "toggle",
56
-                                                   self.ffe_sleep_madi.toggle_main_light)
57
-        self.ffe_button_tradfri_sleep.add_callback(devices.tradfri_button.KEY_ACTION, "brightness_up_click",
58
-                                                   self.ffe_sleep_madi.toggle_bed_light_di)
59
-        self.ffe_button_tradfri_sleep.add_callback(devices.tradfri_button.KEY_ACTION, "brightness_down_click",
60
-                                                   self.ffe_sleep_madi.toggle_bed_light_di)
61
-        self.ffe_button_tradfri_sleep.add_callback(devices.tradfri_button.KEY_ACTION, "arrow_right_click",
62
-                                                   self.ffe_floor.toggle_main_light)
63
-        self.ffe_button_tradfri_sleep.add_callback(devices.tradfri_button.KEY_ACTION, None,
64
-                                                   self.ffe_sleep_madi.fade_light)
61
+        self.gui_button_all_off.add_callback(devices.nodered_gui.KEY_OFF_BUTTON, True, self.all_off)
62
+        self.gui_button_gfw_off.add_callback(devices.nodered_gui.KEY_OFF_BUTTON, True, self.gfw_off)
63
+        self.gui_button_ffw_off.add_callback(devices.nodered_gui.KEY_OFF_BUTTON, True, self.ffw_off)
64
+        self.gui_button_ffe_off.add_callback(devices.nodered_gui.KEY_OFF_BUTTON, True, self.ffe_off)
65
+        # Long push ffe_floor
66
+        self.ffe_floor.main_light_shelly.add_callback(
67
+            devices.shelly.KEY_LONGPUSH_0, True, self.ffe_floor.all_off_feedback)
68
+        self.ffe_floor.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.ffe_off)
69
+        # Long push input device
70
+        self.ffe_sleep_madi.button_tradfri.add_callback(
71
+            devices.tradfri_button.KEY_ACTION, devices.tradfri_button.ACTION_RIGHT_LONG, self.ffe_off)
72
+
73
+    def getmembers(self, prefix):
74
+        rv = []
75
+        for name, obj in inspect.getmembers(self):
76
+            if name.startswith(prefix) and obj.__module__.split('.')[0] == 'function' and len(obj.__module__.split('.')) == 2:
77
+                rv.append(obj)
78
+        return rv
79
+
80
+    def common_off(self, device=None, key=None, data=None):
81
+        logger.info("Switching \"common\" off.")
82
+        for common in self.getmembers('common'):
83
+            common.all_off()
84
+
85
+    def gfw_off(self, device=None, key=None, data=None):
86
+        logger.info("Switching \"ground floor west\" off.")
87
+        for gfw in self.getmembers('gfw'):
88
+            gfw.all_off()
89
+
90
+    def ffw_off(self, device=None, key=None, data=None):
91
+        logger.info("Switching \"first floor west\" off.")
92
+        for ffw in self.getmembers('ffw'):
93
+            ffw.all_off()
94
+
95
+    def ffe_off(self, device=None, key=None, data=None):
96
+        logger.info("Switching \"first floor east\" off.")
97
+        for ffe in self.getmembers('ffe'):
98
+            ffe.all_off()
99
+
100
+    def all_off(self, device=None, key=None, data=None):
101
+        self.common_off(device, key, data)
102
+        self.gfw_off(device, key, data)
103
+        self.ffw_off(device, key, data)
104
+        self.ffe_off(device, key, data)
105
+
106
+    def init_cross_room_interactions(self):
107
+        # shelly dirk input 1
108
+        self.last_gfw_dirk_input_1 = None
109
+        self.gfw_dirk.main_light_shelly.add_callback(devices.shelly.KEY_INPUT_1, None, self.gfw_dirk_input_1)
110
+        # tradfri button sleep madi right click
111
+        self.ffe_sleep_madi.button_tradfri.add_callback(
112
+            devices.tradfri_button.KEY_ACTION, devices.tradfri_button.ACTION_RIGHT, self.ffe_floor.toggle_main_light)
65 113
 
66 114
     def init_circulation_pump(self):
67 115
         self.common_circulation_pump.main_light_shelly.add_callback(

+ 3
- 0
function/common.py View File

@@ -54,3 +54,6 @@ class common_heating(object):
54 54
     def __init__(self, mqtt_client):
55 55
         self.ffe_heating_sleep_madi = heating_function_brennenstuhl(
56 56
             mqtt_client, "zigbee_og_e/radiator/sleep_madi", 20, "gui/ffe_bo_sleep_madi", "gui/ffe_ts_sleep_madi", "gui/ffe_bl_sleep_madi")
57
+
58
+    def all_off(self):
59
+        pass    # dummy method for compatibility reasons

+ 18
- 3
function/first_floor_east.py View File

@@ -74,10 +74,25 @@ class first_floor_east_sleep_madi(room_shelly_tradfri_light):
74 74
         self.gui_brightness_bed_light_di.enable(False)
75 75
         self.gui_brightness_bed_light_di.set_feedback(0)
76 76
         #
77
+        self.button_tradfri = devices.tradfri_button(mqtt_client, topic="zigbee_og_e/input_device/og_east")
78
+        #
77 79
         # Callback initialisation
78 80
         #
79 81
         self.init_bed_light_functions()
80 82
         self.init_fade_function()
83
+        #
84
+        self.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION, devices.tradfri_button.ACTION_TOGGLE,
85
+                                         self.toggle_main_light)
86
+        self.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION, devices.tradfri_button.ACTION_BRIGHTNESS_UP,
87
+                                         self.toggle_bed_light_di)
88
+        self.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION, devices.tradfri_button.ACTION_BRIGHTNESS_DOWN,
89
+                                         self.toggle_bed_light_di)
90
+        self.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION, None,
91
+                                         self.fade_light)
92
+
93
+    def all_off(self, device=None, key=None, data=None):
94
+        return super().all_off(device, key, data)
95
+        self.bed_light_di_tradfri.set_output_0(False)
81 96
 
82 97
     # bed light
83 98
     def init_bed_light_functions(self):
@@ -143,13 +158,13 @@ class first_floor_east_sleep_madi(room_shelly_tradfri_light):
143 158
             target = self.bed_light_di_tradfri
144 159
         else:
145 160
             return
146
-        if (data == 'brightness_up_hold'):
161
+        if (data == devices.tradfri_button.ACTION_BRIGHTNESS_UP_LONG):
147 162
             logger.info("Increasing brightness \"%s\" %s", type(self).__name__, target.topic)
148 163
             target.brightness_inc()
149
-        elif (data == 'brightness_down_hold'):
164
+        elif (data == devices.tradfri_button.ACTION_BRIGHTNESS_DOWN_LONG):
150 165
             logger.info("Decreasing brightness \"%s\" %s", type(self).__name__, target.topic)
151 166
             target.brightness_dec()
152
-        elif (data.startswith('brightness') and data.endswith('release')):
167
+        elif (data in [devices.tradfri_button.ACTION_BRIGHTNESS_UP_RELEASE, devices.tradfri_button.ACTION_BRIGHTNESS_DOWN_RELEASE]):
153 168
             logger.info("Stoping brightness change \"%s\" %s", type(self).__name__, target.topic)
154 169
             target.brightness_stop()
155 170
 

+ 13
- 4
function/rooms.py View File

@@ -33,13 +33,23 @@ class room_shelly(room):
33 33
         self.gui_switch_main_light.add_callback(devices.nodered_gui.KEY_STATE, None, self.gui_switch_command)
34 34
         self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.gui_switch_feedback)
35 35
         #
36
+        self.block_all_off = False
36 37
         self.last_flash_data = None
37 38
         self.delayed_task = task.delayed(.25, self.toggle_main_light, None, None, None)
38 39
 
39 40
     def all_off(self, device=None, key=None, data=None):
40
-        logger.info("Switching all off \"%s\"", type(self).__name__)
41
-        self.main_light_shelly.set_output_0(False)
42
-        self.main_light_shelly.set_output_1(False)
41
+        if not self.block_all_off:
42
+            logger.info("Switching all off \"%s\"", type(self).__name__)
43
+            self.main_light_shelly.set_output_0(False)
44
+            self.main_light_shelly.set_output_1(False)
45
+        self.block_all_off = False
46
+
47
+    def all_off_feedback(self, device=None, key=None, data=None):
48
+        logger.info("Flashing \"%s\" main light", type(self).__name__)
49
+        if self.main_light_shelly.output_0 is False:
50
+            self.main_light_shelly.set_output_0(True)
51
+            self.block_all_off = True
52
+            self.delayed_task.run()
43 53
 
44 54
     def gui_switch_command(self, device, key, data):
45 55
         logger.info("Switching \"%s\" main light: %s", type(self).__name__, str(data))
@@ -50,7 +60,6 @@ class room_shelly(room):
50 60
         self.main_light_shelly.set_output_0("toggle")
51 61
 
52 62
     def flash_main_light(self, device, key, data):
53
-        logging.info("%s::%s", key, str(data))
54 63
         if self.last_flash_data != data and data is True:
55 64
             logger.info("Flashing \"%s\" main light", type(self).__name__)
56 65
             self.toggle_main_light(device, key, data)

Loading…
Cancel
Save