@mschaeffler/node-red-logic 0.0.5 → 0.1.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/README.md CHANGED
@@ -12,45 +12,175 @@ $ npm install @mschaeffler/node-red-logic
12
12
 
13
13
  ## Usage
14
14
 
15
- .
15
+ ### counter
16
+
17
+ A node that just count the messages.
18
+
19
+ #### Output
20
+
21
+ |msg. | type | description |
22
+ |:-------|:-------|:----------------------------------|
23
+ |count | number | number of messages.|
24
+
25
+ ### to bool
26
+
27
+ Converts payload to a bool value:
28
+
29
+ |type|value|is converted to|
30
+ |:---|:----|:--------------|
31
+ |bool|false|false|
32
+ ||true|true|
33
+ |number|0|false|
34
+ ||1|true|
35
+ |string|false|false|
36
+ ||0|false|
37
+ ||off|false|
38
+ ||true|true|
39
+ ||1|true|
40
+ ||on|true|
41
+
42
+ #### Input
43
+
44
+ The message property to be used as payload can be defined with the `Property` property.
45
+
46
+ |msg. | type | description |
47
+ |:-------|:-------|:----------------------------------|
48
+ |payload | | input value. |
49
+
50
+ #### Output
51
+
52
+ |msg. | type | description |
53
+ |:-------|:-------|:----------------------------------|
54
+ |payload | boolean | bool value of payload.|
55
+
56
+ #### Parameters
57
+
58
+ |config| type | description |
59
+ |:-----|:-------|:----------------------------------|
60
+ |Property| string | defines the message property to be used as payload.|
16
61
 
17
62
  ### or
18
63
 
19
- .
64
+ Combines two or more boolean vales with the `or` operator.
65
+
66
+ The input values are converted as described in the `to bool` node.
20
67
 
21
68
  #### Input
22
69
 
23
- .
70
+ The different inputs are differentiated by topics.
71
+
72
+ The message property to be used as payload can be defined with the `Property` property.
24
73
 
25
74
  |msg. | type | description |
26
75
  |:-------|:-------|:----------------------------------|
27
- |topic | string | .|
76
+ |topic | string | name of the input channel. |
28
77
  |payload | boolean| input value for `topic`. |
29
78
 
30
79
  #### Output
31
80
 
32
- .
33
-
34
81
  |msg. | type | description |
35
82
  |:-------|:-------|:----------------------------------|
36
83
  |payload | boolean | result of `or` of all input topics.|
84
+ |count | number | number of data elements.|
37
85
 
38
86
  #### Parameters
39
87
 
40
88
  |config| type | description |
41
89
  |:-----|:-------|:----------------------------------|
42
- | | string | . |
90
+ |Property| string | defines the message property to be used as payload.|
91
+ |min. Data|number|min. amount of topics to generate an output.|
43
92
 
44
93
  ### and
45
94
 
46
- .
95
+ Combines two or more boolean vales with the `and` operator.
96
+
97
+ The input values are converted as described in the `to bool` node.
98
+
99
+ #### Input
100
+
101
+ The different inputs are differentiated by topics.
102
+
103
+ The message property to be used as payload can be defined with the `Property` property.
104
+
105
+ |msg. | type | description |
106
+ |:-------|:-------|:----------------------------------|
107
+ |topic | string | name of the input channel. |
108
+ |payload | boolean| input value for `topic`. |
109
+
110
+ #### Output
111
+
112
+ |msg. | type | description |
113
+ |:-------|:-------|:----------------------------------|
114
+ |payload | boolean | result of `and` of all input topics.|
115
+ |count | number | number of data elements.|
116
+
117
+ #### Parameters
118
+
119
+ |config| type | description |
120
+ |:-----|:-------|:----------------------------------|
121
+ |Property| string | defines the message property to be used as payload.|
122
+ |min. Data|number|min. amount of topics to generate an output.|
123
+
124
+ ### to number
125
+
126
+ Converts payload to a number.
127
+
128
+ #### Input
129
+
130
+ The message property to be used as payload can be defined with the `Property` property.
131
+
132
+ |msg. | type | description |
133
+ |:-------|:-------|:----------------------------------|
134
+ |payload | | input value. |
135
+
136
+ #### Output
137
+
138
+ |msg. | type | description |
139
+ |:-------|:-------|:----------------------------------|
140
+ |payload | number | number value of payload.|
141
+
142
+ #### Parameters
143
+
144
+ |config| type | description |
145
+ |:-----|:-------|:----------------------------------|
146
+ |Property| string | defines the message property to be used as payload.|
147
+
148
+ ### reduce
149
+
150
+ Combines two or more streams of data (topics) into one single value.
151
+
152
+ Each stream can be debounced by arithmatic mean.
47
153
 
48
154
  #### Input
49
155
 
156
+ The different inputs are differentiated by topics.
157
+
158
+ The message property to be used as payload can be defined with the `Property` property.
159
+
160
+ |msg. | type | description |
161
+ |:-------|:-------|:----------------------------------|
162
+ |topic | string | name of the input channel. |
163
+ |payload | number | input value for `topic`. |
164
+
50
165
  #### Output
51
166
 
167
+ |msg. | type | description |
168
+ |:-------|:-------|:----------------------------------|
169
+ |payload | number | result of combining of all input topics.|
170
+ |count | number | number of data elements.|
171
+
52
172
  #### Parameters
53
173
 
174
+ |config| type | description |
175
+ |:-----|:-------|:----------------------------------|
176
+ |Property| string | defines the message property to be used as payload.|
177
+ |min. Mean|number|min. amount of values for the arithmatic mean of one topic.|
178
+ |max. Mean|number|max. amount of values for the arithmatic mean of one topic.|
179
+ |min. Data|number|min. amount of topics to generate an output.|
180
+ |Algorithm|string|algorithm to combine the values.|
181
+
182
+ #### Algorithms
183
+
54
184
  ## Example Flow
55
185
 
56
186
  [example flow](https://github.com/m-schaeffler/node-red-my-nodes/raw/main/node-red-logic/examples/logic.json)
package/counter.html ADDED
@@ -0,0 +1,37 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('counter',{
3
+ category: 'function',
4
+ color: "#C0DEED",
5
+ defaults: {
6
+ name:{value:""}
7
+ },
8
+ inputs:1,
9
+ outputs:1,
10
+ icon: "font-awesome/fa-list-ol",
11
+ label: function() {
12
+ return this.name||"counter";
13
+ },
14
+ inputLabels: 'input',
15
+ outputLabels: 'output'
16
+ });
17
+ </script>
18
+
19
+ <script type="text/html" data-template-name="counter">
20
+ <div class="form-row">
21
+ <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
22
+ <input type="text" id="node-input-name" placeholder="Name">
23
+ </div>
24
+ </script>
25
+
26
+ <script type="text/html" data-help-name="counter">
27
+
28
+ <p>A node that just count the messages.</p>
29
+
30
+ <h3>Output</h3>
31
+
32
+ <dl class="message-properties">
33
+ <dt>count <span class="property-type">number</span></dt>
34
+ <dd> number of messages.</dd>
35
+ </dl>
36
+
37
+ </script>
package/counter.js ADDED
@@ -0,0 +1,28 @@
1
+ module.exports = function(RED) {
2
+
3
+ function CounterNode(config) {
4
+ RED.nodes.createNode(this,config);
5
+ //this.config = config;
6
+ var node = this;
7
+ var context = this.context();
8
+
9
+ node.on('input', function(msg,send,done) {
10
+ msg.count = context.get( "count" ) ?? 0;
11
+ if( msg.reset || msg.topic==="init" )
12
+ {
13
+ msg.count = 0;
14
+ }
15
+ else
16
+ {
17
+ msg.count++;
18
+ }
19
+ context.set( "count", msg.count );
20
+
21
+ node.status( msg.count );
22
+ send( msg );
23
+ done();
24
+ });
25
+ }
26
+
27
+ RED.nodes.registerType("counter",CounterNode);
28
+ }
package/logic_and.html CHANGED
@@ -4,8 +4,10 @@
4
4
  color: "#C0DEED",
5
5
  defaults: {
6
6
  name:{value:""},
7
- property:{value:"payload",required:true},
8
- minData:{value:"1",validate:RED.validators.number(),required:true}
7
+ property:{value:"payload", required:true},
8
+ minData:{value:"1", required:true, validate:function(v){
9
+ return v!=='' && !isNaN(v) && Number(v)>0;
10
+ }}
9
11
  },
10
12
  inputs:1,
11
13
  outputs:1,
@@ -43,8 +45,37 @@
43
45
 
44
46
  <script type="text/html" data-help-name="and">
45
47
 
46
- <p>.</p>
48
+ <p>.Combines two or more boolean vales with the <code>and</code> operator.</p>
49
+ <p>The input values are converted as described in the <code>to bool</code> node.</p>
47
50
 
48
51
  <h3>Input</h3>
52
+
53
+ <p>The different inputs are differentiated by topics.</p>
54
+ <p>The message property to be used as payload can be defined with the <code>Property</code> property.</p>
55
+
56
+ <dl class="message-properties">
57
+ <dt>topic <span class="property-type">string</span></dt>
58
+ <dd> name of the input channel.</dd>
59
+ <dt>payload <span class="property-type">boolean</span></dt>
60
+ <dd> input value for <code>topic</code>.</dd>
61
+ </dl>
62
+
63
+ <h3>Output</h3>
64
+
65
+ <dl class="message-properties">
66
+ <dt>payload <span class="property-type">boolean</span></dt>
67
+ <dd> result of <code>and</code> of all input topics.</dd>
68
+ <dt>count <span class="property-type">number</span></dt>
69
+ <dd> number of data elements.</dd>
70
+ </dl>
71
+
72
+ <h3>Parameter</h3>
49
73
 
74
+ <dl class="message-properties">
75
+ <dt>Property <span class="property-type">string</span></dt>
76
+ <dd> defines the message property to be used as payload.</dd>
77
+ <dt>min. Data <span class="property-type">number</span></dt>
78
+ <dd> min. amount of topics to generate an output.</dd>
79
+ </dl>
80
+
50
81
  </script>
package/logic_and.js CHANGED
@@ -12,29 +12,32 @@ module.exports = function(RED) {
12
12
  node.on('input', function(msg,send,done) {
13
13
  const payload = tools.property2boolean( RED.util.getMessageProperty( msg, node.property ) );
14
14
 
15
- let data = context.get( "data" ) ?? {};
16
- data[msg.topic] = payload;
17
- context.set( "data", data );
18
-
19
- msg.payload = true;
20
- let count = 0;
21
- for( const item in data )
15
+ if( payload !=== null )
22
16
  {
23
- count++;
24
- if( ! data[item] )
17
+ let data = context.get( "data" ) ?? {};
18
+ data[msg.topic] = payload;
19
+ context.set( "data", data );
20
+
21
+ msg.payload = true;
22
+ msg.count = 0;
23
+ for( const item in data )
25
24
  {
26
- msg.payload = false;
25
+ msg.count++;
26
+ if( ! data[item] )
27
+ {
28
+ msg.payload = false;
29
+ }
27
30
  }
28
- }
29
31
 
30
- if( count >= node.minData )
31
- {
32
- node.status( msg.payload );
33
- send( msg );
34
- }
35
- else
36
- {
37
- node.status( "waiting for data" );
32
+ if( msg.count >= node.minData )
33
+ {
34
+ node.status( msg.payload );
35
+ send( msg );
36
+ }
37
+ else
38
+ {
39
+ node.status( "waiting for data" );
40
+ }
38
41
  }
39
42
 
40
43
  done();
package/logic_bool.html CHANGED
@@ -39,8 +39,43 @@
39
39
 
40
40
  <script type="text/html" data-help-name="tobool">
41
41
 
42
- <p>.</p>
42
+ <p>Converts payload to a bool value:</p>
43
+
44
+ <table>
45
+ <tr> <th>type</th> <th>input</th> <th>output</th> </tr>
46
+ <tr> <td>boolean</td> <td>false</td> <td>false</td> </tr>
47
+ <tr> <td></td> <td>true</td> <td>true</td> </tr>
48
+ <tr> <td>number</td> <td>0</td> <td>false</td> </tr>
49
+ <tr> <td></td> <td>1</td> <td>true</td> </tr>
50
+ <tr> <td>string</td> <td>false</td> <td>false</td> </tr>
51
+ <tr> <td></td> <td>true</td> <td>true</td> </tr>
52
+ <tr> <td></td> <td>0</td> <td>false</td> </tr>
53
+ <tr> <td></td> <td>1</td> <td>true</td> </tr>
54
+ <tr> <td></td> <td>on</td> <td>false</td> </tr>
55
+ <tr> <td></td> <td>off</td> <td>true</td> </tr>
56
+ </table>
43
57
 
44
58
  <h3>Input</h3>
59
+
60
+ <p>The message property to be used as payload can be defined with the <code>Property</code> property.</p>
61
+
62
+ <dl class="message-properties">
63
+ <dt>payload <span class="property-type"></span></dt>
64
+ <dd> input value.</dd>
65
+ </dl>
66
+
67
+ <h3>Output</h3>
68
+
69
+ <dl class="message-properties">
70
+ <dt>payload <span class="property-type">boolean</span></dt>
71
+ <dd> bool value of payload.</dd>
72
+ </dl>
73
+
74
+ <h3>Parameter</h3>
45
75
 
76
+ <dl class="message-properties">
77
+ <dt>Property <span class="property-type">string</span></dt>
78
+ <dd> defines the message property to be used as payload.</dd>
79
+ </dl>
80
+
46
81
  </script>
package/logic_bool.js CHANGED
@@ -10,8 +10,15 @@ module.exports = function(RED) {
10
10
  node.on('input', function(msg,send,done) {
11
11
  msg.payload = tools.property2boolean( RED.util.getMessageProperty( msg, node.property ) );
12
12
 
13
- node.status( msg.payload );
14
- send( msg );
13
+ if( msg.payload !== null )
14
+ {
15
+ node.status( msg.payload );
16
+ send( msg );
17
+ }
18
+ else
19
+ {
20
+ node.status( "error" );
21
+ }
15
22
  done();
16
23
  });
17
24
  }
package/logic_or.html CHANGED
@@ -4,8 +4,10 @@
4
4
  color: "#C0DEED",
5
5
  defaults: {
6
6
  name:{value:""},
7
- property:{value:"payload",required:true},
8
- minData:{value:"1",validate:RED.validators.number(),required:true}
7
+ property:{value:"payload", required:true},
8
+ minData:{value:"1", required:true, validate:function(v){
9
+ return v!=='' && !isNaN(v) && Number(v)>0;
10
+ }}
9
11
  },
10
12
  inputs:1,
11
13
  outputs:1,
@@ -43,8 +45,37 @@
43
45
 
44
46
  <script type="text/html" data-help-name="or">
45
47
 
46
- <p>.</p>
48
+ <p>Combines two or more boolean vales with the <code>or</code> operator.</p>
49
+ <p>The input values are converted as described in the <code>to bool</code> node.</p>
47
50
 
48
51
  <h3>Input</h3>
52
+
53
+ <p>The different inputs are differentiated by topics.</p>
54
+ <p>The message property to be used as payload can be defined with the <code>Property</code> property.</p>
55
+
56
+ <dl class="message-properties">
57
+ <dt>topic <span class="property-type">string</span></dt>
58
+ <dd> name of the input channel.</dd>
59
+ <dt>payload <span class="property-type">boolean</span></dt>
60
+ <dd> input value for <code>topic</code>.</dd>
61
+ </dl>
62
+
63
+ <h3>Output</h3>
64
+
65
+ <dl class="message-properties">
66
+ <dt>payload <span class="property-type">boolean</span></dt>
67
+ <dd> result of <code>or</code> of all input topics.</dd>
68
+ <dt>count <span class="property-type">number</span></dt>
69
+ <dd> number of data elements.</dd>
70
+ </dl>
71
+
72
+ <h3>Parameter</h3>
49
73
 
74
+ <dl class="message-properties">
75
+ <dt>Property <span class="property-type">string</span></dt>
76
+ <dd> defines the message property to be used as payload.</dd>
77
+ <dt>min. Data <span class="property-type">number</span></dt>
78
+ <dd> min. amount of topics to generate an output.</dd>
79
+ </dl>
80
+
50
81
  </script>
package/logic_or.js CHANGED
@@ -12,29 +12,32 @@ module.exports = function(RED) {
12
12
  node.on('input', function(msg,send,done) {
13
13
  const payload = tools.property2boolean( RED.util.getMessageProperty( msg, node.property ) );
14
14
 
15
- let data = context.get( "data" ) ?? {};
16
- data[msg.topic] = payload;
17
- context.set( "data", data );
18
-
19
- msg.payload = false;
20
- let count = 0;
21
- for( const item in data )
15
+ if( payload !== null )
22
16
  {
23
- count++;
24
- if( data[item] )
17
+ let data = context.get( "data" ) ?? {};
18
+ data[msg.topic] = payload;
19
+ context.set( "data", data );
20
+
21
+ msg.payload = false;
22
+ msg.count = 0;
23
+ for( const item in data )
25
24
  {
26
- msg.payload = true;
25
+ msg.count++;
26
+ if( data[item] )
27
+ {
28
+ msg.payload = true;
29
+ }
27
30
  }
28
- }
29
31
 
30
- if( count >= node.minData )
31
- {
32
- node.status( msg.payload );
33
- send( msg );
34
- }
35
- else
36
- {
37
- node.status( "waiting for data" );
32
+ if( msg.count >= node.minData )
33
+ {
34
+ node.status( msg.payload );
35
+ send( msg );
36
+ }
37
+ else
38
+ {
39
+ node.status( "waiting for data" );
40
+ }
38
41
  }
39
42
 
40
43
  done();
@@ -0,0 +1,67 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('tonumber',{
3
+ category: 'function',
4
+ color: "#C0DEED",
5
+ defaults: {
6
+ name:{value:""},
7
+ property:{value:"payload",required:true}
8
+ },
9
+ inputs:1,
10
+ outputs:1,
11
+ icon: "font-awesome/fa-adjust",
12
+ label: function() {
13
+ return this.name||"to number";
14
+ },
15
+ paletteLabel: "to number",
16
+ inputLabels: 'input',
17
+ outputLabels: 'number',
18
+ oneditprepare: function() {
19
+ $("#node-input-property").typedInput({
20
+ type:"msg",
21
+ types:["msg"],
22
+ typeField: "#node-input-property-type"
23
+ })
24
+ }
25
+ });
26
+ </script>
27
+
28
+ <script type="text/html" data-template-name="tonumber">
29
+ <div class="form-row">
30
+ <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
31
+ <input type="text" id="node-input-name" placeholder="Name">
32
+ </div>
33
+ <div class="form-row">
34
+ <label for="node-input-input"><i class="fa fa-ellipsis-h"></i> Eigenschaft</label>
35
+ <input type="text" id="node-input-property">
36
+ <input type="hidden" id="node-input-property-type">
37
+ </div>
38
+ </script>
39
+
40
+ <script type="text/html" data-help-name="tonumber">
41
+
42
+ <p>Converts payload to a number.</p>
43
+
44
+ <h3>Input</h3>
45
+
46
+ <p>The message property to be used as payload can be defined with the <code>Property</code> property.</p>
47
+
48
+ <dl class="message-properties">
49
+ <dt>payload <span class="property-type"></span></dt>
50
+ <dd> input value.</dd>
51
+ </dl>
52
+
53
+ <h3>Output</h3>
54
+
55
+ <dl class="message-properties">
56
+ <dt>payload <span class="property-type">number</span></dt>
57
+ <dd> number value of payload.</dd>
58
+ </dl>
59
+
60
+ <h3>Parameter</h3>
61
+
62
+ <dl class="message-properties">
63
+ <dt>Property <span class="property-type">string</span></dt>
64
+ <dd> defines the message property to be used as payload.</dd>
65
+ </dl>
66
+
67
+ </script>
package/math_number.js ADDED
@@ -0,0 +1,26 @@
1
+ module.exports = function(RED) {
2
+
3
+ function NumberNode(config) {
4
+ RED.nodes.createNode(this,config);
5
+ //this.config = config;
6
+ var node = this;
7
+ this.property = config.property || "payload";
8
+
9
+ node.on('input', function(msg,send,done) {
10
+ msg.payload = Number( RED.util.getMessageProperty( msg, node.property ) );
11
+
12
+ if( ! isNaN( msg.payload ) )
13
+ {
14
+ node.status( msg.payload );
15
+ send( msg );
16
+ }
17
+ else
18
+ {
19
+ node.status( "not a Number" );
20
+ }
21
+ done();
22
+ });
23
+ }
24
+
25
+ RED.nodes.registerType("tonumber",NumberNode);
26
+ }
@@ -0,0 +1,131 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('reduce',{
3
+ category: 'function',
4
+ color: "#C0DEED",
5
+ defaults: {
6
+ name:{value:""},
7
+ property:{value:"payload", required:true},
8
+ minMean:{value:"1", required:true, validate:function(v){
9
+ return v!=='' && !isNaN(v) && Number(v)>0;}
10
+ },
11
+ maxMean:{value:"1", required:true, validate:function(v){
12
+ const minMean = $("#node-input-minMean").length ? $("#node-input-minMean").val() : this.minMean;
13
+ return v!=='' && !isNaN(v) && Number(v)>=minMean;}
14
+ },
15
+ minData:{value:"1", required:true, validate:function(v){
16
+ return v!=='' && !isNaN(v) && Number(v)>0;}
17
+ },
18
+ algo:{value:"", required:true}
19
+ },
20
+ inputs:1,
21
+ outputs:1,
22
+ icon: function() {
23
+ switch( this.algo )
24
+ {
25
+ case "add": return "font-awesome/fa-plus";
26
+ case "mean": return "font-awesome/fa-indent";
27
+ case "prod": return "font-awesome/fa-asterisk";
28
+ case "min": return "font-awesome/fa-sort-numeric-desc";
29
+ case "max": return "font-awesome/fa-sort-numeric-asc";
30
+ default: return "font-awesome/fa-flask";
31
+ }
32
+ },
33
+ label: function() {
34
+ return this.name||this.algo||"reduce";
35
+ },
36
+ inputLabels: 'input',
37
+ outputLabels: 'output',
38
+ oneditprepare: function() {
39
+ $("#node-input-property").typedInput({
40
+ type:"msg",
41
+ types:["msg"],
42
+ typeField: "#node-input-property-type"
43
+ });
44
+ $("#node-input-algo").typedInput({
45
+ types:[{
46
+ value:"algo",
47
+ options: [
48
+ { value: "add", label: "Addition"},
49
+ { value: "mean", label: "Mean Value"},
50
+ { value: "prod", label: "Product"},
51
+ { value: "min", label: "Minimum" },
52
+ { value: "max", label: "Maximum" }
53
+ ]
54
+ }]
55
+ })
56
+ }
57
+ });
58
+ </script>
59
+
60
+ <script type="text/html" data-template-name="reduce">
61
+ <div class="form-row">
62
+ <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
63
+ <input type="text" id="node-input-name" placeholder="Name">
64
+ </div>
65
+ <div class="form-row">
66
+ <label for="node-input-input"><i class="fa fa-ellipsis-h"></i> Eigenschaft</label>
67
+ <input type="text" id="node-input-property">
68
+ <input type="hidden" id="node-input-property-type">
69
+ </div>
70
+ <div class="form-row">
71
+ <label for="node-input-minMean"><i class="fa fa-hourglass-o"></i> min. Mean</label>
72
+ <input type="text" id="node-input-minMean">
73
+ </div>
74
+ <div class="form-row">
75
+ <label for="node-input-maxMean"><i class="fa fa-hourglass"></i> max. Mean</label>
76
+ <input type="text" id="node-input-maxMean">
77
+ </div>
78
+ <div class="form-row">
79
+ <label for="node-input-minData"><i class="fa fa-check-square-o "></i> min. Data</label>
80
+ <input type="text" id="node-input-minData">
81
+ </div>
82
+ <div class="form-row">
83
+ <label for="node-input-algo"><i class="fa fa-flask"></i> Algorithm</label>
84
+ <input type="text" id="node-input-algo">
85
+ </div>
86
+ </script>
87
+
88
+ <script type="text/html" data-help-name="reduce">
89
+
90
+ <p>Combines two or more streams of data (topics) into one single value.</p>
91
+ <p>Each stream can be debounced by arithmatic mean.</p>
92
+
93
+ <h3>Input</h3>
94
+
95
+ <p>The different inputs are differentiated by topics.</p>
96
+ <p>The message property to be used as payload can be defined with the <code>Property</code> property.</p>
97
+
98
+ <dl class="message-properties">
99
+ <dt>topic <span class="property-type">string</span></dt>
100
+ <dd> name of the input channel.</dd>
101
+ <dt>payload <span class="property-type">number</span></dt>
102
+ <dd> input value for <code>topic</code>.</dd>
103
+ </dl>
104
+
105
+ <h3>Output</h3>
106
+
107
+ <dl class="message-properties">
108
+ <dt>payload <span class="property-type">number</span></dt>
109
+ <dd> result of combining of all input topics.</dd>
110
+ <dt>count <span class="property-type">number</span></dt>
111
+ <dd> number of data elements.</dd>
112
+ </dl>
113
+
114
+ <h3>Parameter</h3>
115
+
116
+ <dl class="message-properties">
117
+ <dt>Property <span class="property-type">string</span></dt>
118
+ <dd> defines the message property to be used as payload.</dd>
119
+ <dt>min. Mean <span class="property-type">number</span></dt>
120
+ <dd> min. amount of values for the arithmatic mean of one topic.</dd>
121
+ <dt>max. Mean <span class="property-type">number</span></dt>
122
+ <dd> max. amount of values for the arithmatic mean of one topic.</dd>
123
+ <dt>min. Data <span class="property-type">number</span></dt>
124
+ <dd> min. amount of topics to generate an output.</dd>
125
+ <dt>Algorithm <span class="property-type">string</span></dt>
126
+ <dd> algorithm to combine the values.</dd>
127
+ </dl>
128
+
129
+ <h3>Algorithms</h3>
130
+
131
+ </script>
package/math_reduce.js ADDED
@@ -0,0 +1,86 @@
1
+ module.exports = function(RED) {
2
+
3
+ function ReduceNode(config) {
4
+ RED.nodes.createNode(this,config);
5
+ //this.config = config;
6
+ var node = this;
7
+ var context = this.context();
8
+ this.property = config.property || "payload";
9
+ this.minMean = Number( config.minMean );
10
+ this.maxMean = Number( config.maxMean );
11
+ this.minData = Number( config.minData );
12
+ this.algo = config.algo;
13
+
14
+ node.on('input', function(msg,send,done) {
15
+ if( msg.reset || msg.topic==="init" )
16
+ {
17
+ context.set( "data", {} );
18
+ node.status( "" );
19
+ }
20
+ else
21
+ {
22
+ const payload = Number( RED.util.getMessageProperty( msg, node.property ) );
23
+ if( ! isNaN( payload ) )
24
+ {
25
+ let data = context.get( "data" ) ?? {};
26
+ let item = data[msg.topic] ?? [];
27
+ item.push( payload )
28
+ data[msg.topic] = item;
29
+
30
+ msg.count = 0;
31
+ switch( node.algo )
32
+ {
33
+ case "add":
34
+ case "mean": msg.payload = 0; break;
35
+ case "prod": msg.payload = 1; break;
36
+ case "min": msg.payload = Number.MAX_SAFE_INTEGER; break;
37
+ case "max": msg.payload = Number.MIN_SAFE_INTEGER; break;
38
+ default: done( "invalid algo: "+node.algo ); return;
39
+ }
40
+ for( const key in data )
41
+ {
42
+ if( data[key].length >= node.minMean )
43
+ {
44
+ msg.count++;
45
+ while( data[key].length > node.maxMean )
46
+ {
47
+ data[key].shift();
48
+ }
49
+ const help = data[key].reduce( (accumulator,value)=>accumulator+value ) / data[key].length;
50
+ switch( node.algo )
51
+ {
52
+ case "add":
53
+ case "mean": msg.payload += help; break;
54
+ case "prod": msg.payload *= help; break;
55
+ case "min": msg.payload = Math.min( msg.payload, help ); break;
56
+ case "max": msg.payload = Math.max( msg.payload, help ); break;
57
+ }
58
+ }
59
+ }
60
+ context.set( "data", data );
61
+
62
+ if( msg.count >= node.minData )
63
+ {
64
+ switch( node.algo )
65
+ {
66
+ case "mean": msg.payload /= msg.count; break;
67
+ }
68
+ node.status({fill:"green",shape:"dot",text:msg.payload});
69
+ send( msg );
70
+ }
71
+ else
72
+ {
73
+ node.status({fill:"gray",shape:"dot",text:"to less data"});
74
+ }
75
+ }
76
+ else
77
+ {
78
+ node.status({fill:"red",shape:"dot",text:"payload is NaN"});
79
+ }
80
+ }
81
+ done();
82
+ });
83
+ }
84
+
85
+ RED.nodes.registerType("reduce",ReduceNode);
86
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mschaeffler/node-red-logic",
3
- "version": "0.0.5",
3
+ "version": "0.1.0",
4
4
  "description": "nodes for simple mathematical operations.",
5
5
  "license": "LGPL-2.1",
6
6
  "homepage": "https://github.com/m-schaeffler/node-red-my-nodes/tree/main/node-red-logic",
@@ -17,10 +17,12 @@
17
17
  "node-red": {
18
18
  "version": ">=1.3.7",
19
19
  "nodes": {
20
+ "counter":"counter.js",
21
+ "tobool":"logic_bool.js",
22
+ "tonumber":"math_number.js",
20
23
  "or":"logic_or.js",
21
24
  "and":"logic_and.js",
22
- "tobool":"logic_bool.js",
23
- "plus":"math_plus.js"
25
+ "reduce":"math_reduce.js"
24
26
  }
25
27
  },
26
28
  "author": {
package/math_plus.html DELETED
@@ -1,50 +0,0 @@
1
- <script type="text/javascript">
2
- RED.nodes.registerType('plus',{
3
- category: 'function',
4
- color: "#C0DEED",
5
- defaults: {
6
- name:{value:""},
7
- property:{value:"payload",required:true},
8
- minData:{value:"1",validate:RED.validators.number(),required:true}
9
- },
10
- inputs:1,
11
- outputs:1,
12
- icon: "font-awesome/fa-plus",
13
- label: function() {
14
- return this.name||"plus";
15
- },
16
- inputLabels: 'input',
17
- outputLabels: 'plus',
18
- oneditprepare: function() {
19
- $("#node-input-property").typedInput({
20
- type:"msg",
21
- types:["msg"],
22
- typeField: "#node-input-property-type"
23
- })
24
- }
25
- });
26
- </script>
27
-
28
- <script type="text/html" data-template-name="plus">
29
- <div class="form-row">
30
- <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
31
- <input type="text" id="node-input-name" placeholder="Name">
32
- </div>
33
- <div class="form-row">
34
- <label for="node-input-input"><i class="fa fa-ellipsis-h"></i> Eigenschaft</label>
35
- <input type="text" id="node-input-property">
36
- <input type="hidden" id="node-input-property-type">
37
- </div>
38
- <div class="form-row">
39
- <label for="node-input-minData"><i class="fa fa-tag"></i> min. Data</label>
40
- <input type="text" id="node-input-minData">
41
- </div>
42
- </script>
43
-
44
- <script type="text/html" data-help-name="plus">
45
-
46
- <p>.</p>
47
-
48
- <h3>Input</h3>
49
-
50
- </script>
package/math_plus.js DELETED
@@ -1,41 +0,0 @@
1
- module.exports = function(RED) {
2
-
3
- function PlusNode(config) {
4
- RED.nodes.createNode(this,config);
5
- //this.config = config;
6
- var node = this;
7
- var context = this.context();
8
- this.property = config.property || "payload";
9
- this.minData = Number( config.minData );
10
-
11
- node.on('input', function(msg,send,done) {
12
- const payload = Number( RED.util.getMessageProperty( msg, node.property ) );
13
-
14
- let data = context.get( "data" ) ?? {};
15
- data[msg.topic] = payload;
16
- context.set( "data", data );
17
-
18
- msg.payload = 0;
19
- let count = 0;
20
- for( const item in data )
21
- {
22
- count++;
23
- msg.payload += data[item];
24
- }
25
-
26
- if( count >= node.minData )
27
- {
28
- node.status( msg.payload );
29
- send( msg );
30
- }
31
- else
32
- {
33
- node.status( "waiting for data" );
34
- }
35
-
36
- done();
37
- });
38
- }
39
-
40
- RED.nodes.registerType("plus",PlusNode);
41
- }