Category Archives: Development

Raspberry Pi sensors – Munin graphing plugin

I love Munin!  I’ve finally got one of the Raspberry Pi’s to be reasonably stable, so I’ve set up a munin-node on it.  The standard Linux sensord stuff doesn’t run on the arm core, so I had assumed I wouldn’t be able to see any exciting temperature graphs, but I was wrong!

The Raspberry Pi Debian image includes a command called vcgencmd, which allows root to interrogate various settings and measurements.  That includes the temperature, clock frequencies and voltages across various components.

So I’ve knocked up a quick plugin for Munin which gathers that stuff and graphs it.  You can get it over at GitHub here.  The current code looks like this (but the GitHub copy will be most up-to-date),

#!/bin/bash
# -*- sh -*-

: << =cut

=head1 NAME

pisense_ - Wildcard-plugin to monitor Raspberry Pi sensors (temp, volts, clock speed)

=head1 CONFIGURATION

This plugin needs to be run as root for vcgencmd to work.

[pisense_*]
user root

=head2 ENVIRONMENT VARIABLES

This plugin does not use environment variables.

=head2 WILDCARD PLUGIN

This is a wildcard plugin. To specify if you want temperature,
clock speed or volts, link this file to _volt, _temp
or _clock.

For example,

ln -s /usr/share/munin/plugins/pisense_ \
/etc/munin/plugins/pisense_clock

will monitor the clock speeds of your pi.

=head1 BUGS

None known.

=head1 NOTES

This plugin is shamelessley based on the ip_ plugin (structure).

=head1 MAGIC MARKERS

#%# family=auto
#%# capabilities=autoconf suggest

=head1 AUTHOR

Tony (tony@darkstorm.co.uk).

=head1 LICENSE

It's yours, do with it what you like.

=cut

. $MUNIN_LIBDIR/plugins/plugin.sh

sensor=${0##*/pisense_}

if [[ "$1" == "autoconf" ]]; then
    if ! /opt/vc/bin/vcgencmd firmware >/dev/null 2>/dev/null; then
        echo "no (could not run /opt/vc/bin/vcgencmd as user $(whoami))"
        exit 0
    else
        echo yes
        exit 0
    fi
fi

# this is flawed, vcgencmd always returns with RC 0. Needs expanding.
if [[ "$1" == "suggest" ]]; then
    if /opt/vc/bin/vcgencmd measure_temp >/dev/null 2>/dev/null; then
        echo temp
    fi
    if /opt/vc/bin/vcgencmd measure_volts >/dev/null 2>/dev/null; then
        echo volt
    fi
    if /opt/vc/bin/vcgencmd measure_clock core >/dev/null 2>/dev/null; then
        echo clock
    fi
    exit 0
fi

if [[ "$1" == "config" ]]; then

    if [[ "$sensor" == "temp" ]]
    then
        echo "graph_title Raspberry Pi core temp"
        echo "graph_args --base 1000"
        echo "graph_vlabel dgrees Celsius"
        echo "graph_category sensors"
        echo "temp.label Core Temperature"
        echo "temp.min 0"
    fi
    if [[ "$sensor" == "clock" ]]
    then
        echo "graph_title Raspberry Pi clock frequencies"
        echo "graph_args --base 1000"
        echo "graph_vlabel herz"
        echo "graph_category sensors"
        for clock in arm core h264 isp v3d uart pwm emmc pixel vec hdmi dpi
        do
           echo "clock$clock.label $clock clock Frequency"
           echo "clock$clock.min 0"
           echo "clock$clock.type GAUGE"
        done
    fi
    if [[ "$sensor" == "volt" ]]
    then
        echo "graph_title Raspberry Pi voltages"
        echo "graph_args --base 1000"
        echo "graph_vlabel volts"
        echo "graph_category sensors"
        for volt in core sdram_c sdram_i sdram_p
        do
           echo "volt$volt.label $volt voltage"
           echo "volt$volt.min 0"
           echo "volt$volt.type GAUGE"
        done
    fi

    exit 0
fi;

if [[ "$sensor" == "temp" ]]
then
    temp=$(/opt/vc/bin/vcgencmd measure_temp | awk -F"=" '{print $2}' | awk -F"'" '{print $1}')
    echo "temp.value $temp"
fi
if [[ "$sensor" == "clock" ]]
then
    for clock in arm core h264 isp v3d uart pwm emmc pixel vec hdmi dpi
    do
       clockval=$(/opt/vc/bin/vcgencmd measure_clock $clock | awk -F"=" '{print $2}')
       echo "clock$clock.value $clockval"
    done
fi
if [[ "$sensor" == "volt" ]]
then
   for volt in core sdram_c sdram_i sdram_p
   do
       voltage=$(/opt/vc/bin/vcgencmd measure_volts $volt | awk -F"=" '{print $2}' | tr -d "V")
       echo "volt$volt.value $voltage"
   done
fi

I’ll post some sample screenshots in a bit!

Compiling rrdtool on Cygwin

This post is half aide-mémoire and half public service announcement!  I use nmon at work to gather performance data, and I use customised version of nmon2web to graph it.  nmon2web relies on rrdtool, and I do a lot of my UNIX stuff these days using Cygwin.  Rather than use the Windows rrdtool binaries, I wanted to compile the latest version to run directly under Cygwin.

I’ve done this a few times now, with different Cygwin installs on both Windows XP and Windows 7, and every time I have to fight against various compilation issues.  I’ll cut to the chase, I hack at options and compiler settings and configure flags until it works, and I turn off most of the additional stuff to get it in.  But, it does work.

Get the Pre-requisites

All of the libraries and pre-requisites you need can be installed directly within Cygwin.  You’ll obviously need the regular development stuff (gcc, make, etc.) and you’ll also need the various libraries used by rrdtool.  Rather than worry about what you do and don’t need, I just whack on everything.  This is what I’ve got installed for each of the pre-reqs.

  • cairo (libcairo-devel, libcairo2)
  • glib (glib, glib-devel, glib2, glib2-devel, libglib1.2-devel, libglib1.2_0, libglib2.0-devel, libglib2.0_0)
  • libpng (libpng, libpng12, libpng14, libpng14-devel)
  • libxml2 (libxml2, libxml2-devel)
  • pango (libpango1.0-devel, libpango1.0_0, pango, pango-devel)
  • zlib (zlib, zlib-devel)
  • fontconfig (fontconfig, libfontconfig-devel, libfontconfig1)
  • freetype (libfreetype-devel, libfreetype6)
  • expat (expat, libexpat1, libexpat1-devel)

I’m certain that’s overkill, I had some of those installed already and installed a few extra libraries to get the compile working, but better safe than sorry!

configure options

The next step is working out what options to pass configure.  Some of these are required (on Windows 7 there are issues if you don’t use -no-undefined)

configure doesn’t seem to find the pango and cairo libraries under Cygwin unless I add these.

export CPPFLAGS="-I /usr/include/pango-1.0/pango/ -I /usr/include/cairo/cairo/"

and as I said, you need to prevent any undefined symbols in the libraries,

export LDFLAGS=-no-undefined

and then I basically turn off all the additional modules (perl, tcl, python, ruby) as well as mmap which doesn’t seem to work well under Cygwin anyway.  –prefix here is optional, it defaults to /opt, but I prefer everything under /usr/local.

./configure --disable-mmap --prefix=/usr/local/ --disable-tcl --disable-perl --disable-ruby --disable-python

Once that’s done, you can go for the compile.

Compiling

Run the usual make, you’ll get a whole bunch of warnings.  Such as,

warning: ‘optarg’ redeclared without dllimport attribute: previous dllimport ignored

No idea what they mean, but they don’t seem to break anything.

You’ll get a bunch of these,

*** Warning: linker path does not have real file for library -lstdc++.
*** I have the capability to make that library automatically link in when
*** you link to this library. But I can only do this if you have a
*** shared version of the library, which you do not appear to have
*** because I did check the linker path looking for a file starting
*** with libstdc++ and none of the candidates passed a file format test
*** using a file magic. Last file checked: /usr/lib/libpthread.a

because of the -no-undefined flag.  But again, doesn’t seem to break anything.

On Windows 7 (can’t remember if I got this on Windows XP) you’ll also get,

CCLD rrdupdate.exe
../libtool: line 8354: ./rrdupdate.exe: Permission denied
CC rrdcached-rrd_daemon.o

and you won’t be able to use rrdupdate.exe.  Running it gives the same permission denied error.  I’m not sure why yet, but I don’t use rrdupdate so it’s not been a big issue yet1.

Installing it all

Finally, after it all scrolls by, you can do a make install.

In /usr/local/bin you should end up with,

-rwxr-xr-x 1 User None 332K Jan 19 23:39 rrdcached.exe*
-rwxr-xr-x 1 User None 428K Jan 19 23:39 rrdcgi.exe*
-rwxr-xr-x 1 User None 641K Jan 19 23:39 rrdtool.exe*
-rwxr-xr-x 1 User None  14K Jan 19 23:39 rrdupdate.exe*

and rrdtool should work quite happily.

Finished!

So, know a better way?  Know why some bits still don’t work?  Know a sure fire way of fixing the warnings (if necessary), or getting rrdupdate to work, or being able to compile the additional modules?  Let me know!

  1. this only appears to be an issue with 64 bit Windows 7 []

Graphing ngIRCd stats (users / servers / channels) with Munin

I run a little ngIRCd server (well two) for some friends to use (if you’re a friend, and you want to know more, mail me!)

I’m also addicted to numbers, and I’m always interested in monitoring the stuff I run, so I’ve written (adapted really) an existing script to track how many users are connected to the ngIRCd daemons using munin.

I’m hosting them on github (along with some other stuff I wrote, or am writing).  If you’re interested, you can check them out (hah, get it? I made a version control joke!) here.