Merge pull request #523 from iranl/wifi-fix-ota-fix

WiFi + OTA fix
This commit is contained in:
iranl
2024-11-15 20:19:11 +01:00
committed by GitHub
5 changed files with 159 additions and 113 deletions

View File

@@ -4,7 +4,7 @@
#define NUKI_HUB_VERSION "9.02"
#define NUKI_HUB_BUILD "unknownbuildnr"
#define NUKI_HUB_DATE "2024-11-11"
#define NUKI_HUB_DATE "2024-11-15"
#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"

View File

@@ -61,6 +61,7 @@
#define preference_disable_network_not_connected (char*)"disNtwNoCon"
// CHANGE DOES NOT REQUIRE REBOOT TO TAKE EFFECT
#define preference_find_best_rssi (char*)"nwbestrssi"
#define preference_ntw_reconfigure (char*)"ntwRECONF"
#define preference_auth_max_entries (char*)"authmaxentry"
#define preference_auth_info_enabled (char*)"authInfoEna"
@@ -188,6 +189,7 @@ inline void initPreferences(Preferences* preferences)
preferences->putBool(preference_ip_dhcp_enabled, true);
preferences->putBool(preference_enable_bootloop_reset, false);
preferences->putBool(preference_show_secrets, false);
preferences->putBool(preference_find_best_rssi, true);
preferences->putBool(preference_conf_info_enabled, true);
preferences->putBool(preference_keypad_info_enabled, false);
@@ -355,7 +357,7 @@ private:
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_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_webserial_enabled,
preference_update_from_mqtt, preference_show_secrets, preference_ble_tx_power, preference_webserial_enabled, preference_find_best_rssi,
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_pwr, preference_network_custom_mdio, preference_ntw_reconfigure, preference_lock_max_auth_entry_count, preference_opener_max_auth_entry_count,
@@ -376,7 +378,7 @@ private:
preference_publish_authdata, preference_publish_debug_info, preference_official_hybrid_enabled, preference_mqtt_hass_enabled,
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_webserial_enabled, preference_hass_device_discovery,
preference_ntw_reconfigure, preference_keypad_check_code_enabled, preference_disable_network_not_connected
preference_ntw_reconfigure, preference_keypad_check_code_enabled, preference_disable_network_not_connected, preference_find_best_rssi
};
std::vector<char*> _bytePrefs =
{

View File

@@ -592,6 +592,7 @@ esp_err_t WebCfgServer::buildWifiConnectHtml(PsychicRequest *request)
response.print("<table>");
printInputField(&response, "WIFISSID", "SSID", "", 32, "id=\"inputssid\"", false, true);
printInputField(&response, "WIFIPASS", "Secret key", "", 63, "id=\"inputpass\"", false, true);
printCheckBox(&response, "FINDBESTRSSI", "Find AP with best signal (disable for hidden SSID)", _preferences->getBool(preference_find_best_rssi, true), "");
response.print("</table>");
response.print("<h3>IP Address assignment</h3>");
response.print("<table>");
@@ -675,6 +676,13 @@ bool WebCfgServer::processWiFi(PsychicRequest *request, String& message)
_preferences->putString(preference_ip_dns_server, value);
}
}
else if(key == "FINDBESTRSSI")
{
if(_preferences->getBool(preference_find_best_rssi, false) != (value == "1"))
{
_preferences->putBool(preference_find_best_rssi, (value == "1"));
}
}
}
ssid.trim();
@@ -1813,6 +1821,16 @@ bool WebCfgServer::processArgs(PsychicRequest *request, String& message)
//configChanged = true;
}
}
else if(key == "FINDBESTRSSI")
{
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 == "RSTDISC")
{
if(_preferences->getBool(preference_restart_on_disconnect, false) != (value == "1"))
@@ -3508,6 +3526,7 @@ esp_err_t WebCfgServer::buildNetworkConfigHtml(PsychicRequest *request)
#endif
printCheckBox(&response, "RSTDISC", "Restart on disconnect", _preferences->getBool(preference_restart_on_disconnect), "");
printCheckBox(&response, "CHECKUPDATE", "Check for Firmware Updates every 24h", _preferences->getBool(preference_check_updates), "");
printCheckBox(&response, "FINDBESTRSSI", "Find WiFi AP with strongest signal", _preferences->getBool(preference_find_best_rssi, false), "");
response.print("</table>");
response.print("<h3>IP Address assignment</h3>");
response.print("<table>");
@@ -3581,7 +3600,7 @@ esp_err_t WebCfgServer::buildAdvancedConfigHtml(PsychicRequest *request)
response.print(_preferences->getBool(preference_enable_bootloop_reset, false) ? "Enabled" : "Disabled");
response.print("</td></tr>");
printCheckBox(&response, "DISNTWNOCON", "Disable Network if not connected within 60s", _preferences->getBool(preference_disable_network_not_connected, false), "");
printCheckBox(&response, "WEBLOG", "Enable WebSerial logging", _preferences->getBool(preference_webserial_enabled), "");
//printCheckBox(&response, "WEBLOG", "Enable WebSerial logging", _preferences->getBool(preference_webserial_enabled), "");
printCheckBox(&response, "BTLPRST", "Enable Bootloop prevention (Try to reset these settings to default on bootloop)", true, "");
printInputField(&response, "BUFFSIZE", "Char buffer size (min 4096, max 32768)", _preferences->getInt(preference_buffer_size, CHAR_BUFFER_SIZE), 6, "");
response.print("<tr><td>Advised minimum char buffer size based on current settings</td><td id=\"mincharbuffer\"></td>");
@@ -4063,8 +4082,10 @@ esp_err_t WebCfgServer::buildInfoHtml(PsychicRequest *request)
if(esp_psram_get_size() > 0)
{
response.print("\nPSRAM Available: Yes");
response.print("\nFree PSRAM: ");
response.print((esp_get_free_heap_size() - ESP.getFreeHeap()));
response.print("\nFree usable PSRAM: ");
response.print(ESP.getFreePsram());
response.print("\nTotal usable PSRAM: ");
response.print(ESP.getPsramSize());
response.print("\nTotal PSRAM: ");
response.print(esp_psram_get_size());
response.print("\nTotal free heap: ");
@@ -4165,6 +4186,9 @@ esp_err_t WebCfgServer::buildInfoHtml(PsychicRequest *request)
{
response.print(_preferences->getInt(preference_rssi_publish_interval, 60));
}
response.print("\nFind WiFi AP with strongest signal: ");
response.print(_preferences->getBool(preference_find_best_rssi, false) ? "Yes" : "No");
}
#endif
response.print("\nRestart ESP32 on network disconnect enabled: ");
@@ -4644,7 +4668,7 @@ esp_err_t WebCfgServer::processUnpair(PsychicRequest *request, bool opener)
{
_nukiOpener->unpair();
}
_network->disableHASS();
waitAndProcess(false, 1000);
restartEsp(RestartReason::DeviceUnpaired);

View File

@@ -56,7 +56,7 @@ int64_t restartTs = (pow(2,64) - (5 * 1000 * 60000)) / 1000;
#include "../../src/NukiNetwork.h"
#include "../../src/EspMillis.h"
int64_t restartTs = 10 * 1000 * 60000;
int64_t restartTs = 10 * 60 * 1000;
#endif
@@ -129,6 +129,28 @@ void setReroute()
}
#endif
uint8_t checkPartition()
{
const esp_partition_t* running_partition = esp_ota_get_running_partition();
Log->print(F("Partition size: "));
Log->println(running_partition->size);
Log->print(F("Partition subtype: "));
Log->println(running_partition->subtype);
if(running_partition->size == 1966080)
{
return 0; //OLD PARTITION TABLE
}
else if(running_partition->subtype == ESP_PARTITION_SUBTYPE_APP_OTA_0)
{
return 1; //NEW PARTITION TABLE, RUNNING MAIN APP
}
else
{
return 2; //NEW PARTITION TABLE, RUNNING UPDATER APP
}
}
void networkTask(void *pvParameters)
{
int64_t networkLoopTs = 0;
@@ -151,7 +173,7 @@ void networkTask(void *pvParameters)
network->update();
bool connected = network->isConnected();
#ifdef DEBUG_NUKIHUB
if(connected && reroute)
{
@@ -180,6 +202,17 @@ void networkTask(void *pvParameters)
networkLoopTs = espMillis();
}
if(espMillis() > restartTs)
{
uint8_t partitionType = checkPartition();
if(partitionType!=1)
{
esp_ota_set_boot_partition(esp_ota_get_next_update_partition(NULL));
}
restartEsp(RestartReason::RestartTimer);
}
esp_task_wdt_reset();
}
}
@@ -275,28 +308,6 @@ void bootloopDetection()
}
#endif
uint8_t checkPartition()
{
const esp_partition_t* running_partition = esp_ota_get_running_partition();
Log->print(F("Partition size: "));
Log->println(running_partition->size);
Log->print(F("Partition subtype: "));
Log->println(running_partition->subtype);
if(running_partition->size == 1966080)
{
return 0; //OLD PARTITION TABLE
}
else if(running_partition->subtype == ESP_PARTITION_SUBTYPE_APP_OTA_0)
{
return 1; //NEW PARTITION TABLE, RUNNING MAIN APP
}
else
{
return 2; //NEW PARTITION TABLE, RUNNING UPDATER APP
}
}
esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
switch (evt->event_id)
@@ -344,6 +355,13 @@ void otaTask(void *pvParameter)
updateUrl = preferences->getString(preference_ota_main_url);
preferences->putString(preference_ota_main_url, "");
}
while(!network->isConnected())
{
Log->println("OTA waiting for network");
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
Log->println("Starting OTA task");
esp_http_client_config_t config =
{
@@ -581,7 +599,7 @@ void setup()
{
networkOpener->initialize();
}
nukiOpener = new NukiOpenerWrapper("NukiHub", deviceIdOpener, bleScanner, networkOpener, gpio, preferences);
nukiOpener->initialize();
}

View File

@@ -1,6 +1,7 @@
#include "WifiDevice.h"
#include "esp_wifi.h"
#include <WiFi.h>
#include <ESPmDNS.h>
#include "../PreferencesKeys.h"
#include "../Logger.h"
#include "../RestartReason.h"
@@ -62,7 +63,7 @@ void WifiDevice::initialize()
String(F(" and channel: ")) + String(WiFi.channel(i)));
}
if (_connectOnScanDone && _foundNetworks > 0)
if ((_connectOnScanDone && _foundNetworks > 0) || _preferences->getBool(preference_find_best_rssi, false))
{
connect();
}
@@ -199,6 +200,10 @@ void WifiDevice::openAP()
WiFi.softAPsetHostname(_hostname.c_str());
WiFi.softAP("NukiHub", "NukiHubESP32");
_startAP = false;
if(MDNS.begin(_hostname.c_str())){
MDNS.addService("http", "tcp", 80);
}
}
}
@@ -212,107 +217,104 @@ bool WifiDevice::connect()
delay(500);
int bestConnection = -1;
for (int i = 0; i < _foundNetworks; i++)
if(_preferences->getBool(preference_find_best_rssi, false))
{
if (ssid == WiFi.SSID(i))
for (int i = 0; i < _foundNetworks; 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)
if (ssid == WiFi.SSID(i))
{
bestConnection = i;
}
else
{
if (WiFi.RSSI(i) > WiFi.RSSI(bestConnection))
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);
}
else
{
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)));
}
}
if (bestConnection == -1)
_connecting = true;
esp_wifi_scan_stop();
if(!_ipConfiguration->dhcpEnabled())
{
Log->print("No network found with SSID: ");
Log->println(ssid);
if(_preferences->getBool(preference_restart_on_disconnect, false) && (espMillis() > 60000))
{
restartEsp(RestartReason::RestartOnDisconnectWatchdog);
}
WiFi.config(_ipConfiguration->ipAddress(), _ipConfiguration->dnsServer(), _ipConfiguration->defaultGateway(), _ipConfiguration->subnet());
}
WiFi.begin(ssid, pass);
auto status = WiFi.waitForConnectResult(10000);
switch (status)
{
case WL_CONNECTED:
Log->println("WiFi connected");
break;
case WL_NO_SSID_AVAIL:
Log->println("WiFi SSID not available");
break;
case WL_CONNECT_FAILED:
Log->println("WiFi connection failed");
break;
case WL_IDLE_STATUS:
Log->println("WiFi changing status");
break;
case WL_DISCONNECTED:
Log->println("WiFi disconnected");
break;
default:
Log->println("WiFi timeout");
break;
}
if (status != WL_CONNECTED)
{
Log->println("Retrying");
_connectOnScanDone = true;
_openAP = false;
scan(false, true);
_connecting = false;
return false;
}
else
{
_connecting = true;
esp_wifi_scan_stop();
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)));
if(!_ipConfiguration->dhcpEnabled())
if(!_preferences->getBool(preference_wifi_converted, false))
{
WiFi.config(_ipConfiguration->ipAddress(), _ipConfiguration->dnsServer(), _ipConfiguration->defaultGateway(), _ipConfiguration->subnet());
_preferences->putBool(preference_wifi_converted, true);
}
_connecting = false;
return true;
}
WiFi.begin(ssid, pass);
auto status = WiFi.waitForConnectResult(10000);
switch (status)
{
case WL_CONNECTED:
Log->println("WiFi connected");
break;
case WL_NO_SSID_AVAIL:
Log->println("WiFi SSID not available");
break;
case WL_CONNECT_FAILED:
Log->println("WiFi connection failed");
break;
case WL_IDLE_STATUS:
Log->println("WiFi changing status");
break;
case WL_DISCONNECTED:
Log->println("WiFi disconnected");
break;
default:
Log->println("WiFi timeout");
break;
}
if (status != WL_CONNECTED)
{
if(_preferences->getBool(preference_restart_on_disconnect, false) && (espMillis() > 60000))
{
restartEsp(RestartReason::RestartOnDisconnectWatchdog);
_connecting = false;
return false;
}
Log->println("Retrying");
_connectOnScanDone = true;
_openAP = false;
scan(false, true);
_connecting = false;
return false;
}
else
{
if(!_preferences->getBool(preference_wifi_converted, false))
{
_preferences->putBool(preference_wifi_converted, true);
}
_connecting = false;
return true;
}
if(_preferences->getBool(preference_restart_on_disconnect, false) && (espMillis() > 60000))
{
restartEsp(RestartReason::RestartOnDisconnectWatchdog);
_connecting = false;
return false;
}
return false;