/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
 * 
 * This file is part of LoRa APRS iGate.
 * 
 * LoRa APRS iGate is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version.
 * 
 * LoRa APRS iGate is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
 */

#include <ArduinoJson.h>
#include <SPIFFS.h>
#include "configuration.h"
#include "board_pinout.h"
#include "display.h"


bool shouldSleepStop = true;


bool Configuration::writeFile() {
    Serial.println("Saving configuration...");

    StaticJsonDocument<3584> data;
    File configFile = SPIFFS.open("/igate_conf.json", "w");

    if (!configFile) {
        Serial.println("Error: Could not open config file for writing");
        return false;
    }
    try {

        if (wifiAPs[0].ssid != "") { // We don't want to save Auto AP empty SSID
            for (int i = 0; i < wifiAPs.size(); i++) {
                data["wifi"]["AP"][i]["ssid"] = wifiAPs[i].ssid;
                data["wifi"]["AP"][i]["password"] = wifiAPs[i].password;
            }
        }

        data["other"]["startupDelay"]               = startupDelay;

        data["wifi"]["autoAP"]["password"]          = wifiAutoAP.password;
        data["wifi"]["autoAP"]["timeout"]           = wifiAutoAP.timeout;

        callsign.trim();
        callsign.toUpperCase();
        data["callsign"]                            = callsign;

        data["aprs_is"]["active"]                   = aprs_is.active;
        data["aprs_is"]["passcode"]                 = aprs_is.passcode;
        data["aprs_is"]["server"]                   = aprs_is.server;
        data["aprs_is"]["port"]                     = aprs_is.port;
        data["aprs_is"]["filter"]                   = aprs_is.filter;
        data["aprs_is"]["messagesToRF"]             = aprs_is.messagesToRF;
        data["aprs_is"]["objectsToRF"]              = aprs_is.objectsToRF;

        data["beacon"]["comment"]                   = beacon.comment;
        data["beacon"]["interval"]                  = beacon.interval;
        data["beacon"]["latitude"]                  = beacon.latitude;
        data["beacon"]["longitude"]                 = beacon.longitude;
        data["beacon"]["overlay"]                   = beacon.overlay;
        data["beacon"]["symbol"]                    = beacon.symbol;
        data["beacon"]["sendViaAPRSIS"]             = beacon.sendViaAPRSIS;
        data["beacon"]["sendViaRF"]                 = beacon.sendViaRF;
        data["beacon"]["path"]                      = beacon.path;

        data["beacon"]["statusActive"]              = beacon.statusActive;
        data["beacon"]["statusPacket"]              = beacon.statusPacket;

        data["beacon"]["gpsActive"]                 = beacon.gpsActive;
        data["beacon"]["gpsAmbiguity"]              = beacon.gpsAmbiguity;

        data["personalNote"]                        = personalNote;

        data["blacklist"]                           = blacklist;

        data["digi"]["mode"]                        = digi.mode;
        data["digi"]["ecoMode"]                     = digi.ecoMode;
        #if defined(HAS_A7670)
            if (digi.ecoMode == 1) data["digi"]["ecoMode"] = 2;
        #endif
        data["digi"]["beaconOnRxFreq"]              = digi.beaconOnRxFreq;

        data["lora"]["rxActive"]                    = loramodule.rxActive;
        data["lora"]["rxFreq"]                      = loramodule.rxFreq;
        data["lora"]["rxSpreadingFactor"]           = loramodule.rxSpreadingFactor;
        data["lora"]["rxCodingRate4"]               = loramodule.rxCodingRate4;
        data["lora"]["rxSignalBandwidth"]           = loramodule.rxSignalBandwidth;
        data["lora"]["txActive"]                    = loramodule.txActive;      
        data["lora"]["txFreq"]                      = loramodule.txFreq;
        data["lora"]["txSpreadingFactor"]           = loramodule.txSpreadingFactor;
        data["lora"]["txCodingRate4"]               = loramodule.txCodingRate4;
        data["lora"]["txSignalBandwidth"]           = loramodule.txSignalBandwidth;        
        data["lora"]["power"]                       = loramodule.power;        

        data["display"]["alwaysOn"]                 = display.alwaysOn;
        data["display"]["timeout"]                  = display.timeout;
        data["display"]["turn180"]                  = display.turn180;

        data["battery"]["sendInternalVoltage"]      = battery.sendInternalVoltage;
        data["battery"]["monitorInternalVoltage"]   = battery.monitorInternalVoltage;
        data["battery"]["internalSleepVoltage"]     = battery.internalSleepVoltage;

        data["battery"]["sendExternalVoltage"]      = battery.sendExternalVoltage;
        data["battery"]["externalVoltagePin"]       = battery.externalVoltagePin;
        data["battery"]["monitorExternalVoltage"]   = battery.monitorExternalVoltage;
        data["battery"]["externalSleepVoltage"]     = battery.externalSleepVoltage;
        data["battery"]["voltageDividerR1"]         = battery.voltageDividerR1;
        data["battery"]["voltageDividerR2"]         = battery.voltageDividerR2;

        data["battery"]["sendVoltageAsTelemetry"]   = battery.sendVoltageAsTelemetry;

        data["wxsensor"]["active"]                  = wxsensor.active;
        data["wxsensor"]["heightCorrection"]        = wxsensor.heightCorrection;
        data["wxsensor"]["temperatureCorrection"]   = wxsensor.temperatureCorrection;

        data["syslog"]["active"]                    = syslog.active;
        data["syslog"]["server"]                    = syslog.server;
        data["syslog"]["port"]                      = syslog.port;
        data["syslog"]["logBeaconOverTCPIP"]        = syslog.logBeaconOverTCPIP;

        data["tnc"]["enableServer"]                 = tnc.enableServer;
        data["tnc"]["enableSerial"]                 = tnc.enableSerial;
        data["tnc"]["acceptOwn"]                    = tnc.acceptOwn;

        data["mqtt"]["active"]                      = mqtt.active;
        data["mqtt"]["server"]                      = mqtt.server;
        data["mqtt"]["topic"]                       = mqtt.topic;
        data["mqtt"]["username"]                    = mqtt.username;
        data["mqtt"]["password"]                    = mqtt.password;
        data["mqtt"]["port"]                        = mqtt.port;
        data["mqtt"]["beaconOverMqtt"]              = mqtt.beaconOverMqtt;

        data["ota"]["username"]                     = ota.username;
        data["ota"]["password"]                     = ota.password;

        data["webadmin"]["active"]                  = webadmin.active;
        data["webadmin"]["username"]                = webadmin.username;
        data["webadmin"]["password"]                = webadmin.password;

        data["remoteManagement"]["managers"]        = remoteManagement.managers;
        data["remoteManagement"]["rfOnly"]          = remoteManagement.rfOnly;

        data["ntp"]["server"]                       = ntp.server;
        data["ntp"]["gmtCorrection"]                = ntp.gmtCorrection;

        data["other"]["rebootMode"]                 = rebootMode;
        data["other"]["rebootModeTime"]             = rebootModeTime;

        data["other"]["rememberStationTime"]        = rememberStationTime;

        data["other"]["backupDigiMode"]             = backupDigiMode;

        serializeJson(data, configFile);
        configFile.close();
        return true;
    } catch (...) {
        Serial.println("Error: Exception occurred while saving config");
        configFile.close();
        return false;
    }
}

bool Configuration::readFile() {
    Serial.println("Reading config..");
    File configFile = SPIFFS.open("/igate_conf.json", "r");

    if (configFile) {
        bool needsRewrite = false;
        StaticJsonDocument<3584> data;

        DeserializationError error = deserializeJson(data, configFile);
        if (error) {
            Serial.println("Failed to read file, using default configuration");
        }

        JsonArray WiFiArray = data["wifi"]["AP"];
        for (int i = 0; i < WiFiArray.size(); i++) {
            WiFi_AP wifiap;
            wifiap.ssid                   = WiFiArray[i]["ssid"].as<String>();
            wifiap.password               = WiFiArray[i]["password"].as<String>();

            wifiAPs.push_back(wifiap);
        }

        if (!data["other"].containsKey("startupDelay")) needsRewrite = true;
        startupDelay                    = data["other"]["startupDelay"] | 0;

        if (!data["wifi"]["autoAP"].containsKey("password") ||
            !data["wifi"]["autoAP"].containsKey("timeout")) needsRewrite = true;
        wifiAutoAP.password             = data["wifi"]["autoAP"]["password"] | "1234567890";
        wifiAutoAP.timeout              = data["wifi"]["autoAP"]["timeout"] | 10;

        if (!data.containsKey("callsign")) needsRewrite = true;
        callsign                        = data["callsign"] | "NOCALL-10";
        
        if (!data["aprs_is"].containsKey("active") ||
            !data["aprs_is"].containsKey("passcode") ||
            !data["aprs_is"].containsKey("server") ||
            !data["aprs_is"].containsKey("port") ||
            !data["aprs_is"].containsKey("filter") ||
            !data["aprs_is"].containsKey("messagesToRF") ||
            !data["aprs_is"].containsKey("objectsToRF")) needsRewrite = true;
        aprs_is.active                  = data["aprs_is"]["active"] | false;
        aprs_is.passcode                = data["aprs_is"]["passcode"] | "XYZWV";
        aprs_is.server                  = data["aprs_is"]["server"] | "rotate.aprs2.net";
        aprs_is.port                    = data["aprs_is"]["port"] | 14580;
        aprs_is.filter                  = data["aprs_is"]["filter"] | "m/10";
        aprs_is.messagesToRF            = data["aprs_is"]["messagesToRF"] | false;
        aprs_is.objectsToRF             = data["aprs_is"]["objectsToRF"] | false;

        if (!data["beacon"].containsKey("latitude") ||
            !data["beacon"].containsKey("longitude") ||
            !data["beacon"].containsKey("comment") ||
            !data["beacon"].containsKey("interval") ||
            !data["beacon"].containsKey("overlay") ||
            !data["beacon"].containsKey("symbol") ||
            !data["beacon"].containsKey("path") ||
            !data["beacon"].containsKey("sendViaAPRSIS") ||
            !data["beacon"].containsKey("sendViaRF") ||
            !data["beacon"].containsKey("statusActive") ||
            !data["beacon"].containsKey("statusPacket") ||
            !data["beacon"].containsKey("gpsActive") ||
            !data["beacon"].containsKey("gpsAmbiguity")) needsRewrite = true;
        beacon.latitude                 = data["beacon"]["latitude"] | 0.0;
        beacon.longitude                = data["beacon"]["longitude"] | 0.0;
        beacon.comment                  = data["beacon"]["comment"] | "LoRa APRS";
        beacon.interval                 = data["beacon"]["interval"] | 15;
        beacon.overlay                  = data["beacon"]["overlay"] | "L";
        beacon.symbol                   = data["beacon"]["symbol"] | "a";
        beacon.path                     = data["beacon"]["path"] | "WIDE1-1";
        beacon.sendViaAPRSIS            = data["beacon"]["sendViaAPRSIS"] | false;
        beacon.sendViaRF                = data["beacon"]["sendViaRF"] | false;
        beacon.statusActive             = data["beacon"]["statusActive"] | false;
        beacon.statusPacket             = data["beacon"]["statusPacket"] | "";
        beacon.gpsActive                = data["beacon"]["gpsActive"] | false;
        beacon.gpsAmbiguity             = data["beacon"]["gpsAmbiguity"] | false;

        if (!data.containsKey("personalNote")) needsRewrite = true;
        personalNote    	            = data["personalNote"] | "personal note here";

        if (!data.containsKey("blacklist")) needsRewrite = true;
        blacklist                       = data["blacklist"] | "station callsign";

        if (!data["digi"].containsKey("mode") ||
            !data["digi"].containsKey("ecoMode") ||
            !data["digi"].containsKey("beaconOnRxFreq")) needsRewrite = true;
        digi.mode                       = data["digi"]["mode"] | 0;
        digi.ecoMode                    = data["digi"]["ecoMode"] | 0;
        if (digi.ecoMode == 1) shouldSleepStop = false;
        digi.beaconOnRxFreq             = data["digi"]["beaconOnRxFreq"] | false;

        #if defined(HAS_A7670)
            if (digi.ecoMode == 1) digi.ecoMode = 2;
        #endif

        if (!data["lora"].containsKey("rxActive") ||
            !data["lora"].containsKey("rxFreq") ||
            !data["lora"].containsKey("rxSpreadingFactor") ||
            !data["lora"].containsKey("rxCodingRate4") ||
            !data["lora"].containsKey("rxSignalBandwidth") ||
            !data["lora"].containsKey("txActive") ||
            !data["lora"].containsKey("txFreq") ||
            !data["lora"].containsKey("txSpreadingFactor") ||
            !data["lora"].containsKey("txCodingRate4") ||
            !data["lora"].containsKey("txSignalBandwidth") ||
            !data["lora"].containsKey("power")) needsRewrite = true;
        loramodule.rxActive             = data["lora"]["rxActive"] | true;
        loramodule.rxFreq               = data["lora"]["rxFreq"] | 433775000;
        loramodule.rxSpreadingFactor    = data["lora"]["rxSpreadingFactor"] | 12;
        loramodule.rxCodingRate4        = data["lora"]["rxCodingRate4"] | 5;
        loramodule.rxSignalBandwidth    = data["lora"]["rxSignalBandwidth"] | 125000;        
        loramodule.txActive             = data["lora"]["txActive"] | false;
        loramodule.txFreq               = data["lora"]["txFreq"] | 433775000;
        loramodule.txSpreadingFactor    = data["lora"]["txSpreadingFactor"] | 12;
        loramodule.txCodingRate4        = data["lora"]["txCodingRate4"] | 5;
        loramodule.txSignalBandwidth    = data["lora"]["txSignalBandwidth"] | 125000;
        loramodule.power                = data["lora"]["power"] | 20;
        
        if (!data["display"].containsKey("alwaysOn") ||
            !data["display"].containsKey("timeout") ||
            !data["display"].containsKey("turn180")) needsRewrite = true;
        display.alwaysOn                = data["display"]["alwaysOn"] | true;
        display.timeout                 = data["display"]["timeout"] | 4;
        display.turn180                 = data["display"]["turn180"] | false;

        if (!data["battery"].containsKey("sendInternalVoltage") ||
            !data["battery"].containsKey("monitorInternalVoltage") ||
            !data["battery"].containsKey("internalSleepVoltage") ||
            !data["battery"].containsKey("sendExternalVoltage") ||
            !data["battery"].containsKey("externalVoltagePin") ||
            !data["battery"].containsKey("monitorExternalVoltage") ||
            !data["battery"].containsKey("externalSleepVoltage") ||
            !data["battery"].containsKey("voltageDividerR1") ||
            !data["battery"].containsKey("voltageDividerR2") ||
            !data["battery"].containsKey("sendVoltageAsTelemetry")) needsRewrite = true;
        battery.sendInternalVoltage     = data["battery"]["sendInternalVoltage"] | false;
        battery.monitorInternalVoltage  = data["battery"]["monitorInternalVoltage"] | false;
        battery.internalSleepVoltage    = data["battery"]["internalSleepVoltage"] | 2.9;
        battery.sendExternalVoltage     = data["battery"]["sendExternalVoltage"] | false;
        battery.externalVoltagePin      = data["battery"]["externalVoltagePin"] | 34;
        battery.monitorExternalVoltage  = data["battery"]["monitorExternalVoltage"] | false;
        battery.externalSleepVoltage    = data["battery"]["externalSleepVoltage"] | 10.9;
        battery.voltageDividerR1        = data["battery"]["voltageDividerR1"] | 100.0;
        battery.voltageDividerR2        = data["battery"]["voltageDividerR2"] | 27.0;
        battery.sendVoltageAsTelemetry  = data["battery"]["sendVoltageAsTelemetry"] | false;

        if (!data["wxsensor"].containsKey("active") ||
            !data["wxsensor"].containsKey("heightCorrection") ||
            !data["wxsensor"].containsKey("temperatureCorrection")) needsRewrite = true;
        wxsensor.active                 = data["wxsensor"]["active"] | false;
        wxsensor.heightCorrection       = data["wxsensor"]["heightCorrection"] | 0;
        wxsensor.temperatureCorrection  = data["wxsensor"]["temperatureCorrection"] | 0.0;

        if (!data["syslog"].containsKey("active") ||
            !data["syslog"].containsKey("server") ||
            !data["syslog"].containsKey("port") ||
            !data["syslog"].containsKey("logBeaconOverTCPIP")) needsRewrite = true;
        syslog.active                   = data["syslog"]["active"] | false;
        syslog.server                   = data["syslog"]["server"] | "lora.link9.net";
        syslog.port                     = data["syslog"]["port"] | 1514;
        syslog.logBeaconOverTCPIP       = data["syslog"]["logBeaconOverTCPIP"] | false;

        if (!data["tnc"].containsKey("enableServer") ||
            !data["tnc"].containsKey("enableSerial") ||
            !data["tnc"].containsKey("acceptOwn")) needsRewrite = true;
        tnc.enableServer                = data["tnc"]["enableServer"] | false;
        tnc.enableSerial                = data["tnc"]["enableSerial"] | false;
        tnc.acceptOwn                   = data["tnc"]["acceptOwn"] | false;

        if (!data["mqtt"].containsKey("active") ||
            !data["mqtt"].containsKey("server") ||
            !data["mqtt"].containsKey("topic") ||
            !data["mqtt"].containsKey("username") ||
            !data["mqtt"].containsKey("password") ||
            !data["mqtt"].containsKey("port") ||
            !data["mqtt"].containsKey("beaconOverMqtt")) needsRewrite = true;
        mqtt.active                     = data["mqtt"]["active"] | false;
        mqtt.server                     = data["mqtt"]["server"] | "";
        mqtt.topic                      = data["mqtt"]["topic"] | "aprs-igate";
        mqtt.username                   = data["mqtt"]["username"] | "";
        mqtt.password                   = data["mqtt"]["password"] | "";
        mqtt.port                       = data["mqtt"]["port"] | 1883;
        mqtt.beaconOverMqtt             = data["mqtt"]["beaconOverMqtt"] | false;
        
        if (!data["ota"].containsKey("username") ||
            !data["ota"].containsKey("password")) needsRewrite = true;
        ota.username                    = data["ota"]["username"] | "";
        ota.password                    = data["ota"]["password"] | "";

        if (!data["webadmin"].containsKey("active") ||
            !data["webadmin"].containsKey("username") ||
            !data["webadmin"].containsKey("password")) needsRewrite = true;
        webadmin.active                 = data["webadmin"]["active"] | false;
        webadmin.username               = data["webadmin"]["username"] | "admin";
        webadmin.password               = data["webadmin"]["password"] | "";

        if (!data["remoteManagement"].containsKey("managers") ||
            !data["remoteManagement"].containsKey("rfOnly")) needsRewrite = true;
        remoteManagement.managers       = data["remoteManagement"]["managers"] | "";
        remoteManagement.rfOnly         = data["remoteManagement"]["rfOnly"] | true;

        if (!data["ntp"].containsKey("server") ||
            !data["ntp"].containsKey("gmtCorrection")) needsRewrite = true;
        ntp.server                      = data["ntp"]["server"] | "pool.ntp.org";
        ntp.gmtCorrection               = data["ntp"]["gmtCorrection"] | 0.0;

        if (!data["other"].containsKey("rebootMode") ||
            !data["other"].containsKey("rebootModeTime")) needsRewrite = true;
        rebootMode                      = data["other"]["rebootMode"] | false;
        rebootModeTime                  = data["other"]["rebootModeTime"] | 6;

        if (!data["other"].containsKey("rememberStationTime")) needsRewrite = true;
        rememberStationTime             = data["other"]["rememberStationTime"] | 30;

        if (!data["other"].containsKey("backupDigiMode")) needsRewrite = true;
        backupDigiMode                  = data["other"]["backupDigiMode"] | false;

        if (wifiAPs.size() == 0) { // If we don't have any WiFi's from config we need to add "empty" SSID for AUTO AP
            WiFi_AP wifiap;
            wifiap.ssid = "";
            wifiap.password = "";

            wifiAPs.push_back(wifiap);
        }
        configFile.close();

        if (needsRewrite) {
            Serial.println("Config JSON incomplete, rewriting...");
            writeFile();
            delay(1000);
            ESP.restart();
        } 
        Serial.println("Config read successfuly");
        return true;
    } else {
        Serial.println("Config file not found");
        return false;
    }
}
    
void Configuration::setDefaultValues() {

    WiFi_AP wifiap;
    wifiap.ssid                     = "";
    wifiap.password                 = "";

    wifiAPs.push_back(wifiap);

    startupDelay                    = 0;

    wifiAutoAP.password             = "1234567890";
    wifiAutoAP.timeout              = 10;

    callsign                        = "N0CALL-10";

    aprs_is.active                  = false;
    aprs_is.passcode                = "XYZVW";
    aprs_is.server                  = "rotate.aprs2.net";
    aprs_is.port                    = 14580;
    aprs_is.filter                  = "m/10";
    aprs_is.messagesToRF            = false;
    aprs_is.objectsToRF             = false;

    beacon.comment                  = "LoRa APRS";
    beacon.latitude                 = 0.0;
    beacon.longitude                = 0.0;
    beacon.interval                 = 15;
    beacon.overlay                  = "L";
    beacon.symbol                   = "a";
    beacon.sendViaAPRSIS            = true;
    beacon.sendViaRF                = false;
    beacon.path                     = "WIDE1-1";

    beacon.statusActive             = false;
    beacon.statusPacket             = "";    

    beacon.gpsActive                = false;
    beacon.gpsAmbiguity             = false;

    personalNote                    = "";   

    blacklist                       = "";

    digi.mode                       = 0;
    digi.ecoMode                    = 0;
    digi.beaconOnRxFreq             = false;

    loramodule.rxActive             = true;
    loramodule.rxFreq               = 433775000;
    loramodule.rxSpreadingFactor    = 12;
    loramodule.rxCodingRate4        = 5;
    loramodule.rxSignalBandwidth    = 125000;
    loramodule.txActive             = false;
    loramodule.txFreq               = 433775000;
    loramodule.txSpreadingFactor    = 12;
    loramodule.txCodingRate4        = 5;
    loramodule.txSignalBandwidth    = 125000;
    loramodule.power                = 20;

    display.alwaysOn                = true;
    display.timeout                 = 4;
    display.turn180                 = false;
    
    battery.sendInternalVoltage     = false;
    battery.monitorInternalVoltage  = false;
    battery.internalSleepVoltage    = 2.9;

    battery.sendExternalVoltage     = false;
    battery.externalVoltagePin      = 34;
    battery.monitorExternalVoltage  = false;
    battery.externalSleepVoltage    = 10.9;
    battery.voltageDividerR1        = 100.0;
    battery.voltageDividerR2        = 27.0;

    battery.sendVoltageAsTelemetry  = false;

    wxsensor.active                 = false;
    wxsensor.heightCorrection       = 0;
    wxsensor.temperatureCorrection  = 0.0;

    syslog.active                   = false;
    syslog.server                   = "lora.link9.net";
    syslog.port                     = 1514;
    syslog.logBeaconOverTCPIP       = false;

    tnc.enableServer                = false;
    tnc.enableSerial                = false;
    tnc.acceptOwn                   = false;

    mqtt.active                     = false;
    mqtt.server                     = "";
    mqtt.topic                      = "aprs-igate";
    mqtt.username                   = "";
    mqtt.password                   = "";
    mqtt.port                       = 1883;
    mqtt.beaconOverMqtt             = false;

    ota.username                    = "";
    ota.password                    = "";

    webadmin.active                 = false;
    webadmin.username               = "admin";
    webadmin.password               = "";

    remoteManagement.managers       = "";
    remoteManagement.rfOnly         = true;

    ntp.server                      = "pool.ntp.org";
    ntp.gmtCorrection               = 0.0;

    rebootMode                      = false;
    rebootModeTime                  = 0;

    rememberStationTime             = 30;

    backupDigiMode                  = false;

    Serial.println("All is Written!");
}

Configuration::Configuration() {
    if (!SPIFFS.begin(false)) {
        Serial.println("SPIFFS Mount Failed");
        return;
    } else {
        Serial.println("SPIFFS Mounted");
    }

    bool exists = SPIFFS.exists("/igate_conf.json");
    if (!exists) {
        setDefaultValues();
        writeFile();
        delay(1000);
        ESP.restart();
    }

    readFile();
}