Skip to main content

Node-RED without a mouse / Node-RED as a library / Write Node-RED flows in YAML / Efficient test harnesses for Node-RED / Headless Node-RED / Improved development cycle times / Now it all makes sense

Project description

Node-BLUE

Node-BLUE is a friendly wrapper around Node-RED.

Node-RED without a mouse / Node-RED as a library / Write Node-RED flows in YAML / Write Node-RED user-defined functions in Python / Efficient test harnesses for Node-RED / True headless Node-RED / Improved development iteration times / Node-RED without needing to take the red pill / Node-BLUE is Node-RED on rails / Now it all makes sense

About

The idea is to embed Node-RED into Python programs, in order to leverage it for a number of use cases, like system automation, software testing, parallel execution, etc.

The project has similar intentions like node-red-embedded-start, offering to interact programmatically with the Node-RED API, with a few bells and whistles.

The other idea is to extend the Node-RED ecosystem by leveraging other programming languages and their ecosystems natively, beyond what JavaScript/NPM can do. We made a start with Python, by using the excellent JSPyBridge package.

Synopsis

Command-line use

Install Node-BLUE and HTTPie, and their prerequisites.

pip install httpie node-blue

There is currently a little manual post-setup procedure.

node-blue setup
wget https://github.com/daq-tools/node-blue/raw/refs/heads/main/package.json
wget https://github.com/daq-tools/node-blue/raw/refs/heads/main/node.importmap
npm install

Start Node-BLUE with a Node-RED flow defining an HTTP/HTML endpoint/responder.

# Launch Node-BLUE/Node-RED.
node-blue launch --flow=examples/flows/http-html-templating.json
node-blue launch --flow=https://github.com/daq-tools/node-blue/raw/main/examples/flows/http-html-templating.json

# Run an example HTTP request.
http http://localhost:1880/hello-form name=Hotzenplotz

Launch a flow which defines a pipeline to converge data from MQTT to [CrateDB].

# Launch Node-BLUE/Node-RED.
node-blue launch --flow=examples/flows/mqtt-to-cratedb.yaml

Library use

import asyncio
from node_blue.core import NodeBlue

async def launch_blue():
    """
    Launch a Node-BLUE instance.
    """
    
    # Configure Node-BLUE instance with Node-RED flow.
    blue = NodeBlue(flow="https://github.com/daq-tools/node-blue/raw/main/examples/flows/http-html-templating.json")

    # Start Node-RED instance.
    blue.start().wait_started()

    # Wait until termination.
    await blue.forever()

if __name__ == "__main__":
    asyncio.run(launch_blue())

Examples

Introduction

Unless otherwise noted, all subsequent examples can be exercised using MQTT. You will start the Mosquitto MQTT broker, subscribe to a topic, and publish a JSON message, which will be processed by a Node-RED flow definition.

All flow definitions implement the same rule, and as such, can be triggered by using the same MQTT messages, outlined below. For demonstration purposes, the transformation rule is very simple: It applies a unit conversion formula to a numeric input parameter, effectively converting value units, from Fahrenheit to Celsius. In order to not mix things up, the outcome will be published to a different MQTT topic.

This effectively demonstrates message routing and republishing capabilities in both terms of content transformation and topic rewriting. The procedures can be applied to any message broker system, we just used MQTT here, because it is so convenient to operate.

docker run --name=mosquitto -it --rm --publish=1883:1883 eclipse-mosquitto:2.0 \
  mosquitto -c /mosquitto-no-auth.conf

Subscribe to the broker to observe the outcome.

mosquitto_sub -t 'testdrive/#' -v

Run an example MQTT publish.

echo '{"temperature": 42.42}' | mosquitto_pub -t 'testdrive/imperial' -l

JSON5 flow format

Start Node-BLUE with a Node-RED flow defining an MQTT topic rewrite and message transformation step. Note that this example uses the JSON5 format, which has a few advantages over regular JSON, like inline comments, and multi-line strings.

wget https://github.com/daq-tools/node-blue/raw/main/examples/flows/mqtt-unit-rewriting.json5
node-blue launch --flow=mqtt-unit-rewriting.json5

This flow snippet demonstrates JSON5 capabilities on behalf of a sensible example.

// The transformation node element uses a function written in JavaScript to convert from
// Fahrenheit to Celsius, and to rewrite the MQTT topic from `imperial` to `metric`.
// The outcome will be the amended MQTT message object, which can be passed to the `mqtt out`
// data sink node without further ado.
{
  "id": "transformation.55460a",
  "type": "function",
  "func": "\
    if (msg.topic.endsWith('imperial')) { \
      msg.payload.temperature = Number.parseFloat(((Number.parseFloat(msg.payload.temperature) - 32) * 5 / 9).toFixed(2)); \
      msg.topic = msg.topic.replace('imperial', 'metric'); \
      return msg; \
    } \
  ",
  "wires": [
    [
      "sink.3539af",
    ]
  ]
}

YAML flow format

You can also use the YAML format for writing flow recipes. The authors believe it offers the best conciseness and convenience, with even better multi-line code blocks, without needing any sorts of line-continuation characters. YAML is already used by the node-red-contrib-flow-manager and node-red-contrib-yaml-storage plugins.

node-blue launch --flow=https://github.com/daq-tools/node-blue/raw/main/examples/flows/mqtt-unit-rewriting.yaml

With this example flow snippet, you will immediately recognize how convenient it is, especially for user-defined functions.

# The transformation node element uses a function written in JavaScript to convert from
# Fahrenheit to Celsius, and to rewrite the MQTT topic from `imperial` to `metric`.
# The outcome will be the amended MQTT message object, which can be passed to the `mqtt out`
# data sink node without further ado.
- id: transformation.55460a
  type: function
  func: |-
    if (msg.topic.endsWith('imperial')) {
      msg.payload.temperature = Number.parseFloat(((Number.parseFloat(msg.payload.temperature) - 32) * 5 / 9).toFixed(2));
      msg.topic = msg.topic.replace('imperial', 'metric');
      return msg;
    }
  wires: [
    [
      "sink.3539af",
    ]
  ]

Python user-defined functions

This time, let's use the Python language, to define a user-defined function within the flow step.

wget https://github.com/daq-tools/node-blue/raw/main/examples/flows/mqtt-routing-python.yaml
node-blue launch --flow=examples/flows/mqtt-routing-python.yaml
# The transformation node element uses a function written in Python to convert from
# Fahrenheit to Celsius, and to rewrite the MQTT topic from `imperial` to `metric`.
# The outcome will be the amended MQTT message object, which can be passed to the `mqtt out`
# data sink node without further ado.
- id: transformation.66571b
  type: python-function
  func: |-
    if msg.topic.endswith("imperial"):
      msg.payload.temperature = round((float(msg.payload.temperature) - 32) * 5 / 9, 2)
      msg.topic = msg.topic.replace("imperial", "metric")
      send(msg)
    done()
  wires: [
    [
      "sink.3539af",
    ]
  ]

References

See also the IBM Data management article about Implementing ETL flows with Node-RED by Ondrej Lehota.

Etymology

To use the name »Node-BLUE« for this project was obvious. However, we discovered that there has been another project called Node-BLUE, referenced below. On the other hand, because it has been archived two years ago already, we think there will not be much harm to reuse that name now.

Acknowledgements

This project bundles a few significant pieces of software and technologies, which a few bright minds invented the other day, and countless authors contributed to. We are only listing inventors of the major application-level components, remember there may be several layers of operating systems beneath, and silicon either.

Thank you!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

node_blue-0.0.0.tar.gz (34.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

node_blue-0.0.0-py3-none-any.whl (30.2 kB view details)

Uploaded Python 3

File details

Details for the file node_blue-0.0.0.tar.gz.

File metadata

  • Download URL: node_blue-0.0.0.tar.gz
  • Upload date:
  • Size: 34.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.11

File hashes

Hashes for node_blue-0.0.0.tar.gz
Algorithm Hash digest
SHA256 8e9384c159e1a8e002bc1f0e31d1d037fe8c31338b442d95c8413e6aca5801bd
MD5 425d61e1f6b0b8ea34bfaa76b7cce35d
BLAKE2b-256 25234dd0daa86b12d8719bcba7a3422652e5894cca7b3477fcaac9236bb90928

See more details on using hashes here.

File details

Details for the file node_blue-0.0.0-py3-none-any.whl.

File metadata

  • Download URL: node_blue-0.0.0-py3-none-any.whl
  • Upload date:
  • Size: 30.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.11

File hashes

Hashes for node_blue-0.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 aa58480199245a30cdb9a39cbff85cdc578a8f803ba5e7b563a067e27b6b28ba
MD5 11faf12caf99c0ca11ba47fd820551b4
BLAKE2b-256 90aec37326bc2b5e26f159da261ba1120645a6ac1322b67f6df40beaa3b68076

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page