← Open the dashboard About · Data guide · Privacy wind-sensor-data.json

Free Interactive Wind & Boat Speed Dashboard

What this dashboard is for, how to record an apparent-wind log it can read — including straight from a Signal K server — and the short version of the privacy story: your data never leaves your browser.

What the dashboard is for

It turns a log of apparent wind and boat speed into something you can actually read. Load a file and you get:

It is aimed at sailors who want to answer concrete questions after a sail: was that boat speed a gust or good trim, how does apparent angle move against speed on each point of sail, where did the wind field change. It is free, needs no account, and runs entirely in the browser.

Open the dashboard → — the bundled demo log loads first, so you can see every panel before recording anything of your own.

The data file it reads

A JSON object with a data array of records. A plain array of records works too, and so does an object whose first array holds them:

{
  "data": [
    { "datetime": "2026-01-01T10:00:00Z",
      "lat": 12.4115, "lon": 100.0177,
      "sog": 3.2, "heading": 180,
      "windSpeed": 8.1, "windAngle": 45,
      "windGust": 10.4 }
  ]
}
FieldMeaning
datetimeISO date-time — chart labels and popups
lat, londegrees — map, heatmap, wind arrows
sogboat speed over ground, knots
headingvessel heading, degrees, 0–360
windSpeedapparent wind speed, knots
windAngleapparent wind angle in degrees relative to the bow — negative to port, positive to starboard
windGustgust, knots — optional, null is fine

Speeds are interpreted as knots; the unit selectors convert them for display. If your file uses different key names, a one-time field-mapping window opens when you load it. The limit is 25 MB. The i button in the dashboard's data bar opens the same format reference with a Load Sample Data download.

Recording data from a Signal K server

Signal K is the open marine data standard: a gateway or server reads your instruments (NMEA 0183, NMEA 2000, AIS, a connected GPS) and turns them into JSON that any web app can subscribe to over a WebSocket. If your boat already runs a Signal K server, you already have every number this dashboard needs — you just need to record it.

1. Find the server

The entry point is /signalk on the server's host and port (the Node server defaults to port 3000, others use 80/443 or 3443). It answers with the endpoints it supports:

curl http://localhost:3000/signalk

2. Subscribe to the stream

The streaming endpoint sends delta messages — small JSON updates carrying a path and a value for each reading:

ws://localhost:3000/signalk/v1/stream?subscribe=self

3. Record one reading per minute

Save as record-signalk.mjs and run it with Node.js 22 or newer — it uses the built-in WebSocket, so there is nothing to install:

// record-signalk.mjs — sample a Signal K server into dashboard JSON
import { writeFileSync } from 'node:fs';

const SERVER = 'ws://localhost:3000/signalk/v1/stream?subscribe=self';
const INTERVAL_MS = 60_000;            // one reading per minute, like the demo log
const OUT = 'wind-log.json';
const MS_TO_KN = 1.943844;             // Signal K speed unit is m/s
const TO_DEG = 180 / Math.PI;          // Signal K angle unit is radians
const state = {};
const data = [];

const ws = new WebSocket(SERVER);
ws.onmessage = (ev) => {
  const msg = JSON.parse(ev.data);
  if (!msg.updates) return;            // "hello" and heartbeats carry no values
  for (const update of msg.updates) {
    for (const { path, value } of update.values || []) state[path] = value;
  }
};
ws.onopen = () => console.log('recording from ' + SERVER + ' — Ctrl+C stops');

setInterval(() => {
  const pos = state['navigation.position'];
  const sog = state['navigation.speedOverGround'];
  const aws = state['environment.wind.speedApparent'];
  const awa = state['environment.wind.angleApparent'];
  const hdg = state['navigation.headingTrue']
    ?? state['navigation.headingMagnetic']
    ?? state['navigation.courseOverGround'];
  if (!pos || typeof sog !== 'number' || typeof aws !== 'number' ||
      typeof awa !== 'number' || typeof hdg !== 'number') return;

  const rec = {
    datetime: new Date().toISOString(),
    lat: pos.latitude,
    lon: pos.longitude,
    sog: +(sog * MS_TO_KN).toFixed(1),
    heading: Math.round(((hdg * TO_DEG) % 360 + 360) % 360),
    windSpeed: +(aws * MS_TO_KN).toFixed(1),
    windAngle: Math.round(awa * TO_DEG),
    windGust: null                    // no standard Signal K gust key
  };
  data.push(rec);
  writeFileSync(OUT, JSON.stringify({ data }));   // safe to stop with Ctrl+C
  console.log(rec.datetime, rec.windSpeed + ' kn at ' + rec.windAngle + '°');
}, INTERVAL_MS);

When you have enough readings, stop it with Ctrl+C and press Upload statistic in the dashboard's data bar — wind-log.json loads like any other file, mapping window included if your server names things differently.

Units. Signal K publishes speeds in m/s and angles in radians, so the script converts both: m/s → knots, radians → degrees. Apparent wind angle is negative to port in both conventions, so the sign is kept as is. Heading is normalised to 0–360°.

History. A server that keeps a log can replay it through the same protocol — /signalk/v1/playback?startTime=<ISO time>&playbackRate=1 — so this script can record a past sail without the boat leaving the dock. The REST API (/signalk/v1/api/vessels/self) returns the current full model if you prefer to poll.

Other ways to get a file in

Your data stays with you

This dashboard does not collect, store or share your data.

In short: the app visualises your log; it has no mechanism to take it anywhere. Close the tab and nothing of yours remains — except the file you created, which was yours from the start.

← Free Interactive Wind & Boat Speed Dashboard Signal K is documented at signalk.org/specification