Particle.Publish() cuts off after 322 characters

I’m working on publishing a structured JSON string created using JsonParserGeneratorRK and while it appears to be properly formatted according to Serial.print(), when it’s published to the console it gets truncated with the following two terminating characters “�?”. If I remove a list item from the JSON string, bringing the count down to 268 characters, the publish works just fine. And adding an additional element makes it cut off at the same 322 character limit.
The full string is 355 chars (well below the 622 limit) and I’m running a P1 with Dev OS 1.4.2.

This suggests a char array overflow, in that the terminating characters are not printable. Have you had a look inside the library for any such array size constants?

1 Like

Can you try this on your device?
https://go.particle.io/shared_apps/5dc2c2f9afdfb50022478ba4

With my Photon the sketch behaves as expected hence I’d not see the issue in Particle.publish() but rather how the payload is stored in JsonParserVGeneratorRK or any intermediate processing between the library and the publishing instruction.

1 Like

There is a potential issue when using JsonParserGeneratorRK, in that the generated document is stored without being null terminated.

so if you create a document something like this :slight_smile:

        JsonWriterStatic<256> tbPayload;
        tbPayload.startObject();
        tbPayload.insertKeyObject("values");
        tbPayload.insertKeyValue(getAttributeValue(ers), error);
        tbPayload.finishObjectOrArray();
        tbPayload.insertKeyValue("ts", timeMs);
        tbPayload.finishObjectOrArray();

you need to copy that document to your own char array using something like this:

snprintf(tempMsg, tbPayload.getOffset() + 1, "%s", tbPayload.getBuffer());

I originally expected the library to null terminate the document after it was finished.

So may be we need to see some code …

Here's an abbreviated version of what I'm doing

loop(
{
    const char* reading = x.getReading(stuff);
    Serial.println(reading);
    // Conditionals
    Particle.publish("webhookName", reading, PRIVATE, WITH_ACK);
}

const char* x::getReading(std::list<stuff> &r)
{
    JsonWriterStatic<623> jw;
    jw.setFloatPlaces(2);
    { // need obj to go out of scope for obj to properly terminate the buffer
        JsonWriterAutoObject obj(&jw);
        jw.insertKeyValue("1", **);
        jw.insertKeyValue("2", **);
        jw.insertKeyObject("obj");
        jw.insertKeyValue("3", **);
        jw.insertKeyValue("4", *);
        jw.finishObjectOrArray();
        jw.insertKeyArray("arr");
        std::list<stuff>::iterator it;
        for (it = r.begin(); it != r.end(); ++it)
        {
            jw.startObject();
            jw.insertKeyValue("5", it->*);
            jw.insertKeyValue("6", it->*);
            jw.finishObjectOrArray();
        }
        jw.finishObjectOrArray();
    }
    return jw.getBuffer();
}

As stated before printing over serial is giving me what i'm expecting.

Trying that code as is works fine. Though if I try and wrap it in a JSON Key which (should?) add 7 characters I hit the max char limit of 622, despite being at 605 before wrapping.

  JsonWriterStatic<623> jw;
  {
    JsonWriterAutoObject obj(&jw);
    jw.insertKeyValue("key", msg);
  }
  Particle.publish("test", jw.getBuffer(), PRIVATE);

As a side note is there a way to actually pass preformatted JSON through a webhook? I know that the following template will pass back the raw response from the API but it doesn't seem to be working on the sending end. (As I side note it's kinda annoying that I can't see exactly what info the Webhook is sending to the API, only the event data)

{
    "event": "webhook",
    "responseTopic": "{{PARTICLE_DEVICE_ID}}/hook-response/{{PARTICLE_EVENT_NAME}}",
    "errorResponseTopic": "{{PARTICLE_DEVICE_ID}}/hook-error-response/{{PARTICLE_EVENT_NAME}}",
    "url": "***",
    "requestType": "POST",
    "noDefaults": false,
    "rejectUnauthorized": true,
    "responseTemplate": "",
    "json": ""
}

The static buffer for a JSON should usually be about 25-30% bigger than the "raw" data.
On the www you can find some discussion about how to calculate the required buffer size with regards to the depth of your JSON hierarchy and the key count.

1 Like

I love when problems have simple solutions. Didn’t do any math yet but upping to a 1k buffer fixed my issue, will figure out a more precise value later.

You wouldn’t happen to have any insight to my webhook issue would you? I’ve gotten a change to look at the server logs, and as configured above the webhook isn’t passing any data on to my API.

What do you expect to be seen in your response?
I don't see you passing any data on to your target server since your json key has no contents.

I’m trying to pass through the exact JSON string I’m creating in my getReading() function.

getReading()
const char* x::getReading(std::list<stuff> &r)
{
    JsonWriterStatic<623> jw;
    jw.setFloatPlaces(2);
    { // need obj to go out of scope for obj to properly terminate the buffer
        JsonWriterAutoObject obj(&jw);
        jw.insertKeyValue("1", **);
        jw.insertKeyValue("2", **);
        jw.insertKeyObject("obj");
        jw.insertKeyValue("3", **);
        jw.insertKeyValue("4", *);
        jw.finishObjectOrArray();
        jw.insertKeyArray("arr");
        std::list<stuff>::iterator it;
        for (it = r.begin(); it != r.end(); ++it)
        {
            jw.startObject();
            jw.insertKeyValue("5", it->*);
            jw.insertKeyValue("6", it->*);
            jw.finishObjectOrArray();
        }
        jw.finishObjectOrArray();
    }
    return jw.getBuffer();
}

I left nothing in the JSON key as leaving the response template blank will return the full API response through the webhook, which I can then desearilise as needed. I was hoping by leaving the template blank I could achieve a similar result sending data to my API.

This is what you pass to the webhook but your webhook is not forwarding any of that due to this line in your webhook definition

Ah. And I need it to be this:

"json": "{{{PARTICLE_EVENT_VALUE}}}"

Sweet, and now it’s working. Thanks @ScruffR

1 Like