Using a slider value to set the segment position on a gauge

I have a gauge showing values 0-100. The gauge has two segments: normal (0-value & "color": "#00FF00") and excess (value-100 & "color": "#FF0000"). I have a slider that is also 0-100 and I want to use its output as the value.

Deep in the JSON for the gauge is the specification for the segments. Is there a way to change the value of the "from": attribute to be the slider value (cast to string)?

Would the gauge reflect the change dynamically?

[
    {
        "id": "75b5ad00fd309030",
        "type": "ui-gauge",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "Humidity",
        "group": "fc3876ca5fad0f6a",
        "order": 1,
        "value": "payload",
        "valueType": "msg",
        "width": 3,
        "height": 3,
        "gtype": "gauge-half",
        "gstyle": "needle",
        "title": "Humidity",
        "alwaysShowTitle": false,
        "floatingTitlePosition": "top-left",
        "units": "%",
        "icon": "",
        "prefix": "",
        "suffix": "",
        "segments": [
            {
                "from": "20",
                "color": "#00FF00",
                "text": "",
                "textType": "label"
            },
            {
                "from": "100",
                "color": "#FF0000",
                "text": "",
                "textType": "label"
            }
        ],
        "min": "20",
        "max": "100",
        "sizeThickness": 16,
        "sizeGap": 4,
        "sizeKeyThickness": 8,
        "styleRounded": true,
        "styleGlow": false,
        "className": "",
        "x": 920,
        "y": 260,
        "wires": [
            []
        ]
    },
    {
        "id": "fc3876ca5fad0f6a",
        "type": "ui-group",
        "name": "Humidity",
        "page": "cda4aeea5584ffaa",
        "width": 6,
        "height": 1,
        "order": 1,
        "showTitle": true,
        "className": "",
        "visible": "true",
        "disabled": "false",
        "groupType": "default"
    },
    {
        "id": "cda4aeea5584ffaa",
        "type": "ui-page",
        "name": "Bathroom",
        "ui": "5158dba2ce9db01c",
        "path": "/page1",
        "icon": "home",
        "layout": "grid",
        "theme": "f149993e218cdb7d",
        "breakpoints": [
            {
                "name": "Default",
                "px": "0",
                "cols": "3"
            },
            {
                "name": "Tablet",
                "px": "576",
                "cols": "6"
            },
            {
                "name": "Small Desktop",
                "px": "768",
                "cols": "9"
            },
            {
                "name": "Desktop",
                "px": "1024",
                "cols": "12"
            }
        ],
        "order": 2,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "5158dba2ce9db01c",
        "type": "ui-base",
        "name": "Archery",
        "path": "/dashboard",
        "appIcon": "",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-notification",
            "ui-control"
        ],
        "showPathInSidebar": false,
        "headerContent": "page",
        "navigationStyle": "default",
        "titleBarStyle": "default",
        "showReconnectNotification": true,
        "notificationDisplayTime": 1,
        "showDisconnectNotification": true,
        "allowInstall": true
    },
    {
        "id": "f149993e218cdb7d",
        "type": "ui-theme",
        "name": "Default Theme",
        "colors": {
            "surface": "#ffffff",
            "primary": "#0094CE",
            "bgPage": "#eeeeee",
            "groupBg": "#ffffff",
            "groupOutline": "#cccccc"
        },
        "sizes": {
            "density": "default",
            "pagePadding": "12px",
            "groupGap": "12px",
            "groupBorderRadius": "4px",
            "widgetGap": "12px"
        }
    },
    {
        "id": "617d69425c3dc3e7",
        "type": "global-config",
        "env": [],
        "modules": {
            "@flowfuse/node-red-dashboard": "1.27.1"
        }
    }
]

If you look at the help text for the gauge you will see a section Dynamic Properties which reads:

Dynamic Properties (Inputs)

Any of the following can be appended to a msg.ui_update in order to override or set properties on this node at runtime.

label

Update the label rendered above the Gauge

segments

Change the options available in the dropdown at runtime

  • Array<{color: String, from: Number}>

Unfortunately that is rubbish, the text "Change the options available in the dropdown at runtime" was likely copied from the dropdown node help text. It should say that you can dynamically update the segment colours and changeover points by sending the gauge a message where msg.ui_update.segments contains array of objects, where each object contains a colour and a value for the start of the segment. I think that is what you are asking about in your question.

I have submitted an issue to get the help text fixed Docs: Error in help text for ui-gauge · Issue #1856 · FlowFuse/node-red-dashboard · GitHub

That looks like the perfect answer (notwithstanding the help content error) but I'm struggling with my implementation - how to construct the JSON to pass, perhaps? What do you make of the code. What have I got wrong?
Flow:

[
    {
        "id": "7c642c5673f59101",
        "type": "inject",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "OnStart",
        "props": [
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "30",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "x": 340,
        "y": 200,
        "wires": [
            [
                "86f4f6c57298e008"
            ]
        ]
    },
    {
        "id": "86f4f6c57298e008",
        "type": "function",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "TraceThresholdVal",
        "func": "var humidityThresholdVal = global.get('humidityThreshold');\n\nvar segStr = 'color:#ff0000,from:' + String(humidityThresholdVal); //build the object string, including the threshold variable\nvar segObj = {segStr}; // use the string to create a JS Object\nvar seg = JSON.stringify(segObj); // Convert the JS Object to JSON\nmsg.ui_update.segments = seg; //message passes the constructed JSON for the segment\n\n\nvar msg2 = \"\"; //initialise a new message\nmsg2.payload = humidityThresholdVal; //message passes the value for the graph\nmsg2.topic = 'bathroom/humidityThreshold' //message passes the topic for a different series\nreturn [msg, msg2];\n",
        "outputs": 2,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 530,
        "y": 200,
        "wires": [
            [
                "80169acbf2886566",
                "75b5ad00fd309030"
            ],
            [
                "81209091e69e650e",
                "704f9f4ddd08f932"
            ]
        ]
    },
    {
        "id": "80169acbf2886566",
        "type": "debug",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "ChangeSegmentJSON",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1310,
        "y": 160,
        "wires": []
    },
    {
        "id": "704f9f4ddd08f932",
        "type": "debug",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "HumidityThresholdValue",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1320,
        "y": 200,
        "wires": []
    },
    {
        "id": "e2cb3b16443d36da",
        "type": "debug",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "Humidity",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 920,
        "y": 220,
        "wires": []
    },
    {
        "id": "75b5ad00fd309030",
        "type": "ui-gauge",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "Humidity",
        "group": "fc3876ca5fad0f6a",
        "order": 1,
        "value": "payload",
        "valueType": "msg",
        "width": 3,
        "height": 3,
        "gtype": "gauge-half",
        "gstyle": "needle",
        "title": "Humidity",
        "alwaysShowTitle": false,
        "floatingTitlePosition": "top-left",
        "units": "%",
        "icon": "",
        "prefix": "",
        "suffix": "",
        "segments": [
            {
                "from": "20",
                "color": "#99c1f1",
                "text": "",
                "textType": "label"
            },
            {
                "from": "85",
                "color": "#ea5353",
                "text": "",
                "textType": "label"
            }
        ],
        "min": "20",
        "max": "100",
        "sizeThickness": 16,
        "sizeGap": 4,
        "sizeKeyThickness": 8,
        "styleRounded": true,
        "styleGlow": false,
        "className": "",
        "x": 920,
        "y": 260,
        "wires": [
            []
        ]
    },
    {
        "id": "81209091e69e650e",
        "type": "ui-chart",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "group": "fc3876ca5fad0f6a",
        "name": "Humidity",
        "label": "chart",
        "order": 2,
        "chartType": "line",
        "category": "topic",
        "categoryType": "msg",
        "xAxisLabel": "Time",
        "xAxisProperty": "",
        "xAxisPropertyType": "timestamp",
        "xAxisType": "time",
        "xAxisFormat": "",
        "xAxisFormatType": "auto",
        "xmin": "",
        "xmax": "",
        "yAxisLabel": "Humidity %",
        "yAxisProperty": "payload",
        "yAxisPropertyType": "msg",
        "ymin": "20",
        "ymax": "100",
        "bins": 10,
        "action": "append",
        "stackSeries": false,
        "pointShape": "false",
        "pointRadius": 4,
        "showLegend": true,
        "removeOlder": "4",
        "removeOlderUnit": "3600",
        "removeOlderPoints": "",
        "colors": [
            "#0095ff",
            "#e01b24",
            "#ff7f0e",
            "#2ca02c",
            "#a347e1",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "textColor": [
            "#666666"
        ],
        "textColorDefault": true,
        "gridColor": [
            "#e5e5e5"
        ],
        "gridColorDefault": true,
        "width": 6,
        "height": 8,
        "className": "",
        "interpolation": "linear",
        "x": 920,
        "y": 300,
        "wires": [
            []
        ]
    },
    {
        "id": "4b79199fafd41be7",
        "type": "mqtt in",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "Humidity",
        "topic": "bathroom/humidity",
        "qos": "0",
        "datatype": "json",
        "broker": "3f447ded17b259ee",
        "nl": false,
        "rap": false,
        "rh": 0,
        "inputs": 0,
        "x": 330,
        "y": 260,
        "wires": [
            [
                "0a351ffd80a868c9",
                "e2cb3b16443d36da",
                "81209091e69e650e",
                "75b5ad00fd309030"
            ]
        ]
    },
    {
        "id": "0a351ffd80a868c9",
        "type": "function",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "RecordHumidity",
        "func": "flow.set('lastHumidity', msg.payload);\nreturn msg;\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 950,
        "y": 340,
        "wires": [
            []
        ]
    },
    {
        "id": "fc3876ca5fad0f6a",
        "type": "ui-group",
        "name": "Humidity",
        "page": "cda4aeea5584ffaa",
        "width": 6,
        "height": 1,
        "order": 1,
        "showTitle": true,
        "className": "",
        "visible": "true",
        "disabled": "false",
        "groupType": "default"
    },
    {
        "id": "3f447ded17b259ee",
        "type": "mqtt-broker",
        "name": "Mosquitto",
        "broker": "192.168.7.245",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "protocolVersion": "5",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "sessionExpiry": ""
    },
    {
        "id": "cda4aeea5584ffaa",
        "type": "ui-page",
        "name": "Bathroom",
        "ui": "5158dba2ce9db01c",
        "path": "/page1",
        "icon": "home",
        "layout": "grid",
        "theme": "f149993e218cdb7d",
        "breakpoints": [
            {
                "name": "Default",
                "px": "0",
                "cols": "3"
            },
            {
                "name": "Tablet",
                "px": "576",
                "cols": "6"
            },
            {
                "name": "Small Desktop",
                "px": "768",
                "cols": "9"
            },
            {
                "name": "Desktop",
                "px": "1024",
                "cols": "12"
            }
        ],
        "order": 2,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "5158dba2ce9db01c",
        "type": "ui-base",
        "name": "Archery",
        "path": "/dashboard",
        "appIcon": "",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-notification",
            "ui-control"
        ],
        "showPathInSidebar": false,
        "headerContent": "page",
        "navigationStyle": "default",
        "titleBarStyle": "default",
        "showReconnectNotification": true,
        "notificationDisplayTime": 1,
        "showDisconnectNotification": true,
        "allowInstall": true
    },
    {
        "id": "f149993e218cdb7d",
        "type": "ui-theme",
        "name": "Default Theme",
        "colors": {
            "surface": "#ffffff",
            "primary": "#0094CE",
            "bgPage": "#eeeeee",
            "groupBg": "#ffffff",
            "groupOutline": "#cccccc"
        },
        "sizes": {
            "density": "default",
            "pagePadding": "12px",
            "groupGap": "12px",
            "groupBorderRadius": "4px",
            "widgetGap": "12px"
        }
    },
    {
        "id": "8050b049b5fcb4f6",
        "type": "global-config",
        "env": [],
        "modules": {
            "@flowfuse/node-red-dashboard": "1.27.1"
        }
    }
]

Debug output:

9/19/2025, 5:26:58 PMnode: TraceThresholdValfunction : (error)
error
name: "TypeError"
message: "Cannot set properties of undefined (setting 'segments')"
stack: string

TypeError: Cannot set properties of undefined (setting 'segments')
    at Function node:86f4f6c57298e008 [TraceThresholdVal]:7:24
    at Function node:86f4f6c57298e008 [TraceThresholdVal]:15:3
    at Script.runInContext (node:vm:149:12)
    at processMessage (/mnt/dietpi_userdata/node-red/node_modules/@node-red/nodes/core/function/10-function.js:430:37)
    at FunctionNode._inputCallback (/mnt/dietpi_userdata/node-red/node_modules/@node-red/nodes/core/function/10-function.js:348:17)
    at /mnt/dietpi_userdata/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:214:26
    at Object.trigger (/mnt/dietpi_userdata/node-red/node_modules/@node-red/util/lib/hooks.js:166:13)
    at Node._emitInput (/mnt/dietpi_userdata/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:206:11)
    at Node.emit (/mnt/dietpi_userdata/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:190:25)

Minor update to the flow code, above. This is the function code, with array brackets added [ ]

var humidityThresholdVal = global.get('humidityThreshold');

var segStr = 'color:#ff0000,from:' + String(humidityThresholdVal); //build the object string, including the threshold variable
var segObj = {segStr}; // use the string to create a JS Object
var segJSON = JSON.stringify(segObj); // Convert the JS Object to JSON
var segArray = [segJSON];
msg.ui_update.segments = segArray; //message passes the constructed JSON array for the segment


var msg2 = ""; //initialise a new message
msg2.payload = humidityThresholdVal; //message passes the value for the graph
msg2.topic = 'bathroom/humidityThreshold' //message passes the topic for a different series
return [msg, msg2];

When I use the editor for autocomplete, msg .ui_update isn't a suggested autocomplete!?

Not sure the editor is clever enough to include completions for nodes that are not in the base install ( ie the extra dashboard nodes)

You don't need all that complexity when creating an object.
Also, you don't need to send two messages, you can set the payload and the segments in one message.
I think you need to send the whole segments array each time, so assuming that you want a particular colour from the start you should set that too. I haven't looked at the full flow so I dont know what you want for that, it is late here.
Don't use var, use let or const as appropriate.
Generally you don't need the semi colons on the end of lines.
Something like this (untested)

const humidityThresholdVal = global.get('humidityThreshold');

msg.ui_update = {segments: [{color: "green", from: 0}, {color: "red", from: humidityThresholdVal}]}
msg.payload = humidityThresholdVal
msg.topic = 'bathroom/humidityThreshold'
return msg

Do you really want the needle pointing to the threshold value?

The editor is plenty clever, the dumbo who integrated it is not :wink:

It is of course possible to add type hints like we already have .payload and .topic however the issue is the function node has no idea what the shape of the incoming msg is (or supposed to be)

1 Like

I do need to send two messages. The first feeds the threshold value to the ui_gauge segment, as you've illustrated but the second message feeds the threshold as a data series to a ui_graph (which is why I specify both value as payload and the topic, so it's another plot in the graph)

Thank you all (esp @Colin.Smith1205 - Also, nice to see you're still involved @dceejay, post retirement )
This now all works perfectly: instance value gauge shows a variable colour coded threshold segment and historic-value graph has a line series showing the threshold value and history (last 4 hrs)

[
    {
        "id": "4b79199fafd41be7",
        "type": "mqtt in",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "Humidity",
        "topic": "bathroom/humidity",
        "qos": "0",
        "datatype": "json",
        "broker": "3f447ded17b259ee",
        "nl": false,
        "rap": false,
        "rh": 0,
        "inputs": 0,
        "x": 300,
        "y": 400,
        "wires": [
            [
                "0a351ffd80a868c9",
                "e2cb3b16443d36da",
                "81209091e69e650e",
                "75b5ad00fd309030"
            ]
        ]
    },
    {
        "id": "be3e70d8bd7590ee",
        "type": "inject",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "High humidity (95%)",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "bathroom/humidity",
        "payload": "100",
        "payloadType": "num",
        "x": 250,
        "y": 460,
        "wires": [
            [
                "0a351ffd80a868c9",
                "e2cb3b16443d36da",
                "81209091e69e650e",
                "75b5ad00fd309030"
            ]
        ]
    },
    {
        "id": "af02c8f8d2b3e3b7",
        "type": "inject",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "Low humidity (50%)",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "bathroom/humidity",
        "payload": "50",
        "payloadType": "num",
        "x": 250,
        "y": 500,
        "wires": [
            [
                "0a351ffd80a868c9",
                "e2cb3b16443d36da",
                "81209091e69e650e",
                "75b5ad00fd309030"
            ]
        ]
    },
    {
        "id": "0a351ffd80a868c9",
        "type": "function",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "RecordHumidity",
        "func": "flow.set('lastHumidity', msg.payload);\nreturn msg;\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 920,
        "y": 480,
        "wires": [
            []
        ]
    },
    {
        "id": "a59102097a2337a3",
        "type": "comment",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "Old function code",
        "info": "//}\n\n\n\n//Gather persistent variables\nvar requiredFanState    = flow.get('requiredFanState') || \"humidityTrigger\";\nvar startTimer          = flow.get('startTimer') || 0;\nvar fanTimerInterval    = 600000000; //milliseconds (1 minute = 60000ms)\nvar fanSwitch           = {payload: \"\"};\nvar fanStateNR          = {payload: \"\"};\nvar DashSync            = {payload: \"\"};\n\n//If the timer has expired, reset the timer, \n//send a message to turn the fan off and change the persistent \n//flow variable to reflect the resumed default mode\n\nif (requiredFanState == 'fanOn10') { //show timer progress for debug\n        var progress = (Date.now()-startTimer);\n        fanSwitch.payload   = 'ON';\n    if ((progress >=  fanTimerInterval) && (startTimer > 0)) { //timer interval spent\n        //node.warn('Resetting timer! and changing mode to: humidityTrigger');\n        startTimer          = 0; //local\n        flow.set('startTimer',0); //flow\n        \n        //fanSwitch.payload   = 'OFF'; //This will get set by the humidity threshold check function\n        \n        requiredFanState    = \"humidityTrigger\"; //local\n        flow.set('requiredFanState',\"humidityTrigger\"); //flow\n        \n        fanStateNR.payload  = \"humidityTrigger\"; //ready to tell the ESP+Sensor\n        DashSync.payload    = \"humidityTrigger\"; //ready to tell the dashboard dropdown\n        \n        \n        flow.set('fanTimerInterval',fanTimerInterval);\n        \n    } else if ((progress <  fanTimerInterval) && (startTimer > 0)) {\n        //node.warn('timer progress:'+ progress + 'to:'+ fanTimerInterval); // progress up to the point the timer is spent\n        fanSwitch.payload   = 'ON';\n    }\n    \n    flow.set('requiredFanState',requiredFanState); //set the flow params on exit, even if there's no change\n    flow.set('fanTimerInterval',fanTimerInterval);\n\n    return [ DashSync, fanSwitch, fanStateNR ];\n} \n\n",
        "x": 920,
        "y": 520,
        "wires": []
    },
    {
        "id": "e2cb3b16443d36da",
        "type": "debug",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "Humidity",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 890,
        "y": 360,
        "wires": []
    },
    {
        "id": "81209091e69e650e",
        "type": "ui-chart",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "group": "fc3876ca5fad0f6a",
        "name": "Humidity",
        "label": "chart",
        "order": 2,
        "chartType": "line",
        "category": "topic",
        "categoryType": "msg",
        "xAxisLabel": "Time",
        "xAxisProperty": "",
        "xAxisPropertyType": "timestamp",
        "xAxisType": "time",
        "xAxisFormat": "",
        "xAxisFormatType": "auto",
        "xmin": "",
        "xmax": "",
        "yAxisLabel": "Humidity %",
        "yAxisProperty": "payload",
        "yAxisPropertyType": "msg",
        "ymin": "20",
        "ymax": "100",
        "bins": 10,
        "action": "append",
        "stackSeries": false,
        "pointShape": "false",
        "pointRadius": 4,
        "showLegend": true,
        "removeOlder": "4",
        "removeOlderUnit": "3600",
        "removeOlderPoints": "",
        "colors": [
            "#0095ff",
            "#e01b24",
            "#ff7f0e",
            "#2ca02c",
            "#a347e1",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "textColor": [
            "#666666"
        ],
        "textColorDefault": true,
        "gridColor": [
            "#e5e5e5"
        ],
        "gridColorDefault": true,
        "width": 6,
        "height": 8,
        "className": "",
        "interpolation": "linear",
        "x": 890,
        "y": 440,
        "wires": [
            []
        ]
    },
    {
        "id": "75b5ad00fd309030",
        "type": "ui-gauge",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "Humidity",
        "group": "fc3876ca5fad0f6a",
        "order": 1,
        "value": "payload",
        "valueType": "msg",
        "width": 3,
        "height": 3,
        "gtype": "gauge-half",
        "gstyle": "needle",
        "title": "Humidity",
        "alwaysShowTitle": false,
        "floatingTitlePosition": "top-left",
        "units": "%",
        "icon": "",
        "prefix": "",
        "suffix": "",
        "segments": [
            {
                "from": "20",
                "color": "#99c1f1",
                "text": "",
                "textType": "label"
            },
            {
                "from": "85",
                "color": "#ea5353",
                "text": "",
                "textType": "label"
            }
        ],
        "min": "20",
        "max": "100",
        "sizeThickness": 16,
        "sizeGap": 4,
        "sizeKeyThickness": 8,
        "styleRounded": true,
        "styleGlow": false,
        "className": "",
        "x": 890,
        "y": 400,
        "wires": [
            []
        ]
    },
    {
        "id": "7c642c5673f59101",
        "type": "inject",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "OnStart",
        "props": [
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "30",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "x": 310,
        "y": 340,
        "wires": [
            [
                "86f4f6c57298e008"
            ]
        ]
    },
    {
        "id": "86f4f6c57298e008",
        "type": "function",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "TraceThresholdVal",
        "func": "let humidityThresholdVal = global.get('humidityThreshold');\n\nmsg.ui_update = { segments: [{ color: \"green\", from: 0 }, { color: \"red\", from: humidityThresholdVal }] }\n\n//return [msg]\n\nlet msg2 = {} //initialise a new message\nmsg2.payload = humidityThresholdVal //message passes the value for the graph\nmsg2.topic = 'bathroom/humidityThreshold' //message passes the topic for a different series\nreturn [msg, msg2]",
        "outputs": 2,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 500,
        "y": 340,
        "wires": [
            [
                "80169acbf2886566",
                "75b5ad00fd309030"
            ],
            [
                "81209091e69e650e",
                "704f9f4ddd08f932"
            ]
        ]
    },
    {
        "id": "80169acbf2886566",
        "type": "debug",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "ChangeSegmentJSON",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1280,
        "y": 300,
        "wires": []
    },
    {
        "id": "704f9f4ddd08f932",
        "type": "debug",
        "z": "a0ebd549a544bb25",
        "g": "84074881becbb9f2",
        "name": "HumidityThresholdValue",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1290,
        "y": 340,
        "wires": []
    },
    {
        "id": "3f447ded17b259ee",
        "type": "mqtt-broker",
        "name": "Mosquitto",
        "broker": "192.168.7.245",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "protocolVersion": "5",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "sessionExpiry": ""
    },
    {
        "id": "fc3876ca5fad0f6a",
        "type": "ui-group",
        "name": "Humidity",
        "page": "cda4aeea5584ffaa",
        "width": 6,
        "height": 1,
        "order": 1,
        "showTitle": true,
        "className": "",
        "visible": "true",
        "disabled": "false",
        "groupType": "default"
    },
    {
        "id": "cda4aeea5584ffaa",
        "type": "ui-page",
        "name": "Bathroom",
        "ui": "5158dba2ce9db01c",
        "path": "/page1",
        "icon": "home",
        "layout": "grid",
        "theme": "f149993e218cdb7d",
        "breakpoints": [
            {
                "name": "Default",
                "px": "0",
                "cols": "3"
            },
            {
                "name": "Tablet",
                "px": "576",
                "cols": "6"
            },
            {
                "name": "Small Desktop",
                "px": "768",
                "cols": "9"
            },
            {
                "name": "Desktop",
                "px": "1024",
                "cols": "12"
            }
        ],
        "order": 2,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "5158dba2ce9db01c",
        "type": "ui-base",
        "name": "Archery",
        "path": "/dashboard",
        "appIcon": "",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-notification",
            "ui-control"
        ],
        "showPathInSidebar": false,
        "headerContent": "page",
        "navigationStyle": "default",
        "titleBarStyle": "default",
        "showReconnectNotification": true,
        "notificationDisplayTime": 1,
        "showDisconnectNotification": true,
        "allowInstall": true
    },
    {
        "id": "f149993e218cdb7d",
        "type": "ui-theme",
        "name": "Default Theme",
        "colors": {
            "surface": "#ffffff",
            "primary": "#0094CE",
            "bgPage": "#eeeeee",
            "groupBg": "#ffffff",
            "groupOutline": "#cccccc"
        },
        "sizes": {
            "density": "default",
            "pagePadding": "12px",
            "groupGap": "12px",
            "groupBorderRadius": "4px",
            "widgetGap": "12px"
        }
    },
    {
        "id": "b383a3225650aa4f",
        "type": "global-config",
        "env": [],
        "modules": {
            "@flowfuse/node-red-dashboard": "1.27.1"
        }
    }
]

Ought to mention that on another tab (bathroom settings), there's this flow, to adjust & store the humidity threshold value:

[
    {
        "id": "1771977e82aa9387",
        "type": "mqtt in",
        "z": "a60a5305dc8d26e9",
        "g": "387210b936df9da4",
        "name": "humidityThreshold",
        "topic": "bathroom/humidityThreshold",
        "qos": "2",
        "datatype": "auto",
        "broker": "3f447ded17b259ee",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 1330,
        "y": 240,
        "wires": [
            [
                "73c5d9ff9842deec",
                "b2e4ebd197a93bfc",
                "6f896d4c60e8b908"
            ]
        ]
    },
    {
        "id": "73c5d9ff9842deec",
        "type": "function",
        "z": "a60a5305dc8d26e9",
        "g": "387210b936df9da4",
        "name": "StoreHumidityThreshold",
        "func": "if (Number(msg.payload) <= 30) {\n    msg.payload = '30';\n}\nif (Number(msg.payload) >= 95) {\n    msg.payload = '95';\n}\nglobal.set ('humidityThreshold', Number(msg.payload));",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "// Code added here will be run once\n// whenever the node is started.\nglobal.set ('humidityThreshold', 85);",
        "finalize": "",
        "libs": [],
        "x": 1710,
        "y": 240,
        "wires": [
            []
        ]
    },
    {
        "id": "b2e4ebd197a93bfc",
        "type": "debug",
        "z": "a60a5305dc8d26e9",
        "g": "387210b936df9da4",
        "name": "Humidity threshold",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1690,
        "y": 180,
        "wires": []
    },
    {
        "id": "6f896d4c60e8b908",
        "type": "ui-slider",
        "z": "a60a5305dc8d26e9",
        "g": "387210b936df9da4",
        "group": "b98e9fbe6d175507",
        "name": "humidityThreshold",
        "label": "Humidity Threshold",
        "tooltip": "",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "outs": "end",
        "topic": "payload",
        "topicType": "msg",
        "thumbLabel": "true",
        "showTicks": "always",
        "min": "30",
        "max": "100",
        "step": "5",
        "className": "",
        "iconPrepend": "",
        "iconAppend": "",
        "color": "",
        "colorTrack": "",
        "colorThumb": "",
        "showTextField": false,
        "x": 1330,
        "y": 160,
        "wires": [
            [
                "b2e4ebd197a93bfc",
                "73c5d9ff9842deec"
            ]
        ]
    },
    {
        "id": "3f447ded17b259ee",
        "type": "mqtt-broker",
        "name": "Mosquitto",
        "broker": "192.168.7.245",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "protocolVersion": "5",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "sessionExpiry": ""
    },
    {
        "id": "b98e9fbe6d175507",
        "type": "ui-group",
        "name": "Humidity",
        "page": "0cafb08f3c034873",
        "width": 6,
        "height": 1,
        "order": 5,
        "showTitle": true,
        "className": "",
        "visible": "true",
        "disabled": "false",
        "groupType": "default"
    },
    {
        "id": "0cafb08f3c034873",
        "type": "ui-page",
        "name": "Bathroom settings",
        "ui": "5158dba2ce9db01c",
        "path": "/page2",
        "icon": "home",
        "layout": "grid",
        "theme": "f149993e218cdb7d",
        "breakpoints": [
            {
                "name": "Default",
                "px": "0",
                "cols": "3"
            },
            {
                "name": "Tablet",
                "px": "576",
                "cols": "6"
            },
            {
                "name": "Small Desktop",
                "px": "768",
                "cols": "9"
            },
            {
                "name": "Desktop",
                "px": "1024",
                "cols": "12"
            }
        ],
        "order": 1,
        "className": "",
        "visible": true,
        "disabled": false
    },
    {
        "id": "5158dba2ce9db01c",
        "type": "ui-base",
        "name": "Archery",
        "path": "/dashboard",
        "appIcon": "",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-notification",
            "ui-control"
        ],
        "showPathInSidebar": false,
        "headerContent": "page",
        "navigationStyle": "default",
        "titleBarStyle": "default",
        "showReconnectNotification": true,
        "notificationDisplayTime": 1,
        "showDisconnectNotification": true,
        "allowInstall": true
    },
    {
        "id": "f149993e218cdb7d",
        "type": "ui-theme",
        "name": "Default Theme",
        "colors": {
            "surface": "#ffffff",
            "primary": "#0094CE",
            "bgPage": "#eeeeee",
            "groupBg": "#ffffff",
            "groupOutline": "#cccccc"
        },
        "sizes": {
            "density": "default",
            "pagePadding": "12px",
            "groupGap": "12px",
            "groupBorderRadius": "4px",
            "widgetGap": "12px"
        }
    },
    {
        "id": "2ed9137d0128ba1a",
        "type": "global-config",
        "env": [],
        "modules": {
            "@flowfuse/node-red-dashboard": "1.27.1"
        }
    }
]