Visualize Weather Data With Grafana and the DHT22 Sensor
In this tutorial, we will connect the DHT22 sensor to the Raspberry Pi Zero via the GPIO pins to measure temperature and humidity and visualize it with Grafana.
$ cat flask_temps.py
#!/usr/bin/env python3
import Adafruit_DHT as dht_sensor
import time
from flask import Flask, Response
from prometheus_client import Counter, Gauge, start_http_server, generate_latest
import requests
params = {"lat": "-xx.xxxxx", "lon": "xx.xxxx", "units": "metric", "appid": "your-api-key"}
baseurl = "https://api.openweathermap.org/data/2.5/weather"
content_type = str('text/plain; version=0.0.4; charset=utf-8')
def get_temperature_readings():
humidity, temperature = dht_sensor.read_retry(dht_sensor.DHT22, 4)
humidity = format(humidity, ".2f")
temperature = format(temperature, ".2f")
outside_temp = get_outside_weather()
if all(v is not None for v in [humidity, temperature, outside_temp]):
response = {"temperature": temperature, "humidity": humidity, "outside_temp": outside_temp}
return response
else:
time.sleep(0.2)
humidity, temperature = dht_sensor.read_retry(dht_sensor.DHT22, 4)
humidity = format(humidity, ".2f")
temperature = format(temperature, ".2f")
outside_temp = get_outside_weather()
response = {"temperature": temperature, "humidity": humidity, "outside_temp": outside_temp}
return response
def get_outside_weather():
response = requests.get(baseurl, params=params)
temp = response.json()['main']['temp']
return temp
app = Flask(__name__)
current_humidity = Gauge(
'current_humidity',
'the current humidity percentage, this is a gauge as the value can increase or decrease',
['room']
)
current_temperature = Gauge(
'current_temperature',
'the current temperature in celsius, this is a gauge as the value can increase or decrease',
['room']
)
current_temperature_outside = Gauge(
'current_temperature_outside',
'the current outside temperature in celsius, this is a gauge as the value can increase or decrease',
['location']
)
@app.route('/metrics')
def metrics():
metrics = get_temperature_readings()
current_humidity.labels('study').set(metrics['humidity'])
current_temperature.labels('study').set(metrics['temperature'])
current_temperature_outside.labels('za_ct').set(metrics['outside_temp'])
return Response(generate_latest(), mimetype=content_type)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Then install the flask and prometheus_client package:
$ curl http://localhost:5000/metrics
# HELP python_gc_objects_collected_total Objects collected during gc
# TYPE python_gc_objects_collected_total counter
python_gc_objects_collected_total{generation="0"} 646.0
python_gc_objects_collected_total{generation="1"} 129.0
python_gc_objects_collected_total{generation="2"} 0.0
# HELP python_gc_objects_uncollectable_total Uncollectable object found during GC
# TYPE python_gc_objects_uncollectable_total counter
python_gc_objects_uncollectable_total{generation="0"} 0.0
python_gc_objects_uncollectable_total{generation="1"} 0.0
python_gc_objects_uncollectable_total{generation="2"} 0.0
# HELP python_gc_collections_total Number of times this generation was collected
# TYPE python_gc_collections_total counter
python_gc_collections_total{generation="0"} 104.0
python_gc_collections_total{generation="1"} 9.0
python_gc_collections_total{generation="2"} 0.0
# HELP python_info Python platform information
# TYPE python_info gauge
python_info{implementation="CPython",major="3",minor="7",patchlevel="3",version="3.7.3"} 1.0
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 4.4761088e+07
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 2.7267072e+07
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1.61044381853e+09
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 5.86
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 6.0
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
process_max_fds 1024.0
# HELP current_humidity the current humidity percentage, this is a gauge as the value can increase or decrease
# TYPE current_humidity gauge
current_humidity{room="study"} 47.0
# HELP current_temperature the current temperature in celsius, this is a gauge as the value can increase or decrease
# TYPE current_temperature gauge
current_temperature{room="study"} 25.7
# HELP current_temperature_outside the current outside temperature in celsius, this is a gauge as the value can increase or decrease
# TYPE current_temperature_outside gauge
current_temperature_outside{location="za_ct"} 27.97
Now to configure our prometheus scrape config to scrape our endpoint:
We will be adding a new panel with a graph visualization, and from our prometheus datasource, we will be referencing the 2 metrics (different from the screenshot):