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,296 @@
1
+ /**
2
+ * Calculate the crc from a modbus rtu's frame.
3
+ * @param {Buffer} frame The complete modbus rtu frame.
4
+ * @return {number} The CRC.
5
+ */
6
+ function calcCRC(frame){
7
+
8
+ var crc_hi = 0xFF;
9
+ var crc_lo = 0xFF;
10
+ var index;
11
+
12
+ var auxcrc_hi = [0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
13
+ 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
14
+ 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
15
+ 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
16
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
17
+ 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
18
+ 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
19
+ 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
20
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
21
+ 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
22
+ 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
23
+ 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
24
+ 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
25
+ 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
26
+ 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
27
+ 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
28
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
29
+ 0x40];
30
+
31
+ var auxcrc_lo = [0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
32
+ 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
33
+ 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
34
+ 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
35
+ 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
36
+ 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
37
+ 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
38
+ 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
39
+ 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
40
+ 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
41
+ 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
42
+ 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
43
+ 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
44
+ 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
45
+ 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
46
+ 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
47
+ 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
48
+ 0x40];
49
+
50
+ for(var i = 0; i< frame.length-2; i++) {
51
+ index = crc_hi ^ frame[i];
52
+ crc_hi = crc_lo ^ auxcrc_hi[index];
53
+ crc_lo = auxcrc_lo[index];
54
+ }
55
+ return (crc_hi << 8 | crc_lo);
56
+
57
+ }
58
+
59
+ /**
60
+ * Calculate de LRC from a modbus ascii's frame.
61
+ * @param {Buffer} frame The complete modbus ascii frame.
62
+ * @return {number} The LRC.
63
+ */
64
+ function calcLRC(frame){
65
+
66
+ var bufferBytes = Buffer.alloc(Math.floor((frame.length-5)/2));
67
+ var byteLRC = Buffer.alloc(1);
68
+
69
+ for(var i = 0; i < bufferBytes.length; i++){
70
+ bufferBytes[i]=Number('0x'+ frame.toString('ascii',2*i+1 ,2*i+3));
71
+ }
72
+
73
+ for(var i = 0; i < bufferBytes.length;i++){
74
+ byteLRC[0] = byteLRC[0] + bufferBytes[i];
75
+ }
76
+
77
+ var lrc_temp = Buffer.alloc(1);
78
+ lrc_temp[0] = -byteLRC[0];
79
+ var lrc = lrc_temp.readUInt8(0)
80
+ return lrc;
81
+
82
+ }
83
+
84
+ /**
85
+ *function to convert a uint8 in 2 chars lenght buffer
86
+ *@param {number} uint8Val;
87
+ *@return {Buffer}
88
+ */
89
+ function valByte2Chars (uint8Val){
90
+
91
+ let temp = Buffer.alloc(2);
92
+
93
+ //get LSB part
94
+ temp.write((uint8Val & 0x0F).toString(16).toUpperCase(), 1);
95
+ //get msb
96
+ temp.write((uint8Val >> 4).toString(16).toUpperCase());
97
+
98
+ return temp;
99
+ }
100
+
101
+ /**
102
+ * This function calculate the necesary buffer to realize the desired mask function
103
+ * @param {Array} valueArray Array of numbers, values 1 on position that want to be true, 0 on position that
104
+ * want to be false and -1 in position that must be unchanged.
105
+ * example register value: [0 1 1 0 1 1 0 0 0 1 1 1 1 0 0 1] 0x9E36
106
+ * set register value: [1 0 0 1 -1 0 1 -1 -1 -1 0 0 1 1 -1 0]
107
+ * final register value: [1 0 0 1 1 0 1 0 0 1 0 0 1 1 0 0] 0x3259
108
+ * @returns {Buffer} Buffer value with AND MASK and OR MASK for modbus 0x16 function.
109
+ */
110
+ function getMaskRegisterBuffer(valueArray){
111
+
112
+ let value = Buffer.alloc(4);
113
+ let AND_Mask = 0;
114
+ let OR_Mask = 0xFFFF;
115
+ let tempMask = 1;
116
+ let iteratorLimit = 16;
117
+
118
+ if(valueArray.length < 16){
119
+ iteratorLimit = valueArray.length;
120
+ }
121
+
122
+
123
+ for (let i = 0; i < iteratorLimit; i++){
124
+
125
+ if(valueArray[i] == 1){
126
+ //AND_MASK = 0;
127
+ //OR_Mask = 1;
128
+ }
129
+ else if(valueArray[i] == 0){
130
+ //AND_MASK = 0;
131
+ //OR_MASK = 0
132
+ OR_Mask = OR_Mask & (~tempMask); //temp mask negated is 1111 1110 for i = 0
133
+
134
+ }
135
+ else{
136
+ //AND_MASK = 1;
137
+ //OR_MASK = 1
138
+ AND_Mask = AND_Mask | tempMask;
139
+ }
140
+
141
+ tempMask = tempMask << 1;
142
+ }
143
+
144
+ value.writeUInt16BE(AND_Mask);
145
+ value.writeUInt16BE(OR_Mask, 2);
146
+
147
+ return value;
148
+
149
+ }
150
+
151
+ /**
152
+ * Function to get a Buffer from an Array of boolean
153
+ * @param {Array} boolArray Boolena Array to encoded to a buffer
154
+ * @return {Buffer}
155
+ */
156
+ function boolsToBuffer(boolArray){
157
+
158
+ let bufValue = Buffer.alloc(Math.ceil(boolArray.length/8)); //Example 10 bools arrays need two bytes length buffer
159
+ let index = 0;
160
+ let byteOffset = 0;
161
+ let orMask = 0x01;
162
+
163
+
164
+ for(i = 0; i < boolArray.length; i++){
165
+ index = Math.floor((i)/8); //get the index in the buffer. example 0 for values between 0 -7;
166
+ byteOffset = i % 8;
167
+ orMask = 0x01;
168
+
169
+
170
+ if(boolArray[i]){
171
+ bufValue[index] = bufValue[index] | (orMask << byteOffset);
172
+ }
173
+
174
+ }
175
+
176
+ return bufValue;
177
+ }
178
+
179
+
180
+ /**
181
+ * Function to convert a asccii frame to rtu to be processed
182
+ * @param {Buffer} asciiFrame
183
+ * @returns {Buffer} a equivalent rtu buffer
184
+ */
185
+ function aduAsciiToRtu(asciiFrame){
186
+
187
+
188
+ //creating rtu frame. content frame + 2 bytes for crc
189
+ let rtuFrame = Buffer.alloc((asciiFrame.length-1)/2);
190
+
191
+ //droping first character (:), lrc and ending character(CR, LF) see Mover over serial line 1.02 b
192
+ for(let i = 0; i < asciiFrame.length - 4; i++){
193
+ rtuFrame[i] = Number('0x'+ asciiFrame.toString('ascii', 2*i + 1 , 2*i + 3));
194
+ }
195
+
196
+ let crc = calcCRC(rtuFrame);
197
+ rtuFrame.writeUInt16BE(crc,rtuFrame.length - 2);
198
+
199
+ return rtuFrame;
200
+
201
+ }
202
+
203
+ /**
204
+ * Function to convert a rtu frame to ascii to be responsed
205
+ * @param {Buffre} rtuFrame
206
+ * @returns {Buffer} a equivalent ascii buffer
207
+ */
208
+ function aduRtuToAscii(rtuFrame){
209
+
210
+ //creating ascii frame. rtu frame * 2 + 1bytes for ':'
211
+ let asciiFrame = Buffer.alloc(rtuFrame.length * 2 + 1);
212
+ asciiFrame[0] = 0x3A;
213
+ asciiFrame[asciiFrame.length - 2] = 0x0D;
214
+ asciiFrame[asciiFrame.length - 1] = 0x0A;
215
+
216
+ //LRC calculation
217
+ let byteLRC = Buffer.alloc(1);
218
+
219
+ //chars value
220
+ let charsBuffer = Buffer.alloc(2);
221
+
222
+ for(let i = 0; i < rtuFrame.length - 2; i++){
223
+ byteLRC[0] = byteLRC[0] + rtuFrame[i];
224
+ charsBuffer = valByte2Chars(rtuFrame[i])
225
+ charsBuffer.copy(asciiFrame, 2*i + 1)
226
+ }
227
+
228
+ byteLRC[0] = -byteLRC[0]
229
+ //get lrc chars
230
+ charsBuffer = valByte2Chars(byteLRC[0]);
231
+ charsBuffer.copy(asciiFrame, asciiFrame.length - 4);
232
+
233
+ return asciiFrame;
234
+ }
235
+
236
+ /**
237
+ * Low level api function to get a 2 bytes word value from buffer.
238
+ * @param {Buffer} targetBuffer buffer object to read
239
+ * @param {number} offset integer value with bit address.
240
+ * @return {Buffer} 2 bytes length buffer
241
+ * @throws {RangeError} if offset is out of buffer's bound.
242
+ */
243
+ function getWordFromBuffer(targetBuffer, offset = 0){
244
+
245
+ if(offset < targetBuffer.length / 2){
246
+
247
+ let value = Buffer.alloc(2);
248
+ value[0] = targetBuffer[offset * 2];
249
+ value[1] = targetBuffer[offset*2 + 1];
250
+
251
+ return value;
252
+
253
+ }
254
+ else{
255
+ throw new RangeError("offset is out of buffer bounds");
256
+ }
257
+ }
258
+
259
+ /**
260
+ * Low level api function to set a 2 bytes word value into buffer.
261
+ * @param {Buffer} value 2 bytes long buffer object to write
262
+ * @param {Buffer} targetBuffer buffer object to write
263
+ * @param {number} offset integer value with offset in the buffer.
264
+ * @throws {RangeError} if offset is out of buffer's bound.
265
+ */
266
+ function setWordToBuffer(value, targetBuffer, offset = 0){
267
+
268
+ if(offset < targetBuffer.length / 2){
269
+
270
+ targetBuffer[offset * 2] = value[0];
271
+ targetBuffer[offset*2 + 1] = value[1];
272
+
273
+
274
+ }
275
+ else{
276
+ throw new RangeError("offset is out of buffer bounds");
277
+ }
278
+ }
279
+
280
+ module.exports.calcCRC = calcCRC;
281
+
282
+ module.exports.calcLRC = calcLRC;
283
+
284
+ module.exports.valByteToChars = valByte2Chars;
285
+
286
+ module.exports.getMaskRegisterBuffer = getMaskRegisterBuffer;
287
+
288
+ module.exports.boolsToBuffer = boolsToBuffer;
289
+
290
+ module.exports.aduAsciiToRtu = aduAsciiToRtu;
291
+
292
+ module.exports.aduRtuToAscii = aduRtuToAscii;
293
+
294
+ module.exports.getWordFromBuffer = getWordFromBuffer;
295
+
296
+ module.exports.setWordToBuffer = setWordToBuffer
@@ -0,0 +1,184 @@
1
+ /**
2
+ ** Serial server module.
3
+ * @module net/tcpserver.
4
+ * @author Hector E. Socarras.
5
+ * @version 1.0.0
6
+ */
7
+
8
+ const { SerialPort } = require('serialport');
9
+ const { InterByteTimeoutParser } = require('@serialport/parser-inter-byte-timeout')
10
+ const { ReadlineParser } = require('@serialport/parser-readline')
11
+
12
+ //Default Server's Configuration object
13
+ const defaultCfg = {
14
+
15
+ speed : 7, //Enum startin at 0
16
+ dataBits : 8,
17
+ stopBits : 1,
18
+ parity : 1,
19
+ timeBetweenFrame : 20,
20
+ }
21
+
22
+ //No operation default function for listeners
23
+ const noop = () => {};
24
+
25
+ //BaudRates Map
26
+ const allowedBaudRates = [110, 300, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200];
27
+ const allowedParity = ['none', 'even', 'odd'];
28
+
29
+ /**
30
+ * Class to wrap a serial port.
31
+ */
32
+ class SerialServer {
33
+ /**
34
+ * Create a Serial Server.
35
+ * @param {object} netCfg configuration object.
36
+ */
37
+ constructor(netCfg = defaultCfg){
38
+
39
+ netCfg.autoOpen = false;
40
+ netCfg.path = netCfg.port;
41
+ if(netCfg.speed == undefined){ netCfg.speed = defaultCfg.speed}
42
+ netCfg.baudRate = allowedBaudRates[netCfg.speed];
43
+ if(netCfg.dataBits == undefined){ netCfg.dataBits = defaultCfg.dataBits}
44
+ if(netCfg.stopBits == undefined){ netCfg.stopBits = defaultCfg.stopBits}
45
+ if(netCfg.parity == undefined | netCfg.parity < 0 | netCfg.parity > 2){ netCfg.parity = allowedParity[defaultCfg.parity]}
46
+ if(netCfg.timeBetweenFrame == undefined){netCfg.timeBetweenFrame = defaultCfg.timeBetweenFrame}
47
+
48
+ let self = this;
49
+
50
+ /**
51
+ * tcp server
52
+ * @type {Object}
53
+ */
54
+ this.coreServer = new SerialPort(netCfg);
55
+
56
+ this.parser = this.coreServer.pipe(new InterByteTimeoutParser({ interval: netCfg.timeBetweenFrame }));
57
+
58
+
59
+
60
+ /**
61
+ * port
62
+ * @type {number}
63
+ */
64
+ this.port = netCfg.port;
65
+
66
+
67
+
68
+ //API Callback interfaces****************************************************************************************************************************************
69
+
70
+ /**
71
+ * function to executed when event data is emited
72
+ * @param {Buffer} data
73
+ */
74
+ this.onDataHook = noop;
75
+
76
+ /**
77
+ * function to executed when modbus message is detected
78
+ * @param {Buffer} data
79
+ */
80
+ this.onMbAduHook = noop;
81
+
82
+ /**
83
+ * function to executed when event listening is emited
84
+ */
85
+ this.onListeningHook = noop;
86
+ this.coreServer.on('open', () => {
87
+ self.onListeningHook();
88
+ });
89
+
90
+
91
+ /**
92
+ * function to executed when event error is emited
93
+ * @param {Object} error
94
+ */
95
+ this.onErrorHook = noop;
96
+ this.coreServer.on('error', (e) => {
97
+ self.onErrorHook(e);
98
+ });
99
+
100
+ /**
101
+ * function to executed when event close is emited
102
+ */
103
+ this.onServerCloseHook = noop;
104
+ this.coreServer.on('close', function(){
105
+
106
+ self.onServerCloseHook();
107
+
108
+ });
109
+
110
+
111
+ /**
112
+ * function to executed when event write is emited
113
+ * @param {Buffer} buff
114
+ */
115
+ this.onWriteHook = noop;
116
+ //******************************************************************************************************************************************************
117
+
118
+ //function for validating data****************************************************************
119
+ this.validateFrame = ()=>{
120
+ return false
121
+ }
122
+
123
+ this.parser.on('data',function(data){
124
+
125
+ if(self.onDataHook instanceof Function){
126
+ self.onDataHook(self, data);
127
+ }
128
+
129
+
130
+ if(self.onMbAduHook instanceof Function & self.validateFrame(data)){
131
+ self.onMbAduHook(self, data);
132
+ }
133
+
134
+ });
135
+
136
+ }
137
+
138
+ /**
139
+ * listening status
140
+ * @type {boolean}
141
+ */
142
+ get isListening(){
143
+ return this.coreServer.isOpen;
144
+ }
145
+
146
+
147
+ /**
148
+ * Start the tcp server
149
+ */
150
+ start (){
151
+
152
+ this.coreServer.open(function (err) {
153
+ if (err) {
154
+ self.onErrorHook(e);
155
+ }
156
+ })
157
+
158
+ }
159
+
160
+ /**
161
+ * Stop the tcp server
162
+ */
163
+ stop (){
164
+ //cerrando el server
165
+ this.coreServer.close();
166
+ }
167
+
168
+ /**
169
+ * function to write in a conection. Callback to onWriteHook hook function.
170
+ * @param {number} socketIndex. Index to socket in connections array
171
+ * @param {buffer} data
172
+ */
173
+ write (socket, frame){
174
+ let self = this;
175
+
176
+ this.coreServer.write(frame, function(){
177
+ self.onWriteHook(socket, frame);
178
+ });
179
+ }
180
+
181
+
182
+ }
183
+
184
+ module.exports = SerialServer;