Merge pull request #376 from iranl/factory-reset
Add Factory Reset option
This commit is contained in:
@@ -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.
|
- 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 Configuration
|
||||||
|
|
||||||
- Gpio [2-33]: See the "[GPIO lock control](#gpio-lock-control-optional)" section of this README.
|
- Gpio [2-33]: See the "[GPIO lock control](#gpio-lock-control-optional)" section of this README.
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ enum class RestartReason
|
|||||||
OTAAborted,
|
OTAAborted,
|
||||||
OTAUnknownState,
|
OTAUnknownState,
|
||||||
DeviceUnpaired,
|
DeviceUnpaired,
|
||||||
|
NukiHubReset,
|
||||||
NotApplicable
|
NotApplicable
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -100,6 +101,8 @@ inline static String getRestartReason()
|
|||||||
return "OTAUnknownState";
|
return "OTAUnknownState";
|
||||||
case RestartReason::DeviceUnpaired:
|
case RestartReason::DeviceUnpaired:
|
||||||
return "DeviceUnpaired";
|
return "DeviceUnpaired";
|
||||||
|
case RestartReason::NukiHubReset:
|
||||||
|
return "NukiHubFactoryReset";
|
||||||
case RestartReason::NotApplicable:
|
case RestartReason::NotApplicable:
|
||||||
return "NotApplicable";
|
return "NotApplicable";
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "RestartReason.h"
|
#include "RestartReason.h"
|
||||||
#include <esp_task_wdt.h>
|
#include <esp_task_wdt.h>
|
||||||
|
#include <esp_wifi.h>
|
||||||
|
|
||||||
WebCfgServer::WebCfgServer(NukiWrapper* nuki, NukiOpenerWrapper* nukiOpener, Network* network, Gpio* gpio, EthServer* ethServer, Preferences* preferences, bool allowRestartToPortal)
|
WebCfgServer::WebCfgServer(NukiWrapper* nuki, NukiOpenerWrapper* nukiOpener, Network* network, Gpio* gpio, EthServer* ethServer, Preferences* preferences, bool allowRestartToPortal)
|
||||||
: _server(ethServer),
|
: _server(ethServer),
|
||||||
@@ -140,6 +141,13 @@ void WebCfgServer::initialize()
|
|||||||
|
|
||||||
processUnpair(true);
|
processUnpair(true);
|
||||||
});
|
});
|
||||||
|
_server.on("/factoryreset", [&]() {
|
||||||
|
if (_hasCredentials && !_server.authenticate(_credUser, _credPassword)) {
|
||||||
|
return _server.requestAuthentication();
|
||||||
|
}
|
||||||
|
|
||||||
|
processFactoryReset();
|
||||||
|
});
|
||||||
_server.on("/wifimanager", [&]() {
|
_server.on("/wifimanager", [&]() {
|
||||||
if (_hasCredentials && !_server.authenticate(_credUser, _credPassword)) {
|
if (_hasCredentials && !_server.authenticate(_credUser, _credPassword)) {
|
||||||
return _server.requestAuthentication();
|
return _server.requestAuthentication();
|
||||||
@@ -489,7 +497,7 @@ bool WebCfgServer::processArgs(String& message)
|
|||||||
else if(key == "TSKNUKI")
|
else if(key == "TSKNUKI")
|
||||||
{
|
{
|
||||||
if(value.toInt() > 8191 && value.toInt() < 32769)
|
if(value.toInt() > 8191 && value.toInt() < 32769)
|
||||||
{
|
{
|
||||||
_preferences->putInt(preference_task_size_nuki, value.toInt());
|
_preferences->putInt(preference_task_size_nuki, value.toInt());
|
||||||
configChanged = true;
|
configChanged = true;
|
||||||
}
|
}
|
||||||
@@ -505,7 +513,7 @@ bool WebCfgServer::processArgs(String& message)
|
|||||||
else if(key == "ALMAX")
|
else if(key == "ALMAX")
|
||||||
{
|
{
|
||||||
if(value.toInt() > 0 && value.toInt() < 51)
|
if(value.toInt() > 0 && value.toInt() < 51)
|
||||||
{
|
{
|
||||||
_preferences->putInt(preference_authlog_max_entries, value.toInt());
|
_preferences->putInt(preference_authlog_max_entries, value.toInt());
|
||||||
configChanged = true;
|
configChanged = true;
|
||||||
}
|
}
|
||||||
@@ -513,7 +521,7 @@ bool WebCfgServer::processArgs(String& message)
|
|||||||
else if(key == "KPMAX")
|
else if(key == "KPMAX")
|
||||||
{
|
{
|
||||||
if(value.toInt() > 0 && value.toInt() < 101)
|
if(value.toInt() > 0 && value.toInt() < 101)
|
||||||
{
|
{
|
||||||
_preferences->putInt(preference_keypad_max_entries, value.toInt());
|
_preferences->putInt(preference_keypad_max_entries, value.toInt());
|
||||||
configChanged = true;
|
configChanged = true;
|
||||||
}
|
}
|
||||||
@@ -521,7 +529,7 @@ bool WebCfgServer::processArgs(String& message)
|
|||||||
else if(key == "TCMAX")
|
else if(key == "TCMAX")
|
||||||
{
|
{
|
||||||
if(value.toInt() > 0 && value.toInt() < 51)
|
if(value.toInt() > 0 && value.toInt() < 51)
|
||||||
{
|
{
|
||||||
_preferences->putInt(preference_timecontrol_max_entries, value.toInt());
|
_preferences->putInt(preference_timecontrol_max_entries, value.toInt());
|
||||||
configChanged = true;
|
configChanged = true;
|
||||||
}
|
}
|
||||||
@@ -529,11 +537,11 @@ bool WebCfgServer::processArgs(String& message)
|
|||||||
else if(key == "BUFFSIZE")
|
else if(key == "BUFFSIZE")
|
||||||
{
|
{
|
||||||
if(value.toInt() > 4095 && value.toInt() < 32769)
|
if(value.toInt() > 4095 && value.toInt() < 32769)
|
||||||
{
|
{
|
||||||
_preferences->putInt(preference_buffer_size, value.toInt());
|
_preferences->putInt(preference_buffer_size, value.toInt());
|
||||||
configChanged = true;
|
configChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(key == "BTLPRST")
|
else if(key == "BTLPRST")
|
||||||
{
|
{
|
||||||
_preferences->putBool(preference_enable_bootloop_reset, (value == "1"));
|
_preferences->putBool(preference_enable_bootloop_reset, (value == "1"));
|
||||||
@@ -1236,6 +1244,18 @@ void WebCfgServer::buildCredHtml(String &response)
|
|||||||
response.concat("</table>");
|
response.concat("</table>");
|
||||||
response.concat("<br><button type=\"submit\">OK</button></form>");
|
response.concat("<br><button type=\"submit\">OK</button></form>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response.concat("<br><br><h3>Factory reset Nuki Hub</h3>");
|
||||||
|
response.concat("<h4 style=\"color: #ff0000\">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.</h4>");
|
||||||
|
response.concat("<form method=\"post\" action=\"/factoryreset\">");
|
||||||
|
response.concat("<table>");
|
||||||
|
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("</table>");
|
||||||
|
response.concat("<br><button type=\"submit\">OK</button></form>");
|
||||||
response.concat("</body></html>");
|
response.concat("</body></html>");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1862,7 +1882,7 @@ void WebCfgServer::buildInfoHtml(String &response)
|
|||||||
response.concat("Network device: ");
|
response.concat("Network device: ");
|
||||||
response.concat(_network->networkDeviceName());
|
response.concat(_network->networkDeviceName());
|
||||||
response.concat("\n");
|
response.concat("\n");
|
||||||
|
|
||||||
if(_network->networkDeviceName() == "Built-in Wi-Fi")
|
if(_network->networkDeviceName() == "Built-in Wi-Fi")
|
||||||
{
|
{
|
||||||
response.concat("BSSID of AP: ");
|
response.concat("BSSID of AP: ");
|
||||||
@@ -1941,6 +1961,69 @@ void WebCfgServer::processUnpair(bool opener)
|
|||||||
restartEsp(RestartReason::DeviceUnpaired);
|
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)
|
void WebCfgServer::buildHtmlHeader(String &response)
|
||||||
{
|
{
|
||||||
response.concat("<html><head>");
|
response.concat("<html><head>");
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ private:
|
|||||||
void sendCss();
|
void sendCss();
|
||||||
void sendFavicon();
|
void sendFavicon();
|
||||||
void processUnpair(bool opener);
|
void processUnpair(bool opener);
|
||||||
|
void processFactoryReset();
|
||||||
|
|
||||||
void buildHtmlHeader(String& response);
|
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);
|
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user