Record High/Low Temps for the day

Hey All,
I'm building a solar hot water heater and I'm measuring the temperature of the output water. I want to know what the hottest and lowest temps are in a day and reset those numbers at midnight.

So far I've created 2 flow variables currentExitTemp and lastHighTemp. I'm trying to compare them in a function node but something isn't right. The debug shows up as undefined.

How can I make the comparison and record the daily highs and lows?
this is the function

let currentTemp = parseFloat(msg.payload[0]);
let lastHighTemp = parseFloat(msg.payload[1]);

if (currentTemp >= lastHighTemp) {
    msg.payload = msg.payload[0];
    flow.set("lastHighTemp", msg.payload[0]);
}

else {
     msg.payload = msg.payload[1];
}

return msg;

and the flow

[
    {
        "id": "1830970fbab5a9be",
        "type": "function",
        "z": "560c131af0c0df4d",
        "name": "function 19",
        "func": "let currentTemp = parseFloat(msg.payload[0]);\nlet lastHighTemp = parseFloat(msg.payload[1]);\n\nif (currentTemp >= lastHighTemp) {\n    msg.payload = msg.payload[0];\n    flow.set(\"lastHighTemp\", msg.payload[0]);\n}\n\nelse {\n     msg.payload = msg.payload[1];\n}\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 870,
        "y": 1020,
        "wires": [
            [
                "3162e44ddd15262f"
            ]
        ]
    },
    {
        "id": "e91a94d367947402",
        "type": "ui_text",
        "z": "560c131af0c0df4d",
        "group": "7a51f7a62e395bfe",
        "order": 10,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Exit Water High Temp",
        "format": "{{flow.lastHighTemp}}",
        "layout": "row-spread",
        "className": "",
        "style": false,
        "font": "",
        "fontSize": 16,
        "color": "#000000",
        "x": 1100,
        "y": 1060,
        "wires": []
    },
    {
        "id": "5af57c58ba42dfa9",
        "type": "change",
        "z": "560c131af0c0df4d",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "lastHighTemp",
                "pt": "flow",
                "to": "0",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 520,
        "y": 1100,
        "wires": [
            []
        ]
    },
    {
        "id": "8aad94337c8c8e47",
        "type": "inject",
        "z": "560c131af0c0df4d",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 280,
        "y": 1100,
        "wires": [
            [
                "5af57c58ba42dfa9"
            ]
        ]
    },
    {
        "id": "820bd3ee63e64e48",
        "type": "change",
        "z": "560c131af0c0df4d",
        "name": "Current/Last Temp Array",
        "rules": [
            {
                "t": "set",
                "p": "payload[0]",
                "pt": "msg",
                "to": "currentExitTemp",
                "tot": "flow",
                "dc": true
            },
            {
                "t": "set",
                "p": "payload[1]",
                "pt": "msg",
                "to": "lastHighTemp",
                "tot": "flow",
                "dc": true
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 530,
        "y": 1020,
        "wires": [
            [
                "1830970fbab5a9be"
            ]
        ]
    },
    {
        "id": "e4e0630254ab888e",
        "type": "inject",
        "z": "560c131af0c0df4d",
        "name": "lastHighTemp",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "10",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "lastHighTemp",
        "payloadType": "flow",
        "x": 860,
        "y": 1100,
        "wires": [
            [
                "e91a94d367947402"
            ]
        ]
    },
    {
        "id": "5b3b3df5856bd971",
        "type": "inject",
        "z": "560c131af0c0df4d",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "5",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{}",
        "payloadType": "msg",
        "x": 310,
        "y": 1020,
        "wires": [
            [
                "820bd3ee63e64e48"
            ]
        ]
    },
    {
        "id": "3162e44ddd15262f",
        "type": "debug",
        "z": "560c131af0c0df4d",
        "name": "debug 368",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1030,
        "y": 960,
        "wires": []
    },
    {
        "id": "74149027be269f42",
        "type": "change",
        "z": "560c131af0c0df4d",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "currentExitTemp",
                "pt": "flow",
                "to": "msg.payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 610,
        "y": 920,
        "wires": [
            []
        ]
    },
    {
        "id": "c1b0bc59ccef8d2b",
        "type": "mqtt in",
        "z": "560c131af0c0df4d",
        "name": "",
        "topic": "/waterHeater/temp2",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "e8de652f3f0d5685",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 190,
        "y": 860,
        "wires": [
            [
                "279fe863a247588f",
                "7efee34e59ad5c6a",
                "f64e2fcc96d980a8",
                "74149027be269f42"
            ]
        ]
    },
    {
        "id": "7a51f7a62e395bfe",
        "type": "ui_group",
        "name": "Greenhouse",
        "tab": "f3a8a67ff0904e39",
        "order": 5,
        "disp": true,
        "width": "6",
        "collapse": true,
        "className": ""
    },
    {
        "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": ""
    },
    {
        "id": "f3a8a67ff0904e39",
        "type": "ui_tab",
        "name": "Home",
        "icon": "home",
        "order": 1,
        "disabled": false,
        "hidden": false
    }
]

Add a debug node showing what is going into the function and show us what is there. Check that the payload contains an array with the expected values.

Your change node "set flow.currentExitTemp" [tries to] save the value of msg.msg.payload.
Does this really match the structure of your incoming message?
You seem to be doing a lot of unnecessary parseFloat() calls.
Do you not have control of the incoming message?

It is necessary to save the highest reading seen today in a context variable but (if it is not a string) you can compare it directly with msg.payload (or msg.msg.payload) as each message arrives.

Sorry but I can't get my mind round your function and the nodes leading to it.
You start by injecting msg.payload = msg.{}. No idea what that does.
Then you assign values to msg.payload[0] and msg.payload[1] even though it's not an array. Dunno what it is.
And in the function itself you have this

if (currentTemp >= lastHighTemp) {
    msg.payload = msg.payload[0];   // Does this work? Probably. I bet it destroys msg.payload[0] thouh
    flow.set("lastHighTemp", msg.payload[0]); // Can this possibly work?
}

Perhaps something like this would work?

EDIT: I shouldn't have included the bottom three nodes. That's my experiment with assigning msg.payload[0] etc.

[{"id":"d856ee7c4788bbab","type":"switch","z":"a3c3807e16ca19c8","name":"payload > flow.highest?","property":"payload","propertyType":"msg","rules":[{"t":"gt","v":"highest","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":450,"y":360,"wires":[["264c9990646ed1e0","7e18248c979a96d6"]]},{"id":"fba11f61df796b75","type":"inject","z":"a3c3807e16ca19c8","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"99","payloadType":"num","x":210,"y":500,"wires":[["6161b6649bca37db"]]},{"id":"e4a01443dd739821","type":"inject","z":"a3c3807e16ca19c8","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"94","payloadType":"num","x":210,"y":460,"wires":[["6161b6649bca37db"]]},{"id":"264c9990646ed1e0","type":"change","z":"a3c3807e16ca19c8","name":"set flow.highest","rules":[{"t":"set","p":"highest","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":400,"wires":[[]]},{"id":"7e18248c979a96d6","type":"debug","z":"a3c3807e16ca19c8","name":"New highest","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":690,"y":340,"wires":[]},{"id":"6161b6649bca37db","type":"switch","z":"a3c3807e16ca19c8","name":"flow.highest exists?","property":"highest","propertyType":"flow","rules":[{"t":"nnull"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":430,"y":480,"wires":[["d856ee7c4788bbab"],["264c9990646ed1e0","057b4436eeed5287"]]},{"id":"057b4436eeed5287","type":"debug","z":"a3c3807e16ca19c8","name":"Initial highest value","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":690,"y":520,"wires":[]},{"id":"049bacf206863946","type":"mqtt in","z":"a3c3807e16ca19c8","name":"","topic":"/waterHeater/temp2","qos":"2","datatype":"auto-detect","broker":"58adfa22bef137b0","nl":false,"rap":true,"rh":0,"inputs":0,"x":170,"y":420,"wires":[["6161b6649bca37db"]]},{"id":"52283d5136fad550","type":"change","z":"a3c3807e16ca19c8","name":"Delete flow.highest","rules":[{"t":"delete","p":"highest","pt":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":300,"wires":[[]]},{"id":"1d2f77778426744e","type":"inject","z":"a3c3807e16ca19c8","name":"Midnight","props":[{"p":"payload"}],"repeat":"","crontab":"00 00 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":200,"y":300,"wires":[["52283d5136fad550"]]},{"id":"28a9a84949374990","type":"comment","z":"a3c3807e16ca19c8","name":"No","info":"","x":470,"y":520,"wires":[]},{"id":"54a55a8bcf7efddb","type":"comment","z":"a3c3807e16ca19c8","name":"Yes","info":"","x":470,"y":440,"wires":[]},{"id":"3d43e7e435402050","type":"change","z":"a3c3807e16ca19c8","name":"","rules":[{"t":"set","p":"payload[0]","pt":"msg","to":"aaa","tot":"str"},{"t":"set","p":"payload[1]","pt":"msg","to":"bbb","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":620,"wires":[["c6d467f346e688f8"]]},{"id":"aa7ecf89a61ad987","type":"inject","z":"a3c3807e16ca19c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":220,"y":620,"wires":[["3d43e7e435402050"]]},{"id":"c6d467f346e688f8","type":"debug","z":"a3c3807e16ca19c8","name":"debug 395","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":650,"y":620,"wires":[]},{"id":"58adfa22bef137b0","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":""}]

Here is an alternate example of setting lowest and highest incoming temps using context and JSONata in a change node.

[{"id":"c1b0bc59ccef8d2b","type":"mqtt in","z":"b9860b4b9de8c8da","name":"","topic":"/waterHeater/temp2","qos":"2","datatype":"auto-detect","broker":"e8de652f3f0d5685","nl":false,"rap":true,"rh":0,"inputs":0,"x":170,"y":340,"wires":[["4d8c9fefe062f0a2"]]},{"id":"4d8c9fefe062f0a2","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"low_high","pt":"flow","to":"$append([$flowContext(\"low_high\")], $$.payload)^($)[[0,-1]]","tot":"jsonata"},{"t":"set","p":"payload","pt":"msg","to":"low_high[1]","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":400,"wires":[["ed39c45eeeb3ce2b","e91a94d367947402"]]},{"id":"3f85a1e69291ab6d","type":"inject","z":"b9860b4b9de8c8da","name":"incoming temps","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"$round($random()*20,1)","payloadType":"jsonata","x":160,"y":400,"wires":[["4d8c9fefe062f0a2"]]},{"id":"ed39c45eeeb3ce2b","type":"debug","z":"b9860b4b9de8c8da","name":"debug 331","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":630,"y":480,"wires":[]},{"id":"e91a94d367947402","type":"ui_text","z":"b9860b4b9de8c8da","group":"7a51f7a62e395bfe","order":10,"width":0,"height":0,"name":"","label":"Exit Water High Temp","format":"{{msg.payload}}","layout":"row-spread","className":"","style":false,"font":"","fontSize":16,"color":"#000000","x":660,"y":400,"wires":[]},{"id":"0a89d46653a45cfb","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"low_high","tot":"flow"},{"t":"set","p":"low_high","pt":"flow","to":"[]","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":600,"wires":[["ed39c45eeeb3ce2b"]]},{"id":"c4901ba5fcf64563","type":"inject","z":"b9860b4b9de8c8da","name":"retrieve low high","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"low_high","payloadType":"flow","x":140,"y":460,"wires":[["ed39c45eeeb3ce2b"]]},{"id":"b9c31dcf0a0adfb2","type":"inject","z":"b9860b4b9de8c8da","name":"retrieve low","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"low_high[0]","payloadType":"flow","x":130,"y":500,"wires":[["ed39c45eeeb3ce2b"]]},{"id":"c296b62d23d9f5bd","type":"inject","z":"b9860b4b9de8c8da","name":"retrieve high","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"low_high[1]","payloadType":"flow","x":130,"y":540,"wires":[["ed39c45eeeb3ce2b"]]},{"id":"0d1dff527553416c","type":"inject","z":"b9860b4b9de8c8da","name":"retrieve and reset","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":600,"wires":[["0a89d46653a45cfb"]]},{"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":""},{"id":"7a51f7a62e395bfe","type":"ui_group","name":"Greenhouse","tab":"f3a8a67ff0904e39","order":5,"disp":true,"width":"6","collapse":true,"className":""},{"id":"f3a8a67ff0904e39","type":"ui_tab","name":"Home","icon":"home","order":1,"disabled":false,"hidden":false}]

Thanks everyone! I love how the proposed solutions became simpler and simpler.

This is a great example of my years of hand coding can be a handicap in Node-Red. I'm continually blown away by the elegance of Node-Red.

The only thing I love more than Node-Red is the Node-Red community. Thanks again!

Like you I have a backround in coding, so when faced with a problem I automatically write function code to tackle it.
For instance I don't know if there is a node to convert a number in string format to a floating point number. No worries, there is a Javascript function for it.
Therefore my own flows are full of functions.
Answering questions here I try to use the available non-function palette before writing javascript. It's good for my understanding of Node-red :grinning: