UNPKG

@signalk/streams

Version:

Utilities for handling streams of Signal K data

144 lines (143 loc) 5.57 kB
"use strict"; /* * Copyright 2017 Signal K & Fabian Tollenaar <fabian@signalk.org> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const stream_1 = require("stream"); const nmea0183_signalk_1 = __importDefault(require("@signalk/nmea0183-signalk")); const nmea0183_utilities_1 = require("@signalk/nmea0183-utilities"); function isN2KOver0183(msg) { const sentence = msg.charAt(0) === '\\' ? msg.split('\\')[2] : msg; return sentence ? sentence.startsWith('$PCDIN,') || sentence.startsWith('$MXPGN,') : false; } class Nmea0183ToSignalK extends stream_1.Transform { debug; parser; parseN2KOver0183 = // runs only once when needed, replaces itself with the actual function // after loading the required modules (sentence) => { const { FromPgn } = require('@canboat/canboatjs'); const n2kParser = new FromPgn({ ...this.options, useCamelCompat: this.options.useCamelCompat ?? true }); n2kParser.on('warning', (pgn, warning) => { this.debug.enabled && this.debug(`[warning] ${pgn.pgn} ${warning}`); }); n2kParser.on('error', (pgn, err) => { this.debug.enabled && this.debug(`[error] ${pgn.input} ${err.message}`); }); this.parseN2KOver0183 = n2kParser.parseN2KOver0183.bind(n2kParser); this.n2kToDelta = require('@signalk/n2k-signalk').toDelta; return this.parseN2KOver0183(sentence, () => { }); }; n2kToDelta; n2kState = {}; app; sentenceEvents; appendChecksumFlag; options; constructor(options) { super({ objectMode: true }); this.debug = (options.createDebug ?? require('debug'))('signalk:streams:nmea0183-signalk'); this.parser = new nmea0183_signalk_1.default(options); this.options = options; this.app = options.app; this.appendChecksumFlag = options.appendChecksum ?? false; this.sentenceEvents = options.suppress0183event ? [] : ['nmea0183']; if (options.sentenceEvent) { if (Array.isArray(options.sentenceEvent)) { this.sentenceEvents = this.sentenceEvents.concat(options.sentenceEvent); } else { this.sentenceEvents.push(options.sentenceEvent); } } } _transform(chunk, encoding, done) { let sentence; let timestamp = null; if (chunk && typeof chunk === 'object' && !Buffer.isBuffer(chunk) && typeof chunk.line === 'string') { const tsChunk = chunk; timestamp = new Date(Number(tsChunk.timestamp)); sentence = tsChunk.line.trim(); } else if (Buffer.isBuffer(chunk)) { sentence = chunk.toString().trim(); } else if (chunk && typeof chunk === 'string') { sentence = chunk.trim(); } if (sentence === '') { // Empty input (e.g. trailing newline from upstream source). Drop // silently without emitting events or invoking the parser. done(); return; } if (sentence !== undefined && sentence.startsWith('#')) { // Comment line from upstream source (e.g. gpiod-seatalk framing // diagnostics). Log at debug level and drop without parsing or // emitting nmea0183 events. this.debug(sentence); done(); return; } try { if (sentence !== undefined) { if (this.appendChecksumFlag) { sentence = (0, nmea0183_utilities_1.appendChecksum)(sentence); } this.sentenceEvents.forEach((eventName) => { this.app.emit(eventName, sentence); this.app.signalk.emit(eventName, sentence); }); let delta = null; if (isN2KOver0183(sentence)) { const pgn = this.parseN2KOver0183(sentence, () => { }); if (pgn) { delta = this.n2kToDelta(pgn, this.n2kState, { sendMetaData: true }); } } else { delta = this.parser.parse(sentence); } if (delta !== null) { if (timestamp !== null) { delta.updates.forEach((update) => { update.timestamp = timestamp; }); } this.push(delta); } } } catch (e) { this.debug(e); } done(); } } exports.default = Nmea0183ToSignalK; //# sourceMappingURL=nmea0183-signalk.js.map