Rich HTML earthquake email notifier for SeisComP scalert.
When an earthquake is detected, scalert calls this script with event parameters. The script fetches the full event XML from the SeisComP database, builds a detailed HTML email, and sends it via SMTP.
- Rich HTML emails with PTWC-aligned color-coded alert levels (see table below)
- Tsunami alert banners β four-tier system aligned with PTWC (WARNING / ADVISORY / WATCH / INFORMATION)
- Epicenter map generated by
scmapcutwith station triangles (embedded inline in the email) - Distance table to nearest cities and capitals (parsed from SeisComP
cities.xml) - Phase arrivals table with color-coded residuals
- Official bulletin via
scbulletin(autoloc1 / autoloc3 / autoloc3extra / fdsnws) - Travel-time curves (ObsPy TauPy, IASP91 model)
- Waveform plots (optional, requires local FDSNWS dataselect)
- KML attachment for Google Earth
- SeisComP XML attachment β optional, preferred origin with picks, magnitudes, and arrivals
- Google Maps link in the plain-text body
- Configurable magnitude threshold, arrival count, and new-event-only filtering
- Multiple region support β define geographic bounding boxes with per-region thresholds and recipients
- Event cooldown/deduplication β suppress rapid re-notifications as event parameters refine
- Event retraction β automatic cancellation emails when events are set to "not existing"
- Per-event log files β separate log per run (
mceqnotifier_<eventID>_<timestamp>.log) - Configurable log levels β debug / info / warning / error
The email header color and subject line label are determined by magnitude and tsunami risk, whichever yields the higher alert level:
| Level | Color | Magnitude | Tsunami (depth < 100 km) | Action |
|---|---|---|---|---|
| π΄ WARNING | Red | M β₯ 7.0 | M β₯ 7.6 | Dangerous coastal flooding β evacuate if ordered |
| π ADVISORY | Orange | M β₯ 5.5 | M 7.0β7.5 | Strong currents β stay off beaches and harbors |
| π‘ WATCH | Yellow | M β₯ 4.0 | M 6.5β6.9 | Tsunami possible β be prepared to take action |
| π’ INFORMATION | Green | M < 4.0 | M < 6.5 or depth β₯ 100km | No tsunami threat β no action required |
The tsunami banner (WARNING/ADVISORY/WATCH) only appears for shallow events (< 100 km) with M β₯ 6.5. Deep events receive INFORMATION level with no banner.
When an analyst reviews a false or duplicate event in SeisComP and sets its type to not existing, the script automatically sends a retraction email to all applicable recipients. The retraction:
- Uses a distinct
β« CANCELLEDsubject line so it stands out in inboxes - Includes a prominent red banner: "This event has been reviewed and marked as NOT EXISTING"
- Explains possible reasons (false detection, duplicate, analyst review)
- Sends to all matching region recipients (or global recipients)
- Suppresses new events that arrive already marked as
not existing
- SeisComP (>= 4.x) with the following modules available on
$PATH:scxmldumpβ fetches event XML from the databasescmapcutβ generates the epicenter map imagescbulletinβ produces the official bulletin text and KML
- Python 3 via the SeisComP Python environment (
seiscomp-python) - ObsPy β for travel-time curves (
obspy.taup) and optional waveform retrieval - matplotlib and NumPy β for generating plot images
- A running FDSNWS dataselect service (e.g., on
localhost:8081) if you enable waveform plot attachments
Place scalert_mceqnotifier.py and your config file in a directory accessible by scalert. Recommended locations:
Option A β User-level SeisComP config directory (recommended):
This corresponds to @CONFIGDIR@ (~/.seiscomp):
DEST=~/.seiscomp
cp scalert_mceqnotifier.py "$DEST/"
cp scalert_mceqnotifier.cfg.example "$DEST/scalert_mceqnotifier.cfg"
chmod +x "$DEST/scalert_mceqnotifier.py"Option B β System-wide SeisComP config directory:
This corresponds to @SYSTEMCONFIGDIR@ ($SEISCOMP_ROOT/etc):
DEST=$SEISCOMP_ROOT/etc
cp scalert_mceqnotifier.py "$DEST/"
cp scalert_mceqnotifier.cfg.example "$DEST/scalert_mceqnotifier.cfg"
chmod +x "$DEST/scalert_mceqnotifier.py"SeisComP path variables reference:
Variable Default path @ROOTDIR@/opt/seiscomp@SYSTEMCONFIGDIR@/opt/seiscomp/etc@CONFIGDIR@~/.seiscomp@DATADIR@/opt/seiscomp/share@LOGDIR@~/.seiscomp/log
cd $DEST
cp scalert_mceqnotifier.cfg.example scalert_mceqnotifier.cfg
nano scalert_mceqnotifier.cfgEdit at minimum:
| Section | Key | What to set |
|---|---|---|
[smtp] |
user |
Your SMTP username / email address |
[smtp] |
pw |
Your SMTP password (use an App Password for Gmail) |
[smtp] |
from |
Sender email address |
[smtp] |
to |
Comma-separated list of recipient emails |
[seiscomp] |
database |
Your SeisComP database connection string |
[content] |
footer |
Custom footer text for your organization |
Gmail users: You must use an App Password, not your regular Google password. Enable 2-Step Verification first, then generate an App Password.
In scalert.cfg (or via scconfig), set the event script:
# scalert.cfg β if installed under ~/.seiscomp/ (Option A)
scripts.event = @CONFIGDIR@/scalert_mceqnotifier.py
# Or if installed under $SEISCOMP_ROOT/etc/ (Option B)
# scripts.event = @SYSTEMCONFIGDIR@/scalert_mceqnotifier.pyThen restart scalert:
seiscomp restart scalertYou can test the script manually with a known event ID from your database:
seiscomp-python scalert_mceqnotifier.py "Test event" 1 gfz2024abcd 15 5.2Arguments:
| Position | Description |
|---|---|
$1 |
Human-readable description string |
$2 |
1 = new event, 0 = update |
$3 |
SeisComP event public ID |
$4 |
Number of arrivals |
$5 |
Magnitude value (optional) |
The config file scalert_mceqnotifier.cfg must be placed in the same directory as the Python script. All settings have sensible defaults.
| Key | Default | Description |
|---|---|---|
server |
smtp.gmail.com |
SMTP server hostname |
port |
587 |
SMTP port |
ssl |
false |
Use SSL (implicit TLS on port 465) |
tls |
true |
Use STARTTLS (explicit TLS on port 587) |
user |
(empty) | SMTP login username |
pw |
(empty) | SMTP login password |
from |
(same as user) | Sender address |
to |
(empty) | Comma-separated recipient list |
| Key | Default | Description |
|---|---|---|
min_magnitude |
4.0 |
Ignore events below this magnitude |
max_magnitude |
(none) | Ignore events above this magnitude (testing) |
min_arrivals |
0 |
Minimum arrivals to trigger (0 = disabled) |
new_events_only |
false |
If true, skip event updates |
| Key | Default | Description |
|---|---|---|
database |
mysql://sysop:sysop@localhost/seiscomp |
Database URI for scxmldump -d |
| Key | Default | Description |
|---|---|---|
width |
512 |
Map image width in pixels |
height |
512 |
Map image height in pixels |
radius_min |
5 |
Minimum map radius in degrees |
radius_max |
40 |
Maximum map radius in degrees |
auto_radius |
true |
Automatically adjust radius based on magnitude |
| Key | Default | Description |
|---|---|---|
bulletin_format |
autoloc3 |
scbulletin format |
bulletin_enhanced |
true |
Use enhanced bulletin output |
attach_kml |
true |
Attach KML file for Google Earth |
attach_xml |
false |
Attach SeisComP XML (preferred origin, picks, arrivals) |
include_maps_link |
true |
Include Google Maps link in plain-text body |
footer |
Automated Earthquake Notification |
Footer text |
generate_travel_curves |
true |
Attach travel-time curve plot (requires ObsPy) |
generate_waveforms |
false |
Attach waveform plot (requires local FDSNWS) |
fdsnws_url |
http://localhost:8081 |
FDSNWS dataselect base URL |
waveform_pre_secs |
30 |
Seconds before origin for waveform window |
waveform_post_secs |
300 |
Seconds after origin for waveform window |
waveform_max_stations |
8 |
Maximum stations in waveform plot |
max_arrivals_table |
30 |
Maximum rows in phase arrivals table |
| Key | Default | Description |
|---|---|---|
xml |
(auto) | Path to cities.xml (auto-detects from $SEISCOMP_ROOT) |
radius_km |
1000 |
Search radius for nearby cities |
max_count |
10 |
Maximum cities to show |
min_population |
10000 |
Skip non-capitals below this population |
| Key | Default | Description |
|---|---|---|
enabled |
false |
Enable cooldown to suppress rapid re-notifications |
seconds |
300 |
Suppress duplicate notifications within this window |
state_dir |
(tmp) | Directory for cooldown state files |
| Key | Default | Description |
|---|---|---|
level |
info |
Log level: debug, info, warning, error |
log_dir |
(empty) | Directory for per-event log files (empty = disabled) |
Define one or more [region:NAME] sections for geographic filtering. Each region supports a bounding box and per-region overrides. When regions are defined, events outside all regions are silently dropped. When no regions are defined, global filtering applies (backward-compatible).
| Key | Default | Description |
|---|---|---|
enabled |
true |
Enable/disable this region |
lat_min |
(required) | Southern latitude bound |
lat_max |
(required) | Northern latitude bound |
lon_min |
(required) | Western longitude bound |
lon_max |
(required) | Eastern longitude bound |
min_magnitude |
(global value) | Override minimum magnitude for this region |
max_magnitude |
(global value) | Override maximum magnitude for this region |
min_arrivals |
(global value) | Override minimum arrivals for this region |
new_events_only |
(global value) | Override new-events-only for this region |
to |
(global value) | Override recipients for this region |
An event can match multiple regions β each matching region triggers its own notification (with its own recipients).
scalert detects event
β
βΌ
scalert_mceqnotifier.py called with CLI args
β
ββ Global pre-filters: magnitude, arrivals, new_events_only
β
ββ Fetch: scxmldump β full event XML from database
β
ββ Parse: extract origin, magnitude, arrivals, region
β
ββ Generate attachments:
β ββ scmapcut β epicenter map (JPEG)
β ββ TauPy β travel-time curves (PNG)
β ββ FDSNWS β waveform plot (PNG, optional)
β ββ scbulletin --kml β KML file
β
ββ Build: plain-text + rich HTML email
β
ββ Dispatch:
β ββ If regions defined β match epicenter to bounding boxes
β β ββ Per-region: check magnitude, arrivals, cooldown
β β ββ Send to region-specific recipients
β ββ If no regions β global send (backward-compatible)
β
ββ Cooldown: record notification to prevent duplicates
- Never commit
scalert_mceqnotifier.cfgto version control β it contains SMTP credentials - The
.gitignorein this repo excludesscalert_mceqnotifier.cfgby default - Only
scalert_mceqnotifier.cfg.example(with placeholder values) is tracked - For Gmail, always use App Passwords β never your main account password
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0-or-later).
Copyright (C) 2025 Mustafa Comoglu
If you use or modify this software, you must:
- Retain the original copyright notice and license
- Share any modifications under the same license
- Provide source access to users interacting with it over a network