-
Notifications
You must be signed in to change notification settings - Fork 2
/
readCurrentCost
executable file
·151 lines (138 loc) · 5.61 KB
/
readCurrentCost
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
#!/usr/bin/env python
from __future__ import with_statement
import serial
import time
from xml.dom import minidom
import argparse
import sys
import daemon,lockfile.pidlockfile
import ConfigParser
# default configuration
cfg = {
"filename" : None,
"serial_device" : "/dev/ttyUSB0",
"interval" : 300,
"daemon" : False,
"pid_file" : None,
}
cfg_types = {
"interval" : int,
"daemon" : bool,
}
def readCurrentCost(port,interval,outname,baudrate=57600):
if outname is None:
outfile = sys.stdout
else:
outfile = open(outname,'a',buffering=1)
#open serial port
ser = serial.Serial(port=port, baudrate=baudrate,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,timeout=5)
# get current time
startTime = time.time()
# and initialise data
temp = {}
power = {}
count = {}
while True:
line = ser.readline()
thisTime = time.time()
if len(line)>0:
xmldoc = minidom.parseString(line)
watts_nodes = {}
# parse the xml
try:
temperature_nodes = xmldoc.getElementsByTagName('tmpr')
watts_nodes = xmldoc.getElementsByTagName('ch1')[0].getElementsByTagName('watts')
sensor_nodes = xmldoc.getElementsByTagName('sensor')
except:
continue
sensor = int(sensor_nodes[0].childNodes[0].nodeValue)
# check if sensor is already recorded
if sensor not in count.keys():
count[sensor] = 0
temp[sensor] = 0.
power[sensor] = 0.
# accumulate data
temp[sensor] += float(temperature_nodes[0].childNodes[0].nodeValue)
power[sensor] += float(watts_nodes[0].childNodes[0].nodeValue)
count[sensor] += 1
# check if we should write out data
if thisTime-startTime >= interval:
done = 0
have_temp = False
outfile.write("%s "%(time.strftime("%Y-%m-%d %H:%M:%S",
time.gmtime(startTime+(thisTime-startTime)/2.))))
# loop over sensors
for i in range(0,10):
if i in count.keys():
if count[i]>0:
if not have_temp:
outfile.write("%f "%(temp[i]/count[i]))
have_temp = True
outfile.write("%f "%(power[i]/count[i]))
# reset counters
count[i] = 0
temp[i] = 0.
power[i] = 0.
done+=1
else:
outfile.write('NaN ')
# check we have handled all the data
if len(count.keys()) == done:
break
outfile.write('\n')
startTime = thisTime
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Parse data coming from a CurrentCost device.')
parser.add_argument("-c", "--config", metavar="CFG",help="read configuration from CFG")
parser.add_argument("-f", "--file", dest="filename",help="write output to FILE (default: stdout)", metavar="FILE")
parser.add_argument("-s", "--serial-device",metavar="DEV",help="serial device to read from")
parser.add_argument("-i", "--interval",metavar="INT",type=int,help="interval in seconds over which data should be averaged (default:300)")
daemonGrp = parser.add_mutually_exclusive_group()
daemonGrp.add_argument("-d", "--daemon",default=None,action="store_true",help="run in daemon mode")
daemonGrp.add_argument("-n", "--no-daemon",dest="daemon",default=None,action="store_false",help="do not run in daemon mode")
parser.add_argument("-p", "--pid-file",metavar="FILE",help="store PID in FILE")
args = parser.parse_args()
if args.config is not None:
# read configuration file
cfgFile = ConfigParser.ConfigParser()
cfgFile.read(args.config)
sct = "CurrentCost"
if cfgFile.has_section(sct):
for k in cfg:
if cfgFile.has_option(sct,k):
v = cfgFile.get(sct,k)
if k in cfg_types:
cfg[k] = cfg_types[k](v)
else:
cfg[k] = v
else:
print "could not find section %s in config file %s"%(sct,args.config)
# get settings from command line
for k in cfg:
if hasattr(args,k):
v = getattr(args,k)
if v is not None:
if k in cfg_types:
cfg[k] = cfg_types[k](v)
else:
cfg[k] = v
if cfg["daemon"]:
if cfg["pid_file"] is None:
parser.error('no pid file specified')
if cfg["filename"] is None:
parser.error('must specify output file')
ourlockfile = lockfile.pidlockfile.PIDLockFile(cfg["pid_file"],timeout=1)
if ourlockfile.is_locked():
parser.error("pid file %s is already locked"%cfg["pid_file"])
context = daemon.DaemonContext(
working_directory='/tmp',
umask=18 ,
pidfile=ourlockfile
)
with context:
readCurrentCost(cfg["serial_device"],cfg["interval"],cfg["filename"])
else:
readCurrentCost(cfg["serial_device"],cfg["interval"],cfg["filename"])