Getting a unique ID for each node (that doesnt change)

I am trying to build an and gate, without using topics to distinguish the inputs. I would like multiple inject nodes to fire a boolean value to the and gate. If all are true then it outputs true. However, it seems that there is no way to differentiate between the node instances. _msg.id returns a unique id for each occurence. nodeid returns the same id for each node type. What I am looking for is a unique id which references the static node which sent the signal, so that the AND get can store the associated boolean value in a dictionary. I was wondering if there is another way to get this unique id, of if this is not how node-red is intended to be used.

On the basis you're developing a Custom Node for Node RED (one that users can install)

You can take advantage of the hooks API.
https://nodered.org/docs/api/hooks/messaging/

You can subscribe to the event that is triggered when a Message is received,
and if its been received by the Node ID, that this hook resides, store the source Node ID that sent it

Example of the event ( SendEvent)
check if destination.id === this.id and store source.id and use as you see fit

{
    "source": {
        "id": "<node-id>",
        "node": "<node-object>",
        "port": "<index of port being sent on>",
    },
    "destination": {
        "id": "<node-id>",
        "node": undefined,
    },
}

Not true, each node has a unique id (node.id)

node.id will always be the id of this - so in that respect it is true.
to get the node id of the source node - you need to use the Hooks API I provided above.

Yes, there is. Every node has a unique id already.

Sorry Marcus, not sure what you are saying there. The node instances ID has to be unique at all times or Node-RED wouldn't work.

In the runtime or the Editor code, this.id is the ID of the instance of the node. The hooks API is not required.

So....
How do you get the ID of the node that sent the message?
Calling this.id does not return the node id that sent the message.

Example....
This function node cannot get the ID of the inject that sent it
Screenshot 2024-01-15 at 19.55.47

(this is for a custom node)
and as far as I know it, to get the sending ID hooks is needed

The OP wants the Node ID that sent the message, so they can use it as a type of state object for source Node sending the message

But this is in the "Developing nodes" category. As such, not about function nodes.

However, you absolutely can get the node's ID in a function node, simply by referencing node.id

In a function node, this is not relevant in the outer code of the nodes function because that context is globalThis as it is a node.js VM.

Put this code into the top level of a function node's code:

node.warn(globalThis === this)

The output will show true.

To obtain the source ID (automatically) without having to worry about it, in a custom node.
i.e an Inject Node sending a message to the OP's custom node as per requirement.

I am unaware of how without Hooks

Yes, using a function node to send it, you include node.id in the message
(sorry I used this.id to refer to node.id)

but then, its not the inject node that is sending the message, its a function node

Unless the OP used inject as an example :thinking:

I that situation, I don't believe you actually need the source node, only to be able to differentiate? Probably doesn't matter what the id is as long as the two inputs can be differentiated?

In that case, all that is needed is for each separate input to generate an id unique to the input path along the way. That could simply be anything injected in a change node.


Noting that if this WERE a custom node question, then you can (but generally shouldn't) find the upstream node ID.


UPDATE: Actually, I gave up too early - you CAN find the upstream node id in a function node so you only actually need a single one. The node.path contains the upstream node id. But, as mentioned, nodes and node instances should not - generally - want to know this.

1 Like

Close but no cigar :smile:

path is FlowID -> Current Node (I don't think it traverses the message path)

(each calls node.path)

Probably a good thing

Drat, note to self - stop looking at the Node-RED forum after a day a work! One assumption too many.

Yup. It can be done in a custom node but it isn't straight-forward. And certainly isn't recommended.


Anyway, if not talking about custom nodes, there are simpler ways, as mentioned.

1 Like

I am trying to use a hook to receive the source id of the previous node. In this case an inject node. I am getting this error: TypeError: Cannot read properties of undefined (reading 'id'). How should I access the source id for the receiveEvent?

// Example postReceive hook
        RED.hooks.add("postReceive", (receiveEvent) => {
            node.warn(`Message received: ${receiveEvent.msg.payload}`);//true
            node.warn(`Message id: ${receiveEvent.source.id}`);//TypeError: Cannot read properties of undefined (reading 'id')
            
        });

source is only with :

  • onSend
  • preDeliver
  • postDelivery

This is not how NR is intended to be used... at least, not in the way you're trying to do it.

Nodes should not care about who sent them a message; they should care about the message they receive. It would be more Node-RED-like for each Inject node to set msg.topic (for example) and for you to map the boolean against that value - without regard for what node sent it.

The hooks API isn't really intended for this purpose and I'd advise against going down that route.

2 Likes

Sorry, that was my fault, was too taken in of the challenge.
but yes, I wouldn't do this either, and is not a Node RED way.

That being said, there are custom nodes for logic gates that already use that approach by topic. No need to reinvent the wheel. :slightly_smiling_face:

Have a look at: https://flows.nodered.org/node/node-red-contrib-boolean-logic-ultimate

4 Likes

Its like watching The Mandalorian :joy:

3 Likes

This is the way! :nerd_face:

1 Like