One of the most popular projects besides home automation and robots is the Raspberry Pi weather station. This can be used in both indoor and outdoor circumstances and can be expanded as required. We either display the data from other devices via a web interface or use the Raspberry Pi touchscreen.
In this tutorial, we will create a functional and expandable weather station that can be called up and controlled using a touchscreen.
Required Hardware Parts For the Raspberry Pi Weather Station
You will need the following hardware parts for the weather station. Individual components can of course also be omitted or added. However, the code must then also be adjusted accordingly.
- Raspberry Pi including a micro SD card and USB power plug
- alternatively: Raspberry Pi Starter Kit or Sensor Kit (already contains the most important sensors and a display)
- DHT22 sensor for temperature & humidity
- BMP180 air pressure sensor
- Raspberry Pi Touchscreen
- alternative: LCD Display
- Jumper Cable
- Breadboard
In addition, other sensors such as gas sensors, brightness sensors or wind strength sensors are also an option which can be integrated.
Another option is to use an ESP8266 NodeMCU or Raspberry Pi Zero W as an outpost for the weather station. The display on an LCD is not explicitly dealt with in this tutorial. How to display data on it is explained in more detail in a previous tutorial and can be adjusted if necessary.
Construction & Wiring
Let’s start with the wiring of all modules. The easiest way is with the official Raspberry Pi touchscreen. This can be connected to the DSI port of the Raspberry Pi using the ribbon cable. It gets power either via the 5V pin or via USB connection. A detailed description can be found here.
Then the sensors are on. These were also discussed in more detail in previous tutorials, but here is the structure again:
The DHT11 sensor is connected to 3.3V and GND as shown in the picture. Now the data pin goes to GPIO23 and at the same time to 3.3V via a 10k Ω resistor.
The BMP180 is only connected to the I2C bus and also gets a connection to 3.3V and GND.
Preparation: Installing OpenHAB & packages
We use OpenHAB as the interface, which is generally a very good introduction to home automation. Since it offers different graphical interfaces, it is not necessary that we create our own GUI. We can customize these later.
Therefore, we start to install OpenHAB 2 on the Raspberry Pi. When this is complete, we open http://openhabianpi:8080/paperui/index.html#/extensions and look for the “Exec Binding” package under “Binding”, the “RRD4j Persistence” package under the “Persistence” tabs and under “Transformations” “the” RegEx Transformation “package. All are installed.
Now we log in via SSH and install the required packages for the DHT and BMP180 sensors:
sudo apt-get update sudo apt-get install build-essential python-dev python3-dev python3-openssl python3-smbus python3-pip i2c-tools git git clone https://github.com/adafruit/Adafruit_Python_DHT.git && cd Adafruit_Python_DHT sudo python3 setup.py install cd .. git clone https://github.com/adafruit/Adafruit_Python_BMP && cd Adafruit_Python_BMP sudo python3 setup.py install
If you want to use Python2 instead of Python3, you have to adapt the packages and installation calls accordingly.
Then we have to activate I2C:
sudo raspi-config
We activate it under “Interface Options” -> “I2C” (this can vary from the Raspbian version, but is always included in the raspi-config).
If the BMP sensor is already connected, we can test whether it has already been recognized:
i2cdetect -y 1
The result should look like this:
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- 77
Setting Up the Raspberry Pi Weather Station
The functions that we will use need tools that deliver the data to us. The easiest way to do this is with Python, for which there are many libraries (including those that we have already used and installed). So we start with the main script::
sudo nano /etc/openhab2/scripts/weatherstation.py
It gets the following content:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import Adafruit_BMP.BMP085 as BMP085 import Adafruit_DHT import sys, time # constants DHT_PIN = 23 # GPIO nr DHT_SENSOR = Adafruit_DHT.DHT22 if __name__ == '__main__': if len(sys.argv) > 1: call = sys.argv[1].lower() if call == 'temperature': temperature = None while temperature == None: _, temperature = Adafruit_DHT.read_retry(DHT_SENSOR, DHT_PIN) if temperature == None: time.sleep(1.5) print(temperature) elif call == 'humidity': humidity = None while humidity == None: humidity, _ = Adafruit_DHT.read_retry(DHT_SENSOR, DHT_PIN) if humidity == None: time.sleep(1.5) print(humidity) elif call == 'pressure': sensor = BMP085.BMP085() print(sensor.read_pressure() / 100.0) |
Save with CTRL + O and return to the shell with CTRL + X (in the next steps as well).
We also have to give this script and the I2C module admin permissions, which we need for the GPIO calls:
sudo chmod +x /etc/openhab2/scripts/weatherstation.py sudo chmod a+rw /dev/i2c-*
To ensure that the rights for I2C are set permanently, we have it executed every time you reboot. This is done via Crontab:
sudo crontab -e
If you have not yet set up an editor, select 2. nano. Now add the following line at the end and save the file:
@reboot sudo chmod a+rw /dev/i2c-*
Now it goes on with the things: For each value (temperature, humidity, air pressure, etc.) we have to create a thing. For this we use the previously installed Exec Add-On, with which we can start shell calls. For the storage we also need “RRD4j Persistence” (under Add-ons -> Persistence). Our Python script takes various parameters and returns corresponding values. We use this:
sudo nano /etc/openhab2/things/weatherstation.things
1 2 3 4 5 |
Thing exec:command:weatherstation_temperature "Temperatur" [command="/etc/openhab2/scripts/weatherstation.py temperature", transform="REGEX((.*?))", interval=60, timeout=10, autorun=true] Thing exec:command:weatherstation_humidity "Luftfeuchtigkeit" [command="/etc/openhab2/scripts/weatherstation.py humidity", transform="REGEX((.*?))", interval=10, timeout=10, autorun=true] Thing exec:command:weatherstation_pressure "Luftdruck" [command="/etc/openhab2/scripts/weatherstation.py pressure", transform="REGEX((.*?))", interval=60, timeout=10, autorun=true] |
Next, our items come into play:
sudo nano /etc/openhab2/items/weatherstation.items
1 2 3 4 5 6 7 8 9 10 11 12 |
Group Weatherstation_Chart (System, Charts) Number Weatherstation_Chart_Period "Periode" (System) Number Weatherstation_Temperature "Temperatur [%.1f °C]" <temperature> (Weatherstation_Chart) Number Weatherstation_Humidity "Luftfeuchtigkeit [%.1f %%]" <humidity> (Weatherstation_Chart) Number Weatherstation_Pressure "Luftdruck [%.1f hPa]" <pressure> (Weatherstation_Chart) String temperature_out { channel="exec:command:weatherstation_temperature:output" } String humidity_out { channel="exec:command:weatherstation_humidity:output" } String pressure_out { channel="exec:command:weatherstation_pressure:output" } |
In order for the data to be stored permanently (every minute) in the database, we have to indicate this by writing it to a .persist file:
sudo nano /etc/openhab2/persistence/rrd4j.persist
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Strategies { // for rrd charts, we need a cron strategy, every Minute is a must have. everyMinute : "0 * * * * ?" // get the data reduced for older values to keep database small everyHour : "0 0 * * * ?" everyDay : "0 0 0 * * ?" default = everyChange } Items { // additionally persist Items Weatherstation_Chart* : strategy = everyUpdate, everyMinute } |
So far we have created two items each. One as a text value from the script and the other as a numerical value, which we can change if necessary. This works with rules:
sudo nano /etc/openhab2/rules/weatherstation.rules
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
rule "Weatherstation Temperature" when Item temperature_out received update then Weatherstation_Temperature.postUpdate( ( ( Float::parseFloat(temperature_out.state.toString) as Number ) * 10 ) / 10 ) end rule "Weatherstation Humidity" when Item humidity_out received update then Weatherstation_Humidity.postUpdate( ( ( Float::parseFloat(humidity_out.state.toString) as Number ) * 10 ) / 10 ) end rule "Weatherstation Pressure" when Item pressure_out received update then Weatherstation_Pressure.postUpdate( ( ( Float::parseFloat(pressure_out.state.toString) as Number ) * 10 ) / 10 ) end |
A change via regex values and debug logging is also possible here. In general, other events can be triggered here – for example, that if the temperature becomes over 30 degrees, the fan (if connected) turns on. If you are interested, we can go through and explain such scenarios in future tutorials.
Now we create a nicer view. However, this is not visible with the PaperUI, so we have to use it in the BasicUI:
http://openhabianpi:8080/basicui/app
For this we create a sitemap in which the previous items can be inserted:
sudo nano /etc/openhab2/sitemaps/weatherstation.sitemap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// Name of file and name of sitemap has to be the same sitemap weatherstation label="Raspberry Pi Wetterstation" { Frame label="Innentemperatur" { Text item=Weatherstation_Temperature Text item=Weatherstation_Humidity Text item=Weatherstation_Pressure } Frame { Switch item=Weatherstation_Chart_Period mappings=[0="1h", 1="4h", 2="8h", 3="12h", 4="24h"] Chart item=Weatherstation_Chart period=h refresh=60000 visibility=[Weatherstation_Chart_Period==0, Weatherstation_Chart_Period=="Uninitialized"] Chart item=Weatherstation_Chart period=4h refresh=60000 visibility=[Weatherstation_Chart_Period==1] Chart item=Weatherstation_Chart period=8h refresh=60000 visibility=[Weatherstation_Chart_Period==2] Chart item=Weatherstation_Chart period=12h refresh=60000 visibility=[Weatherstation_Chart_Period==3] Chart item=Weatherstation_Chart period=D refresh=60000 visibility=[Weatherstation_Chart_Period==4] } } |
Then update the BasicUI page and select the sitemap “Waiter station”. Here all values and the previous values are now displayed in a table. Since the values are quite different (air pressure ~ 1000 [hPa], temperature 0-30 [° C], air humidity ~ 20-70 [%]), we can also create different graphs/charts or, for example, the unit instead of hPa Use bar.
In addition, we could of course also measure the temperature with the BMP180. He can also measure the height (in meters) and the sea level pressure. With the given examples it should be a breeze to expand the files if necessary.
If contrary to expectations, something does not work as it should, a look at the logs often helps. How you can access it is explained in this article (e.g. via Karaf console).
Addition: Setting up the Weather forecast via Yahoo!
Our Raspberry Pi weather station should get an additional feature: In addition to the currently measured data, we also want to make predictions for the next day. This feature is optimal, but it does make a difference. We can choose between different providers like Forecast.io, OpenWeatherMap, Yahoo! and much more. Depending on the location, some are more accurate or better suited. Since you need an API key everywhere except for the forecasts from Yahoo, we use this service for the sake of simplicity. Of course, it can also be replaced by another one.
For this, we use the OpenHAB weather binding. Go to “Add-Ons” -> “Bindings” in the PaperUI and install the “Weather Binding”.
We also need a so-called WOEID. You can get the required WOEID number for your city on this website. Find your location and copy the number.
Now we create a configuration file:
sudo nano /etc/openhab2/services/weather.cfg
The following content comes in:
1 2 3 4 |
location.home.woeid=547826 location.home.provider=Yahoo location.home.language=eng location.home.updateInterval=60 |
Now we have to create corresponding items. To do this, we edit the previously created Things file and add the following lines (forecast = 1 indicates that the values are retrieved for the next day, 2 for the day after next, etc.). We can also create different locations in the configuration file (we only define “home”) and then create items for different locations:
1 2 |
Number Forecast_Temp_Min "Temperatur min [%.2f °C]" <temperature> {weather="locationId=home, forecast=1, type=temperature, property=min"} Number Forecast_Temp_Max "Temperatur max [%.2f °C]" <temperature> {weather="locationId=home, forecast=1, type=temperature, property=max"} |
The sitemap also needs to be adjusted:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// Name of file and name of sitemap has to be the same sitemap weatherstation label="Raspberry Pi Wetterstation" { Frame label="Innentemperatur" { Text item=Weatherstation_Temperature Text item=Weatherstation_Humidity Text item=Weatherstation_Pressure } Frame label="Vorhersage in 24h" { Text item=Forecast_Temp_Min Text item=Forecast_Temp_Max } Frame { Switch item=Weatherstation_Chart_Period mappings=[0="1h", 1="4h", 2="8h", 3="12h", 4="24h"] Chart item=Weatherstation_Chart period=h refresh=60000 visibility=[Weatherstation_Chart_Period==0, Weatherstation_Chart_Period=="Uninitialized"] Chart item=Weatherstation_Chart period=4h refresh=60000 visibility=[Weatherstation_Chart_Period==1] Chart item=Weatherstation_Chart period=8h refresh=60000 visibility=[Weatherstation_Chart_Period==2] Chart item=Weatherstation_Chart period=12h refresh=60000 visibility=[Weatherstation_Chart_Period==3] Chart item=Weatherstation_Chart period=D refresh=60000 visibility=[Weatherstation_Chart_Period==4] } } |
No other files need to be adjusted because we don’t want to save predictions. If you want to use other icons in the sitemap, you can either upload your own or use the standard icons.
In order to be able to use the entire range of values (wind, clouds, precipitation, snow, perceived outside temperature, fog/visibility, etc.), you can take a look at the other examples.
Show Raspberry Pi Weather Station Data on the Touchscreen
Before we start with the installation, the display must be connected and supplied with power.
Since openHAB is based on Raspbian Lite, it has no graphical user interface. To automatically display the web panel on the touchscreen, we first have to install it. We choose the PIXEL surface and the Chromium browser. The installation runs via SSH.
sudo apt-get install --no-install-recommends xserver-xorg --yes sudo apt-get install --no-install-recommends xinit --yes sudo apt-get install raspberrypi-ui-mods --yes sudo apt-get install chromium-browser --yes
We first activate automatic login to the desktop:
sudo raspi-config
Under “Boot Options” -> “Desktop / CLI” -> “Desktop”.
Now we set the automatic login in the GUI:
sudo nano /etc/lightdm/lightdm.conf
We are looking for the line “# autologin-user =” (search is easy with CTRL + W) and remove the diamond at the beginning and set the user “openhabian” at the end so that it looks like this:
autologin-user=openhabian
Save with CTRL + O and go back to the console with CTRL + X.
Now we make sure that the browser with the corresponding page also starts
sudo nano /home/openhabian/.config/lxsession/LXDE-pi/autostart
The following line comes at the very end of the file.
@xset s noblank @xset s off @xset -dpms @sudo chmod a+rw /dev/i2c-* @/usr/bin/chromium-browser --kiosk --disable-restore-session-state http://http://openhabianpi:8080/basicui/app?sitemap=weatherstation
We also have to edit another file:
sudo nano /etc/kbd/config
Here the values of the following two entries change to zero:
BLANK_TIME=0 POWERDOWN_TIME=0
After saving, we restart the Raspberry Pi:
sudo reboot
Now the browser is started, but it takes a moment until OpenHAB is started and the panel becomes visible.
4 Comments
i’ve used dht22’s for a couple of years and although they are ok for €4/5 a pop, the humidity side is so unreliable that i’m exclusively using htu21d-f’s now on anything i need to work 24/7 (though i appreciate they are more expensive – but i guess you get what you pay for 🙂 )
Agreed. I’m working on a project where I need to be able to scale from 1 to 10 humidity/temp sensors. The DHT22/AM2302 has a wild variance in accuracy from sensor to sensor. Using a known 75% RH sealed environment, I get values ranging from 60%RH to 80% RH. That said, when I find a good sensor it is very accurate. Lifespan sucks, at least for me. I’m looking at other options and debating on I2C or SPI for comms. Neither is particularly attractive. I really wish chip manufacturers would add user-set I2C addresses. It would greatly simplify my life.
How’s the accuracy and lifespan so far with the HTU sensors? I’ve been leaning towards the SHT3X chips but I’m open to anything. Thanks in advance.
a full schematic view of all the parts and connections should be nice !
Hey, this is a great tutorial, however for some reason, following as many of the steps I could, I cannot get it to show temps, I CAN read the sensors manually referring to other documents, do you know if OpenHab2 has had some updates that break things?
Or maybe I missed a step?
I did install the 3 add-ons I found, I would love to see more instructions on this as I am trying build a therostat replacement for my current Nest Thermostat.
I would love to send in a picture of what I have created from your instructions.