njs-modbus 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +121 -14
- package/dist/index.d.ts +7 -0
- package/dist/index.mjs +121 -14
- package/dist/src/layers/application/ascii-application-layer.d.ts +1 -0
- package/dist/src/layers/application/rtu-application-layer.d.ts +1 -0
- package/dist/src/layers/application/tcp-application-layer.d.ts +1 -0
- package/dist/src/master/master.d.ts +2 -0
- package/dist/src/slave/slave.d.ts +2 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -423,6 +423,9 @@ class SerialPhysicalLayer extends AbstractPhysicalLayer {
|
|
|
423
423
|
});
|
|
424
424
|
}
|
|
425
425
|
destroy() {
|
|
426
|
+
if (this._destroyed) {
|
|
427
|
+
return Promise.resolve();
|
|
428
|
+
}
|
|
426
429
|
this._destroyed = true;
|
|
427
430
|
return this.close().then(() => {
|
|
428
431
|
this.removeAllListeners();
|
|
@@ -562,6 +565,9 @@ class TcpClientPhysicalLayer extends AbstractPhysicalLayer {
|
|
|
562
565
|
});
|
|
563
566
|
}
|
|
564
567
|
destroy() {
|
|
568
|
+
if (this._destroyed) {
|
|
569
|
+
return Promise.resolve();
|
|
570
|
+
}
|
|
565
571
|
this._destroyed = true;
|
|
566
572
|
return this.close().then(() => {
|
|
567
573
|
this.removeAllListeners();
|
|
@@ -711,10 +717,18 @@ class TcpServerPhysicalLayer extends AbstractPhysicalLayer {
|
|
|
711
717
|
for (const [socket] of this._connections) {
|
|
712
718
|
socket.destroy();
|
|
713
719
|
}
|
|
714
|
-
|
|
720
|
+
try {
|
|
721
|
+
server.close();
|
|
722
|
+
}
|
|
723
|
+
catch (_a) {
|
|
724
|
+
resolve();
|
|
725
|
+
}
|
|
715
726
|
});
|
|
716
727
|
}
|
|
717
728
|
destroy() {
|
|
729
|
+
if (this._destroyed) {
|
|
730
|
+
return Promise.resolve();
|
|
731
|
+
}
|
|
718
732
|
this._destroyed = true;
|
|
719
733
|
return this.close().then(() => {
|
|
720
734
|
this.removeAllListeners();
|
|
@@ -945,6 +959,9 @@ class UdpPhysicalLayer extends AbstractPhysicalLayer {
|
|
|
945
959
|
});
|
|
946
960
|
}
|
|
947
961
|
destroy() {
|
|
962
|
+
if (this._destroyed) {
|
|
963
|
+
return Promise.resolve();
|
|
964
|
+
}
|
|
948
965
|
this._destroyed = true;
|
|
949
966
|
return this.close().then(() => {
|
|
950
967
|
this.removeAllListeners();
|
|
@@ -1024,6 +1041,12 @@ class RtuApplicationLayer extends AbstractApplicationLayer {
|
|
|
1024
1041
|
writable: true,
|
|
1025
1042
|
value: void 0
|
|
1026
1043
|
});
|
|
1044
|
+
Object.defineProperty(this, "_destroyed", {
|
|
1045
|
+
enumerable: true,
|
|
1046
|
+
configurable: true,
|
|
1047
|
+
writable: true,
|
|
1048
|
+
value: false
|
|
1049
|
+
});
|
|
1027
1050
|
const { intervalBetweenFrames, interCharTimeout } = options;
|
|
1028
1051
|
let threePointFiveT = 0;
|
|
1029
1052
|
let onePointFiveT = 0;
|
|
@@ -1274,14 +1297,20 @@ class RtuApplicationLayer extends AbstractApplicationLayer {
|
|
|
1274
1297
|
return buffer;
|
|
1275
1298
|
}
|
|
1276
1299
|
destroy() {
|
|
1300
|
+
if (this._destroyed) {
|
|
1301
|
+
return;
|
|
1302
|
+
}
|
|
1303
|
+
this._destroyed = true;
|
|
1277
1304
|
this.removeAllListeners();
|
|
1278
1305
|
for (const removeListener of this._removeAllListeners) {
|
|
1279
1306
|
removeListener();
|
|
1280
1307
|
}
|
|
1308
|
+
this._removeAllListeners.length = 0;
|
|
1281
1309
|
for (const state of this._states.values()) {
|
|
1282
1310
|
this.clearStateTimers(state);
|
|
1283
1311
|
}
|
|
1284
1312
|
this._states.clear();
|
|
1313
|
+
this._customFunctionCodes.clear();
|
|
1285
1314
|
}
|
|
1286
1315
|
}
|
|
1287
1316
|
|
|
@@ -1334,6 +1363,12 @@ class AsciiApplicationLayer extends AbstractApplicationLayer {
|
|
|
1334
1363
|
writable: true,
|
|
1335
1364
|
value: []
|
|
1336
1365
|
});
|
|
1366
|
+
Object.defineProperty(this, "_destroyed", {
|
|
1367
|
+
enumerable: true,
|
|
1368
|
+
configurable: true,
|
|
1369
|
+
writable: true,
|
|
1370
|
+
value: false
|
|
1371
|
+
});
|
|
1337
1372
|
this.lenientHex = (_a = options.lenientHex) !== null && _a !== void 0 ? _a : false;
|
|
1338
1373
|
const lenientHex = this.lenientHex;
|
|
1339
1374
|
const isHexChar = (value) => {
|
|
@@ -1471,10 +1506,15 @@ class AsciiApplicationLayer extends AbstractApplicationLayer {
|
|
|
1471
1506
|
return out;
|
|
1472
1507
|
}
|
|
1473
1508
|
destroy() {
|
|
1509
|
+
if (this._destroyed) {
|
|
1510
|
+
return;
|
|
1511
|
+
}
|
|
1512
|
+
this._destroyed = true;
|
|
1474
1513
|
this.removeAllListeners();
|
|
1475
1514
|
for (const removeListener of this._removeAllListeners) {
|
|
1476
1515
|
removeListener();
|
|
1477
1516
|
}
|
|
1517
|
+
this._removeAllListeners.length = 0;
|
|
1478
1518
|
this._states.clear();
|
|
1479
1519
|
}
|
|
1480
1520
|
}
|
|
@@ -1508,6 +1548,12 @@ class TcpApplicationLayer extends AbstractApplicationLayer {
|
|
|
1508
1548
|
writable: true,
|
|
1509
1549
|
value: []
|
|
1510
1550
|
});
|
|
1551
|
+
Object.defineProperty(this, "_destroyed", {
|
|
1552
|
+
enumerable: true,
|
|
1553
|
+
configurable: true,
|
|
1554
|
+
writable: true,
|
|
1555
|
+
value: false
|
|
1556
|
+
});
|
|
1511
1557
|
const handleData = (data, response, connection) => {
|
|
1512
1558
|
var _a;
|
|
1513
1559
|
let buffer = (_a = this._buffers.get(connection.id)) !== null && _a !== void 0 ? _a : EMPTY_BUFFER;
|
|
@@ -1590,10 +1636,15 @@ class TcpApplicationLayer extends AbstractApplicationLayer {
|
|
|
1590
1636
|
return buffer;
|
|
1591
1637
|
}
|
|
1592
1638
|
destroy() {
|
|
1639
|
+
if (this._destroyed) {
|
|
1640
|
+
return;
|
|
1641
|
+
}
|
|
1642
|
+
this._destroyed = true;
|
|
1593
1643
|
this.removeAllListeners();
|
|
1594
1644
|
for (const removeListener of this._removeAllListeners) {
|
|
1595
1645
|
removeListener();
|
|
1596
1646
|
}
|
|
1647
|
+
this._removeAllListeners.length = 0;
|
|
1597
1648
|
this._buffers.clear();
|
|
1598
1649
|
}
|
|
1599
1650
|
}
|
|
@@ -1704,7 +1755,7 @@ class ModbusMaster extends EventEmitter {
|
|
|
1704
1755
|
return this.physicalLayer.isOpen;
|
|
1705
1756
|
}
|
|
1706
1757
|
get destroyed() {
|
|
1707
|
-
return this.physicalLayer.destroyed;
|
|
1758
|
+
return this._cleanLevel === 'destroy' || this.physicalLayer.destroyed;
|
|
1708
1759
|
}
|
|
1709
1760
|
constructor(applicationLayer, physicalLayer, options = {}) {
|
|
1710
1761
|
var _a, _b;
|
|
@@ -1751,6 +1802,12 @@ class ModbusMaster extends EventEmitter {
|
|
|
1751
1802
|
writable: true,
|
|
1752
1803
|
value: false
|
|
1753
1804
|
});
|
|
1805
|
+
Object.defineProperty(this, "_cleanLevel", {
|
|
1806
|
+
enumerable: true,
|
|
1807
|
+
configurable: true,
|
|
1808
|
+
writable: true,
|
|
1809
|
+
value: 'none'
|
|
1810
|
+
});
|
|
1754
1811
|
Object.defineProperty(this, "timeout", {
|
|
1755
1812
|
enumerable: true,
|
|
1756
1813
|
configurable: true,
|
|
@@ -2164,26 +2221,44 @@ class ModbusMaster extends EventEmitter {
|
|
|
2164
2221
|
}
|
|
2165
2222
|
});
|
|
2166
2223
|
}
|
|
2224
|
+
_clean(level) {
|
|
2225
|
+
if (this._cleanLevel === 'destroy') {
|
|
2226
|
+
return;
|
|
2227
|
+
}
|
|
2228
|
+
if (this._cleanLevel === 'close' && level === 'close') {
|
|
2229
|
+
return;
|
|
2230
|
+
}
|
|
2231
|
+
const errorCode = level === 'destroy' ? ModbusErrorCode.MASTER_DESTROYED : ModbusErrorCode.MASTER_CLOSED;
|
|
2232
|
+
const message = level === 'destroy' ? 'Master destroyed' : 'Master closed';
|
|
2233
|
+
this._closed = true;
|
|
2234
|
+
const queued = this._queue.splice(0);
|
|
2235
|
+
for (const item of queued) {
|
|
2236
|
+
item.cancel(new ModbusError(errorCode, message));
|
|
2237
|
+
}
|
|
2238
|
+
this._masterSession.stopAll(new ModbusError(errorCode, message));
|
|
2239
|
+
this._cleanLevel = level;
|
|
2240
|
+
}
|
|
2167
2241
|
open(...args) {
|
|
2242
|
+
if (this._cleanLevel === 'destroy') {
|
|
2243
|
+
return Promise.reject(new ModbusError(ModbusErrorCode.PORT_DESTROYED, 'Master is destroyed'));
|
|
2244
|
+
}
|
|
2245
|
+
this._cleanLevel = 'none';
|
|
2168
2246
|
this._closed = false;
|
|
2247
|
+
this._nextTid = 1;
|
|
2169
2248
|
return this.physicalLayer.open(...args);
|
|
2170
2249
|
}
|
|
2171
2250
|
close() {
|
|
2172
|
-
this.
|
|
2173
|
-
|
|
2174
|
-
for (const item of queued) {
|
|
2175
|
-
item.cancel(new ModbusError(ModbusErrorCode.MASTER_CLOSED, 'Master closed'));
|
|
2251
|
+
if (this._cleanLevel === 'destroy') {
|
|
2252
|
+
return Promise.resolve();
|
|
2176
2253
|
}
|
|
2177
|
-
this.
|
|
2254
|
+
this._clean('close');
|
|
2178
2255
|
return this.physicalLayer.close();
|
|
2179
2256
|
}
|
|
2180
2257
|
destroy() {
|
|
2181
|
-
this.
|
|
2182
|
-
|
|
2183
|
-
for (const item of queued) {
|
|
2184
|
-
item.cancel(new ModbusError(ModbusErrorCode.MASTER_DESTROYED, 'Master destroyed'));
|
|
2258
|
+
if (this._cleanLevel === 'destroy') {
|
|
2259
|
+
return Promise.resolve();
|
|
2185
2260
|
}
|
|
2186
|
-
this.
|
|
2261
|
+
this._clean('destroy');
|
|
2187
2262
|
this.removeAllListeners();
|
|
2188
2263
|
this.applicationLayer.destroy();
|
|
2189
2264
|
return this.physicalLayer.destroy();
|
|
@@ -2195,7 +2270,7 @@ class ModbusSlave extends EventEmitter {
|
|
|
2195
2270
|
return this.physicalLayer.isOpen;
|
|
2196
2271
|
}
|
|
2197
2272
|
get destroyed() {
|
|
2198
|
-
return this.physicalLayer.destroyed;
|
|
2273
|
+
return this._cleanLevel === 'destroy' || this.physicalLayer.destroyed;
|
|
2199
2274
|
}
|
|
2200
2275
|
constructor(applicationLayer, physicalLayer, options = {}) {
|
|
2201
2276
|
var _a;
|
|
@@ -2242,6 +2317,12 @@ class ModbusSlave extends EventEmitter {
|
|
|
2242
2317
|
writable: true,
|
|
2243
2318
|
value: new Map()
|
|
2244
2319
|
});
|
|
2320
|
+
Object.defineProperty(this, "_cleanLevel", {
|
|
2321
|
+
enumerable: true,
|
|
2322
|
+
configurable: true,
|
|
2323
|
+
writable: true,
|
|
2324
|
+
value: 'none'
|
|
2325
|
+
});
|
|
2245
2326
|
this.concurrent = (_a = options.concurrent) !== null && _a !== void 0 ? _a : false;
|
|
2246
2327
|
if (this.concurrent && this.applicationLayer.PROTOCOL !== 'TCP') {
|
|
2247
2328
|
throw new ModbusError(ModbusErrorCode.CONCURRENT_NOT_TCP, 'concurrent mode requires a Modbus TCP application layer');
|
|
@@ -2974,14 +3055,40 @@ class ModbusSlave extends EventEmitter {
|
|
|
2974
3055
|
this._customFunctionCodes.delete(fc);
|
|
2975
3056
|
this.applicationLayer.removeCustomFunctionCode(fc);
|
|
2976
3057
|
}
|
|
3058
|
+
_clean(level) {
|
|
3059
|
+
if (this._cleanLevel === 'destroy') {
|
|
3060
|
+
return;
|
|
3061
|
+
}
|
|
3062
|
+
if (this._cleanLevel === 'close' && level === 'close') {
|
|
3063
|
+
return;
|
|
3064
|
+
}
|
|
3065
|
+
for (const q of this._queues.values()) {
|
|
3066
|
+
q.items.length = 0;
|
|
3067
|
+
}
|
|
3068
|
+
this._queues.clear();
|
|
3069
|
+
this._locks.clear();
|
|
3070
|
+
if (level === 'destroy') {
|
|
3071
|
+
this._customFunctionCodes.clear();
|
|
3072
|
+
this.models.clear();
|
|
3073
|
+
}
|
|
3074
|
+
this._cleanLevel = level;
|
|
3075
|
+
}
|
|
2977
3076
|
open(...args) {
|
|
3077
|
+
this._cleanLevel = 'none';
|
|
2978
3078
|
return this.physicalLayer.open(...args);
|
|
2979
3079
|
}
|
|
2980
3080
|
close() {
|
|
3081
|
+
if (this._cleanLevel === 'destroy') {
|
|
3082
|
+
return Promise.resolve();
|
|
3083
|
+
}
|
|
3084
|
+
this._clean('close');
|
|
2981
3085
|
return this.physicalLayer.close();
|
|
2982
3086
|
}
|
|
2983
3087
|
destroy() {
|
|
2984
|
-
this.
|
|
3088
|
+
if (this._cleanLevel === 'destroy') {
|
|
3089
|
+
return Promise.resolve();
|
|
3090
|
+
}
|
|
3091
|
+
this._clean('destroy');
|
|
2985
3092
|
this.removeAllListeners();
|
|
2986
3093
|
this.applicationLayer.destroy();
|
|
2987
3094
|
return this.physicalLayer.destroy();
|
package/dist/index.d.ts
CHANGED
|
@@ -313,6 +313,7 @@ declare class AsciiApplicationLayer extends AbstractApplicationLayer {
|
|
|
313
313
|
readonly lenientHex: boolean;
|
|
314
314
|
private _states;
|
|
315
315
|
private _removeAllListeners;
|
|
316
|
+
private _destroyed;
|
|
316
317
|
constructor(physicalLayer: SerialPhysicalLayer | TcpServerPhysicalLayer | TcpClientPhysicalLayer | UdpPhysicalLayer, options?: AsciiApplicationLayerOptions);
|
|
317
318
|
private getState;
|
|
318
319
|
flush(): void;
|
|
@@ -362,6 +363,7 @@ declare class RtuApplicationLayer extends AbstractApplicationLayer {
|
|
|
362
363
|
private _removeAllListeners;
|
|
363
364
|
private _threePointFiveT;
|
|
364
365
|
private _onePointFiveT;
|
|
366
|
+
private _destroyed;
|
|
365
367
|
constructor(physicalLayer: SerialPhysicalLayer | TcpServerPhysicalLayer | TcpClientPhysicalLayer | UdpPhysicalLayer, options?: RtuApplicationLayerOptions);
|
|
366
368
|
private getState;
|
|
367
369
|
private clearStateTimers;
|
|
@@ -383,6 +385,7 @@ declare class TcpApplicationLayer extends AbstractApplicationLayer {
|
|
|
383
385
|
private _transactionId;
|
|
384
386
|
private _buffers;
|
|
385
387
|
private _removeAllListeners;
|
|
388
|
+
private _destroyed;
|
|
386
389
|
constructor(physicalLayer: TcpServerPhysicalLayer | TcpClientPhysicalLayer | UdpPhysicalLayer);
|
|
387
390
|
private tryExtract;
|
|
388
391
|
private processFrame;
|
|
@@ -419,6 +422,7 @@ declare class ModbusMaster<A extends AbstractApplicationLayer, P extends Abstrac
|
|
|
419
422
|
private _draining;
|
|
420
423
|
private _nextTid;
|
|
421
424
|
private _closed;
|
|
425
|
+
private _cleanLevel;
|
|
422
426
|
timeout: number;
|
|
423
427
|
readonly concurrent: boolean;
|
|
424
428
|
get isOpen(): boolean;
|
|
@@ -484,6 +488,7 @@ declare class ModbusMaster<A extends AbstractApplicationLayer, P extends Abstrac
|
|
|
484
488
|
removeCustomFunctionCode(fc: number): void;
|
|
485
489
|
sendCustomFC(unit: 0, fc: number, data: Buffer | number[], timeout?: number): Promise<void>;
|
|
486
490
|
sendCustomFC(unit: number, fc: number, data: Buffer | number[], timeout?: number): Promise<Buffer>;
|
|
491
|
+
private _clean;
|
|
487
492
|
open(...args: Parameters<P['open']>): Promise<void>;
|
|
488
493
|
close(): Promise<void>;
|
|
489
494
|
destroy(): Promise<void>;
|
|
@@ -563,6 +568,7 @@ declare class ModbusSlave<A extends AbstractApplicationLayer, P extends Abstract
|
|
|
563
568
|
private _queues;
|
|
564
569
|
private _customFunctionCodes;
|
|
565
570
|
private _locks;
|
|
571
|
+
private _cleanLevel;
|
|
566
572
|
get isOpen(): boolean;
|
|
567
573
|
get destroyed(): boolean;
|
|
568
574
|
constructor(applicationLayer: A, physicalLayer: P, options?: ModbusSlaveOptions);
|
|
@@ -588,6 +594,7 @@ declare class ModbusSlave<A extends AbstractApplicationLayer, P extends Abstract
|
|
|
588
594
|
remove(unit: number): void;
|
|
589
595
|
addCustomFunctionCode(cfc: CustomFunctionCode): void;
|
|
590
596
|
removeCustomFunctionCode(fc: number): void;
|
|
597
|
+
private _clean;
|
|
591
598
|
open(...args: Parameters<P['open']>): Promise<void>;
|
|
592
599
|
close(): Promise<void>;
|
|
593
600
|
destroy(): Promise<void>;
|
package/dist/index.mjs
CHANGED
|
@@ -421,6 +421,9 @@ class SerialPhysicalLayer extends AbstractPhysicalLayer {
|
|
|
421
421
|
});
|
|
422
422
|
}
|
|
423
423
|
destroy() {
|
|
424
|
+
if (this._destroyed) {
|
|
425
|
+
return Promise.resolve();
|
|
426
|
+
}
|
|
424
427
|
this._destroyed = true;
|
|
425
428
|
return this.close().then(() => {
|
|
426
429
|
this.removeAllListeners();
|
|
@@ -560,6 +563,9 @@ class TcpClientPhysicalLayer extends AbstractPhysicalLayer {
|
|
|
560
563
|
});
|
|
561
564
|
}
|
|
562
565
|
destroy() {
|
|
566
|
+
if (this._destroyed) {
|
|
567
|
+
return Promise.resolve();
|
|
568
|
+
}
|
|
563
569
|
this._destroyed = true;
|
|
564
570
|
return this.close().then(() => {
|
|
565
571
|
this.removeAllListeners();
|
|
@@ -709,10 +715,18 @@ class TcpServerPhysicalLayer extends AbstractPhysicalLayer {
|
|
|
709
715
|
for (const [socket] of this._connections) {
|
|
710
716
|
socket.destroy();
|
|
711
717
|
}
|
|
712
|
-
|
|
718
|
+
try {
|
|
719
|
+
server.close();
|
|
720
|
+
}
|
|
721
|
+
catch (_a) {
|
|
722
|
+
resolve();
|
|
723
|
+
}
|
|
713
724
|
});
|
|
714
725
|
}
|
|
715
726
|
destroy() {
|
|
727
|
+
if (this._destroyed) {
|
|
728
|
+
return Promise.resolve();
|
|
729
|
+
}
|
|
716
730
|
this._destroyed = true;
|
|
717
731
|
return this.close().then(() => {
|
|
718
732
|
this.removeAllListeners();
|
|
@@ -943,6 +957,9 @@ class UdpPhysicalLayer extends AbstractPhysicalLayer {
|
|
|
943
957
|
});
|
|
944
958
|
}
|
|
945
959
|
destroy() {
|
|
960
|
+
if (this._destroyed) {
|
|
961
|
+
return Promise.resolve();
|
|
962
|
+
}
|
|
946
963
|
this._destroyed = true;
|
|
947
964
|
return this.close().then(() => {
|
|
948
965
|
this.removeAllListeners();
|
|
@@ -1022,6 +1039,12 @@ class RtuApplicationLayer extends AbstractApplicationLayer {
|
|
|
1022
1039
|
writable: true,
|
|
1023
1040
|
value: void 0
|
|
1024
1041
|
});
|
|
1042
|
+
Object.defineProperty(this, "_destroyed", {
|
|
1043
|
+
enumerable: true,
|
|
1044
|
+
configurable: true,
|
|
1045
|
+
writable: true,
|
|
1046
|
+
value: false
|
|
1047
|
+
});
|
|
1025
1048
|
const { intervalBetweenFrames, interCharTimeout } = options;
|
|
1026
1049
|
let threePointFiveT = 0;
|
|
1027
1050
|
let onePointFiveT = 0;
|
|
@@ -1272,14 +1295,20 @@ class RtuApplicationLayer extends AbstractApplicationLayer {
|
|
|
1272
1295
|
return buffer;
|
|
1273
1296
|
}
|
|
1274
1297
|
destroy() {
|
|
1298
|
+
if (this._destroyed) {
|
|
1299
|
+
return;
|
|
1300
|
+
}
|
|
1301
|
+
this._destroyed = true;
|
|
1275
1302
|
this.removeAllListeners();
|
|
1276
1303
|
for (const removeListener of this._removeAllListeners) {
|
|
1277
1304
|
removeListener();
|
|
1278
1305
|
}
|
|
1306
|
+
this._removeAllListeners.length = 0;
|
|
1279
1307
|
for (const state of this._states.values()) {
|
|
1280
1308
|
this.clearStateTimers(state);
|
|
1281
1309
|
}
|
|
1282
1310
|
this._states.clear();
|
|
1311
|
+
this._customFunctionCodes.clear();
|
|
1283
1312
|
}
|
|
1284
1313
|
}
|
|
1285
1314
|
|
|
@@ -1332,6 +1361,12 @@ class AsciiApplicationLayer extends AbstractApplicationLayer {
|
|
|
1332
1361
|
writable: true,
|
|
1333
1362
|
value: []
|
|
1334
1363
|
});
|
|
1364
|
+
Object.defineProperty(this, "_destroyed", {
|
|
1365
|
+
enumerable: true,
|
|
1366
|
+
configurable: true,
|
|
1367
|
+
writable: true,
|
|
1368
|
+
value: false
|
|
1369
|
+
});
|
|
1335
1370
|
this.lenientHex = (_a = options.lenientHex) !== null && _a !== void 0 ? _a : false;
|
|
1336
1371
|
const lenientHex = this.lenientHex;
|
|
1337
1372
|
const isHexChar = (value) => {
|
|
@@ -1469,10 +1504,15 @@ class AsciiApplicationLayer extends AbstractApplicationLayer {
|
|
|
1469
1504
|
return out;
|
|
1470
1505
|
}
|
|
1471
1506
|
destroy() {
|
|
1507
|
+
if (this._destroyed) {
|
|
1508
|
+
return;
|
|
1509
|
+
}
|
|
1510
|
+
this._destroyed = true;
|
|
1472
1511
|
this.removeAllListeners();
|
|
1473
1512
|
for (const removeListener of this._removeAllListeners) {
|
|
1474
1513
|
removeListener();
|
|
1475
1514
|
}
|
|
1515
|
+
this._removeAllListeners.length = 0;
|
|
1476
1516
|
this._states.clear();
|
|
1477
1517
|
}
|
|
1478
1518
|
}
|
|
@@ -1506,6 +1546,12 @@ class TcpApplicationLayer extends AbstractApplicationLayer {
|
|
|
1506
1546
|
writable: true,
|
|
1507
1547
|
value: []
|
|
1508
1548
|
});
|
|
1549
|
+
Object.defineProperty(this, "_destroyed", {
|
|
1550
|
+
enumerable: true,
|
|
1551
|
+
configurable: true,
|
|
1552
|
+
writable: true,
|
|
1553
|
+
value: false
|
|
1554
|
+
});
|
|
1509
1555
|
const handleData = (data, response, connection) => {
|
|
1510
1556
|
var _a;
|
|
1511
1557
|
let buffer = (_a = this._buffers.get(connection.id)) !== null && _a !== void 0 ? _a : EMPTY_BUFFER;
|
|
@@ -1588,10 +1634,15 @@ class TcpApplicationLayer extends AbstractApplicationLayer {
|
|
|
1588
1634
|
return buffer;
|
|
1589
1635
|
}
|
|
1590
1636
|
destroy() {
|
|
1637
|
+
if (this._destroyed) {
|
|
1638
|
+
return;
|
|
1639
|
+
}
|
|
1640
|
+
this._destroyed = true;
|
|
1591
1641
|
this.removeAllListeners();
|
|
1592
1642
|
for (const removeListener of this._removeAllListeners) {
|
|
1593
1643
|
removeListener();
|
|
1594
1644
|
}
|
|
1645
|
+
this._removeAllListeners.length = 0;
|
|
1595
1646
|
this._buffers.clear();
|
|
1596
1647
|
}
|
|
1597
1648
|
}
|
|
@@ -1702,7 +1753,7 @@ class ModbusMaster extends EventEmitter {
|
|
|
1702
1753
|
return this.physicalLayer.isOpen;
|
|
1703
1754
|
}
|
|
1704
1755
|
get destroyed() {
|
|
1705
|
-
return this.physicalLayer.destroyed;
|
|
1756
|
+
return this._cleanLevel === 'destroy' || this.physicalLayer.destroyed;
|
|
1706
1757
|
}
|
|
1707
1758
|
constructor(applicationLayer, physicalLayer, options = {}) {
|
|
1708
1759
|
var _a, _b;
|
|
@@ -1749,6 +1800,12 @@ class ModbusMaster extends EventEmitter {
|
|
|
1749
1800
|
writable: true,
|
|
1750
1801
|
value: false
|
|
1751
1802
|
});
|
|
1803
|
+
Object.defineProperty(this, "_cleanLevel", {
|
|
1804
|
+
enumerable: true,
|
|
1805
|
+
configurable: true,
|
|
1806
|
+
writable: true,
|
|
1807
|
+
value: 'none'
|
|
1808
|
+
});
|
|
1752
1809
|
Object.defineProperty(this, "timeout", {
|
|
1753
1810
|
enumerable: true,
|
|
1754
1811
|
configurable: true,
|
|
@@ -2162,26 +2219,44 @@ class ModbusMaster extends EventEmitter {
|
|
|
2162
2219
|
}
|
|
2163
2220
|
});
|
|
2164
2221
|
}
|
|
2222
|
+
_clean(level) {
|
|
2223
|
+
if (this._cleanLevel === 'destroy') {
|
|
2224
|
+
return;
|
|
2225
|
+
}
|
|
2226
|
+
if (this._cleanLevel === 'close' && level === 'close') {
|
|
2227
|
+
return;
|
|
2228
|
+
}
|
|
2229
|
+
const errorCode = level === 'destroy' ? ModbusErrorCode.MASTER_DESTROYED : ModbusErrorCode.MASTER_CLOSED;
|
|
2230
|
+
const message = level === 'destroy' ? 'Master destroyed' : 'Master closed';
|
|
2231
|
+
this._closed = true;
|
|
2232
|
+
const queued = this._queue.splice(0);
|
|
2233
|
+
for (const item of queued) {
|
|
2234
|
+
item.cancel(new ModbusError(errorCode, message));
|
|
2235
|
+
}
|
|
2236
|
+
this._masterSession.stopAll(new ModbusError(errorCode, message));
|
|
2237
|
+
this._cleanLevel = level;
|
|
2238
|
+
}
|
|
2165
2239
|
open(...args) {
|
|
2240
|
+
if (this._cleanLevel === 'destroy') {
|
|
2241
|
+
return Promise.reject(new ModbusError(ModbusErrorCode.PORT_DESTROYED, 'Master is destroyed'));
|
|
2242
|
+
}
|
|
2243
|
+
this._cleanLevel = 'none';
|
|
2166
2244
|
this._closed = false;
|
|
2245
|
+
this._nextTid = 1;
|
|
2167
2246
|
return this.physicalLayer.open(...args);
|
|
2168
2247
|
}
|
|
2169
2248
|
close() {
|
|
2170
|
-
this.
|
|
2171
|
-
|
|
2172
|
-
for (const item of queued) {
|
|
2173
|
-
item.cancel(new ModbusError(ModbusErrorCode.MASTER_CLOSED, 'Master closed'));
|
|
2249
|
+
if (this._cleanLevel === 'destroy') {
|
|
2250
|
+
return Promise.resolve();
|
|
2174
2251
|
}
|
|
2175
|
-
this.
|
|
2252
|
+
this._clean('close');
|
|
2176
2253
|
return this.physicalLayer.close();
|
|
2177
2254
|
}
|
|
2178
2255
|
destroy() {
|
|
2179
|
-
this.
|
|
2180
|
-
|
|
2181
|
-
for (const item of queued) {
|
|
2182
|
-
item.cancel(new ModbusError(ModbusErrorCode.MASTER_DESTROYED, 'Master destroyed'));
|
|
2256
|
+
if (this._cleanLevel === 'destroy') {
|
|
2257
|
+
return Promise.resolve();
|
|
2183
2258
|
}
|
|
2184
|
-
this.
|
|
2259
|
+
this._clean('destroy');
|
|
2185
2260
|
this.removeAllListeners();
|
|
2186
2261
|
this.applicationLayer.destroy();
|
|
2187
2262
|
return this.physicalLayer.destroy();
|
|
@@ -2193,7 +2268,7 @@ class ModbusSlave extends EventEmitter {
|
|
|
2193
2268
|
return this.physicalLayer.isOpen;
|
|
2194
2269
|
}
|
|
2195
2270
|
get destroyed() {
|
|
2196
|
-
return this.physicalLayer.destroyed;
|
|
2271
|
+
return this._cleanLevel === 'destroy' || this.physicalLayer.destroyed;
|
|
2197
2272
|
}
|
|
2198
2273
|
constructor(applicationLayer, physicalLayer, options = {}) {
|
|
2199
2274
|
var _a;
|
|
@@ -2240,6 +2315,12 @@ class ModbusSlave extends EventEmitter {
|
|
|
2240
2315
|
writable: true,
|
|
2241
2316
|
value: new Map()
|
|
2242
2317
|
});
|
|
2318
|
+
Object.defineProperty(this, "_cleanLevel", {
|
|
2319
|
+
enumerable: true,
|
|
2320
|
+
configurable: true,
|
|
2321
|
+
writable: true,
|
|
2322
|
+
value: 'none'
|
|
2323
|
+
});
|
|
2243
2324
|
this.concurrent = (_a = options.concurrent) !== null && _a !== void 0 ? _a : false;
|
|
2244
2325
|
if (this.concurrent && this.applicationLayer.PROTOCOL !== 'TCP') {
|
|
2245
2326
|
throw new ModbusError(ModbusErrorCode.CONCURRENT_NOT_TCP, 'concurrent mode requires a Modbus TCP application layer');
|
|
@@ -2972,14 +3053,40 @@ class ModbusSlave extends EventEmitter {
|
|
|
2972
3053
|
this._customFunctionCodes.delete(fc);
|
|
2973
3054
|
this.applicationLayer.removeCustomFunctionCode(fc);
|
|
2974
3055
|
}
|
|
3056
|
+
_clean(level) {
|
|
3057
|
+
if (this._cleanLevel === 'destroy') {
|
|
3058
|
+
return;
|
|
3059
|
+
}
|
|
3060
|
+
if (this._cleanLevel === 'close' && level === 'close') {
|
|
3061
|
+
return;
|
|
3062
|
+
}
|
|
3063
|
+
for (const q of this._queues.values()) {
|
|
3064
|
+
q.items.length = 0;
|
|
3065
|
+
}
|
|
3066
|
+
this._queues.clear();
|
|
3067
|
+
this._locks.clear();
|
|
3068
|
+
if (level === 'destroy') {
|
|
3069
|
+
this._customFunctionCodes.clear();
|
|
3070
|
+
this.models.clear();
|
|
3071
|
+
}
|
|
3072
|
+
this._cleanLevel = level;
|
|
3073
|
+
}
|
|
2975
3074
|
open(...args) {
|
|
3075
|
+
this._cleanLevel = 'none';
|
|
2976
3076
|
return this.physicalLayer.open(...args);
|
|
2977
3077
|
}
|
|
2978
3078
|
close() {
|
|
3079
|
+
if (this._cleanLevel === 'destroy') {
|
|
3080
|
+
return Promise.resolve();
|
|
3081
|
+
}
|
|
3082
|
+
this._clean('close');
|
|
2979
3083
|
return this.physicalLayer.close();
|
|
2980
3084
|
}
|
|
2981
3085
|
destroy() {
|
|
2982
|
-
this.
|
|
3086
|
+
if (this._cleanLevel === 'destroy') {
|
|
3087
|
+
return Promise.resolve();
|
|
3088
|
+
}
|
|
3089
|
+
this._clean('destroy');
|
|
2983
3090
|
this.removeAllListeners();
|
|
2984
3091
|
this.applicationLayer.destroy();
|
|
2985
3092
|
return this.physicalLayer.destroy();
|
|
@@ -15,6 +15,7 @@ export declare class AsciiApplicationLayer extends AbstractApplicationLayer {
|
|
|
15
15
|
readonly lenientHex: boolean;
|
|
16
16
|
private _states;
|
|
17
17
|
private _removeAllListeners;
|
|
18
|
+
private _destroyed;
|
|
18
19
|
constructor(physicalLayer: SerialPhysicalLayer | TcpServerPhysicalLayer | TcpClientPhysicalLayer | UdpPhysicalLayer, options?: AsciiApplicationLayerOptions);
|
|
19
20
|
private getState;
|
|
20
21
|
flush(): void;
|
|
@@ -43,6 +43,7 @@ export declare class RtuApplicationLayer extends AbstractApplicationLayer {
|
|
|
43
43
|
private _removeAllListeners;
|
|
44
44
|
private _threePointFiveT;
|
|
45
45
|
private _onePointFiveT;
|
|
46
|
+
private _destroyed;
|
|
46
47
|
constructor(physicalLayer: SerialPhysicalLayer | TcpServerPhysicalLayer | TcpClientPhysicalLayer | UdpPhysicalLayer, options?: RtuApplicationLayerOptions);
|
|
47
48
|
private getState;
|
|
48
49
|
private clearStateTimers;
|
|
@@ -6,6 +6,7 @@ export declare class TcpApplicationLayer extends AbstractApplicationLayer {
|
|
|
6
6
|
private _transactionId;
|
|
7
7
|
private _buffers;
|
|
8
8
|
private _removeAllListeners;
|
|
9
|
+
private _destroyed;
|
|
9
10
|
constructor(physicalLayer: TcpServerPhysicalLayer | TcpClientPhysicalLayer | UdpPhysicalLayer);
|
|
10
11
|
private tryExtract;
|
|
11
12
|
private processFrame;
|
|
@@ -31,6 +31,7 @@ export declare class ModbusMaster<A extends AbstractApplicationLayer, P extends
|
|
|
31
31
|
private _draining;
|
|
32
32
|
private _nextTid;
|
|
33
33
|
private _closed;
|
|
34
|
+
private _cleanLevel;
|
|
34
35
|
timeout: number;
|
|
35
36
|
readonly concurrent: boolean;
|
|
36
37
|
get isOpen(): boolean;
|
|
@@ -96,6 +97,7 @@ export declare class ModbusMaster<A extends AbstractApplicationLayer, P extends
|
|
|
96
97
|
removeCustomFunctionCode(fc: number): void;
|
|
97
98
|
sendCustomFC(unit: 0, fc: number, data: Buffer | number[], timeout?: number): Promise<void>;
|
|
98
99
|
sendCustomFC(unit: number, fc: number, data: Buffer | number[], timeout?: number): Promise<Buffer>;
|
|
100
|
+
private _clean;
|
|
99
101
|
open(...args: Parameters<P['open']>): Promise<void>;
|
|
100
102
|
close(): Promise<void>;
|
|
101
103
|
destroy(): Promise<void>;
|
|
@@ -60,6 +60,7 @@ export declare class ModbusSlave<A extends AbstractApplicationLayer, P extends A
|
|
|
60
60
|
private _queues;
|
|
61
61
|
private _customFunctionCodes;
|
|
62
62
|
private _locks;
|
|
63
|
+
private _cleanLevel;
|
|
63
64
|
get isOpen(): boolean;
|
|
64
65
|
get destroyed(): boolean;
|
|
65
66
|
constructor(applicationLayer: A, physicalLayer: P, options?: ModbusSlaveOptions);
|
|
@@ -85,6 +86,7 @@ export declare class ModbusSlave<A extends AbstractApplicationLayer, P extends A
|
|
|
85
86
|
remove(unit: number): void;
|
|
86
87
|
addCustomFunctionCode(cfc: CustomFunctionCode): void;
|
|
87
88
|
removeCustomFunctionCode(fc: number): void;
|
|
89
|
+
private _clean;
|
|
88
90
|
open(...args: Parameters<P['open']>): Promise<void>;
|
|
89
91
|
close(): Promise<void>;
|
|
90
92
|
destroy(): Promise<void>;
|