Calculate Average from Global Variables

Hey All,
I'm trying to calculate the average temp from 2 temperature sensors which are stored in global variables. Here's my flow, how can I set it up to calculate the average?
Thanks!

[
    {
        "id": "5e73126742dd6de3",
        "type": "inject",
        "z": "bd5d8f0934d852df",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 220,
        "y": 720,
        "wires": [
            [
                "92eef5368866f343",
                "1e02e4439dfe79f2"
            ]
        ]
    },
    {
        "id": "92eef5368866f343",
        "type": "change",
        "z": "bd5d8f0934d852df",
        "name": "Hanging Lamp Temp",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "currentTempHangingLamp",
                "tot": "global"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 500,
        "y": 680,
        "wires": [
            [
                "5b2168d7ab676831"
            ]
        ]
    },
    {
        "id": "1e02e4439dfe79f2",
        "type": "change",
        "z": "bd5d8f0934d852df",
        "name": "Bookshelf Temp",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "currentTempBookshelfTemp",
                "tot": "global",
                "dc": true
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 400,
        "y": 740,
        "wires": [
            [
                "5b2168d7ab676831"
            ]
        ]
    },
    {
        "id": "ba4501feab4a54cd",
        "type": "function",
        "z": "bd5d8f0934d852df",
        "name": "calculate average",
        "func": "var lamp = msg.payload[1]\nvar bookshelf = msg.payload[2]\n\nmsg.payload = ((lamp + bookshelf)/2);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 910,
        "y": 720,
        "wires": [
            []
        ]
    },
    {
        "id": "8462518c70518a74",
        "type": "debug",
        "z": "bd5d8f0934d852df",
        "name": "debug 351",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1070,
        "y": 640,
        "wires": []
    },
    {
        "id": "5b2168d7ab676831",
        "type": "join",
        "z": "bd5d8f0934d852df",
        "name": "",
        "mode": "custom",
        "build": "array",
        "property": "payload",
        "propertyType": "msg",
        "key": "payload",
        "joiner": "\\n",
        "joinerType": "str",
        "accumulate": false,
        "timeout": "",
        "count": "2",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "",
        "reduceFixup": "",
        "x": 710,
        "y": 720,
        "wires": [
            [
                "ba4501feab4a54cd",
                "8462518c70518a74"
            ]
        ]
    }
]

If you are using a function node, you don't need the two change nodes of the join node. Just get the global variables in the function node.

let lamp = global.get('currentTempHangingLamp');
let bookshelf = global.get('currentTempBookshelfTemp');

msg.payload = ((lamp + bookshelf)/2);
return msg;
1 Like

Arrays atart at 0 not 1.
You do not need a join.
Are the stored globals numbers?
If not you would need to parse them.
here is an example

[{"id":"5e73126742dd6de3","type":"inject","z":"b9860b4b9de8c8da","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[]","payloadType":"json","x":330,"y":120,"wires":[["1e02e4439dfe79f2"]]},{"id":"1e02e4439dfe79f2","type":"change","z":"b9860b4b9de8c8da","name":"global array","rules":[{"t":"set","p":"payload[0]","pt":"msg","to":"currentTempBookshelfTemp","tot":"global","dc":true},{"t":"set","p":"payload[1]","pt":"msg","to":"currentTempHangingLamp","tot":"global","dc":true}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":200,"wires":[["ba4501feab4a54cd","8462518c70518a74"]]},{"id":"ba4501feab4a54cd","type":"function","z":"b9860b4b9de8c8da","name":"calculate average","func":"let lamp = parseFloat(msg.payload[0]);\nlet bookshelf = parseFloat(msg.payload[1]);\n\nmsg.payload = ((lamp + bookshelf)/2);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":650,"y":260,"wires":[["8462518c70518a74"]]},{"id":"8462518c70518a74","type":"debug","z":"b9860b4b9de8c8da","name":"debug 351","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":870,"y":180,"wires":[]}]

Or all in a change node

[{"id":"5e73126742dd6de3","type":"inject","z":"b9860b4b9de8c8da","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[]","payloadType":"json","x":330,"y":140,"wires":[["1e02e4439dfe79f2"]]},{"id":"1e02e4439dfe79f2","type":"change","z":"b9860b4b9de8c8da","name":"global array","rules":[{"t":"set","p":"payload[0]","pt":"msg","to":"currentTempBookshelfTemp","tot":"global","dc":true},{"t":"set","p":"payload[1]","pt":"msg","to":"currentTempHangingLamp","tot":"global","dc":true},{"t":"set","p":"payload","pt":"msg","to":"$average($$.payload.$number($))","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":220,"wires":[["8462518c70518a74"]]},{"id":"8462518c70518a74","type":"debug","z":"b9860b4b9de8c8da","name":"debug 351","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":870,"y":200,"wires":[]}]

[edit]
If you stored the globals in on object rather than separate variables you could do it even easier.
save as
global. current.TempHangingLamp
global. current.TempBokkshelfLamp
Then in a change node
set msg. payload
to :J $average($globalContext("current").*)
This way if you add more temps to current object, you would not have to edit any code to still get an average.

Took me a minute to set it up but this works! Thank you. Here it is for future readers of this thread.

[
    {
        "id": "7f2c0335c9b36ed4",
        "type": "mqtt in",
        "z": "f01c1351c0c2d98d",
        "name": "",
        "topic": "/apartment/bookshelf/temp",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "e8de652f3f0d5685",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 390,
        "y": 160,
        "wires": [
            [
                "523daf1b5c53cad6",
                "6b741b4f0f6d7037",
                "c8c17943408c22fa",
                "0b8499eda245d82d",
                "0ea4d60aafbfbf66"
            ]
        ]
    },
    {
        "id": "c8c17943408c22fa",
        "type": "change",
        "z": "f01c1351c0c2d98d",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "current.tempBookshelf",
                "pt": "global",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 760,
        "y": 60,
        "wires": [
            []
        ]
    },
    {
        "id": "e8de652f3f0d5685",
        "type": "mqtt-broker",
        "name": "",
        "broker": "192.168.1.154",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    }
]

and the second variable

[
    {
        "id": "3dbb97be82245dad",
        "type": "mqtt in",
        "z": "7955d6419dd0e9b3",
        "name": "",
        "topic": "/apartment/ceiling/temp",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "68dfc99953924658",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 280,
        "y": 300,
        "wires": [
            [
                "e27cce5922bd1a7f",
                "6dec5b5f133b1d1f",
                "b16a0e9fcca20514"
            ]
        ]
    },
    {
        "id": "6dec5b5f133b1d1f",
        "type": "change",
        "z": "7955d6419dd0e9b3",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "current.tempApartmentCeiling",
                "pt": "global",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 640,
        "y": 260,
        "wires": [
            []
        ]
    },
    {
        "id": "68dfc99953924658",
        "type": "mqtt-broker",
        "name": "",
        "broker": "192.168.1.217",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    }
]

Followed by bringing them together and calculating the average

[
    {
        "id": "5e73126742dd6de3",
        "type": "inject",
        "z": "bd5d8f0934d852df",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 220,
        "y": 680,
        "wires": [
            [
                "92eef5368866f343"
            ]
        ]
    },
    {
        "id": "92eef5368866f343",
        "type": "change",
        "z": "bd5d8f0934d852df",
        "name": "Calculate apartment temp average",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "$average($globalContext(\"current\").*)",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 460,
        "y": 680,
        "wires": [
            [
                "8462518c70518a74"
            ]
        ]
    },
    {
        "id": "8462518c70518a74",
        "type": "debug",
        "z": "bd5d8f0934d852df",
        "name": "debug 351",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 790,
        "y": 680,
        "wires": []
    }
]

You could also break the object in to further sections for easily adding more info later, i.e store temp and say humidity or other readings.
global.current.temp.Hanginglamp
or
global.current.humidity.Hanginglamp

you could then call
$globalContext("current").temp.*
to retrieve all temps.

Ah! I'll use this for my next variable which is humidity.

Thx!

ACK! this was working... I added another sensor to the mix and now I'm getting the following error

"Invalid JSONata expression: Argument 1 of function "average" must be an array of "numbers""

I deleted the new stuff and I'm still getting the error... Anyway here are my current nodes. I'm having trouble make sense of it.

[
    {
        "id": "df543ac168cbb6e1",
        "type": "change",
        "z": "bd5d8f0934d852df",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "current.tempBookshelf",
                "pt": "global",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 480,
        "y": 680,
        "wires": [
            []
        ]
    },
    {
        "id": "ea09359d10b0fc36",
        "type": "change",
        "z": "bd5d8f0934d852df",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "current.tempHangingLamp",
                "pt": "global",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 490,
        "y": 720,
        "wires": [
            []
        ]
    },
    {
        "id": "17de199bf8f942aa",
        "type": "change",
        "z": "bd5d8f0934d852df",
        "name": "Calculate apartment temp average",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "$average($globalContext(\"current\").*)",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 480,
        "y": 760,
        "wires": [
            [
                "ef931523cdca7dae"
            ]
        ]
    }
]

Edit I added a JSON node to create an object. When I look at the result in the terminal it shows as a number. Still the same error

What does the global current look like when you add the new temp?

I kept messing around and wound up using the solution from zenofmud.

Thanks E1cid!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.