smart-nodes 0.3.37 → 0.4.1
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 +67 -0
- package/README.md +35 -17
- package/central/central.html +26 -12
- package/central/central.js +84 -26
- package/central/locales/de-DE/central.json +1 -4
- package/central/locales/en-US/central.json +0 -3
- package/compare/compare.html +40 -24
- package/compare/compare.js +69 -29
- package/compare/locales/de-DE/compare.json +5 -7
- package/compare/locales/en-US/compare.json +18 -8
- package/counter/counter.html +64 -17
- package/counter/counter.js +43 -20
- package/counter/locales/de-DE/counter.json +6 -9
- package/counter/locales/en-US/counter.json +12 -16
- package/delay/delay.html +18 -88
- 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 +39 -14
- 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 +43 -65
- package/hysteresis/hysteresis.js +94 -69
- 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-control/light-control.html → light/light.html} +34 -144
- 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 +27 -40
- 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 +15 -79
- 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} +18 -121
- 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} +30 -133
- package/shutter-complex/shutter-complex.js +578 -0
- package/smart_helper.js +61 -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 +32 -36
- package/statistic/statistic.js +58 -29
- 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/long-press-control/long-press-control.js +0 -76
- package/shutter-complex-control/shutter-complex-control.js +0 -442
package/logic/logic.js
CHANGED
|
@@ -7,28 +7,38 @@ 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
|
+
// # persistent values #
|
|
24
|
+
// #####################
|
|
14
25
|
var node_settings = {
|
|
15
26
|
input_states: Array.from({ length: config.logic_inputs }).fill(false),
|
|
16
27
|
last_result: null,
|
|
17
28
|
last_message: null,
|
|
18
29
|
};
|
|
19
30
|
|
|
31
|
+
|
|
32
|
+
// load or delete saved values
|
|
20
33
|
if (config.save_state)
|
|
21
|
-
{
|
|
22
|
-
// load old saved values
|
|
23
34
|
node_settings = Object.assign(node_settings, smart_context.get(node.id));
|
|
24
|
-
}
|
|
25
35
|
else
|
|
26
|
-
{
|
|
27
|
-
// delete old saved values
|
|
28
36
|
smart_context.del(node.id);
|
|
29
|
-
}
|
|
30
37
|
|
|
31
|
-
|
|
38
|
+
|
|
39
|
+
// ##################
|
|
40
|
+
// # Dynamic config #
|
|
41
|
+
// ##################
|
|
32
42
|
let logic = config.logic;
|
|
33
43
|
let out_true = helper.evaluateNodeProperty(RED, config.out_true, config.out_true_type || "json");
|
|
34
44
|
let out_false = helper.evaluateNodeProperty(RED, config.out_false, config.out_false_type || "json");
|
|
@@ -38,29 +48,59 @@ module.exports = function (RED)
|
|
|
38
48
|
let send_only_change = helper.evaluateNodeProperty(RED, config.send_only_change, "bool");
|
|
39
49
|
let outputs = helper.evaluateNodeProperty(RED, config.outputs, "num");
|
|
40
50
|
|
|
41
|
-
// runtime values
|
|
42
51
|
|
|
52
|
+
// ##################
|
|
53
|
+
// # Runtime values #
|
|
54
|
+
// ##################
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
// ###############
|
|
58
|
+
// # Node events #
|
|
59
|
+
// ###############
|
|
43
60
|
node.on("input", function (msg)
|
|
44
61
|
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
62
|
+
handleTopic(msg);
|
|
63
|
+
|
|
64
|
+
setStatus();
|
|
65
|
+
|
|
66
|
+
if (config.save_state)
|
|
67
|
+
smart_context.set(node.id, node_settings);
|
|
68
|
+
});
|
|
51
69
|
|
|
52
|
-
|
|
70
|
+
node.on("close", function ()
|
|
71
|
+
{
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
// #####################
|
|
76
|
+
// # Private functions #
|
|
77
|
+
// #####################
|
|
78
|
+
|
|
79
|
+
// This is the main function which handles all topics that was received.
|
|
80
|
+
let handleTopic = msg =>
|
|
81
|
+
{
|
|
82
|
+
helper.log("handle topic:");
|
|
83
|
+
helper.log(msg);
|
|
84
|
+
|
|
85
|
+
let real_topic_number = helper.getTopicNumber(msg.topic);
|
|
86
|
+
|
|
87
|
+
if (real_topic_number == null || real_topic_number < 1 || real_topic_number > logic_inputs)
|
|
53
88
|
{
|
|
54
89
|
node.error("Topic has to be >= 1 and <= " + logic_inputs + ", send: " + msg.topic);
|
|
55
90
|
return;
|
|
56
91
|
}
|
|
57
92
|
|
|
58
|
-
if (inverts.includes(
|
|
59
|
-
node_settings.input_states[
|
|
93
|
+
if (inverts.includes(real_topic_number))
|
|
94
|
+
node_settings.input_states[real_topic_number - 1] = !msg.payload;
|
|
60
95
|
else
|
|
61
|
-
node_settings.input_states[
|
|
96
|
+
node_settings.input_states[real_topic_number - 1] = !!msg.payload; // !! => Convert to boolean
|
|
62
97
|
|
|
63
98
|
let result = getResult();
|
|
99
|
+
|
|
100
|
+
helper.log("getResult:");
|
|
101
|
+
helper.log(result);
|
|
102
|
+
helper.log(node_settings);
|
|
103
|
+
|
|
64
104
|
let out_msg = null;
|
|
65
105
|
|
|
66
106
|
setStatus();
|
|
@@ -72,12 +112,12 @@ module.exports = function (RED)
|
|
|
72
112
|
if (result)
|
|
73
113
|
{
|
|
74
114
|
if (out_true !== null)
|
|
75
|
-
out_msg =
|
|
115
|
+
out_msg = helper.cloneObject(out_true);
|
|
76
116
|
}
|
|
77
117
|
else
|
|
78
118
|
{
|
|
79
119
|
if (out_false !== null)
|
|
80
|
-
out_msg =
|
|
120
|
+
out_msg = helper.cloneObject(out_false);
|
|
81
121
|
}
|
|
82
122
|
|
|
83
123
|
if (out_msg !== null)
|
|
@@ -103,13 +143,7 @@ module.exports = function (RED)
|
|
|
103
143
|
node_settings.last_result = result;
|
|
104
144
|
node_settings.last_message = out_msg;
|
|
105
145
|
|
|
106
|
-
|
|
107
|
-
smart_context.set(node.id, node_settings);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
node.on("close", function ()
|
|
111
|
-
{
|
|
112
|
-
});
|
|
146
|
+
}
|
|
113
147
|
|
|
114
148
|
let getResult = () =>
|
|
115
149
|
{
|
|
@@ -187,7 +221,7 @@ module.exports = function (RED)
|
|
|
187
221
|
{
|
|
188
222
|
setTimeout(() =>
|
|
189
223
|
{
|
|
190
|
-
node.send(node_settings.last_message);
|
|
224
|
+
node.send(helper.cloneObject(node_settings.last_message));
|
|
191
225
|
}, 10000);
|
|
192
226
|
}
|
|
193
227
|
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<script type="text/html" data-help-name="smart_long-press-control">
|
|
2
|
+
<p>Diese Node kann unterscheiden, wie lange ein Taster gedrückt wurde. Die Zeit, ab wann ein Tastendruck als lang gilt, kann in den Eigenschaften der Node eingestellt werden.</p>
|
|
3
|
+
<p>Ein langer Tastendruck wird sofort ausgelöst, wenn die maximal Zeit überschritten wurde.</p>
|
|
4
|
+
<p>Die Node misst die Zeit zwischen <code>msg.payload = true;</code> und <code>msg.payload = false;</code> und gibt eine entsprechende Nachricht aus.</p>
|
|
5
|
+
</script>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"long-press": {
|
|
3
|
+
"ui": {
|
|
4
|
+
"name": "Name",
|
|
5
|
+
"time_for_long": "Zeit für lang",
|
|
6
|
+
"time_for_long_placeholder": "Zeit in ms für einen langen Druck",
|
|
7
|
+
"milliseconds": "Millisekunden",
|
|
8
|
+
"output_messages": "Ausgangsnachrichten",
|
|
9
|
+
"short": "Kurz",
|
|
10
|
+
"long": "Lang"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<script type="text/html" data-help-name="smart_long-press-control">
|
|
2
|
+
<p>This node can distinguish how long a button has been pressed. The time from which a button press is considered long can be set in the properties of the node.</p>
|
|
3
|
+
<p>A long button press is triggered immediately if the maximum time has been exceeded.</p>
|
|
4
|
+
<p>The node measures the time between <code>msg.payload = true;</code> and <code>msg.payload = false;</code> and outputs a corresponding message.</p>
|
|
5
|
+
</script>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"long-press": {
|
|
3
|
+
"ui": {
|
|
4
|
+
"name": "Name",
|
|
5
|
+
"time_for_long": "Time for long",
|
|
6
|
+
"time_for_long_placeholder": "Time in ms for a long press",
|
|
7
|
+
"milliseconds": "Milliseconds",
|
|
8
|
+
"output_messages": "Output messages",
|
|
9
|
+
"short": "Short",
|
|
10
|
+
"long": "Long"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
},
|
|
20
20
|
oneditprepare: function ()
|
|
21
21
|
{
|
|
22
|
+
let node = this;
|
|
23
|
+
|
|
22
24
|
$("#node-input-long_press_ms").spinner({
|
|
23
25
|
min: 1,
|
|
24
26
|
change: function (event, ui)
|
|
@@ -47,28 +49,22 @@
|
|
|
47
49
|
|
|
48
50
|
<script type="text/html" data-template-name="smart_long-press-control">
|
|
49
51
|
<div class="form-row">
|
|
50
|
-
<label for="node-input-name"><i class="fa fa-tag"></i>
|
|
51
|
-
<input type="text" id="node-input-name"
|
|
52
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="long-press.ui.name"></span></label>
|
|
53
|
+
<input type="text" id="node-input-name" data-i18n="[placeholder]long-press.ui.name" />
|
|
52
54
|
</div>
|
|
53
55
|
<div class="form-row">
|
|
54
|
-
<label for="node-input-long_press_ms"><i class="fa fa-clock-o"></i
|
|
55
|
-
<input id="node-input-long_press_ms"
|
|
56
|
-
<span
|
|
56
|
+
<label for="node-input-long_press_ms"><i class="fa fa-clock-o"></i><span data-i18n="long-press.ui.time_for_long"></span></label>
|
|
57
|
+
<input id="node-input-long_press_ms" data-i18n="[placeholder]long-press.ui.time_for_long_placeholder" />
|
|
58
|
+
<span data-i18n="long-press.ui.milliseconds"></span>
|
|
57
59
|
</div>
|
|
58
60
|
<hr/>
|
|
59
|
-
<h4 style="margin: 0.5rem 0;"
|
|
61
|
+
<h4 style="margin: 0.5rem 0;" data-i18n="long-press.ui.output_messages"></h4>
|
|
60
62
|
<div class="form-row">
|
|
61
|
-
<label for="node-input-short"><i class="fa fa-hand-o-up"></i>
|
|
63
|
+
<label for="node-input-short"><i class="fa fa-hand-o-up"></i> <span data-i18n="long-press.ui.short"></span></label>
|
|
62
64
|
<input type="text" id="node-input-short" />
|
|
63
65
|
</div>
|
|
64
66
|
<div class="form-row">
|
|
65
|
-
<label for="node-input-long"><i class="fa fa-hand-o-up"></i>
|
|
67
|
+
<label for="node-input-long"><i class="fa fa-hand-o-up"></i> <span data-i18n="long-press.ui.long"></span></label>
|
|
66
68
|
<input type="text" id="node-input-long" />
|
|
67
69
|
</div>
|
|
68
|
-
</script>
|
|
69
|
-
|
|
70
|
-
<script type="text/html" data-help-name="smart_long-press-control">
|
|
71
|
-
<p>Diese Node kann unterscheiden, wie lange ein Taster gedrückt wurde. Die Zeit, ab wann ein Tastendruck als lang gilt, kann in den Eigenschaften der Node eingestellt werden.</p>
|
|
72
|
-
<p>Ein langer Tastendruck wird sofort ausgelöst, wenn die maximal Zeit überschritten wurde.</p>
|
|
73
|
-
<p>Die Node misst die Zeit zwischen <code>msg.payload = true;</code> und <code>msg.payload = false;</code> und gibt eine entsprechende Nachricht aus.</p>
|
|
74
70
|
</script>
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
module.exports = function (RED)
|
|
2
|
+
{
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
function LongPressControlNode(config)
|
|
6
|
+
{
|
|
7
|
+
const node = this;
|
|
8
|
+
RED.nodes.createNode(node, config);
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
// ###################
|
|
12
|
+
// # Class constants #
|
|
13
|
+
// ###################
|
|
14
|
+
const ACTION_SHORT = 0;
|
|
15
|
+
const ACTION_LONG = 1;
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
// #######################
|
|
19
|
+
// # Global help objects #
|
|
20
|
+
// #######################
|
|
21
|
+
const smart_context = require("../persistence.js")(RED);
|
|
22
|
+
const helper = require("../smart_helper.js");
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
// ##################
|
|
26
|
+
// # Dynamic config #
|
|
27
|
+
// ##################
|
|
28
|
+
let long_press_ms = parseInt(config.long_press_ms || 1000, 10);
|
|
29
|
+
let short = helper.evaluateNodeProperty(RED, config.short, "json");
|
|
30
|
+
let long = helper.evaluateNodeProperty(RED, config.long, "json");
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
// ##################
|
|
34
|
+
// # Runtime values #
|
|
35
|
+
// ##################
|
|
36
|
+
|
|
37
|
+
// The date when the button was pressed
|
|
38
|
+
let on_time = null;
|
|
39
|
+
|
|
40
|
+
// Here the setTimeout return value is stored to detect a long press.
|
|
41
|
+
let timeout = null;
|
|
42
|
+
|
|
43
|
+
// Save the last state of the long press, this isn't needed as persistant value
|
|
44
|
+
let last_action = null;
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
// ###############
|
|
48
|
+
// # Node events #
|
|
49
|
+
// ###############
|
|
50
|
+
node.on("input", function (msg)
|
|
51
|
+
{
|
|
52
|
+
handleTopic(msg);
|
|
53
|
+
|
|
54
|
+
setStatus();
|
|
55
|
+
// smart_context.set(node.id, node_settings);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
node.on("close", function ()
|
|
59
|
+
{
|
|
60
|
+
stopAutoOff();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// #####################
|
|
64
|
+
// # Private functions #
|
|
65
|
+
// #####################
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* This is the main function which handles all topics that was received.
|
|
69
|
+
*/
|
|
70
|
+
let handleTopic = msg =>
|
|
71
|
+
{
|
|
72
|
+
if (msg.payload)
|
|
73
|
+
{
|
|
74
|
+
on_time = Date.now();
|
|
75
|
+
startAutoLongPress();
|
|
76
|
+
}
|
|
77
|
+
else if (on_time != null)
|
|
78
|
+
{
|
|
79
|
+
const pressTime = Date.now() - on_time;
|
|
80
|
+
on_time = null;
|
|
81
|
+
|
|
82
|
+
// Stop if any timeout is set
|
|
83
|
+
stopAutoOff();
|
|
84
|
+
|
|
85
|
+
if (pressTime < long_press_ms)
|
|
86
|
+
{
|
|
87
|
+
last_action = ACTION_SHORT;
|
|
88
|
+
if (short != null)
|
|
89
|
+
node.send([helper.cloneObject(short), null]);
|
|
90
|
+
}
|
|
91
|
+
else
|
|
92
|
+
{
|
|
93
|
+
last_action = ACTION_LONG;
|
|
94
|
+
if (long != null)
|
|
95
|
+
node.send([null, helper.cloneObject(long)]);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Start timer to detect a long press
|
|
102
|
+
*/
|
|
103
|
+
let startAutoLongPress = () =>
|
|
104
|
+
{
|
|
105
|
+
stopAutoOff();
|
|
106
|
+
timeout = setTimeout(() =>
|
|
107
|
+
{
|
|
108
|
+
last_action = ACTION_LONG;
|
|
109
|
+
on_time = null;
|
|
110
|
+
timeout = null;
|
|
111
|
+
|
|
112
|
+
node.send([null, helper.cloneObject(long)]);
|
|
113
|
+
|
|
114
|
+
setStatus();
|
|
115
|
+
}, long_press_ms);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Stop current runnting timer
|
|
120
|
+
*/
|
|
121
|
+
let stopAutoOff = () =>
|
|
122
|
+
{
|
|
123
|
+
if (timeout != null)
|
|
124
|
+
{
|
|
125
|
+
clearTimeout(timeout);
|
|
126
|
+
timeout = null;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Set the current node status
|
|
133
|
+
*/
|
|
134
|
+
let setStatus = () =>
|
|
135
|
+
{
|
|
136
|
+
if (timeout != null)
|
|
137
|
+
{
|
|
138
|
+
node.status({ fill: "yellow", shape: "ring", text: helper.getCurrentTimeForStatus() + ": Wait for button release..." });
|
|
139
|
+
}
|
|
140
|
+
else
|
|
141
|
+
{
|
|
142
|
+
switch (last_action)
|
|
143
|
+
{
|
|
144
|
+
case ACTION_SHORT:
|
|
145
|
+
node.status({ fill: "green", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Last was short" });
|
|
146
|
+
break;
|
|
147
|
+
|
|
148
|
+
case ACTION_LONG:
|
|
149
|
+
node.status({ fill: "green", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Last was long" });
|
|
150
|
+
break;
|
|
151
|
+
|
|
152
|
+
default:
|
|
153
|
+
case null:
|
|
154
|
+
node.status({});
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
RED.nodes.registerType("smart_long-press-control", LongPressControlNode);
|
|
163
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script type="text/html" data-help-name="smart_mixing-valve">
|
|
2
|
+
<p>
|
|
3
|
+
Diese Node steuert einen Heizungsmischer. Dieser kann sowohl fürs Heizen als auch fürs Kühlen verwendet werden.
|
|
4
|
+
Nach der eingestellten Abtastzeit wird geprüft, ob die Position des Mischers korrigiert werden muss.
|
|
5
|
+
</p>
|
|
6
|
+
<p>
|
|
7
|
+
Beim ersten Verwenden wird eine Kalibrierungsfahrt gestartet. D.h. der Mischer schließt für die eingestellte Laufzeit und befindet sich dann auf 0%.
|
|
8
|
+
Danach kann der Mischvorgang starten. Die zuletzt angefahrene Position wird persistent gespeichert, wodurch weitere Kalibrierungsfahrten in der Regel nicht mehr notwending sind.
|
|
9
|
+
</p>
|
|
10
|
+
<p>
|
|
11
|
+
<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/>
|
|
12
|
+
Diese Node verwendet nur den Teil <code>name</code>. <code>#</code> und <code>nummer</code> sind dabei optional.
|
|
13
|
+
</p>
|
|
14
|
+
<p>
|
|
15
|
+
Folgende topics werden akzeptiert:
|
|
16
|
+
<table>
|
|
17
|
+
<thead>
|
|
18
|
+
<tr>
|
|
19
|
+
<th>Topic</th>
|
|
20
|
+
<th>Beschreibung</th>
|
|
21
|
+
</tr>
|
|
22
|
+
</thead>
|
|
23
|
+
<tbody>
|
|
24
|
+
<tr>
|
|
25
|
+
<td><code>enable</code></td>
|
|
26
|
+
<td>Aktiviert die Mischeransteuerung.</td>
|
|
27
|
+
</tr>
|
|
28
|
+
<tr>
|
|
29
|
+
<td><code>disable</code></td>
|
|
30
|
+
<td>Deaktiviert die Mischeransteuerung und fährt die Position an, die als Aus-Modus festgelegt ist.</td>
|
|
31
|
+
</tr>
|
|
32
|
+
<tr>
|
|
33
|
+
<td><code>set_state</code></td>
|
|
34
|
+
<td>Aktiviert das Weiterleiten, wenn <code>msg.payload = true</code> oder deaktiviert das Weiterleiten, wenn <code>msg.payload = false</code>.</td>
|
|
35
|
+
</tr>
|
|
36
|
+
<tr>
|
|
37
|
+
<td><code>setpoint</code></td>
|
|
38
|
+
<td>Überschreibt den Sollwert mit <code>msg.payload</code> °C.</td>
|
|
39
|
+
</tr>
|
|
40
|
+
<tr>
|
|
41
|
+
<td><code>off_mode</code></td>
|
|
42
|
+
<td>
|
|
43
|
+
Überschreibt den Aus-Modus mit <code>msg.payload</code>.
|
|
44
|
+
Gültige Werte für <code>msg.payload</code> sind <code>"NOTHING"</code>, <code>"OPEN"</code> und <code>"CLOSE"</code>.
|
|
45
|
+
</td>
|
|
46
|
+
</tr>
|
|
47
|
+
<tr>
|
|
48
|
+
<td><code>valve_mode</code></td>
|
|
49
|
+
<td>
|
|
50
|
+
Überschreibt den Modus mit <code>msg.payload</code>.
|
|
51
|
+
Gültige Werte für <code>msg.payload</code> sind <code>"HEATING"</code> und <code>"COOLING"</code>.
|
|
52
|
+
</td>
|
|
53
|
+
</tr>
|
|
54
|
+
<tr>
|
|
55
|
+
<td><code>current_temperature</code></td>
|
|
56
|
+
<td>Setzt die aktuelle Temperatur auf <code>msg.payload</code> °C.</td>
|
|
57
|
+
</tr>
|
|
58
|
+
<tr>
|
|
59
|
+
<td><code>calibrate</code></td>
|
|
60
|
+
<td>Erzwingt eine Kalibrierungsfahrt.</td>
|
|
61
|
+
</tr>
|
|
62
|
+
</tbody>
|
|
63
|
+
</table>
|
|
64
|
+
</p>
|
|
65
|
+
</script>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mixing-valve": {
|
|
3
|
+
"ui": {
|
|
4
|
+
"name": "Name",
|
|
5
|
+
"enabled": "Aktiviert",
|
|
6
|
+
"setpoint": "Sollwert",
|
|
7
|
+
"runtime": "Laufzeit",
|
|
8
|
+
"sampling": "Abtastzeit",
|
|
9
|
+
"power_off": "Aus-Modus",
|
|
10
|
+
"mode": "Modus",
|
|
11
|
+
|
|
12
|
+
"nothing": "Nichts",
|
|
13
|
+
"open": "Öffnen (100%)",
|
|
14
|
+
"close": "Schließen (0%)",
|
|
15
|
+
"heating": "Heizen (normal)",
|
|
16
|
+
"cooling": "Kühlen (invertiert)"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<script type="text/html" data-help-name="smart_mixing-valve">
|
|
2
|
+
<p>
|
|
3
|
+
This node controls a heating mixer. This can be used for both heating and cooling.
|
|
4
|
+
After the set sampling time, a check is made to see whether the position of the mixer needs to be corrected.
|
|
5
|
+
</p>
|
|
6
|
+
<p>
|
|
7
|
+
When used for the first time, a calibration run is started. This means that the mixer closes for the set running time and is then at 0%.
|
|
8
|
+
The mixing process can then start. The last position reached is saved persistently, which means that further calibration runs are generally no longer necessary.
|
|
9
|
+
</p>
|
|
10
|
+
<p>
|
|
11
|
+
<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 />
|
|
12
|
+
This node only uses the <code>name</code> part. <code>#</code> and <code>number</code> are optional.
|
|
13
|
+
</p>
|
|
14
|
+
<p>
|
|
15
|
+
The following topics are accepted:
|
|
16
|
+
<table>
|
|
17
|
+
<thead>
|
|
18
|
+
<tr>
|
|
19
|
+
<th>Topic</th>
|
|
20
|
+
<th>Description</th>
|
|
21
|
+
</tr>
|
|
22
|
+
</thead>
|
|
23
|
+
<tbody>
|
|
24
|
+
<tr>
|
|
25
|
+
<td><code>enable</code></td>
|
|
26
|
+
<td>Activates the mixer control.</td>
|
|
27
|
+
</tr>
|
|
28
|
+
<tr>
|
|
29
|
+
<td><code>disable</code></td>
|
|
30
|
+
<td>Deactivates the mixer control and moves to the position that is set as the off mode.</td>
|
|
31
|
+
</tr>
|
|
32
|
+
<tr>
|
|
33
|
+
<td><code>set_state</code></td>
|
|
34
|
+
<td>Activates forwarding if <code>msg.payload = true</code> or deactivates forwarding if
|
|
35
|
+
<code>msg.payload = false</code>.</td>
|
|
36
|
+
</tr>
|
|
37
|
+
<tr>
|
|
38
|
+
<td><code>setpoint</code></td>
|
|
39
|
+
<td>Overrides the setpoint with <code>msg.payload</code> °C.</td>
|
|
40
|
+
</tr>
|
|
41
|
+
<tr>
|
|
42
|
+
<td><code>off_mode</code></td>
|
|
43
|
+
<td>
|
|
44
|
+
Overrides the off mode with <code>msg.payload</code>.
|
|
45
|
+
Valid values for <code>msg.payload</code> are <code>"NOTHING"</code>, <code>"OPEN"</code> and <code>"CLOSE"</code>.
|
|
46
|
+
</td>
|
|
47
|
+
</tr>
|
|
48
|
+
<tr>
|
|
49
|
+
<td><code>valve_mode</code></td>
|
|
50
|
+
<td>
|
|
51
|
+
Overrides the mode with <code>msg.payload</code>.
|
|
52
|
+
Valid values for <code>msg.payload</code> are <code>"HEATING"</code> and <code>"COOLING"</code>.
|
|
53
|
+
</td>
|
|
54
|
+
</tr>
|
|
55
|
+
<tr>
|
|
56
|
+
<td><code>current_temperature</code></td>
|
|
57
|
+
<td>Sets the current temperature to <code>msg.payload</code> °C.</td>
|
|
58
|
+
</tr>
|
|
59
|
+
<tr>
|
|
60
|
+
<td><code>calibrate</code></td>
|
|
61
|
+
<td>Forces a calibration run.</td>
|
|
62
|
+
</tr>
|
|
63
|
+
</tbody>
|
|
64
|
+
</table>
|
|
65
|
+
</p>
|
|
66
|
+
</script>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mixing-valve": {
|
|
3
|
+
"ui": {
|
|
4
|
+
"name": "Name",
|
|
5
|
+
"enabled": "Enabled",
|
|
6
|
+
"setpoint": "Setpoint",
|
|
7
|
+
"runtime": "Runtime",
|
|
8
|
+
"sampling": "Sampling",
|
|
9
|
+
"power_off": "Off mode",
|
|
10
|
+
"mode": "Mode",
|
|
11
|
+
|
|
12
|
+
"nothing": "Nothing",
|
|
13
|
+
"open": "Open (100%)",
|
|
14
|
+
"close": "Close (0%)",
|
|
15
|
+
"heating": "Heating (normal)",
|
|
16
|
+
"cooling": "Cooling (inverted)"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|