node-red-contrib-boolean-logic-ultimate 1.0.43 → 1.0.48
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 +18 -0
- package/README.md +71 -3
- package/boolean-logic-ultimate/InterruptFlowUltimate.html +18 -2
- package/boolean-logic-ultimate/InterruptFlowUltimate.js +41 -20
- package/boolean-logic-ultimate/SumUltimate.html +54 -0
- package/boolean-logic-ultimate/SumUltimate.js +88 -0
- package/img/sum.png +0 -0
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
# node-red-contrib-boolean-logic-ultimate
|
|
2
2
|
[](https://www.paypal.me/techtoday)
|
|
3
3
|
|
|
4
|
+
<p>
|
|
5
|
+
<b>Version 1.0.48</b> February 2022<br/>
|
|
6
|
+
- NEW: SUM node: this new node makes sum, average and measurement count.</br>
|
|
7
|
+
</p>
|
|
8
|
+
<p>
|
|
9
|
+
<b>Version 1.0.47</b> February 2022<br/>
|
|
10
|
+
- NEW: Interrupt Flow: the node now stores the last message, even if in the "stop" state.</br>
|
|
11
|
+
</p>
|
|
12
|
+
<p>
|
|
13
|
+
<b>Version 1.0.46</b> February 2022<br/>
|
|
14
|
+
- NEW: Interrupt Flow: msg.reset will delete the stored message.</br>
|
|
15
|
+
- Updated the README file with samples.</br>
|
|
16
|
+
</p>
|
|
17
|
+
<p>
|
|
18
|
+
<b>Version 1.0.45</b> February 2022<br/>
|
|
19
|
+
- NEW: Interrupt Flow: Now you can auto-toggle the startup behavior selection (to stop or to pass telegrams) after some pre-defined delays.</br>
|
|
20
|
+
- Updated the README file with samples.</br>
|
|
21
|
+
</p>
|
|
4
22
|
<p>
|
|
5
23
|
<b>Version 1.0.44</b> February 2022<br/>
|
|
6
24
|
- Boolean Logic Ultimate: Added the "d" indication, in the node's name, when the delay option is enabled.</br>
|
package/README.md
CHANGED
|
@@ -116,14 +116,48 @@ Resets all inputs to undefined.
|
|
|
116
116
|
|
|
117
117
|
# INTERRUPT FLOWS ULTIMATE
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
**Trigger by topic**
|
|
120
|
+
|
|
121
|
+
Whenever the node receives a payload = false from this topic,it stops output messages to the flow.<br/>
|
|
122
|
+
As soon it receives payload = true from this topic, the output messages start to flow out again. <br/>
|
|
123
|
+
The node will output the current stored message plus an added property "isReplay = true", as soon as it receives a ***msg.play = true*** from this topic.<br/>
|
|
124
|
+
The node will clear the current stored message, as soon as it receives a ***msg.reset = true*** from this topic.<br/>
|
|
120
125
|
The node tries to convert any arbitrary input value to a valid boolean value. It converts Homeassistant ***"on"*** and ***"off"*** to true/false values as well.<br/>
|
|
121
126
|
|
|
127
|
+
**Then**
|
|
128
|
+
This property, allow you to auto toggle the selected start state (pass or block) after a timer has elapsed. You can choose from some pre-defined delays. If you have, for example, an Homekit-Bridged nodeset with a thermostat node or security system node in your flow, once node-red restarts, these homekit nodes output a default message to the flow. Just put an InterruptFlow node with a "block at start" behaviour and a toggle delay enabled behind homekit nodes, to temporary stop the chained nodes to receive the unwanted startup message.</br>
|
|
129
|
+
</br>
|
|
130
|
+
|
|
131
|
+
**INPUT MSG HWITH "TRIGGER" TOPIC**
|
|
132
|
+
|
|
133
|
+
Pass <code>msg.payload = true</code> to allow messages to pass through</br>
|
|
134
|
+
Pass <code>msg.payload = false</code> to prevent messages from passing through</br>
|
|
135
|
+
Pass <code>msg.play = true</code> from a message having the "trigger" topic, to replay the last stored message</br>
|
|
136
|
+
Pass <code>msg.reset = true</code> from a message having the "trigger" topic, to clear the last stored message</br>
|
|
137
|
+
|
|
138
|
+
<code>
|
|
139
|
+
// Assume you set the "trigger by topic" field to "trigger"
|
|
140
|
+
// This code replays the last message and adds the property msg.isReplay = true to the output message.
|
|
141
|
+
msg.topic = "trigger"
|
|
142
|
+
msg.play = true;
|
|
143
|
+
</code>
|
|
144
|
+
|
|
145
|
+
<code>
|
|
146
|
+
// Assume you set the "trigger by topic" field to "trigger"
|
|
147
|
+
// This code clears the last stored message
|
|
148
|
+
msg.topic = "trigger"
|
|
149
|
+
msg.reset = true;
|
|
150
|
+
</code>
|
|
151
|
+
|
|
152
|
+
</br>
|
|
153
|
+
|
|
154
|
+
See the example below.<br/>
|
|
155
|
+
|
|
122
156
|
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-boolean-logic-ultimate/master/img/if0.png' width='60%'>
|
|
123
157
|
|
|
124
158
|
<details><summary>CLICK HERE, copy and paste it into your flow</summary>
|
|
125
159
|
<code>
|
|
126
|
-
[{"id":"1fd91f1f.c1fae9","type":"InterruptFlowUltimate","z":"
|
|
160
|
+
[{"id":"1fd91f1f.c1fae9","type":"InterruptFlowUltimate","z":"96f56ceb91657677","name":"Interrupt Flow","triggertopic":"IsNight","initializewith":"1","autoToggle":"0","x":420,"y":200,"wires":[["b9844c7f.0f306"]]},{"id":"eaa32462.398808","type":"comment","z":"96f56ceb91657677","name":"Motion sensor to switch on stairs light, only if it's night, using flow interruption","info":"","x":350,"y":160,"wires":[]},{"id":"10787f38.edfe81","type":"inject","z":"96f56ceb91657677","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"IsNight","payload":"true","payloadType":"bool","x":170,"y":300,"wires":[["1fd91f1f.c1fae9"]]},{"id":"a6092a15.1c592","type":"inject","z":"96f56ceb91657677","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"IsNight","payload":"false","payloadType":"bool","x":170,"y":340,"wires":[["1fd91f1f.c1fae9"]]},{"id":"21ba9c30.02abbc","type":"comment","z":"96f56ceb91657677","name":"Brightness sensor","info":"","x":170,"y":260,"wires":[]},{"id":"af131ae5.a1bfb8","type":"inject","z":"96f56ceb91657677","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"MotionSensor","payload":"true","payloadType":"bool","x":190,"y":200,"wires":[["1fd91f1f.c1fae9"]]},{"id":"b9844c7f.0f306","type":"debug","z":"96f56ceb91657677","name":"Temporized Stairs Lightbulb","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":660,"y":200,"wires":[]},{"id":"a5305f8bef578897","type":"comment","z":"96f56ceb91657677","name":"Temporary stop the flow, with Toggle","info":"","x":220,"y":440,"wires":[]},{"id":"ffc9d3b9d17bc07b","type":"InterruptFlowUltimate","z":"96f56ceb91657677","name":"Interrupt Flow with toggle","triggertopic":"trigger","initializewith":"0","autoToggle":"20","x":400,"y":480,"wires":[["14a72f83f29bb347"]]},{"id":"398548646f66c457","type":"inject","z":"96f56ceb91657677","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"1","crontab":"","once":true,"onceDelay":0.1,"topic":"","payloadType":"date","x":170,"y":480,"wires":[["ffc9d3b9d17bc07b"]]},{"id":"14a72f83f29bb347","type":"debug","z":"96f56ceb91657677","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":630,"y":480,"wires":[]}]
|
|
127
161
|
</code>
|
|
128
162
|
</details>
|
|
129
163
|
|
|
@@ -136,7 +170,7 @@ This allow to save the state of a node and then replay it back whenever you want
|
|
|
136
170
|
|
|
137
171
|
<details><summary>CLICK HERE, copy and paste it into your flow</summary>
|
|
138
172
|
<code>
|
|
139
|
-
[{"id":"9839dd47.81b2c8","type":"InterruptFlowUltimate","z":"
|
|
173
|
+
[{"id":"9839dd47.81b2c8","type":"InterruptFlowUltimate","z":"1337569a6adbb2e3","name":"Interrupt Flow","triggertopic":"trigger","initializewith":"1","autoToggle":"0","x":580,"y":300,"wires":[["d371d690.1e2fe8"]]},{"id":"568deb73.394fb4","type":"comment","z":"1337569a6adbb2e3","name":"1) Push buttons to change values","info":"","x":190,"y":140,"wires":[]},{"id":"e1c9f10a.0ba518","type":"inject","z":"1337569a6adbb2e3","name":"ALLOW","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"trigger","payload":"true","payloadType":"bool","x":130,"y":360,"wires":[["9839dd47.81b2c8"]]},{"id":"82ba24f9.0f0bd8","type":"inject","z":"1337569a6adbb2e3","name":"INTERRUPT","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"trigger","payload":"false","payloadType":"bool","x":150,"y":320,"wires":[["9839dd47.81b2c8"]]},{"id":"23ba4f9c.86de9","type":"comment","z":"1337569a6adbb2e3","name":"2) Push INTERRUPT, then try again to change value (1)","info":"","x":260,"y":280,"wires":[]},{"id":"24671ef2.4519e2","type":"inject","z":"1337569a6adbb2e3","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":130,"y":180,"wires":[["9839dd47.81b2c8"]]},{"id":"d371d690.1e2fe8","type":"debug","z":"1337569a6adbb2e3","name":"Debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":750,"y":300,"wires":[]},{"id":"409ec415.735d74","type":"inject","z":"1337569a6adbb2e3","name":"REPLAY","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"trigger","payload":"","payloadType":"str","x":140,"y":460,"wires":[["6653ed0.7186014"]]},{"id":"6653ed0.7186014","type":"change","z":"1337569a6adbb2e3","name":"Play","rules":[{"t":"set","p":"play","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":460,"wires":[["9839dd47.81b2c8"]]},{"id":"e957a069.0ac458","type":"inject","z":"1337569a6adbb2e3","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":130,"y":220,"wires":[["9839dd47.81b2c8"]]},{"id":"8f0af608.8fb45","type":"comment","z":"1337569a6adbb2e3","name":"3) Replay last message stored by the node","info":"","x":220,"y":420,"wires":[]},{"id":"46e6f455.0023ac","type":"comment","z":"1337569a6adbb2e3","name":"You can use Interruptflow, to save the state of a node, and then replay the last state as you want.","info":"","x":390,"y":100,"wires":[]}]
|
|
140
174
|
</code>
|
|
141
175
|
</details>
|
|
142
176
|
|
|
@@ -289,6 +323,40 @@ Pass <code>msg.payload = false</code> to the node to stop the running sequence</
|
|
|
289
323
|
|
|
290
324
|
- Output: the node outputs a message you specified in the command textbox<br/>
|
|
291
325
|
|
|
326
|
+
<br/>
|
|
327
|
+
<br/>
|
|
328
|
+
<br/>
|
|
329
|
+
<br/>
|
|
330
|
+
<br/>
|
|
331
|
+
|
|
332
|
+
# SUM ULTIMATE
|
|
333
|
+
|
|
334
|
+
The pourpose of this node is to sum the incoming values. Each incoming message MUST HAVE OWN TOPIC.<br />
|
|
335
|
+
|
|
336
|
+
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-boolean-logic-ultimate/master/img/sum.png' width='60%'>
|
|
337
|
+
<details><summary>CLICK HERE, copy and paste it into your flow</summary>
|
|
338
|
+
<code>
|
|
339
|
+
[{"id":"05b6ce0cb476abd5","type":"SumUltimate","z":"d8fbf871e381cf2c","name":"Sum","property":"payload","x":550,"y":160,"wires":[["567aa6a9719e463e","34fbca5daf8b9fab","e3c2a45a0b77af8f"]]},{"id":"6744e01b88d820b9","type":"inject","z":"d8fbf871e381cf2c","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"Watt Table Lamp","payload":"10","payloadType":"num","x":250,"y":140,"wires":[["05b6ce0cb476abd5"]]},{"id":"75823dbc7db78c3c","type":"inject","z":"d8fbf871e381cf2c","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"Watt Washing machine","payload":"20","payloadType":"num","x":270,"y":180,"wires":[["05b6ce0cb476abd5"]]},{"id":"567aa6a9719e463e","type":"debug","z":"d8fbf871e381cf2c","name":"Sum","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":690,"y":160,"wires":[]},{"id":"1793931ba218bc1d","type":"inject","z":"d8fbf871e381cf2c","name":"Reset","props":[{"p":"reset","v":"","vt":"date"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":210,"y":240,"wires":[["05b6ce0cb476abd5"]]},{"id":"0b3277af03f546d4","type":"comment","z":"d8fbf871e381cf2c","name":"Getting Sum, Average etc. from the SUM node.","info":"","x":320,"y":100,"wires":[]},{"id":"34fbca5daf8b9fab","type":"debug","z":"d8fbf871e381cf2c","name":"Average","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"average","targetType":"msg","statusVal":"","statusType":"auto","x":700,"y":200,"wires":[]},{"id":"e3c2a45a0b77af8f","type":"debug","z":"d8fbf871e381cf2c","name":"Measurements","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"measurements","targetType":"msg","statusVal":"","statusType":"auto","x":720,"y":240,"wires":[]}]
|
|
340
|
+
</code>
|
|
341
|
+
</details>
|
|
342
|
+
|
|
343
|
+
**INPUT**<br />
|
|
344
|
+
|
|
345
|
+
<br /><b>msg.reset</b><br />
|
|
346
|
+
resets the values to zero.
|
|
347
|
+
|
|
348
|
+
<br />
|
|
349
|
+
|
|
350
|
+
- Output: the node outputs a message as follows:<br/>
|
|
351
|
+
|
|
352
|
+
<pre>
|
|
353
|
+
{
|
|
354
|
+
"payload": 30, // This is the SUM
|
|
355
|
+
"topic": "Sum", // Node Topic
|
|
356
|
+
"average": 15, // This is the AVERAVE
|
|
357
|
+
"measurements": 2 // This is the number of topics that have been evaluated
|
|
358
|
+
}
|
|
359
|
+
</pre>
|
|
292
360
|
|
|
293
361
|
[license-image]: https://img.shields.io/badge/license-MIT-blue.svg
|
|
294
362
|
[license-url]: https://github.com/Supergiovane/node-red-contrib-boolean-logic-ultimate/master/LICENSE
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
name: { value: "Interrupt Flow" },
|
|
7
7
|
triggertopic: { value: "trigger" },
|
|
8
8
|
initializewith: { value: "1" },
|
|
9
|
+
autoToggle: { value: "0" }
|
|
9
10
|
},
|
|
10
11
|
inputs: 1,
|
|
11
12
|
outputs: 1,
|
|
@@ -48,15 +49,30 @@
|
|
|
48
49
|
<label for="node-input-triggertopic"><i class="icon-tag"></i> Trigger by topic</label>
|
|
49
50
|
<input type="text" id="node-input-triggertopic" placeholder="Name">
|
|
50
51
|
<div><i>Whenever the node receives a payload = false from this topic,<br/> it stops output messages to the flow.<br/>As soon it receives payload = true from this topic,<br/>the output messages start to flow out again.
|
|
51
|
-
<br/>The node will output the current stored message<br/>plus an added property "isReplay = true",<br/>as soon as it receives a "play" = true from this topic
|
|
52
|
+
<br/>The node will output the current stored message<br/>plus an added property "isReplay = true",<br/>as soon as it receives a "play" = true from this topic.</br>
|
|
53
|
+
The node will clear the current stored message, as soon as it receives a "msg.reset = true" from this topic.
|
|
52
54
|
</i></div>
|
|
53
55
|
</div>
|
|
54
56
|
|
|
55
57
|
<div class="form-row">
|
|
56
|
-
<label for="node-input-initializewith"><i class="fa fa-home"></i> At node-red start</label>
|
|
58
|
+
<label style="width:160px" for="node-input-initializewith"><i class="fa fa-home"></i> At node-red start</label>
|
|
57
59
|
<select type="text" id="node-input-initializewith" placeholder="">
|
|
58
60
|
<option value="1">Pass telegrams</option>
|
|
59
61
|
<option value="0">Block telegrams</option>
|
|
62
|
+
</select>
|
|
63
|
+
</div>
|
|
64
|
+
<div class="form-row">
|
|
65
|
+
<label style="width:160px" for="node-input-autoToggle"><i class="fa fa-hourglass-o"></i> Then</label>
|
|
66
|
+
<select type="text" id="node-input-autoToggle" placeholder="">
|
|
67
|
+
<option value="0">Nothing</option>
|
|
68
|
+
<option value="10">Toggle above option after 10 seconds</option>
|
|
69
|
+
<option value="20">Toggle above option after 20 seconds</option>
|
|
70
|
+
<option value="30">Toggle above option after 30 seconds</option>
|
|
71
|
+
<option value="40">Toggle above option after 40 seconds</option>
|
|
72
|
+
<option value="50">Toggle above option after 50 seconds</option>
|
|
73
|
+
<option value="60">Toggle above option after 60 seconds</option>
|
|
74
|
+
<option value="90">Toggle above option after 90 seconds</option>
|
|
75
|
+
<option value="120">Toggle above option after 120 seconds</option>
|
|
60
76
|
</select>
|
|
61
77
|
</div>
|
|
62
78
|
</script>
|
|
@@ -6,6 +6,8 @@ module.exports = function (RED) {
|
|
|
6
6
|
node.currentMsg = {}; // Stores current payload
|
|
7
7
|
node.sTriggerTopic = node.config.triggertopic.replace(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '') || "trigger"; // Topic controlling the bInviaMessaggio
|
|
8
8
|
node.bInviaMessaggio = (node.config.initializewith === undefined || node.config.initializewith === "1") ? true : false; // Send the message or not
|
|
9
|
+
node.autoToggle = config.autoToggle === undefined ? 0 : parseInt(config.autoToggle); // Auto toggle the selected "initializewith" after a while (useful for homekit bridged, that sends junk after start)
|
|
10
|
+
node.timerAutoToggle = null;
|
|
9
11
|
|
|
10
12
|
function setNodeStatus({ fill, shape, text }) {
|
|
11
13
|
var dDate = new Date();
|
|
@@ -14,12 +16,25 @@ module.exports = function (RED) {
|
|
|
14
16
|
setNodeStatus({ fill: "green", shape: "ring", text: "-> pass" });
|
|
15
17
|
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
node.alignStatus = () => {
|
|
20
|
+
let sAutoToggle = node.autoToggle > 0 ? " (Autotoggle in " + node.autoToggle + "s)" : "";
|
|
21
|
+
if (node.bInviaMessaggio) {
|
|
22
|
+
setNodeStatus({ fill: "green", shape: "dot", text: "-> pass" + sAutoToggle });
|
|
23
|
+
} else {
|
|
24
|
+
setNodeStatus({ fill: "red", shape: "dot", text: "|| stop" + sAutoToggle });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (node.autoToggle > 0) {
|
|
29
|
+
node.timerAutoToggle = setTimeout(() => {
|
|
30
|
+
node.autoToggle = 0;
|
|
31
|
+
node.bInviaMessaggio = !node.bInviaMessaggio;
|
|
32
|
+
node.alignStatus();
|
|
33
|
+
}, node.autoToggle * 1000);
|
|
21
34
|
}
|
|
22
35
|
|
|
36
|
+
node.alignStatus();
|
|
37
|
+
|
|
23
38
|
this.on('input', function (msg) {
|
|
24
39
|
var sIncomingTopic = "";
|
|
25
40
|
if (msg.hasOwnProperty("topic")) {
|
|
@@ -36,23 +51,29 @@ module.exports = function (RED) {
|
|
|
36
51
|
|
|
37
52
|
msg.payload = ToBoolean(msg.payload); // 15/11/2021 Convert input to boolean.
|
|
38
53
|
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
// return;
|
|
42
|
-
// }
|
|
54
|
+
// 28/01/2022 Stop autotoggle
|
|
55
|
+
if (node.timerAutoToggle !== null) clearInterval(node.timerAutoToggle);
|
|
43
56
|
|
|
44
57
|
if (msg.hasOwnProperty("play")) {
|
|
45
|
-
node.currentMsg.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
if (node.currentMsg.payload !== undefined) {
|
|
59
|
+
node.currentMsg.isReplay = true;
|
|
60
|
+
setNodeStatus({ fill: "yellow", shape: "dot", text: "-> replay" });
|
|
61
|
+
// Restore previous status
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
if (node.bInviaMessaggio) {
|
|
64
|
+
setNodeStatus({ fill: "green", shape: "dot", text: "-> pass" });
|
|
65
|
+
} else {
|
|
66
|
+
setNodeStatus({ fill: "red", shape: "dot", text: "|| stop (stored last msg)" });
|
|
67
|
+
}
|
|
68
|
+
}, 1000)
|
|
69
|
+
node.send(node.currentMsg);
|
|
70
|
+
} else {
|
|
71
|
+
setNodeStatus({ fill: "grey", shape: "dot", text: "Nothing to replay" });
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
74
|
+
} else if (msg.hasOwnProperty("reset")) {
|
|
75
|
+
node.currentMsg = {};
|
|
76
|
+
setNodeStatus({ fill: "yellow", shape: "dot", text: "Deleted stored msg" });
|
|
56
77
|
return;
|
|
57
78
|
} else if (msg.payload === true) {
|
|
58
79
|
node.bInviaMessaggio = true;
|
|
@@ -65,8 +86,8 @@ module.exports = function (RED) {
|
|
|
65
86
|
}
|
|
66
87
|
}
|
|
67
88
|
}
|
|
89
|
+
node.currentMsg = RED.util.cloneMessage(msg);
|
|
68
90
|
if (node.bInviaMessaggio) {
|
|
69
|
-
node.currentMsg = msg;
|
|
70
91
|
node.send(msg);
|
|
71
92
|
}
|
|
72
93
|
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
RED.nodes.registerType('SumUltimate', {
|
|
3
|
+
category: 'boolean logic ultimate',
|
|
4
|
+
color: '#ff8080',
|
|
5
|
+
defaults: {
|
|
6
|
+
name: {
|
|
7
|
+
value: "Sum"
|
|
8
|
+
},
|
|
9
|
+
property: {
|
|
10
|
+
value: "payload"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
},
|
|
14
|
+
inputs: 1,
|
|
15
|
+
outputs: 1,
|
|
16
|
+
icon: "font-awesome/fa-plus",
|
|
17
|
+
label:
|
|
18
|
+
function () {
|
|
19
|
+
return this.name || "Sum";
|
|
20
|
+
},
|
|
21
|
+
paletteLabel: function () {
|
|
22
|
+
return "SumUltimate";
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<script type="text/x-red" data-template-name="SumUltimate">
|
|
28
|
+
<div class="form-row">
|
|
29
|
+
<b>Status Ultimate</b>    <span style="color:red"><i class="fa fa-question-circle"></i> <a target="_blank" href="https://github.com/Supergiovane/node-red-contrib-boolean-logic-ultimate"><u>Help online</u></a></span>
|
|
30
|
+
<br/>
|
|
31
|
+
<br/>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="form-row">
|
|
34
|
+
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
|
35
|
+
<input type="text" id="node-input-name" placeholder="Name">
|
|
36
|
+
</div>
|
|
37
|
+
<div class="form-row">
|
|
38
|
+
<label for="node-input-property"><i class="icon-tag"></i> Sum msg.</label>
|
|
39
|
+
<input type="text" id="node-input-property" placeholder="payload">
|
|
40
|
+
</div>
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<script type="text/x-red" data-help-name="SumUltimate">
|
|
44
|
+
<p>
|
|
45
|
+
SEE THE README FOR HELP CONFIGURING THE NODE
|
|
46
|
+
</p>
|
|
47
|
+
|
|
48
|
+
<p>
|
|
49
|
+
<a href="https://github.com/Supergiovane/node-red-contrib-boolean-logic-ultimate" target="_blank">Click here to learn how to configure the node.</a>
|
|
50
|
+
</p>
|
|
51
|
+
|
|
52
|
+
<a href="https://www.paypal.me/techtoday" target="_blank"><img src='https://img.shields.io/badge/Donate-PayPal-blue.svg?style=flat-square' width='30%'></a>
|
|
53
|
+
|
|
54
|
+
</script>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
module.exports = function (RED) {
|
|
2
|
+
function SumUltimate(config) {
|
|
3
|
+
RED.nodes.createNode(this, config);
|
|
4
|
+
this.config = config;
|
|
5
|
+
var node = this;
|
|
6
|
+
this.topics = {};
|
|
7
|
+
|
|
8
|
+
function setNodeStatus({ fill, shape, text }) {
|
|
9
|
+
var dDate = new Date();
|
|
10
|
+
node.status({ fill: fill, shape: shape, text: text + " (" + dDate.getDate() + ", " + dDate.toLocaleTimeString() + ")" })
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
setNodeStatus({ fill: "grey", shape: "dot", text: "" });
|
|
14
|
+
|
|
15
|
+
function fetchFromObject(obj, prop) {
|
|
16
|
+
|
|
17
|
+
if (obj === undefined) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
var _index = prop.indexOf('.')
|
|
22
|
+
if (_index > -1) {
|
|
23
|
+
return fetchFromObject(obj[prop.substring(0, _index)], prop.substr(_index + 1));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return obj[prop];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
this.on('input', function (msg) {
|
|
30
|
+
|
|
31
|
+
// handle reset
|
|
32
|
+
if (msg.hasOwnProperty("reset")) {
|
|
33
|
+
node.topics = {};
|
|
34
|
+
setNodeStatus({ fill: "grey", shape: "ring", text: "Reset" });
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!msg.hasOwnProperty("topic")) {
|
|
39
|
+
setNodeStatus({ fill: "red", shape: "ring", text: "Incoming msg without topic! Please set the topic." });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
let props = [] = this.config.property.split(".");
|
|
45
|
+
let ret = fetchFromObject(msg, this.config.property);
|
|
46
|
+
if (ret !== undefined) {
|
|
47
|
+
|
|
48
|
+
ret = Number(ret);
|
|
49
|
+
|
|
50
|
+
// Sum
|
|
51
|
+
if (!isNaN(ret) && isFinite(ret)) {
|
|
52
|
+
node.topics[msg.topic.toString()] = ret;
|
|
53
|
+
|
|
54
|
+
var quantita = 0;
|
|
55
|
+
var somma = Object.keys(node.topics).reduce(function (a, b) {
|
|
56
|
+
++quantita;
|
|
57
|
+
return a + node.topics[b];
|
|
58
|
+
}, 0);
|
|
59
|
+
|
|
60
|
+
msg.payload = somma; // Sum
|
|
61
|
+
msg.average = somma / quantita; // Average
|
|
62
|
+
msg.measurements = quantita; // Topics
|
|
63
|
+
|
|
64
|
+
// overwrite topic if configured
|
|
65
|
+
if (config.name) {
|
|
66
|
+
msg.topic = config.name;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// everything else
|
|
71
|
+
else {
|
|
72
|
+
setNodeStatus({ fill: "red", shape: "ring", text: "Not a number" });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
} else {
|
|
76
|
+
setNodeStatus({ fill: "red", shape: "ring", text: this.config.property + " is undefined." });
|
|
77
|
+
}
|
|
78
|
+
} catch (error) {
|
|
79
|
+
setNodeStatus({ fill: "red", shape: "ring", text: error.message });
|
|
80
|
+
}
|
|
81
|
+
setNodeStatus({ fill: "green", shape: "dot", text: "Sum " + msg.payload });
|
|
82
|
+
node.send(msg);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
RED.nodes.registerType("SumUltimate", SumUltimate);
|
|
88
|
+
}
|
package/img/sum.png
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-boolean-logic-ultimate",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.48",
|
|
4
4
|
"description": "A set of Node-RED enhanced boolean logic node, flow interruption node, blinker node, invert node, filter node, with persisten values after reboot and more.",
|
|
5
5
|
"author": "Supergiovane (https://github.com/Supergiovane)",
|
|
6
6
|
"dependencies": {
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
"SimpleOutputUltimate": "boolean-logic-ultimate/SimpleOutputUltimate.js",
|
|
30
30
|
"InjectUltimate": "boolean-logic-ultimate/InjectUltimate.js",
|
|
31
31
|
"StatusUltimate": "boolean-logic-ultimate/StatusUltimate.js",
|
|
32
|
-
"ImpulseUltimate": "boolean-logic-ultimate/ImpulseUltimate.js"
|
|
32
|
+
"ImpulseUltimate": "boolean-logic-ultimate/ImpulseUltimate.js",
|
|
33
|
+
"SumUltimate": "boolean-logic-ultimate/SumUltimate.js"
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
}
|