njs-modbus 1.3.5 → 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
@@ -1504,14 +1504,8 @@ class ModbusSlave extends EventEmitter {
1504
1504
  get destroyed() {
1505
1505
  return this.physicalLayer.destroyed;
1506
1506
  }
1507
- constructor(model, applicationLayer, physicalLayer) {
1507
+ constructor(applicationLayer, physicalLayer) {
1508
1508
  super();
1509
- Object.defineProperty(this, "model", {
1510
- enumerable: true,
1511
- configurable: true,
1512
- writable: true,
1513
- value: model
1514
- });
1515
1509
  Object.defineProperty(this, "applicationLayer", {
1516
1510
  enumerable: true,
1517
1511
  configurable: true,
@@ -1524,17 +1518,14 @@ class ModbusSlave extends EventEmitter {
1524
1518
  writable: true,
1525
1519
  value: physicalLayer
1526
1520
  });
1527
- Object.defineProperty(this, "unit", {
1521
+ Object.defineProperty(this, "models", {
1528
1522
  enumerable: true,
1529
1523
  configurable: true,
1530
1524
  writable: true,
1531
- value: 1
1525
+ value: new Map()
1532
1526
  });
1533
- if (typeof model.unit !== 'undefined') {
1534
- this.unit = model.unit;
1535
- }
1536
- applicationLayer.on('framing', (frame, _response) => __awaiter(this, void 0, void 0, function* () {
1537
- if (!(frame.unit === 0x00 || frame.unit === this.unit)) {
1527
+ applicationLayer.on('framing', (frame, _response) => {
1528
+ if (!(frame.unit === 0x00 || this.models.has(frame.unit))) {
1538
1529
  return;
1539
1530
  }
1540
1531
  const response = (data) => __awaiter(this, void 0, void 0, function* () {
@@ -1546,74 +1537,85 @@ class ModbusSlave extends EventEmitter {
1546
1537
  }
1547
1538
  catch (error) { }
1548
1539
  });
1549
- if (model.interceptor) {
1550
- try {
1551
- const data = yield model.interceptor(frame.fc, frame.data);
1552
- if (data) {
1553
- response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data })));
1554
- 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';
1555
1552
  }
1556
1553
  }
1557
- catch (error) {
1558
- this.responseError(frame, response, error);
1559
- return;
1560
- }
1561
- }
1562
- switch (frame.fc) {
1563
- case 0x01: {
1564
- this.handleFC1(frame, response);
1565
- break;
1566
- }
1567
- case 0x02: {
1568
- this.handleFC2(frame, response);
1569
- break;
1570
- }
1571
- case 0x03: {
1572
- this.handleFC3(frame, response);
1573
- break;
1574
- }
1575
- case 0x04: {
1576
- this.handleFC4(frame, response);
1577
- break;
1578
- }
1579
- case 0x05: {
1580
- this.handleFC5(frame, response);
1581
- break;
1582
- }
1583
- case 0x06: {
1584
- this.handleFC6(frame, response);
1585
- break;
1586
- }
1587
- case 0x0f: {
1588
- this.handleFC15(frame, response);
1589
- break;
1590
- }
1591
- case 0x10: {
1592
- this.handleFC16(frame, response);
1593
- break;
1594
- }
1595
- case 0x11: {
1596
- this.handleFC17(frame, response);
1597
- break;
1598
- }
1599
- case 0x16: {
1600
- this.handleFC22(frame, response);
1601
- break;
1602
- }
1603
- case 0x17: {
1604
- this.handleFC23(frame, response);
1605
- break;
1606
- }
1607
- case 0x2b: {
1608
- this.handleFC43_14(frame, response);
1609
- break;
1610
- }
1611
- default: {
1612
- this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
1613
- 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
+ }
1614
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
+ });
1615
1617
  }
1616
- }));
1618
+ });
1617
1619
  physicalLayer.on('error', (error) => {
1618
1620
  this.emit('error', error);
1619
1621
  });
@@ -1621,16 +1623,16 @@ class ModbusSlave extends EventEmitter {
1621
1623
  this.emit('close');
1622
1624
  });
1623
1625
  }
1624
- handleFC1(frame, response) {
1625
- var _a, _b;
1626
+ handleFC1(model, frame, response) {
1627
+ var _a;
1626
1628
  if (frame.data.length === 4) {
1627
- if (this.model.readCoils) {
1629
+ if (model.readCoils) {
1628
1630
  const bufferRx = Buffer.from(frame.data);
1629
1631
  const address = bufferRx.readUInt16BE(0);
1630
1632
  const length = bufferRx.readUInt16BE(2);
1631
1633
  if (length >= 0x0001 && length <= 0x07d0) {
1632
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1633
- 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))
1634
1636
  .then((coils) => {
1635
1637
  const bufferTx = Buffer.alloc(Math.ceil(length / 8));
1636
1638
  coils.forEach((coil, index) => {
@@ -1657,16 +1659,16 @@ class ModbusSlave extends EventEmitter {
1657
1659
  }
1658
1660
  }
1659
1661
  }
1660
- handleFC2(frame, response) {
1661
- var _a, _b;
1662
+ handleFC2(model, frame, response) {
1663
+ var _a;
1662
1664
  if (frame.data.length === 4) {
1663
- if (this.model.readDiscreteInputs) {
1665
+ if (model.readDiscreteInputs) {
1664
1666
  const bufferRx = Buffer.from(frame.data);
1665
1667
  const address = bufferRx.readUInt16BE(0);
1666
1668
  const length = bufferRx.readUInt16BE(2);
1667
1669
  if (length >= 0x0001 && length <= 0x07d0) {
1668
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).discreteInputs)) {
1669
- 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))
1670
1672
  .then((discreteInputs) => {
1671
1673
  const bufferTx = Buffer.alloc(Math.ceil(length / 8));
1672
1674
  discreteInputs.forEach((discreteInput, index) => {
@@ -1693,16 +1695,16 @@ class ModbusSlave extends EventEmitter {
1693
1695
  }
1694
1696
  }
1695
1697
  }
1696
- handleFC3(frame, response) {
1697
- var _a, _b;
1698
+ handleFC3(model, frame, response) {
1699
+ var _a;
1698
1700
  if (frame.data.length === 4) {
1699
- if (this.model.readHoldingRegisters) {
1701
+ if (model.readHoldingRegisters) {
1700
1702
  const bufferRx = Buffer.from(frame.data);
1701
1703
  const address = bufferRx.readUInt16BE(0);
1702
1704
  const length = bufferRx.readUInt16BE(2);
1703
1705
  if (length >= 0x0001 && length <= 0x007d) {
1704
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1705
- 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))
1706
1708
  .then((registers) => {
1707
1709
  const bufferTx = Buffer.alloc(length * 2);
1708
1710
  registers.forEach((register, index) => {
@@ -1727,16 +1729,16 @@ class ModbusSlave extends EventEmitter {
1727
1729
  }
1728
1730
  }
1729
1731
  }
1730
- handleFC4(frame, response) {
1731
- var _a, _b;
1732
+ handleFC4(model, frame, response) {
1733
+ var _a;
1732
1734
  if (frame.data.length === 4) {
1733
- if (this.model.readInputRegisters) {
1735
+ if (model.readInputRegisters) {
1734
1736
  const bufferRx = Buffer.from(frame.data);
1735
1737
  const address = bufferRx.readUInt16BE(0);
1736
1738
  const length = bufferRx.readUInt16BE(2);
1737
1739
  if (length >= 0x0001 && length <= 0x007d) {
1738
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).inputRegisters)) {
1739
- 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))
1740
1742
  .then((registers) => {
1741
1743
  const bufferTx = Buffer.alloc(length * 2);
1742
1744
  registers.forEach((register, index) => {
@@ -1761,16 +1763,16 @@ class ModbusSlave extends EventEmitter {
1761
1763
  }
1762
1764
  }
1763
1765
  }
1764
- handleFC5(frame, response) {
1765
- var _a, _b;
1766
+ handleFC5(model, frame, response) {
1767
+ var _a;
1766
1768
  if (frame.data.length === 4) {
1767
- if (this.model.writeSingleCoil) {
1769
+ if (model.writeSingleCoil) {
1768
1770
  const bufferRx = Buffer.from(frame.data);
1769
1771
  const address = bufferRx.readUInt16BE(0);
1770
1772
  const value = bufferRx.readUInt16BE(2);
1771
1773
  if (value === 0x0000 || value === 0xff00) {
1772
- if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1773
- 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))
1774
1776
  .then(() => {
1775
1777
  response(this.applicationLayer.encode(frame));
1776
1778
  })
@@ -1791,16 +1793,16 @@ class ModbusSlave extends EventEmitter {
1791
1793
  }
1792
1794
  }
1793
1795
  }
1794
- handleFC6(frame, response) {
1795
- var _a, _b;
1796
+ handleFC6(model, frame, response) {
1797
+ var _a;
1796
1798
  if (frame.data.length === 4) {
1797
- if (this.model.writeSingleRegister) {
1799
+ if (model.writeSingleRegister) {
1798
1800
  const bufferRx = Buffer.from(frame.data);
1799
1801
  const address = bufferRx.readUInt16BE(0);
1800
1802
  const value = bufferRx.readUInt16BE(2);
1801
1803
  if (value >= 0x0000 && value <= 0xffff) {
1802
- if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1803
- 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))
1804
1806
  .then(() => {
1805
1807
  response(this.applicationLayer.encode(frame));
1806
1808
  })
@@ -1821,20 +1823,20 @@ class ModbusSlave extends EventEmitter {
1821
1823
  }
1822
1824
  }
1823
1825
  }
1824
- handleFC15(frame, response) {
1825
- var _a, _b;
1826
+ handleFC15(model, frame, response) {
1827
+ var _a;
1826
1828
  if (frame.data.length > 5 && frame.data.length === 5 + frame.data[4]) {
1827
- if (this.model.writeMultipleCoils || this.model.writeSingleCoil) {
1829
+ if (model.writeMultipleCoils || model.writeSingleCoil) {
1828
1830
  const bufferRx = Buffer.from(frame.data);
1829
1831
  const address = bufferRx.readUInt16BE(0);
1830
1832
  const length = bufferRx.readUInt16BE(2);
1831
1833
  const byteCount = bufferRx[4];
1832
1834
  if (length >= 0x0001 && length <= 0x07b0 && byteCount === Math.ceil(length / 8)) {
1833
- 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)) {
1834
1836
  const value = Array.from({ length }).map((_, index) => (bufferRx[5 + ~~(index / 8)] & (1 << index % 8)) > 0);
1835
- Promise.resolve(this.model.writeMultipleCoils
1836
- ? this.model.writeMultipleCoils(address, value)
1837
- : 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))))
1838
1840
  .then(() => {
1839
1841
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: Array.from(bufferRx).slice(0, 4) })));
1840
1842
  })
@@ -1855,20 +1857,20 @@ class ModbusSlave extends EventEmitter {
1855
1857
  }
1856
1858
  }
1857
1859
  }
1858
- handleFC16(frame, response) {
1859
- var _a, _b;
1860
+ handleFC16(model, frame, response) {
1861
+ var _a;
1860
1862
  if (frame.data.length > 5 && frame.data.length === 5 + frame.data[4]) {
1861
- if (this.model.writeMultipleRegisters || this.model.writeSingleRegister) {
1863
+ if (model.writeMultipleRegisters || model.writeSingleRegister) {
1862
1864
  const bufferRx = Buffer.from(frame.data);
1863
1865
  const address = bufferRx.readUInt16BE(0);
1864
1866
  const length = bufferRx.readUInt16BE(2);
1865
1867
  const byteCount = bufferRx[4];
1866
1868
  if (length >= 0x0001 && length <= 0x007b && byteCount === length * 2) {
1867
- 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)) {
1868
1870
  const value = Array.from({ length }).map((_, index) => bufferRx.readUInt16BE(5 + index * 2));
1869
- Promise.resolve(this.model.writeMultipleRegisters
1870
- ? this.model.writeMultipleRegisters(address, value)
1871
- : 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))))
1872
1874
  .then(() => {
1873
1875
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: Array.from(bufferRx).slice(0, 4) })));
1874
1876
  })
@@ -1889,11 +1891,13 @@ class ModbusSlave extends EventEmitter {
1889
1891
  }
1890
1892
  }
1891
1893
  }
1892
- handleFC17(frame, response) {
1894
+ handleFC17(model, frame, response) {
1893
1895
  if (frame.data.length === 0) {
1894
- if (this.model.reportServerId) {
1895
- Promise.resolve(this.model.reportServerId())
1896
- .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;
1897
1901
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: [2 + additionalData.length, serverId, runIndicatorStatus ? 0xff : 0x00].concat(additionalData) })));
1898
1902
  })
1899
1903
  .catch((error) => {
@@ -1905,19 +1909,19 @@ class ModbusSlave extends EventEmitter {
1905
1909
  }
1906
1910
  }
1907
1911
  }
1908
- handleFC22(frame, response) {
1909
- var _a, _b;
1912
+ handleFC22(model, frame, response) {
1913
+ var _a;
1910
1914
  if (frame.data.length === 6) {
1911
- if (this.model.maskWriteRegister || (this.model.readHoldingRegisters && this.model.writeSingleRegister)) {
1915
+ if (model.maskWriteRegister || (model.readHoldingRegisters && model.writeSingleRegister)) {
1912
1916
  const bufferRx = Buffer.from(frame.data);
1913
1917
  const address = bufferRx.readUInt16BE(0);
1914
1918
  const andMask = bufferRx.readUInt16BE(2);
1915
1919
  const orMask = bufferRx.readUInt16BE(4);
1916
- if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1917
- Promise.resolve(this.model.maskWriteRegister
1918
- ? this.model.maskWriteRegister(address, andMask, orMask)
1919
- : Promise.resolve(this.model.readHoldingRegisters(address, 1)).then(([value]) => {
1920
- 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))));
1921
1925
  }))
1922
1926
  .then(() => {
1923
1927
  response(this.applicationLayer.encode(frame));
@@ -1935,10 +1939,10 @@ class ModbusSlave extends EventEmitter {
1935
1939
  }
1936
1940
  }
1937
1941
  }
1938
- handleFC23(frame, response) {
1939
- var _a, _b;
1942
+ handleFC23(model, frame, response) {
1943
+ var _a;
1940
1944
  if (frame.data.length > 9 && frame.data.length === 9 + frame.data[8]) {
1941
- if (this.model.readHoldingRegisters && (this.model.writeMultipleRegisters || this.model.writeSingleRegister)) {
1945
+ if (model.readHoldingRegisters && (model.writeMultipleRegisters || model.writeSingleRegister)) {
1942
1946
  const bufferRx = Buffer.from(frame.data);
1943
1947
  const address = {
1944
1948
  read: bufferRx.readUInt16BE(0),
@@ -1954,12 +1958,12 @@ class ModbusSlave extends EventEmitter {
1954
1958
  length.write >= 0x0001 &&
1955
1959
  length.write <= 0x0079 &&
1956
1960
  byteCount === length.write * 2) {
1957
- 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)) {
1958
1962
  const value = Array.from({ length: length.write }).map((_, index) => bufferRx.readUInt16BE(9 + index * 2));
1959
- Promise.resolve(this.model.writeMultipleRegisters
1960
- ? this.model.writeMultipleRegisters(address.write, value)
1961
- : Promise.all(value.map((v, i) => this.model.writeSingleRegister(address.write + i, v))))
1962
- .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)))
1963
1967
  .then((registers) => {
1964
1968
  const bufferTx = Buffer.alloc(length.read * 2);
1965
1969
  registers.forEach((register, index) => {
@@ -1984,9 +1988,9 @@ class ModbusSlave extends EventEmitter {
1984
1988
  }
1985
1989
  }
1986
1990
  }
1987
- handleFC43_14(frame, response) {
1991
+ handleFC43_14(model, frame, response) {
1988
1992
  if (frame.data.length === 3) {
1989
- if (frame.data[0] === 0x0e && this.model.readDeviceIdentification) {
1993
+ if (frame.data[0] === 0x0e && model.readDeviceIdentification) {
1990
1994
  const readDeviceIDCode = frame.data[1];
1991
1995
  let objectID = frame.data[2];
1992
1996
  switch (readDeviceIDCode) {
@@ -2020,7 +2024,7 @@ class ModbusSlave extends EventEmitter {
2020
2024
  return;
2021
2025
  }
2022
2026
  }
2023
- Promise.resolve(this.model.readDeviceIdentification())
2027
+ Promise.resolve(model.readDeviceIdentification())
2024
2028
  .then((identification) => {
2025
2029
  const objects = new Map([
2026
2030
  [0x00, 'null'],
@@ -2098,6 +2102,13 @@ class ModbusSlave extends EventEmitter {
2098
2102
  responseError(frame, response, error) {
2099
2103
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { fc: frame.fc | 0x80, data: [getCodeByError(error)] })));
2100
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
+ }
2101
2112
  open(...args) {
2102
2113
  return this.physicalLayer.open(...args);
2103
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
@@ -1502,14 +1502,8 @@ class ModbusSlave extends EventEmitter {
1502
1502
  get destroyed() {
1503
1503
  return this.physicalLayer.destroyed;
1504
1504
  }
1505
- constructor(model, applicationLayer, physicalLayer) {
1505
+ constructor(applicationLayer, physicalLayer) {
1506
1506
  super();
1507
- Object.defineProperty(this, "model", {
1508
- enumerable: true,
1509
- configurable: true,
1510
- writable: true,
1511
- value: model
1512
- });
1513
1507
  Object.defineProperty(this, "applicationLayer", {
1514
1508
  enumerable: true,
1515
1509
  configurable: true,
@@ -1522,17 +1516,14 @@ class ModbusSlave extends EventEmitter {
1522
1516
  writable: true,
1523
1517
  value: physicalLayer
1524
1518
  });
1525
- Object.defineProperty(this, "unit", {
1519
+ Object.defineProperty(this, "models", {
1526
1520
  enumerable: true,
1527
1521
  configurable: true,
1528
1522
  writable: true,
1529
- value: 1
1523
+ value: new Map()
1530
1524
  });
1531
- if (typeof model.unit !== 'undefined') {
1532
- this.unit = model.unit;
1533
- }
1534
- applicationLayer.on('framing', (frame, _response) => __awaiter(this, void 0, void 0, function* () {
1535
- if (!(frame.unit === 0x00 || frame.unit === this.unit)) {
1525
+ applicationLayer.on('framing', (frame, _response) => {
1526
+ if (!(frame.unit === 0x00 || this.models.has(frame.unit))) {
1536
1527
  return;
1537
1528
  }
1538
1529
  const response = (data) => __awaiter(this, void 0, void 0, function* () {
@@ -1544,74 +1535,85 @@ class ModbusSlave extends EventEmitter {
1544
1535
  }
1545
1536
  catch (error) { }
1546
1537
  });
1547
- if (model.interceptor) {
1548
- try {
1549
- const data = yield model.interceptor(frame.fc, frame.data);
1550
- if (data) {
1551
- response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data })));
1552
- 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';
1553
1550
  }
1554
1551
  }
1555
- catch (error) {
1556
- this.responseError(frame, response, error);
1557
- return;
1558
- }
1559
- }
1560
- switch (frame.fc) {
1561
- case 0x01: {
1562
- this.handleFC1(frame, response);
1563
- break;
1564
- }
1565
- case 0x02: {
1566
- this.handleFC2(frame, response);
1567
- break;
1568
- }
1569
- case 0x03: {
1570
- this.handleFC3(frame, response);
1571
- break;
1572
- }
1573
- case 0x04: {
1574
- this.handleFC4(frame, response);
1575
- break;
1576
- }
1577
- case 0x05: {
1578
- this.handleFC5(frame, response);
1579
- break;
1580
- }
1581
- case 0x06: {
1582
- this.handleFC6(frame, response);
1583
- break;
1584
- }
1585
- case 0x0f: {
1586
- this.handleFC15(frame, response);
1587
- break;
1588
- }
1589
- case 0x10: {
1590
- this.handleFC16(frame, response);
1591
- break;
1592
- }
1593
- case 0x11: {
1594
- this.handleFC17(frame, response);
1595
- break;
1596
- }
1597
- case 0x16: {
1598
- this.handleFC22(frame, response);
1599
- break;
1600
- }
1601
- case 0x17: {
1602
- this.handleFC23(frame, response);
1603
- break;
1604
- }
1605
- case 0x2b: {
1606
- this.handleFC43_14(frame, response);
1607
- break;
1608
- }
1609
- default: {
1610
- this.responseError(frame, response, getErrorByCode(ErrorCode.ILLEGAL_FUNCTION));
1611
- 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
+ }
1612
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
+ });
1613
1615
  }
1614
- }));
1616
+ });
1615
1617
  physicalLayer.on('error', (error) => {
1616
1618
  this.emit('error', error);
1617
1619
  });
@@ -1619,16 +1621,16 @@ class ModbusSlave extends EventEmitter {
1619
1621
  this.emit('close');
1620
1622
  });
1621
1623
  }
1622
- handleFC1(frame, response) {
1623
- var _a, _b;
1624
+ handleFC1(model, frame, response) {
1625
+ var _a;
1624
1626
  if (frame.data.length === 4) {
1625
- if (this.model.readCoils) {
1627
+ if (model.readCoils) {
1626
1628
  const bufferRx = Buffer.from(frame.data);
1627
1629
  const address = bufferRx.readUInt16BE(0);
1628
1630
  const length = bufferRx.readUInt16BE(2);
1629
1631
  if (length >= 0x0001 && length <= 0x07d0) {
1630
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1631
- 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))
1632
1634
  .then((coils) => {
1633
1635
  const bufferTx = Buffer.alloc(Math.ceil(length / 8));
1634
1636
  coils.forEach((coil, index) => {
@@ -1655,16 +1657,16 @@ class ModbusSlave extends EventEmitter {
1655
1657
  }
1656
1658
  }
1657
1659
  }
1658
- handleFC2(frame, response) {
1659
- var _a, _b;
1660
+ handleFC2(model, frame, response) {
1661
+ var _a;
1660
1662
  if (frame.data.length === 4) {
1661
- if (this.model.readDiscreteInputs) {
1663
+ if (model.readDiscreteInputs) {
1662
1664
  const bufferRx = Buffer.from(frame.data);
1663
1665
  const address = bufferRx.readUInt16BE(0);
1664
1666
  const length = bufferRx.readUInt16BE(2);
1665
1667
  if (length >= 0x0001 && length <= 0x07d0) {
1666
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).discreteInputs)) {
1667
- 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))
1668
1670
  .then((discreteInputs) => {
1669
1671
  const bufferTx = Buffer.alloc(Math.ceil(length / 8));
1670
1672
  discreteInputs.forEach((discreteInput, index) => {
@@ -1691,16 +1693,16 @@ class ModbusSlave extends EventEmitter {
1691
1693
  }
1692
1694
  }
1693
1695
  }
1694
- handleFC3(frame, response) {
1695
- var _a, _b;
1696
+ handleFC3(model, frame, response) {
1697
+ var _a;
1696
1698
  if (frame.data.length === 4) {
1697
- if (this.model.readHoldingRegisters) {
1699
+ if (model.readHoldingRegisters) {
1698
1700
  const bufferRx = Buffer.from(frame.data);
1699
1701
  const address = bufferRx.readUInt16BE(0);
1700
1702
  const length = bufferRx.readUInt16BE(2);
1701
1703
  if (length >= 0x0001 && length <= 0x007d) {
1702
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1703
- 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))
1704
1706
  .then((registers) => {
1705
1707
  const bufferTx = Buffer.alloc(length * 2);
1706
1708
  registers.forEach((register, index) => {
@@ -1725,16 +1727,16 @@ class ModbusSlave extends EventEmitter {
1725
1727
  }
1726
1728
  }
1727
1729
  }
1728
- handleFC4(frame, response) {
1729
- var _a, _b;
1730
+ handleFC4(model, frame, response) {
1731
+ var _a;
1730
1732
  if (frame.data.length === 4) {
1731
- if (this.model.readInputRegisters) {
1733
+ if (model.readInputRegisters) {
1732
1734
  const bufferRx = Buffer.from(frame.data);
1733
1735
  const address = bufferRx.readUInt16BE(0);
1734
1736
  const length = bufferRx.readUInt16BE(2);
1735
1737
  if (length >= 0x0001 && length <= 0x007d) {
1736
- if (checkRange([address, address + length], (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).inputRegisters)) {
1737
- 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))
1738
1740
  .then((registers) => {
1739
1741
  const bufferTx = Buffer.alloc(length * 2);
1740
1742
  registers.forEach((register, index) => {
@@ -1759,16 +1761,16 @@ class ModbusSlave extends EventEmitter {
1759
1761
  }
1760
1762
  }
1761
1763
  }
1762
- handleFC5(frame, response) {
1763
- var _a, _b;
1764
+ handleFC5(model, frame, response) {
1765
+ var _a;
1764
1766
  if (frame.data.length === 4) {
1765
- if (this.model.writeSingleCoil) {
1767
+ if (model.writeSingleCoil) {
1766
1768
  const bufferRx = Buffer.from(frame.data);
1767
1769
  const address = bufferRx.readUInt16BE(0);
1768
1770
  const value = bufferRx.readUInt16BE(2);
1769
1771
  if (value === 0x0000 || value === 0xff00) {
1770
- if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).coils)) {
1771
- 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))
1772
1774
  .then(() => {
1773
1775
  response(this.applicationLayer.encode(frame));
1774
1776
  })
@@ -1789,16 +1791,16 @@ class ModbusSlave extends EventEmitter {
1789
1791
  }
1790
1792
  }
1791
1793
  }
1792
- handleFC6(frame, response) {
1793
- var _a, _b;
1794
+ handleFC6(model, frame, response) {
1795
+ var _a;
1794
1796
  if (frame.data.length === 4) {
1795
- if (this.model.writeSingleRegister) {
1797
+ if (model.writeSingleRegister) {
1796
1798
  const bufferRx = Buffer.from(frame.data);
1797
1799
  const address = bufferRx.readUInt16BE(0);
1798
1800
  const value = bufferRx.readUInt16BE(2);
1799
1801
  if (value >= 0x0000 && value <= 0xffff) {
1800
- if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1801
- 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))
1802
1804
  .then(() => {
1803
1805
  response(this.applicationLayer.encode(frame));
1804
1806
  })
@@ -1819,20 +1821,20 @@ class ModbusSlave extends EventEmitter {
1819
1821
  }
1820
1822
  }
1821
1823
  }
1822
- handleFC15(frame, response) {
1823
- var _a, _b;
1824
+ handleFC15(model, frame, response) {
1825
+ var _a;
1824
1826
  if (frame.data.length > 5 && frame.data.length === 5 + frame.data[4]) {
1825
- if (this.model.writeMultipleCoils || this.model.writeSingleCoil) {
1827
+ if (model.writeMultipleCoils || model.writeSingleCoil) {
1826
1828
  const bufferRx = Buffer.from(frame.data);
1827
1829
  const address = bufferRx.readUInt16BE(0);
1828
1830
  const length = bufferRx.readUInt16BE(2);
1829
1831
  const byteCount = bufferRx[4];
1830
1832
  if (length >= 0x0001 && length <= 0x07b0 && byteCount === Math.ceil(length / 8)) {
1831
- 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)) {
1832
1834
  const value = Array.from({ length }).map((_, index) => (bufferRx[5 + ~~(index / 8)] & (1 << index % 8)) > 0);
1833
- Promise.resolve(this.model.writeMultipleCoils
1834
- ? this.model.writeMultipleCoils(address, value)
1835
- : 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))))
1836
1838
  .then(() => {
1837
1839
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: Array.from(bufferRx).slice(0, 4) })));
1838
1840
  })
@@ -1853,20 +1855,20 @@ class ModbusSlave extends EventEmitter {
1853
1855
  }
1854
1856
  }
1855
1857
  }
1856
- handleFC16(frame, response) {
1857
- var _a, _b;
1858
+ handleFC16(model, frame, response) {
1859
+ var _a;
1858
1860
  if (frame.data.length > 5 && frame.data.length === 5 + frame.data[4]) {
1859
- if (this.model.writeMultipleRegisters || this.model.writeSingleRegister) {
1861
+ if (model.writeMultipleRegisters || model.writeSingleRegister) {
1860
1862
  const bufferRx = Buffer.from(frame.data);
1861
1863
  const address = bufferRx.readUInt16BE(0);
1862
1864
  const length = bufferRx.readUInt16BE(2);
1863
1865
  const byteCount = bufferRx[4];
1864
1866
  if (length >= 0x0001 && length <= 0x007b && byteCount === length * 2) {
1865
- 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)) {
1866
1868
  const value = Array.from({ length }).map((_, index) => bufferRx.readUInt16BE(5 + index * 2));
1867
- Promise.resolve(this.model.writeMultipleRegisters
1868
- ? this.model.writeMultipleRegisters(address, value)
1869
- : 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))))
1870
1872
  .then(() => {
1871
1873
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: Array.from(bufferRx).slice(0, 4) })));
1872
1874
  })
@@ -1887,11 +1889,13 @@ class ModbusSlave extends EventEmitter {
1887
1889
  }
1888
1890
  }
1889
1891
  }
1890
- handleFC17(frame, response) {
1892
+ handleFC17(model, frame, response) {
1891
1893
  if (frame.data.length === 0) {
1892
- if (this.model.reportServerId) {
1893
- Promise.resolve(this.model.reportServerId())
1894
- .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;
1895
1899
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: [2 + additionalData.length, serverId, runIndicatorStatus ? 0xff : 0x00].concat(additionalData) })));
1896
1900
  })
1897
1901
  .catch((error) => {
@@ -1903,19 +1907,19 @@ class ModbusSlave extends EventEmitter {
1903
1907
  }
1904
1908
  }
1905
1909
  }
1906
- handleFC22(frame, response) {
1907
- var _a, _b;
1910
+ handleFC22(model, frame, response) {
1911
+ var _a;
1908
1912
  if (frame.data.length === 6) {
1909
- if (this.model.maskWriteRegister || (this.model.readHoldingRegisters && this.model.writeSingleRegister)) {
1913
+ if (model.maskWriteRegister || (model.readHoldingRegisters && model.writeSingleRegister)) {
1910
1914
  const bufferRx = Buffer.from(frame.data);
1911
1915
  const address = bufferRx.readUInt16BE(0);
1912
1916
  const andMask = bufferRx.readUInt16BE(2);
1913
1917
  const orMask = bufferRx.readUInt16BE(4);
1914
- if (checkRange(address, (_b = (_a = this.model).getAddressRange) === null || _b === void 0 ? void 0 : _b.call(_a).holdingRegisters)) {
1915
- Promise.resolve(this.model.maskWriteRegister
1916
- ? this.model.maskWriteRegister(address, andMask, orMask)
1917
- : Promise.resolve(this.model.readHoldingRegisters(address, 1)).then(([value]) => {
1918
- 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))));
1919
1923
  }))
1920
1924
  .then(() => {
1921
1925
  response(this.applicationLayer.encode(frame));
@@ -1933,10 +1937,10 @@ class ModbusSlave extends EventEmitter {
1933
1937
  }
1934
1938
  }
1935
1939
  }
1936
- handleFC23(frame, response) {
1937
- var _a, _b;
1940
+ handleFC23(model, frame, response) {
1941
+ var _a;
1938
1942
  if (frame.data.length > 9 && frame.data.length === 9 + frame.data[8]) {
1939
- if (this.model.readHoldingRegisters && (this.model.writeMultipleRegisters || this.model.writeSingleRegister)) {
1943
+ if (model.readHoldingRegisters && (model.writeMultipleRegisters || model.writeSingleRegister)) {
1940
1944
  const bufferRx = Buffer.from(frame.data);
1941
1945
  const address = {
1942
1946
  read: bufferRx.readUInt16BE(0),
@@ -1952,12 +1956,12 @@ class ModbusSlave extends EventEmitter {
1952
1956
  length.write >= 0x0001 &&
1953
1957
  length.write <= 0x0079 &&
1954
1958
  byteCount === length.write * 2) {
1955
- 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)) {
1956
1960
  const value = Array.from({ length: length.write }).map((_, index) => bufferRx.readUInt16BE(9 + index * 2));
1957
- Promise.resolve(this.model.writeMultipleRegisters
1958
- ? this.model.writeMultipleRegisters(address.write, value)
1959
- : Promise.all(value.map((v, i) => this.model.writeSingleRegister(address.write + i, v))))
1960
- .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)))
1961
1965
  .then((registers) => {
1962
1966
  const bufferTx = Buffer.alloc(length.read * 2);
1963
1967
  registers.forEach((register, index) => {
@@ -1982,9 +1986,9 @@ class ModbusSlave extends EventEmitter {
1982
1986
  }
1983
1987
  }
1984
1988
  }
1985
- handleFC43_14(frame, response) {
1989
+ handleFC43_14(model, frame, response) {
1986
1990
  if (frame.data.length === 3) {
1987
- if (frame.data[0] === 0x0e && this.model.readDeviceIdentification) {
1991
+ if (frame.data[0] === 0x0e && model.readDeviceIdentification) {
1988
1992
  const readDeviceIDCode = frame.data[1];
1989
1993
  let objectID = frame.data[2];
1990
1994
  switch (readDeviceIDCode) {
@@ -2018,7 +2022,7 @@ class ModbusSlave extends EventEmitter {
2018
2022
  return;
2019
2023
  }
2020
2024
  }
2021
- Promise.resolve(this.model.readDeviceIdentification())
2025
+ Promise.resolve(model.readDeviceIdentification())
2022
2026
  .then((identification) => {
2023
2027
  const objects = new Map([
2024
2028
  [0x00, 'null'],
@@ -2096,6 +2100,13 @@ class ModbusSlave extends EventEmitter {
2096
2100
  responseError(frame, response, error) {
2097
2101
  response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { fc: frame.fc | 0x80, data: [getCodeByError(error)] })));
2098
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
+ }
2099
2110
  open(...args) {
2100
2111
  return this.physicalLayer.open(...args);
2101
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 {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "njs-modbus",
3
- "version": "1.3.5",
3
+ "version": "1.4.0",
4
4
  "description": "A pure JavaScript implemetation of Modbus for NodeJS.",
5
5
  "keywords": [
6
6
  "modbus",