DEV Community

Cover image for Follow that ship! With AISstreamer
Juan Julián Merelo Guervós
Juan Julián Merelo Guervós

Posted on

Follow that ship! With AISstreamer

Imagine you're doing OSINT to track the shenanigans of some ship, or simply want to know where your family, who is cruising on the Mediterranean, is more or less precisely once their phones lack signal in the (more or less high) seas... Well, the Automatic data system AIS has you covered. It's mandatory that ships have automatic transmitter that broadcast data on where the ship is, as well as a certain amount of additional data, like destination.

This data is available in several per-pay and free APIs. A good one, which is for the time being experimental, is AISstream. This is a streaming API: you connect to a websocket, that sends you event; it makes sense, since continuous polling would probably bring down any server. Still, you have to set up some stuff, look for the correct library, and so on... AISstreamer (which tries, and fails, to create a portmanteau between steamer and streamer) has you covered.

Install it via

npm i aisstreamer
Enter fullscreen mode Exit fullscreen mode

And you're good to go with this:

import { AIStrack } from "AISstreamer";
/** API_KEY needs to be defined as an environment variable */
const API_KEY = process.env.AISSTREAM_API_KEY;

/** The exact ship name needs to be used; this might include the company name */
const SHIP_NAME = process.env.SHIP_NAME.toUpperCase();

AIStrack(API_KEY, SHIP_NAME);
Enter fullscreen mode Exit fullscreen mode

There's a single function in the API. It takes two mandatory arguments, the API key (which you will have assigned to the environment variable AISSTREAM_API_KEY) and the ship name (environment variable SHIP_NAME). AISStrack will print the whole message that includes this ship, via its default callback that simply does that, printing the variable; the other default is the bounding box where you want to look: by default it's the whole world, you can reduce it and pass it as the third argument.

Since the default callback function prints the latest AIS message the ship has emitted, it will go more or less like this:

 {
  Message: {
    ShipStaticData: {
      AisVersion: 2,
      CallSign: 'ZGIJ3',
      Destination: 'ANTIBES',
      Dimension: [Object],
      Dte: false,
      Eta: [Object],
      FixType: 3,
      ImoNumber: 9794549,
      MaximumStaticDraught: 3.3,
      MessageID: 5,
      Name: 'PAPA',
      RepeatIndicator: 0,
      Spare: false,
      Type: 37,
      UserID: 319156300,
      Valid: true
    }
  },
  MessageType: 'ShipStaticData',
  MetaData: {
    MMSI: 319156300,
    ShipName: 'PAPA',
    latitude: 43.587181666666666,
    longitude: 7.130946666666667,
    time_utc: '2023-05-10 11:46:52.509865357 +0000 UTC'
  }
}
Enter fullscreen mode Exit fullscreen mode

Generally you will find two types of position messages: ShipStaticData, which, if I understand it correctly, is emitted when the ship is anchored, and PositionReport. AISstream does a good job of picking up earth stations, but apparently not satellites, so you will not always be able to track the position, only when it's close to one of them. At any rate, the most interesting piece of information is in the MetaData key, which is common to all messages: you have the latitude and longitude, which tell you where the ship is. From this static data you can also glean a couple of bits of data: Destination as well as Eta or estimated time of arrival (I guess, didn't check this much more).

The PositionReport do have a TrueHeading and NavigationalStatus, which you can also use to predict future position, I guess (I haven't really tried).

The possibilities are endless, from the simple, which is tracking and saving a ship's position, to the more advanced, like tracking a whole fleet.

And this is just the first version; future versions might include multi-ship tracking, automatic messages based on type of message, and a Lot of Cool Stuff (as well as your suggestions here or anywhere.

Top comments (0)