Saving Custum Paramter with WifiManager & Arduinojson 6

1.5k views Asked by At

I'm trying to save an additional custom parameter to wifimanager which is the mqtt server address but all codes available in the library and all over the internet are for Arduinojson 5, I tried upgrading to Arduinojson 6 to the best of my ability. The code runs with no issues, however, when I restart the esp, it is gone. For somereason, it is not saved.

#include <FS.h>                   //this needs to be first, or it all crashes and burns...
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h>          //https://github.com/bblanchon/ArduinoJson
#define TRIGGER_PIN 16

char mqtt_server[40];
bool shouldSaveConfig = false;
void saveConfigCallback () {  Serial.println("Should save config");  shouldSaveConfig = true; }

WiFiManager wifiManager;
WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);

void setup() {  
  Serial.begin(115200);     
  Serial.println("\n Starting");    
  pinMode(TRIGGER_PIN, INPUT);     

//clean FS, for testing
  //SPIFFS.format();

  if (SPIFFS.begin()) {
    Serial.println("** Mounting file system **");
    if (SPIFFS.exists("/config.json")) {
      //file exists, reading and loading
      Serial.println("** Reading config file **");
      File configFile = SPIFFS.open("/config.json", "r");
      if (configFile) {
        size_t size = configFile.size();
        // Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);

        configFile.readBytes(buf.get(), size);
        DynamicJsonDocument doc(1024);
        DeserializationError error = deserializeJson(doc, buf.get());
       
        // Test if parsing succeeds.
        if (error) {
          Serial.print(F("deserializeJson() failed: "));
          Serial.println(error.c_str());
          return;
        }

        strcpy(mqtt_server, doc["mqtt_server"]);     //get the mqtt_server <== you need one of these for each param

      } else {
        Serial.println("** Failed to load json config **");
      }
      configFile.close();
      Serial.println("** Closed file **");
    }
  }
  else {
    Serial.println("** Failed to mount FS **");
  }
  wifiManager.setSaveConfigCallback(saveConfigCallback);
  wifiManager.addParameter(&custom_mqtt_server);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    resetbtn();
  }
  
  Serial.println("connected...yeey :)");

  //read updated parameters
  strcpy(mqtt_server, custom_mqtt_server.getValue());

  //save the custom parameters to FS
  if (shouldSaveConfig) {
  Serial.println("saving config");
    DynamicJsonDocument doc(1024);
    doc["mqtt_server"] = mqtt_server;

    File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile) {
      Serial.println("failed to open config file for writing");
    }

    serializeJson(doc, Serial);
    serializeJson(doc, configFile);    
    configFile.close();
    //end save
  }
}

void loop() {
  resetbtn();
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    resetbtn();
  }
  Serial.println("Connected");
  wifiManager.process();
  saveParamsCallback();
  delay(3000);
}

void resetbtn() { if ( digitalRead(TRIGGER_PIN) == HIGH ) {    wifiManager.startConfigPortal("Horray");    Serial.println("connected...yeey :)");  } }
void saveParamsCallback () {
  Serial.println("Get Params:");
  Serial.print(custom_mqtt_server.getID());
  Serial.print(" : ");
  Serial.println(custom_mqtt_server.getValue());
}

1

There are 1 answers

0
SvMax On

for same purpose instead of using: serializeJson(doc, configFile); i'm using this function and for me work pretty well

// for writing 

bool writeFile(const char * path, const char * message, unsigned int len){

    File file = SPIFFS.open(path, FILE_WRITE);

    if(!file){
        return false;
    }

    if(!file.write((const uint8_t *)message, len)){
        return false;
    }

    return true;
}

for reading i'm using this function

// for reading

int readFile(const char * path, char ** text){
    // retval int - number of characters in the file
    // in case of empty file 0
    // in case of directory or not found -1

    File file = SPIFFS.open(path);
    if(!file || file.isDirectory()){
        return -1;
    }

    int file_lenght = file.size();
    *text = (char*) malloc(file_lenght*sizeof(char));

    for(int i = 0; i < file_lenght; i++){
        
        (*text)[i] = file.read();

    }

    return file_lenght;
}

you can use this function in this way:

#define WIFI_credential_filename "/config.json"

char * wifi_credentials;
int file_len = readFile(WIFI_credential_filename, &wifi_credentials);

// at this point "wifi_credentials" is filled with the content of 
   "/config.json" file

this is my implementation, surely it can be improved but I have tested it and it works