Een Raspberry Pi weerstation maken is makkelijk en leuk om te doen. Als voorbeeld gaan we aan de slag met sensors voor de temperatuur, luchtvochtigheid en luchtdruk. De data daarvan willen we in een grafiek weergeven die via het netwerk toegankelijk moet zijn. Daar gebruiken we het programma RRDtool voor.
Een Raspberry Pi als weerstation
Meestal wordt voor dit soort Raspberry Pi projects een mysql- of sqlite-database gebruikt om de data op te slaan. Dit wordt dan gecombineerd met een (betaalde) online service voor het het grafisch weergeven van de data en de toegankelijkheid via internet. Het aantal webservices dat dashboards voor allerhande gegevens aanbiedt, groeit door de IoT-hype. Je betaalt dan meestal ook nog voor een abonnement. Voorbeelden zijn plot.ly, pubnub.com, initialstate.com, iot-dashboard.org en adafruit.io. We willen echter niet afhankelijk zijn van een externe service die er op een onbewaakt moment wellicht mee ophoudt of de bijbehorende API plotseling verandert. Daarom hebben we RRDtool van Tobi Oetiker gebruikt. Dat is een database en grafische tool ineen.
RRDtool was oorspronkelijk bedoeld voor het in beeld brengen van netwerksnelheden, processor- en harddisktemperaturen, cpu-belasting et cetera. Maar hij is ook zeer bruikbaar voor allerhande andere datastreams. Het werken met RRDtool verloopt in drie stappen, we komen daar straks op terug.
Stap 1: hardware aansluiten op de Raspberry Pi
Het uitgangspunt is een simpele Raspberry Pi met geïnstalleerde Raspbian Lite en een netwerkverbinding. Eerst sluit je de hardware aan.
Ontvang gratis info en tips voor aansluiten van apparatuur op de Raspberry Pi, schrijf je in voor de nieuwsbrief:
De DHT22 alias AM2302 (een andere naam voor hetzelfde beestje) is een temperatuur- en luchtvochtigheidssensor die erg simpel op de Raspberry Pi is aan te sluiten. Dat kan met een (mini)breadboard of rechtstreeks als je de bijbehorende 4,7kΩ-weerstand aan de pootjes vastsoldeert.
Vervolgens kopiëren we de bestanden van Adafruit voor de DHT22 van GitHub:
git clone https://github.com/adafruit/Adafruit_Python_DHT.git
Nu kun je de aangesloten sensor bij wijze van test rechtstreeks uitlezen met het voorbeeld Python-script van Adafruit:
python /home/pi/Adafruit_Python_DHT/examples/AdafruitDHT.py 2302 4
Dit levert als output bijvoorbeeld op
Temp=19.6* Humidity=50.4%
De sensor levert geen continue datastream, zoals bij analoge temperatuursensors wek het geval is, maar steeds een losse waarde als het Python-script daar om vraagt. Het script heeft twee parameters nodig: de code voor de sensor (2302) en het GPIO-nummer (4) van de pin op de Pi (fysieke pin 7) waar de datalijn op aangesloten is. De output Temp=17.9* Humidity=38.8% geeft meteen beide waarden voor temperatuur en luchtvochtigheid.
Raspberry Pi als weerstation: temperatuur en luchtvochtigheid
Voor onze weerstation-toepassing willen we de twee waarden ieder apart in een variabele opslaan. Kopieer daarom het originele script naar twee andere scripts (AdaAMtemp.py en AdaAMhumid.py) en verwijder uit de eerste kopie de code voor de ‘humidity’ en uit de tweede kopie de code voor de ‘temperature’.
De twee aparte scripts leveren dan alleen de waarde van de temperatuur en de vochtigheid met respectievelijk print(‘{0:0.1f}’.format(temperature)) en print(‘{1:0.1f}’.format(humidity)). Je krijgt dan 19.6 en 50.4 als resultaat. Dit gebruiken we in het uiteindelijke bash-script bij stap 2.
Voor de BMP183 doe je hetzelfde, maar daar gebruik je alleen de luchtdruksensor van. Het aangepaste Python-script noem je pressure.py. Nu kun je aan de slag met de database.
Stap 2: database aanmaken voor Raspberry Pi als weerstation
De database is een zogeheten round-robin database (RRD). In een normale database de data continu toegevoegd, waardoor die blijft groeien. Maar bij een round-robin of circulaire database geef je van tevoren een vaste omvang op. Die ruimte zal hij op de schijf innemen en niet meer dan dat. In het begin zal hij gevuld zijn met dummy data (‘NAN’, not a number), maar gaandeweg worden de oudste gegevens weggegooid om plaats te maken voor de nieuwe. Het installeren is simpel:
sudo apt-get update
sudo apt-get install rrdtool
Daarna staat de software in /usr/bin/rrdtool/. In totaal heb je maar drie commando’s nodig: een om de database aan te maken, een om de database te vullen en een om de data in een grafiek te zetten. Het aanmaken van de database doe je vanuit de home-directory van gebruiker pi met het volgende commando:
/usr/bin/rrdtool create pimeteo.rrd –start N –step 300 \
DS:temp:GAUGE:600:U:U \
DS:humid:GAUGE:600:U:U \
DS:press:GAUGE:600:U:U \
RRA:AVERAGE:0.5:1:288 \
Dat commando kun je voor het gemak in een bashscript zetten (create_pimeteo_rrd.sh). Dat maak je uitvoerbaar met chmod +x en kun je dan later starten met ./create_pimeteo_rrd.sh.
Database-content aanmaken voor Raspberry Pi als weerstation
Met het bovenstaande commando wordt een database aangemaakt met de naam pimeteo. Je moet altijd een startpunt (–start) voor de database opgeven, normaal gesproken het aantal seconden sinds Epoch (01-01-1970). Maar je kunt ook N (now) gebruiken voor het huidige tijdstip. Met –step geef je in seconden aan met welk maximum interval de database nieuwe data kan verwachten. In dit geval is dat om de vijf minuten.
Daarna volgen achter DS (data source) de namen waaronder ze in de database terecht moeten komen, het datasource-type (hier: GAUGE, oftewel absolute data die door RRDtool niet veranderd moeten worden) en de heartbeat (de time-outtijd in seconden). Wanneer er binnen dit interval geen data worden aangeleverd, verschijnt er NAN in de database – en dus een lege plek in de grafiek. Als laatste wordt de datarange gedefinieerd (de te verwachten minimum en maximum waarden). Die zetten we voor het gemak op U (undefined).
RRA staat voor Round Robin Archive. Daarmee bepalen we hoeveel data we opslaan en voor hoelang. AVERAGE betekent dat alleen de gemiddelde waarde (als er meerdere waarden zijn) bewaard moet worden. Met 288 geef je het aantal stappen aan dat bij die berekening meegenomen moet worden. In dit geval betekent dat 288 x 300 = 86400 seconden (1 dag).
Stap 3: database vullen
Om de database met data te vullen, zet je onderstaande commando’s weer in een bash-script (update_pimeteo_ rrd.sh). Eerst worden drie variabelen met de output van de sensors gevuld:
temperature=$(python /home/pi/Adafruit_Python_DHT/examples/AdaAMtemp.py 2302 4)
humidity=$(python /home/pi/Adafruit_Python_DHT/examples/AdaAMhumid.py 2302 4)
pressure=$(python /home/pi/bmp183-master/pressure.py)
Vervolgens worden die aan de database toegevoegd:
/usr/bin/rrdtool update pimeteo.rrd -t temp:humid:press N:$temperature:$humidity:$pressure
Daarbij worden de drie datasources temp, humid en press gevuld met de inhoud van de drie betreffende variabelen en voorzien van het tijdstempel N (now). De switch -t is niet per se nodig, maar maakt wel duidelijker wat er gebeurt.
Stap 4: grafisch weergeven
Aangezien de data in een grafiek via een browser te bekijken moet zijn, moet je tussendoor nog een webserver installeren:
sudo apt-get install apache2 -y
Als er genoeg data in de database zitten, kun je een grafiek maken. Met /usr/bin/rrdtool dump pimeteo.rrd kun je zien welke gegevens er in de database staan. Het commando voor het genereren van de grafiek zet je in het derde bash-script (create_pimeteo_graph.sh). De output wordt dan een afbeelding in png-formaat van 700 × 400 pixels. Daarbij geven we ook de titel en het opschrift van de Y-as op:
/usr/bin/rrdtool graph pimeteo.png –width 700 –height 400 \
–title=”Luchtdruk, luchtvochtigheid en temperatuur van laatste 24 uur” \
–vertical-label=”Temp.(C)<->Luchtvochtigh. (perc.)<->Luchtdruk (hPa/16)” \
DEF:temp=/home/pi/pimeteo.rrd:temp:AVERAGE \
DEF:humid=/home/pi/pimeteo.rrd:humid:AVERAGE \
DEF:press=/home/pi/pimeteo.rrd:press:AVERAGE \
Alles in één grafiek
Daarna wordt bepaald welke data in de grafiek getoond worden. Het feit dat je in dezelfde grafiek geen tweede schaal kunt toevoegen, is voor de luchtdruk een probleem. De temperatuur en luchtvochtigheid passen samen mooi in een schaal van 0 tot 100, maar de luchtdruk in hectoPascal gaat daar met een factor van minstens 10 overheen. Om die lijn niet in een aparte grafiek te hoeven zetten, pas je een trucje toe:
CDEF:press2=press,16,/
Daarmee maak je virtual name (VN), press2, aan die de waarde van de DS press bevat, maar dan gedeeld door 16. Dat staat in de reverse polish notation (RPN), dus eerst de operanden en dan de operator. Vervolgens bepaal je de grafieklijnen, hun kleur (hexadecimaal) en naam:
LINE1:press2#5fd00b:Luchtdruk \
LINE1:humid#0000ff:Luchtvochtigheid \
LINE1:temp#ff0000:Temperatuur \
Die staan in de volgorde waarin ze later in de grafiek verschijnen van boven naar beneden. Voor de luchtdruk gebruik je nu de gemodificeerde waarde van press2. Het getal achter LINE bepaalt de dikte van de lijn (van 1 tot 3).
Legenda
De legenda met de kleurcode wordt automatisch onder de grafiek gezet. Na twee commentaarregels om een nieuwe regel te beginnen, kun je met GPRINT de belangrijkste cijfers onder de grafiek uitlichten. In dit geval laten we de laatste, de hoogste en de laagste waarde van iedere sensor van de laatste 24 uur zien. Hieronder het commandodeel voor de luchtdruk.
De uitgelichte cijfers voor de temperatuur en de vochtigheid kun je naar analogie hiervan zelf programmeren; met telkens twee van de speciale commentaarregels om ze onder elkaar te zetten. Voor de luchtdruk wordt nu wel de echte press met de originele (hogere) waarden gebruikt om onder de tabel in ieder geval de belangrijkste luchtdrukcijfers in hun echte hPa-waarden te krijgen. Bij %2.1lf staat eerst een 1 en dan de letters l en f.
COMMENT:”\t\t\t\t\t\t\l” \
COMMENT:”\t\t\t\t\t\t\l” \
GPRINT:press:LAST:”Luchtdruk Laatste\: %2.1lf” \
GPRINT:press:MAX:”Max.\: %2.1lf” \
GPRINT:press:MIN:”Min.\: %2.1lf” \
Daarna moet de png-afbeelding van de grafiek nog naar de juiste directory van de webserver gekopieerd worden:
cp /home/pi/pimeteo.png /var/www/html
In die directory staat al een index-bestand van Apache. Dat kun je verwijderen en vervangen door een index. html of index.php met het plaatje van de grafiek. Bijvoorbeeld:
<!DOCTYPE html>
<html>
<body>
<h1>PiMeteo</h1>
<p>Woonkamer</>
<img src=”pimeteo.png”>
</body>
</html>
Stap 5: automatiseren met cron
De bash-scripts update_pimeteo_rrd.sh en create_pimeteo_ graph.sh moeten regelmatig herhaald worden om de database te vullen en de grafiek te updaten. Dat kan heel makkelijk met twee cron-jobs. Open de editor met crontab -e en voeg deze twee regels toe:
*/5 * * * * python /home/pi/update_pimeteo_rrd.sh
*/15 * * * * python /home/pi/create_graph.sh
De eerste zet het updaten van de database iedere vijf minuten in gang. De tweede zorgt ervoor dat er iedere vijftien minuten een nieuwe grafiek voor de webpagina klaarstaat.
Stap 6: extra’s toevoegen aan de Raspberry Pi weerstation
Dit is nog maar een eerste eenvoudige kennismaking met RRDtool. Je kunt natuurlijk meer temperatuursensors voor binnen of buiten toevoegen, de webpagina mooier maken en eventueel een weerfoto van een webcam toevoegen. Je kunt de webpagina bovendien nog beveiligen met een of andere vorm van login. RRDtool biedt nog veel meer mogelijkheden.
Op de website van RDDtool staat een uitgebreide documentatie inclusief veel voorbeelden van grafieken en toepassingen. De volledige scripts uit dit artikel kun je als zip-bestand downloaden van onze website.