@sailingnaturali/signalk-dsc 0.1.0 → 0.1.2
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 +59 -4
- package/docs/screenshots/config.png +0 -0
- package/docs/screenshots/data-table.png +0 -0
- package/lib/dsc.js +9 -2
- package/package.json +12 -3
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# signalk-dsc
|
|
1
|
+
# @sailingnaturali/signalk-dsc
|
|
2
2
|
|
|
3
3
|
SignalK plugin that receives, logs, and alerts on **DSC** (VHF digital selective
|
|
4
4
|
calling) traffic — distress, urgency, safety, and routine calls — from both
|
|
@@ -14,6 +14,17 @@ has **no** PGN 129808 mapping at all. If you might be the nearest boat, you want
|
|
|
14
14
|
every received alert stored with its position and surfaced as an alarm — that is
|
|
15
15
|
this plugin.
|
|
16
16
|
|
|
17
|
+
Logging that traffic is also the regulatory standard. Maritime radio rules
|
|
18
|
+
require *compulsorily-equipped* vessels to record every distress, urgency, and
|
|
19
|
+
safety call **made or intercepted**, with the time and position of the station
|
|
20
|
+
in distress ([47 CFR §80.409](https://www.law.cornell.edu/cfr/text/47/80.409);
|
|
21
|
+
SOLAS Ch. IV; ITU Radio Regulations; Canada's TP 1539). Pleasure craft are
|
|
22
|
+
generally exempt from the log mandate — this just gives you that same
|
|
23
|
+
SOLAS-grade record automatically. The parser gaps and the regulation are written
|
|
24
|
+
up in more detail [on the engineering blog][writeup].
|
|
25
|
+
|
|
26
|
+
[writeup]: https://engineering.sailingnaturali.com/signalk-dsc-distress-call-logging-nmea0183-dse-pgn-129808/
|
|
27
|
+
|
|
17
28
|
## What you get
|
|
18
29
|
|
|
19
30
|
For every DSC call heard by a connected radio:
|
|
@@ -65,15 +76,59 @@ For every DSC call heard by a connected radio:
|
|
|
65
76
|
|
|
66
77
|
## Trying it without a radio
|
|
67
78
|
|
|
68
|
-
|
|
79
|
+
### Quick test script
|
|
80
|
+
|
|
81
|
+
The repo includes a script that builds a valid DSC sentence and fires it at the
|
|
82
|
+
server over UDP. First add a UDP input in your SignalK pipedProviders (Settings →
|
|
83
|
+
Connections → Add):
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"id": "dsc-test-udp",
|
|
88
|
+
"pipeElements": [{ "type": "providers/simple",
|
|
89
|
+
"options": { "type": "NMEA0183", "subOptions": { "type": "udp", "port": "7777" } } }]
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Then send a fake distress call:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Default: sinking, MMSI 366191919, near Boundary Pass → naturalaspi.local:7777
|
|
97
|
+
node scripts/send-test-dsc.js
|
|
98
|
+
|
|
99
|
+
# npm alias
|
|
100
|
+
npm run send-test-dsc
|
|
101
|
+
|
|
102
|
+
# Different nature of distress
|
|
103
|
+
node scripts/send-test-dsc.js --nature fire
|
|
104
|
+
node scripts/send-test-dsc.js --nature mob --category urgency
|
|
105
|
+
|
|
106
|
+
# Different vessel / position
|
|
107
|
+
node scripts/send-test-dsc.js --mmsi 316555777 --lat 48.9 --lon -123.5
|
|
108
|
+
|
|
109
|
+
# Different host / port
|
|
110
|
+
node scripts/send-test-dsc.js --host localhost --port 7777
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
All `--nature` values: `fire`, `flooding`, `collision`, `grounding`, `listing`,
|
|
114
|
+
`sinking`, `adrift`, `abandon`, `piracy`, `mob`, `epirb`.
|
|
115
|
+
|
|
116
|
+
Verify the call was captured:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
GET /signalk/v2/api/resources/dsc-calls
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Manual sentence injection
|
|
123
|
+
|
|
124
|
+
You can also feed raw sentences through any NMEA 0183 connection (TCP, UDP, file
|
|
125
|
+
playback):
|
|
69
126
|
|
|
70
127
|
```
|
|
71
128
|
$CDDSC,12,3380400790,12,05,00,1423108312,2019,,,S,E*69
|
|
72
129
|
$CDDSE,1,1,A,3380400790,00,45894494*1B
|
|
73
130
|
```
|
|
74
131
|
|
|
75
|
-
…then `GET /signalk/v2/api/resources/dsc-calls`.
|
|
76
|
-
|
|
77
132
|
## Limitations
|
|
78
133
|
|
|
79
134
|
- Distress relays, acknowledgements, and cancellations are stored (with
|
|
Binary file
|
|
Binary file
|
package/lib/dsc.js
CHANGED
|
@@ -112,8 +112,15 @@ function parseDsc(parts) {
|
|
|
112
112
|
const distress = event.category === 'distress';
|
|
113
113
|
if (distress) {
|
|
114
114
|
const natureCode = field(parts, 3);
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
// natureCode arrives over the air, unsanitised. Only a clean numeric code
|
|
116
|
+
// may reach the NATURES lookup or the code-NN fallback: a key like
|
|
117
|
+
// "__proto__" would otherwise resolve to Object.prototype, and any dotted
|
|
118
|
+
// value would inject extra segments into the notification path that the
|
|
119
|
+
// server walks unguarded (SignalK/signalk-server#2768). Anything else
|
|
120
|
+
// collapses to a safe constant.
|
|
121
|
+
event.natureOfDistress = /^\d{1,2}$/.test(natureCode)
|
|
122
|
+
? NATURES[natureCode] || `code-${natureCode}`
|
|
123
|
+
: 'undesignated';
|
|
117
124
|
event.distressedMmsi = parseMmsi(parts[7]);
|
|
118
125
|
}
|
|
119
126
|
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sailingnaturali/signalk-dsc",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
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": {
|
|
7
|
-
"test": "node --test"
|
|
7
|
+
"test": "node --test",
|
|
8
|
+
"send-test-dsc": "node scripts/send-test-dsc.js"
|
|
8
9
|
},
|
|
9
10
|
"keywords": [
|
|
10
11
|
"signalk-node-server-plugin",
|
|
@@ -25,9 +26,17 @@
|
|
|
25
26
|
"bugs": {
|
|
26
27
|
"url": "https://github.com/sailingnaturali/signalk-dsc/issues"
|
|
27
28
|
},
|
|
29
|
+
"signalk": {
|
|
30
|
+
"displayName": "DSC",
|
|
31
|
+
"screenshots": [
|
|
32
|
+
"./docs/screenshots/config.png",
|
|
33
|
+
"./docs/screenshots/data-table.png"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
28
36
|
"files": [
|
|
29
37
|
"index.js",
|
|
30
|
-
"lib"
|
|
38
|
+
"lib",
|
|
39
|
+
"docs/screenshots/"
|
|
31
40
|
],
|
|
32
41
|
"publishConfig": {
|
|
33
42
|
"access": "public"
|