Skip to content

When SerializeJson(doc, file) to a file the last charachters are missing in the file #1732

Closed
@chess-levin

Description

@chess-levin

Describe the issue
I'm trying to write a struct with config data to a json file. But the last few characters (always the closing curly brackets) are always missing when I read the file again. My work around is to serialize the data to a json String buffer and then writing this buffer to the file. Why does serializeJson(doc, file) not work correctly?

The complete process looks like this:

  1. While setup of ESP a json file with default_config data is read from SPIFFS.
  2. The config data is deserialized an stored in config data struct.
  3. The user can change config data via web interface.
  4. The browser sends data of changed config as json to ESP8266Server.
  5. Changed config data is deserialized and written into existing config data struct.
  6. Config data struct is serialized and written to a user_config.json file.

Troubleshooter report

ArduinoJson Troubleshooter's report
  1. The issue happens at run time
  2. The issue concerns serialization
  3. Output contains garbage
  4. serializeJson() produces garbage
  5. Program doesn’t call deserializeJson()
  6. Program calls serializeJson(const JsonDocument&, ...)
  7. Program uses DynamicJsonDocument
  8. Program doesn’t use String

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

  • Visual Studio Code & PlatformIO
  • wemos d1 mini
  • bblanchon/ArduinoJson@^6.19.1
    PLATFORM: Espressif 8266 (3.2.0) > Espressif ESP8266 ESP-12E
    HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
    PACKAGES:
  • framework-arduinoespressif8266 3.30002.0 (3.0.2)
  • tool-esptool 1.413.0 (4.13)
  • tool-esptoolpy 1.30000.201119 (3.0.0)
  • tool-mklittlefs 1.203.210628 (2.3)
  • tool-mkspiffs 1.200.0 (2.0)
  • toolchain-xtensa 2.100300.210717 (10.3.0)
    LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
    LDF Modes: Finder ~ chain, Compatibility ~ soft

Reproduction
This is the json structure

{
  "wifi": {
    "hostname": "ESP8266",
    "mdns_host": "esp8266",
    "ssid": "XYZABCAND",
    "key": "123456789012345678901234"
  },
  "ntp": {
    "server": "de.pool.ntp.org",
    "timezone": "CET-1CEST,M3.5.0,M10.5.0/3"
  },
  "assigments": {
    "LED1": 16,
    "LED2": 15,
    "LED3": 14,
    "LED4": 2,
    "LED5": 0,
    "PIR1": 12,
    "PIR2": 13
  },
  "pwm_level": {
    "off": 0,
    "low": 25,
    "high": 100
  },
  "lux": {
    "threshold": 5,
    "readInterval": 10
  },
  "dim": {
    "motionTimeout": 60,
    "pwmStepUp": 8,
    "pwmStepDown": 2,
    "stepInterval": 15
  },
  "schedule": {
    "SO": {
      "on": "08:00",
      "off": "23:30"
    },
    "MO": {
      "on": "06:30",
      "off": "23:15"
    },
    "DI": {
      "on": "06:30",
      "off": "23:15"
    },
    "MI": {
      "on": "06:30",
      "off": "23:15"
    },
    "DO": {
      "on": "06:30",
      "off": "23:15"
    },
    "FR": {
      "on": "06:30",
      "off": "23:30"
    },
    "SA": {
      "on": "07:30",
      "off": "23:30"
    }
  }
}

This is the config struct that holds the config data im memory:

struct WifiCfg {
  char hostname[32];
  char mdns_host[32];
  char ssid[64];
  char key[64];
};

struct NtpCfg {
  char server[32];
  char timezone[32];
};

struct DailySwitching {
  char on[6];
  char off[6];
};

struct GpioAssignments {
  uint8_t ledGpioMapping[5];
  uint8_t pirGpioMapping[2];
};


struct Config {
  struct GpioAssignments assignments;
  struct WifiCfg wifiCfg;
  struct NtpCfg ntpCfg;
  struct DailySwitching schedule[7]; 
  int lux_threshold;
  int lux_readInterval;
  int pwm_off;
  int pwm_low;
  int pwm_high;
  int dim_motionTimeout;
  int dim_pwmStepUp;
  int dim_pwmStepDown;
  int dim_stepInterval;
};

extern struct Config globalCfg;

and this my function to serialize the struct into a DynamicJsonDocument:

void serializeConfig(Config &cfg, bool noCredentials, JsonDocument &doc) {
  PRINTSLN(">> serializeConfig >>");

  // wifi
  doc["wifi"]["hostname"] = cfg.wifiCfg.hostname;
  doc["wifi"]["mdns_host"] = cfg.wifiCfg.mdns_host;
  doc["wifi"]["ssid"] = cfg.wifiCfg.ssid;
  doc["wifi"]["key"] = (noCredentials)? KEY_PLACEHOLDER : cfg.wifiCfg.key;

  //ntp
  doc["ntp"]["server"] = cfg.ntpCfg.server;
  doc["ntp"]["timezone"] = cfg.ntpCfg.timezone;

  // gpio assignments
  doc["assigments"]["LED1"]=cfg.assignments.ledGpioMapping[0];
  doc["assigments"]["LED2"]=cfg.assignments.ledGpioMapping[1];
  doc["assigments"]["LED3"]=cfg.assignments.ledGpioMapping[2];
  doc["assigments"]["LED4"]=cfg.assignments.ledGpioMapping[3];
  doc["assigments"]["LED5"]=cfg.assignments.ledGpioMapping[4];
  doc["assigments"]["PIR1"]=cfg.assignments.pirGpioMapping[0];
  doc["assigments"]["PIR2"]=cfg.assignments.pirGpioMapping[1];

  // pwmLevel
  doc["pwm_level"]["off"] = cfg.pwm_off;
  doc["pwm_level"]["low"] = cfg.pwm_low;
  doc["pwm_level"]["high"] = cfg.pwm_high;

  // lux
  doc["lux"]["threshold"] = cfg.lux_threshold;
  doc["lux"]["readInterval"] = cfg.lux_readInterval;

  // dim
  doc["dim"]["motionTimeout"] = cfg.dim_motionTimeout;
  doc["dim"]["pwmStepUp"] = cfg.dim_pwmStepUp;
  doc["dim"]["pwmStepDown"] = cfg.dim_pwmStepDown;
  doc["dim"]["stepInterval"] = cfg.dim_stepInterval;

  // schedule
  for (int i = 0; i < 7; i++)
  {
    doc["schedule"][weekdays[i]]["on"] = cfg.schedule[i].on; 
    doc["schedule"][weekdays[i]]["off"] = cfg.schedule[i].off;
  }

  serializeJsonPretty(doc, Serial);
  PRINTSLN("\n<< serializeConfig() <<");
}

Program output

Expected output:

{"wifi":{"hostname":"ESP8266","mdns_host":"esp8266","ssid":"XYZABCAND","key":"123456789012345678901234"},"ntp":{"server":"de.pool.ntp.org","timezone":"CET-1CEST,M3.5.0,M10.5.0/3"},"assigments":{"LED1":2,"LED2":16,"LED3":0,"LED4":14,"LED5":15,"PIR1":12,"PIR2":13},"pwm_level":{"off":0,"low":25,"high":100},"lux":{"threshold":5,"readInterval":10},"dim":{"motionTimeout":60,"pwmStepUp":8,"pwmStepDown":2,"stepInterval":15},"schedule":{"SO":{"on":"08:00","off":"23:30"},"MO":{"on":"06:30","off":"23:15"},"DI":{"on":"06:30","off":"23:15"},"MI":{"on":"06:30","off":"23:15"},"DO":{"on":"06:30","off":"23:15"},"FR":{"on":"06:30","off":"23:30"},"SA":{"on":"07:30","off":"23:30"}}}

Actual output:

{"wifi":{"hostname":"ESP8266","mdns_host":"esp8266","ssid":"XYZABCAND","key":"123456789012345678901234"},"ntp":{"server":"de.pool.ntp.org","timezone":"CET-1CEST,M3.5.0,M10.5.0/3"},"assigments":{"LED1":2,"LED2":16,"LED3":0,"LED4":14,"LED5":15,"PIR1":12,"PIR2":13},"pwm_level":{"off":0,"low":25,"high":100},"lux":{"threshold":5,"readInterval":10},"dim":{"motionTimeout":60,"pwmStepUp":8,"pwmStepDown":2,"stepInterval":15},"schedule":{"SO":{"on":"08:00","off":"23:30"},"MO":{"on":"06:30","off":"23:15"},"DI":{"on":"06:30","off":"23:15"},"MI":{"on":"06:30","off":"23:15"},"DO":{"on":"06:30","off":"23:15"},"FR":{"on":"06:30","off":"23:30"},"SA":{"on":"07:30","off":"23:30"���

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions