This is part 2 of an incremental series of posts on monitoring the heating oil usage for the house. part 1 is here

Capture packets from the air

In my last post I decided to capture the messages sent by the Watchman oil tank monitor with a USB RTL-SDR. Since then I have tested this out with the rtl_433 software and managed to capture the sensor data on my laptop:

{
    "time": "2022-07-23 13:11:20",
    "model": "Oil-SonicSmart",
    "id": 600000000,
    "flags": 160,
    "maybetemp": 16,
    "temperature_C": 21.667,
    "binding_countdown": 0,
    "depth_cm": 46
}

Quite the win to so easy capture and display the data. The most important key depth_cm is the distance from the sensor at the top of the tank to the top of the fuel so this distance will increase as we use up the fuel.

There was a little confusion when setting up RTL-SDR with my laptop where I could not see any data on the 433Mhz band. To debug this I used gqrx and rtl-sdr to visualise a wider spectrum with a car keyfob as a known source. This revealed that it was my impatience rather than anything technical since the oil level is only transmitted every 50 min or so, a greater delay than I had assumed.

SDR on OpenWRT

The overall aim is to record the sensor data from the oil level monitor via the RTL-SDR attached to the OpenWRT router and send that to a database for storage and future analysis.

Oil Level Monitor -> USB RTL-SDR -> OpenWRT -> Database

The next step therefore is to get the USB RTL-SDR setup with OpenWRT. It is quite straightforward process of plugging it into the USB port on the Linksys MR8300 router and installing the rtl_433 software that works with RTL-SDR library to decode the raw sensor data.

Install rtl_433

Opening a shell on the OpenWRT we can install the package:

opkg update
opkg install rtl_433

Setup procd init script

To keep the rtl_433 software running in the background we will use a procd init script but since the package does not supply it’s own init script we need to create one. We will start with this rtl_433.init template and apply the following modifications to remove quiet option, create a temporary location to save the data and provide an incremental filename to prevent clobbering upon restart of the service. This final location for init script is /etc/init.d/rtl_433

--- rtl_433.init
+++ /etc/init.d/rtl_433
@@ -80,5 +80,5 @@
 
 	procd_open_instance
-	procd_set_param command "$PROG" -q
+	procd_set_param command "$PROG" 
 
 #	append_arg  "$cfg" runtime "-T" "60"
@@ -103,5 +103,8 @@
 	append_list "$cfg" output "-F"
 
-	procd_set_param stdout 1
+	mkdir -p /tmp/rtl_433
+	procd_append_param command -F json:/tmp/rtl_433/oil_level_$(date +"%Y-%m-%dT%H%M").json
 	procd_set_param stderr 0

Note that although json output is specified in the asscoiate config file below, the config parser is not able to handle custom date logic so it has to be hardcoded in the init file instead.

A config file for the rtl_433 init script that will be loaded each time the service starts.

config rtl_433
	# USB SDR Device
	option device 0
	# Respawn every x secs if process crashes
	option respawn_interval	300
	# Timestamp timezone
	option utc		
	# Convert output to metric
	option units si
	# Device protocol - Watchman Sonic oil tank monitor
	list demodulators	"43"
	# Output format 
	list output	"json"
	# Service enabled
	option enabled	1

Start rtl_433 service

Enable the service to be run on startup and start the service:

/etc/init.d/rtl_433 enable
/etc/init.d/rtl_433 start

Have a bit of patience and within a few hours we should start to see data being stored in the json files:

cat /tmp/rtl_433/oil_level_2022-07-23T1259.json
{"time" : "2022-07-28 11:47:32", "model" : "Oil-SonicSmart"...
...

Finally to make sure the init file is not deleted during upgrades add the file to sysupgrade.conf

echo "/etc/init.d/rtl_433" >> /etc/sysupgrade.conf

Archive sensor data with rclone

The json files are being stored in a temporary location in RAM so if the router reboots all data is lost. Therefore we a need a quick solution to archive this raw data until we have a database setup. Since I just created a Backblaze account and wanted to test it out, it is good timing to use it with rclone to save the files to a b2 bucket.

opkg install rclone

Setup a Backblaze b2 bucket and configure rclone for b2

rclone config

Create an hourly cron job for rclone:

crontab -e
crontab -l
@hourly rclone copy /tmp/rtl_433/ b2_remote:OpenWRT/rtl_433

The cron job runs can be verified with logread -e cron. Be aware that the cron log status will be cron.err even for successful runs, which is rather counter-intuitive.

Wrap up

This is a small step towards the final goal of visualising the oil tank level and history over time but being able to automatically store the oil level data is immense, one less thing I have to think about recording. So far it has been a fun wee project, delving deeper into various technologies. Next up we setup a MQTT broker to enable pub/sub pattern to help get data to where we really want it.