forked from thomaseichhorn/bacdevice
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdustmeter.py
129 lines (116 loc) · 5.31 KB
/
dustmeter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/usr/bin/env python3
import logging
logger = logging.getLogger('mybaclog')
import submeter
import socket
import threading
import select
import time
from datetime import datetime
from PyQt5.QtCore import QByteArray, QDataStream, QIODevice
class DustmeterMeter(submeter.SubMeter):
def __init__(self, name, pumpstation):
submeter.SubMeter.__init__(self, name, pumpstation)
class DustmeterError(Exception):
def __init__(self, name, host, port, msg):
self.name = name
self.host = host
self.port = port
self.msg = msg
def __str__(self):
return "Error from {}#{}:{}: {}".format(self.name, self.host, self.port, self.msg)
class Dustmeter(threading.Thread):
defaultProps = {
"name": "myDustmeter",
"host": "localhost",
"port": 8888,
"default_dust": 0,
"reconnect": True
}
def __init__(self, **kwargs):
threading.Thread.__init__(self)
for attr, value in Dustmeter.defaultProps.items():
if attr not in kwargs:
kwargs[attr] = value
self.name = kwargs["name"]
self.host = kwargs["host"]
self.port = kwargs["port"]
self.reconnect = kwargs["reconnect"]
self.dustvalues = [DustmeterMeter("dust_small", self), DustmeterMeter("dust_large", self)]
self.is_connected = False
self.ev = threading.Event()
logger.info("Initiating {} at {}:{}".format(self.name, self.host, self.port))
def run(self):
while True:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if s.connect_ex((self.host, self.port)) == 0:
self.is_connected = True
logger.info("Connected {} at {}:{}".format(self.name, self.host, self.port))
else:
self.is_connected = False
logger.warning("No reply from {} at {}:{} at {}".format(self.name, self.host, self.port, datetime.now()))
if self.reconnect:
logger.warning("Reconnected to {} at {}:{} at {}".format(self.name, self.host, self.port, datetime.now()))
time.sleep(30)
continue
else:
logger.error("Failed to reconnect to {} at {}:{} at {}".format(self.name, self.host, self.port, datetime.now()))
for i, dusts in enumerate(self.dustvalues):
dusts.is_connected = False
#dusts.present_value = DustMeter.defaultProps['default_dust']
dusts.present_value = -2
s.close()
break
inout = [s]
idel_loop_count = 0
while True:
infds, outfds, errfds = select.select(inout, [], [], 0.01)
if len(infds) != 0:
time.sleep(0.1)
buf = s.recv(64)
if len(buf) != 0:
idel_loop_count = 0;
try:
[small_str, large_str] = buf.split(b',')
except ValueError:
small_str = "-1"
large_str = "-1"
smalldst = int(small_str)
largedst = int(large_str)
# According to manual: ( average count over the last minute per cubic foot) / 100
# We return the absolute count per cubic metre, so * 100 and * 35.314666721
smallmetric = int ( smalldst * 3531.4666721 )
largemetric = int ( largedst * 3531.4666721 )
logger.debug("Data from {} at {}:{} at {} is: {}, {}".format(self.name, self.host, self.port, datetime.now(), smallmetric, largemetric))
for i, dusts in enumerate(self.dustvalues):
dusts.is_connected = True
if (i==0):
dusts.present_value = smallmetric
if (i==1):
dusts.present_value = largemetric
if self.ev.wait(30):
self.ev.clear()
logger.info("Closed connection to {} at {}:{} at {}".format(self.name, self.host, self.port, datetime.now()))
for i, dusts in enumerate(self.dustvalues):
dusts.is_connected = False
#dusts.present_value = DustMeter.defaultProps['default_dust']
dusts.present_value = -2
s.close()
return
else:
idel_loop_count += 1
if(idel_loop_count > 4):
logger.info("No data, closing connection to {} at {}:{} at {}".format(self.name, self.host, self.port, datetime.now()))
for i, dusts in enumerate(self.dustvalues):
dusts.is_connected = False
#dusts.present_value = DustMeter.defaultProps['default_dust']
dusts.present_value = -2
s.close()
break
def stop(self):
self._stop_event.set()
def getMeters(config):
dust = Dustmeter(**config)
return dust.dustvalues
if __name__ == "__main__":
pass