smart-nodes 0.5.0 → 0.5.2

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/CHANGELOG.md CHANGED
@@ -209,4 +209,12 @@
209
209
  - Mixing valve can now output as percentage directly or with open/close impulses.
210
210
  - Mixing valve tries to guess the best position, when getting enabled.
211
211
  - Added debug topic to all nodes, to see current values.
212
- - Added new node "mode-selector".
212
+ - Added new node "mode-selector".
213
+
214
+ ## Version 0.5.1:
215
+
216
+ - To be more compatible, topic "set" is also possible instead of "set_state". Same for "set_inverted" instead of "set_state_inverted".
217
+
218
+ ## Version 0.5.2:
219
+
220
+ - Added alarm mode to mixing-valve.
@@ -81,16 +81,19 @@ module.exports = function (RED)
81
81
  {
82
82
  let real_topic = helper.getTopicName(msg.topic);
83
83
 
84
- if (real_topic == "set_state_inverted")
84
+ if (real_topic.startsWith("set_state"))
85
+ real_topic = real_topic.replace("set_state", "set");
86
+
87
+ if (real_topic == "set_inverted")
85
88
  {
86
- real_topic = "set_state";
89
+ real_topic = "set";
87
90
  msg.payload = !msg.payload;
88
91
  }
89
92
 
90
93
  let new_state = null;
91
- if (real_topic == "enable" || (real_topic == "set_state" && msg.payload))
94
+ if (real_topic == "enable" || (real_topic == "set" && msg.payload))
92
95
  new_state = true;
93
- else if (real_topic == "disable" || (real_topic == "set_state" && !msg.payload))
96
+ else if (real_topic == "disable" || (real_topic == "set" && !msg.payload))
94
97
  new_state = false;
95
98
 
96
99
  switch (real_topic)
@@ -27,11 +27,11 @@
27
27
  <td>Deaktiviert das Weiterleiten.</td>
28
28
  </tr>
29
29
  <tr>
30
- <td><code>set_state</code></td>
30
+ <td><code>set</code> oder <code>set_state</code></td>
31
31
  <td>Aktiviert das Weiterleiten, wenn <code>msg.payload = true</code> oder deaktiviert das Weiterleiten, wenn <code>msg.payload = false</code>.</td>
32
32
  </tr>
33
33
  <tr>
34
- <td><code>set_state_inverted</code></td>
34
+ <td><code>set_inverted</code> oder <code>set_state_inverted</code></td>
35
35
  <td>Aktiviert das Weiterleiten, wenn <code>msg.payload = false</code> oder deaktiviert das Weiterleiten, wenn <code>msg.payload = true</code>.</td>
36
36
  </tr>
37
37
  </tbody>
@@ -27,11 +27,11 @@
27
27
  <td>Disables forwarding.</td>
28
28
  </tr>
29
29
  <tr>
30
- <td><code>set_state</code></td>
30
+ <td><code>set</code> or <code>set_state</code></td>
31
31
  <td>Enables forwarding if <code>msg.payload = true</code> or disables forwarding if <code>msg.payload = false</code>.</td>
32
32
  </tr>
33
33
  <tr>
34
- <td><code>set_state_inverted</code></td>
34
+ <td><code>set_inverted</code> or <code>set_state_inverted</code></td>
35
35
  <td>Enables forwarding if <code>msg.payload = false</code> or disables forwarding if <code>msg.payload = true</code>.</td>
36
36
  </tr>
37
37
  </tbody>
package/light/light.js CHANGED
@@ -288,7 +288,6 @@ module.exports = function (RED)
288
288
  break;
289
289
  }
290
290
  }
291
-
292
291
  break;
293
292
 
294
293
  case "blink":
@@ -34,11 +34,11 @@
34
34
  <td>Deaktiviert die Mischeransteuerung und fährt die Position an, die als Aus-Modus festgelegt ist.</td>
35
35
  </tr>
36
36
  <tr>
37
- <td><code>set_state</code></td>
37
+ <td><code>set</code> oder <code>set_state</code></td>
38
38
  <td>Aktiviert den Mischer, wenn <code>msg.payload = true</code> oder deaktiviert ihn, wenn <code>msg.payload = false</code>.</td>
39
39
  </tr>
40
40
  <tr>
41
- <td><code>set_state_inverted</code></td>
41
+ <td><code>set_inverted</code> oder <code>set_state_inverted</code></td>
42
42
  <td>Aktiviert den Mischer, wenn <code>msg.payload = false</code> oder deaktiviert ihn, wenn <code>msg.payload = true</code>.</td>
43
43
  </tr>
44
44
  <tr>
@@ -63,6 +63,12 @@
63
63
  <td><code>current_temperature</code></td>
64
64
  <td>Setzt die aktuelle Temperatur auf <code>msg.payload</code> °C.</td>
65
65
  </tr>
66
+ <tr>
67
+ <td><code>alarm</code></td>
68
+ <td>
69
+ Setzt den aktuellen Alarmzustand auf den Wert von <code>msg.payload</code> und löst die konfigurierte Alarmaktion aus (Öffnen / Schließen).
70
+ </td>
71
+ </tr>
66
72
  <tr>
67
73
  <td><code>calibrate</code></td>
68
74
  <td>Erzwingt eine Kalibrierungsfahrt.</td>
@@ -15,6 +15,8 @@
15
15
 
16
16
  "nothing": "Nichts",
17
17
  "open": "Öffnen (100%)",
18
+ "alarm_on": "Alarm Ein",
19
+ "no_action": "Keine Aktion",
18
20
  "close": "Schließen (0%)",
19
21
  "heating": "Heizen (normal)",
20
22
  "cooling": "Kühlen (invertiert)",
@@ -34,11 +34,11 @@
34
34
  <td>Deactivates the mixer control and moves to the position that is set as the off mode.</td>
35
35
  </tr>
36
36
  <tr>
37
- <td><code>set_state</code></td>
37
+ <td><code>set</code> or <code>set_state</code></td>
38
38
  <td>Activates the mixing valve when <code>msg.payload = true</code> or deactivates it if <code>msg.payload = false</code>.</td>
39
39
  </tr>
40
40
  <tr>
41
- <td><code>set_state_inverted</code></td>
41
+ <td><code>set_inverted</code> or <code>set_state_inverted</code></td>
42
42
  <td>Activates the mixing valve when <code>msg.payload = false</code> or deactivates it if <code>msg.payload = true</code>.</td>
43
43
  </tr>
44
44
  <tr>
@@ -63,6 +63,12 @@
63
63
  <td><code>current_temperature</code></td>
64
64
  <td>Sets the current temperature to <code>msg.payload</code> °C.</td>
65
65
  </tr>
66
+ <tr>
67
+ <td><code>alarm</code></td>
68
+ <td>
69
+ Sets the current alarm state to the value of <code>msg.payload</code> and triggers the configured alarm action (Open / Close).
70
+ </td>
71
+ </tr>
66
72
  <tr>
67
73
  <td><code>calibrate</code></td>
68
74
  <td>Forces a calibration run.</td>
@@ -15,6 +15,8 @@
15
15
 
16
16
  "nothing": "Nothing",
17
17
  "open": "Open (100%)",
18
+ "alarm_on": "Alarm on",
19
+ "no_action": "No action",
18
20
  "close": "Close (0%)",
19
21
  "heating": "Heating (normal)",
20
22
  "cooling": "Cooling (inverted)",
@@ -150,7 +150,8 @@
150
150
  max_change_percent: { value: 1 },
151
151
  max_change_temp_difference: { value: 20 },
152
152
  min_change_time: { value: 100 },
153
- links: { value: [], type: "smart_central-control[]" }
153
+ links: { value: [], type: "smart_central-control[]" },
154
+ alarm_action: { value: "NOTHING" }, // NOTHING | OPEN | CLOSE
154
155
  },
155
156
  inputs: 1,
156
157
  outputs: 1,
@@ -170,6 +171,33 @@
170
171
  onEditPrepare(this, ["smart_central-control"]);
171
172
  initTreeList(node, ["smart_central-control"]);
172
173
 
174
+ $("#node-input-output_mode")
175
+ .css("max-width", "70%")
176
+ .typedInput({
177
+ type: "num",
178
+ types: [{
179
+ value: "output_mode",
180
+ options: [
181
+ { value: "OPEN_CLOSE", label: node._("mixing-valve.ui.open_close") },
182
+ { value: "PERCENTAGE", label: node._("mixing-valve.ui.percentage") },
183
+ ]
184
+ }]
185
+ });
186
+
187
+ $("#node-input-output_mode").on("change", function ()
188
+ {
189
+ if (this.value == "OPEN_CLOSE")
190
+ {
191
+ $(".only-open-close").show();
192
+ node.outputs = 3;
193
+ }
194
+ else
195
+ {
196
+ $(".only-open-close").hide();
197
+ node.outputs = 1;
198
+ }
199
+ });
200
+
173
201
  $("#node-input-setpoint")
174
202
  .css("max-width", "4rem")
175
203
  .spinner({
@@ -239,50 +267,36 @@
239
267
  ],
240
268
  }],
241
269
  });
242
-
243
- $("#node-input-output_mode")
270
+
271
+ $("#node-input-alarm_action")
244
272
  .css("max-width", "70%")
245
273
  .typedInput({
246
- type: "num",
247
274
  types: [{
248
- value: "output_mode",
275
+ value: "alarm_action",
276
+ default: "NOTHING",
249
277
  options: [
250
- { value: "OPEN_CLOSE", label: node._("mixing-valve.ui.open_close") },
251
- { value: "PERCENTAGE", label: node._("mixing-valve.ui.percentage") },
252
- ]
253
- }]
278
+ { value: "NOTHING", label: node._("mixing-valve.ui.no_action") },
279
+ { value: "OPEN", label: node._("mixing-valve.ui.open") },
280
+ { value: "CLOSE", label: node._("mixing-valve.ui.close") }
281
+ ],
282
+ }],
254
283
  });
255
284
 
256
- $("#node-input-output_mode").on("change", function ()
257
- {
258
- if (this.value == "OPEN_CLOSE")
259
- {
260
- $(".only-open-close").show();
261
- node.outputs = 3;
262
- }
263
- else
264
- {
265
- $(".only-open-close").hide();
266
- node.outputs = 1;
267
- }
268
- });
269
-
270
-
271
285
  $("#node-input-precision")
272
- .css("max-width", "4rem")
273
- .spinner({
274
- min: 0.1,
275
- max: 1.0,
276
- step: 0.1,
277
- change: function (event, ui)
278
- {
279
- var value = parseFloat(this.value);
280
- value = isNaN(value) ? 0.0 : value;
281
- value = Math.max(value, parseFloat($(this).attr("aria-valuemin")));
282
- value = Math.min(value, parseFloat($(this).attr("aria-valuemax")));
283
- if (value !== this.value) $(this).spinner("value", value);
284
- },
285
- });
286
+ .css("max-width", "4rem")
287
+ .spinner({
288
+ min: 0.1,
289
+ max: 1.0,
290
+ step: 0.1,
291
+ change: function (event, ui)
292
+ {
293
+ var value = parseFloat(this.value);
294
+ value = isNaN(value) ? 0.0 : value;
295
+ value = Math.max(value, parseFloat($(this).attr("aria-valuemin")));
296
+ value = Math.min(value, parseFloat($(this).attr("aria-valuemax")));
297
+ if (value !== this.value) $(this).spinner("value", value);
298
+ },
299
+ });
286
300
 
287
301
  $("#node-input-max_change_percent")
288
302
  .css("max-width", "4rem")
@@ -372,6 +386,10 @@
372
386
  <label for="node-input-valve_mode"><i class="fa fa-fire"></i> <span data-i18n="mixing-valve.ui.mode"></span></label>
373
387
  <input id="node-input-valve_mode" />
374
388
  </div>
389
+ <div class="form-row">
390
+ <label for="node-input-alarm_action"><i class="fa fa-exclamation-triangle"></i> <span data-i18n="mixing-valve.ui.alarm_on"></span></label>
391
+ <input id="node-input-alarm_action"/>
392
+ </div>
375
393
  <div class="form-row">
376
394
  <label for="node-input-precision" style="width: 250px;"><i class="fa fa-sliders"></i> <span data-i18n="mixing-valve.ui.precision"></span></label>
377
395
  <input id="node-input-precision" value="1.0" /> °C
@@ -33,11 +33,9 @@ module.exports = function (RED)
33
33
  setpoint: config.setpoint,
34
34
  off_mode: config.off_mode,
35
35
  valve_mode: config.valve_mode,
36
- precision: config.precision || 1,
37
- max_change_percent: config.max_change_percent || 2,
38
- max_change_temp_difference: config.max_change_temp_difference || 20,
39
- min_change_time: config.min_change_time || 0,
40
36
  last_position: null,
37
+ last_enabled_sended: null,
38
+ alarm_active: false
41
39
  }, smart_context.get(node.id));
42
40
 
43
41
  // Ensure correct types
@@ -45,10 +43,13 @@ module.exports = function (RED)
45
43
  node_settings.setpoint = parseFloat(node_settings.setpoint);
46
44
  if (isNaN(node_settings.setpoint) || !isFinite(node_settings.setpoint))
47
45
  node_settings.setpoint = 20;
48
- node_settings.precision = parseInt(node_settings.precision, 10);
49
- node_settings.max_change_percent = parseInt(node_settings.max_change_percent, 10);
50
- node_settings.max_change_temp_difference = parseInt(node_settings.max_change_temp_difference, 10);
51
- node_settings.min_change_time = parseInt(node_settings.min_change_time, 10);
46
+
47
+ // Remove old settings
48
+ delete node_settings.precision;
49
+ delete node_settings.max_change_percent;
50
+ delete node_settings.max_change_temp_difference;
51
+ delete node_settings.min_change_time;
52
+
52
53
 
53
54
  // ##################
54
55
  // # Dynamic config #
@@ -57,11 +58,17 @@ module.exports = function (RED)
57
58
  let time_sampling_s = config.time_sampling;
58
59
  let output_mode = config.output_mode || OUTPUT_MODE_OPEN_CLOSE;
59
60
  let force_position = null;
61
+ let alarm_action = config.alarm_action || "NOTHING"; // NOTHING | OPEN | CLOSE
60
62
  let min_temperature = null;
61
63
  let min_temperature_position = null;
62
64
  let max_temperature = null;
63
65
  let max_temperature_position = null;
64
66
  let temp_save_date = Date.now();
67
+ let precision = parseInt(config.precision || 1, 10);
68
+ let max_change_percent = parseInt(config.max_change_percent || 2, 10);
69
+ let max_change_temp_difference = parseInt(config.max_change_temp_difference || 20, 10);
70
+ let min_change_time = parseInt(config.min_change_time || 0, 10);
71
+
65
72
 
66
73
  // ##################
67
74
  // # Runtime values #
@@ -148,13 +155,16 @@ module.exports = function (RED)
148
155
 
149
156
  let real_topic = helper.getTopicName(msg.topic);
150
157
 
151
- if (real_topic == "set_state_inverted")
158
+ if (real_topic.startsWith("set_state"))
159
+ real_topic = real_topic.replace("set_state", "set");
160
+
161
+ if (real_topic == "set_inverted")
152
162
  {
153
- real_topic = "set_state";
163
+ real_topic = "set";
154
164
  msg.payload = !msg.payload;
155
165
  }
156
166
 
157
- if (real_topic == "set_state")
167
+ if (real_topic == "set")
158
168
  real_topic = (!!msg.payload) ? "enable" : "disable";
159
169
 
160
170
  switch (real_topic)
@@ -168,6 +178,10 @@ module.exports = function (RED)
168
178
  heating_mode: node_settings.valve_mode,
169
179
  current_temperature,
170
180
  output_mode,
181
+ precision,
182
+ max_change_percent,
183
+ max_change_temp_difference,
184
+ min_change_time,
171
185
  min_temperature,
172
186
  min_temperature_position,
173
187
  max_temperature,
@@ -179,11 +193,16 @@ module.exports = function (RED)
179
193
  case "enable":
180
194
  if (node_settings.enabled)
181
195
  {
182
- helpers.log(node, "Already enabled");
196
+ helper.log(node, "Already enabled");
183
197
  break;
184
198
  }
185
199
 
186
200
  node_settings.enabled = true;
201
+
202
+ // If in alarm mode, just save enabled state, but don't start changing
203
+ if (node_settings.alarm_active)
204
+ return;
205
+
187
206
  stopChanging();
188
207
 
189
208
  // Set the most probable position
@@ -230,6 +249,10 @@ module.exports = function (RED)
230
249
 
231
250
  node_settings.enabled = false;
232
251
 
252
+ // If in alarm mode, just save enabled state, but don't start changing
253
+ if (node_settings.alarm_active)
254
+ return;
255
+
233
256
  stopSampling();
234
257
  doOffMode();
235
258
  break;
@@ -304,6 +327,45 @@ module.exports = function (RED)
304
327
  calibrate();
305
328
  break;
306
329
 
330
+ case "alarm":
331
+ // Make sure it is bool
332
+ msg.payload = !!msg.payload;
333
+
334
+ // No alarm change -> nothing to do
335
+ if (node_settings.alarm_active == msg.payload)
336
+ break;
337
+
338
+ node_settings.alarm_active = msg.payload;
339
+ if (node_settings.alarm_active)
340
+ {
341
+ switch (alarm_action)
342
+ {
343
+ case "OPEN":
344
+ force_position = 100;;
345
+ break;
346
+
347
+ case "CLOSE":
348
+ force_position = 0;
349
+ break;
350
+
351
+ default:
352
+ case "NOTHING":
353
+ // Don't use alarm mode
354
+ node_settings.alarm_active = false;
355
+ return;
356
+ }
357
+ }
358
+ else
359
+ {
360
+ force_position = null;
361
+ if (!node_settings.enabled)
362
+ doOffMode();
363
+ }
364
+
365
+ stopSampling();
366
+ startSampling();
367
+ break;
368
+
307
369
  default:
308
370
  helper.warn(this, "Invalid topic: " + real_topic);
309
371
  return;
@@ -314,7 +376,7 @@ module.exports = function (RED)
314
376
 
315
377
  let startSampling = () =>
316
378
  {
317
- if (!node_settings.enabled)
379
+ if (!node_settings.enabled && !node_settings.alarm_active)
318
380
  {
319
381
  helper.log(node, "Node is disabled, cannot start sampling");
320
382
  return;
@@ -346,7 +408,7 @@ module.exports = function (RED)
346
408
  helper.log(node, "Force position to " + force_position.toFixed(1) + "%");
347
409
 
348
410
  // Under precision % difference => do nothing
349
- if (Math.abs(node_settings.last_position - force_position) <= node_settings.precision)
411
+ if (Math.abs(node_settings.last_position - force_position) <= precision)
350
412
  {
351
413
  helper.log(node, "No Force position needed");
352
414
  force_position = null;
@@ -365,6 +427,7 @@ module.exports = function (RED)
365
427
  case OUTPUT_MODE_PERCENTAGE:
366
428
  // Output mode percentage
367
429
  node_settings.last_position = force_position;
430
+ force_position = null;
368
431
  node.send({ payload: node_settings.last_position });
369
432
  smart_context.set(node.id, node_settings);
370
433
  setStatus();
@@ -408,20 +471,23 @@ module.exports = function (RED)
408
471
 
409
472
  // +/- 1°C => already good enough, do nothing
410
473
  let temp_diff = Math.abs(current_temperature - node_settings.setpoint);
411
- if (temp_diff < node_settings.precision)
474
+ if (temp_diff < precision)
412
475
  {
413
- // Found a good position for the current setpoint
414
- // Update min/max temperature
415
- if (min_temperature === null || current_temperature < min_temperature)
476
+ if (!node_settings.alarm_active)
416
477
  {
417
- min_temperature = current_temperature;
418
- min_temperature_position = node_settings.last_position;
419
- }
478
+ // Found a good position for the current setpoint
479
+ // Update min/max temperature
480
+ if (min_temperature === null || current_temperature < min_temperature)
481
+ {
482
+ min_temperature = current_temperature;
483
+ min_temperature_position = node_settings.last_position;
484
+ }
420
485
 
421
- if (max_temperature === null || current_temperature > max_temperature)
422
- {
423
- max_temperature = current_temperature;
424
- max_temperature_position = node_settings.last_position;
486
+ if (max_temperature === null || current_temperature > max_temperature)
487
+ {
488
+ max_temperature = current_temperature;
489
+ max_temperature_position = node_settings.last_position;
490
+ }
425
491
  }
426
492
  return;
427
493
  }
@@ -429,11 +495,11 @@ module.exports = function (RED)
429
495
  // 0 °C diff => 0% change
430
496
  // for max_change_temp_difference (default: 20 °C) diff => max_change_percent (default: 2%) change
431
497
  let change_percentage = helper.scale(
432
- Math.min(temp_diff, node_settings.max_change_temp_difference),
498
+ Math.min(temp_diff, max_change_temp_difference),
433
499
  0,
434
- node_settings.max_change_temp_difference,
500
+ max_change_temp_difference,
435
501
  0,
436
- node_settings.max_change_percent
502
+ max_change_percent
437
503
  );
438
504
 
439
505
  // calculate direction
@@ -473,8 +539,8 @@ module.exports = function (RED)
473
539
  // Change time in ms
474
540
  let moving_time = (time_total_s * 1000 / 100) * change_percentage;
475
541
 
476
- if (moving_time < node_settings.min_change_time)
477
- moving_time = node_settings.min_change_time;
542
+ if (moving_time < min_change_time)
543
+ moving_time = min_change_time;
478
544
 
479
545
  // start moving
480
546
  startChanging(adjustAction, moving_time);
@@ -651,9 +717,9 @@ module.exports = function (RED)
651
717
  if (calibration_timeout !== null)
652
718
  node.status({ fill: "yellow", shape: "ring", text: helper.getCurrentTimeForStatus() + ": In calibration" });
653
719
  else if (changing_timeout != null)
654
- node.status({ fill: node_settings.enabled ? "green" : "red", shape: "ring", text: helper.getCurrentTimeForStatus() + ": " + (node_settings.valve_mode == "HEATING" ? "🔥" : "❄️") + " " + (adjusting == ADJUST_OPEN ? "Opening" : "Closing") + ", Set: " + helper.toFixed(node_settings.setpoint, 1) + "°C, Cur: " + helper.toFixed(current_temperature, 1) + "°C, Pos: " + helper.toFixed(node_settings.last_position, 1) + "%" });
720
+ node.status({ fill: node_settings.enabled ? "green" : "red", shape: "ring", text: helper.getCurrentTimeForStatus() + ": " + (node_settings.alarm_active ? "ALARM - " : "") + (node_settings.valve_mode == "HEATING" ? "🔥" : "❄️") + " " + (adjusting == ADJUST_OPEN ? "Opening" : "Closing") + ", Set: " + helper.toFixed(node_settings.setpoint, 1) + "°C, Cur: " + helper.toFixed(current_temperature, 1) + "°C, Pos: " + helper.toFixed(node_settings.last_position, 1) + "%" });
655
721
  else
656
- node.status({ fill: node_settings.enabled ? "green" : "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": " + (node_settings.valve_mode == "HEATING" ? "🔥" : "❄️") + " Set: " + helper.toFixed(node_settings.setpoint, 1) + "°C, Cur: " + helper.toFixed(current_temperature, 1) + "°C, Pos: " + helper.toFixed(node_settings.last_position, 1) + "%" });
722
+ node.status({ fill: node_settings.enabled ? "green" : "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": " + (node_settings.alarm_active ? "ALARM - " : "") + (node_settings.valve_mode == "HEATING" ? "🔥" : "❄️") + " Set: " + helper.toFixed(node_settings.setpoint, 1) + "°C, Cur: " + helper.toFixed(current_temperature, 1) + "°C, Pos: " + helper.toFixed(node_settings.last_position, 1) + "%" });
657
723
  }
658
724
 
659
725
  /**
@@ -685,10 +751,30 @@ module.exports = function (RED)
685
751
  node_settings.last_position = 0;
686
752
  }
687
753
  }
754
+ else if (node_settings.alarm_active)
755
+ {
756
+ switch (alarm_action)
757
+ {
758
+ case "OPEN":
759
+ force_position = 100;;
760
+ break;
761
+
762
+ case "CLOSE":
763
+ force_position = 0;
764
+ break;
765
+
766
+ default:
767
+ case "NOTHING":
768
+ // Don't use alarm mode
769
+ node_settings.alarm_active = false;
770
+ return;
771
+ }
772
+
773
+ startSampling();
774
+ }
688
775
  else if (node_settings.enabled)
689
776
  {
690
777
  startSampling();
691
- node.send([null, null, { payload: helper.toFixed(node_settings.last_position, 1) }]);
692
778
  }
693
779
 
694
780
  setStatus();
@@ -1,5 +1,5 @@
1
1
  {
2
- "modeSelector": {
2
+ "mode-selector": {
3
3
  "ui": {
4
4
  "name": "Name",
5
5
  "update_only_changed_outputs": "Nur an geänderte Ausgänge senden",
@@ -1,5 +1,5 @@
1
1
  {
2
- "modeSelector": {
2
+ "mode-selector": {
3
3
  "ui": {
4
4
  "name": "Name",
5
5
  "update_only_changed_outputs": "Only send to changed outputs",
@@ -81,7 +81,7 @@
81
81
  .appendTo(row);
82
82
 
83
83
  // Output name
84
- var modeName = $("<input/>", { class: "node-input-prop-name", placeholder: node._("modeSelector.ui.name"), type: "text" })
84
+ var modeName = $("<input/>", { class: "node-input-prop-name", placeholder: node._("mode-selector.ui.name"), type: "text" })
85
85
  .css("width", "90%")
86
86
  .appendTo(row);
87
87
 
@@ -115,7 +115,7 @@
115
115
  tabs.addTab({
116
116
  id: "modes-tab-outputs",
117
117
  iconClass: "fa fa-list-ol",
118
- label: node._("modeSelector.ui.modes")
118
+ label: node._("mode-selector.ui.modes")
119
119
  });
120
120
  },
121
121
  oneditsave: function ()
@@ -135,12 +135,12 @@
135
135
 
136
136
  <script type="text/html" data-template-name="smart_mode-selector">
137
137
  <div class="form-row">
138
- <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="modeSelector.ui.name"></span></label>
139
- <input type="text" id="node-input-name" data-i18n="[placeholder]modeSelector.ui.name" />
138
+ <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="mode-selector.ui.name"></span></label>
139
+ <input type="text" id="node-input-name" data-i18n="[placeholder]mode-selector.ui.name" />
140
140
  </div>
141
141
  <div class="form-row">
142
142
  <input type="checkbox" id="node-input-update_only_changed_outputs" style="width: 20px;" />
143
- <label for="node-input-update_only_changed_outputs" style="width: calc(100% - 30px);" data-i18n="modeSelector.ui.update_only_changed_outputs"></label>
143
+ <label for="node-input-update_only_changed_outputs" style="width: calc(100% - 30px);" data-i18n="mode-selector.ui.update_only_changed_outputs"></label>
144
144
  </div>
145
145
 
146
146
  <div id="mode-selector-modes">
@@ -154,10 +154,10 @@
154
154
  </div>
155
155
  </div>
156
156
  <hr/>
157
- <h4 style="margin: 0.5rem 0;" data-i18n="modeSelector.ui.system_start"></h4>
157
+ <h4 style="margin: 0.5rem 0;" data-i18n="mode-selector.ui.system_start"></h4>
158
158
  <div class="form-row">
159
159
  <input type="checkbox" id="node-input-resend_on_start" style="width: 20px;" />
160
- <label for="node-input-resend_on_start" style="width: calc(100% - 30px);" data-i18n="modeSelector.ui.send_after_start"></label>
160
+ <label for="node-input-resend_on_start" style="width: calc(100% - 30px);" data-i18n="mode-selector.ui.send_after_start"></label>
161
161
  </div>
162
162
 
163
163
  </script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smart-nodes",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Controls light, shutters and more. Includes common used logic and statistic nodes to control your home.",
5
5
  "keywords": [
6
6
  "node-red",
@@ -25,11 +25,11 @@
25
25
  <td>Deaktiviert den Scheduler.</td>
26
26
  </tr>
27
27
  <tr>
28
- <td><code>set_state</code></td>
28
+ <td><code>set</code> oder <code>set_state</code></td>
29
29
  <td>Aktiviert den Scheduler, wenn <code>msg.payload = true</code> oder deaktiviert den Scheduler, wenn <code>msg.payload = false</code>.</td>
30
30
  </tr>
31
31
  <tr>
32
- <td><code>set_state_inverted</code></td>
32
+ <td><code>set_inverted</code> oder <code>set_state_inverted</code></td>
33
33
  <td>Aktiviert den Scheduler, wenn <code>msg.payload = false</code> oder deaktiviert den Scheduler, wenn <code>msg.payload = true</code>.</td>
34
34
  </tr>
35
35
  </tbody>
@@ -25,11 +25,11 @@
25
25
  <td>Disables the scheduler.</td>
26
26
  </tr>
27
27
  <tr>
28
- <td><code>set_state</code></td>
28
+ <td><code>set</code> or <code>set_state</code></td>
29
29
  <td>Enables the scheduler if <code>msg.payload = true</code> or disables the scheduler if <code>msg.payload = false</code>.</td>
30
30
  </tr>
31
31
  <tr>
32
- <td><code>set_state_inverted</code></td>
32
+ <td><code>set_inverted</code> oder <code>set_state_inverted</code></td>
33
33
  <td>Enables the scheduler if <code>msg.payload = false</code> or disables the scheduler if <code>msg.payload = true</code>.</td>
34
34
  </tr>
35
35
  </tbody>
@@ -102,13 +102,16 @@ module.exports = function (RED)
102
102
  {
103
103
  let real_topic = helper.getTopicName(msg.topic);
104
104
 
105
- if (real_topic == "set_state_inverted")
105
+ if (real_topic.startsWith("set_state"))
106
+ real_topic = real_topic.replace("set_state", "set");
107
+
108
+ if (real_topic == "set_inverted")
106
109
  {
107
- real_topic = "set_state";
110
+ real_topic = "set";
108
111
  msg.payload = !msg.payload;
109
112
  }
110
113
 
111
- if (real_topic == "set_state")
114
+ if (real_topic == "set")
112
115
  real_topic = (!!msg.payload) ? "enable" : "disable";
113
116
 
114
117
  switch (real_topic)
@@ -1,7 +1,7 @@
1
1
  <script type="text/html" data-help-name="smart_statistic">
2
2
  <p>Dieser Knoten berechnet das Minimum, Maximum, die Summe, die Differenz, den absoluten Wert, die absolute Differenz, den Durchschnitt sowie den gleitenden Mittelwert verschiedener Werte.</p>
3
3
  <p>Jeder Wert muss mit einem eigenen Topic gesendet werden. Kommt ein zweiter Wert mit dem gleichen Topic, wird der entsprechende Wert überschrieben.</p>
4
- <p>Im Falle von MIN, MAX und ABS wird das entsprechende Topic, welches mit den Werten kam, mit ausgegeben. Bei SUM, DIFF, AVG und MOV_AVG handelt es sich um kombinierte Ergebnisse, weshalb Topic hier immer nicht gesetzt ist.</p>
4
+ <p>Im Falle von MIN, MAX und ABS wird das entsprechende Topic, welches mit den Werten kam, mit ausgegeben. Bei SUM, DIFF, AVG und MOV_AVG handelt es sich um kombinierte Ergebnisse, weshalb das Topic hier immer nicht gesetzt ist.</p>
5
5
  <p>Für den absoluten Wert sowie den gleitenden Mittelwert spielt das Topic keine Rolle, jeder Wert der empfangen wird, wird für die Berechnung verwendet.</p>
6
6
  <p>
7
7
  <b>Hinweis:</b> Smart Nodes verwenden Topics im Format <code>name#nummer</code>, damit können verschiedene Smart Nodes mit dem gleichen Topic angesteuert werden.<br/>