【问题标题】:creating/parsing JSON properly [closed]正确创建/解析 JSON [关闭]
【发布时间】:2019-12-04 11:28:02
【问题描述】:

我有一个能够读取温度和湿度的 ESP8266。我们的想法是将这些读数上传到 Firebase 数据库,一旦上传这些数据,就使用 Firebase 的函数触发器采取一些行动。

我有一个从 ESP8622 上传数据的 Arduino 代码。上传的数据是时间戳、传感器 ID、温度和湿度。如下:

void updateDatabase(String &temp, String &humidity, String &temp_feeling)
{

     String path = "/Measurements";
     String SensorID = "1";
     timeClient.update();
    // timeClient.setTimeOffset(3600);

    long timeStamp = timeClient.getEpochTime();
    json.clear().set("id",DEVICE_ID);
    json.set("timestamp",(String)timeStamp);
    json.set("temperature",temp_feeling);
    json.set("humidity",humidity);

    mostrarJSON(json);

    if (Firebase.pushJSON(firebaseData, path,json))
    {
      Serial.println("PASSED");
      Serial.println("PATH: " + firebaseData.dataPath());
      Serial.println("TYPE: " + firebaseData.dataType());
      Serial.println("ETag: " + firebaseData.ETag());
      Serial.print("VALUE: ");
      printResult(firebaseData);
      Serial.println("------------------------------------");
      Serial.println();
    }
    else
    {
      Serial.println("FAILED");
      Serial.println("REASON: " + firebaseData.errorReason());
      Serial.println("------------------------------------");
      Serial.println();
    }

}

此 JSON 已上传到 Firebase 数据库。上传数据的结果如下:

Firebase 函数具有此代码来处理上传的最新测量结果。

exports.onDataAdded = functions.database.ref('/Measurements').onWrite((change,context)=>{

    const snapshot = change.after;
    const val = snapshot.child("").val()
    console.log(val)
    const temperature = snapshot.child("").child("temperature").val()
    const humidity = snapshot.child("").child("humidity").val()

    console.log(`New data received : temp : ${temperature}, humidity : ${humidity}`)

    takeActionSensorUpdate(temperature,humidity)
    return null
})

Firebase 控制台上的代码结果如下:

控制台输出为:

我有一些问题:

  • 我是否在 Arduino 代码上正确构建了 JSON 对象?我应该创建自己的节点名称,而不是为每个测量使用随机的唯一 ID?如果是这样,我该怎么做?
  • 如果我仅在收到来自 ESP8266 的新上传时触发代码,为什么要打印多个数据库实例?
  • 正如您在控制台上看到的,温度和湿度数据显示为空。我想这是因为我在 /Measurements 下添加的每个新测量都有一个自动随机 ID,因为它可以在上传到数据库的对象上看到。如何更改 Firebase 函数的代码以获取我想要的值,在这种情况下是温度和湿度?

非常感谢!

【问题讨论】:

    标签: node.js firebase firebase-realtime-database arduino google-cloud-functions


    【解决方案1】:

    我不了解 Arduino,但我认为以下内容将回答您的问题。

    我是否在 Arduino 代码上正确构建了 JSON 对象?我是不是该 创建我自己的节点名称,而不是为每个节点使用随机唯一 ID 测量?如果是这样,我该怎么做?

    正如我所说,我无法从 Arduino 库的角度回答(我猜您使用此 library),但让数据库使用唯一键(即您的问题中的“节点名称”)生成新的子位置非常标准,正如 doc(例如 JavaScript SDK)中所解释的,它是“向项目集合添加数据的最常见模式”。

    如果我正在触发,为什么要打印多个数据库实例 仅当我收到来自 ESP8266 的新上传时才使用代码?

    这是因为您在 Measurements 节点级别触发了 Cloud Function。 请参阅下面如何为Measurements 的一个特定子节点触发它。

    正如您在控制台上看到的,温度显示为空,并且 湿度数据。我想这是因为我有一个自动随机 ID 可以看到,在 /Measurements 下添加的每个新测量 上载到数据库的对象。如何更改代码 Firebase 函数来获取我想要的值,在这种情况下,温度和 湿度?

    同上原因:change.after代表Measurements节点的数据(触发事件后)。它不代表其中一个孩子的数据。此外,通过执行snapshot.child(""),您将获得undefined 值,因为您将空字符串传递给child()。这是一个可以解决问题的 Cloud Function 代码:

    exports.onDataAdded = functions.database.ref('/Measurements/{pushId}').onWrite((change,context)=>{
    
        const afterData = change.after.val();
        console.log(afterData)
        const temperature = afterData.temperature;
        const humidity = afterData.humidity;
    
        console.log(`New data received : temp : ${temperature}, humidity : ${humidity}`)
    
        takeActionSensorUpdate(temperature,humidity)  //Double check if this is not asynchronous. If yes you need to wait the asynchronous action is done before returning
        return null
    })
    

    正如您将在doc 中读到的,我们使用通配符(用大括号括起来)指定路径组件。换句话说,ref('/Measurements/{pushId}') 匹配 /Measurements 的任何孩子。

    【讨论】:

    • 成功了,非常感谢!
    • @Asaak 很高兴能为您提供帮助,并感谢您接受答案。如果您认为它有帮助,您也可以通过单击答案左侧的大灰色向上箭头来投票。见stackoverflow.com/help/someone-answers。谢谢!
    • 确定我刚刚做到了!最后一个问题:如何将常数温度和常数湿度转换为我可以使用的浮点值,例如,与其他数字进行比较?非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多