@canboat/visual-analyzer
Version:
NMEA 2000 data visualization utility (requires SK Server >= 2.15)
200 lines • 8.52 kB
JavaScript
"use strict";
/**
* Copyright 2025 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 });
const tcp_1 = __importDefault(require("./streams/tcp"));
const udp_1 = __importDefault(require("./streams/udp"));
const serialport_1 = __importDefault(require("./streams/serialport"));
const liner_1 = __importDefault(require("./streams/liner"));
const nullStream_1 = __importDefault(require("./streams/nullStream"));
const ts_pgns_1 = require("@canboat/ts-pgns");
const canboatjs_1 = require("@canboat/canboatjs");
const package_json_1 = __importDefault(require("../package.json"));
const outEvent = 'n2k-device-out';
class CanDevice {
constructor(app, options) {
this.netStream = null;
this.serialStream = null;
this.listeners = [];
//super()
this.options = options;
this.app = {
...app,
on: (event, callback) => {
this.addListener(app, event, callback);
app.on(event, callback);
},
};
}
async start() {
return new Promise((resolve, reject) => {
try {
const n2kOptions = this.getN2kDeviceOptions(this.app);
if (this.options.type === 'socketcan') {
this.stream = (0, canboatjs_1.canbus)({
...n2kOptions,
providerId: this.options.deviceType,
canDevice: this.options.socketcanInterface,
});
this.stream.pipe(new nullStream_1.default());
this.app.emit('connected');
}
else if (this.options.type === 'network') {
const netOptions = {
app: this.app,
providerId: this.options.deviceType,
port: this.options.networkPort,
host: this.options.networkHost,
outEvent,
};
if (this.options.networkProtocol === 'tcp') {
this.netStream = new tcp_1.default(netOptions);
}
else {
this.netStream = new udp_1.default(netOptions);
}
if (this.options.deviceType === 'Yacht Devices RAW') {
this.stream = (0, canboatjs_1.Ydwg02)({ ...n2kOptions, providerId: this.options.deviceType, createDevice: true, ydgwOutEvent: outEvent }, 'net');
}
else if (this.options.deviceType === 'iKonvert') {
this.stream = (0, canboatjs_1.iKonvert)({
app: this.app,
providerId: this.options.deviceType,
tcp: true,
outEvent,
});
}
else if (this.options.deviceType === 'Actisense ASCII') {
this.stream = (0, canboatjs_1.W2k01)({
app: this.app,
providerId: this.options.deviceType,
}, 'ascii', outEvent);
}
const liner = new liner_1.default({});
this.netStream.pipe(liner);
liner.pipe(this.stream);
this.stream.pipe(new nullStream_1.default());
}
else if (this.options.type === 'serial') {
if (this.options.deviceType === 'Actisense') {
this.stream = new canboatjs_1.serial({
providerId: this.options.deviceType,
device: this.options.serialPort,
baudrate: this.options.baudRate,
reconnect: false,
app: this.app,
});
this.app.emit('connected');
}
else if (this.options.deviceType === 'Yacht Devices RAW') {
this.serialStream = new serialport_1.default({
app: this.app,
providerId: this.options.deviceType,
device: this.options.serialPort,
baudrate: this.options.baudRate || 38400,
reconnect: false,
toStdout: outEvent,
});
this.stream = (0, canboatjs_1.Ydwg02)({ ...n2kOptions, createDevice: true, ydgwOutEvent: outEvent }, 'usb');
}
else if (this.options.deviceType === 'iKonvert') {
this.serialStream = new serialport_1.default({
app: this.app,
providerId: this.options.deviceType,
device: this.options.serialPort,
baudrate: this.options.baudRate || 230400,
reconnect: false,
toStdout: 'ikonvertOut',
});
this.stream = (0, canboatjs_1.iKonvert)({
app: this.app,
providerId: this.options.deviceType,
tcp: false,
});
this.serialStream.pipe(this.stream);
}
this.stream.pipe(new nullStream_1.default());
}
resolve(true);
}
catch (error) {
reject(error);
}
});
}
send(pgn) {
if (this.stream) {
this.stream.sendPGN(pgn);
}
}
end() {
this.removeAllListeners();
if (this.netStream) {
this.netStream.end();
this.netStream = null;
}
if (this.serialStream) {
this.serialStream.end();
this.serialStream = null;
}
if (this.stream) {
this.stream.end();
this.stream = null;
}
}
addListener(object, event, listener) {
this.listeners.push({ object, event, listener });
}
removeAllListeners() {
this.listeners.forEach(({ object, event, listener }) => {
object.removeListener(event, listener);
});
this.listeners = [];
}
getN2kDeviceOptions(app) {
return {
app,
providerId: this.options.deviceType,
preferredAddress: this.options.sourceAddress || 11,
disableDefaultTransmitPGNs: true,
addressClaim: new ts_pgns_1.PGN_60928({
manufacturerCode: 999,
deviceFunction: ts_pgns_1.DeviceFunction.Diagnostic,
deviceClass: ts_pgns_1.DeviceClass.SystemTools,
deviceInstanceLower: 0,
deviceInstanceUpper: 0,
systemInstance: 0,
industryGroup: ts_pgns_1.IndustryCode.Marine,
arbitraryAddressCapable: ts_pgns_1.YesNo.Yes,
}),
productInfo: new ts_pgns_1.PGN_126996({
nmea2000Version: 2100,
productCode: 100,
modelId: 'N2K Visual Analyzer',
softwareVersionCode: package_json_1.default.version,
modelVersion: package_json_1.default.version,
modelSerialCode: '01',
certificationLevel: ts_pgns_1.CertificationLevel.LevelA,
loadEquivalency: 1,
}),
};
}
}
exports.default = CanDevice;
//# sourceMappingURL=n2k-device.js.map