Git Product home page Git Product logo

node-red-contrib-events's Introduction

node-red-contrib-events

Event broadcast and receive nodes for Node-RED.

This is an alternative take on Node-RED's link-in and link-out core nodes. Those nodes also use JavaScript events thanks to the RED.events object. However, they attach/consume events named after a node ID and those links have to be manually configured.

Instead, this set of nodes name events after the input msg.topic and allow for wildcard links. Configuration is simply specifying the topic in the settings of the event-in node.

So, throw any msg you like to an event-out node. Then add event-in nodes set to the topic string that you want to listen for.

Then for a msg sent to any of the event-out nodes that has the matching msg.topic string, all of the event-in nodes will receive and output the same msg.

THe event-out node supports topic wildcards using *, / is recognised as a namespace separator as with MQTT.

For more complex requirements, there is also an event-return node that lets you return to the originating event-out that an event-in listened for. This allows you to create sub-flows (sub-routines) and loops very easily.

Notes

  • For the most part, nodes like this should be avoided because then can make the tracing of your logic hard if you aren't careful. However, used with care, these are very powerful but simple to use nodes that can greatly simplify certain types of logic.
  • The event handler is shared between the nodes. Event names are the msg.topic prefixed with node-red-contrib-events/. Return events use node-red-contrib-events/return/<node.id>
  • A separate event handler is needed because the Node-RED core devs want to make sure that Node-RED's own event handlers are not used by contributed nodes. These nodes use a separate event handler module that is shared with other nodes from me including node-red-contrib-uibuilder. That means that these nodes will (in the future) interact with uibuilder where needed but are not dependent. Other nodes could also use the same library. Whichever nodes use the library, they will all get the same event handler.
  • The / char in the topic is used as a level (namespace) separator in the same way as with MQTT.
  • Can use either glob-style (*, **) or MQTT-style (+, #) wildcards.
  • The package contains some example flows. Access using the Import examples library in Node-RED.

Contact the author if you want to make use of this package's event system in other nodes.

Installation

To install from the standard npmjs registry: npm install @totallyinformation/node-red-contrib-events

To install from GitHub: npm install TotallyInformation/node-red-contrib-events

The nodes

event-out

As the output of a flow, emits an event who's name is based on the received msg.topic.

There is no need for any configuration.

However, if you wish, you can:

  • Provide a default topic (in case the received msg does not contain one).
  • Allow the received msg to be passed through to the output.
  • Allow the use of an event-return node so that sub-subflows (sub-routines) or loops can be created.

The node adds a msg._eventOriginator array property that records the event-out node ID that is originating the msg. This helps with debugging and tracing of data flows. If a series of event.out nodes are used, each will add an ID to top of the array so that you can see the full path taken and so that the event-return nodes can navigate back up the tree.

The input topic is sanity checked: it must be a string and no more than 255 chars. It should not contain *, # or +

event-in

As the trigger of a flow, listens for events from event-out nodes and passes on the msg received from them.

Needs to have a topic pattern specified in the settings. This can contain wildcards and so listen for multiple topics.

Wildcards can be glob or MQTT style and the / character denotes namespace delimiters (in the same way that MQTT does).

* or + can be used as single-level wildcards, ** or # as multi-level wildcards.

event-return

Allows event-based sub-flows or loops.

Change an event-out node to allow output from an event-return node.

Then create a flow starting with an event-in node, do some processing and end with an event-return node.

The event-return node does not need any configuration, it uses the msg._eventOriginator property from the input msg to route data back to the originating event-out using an internal event sender/listener based on the node ID of the event-out node. In the process, it adds to top of an array msg._eventReturner with the ID of the return node so that you can trace backwards if needed.

You can, however, allow the node to pass messages through to an output if you want to.

You can also override the msg.topic for the output if you wish.

Dependencies

Similar Nodes

  • link-in/link-out are core nodes, they use Node.js's event system but are linked by source/destination node ID rather than by topic. There is currently no return link capability but this is being looked into.
  • node-red-contrib-topic-link - uses sets and a map and may need a deep object copy. Does not use events. Supports MQTT-style wildcards. This is the node most similar to what I'm doing. The basic usage is similar, it is mostly the execution that is different. However, there is no return link capability.
  • node-red-contrib-sub-link - does not use Node.js's native event system and requires configuration. Supports MQTT-style wildcards.
  • node-red-contrib-pubsub - source code not published. They manually do what the native event system does for you. They manually convert msg objects to a string and back. The stringify process isn't wrapped in a try/catch which may be a little fragile. And finally, they don't support wildcard subscriptions.

Change Log

See the CHANGELOG file for details.

To Do

  • Allow though AND return

node-red-contrib-events's People

Contributors

dependabot[bot] avatar totallyinformation avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

node-red-contrib-events's Issues

msg is not cloned for multiple event handlers

Hi Julian,

first: great idea with the event nodes! Actually we just started with something quite similar when we stumbled upon your solution. :)

After a quick test I found a small bug though: When you have more than one event in node reacting to a specific event, changes on the msg object in one flow mean that the msg object also changes in the other.

Take the following flow for example:

[ { "id": "b3bb2a05cbac7ed0", "type": "tab", "label": "parallel", "disabled": false, "info": "", "env": [] }, { "id": "5c3c11eea10385cb", "type": "inject", "z": "b3bb2a05cbac7ed0", "name": "", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 150, "y": 100, "wires": [ [ "093b13a14d9ef0f2" ] ] }, { "id": "093b13a14d9ef0f2", "type": "event-out", "z": "b3bb2a05cbac7ed0", "name": "", "topic": "test", "passthrough": "none", "outputs": 0, "x": 350, "y": 100, "wires": [] }, { "id": "bdee882c91f697de", "type": "event-in", "z": "b3bb2a05cbac7ed0", "name": "", "topic": "test", "x": 130, "y": 220, "wires": [ [ "083ac3446a69ab30" ] ] }, { "id": "ca8d0c76cd7787eb", "type": "debug", "z": "b3bb2a05cbac7ed0", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 550, "y": 220, "wires": [] }, { "id": "6168bcc64f5a949c", "type": "event-in", "z": "b3bb2a05cbac7ed0", "name": "", "topic": "test", "x": 130, "y": 320, "wires": [ [ "d686424c67e9664b" ] ] }, { "id": "5a80987aef35ac30", "type": "debug", "z": "b3bb2a05cbac7ed0", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 550, "y": 320, "wires": [] }, { "id": "083ac3446a69ab30", "type": "change", "z": "b3bb2a05cbac7ed0", "name": "", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "first", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 330, "y": 220, "wires": [ [ "ca8d0c76cd7787eb" ] ] }, { "id": "d686424c67e9664b", "type": "change", "z": "b3bb2a05cbac7ed0", "name": "", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "second", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 330, "y": 320, "wires": [ [ "5a80987aef35ac30" ] ] } ]

It is expected that the one (sub-) flow prints "first" and the second prints "second". But as the msg object is altered in between, both times "second" gets printed.

The solution in my opinion would be to first collect all relevent event handlers and then clone the msg object accordingly before one (cloned) msg object gets passed to one event in node.

Hope this helps!

Cheers, Chris

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.