smart-nodes 0.3.37 → 0.4.0

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.
Files changed (109) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +35 -17
  3. package/central/central.html +26 -12
  4. package/central/central.js +84 -26
  5. package/central/locales/de-DE/central.json +1 -4
  6. package/central/locales/en-US/central.json +0 -3
  7. package/compare/compare.html +40 -24
  8. package/compare/compare.js +69 -29
  9. package/compare/locales/de-DE/compare.json +5 -7
  10. package/compare/locales/en-US/compare.json +18 -8
  11. package/counter/counter.html +64 -17
  12. package/counter/counter.js +43 -20
  13. package/counter/locales/de-DE/counter.json +6 -9
  14. package/counter/locales/en-US/counter.json +12 -16
  15. package/delay/delay.html +18 -88
  16. package/delay/delay.js +63 -20
  17. package/delay/locales/de-DE/delay.html +71 -0
  18. package/delay/locales/de-DE/delay.json +19 -0
  19. package/delay/locales/en-US/delay.html +76 -0
  20. package/delay/locales/en-US/delay.json +19 -0
  21. package/forwarder/forwarder.html +11 -42
  22. package/forwarder/forwarder.js +59 -18
  23. package/forwarder/locales/de-DE/forwarder.html +32 -0
  24. package/forwarder/locales/de-DE/forwarder.json +15 -0
  25. package/forwarder/locales/en-US/forwarder.html +32 -0
  26. package/forwarder/locales/en-US/forwarder.json +15 -0
  27. package/heating-curve/heating-curve.html +10 -51
  28. package/heating-curve/heating-curve.js +38 -13
  29. package/heating-curve/locales/de-DE/heating-curve.html +38 -0
  30. package/heating-curve/locales/de-DE/heating-curve.json +12 -0
  31. package/heating-curve/locales/en-US/heating-curve.html +38 -0
  32. package/heating-curve/locales/en-US/heating-curve.json +12 -0
  33. package/hysteresis/hysteresis.html +43 -65
  34. package/hysteresis/hysteresis.js +94 -68
  35. package/hysteresis/locales/de-DE/hysteresis.html +36 -0
  36. package/hysteresis/locales/de-DE/hysteresis.json +27 -0
  37. package/hysteresis/locales/en-US/hysteresis.html +36 -0
  38. package/hysteresis/locales/en-US/hysteresis.json +27 -0
  39. package/{light-control/light-control.html → light/light.html} +34 -144
  40. package/{light-control/light-control.js → light/light.js} +151 -32
  41. package/light/locales/de-DE/light.html +149 -0
  42. package/light/locales/de-DE/light.json +24 -0
  43. package/light/locales/en-US/light.html +148 -0
  44. package/light/locales/en-US/light.json +24 -0
  45. package/logic/locales/de-DE/logic.html +12 -0
  46. package/logic/locales/de-DE/logic.json +26 -0
  47. package/logic/locales/en-US/logic.html +12 -0
  48. package/logic/locales/en-US/logic.json +26 -0
  49. package/logic/logic.html +27 -40
  50. package/logic/logic.js +63 -29
  51. package/long-press/locales/de-DE/long-press.html +5 -0
  52. package/long-press/locales/de-DE/long-press.json +13 -0
  53. package/long-press/locales/en-US/long-press.html +5 -0
  54. package/long-press/locales/en-US/long-press.json +13 -0
  55. package/{long-press-control/long-press-control.html → long-press/long-press.html} +10 -14
  56. package/long-press/long-press.js +163 -0
  57. package/mixing-valve/locales/de-DE/mixing-valve.html +65 -0
  58. package/mixing-valve/locales/de-DE/mixing-valve.json +19 -0
  59. package/mixing-valve/locales/en-US/mixing-valve.html +66 -0
  60. package/mixing-valve/locales/en-US/mixing-valve.json +19 -0
  61. package/mixing-valve/mixing-valve.html +15 -79
  62. package/mixing-valve/mixing-valve.js +87 -61
  63. package/multi-press/locales/de-DE/multi-press.html +5 -0
  64. package/multi-press/locales/de-DE/multi-press.json +12 -0
  65. package/multi-press/locales/en-US/multi-press.html +5 -0
  66. package/multi-press/locales/en-US/multi-press.json +12 -0
  67. package/{multi-press-control/multi-press-control.html → multi-press/multi-press.html} +9 -13
  68. package/{multi-press-control/multi-press-control.js → multi-press/multi-press.js} +53 -5
  69. package/package.json +7 -7
  70. package/persistence.js +1 -0
  71. package/scene/locales/de-DE/scene.html +105 -0
  72. package/scene/locales/de-DE/scene.json +21 -0
  73. package/scene/locales/en-US/scene.html +107 -0
  74. package/scene/locales/en-US/scene.json +20 -0
  75. package/{scene-control/scene-control.html → scene/scene.html} +18 -121
  76. package/{scene-control/scene-control.js → scene/scene.js} +76 -26
  77. package/scheduler/locales/de-DE/scheduler.html +30 -0
  78. package/scheduler/locales/de-DE/scheduler.json +21 -0
  79. package/scheduler/locales/en-US/scheduler.html +30 -0
  80. package/scheduler/locales/en-US/scheduler.json +21 -0
  81. package/scheduler/scheduler.html +34 -64
  82. package/scheduler/scheduler.js +85 -53
  83. package/shutter/locales/de-DE/shutter.html +127 -0
  84. package/shutter/locales/de-DE/shutter.json +11 -0
  85. package/shutter/locales/en-US/shutter.html +133 -0
  86. package/shutter/locales/en-US/shutter.json +11 -0
  87. package/{shutter-control/shutter-control.html → shutter/shutter.html} +7 -133
  88. package/{shutter-control/shutter-control.js → shutter/shutter.js} +116 -56
  89. package/shutter-complex/locales/de-DE/shutter-complex.html +120 -0
  90. package/shutter-complex/locales/de-DE/shutter-complex.json +20 -0
  91. package/shutter-complex/locales/en-US/shutter-complex.html +120 -0
  92. package/shutter-complex/locales/en-US/shutter-complex.json +20 -0
  93. package/{shutter-complex-control/shutter-complex-control.html → shutter-complex/shutter-complex.html} +30 -133
  94. package/shutter-complex/shutter-complex.js +578 -0
  95. package/smart_helper.js +52 -9
  96. package/statistic/locales/de-DE/statistic.html +10 -0
  97. package/statistic/locales/de-DE/statistic.json +29 -0
  98. package/statistic/locales/en-US/statistic.html +10 -0
  99. package/statistic/locales/en-US/statistic.json +29 -0
  100. package/statistic/statistic.html +32 -36
  101. package/statistic/statistic.js +57 -28
  102. package/text-exec/locales/de-DE/text-exec.html +18 -0
  103. package/text-exec/locales/de-DE/text-exec.json +7 -0
  104. package/text-exec/locales/en-US/text-exec.html +18 -0
  105. package/text-exec/locales/en-US/text-exec.json +7 -0
  106. package/text-exec/text-exec.html +9 -25
  107. package/text-exec/text-exec.js +43 -2
  108. package/long-press-control/long-press-control.js +0 -76
  109. package/shutter-complex-control/shutter-complex-control.js +0 -442
@@ -142,6 +142,7 @@
142
142
  max_time_on: { value: "0" },
143
143
  max_time_on_unit: { value: "s" },
144
144
  alarm_action: { value: 'NOTHING' }, // NOTHING | ON | OFF
145
+ alarm_off_action: { value: 'NOTHING' }, // NOTHING | ON | OFF | LAST | LAST_SENDED
145
146
  links: { value: [], type: "smart_central-control[]" }
146
147
  },
147
148
  inputs: 1,
@@ -154,22 +155,10 @@
154
155
  oneditprepare: function ()
155
156
  {
156
157
  let node = this;
158
+
157
159
  onEditPrepare(this, ["smart_central-control"]);
158
160
  initTreeList(node, ["smart_central-control"]);
159
161
 
160
- $("#node-input-icon")
161
- .css("max-width", "10rem")
162
- .typedInput({
163
- types: [{
164
- value: "light",
165
- default: "light",
166
- options: [
167
- { value: "light", label: "Licht" },
168
- { value: "outlet", label: "Steckdose" }
169
- ],
170
- }],
171
- });
172
-
173
162
  $("#node-input-max_time_on")
174
163
  .spinner({
175
164
  min: 0,
@@ -190,10 +179,10 @@
190
179
  value: "max_time_on_unit",
191
180
  default: "s",
192
181
  options: [
193
- { value: "ms", label: "Millisekunden" },
194
- { value: "s", label: "Sekunden" },
195
- { value: "min", label: "Minuten" },
196
- { value: "h", label: "Stunden" },
182
+ { value: "ms", label: node._("light.ui.milliseconds") },
183
+ { value: "s", label: node._("light.ui.seconds") },
184
+ { value: "min", label: node._("light.ui.minutes") },
185
+ { value: "h", label: node._("light.ui.hours") },
197
186
  ],
198
187
  }],
199
188
  });
@@ -203,9 +192,23 @@
203
192
  value: "alarm_action",
204
193
  default: "NOTHING",
205
194
  options: [
206
- { value: "NOTHING", label: "Keine Aktion" },
207
- { value: "ON", label: "Einschalten" },
208
- { value: "OFF", label: "Ausschalten" }
195
+ { value: "NOTHING", label: node._("light.ui.no_action") },
196
+ { value: "ON", label: node._("light.ui.turn_on") },
197
+ { value: "OFF", label: node._("light.ui.turn_off") }
198
+ ],
199
+ }],
200
+ });
201
+
202
+ $("#node-input-alarm_off_action").typedInput({
203
+ types: [{
204
+ value: "alarm_off_action",
205
+ default: "NOTHING",
206
+ options: [
207
+ { value: "NOTHING", label: node._("light.ui.no_action") },
208
+ { value: "ON", label: node._("light.ui.turn_on") },
209
+ { value: "OFF", label: node._("light.ui.turn_off") },
210
+ { value: "LAST", label: node._("light.ui.last_state") },
211
+ { value: "LAST_SENDED", label: node._("light.ui.last_sended_state") }
209
212
  ],
210
213
  }],
211
214
  });
@@ -221,140 +224,27 @@
221
224
 
222
225
  <script type="text/html" data-template-name="smart_light-control">
223
226
  <div class="form-row">
224
- <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
225
- <input type="text" id="node-input-name" placeholder="Name" />
227
+ <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="light.ui.name"></span></label>
228
+ <input type="text" id="node-input-name" data-i18n="[placeholder]light.ui.name" />
226
229
  </div>
227
230
  <div class="form-row">
228
- <label for="node-input-exec_text_names"><i class="fa fa-comments-o"></i> Text</label>
231
+ <label for="node-input-exec_text_names"><i class="fa fa-comments-o"></i> <span data-i18n="light.ui.text"></span></label>
229
232
  <input id="node-input-exec_text_names" type="text" />
230
- <div style="max-width: 450px;">Diese Node kann über die eingegebenen Wörter gesteuert werden. Mehrere Wörter werden durch ein Komma getrennt.</div>
233
+ <div style="max-width: 450px;" data-i18n="light.ui.controlled_by_words"></div>
231
234
  </div>
232
235
  <div class="form-row">
233
- <label for="node-input-max_time_on"><i class="fa fa-clock-o"></i> Zeit Ein</label>
236
+ <label for="node-input-max_time_on"><i class="fa fa-clock-o"></i> <span data-i18n="light.ui.time_on"></span></label>
234
237
  <input id="node-input-max_time_on" value="0" />
235
238
  <input id="node-input-max_time_on_unit" />
236
239
  </div>
237
240
  <div class="form-row">
238
- <label for="node-input-alarm_action"><i class="fa fa-exclamation-triangle"></i> Alarm Aktion</label>
241
+ <label for="node-input-alarm_action"><i class="fa fa-exclamation-triangle"></i> <span data-i18n="light.ui.alarm_on"></span></label>
239
242
  <input id="node-input-alarm_action"/>
240
243
  </div>
241
- <span><i class="fa fa-link"></i> Dieser Baustein wird von folgenden Zentralbausteinen gesteuert:</span>
244
+ <div class="form-row">
245
+ <label for="node-input-alarm_off_action"><i class="fa fa-exclamation-triangle"></i> <span data-i18n="light.ui.alarm_off"></span></label>
246
+ <input id="node-input-alarm_off_action"/>
247
+ </div>
248
+ <span><i class="fa fa-link"></i> <span data-i18n="light.ui.controlled_by_central"></span></span>
242
249
  <div class="form-row node-input-link-row node-input-link-rows"></div>
243
- </script>
244
-
245
- <script type="text/html" data-help-name="smart_light-control">
246
- <p>
247
- Diese Node steuert einen Ausgang. Dies kann ein Licht, eine Steckdose oder ähnliches sein.
248
- Als Ausgang wird immer <code>msg.payload = true</code> oder <code>msg.payload = false</code> gesendet um den Ausgang ein-, bzw. auszuschalten.
249
- </p>
250
- <p>
251
- <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/>
252
- Diese Node verwendet nur den Teil <code>name</code>. <code>#</code> und <code>nummer</code> sind dabei optional.
253
- </p>
254
- <p>
255
- Folgende topics werden akzeptiert:
256
- <table>
257
- <thead>
258
- <tr>
259
- <th>Topic</th>
260
- <th>Beschreibung</th>
261
- <th>msg.payload == false wird ignoriert</th>
262
- </tr>
263
- </thead>
264
- <tbody>
265
- <tr>
266
- <td><code>status</code></td>
267
- <td>
268
- Gibt über <code>msg.payload = true</code> oder <code>msg.payload = false</code> den aktuellen Status des Ausgangs an.<br/>
269
- Bei einem Wechsel von ausgeschaltet nach eingeschaltet wird die Zeitmessung für die hinterlegte, bzw. mitgesendete Zeit gestartet, sofern vorhanden.
270
- </td>
271
- <td>Nein</td>
272
- </tr>
273
- <tr>
274
- <td><code>on</code></td>
275
- <td>Schaltet den Ausgang ein und startet die Zeitmessung für die hinterlegte, bzw. mitgesendete Zeit gestartet, sofern vorhanden.</td>
276
- <td>Ja</td>
277
- </tr>
278
- <tr>
279
- <td><code>off</code></td>
280
- <td>Schaltet den Ausgang aus.</td>
281
- <td>Ja</td>
282
- </tr>
283
- <tr>
284
- <td><code>set</code></td>
285
- <td>
286
- Schaltet den Ausgang bei <code>msg.payload = true</code> ein und bei <code>msg.payload = false</code> aus.<br/>
287
- Bei einem Wechsel von ausgeschaltet nach eingeschaltet wird die Zeitmessung für die hinterlegte, bzw. mitgesendete Zeit gestartet, sofern vorhanden.
288
- </td>
289
- <td>Nein</td>
290
- </tr>
291
- <tr>
292
- <td><code>set_permanent</code></td>
293
- <td>
294
- Schaltet den Ausgang bei <code>msg.payload = true</code> dauerhaft ein und bei <code>msg.payload = false</code> aus.<br/>
295
- Es wird dabei keine Zeitmessung gestartet.
296
- </td>
297
- <td>Nein</td>
298
- </tr>
299
- <tr>
300
- <td><code>motion</code></td>
301
- <td>
302
- Schaltet den Ausgang bei <code>msg.payload = true</code> ein ohne eine Zeitmessung.<br/>
303
- Bei <code>msg.payload = false</code> wird die Zeitmessung für die hinterlegte, bzw. mitgesendete Zeit gestartet, sofern vorhanden.<br/>
304
- Ist keine Zeit angegeben oder hinterlegt, schaltet sich der Ausgang sofort aus.
305
- </td>
306
- <td>Nein</td>
307
- </tr>
308
- <tr>
309
- <td><code>alarm</code></td>
310
- <td>Setzt den aktuellen Alarmzustand auf den Wert von <code>msg.payload</code> und löst die entsprechende Aktion aus.</td>
311
- <td>Nein</td>
312
- </tr>
313
- <tr>
314
- <td><code>toggle</code> (default)</td>
315
- <td>
316
- Schaltet den Ausgang abwechselnd ein und aus.<br/>
317
- Bei einem Wechsel von ausgeschaltet nach eingeschaltet wird die Zeitmessung für die hinterlegte, bzw. mitgesendete Zeit gestartet, sofern vorhanden.
318
- </td>
319
- <td>Ja</td>
320
- </tr>
321
- </tbody>
322
- </table>
323
- </p>
324
- <p>
325
- Diese Node hat eine einstellbare Maximallaufzeit, bevor der Ausgang automatisch wieder ausgeschalten wird.
326
- Diese Zeitmessung wird wie in der Tabelle oben verwendet.
327
- Die eingestellte Zeit kann gezielt überschrieben werden.
328
- Beispiel: <code>msg = { "topic": "on", "time_on": 5000 }</code> oder <code>msg = { "topic": "on", "time_on": "5s" }</code><br/>
329
- Diese Nachricht schaltet das Licht für 5000 Millisekunden / 5 Sekunden an und anschließend wieder aus.
330
- Die nächste Nachricht ohne <code>time_on</code> Angabe verwendet wieder die voreingestellte Zeit.
331
- Ist die Zeit auf 0 eingestellt, wird das Licht <b>nicht</b> automatisch ausgeschalten.<br/>
332
- Als Einheit für die Zeit können folgende Werte verwendet werden:
333
- <table>
334
- <thead>
335
- <tr>
336
- <th>Einheit</th>
337
- <th>Beschreibung</th>
338
- </tr>
339
- </thead>
340
- <tbody>
341
- <tr>
342
- <td><code>ms</code> (default)</td>
343
- <td>Millisekunden</td>
344
- </tr>
345
- <tr>
346
- <td><code>s</code> oder <code>sec</code></td>
347
- <td>Sekunden</td>
348
- </tr>
349
- <tr>
350
- <td><code>m</code> oder <code>min</code></td>
351
- <td>Mintun.</td>
352
- </tr>
353
- <tr>
354
- <td><code>h</code></td>
355
- <td>Stunden</td>
356
- </tr>
357
- </tbody>
358
- </table>
359
- </p>
360
250
  </script>
@@ -7,32 +7,69 @@ module.exports = function (RED)
7
7
  const node = this;
8
8
  RED.nodes.createNode(node, config);
9
9
 
10
+ // ###################
11
+ // # Class constants #
12
+ // ###################
13
+
14
+
15
+ // #######################
16
+ // # Global help objects #
17
+ // #######################
10
18
  const smart_context = require("../persistence.js")(RED);
11
19
  const helper = require("../smart_helper.js");
12
20
 
13
- // used from text-exec node
21
+
22
+ // ############################
23
+ // # Used from text-exec node #
24
+ // ############################
14
25
  if (typeof config.exec_text_names == "string")
15
26
  node.exec_text_names = config.exec_text_names.split(",").map(n => n.trim().toLowerCase());
16
27
  else
17
28
  node.exec_text_names = [];
18
29
 
19
- // persistent values
20
- var node_settings = Object.assign({}, {
30
+
31
+ // #####################
32
+ // # persistent values #
33
+ // #####################
34
+ var node_settings = helper.cloneObject({
21
35
  last_value: false,
36
+ last_value_before_alarm: false,
37
+ last_value_sended: false,
38
+ alarm_active: false,
22
39
  }, smart_context.get(node.id));
23
40
 
24
- // dynamic config
41
+
42
+ // ##################
43
+ // # Dynamic config #
44
+ // ##################
25
45
  let max_time_on = helper.getTimeInMs(config.max_time_on, config.max_time_on_unit);
26
46
  let alarm_action = config.alarm_action || "NOTHING";
47
+ let alarm_off_action = config.alarm_off_action || "NOTHING";
48
+
49
+ // ##################
50
+ // # Runtime values #
51
+ // ##################
27
52
 
28
- // runtime values
29
- let max_time_on_timeout = null;
53
+ // Here the setTimeout return value is stored to turn off the light.
54
+ // That means if it is null, the light will not be turned off automatically.
55
+ let timeout = null;
56
+
57
+ // If isPermanent is true, then a default on time value is ignored
58
+ // Also if the motion sensor turns off, no timeout is started.
30
59
  let isPermanent = false;
60
+
61
+ // If this is on, a motion sensor has detected a move, so the on time value is ignored.
62
+ // The timeout starts only if the motion sensor goes off.
31
63
  let isMotion = false;
64
+
65
+ // Here the date is stored, when the light should go off.
66
+ // This is used to calculate the node status.
32
67
  let timeout_end_date = null;
33
- let alarm_active = false;
34
68
 
35
- // central handling
69
+
70
+ // #########################
71
+ // # Central node handling #
72
+ // #########################
36
73
  var event = "node:" + node.id;
37
74
  var handler = function (msg)
38
75
  {
@@ -41,6 +78,9 @@ module.exports = function (RED)
41
78
  RED.events.on(event, handler);
42
79
 
43
80
 
81
+ // ###############
82
+ // # Node events #
83
+ // ###############
44
84
  node.on("input", function (msg)
45
85
  {
46
86
  handleTopic(msg);
@@ -55,17 +95,26 @@ module.exports = function (RED)
55
95
  RED.events.off(event, handler);
56
96
  });
57
97
 
98
+
99
+ // #####################
100
+ // # Private functions #
101
+ // #####################
102
+
103
+ // This is the main function which handles all topics that was received.
58
104
  let handleTopic = msg =>
59
105
  {
60
106
  let doRestartTimer = true;
107
+ let real_topic = helper.getTopicName(msg.topic);
61
108
 
62
- switch (helper.getTopicName(msg.topic))
109
+ switch (real_topic)
63
110
  {
64
111
  case "status":
65
112
  // Make sure it is bool
66
113
  msg.payload = !!msg.payload;
67
114
 
68
- if (node_settings.last_value == msg.payload && max_time_on_timeout != null)
115
+ // Output is already in the state of the status value and the timeout is running.
116
+ // No need to restart the timeout.
117
+ if (node_settings.last_value == msg.payload && timeout != null)
69
118
  doRestartTimer = false;
70
119
 
71
120
  node_settings.last_value = msg.payload;
@@ -77,6 +126,7 @@ module.exports = function (RED)
77
126
  return;
78
127
 
79
128
  node_settings.last_value = false;
129
+ node_settings.last_value_sended = node_settings.last_value;
80
130
  break;
81
131
 
82
132
  case "on":
@@ -85,19 +135,24 @@ module.exports = function (RED)
85
135
  return;
86
136
 
87
137
  node_settings.last_value = true;
138
+ node_settings.last_value_sended = node_settings.last_value;
88
139
  break;
89
140
 
90
141
  case "set":
91
142
  // Make sure it is bool
92
143
  msg.payload = !!msg.payload;
144
+
93
145
  node_settings.last_value = msg.payload;
146
+ node_settings.last_value_sended = node_settings.last_value;
94
147
  break;
95
148
 
96
149
  case "set_permanent":
97
150
  // Make sure it is bool
98
151
  msg.payload = !!msg.payload;
99
- node_settings.last_value = msg.payload;
100
152
  isPermanent = msg.payload;
153
+
154
+ node_settings.last_value = msg.payload;
155
+ node_settings.last_value_sended = node_settings.last_value;
101
156
  break;
102
157
 
103
158
  case "motion":
@@ -119,21 +174,67 @@ module.exports = function (RED)
119
174
  {
120
175
  node_settings.last_value = true;
121
176
  }
177
+ node_settings.last_value_sended = node_settings.last_value;
178
+ break;
179
+
180
+ case "toggle":
181
+ // If button is released, don't handle this message
182
+ if (msg.payload === false)
183
+ return;
184
+
185
+ node_settings.last_value_sended = !node_settings.last_value;
186
+
187
+ if (!node_settings.alarm_active)
188
+ node_settings.last_value = !node_settings.last_value;
122
189
  break;
123
190
 
124
191
  case "alarm":
125
192
  // Make sure it is bool
126
193
  msg.payload = !!msg.payload;
127
- alarm_active = msg.payload;
194
+
195
+ // No alarm change, do nothing
196
+ if (node_settings.alarm_active == msg.payload)
197
+ return;
198
+
199
+ node_settings.alarm_active = msg.payload;
200
+ if (node_settings.alarm_active)
201
+ {
202
+ // Alarm turned on
203
+ node_settings.last_value_before_alarm = node_settings.last_value;
204
+ }
205
+ else
206
+ {
207
+ // Alarm turned off
208
+ switch (alarm_off_action)
209
+ {
210
+ case "NOTHING":
211
+ break;
212
+
213
+ case "ON":
214
+ node_settings.last_value = true;
215
+ break;
216
+
217
+ case "OFF":
218
+ node_settings.last_value = false;
219
+ break;
220
+
221
+ case "LAST":
222
+ node_settings.last_value = node_settings.last_value_before_alarm;
223
+ break;
224
+
225
+ case "LAST_SENDED":
226
+ node_settings.last_value = node_settings.last_value_sended;
227
+ break;
228
+ }
229
+ }
230
+
128
231
  break;
129
232
 
130
- case "toggle":
131
233
  default:
132
- // If button is released, don't handle this message
133
- if (msg.payload === false)
134
- return;
234
+ node_settings.last_value_sended = !node_settings.last_value;
135
235
 
136
- node_settings.last_value = !node_settings.last_value;
236
+ if (!node_settings.alarm_active)
237
+ node_settings.last_value = !node_settings.last_value;
137
238
  break;
138
239
  }
139
240
 
@@ -141,7 +242,7 @@ module.exports = function (RED)
141
242
  stopAutoOff();
142
243
 
143
244
  // Check alarm values
144
- if (alarm_active)
245
+ if (node_settings.alarm_active)
145
246
  {
146
247
  isPermanent = false;
147
248
 
@@ -151,14 +252,17 @@ module.exports = function (RED)
151
252
  node_settings.last_value = true;
152
253
  break;
153
254
 
154
- default:
155
255
  case "OFF":
156
256
  node_settings.last_value = false;
157
257
  break;
258
+
259
+ case "NOTHING":
260
+ default:
261
+ break;
158
262
  }
159
263
  }
160
264
 
161
- if (alarm_active || helper.getTopicName(msg.topic) != "status")
265
+ if (node_settings.alarm_active || helper.getTopicName(msg.topic) != "status")
162
266
  node.send({ payload: node_settings.last_value });
163
267
 
164
268
  // Output is on, now
@@ -168,17 +272,22 @@ module.exports = function (RED)
168
272
  notifyCentral(node_settings.last_value);
169
273
  }
170
274
 
275
+
276
+ /**
277
+ * This function sets a timeout to turn off the light after the defined time is over.
278
+ * @param {*} origTimeMs The on time
279
+ */
171
280
  let startAutoOffIfNeeded = origTimeMs =>
172
281
  {
173
282
  // No timer when alarm is active
174
- if (alarm_active)
283
+ if (node_settings.alarm_active)
175
284
  return;
176
285
 
177
286
  let timeMs = parseInt(origTimeMs);
178
287
 
179
288
  if (isNaN(timeMs))
180
289
  {
181
- node.error("Invalid time_on value send: " + origTimeMs);
290
+ console.warn("Invalid time_on value send: " + origTimeMs);
182
291
  timeMs = max_time_on;
183
292
  }
184
293
 
@@ -193,9 +302,9 @@ module.exports = function (RED)
193
302
  if (timeMs <= 0 || isPermanent || isMotion || !node_settings.last_value)
194
303
  return;
195
304
 
196
- max_time_on_timeout = setTimeout(() =>
305
+ timeout = setTimeout(() =>
197
306
  {
198
- max_time_on_timeout = null;
307
+ timeout = null;
199
308
  node_settings.last_value = false;
200
309
  node.send({ payload: false });
201
310
  notifyCentral(false);
@@ -205,26 +314,32 @@ module.exports = function (RED)
205
314
  }, timeMs);
206
315
  };
207
316
 
317
+ /**
318
+ * Stops the current running timeout
319
+ */
208
320
  let stopAutoOff = () =>
209
321
  {
210
- if (max_time_on_timeout != null)
322
+ if (timeout != null)
211
323
  {
212
- clearTimeout(max_time_on_timeout);
213
- max_time_on_timeout = null;
324
+ clearTimeout(timeout);
325
+ timeout = null;
214
326
  }
215
327
  };
216
328
 
329
+ /**
330
+ * Set the current node status
331
+ */
217
332
  let setStatus = () =>
218
333
  {
219
- if (alarm_active)
334
+ if (node_settings.alarm_active)
220
335
  {
221
336
  node.status({ fill: "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": ALARM is active" });
222
337
  }
223
338
  else if (node_settings.last_value)
224
339
  {
225
- if (isPermanent || isMotion || max_time_on_timeout == null)
340
+ if (isPermanent || isMotion || timeout == null)
226
341
  node.status({ fill: "green", shape: "dot", text: helper.getCurrentTimeForStatus() + ": On" });
227
- else if (max_time_on_timeout)
342
+ else if (timeout)
228
343
  node.status({ fill: "yellow", shape: "ring", text: helper.getCurrentTimeForStatus() + ": Wait " + helper.formatDateToStatus(timeout_end_date, "until") + " for auto off" });
229
344
  }
230
345
  else
@@ -233,6 +348,10 @@ module.exports = function (RED)
233
348
  }
234
349
  }
235
350
 
351
+ /**
352
+ * Notify all connected central nodes
353
+ * @param {boolean} state The state if the light is on
354
+ */
236
355
  let notifyCentral = state =>
237
356
  {
238
357
  if (!config.links)
@@ -240,8 +359,8 @@ module.exports = function (RED)
240
359
 
241
360
  config.links.forEach(link =>
242
361
  {
243
- // console.log(node.id + " -> " + link);
244
- // console.log({ source: node.id, state: state });
362
+ helper.log(node.id + " -> " + link);
363
+ helper.log({ source: node.id, state: state });
245
364
  RED.events.emit("node:" + link, { source: node.id, state: state });
246
365
  });
247
366
  }