@mschaeffler/node-red-logic 3.3.1 → 3.5.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/math_statistics.html +29 -1
- package/math_statistics.js +16 -5
- package/package.json +1 -1
package/math_statistics.html
CHANGED
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
},
|
|
12
12
|
minData:{value:"1", required:true, validate:function(v){
|
|
13
13
|
return v!=='' && !isNaN(v) && Number(v)>0;}
|
|
14
|
-
}
|
|
14
|
+
},
|
|
15
|
+
contextStore:{value:"",required:true},
|
|
16
|
+
showState:{value:false}
|
|
15
17
|
},
|
|
16
18
|
inputs:1,
|
|
17
19
|
outputs:1,
|
|
@@ -25,11 +27,25 @@
|
|
|
25
27
|
inputLabels: 'input',
|
|
26
28
|
outputLabels: 'output',
|
|
27
29
|
oneditprepare: function() {
|
|
30
|
+
const node = this;
|
|
28
31
|
$("#node-input-property").typedInput({
|
|
29
32
|
type:"msg",
|
|
30
33
|
types:["msg","jsonata"],
|
|
31
34
|
typeField: "#node-input-propertyType"
|
|
32
35
|
});
|
|
36
|
+
// populate store names
|
|
37
|
+
$("#node-input-contextStore").empty();
|
|
38
|
+
$("#node-input-contextStore").append(`<option value="none">None</option>`);
|
|
39
|
+
const defaultStore = RED.settings.hasOwnProperty('context') ? RED.settings.context.default : ''
|
|
40
|
+
RED.settings.context.stores.forEach(function(item){
|
|
41
|
+
if( item ) {
|
|
42
|
+
const opt = $(`<option value="${item}">${item}${item===defaultStore?" (default)":""}</option>`);
|
|
43
|
+
$("#node-input-contextStore").append(opt);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
const currentStore = node.contextStore || '';
|
|
47
|
+
// select the current option
|
|
48
|
+
$("#node-input-contextStore").val(currentStore);
|
|
33
49
|
}
|
|
34
50
|
});
|
|
35
51
|
</script>
|
|
@@ -52,6 +68,14 @@
|
|
|
52
68
|
<label for="node-input-minData"><i class="fa fa-check-square-o "></i> min. Data</label>
|
|
53
69
|
<input type="text" id="node-input-minData">
|
|
54
70
|
</div>
|
|
71
|
+
<div class="form-row">
|
|
72
|
+
<label for="node-input-contextStore"><i class="fa fa-database"></i> Contextstore</label>
|
|
73
|
+
<select type="text" id="node-input-contextStore"></select>
|
|
74
|
+
</div>
|
|
75
|
+
<div class="form-row">
|
|
76
|
+
<label for="node-input-showStatus"><i class="fa fa-star-o"></i> Status</label>
|
|
77
|
+
<input type="checkbox" id="node-input-showState" style="display:inline-block; width:20px; vertical-align:baseline;">
|
|
78
|
+
</div>
|
|
55
79
|
</script>
|
|
56
80
|
|
|
57
81
|
<script type="text/html" data-help-name="statistics">
|
|
@@ -104,5 +128,9 @@
|
|
|
104
128
|
<dd> time frame to collect the data for the analysis.</dd>
|
|
105
129
|
<dt>min. Data <span class="property-type">number</span></dt>
|
|
106
130
|
<dd> min. amount of data points to generate an output.</dd>
|
|
131
|
+
<dt>Contextstore <span class="property-type">context store</span></dt>
|
|
132
|
+
<dd> context store for storing the values; <code>none</code> is no storage.</dd>
|
|
133
|
+
<dt>Status <span class="property-type">boolean</span></dt>
|
|
134
|
+
<dd> shows the actual value as a node status.</dd>
|
|
107
135
|
</dl>
|
|
108
136
|
</script>
|
package/math_statistics.js
CHANGED
|
@@ -9,6 +9,8 @@ module.exports = function(RED) {
|
|
|
9
9
|
this.propertyType = config.propertyType ?? "msg";
|
|
10
10
|
this.deltaTime = Number( config.deltaTime ?? 60 )*1000;
|
|
11
11
|
this.minData = Number( config.minData ?? 1 );
|
|
12
|
+
this.contextStore = config.contextStore ?? "none";
|
|
13
|
+
this.showState = Boolean( config.showState );
|
|
12
14
|
if( this.propertyType === "jsonata" )
|
|
13
15
|
{
|
|
14
16
|
try {
|
|
@@ -60,7 +62,7 @@ module.exports = function(RED) {
|
|
|
60
62
|
const payload = Number( value );
|
|
61
63
|
if( ! isNaN( payload ) )
|
|
62
64
|
{
|
|
63
|
-
let data = context.get( "data" ) ?? {};
|
|
65
|
+
let data = context.get( "data", node.contextStore ) ?? {};
|
|
64
66
|
let item = data[msg.topic] ?? [];
|
|
65
67
|
item.push( { time:now, value:payload } );
|
|
66
68
|
while( item[0].time < now - node.deltaTime )
|
|
@@ -68,7 +70,7 @@ module.exports = function(RED) {
|
|
|
68
70
|
item.shift();
|
|
69
71
|
}
|
|
70
72
|
data[msg.topic] = item;
|
|
71
|
-
context.set( "data", data );
|
|
73
|
+
context.set( "data", data, node.contextStore );
|
|
72
74
|
|
|
73
75
|
if( item.length >= node.minData )
|
|
74
76
|
{
|
|
@@ -99,17 +101,26 @@ module.exports = function(RED) {
|
|
|
99
101
|
}
|
|
100
102
|
msg.stat.deviation = Math.sqrt( varianz / msg.stat.count );
|
|
101
103
|
msg.stat.variation = msg.stat.deviation / msg.stat.average;
|
|
102
|
-
node.
|
|
104
|
+
if( node.showState )
|
|
105
|
+
{
|
|
106
|
+
node.status({fill:"green",shape:"dot",text:`${msg.stat.count} / ${msg.stat.deviation.toPrecision(4)}`});
|
|
107
|
+
}
|
|
103
108
|
send( msg );
|
|
104
109
|
}
|
|
105
110
|
else
|
|
106
111
|
{
|
|
107
|
-
node.
|
|
112
|
+
if( node.showState )
|
|
113
|
+
{
|
|
114
|
+
node.status({fill:"gray",shape:"dot",text:"to less data"});
|
|
115
|
+
}
|
|
108
116
|
}
|
|
109
117
|
}
|
|
110
118
|
else
|
|
111
119
|
{
|
|
112
|
-
node.
|
|
120
|
+
if( node.showState )
|
|
121
|
+
{
|
|
122
|
+
node.status({fill:"red",shape:"dot",text:"payload is NaN"});
|
|
123
|
+
}
|
|
113
124
|
}
|
|
114
125
|
done();
|
|
115
126
|
} );
|
package/package.json
CHANGED