smart-nodes 0.3.36 → 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 (116) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +35 -17
  3. package/central/central.html +27 -24
  4. package/central/central.js +84 -26
  5. package/central/locales/de-DE/central.html +10 -0
  6. package/central/locales/de-DE/central.json +14 -0
  7. package/central/locales/en-US/central.html +10 -0
  8. package/central/locales/en-US/central.json +14 -0
  9. package/compare/compare.html +64 -87
  10. package/compare/compare.js +69 -29
  11. package/compare/locales/de-DE/compare.html +36 -0
  12. package/compare/locales/de-DE/compare.json +35 -0
  13. package/compare/locales/en-US/compare.html +36 -0
  14. package/compare/locales/en-US/compare.json +35 -0
  15. package/counter/counter.html +70 -72
  16. package/counter/counter.js +43 -20
  17. package/counter/locales/de-DE/counter.html +48 -0
  18. package/counter/locales/de-DE/counter.json +21 -0
  19. package/counter/locales/en-US/counter.html +48 -0
  20. package/counter/locales/en-US/counter.json +21 -0
  21. package/delay/delay.html +30 -102
  22. package/delay/delay.js +63 -20
  23. package/delay/locales/de-DE/delay.html +71 -0
  24. package/delay/locales/de-DE/delay.json +19 -0
  25. package/delay/locales/en-US/delay.html +76 -0
  26. package/delay/locales/en-US/delay.json +19 -0
  27. package/forwarder/forwarder.html +11 -42
  28. package/forwarder/forwarder.js +59 -18
  29. package/forwarder/locales/de-DE/forwarder.html +32 -0
  30. package/forwarder/locales/de-DE/forwarder.json +15 -0
  31. package/forwarder/locales/en-US/forwarder.html +32 -0
  32. package/forwarder/locales/en-US/forwarder.json +15 -0
  33. package/heating-curve/heating-curve.html +10 -51
  34. package/heating-curve/heating-curve.js +38 -13
  35. package/heating-curve/locales/de-DE/heating-curve.html +38 -0
  36. package/heating-curve/locales/de-DE/heating-curve.json +12 -0
  37. package/heating-curve/locales/en-US/heating-curve.html +38 -0
  38. package/heating-curve/locales/en-US/heating-curve.json +12 -0
  39. package/hysteresis/hysteresis.html +49 -69
  40. package/hysteresis/hysteresis.js +94 -68
  41. package/hysteresis/locales/de-DE/hysteresis.html +36 -0
  42. package/hysteresis/locales/de-DE/hysteresis.json +27 -0
  43. package/hysteresis/locales/en-US/hysteresis.html +36 -0
  44. package/hysteresis/locales/en-US/hysteresis.json +27 -0
  45. package/light/light.html +250 -0
  46. package/{light-control/light-control.js → light/light.js} +151 -32
  47. package/light/locales/de-DE/light.html +149 -0
  48. package/light/locales/de-DE/light.json +24 -0
  49. package/light/locales/en-US/light.html +148 -0
  50. package/light/locales/en-US/light.json +24 -0
  51. package/logic/locales/de-DE/logic.html +12 -0
  52. package/logic/locales/de-DE/logic.json +26 -0
  53. package/logic/locales/en-US/logic.html +12 -0
  54. package/logic/locales/en-US/logic.json +26 -0
  55. package/logic/logic.html +48 -64
  56. package/logic/logic.js +63 -29
  57. package/long-press/locales/de-DE/long-press.html +5 -0
  58. package/long-press/locales/de-DE/long-press.json +13 -0
  59. package/long-press/locales/en-US/long-press.html +5 -0
  60. package/long-press/locales/en-US/long-press.json +13 -0
  61. package/{long-press-control/long-press-control.html → long-press/long-press.html} +10 -14
  62. package/long-press/long-press.js +163 -0
  63. package/mixing-valve/locales/de-DE/mixing-valve.html +65 -0
  64. package/mixing-valve/locales/de-DE/mixing-valve.json +19 -0
  65. package/mixing-valve/locales/en-US/mixing-valve.html +66 -0
  66. package/mixing-valve/locales/en-US/mixing-valve.json +19 -0
  67. package/mixing-valve/mixing-valve.html +27 -93
  68. package/mixing-valve/mixing-valve.js +87 -61
  69. package/multi-press/locales/de-DE/multi-press.html +5 -0
  70. package/multi-press/locales/de-DE/multi-press.json +12 -0
  71. package/multi-press/locales/en-US/multi-press.html +5 -0
  72. package/multi-press/locales/en-US/multi-press.json +12 -0
  73. package/{multi-press-control/multi-press-control.html → multi-press/multi-press.html} +9 -13
  74. package/{multi-press-control/multi-press-control.js → multi-press/multi-press.js} +53 -5
  75. package/package.json +7 -7
  76. package/persistence.js +1 -0
  77. package/scene/locales/de-DE/scene.html +105 -0
  78. package/scene/locales/de-DE/scene.json +21 -0
  79. package/scene/locales/en-US/scene.html +107 -0
  80. package/scene/locales/en-US/scene.json +20 -0
  81. package/{scene-control/scene-control.html → scene/scene.html} +30 -132
  82. package/{scene-control/scene-control.js → scene/scene.js} +76 -26
  83. package/scheduler/locales/de-DE/scheduler.html +30 -0
  84. package/scheduler/locales/de-DE/scheduler.json +21 -0
  85. package/scheduler/locales/en-US/scheduler.html +30 -0
  86. package/scheduler/locales/en-US/scheduler.json +21 -0
  87. package/scheduler/scheduler.html +34 -64
  88. package/scheduler/scheduler.js +85 -53
  89. package/shutter/locales/de-DE/shutter.html +127 -0
  90. package/shutter/locales/de-DE/shutter.json +11 -0
  91. package/shutter/locales/en-US/shutter.html +133 -0
  92. package/shutter/locales/en-US/shutter.json +11 -0
  93. package/{shutter-control/shutter-control.html → shutter/shutter.html} +7 -133
  94. package/{shutter-control/shutter-control.js → shutter/shutter.js} +116 -56
  95. package/shutter-complex/locales/de-DE/shutter-complex.html +120 -0
  96. package/shutter-complex/locales/de-DE/shutter-complex.json +20 -0
  97. package/shutter-complex/locales/en-US/shutter-complex.html +120 -0
  98. package/shutter-complex/locales/en-US/shutter-complex.json +20 -0
  99. package/{shutter-complex-control/shutter-complex-control.html → shutter-complex/shutter-complex.html} +36 -140
  100. package/shutter-complex/shutter-complex.js +578 -0
  101. package/smart_helper.js +52 -9
  102. package/statistic/locales/de-DE/statistic.html +10 -0
  103. package/statistic/locales/de-DE/statistic.json +29 -0
  104. package/statistic/locales/en-US/statistic.html +10 -0
  105. package/statistic/locales/en-US/statistic.json +29 -0
  106. package/statistic/statistic.html +38 -43
  107. package/statistic/statistic.js +57 -28
  108. package/text-exec/locales/de-DE/text-exec.html +18 -0
  109. package/text-exec/locales/de-DE/text-exec.json +7 -0
  110. package/text-exec/locales/en-US/text-exec.html +18 -0
  111. package/text-exec/locales/en-US/text-exec.json +7 -0
  112. package/text-exec/text-exec.html +9 -25
  113. package/text-exec/text-exec.js +43 -2
  114. package/light-control/light-control.html +0 -363
  115. package/long-press-control/long-press-control.js +0 -76
  116. package/shutter-complex-control/shutter-complex-control.js +0 -442
@@ -0,0 +1,29 @@
1
+ {
2
+ "statistic": {
3
+ "ui": {
4
+ "name": "Name",
5
+ "operation": "Operation",
6
+ "count": "Anzahl",
7
+ "message": "Nachricht",
8
+
9
+ "note": "Hinweis:",
10
+ "note_text": "<code>msg.payload</code> wird immer automatisch auf den Ergebnis-Wert gesetzt.",
11
+
12
+ "output_messages": "Ausgangsnachrichten",
13
+ "system_start": "Systemstart",
14
+ "save_state": "Zustand speichern",
15
+ "send_after_start": "Letze Nachricht 10 Sekunden nach dem Start senden",
16
+
17
+ "minimum": "Minimum",
18
+ "maximum": "Maximum",
19
+ "sum": "Summe",
20
+ "difference": "Differenz",
21
+ "absolute_value": "Absoluter Wert",
22
+ "absolute_difference": "Absolute Differenz",
23
+ "average": "Durchschnitt",
24
+ "moving_average": "Gleitender Mittelwert",
25
+
26
+ "default": "Standard"
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,10 @@
1
+ <script type="text/html" data-help-name="smart_statistic">
2
+ <p>This node calculates the minimum, maximum, sum, difference, absolute value, absolute difference, average and moving average of different values.</p>
3
+ <p>Each value must be sent with its own topic. If a second value comes with the same topic, the corresponding value is overwritten.</p>
4
+ <p>In the case of MIN, MAX and ABS, the corresponding topic that came with the values is also output. SUM, DIFF, AVG and MOV_AVG are combined results, which is why Topic is always not set here.</p>
5
+ <p>The topic is not important for the absolute value and the moving average; every value that is received is used for the calculation.</p>
6
+ <p>
7
+ <b>Note:</b> Smart nodes use topics in the format <code>name#number</code>, so that different smart nodes can be controlled with the same topic.<br/>
8
+ This node only uses the <code>number</code> part. <code>name</code> and <code>#</code> are optional.
9
+ </p>
10
+ </script>
@@ -0,0 +1,29 @@
1
+ {
2
+ "statistic": {
3
+ "ui": {
4
+ "name": "Name",
5
+ "operation": "Operation",
6
+ "count": "Count",
7
+ "message": "Message",
8
+
9
+ "note": "Note:",
10
+ "note_text": "<code>msg.payload</code> is always automatically set to the result value.",
11
+
12
+ "output_messages": "Output messages",
13
+ "system_start": "System start",
14
+ "save_state": "Save state",
15
+ "send_after_start": "Send last message 10 seconds after start",
16
+
17
+ "minimum": "Minimum",
18
+ "maximum": "Maximum",
19
+ "sum": "Sum",
20
+ "difference": "Difference",
21
+ "absolute_value": "Absolute value",
22
+ "absolute_difference": "Absolute difference",
23
+ "average": "Average",
24
+ "moving_average": "Moving average",
25
+
26
+ "default": "Default"
27
+ }
28
+ }
29
+ }
@@ -21,23 +21,24 @@
21
21
  },
22
22
  oneditprepare: function ()
23
23
  {
24
+ let node = this;
25
+
24
26
  $("#node-input-operation")
25
27
  .typedInput({
26
- types: [
27
- {
28
- default: "MIN",
29
- options: [
30
- { value: "MIN", label: "Minimum" },
31
- { value: "MAX", label: "Maximum" },
32
- { value: "SUM", label: "Summe" },
33
- { value: "DIFF", label: "Differenz" },
34
- { value: "ABS", label: "Absoluter Wert" },
35
- { value: "ABS_DIFF", label: "Absolute Differenz" },
36
- { value: "AVG", label: "Durchschnitt" },
37
- { value: "MOV_AVG", label: "Gleitender Mittelwert" }
38
- ],
39
- },
40
- ],
28
+ types: [{
29
+ default: "MIN",
30
+ value: "operation",
31
+ options: [
32
+ { value: "MIN", label: node._("statistic.ui.minimum") },
33
+ { value: "MAX", label: node._("statistic.ui.maximum") },
34
+ { value: "SUM", label: node._("statistic.ui.sum") },
35
+ { value: "DIFF", label: node._("statistic.ui.difference") },
36
+ { value: "ABS", label: node._("statistic.ui.absolute_value") },
37
+ { value: "ABS_DIFF", label: node._("statistic.ui.absolute_difference") },
38
+ { value: "AVG", label: node._("statistic.ui.average") },
39
+ { value: "MOV_AVG", label: node._("statistic.ui.moving_average") }
40
+ ],
41
+ }],
41
42
  });
42
43
 
43
44
  $("#node-input-count").css("max-width", "4rem").spinner({
@@ -63,8 +64,8 @@
63
64
  $("#node-input-out_message").typedInput({
64
65
  type: "json",
65
66
  types: ["json", {
66
- value: "null",
67
- label: "Standard",
67
+ value: "DEFAULT",
68
+ label: node._("statistic.ui.default"),
68
69
  icon: "fa fa-times",
69
70
  hasValue: false,
70
71
  }],
@@ -79,57 +80,51 @@
79
80
  $("#resend_on_start_row").hide();
80
81
  });
81
82
  $("#node-input-save_state").trigger("change");
83
+
84
+
85
+ // Backward compatibility
86
+ if (this.out_message_type == "null")
87
+ {
88
+ this.out_message_type = "DEFAULT";
89
+ $("#node-input-out_message_type").val("DEFAULT");
90
+ }
91
+
82
92
  }
83
93
  });
84
94
  </script>
85
95
 
86
96
  <script type="text/html" data-template-name="smart_statistic">
87
97
  <div class="form-row">
88
- <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
89
- <input type="text" id="node-input-name" placeholder="Name" />
98
+ <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="statistic.ui.name"></span></label>
99
+ <input type="text" id="node-input-name" data-i18n="[placeholder]statistic.ui.name" />
90
100
  </div>
91
101
  <div class="form-row">
92
- <label for="node-input-operation"><i class="fa fa-sort"></i> Operation</label>
102
+ <label for="node-input-operation"><i class="fa fa-sort"></i> <span data-i18n="statistic.ui.operation"></span></label>
93
103
  <input id="node-input-operation" />
94
104
  </div>
95
105
  <div class="form-row statistic-moving-average-row" style="display: none;">
96
- <label for="node-input-count"><i class="fa fa-hashtag"></i> Anzahl</label>
106
+ <label for="node-input-count"><i class="fa fa-hashtag"></i> <span data-i18n="statistic.ui.count"></span></label>
97
107
  <input id="node-input-count" />
98
108
  </div>
99
109
  <hr/>
100
- <h4 style="margin: 0.5rem 0;">Ausgangsnachricht</h4>
110
+ <h4 style="margin: 0.5rem 0;" data-i18n="statistic.ui.output_messages"></h4>
101
111
  <div class="form-row">
102
- <label for="node-input-out_message"><i class="fa fa-check-circle"></i> Nachricht</label>
112
+ <label for="node-input-out_message"><i class="fa fa-check-circle"></i> <span data-i18n="statistic.ui.message"></span></label>
103
113
  <input type="text" id="node-input-out_message"/>
104
114
  <input type="hidden" id="node-input-out_message_type">
105
115
  </div>
106
116
  <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>
117
+ <div><strong data-i18n="statistic.ui.note"></strong></div>
118
+ <div data-i18n="[html]statistic.ui.note_text"></div>
113
119
  </div>
114
120
  <hr/>
115
- <h4 style="margin: 0.5rem 0;">Systemstart</h4>
121
+ <h4 style="margin: 0.5rem 0;" data-i18n="statistic.ui.system_start"></h4>
116
122
  <div class="form-row">
117
123
  <input type="checkbox" id="node-input-save_state" style="width: 20px;" />
118
- <label for="node-input-save_state" style="width: calc(100% - 30px);">Zustand speichern</label>
124
+ <label for="node-input-save_state" style="width: calc(100% - 30px);" data-i18n="statistic.ui.save_state"></label>
119
125
  </div>
120
126
  <div class="form-row" id="resend_on_start_row">
121
127
  <input type="checkbox" id="node-input-resend_on_start" style="width: 20px;" />
122
- <label for="node-input-resend_on_start" style="width: calc(100% - 30px);">Letze Nachricht 10 Sekunden nach dem Start senden</label>
128
+ <label for="node-input-resend_on_start" style="width: calc(100% - 30px);" data-i18n="statistic.ui.send_after_start"></label>
123
129
  </div>
124
- </script>
125
-
126
- <script type="text/html" data-help-name="smart_statistic">
127
- <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>
128
- <p>Jeder Wert muss mit einem eigenen Topic gesendet werden. Kommt ein zweiter Wert mit dem gleichen Topic, wird der entsprechende Wert überschrieben.</p>
129
- <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>
130
- <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>
131
- <p>
132
- <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/>
133
- Diese Node verwendet nur den Teil <code>nummer</code>. <code>name</code> und <code>#</code> sind dabei optional.
134
- </p>
135
130
  </script>
@@ -7,44 +7,80 @@ 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
 
21
+
22
+ // #####################
23
+ // # persistent values #
24
+ // #####################
13
25
  var node_settings = {
14
26
  values: [],
15
- lastMessage: null,
27
+ last_message: null,
16
28
  };
17
29
 
30
+
31
+ // load or delete saved values
18
32
  if (config.save_state)
19
- {
20
- // load old saved values
21
33
  node_settings = Object.assign(node_settings, smart_context.get(node.id));
22
- }
23
34
  else
24
- {
25
- // delete old saved values
26
35
  smart_context.del(node.id);
27
- }
28
36
 
29
- // dynamic config
37
+
38
+ // ##################
39
+ // # Dynamic config #
40
+ // ##################
30
41
  let operation = config.operation
31
42
  let out_message = helper.evaluateNodeProperty(RED, config.out_message, config.out_message_type);
32
43
  let count = config.count;
33
44
 
34
- // runtime values
45
+ // ##################
46
+ // # Runtime values #
47
+ // ##################
35
48
 
36
49
 
50
+ // ###############
51
+ // # Node events #
52
+ // ###############
37
53
  node.on("input", function (msg)
54
+ {
55
+ handleTopic(msg);
56
+
57
+ setStatus();
58
+ if (config.save_state)
59
+ smart_context.set(node.id, node_settings);
60
+ });
61
+
62
+ node.on("close", function ()
63
+ {
64
+ });
65
+
66
+
67
+ // #####################
68
+ // # Private functions #
69
+ // #####################
70
+
71
+ // This is the main function which handles all topics that was received.
72
+ let handleTopic = msg =>
38
73
  {
39
74
  if (isNaN(parseFloat(msg.payload)))
40
75
  {
41
- // node.error("Invalid payload: " + msg.payload);
76
+ console.warn("Invalid payload: " + msg.payload);
42
77
  return;
43
78
  }
44
79
 
45
- let real_topic = helper.getTopicNumber(msg.topic) || 0;
46
- // real_topic should be sended with 1-based, but internally 0-based is needed
47
- real_topic--;
80
+ let real_topic_number = helper.getTopicNumber(msg.topic) || 0;
81
+
82
+ // real_topic_number should be sended with 1-based, but internally 0-based is needed
83
+ real_topic_number--;
48
84
 
49
85
  if (operation === "MOV_AVG")
50
86
  {
@@ -59,7 +95,7 @@ module.exports = function (RED)
59
95
  node.error("Topic not set");
60
96
  return;
61
97
  }
62
- node_settings.values[real_topic] = parseFloat(msg.payload);
98
+ node_settings.values[real_topic_number] = parseFloat(msg.payload);
63
99
  }
64
100
 
65
101
  msg = getResult(msg);
@@ -69,19 +105,12 @@ module.exports = function (RED)
69
105
  {
70
106
  // if out_message is set, use this instead of the default message
71
107
  if (out_message)
72
- msg = Object.assign({}, out_message, { payload: msg.payload });
108
+ msg = helper.cloneObject(out_message, { payload: msg.payload });
73
109
 
74
- node_settings.lastMessage = msg;
75
- node.send(msg);
110
+ node_settings.last_message = helper.cloneObject(msg);
111
+ node.send(node_settings.last_message);
76
112
  }
77
-
78
- if (config.save_state)
79
- smart_context.set(node.id, node_settings);
80
- });
81
-
82
- node.on("close", function ()
83
- {
84
- });
113
+ }
85
114
 
86
115
  let getResult = (msg) =>
87
116
  {
@@ -188,15 +217,15 @@ module.exports = function (RED)
188
217
  node.status({ fill: "yellow", shape: "ring", text: helper.getCurrentTimeForStatus() + ": " + operation + "(" + Object.entries(node_settings.values).map(v => v[1]).join(", ") + ") => " + msg.payload });
189
218
  }
190
219
 
191
- if (config.save_state && config.resend_on_start && node_settings.lastMessage != null)
220
+ if (config.save_state && config.resend_on_start && node_settings.last_message != null)
192
221
  {
193
222
  setTimeout(() =>
194
223
  {
195
- node.send(node_settings.lastMessage);
224
+ node.send(helper.cloneObject(node_settings.last_message));
196
225
  }, 10000);
197
226
  }
198
227
 
199
- setStatus(node_settings.lastMessage);
228
+ setStatus(node_settings.last_message);
200
229
  }
201
230
 
202
231
  RED.nodes.registerType("smart_statistic", StatisticNode);
@@ -0,0 +1,18 @@
1
+ <script type="text/html" data-help-name="smart_text-exec">
2
+ <p>
3
+ Diese Node nimmt einen Text entgegen, zerlegt ihn und führt die Kommandos auf den ausgewählten und passenden Nodes aus.
4
+ </p>
5
+ <p>
6
+ <strong>Beispiele:</strong><br/><br/>
7
+ <strong>Schalte das Licht im Wohnzimmer ein.</strong><br/>
8
+ Alle Light-controls und Scene-controls die das Wort <strong>Wohnzimmer</strong> enthalten bekommen eine Nachricht mit dem topic <code>on</code>.<br/><br/>
9
+
10
+ <strong>Schalte das Büro ein und die Küche aus.</strong><br/>
11
+ Alle Light-controls und Scene-controls die das Wort <strong>Büro</strong> enthalten bekommen eine Nachricht mit dem topic <code>on</code> und
12
+ alle Light-controls und Scene-controls die das Wort <strong>Küche</strong> enthalten bekommen eine Nachricht mit dem topic <code>off</code>.<br/><br/>
13
+
14
+ <strong>Schließe die Rollladen im Wohnzimmer und schalte das Licht in der Küche an.</strong><br/>
15
+ Alle Schutter-controls und Shutter-complex-controls die das Wort <strong>Wohnzimmer</strong> enthalten bekommen eine Nachricht mit dem topic <code>down</code> und
16
+ alle Light-controls und Scene-controls die das Wort <strong>Küche</strong> enthalten bekommen eine Nachricht mit dem topic <code>on</code>.<br/><br/>
17
+ </p>
18
+ </script>
@@ -0,0 +1,7 @@
1
+ {
2
+ "text-exec": {
3
+ "ui": {
4
+ "name": "Name"
5
+ }
6
+ }
7
+ }
@@ -0,0 +1,18 @@
1
+ <script type="text/html" data-help-name="smart_text-exec">
2
+ <p>
3
+ This node accepts a text, breaks it down and executes the commands on the selected and appropriate nodes.
4
+ </p>
5
+ <p>
6
+ <strong>Examples:</strong><br/><br/>
7
+ <strong>Turn on the light in the living room.</strong><br/>
8
+ All light controls and scene controls that contain the word <strong>living room</strong> receive a message with the topic <code>on</code>.<br/><br/>
9
+
10
+ <strong>Turn on the office and turn off the kitchen.</strong><br/>
11
+ All light controls and scene controls that contain the word <strong>office</strong> receive a message with the topic <code>on</code> and
12
+ all light controls and scene controls that contain the word <strong>kitchen</strong> receive a message with the topic <code>off</code>.<br/><br/>
13
+
14
+ <strong>Close the shutters in the living room and turn on the light in the kitchen.</strong><br/>
15
+ All shutter controls and shutter complex controls that contain the word <strong>living room</strong> receive a message with the topic <code>down</code> and
16
+ all light controls and scene controls that contain the word <strong>kitchen</strong> receive a message with the topic <code>on</code>.<br/><br/>
17
+ </p>
18
+ </script>
@@ -0,0 +1,7 @@
1
+ {
2
+ "text-exec": {
3
+ "ui": {
4
+ "name": "Name"
5
+ }
6
+ }
7
+ }
@@ -264,11 +264,14 @@
264
264
  },
265
265
  oneditprepare: function ()
266
266
  {
267
- // console.log("Here");
267
+ let node = this;
268
+
268
269
  onEditPrepare(this, ["smart_light-control", "smart_scene-control", "smart_shutter-complex-control", "smart_shutter-control"]);
269
270
  },
270
271
  oneditsave: function ()
271
272
  {
273
+ let node = this;
274
+
272
275
  onEditSave(this);
273
276
  },
274
277
  onadd: onAdd,
@@ -279,30 +282,11 @@
279
282
 
280
283
  <script type="text/html" data-template-name="smart_text-exec">
281
284
  <div class="form-row">
282
- <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
283
- <input type="text" id="node-input-name" />
285
+ <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="text-exec.ui.name"></span></label>
286
+ <input type="text" id="node-input-name" data-i18n="[placeholder]text-exec.ui.name" />
287
+ </div>
288
+ <div class="node-input-link-rows" style="position:relative; height: 30px; text-align: right;">
289
+ <div style="display:inline-block"><input type="text" id="node-input-link-target-filter" /></div>
284
290
  </div>
285
- <div class="node-input-link-rows" style="position:relative; height: 30px; text-align: right;"
286
- ><div style="display:inline-block"><input type="text" id="node-input-link-target-filter" /></div
287
- ></div>
288
291
  <div class="form-row node-input-link-row node-input-link-rows"></div>
289
- </script>
290
-
291
- <script type="text/html" data-help-name="smart_text-exec">
292
- <p>
293
- Diese Node nimmt einen Text entgegen, zerlegt ihn und führt die Kommandos auf den ausgewählten und passenden Nodes aus.
294
- </p>
295
- <p>
296
- <strong>Beispiele:</strong><br/><br/>
297
- <strong>Schalte das Licht im Wohnzimmer ein.</strong><br/>
298
- Alle Light-controls und Scene-controls die das Wort <strong>Wohnzimmer</strong> enthalten bekommen eine Nachricht mit dem topic <code>on</code>.<br/><br/>
299
-
300
- <strong>Schalte das Büro ein und die Küche aus.</strong><br/>
301
- Alle Light-controls und Scene-controls die das Wort <strong>Büro</strong> enthalten bekommen eine Nachricht mit dem topic <code>on</code> und
302
- alle Light-controls und Scene-controls die das Wort <strong>Küche</strong> enthalten bekommen eine Nachricht mit dem topic <code>off</code>.<br/><br/>
303
-
304
- <strong>Schließe die Rollladen im Wohnzimmer und schalte das Licht in der Küche an.</strong><br/>
305
- Alle Schutter-controls und Shutter-complex-controls die das Wort <strong>Wohnzimmer</strong> enthalten bekommen eine Nachricht mit dem topic <code>down</code> und
306
- alle Light-controls und Scene-controls die das Wort <strong>Küche</strong> enthalten bekommen eine Nachricht mit dem topic <code>on</code>.<br/><br/>
307
- </p>
308
292
  </script>
@@ -7,15 +7,52 @@ module.exports = function (RED)
7
7
  const node = this;
8
8
  RED.nodes.createNode(node, config);
9
9
 
10
+
11
+ // ###################
12
+ // # Class constants #
13
+ // ###################
14
+
15
+
16
+ // #######################
17
+ // # Global help objects #
18
+ // #######################
19
+ const smart_context = require("../persistence.js")(RED);
10
20
  const helper = require("../smart_helper.js");
11
21
 
12
- node.status({});
13
22
 
14
- let log = [];
23
+ // #####################
24
+ // # persistent values #
25
+ // #####################
26
+
27
+
28
+ // ##################
29
+ // # Dynamic config #
30
+ // ##################
31
+
32
+
33
+ // ##################
34
+ // # Runtime values #
35
+ // ##################
36
+
37
+ // Here the ouput message for logging purposes is saved.
38
+ // It will be cleared with every new node input
39
+ let log;
40
+
41
+ // Holds a list with all room names, sorted from the longest to the shortest
42
+ // Format: Index => RoomName
15
43
  let rooms = [];
16
44
 
45
+ // Holds references to the nodes to access them by room name
46
+ // Format: RoomName => [Node1, Node2, ..., NodeX]
17
47
  let lookup = [];
18
48
 
49
+
50
+ node.status({});
51
+
52
+
53
+ // ###############
54
+ // # Node events #
55
+ // ###############
19
56
  node.on("input", function (msg)
20
57
  {
21
58
  let mode = "light"; // light || shutter
@@ -216,6 +253,10 @@ module.exports = function (RED)
216
253
  node.send(log);
217
254
  });
218
255
 
256
+ node.on("close", function ()
257
+ {
258
+ });
259
+
219
260
  /**
220
261
  * This function prepares a list of the rooms as well as the lookup tables for lights and shutters
221
262
  */