Arduinojson deseralize json

Hi,
I'm using Arduinojson v6.19.4 to program an ESP32 to water my house plants.

The ESP32 sends soil moisture readings via MQTT to Home Assistant which sends MQTT messages to turn water pumps on and off.

Each ESP32 will have multiple pumps attached and info for the pumps will be stored in an array. Home Assistant sends messages similar to the following turn on pumps on and off. The first value ("1" in the example below) will be used to access the pump array.

{ "1" : { "Power" : "ON" } }

My question is how best to deserialize this message: I need to get that first value - the pump number - into a variable. I've developed the following code, but its not particularly elegant. Is there a way to get the pump number into a variable without the for loop?

    if (mqttTopic == mqttClientID + "/Irrigation/Set_Pump") {
      Serial.println ("MQTT Topic / Action  " + mqttTopic + " / " + mqttAction);

      DeserializationError dsErr = deserializeJson (jsonDoc, mqttAction);
      if (dsErr) {
        Serial.print ("Set_Pump: Error parsing mqttAction: ");
        Serial.println (dsErr.f_str());
      }
      else {
        JsonObject jsonObject = jsonDoc.as<JsonObject>();

        for (JsonPair kv : jsonObject) {
          JsonVariant jv = kv.value().as<JsonVariant>();
          Serial.println ("Pump: " + String(kv.key().c_str()) );
          Serial.println ("Power: " + jv ["Power"].as<String>());
        }
      }
    }

Here's the output

19:12:51.057 -> MQTT Topic / Action  ESP32.EE.18/Irrigation/Set_Pump / { "1" : { "Power" :  "ON" } }
19:12:51.057 -> Pump: 1
19:12:51.057 -> Power: ON

BTW, I could change the json to something like the following, but I'm using this sketch as a learning experience as well, so wondering if there is an elegant way to use the json above.

{ "Pump" : "1", "Power" : "ON" }

I appreciate any help I can get!
Thanks

if you can use key/value pairs like this

{ "Pump" : 1,  "Status" : "ON" }

then it's easy to extract the info

StaticJsonDocument<32> doc;
deserializeJson(doc, message);
int pumpID = doc["Pump"];             // ➜ 1
const char* status = doc["Status"];   // ➜  "ON"

note that I did not have the double quotes around 1 so you can treat that directly as a number

Thanks for the feedback Jackson. I was hoping to find an elegant way to read the first json message but if that's not possible, I'll probably resort to a kvp. Good input on the 1 w/o the quotes, saves me a conversion!

if you want to read the first message, because the key is actually one of the variable you want to use, you need to be a bit creative

#include <ArduinoJson.h>

char payload[] = "{\"1\" : { \"Power\" : \"ON\" } }";

void setup() {
  Serial.begin(115200);
  StaticJsonDocument<64> doc;
  DeserializationError error = deserializeJson(doc, payload);

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

  for (JsonPair keyValue : doc.as<JsonObject>()) {
    const char * k = keyValue.key().c_str();
    Serial.printf("Key %s\n", k);
    const char * v = keyValue.value()["Power"].as<const char *>();
    Serial.printf("Value %s\n", v);
  }
}

void loop() {}

this should print

Key 1
Value ON

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.