njs-modbus 1.0.1 → 1.2.0

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/README.md CHANGED
@@ -69,7 +69,7 @@ npm install njs-modbus
69
69
  import { SerialPhysicalLayer, RtuApplicationLayer, ModbusMaster } from 'njs-modbus';
70
70
 
71
71
  const physicalLayer = new SerialPhysicalLayer({ path: 'COM1', baudRate: 9600, dataBits: 8, parity: 'none', stopBits: 1 });
72
- const applicationLayer = new RtuApplicationLayer(physicalLayer, { baudRate: 9600 });
72
+ const applicationLayer = new RtuApplicationLayer(physicalLayer);
73
73
 
74
74
  const modbusMaster = new ModbusMaster(applicationLayer, physicalLayer);
75
75
 
@@ -99,7 +99,7 @@ const MB_SERVER = {
99
99
  };
100
100
 
101
101
  const physicalLayer = new SerialPhysicalLayer({ path: 'COM1', baudRate: 9600, dataBits: 8, parity: 'none', stopBits: 1 });
102
- const applicationLayer = new RtuApplicationLayer(physicalLayer, { baudRate: 9600 });
102
+ const applicationLayer = new RtuApplicationLayer(physicalLayer);
103
103
 
104
104
  const modbusSlave = new ModbusSlave(
105
105
  {
package/dist/index.cjs CHANGED
@@ -38,6 +38,9 @@ class SerialPhysicalLayer extends AbstractPhysicalLayer {
38
38
  get destroyed() {
39
39
  return this._destroyed;
40
40
  }
41
+ get baudRate() {
42
+ return this._baudRate;
43
+ }
41
44
  constructor(options) {
42
45
  super();
43
46
  Object.defineProperty(this, "TYPE", {
@@ -58,7 +61,14 @@ class SerialPhysicalLayer extends AbstractPhysicalLayer {
58
61
  writable: true,
59
62
  value: false
60
63
  });
64
+ Object.defineProperty(this, "_baudRate", {
65
+ enumerable: true,
66
+ configurable: true,
67
+ writable: true,
68
+ value: void 0
69
+ });
61
70
  this._serialport = new serialport.SerialPort(Object.assign(Object.assign({}, options), { autoOpen: false }));
71
+ this._baudRate = options.baudRate;
62
72
  }
63
73
  open() {
64
74
  if (this.destroyed) {
@@ -93,6 +103,7 @@ class SerialPhysicalLayer extends AbstractPhysicalLayer {
93
103
  reject(error);
94
104
  }
95
105
  else {
106
+ this.emit('write', data);
96
107
  resolve();
97
108
  }
98
109
  });
@@ -189,6 +200,7 @@ class TcpClientPhysicalLayer extends AbstractPhysicalLayer {
189
200
  reject(error);
190
201
  }
191
202
  else {
203
+ this.emit('write', data);
192
204
  resolve();
193
205
  }
194
206
  });
@@ -443,6 +455,7 @@ class UdpPhysicalLayer extends AbstractPhysicalLayer {
443
455
  reject(error);
444
456
  }
445
457
  else {
458
+ this.emit('write', data);
446
459
  resolve();
447
460
  }
448
461
  });
@@ -472,8 +485,22 @@ class AbstractApplicationLayer extends EventEmitter {
472
485
  }
473
486
 
474
487
  function checkRange(value, range) {
475
- if (range && range[0] < range[1]) {
476
- return (Array.isArray(value) ? value : [value]).every((n) => n >= range[0] && n <= range[1]);
488
+ if (range) {
489
+ if (typeof range[0] === 'number' && typeof range[1] === 'number') {
490
+ if (range[0] < range[1]) {
491
+ return (Array.isArray(value) ? value : [value]).every((n) => n >= range[0] && n <= range[1]);
492
+ }
493
+ }
494
+ else if (range.length > 0) {
495
+ for (const r of range) {
496
+ if (r[0] < r[1]) {
497
+ if ((Array.isArray(value) ? value : [value]).every((n) => n >= r[0] && n <= r[1])) {
498
+ return true;
499
+ }
500
+ }
501
+ }
502
+ return false;
503
+ }
477
504
  }
478
505
  return true;
479
506
  }
@@ -519,7 +546,7 @@ function lrc(data) {
519
546
  }
520
547
 
521
548
  class RtuApplicationLayer extends AbstractApplicationLayer {
522
- constructor(physicalLayer, serialFrameInterval) {
549
+ constructor(physicalLayer, bitsBetweenFrames) {
523
550
  super();
524
551
  Object.defineProperty(this, "_timerThreePointFive", {
525
552
  enumerable: true,
@@ -540,10 +567,10 @@ class RtuApplicationLayer extends AbstractApplicationLayer {
540
567
  value: []
541
568
  });
542
569
  let threePointFiveT = 0;
543
- if (physicalLayer.TYPE === 'SERIAL' && serialFrameInterval) {
544
- threePointFiveT = Math.ceil(serialFrameInterval.baudRate > 19200
570
+ if (physicalLayer.TYPE === 'SERIAL') {
571
+ threePointFiveT = Math.ceil(physicalLayer.baudRate > 19200
545
572
  ? 1.8
546
- : getThreePointFiveT(serialFrameInterval.baudRate, serialFrameInterval.bitsBetweenFrames));
573
+ : getThreePointFiveT(physicalLayer.baudRate, bitsBetweenFrames));
547
574
  }
548
575
  const handleData = (data, response) => {
549
576
  this._bufferRx = Buffer.concat([this._bufferRx, data]);
@@ -1368,14 +1395,14 @@ class ModbusSlave extends EventEmitter {
1368
1395
  });
1369
1396
  }
1370
1397
  handleFC1(frame, response) {
1371
- var _a;
1398
+ var _a, _b;
1372
1399
  if (frame.data.length === 4) {
1373
1400
  if (this.model.readCoils) {
1374
1401
  const bufferRx = Buffer.from(frame.data);
1375
1402
  const address = bufferRx.readUInt16BE(0);
1376
1403
  const length = bufferRx.readUInt16BE(2);
1377
1404
  if (length >= 0x0001 && length <= 0x07d0) {
1378
- if (checkRange([address, address + length], (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.coils)) {
1405
+ if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1379
1406
  Promise.resolve(this.model.readCoils(address, length))
1380
1407
  .then((coils) => {
1381
1408
  const bufferTx = Buffer.alloc(Math.ceil(length / 8));
@@ -1404,14 +1431,14 @@ class ModbusSlave extends EventEmitter {
1404
1431
  }
1405
1432
  }
1406
1433
  handleFC2(frame, response) {
1407
- var _a;
1434
+ var _a, _b;
1408
1435
  if (frame.data.length === 4) {
1409
1436
  if (this.model.readDiscreteInputs) {
1410
1437
  const bufferRx = Buffer.from(frame.data);
1411
1438
  const address = bufferRx.readUInt16BE(0);
1412
1439
  const length = bufferRx.readUInt16BE(2);
1413
1440
  if (length >= 0x0001 && length <= 0x07d0) {
1414
- if (checkRange([address, address + length], (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.discreteInputs)) {
1441
+ if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).discreteInputs)) {
1415
1442
  Promise.resolve(this.model.readDiscreteInputs(address, length))
1416
1443
  .then((discreteInputs) => {
1417
1444
  const bufferTx = Buffer.alloc(Math.ceil(length / 8));
@@ -1440,14 +1467,14 @@ class ModbusSlave extends EventEmitter {
1440
1467
  }
1441
1468
  }
1442
1469
  handleFC3(frame, response) {
1443
- var _a;
1470
+ var _a, _b;
1444
1471
  if (frame.data.length === 4) {
1445
1472
  if (this.model.readHoldingRegisters) {
1446
1473
  const bufferRx = Buffer.from(frame.data);
1447
1474
  const address = bufferRx.readUInt16BE(0);
1448
1475
  const length = bufferRx.readUInt16BE(2);
1449
1476
  if (length >= 0x0001 && length <= 0x007d) {
1450
- if (checkRange([address, address + length], (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.holdingRegisters)) {
1477
+ if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1451
1478
  Promise.resolve(this.model.readHoldingRegisters(address, length))
1452
1479
  .then((registers) => {
1453
1480
  const bufferTx = Buffer.alloc(length * 2);
@@ -1474,14 +1501,14 @@ class ModbusSlave extends EventEmitter {
1474
1501
  }
1475
1502
  }
1476
1503
  handleFC4(frame, response) {
1477
- var _a;
1504
+ var _a, _b;
1478
1505
  if (frame.data.length === 4) {
1479
1506
  if (this.model.readInputRegisters) {
1480
1507
  const bufferRx = Buffer.from(frame.data);
1481
1508
  const address = bufferRx.readUInt16BE(0);
1482
1509
  const length = bufferRx.readUInt16BE(2);
1483
1510
  if (length >= 0x0001 && length <= 0x007d) {
1484
- if (checkRange([address, address + length], (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.inputRegisters)) {
1511
+ if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).inputRegisters)) {
1485
1512
  Promise.resolve(this.model.readInputRegisters(address, length))
1486
1513
  .then((registers) => {
1487
1514
  const bufferTx = Buffer.alloc(length * 2);
@@ -1508,14 +1535,14 @@ class ModbusSlave extends EventEmitter {
1508
1535
  }
1509
1536
  }
1510
1537
  handleFC5(frame, response) {
1511
- var _a;
1538
+ var _a, _b;
1512
1539
  if (frame.data.length === 4) {
1513
1540
  if (this.model.writeSingleCoil) {
1514
1541
  const bufferRx = Buffer.from(frame.data);
1515
1542
  const address = bufferRx.readUInt16BE(0);
1516
1543
  const value = bufferRx.readUInt16BE(2);
1517
1544
  if (value === 0x0000 || value === 0xff00) {
1518
- if (checkRange(address, (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.coils)) {
1545
+ if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1519
1546
  Promise.resolve(this.model.writeSingleCoil(address, value === 0xff00))
1520
1547
  .then(() => {
1521
1548
  response(this.applicationLayer.encode(frame));
@@ -1538,14 +1565,14 @@ class ModbusSlave extends EventEmitter {
1538
1565
  }
1539
1566
  }
1540
1567
  handleFC6(frame, response) {
1541
- var _a;
1568
+ var _a, _b;
1542
1569
  if (frame.data.length === 4) {
1543
1570
  if (this.model.writeSingleRegister) {
1544
1571
  const bufferRx = Buffer.from(frame.data);
1545
1572
  const address = bufferRx.readUInt16BE(0);
1546
1573
  const value = bufferRx.readUInt16BE(2);
1547
1574
  if (value >= 0x0000 && value <= 0xffff) {
1548
- if (checkRange(address, (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.holdingRegisters)) {
1575
+ if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1549
1576
  Promise.resolve(this.model.writeSingleRegister(address, value))
1550
1577
  .then(() => {
1551
1578
  response(this.applicationLayer.encode(frame));
@@ -1568,7 +1595,7 @@ class ModbusSlave extends EventEmitter {
1568
1595
  }
1569
1596
  }
1570
1597
  handleFC15(frame, response) {
1571
- var _a;
1598
+ var _a, _b;
1572
1599
  if (frame.data.length > 5 && frame.data.length === 5 + frame.data[4]) {
1573
1600
  if (this.model.writeMultipleCoils || this.model.writeSingleCoil) {
1574
1601
  const bufferRx = Buffer.from(frame.data);
@@ -1576,7 +1603,7 @@ class ModbusSlave extends EventEmitter {
1576
1603
  const length = bufferRx.readUInt16BE(2);
1577
1604
  const byteCount = bufferRx[4];
1578
1605
  if (length >= 0x0001 && length <= 0x07b0 && byteCount === Math.ceil(length / 8)) {
1579
- if (checkRange([address, address + length], (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.coils)) {
1606
+ if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1580
1607
  const value = Array.from({ length }).map((_, index) => (bufferRx[5 + ~~(index / 8)] & (1 << index % 8)) > 0);
1581
1608
  Promise.resolve(this.model.writeMultipleCoils
1582
1609
  ? this.model.writeMultipleCoils(address, value)
@@ -1602,7 +1629,7 @@ class ModbusSlave extends EventEmitter {
1602
1629
  }
1603
1630
  }
1604
1631
  handleFC16(frame, response) {
1605
- var _a;
1632
+ var _a, _b;
1606
1633
  if (frame.data.length > 5 && frame.data.length === 5 + frame.data[4]) {
1607
1634
  if (this.model.writeMultipleRegisters || this.model.writeSingleRegister) {
1608
1635
  const bufferRx = Buffer.from(frame.data);
@@ -1610,7 +1637,7 @@ class ModbusSlave extends EventEmitter {
1610
1637
  const length = bufferRx.readUInt16BE(2);
1611
1638
  const byteCount = bufferRx[4];
1612
1639
  if (length >= 0x0001 && length <= 0x007b && byteCount === length * 2) {
1613
- if (checkRange([address, address + length], (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.holdingRegisters)) {
1640
+ if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1614
1641
  const value = Array.from({ length }).map((_, index) => bufferRx.readUInt16BE(5 + index * 2));
1615
1642
  Promise.resolve(this.model.writeMultipleRegisters
1616
1643
  ? this.model.writeMultipleRegisters(address, value)
@@ -1652,14 +1679,14 @@ class ModbusSlave extends EventEmitter {
1652
1679
  }
1653
1680
  }
1654
1681
  handleFC22(frame, response) {
1655
- var _a;
1682
+ var _a, _b;
1656
1683
  if (frame.data.length === 6) {
1657
1684
  if (this.model.maskWriteRegister || (this.model.readHoldingRegisters && this.model.writeSingleRegister)) {
1658
1685
  const bufferRx = Buffer.from(frame.data);
1659
1686
  const address = bufferRx.readUInt16BE(0);
1660
1687
  const andMask = bufferRx.readUInt16BE(2);
1661
1688
  const orMask = bufferRx.readUInt16BE(4);
1662
- if (checkRange(address, (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.holdingRegisters)) {
1689
+ if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1663
1690
  Promise.resolve(this.model.maskWriteRegister
1664
1691
  ? this.model.maskWriteRegister(address, andMask, orMask)
1665
1692
  : Promise.resolve(this.model.readHoldingRegisters(address, 1)).then(([value]) => {
@@ -1682,7 +1709,7 @@ class ModbusSlave extends EventEmitter {
1682
1709
  }
1683
1710
  }
1684
1711
  handleFC23(frame, response) {
1685
- var _a;
1712
+ var _a, _b;
1686
1713
  if (frame.data.length > 9 && frame.data.length === 9 + frame.data[8]) {
1687
1714
  if (this.model.readHoldingRegisters && (this.model.writeMultipleRegisters || this.model.writeSingleRegister)) {
1688
1715
  const bufferRx = Buffer.from(frame.data);
@@ -1700,7 +1727,7 @@ class ModbusSlave extends EventEmitter {
1700
1727
  length.write >= 0x0001 &&
1701
1728
  length.write <= 0x0079 &&
1702
1729
  byteCount === length.write * 2) {
1703
- if (checkRange([address.read, address.read + length.read, address.write, address.write + length.write], (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.holdingRegisters)) {
1730
+ if (checkRange([address.read, address.read + length.read, address.write, address.write + length.write], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1704
1731
  const value = Array.from({ length: length.write }).map((_, index) => bufferRx.readUInt16BE(9 + index * 2));
1705
1732
  Promise.resolve(this.model.writeMultipleRegisters
1706
1733
  ? this.model.writeMultipleRegisters(address.write, value)
package/dist/index.d.ts CHANGED
@@ -18,6 +18,7 @@ declare function getCodeByError(err: Error): ErrorCode;
18
18
 
19
19
  interface AbstractPhysicalLayerEvents {
20
20
  data: [data: Buffer, response: (data: Buffer) => Promise<void>];
21
+ write: [data: Buffer];
21
22
  error: [error: Error];
22
23
  close: [];
23
24
  }
@@ -60,8 +61,10 @@ declare class SerialPhysicalLayer extends AbstractPhysicalLayer {
60
61
  TYPE: 'SERIAL' | 'NET';
61
62
  private _serialport;
62
63
  private _destroyed;
64
+ private _baudRate;
63
65
  get isOpen(): boolean;
64
66
  get destroyed(): boolean;
67
+ get baudRate(): number;
65
68
  constructor(options: SerialPhysicalLayerOptions);
66
69
  open(): Promise<void>;
67
70
  write(data: Buffer): Promise<void>;
@@ -161,10 +164,7 @@ declare class RtuApplicationLayer extends AbstractApplicationLayer {
161
164
  private _timerThreePointFive?;
162
165
  private _bufferRx;
163
166
  private _removeAllListeners;
164
- constructor(physicalLayer: SerialPhysicalLayer | TcpServerPhysicalLayer | TcpClientPhysicalLayer | UdpPhysicalLayer, serialFrameInterval?: {
165
- baudRate: number;
166
- bitsBetweenFrames?: number;
167
- });
167
+ constructor(physicalLayer: SerialPhysicalLayer | TcpServerPhysicalLayer | TcpClientPhysicalLayer | UdpPhysicalLayer, bitsBetweenFrames?: number);
168
168
  private framing;
169
169
  encode(data: ApplicationDataUnit): Buffer;
170
170
  destroy(): void;
@@ -298,11 +298,11 @@ interface ModbusSlaveModel {
298
298
  readDeviceIdentification?: FConvertPromise<() => {
299
299
  [index: number]: string;
300
300
  }>;
301
- addressRange?: {
302
- discreteInputs?: [number, number];
303
- coils?: [number, number];
304
- inputRegisters?: [number, number];
305
- holdingRegisters?: [number, number];
301
+ getAddressRange?: () => {
302
+ discreteInputs?: [number, number] | [number, number][];
303
+ coils?: [number, number] | [number, number][];
304
+ inputRegisters?: [number, number] | [number, number][];
305
+ holdingRegisters?: [number, number] | [number, number][];
306
306
  };
307
307
  }
308
308
  interface ModbusSlaveEvents {
package/dist/index.mjs CHANGED
@@ -36,6 +36,9 @@ class SerialPhysicalLayer extends AbstractPhysicalLayer {
36
36
  get destroyed() {
37
37
  return this._destroyed;
38
38
  }
39
+ get baudRate() {
40
+ return this._baudRate;
41
+ }
39
42
  constructor(options) {
40
43
  super();
41
44
  Object.defineProperty(this, "TYPE", {
@@ -56,7 +59,14 @@ class SerialPhysicalLayer extends AbstractPhysicalLayer {
56
59
  writable: true,
57
60
  value: false
58
61
  });
62
+ Object.defineProperty(this, "_baudRate", {
63
+ enumerable: true,
64
+ configurable: true,
65
+ writable: true,
66
+ value: void 0
67
+ });
59
68
  this._serialport = new SerialPort(Object.assign(Object.assign({}, options), { autoOpen: false }));
69
+ this._baudRate = options.baudRate;
60
70
  }
61
71
  open() {
62
72
  if (this.destroyed) {
@@ -91,6 +101,7 @@ class SerialPhysicalLayer extends AbstractPhysicalLayer {
91
101
  reject(error);
92
102
  }
93
103
  else {
104
+ this.emit('write', data);
94
105
  resolve();
95
106
  }
96
107
  });
@@ -187,6 +198,7 @@ class TcpClientPhysicalLayer extends AbstractPhysicalLayer {
187
198
  reject(error);
188
199
  }
189
200
  else {
201
+ this.emit('write', data);
190
202
  resolve();
191
203
  }
192
204
  });
@@ -441,6 +453,7 @@ class UdpPhysicalLayer extends AbstractPhysicalLayer {
441
453
  reject(error);
442
454
  }
443
455
  else {
456
+ this.emit('write', data);
444
457
  resolve();
445
458
  }
446
459
  });
@@ -470,8 +483,22 @@ class AbstractApplicationLayer extends EventEmitter {
470
483
  }
471
484
 
472
485
  function checkRange(value, range) {
473
- if (range && range[0] < range[1]) {
474
- return (Array.isArray(value) ? value : [value]).every((n) => n >= range[0] && n <= range[1]);
486
+ if (range) {
487
+ if (typeof range[0] === 'number' && typeof range[1] === 'number') {
488
+ if (range[0] < range[1]) {
489
+ return (Array.isArray(value) ? value : [value]).every((n) => n >= range[0] && n <= range[1]);
490
+ }
491
+ }
492
+ else if (range.length > 0) {
493
+ for (const r of range) {
494
+ if (r[0] < r[1]) {
495
+ if ((Array.isArray(value) ? value : [value]).every((n) => n >= r[0] && n <= r[1])) {
496
+ return true;
497
+ }
498
+ }
499
+ }
500
+ return false;
501
+ }
475
502
  }
476
503
  return true;
477
504
  }
@@ -517,7 +544,7 @@ function lrc(data) {
517
544
  }
518
545
 
519
546
  class RtuApplicationLayer extends AbstractApplicationLayer {
520
- constructor(physicalLayer, serialFrameInterval) {
547
+ constructor(physicalLayer, bitsBetweenFrames) {
521
548
  super();
522
549
  Object.defineProperty(this, "_timerThreePointFive", {
523
550
  enumerable: true,
@@ -538,10 +565,10 @@ class RtuApplicationLayer extends AbstractApplicationLayer {
538
565
  value: []
539
566
  });
540
567
  let threePointFiveT = 0;
541
- if (physicalLayer.TYPE === 'SERIAL' && serialFrameInterval) {
542
- threePointFiveT = Math.ceil(serialFrameInterval.baudRate > 19200
568
+ if (physicalLayer.TYPE === 'SERIAL') {
569
+ threePointFiveT = Math.ceil(physicalLayer.baudRate > 19200
543
570
  ? 1.8
544
- : getThreePointFiveT(serialFrameInterval.baudRate, serialFrameInterval.bitsBetweenFrames));
571
+ : getThreePointFiveT(physicalLayer.baudRate, bitsBetweenFrames));
545
572
  }
546
573
  const handleData = (data, response) => {
547
574
  this._bufferRx = Buffer.concat([this._bufferRx, data]);
@@ -1366,14 +1393,14 @@ class ModbusSlave extends EventEmitter {
1366
1393
  });
1367
1394
  }
1368
1395
  handleFC1(frame, response) {
1369
- var _a;
1396
+ var _a, _b;
1370
1397
  if (frame.data.length === 4) {
1371
1398
  if (this.model.readCoils) {
1372
1399
  const bufferRx = Buffer.from(frame.data);
1373
1400
  const address = bufferRx.readUInt16BE(0);
1374
1401
  const length = bufferRx.readUInt16BE(2);
1375
1402
  if (length >= 0x0001 && length <= 0x07d0) {
1376
- if (checkRange([address, address + length], (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.coils)) {
1403
+ if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1377
1404
  Promise.resolve(this.model.readCoils(address, length))
1378
1405
  .then((coils) => {
1379
1406
  const bufferTx = Buffer.alloc(Math.ceil(length / 8));
@@ -1402,14 +1429,14 @@ class ModbusSlave extends EventEmitter {
1402
1429
  }
1403
1430
  }
1404
1431
  handleFC2(frame, response) {
1405
- var _a;
1432
+ var _a, _b;
1406
1433
  if (frame.data.length === 4) {
1407
1434
  if (this.model.readDiscreteInputs) {
1408
1435
  const bufferRx = Buffer.from(frame.data);
1409
1436
  const address = bufferRx.readUInt16BE(0);
1410
1437
  const length = bufferRx.readUInt16BE(2);
1411
1438
  if (length >= 0x0001 && length <= 0x07d0) {
1412
- if (checkRange([address, address + length], (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.discreteInputs)) {
1439
+ if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).discreteInputs)) {
1413
1440
  Promise.resolve(this.model.readDiscreteInputs(address, length))
1414
1441
  .then((discreteInputs) => {
1415
1442
  const bufferTx = Buffer.alloc(Math.ceil(length / 8));
@@ -1438,14 +1465,14 @@ class ModbusSlave extends EventEmitter {
1438
1465
  }
1439
1466
  }
1440
1467
  handleFC3(frame, response) {
1441
- var _a;
1468
+ var _a, _b;
1442
1469
  if (frame.data.length === 4) {
1443
1470
  if (this.model.readHoldingRegisters) {
1444
1471
  const bufferRx = Buffer.from(frame.data);
1445
1472
  const address = bufferRx.readUInt16BE(0);
1446
1473
  const length = bufferRx.readUInt16BE(2);
1447
1474
  if (length >= 0x0001 && length <= 0x007d) {
1448
- if (checkRange([address, address + length], (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.holdingRegisters)) {
1475
+ if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1449
1476
  Promise.resolve(this.model.readHoldingRegisters(address, length))
1450
1477
  .then((registers) => {
1451
1478
  const bufferTx = Buffer.alloc(length * 2);
@@ -1472,14 +1499,14 @@ class ModbusSlave extends EventEmitter {
1472
1499
  }
1473
1500
  }
1474
1501
  handleFC4(frame, response) {
1475
- var _a;
1502
+ var _a, _b;
1476
1503
  if (frame.data.length === 4) {
1477
1504
  if (this.model.readInputRegisters) {
1478
1505
  const bufferRx = Buffer.from(frame.data);
1479
1506
  const address = bufferRx.readUInt16BE(0);
1480
1507
  const length = bufferRx.readUInt16BE(2);
1481
1508
  if (length >= 0x0001 && length <= 0x007d) {
1482
- if (checkRange([address, address + length], (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.inputRegisters)) {
1509
+ if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).inputRegisters)) {
1483
1510
  Promise.resolve(this.model.readInputRegisters(address, length))
1484
1511
  .then((registers) => {
1485
1512
  const bufferTx = Buffer.alloc(length * 2);
@@ -1506,14 +1533,14 @@ class ModbusSlave extends EventEmitter {
1506
1533
  }
1507
1534
  }
1508
1535
  handleFC5(frame, response) {
1509
- var _a;
1536
+ var _a, _b;
1510
1537
  if (frame.data.length === 4) {
1511
1538
  if (this.model.writeSingleCoil) {
1512
1539
  const bufferRx = Buffer.from(frame.data);
1513
1540
  const address = bufferRx.readUInt16BE(0);
1514
1541
  const value = bufferRx.readUInt16BE(2);
1515
1542
  if (value === 0x0000 || value === 0xff00) {
1516
- if (checkRange(address, (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.coils)) {
1543
+ if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1517
1544
  Promise.resolve(this.model.writeSingleCoil(address, value === 0xff00))
1518
1545
  .then(() => {
1519
1546
  response(this.applicationLayer.encode(frame));
@@ -1536,14 +1563,14 @@ class ModbusSlave extends EventEmitter {
1536
1563
  }
1537
1564
  }
1538
1565
  handleFC6(frame, response) {
1539
- var _a;
1566
+ var _a, _b;
1540
1567
  if (frame.data.length === 4) {
1541
1568
  if (this.model.writeSingleRegister) {
1542
1569
  const bufferRx = Buffer.from(frame.data);
1543
1570
  const address = bufferRx.readUInt16BE(0);
1544
1571
  const value = bufferRx.readUInt16BE(2);
1545
1572
  if (value >= 0x0000 && value <= 0xffff) {
1546
- if (checkRange(address, (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.holdingRegisters)) {
1573
+ if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1547
1574
  Promise.resolve(this.model.writeSingleRegister(address, value))
1548
1575
  .then(() => {
1549
1576
  response(this.applicationLayer.encode(frame));
@@ -1566,7 +1593,7 @@ class ModbusSlave extends EventEmitter {
1566
1593
  }
1567
1594
  }
1568
1595
  handleFC15(frame, response) {
1569
- var _a;
1596
+ var _a, _b;
1570
1597
  if (frame.data.length > 5 && frame.data.length === 5 + frame.data[4]) {
1571
1598
  if (this.model.writeMultipleCoils || this.model.writeSingleCoil) {
1572
1599
  const bufferRx = Buffer.from(frame.data);
@@ -1574,7 +1601,7 @@ class ModbusSlave extends EventEmitter {
1574
1601
  const length = bufferRx.readUInt16BE(2);
1575
1602
  const byteCount = bufferRx[4];
1576
1603
  if (length >= 0x0001 && length <= 0x07b0 && byteCount === Math.ceil(length / 8)) {
1577
- if (checkRange([address, address + length], (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.coils)) {
1604
+ if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1578
1605
  const value = Array.from({ length }).map((_, index) => (bufferRx[5 + ~~(index / 8)] & (1 << index % 8)) > 0);
1579
1606
  Promise.resolve(this.model.writeMultipleCoils
1580
1607
  ? this.model.writeMultipleCoils(address, value)
@@ -1600,7 +1627,7 @@ class ModbusSlave extends EventEmitter {
1600
1627
  }
1601
1628
  }
1602
1629
  handleFC16(frame, response) {
1603
- var _a;
1630
+ var _a, _b;
1604
1631
  if (frame.data.length > 5 && frame.data.length === 5 + frame.data[4]) {
1605
1632
  if (this.model.writeMultipleRegisters || this.model.writeSingleRegister) {
1606
1633
  const bufferRx = Buffer.from(frame.data);
@@ -1608,7 +1635,7 @@ class ModbusSlave extends EventEmitter {
1608
1635
  const length = bufferRx.readUInt16BE(2);
1609
1636
  const byteCount = bufferRx[4];
1610
1637
  if (length >= 0x0001 && length <= 0x007b && byteCount === length * 2) {
1611
- if (checkRange([address, address + length], (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.holdingRegisters)) {
1638
+ if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1612
1639
  const value = Array.from({ length }).map((_, index) => bufferRx.readUInt16BE(5 + index * 2));
1613
1640
  Promise.resolve(this.model.writeMultipleRegisters
1614
1641
  ? this.model.writeMultipleRegisters(address, value)
@@ -1650,14 +1677,14 @@ class ModbusSlave extends EventEmitter {
1650
1677
  }
1651
1678
  }
1652
1679
  handleFC22(frame, response) {
1653
- var _a;
1680
+ var _a, _b;
1654
1681
  if (frame.data.length === 6) {
1655
1682
  if (this.model.maskWriteRegister || (this.model.readHoldingRegisters && this.model.writeSingleRegister)) {
1656
1683
  const bufferRx = Buffer.from(frame.data);
1657
1684
  const address = bufferRx.readUInt16BE(0);
1658
1685
  const andMask = bufferRx.readUInt16BE(2);
1659
1686
  const orMask = bufferRx.readUInt16BE(4);
1660
- if (checkRange(address, (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.holdingRegisters)) {
1687
+ if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1661
1688
  Promise.resolve(this.model.maskWriteRegister
1662
1689
  ? this.model.maskWriteRegister(address, andMask, orMask)
1663
1690
  : Promise.resolve(this.model.readHoldingRegisters(address, 1)).then(([value]) => {
@@ -1680,7 +1707,7 @@ class ModbusSlave extends EventEmitter {
1680
1707
  }
1681
1708
  }
1682
1709
  handleFC23(frame, response) {
1683
- var _a;
1710
+ var _a, _b;
1684
1711
  if (frame.data.length > 9 && frame.data.length === 9 + frame.data[8]) {
1685
1712
  if (this.model.readHoldingRegisters && (this.model.writeMultipleRegisters || this.model.writeSingleRegister)) {
1686
1713
  const bufferRx = Buffer.from(frame.data);
@@ -1698,7 +1725,7 @@ class ModbusSlave extends EventEmitter {
1698
1725
  length.write >= 0x0001 &&
1699
1726
  length.write <= 0x0079 &&
1700
1727
  byteCount === length.write * 2) {
1701
- if (checkRange([address.read, address.read + length.read, address.write, address.write + length.write], (_a = this.model.addressRange) === null || _a === void 0 ? void 0 : _a.holdingRegisters)) {
1728
+ if (checkRange([address.read, address.read + length.read, address.write, address.write + length.write], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1702
1729
  const value = Array.from({ length: length.write }).map((_, index) => bufferRx.readUInt16BE(9 + index * 2));
1703
1730
  Promise.resolve(this.model.writeMultipleRegisters
1704
1731
  ? this.model.writeMultipleRegisters(address.write, value)
@@ -6,10 +6,7 @@ export declare class RtuApplicationLayer extends AbstractApplicationLayer {
6
6
  private _timerThreePointFive?;
7
7
  private _bufferRx;
8
8
  private _removeAllListeners;
9
- constructor(physicalLayer: SerialPhysicalLayer | TcpServerPhysicalLayer | TcpClientPhysicalLayer | UdpPhysicalLayer, serialFrameInterval?: {
10
- baudRate: number;
11
- bitsBetweenFrames?: number;
12
- });
9
+ constructor(physicalLayer: SerialPhysicalLayer | TcpServerPhysicalLayer | TcpClientPhysicalLayer | UdpPhysicalLayer, bitsBetweenFrames?: number);
13
10
  private framing;
14
11
  encode(data: ApplicationDataUnit): Buffer;
15
12
  destroy(): void;
@@ -1,6 +1,7 @@
1
1
  import EventEmitter from 'node:events';
2
2
  interface AbstractPhysicalLayerEvents {
3
3
  data: [data: Buffer, response: (data: Buffer) => Promise<void>];
4
+ write: [data: Buffer];
4
5
  error: [error: Error];
5
6
  close: [];
6
7
  }
@@ -28,8 +28,10 @@ export declare class SerialPhysicalLayer extends AbstractPhysicalLayer {
28
28
  TYPE: 'SERIAL' | 'NET';
29
29
  private _serialport;
30
30
  private _destroyed;
31
+ private _baudRate;
31
32
  get isOpen(): boolean;
32
33
  get destroyed(): boolean;
34
+ get baudRate(): number;
33
35
  constructor(options: SerialPhysicalLayerOptions);
34
36
  open(): Promise<void>;
35
37
  write(data: Buffer): Promise<void>;
@@ -33,11 +33,11 @@ export interface ModbusSlaveModel {
33
33
  readDeviceIdentification?: FConvertPromise<() => {
34
34
  [index: number]: string;
35
35
  }>;
36
- addressRange?: {
37
- discreteInputs?: [number, number];
38
- coils?: [number, number];
39
- inputRegisters?: [number, number];
40
- holdingRegisters?: [number, number];
36
+ getAddressRange?: () => {
37
+ discreteInputs?: [number, number] | [number, number][];
38
+ coils?: [number, number] | [number, number][];
39
+ inputRegisters?: [number, number] | [number, number][];
40
+ holdingRegisters?: [number, number] | [number, number][];
41
41
  };
42
42
  }
43
43
  interface ModbusSlaveEvents {
@@ -1,2 +1 @@
1
- export declare function checkRange(value: number, range?: [number, number]): boolean;
2
- export declare function checkRange(values: number[], range?: [number, number]): boolean;
1
+ export declare function checkRange(value: number | number[], range?: [number, number] | [number, number][]): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "njs-modbus",
3
- "version": "1.0.1",
3
+ "version": "1.2.0",
4
4
  "description": "A pure JavaScript implemetation of Modbus for NodeJS.",
5
5
  "keywords": [
6
6
  "modbus",