let total = 0
let count = 0 // number of samples accumulated
let answer = []
for (i = 0; i < msg.payload.length; i++) {
total += msg.payload[i].y
if (i >= n) {
total -= msg.payload[i-n].y
count = n
} else {
count = i+1
}
answer[i] = {x: msg.payload[i].x, y: total/count}
}
msg.payload = answer
return msg;
output should be
msg.payload : array[6]
.[undefined , undefined , (avg of stored value +latest value) ,(avg of stored value +latest value) ,(avg of stored value +latest value) ]
Welcome to the forum @developedbymayur
In order to make code readable and usable it is necessary to surround your code with three backticks (also known as a left quote or backquote ```
)
```
code goes here
```
You can edit and correct your post by clicking the pencil icon.
See this post for more details - How to share code or flow json
To debug your code you can add node.warn() statements to show intermediate results in the debug pane. For example, after the total +=
line you could add
node.warn(`total = ${total}`)
By using that technique you can follow the flow through and see where it is failing.
Thank you for your reply ,
the problem goes with storing the old msg and then again adding it with the new msg and dividing by count or 2 to get running average
You might also want to add a catch
node connected to a debug
node (set to display thecomplete msg object
) to that tab
[
{
"id": "9fcb452698206e8c",
"type": "tab",
"label": "Flow 3",
"disabled": false,
"info": "",
"env": []
},
{
"id": "a4691e8c2d013040",
"type": "OPCUA-IIoT-Browser",
"z": "9fcb452698206e8c",
"connector": "17a609ce3274baf2",
"nodeId": "i=84 [RootFolder]",
"name": "",
"justValue": false,
"sendNodesToRead": true,
"sendNodesToListener": true,
"sendNodesToBrowser": true,
"singleBrowseResult": false,
"recursiveBrowse": false,
"recursiveDepth": "",
"delayPerMessage": "",
"showStatusActivities": false,
"showErrors": false,
"x": 380,
"y": 80,
"wires": [
[
"2df8b7774cdd5e69",
"e9ad70693beded27",
"103a484dd3f842e5"
]
]
},
{
"id": "bdfac377c3f32d73",
"type": "OPCUA-IIoT-Inject",
"z": "9fcb452698206e8c",
"injectType": "read",
"payloadType": "date",
"topic": "",
"repeat": "10",
"crontab": "",
"once": true,
"startDelay": "",
"name": "Root",
"payload": "",
"addressSpaceItems": [
{
"name": "",
"nodeId": "ns=2;s=Channel2.TEST",
"datatypeName": ""
}
],
"x": 180,
"y": 80,
"wires": [
[
"a4691e8c2d013040"
]
]
},
{
"id": "2df8b7774cdd5e69",
"type": "OPCUA-IIoT-Response",
"z": "9fcb452698206e8c",
"name": "",
"x": 580,
"y": 80,
"wires": [
[
"2c925a3cd0eeb322"
]
]
},
{
"id": "0cc20b88fe657a2f",
"type": "OPCUA-IIoT-Response",
"z": "9fcb452698206e8c",
"name": "",
"compressStructure": false,
"showStatusActivities": false,
"showErrors": false,
"activateUnsetFilter": false,
"activateFilters": false,
"negateFilter": false,
"filters": [],
"x": 580,
"y": 160,
"wires": [
[
"2cc02467c4033f83",
"ceb8c7912beae378"
]
]
},
{
"id": "e9ad70693beded27",
"type": "ui_template",
"z": "9fcb452698206e8c",
"group": "",
"name": "",
"order": 0,
"width": 0,
"height": 0,
"format": "<div layout=\"column\" layout-align=\"space-between\">\n <div layout=\"row\" layout-align=\"space-around center\">\n <p>{{msg.payload.endpoint}}</p>\n </div>\n <div layout=\"row\" layout-align=\"space-around center\">\n <p>{{msg.payload.browseTopic}} with {{msg.payload.browserResultCount}} references</p>\n </div>\n <div layout=\"row\" layout-align=\"space-between center\">\n <h1>Results</h1>\n </div>\n <div layout=\"row\" layout-align=\"space-between center\">\n <select ng-model=\"item\" ng-options=\"item.displayName.text for item in msg.payload.browserItems\">\n <option value=\"\">-- Root --</option>\n </select>\n <button ng-click=\"send({payload: {actiontype: 'browse', root: item}})\">Browse</button>\n </div>\n <div layout=\"row\" layout-align=\"space-around center\">\n <div>\n <ul>\n <li ng-repeat=\"item in msg.payload.browserItems\">\n {{item.displayName.text}} ( {{item.nodeId}} - {{item.browseName}})\n </li>\n </ul>\n </div>\n </div>\n</div>",
"storeOutMessages": false,
"fwdInMessages": false,
"resendOnRefresh": false,
"templateScope": "local",
"className": "",
"x": 380,
"y": 20,
"wires": [
[
"a4691e8c2d013040"
]
]
},
{
"id": "103a484dd3f842e5",
"type": "OPCUA-IIoT-Read",
"z": "9fcb452698206e8c",
"attributeId": "13",
"maxAge": "0",
"depth": 1,
"connector": "17a609ce3274baf2",
"name": "Read browsed NodeIds",
"justValue": false,
"showStatusActivities": false,
"showErrors": false,
"parseStrings": false,
"historyDays": "",
"serverMaxItemsToRead": "1000",
"x": 230,
"y": 160,
"wires": [
[
"0cc20b88fe657a2f",
"03da37f71d40c299"
]
]
},
{
"id": "2cc02467c4033f83",
"type": "debug",
"z": "9fcb452698206e8c",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 850,
"y": 160,
"wires": []
},
{
"id": "2c925a3cd0eeb322",
"type": "debug",
"z": "9fcb452698206e8c",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 850,
"y": 80,
"wires": []
},
{
"id": "0f05e4703ba6eaf8",
"type": "MSSQL",
"z": "9fcb452698206e8c",
"d": true,
"mssqlCN": "367683cd092b717e",
"name": "",
"outField": "",
"returnType": 0,
"throwErrors": "0",
"query": "Insert into dbo.test (EntryId,TimeStamp,Ramp1,Ramp2,Ramp3,Ramp4) values('{{{payload.2}}}','{{{payload.timestamp}}}','{{{payload.2}}}','{{{payload.3}}}','{{{payload.4}}}','{{{payload.5}}}');",
"modeOpt": "queryMode",
"modeOptType": "query",
"queryOpt": "payload",
"queryOptType": "editor",
"paramsOpt": "queryParams",
"paramsOptType": "none",
"rows": "rows",
"rowsType": "msg",
"params": [],
"x": 700,
"y": 300,
"wires": [
[
"bb2f6f9e47cc4b75"
]
]
},
{
"id": "a45fc85ede765387",
"type": "debug",
"z": "9fcb452698206e8c",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 850,
"y": 220,
"wires": []
},
{
"id": "ceb8c7912beae378",
"type": "function",
"z": "9fcb452698206e8c",
"name": "Data Parsor",
"func": "//const msgObj = new Object();\n//const dataObj = new Object();\n//const payloadObj = new Object();\n\n//msg.payload = msg.payload[2].value;\n//return msg;\n\n//------------form data Object with datapoints--------//\nfor(i = 0; i < msg.payload.length; i++){\n msg.payload[i] = msg.payload[i].value;\n}\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 470,
"y": 220,
"wires": [
[
"a45fc85ede765387",
"0f05e4703ba6eaf8",
"25a79a0c11f46372"
]
]
},
{
"id": "03da37f71d40c299",
"type": "debug",
"z": "9fcb452698206e8c",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 270,
"y": 220,
"wires": []
},
{
"id": "25a79a0c11f46372",
"type": "function",
"z": "9fcb452698206e8c",
"name": "average",
"func": "const n = 2 // no of samples to average over\nlet total = []\nlet count = [] // number of samples accumulated\nlet answer = []\nfor (i = 2; i < msg.payload.length; i++) { \n total += msg.payload[i]\n if (i >= n) {\n total -= msg.payload[i-n]\n count = n\n } else {\n count = i+1\n }\n answer[i] = total/count\n}\nmsg.payload = answer\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 600,
"y": 360,
"wires": [
[
"db2c68b0e0ba059c"
]
]
},
{
"id": "db2c68b0e0ba059c",
"type": "debug",
"z": "9fcb452698206e8c",
"name": "Trial",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 850,
"y": 360,
"wires": []
},
{
"id": "bb2f6f9e47cc4b75",
"type": "debug",
"z": "9fcb452698206e8c",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 870,
"y": 300,
"wires": []
},
{
"id": "f508e990ae0cc37e",
"type": "catch",
"z": "9fcb452698206e8c",
"name": "",
"scope": [
"db2c68b0e0ba059c"
],
"uncaught": false,
"x": 710,
"y": 420,
"wires": [
[
"db2c68b0e0ba059c"
]
]
},
{
"id": "17a609ce3274baf2",
"type": "OPCUA-IIoT-Connector",
"discoveryUrl": "opc.tcp://192.168.0.102:49320",
"endpoint": "opc.tcp://192.168.0.102:49320/",
"keepSessionAlive": true,
"loginEnabled": false,
"securityPolicy": "None",
"securityMode": "NONE",
"name": "REMOTE SERVER",
"showErrors": false,
"individualCerts": false,
"publicCertificateFile": "",
"privateKeyFile": "",
"defaultSecureTokenLifetime": "",
"endpointMustExist": false,
"autoSelectRightEndpoint": true,
"strategyMaxRetry": "",
"strategyInitialDelay": "",
"strategyMaxDelay": "",
"strategyRandomisationFactor": "",
"requestedSessionTimeout": "",
"connectionStartDelay": "",
"reconnectDelay": "",
"maxBadSessionRequests": "10"
},
{
"id": "367683cd092b717e",
"type": "MSSQL-CN",
"tdsVersion": "7_4",
"name": "solar",
"server": "SCITHLT0236",
"port": "1433",
"encyption": false,
"trustServerCertificate": true,
"database": "SOLAR STORE FORWARD",
"useUTC": true,
"connectTimeout": "15000",
"requestTimeout": "15000",
"cancelTimeout": "5000",
"pool": "5",
"parseJSON": false,
"enableArithAbort": true
}
]
does not work with array
Can you please all help with forming a function node to do so
I still don't fully understand what you are trying to do. Can you provide an example of the sequence of messages that might come in, and what you want out? An actual example with numbers.
I have done something similar to what you want to do.
Sorry if it is not exactly what you want. But to put it out there:
I receive temperature messages ongoing. 24/7.
This node calculates the Max/Min and Avg values received.
[{"id":"acbd4dca.cd318","type":"function","z":"78d17e5b.9e6ff","g":"7e49ed3d.35f9cc","name":"Avg/Max/Min readings","func":"let max = context.get(\"max\") || 0;\nlet counter = context.get(\"counter\") || 0;\nlet min = context.get(\"min\") || null;\nlet avg = context.get(\"avg\") || null;\nlet total = context.get(\"total\") || 0;\n\n\n//node.warn(\"Initial total reading is \" + total);\n//total = total;\n\nlet new_value = parseInt(msg.payload);\n\nmsg1 = {};\nmsg2 = {};\n\nif (msg.reset == true)\n{\n // Reset all things\n node.warn(\"RESET\");\n context.set(\"max\",0);\n context.set(\"counter\",0);\n context.set(\"min\",0);\n context.set(\"avg\",0);\n context.set(\"total\",0);\n return;\n}\n\nif (counter === 0)\n{\n // First pass\n context.set(\"max\",new_value);\n context.set(\"min\",new_value)\n context.set(\"avg\",new_value);\n min = new_value;\n max = new_value;\n avg = new_value;\n total = new_value;\n}\n\n//new_value = msg.payload;\n\nif (new_value > max)\n{\n max = new_value;\n context.set(\"max\",new_value);\n}\n\nif (new_value < min)\n{\n\tmin = new_value;\n\tcontext.set(\"min\",new_value);\n}\n\ncounter = counter + 1;\ncontext.set(\"counter\",counter);\n\ntotal = context.get(\"total\") || 0;\n//node.warn(\"context TOTAL is \" + total);\ntotal = total + new_value;\n//node.warn(\"TOTAL IS NOW \" + total);\ncontext.set(\"total\",total);\navg = Math.round((total / counter));\n\n//\n\n//msg.payload = \"My calculated average is \" + avg;\nmsg.payload = Math.round(avg);\nmsg1.payload = Math.round(max);\nmsg2.payload = Math.round(min);\nreturn [msg,msg1,msg2];","outputs":3,"noerr":0,"initialize":"","finalize":"","x":2160,"y":1540,"wires":[["b6b37cab.88821","267b42e0.270b16"],["e631bde7.36527","1b588bd.547a2f4"],["e8ec38d8.a3c568","89fd7801.01c23"]],"outputLabels":["AVG","MAX","MIN"]}]
I was running around for a few days trying to get this working.
I know it probably isn't that for which you are looking, but I hope it helps.
Are you looking for something like this:
const payload1 = msg.payload; // resolves to [1,2,3,4,5,6]
const payload2 = [2,4,6,8,10,12]; // example data
const lastValue = flow.get("lastValue") || [0, 0, 0, 0, 0, 0];
const sumArrays = payload1.map(function (num, idx) {
return num + payload2[idx];
});
const expression = [];
expression[0] = jsonata(`$average(${lastValue[0]}+${sumArrays[0]})`);
expression[1] = jsonata(`$average(${lastValue[1]}+${sumArrays[1]})`);
expression[2] = jsonata(`$average(${lastValue[2]}+${sumArrays[2]})`);
expression[3] = jsonata(`$average(${lastValue[3]}+${sumArrays[3]})`);
expression[4] = jsonata(`$average(${lastValue[4]}+${sumArrays[4]})`);
expression[5] = jsonata(`$average(${lastValue[5]}+${sumArrays[5]})`);
msg.payload = [];
msg.payload[0] = expression[0].evaluate();
msg.payload[1] = expression[1].evaluate();
msg.payload[2] = expression[2].evaluate();
msg.payload[3] = expression[3].evaluate();
msg.payload[4] = expression[4].evaluate();
msg.payload[5] = expression[5].evaluate();
flow.set("lastValue", sumArrays);
return msg;
you would need to require jsonata in the function node though
Thank you all you are being helpful
now my expected output is
if first array comes that should be stored added with second array
i.e
[undefined undefined 75 162.5 177 -960] +
undefined undefined 55 154.5 217 -985]
divided by 2 to get average
and when 3rd array comes above answer should be stored and added with this and again get divided by 2
im trying to get running average
and max values should return [ undefined undefined 75 196.5 257 995]
minimum values should return [undefined undefined 35 154.5 177 -985]
i want for an array msg.payload array vales eacjh eleemnt acting individually
pls correct my understanding
- the input comes in arrays of 6 elements example
{10,20,30,40,50}
{60,70,80,90,100}
answer here should be {(10+60)/2,(20+70)/2,(30+80)/2,(40+90)/2,(50+100)/2}
that is = {35,45,55,65,75}
next input {20,40,60,80,100}
so answer here should be {(35+20)/2,(45+40)/2,(55+60)/2,(65+80)/2,(75+100)/2}
that is = {27.5,42.5,57.5,72.5,87.5}
is this correct understanding ?
I think those should be arrays rather than objects
[10,20,30,40,50]
yes correct understanding
yeah those are arrays as you mentioned