From 08585b2bf58662164cc494a7d41c97141d994e17 Mon Sep 17 00:00:00 2001 From: iranl Date: Tue, 28 May 2024 15:59:41 +0200 Subject: [PATCH] Factory Reset --- README.md | 4 ++ src/RestartReason.h | 3 ++ src/WebCfgServer.cpp | 97 ++++++++++++++++++++++++++++++++++++++++---- src/WebCfgServer.h | 1 + 4 files changed, 98 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index aa629539..cc8725dd 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,10 @@ In a browser navigate to the IP address assigned to the ESP32. - Type [4 DIGIT CODE] to confirm unpair: Set to the shown randomly generated code to unpair the Nuki Lock or Opener from the Nuki Hub. +#### Factory reset Nuki Hub + +- Type [4 DIGIT CODE] to confirm factory reset: Set to the shown randomly generated code to reset all Nuki Hub settings to default and unpair Nuki Lock and/or Opener. Optionally also reset WiFi settings to default by enabling the checkbox. + ### GPIO Configuration - Gpio [2-33]: See the "[GPIO lock control](#gpio-lock-control-optional)" section of this README. diff --git a/src/RestartReason.h b/src/RestartReason.h index aacb5aa3..cf13a0e8 100644 --- a/src/RestartReason.h +++ b/src/RestartReason.h @@ -20,6 +20,7 @@ enum class RestartReason OTAAborted, OTAUnknownState, DeviceUnpaired, + NukiHubReset, NotApplicable }; @@ -100,6 +101,8 @@ inline static String getRestartReason() return "OTAUnknownState"; case RestartReason::DeviceUnpaired: return "DeviceUnpaired"; + case RestartReason::NukiHubReset: + return "NukiHubFactoryReset"; case RestartReason::NotApplicable: return "NotApplicable"; default: diff --git a/src/WebCfgServer.cpp b/src/WebCfgServer.cpp index 3932b435..bb3e9776 100644 --- a/src/WebCfgServer.cpp +++ b/src/WebCfgServer.cpp @@ -6,6 +6,7 @@ #include "Config.h" #include "RestartReason.h" #include +#include WebCfgServer::WebCfgServer(NukiWrapper* nuki, NukiOpenerWrapper* nukiOpener, Network* network, Gpio* gpio, EthServer* ethServer, Preferences* preferences, bool allowRestartToPortal) : _server(ethServer), @@ -140,6 +141,13 @@ void WebCfgServer::initialize() processUnpair(true); }); + _server.on("/factoryreset", [&]() { + if (_hasCredentials && !_server.authenticate(_credUser, _credPassword)) { + return _server.requestAuthentication(); + } + + processFactoryReset(); + }); _server.on("/wifimanager", [&]() { if (_hasCredentials && !_server.authenticate(_credUser, _credPassword)) { return _server.requestAuthentication(); @@ -489,7 +497,7 @@ bool WebCfgServer::processArgs(String& message) else if(key == "TSKNUKI") { if(value.toInt() > 8191 && value.toInt() < 32769) - { + { _preferences->putInt(preference_task_size_nuki, value.toInt()); configChanged = true; } @@ -505,7 +513,7 @@ bool WebCfgServer::processArgs(String& message) else if(key == "ALMAX") { if(value.toInt() > 0 && value.toInt() < 51) - { + { _preferences->putInt(preference_authlog_max_entries, value.toInt()); configChanged = true; } @@ -513,7 +521,7 @@ bool WebCfgServer::processArgs(String& message) else if(key == "KPMAX") { if(value.toInt() > 0 && value.toInt() < 101) - { + { _preferences->putInt(preference_keypad_max_entries, value.toInt()); configChanged = true; } @@ -521,7 +529,7 @@ bool WebCfgServer::processArgs(String& message) else if(key == "TCMAX") { if(value.toInt() > 0 && value.toInt() < 51) - { + { _preferences->putInt(preference_timecontrol_max_entries, value.toInt()); configChanged = true; } @@ -529,11 +537,11 @@ bool WebCfgServer::processArgs(String& message) else if(key == "BUFFSIZE") { if(value.toInt() > 4095 && value.toInt() < 32769) - { + { _preferences->putInt(preference_buffer_size, value.toInt()); configChanged = true; } - } + } else if(key == "BTLPRST") { _preferences->putBool(preference_enable_bootloop_reset, (value == "1")); @@ -1236,6 +1244,18 @@ void WebCfgServer::buildCredHtml(String &response) response.concat(""); response.concat("
"); } + + response.concat("

Factory reset Nuki Hub

"); + response.concat("

This will reset all settings to default and unpair Nuki Lock and/or Opener. Optionally will also reset WiFi settings and reopen WiFi manager portal.

"); + response.concat("
"); + response.concat(""); + String message = "Type "; + message.concat(_confirmCode); + message.concat(" to confirm factory reset"); + printInputField(response, "CONFIRMTOKEN", message.c_str(), "", 10); + printCheckBox(response, "WIFI", "Also reset WiFi settings", false, ""); + response.concat("
"); + response.concat("
"); response.concat(""); } @@ -1862,7 +1882,7 @@ void WebCfgServer::buildInfoHtml(String &response) response.concat("Network device: "); response.concat(_network->networkDeviceName()); response.concat("\n"); - + if(_network->networkDeviceName() == "Built-in Wi-Fi") { response.concat("BSSID of AP: "); @@ -1941,6 +1961,69 @@ void WebCfgServer::processUnpair(bool opener) restartEsp(RestartReason::DeviceUnpaired); } +void WebCfgServer::processFactoryReset() +{ + bool resetWifi = false; + String response = ""; + if(_server.args() == 0) + { + buildConfirmHtml(response, "Confirm code is invalid.", 3); + _server.send(200, "text/html", response); + return; + } + else + { + String key = _server.argName(0); + String value = _server.arg(0); + + if(key != "CONFIRMTOKEN" || value != _confirmCode) + { + buildConfirmHtml(response, "Confirm code is invalid.", 3); + _server.send(200, "text/html", response); + return; + } + + String key2 = _server.argName(2); + String value2 = _server.arg(2); + + if(key2 == "WIFI" && value2 == "1") + { + resetWifi = true; + buildConfirmHtml(response, "Factory resetting Nuki Hub, unpairing Nuki Lock and Nuki Opener and resetting WiFi.", 3); + } + else buildConfirmHtml(response, "Factory resetting Nuki Hub, unpairing Nuki Lock and Nuki Opener.", 3); + } + + _server.send(200, "text/html", response); + waitAndProcess(false, 2000); + + if(_nuki != nullptr) + { + _nuki->disableHASS(); + _nuki->unpair(); + } + if(_nukiOpener != nullptr) + { + _nukiOpener->disableHASS(); + _nukiOpener->unpair(); + } + + _preferences->clear(); + + if(resetWifi) + { + wifi_config_t current_conf; + esp_wifi_get_config((wifi_interface_t)ESP_IF_WIFI_STA, ¤t_conf); + memset(current_conf.sta.ssid, 0, sizeof(current_conf.sta.ssid)); + memset(current_conf.sta.password, 0, sizeof(current_conf.sta.password)); + esp_wifi_set_config((wifi_interface_t)ESP_IF_WIFI_STA, ¤t_conf); + _network->reconfigureDevice(); + } + + waitAndProcess(false, 3000); + restartEsp(RestartReason::NukiHubReset); +} + void WebCfgServer::buildHtmlHeader(String &response) { response.concat(""); diff --git a/src/WebCfgServer.h b/src/WebCfgServer.h index 6d3deac5..502cda56 100644 --- a/src/WebCfgServer.h +++ b/src/WebCfgServer.h @@ -51,6 +51,7 @@ class WebCfgServer void sendCss(); void sendFavicon(); void processUnpair(bool opener); + void processFactoryReset(); void buildHtmlHeader(String& response); void printInputField(String& response, const char* token, const char* description, const char* value, const size_t& maxLength, const bool& isPassword = false, const bool& showLengthRestriction = false);