@sailingnaturali/signalk-dsc 0.5.5 → 0.5.7
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 +9 -0
- package/index.js +28 -40
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -212,6 +212,15 @@ broadcasts on behalf of a real, licensed MMSI). Until such hardware is common
|
|
|
212
212
|
this stays out of scope and the plugin remains a passive receiver. If you have a
|
|
213
213
|
radio that exposes a transmit interface, open an issue.
|
|
214
214
|
|
|
215
|
+
## See also
|
|
216
|
+
|
|
217
|
+
DSC is the *alerting* signal — it tells you a vessel is in distress and roughly
|
|
218
|
+
where. For *finding* the casualty, pair this with the companion
|
|
219
|
+
[`@sailingnaturali/signalk-ais-distress`](https://github.com/sailingnaturali/signalk-ais-distress),
|
|
220
|
+
which alarms on AIS survival beacons (SART / MOB / EPIRB) and gives you a
|
|
221
|
+
position stream to home on. Both share the same 97x identity classes and build on
|
|
222
|
+
[`@sailingnaturali/signalk-distress-core`](https://github.com/sailingnaturali/signalk-distress-core).
|
|
223
|
+
|
|
215
224
|
## License
|
|
216
225
|
|
|
217
226
|
MIT
|
package/index.js
CHANGED
|
@@ -34,6 +34,7 @@ const {
|
|
|
34
34
|
buildLogbookText,
|
|
35
35
|
captureOwnShip,
|
|
36
36
|
buildObservations,
|
|
37
|
+
createNotifier,
|
|
37
38
|
unwrap,
|
|
38
39
|
writeLogbookEntry,
|
|
39
40
|
} = require('@sailingnaturali/signalk-distress-core');
|
|
@@ -142,37 +143,33 @@ module.exports = function makePlugin(app) {
|
|
|
142
143
|
};
|
|
143
144
|
}
|
|
144
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
|
+
|
|
145
164
|
function notify(event) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
app.handleMessage(plugin.id, {
|
|
149
|
-
updates: [
|
|
150
|
-
{
|
|
151
|
-
values: [
|
|
152
|
-
{
|
|
153
|
-
path: `notifications.dsc.${event.category}`,
|
|
154
|
-
value: {
|
|
155
|
-
state,
|
|
156
|
-
method: ['visual', 'sound'],
|
|
157
|
-
// Kept terse on purpose: this string gets spoken by the
|
|
158
|
-
// voice pipeline. Full detail lives in the resource store
|
|
159
|
-
// and the logbook entry.
|
|
160
|
-
message: buildMessage(event, messageContext(event)),
|
|
161
|
-
timestamp: event.receivedAt,
|
|
162
|
-
},
|
|
163
|
-
},
|
|
164
|
-
],
|
|
165
|
-
},
|
|
166
|
-
],
|
|
167
|
-
});
|
|
165
|
+
refreshMessage(event);
|
|
166
|
+
notifier.raise(event);
|
|
168
167
|
}
|
|
169
168
|
|
|
170
169
|
/** Clear an active DSC alarm: drop the live notification from our own source
|
|
171
170
|
* and stamp the stored events so the restart reannounce skips them. */
|
|
172
171
|
function clearCategory(category) {
|
|
173
|
-
|
|
174
|
-
updates: [{ values: [{ path: `notifications.dsc.${category}`, value: null }] }],
|
|
175
|
-
});
|
|
172
|
+
notifier.clear(`notifications.dsc.${category}`);
|
|
176
173
|
store.markCleared((e) => e.category === category, new Date().toISOString());
|
|
177
174
|
}
|
|
178
175
|
|
|
@@ -420,23 +417,14 @@ module.exports = function makePlugin(app) {
|
|
|
420
417
|
// Survive server restarts mid-incident: re-raise the newest alert per
|
|
421
418
|
// category that is still fresh (a received MAYDAY must not vanish just
|
|
422
419
|
// because the server bounced). Delayed so position providers are up and
|
|
423
|
-
// the spoken message can say "N miles <direction>" instead of raw
|
|
424
|
-
// 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.
|
|
425
422
|
reannounceTimer = setTimeout(() => {
|
|
426
423
|
if (!started) return;
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
const event = events[i];
|
|
432
|
-
if (!NOTIFICATION_STATES[event.category] || reannounced.has(event.category)) continue;
|
|
433
|
-
if (event.clearedAt) continue; // operator-cleared: never resurrect
|
|
434
|
-
const at = Date.parse(event.lastReceivedAt || event.receivedAt);
|
|
435
|
-
if (now - at <= REANNOUNCE_WINDOW_MS) {
|
|
436
|
-
notify(event);
|
|
437
|
-
reannounced.add(event.category);
|
|
438
|
-
}
|
|
439
|
-
}
|
|
424
|
+
notifier.reannounce(store.list(), {
|
|
425
|
+
window: REANNOUNCE_WINDOW_MS,
|
|
426
|
+
prepare: refreshMessage,
|
|
427
|
+
});
|
|
440
428
|
}, options.reannounceDelayMs ?? 30000);
|
|
441
429
|
};
|
|
442
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.7",
|
|
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
|
}
|