Implementing two inputs in Node-RED
Asked Answered
F

3

9

In my current project, we are trying to implement the current application functionality using Node-RED. The functionality is shown below. Here, Fire state receives two inputs: (1) TemperatureSensor (2) SmokeDetector. Both Sensors are publishing data using MQTT publishers. and Firestate component can receives data through MQTT subsciber.

The fire state can produce an output based on the these two parameters that is if temperaturevalue > 70 and Smokevalue == true. In view of this, my question is -- Does Node-RED support the two inputs functionality? If yes, then how can we implement this functionality? If no, then.. Can I say that two input functionality can not be implemented using Node-RED???? As we have seen that Node-RED provides multiple outputs, but not inputs.

enter image description here

Feinstein answered 26/12, 2015 at 17:32 Comment(1)
I think you would need to save the first input somewhere and when the second input comes in you would need to get the first one to use it in if statement. You can't get two inputs at once in this setup. If you didn't use MQTT you could do it differently, your FireState would need in certain interval ask your sensors for current values and use them in if statement.Treasurehouse
B
20

You will need to use a function node and make use of the context variable to keep state between messages and use the message topic to determine which input a message came from.

Something like this:

context.temp = context.temp || 0.0;
context.smoke = context.smoke || false;

if (msg.topic === 'smokeDetector') {
  context.smoke = msg.payload;
} else if (msg.topic === 'tempSensor') {
  context.temp = msg.payload;
}

if (context.temp >= 70.0 && context.smoke) {
  return {topic: 'fireState', payload: 'FIRE!'}
} else {
  return null
}

More details can be found in the function node doc here

Barber answered 26/12, 2015 at 18:35 Comment(2)
Please look at the doc link as the method for accessing the context has changedBarber
Today the documentation prefers using a syntax like this context.get('count')||0;. Prior to 0.13 it is used like described in the answer, afterwards like written here. The method described is deprecated.Hamnet
T
1

You can wire in any number of inputs to any node -- just be aware that your node will only see one input msg at a time. There is no inherent msg aggregation simply because there are multiple input wires.

Instead, the task of aggregating multiple input msgs is handled by certain nodes -- some of which are built in to the core node-red server, and some that have been contributed by the community. Which one you should choose will depend upon the specific use case. For instance, should two objects be appended into an array, or merged into one big object? Only you will know what you want -- node-red does not make any assumptions, but gives you different nodes to handle many common use cases. For any other use cases, there is always the generic function node, in which you can use javascript to implement whatever behavior you need.

For your original question, you are looking for a way to merge 2 payloads from different sensors into a single object. The core join and change nodes can be used for that, as can the node-red-contrib-bool-gate and node-red-contrib-aggregator nodes, found on the flow library site.

Here's an example of combining two sensor inputs using the join node, and then using a switch node with the expression payload.temp > 70 and payload.smoke to determine whether to send the msg down the flow:

[
  {
    "id": "87df68f8.51ad58",
    "type": "inject",
    "z": "f9a2eec9.c2e26",
    "name": "",
    "topic": "smoke",
    "payload": "true",
    "payloadType": "bool",
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": 0.1,
    "x": 160,
    "y": 1180,
    "wires": [
      [
        "da4182a8.47939"
      ]
    ]
  },
  {
    "id": "3ad419ec.1453a6",
    "type": "inject",
    "z": "f9a2eec9.c2e26",
    "name": "",
    "topic": "smoke",
    "payload": "false",
    "payloadType": "bool",
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": 0.1,
    "x": 170,
    "y": 1140,
    "wires": [
      [
        "da4182a8.47939"
      ]
    ]
  },
  {
    "id": "a45b3cb0.f3312",
    "type": "inject",
    "z": "f9a2eec9.c2e26",
    "name": "",
    "topic": "temp",
    "payload": "65",
    "payloadType": "num",
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": 0.1,
    "x": 160,
    "y": 1220,
    "wires": [
      [
        "da4182a8.47939"
      ]
    ]
  },
  {
    "id": "a3b07d81.e6b17",
    "type": "inject",
    "z": "f9a2eec9.c2e26",
    "name": "",
    "topic": "temp",
    "payload": "75",
    "payloadType": "num",
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": 0.1,
    "x": 160,
    "y": 1260,
    "wires": [
      [
        "da4182a8.47939"
      ]
    ]
  },
  {
    "id": "da4182a8.47939",
    "type": "join",
    "z": "f9a2eec9.c2e26",
    "name": "join payloads",
    "mode": "custom",
    "build": "object",
    "property": "payload",
    "propertyType": "msg",
    "key": "topic",
    "joiner": "\n",
    "joinerType": "str",
    "accumulate": true,
    "timeout": "",
    "count": "2",
    "reduceRight": false,
    "reduceExp": "",
    "reduceInit": "",
    "reduceInitType": "",
    "reduceFixup": "",
    "x": 430,
    "y": 1200,
    "wires": [
      [
        "315c9ce3.570d64",
        "50f981b4.be654"
      ]
    ]
  },
  {
    "id": "315c9ce3.570d64",
    "type": "switch",
    "z": "f9a2eec9.c2e26",
    "name": "Trigger Alarm?",
    "property": "payload.temp > 70 and payload.smoke",
    "propertyType": "jsonata",
    "rules": [
      {
        "t": "true"
      }
    ],
    "checkall": "true",
    "repair": false,
    "outputs": 1,
    "x": 640,
    "y": 1200,
    "wires": [
      [
        "50f981b4.be654"
      ]
    ]
  },
  {
    "id": "50f981b4.be654",
    "type": "debug",
    "z": "f9a2eec9.c2e26",
    "name": "",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "false",
    "x": 690,
    "y": 1260,
    "wires": [

    ]
  }
]
Transect answered 4/2, 2018 at 20:13 Comment(0)
E
0

We can use Join Node and change its configuration by setting mode to manual, and use fixed number of messages as 2. Then once both the inputs are received you can invoke next function node. Join node can combine both payload as array or object. And then in last function code you can send the combined data to MQTT after checking your condition.

Engulf answered 6/6, 2018 at 7:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.