如何在 Node-RED 中进行同步?
How to do Sync in Node-RED?
在我当前的项目中,我们正在尝试开发一个简单的应用程序 "Notify me when my room temperature goes beyond the certain limit"。本应用流程图如下:
这里,温度传感器定期产生温度数据,并将感测到的数据发送到CalculateAvgTemp
组件。 CalculateAvgTemp
组件等待 5 个样本,然后将计算值传递给 DisplayTempController
。 CalculateAvgTemp
组件的代码,写在node.js中,如下
var mqtt=require('mqtt');
var client=mqtt.connect('mqtt://test.mosquitto.org:1883');
var NUM_SAMPLE_FOR_AVG=5;
var numSample=0;
var tempCelcius=0;
var currentAvg=0;
client.subscribe('sensorMeasurement');
client.on('message',function(topic,payload){
sensorMeasurement=JSON.parse(payload);
console.log(sensorMeasurement);
if(numSample <= NUM_SAMPLE_FOR_AVG){
numSample = numSample + 1;
if(sensorMeasurement.unitofMeasurement=='F'){
tempCelcius=((sensorMeasurement.tempValue-32)*(5/9));
}
else{
tempCelcius=sensorMeasurement.tempValue;
}
currentAvg=parseFloat(currentAvg)+parseFloat(tempCelcius);
if(numSample==NUM_SAMPLE_FOR_AVG){
//console.log(currentAvg);
currentAvg=currentAvg/NUM_SAMPLE_FOR_AVG;
var avgTemp={"avgTemp":parseFloat(currentAvg),"unitofMeasurement":sensorMeasurement.unitofMeasurement};
client.publish('roomAvgTemp',JSON.stringify(avgTemp));
numSample =0;
currentAvg=0;
}
}
});
我们正在尝试在 Node-RED 中实现 calculateAvgTemp
组件。 Node-RED 提供 function node 允许开发人员编写自定义函数。现在,真正的问题从这里开始 --- Node-RED 自定义函数没有正确实现 calculateAvgTemp
功能。它不会等待 5 个温度值并在温度到达时触发。我的问题是 - 这是 Node-RED 限制还是我们应该在 Node-RED 中以不同方式实现 calcuateAvgTemp
功能,如果是的话 - 我们如何在 Node-RED 中实现功能?
CalculateAvgTemp
写在Node-RED的代码如下:
context.temps = context.temps || [];
sensorMeasurement=JSON.parse(msg.payload);
var tempValue=parseFloat(sensorMeasurement.tempValue);
context.temps.push(tempValue);
if (context.temps.length > 4) {
if (context.temps.length == 6) {
//throw last value away
context.temps.shift();
}
var avg=0;
for (var i=0; i<=context.temps.length; i++) {
avg += context.temps[i];
}
avg = avg/5;
msg.payload = parseFloat(avg);
return msg;
} else {
return null;
}
一个功能节点不需要传递任何东西,如果它不return(或returns null)那么流程将在那个点停止。
您还可以使用 context
变量将状态存储在函数节点中。这意味着您可以存储传入的最后 5 个值,并且只有 return 一些东西,一旦您拥有所有 5 个值来计算平均值。
类似于:
context.temps = context.temps || [];
context.temps.push(msg.payload);
if (context.temps.length > 4) {
if (context.temps.length == 6) {
//throw last value away
context.temps.shift();
}
var avg=0;
for (var i=0; i<context.temps.length; i++) {
avg += context.temps[i];
}
avg = avg/5;
msg.payload = avg;
return msg;
} else {
return null;
}
@hardillb----非常感谢指点。以下是解决方法
context.temps = context.temps || [];
data=JSON.parse(msg.payload);
context.temps.push(data.tempValue);
var NO_OF_SAMPLE=5;
if (context.temps.length > 4) {
var avg=0.0;
for (var i=0; i<NO_OF_SAMPLE; i++) {
avg =parseFloat(avg)+parseFloat(context.temps[i]);
}
avg =avg/NO_OF_SAMPLE;
msg.payload = avg;
context.temps=[];
return msg;
} else {
return null;
}
在我当前的项目中,我们正在尝试开发一个简单的应用程序 "Notify me when my room temperature goes beyond the certain limit"。本应用流程图如下:
这里,温度传感器定期产生温度数据,并将感测到的数据发送到CalculateAvgTemp
组件。 CalculateAvgTemp
组件等待 5 个样本,然后将计算值传递给 DisplayTempController
。 CalculateAvgTemp
组件的代码,写在node.js中,如下
var mqtt=require('mqtt');
var client=mqtt.connect('mqtt://test.mosquitto.org:1883');
var NUM_SAMPLE_FOR_AVG=5;
var numSample=0;
var tempCelcius=0;
var currentAvg=0;
client.subscribe('sensorMeasurement');
client.on('message',function(topic,payload){
sensorMeasurement=JSON.parse(payload);
console.log(sensorMeasurement);
if(numSample <= NUM_SAMPLE_FOR_AVG){
numSample = numSample + 1;
if(sensorMeasurement.unitofMeasurement=='F'){
tempCelcius=((sensorMeasurement.tempValue-32)*(5/9));
}
else{
tempCelcius=sensorMeasurement.tempValue;
}
currentAvg=parseFloat(currentAvg)+parseFloat(tempCelcius);
if(numSample==NUM_SAMPLE_FOR_AVG){
//console.log(currentAvg);
currentAvg=currentAvg/NUM_SAMPLE_FOR_AVG;
var avgTemp={"avgTemp":parseFloat(currentAvg),"unitofMeasurement":sensorMeasurement.unitofMeasurement};
client.publish('roomAvgTemp',JSON.stringify(avgTemp));
numSample =0;
currentAvg=0;
}
}
});
我们正在尝试在 Node-RED 中实现 calculateAvgTemp
组件。 Node-RED 提供 function node 允许开发人员编写自定义函数。现在,真正的问题从这里开始 --- Node-RED 自定义函数没有正确实现 calculateAvgTemp
功能。它不会等待 5 个温度值并在温度到达时触发。我的问题是 - 这是 Node-RED 限制还是我们应该在 Node-RED 中以不同方式实现 calcuateAvgTemp
功能,如果是的话 - 我们如何在 Node-RED 中实现功能?
CalculateAvgTemp
写在Node-RED的代码如下:
context.temps = context.temps || [];
sensorMeasurement=JSON.parse(msg.payload);
var tempValue=parseFloat(sensorMeasurement.tempValue);
context.temps.push(tempValue);
if (context.temps.length > 4) {
if (context.temps.length == 6) {
//throw last value away
context.temps.shift();
}
var avg=0;
for (var i=0; i<=context.temps.length; i++) {
avg += context.temps[i];
}
avg = avg/5;
msg.payload = parseFloat(avg);
return msg;
} else {
return null;
}
一个功能节点不需要传递任何东西,如果它不return(或returns null)那么流程将在那个点停止。
您还可以使用 context
变量将状态存储在函数节点中。这意味着您可以存储传入的最后 5 个值,并且只有 return 一些东西,一旦您拥有所有 5 个值来计算平均值。
类似于:
context.temps = context.temps || [];
context.temps.push(msg.payload);
if (context.temps.length > 4) {
if (context.temps.length == 6) {
//throw last value away
context.temps.shift();
}
var avg=0;
for (var i=0; i<context.temps.length; i++) {
avg += context.temps[i];
}
avg = avg/5;
msg.payload = avg;
return msg;
} else {
return null;
}
@hardillb----非常感谢指点。以下是解决方法
context.temps = context.temps || [];
data=JSON.parse(msg.payload);
context.temps.push(data.tempValue);
var NO_OF_SAMPLE=5;
if (context.temps.length > 4) {
var avg=0.0;
for (var i=0; i<NO_OF_SAMPLE; i++) {
avg =parseFloat(avg)+parseFloat(context.temps[i]);
}
avg =avg/NO_OF_SAMPLE;
msg.payload = avg;
context.temps=[];
return msg;
} else {
return null;
}