/
heatpumpMonitor.py
executable file
·164 lines (136 loc) · 5.59 KB
/
heatpumpMonitor.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#***************************************************************************
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU General Public License as published by *
#* the Free Software Foundation; either version 3 of the License, or *
#* (at your option) any later version. *
#* *
#***************************************************************************
"""
This is the main module for the heatpump Monitor. It forks into the background
and should to a polling every 60 secs. It is quit simple at this point, no
config files or almost no error handling.
Written by Robert Penz <robert@penz.name>
"""
#TODO: Create a common log system which is able to write a timestamp before the entry
#TODO: define which line is painted over which in the graphs
import time
import sys
import traceback
import os
import signal
import protocol
import storage
import json
import render
import deamon
import threadedExec
import config_manager
import report
import thresholdMonitor
import requests
import stromzaehler
import errorlog
#from kafka import KafkaClient, SimpleProducer, SimpleConsumer, RoundRobinPartitioner
config = None
# Print usage message and exit
def usage(*args):
sys.stdout = sys.stderr
print __doc__
print 50*"-"
for msg in args: print msg
sys.exit(2)
def logError(e):
errorlog.logError(e)
def updateCCU(v):
ccuUrl = "http://pi:8080/api/set"
try:
requests.get(ccuUrl + "/AussenTemp/?value=" + str(v.get('outside_temp')))
requests.get(ccuUrl + "/KollectorTemp/?value=" + str(v.get('collector_temp')))
except Exception,e:
logError(e)
def saveVerbrauchsData(v_wp,v_sz,zs_wp,zs_sz,interval):
y = time.strftime('%Y', time.localtime())
m = time.strftime('%m', time.localtime())
d = time.strftime('%d', time.localtime())
f = open("/var/lib/heatpumpMonitor/verbrauch.%s-%s-%s" %(y,m,d) , 'a')
f.write("%s %04d %04d %d %d %d\n" % (time.strftime('%Y %m %d %a %H %H:%M:%S', time.localtime()), v_wp, v_sz, zs_wp, zs_sz, interval))
f.close
#try:
# kafka = KafkaClient("192.168.178.95:9092")
# producer = SimpleProducer(kafka, async=False, req_acks=SimpleProducer.ACK_AFTER_LOCAL_WRITE, ack_timeout=2000)
# producer.send_messages("verbrauch2", "%s wp %d" % (time.strftime('%Y %m %d %a %H %H:%M:%S', time.localtime()), v_wp))
# producer.send_messages("verbrauch2", "%s sz %d" % (time.strftime('%Y %m %d %a %H %H:%M:%S', time.localtime()), v_sz))
# kafka.close()
#except Exception, e:
# logError(e)
def doMonitor():
try:
print "Starting ..."
sys.stdout.flush()
p = protocol.Protocol(config.getSerialDevice(), config.getProtocolVersionsDirectory(), config.getNewStyleSerialCommunication())
s = storage.Storage(config.getDatabaseFile())
j = json.Json(os.path.join(config.getRenderOutputPath(), "actual_values.json"))
aReport = report.Report(config)
t = thresholdMonitor.ThresholdMonitor(config, aReport)
print "Up and running"
sys.stdout.flush()
counter = 0
sz_wp = stromzaehler.StromZaehler("/dev/lesekopfWP")
sz_sz = stromzaehler.StromZaehler("/dev/lesekopfSZ")
old_wp = sz_wp.getValueAsInt()
old_sz = sz_sz.getValueAsInt()
print "%d %d" % (old_wp, old_sz)
sys.stdout.flush()
time.sleep(60)
while 1:
startTime = time.time()
try:
zs_wp = sz_wp.getValueAsInt()
zs_sz = sz_sz.getValueAsInt()
v_wp = zs_wp - old_wp
v_sz = zs_sz - old_sz
old_wp = zs_wp
old_sz = zs_sz
print "%d %d %d %d " % (zs_wp, zs_sz, v_wp, v_sz)
sys.stdout.flush()
saveVerbrauchsData(v_wp, v_sz, zs_wp, zs_sz, 60)
values = p.query()
values["zaehlerstand_wp"] = v_wp
values["zaehlerstand_sz"] = v_sz
except Exception, e:
# log the error and just try it again in 120 sec - sometimes the heatpump returns an error and works
# seconds later again
# If the query takes longer than 2 minutes, we get a negative value ... maybe a problem in rare contitions
logError(e)
t.gotQueryError()
time.sleep(120 - (time.time() - startTime))
continue
# store the stuff
s.add(values)
updateCCU(values)
# write the json file everything, as it does not use much cpu
j.write(values)
sys.stdout.flush()
counter += 1
# at last check the values if something needs to reported
# t.check(values)
# lets make sure it is aways 60 secs interval, no matter how long the last run took
sleepTime = 61 - (time.time() - startTime)
if sleepTime < 0:
print "System is too slow for 60 sec interval by %d seconds" % abs(int(sleepTime))
else:
time.sleep(sleepTime)
except Exception, e:
# make sure the error got logged
logError(e)
# Main program: parse command line and start processing
def main():
global config
config = config_manager.ConfigManager()
deamon.startstop(config.getLogFile(), pidfile=config.getPidFile())
doMonitor()
if __name__ == '__main__':
main()