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.
- package/CHANGELOG.md +62 -0
- package/README.md +35 -17
- package/central/central.html +27 -24
- package/central/central.js +84 -26
- package/central/locales/de-DE/central.html +10 -0
- package/central/locales/de-DE/central.json +14 -0
- package/central/locales/en-US/central.html +10 -0
- package/central/locales/en-US/central.json +14 -0
- package/compare/compare.html +64 -87
- package/compare/compare.js +69 -29
- package/compare/locales/de-DE/compare.html +36 -0
- package/compare/locales/de-DE/compare.json +35 -0
- package/compare/locales/en-US/compare.html +36 -0
- package/compare/locales/en-US/compare.json +35 -0
- package/counter/counter.html +70 -72
- package/counter/counter.js +43 -20
- package/counter/locales/de-DE/counter.html +48 -0
- package/counter/locales/de-DE/counter.json +21 -0
- package/counter/locales/en-US/counter.html +48 -0
- package/counter/locales/en-US/counter.json +21 -0
- package/delay/delay.html +30 -102
- package/delay/delay.js +63 -20
- package/delay/locales/de-DE/delay.html +71 -0
- package/delay/locales/de-DE/delay.json +19 -0
- package/delay/locales/en-US/delay.html +76 -0
- package/delay/locales/en-US/delay.json +19 -0
- package/forwarder/forwarder.html +11 -42
- package/forwarder/forwarder.js +59 -18
- package/forwarder/locales/de-DE/forwarder.html +32 -0
- package/forwarder/locales/de-DE/forwarder.json +15 -0
- package/forwarder/locales/en-US/forwarder.html +32 -0
- package/forwarder/locales/en-US/forwarder.json +15 -0
- package/heating-curve/heating-curve.html +10 -51
- package/heating-curve/heating-curve.js +38 -13
- package/heating-curve/locales/de-DE/heating-curve.html +38 -0
- package/heating-curve/locales/de-DE/heating-curve.json +12 -0
- package/heating-curve/locales/en-US/heating-curve.html +38 -0
- package/heating-curve/locales/en-US/heating-curve.json +12 -0
- package/hysteresis/hysteresis.html +49 -69
- package/hysteresis/hysteresis.js +94 -68
- package/hysteresis/locales/de-DE/hysteresis.html +36 -0
- package/hysteresis/locales/de-DE/hysteresis.json +27 -0
- package/hysteresis/locales/en-US/hysteresis.html +36 -0
- package/hysteresis/locales/en-US/hysteresis.json +27 -0
- package/light/light.html +250 -0
- package/{light-control/light-control.js → light/light.js} +151 -32
- package/light/locales/de-DE/light.html +149 -0
- package/light/locales/de-DE/light.json +24 -0
- package/light/locales/en-US/light.html +148 -0
- package/light/locales/en-US/light.json +24 -0
- package/logic/locales/de-DE/logic.html +12 -0
- package/logic/locales/de-DE/logic.json +26 -0
- package/logic/locales/en-US/logic.html +12 -0
- package/logic/locales/en-US/logic.json +26 -0
- package/logic/logic.html +48 -64
- package/logic/logic.js +63 -29
- package/long-press/locales/de-DE/long-press.html +5 -0
- package/long-press/locales/de-DE/long-press.json +13 -0
- package/long-press/locales/en-US/long-press.html +5 -0
- package/long-press/locales/en-US/long-press.json +13 -0
- package/{long-press-control/long-press-control.html → long-press/long-press.html} +10 -14
- package/long-press/long-press.js +163 -0
- package/mixing-valve/locales/de-DE/mixing-valve.html +65 -0
- package/mixing-valve/locales/de-DE/mixing-valve.json +19 -0
- package/mixing-valve/locales/en-US/mixing-valve.html +66 -0
- package/mixing-valve/locales/en-US/mixing-valve.json +19 -0
- package/mixing-valve/mixing-valve.html +27 -93
- package/mixing-valve/mixing-valve.js +87 -61
- package/multi-press/locales/de-DE/multi-press.html +5 -0
- package/multi-press/locales/de-DE/multi-press.json +12 -0
- package/multi-press/locales/en-US/multi-press.html +5 -0
- package/multi-press/locales/en-US/multi-press.json +12 -0
- package/{multi-press-control/multi-press-control.html → multi-press/multi-press.html} +9 -13
- package/{multi-press-control/multi-press-control.js → multi-press/multi-press.js} +53 -5
- package/package.json +7 -7
- package/persistence.js +1 -0
- package/scene/locales/de-DE/scene.html +105 -0
- package/scene/locales/de-DE/scene.json +21 -0
- package/scene/locales/en-US/scene.html +107 -0
- package/scene/locales/en-US/scene.json +20 -0
- package/{scene-control/scene-control.html → scene/scene.html} +30 -132
- package/{scene-control/scene-control.js → scene/scene.js} +76 -26
- package/scheduler/locales/de-DE/scheduler.html +30 -0
- package/scheduler/locales/de-DE/scheduler.json +21 -0
- package/scheduler/locales/en-US/scheduler.html +30 -0
- package/scheduler/locales/en-US/scheduler.json +21 -0
- package/scheduler/scheduler.html +34 -64
- package/scheduler/scheduler.js +85 -53
- package/shutter/locales/de-DE/shutter.html +127 -0
- package/shutter/locales/de-DE/shutter.json +11 -0
- package/shutter/locales/en-US/shutter.html +133 -0
- package/shutter/locales/en-US/shutter.json +11 -0
- package/{shutter-control/shutter-control.html → shutter/shutter.html} +7 -133
- package/{shutter-control/shutter-control.js → shutter/shutter.js} +116 -56
- package/shutter-complex/locales/de-DE/shutter-complex.html +120 -0
- package/shutter-complex/locales/de-DE/shutter-complex.json +20 -0
- package/shutter-complex/locales/en-US/shutter-complex.html +120 -0
- package/shutter-complex/locales/en-US/shutter-complex.json +20 -0
- package/{shutter-complex-control/shutter-complex-control.html → shutter-complex/shutter-complex.html} +36 -140
- package/shutter-complex/shutter-complex.js +578 -0
- package/smart_helper.js +52 -9
- package/statistic/locales/de-DE/statistic.html +10 -0
- package/statistic/locales/de-DE/statistic.json +29 -0
- package/statistic/locales/en-US/statistic.html +10 -0
- package/statistic/locales/en-US/statistic.json +29 -0
- package/statistic/statistic.html +38 -43
- package/statistic/statistic.js +57 -28
- package/text-exec/locales/de-DE/text-exec.html +18 -0
- package/text-exec/locales/de-DE/text-exec.json +7 -0
- package/text-exec/locales/en-US/text-exec.html +18 -0
- package/text-exec/locales/en-US/text-exec.json +7 -0
- package/text-exec/text-exec.html +9 -25
- package/text-exec/text-exec.js +43 -2
- package/light-control/light-control.html +0 -363
- package/long-press-control/long-press-control.js +0 -76
- package/shutter-complex-control/shutter-complex-control.js +0 -442
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
<script type="text/html" data-help-name="smart_shutter-control">
|
|
2
|
+
<p>
|
|
3
|
+
<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 />
|
|
4
|
+
This node only uses the part <code>name</code>. <code>#</code> and <code>number</code> are optional.
|
|
5
|
+
</p>
|
|
6
|
+
<p>
|
|
7
|
+
This node controls roller shutters or blinds. There are 3 outputs that can be controlled:
|
|
8
|
+
<ol>
|
|
9
|
+
<li><b>Up/Down:</b> <code>msg.payload = false</code> moves the roller shutter up and <code>msg.payload = true</code> moves the roller shutter down.</li>
|
|
10
|
+
<li><b>Stop:</b> <code>msg.payload = true</code> stops the roller shutter.</li>
|
|
11
|
+
<li><b>Position:</b> <code>msg.payload = 42</code> Moves the roller shutter to 42%.</li>
|
|
12
|
+
</ol>
|
|
13
|
+
The outputs are assigned to the respective KNX group addresses.
|
|
14
|
+
</p>
|
|
15
|
+
<p>
|
|
16
|
+
This node expects the following topics as input:<br />
|
|
17
|
+
<table>
|
|
18
|
+
<thead>
|
|
19
|
+
<tr>
|
|
20
|
+
<th>Topic</th>
|
|
21
|
+
<th>Description</th>
|
|
22
|
+
<th>msg.payload == false is ignored</th>
|
|
23
|
+
</tr>
|
|
24
|
+
</thead>
|
|
25
|
+
<tbody>
|
|
26
|
+
<tr>
|
|
27
|
+
<td><code>status</code> or <code>status_position</code></td>
|
|
28
|
+
<td>
|
|
29
|
+
The node reports the current position.
|
|
30
|
+
This allows the node to determine in which direction a roller shutter last moved.
|
|
31
|
+
This is required for the topic <b>toggle</b> to determine the next direction of travel for a 1-button
|
|
32
|
+
operation.
|
|
33
|
+
</td>
|
|
34
|
+
</tr>
|
|
35
|
+
<tr>
|
|
36
|
+
<td><code>up_down</code></td>
|
|
37
|
+
<td>
|
|
38
|
+
Receives a command from Home Assistant to be informed whether the roller shutter is running and in which
|
|
39
|
+
direction.<br />
|
|
40
|
+
<strong>Important:</strong> This topic <u>does not</u> start the roller shutter, as the group address
|
|
41
|
+
must be directly connected to the blind module.
|
|
42
|
+
</td>
|
|
43
|
+
<td>No</td>
|
|
44
|
+
</tr>
|
|
45
|
+
<tr>
|
|
46
|
+
<td><code>short_up_down</code></td>
|
|
47
|
+
<td>
|
|
48
|
+
Sends a short up command if <code>msg.payload = false</code> and a short down command if
|
|
49
|
+
<code>msg.payload = true</code>.<br />
|
|
50
|
+
The time stored in the module is used. However, this can be overwritten once by setting
|
|
51
|
+
<code>msg.time_on = 1500</code> or <code>msg.time_on = "1.5s"</code>.
|
|
52
|
+
</td>
|
|
53
|
+
<td>No</td>
|
|
54
|
+
</tr>
|
|
55
|
+
<tr>
|
|
56
|
+
<td><code>up</code></td>
|
|
57
|
+
<td>Sends a command to raise the roller shutter if it is not already moving up. If necessary, a stop command
|
|
58
|
+
is sent beforehand.</td>
|
|
59
|
+
<td>Yes</td>
|
|
60
|
+
</tr>
|
|
61
|
+
<tr>
|
|
62
|
+
<td><code>up_stop</code></td>
|
|
63
|
+
<td>Sends a stop and an up command alternately.</td>
|
|
64
|
+
<td>Yes</td>
|
|
65
|
+
</tr>
|
|
66
|
+
<tr>
|
|
67
|
+
<td><code>down</code></td>
|
|
68
|
+
<td>Sends a down command if the roller shutter is not already moving down. If necessary, a stop command is
|
|
69
|
+
sent beforehand.</td>
|
|
70
|
+
<td>Yes</td>
|
|
71
|
+
</tr>
|
|
72
|
+
<tr>
|
|
73
|
+
<td><code>down_stop</code></td>
|
|
74
|
+
<td>Sends a stop and a down command alternately.</td>
|
|
75
|
+
<td>Yes</td>
|
|
76
|
+
</tr>
|
|
77
|
+
<tr>
|
|
78
|
+
<td><code>stop</code></td>
|
|
79
|
+
<td>Sends a stop command.</td>
|
|
80
|
+
<td>Yes</td>
|
|
81
|
+
</tr>
|
|
82
|
+
<tr>
|
|
83
|
+
<td><code>position</code></td>
|
|
84
|
+
<td>Sends a position command. <code>msg.payload</code> should have a value between 0 (open) and 100
|
|
85
|
+
(closed).</td>
|
|
86
|
+
<td>No</td>
|
|
87
|
+
</tr>
|
|
88
|
+
<tr>
|
|
89
|
+
<td><code>toggle</code> (default)</td>
|
|
90
|
+
<td>Switches the roller shutter alternately to up, stop, down, stop.</td>
|
|
91
|
+
<td>Yes</td>
|
|
92
|
+
</tr>
|
|
93
|
+
</tbody>
|
|
94
|
+
</table>
|
|
95
|
+
</p>
|
|
96
|
+
<p>
|
|
97
|
+
This node does not manage a running time for the roller shutter itself. This must be configured for the output via ETS.
|
|
98
|
+
However, it is possible to switch the roller shutter off automatically after a defined time.
|
|
99
|
+
However, it is possible to switch the roller shutter off automatically after a defined time.
|
|
100
|
+
Example: <code>msg = { "topic": "up", "time_on": 5000 }</code> or <code>msg = { "topic": "up", "time_on": "5s" }</code><br />
|
|
101
|
+
This message causes the roller shutter to move up for 5000 milliseconds / 5 seconds. If it is a Venetian blind, the slats are rotated accordingly.
|
|
102
|
+
The following values can be used as a unit for time:
|
|
103
|
+
<table>
|
|
104
|
+
<thead>
|
|
105
|
+
<tr>
|
|
106
|
+
<th>Unit</th>
|
|
107
|
+
<th>Description</th>
|
|
108
|
+
</tr>
|
|
109
|
+
</thead>
|
|
110
|
+
<tbody>
|
|
111
|
+
<tr>
|
|
112
|
+
<td><code>ms</code> (default)</td>
|
|
113
|
+
<td>Milliseconds</td>
|
|
114
|
+
</tr>
|
|
115
|
+
<tr>
|
|
116
|
+
<td><code>s</code> or <code>sec</code></td>
|
|
117
|
+
<td>Seconds</td>
|
|
118
|
+
</tr>
|
|
119
|
+
<tr>
|
|
120
|
+
<td><code>m</code> or <code>min</code></td>
|
|
121
|
+
<td>Mintun.</td>
|
|
122
|
+
</tr>
|
|
123
|
+
<tr>
|
|
124
|
+
<td><code>h</code></td>
|
|
125
|
+
<td>Hours</td>
|
|
126
|
+
</tr>
|
|
127
|
+
</tbody>
|
|
128
|
+
</table>
|
|
129
|
+
</p>
|
|
130
|
+
<p>
|
|
131
|
+
Specifying a time does not work with the topic <b>position</b>.
|
|
132
|
+
</p>
|
|
133
|
+
</script>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"shutter": {
|
|
3
|
+
"ui": {
|
|
4
|
+
"name": "Name",
|
|
5
|
+
"text": "Text",
|
|
6
|
+
"controlled_by_words": "This node can be controlled using the words entered. Multiple words are separated by a comma.",
|
|
7
|
+
"time_short": "Time short",
|
|
8
|
+
"controlled_by_central": "This module is controlled by the following central modules:"
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -153,6 +153,7 @@
|
|
|
153
153
|
oneditprepare: function ()
|
|
154
154
|
{
|
|
155
155
|
let node = this;
|
|
156
|
+
|
|
156
157
|
onEditPrepare(this, ["smart_central-control"]);
|
|
157
158
|
initTreeList(node, ["smart_central-control"]);
|
|
158
159
|
|
|
@@ -180,145 +181,18 @@
|
|
|
180
181
|
|
|
181
182
|
<script type="text/html" data-template-name="smart_shutter-control">
|
|
182
183
|
<div class="form-row">
|
|
183
|
-
<label for="node-input-name"><i class="fa fa-tag"></i>
|
|
184
|
-
<input type="text" id="node-input-name"
|
|
184
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="shutter.ui.name"></span></label>
|
|
185
|
+
<input type="text" id="node-input-name" data-i18n="[placeholder]shutter.ui.name" />
|
|
185
186
|
</div>
|
|
186
187
|
<div class="form-row">
|
|
187
|
-
<label for="node-input-exec_text_names"><i class="fa fa-comments-o"></i>
|
|
188
|
+
<label for="node-input-exec_text_names"><i class="fa fa-comments-o"></i> <span data-i18n="shutter.ui.text"></span></label>
|
|
188
189
|
<input id="node-input-exec_text_names" type="text" />
|
|
189
|
-
<div style="max-width: 450px;"
|
|
190
|
+
<div style="max-width: 450px;" data-i18n="shutter.ui.controlled_by_words"></div>
|
|
190
191
|
</div>
|
|
191
192
|
<div class="form-row">
|
|
192
|
-
<label for="node-input-short_time_on_ms"><i class="fa fa-clock-o"></i>
|
|
193
|
+
<label for="node-input-short_time_on_ms"><i class="fa fa-clock-o"></i> <span data-i18n="shutter.ui.time_short"></span></label>
|
|
193
194
|
<input id="node-input-short_time_on_ms" placeholder="200" /> ms
|
|
194
195
|
</div>
|
|
195
|
-
<span><i class="fa fa-link"></i>
|
|
196
|
+
<span><i class="fa fa-link"></i> <span data-i18n="shutter.ui.controlled_by_central"></span></span>
|
|
196
197
|
<div class="form-row node-input-link-row node-input-link-rows"></div>
|
|
197
|
-
</script>
|
|
198
|
-
|
|
199
|
-
<script type="text/html" data-help-name="smart_shutter-control">
|
|
200
|
-
<p>
|
|
201
|
-
<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/>
|
|
202
|
-
Diese Node verwendet nur den Teil <code>name</code>. <code>#</code> und <code>nummer</code> sind dabei optional.
|
|
203
|
-
</p>
|
|
204
|
-
<p>
|
|
205
|
-
Diese Node steuert Rollladen oder Jalousien.
|
|
206
|
-
Es gibt 3 Ausgänge die angesteuert werden können:
|
|
207
|
-
<ol>
|
|
208
|
-
<li><b>Auf/Ab:</b> <code>msg.payload = false</code> lässt den Rollladen nach oben fahren und <code>msg.payload = true</code> lässt den Rollladen nach unten fahren.</li>
|
|
209
|
-
<li><b>Stop:</b> <code>msg.payload = true</code> lässt den Rollladen stoppen.</li>
|
|
210
|
-
<li><b>Position:</b> <code>msg.payload = 42</code> Lässt den Rollladen auf 42% fahren.</li>
|
|
211
|
-
</ol>
|
|
212
|
-
Die Ausgänge sind den jeweiligen KNX Gruppenadressen zuzuordnen.
|
|
213
|
-
</p>
|
|
214
|
-
<p>
|
|
215
|
-
Diese Node erwartet folgende Topics als Eingang:<br/>
|
|
216
|
-
<table>
|
|
217
|
-
<thead>
|
|
218
|
-
<tr>
|
|
219
|
-
<th>Topic</th>
|
|
220
|
-
<th>Beschreibung</th>
|
|
221
|
-
<th>msg.payload == false wird ignoriert</th>
|
|
222
|
-
</tr>
|
|
223
|
-
</thead>
|
|
224
|
-
<tbody>
|
|
225
|
-
<tr>
|
|
226
|
-
<td><code>status</code> oder <code>status_position</code></td>
|
|
227
|
-
<td>
|
|
228
|
-
Meldet der Node die aktuelle Position.
|
|
229
|
-
Dadurch kann die Node feststellen in welche Richtung ein Rollladen als letztes gefahren ist.
|
|
230
|
-
Dies wird für das topic <b>toggle</b> benötigt um die nächste Laufrichtung bei einer 1-Tasten Bedienung zu ermitteln.
|
|
231
|
-
</td>
|
|
232
|
-
</tr>
|
|
233
|
-
<tr>
|
|
234
|
-
<td><code>up_down</code></td>
|
|
235
|
-
<td>
|
|
236
|
-
Nimmt einen Befehl von Home Assistant entgegen um informiert zu werden ob der Rollladen läuft und in welche Richtung.<br/>
|
|
237
|
-
<strong>Wichtig:</strong> Dieses Topic startet den Rollladen <u>nicht</u>, da die Gruppenadresse direkt mit dem Jalousiemodul verbunden sein muss.
|
|
238
|
-
</td>
|
|
239
|
-
<td>Nein</td>
|
|
240
|
-
</tr>
|
|
241
|
-
<tr>
|
|
242
|
-
<td><code>short_up_down</code></td>
|
|
243
|
-
<td>
|
|
244
|
-
Sendet bei <code>msg.payload = false</code> einen kurzen Hochfahrbefehl und bei <code>msg.payload = true</code> einen kurzen Runterfahrbefehl.<br/>
|
|
245
|
-
Es wird dabei die im Baustein hinterlegte Zeit verwendet. Diese kann aber durch setzen von <code>msg.time_on = 1500</code> oder <code>msg.time_on = "1.5s"</code> einmalig überschrieben werden.
|
|
246
|
-
</td>
|
|
247
|
-
<td>Nein</td>
|
|
248
|
-
</tr>
|
|
249
|
-
<tr>
|
|
250
|
-
<td><code>up</code></td>
|
|
251
|
-
<td>Sendet einen Hochfahrbefehl, falls der Rollladen nicht bereits nach oben fährt. Ggf. wird vorher noch ein Stop-Befehl gesendet.</td>
|
|
252
|
-
<td>Ja</td>
|
|
253
|
-
</tr>
|
|
254
|
-
<tr>
|
|
255
|
-
<td><code>up_stop</code></td>
|
|
256
|
-
<td>Sendet abwechselnd einen Stop- und einen Hochfahrbefehl.</td>
|
|
257
|
-
<td>Ja</td>
|
|
258
|
-
</tr>
|
|
259
|
-
<tr>
|
|
260
|
-
<td><code>down</code></td>
|
|
261
|
-
<td>Sendet einen Runterfahrbefehl, falls der Rollladen nicht bereits nach unten fährt. Ggf. wird vorher noch ein Stop-Befehl gesendet.</td>
|
|
262
|
-
<td>Ja</td>
|
|
263
|
-
</tr>
|
|
264
|
-
<tr>
|
|
265
|
-
<td><code>down_stop</code></td>
|
|
266
|
-
<td>Sendet abwechselnd einen Stop- und einen Runterfahrbefehl.</td>
|
|
267
|
-
<td>Ja</td>
|
|
268
|
-
</tr>
|
|
269
|
-
<tr>
|
|
270
|
-
<td><code>stop</code></td>
|
|
271
|
-
<td>Sendet einen Stopbefehl.</td>
|
|
272
|
-
<td>Ja</td>
|
|
273
|
-
</tr>
|
|
274
|
-
<tr>
|
|
275
|
-
<td><code>position</code></td>
|
|
276
|
-
<td>Sendet einen Positionsbefehl. <code>msg.payload</code> sollte ein Wert zwischen 0 (offen) und 100 (geschlossen) haben.</td>
|
|
277
|
-
<td>Nein</td>
|
|
278
|
-
</tr>
|
|
279
|
-
<tr>
|
|
280
|
-
<td><code>toggle</code> (default)</td>
|
|
281
|
-
<td>Schaltet den Rollladen abwechselnd auf hoch, stop, runter, stop.</td>
|
|
282
|
-
<td>Ja</td>
|
|
283
|
-
</tr>
|
|
284
|
-
</tbody>
|
|
285
|
-
</table>
|
|
286
|
-
</p>
|
|
287
|
-
<p>
|
|
288
|
-
Diese Node verwaltet keine Laufzeit für den Rollladen selbst. Diese muss über ETS für den Ausgang konfiguriert werden.
|
|
289
|
-
Es ist jedoch möglich, den Rollladen nach einer definierten Zeit automatisch abzuschalten.
|
|
290
|
-
Es ist jedoch möglich, den Rollladen nach einer definierten Zeit automatisch abzuschalten.
|
|
291
|
-
Beispiel: <code>msg = { "topic": "up", "time_on": 5000 }</code> oder <code>msg = { "topic": "up", "time_on": "5s" }</code><br/>
|
|
292
|
-
Diese Nachricht lässt den Rollladen für 5000 Millisekunden / 5 Sekunden nach oben fahren. Sollte es sich um eine Jalousie halten, werden die Lamellen entsprechend gedreht.
|
|
293
|
-
Als Einheit für die Zeit können folgende Werte verwendet werden:
|
|
294
|
-
<table>
|
|
295
|
-
<thead>
|
|
296
|
-
<tr>
|
|
297
|
-
<th>Einheit</th>
|
|
298
|
-
<th>Beschreibung</th>
|
|
299
|
-
</tr>
|
|
300
|
-
</thead>
|
|
301
|
-
<tbody>
|
|
302
|
-
<tr>
|
|
303
|
-
<td><code>ms</code> (default)</td>
|
|
304
|
-
<td>Millisekunden</td>
|
|
305
|
-
</tr>
|
|
306
|
-
<tr>
|
|
307
|
-
<td><code>s</code> oder <code>sec</code></td>
|
|
308
|
-
<td>Sekunden</td>
|
|
309
|
-
</tr>
|
|
310
|
-
<tr>
|
|
311
|
-
<td><code>m</code> oder <code>min</code></td>
|
|
312
|
-
<td>Mintun.</td>
|
|
313
|
-
</tr>
|
|
314
|
-
<tr>
|
|
315
|
-
<td><code>h</code></td>
|
|
316
|
-
<td>Stunden</td>
|
|
317
|
-
</tr>
|
|
318
|
-
</tbody>
|
|
319
|
-
</table>
|
|
320
|
-
</p>
|
|
321
|
-
<p>
|
|
322
|
-
Die Angabe einer Zeit funktioniert nicht mit dem topic <b>position</b>.
|
|
323
|
-
</p>
|
|
324
198
|
</script>
|
|
@@ -7,29 +7,57 @@ 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
|
-
|
|
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
|
-
|
|
20
|
-
|
|
30
|
+
|
|
31
|
+
// #####################
|
|
32
|
+
// # persistent values #
|
|
33
|
+
// #####################
|
|
34
|
+
var node_settings = helper.cloneObject({
|
|
21
35
|
last_position: 0, // 0 = opened, 100 = closed
|
|
22
36
|
last_direction_up: true, // remember last direction for toggle action
|
|
23
37
|
}, smart_context.get(node.id));
|
|
24
38
|
|
|
25
|
-
// dynamic config
|
|
26
|
-
let short_time_on_ms = config.short_time_on_ms || 200;
|
|
27
39
|
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
40
|
+
// ##################
|
|
41
|
+
// # Dynamic config #
|
|
42
|
+
// ##################
|
|
43
|
+
let short_time_on_ms = parseInt(config.short_time_on_ms || 200, 10);
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
// ##################
|
|
47
|
+
// # Runtime values #
|
|
48
|
+
// ##################
|
|
49
|
+
|
|
50
|
+
// Here the setTimeout return value is stored to stop the shutter.
|
|
51
|
+
// That means if it is null, the shutter is stopped.
|
|
52
|
+
let timeout = null;
|
|
53
|
+
|
|
54
|
+
// This is set to true if a command to start the shutter is recognized.
|
|
55
|
+
let is_running = false;
|
|
56
|
+
|
|
31
57
|
|
|
32
|
-
//
|
|
58
|
+
// #########################
|
|
59
|
+
// # Central node handling #
|
|
60
|
+
// #########################
|
|
33
61
|
var event = "node:" + config.id;
|
|
34
62
|
var handler = function (msg)
|
|
35
63
|
{
|
|
@@ -37,43 +65,58 @@ module.exports = function (RED)
|
|
|
37
65
|
}
|
|
38
66
|
RED.events.on(event, handler);
|
|
39
67
|
|
|
40
|
-
node.status({ fill: "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Stopped at " + Math.round(node_settings.last_position) + "%" });
|
|
41
68
|
|
|
69
|
+
// ###############
|
|
70
|
+
// # Node events #
|
|
71
|
+
// ###############
|
|
42
72
|
node.on("input", function (msg)
|
|
43
73
|
{
|
|
44
74
|
handleTopic(msg);
|
|
45
75
|
|
|
76
|
+
setStatus();
|
|
46
77
|
smart_context.set(node.id, node_settings);
|
|
47
78
|
});
|
|
48
79
|
|
|
49
80
|
node.on("close", function ()
|
|
50
81
|
{
|
|
51
|
-
|
|
82
|
+
startAction(ACTION_STOP);
|
|
52
83
|
RED.events.off(event, handler);
|
|
53
84
|
});
|
|
54
85
|
|
|
86
|
+
|
|
87
|
+
// #####################
|
|
88
|
+
// # Private functions #
|
|
89
|
+
// #####################
|
|
90
|
+
|
|
91
|
+
// This is the main function which handles all topics that was received.
|
|
55
92
|
let handleTopic = msg =>
|
|
56
93
|
{
|
|
94
|
+
helper.log("handle topic:");
|
|
95
|
+
helper.log(msg);
|
|
96
|
+
|
|
57
97
|
var resultUpDown = null;
|
|
58
98
|
var resultStop = null;
|
|
59
99
|
var resultPosition = null;
|
|
60
100
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
// set default topic
|
|
64
|
-
if (!["status", "status_position", "up_down", "up", "up_stop", "down", "down_stop", "stop", "toggle", "position", "short_up_down"].includes(real_topic))
|
|
65
|
-
real_topic = "toggle";
|
|
101
|
+
let real_topic = helper.getRealTopic(msg.topic, "toggle", ["status", "status_position", "up_down", "up", "up_stop", "down", "down_stop", "stop", "toggle", "position", "short_up_down"]);
|
|
66
102
|
|
|
67
103
|
// skip if button is released
|
|
68
104
|
if (msg.payload === false && ["up", "up_stop", "down", "down_stop", "stop", "toggle"].includes(real_topic))
|
|
69
105
|
return;
|
|
70
106
|
|
|
71
107
|
// Correct next topic to avoid handling up_stop, down_stop or toggle separately.
|
|
72
|
-
if (
|
|
108
|
+
if (real_topic == "short_up_down")
|
|
109
|
+
{
|
|
110
|
+
real_topic = msg.payload ? "down" : "up";
|
|
111
|
+
if (msg.time_on == null)
|
|
112
|
+
msg.time_on = short_time_on_ms;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if ((timeout != null || is_running) && (real_topic == "up_stop" || real_topic == "down_stop" || real_topic == "toggle"))
|
|
73
116
|
{
|
|
74
117
|
real_topic = "stop";
|
|
75
118
|
}
|
|
76
|
-
else if (
|
|
119
|
+
else if (timeout == null && !is_running)
|
|
77
120
|
{
|
|
78
121
|
// shutter is not running, set next command depending on topic
|
|
79
122
|
if (real_topic == "up_stop")
|
|
@@ -86,7 +129,7 @@ module.exports = function (RED)
|
|
|
86
129
|
real_topic = "up";
|
|
87
130
|
}
|
|
88
131
|
|
|
89
|
-
|
|
132
|
+
helper.log("handle real topic: " + real_topic);
|
|
90
133
|
switch (real_topic)
|
|
91
134
|
{
|
|
92
135
|
case "status":
|
|
@@ -96,30 +139,18 @@ module.exports = function (RED)
|
|
|
96
139
|
|
|
97
140
|
if (is_running && (msg.payload == 0 || msg.payload == 100))
|
|
98
141
|
is_running = false;
|
|
99
|
-
|
|
100
|
-
node.status({ fill: "yellow", shape: "ring", text: helper.getCurrentTimeForStatus() + ": Position status received: " + msg.payload + "%" });
|
|
101
142
|
return;
|
|
102
143
|
|
|
103
|
-
// This is only used to track starting of the shutter
|
|
104
144
|
case "up_down":
|
|
145
|
+
// This is only used to track starting of the shutter
|
|
105
146
|
node_settings.last_direction_up = !msg.payload;
|
|
106
147
|
is_running = true;
|
|
107
|
-
|
|
108
|
-
if (node_settings.last_direction_up)
|
|
109
|
-
node.status({ fill: "green", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Up" });
|
|
110
|
-
else
|
|
111
|
-
node.status({ fill: "green", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Down" });
|
|
112
|
-
return;
|
|
113
|
-
|
|
114
|
-
case "short_up_down":
|
|
115
|
-
handleTopic({ topic: msg.payload ? "down" : "up", time_on: msg.time_on ?? short_time_on_ms });
|
|
116
148
|
return;
|
|
117
149
|
|
|
118
150
|
case "up":
|
|
119
151
|
node_settings.last_direction_up = true;
|
|
120
152
|
is_running = true;
|
|
121
153
|
resultUpDown = false;
|
|
122
|
-
node.status({ fill: "green", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Up" });
|
|
123
154
|
startAutoOffIfNeeded(msg);
|
|
124
155
|
break;
|
|
125
156
|
|
|
@@ -127,14 +158,12 @@ module.exports = function (RED)
|
|
|
127
158
|
is_running = false;
|
|
128
159
|
resultStop = true;
|
|
129
160
|
stopAutoOff();
|
|
130
|
-
node.status({ fill: "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Stopped" });
|
|
131
161
|
break;
|
|
132
162
|
|
|
133
163
|
case "down":
|
|
134
164
|
node_settings.last_direction_up = false;
|
|
135
165
|
is_running = true;
|
|
136
166
|
resultUpDown = true;
|
|
137
|
-
node.status({ fill: "green", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Down" });
|
|
138
167
|
startAutoOffIfNeeded(msg);
|
|
139
168
|
break;
|
|
140
169
|
|
|
@@ -145,67 +174,98 @@ module.exports = function (RED)
|
|
|
145
174
|
if (value > 100) value = 100;
|
|
146
175
|
// is_running = true; // Not guaranteed that the shutter starts running.
|
|
147
176
|
resultPosition = value;
|
|
148
|
-
node.status({ fill: "green", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Set position to " + value + "%" });
|
|
149
177
|
break;
|
|
150
178
|
}
|
|
151
179
|
|
|
152
180
|
if (resultUpDown != null)
|
|
153
181
|
{
|
|
154
|
-
node.send([{ payload: resultUpDown
|
|
182
|
+
node.send([{ payload: resultUpDown }, null, null]);
|
|
155
183
|
notifyCentral(true);
|
|
156
184
|
}
|
|
157
185
|
else if (resultStop != null)
|
|
158
186
|
{
|
|
159
|
-
node.send([null, { payload: resultStop
|
|
187
|
+
node.send([null, { payload: resultStop }, null]);
|
|
160
188
|
notifyCentral(false);
|
|
161
189
|
}
|
|
162
190
|
else if (resultPosition != null)
|
|
163
191
|
{
|
|
164
|
-
node.send([null, null, { payload: resultPosition
|
|
192
|
+
node.send([null, null, { payload: resultPosition }]);
|
|
165
193
|
}
|
|
166
194
|
};
|
|
167
195
|
|
|
196
|
+
/**
|
|
197
|
+
* This function sets a timeout to stop the shutter after the defined time is over.
|
|
198
|
+
* @param {*} msg The original message object
|
|
199
|
+
*/
|
|
168
200
|
let startAutoOffIfNeeded = msg =>
|
|
169
201
|
{
|
|
170
|
-
if (
|
|
202
|
+
if (msg.time_on == null || msg.time_on == 0)
|
|
171
203
|
return;
|
|
172
204
|
|
|
205
|
+
// calculate needed time
|
|
173
206
|
let timeMs = helper.getTimeInMsFromString(msg.time_on);
|
|
174
|
-
if (isNaN(timeMs))
|
|
207
|
+
if (isNaN(timeMs) || timeMs <= 0)
|
|
175
208
|
{
|
|
176
|
-
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (timeMs <= 0)
|
|
181
|
-
{
|
|
182
|
-
node.status({ fill: "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": time_on value has to be greater than 0" });
|
|
209
|
+
console.warn("Invalid msg.time_on value was sent.", msg);
|
|
183
210
|
return;
|
|
184
211
|
}
|
|
185
212
|
|
|
186
213
|
// Stop if any timeout is set
|
|
187
214
|
stopAutoOff();
|
|
188
215
|
|
|
189
|
-
|
|
190
|
-
max_time_on_timeout = setTimeout(() =>
|
|
216
|
+
timeout = setTimeout(() =>
|
|
191
217
|
{
|
|
192
|
-
node.status({ fill: "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Stopped" });
|
|
193
218
|
is_running = false;
|
|
219
|
+
timeout = null;
|
|
220
|
+
|
|
194
221
|
node.send([null, { payload: true }, null]);
|
|
195
222
|
notifyCentral(false);
|
|
223
|
+
|
|
224
|
+
smart_context.set(node.id, node_settings);
|
|
225
|
+
|
|
226
|
+
setStatus();
|
|
196
227
|
}, timeMs);
|
|
197
228
|
};
|
|
198
229
|
|
|
230
|
+
/**
|
|
231
|
+
* Stops the current running timeout
|
|
232
|
+
*/
|
|
199
233
|
let stopAutoOff = () =>
|
|
200
234
|
{
|
|
201
|
-
if (
|
|
235
|
+
if (timeout != null)
|
|
202
236
|
{
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
max_time_on_timeout = null;
|
|
237
|
+
clearTimeout(timeout);
|
|
238
|
+
timeout = null;
|
|
206
239
|
}
|
|
207
240
|
};
|
|
208
241
|
|
|
242
|
+
/**
|
|
243
|
+
* Set the current node status
|
|
244
|
+
*/
|
|
245
|
+
let setStatus = () =>
|
|
246
|
+
{
|
|
247
|
+
let fill = "green";
|
|
248
|
+
let shape = (timeout != null || is_running) ? "ring" : "dot";
|
|
249
|
+
|
|
250
|
+
// collect all texts and join later with a comma
|
|
251
|
+
let texts = [];
|
|
252
|
+
|
|
253
|
+
if (timeout == null && !is_running)
|
|
254
|
+
texts.push("Stopped");
|
|
255
|
+
else if (node_settings.last_direction_up)
|
|
256
|
+
texts.push("Up");
|
|
257
|
+
else
|
|
258
|
+
texts.push("Down");
|
|
259
|
+
|
|
260
|
+
texts.push("Position: " + node_settings.last_position?.toFixed(0) + "%");
|
|
261
|
+
|
|
262
|
+
node.status({ fill, shape, text: helper.getCurrentTimeForStatus() + ": " + texts.join(", ") });
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Notify all connected central nodes
|
|
267
|
+
* @param {boolean} state The state if the shutter is running
|
|
268
|
+
*/
|
|
209
269
|
let notifyCentral = state =>
|
|
210
270
|
{
|
|
211
271
|
if (!config.links)
|
|
@@ -213,8 +273,8 @@ module.exports = function (RED)
|
|
|
213
273
|
|
|
214
274
|
config.links.forEach(link =>
|
|
215
275
|
{
|
|
216
|
-
|
|
217
|
-
|
|
276
|
+
helper.log(node.id + " -> " + link);
|
|
277
|
+
helper.log({ source: node.id, state: state });
|
|
218
278
|
RED.events.emit("node:" + link, { source: node.id, state: state });
|
|
219
279
|
});
|
|
220
280
|
};
|