Initial commit: OpenClaw ops workspace
This commit is contained in:
84
skills/capmetro-monitor/scripts/watch-departure-v2.sh
Executable file
84
skills/capmetro-monitor/scripts/watch-departure-v2.sh
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/bin/bash
|
||||
# Route 5 departure watcher v2 — direction-aware, runs in background
|
||||
# Called by monitor.sh with env vars set
|
||||
set -eo pipefail
|
||||
|
||||
VP_URL="https://data.texas.gov/download/cuc7-ywmd/application%2Fjson"
|
||||
TOKEN=$(printenv DISCORD_BOT_TOKEN)
|
||||
MAX_POLLS=${MAX_POLLS:-40}
|
||||
POLL_INTERVAL=20
|
||||
PID_FILE="/home/node/.openclaw/workspace/skills/capmetro-monitor/memory/watcher.pid"
|
||||
|
||||
# Clean up PID file on exit (success, timeout, or signal)
|
||||
cleanup() { rm -f "$PID_FILE" 2>/dev/null; }
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
for i in $(seq 1 $MAX_POLLS); do
|
||||
VP=$(curl -sL --max-time 8 "$VP_URL" 2>/dev/null)
|
||||
|
||||
VEHICLE=$(echo "$VP" | jq -c ".entity[] | select(.vehicle.trip.tripId == \"$TRIP_ID\")" 2>/dev/null)
|
||||
|
||||
if [ -z "$VEHICLE" ]; then
|
||||
sleep $POLL_INTERVAL
|
||||
continue
|
||||
fi
|
||||
|
||||
STOP_ID=$(echo "$VEHICLE" | jq -r '.vehicle.stopId')
|
||||
STATUS=$(echo "$VEHICLE" | jq -r '.vehicle.currentStatus')
|
||||
VEH_ID=$(echo "$VEHICLE" | jq -r '.vehicle.vehicle.label')
|
||||
|
||||
# Bus has left the first stop
|
||||
if [ "$STOP_ID" != "$FIRST_STOP" ] || { [ "$STATUS" = "IN_TRANSIT_TO" ] && [ "$STOP_ID" != "$FIRST_STOP" ]; }; then
|
||||
ACTUAL_TS=$(date +%s)
|
||||
ACTUAL_CST=$(TZ=America/Chicago date +"%I:%M %p")
|
||||
DELAY=$((ACTUAL_TS - DEPART_TS))
|
||||
DELAY_MIN=$((DELAY / 60))
|
||||
|
||||
if [ "$DELAY_MIN" -le 0 ]; then
|
||||
STATUS_ICON="🟢"
|
||||
STATUS_TEXT="On time"
|
||||
elif [ "$DELAY_MIN" -le 2 ]; then
|
||||
STATUS_ICON="🟡"
|
||||
STATUS_TEXT="~${DELAY_MIN}min late"
|
||||
else
|
||||
STATUS_ICON="🔴"
|
||||
STATUS_TEXT="${DELAY_MIN}min late"
|
||||
fi
|
||||
|
||||
# Calculate ETAs
|
||||
ETA_USER=$((ACTUAL_TS + TRAVEL_FIRST_TO_USER))
|
||||
ETA_USER_CST=$(TZ=America/Chicago date -d "@$ETA_USER" +"%I:%M %p")
|
||||
|
||||
if [ "$DIRECTION" = "0" ]; then
|
||||
# EASTBOUND: simple alert
|
||||
MSG=$(printf '🚌 **Route 5 %s Departed!**\nBus %s left %s at %s\n%s %s\n📍 ETA at %s: **%s**' \
|
||||
"$DIR_NAME" "$VEH_ID" "$FIRST_STOP_NAME" "$ACTUAL_CST" \
|
||||
"$STATUS_ICON" "$STATUS_TEXT" "$USER_STOP_NAME" "$ETA_USER_CST")
|
||||
else
|
||||
# WESTBOUND: include leave-office time and home ETA
|
||||
LEAVE_TS=$((ETA_USER - WALK_LEAD))
|
||||
LEAVE_CST=$(TZ=America/Chicago date -d "@$LEAVE_TS" +"%I:%M %p")
|
||||
ETA_HOME=$((ACTUAL_TS + TRAVEL_FIRST_TO_USER + TRAVEL_USER_TO_HOME))
|
||||
ETA_HOME_CST=$(TZ=America/Chicago date -d "@$ETA_HOME" +"%I:%M %p")
|
||||
|
||||
MSG=$(printf '🚌 **Route 5 %s Departed!**\nBus %s left %s at %s\n%s %s\n\n🚶 **Leave office by %s** (15 min walk)\n📍 Bus arrives %s: **%s**\n🏠 Home (%s): **%s**' \
|
||||
"$DIR_NAME" "$VEH_ID" "$FIRST_STOP_NAME" "$ACTUAL_CST" \
|
||||
"$STATUS_ICON" "$STATUS_TEXT" \
|
||||
"$LEAVE_CST" "$USER_STOP_NAME" "$ETA_USER_CST" \
|
||||
"$HOME_STOP_NAME" "$ETA_HOME_CST")
|
||||
fi
|
||||
|
||||
curl -s -X POST -H "Authorization: Bot $TOKEN" -H "Content-Type: application/json" \
|
||||
-d "$(jq -n --arg c "$MSG" '{content: $c}')" \
|
||||
"https://discord.com/api/v10/channels/$CHANNEL/messages" > /dev/null
|
||||
exit 0
|
||||
fi
|
||||
|
||||
sleep $POLL_INTERVAL
|
||||
done
|
||||
|
||||
# Timeout
|
||||
SCHED_CST=$(TZ=America/Chicago date -d "@$DEPART_TS" +"%I:%M %p" 2>/dev/null)
|
||||
curl -s -X POST -H "Authorization: Bot $TOKEN" -H "Content-Type: application/json" \
|
||||
-d "{\"content\":\"⚠️ Route 5 $DIR_NAME watcher timed out — could not confirm $SCHED_CST departure.\"}" \
|
||||
"https://discord.com/api/v10/channels/$CHANNEL/messages" > /dev/null
|
||||
Reference in New Issue
Block a user