Warning
DO NOT RELY ON THIS PROGRAM WHEN LOSS, DAMAGE, INJURY OR DEATH MAY OCCUR! ALWAYS, ALWAYS HAVE MULTIPLE METHODS TO RECEIVE EMERGENCY ALERTS.
THIS IS NOT AN EAS DECODER
A secure, Open Source EAS ENDEC Logger to transmit News Feed messages recieved by a Sage Digital ENDEC Hardware Unit to external destinations.
- News Feed spec: section 9.4 (pg. 70) of the ENDEC manual
- EAS protocol specification: 47 CFR 11.31
- Supports multiple concurrent transmission destinations:
- Generic HTTP(S) webhooks
- GroupMe bot
- Discord embed
- RabbitMQ
- In the future, we would be open to PRs for other destinations, such as:
- Slack
- Email (SMTP)
- Twilio
{
"port": "/dev/ttyUSB0",
"logfile": "/var/log/wbor-endec/wbor-endec.log",
"debug": false
}
port
: The device to read from. This is the/dev/
port for your ENDEC hardware. For example, if your ENDEC is connected to/dev/ttyUSB0
, you would use/dev/ttyUSB0
.logfile
: The (optional) path to the log file. This is where wbor-endec will write its logs if specified. Make sure the user running wbor-endec has write permissions to this file. If not specified, logs go tostderr
/journal
.debug
: Set totrue
to enable debug level logging.
Save as /etc/wbor-endec/config.json
(0644):
sudo mkdir -p /etc/wbor-endec
sudo cp config.json /etc/wbor-endec/config.json
sudo chmod 0644 /etc/wbor-endec/config.json
{
"webhooks": ["https://example.com/webhook1", "https://example.com/webhook2"],
"discord_urls": ["https://discord.com/api/webhooks/...", "..."],
"groupme_bot_ids": ["abcd1234", "efgh5678"],
"rabbitmq_amqp_url": "amqp://guest:guest@localhost:5672",
"rabbitmq_exchange_name": "wbor-endec" // Optional, defaults to "wbor-endec"
}
webhooks
: List of webhook URLs to forward EAS messages to. These can be any HTTP(S) endpoint that accepts POST requests.groupme_bot_ids
: List of GroupMe bot IDs to forward EAS messages to. These can be found in the GroupMe developer portal (public, free).discord_urls
: List of Discord webhook URLs to forward EAS messages to. You can create a webhook in your Discord server channel settings.rabbitmq_amqp_url
: RabbitMQ AMQP URL to forward EAS messages to. This should be in the formatamqp://username:password@hostname:port/vhost
.rabbitmq_exchange_name
: The RabbitMQ exchange name to publish messages to. This is optional and defaults towbor-endec
.
Save in a directory managed by systemd's LoadCredential
(e.g. /etc/wbor-endec/
) as secrets.json
with permissions 0600
and owner root:root
:
sudo mkdir -p /etc/wbor-endec
sudo cp secrets.json /etc/wbor-endec/secrets.json
sudo chmod 0600 /etc/wbor-endec/secrets.json
sudo chown root:root /etc/wbor-endec/secrets.json
This project uses uv
for dependency management (recommended, installation instructions). You can also use pip
if preferred.
For development and quick setup, use the included Makefile:
# Clone and navigate to repo
git clone https://github.com/WBOR-91-1-FM/wbor-endec && cd wbor-endec
# Install dependencies and set up development environment
make dev-setup
# Edit config.json and secrets.json with your configuration
# (config.json template will be created by dev-setup)
# Run the application
make run
See more on the Development page for available Make commands and additional setup instructions.
Example scenario:
-
In Sage's EndecSetD, set one of the DB-9 serial COM ports on your ENDEC to output "News Feed". See section 9.4 (pg. 70) of the ENDEC manual for more info.
-
Use a USB to RS-232 serial adapter to connect the News Feed COM port of your ENDEC to a computer. We're using a Raspberry Pi, though any computer that can run Python and connect to the internet should work fine.
-
Run
sudo dmesg
(for macOS/Linux) to identify the the/dev/
device the adapter is plugged into. We're looking for a new USB detection for a serial device. Using the RS-232 adapter linked above, this is the log we found:usb 1-1.1: FTDI USB Serial Device converter now attached to ttyUSB0
This is telling us that the ENDEC feed will come in at
/dev/ttyUSB0
. If you're feeling up to it, assign the device a more user-friendly name by creating a udev rule. See this guide for more info. -
Clone this repo and navigate to it via
git clone https://github.com/WBOR-91-1-FM/wbor-endec && cd wbor-endec
-
Install dependencies:
- Using uv:
uv sync
- Using uv:
-
Start monitoring the ENDEC by running the script:
uv run python endec.py --config /etc/wbor-endec/config.json
- Reads public settings from
--config
path - Loads secrets from
$CREDENTIALS_DIRECTORY/secrets.json
or/etc/wbor-endec/secrets.json
- Validates port and URLs, then begins reading
<ENDECSTART>…<ENDECEND>
payloads and forwards messages
- Reads public settings from
sudo nano /etc/systemd/system/wbor-endec.service
Reference the template at wbor-endec.service
.
You will need to change:
{DEVICE}
= the/dev/
device you found in step 3, e.g./dev/ttyUSB0
. IMPORTANT NOTE: Systemd derives the device unit name from the path by converting slashes to dashes, e.g./dev/ttyENDEC
→dev-ttyENDEC.device
. So, if your device is/dev/ttyUSB0
, the unit name will bedev-ttyUSB0.device
. You can check this by runningsystemctl list-units --type=device
and looking for your device.Environment=SECRETS_PATH={PATH_TO_SECRETS_JSON}
= path to thesecrets.json
file you created in the previous step (/etc/wbor-endec/secrets.json
). This is where the script will look for the credentials.- Under
ExecStart
{PYTHON3_EXEC_PATH}
= directory for your Python executable, e.g./home/username/wbor-endec/.venv/bin/python
{SCRIPT_PATH}
= path toendec.py
, e.g./home/username/wbor-endec/endec.py
{PATH_TO_CONFIG_JSON}
= the path to theconfig.json
file you created in the previous step (/etc/wbor-endec/config.json
)
WorkingDirectory
= path to thewbor-endec
repo folder you cloned, e.g./home/username/wbor-endec
User
= username for the user running wbor-endec (e.g.pi
for Raspberry Pi)
After saving, run:
sudo systemctl daemon-reload
sudo systemctl enable wbor-endec.service
sudo systemctl start wbor-endec.service
sudo systemctl status wbor-endec.service
Look for active (running)
and the wbor-endec.log
file to confirm it is up and running.
After updating (pulling from this repo), be sure to run:
sudo systemctl daemon-reload
sudo systemctl restart wbor-endec.service
If the service fails to start or continuously restarts, view live output with:
sudo journalctl -u wbor-endec.service -f
To inspect the last 100 entries:
sudo journalctl -u wbor-endec.service -n 100
- Add support for setting different timezones (for users in different timezones)
Maintained by WBOR 91.1 FM and Mason Daugherty, originally inspired by Evan Vander Stoep.