Saturday, January 18, 2014

Measuring temperature with OpenWrt and submitting values to EmonCMS

I'm using OpenWrt with following customizations to send temperature readings to EmonCMS. Hardware is noname Ralink RT3052 router (WR512-3GN) and Dallas DS9097U compatible USB 1-wire adapter. Main reason for going with Image Generator instead of compiling custom firmware was to keep binary and API compatibility with packages from stock OpenWrt repository. Package selection below leaves 168kB free on JFFS2 filesystem. Drop editor, Luci etc. and you'll have a lot more free. If you don't need to patch init scripts like I did due bug in WR512-3GN support you can simply install packages and apply scripts over top of official OpenWrt release flashed to your router.



# Download OpenWrt 12.09 Image Generator (ImageBuilder)
mkdir ~/openwrt
cd ~/openwrt
wget http://downloads.openwrt.org/attitude_adjustment/12.09/ramips/rt305x/OpenWrt-ImageBuilder-ramips_rt305x-for-linux-i486.tar.bz2
tar -xvjf OpenWrt-ImageBuilder-ramips_rt305x-for-linux-i486.tar.bz2
cd OpenWrt-ImageBuilder-ramips_rt305x-for-linux-i486
# Create folder structure for extra files we want to include on our squashfs image
mkdir -p files/etc/config files/etc/uci-defaults files/etc/crontabs files/lib/preinit files/lib/functions

# Various settings we do only once after installing new firmware image
cat<<'__EOF__'>files/etc/uci-defaults/default-conf.sh
#!/bin/sh
# Turn off OpenWrt stock firewall
/etc/init.d/firewall disable

# Enable Luci web management
/etc/init.d/uhttpd enable

# Symlink crontab to standard location
ln -sf /etc/crontabs/root /etc/crontab

# Remove this script so it's executed only once after firmware install
rm -f /etc/uci-defaults/default-conf.sh
__EOF__
# Script needs to be executable
chmod a+x files/etc/uci-defaults/default-conf.sh

# Since we just disabled OpenWrt builtin overly complicated firewall
# rules set some basic stuff over here
cat<<'__EOF__'>files/etc/rc.local
#!/bin/sh
# Do nothing if OpenWrt builtin firewall has been enabled
[ -h /etc/rc.d/S45firewall ] && exit 0
# Very basic iptables to only allow management from local network
iptables -F INPUT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
iptables -A INPUT -m state --state NEW -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 23 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 80 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited
#
exit 0
__EOF__
# Script needs to be executable
chmod a+x files/etc/rc.local

# Changing default network settings has been made REALLY difficult for some reason...
# You can't overwrite default network file as you lose platform specific config.
# You can't change it using custom uci-defaults script because your changes get overwritten.
mkdir -p foo
tar -C foo -xvzf packages/base-files_117-r36088_ramips.ipk
tar -C foo -xvzf foo/data.tar.gz
sed -e"s/^set network.lan.ipaddr=.*/set network.lan.ipaddr='192.168.1.99'/g" \
    -e"s/^set network.lan.netmask=.*/set network.lan.netmask='255.255.255.0'\nset network.lan.gateway='192.168.1.1'\nset network.lan.dns='8.8.8.8 8.8.4.4'/g" \
    < foo/lib/functions/uci-defaults.sh \
    > files/lib/functions/uci-defaults.sh
rm -rf foo

# Fix board detection code - without this ethernet mac is wrong (00:11:22:33:44:55)
sed -e 's/sl-r7205/wr512-3gn|sl-r7205/g' \
    < ./target/linux/ramips/base-files/lib/preinit/06_set_iface_mac \
    > files/lib/preinit/06_set_iface_mac
# Script needs to be executable
chmod a+x files/lib/preinit/06_set_iface_mac

# Crontab to run digitemp once per minute
cat<<'__EOF__'>files/etc/crontabs/root
*/1 * * * * /etc/digitemp.sh >/dev/null 2>/dev/null
__EOF__

# Digitemp script to do magic
cat<<'__EOF__'>files/etc/digitemp.sh
#!/bin/sh

# Turn off leds
echo "0" >"/sys/class/leds/wr512:green:station/brightness"
echo "0" >"/sys/class/leds/wr512:green:ap/brightness"
echo "0" >"/sys/class/leds/wr512:green:gateway/brightness"
echo "0" >"/sys/class/leds/wr512:green:3g/brightness"

# Do nothing if DS9097U is missing
[ -c /dev/ttyUSB0 ] || exit 0

# Turn on leds to signal progress of script (fast blinking)
echo "255" >"/sys/class/leds/wr512:green:station/brightness"
echo "timer" >"/sys/class/leds/wr512:green:station/trigger"
echo "10" >"/sys/class/leds/wr512:green:station/delay_on"
echo "100" >"/sys/class/leds/wr512:green:station/delay_off"

# Kill any old digitemp processes running
killall -9 digitemp_DS9097U >/dev/null 2>/dev/null

# Turn on leds to signal progress of script
echo "255" >"/sys/class/leds/wr512:green:ap/brightness"

# Init digitemprc to cover any changes in list of connected sensors
echo "Found following sensors:"
digitemp_DS9097U -s /dev/ttyUSB0 -q -i

# Turn on leds to signal progress of script
echo "255" >"/sys/class/leds/wr512:green:gateway/brightness"

# Read all sensors and mangle to format that emoncms can accept
submit=$(digitemp_DS9097U -s /dev/ttyUSB0 -q -a -o"temp_%R:%.2C"|grep "^temp_"|xargs|sed -e's| |,|g')
echo "Submitting following info: "${submit}

# Turn on leds to signal progress of script
echo "255" >"/sys/class/leds/wr512:green:3g/brightness"

# Submit using curl
curl 'http://emoncms.example.com/emoncms/input/post.json?apikey=bab33b51f71d4170259ac6eebdc881c4&node=100&json=\{'${submit}'\}'

# Turn off leds
echo "0" >"/sys/class/leds/wr512:green:station/brightness"
echo "0" >"/sys/class/leds/wr512:green:ap/brightness"
echo "0" >"/sys/class/leds/wr512:green:gateway/brightness"
echo "0" >"/sys/class/leds/wr512:green:3g/brightness"

# Done
exit 0
__EOF__
# Script needs to be executable
chmod a+x files/etc/digitemp.sh
# Build custom image with our changes
make image PROFILE=Default FILES=files/ PACKAGES="luci luci-theme-base luci-theme-openwrt luci-i18n-english kmod-usb-serial-ftdi digitemp curl joe -dnsmasq -ppp -ppp-mod-pppoe"
# Copy bin/ramips/openwrt-ramips-rt305x-wr512-3gn-4M-squashfs-sysupgrade.bin to router
# Run these on router, not on your PC used to create image
# wget is just one way to transfer new image, use your imagination as necessary
cd /tmp
wget http://192.168.1.10/openwrt/ramips/openwrt-ramips-rt305x-wr512-3gn-4M-squashfs-sysupgrade.bin
sysupgrade -n -v openwrt-ramips-rt305x-wr512-3gn-4M-squashfs-sysupgrade.bin 

After reboot login to OpenWrt device, set password and that's about it

No comments:

Post a Comment

Got something to say?!