@aurora-blue/signalk-connector 0.2.0-dev.28 → 0.2.0-dev.30
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/VERSION +1 -1
- package/dist/src/connector.d.ts +7 -2
- package/dist/src/connector.js +62 -11
- package/dist/src/telemetry-catalog.js +36 -0
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +4 -4
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.2.0-dev.
|
|
1
|
+
0.2.0-dev.30
|
package/dist/src/connector.d.ts
CHANGED
|
@@ -45,7 +45,11 @@ export declare class ConnectorRuntime {
|
|
|
45
45
|
private readonly emissionTimes;
|
|
46
46
|
private publisher;
|
|
47
47
|
private captureTail;
|
|
48
|
-
private
|
|
48
|
+
private captureResult;
|
|
49
|
+
private captureRunning;
|
|
50
|
+
private readonly pendingCaptures;
|
|
51
|
+
private captureInFlight;
|
|
52
|
+
private captureTransition;
|
|
49
53
|
private nextCaptureStatusAt;
|
|
50
54
|
constructor(app: ServerAPI, store: StateStore, config: ConnectorConfig, options?: ConnectorRuntimeOptions);
|
|
51
55
|
start(): Promise<void>;
|
|
@@ -59,7 +63,8 @@ export declare class ConnectorRuntime {
|
|
|
59
63
|
source: string | null;
|
|
60
64
|
} | null;
|
|
61
65
|
stop(): Promise<void>;
|
|
62
|
-
capture(delta: Delta, subscriptionScope?: SubscriptionScope): Promise<void>;
|
|
66
|
+
capture(delta: Delta, subscriptionScope?: SubscriptionScope, waitForPersistence?: boolean): Promise<void>;
|
|
67
|
+
private drainCaptures;
|
|
63
68
|
private captureEvents;
|
|
64
69
|
status(): Promise<ConnectorStatus>;
|
|
65
70
|
flush(): Promise<void>;
|
package/dist/src/connector.js
CHANGED
|
@@ -57,7 +57,11 @@ class ConnectorRuntime {
|
|
|
57
57
|
emissionTimes = [];
|
|
58
58
|
publisher = null;
|
|
59
59
|
captureTail = Promise.resolve();
|
|
60
|
-
|
|
60
|
+
captureResult = Promise.resolve();
|
|
61
|
+
captureRunning = false;
|
|
62
|
+
pendingCaptures = new Map();
|
|
63
|
+
captureInFlight = 0;
|
|
64
|
+
captureTransition = 0;
|
|
61
65
|
nextCaptureStatusAt = 0;
|
|
62
66
|
constructor(app, store, config, options = {}) {
|
|
63
67
|
this.app = app;
|
|
@@ -204,7 +208,7 @@ class ConnectorRuntime {
|
|
|
204
208
|
await this.captureTail;
|
|
205
209
|
await this.store.summary();
|
|
206
210
|
}
|
|
207
|
-
async capture(delta, subscriptionScope = "self") {
|
|
211
|
+
async capture(delta, subscriptionScope = "self", waitForPersistence = true) {
|
|
208
212
|
if (this.stopped) {
|
|
209
213
|
return;
|
|
210
214
|
}
|
|
@@ -229,19 +233,66 @@ class ConnectorRuntime {
|
|
|
229
233
|
events.length === 0) {
|
|
230
234
|
return;
|
|
231
235
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
236
|
+
let admitted = false;
|
|
237
|
+
for (const event of events) {
|
|
238
|
+
const kind = (0, telemetry_catalog_1.telemetryDefinition)(event.context, event.path)?.valueKind;
|
|
239
|
+
// Keep transitions in order. Only unpersisted sampled values may be replaced.
|
|
240
|
+
const sampled = kind === "number" || kind === "position" || kind === "json";
|
|
241
|
+
const key = sampled
|
|
242
|
+
? `${event.context}\0${event.path}\0${event.source ?? ""}`
|
|
243
|
+
: this.captureTransition++;
|
|
244
|
+
if (this.pendingCaptures.has(key)) {
|
|
245
|
+
// Map.set preserves the original FIFO position, preventing hot-path starvation.
|
|
246
|
+
this.pendingCaptures.set(key, event);
|
|
247
|
+
admitted = true;
|
|
248
|
+
this.suppressedEvents += 1;
|
|
249
|
+
}
|
|
250
|
+
else if (this.pendingCaptures.size + this.captureInFlight <
|
|
251
|
+
MAXIMUM_PENDING_CAPTURE_EVENTS) {
|
|
252
|
+
this.pendingCaptures.set(key, event);
|
|
253
|
+
admitted = true;
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
this.droppedEvents += 1;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
if (!admitted)
|
|
235
260
|
return;
|
|
261
|
+
if (!this.captureRunning && this.pendingCaptures.size > 0) {
|
|
262
|
+
this.captureRunning = true;
|
|
263
|
+
const current = Promise.resolve().then(() => this.drainCaptures());
|
|
264
|
+
this.captureTail = current.catch((error) => {
|
|
265
|
+
this.app.setPluginError("Signal K data could not be buffered safely.");
|
|
266
|
+
this.app.error(error instanceof Error ? error.message : String(error));
|
|
267
|
+
});
|
|
268
|
+
// All admitted callbacks observe write failures; the tail remains safe for stop().
|
|
269
|
+
this.captureResult = current;
|
|
236
270
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
271
|
+
// Subscription callbacks must not retain a waiter for a continuously busy drain.
|
|
272
|
+
if (waitForPersistence)
|
|
273
|
+
await this.captureResult;
|
|
274
|
+
}
|
|
275
|
+
async drainCaptures() {
|
|
240
276
|
try {
|
|
241
|
-
|
|
277
|
+
while (this.pendingCaptures.size > 0) {
|
|
278
|
+
const [key, event] = this.pendingCaptures.entries().next().value;
|
|
279
|
+
this.pendingCaptures.delete(key);
|
|
280
|
+
this.captureInFlight = 1;
|
|
281
|
+
try {
|
|
282
|
+
await this.captureEvents([event]);
|
|
283
|
+
}
|
|
284
|
+
finally {
|
|
285
|
+
this.captureInFlight = 0;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
this.droppedEvents += this.pendingCaptures.size;
|
|
291
|
+
this.pendingCaptures.clear();
|
|
292
|
+
throw error;
|
|
242
293
|
}
|
|
243
294
|
finally {
|
|
244
|
-
this.
|
|
295
|
+
this.captureRunning = false;
|
|
245
296
|
}
|
|
246
297
|
}
|
|
247
298
|
async captureEvents(events) {
|
|
@@ -412,7 +463,7 @@ class ConnectorRuntime {
|
|
|
412
463
|
this.app.setPluginError("Signal K subscription failed.");
|
|
413
464
|
this.app.error(error instanceof Error ? error.message : String(error));
|
|
414
465
|
}, (delta) => {
|
|
415
|
-
void this.capture(delta, context === "vessels.self" ? "self" : "ais").catch((error) => {
|
|
466
|
+
void this.capture(delta, context === "vessels.self" ? "self" : "ais", false).catch((error) => {
|
|
416
467
|
this.app.setPluginError("Signal K data could not be buffered safely.");
|
|
417
468
|
this.app.error(error instanceof Error ? error.message : String(error));
|
|
418
469
|
});
|
|
@@ -55,6 +55,42 @@ exports.SELF_TELEMETRY = [
|
|
|
55
55
|
self("environment.outside.temperature", "number", "scalar", 30_000, 60_000, 0.5),
|
|
56
56
|
self("environment.outside.pressure", "number", "scalar", 30_000, 60_000, 50),
|
|
57
57
|
self("environment.outside.relativeHumidity", "number", "scalar", 30_000, 60_000, 0.02),
|
|
58
|
+
self("electrical.batteries.*.power", "number", "scalar", 5_000, 60_000, 1),
|
|
59
|
+
self("electrical.batteries.*.capacity.remaining", "number", "scalar", 5_000, 60_000, 1),
|
|
60
|
+
self("electrical.batteries.*.capacity.nominal", "number", "scalar", 5_000, 60_000, 1),
|
|
61
|
+
self("electrical.solar.*.voltage", "number", "scalar", 5_000, 60_000, 1),
|
|
62
|
+
self("electrical.solar.*.current", "number", "scalar", 5_000, 60_000, 1),
|
|
63
|
+
self("electrical.solar.*.power", "number", "scalar", 5_000, 60_000, 1),
|
|
64
|
+
self("electrical.chargers.*.voltage", "number", "scalar", 5_000, 60_000, 1),
|
|
65
|
+
self("electrical.chargers.*.current", "number", "scalar", 5_000, 60_000, 1),
|
|
66
|
+
self("electrical.chargers.*.power", "number", "scalar", 5_000, 60_000, 1),
|
|
67
|
+
self("electrical.alternators.*.voltage", "number", "scalar", 5_000, 60_000, 1),
|
|
68
|
+
self("electrical.alternators.*.current", "number", "scalar", 5_000, 60_000, 1),
|
|
69
|
+
self("electrical.alternators.*.power", "number", "scalar", 5_000, 60_000, 1),
|
|
70
|
+
self("electrical.solar.*.panelPower", "number", "scalar", 5_000, 60_000, 1),
|
|
71
|
+
self("electrical.solar.*.yieldToday", "number", "scalar", 5_000, 60_000, 1),
|
|
72
|
+
self("electrical.inverters.*.dc.voltage", "number", "scalar", 5_000, 60_000, 1),
|
|
73
|
+
self("electrical.inverters.*.dc.current", "number", "scalar", 5_000, 60_000, 1),
|
|
74
|
+
self("electrical.inverters.*.dc.power", "number", "scalar", 5_000, 60_000, 1),
|
|
75
|
+
self("electrical.inverters.*.ac.realPower", "number", "scalar", 5_000, 60_000, 1),
|
|
76
|
+
self("electrical.inverters.*.ac.lineNeutralVoltage", "number", "scalar", 5_000, 60_000, 1),
|
|
77
|
+
self("electrical.inverters.*.ac.frequency", "number", "scalar", 5_000, 60_000, 1),
|
|
78
|
+
self("electrical.ac.*.phase.*.realPower", "number", "scalar", 5_000, 60_000, 1),
|
|
79
|
+
self("electrical.ac.*.phase.*.lineNeutralVoltage", "number", "scalar", 5_000, 60_000, 1),
|
|
80
|
+
self("electrical.ac.*.phase.*.current", "number", "scalar", 5_000, 60_000, 1),
|
|
81
|
+
self("electrical.ac.*.phase.*.frequency", "number", "scalar", 5_000, 60_000, 1),
|
|
82
|
+
self("electrical.dc.*.power", "number", "scalar", 5_000, 60_000, 1),
|
|
83
|
+
self("electrical.dc.*.voltage", "number", "scalar", 5_000, 60_000, 1),
|
|
84
|
+
self("electrical.dc.*.current", "number", "scalar", 5_000, 60_000, 1),
|
|
85
|
+
self("electrical.batteries.*.name", "string", "identity", 30_000, 600_000, 0),
|
|
86
|
+
self("electrical.solar.*.name", "string", "identity", 30_000, 600_000, 0),
|
|
87
|
+
self("electrical.chargers.*.name", "string", "identity", 30_000, 600_000, 0),
|
|
88
|
+
self("electrical.alternators.*.name", "string", "identity", 30_000, 600_000, 0),
|
|
89
|
+
self("electrical.inverters.*.name", "string", "identity", 30_000, 600_000, 0),
|
|
90
|
+
self("electrical.ac.*.name", "string", "identity", 30_000, 600_000, 0),
|
|
91
|
+
self("electrical.dc.*.name", "string", "identity", 30_000, 600_000, 0),
|
|
92
|
+
self("electrical.inverters.*.inverterMode", "string", "identity", 30_000, 60_000, 0),
|
|
93
|
+
self("electrical.chargers.*.chargingMode", "string", "identity", 30_000, 60_000, 0),
|
|
58
94
|
self("electrical.batteries.*.voltage", "number", "scalar", 10_000, 300_000, 0.1),
|
|
59
95
|
self("electrical.batteries.*.current", "number", "scalar", 5_000, 120_000, 1),
|
|
60
96
|
self("electrical.batteries.*.temperature", "number", "scalar", 30_000, 600_000, 0.5),
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const CONNECTOR_VERSION = "0.2.0-dev.
|
|
1
|
+
export declare const CONNECTOR_VERSION = "0.2.0-dev.30";
|
package/dist/src/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aurora-blue/signalk-connector",
|
|
3
|
-
"version": "0.2.0-dev.
|
|
3
|
+
"version": "0.2.0-dev.30",
|
|
4
4
|
"description": "Signal K edge connector for the Aurora Blue ABOARD ingest protocol",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -48,9 +48,9 @@
|
|
|
48
48
|
"release:verify": "node tools/release.mjs verify"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@signalk/server-api": "2.
|
|
52
|
-
"@types/node": "
|
|
53
|
-
"prettier": "3.9.
|
|
51
|
+
"@signalk/server-api": "2.35.0",
|
|
52
|
+
"@types/node": "24.19.2",
|
|
53
|
+
"prettier": "3.9.10",
|
|
54
54
|
"typescript": "7.0.2"
|
|
55
55
|
},
|
|
56
56
|
"license": "MIT",
|