commit a67be3af05a3e3f67eabd9c77e257e51076c54a1 Author: Martin Kompf Date: Mon Mar 28 16:37:53 2016 +0200 Initial checkin - program uses polling on gpio diff --git a/graph.sh b/graph.sh new file mode 100755 index 0000000..8700bd1 --- /dev/null +++ b/graph.sh @@ -0,0 +1,13 @@ +#!/bin/sh +rrdtool graph counter.gif \ + -s 'now -20 hour' -e 'now' \ + -X 0 -A \ + DEF:counter=water.rrd:counter:LAST \ + LINE2:counter#000000:"Zählerstand [m³]" +display counter.gif& +rrdtool graph consum.gif \ + -s 'now -20 hour' -e 'now' \ + DEF:consum=water.rrd:consum:AVERAGE \ + CDEF:consumltr=consum,60000,* \ + LINE2:consumltr#00FF00:"Verbrauch [l/min]" +display consum.gif& diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..1d00a5a --- /dev/null +++ b/setup.sh @@ -0,0 +1 @@ +gpio export 9 in diff --git a/wairc.py b/wairc.py new file mode 100755 index 0000000..03a9934 --- /dev/null +++ b/wairc.py @@ -0,0 +1,116 @@ +#!/usr/bin/python -u +# +# emeir.py +# +# Program to read the electrical meter using a reflective light sensor +# This is the data recording part running on a Raspberry Pi. +# It retrieves data from the Arduino over USB serial and stores +# counter and consumption values into a round robin database. + +# Copyright 2015 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 . + +import serial +import time +import sys +import os +import re +import argparse +import rrdtool + +# GPIO value files (wiringPi) +gpin = '/sys/class/gpio/gpio9/value' + +# 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() + + trigger_state = 0 + counter = last_rrd_count() + print "restoring counter to %f" % counter + + while(1==1): + # read gpio input value file + f = open(gpin, 'r') + line = f.read().strip() + f.close() + + 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) + time.sleep(0.1) + + +if __name__ == '__main__': + main()