0

Parameter file containing MQTT topics as shown below, is read into StaticJsonDocument<1250> DOC variable.

Size of some groups may differ between MCU's, for example sub_topics_win may contain more topics, if MCU is 8 relay unit. For that I need the flexibility to read a specific topic that can differ in size.

What is the rifht way to do it?

{
    "pub_gen_topics": [
        "myHome/Messages",
        "myHome/log",
        "myHome/debug"
    ],
    "pub_topics": [
        "myHome/Cont_A/Avail",
        "myHome/Cont_A/State"
    ],
    "sub_topics": [
        "myHome/Cont_A",
        "myHome/All",
        "myHome/lockdown"
    ],
    "sub_topics_win": [
        "myHome/Windows/gFloor/TwinWindow",
        "myHome/Windows/gFloor/Pergola"
    ],
    "sub_topics_SW": [
        "myHome/Light/int/gFloor/SalAmbient1",
        "myHome/Light/int/gFloor/SalAmbient2",
        "myHome/Light/int/gFloor/Lobby",
        "myHome/Light/int/gFloor/Corridor"
    ],
    "sub_topics_win_g": [
        "myHome/Windows",
        "myHome/Windows/gFloor"
    ],
    "sub_topics_SW_g": [
        "myHome/Light",
        "myHome/Light/int",
        "myHome/Light/int/gFloor/"
    ],
    "ver": 0.1
}
3
  • arduinojson.org/v6/api/jsonarray/size
    – Juraj
    Sep 8, 2022 at 15:23
  • @Juraj I tried to define DOC["pub_gen_topics"], for example, as an array and using size() to get its size, without any luck.
    – guyd
    Sep 8, 2022 at 16:42
  • add some code to the question
    – Juraj
    Sep 8, 2022 at 17:38

2 Answers 2

2

If your question is How can I read each element of an array when I don't know its size?, then simply use a for-loop, like so:

JsonArray sub_topics_win = doc["sub_topics_win"];

for (const char* topic : pub_gen_topics) {
  Serial.println(topic);
}

See also: JsonArray::begin() / end(), JsonArray::size().

2
  • An early try was JsonArray array = DOC["sub_topic_win"].to<JsonArray>();. I tried to create it as an Array by adding .to<JsonArray>()
    – guyd
    Sep 8, 2022 at 18:32
  • 1
    to<JsonArray>() creates an empty array, as<JsonArray>() casts the value to a JsonArray, allowing you to use the for-loop. Sep 8, 2022 at 18:43
0

As I understand, your question is How can I determine the best capacity for a JsonDocument when my input varies?

If that's the case, I recommend that you read How to determine the capacity of the JsonDocument?. Here is an extract from the section "What if my input varies?":

If your program must deserialize a JSON document that changes, you must allocate a JsonDocument that is large enough for the largest valid input. I insist on the term valid because your program doesn't need to support any JSON document, but only the ones relevant to your use case.

Applying this to your problem, you need to put eight topics in each list and pass this document to the ArduinoJson Assistant, which results in a recommended capacity of 3027 bytes on ESP8266. Now, this is a bit large for a StaticJsonDocument, so consider switching to a DynamicJsonDocument.

1
  • Sorry for not explaining myself good enough. Input, as show in my question is considered to be suited in size of 1250. But there is a real life situation that "sub_topics_win" would be consisted of 8 elements and not 2 as shown. When array size is known (2 in show case) I use a for loop of 2 iterations to read that array. And my question is - how can I read an array when is size can vary ?
    – guyd
    Sep 8, 2022 at 17:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.