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
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
const net = require('node:net');
|
|
2
|
+
const Nodbus = require('../src/nodbus-plus');
|
|
3
|
+
|
|
4
|
+
//creating config file for basic server 1
|
|
5
|
+
let serverCfg1 = {
|
|
6
|
+
inputs : 524,
|
|
7
|
+
coils : 0,
|
|
8
|
+
holdingRegisters : 512,
|
|
9
|
+
inputRegisters : 256,
|
|
10
|
+
udpType : 'udp6',
|
|
11
|
+
port: 503,
|
|
12
|
+
speed: 7,
|
|
13
|
+
address : 1,
|
|
14
|
+
transmitionMode : 0,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let serverCfg2 = {
|
|
18
|
+
inputs : 524,
|
|
19
|
+
coils : 0,
|
|
20
|
+
holdingRegisters : 512,
|
|
21
|
+
inputRegisters : 256,
|
|
22
|
+
udpType : 'udp6',
|
|
23
|
+
port: 504,
|
|
24
|
+
address : 1,
|
|
25
|
+
transmitionMode : 1,
|
|
26
|
+
tcpCoalescingDetection : true,
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
describe("Instanciate a nodbus serial server with tcp net", () => {
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
let server1 = Nodbus.createSerialServer('tcp', serverCfg1);
|
|
34
|
+
//let server2 = new ModbusTcpServer();
|
|
35
|
+
|
|
36
|
+
it("instance", () => {
|
|
37
|
+
|
|
38
|
+
expect(server1.port).toEqual(503);
|
|
39
|
+
expect(server1.address).toEqual(1);
|
|
40
|
+
expect(server1.net.tcpCoalescingDetection).toEqual(false);
|
|
41
|
+
} );
|
|
42
|
+
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe("rtu server", () => {
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
let server1 = Nodbus.createSerialServer('tcp', serverCfg1);
|
|
49
|
+
let testClient = new net.Socket()
|
|
50
|
+
|
|
51
|
+
test("server", (done) => {
|
|
52
|
+
|
|
53
|
+
expect(server1.isListening).toEqual(false);
|
|
54
|
+
|
|
55
|
+
testClient.on('data', (data)=>{
|
|
56
|
+
//console.log('client data')
|
|
57
|
+
expect(data[0]).toEqual(1);
|
|
58
|
+
expect(data[1]).toEqual(3);
|
|
59
|
+
server1.stop()
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
function listeningCallback(port){
|
|
63
|
+
//console.log('listening')
|
|
64
|
+
expect(server1.isListening).toEqual(true);
|
|
65
|
+
expect(port).toEqual(503);
|
|
66
|
+
|
|
67
|
+
testClient.connect(503);
|
|
68
|
+
|
|
69
|
+
function connectionCallback(){
|
|
70
|
+
//console.log('connection')
|
|
71
|
+
|
|
72
|
+
let adu1 = Buffer.from([0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x45, 0xD8]); //broadcast
|
|
73
|
+
let adu2 = Buffer.from([0x0A, 0x03, 0x00, 0x00, 0x00, 0x04, 0x45, 0x72]); //address 10 wrong address
|
|
74
|
+
let adu3 = Buffer.from([0x01, 0x03, 0x00, 0x00, 0x00, 0x04, 0x44, 0x09]); //good
|
|
75
|
+
let adu4 = Buffer.from([0x01, 0x03, 0x00, 0x00, 0x00, 0x04, 0x44, 0x19]); //wrong crc
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
function dataCallback(socket, frame){
|
|
79
|
+
//console.log('data')
|
|
80
|
+
//console.log(frame)
|
|
81
|
+
expect(frame[0] == 0 | frame[0] == 1 | frame[0] == 10).toBeTruthy();
|
|
82
|
+
expect(frame[1]).toEqual(3);
|
|
83
|
+
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
server1.on('data', dataCallback);
|
|
87
|
+
|
|
88
|
+
function reqCallback(socket, req){
|
|
89
|
+
expect(socket).toBeInstanceOf(net.Socket)
|
|
90
|
+
//console.log('req')
|
|
91
|
+
expect(req.address == 0 | req.address == 1).toBeTruthy();
|
|
92
|
+
expect(req.functionCode).toEqual(3);
|
|
93
|
+
expect(req.data.length).toEqual(4);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
server1.on('request', reqCallback);
|
|
97
|
+
|
|
98
|
+
function resCallback(sock, res){
|
|
99
|
+
//console.log('res')
|
|
100
|
+
expect(res.address).toEqual(1);
|
|
101
|
+
expect(res.functionCode).toEqual(3);
|
|
102
|
+
expect(res.data.length).toEqual(9);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
server1.on('response', resCallback);
|
|
106
|
+
|
|
107
|
+
function writeCallback(socket, frame){
|
|
108
|
+
expect(socket).toBeInstanceOf(net.Socket)
|
|
109
|
+
expect(frame[0]).toEqual(0);
|
|
110
|
+
expect(frame[1]).toEqual(3);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
//server1.on('write', writeCallback);
|
|
114
|
+
|
|
115
|
+
testClient.write(adu1)
|
|
116
|
+
|
|
117
|
+
setTimeout(() => {
|
|
118
|
+
testClient.write(adu2)
|
|
119
|
+
}, 100)
|
|
120
|
+
|
|
121
|
+
setTimeout(() => {
|
|
122
|
+
testClient.write(adu4)
|
|
123
|
+
}, 200)
|
|
124
|
+
|
|
125
|
+
setTimeout(() => {
|
|
126
|
+
testClient.write(adu3)
|
|
127
|
+
}, 300)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
testClient.on('connect', connectionCallback)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
server1.on('listening', listeningCallback);
|
|
136
|
+
|
|
137
|
+
function closedCallback(){
|
|
138
|
+
//console.log('closed')
|
|
139
|
+
expect(server1.isListening).toEqual(false);
|
|
140
|
+
done()
|
|
141
|
+
}
|
|
142
|
+
server1.on('closed', closedCallback)
|
|
143
|
+
|
|
144
|
+
server1.start()
|
|
145
|
+
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
describe("ascii server", () => {
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
let server1 = Nodbus.createSerialServer('tcp', serverCfg2);
|
|
155
|
+
let testClient = new net.Socket()
|
|
156
|
+
|
|
157
|
+
test("server", (done) => {
|
|
158
|
+
|
|
159
|
+
expect(server1.isListening).toEqual(false);
|
|
160
|
+
|
|
161
|
+
testClient.on('data', (data)=>{
|
|
162
|
+
//console.log('client data')
|
|
163
|
+
expect(data[0]).toEqual(0x3A);
|
|
164
|
+
|
|
165
|
+
server1.stop()
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
function listeningCallback(port){
|
|
169
|
+
//console.log('listening')
|
|
170
|
+
expect(server1.isListening).toEqual(true);
|
|
171
|
+
expect(port).toEqual(504);
|
|
172
|
+
|
|
173
|
+
testClient.connect(504);
|
|
174
|
+
|
|
175
|
+
function connectionCallback(){
|
|
176
|
+
//console.log('connection')
|
|
177
|
+
|
|
178
|
+
let adu1 = Buffer.from([0x3A, 0x30, 0x30, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x46, 0x39, 0x0D, 0x0A]); //broadcast 0 3 0 0 0 4 45 d8
|
|
179
|
+
let adu2 = Buffer.from([0x3A, 0x30, 0x41, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x45, 0x36, 0x0D, 0x0A]); //address 10 wrong address
|
|
180
|
+
let adu3 = Buffer.from([0x3A, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x46, 0x38, 0x0D, 0x0A]); //good
|
|
181
|
+
let adu4 = Buffer.from([0x3A, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x46, 0x36, 0x0D, 0x0A]); //wrong crc
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
function dataCallback(socket, frame){
|
|
185
|
+
//console.log('data')
|
|
186
|
+
//console.log(frame)
|
|
187
|
+
expect(frame[0]).toEqual(0x3A);
|
|
188
|
+
expect(frame[1]).toEqual(0x30);
|
|
189
|
+
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
server1.on('data', dataCallback);
|
|
193
|
+
|
|
194
|
+
function reqCallback(socket, req){
|
|
195
|
+
expect(socket).toBeInstanceOf(net.Socket)
|
|
196
|
+
//console.log('req')
|
|
197
|
+
expect(req.address == 0 | req.address == 1).toBeTruthy();
|
|
198
|
+
expect(req.functionCode).toEqual(3);
|
|
199
|
+
expect(req.data.length).toEqual(4);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
server1.on('request', reqCallback);
|
|
203
|
+
|
|
204
|
+
function resCallback(sock, res){
|
|
205
|
+
//console.log('res')
|
|
206
|
+
expect(res.address).toEqual(1);
|
|
207
|
+
expect(res.functionCode).toEqual(3);
|
|
208
|
+
expect(res.data.length).toEqual(9);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
server1.on('response', resCallback);
|
|
212
|
+
|
|
213
|
+
function writeCallback(socket, frame){
|
|
214
|
+
expect(socket).toBeInstanceOf(net.Socket)
|
|
215
|
+
expect(frame[0]).toEqual(0);
|
|
216
|
+
expect(frame[1]).toEqual(3);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
//server1.on('write', writeCallback);
|
|
220
|
+
|
|
221
|
+
testClient.write(adu1)
|
|
222
|
+
|
|
223
|
+
setTimeout(() => {
|
|
224
|
+
testClient.write(adu2)
|
|
225
|
+
}, 100)
|
|
226
|
+
|
|
227
|
+
setTimeout(() => {
|
|
228
|
+
testClient.write(adu4)
|
|
229
|
+
}, 200)
|
|
230
|
+
|
|
231
|
+
setTimeout(() => {
|
|
232
|
+
testClient.write(adu3)
|
|
233
|
+
}, 300)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
testClient.on('connect', connectionCallback)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
server1.on('listening', listeningCallback);
|
|
242
|
+
|
|
243
|
+
function closedCallback(){
|
|
244
|
+
//console.log('closed')
|
|
245
|
+
expect(server1.isListening).toEqual(false);
|
|
246
|
+
done()
|
|
247
|
+
}
|
|
248
|
+
server1.on('closed', closedCallback)
|
|
249
|
+
|
|
250
|
+
server1.start()
|
|
251
|
+
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
});
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
const net = require('node:net');
|
|
2
|
+
const dgram = require('node:dgram');
|
|
3
|
+
const Nodbus = require('../src/nodbus-plus');
|
|
4
|
+
|
|
5
|
+
//creating config file for basic server 1
|
|
6
|
+
let serverCfg = {
|
|
7
|
+
inputs : 524,
|
|
8
|
+
coils : 0,
|
|
9
|
+
holdingRegisters : 512,
|
|
10
|
+
inputRegisters : 256,
|
|
11
|
+
tcpCoalescingDetection : false,
|
|
12
|
+
udpType : 'udp6',
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe("Instanciate a nodbus tcp server with tcp net", () => {
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
let server1 = Nodbus.createTcpServer('tcp', serverCfg);
|
|
19
|
+
//let server2 = new ModbusTcpServer();
|
|
20
|
+
|
|
21
|
+
it("instanciate transaction", () => {
|
|
22
|
+
|
|
23
|
+
expect(server1.port).toEqual(502);
|
|
24
|
+
expect(server1.maxConnections).toEqual(32);
|
|
25
|
+
|
|
26
|
+
} );
|
|
27
|
+
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe("tcp server", () => {
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
let server1 = Nodbus.createTcpServer();
|
|
34
|
+
//let server2 = Nodbus.CreateTcpServer('tcp', serverCfg);
|
|
35
|
+
let testClient = new net.Socket()
|
|
36
|
+
|
|
37
|
+
test("callbacks", (done) => {
|
|
38
|
+
expect(server1.isListening).toEqual(false);
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
testClient.on('data', (data)=>{
|
|
42
|
+
server1.stop()
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
function listeningCallback(port){
|
|
46
|
+
//console.log('listening')
|
|
47
|
+
expect(server1.isListening).toEqual(true);
|
|
48
|
+
expect(port).toEqual(502);
|
|
49
|
+
testClient.connect(502);
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
function connectionCallback(socket){
|
|
53
|
+
//console.log('connection')
|
|
54
|
+
expect(socket.localPort).toEqual(502);
|
|
55
|
+
let adu1 = Buffer.from([0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x03,
|
|
56
|
+
0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x03]);
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
function dataCallback(socket, frame){
|
|
62
|
+
expect(socket).toBeInstanceOf(net.Socket)
|
|
63
|
+
expect(frame.length).toEqual(24);
|
|
64
|
+
expect(frame[2]).toEqual(0);
|
|
65
|
+
expect(frame[6]).toEqual(255);
|
|
66
|
+
expect(frame[9]).toEqual(0);
|
|
67
|
+
expect(frame[15]).toEqual(0);
|
|
68
|
+
expect(frame[21]).toEqual(0);
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
server1.on('data', dataCallback);
|
|
73
|
+
|
|
74
|
+
function reqCallback(socket, req){
|
|
75
|
+
expect(socket).toBeInstanceOf(net.Socket)
|
|
76
|
+
expect(req.unitId).toEqual(255);
|
|
77
|
+
expect(req.functionCode).toEqual(1);
|
|
78
|
+
expect(req.data.length).toEqual(4);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
server1.on('request', reqCallback);
|
|
82
|
+
|
|
83
|
+
function resCallback(sock, res){
|
|
84
|
+
expect(res.unitId).toEqual(255);
|
|
85
|
+
expect(res.functionCode).toEqual(1);
|
|
86
|
+
expect(res.data.length).toEqual(2);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
server1.on('response', resCallback);
|
|
90
|
+
|
|
91
|
+
function writeCallback(socket, frame){
|
|
92
|
+
expect(socket).toBeInstanceOf(net.Socket)
|
|
93
|
+
expect(frame[2]).toEqual(0);
|
|
94
|
+
expect(frame[6]).toEqual(255);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
testClient.write(adu1)
|
|
98
|
+
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
server1.on('connection', connectionCallback)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
server1.on('listening', listeningCallback);
|
|
105
|
+
|
|
106
|
+
function closedCallback(){
|
|
107
|
+
//console.log('closed')
|
|
108
|
+
expect(server1.isListening).toEqual(false);
|
|
109
|
+
done()
|
|
110
|
+
}
|
|
111
|
+
server1.on('closed', closedCallback)
|
|
112
|
+
|
|
113
|
+
server1.start()
|
|
114
|
+
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
describe("udp server", () => {
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
let server2 = Nodbus.createTcpServer('udp6', serverCfg);
|
|
124
|
+
server2.port = 1502;
|
|
125
|
+
|
|
126
|
+
let testClient2 = dgram.createSocket('udp6');
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
testClient2.once('message', (data, rinfo)=>{
|
|
131
|
+
//console.log('stopping server udp')
|
|
132
|
+
testClient2.disconnect()
|
|
133
|
+
server2.stop();
|
|
134
|
+
testClient2.close();
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
test("callbacks", (done) => {
|
|
139
|
+
|
|
140
|
+
expect(server2.isListening).toEqual(false);
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
function listeningCallback(port){
|
|
144
|
+
|
|
145
|
+
const address = server2.net.coreServer.address();
|
|
146
|
+
//console.log(`server listening ${address.address}:${address.port} for ${address.family}`);
|
|
147
|
+
expect(server2.isListening).toEqual(true);
|
|
148
|
+
expect(port).toEqual(1502);
|
|
149
|
+
expect(address.family).toEqual('IPv6')
|
|
150
|
+
|
|
151
|
+
testClient2.connect(1502, 'localhost', connectionCallback);
|
|
152
|
+
|
|
153
|
+
function connectionCallback(){
|
|
154
|
+
//console.log('connection')
|
|
155
|
+
|
|
156
|
+
let adu1 = Buffer.from([0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x03,
|
|
157
|
+
0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x03]);
|
|
158
|
+
|
|
159
|
+
let conectedClients = server2.net.activeConnections;
|
|
160
|
+
expect(conectedClients.length).toEqual(0);
|
|
161
|
+
|
|
162
|
+
function dataCallback(socket, frame){
|
|
163
|
+
//console.log('data')
|
|
164
|
+
|
|
165
|
+
expect(frame.length).toEqual(24);
|
|
166
|
+
expect(frame[2]).toEqual(0);
|
|
167
|
+
expect(frame[6]).toEqual(255);
|
|
168
|
+
expect(frame[9]).toEqual(0);
|
|
169
|
+
expect(frame[15]).toEqual(0);
|
|
170
|
+
expect(frame[21]).toEqual(0);
|
|
171
|
+
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
server2.on('data', dataCallback);
|
|
175
|
+
|
|
176
|
+
function reqCallback(socket, req){
|
|
177
|
+
//console.log('request')
|
|
178
|
+
|
|
179
|
+
expect(req.unitId).toEqual(255);
|
|
180
|
+
expect(req.functionCode).toEqual(1);
|
|
181
|
+
expect(req.data.length).toEqual(4);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
server2.on('request', reqCallback);
|
|
185
|
+
|
|
186
|
+
function writeCallback(socket, frame){
|
|
187
|
+
expect(socket).toBeInstanceOf(net.Socket)
|
|
188
|
+
expect(frame[2]).toEqual(0);
|
|
189
|
+
expect(frame[6]).toEqual(255);
|
|
190
|
+
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
testClient2.send(adu1, 1502, 'localhost');
|
|
194
|
+
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
server2.on('listening', listeningCallback);
|
|
200
|
+
|
|
201
|
+
function closedCallback(){
|
|
202
|
+
//console.log('closed')
|
|
203
|
+
expect(server2.isListening).toEqual(false);
|
|
204
|
+
|
|
205
|
+
done()
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
server2.on('closed', closedCallback)
|
|
209
|
+
|
|
210
|
+
server2.start()
|
|
211
|
+
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
});
|
package/CHANGELOG.md
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# Nodbus-Plus Changelog
|
|
2
|
-
|
|
3
|
-
## Verion 0.6.2
|
|
4
|
-
* ### Client
|
|
5
|
-
|
|
6
|
-
Se implementa el evento idle en el modbus master.
|
|
7
|
-
Se agrega la propiedad isIdle
|
|
8
|
-
|
|
9
|
-
## Verion 0.6.4
|
|
10
|
-
* ### Slave
|
|
11
|
-
|
|
12
|
-
Se implementa la propiedad modbusAddress en modbus_slave con chequeo de rango.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
## Verison 0.7.2
|
|
16
|
-
* ### Nodbus
|
|
17
|
-
|
|
18
|
-
Se agrega el modbus slave a lo objetos exportados por nodbus.
|
|
19
|
-
|
|
20
|
-
## Version 0.8.0
|
|
21
|
-
* ### ModbusMaster
|
|
22
|
-
|
|
23
|
-
Add retries when a modbus indication has timeout.
|
|
24
|
-
Add suport for multiples slaves.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
** Modbus Serial over Tcp Client module.
|
|
3
|
-
* @module client/modbus_stcp_client
|
|
4
|
-
* @author Hector E. Socarras.
|
|
5
|
-
* @version 0.6.0
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const ModbusMaster = require('../protocol/modbus_master');
|
|
9
|
-
const TcpClient = require('../net/tcpclient');
|
|
10
|
-
const RTU_ADU = require('../protocol/rtu_adu');
|
|
11
|
-
const ASCII_ADU = require('../protocol/ascii_adu');
|
|
12
|
-
var ADU ;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Class representing a modbus master over tcp.
|
|
16
|
-
* @extends ModbusMaster
|
|
17
|
-
*/
|
|
18
|
-
class ModbusTCPClient extends ModbusMaster {
|
|
19
|
-
/**
|
|
20
|
-
* Create a Modbus Serial over Tcp Client.
|
|
21
|
-
*/
|
|
22
|
-
constructor(mode = 'rtu'){
|
|
23
|
-
super();
|
|
24
|
-
|
|
25
|
-
var self = this;
|
|
26
|
-
|
|
27
|
-
var serialMode = mode;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* tcp layer
|
|
31
|
-
* @type {object}
|
|
32
|
-
*/
|
|
33
|
-
this.netClient = new TcpClient();
|
|
34
|
-
|
|
35
|
-
//asociando el evento data del netClient con la funcion ProcessResponse
|
|
36
|
-
this.netClient.onData = this.ProcessResponse.bind(this);
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Emit connect and ready events
|
|
40
|
-
* @param {object} target Socket object
|
|
41
|
-
* @fires ModbusTCPClient#connect {object}
|
|
42
|
-
* @fires ModbusTCPClient#ready
|
|
43
|
-
*/
|
|
44
|
-
this.netClient.onConnect = self._EmitConnect.bind(this);
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
*Emit disconnect event
|
|
49
|
-
* @param {object} had_error
|
|
50
|
-
* @fires ModbusTCPClient#disconnect {object}
|
|
51
|
-
*/
|
|
52
|
-
function EmitDisconnect(id, had_error){
|
|
53
|
-
let slave = this.slaveList.get(id);
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* disconnect event.
|
|
57
|
-
* @event ModbusTCPClient#disconnect
|
|
58
|
-
*/
|
|
59
|
-
this.emit('disconnect',id, had_error);
|
|
60
|
-
slave.isReady = false;
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
this.netClient.onClose = EmitDisconnect.bind(this);
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
*Emit error event
|
|
67
|
-
* @param {object} error
|
|
68
|
-
* @fires ModbusTCPClient#error {object}
|
|
69
|
-
*/
|
|
70
|
-
function EmitError (id, err){
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* error event.
|
|
74
|
-
* @event ModbusTCPClient#error
|
|
75
|
-
* @type {object}
|
|
76
|
-
*/
|
|
77
|
-
this.emit('error',id, err);
|
|
78
|
-
}
|
|
79
|
-
this.netClient.onError = EmitError.bind(this);
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Emit timeout event *
|
|
83
|
-
* @fires ModbusTCPClient#timeout
|
|
84
|
-
*/
|
|
85
|
-
this.netClient.onTimeOut = self._EmitTimeout.bind(this);;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Emit Indication event *
|
|
89
|
-
* @fires ModbusTCPClient#indication
|
|
90
|
-
*/
|
|
91
|
-
function EmitIndication(id, data){
|
|
92
|
-
/**
|
|
93
|
-
* indication event.
|
|
94
|
-
* @event ModbusTCPClient#indication
|
|
95
|
-
*/
|
|
96
|
-
this.emit('indication',id, data);
|
|
97
|
-
}
|
|
98
|
-
this.netClient.onWrite = EmitIndication.bind(this);
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* function to create a adu
|
|
105
|
-
* @param {object} pdu of request
|
|
106
|
-
* @return {object} adu request
|
|
107
|
-
*/
|
|
108
|
-
CreateADU(id, pdu){
|
|
109
|
-
let slave = this.slaveList.get(id);
|
|
110
|
-
var ADU;
|
|
111
|
-
|
|
112
|
-
if(slave.serialMode == 'ascii'){
|
|
113
|
-
ADU = ASCII_ADU;
|
|
114
|
-
}
|
|
115
|
-
else{
|
|
116
|
-
ADU = RTU_ADU;
|
|
117
|
-
}
|
|
118
|
-
let adu = new ADU();
|
|
119
|
-
adu.address = slave.modbusAddress;
|
|
120
|
-
adu.pdu = pdu;
|
|
121
|
-
|
|
122
|
-
adu.MakeBuffer();
|
|
123
|
-
|
|
124
|
-
return adu;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* function to pasrse server response
|
|
129
|
-
* @param {Buffer} aduBuffer frame of response
|
|
130
|
-
* @return {object} map Object whit register:value pairs
|
|
131
|
-
* @fires ModbusTCPClient#modbus_exception {object}
|
|
132
|
-
* @fires ModbusTCPClient#error {object}
|
|
133
|
-
*/
|
|
134
|
-
ParseResponse(id, aduBuffer) {
|
|
135
|
-
|
|
136
|
-
let slave = this.slaveList.get(id);
|
|
137
|
-
var ADU;
|
|
138
|
-
if(slave.serialMode == 'ascii'){
|
|
139
|
-
ADU = ASCII_ADU;
|
|
140
|
-
}
|
|
141
|
-
else{
|
|
142
|
-
ADU = RTU_ADU;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
let resp = new ADU(aduBuffer);
|
|
146
|
-
try{
|
|
147
|
-
resp.ParseBuffer();
|
|
148
|
-
return this.ParseResponsePDU(id, resp.pdu);
|
|
149
|
-
}
|
|
150
|
-
catch(err){
|
|
151
|
-
if(err.description == 'checksum error'){
|
|
152
|
-
this.emit('modbus_exception', id, "CHEKSUM ERROR");
|
|
153
|
-
return false;
|
|
154
|
-
}
|
|
155
|
-
else throw err;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
Start(id){
|
|
162
|
-
let self = this;
|
|
163
|
-
let successPromise;
|
|
164
|
-
|
|
165
|
-
if(id){
|
|
166
|
-
let slave = self.slaveList.get(id);
|
|
167
|
-
if(slave.isReady){
|
|
168
|
-
return Promise.resolve(id);
|
|
169
|
-
}
|
|
170
|
-
else{
|
|
171
|
-
return self.netClient.Connect(slave);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
else{
|
|
175
|
-
let promiseList = [];
|
|
176
|
-
this.slaveList.forEach(function(slave, key){
|
|
177
|
-
let promise;
|
|
178
|
-
promise = self.netClient.Connect(slave);
|
|
179
|
-
promiseList.push(promise);
|
|
180
|
-
})
|
|
181
|
-
successPromise = Promise.all(promiseList);
|
|
182
|
-
|
|
183
|
-
return successPromise;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
*disconnect from server
|
|
189
|
-
*/
|
|
190
|
-
Stop(id){
|
|
191
|
-
if(id){
|
|
192
|
-
let slave = this.slaveList.get(id);
|
|
193
|
-
if(slave.isReady){
|
|
194
|
-
return Promise.resolve(id);
|
|
195
|
-
}
|
|
196
|
-
else{
|
|
197
|
-
return this.netClient.Disconnet(id);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
else{
|
|
201
|
-
let promiseList = [];
|
|
202
|
-
this.slaveList.forEach(function(slave, key){
|
|
203
|
-
let promise;
|
|
204
|
-
promise = this.netClient.Disconnet(id);
|
|
205
|
-
promiseList.push(promise);
|
|
206
|
-
})
|
|
207
|
-
successPromise = Promise.all(promiseList);
|
|
208
|
-
return successPromise;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
module.exports = ModbusTCPClient;
|