On my route to rebuild the M2M demo at real-world scale, I have taken the first step. An old (from around 2004) and absurdly underpowered ARM Intel XScale IXP420 running today's Debian Wheezy (NSLU2) with just 266mhz has been recommissioned to act as a temperature sensor (why buy an Rasperry Pi or Arduino, if you can recycle?). The actual thermostat is a cheapish ~10bucks USB connected "TEMPer" device.
Once the hardware is wired up and put in place, the following instructions build the pcsensor binary that is needed to read data from the USB dongle:
# Install Debian necessities
apt-get install libusb-dev build-essential
# Get source (without git installed, download zip file from github)
# (I had to hack the original code to continuously flush the output to stdout to subsequently read it with mosquitto)
git clone https://github.com/lemmy/usb-thermometer.git
# Build binary
cd usb-thermometer/
make
# "Install" into system
cp 99-tempsensor.rules /etc/udev/rules.d/
cp pcsensor /usr/local/bin/
At this point a simple monitoring tool like e.g. munin can already show the temperature readings for last night - classico.
Rendering to a static web page however is too old school and thus I wanted each reading to be send out with MQTT so that I can get the readings on any smartphone (or browser in realtime below). Fortunately, Wheezy comes with a simple MQTT command line client that is easily connected to the pcsensor process (Btw. re-spawning a new pcsensor process for every reading and piping the output to mosquitoo turned out to cause problems on the USB layer (device re-connects). The current solution with long-lived processes is also less resource intensive):
# Start a pcsensor process and send its output via mosquitto (line by line) to m2m.eclipse.org
pcsensor -c -s -l | mosquitto_pub -t 8742hvvgsdf/temp -l -h m2m.eclipse.org
Thanks to mosquitto's javascript client (though deprecated in favor of Paho) and websockets it is actually almost trivial to show MQTT messages in-line in a blog post like this one. :-) (I will leave it to the educated reader to lookup the source code manually. It's almost identical to their examples)
Current temperature reading is -1 in °C for topic NA
(with timestamp epoch)
Btw. this project serves a real world purpose too ;-). The greenhouse has electrical heating to protect the plants from frost over winter. Last winter though, the heating broke and all plants died as a consequence. Thus, the temperature readings are written to a local (history) file and collected by said Munin. Munin then sends out alarms via email when a certain threshold gets reached:
# Optionally one can multiplex the sensor reading to a local file to feed the data also to munin:
# Create ramdisk to avoid writes to the slow and worn out USB pen drive
mkdir /var/lib/ram; chmod 777 /var/lib/ram
mount -t tmpfs -o size=256 tmpfs /var/lib/ram
# Or permanently
echo 'none /var/lib/ram tmpfs nodev,nosuid,noexec,nodiratime,size=256 0 0' >> /etc/fstab
# Write a local history to a tiny (ramdisk) file
pcsensor -c -s -l | awk '{print; print >f;close(f)}' f=/var/lib/ram/temp.txt | mosquitto_pub -t 8742hvvgsdf/temp -l -h m2m.eclipse.org
# Save the following file
echo '#!/bin/sh
case $1 in
config)
cat < <'EOM'
graph_title Temperature
graph_vlabel temp in C
graph_args --base 1000 -l 0
graph_category Temperature
temp.label Temperature
temp.warning 0
temp.critical -5
EOM
exit 0;;
esac
temp=`cat /var/lib/ram/temp.txt | tail -1`
echo "temp.value "$temp""' > /etc/munin/plugins/temperature
To automatically start temperature readins at boot time, create (yet another) script and have it spawned by init.
echo '#!/bin/bash
# make sure pcsensor, awk and mosquitto are killed along with this script
# http://riccomini.name/posts/linux/2012-09-25-kill-subprocesses-linux-bash/
trap 'kill $(jobs -p)' EXIT
# do the actual work
/usr/local/bin/pcsensor -c -s -l | awk \'{print; print >f;close(f)}\' f=/var/lib/ram/temp.txt | /usr/bin/mosquitto_pub -t 8742hvvgsdf/temp -l -h m2m.eclipse.org
' > /usr/local/bin/measureTemp.sh
sudo echo '# measureTemp
mt:2345:respawn:/usr/bin/sudo -u markus "/usr/local/bin/measureTemp.sh"' >> /etc/inittab