@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
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import type { CreateDebug, DebugLogger, DeltaCache } from './types';
|
|
3
|
+
interface MockAppOptions {
|
|
4
|
+
selfContext?: string;
|
|
5
|
+
configPath?: string;
|
|
6
|
+
loggingDirectory?: string;
|
|
7
|
+
keepMostRecentLogsOnly?: boolean;
|
|
8
|
+
logCountToKeep?: number;
|
|
9
|
+
isNmea2000OutAvailable?: boolean;
|
|
10
|
+
}
|
|
11
|
+
interface MockApp extends EventEmitter {
|
|
12
|
+
selfContext: string;
|
|
13
|
+
isNmea2000OutAvailable: boolean;
|
|
14
|
+
deltaCache: DeltaCache;
|
|
15
|
+
config: {
|
|
16
|
+
configPath: string;
|
|
17
|
+
settings: {
|
|
18
|
+
loggingDirectory?: string;
|
|
19
|
+
keepMostRecentLogsOnly?: boolean;
|
|
20
|
+
logCountToKeep?: number;
|
|
21
|
+
};
|
|
22
|
+
getExternalHostname(): string;
|
|
23
|
+
getExternalPort(): number;
|
|
24
|
+
};
|
|
25
|
+
setProviderStatus(id: string, msg: string): void;
|
|
26
|
+
setProviderError(id: string, msg: string): void;
|
|
27
|
+
handleMessage(id: string, delta: object): void;
|
|
28
|
+
emitPropertyValue(name: string, value: unknown): void;
|
|
29
|
+
signalk: EventEmitter;
|
|
30
|
+
providerStatuses: Array<{
|
|
31
|
+
id: string;
|
|
32
|
+
msg: string;
|
|
33
|
+
}>;
|
|
34
|
+
providerErrors: Array<{
|
|
35
|
+
id: string;
|
|
36
|
+
msg: string;
|
|
37
|
+
}>;
|
|
38
|
+
handledMessages: Array<{
|
|
39
|
+
id: string;
|
|
40
|
+
delta: object;
|
|
41
|
+
}>;
|
|
42
|
+
propertyValues: Array<{
|
|
43
|
+
name: string;
|
|
44
|
+
value: unknown;
|
|
45
|
+
}>;
|
|
46
|
+
}
|
|
47
|
+
export declare function createMockApp(options?: MockAppOptions): MockApp;
|
|
48
|
+
export declare function collectStreamOutput<T = unknown>(stream: NodeJS.ReadableStream): Promise<T[]>;
|
|
49
|
+
export declare function noopDebug(): DebugLogger;
|
|
50
|
+
export declare function createDebugStub(): CreateDebug;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=test-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-helpers.d.ts","sourceRoot":"","sources":["../src/test-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEnE,UAAU,cAAc;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,sBAAsB,CAAC,EAAE,OAAO,CAAA;CACjC;AAED,UAAU,OAAQ,SAAQ,YAAY;IACpC,WAAW,EAAE,MAAM,CAAA;IACnB,sBAAsB,EAAE,OAAO,CAAA;IAC/B,UAAU,EAAE,UAAU,CAAA;IACtB,MAAM,EAAE;QACN,UAAU,EAAE,MAAM,CAAA;QAClB,QAAQ,EAAE;YACR,gBAAgB,CAAC,EAAE,MAAM,CAAA;YACzB,sBAAsB,CAAC,EAAE,OAAO,CAAA;YAChC,cAAc,CAAC,EAAE,MAAM,CAAA;SACxB,CAAA;QACD,mBAAmB,IAAI,MAAM,CAAA;QAC7B,eAAe,IAAI,MAAM,CAAA;KAC1B,CAAA;IACD,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAChD,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/C,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9C,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;IACrD,OAAO,EAAE,YAAY,CAAA;IACrB,gBAAgB,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACpD,cAAc,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAClD,eAAe,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACrD,cAAc,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;CACxD;AAED,wBAAgB,aAAa,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAoDnE;AAED,wBAAgB,mBAAmB,CAAC,CAAC,GAAG,OAAO,EAC7C,MAAM,EAAE,MAAM,CAAC,cAAc,GAC5B,OAAO,CAAC,CAAC,EAAE,CAAC,CAOd;AAED,wBAAgB,SAAS,IAAI,WAAW,CAIvC;AAED,wBAAgB,eAAe,IAAI,WAAW,CAE7C"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMockApp = createMockApp;
|
|
4
|
+
exports.collectStreamOutput = collectStreamOutput;
|
|
5
|
+
exports.noopDebug = noopDebug;
|
|
6
|
+
exports.createDebugStub = createDebugStub;
|
|
7
|
+
const events_1 = require("events");
|
|
8
|
+
function createMockApp(options = {}) {
|
|
9
|
+
const emitter = new events_1.EventEmitter();
|
|
10
|
+
const signalk = new events_1.EventEmitter();
|
|
11
|
+
const providerStatuses = [];
|
|
12
|
+
const providerErrors = [];
|
|
13
|
+
const handledMessages = [];
|
|
14
|
+
const propertyValues = [];
|
|
15
|
+
const sourceDeltaStore = {};
|
|
16
|
+
const app = Object.assign(emitter, {
|
|
17
|
+
selfContext: options.selfContext ?? 'vessels.urn:mrn:imo:mmsi:000000000',
|
|
18
|
+
isNmea2000OutAvailable: options.isNmea2000OutAvailable ?? false,
|
|
19
|
+
deltaCache: {
|
|
20
|
+
setSourceDelta(key, delta) {
|
|
21
|
+
sourceDeltaStore[key] = delta;
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
config: {
|
|
25
|
+
configPath: options.configPath ?? '/tmp/test-config',
|
|
26
|
+
settings: {
|
|
27
|
+
loggingDirectory: options.loggingDirectory,
|
|
28
|
+
keepMostRecentLogsOnly: options.keepMostRecentLogsOnly,
|
|
29
|
+
logCountToKeep: options.logCountToKeep
|
|
30
|
+
},
|
|
31
|
+
getExternalHostname() {
|
|
32
|
+
return 'localhost';
|
|
33
|
+
},
|
|
34
|
+
getExternalPort() {
|
|
35
|
+
return 3000;
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
setProviderStatus(id, msg) {
|
|
39
|
+
providerStatuses.push({ id, msg });
|
|
40
|
+
},
|
|
41
|
+
setProviderError(id, msg) {
|
|
42
|
+
providerErrors.push({ id, msg });
|
|
43
|
+
},
|
|
44
|
+
handleMessage(id, delta) {
|
|
45
|
+
handledMessages.push({ id, delta });
|
|
46
|
+
},
|
|
47
|
+
emitPropertyValue(name, value) {
|
|
48
|
+
propertyValues.push({ name, value });
|
|
49
|
+
},
|
|
50
|
+
signalk,
|
|
51
|
+
providerStatuses,
|
|
52
|
+
providerErrors,
|
|
53
|
+
handledMessages,
|
|
54
|
+
propertyValues
|
|
55
|
+
});
|
|
56
|
+
return app;
|
|
57
|
+
}
|
|
58
|
+
function collectStreamOutput(stream) {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
const results = [];
|
|
61
|
+
stream.on('data', (chunk) => results.push(chunk));
|
|
62
|
+
stream.on('end', () => resolve(results));
|
|
63
|
+
stream.on('error', reject);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function noopDebug() {
|
|
67
|
+
const fn = ((..._args) => { });
|
|
68
|
+
fn.enabled = false;
|
|
69
|
+
return fn;
|
|
70
|
+
}
|
|
71
|
+
function createDebugStub() {
|
|
72
|
+
return () => noopDebug();
|
|
73
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../src/throttle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE1C,eAAe,QAAQ,CAAA"}
|
package/dist/throttle.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Transform, TransformCallback } from 'stream';
|
|
2
|
+
interface TimestampMessage {
|
|
3
|
+
timestamp: string;
|
|
4
|
+
}
|
|
5
|
+
type GetMilliseconds = (msg: TimestampMessage) => number;
|
|
6
|
+
interface TimestampThrottleOptions {
|
|
7
|
+
getMilliseconds?: GetMilliseconds;
|
|
8
|
+
}
|
|
9
|
+
export default class TimestampThrottle extends Transform {
|
|
10
|
+
private lastMsgMillis;
|
|
11
|
+
private offsetMillis;
|
|
12
|
+
private readonly getMilliseconds;
|
|
13
|
+
constructor(options?: TimestampThrottleOptions);
|
|
14
|
+
_transform(msg: TimestampMessage, encoding: BufferEncoding, done: TransformCallback): void;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=timestamp-throttle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timestamp-throttle.d.ts","sourceRoot":"","sources":["../src/timestamp-throttle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAA;AAErD,UAAU,gBAAgB;IACxB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,KAAK,eAAe,GAAG,CAAC,GAAG,EAAE,gBAAgB,KAAK,MAAM,CAAA;AAExD,UAAU,wBAAwB;IAChC,eAAe,CAAC,EAAE,eAAe,CAAA;CAClC;AAOD,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,SAAS;IACtD,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;gBAErC,OAAO,GAAE,wBAA6B;IAMlD,UAAU,CACR,GAAG,EAAE,gBAAgB,EACrB,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,iBAAiB,GACtB,IAAI;CAkBR"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const moment_1 = __importDefault(require("moment"));
|
|
7
|
+
const stream_1 = require("stream");
|
|
8
|
+
function defaultGetMilliseconds(msg) {
|
|
9
|
+
// 2014-08-15-16:00:00.083
|
|
10
|
+
return (0, moment_1.default)(msg.timestamp, 'YYYY-MM-DD-HH:mm:ss.SSS').valueOf();
|
|
11
|
+
}
|
|
12
|
+
class TimestampThrottle extends stream_1.Transform {
|
|
13
|
+
lastMsgMillis;
|
|
14
|
+
offsetMillis = 0;
|
|
15
|
+
getMilliseconds;
|
|
16
|
+
constructor(options = {}) {
|
|
17
|
+
super({ objectMode: true });
|
|
18
|
+
this.lastMsgMillis = Date.now();
|
|
19
|
+
this.getMilliseconds = options.getMilliseconds ?? defaultGetMilliseconds;
|
|
20
|
+
}
|
|
21
|
+
_transform(msg, encoding, done) {
|
|
22
|
+
const msgMillis = this.getMilliseconds(msg);
|
|
23
|
+
if (msgMillis < this.lastMsgMillis) {
|
|
24
|
+
this.offsetMillis = Date.now() - msgMillis;
|
|
25
|
+
}
|
|
26
|
+
this.lastMsgMillis = msgMillis;
|
|
27
|
+
const millisToCorrectSendTime = msgMillis - Date.now() + this.offsetMillis;
|
|
28
|
+
if (millisToCorrectSendTime <= 0) {
|
|
29
|
+
this.push(msg);
|
|
30
|
+
done();
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const doPush = this.push.bind(this, msg);
|
|
34
|
+
setTimeout(() => {
|
|
35
|
+
doPush();
|
|
36
|
+
done();
|
|
37
|
+
}, millisToCorrectSendTime);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.default = TimestampThrottle;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type DebugLogger = ((...args: unknown[]) => void) & {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
};
|
|
4
|
+
export type CreateDebug = (namespace: string) => DebugLogger;
|
|
5
|
+
export interface DeltaCache {
|
|
6
|
+
setSourceDelta(key: string, delta: object): void;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,GAAG;IACzD,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,WAAW,CAAA;AAE5D,MAAM,WAAW,UAAU;IACzB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACjD"}
|
package/dist/types.js
ADDED
package/dist/udp.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Transform, TransformCallback } from 'stream';
|
|
2
|
+
import type { CreateDebug } from './types';
|
|
3
|
+
interface UdpOptions {
|
|
4
|
+
port: number;
|
|
5
|
+
host?: string;
|
|
6
|
+
app: {
|
|
7
|
+
on(event: string, cb: (...args: any[]) => void): void;
|
|
8
|
+
setProviderError(id: string, msg: string): void;
|
|
9
|
+
};
|
|
10
|
+
providerId: string;
|
|
11
|
+
outEvent?: string;
|
|
12
|
+
createDebug?: CreateDebug;
|
|
13
|
+
[key: string]: unknown;
|
|
14
|
+
}
|
|
15
|
+
export default class Udp extends Transform {
|
|
16
|
+
private readonly options;
|
|
17
|
+
private readonly debug;
|
|
18
|
+
private socket;
|
|
19
|
+
private pipeTo;
|
|
20
|
+
constructor(options: UdpOptions);
|
|
21
|
+
pipe<T extends NodeJS.WritableStream>(pipeTo: T): T;
|
|
22
|
+
_transform(chunk: Buffer, encoding: BufferEncoding, done: TransformCallback): void;
|
|
23
|
+
end(): this;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=udp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"udp.d.ts","sourceRoot":"","sources":["../src/udp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAY,MAAM,QAAQ,CAAA;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,SAAS,CAAA;AAEvD,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,EAAE;QAEH,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAA;QACrD,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAChD,CAAA;IACD,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,MAAM,CAAC,OAAO,OAAO,GAAI,SAAQ,SAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAwB;gBAE1B,OAAO,EAAE,UAAU;IAO/B,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC;IAqCnD,UAAU,CACR,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,iBAAiB,GACtB,IAAI;IAIP,GAAG,IAAI,IAAI;CASZ"}
|
package/dist/udp.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const dgram_1 = require("dgram");
|
|
4
|
+
const stream_1 = require("stream");
|
|
5
|
+
class Udp extends stream_1.Transform {
|
|
6
|
+
options;
|
|
7
|
+
debug;
|
|
8
|
+
socket = null;
|
|
9
|
+
pipeTo = null;
|
|
10
|
+
constructor(options) {
|
|
11
|
+
super({ objectMode: false });
|
|
12
|
+
this.options = options;
|
|
13
|
+
const createDebug = options.createDebug ?? require('debug');
|
|
14
|
+
this.debug = createDebug('signalk:streams:udp');
|
|
15
|
+
}
|
|
16
|
+
pipe(pipeTo) {
|
|
17
|
+
this.pipeTo = pipeTo;
|
|
18
|
+
super.pipe(pipeTo);
|
|
19
|
+
const socket = (0, dgram_1.createSocket)('udp4');
|
|
20
|
+
this.socket = socket;
|
|
21
|
+
if (this.options.outEvent && this.options.port !== undefined) {
|
|
22
|
+
this.options.app.on(this.options.outEvent, (d) => {
|
|
23
|
+
this.debug('sending over udp: %s', d);
|
|
24
|
+
socket.send(d, 0, d.length, this.options.port, this.options.host ?? '255.255.255.255');
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
socket.on('message', (message) => {
|
|
28
|
+
this.debug(message.toString());
|
|
29
|
+
this.push(message);
|
|
30
|
+
});
|
|
31
|
+
socket.on('error', (err) => {
|
|
32
|
+
this.options.app.setProviderError(this.options.providerId, err.message);
|
|
33
|
+
console.error('UdpProvider:' + err);
|
|
34
|
+
});
|
|
35
|
+
socket.bind(this.options.port, () => {
|
|
36
|
+
socket.setBroadcast(true);
|
|
37
|
+
});
|
|
38
|
+
return pipeTo;
|
|
39
|
+
}
|
|
40
|
+
_transform(chunk, encoding, done) {
|
|
41
|
+
done();
|
|
42
|
+
}
|
|
43
|
+
end() {
|
|
44
|
+
if (this.socket) {
|
|
45
|
+
this.socket.close();
|
|
46
|
+
}
|
|
47
|
+
if (this.pipeTo) {
|
|
48
|
+
this.pipeTo.end();
|
|
49
|
+
}
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.default = Udp;
|
package/package.json
CHANGED
|
@@ -1,11 +1,53 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signalk/streams",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "Utilities for handling streams of Signal K data",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"!dist/**/*.test.*"
|
|
10
|
+
],
|
|
6
11
|
"scripts": {
|
|
7
|
-
"
|
|
8
|
-
"
|
|
12
|
+
"build": "tsc -b",
|
|
13
|
+
"watch": "tsc --watch",
|
|
14
|
+
"test": "mocha 'src/**/*.test.ts'",
|
|
15
|
+
"ci": "prettier --check src/",
|
|
16
|
+
"format": "prettier --write src/"
|
|
17
|
+
},
|
|
18
|
+
"exports": {
|
|
19
|
+
".": "./dist/index.js",
|
|
20
|
+
"./actisense-serial": "./dist/actisense-serial.js",
|
|
21
|
+
"./autodetect": "./dist/autodetect.js",
|
|
22
|
+
"./canboatjs": "./dist/canboatjs.js",
|
|
23
|
+
"./canbus": "./dist/canbus.js",
|
|
24
|
+
"./execute": "./dist/execute.js",
|
|
25
|
+
"./filestream": "./dist/filestream.js",
|
|
26
|
+
"./folderstream": "./dist/folderstream.js",
|
|
27
|
+
"./from_json": "./dist/from_json.js",
|
|
28
|
+
"./gpiod-seatalk": "./dist/gpiod-seatalk.js",
|
|
29
|
+
"./gpsd": "./dist/gpsd.js",
|
|
30
|
+
"./keys-filter": "./dist/keys-filter.js",
|
|
31
|
+
"./liner": "./dist/liner.js",
|
|
32
|
+
"./log": "./dist/log.js",
|
|
33
|
+
"./logging": "./dist/logging.js",
|
|
34
|
+
"./mdns-ws": "./dist/mdns-ws.js",
|
|
35
|
+
"./multiplexedlog": "./dist/multiplexedlog.js",
|
|
36
|
+
"./n2kAnalyzer": "./dist/n2kAnalyzer.js",
|
|
37
|
+
"./n2k-signalk": "./dist/n2k-signalk.js",
|
|
38
|
+
"./nmea0183-signalk": "./dist/nmea0183-signalk.js",
|
|
39
|
+
"./nullprovider": "./dist/nullprovider.js",
|
|
40
|
+
"./pigpio-seatalk": "./dist/pigpio-seatalk.js",
|
|
41
|
+
"./replacer": "./dist/replacer.js",
|
|
42
|
+
"./s3": "./dist/s3.js",
|
|
43
|
+
"./serialport": "./dist/serialport.js",
|
|
44
|
+
"./simple": "./dist/simple.js",
|
|
45
|
+
"./splitting-liner": "./dist/splitting-liner.js",
|
|
46
|
+
"./tcp": "./dist/tcp.js",
|
|
47
|
+
"./tcpserver": "./dist/tcpserver.js",
|
|
48
|
+
"./throttle": "./dist/throttle.js",
|
|
49
|
+
"./timestamp-throttle": "./dist/timestamp-throttle.js",
|
|
50
|
+
"./udp": "./dist/udp.js"
|
|
9
51
|
},
|
|
10
52
|
"repository": {
|
|
11
53
|
"type": "git",
|
package/actisense-serial.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('@canboat/canboatjs').serial
|
package/autodetect.js
DELETED
|
@@ -1,198 +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
|
-
const Writable = require('stream').Writable
|
|
19
|
-
const TimestampThrottle = require('./timestamp-throttle')
|
|
20
|
-
|
|
21
|
-
const N2KJsonToSignalK = require('./n2k-signalk')
|
|
22
|
-
const ActisenseSerialToJSON = require('./n2kAnalyzer')
|
|
23
|
-
const canboatjs = require('./canboatjs')
|
|
24
|
-
const Nmea01832SignalK = require('./nmea0183-signalk')
|
|
25
|
-
const _ = require('lodash')
|
|
26
|
-
|
|
27
|
-
/*
|
|
28
|
-
|
|
29
|
-
Provider to handle any kind of supported input data.
|
|
30
|
-
|
|
31
|
-
It will detect if the incoming data is in the 'multiplexedlog' format
|
|
32
|
-
(produced by the server's logging function)and if not, then it will
|
|
33
|
-
look at each incoming line to try to determine the type of data.
|
|
34
|
-
|
|
35
|
-
A multiplexed log should have this format:
|
|
36
|
-
|
|
37
|
-
milliseconds;discriminator;data
|
|
38
|
-
where discriminator can be
|
|
39
|
-
N => NMEA0183
|
|
40
|
-
I => Signal K delta
|
|
41
|
-
A => actisense-serial format N2K data
|
|
42
|
-
|
|
43
|
-
1471172400151;N;!AIVDM,1,1,,A,13KdO60034Qk?WtRHUJQ3@ol05Cd,0*55
|
|
44
|
-
1471172400152;I;{"updates":[{"source":{"label":"i2c"},"values":[{"path":"electrical.batteries.house.voltage","value":13.5741469711775},{"path":"electrical.batteries.house.current","value":0.39957033121875}],"timestamp":"2016-07-16T12:00:08.825Z"}],"context":"vessels.230029970"}
|
|
45
|
-
1471172400153;A;2016-07-16T12:00:00.000Z,2,130306,105,255,8,00,d1,03,c9,23,fa,ff,ff
|
|
46
|
-
*/
|
|
47
|
-
|
|
48
|
-
function DeMultiplexer(options) {
|
|
49
|
-
Writable.call(this)
|
|
50
|
-
|
|
51
|
-
this.toTimestamped = new ToTimestamped(this, options)
|
|
52
|
-
this.timestampThrottle = new TimestampThrottle({
|
|
53
|
-
getMilliseconds: (msg) => msg.timestamp
|
|
54
|
-
})
|
|
55
|
-
this.splitter = new Splitter(this, options)
|
|
56
|
-
this.options = options
|
|
57
|
-
|
|
58
|
-
this.toTimestamped.on('drain', this.emit.bind(this, 'drain'))
|
|
59
|
-
}
|
|
60
|
-
require('util').inherits(DeMultiplexer, Writable)
|
|
61
|
-
|
|
62
|
-
DeMultiplexer.prototype.pipe = function (target) {
|
|
63
|
-
return this.splitter.pipe(target)
|
|
64
|
-
}
|
|
65
|
-
DeMultiplexer.prototype.write = function (chunk, encoding, callback) {
|
|
66
|
-
return this.toTimestamped.write(chunk, encoding, callback)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function Splitter(deMultiplexer, options) {
|
|
70
|
-
Transform.call(this, { objectMode: true })
|
|
71
|
-
this.demuxEmitData = function (msg) {
|
|
72
|
-
deMultiplexer.emit('data', msg)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
this.fromN2KJson = new N2KJsonToSignalK(options)
|
|
76
|
-
this.fromN2KJson.on('data', this.demuxEmitData)
|
|
77
|
-
|
|
78
|
-
if (_.isUndefined(options.useCanboatjs) || options.useCanboatjs) {
|
|
79
|
-
this.fromActisenseSerial = new canboatjs(options)
|
|
80
|
-
} else {
|
|
81
|
-
this.fromActisenseSerial = new ActisenseSerialToJSON(options)
|
|
82
|
-
}
|
|
83
|
-
this.fromActisenseSerial.pipe(this.fromN2KJson)
|
|
84
|
-
|
|
85
|
-
this.fromNMEA0183 = new Nmea01832SignalK(options)
|
|
86
|
-
this.fromNMEA0183.on('data', this.demuxEmitData)
|
|
87
|
-
}
|
|
88
|
-
require('util').inherits(Splitter, Transform)
|
|
89
|
-
|
|
90
|
-
Splitter.prototype._transform = function (msg, encoding, _done) {
|
|
91
|
-
let done = _done
|
|
92
|
-
try {
|
|
93
|
-
switch (msg.discriminator) {
|
|
94
|
-
case 'A': {
|
|
95
|
-
msg.fromFile = true
|
|
96
|
-
const result = this.fromActisenseSerial.write(msg, encoding)
|
|
97
|
-
if (!result) {
|
|
98
|
-
this.fromActisenseSerial.once('drain', _done)
|
|
99
|
-
done = () => {}
|
|
100
|
-
}
|
|
101
|
-
break
|
|
102
|
-
}
|
|
103
|
-
case 'C':
|
|
104
|
-
case 'N':
|
|
105
|
-
case 'G':
|
|
106
|
-
case 'M':
|
|
107
|
-
this.fromNMEA0183.write(
|
|
108
|
-
{ line: msg.data, timestamp: msg.timestamp },
|
|
109
|
-
encoding
|
|
110
|
-
)
|
|
111
|
-
break
|
|
112
|
-
case 'I':
|
|
113
|
-
default:
|
|
114
|
-
try {
|
|
115
|
-
const parsed = JSON.parse(msg.data)
|
|
116
|
-
const timestamp = new Date(Number(msg.timestamp))
|
|
117
|
-
parsed.updates &&
|
|
118
|
-
parsed.updates.forEach((update) => (update.timestamp = timestamp))
|
|
119
|
-
this.push(parsed)
|
|
120
|
-
this.demuxEmitData(parsed)
|
|
121
|
-
} catch (e) {
|
|
122
|
-
console.error(e)
|
|
123
|
-
}
|
|
124
|
-
break
|
|
125
|
-
}
|
|
126
|
-
} finally {
|
|
127
|
-
done()
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
Splitter.prototype.pipe = function (target) {
|
|
131
|
-
this.fromN2KJson.pipe(target)
|
|
132
|
-
this.fromNMEA0183.pipe(target)
|
|
133
|
-
return Transform.prototype.pipe.call(this, target)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function ToTimestamped(deMultiplexer, options) {
|
|
137
|
-
Transform.call(this, { objectMode: true })
|
|
138
|
-
this.deMultiplexer = deMultiplexer
|
|
139
|
-
this.options = options
|
|
140
|
-
}
|
|
141
|
-
require('util').inherits(ToTimestamped, Transform)
|
|
142
|
-
|
|
143
|
-
// runs only once, self-assigns the actual transform functions
|
|
144
|
-
// on first call
|
|
145
|
-
ToTimestamped.prototype._transform = function (msg, encoding, done) {
|
|
146
|
-
//ignore empty lines in the beginning of the file, encountered in some cases
|
|
147
|
-
if (msg.trim().length === 0) {
|
|
148
|
-
done()
|
|
149
|
-
return
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const line = msg.toString()
|
|
153
|
-
this.multiplexedFormat =
|
|
154
|
-
line.length > 16 && line.charAt(13) === ';' && line.split(';').length >= 3
|
|
155
|
-
if (this.multiplexedFormat) {
|
|
156
|
-
if (this.options.noThrottle) {
|
|
157
|
-
this.deMultiplexer.toTimestamped.pipe(this.deMultiplexer.splitter)
|
|
158
|
-
} else {
|
|
159
|
-
this.deMultiplexer.toTimestamped
|
|
160
|
-
.pipe(this.deMultiplexer.timestampThrottle)
|
|
161
|
-
.pipe(this.deMultiplexer.splitter)
|
|
162
|
-
}
|
|
163
|
-
this._transform = this.handleMultiplexed
|
|
164
|
-
} else {
|
|
165
|
-
this._transform = this.handleMixed
|
|
166
|
-
}
|
|
167
|
-
this._transform(msg, encoding, done)
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
ToTimestamped.prototype.handleMixed = function (msg, encoding, done) {
|
|
171
|
-
const line = msg.toString()
|
|
172
|
-
const res = { timestamp: new Date().getTime(), data: line }
|
|
173
|
-
if (line.charAt(0) === '{') {
|
|
174
|
-
res.discriminator = 'I'
|
|
175
|
-
} else if (
|
|
176
|
-
(line.charAt(0) === '$' || line.charAt(0) === '!') &&
|
|
177
|
-
!line.startsWith('!PDGY') // iKonect
|
|
178
|
-
) {
|
|
179
|
-
res.discriminator = 'N'
|
|
180
|
-
} else {
|
|
181
|
-
res.discriminator = 'A'
|
|
182
|
-
}
|
|
183
|
-
this.push(res)
|
|
184
|
-
done()
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
ToTimestamped.prototype.handleMultiplexed = function (msg, encoding, done) {
|
|
188
|
-
const line = msg.toString()
|
|
189
|
-
const parts = line.split(';')
|
|
190
|
-
this.push({
|
|
191
|
-
timestamp: parts[0],
|
|
192
|
-
discriminator: parts[1],
|
|
193
|
-
data: parts.slice(2).join(';')
|
|
194
|
-
})
|
|
195
|
-
done()
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
module.exports = DeMultiplexer
|
package/canboatjs.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2017 Signal K & Fabian Tollenaar <fabian@signalk.org>
|
|
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
|
-
const FromPgn = require('@canboat/canboatjs').FromPgn
|
|
19
|
-
const _ = require('lodash')
|
|
20
|
-
|
|
21
|
-
function CanboatJs(options) {
|
|
22
|
-
Transform.call(this, {
|
|
23
|
-
objectMode: true
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
if (options.useCamelCompat === undefined) {
|
|
27
|
-
options.useCamelCompat = true
|
|
28
|
-
}
|
|
29
|
-
this.fromPgn = new FromPgn(options)
|
|
30
|
-
const createDebug = options.createDebug || require('debug')
|
|
31
|
-
const debug = createDebug('signalk:streams:canboatjs')
|
|
32
|
-
|
|
33
|
-
this.fromPgn.on('warning', (pgn, warning) => {
|
|
34
|
-
debug(`[warning] ${pgn.pgn} ${warning}`)
|
|
35
|
-
options.app.emit(`canboatjs:warning`, warning)
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
this.fromPgn.on('error', (pgn, err) => {
|
|
39
|
-
console.error(pgn.input, err.message)
|
|
40
|
-
options.app.emit(`canboatjs:error`, err)
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
this.app = options.app
|
|
44
|
-
this.analyzerOutEvent = options.analyzerOutEvent || 'N2KAnalyzerOut'
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
require('util').inherits(CanboatJs, Transform)
|
|
48
|
-
|
|
49
|
-
CanboatJs.prototype._transform = function (chunk, encoding, done) {
|
|
50
|
-
if (_.isObject(chunk) && chunk.fromFile) {
|
|
51
|
-
const pgnData = this.fromPgn.parse(chunk.data)
|
|
52
|
-
if (pgnData) {
|
|
53
|
-
pgnData.timestamp = new Date(Number(chunk.timestamp)).toISOString()
|
|
54
|
-
this.push(pgnData)
|
|
55
|
-
this.app.emit(this.analyzerOutEvent, pgnData)
|
|
56
|
-
} else {
|
|
57
|
-
this.app.emit('canboatjs:unparsed:object', chunk)
|
|
58
|
-
}
|
|
59
|
-
} else {
|
|
60
|
-
const pgnData = this.fromPgn.parse(chunk)
|
|
61
|
-
if (pgnData) {
|
|
62
|
-
this.push(pgnData)
|
|
63
|
-
this.app.emit(this.analyzerOutEvent, pgnData)
|
|
64
|
-
} else {
|
|
65
|
-
this.app.emit('canboatjs:unparsed:data', chunk)
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
done()
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
module.exports = CanboatJs
|
package/canbus.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2018 Signal K & 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
|
-
module.exports = require('@canboat/canboatjs').canbus
|