@devalexdom/victron-vedirect-pnp
Version:
A plug and play way to easily read data from your connected Victron VE.Direct devices
627 lines (539 loc) • 23.2 kB
JavaScript
'use strict';
var child_process = require('child_process');
var stream = require('stream');
var SerialPort = require('serialport');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var SerialPort__default = /*#__PURE__*/_interopDefaultLegacy(SerialPort);
class VEDirectData {
constructor(VEDirectRawData) {
for (const key in VEDirectRawData) {
if (isNaN(VEDirectRawData[key])) {
this[key] = VEDirectRawData[key];
} else {
this[key] = parseInt(VEDirectRawData[key]);
}
}
}
}
class VEDirectParser extends stream.Transform {
constructor() {
super({
readableObjectMode: true
});
this.buffer = Buffer.alloc(0);
this.rawDataBlock = {};
}
isChecksumValid() {
return this.buffer.reduce((prev, curr) => prev + curr & 255, 0) === 0;
}
_transform(dataChunk, encoding, callback) {
const [key, value] = dataChunk.toString().split('\t');
if (key[0] === ':') {
callback();
return;
}
this.buffer = Buffer.concat([this.buffer, Buffer.from([0x0d, 0x0a]), dataChunk]);
if (key === "Checksum") {
if (this.isChecksumValid()) {
this.push(this.rawDataBlock);
}
this.buffer = Buffer.alloc(0);
this.rawDataBlock = {};
} else {
this.rawDataBlock[key] = value;
}
callback();
}
}
const deviceName = {
768: "BlueSolar MPPT 70|15",
41087: "All-In-1 SmartSolar MPPT 75/15 12V",
41024: "BlueSolar MPPT 75|50",
41025: "BlueSolar MPPT 150|35",
41026: "BlueSolar MPPT 75|15",
41027: "BlueSolar MPPT 100|15",
41028: "BlueSolar MPPT 100|30",
41029: "BlueSolar MPPT 100|50",
41030: "BlueSolar MPPT 150|70",
41031: "BlueSolar MPPT 150|100",
41033: "BlueSolar MPPT 100|50 rev2",
41034: "BlueSolar MPPT 100|30 rev2",
41035: "BlueSolar MPPT 150|35 rev2",
41036: "BlueSolar MPPT 75|10",
41037: "BlueSolar MPPT 150|45",
41074: "BlueSolar MPPT 150/45 rev3",
41038: "BlueSolar MPPT 150|60",
41039: "BlueSolar MPPT 150|85",
41040: "SmartSolar MPPT 250|100",
41041: "SmartSolar MPPT 150|100",
41042: "SmartSolar MPPT 150|85",
41043: "SmartSolar MPPT 75|15",
41044: "SmartSolar MPPT 75|10",
41045: "SmartSolar MPPT 100|15",
41046: "SmartSolar MPPT 100|30",
41047: "SmartSolar MPPT 100|50",
41048: "SmartSolar MPPT 150|35",
41049: "SmartSolar MPPT 150|100 rev2",
41050: "SmartSolar MPPT 150|85 rev2",
41051: "SmartSolar MPPT 250|70",
41052: "SmartSolar MPPT 250|85",
41053: "SmartSolar MPPT 250|60",
41054: "SmartSolar MPPT 250|45",
41055: "SmartSolar MPPT 100|20",
41056: "SmartSolar MPPT 100|20 48V",
41057: "SmartSolar MPPT 150|45",
41058: "SmartSolar MPPT 150|60",
41059: "SmartSolar MPPT 150|70",
41060: "SmartSolar MPPT 250|85 rev2",
41061: "SmartSolar MPPT 250|100 rev2",
41062: "BlueSolar MPPT 100|20",
41063: "BlueSolar MPPT 100|20 48V",
41064: "SmartSolar MPPT 250|60 rev2",
41065: "SmartSolar MPPT 250|70 rev2",
41066: "SmartSolar MPPT 150|45 rev2",
41067: "SmartSolar MPPT 150|60 rev2",
41068: "SmartSolar MPPT 150|70 rev2",
41069: "SmartSolar MPPT 150|85 rev3",
41070: "SmartSolar MPPT 150|100 rev3",
41071: "BlueSolar MPPT 150|45 rev2",
41072: "BlueSolar MPPT 150|60 rev2",
41073: "BlueSolar MPPT 150|70 rev2",
41075: "SmartSolar MPPT 150/45 rev3",
41218: "SmartSolar MPPT VE.Can 150/70",
41219: "SmartSolar MPPT VE.Can 150/45",
41220: "SmartSolar MPPT VE.Can 150/60",
41221: "SmartSolar MPPT VE.Can 150/85",
41222: "SmartSolar MPPT VE.Can 150/100",
41223: "SmartSolar MPPT VE.Can 250/45",
41224: "SmartSolar MPPT VE.Can 250/60",
41225: "SmartSolar MPPT VE.Can 250/70",
41226: "SmartSolar MPPT VE.Can 250/85",
41227: "SmartSolar MPPT VE.Can 250/100",
41228: "SmartSolar MPPT VE.Can 150/70 rev2",
41229: "SmartSolar MPPT VE.Can 150/85 rev2",
41230: "SmartSolar MPPT VE.Can 150/100 rev2",
41231: "BlueSolar MPPT VE.Can 150/100",
41234: "BlueSolar MPPT VE.Can 250/70",
41235: "BlueSolar MPPT VE.Can 250/100",
41236: "SmartSolar MPPT VE.Can 250/70 rev2",
41237: "SmartSolar MPPT VE.Can 250/100 rev2",
41238: "SmartSolar MPPT VE.Can 250/85 rev2",
41239: "BlueSolar MPPT VE.Can 150/100 rev2",
41968: "Smart BuckBoost 12V/12V-50A",
41865: "SmartShunt 500A/50mV",
41866: "SmartShunt 1000A/50mV",
41867: "SmartShunt 2000A/50mV",
41857: "BMV-712 Smart",
41858: "BMV-710H Smart",
41859: "BMV-712 Smart Rev2"
};
var StatusMessage;
(function (StatusMessage) {
StatusMessage[StatusMessage["Off"] = 0] = "Off";
StatusMessage[StatusMessage["Low power"] = 1] = "Low power";
StatusMessage[StatusMessage["Fault"] = 2] = "Fault";
StatusMessage[StatusMessage["Bulk"] = 3] = "Bulk";
StatusMessage[StatusMessage["Absorption"] = 4] = "Absorption";
StatusMessage[StatusMessage["Float"] = 5] = "Float";
StatusMessage[StatusMessage["Storage"] = 6] = "Storage";
StatusMessage[StatusMessage["Equalize (manual)"] = 7] = "Equalize (manual)";
StatusMessage[StatusMessage["Inverting"] = 9] = "Inverting";
StatusMessage[StatusMessage["Power supply"] = 11] = "Power supply";
StatusMessage[StatusMessage["Starting-up"] = 245] = "Starting-up";
StatusMessage[StatusMessage["Repeated absorption"] = 246] = "Repeated absorption";
StatusMessage[StatusMessage["Auto equalize / Recondition"] = 247] = "Auto equalize / Recondition";
StatusMessage[StatusMessage["BatterySafe"] = 247] = "BatterySafe";
StatusMessage[StatusMessage["External Control"] = 252] = "External Control";
})(StatusMessage || (StatusMessage = {}));
var ErrorMessage;
(function (ErrorMessage) {
ErrorMessage[ErrorMessage[""] = 0] = "";
ErrorMessage[ErrorMessage["Battery voltage too high"] = 2] = "Battery voltage too high";
ErrorMessage[ErrorMessage["Charger temperature too high"] = 17] = "Charger temperature too high";
ErrorMessage[ErrorMessage["Charger over current"] = 18] = "Charger over current";
ErrorMessage[ErrorMessage["Charger current reversed"] = 19] = "Charger current reversed";
ErrorMessage[ErrorMessage["Bulk time limit exceeded"] = 20] = "Bulk time limit exceeded";
ErrorMessage[ErrorMessage["Current sensor issue (sensor bias/sensor broken)"] = 21] = "Current sensor issue (sensor bias/sensor broken)";
ErrorMessage[ErrorMessage["Terminals overheated"] = 26] = "Terminals overheated";
ErrorMessage[ErrorMessage["Converter issue (dual converter models only)"] = 28] = "Converter issue (dual converter models only)";
ErrorMessage[ErrorMessage["Input voltage too high (solar panel)"] = 33] = "Input voltage too high (solar panel)";
ErrorMessage[ErrorMessage["Input current too high (solar panel)"] = 34] = "Input current too high (solar panel)";
ErrorMessage[ErrorMessage["Input shutdown (due to excessive battery voltage)"] = 38] = "Input shutdown (due to excessive battery voltage)";
ErrorMessage[ErrorMessage["Input shutdown (due to current flow during off mode)"] = 39] = "Input shutdown (due to current flow during off mode)";
ErrorMessage[ErrorMessage["Lost communication with one of devices"] = 65] = "Lost communication with one of devices";
ErrorMessage[ErrorMessage["Synchronised charging device configuration issue"] = 66] = "Synchronised charging device configuration issue";
ErrorMessage[ErrorMessage["BMS connection lost"] = 67] = "BMS connection lost";
ErrorMessage[ErrorMessage["Network misconfigured"] = 68] = "Network misconfigured";
ErrorMessage[ErrorMessage["Factory calibration data lost"] = 116] = "Factory calibration data lost";
ErrorMessage[ErrorMessage["Invalid/incompatible firmware"] = 117] = "Invalid/incompatible firmware";
ErrorMessage[ErrorMessage["User settings invalid"] = 119] = "User settings invalid";
})(ErrorMessage || (ErrorMessage = {}));
var MPPTMessage;
(function (MPPTMessage) {
MPPTMessage[MPPTMessage["Off"] = 0] = "Off";
MPPTMessage[MPPTMessage["Voltage or current limited"] = 1] = "Voltage or current limited";
MPPTMessage[MPPTMessage["MPP Tracker active"] = 2] = "MPP Tracker active";
})(MPPTMessage || (MPPTMessage = {}));
var AlarmReasonMessage;
(function (AlarmReasonMessage) {
AlarmReasonMessage[AlarmReasonMessage[""] = 0] = "";
AlarmReasonMessage[AlarmReasonMessage["Low Voltage"] = 1] = "Low Voltage";
AlarmReasonMessage[AlarmReasonMessage["High Voltage"] = 2] = "High Voltage";
AlarmReasonMessage[AlarmReasonMessage["Low SOC"] = 4] = "Low SOC";
AlarmReasonMessage[AlarmReasonMessage["Low Starter Voltage"] = 8] = "Low Starter Voltage";
AlarmReasonMessage[AlarmReasonMessage["High Starter Voltage"] = 16] = "High Starter Voltage";
AlarmReasonMessage[AlarmReasonMessage["Low Temperature"] = 32] = "Low Temperature";
AlarmReasonMessage[AlarmReasonMessage["High Temperature"] = 64] = "High Temperature";
AlarmReasonMessage[AlarmReasonMessage["Mid Voltage"] = 128] = "Mid Voltage";
AlarmReasonMessage[AlarmReasonMessage["Overload"] = 256] = "Overload";
AlarmReasonMessage[AlarmReasonMessage["DC-ripple"] = 512] = "DC-ripple";
AlarmReasonMessage[AlarmReasonMessage["Low V AC out"] = 1024] = "Low V AC out";
AlarmReasonMessage[AlarmReasonMessage["High V AC out"] = 2048] = "High V AC out";
AlarmReasonMessage[AlarmReasonMessage["Short Circuit"] = 4096] = "Short Circuit";
AlarmReasonMessage[AlarmReasonMessage["BMS Lockout"] = 8192] = "BMS Lockout";
})(AlarmReasonMessage || (AlarmReasonMessage = {}));
var DeviceType;
(function (DeviceType) {
DeviceType[DeviceType["MPPT"] = 0] = "MPPT";
DeviceType[DeviceType["Inverter"] = 1] = "Inverter";
DeviceType[DeviceType["BMV"] = 2] = "BMV";
DeviceType[DeviceType["Charger"] = 3] = "Charger";
})(DeviceType || (DeviceType = {}));
var OffReasonMessage;
(function (OffReasonMessage) {
OffReasonMessage[OffReasonMessage[""] = 0] = "";
OffReasonMessage[OffReasonMessage["No input power"] = 1] = "No input power";
OffReasonMessage[OffReasonMessage["Switched off (power switch)"] = 2] = "Switched off (power switch)";
OffReasonMessage[OffReasonMessage["Switched off (device mode register) "] = 4] = "Switched off (device mode register) ";
OffReasonMessage[OffReasonMessage["Remote input"] = 8] = "Remote input";
OffReasonMessage[OffReasonMessage["Protection active"] = 10] = "Protection active";
OffReasonMessage[OffReasonMessage["Paygo"] = 20] = "Paygo";
OffReasonMessage[OffReasonMessage["BMS"] = 40] = "BMS";
OffReasonMessage[OffReasonMessage["Engine shutdown detection"] = 80] = "Engine shutdown detection";
OffReasonMessage[OffReasonMessage["Analysing input voltage"] = 100] = "Analysing input voltage";
})(OffReasonMessage || (OffReasonMessage = {}));
class VEDirectPnP_UnsupportedDeviceData {
constructor(VEDirectRawData) {
var _a; //VE.Direct -> UnsupportedDeviceData properties mapping
const data = new VEDirectData(VEDirectRawData);
this.deviceName = getDeviceName(data["PID"]);
this.deviceSN = (_a = data["SER#"]) !== null && _a !== void 0 ? _a : "Unknown";
this.VEDirectData = data;
}
}
class VEDirectPnP_BMVDeviceData {
constructor(VEDirectRawData) {
var _a; //VE.Direct -> MPPTDeviceData properties mapping
const data = new VEDirectData(VEDirectRawData);
this.deviceName = getDeviceName(data["PID"]);
this.deviceSN = (_a = data["SER#"]) !== null && _a !== void 0 ? _a : "Unknown";
this.deviceType = DeviceType[2];
this.deviceFirmwareVersion = getDeviceFW(data);
this.batteryMidPointVoltage = getNullableNumber(data.VM) / 1000; //mV -> V
this.batteryMidPointDeviation = getNullableNumber(data.DM) / 10;
this.batteryAuxVoltage = getNullableNumber(data.VS) / 1000; //mV -> V
this.batteryVoltage = getNullableNumber(data.V) / 1000; //mV -> V
this.batteryCurrent = getNullableNumber(data.I) / 1000; //mA -> A
this.batteryPercentage = getNullableNumber(data.SOC) / 10;
this.batteryInstantaneousPower = getNullableNumber(data.P) / 1000;
this.batteryTemperature = getNullableNumber(data.T); //Celsius
this.consumedAmpHours = getNullableNumber(data.CE) / 1000;
this.relayState = getStringBoolean(data.Relay);
this.deepestDischargeAmpHours = getNullableNumber(data.H1) / 1000;
this.lastDischargeAmpHours = getNullableNumber(data.H2) / 1000;
this.averageDischargeAmpHours = getNullableNumber(data.H3) / 1000;
this.chargeCycles = getNullableNumber(data.H4);
this.fullDischarges = getNullableNumber(data.H5);
this.cumulativeDrawnAmpHours = getNullableNumber(data.H6) / 1000;
this.batteryMinVoltage = getNullableNumber(data.H7) / 1000;
this.batteryMaxVoltage = getNullableNumber(data.H8) / 1000;
this.hoursSinceLastFullCharge = getNullableNumber(data.H9) / 3600;
this.automaticSynchronizations = getNullableNumber(data.H10);
this.lowMainVoltageAlarms = getNullableNumber(data.H11);
this.highMainVoltageAlarms = getNullableNumber(data.H12);
this.lowAuxVoltageAlarms = getNullableNumber(data.H13);
this.highAuxVoltageAlarms = getNullableNumber(data.H14);
this.batteryAuxMinVoltage = getNullableNumber(data.H15) / 1000;
this.batteryAuxMaxVoltage = getNullableNumber(data.H16) / 1000;
this.dischargedEnergy = getNullableNumber(data.H17) / 100; //KWh
this.chargedEnergy = getNullableNumber(data.H18) / 100; //KWh
this.alarmState = getStringBoolean(data.Alarm);
this.alarmMessage = AlarmReasonMessage[data.AR];
this.VEDirectData = data;
}
}
class VEDirectPnP_MPPTDeviceData {
constructor(VEDirectRawData) {
//VE.Direct -> MPPTDeviceData properties mapping
const data = new VEDirectData(VEDirectRawData);
this.deviceName = getDeviceName(data["PID"]);
this.deviceSN = data["SER#"];
this.deviceType = DeviceType[0];
this.deviceFirmwareVersion = getDeviceFW(data);
this.batteryVoltage = data["V"] / 1000; //mV -> V
this.batteryCurrent = data["I"] / 1000; //mA -> A
this.statusMessage = StatusMessage[data["CS"]];
this.errorMessage = ErrorMessage[data["ERR"]];
this.mpptMessage = MPPTMessage[data["MPPT"]];
this.maximumPowerToday = data["H21"]; // W
this.maximumPowerYesterday = data["H23"]; // W
this.totalEnergyProduced = data["H19"] / 100; // kWh
this.energyProducedToday = data["H20"] / 100; // kWh
this.energyProducedYesterday = data["H22"] / 100; // kWh
this.photovoltaicPower = data["PPV"]; // W
this.photovoltaicVoltage = data["VPV"] / 1000; //mV -> V
this.photovoltaicCurrent = this.photovoltaicPower / this.photovoltaicVoltage; //A
this.loadCurrent = data["IL"] ? data["IL"] / 1000 : 0; //mA -> A
this.loadOutputState = getStringBoolean(data["LOAD"]);
this.relayState = getStringBoolean(data["Relay"]);
this.offReasonMessage = OffReasonMessage[data["OR"]];
this.daySequenceNumber = data["HSDS"];
this.VEDirectData = data;
}
}
function getDeviceName(pid) {
if (deviceName[pid]) {
return deviceName[pid];
}
return "Unknow Victron Device";
}
function getDeviceFW(VEDirectData) {
const fw = VEDirectData["FW"] || VEDirectData["FWE"];
return typeof fw === "number" ? fw / 100 : -1;
}
function getStringBoolean(stringBoolean) {
return stringBoolean === "ON" || stringBoolean === "On";
}
function getNullableNumber(nullableNumber) {
return nullableNumber !== null && nullableNumber !== void 0 ? nullableNumber : 0;
}
class VEDirectPnP {
constructor({
VEDirectDevicesPath = "/dev/serial/by-id/",
customVEDirectDevicesPaths = []
} = {}) {
this.version = 0.10;
this.parameters = {
VEDirectDevicesPath,
customVEDirectDevicesPaths
};
this.listenersStack = [];
this.devicesVEDirectData = {};
this.serialPorts = [];
this.fluidModeReady = false;
this.init();
}
on(event, callback) {
const listener = (eventEmmited, eventData) => {
if (event === eventEmmited || event === "all") {
callback(eventData);
}
};
this.listenersStack.push(listener);
}
emitEvent(event, eventData) {
for (const listener of this.listenersStack) {
listener(event, Object.assign(Object.assign({}, eventData), {
eventName: event
}));
}
}
getVictronDeviceSN(VEDirectData, VEDirectDevicePath, deviceIndex) {
const deviceSerialNumber = VEDirectData["SER#"];
if (deviceSerialNumber) {
return deviceSerialNumber;
} else {
const vedirectSerialNumber = VEDirectDevicePath === null || VEDirectDevicePath === void 0 ? void 0 : VEDirectDevicePath.match(/Direct_cable_([^-]+)/)[1];
if (vedirectSerialNumber) {
return vedirectSerialNumber;
}
}
return `unknown_id_victron_device-${deviceIndex}`;
}
mapVictronDeviceData(devicesData) {
const devicesDataMapped = {};
for (const deviceSN in devicesData) {
const deviceData = devicesData[deviceSN];
if (!isNaN(deviceData["MPPT"])) {
devicesDataMapped[deviceSN] = new VEDirectPnP_MPPTDeviceData(deviceData);
} else if (!isNaN(deviceData["SOC"])) {
devicesDataMapped[deviceSN] = new VEDirectPnP_BMVDeviceData(deviceData);
} else {
devicesDataMapped[deviceSN] = new VEDirectPnP_UnsupportedDeviceData(deviceData);
}
}
return devicesDataMapped;
}
init() {
this.initVEDirectDataStreamFromAllDevices().then(() => {
this.emitEvent("stream-init", {
message: "VE.Direct devices data stream init"
});
}).catch(() => {
this.emitEvent("error", {
message: "Failed to get data from VE.Direct devices"
});
});
}
clean() {
this.devicesVEDirectData = {};
}
reset() {
this.destroy(() => {
this.clean();
this.init();
});
}
closeSerialPorts() {
return new Promise((resolve, reject) => {
if (this.serialPorts.length > 0) {
const serialPortClosePromises = this.serialPorts.map(serialPort => {
return new Promise((resolve, reject) => {
serialPort.close(error => {
if (error) {
console.error(error);
reject();
} else {
resolve();
}
});
});
});
Promise.all(serialPortClosePromises).then(() => {
this.serialPorts = [];
resolve();
}).catch(() => reject);
} else {
reject();
}
});
}
destroy(callback) {
if (this.serialPorts.length > 0) {
this.closeSerialPorts().then(() => {
this.emitEvent("stream-destroy", {
message: "VE.Direct devices data stream has been destroyed"
});
if (callback) callback();
}).catch(() => {
this.emitEvent("error", {
message: "Something went wrong trying to destroy VE.Direct devices data stream"
});
});
}
}
getDevicesData() {
return this.mapVictronDeviceData(this.devicesVEDirectData);
}
updateVEDirectDataDeviceData(VEDirectRawData, devicePath, deviceIndex) {
var _a;
const serialNumber = this.getVictronDeviceSN(VEDirectRawData, devicePath, deviceIndex);
if (!serialNumber) {
this.emitEvent("error", {
message: "Device does not have a valid serial number.",
dataDump: VEDirectRawData
});
return;
}
const previousVEDirectRawData = (_a = this.devicesVEDirectData[serialNumber]) !== null && _a !== void 0 ? _a : {};
this.devicesVEDirectData = Object.assign(Object.assign({}, this.devicesVEDirectData), {
[serialNumber]: Object.assign(Object.assign({}, previousVEDirectRawData), Object.assign(Object.assign({}, VEDirectRawData), {
dataTimeStamp: new Date().getTime()
}))
});
}
getVEDirectDevicesAvailable() {
return new Promise((resolve, reject) => {
child_process.exec(`ls ${this.parameters.VEDirectDevicesPath}`, (error, stdout, stderr) => {
const errorData = error || stderr;
if (errorData) {
this.emitEvent("error", {
message: "Failed to get available VE.Direct devices, try with customVEDirectDevicesPaths option.",
dataDump: errorData
});
reject([]);
return;
}
const rawConsoleResponse = stdout.split('\n');
const validVEDirectInterfaces = rawConsoleResponse.filter(deviceId => deviceId.indexOf("VE_Direct") !== -1);
const absoluteDevicesPath = validVEDirectInterfaces.map(device => {
const absoluteDevicePath = this.parameters.VEDirectDevicesPath + device;
this.emitEvent("interface-found", {
message: "Found VE.Direct serial port interface",
dataDump: absoluteDevicePath
});
return absoluteDevicePath;
});
resolve(absoluteDevicesPath);
});
});
}
initVEDirectDataStreamFromAllDevices() {
return new Promise((resolve, reject) => {
if (this.parameters.customVEDirectDevicesPaths && this.parameters.customVEDirectDevicesPaths.length > 0) {
const devicesPromises = this.parameters.customVEDirectDevicesPaths.map((devicePath, deviceIndex) => this.initDataStreamFromVEDirect(devicePath, deviceIndex));
Promise.all(devicesPromises).then(() => {
resolve();
}).catch(() => {
reject();
});
} else {
this.getVEDirectDevicesAvailable().then(devicesPathsFound => {
const devicesPromises = devicesPathsFound.map((devicePath, deviceIndex) => this.initDataStreamFromVEDirect(devicePath, deviceIndex));
Promise.all(devicesPromises).then(() => {
resolve();
});
}).catch(() => {
reject();
});
}
});
}
initDataStreamFromVEDirect(devicePath, deviceIndex) {
return new Promise((resolve, reject) => {
const port = new SerialPort__default["default"](devicePath, {
baudRate: 19200,
dataBits: 8,
parity: 'none'
}, err => {
if (err) {
this.emitEvent("error", {
message: `Device ${devicePath} serial port error`,
dataDump: err
});
this.devicesVEDirectData = {};
reject();
}
});
port.on("open", () => {
this.emitEvent("device-connection-open", {
message: "VE.Direct device connected through serial port",
dataDump: devicePath
});
});
port.on('error', err => {
this.emitEvent("device-connection-error", {
message: "VE.Direct device connection error through serial port",
dataDump: {
devicePath: devicePath,
errorDataDump: err
}
});
});
this.serialPorts.push(port);
const delimiter = new SerialPort__default["default"].parsers.Delimiter({
delimiter: Buffer.from([0x0d, 0x0a], 'hex'),
includeDelimiter: false
});
const VEDParser = new VEDirectParser();
port.pipe(delimiter).pipe(VEDParser);
VEDParser.on("data", VEDirectRawData => {
if (!this.devicesVEDirectData[this.getVictronDeviceSN(VEDirectRawData, devicePath, deviceIndex)]) {
resolve();
}
this.updateVEDirectDataDeviceData(VEDirectRawData, devicePath, deviceIndex);
});
});
}
}
module.exports = VEDirectPnP;