A NOAA SAME/EAS alert decoder for the MeshHall MeshCore bot.
Decodes NOAA Weather Radio SAME headers via RTL-SDR and writes alerts directly
to a MeshHall SQLite database. The main bot then serves them via !alerts and
!alert <id> with zero internet dependency.
Runs as a separate systemd service alongside MeshHall. Both share the same SQLite database safely via WAL mode.
Status: Untested - My hardware for validation isn't working. The decoder logic is complete but has not been run against a live RTL-SDR + NOAA signal. Contributions and test reports welcome.
There is no warranty of fitness of this code for any purpose. It was originally written to meet my needs of running on a Raspberry Pi 3B+, but likely will work on other Linux or Unix-like operating systems.
This code is developed with both human authoring and agentic assistance.
- RTL-SDR dongle (RTL2832U-based, e.g. RTL-SDR Blog v3)
- Antenna suitable for 162 MHz (VHF weather band)
sudo apt install rtl-sdr multimon-ngPython dependencies are minimal - the decoder uses only stdlib plus the
aiosqlite package already present in a MeshHall venv.
git clone <repo> ~/meshhall-same
cd ~/meshhall-sameThe installer creates a meshhall-same service account, installs to
/opt/meshhall-same, creates a Python venv, installs dependencies, and
registers the systemd service. It detects whether a previous version is
installed and upgrades in place.
sudo bash install.shOptions:
--yes Skip all confirmation prompts (for automation)
--install-dir PATH Custom install path (default: /opt/meshhall-same)
--db-path PATH MeshHall database path (default: /opt/meshhall/data/meshhall.db)
NOAA Weather Radio broadcasts on one of seven frequencies (MHz):
162.400 162.425 162.450 162.475 162.500 162.525 162.550
Find the strongest station in your area: https://www.weather.gov/nwr/station_listing
sudo nano /etc/systemd/system/meshhall-same.service
# Edit the --freq argument in the ExecStart line
sudo systemctl daemon-reloadsudo systemctl start meshhall-same
# Watch logs
sudo journalctl -u meshhall-same -fRun the installer again - it detects the existing installation and upgrades in place without touching any configuration:
sudo bash install.shsudo bash uninstall.shThe MeshHall database is not touched - alerts already decoded remain
queryable via !alerts.
# Run manually (stop the service first)
sudo systemctl stop meshhall-same
/opt/meshhall-same/venv/bin/python /opt/meshhall-same/same_decoder.py \
--db /opt/meshhall/data/meshhall.db \
--freq 162.550M \
--device 0Multiple RTL-SDR dongles are supported - duplicate the service file with
--device 1 and a different --freq for a second dongle.
rtl_fm (tunes SDR to WX freq) → multimon-ng (decodes SAME headers) → same_decoder.py → SQLite
same_decoder.py parses the SAME protocol fields (event code, FIPS codes,
duration, originator) and writes decoded alerts to the alerts table in
MeshHall's database. The main bot reads from this table for !alerts and
!alert <id> responses.
The decoder writes to the alerts table, which is expected to already exist
in the MeshHall database (created by the weather plugin's schema registration).
Do not run the decoder against a database that hasn't been initialized by
MeshHall at least once.
GPLv3 - see LICENSE file for full license text.