Remote Sensor (Raspberry Pi) locale temperature monitoring via snmp and cacti
Imagine you're running an example configuration as shown in the image below.
There is a server running at a data center (internal ip 192.168.0.1). Remotely you're running for example a Raspberry Pi box (internal 10.0.0.250) where you'd like to monitor the locale temperature as a RRD graph within Cacti (Cacti runs on the data center server).
First of all we need to clarify some environmental parameters for this example (at the time this article was written):
- Server at the data center (DC) runs Ubuntu 12.04, iptables and OpenVPN
- Raspi at the branch is behind a router (NAT enabled) and served by a public dynamic ip address (ip address really changing!)
- Raspi runs Debian Wheezy as well as OpenVPN and some iptables stuff (for a secure connection between DC and the branch)
Some questions which you may ask yourself:
Q: Why do we need a secure connection?
A: snmp is an UDP based protocol. It is stateless and it transports data (request and response) unencrypted. As we want to analyze remote data - connected over the Internet - we use in this example transparent encryption on the basis of OpenVPN.
Q: Why do we use snmp, iptables and OpenVPN instead of simple ssh on the remote site for accessing data like the temperature?
A: We may use ssh instead of snmp but getting data via ssh means a lot of cpu load on a small remote device (like a Raspberry Pi) for secure login and data encryption and there are much more data being transmitted for a single temperature request when using ssh.
Let us furthermore assume:
- Server at the data center can access the server at the branch through internal ip addresses only (192.168.0.1 -> 10.0.0.250 --> means: transparent OpenVPN encryption).
- Server at the branch (Raspberry Pi) is providing all necessary data to be drawn by Cacti via snmp.
What do we need to do to get the Raspi temperature via snmp?
In general Raspi provides its environmental data through a Raspi specific application installed by default.
Command: /opt/vc/bin/vcgencmd measure_temp Response: temp=40.1'C
As Cacti needs data in form of a key-value pair separated by ":" we simply extract and strip the trailing unit information.
Command: /opt/vc/bin/vcgencmd measure_temp | sed 's/temp=//g' | sed "s/'.*//g" Reponse: 40.1
Lets make a shell script doing the above described steps all in one:
Command: cat /opt/temp_cacti.sh Response: #!/bin/bash T=`/opt/vc/bin/vcgencmd measure_temp | sed 's/temp=//g' | sed "s/'.*//g"` echo -n "temp:$T" exit 0;
When calling the script we get:
Command: /opt/temp_cacti.sh Response: temp:40.6
This kind of output is exactly what Cacti needs as input for a new "Data Input Method".
As next step we need to make snmp able to provide Raspis temperature as a new private enterprise OID. Therefore you need to add the following line to /etc/snmp/snmpd.conf:
extend .18.104.22.168.4.1.65535.1 /bin/bash "/usr/bin/sudo /opt/temp_cacti.sh"
As snmpd runs as user "snmp" we additionally need to execute "/opt/temp_cacti.sh" by using sudo. So add the follow line to your sudoers configuration:
Finally let us test our locale "get the temperature via snmp" configuration:
Command: sudo -s -u snmp Command: /opt/temp_cacti.sh -> won't work: Response: "temp:VCHI initialization failed" Command: sudo /opt/temp_cacti.sh -> will work: Response: "temp:40.6" :-) Command: exit
Lets now test if the temperature is also provided by snmpwalk/snmpget (implies correct snmp configuration):
Command: snmpwalk -c public -v 1 localhost iso.22.214.171.124.1.65535.1 Response: iso.126.96.36.199.1.655188.8.131.52 = INTEGER: 1 iso.184.108.40.206.1.655220.127.116.11.18.104.22.168.22.214.171.124.97.115.104 = STRING: "/usr/bin/sudo /opt/temp_cacti.sh" iso.126.96.36.199.1.655188.8.131.52.184.108.40.206.220.127.116.11.97.115.104 = "" iso.18.104.22.168.1.65522.214.171.124.126.96.36.199.188.8.131.52.97.115.104 = "" iso.184.108.40.206.1.655220.127.116.11.18.104.22.168.22.214.171.124.97.115.104 = INTEGER: 5 iso.126.96.36.199.1.655188.8.131.52.184.108.40.206.220.127.116.11.97.115.104 = INTEGER: 1 iso.18.104.22.168.1.65522.214.171.124.126.96.36.199.188.8.131.52.97.115.104 = INTEGER: 1 iso.184.108.40.206.1.655220.127.116.11.18.104.22.168.22.214.171.124.97.115.104 = INTEGER: 4 iso.126.96.36.199.1.655188.8.131.52.184.108.40.206.220.127.116.11.97.115.104 = INTEGER: 1 iso.18.104.22.168.1.65522.214.171.124.126.96.36.199.188.8.131.52.97.115.104 = STRING: "temp:40.6" iso.184.108.40.206.1.655220.127.116.11.18.104.22.168.22.214.171.124.97.115.104 = STRING: "temp:40.6" iso.126.96.36.199.1.655188.8.131.52.184.108.40.206.220.127.116.11.97.115.104 = INTEGER: 1 iso.18.104.22.168.1.65522.214.171.124.126.96.36.199.188.8.131.52.97.115.104 = INTEGER: 0 iso.184.108.40.206.1.655220.127.116.11.18.104.22.168.22.214.171.124.126.96.36.199 = STRING: "temp:40.6"
Command: snmpget -c public -v 1 localhost iso.188.8.131.52.1.655184.108.40.206.220.127.116.11.18.104.22.168.97.115.104 Reponse: iso.22.214.171.124.1.655126.96.36.199.188.8.131.52.184.108.40.206.97.115.104 = STRING: "temp:40.6"
Great! This is what we need and what Cacti is going to poll for the RRD graph.
Let us know switch back to our server running at the data center.
As described above we're know able to get the remote Raspi temperature via snmpget.
Try this by executing the following command on our server running at the data center:
Command: snmpget -c public -v 1 10.0.0.250 iso.220.127.116.11.1.65518.104.22.168.22.214.171.124.126.96.36.199.97.115.104 Response: iso.188.8.131.52.1.655184.108.40.206.220.127.116.11.18.104.22.168.97.115.104 = STRING: "temp:40.6"
As next step we need to extract the temperature information from the snmpget response. To accomplish this we use a simple script which will also be used by Cacti ("Data Input Method").
Command: cat /opt/raspi_temp_cacti.sh Response: #!/bin/bash /usr/bin/snmpget -c public -v 1 $1 iso.22.214.171.124.1.655126.96.36.199.188.8.131.52.184.108.40.206.97.115.104 | /usr/bin/perl -e '<STDIN> =~ m/\"(temp:.*?)\"/; print $1;' exit 0;
Let us test the script:
Command: /opt/raspi_temp_cacti.sh 10.0.0.250 Response: temp:40.6
Finally: Let us configure Cacti.
Add a new "Data Input Method":
Add a new "Data Source":
Add a new "Graph":
This is the result:
This method can be used to transfer any kind of information to an input as a new "Data Input Method" and to be finally drawn as RRD graph by Cacti.