1

我正在尝试迭代一个嵌套的 JSON 对象,我从我的 Hue-Bridge 获得一个 HTTP-GET 响应。响应是这样的:

{
    "name": "ViKo",
    "type": "GroupScene",
    "group": "2",
    "lights": [
        "1",
        "2",
        "6",
        "9",
        "11",
        "17",
        "18"
    ],
    "recycle": false,
    "locked": false,
    "picture": "",
    "version": 2,
    "lightstates": {
        "1": {
            "on": false,
            "bri": 254,
            "ct": 230
        },
        "2": {
            "on": false,
            "bri": 254,
            "ct": 230
        },
        "6": {
            "on": true,
            "bri": 254,
            "ct": 230
        },
        "9": {
            "on": false,
            "bri": 254,
            "ct": 230
        },
        "11": {
            "on": true,
            "bri": 254,
            "ct": 230
        },
        "17": {
            "on": true,
            "bri": 254,
            "ct": 230
        },
        "18": {
            "on": true,
            "bri": 254,
            "ct": 230
        }
    }
}

现在我对成员 lightstates 和包含的子对象感兴趣,并使用循环(或类似 thsi 的东西)迭代子项。

我的 Arduino (NodeMCU)-代码如下所示:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <ArduinoJson.h>

void loop()
{

  if (digitalRead(BUTTON) == HIGH)
  {

    //Check WiFi connection status
    if (WiFi.status() == WL_CONNECTED)
    {
      HTTPClient http;
      WiFiClient client;

      http.begin(client, BRIDGE_SCENE_URL + SCENE_VIKO);

      int httpCode = http.GET();
      String payload = http.getString();

      if (httpCode == 200)
      {
        const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60;

        DynamicJsonDocument doc(capacity);
        deserializeJson(doc, payload);
        JsonObject root = doc.as<JsonObject>();

        JsonObject name = root.getMember("lightstates").as<JsonObject>();

        for (JsonPair kv : name)
        {
          Serial.println(kv.key().c_str());
        }

      }

      http.end(); //Close connection

      delay(500);
    }

  }

}

因此,我从 Bridge 获得了有效的 json 响应,但 for 循环不打印任何内容。目标是迭代lightstates并将值放入具有类似于签名的方法中

void changeLightState(int id, boolean on, int bri, int ct)

如果有人对我有想法,那就太好了。

4

1 回答 1

1

如果您仔细观察 json 对象,它lightstates是一个JsonObject, 在其中,每个灯光都是另一个JsonObject由每个灯光的灯光状态组成,因此您正在处理另一个对象的对象内的对象。

所以需要更多的时间来获得你想要的数据,这里是例子:

#include <ArduinoJson.h>

String in = "{\"lightstates\": {\"1\": {\"on\": false,\"bri\": 254,\"ct\": 230},\"2\": {\"on\": false,\"bri\": 125,\"ct\": 120} } }";

void setup() {
  Serial.begin(115200);

  StaticJsonDocument<1024> doc;

  DeserializationError error = deserializeJson(doc, in);

  if (error) {
    Serial.print("deserializeJson() failed: ");
    Serial.println(error.c_str());
    return;
  }

  JsonObject lightstates = doc["lightstates"];  //get lightstates obj
  for (JsonPair light: lightstates) {           //iterate thru each light obj  
    JsonObject lightstate = light.value();      //get lightstates of each light

    int light_id = atoi(light.key().c_str());    
    bool light_on = lightstate["on"];
    int light_bri = lightstate["bri"];
    int light_ct = lightstate["ct"];

    Serial.printf("Light %d: on - %s, bri - %d, ct - %d\n", 
      light_id, 
      light_on ? "true": "false",
      light_bri, 
      light_ct
    );
  }

}

void loop() {

}

这会将数据打印为:

Light 1: on - false, bri - 254, ct - 230
Light 2: on - false, bri - 125, ct - 120
于 2021-08-14T03:14:58.833 回答