【问题标题】:How to do Sync in Node-RED?如何在 Node-RED 中进行同步?
【发布时间】:2015-12-15 06:41:04
【问题描述】:

在我当前的项目中,我们正在尝试开发一个简单的应用程序“当我的室温超出特定限制时通知我”。本应用程序流程图如下:

在这里,温度传感器周期性地产生温度数据,并将检测到的数据发送到CalculateAvgTemp 组件。 CalculateAvgTemp 组件等待 5 个样本,然后将计算值传递给 DisplayTempControllerCalculateAvgTemp组件的代码,用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 提供函数节点,允许开发者编写自定义函数。现在,真正的问题从这里开始 --- 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;
}

【问题讨论】:

    标签: javascript node.js iot node-red


    【解决方案1】:

    函数节点不需要传递任何东西,如果它不返回(或返回 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;
    }
    

    【讨论】:

    • @hardilb: 它产生类似的输出: sensorMeasurement : msg.payload : number NaN 15/12/2015, 16:40:38ec595717.13a6a8 sensorMeasurement : msg.payload : number NaN
    • 提供的代码仅供参考,您需要根据实际情况对其进行编辑
    • @hardilb:我已根据要求修改了代码。你能检查一下吗?仍然显示相同的消息:15/12/2015, 17:21:23ec595717.13a6a8 sensorMeasurement : msg.payload : number NaN
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多