signalk-aiscast 0.0.0
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/README.md +44 -0
- package/dist/downlink.d.ts +47 -0
- package/dist/downlink.js +187 -0
- package/dist/downlink.js.map +1 -0
- package/dist/identity.d.ts +15 -0
- package/dist/identity.js +51 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +263 -0
- package/dist/index.js.map +1 -0
- package/dist/link.d.ts +33 -0
- package/dist/link.js +134 -0
- package/dist/link.js.map +1 -0
- package/dist/n2k.d.ts +10 -0
- package/dist/n2k.js +112 -0
- package/dist/n2k.js.map +1 -0
- package/dist/nmea.d.ts +6 -0
- package/dist/nmea.js +33 -0
- package/dist/nmea.js.map +1 -0
- package/dist/uplink.d.ts +44 -0
- package/dist/uplink.js +257 -0
- package/dist/uplink.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/link.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
export interface Frame {
|
|
3
|
+
type: string;
|
|
4
|
+
[k: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
export interface LinkEvents {
|
|
7
|
+
open: [];
|
|
8
|
+
close: [code: number, reason: string];
|
|
9
|
+
frame: [frame: Frame];
|
|
10
|
+
error: [message: string];
|
|
11
|
+
}
|
|
12
|
+
export declare class Link extends EventEmitter<LinkEvents> {
|
|
13
|
+
private readonly url;
|
|
14
|
+
private readonly headers;
|
|
15
|
+
private readonly log;
|
|
16
|
+
private ws;
|
|
17
|
+
private attempt;
|
|
18
|
+
private timer;
|
|
19
|
+
private pinger;
|
|
20
|
+
private lastActivity;
|
|
21
|
+
private stopped;
|
|
22
|
+
lastRefusal: string | null;
|
|
23
|
+
constructor(url: () => string, headers?: () => Record<string, string>, log?: (msg: string) => void);
|
|
24
|
+
get open(): boolean;
|
|
25
|
+
start(): void;
|
|
26
|
+
stop(): void;
|
|
27
|
+
reconnect(): void;
|
|
28
|
+
send(frame: Frame): boolean;
|
|
29
|
+
private connect;
|
|
30
|
+
private scheduleReconnect;
|
|
31
|
+
private startPing;
|
|
32
|
+
private stopPing;
|
|
33
|
+
}
|
package/dist/link.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import WebSocket from "ws";
|
|
3
|
+
const MIN_BACKOFF = 5_000;
|
|
4
|
+
const MAX_BACKOFF = 5 * 60_000;
|
|
5
|
+
const REFUSED_BACKOFF = 30 * 60_000; // after the server refused us (1008): don't hammer it
|
|
6
|
+
const PING_EVERY = 30_000;
|
|
7
|
+
const SILENCE = 60_000; // no frame or pong for this long → the socket is dead whatever TCP thinks
|
|
8
|
+
// One WebSocket to aiscast /v1/stream with reconnect, jittered backoff, and a silence watchdog.
|
|
9
|
+
// `url()` and `headers()` are re-evaluated on every connect so a refreshed token is picked up without a restart.
|
|
10
|
+
export class Link extends EventEmitter {
|
|
11
|
+
url;
|
|
12
|
+
headers;
|
|
13
|
+
log;
|
|
14
|
+
ws = null;
|
|
15
|
+
attempt = 0;
|
|
16
|
+
timer = null;
|
|
17
|
+
pinger = null;
|
|
18
|
+
lastActivity = 0;
|
|
19
|
+
stopped = true;
|
|
20
|
+
lastRefusal = null;
|
|
21
|
+
constructor(url, headers = () => ({}), log = () => { }) {
|
|
22
|
+
super();
|
|
23
|
+
this.url = url;
|
|
24
|
+
this.headers = headers;
|
|
25
|
+
this.log = log;
|
|
26
|
+
}
|
|
27
|
+
get open() {
|
|
28
|
+
return this.ws?.readyState === WebSocket.OPEN;
|
|
29
|
+
}
|
|
30
|
+
start() {
|
|
31
|
+
this.stopped = false;
|
|
32
|
+
this.connect();
|
|
33
|
+
}
|
|
34
|
+
stop() {
|
|
35
|
+
this.stopped = true;
|
|
36
|
+
if (this.timer)
|
|
37
|
+
clearTimeout(this.timer);
|
|
38
|
+
this.timer = null;
|
|
39
|
+
this.stopPing();
|
|
40
|
+
this.ws?.close(1000, "plugin stopped");
|
|
41
|
+
this.ws = null;
|
|
42
|
+
}
|
|
43
|
+
// Reconnect now: drop the current socket, or cut a pending backoff short. Used after a token refresh.
|
|
44
|
+
reconnect() {
|
|
45
|
+
if (this.ws) {
|
|
46
|
+
this.ws.terminate();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (this.timer) {
|
|
50
|
+
clearTimeout(this.timer);
|
|
51
|
+
this.timer = null;
|
|
52
|
+
this.connect();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
send(frame) {
|
|
56
|
+
if (!this.open)
|
|
57
|
+
return false;
|
|
58
|
+
this.ws.send(JSON.stringify(frame));
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
connect() {
|
|
62
|
+
if (this.stopped)
|
|
63
|
+
return;
|
|
64
|
+
const url = this.url();
|
|
65
|
+
this.log(`connecting to ${url}`);
|
|
66
|
+
const ws = new WebSocket(url, { headers: this.headers(), perMessageDeflate: true, handshakeTimeout: 30_000 });
|
|
67
|
+
this.ws = ws;
|
|
68
|
+
this.lastActivity = Date.now();
|
|
69
|
+
ws.on("open", () => {
|
|
70
|
+
this.attempt = 0;
|
|
71
|
+
this.lastRefusal = null;
|
|
72
|
+
this.startPing(ws);
|
|
73
|
+
this.emit("open");
|
|
74
|
+
});
|
|
75
|
+
ws.on("message", (data) => {
|
|
76
|
+
this.lastActivity = Date.now();
|
|
77
|
+
let frame;
|
|
78
|
+
try {
|
|
79
|
+
frame = JSON.parse(data.toString());
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (frame.type === "error") {
|
|
85
|
+
const message = String(frame.error ?? "");
|
|
86
|
+
this.emit("error", message);
|
|
87
|
+
}
|
|
88
|
+
this.emit("frame", frame);
|
|
89
|
+
});
|
|
90
|
+
ws.on("pong", () => {
|
|
91
|
+
this.lastActivity = Date.now();
|
|
92
|
+
});
|
|
93
|
+
ws.on("error", (err) => this.log(`socket error: ${err.message}`));
|
|
94
|
+
ws.on("close", (code, reason) => {
|
|
95
|
+
this.stopPing();
|
|
96
|
+
if (this.ws === ws)
|
|
97
|
+
this.ws = null;
|
|
98
|
+
const why = reason.toString();
|
|
99
|
+
this.emit("close", code, why);
|
|
100
|
+
if (code === 1008)
|
|
101
|
+
this.lastRefusal = why;
|
|
102
|
+
this.scheduleReconnect(code === 1008);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
scheduleReconnect(refused) {
|
|
106
|
+
if (this.stopped || this.timer)
|
|
107
|
+
return;
|
|
108
|
+
const base = refused ? REFUSED_BACKOFF : Math.min(MAX_BACKOFF, MIN_BACKOFF * 2 ** this.attempt++);
|
|
109
|
+
const delay = base * (0.8 + Math.random() * 0.4);
|
|
110
|
+
this.log(`reconnecting in ${Math.round(delay / 1000)} s`);
|
|
111
|
+
this.timer = setTimeout(() => {
|
|
112
|
+
this.timer = null;
|
|
113
|
+
this.connect();
|
|
114
|
+
}, delay);
|
|
115
|
+
}
|
|
116
|
+
startPing(ws) {
|
|
117
|
+
this.stopPing();
|
|
118
|
+
this.pinger = setInterval(() => {
|
|
119
|
+
if (Date.now() - this.lastActivity > SILENCE) {
|
|
120
|
+
this.log("no frames or pongs for 60 s; reconnecting");
|
|
121
|
+
ws.terminate();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (ws.readyState === WebSocket.OPEN)
|
|
125
|
+
ws.ping();
|
|
126
|
+
}, PING_EVERY);
|
|
127
|
+
}
|
|
128
|
+
stopPing() {
|
|
129
|
+
if (this.pinger)
|
|
130
|
+
clearInterval(this.pinger);
|
|
131
|
+
this.pinger = null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=link.js.map
|
package/dist/link.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link.js","sourceRoot":"","sources":["../src/link.ts"],"names":[],"mappings":"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"}
|
package/dist/n2k.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ServerAPI } from "@signalk/server-api";
|
|
2
|
+
export declare const AIS_PGNS: Set<number>;
|
|
3
|
+
interface Fields {
|
|
4
|
+
[k: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
export declare function n2kToSentence(app: ServerAPI, msg: {
|
|
7
|
+
pgn: number;
|
|
8
|
+
fields?: Fields;
|
|
9
|
+
}): string | null;
|
|
10
|
+
export {};
|
package/dist/n2k.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { AisAssignedModeValues, AisTransceiver, AtonTypeValues, convertNamesToCamel, NavStatusValues, PositionAccuracy, RaimFlag, ShipTypeValues, YesNo, } from "@canboat/ts-pgns";
|
|
2
|
+
import ggencoder from "ggencoder";
|
|
3
|
+
const { AisEncode } = ggencoder; // CommonJS without static named exports
|
|
4
|
+
export const AIS_PGNS = new Set([129038, 129039, 129041, 129794, 129809, 129810]);
|
|
5
|
+
// One canboatjs message (app.on('N2KAnalyzerOut')) → one sentence, or null when it is not an AIS PGN we encode.
|
|
6
|
+
export function n2kToSentence(app, msg) {
|
|
7
|
+
if (!AIS_PGNS.has(msg.pgn))
|
|
8
|
+
return null;
|
|
9
|
+
const pgn = convertNamesToCamel(app, msg);
|
|
10
|
+
const f = pgn.fields ?? {};
|
|
11
|
+
const own = f.aisTransceiverInformation === AisTransceiver.OwnInformationNotBroadcast;
|
|
12
|
+
let enc = null;
|
|
13
|
+
switch (msg.pgn) {
|
|
14
|
+
case 129038: // class A position
|
|
15
|
+
enc = {
|
|
16
|
+
aistype: 3,
|
|
17
|
+
mmsi: f.userId,
|
|
18
|
+
navstatus: f.navStatus !== undefined ? NavStatusValues[f.navStatus] : undefined,
|
|
19
|
+
sog: mpsToKn(f.sog),
|
|
20
|
+
lon: f.longitude,
|
|
21
|
+
lat: f.latitude,
|
|
22
|
+
cog: radToDeg(f.cog),
|
|
23
|
+
hdg: radToDeg(f.heading),
|
|
24
|
+
rot: rotToAis(f.rateOfTurn),
|
|
25
|
+
};
|
|
26
|
+
break;
|
|
27
|
+
case 129039: // class B position
|
|
28
|
+
enc = {
|
|
29
|
+
aistype: 18,
|
|
30
|
+
mmsi: f.userId,
|
|
31
|
+
sog: mpsToKn(f.sog),
|
|
32
|
+
accuracy: f.positionAccuracy === PositionAccuracy.Low ? 0 : 1,
|
|
33
|
+
lon: f.longitude,
|
|
34
|
+
lat: f.latitude,
|
|
35
|
+
cog: radToDeg(f.cog),
|
|
36
|
+
hdg: radToDeg(f.heading),
|
|
37
|
+
};
|
|
38
|
+
break;
|
|
39
|
+
case 129794: // class A static and voyage
|
|
40
|
+
enc = {
|
|
41
|
+
aistype: 5,
|
|
42
|
+
mmsi: f.userId,
|
|
43
|
+
imo: f.imoNumber,
|
|
44
|
+
cargo: f.typeOfShip !== undefined ? ShipTypeValues[f.typeOfShip] : undefined,
|
|
45
|
+
callsign: f.callsign,
|
|
46
|
+
shipname: f.name,
|
|
47
|
+
destination: f.destination,
|
|
48
|
+
draught: f.draft,
|
|
49
|
+
...dimensions(f.positionReferenceFromBow, f.length, f.positionReferenceFromStarboard, f.beam),
|
|
50
|
+
};
|
|
51
|
+
break;
|
|
52
|
+
case 129809: // class B static, part A
|
|
53
|
+
enc = { aistype: 24, part: 0, mmsi: f.userId, shipname: f.name };
|
|
54
|
+
break;
|
|
55
|
+
case 129810: // class B static, part B
|
|
56
|
+
enc = {
|
|
57
|
+
aistype: 24,
|
|
58
|
+
part: 1,
|
|
59
|
+
mmsi: f.userId,
|
|
60
|
+
cargo: f.typeOfShip !== undefined ? ShipTypeValues[f.typeOfShip] : undefined,
|
|
61
|
+
callsign: f.callsign,
|
|
62
|
+
...dimensions(f.positionReferenceFromBow, f.length, f.positionReferenceFromStarboard, f.beam),
|
|
63
|
+
};
|
|
64
|
+
break;
|
|
65
|
+
case 129041: // aid to navigation
|
|
66
|
+
enc = {
|
|
67
|
+
aistype: 21,
|
|
68
|
+
mmsi: f.userId,
|
|
69
|
+
aid_type: f.atonType !== undefined ? AtonTypeValues[f.atonType] : undefined,
|
|
70
|
+
atonname: f.atonName,
|
|
71
|
+
accuracy: f.positionAccuracy === PositionAccuracy.Low ? 0 : 1,
|
|
72
|
+
lon: f.longitude,
|
|
73
|
+
lat: f.latitude,
|
|
74
|
+
off_position: f.offPositionIndicator === YesNo.Yes ? 1 : 0,
|
|
75
|
+
raim: f.raim === RaimFlag.InUse ? 1 : 0,
|
|
76
|
+
virtual_aid: f.virtualAtonFlag === YesNo.Yes ? 1 : 0,
|
|
77
|
+
assigned: f.assignedModeFlag !== undefined ? AisAssignedModeValues[f.assignedModeFlag] : undefined,
|
|
78
|
+
...dimensions(f.positionReferenceFromTrueNorthFacingEdge, f.lengthDiameter, f.positionReferenceFromStarboardEdge, f.beamDiameter),
|
|
79
|
+
};
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
if (!enc || typeof enc.mmsi !== "number" || enc.mmsi === 0)
|
|
83
|
+
return null;
|
|
84
|
+
const out = new AisEncode({ repeat: 0, own, ...enc });
|
|
85
|
+
return out.valid ? out.nmea : null;
|
|
86
|
+
}
|
|
87
|
+
function dimensions(fromBow, length, fromStarboard, beam) {
|
|
88
|
+
const d = {};
|
|
89
|
+
if (typeof fromBow === "number")
|
|
90
|
+
d.dimA = fromBow;
|
|
91
|
+
if (typeof fromBow === "number" && typeof length === "number")
|
|
92
|
+
d.dimB = length - fromBow;
|
|
93
|
+
if (typeof beam === "number" && typeof fromStarboard === "number")
|
|
94
|
+
d.dimC = beam - fromStarboard;
|
|
95
|
+
if (typeof fromStarboard === "number")
|
|
96
|
+
d.dimD = fromStarboard;
|
|
97
|
+
return d;
|
|
98
|
+
}
|
|
99
|
+
function radToDeg(rad) {
|
|
100
|
+
return rad === undefined ? undefined : Math.round((rad * 180) / Math.PI);
|
|
101
|
+
}
|
|
102
|
+
function mpsToKn(mps) {
|
|
103
|
+
return mps === undefined ? undefined : mps * 1.9438444924574;
|
|
104
|
+
}
|
|
105
|
+
// AIS rate of turn: 4.733 * sqrt(deg/min), sign preserved; 0 stays "not turning".
|
|
106
|
+
function rotToAis(radPerSec) {
|
|
107
|
+
if (radPerSec === undefined || radPerSec === 0)
|
|
108
|
+
return radPerSec;
|
|
109
|
+
const degPerMin = Math.abs(radPerSec) * 3437.74677078493;
|
|
110
|
+
return Math.sign(radPerSec) * 4.733 * Math.sqrt(degPerMin);
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=n2k.js.map
|
package/dist/n2k.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"n2k.js","sourceRoot":"","sources":["../src/n2k.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,cAAc,EACd,KAAK,GACN,MAAM,kBAAkB,CAAC;AAC1B,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC,CAAC,wCAAwC;AAEzE,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAMlF,gHAAgH;AAChH,MAAM,UAAU,aAAa,CAAC,GAAc,EAAE,GAAqC;IACjF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,GAAG,GAAG,mBAAmB,CAAC,GAAG,EAAE,GAAY,CAAuB,CAAC;IACzE,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,CAAC,CAAC,yBAAyB,KAAK,cAAc,CAAC,0BAA0B,CAAC;IACtF,IAAI,GAAG,GAAmC,IAAI,CAAC;IAC/C,QAAQ,GAAG,CAAC,GAAG,EAAE,CAAC;QAChB,KAAK,MAAM,EAAE,mBAAmB;YAC9B,GAAG,GAAG;gBACJ,OAAO,EAAE,CAAC;gBACV,IAAI,EAAE,CAAC,CAAC,MAAM;gBACd,SAAS,EAAE,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAmB,CAAC,CAAC,CAAC,CAAC,SAAS;gBACzF,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,GAAyB,CAAC;gBACzC,GAAG,EAAE,CAAC,CAAC,SAAS;gBAChB,GAAG,EAAE,CAAC,CAAC,QAAQ;gBACf,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAyB,CAAC;gBAC1C,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,OAA6B,CAAC;gBAC9C,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAgC,CAAC;aAClD,CAAC;YACF,MAAM;QACR,KAAK,MAAM,EAAE,mBAAmB;YAC9B,GAAG,GAAG;gBACJ,OAAO,EAAE,EAAE;gBACX,IAAI,EAAE,CAAC,CAAC,MAAM;gBACd,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,GAAyB,CAAC;gBACzC,QAAQ,EAAE,CAAC,CAAC,gBAAgB,KAAK,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7D,GAAG,EAAE,CAAC,CAAC,SAAS;gBAChB,GAAG,EAAE,CAAC,CAAC,QAAQ;gBACf,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAyB,CAAC;gBAC1C,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,OAA6B,CAAC;aAC/C,CAAC;YACF,MAAM;QACR,KAAK,MAAM,EAAE,4BAA4B;YACvC,GAAG,GAAG;gBACJ,OAAO,EAAE,CAAC;gBACV,IAAI,EAAE,CAAC,CAAC,MAAM;gBACd,GAAG,EAAE,CAAC,CAAC,SAAS;gBAChB,KAAK,EAAE,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,UAAoB,CAAC,CAAC,CAAC,CAAC,SAAS;gBACtF,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,QAAQ,EAAE,CAAC,CAAC,IAAI;gBAChB,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,OAAO,EAAE,CAAC,CAAC,KAAK;gBAChB,GAAG,UAAU,CAAC,CAAC,CAAC,wBAAwB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,8BAA8B,EAAE,CAAC,CAAC,IAAI,CAAC;aAC9F,CAAC;YACF,MAAM;QACR,KAAK,MAAM,EAAE,yBAAyB;YACpC,GAAG,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACjE,MAAM;QACR,KAAK,MAAM,EAAE,yBAAyB;YACpC,GAAG,GAAG;gBACJ,OAAO,EAAE,EAAE;gBACX,IAAI,EAAE,CAAC;gBACP,IAAI,EAAE,CAAC,CAAC,MAAM;gBACd,KAAK,EAAE,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,UAAoB,CAAC,CAAC,CAAC,CAAC,SAAS;gBACtF,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,GAAG,UAAU,CAAC,CAAC,CAAC,wBAAwB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,8BAA8B,EAAE,CAAC,CAAC,IAAI,CAAC;aAC9F,CAAC;YACF,MAAM;QACR,KAAK,MAAM,EAAE,oBAAoB;YAC/B,GAAG,GAAG;gBACJ,OAAO,EAAE,EAAE;gBACX,IAAI,EAAE,CAAC,CAAC,MAAM;gBACd,QAAQ,EAAE,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,QAAkB,CAAC,CAAC,CAAC,CAAC,SAAS;gBACrF,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,QAAQ,EAAE,CAAC,CAAC,gBAAgB,KAAK,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7D,GAAG,EAAE,CAAC,CAAC,SAAS;gBAChB,GAAG,EAAE,CAAC,CAAC,QAAQ;gBACf,YAAY,EAAE,CAAC,CAAC,oBAAoB,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC1D,IAAI,EAAE,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACvC,WAAW,EAAE,CAAC,CAAC,eAAe,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpD,QAAQ,EAAE,CAAC,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,gBAA0B,CAAC,CAAC,CAAC,CAAC,SAAS;gBAC5G,GAAG,UAAU,CAAC,CAAC,CAAC,wCAAwC,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,kCAAkC,EAAE,CAAC,CAAC,YAAY,CAAC;aAClI,CAAC;YACF,MAAM;IACV,CAAC;IACD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACxE,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;IACtD,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACrC,CAAC;AAED,SAAS,UAAU,CAAC,OAAgB,EAAE,MAAe,EAAE,aAAsB,EAAE,IAAa;IAC1F,MAAM,CAAC,GAA2B,EAAE,CAAC;IACrC,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,CAAC,CAAC,IAAI,GAAG,OAAO,CAAC;IAClD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,CAAC,CAAC,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC;IACzF,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,aAAa,KAAK,QAAQ;QAAE,CAAC,CAAC,IAAI,GAAG,IAAI,GAAG,aAAa,CAAC;IACjG,IAAI,OAAO,aAAa,KAAK,QAAQ;QAAE,CAAC,CAAC,IAAI,GAAG,aAAa,CAAC;IAC9D,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,QAAQ,CAAC,GAAuB;IACvC,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,OAAO,CAAC,GAAuB;IACtC,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,eAAe,CAAC;AAC/D,CAAC;AAED,kFAAkF;AAClF,SAAS,QAAQ,CAAC,SAA6B;IAC7C,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACjE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,gBAAgB,CAAC;IACzD,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC7D,CAAC"}
|
package/dist/nmea.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function isAis(sentence: string): boolean;
|
|
2
|
+
export declare function isOwnShip(sentence: string): boolean;
|
|
3
|
+
export declare function stripTag(sentence: string): string;
|
|
4
|
+
export declare function xorChecksum(s: string): string;
|
|
5
|
+
export declare function tagged(sentence: string, receivedAt: number, source?: string): string;
|
|
6
|
+
export declare function payloadKey(sentence: string): string;
|
package/dist/nmea.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Sentence-level helpers. The plugin never decodes AIS itself; aiscast and the server's parser do that.
|
|
2
|
+
const TAG_BLOCK = /^\\[^\\]*\\/;
|
|
3
|
+
// Optional TAG block, then !AIVDM / !BSVDM / !AIVDO ... from any talker.
|
|
4
|
+
const AIS_SENTENCE = /^(\\[^\\]*\\)?[!$][A-Z]{2}VD[MO],/;
|
|
5
|
+
export function isAis(sentence) {
|
|
6
|
+
return AIS_SENTENCE.test(sentence);
|
|
7
|
+
}
|
|
8
|
+
export function isOwnShip(sentence) {
|
|
9
|
+
return /^(\\[^\\]*\\)?[!$][A-Z]{2}VDO,/.test(sentence);
|
|
10
|
+
}
|
|
11
|
+
export function stripTag(sentence) {
|
|
12
|
+
return sentence.replace(TAG_BLOCK, "");
|
|
13
|
+
}
|
|
14
|
+
export function xorChecksum(s) {
|
|
15
|
+
let sum = 0;
|
|
16
|
+
for (let i = 0; i < s.length; i++)
|
|
17
|
+
sum ^= s.charCodeAt(i);
|
|
18
|
+
return sum.toString(16).toUpperCase().padStart(2, "0");
|
|
19
|
+
}
|
|
20
|
+
// Prepend a NMEA 4.10 TAG block carrying the receive time (and a source label such as `n2k` for re-encoded
|
|
21
|
+
// sentences), unless the sentence already has one.
|
|
22
|
+
export function tagged(sentence, receivedAt, source) {
|
|
23
|
+
if (TAG_BLOCK.test(sentence))
|
|
24
|
+
return sentence;
|
|
25
|
+
const tag = `${source ? `s:${source},` : ""}c:${receivedAt}`; // 13 digits: aiscast reads that as milliseconds
|
|
26
|
+
return `\\${tag}*${xorChecksum(tag)}\\${sentence}`;
|
|
27
|
+
}
|
|
28
|
+
// The armoured payload (6th field) plus channel, which is what aiscast dedupes on.
|
|
29
|
+
export function payloadKey(sentence) {
|
|
30
|
+
const f = stripTag(sentence).split(",");
|
|
31
|
+
return f.length > 5 ? `${f[5]}/${f[4]}` : sentence;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=nmea.js.map
|
package/dist/nmea.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nmea.js","sourceRoot":"","sources":["../src/nmea.ts"],"names":[],"mappings":"AAAA,wGAAwG;AAExG,MAAM,SAAS,GAAG,aAAa,CAAC;AAChC,yEAAyE;AACzE,MAAM,YAAY,GAAG,mCAAmC,CAAC;AAEzD,MAAM,UAAU,KAAK,CAAC,QAAgB;IACpC,OAAO,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,OAAO,gCAAgC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,QAAgB;IACvC,OAAO,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC1D,OAAO,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACzD,CAAC;AAED,2GAA2G;AAC3G,mDAAmD;AACnD,MAAM,UAAU,MAAM,CAAC,QAAgB,EAAE,UAAkB,EAAE,MAAe;IAC1E,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC9C,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,EAAE,CAAC,CAAC,gDAAgD;IAC9G,OAAO,KAAK,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE,CAAC;AACrD,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;AACrD,CAAC"}
|
package/dist/uplink.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Link } from "./link.js";
|
|
2
|
+
export interface UplinkStats {
|
|
3
|
+
sent: number;
|
|
4
|
+
queued: number;
|
|
5
|
+
dropped: number;
|
|
6
|
+
inFlight: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class Uplink {
|
|
9
|
+
private readonly link;
|
|
10
|
+
private readonly log;
|
|
11
|
+
enabled: boolean;
|
|
12
|
+
private backlog;
|
|
13
|
+
private inflight;
|
|
14
|
+
private pendingLive;
|
|
15
|
+
private liveScheduled;
|
|
16
|
+
private draining;
|
|
17
|
+
private drainAgain;
|
|
18
|
+
private flushTimer;
|
|
19
|
+
private ackTimer;
|
|
20
|
+
private seen;
|
|
21
|
+
private readonly dir;
|
|
22
|
+
private readonly onOpen;
|
|
23
|
+
private readonly onClose;
|
|
24
|
+
private readonly onFrame;
|
|
25
|
+
stats: UplinkStats;
|
|
26
|
+
constructor(link: Link, dataDir: string, log?: (msg: string) => void);
|
|
27
|
+
start(): Promise<void>;
|
|
28
|
+
stop(): Promise<void>;
|
|
29
|
+
noteReceived(sentence: string, now?: number): void;
|
|
30
|
+
hear(sentence: string, now?: number, source?: string): void;
|
|
31
|
+
private sendLive;
|
|
32
|
+
private sendFrame;
|
|
33
|
+
private ack;
|
|
34
|
+
private checkAcks;
|
|
35
|
+
private requeueInFlight;
|
|
36
|
+
private flush;
|
|
37
|
+
private files;
|
|
38
|
+
private readQueueFile;
|
|
39
|
+
private countQueued;
|
|
40
|
+
private enforceCap;
|
|
41
|
+
private drain;
|
|
42
|
+
private drainLoop;
|
|
43
|
+
private pruneSeen;
|
|
44
|
+
}
|