modbus-serial
Advanced tools
Comparing version 8.0.11 to 8.0.12
@@ -63,2 +63,3 @@ "use strict"; | ||
this._enronTables = options.enronTables; | ||
this._encapsulatedRTU = options.encapsulatedRTU; | ||
} | ||
@@ -101,2 +102,3 @@ | ||
this._enronTables = options.enronTables; | ||
this._encapsulatedRTU = options.encapsulatedRTU; | ||
} | ||
@@ -330,2 +332,3 @@ | ||
this._enronTables = options.enronTables; | ||
this._encapsulatedRTU = options.encapsulatedRTU; | ||
} | ||
@@ -388,3 +391,20 @@ | ||
*/ | ||
cl.connectRTUSocket = function(socket, next) { | ||
cl.connectRTUSocket = function(socket, options, next) { | ||
if (options) { | ||
this._enron = options.enron; | ||
this._enronTables = options.enronTables; | ||
this._encapsulatedRTU = options.encapsulatedRTU; | ||
} | ||
// check if we have options | ||
if (typeof next === "undefined" && typeof options === "function") { | ||
next = options; | ||
options = {}; | ||
} | ||
// check if we have options | ||
if (typeof options === "undefined") { | ||
options = {}; | ||
} | ||
const thisModbus = this; | ||
@@ -391,0 +411,0 @@ this._port = socket; |
428
index.js
@@ -354,187 +354,297 @@ "use strict"; | ||
// set locale helpers variables | ||
const transaction = modbus._transactions[modbus._port._transactionIdRead]; | ||
let next; | ||
// the _transactionIdRead can be missing, ignore wrong transaction it's | ||
if (!transaction) { | ||
return; | ||
} | ||
/* check enron options are valid | ||
*/ | ||
function validateEnron() { | ||
if (modbus._enron) { | ||
const example = { | ||
enronTables: { | ||
booleanRange: [1001, 1999], | ||
shortRange: [3001, 3999], | ||
longRange: [5001, 5999], | ||
floatRange: [7001, 7999] | ||
} | ||
}; | ||
if (transaction.responses) { | ||
/* Stash what we received */ | ||
transaction.responses.push(Uint8Array.prototype.slice.call(data)); | ||
if (typeof modbus._enronTables === "undefined" || | ||
modbus._enronTables.shortRange.length !== 2 || | ||
modbus._enronTables.shortRange[0] >= modbus._enronTables.shortRange[1]) { | ||
next(new Error("Enron table definition missing from options. Example: " + JSON.stringify(example))); | ||
return; | ||
} | ||
} | ||
} | ||
/* What do we do next? */ | ||
const next = function(err, res) { | ||
if (transaction.next) { | ||
/* Include request/response data if enabled */ | ||
if (transaction.request && transaction.responses) { | ||
if (err) { | ||
err.modbusRequest = transaction.request; | ||
err.modbusResponses = transaction.responses; | ||
} | ||
if (modbus._encapsulatedRTU === true) { | ||
let finished = false; | ||
let dataLength = data.readUInt8(2); | ||
let transaction = modbus._transactions[modbus._port._transactionIdRead]; | ||
modbus._port._transactionIdRead += 1; | ||
if (res) { | ||
res.request = transaction.request; | ||
res.responses = transaction.responses; | ||
} | ||
/* What do we do next? */ | ||
next = function(err, res) { | ||
if (transaction && transaction.next) { | ||
return transaction.next(err, res); | ||
} | ||
}; | ||
/* Pass the data on */ | ||
return transaction.next(err, res); | ||
} | ||
}; | ||
validateEnron(); | ||
/* cancel the timeout */ | ||
_cancelTimeout(transaction._timeoutHandle); | ||
transaction._timeoutHandle = undefined; | ||
let messageBuf; | ||
let offset = 0; | ||
/* check if the timeout fired */ | ||
if (transaction._timeoutFired === true) { | ||
// we have already called back with an error, so don't generate a new callback | ||
return; | ||
} | ||
while (!finished) { | ||
// do stuff | ||
messageBuf = Buffer.alloc(dataLength + 5); | ||
/* check incoming data | ||
*/ | ||
data.copy(messageBuf, 0, offset, offset + dataLength + 5); | ||
/* check minimal length | ||
*/ | ||
if (!transaction.lengthUnknown && data.length < 5) { | ||
error = "Data length error, expected " + | ||
transaction.nextLength + " got " + data.length; | ||
next(new Error(error)); | ||
return; | ||
} | ||
const crcIn = messageBuf.readUInt16LE(messageBuf.length - 2); | ||
/* check message CRC | ||
* if CRC is bad raise an error | ||
*/ | ||
const crcIn = data.readUInt16LE(data.length - 2); | ||
if (crcIn !== crc16(data.slice(0, -2))) { | ||
error = "CRC error"; | ||
next(new Error(error)); | ||
return; | ||
} | ||
if (crcIn !== crc16(messageBuf.slice(0, -2))) { | ||
error = "CRC error"; | ||
return; | ||
} | ||
// if crc is OK, read address and function code | ||
const address = data.readUInt8(0); | ||
const code = data.readUInt8(1); | ||
// if crc is OK, read address and function code | ||
const address = messageBuf.readUInt8(0); | ||
const code = messageBuf.readUInt8(1); | ||
/* check for modbus exception | ||
*/ | ||
if (data.length >= 5 && | ||
code === (0x80 | transaction.nextCode)) { | ||
const errorCode = data.readUInt8(2); | ||
if (transaction.next) { | ||
error = new Error("Modbus exception " + errorCode + ": " + (modbusErrorMessages[errorCode] || "Unknown error")); | ||
error.modbusCode = errorCode; | ||
next(error); | ||
/* check for modbus exception | ||
*/ | ||
if (messageBuf.length >= 5 && | ||
code === (0x80 | code)) { | ||
const errorCode = messageBuf.readUInt8(2); | ||
error = new Error("Modbus exception " + errorCode + ": " + (modbusErrorMessages[errorCode] || "Unknown error")); | ||
error.modbusCode = errorCode; | ||
return; | ||
} | ||
switch (code) { | ||
case 1: | ||
case 2: | ||
// Read Coil Status (FC=01) | ||
// Read Input Status (FC=02) | ||
_readFC2(messageBuf, next); | ||
break; | ||
case 3: | ||
case 4: | ||
// Read Input Registers (FC=04) | ||
// Read Holding Registers (FC=03) | ||
if (modbus._enron && !(address >= modbus._enronTables.shortRange[0] && address <= modbus._enronTables.shortRange[1])) { | ||
_readFC3or4Enron(messageBuf, next); | ||
} else { | ||
_readFC3or4(messageBuf, next); | ||
} | ||
break; | ||
case 5: | ||
// Force Single Coil | ||
_readFC5(messageBuf, next); | ||
break; | ||
case 6: | ||
// Preset Single Register | ||
if (modbus._enron && !(address >= modbus._enronTables.shortRange[0] && address <= modbus._enronTables.shortRange[1])) { | ||
_readFC6Enron(messageBuf, next); | ||
} else { | ||
_readFC6(messageBuf, next); | ||
} | ||
break; | ||
case 15: | ||
case 16: | ||
// Force Multiple Coils | ||
// Preset Multiple Registers | ||
_readFC16(messageBuf, next); | ||
break; | ||
case 17: | ||
_readFC17(messageBuf, next); | ||
break; | ||
case 20: | ||
_readFC20(messageBuf, transaction.next); | ||
break; | ||
case 43: | ||
// read device identification | ||
_readFC43(messageBuf, modbus, next); | ||
} | ||
// move on to next | ||
offset += 5 + dataLength; | ||
if (offset + 2 > data.length) { | ||
finished = true; | ||
} else { | ||
dataLength = data.readUInt8(offset + 2); | ||
transaction = modbus._transactions[modbus._port._transactionIdRead]; | ||
modbus._port._transactionIdRead += 1; | ||
} | ||
} | ||
return; | ||
} | ||
} else { | ||
// set locale helpers variables | ||
const transaction = modbus._transactions[modbus._port._transactionIdRead]; | ||
/* check enron options are valid | ||
*/ | ||
if (modbus._enron) { | ||
const example = { | ||
enronTables: { | ||
booleanRange: [1001, 1999], | ||
shortRange: [3001, 3999], | ||
longRange: [5001, 5999], | ||
floatRange: [7001, 7999] | ||
// the _transactionIdRead can be missing, ignore wrong transaction it's | ||
if (!transaction) { | ||
return; | ||
} | ||
if (transaction.responses) { | ||
/* Stash what we received */ | ||
transaction.responses.push(Uint8Array.prototype.slice.call(data)); | ||
} | ||
/* What do we do next? */ | ||
next = function(err, res) { | ||
if (transaction.next) { | ||
/* Include request/response data if enabled */ | ||
if (transaction.request && transaction.responses) { | ||
if (err) { | ||
err.modbusRequest = transaction.request; | ||
err.modbusResponses = transaction.responses; | ||
} | ||
if (res) { | ||
res.request = transaction.request; | ||
res.responses = transaction.responses; | ||
} | ||
} | ||
/* Pass the data on */ | ||
return transaction.next(err, res); | ||
} | ||
}; | ||
if (typeof modbus._enronTables === "undefined" || | ||
modbus._enronTables.shortRange.length !== 2 || | ||
modbus._enronTables.shortRange[0] >= modbus._enronTables.shortRange[1]) { | ||
next(new Error("Enron table definition missing from options. Example: " + JSON.stringify(example))); | ||
validateEnron(); | ||
/* cancel the timeout */ | ||
_cancelTimeout(transaction._timeoutHandle); | ||
transaction._timeoutHandle = undefined; | ||
/* check if the timeout fired */ | ||
if (transaction._timeoutFired === true) { | ||
// we have already called back with an error, so don't generate a new callback | ||
return; | ||
} | ||
} | ||
/* check message length | ||
* if we do not expect this data | ||
* raise an error | ||
*/ | ||
if (!transaction.lengthUnknown && data.length !== transaction.nextLength) { | ||
error = "Data length error, expected " + | ||
transaction.nextLength + " got " + data.length; | ||
next(new Error(error)); | ||
return; | ||
} | ||
/* check incoming data | ||
*/ | ||
/* check message address | ||
* if we do not expect this message | ||
* raise an error | ||
*/ | ||
if (address !== transaction.nextAddress) { | ||
error = "Unexpected data error, expected " + | ||
"address " + transaction.nextAddress + " got " + address; | ||
if (transaction.next) | ||
/* check minimal length | ||
*/ | ||
if (!transaction.lengthUnknown && data.length < 5) { | ||
error = "Data length error, expected " + | ||
transaction.nextLength + " got " + data.length; | ||
next(new Error(error)); | ||
return; | ||
} | ||
return; | ||
} | ||
/* check message code | ||
* if we do not expect this message | ||
* raise an error | ||
*/ | ||
if (code !== transaction.nextCode) { | ||
error = "Unexpected data error, expected " + | ||
"code " + transaction.nextCode + " got " + code; | ||
if (transaction.next) | ||
/* check message CRC | ||
* if CRC is bad raise an error | ||
*/ | ||
const crcIn = data.readUInt16LE(data.length - 2); | ||
if (crcIn !== crc16(data.slice(0, -2))) { | ||
error = "CRC error"; | ||
next(new Error(error)); | ||
return; | ||
} | ||
return; | ||
} | ||
/* parse incoming data | ||
*/ | ||
// if crc is OK, read address and function code | ||
const address = data.readUInt8(0); | ||
const code = data.readUInt8(1); | ||
switch (code) { | ||
case 1: | ||
case 2: | ||
// Read Coil Status (FC=01) | ||
// Read Input Status (FC=02) | ||
_readFC2(data, next); | ||
break; | ||
case 3: | ||
case 4: | ||
// Read Input Registers (FC=04) | ||
// Read Holding Registers (FC=03) | ||
if (modbus._enron && !(transaction.nextDataAddress >= modbus._enronTables.shortRange[0] && transaction.nextDataAddress <= modbus._enronTables.shortRange[1])) { | ||
_readFC3or4Enron(data, next); | ||
} else { | ||
_readFC3or4(data, next); | ||
/* check for modbus exception | ||
*/ | ||
if (data.length >= 5 && | ||
code === (0x80 | transaction.nextCode)) { | ||
const errorCode = data.readUInt8(2); | ||
if (transaction.next) { | ||
error = new Error("Modbus exception " + errorCode + ": " + (modbusErrorMessages[errorCode] || "Unknown error")); | ||
error.modbusCode = errorCode; | ||
next(error); | ||
} | ||
break; | ||
case 5: | ||
// Force Single Coil | ||
_readFC5(data, next); | ||
break; | ||
case 6: | ||
// Preset Single Register | ||
if (modbus._enron && !(transaction.nextDataAddress >= modbus._enronTables.shortRange[0] && transaction.nextDataAddress <= modbus._enronTables.shortRange[1])) { | ||
_readFC6Enron(data, next); | ||
} else { | ||
_readFC6(data, next); | ||
} | ||
break; | ||
case 15: | ||
case 16: | ||
// Force Multiple Coils | ||
// Preset Multiple Registers | ||
_readFC16(data, next); | ||
break; | ||
case 17: | ||
_readFC17(data, next); | ||
break; | ||
case 20: | ||
_readFC20(data, transaction.next); | ||
break; | ||
case 43: | ||
// read device identification | ||
_readFC43(data, modbus, next); | ||
return; | ||
} | ||
/* check message length | ||
* if we do not expect this data | ||
* raise an error | ||
*/ | ||
if (!transaction.lengthUnknown && data.length !== transaction.nextLength) { | ||
error = "Data length error, expected " + | ||
transaction.nextLength + " got " + data.length; | ||
next(new Error(error)); | ||
return; | ||
} | ||
/* check message address | ||
* if we do not expect this message | ||
* raise an error | ||
*/ | ||
if (address !== transaction.nextAddress) { | ||
error = "Unexpected data error, expected " + | ||
"address " + transaction.nextAddress + " got " + address; | ||
if (transaction.next) | ||
next(new Error(error)); | ||
return; | ||
} | ||
/* check message code | ||
* if we do not expect this message | ||
* raise an error | ||
*/ | ||
if (code !== transaction.nextCode) { | ||
error = "Unexpected data error, expected " + | ||
"code " + transaction.nextCode + " got " + code; | ||
if (transaction.next) | ||
next(new Error(error)); | ||
return; | ||
} | ||
/* parse incoming data | ||
*/ | ||
switch (code) { | ||
case 1: | ||
case 2: | ||
// Read Coil Status (FC=01) | ||
// Read Input Status (FC=02) | ||
_readFC2(data, next); | ||
break; | ||
case 3: | ||
case 4: | ||
// Read Input Registers (FC=04) | ||
// Read Holding Registers (FC=03) | ||
if (modbus._enron && !(transaction.nextDataAddress >= modbus._enronTables.shortRange[0] && transaction.nextDataAddress <= modbus._enronTables.shortRange[1])) { | ||
_readFC3or4Enron(data, next); | ||
} else { | ||
_readFC3or4(data, next); | ||
} | ||
break; | ||
case 5: | ||
// Force Single Coil | ||
_readFC5(data, next); | ||
break; | ||
case 6: | ||
// Preset Single Register | ||
if (modbus._enron && !(transaction.nextDataAddress >= modbus._enronTables.shortRange[0] && transaction.nextDataAddress <= modbus._enronTables.shortRange[1])) { | ||
_readFC6Enron(data, next); | ||
} else { | ||
_readFC6(data, next); | ||
} | ||
break; | ||
case 15: | ||
case 16: | ||
// Force Multiple Coils | ||
// Preset Multiple Registers | ||
_readFC16(data, next); | ||
break; | ||
case 17: | ||
_readFC17(data, next); | ||
break; | ||
case 20: | ||
_readFC20(data, transaction.next); | ||
break; | ||
case 43: | ||
// read device identification | ||
_readFC43(data, modbus, next); | ||
} | ||
} | ||
@@ -774,3 +884,2 @@ } | ||
} | ||
// set state variables | ||
@@ -781,3 +890,3 @@ this._transactions[this._port._transactionIdWrite] = { | ||
nextCode: code, | ||
nextLength: 3 + (valueSize * length) + 2, | ||
nextLength: 3 + (valueSize * length) + 2, // response size: unitID, FC, length, data, CRC | ||
next: next | ||
@@ -799,2 +908,4 @@ }; | ||
_writeBufferToPort.call(this, buf, this._port._transactionIdWrite); | ||
this._port._transactionIdWrite += 1; | ||
} | ||
@@ -1179,4 +1290,5 @@ | ||
module.exports.Server = require("./servers/server"); | ||
module.exports.ServerTCP = require("./servers/servertcp"); | ||
module.exports.ServerSerial = require("./servers/serverserial"); | ||
module.exports.default = module.exports; |
@@ -48,4 +48,4 @@ import { Socket } from 'net'; | ||
linkTelnet(socket: Socket, options: TelnetPortOptions): Promise<void>; | ||
connectRTUSocket(socket: Socket, next: Function): void; | ||
connectRTUSocket(socket: Socket): Promise<void>; | ||
connectRTUSocket(socket: Socket, options: SocketOptions, next: Function): void; | ||
connectRTUSocket(socket: Socket, options: SocketOptions): Promise<void>; | ||
@@ -156,2 +156,5 @@ // Promise API | ||
export interface SocketOptions { | ||
} | ||
export interface TelnetPortOptions { | ||
@@ -158,0 +161,0 @@ port?: number; |
{ | ||
"name": "modbus-serial", | ||
"version": "8.0.11", | ||
"version": "8.0.12", | ||
"description": "A pure JavaScript implemetation of MODBUS-RTU (Serial and TCP) for NodeJS.", | ||
@@ -44,4 +44,4 @@ "main": "index.js", | ||
"debug": "^4.1.1", | ||
"serialport": "^10.4.0" | ||
"serialport": "^11.0.0" | ||
} | ||
} |
@@ -64,10 +64,11 @@ # modbus-serial | ||
| FC2 "Read Input Status" | `readDiscreteInputs(addr, arg)` | | ||
| FC3 "Read Holding Registers" | `readHoldingRegisters(addr, len) ` | | ||
| FC3 "Read Holding Registers" | `readHoldingRegisters(addr, len)`, `readRegistersEnron(addr, len)`* | | ||
| FC4 "Read Input Registers" | `readInputRegisters(addr, len) ` | | ||
| FC5 "Force Single Coil" | `writeCoil(coil, binary) //NOT setCoil` | | ||
| FC6 "Preset Single Register" | `writeRegister(addr, value)` | | ||
| FC15 "Force Multiple Coil" | `writeCoils(addr, valueAry)` | | ||
| FC16 "Preset Multiple Registers" | `writeRegisters(addr, valueAry)` | | ||
| FC15 "Force Multiple Coil" | `writeCoils(addr, valueAry)` | | ||
| FC16 "Preset Multiple Registers" | `writeRegisters(addr, valueAry)`, `writeRegistersEnron(addr, valueAry)`* | | ||
| FC43/14 "Read Device Identification" (supported ports: TCP, RTU) | `readDeviceIdentification(id, obj)` | | ||
\* See examples/server_enron.js for enron configuration example. | ||
###### Client Serial: | ||
@@ -88,5 +89,6 @@ | ||
* modbus-TCP (ServerTCP): Over TCP/IP line. | ||
* modbus-TCP ServerTCP(): Encapsulated TCP/IP. | ||
* modbus-RTU Server(): RTU over TCP/IP Socket. | ||
* modbus-Serial ServerSerial(): Over serial. | ||
#### Examples | ||
@@ -232,3 +234,3 @@ | ||
---- | ||
###### ModbusTCP Server | ||
###### Modbus TCP Server | ||
``` javascript | ||
@@ -289,2 +291,87 @@ // create an empty modbus client | ||
---- | ||
###### Modbus Serial Server | ||
``` javascript | ||
const ModbusRTU = require(".."); | ||
const holdingRegisters = {}; | ||
const coils = {}; | ||
const inputRegisters = {}; | ||
const discreteInputs = {}; | ||
const vector = { | ||
getInputRegister: function(addr) { | ||
return inputRegisters[addr]; | ||
}, | ||
getMultipleInputRegisters: function(startAddr, length) { | ||
const values = []; | ||
for (let i = 0; i < length; i++) { | ||
values[i] = inputRegisters[startAddr + i]; | ||
} | ||
return values; | ||
}, | ||
getDiscreteInput: function(addr) { | ||
return discreteInputs[addr]; | ||
}, | ||
getHoldingRegister: function(addr) { | ||
return holdingRegisters[addr]; | ||
}, | ||
setRegister: function(addr, value) { | ||
holdingRegisters[addr] = value; | ||
return; | ||
}, | ||
getMultipleHoldingRegisters: function(startAddr, length) { | ||
const values = []; | ||
for (let i = 0; i < length; i++) { | ||
values[i] = holdingRegisters[startAddr + i]; | ||
} | ||
return values; | ||
}, | ||
getCoil: function(addr) { | ||
return coils[addr]; | ||
}, | ||
setCoil: function(addr, value) { | ||
coils[addr] = value; | ||
return coils[addr]; | ||
}, | ||
readDeviceIdentification: function() { | ||
return { | ||
0x00: "MyVendorName", | ||
0x01: "MyProductCode", | ||
0x02: "MyMajorMinorRevision", | ||
0x05: "MyModelName", | ||
0x97: "MyExtendedObject1", | ||
0xab: "MyExtendedObject2" | ||
}; | ||
} | ||
}; | ||
// set the server to answer for modbus requests | ||
const serverSerial = new ModbusRTU.ServerSerial( | ||
vector, | ||
{ | ||
port: "/tmp/ttyp0", | ||
debug: true, | ||
unitID: 1 | ||
// enron: true, | ||
// enronTables: { | ||
// booleanRange: [1001, 1999], | ||
// shortRange: [3001, 3999], | ||
// longRange: [5001, 5999], | ||
// floatRange: [7001, 7999] | ||
// } | ||
}, | ||
{ | ||
baudRate: 9600, | ||
dataBits: 8, | ||
stopBits: 1, | ||
parity: "even" | ||
} | ||
); | ||
serverSerial.on("error", function(err) { | ||
// Handle socket error if needed, can be ignored | ||
console.error(err); | ||
}); | ||
``` | ||
---- | ||
###### Read and Write Modbus ASCII | ||
@@ -291,0 +378,0 @@ ``` javascript |
@@ -71,2 +71,5 @@ "use strict"; | ||
debug: true | ||
}, | ||
{ | ||
baudRate: 9600 | ||
}); | ||
@@ -262,2 +265,5 @@ }); | ||
unitID: 4 | ||
}, | ||
{ | ||
baudRate: 9600 | ||
}); | ||
@@ -323,2 +329,5 @@ }); | ||
unitID: 4 | ||
}, | ||
{ | ||
baudRate: 9600 | ||
}); | ||
@@ -325,0 +334,0 @@ }); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
450649
80
11643
418
1
12
+ Added@serialport/bindings-cpp@11.0.3(transitive)
+ Added@serialport/parser-byte-length@11.0.1(transitive)
+ Added@serialport/parser-cctalk@11.0.1(transitive)
+ Added@serialport/parser-delimiter@11.0.011.0.1(transitive)
+ Added@serialport/parser-inter-byte-timeout@11.0.1(transitive)
+ Added@serialport/parser-packet-length@11.0.1(transitive)
+ Added@serialport/parser-readline@11.0.011.0.1(transitive)
+ Added@serialport/parser-ready@11.0.1(transitive)
+ Added@serialport/parser-regex@11.0.1(transitive)
+ Added@serialport/parser-slip-encoder@11.0.1(transitive)
+ Added@serialport/parser-spacepacket@11.0.1(transitive)
+ Added@serialport/stream@11.0.1(transitive)
+ Addeddebug@4.3.4(transitive)
+ Addedms@2.1.2(transitive)
+ Addednode-addon-api@6.1.0(transitive)
+ Addednode-gyp-build@4.6.0(transitive)
+ Addedserialport@11.0.1(transitive)
- Removed@serialport/bindings-cpp@10.8.0(transitive)
- Removed@serialport/parser-byte-length@10.5.0(transitive)
- Removed@serialport/parser-cctalk@10.5.0(transitive)
- Removed@serialport/parser-delimiter@10.5.0(transitive)
- Removed@serialport/parser-inter-byte-timeout@10.5.0(transitive)
- Removed@serialport/parser-packet-length@10.5.0(transitive)
- Removed@serialport/parser-readline@10.5.0(transitive)
- Removed@serialport/parser-ready@10.5.0(transitive)
- Removed@serialport/parser-regex@10.5.0(transitive)
- Removed@serialport/parser-slip-encoder@10.5.0(transitive)
- Removed@serialport/parser-spacepacket@10.5.0(transitive)
- Removed@serialport/stream@10.5.0(transitive)
- Removednode-addon-api@5.1.0(transitive)
- Removednode-gyp-build@4.8.3(transitive)
- Removedserialport@10.5.0(transitive)
Updatedserialport@^11.0.0