WiFi portal
This commit is contained in:
@@ -84,7 +84,8 @@ Unpack the zip archive and read the included how-to-flash.txt for installation i
|
|||||||
|
|
||||||
## Initial setup (Network and MQTT)
|
## Initial setup (Network and MQTT)
|
||||||
|
|
||||||
Power up the ESP32 and a new Wi-Fi access point named "ESP32_(8 CHARACTER ALPHANUMERIC)" should appear.<br>
|
Power up the ESP32 and a new Wi-Fi access point named "NukiHub" should appear.<br>
|
||||||
|
The password of the access point is "NukiHubESP32".<br>
|
||||||
Connect a client device to this access point and in a browser navigate to "http://192.168.4.1".<br>
|
Connect a client device to this access point and in a browser navigate to "http://192.168.4.1".<br>
|
||||||
Use the web interface to connect the ESP to your preferred Wi-Fi network.<br>
|
Use the web interface to connect the ESP to your preferred Wi-Fi network.<br>
|
||||||
<br>
|
<br>
|
||||||
@@ -138,7 +139,7 @@ PSRAM is usually 2, 4 or 8MB in size and thus greatly enlarges the 320kb of inte
|
|||||||
It is basically impossible to run out of RAM when PSRAM is available.
|
It is basically impossible to run out of RAM when PSRAM is available.
|
||||||
You can check on the info page of the Web configurator if PSRAM is available.
|
You can check on the info page of the Web configurator if PSRAM is available.
|
||||||
|
|
||||||
Note that there are two build of Nuki Hub for the ESP32-S3 available.<br>
|
Note that there are two builds of Nuki Hub for the ESP32-S3 available.<br>
|
||||||
One for devices with no or Quad SPI PSRAM and one for devices with Octal SPI PSRAM.<br>
|
One for devices with no or Quad SPI PSRAM and one for devices with Octal SPI PSRAM.<br>
|
||||||
If your ESP32-S3 device has PSRAM but it is not detected please flash the other S3 binary.
|
If your ESP32-S3 device has PSRAM but it is not detected please flash the other S3 binary.
|
||||||
|
|
||||||
@@ -165,7 +166,6 @@ In a browser navigate to the IP address assigned to the ESP32.
|
|||||||
- MQTT SSL Client Certificate: Optionally set to the Client SSL certificate of the MQTT broker, see the "[MQTT Encryption](#mqtt-encryption-optional)" section of this README.
|
- MQTT SSL Client Certificate: Optionally set to the Client SSL certificate of the MQTT broker, see the "[MQTT Encryption](#mqtt-encryption-optional)" section of this README.
|
||||||
- MQTT SSL Client Key: Optionally set to the Client SSL key of the MQTT broker, see the "[MQTT Encryption](#mqtt-encryption-optional)" section of this README.
|
- MQTT SSL Client Key: Optionally set to the Client SSL key of the MQTT broker, see the "[MQTT Encryption](#mqtt-encryption-optional)" section of this README.
|
||||||
- Network hardware: "Wi-Fi only" by default, set to one of the specified ethernet modules if available, see the "Supported Ethernet devices" and "[Connecting via Ethernet](#connecting-via-ethernet-optional)" section of this README.
|
- Network hardware: "Wi-Fi only" by default, set to one of the specified ethernet modules if available, see the "Supported Ethernet devices" and "[Connecting via Ethernet](#connecting-via-ethernet-optional)" section of this README.
|
||||||
- Disable fallback to Wi-Fi / Wi-Fi config portal: By default the Nuki Hub will fallback to Wi-Fi and open the Wi-Fi configuration portal when the network connection fails. Enable this setting to disable this fallback.
|
|
||||||
- Connect to AP with the best signal in an environment with multiple APs with the same SSID: Enable to perform a scan for the Access Point with the best signal strenght for the specified SSID in a multi AP/Mesh environment.
|
- Connect to AP with the best signal in an environment with multiple APs with the same SSID: Enable to perform a scan for the Access Point with the best signal strenght for the specified SSID in a multi AP/Mesh environment.
|
||||||
- RSSI Publish interval: Set to a positive integer to set the amount of seconds between updates to the maintenance/wifiRssi MQTT topic with the current Wi-Fi RSSI, set to -1 to disable, default 60.
|
- RSSI Publish interval: Set to a positive integer to set the amount of seconds between updates to the maintenance/wifiRssi MQTT topic with the current Wi-Fi RSSI, set to -1 to disable, default 60.
|
||||||
- MQTT Timeout until restart: Set to a positive integer to restart the Nuki Hub after the set amount of seconds has passed without an active connection to the MQTT broker, set to -1 to disable, default 60.
|
- MQTT Timeout until restart: Set to a positive integer to restart the Nuki Hub after the set amount of seconds has passed without an active connection to the MQTT broker, set to -1 to disable, default 60.
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ board_build.partitions = partitions.csv
|
|||||||
build_unflags =
|
build_unflags =
|
||||||
-DCONFIG_BT_NIMBLE_LOG_LEVEL
|
-DCONFIG_BT_NIMBLE_LOG_LEVEL
|
||||||
-DCONFIG_BTDM_BLE_SCAN_DUPL
|
-DCONFIG_BTDM_BLE_SCAN_DUPL
|
||||||
|
-DESP32
|
||||||
-Werror=all
|
-Werror=all
|
||||||
-Wall
|
-Wall
|
||||||
build_flags =
|
build_flags =
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#define NUKI_HUB_VERSION "9.01"
|
#define NUKI_HUB_VERSION "9.01"
|
||||||
#define NUKI_HUB_BUILD "unknownbuildnr"
|
#define NUKI_HUB_BUILD "unknownbuildnr"
|
||||||
#define NUKI_HUB_DATE "2024-09-06"
|
#define NUKI_HUB_DATE "2024-10-14"
|
||||||
|
|
||||||
#define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest"
|
#define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest"
|
||||||
#define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json"
|
#define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json"
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ void NukiNetwork::setupDevice()
|
|||||||
{
|
{
|
||||||
_ipConfiguration = new IPConfiguration(_preferences);
|
_ipConfiguration = new IPConfiguration(_preferences);
|
||||||
int hardwareDetect = _preferences->getInt(preference_network_hardware, 0);
|
int hardwareDetect = _preferences->getInt(preference_network_hardware, 0);
|
||||||
Log->print(F("Hardware detect : "));
|
Log->print(F("Hardware detect: "));
|
||||||
Log->println(hardwareDetect);
|
Log->println(hardwareDetect);
|
||||||
|
|
||||||
_firstBootAfterDeviceChange = _preferences->getBool(preference_ntw_reconfigure, false);
|
_firstBootAfterDeviceChange = _preferences->getBool(preference_ntw_reconfigure, false);
|
||||||
@@ -95,7 +95,7 @@ void NukiNetwork::setupDevice()
|
|||||||
if(strcmp(WiFi_fallbackDetect, "wifi_fallback") == 0)
|
if(strcmp(WiFi_fallbackDetect, "wifi_fallback") == 0)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
if(_preferences->getBool(preference_network_wifi_fallback_disabled) && !_firstBootAfterDeviceChange)
|
if(!_firstBootAfterDeviceChange)
|
||||||
{
|
{
|
||||||
Log->println(F("Failed to connect to network. Wi-Fi fallback is disabled, rebooting."));
|
Log->println(F("Failed to connect to network. Wi-Fi fallback is disabled, rebooting."));
|
||||||
memset(WiFi_fallbackDetect, 0, sizeof(WiFi_fallbackDetect));
|
memset(WiFi_fallbackDetect, 0, sizeof(WiFi_fallbackDetect));
|
||||||
@@ -122,7 +122,7 @@ void NukiNetwork::setupDevice()
|
|||||||
_device = NetworkDeviceInstantiator::Create(_networkDeviceType, _hostname, _preferences, _ipConfiguration);
|
_device = NetworkDeviceInstantiator::Create(_networkDeviceType, _hostname, _preferences, _ipConfiguration);
|
||||||
|
|
||||||
Log->print(F("Network device: "));
|
Log->print(F("Network device: "));
|
||||||
Log->print(_device->deviceName());
|
Log->println(_device->deviceName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiNetwork::reconfigureDevice()
|
void NukiNetwork::reconfigureDevice()
|
||||||
@@ -130,6 +130,16 @@ void NukiNetwork::reconfigureDevice()
|
|||||||
_device->reconfigure();
|
_device->reconfigure();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NukiNetwork::scan(bool passive, bool async)
|
||||||
|
{
|
||||||
|
_device->scan(passive, async);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NukiNetwork::isApOpen()
|
||||||
|
{
|
||||||
|
return _device->isApOpen();
|
||||||
|
}
|
||||||
|
|
||||||
const String NukiNetwork::networkDeviceName() const
|
const String NukiNetwork::networkDeviceName() const
|
||||||
{
|
{
|
||||||
return _device->deviceName();
|
return _device->deviceName();
|
||||||
@@ -317,7 +327,6 @@ void NukiNetwork::readSettings()
|
|||||||
{
|
{
|
||||||
_restartOnDisconnect = _preferences->getBool(preference_restart_on_disconnect, false);
|
_restartOnDisconnect = _preferences->getBool(preference_restart_on_disconnect, false);
|
||||||
_checkUpdates = _preferences->getBool(preference_check_updates, false);
|
_checkUpdates = _preferences->getBool(preference_check_updates, false);
|
||||||
_reconnectNetworkOnMqttDisconnect = _preferences->getBool(preference_recon_netw_on_mqtt_discon, false);
|
|
||||||
_rssiPublishInterval = _preferences->getInt(preference_rssi_publish_interval, 0) * 1000;
|
_rssiPublishInterval = _preferences->getInt(preference_rssi_publish_interval, 0) * 1000;
|
||||||
|
|
||||||
if(_rssiPublishInterval == 0)
|
if(_rssiPublishInterval == 0)
|
||||||
@@ -341,38 +350,17 @@ bool NukiNetwork::update()
|
|||||||
int64_t ts = (esp_timer_get_time() / 1000);
|
int64_t ts = (esp_timer_get_time() / 1000);
|
||||||
_device->update();
|
_device->update();
|
||||||
|
|
||||||
if(!_mqttEnabled)
|
if(!_mqttEnabled || _device->isApOpen())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!_device->isConnected() || (_mqttConnectCounter > 15 && _reconnectNetworkOnMqttDisconnect && !_firstConnect))
|
if(!_device->isConnected() || (_mqttConnectCounter > 15 && !_firstConnect))
|
||||||
{
|
{
|
||||||
_mqttConnectCounter = 0;
|
_mqttConnectCounter = 0;
|
||||||
|
|
||||||
if(!_webEnabled) forceEnableWebServer = true;
|
if(!_webEnabled) forceEnableWebServer = true;
|
||||||
if(_restartOnDisconnect && (esp_timer_get_time() / 1000) > 60000) restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
if(_restartOnDisconnect && (esp_timer_get_time() / 1000) > 60000) restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
||||||
|
|
||||||
Log->println(F("Network not connected. Trying reconnect."));
|
|
||||||
ReconnectStatus reconnectStatus = _device->reconnect(true);
|
|
||||||
|
|
||||||
switch(reconnectStatus)
|
|
||||||
{
|
|
||||||
case ReconnectStatus::CriticalFailure:
|
|
||||||
strcpy(WiFi_fallbackDetect, "wifi_fallback");
|
|
||||||
Log->println("Network device has a critical failure, enable fallback to Wi-Fi and reboot.");
|
|
||||||
delay(200);
|
|
||||||
restartEsp(RestartReason::NetworkDeviceCriticalFailure);
|
|
||||||
break;
|
|
||||||
case ReconnectStatus::Success:
|
|
||||||
memset(WiFi_fallbackDetect, 0, sizeof(WiFi_fallbackDetect));
|
|
||||||
Log->print(F("Reconnect successful: IP: "));
|
|
||||||
Log->println(_device->localIP());
|
|
||||||
break;
|
|
||||||
case ReconnectStatus::Failure:
|
|
||||||
Log->println(F("Reconnect failed"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_device->isConnected() && !_mqttClientInitiated && strcmp(_mqttBrokerAddr, "") != 0)
|
if(_device->isConnected() && !_mqttClientInitiated && strcmp(_mqttBrokerAddr, "") != 0)
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ public:
|
|||||||
void readSettings();
|
void readSettings();
|
||||||
bool update();
|
bool update();
|
||||||
void reconfigureDevice();
|
void reconfigureDevice();
|
||||||
|
void scan(bool passive = false, bool async = true);
|
||||||
|
bool isApOpen();
|
||||||
void clearWifiFallback();
|
void clearWifiFallback();
|
||||||
|
|
||||||
const String networkDeviceName() const;
|
const String networkDeviceName() const;
|
||||||
@@ -168,7 +170,6 @@ private:
|
|||||||
std::vector<MqttReceiver*> _mqttReceivers;
|
std::vector<MqttReceiver*> _mqttReceivers;
|
||||||
bool _restartOnDisconnect = false;
|
bool _restartOnDisconnect = false;
|
||||||
bool _checkUpdates = false;
|
bool _checkUpdates = false;
|
||||||
bool _reconnectNetworkOnMqttDisconnect = false;
|
|
||||||
bool _firstConnect = true;
|
bool _firstConnect = true;
|
||||||
bool _publishDebugInfo = false;
|
bool _publishDebugInfo = false;
|
||||||
bool _logIp = true;
|
bool _logIp = true;
|
||||||
|
|||||||
@@ -1772,21 +1772,21 @@ void NukiOpenerWrapper::onKeypadJsonCommandReceived(const char *value)
|
|||||||
String allowedFromTime;
|
String allowedFromTime;
|
||||||
String allowedUntilTime;
|
String allowedUntilTime;
|
||||||
|
|
||||||
if(json.containsKey("code")) code = json["code"].as<unsigned int>();
|
if(json["code"].is<unsigned int>()) code = json["code"].as<unsigned int>();
|
||||||
else code = 12;
|
else code = 12;
|
||||||
|
|
||||||
if(json.containsKey("enabled")) enabled = json["enabled"].as<unsigned int>();
|
if(json["enabled"].is<unsigned int>()) enabled = json["enabled"].as<unsigned int>();
|
||||||
else enabled = 2;
|
else enabled = 2;
|
||||||
|
|
||||||
if(json.containsKey("timeLimited")) timeLimited = json["timeLimited"].as<unsigned int>();
|
if(json["timeLimited"].is<unsigned int>()) timeLimited = json["timeLimited"].as<unsigned int>();
|
||||||
else timeLimited = 2;
|
else timeLimited = 2;
|
||||||
|
|
||||||
if(json.containsKey("name")) name = json["name"].as<String>();
|
if(json["name"].is<String>()) name = json["name"].as<String>();
|
||||||
if(json.containsKey("allowedFrom")) allowedFrom = json["allowedFrom"].as<String>();
|
if(json["allowedFrom"].is<String>()) allowedFrom = json["allowedFrom"].as<String>();
|
||||||
if(json.containsKey("allowedUntil")) allowedUntil = json["allowedUntil"].as<String>();
|
if(json["allowedUntil"].is<String>()) allowedUntil = json["allowedUntil"].as<String>();
|
||||||
if(json.containsKey("allowedWeekdays")) allowedWeekdays = json["allowedWeekdays"].as<String>();
|
if(json["allowedWeekdays"].is<String>()) allowedWeekdays = json["allowedWeekdays"].as<String>();
|
||||||
if(json.containsKey("allowedFromTime")) allowedFromTime = json["allowedFromTime"].as<String>();
|
if(json["allowedFromTime"].is<String>()) allowedFromTime = json["allowedFromTime"].as<String>();
|
||||||
if(json.containsKey("allowedUntilTime")) allowedUntilTime = json["allowedUntilTime"].as<String>();
|
if(json["allowedUntilTime"].is<String>()) allowedUntilTime = json["allowedUntilTime"].as<String>();
|
||||||
|
|
||||||
if(action)
|
if(action)
|
||||||
{
|
{
|
||||||
@@ -2209,12 +2209,12 @@ void NukiOpenerWrapper::onTimeControlCommandReceived(const char *value)
|
|||||||
String lockAction;
|
String lockAction;
|
||||||
NukiOpener::LockAction timeControlLockAction;
|
NukiOpener::LockAction timeControlLockAction;
|
||||||
|
|
||||||
if(json.containsKey("enabled")) enabled = json["enabled"].as<unsigned int>();
|
if(json["enabled"].is<unsigned int>()) enabled = json["enabled"].as<unsigned int>();
|
||||||
else enabled = 2;
|
else enabled = 2;
|
||||||
|
|
||||||
if(json.containsKey("weekdays")) weekdays = json["weekdays"].as<String>();
|
if(json["weekdays"].is<String>()) weekdays = json["weekdays"].as<String>();
|
||||||
if(json.containsKey("time")) time = json["time"].as<String>();
|
if(json["time"].is<String>()) time = json["time"].as<String>();
|
||||||
if(json.containsKey("lockAction")) lockAction = json["lockAction"].as<String>();
|
if(json["lockAction"].is<String>()) lockAction = json["lockAction"].as<String>();
|
||||||
|
|
||||||
if(lockAction.length() > 0)
|
if(lockAction.length() > 0)
|
||||||
{
|
{
|
||||||
@@ -2443,22 +2443,22 @@ void NukiOpenerWrapper::onAuthCommandReceived(const char *value)
|
|||||||
String allowedFromTime;
|
String allowedFromTime;
|
||||||
String allowedUntilTime;
|
String allowedUntilTime;
|
||||||
|
|
||||||
if(json.containsKey("remoteAllowed")) remoteAllowed = json["remoteAllowed"].as<unsigned int>();
|
if(json["remoteAllowed"].is<unsigned int>()) remoteAllowed = json["remoteAllowed"].as<unsigned int>();
|
||||||
else remoteAllowed = 2;
|
else remoteAllowed = 2;
|
||||||
|
|
||||||
if(json.containsKey("enabled")) enabled = json["enabled"].as<unsigned int>();
|
if(json["enabled"].is<unsigned int>()) enabled = json["enabled"].as<unsigned int>();
|
||||||
else enabled = 2;
|
else enabled = 2;
|
||||||
|
|
||||||
if(json.containsKey("timeLimited")) timeLimited = json["timeLimited"].as<unsigned int>();
|
if(json["timeLimited"].is<unsigned int>()) timeLimited = json["timeLimited"].as<unsigned int>();
|
||||||
else timeLimited = 2;
|
else timeLimited = 2;
|
||||||
|
|
||||||
if(json.containsKey("name")) name = json["name"].as<String>();
|
if(json["name"].is<String>()) name = json["name"].as<String>();
|
||||||
//if(json.containsKey("sharedKey")) sharedKey = json["sharedKey"].as<String>();
|
//if(json["sharedKey"].is<String>()) sharedKey = json["sharedKey"].as<String>();
|
||||||
if(json.containsKey("allowedFrom")) allowedFrom = json["allowedFrom"].as<String>();
|
if(json["allowedFrom"].is<String>()) allowedFrom = json["allowedFrom"].as<String>();
|
||||||
if(json.containsKey("allowedUntil")) allowedUntil = json["allowedUntil"].as<String>();
|
if(json["allowedUntil"].is<String>()) allowedUntil = json["allowedUntil"].as<String>();
|
||||||
if(json.containsKey("allowedWeekdays")) allowedWeekdays = json["allowedWeekdays"].as<String>();
|
if(json["allowedWeekdays"].is<String>()) allowedWeekdays = json["allowedWeekdays"].as<String>();
|
||||||
if(json.containsKey("allowedFromTime")) allowedFromTime = json["allowedFromTime"].as<String>();
|
if(json["allowedFromTime"].is<String>()) allowedFromTime = json["allowedFromTime"].as<String>();
|
||||||
if(json.containsKey("allowedUntilTime")) allowedUntilTime = json["allowedUntilTime"].as<String>();
|
if(json["allowedUntilTime"].is<String>()) allowedUntilTime = json["allowedUntilTime"].as<String>();
|
||||||
|
|
||||||
if(action)
|
if(action)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#endif
|
||||||
#include "NukiWrapper.h"
|
#include "NukiWrapper.h"
|
||||||
#include "PreferencesKeys.h"
|
#include "PreferencesKeys.h"
|
||||||
#include "MqttTopics.h"
|
#include "MqttTopics.h"
|
||||||
@@ -58,8 +61,24 @@ void NukiWrapper::initialize(const bool& firstStart)
|
|||||||
if(firstStart)
|
if(firstStart)
|
||||||
{
|
{
|
||||||
Log->println("First start, setting preference defaults");
|
Log->println("First start, setting preference defaults");
|
||||||
_preferences->putBool(preference_network_wifi_fallback_disabled, false);
|
|
||||||
_preferences->putBool(preference_find_best_rssi, false);
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
wifi_config_t wifi_cfg;
|
||||||
|
if(esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) {
|
||||||
|
Log->println("Failed to get Wi-Fi configuration in RAM");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esp_wifi_set_storage(WIFI_STORAGE_FLASH) != ESP_OK) {
|
||||||
|
Log->println("Failed to set storage Wi-Fi");
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(wifi_cfg.sta.ssid, 0, sizeof(wifi_cfg.sta.ssid));
|
||||||
|
memset(wifi_cfg.sta.password, 0, sizeof(wifi_cfg.sta.password));
|
||||||
|
|
||||||
|
if (esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) {
|
||||||
|
Log->println("Failed to clear NVS Wi-Fi configuration");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
_preferences->putBool(preference_check_updates, true);
|
_preferences->putBool(preference_check_updates, true);
|
||||||
_preferences->putBool(preference_opener_continuous_mode, false);
|
_preferences->putBool(preference_opener_continuous_mode, false);
|
||||||
_preferences->putBool(preference_official_hybrid_enabled, false);
|
_preferences->putBool(preference_official_hybrid_enabled, false);
|
||||||
@@ -1894,21 +1913,21 @@ void NukiWrapper::onKeypadJsonCommandReceived(const char *value)
|
|||||||
String allowedFromTime;
|
String allowedFromTime;
|
||||||
String allowedUntilTime;
|
String allowedUntilTime;
|
||||||
|
|
||||||
if(json.containsKey("code")) code = json["code"].as<unsigned int>();
|
if(json["code"].is<unsigned int>()) code = json["code"].as<unsigned int>();
|
||||||
else code = 12;
|
else code = 12;
|
||||||
|
|
||||||
if(json.containsKey("enabled")) enabled = json["enabled"].as<unsigned int>();
|
if(json["enabled"].is<unsigned int>()) enabled = json["enabled"].as<unsigned int>();
|
||||||
else enabled = 2;
|
else enabled = 2;
|
||||||
|
|
||||||
if(json.containsKey("timeLimited")) timeLimited = json["timeLimited"].as<unsigned int>();
|
if(json["timeLimited"].is<unsigned int>()) timeLimited = json["timeLimited"].as<unsigned int>();
|
||||||
else timeLimited = 2;
|
else timeLimited = 2;
|
||||||
|
|
||||||
if(json.containsKey("name")) name = json["name"].as<String>();
|
if(json["name"].is<String>()) name = json["name"].as<String>();
|
||||||
if(json.containsKey("allowedFrom")) allowedFrom = json["allowedFrom"].as<String>();
|
if(json["allowedFrom"].is<String>()) allowedFrom = json["allowedFrom"].as<String>();
|
||||||
if(json.containsKey("allowedUntil")) allowedUntil = json["allowedUntil"].as<String>();
|
if(json["allowedUntil"].is<String>()) allowedUntil = json["allowedUntil"].as<String>();
|
||||||
if(json.containsKey("allowedWeekdays")) allowedWeekdays = json["allowedWeekdays"].as<String>();
|
if(json["allowedWeekdays"].is<String>()) allowedWeekdays = json["allowedWeekdays"].as<String>();
|
||||||
if(json.containsKey("allowedFromTime")) allowedFromTime = json["allowedFromTime"].as<String>();
|
if(json["allowedFromTime"].is<String>()) allowedFromTime = json["allowedFromTime"].as<String>();
|
||||||
if(json.containsKey("allowedUntilTime")) allowedUntilTime = json["allowedUntilTime"].as<String>();
|
if(json["allowedUntilTime"].is<String>()) allowedUntilTime = json["allowedUntilTime"].as<String>();
|
||||||
|
|
||||||
if(action)
|
if(action)
|
||||||
{
|
{
|
||||||
@@ -2331,12 +2350,12 @@ void NukiWrapper::onTimeControlCommandReceived(const char *value)
|
|||||||
String lockAction;
|
String lockAction;
|
||||||
NukiLock::LockAction timeControlLockAction;
|
NukiLock::LockAction timeControlLockAction;
|
||||||
|
|
||||||
if(json.containsKey("enabled")) enabled = json["enabled"].as<unsigned int>();
|
if(json["enabled"].is<unsigned int>()) enabled = json["enabled"].as<unsigned int>();
|
||||||
else enabled = 2;
|
else enabled = 2;
|
||||||
|
|
||||||
if(json.containsKey("weekdays")) weekdays = json["weekdays"].as<String>();
|
if(json["weekdays"].is<String>()) weekdays = json["weekdays"].as<String>();
|
||||||
if(json.containsKey("time")) time = json["time"].as<String>();
|
if(json["time"].is<String>()) time = json["time"].as<String>();
|
||||||
if(json.containsKey("lockAction")) lockAction = json["lockAction"].as<String>();
|
if(json["lockAction"].is<String>()) lockAction = json["lockAction"].as<String>();
|
||||||
|
|
||||||
if(lockAction.length() > 0)
|
if(lockAction.length() > 0)
|
||||||
{
|
{
|
||||||
@@ -2567,22 +2586,22 @@ void NukiWrapper::onAuthCommandReceived(const char *value)
|
|||||||
String allowedFromTime;
|
String allowedFromTime;
|
||||||
String allowedUntilTime;
|
String allowedUntilTime;
|
||||||
|
|
||||||
if(json.containsKey("remoteAllowed")) remoteAllowed = json["remoteAllowed"].as<unsigned int>();
|
if(json["remoteAllowed"].is<unsigned int>()) remoteAllowed = json["remoteAllowed"].as<unsigned int>();
|
||||||
else remoteAllowed = 2;
|
else remoteAllowed = 2;
|
||||||
|
|
||||||
if(json.containsKey("enabled")) enabled = json["enabled"].as<unsigned int>();
|
if(json["enabled"].is<unsigned int>()) enabled = json["enabled"].as<unsigned int>();
|
||||||
else enabled = 2;
|
else enabled = 2;
|
||||||
|
|
||||||
if(json.containsKey("timeLimited")) timeLimited = json["timeLimited"].as<unsigned int>();
|
if(json["timeLimited"].is<unsigned int>()) timeLimited = json["timeLimited"].as<unsigned int>();
|
||||||
else timeLimited = 2;
|
else timeLimited = 2;
|
||||||
|
|
||||||
if(json.containsKey("name")) name = json["name"].as<String>();
|
if(json["name"].is<String>()) name = json["name"].as<String>();
|
||||||
//if(json.containsKey("sharedKey")) sharedKey = json["sharedKey"].as<String>();
|
//if(json["sharedKey"].is<String>()) sharedKey = json["sharedKey"].as<String>();
|
||||||
if(json.containsKey("allowedFrom")) allowedFrom = json["allowedFrom"].as<String>();
|
if(json["allowedFrom"].is<String>()) allowedFrom = json["allowedFrom"].as<String>();
|
||||||
if(json.containsKey("allowedUntil")) allowedUntil = json["allowedUntil"].as<String>();
|
if(json["allowedUntil"].is<String>()) allowedUntil = json["allowedUntil"].as<String>();
|
||||||
if(json.containsKey("allowedWeekdays")) allowedWeekdays = json["allowedWeekdays"].as<String>();
|
if(json["allowedWeekdays"].is<String>()) allowedWeekdays = json["allowedWeekdays"].as<String>();
|
||||||
if(json.containsKey("allowedFromTime")) allowedFromTime = json["allowedFromTime"].as<String>();
|
if(json["allowedFromTime"].is<String>()) allowedFromTime = json["allowedFromTime"].as<String>();
|
||||||
if(json.containsKey("allowedUntilTime")) allowedUntilTime = json["allowedUntilTime"].as<String>();
|
if(json["allowedUntilTime"].is<String>()) allowedUntilTime = json["allowedUntilTime"].as<String>();
|
||||||
|
|
||||||
if(action)
|
if(action)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -52,9 +52,10 @@
|
|||||||
#define preference_update_from_mqtt (char*)"updMqtt"
|
#define preference_update_from_mqtt (char*)"updMqtt"
|
||||||
#define preference_disable_non_json (char*)"disnonjson"
|
#define preference_disable_non_json (char*)"disnonjson"
|
||||||
#define preference_official_hybrid_enabled (char*)"offHybrid"
|
#define preference_official_hybrid_enabled (char*)"offHybrid"
|
||||||
|
#define preference_wifi_ssid (char*)"wifiSSID"
|
||||||
|
#define preference_wifi_pass (char*)"wifiPass"
|
||||||
|
|
||||||
// CHANGE DOES NOT REQUIRE REBOOT TO TAKE EFFECT
|
// CHANGE DOES NOT REQUIRE REBOOT TO TAKE EFFECT
|
||||||
#define preference_find_best_rssi (char*)"nwbestrssi"
|
|
||||||
#define preference_ntw_reconfigure (char*)"ntwRECONF"
|
#define preference_ntw_reconfigure (char*)"ntwRECONF"
|
||||||
#define preference_auth_max_entries (char*)"authmaxentry"
|
#define preference_auth_max_entries (char*)"authmaxentry"
|
||||||
#define preference_auth_info_enabled (char*)"authInfoEna"
|
#define preference_auth_info_enabled (char*)"authInfoEna"
|
||||||
@@ -88,14 +89,12 @@
|
|||||||
#define preference_command_retry_delay (char*)"rtryDelay"
|
#define preference_command_retry_delay (char*)"rtryDelay"
|
||||||
#define preference_query_interval_hybrid_lockstate (char*)"hybridTimer"
|
#define preference_query_interval_hybrid_lockstate (char*)"hybridTimer"
|
||||||
#define preference_mqtt_hass_cu_url (char*)"hassConfigUrl"
|
#define preference_mqtt_hass_cu_url (char*)"hassConfigUrl"
|
||||||
#define preference_network_wifi_fallback_disabled (char*)"nwwififb"
|
|
||||||
#define preference_check_updates (char*)"checkupdates"
|
#define preference_check_updates (char*)"checkupdates"
|
||||||
#define preference_opener_continuous_mode (char*)"openercont"
|
#define preference_opener_continuous_mode (char*)"openercont"
|
||||||
#define preference_rssi_publish_interval (char*)"rssipb"
|
#define preference_rssi_publish_interval (char*)"rssipb"
|
||||||
#define preference_network_timeout (char*)"nettmout"
|
#define preference_network_timeout (char*)"nettmout"
|
||||||
#define preference_restart_on_disconnect (char*)"restdisc"
|
#define preference_restart_on_disconnect (char*)"restdisc"
|
||||||
#define preference_publish_debug_info (char*)"pubdbg"
|
#define preference_publish_debug_info (char*)"pubdbg"
|
||||||
#define preference_recon_netw_on_mqtt_discon (char*)"recNtwMqttDis"
|
|
||||||
#define preference_official_hybrid_actions (char*)"hybridAct"
|
#define preference_official_hybrid_actions (char*)"hybridAct"
|
||||||
#define preference_official_hybrid_retry (char*)"hybridRtry"
|
#define preference_official_hybrid_retry (char*)"hybridRtry"
|
||||||
|
|
||||||
@@ -118,12 +117,14 @@
|
|||||||
#define preference_lock_max_timecontrol_entry_count (char*)"maxtc"
|
#define preference_lock_max_timecontrol_entry_count (char*)"maxtc"
|
||||||
#define preference_opener_max_timecontrol_entry_count (char*)"opmaxtc"
|
#define preference_opener_max_timecontrol_entry_count (char*)"opmaxtc"
|
||||||
#define preference_latest_version (char*)"latest"
|
#define preference_latest_version (char*)"latest"
|
||||||
|
#define preference_wifi_converted (char*)"wifiConv"
|
||||||
|
|
||||||
//OBSOLETE
|
//OBSOLETE
|
||||||
#define preference_access_level (char*)"accLvl"
|
#define preference_access_level (char*)"accLvl"
|
||||||
#define preference_gpio_locking_enabled (char*)"gpiolck"
|
#define preference_gpio_locking_enabled (char*)"gpiolck"
|
||||||
#define preference_network_hardware_gpio (char*)"nwhwdt"
|
#define preference_network_hardware_gpio (char*)"nwhwdt"
|
||||||
#define preference_presence_detection_timeout (char*)"prdtimeout"
|
#define preference_presence_detection_timeout (char*)"prdtimeout"
|
||||||
|
#define preference_network_wifi_fallback_disabled (char*)"nwwififb"
|
||||||
|
|
||||||
inline bool initPreferences(Preferences* preferences)
|
inline bool initPreferences(Preferences* preferences)
|
||||||
{
|
{
|
||||||
@@ -248,9 +249,15 @@ inline bool initPreferences(Preferences* preferences)
|
|||||||
if (configVer < 901)
|
if (configVer < 901)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||||
if (preferences->getInt(preference_network_hardware) == 3) preferences->putInt(preference_network_hardware, 10);
|
if (preferences->getInt(preference_network_hardware) == 3)
|
||||||
|
{
|
||||||
|
preferences->putInt(preference_network_hardware, 10);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (preferences->getInt(preference_network_hardware) == 2) preferences->putInt(preference_network_hardware, 3);
|
if (preferences->getInt(preference_network_hardware) == 2)
|
||||||
|
{
|
||||||
|
preferences->putInt(preference_network_hardware, 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
preferences->putInt(preference_config_version, atof(NUKI_HUB_VERSION) * 100);
|
preferences->putInt(preference_config_version, atof(NUKI_HUB_VERSION) * 100);
|
||||||
@@ -271,8 +278,8 @@ private:
|
|||||||
preference_opener_continuous_mode, preference_mqtt_opener_path, preference_lock_max_keypad_code_count, preference_opener_max_keypad_code_count,
|
preference_opener_continuous_mode, preference_mqtt_opener_path, preference_lock_max_keypad_code_count, preference_opener_max_keypad_code_count,
|
||||||
preference_lock_max_timecontrol_entry_count, preference_opener_max_timecontrol_entry_count, preference_enable_bootloop_reset, preference_mqtt_ca, preference_mqtt_crt,
|
preference_lock_max_timecontrol_entry_count, preference_opener_max_timecontrol_entry_count, preference_enable_bootloop_reset, preference_mqtt_ca, preference_mqtt_crt,
|
||||||
preference_mqtt_key, preference_mqtt_hass_discovery, preference_mqtt_hass_cu_url, preference_buffer_size, preference_ip_dhcp_enabled, preference_ip_address,
|
preference_mqtt_key, preference_mqtt_hass_discovery, preference_mqtt_hass_cu_url, preference_buffer_size, preference_ip_dhcp_enabled, preference_ip_address,
|
||||||
preference_ip_subnet, preference_ip_gateway, preference_ip_dns_server, preference_network_hardware, preference_network_wifi_fallback_disabled,
|
preference_ip_subnet, preference_ip_gateway, preference_ip_dns_server, preference_network_hardware,
|
||||||
preference_rssi_publish_interval, preference_hostname, preference_find_best_rssi, preference_network_timeout, preference_restart_on_disconnect,
|
preference_rssi_publish_interval, preference_hostname, preference_network_timeout, preference_restart_on_disconnect,
|
||||||
preference_restart_ble_beacon_lost, preference_query_interval_lockstate, preference_timecontrol_topic_per_entry, preference_keypad_topic_per_entry,
|
preference_restart_ble_beacon_lost, preference_query_interval_lockstate, preference_timecontrol_topic_per_entry, preference_keypad_topic_per_entry,
|
||||||
preference_query_interval_configuration, preference_query_interval_battery, preference_query_interval_keypad, preference_keypad_control_enabled,
|
preference_query_interval_configuration, preference_query_interval_battery, preference_query_interval_keypad, preference_keypad_control_enabled,
|
||||||
preference_keypad_info_enabled, preference_keypad_publish_code, preference_timecontrol_control_enabled, preference_timecontrol_info_enabled, preference_conf_info_enabled,
|
preference_keypad_info_enabled, preference_keypad_publish_code, preference_timecontrol_control_enabled, preference_timecontrol_info_enabled, preference_conf_info_enabled,
|
||||||
@@ -280,26 +287,26 @@ private:
|
|||||||
preference_cred_password, preference_disable_non_json, preference_publish_authdata, preference_publish_debug_info,
|
preference_cred_password, preference_disable_non_json, preference_publish_authdata, preference_publish_debug_info,
|
||||||
preference_official_hybrid_enabled, preference_query_interval_hybrid_lockstate, preference_official_hybrid_actions, preference_official_hybrid_retry,
|
preference_official_hybrid_enabled, preference_query_interval_hybrid_lockstate, preference_official_hybrid_actions, preference_official_hybrid_retry,
|
||||||
preference_task_size_network, preference_task_size_nuki, preference_authlog_max_entries, preference_keypad_max_entries, preference_timecontrol_max_entries,
|
preference_task_size_network, preference_task_size_nuki, preference_authlog_max_entries, preference_keypad_max_entries, preference_timecontrol_max_entries,
|
||||||
preference_update_from_mqtt, preference_show_secrets, preference_ble_tx_power, preference_recon_netw_on_mqtt_discon, preference_webserial_enabled,
|
preference_update_from_mqtt, preference_show_secrets, preference_ble_tx_power, preference_webserial_enabled,
|
||||||
preference_network_custom_mdc, preference_network_custom_clk, preference_network_custom_phy, preference_network_custom_addr, preference_network_custom_irq,
|
preference_network_custom_mdc, preference_network_custom_clk, preference_network_custom_phy, preference_network_custom_addr, preference_network_custom_irq,
|
||||||
preference_network_custom_rst, preference_network_custom_cs, preference_network_custom_sck, preference_network_custom_miso, preference_network_custom_mosi,
|
preference_network_custom_rst, preference_network_custom_cs, preference_network_custom_sck, preference_network_custom_miso, preference_network_custom_mosi,
|
||||||
preference_network_custom_pwr, preference_network_custom_mdio, preference_ntw_reconfigure, preference_lock_max_auth_entry_count, preference_opener_max_auth_entry_count,
|
preference_network_custom_pwr, preference_network_custom_mdio, preference_ntw_reconfigure, preference_lock_max_auth_entry_count, preference_opener_max_auth_entry_count,
|
||||||
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_auth_max_entries,
|
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_auth_max_entries, preference_wifi_ssid, preference_wifi_pass
|
||||||
};
|
};
|
||||||
std::vector<char*> _redact =
|
std::vector<char*> _redact =
|
||||||
{
|
{
|
||||||
preference_mqtt_user, preference_mqtt_password, preference_mqtt_ca, preference_mqtt_crt, preference_mqtt_key, preference_cred_user, preference_cred_password,
|
preference_mqtt_user, preference_mqtt_password, preference_mqtt_ca, preference_mqtt_crt, preference_mqtt_key, preference_cred_user, preference_cred_password,
|
||||||
preference_nuki_id_lock, preference_nuki_id_opener,
|
preference_nuki_id_lock, preference_nuki_id_opener, preference_wifi_pass
|
||||||
};
|
};
|
||||||
std::vector<char*> _boolPrefs =
|
std::vector<char*> _boolPrefs =
|
||||||
{
|
{
|
||||||
preference_started_before, preference_mqtt_log_enabled, preference_check_updates, preference_lock_enabled, preference_opener_enabled, preference_opener_continuous_mode,
|
preference_started_before, preference_mqtt_log_enabled, preference_check_updates, preference_lock_enabled, preference_opener_enabled, preference_opener_continuous_mode,
|
||||||
preference_timecontrol_topic_per_entry, preference_keypad_topic_per_entry, preference_enable_bootloop_reset, preference_webserver_enabled, preference_find_best_rssi,
|
preference_timecontrol_topic_per_entry, preference_keypad_topic_per_entry, preference_enable_bootloop_reset, preference_webserver_enabled,
|
||||||
preference_restart_on_disconnect, preference_keypad_control_enabled, preference_keypad_info_enabled, preference_keypad_publish_code, preference_show_secrets,
|
preference_restart_on_disconnect, preference_keypad_control_enabled, preference_keypad_info_enabled, preference_keypad_publish_code, preference_show_secrets,
|
||||||
preference_timecontrol_control_enabled, preference_timecontrol_info_enabled, preference_register_as_app, preference_register_opener_as_app, preference_ip_dhcp_enabled,
|
preference_timecontrol_control_enabled, preference_timecontrol_info_enabled, preference_register_as_app, preference_register_opener_as_app, preference_ip_dhcp_enabled,
|
||||||
preference_publish_authdata, preference_publish_debug_info, preference_network_wifi_fallback_disabled, preference_official_hybrid_enabled,
|
preference_publish_authdata, preference_publish_debug_info, preference_official_hybrid_enabled,
|
||||||
preference_official_hybrid_actions, preference_official_hybrid_retry, preference_conf_info_enabled, preference_disable_non_json, preference_update_from_mqtt,
|
preference_official_hybrid_actions, preference_official_hybrid_retry, preference_conf_info_enabled, preference_disable_non_json, preference_update_from_mqtt,
|
||||||
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_recon_netw_on_mqtt_discon, preference_webserial_enabled,
|
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_webserial_enabled,
|
||||||
preference_ntw_reconfigure
|
preference_ntw_reconfigure
|
||||||
};
|
};
|
||||||
std::vector<char*> _bytePrefs =
|
std::vector<char*> _bytePrefs =
|
||||||
|
|||||||
@@ -33,12 +33,9 @@ enum class RestartReason
|
|||||||
extern int restartReason;
|
extern int restartReason;
|
||||||
extern uint64_t restartReasonValidDetect;
|
extern uint64_t restartReasonValidDetect;
|
||||||
extern bool rebuildGpioRequested;
|
extern bool rebuildGpioRequested;
|
||||||
|
|
||||||
extern RestartReason currentRestartReason;
|
extern RestartReason currentRestartReason;
|
||||||
|
|
||||||
extern bool restartReason_isValid;
|
extern bool restartReason_isValid;
|
||||||
|
|
||||||
|
|
||||||
inline static void restartEsp(RestartReason reason)
|
inline static void restartEsp(RestartReason reason)
|
||||||
{
|
{
|
||||||
if(reason == RestartReason::GpioConfigurationUpdated)
|
if(reason == RestartReason::GpioConfigurationUpdated)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
#include <esp_wifi.h>
|
#include <esp_wifi.h>
|
||||||
|
#include <WiFi.h>
|
||||||
#endif
|
#endif
|
||||||
#include <Update.h>
|
#include <Update.h>
|
||||||
|
|
||||||
@@ -77,12 +78,22 @@ void WebCfgServer::initialize()
|
|||||||
{
|
{
|
||||||
_psychicServer->on("/", HTTP_GET, [&](PsychicRequest *request){
|
_psychicServer->on("/", HTTP_GET, [&](PsychicRequest *request){
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
#ifndef NUKI_HUB_UPDATER
|
if(!_network->isApOpen())
|
||||||
return buildHtml(request);
|
{
|
||||||
#else
|
#ifndef NUKI_HUB_UPDATER
|
||||||
return buildOtaHtml(request);
|
return buildHtml(request);
|
||||||
|
#else
|
||||||
|
return buildOtaHtml(request);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return buildWifiConnectHtml(request);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
_psychicServer->on("/style.css", HTTP_GET, [&](PsychicRequest *request){
|
_psychicServer->on("/style.css", HTTP_GET, [&](PsychicRequest *request){
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
return sendCss(request);
|
return sendCss(request);
|
||||||
@@ -91,128 +102,6 @@ void WebCfgServer::initialize()
|
|||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
return sendFavicon(request);
|
return sendFavicon(request);
|
||||||
});
|
});
|
||||||
#ifndef NUKI_HUB_UPDATER
|
|
||||||
_psychicServer->on("/import", HTTP_POST, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
String message = "";
|
|
||||||
bool restart = processImport(request, message);
|
|
||||||
return buildConfirmHtml(request, message, 3, true);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/export", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return sendSettings(request);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/impexpcfg", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return buildImportExportHtml(request);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/status", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return buildStatusHtml(request);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/acclvl", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return buildAccLvlHtml(request);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/custntw", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return buildCustomNetworkConfigHtml(request);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/advanced", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return buildAdvancedConfigHtml(request);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/cred", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return buildCredHtml(request);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/mqttconfig", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return buildMqttConfigHtml(request);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/nukicfg", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return buildNukiConfigHtml(request);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/gpiocfg", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return buildGpioConfigHtml(request);
|
|
||||||
});
|
|
||||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
|
||||||
_psychicServer->on("/wifi", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return buildConfigureWifiHtml(request);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/wifimanager", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
if(_allowRestartToPortal)
|
|
||||||
{
|
|
||||||
esp_err_t res = buildConfirmHtml(request, "Restarting. Connect to ESP access point to reconfigure Wi-Fi.", 0);
|
|
||||||
waitAndProcess(false, 1000);
|
|
||||||
_network->reconfigureDevice();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
return(ESP_OK);
|
|
||||||
});
|
|
||||||
#endif
|
|
||||||
_psychicServer->on("/unpairlock", HTTP_POST, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return processUnpair(request, false);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/unpairopener", HTTP_POST, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return processUnpair(request, true);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/factoryreset", HTTP_POST, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return processFactoryReset(request);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/infopg", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return buildInfoHtml(request);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/debugon", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
_preferences->putBool(preference_publish_debug_info, true);
|
|
||||||
return buildConfirmHtml(request, "Debug On", 3, true);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/debugoff", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
_preferences->putBool(preference_publish_debug_info, false);
|
|
||||||
return buildConfirmHtml(request, "Debug Off", 3, true);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/savecfg", HTTP_POST, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
String message = "";
|
|
||||||
bool restart = processArgs(request, message);
|
|
||||||
return buildConfirmHtml(request, message, 3, true);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/savegpiocfg", HTTP_POST, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
processGpioArgs(request);
|
|
||||||
esp_err_t res = buildConfirmHtml(request, "Saving GPIO configuration. Restarting.", 3, true);
|
|
||||||
Log->println(F("Restarting"));
|
|
||||||
waitAndProcess(true, 1000);
|
|
||||||
restartEsp(RestartReason::GpioConfigurationUpdated);
|
|
||||||
return res;
|
|
||||||
});
|
|
||||||
#endif
|
|
||||||
_psychicServer->on("/ota", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return buildOtaHtml(request);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/otadebug", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
return buildOtaHtml(request, true);
|
|
||||||
});
|
|
||||||
_psychicServer->on("/reboottoota", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
esp_err_t res = buildConfirmHtml(request, "Rebooting to other partition", 2, true);
|
|
||||||
waitAndProcess(true, 1000);
|
|
||||||
esp_ota_set_boot_partition(esp_ota_get_next_update_partition(NULL));
|
|
||||||
restartEsp(RestartReason::OTAReboot);
|
|
||||||
return res;
|
|
||||||
});
|
|
||||||
_psychicServer->on("/reboot", HTTP_GET, [&](PsychicRequest *request){
|
_psychicServer->on("/reboot", HTTP_GET, [&](PsychicRequest *request){
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
esp_err_t res = buildConfirmHtml(request, "Rebooting", 2, true);
|
esp_err_t res = buildConfirmHtml(request, "Rebooting", 2, true);
|
||||||
@@ -220,50 +109,371 @@ void WebCfgServer::initialize()
|
|||||||
restartEsp(RestartReason::RequestedViaWebServer);
|
restartEsp(RestartReason::RequestedViaWebServer);
|
||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
_psychicServer->on("/autoupdate", HTTP_GET, [&](PsychicRequest *request){
|
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
|
||||||
#ifndef NUKI_HUB_UPDATER
|
|
||||||
return processUpdate(request);
|
|
||||||
#else
|
|
||||||
return request->redirect("/");
|
|
||||||
#endif
|
|
||||||
});
|
|
||||||
|
|
||||||
PsychicUploadHandler *updateHandler = new PsychicUploadHandler();
|
if(_network->isApOpen())
|
||||||
updateHandler->onUpload([&](PsychicRequest *request, const String& filename, uint64_t index, uint8_t *data, size_t len, bool final)
|
{
|
||||||
{
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
_psychicServer->on("/ssidlist", HTTP_GET, [&](PsychicRequest *request){
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
return handleOtaUpload(request, filename, index, data, len, final);
|
return buildSSIDListHtml(request);
|
||||||
}
|
});
|
||||||
);
|
_psychicServer->on("/savewifi", HTTP_POST, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
String message = "";
|
||||||
|
bool connected = processWiFi(request, message);
|
||||||
|
esp_err_t res = buildConfirmHtml(request, message, 10, true);
|
||||||
|
|
||||||
updateHandler->onRequest([&](PsychicRequest *request) {
|
if(connected)
|
||||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
{
|
||||||
|
waitAndProcess(true, 3000);
|
||||||
String result;
|
restartEsp(RestartReason::ReconfigureWifi);
|
||||||
if (!Update.hasError())
|
//abort();
|
||||||
{
|
}
|
||||||
Log->print("Update code or data OK Update.errorString() ");
|
|
||||||
Log->println(Update.errorString());
|
|
||||||
result = "<b style='color:green'>Update OK.</b>";
|
|
||||||
esp_err_t res = request->reply(200,"text/html",result.c_str());
|
|
||||||
restartEsp(RestartReason::OTACompleted);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
});
|
||||||
else {
|
#endif
|
||||||
result = " Update.errorString() " + String(Update.errorString());
|
}
|
||||||
Log->print("ERROR : error ");
|
else
|
||||||
Log->println(result.c_str());
|
{
|
||||||
esp_err_t res = request->reply(500, "text/html", result.c_str());
|
#ifndef NUKI_HUB_UPDATER
|
||||||
restartEsp(RestartReason::OTAAborted);
|
_psychicServer->on("/import", HTTP_POST, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
String message = "";
|
||||||
|
bool restart = processImport(request, message);
|
||||||
|
return buildConfirmHtml(request, message, 3, true);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/export", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return sendSettings(request);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/impexpcfg", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return buildImportExportHtml(request);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/status", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return buildStatusHtml(request);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/acclvl", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return buildAccLvlHtml(request);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/custntw", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return buildCustomNetworkConfigHtml(request);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/advanced", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return buildAdvancedConfigHtml(request);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/cred", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return buildCredHtml(request);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/mqttconfig", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return buildMqttConfigHtml(request);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/nukicfg", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return buildNukiConfigHtml(request);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/gpiocfg", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return buildGpioConfigHtml(request);
|
||||||
|
});
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
_psychicServer->on("/wifi", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return buildConfigureWifiHtml(request);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/wifimanager", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
if(_allowRestartToPortal)
|
||||||
|
{
|
||||||
|
esp_err_t res = buildConfirmHtml(request, "Restarting. Connect to ESP access point (\"NukiHub\" with password \"NukiHubESP32\") to reconfigure Wi-Fi.", 0);
|
||||||
|
waitAndProcess(false, 1000);
|
||||||
|
_network->reconfigureDevice();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return(ESP_OK);
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
_psychicServer->on("/unpairlock", HTTP_POST, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return processUnpair(request, false);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/unpairopener", HTTP_POST, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return processUnpair(request, true);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/factoryreset", HTTP_POST, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return processFactoryReset(request);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/infopg", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return buildInfoHtml(request);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/debugon", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
_preferences->putBool(preference_publish_debug_info, true);
|
||||||
|
return buildConfirmHtml(request, "Debug On", 3, true);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/debugoff", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
_preferences->putBool(preference_publish_debug_info, false);
|
||||||
|
return buildConfirmHtml(request, "Debug Off", 3, true);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/savecfg", HTTP_POST, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
String message = "";
|
||||||
|
bool restart = processArgs(request, message);
|
||||||
|
return buildConfirmHtml(request, message, 3, true);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/savegpiocfg", HTTP_POST, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
processGpioArgs(request);
|
||||||
|
esp_err_t res = buildConfirmHtml(request, "Saving GPIO configuration. Restarting.", 3, true);
|
||||||
|
Log->println(F("Restarting"));
|
||||||
|
waitAndProcess(true, 1000);
|
||||||
|
restartEsp(RestartReason::GpioConfigurationUpdated);
|
||||||
return res;
|
return res;
|
||||||
}
|
});
|
||||||
});
|
#endif
|
||||||
|
_psychicServer->on("/ota", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return buildOtaHtml(request);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/otadebug", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return buildOtaHtml(request, true);
|
||||||
|
});
|
||||||
|
_psychicServer->on("/reboottoota", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
esp_err_t res = buildConfirmHtml(request, "Rebooting to other partition", 2, true);
|
||||||
|
waitAndProcess(true, 1000);
|
||||||
|
esp_ota_set_boot_partition(esp_ota_get_next_update_partition(NULL));
|
||||||
|
restartEsp(RestartReason::OTAReboot);
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
_psychicServer->on("/autoupdate", HTTP_GET, [&](PsychicRequest *request){
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
#ifndef NUKI_HUB_UPDATER
|
||||||
|
return processUpdate(request);
|
||||||
|
#else
|
||||||
|
return request->redirect("/");
|
||||||
|
#endif
|
||||||
|
});
|
||||||
|
|
||||||
_psychicServer->on("/uploadota", HTTP_POST, updateHandler);
|
PsychicUploadHandler *updateHandler = new PsychicUploadHandler();
|
||||||
//Update.onProgress(printProgress);
|
updateHandler->onUpload([&](PsychicRequest *request, const String& filename, uint64_t index, uint8_t *data, size_t len, bool final)
|
||||||
|
{
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
return handleOtaUpload(request, filename, index, data, len, final);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
updateHandler->onRequest([&](PsychicRequest *request) {
|
||||||
|
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0) if(!request->authenticate(_credUser, _credPassword)) return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||||
|
|
||||||
|
String result;
|
||||||
|
if (!Update.hasError())
|
||||||
|
{
|
||||||
|
Log->print("Update code or data OK Update.errorString() ");
|
||||||
|
Log->println(Update.errorString());
|
||||||
|
result = "<b style='color:green'>Update OK.</b>";
|
||||||
|
esp_err_t res = request->reply(200,"text/html",result.c_str());
|
||||||
|
restartEsp(RestartReason::OTACompleted);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = " Update.errorString() " + String(Update.errorString());
|
||||||
|
Log->print("ERROR : error ");
|
||||||
|
Log->println(result.c_str());
|
||||||
|
esp_err_t res = request->reply(500, "text/html", result.c_str());
|
||||||
|
restartEsp(RestartReason::OTAAborted);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_psychicServer->on("/uploadota", HTTP_POST, updateHandler);
|
||||||
|
//Update.onProgress(printProgress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
esp_err_t WebCfgServer::buildSSIDListHtml(PsychicRequest *request)
|
||||||
|
{
|
||||||
|
_network->scan(true, false);
|
||||||
|
createSsidList();
|
||||||
|
|
||||||
|
PsychicStreamResponse response(request, "text/plain");
|
||||||
|
response.beginSend();
|
||||||
|
|
||||||
|
for (int i = 0; i < _ssidList.size(); i++)
|
||||||
|
{
|
||||||
|
response.print("<tr class=\"trssid\" onclick=\"document.getElementById('inputssid').value = '" + _ssidList[i] + "';\"><td colspan=\"2\">" + _ssidList[i] + String(F(" (")) + String(_rssiList[i]) + String(F(" %)")) + "</td></tr>");
|
||||||
|
}
|
||||||
|
return response.endSend();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebCfgServer::createSsidList()
|
||||||
|
{
|
||||||
|
int _foundNetworks = WiFi.scanComplete();
|
||||||
|
std::vector<String> _tmpSsidList;
|
||||||
|
std::vector<int> _tmpRssiList;
|
||||||
|
|
||||||
|
for (int i = 0; i < _foundNetworks; i++)
|
||||||
|
{
|
||||||
|
int rssi = constrain((100.0 + WiFi.RSSI(i)) * 2, 0, 100);
|
||||||
|
auto it1 = std::find(_ssidList.begin(), _ssidList.end(), WiFi.SSID(i));
|
||||||
|
auto it2 = std::find(_tmpSsidList.begin(), _tmpSsidList.end(), WiFi.SSID(i));
|
||||||
|
|
||||||
|
if(it1 == _ssidList.end())
|
||||||
|
{
|
||||||
|
_ssidList.push_back(WiFi.SSID(i));
|
||||||
|
_rssiList.push_back(rssi);
|
||||||
|
_tmpSsidList.push_back(WiFi.SSID(i));
|
||||||
|
_tmpRssiList.push_back(rssi);
|
||||||
|
}
|
||||||
|
else if (it2 == _tmpSsidList.end())
|
||||||
|
{
|
||||||
|
_tmpSsidList.push_back(WiFi.SSID(i));
|
||||||
|
_tmpRssiList.push_back(rssi);
|
||||||
|
int index = it1 - _ssidList.begin();
|
||||||
|
_rssiList[index] = rssi;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int index = it1 - _ssidList.begin();
|
||||||
|
int index2 = it2 - _tmpSsidList.begin();
|
||||||
|
if (_tmpRssiList[index2] < rssi)
|
||||||
|
{
|
||||||
|
_tmpRssiList[index2] = rssi;
|
||||||
|
_rssiList[index] = rssi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t WebCfgServer::buildWifiConnectHtml(PsychicRequest *request)
|
||||||
|
{
|
||||||
|
String header = "<style>.trssid:hover { cursor: pointer; color: blue; }</style><script>let intervalId; window.onload = function() { intervalId = setInterval(updateSSID, 3000); }; function updateSSID() { var request = new XMLHttpRequest(); request.open('GET', '/ssidlist', true); request.onload = () => { if (document.getElementById(\"aplist\") !== null) { document.getElementById(\"aplist\").innerHTML = request.responseText; } }; request.send(); }</script>";
|
||||||
|
PsychicStreamResponse response(request, "text/plain");
|
||||||
|
response.beginSend();
|
||||||
|
buildHtmlHeader(&response, header);
|
||||||
|
response.print("<h3>Available WiFi networks</h3>");
|
||||||
|
response.print("<table id=\"aplist\">");
|
||||||
|
createSsidList();
|
||||||
|
for (int i = 0; i < _ssidList.size(); i++)
|
||||||
|
{
|
||||||
|
response.print("<tr class=\"trssid\" onclick=\"document.getElementById('inputssid').value = '" + _ssidList[i] + "';\"><td colspan=\"2\">" + _ssidList[i] + String(F(" (")) + String(_rssiList[i]) + String(F(" %)")) + "</td></tr>");
|
||||||
|
}
|
||||||
|
response.print("</table>");
|
||||||
|
response.print("<form class=\"adapt\" method=\"post\" action=\"savewifi\">");
|
||||||
|
response.print("<h3>WiFi credentials</h3>");
|
||||||
|
response.print("<table>");
|
||||||
|
printInputField(&response, "WIFISSID", "SSID", "", 32, "id=\"inputssid\"", false, true);
|
||||||
|
printInputField(&response, "WIFIPASS", "Secret key", "", 63, "id=\"inputpass\"", false, true);
|
||||||
|
response.print("</table>");
|
||||||
|
response.print("<br><input type=\"submit\" name=\"submit\" value=\"Save\">");
|
||||||
|
response.print("</form>");
|
||||||
|
response.print("<form action=\"/reboot\" method=\"get\"><br><input type=\"submit\" value=\"Reboot\" /></form>");
|
||||||
|
response.print("</body></html>");
|
||||||
|
return response.endSend();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WebCfgServer::processWiFi(PsychicRequest *request, String& message)
|
||||||
|
{
|
||||||
|
bool res = false;
|
||||||
|
int params = request->params();
|
||||||
|
String ssid;
|
||||||
|
String pass;
|
||||||
|
|
||||||
|
for(int index = 0; index < params; index++)
|
||||||
|
{
|
||||||
|
const PsychicWebParameter* p = request->getParam(index);
|
||||||
|
String key = p->name();
|
||||||
|
String value = p->value();
|
||||||
|
|
||||||
|
|
||||||
|
if(index < params -1)
|
||||||
|
{
|
||||||
|
const PsychicWebParameter* next = request->getParam(index+1);
|
||||||
|
if(key == next->name()) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(key == "WIFISSID")
|
||||||
|
{
|
||||||
|
ssid = value;
|
||||||
|
}
|
||||||
|
else if(key == "WIFIPASS")
|
||||||
|
{
|
||||||
|
pass = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ssid.trim();
|
||||||
|
pass.trim();
|
||||||
|
|
||||||
|
if (ssid.length() > 0 && pass.length() > 0)
|
||||||
|
{
|
||||||
|
WiFi.begin(ssid, pass);
|
||||||
|
|
||||||
|
int loop = 0;
|
||||||
|
while(WiFi.status() != WL_CONNECTED && loop < 150)
|
||||||
|
{
|
||||||
|
delay(100);
|
||||||
|
loop++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WiFi.status() != WL_CONNECTED)
|
||||||
|
{
|
||||||
|
message = "Failed to connect to the given SSID with the given secret key, credentials not saved<br/>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message = "Connection successful. Rebooting Nuki Hub.<br/>";
|
||||||
|
if(WiFi.isConnected())
|
||||||
|
{
|
||||||
|
esp_wifi_disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
wifi_config_t wifi_cfg;
|
||||||
|
if(esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) {
|
||||||
|
Log->println("Failed to get Wi-Fi configuration in RAM");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esp_wifi_set_storage(WIFI_STORAGE_FLASH) != ESP_OK) {
|
||||||
|
Log->println("Failed to set storage Wi-Fi");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(wifi_cfg.sta.ssid, 0, sizeof(wifi_cfg.sta.ssid));
|
||||||
|
memset(wifi_cfg.sta.password, 0, sizeof(wifi_cfg.sta.password));
|
||||||
|
|
||||||
|
if (esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) {
|
||||||
|
Log->println("Failed to set Wi-Fi configuration");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
_preferences->putString(preference_wifi_ssid, ssid);
|
||||||
|
_preferences->putString(preference_wifi_pass, pass);
|
||||||
|
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message = "No SSID or secret key entered, credentials not saved<br/>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
esp_err_t WebCfgServer::buildOtaHtml(PsychicRequest *request, bool debug)
|
esp_err_t WebCfgServer::buildOtaHtml(PsychicRequest *request, bool debug)
|
||||||
{
|
{
|
||||||
PsychicStreamResponse response(request, "text/plain");
|
PsychicStreamResponse response(request, "text/plain");
|
||||||
@@ -648,6 +858,62 @@ String WebCfgServer::generateConfirmCode()
|
|||||||
return String(code);
|
return String(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebCfgServer::printInputField(PsychicStreamResponse *response,
|
||||||
|
const char *token,
|
||||||
|
const char *description,
|
||||||
|
const char *value,
|
||||||
|
const size_t& maxLength,
|
||||||
|
const char *args,
|
||||||
|
const bool& isPassword,
|
||||||
|
const bool& showLengthRestriction)
|
||||||
|
{
|
||||||
|
char maxLengthStr[20];
|
||||||
|
|
||||||
|
itoa(maxLength, maxLengthStr, 10);
|
||||||
|
|
||||||
|
response->print("<tr><td>");
|
||||||
|
response->print(description);
|
||||||
|
|
||||||
|
if(showLengthRestriction)
|
||||||
|
{
|
||||||
|
response->print(" (Max. ");
|
||||||
|
response->print(maxLength);
|
||||||
|
response->print(" characters)");
|
||||||
|
}
|
||||||
|
|
||||||
|
response->print("</td><td>");
|
||||||
|
response->print("<input type=");
|
||||||
|
response->print(isPassword ? "\"password\"" : "\"text\"");
|
||||||
|
if(strcmp(args, "") != 0)
|
||||||
|
{
|
||||||
|
response->print(" ");
|
||||||
|
response->print(args);
|
||||||
|
}
|
||||||
|
if(strcmp(value, "") != 0)
|
||||||
|
{
|
||||||
|
response->print(" value=\"");
|
||||||
|
response->print(value);
|
||||||
|
}
|
||||||
|
response->print("\" name=\"");
|
||||||
|
response->print(token);
|
||||||
|
response->print("\" size=\"25\" maxlength=\"");
|
||||||
|
response->print(maxLengthStr);
|
||||||
|
response->print("\"/>");
|
||||||
|
response->print("</td></tr>");
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebCfgServer::printInputField(PsychicStreamResponse *response,
|
||||||
|
const char *token,
|
||||||
|
const char *description,
|
||||||
|
const int value,
|
||||||
|
size_t maxLength,
|
||||||
|
const char *args)
|
||||||
|
{
|
||||||
|
char valueStr[20];
|
||||||
|
itoa(value, valueStr, 10);
|
||||||
|
printInputField(response, token, description, valueStr, maxLength, args);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NUKI_HUB_UPDATER
|
#ifndef NUKI_HUB_UPDATER
|
||||||
esp_err_t WebCfgServer::sendSettings(PsychicRequest *request)
|
esp_err_t WebCfgServer::sendSettings(PsychicRequest *request)
|
||||||
{
|
{
|
||||||
@@ -1162,16 +1428,6 @@ bool WebCfgServer::processArgs(PsychicRequest *request, String& message)
|
|||||||
//configChanged = true;
|
//configChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(key == "BESTRSSI")
|
|
||||||
{
|
|
||||||
if(_preferences->getBool(preference_find_best_rssi, false) != (value == "1"))
|
|
||||||
{
|
|
||||||
_preferences->putBool(preference_find_best_rssi, (value == "1"));
|
|
||||||
Log->print(F("Setting changed: "));
|
|
||||||
Log->println(key);
|
|
||||||
//configChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(key == "HOSTNAME")
|
else if(key == "HOSTNAME")
|
||||||
{
|
{
|
||||||
if(_preferences->getString(preference_hostname, "") != value)
|
if(_preferences->getString(preference_hostname, "") != value)
|
||||||
@@ -1202,16 +1458,6 @@ bool WebCfgServer::processArgs(PsychicRequest *request, String& message)
|
|||||||
//configChanged = true;
|
//configChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(key == "RECNWTMQTTDIS")
|
|
||||||
{
|
|
||||||
if(_preferences->getBool(preference_recon_netw_on_mqtt_discon, false) != (value == "1"))
|
|
||||||
{
|
|
||||||
_preferences->putBool(preference_recon_netw_on_mqtt_discon, (value == "1"));
|
|
||||||
Log->print(F("Setting changed: "));
|
|
||||||
Log->println(key);
|
|
||||||
//configChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(key == "MQTTLOG")
|
else if(key == "MQTTLOG")
|
||||||
{
|
{
|
||||||
if(_preferences->getBool(preference_mqtt_log_enabled, false) != (value == "1"))
|
if(_preferences->getBool(preference_mqtt_log_enabled, false) != (value == "1"))
|
||||||
@@ -2794,13 +3040,10 @@ esp_err_t WebCfgServer::buildMqttConfigHtml(PsychicRequest *request)
|
|||||||
printTextarea(&response, "MQTTKEY", "MQTT SSL Client Key (*, optional)", _preferences->getString(preference_mqtt_key).c_str(), TLS_KEY_MAX_SIZE, true, true);
|
printTextarea(&response, "MQTTKEY", "MQTT SSL Client Key (*, optional)", _preferences->getString(preference_mqtt_key).c_str(), TLS_KEY_MAX_SIZE, true, true);
|
||||||
printDropDown(&response, "NWHW", "Network hardware", String(_preferences->getInt(preference_network_hardware)), getNetworkDetectionOptions(), "");
|
printDropDown(&response, "NWHW", "Network hardware", String(_preferences->getInt(preference_network_hardware)), getNetworkDetectionOptions(), "");
|
||||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
printCheckBox(&response, "NWHWWIFIFB", "Disable fallback to Wi-Fi / Wi-Fi config portal", _preferences->getBool(preference_network_wifi_fallback_disabled), "");
|
|
||||||
printCheckBox(&response, "BESTRSSI", "Connect to AP with the best signal in an environment with multiple APs with the same SSID", _preferences->getBool(preference_find_best_rssi), "");
|
|
||||||
printInputField(&response, "RSSI", "RSSI Publish interval (seconds; -1 to disable)", _preferences->getInt(preference_rssi_publish_interval), 6, "");
|
printInputField(&response, "RSSI", "RSSI Publish interval (seconds; -1 to disable)", _preferences->getInt(preference_rssi_publish_interval), 6, "");
|
||||||
#endif
|
#endif
|
||||||
printInputField(&response, "NETTIMEOUT", "MQTT Timeout until restart (seconds; -1 to disable)", _preferences->getInt(preference_network_timeout), 5, "");
|
printInputField(&response, "NETTIMEOUT", "MQTT Timeout until restart (seconds; -1 to disable)", _preferences->getInt(preference_network_timeout), 5, "");
|
||||||
printCheckBox(&response, "RSTDISC", "Restart on disconnect", _preferences->getBool(preference_restart_on_disconnect), "");
|
printCheckBox(&response, "RSTDISC", "Restart on disconnect", _preferences->getBool(preference_restart_on_disconnect), "");
|
||||||
printCheckBox(&response, "RECNWTMQTTDIS", "Reconnect network on MQTT connection failure", _preferences->getBool(preference_recon_netw_on_mqtt_discon), "");
|
|
||||||
printCheckBox(&response, "MQTTLOG", "Enable MQTT logging", _preferences->getBool(preference_mqtt_log_enabled), "");
|
printCheckBox(&response, "MQTTLOG", "Enable MQTT logging", _preferences->getBool(preference_mqtt_log_enabled), "");
|
||||||
printCheckBox(&response, "CHECKUPDATE", "Check for Firmware Updates every 24h", _preferences->getBool(preference_check_updates), "");
|
printCheckBox(&response, "CHECKUPDATE", "Check for Firmware Updates every 24h", _preferences->getBool(preference_check_updates), "");
|
||||||
printCheckBox(&response, "UPDATEMQTT", "Allow updating using MQTT", _preferences->getBool(preference_update_from_mqtt), "");
|
printCheckBox(&response, "UPDATEMQTT", "Allow updating using MQTT", _preferences->getBool(preference_update_from_mqtt), "");
|
||||||
@@ -2945,13 +3188,13 @@ String WebCfgServer::pinStateToString(uint8_t value) {
|
|||||||
switch(value)
|
switch(value)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return (String)"PIN not set";
|
return String("PIN not set");
|
||||||
case 1:
|
case 1:
|
||||||
return (String)"PIN valid";
|
return String("PIN valid");
|
||||||
case 2:
|
case 2:
|
||||||
return (String)"PIN set but invalid";;
|
return String("PIN set but invalid");
|
||||||
default:
|
default:
|
||||||
return (String)"Unknown";
|
return String("Unknown");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3230,7 +3473,7 @@ esp_err_t WebCfgServer::buildConfigureWifiHtml(PsychicRequest *request)
|
|||||||
response.beginSend();
|
response.beginSend();
|
||||||
buildHtmlHeader(&response);
|
buildHtmlHeader(&response);
|
||||||
response.print("<h3>Wi-Fi</h3>");
|
response.print("<h3>Wi-Fi</h3>");
|
||||||
response.print("Click confirm to restart ESP into Wi-Fi configuration mode. After restart, connect to ESP access point to reconfigure Wi-Fi.<br><br>");
|
response.print("Click confirm to remove saved WiFi settings and restart ESP into Wi-Fi configuration mode. After restart, connect to ESP access point to reconfigure Wi-Fi.<br><br>");
|
||||||
buildNavigationButton(&response, "Confirm", "/wifimanager");
|
buildNavigationButton(&response, "Confirm", "/wifimanager");
|
||||||
response.print("</body></html>");
|
response.print("</body></html>");
|
||||||
return response.endSend();
|
return response.endSend();
|
||||||
@@ -3366,12 +3609,8 @@ esp_err_t WebCfgServer::buildInfoHtml(PsychicRequest *request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
response.print("\nFallback to Wi-Fi / Wi-Fi config portal disabled: ");
|
|
||||||
response.print(_preferences->getBool(preference_network_wifi_fallback_disabled, false) ? "Yes" : "No");
|
|
||||||
if(_network->networkDeviceName() == "Built-in Wi-Fi")
|
if(_network->networkDeviceName() == "Built-in Wi-Fi")
|
||||||
{
|
{
|
||||||
response.print("\nConnect to AP with the best signal enabled: ");
|
|
||||||
response.print(_preferences->getBool(preference_find_best_rssi, false) ? "Yes" : "No");
|
|
||||||
response.print("\nRSSI Publish interval (s): ");
|
response.print("\nRSSI Publish interval (s): ");
|
||||||
|
|
||||||
if(_preferences->getInt(preference_rssi_publish_interval, 60) < 0) response.print("Disabled");
|
if(_preferences->getInt(preference_rssi_publish_interval, 60) < 0) response.print("Disabled");
|
||||||
@@ -3380,8 +3619,6 @@ esp_err_t WebCfgServer::buildInfoHtml(PsychicRequest *request)
|
|||||||
#endif
|
#endif
|
||||||
response.print("\nRestart ESP32 on network disconnect enabled: ");
|
response.print("\nRestart ESP32 on network disconnect enabled: ");
|
||||||
response.print(_preferences->getBool(preference_restart_on_disconnect, false) ? "Yes" : "No");
|
response.print(_preferences->getBool(preference_restart_on_disconnect, false) ? "Yes" : "No");
|
||||||
response.print("\nReconnect network on MQTT connection failure enabled: ");
|
|
||||||
response.print(_preferences->getBool(preference_recon_netw_on_mqtt_discon, false) ? "Yes" : "No");
|
|
||||||
response.print("\nMQTT Timeout until restart (s): ");
|
response.print("\nMQTT Timeout until restart (s): ");
|
||||||
if(_preferences->getInt(preference_network_timeout, 60) < 0) response.print("Disabled");
|
if(_preferences->getInt(preference_network_timeout, 60) < 0) response.print("Disabled");
|
||||||
else response.print(_preferences->getInt(preference_network_timeout, 60));
|
else response.print(_preferences->getInt(preference_network_timeout, 60));
|
||||||
@@ -3967,11 +4204,6 @@ esp_err_t WebCfgServer::processFactoryReset(PsychicRequest *request)
|
|||||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
if(resetWifi)
|
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();
|
_network->reconfigureDevice();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -3981,62 +4213,6 @@ esp_err_t WebCfgServer::processFactoryReset(PsychicRequest *request)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebCfgServer::printInputField(PsychicStreamResponse *response,
|
|
||||||
const char *token,
|
|
||||||
const char *description,
|
|
||||||
const char *value,
|
|
||||||
const size_t& maxLength,
|
|
||||||
const char *args,
|
|
||||||
const bool& isPassword,
|
|
||||||
const bool& showLengthRestriction)
|
|
||||||
{
|
|
||||||
char maxLengthStr[20];
|
|
||||||
|
|
||||||
itoa(maxLength, maxLengthStr, 10);
|
|
||||||
|
|
||||||
response->print("<tr><td>");
|
|
||||||
response->print(description);
|
|
||||||
|
|
||||||
if(showLengthRestriction)
|
|
||||||
{
|
|
||||||
response->print(" (Max. ");
|
|
||||||
response->print(maxLength);
|
|
||||||
response->print(" characters)");
|
|
||||||
}
|
|
||||||
|
|
||||||
response->print("</td><td>");
|
|
||||||
response->print("<input type=");
|
|
||||||
response->print(isPassword ? "\"password\"" : "\"text\"");
|
|
||||||
if(strcmp(args, "") != 0)
|
|
||||||
{
|
|
||||||
response->print(" ");
|
|
||||||
response->print(args);
|
|
||||||
}
|
|
||||||
if(strcmp(value, "") != 0)
|
|
||||||
{
|
|
||||||
response->print(" value=\"");
|
|
||||||
response->print(value);
|
|
||||||
}
|
|
||||||
response->print("\" name=\"");
|
|
||||||
response->print(token);
|
|
||||||
response->print("\" size=\"25\" maxlength=\"");
|
|
||||||
response->print(maxLengthStr);
|
|
||||||
response->print("\"/>");
|
|
||||||
response->print("</td></tr>");
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebCfgServer::printInputField(PsychicStreamResponse *response,
|
|
||||||
const char *token,
|
|
||||||
const char *description,
|
|
||||||
const int value,
|
|
||||||
size_t maxLength,
|
|
||||||
const char *args)
|
|
||||||
{
|
|
||||||
char valueStr[20];
|
|
||||||
itoa(value, valueStr, 10);
|
|
||||||
printInputField(response, token, description, valueStr, maxLength, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebCfgServer::printCheckBox(PsychicStreamResponse *response, const char *token, const char *description, const bool value, const char *htmlClass)
|
void WebCfgServer::printCheckBox(PsychicStreamResponse *response, const char *token, const char *description, const bool value, const char *htmlClass)
|
||||||
{
|
{
|
||||||
response->print("<tr><td>");
|
response->print("<tr><td>");
|
||||||
@@ -4183,7 +4359,7 @@ const std::vector<std::pair<String, String>> WebCfgServer::getNetworkDetectionOp
|
|||||||
{
|
{
|
||||||
std::vector<std::pair<String, String>> options;
|
std::vector<std::pair<String, String>> options;
|
||||||
|
|
||||||
options.push_back(std::make_pair("1", "Wi-Fi only"));
|
options.push_back(std::make_pair("1", "Wi-Fi"));
|
||||||
options.push_back(std::make_pair("2", "Generic W5500"));
|
options.push_back(std::make_pair("2", "Generic W5500"));
|
||||||
options.push_back(std::make_pair("3", "M5Stack Atom POE (W5500)"));
|
options.push_back(std::make_pair("3", "M5Stack Atom POE (W5500)"));
|
||||||
options.push_back(std::make_pair("10", "M5Stack Atom POE S3 (W5500)"));
|
options.push_back(std::make_pair("10", "M5Stack Atom POE S3 (W5500)"));
|
||||||
|
|||||||
@@ -67,8 +67,6 @@ private:
|
|||||||
esp_err_t processUnpair(PsychicRequest *request, bool opener);
|
esp_err_t processUnpair(PsychicRequest *request, bool opener);
|
||||||
esp_err_t processUpdate(PsychicRequest *request);
|
esp_err_t processUpdate(PsychicRequest *request);
|
||||||
esp_err_t processFactoryReset(PsychicRequest *request);
|
esp_err_t processFactoryReset(PsychicRequest *request);
|
||||||
void printInputField(PsychicStreamResponse *response, const char* token, const char* description, const char* value, const size_t& maxLength, const char* args, const bool& isPassword = false, const bool& showLengthRestriction = false);
|
|
||||||
void printInputField(PsychicStreamResponse *response, const char* token, const char* description, const int value, size_t maxLength, const char* args);
|
|
||||||
void printCheckBox(PsychicStreamResponse *response, const char* token, const char* description, const bool value, const char* htmlClass);
|
void printCheckBox(PsychicStreamResponse *response, const char* token, const char* description, const bool value, const char* htmlClass);
|
||||||
void printTextarea(PsychicStreamResponse *response, const char *token, const char *description, const char *value, const size_t& maxLength, const bool& enabled = true, const bool& showLengthRestriction = false);
|
void printTextarea(PsychicStreamResponse *response, const char *token, const char *description, const char *value, const size_t& maxLength, const bool& enabled = true, const bool& showLengthRestriction = false);
|
||||||
void printDropDown(PsychicStreamResponse *response, const char *token, const char *description, const String preselectedValue, std::vector<std::pair<String, String>> options, const String className);
|
void printDropDown(PsychicStreamResponse *response, const char *token, const char *description, const String preselectedValue, std::vector<std::pair<String, String>> options, const String className);
|
||||||
@@ -95,17 +93,28 @@ private:
|
|||||||
bool _rebootRequired = false;
|
bool _rebootRequired = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
std::vector<String> _ssidList;
|
||||||
|
std::vector<int> _rssiList;
|
||||||
String generateConfirmCode();
|
String generateConfirmCode();
|
||||||
String _confirmCode = "----";
|
String _confirmCode = "----";
|
||||||
|
esp_err_t buildSSIDListHtml(PsychicRequest *request);
|
||||||
esp_err_t buildConfirmHtml(PsychicRequest *request, const String &message, uint32_t redirectDelay = 5, bool redirect = false);
|
esp_err_t buildConfirmHtml(PsychicRequest *request, const String &message, uint32_t redirectDelay = 5, bool redirect = false);
|
||||||
esp_err_t buildOtaHtml(PsychicRequest *request, bool debug = false);
|
esp_err_t buildOtaHtml(PsychicRequest *request, bool debug = false);
|
||||||
esp_err_t buildOtaCompletedHtml(PsychicRequest *request);
|
esp_err_t buildOtaCompletedHtml(PsychicRequest *request);
|
||||||
esp_err_t sendCss(PsychicRequest *request);
|
esp_err_t sendCss(PsychicRequest *request);
|
||||||
esp_err_t sendFavicon(PsychicRequest *request);
|
esp_err_t sendFavicon(PsychicRequest *request);
|
||||||
|
void createSsidList();
|
||||||
void buildHtmlHeader(PsychicStreamResponse *response, String additionalHeader = "");
|
void buildHtmlHeader(PsychicStreamResponse *response, String additionalHeader = "");
|
||||||
void waitAndProcess(const bool blocking, const uint32_t duration);
|
void waitAndProcess(const bool blocking, const uint32_t duration);
|
||||||
esp_err_t handleOtaUpload(PsychicRequest *request, const String& filename, uint64_t index, uint8_t *data, size_t len, bool final);
|
esp_err_t handleOtaUpload(PsychicRequest *request, const String& filename, uint64_t index, uint8_t *data, size_t len, bool final);
|
||||||
void printProgress(size_t prg, size_t sz);
|
void printProgress(size_t prg, size_t sz);
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
esp_err_t buildWifiConnectHtml(PsychicRequest *request);
|
||||||
|
bool processWiFi(PsychicRequest *request, String& message);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
void printInputField(PsychicStreamResponse *response, const char* token, const char* description, const char* value, const size_t& maxLength, const char* args, const bool& isPassword = false, const bool& showLengthRestriction = false);
|
||||||
|
void printInputField(PsychicStreamResponse *response, const char* token, const char* description, const int value, size_t maxLength, const char* args);
|
||||||
|
|
||||||
PsychicHttpServer* _psychicServer = nullptr;
|
PsychicHttpServer* _psychicServer = nullptr;
|
||||||
NukiNetwork* _network = nullptr;
|
NukiNetwork* _network = nullptr;
|
||||||
|
|||||||
35
src/main.cpp
35
src/main.cpp
@@ -5,7 +5,7 @@
|
|||||||
#include "esp_ota_ops.h"
|
#include "esp_ota_ops.h"
|
||||||
#include "esp_http_client.h"
|
#include "esp_http_client.h"
|
||||||
#include "esp_https_ota.h"
|
#include "esp_https_ota.h"
|
||||||
#include <esp_task_wdt.h>
|
#include "esp_task_wdt.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
|
||||||
#ifndef NUKI_HUB_UPDATER
|
#ifndef NUKI_HUB_UPDATER
|
||||||
@@ -78,7 +78,6 @@ TaskHandle_t networkTaskHandle = nullptr;
|
|||||||
ssize_t write_fn(void* cookie, const char* buf, ssize_t size)
|
ssize_t write_fn(void* cookie, const char* buf, ssize_t size)
|
||||||
{
|
{
|
||||||
Log->write((uint8_t *)buf, (size_t)size);
|
Log->write((uint8_t *)buf, (size_t)size);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,8 +376,11 @@ void setupTasks(bool ota)
|
|||||||
xTaskCreatePinnedToCore(networkTask, "ntw", preferences->getInt(preference_task_size_network, NETWORK_TASK_SIZE), NULL, 3, &networkTaskHandle, 1);
|
xTaskCreatePinnedToCore(networkTask, "ntw", preferences->getInt(preference_task_size_network, NETWORK_TASK_SIZE), NULL, 3, &networkTaskHandle, 1);
|
||||||
esp_task_wdt_add(networkTaskHandle);
|
esp_task_wdt_add(networkTaskHandle);
|
||||||
#ifndef NUKI_HUB_UPDATER
|
#ifndef NUKI_HUB_UPDATER
|
||||||
xTaskCreatePinnedToCore(nukiTask, "nuki", preferences->getInt(preference_task_size_nuki, NUKI_TASK_SIZE), NULL, 2, &nukiTaskHandle, 0);
|
if(!network->isApOpen())
|
||||||
esp_task_wdt_add(nukiTaskHandle);
|
{
|
||||||
|
xTaskCreatePinnedToCore(nukiTask, "nuki", preferences->getInt(preference_task_size_nuki, NUKI_TASK_SIZE), NULL, 2, &nukiTaskHandle, 0);
|
||||||
|
esp_task_wdt_add(nukiTaskHandle);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -453,7 +455,6 @@ void setup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
char16_t buffer_size = preferences->getInt(preference_buffer_size, 4096);
|
char16_t buffer_size = preferences->getInt(preference_buffer_size, 4096);
|
||||||
|
|
||||||
CharBuffer::initialize(buffer_size);
|
CharBuffer::initialize(buffer_size);
|
||||||
|
|
||||||
gpio = new Gpio(preferences);
|
gpio = new Gpio(preferences);
|
||||||
@@ -461,22 +462,30 @@ void setup()
|
|||||||
gpio->getConfigurationText(gpioDesc, gpio->pinConfiguration(), "\n\r");
|
gpio->getConfigurationText(gpioDesc, gpio->pinConfiguration(), "\n\r");
|
||||||
Log->print(gpioDesc.c_str());
|
Log->print(gpioDesc.c_str());
|
||||||
|
|
||||||
|
const String mqttLockPath = preferences->getString(preference_mqtt_lock_path);
|
||||||
|
|
||||||
|
network = new NukiNetwork(preferences, gpio, mqttLockPath, CharBuffer::get(), buffer_size);
|
||||||
|
network->initialize();
|
||||||
|
|
||||||
|
lockEnabled = preferences->getBool(preference_lock_enabled);
|
||||||
|
openerEnabled = preferences->getBool(preference_opener_enabled);
|
||||||
|
|
||||||
|
if(network->isApOpen())
|
||||||
|
{
|
||||||
|
forceEnableWebServer = true;
|
||||||
|
doOta = false;
|
||||||
|
lockEnabled = false;
|
||||||
|
openerEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
bleScanner = new BleScanner::Scanner();
|
bleScanner = new BleScanner::Scanner();
|
||||||
// Scan interval and window according to Nuki recommendations:
|
// Scan interval and window according to Nuki recommendations:
|
||||||
// https://developer.nuki.io/t/bluetooth-specification-questions/1109/27
|
// https://developer.nuki.io/t/bluetooth-specification-questions/1109/27
|
||||||
bleScanner->initialize("NukiHub", true, 40, 40);
|
bleScanner->initialize("NukiHub", true, 40, 40);
|
||||||
bleScanner->setScanDuration(0);
|
bleScanner->setScanDuration(0);
|
||||||
|
|
||||||
lockEnabled = preferences->getBool(preference_lock_enabled);
|
|
||||||
openerEnabled = preferences->getBool(preference_opener_enabled);
|
|
||||||
|
|
||||||
const String mqttLockPath = preferences->getString(preference_mqtt_lock_path);
|
|
||||||
|
|
||||||
nukiOfficial = new NukiOfficial(preferences);
|
nukiOfficial = new NukiOfficial(preferences);
|
||||||
|
|
||||||
network = new NukiNetwork(preferences, gpio, mqttLockPath, CharBuffer::get(), buffer_size);
|
|
||||||
network->initialize();
|
|
||||||
|
|
||||||
networkLock = new NukiNetworkLock(network, nukiOfficial, preferences, CharBuffer::get(), buffer_size);
|
networkLock = new NukiNetworkLock(network, nukiOfficial, preferences, CharBuffer::get(), buffer_size);
|
||||||
networkLock->initialize();
|
networkLock->initialize();
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
#include "../Logger.h"
|
#include "../Logger.h"
|
||||||
#include "../RestartReason.h"
|
#include "../RestartReason.h"
|
||||||
|
|
||||||
|
RTC_NOINIT_ATTR bool criticalEthFailure;
|
||||||
|
extern char WiFi_fallbackDetect[14];
|
||||||
|
|
||||||
EthernetDevice::EthernetDevice(const String& hostname, Preferences* preferences, const IPConfiguration* ipConfiguration, const std::string& deviceName, uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t ethtype, eth_clock_mode_t clock_mode)
|
EthernetDevice::EthernetDevice(const String& hostname, Preferences* preferences, const IPConfiguration* ipConfiguration, const std::string& deviceName, uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t ethtype, eth_clock_mode_t clock_mode)
|
||||||
: NetworkDevice(hostname, ipConfiguration),
|
: NetworkDevice(hostname, ipConfiguration),
|
||||||
_deviceName(deviceName),
|
_deviceName(deviceName),
|
||||||
@@ -54,20 +57,34 @@ const String EthernetDevice::deviceName() const
|
|||||||
void EthernetDevice::initialize()
|
void EthernetDevice::initialize()
|
||||||
{
|
{
|
||||||
delay(250);
|
delay(250);
|
||||||
|
if(criticalEthFailure)
|
||||||
|
{
|
||||||
|
criticalEthFailure = false;
|
||||||
|
Log->println(F("Failed to initialize ethernet hardware"));
|
||||||
|
Log->println("Network device has a critical failure, enable fallback to Wi-Fi and reboot.");
|
||||||
|
strcpy(WiFi_fallbackDetect, "wifi_fallback");
|
||||||
|
delay(200);
|
||||||
|
restartEsp(RestartReason::NetworkDeviceCriticalFailure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Log->println(F("Init Ethernet"));
|
Log->println(F("Init Ethernet"));
|
||||||
|
|
||||||
if(_useSpi)
|
if(_useSpi)
|
||||||
{
|
{
|
||||||
Log->println(F("Use SPI"));
|
Log->println(F("Use SPI"));
|
||||||
|
criticalEthFailure = true;
|
||||||
SPI.begin(_spi_sck, _spi_miso, _spi_mosi);
|
SPI.begin(_spi_sck, _spi_miso, _spi_mosi);
|
||||||
_hardwareInitialized = ETH.begin(_type, _phy_addr, _cs, _irq, _rst, SPI);
|
_hardwareInitialized = ETH.begin(_type, _phy_addr, _cs, _irq, _rst, SPI);
|
||||||
|
criticalEthFailure = false;
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log->println(F("Use RMII"));
|
Log->println(F("Use RMII"));
|
||||||
|
criticalEthFailure = true;
|
||||||
_hardwareInitialized = ETH.begin(_type, _phy_addr, _mdc, _mdio, _power, _clock_mode);
|
_hardwareInitialized = ETH.begin(_type, _phy_addr, _mdc, _mdio, _power, _clock_mode);
|
||||||
|
criticalEthFailure = false;
|
||||||
if(!_ipConfiguration->dhcpEnabled())
|
if(!_ipConfiguration->dhcpEnabled())
|
||||||
{
|
{
|
||||||
_checkIpTs = (esp_timer_get_time() / 1000) + 2000;
|
_checkIpTs = (esp_timer_get_time() / 1000) + 2000;
|
||||||
@@ -78,6 +95,7 @@ void EthernetDevice::initialize()
|
|||||||
if(_hardwareInitialized)
|
if(_hardwareInitialized)
|
||||||
{
|
{
|
||||||
Log->println(F("Ethernet hardware Initialized"));
|
Log->println(F("Ethernet hardware Initialized"));
|
||||||
|
memset(WiFi_fallbackDetect, 0, sizeof(WiFi_fallbackDetect));
|
||||||
|
|
||||||
if(_useSpi && !_ipConfiguration->dhcpEnabled())
|
if(_useSpi && !_ipConfiguration->dhcpEnabled())
|
||||||
{
|
{
|
||||||
@@ -92,6 +110,11 @@ void EthernetDevice::initialize()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log->println(F("Failed to initialize ethernet hardware"));
|
Log->println(F("Failed to initialize ethernet hardware"));
|
||||||
|
Log->println("Network device has a critical failure, enable fallback to Wi-Fi and reboot.");
|
||||||
|
strcpy(WiFi_fallbackDetect, "wifi_fallback");
|
||||||
|
delay(200);
|
||||||
|
restartEsp(RestartReason::NetworkDeviceCriticalFailure);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,25 +196,23 @@ void EthernetDevice::reconfigure()
|
|||||||
restartEsp(RestartReason::ReconfigureETH);
|
restartEsp(RestartReason::ReconfigureETH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EthernetDevice::scan(bool passive, bool async)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool EthernetDevice::isConnected()
|
bool EthernetDevice::isConnected()
|
||||||
{
|
{
|
||||||
return _connected;
|
return _connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReconnectStatus EthernetDevice::reconnect(bool force)
|
bool EthernetDevice::isApOpen()
|
||||||
{
|
{
|
||||||
if(!_hardwareInitialized)
|
return false;
|
||||||
{
|
|
||||||
return ReconnectStatus::CriticalFailure;
|
|
||||||
}
|
|
||||||
delay(200);
|
|
||||||
return isConnected() ? ReconnectStatus::Success : ReconnectStatus::Failure;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EthernetDevice::onDisconnected()
|
void EthernetDevice::onDisconnected()
|
||||||
{
|
{
|
||||||
if(_preferences->getBool(preference_restart_on_disconnect, false) && ((esp_timer_get_time() / 1000) > 60000)) restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
if(_preferences->getBool(preference_restart_on_disconnect, false) && ((esp_timer_get_time() / 1000) > 60000)) restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
||||||
reconnect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t EthernetDevice::signalStrength()
|
int8_t EthernetDevice::signalStrength()
|
||||||
|
|||||||
@@ -45,10 +45,10 @@ public:
|
|||||||
virtual void initialize();
|
virtual void initialize();
|
||||||
virtual void reconfigure();
|
virtual void reconfigure();
|
||||||
virtual void update();
|
virtual void update();
|
||||||
|
virtual void scan(bool passive = false, bool async = true);
|
||||||
virtual ReconnectStatus reconnect(bool force = false);
|
|
||||||
|
|
||||||
virtual bool isConnected();
|
virtual bool isConnected();
|
||||||
|
virtual bool isApOpen();
|
||||||
|
|
||||||
int8_t signalStrength() override;
|
int8_t signalStrength() override;
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "IPConfiguration.h"
|
#include "IPConfiguration.h"
|
||||||
|
|
||||||
enum class ReconnectStatus
|
|
||||||
{
|
|
||||||
Failure = 0,
|
|
||||||
Success = 1,
|
|
||||||
CriticalFailure = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
class NetworkDevice
|
class NetworkDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -19,11 +12,12 @@ public:
|
|||||||
virtual const String deviceName() const = 0;
|
virtual const String deviceName() const = 0;
|
||||||
|
|
||||||
virtual void initialize() = 0;
|
virtual void initialize() = 0;
|
||||||
virtual ReconnectStatus reconnect(bool force = false) = 0;
|
|
||||||
virtual void reconfigure() = 0;
|
virtual void reconfigure() = 0;
|
||||||
virtual void update();
|
virtual void update();
|
||||||
|
virtual void scan(bool passive = false, bool async = true) = 0;
|
||||||
|
|
||||||
virtual bool isConnected() = 0;
|
virtual bool isConnected() = 0;
|
||||||
|
virtual bool isApOpen() = 0;
|
||||||
virtual int8_t signalStrength() = 0;
|
virtual int8_t signalStrength() = 0;
|
||||||
|
|
||||||
virtual String localIP() = 0;
|
virtual String localIP() = 0;
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
|
#include "esp_wifi.h"
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include "WifiDevice.h"
|
#include "WifiDevice.h"
|
||||||
#include "../PreferencesKeys.h"
|
#include "../PreferencesKeys.h"
|
||||||
#include "../Logger.h"
|
#include "../Logger.h"
|
||||||
#include "../RestartReason.h"
|
#include "../RestartReason.h"
|
||||||
|
|
||||||
RTC_NOINIT_ATTR char WiFiDevice_reconfdetect[17];
|
|
||||||
|
|
||||||
WifiDevice::WifiDevice(const String& hostname, Preferences* preferences, const IPConfiguration* ipConfiguration)
|
WifiDevice::WifiDevice(const String& hostname, Preferences* preferences, const IPConfiguration* ipConfiguration)
|
||||||
: NetworkDevice(hostname, ipConfiguration),
|
: NetworkDevice(hostname, ipConfiguration),
|
||||||
_preferences(preferences),
|
_preferences(preferences)
|
||||||
_wm(preferences->getString(preference_cred_user, "").c_str(), preferences->getString(preference_cred_password, "").c_str())
|
|
||||||
{
|
{
|
||||||
_startAp = strcmp(WiFiDevice_reconfdetect, "reconfigure_wifi") == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const String WifiDevice::deviceName() const
|
const String WifiDevice::deviceName() const
|
||||||
@@ -21,123 +18,399 @@ const String WifiDevice::deviceName() const
|
|||||||
|
|
||||||
void WifiDevice::initialize()
|
void WifiDevice::initialize()
|
||||||
{
|
{
|
||||||
std::vector<const char *> wm_menu;
|
String ssid = _preferences->getString(preference_wifi_ssid, "");
|
||||||
wm_menu.push_back("wifi");
|
String pass = _preferences->getString(preference_wifi_pass, "");
|
||||||
wm_menu.push_back("exit");
|
WiFi.setHostname(_hostname.c_str());
|
||||||
_wm.setEnableConfigPortal(_startAp || !_preferences->getBool(preference_network_wifi_fallback_disabled, false));
|
|
||||||
// reduced timeout if ESP is set to restart on disconnect
|
|
||||||
_wm.setFindBestRSSI(_preferences->getBool(preference_find_best_rssi));
|
|
||||||
_wm.setConnectTimeout(20);
|
|
||||||
_wm.setConfigPortalTimeout(_preferences->getBool(preference_restart_on_disconnect, false) ? 60 * 3 : 60 * 30);
|
|
||||||
_wm.setShowInfoUpdate(false);
|
|
||||||
_wm.setMenu(wm_menu);
|
|
||||||
_wm.setHostname(_hostname);
|
|
||||||
|
|
||||||
if(!_ipConfiguration->dhcpEnabled())
|
if(!_ipConfiguration->dhcpEnabled())
|
||||||
{
|
{
|
||||||
_wm.setSTAStaticIPConfig(_ipConfiguration->ipAddress(), _ipConfiguration->defaultGateway(), _ipConfiguration->subnet(), _ipConfiguration->dnsServer());
|
WiFi.config(_ipConfiguration->ipAddress(), _ipConfiguration->dnsServer(), _ipConfiguration->defaultGateway(), _ipConfiguration->subnet());
|
||||||
}
|
|
||||||
|
|
||||||
_wm.setAPCallback(clearRtcInitVar);
|
|
||||||
|
|
||||||
bool res = false;
|
|
||||||
bool connectedFromPortal = false;
|
|
||||||
|
|
||||||
if(_startAp)
|
|
||||||
{
|
|
||||||
Log->println(F("Opening Wi-Fi configuration portal."));
|
|
||||||
res = _wm.startConfigPortal();
|
|
||||||
connectedFromPortal = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
res = _wm.autoConnect(); // password protected ap
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!res)
|
|
||||||
{
|
|
||||||
esp_wifi_disconnect();
|
|
||||||
esp_wifi_stop();
|
|
||||||
esp_wifi_deinit();
|
|
||||||
|
|
||||||
Log->println(F("Failed to connect. Wait for ESP restart."));
|
|
||||||
delay(1000);
|
|
||||||
restartEsp(RestartReason::WifiInitFailed);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Log->print(F("Wi-Fi connected: "));
|
|
||||||
Log->println(WiFi.localIP().toString());
|
|
||||||
|
|
||||||
if(connectedFromPortal)
|
|
||||||
{
|
|
||||||
Log->println(F("Connected using WifiManager portal. Wait for ESP restart."));
|
|
||||||
delay(1000);
|
|
||||||
restartEsp(RestartReason::ConfigurationUpdated);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WiFi.onEvent([&](WiFiEvent_t event, WiFiEventInfo_t info)
|
WiFi.onEvent([&](WiFiEvent_t event, WiFiEventInfo_t info)
|
||||||
{
|
{
|
||||||
if(event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED)
|
if(event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED)
|
||||||
{
|
{
|
||||||
onDisconnected();
|
if(!_openAP && !_connecting && _connected)
|
||||||
|
{
|
||||||
|
onDisconnected();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(event == ARDUINO_EVENT_WIFI_STA_GOT_IP)
|
else if(event == ARDUINO_EVENT_WIFI_STA_CONNECTED)
|
||||||
{
|
{
|
||||||
onConnected();
|
onConnected();
|
||||||
}
|
}
|
||||||
|
else if(event == ARDUINO_EVENT_WIFI_SCAN_DONE)
|
||||||
|
{
|
||||||
|
Log->println(F("Wi-Fi scan done"));
|
||||||
|
_foundNetworks = WiFi.scanComplete();
|
||||||
|
|
||||||
|
for (int i = 0; i < _foundNetworks; i++)
|
||||||
|
{
|
||||||
|
Log->println(String(F("SSID ")) + WiFi.SSID(i) + String(F(" found with RSSI: ")) +
|
||||||
|
String(WiFi.RSSI(i)) + String(F("(")) +
|
||||||
|
String(constrain((100.0 + WiFi.RSSI(i)) * 2, 0, 100)) +
|
||||||
|
String(F(" %) and BSSID: ")) + WiFi.BSSIDstr(i) +
|
||||||
|
String(F(" and channel: ")) + String(WiFi.channel(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_connectOnScanDone && _foundNetworks > 0)
|
||||||
|
{
|
||||||
|
connect();
|
||||||
|
}
|
||||||
|
else if (_connectOnScanDone)
|
||||||
|
{
|
||||||
|
Log->println("No networks found, restarting scan");
|
||||||
|
scan(false, true);
|
||||||
|
}
|
||||||
|
else if (_openAP)
|
||||||
|
{
|
||||||
|
openAP();
|
||||||
|
}
|
||||||
|
else if(_convertOldWiFi)
|
||||||
|
{
|
||||||
|
_convertOldWiFi = false;
|
||||||
|
_preferences->putBool(preference_wifi_converted, true);
|
||||||
|
|
||||||
|
wifi_config_t wifi_cfg;
|
||||||
|
if(esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) {
|
||||||
|
Log->println("Failed to get Wi-Fi configuration in RAM");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esp_wifi_set_storage(WIFI_STORAGE_FLASH) != ESP_OK) {
|
||||||
|
Log->println("Failed to set storage Wi-Fi");
|
||||||
|
}
|
||||||
|
|
||||||
|
String tempSSID = String(reinterpret_cast<const char*>(wifi_cfg.sta.ssid));
|
||||||
|
String tempPass = String(reinterpret_cast<const char*>(wifi_cfg.sta.password));
|
||||||
|
tempSSID.trim();
|
||||||
|
tempPass.trim();
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < _foundNetworks; i++)
|
||||||
|
{
|
||||||
|
if(tempSSID.length() > 0 && tempSSID == WiFi.SSID(i) && tempPass.length() > 0)
|
||||||
|
{
|
||||||
|
ssid = tempSSID;
|
||||||
|
pass = tempPass;
|
||||||
|
_preferences->putString(preference_wifi_ssid, ssid);
|
||||||
|
_preferences->putString(preference_wifi_pass, pass);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(wifi_cfg.sta.ssid, 0, sizeof(wifi_cfg.sta.ssid));
|
||||||
|
memset(wifi_cfg.sta.password, 0, sizeof(wifi_cfg.sta.password));
|
||||||
|
|
||||||
|
if (esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) {
|
||||||
|
Log->println("Failed to clear NVS Wi-Fi configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(found)
|
||||||
|
{
|
||||||
|
Log->println(String("Attempting to connect to saved SSID ") + String(ssid));
|
||||||
|
_connectOnScanDone = true;
|
||||||
|
_openAP = false;
|
||||||
|
scan(false, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log->println("No SSID or Wifi password saved, opening AP");
|
||||||
|
_connectOnScanDone = false;
|
||||||
|
_openAP = true;
|
||||||
|
scan(false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ssid.trim();
|
||||||
|
pass.trim();
|
||||||
|
|
||||||
|
if(ssid.length() > 0 && ssid != "~" && pass.length() > 0)
|
||||||
|
{
|
||||||
|
Log->println(String("Attempting to connect to saved SSID ") + String(ssid));
|
||||||
|
_connectOnScanDone = true;
|
||||||
|
_openAP = false;
|
||||||
|
scan(false, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!_preferences->getBool(preference_wifi_converted, false))
|
||||||
|
{
|
||||||
|
_connectOnScanDone = false;
|
||||||
|
_openAP = false;
|
||||||
|
_convertOldWiFi = true;
|
||||||
|
scan(false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssid.trim();
|
||||||
|
pass.trim();
|
||||||
|
|
||||||
|
if(ssid.length() > 0 && ssid != "~" && pass.length() > 0)
|
||||||
|
{
|
||||||
|
Log->println(String("Attempting to connect to saved SSID ") + String(ssid));
|
||||||
|
_connectOnScanDone = true;
|
||||||
|
_openAP = false;
|
||||||
|
scan(false, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log->println("No SSID or Wifi password saved, opening AP");
|
||||||
|
_connectOnScanDone = false;
|
||||||
|
_openAP = true;
|
||||||
|
scan(false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WifiDevice::scan(bool passive, bool async)
|
||||||
|
{
|
||||||
|
WiFi.scanDelete();
|
||||||
|
|
||||||
|
if(async)
|
||||||
|
{
|
||||||
|
Log->println(F("Wi-Fi async scan started"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log->println(F("Wi-Fi sync scan started"));
|
||||||
|
}
|
||||||
|
if(passive)
|
||||||
|
{
|
||||||
|
WiFi.scanNetworks(async,false,true,75U);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WiFi.scanNetworks(async);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WifiDevice::openAP()
|
||||||
|
{
|
||||||
|
if(_startAP)
|
||||||
|
{
|
||||||
|
WiFi.persistent(false);
|
||||||
|
WiFi.mode(WIFI_AP_STA);
|
||||||
|
WiFi.persistent(false);
|
||||||
|
WiFi.softAPsetHostname(_hostname.c_str());
|
||||||
|
WiFi.softAP("NukiHub", "NukiHubESP32");
|
||||||
|
WiFi.persistent(false);
|
||||||
|
_startAP = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WifiDevice::connect()
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
String ssid = _preferences->getString(preference_wifi_ssid, "");
|
||||||
|
String pass = _preferences->getString(preference_wifi_pass, "");
|
||||||
|
WiFi.persistent(false);
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.setHostname(_hostname.c_str());
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
int bestConnection = -1;
|
||||||
|
for (int i = 0; i < _foundNetworks; i++)
|
||||||
|
{
|
||||||
|
if (ssid == WiFi.SSID(i))
|
||||||
|
{
|
||||||
|
Log->println(String(F("Saved SSID ")) + ssid + String(F(" found with RSSI: ")) +
|
||||||
|
String(WiFi.RSSI(i)) + String(F("(")) +
|
||||||
|
String(constrain((100.0 + WiFi.RSSI(i)) * 2, 0, 100)) +
|
||||||
|
String(F(" %) and BSSID: ")) + WiFi.BSSIDstr(i) +
|
||||||
|
String(F(" and channel: ")) + String(WiFi.channel(i)));
|
||||||
|
if (bestConnection == -1)
|
||||||
|
{
|
||||||
|
bestConnection = i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (WiFi.RSSI(i) > WiFi.RSSI(bestConnection))
|
||||||
|
{
|
||||||
|
bestConnection = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestConnection == -1)
|
||||||
|
{
|
||||||
|
Log->print("No network found with SSID: ");
|
||||||
|
Log->println(ssid);
|
||||||
|
if(_preferences->getBool(preference_restart_on_disconnect, false) && ((esp_timer_get_time() / 1000) > 60000)) restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
||||||
|
_connectOnScanDone = true;
|
||||||
|
_openAP = false;
|
||||||
|
scan(false, true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_connecting = true;
|
||||||
|
Log->println(String(F("Trying to connect to SSID ")) + ssid + String(F(" found with RSSI: ")) +
|
||||||
|
String(WiFi.RSSI(bestConnection)) + String(F("(")) +
|
||||||
|
String(constrain((100.0 + WiFi.RSSI(bestConnection)) * 2, 0, 100)) +
|
||||||
|
String(F(" %) and BSSID: ")) + WiFi.BSSIDstr(bestConnection) +
|
||||||
|
String(F(" and channel: ")) + String(WiFi.channel(bestConnection)));
|
||||||
|
ret = WiFi.begin(ssid.c_str(), pass.c_str(), WiFi.channel(bestConnection), WiFi.BSSID(bestConnection), true);
|
||||||
|
WiFi.persistent(false);
|
||||||
|
_connecting = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ret)
|
||||||
|
{
|
||||||
|
int loop = 0;
|
||||||
|
|
||||||
|
while(!isConnected() && loop < 200)
|
||||||
|
{
|
||||||
|
loop++;
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isConnected())
|
||||||
|
{
|
||||||
|
esp_wifi_disconnect();
|
||||||
|
esp_wifi_stop();
|
||||||
|
esp_wifi_deinit();
|
||||||
|
|
||||||
|
Log->println(F("Failed to connect. Wait for ESP restart."));
|
||||||
|
delay(1000);
|
||||||
|
restartEsp(RestartReason::WifiInitFailed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!_preferences->getBool(preference_wifi_converted, false))
|
||||||
|
{
|
||||||
|
_preferences->putBool(preference_wifi_converted, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
int loop = 0;
|
||||||
|
|
||||||
|
while(!isConnected() && loop < 200)
|
||||||
|
{
|
||||||
|
loop++;
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isConnected())
|
||||||
|
{
|
||||||
|
if(_preferences->getBool(preference_restart_on_disconnect, false) && ((esp_timer_get_time() / 1000) > 60000))
|
||||||
|
{
|
||||||
|
restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Log->print("Connection failed, retrying");
|
||||||
|
_connectOnScanDone = true;
|
||||||
|
_openAP = false;
|
||||||
|
scan(false, true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WifiDevice::reconfigure()
|
void WifiDevice::reconfigure()
|
||||||
{
|
{
|
||||||
strcpy(WiFiDevice_reconfdetect, "reconfigure_wifi");
|
bool changed = false;
|
||||||
|
wifi_config_t wifi_cfg;
|
||||||
|
if(esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) {
|
||||||
|
Log->println("Failed to get Wi-Fi configuration in RAM");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esp_wifi_set_storage(WIFI_STORAGE_FLASH) != ESP_OK) {
|
||||||
|
Log->println("Failed to set storage Wi-Fi");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sizeof(wifi_cfg.sta.ssid) > 0)
|
||||||
|
{
|
||||||
|
memset(wifi_cfg.sta.ssid, 0, sizeof(wifi_cfg.sta.ssid));
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if(sizeof(wifi_cfg.sta.password) > 0)
|
||||||
|
{
|
||||||
|
memset(wifi_cfg.sta.password, 0, sizeof(wifi_cfg.sta.password));
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if(changed)
|
||||||
|
{
|
||||||
|
if (esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) {
|
||||||
|
Log->println("Failed to clear NVS Wi-Fi configuration");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_preferences->putString(preference_wifi_ssid, "");
|
||||||
|
_preferences->putString(preference_wifi_pass, "");
|
||||||
delay(200);
|
delay(200);
|
||||||
restartEsp(RestartReason::ReconfigureWifi);
|
restartEsp(RestartReason::ReconfigureWifi);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WifiDevice::isConnected()
|
bool WifiDevice::isConnected()
|
||||||
{
|
{
|
||||||
return WiFi.isConnected();
|
return (WiFi.status() == WL_CONNECTED);
|
||||||
}
|
|
||||||
|
|
||||||
ReconnectStatus WifiDevice::reconnect(bool force)
|
|
||||||
{
|
|
||||||
_wm.setFindBestRSSI(_preferences->getBool(preference_find_best_rssi));
|
|
||||||
|
|
||||||
if((!isConnected() || force) && !_isReconnecting)
|
|
||||||
{
|
|
||||||
_isReconnecting = true;
|
|
||||||
WiFi.disconnect();
|
|
||||||
int loop = 0;
|
|
||||||
|
|
||||||
while(isConnected() && loop <20)
|
|
||||||
{
|
|
||||||
delay(100);
|
|
||||||
loop++;
|
|
||||||
}
|
|
||||||
|
|
||||||
_wm.resetScan();
|
|
||||||
_wm.autoConnect();
|
|
||||||
_isReconnecting = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!isConnected() && _disconnectTs > (esp_timer_get_time() / 1000) - 120000) _wm.setEnableConfigPortal(_startAp || !_preferences->getBool(preference_network_wifi_fallback_disabled, false));
|
|
||||||
return isConnected() ? ReconnectStatus::Success : ReconnectStatus::Failure;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WifiDevice::onConnected()
|
void WifiDevice::onConnected()
|
||||||
{
|
{
|
||||||
_isReconnecting = false;
|
Log->println(F("Wi-Fi connected"));
|
||||||
_wm.setEnableConfigPortal(_startAp || !_preferences->getBool(preference_network_wifi_fallback_disabled, false));
|
_connectedChannel = WiFi.channel();
|
||||||
|
_connectedBSSID = WiFi.BSSID();
|
||||||
|
_connected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WifiDevice::onDisconnected()
|
void WifiDevice::onDisconnected()
|
||||||
{
|
{
|
||||||
_disconnectTs = (esp_timer_get_time() / 1000);
|
if(_connected)
|
||||||
if(_preferences->getBool(preference_restart_on_disconnect, false) && ((esp_timer_get_time() / 1000) > 60000)) restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
{
|
||||||
_wm.setEnableConfigPortal(false);
|
_connected = false;
|
||||||
reconnect();
|
_disconnectTs = (esp_timer_get_time() / 1000);
|
||||||
|
Log->println(F("Wi-Fi disconnected"));
|
||||||
|
|
||||||
|
//QUICK RECONNECT
|
||||||
|
_connecting = true;
|
||||||
|
String ssid = _preferences->getString(preference_wifi_ssid, "");
|
||||||
|
String pass = _preferences->getString(preference_wifi_pass, "");
|
||||||
|
WiFi.begin(ssid.c_str(), pass.c_str(), _connectedChannel, _connectedBSSID, true);
|
||||||
|
WiFi.persistent(false);
|
||||||
|
|
||||||
|
int loop = 0;
|
||||||
|
|
||||||
|
while(!isConnected() && loop < 50)
|
||||||
|
{
|
||||||
|
loop++;
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
_connecting = false;
|
||||||
|
//END QUICK RECONECT
|
||||||
|
|
||||||
|
if(!isConnected())
|
||||||
|
{
|
||||||
|
if(_preferences->getBool(preference_restart_on_disconnect, false) && ((esp_timer_get_time() / 1000) > 60000)) restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
||||||
|
|
||||||
|
WiFi.persistent(false);
|
||||||
|
WiFi.disconnect(true);
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.disconnect();
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
wifi_mode_t wifiMode;
|
||||||
|
esp_wifi_get_mode(&wifiMode);
|
||||||
|
|
||||||
|
while (wifiMode != WIFI_MODE_STA || WiFi.status() == WL_CONNECTED)
|
||||||
|
{
|
||||||
|
delay(500);
|
||||||
|
Log->println(F("Waiting for WiFi mode change or disconnection."));
|
||||||
|
esp_wifi_get_mode(&wifiMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
_connectOnScanDone = true;
|
||||||
|
_openAP = false;
|
||||||
|
scan(false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t WifiDevice::signalStrength()
|
int8_t WifiDevice::signalStrength()
|
||||||
@@ -155,7 +428,7 @@ String WifiDevice::BSSIDstr()
|
|||||||
return WiFi.BSSIDstr();
|
return WiFi.BSSIDstr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WifiDevice::clearRtcInitVar(WiFiManager *)
|
bool WifiDevice::isApOpen()
|
||||||
{
|
{
|
||||||
memset(WiFiDevice_reconfdetect, 0, sizeof WiFiDevice_reconfdetect);
|
return _openAP;
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <NetworkClientSecure.h>
|
#include <NetworkClientSecure.h>
|
||||||
#include <Preferences.h>
|
#include <Preferences.h>
|
||||||
#include "NetworkDevice.h"
|
#include "NetworkDevice.h"
|
||||||
#include "WiFiManager.h"
|
|
||||||
#include "IPConfiguration.h"
|
#include "IPConfiguration.h"
|
||||||
|
|
||||||
class WifiDevice : public NetworkDevice
|
class WifiDevice : public NetworkDevice
|
||||||
@@ -16,25 +15,32 @@ public:
|
|||||||
|
|
||||||
virtual void initialize();
|
virtual void initialize();
|
||||||
virtual void reconfigure();
|
virtual void reconfigure();
|
||||||
virtual ReconnectStatus reconnect(bool force = false);
|
virtual void scan(bool passive = false, bool async = true);
|
||||||
|
|
||||||
virtual bool isConnected();
|
virtual bool isConnected();
|
||||||
|
virtual bool isApOpen();
|
||||||
|
|
||||||
int8_t signalStrength() override;
|
int8_t signalStrength() override;
|
||||||
|
|
||||||
String localIP() override;
|
String localIP() override;
|
||||||
String BSSIDstr() override;
|
String BSSIDstr() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void clearRtcInitVar(WiFiManager*);
|
void openAP();
|
||||||
|
|
||||||
void onDisconnected();
|
void onDisconnected();
|
||||||
void onConnected();
|
void onConnected();
|
||||||
|
bool connect();
|
||||||
|
|
||||||
WiFiManager _wm;
|
|
||||||
Preferences* _preferences = nullptr;
|
Preferences* _preferences = nullptr;
|
||||||
|
|
||||||
bool _startAp = false;
|
int _foundNetworks = 0;
|
||||||
bool _isReconnecting = false;
|
int _disconnectCount = 0;
|
||||||
|
bool _connectOnScanDone = false;
|
||||||
|
bool _connecting = false;
|
||||||
|
bool _openAP = false;
|
||||||
|
bool _startAP = true;
|
||||||
|
bool _convertOldWiFi = false;
|
||||||
|
bool _connected = false;
|
||||||
|
uint8_t _connectedChannel = 0;
|
||||||
|
uint8_t* _connectedBSSID;
|
||||||
int64_t _disconnectTs = 0;
|
int64_t _disconnectTs = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ build_type = release
|
|||||||
custom_build = release
|
custom_build = release
|
||||||
board_build.partitions = partitions.csv
|
board_build.partitions = partitions.csv
|
||||||
build_unflags =
|
build_unflags =
|
||||||
|
-DESP32
|
||||||
-Werror=all
|
-Werror=all
|
||||||
-Wall
|
-Wall
|
||||||
build_flags =
|
build_flags =
|
||||||
@@ -54,7 +55,7 @@ lib_ignore =
|
|||||||
WiFiProv
|
WiFiProv
|
||||||
lib_deps =
|
lib_deps =
|
||||||
PsychicHttp=symlink://../lib/PsychicHttp
|
PsychicHttp=symlink://../lib/PsychicHttp
|
||||||
WiFiManager=symlink://../lib/WiFiManager
|
ArduinoJson=symlink://../lib/ArduinoJson
|
||||||
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
monitor_filters =
|
monitor_filters =
|
||||||
|
|||||||
Reference in New Issue
Block a user