njs-modbus 1.3.4 → 1.4.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
@@ -66,6 +66,7 @@ npm install njs-modbus
66
66
  ### Modbus RTU Master
67
67
 
68
68
  ```typescript
69
+ import type { ModbusSlaveModel } from 'njs-modbus';
69
70
  import { SerialPhysicalLayer, RtuApplicationLayer, ModbusMaster } from 'njs-modbus';
70
71
 
71
72
  const physicalLayer = new SerialPhysicalLayer({ path: 'COM1', baudRate: 9600, dataBits: 8, parity: 'none', stopBits: 1 });
@@ -100,72 +101,70 @@ const MB_SERVER = {
100
101
 
101
102
  const physicalLayer = new SerialPhysicalLayer({ path: 'COM1', baudRate: 9600, dataBits: 8, parity: 'none', stopBits: 1 });
102
103
  const applicationLayer = new RtuApplicationLayer(physicalLayer);
104
+ const slave1: ModbusSlaveModel = {
105
+ readDiscreteInputs: (address, length) => {
106
+ return Array.from({ length }).map((_, i) => {
107
+ const discreteInput = MB_SERVER.discreteInputs.get(address + i);
108
+ if (typeof discreteInput === 'undefined') {
109
+ return false;
110
+ }
111
+ return discreteInput;
112
+ });
113
+ },
114
+
115
+ readCoils: (address, length) => {
116
+ return Array.from({ length }).map((_, i) => {
117
+ const coil = MB_SERVER.coils.get(address + i);
118
+ if (typeof coil === 'undefined') {
119
+ return false;
120
+ }
121
+ return coil;
122
+ });
123
+ },
124
+ writeSingleCoil: (address, value) => {
125
+ MB_SERVER.coils.set(address, value);
126
+ },
127
+
128
+ readInputRegisters: (address, length) => {
129
+ return Array.from({ length }).map((_, i) => {
130
+ const inputRegister = MB_SERVER.inputRegisters.get(address + i);
131
+ if (typeof inputRegister === 'undefined') {
132
+ return 0;
133
+ }
134
+ return inputRegister;
135
+ });
136
+ },
103
137
 
104
- const modbusSlave = new ModbusSlave(
105
- {
106
- readDiscreteInputs: (address, length) => {
107
- return Array.from({ length }).map((_, i) => {
108
- const discreteInput = MB_SERVER.discreteInputs.get(address + i);
109
- if (typeof discreteInput === 'undefined') {
110
- return false;
111
- }
112
- return discreteInput;
113
- });
114
- },
115
-
116
- readCoils: (address, length) => {
117
- return Array.from({ length }).map((_, i) => {
118
- const coil = MB_SERVER.coils.get(address + i);
119
- if (typeof coil === 'undefined') {
120
- return false;
121
- }
122
- return coil;
123
- });
124
- },
125
- writeSingleCoil: (address, value) => {
126
- MB_SERVER.coils.set(address, value);
127
- },
128
-
129
- readInputRegisters: (address, length) => {
130
- return Array.from({ length }).map((_, i) => {
131
- const inputRegister = MB_SERVER.inputRegisters.get(address + i);
132
- if (typeof inputRegister === 'undefined') {
133
- return 0;
134
- }
135
- return inputRegister;
136
- });
137
- },
138
-
139
- readHoldingRegisters: (address, length) => {
140
- return Array.from({ length }).map((_, i) => {
141
- const holdingRegister = MB_SERVER.holdingRegisters.get(address + i);
142
- if (typeof holdingRegister === 'undefined') {
143
- return 0;
144
- }
145
- return holdingRegister;
146
- });
147
- },
148
- writeSingleRegister: (address, value) => {
149
- MB_SERVER.holdingRegisters.set(address, value);
150
- },
151
-
152
- reportServerId: () => ({ additionalData: [1, 2, 3] }),
153
-
154
- readDeviceIdentification: () => ({
155
- 0x00: 'Basic:VendorName',
156
- 0x01: 'Basic:ProductCode',
157
- 0x02: 'Basic:MajorMinorRevision',
158
- 0x03: 'Regular:VendorUrl',
159
- 0x04: 'Regular:ProductName',
160
- 0x05: 'Regular:ModelName',
161
- 0x06: 'Regular:UserApplicationName',
162
- 0x80: 'Extended:Extended',
163
- 0xff: 'Extended:Extended',
164
- }),
138
+ readHoldingRegisters: (address, length) => {
139
+ return Array.from({ length }).map((_, i) => {
140
+ const holdingRegister = MB_SERVER.holdingRegisters.get(address + i);
141
+ if (typeof holdingRegister === 'undefined') {
142
+ return 0;
143
+ }
144
+ return holdingRegister;
145
+ });
146
+ },
147
+ writeSingleRegister: (address, value) => {
148
+ MB_SERVER.holdingRegisters.set(address, value);
165
149
  },
166
- applicationLayer,
167
- physicalLayer,
168
- );
150
+
151
+ reportServerId: () => ({ additionalData: [1, 2, 3] }),
152
+
153
+ readDeviceIdentification: () => ({
154
+ 0x00: 'Basic:VendorName',
155
+ 0x01: 'Basic:ProductCode',
156
+ 0x02: 'Basic:MajorMinorRevision',
157
+ 0x03: 'Regular:VendorUrl',
158
+ 0x04: 'Regular:ProductName',
159
+ 0x05: 'Regular:ModelName',
160
+ 0x06: 'Regular:UserApplicationName',
161
+ 0x80: 'Extended:Extended',
162
+ 0xff: 'Extended:Extended',
163
+ }),
164
+ };
165
+
166
+ const modbusSlave = new ModbusSlave(applicationLayer, physicalLayer);
167
+ modbusSlave.add(slave1);
169
168
 
170
169
  modbusSlave
171
170
  .open()
package/dist/index.cjs CHANGED
@@ -545,6 +545,7 @@ function lrc(data) {
545
545
  return (~data.reduce((sum, n) => sum + n, 0) + 1) & 0xff;
546
546
  }
547
547
 
548
+ const MAX_FRAME_LENGTH = 256;
548
549
  class RtuApplicationLayer extends AbstractApplicationLayer {
549
550
  constructor(physicalLayer,
550
551
  /**
@@ -609,11 +610,16 @@ class RtuApplicationLayer extends AbstractApplicationLayer {
609
610
  }
610
611
  });
611
612
  };
612
- if (threePointFiveT) {
613
- this._timerThreePointFive = setTimeout(handleData, threePointFiveT);
613
+ if (this._bufferRx.length >= MAX_FRAME_LENGTH) {
614
+ handleData();
614
615
  }
615
616
  else {
616
- handleData();
617
+ if (threePointFiveT) {
618
+ this._timerThreePointFive = setTimeout(handleData, threePointFiveT);
619
+ }
620
+ else {
621
+ handleData();
622
+ }
617
623
  }
618
624
  };
619
625
  physicalLayer.on('data', handleData);
@@ -1498,14 +1504,8 @@ class ModbusSlave extends EventEmitter {
1498
1504
  get destroyed() {
1499
1505
  return this.physicalLayer.destroyed;
1500
1506
  }
1501
- constructor(model, applicationLayer, physicalLayer) {
1507
+ constructor(applicationLayer, physicalLayer) {
1502
1508
  super();
1503
- Object.defineProperty(this, "model", {
1504
- enumerable: true,
1505
- configurable: true,
1506
- writable: true,
1507
- value: model
1508
- });
1509
1509
  Object.defineProperty(this, "applicationLayer", {
1510
1510
  enumerable: true,
1511
1511
  configurable: true,
@@ -1518,17 +1518,14 @@ class ModbusSlave extends EventEmitter {
1518
1518
  writable: true,
1519
1519
  value: physicalLayer
1520
1520
  });
1521
- Object.defineProperty(this, "unit", {
1521
+ Object.defineProperty(this, "models", {
1522
1522
  enumerable: true,
1523
1523
  configurable: true,
1524
1524
  writable: true,
1525
- value: 1
1525
+ value: new Map()
1526
1526
  });
1527
- if (typeof model.unit !== 'undefined') {
1528
- this.unit = model.unit;
1529
- }
1530
- applicationLayer.on('framing', (frame, _response) => __awaiter(this, void 0, void 0, function* () {
1531
- if (!(frame.unit === 0x00 || frame.unit === this.unit)) {
1527
+ applicationLayer.on('framing', (frame, _response) => {
1528
+ if (!(frame.unit === 0x00 || this.models.has(frame.unit))) {
1532
1529
  return;
1533
1530
  }
1534
1531
  const response = (data) => __awaiter(this, void 0, void 0, function* () {
@@ -1540,74 +1537,85 @@ class ModbusSlave extends EventEmitter {
1540
1537
  }
1541
1538
  catch (error) { }
1542
1539
  });
1543
- if (model.interceptor) {
1544
- try {
1545
- const data = yield model.interceptor(frame.fc, frame.data);
1546
- if (data) {
1547
- response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data })));
1548
- return;
1540
+ const intercept = (model) => __awaiter(this, void 0, void 0, function* () {
1541
+ if (model.interceptor) {
1542
+ try {
1543
+ const data = yield model.interceptor(frame.fc, frame.data);
1544
+ if (data) {
1545
+ response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data })));
1546
+ return 'break';
1547
+ }
1548
+ }
1549
+ catch (error) {
1550
+ this.responseError(frame, response, error);
1551
+ return 'break';
1549
1552
  }
1550
1553
  }
1551
- catch (error) {
1552
- this.responseError(frame, response, error);
1553
- return;
1554
- }
1555
- }
1556
- switch (frame.fc) {
1557
- case 0x01: {
1558
- this.handleFC1(frame, response);
1559
- break;
1560
- }
1561
- case 0x02: {
1562
- this.handleFC2(frame, response);
1563
- break;
1564
- }
1565
- case 0x03: {
1566
- this.handleFC3(frame, response);
1567
- break;
1568
- }
1569
- case 0x04: {
1570
- this.handleFC4(frame, response);
1571
- break;
1572
- }
1573
- case 0x05: {
1574
- this.handleFC5(frame, response);
1575
- break;
1576
- }
1577
- case 0x06: {
1578
- this.handleFC6(frame, response);
1579
- break;
1580
- }
1581
- case 0x0f: {
1582
- this.handleFC15(frame, response);
1583
- break;
1584
- }
1585
- case 0x10: {
1586
- this.handleFC16(frame, response);
1587
- break;
1588
- }
1589
- case 0x11: {
1590
- this.handleFC17(frame, response);
1591
- break;
1592
- }
1593
- case 0x16: {
1594
- this.handleFC22(frame, response);
1595
- break;
1596
- }
1597
- case 0x17: {
1598
- this.handleFC23(frame, response);
1599
- break;
1600
- }
1601
- case 0x2b: {
1602
- this.handleFC43_14(frame, response);
1603
- break;
1604
- }
1605
- default: {
1606
- this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
1607
- break;
1554
+ });
1555
+ const handleFC = (model) => {
1556
+ switch (frame.fc) {
1557
+ case 0x01: {
1558
+ this.handleFC1(model, frame, response);
1559
+ break;
1560
+ }
1561
+ case 0x02: {
1562
+ this.handleFC2(model, frame, response);
1563
+ break;
1564
+ }
1565
+ case 0x03: {
1566
+ this.handleFC3(model, frame, response);
1567
+ break;
1568
+ }
1569
+ case 0x04: {
1570
+ this.handleFC4(model, frame, response);
1571
+ break;
1572
+ }
1573
+ case 0x05: {
1574
+ this.handleFC5(model, frame, response);
1575
+ break;
1576
+ }
1577
+ case 0x06: {
1578
+ this.handleFC6(model, frame, response);
1579
+ break;
1580
+ }
1581
+ case 0x0f: {
1582
+ this.handleFC15(model, frame, response);
1583
+ break;
1584
+ }
1585
+ case 0x10: {
1586
+ this.handleFC16(model, frame, response);
1587
+ break;
1588
+ }
1589
+ case 0x11: {
1590
+ this.handleFC17(model, frame, response);
1591
+ break;
1592
+ }
1593
+ case 0x16: {
1594
+ this.handleFC22(model, frame, response);
1595
+ break;
1596
+ }
1597
+ case 0x17: {
1598
+ this.handleFC23(model, frame, response);
1599
+ break;
1600
+ }
1601
+ case 0x2b: {
1602
+ this.handleFC43_14(model, frame, response);
1603
+ break;
1604
+ }
1605
+ default: {
1606
+ this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
1607
+ break;
1608
+ }
1608
1609
  }
1610
+ };
1611
+ for (const model of frame.unit === 0x00 ? this.models.values() : [this.models.get(frame.unit)]) {
1612
+ intercept(model).then((res) => {
1613
+ if (res !== 'break') {
1614
+ handleFC(model);
1615
+ }
1616
+ });
1609
1617
  }
1610
- }));
1618
+ });
1611
1619
  physicalLayer.on('error', (error) => {
1612
1620
  this.emit('error', error);
1613
1621
  });
@@ -1615,16 +1623,16 @@ class ModbusSlave extends EventEmitter {
1615
1623
  this.emit('close');
1616
1624
  });
1617
1625
  }
1618
- handleFC1(frame, response) {
1619
- var _a, _b;
1626
+ handleFC1(model, frame, response) {
1627
+ var _a;
1620
1628
  if (frame.data.length === 4) {
1621
- if (this.model.readCoils) {
1629
+ if (model.readCoils) {
1622
1630
  const bufferRx = Buffer.from(frame.data);
1623
1631
  const address = bufferRx.readUInt16BE(0);
1624
1632
  const length = bufferRx.readUInt16BE(2);
1625
1633
  if (length >= 0x0001 && length <= 0x07d0) {
1626
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1627
- Promise.resolve(this.model.readCoils(address, length))
1634
+ if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).coils)) {
1635
+ Promise.resolve(model.readCoils(address, length))
1628
1636
  .then((coils) => {
1629
1637
  const bufferTx = Buffer.alloc(Math.ceil(length / 8));
1630
1638
  coils.forEach((coil, index) => {
@@ -1651,16 +1659,16 @@ class ModbusSlave extends EventEmitter {
1651
1659
  }
1652
1660
  }
1653
1661
  }
1654
- handleFC2(frame, response) {
1655
- var _a, _b;
1662
+ handleFC2(model, frame, response) {
1663
+ var _a;
1656
1664
  if (frame.data.length === 4) {
1657
- if (this.model.readDiscreteInputs) {
1665
+ if (model.readDiscreteInputs) {
1658
1666
  const bufferRx = Buffer.from(frame.data);
1659
1667
  const address = bufferRx.readUInt16BE(0);
1660
1668
  const length = bufferRx.readUInt16BE(2);
1661
1669
  if (length >= 0x0001 && length <= 0x07d0) {
1662
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).discreteInputs)) {
1663
- Promise.resolve(this.model.readDiscreteInputs(address, length))
1670
+ if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).discreteInputs)) {
1671
+ Promise.resolve(model.readDiscreteInputs(address, length))
1664
1672
  .then((discreteInputs) => {
1665
1673
  const bufferTx = Buffer.alloc(Math.ceil(length / 8));
1666
1674
  discreteInputs.forEach((discreteInput, index) => {
@@ -1687,16 +1695,16 @@ class ModbusSlave extends EventEmitter {
1687
1695
  }
1688
1696
  }
1689
1697
  }
1690
- handleFC3(frame, response) {
1691
- var _a, _b;
1698
+ handleFC3(model, frame, response) {
1699
+ var _a;
1692
1700
  if (frame.data.length === 4) {
1693
- if (this.model.readHoldingRegisters) {
1701
+ if (model.readHoldingRegisters) {
1694
1702
  const bufferRx = Buffer.from(frame.data);
1695
1703
  const address = bufferRx.readUInt16BE(0);
1696
1704
  const length = bufferRx.readUInt16BE(2);
1697
1705
  if (length >= 0x0001 && length <= 0x007d) {
1698
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1699
- Promise.resolve(this.model.readHoldingRegisters(address, length))
1706
+ if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
1707
+ Promise.resolve(model.readHoldingRegisters(address, length))
1700
1708
  .then((registers) => {
1701
1709
  const bufferTx = Buffer.alloc(length * 2);
1702
1710
  registers.forEach((register, index) => {
@@ -1721,16 +1729,16 @@ class ModbusSlave extends EventEmitter {
1721
1729
  }
1722
1730
  }
1723
1731
  }
1724
- handleFC4(frame, response) {
1725
- var _a, _b;
1732
+ handleFC4(model, frame, response) {
1733
+ var _a;
1726
1734
  if (frame.data.length === 4) {
1727
- if (this.model.readInputRegisters) {
1735
+ if (model.readInputRegisters) {
1728
1736
  const bufferRx = Buffer.from(frame.data);
1729
1737
  const address = bufferRx.readUInt16BE(0);
1730
1738
  const length = bufferRx.readUInt16BE(2);
1731
1739
  if (length >= 0x0001 && length <= 0x007d) {
1732
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).inputRegisters)) {
1733
- Promise.resolve(this.model.readInputRegisters(address, length))
1740
+ if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).inputRegisters)) {
1741
+ Promise.resolve(model.readInputRegisters(address, length))
1734
1742
  .then((registers) => {
1735
1743
  const bufferTx = Buffer.alloc(length * 2);
1736
1744
  registers.forEach((register, index) => {
@@ -1755,16 +1763,16 @@ class ModbusSlave extends EventEmitter {
1755
1763
  }
1756
1764
  }
1757
1765
  }
1758
- handleFC5(frame, response) {
1759
- var _a, _b;
1766
+ handleFC5(model, frame, response) {
1767
+ var _a;
1760
1768
  if (frame.data.length === 4) {
1761
- if (this.model.writeSingleCoil) {
1769
+ if (model.writeSingleCoil) {
1762
1770
  const bufferRx = Buffer.from(frame.data);
1763
1771
  const address = bufferRx.readUInt16BE(0);
1764
1772
  const value = bufferRx.readUInt16BE(2);
1765
1773
  if (value === 0x0000 || value === 0xff00) {
1766
- if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1767
- Promise.resolve(this.model.writeSingleCoil(address, value === 0xff00))
1774
+ if (checkRange(address, (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).coils)) {
1775
+ Promise.resolve(model.writeSingleCoil(address, value === 0xff00))
1768
1776
  .then(() => {
1769
1777
  response(this.applicationLayer.encode(frame));
1770
1778
  })
@@ -1785,16 +1793,16 @@ class ModbusSlave extends EventEmitter {
1785
1793
  }
1786
1794
  }
1787
1795
  }
1788
- handleFC6(frame, response) {
1789
- var _a, _b;
1796
+ handleFC6(model, frame, response) {
1797
+ var _a;
1790
1798
  if (frame.data.length === 4) {
1791
- if (this.model.writeSingleRegister) {
1799
+ if (model.writeSingleRegister) {
1792
1800
  const bufferRx = Buffer.from(frame.data);
1793
1801
  const address = bufferRx.readUInt16BE(0);
1794
1802
  const value = bufferRx.readUInt16BE(2);
1795
1803
  if (value >= 0x0000 && value <= 0xffff) {
1796
- if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1797
- Promise.resolve(this.model.writeSingleRegister(address, value))
1804
+ if (checkRange(address, (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
1805
+ Promise.resolve(model.writeSingleRegister(address, value))
1798
1806
  .then(() => {
1799
1807
  response(this.applicationLayer.encode(frame));
1800
1808
  })
@@ -1815,20 +1823,20 @@ class ModbusSlave extends EventEmitter {
1815
1823
  }
1816
1824
  }
1817
1825
  }
1818
- handleFC15(frame, response) {
1819
- var _a, _b;
1826
+ handleFC15(model, frame, response) {
1827
+ var _a;
1820
1828
  if (frame.data.length > 5 && frame.data.length === 5 + frame.data[4]) {
1821
- if (this.model.writeMultipleCoils || this.model.writeSingleCoil) {
1829
+ if (model.writeMultipleCoils || model.writeSingleCoil) {
1822
1830
  const bufferRx = Buffer.from(frame.data);
1823
1831
  const address = bufferRx.readUInt16BE(0);
1824
1832
  const length = bufferRx.readUInt16BE(2);
1825
1833
  const byteCount = bufferRx[4];
1826
1834
  if (length >= 0x0001 && length <= 0x07b0 && byteCount === Math.ceil(length / 8)) {
1827
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1835
+ if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).coils)) {
1828
1836
  const value = Array.from({ length }).map((_, index) => (bufferRx[5 + ~~(index / 8)] & (1 << index % 8)) > 0);
1829
- Promise.resolve(this.model.writeMultipleCoils
1830
- ? this.model.writeMultipleCoils(address, value)
1831
- : Promise.all(value.map((v, i) => this.model.writeSingleCoil(address + i, v))))
1837
+ Promise.resolve(model.writeMultipleCoils
1838
+ ? model.writeMultipleCoils(address, value)
1839
+ : Promise.all(value.map((v, i) => model.writeSingleCoil(address + i, v))))
1832
1840
  .then(() => {
1833
1841
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: Array.from(bufferRx).slice(0, 4) })));
1834
1842
  })
@@ -1849,20 +1857,20 @@ class ModbusSlave extends EventEmitter {
1849
1857
  }
1850
1858
  }
1851
1859
  }
1852
- handleFC16(frame, response) {
1853
- var _a, _b;
1860
+ handleFC16(model, frame, response) {
1861
+ var _a;
1854
1862
  if (frame.data.length > 5 && frame.data.length === 5 + frame.data[4]) {
1855
- if (this.model.writeMultipleRegisters || this.model.writeSingleRegister) {
1863
+ if (model.writeMultipleRegisters || model.writeSingleRegister) {
1856
1864
  const bufferRx = Buffer.from(frame.data);
1857
1865
  const address = bufferRx.readUInt16BE(0);
1858
1866
  const length = bufferRx.readUInt16BE(2);
1859
1867
  const byteCount = bufferRx[4];
1860
1868
  if (length >= 0x0001 && length <= 0x007b && byteCount === length * 2) {
1861
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1869
+ if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
1862
1870
  const value = Array.from({ length }).map((_, index) => bufferRx.readUInt16BE(5 + index * 2));
1863
- Promise.resolve(this.model.writeMultipleRegisters
1864
- ? this.model.writeMultipleRegisters(address, value)
1865
- : Promise.all(value.map((v, i) => this.model.writeSingleRegister(address + i, v))))
1871
+ Promise.resolve(model.writeMultipleRegisters
1872
+ ? model.writeMultipleRegisters(address, value)
1873
+ : Promise.all(value.map((v, i) => model.writeSingleRegister(address + i, v))))
1866
1874
  .then(() => {
1867
1875
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: Array.from(bufferRx).slice(0, 4) })));
1868
1876
  })
@@ -1883,11 +1891,13 @@ class ModbusSlave extends EventEmitter {
1883
1891
  }
1884
1892
  }
1885
1893
  }
1886
- handleFC17(frame, response) {
1894
+ handleFC17(model, frame, response) {
1887
1895
  if (frame.data.length === 0) {
1888
- if (this.model.reportServerId) {
1889
- Promise.resolve(this.model.reportServerId())
1890
- .then(({ serverId = this.unit, runIndicatorStatus = true, additionalData = [] }) => {
1896
+ if (model.reportServerId) {
1897
+ Promise.resolve(model.reportServerId())
1898
+ .then((_a) => {
1899
+ var _b;
1900
+ var { serverId = (_b = model.unit) !== null && _b !== void 0 ? _b : 1, runIndicatorStatus = true, additionalData = [] } = _a;
1891
1901
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: [2 + additionalData.length, serverId, runIndicatorStatus ? 0xff : 0x00].concat(additionalData) })));
1892
1902
  })
1893
1903
  .catch((error) => {
@@ -1899,19 +1909,19 @@ class ModbusSlave extends EventEmitter {
1899
1909
  }
1900
1910
  }
1901
1911
  }
1902
- handleFC22(frame, response) {
1903
- var _a, _b;
1912
+ handleFC22(model, frame, response) {
1913
+ var _a;
1904
1914
  if (frame.data.length === 6) {
1905
- if (this.model.maskWriteRegister || (this.model.readHoldingRegisters && this.model.writeSingleRegister)) {
1915
+ if (model.maskWriteRegister || (model.readHoldingRegisters && model.writeSingleRegister)) {
1906
1916
  const bufferRx = Buffer.from(frame.data);
1907
1917
  const address = bufferRx.readUInt16BE(0);
1908
1918
  const andMask = bufferRx.readUInt16BE(2);
1909
1919
  const orMask = bufferRx.readUInt16BE(4);
1910
- if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1911
- Promise.resolve(this.model.maskWriteRegister
1912
- ? this.model.maskWriteRegister(address, andMask, orMask)
1913
- : Promise.resolve(this.model.readHoldingRegisters(address, 1)).then(([value]) => {
1914
- return Promise.resolve(this.model.writeSingleRegister(address, (value & andMask) | (orMask & (~andMask & 0xff))));
1920
+ if (checkRange(address, (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
1921
+ Promise.resolve(model.maskWriteRegister
1922
+ ? model.maskWriteRegister(address, andMask, orMask)
1923
+ : Promise.resolve(model.readHoldingRegisters(address, 1)).then(([value]) => {
1924
+ return Promise.resolve(model.writeSingleRegister(address, (value & andMask) | (orMask & (~andMask & 0xff))));
1915
1925
  }))
1916
1926
  .then(() => {
1917
1927
  response(this.applicationLayer.encode(frame));
@@ -1929,10 +1939,10 @@ class ModbusSlave extends EventEmitter {
1929
1939
  }
1930
1940
  }
1931
1941
  }
1932
- handleFC23(frame, response) {
1933
- var _a, _b;
1942
+ handleFC23(model, frame, response) {
1943
+ var _a;
1934
1944
  if (frame.data.length > 9 && frame.data.length === 9 + frame.data[8]) {
1935
- if (this.model.readHoldingRegisters && (this.model.writeMultipleRegisters || this.model.writeSingleRegister)) {
1945
+ if (model.readHoldingRegisters && (model.writeMultipleRegisters || model.writeSingleRegister)) {
1936
1946
  const bufferRx = Buffer.from(frame.data);
1937
1947
  const address = {
1938
1948
  read: bufferRx.readUInt16BE(0),
@@ -1948,12 +1958,12 @@ class ModbusSlave extends EventEmitter {
1948
1958
  length.write >= 0x0001 &&
1949
1959
  length.write <= 0x0079 &&
1950
1960
  byteCount === length.write * 2) {
1951
- 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)) {
1961
+ if (checkRange([address.read, address.read + length.read, address.write, address.write + length.write], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
1952
1962
  const value = Array.from({ length: length.write }).map((_, index) => bufferRx.readUInt16BE(9 + index * 2));
1953
- Promise.resolve(this.model.writeMultipleRegisters
1954
- ? this.model.writeMultipleRegisters(address.write, value)
1955
- : Promise.all(value.map((v, i) => this.model.writeSingleRegister(address.write + i, v))))
1956
- .then(() => Promise.resolve(this.model.readHoldingRegisters(address.read, length.read)))
1963
+ Promise.resolve(model.writeMultipleRegisters
1964
+ ? model.writeMultipleRegisters(address.write, value)
1965
+ : Promise.all(value.map((v, i) => model.writeSingleRegister(address.write + i, v))))
1966
+ .then(() => Promise.resolve(model.readHoldingRegisters(address.read, length.read)))
1957
1967
  .then((registers) => {
1958
1968
  const bufferTx = Buffer.alloc(length.read * 2);
1959
1969
  registers.forEach((register, index) => {
@@ -1978,9 +1988,9 @@ class ModbusSlave extends EventEmitter {
1978
1988
  }
1979
1989
  }
1980
1990
  }
1981
- handleFC43_14(frame, response) {
1991
+ handleFC43_14(model, frame, response) {
1982
1992
  if (frame.data.length === 3) {
1983
- if (frame.data[0] === 0x0e && this.model.readDeviceIdentification) {
1993
+ if (frame.data[0] === 0x0e && model.readDeviceIdentification) {
1984
1994
  const readDeviceIDCode = frame.data[1];
1985
1995
  let objectID = frame.data[2];
1986
1996
  switch (readDeviceIDCode) {
@@ -2014,7 +2024,7 @@ class ModbusSlave extends EventEmitter {
2014
2024
  return;
2015
2025
  }
2016
2026
  }
2017
- Promise.resolve(this.model.readDeviceIdentification())
2027
+ Promise.resolve(model.readDeviceIdentification())
2018
2028
  .then((identification) => {
2019
2029
  const objects = new Map([
2020
2030
  [0x00, 'null'],
@@ -2092,6 +2102,13 @@ class ModbusSlave extends EventEmitter {
2092
2102
  responseError(frame, response, error) {
2093
2103
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { fc: frame.fc | 0x80, data: [getCodeByError(error)] })));
2094
2104
  }
2105
+ add(model) {
2106
+ var _a;
2107
+ this.models.set((_a = model.unit) !== null && _a !== void 0 ? _a : 1, model);
2108
+ }
2109
+ remove(unit) {
2110
+ this.models.delete(unit);
2111
+ }
2095
2112
  open(...args) {
2096
2113
  return this.physicalLayer.open(...args);
2097
2114
  }
package/dist/index.d.ts CHANGED
@@ -342,13 +342,12 @@ interface ModbusSlaveEvents {
342
342
  close: [];
343
343
  }
344
344
  declare class ModbusSlave<A extends AbstractApplicationLayer, P extends AbstractPhysicalLayer> extends EventEmitter<ModbusSlaveEvents> {
345
- private model;
346
345
  private applicationLayer;
347
346
  private physicalLayer;
348
- unit: number;
347
+ models: Map<number, ModbusSlaveModel>;
349
348
  get isOpen(): boolean;
350
349
  get destroyed(): boolean;
351
- constructor(model: ModbusSlaveModel, applicationLayer: A, physicalLayer: P);
350
+ constructor(applicationLayer: A, physicalLayer: P);
352
351
  private handleFC1;
353
352
  private handleFC2;
354
353
  private handleFC3;
@@ -362,6 +361,8 @@ declare class ModbusSlave<A extends AbstractApplicationLayer, P extends Abstract
362
361
  private handleFC23;
363
362
  private handleFC43_14;
364
363
  private responseError;
364
+ add(model: ModbusSlaveModel): void;
365
+ remove(unit: number): void;
365
366
  open(...args: Parameters<P['open']>): Promise<void>;
366
367
  close(): Promise<void>;
367
368
  destroy(): Promise<void>;
package/dist/index.mjs CHANGED
@@ -543,6 +543,7 @@ function lrc(data) {
543
543
  return (~data.reduce((sum, n) => sum + n, 0) + 1) & 0xff;
544
544
  }
545
545
 
546
+ const MAX_FRAME_LENGTH = 256;
546
547
  class RtuApplicationLayer extends AbstractApplicationLayer {
547
548
  constructor(physicalLayer,
548
549
  /**
@@ -607,11 +608,16 @@ class RtuApplicationLayer extends AbstractApplicationLayer {
607
608
  }
608
609
  });
609
610
  };
610
- if (threePointFiveT) {
611
- this._timerThreePointFive = setTimeout(handleData, threePointFiveT);
611
+ if (this._bufferRx.length >= MAX_FRAME_LENGTH) {
612
+ handleData();
612
613
  }
613
614
  else {
614
- handleData();
615
+ if (threePointFiveT) {
616
+ this._timerThreePointFive = setTimeout(handleData, threePointFiveT);
617
+ }
618
+ else {
619
+ handleData();
620
+ }
615
621
  }
616
622
  };
617
623
  physicalLayer.on('data', handleData);
@@ -1496,14 +1502,8 @@ class ModbusSlave extends EventEmitter {
1496
1502
  get destroyed() {
1497
1503
  return this.physicalLayer.destroyed;
1498
1504
  }
1499
- constructor(model, applicationLayer, physicalLayer) {
1505
+ constructor(applicationLayer, physicalLayer) {
1500
1506
  super();
1501
- Object.defineProperty(this, "model", {
1502
- enumerable: true,
1503
- configurable: true,
1504
- writable: true,
1505
- value: model
1506
- });
1507
1507
  Object.defineProperty(this, "applicationLayer", {
1508
1508
  enumerable: true,
1509
1509
  configurable: true,
@@ -1516,17 +1516,14 @@ class ModbusSlave extends EventEmitter {
1516
1516
  writable: true,
1517
1517
  value: physicalLayer
1518
1518
  });
1519
- Object.defineProperty(this, "unit", {
1519
+ Object.defineProperty(this, "models", {
1520
1520
  enumerable: true,
1521
1521
  configurable: true,
1522
1522
  writable: true,
1523
- value: 1
1523
+ value: new Map()
1524
1524
  });
1525
- if (typeof model.unit !== 'undefined') {
1526
- this.unit = model.unit;
1527
- }
1528
- applicationLayer.on('framing', (frame, _response) => __awaiter(this, void 0, void 0, function* () {
1529
- if (!(frame.unit === 0x00 || frame.unit === this.unit)) {
1525
+ applicationLayer.on('framing', (frame, _response) => {
1526
+ if (!(frame.unit === 0x00 || this.models.has(frame.unit))) {
1530
1527
  return;
1531
1528
  }
1532
1529
  const response = (data) => __awaiter(this, void 0, void 0, function* () {
@@ -1538,74 +1535,85 @@ class ModbusSlave extends EventEmitter {
1538
1535
  }
1539
1536
  catch (error) { }
1540
1537
  });
1541
- if (model.interceptor) {
1542
- try {
1543
- const data = yield model.interceptor(frame.fc, frame.data);
1544
- if (data) {
1545
- response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data })));
1546
- return;
1538
+ const intercept = (model) => __awaiter(this, void 0, void 0, function* () {
1539
+ if (model.interceptor) {
1540
+ try {
1541
+ const data = yield model.interceptor(frame.fc, frame.data);
1542
+ if (data) {
1543
+ response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data })));
1544
+ return 'break';
1545
+ }
1546
+ }
1547
+ catch (error) {
1548
+ this.responseError(frame, response, error);
1549
+ return 'break';
1547
1550
  }
1548
1551
  }
1549
- catch (error) {
1550
- this.responseError(frame, response, error);
1551
- return;
1552
- }
1553
- }
1554
- switch (frame.fc) {
1555
- case 0x01: {
1556
- this.handleFC1(frame, response);
1557
- break;
1558
- }
1559
- case 0x02: {
1560
- this.handleFC2(frame, response);
1561
- break;
1562
- }
1563
- case 0x03: {
1564
- this.handleFC3(frame, response);
1565
- break;
1566
- }
1567
- case 0x04: {
1568
- this.handleFC4(frame, response);
1569
- break;
1570
- }
1571
- case 0x05: {
1572
- this.handleFC5(frame, response);
1573
- break;
1574
- }
1575
- case 0x06: {
1576
- this.handleFC6(frame, response);
1577
- break;
1578
- }
1579
- case 0x0f: {
1580
- this.handleFC15(frame, response);
1581
- break;
1582
- }
1583
- case 0x10: {
1584
- this.handleFC16(frame, response);
1585
- break;
1586
- }
1587
- case 0x11: {
1588
- this.handleFC17(frame, response);
1589
- break;
1590
- }
1591
- case 0x16: {
1592
- this.handleFC22(frame, response);
1593
- break;
1594
- }
1595
- case 0x17: {
1596
- this.handleFC23(frame, response);
1597
- break;
1598
- }
1599
- case 0x2b: {
1600
- this.handleFC43_14(frame, response);
1601
- break;
1602
- }
1603
- default: {
1604
- this.responseError(frame, response, getErrorByCode(ErrorCode.ILLEGAL_FUNCTION));
1605
- break;
1552
+ });
1553
+ const handleFC = (model) => {
1554
+ switch (frame.fc) {
1555
+ case 0x01: {
1556
+ this.handleFC1(model, frame, response);
1557
+ break;
1558
+ }
1559
+ case 0x02: {
1560
+ this.handleFC2(model, frame, response);
1561
+ break;
1562
+ }
1563
+ case 0x03: {
1564
+ this.handleFC3(model, frame, response);
1565
+ break;
1566
+ }
1567
+ case 0x04: {
1568
+ this.handleFC4(model, frame, response);
1569
+ break;
1570
+ }
1571
+ case 0x05: {
1572
+ this.handleFC5(model, frame, response);
1573
+ break;
1574
+ }
1575
+ case 0x06: {
1576
+ this.handleFC6(model, frame, response);
1577
+ break;
1578
+ }
1579
+ case 0x0f: {
1580
+ this.handleFC15(model, frame, response);
1581
+ break;
1582
+ }
1583
+ case 0x10: {
1584
+ this.handleFC16(model, frame, response);
1585
+ break;
1586
+ }
1587
+ case 0x11: {
1588
+ this.handleFC17(model, frame, response);
1589
+ break;
1590
+ }
1591
+ case 0x16: {
1592
+ this.handleFC22(model, frame, response);
1593
+ break;
1594
+ }
1595
+ case 0x17: {
1596
+ this.handleFC23(model, frame, response);
1597
+ break;
1598
+ }
1599
+ case 0x2b: {
1600
+ this.handleFC43_14(model, frame, response);
1601
+ break;
1602
+ }
1603
+ default: {
1604
+ this.responseError(frame, response, getErrorByCode(ErrorCode.ILLEGAL_FUNCTION));
1605
+ break;
1606
+ }
1606
1607
  }
1608
+ };
1609
+ for (const model of frame.unit === 0x00 ? this.models.values() : [this.models.get(frame.unit)]) {
1610
+ intercept(model).then((res) => {
1611
+ if (res !== 'break') {
1612
+ handleFC(model);
1613
+ }
1614
+ });
1607
1615
  }
1608
- }));
1616
+ });
1609
1617
  physicalLayer.on('error', (error) => {
1610
1618
  this.emit('error', error);
1611
1619
  });
@@ -1613,16 +1621,16 @@ class ModbusSlave extends EventEmitter {
1613
1621
  this.emit('close');
1614
1622
  });
1615
1623
  }
1616
- handleFC1(frame, response) {
1617
- var _a, _b;
1624
+ handleFC1(model, frame, response) {
1625
+ var _a;
1618
1626
  if (frame.data.length === 4) {
1619
- if (this.model.readCoils) {
1627
+ if (model.readCoils) {
1620
1628
  const bufferRx = Buffer.from(frame.data);
1621
1629
  const address = bufferRx.readUInt16BE(0);
1622
1630
  const length = bufferRx.readUInt16BE(2);
1623
1631
  if (length >= 0x0001 && length <= 0x07d0) {
1624
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1625
- Promise.resolve(this.model.readCoils(address, length))
1632
+ if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).coils)) {
1633
+ Promise.resolve(model.readCoils(address, length))
1626
1634
  .then((coils) => {
1627
1635
  const bufferTx = Buffer.alloc(Math.ceil(length / 8));
1628
1636
  coils.forEach((coil, index) => {
@@ -1649,16 +1657,16 @@ class ModbusSlave extends EventEmitter {
1649
1657
  }
1650
1658
  }
1651
1659
  }
1652
- handleFC2(frame, response) {
1653
- var _a, _b;
1660
+ handleFC2(model, frame, response) {
1661
+ var _a;
1654
1662
  if (frame.data.length === 4) {
1655
- if (this.model.readDiscreteInputs) {
1663
+ if (model.readDiscreteInputs) {
1656
1664
  const bufferRx = Buffer.from(frame.data);
1657
1665
  const address = bufferRx.readUInt16BE(0);
1658
1666
  const length = bufferRx.readUInt16BE(2);
1659
1667
  if (length >= 0x0001 && length <= 0x07d0) {
1660
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).discreteInputs)) {
1661
- Promise.resolve(this.model.readDiscreteInputs(address, length))
1668
+ if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).discreteInputs)) {
1669
+ Promise.resolve(model.readDiscreteInputs(address, length))
1662
1670
  .then((discreteInputs) => {
1663
1671
  const bufferTx = Buffer.alloc(Math.ceil(length / 8));
1664
1672
  discreteInputs.forEach((discreteInput, index) => {
@@ -1685,16 +1693,16 @@ class ModbusSlave extends EventEmitter {
1685
1693
  }
1686
1694
  }
1687
1695
  }
1688
- handleFC3(frame, response) {
1689
- var _a, _b;
1696
+ handleFC3(model, frame, response) {
1697
+ var _a;
1690
1698
  if (frame.data.length === 4) {
1691
- if (this.model.readHoldingRegisters) {
1699
+ if (model.readHoldingRegisters) {
1692
1700
  const bufferRx = Buffer.from(frame.data);
1693
1701
  const address = bufferRx.readUInt16BE(0);
1694
1702
  const length = bufferRx.readUInt16BE(2);
1695
1703
  if (length >= 0x0001 && length <= 0x007d) {
1696
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1697
- Promise.resolve(this.model.readHoldingRegisters(address, length))
1704
+ if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
1705
+ Promise.resolve(model.readHoldingRegisters(address, length))
1698
1706
  .then((registers) => {
1699
1707
  const bufferTx = Buffer.alloc(length * 2);
1700
1708
  registers.forEach((register, index) => {
@@ -1719,16 +1727,16 @@ class ModbusSlave extends EventEmitter {
1719
1727
  }
1720
1728
  }
1721
1729
  }
1722
- handleFC4(frame, response) {
1723
- var _a, _b;
1730
+ handleFC4(model, frame, response) {
1731
+ var _a;
1724
1732
  if (frame.data.length === 4) {
1725
- if (this.model.readInputRegisters) {
1733
+ if (model.readInputRegisters) {
1726
1734
  const bufferRx = Buffer.from(frame.data);
1727
1735
  const address = bufferRx.readUInt16BE(0);
1728
1736
  const length = bufferRx.readUInt16BE(2);
1729
1737
  if (length >= 0x0001 && length <= 0x007d) {
1730
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).inputRegisters)) {
1731
- Promise.resolve(this.model.readInputRegisters(address, length))
1738
+ if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).inputRegisters)) {
1739
+ Promise.resolve(model.readInputRegisters(address, length))
1732
1740
  .then((registers) => {
1733
1741
  const bufferTx = Buffer.alloc(length * 2);
1734
1742
  registers.forEach((register, index) => {
@@ -1753,16 +1761,16 @@ class ModbusSlave extends EventEmitter {
1753
1761
  }
1754
1762
  }
1755
1763
  }
1756
- handleFC5(frame, response) {
1757
- var _a, _b;
1764
+ handleFC5(model, frame, response) {
1765
+ var _a;
1758
1766
  if (frame.data.length === 4) {
1759
- if (this.model.writeSingleCoil) {
1767
+ if (model.writeSingleCoil) {
1760
1768
  const bufferRx = Buffer.from(frame.data);
1761
1769
  const address = bufferRx.readUInt16BE(0);
1762
1770
  const value = bufferRx.readUInt16BE(2);
1763
1771
  if (value === 0x0000 || value === 0xff00) {
1764
- if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1765
- Promise.resolve(this.model.writeSingleCoil(address, value === 0xff00))
1772
+ if (checkRange(address, (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).coils)) {
1773
+ Promise.resolve(model.writeSingleCoil(address, value === 0xff00))
1766
1774
  .then(() => {
1767
1775
  response(this.applicationLayer.encode(frame));
1768
1776
  })
@@ -1783,16 +1791,16 @@ class ModbusSlave extends EventEmitter {
1783
1791
  }
1784
1792
  }
1785
1793
  }
1786
- handleFC6(frame, response) {
1787
- var _a, _b;
1794
+ handleFC6(model, frame, response) {
1795
+ var _a;
1788
1796
  if (frame.data.length === 4) {
1789
- if (this.model.writeSingleRegister) {
1797
+ if (model.writeSingleRegister) {
1790
1798
  const bufferRx = Buffer.from(frame.data);
1791
1799
  const address = bufferRx.readUInt16BE(0);
1792
1800
  const value = bufferRx.readUInt16BE(2);
1793
1801
  if (value >= 0x0000 && value <= 0xffff) {
1794
- if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1795
- Promise.resolve(this.model.writeSingleRegister(address, value))
1802
+ if (checkRange(address, (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
1803
+ Promise.resolve(model.writeSingleRegister(address, value))
1796
1804
  .then(() => {
1797
1805
  response(this.applicationLayer.encode(frame));
1798
1806
  })
@@ -1813,20 +1821,20 @@ class ModbusSlave extends EventEmitter {
1813
1821
  }
1814
1822
  }
1815
1823
  }
1816
- handleFC15(frame, response) {
1817
- var _a, _b;
1824
+ handleFC15(model, frame, response) {
1825
+ var _a;
1818
1826
  if (frame.data.length > 5 && frame.data.length === 5 + frame.data[4]) {
1819
- if (this.model.writeMultipleCoils || this.model.writeSingleCoil) {
1827
+ if (model.writeMultipleCoils || model.writeSingleCoil) {
1820
1828
  const bufferRx = Buffer.from(frame.data);
1821
1829
  const address = bufferRx.readUInt16BE(0);
1822
1830
  const length = bufferRx.readUInt16BE(2);
1823
1831
  const byteCount = bufferRx[4];
1824
1832
  if (length >= 0x0001 && length <= 0x07b0 && byteCount === Math.ceil(length / 8)) {
1825
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1833
+ if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).coils)) {
1826
1834
  const value = Array.from({ length }).map((_, index) => (bufferRx[5 + ~~(index / 8)] & (1 << index % 8)) > 0);
1827
- Promise.resolve(this.model.writeMultipleCoils
1828
- ? this.model.writeMultipleCoils(address, value)
1829
- : Promise.all(value.map((v, i) => this.model.writeSingleCoil(address + i, v))))
1835
+ Promise.resolve(model.writeMultipleCoils
1836
+ ? model.writeMultipleCoils(address, value)
1837
+ : Promise.all(value.map((v, i) => model.writeSingleCoil(address + i, v))))
1830
1838
  .then(() => {
1831
1839
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: Array.from(bufferRx).slice(0, 4) })));
1832
1840
  })
@@ -1847,20 +1855,20 @@ class ModbusSlave extends EventEmitter {
1847
1855
  }
1848
1856
  }
1849
1857
  }
1850
- handleFC16(frame, response) {
1851
- var _a, _b;
1858
+ handleFC16(model, frame, response) {
1859
+ var _a;
1852
1860
  if (frame.data.length > 5 && frame.data.length === 5 + frame.data[4]) {
1853
- if (this.model.writeMultipleRegisters || this.model.writeSingleRegister) {
1861
+ if (model.writeMultipleRegisters || model.writeSingleRegister) {
1854
1862
  const bufferRx = Buffer.from(frame.data);
1855
1863
  const address = bufferRx.readUInt16BE(0);
1856
1864
  const length = bufferRx.readUInt16BE(2);
1857
1865
  const byteCount = bufferRx[4];
1858
1866
  if (length >= 0x0001 && length <= 0x007b && byteCount === length * 2) {
1859
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1867
+ if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
1860
1868
  const value = Array.from({ length }).map((_, index) => bufferRx.readUInt16BE(5 + index * 2));
1861
- Promise.resolve(this.model.writeMultipleRegisters
1862
- ? this.model.writeMultipleRegisters(address, value)
1863
- : Promise.all(value.map((v, i) => this.model.writeSingleRegister(address + i, v))))
1869
+ Promise.resolve(model.writeMultipleRegisters
1870
+ ? model.writeMultipleRegisters(address, value)
1871
+ : Promise.all(value.map((v, i) => model.writeSingleRegister(address + i, v))))
1864
1872
  .then(() => {
1865
1873
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: Array.from(bufferRx).slice(0, 4) })));
1866
1874
  })
@@ -1881,11 +1889,13 @@ class ModbusSlave extends EventEmitter {
1881
1889
  }
1882
1890
  }
1883
1891
  }
1884
- handleFC17(frame, response) {
1892
+ handleFC17(model, frame, response) {
1885
1893
  if (frame.data.length === 0) {
1886
- if (this.model.reportServerId) {
1887
- Promise.resolve(this.model.reportServerId())
1888
- .then(({ serverId = this.unit, runIndicatorStatus = true, additionalData = [] }) => {
1894
+ if (model.reportServerId) {
1895
+ Promise.resolve(model.reportServerId())
1896
+ .then((_a) => {
1897
+ var _b;
1898
+ var { serverId = (_b = model.unit) !== null && _b !== void 0 ? _b : 1, runIndicatorStatus = true, additionalData = [] } = _a;
1889
1899
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: [2 + additionalData.length, serverId, runIndicatorStatus ? 0xff : 0x00].concat(additionalData) })));
1890
1900
  })
1891
1901
  .catch((error) => {
@@ -1897,19 +1907,19 @@ class ModbusSlave extends EventEmitter {
1897
1907
  }
1898
1908
  }
1899
1909
  }
1900
- handleFC22(frame, response) {
1901
- var _a, _b;
1910
+ handleFC22(model, frame, response) {
1911
+ var _a;
1902
1912
  if (frame.data.length === 6) {
1903
- if (this.model.maskWriteRegister || (this.model.readHoldingRegisters && this.model.writeSingleRegister)) {
1913
+ if (model.maskWriteRegister || (model.readHoldingRegisters && model.writeSingleRegister)) {
1904
1914
  const bufferRx = Buffer.from(frame.data);
1905
1915
  const address = bufferRx.readUInt16BE(0);
1906
1916
  const andMask = bufferRx.readUInt16BE(2);
1907
1917
  const orMask = bufferRx.readUInt16BE(4);
1908
- if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1909
- Promise.resolve(this.model.maskWriteRegister
1910
- ? this.model.maskWriteRegister(address, andMask, orMask)
1911
- : Promise.resolve(this.model.readHoldingRegisters(address, 1)).then(([value]) => {
1912
- return Promise.resolve(this.model.writeSingleRegister(address, (value & andMask) | (orMask & (~andMask & 0xff))));
1918
+ if (checkRange(address, (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
1919
+ Promise.resolve(model.maskWriteRegister
1920
+ ? model.maskWriteRegister(address, andMask, orMask)
1921
+ : Promise.resolve(model.readHoldingRegisters(address, 1)).then(([value]) => {
1922
+ return Promise.resolve(model.writeSingleRegister(address, (value & andMask) | (orMask & (~andMask & 0xff))));
1913
1923
  }))
1914
1924
  .then(() => {
1915
1925
  response(this.applicationLayer.encode(frame));
@@ -1927,10 +1937,10 @@ class ModbusSlave extends EventEmitter {
1927
1937
  }
1928
1938
  }
1929
1939
  }
1930
- handleFC23(frame, response) {
1931
- var _a, _b;
1940
+ handleFC23(model, frame, response) {
1941
+ var _a;
1932
1942
  if (frame.data.length > 9 && frame.data.length === 9 + frame.data[8]) {
1933
- if (this.model.readHoldingRegisters && (this.model.writeMultipleRegisters || this.model.writeSingleRegister)) {
1943
+ if (model.readHoldingRegisters && (model.writeMultipleRegisters || model.writeSingleRegister)) {
1934
1944
  const bufferRx = Buffer.from(frame.data);
1935
1945
  const address = {
1936
1946
  read: bufferRx.readUInt16BE(0),
@@ -1946,12 +1956,12 @@ class ModbusSlave extends EventEmitter {
1946
1956
  length.write >= 0x0001 &&
1947
1957
  length.write <= 0x0079 &&
1948
1958
  byteCount === length.write * 2) {
1949
- 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)) {
1959
+ if (checkRange([address.read, address.read + length.read, address.write, address.write + length.write], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
1950
1960
  const value = Array.from({ length: length.write }).map((_, index) => bufferRx.readUInt16BE(9 + index * 2));
1951
- Promise.resolve(this.model.writeMultipleRegisters
1952
- ? this.model.writeMultipleRegisters(address.write, value)
1953
- : Promise.all(value.map((v, i) => this.model.writeSingleRegister(address.write + i, v))))
1954
- .then(() => Promise.resolve(this.model.readHoldingRegisters(address.read, length.read)))
1961
+ Promise.resolve(model.writeMultipleRegisters
1962
+ ? model.writeMultipleRegisters(address.write, value)
1963
+ : Promise.all(value.map((v, i) => model.writeSingleRegister(address.write + i, v))))
1964
+ .then(() => Promise.resolve(model.readHoldingRegisters(address.read, length.read)))
1955
1965
  .then((registers) => {
1956
1966
  const bufferTx = Buffer.alloc(length.read * 2);
1957
1967
  registers.forEach((register, index) => {
@@ -1976,9 +1986,9 @@ class ModbusSlave extends EventEmitter {
1976
1986
  }
1977
1987
  }
1978
1988
  }
1979
- handleFC43_14(frame, response) {
1989
+ handleFC43_14(model, frame, response) {
1980
1990
  if (frame.data.length === 3) {
1981
- if (frame.data[0] === 0x0e && this.model.readDeviceIdentification) {
1991
+ if (frame.data[0] === 0x0e && model.readDeviceIdentification) {
1982
1992
  const readDeviceIDCode = frame.data[1];
1983
1993
  let objectID = frame.data[2];
1984
1994
  switch (readDeviceIDCode) {
@@ -2012,7 +2022,7 @@ class ModbusSlave extends EventEmitter {
2012
2022
  return;
2013
2023
  }
2014
2024
  }
2015
- Promise.resolve(this.model.readDeviceIdentification())
2025
+ Promise.resolve(model.readDeviceIdentification())
2016
2026
  .then((identification) => {
2017
2027
  const objects = new Map([
2018
2028
  [0x00, 'null'],
@@ -2090,6 +2100,13 @@ class ModbusSlave extends EventEmitter {
2090
2100
  responseError(frame, response, error) {
2091
2101
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { fc: frame.fc | 0x80, data: [getCodeByError(error)] })));
2092
2102
  }
2103
+ add(model) {
2104
+ var _a;
2105
+ this.models.set((_a = model.unit) !== null && _a !== void 0 ? _a : 1, model);
2106
+ }
2107
+ remove(unit) {
2108
+ this.models.delete(unit);
2109
+ }
2093
2110
  open(...args) {
2094
2111
  return this.physicalLayer.open(...args);
2095
2112
  }
@@ -45,13 +45,12 @@ interface ModbusSlaveEvents {
45
45
  close: [];
46
46
  }
47
47
  export declare class ModbusSlave<A extends AbstractApplicationLayer, P extends AbstractPhysicalLayer> extends EventEmitter<ModbusSlaveEvents> {
48
- private model;
49
48
  private applicationLayer;
50
49
  private physicalLayer;
51
- unit: number;
50
+ models: Map<number, ModbusSlaveModel>;
52
51
  get isOpen(): boolean;
53
52
  get destroyed(): boolean;
54
- constructor(model: ModbusSlaveModel, applicationLayer: A, physicalLayer: P);
53
+ constructor(applicationLayer: A, physicalLayer: P);
55
54
  private handleFC1;
56
55
  private handleFC2;
57
56
  private handleFC3;
@@ -65,6 +64,8 @@ export declare class ModbusSlave<A extends AbstractApplicationLayer, P extends A
65
64
  private handleFC23;
66
65
  private handleFC43_14;
67
66
  private responseError;
67
+ add(model: ModbusSlaveModel): void;
68
+ remove(unit: number): void;
68
69
  open(...args: Parameters<P['open']>): Promise<void>;
69
70
  close(): Promise<void>;
70
71
  destroy(): Promise<void>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "njs-modbus",
3
- "version": "1.3.4",
3
+ "version": "1.4.0",
4
4
  "description": "A pure JavaScript implemetation of Modbus for NodeJS.",
5
5
  "keywords": [
6
6
  "modbus",