Aquacontroller Jr data collection

bohlke

PBITAWA
Warning if you are not a geek (like me) you may find this post a bit boring, proceed at your own risk.

I had to edit some of the syntax to remove the smileys (too many images error message) you may see extra spaces in front of the pH statements in the script.

I have an Aquacontroller Jr and as happy as I am with Aquanotes I wanted a better way to collect statistics in a database. For those of you not familiar with MRTG and RRD tool RRD is the Acronym for Round Robin Database. RRD is a system to store and display time-series data (network bandwidth, machine-room temperature, mysql queries,dns queries). You use it directly via a command line or in a scheduler. It is available for a variety of operating systems however I chose linux.

The first problem I had to solve was how to get the data from the Ac Jr into a variable that I could send to rrdtool. The serial interface to the Ac Jr is pretty easy to use however I had to use a non-grounded power cord to avoid the ground loop problems with the Ac Jr serial interface. I decided that I would poll current status every five minutes instead of using the data logging options. This way I would not have to worry about overlapping data sets. To do this I used minicom which is available for many linux distributions. Minicom supports scripting and can log the output to a file, I figured I was all set. I configured minicom (using minicom -s) to use /dev/ttyS0 and I removed all of the modem init strings. Here is what the sample output from the c command on my Ac Jr looked like:

c
Current Status is:

Dec 28 2008 12:00:48
Temp pH
78.6 8.06
LT1 is OFF Auto
LT2 is ON Auto
LT3 is OFF Auto
LT4 is OFF Auto
LT5 is OFF Auto
HT1 is ON Auto
HT2 is OFF Auto
CO1 is OFF Auto
CO2 is OFF Auto
PO1 is OFF Auto
ALT is OFF Auto
ALP is OFF Auto

The only thing that wasnt completely clear was how to exit minicom after the script was complete. I found a solution tough its not perfect, but it was the first solution so I used it Here is my minicom script

send "c^M"
expect {
"AquaController>"
}
sleep 5
! killall -9 minicom

I called it aquadata and the output is saved to aqua.log, here are the command line options I used:

minicom -o -C aqua.log -S /home/bohlke/rrdfiles/aquadata

now all I had to do was construct a script that I could run to parse the output, using my old school tools (head, tail, and awk) I parsed the data. I am sure there is a better way to do it but this again was the first one that worked


#!/bin/bash

PATH=/usr/bin:/bin:/usr/local/rrdtool-1.3.5/bin

rm -f aqua.log
minicom -o -C aqua.log -S /home/bohlke/rrdfiles/aquadata > /dev/null
TEMP=`head -6 aqua.log | tail -1 | awk '{print $1}'`
PH=`head -6 aqua.log | tail -1 | awk '{print $2}'`

I have to remove the file every time as minicom appends the data to the output log file. So now I have the ability to capture the tank pH and temp at the interval of my choosing, now its time to setup my rrdtool database. To do that we first must create the rrdtool database.

So I built a little script to create the database, I have two dbs right now one for temp and the other for pH

#!/bin/bash
PATH=/usr/bin:/bin:/usr/local/rrdtool-1.3.5/bin

rrdtool create /home/bohlke/rrdfiles/db/tanktemp.rrd DS:temp:GAUGE:600:50:100 RRA:AVERAGE:0.5:1:1200 RRA:MIN:0.5:12:2400 RRA:MAX:0.5:12:2400 RRA:AVERAGE:0.5:12:2400
rrdtool create /home/bohlke/rrdfiles/db/tankph.rrd DS: ph:GAUGE:600:5:9 RRA:AVERAGE:0.5:1:1200 RRA:MIN:0.5:12:2400 RRA:MAX:0.5:12:2400 RRA:AVERAGE:0.5:12:2400

I chose some default values for the dataset sizes, I can keep realtime stats for 2 days and rolled up average, min and max for 100 days:


AVERAGE : 300 seconds * 1 * 1200 = 180000 seconds = 50 hours = 2 days
MIN : 300 seconds * 12 * 2400 = 8640000 seconds = 2400 hours = 100 days
MAX : 300 seconds * 12 * 2400 = 8640000 seconds = 2400 hours = 100 days
AVERAGE : 300 seconds * 12 * 2400 = 8640000 seconds = 2400 hours = 100 days

once I had the database created I added the statements to my script to send the data to the database:

#!/bin/bash

PATH=/usr/bin:/bin:/usr/local/rrdtool-1.3.5/bin

rm -f aqua.log
minicom -o -C aqua.log -S /home/bohlke/rrdfiles/aquadata > /dev/null
TEMP=`head -6 aqua.log | tail -1 | awk '{print $1}'`
PH=`head -6 aqua.log | tail -1 | awk '{print $2}'`
rrdtool update /home/bohlke/rrdfiles/db/tanktemp.rrd N:${TEMP}
rrdtool update /home/bohlke/rrdfiles/db/tankph.rrd N:${PH}

Now all I have to do is run this script every 5 minutes to collect the data. To display the data you use the rrdtool graph function, this builds the png file on demand. You can see some examples of really cool rddtool graphs here. Here is my simple rrdtool graph, I will hopefully have something a bit cooler soon.

#!/bin/bash
PATH=/usr/bin:/bin:/usr/local/rrdtool-1.3.5/bin

rrdtool graph temp.png -s now-24h --title="Temperature" -w 600 -h 200 --alt-autoscale-max --lower-limit -20 --vertical-label "Degrees" DEF:temp=/home/bohlke/rrdfiles/db/tanktemp.rrd:temp:AVERAGE DEF:outsidetemp=/home/bohlke/rrdfiles/db/68502/real.rrd:real:AVERAGE DEF:outsidefelt=/home/bohlke/rrdfiles/db/68502/felt.rrd:felt:AVERAGE DEF: ph=/home/bohlke/rrdfiles/db/tankph.rrd: ph:AVERAGE CDEF:negph=ph,-1,* VRULE:1120687200#EE00EE: COMMENT:" Maximum Minimum Average Last\l" GPRINT:temp:MAX:"Temp %6.2lf %s\:" GPRINT:temp:MIN:"%6.2lf %s\:" GPRINT:temp:AVERAGE:"%6.2lf %s\:" GPRINT:temp:LAST:"%6.2lf %s\:\l" AREA:temp#00EE00:"Tank Temp \l" LINE:outsidetemp#EE0000:"Outside Temp\l"

#!/bin/bash
PATH=/usr/bin:/bin:/usr/local/rrdtool-1.3.5/bin

rrdtool graph ph.png -s now-24h --title="Tank pH" -w 600 -h 200 --alt-autoscale-max --lower-limit 7 --vertical-label "pH" DEF:temp=/home/bohlke/rrdfiles/db/tanktemp.rrd:temp:AVERAGE DEF:outsidetemp=/home/bohlke/rrdfiles/db/68502/real.rrd:real:AVERAGE DEF:outsidefelt=/home/bohlke/rrdfiles/db/68502/felt.rrd:felt:AVERAGE DEF: ph=/home/bohlke/rrdfiles/db/tankph.rrd: ph:AVERAGE CDEF:negph=ph,-1,* VRULE:1120687200#EE00EE: COMMENT:" Maximum Minimum Average Last\l" GPRINT: ph:MAX:"pH %6.2lf %s\:" GPRINT: ph:MIN:"%6.2lf %s\:" GPRINT: ph:AVERAGE:"%6.2lf %s\:" GPRINT: ph:LAST:"%6.2lf %s\:\l" AREA: ph#00EE00:"Tank pH \l"

So now I have two graphs one for pH and the other for Temp. Since these are created on demand I will need to create a cgi app to build them on the webserver, still not done with that yet. Here are the graphs

ph.png


Temp.png


Hope this helps anyone else who wants to track and store tank data.
 
While minicom is a fairly useful tool, it is overkill for this application (and I have found it somewhat unreliable). As a result I threw together a quick python script to do the same thing. the advantage is that the python script flushes the buffer after connect and before disconnect, and closes cleanly.

#!/usr/bin/python

import serial
import time

ac2 = serial.Serial('/dev/ttyS0', 9600, timeout=5)
ac2.flushInput()
ac2.write('c\n')
time.sleep(5)
numchar = ac2.inWaiting()
output=ac2.read(numchar)
ac2.flushOutput()
ac2.close()
print output

Of course you can replace ttyS0 with your serial port. The timeout is a bit long, but we are not performance critical here and it ensures that the Aqua controller has time to respond in case it is busy. Now instead of calling your minicom line, you can simply name this script checkac.py and call it with checkac.py > aqua.log to get your data. All of your other scripting should work with it fine, no line numbers were changed in the output.

This script requires pyserial (python-serial package under several distributions). Of course this could be expanded to actually collect the proper variables and throw them all into rrdtool using the python bindings, but this was a quick hack. I will post a follow up if I expand the script further.
 
Do you know if the python script is interactive? The biggest drawback (for me) to minicom is that I cant run it in cron as it is cursor interactive.
 
<a href=showthread.php?s=&postid=14200634#post14200634 target=_blank>Originally posted</a> by bohlke
Do you know if the python script is interactive? The biggest drawback (for me) to minicom is that I cant run it in cron as it is cursor interactive.

The script is not at all interactive. It simply dumps the contents that you were getting in aqua.log to stdout. If you redirect the output to aqua.log it puts it in the file. The script takes less than 6 seconds to run (5 of that is sleep to make sure the Aquacontroller has time to respond). When the run is finished, the serial port connection is closed and the output buffer is flushed.

Nice graphing BTW
 
How/where do you run the script? It would be nice if it was run automatically every day at a certain time.
 
<a href=showthread.php?s=&postid=14201894#post14201894 target=_blank>Originally posted</a> by melev
How/where do you run the script? It would be nice if it was run automatically every day at a certain time.

Before I had to run it in an interactive loop but now with this new script I can run it as a cron job that executes every 5 min. Works like a dream.
 
I do the same, though I have 2 scripts... One that runs every 5 minutes and updates the database and graphs plus web pages on the local server, and one that runs every 15 minutes and updates both the local and the remote server. No need to update the outside world more often than that, but I use it frequently when I travel.
 
How does it run exactly? Is this on a linux box, or Windows-based? Is it a program you start up and it runs in the background?

Sorry, I'm just not understanding exactly.

OT: And if one of you would like to talk me through setting up a local server on my computer, that would make my life a lot easier as I build the magazine each month. What I do currently is work on a page, then upload it to the site to view it. I tried to install some software that will allow me to test those pages locally with CSS and JS, but I've gotten stuck, disgusted, and disgruntled. Any advice appreciated.
 
Its a program on a linux machine, its the scheduler. There is a similar option on windows machines that is the task scheduler (in the accessories->system tools menu).

As far as setting up your own server I would recommend running vmware server (download it free here http://www.vmware.com/download/server/ ) and loading a test linux box on your local machine. At that point it acts like a remote machine and all you need is a little free disk space to make it run. That way you can download a linux distro install it and test your web pages. In some cases you can download virutal appliances ( http://www.vmware.com/appliances/directory/cat/53 ) from vmware that are pre configured machines which might help you out.
 
Back
Top