Node red variable in a service call

Hello,

I’m having a little trouble trying to incorporate a variable into a Node Red service call.

I’ll explain what I’m trying to accomplish in case there’s a better way to go about it.

I’m using a combination of Node Red and Home Assistant automations to control my heating system via 2 wall thermostats which control my boiler and several TRVs

When I leave the house, my TRV temperate targets are changed depending on the status of a switch that tells the system whether or not my dog is at home.

If the dog is home, all the other TRVs are set to a lower temperature while the TRV in the man cave is set to a higher temperature (this is what I need to be a variable)
The wall thermostat for the bedrooms is then set to a high or low temperature based on a stand alone climate sensor in the man cave. If the temperature goes below 17.5 degrees, the wall thermostat gets set to 25. Once the man cave hits 19 degrees, the wall thermostat gets set to 10 degrees. When I come home, the other TRVs are set to the high setting again (ie I will have multiple different entities being set to that temperature)

The TRV temp settings are currently changed by automations, while the auto heating for the dog is currently being controlled via Node Red. Node Red also has some flows to switch the thermostats for upstairs and downstairs to a higher temperature to turn the heating on for an hour by pressing a button.

I’m using one of these flows to experiment with using a variable in the temperature service call going to the thermostat.
The reason for this is that I’ve been doing a little tweaking to try to find the best values. Because I’m using a standalone climate sensor in the middle of the room rather than the TRV, if the TRV setting is too low and it’s too cold outside, the TRV closes before the temperature of the room rises enough to trigger the thermostat back to the low setting. But a few days ago the node red flow failed so the heating was on all day and the poor dog drank his full bowl of water and pissed on my sofa. Because the man cave is the only radiator that is on during the day bar the hallway which is a dumb valve and set very low, and the two bathrooms which don’t have thermostatic valves at all, the boiler ran all day.

I’ve tweaked enough with the temperatures in the past that I’d rather just be able to set a couple of variables and use those to set the temperatures in the service calls.

I’ve also thought of using automations then just having node red press a button to set the thermostat but I can’t see any way to use a variable in a temperature service call in an automation either.

I’ve set 2 environment variables in the Node Red settings (temphigh and templow) and tested a little using the least critical flow that boosts the downstairs heating for an hour.

I’ve used various combinations of global.temphigh $env{temphigh} $env(‘temphigh’) but I can’t seem to get the temperature to change with anything except a plain number in the service call.

I’ll include the nodes here. The heating off flow is currently just using the standard temperature of 10 degrees while the heating boost is where I’m trying to put the variable in the service call.


[
    {
        "id": "8d25853ae6b0d0f3",
        "type": "tab",
        "label": "test heating flow",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "11fb445d05b1ae26",
        "type": "api-call-service",
        "z": "8d25853ae6b0d0f3",
        "d": true,
        "name": "",
        "server": "f0314f01c7348223",
        "version": 5,
        "debugenabled": true,
        "domain": "climate",
        "service": "set_temperature",
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "climate.living_room_thermostat"
        ],
        "data": "{\t    \"temperature\": \"{{global.temphigh}}\"\t}",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [
            {
                "property": "1",
                "propertyType": "msg",
                "value": "",
                "valueType": "data"
            },
            {
                "property": "1",
                "propertyType": "flow",
                "value": "",
                "valueType": "data"
            },
            {
                "property": "1",
                "propertyType": "global",
                "value": "",
                "valueType": "data"
            }
        ],
        "queue": "none",
        "x": 450,
        "y": 200,
        "wires": [
            [
                "29bc0dda9bc73364"
            ]
        ]
    },
    {
        "id": "3d0167ac4d552d88",
        "type": "api-call-service",
        "z": "8d25853ae6b0d0f3",
        "d": true,
        "name": "",
        "server": "f0314f01c7348223",
        "version": 5,
        "debugenabled": true,
        "domain": "climate",
        "service": "set_temperature",
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "climate.living_room_thermostat"
        ],
        "data": "{\"temperature\":10}",
        "dataType": "json",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 550,
        "y": 400,
        "wires": [
            []
        ]
    },
    {
        "id": "8abaed45023ced42",
        "type": "ha-button",
        "z": "8d25853ae6b0d0f3",
        "d": true,
        "name": "Downstairs Heating 1 Hour Boost",
        "version": 0,
        "debugenabled": false,
        "outputs": 1,
        "entityConfig": "ae607660d1d070be",
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "entity"
            }
        ],
        "x": 150,
        "y": 260,
        "wires": [
            [
                "11fb445d05b1ae26"
            ]
        ]
    },
    {
        "id": "4e7bd4937e817ec1",
        "type": "ha-button",
        "z": "8d25853ae6b0d0f3",
        "d": true,
        "name": "Downstairs Heating Off",
        "version": 0,
        "debugenabled": false,
        "outputs": 1,
        "entityConfig": "f12d701cc47d62eb",
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "entity"
            }
        ],
        "x": 260,
        "y": 380,
        "wires": [
            [
                "3d0167ac4d552d88"
            ]
        ]
    },
    {
        "id": "29bc0dda9bc73364",
        "type": "trigger",
        "z": "8d25853ae6b0d0f3",
        "d": true,
        "name": "",
        "op1": "",
        "op2": "",
        "op1type": "nul",
        "op2type": "pay",
        "duration": "60",
        "extend": false,
        "overrideDelay": false,
        "units": "min",
        "reset": "",
        "bytopic": "all",
        "topic": "topic",
        "outputs": 1,
        "x": 710,
        "y": 140,
        "wires": [
            [
                "3d0167ac4d552d88"
            ]
        ]
    },
    {
        "id": "f0314f01c7348223",
        "type": "server",
        "name": "Home Assistant",
        "version": 2,
        "addon": true,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": true,
        "heartbeatInterval": "30"
    },
    {
        "id": "ae607660d1d070be",
        "type": "ha-entity-config",
        "server": "f0314f01c7348223",
        "name": "Downstairs Heating 1 Hour Boost",
        "version": 2,
        "haConfig": [
            {
                "property": "name",
                "value": "Downstairs Heating 1 Hour Boost"
            },
            {
                "property": "icon",
                "value": ""
            },
            {
                "property": "device_class",
                "value": ""
            }
        ],
        "entityType": "button"
    },
    {
        "id": "f12d701cc47d62eb",
        "type": "ha-entity-config",
        "server": "f0314f01c7348223",
        "name": "Downstairs Heating Off",
        "version": 2,
        "haConfig": [
            {
                "property": "name",
                "value": "Downstairs Heating Off"
            },
            {
                "property": "icon",
                "value": ""
            },
            {
                "property": "device_class",
                "value": ""
            }
        ],
        "entityType": "button"
    }
]

You’re using mustache templates in the data field, but they’re only supported if the type is JSON (image), and you’ve got it set to JASONata (image).

Alternatively, you could leave it as JSONata, and use the following:

{
    "temperature": $globalContext("temphigh")
}

.

I think that was one of the ones I tried but it won’t change the temperature of the thermostat. I’d also tried both JSON (which is what I was using with the static temperature entry) and JSONata.

Just to confirm, $globalContext(“temphigh”) will pull the data from >settings>Environment>Global Environment Variables?
What format should I be using for the variable? I would assume it would just be a string but I’ve tried string, number, JSON, JSONata.

I put a static 20 in the JSONata expression and it changed the temperature OK when I pressed the button so the command is good, it’s just getting the variable in there.

No - $globalContext() reads from global context, which is under the dropdown at the top right and then Context Data. To access environment variables you use $env() with JSONata.

1 Like

The most straight forward way to send a global is use the output properties of the button node.

Screenshot 2024-01-26 231203

then use {{payload}} in your template.

Check to see if the global exists, where the debug window is, set it to context.

Screenshot 2024-01-26 231546

hit the little refresh button on the right.

Then to set a global use the value in an inject node. Connect it to a change node and set as follows.

Screenshot 2024-01-26 231637

1 Like

That did it, thank you.

Thank you. @michaelblight’s solution worked but I might use the information in yours to see if i can make a more elegant solution than having to manually go into the environment variables to change the target temperatures.

There are many ways to do things in node red. Let me take a second and explain the different types of variables.

env or environmental or node:

(Node is what it shows as in the context menu).

This information is only available inside that one particular node.

For instance a defined entity in a home assistant node is now an environmental variable for that node.

Screenshot 2024-01-31 163034

flow variable:

Is accessible by any node on one given page or tab.

global variable:

Is accessible by all of node red.

1 Like

This is excellent, so I could set an entity value which would automatically change the variables in Node Red. That’s going to be useful, thank you.

To be clear when you set an entity (yellow) it creates an environmental variable. That can only be used in the blue area of that one node.

If you need to reference the set entity(yellow) in the blue area, rather than use the entity’s name (ex. sensor.long_name_xyz_123) in the blue area you can use entity instead.

For different ways to manipulate that variable see:

1 Like

Thank you. I made a number helper, set up a state node to monitor it and sent the output to global variables and used globalContext instead of env as the variable and now I can set my high and low temperatures from Lovelace.