@signalk/streams 2.0.1 → 2.0.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/.prettierrc.json +4 -0
- package/README.md +6 -6
- package/autodetect.js +5 -5
- package/canboatjs.js +8 -7
- package/execute.js +8 -6
- package/filestream.js +2 -2
- package/folderstream.js +20 -23
- package/from_json.js +2 -2
- package/gpsd.js +12 -9
- package/keys-filter.js +6 -6
- package/liner.js +2 -2
- package/log.js +3 -3
- package/logging.js +31 -26
- package/mdns-ws.js +57 -33
- package/n2k-signalk.js +88 -61
- package/n2kAnalyzer.js +4 -4
- package/nmea0183-signalk.js +9 -9
- package/nullprovider.js +2 -2
- package/package.json +6 -3
- package/replacer.js +2 -4
- package/s3.js +10 -13
- package/serialport.js +6 -6
- package/signalk-streams-3.0.1.tgz +0 -0
- package/simple.js +81 -63
- package/splitting-liner.js +2 -2
- package/tcp.js +25 -22
- package/tcpserver.js +2 -2
- package/timestamp-throttle.js +3 -3
- package/udp.js +2 -2
package/n2k-signalk.js
CHANGED
|
@@ -20,22 +20,22 @@ const N2kMapper = require('@signalk/n2k-signalk').N2kMapper
|
|
|
20
20
|
|
|
21
21
|
require('util').inherits(ToSignalK, Transform)
|
|
22
22
|
|
|
23
|
-
function ToSignalK
|
|
23
|
+
function ToSignalK(options) {
|
|
24
24
|
Transform.call(this, {
|
|
25
|
-
objectMode: true
|
|
25
|
+
objectMode: true,
|
|
26
26
|
})
|
|
27
27
|
const n2kOutEvent = 'nmea2000JsonOut'
|
|
28
28
|
this.sourceMeta = {}
|
|
29
29
|
this.notifications = {}
|
|
30
30
|
this.options = options
|
|
31
31
|
this.app = options.app
|
|
32
|
-
if (
|
|
33
|
-
this.filters = options.filters.filter(f => {
|
|
32
|
+
if (options.filters && options.filtersEnabled) {
|
|
33
|
+
this.filters = options.filters.filter((f) => {
|
|
34
34
|
return (f.source && f.source.length) || (f.pgn && f.pgn.length)
|
|
35
35
|
})
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
this.n2kMapper = new N2kMapper({...options, sendMetaData: true})
|
|
38
|
+
this.n2kMapper = new N2kMapper({ ...options, sendMetaData: true })
|
|
39
39
|
|
|
40
40
|
this.n2kMapper.on('n2kOut', (pgn) => this.app.emit('nmea2000JsonOut', pgn))
|
|
41
41
|
|
|
@@ -43,7 +43,7 @@ function ToSignalK (options) {
|
|
|
43
43
|
const existing = this.sourceMeta[n2k.src] || {}
|
|
44
44
|
this.sourceMeta[n2k.src] = {
|
|
45
45
|
...existing,
|
|
46
|
-
...meta
|
|
46
|
+
...meta,
|
|
47
47
|
}
|
|
48
48
|
const delta = {
|
|
49
49
|
context: this.app.selfContext,
|
|
@@ -54,21 +54,24 @@ function ToSignalK (options) {
|
|
|
54
54
|
label: this.options.providerId,
|
|
55
55
|
type: 'NMEA2000',
|
|
56
56
|
pgn: Number(n2k.pgn),
|
|
57
|
-
src: n2k.src.toString()
|
|
57
|
+
src: n2k.src.toString(),
|
|
58
58
|
},
|
|
59
59
|
timestamp:
|
|
60
60
|
n2k.timestamp.substring(0, 10) +
|
|
61
61
|
'T' +
|
|
62
62
|
n2k.timestamp.substring(11, n2k.timestamp.length),
|
|
63
|
-
values: []
|
|
64
|
-
}
|
|
65
|
-
]
|
|
63
|
+
values: [],
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
66
|
}
|
|
67
|
-
this.app.deltaCache.setSourceDelta(
|
|
67
|
+
this.app.deltaCache.setSourceDelta(
|
|
68
|
+
`${this.options.providerId}.${n2k.src}`,
|
|
69
|
+
delta
|
|
70
|
+
)
|
|
68
71
|
})
|
|
69
72
|
|
|
70
73
|
this.n2kMapper.on('n2kSourceMetadataTimeout', (pgn, src) => {
|
|
71
|
-
if (
|
|
74
|
+
if (pgn == 60928) {
|
|
72
75
|
console.warn(`n2k-signalk: unable to detect can name for src ${src}`)
|
|
73
76
|
this.sourceMeta[src].unknowCanName = true
|
|
74
77
|
}
|
|
@@ -76,86 +79,110 @@ function ToSignalK (options) {
|
|
|
76
79
|
|
|
77
80
|
this.n2kMapper.on('n2kSourceChanged', (src, from, to) => {
|
|
78
81
|
console.warn(`n2k-signalk: address ${src} changed from ${from} ${to}`)
|
|
79
|
-
if (
|
|
82
|
+
if (this.sourceMeta[src]) {
|
|
80
83
|
delete this.sourceMeta[src]
|
|
81
84
|
}
|
|
82
85
|
})
|
|
83
86
|
|
|
84
|
-
if (
|
|
87
|
+
if (this.app.isNmea2000OutAvailable) {
|
|
85
88
|
this.n2kMapper.n2kOutIsAvailable(this.app, n2kOutEvent)
|
|
86
89
|
} else {
|
|
87
90
|
this.app.on('nmea2000OutAvailable', () =>
|
|
88
|
-
|
|
91
|
+
this.n2kMapper.n2kOutIsAvailable(this.app, n2kOutEvent)
|
|
92
|
+
)
|
|
89
93
|
}
|
|
90
94
|
}
|
|
91
95
|
|
|
92
|
-
ToSignalK.prototype.isFiltered = function(source) {
|
|
93
|
-
return
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
ToSignalK.prototype.isFiltered = function (source) {
|
|
97
|
+
return (
|
|
98
|
+
this.filters &&
|
|
99
|
+
this.filters.find((filter) => {
|
|
100
|
+
const sFilter = this.options.useCanName ? source.canName : source.src
|
|
101
|
+
return (
|
|
102
|
+
(!filter.source ||
|
|
103
|
+
filter.source.length === 0 ||
|
|
104
|
+
filter.source == sFilter) &&
|
|
105
|
+
(!filter.pgn || filter.pgn.length === 0 || filter.pgn == source.pgn)
|
|
106
|
+
)
|
|
107
|
+
})
|
|
108
|
+
)
|
|
97
109
|
}
|
|
98
110
|
|
|
99
111
|
ToSignalK.prototype._transform = function (chunk, encoding, done) {
|
|
100
112
|
try {
|
|
101
113
|
const delta = this.n2kMapper.toDelta(chunk)
|
|
102
|
-
|
|
114
|
+
|
|
103
115
|
const src = Number(chunk.src)
|
|
104
|
-
if (
|
|
116
|
+
if (!this.sourceMeta[src]) {
|
|
105
117
|
this.sourceMeta[src] = {}
|
|
106
|
-
}
|
|
118
|
+
}
|
|
107
119
|
|
|
108
|
-
if (
|
|
109
|
-
|
|
120
|
+
if (
|
|
121
|
+
delta &&
|
|
122
|
+
delta.updates[0].values.length > 0 &&
|
|
123
|
+
!this.isFiltered(delta.updates[0].source)
|
|
124
|
+
) {
|
|
125
|
+
if (!this.options.useCanName) {
|
|
110
126
|
delete delta.updates[0].source.canName
|
|
111
127
|
}
|
|
112
128
|
|
|
113
129
|
const canName = delta.updates[0].source.canName
|
|
114
|
-
|
|
115
|
-
if (
|
|
130
|
+
|
|
131
|
+
if (
|
|
132
|
+
this.options.useCanName &&
|
|
133
|
+
!canName &&
|
|
134
|
+
!this.sourceMeta[src].unknowCanName
|
|
135
|
+
) {
|
|
116
136
|
done()
|
|
117
137
|
return
|
|
118
138
|
}
|
|
119
139
|
|
|
120
|
-
delta.updates.forEach(update => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
140
|
+
delta.updates.forEach((update) => {
|
|
141
|
+
update.values.forEach((kv) => {
|
|
142
|
+
if (kv.path && kv.path.startsWith('notifications.')) {
|
|
143
|
+
if (
|
|
144
|
+
kv.value.state === 'normal' &&
|
|
145
|
+
this.notifications[kv.path] &&
|
|
146
|
+
this.notifications[kv.path][src]
|
|
147
|
+
) {
|
|
148
|
+
clearInterval(this.notifications[kv.path][src].interval)
|
|
149
|
+
delete this.notifications[kv.path][src]
|
|
150
|
+
} else if (kv.value.state !== 'normal') {
|
|
151
|
+
if (!this.notifications[kv.path]) {
|
|
152
|
+
this.notifications[kv.path] = {}
|
|
153
|
+
}
|
|
154
|
+
if (!this.notifications[kv.path][src]) {
|
|
155
|
+
const interval = setInterval(() => {
|
|
156
|
+
if (
|
|
157
|
+
Date.now() - this.notifications[kv.path][src].lastTime >
|
|
158
|
+
10000
|
|
159
|
+
) {
|
|
160
|
+
const copy = JSON.parse(JSON.stringify(kv))
|
|
161
|
+
copy.value.state = 'normal'
|
|
162
|
+
const normalDelta = {
|
|
163
|
+
context: delta.context,
|
|
164
|
+
updates: [
|
|
165
|
+
{
|
|
166
|
+
source: update.source,
|
|
167
|
+
values: [copy],
|
|
168
|
+
},
|
|
169
|
+
],
|
|
147
170
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
interval: interval
|
|
171
|
+
delete this.notifications[kv.path][src]
|
|
172
|
+
clearInterval(interval)
|
|
173
|
+
this.app.handleMessage(this.options.providerId, normalDelta)
|
|
152
174
|
}
|
|
153
|
-
}
|
|
154
|
-
|
|
175
|
+
}, 5000)
|
|
176
|
+
this.notifications[kv.path][src] = {
|
|
177
|
+
lastTime: Date.now(),
|
|
178
|
+
interval: interval,
|
|
155
179
|
}
|
|
180
|
+
} else {
|
|
181
|
+
this.notifications[kv.path][src].lastTime = Date.now()
|
|
156
182
|
}
|
|
157
183
|
}
|
|
158
|
-
}
|
|
184
|
+
}
|
|
185
|
+
})
|
|
159
186
|
})
|
|
160
187
|
this.push(delta)
|
|
161
188
|
}
|
package/n2kAnalyzer.js
CHANGED
|
@@ -16,19 +16,19 @@
|
|
|
16
16
|
|
|
17
17
|
const Transform = require('stream').Transform
|
|
18
18
|
|
|
19
|
-
function N2KAnalyzer
|
|
19
|
+
function N2KAnalyzer(options) {
|
|
20
20
|
Transform.call(this, {
|
|
21
|
-
objectMode: true
|
|
21
|
+
objectMode: true,
|
|
22
22
|
})
|
|
23
23
|
if (process.platform === 'win32') {
|
|
24
24
|
this.analyzerProcess = require('child_process').spawn('cmd', [
|
|
25
25
|
'/c',
|
|
26
|
-
'analyzer -json -si'
|
|
26
|
+
'analyzer -json -si',
|
|
27
27
|
])
|
|
28
28
|
} else {
|
|
29
29
|
this.analyzerProcess = require('child_process').spawn('sh', [
|
|
30
30
|
'-c',
|
|
31
|
-
'analyzer -json -si'
|
|
31
|
+
'analyzer -json -si',
|
|
32
32
|
])
|
|
33
33
|
}
|
|
34
34
|
this.analyzerProcess.stderr.on('data', function (data) {
|
package/nmea0183-signalk.js
CHANGED
|
@@ -35,9 +35,9 @@ const utils = require('@signalk/nmea0183-utilities')
|
|
|
35
35
|
const n2kToDelta = require('@signalk/n2k-signalk').toDelta
|
|
36
36
|
const FromPgn = require('@canboat/canboatjs').FromPgn
|
|
37
37
|
|
|
38
|
-
function Nmea0183ToSignalK
|
|
38
|
+
function Nmea0183ToSignalK(options) {
|
|
39
39
|
Transform.call(this, {
|
|
40
|
-
objectMode: true
|
|
40
|
+
objectMode: true,
|
|
41
41
|
})
|
|
42
42
|
|
|
43
43
|
this.parser = new Parser(options)
|
|
@@ -49,7 +49,7 @@ function Nmea0183ToSignalK (options) {
|
|
|
49
49
|
|
|
50
50
|
// Prepare a list of events to send for each sentence received
|
|
51
51
|
this.sentenceEvents = options.suppress0183event ? [] : ['nmea0183']
|
|
52
|
-
this.appendChecksum = options.appendChecksum
|
|
52
|
+
this.appendChecksum = options.appendChecksum
|
|
53
53
|
|
|
54
54
|
if (options.sentenceEvent) {
|
|
55
55
|
if (Array.isArray(options.sentenceEvent)) {
|
|
@@ -78,19 +78,19 @@ Nmea0183ToSignalK.prototype._transform = function (chunk, encoding, done) {
|
|
|
78
78
|
try {
|
|
79
79
|
if (sentence !== undefined) {
|
|
80
80
|
if (this.appendChecksum) {
|
|
81
|
-
sentence = utils.appendChecksum(sentence)
|
|
81
|
+
sentence = utils.appendChecksum(sentence)
|
|
82
82
|
}
|
|
83
83
|
// Send 'sentences' event to the app for each sentence
|
|
84
|
-
this.sentenceEvents.forEach(eventName => {
|
|
84
|
+
this.sentenceEvents.forEach((eventName) => {
|
|
85
85
|
this.app.emit(eventName, sentence)
|
|
86
86
|
this.app.signalk.emit(eventName, sentence)
|
|
87
87
|
})
|
|
88
88
|
|
|
89
89
|
let delta = null
|
|
90
|
-
if (
|
|
90
|
+
if (this.n2kParser.isN2KOver0183(sentence)) {
|
|
91
91
|
const pgn = this.n2kParser.parseN2KOver0183(sentence)
|
|
92
|
-
if (
|
|
93
|
-
delta = n2kToDelta(pgn, this.state, {sendMetaData: true})
|
|
92
|
+
if (pgn) {
|
|
93
|
+
delta = n2kToDelta(pgn, this.state, { sendMetaData: true })
|
|
94
94
|
}
|
|
95
95
|
} else {
|
|
96
96
|
delta = this.parser.parse(sentence)
|
|
@@ -98,7 +98,7 @@ Nmea0183ToSignalK.prototype._transform = function (chunk, encoding, done) {
|
|
|
98
98
|
|
|
99
99
|
if (delta !== null) {
|
|
100
100
|
if (timestamp !== null) {
|
|
101
|
-
delta.updates.forEach(update => {
|
|
101
|
+
delta.updates.forEach((update) => {
|
|
102
102
|
update.timestamp = timestamp
|
|
103
103
|
})
|
|
104
104
|
}
|
package/nullprovider.js
CHANGED
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signalk/streams",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Utilities for handling streams of Signal K data",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"
|
|
7
|
+
"ci": "prettier --check .",
|
|
8
|
+
"format": "prettier --write ."
|
|
8
9
|
},
|
|
9
10
|
"repository": {
|
|
10
11
|
"type": "git",
|
|
@@ -28,7 +29,6 @@
|
|
|
28
29
|
"@signalk/nmea0183-utilities": "^0.8.0",
|
|
29
30
|
"@signalk/signalk-schema": "^1.5.0",
|
|
30
31
|
"any-shell-escape": "^0.1.1",
|
|
31
|
-
"aws-sdk": "^2.413.0",
|
|
32
32
|
"file-timestamp-stream": "^2.1.2",
|
|
33
33
|
"lodash": "^4.17.4",
|
|
34
34
|
"moment": "^2.24.0",
|
|
@@ -38,5 +38,8 @@
|
|
|
38
38
|
},
|
|
39
39
|
"optionalDependencies": {
|
|
40
40
|
"serialport": "^9.0.1"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"prettier": "2.5.1"
|
|
41
44
|
}
|
|
42
45
|
}
|
package/replacer.js
CHANGED
|
@@ -14,21 +14,19 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
|
|
18
17
|
const Transform = require('stream').Transform
|
|
19
18
|
|
|
20
19
|
require('util').inherits(Replacer, Transform)
|
|
21
20
|
|
|
22
|
-
function Replacer
|
|
21
|
+
function Replacer(options) {
|
|
23
22
|
Transform.call(this, {
|
|
24
|
-
objectMode: true
|
|
23
|
+
objectMode: true,
|
|
25
24
|
})
|
|
26
25
|
this.doPush = this.push.bind(this)
|
|
27
26
|
this.regexp = new RegExp(options.regexp, 'gu')
|
|
28
27
|
this.template = options.template
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
|
|
32
30
|
Replacer.prototype._transform = function (chunk, encoding, done) {
|
|
33
31
|
this.doPush(chunk.toString().replace(this.regexp, this.template))
|
|
34
32
|
done()
|
package/s3.js
CHANGED
|
@@ -25,9 +25,9 @@ var Transform = require('stream').Transform
|
|
|
25
25
|
*/
|
|
26
26
|
const AWS = require('aws-sdk')
|
|
27
27
|
|
|
28
|
-
function S3Provider
|
|
28
|
+
function S3Provider({ bucket, prefix }) {
|
|
29
29
|
Transform.call(this, {
|
|
30
|
-
objectMode: false
|
|
30
|
+
objectMode: false,
|
|
31
31
|
})
|
|
32
32
|
this.Bucket = bucket
|
|
33
33
|
this.Prefix = prefix
|
|
@@ -41,12 +41,12 @@ S3Provider.prototype.pipe = function (pipeTo) {
|
|
|
41
41
|
const s3 = new AWS.S3()
|
|
42
42
|
const params = {
|
|
43
43
|
Bucket: this.Bucket,
|
|
44
|
-
Prefix: this.Prefix
|
|
44
|
+
Prefix: this.Prefix,
|
|
45
45
|
}
|
|
46
46
|
console.log('listobjects')
|
|
47
47
|
s3.listObjects(params)
|
|
48
48
|
.promise()
|
|
49
|
-
.then(data => {
|
|
49
|
+
.then((data) => {
|
|
50
50
|
// console.log(data)
|
|
51
51
|
const jobs = data.Contents.map(
|
|
52
52
|
(item, i) =>
|
|
@@ -55,18 +55,15 @@ S3Provider.prototype.pipe = function (pipeTo) {
|
|
|
55
55
|
console.log('Starting key ' + item.Key)
|
|
56
56
|
const objectParams = {
|
|
57
57
|
Bucket: params.Bucket,
|
|
58
|
-
Key: item.Key
|
|
58
|
+
Key: item.Key,
|
|
59
59
|
}
|
|
60
60
|
const request = s3.getObject(objectParams)
|
|
61
|
-
request.on('error', err => {
|
|
61
|
+
request.on('error', (err) => {
|
|
62
62
|
console.log(err)
|
|
63
63
|
})
|
|
64
64
|
const stream = request.createReadStream()
|
|
65
65
|
stream.on('end', resolve)
|
|
66
|
-
stream.pipe(
|
|
67
|
-
pipeTo,
|
|
68
|
-
{ end: i === data.Contents.length-1 }
|
|
69
|
-
)
|
|
66
|
+
stream.pipe(pipeTo, { end: i === data.Contents.length - 1 })
|
|
70
67
|
})
|
|
71
68
|
}
|
|
72
69
|
)
|
|
@@ -74,14 +71,14 @@ S3Provider.prototype.pipe = function (pipeTo) {
|
|
|
74
71
|
let i = 0
|
|
75
72
|
function startNext() {
|
|
76
73
|
if (i < jobs.length) {
|
|
77
|
-
jobs[i++]().then(startNext)
|
|
74
|
+
jobs[i++]().then(startNext)
|
|
78
75
|
} else {
|
|
79
76
|
doEnd()
|
|
80
77
|
}
|
|
81
78
|
}
|
|
82
|
-
startNext()
|
|
79
|
+
startNext()
|
|
83
80
|
})
|
|
84
|
-
.catch(error => {
|
|
81
|
+
.catch((error) => {
|
|
85
82
|
console.error(error)
|
|
86
83
|
})
|
|
87
84
|
return pipeTo
|
package/serialport.js
CHANGED
|
@@ -64,7 +64,7 @@ const SerialPort = require('serialport')
|
|
|
64
64
|
const isArray = require('lodash').isArray
|
|
65
65
|
const isBuffer = require('lodash').isBuffer
|
|
66
66
|
|
|
67
|
-
function SerialStream
|
|
67
|
+
function SerialStream(options) {
|
|
68
68
|
if (!(this instanceof SerialStream)) {
|
|
69
69
|
return new SerialStream(options)
|
|
70
70
|
}
|
|
@@ -105,7 +105,7 @@ SerialStream.prototype.start = function () {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
this.serial = new SerialPort(this.options.device, {
|
|
108
|
-
baudRate: this.options.baudrate
|
|
108
|
+
baudRate: this.options.baudrate,
|
|
109
109
|
})
|
|
110
110
|
|
|
111
111
|
this.serial.on(
|
|
@@ -148,22 +148,22 @@ SerialStream.prototype.start = function () {
|
|
|
148
148
|
let pendingWrites = 0
|
|
149
149
|
const stdOutEvent = this.options.toStdout
|
|
150
150
|
if (stdOutEvent) {
|
|
151
|
-
(isArray(stdOutEvent) ? stdOutEvent : [stdOutEvent]).forEach(event => {
|
|
151
|
+
;(isArray(stdOutEvent) ? stdOutEvent : [stdOutEvent]).forEach((event) => {
|
|
152
152
|
const onDrain = () => {
|
|
153
153
|
pendingWrites--
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
that.options.app.on(event, d => {
|
|
156
|
+
that.options.app.on(event, (d) => {
|
|
157
157
|
if (pendingWrites > that.maxPendingWrites) {
|
|
158
158
|
that.debug('Buffer overflow, not writing:' + d)
|
|
159
159
|
return
|
|
160
160
|
}
|
|
161
161
|
that.debug('Writing:' + d)
|
|
162
|
-
if (
|
|
162
|
+
if (isBuffer(d)) {
|
|
163
163
|
that.serial.write(d)
|
|
164
164
|
} else {
|
|
165
165
|
that.serial.write(d + '\r\n')
|
|
166
|
-
}
|
|
166
|
+
}
|
|
167
167
|
pendingWrites++
|
|
168
168
|
that.serial.drain(onDrain)
|
|
169
169
|
})
|
|
Binary file
|