signalk-lift-header
v0.1.0
Published
Signal K plugin that detects wind lifts and headers while beating and notifies you when to consider tacking.
Maintainers
Readme
signalk-lift-header
A Signal K server plugin that detects wind lifts and headers while you are beating to windward, and notifies you when a sustained header suggests it may be time to tack.
What it does
While close-hauled, the plugin watches true wind direction against a rolling baseline and works out, for your current tack, whether the wind is lifting you (letting you point higher) or heading you (knocking you down). When a shift is large enough and holds long enough, it raises a Signal K notification.
The detection is tack-aware: the same wind veer is a lift on one tack and a header on the other, and the plugin accounts for that automatically.
How it works
- Tack is derived from the true wind angle (
TWD − heading): wind from starboard ⇒ starboard tack. - A baseline wind direction is kept as a rolling circular average over a configurable window (vector-averaged, so it is correct across the 359°→1° wrap). The baseline deliberately excludes the most recent sustained duration of samples — it represents the wind before the shift being evaluated — so a genuine persistent header stays detectable instead of being silently absorbed as "the new normal."
- The shift is the current wind direction relative to that baseline (veer = positive, back = negative).
- Lift/header =
shift × sign(TWA). Positive is a lift, negative is a header. - It only runs when you are actually beating (true wind angle inside a configurable cone) and moving (above a minimum speed), and it resets the baseline on a tack change so the swing across the tack is not reported as a shift.
Requirements
- Signal K server (Node.js 20+)
- The boat must publish true wind direction on
environment.wind.directionTrueand heading onnavigation.headingTrue(these are the defaults; both source paths are configurable).
Apparent-wind-only boats: if your instruments only provide apparent wind, install a plugin such as
signalk-derived-datato computeenvironment.wind.directionTruefirst. Deriving true wind from apparent is intentionally out of scope here.
Installation
From the Signal K App Store, search for Lift / Header Detector (once published).
For development, link it into your server:
npm install
npm run build
npm link
cd ~/.signalk
npm link signalk-lift-headerThen enable and configure it under Server → Plugin Config.
Configuration
| Option | Default | Meaning |
| --- | --- | --- |
| True wind direction path | environment.wind.directionTrue | Source path for true wind direction |
| Heading path | navigation.headingTrue | Source path for heading |
| Boat speed path | navigation.speedThroughWater | Source path for speed gating |
| Baseline window (seconds) | 120 | Rolling period for the wind baseline |
| Shift threshold (degrees) | 10 | Magnitude that counts as a lift/header |
| Sustained duration (seconds) | 30 | How long a shift must hold before notifying |
| Beating cone (degrees) | 60 | Only active when |TWA| is within this |
| Minimum boat speed (knots) | 1 | Detector idles below this speed |
| Notify on sustained headers | true | Fire a notification on headers |
| Notify on sustained lifts | true | Fire a notification on lifts |
| Notification methods | visual, sound | Signal K notification methods |
Dashboard
The plugin ships a self-contained webapp served by the Signal K server at
http://{server}:3000/signalk-lift-header (it also appears in the server's
Webapps menu as Lift / Header).
It shows a tack-aware lift/header gauge — needle to the right (green) for a lift, to the left (red) for a header — with the current magnitude, tack, signed wind shift (veer/back), live true wind direction, and the rolling baseline. A banner appears on a sustained header ("consider tacking"). There is a Night mode (red-on-black, to protect night vision) and the page auto-reconnects to the server.
The webapp has no external dependencies (no CDN), so it works fully offline at sea. It subscribes to the plugin's own Signal K paths over the streaming API.
Emitted Signal K paths
| Path | Units | Description |
| --- | --- | --- |
| navigation.sailing.tack | "port" / "starboard" | Current tack |
| environment.wind.directionTrue.reference | rad | Rolling baseline wind direction |
| navigation.sailing.windShift | rad | Signed shift vs baseline (+ veer) |
| navigation.sailing.liftHeader | rad | Signed lift/header (+ lift, − header) |
| notifications.navigation.sailing.windShift | — | Notification on sustained lift/header |
All angles are emitted in radians, per the Signal K convention.
Development
npm install
npm run build # compile src -> plugin/
npm test # compile and run the detector unit testsThe detection math lives in src/detector.ts as pure functions and a small
stateful class, kept separate from the server glue in src/index.ts so the
sign conventions can be unit-tested without a running server.
License
Apache-2.0
