Temperature monitoring with Zabbix and Raspberry Pi via SNMP using DS18B20 sensors

To monitor the temperature I have made a system based on a Raspberry Pi combined with the classic Maxim DS18B20 temperature sensors. My Raspberry Pi is running Raspbian Lite image (Check my Raspberry Pi ADS-B Receiver Project article to install it or use Raspbian ISO from raspberrypi.org)

Raspberry Pi

What you will need:

  • Raspberry Pi 2 or 3
  • microSD memory card. I have used a 16GB card
  • Power Supply 5V micro USB. Currently I use a 2A 5V PSU
  • Maxim DS18B20 sensor(s)
  • Regular 4K7 Ohm through hole resistor
  • Wago terminal blocks or soldering iron.

Raspberry Pi pinout:Connect the three wires from the temperature sensor(s) like this:

Positive (red): 3.3V –> Physical pin 1
Data (yellow): GPIO4 –> Physical pin 7
Ground (black): GND –> Physical pin 9

Since I used the DS18B20 sensors, they are polled over a single wire with a 4K7 resistor across the VCC and Data wires. Solder 1 (one) 4K7 resistor between Red and Yellow sensor wire. You can have as many DS18B20 sensors as you want and for all of them you need only one resistor!

 

I’m using Raspbian on my Pi, so any instructions are done with a Raspbian flavour. Most other distros should have the same setup though.
The Pi needs to be configured to use the w1-gpio device tree overlay (dtoverlay).
This is done by adding the line dtoverlay=w1-gpio to the end of the config.txt file on the /boot partition.

sudo nano /boot/config.txt

add at the end of this file:

dtoverlay=w1-gpio,gpiopin=4

Ctrl-X, Y, Enter.

Reboot:

sudo reboot

Once this dtoverlay has been activated, you should be able to see your sensors under /sys/devices/w1_bus_master1/

sudo cat /sys/devices/w1_bus_master1/w1_master_slave_count

If everything works, the output should mutch your number of connected sensors. 3 in my case.

Each DS18B20 sensor has unique ID, you can find it by using this command:

ls -l /sys/bus/w1/devices/

Output will be something like this:

lrwxrwxrwx 1 root root 0 Dec 01 14:41 28-011564a5031f -> ../../../devices/w1_bus_master1/28-011564a5031f

where 28-XXXXXXXXXXXX is sensor ID.

Let’s try to get temperature from one sensor:

cat /sys/bus/w1/devices/28-XXXXXXXXXXXX/w1_slave

change 28-X… to your sensor ID.

The output should be something similar to this:

8f 02 4b 46 7f ff 0c 10 da : crc=da YES
8f 02 4b 46 7f ff 0c 10 da t=40937

From this we can see that the CRC is OK with “YES“. If you get “NO” you should check your connections and that you have the correct resistor. We can also see that the measured temperature is 40.937°C. The output needs to be divided by 1000 to get the temperature to the correct amount of decimal places.

If you have multiple sensors connected, check that all of them works and have “crc = da YES” in the output.

Now we need to install the necessary SNMP dependencies and add loading of a module called “Extend”

sudo apt-get update && sudo apt-get install snmp snmpd snmp-mibs-downloader

Due to a unknown reason, the extend module is not loaded by default. Therefore we need to add it manually:

sudo nano /etc/default/snmpd

With the sensors plugged in, it’s time to extend the SNMP agent to allow us to poll the temperature sensors over SNMP.
I’ve written a script that will output just the temperature to the SNMP agent, I’ve placed this script in /opt/scripts

sudo mkdir /opt/scripts

but you’re free to put it wherever you want. You’ll need to keep the location handy for when we extend the SNMP agent.

I’ve named this script gettemp.sh:

sudo nano /opt/scripts/gettemp.sh

#!/bin/bash
#
# Usage: gettemp.sh 
# e.g. gettemp.sh 28-021564b3ebff
SENSOR=$1
SLAVE="/sys/devices/w1_bus_master1/"$SENSOR"/w1_slave"
OUTPUT=$(/bin/cat $SLAVE | /usr/bin/awk -F 't=' ' { printf $2 } ')
echo $OUTPUT

Make our script executable:

sudo chmod +x /opt/scripts/gettemp.sh

With this script, you should be able to call the script from a command line, and it should output the temperature for that sensor:

/opt/scripts/gettemp.sh 28-XXXXXXXXXXXX

With this script operational, we’ll need to setup the SNMP agent to run this script to provide us the output of this script over SNMP.
To do this, we need to modify /etc/snmp/snmpd.conf

sudo nano /etc/snmp/snmpd.conf

At the end of the file, put in this line:

extend .1.3.6.1.3.1.1 temp1 /bin/bash /opt/scripts/gettemp.sh 28-XXXXXXXXXXXX

Make sure you replace the sensor id with your own sensor id. If you want to monitor more than one sensor, add more extend lines, and give them differing names, like temp2, temp3, etc. One line for each sensor.

Comment line with local host address and uncomment the next one to be able connect from Zabbix server.

#  Listen for connections from the local system only
#agentAddress  udp:127.0.0.1:161
#  Listen for connections on all interfaces (both IPv4 *and* IPv6)
agentAddress udp:161,udp6:[::1]:161

In ACCESS CONTROL section add:

view   systemonly  included   .1.3.6.1.2
view   systemonly  included   .1.3.6.1.3

to be able to use snmpwalk.

After you modify the snmpd.conf file, make sure you restart SNMP agent with

sudo /etc/init.d/snmpd restart

or

sudo service snmpd restart

Once the SNMP agent is back up and running, you should be able to poll the OID we specified above (.1.3.6.1.3.1.1) and get the output of the command. I’ve run the snmpwalk on the Pi itself, polling itself:

snmpwalk -v 2c -c public 127.0.0.1 .1.3.6.1.3.1.1

Output:

pi@raspberrypi:~ $ snmpwalk -v 2c -c public 127.0.0.1 .1.3.6.1.3.1.1
iso.3.6.1.3.1.1.1.0 = INTEGER: 3
iso.3.6.1.3.1.1.2.1.2.5.116.101.109.112.49 = STRING: "/bin/bash"
iso.3.6.1.3.1.1.2.1.2.5.116.101.109.112.50 = STRING: "/bin/bash"
iso.3.6.1.3.1.1.2.1.2.5.116.101.109.112.51 = STRING: "/bin/bash"
iso.3.6.1.3.1.1.2.1.3.5.116.101.109.112.49 = STRING: "/opt/scripts/gettemp.sh 28-021564b3ebff"
iso.3.6.1.3.1.1.2.1.3.5.116.101.109.112.50 = STRING: "/opt/scripts/gettemp.sh 28-021564ba9dff"
iso.3.6.1.3.1.1.2.1.3.5.116.101.109.112.51 = STRING: "/opt/scripts/gettemp.sh 28-011564b50fff"
iso.3.6.1.3.1.1.2.1.4.5.116.101.109.112.49 = ""
iso.3.6.1.3.1.1.2.1.4.5.116.101.109.112.50 = ""
iso.3.6.1.3.1.1.2.1.4.5.116.101.109.112.51 = ""
iso.3.6.1.3.1.1.2.1.5.5.116.101.109.112.49 = INTEGER: 5
iso.3.6.1.3.1.1.2.1.5.5.116.101.109.112.50 = INTEGER: 5
iso.3.6.1.3.1.1.2.1.5.5.116.101.109.112.51 = INTEGER: 5
iso.3.6.1.3.1.1.2.1.6.5.116.101.109.112.49 = INTEGER: 1
iso.3.6.1.3.1.1.2.1.6.5.116.101.109.112.50 = INTEGER: 1
iso.3.6.1.3.1.1.2.1.6.5.116.101.109.112.51 = INTEGER: 1
iso.3.6.1.3.1.1.2.1.7.5.116.101.109.112.49 = INTEGER: 1
iso.3.6.1.3.1.1.2.1.7.5.116.101.109.112.50 = INTEGER: 1
iso.3.6.1.3.1.1.2.1.7.5.116.101.109.112.51 = INTEGER: 1
iso.3.6.1.3.1.1.2.1.20.5.116.101.109.112.49 = INTEGER: 4
iso.3.6.1.3.1.1.2.1.20.5.116.101.109.112.50 = INTEGER: 4
iso.3.6.1.3.1.1.2.1.20.5.116.101.109.112.51 = INTEGER: 4
iso.3.6.1.3.1.1.2.1.21.5.116.101.109.112.49 = INTEGER: 1
iso.3.6.1.3.1.1.2.1.21.5.116.101.109.112.50 = INTEGER: 1
iso.3.6.1.3.1.1.2.1.21.5.116.101.109.112.51 = INTEGER: 1
iso.3.6.1.3.1.1.3.1.1.5.116.101.109.112.49 = STRING: "20875"
iso.3.6.1.3.1.1.3.1.1.5.116.101.109.112.50 = STRING: "26375"
iso.3.6.1.3.1.1.3.1.1.5.116.101.109.112.51 = STRING: "40937"
iso.3.6.1.3.1.1.3.1.2.5.116.101.109.112.49 = STRING: "20875"
iso.3.6.1.3.1.1.3.1.2.5.116.101.109.112.50 = STRING: "26375"
iso.3.6.1.3.1.1.3.1.2.5.116.101.109.112.51 = STRING: "40937"
iso.3.6.1.3.1.1.3.1.3.5.116.101.109.112.49 = INTEGER: 1
iso.3.6.1.3.1.1.3.1.3.5.116.101.109.112.50 = INTEGER: 1
iso.3.6.1.3.1.1.3.1.3.5.116.101.109.112.51 = INTEGER: 1
iso.3.6.1.3.1.1.3.1.4.5.116.101.109.112.49 = INTEGER: 0
iso.3.6.1.3.1.1.3.1.4.5.116.101.109.112.50 = INTEGER: 0
iso.3.6.1.3.1.1.3.1.4.5.116.101.109.112.51 = INTEGER: 0
iso.3.6.1.3.1.1.4.1.2.5.116.101.109.112.49.1 = STRING: "20875"
iso.3.6.1.3.1.1.4.1.2.5.116.101.109.112.50.1 = STRING: "26375"
iso.3.6.1.3.1.1.4.1.2.5.116.101.109.112.51.1 = STRING: "40937"
iso.3.6.1.3.1.1.4.1.2.5.116.101.109.112.51.1 = No more variables left in this MIB View (It is past the end of the MIB tree)

As you can see from the example, the temperature is output in a couple of different places.
Polling the SNMP agent with one of those locations directly should yield only the temperature.

snmpwalk -v 2c -c public 127.0.0.1 .1.3.6.1.3.1.1.4

iso.3.6.1.3.1.1.4.1.2.5.116.101.109.112.49.1 = STRING: "20875"
iso.3.6.1.3.1.1.4.1.2.5.116.101.109.112.50.1 = STRING: "26375"
iso.3.6.1.3.1.1.4.1.2.5.116.101.109.112.51.1 = STRING: "40937"
iso.3.6.1.3.1.1.4.1.2.5.116.101.109.112.51.1 = No more variables left in this MIB View (It is past the end of the MIB tree)

With that, we now have SNMP set up on the Pi, ready to be polled for the temperature by Zabbix server.

Zabbix server

The Raspberry Pi will need to be monitored in some way by Zabbix in order for us to record the temperatures from the SNMP agent that we’ve set up.
You’ll need to add the Raspberry Pi as a host in Zabbix, and give it an IP address under the SNMP interfaces section. I’ve added the SNMP OS Linux template to monitor the rest of the Pi stats, but that’s not required for monitoring temperatures.

Once the Pi is monitored, we’ll need to create an item for each sensor. I have 3 sensors hooked up to my Pi but I’ll only set up one in this blog post as the other 2 will be setup in the exact same way.

In the Items section for your Raspberry Pi host, create a new item.
Give the item a name, I’ve used Temperature GREEN 28-021564ba9dff as a name, this is so that I know which sensor this is, and what role the sensor is playing – in this case it’s sensor 28-021564ba9dff.

For the key, I’ve used TempSensor-28-021564ba9dff, this is to match it up with the sensor ID as the key needs to be unique.
For the SNMP OID, you will need to customise this to your own setup. I have used iso.3.6.1.3.1.1.4.1.2.5.116.101.109.112.50.1 for my Pi as that’s the OID that returns the temperature value of the sensor.

I use a public for my SNMP community string, however you’re free to hard code the community string here.
For the Type of information, I’ve used Numeric (float) so that I can get the full precision of the sensor.
I’ve set Units to 'C to indicate degrees Celsius, and I’ve also set a custom multiplier of 0.001 to get the decimal point to the correct location for the sensor reading.

The rest of the settings are up to you to define, I’ve used defaults for most of it. After the item is created, we should be able to check the Latest Data section for the Pi, and see the data coming in from the sensor.

Creating a Graph

Since there’s not much use of data being recorded but not being displayed, we’ll create a graph to display the data on.
On the Raspberry Pi host, click on the graphs link to open the graphs page, and then click on the Create Graph button.
Give the graph a name, and add in the sensor items you created previously.

Once the items have been added in, click on the Save button to save the graph.
Give Zabbix some time to go through some polling cycles, and you should get a graph of the temperature data from the sensors.

With this data, you could then also set up triggers if things go over or under a certain temperature. These triggers could then do things like send emails, start fans, start heaters etc.
This is just the start of what you could do with Zabbix and a Raspberry Pi!

Done!

Stay in the Loop

Get the weekly email from TechLifeTravel that makes reading the news actually enjoyable. Join our mailing list to stay in the loop to stay informed, for free.

LATEST ARTICLES