@mschaeffler/node-red-logic 0.0.4 → 0.0.7

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,7 +12,41 @@ $ npm install @mschaeffler/node-red-logic
12
12
 
13
13
  ## Usage
14
14
 
15
- .
15
+ ### bool
16
+
17
+ Converts payload to a bool value:
18
+ |type|value|is converted to|
19
+ |:---|:----|:--------------|
20
+ |bool|false|false|
21
+ ||true|true|
22
+ |number|0|false|
23
+ ||1|true|
24
+ |string|false|false|
25
+ ||0|false|
26
+ ||off|false|
27
+ ||true|true|
28
+ ||1|true|
29
+ ||on|true|
30
+
31
+ #### Input
32
+
33
+ The message property to be used as payload can be defined with the `Property` property.
34
+
35
+ |msg. | type | description |
36
+ |:-------|:-------|:----------------------------------|
37
+ |payload | | input value. |
38
+
39
+ #### Output
40
+
41
+ |msg. | type | description |
42
+ |:-------|:-------|:----------------------------------|
43
+ |payload | boolean | bool value of payload.|
44
+
45
+ #### Parameters
46
+
47
+ |config| type | description |
48
+ |:-----|:-------|:----------------------------------|
49
+ |Property| string | defines the message property to be used as payload.|
16
50
 
17
51
  ### or
18
52
 
package/counter.html ADDED
@@ -0,0 +1,32 @@
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>Input</h3>
31
+
32
+ </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,7 +4,10 @@
4
4
  color: "#C0DEED",
5
5
  defaults: {
6
6
  name:{value:""},
7
- property:{value:"payload",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
+ }}
8
11
  },
9
12
  inputs:1,
10
13
  outputs:1,
@@ -34,6 +37,10 @@
34
37
  <input type="text" id="node-input-property">
35
38
  <input type="hidden" id="node-input-property-type">
36
39
  </div>
40
+ <div class="form-row">
41
+ <label for="node-input-minData"><i class="fa fa-tag"></i> min. Data</label>
42
+ <input type="text" id="node-input-minData">
43
+ </div>
37
44
  </script>
38
45
 
39
46
  <script type="text/html" data-help-name="and">
package/logic_and.js CHANGED
@@ -7,26 +7,39 @@ module.exports = function(RED) {
7
7
  var node = this;
8
8
  var context = this.context();
9
9
  this.property = config.property || "payload";
10
+ this.minData = Number( config.minData );
10
11
 
11
12
  node.on('input', function(msg,send,done) {
12
13
  const payload = tools.property2boolean( RED.util.getMessageProperty( msg, node.property ) );
13
14
 
14
- let data = context.get( "data" ) ?? {};
15
- data[msg.topic] = payload;
16
- context.set( "data", data );
17
-
18
- msg.payload = true;
19
- for( const item in data )
15
+ if( payload !=== null )
20
16
  {
21
- 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 )
24
+ {
25
+ msg.count++;
26
+ if( ! data[item] )
27
+ {
28
+ msg.payload = false;
29
+ }
30
+ }
31
+
32
+ if( msg.count >= node.minData )
33
+ {
34
+ node.status( msg.payload );
35
+ send( msg );
36
+ }
37
+ else
22
38
  {
23
- msg.payload = false;
24
- break;
39
+ node.status( "waiting for data" );
25
40
  }
26
41
  }
27
42
 
28
- node.status( msg.payload );
29
- send( msg );
30
43
  done();
31
44
  });
32
45
  }
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,7 +4,10 @@
4
4
  color: "#C0DEED",
5
5
  defaults: {
6
6
  name:{value:""},
7
- property:{value:"payload",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
+ }}
8
11
  },
9
12
  inputs:1,
10
13
  outputs:1,
@@ -34,6 +37,10 @@
34
37
  <input type="text" id="node-input-property">
35
38
  <input type="hidden" id="node-input-property-type">
36
39
  </div>
40
+ <div class="form-row">
41
+ <label for="node-input-minData"><i class="fa fa-tag"></i> min. Data</label>
42
+ <input type="text" id="node-input-minData">
43
+ </div>
37
44
  </script>
38
45
 
39
46
  <script type="text/html" data-help-name="or">
package/logic_or.js CHANGED
@@ -7,26 +7,39 @@ module.exports = function(RED) {
7
7
  var node = this;
8
8
  var context = this.context();
9
9
  this.property = config.property || "payload";
10
+ this.minData = Number( config.minData );
10
11
 
11
12
  node.on('input', function(msg,send,done) {
12
13
  const payload = tools.property2boolean( RED.util.getMessageProperty( msg, node.property ) );
13
14
 
14
- let data = context.get( "data" ) ?? {};
15
- data[msg.topic] = payload;
16
- context.set( "data", data );
17
-
18
- msg.payload = false;
19
- for( const item in data )
15
+ if( payload !== null )
20
16
  {
21
- 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 )
24
+ {
25
+ msg.count++;
26
+ if( data[item] )
27
+ {
28
+ msg.payload = true;
29
+ }
30
+ }
31
+
32
+ if( msg.count >= node.minData )
33
+ {
34
+ node.status( msg.payload );
35
+ send( msg );
36
+ }
37
+ else
22
38
  {
23
- msg.payload = true;
24
- break;
39
+ node.status( "waiting for data" );
25
40
  }
26
41
  }
27
42
 
28
- node.status( msg.payload );
29
- send( msg );
30
43
  done();
31
44
  });
32
45
  }
@@ -1,5 +1,5 @@
1
1
  <script type="text/javascript">
2
- RED.nodes.registerType('plus',{
2
+ RED.nodes.registerType('tonumber',{
3
3
  category: 'function',
4
4
  color: "#C0DEED",
5
5
  defaults: {
@@ -8,12 +8,13 @@
8
8
  },
9
9
  inputs:1,
10
10
  outputs:1,
11
- icon: "font-awesome/fa-plus",
11
+ icon: "font-awesome/fa-adjust",
12
12
  label: function() {
13
- return this.name||"plus";
13
+ return this.name||"to number";
14
14
  },
15
+ paletteLabel: "to number",
15
16
  inputLabels: 'input',
16
- outputLabels: 'plus',
17
+ outputLabels: 'number',
17
18
  oneditprepare: function() {
18
19
  $("#node-input-property").typedInput({
19
20
  type:"msg",
@@ -24,7 +25,7 @@
24
25
  });
25
26
  </script>
26
27
 
27
- <script type="text/html" data-template-name="plus">
28
+ <script type="text/html" data-template-name="tonumber">
28
29
  <div class="form-row">
29
30
  <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
30
31
  <input type="text" id="node-input-name" placeholder="Name">
@@ -36,7 +37,7 @@
36
37
  </div>
37
38
  </script>
38
39
 
39
- <script type="text/html" data-help-name="plus">
40
+ <script type="text/html" data-help-name="tonumber">
40
41
 
41
42
  <p>.</p>
42
43
 
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,94 @@
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>.</p>
91
+
92
+ <h3>Input</h3>
93
+
94
+ </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.4",
3
+ "version": "0.0.7",
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
+ "tobool":"logic_bool.js",
21
+ "tonumber":"math_number.js",
20
22
  "or":"logic_or.js",
21
23
  "and":"logic_and.js",
22
- "tobool":"logic_bool.js",
23
- "plus":"math_plus.js"
24
+ "counter":"counter.js",
25
+ "reduce":"math_reduce.js"
24
26
  }
25
27
  },
26
28
  "author": {
package/math_plus.js DELETED
@@ -1,30 +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
-
10
- node.on('input', function(msg,send,done) {
11
- const payload = Number( RED.util.getMessageProperty( msg, node.property ) );
12
-
13
- let data = context.get( "data" ) ?? {};
14
- data[msg.topic] = payload;
15
- context.set( "data", data );
16
-
17
- msg.payload = 0;
18
- for( const item in data )
19
- {
20
- msg.payload += data[item];
21
- }
22
-
23
- node.status( msg.payload );
24
- send( msg );
25
- done();
26
- });
27
- }
28
-
29
- RED.nodes.registerType("plus",PlusNode);
30
- }