Arduinojson: SPIFFS file append does not work when adding data in JSON format (ESP32. ArduinoJSON v1.6)

Created on 22 Dec 2019  路  3Comments  路  Source: bblanchon/ArduinoJson

Hi,

There is a file "/transact.txt", which stores the following data:

{
uid: 123456789
time_start: 2019-12-22 10:35:00
time_stop:
}

The challenge is to replace the contents of time_stop without deleting other elements.

Code:

#include "FS.h" // FS for SPIFFS storage
#include "SPIFFS.h" // SPIFFS storage
#include <ArduinoJson.h> // Json lib for SPIFFS storage
#include <WiFi.h> // Wifi connection lib
#include <esp_wifi.h> // ESP32 wifi system

#define FORMAT_SPIFFS_IF_FAILED true // Storage formatting

  // SPIFFS test variables
  char id_tag[20]; // ID tag
  char t_time_start[30]; // start time
  char t_time_stop[30]; // stop time

  // SPIFFS test functions
  // #1 - SPIFFS write file
  bool write_file(fs::FS &fs, const char * path) {
    Serial.println("Write function start");
    // Open file
    File file = fs.open(path, FILE_WRITE);
    // If file not opened - return false
    if(!file) {
      Serial.println("Fail open file");
      return false;
    }
    // Set JSON file size
    DynamicJsonDocument root(2048); // 1.6 Arduino JSON
    // Set data
    root["idTag"] = "1920823258";
    root["time_start"] = "2019-12-22 12:28:01";
    root["time_stop"] = "";
    // Write file start
    if(serializeJson(root, file) == 0) { // If write fail
      Serial.println("Fail write");
      return false;
    } else { // If write success
      Serial.println("Success write");
      return true;
    }
  }
  // #2 - SPIFFS read file
  bool read_file(fs::FS &fs, const char * path) {
    Serial.println("Start read file function");
    // Open file
    File file = fs.open(path);
    // If open file failed - return false
    if(!file || file.isDirectory()) {
      Serial.println("Fail open file");
      return false;
    }
    // Set JSON document size
    DynamicJsonDocument root(2048); // 1.6 Arduino JSON
    // Parse file data
    deserializeJson(root, file);

    // Get data
    strlcpy(id_tag, root["idTag"], sizeof(id_tag));
    Serial.println(id_tag);

    strlcpy(t_time_start, root["time_start"], sizeof(t_time_start));
    Serial.println(t_time_start);

    strlcpy(t_time_stop, root["time_stop"], sizeof(t_time_stop));
    Serial.println(t_time_stop);

    // Return true
    return true;

  }
  // #3 - SPIFFS file append
  bool append_file(fs::FS &fs, const char * path) {
    Serial.println("Append file start function");
    // Open file
    File file = fs.open(path, FILE_APPEND);
    // If fail opened file - return false
    if(!file) {
      Serial.println("Fail open file");
      return false;
    }
    // Set JSON document size
    DynamicJsonDocument root(2048); // 1.6 Arduino JSON
    // Append data
    root["time_stop"].add("2019-12-23 15:21:05");
    // Write appended data
    if(serializeJson(root, file) == 0) {
      Serial.println("Fail append data");
      return false;
    } else {
      Serial.println("Success append data");
      return true;
    }
  }


  void setup() {
    delay(2500);
    Serial.begin(115200);
    Serial.println("Load");
    if(!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)) {
      return;
    }

    // Write file
    if(write_file(SPIFFS, "/transact.txt")) {
      Serial.println("Success write file");
    }

    delay(250);

    // Read file
    if(read_file(SPIFFS, "/transact.txt")) {
      Serial.println("Success read file");
    }

    delay(250);

    // Append file
    if(append_file(SPIFFS, "/transact.txt")) {
      Serial.println("Success append data to file");
    }

    delay(250);

    // Read file
    if(read_file(SPIFFS, "/transact.txt")) {
      Serial.println("Success read file");
    }

  }

  void loop() {}

After executing the append_file () function, nothing has changed in the time_stop element.

As I try to add:

// Append data
root["time_stop"].add("2019-12-23 15:21:05");

What could be the mistake?

Regards,
Alex

question

All 3 comments

There are a few mistakes in your approach.

Firstly, you can't simply append another value for time_stop to the file, unless you want to make your file look like
{"uid": 123456789,"time_start": "2019-12-22 10:35:00","time_stop": ""}{"time_stop": "2019-12-22 10:40:00"}

If this is not what you want, you need to write the whole file content again. I'd recommend to remove append_file() and to add a parameter for time_stop to write_file().

Secondly, root["time_stop"].add() would only work if root["time_stop"] was an array. But you are using an empty DynamicJsonDocument, and therefore root["time_stop"] is Null. This means that root["time_stop"].add() does nothing. You can check if root["time_stop"].add() is successful by looking at the return value of this method.

And lastly, using an array for time_stop does not even seem to be what you want. So root["time_stop"] = "2019-12-23 15:21:05" would be the way to go.

Hi @DeltaVetal26,

As @codefrey said, to update one value in a JSON file, you must:

  1. deserialize
  2. update
  3. serialize

JsonConfigFile.ino might be a good starting point.

If you do that repeatedly, you could be tempted to keep the JsonDocument in memory, but I strongly recommend against it because you would exhaust the memory pool.

Best regards,
Benoit

@codefrey , @bblanchon ,

Many thanks for the help!

I will use your option to update records.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  7Comments

kylegordon picture kylegordon  路  6Comments

ligantx picture ligantx  路  4Comments

egadgetjnr picture egadgetjnr  路  3Comments

dimityrivanov picture dimityrivanov  路  5Comments