ソースを参照

all_off functionality added

tags/v1.0.0
Dirk Alders 1年前
コミット
6c1f81f0be
7個のファイルの変更135行の追加80行の削除
  1. 23
    74
      function/__init__.py
  2. 11
    1
      function/first_floor_east.py
  3. 10
    1
      function/first_floor_west.py
  4. 9
    1
      function/ground_floor_west.py
  5. 16
    0
      function/rooms.py
  6. 8
    2
      function/stairway.py
  7. 58
    1
      function/videv.py

+ 23
- 74
function/__init__.py ファイルの表示

@@ -1,11 +1,14 @@
1 1
 #!/usr/bin/env python
2 2
 # -*- coding: utf-8 -*-
3 3
 #
4
+import config
4 5
 import devices
5 6
 from function.stairway import stairway
6
-from function.ground_floor_west import ground_floor_west_floor, ground_floor_west_marion, ground_floor_west_dirk
7
-from function.first_floor_west import first_floor_west_julian, first_floor_west_living, first_floor_west_bath, first_floor_west_sleep
8
-from function.first_floor_east import first_floor_east_floor, first_floor_east_kitchen, first_floor_east_dining, first_floor_east_sleep, first_floor_east_living
7
+from function.ground_floor_west import ground_floor_west
8
+from function.first_floor_west import first_floor_west
9
+from function.first_floor_east import first_floor_east
10
+from function.rooms import room_collection
11
+from function.videv import all_off
9 12
 import inspect
10 13
 import logging
11 14
 
@@ -19,31 +22,20 @@ logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
19 22
 # TODO: implement warning message
20 23
 
21 24
 
22
-class all_functions(object):
25
+class all_functions(room_collection):
23 26
     def __init__(self, mqtt_client):
24
-        self.mqtt_client = mqtt_client
25
-        #
26
-        self.__devices__ = None
27
+        super().__init__(mqtt_client)
27 28
         #
28 29
         # Rooms
29 30
         #
30 31
         # stairway
31
-        self.stw_stairway = stairway(self.mqtt_client)
32
+        self.stw = stairway(self.mqtt_client)
32 33
         # ground floor west
33
-        self.gfw_floor = ground_floor_west_floor(self.mqtt_client)
34
-        self.gfw_marion = ground_floor_west_marion(self.mqtt_client)
35
-        self.gfw_dirk = ground_floor_west_dirk(self.mqtt_client)
34
+        self.gfw = ground_floor_west(self.mqtt_client)
36 35
         # first floor west
37
-        self.ffw_julian = first_floor_west_julian(self.mqtt_client)
38
-        self.ffw_bath = first_floor_west_bath(self.mqtt_client)
39
-        self.ffw_living = first_floor_west_living(self.mqtt_client)
40
-        self.ffw_sleep = first_floor_west_sleep(self.mqtt_client)
36
+        self.ffw = first_floor_west(self.mqtt_client)
41 37
         # first floor east
42
-        self.ffe_floor = first_floor_east_floor(self.mqtt_client)
43
-        self.ffe_kitchen = first_floor_east_kitchen(self.mqtt_client)
44
-        self.ffe_dining = first_floor_east_dining(self.mqtt_client)
45
-        self.ffe_sleep = first_floor_east_sleep(self.mqtt_client)
46
-        self.ffe_living = first_floor_east_living(self.mqtt_client)
38
+        self.ffe = first_floor_east(self.mqtt_client)
47 39
         #
48 40
         # Interactions
49 41
         #
@@ -55,71 +47,28 @@ class all_functions(object):
55 47
     def init_cross_room_interactions(self):
56 48
         # shelly dirk input 1
57 49
         self.last_gfw_dirk_input_1 = None
58
-        self.gfw_dirk.main_light_shelly.add_callback(devices.shelly.KEY_INPUT_1, None, self.gfw_dirk_input_1)
50
+        self.gfw.dirk.main_light_shelly.add_callback(devices.shelly.KEY_INPUT_1, None, self.gfw_dirk_input_1)
59 51
         # tradfri button ffe_sleep right click
60
-        self.ffe_sleep.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION,
61
-                                                   devices.tradfri_button.ACTION_RIGHT, self.ffe_floor.main_light_shelly.toggle_output_0_mcb)
52
+        self.ffe.sleep.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION,
53
+                                                   devices.tradfri_button.ACTION_RIGHT, self.ffe.floor.main_light_shelly.toggle_output_0_mcb)
62 54
 
63 55
     def init_off_functionality(self):
64
-        ##### TEMPORARY ###################################################################################################################
65
-        # # Off Buttons
66
-        # self.gui_button_all_off = devices.nodered_gui_button(self.mqtt_client, "gui/all/common/off/button")
67
-        # self.gui_button_gfw_off = devices.nodered_gui_button(self.mqtt_client, "gui/gfw/common/off/button")
68
-        # self.gui_button_ffw_off = devices.nodered_gui_button(self.mqtt_client, "gui/ffw/common/off/button")
69
-        # self.gui_button_ffe_off = devices.nodered_gui_button(self.mqtt_client, "gui/ffe/common/off/button")
70
-        # #
71
-        # self.gui_button_all_off.add_callback(devices.nodered_gui_button.KEY_STATE, True, self.all_off)
72
-        # self.gui_button_gfw_off.add_callback(devices.nodered_gui_button.KEY_STATE, True, self.gfw_off)
73
-        # self.gui_button_ffw_off.add_callback(devices.nodered_gui_button.KEY_STATE, True, self.ffw_off)
74
-        # self.gui_button_ffe_off.add_callback(devices.nodered_gui_button.KEY_STATE, True, self.ffe_off)
75
-        ##### TEMPORARY ###################################################################################################################
56
+        # ALL OFF - Virtual device
57
+        self.videv_all_off = all_off(self.mqtt_client, config.TOPIC_ALL_OFF_VIDEV, self)
76 58
 
77 59
         # ALL OFF - Long push stairway
78
-        self.stw_stairway.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.stw_stairway.main_light_shelly.flash_0_mcb)
79
-        self.stw_stairway.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.all_off)
60
+        self.stw.stairway.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.stw.stairway.main_light_shelly.flash_0_mcb)
61
+        self.stw.stairway.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.all_off)
80 62
 
81 63
         # FFE ALL OFF - Long push ffe_floor
82
-        self.ffe_floor.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.ffe_floor.main_light_shelly.flash_0_mcb)
83
-        self.ffe_floor.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.ffe_off)
64
+        self.ffe.floor.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.ffe.floor.main_light_shelly.flash_0_mcb)
65
+        self.ffe.floor.main_light_shelly.add_callback(devices.shelly.KEY_LONGPUSH_0, True, self.ffe.all_off)
84 66
 
85 67
         # FFE ALL OFF - Long push input device
86
-        self.ffe_sleep.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION, devices.tradfri_button.ACTION_RIGHT_LONG, self.ffe_off)
68
+        self.ffe.sleep.button_tradfri.add_callback(devices.tradfri_button.KEY_ACTION, devices.tradfri_button.ACTION_RIGHT_LONG, self.ffe.all_off)
87 69
 
88 70
     def gfw_dirk_input_1(self, device, key, data):
89 71
         if self.last_gfw_dirk_input_1 is not None:
90 72
             if self.last_gfw_dirk_input_1 != data:
91
-                self.gfw_floor.main_light_shelly.toggle_output_0_mcb(device, key, data)
73
+                self.gfw.floor.main_light_shelly.toggle_output_0_mcb(device, key, data)
92 74
         self.last_gfw_dirk_input_1 = data
93
-
94
-    def getmembers(self, prefix):
95
-        rv = []
96
-        for name, obj in inspect.getmembers(self):
97
-            if name.startswith(prefix) and obj.__module__.split('.')[0] == 'function' and len(obj.__module__.split('.')) == 2:
98
-                rv.append(obj)
99
-        return rv
100
-
101
-    def gfw_off(self, device=None, key=None, data=None):
102
-        logger.info("Switching \"ground floor west\" off.")
103
-        for gfw in self.getmembers('gfw'):
104
-            gfw.all_off()
105
-
106
-    def ffw_off(self, device=None, key=None, data=None):
107
-        logger.info("Switching \"first floor west\" off.")
108
-        for ffw in self.getmembers('ffw'):
109
-            ffw.all_off()
110
-
111
-    def ffe_off(self, device=None, key=None, data=None):
112
-        logger.info("Switching \"first floor east\" off.")
113
-        for ffe in self.getmembers('ffe'):
114
-            ffe.all_off()
115
-
116
-    def stw_off(self, device=None, key=None, data=None):
117
-        logger.info("Switching \"stairway\" off.")
118
-        for stw in self.getmembers('stw'):
119
-            stw.all_off()
120
-
121
-    def all_off(self, device=None, key=None, data=None):
122
-        for name, obj in inspect.getmembers(self):
123
-            parent_name = obj.__class__.__base__.__name__
124
-            if parent_name == "room":
125
-                obj.all_off()

+ 11
- 1
function/first_floor_east.py ファイルの表示

@@ -5,7 +5,7 @@
5 5
 import config
6 6
 import devices
7 7
 from function.modules import brightness_choose_n_action, timer_on_activation, heating_function
8
-from function.rooms import room
8
+from function.rooms import room, room_collection
9 9
 from function.videv import videv_switching, videv_switch_brightness, videv_switching_timer, videv_switch_brightness_color_temp, videv_heating, videv_multistate
10 10
 import logging
11 11
 
@@ -16,6 +16,16 @@ except ImportError:
16 16
 logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
17 17
 
18 18
 
19
+class first_floor_east(room_collection):
20
+    def __init__(self, mqtt_client):
21
+        super().__init__(mqtt_client)
22
+        self.dining = first_floor_east_dining(mqtt_client)
23
+        self.floor = first_floor_east_floor(mqtt_client)
24
+        self.kitchen = first_floor_east_kitchen(mqtt_client)
25
+        self.livingroom = first_floor_east_living(mqtt_client)
26
+        self.sleep = first_floor_east_sleep(mqtt_client)
27
+
28
+
19 29
 class first_floor_east_floor(room):
20 30
     def __init__(self, mqtt_client):
21 31
         #

+ 10
- 1
function/first_floor_west.py ファイルの表示

@@ -5,7 +5,7 @@
5 5
 import config
6 6
 import devices
7 7
 from function.modules import heating_function
8
-from function.rooms import room
8
+from function.rooms import room, room_collection
9 9
 from function.videv import videv_switch_brightness, videv_switch_brightness_color_temp, videv_heating
10 10
 import logging
11 11
 
@@ -17,6 +17,15 @@ except ImportError:
17 17
 logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
18 18
 
19 19
 
20
+class first_floor_west(room_collection):
21
+    def __init__(self, mqtt_client):
22
+        super().__init__(mqtt_client)
23
+        self.bath = first_floor_west_bath(mqtt_client)
24
+        self.julian = first_floor_west_julian(mqtt_client)
25
+        self.livingroom = first_floor_west_living(mqtt_client)
26
+        self.sleep = first_floor_west_sleep(mqtt_client)
27
+
28
+
20 29
 class first_floor_west_julian(room):
21 30
     def __init__(self, mqtt_client):
22 31
         #

+ 9
- 1
function/ground_floor_west.py ファイルの表示

@@ -5,7 +5,7 @@
5 5
 import config
6 6
 import devices
7 7
 from function.modules import brightness_choose_n_action, heating_function, switched_light
8
-from function.rooms import room
8
+from function.rooms import room, room_collection
9 9
 from function.videv import videv_switching, videv_switch_brightness_color_temp, videv_heating, videv_multistate, videv_audio_player
10 10
 import logging
11 11
 import task
@@ -17,6 +17,14 @@ except ImportError:
17 17
 logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
18 18
 
19 19
 
20
+class ground_floor_west(room_collection):
21
+    def __init__(self, mqtt_client):
22
+        super().__init__(mqtt_client)
23
+        self.dirk = ground_floor_west_dirk(mqtt_client)
24
+        self.floor = ground_floor_west_floor(mqtt_client)
25
+        self.marion = ground_floor_west_marion(mqtt_client)
26
+
27
+
20 28
 class ground_floor_west_floor(room):
21 29
     def __init__(self, mqtt_client):
22 30
         #

+ 16
- 0
function/rooms.py ファイルの表示

@@ -24,3 +24,19 @@ class room(object):
24 24
                     obj.all_off()
25 25
             except AttributeError:
26 26
                 pass    # not a module or has no method all_off
27
+
28
+
29
+class room_collection(object):
30
+    ALLOWED_CLASSES = ("room", "room_collection")
31
+
32
+    def __init__(self, mqtt_client):
33
+        self.mqtt_client = mqtt_client
34
+
35
+    def all_off(self, device=None, key=None, data=None):
36
+        logger.info("Switching all off \"%s\"", type(self).__name__)
37
+        for sub_name in dir(self):
38
+            # attribute name is not private
39
+            if not sub_name.startswith("__"):
40
+                sub = getattr(self, sub_name)
41
+                if sub.__class__.__bases__[0].__name__ in self.ALLOWED_CLASSES:
42
+                    sub.all_off()

+ 8
- 2
function/stairway.py ファイルの表示

@@ -6,7 +6,7 @@ import config
6 6
 import devices
7 7
 import logging
8 8
 from function.modules import motion_sensor_light
9
-from function.rooms import room
9
+from function.rooms import room, room_collection
10 10
 from function.videv import videv_switching_motion
11 11
 
12 12
 try:
@@ -16,7 +16,13 @@ except ImportError:
16 16
 logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
17 17
 
18 18
 
19
-class stairway(room):
19
+class stairway(room_collection):
20
+    def __init__(self, mqtt_client):
21
+        super().__init__(mqtt_client)
22
+        self.stairway = stairway_stairway(mqtt_client)
23
+
24
+
25
+class stairway_stairway(room):
20 26
     def __init__(self, mqtt_client):
21 27
         #
22 28
         # Device initialisation

+ 58
- 1
function/videv.py ファイルの表示

@@ -11,7 +11,7 @@ Targets:
11 11
 """
12 12
 
13 13
 from base import mqtt_base
14
-import devices
14
+from function.rooms import room, room_collection
15 15
 import json
16 16
 import time
17 17
 
@@ -258,3 +258,60 @@ class videv_audio_player(base):
258 258
         super().capabilities
259 259
         self.__capabilities__[self.KEY_TITLE] = {'display': True}
260 260
         return self.__capabilities__
261
+
262
+
263
+class all_off(base):
264
+    ALLOWED_CLASSES = (room, room_collection, )
265
+
266
+    def __init__(self, mqtt_client, topic, room_collection):
267
+        super().__init__(mqtt_client, topic)
268
+        self.__room_collection__ = room_collection
269
+        # init __inst_dict__
270
+        self.__inst_dict__ = {}
271
+        self.__add_instances__("all", self.__room_collection__)
272
+        # register mqtt callbacks for all my keys
273
+        for key in self.__inst_dict__:
274
+            mqtt_client.add_callback(topic + "/" + key, self.all_off)
275
+        #
276
+        self.__tx_capabilities__()
277
+
278
+    def __check_inst_capabilities__(self, name, inst):
279
+        # fits to specified classes
280
+        if isinstance(inst, self.ALLOWED_CLASSES):
281
+            try:
282
+                # all_off method is callable
283
+                return callable(inst.all_off)
284
+            except AttributeError:
285
+                # all_off method does not exist
286
+                return False
287
+        return False
288
+
289
+    def __add_instances__(self, name, inst, level=0):
290
+        if self.__check_inst_capabilities__(name, inst):
291
+            # add given instance to my __inst_dict__
292
+            self.__inst_dict__[name] = inst
293
+            # iterate over all attribute names of instance
294
+            for sub_name in dir(inst):
295
+                # attribute name is not private
296
+                if not sub_name.startswith("__"):
297
+                    sub = getattr(inst, sub_name)
298
+                    # recurse with this object
299
+                    if level == 0:
300
+                        self.__add_instances__(sub_name, sub, level=level+1)
301
+                    else:
302
+                        self.__add_instances__(name + "/" + sub_name, sub, level=level+1)
303
+
304
+    def all_off(self, client, userdata, message):
305
+        key = message.topic[len(self.topic) + 1:]
306
+        self.__inst_dict__[key].all_off()
307
+        self.__tx_capabilities__()
308
+
309
+    @property
310
+    def capabilities(self):
311
+        if self.__capabilities__ is None:
312
+            self.__capabilities__ = {}
313
+            self.__capabilities__['__type__'] = self.__class__.__name__
314
+            for key in self.__inst_dict__:
315
+                self.__capabilities__[key] = {}
316
+                self.__capabilities__[key]['control'] = True
317
+        return self.__capabilities__

読み込み中…
キャンセル
保存