A lightweight, efficient radiosonde decoder for Raspberry Pi and X86_64 gateways, designed to work with RTL-SDR, Airspy and KA9Q radio receivers. Using the excellent rs1729/RS decoders embedded into this framework.
β Important notice: From version 1.0.60 and higher upload of radiosonde telemetry to sondehub.org is now available for this sondetypes:
-
RS41 (from v1.0.60)
-
DFM06 (from v1.0.60)
-
DFM09 (from v1.0.60)
-
DFM17 (from v1.0.60)
-
M10 (from v1.0.61)
-
M20 (from v1.0.61)
-
RS92 (from v1.0.62)
The RS92 data validation was successfully granted, it may take some time until sondehub makes the infrastructure update.
- Pinned decoder source.
scripts/install_softchain.shnow clonesradiosonde_auto_rxat a fixed tag (v1.8.2, override withAUTORX_REF), so every gateway builds identicaldft_detect/fsk_demod/iq_dec/*modbinaries β no more perβinstall behaviour drift. - RS41 bandwidth fastβpath is now OFF by default. Every candidate is
classified purely by
dft_detectcorrelation (auto_rx's method), which removes the bandwidthβguess that let a narrowβmeasuring DFM start as RS41. Reβenable per gateway withdetection.rs41_fastpath: true(β15 s faster RS41 start). - dft_detect classification hardened: M10/M20 negativeβcorrelation now compared
by magnitude (fixes M10/M20 being misβtyped), MRZ + iMet variants + build
suffixes (RS41SG) added to the parser, and unreachable "no type passed
threshold" logging fixed (now reports each type's score for calibration).
Thresholds are configβdriven via
detection.dft_thresholds. - DFM decode fix:
--dist/--ptu/-IDare gated on--helponly (fielddfm09modrejects them β exit 255 β dead DFM). M10/M20 flags passed unconditionally. Softβchain params aligned with auto_rx (--mask 5000 --nsym=300 -p 5, DFM-i).datetime.utcnow()deprecation removed. - iq_dec inline DC removal (auto_rx method) available in both the
--IQand soft chains viadecoders.iq_dc_block.
- Ghost / "birdie" reject. The scanner now rejects strongβbutβnarrow peaks
(CW/spurs) that were starting phantom decoders β configurable via
sdr.airspy.birdie_reject_snr_db/birdie_reject_bw_hz/scan_min_bw_hz.
- System Statistics tiles: ActiveβSondes 3βdot menu (Active / Total); Frames menu (Total / Today's, new UTCβday counter); CPU/RAM Live / Graph (60βmin chart, fullβrow when graphed).
- Sonde tiles: Standard / Extended 3βdot menu (Extended row shows Distance /
Elevation / Battery, heightβaware); M10/M20/DFM show battery instead of SNR;
header time as
β¦Z; correct DFM subtype badges (DFM06/09/17) resolved from the log with correct colours. - Ownβgateway map marker. Click for identity/hardware + the sondes received in
the last
sonde_retention_timewindow, each with heightβaware slant distance, elevation and course. Rightβclick β Landings (25/50/100/150 km range rings + lastβposition markers) / Heatmap (last positions) / Clear, with a "Loading data β¦" dialog. - Landings: liveβstyled popups (id, date/time, position, altitude, vβvel, frequency, distance); rightβclick a landing β Show / Clear sonde path (polyline loaded from the logfile).
- Sonde Statistics modal: serverβside LTTB decimation (huge speedβup on
long flights,
?max_points); new Elevation chart with a second Distance line on a right axis; tiles reordered (Altitude|Elevation, HVel|VVel, Sats|Battery, SNR|RSSI); sonde identity in the title and maximized headers; fixed missing frequency when opened via rightβclick on an active tile. - Gateway details modal shows Hostname/IP, version, memory/disk.
- Fixed a stuck "Loading data β¦" modal backdrop (Bootstrap show/hide race), and
M10/M20 dashedβserial (
210β2β11234ββ¦) logfile loading being truncated to210.
- Optβin downloader (
rs92.ephemeris_download) fetches the current GPSβday broadcast ephemeris intodata/rs92and feedsrs92mod -efor a position solve. Default source is BKG (Germany, HTTPS, no login) RINEX3 mixedβnavBRDC00WRD_R_<yyyy><doy>0000_01D_MN.rnx.gz. Runs in the background with retry/backoff (recovers a networkβnotβreadyβatβboot failure) and reβchecks hourly for the UTCβmidnight day rollover. A System Health "Ephemeris" row shows ready/pending (only when enabled).
Inline check of the installation and configuration of optional modules.
See changelog in the release section for all details.
For quickstart and easy setup from scratch the openwxsdr_config script is available now. It also contains a config backup and configuration check.
The receiver statistics gives an comprehensive overview of your radiosonde detection and decoding performance
Received radiosonde frequencies are shown at a glance, you clearly see the most frequent radiosonde frequencies used in your area.
Telemetry and sensor data of each received radiosonde is available in the sonde statistics menu.
In band sweep mode a single SDR checks the whole radiosonde spectrum and writes detected frequencies into Frequency Repository. Instantly manual decoder start is available from the repo manager for detected new frequencies.
- π― Automatic Signal Detection: Scans spectrum and automatically detects radiosonde signals
- π§ Multiple Sonde Types: Supports RS41, RS92, DFM, M10, M20, iMet, LMS6, MRZ
- π‘ Multi SDR Support: Works with up to 4 RTL-SDR or Airspy R2, Airspy Mini USB dongles
- ποΈ Virtual Receivers: Configurable parallel decoding of multiple sondes with KA9Q radio
- πΊοΈ Web Interface: Clean Leaflet-based map showing real-time flight paths
- π€ OpenWX Integration: MQTT & UDP JSON output for seamless data upload
- π€ Sondehub Integration: seamless data upload to sondehub.org
- β‘ Lightweight: Minimal overhead compared to several other decoder solutions
- π§ One-step installer: Easy installtion of all required packages
- Raspberry Pi 4 / 5 / 400 / 500 (8GB recommended) or Intel x86_64 client
- Debian 13 "Trixie" or Raspberry Pi OS (64 Bit)
- RTL-SDR, Airspy R2, Airspy Mini dongle or KA9Q-compatible SDR
- Antenna tuned for 400-406 MHz
- Selective 400 MHz LNA
- SAW filter recommended
βββββββββββββββββββ
β RTL-SDR/Airspy β
β KA9Q Radio β
ββββββββββ¬βββββββββ
β
ββββββΌβββββββββββββββ
β Spectrum Analyzer β
β Signal Detector β
ββββββ¬βββββββββββββββ
β
ββββββΌββββββββββββββββββ
β Decoder Manager β
β (rs1729/RS decoders) β
ββββββ¬ββββββββββββββββββ
β
ββββββΌβββββββββ¬βββββββββββ¬ββββββββββ
β β β β
βββββΌβββββ ββββββΌββββββ βββΌβββββββ β
β Web UI β β UDP JSON β β Log β β
β Flask β β OpenWX β β File β β
ββββββββββ ββββββββββββ ββββββββββ β
β
[sondehub]
OpenWXSDR offers an easy-to-use One-Step-Installer to install the necessary libraries, packages and OpenWXSDR package.
See the wiki for detailed installation instructions: https://github.com/DL2MF/OpenWXSDR/wiki/Installation
If you prefer manual installation of the package, continue below.
sudo apt-get update
sudo apt-get install -y git build-essential cmake pkg-config \
libusb-1.0-0-dev python3-pip python3-venv rtl-sdrmkdir -p decoders
cd decoders
git clone https://github.com/rs1729/RS.git rs1729
cd rs1729
# Build the decoders
cd demod && make
cd ../rs41 && make
cd ../rs92 && make
cd ../dfm && make
cd ../m10 && make
cd ../imet && make
cd ../lms6 && make
cd ..cd ~/!Develop_OpenWXSDR
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txtEdit config.yaml to match your setup:
- Set SDR type and parameters
- Configure frequency ranges for your region
- Set receiver specific settings (span, gain, fft, treshold)
- Configure OpenWX UDP and external output destinations
Key configuration options in config.yaml:
- sdr.type: Choose 'rtlsdr', 'airspy', 'flux242' or 'ka9q'
- receivers.max_concurrent: Number of parallel decoders (1-8 recommended)
- detection.freq_ranges: Frequency ranges to scan
- output.udp: Configure OpenWX server destination
Data sent to OpenWX server:
{
"software_name": "OpenWXSDR",
"software_version": "1.0.45",
"uploader_callsign": "<your-call>",
"time_received": "2026-04-30T12:34:56.789Z",
"type": "RS41",
"frame": 12345,
"id": "T1234567",
"datetime": "2026-04-30T12:34:56.000Z",
"lat": 51.5074,
"lon": -0.1278,
"alt": 15420.5,
"vel_h": 12.3,
"vel_v": 5.2,
"heading": 285.5,
"temp": -45.2,
"humidity": 25.5,
"pressure": 150.25,
"frequency": 402.700,
"sats": 8,
"snr": 25.5
}| Type | Decoder | Notes |
|---|---|---|
| RS41 | rs41mod | Vaisala RS41-SG/SGP/SGM |
| RS92 | rs92mod | Vaisala RS92-SGP/NGP |
| DFM | dfm09mod | Graw DFM06/09/17 |
| M10 | m10mod | Meteomodem M10 |
| M20 | m20mod | Meteomodem M20 |
| iMet | imet54mod | InterMet iMet-54 |
| LMS6 | lms6mod | Lockheed Martin LMS6 |
| MRZ | mrzmod | Meteo-Radiy MRZ |
python3 openwxsdr.pyAccess the web UI at http://raspberry-pi-ip:5000
Many configuration settings are also available in the WebUI and can be changed during operation:
- SNR treshold
- Scan interval
- Callsign and SSID
- SDR-Type and device settings
- Center Frequency
- Sample Rate
- Gain
- PPM correction
- MQTT and upload
- Server IP / hostname
- Port
- User credentials
The local web UI is available at http://yourdevice-ip:5000
For each configured receiver the frequency spectrum is available:
If enabled in config.yaml your device will upload radiosonde telemetry and sensor ptu to OpenWX.de http://map.openwx.de:
Upload to OpenWX.de is preferable via MQTT configurable. Generate your API-key in your OpenWX-Account and configure your credentials in config.yaml.
# MQTT upload to OpenWX.de broker
mqtt:
enabled: true
server: '<server-ip>' # MQTT broker hostname or IP
port: 1883 # MQTT broker port (1883 = plain, 8883 = TLS)
username: '<username>' # MQTT username (leave empty if not required)
password: '<password>' # MQTT password (leave empty if not required)
topic_prefix: 'OPENWXSDR/<your-call>/' # MQTT topic prefix (e.g. OPENWXSDR/<callsign>/<serial>)
client_id: '<your-call>-15' # MQTT client ID
keepalive: 60 # MQTT keepalive in seconds
connect_timeout: 10 # Wait this many seconds for initial CONNACK
tls_enabled: true # Set false for username/password brokers on plain TCP (usually port 1883)
tls_insecure: true # Accept brokers by IP/self-signed cert without CA validation
tls_ca_certs: '' # Optional CA bundle path for strict TLS validation
transport: 'tcp' # MQTT transport
If enabled in config.yaml your device will upload radiosonde telemetry and sensor ptu to sondehub.org:
# ============================================================
# SondeHub Upload
# ============================================================
sondehub:
enabled: true # Since V1.0.60 upload to sondehub.org is granted
queue_mode: true # false = direct upload mode, true = queued batch upload mode
queue_batch_max: 50 # Max telemetry objects uploaded per queued request (10-fast 50-robust)
queue_max_size: 1000 # Max queued objects before oldest/new drops may occur (200-fast 1000-robust)
upload_url: 'https://api.v2.sondehub.org/sondes/telemetry'
listeners_url: 'https://api.v2.sondehub.org/listeners' # Listener metadata endpoint
station_id: '<your-call>->ssid>' # Station ID (use callsign/SSID style)
uploader_callsign: '<your-call>' # Receiver callsign shown in SondeHub
uploader_antenna: '1/4 wave UHF vertical' # Receiver antenna
uploader_radio: 'Airspy Mini + rs1729' # Optional receiver hardware/radio description
contact_email: '<mail>@domain.com' # Optional contact email for listener metadata
uploader_lat: 52.00 # Must match station.lat above
uploader_lon: 10.00 # Must match station.lon above
uploader_alt: 100 # Must match station.alt above
upload_rate_s: 10 # Upload interval in seconds (1-5 for queue mode -10 recommended for single tracking)
listener_upload_interval_s: 21600 # Listener metadata upload interval in seconds (6h / 4 times/day recommend)
GNU GPLv3 License - See (https://github.com/DL2MF/OpenWXSDR/blob/main/LICENSE) file
- rs1729/RS decoders: https://github.com/rs1729/RS
- Inspired by Project Horus radiosonde_auto_rx: https://github.com/projecthorus/radiosonde_auto_rx/
- Built for the OpenWX.de network community
For issues and questions, please open an issue on GitHub.
