smart-nodes 0.3.27 → 0.3.28

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.
@@ -22,8 +22,17 @@ module.exports = function (RED)
22
22
  last_direction_up: true, // remember last direction for toggle action
23
23
  }, smart_context.get(node.id));
24
24
 
25
+ // Backward compatibility
26
+ if (typeof config.max_time != "undefined")
27
+ {
28
+ config.max_time_up = config.max_time;
29
+ config.max_time_down = config.max_time;
30
+ delete config.max_time;
31
+ }
32
+
25
33
  // dynamic config
26
- let max_time = parseInt(config.max_time || 60);
34
+ let max_time_up = parseInt(config.max_time_up || 60);
35
+ let max_time_down = parseInt(config.max_time_down || 60);
27
36
  let revert_time_ms = parseInt(config.revert_time_ms || 100);
28
37
  let alarm_action = config.alarm_action || "NOTHING";
29
38
 
@@ -123,9 +132,7 @@ module.exports = function (RED)
123
132
 
124
133
  on_time = Date.now();
125
134
  resultUp = true;
126
- startAutoOff(false, helper.getTimeInMsFromString(msg.time_on) || null);
127
- if (!alarm_active)
128
- node.status({ fill: "green", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Up" });
135
+ startAutoOff(false, helper.getTimeInMsFromString(msg.time_on) || null, null, msg.exact);
129
136
  break;
130
137
 
131
138
  case "stop":
@@ -135,15 +142,19 @@ module.exports = function (RED)
135
142
  resultStop = true;
136
143
  if (max_time_timeout != null)
137
144
  {
138
- const change_percentage = (Date.now() - on_time) / 1000 / max_time * 100;
139
145
  if (node_settings.last_direction_up)
146
+ {
147
+ const change_percentage = (Date.now() - on_time) / 1000 / max_time_up * 100;
140
148
  node_settings.last_position = Math.max(0, node_settings.last_position - change_percentage);
149
+ }
141
150
  else
151
+ {
152
+ const change_percentage = (Date.now() - on_time) / 1000 / max_time_down * 100;
142
153
  node_settings.last_position = Math.min(100, node_settings.last_position + change_percentage);
154
+ }
143
155
  }
144
156
  off_time = Date.now();
145
157
  stopAutoOff();
146
- node.status({ fill: "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Stopped at " + Math.round(node_settings.last_position) + "%" });
147
158
  break;
148
159
 
149
160
  case "down":
@@ -164,9 +175,7 @@ module.exports = function (RED)
164
175
 
165
176
  on_time = Date.now();
166
177
  resultDown = true;
167
- startAutoOff(true, helper.getTimeInMsFromString(msg.time_on) || null);
168
- if (!alarm_active)
169
- node.status({ fill: "green", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Down" });
178
+ startAutoOff(true, helper.getTimeInMsFromString(msg.time_on) || null, null, msg.exact);
170
179
  break;
171
180
 
172
181
  case "position":
@@ -184,13 +193,16 @@ module.exports = function (RED)
184
193
  {
185
194
  // Change position while running,
186
195
  // Calculate current position first
187
- const change_percentage = (now - on_time) / 1000 / max_time * 100;
188
196
  if (node_settings.last_direction_up)
197
+ {
198
+ const change_percentage = (now - on_time) / 1000 / max_time_up * 100;
189
199
  node_settings.last_position = Math.max(0, node_settings.last_position - change_percentage);
200
+ }
190
201
  else
202
+ {
203
+ const change_percentage = (now - on_time) / 1000 / max_time_down * 100;
191
204
  node_settings.last_position = Math.min(100, node_settings.last_position + change_percentage);
192
-
193
- node.status({ fill: "gray", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Update current position to " + node_settings.last_position + "%" });
205
+ }
194
206
 
195
207
  // Runs in the wrong direction at the moment, so stop first
196
208
  if (node_settings.last_direction_up && value > node_settings.last_position)
@@ -213,13 +225,13 @@ module.exports = function (RED)
213
225
  {
214
226
  // Go up
215
227
  resultUp = true;
216
- startAutoOff(false, (node_settings.last_position - value) / 100 * max_time * 1000, value);
228
+ startAutoOff(false, (node_settings.last_position - value) / 100 * max_time_up * 1000, value);
217
229
  }
218
230
  else if (value > node_settings.last_position)
219
231
  {
220
232
  // Go down
221
233
  resultDown = true;
222
- startAutoOff(true, (value - node_settings.last_position) / 100 * max_time * 1000, value);
234
+ startAutoOff(true, (value - node_settings.last_position) / 100 * max_time_down * 1000, value);
223
235
  }
224
236
  else
225
237
  {
@@ -227,8 +239,6 @@ module.exports = function (RED)
227
239
  handleTopic({ topic: "stop" });
228
240
  return;
229
241
  }
230
-
231
- node.status({ fill: "green", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Set position from " + node_settings.last_position + "% to " + value + "%" });
232
242
  break;
233
243
 
234
244
  case "alarm":
@@ -236,7 +246,7 @@ module.exports = function (RED)
236
246
 
237
247
  if (alarm_active)
238
248
  {
239
- node.status({ fill: "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": ALARM is active" });
249
+ node.status({ fill: "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": ALARM turned on" });
240
250
 
241
251
  switch (alarm_action)
242
252
  {
@@ -249,13 +259,17 @@ module.exports = function (RED)
249
259
  break;
250
260
  }
251
261
  }
262
+ else
263
+ {
264
+ node.status({ fill: "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": ALARM turned off" });
265
+ }
252
266
  break;
253
267
  }
254
268
 
255
- sendResult(resultUp, resultDown, resultStop);
269
+ sendResult(resultUp, resultDown, resultStop, msg.exact);
256
270
  };
257
271
 
258
- let startAutoOff = (down, wait_time_ms = null, new_position = null) =>
272
+ let startAutoOff = (down, wait_time_ms = null, new_position = null, exact = false) =>
259
273
  {
260
274
  // console.log("startAutoOff (" + down + ", " + wait_time_ms + ", " + new_position + ");");
261
275
 
@@ -276,16 +290,20 @@ module.exports = function (RED)
276
290
  down = true;
277
291
  }
278
292
  }
293
+
279
294
  if (wait_time_ms == null)
280
295
  {
281
296
  if (down)
282
- wait_time_ms = (100 - node_settings.last_position) * max_time / 100 * 1000;
297
+ wait_time_ms = (100 - node_settings.last_position) * max_time_down / 100 * 1000;
283
298
  else
284
- wait_time_ms = node_settings.last_position * max_time / 100 * 1000;
299
+ wait_time_ms = node_settings.last_position * max_time_up / 100 * 1000;
285
300
 
286
- // Run at least for 5 seconds
287
- if (wait_time_ms < 5000)
288
- wait_time_ms = 5000;
301
+ if (exact !== true)
302
+ {
303
+ // Run at least for 5 seconds
304
+ if (wait_time_ms < 5000)
305
+ wait_time_ms = 5000;
306
+ }
289
307
  }
290
308
 
291
309
  if (wait_time_ms < 0)
@@ -294,6 +312,9 @@ module.exports = function (RED)
294
312
  return;
295
313
  }
296
314
 
315
+ if (wait_time_ms == 0)
316
+ return;
317
+
297
318
  if (!alarm_active)
298
319
  node.status({ fill: "yellow", shape: "ring", text: helper.getCurrentTimeForStatus() + ": " + (down ? "Down" : "Up") + ", wait " + helper.formatMsToStatus(wait_time_ms, "until") + " for auto off" });
299
320
 
@@ -319,8 +340,18 @@ module.exports = function (RED)
319
340
  }
320
341
  };
321
342
 
322
- let sendResult = (up, down, stop) =>
343
+ let sendResult = (up, down, stop, exact) =>
323
344
  {
345
+ if (exact === true)
346
+ {
347
+ console.log({ up, down, stop, exact, last_pos: node_settings.last_position });
348
+ // Don't start moving if exact is enabled and already on top/bottom.
349
+ if (down && node_settings.last_position == 100)
350
+ return;
351
+ if (up && node_settings.last_position == 0)
352
+ return;
353
+ }
354
+
324
355
  // console.log("sendResult(" + up + ", " + down + ", " + stop + ");");
325
356
  if ((up && wait_for_down) || (down && wait_for_up))
326
357
  {
@@ -343,7 +374,7 @@ module.exports = function (RED)
343
374
  wait_timeout = setTimeout(() =>
344
375
  {
345
376
  wait_timeout = null;
346
- sendResult(up, down, stop);
377
+ sendResult(up, down, stop, exact);
347
378
  }, off_time + revert_time_ms - now);
348
379
  return;
349
380
  }
@@ -355,7 +386,7 @@ module.exports = function (RED)
355
386
  wait_timeout = null;
356
387
  }
357
388
 
358
- // console.log("really sendResult(" + up + ", " + down + ", " + stop + ");");
389
+ // console.log("really sendResult(" + up + ", " + down + ", " + stop + ", " + exact + ");");
359
390
  if (up)
360
391
  {
361
392
  if (!alarm_active || alarm_action === "UP")
@@ -363,6 +394,7 @@ module.exports = function (RED)
363
394
  node_settings.last_direction_up = true;
364
395
  node.send([{ payload: true }, { payload: false }, { payload: node_settings.last_position }]);
365
396
  notifyCentral(true);
397
+ node.status({ fill: "green", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Up" });
366
398
  }
367
399
  }
368
400
  else if (down)
@@ -372,12 +404,14 @@ module.exports = function (RED)
372
404
  node_settings.last_direction_up = false;
373
405
  node.send([{ payload: false }, { payload: true }, { payload: node_settings.last_position }]);
374
406
  notifyCentral(true);
407
+ node.status({ fill: "green", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Down" });
375
408
  }
376
409
  }
377
410
  else if (stop && !alarm_active)
378
411
  {
379
412
  node.send([{ payload: false }, { payload: false }, { payload: node_settings.last_position }]);
380
413
  notifyCentral(false);
414
+ node.status({ fill: "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Stopped at " + Math.round(node_settings.last_position) + "%" });
381
415
  }
382
416
  };
383
417
 
@@ -395,7 +429,7 @@ module.exports = function (RED)
395
429
  };
396
430
 
397
431
  // For security reason, stop shutter at node start
398
- setTimeout(() =>
432
+ wait_timeout = setTimeout(() =>
399
433
  {
400
434
  node.send([{ payload: false }, { payload: false }, { payload: node_settings.last_position }]);
401
435
  node.status({ fill: "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Stopped at " + Math.round(node_settings.last_position) + "%" });
package/smart_helper.js CHANGED
@@ -5,7 +5,7 @@ module.exports = {
5
5
  * If a type is unknown the NodeRed function is used for conversation.
6
6
  *
7
7
  * Known types are:
8
- * - null, which will return always null
8
+ * - "null", which will return always null
9
9
  */
10
10
  evaluateNodeProperty(RED, value, type)
11
11
  {
@@ -26,6 +26,7 @@ module.exports = {
26
26
  console.error(value);
27
27
  console.error(type);
28
28
  console.error(error);
29
+ console.error(msg);
29
30
  return null;
30
31
  }
31
32
  },
@@ -7,6 +7,8 @@
7
7
  name: { value: "" },
8
8
  operation: { value: "MIN" }, // MIN, MAX, SUM, DIFF, ABS, ABS_DIFF, AVG, MOV_AVG
9
9
  count: { value: 10 },
10
+ out_message: { value: '{"topic": ""}' },
11
+ out_message_type: { value: 'json' },
10
12
  save_state: { value: true },
11
13
  resend_on_start: { value: true }
12
14
  },
@@ -58,6 +60,17 @@
58
60
  $(".statistic-moving-average-row").hide();
59
61
  });
60
62
 
63
+ $("#node-input-out_message").typedInput({
64
+ type: "json",
65
+ types: ["json", {
66
+ value: "null",
67
+ label: "Standard",
68
+ icon: "fa fa-times",
69
+ hasValue: false,
70
+ }],
71
+ typeField: "#node-input-out_message_type"
72
+ });
73
+
61
74
  $("#node-input-save_state").on("change", ev =>
62
75
  {
63
76
  if (ev.target.checked)
@@ -84,6 +97,21 @@
84
97
  <input id="node-input-count" />
85
98
  </div>
86
99
  <hr/>
100
+ <h4 style="margin: 0.5rem 0;">Ausgangsnachricht</h4>
101
+ <div class="form-row">
102
+ <label for="node-input-out_message"><i class="fa fa-check-circle"></i> Nachricht</label>
103
+ <input type="text" id="node-input-out_message"/>
104
+ <input type="hidden" id="node-input-out_message_type">
105
+ </div>
106
+ <div class="form-row">
107
+ <span><strong>Hinweis:</strong></span>
108
+ </div>
109
+ <div class="form-row">
110
+ <span>
111
+ <code>msg.payload</code> wird immer automatisch auf den Ergebnis-Wert gesetzt.
112
+ </span>
113
+ </div>
114
+ <hr/>
87
115
  <h4 style="margin: 0.5rem 0;">Systemstart</h4>
88
116
  <div class="form-row">
89
117
  <input type="checkbox" id="node-input-save_state" style="width: 20px;" />
@@ -28,6 +28,7 @@ module.exports = function (RED)
28
28
 
29
29
  // dynamic config
30
30
  let operation = config.operation
31
+ let out_message = helper.evaluateNodeProperty(RED, config.out_message, config.out_message_type);
31
32
  let count = config.count;
32
33
 
33
34
  // runtime values
@@ -66,6 +67,10 @@ module.exports = function (RED)
66
67
 
67
68
  if (msg)
68
69
  {
70
+ // if out_message is set, use this instead of the default message
71
+ if (out_message)
72
+ msg = Object.assign({}, out_message, { payload: msg.payload });
73
+
69
74
  node_settings.lastMessage = msg;
70
75
  node.send(msg);
71
76
  }
@@ -180,7 +185,7 @@ module.exports = function (RED)
180
185
  if (operation === "ABS")
181
186
  node.status({ fill: "yellow", shape: "ring", text: helper.getCurrentTimeForStatus() + ": " + operation + " => " + msg.payload });
182
187
  else
183
- node.status({ fill: "yellow", shape: "ring", text: helper.getCurrentTimeForStatus() + ": " + operation + "(" + Object.entries(node_settings.values).map(v => v[1]).join(",") + ") => " + msg.payload });
188
+ node.status({ fill: "yellow", shape: "ring", text: helper.getCurrentTimeForStatus() + ": " + operation + "(" + Object.entries(node_settings.values).map(v => v[1]).join(", ") + ") => " + msg.payload });
184
189
  }
185
190
 
186
191
  if (config.save_state && config.resend_on_start && node_settings.lastMessage != null)
File without changes