瀏覽代碼

Initial zigbee heating valve check implemented

master
Dirk Alders 1 年之前
父節點
當前提交
9b3e64060b

+ 2
- 0
.gitignore 查看文件

@@ -1,3 +1,5 @@
1
+z_server/config.py
2
+
1 3
 # ---> Linux
2 4
 *~
3 5
 

+ 21
- 0
.gitmodules 查看文件

@@ -1,3 +1,24 @@
1 1
 [submodule "nagios"]
2 2
 	path = nagios
3 3
 	url = https://git.mount-mockery.de/pylib/nagios.git
4
+[submodule "z_server/mqtt"]
5
+	path = z_server/mqtt
6
+	url = https://git.mount-mockery.de/pylib/mqtt.git
7
+[submodule "z_server/report"]
8
+	path = z_server/report
9
+	url = https://git.mount-mockery.de/pylib/report.git
10
+[submodule "z_server/socket_protocol"]
11
+	path = socket_protocol
12
+	url = https://git.mount-mockery.de/pylib/socket_protocol.git
13
+[submodule "z_server/stringtools"]
14
+	path = stringtools
15
+	url = https://git.mount-mockery.de/pylib/stringtools.git
16
+[submodule "z_server/task"]
17
+	path = task
18
+	url = https://git.mount-mockery.de/pylib/task.git
19
+[submodule "z_server/tcp_socket"]
20
+	path = tcp_socket
21
+	url = https://git.mount-mockery.de/pylib/tcp_socket.git
22
+[submodule "z_server/smart_devdi"]
23
+	path = z_server/devdi
24
+	url = https://git.mount-mockery.de/smarthome/smart_devdi.git

+ 16
- 0
.vscode/launch.json 查看文件

@@ -0,0 +1,16 @@
1
+{
2
+    // Verwendet IntelliSense zum Ermitteln möglicher Attribute.
3
+    // Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen.
4
+    // Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387
5
+    "version": "0.2.0",
6
+    "configurations": [
7
+        {
8
+            "name": "Python: Main File execution",
9
+            "type": "python",
10
+            "request": "launch",
11
+            "program": "${workspaceFolder}/z_server/z_server.py",
12
+            "console": "integratedTerminal",
13
+            "justMyCode": true
14
+        }
15
+    ]
16
+}

+ 1
- 0
.vscode/settings.json 查看文件

@@ -1,4 +1,5 @@
1 1
 {
2
+  "python.defaultInterpreterPath": "./z_server/venv/bin/python",
2 3
   "autopep8.args": ["--max-line-length=150"],
3 4
   "[python]": {
4 5
     "python.formatting.provider": "none",

+ 36
- 0
check_z_heat_vlv 查看文件

@@ -0,0 +1,36 @@
1
+#!/bin/python3
2
+#
3
+
4
+import argparse
5
+import nagios
6
+import time
7
+from z_server import config
8
+from z_server import tcp_socket
9
+from z_server.z_protocol import server as client_prot
10
+from z_server.z_protocol import DID_FOLLOWS_HEATING_SETPOINT
11
+from z_server import socket_protocol
12
+import sys
13
+
14
+if __name__ == '__main__':
15
+    parser = argparse.ArgumentParser(
16
+        prog='ProgramName',
17
+        description='What the program does',
18
+        epilog='Text at the bottom of help')
19
+    parser.add_argument('-s', '--stg', required=True)
20
+    parser.add_argument('-l', '--loc', required=True)
21
+    parser.add_argument('-r', '--roo', required=True)
22
+    args = parser.parse_args()
23
+    #
24
+    c = tcp_socket.tcp_client_stp('127.0.0.1', config.SOCK_PROT_PORT)
25
+    sp = client_prot(c, channel_name='example_client')
26
+    #
27
+    data = {
28
+        "stg": args.stg,
29
+        "loc": args.loc,
30
+        "roo": args.roo,
31
+        "fun": "FUN_HEA"    # <-- Const, because script is for heat_vlv only
32
+    }
33
+    sp.send(socket_protocol.SID_READ_REQUEST, DID_FOLLOWS_HEATING_SETPOINT, data)
34
+    #
35
+    sp_data = sp.receive(socket_protocol.SID_READ_RESPONSE, DID_FOLLOWS_HEATING_SETPOINT).get_data()
36
+    nagios.Nagios().exit(**sp_data)

+ 1
- 0
socket_protocol

@@ -0,0 +1 @@
1
+Subproject commit 7f2b90c99030ac39f5bf7bfd92d1dd3d6c3657fa

+ 1
- 0
stringtools

@@ -0,0 +1 @@
1
+Subproject commit e1f76d96312e540544b2328d0937b0aa41126aa9

+ 1
- 0
task

@@ -0,0 +1 @@
1
+Subproject commit af35e83d1f07fd4cb9070bdb77cf1f3bdda3a463

+ 1
- 0
tcp_socket

@@ -0,0 +1 @@
1
+Subproject commit 72275a3270b0d34a696a2809cc066f84d72268a5

+ 0
- 0
z_server/__init__.py 查看文件


+ 13
- 0
z_server/config_example/config.py 查看文件

@@ -0,0 +1,13 @@
1
+import logging
2
+
3
+DEBUG = False   # False: logging to stdout with given LOGLEVEL  - True: logging all to localhost:19996 and warnings or higher to stdout
4
+LOGLEVEL = logging.INFO
5
+
6
+APP_NAME = "z_monitor"
7
+
8
+MQTT_SERVER = "<hostname>"
9
+MQTT_PORT = 1883
10
+MQTT_USER = "<username>"
11
+MQTT_PASSWORD = "<password>"
12
+
13
+SOCK_PROT_PORT = 8380

+ 1
- 0
z_server/devdi

@@ -0,0 +1 @@
1
+Subproject commit 7e4f92aaf1cd1dd2626e2b3337277eddfc37578e

+ 114
- 0
z_server/devices/__init__.py 查看文件

@@ -0,0 +1,114 @@
1
+import json
2
+import logging
3
+import mqtt
4
+import nagios
5
+import time
6
+
7
+try:
8
+    from config import APP_NAME as ROOT_LOGGER_NAME
9
+except ImportError:
10
+    ROOT_LOGGER_NAME = 'root'
11
+logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
12
+
13
+
14
+class base(object):
15
+    FOLLOW_REQUEST_WARNING = 5      # Seconds, till warning comes up, if device does not follow the command
16
+    FOLLOW_REQUEST_ERROR = 60       # Seconds, till error comes up, if device does not follow the command
17
+
18
+    def __init__(self, mqtt_client: mqtt.mqtt_client, topic):
19
+        self.topic = topic
20
+        #
21
+        mqtt_client.add_callback(topic, self.__rx__)
22
+        mqtt_client.add_callback(topic + '/#', self.__rx__)
23
+        #
24
+        self.__target_storage__ = {}
25
+        self.__state_storage__ = {}
26
+
27
+    def __rx__(self, client, userdata, message):
28
+        pass
29
+
30
+    def target(self, key, value):
31
+        tm_t, value_t = self.__target_storage__.get(key, (0, None))
32
+        if value != value_t:
33
+            self.__target_storage__[key] = time.time(), value
34
+        logger.debug("Target value for device identified: %s: %s", key, repr(value))
35
+
36
+    def state(self, key, value):
37
+        self.__state_storage__[key] = value
38
+        logger.debug("Device state identified: %s: %s", key, repr(value))
39
+
40
+    def status(self, key):
41
+        try:
42
+            tm_t, value_t = self.__target_storage__[key]
43
+            value_s = self.__state_storage__.get(key)
44
+        except KeyError:
45
+            return {"status": nagios.Nagios.UNKNOWN, "msg": "Device exists, but no setpoint change or unknown monitoring"}
46
+        else:
47
+            tm = time.time()
48
+            dt = tm - tm_t
49
+            if value_t != value_s and dt > self.FOLLOW_REQUEST_ERROR:
50
+                return {"status": nagios.Nagios.ERROR, "msg": "Requested setpoint unequal valve setpoint since %.1fs" % dt}
51
+            elif value_t != value_s and dt > self.FOLLOW_REQUEST_WARNING:
52
+                return {"status": nagios.Nagios.WARNING, "msg": "Requested setpoint unequal valve setpoint since %.1fs" % dt}
53
+            return {"status": nagios.Nagios.OK, "msg": "Requested setpoint equal valve setpoint"}
54
+
55
+
56
+class group(object):
57
+    def __init__(self, *args, **kwargs):
58
+        pass
59
+
60
+
61
+class shelly_sw1(base):
62
+    pass
63
+
64
+
65
+class tradfri_sw(base):
66
+    pass
67
+
68
+
69
+class tradfri_sw_br(base):
70
+    pass
71
+
72
+
73
+class tradfri_sw_br_ct(base):
74
+    pass
75
+
76
+
77
+class tradfri_button(base):
78
+    pass
79
+
80
+
81
+class livarno_sw_br_ct(base):
82
+    pass
83
+
84
+
85
+class brennenstuhl_heatingvalve(base):
86
+    def __init__(self, mqtt_client: mqtt.mqtt_client, topic):
87
+        base.__init__(self, mqtt_client, topic)
88
+
89
+    def __rx__(self, client, userdata, message):
90
+        payload = json.loads(message.payload)
91
+        if message.topic == self.topic + '/set':
92
+            self.target("current_heating_setpoint", payload["current_heating_setpoint"])
93
+        if message.topic == self.topic:
94
+            self.state("current_heating_setpoint", payload["current_heating_setpoint"])
95
+
96
+
97
+class silvercrest_powerplug(base):
98
+    pass
99
+
100
+
101
+class silvercrest_motion_sensor(base):
102
+    pass
103
+
104
+
105
+class my_powerplug(base):
106
+    pass
107
+
108
+
109
+class audio_status(base):
110
+    pass
111
+
112
+
113
+class remote(base):
114
+    pass

+ 1
- 0
z_server/mqtt

@@ -0,0 +1 @@
1
+Subproject commit 1adfb0626e7777c6d29be65d4ad4ce2d57541301

+ 1
- 0
z_server/nagios 查看文件

@@ -0,0 +1 @@
1
+../nagios

+ 1
- 0
z_server/report

@@ -0,0 +1 @@
1
+Subproject commit b53dd30eae1d679b7eec4999bec50aed55bc105b

+ 1
- 0
z_server/socket_protocol 查看文件

@@ -0,0 +1 @@
1
+../socket_protocol

+ 1
- 0
z_server/stringtools 查看文件

@@ -0,0 +1 @@
1
+../stringtools

+ 1
- 0
z_server/task 查看文件

@@ -0,0 +1 @@
1
+../task

+ 1
- 0
z_server/tcp_socket 查看文件

@@ -0,0 +1 @@
1
+../tcp_socket

+ 31
- 0
z_server/z_protocol.py 查看文件

@@ -0,0 +1,31 @@
1
+import nagios
2
+import socket_protocol
3
+# from devdi.topic import topic_by_props
4
+
5
+DID_FOLLOWS_HEATING_SETPOINT = 'current_heating_setpoint'
6
+
7
+
8
+class server(socket_protocol.pure_json_protocol):
9
+    def __init__(self, *args, **kwargs):
10
+        if 'devices' in kwargs:
11
+            self.__devices__ = kwargs.pop('devices')
12
+        socket_protocol.pure_json_protocol.__init__(self, *args, **kwargs)
13
+        #
14
+        # self.add_data((socket_protocol.SID_READ_REQUEST, socket_protocol.SID_READ_RESPONSE),
15
+        #              DID_FOLLOWS_HEATING_SETPOINT, 'current_heating_setpoint')
16
+        #
17
+        if not self.__comm_inst__.IS_CLIENT:
18
+            self.register_callback(socket_protocol.SID_READ_REQUEST, DID_FOLLOWS_HEATING_SETPOINT, self.follow_heating_setpoint)
19
+
20
+    def follow_heating_setpoint(self, msg):
21
+        if msg.get_status() == socket_protocol.STATUS_OKAY:
22
+            try:
23
+                dev = self.__devices__.get_str(**msg.get_data())
24
+            except:
25
+                return socket_protocol.STATUS_CALLBACK_ERROR, {"status": nagios.Nagios.UNKNOWN, "msg": "Exception while getting device."}
26
+            if dev is None:
27
+                return socket_protocol.STATUS_SERVICE_OR_DATA_UNKNOWN, {"status": nagios.Nagios.UNKNOWN, "msg": "Device does not exist."}
28
+            else:
29
+                return socket_protocol.STATUS_OKAY, dev.status(msg.get_data_id())
30
+        else:
31
+            return socket_protocol.STATUS_OPERATION_NOT_PERMITTED, {"status": nagios.Nagios.UNKNOWN, "msg": "Socket protocol error."}

+ 40
- 0
z_server/z_server.py 查看文件

@@ -0,0 +1,40 @@
1
+import config
2
+import devdi.devices as devices
3
+import logging
4
+import mqtt
5
+import report
6
+import z_protocol
7
+import socket_protocol
8
+import tcp_socket
9
+import time
10
+
11
+logger = logging.getLogger(config.APP_NAME)
12
+
13
+
14
+if __name__ == "__main__":
15
+    #
16
+    # Logging
17
+    #
18
+    if config.DEBUG:
19
+        report.appLoggingConfigure(None, 'stdout', ((config.APP_NAME, logging.DEBUG), ),
20
+                                   target_level=logging.WARNING, fmt=report.SHORT_FMT, host='localhost', port=19996)
21
+    else:
22
+        report.stdoutLoggingConfigure(((config.APP_NAME, config.LOGLEVEL), ), report.SHORT_FMT)
23
+
24
+    #
25
+    # MQTT Client
26
+    #
27
+    mc = mqtt.mqtt_client(host=config.MQTT_SERVER, port=config.MQTT_PORT, username=config.MQTT_USER,
28
+                          password=config.MQTT_PASSWORD, name=config.APP_NAME)
29
+    #
30
+    # Smarthome physical Devices
31
+    #
32
+    pd = devices.physical_devices(mc)
33
+
34
+    #
35
+    # Socket Protocol
36
+    #
37
+    s = tcp_socket.tcp_server_stp('127.0.0.1', config.SOCK_PROT_PORT)
38
+    sp = z_protocol.server(s, channel_name='example_server', devices=pd)
39
+    while (True):
40
+        time.sleep(5)

+ 4
- 0
z_server/z_server.sh 查看文件

@@ -0,0 +1,4 @@
1
+#!/bin/sh
2
+#
3
+BASEPATH=`dirname $0`
4
+$BASEPATH/venv/bin/python $BASEPATH/z_server.py

Loading…
取消
儲存