Emergency Alert Display System for Raspberry Pi
SAMEasy is a complete emergency alert monitoring system that receives SAME (Specific Area Message Encoding) alerts from weather radios and displays them on an e-ink screen. Perfect for emergency preparedness, weather monitoring, and staying informed about local threats.
SAMEasy automatically:
- π» Monitors weather radio frequencies for emergency alerts
- π Decodes SAME messages (tornado warnings, flood alerts, etc.)
- πΎ Stores alerts in a searchable database with full history
- π₯οΈ Displays current alerts on an e-ink screen with icons
- π± Outputs structured JSON data for integration with other systems
- Raspberry Pi 4 (3B+ works, but slower)
- RTL-SDR USB Dongle (RTL2832U based, ~$20)
- Waveshare 2.7" E-Ink Display (264x176 pixels)
- MicroSD Card (16GB+ recommended)
- Weather Radio Antenna (or just a wire for testing)
- SMA to UHF RF Adapter
- Powered USB Hub (if using multiple RTL-SDR dongles)
- Case/Enclosure (for weather protection)
Flash Raspberry Pi OS Lite to your SD card and enable SSH.
# On your Raspberry Pi as user 'noaa'
cd ~
git clone git@github.com:ifnull/sameasy.git sameasy
cd sameasy
chmod +x setup.sh
sudo ./setup.shThe setup script will:
- Install all dependencies (Python, Rust, system packages)
- Set up the database and directory structure
- Install systemd services for automatic monitoring
- Configure SPI for the e-ink display
- Install Waveshare e-Paper libraries
Edit the configuration file:
nano config.jsonKey settings to review:
- Font paths: Verify fonts exist on your system
- Icon mappings: Customize alert type icons
- Display settings: Adjust padding and icon size
# Change to the sameasy directory
cd ~/sameasy
# Test database
python3 scripts/check_database.py
# Test with sample alert
python3 scripts/test_decoder.py
# Test e-ink display (if connected)
python3 src/update_eink.pyAfter setup completes, the services are installed and ready. If you chose to start monitoring during setup, you can monitor the system with:
# Check service status
sudo systemctl status same_monitor.service
# Monitor live logs
journalctl -u same_monitor.service -fIf you didn't start the service during setup, start it manually:
sudo systemctl start same_monitor.servicesameasy/
βββ README.md # This file
βββ setup.sh # Automated installation script
βββ config.json # Display and system configuration
β
βββ src/ # Core application code
β βββ same_decoder.py # SAME message parser and processor
β βββ update_eink.py # E-ink display renderer
β βββ database_migrations.py # Database schema management
β
βββ scripts/ # Utility and management scripts
β βββ init_db.py # Database initialization
β βββ check_database.py # Database health checker
β βββ view_alerts.py # Alert viewing and search tool
β βββ test_decoder.py # System testing script
β
βββ system/ # System service files
β βββ same_monitor.service # Main monitoring service
β βββ same_monitor.sh # Service startup script
β βββ same-eink.service # E-ink update service
β βββ same-eink.path # File watcher for JSON updates
β
βββ data/ # Reference data files
β βββ eas_events.csv # Emergency event codes
β βββ fips_counties.csv # County FIPS codes
β βββ fips_states.csv # State codes
β βββ originators.csv # Alert originator codes
β
βββ icons/material/ # Alert type icons
β βββ tornado.png # Tornado warnings
β βββ flood.png # Flood alerts
β βββ warning.png # General warnings
β βββ [more icons...]
β
βββ runtime/ # Runtime data (auto-created)
βββ logs/ # Application logs
βββ alerts.db # SQLite alert database
βββ last_message.json # Current alert for display
Weather Radio β RTL-SDR β samedec β same_decoder.py β Database + JSON β E-ink Display
β
Audio Processing & SAME Decoding
1. Radio Reception
- RTL-SDR receives weather radio audio
samedec(Rust) decodes SAME bursts- Outputs structured alert data
2. Message Processing
same_decoder.pyvalidates and parses alerts- Resolves codes to human-readable descriptions
- Stores in SQLite database with full history
3. Display Management
- Monitors JSON file for new alerts
- Renders formatted display with icons
- Updates e-ink screen via SPI
4. Database System
- Automatic schema migrations
- Performance indexes for fast queries
- Full alert history with search capabilities
CREATE TABLE alerts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp_utc TEXT NOT NULL, -- When alert was issued
originator TEXT NOT NULL, -- Who issued it (NWS, etc.)
event TEXT NOT NULL, -- Human readable event type
event_code TEXT, -- SAME event code (TOR, FFW, etc.)
fips_codes TEXT NOT NULL, -- Affected area codes
regions TEXT NOT NULL, -- Human readable regions
duration_minutes INTEGER NOT NULL, -- How long alert is valid
issued_code TEXT NOT NULL, -- Raw timestamp code
source TEXT NOT NULL, -- Radio station ID
raw_message TEXT NOT NULL, -- Original SAME message
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);idx_alerts_timestamp- Time-based queriesidx_alerts_event_code- Filter by alert typeidx_alerts_originator- Filter by sourceidx_alerts_created_at- Recent alerts
βββββββββββββββββββββββββββββββββββββββ
β Tornado Warning β
β National Weather Service (NWS/ABC) β
β βββββββββββββββββββββββββββββββββββ β
β Oct 15 2025, 2:30 PM (60 minutes) β
β Madison, Jefferson, Hamilton β
β β
β Updated: 14:35 β
βββββββββββββββββββββββββββββββββββββββ
- Clean Typography: Uses DejaVu Sans for readability
- Smart Text Wrapping: Handles long region names
- Status Icons: Visual indicators for alert types
- Automatic Updates: Refreshes when new alerts arrive
- County Name Cleanup: Removes redundant "County" text
- πͺοΈ Tornado - TOR, SVR warnings
- π Flood - FFW, FLW alerts
- βοΈ Winter - WSW, BWS warnings
β οΈ General - Other warnings- ποΈ Watch - TOA, SVA watches
- π§ͺ Test - RWT, RMT test messages
- TOR - Tornado Warning
- SVR - Severe Thunderstorm Warning
- FFW - Flash Flood Warning
- FLW - Flood Warning
- WSW - Winter Storm Warning
- TOA - Tornado Watch
- SVA - Severe Thunderstorm Watch
- FFA - Flash Flood Watch
- RWT - Required Weekly Test
- RMT - Required Monthly Test
- NPT - National Periodic Test
- CAE - Child Abduction Emergency (AMBER Alert)
- EAN - Emergency Action Notification
- And many more...
# Change to sameasy directory
cd ~/sameasy
# Check database status
python3 scripts/check_database.py
# View recent alerts
python3 scripts/view_alerts.py --limit 5
# Search for specific alerts
python3 scripts/view_alerts.py --event "Warning" --since 2025-08-01
python3 scripts/view_alerts.py --event-code "TOR"
# Initialize/migrate database
python3 scripts/init_db.py# Service status
sudo systemctl status same_monitor.service
# View logs
journalctl -u same_monitor.service -f
# Restart services
sudo systemctl restart same_monitor.service
sudo systemctl restart same-eink.path
# Test e-ink display (from ~/sameasy directory)
cd ~/sameasy
python3 src/update_eink.py# Change to sameasy directory
cd ~/sameasy
# Test with sample message
python3 scripts/test_decoder.py
# Manual message processing
echo "ZCZC-EAS-TOR-048013+0030-1234567-KLOX/NWS-" | python3 src/same_decoder.py
# Monitor SDR input (if samedec is running)
samedec --help- CPU: ARM Cortex-A72 (Pi 4) or better
- RAM: 1GB+ (database and image processing)
- Storage: 8GB+ for logs and alert history
- Network: Optional (for time sync and updates)
- Automatic Recovery: Services restart on failure
- Database Backups: Created before schema migrations
- Error Logging: Comprehensive logging to files and journal
- Atomic Operations: Database transactions prevent corruption
- Graceful Degradation: System continues without display if needed
- CSV Caching: Reference data loaded once at startup
- Database Indexes: Fast queries on large datasets
- Efficient Rendering: Minimal e-ink updates to preserve display
- Memory Management: Proper cleanup of resources
- Edit
config.jsonto add icon mappings:
{
"icon_mappings": {
"NEW": "custom_icon.png"
}
}- Add icon file to
icons/material/custom_icon.png
Edit src/update_eink.py:
- Modify font sizes in config.json
- Adjust padding and spacing
- Change icon size and position
- Add new display elements
The system is designed to be extensible:
- Add new CSV files to
data/directory - Modify
load_all_csv_data()insame_decoder.py - Update database schema if needed
- System works offline (no network required for core function)
- No incoming network connections
- Radio reception is passive (receive-only)
- Local SQLite database (no cloud dependencies)
- Alert data stays on device
- Standard file permissions on logs and database
- Runs as unprivileged user where possible
- Systemd services with restart limits
- No sudo required for normal operation
No Alerts Received
# Check if RTL-SDR is detected
lsusb | grep RTL
# Check samedec is working
samedec --help
ps aux | grep samedec
# Check service status
sudo systemctl status same_monitor.service
journalctl -u same_monitor.service -n 50E-ink Display Not Working
# Check SPI is enabled
sudo raspi-config nonint get_spi
# Test display connection
python3 -c "from waveshare_epd import epd2in7_V2; epd = epd2in7_V2.EPD(); print('Display OK')"
# Check for errors in display service
journalctl -u same-eink.service -n 20Database Issues
# Change to sameasy directory
cd ~/sameasy
# Check database health
python3 scripts/check_database.py
# Run migrations manually
python3 src/database_migrations.py
# View recent database activity
tail -f runtime/logs/same_decoder.logFont/Display Rendering Issues
# Check font files exist
ls -la /usr/share/fonts/truetype/dejavu/
# Test font loading
python3 -c "from PIL import ImageFont; ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 12)"
# Verify config.json syntax (from ~/sameasy directory)
cd ~/sameasy
python3 -c "import json; print(json.load(open('config.json')))"- Application Logs:
runtime/logs/same_decoder.log - System Logs:
journalctl -u same_monitor.service - Display Logs:
journalctl -u same-eink.service
# Clone repository
git clone git@github.com:ifnull/sameasy.git sameasy-dev
cd sameasy-dev
# Create development environment
python3 -m venv dev-venv
source dev-venv/bin/activate
pip install -r requirements-dev.txt # If exists
# Run tests
python3 scripts/test_decoder.py- Follow PEP 8 for Python code
- Use type hints where possible
- Include docstrings for functions
- Add logging for debugging
- Write tests for new features
- Additional alert type support
- New display layouts or themes
- Integration with other systems
- Performance optimizations
- Documentation improvements
- Hardware support (different displays, etc.)
- SAME Summary
- SAME Protocol Specification
- Event Codes Reference
- FIPS County Codes
- EAS Message Generator
[Specify your license here - MIT, GPL, Apache, etc.]
- Issues: Create GitHub issues for bugs or feature requests
- Discussions: Use GitHub discussions for questions
- Documentation: Check this README and inline comments
This system is designed for informational purposes only. Always have multiple sources of emergency information:
- Battery/hand-crank weather radio
- Mobile phone emergency alerts
- Local emergency management notifications
- Television and radio broadcasts
π¨ This system should complement, not replace, official emergency alerting systems.
Built with β€οΈ for emergency preparedness and community safety
Last updated: August 2025