#!/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) OUTPUT_FILE="$dir/data/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 --text - -H "Sec-WebSocket-Protocol: json" -v autoreconnect:"$WEBSOCKET_URL" | process_message