@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/.prettierrc.json
ADDED
package/README.md
CHANGED
|
@@ -6,9 +6,9 @@ The code is not compiled and is not more effective, but allows using the streams
|
|
|
6
6
|
|
|
7
7
|
## Development
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
- Install dev packages with `npm i`.
|
|
10
|
+
- Edit files with `/src`.
|
|
11
|
+
- `npm link`
|
|
12
|
+
- `cd ../../`
|
|
13
|
+
- `npm link @signalk/streams`
|
|
14
|
+
- Restart signalk `npm start`
|
package/autodetect.js
CHANGED
|
@@ -45,12 +45,12 @@ A => actisense-serial format N2K data
|
|
|
45
45
|
1471172400153;A;2016-07-16T12:00:00.000Z,2,130306,105,255,8,00,d1,03,c9,23,fa,ff,ff
|
|
46
46
|
*/
|
|
47
47
|
|
|
48
|
-
function DeMultiplexer
|
|
48
|
+
function DeMultiplexer(options) {
|
|
49
49
|
Writable.call(this)
|
|
50
50
|
|
|
51
51
|
this.toTimestamped = new ToTimestamped(this, options)
|
|
52
52
|
this.timestampThrottle = new TimestampThrottle({
|
|
53
|
-
getMilliseconds: msg => msg.timestamp
|
|
53
|
+
getMilliseconds: (msg) => msg.timestamp,
|
|
54
54
|
})
|
|
55
55
|
this.splitter = new Splitter(this, options)
|
|
56
56
|
this.options = options
|
|
@@ -66,7 +66,7 @@ DeMultiplexer.prototype.write = function (chunk, encoding, callback) {
|
|
|
66
66
|
return this.toTimestamped.write(chunk, encoding, callback)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
function Splitter
|
|
69
|
+
function Splitter(deMultiplexer, options) {
|
|
70
70
|
Transform.call(this, { objectMode: true })
|
|
71
71
|
this.demuxEmitData = function (msg) {
|
|
72
72
|
deMultiplexer.emit('data', msg)
|
|
@@ -91,7 +91,7 @@ Splitter.prototype._transform = function (msg, encoding, _done) {
|
|
|
91
91
|
let done = _done
|
|
92
92
|
try {
|
|
93
93
|
switch (msg.discriminator) {
|
|
94
|
-
|
|
94
|
+
case 'A': {
|
|
95
95
|
msg.fromFile = true
|
|
96
96
|
const result = this.fromActisenseSerial.write(msg, encoding)
|
|
97
97
|
if (!result) {
|
|
@@ -130,7 +130,7 @@ Splitter.prototype.pipe = function (target) {
|
|
|
130
130
|
return Transform.prototype.pipe.call(this, target)
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
function ToTimestamped
|
|
133
|
+
function ToTimestamped(deMultiplexer, options) {
|
|
134
134
|
Transform.call(this, { objectMode: true })
|
|
135
135
|
this.deMultiplexer = deMultiplexer
|
|
136
136
|
this.options = options
|
package/canboatjs.js
CHANGED
|
@@ -18,21 +18,22 @@ const Transform = require('stream').Transform
|
|
|
18
18
|
const FromPgn = require('@canboat/canboatjs').FromPgn
|
|
19
19
|
const _ = require('lodash')
|
|
20
20
|
|
|
21
|
-
function CanboatJs
|
|
21
|
+
function CanboatJs(options) {
|
|
22
22
|
Transform.call(this, {
|
|
23
|
-
objectMode: true
|
|
23
|
+
objectMode: true,
|
|
24
24
|
})
|
|
25
25
|
|
|
26
26
|
this.fromPgn = new FromPgn(options)
|
|
27
|
-
const createDebug = options.createDebug ||
|
|
27
|
+
const createDebug = options.createDebug || require('debug')
|
|
28
28
|
const debug = createDebug('signalk:streams:nmea0183-signalk')
|
|
29
29
|
|
|
30
|
-
|
|
31
30
|
this.fromPgn.on('warning', (pgn, warning) => {
|
|
32
31
|
debug(`[warning] ${pgn.pgn} ${warning}`)
|
|
33
32
|
})
|
|
34
33
|
|
|
35
|
-
this.fromPgn.on('error', (pgn, err) => {
|
|
34
|
+
this.fromPgn.on('error', (pgn, err) => {
|
|
35
|
+
console.log(err)
|
|
36
|
+
})
|
|
36
37
|
|
|
37
38
|
this.app = options.app
|
|
38
39
|
}
|
|
@@ -42,14 +43,14 @@ require('util').inherits(CanboatJs, Transform)
|
|
|
42
43
|
CanboatJs.prototype._transform = function (chunk, encoding, done) {
|
|
43
44
|
if (_.isObject(chunk) && chunk.fromFile) {
|
|
44
45
|
const pgnData = this.fromPgn.parse(chunk.data)
|
|
45
|
-
if (
|
|
46
|
+
if (pgnData) {
|
|
46
47
|
pgnData.timestamp = new Date(Number(chunk.timestamp)).toISOString()
|
|
47
48
|
this.push(pgnData)
|
|
48
49
|
this.app.emit('N2KAnalyzerOut', pgnData)
|
|
49
50
|
}
|
|
50
51
|
} else {
|
|
51
52
|
const pgnData = this.fromPgn.parse(chunk)
|
|
52
|
-
if (
|
|
53
|
+
if (pgnData) {
|
|
53
54
|
this.push(pgnData)
|
|
54
55
|
this.app.emit('N2KAnalyzerOut', pgnData)
|
|
55
56
|
}
|
package/execute.js
CHANGED
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
const Transform = require('stream').Transform
|
|
40
40
|
const { pgnToActisenseSerialFormat } = require('@canboat/canboatjs')
|
|
41
41
|
|
|
42
|
-
function Execute
|
|
42
|
+
function Execute(options) {
|
|
43
43
|
Transform.call(this, {})
|
|
44
44
|
this.options = options
|
|
45
|
-
const createDebug = options.createDebug ||
|
|
45
|
+
const createDebug = options.createDebug || require('debug')
|
|
46
46
|
this.debug = options.debug || createDebug('signalk:streams:execute')
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -53,7 +53,7 @@ Execute.prototype._transform = function (chunk, encoding, done) {
|
|
|
53
53
|
this.analyzerProcess.stdin.write(chunk.toString())
|
|
54
54
|
done()
|
|
55
55
|
}
|
|
56
|
-
function start
|
|
56
|
+
function start(command, that) {
|
|
57
57
|
that.debug(`starting |${command}|`)
|
|
58
58
|
if (process.platform === 'win32') {
|
|
59
59
|
that.childProcess = require('child_process').spawn('cmd', ['/c', command])
|
|
@@ -76,7 +76,7 @@ function start (command, that) {
|
|
|
76
76
|
that.push(data)
|
|
77
77
|
})
|
|
78
78
|
|
|
79
|
-
that.childProcess.on('close', code => {
|
|
79
|
+
that.childProcess.on('close', (code) => {
|
|
80
80
|
const msg = `|${command}| exited with ${code}`
|
|
81
81
|
// that.options.app.setProviderError(that.options.providerId, msg)
|
|
82
82
|
console.error(msg)
|
|
@@ -107,7 +107,9 @@ Execute.prototype.pipe = function (pipeTo) {
|
|
|
107
107
|
start(this.options.command, this)
|
|
108
108
|
|
|
109
109
|
const stdOutEvent = this.options.toChildProcess || 'toChildProcess'
|
|
110
|
-
this.debug(
|
|
110
|
+
this.debug(
|
|
111
|
+
'Using event ' + stdOutEvent + " for output to child process's stdin"
|
|
112
|
+
)
|
|
111
113
|
const that = this
|
|
112
114
|
that.options.app.on(stdOutEvent, function (d) {
|
|
113
115
|
try {
|
|
@@ -118,7 +120,7 @@ Execute.prototype.pipe = function (pipeTo) {
|
|
|
118
120
|
})
|
|
119
121
|
|
|
120
122
|
if (stdOutEvent === 'nmea2000out') {
|
|
121
|
-
that.options.app.on('nmea2000JsonOut', pgn => {
|
|
123
|
+
that.options.app.on('nmea2000JsonOut', (pgn) => {
|
|
122
124
|
that.childProcess.stdin.write(pgnToActisenseSerialFormat(pgn) + '\r\n')
|
|
123
125
|
})
|
|
124
126
|
that.options.app.emit('nmea2000OutAvailable')
|
package/filestream.js
CHANGED
|
@@ -37,7 +37,7 @@ const path = require('path')
|
|
|
37
37
|
const PassThrough = require('stream').PassThrough
|
|
38
38
|
const fs = require('fs')
|
|
39
39
|
|
|
40
|
-
function EndIgnoringPassThrough
|
|
40
|
+
function EndIgnoringPassThrough() {
|
|
41
41
|
PassThrough.call(this)
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -72,7 +72,7 @@ FileStream.prototype.startStream = function () {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
this.filestream = require('fs').createReadStream(filename)
|
|
75
|
-
this.filestream.on('error', err => {
|
|
75
|
+
this.filestream.on('error', (err) => {
|
|
76
76
|
console.error(err.message)
|
|
77
77
|
this.keepRunning = false
|
|
78
78
|
})
|
package/folderstream.js
CHANGED
|
@@ -1,39 +1,36 @@
|
|
|
1
|
-
const Transform = require(
|
|
2
|
-
const fs = require(
|
|
1
|
+
const Transform = require('stream').Transform
|
|
2
|
+
const fs = require('fs')
|
|
3
3
|
|
|
4
4
|
function FolderStreamProvider(folder) {
|
|
5
5
|
Transform.call(this, {
|
|
6
6
|
objectMode: false,
|
|
7
|
-
})
|
|
8
|
-
this.folder = folder
|
|
9
|
-
this.fileIndex = 0
|
|
7
|
+
})
|
|
8
|
+
this.folder = folder
|
|
9
|
+
this.fileIndex = 0
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
require(
|
|
12
|
+
require('util').inherits(FolderStreamProvider, Transform)
|
|
13
13
|
|
|
14
|
-
FolderStreamProvider.prototype.pipe = function(pipeTo) {
|
|
15
|
-
const files = fs.readdirSync(this.folder)
|
|
16
|
-
pipeNextFile.bind(this)()
|
|
14
|
+
FolderStreamProvider.prototype.pipe = function (pipeTo) {
|
|
15
|
+
const files = fs.readdirSync(this.folder)
|
|
16
|
+
pipeNextFile.bind(this)()
|
|
17
17
|
|
|
18
18
|
function pipeNextFile() {
|
|
19
19
|
const fileStream = fs.createReadStream(
|
|
20
|
-
this.folder +
|
|
21
|
-
)
|
|
22
|
-
fileStream.pipe(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
);
|
|
26
|
-
fileStream.on("end", () => {
|
|
27
|
-
this.fileIndex++;
|
|
20
|
+
this.folder + '/' + files[this.fileIndex]
|
|
21
|
+
)
|
|
22
|
+
fileStream.pipe(pipeTo, { end: false })
|
|
23
|
+
fileStream.on('end', () => {
|
|
24
|
+
this.fileIndex++
|
|
28
25
|
if (this.fileIndex === files.length) {
|
|
29
|
-
pipeTo.end()
|
|
26
|
+
pipeTo.end()
|
|
30
27
|
} else {
|
|
31
|
-
pipeNextFile.bind(this)()
|
|
28
|
+
pipeNextFile.bind(this)()
|
|
32
29
|
}
|
|
33
|
-
})
|
|
30
|
+
})
|
|
34
31
|
}
|
|
35
32
|
|
|
36
|
-
return pipeTo
|
|
37
|
-
}
|
|
33
|
+
return pipeTo
|
|
34
|
+
}
|
|
38
35
|
|
|
39
|
-
module.exports = FolderStreamProvider
|
|
36
|
+
module.exports = FolderStreamProvider
|
package/from_json.js
CHANGED
package/gpsd.js
CHANGED
|
@@ -33,11 +33,11 @@
|
|
|
33
33
|
const Transform = require('stream').Transform
|
|
34
34
|
const gpsd = require('node-gpsd')
|
|
35
35
|
|
|
36
|
-
function Gpsd
|
|
36
|
+
function Gpsd(options) {
|
|
37
37
|
Transform.call(this, {
|
|
38
|
-
objectMode: true
|
|
38
|
+
objectMode: true,
|
|
39
39
|
})
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
const port = options.port || 2947
|
|
42
42
|
const hostname = options.hostname || options.host || 'localhost'
|
|
43
43
|
|
|
@@ -45,7 +45,7 @@ function Gpsd (options) {
|
|
|
45
45
|
options.app.setProviderStatus(options.providerId, msg)
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
const createDebug = options.createDebug ||
|
|
48
|
+
const createDebug = options.createDebug || require('debug')
|
|
49
49
|
|
|
50
50
|
this.listener = new gpsd.Listener({
|
|
51
51
|
port,
|
|
@@ -54,14 +54,17 @@ function Gpsd (options) {
|
|
|
54
54
|
info: createDebug('signalk:streams:gpsd'),
|
|
55
55
|
warn: console.warn,
|
|
56
56
|
error: (msg) => {
|
|
57
|
-
options.app.setProviderError(
|
|
58
|
-
|
|
57
|
+
options.app.setProviderError(
|
|
58
|
+
options.providerId,
|
|
59
|
+
`${hostname}:${port}: ` + msg
|
|
60
|
+
)
|
|
61
|
+
},
|
|
59
62
|
},
|
|
60
|
-
parse: false
|
|
63
|
+
parse: false,
|
|
61
64
|
})
|
|
62
65
|
|
|
63
66
|
setProviderStatus(`Connecting to ${hostname}:${port}`)
|
|
64
|
-
|
|
67
|
+
|
|
65
68
|
this.listener.connect(function () {
|
|
66
69
|
setProviderStatus(`Connected to ${hostname}:${port}`)
|
|
67
70
|
})
|
|
@@ -73,7 +76,7 @@ function Gpsd (options) {
|
|
|
73
76
|
|
|
74
77
|
this.listener.watch({
|
|
75
78
|
class: 'WATCH',
|
|
76
|
-
nmea: true
|
|
79
|
+
nmea: true,
|
|
77
80
|
})
|
|
78
81
|
}
|
|
79
82
|
|
package/keys-filter.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
const Transform = require('stream').Transform
|
|
4
4
|
|
|
5
|
-
function ToSignalK
|
|
5
|
+
function ToSignalK(options) {
|
|
6
6
|
Transform.call(this, {
|
|
7
|
-
objectMode: true
|
|
7
|
+
objectMode: true,
|
|
8
8
|
})
|
|
9
9
|
|
|
10
|
-
const createDebug = options.createDebug ||
|
|
10
|
+
const createDebug = options.createDebug || require('debug')
|
|
11
11
|
this.debug = createDebug('signalk:streams:keys-filter')
|
|
12
12
|
this.exclude = options.excludeMatchingPaths
|
|
13
13
|
}
|
|
@@ -32,11 +32,11 @@ ToSignalK.prototype._transform = function (chunk, encoding, done) {
|
|
|
32
32
|
|
|
33
33
|
if (Array.isArray(delta.updates)) {
|
|
34
34
|
const updates = []
|
|
35
|
-
delta.updates.forEach(update => {
|
|
35
|
+
delta.updates.forEach((update) => {
|
|
36
36
|
if (Array.isArray(update.values)) {
|
|
37
37
|
const values = []
|
|
38
38
|
|
|
39
|
-
update.values.forEach(value => {
|
|
39
|
+
update.values.forEach((value) => {
|
|
40
40
|
if (this.exclude.includes(value.path) !== true) {
|
|
41
41
|
values.push(value)
|
|
42
42
|
}
|
|
@@ -44,7 +44,7 @@ ToSignalK.prototype._transform = function (chunk, encoding, done) {
|
|
|
44
44
|
|
|
45
45
|
if (values.length > 0) {
|
|
46
46
|
const upd = {
|
|
47
|
-
values
|
|
47
|
+
values,
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
if (update.hasOwnProperty('$source')) {
|
package/liner.js
CHANGED
|
@@ -28,9 +28,9 @@ const Transform = require('stream').Transform
|
|
|
28
28
|
|
|
29
29
|
require('util').inherits(Liner, Transform)
|
|
30
30
|
|
|
31
|
-
function Liner
|
|
31
|
+
function Liner(options) {
|
|
32
32
|
Transform.call(this, {
|
|
33
|
-
objectMode: true
|
|
33
|
+
objectMode: true,
|
|
34
34
|
})
|
|
35
35
|
this.doPush = this.push.bind(this)
|
|
36
36
|
this.lineSeparator = options.lineSeparator || '\n'
|
package/log.js
CHANGED
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
const Transform = require('stream').Transform
|
|
33
33
|
const getLogger = require('./logging').getLogger
|
|
34
34
|
|
|
35
|
-
function Log
|
|
35
|
+
function Log(options) {
|
|
36
36
|
Transform.call(this, {
|
|
37
|
-
objectMode: true
|
|
37
|
+
objectMode: true,
|
|
38
38
|
})
|
|
39
39
|
|
|
40
40
|
this.logger = getLogger(options.app, options.discriminator, options.logdir)
|
|
@@ -48,7 +48,7 @@ Log.prototype._transform = function (msg, encoding, done) {
|
|
|
48
48
|
done()
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
function pad
|
|
51
|
+
function pad(num) {
|
|
52
52
|
return (num > 9 ? '' : '0') + num
|
|
53
53
|
}
|
|
54
54
|
|
package/logging.js
CHANGED
|
@@ -25,11 +25,11 @@ const loggers = {}
|
|
|
25
25
|
module.exports = {
|
|
26
26
|
getLogger,
|
|
27
27
|
getFullLogDir,
|
|
28
|
-
listLogFiles
|
|
28
|
+
listLogFiles,
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
class FileTimestampStreamWithDelete extends FileTimestampStream {
|
|
32
|
-
constructor(app, fullLogDir, filesToKeep, options){
|
|
32
|
+
constructor(app, fullLogDir, filesToKeep, options) {
|
|
33
33
|
super(options)
|
|
34
34
|
this.app = app
|
|
35
35
|
this.filesToKeep = filesToKeep
|
|
@@ -41,42 +41,42 @@ class FileTimestampStreamWithDelete extends FileTimestampStream {
|
|
|
41
41
|
// This method of base class is called when new file name is contemplated
|
|
42
42
|
// So let's override it to check how many files are there and delete the oldest ones
|
|
43
43
|
newFilename() {
|
|
44
|
-
if (this.prevFilename !== this.currentFilename){
|
|
44
|
+
if (this.prevFilename !== this.currentFilename) {
|
|
45
|
+
// Only do that after new file created
|
|
45
46
|
this.prevFilename = this.currentFilename
|
|
46
47
|
this.deleteOldFiles()
|
|
47
48
|
}
|
|
48
49
|
return super.newFilename()
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
deleteOldFiles(){
|
|
52
|
+
deleteOldFiles() {
|
|
52
53
|
debug(`Checking for old log files`)
|
|
53
54
|
listLogFiles(this.app, (err, files) => {
|
|
54
55
|
if (err) {
|
|
55
|
-
console.error(err)
|
|
56
|
-
}else{
|
|
56
|
+
console.error(err)
|
|
57
|
+
} else {
|
|
57
58
|
if (files.length > this.filesToKeep) {
|
|
58
|
-
const sortedFiles = files.sort()
|
|
59
|
-
const numToDelete =
|
|
59
|
+
const sortedFiles = files.sort()
|
|
60
|
+
const numToDelete = files.length - this.filesToKeep
|
|
60
61
|
debug(`Will delete ${numToDelete} files`)
|
|
61
|
-
for(let i = 0; i < numToDelete; i++){
|
|
62
|
+
for (let i = 0; i < numToDelete; i++) {
|
|
62
63
|
const fileName = path.join(this.fullLogDir, sortedFiles[i])
|
|
63
64
|
debug(`Deleting ${fileName}`)
|
|
64
65
|
fs.unlink(fileName, (err) => {
|
|
65
|
-
if (err){
|
|
66
|
+
if (err) {
|
|
66
67
|
console.error(err)
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
68
|
+
} else {
|
|
69
69
|
debug(`${fileName} was deleted`)
|
|
70
70
|
}
|
|
71
|
-
})
|
|
71
|
+
})
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
|
-
})
|
|
75
|
+
})
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
function getLogger
|
|
79
|
+
function getLogger(app, discriminator = '', logdir) {
|
|
80
80
|
const fullLogdir = getFullLogDir(app, logdir)
|
|
81
81
|
|
|
82
82
|
if (!loggers[fullLogdir]) {
|
|
@@ -85,26 +85,28 @@ function getLogger (app, discriminator = '', logdir) {
|
|
|
85
85
|
debug(`logging to ${fileName}`)
|
|
86
86
|
|
|
87
87
|
let fileTimestampStream
|
|
88
|
-
if (app.config.settings.keepMostRecentLogsOnly){
|
|
88
|
+
if (app.config.settings.keepMostRecentLogsOnly) {
|
|
89
|
+
// Delete old logs
|
|
89
90
|
fileTimestampStream = new FileTimestampStreamWithDelete(
|
|
90
|
-
app,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}else{ // Don't delete any logs
|
|
94
|
-
fileTimestampStream = new FileTimestampStream(
|
|
91
|
+
app,
|
|
92
|
+
fullLogdir,
|
|
93
|
+
app.config.settings.logCountToKeep,
|
|
95
94
|
{ path: fileName }
|
|
96
95
|
)
|
|
96
|
+
} else {
|
|
97
|
+
// Don't delete any logs
|
|
98
|
+
fileTimestampStream = new FileTimestampStream({ path: fileName })
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
loggers[fullLogdir] = fileTimestampStream
|
|
100
102
|
}
|
|
101
103
|
|
|
102
104
|
const logger = loggers[fullLogdir]
|
|
103
|
-
logger.on('error', err => {
|
|
105
|
+
logger.on('error', (err) => {
|
|
104
106
|
console.error(`Error opening data logging file: ${err.message}`)
|
|
105
107
|
})
|
|
106
108
|
|
|
107
|
-
return msg => {
|
|
109
|
+
return (msg) => {
|
|
108
110
|
try {
|
|
109
111
|
logger.write(
|
|
110
112
|
Date.now() +
|
|
@@ -120,7 +122,7 @@ function getLogger (app, discriminator = '', logdir) {
|
|
|
120
122
|
}
|
|
121
123
|
}
|
|
122
124
|
|
|
123
|
-
function getFullLogDir
|
|
125
|
+
function getFullLogDir(app, logdir) {
|
|
124
126
|
if (!logdir) {
|
|
125
127
|
logdir = app.config.settings.loggingDirectory || app.config.configPath
|
|
126
128
|
}
|
|
@@ -129,10 +131,13 @@ function getFullLogDir (app, logdir) {
|
|
|
129
131
|
: path.join(app.config.configPath, logdir)
|
|
130
132
|
}
|
|
131
133
|
|
|
132
|
-
function listLogFiles
|
|
134
|
+
function listLogFiles(app, cb) {
|
|
133
135
|
fs.readdir(getFullLogDir(app), (err, files) => {
|
|
134
136
|
if (!err) {
|
|
135
|
-
cb(
|
|
137
|
+
cb(
|
|
138
|
+
undefined,
|
|
139
|
+
files.filter((filename) => filename.match(filenamePattern))
|
|
140
|
+
)
|
|
136
141
|
} else {
|
|
137
142
|
cb(err)
|
|
138
143
|
}
|
package/mdns-ws.js
CHANGED
|
@@ -18,12 +18,11 @@ const Transform = require('stream').Transform
|
|
|
18
18
|
|
|
19
19
|
const SignalK = require('@signalk/client')
|
|
20
20
|
|
|
21
|
-
|
|
22
21
|
const WebSocket = require('ws')
|
|
23
22
|
|
|
24
|
-
function MdnsWs
|
|
23
|
+
function MdnsWs(options) {
|
|
25
24
|
Transform.call(this, {
|
|
26
|
-
objectMode: true
|
|
25
|
+
objectMode: true,
|
|
27
26
|
})
|
|
28
27
|
this.options = options
|
|
29
28
|
this.selfHost = options.app.config.getExternalHostname() + '.'
|
|
@@ -32,12 +31,12 @@ function MdnsWs (options) {
|
|
|
32
31
|
this.remoteServers[this.selfHost + ':' + this.selfPort] = {}
|
|
33
32
|
const deltaStreamBehaviour = options.subscription ? 'none' : 'all'
|
|
34
33
|
|
|
35
|
-
const createDebug = options.createDebug ||
|
|
34
|
+
const createDebug = options.createDebug || require('debug')
|
|
36
35
|
this.debug = createDebug('signalk:streams:mdns-ws')
|
|
37
36
|
this.dataDebug = createDebug('signalk:streams:mdns-ws-data')
|
|
38
37
|
debug(`deltaStreamBehaviour:${deltaStreamBehaviour}`)
|
|
39
38
|
|
|
40
|
-
this.handleContext = () => {
|
|
39
|
+
this.handleContext = () => {}
|
|
41
40
|
if (options.selfHandling === 'manualSelf') {
|
|
42
41
|
if (options.remoteSelf) {
|
|
43
42
|
debug(`Using manual remote self ${options.remoteSelf}`)
|
|
@@ -47,12 +46,14 @@ function MdnsWs (options) {
|
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
48
|
} else {
|
|
50
|
-
console.error(
|
|
49
|
+
console.error(
|
|
50
|
+
'Manual self handling speficied but no remoteSelf configured'
|
|
51
|
+
)
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
if (options.ignoreServers) {
|
|
55
|
-
options.ignoreServers.forEach(s => {
|
|
56
|
+
options.ignoreServers.forEach((s) => {
|
|
56
57
|
this.remoteServers[s] = {}
|
|
57
58
|
})
|
|
58
59
|
}
|
|
@@ -64,18 +65,21 @@ function MdnsWs (options) {
|
|
|
64
65
|
reconnect: true,
|
|
65
66
|
autoConnect: false,
|
|
66
67
|
deltaStreamBehaviour,
|
|
67
|
-
rejectUnauthorized: !(options.selfsignedcert === true)
|
|
68
|
+
rejectUnauthorized: !(options.selfsignedcert === true),
|
|
68
69
|
})
|
|
69
70
|
this.connect(this.signalkClient)
|
|
70
71
|
} else {
|
|
71
|
-
this.options.app.setProviderError(
|
|
72
|
+
this.options.app.setProviderError(
|
|
73
|
+
this.options.providerId,
|
|
74
|
+
'This connection is deprecated and must be deleted'
|
|
75
|
+
)
|
|
72
76
|
return
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
require('util').inherits(MdnsWs, Transform)
|
|
77
81
|
|
|
78
|
-
function setProviderStatus
|
|
82
|
+
function setProviderStatus(that, providerId, message, isError) {
|
|
79
83
|
if (!isError) {
|
|
80
84
|
that.options.app.setProviderStatus(providerId, message)
|
|
81
85
|
console.log(message)
|
|
@@ -91,30 +95,46 @@ MdnsWs.prototype.connect = function (client) {
|
|
|
91
95
|
client
|
|
92
96
|
.connect()
|
|
93
97
|
.then(() => {
|
|
94
|
-
setProviderStatus(
|
|
98
|
+
setProviderStatus(
|
|
99
|
+
that,
|
|
100
|
+
that.options.providerId,
|
|
101
|
+
`ws connection connected to ${client.options.hostname}:${client.options.port}`
|
|
102
|
+
)
|
|
95
103
|
if (this.options.selfHandling === 'useRemoteSelf') {
|
|
96
|
-
client
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
104
|
+
client
|
|
105
|
+
.API()
|
|
106
|
+
.then((api) => api.get('/self'))
|
|
107
|
+
.then((selfFromServer) => {
|
|
108
|
+
that.debug(
|
|
109
|
+
`Mapping context ${selfFromServer} to self (empty context)`
|
|
110
|
+
)
|
|
111
|
+
this.handleContext = (delta) => {
|
|
112
|
+
if (delta.context === selfFromServer) {
|
|
113
|
+
delete delta.context
|
|
114
|
+
}
|
|
101
115
|
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
116
|
+
})
|
|
117
|
+
.catch((err) => {
|
|
118
|
+
console.error('Error retrieving self from remote server')
|
|
119
|
+
console.error(err)
|
|
120
|
+
})
|
|
107
121
|
}
|
|
108
|
-
that.remoteServers[client.options.hostname + ':' + client.options.port] =
|
|
109
|
-
|
|
110
|
-
|
|
122
|
+
that.remoteServers[client.options.hostname + ':' + client.options.port] =
|
|
123
|
+
client
|
|
124
|
+
if (that.options.subscription) {
|
|
125
|
+
let parsed
|
|
111
126
|
try {
|
|
112
127
|
parsed = JSON.parse(that.options.subscription)
|
|
113
|
-
} catch (
|
|
114
|
-
setProviderStatus(
|
|
128
|
+
} catch (ex) {
|
|
129
|
+
setProviderStatus(
|
|
130
|
+
that,
|
|
131
|
+
that.options.providerId,
|
|
132
|
+
`unable to parse subscription json: ${that.options.subscription}: ${ex.message}`,
|
|
133
|
+
true
|
|
134
|
+
)
|
|
115
135
|
}
|
|
116
|
-
if (
|
|
117
|
-
parsed = [
|
|
136
|
+
if (!Array.isArray(parsed)) {
|
|
137
|
+
parsed = [parsed]
|
|
118
138
|
}
|
|
119
139
|
parsed.forEach((sub, idx) => {
|
|
120
140
|
that.debug('sending subscription %j', sub)
|
|
@@ -122,19 +142,23 @@ MdnsWs.prototype.connect = function (client) {
|
|
|
122
142
|
})
|
|
123
143
|
}
|
|
124
144
|
})
|
|
125
|
-
.catch(err => {
|
|
145
|
+
.catch((err) => {
|
|
126
146
|
setProviderStatus(that, that.options.providerId, err.message, true)
|
|
127
147
|
})
|
|
128
|
-
|
|
148
|
+
|
|
129
149
|
client.on('delta', (data) => {
|
|
130
150
|
if (data && data.updates) {
|
|
131
151
|
that.handleContext(data)
|
|
132
|
-
if (that.dataDebug.enabled) {
|
|
152
|
+
if (that.dataDebug.enabled) {
|
|
153
|
+
that.dataDebug(JSON.stringify(data))
|
|
154
|
+
}
|
|
133
155
|
data.updates.forEach(function (update) {
|
|
134
|
-
update[
|
|
156
|
+
update[
|
|
157
|
+
'$source'
|
|
158
|
+
] = `${that.options.providerId}.${client.options.hostname}:${client.options.port}`
|
|
135
159
|
})
|
|
136
160
|
}
|
|
137
|
-
|
|
161
|
+
|
|
138
162
|
that.push(data)
|
|
139
163
|
})
|
|
140
164
|
}
|