If function returns duplicate msg

Hi all,

I'm trying to learn more about functions so I created a function wich gets multiple information and compares all inputs to send a payload. Here is my code

context.cover_arzi_aussetzen = context.cover_arzi_aussetzen
context.cover_arzi_status = context.cover_arzi_status
context.cover_bazi_aussetzen = context.cover_bazi_aussetzen
context.cover_bazi_status = context.cover_bazi_status


if (msg.data.entity_id === 'input_boolean.arbeitszimmerrollo_aussetzen')
{
    context.cover_arzi_aussetzen = msg.payload
}
if (msg.data.entity_id === 'cover.arzi_shlsht_fenster')
{
    context.cover_arzi_status = msg.data.attributes.current_position
}

if (msg.data.entity_id === 'input_boolean.badezimmerrollo_aussetzen')
{
    context.cover_bazi_aussetzen = msg.payload
}
if (msg.data.entity_id === 'cover.bazi_shlsht_fenster')
{
    context.cover_bazi_status = msg.data.attributes.current_position
}

//----------------------------
if (context.cover_arzi_aussetzen === "off" && context.cover_arzi_status === 100)
{
msg.payload =

    {"service": "notify", data:{"message":"Arbeitszimmer Aussetzen off, status  100"}}
  return [msg,null]
}

if (context.cover_bazi_aussetzen === "off" && context.cover_bazi_status === 100)
{
msg.payload =

    {"service": "notify", data:{"message":"Badezimmer Aussetzen off, status  100"}}
  return [null,msg]
}

My problem is that I receive 4 times the notify Arbeitszimmer Aussetzen off, status 100 but no time Badezimmer Aussetzen off, status 100. All conditions match, if I only use the if function for Badezimmer I receive the notify 4 times for Badezimmer. Can someone help me out? What is my mistake? Of course I can use other nodes to solve this wich I currently using but on the one hand my flow is much too big and on the other hand I want to learn more about the function node as I wrote earlier.

I would appreciate any help.

Thanks in advance and cheers
PaWƤl

First off why are you setting these variables to themself's?

second are these suppose to be persistant variables? If so, you are doing it wrong and need to go read the documentation Writing Functions : Node-RED

If not, where does that variable come from in the first place?

As to receiving for notifications, how many msg's are being sent to the function node? what is the data going into the function node?

hi @zenofmud
thank you for your answer. I hope I can answer all your questions correctly. Before I opened this thread I tried to solve it myself googling for answers. In one "guide" I found a solution to set the variable by itself. So if I understand your question correctly this procedure seems to be wrong.

The variables must not be persistant because they will be "refilled" after a trigger starts.
Currently 4 Home Assistant current state nodes are going into the input connection. 2 of them with boolean on or off and 2 of them with all information that my device delivers. Because of this I set the msg.payload to msg.data.attributes.current_position. In my honest opinion I was able to check both payloads if they are true. So the first part is to set the payload that I really want and the second part is the "logic" part. I hope you are able to understand my explanation as English is not my mother language.

I'd really like to see that 'guide'.

BACKGROUND:
Context data is a way to share data between nodes without passing it in a message. There are three types: Global, Flow and Node.

With Global context, any node, in any flow, on any tab, can share the data
With Flow context, any node, in that flow can share the data
With Node context, any msg that comes thru the node that creates it, can access that data.

The word 'persistant' means it will exist to be used later, it does NOT mean it can never be changed. Let's say you want to count the number of msgs that go thru a function node. In the functio node you would do this

let count_m = flow.get("msg_counter") || 0;
count_m++;
flow.set("msg_counter", count_m);

The first line tries to get the flow context variable called 'msg_counter' and it it doesn't exist, it sends a zero to the variable count_m.
Then next line increases the value of count_m by one.
The third line stores the value in count_m in the flow context variable msg_counter.

So each time a msg passes into this function node, the value is increased by one. So the 'variable' is persisant but the value it contains changes. (you can delete the variable by setting it's value to null.)

Now about your issue. Without seeing your flow, I don't know if one msg with all four current states go into the function node or if four seperate msg go into the function node. Each time a msg enters a node, the node has know knowledge of what has happened before. So if msg 1 goes into a function node, it does it's work and leaves. Now msg 2 comes along and enters the function node. There is nothing in the function node about msg 1, it is starting clean. If you stored some data in a context variable, this iteration of the function node could go get the stored context variable and use that along with the data in the current function.

I hope that helps you out. If you still need help, having a copy of your flow would allow us to see what you are doing.

If you need it, see this article in the cookbook for an example of how to join messages into one object.

Wow, thank you for your detailed explanation!
Currently 4 current state nodes go into the function node. In the function node I want to "extract" the payload I need (context.cover_bazi_status = msg.data.attributes.current_position) because the original payload is "open" but I need the number of current_position. After comparing the 4 values I want so pass my new msg to 2 separate output, one for each device.
As I understand you correctly because of the 4 input nodes I have 4 times msg processing and therefor 4 times output?

Here is my flow:

[
    {
        "id": "38e4d6300fc6052d",
        "type": "api-current-state",
        "z": "6033c466a6e49c53",
        "name": "CHK: Ist Rollo AZ aussetzen an?",
        "server": "ddbd0338d04ff2f9",
        "version": 3,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "input_boolean.arbeitszimmerrollo_aussetzen",
        "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",
        "x": 1180,
        "y": 1280,
        "wires": [
            [
                "5d8cac5bf08eb163"
            ]
        ]
    },
    {
        "id": "9f7097f6a82744bf",
        "type": "api-current-state",
        "z": "6033c466a6e49c53",
        "name": "CHK: Ist Rollo BZ aussetzen an?",
        "server": "ddbd0338d04ff2f9",
        "version": 3,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "input_boolean.badezimmerrollo_aussetzen",
        "state_type": "str",
        "blockInputOverrides": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "entity"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "rollos_garten_aussetzen",
                "valueType": "str"
            }
        ],
        "for": 0,
        "forType": "num",
        "forUnits": "minutes",
        "x": 1180,
        "y": 1340,
        "wires": [
            [
                "5d8cac5bf08eb163"
            ]
        ]
    },
    {
        "id": "b826085b6b3c72d2",
        "type": "api-current-state",
        "z": "6033c466a6e49c53",
        "name": "CHK: Ist Rollo AZ bereits geƶffnet",
        "server": "ddbd0338d04ff2f9",
        "version": 3,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "cover.arzi_shlsht_fenster",
        "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",
        "x": 1180,
        "y": 1400,
        "wires": [
            [
                "5d8cac5bf08eb163"
            ]
        ]
    },
    {
        "id": "820d6d35d25f9547",
        "type": "api-current-state",
        "z": "6033c466a6e49c53",
        "name": "CHK: Ist Rollo BZ bereits geƶffnet",
        "server": "ddbd0338d04ff2f9",
        "version": 3,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "cover.bazi_shlsht_fenster",
        "state_type": "str",
        "blockInputOverrides": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "entity"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "rollos_garten_status",
                "valueType": "str"
            }
        ],
        "for": 0,
        "forType": "num",
        "forUnits": "minutes",
        "x": 1180,
        "y": 1460,
        "wires": [
            [
                "5d8cac5bf08eb163"
            ]
        ]
    },
    {
        "id": "5d8cac5bf08eb163",
        "type": "function",
        "z": "6033c466a6e49c53",
        "name": "Rollosteuerung",
        "func": "context.cover_arzi_aussetzen = context.cover_arzi_aussetzen\ncontext.cover_arzi_status = context.cover_arzi_status\ncontext.cover_bazi_aussetzen = context.cover_bazi_aussetzen\ncontext.cover_bazi_status = context.cover_bazi_status\n\n\nif (msg.data.entity_id === 'input_boolean.arbeitszimmerrollo_aussetzen')\n{\n    context.cover_arzi_aussetzen = msg.payload\n}\nif (msg.data.entity_id === 'cover.arzi_shlsht_fenster')\n{\n    context.cover_arzi_status = msg.data.attributes.current_position\n}\n\nif (msg.data.entity_id === 'input_boolean.badezimmerrollo_aussetzen')\n{\n    context.cover_bazi_aussetzen = msg.payload\n}\nif (msg.data.entity_id === 'cover.bazi_shlsht_fenster')\n{\n    context.cover_bazi_status = msg.data.attributes.current_position\n}\n\n//----------------------------\nif (context.cover_arzi_aussetzen === \"off\" && context.cover_arzi_status === 100)\n{\nmsg.payload =\n\n    {\"service\": \"notify\", data:{\"message\":\"Arbeitszimmer Aussetzen off, status  100\"}}\n  return [msg,null]\n}\n\nif (context.cover_bazi_aussetzen === \"off\" && context.cover_bazi_status === 100)\n{\nmsg.payload =\n\n    {\"service\": \"notify\", data:{\"message\":\"Badezimmer Aussetzen off, status  100\"}}\n  return [null,msg]\n}\n",
        "outputs": 2,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1500,
        "y": 1380,
        "wires": [
            [
                "ffb3cdb229a48952"
            ],
            [
                "ffb3cdb229a48952"
            ]
        ],
        "outputLabels": [
            "Sonnenstand",
            ""
        ]
    },
    {
        "id": "82060ac7f40364b5",
        "type": "inject",
        "z": "6033c466a6e49c53",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 880,
        "y": 1380,
        "wires": [
            [
                "38e4d6300fc6052d",
                "9f7097f6a82744bf",
                "b826085b6b3c72d2",
                "820d6d35d25f9547"
            ]
        ]
    },
    {
        "id": "ffb3cdb229a48952",
        "type": "debug",
        "z": "6033c466a6e49c53",
        "name": "Function Data",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1740,
        "y": 1380,
        "wires": []
    },
    {
        "id": "ddbd0338d04ff2f9",
        "type": "server",
        "name": "wlb-ha01.skynet.loc",
        "version": 2,
        "addon": false,
        "rejectUnauthorizedCerts": false,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": false,
        "heartbeatInterval": "30"
    }
]

Ahh, you are using Home Assistant. It would have been helpful if you had mentioned that in the begining. Which contrib home assistant node are you using? (node-red-contrib-home-????)

Oh my bad you are right. I'm sorry!
I'm using node-red-contrib-home-assistant-websocket

With four msgs going into your function node, each of te four wll be processed seperately. If you need to combine the msgs before processing take a look at the join node.

See this article in the cookbook for an example of how to join messages into one object.

also put a debug node (set to display the complete msg object) on the output of one of the HA nodes and copy/past the results here.

Thereā€™s a great page in the docs (Working with messages : Node-RED) that will explain how to use the debug panel to find the right path to any data item.

Pay particular attention to the part about the buttons that appear under your mouse pointer when you over hover a debug message property in the sidebar.

BX00Cy7yHi

1 Like

YES, that's it. Its working correctly. Perfect!!!
Thank you very very much for your great help!!!

Are there any information I need to provide to help other people when they have this problem?

Explain what you did to get it to work then mark one of the posts as the solution.

Glad you got it working.

1 Like
[
    {
        "id": "ca237f11c6490509",
        "type": "api-current-state",
        "z": "6033c466a6e49c53",
        "name": "CHK: Ist Rollo AZ bereits geƶffnet",
        "server": "ddbd0338d04ff2f9",
        "version": 3,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "cover.arzi_shlsht_fenster",
        "state_type": "str",
        "blockInputOverrides": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "entity"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "arzi2",
                "valueType": "str"
            }
        ],
        "for": 0,
        "forType": "num",
        "forUnits": "minutes",
        "x": 1120,
        "y": 1120,
        "wires": [
            [
                "a189bda238d4ed71"
            ]
        ]
    },
    {
        "id": "c591e66e75895653",
        "type": "join",
        "z": "6033c466a6e49c53",
        "name": "",
        "mode": "custom",
        "build": "object",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": "\\n",
        "joinerType": "str",
        "accumulate": false,
        "timeout": "",
        "count": "2",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "",
        "reduceFixup": "",
        "x": 1590,
        "y": 1000,
        "wires": [
            [
                "6088e2386c5a3173"
            ]
        ]
    },
    {
        "id": "b901675fdea50c48",
        "type": "api-current-state",
        "z": "6033c466a6e49c53",
        "name": "CHK: Ist Rollo AZ aussetzen an?",
        "server": "ddbd0338d04ff2f9",
        "version": 3,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "input_boolean.arbeitszimmerrollo_aussetzen",
        "state_type": "str",
        "blockInputOverrides": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "entity"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "arzi1",
                "valueType": "str"
            }
        ],
        "for": 0,
        "forType": "num",
        "forUnits": "minutes",
        "x": 1120,
        "y": 1040,
        "wires": [
            [
                "c591e66e75895653"
            ]
        ]
    },
    {
        "id": "a189bda238d4ed71",
        "type": "change",
        "z": "6033c466a6e49c53",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "data.attributes.current_position",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1390,
        "y": 1100,
        "wires": [
            [
                "c591e66e75895653"
            ]
        ]
    },
    {
        "id": "1248ffa98b229580",
        "type": "inject",
        "z": "6033c466a6e49c53",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 800,
        "y": 1100,
        "wires": [
            [
                "b901675fdea50c48",
                "ca237f11c6490509",
                "3e0b240261377415",
                "a692a371b4ced6de"
            ]
        ]
    },
    {
        "id": "0dd0fc2185721fe0",
        "type": "debug",
        "z": "6033c466a6e49c53",
        "name": "debug 1",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 1920,
        "y": 1080,
        "wires": []
    },
    {
        "id": "6088e2386c5a3173",
        "type": "function",
        "z": "6033c466a6e49c53",
        "name": "Rollosteuerung",
        "func": "\n//----------------------------\nif (msg.payload.arzi1 === \"off\" && msg.payload.arzi2 === 100)\n{\nmsg.payload =\n\n    {\"service\": \"notify\", data:{\"message\":\"Arbeitszimmer Aussetzen off, status  100\"}}\n  return [msg,null]\n}\n\nif (msg.payload.bazi1 === \"off\" && msg.payload.bazi2 === 100)\n{\nmsg.payload =\n\n    {\"service\": \"notify\", data:{\"message\":\"Badezimmer Aussetzen off, status  100\"}}\n  return [msg,null]\n}\n\n",
        "outputs": 2,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1720,
        "y": 1100,
        "wires": [
            [
                "0dd0fc2185721fe0"
            ],
            []
        ],
        "outputLabels": [
            "Sonnenstand",
            ""
        ]
    },
    {
        "id": "3e0b240261377415",
        "type": "api-current-state",
        "z": "6033c466a6e49c53",
        "name": "CHK: Ist Rollo BZ aussetzen an?",
        "server": "ddbd0338d04ff2f9",
        "version": 3,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "input_boolean.badezimmerrollo_aussetzen",
        "state_type": "str",
        "blockInputOverrides": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "entity"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "bazi1",
                "valueType": "str"
            }
        ],
        "for": 0,
        "forType": "num",
        "forUnits": "minutes",
        "x": 1120,
        "y": 1200,
        "wires": [
            [
                "4e712983e2706850"
            ]
        ]
    },
    {
        "id": "a692a371b4ced6de",
        "type": "api-current-state",
        "z": "6033c466a6e49c53",
        "name": "CHK: Ist Rollo BZ bereits geƶffnet",
        "server": "ddbd0338d04ff2f9",
        "version": 3,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "cover.bazi_shlsht_fenster",
        "state_type": "str",
        "blockInputOverrides": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "entity"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "bazi2",
                "valueType": "str"
            }
        ],
        "for": 0,
        "forType": "num",
        "forUnits": "minutes",
        "x": 1120,
        "y": 1260,
        "wires": [
            [
                "d7b90bcdf50aa039"
            ]
        ]
    },
    {
        "id": "d7b90bcdf50aa039",
        "type": "change",
        "z": "6033c466a6e49c53",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "data.attributes.current_position",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1390,
        "y": 1300,
        "wires": [
            [
                "4e712983e2706850"
            ]
        ]
    },
    {
        "id": "4e712983e2706850",
        "type": "join",
        "z": "6033c466a6e49c53",
        "name": "",
        "mode": "custom",
        "build": "object",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": "\\n",
        "joinerType": "str",
        "accumulate": false,
        "timeout": "",
        "count": "2",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "",
        "reduceFixup": "",
        "x": 1550,
        "y": 1220,
        "wires": [
            [
                "6088e2386c5a3173"
            ]
        ]
    },
    {
        "id": "ddbd0338d04ff2f9",
        "type": "server",
        "name": "wlb-ha01.skynet.loc",
        "version": 2,
        "addon": false,
        "rejectUnauthorizedCerts": false,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": false,
        "heartbeatInterval": "30"
    }
]

First I set topics in the current_state nodes because in manual mode the join node requires topics.
After that I changed my payload from "open" to the current percentage of my shutters (cover.arzi_shlsht_fenster and cover.bazi_shlsht_fenster). Then I sent the msgs from each room (Abeitszimmer and Badezimmer) to their own join node. The join node sends the combined messages to the function node and here I compare my values. Now the output is only one message per room.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.