@mschaeffler/node-red-logic 4.3.3 → 4.4.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 +3 -0
- package/icons/lowpassfilter.svg +87 -0
- package/logic_blinker.js +12 -5
- package/math_lowpass.html +3 -4
- package/math_lowpass.js +33 -55
- package/math_mean.html +1 -1
- package/package.json +2 -2
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/logic_blinker.js
CHANGED
|
@@ -9,11 +9,11 @@ module.exports = function(RED) {
|
|
|
9
9
|
this.onTime = Number( config.onTime ?? 1 ) * tools.timeUnits( config.onTimeUnit );
|
|
10
10
|
this.offTime = Number( config.offTime ?? 1 ) * tools.timeUnits( config.offTimeUnit );
|
|
11
11
|
this.firstType = config.outputFirstType ?? "bool";
|
|
12
|
-
this.lastType = config.outputLastType
|
|
13
|
-
this.
|
|
14
|
-
this.
|
|
15
|
-
this.
|
|
16
|
-
this.
|
|
12
|
+
this.lastType = config.outputLastType ?? "bool";
|
|
13
|
+
this.configOutputFirst = RED.util.evaluateNodeProperty( config.outputFirst ?? "true", this.firstType );
|
|
14
|
+
this.configOutputOn = RED.util.evaluateNodeProperty( config.outputOn ?? "true", config.outputOnType ?? "bool" );
|
|
15
|
+
this.configOutputOff = RED.util.evaluateNodeProperty( config.outputOff ?? "false", config.outputOffType ?? "bool" );
|
|
16
|
+
this.configOutputLast = RED.util.evaluateNodeProperty( config.outputLast ?? "false", this.lastType );
|
|
17
17
|
this.filter = Boolean( config.filter );
|
|
18
18
|
this.showState = Boolean( config.showState );
|
|
19
19
|
this.timerOn = null;
|
|
@@ -95,6 +95,13 @@ module.exports = function(RED) {
|
|
|
95
95
|
done();
|
|
96
96
|
return;
|
|
97
97
|
}
|
|
98
|
+
if( msg.output || node.outputFirst === undefined )
|
|
99
|
+
{
|
|
100
|
+
node.outputFirst = msg.output?.first ?? node.configOutputFirst;
|
|
101
|
+
node.outputOn = msg.output?.on ?? node.configOutputOn;
|
|
102
|
+
node.outputOff = msg.output?.off ?? node.configOutputOff;
|
|
103
|
+
node.outputLast = msg.output?.last ?? node.configOutputLast;
|
|
104
|
+
}
|
|
98
105
|
node.state = tools.property2boolean( RED.util.getMessageProperty( msg, node.property ) );
|
|
99
106
|
if( node.state !== null )
|
|
100
107
|
{
|
package/math_lowpass.html
CHANGED
|
@@ -18,13 +18,14 @@
|
|
|
18
18
|
},
|
|
19
19
|
inputs:1,
|
|
20
20
|
outputs:1,
|
|
21
|
-
icon:"
|
|
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
|
|
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
|
|
83
|
-
if( ! isNaN(
|
|
80
|
+
const measurement = Number( value );
|
|
81
|
+
if( ! isNaN( measurement ) )
|
|
84
82
|
{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
|
|
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
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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="
|
|
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
|
+
"version": "4.4.0",
|
|
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
|
|
44
|
+
"test": "mocha \"test/*_spec.js\""
|
|
45
45
|
}
|
|
46
46
|
}
|