@sailingnaturali/signalk-dsc 0.5.4 → 0.5.6
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/index.js +36 -59
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -34,7 +34,9 @@ const {
|
|
|
34
34
|
buildLogbookText,
|
|
35
35
|
captureOwnShip,
|
|
36
36
|
buildObservations,
|
|
37
|
+
createNotifier,
|
|
37
38
|
unwrap,
|
|
39
|
+
writeLogbookEntry,
|
|
38
40
|
} = require('@sailingnaturali/signalk-distress-core');
|
|
39
41
|
|
|
40
42
|
const DSC_PGN = 129808;
|
|
@@ -141,37 +143,33 @@ module.exports = function makePlugin(app) {
|
|
|
141
143
|
};
|
|
142
144
|
}
|
|
143
145
|
|
|
146
|
+
// Notification plumbing (raise/clear/reannounce) is shared with
|
|
147
|
+
// signalk-ais-distress via signalk-distress-core. A non-alarming category
|
|
148
|
+
// (routine/unknown, not in NOTIFICATION_STATES) makes raise a no-op.
|
|
149
|
+
const notifier = createNotifier({
|
|
150
|
+
app,
|
|
151
|
+
pluginId: plugin.id,
|
|
152
|
+
pathFor: (event) => `notifications.dsc.${event.category}`,
|
|
153
|
+
stateFor: (event) => NOTIFICATION_STATES[event.category],
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Rebuild the spoken message against the current own-ship position — range
|
|
157
|
+
// and direction shift as we move. Terse on purpose: this string gets spoken;
|
|
158
|
+
// full detail lives in the resource store and the logbook entry.
|
|
159
|
+
function refreshMessage(event) {
|
|
160
|
+
event.message = buildMessage(event, messageContext(event));
|
|
161
|
+
return event;
|
|
162
|
+
}
|
|
163
|
+
|
|
144
164
|
function notify(event) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
app.handleMessage(plugin.id, {
|
|
148
|
-
updates: [
|
|
149
|
-
{
|
|
150
|
-
values: [
|
|
151
|
-
{
|
|
152
|
-
path: `notifications.dsc.${event.category}`,
|
|
153
|
-
value: {
|
|
154
|
-
state,
|
|
155
|
-
method: ['visual', 'sound'],
|
|
156
|
-
// Kept terse on purpose: this string gets spoken by the
|
|
157
|
-
// voice pipeline. Full detail lives in the resource store
|
|
158
|
-
// and the logbook entry.
|
|
159
|
-
message: buildMessage(event, messageContext(event)),
|
|
160
|
-
timestamp: event.receivedAt,
|
|
161
|
-
},
|
|
162
|
-
},
|
|
163
|
-
],
|
|
164
|
-
},
|
|
165
|
-
],
|
|
166
|
-
});
|
|
165
|
+
refreshMessage(event);
|
|
166
|
+
notifier.raise(event);
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
/** Clear an active DSC alarm: drop the live notification from our own source
|
|
170
170
|
* and stamp the stored events so the restart reannounce skips them. */
|
|
171
171
|
function clearCategory(category) {
|
|
172
|
-
|
|
173
|
-
updates: [{ values: [{ path: `notifications.dsc.${category}`, value: null }] }],
|
|
174
|
-
});
|
|
172
|
+
notifier.clear(`notifications.dsc.${category}`);
|
|
175
173
|
store.markCleared((e) => e.category === category, new Date().toISOString());
|
|
176
174
|
}
|
|
177
175
|
|
|
@@ -185,26 +183,14 @@ module.exports = function makePlugin(app) {
|
|
|
185
183
|
}
|
|
186
184
|
|
|
187
185
|
async function postLogbook(event) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
Authorization: `Bearer ${options.logbookToken}`,
|
|
196
|
-
Cookie: `JAUTHENTICATION=${options.logbookToken}`,
|
|
197
|
-
},
|
|
198
|
-
body: JSON.stringify({
|
|
199
|
-
text: buildLogbookText(event, messageContext(event)),
|
|
200
|
-
ago: 0,
|
|
201
|
-
category: 'radio',
|
|
202
|
-
// DSC is received on VHF channel 70 by definition.
|
|
203
|
-
vhf: '70',
|
|
204
|
-
...(observations ? { observations } : {}),
|
|
205
|
-
}),
|
|
186
|
+
await writeLogbookEntry({
|
|
187
|
+
url: options.logbookUrl,
|
|
188
|
+
token: options.logbookToken,
|
|
189
|
+
text: buildLogbookText(event, messageContext(event)),
|
|
190
|
+
observations: buildObservations(event.ownShip),
|
|
191
|
+
// DSC is received on VHF channel 70 by definition.
|
|
192
|
+
extra: { vhf: '70' },
|
|
206
193
|
});
|
|
207
|
-
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
208
194
|
}
|
|
209
195
|
|
|
210
196
|
/** Store a normalized call, alarm on it, and log it. Returns the stored event. */
|
|
@@ -431,23 +417,14 @@ module.exports = function makePlugin(app) {
|
|
|
431
417
|
// Survive server restarts mid-incident: re-raise the newest alert per
|
|
432
418
|
// category that is still fresh (a received MAYDAY must not vanish just
|
|
433
419
|
// because the server bounced). Delayed so position providers are up and
|
|
434
|
-
// the spoken message can say "N miles <direction>" instead of raw
|
|
435
|
-
// coordinates.
|
|
420
|
+
// the refreshed spoken message can say "N miles <direction>" instead of raw
|
|
421
|
+
// coordinates. Non-alarming categories are skipped by raise's no-op path.
|
|
436
422
|
reannounceTimer = setTimeout(() => {
|
|
437
423
|
if (!started) return;
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
const event = events[i];
|
|
443
|
-
if (!NOTIFICATION_STATES[event.category] || reannounced.has(event.category)) continue;
|
|
444
|
-
if (event.clearedAt) continue; // operator-cleared: never resurrect
|
|
445
|
-
const at = Date.parse(event.lastReceivedAt || event.receivedAt);
|
|
446
|
-
if (now - at <= REANNOUNCE_WINDOW_MS) {
|
|
447
|
-
notify(event);
|
|
448
|
-
reannounced.add(event.category);
|
|
449
|
-
}
|
|
450
|
-
}
|
|
424
|
+
notifier.reannounce(store.list(), {
|
|
425
|
+
window: REANNOUNCE_WINDOW_MS,
|
|
426
|
+
prepare: refreshMessage,
|
|
427
|
+
});
|
|
451
428
|
}, options.reannounceDelayMs ?? 30000);
|
|
452
429
|
};
|
|
453
430
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sailingnaturali/signalk-dsc",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.6",
|
|
4
4
|
"description": "Receive, log, and alert on DSC (VHF digital selective calling) calls — distress, urgency, safety, routine — from NMEA 0183 ($CDDSC/$CDDSE) and NMEA 2000 (PGN 129808).",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -49,6 +49,6 @@
|
|
|
49
49
|
"node": ">=18"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@sailingnaturali/signalk-distress-core": "^0.
|
|
52
|
+
"@sailingnaturali/signalk-distress-core": "^0.3.0"
|
|
53
53
|
}
|
|
54
54
|
}
|