Mounted Acurite Atlas Mounted Acurite Atlas

Motivation

A few weeks ago, we were clearing some cobwebs from the area near our front door where I’d put a $13 Acurite 06002M and accidentally sprayed the sensor with a water hose.

It survived, but the graph looked like this for a while:

Sad temperature/humidity graph

While I’m glad the sensor came back, there are better options for something that’s going to sit outside all day, like a personal weather station.

I’ve considered getting a weather station for a while, but haven’t for a few reasons. For one, they are often somewhat expensive and don’t have many instruments on-board. If you want to publish the data to the internet, it’s usually even more expensive, and you might not get a lot of access to the data directly (or worse, have to pay for a subscription to get to your own data).

I’ve been using the rtl_433 software that works with the rtl-sdr software defined radio (SDR) dongles to read wireless sensors around my house for a while now, and have been a fan of how easy it is to collect data from cheap sensors. I’d wanted something similar to that, but for a weather station.

It turns out that something similar exists for the full-blown station for around $125 directly from Acurite, with significant savings by not buying the display.

Given that I already had a way to read the sensor set up, and given the reasonable price, I decided to go ahead and buy it.

Locating the Weather Station

The first thing I needed to do was mount the thing somewhere. Guidance on this varies, but the National Weather Service has suggestions for how and where to put different weather instruments. Since this is an all-in-one package, there’s going to be some amount of compromise for a weather station like this. Ideally you have a temperature sensor and rain gauge around 1.25-2.0 meters above the ground and anemometer around 10 meters above the ground.

I decided that a 19mm (3/4-inch) diameter and 3 meter tall (10-foot) pole in a bucket of fast-setting concrete would be a good way to get started. EMT conduit works pretty well for this purpose and is relatively inexpensive. A 13.5kg (30-lbs) bag of fast setting quick-rete (in the red bag) was used to secure it in the bucket.

Pole Leveling Jig Pole Leveling Jig

To get the pole level, I first found a place on my patio where the bucket was perfectly level, then built a jig to keep it level with scrap wood, screws and zip-ties, and added the concrete, added the pole, re-leveled the pole again, and then added water to the bucket. This process is made much easier with more than one set of hands. Quick-rete advertises that it should be cured at 40 minutes, with a few hour wait before accepting a load, so I did just that. There’s some folks that say that you should mix up the cement, and you can certainly do that, but the manufacturers say that you can be lazy and just add water. I opted to be lazy.

Mounted Weather Station Mounted Weather Station

Weather Station Software

A pretty common piece of software for running weather stations is WeeWX. You can use weewx-sdr with a number of common stations, the Atlas being one of them.

Here’s a sample configuration for my station:

##############################################################################

[SDR]
    # This section is for the software-defined radio driver.

    # The driver to use
    driver = user.sdr
    [[sensor_map]]
        windDir = wind_dir.0041.AcuriteAtlasPacket
        windSpeed = wind_speed.0041.AcuriteAtlasPacket
        outTemp = temperature.0041.AcuriteAtlasPacket
        outHumidity = humidity.0041.AcuriteAtlasPacket
        rain_total = rain_total.0041.AcuriteAtlasPacket
        UV = uv.0041.AcuriteAtlasPacket
        outTempBatteryStatus = battery.0041.AcuriteAtlasPacket
        luminosity = lux.0041.AcuriteAtlasPacket

##############################################################################

There’s a few things still missing, namely radiation and barometric pressure. This particular station only measures luminosity.

You can approximate solar radiation from luminosity with a conversion factor, like so:

[StdCalibrate]

    [[Corrections]]
        radiation = luminosity/126.7 if luminosity is not None else None

Adding Barometric Pressure to WeeWX with Data Services

Barometric pressure is a little harder. Acurite usually puts the barometric sensor in the display, so no display means no sensor. There are a few ways to work around this, but one way is to add a data services engine.

One example of that is at github.com/bdwilson/acurite, but it specifically works off weewx.NEW_ARCHIVE_RECORD events. This is fine if you’re using the output generated by the weather station, but it means that you will be missing data if you’re trying to publish to somewhere like Weather Underground.

In order to fix that, you’ll need to bind to weewx.NEW_LOOP_PACKET and drop in pressure into the event. I happen to already have this data from a BME280 in InfluxDB, so I wrote a little glue to get that with a data services engine.

Here’s an example of how you might do that:

import weewx
from weewx.engine import StdService
import sys
import syslog
import json
from influxdb import InfluxDBClient

import cachetools.func
import weeutil.logger
import logging
log = logging.getLogger(__name__)

# Inherit from the base class StdService:
class AddExternalPressure(StdService):
    def __init__(self, engine, config_dict):
        log.info('Add Pressure service started!')

        # Pass the initialization information on to my superclass:
        super(AddExternalPressure, self).__init__(engine, config_dict)

        self.db = InfluxDBClient('127.0.0.1', 8086, '', '', 'metermon')
        self.bind(weewx.NEW_LOOP_PACKET, self.emit_data)

    def emit_data(self, event):
        pressure_hPa = self.get_conditions('pressure_hPa')
        pressure_vt = weewx.units.ValueTuple(pressure_hPa, 'hPa', 'group_pressure')
        conv_pressure_vt = weewx.units.convertStd(pressure_vt, event.packet['usUnits'])
        event.packet['barometer'] = conv_pressure_vt.value
        log.debug('Adding record of ' + str(event.packet['pressure']))

    @cachetools.func.ttl_cache(maxsize=128, ttl=10)
    def get_conditions(self, key):
        # Assuming not stale
        # TODO: Add a check for this being stale from the timestamp
        results = self.db.query("select pressure_hPa from enviro where sensor_address='7c:df:a1:xx:xx:xx' order by time desc limit 1")
        response = list(results.get_points())
        data = json.dumps(response, default=str)
        return data[key]

if __name__ == '__main__':
    logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
    print(get_conditions('pressure_hPa'))
    print(get_conditions('pressure_hPa'))

This will go in the same directory as sdr.py from above and will get added to services:

[Engine]
    [[Services]]
        data_services = user.extpressure.AddExternalPressure

Adding Barometric pressure to WeeWX with WeeWX-SDR and RTL_433 using a new sensor

This got me to a working station, but it would be nice if I could use regular 433 MHz sensors for pressure versus having to hit an IP network. weewx-sdr does support a number of sensors that can do this, such as the Fine Offset Electronics WH25/WH32B and Oregon Scientific BTHR968/BTHGN129. I looked for these on eBay, but couldn’t find those sensors. I did, however, find a Oregon Scientific BTHR918 for $30.

Since rtl_433 didn’t say it was supported, but I did find other folks using this sensor online, I figured it would be fun to add support if it wasn’t. It turns out that it’s similar to the BTHR968, but isn’t quite the same. The identifier is a little bit different than what documentation in oregon_scientific.c implied (0x5d50 vs 0x5d59), and the pressure offset is 795 instead of 856, but it’s otherwise similar to the BTHR968.

I was a bit confused at first by the tools thinking that the encoding was OOK_PULSE_PWM instead of OOK_PULSE_MANCHESTER_ZEROBIT on the wire, but it turned out to be the same as the others.

And with that, it works!

./rtl_433 -r ~/ws/rtl_433_tests/tests/oregon_scientific/BTHR918/BTHR918.cu8 -F json
...
{"time" : "@0.295496s", "model" : "Oregon-BHTR918", "id" : 20, "channel" : 0, "battery_ok" : 1, "temperature_C" : 22.200, "humidity" : 58, "pressure_hPa" : 1009.000}

With that done, I got a pull request to add support to rtl_433 accepted, and I’m still pending a the one for weewx-sdr, but I can now use the above sensor to get pressure.

I can now add it to the SDR configuration with:

barometer = pressure.0:20.OSBTHR918Packet

And remove the data engine.

Final Thoughts

With all that done, I have a fully functional weather station with two different wireless sensors. If you don’t want to fiddle with it all that much, then buying something off the shelf is probably the way to go. If you want any ability to customize your station or just have some level of reliability, then I think this is a nice option.