Check exitstence of a key in a JSON object with JsonParserGenerator

mesh
Tags: #<Tag:0x00007fe22b03aad8>

#1

I have a Xenon device in a mesh network that publishes either one of these two json strings.
I’m putting the pattern here:

"{\"PM_atm\":{\"PM1.0\": %d,\"PM2.5\": %d,\"PM10\": %d}}"
or
"{\"Env\":{\"°F\":%.1f,\"°C\":%.1f,\"%%RH\":%.1f,\"lux\":%.1f}}"

On the Argon side, I’d like to use the same handler function called in Mesh.subscribe() to parse either of these, by checking the outer key of the received data if it’s “PM_atm” or “Env”.
What method in JsonParserGenerator class do I need to use and how do I call it?

I already made it work using separate pairs of Mesh.publish()/subscribe() with different event names for each json and then using the JsonParserGenerator to extract the different values but I want a more efficient parsing as I’m planning to publish additional data messages in the future.


#2

While I’m sure there is a way of checking the keys, there is also an alternative revolving around separate event names but one subscription.
Since the subscribe filter is a prefix filter, you can e.g. use "sensor_PM" and "sensor_Env" for your events but subscribe to "sensor_" only to catch both events with the same handler. Then inside that handler you can distinguish between the two by checking the name parameter.

You can also just check whether your data string contains Env or PM_atm before even parsing the data.

And you can use json.getValueByKey() and check the return value. It will be false if the key doesn’t exist.


#3

This has worked for me so far


   JsonParserStatic<256, 20> jsonData;


    jsonData.addString(jsonDocument);
    jsonData.parse();

    const JsonParserGeneratorRK::jsmntok_t *macdObj;
    if (jsonData.getValueTokenByKey(jsonData.getOuterObject(), "PM_atm", macdObj))
    {
      // do stuff
      jsonData.getReference().key("PM_atm").key("PM1.0").valueInt();
    }
    else if (jsonData.getValueTokenByKey(jsonData.getOuterObject(), "Env", macdObj))
    {
      // do stuff
      
    }


#4

That’s one good alternative solution. I thought about using suffixes for my events name for different devices in the network, and I also like extending the idea to the type of data being sent. Thanks @ScruffR!


#5

That’s exactly what I wanted to do. Thanks @shanevanj for the code snippet.