~kris/dots

srice

ref: e98f3b030dc24445bd55c68d95d2d81933fd68b3 srice/.local/bin/monitoring/subsea-seismic-monitor -rw-r--r-- 6.2 KiB
e98f3b03 — Kris Yotam chore: sync local state after restore (push updates, no pull) a month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#!/bin/bash
# Subsea Seismic Monitor
# Tracks underwater earthquakes via USGS API
# Alias: seismic

export DISPLAY=:0

# USGS Earthquake API endpoints
api_base="https://earthquake.usgs.gov/fdsnws/event/1/query"
# Feed URLs for quick access
feed_hour="https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson"
feed_day="https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson"
feed_week="https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.geojson"
feed_month="https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_month.geojson"

# Map image
map_url="https://earthquake.usgs.gov/earthquakes/map/images/us_seismicity.png"

# Cache locations
cache_dir="$HOME/.cache/maritime/seismic"
cache_hour="$cache_dir/hour.json"
cache_day="$cache_dir/day.json"
cache_week="$cache_dir/week.json"
cache_map="$cache_dir/seismicity_map.png"
cache_report="$cache_dir/report.txt"

# Ensure cache dir exists
mkdir -p "$cache_dir"

# Fetch and cache data
update() {
    echo "Fetching seismic data from USGS..."
    curl -sLo "$cache_hour" "$feed_hour" &
    curl -sLo "$cache_day" "$feed_day" &
    curl -sLo "$cache_week" "$feed_week" &
    wait
    generate_report
    notify-send -t 3000 "Seismic Data Updated" "$(head -5 "$cache_report")"
}

# Generate human-readable report
generate_report() {
    local count_hour count_day count_week max_mag max_place

    count_hour=$(jq '.metadata.count' "$cache_hour" 2>/dev/null || echo "0")
    count_day=$(jq '.metadata.count' "$cache_day" 2>/dev/null || echo "0")
    count_week=$(jq '.features | length' "$cache_week" 2>/dev/null || echo "0")

    # Get strongest quake in past week
    max_mag=$(jq -r '[.features[].properties.mag] | max' "$cache_week" 2>/dev/null || echo "N/A")
    max_place=$(jq -r '.features | max_by(.properties.mag) | .properties.place' "$cache_week" 2>/dev/null || echo "Unknown")

    cat > "$cache_report" << EOF
SUBSEA SEISMIC REPORT - $(date '+%Y-%m-%d %H:%M')
═══════════════════════════════════════════════
Events (Last Hour):  $count_hour
Events (Last 24h):   $count_day
Events (Last Week):  $count_week (M2.5+)

Strongest This Week: M$max_mag
Location: $max_place
═══════════════════════════════════════════════
EOF
}

# Query specific parameters
query() {
    local params="format=geojson"
    local min_mag="${1:-2.5}"
    local time_range="${2:-day}"
    local start_time end_time

    end_time=$(date -u +%Y-%m-%dT%H:%M:%S)
    case "$time_range" in
        hour) start_time=$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) ;;
        day)  start_time=$(date -u -d '1 day ago' +%Y-%m-%dT%H:%M:%S) ;;
        week) start_time=$(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%S) ;;
        month) start_time=$(date -u -d '30 days ago' +%Y-%m-%dT%H:%M:%S) ;;
    esac

    curl -s "${api_base}?${params}&starttime=${start_time}&endtime=${end_time}&minmagnitude=${min_mag}"
}

# List recent earthquakes
list_recent() {
    local count="${1:-10}"
    echo "Recent Seismic Events (Top $count):"
    echo "════════════════════════════════════"
    jq -r ".features[:$count][] | \"M\(.properties.mag | tostring | .[0:3]) | \(.properties.place) | \(.properties.time / 1000 | strftime(\"%Y-%m-%d %H:%M\"))\"" "$cache_day" 2>/dev/null
}

# Filter by ocean basin (approximate bounding boxes)
filter_ocean() {
    local ocean="$1"
    local minlat maxlat minlon maxlon

    case "$ocean" in
        pacific|P)
            minlat=-60; maxlat=60; minlon=100; maxlon=-100
            ;;
        atlantic|A)
            minlat=-60; maxlat=60; minlon=-80; maxlon=0
            ;;
        indian|I)
            minlat=-60; maxlat=30; minlon=20; maxlon=120
            ;;
        arctic|AR)
            minlat=66; maxlat=90; minlon=-180; maxlon=180
            ;;
        *)
            echo "Unknown ocean: $ocean"
            echo "Use: P (Pacific), A (Atlantic), I (Indian), AR (Arctic)"
            return 1
            ;;
    esac

    echo "Seismic events in $ocean basin:"
    jq -r ".features[] | select(.geometry.coordinates[1] >= $minlat and .geometry.coordinates[1] <= $maxlat) | \"M\(.properties.mag) | \(.properties.place)\"" "$cache_day" 2>/dev/null | head -20
}

# Show seismicity map
show_map() {
    setsid -f mpv --title="Global Seismicity" --autofit=70% "$cache_map"
}

# Display help
help() {
    cat << EOF
Subsea Seismic Monitor - USGS Earthquake Tracker
Usage: seismic [OPTION]

Options:
  update, u          Update seismic data from USGS
  list [N]           List N most recent events (default: 10)
  report, r          Show current seismic report
  map, m             Show global seismicity map
  ocean, -o BASIN    Filter by ocean (P/A/I/AR)
  query MAG TIME     Custom query (mag threshold, time: hour/day/week)
  help, h            Show this help

Ocean Basins:
  P   Pacific Ocean
  A   Atlantic Ocean
  I   Indian Ocean
  AR  Arctic Ocean

Examples:
  seismic list 20        # Show 20 most recent quakes
  seismic -o P           # Pacific basin events
  seismic query 4.0 week # M4.0+ events this week

Data Source: USGS Earthquake Hazards Program
EOF
}

# Status bar output
tobar() {
    local count
    count=$(jq '.metadata.count' "$cache_day" 2>/dev/null || echo "?")
    echo " $count"
}

# Handle arguments
case "$1" in
    u*) update ;;
    list|l) shift; list_recent "$1" ;;
    report|r) cat "$cache_report" 2>/dev/null || echo "Run 'seismic update' first" ;;
    map|m) show_map ;;
    ocean|-o) shift; filter_ocean "$1" ;;
    query|q) shift; query "$1" "$2" | jq '.' ;;
    h*|--help) help ;;
    "") tobar ;;
    *) help ;;
esac

# Status bar click handlers
case $BLOCK_BUTTON in
    1)
        [ -f "$cache_report" ] || update
        notify-send -t 60000 "Seismic Activity" "$(cat "$cache_report")"
        ;;
    2) update ;;
    3)
        notify-send -t 60000 "Recent Earthquakes" "$(list_recent 8)"
        ;;
    4) show_map ;;
    5) notify-send -t 60000 "Seismic Help" "L-click: Report | M-click: Update | R-click: List | Scroll: Map" ;;
    6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac