node-red-contrib-prib-functions 0.20.4 → 0.22.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 +82 -68
- package/dataAnalysis/arrayAverage.js +13 -0
- package/dataAnalysis/arraySum.js +14 -0
- package/dataAnalysis/arrayTypesForEach.js +5 -0
- package/dataAnalysis/autocorrelation.js +29 -0
- package/dataAnalysis/dataAnalysis.html +25 -9
- package/dataAnalysis/dataAnalysis.js +66 -43
- package/documentation/DataAnalysisRealtime.JPG +0 -0
- package/documentation/matrix.jpg +0 -0
- package/documentation/monitorSystem.JPG +0 -0
- package/documentation/monitorSystemTest.JPG +0 -0
- package/matrix/matrix.js +93 -8
- package/matrix/matrixNode.html +88 -55
- package/matrix/matrixNode.js +12 -5
- package/monitor/monitorSystem.html +2 -1
- package/monitor/monitorSystem.js +1 -1
- package/package.json +5 -1
- package/test/data/.config.nodes.json +1 -1
- package/test/data/.config.nodes.json.backup +2 -2
- package/test/data/.flow.json.backup +2486 -1814
- package/test/data/flow.json +2486 -1814
- package/test/data/package-lock.json +1 -1
- package/test/dataAnalysisExtensions.js +20 -1
- package/test/transformConfluence.js +1 -1
- package/testing/test.html +5 -1
- package/testing/test.js +79 -54
- package/arima/index.js +0 -18
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const assert=require('assert');
|
|
2
|
-
const should=require("should");
|
|
3
2
|
const m2x2=[[11,12],[21,22]]
|
|
4
3
|
const m2x3=[[11,12,13],[21,22,23]]
|
|
5
4
|
|
|
@@ -159,6 +158,13 @@ describe('sum', function(){
|
|
|
159
158
|
done();
|
|
160
159
|
});
|
|
161
160
|
});
|
|
161
|
+
describe('average', function(){
|
|
162
|
+
require("../dataAnalysis/arrayAverage.js");
|
|
163
|
+
it("array 1 to 4", function(done){
|
|
164
|
+
assert.deepEqual([1,2,3,4].average(),(1+2+3+4)/4)
|
|
165
|
+
done();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
162
168
|
describe('sumSquared', function(){
|
|
163
169
|
require("../dataAnalysis/arraySumSquared.js");
|
|
164
170
|
it("array 1 to 4", function(done){
|
|
@@ -469,4 +475,17 @@ describe('pca', function(){
|
|
|
469
475
|
console.log(multiplyMatrix(matrix,3,2,[[1,1],[1,1]]));
|
|
470
476
|
done();
|
|
471
477
|
})
|
|
478
|
+
describe('autocovariance', function(){ //autocorrelation
|
|
479
|
+
require("../dataAnalysis/autocorrelation.js");
|
|
480
|
+
const data=[0.05,0.01,-0.02,0.03,-0.04,0.06,0.02,-0.01,-0.03,0.04]
|
|
481
|
+
it("autocovariance", function(done){
|
|
482
|
+
assert.deepEqual(data.autocovariance(1).toFixed(5),-0.00046)
|
|
483
|
+
done();
|
|
484
|
+
});
|
|
485
|
+
it("autocorrelation", function(done){
|
|
486
|
+
assert.deepEqual(data.autocorrelation(1).toFixed(2),-0.38)
|
|
487
|
+
done();
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
});
|
|
472
491
|
});
|
package/testing/test.html
CHANGED
|
@@ -46,7 +46,11 @@
|
|
|
46
46
|
<input type="number" id="node-input-errorFactor" list="defaultErrorFactors" >
|
|
47
47
|
<datalist id="defaultErrorFactors">
|
|
48
48
|
<option value="0">
|
|
49
|
+
<option value="0.1">
|
|
50
|
+
<option value="0.01">
|
|
49
51
|
<option value="0.001">
|
|
52
|
+
<option value="0.0001">
|
|
53
|
+
<option value="0.00001">
|
|
50
54
|
<option value="0.000001">
|
|
51
55
|
<option value="0.000000001">
|
|
52
56
|
</datalist>
|
|
@@ -153,7 +157,7 @@
|
|
|
153
157
|
this.payloadType=setType(this.payloadType);
|
|
154
158
|
this.resultType=setType(this.resultType);
|
|
155
159
|
function setInput(t) {
|
|
156
|
-
let types=['flow','global','str','num','bool','json','bin','date','env'];
|
|
160
|
+
let types=['flow','global','str','num','bool','json','jsonata','bin','date','env'];
|
|
157
161
|
if(t=="result") types.push('re');
|
|
158
162
|
$("#node-input-"+t+"Type").val(this[t+"Type"]);
|
|
159
163
|
$("#node-input-"+t).typedInput({
|
package/testing/test.js
CHANGED
|
@@ -29,25 +29,35 @@ function setError(msg,node,err) {
|
|
|
29
29
|
node.send([null,msg]);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
function equalObjects(obj1,obj2,errorFactor) {
|
|
33
|
-
if( obj1 === obj2 ) return
|
|
32
|
+
function equalObjects(obj1,obj2,errorFactor,callEquals=()=>true,callNotEquals=()=>false) {
|
|
33
|
+
if( obj1 === obj2 ) return callEquals();
|
|
34
34
|
if(obj1 instanceof Buffer ) return Buffer.compare(obj1, obj2) === 0
|
|
35
|
-
if( obj1 === Number.POSITIVE_INFINITY && obj2==="Infinity") return
|
|
36
|
-
if( obj1 === Number.NEGATIVE_INFINITY && obj2==="-Infinity") return
|
|
37
|
-
if( Number.isNaN(obj1) && obj2==="NaN") return
|
|
35
|
+
if( obj1 === Number.POSITIVE_INFINITY && obj2==="Infinity") return callEquals();
|
|
36
|
+
if( obj1 === Number.NEGATIVE_INFINITY && obj2==="-Infinity") return callEquals();
|
|
37
|
+
if( Number.isNaN(obj1) && obj2==="NaN") return callEquals();
|
|
38
38
|
const obj1type=typeof obj1;
|
|
39
|
-
if( obj1type != typeof obj2 ) return
|
|
40
|
-
if(errorFactor && obj1type=="number") return (Math.abs(obj2-obj1)/obj2)<errorFactor;
|
|
41
|
-
if( !(obj1 instanceof Object) ) return
|
|
42
|
-
if( Object.keys(obj1).length !== Object.keys(obj2).length ) return
|
|
39
|
+
if( obj1type != typeof obj2 ) return callNotEquals();
|
|
40
|
+
if(errorFactor && obj1type=="number") return (Math.abs(obj2-obj1)/obj2)<errorFactor?callEquals():callNotEquals();
|
|
41
|
+
if( !(obj1 instanceof Object) ) return callNotEquals();
|
|
42
|
+
if( Object.keys(obj1).length !== Object.keys(obj2).length ) return callNotEquals();
|
|
43
43
|
try{
|
|
44
44
|
for(let key in obj1) {
|
|
45
|
-
if( !equalObjects(obj1[key],obj2[key],errorFactor) ) return
|
|
45
|
+
if( !equalObjects(obj1[key],obj2[key],errorFactor) ) return callNotEquals();
|
|
46
46
|
}
|
|
47
47
|
} catch(e) {
|
|
48
|
-
return
|
|
48
|
+
return callNotEquals();
|
|
49
49
|
}
|
|
50
|
-
return
|
|
50
|
+
return callEquals();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const testedOK=(node,msg)=>{
|
|
54
|
+
node.status({fill:"green",shape:"ring",text:"Success"});
|
|
55
|
+
delete msg._test;
|
|
56
|
+
node.send([null,null,msg]);
|
|
57
|
+
}
|
|
58
|
+
const testedFailed=(node,msg)=>{
|
|
59
|
+
msg._test.testedValue=node.getData(msg,node);
|
|
60
|
+
setError(msg,node,"Test failed");
|
|
51
61
|
}
|
|
52
62
|
|
|
53
63
|
module.exports = function(RED) {
|
|
@@ -56,9 +66,17 @@ module.exports = function(RED) {
|
|
|
56
66
|
RED.nodes.createNode(this,n);
|
|
57
67
|
let node=Object.assign(this,n);
|
|
58
68
|
try{
|
|
59
|
-
node.
|
|
69
|
+
node.isJSONata=node.resultType=="jsonata"
|
|
60
70
|
if(node.escapeString && node.resultType=="str") {
|
|
61
71
|
node.getData=eval("((msg,node)=>escapeSpecialChars("+(node.resultProperty||"msg.payload")+"))");
|
|
72
|
+
} else{
|
|
73
|
+
if(node.isJSONata) {
|
|
74
|
+
if(!node.result.startsWith("$boolean"))
|
|
75
|
+
throw Error("JSONata must have $boolean outcome, found: "+node.resultProperty.substr(0,8))
|
|
76
|
+
node.resultExpression=RED.util.prepareJSONataExpression(node.result, node)
|
|
77
|
+
node.resultExpression.assign('node', node);
|
|
78
|
+
}
|
|
79
|
+
node.getData=eval("((msg,node)=>"+(node.resultProperty||"msg.payload")+")");
|
|
62
80
|
}
|
|
63
81
|
node.status({fill:"green",shape:"ring",text:"Ready"});
|
|
64
82
|
} catch(e) {
|
|
@@ -66,59 +84,66 @@ module.exports = function(RED) {
|
|
|
66
84
|
node.status({fill:"red",shape:"ring",text:"Invalid setup "+e.toString()});
|
|
67
85
|
}
|
|
68
86
|
node.payloadEscape=(node.payloadType=="str"&&node.escapeString);
|
|
69
|
-
node.equalObjects=node.resultType=="re"?
|
|
87
|
+
node.equalObjects=node.resultType=="re"?
|
|
88
|
+
(value,regex,callEquals,callNotEquals)=>(RegExp(regex).test(value)?callEquals():callNotEquals()):
|
|
89
|
+
(obj1,obj2,errorFactor,callEquals,callNotEquals)=>equalObjects(obj1,obj2,errorFactor,callEquals,callNotEquals);
|
|
70
90
|
node.on("input",function(msg) {
|
|
71
91
|
if(msg._test) {
|
|
72
92
|
try{
|
|
73
|
-
if(msg._test.id!==node.id)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
93
|
+
if(msg._test.id!==node.id) return setError(msg,node,"Sent by another test "+msg._test.id);
|
|
94
|
+
|
|
95
|
+
if(node.isJSONata)
|
|
96
|
+
return RED.util.evaluateJSONataExpression(node.resultExpression,msg,(err,data)=>{
|
|
97
|
+
if(err) testedFailed(node,msg)
|
|
98
|
+
else return data?testedOK(node,msg):testedFailed(node,msg)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
node.equalObjects(node.getData(msg,node),msg._test.result,node.errorFactor,
|
|
102
|
+
()=>testedOK(node,msg),
|
|
103
|
+
()=>testedFailed(node,msg)
|
|
104
|
+
);
|
|
105
|
+
|
|
83
106
|
} catch(ex){
|
|
84
107
|
setError(msg,node,"Test failed on get data "+ex.message);
|
|
85
108
|
}
|
|
86
109
|
return;
|
|
87
110
|
}
|
|
88
111
|
node.status({fill:"yellow",shape:"ring",text:"waiting on response"});
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
112
|
+
let result=RED.util.evaluateNodeProperty(node.result,node.resultType,node,msg,(err,data)=>{
|
|
113
|
+
if(err) node.error(err,msg)
|
|
114
|
+
msg._test={
|
|
115
|
+
id:node.id,
|
|
116
|
+
result:node.escapeString&&node.resultType=="str"?escapeSpecialChars(data):data
|
|
117
|
+
};
|
|
118
|
+
msg.topic=node.topic;
|
|
119
|
+
if(["flow","global"].includes(node.payloadType)) {
|
|
120
|
+
RED.util.evaluateNodeProperty(node.payload,node.payloadType,node,msg, (err,res)=>{
|
|
121
|
+
if (err) {
|
|
122
|
+
node.error(err,msg);
|
|
123
|
+
} else {
|
|
124
|
+
msg.payload=res;
|
|
125
|
+
node.send(msg);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
} else {
|
|
129
|
+
try {
|
|
130
|
+
if ( (node.payloadType == null && node.payload === "") || node.payloadType === "date") {
|
|
131
|
+
msg.payload = Date.now();
|
|
132
|
+
} else if (node.payloadType == null) {
|
|
133
|
+
msg.payload = node.payload;
|
|
134
|
+
} else if (node.payloadType === 'none') {
|
|
135
|
+
msg.payload = "";
|
|
136
|
+
} else {
|
|
137
|
+
msg.payload=RED.util.evaluateNodeProperty(this.payload,node.payloadType,node,msg);
|
|
138
|
+
if(node.payloadEscape) msg.payload=msg.payload.escapeSpecialChars();
|
|
139
|
+
}
|
|
101
140
|
node.send(msg);
|
|
141
|
+
msg = null;
|
|
142
|
+
} catch(err) {
|
|
143
|
+
node.error(err,msg);
|
|
102
144
|
}
|
|
103
|
-
});
|
|
104
|
-
} else {
|
|
105
|
-
try {
|
|
106
|
-
if ( (node.payloadType == null && node.payload === "") || node.payloadType === "date") {
|
|
107
|
-
msg.payload = Date.now();
|
|
108
|
-
} else if (node.payloadType == null) {
|
|
109
|
-
msg.payload = node.payload;
|
|
110
|
-
} else if (node.payloadType === 'none') {
|
|
111
|
-
msg.payload = "";
|
|
112
|
-
} else {
|
|
113
|
-
msg.payload=RED.util.evaluateNodeProperty(this.payload,node.payloadType,node,msg);
|
|
114
|
-
if(node.payloadEscape) msg.payload=msg.payload.escapeSpecialChars();
|
|
115
|
-
}
|
|
116
|
-
node.send(msg);
|
|
117
|
-
msg = null;
|
|
118
|
-
} catch(err) {
|
|
119
|
-
node.error(err,msg);
|
|
120
145
|
}
|
|
121
|
-
}
|
|
146
|
+
});
|
|
122
147
|
});
|
|
123
148
|
}
|
|
124
149
|
|
package/arima/index.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
const observations=[]
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if(Array.prototype.differenceSeasonalSecondOrder ==null)
|
|
6
|
-
Object.defineProperty(Array.prototype, "differenceSeasonalSecondOrder", {
|
|
7
|
-
value(lag) {
|
|
8
|
-
let i=result.length-lag-1
|
|
9
|
-
const result=new Array(size)
|
|
10
|
-
while(i--) {
|
|
11
|
-
const ilag=i-lag
|
|
12
|
-
result[i]=this[i]-this[i+1]-this[iLag]+this[iLag+1]
|
|
13
|
-
}
|
|
14
|
-
return result;
|
|
15
|
-
},
|
|
16
|
-
writable: true,
|
|
17
|
-
configurable: true
|
|
18
|
-
});
|