JSON generation with JsonParserGeneratorRK

Hello everyone (and especially @rickkas7 !)

First, I’m new to C++ coding, so apologies if I get my terminology mixed up (if anyone can recommend a good book that’s suitable for me, that would be great - I have loads of experience with very high level languages [esp. Matlab], but I’m navigating in the dark with pointers, objects, classes etc).

I’m collecting data from various sensors. My main loop() calls a function for each sensor, which reads it’s value, creates a JSON string and publishes the result. Ideally, I would like a single (nested) JSON string containing data from all of the sensors. If everything was done within my main loop(), I could do it like this:

JsonWriterStatic<100> meta;
  {
    JsonWriterAutoObject obj(&meta);
    meta.insertKeyValue("deviceId", System.deviceID()); 
  }
JsonWriterStatic<100> data1;
  {
    JsonWriterAutoObject obj(&data1);
    data1.insertKeyValue("sensor1val", sensor1val); 
  }
JsonWriterStatic<100> data2;
  {
    JsonWriterAutoObject obj(&data2);
    data2.insertKeyValue("sensor2val", sensor2val); 
  }
 JsonWriterStatic<400> full;
  {
      JsonWriterAutoObject obj(&full);
      full.insertKeyValue("meta", meta.getBuffer());
      full.insertKeyValue("firstSensor", data1.getBuffer());
      full.insertKeyValue("secondSensor", data2.getBuffer());
   }
Particle.publish("MyData", full.getBuffer(), PRIVATE, WITH_ACK);

What I want to achieve is (pseudocode):

loop() 
{
   JsonWriterStatic<100> meta;
   {
     JsonWriterAutoObject obj(&meta);
     meta.insertKeyValue("deviceId", System.deviceID()); 
   }
   JsonWriterStatic<400> full;
   {
     JsonWriterAutoObject obj(&full);
     full.insertKeyValue("meta", meta.getBuffer());
     full.insertKeyValue("firstSensor", data1.getBuffer());
     full.insertKeyValue("secondSensor", data2.getBuffer());
   }
   Particle.publish("MyData", full.getBuffer(), PRIVATE, WITH_ACK);
}

XXXX mySensor1function()
{
  sensor1val = <read my sensor>;
  JsonWriterStatic<100> data1;
  {
    JsonWriterAutoObject obj(&data1);
    data1.insertKeyValue("sensor1val", sensor1val); 
  }
}

YYYY mySensor2function()
{
  sensor2val = <read my sensor>;
  JsonWriterStatic<100> data2;
  {
    JsonWriterAutoObject obj(&data2);
    data2.insertKeyValue("sensor2val", sensor2val); 
  }
}

I’m uncertain how to pass the JSON object from my functions back to the loop(). Any tips/advice gratefully received!

Thanks

Dave

C++ - try C++ All in one for Dummies (800 pages) - I found it very useful and it helped me get my head around the key concepts.

I don’t use this library to generate JSON but I do use it to Parse JSON. I find it easier to use some macro or #define or const char for common string parts and then snprintf() to format a char array using normal c formatting. One reason I do this is that it is better (IMHO) to format event data payload at the same time rather than as separate parts which are later concatenated.

To answer your questions about the scope of the buffers created by JsonWriterStatic <100> data1; say is limited to the function it was called from hence when control exits from the function the buffer is lost.

To get this data out of the function and back to the calling function (assume this is the loop()) you could define a global variable char eventBuf[622]; and then just copy the generated JSON into this OR you could pass a pointer to a char array in the parameter of the function call (remember that you cannot update the value of a function parameter but if you pass a pointer then that does not change) clearly you need to copy the buffer formatted by the JsonWriter to your char array before exiting.

1 Like

Thanks @armor. I’ve ordered the book :slight_smile:
I’m keen to stick with the library for JSON generation for the time being. It seems quite an elegant way of doing it, but I note your reservations.
I’ll give your suggestions of a global variable or pointer a go. I’m finding C++ to be quite a steep learning curve, so I may be back with a follow-up!