Browse Source

sys: refactor custom reset codes

mcspr-patch-1
Maxim Prokhorov 3 years ago
parent
commit
c4f0ceb1ae
19 changed files with 139 additions and 116 deletions
  1. +2
    -4
      code/espurna/button.cpp
  2. +0
    -17
      code/espurna/config/types.h
  3. +1
    -1
      code/espurna/curtain_kingart.cpp
  4. +1
    -1
      code/espurna/nofuss.cpp
  5. +2
    -2
      code/espurna/ota.cpp
  6. +1
    -1
      code/espurna/ota.h
  7. +1
    -1
      code/espurna/ota_arduinoota.cpp
  8. +1
    -1
      code/espurna/ota_asynctcp.cpp
  9. +1
    -1
      code/espurna/ota_httpupdate.cpp
  10. +1
    -1
      code/espurna/ota_web.cpp
  11. +1
    -1
      code/espurna/rpc.cpp
  12. +1
    -1
      code/espurna/rpnrules.cpp
  13. +11
    -11
      code/espurna/settings.cpp
  14. +67
    -16
      code/espurna/system.cpp
  15. +22
    -6
      code/espurna/system.h
  16. +3
    -3
      code/espurna/terminal.cpp
  17. +20
    -42
      code/espurna/utils.cpp
  18. +1
    -2
      code/espurna/web.cpp
  19. +2
    -4
      code/espurna/ws.cpp

+ 2
- 4
code/espurna/button.cpp View File

@ -549,13 +549,11 @@ void buttonEvent(unsigned char id, button_event_t event) {
break;
case ButtonAction::Reset:
deferredReset(100, CUSTOM_RESET_HARDWARE);
deferredReset(100, CustomResetReason::Button);
break;
case ButtonAction::FactoryReset:
DEBUG_MSG_P(PSTR("\n\nFACTORY RESET\n\n"));
resetSettings();
deferredReset(100, CUSTOM_RESET_FACTORY);
factoryReset();
break;
case ButtonAction::Wps:


+ 0
- 17
code/espurna/config/types.h View File

@ -252,23 +252,6 @@
#define LIGHT_EFFECT_FADE 3
#define LIGHT_EFFECT_SMOOTH 4
//------------------------------------------------------------------------------
// RESET
//------------------------------------------------------------------------------
#define CUSTOM_RESET_HARDWARE 1 // Reset from hardware button
#define CUSTOM_RESET_WEB 2 // Reset from web interface
#define CUSTOM_RESET_TERMINAL 3 // Reset from terminal
#define CUSTOM_RESET_MQTT 4 // Reset via MQTT
#define CUSTOM_RESET_RPC 5 // Reset via RPC (HTTP)
#define CUSTOM_RESET_OTA 6 // Reset after successful OTA update
#define CUSTOM_RESET_HTTP 7 // Reset via HTTP GET
#define CUSTOM_RESET_NOFUSS 8 // Reset after successful NOFUSS update
#define CUSTOM_RESET_UPGRADE 9 // Reset after update from web interface
#define CUSTOM_RESET_FACTORY 10 // Factory reset from terminal
#define CUSTOM_RESET_MAX 10
//------------------------------------------------------------------------------
// ENVIRONMENTAL
//------------------------------------------------------------------------------


+ 1
- 1
code/espurna/curtain_kingart.cpp View File

@ -343,7 +343,7 @@ void _KACurtainResult() {
if (buffer.indexOf("enterESPTOUCH") > 0) {
wifiStartAP();
} else if (buffer.indexOf("exitESPTOUCH") > 0) {
deferredReset(100, CUSTOM_RESET_HARDWARE);
deferredReset(100, CustomResetReason::Hardware);
} else { //In any other case, update as it could be a move action
curtainUpdateUI();
}


+ 1
- 1
code/espurna/nofuss.cpp View File

@ -168,7 +168,7 @@ void nofussSetup() {
#endif
// TODO: NoFUSS will reset the board after this callback returns.
// Maybe this should be optional
customResetReason(CUSTOM_RESET_NOFUSS);
customResetReason(CustomResetReason::Ota);
nice_delay(100);
}


+ 2
- 2
code/espurna/ota.cpp View File

@ -23,7 +23,7 @@ void otaPrintError() {
}
}
bool otaFinalize(size_t size, int reason, bool evenIfRemaining) {
bool otaFinalize(size_t size, CustomResetReason reason, bool evenIfRemaining) {
if (Update.isRunning() && Update.end(evenIfRemaining)) {
DEBUG_MSG_P(PSTR("[OTA] Success: %7u bytes\n"), size);
deferredReset(500, reason);
@ -106,7 +106,7 @@ void otaSetup() {
if ((0xA55A == rtcmem[64]) && (0xA55A == rtcmem[68])) {
DEBUG_MSG_P(PSTR("[OTA] Detected TASMOTA OTA, resetting the device...\n"));
rtcmem[64] = rtcmem[68] = 0;
customResetReason(CUSTOM_RESET_TERMINAL);
customResetReason(CustomResetReason::Factory);
resetSettings();
eraseSDKConfig();
*((int*) 0) = 0;


+ 1
- 1
code/espurna/ota.h View File

@ -40,7 +40,7 @@ void otaClientSetup();
void otaSetup();
void otaPrintError();
bool otaFinalize(size_t size, int reason, bool evenIfRemaining = false);
bool otaFinalize(size_t size, CustomResetReason reason, bool evenIfRemaining = false);
// Helper methods from UpdaterClass that need to be called manually for async mode,
// because we are not using Stream interface to feed it data.


+ 1
- 1
code/espurna/ota_arduinoota.cpp View File

@ -57,7 +57,7 @@ void _arduinoOtaOnEnd() {
#endif
// Note: ArduinoOTA will reset the board after this callback returns.
customResetReason(CUSTOM_RESET_OTA);
customResetReason(CustomResetReason::Ota);
nice_delay(100);
}


+ 1
- 1
code/espurna/ota_asynctcp.cpp View File

@ -70,7 +70,7 @@ void _otaClientDisconnect() {
void _otaClientOnDisconnect(void* arg, AsyncClient* client) {
DEBUG_MSG_P(PSTR("\n"));
otaFinalize(reinterpret_cast<ota_client_t*>(arg)->size, CUSTOM_RESET_OTA, true);
otaFinalize(reinterpret_cast<ota_client_t*>(arg)->size, CustomResetReason::Ota, true);
schedule_function(_otaClientDisconnect);
}


+ 1
- 1
code/espurna/ota_httpupdate.cpp View File

@ -139,7 +139,7 @@ void _otaClientRunUpdater(__attribute__((unused)) WiFiClient* client, const Stri
break;
case HTTP_UPDATE_OK:
DEBUG_MSG_P(PSTR("[OTA] Done, restarting..."));
deferredReset(500, CUSTOM_RESET_OTA); // wait a bit more than usual
deferredReset(500, CustomResetReason::Ota); // wait a bit more than usual
break;
}


+ 1
- 1
code/espurna/ota_web.cpp View File

@ -128,7 +128,7 @@ void _onUpgradeFile(AsyncWebServerRequest *request, String filename, size_t inde
}
if (final) {
otaFinalize(index + len, CUSTOM_RESET_UPGRADE, true);
otaFinalize(index + len, CustomResetReason::Ota, true);
} else {
otaProgress(index + len);
}


+ 1
- 1
code/espurna/rpc.cpp View File

@ -21,7 +21,7 @@ bool rpcHandleAction(const String& action) {
if (action.equals("reboot")) {
result = true;
schedule_function([]() {
deferredReset(100, CUSTOM_RESET_RPC);
deferredReset(100, CustomResetReason::Rpc);
});
} else if (action.equals("heartbeat")) {
result = true;


+ 1
- 1
code/espurna/rpnrules.cpp View File

@ -807,7 +807,7 @@ void _rpnInit() {
rpn_operator_set(_rpn_ctxt, "reset", 0, [](rpn_context & ctxt) -> rpn_error {
static bool once = ([]() {
deferredReset(100, CUSTOM_RESET_TERMINAL);
deferredReset(100, CustomResetReason::Rule);
return true;
})();
return once


+ 11
- 11
code/espurna/settings.cpp View File

@ -541,22 +541,22 @@ void settingsSetup() {
terminalOK(ctx);
});
terminalRegisterCommand(F("RELOAD"), [](const terminal::CommandContext&) {
terminalRegisterCommand(F("RELOAD"), [](const terminal::CommandContext& ctx) {
espurnaReload();
terminalOK();
terminalOK(ctx);
});
terminalRegisterCommand(F("FACTORY.RESET"), [](const terminal::CommandContext&) {
resetSettings();
terminalOK();
terminalRegisterCommand(F("FACTORY.RESET"), [](const terminal::CommandContext& ctx) {
factoryReset();
terminalOK(ctx);
});
#if not SETTINGS_AUTOSAVE
terminalRegisterCommand(F("SAVE"), [](const terminal::CommandContext&) {
eepromCommit();
terminalOK();
});
#endif
#if not SETTINGS_AUTOSAVE
terminalRegisterCommand(F("SAVE"), [](const terminal::CommandContext& ctx) {
eepromCommit();
terminalOK(ctx);
});
#endif
}

+ 67
- 16
code/espurna/system.cpp View File

@ -50,16 +50,16 @@ void systemStabilityCounter(uint8_t count) {
Rtcmem->sys = data.value;
}
uint8_t _systemResetReason() {
CustomResetReason _systemRtcmemResetReason() {
system_rtcmem_t data;
data.value = Rtcmem->sys;
return data.packed.reset_reason;
return static_cast<CustomResetReason>(data.packed.reset_reason);
}
void _systemResetReason(uint8_t reason) {
void _systemRtcmemResetReason(CustomResetReason reason) {
system_rtcmem_t data;
data.value = Rtcmem->sys;
data.packed.reset_reason = reason;
data.packed.reset_reason = static_cast<uint8_t>(reason);
Rtcmem->sys = data.value;
}
@ -116,39 +116,90 @@ void systemCheckLoop() {
// -----------------------------------------------------------------------------
// Reset
// -----------------------------------------------------------------------------
Ticker _defer_reset;
uint8_t _reset_reason = 0;
auto _reset_reason = CustomResetReason::None;
String customResetReasonToPayload(CustomResetReason reason) {
const __FlashStringHelper* ptr { nullptr };
switch (reason) {
case CustomResetReason::None:
ptr = F("None");
break;
case CustomResetReason::Button:
ptr = F("Hardware button");
break;
case CustomResetReason::Factory:
ptr = F("Factory reset");
break;
case CustomResetReason::Hardware:
ptr = F("Reboot from a Hardware request");
break;
case CustomResetReason::Mqtt:
ptr = F("Reboot from MQTT");
break;
case CustomResetReason::Ota:
ptr = F("Reboot after a successful OTA update");
break;
case CustomResetReason::Rpc:
ptr = F("Reboot from a RPC action");
break;
case CustomResetReason::Rule:
ptr = F("Reboot from an automation rule");
break;
case CustomResetReason::Scheduler:
ptr = F("Reboot from a scheduler action");
break;
case CustomResetReason::Terminal:
ptr = F("Reboot from a terminal command");
break;
case CustomResetReason::Web:
ptr = F("Reboot from web interface");
break;
}
return String(ptr);
}
// system_get_rst_info() result is cached by the Core init for internal use
uint32_t systemResetReason() {
return resetInfo.reason;
}
void customResetReason(unsigned char reason) {
void customResetReason(CustomResetReason reason) {
_reset_reason = reason;
_systemResetReason(reason);
_systemRtcmemResetReason(reason);
}
unsigned char customResetReason() {
static unsigned char status = 255;
if (status == 255) {
if (rtcmemStatus()) status = _systemResetReason();
if (status > 0) customResetReason(0);
if (status > CUSTOM_RESET_MAX) status = 0;
CustomResetReason customResetReason() {
bool once { true };
static auto reason = CustomResetReason::None;
if (once) {
once = false;
if (rtcmemStatus()) {
reason = _systemRtcmemResetReason();
}
customResetReason(CustomResetReason::None);
}
return status;
return reason;
}
void reset() {
ESP.restart();
}
void deferredReset(unsigned long delay, unsigned char reason) {
void deferredReset(unsigned long delay, CustomResetReason reason) {
_defer_reset.once_ms(delay, customResetReason, reason);
}
void factoryReset() {
DEBUG_MSG_P(PSTR("\n\nFACTORY RESET\n\n"));
resetSettings();
deferredReset(100, CustomResetReason::Factory);
}
bool checkNeedsReset() {
return _reset_reason > 0;
return _reset_reason != CustomResetReason::None;
}
// -----------------------------------------------------------------------------


+ 22
- 6
code/espurna/system.h View File

@ -11,10 +11,26 @@ Copyright (C) 2019 by Xose Pérez <xose dot perez at gmail dot com>
#include "espurna.h"
extern "C" {
#include "user_interface.h"
extern struct rst_info resetInfo;
#include "user_interface.h"
extern struct rst_info resetInfo;
}
enum class CustomResetReason : uint8_t {
None,
Button,
Factory,
Hardware,
Mqtt,
Ota,
Rpc,
Rule,
Scheduler,
Terminal,
Web
};
void factoryReset();
uint32_t systemResetReason();
uint8_t systemStabilityCounter();
void systemStabilityCounter(uint8_t count);
@ -22,11 +38,11 @@ void systemStabilityCounter(uint8_t count);
void systemCheck(bool stable);
bool systemCheck();
uint32_t systemResetReason();
unsigned char customResetReason();
void customResetReason(unsigned char reason);
void customResetReason(CustomResetReason reason);
CustomResetReason customResetReason();
String customResetReasonToPayload(CustomResetReason reason);
void deferredReset(unsigned long delay, unsigned char reason);
void deferredReset(unsigned long delay, CustomResetReason reason);
bool checkNeedsReset();
unsigned long systemLoadAverage();


+ 3
- 3
code/espurna/terminal.cpp View File

@ -288,7 +288,7 @@ void _terminalInitCommands() {
terminalRegisterCommand(F("ERASE.CONFIG"), [](const terminal::CommandContext&) {
terminalOK();
customResetReason(CUSTOM_RESET_TERMINAL);
customResetReason(CustomResetReason::Terminal);
eraseSDKConfig();
*((int*) 0) = 0; // see https://github.com/esp8266/Arduino/issues/1494
});
@ -358,13 +358,13 @@ void _terminalInitCommands() {
terminalRegisterCommand(F("RESET"), [](const terminal::CommandContext&) {
terminalOK();
deferredReset(100, CUSTOM_RESET_TERMINAL);
deferredReset(100, CustomResetReason::Terminal);
});
terminalRegisterCommand(F("RESET.SAFE"), [](const terminal::CommandContext&) {
systemStabilityCounter(SYSTEM_CHECK_MAX);
terminalOK();
deferredReset(100, CUSTOM_RESET_TERMINAL);
deferredReset(100, CustomResetReason::Terminal);
});
terminalRegisterCommand(F("UPTIME"), [](const terminal::CommandContext&) {


+ 20
- 42
code/espurna/utils.cpp View File

@ -24,23 +24,6 @@ Copyright (C) 2017-2019 by Xose Pérez <xose dot perez at gmail dot com>
// Reset reasons
//--------------------------------------------------------------------------------
PROGMEM const char custom_reset_hardware[] = "Hardware button";
PROGMEM const char custom_reset_web[] = "Reboot from web interface";
PROGMEM const char custom_reset_terminal[] = "Reboot from terminal";
PROGMEM const char custom_reset_mqtt[] = "Reboot from MQTT";
PROGMEM const char custom_reset_rpc[] = "Reboot from RPC";
PROGMEM const char custom_reset_ota[] = "Reboot after successful OTA update";
PROGMEM const char custom_reset_http[] = "Reboot from HTTP";
PROGMEM const char custom_reset_nofuss[] = "Reboot after successful NoFUSS update";
PROGMEM const char custom_reset_upgrade[] = "Reboot after successful web update";
PROGMEM const char custom_reset_factory[] = "Factory reset";
PROGMEM const char* const custom_reset_string[] = {
custom_reset_hardware, custom_reset_web, custom_reset_terminal,
custom_reset_mqtt, custom_reset_rpc, custom_reset_ota,
custom_reset_http, custom_reset_nofuss, custom_reset_upgrade,
custom_reset_factory
};
void setDefaultHostname() {
if (strlen(HOSTNAME) > 0) {
setSetting("hostname", F(HOSTNAME));
@ -540,13 +523,10 @@ const char* _info_wifi_sleep_mode(WiFiSleepType_t type) {
void info(bool first) {
// Avoid printing on early boot when buffering is enabled
#if DEBUG_SUPPORT
#if DEBUG_LOG_BUFFER_SUPPORT
if (first && debugLogBuffer()) return;
#endif
#if DEBUG_SUPPORT
#if DEBUG_LOG_BUFFER_SUPPORT
if (first && debugLogBuffer()) return;
#endif
DEBUG_MSG_P(PSTR("\n\n---8<-------\n\n"));
@ -618,14 +598,13 @@ void info(bool first) {
DEBUG_MSG_P(PSTR("[MAIN] Boot version: %d\n"), ESP.getBootVersion());
DEBUG_MSG_P(PSTR("[MAIN] Boot mode: %d\n"), ESP.getBootMode());
unsigned char reason = customResetReason();
if (reason > 0) {
char buffer[32];
strcpy_P(buffer, custom_reset_string[reason-1]);
DEBUG_MSG_P(PSTR("[MAIN] Last reset reason: %s\n"), buffer);
auto reason = customResetReason();
if (CustomResetReason::None != reason) {
DEBUG_MSG_P(PSTR("[MAIN] Last reset reason: %s\n"), customResetReasonToPayload(reason).c_str());
} else {
DEBUG_MSG_P(PSTR("[MAIN] Last reset reason: %s\n"), (char *) ESP.getResetReason().c_str());
DEBUG_MSG_P(PSTR("[MAIN] Last reset info: %s\n"), (char *) ESP.getResetInfo().c_str());
DEBUG_MSG_P(PSTR("[MAIN] Last reset reason: %s\n"), ESP.getResetReason().c_str());
DEBUG_MSG_P(PSTR("[MAIN] Last reset info: %s\n"), ESP.getResetInfo().c_str());
}
DEBUG_MSG_P(PSTR("\n"));
@ -634,9 +613,9 @@ void info(bool first) {
DEBUG_MSG_P(PSTR("[MAIN] Board: %s\n"), getBoardName().c_str());
DEBUG_MSG_P(PSTR("[MAIN] Support: %s\n"), getEspurnaModules().c_str());
DEBUG_MSG_P(PSTR("[MAIN] OTA: %s\n"), getEspurnaOTAModules().c_str());
#if SENSOR_SUPPORT
DEBUG_MSG_P(PSTR("[MAIN] Sensors: %s\n"), getEspurnaSensors().c_str());
#endif // SENSOR_SUPPORT
#if SENSOR_SUPPORT
DEBUG_MSG_P(PSTR("[MAIN] Sensors: %s\n"), getEspurnaSensors().c_str());
#endif
DEBUG_MSG_P(PSTR("[MAIN] WebUI image: %s\n"), getEspurnaWebUI().c_str());
DEBUG_MSG_P(PSTR("\n"));
@ -660,19 +639,18 @@ void info(bool first) {
// -------------------------------------------------------------------------
#if SYSTEM_CHECK_ENABLED
if (!systemCheck()) {
DEBUG_MSG_P(PSTR("\n"));
DEBUG_MSG_P(PSTR("[MAIN] Device is in SAFE MODE\n"));
}
#endif
#if SYSTEM_CHECK_ENABLED
if (!systemCheck()) {
DEBUG_MSG_P(PSTR("\n"));
DEBUG_MSG_P(PSTR("[MAIN] Device is in SAFE MODE\n"));
}
#endif
// -------------------------------------------------------------------------
DEBUG_MSG_P(PSTR("\n\n---8<-------\n\n"));
#endif // DEBUG_SUPPORT == 1
#endif // DEBUG_SUPPORT == 1
}
// -----------------------------------------------------------------------------


+ 1
- 2
code/espurna/web.cpp View File

@ -220,13 +220,12 @@ constexpr const size_t WEB_CONFIG_BUFFER_MAX = 4096;
// -----------------------------------------------------------------------------
void _onReset(AsyncWebServerRequest *request) {
webLog(request);
if (!webAuthenticate(request)) {
return request->requestAuthentication(getSetting("hostname").c_str());
}
deferredReset(100, CUSTOM_RESET_HTTP);
deferredReset(100, CustomResetReason::Web);
request->send(200);
}


+ 2
- 4
code/espurna/ws.cpp View File

@ -338,7 +338,7 @@ void _wsParse(AsyncWebSocketClient *client, uint8_t * payload, size_t length) {
DEBUG_MSG_P(PSTR("[WEBSOCKET] Requested action: %s\n"), action);
if (strcmp(action, "reboot") == 0) {
deferredReset(100, CUSTOM_RESET_WEB);
deferredReset(100, CustomResetReason::Web);
return;
}
@ -352,9 +352,7 @@ void _wsParse(AsyncWebSocketClient *client, uint8_t * payload, size_t length) {
}
if (strcmp(action, "factory_reset") == 0) {
DEBUG_MSG_P(PSTR("\n\nFACTORY RESET\n\n"));
resetSettings();
deferredReset(100, CUSTOM_RESET_FACTORY);
factoryReset();
return;
}


Loading…
Cancel
Save