new WiFi async connect

This commit is contained in:
Mit4el
2025-02-15 00:20:44 +03:00
parent dccdf4af66
commit 9b620fda5e
7 changed files with 367 additions and 114 deletions

View File

@@ -200,8 +200,11 @@ void setup() {
initErrorMarker(SETUPINET_ERRORMARKER);
// подключаемся к роутеру
#ifdef ESP8266
routerConnect();
#else
WiFiUtilsItit();
#endif
// инициализация асинхронного веб сервера и веб сокетов
#ifdef ASYNC_WEB_SERVER
asyncWebServerInit();

View File

@@ -61,7 +61,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length)
//----------------------------------------------------------------------//
if (headerStr == "p|") {
standWebSocket.sendTXT(num, "p|");
Serial.printf("Ping client: %u\n", num);
//Serial.printf("Ping client: %u\n", num);
ws_clients[num]=1;
}
// публикация всех виджетов
@@ -175,7 +175,9 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length)
if (headerStr == "/scan|") {
std::vector<String> jArray;
jsonReadArray(settingsFlashJson, "routerssid", jArray);
#ifdef ESP8266
RouterFind(jArray);
#endif
sendStringToWs("ssidli", ssidListHeapJson, num);
}

View File

@@ -98,9 +98,6 @@
"usedLibs": {
"esp32*": [
"https://github.com/eModBus/eModBus"
],
"esp82*": [
"https://github.com/eModBus/eModBus"
]
}
}

View File

@@ -3,17 +3,276 @@
#if defined(ESP32)
#include <esp_task_wdt.h>
#endif
#define TRIESONE 25 // количество попыток подключения к одной сети из несколких
#define TRIES 40 // количество попыток подключения сети если она одна
/*
IPAddress stringToIp(String strIp)
#define TRIESONE 20 // количество секунд ожидания подключения к одной сети из несколких
#define TRIES 30 // количество секунд ожидания подключения сети если она одна
#ifndef ESP8266
std::vector<String> _ssidList;
std::vector<String> _passwordList;
volatile bool scanInProgress = false;
// номер сети, для перебирания в момент подключения к сетям из массива
volatile uint8_t currentNetwork = 0;
volatile bool wifiConnecting = false;
volatile uint8_t connectionAttempts = 0;
//------------------------------------------
// Обработчики событий Wi-Fi
//------------------------------------------
void WiFiEvent(arduino_event_t *event)
{
IPAddress ip;
ip.fromString(strIp);
return ip;
} */
switch (event->event_id)
{
#if defined(LIBRETINY) || defined(esp32c6_4mb) || defined(esp32c6_8mb)
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
#else
case SYSTEM_EVENT_STA_CONNECTED:
#endif
// Подключились к STA
SerialPrint("i", "WIFI", "Connected to AP: " + WiFi.SSID());
// TODO если подключились, но не получили IP что будет?
break;
#if defined(LIBRETINY) || defined(esp32c6_4mb) || defined(esp32c6_8mb)
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
#else
case SYSTEM_EVENT_STA_GOT_IP:
#endif
// Получили IP от роутера
// wifiReconnectTicker.detach();
ts.remove(WIFI_SCAN);
ts.remove(WIFI_CONN);
#ifdef LIBRETINY
SerialPrint("i", "WIFI", "http://" + ipToString(WiFi.localIP()));
jsonWriteStr(settingsFlashJson, "ip", ipToString(WiFi.localIP()));
#else
SerialPrint("i", "WIFI", "http://" + WiFi.localIP().toString());
jsonWriteStr(settingsFlashJson, "ip", WiFi.localIP().toString());
#endif
// запускаем MQTT
mqttInit();
SerialPrint("i", F("WIFI"), F("Network Init"));
// Отключаем AP при успешном подключении
WiFi.softAPdisconnect(true);
break;
#if defined(LIBRETINY) || defined(esp32c6_4mb) || defined(esp32c6_8mb)
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
#else
case SYSTEM_EVENT_STA_DISCONNECTED:
#endif
// Отключились от STA
SerialPrint("i", "WIFI", "Disconnected from STA");
// Завершаем задачу проверки сети
ts.remove(WIFI_CONN);
if (wifiConnecting)
{ // если у нас ещё не закончились попытки подключения, то перезапускаем задачу
Serial.print(".");
checkConnection();
// wifiReconnectTicker.once_ms(WIFI_CHECK_INTERVAL, checkConnection);
}
else
{ // если попытки подключения исчерпаны, то переходим в AP
startAPMode();
}
break;
#if defined(LIBRETINY) || defined(esp32c6_4mb) || defined(esp32c6_8mb)
case ARDUINO_EVENT_WIFI_SCAN_DONE:
#else
case SYSTEM_EVENT_SCAN_DONE:
#endif
// Завершилось сканирование сетей
Serial.println("Scan completed");
scanInProgress = false;
handleScanResults();
break;
}
}
//------------------------------------------
// Обработка результатов сканирования
//------------------------------------------
void handleScanResults()
{
ssidListHeapJson = "{}";
_ssidList.clear();
_passwordList.clear();
jsonReadArray(settingsFlashJson, "routerssid", _ssidList);
jsonReadArray(settingsFlashJson, "routerpass", _passwordList);
int16_t numNetworks = WiFi.scanComplete();
if (numNetworks <= 0)
{
SerialPrint("i", "WIFI", "no networks found");
return;
}
// Ищем известные сети
int connectNumNet = -1;
// SerialPrint("i", "WIFI", "Count found: "+numNetworks);
for (int n = 0; n < numNetworks; ++n)
{
String ssid = WiFi.SSID(n);
jsonWriteStr_(ssidListHeapJson, String(n), ssid);
for (size_t i = 0; i < _ssidList.size(); i++)
{
if (ssid == _ssidList[i])
{
Serial.printf("Found known network: %s\n", _ssidList[i]);
if (connectNumNet < 0)
connectNumNet = i;
}
}
// if
}
SerialPrint("i", "WIFI", "Scan Found: " + ssidListHeapJson);
if (connectNumNet >= 0)
{
// ts.remove(WIFI_SCAN);
connectToNextNetwork();
}
// checkConnection();
// connectToSTA(_ssidList[connectNumNet], _passwordList[connectNumNet]);
WiFi.scanDelete();
}
void WiFiUtilsItit()
{
#if !defined LIBRETINY
#if defined(esp32c6_4mb) || defined(esp32c6_8mb)
WiFi.setAutoReconnect(false);
#else
WiFi.setAutoConnect(false);
#endif
WiFi.persistent(false);
WiFi.setSleep(true);
#endif
WiFi.mode(WIFI_STA);
WiFi.onEvent(WiFiEvent);
jsonReadArray(settingsFlashJson, "routerssid", _ssidList);
jsonReadArray(settingsFlashJson, "routerpass", _passwordList);
if (_ssidList.empty() || _passwordList.empty())
{
SerialPrint("E", "WIFI", "No networks configured");
startAPMode();
return;
}
currentNetwork = 0;
connectionAttempts = 0;
connectToNextNetwork();
}
void connectToNextNetwork()
{
// все сети перебрали
if (currentNetwork >= _ssidList.size())
{
SerialPrint("i", "WIFI", "All networks tried");
ts.remove(WIFI_CONN);
startAPMode();
return;
}
wifiConnecting = true;
// connectionAttempts++;
const char *ssid = _ssidList[currentNetwork].c_str();
const char *pass = _passwordList[currentNetwork].c_str();
// Пробуем подключиться к сети
SerialPrint("i", "WIFI", "Connecting to: " + String(ssid));
WiFi.begin(ssid, pass);
#if defined(ESP32)
WiFi.setTxPower(WIFI_POWER_19_5dBm);
#elif defined(ESP8266)
WiFi.setOutputPower(20.5);
#endif
// проверяем статус подключения и перебираем сети если таймаут не вышел
checkConnection();
// wifiReconnectTicker.once_ms(WIFI_CHECK_INTERVAL, checkConnection);
}
void checkConnection()
{
ts.add(
WIFI_CONN, 1000,
[&](void *)
{
connectionAttempts++;
if (WiFi.status() == WL_CONNECTED)
{
connectionAttempts = 0;
wifiConnecting = false;
return;
}
if (connectionAttempts >= (_ssidList.size() > 1 ? TRIESONE : TRIES))
{
SerialPrint("i", "WIFI", "Max attempts reached");
currentNetwork++;
connectionAttempts = 0;
wifiConnecting = false;
}
if (wifiConnecting)
{
#ifdef ESP8266
if (WiFi.status() == WL_CONNECT_FAILED || WiFi.status() == WL_WRONG_PASSWORD)
#else
if (WiFi.status() == WL_CONNECT_FAILED)
#endif
{
SerialPrint("E", "WIFI", "Connection failed, wrong password?");
jsonWriteInt(errorsHeapJson, "passer", 1);
currentNetwork++;
connectionAttempts = 0;
}
// wifiReconnectTicker.once_ms(WIFI_CHECK_INTERVAL, checkConnection);
}
if (!wifiConnecting)
{
connectToNextNetwork();
}
},
nullptr, true);
}
//------------------------------------------
// Неблокирующее подключение к STA
//------------------------------------------
void connectToSTA(const char *ssid, const char *pass)
{
if (isNetworkActive())
return;
SerialPrint("i", "WIFI", "Connecting to ... " + String(ssid));
// SerialPrint("i", "WIFI", "pass connect: " + _passwordList[i]);
WiFi.begin(ssid, pass);
#if defined(ESP32)
WiFi.setTxPower(WIFI_POWER_19_5dBm);
#elif defined(ESP8266)
WiFi.setOutputPower(20.5);
#endif
}
void ScanAsync()
{
// bool res = false;
int n = WiFi.scanComplete();
SerialPrint("i", "WIFI", "scan result: " + String(n, DEC));
if (n == -1)
{ // Сканирование все еще выполняется
SerialPrint("i", "WIFI", "scanning in progress");
}
else
{
SerialPrint("i", "WIFI", "start scanning");
WiFi.scanNetworks(true, false);
}
}
#else
// ESP8266
void routerConnect()
{
#if !defined LIBRETINY
@@ -126,9 +385,14 @@ void routerConnect()
}
SerialPrint("i", F("WIFI"), F("Network Init"));
}
#endif
bool startAPMode()
{
#ifndef ESP8266
wifiConnecting = false;
currentNetwork = 0;
connectionAttempts = 0;
#endif
SerialPrint("i", "WIFI", "AP Mode");
WiFi.disconnect();
@@ -137,9 +401,9 @@ bool startAPMode()
String _ssidAP = jsonReadStr(settingsFlashJson, "apssid");
String _passwordAP = jsonReadStr(settingsFlashJson, "appass");
if (_passwordAP == "")
WiFi.softAP(_ssidAP.c_str());
WiFi.softAP(_ssidAP.c_str(), NULL, 6);
else
WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str());
WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str(), 6);
IPAddress myIP = WiFi.softAPIP();
#ifdef LIBRETINY
SerialPrint("i", "WIFI", "AP IP: " + ipToString(myIP));
@@ -154,6 +418,7 @@ bool startAPMode()
WIFI_SCAN, 30 * 1000,
[&](void *)
{
#ifdef ESP8266
std::vector<String> jArray;
jsonReadArray(settingsFlashJson, "routerssid", jArray);
for (int8_t i = 0; i < jArray.size(); i++)
@@ -166,59 +431,16 @@ bool startAPMode()
WiFi.scanDelete();
routerConnect();
}
#else
ScanAsync();
#endif
},
nullptr, true);
}
return true;
}
#if defined (LIBRETINY)
boolean RouterFind(std::vector<String> jArray)
{
bool res = false;
int n = WiFi.scanComplete();
SerialPrint("i", "WIFI", "scan result: " + String(n, DEC));
if (n == -2)
{ // Сканирование не было запущено, запускаем
SerialPrint("i", "WIFI", "start scanning");
n = WiFi.scanNetworks(false, false); // async, show_hidden
SerialPrint("i", "WIFI", "scan result: " + String(n, DEC));
}
else if (n == -1)
{ // Сканирование все еще выполняется
SerialPrint("i", "WIFI", "scanning in progress");
}
else if (n == 0)
{ // ни одна сеть не найдена
SerialPrint("i", "WIFI", "no networks found");
n = WiFi.scanNetworks(false, false);
SerialPrint("i", "WIFI", "scan result: " + String(n, DEC));
}
if (n > 0)
{
for (int8_t i = 0; i < n; i++)
{
for (int8_t k = 0; k < jArray.size(); k++)
{
if (WiFi.SSID(i) == jArray[k])
{
res = true;
}
}
// SerialPrint("i", "WIFI", (res ? "*" : "") + String(i, DEC) + ") " + WiFi.SSID(i));
jsonWriteStr_(ssidListHeapJson, String(i), WiFi.SSID(i));
// String(WiFi.RSSI(i)
}
}
SerialPrint("i", "WIFI", ssidListHeapJson);
WiFi.scanDelete();
return res;
}
#elif defined (ESP8266) || defined (ESP32)
#if defined(ESP8266)
boolean RouterFind(std::vector<String> jArray)
{
bool res = false;
@@ -264,67 +486,85 @@ boolean RouterFind(std::vector<String> jArray)
}
#endif
boolean isNetworkActive() {
return WiFi.status() == WL_CONNECTED;
boolean isNetworkActive()
{
return WiFi.status() == WL_CONNECTED;
}
uint8_t getNumAPClients() {
return WiFi.softAPgetStationNum();
uint8_t getNumAPClients()
{
return WiFi.softAPgetStationNum();
}
uint8_t RSSIquality() {
uint8_t res = 0;
if (isNetworkActive()) {
int rssi = WiFi.RSSI();
if (rssi >= -50) {
res = 6; //"Excellent";
} else if (rssi < -50 && rssi >= -60) {
res = 5; //"Very good";
} else if (rssi < -60 && rssi >= -70) {
res = 4; //"Good";
} else if (rssi < -70 && rssi >= -80) {
res = 3; //"Low";
} else if (rssi < -80 && rssi > -100) {
res = 2; //"Very low";
} else if (rssi <= -100) {
res = 1; //"No signal";
}
uint8_t RSSIquality()
{
uint8_t res = 0;
if (isNetworkActive())
{
int rssi = WiFi.RSSI();
if (rssi >= -50)
{
res = 6; //"Excellent";
}
return res;
else if (rssi < -50 && rssi >= -60)
{
res = 5; //"Very good";
}
else if (rssi < -60 && rssi >= -70)
{
res = 4; //"Good";
}
else if (rssi < -70 && rssi >= -80)
{
res = 3; //"Low";
}
else if (rssi < -80 && rssi > -100)
{
res = 2; //"Very low";
}
else if (rssi <= -100)
{
res = 1; //"No signal";
}
}
return res;
}
#ifdef LIBRETINY
String httpGetString(HTTPClient &http)
{
String payload = "";
int len = http.getSize();
uint8_t buff[128] = { 0 };
WiFiClient * stream = http.getStreamPtr();
String payload = "";
int len = http.getSize();
uint8_t buff[128] = {0};
WiFiClient *stream = http.getStreamPtr();
// read all data from server
while(http.connected() && (len > 0 || len == -1)) {
// get available data size
size_t size = stream->available();
// read all data from server
while (http.connected() && (len > 0 || len == -1))
{
// get available data size
size_t size = stream->available();
if(size) {
// read up to 128 byte
int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
if (size)
{
// read up to 128 byte
int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
// write it to Serial
// Serial.write(buff,c);
//payload += String((char*)buff);
char charBuff[c + 1]; // Create a character array with space for null terminator
memcpy(charBuff, buff, c); // Copy the data to the character array
charBuff[c] = '\0'; // Null-terminate the character array
payload += String(charBuff); // Append the character array to the payload
// write it to Serial
// Serial.write(buff,c);
if(len > 0) {
len -= c;
}
}
delay(1);
}
return payload;
// payload += String((char*)buff);
char charBuff[c + 1]; // Create a character array with space for null terminator
memcpy(charBuff, buff, c); // Copy the data to the character array
charBuff[c] = '\0'; // Null-terminate the character array
payload += String(charBuff); // Append the character array to the payload
if (len > 0)
{
len -= c;
}
}
delay(1);
}
return payload;
}
#endif