nodbus-plus 0.8.2 → 1.0.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.
Files changed (101) hide show
  1. package/.readthedocs.yaml +35 -0
  2. package/LICENSE.md +21 -21
  3. package/README.md +163 -48
  4. package/docs/Makefile +20 -0
  5. package/docs/client/channel.rst +209 -0
  6. package/docs/client/nodbus_master_serial.rst +559 -0
  7. package/docs/client/nodbus_master_tcp.rst +573 -0
  8. package/docs/conf.py +41 -0
  9. package/docs/images/01-readcoils.png +0 -0
  10. package/docs/images/02-readinputs.png +0 -0
  11. package/docs/images/03-readholding.png +0 -0
  12. package/docs/images/04-readinputsreg.png +0 -0
  13. package/docs/images/05-writecoil.png +0 -0
  14. package/docs/images/06-writeregister.png +0 -0
  15. package/docs/images/15-writecoil.png +0 -0
  16. package/docs/images/16.png +0 -0
  17. package/docs/images/22-mask.png +0 -0
  18. package/docs/images/23.png +0 -0
  19. package/docs/images/7.png +0 -0
  20. package/docs/images/modbus_pdu.png +0 -0
  21. package/docs/images/serial_adu.png +0 -0
  22. package/docs/images/tcp_adu.png +0 -0
  23. package/docs/index.rst +30 -0
  24. package/docs/make.bat +35 -0
  25. package/docs/protocol/modbus_master.rst +276 -0
  26. package/docs/protocol/modbus_master_serial.rst +290 -0
  27. package/docs/protocol/modbus_master_tcp.rst +296 -0
  28. package/docs/protocol/modbus_server.rst +469 -0
  29. package/docs/protocol/modbus_server_serial.rst +543 -0
  30. package/docs/protocol/modbus_server_tcp.rst +365 -0
  31. package/docs/requirements.txt +4 -0
  32. package/docs/server/net_server.rst +242 -0
  33. package/docs/server/nodbus_serial_server.rst +652 -0
  34. package/docs/server/nodbus_tcp_server.rst +505 -0
  35. package/docs/starting.rst +192 -0
  36. package/docs/static/simple logo.jpg +0 -0
  37. package/package.json +39 -30
  38. package/samples/mb_serial_server.js +77 -0
  39. package/samples/mb_tcp_client.js +114 -0
  40. package/samples/mb_tcp_server.js +58 -0
  41. package/src/client/net/serialchannel.js +195 -0
  42. package/src/client/net/tcpchannel.js +233 -0
  43. package/src/client/net/udpchannel.js +243 -0
  44. package/src/client/nodbus_serial_client.js +577 -0
  45. package/src/client/nodbus_tcp_client.js +542 -0
  46. package/src/nodbus-plus.js +157 -110
  47. package/src/protocol/modbus_master.js +298 -961
  48. package/src/protocol/modbus_master_serial.js +247 -0
  49. package/src/protocol/modbus_master_tcp.js +219 -0
  50. package/src/protocol/modbus_server.js +936 -0
  51. package/src/protocol/modbus_server_serial.js +368 -0
  52. package/src/protocol/modbus_server_tcp.js +129 -0
  53. package/src/protocol/utils.js +296 -0
  54. package/src/server/net/serialserver.js +184 -0
  55. package/src/server/net/tcpserver.js +290 -0
  56. package/src/server/net/udpserver.js +242 -0
  57. package/src/server/nodbus_serial_server.js +238 -0
  58. package/src/server/nodbus_tcp_server.js +249 -0
  59. package/test/modbus_master.test.js +279 -0
  60. package/test/modbus_master_serial.test.js +124 -0
  61. package/test/modbus_master_tcp.test.js +178 -0
  62. package/test/modbus_server.test.js +506 -0
  63. package/test/modbus_server_serial.test.js +328 -0
  64. package/test/modbus_server_tcp.test.js +91 -0
  65. package/test/nodbus_client_serial.test.js +307 -0
  66. package/test/nodbus_client_tcp.test.js +334 -0
  67. package/test/nodbus_server_serial.test.js +255 -0
  68. package/test/nodbus_server_tcp.test.js +216 -0
  69. package/CHANGELOG.md +0 -27
  70. package/src/client/m_stcp_client.js +0 -214
  71. package/src/client/m_tcp_client.js +0 -234
  72. package/src/net/tcpclient.js +0 -173
  73. package/src/net/tcpserver.js +0 -329
  74. package/src/protocol/adu.js +0 -40
  75. package/src/protocol/ascii_adu.js +0 -139
  76. package/src/protocol/boolean_register.js +0 -78
  77. package/src/protocol/functions/Force_Multiple_Coils.js +0 -76
  78. package/src/protocol/functions/Force_Single_Coil.js +0 -54
  79. package/src/protocol/functions/Mask_Holding_Register.js +0 -47
  80. package/src/protocol/functions/Preset_Multiple_Registers.js +0 -53
  81. package/src/protocol/functions/Preset_Single_Register.js +0 -39
  82. package/src/protocol/functions/Read_Coil_Status.js +0 -59
  83. package/src/protocol/functions/Read_Holding_Registers.js +0 -52
  84. package/src/protocol/functions/Read_Input_Registers.js +0 -52
  85. package/src/protocol/functions/Read_Input_Status.js +0 -58
  86. package/src/protocol/mbap.js +0 -60
  87. package/src/protocol/modbus_device.js +0 -35
  88. package/src/protocol/modbus_slave.js +0 -522
  89. package/src/protocol/pdu.js +0 -70
  90. package/src/protocol/rtu_adu.js +0 -122
  91. package/src/protocol/serial_adu.js +0 -29
  92. package/src/protocol/tcp_adu.js +0 -84
  93. package/src/protocol/word_register.js +0 -122
  94. package/src/server/m_stcp_server.js +0 -310
  95. package/src/server/m_tcp_server.js +0 -295
  96. package/test/modbus-stcp-server-test.js +0 -72
  97. package/test/modbus-stcp-server-test1.js +0 -72
  98. package/test/modbus-tcp-client-test.js +0 -159
  99. package/test/modbus-tcp-server-test.js +0 -75
  100. package/test/modbus-tcp-server-test2.js +0 -75
  101. package/test/modbus_stcp_client.js +0 -149
@@ -0,0 +1,238 @@
1
+ /**
2
+ * Modbus Serial encapsulated on Tcp server module.
3
+ * @module server/m_stcp_server.
4
+ * @author Hector E. Socarras.
5
+ * @version 0.4.0
6
+ */
7
+
8
+ const ModbusSerialServer = require('../protocol/modbus_server_serial');
9
+ const SerialServer = require('./net/serialserver');
10
+ const TcpServer = require('./net/tcpserver');
11
+
12
+ //Default Server's Configuration object
13
+ const defaultCfg = {
14
+ transmitionMode : 0, //transmition mode 0-auto, 1-rtu, 2-ascii
15
+ address : 1,
16
+ inputs : 2048,
17
+ coils : 2048,
18
+ holdingRegisters : 2048,
19
+ inputRegisters : 2048,
20
+ udpType : 'udp4',
21
+ timeBetweenFrame : 20,
22
+ }
23
+
24
+
25
+ /**
26
+ * Class representing a modbus serial server fully functional.
27
+ * @extends ModbusSerialServer
28
+ */
29
+ class NodbusSerialServer extends ModbusSerialServer {
30
+ /**
31
+ * Create a Modbus Tcp Server.
32
+ * @param {object} config object.
33
+ * @param {number} netClass: Constructor for network object
34
+ *
35
+ */
36
+ constructor(netClass = SerialServer, mbTcpServerCfg = defaultCfg){
37
+ super(mbTcpServerCfg);
38
+
39
+ var self = this;
40
+
41
+ //arguments check
42
+ mbTcpServerCfg.tcpCoalescingDetection = false;
43
+ if(mbTcpServerCfg.maxConnections == undefined){ mbTcpServerCfg.maxConnections = defaultCfg.maxConnections}
44
+ if(mbTcpServerCfg.udpType != 'udp4' & mbTcpServerCfg.udpType != 'udp6'){ mbTcpServerCfg.udpType = defaultCfg.udpType}
45
+
46
+ /**
47
+ * network layer
48
+ * @type {object}
49
+ */
50
+ try {
51
+ this.net = new netClass(mbTcpServerCfg);
52
+ }
53
+ catch(e){
54
+ this.emit('error', e);
55
+ this.net = new TcpServer(mbTcpServerCfg);
56
+ }
57
+
58
+ //Adding listeners to netServer events
59
+ //function to call by net interface when data arrive.
60
+ this.net.onDataHook = (socket, dataFrame) => {
61
+ /**
62
+ * indication event.
63
+ * @event ModbusnetServer#indication
64
+ */
65
+ this.emit('data', socket, dataFrame);
66
+ };
67
+
68
+ this.net.onMbAduHook = (sock, adu) =>{
69
+
70
+ let pdu = this.getPdu(adu);
71
+ let req = {};
72
+
73
+ req.timeStamp = Date.now();
74
+ req.address = this.getAddress(adu)
75
+ req.checkSum = this.getChecksum(adu);
76
+ req.functionCode = pdu[0];
77
+ req.data = pdu.subarray(1);
78
+
79
+ this.emit('request', sock, req);
80
+
81
+ let resAdu;
82
+ if(req.address == 0){
83
+ this.executeBroadcastReq(adu);
84
+ }
85
+ else{
86
+ resAdu = this.getResponseAdu(adu);
87
+ let resPdu = this.getPdu(resAdu);
88
+ let res = {};
89
+
90
+ res.timeStamp = Date.now();
91
+ res.address = this.address;
92
+ res.checkSum = this.getChecksum(resAdu);
93
+ res.functionCode = pdu[0];
94
+ res.data = resPdu.subarray(1);
95
+ this.emit('response',sock, res);
96
+ this.net.write(sock, resAdu);
97
+ }
98
+
99
+ };
100
+
101
+
102
+ /**
103
+ * Event listening
104
+ * Emited when server is listening
105
+ * @see https://nodejs.org/api/net.html
106
+ * @fires ModbusnetServer#listening
107
+ */
108
+ this.net.onListeningHook = () => {
109
+ /**
110
+ * listening event.
111
+ * @event ModbusNetServer#listening
112
+ * @type {number}
113
+ */
114
+ this.emit('listening',self.port);
115
+ };
116
+
117
+ /**
118
+ * Event closed
119
+ * Emited when server is closed
120
+ * @see https://nodejs.org/api/net.html
121
+ * @fires ModbusnetServer#closed
122
+ */
123
+ this.net.onServerCloseHook = () => {
124
+ /**
125
+ * closed event.
126
+ * @event ModbusNetServer#closed
127
+ */
128
+ this.emit('closed');
129
+ };
130
+
131
+
132
+ /**
133
+ * Event error
134
+ * Emited when error hapen
135
+ * @fires ModbusNetServer#error
136
+ */
137
+ this.net.onErrorHook = (err) =>{
138
+ /**
139
+ * error event.
140
+ * @event ModbusNetServer#error
141
+ */
142
+ this.emit('error', err);
143
+ };
144
+
145
+ /**
146
+ * Event response
147
+ * Emited when response is send to master
148
+ * @fires ModbusnetServer#response
149
+ */
150
+ this.net.onWriteHook = (sock, resAdu) => {
151
+ /**
152
+ * response event.
153
+ * @event ModbusnetServer#response
154
+ */
155
+ this.emit('write', sock, resAdu);
156
+
157
+ };
158
+
159
+
160
+
161
+ /**
162
+ * current req
163
+ * If another req arrive while the current req is not null, exepction 5 should be sended
164
+ * @type {Array}
165
+ */
166
+ this.currentRequest = null;
167
+
168
+ //Function to validate data in net layer
169
+ this.net.validateFrame = (frame)=>{
170
+ //validating length of message
171
+
172
+ if(frame.length >= 3){
173
+ //validating crc
174
+ if(this.validateCheckSum(frame)){
175
+
176
+ this.busMessageCount++; //inc message counter
177
+
178
+ if(this.validateAddress(frame)){
179
+ return true
180
+ }
181
+ else{
182
+ return false
183
+ }
184
+ }
185
+ else{
186
+ this.busCommunicationErrorCount++;
187
+ return false;
188
+ }
189
+ }
190
+ else{
191
+ this.busCommunicationErrorCount++;
192
+ return false;
193
+ }
194
+ };
195
+
196
+ //Sealling net layer object
197
+ Object.defineProperty(self, 'net', {
198
+ enumerable:false,
199
+ writable:false,
200
+ configurable:false
201
+ })
202
+
203
+ }
204
+
205
+ /**
206
+ * Getter listening status
207
+ */
208
+ get isListening(){
209
+ return this.net.isListening;
210
+ }
211
+
212
+ get port(){
213
+ return this.net.port
214
+ }
215
+
216
+ set port(newport){
217
+ this.net.port = newport
218
+ }
219
+
220
+ /**
221
+ * Function to start the server
222
+ */
223
+ start(){
224
+ this.net.start();
225
+ }
226
+
227
+ /**
228
+ * Function to stop the server
229
+ */
230
+ stop(){
231
+ this.net.stop();
232
+ }
233
+
234
+
235
+
236
+ }
237
+
238
+ module.exports = NodbusSerialServer;
@@ -0,0 +1,249 @@
1
+ /**
2
+ * A fully functional Modbus Tcp protocol server.
3
+ * @module server/mb_tcp_server.
4
+ * @author Hector E. Socarras.
5
+ * @version 1.0.0
6
+ */
7
+
8
+ const ModbusTcpServer = require('../protocol/modbus_server_tcp');
9
+ const TcpServer = require('./net/tcpserver');
10
+ const UdpServer = require('./net/udpserver');
11
+
12
+ //Default Server's Configuration object
13
+ const defaultCfg = {
14
+ inputs : 2048,
15
+ coils : 2048,
16
+ holdingRegisters : 2048,
17
+ inputRegisters : 2048,
18
+ port : 502,
19
+ maxConnections : 32,
20
+ udpType : 'udp4',
21
+ tcpCoalescingDetection: true
22
+ }
23
+
24
+ /**
25
+ * Class representing a modbus tcp server fully functional.
26
+ * @extends ModbusTcpServer
27
+ */
28
+ class NodbusTcpServer extends ModbusTcpServer {
29
+ /**
30
+ * Create a Modbus Tcp Server.
31
+ * @param {object} config object.
32
+ * @param {number} netClass: Constructor for network object
33
+ *
34
+ */
35
+ constructor(netClass = TcpServer, mbTcpServerCfg = defaultCfg){
36
+ super(mbTcpServerCfg);
37
+ let self = this;
38
+
39
+ //arguments check
40
+ mbTcpServerCfg.tcpCoalescingDetection = true;
41
+ if(mbTcpServerCfg.port == undefined){ mbTcpServerCfg.port = defaultCfg.port}
42
+ if(mbTcpServerCfg.maxConnections == undefined){ mbTcpServerCfg.maxConnections = defaultCfg.maxConnections}
43
+ if(mbTcpServerCfg.udpType != 'udp4' & mbTcpServerCfg.udpType != 'udp6'){ mbTcpServerCfg.udpType = defaultCfg.udpType}
44
+
45
+ /**
46
+ * network layer
47
+ * @type {object}
48
+ */
49
+ try {
50
+ this.net = new netClass(mbTcpServerCfg);
51
+ }
52
+ catch(e){
53
+ this.emit('error', e);
54
+ this.net = new TcpServer(mbTcpServerCfg);
55
+ }
56
+
57
+
58
+ //Adding listeners to netServer events
59
+ //function to call by net interface when data arrive.
60
+ this.net.onDataHook = (socket, dataFrame) => {
61
+ /**
62
+ * indication event.
63
+ * @event ModbusnetServer#indication
64
+ */
65
+ this.emit('data', socket, dataFrame);
66
+ };
67
+
68
+ this.net.onMbAduHook = (sock, adu) =>{
69
+
70
+ //Checking PDU Modbus Tcp Implementation Guide Figure 16
71
+ let header = this.getMbapHeader(adu);
72
+ if(this.validateMbapHeader(header)){
73
+ let pdu = this.getPdu(adu);
74
+ let req = {};
75
+
76
+ req.timeStamp = Date.now();
77
+ req.transactionId = header.readUint16BE(0);
78
+ req.unitId = header[6];
79
+ req.functionCode = pdu[0];
80
+ req.data = pdu.subarray(1);
81
+
82
+ this.emit('request', sock, req);
83
+
84
+ let resAdu = this.getResponseAdu(adu)
85
+ let res = {};
86
+
87
+ res.timeStamp = Date.now();
88
+ res.transactionId = resAdu.readUint16BE(0);
89
+ res.unitId = resAdu[6];
90
+ res.functionCode = resAdu[7];
91
+ res.data = resAdu.subarray(8);
92
+ this.emit('response',sock, res)
93
+ this.net.write(sock, resAdu)
94
+ }
95
+ else return
96
+
97
+ };
98
+
99
+ /**
100
+ * @fires ModbusnetServer#connection
101
+ */
102
+ this.net.onConnectionAcceptedHook = (socket) => {
103
+ /**
104
+ * connection event.
105
+ * Emited when new connecton is sablished
106
+ * @event ModbusnetServer#connection
107
+ * @type {object}
108
+ * @see https://nodejs.org/api/net.html
109
+ */
110
+ this.emit('connection',socket);
111
+ };
112
+
113
+
114
+ /**
115
+ * Event connection closed
116
+ * Emited when socket closed
117
+ * @see https://nodejs.org/api/net.html
118
+ * @fires ModbusnetServer#connection-closed
119
+ */
120
+ this.net.onConnectionCloseHook = (socket) => {
121
+ /**
122
+ * connection-closed event.
123
+ * @event ModbusnetServer#connection-closed
124
+ * @type {object}
125
+ */
126
+ this.emit('connection-closed', socket)
127
+ };
128
+
129
+
130
+ /**
131
+ * Event listening
132
+ * Emited when server is listening
133
+ * @see https://nodejs.org/api/net.html
134
+ * @fires ModbusnetServer#listening
135
+ */
136
+ this.net.onListeningHook = () => {
137
+ /**
138
+ * listening event.
139
+ * @event ModbusNetServer#listening
140
+ * @type {number}
141
+ */
142
+ this.emit('listening',self.port);
143
+ };
144
+
145
+ /**
146
+ * Event closed
147
+ * Emited when server is closed
148
+ * @see https://nodejs.org/api/net.html
149
+ * @fires ModbusnetServer#closed
150
+ */
151
+ this.net.onServerCloseHook = () => {
152
+ /**
153
+ * closed event.
154
+ * @event ModbusNetServer#closed
155
+ */
156
+ this.emit('closed');
157
+ };
158
+
159
+ /**
160
+ * Event error
161
+ * Emited when error hapen
162
+ * @fires ModbusNetServer#error
163
+ */
164
+ this.net.onErrorHook = (err) =>{
165
+ /**
166
+ * error event.
167
+ * @event ModbusNetServer#error
168
+ */
169
+ this.emit('error', err);
170
+ };
171
+
172
+ /**
173
+ * Event response
174
+ * Emited when response is send to master
175
+ * @fires ModbusnetServer#response
176
+ */
177
+ this.net.onWriteHook = (sock, resAdu) => {
178
+ /**
179
+ * response event.
180
+ * @event ModbusnetServer#response
181
+ */
182
+ this.emit('write', sock, resAdu);
183
+
184
+ };
185
+
186
+ //Function to validate data in net layer
187
+ this.net.validateFrame = (frame)=>{
188
+ if(frame.length > 7){
189
+
190
+ let expectedLength = frame.readUInt16BE(4) + 6;
191
+ let protocolId = frame.readUInt16BE(2);
192
+ return frame.length == expectedLength & protocolId == 0;
193
+ }
194
+ return false;
195
+ }
196
+
197
+
198
+
199
+ //Sealling net layer object
200
+ Object.defineProperty(self, 'net', {
201
+ enumerable:false,
202
+ writable:false,
203
+ configurable:false
204
+ })
205
+
206
+ }
207
+
208
+ /**
209
+ * Getter listening status
210
+ */
211
+ get isListening(){
212
+ return this.net.isListening;
213
+ }
214
+
215
+ get maxConnections(){
216
+ return this.net.maxConnections;
217
+ }
218
+
219
+ set maxConnections(max){
220
+ this.net.maxConnections = max;
221
+ }
222
+
223
+ get port(){
224
+ return this.net.port
225
+ }
226
+
227
+ set port(newport){
228
+ this.net.port = newport
229
+ }
230
+
231
+ /**
232
+ * Function to start the server
233
+ */
234
+ start(){
235
+ this.net.start();
236
+ }
237
+
238
+ /**
239
+ * Function to stop the server
240
+ */
241
+ stop(){
242
+ this.net.stop();
243
+ }
244
+
245
+
246
+ }
247
+
248
+ module.exports = NodbusTcpServer;
249
+