From de9417ff73804930042cbe41f423149880e48ffe Mon Sep 17 00:00:00 2001 From: Ray Jones Date: Sat, 21 Sep 2019 09:58:51 +1000 Subject: [PATCH] Tidied JSON/MQTT topic command decode into UtilClasses.cpp --- src/Afterburner.cpp | 18 +- src/Utility/BTC_JSON.cpp | 589 +++--------------------------------- src/Utility/BTC_JSON.h | 16 +- src/Utility/UtilClasses.cpp | 281 +++++++++++++++++ src/Utility/helpers.h | 3 +- src/WiFi/ABMqtt.cpp | 43 ++- src/WiFi/BTCWebServer.cpp | 93 +++--- 7 files changed, 418 insertions(+), 625 deletions(-) diff --git a/src/Afterburner.cpp b/src/Afterburner.cpp index 378c3ec..e5d7557 100644 --- a/src/Afterburner.cpp +++ b/src/Afterburner.cpp @@ -382,10 +382,10 @@ void setup() { NVstore.init(); NVstore.load(); - initMQTTJSONmoderator(); // prevents JSON for MQTT unless requested - initIPJSONmoderator(); // prevents JSON for IP unless requested - initTimerJSONmoderator(); // prevents JSON for timers unless requested - initSysModerator(); + initJSONMQTTmoderator(); // prevents JSON for MQTT unless requested + initJSONIPmoderator(); // prevents JSON for IP unless requested + initJSONTimermoderator(); // prevents JSON for timers unless requested + initJSONSysModerator(); KeyPad.begin(keyLeft_pin, keyRight_pin, keyCentre_pin, keyUp_pin, keyDown_pin); @@ -1653,13 +1653,13 @@ void doStreaming() Bluetooth.check(); // check for Bluetooth activity GPIOin.manage(); - GPIOout.manage(); + GPIOout.manage(); GPIOalg.manage(); // manage changes in Bluetooth connection status if(Bluetooth.isConnected()) { if(!bBTconnected) { - resetJSONmoderator(); // force full send upon BT client connect + resetAllJSONmoderators(); // force full send upon BT client connect } bBTconnected = true; } @@ -1668,7 +1668,7 @@ void doStreaming() } // manage changes in number of wifi clients if(isWebSocketClientChange()) { - resetJSONmoderator(); // force full send upon number of Wifi clients change + resetAllJSONmoderators(); // force full send upon increase of Wifi clients } DebugPort.handle(); // keep telnet spy alive @@ -1725,12 +1725,12 @@ float getGlowCurrent() #endif } -float getFanSpeed() +int getFanSpeed() { #ifdef RAW_SAMPLES return getHeaterInfo().getFan_Actual(); #else - return FilteredSamples.Fan.getValue(); + return (int)FilteredSamples.Fan.getValue(); #endif } diff --git a/src/Utility/BTC_JSON.cpp b/src/Utility/BTC_JSON.cpp index 7a10dcc..432ba36 100644 --- a/src/Utility/BTC_JSON.cpp +++ b/src/Utility/BTC_JSON.cpp @@ -50,7 +50,6 @@ CModerator SysModerator; bool bTriggerSysParams = false; bool bTriggerDateTime = false; -void validateTimer(int ID); void Expand(std::string& str); bool makeJSONString(CModerator& moderator, char* opStr, int len); bool makeJSONStringEx(CModerator& moderator, char* opStr, int len); @@ -61,6 +60,43 @@ bool makeJSONStringMQTT(CModerator& moderator, char* opStr, int len); bool makeJSONStringIP(CModerator& moderator, char* opStr, int len); void DecodeCmd(const char* cmd, String& payload); +void triggerJSONTimeUpdate() +{ + bTriggerDateTime = true; +} + +void resetJSONTimerModerator(int timerID) +{ + if(timerID) + TimerModerator.reset(timerID-1); + else + TimerModerator.reset(); +} + +void resetJSONIPmoderator() +{ + IPmoderator.reset(); // force IP params to be sent +} + +void resetJSONmoderator(const char* name) +{ + if(name) + JSONmoderator.reset(name); + else + JSONmoderator.reset(); +} + +void resetJSONSysModerator() +{ + SysModerator.reset(); // force MQTT params to be sent + bTriggerSysParams = true; +} + +void resetJSONMQTTmoderator() +{ + MQTTJSONmoderator.reset(); // force MQTT params to be sent +} + void interpretJsonCommand(char* pLine) { if(strlen(pLine) == 0) @@ -81,276 +117,6 @@ void interpretJsonCommand(char* pLine) String payload(it->value.as()); DecodeCmd(it->key, payload); -/* - - if(strcmp("TempDesired", it->key) == 0) { - if( !reqDemand(it->value.as(), false) ) { // this request is blocked if OEM controller active - JSONmoderator.reset("TempDesired"); - } - } - else if(strcmp("RunState", it->key) == 0) { - if(it->value.as()) { - requestOn(); - } - else { - requestOff(); - } - } - else if(strcmp("PumpMin", it->key) == 0) { - setPumpMin(it->value.as()); - } - else if(strcmp("PumpMax", it->key) == 0) { - setPumpMax(it->value.as()); - } - else if(strcmp("FanMin", it->key) == 0) { - setFanMin(it->value.as()); - } - else if(strcmp("FanMax", it->key) == 0) { - setFanMax(it->value.as()); - } - else if(strcmp("CyclicTemp", it->key) == 0) { - setDemandDegC(it->value.as()); // directly set demandDegC - } - else if((strcmp("CyclicOff", it->key) == 0) || (strcmp("ThermostatOvertemp", it->key) == 0)) { - sUserSettings us = NVstore.getUserSettings(); - us.cyclic.Stop = it->value.as(); - if(INBOUNDS(us.cyclic.Stop, 0, 10)) { - if(us.cyclic.Stop > 1) - us.cyclic.Stop--; // internal uses a 1 offset - NVstore.setUserSettings(us); - } - } - else if((strcmp("CyclicOn", it->key) == 0) || (strcmp("ThermostatUndertemp", it->key) == 0)) { - sUserSettings us = NVstore.getUserSettings(); - us.cyclic.Start = it->value.as(); - if(INBOUNDS(us.cyclic.Start, -20, 0)) - NVstore.setUserSettings(us); - } - else if(strcmp("ThermostatMethod", it->key) == 0) { - sUserSettings settings = NVstore.getUserSettings(); - settings.ThermostatMethod = it->value.as(); - if(INBOUNDS(settings.ThermostatMethod, 0, 3)) - NVstore.setUserSettings(settings); - } - else if(strcmp("ThermostatWindow", it->key) == 0) { - sUserSettings settings = NVstore.getUserSettings(); - settings.ThermostatWindow = it->value.as(); - if(INBOUNDS(settings.ThermostatWindow, 0.2f, 10.f)) - NVstore.setUserSettings(settings); - } - else if(strcmp("Thermostat", it->key) == 0) { - if(!setThermostatMode(it->value.as())) { // this request is blocked if OEM controller active - JSONmoderator.reset("ThermoStat"); - } - } - else if(strcmp("ExtThermoTmout", it->key) == 0) { - sUserSettings us = NVstore.getUserSettings(); - us.ExtThermoTimeout = it->value.as(); - if(INBOUNDS(us.ExtThermoTimeout, 0, 3600000)) - NVstore.setUserSettings(us); - } - else if(strcmp("NVsave", it->key) == 0) { - if(it->value.as() == 8861) - saveNV(); - } - else if(strcmp("Watchdog", it->key) == 0) { - doJSONwatchdog(it->value.as()); - } - else if(strcmp("DateTime", it->key) == 0) { - setDateTime(it->value.as()); - bTriggerDateTime = true; - } - else if(strcmp("Date", it->key) == 0) { - setDate(it->value.as()); - bTriggerDateTime = true; - } - else if(strcmp("Time", it->key) == 0) { - setTime(it->value.as()); - bTriggerDateTime = true; - } - else if(strcmp("Time12hr", it->key) == 0) { - sUserSettings us = NVstore.getUserSettings(); - us.clock12hr = it->value.as() ? 1 : 0; - NVstore.setUserSettings(us); - NVstore.save(); - } - else if(strcmp("PumpPrime", it->key) == 0) { - reqPumpPrime(it->value.as()); - } - else if(strcmp("Refresh", it->key) == 0) { - resetJSONmoderator(); - refreshMQTT(); - } - else if(strcmp("SystemVoltage", it->key) == 0) { - setSystemVoltage(it->value.as()); - } - else if(strcmp("TimerDays", it->key) == 0) { - // value encoded as "ID Days,Days" - decodeJSONTimerDays(it->value.as()); - } - else if(strcmp("TimerStart", it->key) == 0) { - // value encoded as "ID HH:MM" - decodeJSONTimerTime(0, it->value.as()); - } - else if(strcmp("TimerStop", it->key) == 0) { - // value encoded as "ID HH:MM" - decodeJSONTimerTime(1, it->value.as()); - } - else if(strcmp("TimerRepeat", it->key) == 0) { - // value encoded as "ID val" - decodeJSONTimerNumeric(0, it->value.as()); - } - else if(strcmp("TimerTemp", it->key) == 0) { - decodeJSONTimerNumeric(1, it->value.as()); - } - else if(strcmp("TimerConflict", it->key) == 0) { - validateTimer(it->value.as()); - } - // request specific timer refresh - else if((strcmp("TQuery", it->key) == 0) || (strcmp("TimerRefresh", it->key) == 0) ) { - int timerID = it->value.as(); - if(timerID) - TimerModerator.reset(timerID-1); - else - TimerModerator.reset(); - } - else if(strcmp("FanSensor", it->key) == 0) { - setFanSensor(it->value.as()); - } - else if(strcmp("IQuery", it->key) == 0) { - IPmoderator.reset(); // force IP params to be sent - } - // system info - else if(strcmp("SQuery", it->key) == 0) { - SysModerator.reset(); // force MQTT params to be sent - bTriggerSysParams = true; - } - // MQTT parameters - else if(strcmp("MQuery", it->key) == 0) { - MQTTJSONmoderator.reset(); // force MQTT params to be sent - } - else if(strcmp("MEn", it->key) == 0) { - sMQTTparams info = NVstore.getMQTTinfo(); - info.enabled = it->value.as(); - NVstore.setMQTTinfo(info); - } - else if(strcmp("MPort", it->key) == 0) { - sMQTTparams info = NVstore.getMQTTinfo(); - info.port = it->value.as(); - NVstore.setMQTTinfo(info); - } - else if(strcmp("MHost", it->key) == 0) { - sMQTTparams info = NVstore.getMQTTinfo(); - strncpy(info.host, it->value.as(), 127); - info.host[127] = 0; - NVstore.setMQTTinfo(info); - } - else if(strcmp("MUser", it->key) == 0) { - sMQTTparams info = NVstore.getMQTTinfo(); - strncpy(info.username, it->value.as(), 31); - info.username[31] = 0; - NVstore.setMQTTinfo(info); - } - else if(strcmp("MPasswd", it->key) == 0) { - sMQTTparams info = NVstore.getMQTTinfo(); - strncpy(info.password, it->value.as(), 31); - info.password[31] = 0; - NVstore.setMQTTinfo(info); - } - else if(strcmp("MQoS", it->key) == 0) { - sMQTTparams info = NVstore.getMQTTinfo(); - info.qos = it->value.as(); - if(INBOUNDS(info.qos, 0, 2)) { - NVstore.setMQTTinfo(info); - } - } - else if(strcmp("MTopic", it->key) == 0) { - sMQTTparams info = NVstore.getMQTTinfo(); - strncpy(info.topic, it->value.as(), 31); - info.topic[31] = 0; - NVstore.setMQTTinfo(info); - } - else if(strcmp("UploadSize", it->key) == 0) { - setUploadSize(it->value.as()); - } - else if(strcmp("GPout1", it->key) == 0) { - setGPIOout(0, it->value.as() ? true : false); - } - else if(strcmp("GPout2", it->key) == 0) { - setGPIOout(1, it->value.as() ? true : false); - } - else if(strcmp("GPin1", it->key) == 0) { - simulateGPIOin(it->value.as() ? 0x01 : 0x00); // simulate key 1 press - } - else if(strcmp("GPin2", it->key) == 0) { - simulateGPIOin(it->value.as() ? 0x02 : 0x00); // simulate key 2 press - } - else if(strcmp("JSONpack", it->key) == 0) { - sUserSettings us = NVstore.getUserSettings(); - uint8_t packed = it->value.as() ? 0x00 : 0x01; - us.JSON.LF = packed; - us.JSON.padding = packed; - us.JSON.singleElement = packed; - NVstore.setUserSettings(us); - NVstore.save(); - resetJSONmoderator(); - } - else if(strcmp("TempMode", it->key) == 0) { - sUserSettings us = NVstore.getUserSettings(); - us.degF = it->value.as() ? 0x01 : 0x00; - NVstore.setUserSettings(us); - NVstore.save(); - } - else if(strcmp("PumpCount", it->key) == 0) { // reset fuel gauge - int Count = it->value.as(); - if(Count == 0) { - resetFuelGauge(); - } - } - else if(strcmp("PumpCal", it->key) == 0) { - sHeaterTuning ht = NVstore.getHeaterTuning(); - ht.pumpCal = it->value.as(); - if(INBOUNDS(ht.pumpCal, 0.001, 1)) { - NVstore.setHeaterTuning(ht); - } - } - else if(strcmp("TempOffset", it->key) == 0) { - sHeaterTuning ht = NVstore.getHeaterTuning(); - ht.tempOfs = it->value.as(); - if(INBOUNDS(ht.tempOfs, -10.0, +10.0)) { - NVstore.setHeaterTuning(ht); - } - } - else if(strcmp("LowVoltCutout", it->key) == 0) { - float fCal = it->value.as(); - bool bOK = false; - if(NVstore.getHeaterTuning().sysVoltage == 120) - bOK |= (fCal == 0) || INBOUNDS(fCal, 10.0, 12.5); - else - bOK |= (fCal == 0) || INBOUNDS(fCal, 20.0, 25.0); - if(bOK) { - sHeaterTuning ht = NVstore.getHeaterTuning(); - ht.lowVolts = uint8_t(fCal * 10); - NVstore.setHeaterTuning(ht); - } - }*/ - else if(strcmp("SMenu", it->key) == 0) { - sUserSettings us = NVstore.getUserSettings(); - us.menuMode = it->value.as(); - if(us.menuMode <=2) { - NVstore.setUserSettings(us); - NVstore.save(); - switch(us.menuMode) { - case 0: DebugPort.println("Invoking Full menu control mode"); break; - case 1: DebugPort.println("Invoking Basic menu mode"); break; - case 2: DebugPort.println("Invoking cut back No Heater mode"); break; - } - reloadScreens(); - } - } - else if(strcmp("SysHourMeters", it->key) == 0) { - pHourMeter->resetHard(); - } } } @@ -701,39 +467,39 @@ void updateJSONclients(bool report) } -void resetJSONmoderator() +void resetAllJSONmoderators() { JSONmoderator.reset(); #ifdef SALWAYS_SEND_TIMERS TimerModerator.reset(); #else - initTimerJSONmoderator(); + initJSONTimermoderator(); #endif - initMQTTJSONmoderator(); - initIPJSONmoderator(); - initSysModerator(); + initJSONMQTTmoderator(); + initJSONIPmoderator(); + initJSONSysModerator(); GPIOmoderator.reset(); } -void initMQTTJSONmoderator() +void initJSONMQTTmoderator() { char jsonStr[800]; makeJSONStringMQTT(MQTTJSONmoderator, jsonStr, sizeof(jsonStr)); } -void initIPJSONmoderator() +void initJSONIPmoderator() { char jsonStr[800]; makeJSONStringIP(IPmoderator, jsonStr, sizeof(jsonStr)); } -void initSysModerator() +void initJSONSysModerator() { char jsonStr[800]; makeJSONStringSysInfo(SysModerator, jsonStr, sizeof(jsonStr)); } -void initTimerJSONmoderator() +void initJSONTimermoderator() { char jsonStr[800]; for(int tmr=0; tmr<14; tmr++) @@ -766,266 +532,3 @@ void Expand(std::string& str) } } -void DecodeCmd(const char* cmd, String& payload) -{ - if(strcmp("TempDesired", cmd) == 0) { - if( !reqDemand(payload.toInt(), false) ) { // this request is blocked if OEM controller active - JSONmoderator.reset("TempDesired"); - } - } - else if(strcmp("Run", cmd) == 0) { - refreshMQTT(); - if(payload == "1") { - requestOn(); - } - else if(payload == "0") { - requestOff(); - } - } - else if(strcmp("RunState", cmd) == 0) { - if(payload.toInt()) { - requestOn(); - } - else { - requestOff(); - } - } - else if(strcmp("PumpMin", cmd) == 0) { - setPumpMin(payload.toFloat()); - } - else if(strcmp("PumpMax", cmd) == 0) { - setPumpMax(payload.toFloat()); - } - else if(strcmp("FanMin", cmd) == 0) { - setFanMin(payload.toInt()); - } - else if(strcmp("FanMax", cmd) == 0) { - setFanMax(payload.toInt()); - } - else if(strcmp("CyclicTemp", cmd) == 0) { - setDemandDegC(payload.toInt()); // directly set demandDegC - } - else if((strcmp("CyclicOff", cmd) == 0) || (strcmp("ThermostatOvertemp", cmd) == 0)) { - sUserSettings us = NVstore.getUserSettings(); - us.cyclic.Stop = payload.toInt(); - if(INBOUNDS(us.cyclic.Stop, 0, 10)) { - if(us.cyclic.Stop > 1) - us.cyclic.Stop--; // internal uses a 1 offset - NVstore.setUserSettings(us); - } - } - else if((strcmp("CyclicOn", cmd) == 0) || (strcmp("ThermostatUndertemp", cmd) == 0)) { - sUserSettings us = NVstore.getUserSettings(); - us.cyclic.Start = payload.toInt(); - if(INBOUNDS(us.cyclic.Start, -20, 0)) - NVstore.setUserSettings(us); - } - else if(strcmp("ThermostatMethod", cmd) == 0) { - sUserSettings settings = NVstore.getUserSettings(); - settings.ThermostatMethod = payload.toInt(); - if(INBOUNDS(settings.ThermostatMethod, 0, 3)) - NVstore.setUserSettings(settings); - } - else if(strcmp("ThermostatWindow", cmd) == 0) { - sUserSettings settings = NVstore.getUserSettings(); - settings.ThermostatWindow = payload.toFloat(); - if(INBOUNDS(settings.ThermostatWindow, 0.2f, 10.f)) - NVstore.setUserSettings(settings); - } - else if(strcmp("Thermostat", cmd) == 0) { - if(!setThermostatMode(payload.toInt())) { // this request is blocked if OEM controller active - JSONmoderator.reset("ThermoStat"); - } - } - else if(strcmp("ExtThermoTmout", cmd) == 0) { - sUserSettings us = NVstore.getUserSettings(); - us.ExtThermoTimeout = payload.toInt(); - if(INBOUNDS(us.ExtThermoTimeout, 0, 3600000)) - NVstore.setUserSettings(us); - } - else if(strcmp("NVsave", cmd) == 0) { - if(payload.toInt() == 8861) - saveNV(); - } - else if(strcmp("Watchdog", cmd) == 0) { - doJSONwatchdog(payload.toInt()); - } - else if(strcmp("DateTime", cmd) == 0) { - setDateTime(payload.c_str()); - bTriggerDateTime = true; - } - else if(strcmp("Date", cmd) == 0) { - setDate(payload.c_str()); - bTriggerDateTime = true; - } - else if(strcmp("Time", cmd) == 0) { - setTime(payload.c_str()); - bTriggerDateTime = true; - } - else if(strcmp("Time12hr", cmd) == 0) { - sUserSettings us = NVstore.getUserSettings(); - us.clock12hr = payload.toInt() ? 1 : 0; - NVstore.setUserSettings(us); - NVstore.save(); - } - else if(strcmp("PumpPrime", cmd) == 0) { - reqPumpPrime(payload.toInt()); - } - else if(strcmp("Refresh", cmd) == 0) { - resetJSONmoderator(); - refreshMQTT(); - } - else if(strcmp("SystemVoltage", cmd) == 0) { - setSystemVoltage(payload.toFloat()); - } - else if(strcmp("TimerDays", cmd) == 0) { - // value encoded as "ID Days,Days" - decodeJSONTimerDays(payload.c_str()); - } - else if(strcmp("TimerStart", cmd) == 0) { - // value encoded as "ID HH:MM" - decodeJSONTimerTime(0, payload.c_str()); - } - else if(strcmp("TimerStop", cmd) == 0) { - // value encoded as "ID HH:MM" - decodeJSONTimerTime(1, payload.c_str()); - } - else if(strcmp("TimerRepeat", cmd) == 0) { - // value encoded as "ID val" - decodeJSONTimerNumeric(0, payload.c_str()); - } - else if(strcmp("TimerTemp", cmd) == 0) { - decodeJSONTimerNumeric(1, payload.c_str()); - } - else if(strcmp("TimerConflict", cmd) == 0) { - validateTimer(payload.toInt()); - } - // request specific timer refresh - else if((strcmp("TQuery", cmd) == 0) || (strcmp("TimerRefresh", cmd) == 0) ) { - int timerID = payload.toInt(); - if(timerID) - TimerModerator.reset(timerID-1); - else - TimerModerator.reset(); - } - else if(strcmp("FanSensor", cmd) == 0) { - setFanSensor(payload.toInt()); - } - else if(strcmp("IQuery", cmd) == 0) { - IPmoderator.reset(); // force IP params to be sent - } - // system info - else if(strcmp("SQuery", cmd) == 0) { - SysModerator.reset(); // force MQTT params to be sent - bTriggerSysParams = true; - } - // MQTT parameters - else if(strcmp("MQuery", cmd) == 0) { - MQTTJSONmoderator.reset(); // force MQTT params to be sent - } - else if(strcmp("MEn", cmd) == 0) { - sMQTTparams info = NVstore.getMQTTinfo(); - info.enabled = payload.toInt(); - NVstore.setMQTTinfo(info); - } - else if(strcmp("MPort", cmd) == 0) { - sMQTTparams info = NVstore.getMQTTinfo(); - info.port = payload.toInt(); - NVstore.setMQTTinfo(info); - } - else if(strcmp("MHost", cmd) == 0) { - sMQTTparams info = NVstore.getMQTTinfo(); - strncpy(info.host, payload.c_str(), 127); - info.host[127] = 0; - NVstore.setMQTTinfo(info); - } - else if(strcmp("MUser", cmd) == 0) { - sMQTTparams info = NVstore.getMQTTinfo(); - strncpy(info.username, payload.c_str(), 31); - info.username[31] = 0; - NVstore.setMQTTinfo(info); - } - else if(strcmp("MPasswd", cmd) == 0) { - sMQTTparams info = NVstore.getMQTTinfo(); - strncpy(info.password, payload.c_str(), 31); - info.password[31] = 0; - NVstore.setMQTTinfo(info); - } - else if(strcmp("MQoS", cmd) == 0) { - sMQTTparams info = NVstore.getMQTTinfo(); - info.qos = payload.toInt(); - if(INBOUNDS(info.qos, 0, 2)) { - NVstore.setMQTTinfo(info); - } - } - else if(strcmp("MTopic", cmd) == 0) { - sMQTTparams info = NVstore.getMQTTinfo(); - strncpy(info.topic, payload.c_str(), 31); - info.topic[31] = 0; - NVstore.setMQTTinfo(info); - } - else if(strcmp("UploadSize", cmd) == 0) { - setUploadSize(payload.toInt()); - } - else if(strcmp("GPout1", cmd) == 0) { - setGPIOout(0, payload.toInt() ? true : false); - } - else if(strcmp("GPout2", cmd) == 0) { - setGPIOout(1, payload.toInt() ? true : false); - } - else if(strcmp("GPin1", cmd) == 0) { - simulateGPIOin(payload.toInt() ? 0x01 : 0x00); // simulate key 1 press - } - else if(strcmp("GPin2", cmd) == 0) { - simulateGPIOin(payload.toInt() ? 0x02 : 0x00); // simulate key 2 press - } - else if(strcmp("JSONpack", cmd) == 0) { - sUserSettings us = NVstore.getUserSettings(); - uint8_t packed = payload.toInt() ? 0x00 : 0x01; - us.JSON.LF = packed; - us.JSON.padding = packed; - us.JSON.singleElement = packed; - NVstore.setUserSettings(us); - NVstore.save(); - resetJSONmoderator(); - } - else if(strcmp("TempMode", cmd) == 0) { - sUserSettings us = NVstore.getUserSettings(); - us.degF = payload.toInt() ? 0x01 : 0x00; - NVstore.setUserSettings(us); - NVstore.save(); - } - else if(strcmp("PumpCount", cmd) == 0) { // reset fuel gauge - int Count = payload.toInt(); - if(Count == 0) { - resetFuelGauge(); - } - } - else if(strcmp("PumpCal", cmd) == 0) { - sHeaterTuning ht = NVstore.getHeaterTuning(); - ht.pumpCal = payload.toFloat(); - if(INBOUNDS(ht.pumpCal, 0.001, 1)) { - NVstore.setHeaterTuning(ht); - } - } - else if(strcmp("TempOffset", cmd) == 0) { - sHeaterTuning ht = NVstore.getHeaterTuning(); - ht.tempOfs = payload.toFloat(); - if(INBOUNDS(ht.tempOfs, -10.0, +10.0)) { - NVstore.setHeaterTuning(ht); - } - } - else if(strcmp("LowVoltCutout", cmd) == 0) { - float fCal = payload.toFloat(); - bool bOK = false; - if(NVstore.getHeaterTuning().sysVoltage == 120) - bOK |= (fCal == 0) || INBOUNDS(fCal, 10.0, 12.5); - else - bOK |= (fCal == 0) || INBOUNDS(fCal, 20.0, 25.0); - if(bOK) { - sHeaterTuning ht = NVstore.getHeaterTuning(); - ht.lowVolts = uint8_t(fCal * 10); - NVstore.setHeaterTuning(ht); - } - } -} \ No newline at end of file diff --git a/src/Utility/BTC_JSON.h b/src/Utility/BTC_JSON.h index e4639e0..2d295b7 100644 --- a/src/Utility/BTC_JSON.h +++ b/src/Utility/BTC_JSON.h @@ -28,10 +28,18 @@ extern char defaultJSONstr[64]; void updateJSONclients(bool report); -void initMQTTJSONmoderator(); -void initIPJSONmoderator(); -void initTimerJSONmoderator(); -void initSysModerator(); +void initJSONMQTTmoderator(); +void initJSONIPmoderator(); +void initJSONTimermoderator(); +void initJSONSysModerator(); +void triggerJSONTimeUpdate(); +void resetAllJSONmoderators(); +void resetJSONmoderator(const char* name); +void resetJSONTimerModerator(int timerID); +void resetJSONIPmoderator(); +void resetJSONSysModerator(); +void resetJSONMQTTmoderator(); +void validateTimer(int ID); template const char* createJSON(const char* name, T value) diff --git a/src/Utility/UtilClasses.cpp b/src/Utility/UtilClasses.cpp index 1c03e3e..a64afdc 100644 --- a/src/Utility/UtilClasses.cpp +++ b/src/Utility/UtilClasses.cpp @@ -22,6 +22,10 @@ #include #include "../Protocol/Protocol.h" #include "UtilClasses.h" +#include "NVStorage.h" +#include "HourMeter.h" +#include "macros.h" +#include "BTC_JSON.h" // a class to track the blue wire receive / transmit states @@ -96,3 +100,280 @@ CProfile::elapsed(bool reset/* = false*/) return retval; } + +void DecodeCmd(const char* cmd, String& payload) +{ + if(strcmp("TempDesired", cmd) == 0) { + if( !reqDemand(payload.toInt(), false) ) { // this request is blocked if OEM controller active + resetJSONmoderator("TempDesired"); + } + } + else if(strcmp("Run", cmd) == 0) { + refreshMQTT(); + if(payload == "1") { + requestOn(); + } + else if(payload == "0") { + requestOff(); + } + } + else if(strcmp("RunState", cmd) == 0) { + if(payload.toInt()) { + requestOn(); + } + else { + requestOff(); + } + } + else if(strcmp("PumpMin", cmd) == 0) { + setPumpMin(payload.toFloat()); + } + else if(strcmp("PumpMax", cmd) == 0) { + setPumpMax(payload.toFloat()); + } + else if(strcmp("FanMin", cmd) == 0) { + setFanMin(payload.toInt()); + } + else if(strcmp("FanMax", cmd) == 0) { + setFanMax(payload.toInt()); + } + else if(strcmp("CyclicTemp", cmd) == 0) { + setDemandDegC(payload.toInt()); // directly set demandDegC + } + else if((strcmp("CyclicOff", cmd) == 0) || (strcmp("ThermostatOvertemp", cmd) == 0)) { + sUserSettings us = NVstore.getUserSettings(); + us.cyclic.Stop = payload.toInt(); + if(INBOUNDS(us.cyclic.Stop, 0, 10)) { + if(us.cyclic.Stop > 1) + us.cyclic.Stop--; // internal uses a 1 offset + NVstore.setUserSettings(us); + } + } + else if((strcmp("CyclicOn", cmd) == 0) || (strcmp("ThermostatUndertemp", cmd) == 0)) { + sUserSettings us = NVstore.getUserSettings(); + us.cyclic.Start = payload.toInt(); + if(INBOUNDS(us.cyclic.Start, -20, 0)) + NVstore.setUserSettings(us); + } + else if(strcmp("ThermostatMethod", cmd) == 0) { + sUserSettings settings = NVstore.getUserSettings(); + settings.ThermostatMethod = payload.toInt(); + if(INBOUNDS(settings.ThermostatMethod, 0, 3)) + NVstore.setUserSettings(settings); + } + else if(strcmp("ThermostatWindow", cmd) == 0) { + sUserSettings settings = NVstore.getUserSettings(); + settings.ThermostatWindow = payload.toFloat(); + if(INBOUNDS(settings.ThermostatWindow, 0.2f, 10.f)) + NVstore.setUserSettings(settings); + } + else if(strcmp("Thermostat", cmd) == 0) { + if(!setThermostatMode(payload.toInt())) { // this request is blocked if OEM controller active + resetJSONmoderator("ThermoStat"); + } + } + else if(strcmp("ExtThermoTmout", cmd) == 0) { + sUserSettings us = NVstore.getUserSettings(); + us.ExtThermoTimeout = payload.toInt(); + if(INBOUNDS(us.ExtThermoTimeout, 0, 3600000)) + NVstore.setUserSettings(us); + } + else if(strcmp("NVsave", cmd) == 0) { + if(payload.toInt() == 8861) + saveNV(); + } + else if(strcmp("Watchdog", cmd) == 0) { + doJSONwatchdog(payload.toInt()); + } + else if(strcmp("DateTime", cmd) == 0) { + setDateTime(payload.c_str()); + triggerJSONTimeUpdate(); + } + else if(strcmp("Date", cmd) == 0) { + setDate(payload.c_str()); + triggerJSONTimeUpdate(); + } + else if(strcmp("Time", cmd) == 0) { + setTime(payload.c_str()); + triggerJSONTimeUpdate(); + } + else if(strcmp("Time12hr", cmd) == 0) { + sUserSettings us = NVstore.getUserSettings(); + us.clock12hr = payload.toInt() ? 1 : 0; + NVstore.setUserSettings(us); + NVstore.save(); + } + else if(strcmp("PumpPrime", cmd) == 0) { + reqPumpPrime(payload.toInt()); + } + else if(strcmp("Refresh", cmd) == 0) { + resetAllJSONmoderators(); + refreshMQTT(); + } + else if(strcmp("SystemVoltage", cmd) == 0) { + setSystemVoltage(payload.toFloat()); + } + else if(strcmp("TimerDays", cmd) == 0) { + // value encoded as "ID Days,Days" + decodeJSONTimerDays(payload.c_str()); + } + else if(strcmp("TimerStart", cmd) == 0) { + // value encoded as "ID HH:MM" + decodeJSONTimerTime(0, payload.c_str()); + } + else if(strcmp("TimerStop", cmd) == 0) { + // value encoded as "ID HH:MM" + decodeJSONTimerTime(1, payload.c_str()); + } + else if(strcmp("TimerRepeat", cmd) == 0) { + // value encoded as "ID val" + decodeJSONTimerNumeric(0, payload.c_str()); + } + else if(strcmp("TimerTemp", cmd) == 0) { + decodeJSONTimerNumeric(1, payload.c_str()); + } + else if(strcmp("TimerConflict", cmd) == 0) { + validateTimer(payload.toInt()); + } + // request specific timer refresh + else if((strcmp("TQuery", cmd) == 0) || (strcmp("TimerRefresh", cmd) == 0) ) { + resetJSONTimerModerator(payload.toInt()); + } + else if(strcmp("FanSensor", cmd) == 0) { + setFanSensor(payload.toInt()); + } + else if(strcmp("IQuery", cmd) == 0) { + resetJSONIPmoderator(); // force IP params to be sent + } + // system info + else if(strcmp("SQuery", cmd) == 0) { + resetJSONSysModerator(); // force system params to be sent + } + // MQTT parameters + else if(strcmp("MQuery", cmd) == 0) { + resetJSONMQTTmoderator(); // force MQTT params to be sent + } + else if(strcmp("MEn", cmd) == 0) { + sMQTTparams info = NVstore.getMQTTinfo(); + info.enabled = payload.toInt(); + NVstore.setMQTTinfo(info); + } + else if(strcmp("MPort", cmd) == 0) { + sMQTTparams info = NVstore.getMQTTinfo(); + info.port = payload.toInt(); + NVstore.setMQTTinfo(info); + } + else if(strcmp("MHost", cmd) == 0) { + sMQTTparams info = NVstore.getMQTTinfo(); + strncpy(info.host, payload.c_str(), 127); + info.host[127] = 0; + NVstore.setMQTTinfo(info); + } + else if(strcmp("MUser", cmd) == 0) { + sMQTTparams info = NVstore.getMQTTinfo(); + strncpy(info.username, payload.c_str(), 31); + info.username[31] = 0; + NVstore.setMQTTinfo(info); + } + else if(strcmp("MPasswd", cmd) == 0) { + sMQTTparams info = NVstore.getMQTTinfo(); + strncpy(info.password, payload.c_str(), 31); + info.password[31] = 0; + NVstore.setMQTTinfo(info); + } + else if(strcmp("MQoS", cmd) == 0) { + sMQTTparams info = NVstore.getMQTTinfo(); + info.qos = payload.toInt(); + if(INBOUNDS(info.qos, 0, 2)) { + NVstore.setMQTTinfo(info); + } + } + else if(strcmp("MTopic", cmd) == 0) { + sMQTTparams info = NVstore.getMQTTinfo(); + strncpy(info.topic, payload.c_str(), 31); + info.topic[31] = 0; + NVstore.setMQTTinfo(info); + } + else if(strcmp("UploadSize", cmd) == 0) { + setUploadSize(payload.toInt()); + } + else if(strcmp("GPout1", cmd) == 0) { + setGPIOout(0, payload.toInt() ? true : false); + } + else if(strcmp("GPout2", cmd) == 0) { + setGPIOout(1, payload.toInt() ? true : false); + } + else if(strcmp("GPin1", cmd) == 0) { + simulateGPIOin(payload.toInt() ? 0x01 : 0x00); // simulate key 1 press + } + else if(strcmp("GPin2", cmd) == 0) { + simulateGPIOin(payload.toInt() ? 0x02 : 0x00); // simulate key 2 press + } + else if(strcmp("JSONpack", cmd) == 0) { + sUserSettings us = NVstore.getUserSettings(); + uint8_t packed = payload.toInt() ? 0x00 : 0x01; + us.JSON.LF = packed; + us.JSON.padding = packed; + us.JSON.singleElement = packed; + NVstore.setUserSettings(us); + NVstore.save(); + resetAllJSONmoderators(); + } + else if(strcmp("TempMode", cmd) == 0) { + sUserSettings us = NVstore.getUserSettings(); + us.degF = payload.toInt() ? 0x01 : 0x00; + NVstore.setUserSettings(us); + NVstore.save(); + } + else if(strcmp("PumpCount", cmd) == 0) { // reset fuel gauge + int Count = payload.toInt(); + if(Count == 0) { + resetFuelGauge(); + } + } + else if(strcmp("PumpCal", cmd) == 0) { + sHeaterTuning ht = NVstore.getHeaterTuning(); + ht.pumpCal = payload.toFloat(); + if(INBOUNDS(ht.pumpCal, 0.001, 1)) { + NVstore.setHeaterTuning(ht); + } + } + else if(strcmp("TempOffset", cmd) == 0) { + sHeaterTuning ht = NVstore.getHeaterTuning(); + ht.tempOfs = payload.toFloat(); + if(INBOUNDS(ht.tempOfs, -10.0, +10.0)) { + NVstore.setHeaterTuning(ht); + } + } + else if(strcmp("LowVoltCutout", cmd) == 0) { + float fCal = payload.toFloat(); + bool bOK = false; + if(NVstore.getHeaterTuning().sysVoltage == 120) + bOK |= (fCal == 0) || INBOUNDS(fCal, 10.0, 12.5); + else + bOK |= (fCal == 0) || INBOUNDS(fCal, 20.0, 25.0); + if(bOK) { + sHeaterTuning ht = NVstore.getHeaterTuning(); + ht.lowVolts = uint8_t(fCal * 10); + NVstore.setHeaterTuning(ht); + } + } + else if(strcmp("SMenu", cmd) == 0) { + sUserSettings us = NVstore.getUserSettings(); + us.menuMode = payload.toInt(); + if(us.menuMode <=2) { + NVstore.setUserSettings(us); + NVstore.save(); + switch(us.menuMode) { + case 0: DebugPort.println("Invoking Full menu control mode"); break; + case 1: DebugPort.println("Invoking Basic menu mode"); break; + case 2: DebugPort.println("Invoking cut back No Heater mode"); break; + } + reloadScreens(); + } + } + else if(strcmp("SysHourMeters", cmd) == 0) { + pHourMeter->resetHard(); + } +} + diff --git a/src/Utility/helpers.h b/src/Utility/helpers.h index f20b98b..777f735 100644 --- a/src/Utility/helpers.h +++ b/src/Utility/helpers.h @@ -59,7 +59,6 @@ extern void saveNV(); extern void setSystemVoltage(float val); extern void interpretJsonCommand(char* pLine); extern void resetWebModerator(); -extern void resetJSONmoderator(); extern void resetFuelGauge(); extern const char* getBlueWireStatStr(); extern bool hasOEMcontroller(); @@ -85,7 +84,7 @@ extern void setDegFMode(bool state); extern float getBatteryVoltage(bool fast); extern float getGlowVolts(); extern float getGlowCurrent(); -extern float getFanSpeed(); +extern int getFanSpeed(); extern int sysUptime(); extern void doJSONwatchdog(int topup); extern void reloadScreens(); diff --git a/src/WiFi/ABMqtt.cpp b/src/WiFi/ABMqtt.cpp index c6e3cb2..c783b92 100644 --- a/src/WiFi/ABMqtt.cpp +++ b/src/WiFi/ABMqtt.cpp @@ -33,6 +33,7 @@ #include "../Utility/NVStorage.h" #include "../Utility/Moderator.h" #include "../Protocol/Protocol.h" +#include "../Utility/BTC_JSON.h" extern void DecodeCmd(const char* cmd, String& payload); @@ -109,7 +110,7 @@ void onMqttConnect(bool sessionPresent) MQTTclient.subscribe(lcltopic, NVstore.getMQTTinfo().qos); #endif - resetJSONmoderator(); + resetAllJSONmoderators(); } void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) @@ -292,7 +293,7 @@ bool isMQTTconnected() { } -void checkTopic(const char* name, int value) +void pubTopic(const char* name, int value) { if(MQTTclient.connected()) { if(MQTTmoderator.shouldSend(name, value)) { @@ -306,7 +307,7 @@ void checkTopic(const char* name, int value) } } -void checkTopic(const char* name, float value) +void pubTopic(const char* name, float value) { if(MQTTclient.connected()) { if(MQTTmoderator.shouldSend(name, value)) { @@ -320,7 +321,7 @@ void checkTopic(const char* name, float value) } } -void checkTopic(const char* name, const char* payload) +void pubTopic(const char* name, const char* payload) { if(MQTTclient.connected()) { if(MQTTmoderator.shouldSend(name, payload)) { @@ -334,28 +335,26 @@ void checkTopic(const char* name, const char* payload) void updateMQTT() { - checkTopic("RunState", getHeaterInfo().getRunStateEx()); -// checkTopic("Run", getHeaterInfo().getRunStateEx() ? "{\"RunState\":1}" : "{\"RunState\":0}"); -// checkTopic("RunSts", getHeaterInfo().getRunStateEx() ? "1" : "0"); - checkTopic("Run", getHeaterInfo().getRunStateEx() ? "1" : "0"); - checkTopic("RunString", getHeaterInfo().getRunStateStr()); + pubTopic("RunState", getHeaterInfo().getRunStateEx()); + pubTopic("Run", getHeaterInfo().getRunStateEx() ? "1" : "0"); + pubTopic("RunString", getHeaterInfo().getRunStateStr()); float tidyTemp = getTemperatureSensor(); tidyTemp = int(tidyTemp * 10 + 0.5) * 0.1f; // round to 0.1 resolution - checkTopic("TempCurrent", tidyTemp); - checkTopic("TempDesired", getTemperatureDesired()); - checkTopic("TempBody", getHeaterInfo().getTemperature_HeatExchg()); - checkTopic("ErrorState", getHeaterInfo().getErrState()); - checkTopic("ErrorString", getHeaterInfo().getErrStateStrEx()); // verbose it up! - checkTopic("Thermostat", getThermostatModeActive()); - checkTopic("PumpFixed", getHeaterInfo().getPump_Fixed() ); - checkTopic("PumpActual", getHeaterInfo().getPump_Actual()); - checkTopic("FanRPM", getFanSpeed()); - checkTopic("InputVoltage", getBatteryVoltage(false)); - checkTopic("GlowVoltage", getGlowVolts()); - checkTopic("GlowCurrent", getGlowCurrent()); + pubTopic("TempCurrent", tidyTemp); + pubTopic("TempDesired", getTemperatureDesired()); + pubTopic("TempBody", getHeaterInfo().getTemperature_HeatExchg()); + pubTopic("ErrorState", getHeaterInfo().getErrState()); + pubTopic("ErrorString", getHeaterInfo().getErrStateStrEx()); // verbose it up! + pubTopic("Thermostat", getThermostatModeActive()); + pubTopic("PumpFixed", getHeaterInfo().getPump_Fixed() ); + pubTopic("PumpActual", getHeaterInfo().getPump_Actual()); + pubTopic("FanRPM", getFanSpeed()); + pubTopic("InputVoltage", getBatteryVoltage(false)); + pubTopic("GlowVoltage", getGlowVolts()); + pubTopic("GlowCurrent", getGlowCurrent()); sGPIO info; getGPIOinfo(info); - checkTopic("GPanlg", info.algVal * 100 / 4096); + pubTopic("GPanlg", info.algVal * 100 / 4096); } void refreshMQTT() diff --git a/src/WiFi/BTCWebServer.cpp b/src/WiFi/BTCWebServer.cpp index e5fa2a2..6e94ef6 100644 --- a/src/WiFi/BTCWebServer.cpp +++ b/src/WiFi/BTCWebServer.cpp @@ -86,12 +86,12 @@ void build500Response(String& content, String file); void initWebServer(void) { - if (MDNS.begin("Afterburner")) { - DebugPort.println("MDNS responder started"); - } - - server.on("/wmconfig", onWMConfig); - server.on("/resetwifi", onResetWifi); + if (MDNS.begin("Afterburner")) { + DebugPort.println("MDNS responder started"); + } + + server.on("/wmconfig", onWMConfig); + server.on("/resetwifi", onResetWifi); server.on("/erase", HTTP_POST, onErase); // erase file from SPIFFS // Magical code originally shamelessly lifted from Arduino WebUpdate example, then greatly modified @@ -115,7 +115,7 @@ void initWebServer(void) { DebugPort.println("WEB: GET /formatnow - ILLEGAL - root redirect"); rootRedirect(); }); - server.on("/formatnow", HTTP_POST, onFormatNow); // access via POST is legal, but only if bFormatAccess == true + server.on("/formatnow", HTTP_POST, onFormatNow); // access via POST is legal, but only if bFormatAccess == true server.on("/reboot", HTTP_GET, onReboot); // access via POST is legal, but only if bFormatAccess == true server.on("/reboot", HTTP_POST, onDoReboot); // access via POST is legal, but only if bFormatAccess == true @@ -130,12 +130,12 @@ void initWebServer(void) { } }); - server.begin(); + server.begin(); - webSocket.begin(); - webSocket.onEvent(webSocketEvent); + webSocket.begin(); + webSocket.onEvent(webSocketEvent); - DebugPort.println("HTTP server started"); + DebugPort.println("HTTP server started"); } @@ -438,8 +438,8 @@ function onformatClick() { void onWMConfig() { DebugPort.println("WEB: GET /wmconfig"); - server.send(200, "text/plain", "Start Config Portal - Retaining credential"); - DebugPort.println("Starting web portal for wifi config"); + server.send(200, "text/plain", "Start Config Portal - Retaining credential"); + DebugPort.println("Starting web portal for wifi config"); delay(500); wifiEnterConfigPortal(true, false, 3000); } @@ -447,8 +447,8 @@ void onWMConfig() void onResetWifi() { DebugPort.println("WEB: GET /resetwifi"); - server.send(200, "text/plain", "Start Config Portal - Resetting Wifi credentials!"); - DebugPort.println("diconnecting client and wifi, then rebooting"); + server.send(200, "text/plain", "Start Config Portal - Resetting Wifi credentials!"); + DebugPort.println("diconnecting client and wifi, then rebooting"); delay(500); wifiEnterConfigPortal(true, true, 3000); } @@ -462,7 +462,7 @@ void onNotFound() String message; build404Response(message, path); - server.send(404, "text/html", message); + server.send(404, "text/html", message); } void rootRedirect() @@ -477,7 +477,7 @@ bool sendWebSocketString(const char* Str) CProfile profile; #endif - if(webSocket.connectedClients()) { + if(webSocket.connectedClients()) { #ifdef WEBTIMES unsigned long tCon = profile.elapsed(true); @@ -491,52 +491,55 @@ bool sendWebSocketString(const char* Str) DebugPort.printf("Websend times : %ld,%ld\r\n", tCon, tWeb); #endif - return true; - } + return true; + } return false; } void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { - if (type == WStype_TEXT) { - bRxWebData = true; - char cmd[256]; - memset(cmd, 0, 256); - for (int i = 0; i < length && i < 256; i++) { - cmd[i] = payload[i]; - } - interpretJsonCommand(cmd); // send to the main heater controller decode routine + if (type == WStype_TEXT) { + bRxWebData = true; + char cmd[256]; + memset(cmd, 0, 256); + for (int i = 0; i < length && i < 256; i++) { + cmd[i] = payload[i]; + } + interpretJsonCommand(cmd); // send to the main heater controller decode routine } } bool isWebSocketClientChange() { - static int prevNumClients = -1; + static int prevNumClients = -1; - int numClients = webSocket.connectedClients(); - if(numClients != prevNumClients) { - prevNumClients = numClients; - DebugPort.println("Changed number of web clients, should reset JSON moderator"); - return true; - } + int numClients = webSocket.connectedClients(); + if(numClients != prevNumClients) { + bool retval = numClients > prevNumClients; + prevNumClients = numClients; + if(retval) { + DebugPort.println("Increased number of web socket clients, should reset JSON moderator"); + return true; + } + } return false; } bool hasWebClientSpoken(bool reset) { - bool retval = bRxWebData; - if(reset) - bRxWebData = false; - return retval; + bool retval = bRxWebData; + if(reset) + bRxWebData = false; + return retval; } bool hasWebServerSpoken(bool reset) { - bool retval = bTxWebData; - if(reset) - bTxWebData = false; - return retval; + bool retval = bTxWebData; + if(reset) + bTxWebData = false; + return retval; } void setUploadSize(long val) @@ -911,7 +914,7 @@ void onFormatNow() DebugPort.println("WEB: POST /formatnow"); String confirm = server.arg("confirm"); // get request argument value by name if(confirm == "yes" && bFormatAccessed) { // confirm user agrees, and we did pass thru /formatspiffs first - DebugPort.println("Formatting SPIFFS partition"); + DebugPort.println("Formatting SPIFFS partition"); SPIFFS.format(); // re-format the SPIFFS partition bFormatPerformed = true; } @@ -936,7 +939,7 @@ void onDoReboot() DebugPort.println("WEB: POST /reboot"); String confirm = server.arg("reboot"); // get request argument value by name if(confirm == "yes") { // confirm user agrees, and we did pass thru /formatspiffs first - DebugPort.println("Rebooting via /reboot"); + DebugPort.println("Rebooting via /reboot"); ESP.restart(); } } @@ -986,7 +989,7 @@ void onRename() String oldname = server.arg("oldname"); // get request argument value by name String newname = server.arg("newname"); // get request argument value by name if(oldname != "" && newname != "") { - DebugPort.printf("Renaming %s to %s\r\n", oldname.c_str(), newname.c_str()); + DebugPort.printf("Renaming %s to %s\r\n", oldname.c_str(), newname.c_str()); SPIFFS.rename(oldname.c_str(), newname.c_str()); checkSplashScreenUpdate(); }