Bläddra i källkod

added main function first floor east

tags/v1.0.0
Dirk Alders 2 år sedan
förälder
incheckning
a4a8134d31
4 ändrade filer med 197 tillägg och 99 borttagningar
  1. 36
    1
      devices/__init__.py
  2. 157
    6
      function/__init__.py
  3. 0
    24
      function/first_floor_dining.py
  4. 4
    68
      smart_brain.py

+ 36
- 1
devices/__init__.py Visa fil

@@ -40,6 +40,10 @@ logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
40 40
 BATTERY_WARN_LEVEL = 5
41 41
 
42 42
 
43
+def DEVICE_TYPE_LIST():
44
+    return [shelly, silvercrest_powerplug, my_powerplug, tradfri_light, tradfri_button]
45
+
46
+
43 47
 def is_json(data):
44 48
     try:
45 49
         json.loads(data)
@@ -163,7 +167,7 @@ class base(dict):
163 167
 
164 168
     def callback_caller(self, key, data):
165 169
         for cb_key, cb_data, callback in self.callback_list:
166
-            if (cb_key == key or cb_key is None) and (cb_data == data or cb_data is None):
170
+            if (cb_key == key or cb_key is None) and (cb_data == data or cb_data is None) and callback is not None:
167 171
                 callback(self, key, data)
168 172
 
169 173
     def warning_caller(self):
@@ -459,3 +463,34 @@ class tradfri_button(base):
459 463
 
460 464
     def warning_text(self):
461 465
         return "Low battery level detected for %s. Battery level was %.0f%%." % (self.topic, self.get(self.KEY_BATTERY))
466
+
467
+
468
+class nodered_gui(base):
469
+    KEY_FEEDBACK = "feedback"
470
+    KEY_STATE = "state"
471
+    #
472
+    TX_TOPIC = 'set'
473
+    TX_TYPE = base.TX_VALUE
474
+    TX_FILTER_DATA_KEYS = []
475
+    #
476
+    RX_LOG_INFO_ALWAYS_KEYS = []
477
+    RX_KEYS = [KEY_STATE]
478
+    RX_IGNORE_TOPICS = [KEY_FEEDBACK + '/' + TX_TOPIC]
479
+    RX_FILTER_DATA_KEYS = []
480
+
481
+    def __init__(self, mqtt_client, topic):
482
+        super().__init__(mqtt_client, topic)
483
+
484
+    #
485
+    # RX
486
+    #
487
+    @property
488
+    def state(self):
489
+        """rv: [True, False]"""
490
+        return self.get(self.KEY_STATE)
491
+
492
+    #
493
+    # TX
494
+    #
495
+    def set_feedback(self, data):
496
+        self.pack(self.KEY_FEEDBACK, data)

+ 157
- 6
function/__init__.py Visa fil

@@ -1,19 +1,170 @@
1 1
 #!/usr/bin/env python
2 2
 # -*- coding: utf-8 -*-
3 3
 #
4
+import config
5
+import devices
6
+import inspect
4 7
 import logging
5 8
 
6
-__all__ = ['all_functions', 'first_floor_dining']
7
-
8
-from . import first_floor_dining
9
-
10 9
 try:
11 10
     from config import APP_NAME as ROOT_LOGGER_NAME
12 11
 except ImportError:
13 12
     ROOT_LOGGER_NAME = 'root'
14 13
 logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
15 14
 
15
+# TODO: Add brightness and color temp including disable of gui elements.
16
+# TODO: Add lamp sleep_di
17
+
18
+
19
+class room(object):
20
+    def gui_switch_feedback(self, device, key, data):
21
+        self.gui_switch_main_light.set_feedback(data)
22
+
23
+
24
+class room_shelly(room):
25
+    def __init__(self, mqtt_client, topic_shelly, topic_gui_switch):
26
+        self.main_light_shelly = devices.shelly(mqtt_client, topic=topic_shelly)
27
+        #
28
+        self.gui_switch_main_light = devices.nodered_gui(mqtt_client, topic=topic_gui_switch)
29
+        #
30
+        # Callback initialisation
31
+        #
32
+        self.gui_switch_main_light.add_callback(devices.nodered_gui.KEY_STATE, None, self.gui_switch_command)
33
+        self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.gui_switch_feedback)
34
+
35
+    def all_off(self):
36
+        self.main_light_shelly.set_output_0(False)
37
+        self.main_light_shelly.set_output_1(False)
38
+
39
+    def gui_switch_command(self, device, key, data):
40
+        logger.info("Switching \"%s\" main light: %s", type(self).__name__, str(data))
41
+        self.main_light_shelly.set_output_0(data)
42
+
43
+
44
+class first_floor_east_floor(room_shelly):
45
+    def __init__(self, mqtt_client):
46
+        # http://shelly1l-3C6105E4E629
47
+        super().__init__(mqtt_client, "shellies/floor_madi", "gui/ffe_floor")
48
+
49
+
50
+class first_floor_east_kitchen(room_shelly):
51
+    # TODO: add circulation pump (switch, time)
52
+    def __init__(self, mqtt_client):
53
+        # http://shelly1l-8CAAB5616C01
54
+        super().__init__(mqtt_client, "shellies/kitchen", "gui/ffe_kitchen")
55
+
56
+
57
+class first_floor_east_dining(room_shelly):
58
+    def __init__(self, mqtt_client):
59
+        # http://shelly1l-84CCA8ADD055
60
+        super().__init__(mqtt_client, "shellies/diningroom", "gui/ffe_diningroom")
61
+        self.floorlamp_powerplug = devices.silvercrest_powerplug(mqtt_client, "zigbee_og_e/powerplug/dining_floorlamp")
62
+        if config.CHRISTMAS:
63
+            self.garland_powerplug = devices.silvercrest_powerplug(mqtt_client, topic="zigbee_og_e/powerplug/aux")
64
+        #
65
+        self.gui_switch_floorlamp = devices.nodered_gui(mqtt_client, topic="gui/ffe_dining_floorlamp")
66
+        #
67
+        # Callback initialisation
68
+        #
69
+        self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.floorlamp_synchronisation)
70
+        self.gui_switch_floorlamp.add_callback(devices.nodered_gui.KEY_STATE, None, self.gui_switch_command_floorlamp)
71
+        self.floorlamp_powerplug.add_callback(devices.silvercrest_powerplug.KEY_OUTPUT_0,
72
+                                              None, self.gui_switch_feedback_floorlamp)
73
+        #
74
+        self.main_light_shelly_last = None
75
+
76
+    def floorlamp_synchronisation(self, device, key, data):
77
+        if data != self.main_light_shelly_last:
78
+            logger.info("Synching \"%s\" floorlamp with main light (%s)", type(self).__name__, str(data))
79
+            self.floorlamp_powerplug.set_output_0(data)
80
+        self.main_light_shelly_last = data
81
+
82
+    def gui_switch_command_floorlamp(self, device, key, data):
83
+        logger.info("Switching \"%s\" floorlamp: %s", type(self).__name__, str(data))
84
+        self.floorlamp_powerplug.set_output_0(data)
85
+
86
+    def gui_switch_feedback_floorlamp(self, device, key, data):
87
+        self.gui_switch_floorlamp.set_feedback(data)
88
+
89
+
90
+class first_floor_east_sleep_madi(room_shelly):
91
+    def __init__(self, mqtt_client):
92
+        # http://shelly1l-E8DB84A254C7
93
+        super().__init__(mqtt_client, "shellies/sleep_madi", "gui/ffe_sleep_madi")
94
+        self.main_light_tradfri = devices.tradfri_light(mqtt_client, topic="zigbee_og_e/light/sleep_madi")
95
+        self.bed_light_di_tradfri = devices.tradfri_light(mqtt_client, topic="zigbee_og_e/light/sleep_bed_di")
96
+        self.button_tradfri = devices.tradfri_button(mqtt_client, topic="zigbee_og_e/input_device/og_east")
97
+
98
+
99
+class first_floor_east_living(room_shelly):
100
+    def __init__(self, mqtt_client):
101
+        # http://shelly1l-3C6105E3F910
102
+        super().__init__(mqtt_client, "shellies/livingroom", "gui/ffe_livingroom")
103
+        self.main_light_tradfri = devices.tradfri_light(mqtt_client, topic="zigbee_og_e/light/livingroom")
104
+        for i in range(1, 7):
105
+            setattr(self, 'floorlamp_tradfri_%d' % i,
106
+                    devices.tradfri_light(mqtt_client, topic="zigbee_og_e/light/living_floorlamp_%d" % i))
107
+        #
108
+        self.gui_switch_floorlamp = devices.nodered_gui(mqtt_client, topic="gui/ffe_living_floorlamp")
109
+        #
110
+        # Callback initialisation
111
+        #
112
+        self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.floorlamp_synchronisation)
113
+        self.gui_switch_floorlamp.add_callback(devices.nodered_gui.KEY_STATE, None, self.gui_switch_command_floorlamp)
114
+        self.floorlamp_tradfri_1.add_callback(devices.tradfri_light.KEY_OUTPUT_0,
115
+                                              None, self.gui_switch_feedback_floorlamp)
116
+        #
117
+        self.main_light_shelly_last = None
118
+
119
+    def __floorlamp_devices__(self):
120
+        rv = []
121
+        for i in range(1, 7):
122
+            rv.append(getattr(self, 'floorlamp_tradfri_%d' % i))
123
+        return rv
124
+
125
+    def floorlamp_synchronisation(self, device, key, data):
126
+        if data != self.main_light_shelly_last:
127
+            logger.info("Synching \"%s\" floorlamp with main light (%s)", type(self).__name__, str(data))
128
+            for device in self.__floorlamp_devices__():
129
+                device.set_output_0(data)
130
+        self.main_light_shelly_last = data
131
+
132
+    def gui_switch_command_floorlamp(self, device, key, data):
133
+        logger.info("Switching \"%s\" floorlamp: %s", type(self).__name__, str(data))
134
+        for device in self.__floorlamp_devices__():
135
+            device.set_output_0(data)
136
+
137
+    def gui_switch_feedback_floorlamp(self, device, key, data):
138
+        self.gui_switch_floorlamp.set_feedback(data)
139
+
16 140
 
17 141
 class all_functions(object):
18
-    def __init__(self, device_collection):
19
-        first_floor_dining.room_function(device_collection)
142
+    def __init__(self, mqtt_client):
143
+        self.rooms = {}
144
+        self.__devices__ = None
145
+        #
146
+        # first floor east
147
+        #
148
+        self.ffe_floor = first_floor_east_floor(mqtt_client)
149
+        self.ffe_kitchen = first_floor_east_kitchen(mqtt_client)
150
+        self.ffe_dining = first_floor_east_dining(mqtt_client)
151
+        self.ffe_sleep_madi = first_floor_east_sleep_madi(mqtt_client)
152
+        self.ffe_living = first_floor_east_living(mqtt_client)
153
+
154
+    def ffe_off(self):
155
+        self.ffe_floor.off()
156
+        self.ffe_kitchen.off()
157
+        self.ffe_dining.off()
158
+        self.ffe_sleep_madi.off()
159
+        self.ffe_living.off()
160
+
161
+    def devicelist(self):
162
+        raise Exception
163
+        # TODO: generate list by using getattr
164
+        if self.__devices__ is None:
165
+            self.__devices__ = []
166
+            for room in self.rooms:
167
+                for name, obj in inspect.getmembers(room):
168
+                    if type(obj) in devices.DEVICE_TYPE_LIST():
169
+                        self.__devices__.append(obj)
170
+        return self.__devices__

+ 0
- 24
function/first_floor_dining.py Visa fil

@@ -1,24 +0,0 @@
1
-import devices
2
-import logging
3
-
4
-try:
5
-    from config import APP_NAME as ROOT_LOGGER_NAME
6
-except ImportError:
7
-    ROOT_LOGGER_NAME = 'root'
8
-logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
9
-
10
-
11
-class room_function(object):
12
-    def __init__(self, device_collection):
13
-        self.main_light_shelly = device_collection.shellies.dinigroom
14
-        self.floorlamp_powerplug = device_collection.powerplugs.dining_floorlamp
15
-        #
16
-        self.main_light_shelly.add_callback(devices.shelly.KEY_OUTPUT_0, None, self.main_light_shelly_callback)
17
-        #
18
-        self.main_light_shelly_last = None
19
-
20
-    def main_light_shelly_callback(self, device, key, data):
21
-        if data != self.main_light_shelly_last:
22
-            logger.info("Test")
23
-            self.floorlamp_powerplug.set_output_0(data)
24
-        self.main_light_shelly_last

+ 4
- 68
smart_brain.py Visa fil

@@ -11,66 +11,9 @@ import time
11 11
 logger = logging.getLogger(config.APP_NAME)
12 12
 
13 13
 
14
-class shellies(object):
15
-    def __init__(self, mc):
16
-        self.dinigroom = devices.shelly(mc, topic="shellies/diningroom")            # http://shelly1l-84CCA8ADD055
17
-        self.sleep_madi = devices.shelly(mc, topic="shellies/sleep_madi")           # http://shelly1l-E8DB84A254C7
18
-        # self._ = devices.shelly(mc, topic="")            # http://
19
-        # self._ = devices.shelly(mc, topic="")            # http://
20
-        # self._ = devices.shelly(mc, topic="")            # http://
21
-        # self._ = devices.shelly(mc, topic="")            # http://
22
-        # self._ = devices.shelly(mc, topic="")            # http://
23
-        # self._ = devices.shelly(mc, topic="")            # http://
24
-        # self._ = devices.shelly(mc, topic="")            # http://
25
-
26
-
27
-class powerplugs(object):
28
-    def __init__(self, mc):
29
-        self.dining_floorlamp = devices.silvercrest_powerplug(mc, "zigbee_og_e/powerplug/dining_floorlamp")
30
-        self.aux = devices.silvercrest_powerplug(mc, topic="zigbee_og_e/powerplug/aux")
31
-        self.dirk = devices.my_powerplug(mc, "powerplug/dirk")
32
-
33
-
34
-class lights(object):
35
-    def __init__(self, mc):
36
-        self.sleep_madi = devices.tradfri_light(mc, topic="zigbee_og_e/light/sleep_madi")
37
-        self.sleep_bed_di = devices.tradfri_light(mc, topic="zigbee_og_e/light/sleep_bed_di")
38
-        # self._ = devices.tradfri_light(mc, topic="")
39
-        # self._ = devices.tradfri_light(mc, topic="")
40
-        # self._ = devices.tradfri_light(mc, topic="")
41
-        # self._ = devices.tradfri_light(mc, topic="")
42
-        # self._ = devices.tradfri_light(mc, topic="")
43
-        # self._ = devices.tradfri_light(mc, topic="")
44
-        # self._ = devices.tradfri_light(mc, topic="")
45
-        # self._ = devices.tradfri_light(mc, topic="")
46
-        # self._ = devices.tradfri_light(mc, topic="")
47
-
48
-
49
-class input_devices(object):
50
-    def __init__(self, mc):
51
-        self.og_east = devices.tradfri_button(mc, topic="zigbee_og_e/input_device/og_east")
52
-
53
-
54
-class all_devices(object):
55
-    def __init__(self, mc):
56
-        self.shellies = shellies(mc)
57
-        self.powerplugs = powerplugs(mc)
58
-        self.lights = lights(mc)
59
-        self.input_devices = input_devices(mc)
60
-
61
-    def devicelist(self):
62
-        rv = []
63
-        for name, obj in inspect.getmembers(self):
64
-            if not name.startswith('_') and name != inspect.stack()[0][3]:
65
-                for devicename, deviceobj in inspect.getmembers(obj):
66
-                    if not devicename.startswith('_'):
67
-                        rv.append(deviceobj)
68
-        return rv
69
-
70
-
71 14
 if __name__ == "__main__":
72 15
     if config.DEBUG:
73
-        report.stdoutLoggingConfigure(([config.APP_NAME, config.DEBUGLEVEL], ), report.LONG_FMT)
16
+        report.stdoutLoggingConfigure(([config.APP_NAME, logging.DEBUG], ), report.LONG_FMT)
74 17
     else:
75 18
         report.stdoutLoggingConfigure(((config.APP_NAME, logging.INFO),
76 19
                                       (config.APP_NAME+'.devices', logging.WARNING)), report.SHORT_FMT)
@@ -78,17 +21,10 @@ if __name__ == "__main__":
78 21
     mc = mqtt.mqtt_client(host=config.MQTT_SERVER, port=config.MQTT_PORT,
79 22
                           username=config.MQTT_USER, password=config.MQTT_PASSWORD, name=config.APP_NAME)
80 23
 
81
-    ad = all_devices(mc)
82
-    func = function.all_functions(ad)
83
-
84
-    # def wcb(device, txt):
85
-    #     logger.warning("%s: %s", device.topic, txt)
86
-    # for device in ad.devicelist():
87
-    #     device.add_warning_callback(wcb)
24
+    func = function.all_functions(mc)
88 25
 
89
-    # def cb(device, key, data):
90
-    #     print("Callback: %s::%s" % (key, str(data)))
91
-    # ad.shellies.dinigroom.add_callback(devices.shelly.KEY_OUTPUT_0, None, cb)
26
+    # for device in func.devicelist():
27
+    #     device.add_warning_callback(None)
92 28
 
93 29
     while (True):
94 30
         time.sleep(1)

Laddar…
Avbryt
Spara