Added WIFI auto-tune for EMP prevention
This commit is contained in:
parent
682ffb4fee
commit
cf8ddebcc6
293
main/App.cpp
293
main/App.cpp
@ -36,153 +36,176 @@ CommandProcessor * App::getCommandProcessor()
|
|||||||
|
|
||||||
void App::init()
|
void App::init()
|
||||||
{
|
{
|
||||||
#pragma message(WH_VERSION)
|
#pragma message(WH_VERSION)
|
||||||
ESP_LOGW(TAG, "Starting the app...");
|
ESP_LOGW(TAG, "Starting the app...");
|
||||||
uint8_t mac[8];
|
uint8_t mac[8];
|
||||||
esp_read_mac(mac, ESP_MAC_WIFI_STA);
|
esp_read_mac(mac, ESP_MAC_WIFI_STA);
|
||||||
//Lets report all programmed parameters
|
//Lets report all programmed parameters
|
||||||
ESP_LOGI(TAG, "mqtt_id: %s, wifi mac: %02x:%02x:%02x:%02x:%02x:%02x well_id: %u, group_id: %u", SETTINGS.mqtt.device_id,
|
ESP_LOGI(TAG, "mqtt_id: %s, wifi mac: %02x:%02x:%02x:%02x:%02x:%02x well_id: %u, group_id: %u", SETTINGS.mqtt.device_id,
|
||||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], SETTINGS.device.tata_id, SETTINGS.device.group_id);
|
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], SETTINGS.device.tata_id, SETTINGS.device.group_id);
|
||||||
|
|
||||||
m_led = new Led(LED_PIN);
|
m_led = new Led(LED_PIN);
|
||||||
m_wifi = new Wifi();
|
m_wifi = new Wifi();
|
||||||
|
m_commandProcessor = new CommandProcessor(*this);
|
||||||
|
m_ble_service = new BleService(*this);
|
||||||
|
m_ble_service->start();
|
||||||
|
|
||||||
m_commandProcessor = new CommandProcessor(*this);
|
bool needs_provision = true;
|
||||||
|
bool first_attempt = true;
|
||||||
|
bool connected = false;
|
||||||
|
|
||||||
m_ble_service = new BleService(*this);
|
#if 0
|
||||||
m_ble_service->start();
|
ESP_LOGI(TAG, "Scanning wifi networks...");
|
||||||
|
int num_networks = WiFi.scanNetworks(false, false, false, 0);
|
||||||
|
for(int n = 0; n < num_networks; n++)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "%s, %d", WiFi.SSID(n).c_str(), WiFi.RSSI(n));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool needs_provision = true;
|
// Main connection/provisioning cycle
|
||||||
|
while(!connected)
|
||||||
|
{
|
||||||
|
needs_provision = true;
|
||||||
|
|
||||||
#if 0
|
// Try WiFi connections (provisioned networks + fallback)
|
||||||
ESP_LOGI(TAG, "Scanning wifi networks...");
|
if(SETTINGS.wifi.num > 0 || !first_attempt)
|
||||||
|
{
|
||||||
|
if(!first_attempt)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Retrying WiFi connections after provisioning timeout...");
|
||||||
|
m_wifi->pause(false); // Resume WiFi task
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Trying provisioned networks...");
|
||||||
|
m_wifi->start();
|
||||||
|
}
|
||||||
|
|
||||||
int num_networks = WiFi.scanNetworks(false, false, false, 0);
|
m_led->setColor(0, 255, 0);
|
||||||
|
Wifi::WIFI_STATUS wifi_status = m_wifi->waitForConnection();
|
||||||
|
ESP_LOGI(TAG, "WiFi final status: %d", (int)wifi_status);
|
||||||
|
|
||||||
for(int n = 0; n < num_networks; n++)
|
if(wifi_status == Wifi::WIFI_STATUS::CONNECTED)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "%s, %d", WiFi.SSID(n).c_str(), WiFi.RSSI(n));
|
ESP_LOGI(TAG, "Connected to WiFi successfully");
|
||||||
}
|
|
||||||
#endif
|
// Sync time
|
||||||
|
ESP_LOGI(TAG, "Getting local time...");
|
||||||
|
struct tm timeinfo;
|
||||||
|
int tries = 5;
|
||||||
|
while (tries--)
|
||||||
|
{
|
||||||
|
configTime(0, 0, "pool.ntp.org");
|
||||||
|
if(getLocalTime(&timeinfo))
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "pool.ntp.org ok");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ESP_LOGE(TAG, "pool.ntp.org Failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
needs_provision = false;
|
||||||
|
connected = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "All WiFi connections failed, will enter provisioning mode");
|
||||||
|
m_wifi->pause(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(first_attempt)
|
||||||
|
{
|
||||||
|
// No provisioned networks - try fallback directly
|
||||||
|
ESP_LOGI(TAG, "No provisioned networks, trying fallback...");
|
||||||
|
m_led->setColor(0, 255, 0);
|
||||||
|
m_wifi->start();
|
||||||
|
Wifi::WIFI_STATUS wifi_status = m_wifi->waitForConnection();
|
||||||
|
|
||||||
|
if(wifi_status == Wifi::WIFI_STATUS::CONNECTED)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Connected to fallback network");
|
||||||
|
|
||||||
|
// Sync time
|
||||||
|
ESP_LOGI(TAG, "Getting local time...");
|
||||||
|
struct tm timeinfo;
|
||||||
|
int tries = 5;
|
||||||
|
while (tries--)
|
||||||
|
{
|
||||||
|
configTime(0, 0, "pool.ntp.org");
|
||||||
|
if(getLocalTime(&timeinfo))
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "pool.ntp.org ok");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ESP_LOGE(TAG, "pool.ntp.org Failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
needs_provision = false;
|
||||||
|
connected = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Fallback connection failed");
|
||||||
|
m_wifi->pause(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(SETTINGS.wifi.num > 0)
|
// Enter provisioning mode if needed
|
||||||
{
|
if(needs_provision && !connected)
|
||||||
// try connecting
|
{
|
||||||
m_led->setColor(0, 255, 0);
|
ESP_LOGI(TAG, "Entering provisioning mode for 10 minutes...");
|
||||||
m_wifi->start();
|
m_led->setPulse(0, 0, 255);
|
||||||
|
|
||||||
|
// Start provisioning mode in WiFi
|
||||||
|
m_wifi->startProvisioning();
|
||||||
|
|
||||||
|
// Start the provision server
|
||||||
|
ProvisionSoftAP provision(80);
|
||||||
|
provision.start();
|
||||||
|
|
||||||
|
// Wait for either successful provisioning or timeout
|
||||||
|
ESP_LOGI(TAG, "Waiting for provisioning (10 minute timeout)...");
|
||||||
|
while(m_wifi->status() == Wifi::WIFI_STATUS::PROVISIONING)
|
||||||
|
{
|
||||||
|
if(m_wifi->isProvisioningTimedOut())
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Provisioning timeout reached (10 minutes)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// You could add logic here to check if new credentials were received
|
||||||
|
// and attempt immediate connection if so
|
||||||
|
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop provisioning
|
||||||
|
ESP_LOGI(TAG, "Stopping provisioning mode...");
|
||||||
|
// provision.stop(); // Add this method to ProvisionSoftAP if available
|
||||||
|
m_wifi->stopProvisioning();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Provisioning period ended, will retry connections in 5 seconds...");
|
||||||
|
delay(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
first_attempt = false;
|
||||||
|
}
|
||||||
|
|
||||||
Wifi::WIFI_STATUS wifi_status = m_wifi->waitForConnection();
|
ESP_LOGI(TAG, "WiFi connection established, continuing with app initialization...");
|
||||||
|
|
||||||
if(wifi_status == Wifi::WIFI_STATUS::CONNECTED)
|
otaCheck();
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "Getting local time...");
|
// m_led->setPulse(255, 0, 255);
|
||||||
struct tm timeinfo;
|
m_led->allOff();
|
||||||
|
|
||||||
int tries = 5;
|
m_mqtt_service = new MqttService(*this);
|
||||||
while (tries--)
|
m_mqtt_service->start();
|
||||||
{
|
|
||||||
configTime(0, 0, "pool.ntp.org"); // needed?
|
|
||||||
|
|
||||||
if(getLocalTime(&timeinfo))
|
m_sensor_service = new SensorService(*this);
|
||||||
{
|
m_sensor_service->start();
|
||||||
ESP_LOGI(TAG, "pool.ntp.org ok");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ESP_LOGE(TAG, "pool.ntp.org Failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
needs_provision = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "Provisioned networks failed, trying fallback...");
|
|
||||||
// Don't pause yet - let it try the fallback
|
|
||||||
// The modified startConnecting() will attempt CBX_IoT fallback
|
|
||||||
// Wait a bit more for the fallback attempt
|
|
||||||
delay(5000);
|
|
||||||
wifi_status = m_wifi->status();
|
|
||||||
|
|
||||||
if(wifi_status == Wifi::WIFI_STATUS::CONNECTED)
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "Connected via fallback network");
|
|
||||||
ESP_LOGI(TAG, "Getting local time...");
|
|
||||||
struct tm timeinfo;
|
|
||||||
|
|
||||||
int tries = 5;
|
|
||||||
while (tries--)
|
|
||||||
{
|
|
||||||
configTime(0, 0, "pool.ntp.org"); // needed?
|
|
||||||
|
|
||||||
if(getLocalTime(&timeinfo))
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "pool.ntp.org ok");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ESP_LOGE(TAG, "pool.ntp.org Failed");
|
|
||||||
}
|
|
||||||
needs_provision = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "Fallback also failed, entering provisioning mode");
|
|
||||||
m_wifi->pause(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// No provisioned networks - try fallback directly
|
|
||||||
ESP_LOGI(TAG, "No provisioned networks, trying fallback...");
|
|
||||||
m_led->setColor(0, 255, 0);
|
|
||||||
m_wifi->start();
|
|
||||||
Wifi::WIFI_STATUS wifi_status = m_wifi->waitForConnection();
|
|
||||||
|
|
||||||
if(wifi_status == Wifi::WIFI_STATUS::CONNECTED)
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "Connected to fallback network");
|
|
||||||
ESP_LOGI(TAG, "Getting local time...");
|
|
||||||
struct tm timeinfo;
|
|
||||||
|
|
||||||
int tries = 5;
|
|
||||||
while (tries--)
|
|
||||||
{
|
|
||||||
configTime(0, 0, "pool.ntp.org"); // needed?
|
|
||||||
|
|
||||||
if(getLocalTime(&timeinfo))
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "pool.ntp.org ok");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ESP_LOGE(TAG, "pool.ntp.org Failed");
|
|
||||||
}
|
|
||||||
needs_provision = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "Fallback failed, entering provisioning mode");
|
|
||||||
m_wifi->pause(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(needs_provision)
|
|
||||||
{
|
|
||||||
m_led->setPulse(0, 0, 255);
|
|
||||||
ProvisionSoftAP provision(80);
|
|
||||||
provision.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
otaCheck();
|
|
||||||
|
|
||||||
// m_led->setPulse(255, 0, 255);
|
|
||||||
m_led->allOff();
|
|
||||||
|
|
||||||
m_mqtt_service = new MqttService(*this);
|
|
||||||
m_mqtt_service->start();
|
|
||||||
|
|
||||||
m_sensor_service = new SensorService(*this);
|
|
||||||
m_sensor_service->start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::otaCheck()
|
void App::otaCheck()
|
||||||
|
|||||||
375
main/Wifi.cpp
375
main/Wifi.cpp
@ -9,6 +9,7 @@
|
|||||||
#include "app_config.h"
|
#include "app_config.h"
|
||||||
|
|
||||||
#include <esp_wifi.h>
|
#include <esp_wifi.h>
|
||||||
|
#include "esp_phy_init.h"
|
||||||
|
|
||||||
static const char *TAG = "Wifi";
|
static const char *TAG = "Wifi";
|
||||||
#define IGNORE_SSID_MINS 20
|
#define IGNORE_SSID_MINS 20
|
||||||
@ -20,6 +21,9 @@ Wifi::Wifi()
|
|||||||
{
|
{
|
||||||
esp_log_level_set("wifi", ESP_LOG_WARN);
|
esp_log_level_set("wifi", ESP_LOG_WARN);
|
||||||
esp_log_level_set("wifi_init", ESP_LOG_INFO);
|
esp_log_level_set("wifi_init", ESP_LOG_INFO);
|
||||||
|
// Add WiFi configuration here
|
||||||
|
esp_wifi_set_country_code("US", true); // Or your country code
|
||||||
|
//WiFi.setSleep(false); // Disable power saving if BT is enabled, do not do this!
|
||||||
|
|
||||||
WiFi.onEvent(std::bind(&Wifi::wifi_event, this, _1, _2));
|
WiFi.onEvent(std::bind(&Wifi::wifi_event, this, _1, _2));
|
||||||
#ifdef USE_TIMER
|
#ifdef USE_TIMER
|
||||||
@ -48,78 +52,230 @@ void Wifi::timerCallback(void* arg)
|
|||||||
|
|
||||||
void Wifi::wifi_event(arduino_event_id_t event, arduino_event_info_t info)
|
void Wifi::wifi_event(arduino_event_id_t event, arduino_event_info_t info)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "event: %s (%d)", WiFi.eventName(event), (int)event);
|
ESP_LOGI(TAG, "event: %s (%d)", WiFi.eventName(event), (int)event);
|
||||||
if(event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED)
|
if(event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED)
|
||||||
{
|
{
|
||||||
wifi_err_reason_t reason = (wifi_err_reason_t)info.wifi_sta_disconnected.reason;
|
wifi_err_reason_t reason = (wifi_err_reason_t)info.wifi_sta_disconnected.reason;
|
||||||
ESP_LOGI(TAG, "reason: %s", WiFi.disconnectReasonName(reason));
|
ESP_LOGI(TAG, "reason: %s, rssi: %d", WiFi.disconnectReasonName(reason), WiFi.RSSI());
|
||||||
}
|
ESP_LOGI(TAG, "Local IP: %s", WiFi.localIP().toString().c_str());
|
||||||
|
}
|
||||||
|
if(event == ARDUINO_EVENT_WIFI_STA_CONNECTED)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Connected - RSSI: %d, Channel: %d", WiFi.RSSI(), WiFi.channel());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wifi::task()
|
void Wifi::task()
|
||||||
{
|
{
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
if(!WiFi.isConnected())
|
// Check if we're in provisioning mode and handle timeout
|
||||||
{
|
if(m_wifi_status == WIFI_STATUS::PROVISIONING)
|
||||||
m_wifi_status = WIFI_STATUS::PENDING;
|
{
|
||||||
m_wifi_status = startConnecting();
|
if(isProvisioningTimedOut())
|
||||||
|
{
|
||||||
delay(500);
|
ESP_LOGW(TAG, "Provisioning timeout reached, stopping AP mode");
|
||||||
|
stopProvisioning();
|
||||||
while(m_pause)
|
m_wifi_status = WIFI_STATUS::NOT_CONNECTED;
|
||||||
{
|
m_provision_timeout = true;
|
||||||
delay(100);
|
}
|
||||||
}
|
delay(1000); // Check every second during provisioning
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check pause flag FIRST (but not during provisioning)
|
||||||
|
while(m_pause && m_wifi_status != WIFI_STATUS::PROVISIONING)
|
||||||
|
{
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!WiFi.isConnected())
|
||||||
|
{
|
||||||
|
m_wifi_status = WIFI_STATUS::PENDING;
|
||||||
|
m_wifi_status = startConnecting();
|
||||||
|
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
delay(15000);
|
delay(15000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Wifi::startProvisioning()
|
||||||
|
{
|
||||||
|
m_wifi_status = WIFI_STATUS::PROVISIONING;
|
||||||
|
m_provision_start_time = millis();
|
||||||
|
m_provision_timeout = false;
|
||||||
|
ESP_LOGI(TAG, "Starting provisioning mode for %lu minutes", PROVISION_TIMEOUT_MS / 60000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Wifi::stopProvisioning()
|
||||||
|
{
|
||||||
|
m_wifi_status = WIFI_STATUS::NOT_CONNECTED;
|
||||||
|
m_provision_start_time = 0;
|
||||||
|
WiFi.mode(WIFI_STA); // Stop AP mode
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Wifi::isProvisioningTimedOut()
|
||||||
|
{
|
||||||
|
if(m_provision_start_time == 0) return false;
|
||||||
|
return (millis() - m_provision_start_time) > PROVISION_TIMEOUT_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Wifi::resetProvisioningTimer()
|
||||||
|
{
|
||||||
|
m_provision_start_time = millis();
|
||||||
|
m_provision_timeout = false;
|
||||||
|
}
|
||||||
|
|
||||||
void Wifi::pause(bool pause)
|
void Wifi::pause(bool pause)
|
||||||
{
|
{
|
||||||
m_pause = pause;
|
m_pause = pause;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Wifi::shouldRecalibrateRadio(int failed_ssid_index)
|
||||||
|
{
|
||||||
|
// Check cooldown period
|
||||||
|
unsigned long current_time = millis();
|
||||||
|
bool cooldown_ok = (m_last_recalibration_time == 0) ||
|
||||||
|
(current_time - m_last_recalibration_time >= RECALIBRATION_COOLDOWN_MS);
|
||||||
|
|
||||||
|
if(!cooldown_ok)
|
||||||
|
{
|
||||||
|
unsigned long time_remaining = RECALIBRATION_COOLDOWN_MS - (current_time - m_last_recalibration_time);
|
||||||
|
ESP_LOGD(TAG, "Recalibration skipped - cooldown period active (%lu ms remaining)", time_remaining);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we have credentials for this index
|
||||||
|
if(failed_ssid_index < 0 || failed_ssid_index >= SETTINGS.wifi.num)
|
||||||
|
{
|
||||||
|
ESP_LOGD(TAG, "Recalibration skipped - no valid credentials");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the SSID is visible (network is up)
|
||||||
|
const char* target_ssid = SETTINGS.wifi.entry[failed_ssid_index].ssid;
|
||||||
|
if(!isSSIDVisible(target_ssid))
|
||||||
|
{
|
||||||
|
ESP_LOGD(TAG, "Recalibration skipped - SSID '%s' not visible", target_ssid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGW(TAG, "Radio recalibration needed - connection failed but SSID '%s' is visible", target_ssid);
|
||||||
|
ESP_LOGI(TAG, "Current time: %lu, Last recalibration: %lu", current_time, m_last_recalibration_time);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Wifi::isSSIDVisible(const char* ssid)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Scanning for SSID '%s' visibility...", ssid);
|
||||||
|
|
||||||
|
int num_networks = WiFi.scanNetworks(false, false, false, 500);
|
||||||
|
ESP_LOGI(TAG, "Found %d networks during visibility check", num_networks);
|
||||||
|
|
||||||
|
for(int n = 0; n < num_networks; n++)
|
||||||
|
{
|
||||||
|
if(strcmp(WiFi.SSID(n).c_str(), ssid) == 0)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "SSID '%s' found with RSSI %d dBm", ssid, WiFi.RSSI(n));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "SSID '%s' not found in scan results", ssid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Wifi::performRadioRecalibration()
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Performing WiFi radio recalibration...");
|
||||||
|
|
||||||
|
// Disconnect and stop WiFi
|
||||||
|
WiFi.disconnect();
|
||||||
|
WiFi.mode(WIFI_OFF);
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
// Erase calibration data to force fresh calibration
|
||||||
|
esp_phy_erase_cal_data_in_nvs();
|
||||||
|
|
||||||
|
// Record recalibration time
|
||||||
|
m_last_recalibration_time = millis();
|
||||||
|
|
||||||
|
ESP_LOGW(TAG, "Radio recalibration completed - WiFi will reinitialize on next connection attempt");
|
||||||
|
|
||||||
|
// Brief delay to let the radio settle
|
||||||
|
delay(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// @brief Connect to provisioned wifi
|
/// @brief Connect to provisioned wifi
|
||||||
/// @param index index of wifi in settings
|
/// @param index index of wifi in settings
|
||||||
/// @return WIFI_STATUS::CONNECTED/NOT_CONENCTED connected
|
/// @return WIFI_STATUS::CONNECTED/NOT_CONENCTED connected
|
||||||
|
// Modified connectTo method with smart recalibration
|
||||||
Wifi::WIFI_STATUS Wifi::connectTo(int index)
|
Wifi::WIFI_STATUS Wifi::connectTo(int index)
|
||||||
{
|
{
|
||||||
IPAddress local_IP(0, 0, 0, 0);
|
IPAddress local_IP(0, 0, 0, 0);
|
||||||
IPAddress gateway(0, 0, 0, 0);
|
IPAddress gateway(0, 0, 0, 0);
|
||||||
IPAddress subnet(SETTINGS.wifi.subnet_mask);
|
IPAddress subnet(SETTINGS.wifi.subnet_mask);
|
||||||
IPAddress primaryDNS(SETTINGS.wifi.dns_primary);
|
IPAddress primaryDNS(SETTINGS.wifi.dns_primary);
|
||||||
IPAddress secondaryDNS(SETTINGS.wifi.dns_secondary);
|
IPAddress secondaryDNS(SETTINGS.wifi.dns_secondary);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Connecting to %s...", SETTINGS.wifi.entry[index].ssid);
|
ESP_LOGI(TAG, "Connecting to %s...", SETTINGS.wifi.entry[index].ssid);
|
||||||
|
|
||||||
delay(1000);
|
delay(1000);
|
||||||
|
|
||||||
// set hostname
|
// set hostname
|
||||||
uint8_t mac[6];
|
uint8_t mac[6];
|
||||||
WiFi.macAddress(mac);
|
WiFi.macAddress(mac);
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
sprintf(buffer, "wellhub-tag%02x%02x%02x", mac[3], mac[4], mac[5]);
|
sprintf(buffer, "wellhub-tag%02x%02x%02x", mac[3], mac[4], mac[5]);
|
||||||
WiFi.hostname(buffer);
|
WiFi.hostname(buffer);
|
||||||
|
|
||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
|
WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
|
||||||
|
|
||||||
WiFi.begin(SETTINGS.wifi.entry[index].ssid, SETTINGS.wifi.entry[index].pwd);
|
WiFi.begin(SETTINGS.wifi.entry[index].ssid, SETTINGS.wifi.entry[index].pwd);
|
||||||
int status = WiFi.waitForConnectResult(10000);
|
int status = WiFi.waitForConnectResult(10000);
|
||||||
|
|
||||||
if(status == WL_CONNECTED)
|
if(status == WL_CONNECTED)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "Connected");
|
ESP_LOGI(TAG, "Connected");
|
||||||
return WIFI_STATUS::CONNECTED;
|
return WIFI_STATUS::CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
delay(1000);
|
delay(1000);
|
||||||
|
WiFi.disconnect();
|
||||||
WiFi.disconnect();
|
|
||||||
ESP_LOGW(TAG, "Failed to connect, status: %d", status);
|
ESP_LOGW(TAG, "Failed to connect, status: %d", status);
|
||||||
return WIFI_STATUS::NOT_CONNECTED;
|
|
||||||
|
// Check if we should recalibrate the radio
|
||||||
|
if(shouldRecalibrateRadio(index))
|
||||||
|
{
|
||||||
|
performRadioRecalibration();
|
||||||
|
|
||||||
|
// Try connecting one more time after recalibration
|
||||||
|
ESP_LOGI(TAG, "Retrying connection after recalibration...");
|
||||||
|
delay(3000); // Give radio time to reinitialize
|
||||||
|
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
|
||||||
|
WiFi.begin(SETTINGS.wifi.entry[index].ssid, SETTINGS.wifi.entry[index].pwd);
|
||||||
|
|
||||||
|
status = WiFi.waitForConnectResult(10000);
|
||||||
|
if(status == WL_CONNECTED)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Connected after recalibration!");
|
||||||
|
return WIFI_STATUS::CONNECTED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Still failed after recalibration, status: %d", status);
|
||||||
|
WiFi.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return WIFI_STATUS::NOT_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Wifi::start()
|
int Wifi::start()
|
||||||
@ -147,44 +303,46 @@ Wifi::WIFI_STATUS Wifi::waitForConnection()
|
|||||||
|
|
||||||
/// @brief Connect to default fallback wifi network
|
/// @brief Connect to default fallback wifi network
|
||||||
/// @return WIFI_STATUS::CONNECTED/NOT_CONNECTED
|
/// @return WIFI_STATUS::CONNECTED/NOT_CONNECTED
|
||||||
|
// Also modify startConnecting to handle recalibration for fallback network
|
||||||
Wifi::WIFI_STATUS Wifi::connectToDefault()
|
Wifi::WIFI_STATUS Wifi::connectToDefault()
|
||||||
{
|
{
|
||||||
const char* default_ssid = "CBX_IoT";
|
const char* default_ssid = "CBX_IoT";
|
||||||
const char* default_password = "69696969";
|
const char* default_password = "69696969";
|
||||||
|
|
||||||
IPAddress local_IP(0, 0, 0, 0);
|
IPAddress local_IP(0, 0, 0, 0);
|
||||||
IPAddress gateway(0, 0, 0, 0);
|
IPAddress gateway(0, 0, 0, 0);
|
||||||
IPAddress subnet(SETTINGS.wifi.subnet_mask);
|
IPAddress subnet(SETTINGS.wifi.subnet_mask);
|
||||||
IPAddress primaryDNS(SETTINGS.wifi.dns_primary);
|
IPAddress primaryDNS(SETTINGS.wifi.dns_primary);
|
||||||
IPAddress secondaryDNS(SETTINGS.wifi.dns_secondary);
|
IPAddress secondaryDNS(SETTINGS.wifi.dns_secondary);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Connecting to default network %s...", default_ssid);
|
ESP_LOGI(TAG, "Connecting to default network %s...", default_ssid);
|
||||||
|
|
||||||
delay(1000);
|
delay(1000);
|
||||||
|
|
||||||
// set hostname
|
// set hostname
|
||||||
uint8_t mac[6];
|
uint8_t mac[6];
|
||||||
WiFi.macAddress(mac);
|
WiFi.macAddress(mac);
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
sprintf(buffer, "wellhub-tag%02x%02x%02x", mac[3], mac[4], mac[5]);
|
sprintf(buffer, "wellhub-tag%02x%02x%02x", mac[3], mac[4], mac[5]);
|
||||||
WiFi.hostname(buffer);
|
WiFi.hostname(buffer);
|
||||||
|
|
||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
|
WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
|
||||||
|
|
||||||
WiFi.begin(default_ssid, default_password);
|
WiFi.begin(default_ssid, default_password);
|
||||||
int status = WiFi.waitForConnectResult(10000);
|
int status = WiFi.waitForConnectResult(10000);
|
||||||
|
|
||||||
if(status == WL_CONNECTED)
|
if(status == WL_CONNECTED)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "Connected to default network");
|
ESP_LOGI(TAG, "Connected to default network");
|
||||||
return WIFI_STATUS::CONNECTED;
|
return WIFI_STATUS::CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
delay(1000);
|
delay(1000);
|
||||||
WiFi.disconnect();
|
WiFi.disconnect();
|
||||||
ESP_LOGW(TAG, "Failed to connect to default network, status: %d", status);
|
ESP_LOGW(TAG, "Failed to connect to default network, status: %d", status);
|
||||||
return WIFI_STATUS::NOT_CONNECTED;
|
|
||||||
|
return WIFI_STATUS::NOT_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Connects to wifi. Returns immediately if already connected.
|
/// @brief Connects to wifi. Returns immediately if already connected.
|
||||||
@ -268,15 +426,60 @@ Wifi::WIFI_STATUS Wifi::startConnecting()
|
|||||||
// Fallback: Try default WiFi network CBX_IoT
|
// Fallback: Try default WiFi network CBX_IoT
|
||||||
ESP_LOGI(TAG, "Attempting fallback connection to default network CBX_IoT...");
|
ESP_LOGI(TAG, "Attempting fallback connection to default network CBX_IoT...");
|
||||||
|
|
||||||
WIFI_STATUS fallback_status = connectToDefault();
|
WIFI_STATUS fallback_status = connectToDefault();
|
||||||
if(fallback_status == WIFI_STATUS::CONNECTED)
|
if(fallback_status == WIFI_STATUS::CONNECTED)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "Successfully connected to default network");
|
ESP_LOGI(TAG, "Successfully connected to default network");
|
||||||
return WIFI_STATUS::CONNECTED;
|
return WIFI_STATUS::CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGE(TAG, "Cannot connect to any network including default fallback");
|
// Check if we should recalibrate for the fallback network
|
||||||
return WIFI_STATUS::NOT_PROVISIONED;
|
ESP_LOGW(TAG, "Fallback connection failed, checking if recalibration needed...");
|
||||||
|
|
||||||
|
const char* default_ssid = "CBX_IoT";
|
||||||
|
if(isSSIDVisible(default_ssid))
|
||||||
|
{
|
||||||
|
unsigned long current_time = millis();
|
||||||
|
|
||||||
|
// Allow recalibration if:
|
||||||
|
// 1. Never recalibrated before (m_last_recalibration_time == 0)
|
||||||
|
// 2. Or enough time has passed since last recalibration
|
||||||
|
bool cooldown_ok = (m_last_recalibration_time == 0) ||
|
||||||
|
(current_time - m_last_recalibration_time >= RECALIBRATION_COOLDOWN_MS);
|
||||||
|
|
||||||
|
if(cooldown_ok)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Fallback network '%s' visible but connection failed - performing recalibration", default_ssid);
|
||||||
|
ESP_LOGI(TAG, "Current time: %lu, Last recalibration: %lu", current_time, m_last_recalibration_time);
|
||||||
|
|
||||||
|
performRadioRecalibration();
|
||||||
|
|
||||||
|
// Retry fallback connection after recalibration
|
||||||
|
ESP_LOGI(TAG, "Retrying fallback connection after recalibration...");
|
||||||
|
fallback_status = connectToDefault();
|
||||||
|
if(fallback_status == WIFI_STATUS::CONNECTED)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Successfully connected to fallback after recalibration!");
|
||||||
|
return WIFI_STATUS::CONNECTED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Fallback still failed after recalibration");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned long time_remaining = RECALIBRATION_COOLDOWN_MS - (current_time - m_last_recalibration_time);
|
||||||
|
ESP_LOGD(TAG, "Recalibration skipped - cooldown period active (%lu ms remaining)", time_remaining);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Fallback network not visible - network may be down");
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGE(TAG, "Cannot connect to any network including default fallback");
|
||||||
|
return WIFI_STATUS::NOT_PROVISIONED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Scans all visible ssid's and picks known ssid with highest rssi that is not ignored.
|
/// @brief Scans all visible ssid's and picks known ssid with highest rssi that is not ignored.
|
||||||
|
|||||||
16
main/Wifi.h
16
main/Wifi.h
@ -18,7 +18,8 @@ public:
|
|||||||
NOT_CONNECTED,
|
NOT_CONNECTED,
|
||||||
PENDING,
|
PENDING,
|
||||||
NOT_PROVISIONED,
|
NOT_PROVISIONED,
|
||||||
CONNECTED
|
CONNECTED,
|
||||||
|
PROVISIONING
|
||||||
} WIFI_STATUS;
|
} WIFI_STATUS;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -40,9 +41,16 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Wifi();
|
Wifi();
|
||||||
|
void startProvisioning();
|
||||||
|
void stopProvisioning();
|
||||||
|
bool isProvisioningTimedOut();
|
||||||
|
void resetProvisioningTimer();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void wifi_event(arduino_event_id_t event, arduino_event_info_t info);
|
void wifi_event(arduino_event_id_t event, arduino_event_info_t info);
|
||||||
|
unsigned long m_provision_start_time = 0;
|
||||||
|
static const unsigned long PROVISION_TIMEOUT_MS = 600000; // 10 minutes
|
||||||
|
bool m_provision_timeout = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int start();
|
int start();
|
||||||
@ -53,6 +61,12 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
WIFI_STATUS connectToDefault();
|
WIFI_STATUS connectToDefault();
|
||||||
|
unsigned long m_last_recalibration_time = 0;
|
||||||
|
static const unsigned long RECALIBRATION_COOLDOWN_MS = 3600000; // 1 hour
|
||||||
|
|
||||||
|
bool shouldRecalibrateRadio(int failed_ssid_index);
|
||||||
|
void performRadioRecalibration();
|
||||||
|
bool isSSIDVisible(const char* ssid);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __WIFI_H__ */
|
#endif /* __WIFI_H__ */
|
||||||
Loading…
x
Reference in New Issue
Block a user