node-red-contrib-ntrip 0.2.9 → 0.2.10
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/CHANGELOG.md +7 -0
- package/README.md +15 -0
- package/examples/watchdog.json +1 -0
- package/ntrip/lib/ntrip-client.js +37 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
|
3
3
|
|
|
4
|
+
## [0.2.10]
|
|
5
|
+
### NtripClient
|
|
6
|
+
- Reconnect attempts now use an exponential-ish backoff schedule (`1 s`, `2 s`, `5 s`, `10 s`, then capped at `10 s`) instead of the upstream library's fixed `2 s` interval. The schedule resets to `1 s` the moment the caster completes the `ICY 200 OK` handshake, so a brief outage restarts from the short end and a caster that stays down is no longer hammered.
|
|
7
|
+
|
|
8
|
+
### Documentation
|
|
9
|
+
- Added `examples/watchdog.json` — an example flow that alerts (via a built-in `trigger` node) when the NTRIP correction stream stops delivering data for more than 60 seconds. Closes [#4](https://github.com/windkh/node-red-contrib-ntrip/issues/4).
|
|
10
|
+
|
|
4
11
|
## [0.2.9]
|
|
5
12
|
### NtripClient
|
|
6
13
|
- Status badge now shows the inbound data rate alongside the Rx/Tx message counters (e.g. `2.4 kbps Rx 123 Tx 4`). The rate is sampled once per second and formatted as `bps`, `kbps`, or `Mbps` depending on magnitude.
|
package/README.md
CHANGED
|
@@ -299,6 +299,11 @@ A few things that are easy to get wrong:
|
|
|
299
299
|
- **NTRIP Client: CR/LF in credentials.** `mountpoint`, `username`, and
|
|
300
300
|
`password` are interpolated into the handshake string. CR/LF in these fields
|
|
301
301
|
is rejected at startup to prevent header injection.
|
|
302
|
+
- **NTRIP Client: reconnect backoff.** When the socket to the caster drops the
|
|
303
|
+
client waits `1 s`, then `2 s`, `5 s`, `10 s` before each successive retry
|
|
304
|
+
(capped at `10 s`). The schedule resets to `1 s` as soon as the caster
|
|
305
|
+
completes the `ICY 200 OK` handshake again — so a brief outage restarts at
|
|
306
|
+
the low end, and a caster that stays down doesn't get hammered.
|
|
302
307
|
- **NMEA Encoder input shape.** The encoder expects `msg.payload` to be an
|
|
303
308
|
object with `messageType` and `nmeaMessage` properties — not a NMEA string.
|
|
304
309
|
To re-encode the output of the NMEA Decoder you can pipe it straight in;
|
|
@@ -345,6 +350,16 @@ a local demo version of SNIP by creating a raw TCP input stream.
|
|
|
345
350
|
(SNIP can be found here https://www.use-snip.com)
|
|
346
351
|
See also example flow [**Upload flow**](examples/upload.json)
|
|
347
352
|
|
|
353
|
+
## Detect a stalled correction stream
|
|
354
|
+
NTRIP casters occasionally stop emitting data without closing the TCP socket
|
|
355
|
+
— the NtripClient node stays "connected" but no new frames arrive, and any
|
|
356
|
+
downstream rover eventually drops out of RTK-fixed mode without an obvious
|
|
357
|
+
cause. This example wires the NtripClient output into a built-in `trigger`
|
|
358
|
+
node configured to fire an alert message after 60 seconds of silence
|
|
359
|
+
(configurable via the trigger's Duration field). Every incoming frame resets
|
|
360
|
+
the timer, so the alert only fires when the stream is genuinely stalled.
|
|
361
|
+
See also example flow [**Watchdog flow**](examples/watchdog.json) (closes [#4](https://github.com/windkh/node-red-contrib-ntrip/issues/4))
|
|
362
|
+
|
|
348
363
|
# License
|
|
349
364
|
|
|
350
365
|
Author: Karl-Heinz Wind
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[{"id":"47bd8463328d83d3","type":"comment","z":"a604108643639054","name":"NTRIP stream stall watchdog — alert after 60s of silence","info":"Alerts when the NTRIP correction stream stops delivering data.\n\nHow it works:\n- Every message from the NTRIP Client resets the trigger node's timer.\n- If no message arrives within 60 seconds, the trigger fires and the STALL\n debug pane shows an alert.\n- When data resumes, the next message resets the timer — no explicit\n \"recovered\" notification is emitted (extend the flow with a function\n node if you need that).\n\nAdjust the timeout in the trigger node's Duration field.\n","x":260,"y":80,"wires":[]},{"id":"9f622b9ab6a72772","type":"NtripClient","z":"a604108643639054","description":"RTK2Go","passthrough":false,"port":"2101","host":"rtk2go.com","mountpoint":"Foo","interval":1000,"xcoordinate":"","ycoordinate":"","zcoordinate":"","x":140,"y":180,"wires":[["5107785e11b2425a","eb42f2cd60fcdc8f"]]},{"id":"5107785e11b2425a","type":"debug","z":"a604108643639054","name":"data (each frame)","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":430,"y":140,"wires":[]},{"id":"eb42f2cd60fcdc8f","type":"trigger","z":"a604108643639054","name":"60s stall watchdog","op1":"","op2":"NTRIP stream stalled — no data for 60 s","op1type":"nul","op2type":"str","duration":"60","extend":true,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":440,"y":220,"wires":[["25f028d01cad6b57"]]},{"id":"25f028d01cad6b57","type":"debug","z":"a604108643639054","name":"STALL","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":660,"y":220,"wires":[]}]
|
|
@@ -4,8 +4,43 @@
|
|
|
4
4
|
const { NtripClient } = require('ntrip-client');
|
|
5
5
|
const net = require('net');
|
|
6
6
|
|
|
7
|
+
// Backoff schedule for reconnect attempts, in milliseconds. The upstream
|
|
8
|
+
// client's default is a fixed 2000ms interval which flooded casters (and the
|
|
9
|
+
// Node-RED error log) when a server was down for a while. See issue on repeated
|
|
10
|
+
// error output during outages. The last entry acts as a cap for further retries.
|
|
11
|
+
const RECONNECT_BACKOFF_MS = [1000, 2000, 5000, 10000];
|
|
12
|
+
|
|
13
|
+
// Extends the upstream client with an exponential backoff on reconnect.
|
|
14
|
+
// The schedule advances on each failed reconnect and resets to the first
|
|
15
|
+
// entry as soon as the caster completes the handshake (`ICY 200 OK`).
|
|
16
|
+
class NtripClientWithBackoff extends NtripClient {
|
|
17
|
+
constructor(options) {
|
|
18
|
+
super(options);
|
|
19
|
+
this._backoffIndex = 0;
|
|
20
|
+
this.reconnectInterval = RECONNECT_BACKOFF_MS[0];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
_onData(data) {
|
|
24
|
+
const wasReady = this.isReady;
|
|
25
|
+
super._onData(data);
|
|
26
|
+
// Reset the backoff schedule the moment the handshake completes —
|
|
27
|
+
// subsequent connection failures start over at the first entry.
|
|
28
|
+
if (!wasReady && this.isReady) {
|
|
29
|
+
this._backoffIndex = 0;
|
|
30
|
+
this.reconnectInterval = RECONNECT_BACKOFF_MS[0];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async _reconnect() {
|
|
35
|
+
const step = Math.min(this._backoffIndex, RECONNECT_BACKOFF_MS.length - 1);
|
|
36
|
+
this.reconnectInterval = RECONNECT_BACKOFF_MS[step];
|
|
37
|
+
this._backoffIndex++;
|
|
38
|
+
return super._reconnect();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
7
42
|
// Orginal class is extended to be able to send data to the caster.
|
|
8
|
-
class NtripClientUploader extends
|
|
43
|
+
class NtripClientUploader extends NtripClientWithBackoff {
|
|
9
44
|
constructor(options) {
|
|
10
45
|
super(options);
|
|
11
46
|
this.authmode = options.authmode || 'legacy';
|
|
@@ -98,7 +133,7 @@ class NtripClientUploader extends NtripClient {
|
|
|
98
133
|
}
|
|
99
134
|
|
|
100
135
|
function createDownloader(options) {
|
|
101
|
-
return new
|
|
136
|
+
return new NtripClientWithBackoff(options);
|
|
102
137
|
}
|
|
103
138
|
|
|
104
139
|
function createUploader(options) {
|