ais/ais_query.sh
2025-09-30 14:09:56 +02:00

189 lines
5.5 KiB
Bash
Executable File

#!/bin/sh
# AIS Stream Ship Position Query Script
# Uses websocat to connect to aisstream.io and query ship position data
# Requires: websocat command-line tool and a valid aisstream.io API key
# Configuration variables - Edit these as needed
API_KEY="${AIS_API_KEY:-8d32f42f3d7fa506ed5ed549d29279580b99303b}"
WEBSOCKET_URL="wss://stream.aisstream.io/v0/stream"
# Default bounding box (worldwide coverage)
# Format: [[lat1, lon1], [lat2, lon2]]
# Current setting covers the entire world
BOUNDING_BOX='[[[-90,0],[5,60]]]'
#BOUNDING_BOX='[[[-90, -180], [90, 180]]]'
# Optional: Filter by specific ship MMSI numbers (up to 50)
# Leave empty for all ships
SHIP_MMSI_FILTER='["227397210"]'
# Optional: Filter by message types (default: PositionReport)
# Available types: PositionReport, ShipStaticData, BaseStationReport, etc.
MESSAGE_TYPE_FILTER='["PositionReport"]'
# Output file for logging (optional)
DateFichier=$(date +"%Y%m%d-%H%M%S")
dir=$(dirname $0)"/data"
OUTPUT_FILE="$dir/raw_ais_$DateFichier.log"
mkdir -p "$dir"
# Function to display usage information
show_usage() {
cat << EOF
Usage: $0 [OPTIONS]
Query AIS ship position data from aisstream.io using websocat
OPTIONS:
-k, --api-key KEY Set API key (can also use AIS_API_KEY environment variable)
-b, --bbox BBOX Set bounding box in JSON format
Example: '[[[25.0, -80.0], [26.0, -79.0]]]'
-m, --mmsi MMSI_LIST Filter by MMSI numbers in JSON array format
Example: '["123456789", "987654321"]'
-t, --types TYPES Filter by message types in JSON array format
Example: '["PositionReport", "ShipStaticData"]'
-o, --output FILE Save output to file (in addition to stdout)
-h, --help Show this help message
EXAMPLES:
# Basic usage with API key from environment
export AIS_API_KEY="your_api_key_here"
$0
# Query specific region (Miami area)
$0 -k "your_api_key" -b '[[[25.6, -80.3], [25.8, -80.1]]]'
# Filter specific ships
$0 -k "your_api_key" -m '["368207620", "367719770"]'
# Save output to file
$0 -k "your_api_key" -o ship_positions.json
NOTES:
- API key is required and can be obtained free from aisstream.io
- Subscription message must be sent within 3 seconds of connection
- Bounding box format: [[[lat1, lon1], [lat2, lon2]]]
- Coordinates: latitude (-90 to 90), longitude (-180 to 180)
- Press Ctrl+C to stop the stream
EOF
}
# Function to validate JSON format
validate_json() {
echo "$1" | python3 -c "import sys, json; json.load(sys.stdin)" 2>/dev/null
return $?
}
# Parse command line arguments
while [ $# -gt 0 ]; do
case $1 in
-k|--api-key)
API_KEY="$2"
shift 2
;;
-b|--bbox)
BOUNDING_BOX="$2"
shift 2
;;
-m|--mmsi)
SHIP_MMSI_FILTER="$2"
shift 2
;;
-t|--types)
MESSAGE_TYPE_FILTER="$2"
shift 2
;;
-o|--output)
OUTPUT_FILE="$2"
shift 2
;;
-h|--help)
show_usage
exit 0
;;
*)
echo "Error: Unknown option $1" >&2
show_usage
exit 1
;;
esac
done
# Validate required tools
if ! command -v websocat >/dev/null 2>&1; then
echo "Error: websocat is not installed or not in PATH" >&2
echo "Install websocat from: https://github.com/vi/websocat" >&2
exit 1
fi
# Validate API key
if [ "$API_KEY" = "YOUR_API_KEY_HERE" ] || [ -z "$API_KEY" ]; then
echo "Error: API key is required" >&2
echo "Set AIS_API_KEY environment variable or use -k option" >&2
echo "Get free API key from: https://aisstream.io/authenticate" >&2
exit 1
fi
# Validate JSON formats
#if ! validate_json "$BOUNDING_BOX"; then
# echo "Error: Invalid bounding box JSON format" >&2
# exit 1
#fi
#if ! validate_json "$SHIP_MMSI_FILTER"; then
# echo "Error: Invalid MMSI filter JSON format" >&2
# exit 1
#fi
#if ! validate_json "$MESSAGE_TYPE_FILTER"; then
# echo "Error: Invalid message type filter JSON format" >&2
# exit 1
#fi
# Create subscription message
create_subscription_message() {
echo "{\"APIKey\":\"$API_KEY\",\"BoundingBoxes\":$BOUNDING_BOX,\"FiltersShipMMSI\":$SHIP_MMSI_FILTER}"
}
# Function to process AIS messages
process_message() {
if [ -n "$OUTPUT_FILE" ]; then
# Output to both stdout and file
tee -a "$OUTPUT_FILE"
else
# Output to stdout only
cat
fi
}
# Display connection information
echo "Connecting to AIS Stream..."
echo "WebSocket URL: $WEBSOCKET_URL"
echo "Bounding Box: $BOUNDING_BOX"
echo "MMSI Filter: $SHIP_MMSI_FILTER"
echo "Message Types: $MESSAGE_TYPE_FILTER"
if [ -n "$OUTPUT_FILE" ]; then
echo "Output File: $OUTPUT_FILE"
# Create output file with timestamp header
#echo "# AIS Stream Data - $(date)" > "$OUTPUT_FILE"
fi
echo "Press Ctrl+C to stop..."
echo "----------------------------------------"
# Setup cleanup on script exit
cleanup() {
echo ""
echo "Connection closed."
if [ -n "$OUTPUT_FILE" ]; then
echo "Data saved to: $OUTPUT_FILE"
fi
}
trap cleanup EXIT INT TERM
# Create subscription message and connect
SUBSCRIPTION_MSG=$(create_subscription_message)
# Connect to websocket and send subscription message
echo "$SUBSCRIPTION_MSG" | websocat --ping-interval 10 --no-close --text -vv "$WEBSOCKET_URL" - | process_message
#-H "Sec-WebSocket-Protocol: json"