如何在Node-RED中进行同步?

时间:2015-12-15 06:41:05

标签: javascript node.js iot node-red

在我目前的项目中,我们正在尝试开发一个简单的应用程序"当我的室温超过某个限制时通知我"。此应用程序的流程图如下:enter image description here

此处,温度传感器正在周期性生成的温度数据,并且感测的数据被发送到CalculateAvgTemp组件。 CalculateAvgTemp组件等待5个样本,然后将计算值传递给DisplayTempController。使用 node.js 编写的CalculateAvgTemp组件代码如下。

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提供功能节点,允许开发人员编写自定义功能。现在,真正的问题从这里开始--- Node-RED自定义函数没有正确实现calculateAvgTemp功能。它不等待5个温度值,并在温度到达时点火。我的问题是 - 这是Node-RED的限制还是我们应该在Node-RED中以不同的方式实现calcuateAvgTemp功能,如果是的话 - 我们如何在Node-RED中实现功能? 以 Node-RED 编写的CalculateAvgTemp代码如下:

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;
}

2 个答案:

答案 0 :(得分:2)

函数节点不需要传递任何东西,如果它没有返回(或返回null),那么流将在那时停止。

您还可以使用context变量将状态存储在函数节点中。这意味着您可以存储传入的最后5个值,并且只有在您拥有全部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;
}

答案 1 :(得分:0)

@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;
  }