@mschaeffler/node-red-logic 4.3.3 → 4.3.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/README.md CHANGED
@@ -349,6 +349,9 @@ Trigger message, in case an edge is detected.
349
349
  for `falling edge`, `raising edge` and `hysteresis`:
350
350
  * [Eugene Schava](https://github.com/eschava/node-red-contrib-edge-trigger)
351
351
 
352
+ for lowpass icon:
353
+ * [Cabfdb - Eigenes Werk, CC BY-SA 3.0](https://commons.wikimedia.org/w/index.php?curid=9651125)
354
+
352
355
  ## License
353
356
 
354
357
  LGPL-2.1
@@ -0,0 +1,87 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+ <svg
5
+ width="188.59811"
6
+ height="187.48582"
7
+ id="svg3970"
8
+ version="1.1"
9
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
10
+ sodipodi:docname="Low-pass_filter.svg"
11
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
13
+ xmlns="http://www.w3.org/2000/svg"
14
+ xmlns:svg="http://www.w3.org/2000/svg"
15
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
16
+ xmlns:cc="http://creativecommons.org/ns#"
17
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
18
+ <defs
19
+ id="defs3972">
20
+ <inkscape:perspective
21
+ sodipodi:type="inkscape:persp3d"
22
+ inkscape:vp_x="0 : 526.18109 : 1"
23
+ inkscape:vp_y="0 : 1000 : 0"
24
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
25
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
26
+ id="perspective3978" />
27
+ <inkscape:perspective
28
+ id="perspective3951"
29
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
30
+ inkscape:vp_z="1 : 0.5 : 1"
31
+ inkscape:vp_y="0 : 1000 : 0"
32
+ inkscape:vp_x="0 : 0.5 : 1"
33
+ sodipodi:type="inkscape:persp3d" />
34
+ </defs>
35
+ <sodipodi:namedview
36
+ id="base"
37
+ pagecolor="#ffffff"
38
+ bordercolor="#ffffff"
39
+ borderopacity="0.0"
40
+ inkscape:pageopacity="0.0"
41
+ inkscape:pageshadow="0"
42
+ inkscape:zoom="5.9508176"
43
+ inkscape:cx="93.264495"
44
+ inkscape:cy="90.743833"
45
+ inkscape:document-units="px"
46
+ inkscape:current-layer="layer1"
47
+ showgrid="false"
48
+ inkscape:window-width="3440"
49
+ inkscape:window-height="1366"
50
+ inkscape:window-x="0"
51
+ inkscape:window-y="0"
52
+ inkscape:window-maximized="1"
53
+ inkscape:showpageshadow="2"
54
+ inkscape:pagecheckerboard="true"
55
+ inkscape:deskcolor="#d1d1d1" />
56
+ <metadata
57
+ id="metadata3975">
58
+ <rdf:RDF>
59
+ <cc:Work
60
+ rdf:about="">
61
+ <dc:format>image/svg+xml</dc:format>
62
+ <dc:type
63
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
64
+ </cc:Work>
65
+ </rdf:RDF>
66
+ </metadata>
67
+ <g
68
+ inkscape:label="Layer 1"
69
+ inkscape:groupmode="layer"
70
+ id="layer1"
71
+ transform="translate(271.34805,-134.11113)">
72
+ <path
73
+ style="fill:none;stroke:#ffffff;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
74
+ d="m -240.65258,203.78557 c 0,0 28.57143,-61.42858 62.14286,0 33.57143,61.42856 61.42857,-1.07143 61.42857,-1.07143"
75
+ id="path2876"
76
+ sodipodi:nodetypes="csc" />
77
+ <path
78
+ style="fill:none;stroke:#ffffff;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
79
+ d="m -190.04518,216.95956 26.53923,-25.16392"
80
+ id="path2878" />
81
+ <path
82
+ style="fill:none;stroke:#ffffff;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
83
+ d="m -240.0424,249.87743 c 0,0 28.57143,-61.42856 62.14286,0 33.57143,61.42857 61.42857,-1.07143 61.42857,-1.07143"
84
+ id="path2876-0"
85
+ sodipodi:nodetypes="csc" />
86
+ </g>
87
+ </svg>
package/math_lowpass.html CHANGED
@@ -18,13 +18,14 @@
18
18
  },
19
19
  inputs:1,
20
20
  outputs:1,
21
- icon:"smooth.png",
21
+ icon:"lowpassfilter.svg",
22
22
  label: function() {
23
23
  return this.name||this.topic||"lowPass";
24
24
  },
25
25
  labelStyle: function() {
26
26
  return this.name?"node_label_italic":"";
27
27
  },
28
+ paletteLabel: "lowPass",
28
29
  inputLabels: 'input',
29
30
  outputLabels: 'output',
30
31
  oneditprepare: function() {
@@ -90,7 +91,7 @@
90
91
 
91
92
  <script type="text/html" data-help-name="lowpass">
92
93
 
93
- <p>Filter the values of one or more data streams wuth an adaptive Kalman filter.</p>
94
+ <p>Filter the values of one or more data streams with a recursive low pass filter.</p>
94
95
  <p>If the msg property <code>invalid</code> is present in the message, all nodes ignore the message.</p>
95
96
 
96
97
  <h3>Input</h3>
@@ -103,8 +104,6 @@
103
104
  <dd> name of the input channel.</dd>
104
105
  <dt>payload <span class="property-type">number</span></dt>
105
106
  <dd> input value for <code>topic</code>.</dd>
106
- <dt>control <span class="property-type">number</span></dt>
107
- <dd> control value, THe message property can be selected with the <code>Control</code> property.</dd>
108
107
  </dl>
109
108
 
110
109
  <h3>Output</h3>
package/math_lowpass.js CHANGED
@@ -16,8 +16,8 @@ module.exports = function(RED) {
16
16
  this.zeroIsZero = Boolean( config.zeroIsZero );
17
17
  this.round = config.decimals ? Math.pow( 10, Number( config.decimals ) ) : null;
18
18
  this.showState = Boolean( config.showState );
19
- this.data = {};
20
- this.last = {};
19
+ this.data = {};
20
+ this.last = {};
21
21
  if( this.propertyType === "jsonata" )
22
22
  {
23
23
  try {
@@ -41,14 +41,12 @@ module.exports = function(RED) {
41
41
  node.on('input', function(msg,send,done) {
42
42
  if( msg.invalid )
43
43
  {
44
- done();
45
44
  }
46
45
  else if( msg.reset || msg.topic==="init" )
47
46
  {
48
47
  node.data = {};
49
48
  node.last = {};
50
49
  node.status( "" );
51
- done();
52
50
  }
53
51
  else
54
52
  {
@@ -79,59 +77,39 @@ module.exports = function(RED) {
79
77
  {
80
78
  msg.topic = node.topic;
81
79
  }
82
- const payload = Number( value );
83
- if( ! isNaN( payload ) )
80
+ const measurement = Number( value );
81
+ if( ! isNaN( measurement ) )
84
82
  {
85
- node.data[msg.topic] ??= {};
86
- const data = node.data[msg.topic];
87
- const now = Date.now();
88
-
89
- function lowPassFilter(measurement)
90
- {
91
- if( data.last == undefined )
92
- {
93
- data.last = measurement;
94
- }
95
- else
96
- {
97
- data.last += node.alpha * ( measurement - data.last );
98
- }
99
- return data.last;
100
- }
83
+ // Alpha-Filter
84
+ if( node.data[msg.topic] === undefined || ( node.zeroIsZero && measurement === 0 ) )
85
+ {
86
+ node.data[msg.topic] = measurement;
87
+ }
88
+ else
89
+ {
90
+ node.data[msg.topic] += node.alpha * ( measurement - node.data[msg.topic] );
91
+ }
101
92
 
102
- function sendValue(value)
103
- {
104
- msg.payload = value;
105
- node.last[msg.topic] = {value:value,time:now};
106
- setStatus( "green", tools.formatNumber(value) );
107
- send( msg );
108
- }
93
+ // Round
94
+ msg.payload = node.round ? Math.round( node.data[msg.topic] * node.round ) / node.round : node.data[msg.topic];
109
95
 
110
- if( node.zeroIsZero && payload === 0 )
111
- {
112
- data.estimate = 0;
113
- sendValue( 0 );
114
- }
115
- else
116
- {
117
- let value = lowPassFilter( payload );
118
- const help = node.last[msg.topic];
119
- if( help === undefined ||
120
- ( help.time + node.filterTime < now && tools.distance( help.value, value ) >= node.filterValue ) ||
121
- ( node.filterLongTime > 0 && help.time + node.filterLongTime < now ) )
122
- {
123
- if( node.round )
124
- {
125
- value = Math.round( value * node.round ) / node.round;
126
- }
127
- sendValue( value );
128
- }
129
- else
130
- {
131
- setStatus( "gray", tools.formatNumber(value) );
132
- }
133
- }
134
- context.set( "data", node.data, node.contextStore );
96
+ // Send-Filter
97
+ const now = Date.now();
98
+ const help = node.last[msg.topic];
99
+ let color;
100
+ if( help === undefined ||
101
+ ( help.time + node.filterTime < now && tools.distance( help.value, node.data[msg.topic] ) >= node.filterValue ) ||
102
+ ( node.filterLongTime > 0 && help.time + node.filterLongTime < now ) )
103
+ {
104
+ node.last[msg.topic] = { value:msg.payload, time:now };
105
+ send( msg );
106
+ color = "green";
107
+ }
108
+ else
109
+ {
110
+ color = "gray";
111
+ }
112
+ setStatus( color, tools.formatNumber(msg.payload) );
135
113
  }
136
114
  else
137
115
  {
@@ -141,9 +119,9 @@ module.exports = function(RED) {
141
119
  node.warn( `payload is NaN (${msg.topic}=${value})` );
142
120
  }
143
121
  }
144
- done();
145
122
  } );
146
123
  }
124
+ done();
147
125
  });
148
126
  }
149
127
 
package/math_mean.html CHANGED
@@ -67,7 +67,7 @@
67
67
  </div>
68
68
  <div class="form-row">
69
69
  <label for="node-input-minMean"><i class="fa fa-hourglass-o"></i> Zeitspanne</label>
70
- <input type="text" id="node-input-deltaTime" style="width:70px;" placeholder="Time">
70
+ <input type="number" id="node-input-deltaTime" style="width:70px;" placeholder="Time">
71
71
  <select id="node-input-deltaUnit" style="width:140px;">
72
72
  <option value="msecs">MilliSeconds</option>
73
73
  <option value="secs">Seconds</option>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mschaeffler/node-red-logic",
3
- "version": "4.3.3",
3
+ "version": "4.3.5",
4
4
  "description": "nodes for simple operations.",
5
5
  "license": "LGPL-2.1",
6
6
  "homepage": "https://github.com/m-schaeffler/node-red-my-nodes/tree/main/node-red-logic",
@@ -41,6 +41,6 @@
41
41
  "url": "https://github.com/m-schaeffler"
42
42
  },
43
43
  "scripts": {
44
- "test": "mocha \"test/math_lowpass_spec.js\""
44
+ "test": "mocha \"test/*_spec.js\""
45
45
  }
46
46
  }