-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
117 lines (107 loc) · 3.97 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/**
* Modbus-event is a TCP/IP Master, event-driven, implementation for modbus protocol.
* Created by Raphael Brandão (a.k.a. ralpha) on 20/05/2016.
* Contact me: [email protected]
* More information on NPM: https://www.npmjs.com/package/modbus-event
*/
// Modulo modbus-serial
var ModbusRTU = require('modbus-serial');
var deprecate = require('deprecate');
var client = new ModbusRTU();
// vars
var arrays = {
coils : [], inputStatus : [], holdingReg : [], inputReg : []
}, events = {
update : 'callback(type, address, from, to)'
}, defs = {}, firstUpdate = true, stack = [];
var print = function(type, msg){
if(!defs.debug) return;
if(type === 0 || !msg) return console.log('[Modbus-event] ' + (msg || type));
return console.error('[Modbus-event] ' + msg);
};
var displayChange = function(data, array, key){
for(var i = 0; i<data.length; i++){
if(data[i] !== array[i]){
print('[' + key + ':' + i + '] ' + array[i] + ' -> ' + data[i]);
events.update && events.update(key, i, data[i], array[i]);
}
}
};
var genCallback = function(err, data, key){
if(err) return console.error(err);
!firstUpdate && displayChange(data.data, arrays[key], key);
arrays[key] = data.data;
};
var forgetCallUpdate = function(){
print(1, 'The chain is broken! You need to invoke "NEXT" (third argument from "callee")!');
process.exit(1);
};
var errorInRuntime = function(err){
print(1, 'There was an error in the "callee" runtime:\n' + err);
process.exit(1);
};
var timer;
var update = function(){
var cleanFn = function(){
clearTimeout(timer);
update();
};
var next = function(err){
if(err) return errorInRuntime(err);
var fn = stack.shift();
if(fn && typeof fn === 'function'){
timer = setTimeout(forgetCallUpdate, 4000);
fn(client, arrays, cleanFn);
}else{
update();
}
if(firstUpdate) firstUpdate = false;
};
eval(readFunctions[0]);
};
var readFunctions = [], labels = ['coils', 'inputStatus', 'holdingReg', 'inputReg'];
var buildReadFunctions = function(){
for(var i=4; i>0; i--){
readFunctions[i-1] = 'client.writeFC' + i + '(' + defs.id + ',' + defs.address.init + ',' + defs.address.length +
', function(err, data){ genCallback(err, data, "' + labels[i-1] + '"); ' +
((i!=4) ? (readFunctions[i]) : ('next()')) + '; });';
}
};
var onConnectEvent = function(err){
if(err) {
print(1, 'Error while trying to connect (' + err.code + '). Slave online? Trying again..');
return tryToConnect();
}
print('Connection successful!');
buildReadFunctions();
update();
};
var tryToConnect = function(){
client.connectTCP(defs.ip, {port: defs.port}, onConnectEvent);
client.setID(defs.id);
};
var Obj = function(options){
defs.debug = (options && options.debug) || false;
defs.ip = (options && options.ip) || '127.0.0.1';
defs.port = (options && options.port) || 502;
defs.id = (options && options.id) || 1;
defs.address = (options && options.address) || {init : 0, length : 10};
tryToConnect();
return {
on: function (name, callback) {
if(!name || !callback || typeof name != 'string' || typeof callback != 'function')
throw new Error('Invalid arguments in method #on(' + typeof name + ', ' + typeof callback + ')' + ' where it should be: #on(string, function)');
events[name] = callback;
},
run : function(callback){
if(!callback || typeof callback != 'function')
throw new Error('Invalid arguments in method #run(' + typeof callback + ')' + ' where it should be: #run(function)');
stack.push(callback);
},
callee: function(callback){
deprecate('callee() is deprecated, use #run() instead.');
this.run(callback);
}
}
};
module.exports = Obj;