A high-performance severe weather monitoring platform with near-zero latency alerts, real-time warning lifecycle tracking, and automated scientific analysis. Uses NWWS-OI (XMPP) as the fastest warning path, with IEM/NWS API fallbacks, high-availability failover, and interactive Discord dashboards.
SPC Products: Day 1–8 convective outlooks (with automatic Gemini AI summary follow-ups), side-by-side outlook /compare tool, searchable /historical outlook archive (categorical and individual hazards), mesoscale discussions with watch probability detection (auto-summarized), SPC watches, WPC rainfall outlooks, WPC surface fronts, SCP, CSU-MLP, NCAR WxNext2 forecasts, and Project WxEye briefings.
Real-Time Alerts:
Important
Warning features are Beta. While designed for ultra-low latency, this bot is for situational awareness only. Redundancy saves lives. Avoid a single point of failure by always maintaining multiple independent methods for receiving life-safety alerts. Recommended sources include: NOAA Radio (w/ battery backup), WEA mobile alerts, TV/Radio Broadcast.
NWWS-OI fast path, IEMBot fallback, NWS API polling, SPC watch alerts with deduplication, NWS warnings (TOR/SVR/FFW/SPS) routable to dedicated per-type channels with runtime configuration via /enablewarnings, lifecycle tracking (CON/EXT/EXA), damage survey detection with DAT integration and photo carousels, VAD hodograph evolution recording for confirmed tornadoes (/archive to search).
Scientific Tools: Interactive RAOB/ACARS sounding plots with a fast Skew-T placeholder that upgrades in place (auto-posted near active watches and MDT/HIGH risk areas, with automatic AI environmental analysis), VWP hodographs with named radar sites (with AI-powered analysis buttons), Context-Aware AI Analysis (Gemini-powered environmental synthesis cross-referenced with SPC products, Day 1 outlooks, active MDs, and nearby watches), searchable tornado forensics archive, NEXRAD Level 2 downloader, historical radar loop GIFs for any location/time (/radarhistory), and IEM-based tornado analytics.
System: Real-time /status dashboard, owner-only /taskmgr and /logs monitoring, dual-endpoint watchdog, leader-election failover with self-hosted Redis (via Tailscale), SQLite durability, optional Syncthing event archive replication, and a Rust hybrid core (Phases 1–8) that accelerates VAD hodograph math, S3 VAD data fetching, VTEC parsing, XXH3 image hashing, NWWS product ID normalization, haversine distance queries, VAD storm-mode calculations (shear_mag, sr_flow, clip_profile), and batch spatial joins (find_nearest_stations_batch, points_in_polygon_counts). All Rust paths fall back to pure Python if the extension is unavailable.
- Python 3.10+ or Docker
- Discord bot token (Discord Developer Portal)
- Discord channel IDs for SPC/model posts
- A non-default
FAILOVER_TOKEN(required at startup) - Local Redis 7+ for high-availability failover and shared operational state (single-node installs skip this)
mkdir spc-bot && cd spc-bot
curl -O https://raw.githubusercontent.com/full-bars/spc-bot/main/docker-compose.yml
curl -O https://raw.githubusercontent.com/full-bars/spc-bot/main/.env.example
cp .env.example .env
# Edit .env with your Discord token and channel IDs
docker compose up -dMinimum required .env for a single-node install:
DISCORD_TOKEN=your_bot_token_here
SPC_CHANNEL_ID=your_spc_channel_id
MODELS_CHANNEL_ID=your_models_channel_id
GUILD_ID=your_guild_id
FAILOVER_TOKEN=your_non_default_shared_secretADMIN_USER_ID is only required if you want to use the manual /failover control.
git clone https://github.com/full-bars/spc-bot.git
cd spc-bot
sudo ./deploy.shCreates systemd service and bash aliases: spcon, spcoff, spcrestart, spcstatus, spclog, spclog50, spcupdate.
Run two nodes with automatic failover. No HTTP tunnel required. Leader election is backed by a shared local Redis 7+ instance on the primary node; nodes communicate over Tailscale (or any private network where Redis port 6379 is reachable). Requires:
- Redis 7+ running on the primary node
- Tailscale (or equivalent) so the standby can reach the primary's Redis
REDIS_URL=redis://localhost:6379/0on the primary;REDIS_URL=redis://localhost:6379/0on the standby (for local state) plusELECTION_REDIS_URL=redis://<primary-tailscale-ip>:6379/0on the standby (for lease/election traffic)FAILOVER_TOKEN(same value on both nodes)IS_PRIMARY=trueon primary,IS_PRIMARY=falseon standbyADMIN_USER_IDon both nodes if you want to manually designate the primary with/failover
See High Availability & Failover in the wiki for complete setup.
Replicate the tornado events database (cache/events.db) across nodes for seamless standby promotion:
- Install Syncthing on both nodes
- Create a shared folder for
cache/events_sync/ - Add
SYNCTHING_API_KEYandSYNCTHING_FOLDER_IDto.env
The bot automatically manages folder modes (send-only on Primary, receive-only on Standby).
- PROJECT_STRUCTURE.md — Full file tree, module descriptions, architecture overview, testing guide
- CONTRIBUTING.md — Development setup, slash commands, auto-posting mechanics, persistence model, failover details, running tests
- docs/testing.md — Focused test-running guide for local development and CI troubleshooting
- GitHub Wiki — Feature guides (Alerting Authority, Warning Lifecycle, Soundings, Maintenance)
- CHANGELOG.md — Release history and version-by-version improvements
- PRIVACY_POLICY.md — Data collection and usage policies
- TERMS_OF_SERVICE.md — Usage terms and situational awareness disclaimer
Work in progress. Actively developed in free time; expect behavior to evolve between releases.
- discord.py
- aiohttp
- aioboto3
- aiosqlite
- sounderpy
- MetPy
- numpy
- matplotlib
- pytz
- vad-plotter by Tim Supinie
- BowEcho by Fahrenheit Research
- slixmpp — NWWS-OI XMPP connection
- Cartopy — Map projections
- SciPy — Scientific computing
- Shapely — Polygon operations
- pyproj — Coordinate transformations
- Redis — Shared state for failover leader election