signalk-livedepth-plugin 0.3.18 → 0.3.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,46 @@ All notable changes to this project are documented here, newest first. The
4
4
  format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
5
5
  versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.3.20] - 2026-11-07
8
+
9
+ ### Fixed
10
+
11
+ - **An interrupted history rebuild now resumes.** A server or plugin restart
12
+ aborts the rebuild, but the one-time trigger was cleared anyway, so the next
13
+ start did not resume and the rebuild looked finished. An interrupted run now
14
+ leaves the trigger set and continues from the last completed chunk; it is
15
+ cleared only when the rebuild completes (or fails).
16
+
17
+ ## [0.3.19] - 2026-11-07
18
+
19
+ ### Added
20
+
21
+ - **Tide-corrected soundings.** With tide correction on, every depth is reduced
22
+ to a fixed chart datum (LAT or MLLW) using the predicted water level at that
23
+ sample's time and position, so soundings from different days and different
24
+ vessels share one grid. The Slackwater station database ships with the
25
+ plugin, so nothing is downloaded. The chart is told the datum in the plugin
26
+ metadata and stops folding its own live depth onto the corrected grid.
27
+
28
+ ### Changed
29
+
30
+ - **Depth is always read from a Signal K depth path.** The external
31
+ tide-compensated paths (`belowSurfaceTideCompensated`, `…LAT`, `…MLLW`) are
32
+ removed; tide compensation now happens inside the plugin. Point the Depth
33
+ setting at `environment.depth.belowSurface` and turn tide correction on.
34
+ - **The Depth selector is disabled while tide correction is on**, with a note
35
+ that changing the datum clears the grid because the stored cells are depths
36
+ in the old datum.
37
+
38
+ ### Fixed
39
+
40
+ - **A history rebuild no longer races the history provider.** The plugin waits
41
+ up to 30 s for the History API provider to register before falling back to
42
+ the HTTP endpoint, so a rebuild at server start no longer fails instantly.
43
+ - **Older pinned Slackwater versions are supported.** The tide predictor is
44
+ awaited, which works whether `nearestStation` returns a promise or the
45
+ predictor directly.
46
+
7
47
  ## [0.3.18] - 2026-11-02
8
48
 
9
49
  ### Changed
package/README.md CHANGED
@@ -19,6 +19,9 @@ already covered is there to look at the next time you're in the area.
19
19
  server has built up over time — extended live as you move.
20
20
  - **Rebuild from history.** Already have a track recorded on the server? A
21
21
  one-time rebuild fills the map in from it.
22
+ - **Comparable across days.** Optionally reduce every sounding to a fixed
23
+ vertical datum (LAT or MLLW) using the tide predicted at the moment and place
24
+ it was taken, so a depth recorded months ago still means the same thing.
22
25
 
23
26
  ## What you need
24
27
 
@@ -37,7 +40,6 @@ chart's. Open **Layer settings** on its row (or the LiveDepth toolbar button) to
37
40
  choose what it shows:
38
41
 
39
42
  - **Show the layer** — on or off.
40
- - **Depth source** — your own recent track, or the accumulated depth map.
41
43
  - **Shade limit** — the depth the shading runs to; deeper water is left to the
42
44
  chart.
43
45
  - **Isobath interval** — how far apart the depth-contour lines are.
@@ -51,7 +53,16 @@ Depth values are shown in your preferred units.
51
53
  ## Server settings
52
54
 
53
55
  - **Path** — which depth measurement to record (below surface, transducer or
54
- keel).
56
+ keel). Ignored when tide correction is on, which always uses the raw depth
57
+ below the surface.
58
+ - **Tide correction** — store soundings relative to a fixed vertical datum
59
+ instead of the moving surface. Choose chart datum, **LAT** or **MLLW**. LAT
60
+ and MLLW are fixed references at each location, so a corrected depth keeps its
61
+ meaning when you return; chart datum changes with the chart region. Each
62
+ sounding — live, rebuilt from history, or recorded by another vessel — is
63
+ reduced using the tide predicted at its own time and position. Changing the
64
+ datum clears the map, because the stored cells are depths in the old datum;
65
+ run **Rebuild from history** to repopulate it.
55
66
  - **Depth transducer** — where the sounder sits on the hull, so each reading is
56
67
  placed at it rather than at the position the server reports.
57
68
  - **Transducer position correction** — shift readings from the vessel's
@@ -62,9 +73,15 @@ Depth values are shown in your preferred units.
62
73
  ## How it works
63
74
 
64
75
  The plugin runs on your Signal K server and turns each sounding into a
65
- Web-Mercator depth map, keeping the shallowest reading for every spot. A
66
- chartplotter that supports plotter extensions draws it as a map layer, rendering
67
- in the browser. The plugin offers the layer to the chartplotter automatically —
76
+ Web-Mercator depth map, keeping the shallowest reading for every spot. With tide
77
+ correction on it predicts the water level from the station database bundled with
78
+ the plugin (Slackwater) — offline, for any past or future instant — and
79
+ subtracts it before the reading reaches the map; a reading whose tide cannot be
80
+ predicted is skipped rather than stored in the wrong datum. Because the browser
81
+ cannot correct its own live readings, the layer then draws the corrected server
82
+ tiles (refreshed as new soundings arrive) instead of adding the raw live depth on
83
+ top. A chartplotter that supports plotter extensions draws it as a map layer,
84
+ rendering in the browser. The plugin offers the layer to the chartplotter automatically —
68
85
  there's nothing to configure on the chart side.
69
86
 
70
87
  ## Development
@@ -2,6 +2,7 @@ import { Writable } from "stream";
2
2
  import { ServerAPI } from "@signalk/server-api";
3
3
  import { TransducerOffset } from "./tiles/core/index.js";
4
4
  import { Config } from "./config.js";
5
+ import { TideCorrection } from "./tide.js";
5
6
  export interface CollectorOptions {
6
7
  app: ServerAPI;
7
8
  config: Config;
@@ -9,10 +10,17 @@ export interface CollectorOptions {
9
10
  writer: Writable;
10
11
  /** Shift each sounding from the reported position to the transducer. */
11
12
  offset?: TransducerOffset;
13
+ /** Reduce each sounding to a fixed datum, using that sounding's own time and
14
+ * position. */
15
+ tide?: TideCorrection;
12
16
  signal: AbortSignal;
13
17
  }
14
18
  /**
15
19
  * Pair depth with position once and feed the soundings to the tile writer.
20
+ *
21
+ * With tide correction on, the raw depth below the surface is recorded (not the
22
+ * configured depth path, which may already be compensated) and each sounding is
23
+ * reduced to the chosen datum before it reaches the store.
16
24
  */
17
- export declare function createCollector({ app, config, writer, offset, signal, }: CollectorOptions): import("stream-transform").Transformer;
25
+ export declare function createCollector({ app, config, writer, offset, tide, signal, }: CollectorOptions): import("stream-transform").Transformer;
18
26
  //# sourceMappingURL=collector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,MAAM,EAAE,QAAQ,CAAC;IACjB,wEAAwE;IACxE,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,MAAM,EACN,MAAM,EACN,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,0CAkBlB"}
1
+ {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,cAAc,EAAsB,MAAM,WAAW,CAAC;AAG/D,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,MAAM,EAAE,QAAQ,CAAC;IACjB,wEAAwE;IACxE,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B;mBACe;IACf,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,MAAM,EACN,MAAM,EACN,MAAM,EACN,IAAI,EACJ,MAAM,GACP,EAAE,gBAAgB,0CAyBlB"}
package/dist/collector.js CHANGED
@@ -1,15 +1,22 @@
1
1
  import { transform } from "stream-transform";
2
2
  import { createLiveStream, toPrecision } from "./streams/index.js";
3
+ import { recordingDepthPath } from "./tide.js";
3
4
  /**
4
5
  * Pair depth with position once and feed the soundings to the tile writer.
6
+ *
7
+ * With tide correction on, the raw depth below the surface is recorded (not the
8
+ * configured depth path, which may already be compensated) and each sounding is
9
+ * reduced to the chosen datum before it reaches the store.
5
10
  */
6
- export function createCollector({ app, config, writer, offset, signal, }) {
7
- const live = createLiveStream(app, config, offset);
11
+ export function createCollector({ app, config, writer, offset, tide, signal, }) {
12
+ const live = createLiveStream(app, config, offset, recordingDepthPath(config, tide !== undefined));
8
13
  const precise = live.pipe(transform(toPrecision()));
9
- precise.pipe(writer);
14
+ const output = tide ? precise.pipe(transform(tideTransform(tide))) : precise;
15
+ output.pipe(writer);
10
16
  const destroy = () => {
11
17
  live.destroy();
12
18
  precise.destroy();
19
+ output.destroy();
13
20
  writer.destroy();
14
21
  };
15
22
  if (signal.aborted) {
@@ -18,6 +25,18 @@ export function createCollector({ app, config, writer, offset, signal, }) {
18
25
  else {
19
26
  signal.addEventListener("abort", destroy, { once: true });
20
27
  }
21
- return precise;
28
+ return output;
29
+ }
30
+ /**
31
+ * Async stream handler that corrects each sounding. A sounding is dropped when
32
+ * the tide is unavailable, so a datum grid never mixes in a raw depth.
33
+ */
34
+ function tideTransform(tide) {
35
+ return (data, callback) => {
36
+ tide
37
+ .correct(data.longitude, data.latitude, data.timestamp, data.depth)
38
+ .then((depth) => callback(null, depth === undefined ? undefined : { ...data, depth }))
39
+ .catch((error) => callback(error));
40
+ };
22
41
  }
23
42
  //# sourceMappingURL=collector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"collector.js","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAK7C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAYnE;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,GAAG,EACH,MAAM,EACN,MAAM,EACN,MAAM,EACN,MAAM,GACW;IACjB,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAErB,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,OAAO,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC,CAAC;IAEF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,CAAC;IACZ,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"collector.js","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAK7C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAkB,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAgB/D;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,GAAG,EACH,MAAM,EACN,MAAM,EACN,MAAM,EACN,IAAI,EACJ,MAAM,GACW;IACjB,MAAM,IAAI,GAAG,gBAAgB,CAC3B,GAAG,EACH,MAAM,EACN,MAAM,EACN,kBAAkB,CAAC,MAAM,EAAE,IAAI,KAAK,SAAS,CAAC,CAC/C,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC7E,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEpB,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,OAAO,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC,CAAC;IAEF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,CAAC;IACZ,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,IAAoB;IACzC,OAAO,CACL,IAAoB,EACpB,QAAiE,EACjE,EAAE;QACF,IAAI;aACD,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;aAClE,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CACd,QAAQ,CAAC,IAAI,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,CACrE;aACA,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAc,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC;AACJ,CAAC"}
package/dist/config.d.ts CHANGED
@@ -1,8 +1,17 @@
1
1
  import { ServerAPI } from "@signalk/server-api";
2
+ import { TideDatum } from "./tide.js";
2
3
  export type Config = {
3
- /** Which depth datum to record. Signal K already publishes each relative to
4
- * its own reference, so the value is stored as-is. */
4
+ /** Which depth measurement to record when tide correction is off. Signal K
5
+ * already publishes each relative to its own reference, so it is stored
6
+ * as-is. With tide correction on, the raw depth below the surface is used
7
+ * and reduced to {@link Config.tide.datum} instead. */
5
8
  path: (typeof DepthPaths)[number];
9
+ /** Reduce each sounding to a fixed vertical datum, using the predicted tide
10
+ * at that sounding's own time and position. */
11
+ tide?: {
12
+ enabled?: boolean;
13
+ datum?: TideDatum;
14
+ };
6
15
  /** The depth transducer's position on the hull: `y` from the bow, `x` from
7
16
  * the centreline (+starboard). Used only to place a sounding at the
8
17
  * transducer rather than at the position the server reports. */
@@ -40,7 +49,13 @@ export type Config = {
40
49
  vesselFootprint?: boolean;
41
50
  };
42
51
  };
43
- export declare const DepthPaths: readonly ["belowSurface", "belowTransducer", "belowKeel", "belowSurfaceTideCompensated", "belowSurfaceTideCompensatedLAT", "belowSurfaceTideCompensatedMLLW"];
52
+ export declare const DepthPaths: readonly ["belowSurface", "belowTransducer", "belowKeel"];
53
+ /**
54
+ * The form overrides for the saved config. The Depth selector has no effect
55
+ * while tide correction is on (the raw below-surface depth is used), so the
56
+ * admin UI should show it disabled rather than as a live control.
57
+ */
58
+ export declare function formUiSchema(config?: Pick<Config, "tide">): Record<string, object>;
44
59
  export declare function schema(app: ServerAPI): {
45
60
  type: string;
46
61
  description: string;
@@ -49,9 +64,30 @@ export declare function schema(app: ServerAPI): {
49
64
  type: string;
50
65
  title: string;
51
66
  description: string;
52
- enum: readonly ["belowSurface", "belowTransducer", "belowKeel", "belowSurfaceTideCompensated", "belowSurfaceTideCompensatedLAT", "belowSurfaceTideCompensatedMLLW"];
67
+ enum: readonly ["belowSurface", "belowTransducer", "belowKeel"];
53
68
  enumNames: string[];
54
- default?: "belowKeel" | "belowSurface" | "belowSurfaceTideCompensated" | "belowSurfaceTideCompensatedLAT" | "belowSurfaceTideCompensatedMLLW" | "belowTransducer" | undefined;
69
+ default?: "belowKeel" | "belowSurface" | "belowTransducer" | undefined;
70
+ };
71
+ tide: {
72
+ type: string;
73
+ title: string;
74
+ description: string;
75
+ properties: {
76
+ enabled: {
77
+ type: string;
78
+ default: boolean;
79
+ title: string;
80
+ description: string;
81
+ };
82
+ datum: {
83
+ type: string;
84
+ title: string;
85
+ enum: readonly TideDatum[];
86
+ enumNames: string[];
87
+ default: string;
88
+ description: string;
89
+ };
90
+ };
55
91
  };
56
92
  sounder: {
57
93
  type: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,MAAM,MAAM,MAAM,GAAG;IACnB;0DACsD;IACtD,IAAI,EAAE,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;IAClC;;oEAEgE;IAChE,OAAO,EAAE;QACP,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;IACF;kEAC8D;IAC9D,oBAAoB,EAAE,KAAK,GAAG,SAAS,CAAC;IACxC;;;mFAG+E;IAC/E,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IACF;;;gEAG4D;IAC5D,cAAc,CAAC,EAAE;QACf,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,IAAI,CAAC,EAAE;QACL,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,oEAAoE;IACpE,KAAK,CAAC,EAAE;QACN,mEAAmE;QACnE,eAAe,CAAC,EAAE,OAAO,CAAC;KAC3B,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,UAAU,YACrB,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,6BAA6B,EAC7B,gCAAgC,EAChC,iCAAiC,CACzB,CAAC;AAEX,wBAAgB,MAAM,CAAC,GAAG,EAAE,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAoD7B,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,IAAI;YACJ,SAAS;YACT,OAAO;;;YAGP,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,UAAU;gBACR,OAAO;oBACL,IAAI;oBACJ,KAAK;oBACL,WAAW;oBAEX,KAAK;wBAAI,IAAI;;;gBAEf,OAAO;oBACL,IAAI;oBACJ,KAAK;oBACL,WAAW;oBACX,KAAK;wBAAI,IAAI;;;;;;YAKjB,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,UAAU;gBACR,OAAO;oBACL,IAAI;oBACJ,OAAO;oBACP,KAAK;oBACL,WAAW;;gBAGb,OAAO;oBACL,IAAI;oBACJ,OAAO;oBACP,OAAO;oBACP,KAAK;oBACL,WAAW;;gBAGb,MAAM;oBACJ,IAAI;oBACJ,OAAO;oBACP,OAAO;oBACP,KAAK;oBACL,WAAW;;;;;YAMf,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,UAAU;gBACR,GAAG;oBACD,IAAI;oBACJ,OAAO;oBACP,KAAK;oBACL,WAAW;;gBAGb,UAAU;oBACR,IAAI;oBACJ,OAAO;oBACP,KAAK;oBACL,WAAW;;;;;YAMf,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,UAAU;gBACR,eAAe;oBACb,IAAI;oBACJ,OAAO;oBACP,KAAK;oBACL,WAAW;;;;;EAOtB"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -1,11 +1,17 @@
1
+ import { TIDE_DATUMS } from "./tide.js";
1
2
  export const DepthPaths = [
2
3
  "belowSurface",
3
4
  "belowTransducer",
4
5
  "belowKeel",
5
- "belowSurfaceTideCompensated",
6
- "belowSurfaceTideCompensatedLAT",
7
- "belowSurfaceTideCompensatedMLLW",
8
6
  ];
7
+ /**
8
+ * The form overrides for the saved config. The Depth selector has no effect
9
+ * while tide correction is on (the raw below-surface depth is used), so the
10
+ * admin UI should show it disabled rather than as a live control.
11
+ */
12
+ export function formUiSchema(config) {
13
+ return config?.tide?.enabled ? { path: { "ui:disabled": true } } : {};
14
+ }
9
15
  export function schema(app) {
10
16
  const defaultPath = DepthPaths.find((path) => app.getSelfPath(`environment.depth.${path}.value`));
11
17
  // A `default` is attached only when present: `default: undefined` survives in
@@ -20,18 +26,40 @@ export function schema(app) {
20
26
  path: {
21
27
  type: "string",
22
28
  title: "Depth",
23
- description: "Which depth datum to record. Signal K publishes each relative to its own reference, so no draft or transducer offset is needed here.",
29
+ description: "Which depth measurement to record. Signal K publishes each relative to its own reference, so no draft or transducer offset is needed here. Disabled while tide correction is on: the raw depth below the surface is used then and reduced to the chosen datum.",
24
30
  enum: DepthPaths,
25
31
  enumNames: [
26
32
  "Depth below surface",
27
33
  "Depth below transducer",
28
34
  "Depth below keel",
29
- "Depth below surface (tide compensated)",
30
- "Depth below surface (tide compensated, LAT)",
31
- "Depth below surface (tide compensated, MLLW)",
32
35
  ],
33
36
  ...(defaultPath === undefined ? {} : { default: defaultPath }),
34
37
  },
38
+ tide: {
39
+ type: "object",
40
+ title: "Tide correction",
41
+ description: "Store soundings relative to a fixed vertical datum by subtracting the predicted tide at each sounding's own time and position. A depth below the surface rises and falls with the tide; a depth below a datum does not, so it still means the same thing when you return months later. When this is on, depth is always calculated using 'Depth below surface'. Changing the datum clears the depth map, because the stored cells are depths in the old datum.",
42
+ properties: {
43
+ enabled: {
44
+ type: "boolean",
45
+ default: false,
46
+ title: "Correct samples for tides?",
47
+ description: "Off records the selected Depth as measured. On records the depth below the surface reduced to the datum below.",
48
+ },
49
+ datum: {
50
+ type: "string",
51
+ title: "Datum",
52
+ enum: TIDE_DATUMS,
53
+ enumNames: [
54
+ "Chart datum / local datum",
55
+ "Lowest Astronomical Tide (LAT)",
56
+ "Mean Lower Low Water (MLLW)",
57
+ ],
58
+ default: "LAT",
59
+ description: "LAT and MLLW are fixed references at each location, so a corrected sounding keeps its meaning wherever and whenever you return. Chart datum is set per chart region, so a map corrected to it cannot be compared across regions; LAT and MLLW are the predictable choices.",
60
+ },
61
+ },
62
+ },
35
63
  sounder: {
36
64
  type: "object",
37
65
  title: "Depth Transducer",
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/history.d.ts CHANGED
@@ -3,12 +3,16 @@ import { HistoryApi, ValuesResponse } from "@signalk/server-api/history";
3
3
  export type HistoryAPIOptions = {
4
4
  app: ServerAPI;
5
5
  host?: string;
6
+ /** How long to wait for a provider to register, in milliseconds. */
7
+ waitMs?: number;
8
+ /** Delay between provider checks, in milliseconds. */
9
+ pollMs?: number;
6
10
  };
7
11
  /**
8
12
  * The History Provider API is new and may not be available. This uses a provider if available,
9
13
  * and otherwise falls back to direct HTTP access if available.
10
14
  */
11
- export declare function getHistoryAPI({ app, port, host, }: HistoryAPIOptions): Promise<HistoryApi | undefined>;
15
+ export declare function getHistoryAPI({ app, port, host, waitMs, pollMs, }: HistoryAPIOptions): Promise<HistoryApi | undefined>;
12
16
  /**
13
17
  * Build a lookup from SignalK path to its column index in a history `DataRow`.
14
18
  *
@@ -1 +1 @@
1
- {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAGL,UAAU,EAIV,cAAc,EACf,MAAM,6BAA6B,CAAC;AAKrC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,SAAS,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAMF;;;GAGG;AACH,wBAAsB,aAAa,CAAC,EAClC,GAAG,EAEH,IAAqE,EACrE,IAA8D,GAC/D,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CA2DrD;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG,SAAS,EAC5C,SAAS,EAAE,SAAS;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,EAAE,GACnC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAOrB"}
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAGL,UAAU,EAIV,cAAc,EACf,MAAM,6BAA6B,CAAC;AAKrC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,SAAS,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AASF;;;GAGG;AACH,wBAAsB,aAAa,CAAC,EAClC,GAAG,EAEH,IAAqE,EACrE,IAA8D,EAC9D,MAAiC,EACjC,MAAiC,GAClC,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAwErD;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG,SAAS,EAC5C,SAAS,EAAE,SAAS;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,EAAE,GACnC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAOrB"}
package/dist/history.js CHANGED
@@ -1,23 +1,24 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { BATHY_EPOCH } from "./constants.js";
3
3
  import fetch from "./fetch.js";
4
+ const DEFAULT_PROVIDER_WAIT_MS = 30_000;
5
+ const DEFAULT_PROVIDER_POLL_MS = 500;
4
6
  /**
5
7
  * The History Provider API is new and may not be available. This uses a provider if available,
6
8
  * and otherwise falls back to direct HTTP access if available.
7
9
  */
8
10
  export async function getHistoryAPI({ app,
9
11
  // @ts-expect-error: app.config is not a public API
10
- port = Number(process.env.PORT) || app.config?.settings?.port || 3000, host = process.env.SIGNALK_HOST ?? `http://localhost:${port}/`, }) {
11
- try {
12
- // Try to get the built-in history provider API first. It either returns the API or throws
13
- // an error if no provider is configured. It will also throw if the API is not available.
14
- const api = await app.getHistoryApi();
12
+ port = Number(process.env.PORT) || app.config?.settings?.port || 3000, host = process.env.SIGNALK_HOST ?? `http://localhost:${port}/`, waitMs = DEFAULT_PROVIDER_WAIT_MS, pollMs = DEFAULT_PROVIDER_POLL_MS, }) {
13
+ // Plugins start in an unspecified order, so this plugin can reach the History
14
+ // API before the provider plugin has registered. Wait briefly for it instead
15
+ // of falling through to the HTTP path, which may not be reachable from the
16
+ // server's own network namespace.
17
+ const api = await waitForProvider();
18
+ if (api) {
15
19
  app.debug("Using built-in history provider");
16
20
  return api;
17
21
  }
18
- catch {
19
- // History provider API not available or no provider configured.
20
- }
21
22
  try {
22
23
  await getContexts({
23
24
  from: BATHY_EPOCH,
@@ -30,6 +31,21 @@ port = Number(process.env.PORT) || app.config?.settings?.port || 3000, host = pr
30
31
  return;
31
32
  }
32
33
  return { getValues, getContexts, getPaths };
34
+ async function waitForProvider() {
35
+ if (typeof app.getHistoryApi !== "function")
36
+ return undefined;
37
+ const deadline = Date.now() + waitMs;
38
+ for (;;) {
39
+ try {
40
+ return await app.getHistoryApi();
41
+ }
42
+ catch {
43
+ if (Date.now() >= deadline)
44
+ return undefined;
45
+ await new Promise((resolve) => setTimeout(resolve, pollMs));
46
+ }
47
+ }
48
+ }
33
49
  async function get(path, params = {}) {
34
50
  const url = new URL(path, new URL("/signalk/v2/api/history/", host));
35
51
  url.search = new URLSearchParams(params).toString();
@@ -1 +1 @@
1
- {"version":3,"file":"history.js","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,MAAM,YAAY,CAAC;AAW/B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAClC,GAAG;AACH,mDAAmD;AACnD,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,IAAI,IAAI,EACrE,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,oBAAoB,IAAI,GAAG,GAC5C;IAClB,IAAI,CAAC;QACH,0FAA0F;QAC1F,yFAAyF;QACzF,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,aAAc,EAAE,CAAC;QACvC,GAAG,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QAC7C,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,gEAAgE;IAClE,CAAC;IAED,IAAI,CAAC;QACH,MAAM,WAAW,CAAC;YAChB,IAAI,EAAE,WAAW;YACjB,EAAE,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE;SAC3B,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,mCAAmC,EAAE,IAAI,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;IAE5C,KAAK,UAAU,GAAG,CAAC,IAAY,EAAE,MAAM,GAA2B,EAAE;QAClE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,0BAA0B,EAAE,IAAI,CAAC,CAAC,CAAC;QACrE,GAAG,CAAC,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;QAEpD,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEzC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,mBAAmB,GAAG,KAAK,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAC1D,CAAC;QACJ,CAAC;QAED,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAED,SAAS,SAAS,CAAC,EACjB,SAAS,EACT,GAAG,KAAK,EACM;QACd,OAAO,GAAG,CAAC,QAAQ,EAAE;YACnB,GAAG,KAAK;YACR,KAAK,EAAE,SAAS;iBACb,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;iBACzD,IAAI,CAAC,GAAG,CAAC;SACb,CAAC,CAAC;IACL,CAAC;IAED,SAAS,WAAW,CAAC,KAAuB;QAC1C,OAAO,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,SAAS,QAAQ,CAAC,KAAoB;QACpC,OAAO,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAC3B,MAA4C,EAC5C,SAAoC;IAEpC,MAAM,MAAM,GAAG,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QAC3B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"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"}
package/dist/plugin.d.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  import { ServerAPI, Plugin } from "@signalk/server-api";
2
2
  import { TransducerOffset } from "./tiles/core/index.js";
3
3
  import { Config } from "./config.js";
4
+ /** How a history rebuild ended. Only a completed or failed run consumes the
5
+ * one-time `seed.run` trigger; an interrupted run leaves it set so the next
6
+ * start resumes from the stored cursor. */
7
+ export type SeedOutcome = "completed" | "failed" | "aborted" | "skipped";
4
8
  /** The vessel's length overall, for locating the reference point the server
5
9
  * reports (the CCRP is midships).
6
10
  *
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAgB,MAAM,qBAAqB,CAAC;AAEtE,OAAO,EAAE,gBAAgB,EAAa,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAU,MAAM,EAAE,MAAM,aAAa,CAAC;AAa7C;;;;;;;mEAOmE;AACnE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAWpE;AAED;sEACsE;AACtE,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAOjE;AAQD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,MAAM,GACb,gBAAgB,GAAG,SAAS,CA2B9B;AAED,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CA4H3D"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAgB,MAAM,qBAAqB,CAAC;AAEtE,OAAO,EAAE,gBAAgB,EAAa,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAwB,MAAM,EAAE,MAAM,aAAa,CAAC;AAuB3D;;2CAE2C;AAC3C,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAEzE;;;;;;;mEAOmE;AACnE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAWpE;AAED;sEACsE;AACtE,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAOjE;AAQD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,MAAM,GACb,gBAAgB,GAAG,SAAS,CA2B9B;AAOD,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAuO3D"}