node-red-contrib-boolean-logic-ultimate 1.2.3 → 1.2.5
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 +12 -0
- package/README.md +15 -2
- package/boolean-logic-ultimate/RailwaySwitchUltimate.html +100 -10
- package/boolean-logic-ultimate/RailwaySwitchUltimate.js +42 -9
- package/examples/BlinkerUltimate.json +119 -0
- package/examples/BooleanLogicUltimate.json +171 -0
- package/examples/Comparator.json +104 -0
- package/examples/FilterUltimate.json +105 -0
- package/examples/ImpulseUltimate.json +82 -0
- package/examples/InjectUltimate.json +100 -0
- package/examples/InterruptFlowUltimate.json +153 -0
- package/examples/InvertUltimate.json +88 -0
- package/examples/KalmanFilterUltimate.json +96 -0
- package/examples/PresenceSimulatorUltimate.json +105 -0
- package/examples/RailwaySwitchUltimate.json +186 -0
- package/examples/RateLimiterUltimate.json +178 -0
- package/examples/SimpleOutputUltimate.json +80 -0
- package/examples/StaircaseLightUltimate.json +145 -0
- package/examples/StatusUltimate.json +61 -0
- package/examples/SumUltimate.json +222 -0
- package/examples/toggleUltimate.json +63 -0
- package/examples/translator-config.json +99 -0
- package/package.json +2 -2
- package/test/helpers.js +21 -1
- package/test/presence-simulator.spec.js +5 -5
- package/test/railway-switch.spec.js +251 -0
- package/test/rate-limiter.spec.js +8 -8
- package/test/staircase-light.spec.js +20 -7
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
|
|
4
4
|
# CHANGELOG
|
|
5
5
|
|
|
6
|
+
|
|
7
|
+
<p>
|
|
8
|
+
<b>Version 1.2.5</b> January 2026<br/>
|
|
9
|
+
- RailwaySwitchUltimate: configurable output pins (1..10) using Node-RED standard <code>outputs</code> property + migration from legacy <code>outputCount</code> (fixes editor placement issue).<br/>
|
|
10
|
+
- Updated README and examples accordingly.</br>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p>
|
|
14
|
+
<b>Version 1.2.4</b> January 2026<br/>
|
|
15
|
+
- Added sample flows in the "example" folder. Just import it via the "import" menu of node-red</br>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
6
18
|
<p>
|
|
7
19
|
<b>Version 1.2.3</b> November 2025<br/>
|
|
8
20
|
- Impulse node allows now to send JSON as payload. Grazie Waldmensch1 !!</br>
|
package/README.md
CHANGED
|
@@ -17,6 +17,18 @@ A set of Node-RED enhanced boolean logic and utility nodes, with persistent valu
|
|
|
17
17
|
|
|
18
18
|
- See <a href="https://github.com/Supergiovane/node-red-contrib-boolean-logic-ultimate/blob/master/CHANGELOG.md">here the changelog</a>
|
|
19
19
|
|
|
20
|
+
<br/>
|
|
21
|
+
<br/>
|
|
22
|
+
|
|
23
|
+
# EXAMPLES
|
|
24
|
+
|
|
25
|
+
Importable Node-RED example flows are available in the [`examples/`](examples/) folder (one JSON per node). See [`examples/README.md`](examples/README.md) for a quick overview.
|
|
26
|
+
|
|
27
|
+
**How to import**
|
|
28
|
+
|
|
29
|
+
- Node-RED editor → Menu (☰) → **Import** → **Examples** and select an example from `node-red-contrib-boolean-logic-ultimate`
|
|
30
|
+
|
|
31
|
+
|
|
20
32
|
<br/>
|
|
21
33
|
<br/>
|
|
22
34
|
|
|
@@ -456,6 +468,7 @@ The railway switcher, redirect the incoming messages to one ot the avaiable outp
|
|
|
456
468
|
| Property | Description |
|
|
457
469
|
| -------------- | ---------------------------------------------------------------------------------------------------- |
|
|
458
470
|
| Switcher topic | Whenever the node receives a payload from this **topic**, it redirects the input messages to a choosen output PIN. |
|
|
471
|
+
| Output pins | Number of output pins (outputs) to show. Default is 5, range is 1..10. |
|
|
459
472
|
| With Input | It's the msg property to be evaluated. *By default, it is "payload", but you can also specify other properties, for example "payload.value"* |
|
|
460
473
|
| Translator | Translates the incoming <code>payload</code> value. This allows the compatibility with, for example, **HomeAssistant** nodes. |
|
|
461
474
|
|
|
@@ -467,7 +480,7 @@ Once an output PIN has been choosen, all messages passing through the node will
|
|
|
467
480
|
|
|
468
481
|
: topic (string|number) : this is the topic of the switcher message.
|
|
469
482
|
|
|
470
|
-
: payload (number|boolean) : this is the ouput PIN selector, base 0 (0 is the first output PIN).
|
|
483
|
+
: payload (number|boolean) : this is the ouput PIN selector, base 0 (0 is the first output PIN). Valid range is <code>0..(outputs-1)</code>.
|
|
471
484
|
|
|
472
485
|
### JSON switcher message
|
|
473
486
|
|
|
@@ -513,7 +526,7 @@ See the example below.<br/>
|
|
|
513
526
|
Copy and paste it into your flow
|
|
514
527
|
|
|
515
528
|
```javascript
|
|
516
|
-
[{"id":"8243309f7c926112","type":"RailwaySwitchUltimate","z":"aa3efc585a6c7b9b","name":"Railway Switch","triggertopic":"switcher","initializewith":"3","payloadPropName":"payload","translatorConfig":"","x":350,"y":260,"wires":[["7f5a2c19a9ef64c8"],["5a35a650b225d910"],[],[],[]]},{"id":"d7bbc077bc20f4ea","type":"InjectUltimate","z":"aa3efc585a6c7b9b","name":"Junction switcher to Rail 0","topic":"","curVal":true,"outputJSON":"{ \n\t\"payload\":0,\n\t\"topic\":\"switcher\"\n}","x":350,"y":80,"wires":[[],[],[],["8243309f7c926112"]]},{"id":"5656d0c2ba66ed5e","type":"InjectUltimate","z":"aa3efc585a6c7b9b","name":"Junction switcher to Rail 1","topic":"","curVal":true,"outputJSON":"{ \n\t\"payload\":\"1\",\n\t\"topic\":\"switcher\"\n}","x":350,"y":160,"wires":[[],[],[],["8243309f7c926112"]]},{"id":"2253336fa8374c78","type":"InjectUltimate","z":"aa3efc585a6c7b9b","name":"Train","topic":"","curVal":true,"outputJSON":"{ \n\t\"payload\":\"hello\",\n\t\"topic\":\"I'm a train!\"\n}","x":110,"y":280,"wires":[["8243309f7c926112"],[],[],[]]},{"id":"7f5a2c19a9ef64c8","type":"debug","z":"aa3efc585a6c7b9b","name":"Rail 0","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":590,"y":260,"wires":[]},{"id":"5a35a650b225d910","type":"debug","z":"aa3efc585a6c7b9b","name":"Rail 1","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":590,"y":300,"wires":[]}]
|
|
529
|
+
[{"id":"8243309f7c926112","type":"RailwaySwitchUltimate","z":"aa3efc585a6c7b9b","name":"Railway Switch","triggertopic":"switcher","outputs":5,"initializewith":"3","payloadPropName":"payload","translatorConfig":"","x":350,"y":260,"wires":[["7f5a2c19a9ef64c8"],["5a35a650b225d910"],[],[],[]]},{"id":"d7bbc077bc20f4ea","type":"InjectUltimate","z":"aa3efc585a6c7b9b","name":"Junction switcher to Rail 0","topic":"","curVal":true,"outputJSON":"{ \n\t\"payload\":0,\n\t\"topic\":\"switcher\"\n}","x":350,"y":80,"wires":[[],[],[],["8243309f7c926112"]]},{"id":"5656d0c2ba66ed5e","type":"InjectUltimate","z":"aa3efc585a6c7b9b","name":"Junction switcher to Rail 1","topic":"","curVal":true,"outputJSON":"{ \n\t\"payload\":\"1\",\n\t\"topic\":\"switcher\"\n}","x":350,"y":160,"wires":[[],[],[],["8243309f7c926112"]]},{"id":"2253336fa8374c78","type":"InjectUltimate","z":"aa3efc585a6c7b9b","name":"Train","topic":"","curVal":true,"outputJSON":"{ \n\t\"payload\":\"hello\",\n\t\"topic\":\"I'm a train!\"\n}","x":110,"y":280,"wires":[["8243309f7c926112"],[],[],[]]},{"id":"7f5a2c19a9ef64c8","type":"debug","z":"aa3efc585a6c7b9b","name":"Rail 0","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":590,"y":260,"wires":[]},{"id":"5a35a650b225d910","type":"debug","z":"aa3efc585a6c7b9b","name":"Rail 1","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":590,"y":300,"wires":[]}]
|
|
517
530
|
```
|
|
518
531
|
|
|
519
532
|
<br/>
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
defaults: {
|
|
6
6
|
name: { value: "Railway Switch" },
|
|
7
7
|
triggertopic: { value: "switcher" },
|
|
8
|
+
outputs: { value: 5 },
|
|
9
|
+
outputCount: { value: 5 }, // legacy (pre-outputs property) kept for backward compatibility
|
|
8
10
|
initializewith: { value: "1" },
|
|
9
11
|
payloadPropName: { value: "payload", required: false },
|
|
10
12
|
translatorConfig: { type: "translator-config", required: false }
|
|
@@ -22,9 +24,87 @@
|
|
|
22
24
|
paletteLabel: function () {
|
|
23
25
|
return "Railway Switch";
|
|
24
26
|
},
|
|
27
|
+
onadd: function () {
|
|
28
|
+
// Prefer the saved `wires.length` (it reflects the node's output count in the flow),
|
|
29
|
+
// otherwise fall back to legacy `outputCount`, then default to 5.
|
|
30
|
+
function clampOutputs(raw) {
|
|
31
|
+
var value = parseInt(raw, 10);
|
|
32
|
+
if (isNaN(value)) value = 5;
|
|
33
|
+
value = Math.max(1, Math.min(10, value));
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
var wiresCount = Array.isArray(this.wires) ? this.wires.length : NaN;
|
|
38
|
+
if (!isNaN(wiresCount) && wiresCount >= 1) {
|
|
39
|
+
this.outputs = clampOutputs(wiresCount);
|
|
40
|
+
this.outputCount = this.outputs; // keep legacy aligned
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
var legacy = parseInt(this.outputCount, 10);
|
|
45
|
+
if (!isNaN(legacy)) {
|
|
46
|
+
this.outputs = clampOutputs(legacy);
|
|
47
|
+
this.outputCount = this.outputs;
|
|
48
|
+
}
|
|
49
|
+
},
|
|
25
50
|
oneditprepare: function () {
|
|
26
51
|
if ($("#node-input-payloadPropName").val() === "") $("#node-input-payloadPropName").val("payload");
|
|
27
52
|
$("#node-input-payloadPropName").typedInput({ default: 'msg', types: ['msg'] });
|
|
53
|
+
|
|
54
|
+
function rebuildPinSelect(outputCount) {
|
|
55
|
+
const $select = $("#node-input-initializewith");
|
|
56
|
+
const previous = $select.val();
|
|
57
|
+
$select.empty();
|
|
58
|
+
for (let i = 0; i < outputCount; i += 1) {
|
|
59
|
+
$("<option></option>").val(String(i)).text("PIN " + i).appendTo($select);
|
|
60
|
+
}
|
|
61
|
+
let nextValue = previous;
|
|
62
|
+
if (nextValue === undefined || nextValue === null || nextValue === "" || parseInt(nextValue, 10) >= outputCount) {
|
|
63
|
+
nextValue = "0";
|
|
64
|
+
}
|
|
65
|
+
$select.val(nextValue);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function clampOutputs(raw) {
|
|
69
|
+
var value = parseInt(raw, 10);
|
|
70
|
+
if (isNaN(value)) value = 5;
|
|
71
|
+
value = Math.max(1, Math.min(10, value));
|
|
72
|
+
return value;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Migration: prefer saved wires length, then legacy outputCount, then current outputs.
|
|
76
|
+
var outputs = clampOutputs($("#node-input-outputs").val());
|
|
77
|
+
var wiresCount = Array.isArray(this.wires) ? this.wires.length : NaN;
|
|
78
|
+
if (!isNaN(wiresCount) && wiresCount >= 1 && wiresCount <= 10) {
|
|
79
|
+
outputs = clampOutputs(wiresCount);
|
|
80
|
+
} else {
|
|
81
|
+
var legacy = parseInt(this.outputCount, 10);
|
|
82
|
+
if (!isNaN(legacy) && legacy >= 1 && legacy <= 10 && outputs === 5 && legacy !== 5) {
|
|
83
|
+
outputs = legacy;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
$("#node-input-outputs").val(String(outputs));
|
|
87
|
+
rebuildPinSelect(outputs);
|
|
88
|
+
|
|
89
|
+
$("#node-input-outputs").on("change", function () {
|
|
90
|
+
var nextOutputs = clampOutputs($(this).val());
|
|
91
|
+
$(this).val(String(nextOutputs));
|
|
92
|
+
rebuildPinSelect(nextOutputs);
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
oneditsave: function () {
|
|
96
|
+
var value = parseInt($("#node-input-outputs").val(), 10);
|
|
97
|
+
if (isNaN(value)) value = 5;
|
|
98
|
+
value = Math.max(1, Math.min(10, value));
|
|
99
|
+
this.outputs = value;
|
|
100
|
+
this.outputCount = value; // keep legacy field aligned for backward compatibility
|
|
101
|
+
|
|
102
|
+
var init = parseInt($("#node-input-initializewith").val(), 10);
|
|
103
|
+
if (isNaN(init) || init < 0 || init >= value) {
|
|
104
|
+
this.initializewith = "0";
|
|
105
|
+
} else {
|
|
106
|
+
this.initializewith = String(init);
|
|
107
|
+
}
|
|
28
108
|
}
|
|
29
109
|
});
|
|
30
110
|
</script>
|
|
@@ -41,23 +121,32 @@
|
|
|
41
121
|
<input type="text" id="node-input-name" placeholder="Name">
|
|
42
122
|
</div>
|
|
43
123
|
|
|
44
|
-
|
|
124
|
+
<div class="form-row">
|
|
45
125
|
<label for="node-input-triggertopic"><i class="icon-tag"></i> Switcher topic</label>
|
|
46
126
|
<input type="text" id="node-input-triggertopic" placeholder="Name">
|
|
47
127
|
</div>
|
|
128
|
+
<div class="form-row">
|
|
129
|
+
<label style="width:160px" for="node-input-outputs"><i class="fa fa-circle-o-notch"></i> Output pins</label>
|
|
130
|
+
<select type="text" id="node-input-outputs" style="width:250px">
|
|
131
|
+
<option value="1">1</option>
|
|
132
|
+
<option value="2">2</option>
|
|
133
|
+
<option value="3">3</option>
|
|
134
|
+
<option value="4">4</option>
|
|
135
|
+
<option value="5">5</option>
|
|
136
|
+
<option value="6">6</option>
|
|
137
|
+
<option value="7">7</option>
|
|
138
|
+
<option value="8">8</option>
|
|
139
|
+
<option value="9">9</option>
|
|
140
|
+
<option value="10">10</option>
|
|
141
|
+
</select>
|
|
142
|
+
</div>
|
|
48
143
|
<div class="form-row">
|
|
49
144
|
<label for="node-input-payloadPropName"><i class="fa fa-ellipsis-h"></i> With Input</label>
|
|
50
145
|
<input type="text" id="node-input-payloadPropName">
|
|
51
146
|
</div>
|
|
52
147
|
<div class="form-row">
|
|
53
148
|
<label style="width:160px" for="node-input-initializewith"><i class="fa fa-home"></i> At node-red start</label>
|
|
54
|
-
<select type="text" id="node-input-initializewith" placeholder="" style="width:250px">
|
|
55
|
-
<option value="0">PIN 0</option>
|
|
56
|
-
<option value="1">PIN 1</option>
|
|
57
|
-
<option value="2">PIN 2</option>
|
|
58
|
-
<option value="3">PIN 3</option>
|
|
59
|
-
<option value="4">PIN 4</option>
|
|
60
|
-
</select>
|
|
149
|
+
<select type="text" id="node-input-initializewith" placeholder="" style="width:250px"></select>
|
|
61
150
|
</div>
|
|
62
151
|
<div class="form-row">
|
|
63
152
|
<label for="node-input-translatorConfig">
|
|
@@ -73,6 +162,7 @@
|
|
|
73
162
|
|Property|Description|
|
|
74
163
|
|--|--|
|
|
75
164
|
| Switcher topic | Whenever the node receives a payload from this **topic**, it redirects the input messages to a choosen output PIN. |
|
|
165
|
+
| Output pins | Number of output pins to display (1..10). |
|
|
76
166
|
| With Input | It's the msg property to be evaluated. *By default, it is "payload", but you can also specify other properties, for example "payload.value"* |
|
|
77
167
|
| Translator | Translates the incoming <code>payload</code> value. This allows the compatibility with, for example, **HomeAssistant** nodes. |
|
|
78
168
|
|
|
@@ -82,7 +172,7 @@ The *Switcher topic* controls where the railway switch must be switched, between
|
|
|
82
172
|
Once an output PIN has been choosen, all messages passing through the node will be deviated to te choosen output PIN.
|
|
83
173
|
|
|
84
174
|
: topic (string|number) : this is the topic of the switcher message.
|
|
85
|
-
: payload (number|boolean) : this is the
|
|
175
|
+
: payload (number|boolean) : this is the output PIN selector, base 0 (0 is the first output PIN). Valid range is <code>0..(output pins-1)</code>.
|
|
86
176
|
|
|
87
177
|
### JSON switcher message
|
|
88
178
|
|
|
@@ -122,4 +212,4 @@ this JSON input message redirects all input messages to the third PIN, and so on
|
|
|
122
212
|
|
|
123
213
|
[Find it useful?](https://www.paypal.me/techtoday)
|
|
124
214
|
|
|
125
|
-
</script>
|
|
215
|
+
</script>
|
|
@@ -4,12 +4,31 @@ module.exports = function (RED) {
|
|
|
4
4
|
this.config = config;
|
|
5
5
|
var node = this;
|
|
6
6
|
node.currentMsg = {}; // Stores current payload
|
|
7
|
+
|
|
8
|
+
const outputCountRaw =
|
|
9
|
+
config.outputs !== undefined ? parseInt(config.outputs, 10) : parseInt(config.outputCount, 10);
|
|
10
|
+
node.outputCount = Number.isFinite(outputCountRaw)
|
|
11
|
+
? Math.max(1, Math.min(10, outputCountRaw))
|
|
12
|
+
: 5;
|
|
13
|
+
|
|
7
14
|
node.sTriggerTopic =
|
|
8
15
|
node.config.triggertopic.replace(
|
|
9
16
|
/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi,
|
|
10
17
|
""
|
|
11
18
|
) || "trigger"; // Topic controlling the sRailway
|
|
12
|
-
|
|
19
|
+
|
|
20
|
+
function parsePinIndex(value) {
|
|
21
|
+
if (value === false) return 0;
|
|
22
|
+
if (value === true) return 1;
|
|
23
|
+
const parsed = parseInt(String(value), 10);
|
|
24
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const initialPin = parsePinIndex(node.config.initializewith);
|
|
28
|
+
node.railIndex =
|
|
29
|
+
initialPin === null
|
|
30
|
+
? 0
|
|
31
|
+
: Math.max(0, Math.min(node.outputCount - 1, initialPin)); // Railway selector
|
|
13
32
|
|
|
14
33
|
function setNodeStatus({ fill, shape, text }) {
|
|
15
34
|
let dDate = new Date();
|
|
@@ -30,7 +49,7 @@ module.exports = function (RED) {
|
|
|
30
49
|
setNodeStatus({
|
|
31
50
|
fill: "green",
|
|
32
51
|
shape: "dot",
|
|
33
|
-
text: "-> PIN " + node.
|
|
52
|
+
text: "-> PIN " + node.railIndex,
|
|
34
53
|
});
|
|
35
54
|
|
|
36
55
|
};
|
|
@@ -67,7 +86,7 @@ module.exports = function (RED) {
|
|
|
67
86
|
setNodeStatus({
|
|
68
87
|
fill: "red",
|
|
69
88
|
shape: "dot",
|
|
70
|
-
text: "Received invalid payload from " + msg.topic || "",
|
|
89
|
+
text: "Received invalid payload from " + (msg.topic || ""),
|
|
71
90
|
});
|
|
72
91
|
return;
|
|
73
92
|
}
|
|
@@ -78,17 +97,31 @@ module.exports = function (RED) {
|
|
|
78
97
|
);
|
|
79
98
|
if (msg.payload === undefined) return null;
|
|
80
99
|
|
|
81
|
-
|
|
100
|
+
const nextPin = parsePinIndex(msg.payload);
|
|
101
|
+
if (nextPin === null || nextPin < 0 || nextPin >= node.outputCount) {
|
|
102
|
+
setNodeStatus({
|
|
103
|
+
fill: "red",
|
|
104
|
+
shape: "dot",
|
|
105
|
+
text:
|
|
106
|
+
"Invalid PIN " +
|
|
107
|
+
String(msg.payload) +
|
|
108
|
+
" (valid 0.." +
|
|
109
|
+
String(node.outputCount - 1) +
|
|
110
|
+
")",
|
|
111
|
+
});
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
node.railIndex = nextPin;
|
|
82
116
|
node.alignStatus();
|
|
83
117
|
return; // DONT'S SEND THIS MESSAGE
|
|
84
118
|
}
|
|
85
119
|
}
|
|
86
120
|
node.currentMsg = RED.util.cloneMessage(msg);
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (node.sRailway === "4") node.send([null, null, null, null, msg]);
|
|
121
|
+
|
|
122
|
+
const out = new Array(node.outputCount).fill(null);
|
|
123
|
+
out[node.railIndex] = msg;
|
|
124
|
+
node.send(out);
|
|
92
125
|
});
|
|
93
126
|
}
|
|
94
127
|
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "blk_tab_1",
|
|
4
|
+
"type": "tab",
|
|
5
|
+
"label": "BlinkerUltimate - start/stop/interval",
|
|
6
|
+
"disabled": false,
|
|
7
|
+
"info": "Esempio: avvia/ferma il blink e cambia l'intervallo tramite msg.interval."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": "blk_cmt_1",
|
|
11
|
+
"type": "comment",
|
|
12
|
+
"z": "blk_tab_1",
|
|
13
|
+
"name": "Start/Stop + cambio intervallo",
|
|
14
|
+
"info": "payload=true avvia; payload=false ferma. msg.interval (ms) cambia la frequenza.",
|
|
15
|
+
"x": 220,
|
|
16
|
+
"y": 60,
|
|
17
|
+
"wires": []
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "blk_inj_start",
|
|
21
|
+
"type": "inject",
|
|
22
|
+
"z": "blk_tab_1",
|
|
23
|
+
"name": "Start (true)",
|
|
24
|
+
"props": [{ "p": "payload" }],
|
|
25
|
+
"repeat": "",
|
|
26
|
+
"crontab": "",
|
|
27
|
+
"once": false,
|
|
28
|
+
"onceDelay": 0.1,
|
|
29
|
+
"topic": "",
|
|
30
|
+
"payload": "true",
|
|
31
|
+
"payloadType": "bool",
|
|
32
|
+
"x": 150,
|
|
33
|
+
"y": 140,
|
|
34
|
+
"wires": [["blk_node_1"]]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "blk_inj_stop",
|
|
38
|
+
"type": "inject",
|
|
39
|
+
"z": "blk_tab_1",
|
|
40
|
+
"name": "Stop (false)",
|
|
41
|
+
"props": [{ "p": "payload" }],
|
|
42
|
+
"repeat": "",
|
|
43
|
+
"crontab": "",
|
|
44
|
+
"once": false,
|
|
45
|
+
"onceDelay": 0.1,
|
|
46
|
+
"topic": "",
|
|
47
|
+
"payload": "false",
|
|
48
|
+
"payloadType": "bool",
|
|
49
|
+
"x": 150,
|
|
50
|
+
"y": 180,
|
|
51
|
+
"wires": [["blk_node_1"]]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "blk_inj_interval",
|
|
55
|
+
"type": "inject",
|
|
56
|
+
"z": "blk_tab_1",
|
|
57
|
+
"name": "Interval 200ms + start",
|
|
58
|
+
"props": [
|
|
59
|
+
{ "p": "payload", "v": "true", "vt": "bool" },
|
|
60
|
+
{ "p": "interval", "v": "200", "vt": "num" }
|
|
61
|
+
],
|
|
62
|
+
"repeat": "",
|
|
63
|
+
"crontab": "",
|
|
64
|
+
"once": false,
|
|
65
|
+
"onceDelay": 0.1,
|
|
66
|
+
"x": 190,
|
|
67
|
+
"y": 220,
|
|
68
|
+
"wires": [["blk_node_1"]]
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"id": "blk_node_1",
|
|
72
|
+
"type": "BlinkerUltimate",
|
|
73
|
+
"z": "blk_tab_1",
|
|
74
|
+
"name": "Blinker",
|
|
75
|
+
"stopbehaviorPIN1": "0",
|
|
76
|
+
"stopbehaviorPIN2": "1",
|
|
77
|
+
"blinkfrequency": "500",
|
|
78
|
+
"initializewith": "0",
|
|
79
|
+
"payloadPropName": "payload",
|
|
80
|
+
"x": 390,
|
|
81
|
+
"y": 180,
|
|
82
|
+
"wires": [["blk_dbg_1"], ["blk_dbg_2"]]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "blk_dbg_1",
|
|
86
|
+
"type": "debug",
|
|
87
|
+
"z": "blk_tab_1",
|
|
88
|
+
"name": "PIN1",
|
|
89
|
+
"active": true,
|
|
90
|
+
"tosidebar": true,
|
|
91
|
+
"console": false,
|
|
92
|
+
"tostatus": false,
|
|
93
|
+
"complete": "payload",
|
|
94
|
+
"targetType": "msg",
|
|
95
|
+
"statusVal": "",
|
|
96
|
+
"statusType": "auto",
|
|
97
|
+
"x": 570,
|
|
98
|
+
"y": 160,
|
|
99
|
+
"wires": []
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"id": "blk_dbg_2",
|
|
103
|
+
"type": "debug",
|
|
104
|
+
"z": "blk_tab_1",
|
|
105
|
+
"name": "PIN2 (inverted)",
|
|
106
|
+
"active": true,
|
|
107
|
+
"tosidebar": true,
|
|
108
|
+
"console": false,
|
|
109
|
+
"tostatus": false,
|
|
110
|
+
"complete": "payload",
|
|
111
|
+
"targetType": "msg",
|
|
112
|
+
"statusVal": "",
|
|
113
|
+
"statusType": "auto",
|
|
114
|
+
"x": 610,
|
|
115
|
+
"y": 200,
|
|
116
|
+
"wires": []
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "bgu_tab_1",
|
|
4
|
+
"type": "tab",
|
|
5
|
+
"label": "BooleanLogicUltimate - AND/OR/XOR",
|
|
6
|
+
"disabled": false,
|
|
7
|
+
"info": "Esempio base: 2 ingressi identificati da msg.topic (a/b). Il nodo calcola AND/OR/XOR e li espone su 3 uscite."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": "bgu_cmt_1",
|
|
11
|
+
"type": "comment",
|
|
12
|
+
"z": "bgu_tab_1",
|
|
13
|
+
"name": "Invia A e B (topic diversi) per calcolare AND/OR/XOR",
|
|
14
|
+
"info": "Clicca gli inject (A/B true/false). Il nodo valuta quando ha ricevuto almeno un valore per ciascun topic, fino al conteggio inputCount.",
|
|
15
|
+
"x": 250,
|
|
16
|
+
"y": 60,
|
|
17
|
+
"wires": []
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "bgu_inj_a_true",
|
|
21
|
+
"type": "inject",
|
|
22
|
+
"z": "bgu_tab_1",
|
|
23
|
+
"name": "A = true",
|
|
24
|
+
"props": [
|
|
25
|
+
{ "p": "payload" },
|
|
26
|
+
{ "p": "topic", "vt": "str" }
|
|
27
|
+
],
|
|
28
|
+
"repeat": "",
|
|
29
|
+
"crontab": "",
|
|
30
|
+
"once": false,
|
|
31
|
+
"onceDelay": 0.1,
|
|
32
|
+
"topic": "a",
|
|
33
|
+
"payload": "true",
|
|
34
|
+
"payloadType": "bool",
|
|
35
|
+
"x": 120,
|
|
36
|
+
"y": 120,
|
|
37
|
+
"wires": [["bgu_gate_1"]]
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "bgu_inj_a_false",
|
|
41
|
+
"type": "inject",
|
|
42
|
+
"z": "bgu_tab_1",
|
|
43
|
+
"name": "A = false",
|
|
44
|
+
"props": [
|
|
45
|
+
{ "p": "payload" },
|
|
46
|
+
{ "p": "topic", "vt": "str" }
|
|
47
|
+
],
|
|
48
|
+
"repeat": "",
|
|
49
|
+
"crontab": "",
|
|
50
|
+
"once": false,
|
|
51
|
+
"onceDelay": 0.1,
|
|
52
|
+
"topic": "a",
|
|
53
|
+
"payload": "false",
|
|
54
|
+
"payloadType": "bool",
|
|
55
|
+
"x": 120,
|
|
56
|
+
"y": 160,
|
|
57
|
+
"wires": [["bgu_gate_1"]]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"id": "bgu_inj_b_true",
|
|
61
|
+
"type": "inject",
|
|
62
|
+
"z": "bgu_tab_1",
|
|
63
|
+
"name": "B = true",
|
|
64
|
+
"props": [
|
|
65
|
+
{ "p": "payload" },
|
|
66
|
+
{ "p": "topic", "vt": "str" }
|
|
67
|
+
],
|
|
68
|
+
"repeat": "",
|
|
69
|
+
"crontab": "",
|
|
70
|
+
"once": false,
|
|
71
|
+
"onceDelay": 0.1,
|
|
72
|
+
"topic": "b",
|
|
73
|
+
"payload": "true",
|
|
74
|
+
"payloadType": "bool",
|
|
75
|
+
"x": 120,
|
|
76
|
+
"y": 220,
|
|
77
|
+
"wires": [["bgu_gate_1"]]
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"id": "bgu_inj_b_false",
|
|
81
|
+
"type": "inject",
|
|
82
|
+
"z": "bgu_tab_1",
|
|
83
|
+
"name": "B = false",
|
|
84
|
+
"props": [
|
|
85
|
+
{ "p": "payload" },
|
|
86
|
+
{ "p": "topic", "vt": "str" }
|
|
87
|
+
],
|
|
88
|
+
"repeat": "",
|
|
89
|
+
"crontab": "",
|
|
90
|
+
"once": false,
|
|
91
|
+
"onceDelay": 0.1,
|
|
92
|
+
"topic": "b",
|
|
93
|
+
"payload": "false",
|
|
94
|
+
"payloadType": "bool",
|
|
95
|
+
"x": 120,
|
|
96
|
+
"y": 260,
|
|
97
|
+
"wires": [["bgu_gate_1"]]
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"id": "bgu_gate_1",
|
|
101
|
+
"type": "BooleanLogicUltimate",
|
|
102
|
+
"z": "bgu_tab_1",
|
|
103
|
+
"name": "",
|
|
104
|
+
"payloadPropName": "payload",
|
|
105
|
+
"filtertrue": "both",
|
|
106
|
+
"persist": false,
|
|
107
|
+
"sInitializeWith": "WaitForPayload",
|
|
108
|
+
"triggertopic": "trigger",
|
|
109
|
+
"outputtriggeredby": "all",
|
|
110
|
+
"inputCount": 2,
|
|
111
|
+
"topic": "result",
|
|
112
|
+
"restrictinputevaluation": false,
|
|
113
|
+
"delayEvaluation": 0,
|
|
114
|
+
"translatorConfig": "",
|
|
115
|
+
"x": 380,
|
|
116
|
+
"y": 200,
|
|
117
|
+
"wires": [["bgu_dbg_and"], ["bgu_dbg_or"], ["bgu_dbg_xor"]]
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "bgu_dbg_and",
|
|
121
|
+
"type": "debug",
|
|
122
|
+
"z": "bgu_tab_1",
|
|
123
|
+
"name": "AND",
|
|
124
|
+
"active": true,
|
|
125
|
+
"tosidebar": true,
|
|
126
|
+
"console": false,
|
|
127
|
+
"tostatus": false,
|
|
128
|
+
"complete": "payload",
|
|
129
|
+
"targetType": "msg",
|
|
130
|
+
"statusVal": "",
|
|
131
|
+
"statusType": "auto",
|
|
132
|
+
"x": 590,
|
|
133
|
+
"y": 160,
|
|
134
|
+
"wires": []
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"id": "bgu_dbg_or",
|
|
138
|
+
"type": "debug",
|
|
139
|
+
"z": "bgu_tab_1",
|
|
140
|
+
"name": "OR",
|
|
141
|
+
"active": true,
|
|
142
|
+
"tosidebar": true,
|
|
143
|
+
"console": false,
|
|
144
|
+
"tostatus": false,
|
|
145
|
+
"complete": "payload",
|
|
146
|
+
"targetType": "msg",
|
|
147
|
+
"statusVal": "",
|
|
148
|
+
"statusType": "auto",
|
|
149
|
+
"x": 590,
|
|
150
|
+
"y": 200,
|
|
151
|
+
"wires": []
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"id": "bgu_dbg_xor",
|
|
155
|
+
"type": "debug",
|
|
156
|
+
"z": "bgu_tab_1",
|
|
157
|
+
"name": "XOR",
|
|
158
|
+
"active": true,
|
|
159
|
+
"tosidebar": true,
|
|
160
|
+
"console": false,
|
|
161
|
+
"tostatus": false,
|
|
162
|
+
"complete": "payload",
|
|
163
|
+
"targetType": "msg",
|
|
164
|
+
"statusVal": "",
|
|
165
|
+
"statusType": "auto",
|
|
166
|
+
"x": 590,
|
|
167
|
+
"y": 240,
|
|
168
|
+
"wires": []
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
|