Trying to chart high/low temp

I’m real new to Node-Red. People here have been so kind to help me out, so I thought I’d try to help others. I didn’t see where someone showed a reset capability. Here is the solution I use that resets every day.

[
    {
        "id": "b079c63558100c2d",
        "type": "mqtt in",
        "z": "660480f6a68e2c2d",
        "name": "Temperature",
        "topic": "Outside/temperature",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "b8758158381423f0",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 110,
        "y": 100,
        "wires": [
            [
                "1cab0dd86162fd95"
            ]
        ]
    },
    {
        "id": "1cab0dd86162fd95",
        "type": "function",
        "z": "660480f6a68e2c2d",
        "name": "function 1",
        "func": "let old = context.get('Day');\nlet day = new Date().getDay();\nif (old != day)\n{\n    context.set('Day', day);\n    msg.min = 10E6;\n    msg.max = -10E6;\n}\nelse\n{\n    msg.min = context.get('Min');\n    msg.max = context.get('Max');\n}\n\nif (msg.payload < msg.min) \n{\n    msg.min = msg.payload;\n    context.set('Min', msg.min);\n}\nif (msg.payload > msg.max) \n{\n    msg.max = msg.payload;\n    context.set('Max', msg.max);\n}\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "if (context.get(\"Day\") === undefined)\n    context.set(\"Day\", -1);\nif (context.get(\"Min\") === undefined)\n    context.set(\"Min\", 10E6);\nif (context.get(\"Max\") === undefined)\n    context.set(\"Max\", -10E6);",
        "finalize": "",
        "libs": [],
        "x": 280,
        "y": 100,
        "wires": [
            [
                "f03eada3305694ef",
                "3155dd6e832f91d2"
            ]
        ]
    },
    {
        "id": "f03eada3305694ef",
        "type": "ui_text",
        "z": "660480f6a68e2c2d",
        "group": "e8d1ae835631bb1a",
        "order": 0,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Today's Min",
        "format": "{{msg.min}}",
        "layout": "row-spread",
        "className": "",
        "style": false,
        "font": "",
        "fontSize": 16,
        "color": "#000000",
        "x": 470,
        "y": 60,
        "wires": []
    },
    {
        "id": "3155dd6e832f91d2",
        "type": "ui_text",
        "z": "660480f6a68e2c2d",
        "group": "e8d1ae835631bb1a",
        "order": 1,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Today's Max",
        "format": "{{msg.max}}",
        "layout": "row-spread",
        "className": "",
        "style": false,
        "font": "",
        "fontSize": 16,
        "color": "#000000",
        "x": 470,
        "y": 140,
        "wires": []
    },
    {
        "id": "b8758158381423f0",
        "type": "mqtt-broker",
        "name": "Local Broker",
        "broker": "localhost",
        "port": 1883,
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": 4,
        "keepalive": 60,
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthRetain": "false",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closeRetain": "false",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willRetain": "false",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    },
    {
        "id": "e8d1ae835631bb1a",
        "type": "ui_group",
        "name": "Group 1",
        "tab": "b9feac347f4789ce",
        "order": 1,
        "disp": true,
        "width": 6
    },
    {
        "id": "b9feac347f4789ce",
        "type": "ui_tab",
        "name": "Tab 12",
        "icon": "dashboard",
        "order": 12
    }
]

That was a nice trick you did for the new day detection.

:+1:

Sorry I didn't expand on that part.

Glad it is working.

hi i added bar-chart-data-2 min for one and max for the other after the function node , seems to be working not sure how, I haven't the foggiest

[
    {
        "id": "b3a8374aa5da37ac",
        "type": "tab",
        "label": "Flow 1",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "8449a5141f0fa835",
        "type": "function",
        "z": "b3a8374aa5da37ac",
        "name": "function 1",
        "func": "if (msg.topic == \"NEWDAY\") {\n    // You need to reset values\n    //  you need to add stuff here.\n    context.set('previous_max', 0)\n    context.set('previous_min', 100)\n    return   // exit.\n}\n\nlet previous_max = context.get('previous_max') || 0\nlet previous_min = context.get('previous_min') || 100\n\n//  get the temperature.\nconst temperature = msg.payload\n\n    if(temperature > previous_max)\n{\n    //\n    context.set('previous_max', temperature)\n    msg.topic = 'maximum'\n    return msg\n}\n\nif (temperature < previous_min) {\n    //\n    context.set('previous_min', temperature)\n    msg.topic = 'minimum'\n    return msg\n}",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 280,
        "y": 160,
        "wires": [
            [
                "6769276dd1369687",
                "96f552e00a05af0a",
                "e87bd04eade7bcaa"
            ]
        ]
    },
    {
        "id": "03a0ef28daf000f2",
        "type": "mqtt in",
        "z": "b3a8374aa5da37ac",
        "name": "outside",
        "topic": "zone0/text",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "dc0340c9643bd396",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 130,
        "y": 160,
        "wires": [
            [
                "8449a5141f0fa835"
            ]
        ]
    },
    {
        "id": "6769276dd1369687",
        "type": "bar-chart-data2",
        "z": "b3a8374aa5da37ac",
        "name": "bar-chart-data2",
        "x_interval": "days",
        "x_size": 24,
        "unit": "",
        "precision": 2,
        "is_meter_reading": "False",
        "agg_by": "min",
        "x": 410,
        "y": 280,
        "wires": [
            [
                "42d05518f43a7dec"
            ]
        ]
    },
    {
        "id": "42d05518f43a7dec",
        "type": "ui_chart",
        "z": "b3a8374aa5da37ac",
        "name": "",
        "group": "b5f7f90a2f77ea3d",
        "order": 5,
        "width": "18",
        "height": "4",
        "label": "newest chart",
        "chartType": "bar",
        "legend": "false",
        "xformat": "HH:mm:ss",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "",
        "ymax": "",
        "removeOlder": 1,
        "removeOlderPoints": "",
        "removeOlderUnit": "3600",
        "cutout": 0,
        "useOneColor": false,
        "useUTC": false,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "outputs": 1,
        "useDifferentColor": false,
        "className": "",
        "x": 610,
        "y": 280,
        "wires": [
            []
        ]
    },
    {
        "id": "96f552e00a05af0a",
        "type": "bar-chart-data2",
        "z": "b3a8374aa5da37ac",
        "name": "bar-chart-data2",
        "x_interval": "days",
        "x_size": 24,
        "unit": "",
        "precision": 2,
        "is_meter_reading": "False",
        "agg_by": "max",
        "x": 400,
        "y": 340,
        "wires": [
            [
                "42d05518f43a7dec"
            ]
        ]
    },
    {
        "id": "12efdbbefe6130e1",
        "type": "inject",
        "z": "b3a8374aa5da37ac",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "0",
        "payloadType": "str",
        "x": 480,
        "y": 420,
        "wires": [
            [
                "42d05518f43a7dec"
            ]
        ]
    },
    {
        "id": "e87bd04eade7bcaa",
        "type": "debug",
        "z": "b3a8374aa5da37ac",
        "name": "debug 4",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 450,
        "y": 160,
        "wires": []
    },
    {
        "id": "dc0340c9643bd396",
        "type": "mqtt-broker",
        "name": "",
        "broker": "192.168.0.107",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    },
    {
        "id": "b5f7f90a2f77ea3d",
        "type": "ui_group",
        "name": "Group 1",
        "tab": "eaa84631f407bcd4",
        "order": 1,
        "disp": true,
        "width": "18",
        "collapse": false,
        "className": ""
    },
    {
        "id": "eaa84631f407bcd4",
        "type": "ui_tab",
        "name": "daily temperatures",
        "icon": "dashboard",
        "order": 5,
        "disabled": false,
        "hidden": false
    },
    {
        "id": "5881260ad5e9384c",
        "type": "global-config",
        "env": [],
        "modules": {
            "node-red-contrib-dashboard-bar-chart-data2": "0.9.101",
            "node-red-dashboard": "3.6.6"
        }
    }
]
![image|690x152](upload://agwPg7e3KHGx4gs8XX1WnKX0BX4.png)

As each message for max and min have different topics when they get to the chart node they are shown as different sets of data/lines/(what ever)

Yes, injecting a 0 will wipe the chart.
I also believe if you send an empty payload. msg.payload = {} will also work from what I remember.

1 Like

thanks
martin

(Could you post the code in the function node?)
I'll show you a trick of which I've just thought to maybe help you.

if (msg.topic == "NEWDAY") {
    // You need to reset values
    //  you need to add stuff here.
    context.set('previous_max', 0)
    context.set('previous_min', 100)
    return   // exit.
}

let previous_max = context.get('previous_max') || 0
let previous_min = context.get('previous_min') || 100

//  get the temperature.
const temperature = msg.payload

    if(temperature > previous_max)
{
    //
    context.set('previous_max', temperature)
    msg.topic = 'maximum'
    return msg
}

if (temperature < previous_min) {
    //
    context.set('previous_min', temperature)
    msg.topic = 'minimum'
    return msg
}

I meant the function node you are using. That looks like the code I posted.
:person_shrugging:

Don't worry. Dug it up.
Hang on while I look at it.

This code:

let old = context.get('Day');
let day = new Date().getDay();
if (old != day)
{
    context.set('Day', day);
    msg.min = 10E6;
    msg.max = -10E6;
}
else
{
    msg.min = context.get('Min');
    msg.max = context.get('Max');
}

if (msg.payload < msg.min) 
{
    msg.min = msg.payload;
    context.set('Min', msg.min);
}
if (msg.payload > msg.max) 
{
    msg.max = msg.payload;
    context.set('Max', msg.max);
}
return msg;

As I see it, it isn't the best.
(Not a problem, but a few things I'm seeing.)

1 - ok, you got around the new day bit but then what you do is a problem.
2 - when the code detects it is a new day, it needs to save the reset values to context. Not really the msg.min and msg.max values.

Each new day the chart/values will be thrown to their extremes.
I'm not sure that is what you want.
Rather to reset the stuff shown/displayed.

if (old != day)
{
    context.set('Day', day);
    msg.min = 10E6;
    msg.max = -10E6;
}

Works but maybe this would be better.
(I haven't tested it.)

if (old != day)
{
    context.set('Day', day);
    context.set('Min',10E6)
    context.set('Max',-10E6)
    msg.min = {}
    msg.max = {}
    return msg
}

This way, the context values will be set to their extremes - ready for the new day's data.
Also a message with msg.max and msg.min will be sent with {} as the content.
(You could change that to 0 as per you inject node to clear things. I just think this way is nicer.)

For the sake of making it easier for testing, try this code:

let old = context.get('Day');
let day = new Date().getDay();

//----
//  test block here
if (msg.payload == 'TEST')
{
    context.set('Day', day);
    context.set('Min',10E6)
    context.set('Max',-10E6)
    msg.min = []  // edited
    msg.max = []  //edited (Sorry)
    return msg
}
//  end test block

if (old != day)
{
    context.set('Day', day);
    context.set('Min',10E6)
    context.set('Max',-10E6)
    msg.min = []    // edited
    msg.max = []   // edited
    return msg
}else
{
    msg.min = context.get('Min');
    msg.max = context.get('Max');
}

if (msg.payload < msg.min) 
{
    msg.min = msg.payload;
    context.set('Min', msg.min);
}
if (msg.payload > msg.max) 
{
    msg.max = msg.payload;
    context.set('Max', msg.max);
}
return msg;

Add am inject node that has the payload set to TEST and connect it to the input of the function node.

Then if/when you press it, it will WIPE things as if a new day.

See if that way is better.

If you like it, use it.

Delete the injectnode and the small bit of extra code.

1 Like

To clear the chart send an empty array []

2 Likes

Thanks.

I sometimes get those two mixed up.

using the inject node is not working for some reason,

You need to put TEST in the payload field.

1 Like

thanks I'll see how it goes
martin

Is that code any better?

Can you see/understand what I did and why?

hi i can see what you've not sure i understand it ,
i only seem to be getting one reading (low) on a few i think ,

however i have found a way to get what i need using 2 charts .

[
    {
        "id": "d3637ed3c66aa0d7",
        "type": "tab",
        "label": "daily temps",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "558a976d1540e55c",
        "type": "group",
        "z": "d3637ed3c66aa0d7",
        "style": {
            "stroke": "#999999",
            "stroke-opacity": "1",
            "fill": "none",
            "fill-opacity": "1",
            "label": true,
            "label-position": "nw",
            "color": "#a4a4a4"
        },
        "nodes": [
            "e1cc8e5dcfa599e4",
            "8dc4a744a869b740",
            "6a492259f74bde19",
            "9e7148d9a5fcbfae",
            "b6ed25afa97b9f26",
            "5ae30d57abb32fac",
            "5269df838f656cd0",
            "6eaf9754b1bf4d38"
        ],
        "x": 14,
        "y": 159,
        "w": 712,
        "h": 222
    },
    {
        "id": "e1cc8e5dcfa599e4",
        "type": "mqtt in",
        "z": "d3637ed3c66aa0d7",
        "g": "558a976d1540e55c",
        "name": "outside",
        "topic": "zone0/text",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "dc0340c9643bd396",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 90,
        "y": 240,
        "wires": [
            [
                "5269df838f656cd0",
                "5ae30d57abb32fac",
                "6eaf9754b1bf4d38"
            ]
        ]
    },
    {
        "id": "8dc4a744a869b740",
        "type": "bar-chart-data2",
        "z": "d3637ed3c66aa0d7",
        "g": "558a976d1540e55c",
        "name": "bar-chart-data2",
        "x_interval": "days",
        "x_size": 24,
        "unit": "c",
        "precision": 2,
        "is_meter_reading": "False",
        "agg_by": "min",
        "x": 420,
        "y": 200,
        "wires": [
            [
                "6a492259f74bde19"
            ]
        ]
    },
    {
        "id": "6a492259f74bde19",
        "type": "ui_chart",
        "z": "d3637ed3c66aa0d7",
        "g": "558a976d1540e55c",
        "name": "",
        "group": "b5f7f90a2f77ea3d",
        "order": 2,
        "width": 18,
        "height": 5,
        "label": "lowest outside",
        "chartType": "bar",
        "legend": "true",
        "xformat": "HH:mm:ss",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "",
        "ymax": "",
        "removeOlder": 1,
        "removeOlderPoints": "",
        "removeOlderUnit": "3600",
        "cutout": 0,
        "useOneColor": false,
        "useUTC": false,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "outputs": 1,
        "useDifferentColor": false,
        "className": "",
        "x": 620,
        "y": 200,
        "wires": [
            []
        ]
    },
    {
        "id": "9e7148d9a5fcbfae",
        "type": "bar-chart-data2",
        "z": "d3637ed3c66aa0d7",
        "g": "558a976d1540e55c",
        "name": "bar-chart-data2",
        "x_interval": "days",
        "x_size": 24,
        "unit": "c",
        "precision": 2,
        "is_meter_reading": "False",
        "agg_by": "max",
        "x": 420,
        "y": 280,
        "wires": [
            [
                "b6ed25afa97b9f26"
            ]
        ]
    },
    {
        "id": "b6ed25afa97b9f26",
        "type": "ui_chart",
        "z": "d3637ed3c66aa0d7",
        "g": "558a976d1540e55c",
        "name": "",
        "group": "b5f7f90a2f77ea3d",
        "order": 1,
        "width": 18,
        "height": 5,
        "label": "highest outside",
        "chartType": "bar",
        "legend": "true",
        "xformat": "HH:mm:ss",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "",
        "ymax": "",
        "removeOlder": 1,
        "removeOlderPoints": "",
        "removeOlderUnit": "3600",
        "cutout": 0,
        "useOneColor": false,
        "useUTC": false,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "outputs": 1,
        "useDifferentColor": false,
        "className": "",
        "x": 600,
        "y": 280,
        "wires": [
            []
        ]
    },
    {
        "id": "5ae30d57abb32fac",
        "type": "smooth",
        "z": "d3637ed3c66aa0d7",
        "g": "558a976d1540e55c",
        "name": "lowest",
        "property": "payload",
        "action": "min",
        "count": "10",
        "round": "",
        "mult": "single",
        "reduce": false,
        "x": 270,
        "y": 200,
        "wires": [
            [
                "8dc4a744a869b740"
            ]
        ]
    },
    {
        "id": "5269df838f656cd0",
        "type": "smooth",
        "z": "d3637ed3c66aa0d7",
        "g": "558a976d1540e55c",
        "name": "highest",
        "property": "payload",
        "action": "max",
        "count": "10",
        "round": "",
        "mult": "single",
        "reduce": false,
        "x": 260,
        "y": 280,
        "wires": [
            [
                "9e7148d9a5fcbfae"
            ]
        ]
    },
    {
        "id": "6eaf9754b1bf4d38",
        "type": "show-value",
        "z": "d3637ed3c66aa0d7",
        "g": "558a976d1540e55c",
        "name": "",
        "path": "",
        "x": 190,
        "y": 340,
        "wires": [
            []
        ]
    },
    {
        "id": "dc0340c9643bd396",
        "type": "mqtt-broker",
        "name": "",
        "broker": "192.168.0.107",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    },
    {
        "id": "b5f7f90a2f77ea3d",
        "type": "ui_group",
        "name": "Group 1",
        "tab": "eaa84631f407bcd4",
        "order": 1,
        "disp": true,
        "width": "18",
        "collapse": false,
        "className": ""
    },
    {
        "id": "eaa84631f407bcd4",
        "type": "ui_tab",
        "name": "daily temperatures",
        "icon": "dashboard",
        "order": 5,
        "disabled": false,
        "hidden": false
    },
    {
        "id": "0d746eb07550f0f5",
        "type": "global-config",
        "env": [],
        "modules": {
            "node-red-contrib-dashboard-bar-chart-data2": "0.9.101",
            "node-red-dashboard": "3.6.6",
            "node-red-node-smooth": "0.1.2",
            "node-red-show-value": "1.0.4"
        }
    }
]


really appreciate all the help thanks
martin

No problems.

I don't mind helping. Though from what I am reading it isn't really helping you.

Mind posting that function node's code again?
I know I wrote it, but it would be better you post it to me as I am not sure where it is and I have LOT of tabs. Find it may not be as easy as you think.

(Sorry. Scrolled up and found it.)
Silly me.

Hang on while I test things.

UPDATE:

Sorry, just asking:
Excluding the mqtt in, and chart nodes, please export the flow you have.

Rather than the mqtt in node, add a few inject nodes with values like:
1, 10, 20, 30, 40, 50
Replacing the chart nodes (or template nodes) add debug nodes that display the same data as used by the chart/template nodes.

Note:
the OUTPUT from the function node is not SIMPLE.
Rather than the payload you have to use msg.max and msg.min for the maximum and minimum values.
Sorry.
The payload is the value.
The msg.max and msg.min are the stored values included in the message just for the fun of it.
Which is kind of handy anyway.

Looking at the two charts/graphs/what ever.....
Yeah, you are getting values for 12 of Jan, 12 Feb, 12 Mar 12 April.....
Oh, sorry.
1, 2, 3, 4 December.
5 December isn't included but I'm not sure it has become 5 December when you posted it, and there is/was any data received.

Sorry.
I did a bit of tweaking but at this point it is not mission critical or really changing the output anyway.

Later on I'll post the newer one once we get out heads around what's going on.

New bit of code anyway.

I am still not sure I am completely understanding you need.
(My bad.)

This maybe is more what you want.
Dunno.

let old = context.get('Day')
let day = new Date().getDay()

//----
//  test block here
if (msg.payload == 'TEST')
{
    node.warn("Resetting for new day")
    context.set('Day', day)
    context.set('Min',10E6)
    context.set('Max',-10E6)
    msg.min = []  // edited
    msg.max = []  //edited (Sorry)
    return
}
//  end test block

if (old != day)
{
    node.warn("Resetting for new day")
    context.set('Day', day)
    context.set('Min',10E6)
    context.set('Max',-10E6)
    msg.min = []    // edited
    msg.max = []   // edited
    return  //  This may actually not be needed when the day changes.
               //   We'll work on this later.
}else
{
    msg.min = context.get('Min')
    msg.max = context.get('Max')
}

if (msg.payload < msg.min) 
{
    node.warn("new min")
    msg.min = msg.payload
    context.set('Min', msg.min)
    return msg
}
if (msg.payload > msg.max) 
{
    node.warn("new max")
    msg.max = msg.payload
    context.set('Max', msg.max)
    return msg
}

It has a quick that it needs 2 messages to establish the max and min values.
But again: you are losing ONE (well ok: TWO) messages to establish things.
Actually THREE if you are not sending a newday message. (TEST)

UPDATE:

See the comment on the return line. It may be deleted if you are getting the readings as this is/would/should be a valid new value. As is, I dropped the message, but in retrospect, it may be ok to delete the return line.

thanks i]ll give it a try
martin