Wednesday, June 15, 2016

Quick and dirty temperature monitoring.

One of the projects I've been tasked with is finding a new CPU assembly to replace my employer's aging PC104 stack. While the PC104 stuff is still available, it's nearing EOL and last time buys, so we need to get it out of circulation now.

One of the requirements, as this device is going to be on factory floors, is that the CPU runs comfortably at 120F in a 10x12" painted steel box. Comfortably, meaning the device can sit there and not halt or otherwise die while running at a load of 40-60% CPU time. Getting the temperature up to that point is no problem - our homemade solution is a modified chest freezer with some heating coils and a simple FUJI-style temperature controller.

Measuring the temperature and getting it into a useful form, however, is a different story. The usual solution here is to use Labview and a bunch of complicated Advantech hardware to read sensors, store it someplace and graph the results. Since I only have a few weeks to evaluate this, tasking the programmers with yet another project was out of the question.

So, how to do?

I had an AVTech RoomAlert 4E device left from a previous project, with a couple of DS1820-compatible temperature sensors. While the 4E is meant for permanent installation to monitor computer rooms for overtemperature (and other environmental failures,) it works just as well as an SNMP-capable temperature box.


A single point calibration was performed on the sensors. They are in a plastic bag, suspended in an icewater bath. A NIST-traceable thermometer provides the standard.

The logical choice for a simple project (in my mind) was a Raspberry Pi. I had an older Model B laying around doing nothing, so a simple reflash with Raspbian Lite started me off. I needed some tools, so:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install snmp rrdtools apache2

snmp - gives snmptools, which gets me the snmpwalk command to read the box
rrdtools - so I can create and maintain Round-Robin Archives and graph the data
apache2 - so I can display the information on a local webserver for viewing

First thing to do was create the graphs.

rrdtool create freeair.rrd \
        --step 20 \
        DS:fa:GAUGE:120:U:U \
        RRA:AVERAGE:0.5:1:525600

rrdtool create cputemp.rrd \
        --step 20 \
        DS:cp:GAUGE:120:U:U \
        RRA:AVERAGE:0.5:1:525600

Basically, just a 20 second step with a 120 second timeout. The points specified are far in excess of the 3 days or so the test is going to run.

The next part was more difficult. I had to figure out how to read the SNMP values from the AVTech box. That's normally pretty easy, but the MIBfile that AVTech provides had errors and didn't provide the entire OID necessary to get the values. I also found out that the local network here was kind of flaky - where I can read values all day, the network here timed out my reads for some reason, so I had to put in a small routine to hold values and check against new ones.

#!/bin/bash

# Read the SNMP values and put them in a RRD.

function showme {

fa=`N=4; snmpwalk -v 1 -c public 10.0.0.93 1.3.6.1.4.1.20916.1.6.1.2.1.2.0 | awk -v N=$N '{print $N}'`
cu=`N=4; snmpwalk -v 1 -c public 10.0.0.93 1.3.6.1.4.1.20916.1.6.1.2.2.2.0 | awk -v N=$N '{print $N}'`

if [ "$fa" = "" ]
        then
                fa="$fold"
                cu="$cold"
                echo "Old values retained"
fi

echo $fa
echo $cu
echo " "

}

while :
do
        showme
        rrdtool update /mnt/flash/freeair.rrd N:$fa
        rrdtool update /mnt/flash/cputemp.rrd N:$cu
        sleep 20
        fold=$fa
        cold=$cu

done

I was able to find the OID values necessary by looking at other AVTech units I'm using, deducing the values, and comparing them to other IDs I found online. It ended up working, and I'm planning on notifying the vendor that the values they provide are incomplete.

The script reads the values with SNMP and returns only the 4th data item in the string, which is the actual data I need. It's compared to an empty string, and if empty, the last good values recorded are used. A simple infinite while loop calls the read routing, puts the values in the RRAs, and waits.
Graphing the data was a simple matter of using RRDTOOL's built in graph function:

rrdtool graph  "/var/www/html/fa.png" \
-w 1000 -h 343  -a PNG \
--start -1h --end now \
--title "Chamber Air: Last Hour" \
--vertical-label "DEGFx100" \
--upper-limit 14000 --lower-limit 3000 --rigid \
DEF:asource="/mnt/flash/freeair.rrd":fa:AVERAGE \
LINE1:asource#fcad00:"Chamber Free Air."

This was repeated for each graph, with the filename being changed as appropriate.

Finally, to get the information into a useful form, it was pulled into a simple webpage and served by Apache2:



The whole mess was started at boot via a crontab @REBOOT call, with the graphs being regenerated every 10 minutes. A 30 minute refresh was specified in the HTML code, and it all worked nicely.
The Raspberry Pi ended up just sitting on a table, needing only an Ethernet connection and power provided by an old BlackBerry phone charger.


Everything turned out better than I expected. (Note that the data was graphed raw. SNMP doesn't provide decimal points, so everything needs to be divided by 100 to get "actual" values.)



The CPU performed without issues, and I have some nice graphed data for what amounted to 30 minutes worth of setup time, instead of the unknown amount of time that would have been needed otherwise.

And the Pi? It gets put back into my pool for use in another project, some other time.