Ilma · NAVTEX receiver
NAVTEX 518 kHz RTTY 4.5 / 7.6 / 10.1 MHz WEFAX 3.8 / 7.9 / 13.9 MHz

Songs propagating through the air, decoded at sea

Ilma decodes maritime weather services — unattended on a Raspberry Pi in the boat, and on a Mac for development.

Source on Codeberg

The interface

navtex-pi.local:8080
Ilma web interface: barometric-pressure trend in the topbar, NAVAREA and subject-code filters down the side, and a received DWD weather bulletin in the message archive.
518 kHz · MF

NAVTEX

International English service · single dial, monitored 24/7

SITOR-B FSK at 518 kHz. NAVAREA I stations take turns in fixed 10-minute slots, so the channel is live around the clock. When the same bulletin is re-broadcast a few hours later, Ilma merges the receptions — useful when fading varies between them.

Protocol
SITOR-B · F1B
Baud
100
Shift
±85 Hz
Areas
NAVAREA I
4.5 / 7.6 / 10.1 MHz · HF

RTTY

DDK2 · DDH7 · DDK9 — scheduled UTC windows

Baudot at 50 baud. Maritime weather forecasts and safety bulletins.

DDH7 · 7646 kHzF1B · 50 baud
ADRIA-N (44.1N  14.0E) SST: 18 C
MO 18. 00Z: S      0-2     0  M //
MO 18. 12Z: SE-S   2-3     0  M //
TU 19. 00Z: SW-W   0-2     0  M //
TU 19. 12Z: NW       3   0.5 M //
WE 20. 00Z: 
Protocol
Baudot · F1B
Baud
50
Shift
±225 Hz
Stations
DDK2 · DDH7 · DDK9
3.8 / 7.9 / 13.9 MHz · HF

Weather fax

DDK3 · DDH3 · DDK6 — Pinneberg, simultaneous

FM-modulated facsimile at 120 lines per minute. Ilma syncs to the phasing band, accumulates the image, and writes one PNG per chart. The chart below is from the Royal Navy's GYA at Northwood, which Ilma also tracks.

Decoded 10 m wind forecast chart received from Northwood, valid 22 May 2026 12:00 UTC, showing wind barbs and isotachs over the North Atlantic.
GYA Northwood10 m wind · 22 May 2026 12:00 UTC
Modulation
FM · 120 LPM
IOC
576
Output
PNG · trimmed
Clock
disciplined
01

Offline re-decode

A separate process re-decodes each window from saved IQ and replaces the live transcript if it scores better.

02

Archive

Bulletins kept on disk and in SQLite. Search by body text, filter by area, station, subject, or date.

03

Schedule

Daily UTC windows, editable from the phone UI. Conflicts checked against the NAVAREA I slot table.

04

Phone notifications

Optional ntfy for new bulletins. SAR messages (subject D) bypass filters, per IMO MSC.1/Circ.1403.

Two ways to run it
I The bench

Mac or PC with an SDR dongle

SDR++ sends audio into BlackHole 2ch and main.py --source audio reads from there. I check it against a known window — Den Helder at 14:30 UTC, or Pinneberg at 15:00 UTC.

shell · macOS
# clone, venv, install, run
$ git clone https://codeberg.org/sailingthroughcode/Ilma.git
$ cd Ilma
$ python3 -m venv .venv && source .venv/bin/activate
$ pip install -r requirements.txt
$ python3 main.py
SDR app
SDR++ · BlackHole 2ch
Dial
517.000 kHz USB · IQ correction on
Antenna
1:9 balun + long wire
Web UI
localhost:8080
II The boat

Raspberry Pi, headless, on board

The Pi reads IQ directly from the dongle. Everything runs as systemd services from boot. setup_pi.sh is idempotent: it installs deps, the RTL-SDR DVB blacklist, the NetworkManager AP profile, and the units.

shell · Raspberry Pi
# one-shot install on a fresh Pi OS
$ git clone https://codeberg.org/sailingthroughcode/Ilma.git ~/navtex
$ cd ~/navtex
$ bash scripts/setup_pi.sh
$ sudo systemctl enable --now navtex.service
SBC
Pi Zero 2 W · headless
IQ rate
256 kS/s direct from pyrtlsdr
Antenna
Active marine NAVTEX
Web UI
navtex-pi.local:8080 · or 10.42.0.1 (AP)