-
Notifications
You must be signed in to change notification settings - Fork 2
/
wairc.py
executable file
·123 lines (108 loc) · 3.46 KB
/
wairc.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
#!/usr/bin/python -u
#
# wairc.py
#
# Program to read the water counter using a reflective light sensor
# This is the data recording part running on a Raspberry Pi.
# It retrieves data from the Arduino over serial and stores
# counter and consumption values into a round robin database.
# Copyright 2015-16 Martin Kompf
#
# 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 program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import time
import sys
import os
import re
import argparse
import serial
import rrdtool
# Serial port of arduino
#port = '/dev/ttyAMA0'
port = '/dev/serial0'
# counter unit: 1 revolution = x m^3
trigger_step = 0.001
# Path to RRD with counter values
count_rrd = "%s/water.rrd" % (os.path.dirname(os.path.abspath(__file__)))
# Create the Round Robin Database
def create_rrd():
print 'Creating RRD: ' + count_rrd
# Create RRD to store counter and consumption:
# Counter is GAUGE (m^3)
# Consumption is ABSOLUTE (m^3/s)
# 1 value per minute for 3 days
# 1 value per day for 30 days
# 1 value per week for 10 years
# Consolidation LAST for counter
# Consolidation AVERAGE for consumption
try:
rrdtool.create(count_rrd,
'--no-overwrite',
'--step', '60',
'DS:counter:GAUGE:86400:0:1000000',
'DS:consum:ABSOLUTE:86400:0:1000000',
'RRA:LAST:0.5:1:4320',
'RRA:AVERAGE:0.5:1:4320',
'RRA:LAST:0.5:1440:30',
'RRA:AVERAGE:0.5:1440:30',
'RRA:LAST:0.5:10080:520',
'RRA:AVERAGE:0.5:10080:520')
except Exception as e:
print 'Error ' + str(e)
# Get the last counter value from the rrd database
def last_rrd_count():
val = 0.0
handle = os.popen("rrdtool lastupdate " + count_rrd)
for line in handle:
m = re.match(r"^[0-9]*: ([0-9.]*) [0-9.]*", line)
if m:
val = float(m.group(1))
break
handle.close()
return val
# Main
def main():
# Check command args
parser = argparse.ArgumentParser(description='Program to read the water meter using a reflective light sensor.')
parser.add_argument('-c', '--create', action='store_true', default=False, help='Create rrd database if necessary')
args = parser.parse_args()
if args.create:
create_rrd()
# Open serial line
ser = serial.Serial(port, 9600)
if not ser.isOpen():
print "Unable to open serial port %s" % port
sys.exit(1)
# set trigger mode
ser.write(b'C\r\n')
ser.write(b'T\r\n')
trigger_state = 0
counter = last_rrd_count()
print "restoring counter to %f" % counter
while(1==1):
# Read line from arduino and convert to trigger value
line = ser.readline()
line = line.strip()
old_state = trigger_state
if line == '1':
trigger_state = 1
elif line == '0':
trigger_state = 0
if old_state == 1 and trigger_state == 0:
# trigger active -> update count rrd
counter += trigger_step
update = "N:%.3f:%.3f" % (counter, trigger_step)
#print update
rrdtool.update(count_rrd, update)
if __name__ == '__main__':
main()