UNPKG

@canboat/canboatjs

Version:

Native javascript version of canboat

234 lines 8.91 kB
"use strict"; /** * Copyright 2018 Scott Bender (scott@scottbender.net) * * 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 }); exports.iKonvertStream = iKonvertStream; const utilities_1 = require("./utilities"); const stream_1 = require("stream"); const toPgn_1 = require("./toPgn"); const fromPgn_1 = require("./fromPgn"); const lodash_1 = __importDefault(require("lodash")); const codes_1 = require("./codes"); const util_1 = __importDefault(require("util")); //const pgnsSent = {} function iKonvertStream(options) { if (this == undefined) { return new iKonvertStream(options); } this.debug = (0, utilities_1.createDebug)('canboatjs:ikonvert', options); this.debugOut = (0, utilities_1.createDebug)('canboatjs:n2k-out', options); stream_1.Transform.call(this, { objectMode: true }); this.isTcp = options.tcp === true; this.outEvent = this.isTcp ? 'navlink2-out' : 'ikonvertOut'; this.plainText = false; this.reconnect = options.reconnect || true; this.options = options; this.cansend = false; this.buffer = Buffer.alloc(500); this.bufferOffset = 0; this.start(); this.setProviderStatus = options.app && options.app.setProviderStatus ? (msg) => { options.app.setProviderStatus(options.providerId, msg); } : () => { }; this.setProviderError = options.app && options.app.setProviderError ? (msg) => { options.app.setProviderError(options.providerId, msg); } : () => { }; this.transmitPGNs = codes_1.defaultTransmitPGNs; if (this.options.transmitPGNs) { this.transmitPGNs = lodash_1.default.union(this.transmitPGNs, this.options.transmitPGNs); } // eslint-disable-next-line @typescript-eslint/no-this-alias const that = this; if (this.options.app) { options.app.on(this.options.outEevent || 'nmea2000out', (msg) => { if (typeof msg === 'string') { that.sendActisensePGN(msg); } else { that.sendPGN(msg); } options.app.emit('connectionwrite', { providerId: options.providerId }); }); options.app.on(options.jsonOutEvent || 'nmea2000JsonOut', (msg) => { that.sendPGN(msg); options.app.emit('connectionwrite', { providerId: options.providerId }); }); this.isSetup = false; //this.cansend = true this.state = 0; this.setupCommands = this.getSetupCommands(); this.expecting = false; this.debug('started'); } } util_1.default.inherits(iKonvertStream, stream_1.Transform); iKonvertStream.prototype.start = function () { }; iKonvertStream.prototype.sendString = function (msg) { this.debugOut('sending %s', msg); if (this.isTcp) { msg = msg + '\n\r'; } this.options.app.emit(this.outEvent, msg); }; iKonvertStream.prototype.sendPGN = function (pgn) { if (this.cansend) { //let now = Date.now() //let lastSent = pgnsSent[pgn.pgn] const msg = (0, toPgn_1.pgnToiKonvertSerialFormat)(pgn); if (this.options.app.listenerCount('canboatjs:rawsend') > 0) { this.options.app.emit('canboatjs:rawsend', { data: msg }); } this.sendString(msg); //pgnsSent[pgn.pgn] = now } }; iKonvertStream.prototype.sendActisensePGN = function (msg) { if (this.cansend) { if (!this.parser) { this.parser = new fromPgn_1.Parser(this.options); // eslint-disable-next-line @typescript-eslint/no-this-alias const that = this; this.parser.on('error', (pgn, error) => { console.error(`Error parsing ${pgn.pgn} ${error}`); console.error(error.stack); }); this.parser.on('pgn', (pgn) => { //let now = Date.now() //let lastSent = pgnsSent[pgn.pgn] const msg = (0, toPgn_1.pgnToiKonvertSerialFormat)(pgn); if (this.options.app.listenerCount('canboatjs:rawsend') > 0) { this.options.app.emit('canboatjs:rawsend', { data: msg }); } that.sendString(msg); //pgnsSent[pgn.pgn] = now }); } this.parser.parseString(msg); } }; iKonvertStream.prototype.setup = function () { let txPgns = '$PDGY,TX_LIST'; this.transmitPGNs.forEach((pgn) => { txPgns = txPgns + `,${pgn}`; }); this.debug('sending pgn tx list'); this.sendString(txPgns); }; iKonvertStream.prototype.getSetupCommands = function () { let txPgns = '$PDGY,TX_LIST'; this.transmitPGNs.forEach((pgn) => { txPgns = txPgns + `,${pgn}`; }); const setupCommands = []; setupCommands.push('$PDGY,N2NET_OFFLINE:$PDGY,TEXT,Digital_Yacht_'); if (this.isTcp) { setupCommands.push('$PDGY,N2NET_MODE,15:$PDGY,ACK,N2NET_MODE'); } setupCommands.push('$PDGY,TX_LIMIT,OFF:$PDGY,'); // NACK is ok with old firmware setupCommands.push(`${txPgns}:$PDGY,ACK,TX_LIST`); setupCommands.push('$PDGY,N2NET_INIT,ALL:$PDGY,ACK,N2NET_INIT,ALL'); return setupCommands; }; iKonvertStream.prototype._transform = function (chunk, encoding, done) { let line = chunk.toString().trim(); line = line.substring(0, line.length); // take off the \r if (line.startsWith('$PDGY,TEXT')) { this.debug(line); } else if (line.startsWith('$PDGY,000000,')) { const parts = line.split(','); //FIXME, camelCase? if (this.options.sendNetworkStats && parts[2] && parts[2].length > 0) { const pgn = { pgn: 0x40100, prio: 7, dst: 255, src: 0, 'CAN network load': Number(parts[2]), Errors: Number(parts[3]), 'Device count': Number(parts[4]), Uptime: Number(parts[5]), 'Gateway address': Number(parts[6]), 'Rejected TX requests': Number(parts[7]) }; const buf = (0, toPgn_1.toPgn)(pgn); if (buf) { this.push(`!PDGY,${pgn.pgn},${pgn.prio},${pgn.src},${pgn.dst},0,${buf.toString('base64')}`); } done(); return; } } else if (line.startsWith('$PDGY,NAK')) { const parts = line.split(','); const msg = `NavLink2 error ${parts[2]}: ${parts[3]}`; console.error(msg); //this.setProviderError(msg) } if (!this.isSetup) { this.debug(line); let command = this.setupCommands[this.state].split(':'); if (!this.expecting) { this.sendString(command[0]); this.expecting = true; this.sentTime = Date.now(); this.debug(`Waiting for ${command[1]}`); } else { if (line.startsWith(command[1])) { this.state = this.state + 1; if (this.state == this.setupCommands.length) { this.isSetup = true; this.cansend = true; this.options.app.emit('nmea2000OutAvailable'); this.debug('Setup completed'); } else { command = this.setupCommands[this.state].split(':'); this.sendString(command[0]); this.expecting = true; this.sentTime = Date.now(); this.debug(`Waiting for ${command[1]}`); } } else if (Date.now() - this.sentTime > 5000) { this.debug(`Did not receive expected: ${command[1]}, retrying...`); this.sendString(command[0]); this.sentTime = Date.now(); } } } else { this.push(line); if (this.options.app.listenerCount('canboatjs:rawoutput') > 0) { this.options.app.emit('canboatjs:rawoutput', line); } } done(); }; iKonvertStream.prototype.end = function () { }; //# sourceMappingURL=ikonvert.js.map