osiota-app-modbus 1.0.8 → 1.0.9

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/busscan.js CHANGED
@@ -15,13 +15,19 @@ var app_config = {
15
15
  var m = new modbus.modbus(app_config);
16
16
  m.onerror = function(err) {
17
17
  if (err.name === "TransactionTimedOutError") {
18
+ m.client._port.openFlag = true;
18
19
  return;
19
20
  }
20
21
  console.log("modbus, error:", err.stack || err);
21
22
  };
22
23
 
23
24
 
24
- m.connect(app_config.connect_type, app_config.connect_path, app_config.connect_options, function() {
25
+ m.connect(app_config.connect_type, app_config.connect_path, app_config.connect_options, function(err) {
26
+ if (err) {
27
+ console.error("Error:", err);
28
+ return;
29
+ }
30
+ console.log("Connected");
25
31
  scan();
26
32
  });
27
33
 
package/busscan_tcp.js ADDED
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+
3
+ var modbus = require("./helper_modbus.js");
4
+
5
+
6
+ var app_config = {
7
+ "connect_type": "Telnet",
8
+ "connect_path": "192.168.2.111",
9
+ "connect_options": {
10
+ "port": 12345
11
+ },
12
+ "packet_timeout": 200
13
+ };
14
+
15
+ var m = new modbus.modbus(app_config);
16
+ m.onerror = function(err) {
17
+ if (err.name === "TransactionTimedOutError") {
18
+ m.client._port.openFlag = true;
19
+ //m.client.openFlag = true;
20
+ return;
21
+ }
22
+ console.log("modbus, error:", err.stack || err);
23
+ };
24
+
25
+
26
+ m.connect(app_config.connect_type, app_config.connect_path, app_config.connect_options, function(err) {
27
+ if (err) {
28
+ console.error("Error:", err);
29
+ return;
30
+ }
31
+ console.log("Connected");
32
+ scan();
33
+ });
34
+
35
+ var cid = 1;
36
+ var scan = function() {
37
+ if (cid > 255) {
38
+ m.close();
39
+ return;
40
+ }
41
+
42
+ m.send_set("writeFC1", cid, 0, 1, function(err) {
43
+ if (err) {
44
+ console.log(cid, "No Client");
45
+ }
46
+ else {
47
+ console.log(cid, "Found");
48
+ }
49
+ cid++;
50
+ scan();
51
+ });
52
+ };
package/helper_modbus.js CHANGED
@@ -1,10 +1,12 @@
1
1
 
2
2
  var ModbusRTU = require("modbus-serial");
3
3
 
4
- var read_data = function(client_items, address_min, data) {
4
+ var read_data = function(client_items, address_min, data, buffer) {
5
5
  client_items.forEach(function(c) {
6
6
  c.callback(data.slice(c.address-address_min,
7
- c.address-address_min+c.length));
7
+ c.address-address_min+c.length),
8
+ buffer.slice(2*(c.address-address_min),
9
+ 2*(c.address-address_min+c.length)));
8
10
  });
9
11
  };
10
12
 
@@ -28,6 +30,10 @@ exports.modbus = function(config) {
28
30
  this.packet_delay = config.packet_delay;
29
31
  this.circle_delay = config.circle_delay;
30
32
  this.client.setTimeout(config.packet_timeout);
33
+ this.max_payload = 60;
34
+ if (typeof config.max_payload === "number") {
35
+ this.max_payload = config.max_payload;
36
+ }
31
37
 
32
38
  this.commands = {
33
39
  "output boolean": {
@@ -54,7 +60,7 @@ exports.modbus = function(config) {
54
60
  this.set_commands = [];
55
61
 
56
62
  this.onerror = function(err) {
57
- console.log("modbus, run:", err.stack || err);
63
+ console.error("modbus, run:", err.stack || err);
58
64
  return false;
59
65
  };
60
66
 
@@ -95,12 +101,16 @@ exports.modbus.prototype.client_add = function(type, cid, config) {
95
101
  throw new Error("type undefined: " + type);
96
102
  return;
97
103
  }
104
+ var gid = config.address - (config.address % this.max_payload);
98
105
  if (typeof this.commands[type].clients[cid] !== "object" ||
99
- !Array.isArray(this.commands[type].clients[cid])) {
100
- this.commands[type].clients[cid] = [];
106
+ this.commands[type].clients[cid] === null) {
107
+ this.commands[type].clients[cid] = {"groups": []};
108
+ }
109
+ if (!Array.isArray(this.commands[type].clients[cid].groups[gid])) {
110
+ this.commands[type].clients[cid].groups[gid] = [];
101
111
  }
102
112
 
103
- this.commands[type].clients[cid].push(config);
113
+ this.commands[type].clients[cid].groups[gid].push(config);
104
114
  };
105
115
 
106
116
  exports.modbus.prototype.client_can_set = function(type) {
@@ -146,7 +156,7 @@ exports.modbus.prototype.send_poll = function(command, cid, address, length, cli
146
156
  length,
147
157
  function(err, data) {
148
158
  if (already_called) {
149
- console.log("Warn: Called callback twice. Command: POLL", command, cid, address, data, "\nThis happens after a timeout. Please increase the packet timeout.");
159
+ console.warn("Warn: Called callback twice. Command: POLL", command, cid, address, data, "\nThis happens after a timeout. Please increase the packet timeout.");
150
160
  return;
151
161
  }
152
162
  already_called = true;
@@ -161,11 +171,11 @@ exports.modbus.prototype.send_poll = function(command, cid, address, length, cli
161
171
  if (_this.onerror(err))
162
172
  return;
163
173
  } else {
164
- read_data(client_items, address, data.data);
174
+ read_data(client_items, address, data.data, data.buffer);
165
175
  }
166
176
  callback();
167
177
  }
168
- );
178
+ );
169
179
  };
170
180
  exports.modbus.prototype.send_set = function(command, cid, address, data, callback) {
171
181
  var _this = this;
@@ -179,7 +189,7 @@ exports.modbus.prototype.send_set = function(command, cid, address, data, callba
179
189
  data,
180
190
  function(err, new_data) {
181
191
  if (already_called) {
182
- console.log("Warn: Called callback twice. Command: SET", command, cid, address, data, "\nThis happens after a timeout. Please increase the packet timeout.");
192
+ console.warn("Warn: Called callback twice. Command: SET", command, cid, address, data, "\nThis happens after a timeout. Please increase the packet timeout.");
183
193
  return;
184
194
  }
185
195
  already_called = true;
@@ -222,11 +232,14 @@ exports.modbus.prototype.connect = function(connect_type, path, options,
222
232
  }
223
233
  });
224
234
 
225
- for (var type in this.commands) {
226
- for (var cid in this.commands[type].clients) {
227
- var address_min = null;
228
- var address_max = null;
229
- this.commands[type].clients[cid].forEach(function(c) {
235
+ this.poll_commands = [];
236
+ for (let type in this.commands) {
237
+ for (let cid in this.commands[type].clients) {
238
+ for (let gid in this.commands[type].clients[cid].groups) {
239
+ let address_min = null;
240
+ let address_max = null;
241
+ this.commands[type].clients[cid].groups[gid].
242
+ forEach(function(c) {
230
243
  if (address_min === null || c.address < address_min) {
231
244
  address_min = c.address;
232
245
  }
@@ -238,13 +251,22 @@ exports.modbus.prototype.connect = function(connect_type, path, options,
238
251
  //commands[type].clients[cid].address = address_min;
239
252
  //commands[type].clients[cid].length = address_max-address_min;
240
253
 
241
- (function(_this, command, cid, address, length, client_items) {
242
- _this.poll_commands.push(function(next) {
243
- _this.send_poll(command, +cid, address, length, client_items, next);
244
- });
245
- })(this, this.commands[type].command_poll, cid, address_min,
246
- address_max-address_min,
247
- this.commands[type].clients[cid]);
254
+ let command = this.commands[type].command_poll;
255
+ let address = address_min;
256
+ let length = address_max-address_min;
257
+ let client_items = this.commands[type].clients[cid].groups[gid];
258
+
259
+ this.poll_commands.push(function(next) {
260
+ _this.send_poll(
261
+ command,
262
+ +cid,
263
+ address_min,
264
+ length,
265
+ client_items,
266
+ next
267
+ );
268
+ });
269
+ }
248
270
  }
249
271
  }
250
272
 
package/index.js CHANGED
@@ -1,10 +1,25 @@
1
1
 
2
2
  var modbus = require("./helper_modbus.js");
3
3
 
4
- var map_value = function(datatype, data) {
4
+ var map_value = function(datatype, data, buffer) {
5
5
  if (datatype == "uint16") {
6
+ //return buffer.readUInt16BE(0);
6
7
  return data[0];
7
8
  }
9
+ else if (datatype == "floatBE") {
10
+ return buffer.readFloatBE(0);
11
+ }
12
+ else if (datatype == "floatLE") {
13
+ return buffer.readFloatLE(0);
14
+ }
15
+ else if (datatype == "floatBE-swap") {
16
+ buffer.swap16();
17
+ return buffer.readFloatBE(0);
18
+ }
19
+ else if (datatype == "floatLE-swap") {
20
+ buffer.swap16();
21
+ return buffer.readFloatLE(0);
22
+ }
8
23
  else if (datatype == "boolean") {
9
24
  return data[0] != 0;
10
25
  }
@@ -15,6 +30,30 @@ var remap_value = function(datatype, value) {
15
30
  if (datatype == "uint16") {
16
31
  return [ value*1 ];
17
32
  }
33
+ if (datatype == "floatBE") {
34
+ let buffer = Buffer.alloc(4);
35
+ buffer.writeFloatBE(value);
36
+ return buffer;
37
+ //return new Uint16Array(buffer.buffer,buffer.byteOffset,buffer.length/2);
38
+ //return [ buffer.readUInt16BE(0), buffer.readUInt16BE(2) ];
39
+ }
40
+ else if (datatype == "floatLE") {
41
+ let buffer = Buffer.alloc(4);
42
+ buffer.writeFloatLE(value);
43
+ return buffer;
44
+ }
45
+ else if (datatype == "floatBE-swap") {
46
+ let buffer = Buffer.alloc(4);
47
+ buffer.writeFloatBE(value);
48
+ buffer.swap16();
49
+ return buffer;
50
+ }
51
+ else if (datatype == "floatLE-swap") {
52
+ let buffer = Buffer.alloc(4);
53
+ buffer.writeFloatLE(value);
54
+ buffer.swap16();
55
+ return buffer;
56
+ }
18
57
  else if (datatype == "boolean") {
19
58
  return [ value*1 ];
20
59
  }
@@ -22,11 +61,6 @@ var remap_value = function(datatype, value) {
22
61
  };
23
62
 
24
63
  exports.init = function(node, app_config, main, host_info) {
25
-
26
- var baudrate = 38400;
27
-
28
- var models = {};
29
-
30
64
  if (typeof app_config !== "object") {
31
65
  app_config = {};
32
66
  }
@@ -41,7 +75,7 @@ exports.init = function(node, app_config, main, host_info) {
41
75
 
42
76
  var m = new modbus.modbus(app_config);
43
77
  m.onerror = function(err) {
44
- console.log("modbus, error:", err.stack || err);
78
+ console.error("modbus, error:", err.stack || err);
45
79
 
46
80
  if (typeof err.message === "string" &&
47
81
  err.message.match(/^Timed out/))
@@ -52,7 +86,7 @@ exports.init = function(node, app_config, main, host_info) {
52
86
  if (this.close)
53
87
  this.close();
54
88
 
55
- console.log("modbus, restarting ...");
89
+ console.info("modbus, restarting ...");
56
90
  _this._reinit_delay(5000);
57
91
  return true;
58
92
  };
@@ -60,13 +94,13 @@ exports.init = function(node, app_config, main, host_info) {
60
94
  var map_itemtype = function(type) {
61
95
  if (typeof type !== "string")
62
96
  return "output boolean";
63
- if (type.match(/FC1/i))
97
+ if (type.match(/^FC(1|5|15)$/i))
64
98
  return "output boolean";
65
- if (type.match(/FC2/i))
99
+ if (type.match(/^FC2$/i))
66
100
  return "input boolean";
67
- if (type.match(/FC3/i))
101
+ if (type.match(/^FC(3|6|16)$/i))
68
102
  return "output register";
69
- if (type.match(/FC4/i))
103
+ if (type.match(/^FC4$/i))
70
104
  return "input register";
71
105
 
72
106
  if (type.match(/coil/))
@@ -84,6 +118,10 @@ exports.init = function(node, app_config, main, host_info) {
84
118
  return "output boolean";
85
119
  };
86
120
 
121
+ node.announce({
122
+ "type": "modbus.app"
123
+ });
124
+
87
125
  var map = node.map(app_config.map, null, true, null,
88
126
  function(n,metadata,config) {
89
127
  var command = map_itemtype(config.type);
@@ -92,7 +130,11 @@ exports.init = function(node, app_config, main, host_info) {
92
130
  var length = config.length;
93
131
  if (typeof length !== "number") {
94
132
  var tmp = remap_value(config.datatype, 0);
95
- length = tmp.length;
133
+ if (Buffer.isBuffer(tmp)) {
134
+ length = tmp.length / 2;
135
+ } else {
136
+ length = tmp.length;
137
+ }
96
138
  }
97
139
 
98
140
  var type = "number";
@@ -104,8 +146,8 @@ exports.init = function(node, app_config, main, host_info) {
104
146
  m.client_add(command, cid, {
105
147
  "address": config.address || 0,
106
148
  "length": length || 1,
107
- "callback": function(data) {
108
- var value = map_value(config.datatype, data);
149
+ "callback": function(data, buffer) {
150
+ var value = map_value(config.datatype, data, buffer);
109
151
  // better name: reset
110
152
  if (config.erase && value) {
111
153
  // uninitialized?
@@ -141,6 +183,9 @@ exports.init = function(node, app_config, main, host_info) {
141
183
  }
142
184
  });
143
185
  };
186
+ n.rpc_toggle = function(reply, time) {
187
+ return n.rpc_set(reply, !n.value, time);
188
+ };
144
189
  n.rpc_publish = function(reply, time, value) {
145
190
  return n.rpc_set(reply, value, time);
146
191
  };
@@ -163,7 +208,8 @@ exports.init = function(node, app_config, main, host_info) {
163
208
  });
164
209
 
165
210
  // open connection to a port
166
- m.connect(app_config.connect_type, app_config.connect_path, app_config.connect_options);
211
+ m.connect(app_config.connect_type, app_config.connect_path,
212
+ JSON.parse(JSON.stringify(app_config.connect_options || {})));
167
213
 
168
- return [map, m];
214
+ return [node, map, m];
169
215
  };
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "osiota-app-modbus",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "This application connects devices via Modbus",
5
5
  "main": "index.js",
6
6
  "dependencies": {
7
- "modbus-serial": "^7.7.2",
8
- "serialport": "^7.1.5"
7
+ "modbus-serial": "^8.0.23",
8
+ "serialport": "^13.0.0"
9
9
  },
10
10
  "devDependencies": {
11
11
  "osiota-dev": "^1.x"
package/schema.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "type": "object",
3
- "title": "osiota application modbus",
3
+ "title": "osiota Application Modbus",
4
4
  "description": "This application connects devices via Modbus.",
5
5
  "oneOf": [{
6
6
  "description": "Modbus Serial Interface",
@@ -112,7 +112,7 @@
112
112
  "type": {
113
113
  "title": "Modbus Field Type",
114
114
  "type": "string",
115
- "enum": [ "input boolean", "input register", "output boolen", "output register" ]
115
+ "enum": [ "input boolean", "input register", "output boolean", "output register" ]
116
116
  },
117
117
  "datatype": {
118
118
  "title": "Field Data Type",
@@ -136,6 +136,7 @@
136
136
  "power": 60
137
137
  }
138
138
  }],
139
+ "additionalProperties": false,
139
140
  "required": [ "id", "address", "datatype" ]
140
141
  }
141
142
  }