node-red-contrib-boolean-logic-ultimate 1.0.45 → 1.0.49

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 CHANGED
@@ -1,6 +1,23 @@
1
1
  # node-red-contrib-boolean-logic-ultimate
2
2
  [![Donate via PayPal](https://img.shields.io/badge/Donate-PayPal-blue.svg?style=flat-square)](https://www.paypal.me/techtoday)
3
3
 
4
+ <p>
5
+ <b>Version 1.0.48</b> February 2022<br/>
6
+ - NEW: TOGGLE node: Simple toggle node.</br>
7
+ </p>
8
+ <p>
9
+ <b>Version 1.0.48</b> February 2022<br/>
10
+ - NEW: SUM node: this new node makes sum, average and measurement count.</br>
11
+ </p>
12
+ <p>
13
+ <b>Version 1.0.47</b> February 2022<br/>
14
+ - NEW: Interrupt Flow: the node now stores the last message, even if in the "stop" state.</br>
15
+ </p>
16
+ <p>
17
+ <b>Version 1.0.46</b> February 2022<br/>
18
+ - NEW: Interrupt Flow: msg.reset will delete the stored message.</br>
19
+ - Updated the README file with samples.</br>
20
+ </p>
4
21
  <p>
5
22
  <b>Version 1.0.45</b> February 2022<br/>
6
23
  - NEW: Interrupt Flow: Now you can auto-toggle the startup behavior selection (to stop or to pass telegrams) after some pre-defined delays.</br>
package/README.md CHANGED
@@ -116,9 +116,41 @@ Resets all inputs to undefined.
116
116
 
117
117
  # INTERRUPT FLOWS ULTIMATE
118
118
 
119
- Whenever this node receives a payload = false from a specific topic, it stops output messages to the flow. As soon it receives payload = true from this topic, the output messages start to flow out again.<br/>
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
- The *Then* option, 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>
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
+
122
154
  See the example below.<br/>
123
155
 
124
156
  <img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-boolean-logic-ultimate/master/img/if0.png' width='60%'>
@@ -291,6 +323,57 @@ Pass <code>msg.payload = false</code> to the node to stop the running sequence</
291
323
 
292
324
  - Output: the node outputs a message you specified in the command textbox<br/>
293
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>
360
+
361
+ br/>
362
+ <br/>
363
+ <br/>
364
+ <br/>
365
+ <br/>
366
+
367
+ # TOGGLE ULTIMATE
368
+
369
+ The pourpose of this node is to toggle between true/false the payload of every incoming message.<br />
370
+
371
+
372
+ **INPUT**<br />
373
+
374
+ Any message that arrives on input, will be passwd through to the output with the payload toggled between true and false.
375
+
376
+
294
377
 
295
378
  [license-image]: https://img.shields.io/badge/license-MIT-blue.svg
296
379
  [license-url]: https://github.com/Supergiovane/node-red-contrib-boolean-logic-ultimate/master/LICENSE
@@ -49,7 +49,8 @@
49
49
  <label for="node-input-triggertopic"><i class="icon-tag"></i> Trigger by topic</label>
50
50
  <input type="text" id="node-input-triggertopic" placeholder="Name">
51
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.
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.
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.
53
54
  </i></div>
54
55
  </div>
55
56
 
@@ -55,17 +55,25 @@ module.exports = function (RED) {
55
55
  if (node.timerAutoToggle !== null) clearInterval(node.timerAutoToggle);
56
56
 
57
57
  if (msg.hasOwnProperty("play")) {
58
- node.currentMsg.isReplay = true;
59
- setNodeStatus({ fill: "yellow", shape: "dot", text: "-> replay" });
60
- // Restore previous status
61
- setTimeout(() => {
62
- if (node.bInviaMessaggio) {
63
- setNodeStatus({ fill: "green", shape: "dot", text: "-> pass" });
64
- } else {
65
- setNodeStatus({ fill: "red", shape: "dot", text: "|| stop (stored last msg)" });
66
- }
67
- }, 1000)
68
- node.send(node.currentMsg);
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" });
69
77
  return;
70
78
  } else if (msg.payload === true) {
71
79
  node.bInviaMessaggio = true;
@@ -78,8 +86,8 @@ module.exports = function (RED) {
78
86
  }
79
87
  }
80
88
  }
89
+ node.currentMsg = RED.util.cloneMessage(msg);
81
90
  if (node.bInviaMessaggio) {
82
- node.currentMsg = msg;
83
91
  node.send(msg);
84
92
  }
85
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>&nbsp&nbsp&nbsp&nbsp<span style="color:red"><i class="fa fa-question-circle"></i>&nbsp<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
+ }
@@ -0,0 +1,63 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('toggleUltimate', {
3
+ category: 'boolean logic ultimate',
4
+ color: '#ff8080',
5
+ defaults: {
6
+ name: {
7
+ value: "Toggle"
8
+ },
9
+ valueToToggle: { value: "true" }
10
+ },
11
+ inputs: 1,
12
+ outputs: 1,
13
+ icon: "serial.png",
14
+ label:
15
+ function () {
16
+ return this.name || "Toggle";
17
+ },
18
+ paletteLabel: function () {
19
+ return "toggleUltimate";
20
+ }
21
+ });
22
+ </script>
23
+
24
+ <script type="text/x-red" data-template-name="toggleUltimate">
25
+ <div class="form-row">
26
+ <b>Toggle Ultimate</b>&nbsp&nbsp&nbsp&nbsp<span style="color:red"><i class="fa fa-question-circle"></i>&nbsp<a target="_blank" href="https://github.com/Supergiovane/node-red-contrib-boolean-logic-ultimate"><u>Help online</u></a></span>
27
+ <br/>
28
+ <br/>
29
+ </div>
30
+ <div class="form-row">
31
+ <label for="node-input-name"><i class="icon-tag"></i> Name</label>
32
+ <input type="text" id="node-input-name" placeholder="Name">
33
+ </div>
34
+ <div class="form-row">
35
+ <label style="width:160px" for="node-input-valueToToggle"><i class="fa fa-toggle-on"></i> Initial value</label>
36
+ <select type="text" id="node-input-valueToToggle" placeholder="">
37
+ <option value="true">Initialize wiht True</option>
38
+ <option value="false">Initialize with False</option>
39
+ </select>
40
+ </div>
41
+ <!-- <div class="form-row">
42
+ <input type="checkbox" id="node-input-homeAssitantBoolean" style="display:inline-block; width:auto; vertical-align:top;">
43
+ &nbsp;
44
+ <label style="width:85%" for="node-input-homeAssitantBoolean">
45
+ <i class="fa fa-home"></i>&nbsp;Output Home Assistant "on"/"off" instead of true/false
46
+ </label>
47
+ </div> -->
48
+
49
+
50
+ </script>
51
+
52
+ <script type="text/x-red" data-help-name="toggleUltimate">
53
+ <p>
54
+ SEE THE README FOR HELP CONFIGURING THE NODE
55
+ </p>
56
+
57
+ <p>
58
+ <a href="https://github.com/Supergiovane/node-red-contrib-boolean-logic-ultimate" target="_blank">Click here to learn how to configure the node.</a>
59
+ </p>
60
+
61
+ <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>
62
+
63
+ </script>
@@ -0,0 +1,71 @@
1
+ module.exports = function (RED) {
2
+ function toggleUltimate(config) {
3
+ RED.nodes.createNode(this, config);
4
+ this.config = config;
5
+ var node = this;
6
+ node.valueToToggle = config.valueToToggle === undefined ? true : ToBoolean(config.valueToToggle);
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: "Waiting" });
14
+
15
+ this.on('input', function (msg) {
16
+
17
+
18
+ // 15/11/2021 inform user about undefined topic or payload
19
+ if (!msg.hasOwnProperty("payload") || msg.payload === undefined || msg.payload === null) {
20
+ setNodeStatus({ fill: "red", shape: "dot", text: "Received invalid payload from " + msg.topic || "" });
21
+ return;
22
+ }
23
+
24
+ node.valueToToggle = !node.valueToToggle;
25
+
26
+ var msgOUT = RED.util.cloneMessage(msg);
27
+ try {
28
+ msgOUT.payload = node.valueToToggle;
29
+ setNodeStatus({ fill: "green", shape: "dot", text: "(Send) " + msgOUT.payload });
30
+ node.send(msgOUT);
31
+ } catch (error) {
32
+ setNodeStatus({ fill: "red", shape: "dot", text: "Unable to invert the input payload " + bRes });
33
+ }
34
+
35
+ });
36
+
37
+
38
+
39
+ function ToBoolean(value) {
40
+ var res = false;
41
+ var decimal = /^\s*[+-]{0,1}\s*([\d]+(\.[\d]*)*)\s*$/
42
+
43
+ if (typeof value === 'boolean') {
44
+ res = value;
45
+ }
46
+ else if (typeof value === 'number' || typeof value === 'string') {
47
+
48
+ if (typeof value === "string" && value.toLowerCase() === "on") return true;
49
+ if (typeof value === "string" && value.toLowerCase() === "off") return false;
50
+
51
+ // Is it formated as a decimal number?
52
+ if (decimal.test(value)) {
53
+ var v = parseFloat(value);
54
+ res = v != 0;
55
+ }
56
+ else {
57
+ res = value.toLowerCase() === "true";
58
+ }
59
+ }
60
+
61
+ return res;
62
+ };
63
+
64
+
65
+
66
+ }
67
+
68
+
69
+
70
+ RED.nodes.registerType("toggleUltimate", toggleUltimate);
71
+ }
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.45",
3
+ "version": "1.0.49",
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,9 @@
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",
34
+ "toggleUltimate": "boolean-logic-ultimate/toggleUltimate.js"
33
35
  }
34
36
  }
35
37
  }