ArduinoJson icon indicating copy to clipboard operation
ArduinoJson copied to clipboard

Getting EmptyInput from deserializeJson when using external json file opened with LittleFS

Open dederomagnolo opened this issue 1 year ago • 4 comments

Describe the issue
Hi all,

First of all thanks for this lib. This is an awesome job and saved me to integrate an esp8266 with a JS stack!

I am having trouble to deserialize an external json file that I am opening with LittleFS. I tried to follow all the available examples and some approaches I found here on the issues, but without success.

Troubleshooter report

  1. The program uses ArduinoJson 6
  2. The issue happens at run time
  3. The issue concerns deserialization
  4. deserializeJson() returns EmptyInput
  5. Input comes from a file
  6. The file is not the problem

Environment
Here is the environment that I'm using':

  • Microconroller: ESP8266
  • Core/runtime: ESP8266 core for Arduino v3.0.2
  • IDE: Arduino IDE 1.8.19

Reproduction

I have the external json file like:

{
   "SERIAL_KEY_PROD": "BLABLA123",
   "BUTTON_PIN": 12 
}
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
#include <ArduinoJson.h>
#include "LittleFS.h"

StaticJsonDocument<1024> configsDoc;

bool loadConfigFile(){
  File deviceConfigFile = LittleFS.open("/dante.json", "r");

  if (!deviceConfigFile) {
    Serial.println("Failed to open device config file");
    return false; 
  }

  size_t fileSize = deviceConfigFile.size();
 
  if (fileSize > 1024) {
    Serial.println("Config file is too large");
    return false;
  }

  String jsonContent = "";

  while(deviceConfigFile.available()) {
    jsonContent = deviceConfigFile.readString();
  }
  
  Serial.println(jsonContent);

  // on this point, I tried to pass the deviceConfigFile and jsonContent as argument, and I got the same result.
  DeserializationError error =  deserializeJson(configsDoc, deviceConfigFile);

  if (error) {
    Serial.println("Failed to parse config file");
    Serial.println(error.f_str());
    return false; 
  }

  deviceConfigFile.close();
  return true;
}

void setup() {
  Serial.begin(115200);
  while(!Serial);

 if(!LittleFS.begin()) {
  Serial.println("Failed to initialize LittleFS");
 }

 bool configsLoaded = loadConfigsFile();

 if(configsLoaded) {
  Serial.println("Configs loaded with success");
 }  else {
  Serial.println("Failed to get the configs from external file");
 }
}

Program output

I can see the json content, so LittleFS is working fine on the task to open the json file and read it but everytime I get the error from the deserialize function from Serial.println(error.f_str()) equal to EmptyInput

Am I missing something before pass the opened json to deserialize function?

dederomagnolo avatar Jan 05 '24 22:01 dederomagnolo

Hi @dederomagnolo,

deviceConfigFile.readString() reads the entire file, placing the playhead at the end. When you call deserializeJson(), there is nothing left to read, so it returns EmptyInput.

To work around this issue, you must either:

  1. remove deviceConfigFile.readString() (preferred)
  2. pass jsonContent to deserializeJson()
  3. call deviceConfigFile.seek(0, SeekSet) before deserializeJson()

Best regards, Benoit

bblanchon avatar Jan 08 '24 10:01 bblanchon

Hi @bblanchon thanksfor your response!

I tried the 1) option removing this part:

  String jsonContent = "";

  while(deviceConfigFile.available()) {
    jsonContent = deviceConfigFile.readString();
  }
  
  Serial.println(jsonContent);

and passing deviceConfigFile directly to desserializeJson() like: DeserializationError error = deserializeJson(configsDoc, deviceConfigFile);

for this approach I got InvalidInput error

For the 2) option I got InvalidInput too.. even callin deviceConfigFile.seek(0, SeekSet) before deserializeJson()

maybe am I missing something on my json file? Is needed to add linebreak chars or something like that? I tried to stringify the JSON, but this approach not worked too.

Thanks in advance!

dederomagnolo avatar Jan 09 '24 22:01 dederomagnolo

I was checking one more thing following the suggestions for InvalidInput on the docs, maybe I am really messing up with chars on my json document but I can't figure out what is going on, cause I just opened a new notepad file extending .json on my windows and added a common json, as described on my first post.

I tried to detect the BOM on my json file, and when I use this:

deviceConfigFile.read();
deviceConfigFile.read();
deserializeJson(configsDoc, deviceConfigFile);

Running this I am able to use deserializeJson(), but still all values returned are null

dederomagnolo avatar Jan 09 '24 23:01 dederomagnolo

What does the troubleshooter say?

bblanchon avatar Jan 11 '24 14:01 bblanchon