在 Node-RED 中实现两个输入
Implementing two inputs in Node-RED
在我当前的项目中,我们正在尝试使用 Node-RED 来实现当前的应用程序功能。功能如下所示。这里,Fire 状态接收两个输入:(1) TemperatureSensor
(2) SmokeDetector
。两个传感器都使用 MQTT 发布器发布数据。 Firestate
组件可以通过 MQTT 订阅者接收数据。
火灾状态可以根据这两个参数产生输出if temperaturevalue > 70 and Smokevalue == true
。鉴于此,我的问题是 -- Node-RED 是否支持双输入功能? 如果支持,那么我们如何实现此功能?如果不是,那么.. 我能说两个输入功能不能用 Node-RED 实现吗????正如我们所见,Node-RED 提供 多个输出,但不提供输入 .
您将需要使用功能节点并使用 context
变量来保持消息之间的状态,并使用消息主题来确定消息来自哪个输入。
像这样:
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
}
可以在函数节点文档中找到更多详细信息here
您可以将任意数量的输入连接到任何节点——请注意您的节点一次只能看到一个输入消息。没有固有的味精聚合只是因为有多个输入线。
相反,聚合多个输入消息的任务由某些节点处理——其中一些内置于核心节点-red 服务器,一些由社区提供。您应该选择哪一个取决于具体的用例。例如,应该将两个对象附加到一个数组中,还是合并到一个大对象中?只有你会知道你想要什么——node-red 不做任何假设,而是给你不同的节点来处理许多常见的用例。对于任何其他用例,总是有通用的 function
节点,您可以在其中使用 javascript 来实现您需要的任何行为。
对于您的原始问题,您正在寻找一种方法将来自不同传感器的 2 个有效载荷合并到一个对象中。核心 join
和 change
节点可用于此目的,node-red-contrib-bool-gate
和 node-red-contrib-aggregator
节点也可用于 flow library 站点。
下面是一个使用 join
节点组合两个传感器输入的示例,然后使用带有表达式 payload.temp > 70 and payload.smoke
的 switch
节点来确定是否向下发送消息:
[
{
"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": [
]
}
]
我们可以通过将模式设置为手动来使用Join Node and change its configuration,并使用固定数量的消息作为2。然后一旦收到两个输入,您就可以调用下一个功能节点。加入节点可以将有效负载组合为数组或对象。然后在最后一个功能代码中,您可以在检查您的条件后将组合数据发送到 MQTT。
在我当前的项目中,我们正在尝试使用 Node-RED 来实现当前的应用程序功能。功能如下所示。这里,Fire 状态接收两个输入:(1) TemperatureSensor
(2) SmokeDetector
。两个传感器都使用 MQTT 发布器发布数据。 Firestate
组件可以通过 MQTT 订阅者接收数据。
火灾状态可以根据这两个参数产生输出if temperaturevalue > 70 and Smokevalue == true
。鉴于此,我的问题是 -- Node-RED 是否支持双输入功能? 如果支持,那么我们如何实现此功能?如果不是,那么.. 我能说两个输入功能不能用 Node-RED 实现吗????正如我们所见,Node-RED 提供 多个输出,但不提供输入 .
您将需要使用功能节点并使用 context
变量来保持消息之间的状态,并使用消息主题来确定消息来自哪个输入。
像这样:
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
}
可以在函数节点文档中找到更多详细信息here
您可以将任意数量的输入连接到任何节点——请注意您的节点一次只能看到一个输入消息。没有固有的味精聚合只是因为有多个输入线。
相反,聚合多个输入消息的任务由某些节点处理——其中一些内置于核心节点-red 服务器,一些由社区提供。您应该选择哪一个取决于具体的用例。例如,应该将两个对象附加到一个数组中,还是合并到一个大对象中?只有你会知道你想要什么——node-red 不做任何假设,而是给你不同的节点来处理许多常见的用例。对于任何其他用例,总是有通用的 function
节点,您可以在其中使用 javascript 来实现您需要的任何行为。
对于您的原始问题,您正在寻找一种方法将来自不同传感器的 2 个有效载荷合并到一个对象中。核心 join
和 change
节点可用于此目的,node-red-contrib-bool-gate
和 node-red-contrib-aggregator
节点也可用于 flow library 站点。
下面是一个使用 join
节点组合两个传感器输入的示例,然后使用带有表达式 payload.temp > 70 and payload.smoke
的 switch
节点来确定是否向下发送消息:
[
{
"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": [
]
}
]
我们可以通过将模式设置为手动来使用Join Node and change its configuration,并使用固定数量的消息作为2。然后一旦收到两个输入,您就可以调用下一个功能节点。加入节点可以将有效负载组合为数组或对象。然后在最后一个功能代码中,您可以在检查您的条件后将组合数据发送到 MQTT。