Most cheap consumer weather stations, AcuRite, La Crosse, Fine Offset and their many rebadges, talk to their indoor console over 433 MHz. An RTL-SDR dongle can hear those same transmissions, which means the console is optional and the station can go straight onto APRS-IS without a vendor gateway.
The installer sets that whole chain up on a Raspberry Pi with one command:
curl -fsSL https://wxalerts.org/install-sdr-aprs.sh | sudo bash
It is interactive. It will ask you which station to publish, your callsign, and where the sensors are, and then it starts a beacon that runs on its own from then on.
What you need
| A Raspberry Pi | Any model that runs Raspberry Pi OS; a Zero 2 W is enough. Debian and Ubuntu also work. It needs to be on the internet. |
| An RTL-SDR dongle | RTL2832U based: RTL-SDR Blog V3 or V4, Nooelec NESDR, or a generic “DVB-T” stick. |
| A 433 MHz station | Anything rtl_433 decodes. The installer has the best support for the AcuRite 5-in-1. |
| A callsign | Your own, as a licensed ham. |
| Your station’s coordinates | In decimal degrees, and ideally the altitude too. |
| About 20 minutes | Most of it is the system update at the start. |
Have the station running and within range when you start, because part of the install is a live scan of the airwaves.
Running it
Run the one-line command above in a terminal on the Pi, over SSH or with a
keyboard and screen. If you would rather read the script before running it,
which is a good habit with anything piped into sudo bash, download it first:
curl -fsSL https://wxalerts.org/install-sdr-aprs.sh -o /tmp/wxalerts-install.sh
less /tmp/wxalerts-install.sh
sudo bash /tmp/wxalerts-install.sh
The installer needs a terminal to ask its questions. Over SSH that is the
default. If you are driving it from another script, use ssh -t.
What it asks you, in order
-
License confirmation. Type
YES. Anything else stops the install. -
Plug in the dongle, if it is not already. The installer waits until the dongle shows up on USB.
-
Which station to publish. After a 60-second scan it lists every sensor it decoded, strongest signal first, with the latest readings from each:
[1] Acurite-5n1 id=2002 signal -6.2 dB packets=12 60.2°F (15.7°C), 91% RH, wind 2.2 mph from 45°, rain counter 1.04 in [2] Acurite-5n1 id=1862 signal -14.0 dB packets=9 60.4°F (15.8°C), 99% RH, wind 3.2 mph from 202°, rain counter 96.42 in [0] Enter model/id manuallyType the number in brackets, not the ID. See Picking your station for how to tell which one is yours. If the scan found nothing, you can type the rtl_433 model name and ID by hand.
-
Callsign, for example
W1AWorW1AW-13. If you leave off the SSID it asks for one, and suggests13, the usual SSID for a weather station. The installer works out your APRS-IS passcode from the callsign and shows it to you. -
Location. Latitude and longitude in decimal degrees, north and east positive. You can paste a
33.4484, -112.0740pair straight from Google Maps. Then the altitude in feet above sea level, which can be left at 0. Use the position of the sensors, not your house’s street address and not the Pi’s. -
Comment, the text shown after the weather on aprs.fi. It defaults to
WXAlerts RTL-SDRand is trimmed to 43 characters.
After the last answer it starts the beacon and prints a summary with your callsign, passcode, station and the commands to watch it.
Picking your station
433 MHz carries a long way. In a neighborhood the scan will often find other people’s weather stations, and sometimes car tire pressure sensors and wireless thermometers too. Two stations of the same model, like the two AcuRite 5-in-1s above, are completely separate units: different IDs, different readings, and only one of them is yours. Picking the wrong one puts your callsign on your neighbor’s weather.
Ways to tell them apart, most reliable first:
- Match the readings to your own console. Temperature, humidity and wind direction are the easiest to compare. In the example above the two stations agree on temperature within a few tenths but disagree on humidity by 8% and on wind direction by 150°, so the console settles it at a glance.
- Make your station do something. Spin the anemometer by hand, or turn the wind vane to point a known way, and re-run the scan. The station whose wind changed is yours.
- Signal strength. The list is sorted strongest first, and the nearest station is usually the strongest. It is a hint, not proof: a station on your roof can read weaker than one on a neighbor’s pole with a clear line of sight.
The packet count is not a good guide. It depends on distance, antenna and where the 60-second window happened to fall in each station’s transmit cycle, and says little about whose station it is.
What it does, step by step
Updates the system and installs rtl_433. It runs a full apt-get dist-upgrade, then installs rtl-sdr and rtl-433 from the distribution. If
the distribution has no rtl_433 package, it builds rtl_433 from source.
Keeps the TV driver off the dongle. Linux treats these dongles as TV
tuners and loads a driver that grabs the device, which blocks rtl_433. The
installer blacklists that driver in
/etc/modprobe.d/wxalerts-rtl-sdr-blacklist.conf and unloads it.
Installs WeeWX and the weewx-sdr driver. WeeWX comes from its own apt
repository, and the installer writes an [SDR] sensor map for your station into
/etc/weewx/weewx.conf, keeping a copy of the original as
weewx.conf.bak-wxalerts. WeeWX is then left stopped; see
WeeWX or the beacon, not both.
Frees the dongle. Before scanning, it stops anything that could be holding
the SDR: WeeWX, an earlier beacon, stray rtl_433 or rtl_tcp processes, and
the TV driver. It then checks that the dongle actually opens. If something still
has it, the installer names the process and stops rather than carrying on with
a dead radio.
Scans, asks, and writes the config. The scan output is kept in
/opt/wxalerts/scan.jsonl, and your answers go to /opt/wxalerts/station.conf,
which is readable by root only.
Starts the beacon. It installs /opt/wxalerts/aprs_beacon.py as the
systemd service wxalerts-aprs, enabled so it starts at every boot.
How the beacon works
The beacon runs its own rtl_433 in the background and reads every decoded
packet. It keeps only packets whose model and ID match exactly the ones you
picked, and remembers the latest temperature, humidity, wind speed, gust, wind
direction and rain counter from them.
Every five minutes it logs in to rotate.aprs2.net on port 14580 and sends one
weather packet. A typical one looks like this:
W1AW-13>APZWXA,TCPIP*:@241430z3326.90N/11204.44W_225/004g009t072r000p012h45WXAlerts RTL-SDR
Read left to right: your callsign, the time in UTC, the position, then wind direction 225°, sustained 4 mph, gusting 9 mph, 72 °F, no rain in the last hour, 0.12 in since midnight, and 45% humidity. The APRS weather packet explains every field.
A few rules keep what it sends honest:
- Unknown is sent as unknown. Any field the station does not report goes
out as dots (
g...), which is how APRS says “no data”. These stations have no outdoor barometer, so the packet never carries pressure. - Stale readings expire. A value that has not been updated for 15 minutes is sent as unknown. If the temperature itself goes stale, for example because the sensor’s batteries died, the beacon stops sending until it hears the sensor again.
- Rain totals need history. The sensor only reports a running rain counter, so the beacon works out the totals itself. Rain in the last hour is sent once the beacon has an hour of readings. Rain since midnight is sent only after the beacon has run through a midnight, so the first day’s total is never a partial guess. A counter that jumps back to zero, which is what happens when the batteries are changed, is handled without losing the running total.
- A failed login is an error, not a silent drop. If APRS-IS does not accept the passcode, the beacon logs it and retries 30 seconds later, instead of sending packets the server would throw away.
- If the radio stops, the beacon restarts. If
rtl_433dies, for example because the dongle was unplugged, the beacon exits and systemd starts it again 10 seconds later.
Packets carry the tocall APZWXA, the prefix the APRS tocall registry sets
aside for experimental software.
After it is running
Watch the beacon work:
journalctl -u wxalerts-aprs -f
You should see update lines as the station transmits, roughly every half
minute for most sensors, and a TX line with the full packet every five minutes. A
few minutes after the first TX, look your callsign up on
aprs.fi. Then register the station with CWOP, as described
in Getting an ID. Registering is what
gets a ham callsign’s data quality-controlled by MADIS and passed on to the
NWS.
Other commands you will want:
systemctl status wxalerts-aprs # is it running?
sudo systemctl restart wxalerts-aprs # after editing station.conf
sudo systemctl stop wxalerts-aprs # stop beaconing
Changing things later
Re-run the installer to pick a different sensor, callsign or location. It
is safe to run again: it rewrites station.conf, keeps the original WeeWX
backup, and restarts the beacon. It also runs the full system update again, so
allow the time.
Or edit /opt/wxalerts/station.conf directly and restart the service. The
file is plain KEY=value lines:
| Key | What it is |
|---|---|
CALL |
Callsign and SSID the packets are sent as |
PASS |
APRS-IS passcode for the callsign |
LAT, LON |
Position in decimal degrees |
ALT |
Altitude in feet |
COMMENT |
Text after the weather data |
FREQ |
Frequency rtl_433 listens on |
MODEL, SENSOR_ID |
The station to publish, exactly as rtl_433 names it |
SENSOR_HEX |
The same ID in the form weewx-sdr uses |
Three optional keys are not written by the installer but are honored if you add
them: BEACON_SEC, the seconds between packets (300 minimum, which is also the
default), and APRS_HOST and APRS_PORT to use a particular APRS-IS server.
Settings you can change
Two environment variables change how the installer runs. Because of sudo,
they go after it:
curl -fsSL https://wxalerts.org/install-sdr-aprs.sh | sudo WXALERTS_FREQ=915M WXALERTS_SCAN_SECONDS=120 bash
| Variable | Default | What it does |
|---|---|---|
WXALERTS_FREQ |
433.92M |
Frequency to scan and listen on. Use 915M for 915 MHz AcuRite gear, 868M in Europe. |
WXALERTS_SCAN_SECONDS |
60 |
How long the station scan lasts. Raise it if your station transmits rarely. |
WeeWX or the beacon, not both
One RTL-SDR can be opened by one program at a time. The installer configures WeeWX for your station but runs the beacon, so WeeWX stays stopped. To run WeeWX instead, for its web pages, archive and its own uploads:
sudo systemctl disable --now wxalerts-aprs
sudo systemctl enable --now weewx
and the reverse to switch back. Running both needs a second dongle, and
editing the cmd line in the [SDR] section of weewx.conf so WeeWX uses it.
Troubleshooting
“usb_claim_interface error -6” or “The SDR is in use by something else”. Another program or the kernel TV driver has the dongle. The installer names the process if it can find it. Stop it, or simply reboot: the blacklist is already in place, so after a reboot the TV driver stays away. Then run the installer again.
“No packets” from the scan. Check that the station is powered and
transmitting, and that you have the right frequency (433 or 915 MHz; the label
on the sensor usually says). Move the dongle away from the Pi and any USB 3
ports, which put out enough noise to drown a weak sensor, and give it a proper
antenna rather than the stub in the box. Try a longer scan with
WXALERTS_SCAN_SECONDS=180. The raw rtl_433 errors are in
/opt/wxalerts/scan.err.
The beacon is running but nothing appears on aprs.fi. Look in the journal
first. APRS-IS did not verify the login means the callsign and passcode do
not match; re-run the installer or fix PASS. No TX lines at all means the
beacon has not heard your sensor; check for update lines and see the
battery-change tip above. APRS send failed with a network error means the Pi
cannot reach rotate.aprs2.net on port 14580.
Wind or rain is always dots. Your sensor does not report that value, or reports it in a unit the beacon does not recognize. Run rtl_433 by hand and look at the field names. Rain in the last hour and since midnight are dots at first by design; see How the beacon works.
“No terminal to prompt on”. The installer was started without an
interactive terminal, for example from cron or ssh host 'command'. Use
ssh -t, or run it from a normal login.
SyntaxWarning: invalid escape sequence lines during the install. These
come from the weewx-sdr driver’s own code on newer Python versions. They are
harmless and can be ignored.
Uninstalling
sudo systemctl disable --now wxalerts-aprs
sudo rm /etc/systemd/system/wxalerts-aprs.service
sudo systemctl daemon-reload
sudo rm -rf /opt/wxalerts
sudo rm /etc/modprobe.d/wxalerts-rtl-sdr-blacklist.conf
That removes everything the installer created. WeeWX, rtl_433 and the other
packages stay installed; remove them with apt if you do not want them, and
delete /etc/apt/sources.list.d/weewx.list to drop the WeeWX repository.
Where to go next
- Getting an ID: register your callsign with CWOP so the data reaches MADIS.
- The APRS weather packet: every field the beacon sends.
- Install, commission and maintain: siting the sensors so the numbers are worth sending.
- Your station on WxAlerts: where your observations show up once they are flowing.

