home-assistant-config
home-assistant-config copied to clipboard
Building an IoT weather station
Objective
I've wanted a weather station since I can remember and whilst we have been locked up socially distancing during the COVID-19 pandemic I decided to make this a reality. This was mainly driven by the amazing weather, blue skies, and clean air. The idea being I could use this unique moment to capture a dataset and compare it against whatever normal is when we return to living our lives after the pandemic. I've often looked at the different types of weather stations available on the market and always been drawn to the Bresser weather centre for the design and build quality. The Bresser looks to have a solid frame and isn't unpleasant to the eye. compared to some on the market.
Not stopping there I wanted to make the data digitally available for me to access as I liked. Through integrating the data with Home Assistant I can drive all kinds of automation and integration with other products. Over and above the typical data that weather stations capture, I want to include other weather-related sensors such as air quality (co2, no2, 2.5PM, and 10PM etc) and a lightning sensor and learn more about the weather and environment quality where I live.
- [x] Sniff 838mHz data from the weather station using RTL_433
- [x] Send the data over to Home Assistant via MQTT
- [x] Include an air pressure sensor
- [ ] Integrate air quality PM, VOC, NO₂ and CO₂ sensors (including 3D printed Stevenson screen and fixings)
- [ ] Research building RTL_433 on ESPHome on an ESP32 board
- [ ] Add additional weather and environmental sensors
- [x] Rain wet sensor #22
- [ ] Indoor display
- [ ] Stevenson screen
Ingredients
- Bresser 5-in-1 weather station
- 868mHz software-defined radio receiver
- Raspberry Pi or ESP32 for hosting the radio receiver
- MQTT broker
Here is the Bresser weather station after it arrived and it mounted in the garden shortly afterward.
Fortunately, there is a framework call RTL_433 available on GitHub which allows you to easily receive the data from some 150+ devices. Unlike the name, the framework works on 433, 868, 315, 345, and 915 MHz bands. Luckily my device was already part of their supported device protocols. The device code for my weather station is. I followed their build instructions.
[119] Bresser Weather Centre 5-in-1
I used this framework with a Raspberry Pi and an 868 MHz SDR receiver to test if I was able to receive data from my weather station. Luckily I was able to receive data without any problems at all. Next up is to send the data over to Home Assistant via MQTT. The longer-term plan is to try and get RTL_433 running on an ESP board and working with ESPHome if possible.
Here is RTL_433 running on a Raspberry Pi and receiving data from my weather station.
rtl_433 -f 868M -s 1024k -R 119
For MQTT test I used
rtl_433 -f 868M -s 1024k -F "mqtt://localhost:1883,user=USERNAME,pass=PASSWORD,retain=0,devices=rtl_433[/id]"
- [x] Wind direction offset.
You are expected to point the weather station North. In my view, this looks odd as it looks better parrel to the roofline rather than skewed. To mitigate this I plan to include an option to offset the wind direction to allow for this.
This is to help when installing outside.
My weather station is ~62 degrees off North.
As part of this project, I wanted to capture additional data so I created a list of sensors I wanted to consider adding to the weather station to provide me with valuable environmental data. Remember this was not just about having access to the basic data from my weather station, this project was for me to learn about the weather and have an interesting dataset to analyse over time.
Data/Issue | Sensor | Integration | Reasoning |
---|---|---|---|
Temperature, humidity and pressure #37 | BME680 Digital Temperature Humidity Pressure Sensor | ESPHome | |
Surface/ground temperature | Pyrometer | ||
Soil temperature (consider soil moisture) #39 | Dallas temperature probe Science Direct | ESPHome Instructables | |
Air temperature | Bresser built-in, BME680 and zigbee sensor | ||
Particulate Matter (2.5PM, 10PM) #34 | Laser PM2.5 Air Quality Sensor | Arduino sketch | |
Dew point #44 | Humidity and air temperature | Home Assistant Template sensor, Calculation | |
Air quality - VOC, CO₂ #36 | SGP30 Air Quality Sensor Breakout | ESPHome | |
Air quality - CO, NO₂, NH₃ #0 | MICS-4514 MICS-6814 | ||
Air quality - LPG, CO, Smoke #0 | MQ2 | ||
Air quality - Ozone #0 | MQ-131 | ||
Wind direction, speed and gusts (daily, weekly average etc) | Bresser 5-in-1 weather station | RTL_433 + MQTT | |
Rainfall | Bresser 5-in-1 weather station | RTL_433 + MQTT | |
Rain sensor #22 | Rain sensor | ESPHome | |
Lightning detector #42 | AS3935 I2C SPI Lightning Sensor | ESPHome | |
Visibility (Fog/mist/smoke) | Particle Photon | Definition Instructables | |
UV #43 | MP8511 UV Sensor | ESPHome | |
LUX #38 | BH1750 Photosensitive Resistance Sensor | ESPHome | |
Solar radiation (Pyranometer, solar irradiance) | |||
Environmental noise #40 | Omnidirectional Microphone Module I2S Interface INMP441 | Instructables Hackaday GitHub maspetsberger | |
Ceilometer Backscatter (cloud height) | Adafruit | ||
Terrestrial Radiation | |||
Weather/sky timelapse camera #41 | ESP32-CAM Camera | ESPHome | This would provide a live feed on-demand and take pictures for a day timelapse. It could also be configured to record if the data suggests a weather event is happening or object detection in the video. |
I plan to come back and add my reasoning about why I wanted to capture this data.
Yay. 🥳
RTL_433 is now supplying Home Assistant with data over MQTT. I still plan to look at running RTL_433 on an ESP board if possible but if this is not possible I might look at some alternatives to get the data over to Home Assistant from the Raspberry Pi it is currently running on. I just want to avoid my dependency on MQTT when other APIs exist.
Due to how I mounted my weather station it doesn't point North. Therefore my wind direction was skewed and doesn't report correctly. As highlighted above my North was 296° so I wanted to build something using Home Assistant to correct this but at the same time also create the wind direction as a heading rather than a value. For this, I chose to use the names from a 16-wind compass rose. What was nice was reaching the same solution others had created prior to finding such articles. 🤓
I took off to the trusted template editor available in Dev Tools to test some YAML for me to use in a number of new sensors.
Wind RAW from Weather Station: {{ states('sensor.wind_direction') }}°
{% set calibrate = 296 | int %}
Weather station mounted North at: {{ calibrate | int }}°
{% set adjusted = (states('sensor.wind_direction') | float(2) + calibrate) %}
Adjusted Wind (pre-calculation): {{ adjusted }}°
{% if adjusted > 360 %}{% set wind = adjusted - 360 %}{% elif adjusted < 0 %}{% set wind = 0 + adjusted %}{% else %}{% set wind = adjusted %}{% endif %}
Wind offset: {{ wind }}
{% if wind >= 348.75 or wind <= 11.25 %}
Wind heading: North (N)
{% elif wind >= 11.25 and wind <= 33.75 %}
Wind heading: North Northeast (NNE)
{% elif wind >= 33.75 and wind <= 56.25 %}
Wind heading: North East (NE)
{% elif wind >= 56.25 and wind <= 78.75 %}
Wind heading: East Northeast (ENE)
{% elif wind >= 78.75 and wind <= 101.25 %}
Wind heading: East (E)
{% elif wind >= 101.25 and wind <= 123.75 %}
Wind heading: East Southeast (ESE)
{% elif wind >= 123.75 and wind <= 146.25 %}
Wind heading: South East (SE)
{% elif wind >= 146.25 and wind <= 168.75 %}
Wind heading: South Southeast (SSE)
{% elif wind >= 168.75 and wind <= 191.25 %}
Wind heading: South (S)
{% elif wind >= 191.25 and wind <= 213.75 %}
Wind heading: South Southwest (SSW)
{% elif wind >= 213.75 and wind <= 236.25 %}
Wind heading: South West (SW)
{% elif wind >= 236.25 and wind <= 258.75 %}
Wind heading: West Southwest (WSW)
{% elif wind >= 258.75 and wind <= 281.25 %}
Wind heading: West (W)
{% elif wind >= 281.25 and wind <= 303.75 %}
Wind heading: West Northwest (WNW)
{% elif wind >= 303.75 and wind <= 326.25 %}
Wind heading: North West (NW)
{% elif wind >= 326.25 and wind <= 348.75 %}
Wind heading: North Northwest (NNW)
{% else %}
Wind heading: ?
{% endif %}
This provided me with the following data.
I created an input_number entity to store my offset value. This is the new North bearing of weather station.
input_number:
weather_station_wind_north_offset:
name: North Offset
min: 0
max: 360
step: 0.1
mode: box
unit_of_measurement: '°'
icon: mdi:compass
I then created a template sensor to convert the compass value to the 16-point wind direction.
sensor:
platform: template
sensors:
wind_bearing:
friendly_name_template: "Wind Direction"
value_template: >-
{% set wind = states('sensor.wind_direction_calibrated') | int %}
{% if wind >= 348.75 or wind <= 11.25 %}
North (N)
{% elif wind >= 11.25 and wind <= 33.75 %}
North Northeast (NNE)
{% elif wind >= 33.75 and wind <= 56.25 %}
North East (NE)
{% elif wind >= 56.25 and wind <= 78.75 %}
East Northeast (ENE)
{% elif wind >= 78.75 and wind <= 101.25 %}
East (E)
{% elif wind >= 101.25 and wind <= 123.75 %}
East Southeast (ESE)
{% elif wind >= 123.75 and wind <= 146.25 %}
South East (SE)
{% elif wind >= 146.25 and wind <= 168.75 %}
South Southeast (SSE)
{% elif wind >= 168.75 and wind <= 191.25 %}
South (S)
{% elif wind >= 191.25 and wind <= 213.75 %}
South Southwest (SSW)
{% elif wind >= 213.75 and wind <= 236.25 %}
South West (SW)
{% elif wind >= 236.25 and wind <= 258.75 %}
West Southwest (WSW)
{% elif wind >= 258.75 and wind <= 281.25 %}
West (W)
{% elif wind >= 281.25 and wind <= 303.75 %}
West Northwest (WNW)
{% elif wind >= 303.75 and wind <= 326.25 %}
North West (NW)
{% elif wind >= 326.25 and wind <= 348.75 %}
North Northwest (NNW)
{% else %}
?
{% endif %}
unit_of_measurement: '°'
Next up is creating this as a real-time graphic in Home Assistant.
Useful guidance I found during setting up these templates sensors.
Last night I tried to find images for my compass and needle. None lacked any quality or resolution. Also, whilst many exist few split the gauge and needle as layers so I use one that was available for free that I liked made by ShaneTurcotte.Murazik and took off in Photoshop to recreate it.
Using the CSS rotate feature I am easily able to rotate the need to represent the wind direction. To compensate for the change in X-axis I used an additional attribute with the rotate transform styling.
.example{
transform: translateX(180px) rotate(45deg);
}
Well this evening, after recreating the compass and needle as two layers I uploaded them to my Home Assistant images directory in my www folder. I then used the picture elements card to display the compass gauge as the background image and added an image element to control the needle.
elements:
- type: image
entity: sensor.wind_bearing
tap_action:
action: toggle
image: /local/images/compass_needle.png
style:
top: 1%
left: 25%
width: 15%
transform: translateX(85px) rotate(318deg)
image: /local/images/compass_bg.png
type: picture-elements
My next challenge is updating the rotate transform attribute with the sensor value or alternatively using the state_filter with the image element.
Really happy with how accurate the weather station temperature and humidity are. I stuck a Zigbee Aqara temperature sensor directly underneath the weather station and they both have been reporting almost identical values.
Weather station: humidity blue; temperature red;
Particulate Matter 2.5
Time to get the Particulate Matter sensor working. I have a working Arduino sketch so just need to get this converted and working in ESPHome.
@DinoTech suggested on Discording using a state-switch and matching 16 or 64 of the 360 degrees by overlaying the needle image of the top of a picture-elements cards and having the state match and image 'swapped' for that templated match. (e.g. 25°, NNE, 225° SW)
SGP30 TVOC and eCO2
My SGP30 TVOC and eCO2 will be on the same board as my PM sensor so time to get this working too.
BME680 Digital Temperature Humidity Pressure Sensor
The VOC sensor allows temperature and humidity compensation. To achieve this I need to incorporate my BME680.
Soil temperature and moisture
Notes:
- Depth 30cm
- Soil temperature definition
- Photosynthetic activity was more highly correlated with soil temperature at 30 cm than with air temperature or soil temperature at shallower depths.
Environmental noise (dB)
Notes
I had planned to use an Omnidirectional Microphone Module I2S Interface INMP441 but the I2S interface seems to have poor documentation and community traction. Instead, I opted for a more sensitive decibel meter which I think will perform better for this project.
Weather/sky camera
Notes
- This could provide a live on-demand RTSP stream
- Daily timelapse (gif?)
- Could be triggered to record if the weather data suggests a weather event is happening or object detection in the video (Blue Iris and TensorFlow)
Dew point
Given I have data for air temperature and humidity I can calculate the dew point. See #44 for details how I achieved this.
Air quality sensors build
I started to solder the sensors to a PCB board this evening. I am soldering them on to two 10x26 PCB boards. This will fit nicely inside the Stevenson screen that will house them all.
Predictions
- The hot glue gun sealing the UV sensors to the top of the Stevenson screen will not endure high (summer) temperatures and will likely melt away leaving the sensor exposed and no longer mounted in the recessed hole exposing.
- The sensors won’t work once mounted due to the difficulty of removing them from their breakout board pin connectors.
Air Quality - CO, NO₂, NH₃
- MICS-4514 MICS-6814 Carbon Monoxide Nitrogen Oxygen Gas Sensor Module CO/NO2/NH3
- MICS-4514 Sensor Module
- Brand Name: CJMCU
- Carbon monoxide CO 1-1000ppm
- Nitrogen dioxide NO2 0.05-10ppm
- Ethanol C2H5OH 10-500ppm
- Hydrogen H2 1-1000ppm
- Ammonia NH3 1-500ppm
- Methane CH4 >1000ppm
- Propane C3H8 >1000ppm
- Iso-butane C4H10 >1000ppm
Air quality - LPG, CO, Smoke
- MQ-2 sensor
Air quality - Ozone
- MQ-131 sensor
Display
Cool idea to use ESPHome and a display to show weather station data.
https://home-assistant-guide.com/2020/10/08/the-esphome-weather-station-with-a-nextion-display/
Home Assistant GuideToday’s featured project is one I’ve been wanting to build for quite some time. Unfortunately, I’m still missing the crucial 3D printer needed for such projects. This project uses a 2.4″ Nextion display, which are quite interesting on their own, and the popular Wemos D1 mini ESP8266 board housed inside…
KKmoon 100KHz-1.7GHz Full Band UV HF RTL-SDR USB Tuner Receiver/ R820T+RTL2832U AM CW FM DSB LSB https://www.amazon.co.uk/gp/product/B0716CB1PM
Amazon.co.ukKKmoon 100KHz-1.7GHz Full Band UV HF RTL-SDR USB Tuner Receiver/ R820T+RTL2832U AM CW FM DSB LSB
https://esphome.io/components/tca9548a.html
ESPHome
Instructions for setting up TCA9548A I²C multiplexer in ESPHome.
Hi, Really interesting project! Have you made any headway with using the ESP32 in place of the Pi? I'm hoping to use a Bresser in a remote location where i already have a suite of rain gauges connected rto IoT vi two soplar powered gateways. I want to power the weather station reporting device from the gateway battery, so minimal power usage is essential, and as i dont need any of the Pi's extra capabilities i think the ESP32 is ideal
Hello, I am interested in the purchase of a Bresser weather station (a 5 in 1 or a 7 in 1, but does not matter right now) and I ended up here because of the following reason. RTL_443 is good to gather the values of the outdoor sensors because of RF, but I would like to gather, store and monitor the indoor temperatures and humidity % from the central base station inside home. How could I accomplish this task? I had searched for many days but I got nothing useful.
Another question I have I related to the Wind direction offset. I would setup the external unit approx to 022° North. Reading your post here, I did not understand how and where I should offset the North.
Many thanks.
Hello,
First of all really interesting project, thank you for documenting it this much.
I have a Bresser weather station and a Raspberry Pi, same use case as you. I would like to know which 868 MHz SDR receiver did you used?
Thank you,