# SDR to APRS installer reference

> What the installer changes on your Pi, how the beacon builds and sends packets, the settings you can change, the station.conf keys, troubleshooting and uninstalling.

Weather stations · Reference · https://wxalerts.org/docs/weather-stations/installer-reference/

This page describes the installer from [One-command SDR to APRS installer](/docs/weather-stations/sdr-aprs-installer/).

## 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](#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](/docs/weather-stations/packet-format/) 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_433` dies, 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.

## Settings you can change

Two environment variables change how the installer runs. Because of `sudo`,
they go after it:

```bash
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. |

## 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.

  AcuRite and many other sensors pick a new random ID when their batteries are
  changed. If the journal suddenly stops showing `update` lines after a battery
  swap, that is almost always why. Run
  `sudo rtl_433 -f 433.92M -F json` for a minute (stop the beacon first),
  find your station's new `id`, and put it in `SENSOR_ID`.

### Service commands

```bash
systemctl status wxalerts-aprs      # is it running?
sudo systemctl restart wxalerts-aprs    # after editing station.conf
sudo systemctl stop wxalerts-aprs       # stop beaconing
```

### 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:

```bash
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](#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

```bash
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.
