@signalk/streams 5.1.3 → 6.0.0
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/dist/actisense-serial.d.ts +3 -0
- package/dist/actisense-serial.d.ts.map +1 -0
- package/dist/actisense-serial.js +4 -0
- package/dist/autodetect.d.ts +54 -0
- package/dist/autodetect.d.ts.map +1 -0
- package/dist/autodetect.js +186 -0
- package/dist/canboatjs.d.ts +25 -0
- package/dist/canboatjs.d.ts.map +1 -0
- package/dist/canboatjs.js +57 -0
- package/dist/canbus.d.ts +3 -0
- package/dist/canbus.d.ts.map +1 -0
- package/dist/canbus.js +4 -0
- package/dist/execute.d.ts +34 -0
- package/dist/execute.d.ts.map +1 -0
- package/dist/execute.js +101 -0
- package/dist/filestream.d.ts +24 -0
- package/dist/filestream.d.ts.map +1 -0
- package/dist/filestream.js +58 -0
- package/dist/folderstream.d.ts +12 -0
- package/dist/folderstream.d.ts.map +1 -0
- package/dist/folderstream.js +36 -0
- package/dist/from_json.d.ts +6 -0
- package/dist/from_json.d.ts.map +1 -0
- package/dist/from_json.js +22 -0
- package/dist/gpiod-seatalk.d.ts +19 -0
- package/dist/gpiod-seatalk.d.ts.map +1 -0
- package/{gpiod-seatalk.js → dist/gpiod-seatalk.js} +18 -16
- package/dist/gpsd.d.ts +23 -0
- package/dist/gpsd.d.ts.map +1 -0
- package/dist/gpsd.js +55 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/keys-filter.d.ts +27 -0
- package/dist/keys-filter.d.ts.map +1 -0
- package/dist/keys-filter.js +59 -0
- package/dist/liner.d.ts +14 -0
- package/dist/liner.d.ts.map +1 -0
- package/dist/liner.js +35 -0
- package/dist/log.d.ts +15 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +17 -0
- package/dist/logging.d.ts +14 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +125 -0
- package/dist/mdns-ws.d.ts +37 -0
- package/dist/mdns-ws.d.ts.map +1 -0
- package/dist/mdns-ws.js +144 -0
- package/dist/multiplexedlog.d.ts +3 -0
- package/dist/multiplexedlog.d.ts.map +1 -0
- package/dist/multiplexedlog.js +7 -0
- package/dist/n2k-signalk.d.ts +39 -0
- package/dist/n2k-signalk.d.ts.map +1 -0
- package/dist/n2k-signalk.js +180 -0
- package/dist/n2kAnalyzer.d.ts +19 -0
- package/dist/n2kAnalyzer.d.ts.map +1 -0
- package/dist/n2kAnalyzer.js +61 -0
- package/dist/nmea0183-signalk.d.ts +33 -0
- package/dist/nmea0183-signalk.d.ts.map +1 -0
- package/dist/nmea0183-signalk.js +105 -0
- package/dist/nullprovider.d.ts +5 -0
- package/dist/nullprovider.d.ts.map +1 -0
- package/dist/nullprovider.js +9 -0
- package/dist/pigpio-seatalk.d.ts +19 -0
- package/dist/pigpio-seatalk.d.ts.map +1 -0
- package/{pigpio-seatalk.js → dist/pigpio-seatalk.js} +21 -18
- package/dist/replacer.d.ts +13 -0
- package/dist/replacer.d.ts.map +1 -0
- package/dist/replacer.js +20 -0
- package/dist/s3.d.ts +13 -0
- package/dist/s3.d.ts.map +1 -0
- package/dist/s3.js +82 -0
- package/dist/serialport.d.ts +35 -0
- package/dist/serialport.d.ts.map +1 -0
- package/dist/serialport.js +125 -0
- package/dist/simple.d.ts +78 -0
- package/dist/simple.d.ts.map +1 -0
- package/dist/simple.js +446 -0
- package/dist/splitting-liner.d.ts +12 -0
- package/dist/splitting-liner.d.ts.map +1 -0
- package/dist/splitting-liner.js +19 -0
- package/dist/tcp.d.ts +32 -0
- package/dist/tcp.d.ts.map +1 -0
- package/dist/tcp.js +113 -0
- package/dist/tcpserver.d.ts +14 -0
- package/dist/tcpserver.d.ts.map +1 -0
- package/dist/tcpserver.js +18 -0
- package/dist/test-helpers.d.ts +52 -0
- package/dist/test-helpers.d.ts.map +1 -0
- package/dist/test-helpers.js +73 -0
- package/dist/throttle.d.ts +3 -0
- package/dist/throttle.d.ts.map +1 -0
- package/dist/throttle.js +4 -0
- package/dist/timestamp-throttle.d.ts +17 -0
- package/dist/timestamp-throttle.d.ts.map +1 -0
- package/dist/timestamp-throttle.js +41 -0
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/udp.d.ts +26 -0
- package/dist/udp.d.ts.map +1 -0
- package/dist/udp.js +53 -0
- package/package.json +46 -4
- package/actisense-serial.js +0 -1
- package/autodetect.js +0 -198
- package/canboatjs.js +0 -71
- package/canbus.js +0 -17
- package/execute.js +0 -137
- package/filestream.js +0 -90
- package/folderstream.js +0 -36
- package/from_json.js +0 -51
- package/gpsd.js +0 -94
- package/keys-filter.js +0 -81
- package/liner.js +0 -68
- package/log.js +0 -51
- package/logging.js +0 -149
- package/mdns-ws.js +0 -167
- package/multiplexedlog.js +0 -3
- package/n2k-signalk.js +0 -195
- package/n2kAnalyzer.js +0 -82
- package/nmea0183-signalk.js +0 -119
- package/nullprovider.js +0 -31
- package/replacer.js +0 -57
- package/s3.js +0 -87
- package/serialport.js +0 -209
- package/simple.js +0 -446
- package/splitting-liner.js +0 -46
- package/tcp.js +0 -138
- package/tcpserver.js +0 -40
- package/throttle.js +0 -31
- package/timestamp-throttle.js +0 -63
- package/udp.js +0 -95
package/logging.js
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2017 Scott Bender (scott@scottbender.net)
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
const { FileTimestampStream } = require('file-timestamp-stream')
|
|
18
|
-
const path = require('path')
|
|
19
|
-
let debug = require('debug')('signalk:streams:logging')
|
|
20
|
-
const fs = require('fs')
|
|
21
|
-
const { isUndefined } = require('lodash')
|
|
22
|
-
|
|
23
|
-
const filenamePattern = /skserver-raw_\d\d\d\d-\d\d-\d\dT\d\d\.log/
|
|
24
|
-
const loggers = {}
|
|
25
|
-
|
|
26
|
-
module.exports = {
|
|
27
|
-
getLogger,
|
|
28
|
-
getFullLogDir,
|
|
29
|
-
listLogFiles
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
class FileTimestampStreamWithDelete extends FileTimestampStream {
|
|
33
|
-
constructor(app, fullLogDir, filesToKeep, options) {
|
|
34
|
-
super(options)
|
|
35
|
-
this.app = app
|
|
36
|
-
this.filesToKeep = filesToKeep
|
|
37
|
-
this.fullLogDir = fullLogDir
|
|
38
|
-
this.prevFilename = undefined
|
|
39
|
-
debug = (options.createDebug || require('debug'))('signalk:streams:logging')
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// This method of base class is called when new file name is contemplated
|
|
43
|
-
// So let's override it to check how many files are there and delete the oldest ones
|
|
44
|
-
newFilename() {
|
|
45
|
-
if (this.prevFilename !== this.currentFilename) {
|
|
46
|
-
// Only do that after new file created
|
|
47
|
-
this.prevFilename = this.currentFilename
|
|
48
|
-
this.deleteOldFiles()
|
|
49
|
-
}
|
|
50
|
-
return super.newFilename()
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
deleteOldFiles() {
|
|
54
|
-
debug(`Checking for old log files`)
|
|
55
|
-
listLogFiles(this.app, (err, files) => {
|
|
56
|
-
if (err) {
|
|
57
|
-
console.error(err)
|
|
58
|
-
} else {
|
|
59
|
-
if (files.length > this.filesToKeep) {
|
|
60
|
-
const sortedFiles = files.sort()
|
|
61
|
-
const numToDelete = files.length - this.filesToKeep
|
|
62
|
-
debug(`Will delete ${numToDelete} files`)
|
|
63
|
-
for (let i = 0; i < numToDelete; i++) {
|
|
64
|
-
const fileName = path.join(this.fullLogDir, sortedFiles[i])
|
|
65
|
-
debug(`Deleting ${fileName}`)
|
|
66
|
-
fs.unlink(fileName, (err) => {
|
|
67
|
-
if (err) {
|
|
68
|
-
console.error(err)
|
|
69
|
-
} else {
|
|
70
|
-
debug(`${fileName} was deleted`)
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
})
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function getLogger(app, discriminator = '', logdir) {
|
|
81
|
-
const fullLogdir = getFullLogDir(app, logdir)
|
|
82
|
-
|
|
83
|
-
if (!loggers[fullLogdir]) {
|
|
84
|
-
const fileName = path.join(fullLogdir, 'skserver-raw_%Y-%m-%dT%H.log')
|
|
85
|
-
|
|
86
|
-
debug(`logging to ${fileName}`)
|
|
87
|
-
|
|
88
|
-
let fileTimestampStream
|
|
89
|
-
if (
|
|
90
|
-
isUndefined(app.config.settings.keepMostRecentLogsOnly) ||
|
|
91
|
-
app.config.settings.keepMostRecentLogsOnly
|
|
92
|
-
) {
|
|
93
|
-
// Delete old logs
|
|
94
|
-
fileTimestampStream = new FileTimestampStreamWithDelete(
|
|
95
|
-
app,
|
|
96
|
-
fullLogdir,
|
|
97
|
-
app.config.settings.logCountToKeep,
|
|
98
|
-
{ path: fileName }
|
|
99
|
-
)
|
|
100
|
-
} else {
|
|
101
|
-
// Don't delete any logs
|
|
102
|
-
fileTimestampStream = new FileTimestampStream({ path: fileName })
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
loggers[fullLogdir] = fileTimestampStream
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const logger = loggers[fullLogdir]
|
|
109
|
-
logger.on('error', (err) => {
|
|
110
|
-
console.error(`Error opening data logging file: ${err.message}`)
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
return (msg) => {
|
|
114
|
-
try {
|
|
115
|
-
logger.write(
|
|
116
|
-
Date.now() +
|
|
117
|
-
';' +
|
|
118
|
-
discriminator +
|
|
119
|
-
';' +
|
|
120
|
-
(msg.updates ? JSON.stringify(msg) : msg.toString()) +
|
|
121
|
-
'\n'
|
|
122
|
-
)
|
|
123
|
-
} catch (e) {
|
|
124
|
-
console.error(e)
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function getFullLogDir(app, logdir) {
|
|
130
|
-
if (!logdir) {
|
|
131
|
-
logdir = app.config.settings.loggingDirectory || app.config.configPath
|
|
132
|
-
}
|
|
133
|
-
return path.isAbsolute(logdir)
|
|
134
|
-
? logdir
|
|
135
|
-
: path.join(app.config.configPath, logdir)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function listLogFiles(app, cb) {
|
|
139
|
-
fs.readdir(getFullLogDir(app), (err, files) => {
|
|
140
|
-
if (!err) {
|
|
141
|
-
cb(
|
|
142
|
-
undefined,
|
|
143
|
-
files.filter((filename) => filename.match(filenamePattern))
|
|
144
|
-
)
|
|
145
|
-
} else {
|
|
146
|
-
cb(err)
|
|
147
|
-
}
|
|
148
|
-
})
|
|
149
|
-
}
|
package/mdns-ws.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2016 Teppo Kurki <teppo.kurki@iki.fi>
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
const Transform = require('stream').Transform
|
|
18
|
-
|
|
19
|
-
const SignalK = require('@signalk/client')
|
|
20
|
-
|
|
21
|
-
function MdnsWs(options) {
|
|
22
|
-
Transform.call(this, {
|
|
23
|
-
objectMode: true
|
|
24
|
-
})
|
|
25
|
-
this.options = options
|
|
26
|
-
this.selfHost = options.app.config.getExternalHostname() + '.'
|
|
27
|
-
this.selfPort = options.app.config.getExternalPort()
|
|
28
|
-
this.remoteServers = {}
|
|
29
|
-
this.remoteServers[this.selfHost + ':' + this.selfPort] = {}
|
|
30
|
-
const deltaStreamBehaviour = options.subscription ? 'none' : 'all'
|
|
31
|
-
|
|
32
|
-
const createDebug = options.createDebug || require('debug')
|
|
33
|
-
this.debug = createDebug('signalk:streams:mdns-ws')
|
|
34
|
-
this.dataDebug = createDebug('signalk:streams:mdns-ws-data')
|
|
35
|
-
this.debug(`deltaStreamBehaviour:${deltaStreamBehaviour}`)
|
|
36
|
-
|
|
37
|
-
this.handleContext = () => {}
|
|
38
|
-
if (options.selfHandling === 'manualSelf') {
|
|
39
|
-
if (options.remoteSelf) {
|
|
40
|
-
this.debug(`Using manual remote self ${options.remoteSelf}`)
|
|
41
|
-
this.handleContext = (delta) => {
|
|
42
|
-
if (delta.context === options.remoteSelf) {
|
|
43
|
-
delete delta.context
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
} else {
|
|
47
|
-
console.error(
|
|
48
|
-
'Manual self handling speficied but no remoteSelf configured'
|
|
49
|
-
)
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (options.ignoreServers) {
|
|
54
|
-
options.ignoreServers.forEach((s) => {
|
|
55
|
-
this.remoteServers[s] = {}
|
|
56
|
-
})
|
|
57
|
-
}
|
|
58
|
-
if (options.host && options.port) {
|
|
59
|
-
this.signalkClient = new SignalK.Client({
|
|
60
|
-
hostname: options.host,
|
|
61
|
-
port: options.port,
|
|
62
|
-
useTLS: options.type === 'wss',
|
|
63
|
-
reconnect: true,
|
|
64
|
-
notifications: false,
|
|
65
|
-
autoConnect: false,
|
|
66
|
-
deltaStreamBehaviour,
|
|
67
|
-
rejectUnauthorized: !(options.selfsignedcert === true),
|
|
68
|
-
wsKeepaliveInterval: 10
|
|
69
|
-
})
|
|
70
|
-
this.connect(this.signalkClient)
|
|
71
|
-
} else {
|
|
72
|
-
this.options.app.setProviderError(
|
|
73
|
-
this.options.providerId,
|
|
74
|
-
'This connection is deprecated and must be deleted'
|
|
75
|
-
)
|
|
76
|
-
return
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
require('util').inherits(MdnsWs, Transform)
|
|
81
|
-
|
|
82
|
-
function setProviderStatus(that, providerId, message, isError) {
|
|
83
|
-
if (!isError) {
|
|
84
|
-
that.options.app.setProviderStatus(providerId, message)
|
|
85
|
-
console.log(message)
|
|
86
|
-
} else {
|
|
87
|
-
that.options.app.setProviderError(providerId, message)
|
|
88
|
-
console.error(message)
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
MdnsWs.prototype.connect = function (client) {
|
|
93
|
-
const that = this
|
|
94
|
-
|
|
95
|
-
client
|
|
96
|
-
.connect()
|
|
97
|
-
.then(() => {
|
|
98
|
-
setProviderStatus(
|
|
99
|
-
that,
|
|
100
|
-
that.options.providerId,
|
|
101
|
-
`ws connection connected to ${client.options.hostname}:${client.options.port}`
|
|
102
|
-
)
|
|
103
|
-
if (this.options.selfHandling === 'useRemoteSelf') {
|
|
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
|
-
}
|
|
115
|
-
}
|
|
116
|
-
})
|
|
117
|
-
.catch((err) => {
|
|
118
|
-
console.error('Error retrieving self from remote server')
|
|
119
|
-
console.error(err)
|
|
120
|
-
})
|
|
121
|
-
}
|
|
122
|
-
that.remoteServers[client.options.hostname + ':' + client.options.port] =
|
|
123
|
-
client
|
|
124
|
-
if (that.options.subscription) {
|
|
125
|
-
let parsed
|
|
126
|
-
try {
|
|
127
|
-
parsed = JSON.parse(that.options.subscription)
|
|
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
|
-
)
|
|
135
|
-
}
|
|
136
|
-
if (!Array.isArray(parsed)) {
|
|
137
|
-
parsed = [parsed]
|
|
138
|
-
}
|
|
139
|
-
parsed.forEach((sub, idx) => {
|
|
140
|
-
that.debug('sending subscription %j', sub)
|
|
141
|
-
client.subscribe(sub, String(idx))
|
|
142
|
-
})
|
|
143
|
-
}
|
|
144
|
-
})
|
|
145
|
-
.catch((err) => {
|
|
146
|
-
setProviderStatus(that, that.options.providerId, err.message, true)
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
client.on('delta', (data) => {
|
|
150
|
-
if (data && data.updates) {
|
|
151
|
-
that.handleContext(data)
|
|
152
|
-
if (that.dataDebug.enabled) {
|
|
153
|
-
that.dataDebug(JSON.stringify(data))
|
|
154
|
-
}
|
|
155
|
-
data.updates.forEach(function (update) {
|
|
156
|
-
update['$source'] =
|
|
157
|
-
`${that.options.providerId}.${client.options.hostname}:${client.options.port}`
|
|
158
|
-
})
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
that.push(data)
|
|
162
|
-
})
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
MdnsWs.prototype._transform = function () {}
|
|
166
|
-
|
|
167
|
-
module.exports = MdnsWs
|
package/multiplexedlog.js
DELETED
package/n2k-signalk.js
DELETED
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2014-2015 Fabian Tollenaar <fabian@starting-point.nl>
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
const Transform = require('stream').Transform
|
|
18
|
-
|
|
19
|
-
const N2kMapper = require('@signalk/n2k-signalk').N2kMapper
|
|
20
|
-
|
|
21
|
-
require('util').inherits(ToSignalK, Transform)
|
|
22
|
-
|
|
23
|
-
function ToSignalK(options) {
|
|
24
|
-
Transform.call(this, {
|
|
25
|
-
objectMode: true
|
|
26
|
-
})
|
|
27
|
-
const n2kOutEvent = 'nmea2000JsonOut'
|
|
28
|
-
this.sourceMeta = {}
|
|
29
|
-
this.notifications = {}
|
|
30
|
-
this.options = options
|
|
31
|
-
this.app = options.app
|
|
32
|
-
if (options.filters && options.filtersEnabled) {
|
|
33
|
-
this.filters = options.filters.filter((f) => {
|
|
34
|
-
return (f.source && f.source.length) || (f.pgn && f.pgn.length)
|
|
35
|
-
})
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
this.n2kMapper = new N2kMapper({ ...options, sendMetaData: true })
|
|
39
|
-
|
|
40
|
-
this.n2kMapper.on('n2kOut', (pgn) => this.app.emit('nmea2000JsonOut', pgn))
|
|
41
|
-
|
|
42
|
-
this.n2kMapper.on('n2kSourceMetadata', (n2k, meta) => {
|
|
43
|
-
const existing = this.sourceMeta[n2k.src] || {}
|
|
44
|
-
this.sourceMeta[n2k.src] = {
|
|
45
|
-
...existing,
|
|
46
|
-
...meta
|
|
47
|
-
}
|
|
48
|
-
const delta = {
|
|
49
|
-
context: this.app.selfContext,
|
|
50
|
-
updates: [
|
|
51
|
-
{
|
|
52
|
-
source: {
|
|
53
|
-
...this.sourceMeta[n2k.src],
|
|
54
|
-
label: this.options.providerId,
|
|
55
|
-
type: 'NMEA2000',
|
|
56
|
-
pgn: Number(n2k.pgn),
|
|
57
|
-
src: n2k.src.toString()
|
|
58
|
-
},
|
|
59
|
-
timestamp:
|
|
60
|
-
n2k.timestamp.substring(0, 10) +
|
|
61
|
-
'T' +
|
|
62
|
-
n2k.timestamp.substring(11, n2k.timestamp.length),
|
|
63
|
-
values: []
|
|
64
|
-
}
|
|
65
|
-
]
|
|
66
|
-
}
|
|
67
|
-
this.app.deltaCache.setSourceDelta(
|
|
68
|
-
`${this.options.providerId}.${n2k.src}`,
|
|
69
|
-
delta
|
|
70
|
-
)
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
this.n2kMapper.on('n2kSourceMetadataTimeout', (pgn, src) => {
|
|
74
|
-
if (pgn == 60928) {
|
|
75
|
-
console.warn(`n2k-signalk: unable to detect can name for src ${src}`)
|
|
76
|
-
this.sourceMeta[src].unknowCanName = true
|
|
77
|
-
}
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
this.n2kMapper.on('n2kSourceChanged', (src, from, to) => {
|
|
81
|
-
console.warn(`n2k-signalk: address ${src} changed from ${from} ${to}`)
|
|
82
|
-
if (this.sourceMeta[src]) {
|
|
83
|
-
delete this.sourceMeta[src]
|
|
84
|
-
}
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
if (this.app.isNmea2000OutAvailable) {
|
|
88
|
-
this.n2kMapper.n2kOutIsAvailable(this.app, n2kOutEvent)
|
|
89
|
-
} else {
|
|
90
|
-
this.app.on('nmea2000OutAvailable', () =>
|
|
91
|
-
this.n2kMapper.n2kOutIsAvailable(this.app, n2kOutEvent)
|
|
92
|
-
)
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
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
|
-
)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
ToSignalK.prototype._transform = function (chunk, encoding, done) {
|
|
112
|
-
try {
|
|
113
|
-
const delta = this.n2kMapper.toDelta(chunk)
|
|
114
|
-
|
|
115
|
-
const src = Number(chunk.src)
|
|
116
|
-
if (!this.sourceMeta[src]) {
|
|
117
|
-
this.sourceMeta[src] = {}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (
|
|
121
|
-
delta &&
|
|
122
|
-
delta.updates[0].values.length > 0 &&
|
|
123
|
-
!this.isFiltered(delta.updates[0].source)
|
|
124
|
-
) {
|
|
125
|
-
if (!this.options.useCanName) {
|
|
126
|
-
delete delta.updates[0].source.canName
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const canName = delta.updates[0].source.canName
|
|
130
|
-
|
|
131
|
-
if (
|
|
132
|
-
this.options.useCanName &&
|
|
133
|
-
!canName &&
|
|
134
|
-
!this.sourceMeta[src].unknowCanName
|
|
135
|
-
) {
|
|
136
|
-
done()
|
|
137
|
-
return
|
|
138
|
-
}
|
|
139
|
-
|
|
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
|
-
]
|
|
170
|
-
}
|
|
171
|
-
delete this.notifications[kv.path][src]
|
|
172
|
-
clearInterval(interval)
|
|
173
|
-
this.app.handleMessage(this.options.providerId, normalDelta)
|
|
174
|
-
}
|
|
175
|
-
}, 5000)
|
|
176
|
-
this.notifications[kv.path][src] = {
|
|
177
|
-
lastTime: Date.now(),
|
|
178
|
-
interval: interval
|
|
179
|
-
}
|
|
180
|
-
} else {
|
|
181
|
-
this.notifications[kv.path][src].lastTime = Date.now()
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
})
|
|
186
|
-
})
|
|
187
|
-
this.push(delta)
|
|
188
|
-
}
|
|
189
|
-
} catch (ex) {
|
|
190
|
-
console.error(ex)
|
|
191
|
-
}
|
|
192
|
-
done()
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
module.exports = ToSignalK
|
package/n2kAnalyzer.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2014-2015 Fabian Tollenaar <fabian@starting-point.nl>
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
const Transform = require('stream').Transform
|
|
18
|
-
|
|
19
|
-
function N2KAnalyzer(options) {
|
|
20
|
-
Transform.call(this, {
|
|
21
|
-
objectMode: true
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
this.analyzerOutEvent = options.analyzerOutEvent || 'N2KAnalyzerOut'
|
|
25
|
-
|
|
26
|
-
if (process.platform === 'win32') {
|
|
27
|
-
this.analyzerProcess = require('child_process').spawn('cmd', [
|
|
28
|
-
'/c',
|
|
29
|
-
'analyzer -json -si -camel'
|
|
30
|
-
])
|
|
31
|
-
} else {
|
|
32
|
-
this.analyzerProcess = require('child_process').spawn('sh', [
|
|
33
|
-
'-c',
|
|
34
|
-
'analyzer -json -si -camel'
|
|
35
|
-
])
|
|
36
|
-
}
|
|
37
|
-
this.analyzerProcess.stderr.on('data', function (data) {
|
|
38
|
-
console.error(data.toString())
|
|
39
|
-
})
|
|
40
|
-
this.analyzerProcess.on('close', function (code) {
|
|
41
|
-
console.error('Analyzer process exited with code ' + code)
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
this.linereader = require('readline').createInterface(
|
|
45
|
-
this.analyzerProcess.stdout,
|
|
46
|
-
this.analyzerProcess.stdin
|
|
47
|
-
)
|
|
48
|
-
const that = this
|
|
49
|
-
this.linereader.on('line', function (data) {
|
|
50
|
-
try {
|
|
51
|
-
let parsed = JSON.parse(data)
|
|
52
|
-
if (parsed.version) {
|
|
53
|
-
console.log('Connected to analyzer v' + parsed.version)
|
|
54
|
-
return
|
|
55
|
-
}
|
|
56
|
-
that.push(parsed)
|
|
57
|
-
options.app.emit(that.analyzerOutEvent, parsed)
|
|
58
|
-
} catch (ex) {
|
|
59
|
-
console.error(data)
|
|
60
|
-
console.error(ex.stack)
|
|
61
|
-
}
|
|
62
|
-
})
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
require('util').inherits(N2KAnalyzer, Transform)
|
|
66
|
-
|
|
67
|
-
N2KAnalyzer.prototype._transform = function (chunk, encoding, done) {
|
|
68
|
-
this.analyzerProcess.stdin.write(chunk.toString() + '\n')
|
|
69
|
-
done()
|
|
70
|
-
}
|
|
71
|
-
N2KAnalyzer.prototype.pipe = function (pipeTo) {
|
|
72
|
-
this.pipeTo = pipeTo
|
|
73
|
-
N2KAnalyzer.super_.prototype.pipe.call(this, pipeTo)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
N2KAnalyzer.prototype.end = function () {
|
|
77
|
-
console.log('end, killing child analyzer process')
|
|
78
|
-
this.analyzerProcess.kill()
|
|
79
|
-
this.pipeTo.end()
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
module.exports = N2KAnalyzer
|