Linking 2 or more instances on a local network

Hello

I'm very new to NodeRed, having been introduced to it via openHAB2

I also have a company that distrubutes Velbus hardware, so I have customers that want to have a nice dashboard or UI for their hardware.

One installer asked me if it were possible to link two instances of NodeRed, which has lead me to a lot of reading and not very many "simple" solutions.

So I took it upon myself to create something that "works", I'm not saying it's secure or robust, maybe even has some limitations that I don't fully understand yet, but I though that I might share it here as an alternative for those that just want something simple.

I would welcome any feedback and constructive critisim.

So the premise is that there are two (or more) machines on a local network that are running NodeRed (for reasons that I'm still not entirely sure of, but I'm sure I will be educated at some point)

I understand that one NodeRed instance needs to send simple messages to the other NodeRed instance.

On the sending machine, I have setup a TCP OUT mode, that connects to a port on the Receiving machine.

Messages are contructed in such a way that they can be split at the receiving machine.

For example, an ON & OFF message would be prefixed with an ID number.

  • 1:ON
  • 1:OFF

This set of nodes does this and sends it to port 9000 on the receiving machine

Screenshot 2020-04-15 at 12.05.12 - Edited

[
    {
        "id": "efa5d89c.7614a8",
        "type": "tcp out",
        "z": "bcd03685.5bead8",
        "host": "192.168.178.42",
        "port": "9000",
        "beserver": "client",
        "base64": false,
        "end": true,
        "name": "",
        "x": 570,
        "y": 260,
        "wires": []
    },
    {
        "id": "5bdd1cf.5a6ece4",
        "type": "inject",
        "z": "bcd03685.5bead8",
        "name": "",
        "topic": "",
        "payload": "1:ON",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 90,
        "y": 80,
        "wires": [
            [
                "efa5d89c.7614a8"
            ]
        ]
    },
    {
        "id": "7bceec6c.f97e94",
        "type": "inject",
        "z": "bcd03685.5bead8",
        "name": "",
        "topic": "",
        "payload": "1:OFF",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 270,
        "y": 80,
        "wires": [
            [
                "efa5d89c.7614a8"
            ]
        ]
    },
    {
        "id": "c5731b25.6cd4d8",
        "type": "inject",
        "z": "bcd03685.5bead8",
        "name": "",
        "topic": "",
        "payload": "2:ON",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 90,
        "y": 200,
        "wires": [
            [
                "efa5d89c.7614a8"
            ]
        ]
    },
    {
        "id": "3519eb3b.a58484",
        "type": "inject",
        "z": "bcd03685.5bead8",
        "name": "",
        "topic": "",
        "payload": "2:OFF",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 270,
        "y": 200,
        "wires": [
            [
                "efa5d89c.7614a8"
            ]
        ]
    },
    {
        "id": "ca510eba.dded8",
        "type": "inject",
        "z": "bcd03685.5bead8",
        "name": "",
        "topic": "",
        "payload": "3:ON",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 90,
        "y": 320,
        "wires": [
            [
                "efa5d89c.7614a8"
            ]
        ]
    },
    {
        "id": "52764144.e71c7",
        "type": "inject",
        "z": "bcd03685.5bead8",
        "name": "",
        "topic": "",
        "payload": "3:OFF",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 270,
        "y": 320,
        "wires": [
            [
                "efa5d89c.7614a8"
            ]
        ]
    },
    {
        "id": "7a5127ac.66a918",
        "type": "inject",
        "z": "bcd03685.5bead8",
        "name": "",
        "topic": "",
        "payload": "4:ON",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 90,
        "y": 440,
        "wires": [
            [
                "efa5d89c.7614a8"
            ]
        ]
    },
    {
        "id": "65f003fc.48103c",
        "type": "inject",
        "z": "bcd03685.5bead8",
        "name": "",
        "topic": "",
        "payload": "4:OFF",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 250,
        "y": 440,
        "wires": [
            [
                "efa5d89c.7614a8"
            ]
        ]
    },
    {
        "id": "458954ee.1aacfc",
        "type": "inject",
        "z": "bcd03685.5bead8",
        "name": "",
        "topic": "",
        "payload": "4:1",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 90,
        "y": 480,
        "wires": [
            [
                "efa5d89c.7614a8"
            ]
        ]
    },
    {
        "id": "7f152040.5afb9",
        "type": "inject",
        "z": "bcd03685.5bead8",
        "name": "",
        "topic": "",
        "payload": "4:2",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 250,
        "y": 480,
        "wires": [
            [
                "efa5d89c.7614a8"
            ]
        ]
    },
    {
        "id": "391ccb68.eb00b4",
        "type": "inject",
        "z": "bcd03685.5bead8",
        "name": "",
        "topic": "",
        "payload": "4:1.5",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 90,
        "y": 520,
        "wires": [
            [
                "efa5d89c.7614a8"
            ]
        ]
    },
    {
        "id": "fe69ee81.62e2b",
        "type": "inject",
        "z": "bcd03685.5bead8",
        "name": "3:Words Man, lots of words",
        "topic": "",
        "payload": "3:Words Man, lots of words",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 170,
        "y": 360,
        "wires": [
            [
                "efa5d89c.7614a8"
            ]
        ]
    },
    {
        "id": "84bc4061.2cc19",
        "type": "function",
        "z": "bcd03685.5bead8",
        "name": "Add prefix of  \"5:\"",
        "func": "msg.payload = \"5:\"+(msg.payload);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 280,
        "y": 640,
        "wires": [
            [
                "af5c76ca.c36b28",
                "efa5d89c.7614a8"
            ]
        ]
    },
    {
        "id": "dafc80e3.a3e67",
        "type": "inject",
        "z": "bcd03685.5bead8",
        "name": "",
        "topic": "",
        "payload": "OFF",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 80,
        "y": 620,
        "wires": [
            [
                "84bc4061.2cc19"
            ]
        ]
    },
    {
        "id": "e8375d6d.727fd",
        "type": "inject",
        "z": "bcd03685.5bead8",
        "name": "",
        "topic": "",
        "payload": "ON",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 80,
        "y": 660,
        "wires": [
            [
                "84bc4061.2cc19"
            ]
        ]
    },
    {
        "id": "af5c76ca.c36b28",
        "type": "debug",
        "z": "bcd03685.5bead8",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "x": 270,
        "y": 740,
        "wires": []
    }
]

The receiving machine simply splits the messages up according to the Prefix.

[
    {
        "id": "810a0394.2f0d6",
        "type": "function",
        "z": "a4fb5176.e214b",
        "name": "Split incoming message",
        "func": "var input = String(msg.payload);\nvar msgOUT = (msg.payload);\nmsg.payload = input;\n\n\nvar inputSplit = input.split(\":\");\n\nvar port = inputSplit[0];\nmsgOUT = {payload:inputSplit[1]};\n\nif  (port == 1 ) { \n        return [msgOUT,null, null, null, null];\n\t}\n\t\nif  (port == 2 ) { \n        return [null, msgOUT, null, null, null];\n\t}\n\nif  (port == 3 ) { \n        return [null, null, msgOUT,null, null];\n\t}\n\t\nif  (port == 4 ) { \n        return [null, null, null, msgOUT, null];\n\t}\t\n\n\nif  (port == 5 ) { \n        return [null, null, null, null, msgOUT];\n\t}\n\nreturn [ null, null, null, null ];",
        "outputs": 5,
        "noerr": 0,
        "x": 170,
        "y": 560,
        "wires": [
            [
                "f5b7cb75.eb3c18"
            ],
            [
                "1a4458de.d91057"
            ],
            [
                "c5beafaa.974ef"
            ],
            [
                "9475a5a0.83e4e8"
            ],
            [
                "8dc17d6d.57e4a"
            ]
        ]
    },
    {
        "id": "f5b7cb75.eb3c18",
        "type": "debug",
        "z": "a4fb5176.e214b",
        "name": "",
        "active": true,
        "tosidebar": false,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "x": 370,
        "y": 480,
        "wires": []
    },
    {
        "id": "1a4458de.d91057",
        "type": "debug",
        "z": "a4fb5176.e214b",
        "name": "",
        "active": true,
        "tosidebar": false,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "x": 590,
        "y": 500,
        "wires": []
    },
    {
        "id": "9cd60081.4be",
        "type": "tcp in",
        "z": "a4fb5176.e214b",
        "name": "",
        "server": "server",
        "host": "",
        "port": "9000",
        "datamode": "single",
        "datatype": "utf8",
        "newline": ":",
        "topic": "",
        "base64": false,
        "x": 100,
        "y": 420,
        "wires": [
            [
                "fbc125d3.c1b368",
                "810a0394.2f0d6"
            ]
        ]
    },
    {
        "id": "c5beafaa.974ef",
        "type": "debug",
        "z": "a4fb5176.e214b",
        "name": "",
        "active": true,
        "tosidebar": false,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "x": 410,
        "y": 540,
        "wires": []
    },
    {
        "id": "9475a5a0.83e4e8",
        "type": "debug",
        "z": "a4fb5176.e214b",
        "name": "",
        "active": true,
        "tosidebar": false,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "x": 610,
        "y": 580,
        "wires": []
    },
    {
        "id": "8dc17d6d.57e4a",
        "type": "debug",
        "z": "a4fb5176.e214b",
        "name": "",
        "active": true,
        "tosidebar": false,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "x": 410,
        "y": 660,
        "wires": []
    },
    {
        "id": "fbc125d3.c1b368",
        "type": "debug",
        "z": "a4fb5176.e214b",
        "d": true,
        "name": "",
        "active": true,
        "tosidebar": false,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "x": 350,
        "y": 420,
        "wires": []
    }
]

I appreciate that adding a MQTT server might have been easier, but as I don't know anything about MQTT, I thought I should try something else.
If the needs of this installer's project are more complex, I'll point them to MQTT.

I hope that this helps someone else who just wants something really simple.

Wrong choice I think. You could have learnt what you need to know about MQTT and implemented the communications in half the time it must have taken to build that flow.
Installing and using MQTT is almost trivial and will give you a robust, efficient and well tested solution.

Spend an hour reading the hivemq guide then it takes literally ten minutes to install mosquitto, place a couple of MQTT nodes on the flow and go. Rather than continuing with a two year old thread, if you have any problems then start a new thread please.

1 Like

It would have been easier and more future proofing to read up on MQTT (IMO).

Heres the 30sec intro...

MQTT is a Client Server publish/subscribe messaging transport protocol. It is light weight, open, simple, and designed so as to be easy to implement"

  • An MQTT client (node-red / IoT sensor / whatever) publishes to an MQTT broker
    • a topic and payload are sent in each publish
      • a topic is a string e.g. "house/bedroom/light" or "machine/1/motor/speed"
      • a payload is anything you want (boolean true / string 'on' / JSON '{"i_am_a_property" : "I am a value"}' )
  • anyone subscribed to the same topic will get the payload published

You can even run the whole thing in node-red...

  • install node-red-contrib-aedes from the pallet
  • import this...
[{"id":"7ef0c0cb.93e75","type":"aedes broker","z":"5396dbf2.571004","name":"","mqtt_port":1883,"mqtt_ws_port":"","cert":"","key":"","certname":"","keyname":"","dburl":"","usetls":false,"x":370,"y":100,"wires":[[]]},{"id":"d400ab1c.e5aa98","type":"comment","z":"5396dbf2.571004","name":"NODE RED Server 1","info":"","x":380,"y":60,"wires":[]},{"id":"d0e47698.475c88","type":"comment","z":"5396dbf2.571004","name":"NODE RED Server 2 (lets just pretend)","info":"","x":430,"y":360,"wires":[]},{"id":"bca7954b.6c6f38","type":"mqtt in","z":"5396dbf2.571004","name":"subscribe only to test/topic","topic":"test/topic","qos":"2","datatype":"auto","broker":"4af1f016.58aaa","x":390,"y":160,"wires":[["90624683.dd7b48"]]},{"id":"90624683.dd7b48","type":"debug","z":"5396dbf2.571004","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":670,"y":160,"wires":[]},{"id":"c3ef294f.bd5848","type":"inject","z":"5396dbf2.571004","name":"","topic":"test/topic","payload":"hello from server 2","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":420,"y":420,"wires":[["c828a72a.c256f8"]]},{"id":"c828a72a.c256f8","type":"mqtt out","z":"5396dbf2.571004","name":"","topic":"","qos":"","retain":"","broker":"4af1f016.58aaa","x":630,"y":420,"wires":[]},{"id":"4003927f.a8358c","type":"inject","z":"5396dbf2.571004","name":"","topic":"test/motor/speed","payload":"180","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":400,"y":480,"wires":[["c828a72a.c256f8"]]},{"id":"f21dcebf.1490b","type":"inject","z":"5396dbf2.571004","name":"send multiple values in JSON","topic":"test/data","payload":"{\"name\":\"lucky number\",\"value\":7}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":420,"y":540,"wires":[["c828a72a.c256f8"]]},{"id":"172cfdaa.6e2622","type":"mqtt in","z":"5396dbf2.571004","name":"subscribe to everything after test/","topic":"test/#","qos":"2","datatype":"auto","broker":"4af1f016.58aaa","x":410,"y":200,"wires":[["b17c801a.a37b"]]},{"id":"b17c801a.a37b","type":"debug","z":"5396dbf2.571004","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":670,"y":200,"wires":[]},{"id":"fc86b9d3.1de028","type":"inject","z":"5396dbf2.571004","name":"","topic":"server1/test","payload":"hello from server 1","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":430,"y":260,"wires":[["43565974.6592e8"]]},{"id":"43565974.6592e8","type":"mqtt out","z":"5396dbf2.571004","name":"","topic":"","qos":"","retain":"","broker":"4af1f016.58aaa","x":630,"y":260,"wires":[]},{"id":"db24acf8.d8462","type":"mqtt in","z":"5396dbf2.571004","name":"subscribe to server1/test","topic":"server1/test","qos":"2","datatype":"auto","broker":"4af1f016.58aaa","x":410,"y":600,"wires":[["7a5973a9.7577ec"]]},{"id":"7a5973a9.7577ec","type":"debug","z":"5396dbf2.571004","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":690,"y":600,"wires":[]},{"id":"4af1f016.58aaa","type":"mqtt-broker","z":"","name":"aedes local","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"40","cleansession":true,"birthTopic":"aedes/state","birthQos":"0","birthPayload":"ready","closeTopic":"aedes/state","closeQos":"0","closePayload":"alert","willTopic":"aedes/state","willQos":"0","willPayload":"alert"}]

Bingo...

1 Like

& @Colin
Indeed, if I'd found that bit of information, I would probably have tried running MQTT from within NodeRed.

As for not starting a new thread...

I found this one and read every single word, in search of an answer.
How many other people have done the same and gone away?

I also found a fabulous thread that explored the possibility of creating a version of the LinkIn & LinkOut nodes that spanned instances, but that rabbit hole lead to a dead end.

2 Likes

A thank you would suffice :slight_smile:

It has been covered many many times - finding all necessary info is sometimes a pain, but its all there.

Perhaps a question on here along the lines of "node-red to node-red communication - MQTT or TCP" and stated your intention - perhaps asking for a leg up on MQTT?

It really is that easy - that demo - i wrote in less than 5 minutes (that includes installing node-red-contrib-aedes)

1 Like

Sorry if I've caused any offence.
I just thought I had exhausted the search options, it turns out that I didn't know the correct words.

1 Like

No offence taken - all good.

You will find (on this forum) if you ask a question & you have done some leg work yourself, the people here are amazing (and sometimes answers may seem vague - but that's often to put the OP on the right track to learning rather than providing full solutions)

3 Likes

The last three posts of the thread all said that MQTT is the best solution and one of them included the hivemq tutorial link, so I don't know why anyone would go away without an answer, what information were you missing?

1 Like

Hey @Colin, its a curious thing - I have seen so many people (@MDAR is definitely not the first to) shy away from MQTT because they dont "know it" then spend several hours implementing a "lesser capable" version of MQTT themselves (me included prior to node-red).

I hope the enormous effort I went to (a whole 5 mins) demonstrates how simple it can be.

1 Like

Unless I missed it, I don't think anyone has mentioned security so far.

Although very unlikely in a local network, if the instances are ever publicly exposed, and of course depending upon the nature of the data being transferred, there is always the risk of a 3rd party intercepting your MQTT messages, unless further steps are taken to secure it, using TLS for example.

But hey @MDAR, welcome to the forum. I hope you don't mind, but I've moved these posts to their own thread, as the original was over 2 years old. I've also left a link to this thread for future visitors.

3 Likes

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