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.
@@ -0,0 +1,145 @@
1
+ [
2
+ {
3
+ "id": "st_tab_1",
4
+ "type": "tab",
5
+ "label": "StaircaseLightUltimate - timed light",
6
+ "disabled": false,
7
+ "info": "Esempio: accende la luce per una durata e la spegne automaticamente, con warning pre-off opzionale."
8
+ },
9
+ {
10
+ "id": "st_cmt_1",
11
+ "type": "comment",
12
+ "z": "st_tab_1",
13
+ "name": "Trigger = payload true, off = payload false (se abilitato)",
14
+ "info": "Il topic di controllo è \"stairs\" (comandi on/off/extend).",
15
+ "x": 300,
16
+ "y": 60,
17
+ "wires": []
18
+ },
19
+ {
20
+ "id": "st_inj_motion",
21
+ "type": "inject",
22
+ "z": "st_tab_1",
23
+ "name": "Motion (true)",
24
+ "props": [
25
+ { "p": "payload", "v": "true", "vt": "bool" },
26
+ { "p": "topic", "v": "sensor", "vt": "str" }
27
+ ],
28
+ "repeat": "",
29
+ "crontab": "",
30
+ "once": false,
31
+ "onceDelay": 0.1,
32
+ "x": 150,
33
+ "y": 140,
34
+ "wires": [["st_node_1"]]
35
+ },
36
+ {
37
+ "id": "st_inj_off_input",
38
+ "type": "inject",
39
+ "z": "st_tab_1",
40
+ "name": "Off input (false)",
41
+ "props": [
42
+ { "p": "payload", "v": "false", "vt": "bool" },
43
+ { "p": "topic", "v": "sensor", "vt": "str" }
44
+ ],
45
+ "repeat": "",
46
+ "crontab": "",
47
+ "once": false,
48
+ "onceDelay": 0.1,
49
+ "x": 160,
50
+ "y": 180,
51
+ "wires": [["st_node_1"]]
52
+ },
53
+ {
54
+ "id": "st_inj_extend",
55
+ "type": "inject",
56
+ "z": "st_tab_1",
57
+ "name": "Extend (topic=stairs)",
58
+ "props": [
59
+ { "p": "topic", "v": "stairs", "vt": "str" },
60
+ { "p": "extend", "v": "true", "vt": "bool" }
61
+ ],
62
+ "repeat": "",
63
+ "crontab": "",
64
+ "once": false,
65
+ "onceDelay": 0.1,
66
+ "x": 170,
67
+ "y": 240,
68
+ "wires": [["st_node_1"]]
69
+ },
70
+ {
71
+ "id": "st_inj_force_off",
72
+ "type": "inject",
73
+ "z": "st_tab_1",
74
+ "name": "Force off (topic=stairs)",
75
+ "props": [
76
+ { "p": "topic", "v": "stairs", "vt": "str" },
77
+ { "p": "command", "v": "off", "vt": "str" }
78
+ ],
79
+ "repeat": "",
80
+ "crontab": "",
81
+ "once": false,
82
+ "onceDelay": 0.1,
83
+ "x": 180,
84
+ "y": 280,
85
+ "wires": [["st_node_1"]]
86
+ },
87
+ {
88
+ "id": "st_node_1",
89
+ "type": "StaircaseLightUltimate",
90
+ "z": "st_tab_1",
91
+ "name": "Stairs",
92
+ "controlTopic": "stairs",
93
+ "payloadPropName": "payload",
94
+ "translatorConfig": "",
95
+ "durationSeconds": 10,
96
+ "warningEnabled": true,
97
+ "warningOffsetSeconds": 3,
98
+ "restartOnTrigger": true,
99
+ "allowOffInput": true,
100
+ "onPayload": true,
101
+ "onPayloadType": "bool",
102
+ "offPayload": false,
103
+ "offPayloadType": "bool",
104
+ "warningPayload": "warning",
105
+ "warningPayloadType": "str",
106
+ "x": 390,
107
+ "y": 200,
108
+ "wires": [["st_dbg_cmd"], ["st_dbg_warn"]]
109
+ },
110
+ {
111
+ "id": "st_dbg_cmd",
112
+ "type": "debug",
113
+ "z": "st_tab_1",
114
+ "name": "Light command",
115
+ "active": true,
116
+ "tosidebar": true,
117
+ "console": false,
118
+ "tostatus": false,
119
+ "complete": "true",
120
+ "targetType": "full",
121
+ "statusVal": "",
122
+ "statusType": "auto",
123
+ "x": 600,
124
+ "y": 180,
125
+ "wires": []
126
+ },
127
+ {
128
+ "id": "st_dbg_warn",
129
+ "type": "debug",
130
+ "z": "st_tab_1",
131
+ "name": "Warning",
132
+ "active": true,
133
+ "tosidebar": true,
134
+ "console": false,
135
+ "tostatus": false,
136
+ "complete": "true",
137
+ "targetType": "full",
138
+ "statusVal": "",
139
+ "statusType": "auto",
140
+ "x": 580,
141
+ "y": 220,
142
+ "wires": []
143
+ }
144
+ ]
145
+
@@ -0,0 +1,61 @@
1
+ [
2
+ {
3
+ "id": "stu_tab_1",
4
+ "type": "tab",
5
+ "label": "StatusUltimate - show msg property",
6
+ "disabled": false,
7
+ "info": "Esempio: mostra il valore di una proprietà del msg nello status del nodo, e lascia passare il msg."
8
+ },
9
+ {
10
+ "id": "stu_cmt_1",
11
+ "type": "comment",
12
+ "z": "stu_tab_1",
13
+ "name": "Lo status mostra msg.payload",
14
+ "info": "Configura la proprietà da mostrare (es. payload, mycar.color, ecc.).",
15
+ "x": 200,
16
+ "y": 60,
17
+ "wires": []
18
+ },
19
+ {
20
+ "id": "stu_inj_1",
21
+ "type": "inject",
22
+ "z": "stu_tab_1",
23
+ "name": "payload = \"Ciao\"",
24
+ "props": [{ "p": "payload", "v": "Ciao", "vt": "str" }],
25
+ "repeat": "",
26
+ "crontab": "",
27
+ "once": false,
28
+ "onceDelay": 0.1,
29
+ "x": 150,
30
+ "y": 140,
31
+ "wires": [["stu_node_1"]]
32
+ },
33
+ {
34
+ "id": "stu_node_1",
35
+ "type": "StatusUltimate",
36
+ "z": "stu_tab_1",
37
+ "name": "Status",
38
+ "property": "payload",
39
+ "x": 340,
40
+ "y": 140,
41
+ "wires": [["stu_dbg_1"]]
42
+ },
43
+ {
44
+ "id": "stu_dbg_1",
45
+ "type": "debug",
46
+ "z": "stu_tab_1",
47
+ "name": "Pass-through",
48
+ "active": true,
49
+ "tosidebar": true,
50
+ "console": false,
51
+ "tostatus": false,
52
+ "complete": "true",
53
+ "targetType": "full",
54
+ "statusVal": "",
55
+ "statusType": "auto",
56
+ "x": 560,
57
+ "y": 140,
58
+ "wires": []
59
+ }
60
+ ]
61
+
@@ -0,0 +1,222 @@
1
+ [
2
+ {
3
+ "id": "sum_tab_1",
4
+ "type": "tab",
5
+ "label": "SumUltimate - sum + subtract",
6
+ "disabled": false,
7
+ "info": "Esempi: somma con topic diversi e sottrazione con \"Subtract from\"."
8
+ },
9
+ {
10
+ "id": "sum_cmt_1",
11
+ "type": "comment",
12
+ "z": "sum_tab_1",
13
+ "name": "SUM: ogni msg.topic rappresenta una variabile",
14
+ "info": "Il nodo memorizza l'ultimo valore per ciascun topic e ricalcola ad ogni arrivo.",
15
+ "x": 240,
16
+ "y": 60,
17
+ "wires": []
18
+ },
19
+ {
20
+ "id": "sum_inj_a",
21
+ "type": "inject",
22
+ "z": "sum_tab_1",
23
+ "name": "a = 10",
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": "10",
34
+ "payloadType": "num",
35
+ "x": 120,
36
+ "y": 120,
37
+ "wires": [["sum_node_sum"]]
38
+ },
39
+ {
40
+ "id": "sum_inj_b",
41
+ "type": "inject",
42
+ "z": "sum_tab_1",
43
+ "name": "b = 5",
44
+ "props": [
45
+ { "p": "payload" },
46
+ { "p": "topic", "vt": "str" }
47
+ ],
48
+ "repeat": "",
49
+ "crontab": "",
50
+ "once": false,
51
+ "onceDelay": 0.1,
52
+ "topic": "b",
53
+ "payload": "5",
54
+ "payloadType": "num",
55
+ "x": 110,
56
+ "y": 160,
57
+ "wires": [["sum_node_sum"]]
58
+ },
59
+ {
60
+ "id": "sum_inj_c",
61
+ "type": "inject",
62
+ "z": "sum_tab_1",
63
+ "name": "c = 2",
64
+ "props": [
65
+ { "p": "payload" },
66
+ { "p": "topic", "vt": "str" }
67
+ ],
68
+ "repeat": "",
69
+ "crontab": "",
70
+ "once": false,
71
+ "onceDelay": 0.1,
72
+ "topic": "c",
73
+ "payload": "2",
74
+ "payloadType": "num",
75
+ "x": 110,
76
+ "y": 200,
77
+ "wires": [["sum_node_sum"]]
78
+ },
79
+ {
80
+ "id": "sum_inj_reset_1",
81
+ "type": "inject",
82
+ "z": "sum_tab_1",
83
+ "name": "reset",
84
+ "props": [{ "p": "reset", "v": "true", "vt": "bool" }],
85
+ "repeat": "",
86
+ "crontab": "",
87
+ "once": false,
88
+ "onceDelay": 0.1,
89
+ "x": 110,
90
+ "y": 240,
91
+ "wires": [["sum_node_sum", "sum_node_sub"]]
92
+ },
93
+ {
94
+ "id": "sum_node_sum",
95
+ "type": "SumUltimate",
96
+ "z": "sum_tab_1",
97
+ "name": "Sum",
98
+ "property": "payload",
99
+ "math": "sum",
100
+ "subtractstartfrom": "",
101
+ "x": 320,
102
+ "y": 160,
103
+ "wires": [["sum_dbg_sum"]]
104
+ },
105
+ {
106
+ "id": "sum_dbg_sum",
107
+ "type": "debug",
108
+ "z": "sum_tab_1",
109
+ "name": "SUM result",
110
+ "active": true,
111
+ "tosidebar": true,
112
+ "console": false,
113
+ "tostatus": false,
114
+ "complete": "payload",
115
+ "targetType": "msg",
116
+ "statusVal": "",
117
+ "statusType": "auto",
118
+ "x": 540,
119
+ "y": 160,
120
+ "wires": []
121
+ },
122
+ {
123
+ "id": "sum_cmt_2",
124
+ "type": "comment",
125
+ "z": "sum_tab_1",
126
+ "name": "SUBTRACT: scegli il topic iniziale (Subtract from)",
127
+ "info": "Qui la sottrazione parte dal topic \"startNumber\" e sottrae a/b.",
128
+ "x": 270,
129
+ "y": 300,
130
+ "wires": []
131
+ },
132
+ {
133
+ "id": "sum_inj_start",
134
+ "type": "inject",
135
+ "z": "sum_tab_1",
136
+ "name": "startNumber = 100",
137
+ "props": [
138
+ { "p": "payload" },
139
+ { "p": "topic", "vt": "str" }
140
+ ],
141
+ "repeat": "",
142
+ "crontab": "",
143
+ "once": false,
144
+ "onceDelay": 0.1,
145
+ "topic": "startNumber",
146
+ "payload": "100",
147
+ "payloadType": "num",
148
+ "x": 150,
149
+ "y": 360,
150
+ "wires": [["sum_node_sub"]]
151
+ },
152
+ {
153
+ "id": "sum_inj_sa",
154
+ "type": "inject",
155
+ "z": "sum_tab_1",
156
+ "name": "a = 20",
157
+ "props": [
158
+ { "p": "payload" },
159
+ { "p": "topic", "vt": "str" }
160
+ ],
161
+ "repeat": "",
162
+ "crontab": "",
163
+ "once": false,
164
+ "onceDelay": 0.1,
165
+ "topic": "a",
166
+ "payload": "20",
167
+ "payloadType": "num",
168
+ "x": 120,
169
+ "y": 400,
170
+ "wires": [["sum_node_sub"]]
171
+ },
172
+ {
173
+ "id": "sum_inj_sb",
174
+ "type": "inject",
175
+ "z": "sum_tab_1",
176
+ "name": "b = 10",
177
+ "props": [
178
+ { "p": "payload" },
179
+ { "p": "topic", "vt": "str" }
180
+ ],
181
+ "repeat": "",
182
+ "crontab": "",
183
+ "once": false,
184
+ "onceDelay": 0.1,
185
+ "topic": "b",
186
+ "payload": "10",
187
+ "payloadType": "num",
188
+ "x": 120,
189
+ "y": 440,
190
+ "wires": [["sum_node_sub"]]
191
+ },
192
+ {
193
+ "id": "sum_node_sub",
194
+ "type": "SumUltimate",
195
+ "z": "sum_tab_1",
196
+ "name": "Subtract",
197
+ "property": "payload",
198
+ "math": "subtract",
199
+ "subtractstartfrom": "startNumber",
200
+ "x": 330,
201
+ "y": 420,
202
+ "wires": [["sum_dbg_sub"]]
203
+ },
204
+ {
205
+ "id": "sum_dbg_sub",
206
+ "type": "debug",
207
+ "z": "sum_tab_1",
208
+ "name": "SUBTRACT result",
209
+ "active": true,
210
+ "tosidebar": true,
211
+ "console": false,
212
+ "tostatus": false,
213
+ "complete": "payload",
214
+ "targetType": "msg",
215
+ "statusVal": "",
216
+ "statusType": "auto",
217
+ "x": 560,
218
+ "y": 420,
219
+ "wires": []
220
+ }
221
+ ]
222
+
@@ -0,0 +1,63 @@
1
+ [
2
+ {
3
+ "id": "tog_tab_1",
4
+ "type": "tab",
5
+ "label": "toggleUltimate - toggle true/false",
6
+ "disabled": false,
7
+ "info": "Esempio: ad ogni msg in ingresso, il nodo alterna il payload tra true e false."
8
+ },
9
+ {
10
+ "id": "tog_cmt_1",
11
+ "type": "comment",
12
+ "z": "tog_tab_1",
13
+ "name": "Ogni click alterna true/false",
14
+ "info": "Serve solo che esista msg.payload (il valore non viene usato, ma deve essere presente).",
15
+ "x": 220,
16
+ "y": 60,
17
+ "wires": []
18
+ },
19
+ {
20
+ "id": "tog_inj_1",
21
+ "type": "inject",
22
+ "z": "tog_tab_1",
23
+ "name": "Toggle",
24
+ "props": [{ "p": "payload", "v": "1", "vt": "num" }],
25
+ "repeat": "",
26
+ "crontab": "",
27
+ "once": false,
28
+ "onceDelay": 0.1,
29
+ "x": 140,
30
+ "y": 140,
31
+ "wires": [["tog_node_1"]]
32
+ },
33
+ {
34
+ "id": "tog_node_1",
35
+ "type": "toggleUltimate",
36
+ "z": "tog_tab_1",
37
+ "name": "Toggle",
38
+ "valueToToggle": "true",
39
+ "payloadPropName": "payload",
40
+ "translatorConfig": "",
41
+ "x": 330,
42
+ "y": 140,
43
+ "wires": [["tog_dbg_1"]]
44
+ },
45
+ {
46
+ "id": "tog_dbg_1",
47
+ "type": "debug",
48
+ "z": "tog_tab_1",
49
+ "name": "Output",
50
+ "active": true,
51
+ "tosidebar": true,
52
+ "console": false,
53
+ "tostatus": false,
54
+ "complete": "payload",
55
+ "targetType": "msg",
56
+ "statusVal": "",
57
+ "statusType": "auto",
58
+ "x": 520,
59
+ "y": 140,
60
+ "wires": []
61
+ }
62
+ ]
63
+
@@ -0,0 +1,99 @@
1
+ [
2
+ {
3
+ "id": "tr_tab_1",
4
+ "type": "tab",
5
+ "label": "translator-config - example usage",
6
+ "disabled": false,
7
+ "info": "Esempio: usa translator-config per convertire stringhe (on/off, open/closed, ecc.) in booleani."
8
+ },
9
+ {
10
+ "id": "tr_cmt_1",
11
+ "type": "comment",
12
+ "z": "tr_tab_1",
13
+ "name": "Il FilterUltimate usa translator-config",
14
+ "info": "Invia payload \"open\"/\"closed\" e osserva su quale uscita viene instradato.",
15
+ "x": 240,
16
+ "y": 60,
17
+ "wires": []
18
+ },
19
+ {
20
+ "id": "tr_inj_open",
21
+ "type": "inject",
22
+ "z": "tr_tab_1",
23
+ "name": "payload = \"open\"",
24
+ "props": [{ "p": "payload", "v": "open", "vt": "str" }],
25
+ "repeat": "",
26
+ "crontab": "",
27
+ "once": false,
28
+ "onceDelay": 0.1,
29
+ "x": 150,
30
+ "y": 140,
31
+ "wires": [["tr_filter_1"]]
32
+ },
33
+ {
34
+ "id": "tr_inj_closed",
35
+ "type": "inject",
36
+ "z": "tr_tab_1",
37
+ "name": "payload = \"closed\"",
38
+ "props": [{ "p": "payload", "v": "closed", "vt": "str" }],
39
+ "repeat": "",
40
+ "crontab": "",
41
+ "once": false,
42
+ "onceDelay": 0.1,
43
+ "x": 160,
44
+ "y": 180,
45
+ "wires": [["tr_filter_1"]]
46
+ },
47
+ {
48
+ "id": "tr_filter_1",
49
+ "type": "FilterUltimate",
50
+ "z": "tr_tab_1",
51
+ "name": "Filter + Translator",
52
+ "payloadPropName": "payload",
53
+ "translatorConfig": "tr_cfg_1",
54
+ "x": 380,
55
+ "y": 160,
56
+ "wires": [["tr_dbg_true"], ["tr_dbg_false"]]
57
+ },
58
+ {
59
+ "id": "tr_dbg_true",
60
+ "type": "debug",
61
+ "z": "tr_tab_1",
62
+ "name": "True (translated)",
63
+ "active": true,
64
+ "tosidebar": true,
65
+ "console": false,
66
+ "tostatus": false,
67
+ "complete": "payload",
68
+ "targetType": "msg",
69
+ "statusVal": "",
70
+ "statusType": "auto",
71
+ "x": 600,
72
+ "y": 140,
73
+ "wires": []
74
+ },
75
+ {
76
+ "id": "tr_dbg_false",
77
+ "type": "debug",
78
+ "z": "tr_tab_1",
79
+ "name": "False (translated)",
80
+ "active": true,
81
+ "tosidebar": true,
82
+ "console": false,
83
+ "tostatus": false,
84
+ "complete": "payload",
85
+ "targetType": "msg",
86
+ "statusVal": "",
87
+ "statusType": "auto",
88
+ "x": 610,
89
+ "y": 180,
90
+ "wires": []
91
+ },
92
+ {
93
+ "id": "tr_cfg_1",
94
+ "type": "translator-config",
95
+ "name": "Default translations",
96
+ "commandText": "on:true\noff:false\nactive:true\ninactive:false\nopen:true\nclosed:false\nclose:false\n1:true\n0:false\ntrue:true\nfalse:false\nhome:true\nnot_home:false"
97
+ }
98
+ ]
99
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-boolean-logic-ultimate",
3
- "version": "1.2.3",
3
+ "version": "1.2.5",
4
4
  "description": "A set of Node-RED enhanced boolean logic and utility nodes, flow interruption, blinker, invert, filter, toggle etc.., with persistent values after reboot. Compatible also with Homeassistant values.",
5
5
  "author": "Supergiovane (https://github.com/Supergiovane)",
6
6
  "dependencies": {
@@ -51,4 +51,4 @@
51
51
  "scripts": {
52
52
  "test": "mocha test/**/*.spec.js"
53
53
  }
54
- }
54
+ }
package/test/helpers.js CHANGED
@@ -8,10 +8,25 @@ helper.init(require.resolve('node-red')); // initialise with Node-RED runtime
8
8
  const nodes = {
9
9
  RateLimiterUltimate: require(path.join('..', 'boolean-logic-ultimate', 'RateLimiterUltimate.js')),
10
10
  PresenceSimulatorUltimate: require(path.join('..', 'boolean-logic-ultimate', 'PresenceSimulatorUltimate.js')),
11
+ RailwaySwitchUltimate: require(path.join('..', 'boolean-logic-ultimate', 'RailwaySwitchUltimate.js')),
11
12
  };
12
13
 
13
14
  function loadNode(nodeDef, flow, credentials = {}) {
14
- return helper.load(nodeDef, flow, credentials);
15
+ const normalizedFlow = flow.map((node, index) => {
16
+ if (
17
+ node &&
18
+ node.type &&
19
+ node.type !== 'tab' &&
20
+ node.type !== 'subflow' &&
21
+ node.type !== 'group' &&
22
+ node.z &&
23
+ !(Object.prototype.hasOwnProperty.call(node, 'x') && Object.prototype.hasOwnProperty.call(node, 'y'))
24
+ ) {
25
+ return { ...node, x: 100 + index * 10, y: 100 + index * 10 };
26
+ }
27
+ return node;
28
+ });
29
+ return helper.load(nodeDef, normalizedFlow, credentials);
15
30
  }
16
31
 
17
32
  function loadRateLimiter(flow, credentials = {}) {
@@ -22,8 +37,13 @@ function loadPresence(flow, credentials = {}) {
22
37
  return loadNode(nodes.PresenceSimulatorUltimate, flow, credentials);
23
38
  }
24
39
 
40
+ function loadRailwaySwitch(flow, credentials = {}) {
41
+ return loadNode(nodes.RailwaySwitchUltimate, flow, credentials);
42
+ }
43
+
25
44
  module.exports = {
26
45
  helper,
27
46
  loadRateLimiter,
28
47
  loadPresence,
48
+ loadRailwaySwitch,
29
49
  };
@@ -39,7 +39,7 @@ describe('PresenceSimulatorUltimate node', function () {
39
39
  ];
40
40
 
41
41
  loadPresence(flow).then(() => {
42
- const input = helper.getNode('in');
42
+ const presence = helper.getNode('presence');
43
43
  const out = helper.getNode('out');
44
44
 
45
45
  out.on('input', (msg) => {
@@ -52,7 +52,7 @@ describe('PresenceSimulatorUltimate node', function () {
52
52
  }
53
53
  });
54
54
 
55
- input.receive({ topic: 'presence', command: 'start' });
55
+ presence.receive({ topic: 'presence', command: 'start' });
56
56
  }).catch(done);
57
57
  });
58
58
 
@@ -76,14 +76,14 @@ describe('PresenceSimulatorUltimate node', function () {
76
76
  ];
77
77
 
78
78
  loadPresence(flow).then(() => {
79
- const input = helper.getNode('in');
79
+ const presence = helper.getNode('presence');
80
80
  const out = helper.getNode('out');
81
81
  let received = 0;
82
82
 
83
83
  out.on('input', () => {
84
84
  received += 1;
85
85
  if (received === 1) {
86
- input.receive({ topic: 'presence', command: 'stop' });
86
+ presence.receive({ topic: 'presence', command: 'stop' });
87
87
  setTimeout(() => {
88
88
  try {
89
89
  expect(received).to.equal(1);
@@ -95,7 +95,7 @@ describe('PresenceSimulatorUltimate node', function () {
95
95
  }
96
96
  });
97
97
 
98
- input.receive({ topic: 'presence', command: 'start' });
98
+ presence.receive({ topic: 'presence', command: 'start' });
99
99
  }).catch(done);
100
100
  });
101
101
  });