node-red-contrib-mobius-flow-base 2.5.86-beta.11 → 2.5.86-beta.112

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.
@@ -193,12 +193,142 @@ module.exports = function (RED) {
193
193
  });
194
194
  };
195
195
 
196
+ /**
197
+ * Select status text and colour of node status based on last active time
198
+ * @param {number} lastActiveTime - The node's last active time
199
+ * @returns Object containing status text and status colour
200
+ */
201
+ node.buildLastActiveTimeStatus = function (lastActiveTime) {
202
+ let response = {
203
+ text: 'Unknown',
204
+ colour: 'green',
205
+ };
206
+ const timeSinceLastActive = Date.now() - lastActiveTime;
207
+ if (timeSinceLastActive < 15 * 60000) {
208
+ response.text = 'Active less than 15 minutes ago';
209
+ }
210
+ if (timeSinceLastActive >= 15 * 60000 && timeSinceLastActive < 3 * 60 * 60000) {
211
+ response.text = 'Active less than 3 hours ago';
212
+ }
213
+ if (timeSinceLastActive >= 3 * 60 * 60000 && timeSinceLastActive < 12 * 60 * 60000) {
214
+ response.text = 'Active less than 12 hours ago';
215
+ }
216
+ if (timeSinceLastActive >= 12 * 60 * 60000 && timeSinceLastActive < 24 * 60 * 60000) {
217
+ response.text = 'Active less than 24 hours ago';
218
+ }
219
+ if (timeSinceLastActive > 24 * 60 * 60000 && lastActiveTime > 0) {
220
+ response.colour = 'grey';
221
+ response.text = 'Active more than 24 hours ago';
222
+ }
223
+ if (lastActiveTime === 0) {
224
+ response.colour = 'grey';
225
+ response.text = 'Never Active';
226
+ }
227
+ return {
228
+ fill: response.colour,
229
+ shape: 'dot',
230
+ text: response.text,
231
+ };
232
+ };
233
+
234
+ /**
235
+ * Update a given node's node status based on last active time
236
+ * @param {Object} mobiusNode - The node whos status is to be updated
237
+ */
238
+ node.updateNodeStatus = function (mobiusNode) {
239
+ node.users[mobiusNode.id] = mobiusNode;
240
+ if (!node.users[mobiusNode.id].inError) {
241
+ switch (node.users[mobiusNode.id].statusType) {
242
+ case 'timeSinceLastActive':
243
+ node.users[mobiusNode.id].status(
244
+ node.buildLastActiveTimeStatus(node.users[mobiusNode.id].lastActiveTime)
245
+ );
246
+ break;
247
+ case 'lastUri':
248
+ const uri = node.users[mobiusNode.id].latestUri;
249
+ if (uri !== '' && uri !== undefined) {
250
+ node.users[mobiusNode.id].status({
251
+ fill: 'green',
252
+ shape: 'dot',
253
+ text: uri,
254
+ });
255
+ }
256
+ break;
257
+ case 'lastValue':
258
+ const value = node.users[mobiusNode.id].latestValue;
259
+ if (value !== '' && value !== undefined) {
260
+ node.users[mobiusNode.id].status({
261
+ fill: 'green',
262
+ shape: 'dot',
263
+ text: value,
264
+ });
265
+ }
266
+ break;
267
+ }
268
+ } else {
269
+ node.users[mobiusNode.id].status({
270
+ fill: 'yellow',
271
+ shape: 'dot',
272
+ text: node.users[mobiusNode.id].latestErrMessage,
273
+ });
274
+ }
275
+ };
276
+
277
+ // Information update functions to be used by node status
278
+ // Calling any of these will update the node status
279
+ node.update = {
280
+ /**
281
+ * Update a given node's node last active time
282
+ * @param {Object} mobiusNode - The node whos last active time is to be updated
283
+ */
284
+ lastActiveTime: (mobiusNode) => {
285
+ node.users[mobiusNode.id] = mobiusNode;
286
+ node.users[mobiusNode.id].lastActiveTime = Date.now();
287
+ node.users[mobiusNode.id].inError = false;
288
+ node.updateNodeStatus(mobiusNode);
289
+ },
290
+ /**
291
+ * Update a given node's node latest URI record
292
+ * @param {Object} mobiusNode - The node whos last URI record is to be updated
293
+ * @param {string} uri - The latest uri to be sent by the node
294
+ */
295
+ latestUri: (mobiusNode, uri) => {
296
+ node.users[mobiusNode.id] = mobiusNode;
297
+ node.users[mobiusNode.id].latestUri = uri;
298
+ node.users[mobiusNode.id].inError = false;
299
+ node.updateNodeStatus(mobiusNode);
300
+ },
301
+ /**
302
+ * Update a given node's node latest sent value record
303
+ * @param {Object} mobiusNode - The node whos last value record is to be updated
304
+ * @param {number} value - The latest value to be sent by the node
305
+ */
306
+ latestValue: (mobiusNode, value) => {
307
+ node.users[mobiusNode.id] = mobiusNode;
308
+ node.users[mobiusNode.id].latestValue = value;
309
+ node.users[mobiusNode.id].inError = false;
310
+ node.updateNodeStatus(mobiusNode);
311
+ },
312
+ /**
313
+ * Update a given node's node latest error message record
314
+ * @param {Object} mobiusNode - The node whos last error message record is to be updated
315
+ * @param {number} value - The node's latest error message
316
+ */
317
+ errMessage: (mobiusNode, message) => {
318
+ node.users[mobiusNode.id] = mobiusNode;
319
+ node.users[mobiusNode.id].latestErrMessage = message;
320
+ node.users[mobiusNode.id].inError = true;
321
+ node.updateNodeStatus(mobiusNode);
322
+ },
323
+ };
324
+
196
325
  /**
197
326
  * Register a new Mobius node with this config node
198
327
  * @param {Object} mobiusNode - The new node to register
199
328
  */
200
329
  node.register = function (mobiusNode) {
201
330
  node.users[mobiusNode.id] = mobiusNode;
331
+ node.users[mobiusNode.id].inError = false;
202
332
  if (node.connected) {
203
333
  node.users[mobiusNode.id].status({
204
334
  fill: 'green',
@@ -206,6 +336,12 @@ module.exports = function (RED) {
206
336
  text: 'Connected',
207
337
  });
208
338
  }
339
+ node.users[mobiusNode.id].lastActiveTime = 0;
340
+ node.users[mobiusNode.id].statusCheckLoop = setInterval(() => {
341
+ if (node.connected) {
342
+ node.updateNodeStatus(mobiusNode);
343
+ }
344
+ }, 60000);
209
345
  };
210
346
 
211
347
  /**
@@ -214,6 +350,7 @@ module.exports = function (RED) {
214
350
  * @param {Function} done - A callback to be run by the node after it has been deregistered
215
351
  */
216
352
  node.deregister = function (mobiusNode, done) {
353
+ clearInterval(node.users[mobiusNode.id].statusCheckLoop);
217
354
  delete node.users[mobiusNode.id];
218
355
  if (node.service) {
219
356
  try {
@@ -520,30 +657,6 @@ module.exports = function (RED) {
520
657
  node.updateObjectInServiceConfig = function (hid, sid, pid, ins, config, callback) {
521
658
  node.service.srvcAPI.updateObjectInServiceConfig(hid, sid, pid, ins, config, callback);
522
659
  };
523
-
524
- node.getNodeConfig = function (hid) {
525
- return new Promise((resolve, reject) => {
526
- node.service.srvcAPI.getNodeConfig(hid, (err, response) => {
527
- if (!err) {
528
- resolve(response);
529
- } else {
530
- reject(err);
531
- }
532
- });
533
- });
534
- };
535
-
536
- node.getServiceConfigProm = function (hid, sid) {
537
- return new Promise((resolve, reject) => {
538
- node.service.srvcAPI.getServiceConfig(hid, sid, (err, response) => {
539
- if (!err) {
540
- resolve(response);
541
- } else {
542
- reject(err);
543
- }
544
- });
545
- });
546
- };
547
660
  }
548
661
 
549
662
  RED.nodes.registerType('mobius connection', MobiusConnectionNode);
@@ -604,42 +717,4 @@ module.exports = function (RED) {
604
717
  }
605
718
  }
606
719
  );
607
-
608
- // Register the endpoint for node-red mobius discovery in node-red node config pages
609
- RED.httpAdmin.get('/mdiscover', RED.auth.needsPermission('serial.read'), function (req, res) {
610
- let conn = RED.nodes.getNode(req.query.mobius);
611
- let uri = req.query.uri;
612
- if (conn === null || !conn.service.connected) {
613
- RED.log.error('Discover services failed - could not to connect to MOBiUS hub.');
614
- throw new Error('Discover services failed - could not to connect to MOBiUS hub.');
615
- } else {
616
- uiDeviceDiscovery
617
- .discover(conn, uri)
618
- .then((response) => {
619
- res.json(response);
620
- })
621
- .catch((err) => {
622
- throw err;
623
- });
624
- }
625
- });
626
-
627
- // Register the endpoint for node-red mobius discovery in node-red node config pages
628
- RED.httpAdmin.get('/mgetservices', RED.auth.needsPermission('serial.read'), function (req, res) {
629
- let conn = RED.nodes.getNode(req.query.mobius);
630
- let hid = req.query.hid;
631
- if (conn === null || !conn.service.connected) {
632
- RED.log.error('Get services failed - could not to connect to MOBiUS hub.');
633
- throw new Error('Get services failed - could not to connect to MOBiUS hub.');
634
- } else {
635
- uiDeviceDiscovery
636
- .getServiceList(conn, hid)
637
- .then((response) => {
638
- res.json(response);
639
- })
640
- .catch((err) => {
641
- RED.log.warn(`Get services failed - ${err}`);
642
- });
643
- }
644
- });
645
720
  };
@@ -53,6 +53,13 @@ POSSIBILITY OF SUCH DAMAGE.
53
53
  <label for="node-input-detailedOutput" style="width: 70%;"> Use detailed outputs</label>
54
54
  </div>
55
55
  <hr>
56
+ <div class="form-row">
57
+ <label for="node-input-statusType" style="width: 135px;"><p><font color=##55aa88><i class="fa fa-square"></i></font> Status Display</p></label>
58
+ <select type="text" id="node-input-statusType" style="display: inline-block; width: 287px; vertical-align: center;">
59
+ <option value="timeSinceLastActive">Show time since last active</option>
60
+ <option value="lastUri">Show last URI</option>
61
+ </select>
62
+ </div>
56
63
  <div class="form-row">
57
64
  <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
58
65
  <input type="text" id="node-input-name" placeholder="Name">
@@ -64,6 +71,7 @@ POSSIBILITY OF SUCH DAMAGE.
64
71
  category: 'mobius',
65
72
  defaults: {
66
73
  name: {value:""},
74
+ statusType: {value:"timeSinceLastActive"},
67
75
  detailedOutput: {value:false},
68
76
  format: {value: "name", required: true},
69
77
  include: {value: "changed", required: true},
@@ -29,29 +29,29 @@
29
29
  var _ = require('lodash');
30
30
 
31
31
  module.exports = function (RED) {
32
- function MobiusObjectCovNode (n) {
32
+ function MobiusObjectCovNode(n) {
33
33
  RED.nodes.createNode(this, n);
34
34
  this.detailedOutput = n.detailedOutput;
35
35
  this.object = n.object;
36
36
  this.format = n.format;
37
37
  this.include = n.include;
38
38
  this.serviceConn = RED.nodes.getNode(n.connection);
39
+ this.statusType = n.statusType;
39
40
  var node = this;
40
41
 
41
42
  if (node.serviceConn) {
42
43
  node.status({
43
44
  fill: 'red',
44
45
  shape: 'ring',
45
- text: 'Disconnected'
46
+ text: 'Disconnected',
46
47
  });
47
-
48
48
  node.serviceConn.subscribeToObjectCOV(node.object, this.id, (response) => {
49
- node.status({
50
- fill: 'green',
51
- shape: 'dot',
52
- text: JSON.stringify(response.uri)
53
- });
54
- let allResources = _.keyBy(response.value.resources, node.format === 'name' ? 'name' : 'rid');
49
+ node.serviceConn.update.latestUri(node, response.uri);
50
+ node.serviceConn.update.lastActiveTime(node);
51
+ let allResources = _.keyBy(
52
+ response.value.resources,
53
+ node.format === 'name' ? 'name' : 'rid'
54
+ );
55
55
  if (node.include === 'changed') {
56
56
  allResources = _.pickBy(allResources, (res) => {
57
57
  return response.changed.includes(res.rid);
@@ -61,7 +61,7 @@ module.exports = function (RED) {
61
61
  node.send([
62
62
  { topic: response.uri, payload: allResources },
63
63
  { topic: response.uri, payload: response.value },
64
- { topic: response.uri, payload: { response: response } }
64
+ { topic: response.uri, payload: { response: response } },
65
65
  ]);
66
66
  } else {
67
67
  node.send({ topic: response.uri, payload: allResources });
@@ -29,7 +29,7 @@
29
29
  const _ = require('lodash');
30
30
 
31
31
  module.exports = {
32
- async discover(connection, uri) {
32
+ async discover (connection, uri) {
33
33
  return new Promise((resolve, reject) => {
34
34
  connection.discover(uri, (err, response) => {
35
35
  if (err) {
@@ -41,7 +41,7 @@ module.exports = {
41
41
  });
42
42
  },
43
43
 
44
- async discoverDevicesByPID(RED, connection, hid, spids, pid) {
44
+ async discoverDevicesByPID (RED, connection, hid, spids, pid) {
45
45
  let devices = [];
46
46
  if (!hid || hid === '') {
47
47
  hid = connection.service.srvcAPI.status.hubId;
@@ -54,17 +54,12 @@ module.exports = {
54
54
  throw new Error(`Discover devices failed (${hid}) - ${err.message}`);
55
55
  }
56
56
  for (let srvcLoop = 0; srvcLoop < services.value.length; srvcLoop++) {
57
- if (
58
- services.value[srvcLoop].status === 'online' &&
59
- (spids.length === 0 || spids.includes(services.value[srvcLoop].spid))
60
- ) {
57
+ if (services.value[srvcLoop].status === 'online' && (spids.length === 0 || spids.includes(services.value[srvcLoop].spid))) {
61
58
  let insURI = `${hid}/${services.value[srvcLoop].id.split('/')[1]}/${pid}`;
62
59
  try {
63
60
  let instances = await this.discover(connection, insURI);
64
61
  for (let insLoop = 0; insLoop < instances.value.length; insLoop++) {
65
- let deviceURI = `${hid}/${services.value[srvcLoop].id.split('/')[1]}/${pid}/${
66
- instances.value[insLoop]
67
- }`;
62
+ let deviceURI = `${hid}/${services.value[srvcLoop].id.split('/')[1]}/${pid}/${instances.value[insLoop]}`;
68
63
  let device = await this.discover(connection, deviceURI);
69
64
  let resourcesByName = _.keyBy(device.value[0].resources, 'name');
70
65
  let deviceName = resourcesByName['name'].pv;
@@ -84,7 +79,7 @@ module.exports = {
84
79
  });
85
80
  },
86
81
 
87
- async discoverServicesBySPID(RED, connection, hid, spid) {
82
+ async discoverServicesBySPID (RED, connection, hid, spid) {
88
83
  if (!hid || hid === '') {
89
84
  hid = connection.service.srvcAPI.status.hubId;
90
85
  }
@@ -104,101 +99,5 @@ module.exports = {
104
99
  return new Promise((resolve) => {
105
100
  resolve(srvcs);
106
101
  });
107
- },
108
-
109
- getServiceList(connection, hid) {
110
- // getNodeConfig -> id, spid, uri, name, enabled, runAtStart
111
- // For every: getServiceConfig -> mobiusSettings, customSettings
112
- // discover -> registered, last connected, status + any remaining if new service
113
- // For every: discover object -/0001/0001 -> status, statusText
114
- return new Promise(async (resolve, reject) => {
115
- try {
116
- // Fetch information from node config
117
- const nodeConfig = await connection.getNodeConfig(hid);
118
- const servicesFromConfig = nodeConfig.value.services;
119
- let services = [];
120
- for (let i = 0; i < servicesFromConfig.length; i++) {
121
- services.push({
122
- id: servicesFromConfig[i].id,
123
- spid: servicesFromConfig[i].id.split('/')[0],
124
- sid: servicesFromConfig[i].id.split('/')[1],
125
- uri: `${nodeConfig.uri}/${servicesFromConfig[i].id.split('/')[1]}`,
126
- name: servicesFromConfig[i].name,
127
- enabled: servicesFromConfig[i].enabled,
128
- runAtStart: servicesFromConfig[i].runAtStart,
129
- registered: null,
130
- lastConnected: null,
131
- status: null,
132
- statusText: null,
133
- mobiusSettings: null,
134
- customSettings: null,
135
- });
136
- }
137
-
138
- // Fetch information from each service config
139
- for (let i = 0; i < services.length; i++) {
140
- const fullServiceConfig = await connection.getServiceConfigProm(hid, services[i].sid);
141
- console.log(fullServiceConfig);
142
- services[i].mobiusSettings = fullServiceConfig.value.serviceConfig.settings;
143
- services[i].customSettings = fullServiceConfig.value.serviceConfig.custom;
144
- }
145
-
146
- console.log('Following service node configs');
147
- console.log(services);
148
-
149
- // Fetch information from discovered services
150
- const discoveryResponse = await this.discover(connection, hid);
151
- const servicesFromDiscovery = discoveryResponse.value;
152
- for (let i = 0; i < servicesFromDiscovery.length; i++) {
153
- let serviceFound = false;
154
- for (let j = 0; j < services.length; j++) {
155
- if (servicesFromDiscovery[i].id === services[j].id) {
156
- serviceFound = true;
157
- services[j].registered = servicesFromDiscovery[i].registered;
158
- services[j].lastConnected = servicesFromDiscovery[i].lastconnected;
159
- j = services.length;
160
- }
161
- }
162
- if (!serviceFound) {
163
- services.push({
164
- id: servicesFromDiscovery[i].id,
165
- spid: servicesFromDiscovery[i].id.split('/')[0],
166
- sid: servicesFromDiscovery[i].id.split('/')[1],
167
- uri: `${nodeConfig.uri}/${servicesFromDiscovery[i].id.split('/')[1]}`,
168
- name: null,
169
- enabled: null,
170
- runAtStart: null,
171
- registered: servicesFromDiscovery[i].registered,
172
- lastConnected: servicesFromDiscovery[i].lastconnected,
173
- status: null,
174
- statusText: null,
175
- mobiusSettings: null,
176
- customSettings: null,
177
- });
178
- }
179
- }
180
-
181
- console.log('Following discover');
182
- console.log(services);
183
-
184
- // Fetch status object from all services
185
- for (let i = 0; i < services.length; i++) {
186
- const statusObjectResponse = await this.discover(
187
- connection,
188
- `${hid}/${services[i].sid}/0001/0001`
189
- );
190
- const statusObject = statusObjectResponse.value;
191
- services[i].status = statusObject.resources[1].pv;
192
- services[i].statusText = `${statusObject.resources[2].pv}`;
193
- }
194
-
195
- console.log('Complete');
196
- console.log(services);
197
-
198
- resolve(services);
199
- } catch (err) {
200
- reject(err);
201
- }
202
- });
203
- },
102
+ }
204
103
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-mobius-flow-base",
3
- "version": "2.5.86-beta.11",
3
+ "version": "2.5.86-beta.112",
4
4
  "description": "Node-RED base nodes for Mobius Flow",
5
5
  "main": "index.js",
6
6
  "types": "dist/index.d.ts",