How fun would it be if you were able to monitor the real time temperature and humidity of your home or work location? In this tutorial we’re going to do just that. First of all, we’re going to setup a Raspberry Pi equipped with a DHT-22 Temperature and Humidity sensor to capture real time readings. Then we’re going to push these captured metrics to InfluxDb – a time series database. Finally, we’re going to set up Grafana on our Raspberry Pi to create real time graphs of the temperature and humidity fluctuations.

Requirements

  • Raspberry Pi 
  • DHT22 – am2302 temperature and humidity sensor

Connecting DHT22 to the Raspberry Pi 

To be able to capture temperature and humidity readings from the Raspberry Pi, we need to connect the DHT22 – am2302 sensor to the Pi. This step will require 3 Female to Female jumper wires, a DHT22 – am2302 sensor.

Connections: 

DHT22 comes in two variants, one is a naked one with 4 pins and the other one comes with a driver circuit and has only 3 pins. The driver circuit already contains a resistive load so you can skip connecting a resistor if you have the 3 legged one.

DHT-22, 3 Pin with Driver Circuit
DHT-22, 3 Pin with Driver Circuit
DHT-22 without Driver Circuit
DHT-22 without Driver Circuit

DHT22 with 4 pins

  1. Connect Pin 1 of the DHT22 to the 3.3v power GPIO pin on the Raspberry Pi.
  2. Pin 2 of the DHT22 to the GPIO 4 of the Pi.
  3. And the Pin 4 with the ground pin on the Pi. No connection is required on the Pin 3 of the sensor.
  4. Connect a 10k resistor between the Pin 1 and Pin 4 connections as shown in the figure.

DHT22 with a driver circuit

  1. Connect Pin 1 of the DHT22 to the 3.3v power GPIO pin on the Raspberry Pi.
  2. Pin 2 of the DHT22 to the GPIO 4 of the Pi.
  3. Pin 3 with the ground pin on the Pi. No resistor is required with this circuit.
DHT-22 am2302 Raspberry Pi Connection

Once all the connections have been made, boot the Raspberry Pi by plugging it into a power supply. And if you don’t have a monitor attached to the Raspberry Pi, then connect to it using ssh.

Logging temperature values from the DHT22 sensor with Python3

We’ll be using Python3 to log temperature and humidity values to a log file. We’ll then read this data in the next section to push data to a time-series database.

To get the readings from the Raspberry Pi, we’ll be using the open source Adafruit_DHT library. First we need to make sure python3 and all the build essential tools are installed properly on the Raspberry Pi. Run the following commands in the Raspberry Pi to update the sources and install the packages.

sudo apt-get update
sudo apt-get install build-essential python3-dev

Now install the Adafruit_DHT library.

sudo pip3 install Adafruit_DHT

To verify everything is working as expected run python3 shell using sudo python3, and execute the following code. We’re using sudo because accessing the GPIO requires root privileges on the Pi.

import Adafruit_DHT as adht
humidity,temperature = adht.read_retry(adht.DHT22, 4)
print( "humidity: {1:0.1f} and temperature: {1:0.1f} C".format(humidity, temperature))

Exit the shell using exit() after verifying the values. We’re now ready to create a script that will read values from the sensor and log them in a log file.

Technically we can directly push values from Python3 to Influxdb. However using the log file approach is better suited for our task simply because we wouldn’t have to write the retry logic for the scenario where our script cannot make a connection to the database. And in case the database is not local and we’re pushing the data over the internet, we would want a copy of our data in cases of connection failures. All the similar cases and the retry logic will be handled by our log parser, telegraf

Now we write a custom simple python3 script for logging these values to a log file every 2 seconds.

import Adafruit_DHT as adht
import time
import logging

logging.basicConfig(filename='temperature.log', filemode='a', format='%(created)f %(message)s', level=logging.INFO)

while True:     
    h,t = adht.read_retry(adht.DHT22, 4)    
    logging.info('Temp={0:0.1f} C and Humidity={1:0.1f} %'.format(t, h))

Sample output in temperature.log:

1551010824.434111 Temp=24.0 C  and Humidity=72.0 %
1551010826.963109 Temp=24.0 C  and Humidity=72.3 %
1551010829.492004 Temp=24.0 C  and Humidity=72.5 %
1551010834.547388 Temp=24.0 C  and Humidity=72.6 %

This is a time-series data, containing timestamp and the temperature & humidity at that instance. Run the script in the permanently in the background using screen or nohup.

Setting up InfluxDb and telegraf

In this step we setup InfluxDb and Telegraf log parser on the Raspberry Pi. 

InfluxDb Installation on Raspberry Pi

wget -qO- https://repos.influxdata.com/influxdb.key | sudo tee /etc/apt/sources.list.d/influxdb.list test $VERSION\_ID = "8" && echo "deb https://repos.influxdata.com/debian jessie stable" | sudo tee /etc/apt/sources.list.d/influxdb.list test $VERSION\_ID = "9" && echo "deb https://repos.influxdata.com/debian stretch stable" | sudo tee /etc/apt/sources.list.d/influxdb.list

sudo apt-get update && sudo apt-get install influxdb
sudo service influxdb start

#verify influxdb is running with the following command.
sudo service influxdb status

Telgraf log parser Installation on Raspberry Pi

Find the suitable (armhf) version for your Raspberry Pi from here and download using wget. For folks running a Raspbian variant, download the .deb package and install using the following command.

sudo dpkg -i telegraf_1.9.4-1_armhf.deb

Parsing logs on Raspberry Pi using telegraf

After setting up telegraf and Influxdb on the Raspberry Pi, we need to create a grok log parser configuration. Telegraf will use this configuration to parse our log file on regular intervals and push the data into Influxdb.  As an added bonus, we can also monitor the CPU usage and disk usage on the Raspberry PI using telegraf and grafana without much effort.
In telegraf, we define inputs and outputs. As the name suggests, telegraf reads data from the provided inputs, processes them and finally pushes the data to the outputs.
Create a file named temperatureLog.conf with the following content. 

[agent]
   # Batch size of values that Telegraf sends to output plugins.
   metric_batch_size = 1000
   # Default data collection interval for inputs.
   interval = "30s"
   # Added degree of randomness in the collection interval.
   collection_jitter = "5s"
   # Send output every 5 seconds
   flush_interval = "5s"
   # Buffer size for failed writes.
   metric_buffer_limit = 10000
   # Run in quiet mode, i.e don't display anything on the console.
   quiet = true

# Read metrics about cpu usage
[[inputs.cpu]]
   ## Whether to report per-cpu stats or not
   percpu = false
   ## Whether to report total system cpu stats or not
   totalcpu = true
   ## If true, collect raw CPU time metrics.
   collect_cpu_time = false
   ## If true, compute and report the sum of all non-idle CPU states.
   report_active = false

[[inputs.logparser]]
   ## file(s) to read:
   files = ["/path/to/temperature.log"]

   # Only send these fields to the output plugins
   fieldpass = ["temperature", "humidity", "timestamp"]
   tagexclude = ["path"]

   # Read the file from beginning on telegraf startup.
   from_beginning = true
   name_override = "room_temperature_humidity"

   ## For parsing logstash-style "grok" patterns:
   [inputs.logparser.grok]
     patterns = ["%{TEMPERATURE_HUMIDITY_PATTERN}"]
     custom_patterns = '''
       TEMPERATURE_HUMIDITY_PATTERN %{NUMBER:timestamp:ts-epoch} Temp=%{NUMBER:temperature:float} %{GREEDYDATA}=%{NUMBER:humidity:float}%{GREEDYDATA}
     '''
     timezone = "Asia/Kolkata"

[[outputs.influxdb]]
   ## The full HTTP or UDP URL for your InfluxDB instance.
   urls = ["http://127.0.0.1:8086"] # required

   ## The target database for metrics (telegraf will create it if not exists).
   database = "temperature" # required

   ## Name of existing retention policy to write to.  Empty string writes to
   ## the default retention policy.
   retention_policy = ""
   ## Write consistency (clusters only), can be: "any", "one", "quorum", "all"
   write_consistency = "any"

   ## Write timeout (for the InfluxDB client), formatted as a string.
   ## If not provided, will default to 5s. 0s means no timeout (not recommended).
   timeout = "10s"
   # username = "telegraf"
   # password = "metricsmetricsmetricsmetrics"
   ## Set the user agent for HTTP POSTs (can be useful for log differentiation)
   # user_agent = "telegraf"
   ## Set UDP payload size, defaults to InfluxDB UDP Client default (512 bytes)
   # udp_payload = 512

Command: telegraf --config temperatureLog.conf

After saving the file, run telegraf process in the background as well, using screen or nohup.

Installing Grafana and creating dashboards on the Raspberry Pi

echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list curl https://packages.grafana.com/gpg.key | sudo apt-key add -

sudo apt-get update
sudo apt-get install grafana
sudo service grafana-server start

This will start the grafana server and you can now access grafana on the default 3000 port. Just open up a browser and go to http://RASPBERRY_IP:3000/ and login using the default username and password — admin, admin.

Once you’ve logged into Grafana, add InfluxDb as the default data source and start creating dashboards.

Adding datasource in grafana on Raspberry Pi:

Click add data source in the Grafana admin panel on Raspberry Pi

Add influxDb Url, which will be http://localhost:8086 if you’re running influxDb locally. And add database name as temperature. Leave everything else to its default.

Adding InfluxDb details in Grafana

Create a new Grafana dashboard:

Add a new panel to the newly created dashboard and edit the query behind the panel datasource.

Add More Panels for a cool look

Final Look:

grafana-temperature-humidity-dashboard-raspberry-pi

This concludes this tutorial of setting up a Grafana dashboard for temperature and humidity using DHT22 am2302, Influxdb and telegraf. Comment if you have any thoughts of improving it or any doubts about the process.

Also, checkout how to setup a free Minecraft Server in the cloud or how to build a scalable Typescript-Nodejs application.