Davis Van ISS Weather Station With Raspbe

by guidocioni in Workshop > Home Improvement

3001 Views, 4 Favorites, 0 Comments

Davis Van ISS Weather Station With Raspbe

Screen Shot 2022-08-05 at 14.26.13.png
bme280-environmental-sensor-4.png

In this project I'm going to document my journey trying to set up a Davis Vantage Vue weather station continuously updating data on the internet with the help of a Raspberry Pi 4. You may say: there are a lot of projects like that on the internet! And you may be wrong :)

In this project we're going to use ONLY the Integrated Sensor Suite (ISS) of the Vantage Vue (which is sold separately for about 100 euros less than the kit including the console) and a RTL-SDR type receiver to get the sensor data. This way we'll be able to save a lot of money as a normal setup would need to have at least the console (to receive the data) and the USB datalogger from Davis (to interface with any software).

We're going to use Weewx (https://www.weewx.com/) to manage the weather station data. It is an amazing piece of open-source software which lets you connect basically every weather station that you can find on the market. Notably, it lets you use an RTL-SDR dongle to intercept data transmitted from a Davis Station (but really you could also get any data transmitted by a "normal" weather station) on the 868 MHz band (I'm based in Europe but it will work in a similar way for people in the US).

Supplies

31mgjWzg1NL._AC_.jpg
raspberry-pi-4-modell-b-4-gb-ram.jpg
download.jpeg
download.jpeg
  • NooElec NSDR Nano2+ RTL receiver - 35 EUR (but you can use whatever you have available)
  • Davis Vantage Vue ISS - 269 EUR
  • Raspberry Pi 4 4GB, Power Adapter, SD Card - I paid 80 EUR for a complete set also with case
  • BME280 Pressure and temperature sensor (optional) - 15 EUR
  • Lots of patience

Install WeeWx

NOTE: this assumes that you have a working installation of Debian or Ubuntu on the Raspberry PI. If that's not the case you can just check one of the thousand guides that explain how to perform a first setup. I will mainly work for the terminal so you can perform the following operations either connected via SSH or directly on the raspberry terminal.


Installing WeeWx is fairly easy. I followed the instructions for Debian (https://www.weewx.com/docs/debian.htm) and used the installation method with apt. Take note of the installation folders because we'll need that later.

executable:	/usr/bin/weewxd
configuration file:	/etc/weewx/weewx.conf
skins and templates:	/etc/weewx/skins
sqlite databases:	/var/lib/weewx/
generated web pages and images:	/var/www/html/weewx/
documentation:	/usr/share/doc/weewx/
examples:	/usr/share/doc/weewx/examples/
utilities:	/usr/bin/wee_*

You can use the "Simulator" station to start with while we set up the rtldavis executable, which will take most of our time.

Once finished the installation a daemon will already be running in the background: you can check that by doing

systemctl status weewx

In order to reach the webpage of the station you either need to configure a web server/reverse proxy (to access directly the web page to the same machine where weewx is running) or just set up a copy of the files into a FTP server (optional step). The HTML pages created by weewx are nothing but pure static content created on a user-defined interval so you can put them wherever you want.

I only had to install lighttpd to see the webpage

sudo apt install lighttpd

it will look for files into /var/www/html and, as weewx copies its files into /var/www/html/weewx, you'll be able to reach the webpage at raspberry-pi-local-ip/weewx.

You'll see the data update after the first 5 minutes. Don't worry, we'll change this ugly skin in a minute :)

Install RTL Drivers

This step really depends on the system that you're using, but in theory you should only need to install some packages from apt and make some correction to the udev rules. The final goal is to have a working installation of RTL-SDR which can recognize your dongle.

NOTE: you don't have to use the Noeelec NANO: any RTL-SDR dongle with the RTL2832U chip will work. This happened to be the smallest and cheapest receiver that I could find in Germany.

Start by installing the drivers.

sudo apt install rtl-sdr

Now we have to set some rules.

echo 'blacklist dvb_usb_rtl28xxu' | sudo tee – append /etc/modprobe.d/blacklist-dvb_usb_rtl28xxu.conf

Then go into /etc/udev/rules.d and create a new file (with sudo) called rtl-sdr.rules, with the content from this file https://osmocom.org/projects/rtl-sdr/repository/rtl-sdr/revisions/master/entry/rtl-sdr.rules.

It should be everything; if you now execute rtl_test into the command line you should be able to see something like this

$ rtl_test
Found 1 device(s):
 0: Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6
[R82XX] PLL not locked!
Sampling at 2048000 S/s.

Info: This tool will continuously read from the device, and report if
samples get lost. If you observe no further output, everything is fine.

Reading samples in async mode...

If you have troubles make sure to follow the RLT-SDR blog installation here https://www.rtl-sdr.com/tag/install-guide/ (scroll to Install on Linux)

Install Rtldavis

This is the step that took me the longest, as it is poorly documented. rtldavis is a program initially created by

Douglas Hall (https://github.com/bemasher/rtldavis) who unfortunately hasn't been able to maintain it. Luckily

Luc Heijst forked the repo (https://github.com/lheijst/rtldavis) and added some new corrections and the European frequencies, which we're going to need. That's the one that we're going to use, together with the driver for weewx (weewx-rtldavis), which is needed to translate the data read by rtldavis into a LOOP packet that weewx can use.

We'll start by installing rtldavis and testing it .

First of all install golang

sudo apt-get install golang git cmake

Then install librtlsdr-dev manually: this is a requirement, otherwise rtldavis will not work.

cd /home/pi
git clone https://github.com/steve-m/librtlsdr.git
cd librtlsdr
mkdir build
cd build
cmake ../ -DINSTALL_UDEV_RULES=ON
make
sudo make install
sudo ldconfig

Change some lines into your profile file

sudo vim ~/.profile 

  export GOROOT=/usr/lib/go
  export GOPATH=$HOME
  export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
  
source ~/.profile

Now get the rtldavis package

cd /home/pi
go get -v github.com/lheijst/rtldavis

and compile the source

cd $GOPATH/src/github.com/lheijst/rtldavis
git submodule init
git submodule update
go install -v .

If everything goes well you should find a new folder in your home with the executable inside /home/pi/bin/rtldavis.

Make sure to install librtlsdr-dev as showed before; if you use the one packaged in your system you'll not see an error, but instead a message (allocating zero copy buffer) and the executable will not produce anything.

Set Up Rtldavis

We're going to test the executable alone to see that everything's working fine. Most importantly we NEED to find the right frequencies. The go package has some EU frequencies hardcoded (868077250, 868197250, 868317250, 868437250, 868557250) but those will likely not work for you out of the box because of some discrepancies.

Go into /home/pi/bin/ and tun this command

./rtldavis -startfreq 868000000 -endfreq 868600000 -stepfreq 10000

This will scan the entire frequency spectrum where the station should transmit (you already turned the ISS sensors on, haven't you?). It will take a while but you should see some frequencies where the transmission is

10:10:31.123820 rtldavis.go VERSION=0.15
10:10:31.124130 tr=1 fc=0 ppm=0 gain=0 maxmissed=51 ex=0 receiveWindow=300 actChan=[0] maxChan=1
10:10:31.124179 undefined=false verbose=false disableAfc=false deviceString=0
10:10:31.124216 TEST: startFreq=868000000 endFreq=868600000 stepFreq=10000
10:10:31.124687 BitRate: 19200
10:10:31.124738 SymbolLength: 14
10:10:31.124773 SampleRate: 268800
10:10:31.124807 Preamble: 1100101110001001
10:10:31.124841 PreambleSymbols: 16
10:10:31.124875 PreambleLength: 224
10:10:31.124909 PacketSymbols: 80
10:10:31.124943 PacketLength: 1120
10:10:31.124977 BlockSize: 512
10:10:31.125010 BufferLength: 2048
Found Rafael Micro R820T tuner
10:10:31.525099 Hop: {ChannelIdx:0 ChannelFreq:868077250 FreqError:0 Transmitter:0}
Exact sample rate is: 268800.001367 Hz
10:10:31.698617 GetTunerGain: 0 Db
10:10:31.698697 SetFreqCorrection 0 ppm Successful
10:10:31.702138 Init channels: wait max 17 seconds for a message of each transmitter
10:11:07.580455 TESTFREQ 1: Frequency 868000000: NOK
10:11:25.519440 TESTFREQ 2: Frequency 868010000: NOK
10:11:43.458467 TESTFREQ 3: Frequency 868020000: NOK
10:12:01.397429 TESTFREQ 4: Frequency 868030000: NOK
10:12:19.337436 TESTFREQ 5: Frequency 868040000: NOK
10:12:37.276475 TESTFREQ 6: Frequency 868050000: NOK
10:12:55.215505 TESTFREQ 7: Frequency 868060000: NOK
10:13:13.154774 TESTFREQ 8: Frequency 868070000: NOK
10:13:31.093651 TESTFREQ 9: Frequency 868080000: NOK
10:13:49.032647 TESTFREQ 10: Frequency 868090000: NOK
10:14:06.971697 TESTFREQ 11: Frequency 868100000: NOK
10:14:24.910614 TESTFREQ 12: Frequency 868110000: NOK
10:14:27.099174 TESTFREQ 13: Frequency 868120000 (freqCorr=0): OK, msg.data: 80014D272907E6A4
10:14:39.912796 TESTFREQ 14: Frequency 868130000 (freqCorr=1031): OK, msg.data: 90058B09F39525CB
10:14:57.851600 TESTFREQ 15: Frequency 868140000: NOK
10:15:15.790642 TESTFREQ 16: Frequency 868150000: NOK
10:15:33.729646 TESTFREQ 17: Frequency 868160000: NOK
10:15:51.668677 TESTFREQ 18: Frequency 868170000: NOK
10:16:09.607740 TESTFREQ 19: Frequency 868180000: NOK
10:16:27.546769 TESTFREQ 20: Frequency 868190000: NOK
10:16:45.486136 TESTFREQ 21: Frequency 868200000: NOK
10:17:03.425139 TESTFREQ 22: Frequency 868210000: NOK
10:17:21.364168 TESTFREQ 23: Frequency 868220000: NOK
10:17:39.303185 TESTFREQ 24: Frequency 868230000: NOK
10:17:46.975373 TESTFREQ 25: Frequency 868240000 (freqCorr=1170): OK, msg.data: E0045ACB030E7D35
10:17:59.788122 TESTFREQ 26: Frequency 868250000 (freqCorr=2130): OK, msg.data: 50075FFF730024FC
10:18:17.727103 TESTFREQ 27: Frequency 868260000: NOK
10:18:35.666147 TESTFREQ 28: Frequency 868270000: NOK
10:18:53.605043 TESTFREQ 29: Frequency 868280000: NOK
10:19:11.544189 TESTFREQ 30: Frequency 868290000: NOK
10:19:29.483189 TESTFREQ 31: Frequency 868300000: NOK
10:19:47.422126 TESTFREQ 32: Frequency 868310000: NOK
10:20:05.361277 TESTFREQ 33: Frequency 868320000: NOK
10:20:23.300354 TESTFREQ 34: Frequency 868330000: NOK
10:20:41.239652 TESTFREQ 35: Frequency 868340000: NOK
10:20:59.178850 TESTFREQ 36: Frequency 868350000: NOK
10:21:06.849820 TESTFREQ 37: Frequency 868360000 (freqCorr=2310): OK, msg.data: 80046326B9066F1D
10:21:06.851418 TESTFREQ 38: Frequency 868370000 (freqCorr=3070): OK, msg.data: 80046326B9066F1D
10:21:24.789923 TESTFREQ 39: Frequency 868380000: NOK
10:21:42.729097 TESTFREQ 40: Frequency 868390000: NOK
10:22:00.668286 TESTFREQ 41: Frequency 868400000: NOK
10:22:18.607461 TESTFREQ 42: Frequency 868410000: NOK
10:22:36.546700 TESTFREQ 43: Frequency 868420000: NOK
10:22:54.484625 TESTFREQ 44: Frequency 868430000: NOK
10:23:12.423892 TESTFREQ 45: Frequency 868440000: NOK
10:23:30.363085 TESTFREQ 46: Frequency 868450000: NOK
10:23:48.302206 TESTFREQ 47: Frequency 868460000: NOK
10:24:06.241397 TESTFREQ 48: Frequency 868470000: NOK
10:24:13.915688 TESTFREQ 49: Frequency 868480000 (freqCorr=3727): OK, msg.data: A00552752B01A3E9
10:24:26.727222 TESTFREQ 50: Frequency 868490000 (freqCorr=4422): OK, msg.data: E00455CB010B9F1C
10:24:44.666628 TESTFREQ 51: Frequency 868500000: NOK
10:25:02.605734 TESTFREQ 52: Frequency 868510000: NOK
10:25:20.544182 TESTFREQ 53: Frequency 868520000: NOK
10:25:38.483333 TESTFREQ 54: Frequency 868530000: NOK
10:25:56.422456 TESTFREQ 55: Frequency 868540000: NOK
10:26:14.361597 TESTFREQ 56: Frequency 868550000: NOK
10:26:32.300674 TESTFREQ 57: Frequency 868560000: NOK
10:26:50.240205 TESTFREQ 58: Frequency 868570000: NOK
10:27:08.179294 TESTFREQ 59: Frequency 868580000: NOK
10:27:26.118451 TESTFREQ 60: Frequency 868590000: NOK
10:27:33.790629 TESTFREQ 61: Frequency 868600000 (freqCorr=3955): OK, msg.data: 500565FF720677CA
10:27:33.790832 Test reached endfreq; test ended

Results will probably vary for you, in my case I immediately saw that there was a frequency shift with respect to the "official" EU frequency of about 50000 Hz, and this was the reason why running rtldavis directly didn't work.

Anyway, after finding your offset you can re-rung rtldavis in receiving mode

./rtldavis -fc 56000 -tf EU -tr 1 -ppm 1

and you should see messages being received. You won't see any data from the sensors yet, but you should see something being printed like this

10:31:27.364138 rtldavis.go VERSION=0.15
10:31:27.365227 tr=1 fc=56000 ppm=1 gain=0 maxmissed=51 ex=0 receiveWindow=300 actChan=[0] maxChan=1
10:31:27.365752 undefined=false verbose=false disableAfc=false deviceString=0
10:31:27.367250 BitRate: 19200
10:31:27.367777 SymbolLength: 14
10:31:27.368256 SampleRate: 268800
10:31:27.368757 Preamble: 1100101110001001
10:31:27.369228 PreambleSymbols: 16
10:31:27.369697 PreambleLength: 224
10:31:27.370163 PacketSymbols: 80
10:31:27.370701 PacketLength: 1120
10:31:27.371174 BlockSize: 512
10:31:27.371642 BufferLength: 2048
Found Rafael Micro R820T tuner
10:31:27.811079 Hop: {ChannelIdx:0 ChannelFreq:868077250 FreqError:0 Transmitter:0}
Exact sample rate is: 268800.001367 Hz
10:31:27.988707 GetTunerGain: 0 Db
10:31:28.049017 SetFreqCorrection 1 ppm Successful
10:31:28.053112 Init channels: wait max 17 seconds for a message of each transmitter
10:31:32.105955 TRANSMITTER 0 SEEN
10:31:32.106099 Hop: {ChannelIdx:2 ChannelFreq:868317250 FreqError:0 Transmitter:0}
10:31:34.667998 300567FFC1807FAA 2 0 0 0 0 msg.ID=0
10:31:34.668201 Hop: {ChannelIdx:4 ChannelFreq:868557250 FreqError:0 Transmitter:0}
10:31:37.229970 E00367CB03079EA7 3 0 0 0 0 msg.ID=0
10:31:37.230392 Hop: {ChannelIdx:1 ChannelFreq:868197250 FreqError:0 Transmitter:0}
10:31:39.793944 50035FFF7101DBB9 4 0 0 0 0 msg.ID=0
10:31:39.794112 Hop: {ChannelIdx:3 ChannelFreq:868437250 FreqError:0 Transmitter:0}
10:31:42.355950 80035E2679071BD3 5 0 0 0 0 msg.ID=0
10:31:42.356254 Hop: {ChannelIdx:0 ChannelFreq:868077250 FreqError:274 Transmitter:0}

You're ready to go to the next step

Install Weewx-rtldavis

Now we can install the rtldavis driver for weewx. Make sure to stop weewx before proceeding further

sudo systemctl stop weewx
wget -O weewx-rtldavis-master.zip https://github.com/lheijst/weewx-rtldavis/archive/master.zip
sudo wee_extension --install weewx-rtldavis-master.zip
sudo wee_config --reconfigure --driver=user.rtldavis --no-prompt

We first need to do some modifications to the hardcoded folder of the binary:

sudo vim /usr/share/weewx/user/rtldavis.py

and modify all the occurrences of /home/pi/work/bin/rtldavis with /home/pi/bin/rtldavis.

Now try to run the driver

sudo PYTHONPATH=/usr/share/weewx python /usr/share/weewx/user/rtldavis.py

and you should see some output.

Now let's configure the driver in weewx.

sudo vim /etc/weewx/weewx.conf

[Rtldavis]
  cmd = /home/pi/bin/rtldavis -fc 55500 -ppm 1
  transceiver_frequency = EU

  iss_channel = 1
  # The values below only apply for Vantage Pro or Pro2
  anemometer_channel = 0
  leaf_soil_channel = 0
  temp_hum_1_channel = 0
  temp_hum_2_channel = 0
  # rain bucket type (0: 0.01 inch, 1: 0.2 mm)
  rain_bucket_type = 1

  # Print debug messages
  # 0=no logging; 1=minimum logging; 2=normal logging; 3=detailed logging
  debug_parse = 0
  debug_rain = 0
  debug_rtld = 1  # rtldavis logging: 1=inf; 2=(1)+data+chan; 3=(2)+pkt

  # The pct_good per transmitter can be saved to the database
  # This has only effect with 2 transmitters or more
  save_pct_good_per_transmitter = True
  log_unknown_sensors = True
  log_unmapped_sensors = True

  # The driver to use:
  driver = user.rtldavis

Remember to change the station type to rtldavis in [Station] before rebooting weewx. You can also turn debug=1 and debug_rtld=3 to check that everything is working properly.

Optional: Add BME280 Sensors for Pressure and Inside Temperature

1_y2KMvpP95QITrp4rZy29CA.jpeg

The ISS does not have sensors for pressure, nor it can measure inside temperature and humidity (obviously), so to replicate the original Davis console we need to add these data manually. While Weewx can easily continue running without inside temperature and humidity, pressure is such an important weather variable that it would be a pity not having it into the DB. Luckily you can use a cheap BME280 sensor to enhance the database with pressure, inside temperature and humidity.

First of all we need to turn of the inside temperature and humidity captured by rtldavis

sudo vim /usr/share/weewx/user/rtldavis.py

look for DEFAULT_SENSOR_MAP and comment these lines

    #'inTemp': 'temp_in', # temperature of optional BMP280 module
    #'inHumidity': 'humidity_in',

Then connect the BME280 sensor with the right pins (see attached image) and make sure that I2C is enabled in raspi-config (https://www.raspberrypi-spy.co.uk/2014/11/enabling-the-i2c-interface-on-the-raspberry-pi/).

Now you can install i2cdetect

sudo apt install i2c-tools

if everything went well you should be able to run the following command and see the output

i2cdetect -y 1
   0 1 2 3 4 5 6 7 8 9 a b c d e f
00:             -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- 1a -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- 77

77 is the address of our sensor, which we'll need later.

Now that the sensor is working we need to (you say it) install a weewx driver that can parse this data. Luckily there's already a driver ready to be downloaded: https://gitlab.com/mfraz74/bme280wx/ (note, I use a fork of the original project that reduces logging).

Download and install the driver with

sudo systemctl stop weewx
wget https://gitlab.com/mfraz74/bme280wx/-/archive/master/bme280wx-master.zip
sudo wee_extension --install bme280wx-master.zip

Then go into the configuration file /etc/weewx/weewx.conf and modify some lines

[Bme280wx]
  i2c_port = 1
  i2c_address = 0x77
  usUnits = US
  temperatureKeys = inTemp
  temperature_must_have = ""
  pressureKeys = pressure
  pressure_must_have = outTemp
  humidityKeys = inHumidity
  humidity_must_have = ""

you'll notice we use the same address found with i2cdetect: in case you have a different address you of course need to change it. You can leave the rest as it is. Just make sure that the Engine / Services part of the configuration file has data_services = user.bme280wx.Bme280wx (should be added automatically by the installation).

Restart weewx and you should see the internal temperature and humidity, together with the pressure, being updated.


(Optional) Change Skin and Configuration

F0F0ZV6L6FHFE96.png
Screen Shot 2022-08-05 at 14.47.04.png

I used the skin shown in the picture which includes data and plots of different periods.

You can install it easily by following the instructions here https://neoground.com/docs/neowx-material/installation

Once you installed the skin make sure you change your weewx.conf to only produce HTML pages for the neowx skin:

[StdReport]
 ...
  [[SeasonsReport]]
    skin = Seasons
    enable = false

  [[SmartphoneReport]]
    skin = Smartphone
    enable = false

  [[MobileReport]]
    skin = Mobile
    enable = false

  [[StandardReport]]
    skin = Standard
    enable = false

  [[Neow]]
    skin = neowx-material
    enable = true

Restart again weewx and everything should work as expected.

You can modify settings of the skin here /etc/weewx/skins/neowx-material. Note that if you press on the "telemetry" link (lower left) you can see the frequency errors, which clearly depend on the temperature, so that you can check if the frequency offset that you chose at the beginning needs to be tuned. You can even check if the battery of the capacitor in the Sensor suite is low or not.

See the screenshot for the values that I have,

(Optional) Where Is the Database/Modifying Values

Unfortunately weewx does not give you the possibility to modify the data directly in the web interface.

However, the data is stored into a simple database file that you can open, view and modify: it can be found in /var/lib/weewx/

here is a sample Python script to read the data

import sqlite3
import pandas as pd
con = sqlite3.connect('/var/lib/weewx/weewx.sdb')
df = pd.read_sql_query("SELECT * from archive", con,
                       index_col='dateTime')#.dropna(axis=1)

df['datetime'] = pd.to_datetime(df.index, unit='s', utc=True)
df['outTemp'] = df['outTemp'].apply(lambda x: (x-32.) * (5./9.) )
df['inTemp'] = df['inTemp'].apply(lambda x: (x-32.) * (5./9.) )
df['appTemp'] = df['outTemp'].apply(lambda x: (x-32.) * (5./9.) )

df['heatindex'] = df['heatindex'].apply(lambda x: (x-32.) * (5./9.) )
df['humidex'] = df['humidex'].apply(lambda x: (x-32.) * (5./9.) )
df['barometer']=df['barometer'].apply(lambda x:  x * 33.86389 )
df['pressure']=df['pressure'].apply(lambda x:  x * 33.86389 )
df['altimeter']=df['altimeter'].apply(lambda x:  x * 33.86389 )
df['dewpoint'] = df['dewpoint'].apply(lambda x: (x-32.) * (5./9.) )
df['inDewpoint'] = df['dewpoint'].apply(lambda x: (x-32.) * (5./9.) )

To modify the data see the article https://github.com/weewx/weewx/wiki/Cleaning-up-old-'bad'-data


(Optional) Upload Data Via FTP to a Server

You can use the [[FTP]] skin to upload the data to your website so that you can access the data also on the go, not only in your local LAN.

Just set the settings accordingly

  [[FTP]]
    skin = Ftp
    enable = true
    user = ...
    password = ....
    server = ....  # The ftp server name, e.g, www.myserver.org
    path = ....  # The destination directory, e.g., /weather
    secure_ftp = False
    port = 21
    passive = 1
    ftp_encoding = latin-1

Note that I used ftp_encoding = latin-1 because some servers only accept this encoding. if that's not the case for you just comment this line.

(Optional) Backup the Database

Coming soon...