186 lines
5.4 KiB
Bash
Executable File
186 lines
5.4 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, -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"`
|
|
OUTPUT_FILE="raw_ais_"$DateFichier".log"
|
|
|
|
# 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 -n -H "Sec-WebSocket-Protocol: json" -v "$WEBSOCKET_URL" - | process_message
|