Initial commit: OpenClaw ops workspace
This commit is contained in:
89
skills/capmetro-monitor/scripts/monitor.sh
Executable file
89
skills/capmetro-monitor/scripts/monitor.sh
Executable file
@@ -0,0 +1,89 @@
|
||||
#!/bin/bash
|
||||
# Route 5 smart monitor — determines direction by time of day, launches background watcher
|
||||
# Usage: bash monitor.sh [channel_id]
|
||||
# Before 11 AM CST → Eastbound (morning commute)
|
||||
# After 11 AM CST → Westbound (evening commute)
|
||||
set -eo pipefail
|
||||
|
||||
CHANNEL="${1:-1467247377743347953}"
|
||||
TU_URL="https://data.texas.gov/download/mqtr-wwpy/application%2Fjson"
|
||||
|
||||
STATE_DIR="/home/node/.openclaw/workspace/skills/capmetro-monitor/memory"
|
||||
mkdir -p "$STATE_DIR"
|
||||
|
||||
NOW=$(date +%s)
|
||||
CST_HOUR=$(TZ=America/Chicago date +%H)
|
||||
|
||||
if [ "$CST_HOUR" -lt 11 ]; then
|
||||
DIRECTION=0
|
||||
DIR_NAME="Eastbound"
|
||||
FIRST_STOP="5854"
|
||||
FIRST_STOP_NAME="Anderson/Northcross"
|
||||
USER_STOP="964"
|
||||
USER_STOP_NAME="Woodrow/Choquette"
|
||||
TRAVEL_FIRST_TO_USER=446 # 7m26s
|
||||
WALK_LEAD=0 # already near stop
|
||||
else
|
||||
DIRECTION=1
|
||||
DIR_NAME="Westbound"
|
||||
FIRST_STOP="4606"
|
||||
FIRST_STOP_NAME="Tannehill/Webberville"
|
||||
USER_STOP="5499"
|
||||
USER_STOP_NAME="6th/West"
|
||||
TRAVEL_FIRST_TO_USER=2384 # 39m44s
|
||||
WALK_LEAD=900 # 15 min walk from office
|
||||
HOME_STOP="1072"
|
||||
HOME_STOP_NAME="Woodrow/Dwyce"
|
||||
TRAVEL_USER_TO_HOME=1344 # 22m24s
|
||||
fi
|
||||
|
||||
# Find next departure from first stop
|
||||
TU=$(curl -sL --max-time 10 "$TU_URL" 2>/dev/null)
|
||||
NEXT=$(echo "$TU" | jq --arg dir "$DIRECTION" --arg fs "$FIRST_STOP" --arg now "$NOW" '
|
||||
[.entity[] |
|
||||
select(.tripUpdate.trip.routeId == "5" and (.tripUpdate.trip.directionId | tostring) == $dir) |
|
||||
{
|
||||
tripId: .tripUpdate.trip.tripId,
|
||||
depart: ([.tripUpdate.stopTimeUpdate[] | select(.stopId == $fs) | (.departure.time // .arrival.time)] | .[0])
|
||||
}
|
||||
] | [.[] | select(.depart != null and (.depart | tonumber) > ($now | tonumber))]
|
||||
| sort_by(.depart | tonumber) | .[0]' 2>/dev/null)
|
||||
|
||||
TRIP_ID=$(echo "$NEXT" | jq -r '.tripId // empty')
|
||||
DEPART_TS=$(echo "$NEXT" | jq -r '.depart // empty')
|
||||
|
||||
if [ -z "$TRIP_ID" ] || [ -z "$DEPART_TS" ]; then
|
||||
echo '{"ok":false,"error":"No upcoming Route 5 departures found"}'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DEPART_CST=$(TZ=America/Chicago date -d "@$DEPART_TS" +"%I:%M %p" 2>/dev/null)
|
||||
MINS_AWAY=$(( (DEPART_TS - NOW) / 60 ))
|
||||
|
||||
# Export config for the watcher
|
||||
export DIRECTION DIR_NAME FIRST_STOP FIRST_STOP_NAME USER_STOP USER_STOP_NAME
|
||||
export TRAVEL_FIRST_TO_USER WALK_LEAD TRIP_ID DEPART_TS CHANNEL
|
||||
export HOME_STOP HOME_STOP_NAME TRAVEL_USER_TO_HOME
|
||||
|
||||
echo "{\"ok\":true,\"direction\":\"$DIR_NAME\",\"tripId\":\"$TRIP_ID\",\"firstStopDepart\":\"$DEPART_CST\",\"minsUntilDepart\":$MINS_AWAY,\"userStop\":\"$USER_STOP_NAME\"}"
|
||||
|
||||
# Kill any existing watcher
|
||||
PID_FILE="$STATE_DIR/watcher.pid"
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
OLD_PID=$(cat "$PID_FILE" 2>/dev/null)
|
||||
if [ -n "$OLD_PID" ] && kill -0 "$OLD_PID" 2>/dev/null; then
|
||||
kill "$OLD_PID" 2>/dev/null || true
|
||||
fi
|
||||
rm -f "$PID_FILE"
|
||||
fi
|
||||
|
||||
# Dynamic timeout: time until departure + 5 min buffer for delays
|
||||
WAIT_SECS=$(( DEPART_TS - NOW + 300 ))
|
||||
[ "$WAIT_SECS" -lt 900 ] && WAIT_SECS=900 # minimum 15 min
|
||||
|
||||
# Calculate MAX_POLLS for the watcher (poll every 20s)
|
||||
export MAX_POLLS=$(( WAIT_SECS / 20 ))
|
||||
|
||||
SCRIPT_DIR="$(dirname "$0")"
|
||||
nohup timeout "$WAIT_SECS" bash "$SCRIPT_DIR/watch-departure-v2.sh" > /dev/null 2>&1 &
|
||||
echo $! > "$PID_FILE"
|
||||
Reference in New Issue
Block a user