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.
- package/.readthedocs.yaml +35 -0
- package/LICENSE.md +21 -21
- package/README.md +163 -48
- package/docs/Makefile +20 -0
- package/docs/client/channel.rst +209 -0
- package/docs/client/nodbus_master_serial.rst +559 -0
- package/docs/client/nodbus_master_tcp.rst +573 -0
- package/docs/conf.py +41 -0
- package/docs/images/01-readcoils.png +0 -0
- package/docs/images/02-readinputs.png +0 -0
- package/docs/images/03-readholding.png +0 -0
- package/docs/images/04-readinputsreg.png +0 -0
- package/docs/images/05-writecoil.png +0 -0
- package/docs/images/06-writeregister.png +0 -0
- package/docs/images/15-writecoil.png +0 -0
- package/docs/images/16.png +0 -0
- package/docs/images/22-mask.png +0 -0
- package/docs/images/23.png +0 -0
- package/docs/images/7.png +0 -0
- package/docs/images/modbus_pdu.png +0 -0
- package/docs/images/serial_adu.png +0 -0
- package/docs/images/tcp_adu.png +0 -0
- package/docs/index.rst +30 -0
- package/docs/make.bat +35 -0
- package/docs/protocol/modbus_master.rst +276 -0
- package/docs/protocol/modbus_master_serial.rst +290 -0
- package/docs/protocol/modbus_master_tcp.rst +296 -0
- package/docs/protocol/modbus_server.rst +469 -0
- package/docs/protocol/modbus_server_serial.rst +543 -0
- package/docs/protocol/modbus_server_tcp.rst +365 -0
- package/docs/requirements.txt +4 -0
- package/docs/server/net_server.rst +242 -0
- package/docs/server/nodbus_serial_server.rst +652 -0
- package/docs/server/nodbus_tcp_server.rst +505 -0
- package/docs/starting.rst +192 -0
- package/docs/static/simple logo.jpg +0 -0
- package/package.json +39 -30
- package/samples/mb_serial_server.js +77 -0
- package/samples/mb_tcp_client.js +114 -0
- package/samples/mb_tcp_server.js +58 -0
- package/src/client/net/serialchannel.js +195 -0
- package/src/client/net/tcpchannel.js +233 -0
- package/src/client/net/udpchannel.js +243 -0
- package/src/client/nodbus_serial_client.js +577 -0
- package/src/client/nodbus_tcp_client.js +542 -0
- package/src/nodbus-plus.js +157 -110
- package/src/protocol/modbus_master.js +298 -961
- package/src/protocol/modbus_master_serial.js +247 -0
- package/src/protocol/modbus_master_tcp.js +219 -0
- package/src/protocol/modbus_server.js +936 -0
- package/src/protocol/modbus_server_serial.js +368 -0
- package/src/protocol/modbus_server_tcp.js +129 -0
- package/src/protocol/utils.js +296 -0
- package/src/server/net/serialserver.js +184 -0
- package/src/server/net/tcpserver.js +290 -0
- package/src/server/net/udpserver.js +242 -0
- package/src/server/nodbus_serial_server.js +238 -0
- package/src/server/nodbus_tcp_server.js +249 -0
- package/test/modbus_master.test.js +279 -0
- package/test/modbus_master_serial.test.js +124 -0
- package/test/modbus_master_tcp.test.js +178 -0
- package/test/modbus_server.test.js +506 -0
- package/test/modbus_server_serial.test.js +328 -0
- package/test/modbus_server_tcp.test.js +91 -0
- package/test/nodbus_client_serial.test.js +307 -0
- package/test/nodbus_client_tcp.test.js +334 -0
- package/test/nodbus_server_serial.test.js +255 -0
- package/test/nodbus_server_tcp.test.js +216 -0
- package/CHANGELOG.md +0 -27
- package/src/client/m_stcp_client.js +0 -214
- package/src/client/m_tcp_client.js +0 -234
- package/src/net/tcpclient.js +0 -173
- package/src/net/tcpserver.js +0 -329
- package/src/protocol/adu.js +0 -40
- package/src/protocol/ascii_adu.js +0 -139
- package/src/protocol/boolean_register.js +0 -78
- package/src/protocol/functions/Force_Multiple_Coils.js +0 -76
- package/src/protocol/functions/Force_Single_Coil.js +0 -54
- package/src/protocol/functions/Mask_Holding_Register.js +0 -47
- package/src/protocol/functions/Preset_Multiple_Registers.js +0 -53
- package/src/protocol/functions/Preset_Single_Register.js +0 -39
- package/src/protocol/functions/Read_Coil_Status.js +0 -59
- package/src/protocol/functions/Read_Holding_Registers.js +0 -52
- package/src/protocol/functions/Read_Input_Registers.js +0 -52
- package/src/protocol/functions/Read_Input_Status.js +0 -58
- package/src/protocol/mbap.js +0 -60
- package/src/protocol/modbus_device.js +0 -35
- package/src/protocol/modbus_slave.js +0 -522
- package/src/protocol/pdu.js +0 -70
- package/src/protocol/rtu_adu.js +0 -122
- package/src/protocol/serial_adu.js +0 -29
- package/src/protocol/tcp_adu.js +0 -84
- package/src/protocol/word_register.js +0 -122
- package/src/server/m_stcp_server.js +0 -310
- package/src/server/m_tcp_server.js +0 -295
- package/test/modbus-stcp-server-test.js +0 -72
- package/test/modbus-stcp-server-test1.js +0 -72
- package/test/modbus-tcp-client-test.js +0 -159
- package/test/modbus-tcp-server-test.js +0 -75
- package/test/modbus-tcp-server-test2.js +0 -75
- package/test/modbus_stcp_client.js +0 -149
|
@@ -1,522 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
** Modbus Slave Base Class module.
|
|
3
|
-
* @module protocol/modbus-slave
|
|
4
|
-
* @author Hector E. Socarras.
|
|
5
|
-
* @version 0.4.0
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const ModbusDevice = require('./modbus_device');
|
|
10
|
-
const BooleanRegister = require('./boolean_register');
|
|
11
|
-
const WordRegister = require('./word_register');
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Class representing a modbus slave.
|
|
16
|
-
* @extends ModbusDevice
|
|
17
|
-
*/
|
|
18
|
-
class ModbusSlave extends ModbusDevice {
|
|
19
|
-
/**
|
|
20
|
-
* Create a Modbus Slave.
|
|
21
|
-
*/
|
|
22
|
-
constructor(modbusAddress = 1){
|
|
23
|
-
super();
|
|
24
|
-
|
|
25
|
-
var self = this;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
*Suported functions
|
|
29
|
-
* @type {number[]}
|
|
30
|
-
*/
|
|
31
|
-
this.supportedModbusFunctions = [0x01,0x02,0x03,0x04,0x05,0x06,0x0F,0x10, 0x16];
|
|
32
|
-
|
|
33
|
-
//Sellando esta propiedad
|
|
34
|
-
Object.defineProperty(self, 'supportedModbusFunctions',{
|
|
35
|
-
enumerable:true,
|
|
36
|
-
writable:false,
|
|
37
|
-
configurable:false
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* modbus address. Value between 1 and 247
|
|
42
|
-
* @type {number}
|
|
43
|
-
** @throws {RangeError}
|
|
44
|
-
*/
|
|
45
|
-
this.mAddress = modbusAddress;
|
|
46
|
-
Object.defineProperty(self, 'modbusAddress',{
|
|
47
|
-
get: function(){
|
|
48
|
-
return self.mAddress;
|
|
49
|
-
},
|
|
50
|
-
set: function(address){
|
|
51
|
-
if(address >= 1 && address <= 247){
|
|
52
|
-
self.mAddress = address
|
|
53
|
-
}
|
|
54
|
-
else{
|
|
55
|
-
throw new RangeError('Address must be a value fron 1 to 247', 'modbus_slave.js', '55');
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Inputs. Reference 1x;
|
|
62
|
-
* @type {Object}
|
|
63
|
-
* @public
|
|
64
|
-
*/
|
|
65
|
-
this.inputs = new BooleanRegister();
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Registro coils. En el primer byte se encuentran 0-7 en el segundo 8-14 etc;
|
|
69
|
-
* denttro del mismo byte el bit menos significatico es 0 y el mas significativo es el 7
|
|
70
|
-
* @type {Object}
|
|
71
|
-
* @public
|
|
72
|
-
*/
|
|
73
|
-
this.coils = new BooleanRegister();
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Registro holdings.
|
|
78
|
-
* @type {Object}
|
|
79
|
-
* @public
|
|
80
|
-
*/
|
|
81
|
-
this.holdingRegisters = new WordRegister();
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Registro inputs. Ocupan 2 Bytes. Se transmiten B y B+1 en ese orden
|
|
85
|
-
* @type {Buffer}
|
|
86
|
-
* @public
|
|
87
|
-
*/
|
|
88
|
-
this.inputRegisters = new WordRegister();
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
Start(){
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
Stop(){
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Build a response PDU
|
|
103
|
-
* @param {Object} PDU protocol data unit
|
|
104
|
-
* @return {Object} PDU protocol data unit
|
|
105
|
-
*/
|
|
106
|
-
BuildResponse(pdu) {
|
|
107
|
-
|
|
108
|
-
let respPDU = this.CreatePDU();
|
|
109
|
-
|
|
110
|
-
/** Valid PDU*/
|
|
111
|
-
if(this.AnalizePDU(pdu) == 0){
|
|
112
|
-
|
|
113
|
-
switch( pdu.modbus_function ){
|
|
114
|
-
case 0x01:
|
|
115
|
-
respPDU = this.ReadCoilStatus(pdu);
|
|
116
|
-
break;
|
|
117
|
-
case 0x02:
|
|
118
|
-
respPDU = this.ReadInputStatus(pdu);
|
|
119
|
-
break;
|
|
120
|
-
case 0x03:
|
|
121
|
-
respPDU = this.ReadHoldingRegisters(pdu);
|
|
122
|
-
break;
|
|
123
|
-
case 0x04:
|
|
124
|
-
respPDU = this.ReadInputRegisters(pdu);
|
|
125
|
-
break;
|
|
126
|
-
case 0x05:
|
|
127
|
-
respPDU = this.ForceSingleCoil(pdu);
|
|
128
|
-
break;
|
|
129
|
-
case 0x06:
|
|
130
|
-
respPDU = this.PresetSingleRegister(pdu);
|
|
131
|
-
break;
|
|
132
|
-
case 0x0F:
|
|
133
|
-
respPDU = this.ForceMultipleCoils(pdu);
|
|
134
|
-
break;
|
|
135
|
-
case 0x10:
|
|
136
|
-
respPDU = this.PresetMultipleRegisters(pdu);
|
|
137
|
-
case 0x16:
|
|
138
|
-
respPDU = this.MaskHoldingRegister(pdu);
|
|
139
|
-
break;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
respPDU.MakeBuffer();
|
|
143
|
-
return respPDU;
|
|
144
|
-
}
|
|
145
|
-
/** Exception */
|
|
146
|
-
else if(this.AnalizePDU(pdu) == 1){
|
|
147
|
-
|
|
148
|
-
respPDU.modbus_function = pdu.modbus_function | 0x80;
|
|
149
|
-
respPDU.modbus_data[0] = 0x01;
|
|
150
|
-
|
|
151
|
-
respPDU.MakeBuffer();
|
|
152
|
-
return respPDU;
|
|
153
|
-
}
|
|
154
|
-
/** Bad PDU*/
|
|
155
|
-
else{
|
|
156
|
-
return null
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Chech PDU
|
|
163
|
-
* @param {Object} PDU protocol data unit
|
|
164
|
-
* @return {number} Error code. 0-no error, 1-modbus exception, 2-error
|
|
165
|
-
* @fires ModbusSlave#modbus_exeption
|
|
166
|
-
*/
|
|
167
|
-
AnalizePDU(pdu){
|
|
168
|
-
|
|
169
|
-
var tempPDU = this.CreatePDU();
|
|
170
|
-
|
|
171
|
-
/**Checks for supported functions*/
|
|
172
|
-
if(this.supportedModbusFunctions.indexOf(pdu.modbus_function) == -1){
|
|
173
|
-
/**
|
|
174
|
-
* modbus_exeption event.
|
|
175
|
-
* @event ModbusSlave#modbus_exeption
|
|
176
|
-
* @type {String}
|
|
177
|
-
*/
|
|
178
|
-
this.emit('modbus_exeption',"Illegal Function");
|
|
179
|
-
|
|
180
|
-
return 1;
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
if(pdu.modbus_data.length < 4){
|
|
184
|
-
return 2;
|
|
185
|
-
}
|
|
186
|
-
else if (pdu.modbus_function == 15 || pdu.modbus_function == 16) {
|
|
187
|
-
let byteCount = pdu.modbus_data.readUInt8(4);
|
|
188
|
-
if(pdu.modbus_data.length-5 === byteCount){
|
|
189
|
-
return 0;
|
|
190
|
-
}
|
|
191
|
-
else{
|
|
192
|
-
return 2;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
/** Valid PDU. */
|
|
196
|
-
else{
|
|
197
|
-
return 0;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Write Data on slave memory
|
|
205
|
-
* @param {number} value value to be write
|
|
206
|
-
* @param {string|number} area modbus registers. Suppoting values: holding-register, holding, 4, inputs-registers, 3, inputs, 1, coils, 0;
|
|
207
|
-
* @param {number} offset number of register;
|
|
208
|
-
* @param {string} dataType value format. Suppoting format: bool, uint, uint32, int, int32, float, double.
|
|
209
|
-
* @throws {String} description of error
|
|
210
|
-
* @example
|
|
211
|
-
* SetData(25.2, 'float', 'holding-register', 10);
|
|
212
|
-
*/
|
|
213
|
-
SetData(value, area = 'holding-register', dataAddress = 0, dataType = 'uint'){
|
|
214
|
-
|
|
215
|
-
if(value == null || value == undefined){
|
|
216
|
-
throw 'Error SetData value argument must be define'
|
|
217
|
-
return
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
let memoryArea = null;
|
|
221
|
-
|
|
222
|
-
let buff32 = Buffer.alloc(4);
|
|
223
|
-
let buff64 = Buffer.alloc(8);
|
|
224
|
-
|
|
225
|
-
switch(area){
|
|
226
|
-
case 'holding-registers':
|
|
227
|
-
memoryArea = this.holdingRegisters;
|
|
228
|
-
if(dataType == 'bool'){
|
|
229
|
-
dataType = 'uint8';
|
|
230
|
-
}
|
|
231
|
-
break;
|
|
232
|
-
case 'holding':
|
|
233
|
-
memoryArea = this.holdingRegisters;
|
|
234
|
-
if(dataType == 'bool'){
|
|
235
|
-
dataType = 'uint8';
|
|
236
|
-
}
|
|
237
|
-
break;
|
|
238
|
-
case 4:
|
|
239
|
-
memoryArea = this.holdingRegisters;
|
|
240
|
-
if(dataType == 'bool'){
|
|
241
|
-
dataType = 'uint8';
|
|
242
|
-
}
|
|
243
|
-
break;
|
|
244
|
-
case 'inputs-registers':
|
|
245
|
-
memoryArea = this.inputRegisters;
|
|
246
|
-
if(dataType == 'bool'){
|
|
247
|
-
dataType = 'uint8';
|
|
248
|
-
}
|
|
249
|
-
break;
|
|
250
|
-
case 3:
|
|
251
|
-
memoryArea = this.inputRegisters;
|
|
252
|
-
if(dataType == 'bool'){
|
|
253
|
-
dataType = 'uint8';
|
|
254
|
-
}
|
|
255
|
-
break;
|
|
256
|
-
case 'inputs':
|
|
257
|
-
memoryArea = this.inputs;
|
|
258
|
-
if(dataType != 'bool'){
|
|
259
|
-
dataType = 'bool';
|
|
260
|
-
value > 0 ? value = true : value = false;
|
|
261
|
-
}
|
|
262
|
-
break;
|
|
263
|
-
case 1:
|
|
264
|
-
memoryArea = this.inputs;
|
|
265
|
-
if(dataType != 'bool'){
|
|
266
|
-
dataType = 'bool';
|
|
267
|
-
value > 0 ? value = true : value = false;
|
|
268
|
-
}
|
|
269
|
-
break;
|
|
270
|
-
case 'coils':
|
|
271
|
-
memoryArea = this.coils;
|
|
272
|
-
if(dataType != 'bool'){
|
|
273
|
-
dataType = 'bool';
|
|
274
|
-
value > 0 ? value = true : value = false;
|
|
275
|
-
}
|
|
276
|
-
break;
|
|
277
|
-
case 0:
|
|
278
|
-
memoryArea = this.coils;
|
|
279
|
-
if(dataType != 'bool'){
|
|
280
|
-
dataType = 'bool';
|
|
281
|
-
value > 0 ? value = true : value = false;
|
|
282
|
-
}
|
|
283
|
-
break;
|
|
284
|
-
default:
|
|
285
|
-
throw 'invalid address'
|
|
286
|
-
break;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
if(typeof(value) == 'number'|| typeof(value) == 'boolean'){
|
|
290
|
-
let val = Buffer.alloc(2);
|
|
291
|
-
switch(dataType){
|
|
292
|
-
case 'bool':
|
|
293
|
-
val[0] = value ? 1 : 0;
|
|
294
|
-
if(memoryArea. WriteData != 'undefined'){
|
|
295
|
-
memoryArea. WriteData(value, dataAddress);
|
|
296
|
-
}
|
|
297
|
-
else{
|
|
298
|
-
memoryArea.SetRegister(val, dataAddress);
|
|
299
|
-
}
|
|
300
|
-
break;
|
|
301
|
-
case 'uint':
|
|
302
|
-
val.writeUInt16LE(value)
|
|
303
|
-
memoryArea.SetRegister(val, dataAddress);
|
|
304
|
-
break;
|
|
305
|
-
case 'uint32':
|
|
306
|
-
buff32.writeUInt32LE(value);
|
|
307
|
-
memoryArea.SetRegister(buff32.slice(0,2), dataAddress);
|
|
308
|
-
memoryArea.SetRegister(buff32.slice(2), dataAddress + 1);
|
|
309
|
-
break;
|
|
310
|
-
case 'int':
|
|
311
|
-
val.writeInt16LE(value)
|
|
312
|
-
memoryArea.SetRegister(val, dataAddress);
|
|
313
|
-
break;
|
|
314
|
-
case 'int32':
|
|
315
|
-
buff32.writeInt32LE(value);
|
|
316
|
-
memoryArea.SetRegister(buff32.slice(0,2), dataAddress);
|
|
317
|
-
memoryArea.SetRegister(buff32.slice(2), dataAddress + 1);
|
|
318
|
-
break;
|
|
319
|
-
case 'float':
|
|
320
|
-
buff32.writeFloatLE(value);
|
|
321
|
-
memoryArea.SetRegister(buff32.slice(0,2), dataAddress);
|
|
322
|
-
memoryArea.SetRegister(buff32.slice(2), dataAddress + 1);
|
|
323
|
-
break;
|
|
324
|
-
case 'double':
|
|
325
|
-
buff64.writeDoubleLE(value);
|
|
326
|
-
memoryArea.SetRegister(buff64.slice(0,2), dataAddress);
|
|
327
|
-
memoryArea.SetRegister(buff64.slice(2, 4), dataAddress + 1);
|
|
328
|
-
memoryArea.SetRegister(buff64.slice(4, 6), dataAddress + 2);
|
|
329
|
-
memoryArea.SetRegister(buff64.slice(6), dataAddress + 3);
|
|
330
|
-
break;
|
|
331
|
-
default:
|
|
332
|
-
throw 'invalid dataType'+ dataType;
|
|
333
|
-
break
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
else{
|
|
337
|
-
throw 'value not suported'
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Read Data on slave memory *
|
|
344
|
-
* @param {string|number} area modbus registers. Suppoting values: holding-register, holding, 4, inputs-registers, 3, inputs, 1, coils, 0;
|
|
345
|
-
* @param {number} offset number of register;
|
|
346
|
-
* @param {string} dataType value format. Suppoting format: bool, uint, uint32, int, int32, float, double.
|
|
347
|
-
* @example
|
|
348
|
-
* //return 25.2
|
|
349
|
-
* GetData('4', 10, 'float');
|
|
350
|
-
*/
|
|
351
|
-
GetData(area = 'holding-register', dataAddress = 0, dataType = 'uint'){
|
|
352
|
-
/*
|
|
353
|
-
*@param {number or array} value values to write in server memory for use app
|
|
354
|
-
*/
|
|
355
|
-
|
|
356
|
-
let memoryArea = null;
|
|
357
|
-
let value = null;
|
|
358
|
-
|
|
359
|
-
let buff32 = Buffer.alloc(4);
|
|
360
|
-
let buff64 = Buffer.alloc(8);
|
|
361
|
-
|
|
362
|
-
switch(area){
|
|
363
|
-
case 'holding-registers':
|
|
364
|
-
memoryArea = this.holdingRegisters;
|
|
365
|
-
if(dataType == 'bool'){
|
|
366
|
-
dataType = 'uint8';
|
|
367
|
-
}
|
|
368
|
-
break;
|
|
369
|
-
case 'holding':
|
|
370
|
-
memoryArea = this.holdingRegisters;
|
|
371
|
-
if(dataType == 'bool'){
|
|
372
|
-
dataType = 'uint8';
|
|
373
|
-
}
|
|
374
|
-
break;
|
|
375
|
-
case 4:
|
|
376
|
-
memoryArea = this.holdingRegisters;
|
|
377
|
-
if(dataType == 'bool'){
|
|
378
|
-
dataType = 'uint8';
|
|
379
|
-
}
|
|
380
|
-
break;
|
|
381
|
-
case 'inputs-registers':
|
|
382
|
-
memoryArea = this.inputRegisters;
|
|
383
|
-
if(dataType == 'bool'){
|
|
384
|
-
dataType = 'uint8';
|
|
385
|
-
}
|
|
386
|
-
break;
|
|
387
|
-
case 3:
|
|
388
|
-
memoryArea = this.inputRegisters;
|
|
389
|
-
if(dataType == 'bool'){
|
|
390
|
-
dataType = 'uint8';
|
|
391
|
-
}
|
|
392
|
-
break;
|
|
393
|
-
case 'inputs':
|
|
394
|
-
memoryArea = this.inputs;
|
|
395
|
-
if(dataType != 'bool'){
|
|
396
|
-
dataType = 'bool';
|
|
397
|
-
}
|
|
398
|
-
break;
|
|
399
|
-
case 1:
|
|
400
|
-
memoryArea = this.inputs;
|
|
401
|
-
if(dataType != 'bool'){
|
|
402
|
-
dataType = 'bool';
|
|
403
|
-
}
|
|
404
|
-
break;
|
|
405
|
-
case 'coils':
|
|
406
|
-
memoryArea = this.coils;
|
|
407
|
-
if(dataType != 'bool'){
|
|
408
|
-
dataType = 'bool';
|
|
409
|
-
}
|
|
410
|
-
break;
|
|
411
|
-
case 0:
|
|
412
|
-
memoryArea = this.coils;
|
|
413
|
-
if(dataType != 'bool'){
|
|
414
|
-
dataType = 'bool';
|
|
415
|
-
}
|
|
416
|
-
break;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
switch(dataType){
|
|
420
|
-
case 'bool':
|
|
421
|
-
if(memoryArea.ReadData != 'undefined'){
|
|
422
|
-
value = memoryArea.ReadData(dataAddress)
|
|
423
|
-
}
|
|
424
|
-
else{
|
|
425
|
-
value = memoryArea.GetRegister(dataAddress).readUInt16LE > 0 ? true : false;
|
|
426
|
-
}
|
|
427
|
-
break;
|
|
428
|
-
case 'uint':
|
|
429
|
-
value = memoryArea.GetRegister(dataAddress).readUInt16LE();
|
|
430
|
-
break;
|
|
431
|
-
case 'uint32':
|
|
432
|
-
memoryArea.GetRegister(dataAddress).copy(buff32, 0);
|
|
433
|
-
memoryArea.GetRegister(dataAddress + 1).copy(buff32, 2);
|
|
434
|
-
value = buff32.readUInt32LE();
|
|
435
|
-
break;
|
|
436
|
-
case 'int':
|
|
437
|
-
value = memoryArea.GetRegister(dataAddress).readInt16LE();;
|
|
438
|
-
break;
|
|
439
|
-
case 'int32':
|
|
440
|
-
memoryArea.GetRegister(dataAddress).copy(buff32, 0);
|
|
441
|
-
memoryArea.GetRegister(dataAddress + 1).copy(buff32, 2);
|
|
442
|
-
value = buff32.readInt32LE();
|
|
443
|
-
break;
|
|
444
|
-
case 'float':
|
|
445
|
-
memoryArea.GetRegister(dataAddress).copy(buff32, 0);
|
|
446
|
-
memoryArea.GetRegister(dataAddress + 1).copy(buff32, 2);
|
|
447
|
-
value = buff32.readFloatLE();
|
|
448
|
-
break;
|
|
449
|
-
case 'double':
|
|
450
|
-
memoryArea.GetRegister(dataAddress).copy(buff64, 0);
|
|
451
|
-
memoryArea.GetRegister(dataAddress + 1).copy(buff64, 2);
|
|
452
|
-
memoryArea.GetRegister(dataAddress + 2).copy(buff64, 4);
|
|
453
|
-
memoryArea.GetRegister(dataAddress + 3).copy(buff64, 6);
|
|
454
|
-
value = buff64.readDoubleLE();
|
|
455
|
-
break;
|
|
456
|
-
default:
|
|
457
|
-
throw 'invalid dataType'+ dataType;
|
|
458
|
-
break
|
|
459
|
-
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
return value;
|
|
463
|
-
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
/**
|
|
468
|
-
* Procesesing modbus function 01 indication.
|
|
469
|
-
* @private
|
|
470
|
-
*/
|
|
471
|
-
ModbusSlave.prototype.ReadCoilStatus = require('./functions/Read_Coil_Status');
|
|
472
|
-
|
|
473
|
-
/**
|
|
474
|
-
* Procesesing modbus function 02 indication.
|
|
475
|
-
* @private
|
|
476
|
-
*/
|
|
477
|
-
ModbusSlave.prototype.ReadInputStatus = require('./functions/Read_Input_Status');
|
|
478
|
-
|
|
479
|
-
/**
|
|
480
|
-
* Procesesing modbus function 03 indication.
|
|
481
|
-
* @private
|
|
482
|
-
*/
|
|
483
|
-
ModbusSlave.prototype.ReadHoldingRegisters = require('./functions/Read_Holding_Registers');
|
|
484
|
-
|
|
485
|
-
/**
|
|
486
|
-
* Procesesing modbus function 04 indication.
|
|
487
|
-
* @private
|
|
488
|
-
*/
|
|
489
|
-
ModbusSlave.prototype.ReadInputRegisters = require('./functions/Read_Input_Registers');
|
|
490
|
-
|
|
491
|
-
/**
|
|
492
|
-
* Procesesing modbus function 05 indication.
|
|
493
|
-
* @private
|
|
494
|
-
*/
|
|
495
|
-
ModbusSlave.prototype.ForceSingleCoil = require('./functions/Force_Single_Coil');
|
|
496
|
-
|
|
497
|
-
/**
|
|
498
|
-
* Procesesing modbus function 06 indication.
|
|
499
|
-
* @private
|
|
500
|
-
*/
|
|
501
|
-
ModbusSlave.prototype.PresetSingleRegister = require('./functions/Preset_Single_Register');
|
|
502
|
-
|
|
503
|
-
/**
|
|
504
|
-
* Procesesing modbus function 15 indication.
|
|
505
|
-
* @private
|
|
506
|
-
*/
|
|
507
|
-
ModbusSlave.prototype.ForceMultipleCoils = require('./functions/Force_Multiple_Coils');
|
|
508
|
-
|
|
509
|
-
/**
|
|
510
|
-
* Procesesing modbus function 16 indication.
|
|
511
|
-
* @private
|
|
512
|
-
*/
|
|
513
|
-
ModbusSlave.prototype.PresetMultipleRegisters = require('./functions/Preset_Multiple_Registers');
|
|
514
|
-
|
|
515
|
-
/**
|
|
516
|
-
* Procesesing modbus function 22 indication.
|
|
517
|
-
* @private
|
|
518
|
-
*/
|
|
519
|
-
ModbusSlave.prototype.MaskHoldingRegister = require('./functions/Mask_Holding_Register');
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
module.exports = ModbusSlave;
|
package/src/protocol/pdu.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
** Modbus Protocol Data Unit base class.
|
|
3
|
-
* @module protocol/pdu
|
|
4
|
-
* @author Hector E. Socarras.
|
|
5
|
-
* @version 0.4.0
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Class representing a modbus protocol data unit.
|
|
10
|
-
*/
|
|
11
|
-
class PDU {
|
|
12
|
-
/**
|
|
13
|
-
* Create a PDU.
|
|
14
|
-
* @param {Buffer} pduRaw fragment off modbus frame corresponding to pdu.
|
|
15
|
-
*/
|
|
16
|
-
constructor(pduRaw = Buffer.alloc(1)){
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
*Frame
|
|
20
|
-
*@type {Buffer}
|
|
21
|
-
*/
|
|
22
|
-
this.pduBuffer = pduRaw;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
*modbus function
|
|
26
|
-
*@type {number}
|
|
27
|
-
*/
|
|
28
|
-
this.modbus_function = 0;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
*Frame data segment
|
|
32
|
-
*@type {Buffer}
|
|
33
|
-
*/
|
|
34
|
-
this.modbus_data = Buffer.alloc(1);
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* function to make pdu frame from function and data fields
|
|
40
|
-
*/
|
|
41
|
-
MakeBuffer(){
|
|
42
|
-
|
|
43
|
-
var buff = Buffer.alloc(this.modbus_data.length + 1);
|
|
44
|
-
buff[0] = this.modbus_function;
|
|
45
|
-
this.modbus_data.copy(buff,1);
|
|
46
|
-
this.pduBuffer = buff;
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
*function to parse the pdu buffer to extract function and data fields
|
|
52
|
-
* @throws {Error}
|
|
53
|
-
*/
|
|
54
|
-
ParseBuffer(){
|
|
55
|
-
if(this.pduBuffer.length >= 2){
|
|
56
|
-
|
|
57
|
-
this.modbus_function = this.pduBuffer[0];
|
|
58
|
-
|
|
59
|
-
//creando el buffer de datos
|
|
60
|
-
this.modbus_data = Buffer.alloc(this.pduBuffer.length-1);
|
|
61
|
-
this.pduBuffer.copy(this.modbus_data,0,1);
|
|
62
|
-
}
|
|
63
|
-
else{
|
|
64
|
-
throw new Error('wrong pdu buffer');
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
module.exports = PDU
|
package/src/protocol/rtu_adu.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*@brief Clase de Aplication Data Unit RTU
|
|
3
|
-
*
|
|
4
|
-
*@author Hector E. Socarras.
|
|
5
|
-
*date 19/5/2016
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const SerialADU = require('./serial_adu');
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
module.exports = class RtuADU extends SerialADU {
|
|
12
|
-
constructor(aduRaw = Buffer.alloc(1)){
|
|
13
|
-
super(aduRaw)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
MakeBuffer(){
|
|
17
|
-
|
|
18
|
-
this.pdu.MakeBuffer();
|
|
19
|
-
|
|
20
|
-
var tempBuffer = Buffer.alloc(this.pdu.pduBuffer.length + 3);
|
|
21
|
-
|
|
22
|
-
if(this.address <= 247){
|
|
23
|
-
tempBuffer[0] = this.address;
|
|
24
|
-
}
|
|
25
|
-
else{
|
|
26
|
-
throw Error('address error');
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
this.pdu.pduBuffer.copy(tempBuffer,1);
|
|
31
|
-
|
|
32
|
-
this.errorCheck = this.GetCRC(tempBuffer);
|
|
33
|
-
|
|
34
|
-
tempBuffer.writeUInt16BE(this.errorCheck, tempBuffer.length - 2);
|
|
35
|
-
|
|
36
|
-
this.aduBuffer = tempBuffer;
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
*function to parse the adu buffer to make MBAP and PDU object
|
|
42
|
-
* @throws {string}
|
|
43
|
-
*/
|
|
44
|
-
ParseBuffer(){
|
|
45
|
-
|
|
46
|
-
this.address = this.aduBuffer.readUInt8(0);
|
|
47
|
-
this.pdu.pduBuffer = this.aduBuffer.slice(1,-2);
|
|
48
|
-
this.errorCheck = this.aduBuffer.readUInt16BE(this.aduBuffer.length - 2);
|
|
49
|
-
|
|
50
|
-
if(this.errorCheck == this.GetCRC()){
|
|
51
|
-
try{
|
|
52
|
-
this.pdu.ParseBuffer();
|
|
53
|
-
}
|
|
54
|
-
catch(e){
|
|
55
|
-
throw err;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
else{
|
|
59
|
-
throw new Error('checksum error');
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Get crc from a modbus rtu's frame.
|
|
66
|
-
* @param {Buffer} frame The complete modbus rtu frame.
|
|
67
|
-
* @return {number} The CRC.
|
|
68
|
-
*/
|
|
69
|
-
GetCRC(frame = this.aduBuffer){
|
|
70
|
-
|
|
71
|
-
var crc_hi = 0xFF;
|
|
72
|
-
var crc_lo = 0xFF;
|
|
73
|
-
var index;
|
|
74
|
-
|
|
75
|
-
var auxcrc_hi = [0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
|
|
76
|
-
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
|
|
77
|
-
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
|
|
78
|
-
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
|
79
|
-
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
|
|
80
|
-
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
|
|
81
|
-
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
|
|
82
|
-
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
|
83
|
-
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
|
|
84
|
-
0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
|
|
85
|
-
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
|
|
86
|
-
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
|
87
|
-
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
|
|
88
|
-
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
|
|
89
|
-
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
|
|
90
|
-
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
|
91
|
-
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
|
|
92
|
-
0x40];
|
|
93
|
-
|
|
94
|
-
var auxcrc_lo = [0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
|
|
95
|
-
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
|
|
96
|
-
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
|
|
97
|
-
0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
|
|
98
|
-
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
|
|
99
|
-
0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
|
|
100
|
-
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
|
|
101
|
-
0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
|
|
102
|
-
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
|
|
103
|
-
0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
|
|
104
|
-
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
|
|
105
|
-
0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
|
|
106
|
-
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
|
|
107
|
-
0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
|
|
108
|
-
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
|
|
109
|
-
0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
|
|
110
|
-
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
|
|
111
|
-
0x40];
|
|
112
|
-
|
|
113
|
-
for(var i = 0; i< frame.length-2; i++) {
|
|
114
|
-
index = crc_hi ^ frame[i];
|
|
115
|
-
crc_hi = crc_lo ^ auxcrc_hi[index];
|
|
116
|
-
crc_lo = auxcrc_lo[index];
|
|
117
|
-
}
|
|
118
|
-
return (crc_hi << 8 | crc_lo);
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
}
|