Skip to content

Instantly share code, notes, and snippets.

@Jixabon
Last active March 17, 2026 13:23
Show Gist options
  • Select an option

  • Save Jixabon/ef6ba1c067b52b3d7c9bd8f3ce22baa9 to your computer and use it in GitHub Desktop.

Select an option

Save Jixabon/ef6ba1c067b52b3d7c9bd8f3ce22baa9 to your computer and use it in GitHub Desktop.

NOAA Weather Radio/EAS for Home Assistant

My goal of this project was to be able to receive the NOAA weather radio, decode alerts and trigger webhooks and stream the audio from the SDR.

Requirements

  • RTL-SDR Dongle (with antenna)
  • Device to host dongle
  • Running Home Assistant instance

This project is made possible mainly by the rtl_sdr package as well as multimon-ng and dsame. Thank you to the creators and contributors of these projects.

Tuning a Frequency

To start we'll need some apt packages

sudo apt-get install rtl-sdr sox lame ezstream icecast2

NOTE: At some point along installing the apt packages it will ask you to configure icecast. You can do this now or later by following icecast documentation. Be sure to remember the passwords you set as the "source" one will be needed later.

Configure ezstream

sudo nano /etc/ezstream.xml

Use the example here and paste it into nano but change the source password to the icecast source password. You should also change the mount_point to something such as /noaa and Ogg to MP3.

Test SDR Audio Stream

At this point with the SDR plugged in you can run rtl_test to see if it is being recognized. If it shows on the list we can run a command to stream our audio. Be sure to change the frequency (-f 162.40M) to your local NOAA weather radio.

rtl_fm -f 162.40M -s 48000 -l 0 -d 0 -g 45 | lame -s 48000 --lowpass 3200 --abr 64 --scale 9 -r -m m - - | ezstream -c /etc/ezstream.xml -v -r

Using a browser or a program like VLC we can then navigate to the IP of the device hosting the SDR along with the port for icecast and the mount_point path from our ezstream config.

eg http://192.168.1.10:8000/noaa

This should load a media player (if using a browser) that will play the radio frequency tuned. From here if all you wish to do is hear the radio then you're all set. I wanted to take it a step further and integrate this into Home Assistant to alert me when there are EAS messages.

You can play the audio stream on a Home Assistant media_player with something like:

action: media_player.play_media
target:
  entity_id: media_player.my_media_player
data:
  media_content_id: http://192.168.1.10:8000/noaa
  media_content_type: audio/mpeg
  enqueue: play

Getting Alerts

Start by downloading the required projects

sudo apt-get install python3-pip cmake

wget -O dsame-master.zip https://github.com/cuppa-joe/dsame/archive/refs/heads/master.zip

wget -O multimon-ng-master.zip https://github.com/EliasOenal/multimon-ng/archive/refs/heads/master.zip

Build and Install multimon-ng

Run the following commands found from the projects git page. This converts the digital information stored in the infamous EAS sound.

unzip ~/multimon-ng-master.zip
cd ~/multimon-ng-master

mkdir build
cd build
cmake ..
make
sudo make install

You can use sox to play an audio file that contains an EAS message and pipe it into multimon-ng to test the output with the following command to decode it.

sox | multimon-ng -t raw -a EAS -q -

Translate the EAS Codes

This will "translate" the EAS text string from multimon-ng into understandable information. Extract the dsame zip.

unzip ~/dsame-master.zip

Test it's functioning by running the following command

python3 ~/dsame-master/dsame.py --msg "ZCZC-WXR-RWT-020103-020209-020091-020121-029047-029165-029095-029037+0030-1051700-KEAX/NWS"

Adding HA Webhook Script

Create the following file in your home directory. Replace the end of each curl command with a webhook generated by adding a webhook trigger to an automation. The script offers place for running separate webhooks for a Test, Warnings and general Messages. I like to keep track of the date of the last test to ensure that everything is still operating properly. Warnings can be set to automatically play the message sent in the webhook payload or the media stream as shown above. The data sent by the webhook can be accessed by {{ trigger.json.<key> }} within an action of the automation.

~/ha-webhook.sh

#!/bin/sh
echo HA Webhook: running 1>&2
EVENT_CODE=$2
TYPE="${11}"
URL_PREFIX=https://homeassistant.local/api/webhook
LOG_DIR=~/events
JSON_STRING="{\"org_code\": \"${1}\", \"event_code\": \"${2}\", \"same\": \"${3}\", \"purge_time_code\": \"${4}\", \"date_code\": \"${5}\", \"originator_code\": \"${6}\", \"country\": \"${7}\", \"organization\": \"${8}\", \"location\": \"${9}\", \"event\": \"${10}\", \"type\": \"${11}\", \"start\": \"${12}\", \"end\": \"${13}\", \"length\": \"${14}\", \"seconds\": \"${15}\", \"date\": \"${16}\", \"message\": \"${17}\"}"

# Write to json file as way to log events
echo $JSON_STRING >> $LOG_DIR/$EVENT_CODE-$(date -d "today" +"%Y%m%d%H%M").json

# Trigger HA webhooks
if [ "$TYPE" = "T" ]; then
  echo HA Webhook: Test
  curl -H "Content-Type: application/json" --request POST -d "${JSON_STRING}" $URL_PREFIX/my-webhook_test
elif [ "$TYPE" = "W" ] || [ "$TYPE" = "A" ] || [ "$TYPE" = "E" ] || [ "$TYPE" = "R" ]; then
  echo HA Webhook: Alert
  curl -H "Content-Type: application/json" --request POST -d "${JSON_STRING}" $URL_PREFIX/my-webhook_alert
else
  echo HA Webhook: Message
  curl -H "Content-Type: application/json" --request POST -d "${JSON_STRING}" $URL_PREFIX/my-webhook_message
fi

After creating the script file be sure to add the ability to execute.

chmod +x ~/ha-webhook.sh

You can test dsame with HA webhooks with the following command.

python3 ~/dsame-master/dsame.py --msg "ZCZC-WXR-RWT-020103-020209-020091-020121-029047-029165-029095-029037+0030-1051700-KEAX/NWS" --call ~/ha-webhook.sh --command "{ORG}" "{EEE}" "{PSSCCC}" "{TTTT}" "{JJJHHMM}" "{LLLLLLLL}" "{COUNTRY}" "{organization}" "{location}" "{event}" "{type}" "{start}" "{end}" "{length}" "{seconds}" "{date}" "{MESSAGE}"

Live Alerts

This command will continuously monitor the SDR feed for decodeable information and run the script.

rtl_fm -f 162.40M -s 22050 -l 0 -d 0 -g 45 | multimon-ng -t raw -a EAS -q - | python3 ~/dsame-master/dsame.py --no-text --call ~/ha-webhook.sh --command "{ORG}" "{EEE}" "{PSSCCC}" "{TTTT}" "{JJJHHMM}" "{LLLLLLLL}" "{COUNTRY}" "{organization}" "{location}" "{event}" "{type}" "{start}" "{end}" "{length}" "{seconds}" "{date}" "{MESSAGE}"

Bring it all together

To bring together our audio stream and our EAS alerts we'll make a couple more scripts and a service to keep it running in the background.

~/source.sh

#!/bin/bash
echo INPUT: rtl_fm Device 1>&2
PPM=0
FREQ=162.400M
GAIN=42
until rtl_fm -f ${FREQ} -M fm -s 22050 -E dc -p ${PPM} -g ${GAIN} -| tee >(lame -s 22050 --lowpass 3200 --abr 64 --scale 9 -r -m m - - | ezstream -c /etc/ezstream.xml) | multimon-ng -t raw -a EAS /dev/stdin; do
    echo Restarting... >&2
    sleep 2
done
~/weather_radio.sh

#!bin/sh
python3 /home/radio/dsame-master/dsame.py --source /home/radio/source.sh --call /home/radio/ha-webhook.sh --command "{ORG}" "{EEE}" "{PSSCCC}" "{TTTT}" "{JJJHHMM}" "{LLLLLLLL}" "{COUNTRY}" "{organization}" "{location}" "{event}" "{type}" "{start}" "{end}" "{length}" "{seconds}" "{date}" "{MESSAGE}"

NOTE: Notice the fully declared file paths in this file. This is because it will be called by a service which will not have an associated user thus no associated home directory. Please update this to reflect the user that you have created these files under. Same goes for the service created in the next step.

We'll want both these new files to be executable

chmod +x source.sh
chmod +x weather_radio.sh

Next we'll create a service to run our weather alert scripts

sudo nano /lib/systemd/system/weather_radio.service

/lib/systemd/system/weather_radio.service

[Unit]
Description=Weather Radio with Alerts for Home Assistant
Before=multi-user.target

[Service]
Type=simple
ExecStart=/home/radio/weather_radio.sh
Restart=on-abort
 
[Install]
WantedBy=multi-user.target

Then run the following commands to get it running

sudo systemctl daemon-reload
sudo systemctl enable weather_radio.service
sudo systemctl start weather_radio.service

You can check to see if it is running smoothly with:

sudo systemctl status weather_radio.service

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment