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.
- package/CHANGELOG.md +62 -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 +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 +43 -65
- 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-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 +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 +32 -36
- 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/long-press-control/long-press-control.js +0 -76
- package/shutter-complex-control/shutter-complex-control.js +0 -442
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
},
|
|
30
30
|
oneditprepare: function ()
|
|
31
31
|
{
|
|
32
|
+
let node = this;
|
|
33
|
+
|
|
32
34
|
$("#node-input-setpoint").typedInput({
|
|
33
35
|
type: "num",
|
|
34
36
|
types: ["num"]
|
|
@@ -45,13 +47,13 @@
|
|
|
45
47
|
type: "json",
|
|
46
48
|
types: ["json",
|
|
47
49
|
{
|
|
48
|
-
value: "
|
|
49
|
-
label: "
|
|
50
|
+
value: "NOTHING",
|
|
51
|
+
label: node._("hysteresis.ui.send_nothing"),
|
|
50
52
|
icon: "fa fa-times",
|
|
51
53
|
hasValue: false,
|
|
52
54
|
}, {
|
|
53
|
-
value: "
|
|
54
|
-
label: "
|
|
55
|
+
value: "ORIGINAL",
|
|
56
|
+
label: node._("hysteresis.ui.original_message"),
|
|
55
57
|
icon: "fa fa-arrow-right",
|
|
56
58
|
hasValue: false,
|
|
57
59
|
}
|
|
@@ -63,13 +65,13 @@
|
|
|
63
65
|
type: "json",
|
|
64
66
|
types: ["json",
|
|
65
67
|
{
|
|
66
|
-
value: "
|
|
67
|
-
label: "
|
|
68
|
+
value: "NOTHING",
|
|
69
|
+
label: node._("hysteresis.ui.send_nothing"),
|
|
68
70
|
icon: "fa fa-times",
|
|
69
71
|
hasValue: false,
|
|
70
72
|
}, {
|
|
71
|
-
value: "
|
|
72
|
-
label: "
|
|
73
|
+
value: "ORIGINAL",
|
|
74
|
+
label: node._("hysteresis.ui.original_message"),
|
|
73
75
|
icon: "fa fa-arrow-right",
|
|
74
76
|
hasValue: false,
|
|
75
77
|
}
|
|
@@ -82,8 +84,8 @@
|
|
|
82
84
|
types: [{
|
|
83
85
|
value: "send_only_change",
|
|
84
86
|
options: [
|
|
85
|
-
{ value: "true", label: "
|
|
86
|
-
{ value: "false", label: "
|
|
87
|
+
{ value: "true", label: node._("hysteresis.ui.send_only_change") },
|
|
88
|
+
{ value: "false", label: node._("hysteresis.ui.always") },
|
|
87
89
|
]
|
|
88
90
|
}]
|
|
89
91
|
});
|
|
@@ -93,8 +95,8 @@
|
|
|
93
95
|
types: [{
|
|
94
96
|
value: "outputs",
|
|
95
97
|
options: [
|
|
96
|
-
{ value: "1", label: "
|
|
97
|
-
{ value: "2", label: "
|
|
98
|
+
{ value: "1", label: node._("hysteresis.ui.common_output") },
|
|
99
|
+
{ value: "2", label: node._("hysteresis.ui.separate_output") },
|
|
98
100
|
]
|
|
99
101
|
}]
|
|
100
102
|
});
|
|
@@ -109,9 +111,24 @@
|
|
|
109
111
|
$("#resend_on_start_row").hide();
|
|
110
112
|
});
|
|
111
113
|
$("#node-input-save_state").trigger("change");
|
|
114
|
+
|
|
115
|
+
// Backward compatibility
|
|
116
|
+
if (this.out_higher_type == "null")
|
|
117
|
+
{
|
|
118
|
+
this.out_higher_type = "NOTHING";
|
|
119
|
+
$("#node-input-out_higher_type").val("NOTHING");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (this.out_lower_type == "null")
|
|
123
|
+
{
|
|
124
|
+
this.out_lower_type = "NOTHING";
|
|
125
|
+
$("#node-input-out_lower_type").val("NOTHING");
|
|
126
|
+
}
|
|
112
127
|
},
|
|
113
128
|
oneditsave: function ()
|
|
114
129
|
{
|
|
130
|
+
let node = this;
|
|
131
|
+
|
|
115
132
|
this.setpoint = parseFloat(this.setpoint);
|
|
116
133
|
this.hysteresis = parseFloat(this.hysteresis);
|
|
117
134
|
}
|
|
@@ -120,88 +137,49 @@
|
|
|
120
137
|
|
|
121
138
|
<script type="text/html" data-template-name="smart_hysteresis">
|
|
122
139
|
<div class="form-row">
|
|
123
|
-
<label for="node-input-name"><i class="fa fa-tag"></i>
|
|
124
|
-
<input type="text" id="node-input-name"
|
|
140
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="hysteresis.ui.name"></span></label>
|
|
141
|
+
<input type="text" id="node-input-name" data-i18n="[placeholder]hysteresis.ui.name" />
|
|
125
142
|
</div>
|
|
126
143
|
<div class="form-row">
|
|
127
|
-
<label for="node-input-setpoint"><i class="fa fa-sign-out"></i>
|
|
144
|
+
<label for="node-input-setpoint"><i class="fa fa-sign-out"></i> <span data-i18n="hysteresis.ui.setpoint"></span></label>
|
|
128
145
|
<input id="node-input-setpoint" />
|
|
129
146
|
</div>
|
|
130
147
|
<div class="form-row">
|
|
131
|
-
<label for="node-input-hysteresis"><i class="fa fa-sort"></i>
|
|
148
|
+
<label for="node-input-hysteresis"><i class="fa fa-sort"></i> <span data-i18n="hysteresis.ui.hysteresis"></span></label>
|
|
132
149
|
<input id="node-input-hysteresis" />
|
|
133
150
|
</div>
|
|
134
151
|
<hr/>
|
|
135
|
-
<h4 style="margin: 0.5rem 0;"
|
|
152
|
+
<h4 style="margin: 0.5rem 0;" data-i18n="hysteresis.ui.output_messages"></h4>
|
|
136
153
|
<div class="form-row">
|
|
137
|
-
<label for="node-input-out_higher"><i class="fa fa-arrow-up"></i>
|
|
154
|
+
<label for="node-input-out_higher"><i class="fa fa-arrow-up"></i> <span data-i18n="hysteresis.ui.over"></span></label>
|
|
138
155
|
<input type="text" id="node-input-out_higher"/>
|
|
139
156
|
<input type="hidden" id="node-input-out_higher_type">
|
|
140
157
|
</div>
|
|
141
158
|
<div class="form-row">
|
|
142
|
-
<label for="node-input-out_lower"><i class="fa fa-arrow-down"></i>
|
|
159
|
+
<label for="node-input-out_lower"><i class="fa fa-arrow-down"></i> <span data-i18n="hysteresis.ui.under"></span></label>
|
|
143
160
|
<input type="text" id="node-input-out_lower" />
|
|
144
161
|
<input type="hidden" id="node-input-out_lower_type">
|
|
145
162
|
</div>
|
|
146
163
|
<div class="form-row">
|
|
147
|
-
<label for="node-input-send_only_change"><i class="fa fa-repeat"></i>
|
|
164
|
+
<label for="node-input-send_only_change"><i class="fa fa-repeat"></i> <span data-i18n="hysteresis.ui.send"></span></label>
|
|
148
165
|
<input id="node-input-send_only_change" />
|
|
149
166
|
</div>
|
|
150
167
|
<div class="form-row">
|
|
151
|
-
<label for="node-input-outputs"><i class="fa fa-hashtag"></i>
|
|
168
|
+
<label for="node-input-outputs"><i class="fa fa-hashtag"></i> <span data-i18n="hysteresis.ui.outputs"></span></label>
|
|
152
169
|
<input id="node-input-outputs" />
|
|
153
170
|
</div>
|
|
154
171
|
<div class="form-row">
|
|
155
|
-
<div><strong
|
|
156
|
-
<div
|
|
157
|
-
<div>sofern es nicht bereits hier in der Konfiguration gesetzt wurde.</div>
|
|
158
|
-
<div><code>true</code>, wenn höher, <code>false</code> wenn niedriger.</div>
|
|
172
|
+
<div><strong data-i18n="hysteresis.ui.note"></strong></div>
|
|
173
|
+
<div data-i18n="[html]hysteresis.ui.note_text"></div>
|
|
159
174
|
</div>
|
|
160
175
|
<hr/>
|
|
161
|
-
<h4 style="margin: 0.5rem 0;"
|
|
176
|
+
<h4 style="margin: 0.5rem 0;" data-i18n="hysteresis.ui.system_start"></h4>
|
|
162
177
|
<div class="form-row">
|
|
163
178
|
<input type="checkbox" id="node-input-save_state" style="width: 20px;" />
|
|
164
|
-
<label for="node-input-save_state" style="width: calc(100% - 30px);"
|
|
179
|
+
<label for="node-input-save_state" style="width: calc(100% - 30px);" data-i18n="hysteresis.ui.save_state"></label>
|
|
165
180
|
</div>
|
|
166
181
|
<div class="form-row" id="resend_on_start_row">
|
|
167
182
|
<input type="checkbox" id="node-input-resend_on_start" style="width: 20px;" />
|
|
168
|
-
<label for="node-input-resend_on_start" style="width: calc(100% - 30px);"
|
|
183
|
+
<label for="node-input-resend_on_start" style="width: calc(100% - 30px);" data-i18n="hysteresis.ui.send_after_start"></label>
|
|
169
184
|
</div>
|
|
170
|
-
</script>
|
|
171
|
-
|
|
172
|
-
<script type="text/html" data-help-name="smart_hysteresis">
|
|
173
|
-
<p>
|
|
174
|
-
Diese Node sendet die einkommende Nachricht an den Ausgang <code>Über</code>, wenn der einkommende Wert größer gleich dem Sollwert plus Hysterese ist und
|
|
175
|
-
die einkommende Nachricht an den Ausgang <code>Unter</code>, wenn der einkommende Wert kleiner gleich dem Sollwert minus Hysterese ist.<br/>
|
|
176
|
-
Die Nachricht wird dabei nur einmalig bei über- bzw. unterschreiten des Grenzwertes weitergeleitet.<br/>
|
|
177
|
-
Die Note behält den aktuellen Zustand auch nach dem Deploy bei.
|
|
178
|
-
</p>
|
|
179
|
-
<p>
|
|
180
|
-
<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/>
|
|
181
|
-
Diese Node verwendet nur den Teil <code>name</code>. <code>#</code> und <code>nummer</code> sind dabei optional.
|
|
182
|
-
</p>
|
|
183
|
-
<p>
|
|
184
|
-
Folgende topics werden akzeptiert:
|
|
185
|
-
<table>
|
|
186
|
-
<thead>
|
|
187
|
-
<tr>
|
|
188
|
-
<th>Topic</th>
|
|
189
|
-
<th>Beschreibung</th>
|
|
190
|
-
</tr>
|
|
191
|
-
</thead>
|
|
192
|
-
<tbody>
|
|
193
|
-
<tr>
|
|
194
|
-
<td><code>setpoint</code></td>
|
|
195
|
-
<td>Überschreibt den Sollwert mit <code>msg.payload</code>.</td>
|
|
196
|
-
</tr>
|
|
197
|
-
<tr>
|
|
198
|
-
<td><code>hysteresis</code></td>
|
|
199
|
-
<td>Überschreibt die Hysterese mit <code>msg.payload</code>.</td>
|
|
200
|
-
</tr>
|
|
201
|
-
</tbody>
|
|
202
|
-
</table>
|
|
203
|
-
</p>
|
|
204
|
-
<p>
|
|
205
|
-
Die einkommende Nachricht wird mit den angegebenen Ausgangsnachrichten ergänzt, sofern nicht Originalnachricht ausgewählt wurde.
|
|
206
|
-
</p>
|
|
207
185
|
</script>
|
package/hysteresis/hysteresis.js
CHANGED
|
@@ -7,10 +7,22 @@ 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
|
+
// #######################
|
|
10
19
|
const smart_context = require("../persistence.js")(RED);
|
|
11
20
|
const helper = require("../smart_helper.js");
|
|
12
21
|
|
|
13
|
-
|
|
22
|
+
|
|
23
|
+
// #####################
|
|
24
|
+
// # persistent values #
|
|
25
|
+
// #####################
|
|
14
26
|
var node_settings = {
|
|
15
27
|
last_value: null,
|
|
16
28
|
last_result: null,
|
|
@@ -46,22 +58,52 @@ module.exports = function (RED)
|
|
|
46
58
|
smart_context.del(node.id);
|
|
47
59
|
}
|
|
48
60
|
|
|
49
|
-
|
|
61
|
+
|
|
62
|
+
// ##################
|
|
63
|
+
// # Dynamic config #
|
|
64
|
+
// ##################
|
|
50
65
|
let out_higher = helper.evaluateNodeProperty(RED, config.out_higher, config.out_higher_type);
|
|
51
66
|
let out_lower = helper.evaluateNodeProperty(RED, config.out_lower, config.out_lower_type);
|
|
52
67
|
let send_only_change = helper.evaluateNodeProperty(RED, config.send_only_change, "bool");
|
|
53
68
|
let outputs = helper.evaluateNodeProperty(RED, config.outputs, "num");
|
|
54
69
|
|
|
55
|
-
// runtime values
|
|
56
70
|
|
|
71
|
+
// ##################
|
|
72
|
+
// # Runtime values #
|
|
73
|
+
// ##################
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
// ###############
|
|
77
|
+
// # Node events #
|
|
78
|
+
// ###############
|
|
57
79
|
node.on("input", function (msg)
|
|
58
80
|
{
|
|
59
|
-
|
|
81
|
+
handleTopic(msg);
|
|
82
|
+
|
|
83
|
+
setStatus();
|
|
84
|
+
|
|
85
|
+
if (config.save_state)
|
|
86
|
+
smart_context.set(node.id, node_settings);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
node.on("close", function ()
|
|
90
|
+
{
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
// #####################
|
|
95
|
+
// # Private functions #
|
|
96
|
+
// #####################
|
|
97
|
+
|
|
98
|
+
// This is the main function which handles all topics that was received.
|
|
99
|
+
let handleTopic = msg =>
|
|
100
|
+
{
|
|
60
101
|
let real_topic = helper.getTopicName(msg.topic);
|
|
102
|
+
let value = parseFloat(msg.payload);
|
|
61
103
|
|
|
62
104
|
if (isNaN(value))
|
|
63
105
|
{
|
|
64
|
-
|
|
106
|
+
console.warn("Invalid payload: " + msg.payload);
|
|
65
107
|
return;
|
|
66
108
|
}
|
|
67
109
|
|
|
@@ -69,67 +111,51 @@ module.exports = function (RED)
|
|
|
69
111
|
{
|
|
70
112
|
case "setpoint":
|
|
71
113
|
node_settings.setpoint = value;
|
|
72
|
-
node.status({ fill: node_settings.last_result ? "green" : "red", shape: "ring", text: helper.getCurrentTimeForStatus() + ": New setpoint: " + value + "" });
|
|
73
|
-
|
|
74
|
-
if (config.save_state)
|
|
75
|
-
smart_context.set(node.id, node_settings);
|
|
76
114
|
break;
|
|
77
115
|
|
|
78
116
|
case "hysteresis":
|
|
79
117
|
node_settings.hysteresis = value;
|
|
80
|
-
node.status({ fill: node_settings.last_result ? "green" : "red", shape: "ring", text: helper.getCurrentTimeForStatus() + ": New hysteresis: " + value + "" });
|
|
81
|
-
|
|
82
|
-
if (config.save_state)
|
|
83
|
-
smart_context.set(node.id, node_settings);
|
|
84
118
|
break;
|
|
85
119
|
|
|
86
120
|
default:
|
|
87
|
-
|
|
88
|
-
let out_msg = null;
|
|
89
|
-
|
|
90
|
-
// No change, nothing to send
|
|
91
|
-
if (result !== null)
|
|
92
|
-
{
|
|
93
|
-
// Get custom output message
|
|
94
|
-
if (result)
|
|
95
|
-
out_msg = createMessage(out_higher, config.out_higher_type, msg, value);
|
|
96
|
-
else
|
|
97
|
-
out_msg = createMessage(out_lower, config.out_lower_type, msg, value);
|
|
98
|
-
|
|
99
|
-
// Overwrite automatic values, if not already defined
|
|
100
|
-
if (typeof out_msg.payload === "undefined")
|
|
101
|
-
out_msg.payload = result ?? node_settings.last_result;
|
|
102
|
-
|
|
103
|
-
// Separate outputs if needed
|
|
104
|
-
if (outputs == 2)
|
|
105
|
-
{
|
|
106
|
-
if (result)
|
|
107
|
-
out_msg = [out_msg, null];
|
|
108
|
-
else
|
|
109
|
-
out_msg = [null, out_msg];
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Send only if needed
|
|
113
|
-
if (send_only_change == false || node_settings.last_result != result)
|
|
114
|
-
node.send(out_msg);
|
|
115
|
-
|
|
116
|
-
node_settings.last_result = result;
|
|
117
|
-
node_settings.last_message = out_msg;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
node_settings.last_value = value;
|
|
121
|
-
|
|
122
|
-
setStatus(result === null);
|
|
123
|
-
|
|
124
|
-
if (config.save_state)
|
|
125
|
-
smart_context.set(node.id, node_settings);
|
|
121
|
+
node_settings.last_value = value
|
|
126
122
|
break;
|
|
127
123
|
}
|
|
128
|
-
});
|
|
129
124
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
125
|
+
// Always calculate new result
|
|
126
|
+
let result = getResult(node_settings.last_value);
|
|
127
|
+
let out_msg = null;
|
|
128
|
+
|
|
129
|
+
// No change, nothing to send
|
|
130
|
+
if (result === null)
|
|
131
|
+
return;
|
|
132
|
+
|
|
133
|
+
// Get custom output message
|
|
134
|
+
if (result)
|
|
135
|
+
out_msg = createMessage(out_higher, config.out_higher_type, msg, node_settings.last_value);
|
|
136
|
+
else
|
|
137
|
+
out_msg = createMessage(out_lower, config.out_lower_type, msg, node_settings.last_value);
|
|
138
|
+
|
|
139
|
+
// Overwrite automatic values, if not already defined
|
|
140
|
+
if (typeof out_msg.payload === "undefined")
|
|
141
|
+
out_msg.payload = result ?? node_settings.last_result;
|
|
142
|
+
|
|
143
|
+
// Separate outputs if needed
|
|
144
|
+
if (outputs == 2)
|
|
145
|
+
{
|
|
146
|
+
if (result)
|
|
147
|
+
out_msg = [out_msg, null];
|
|
148
|
+
else
|
|
149
|
+
out_msg = [null, out_msg];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Send only if needed
|
|
153
|
+
if (send_only_change == false || node_settings.last_result != result)
|
|
154
|
+
node.send(out_msg);
|
|
155
|
+
|
|
156
|
+
node_settings.last_result = result;
|
|
157
|
+
node_settings.last_message = out_msg;
|
|
158
|
+
}
|
|
133
159
|
|
|
134
160
|
let getResult = value =>
|
|
135
161
|
{
|
|
@@ -145,19 +171,17 @@ module.exports = function (RED)
|
|
|
145
171
|
return node_settings.last_result;
|
|
146
172
|
}
|
|
147
173
|
|
|
148
|
-
let setStatus =
|
|
174
|
+
let setStatus = () =>
|
|
149
175
|
{
|
|
150
|
-
if (
|
|
151
|
-
node.status({ fill:
|
|
152
|
-
else
|
|
153
|
-
node.status({ fill: "green", shape: "dot", text: helper.getCurrentTimeForStatus() + ":
|
|
154
|
-
else if (node_settings.last_result === false)
|
|
155
|
-
node.status({ fill: "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Turned lower by value " + node_settings.last_value + "" });
|
|
176
|
+
if (node_settings.last_result == null)
|
|
177
|
+
node.status({ fill: "yellow", shape: "ring", text: helper.getCurrentTimeForStatus() + ": ❓ S: " + node_settings.setpoint + " - H: " + node_settings.hysteresis + " - V: null" });
|
|
178
|
+
else
|
|
179
|
+
node.status({ fill: node_settings.last_result ? "green" : "red", shape: "dot", text: helper.getCurrentTimeForStatus() + ": " + (node_settings.last_result ? "⬆️" : "⬇️") + " S: " + node_settings.setpoint + " - H: " + node_settings.hysteresis + " - V: " + node_settings.last_value.toFixed(2) });
|
|
156
180
|
}
|
|
157
181
|
|
|
158
182
|
let createMessage = (out_msg, out_type, msg, value) =>
|
|
159
183
|
{
|
|
160
|
-
return
|
|
184
|
+
return helper.cloneObject(out_type == "ORIGINAL" ? msg : out_msg, {
|
|
161
185
|
smart_info: {
|
|
162
186
|
last_result: node_settings.last_result,
|
|
163
187
|
hysteresis: node_settings.hysteresis,
|
|
@@ -165,7 +189,7 @@ module.exports = function (RED)
|
|
|
165
189
|
last_value: node_settings.last_value,
|
|
166
190
|
value: value
|
|
167
191
|
}
|
|
168
|
-
})
|
|
192
|
+
});
|
|
169
193
|
};
|
|
170
194
|
|
|
171
195
|
if (config.save_state && config.resend_on_start && node_settings.last_result !== null && node_settings.last_message !== null)
|
|
@@ -175,16 +199,18 @@ module.exports = function (RED)
|
|
|
175
199
|
if (outputs == 2)
|
|
176
200
|
{
|
|
177
201
|
if (node_settings.last_result)
|
|
178
|
-
node.send([node_settings.last_message, null]);
|
|
202
|
+
node.send([helper.cloneObject(node_settings.last_message), null]);
|
|
179
203
|
else
|
|
180
|
-
node.send([null, node_settings.last_message]);
|
|
204
|
+
node.send([null, helper.cloneObject(node_settings.last_message)]);
|
|
181
205
|
}
|
|
182
206
|
else
|
|
183
207
|
{
|
|
184
|
-
node.send(node_settings.last_message);
|
|
208
|
+
node.send(helper.cloneObject(node_settings.last_message));
|
|
185
209
|
}
|
|
186
210
|
}, 10000);
|
|
187
211
|
}
|
|
212
|
+
|
|
213
|
+
setStatus();
|
|
188
214
|
}
|
|
189
215
|
|
|
190
216
|
RED.nodes.registerType("smart_hysteresis", HysteresisNode);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script type="text/html" data-help-name="smart_hysteresis">
|
|
2
|
+
<p>
|
|
3
|
+
Diese Node sendet die einkommende Nachricht an den Ausgang <code>Über</code>, wenn der einkommende Wert größer gleich dem Sollwert plus Hysterese ist und
|
|
4
|
+
die einkommende Nachricht an den Ausgang <code>Unter</code>, wenn der einkommende Wert kleiner gleich dem Sollwert minus Hysterese ist.<br/>
|
|
5
|
+
Die Nachricht wird dabei nur einmalig bei über- bzw. unterschreiten des Grenzwertes weitergeleitet.<br/>
|
|
6
|
+
Die Node behält den aktuellen Zustand auch nach dem Deploy bei.
|
|
7
|
+
</p>
|
|
8
|
+
<p>
|
|
9
|
+
<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/>
|
|
10
|
+
Diese Node verwendet nur den Teil <code>name</code>. <code>#</code> und <code>nummer</code> sind dabei optional.
|
|
11
|
+
</p>
|
|
12
|
+
<p>
|
|
13
|
+
Folgende topics werden akzeptiert:
|
|
14
|
+
<table>
|
|
15
|
+
<thead>
|
|
16
|
+
<tr>
|
|
17
|
+
<th>Topic</th>
|
|
18
|
+
<th>Beschreibung</th>
|
|
19
|
+
</tr>
|
|
20
|
+
</thead>
|
|
21
|
+
<tbody>
|
|
22
|
+
<tr>
|
|
23
|
+
<td><code>setpoint</code></td>
|
|
24
|
+
<td>Überschreibt den Sollwert mit <code>msg.payload</code>.</td>
|
|
25
|
+
</tr>
|
|
26
|
+
<tr>
|
|
27
|
+
<td><code>hysteresis</code></td>
|
|
28
|
+
<td>Überschreibt die Hysterese mit <code>msg.payload</code>.</td>
|
|
29
|
+
</tr>
|
|
30
|
+
</tbody>
|
|
31
|
+
</table>
|
|
32
|
+
</p>
|
|
33
|
+
<p>
|
|
34
|
+
Die einkommende Nachricht wird mit den angegebenen Ausgangsnachrichten ergänzt, sofern nicht Originalnachricht ausgewählt wurde.
|
|
35
|
+
</p>
|
|
36
|
+
</script>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hysteresis": {
|
|
3
|
+
"ui": {
|
|
4
|
+
"name": "Name",
|
|
5
|
+
"setpoint": "Sollwert",
|
|
6
|
+
"hysteresis": "Hysterese",
|
|
7
|
+
"output_messages": "Ausgangsnachrichten",
|
|
8
|
+
"over": "Über",
|
|
9
|
+
"under": "Unter",
|
|
10
|
+
"send": "Senden",
|
|
11
|
+
"outputs": "Ausgänge",
|
|
12
|
+
|
|
13
|
+
"note": "Hinweis:",
|
|
14
|
+
"note_text": "<code>msg.payload</code> wird automatisch auf das Hystere-Ergebnis gesetzt,<br/>sofern es nicht bereits hier in der Konfiguration gesetzt wurde.<br/><code>true</code> wenn höher, <code>false</code> wenn niedriger",
|
|
15
|
+
"system_start": "Systemstart",
|
|
16
|
+
"save_state": "Zustand speichern",
|
|
17
|
+
"send_after_start": "Letze Nachricht 10 Sekunden nach dem Start senden",
|
|
18
|
+
|
|
19
|
+
"send_nothing": "Nichts senden",
|
|
20
|
+
"original_message": "Originalnachricht",
|
|
21
|
+
"send_only_change": "Nur bei Änderung",
|
|
22
|
+
"always": "Immer",
|
|
23
|
+
"common_output": "Gemeinsamer Ausgang",
|
|
24
|
+
"separate_output": "Separate Ausgänge"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script type="text/html" data-help-name="smart_hysteresis">
|
|
2
|
+
<p>
|
|
3
|
+
This node sends the incoming message to the output <code>Over</code> if the incoming value is greater than or equal to the setpoint plus hysteresis and
|
|
4
|
+
the incoming message to the output <code>Under</code> if the incoming value is less than or equal to the setpoint minus hysteresis.<br />
|
|
5
|
+
The message is only forwarded once when the limit is exceeded or not reached.<br />
|
|
6
|
+
The node retains the current state even after deployment.
|
|
7
|
+
</p>
|
|
8
|
+
<p>
|
|
9
|
+
<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 />
|
|
10
|
+
This node only uses the part <code>name</code>. <code>#</code> and <code>number</code> are optional.
|
|
11
|
+
</p>
|
|
12
|
+
<p>
|
|
13
|
+
The following topics are accepted:
|
|
14
|
+
<table>
|
|
15
|
+
<thead>
|
|
16
|
+
<tr>
|
|
17
|
+
<th>Topic</th>
|
|
18
|
+
<th>Description</th>
|
|
19
|
+
</tr>
|
|
20
|
+
</thead>
|
|
21
|
+
<tbody>
|
|
22
|
+
<tr>
|
|
23
|
+
<td><code>setpoint</code></td>
|
|
24
|
+
<td>Overwrites the setpoint with <code>msg.payload</code>.</td>
|
|
25
|
+
</tr>
|
|
26
|
+
<tr>
|
|
27
|
+
<td><code>hysteresis</code></td>
|
|
28
|
+
<td>Overwrites the hysteresis with <code>msg.payload</code>.</td>
|
|
29
|
+
</tr>
|
|
30
|
+
</tbody>
|
|
31
|
+
</table>
|
|
32
|
+
</p>
|
|
33
|
+
<p>
|
|
34
|
+
The incoming message is supplemented with the specified outgoing messages, unless the original message was selected.
|
|
35
|
+
</p>
|
|
36
|
+
</script>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hysteresis": {
|
|
3
|
+
"ui": {
|
|
4
|
+
"name": "Name",
|
|
5
|
+
"setpoint": "Setpoint",
|
|
6
|
+
"hysteresis": "Hysteresis",
|
|
7
|
+
"output_messages": "Output messages",
|
|
8
|
+
"over": "Over",
|
|
9
|
+
"under": "Under",
|
|
10
|
+
"send": "Send",
|
|
11
|
+
"outputs": "Outputs",
|
|
12
|
+
|
|
13
|
+
"note": "Note:",
|
|
14
|
+
"note_text": "<code>msg.payload</code> is automatically set to the hysteresis result,<br/>if it has not already been set here in the configuration.<br/><code>true</code> if higher, <code>false</code> if lower",
|
|
15
|
+
"system_start": "System start",
|
|
16
|
+
"save_state": "Save state",
|
|
17
|
+
"send_after_start": "Send last message 10 seconds after start",
|
|
18
|
+
|
|
19
|
+
"send_nothing": "Send nothing",
|
|
20
|
+
"original_message": "Original message",
|
|
21
|
+
"send_only_change": "Only when changed",
|
|
22
|
+
"always": "Always",
|
|
23
|
+
"common_output": "Common output",
|
|
24
|
+
"separate_output": "Separate outputs"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|