How to save several states of a climate the best?

Hi all,
I have mounted a window open/closed sensor at my window (which sends the data via mqtt) and I am planning to do the following with NodeRed (and HomeAssistant):
If I open the window, NodeRed should save the climate settings and turn the climate off. When the window gets closed again it should turn on the climate with the same setting than before.

The following settings are possible with the climate:

At the moment I save the climate state in a flow variable like this:

[
    {
        "id": "97421084ccfd057c",
        "type": "tab",
        "label": "Flow 1",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "5e5c8a874d64033a",
        "type": "api-call-service",
        "z": "97421084ccfd057c",
        "name": "",
        "server": "42c5021e.042e7c",
        "version": 5,
        "debugenabled": false,
        "domain": "climate",
        "service": "turn_off",
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "climate.schlafzimmer_2"
        ],
        "data": "",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 1640,
        "y": 435,
        "wires": [
            []
        ]
    },
    {
        "id": "0e1960f6671ea943",
        "type": "api-call-service",
        "z": "97421084ccfd057c",
        "name": "",
        "server": "42c5021e.042e7c",
        "version": 5,
        "debugenabled": false,
        "domain": "climate",
        "service": "set_hvac_mode",
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "climate.schlafzimmer_2"
        ],
        "data": "",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 1670,
        "y": 360,
        "wires": [
            []
        ]
    },
    {
        "id": "470a7259b1705568",
        "type": "change",
        "z": "97421084ccfd057c",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "climate_state_before",
                "pt": "flow",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1135,
        "y": 435,
        "wires": [
            [
                "5e5c8a874d64033a"
            ]
        ]
    },
    {
        "id": "bdcb58795f5e7b70",
        "type": "api-current-state",
        "z": "97421084ccfd057c",
        "name": "",
        "server": "42c5021e.042e7c",
        "version": 3,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "climate.schlafzimmer_2",
        "state_type": "str",
        "blockInputOverrides": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "entity"
            }
        ],
        "for": "0",
        "forType": "num",
        "forUnits": "minutes",
        "override_topic": false,
        "state_location": "payload",
        "override_payload": "msg",
        "entity_location": "data",
        "override_data": "msg",
        "x": 840,
        "y": 435,
        "wires": [
            [
                "470a7259b1705568"
            ]
        ]
    },
    {
        "id": "ddf3599b80f08a1e",
        "type": "switch",
        "z": "97421084ccfd057c",
        "name": "climate state before",
        "property": "climate_state_before",
        "propertyType": "flow",
        "rules": [
            {
                "t": "eq",
                "v": "dry",
                "vt": "jsonata"
            },
            {
                "t": "eq",
                "v": "cool",
                "vt": "jsonata"
            },
            {
                "t": "eq",
                "v": "heat",
                "vt": "jsonata"
            },
            {
                "t": "eq",
                "v": "heat_cool",
                "vt": "jsonata"
            },
            {
                "t": "eq",
                "v": "fan_only",
                "vt": "jsonata"
            },
            {
                "t": "eq",
                "v": "off",
                "vt": "jsonata"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 6,
        "x": 1380,
        "y": 375,
        "wires": [
            [
                "0e1960f6671ea943"
            ],
            [
                "0e1960f6671ea943"
            ],
            [
                "0e1960f6671ea943"
            ],
            [
                "0e1960f6671ea943"
            ],
            [
                "0e1960f6671ea943"
            ],
            [
                "0e1960f6671ea943"
            ]
        ]
    },
    {
        "id": "13a90ccbaa9aeb7c",
        "type": "change",
        "z": "97421084ccfd057c",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "climate_state_before",
                "pt": "flow",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1130,
        "y": 375,
        "wires": [
            [
                "ddf3599b80f08a1e"
            ]
        ]
    },
    {
        "id": "9f0f62575467ed4d",
        "type": "api-current-state",
        "z": "97421084ccfd057c",
        "name": "",
        "server": "42c5021e.042e7c",
        "version": 3,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "climate.schlafzimmer_2",
        "state_type": "str",
        "blockInputOverrides": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "entity"
            }
        ],
        "for": "0",
        "forType": "num",
        "forUnits": "minutes",
        "override_topic": false,
        "state_location": "payload",
        "override_payload": "msg",
        "entity_location": "data",
        "override_data": "msg",
        "x": 835,
        "y": 375,
        "wires": [
            [
                "13a90ccbaa9aeb7c"
            ]
        ]
    },
    {
        "id": "5569d4be19f0d116",
        "type": "switch",
        "z": "97421084ccfd057c",
        "name": "closed/open",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "true",
                "vt": "jsonata"
            },
            {
                "t": "eq",
                "v": "false",
                "vt": "jsonata"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 535,
        "y": 405,
        "wires": [
            [
                "9f0f62575467ed4d"
            ],
            [
                "bdcb58795f5e7b70"
            ]
        ]
    },
    {
        "id": "30a66f6407b77831",
        "type": "mqtt in",
        "z": "97421084ccfd057c",
        "name": "Schlafzimmersensor",
        "topic": "zigbee2mqtt/Schlafzimmerfenster rechts",
        "qos": "2",
        "datatype": "json",
        "broker": "b496b411.fe5358",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 155,
        "y": 405,
        "wires": [
            [
                "c51b1d3eeaa4c37f"
            ]
        ]
    },
    {
        "id": "c51b1d3eeaa4c37f",
        "type": "change",
        "z": "97421084ccfd057c",
        "name": "closed/opened",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload.contact",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 355,
        "y": 405,
        "wires": [
            [
                "5569d4be19f0d116"
            ]
        ]
    },
    {
        "id": "42c5021e.042e7c",
        "type": "server",
        "name": "Home Assistant",
        "version": 5,
        "addon": false,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": false,
        "heartbeatInterval": "30",
        "areaSelector": "friendlyName",
        "deviceSelector": "friendlyName",
        "entitySelector": "friendlyName",
        "statusSeparator": "at: ",
        "statusYear": "hidden",
        "statusMonth": "short",
        "statusDay": "numeric",
        "statusHourCycle": "h23",
        "statusTimeFormat": "h:m",
        "enableGlobalContextStore": true
    },
    {
        "id": "b496b411.fe5358",
        "type": "mqtt-broker",
        "name": "MQTT",
        "broker": "192.168.0.2",
        "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": {},
        "sessionExpiry": ""
    }
]

(I didn't test the flow up to now so there could be an error in it...)
The problem with this is, that I would need several flow variables (hvac_modes, fan_modes, preset_modes...) and I though that there might be a simpler solution... Do you have any advise for me?

Thanks!

BR

(I didn't test the flow up to now so there could be an error in it...)

We cannot test your flow as we don't have your devices (and/or are not using home assistant)

I thought you would be able to handle this directly in home assistant ?

Thanks for the answer. I understand that you can not test it due due missing nodes... What I am asking for is the approach how to save several states. Maybe there is another way (instead of several flow variables) which suits better for several states... :slight_smile:

BR

which suits better for several states...

This was my point of home assistant: it is a state machine, it knows current and previous values, you should be able to restore the previous state with state triggers ?

Managing a state in node-red with home-assistant in between only makes things more complex.
I would choose one or the other.

If you update a state via mqtt, does this not automatically update home assistant ?
If yes, just save all previous states in flow variables and let it get triggered/handled through node-red directly.

Then again, I don't know how home-assistant works with the node-red nodes.

While bakman2's reply seems to be the way to go why not store all states in one object? (can't use your flow at the moment so you may already do this)

Hi,
I will try it the way bakman2 suggested. Nevertheless, can you give me a small demo flow how to store more state in one object?

BR

As I said I cannot load your flow at the moment so I have no idea how your data is presented (show what you get as an input in a debug node) but using the Statusattribute that you showed as an example

if the payload contains the complete climate data

const climate = msg.payload

flow.set('climate', climate)

then get the various attributes

const climate = flow.get('climate')

let hvacMode = climate.hvac_mode
...
let friendlyName = climate.friendly_name

or altogether

// Use deconstruction to get object values
let [hvac_mode, min_temp, max_temp, fan_mode, preset_mode, swing_mode, current_temperature, temperature, fan_mode, friendly_name] = flow_get('climate')

If you do not get the data in one payload you just create the object and save the individual elements to it as they arrive

`the msg.data looks like this:


`
if I understand you right I take a function node where I put in

const climate = msg.data

flow.set('climate', climate)

and in another function node I can use the flow.get to get the whole object and with e.g.

let swing_modes= climate.swing_modes

I would get the selected swing mode. Am I correct? This is very nice to know because I can use this for other things too :smiley:

Yes, although apart from selection options you can probably ignore the *_modes

arrays as they will not change