//------------Сеть
  extern "C" {
  #include "esp_wifi.h"
  }
  void PauseForConnect(int timeout = 15000) {
    uint32_t startTime = millis();
    while (WiFi.status() != WL_CONNECTED && millis() - startTime < timeout) {
      Serial.print(".");
      delay(500);
    }
  }
String current_pass;
bool connectToWiFi(const char* ssid, const char* password, const char* attemptName, int timeout = 15000) {
    Serial.print(attemptName);
    Serial.println(ssid);
    //Serial.println(password);
    WiFi.disconnect(true);
    delay(1000);
    WiFi.mode(WIFI_OFF);
    delay(500);
    WiFi.mode(WIFI_STA);
    WiFi.persistent(false);
    WiFi.begin(ssid, password);
    PauseForConnect(timeout);
    WiFi.persistent(true);
    Serial.println();
    if (WiFi.status() == WL_CONNECTED) current_pass = String(password);
    return (WiFi.status() == WL_CONNECTED);
}

// Максимальное количество сетей
#define MAX_NETWORKS 10

struct WiFiNetwork {
    char ssid[17];      // Максимум 32 символа для SSID
    char password[33];  // Максимум 64 символа для пароля
    int32_t rssi;
    bool configured;
    bool available;
};

// Динамическое выделение памяти
WiFiNetwork* networks = nullptr;
int networkCount = 0;


int parseWiFiConfig() {// Функция для парсинга wifi.ini
    // Освобождаем предыдущую память
    if (networks != nullptr) {
        delete[] networks;
        networks = nullptr;
    }
    networkCount = 0;
    
    if (!LittleFS.exists("/wifi.ini")) {
        Serial.println("wifi.ini not found");
        return 0;
    }
    
    File file = LittleFS.open("/wifi.ini", "r");
    if (!file) {
        Serial.println("Failed to open wifi.ini");
        return 0;
    }
    
    // Сначала посчитаем количество сетей в файле
    int tempCount = 0;
    while (file.available()) {
        String line = file.readStringUntil('\n');
        line.trim();
        
        if (line.length() == 0 || line.startsWith("#")) {
            continue;
        }
        
        int separatorPos = line.indexOf(' ');
        if (separatorPos > 0) {
            tempCount++;
        }
    }
    
    if (tempCount == 0) {
        file.close();
        return 0;
    }
    
    // Ограничиваем максимальным количеством
    networkCount = (tempCount > MAX_NETWORKS) ? MAX_NETWORKS : tempCount;
    
    // Выделяем память только под нужное количество сетей
    networks = new WiFiNetwork[networkCount];
    if (networks == nullptr) {
        Serial.println("Failed to allocate memory for networks");
        file.close();
        networkCount = 0;
        return 0;
    }
    
    // Возвращаемся к началу файла
    file.seek(0);
    
    int index = 0;
    while (file.available() && index < networkCount) {
        String line = file.readStringUntil('\n');
        line.trim();
        
        if (line.length() == 0 || line.startsWith("#")) {
            continue;
        }
        
        int separatorPos = line.indexOf(' ');
        if (separatorPos > 0) {
            String ssidStr = line.substring(0, separatorPos);
            String passStr = line.substring(separatorPos + 1);
            
            if (ssidStr.length() > 0 && ssidStr.length() <= 32) {
                // Копируем в структуру
                ssidStr.toCharArray(networks[index].ssid, 
                                   sizeof(networks[index].ssid));
                passStr.toCharArray(networks[index].password, 
                                   sizeof(networks[index].password));
                networks[index].rssi = -1000;
                networks[index].configured = true;
                networks[index].available = false;
                
                index++;
                Serial.printf("Found network #%d: %s\n", index, ssidStr.c_str());
            }
        }
    }
    
    file.close();
    Serial.printf("Parsed %d networks from wifi.ini\n", networkCount);
    return networkCount;
}

// Функция высвобождения памяти
void freeNetworksMemory() {
    if (networks != nullptr) {
        delete[] networks;
        networks = nullptr;
    }
    networkCount = 0;
    Serial.println("WiFi networks memory freed");
}

// Функция сканирования сетей (используется только если сетей > 1)
bool scanSpecificNetworks() {
    Serial.println("Starting targeted WiFi scan...");
    
    // Сбрасываем флаги доступности
    for (int i = 0; i < networkCount; i++) {
        networks[i].available = false;
        networks[i].rssi = -1000;
    }
    
    // Для каждой сети выполняем целевое сканирование
    int foundCount = 0;
    
    for (int i = 0; i < networkCount; i++) {
        // Сканируем конкретную сеть
        int scanResult = WiFi.scanNetworks(false, false, false, 300, 0, networks[i].ssid);
        
        if (scanResult == 1) {
            // Найдена искомая сеть
            networks[i].rssi = WiFi.RSSI(0);
            networks[i].available = true;
            foundCount++;
            
            Serial.printf("✓ Found: %s (RSSI: %d dBm)\n", 
                         networks[i].ssid, networks[i].rssi);
        } else if (scanResult == 0) {
            // Сеть не найдена
            Serial.printf("✗ Not found: %s\n", networks[i].ssid);
        } else if (scanResult < 0) {
            // Ошибка сканирования
            Serial.printf("! Scan error for %s: %d\n", networks[i].ssid, scanResult);
        }
        
        // Очищаем результаты после каждого сканирования
        WiFi.scanDelete();
        
        // Небольшая пауза между сканированиями
        if (i < networkCount - 1) {
            delay(100);
        }
    }
    
    Serial.printf("Targeted scan complete. Found %d/%d networks\n", foundCount, networkCount);
    return (foundCount > 0);
}

// Простая сортировка по RSSI (используется только если сетей > 1)
void sortNetworksByRSSI() {
    // Сортировка пузырьком
    for (int i = 0; i < networkCount - 1; i++) {
        for (int j = i + 1; j < networkCount; j++) {
            // Сначала доступные сети, потом недоступные
            bool iAvailable = networks[i].available;
            bool jAvailable = networks[j].available;
            
            if ((!iAvailable && jAvailable) || 
                (iAvailable && jAvailable && networks[j].rssi > networks[i].rssi)) {
                // Меняем местами
                WiFiNetwork temp = networks[i];
                networks[i] = networks[j];
                networks[j] = temp;
            }
        }
    }
}

// Подключение к одной сети 
bool connectToSingleWiFi() {
    if (networkCount != 1 || networks == nullptr) {
        return false;
    }
    
    Serial.println("\n=== Single Network Connection ===");
    Serial.printf("Attempting to connect to: %s\n", networks[0].ssid);
    
    if (connectToWiFi(networks[0].ssid, networks[0].password, "Single network: ", 15000)) {
        Serial.printf("✓ Success! Connected to: %s\n", networks[0].ssid);
        Serial.printf("  IP Address: %s\n", WiFi.localIP().toString().c_str());
        return true;
    }
    
    Serial.printf("✗ Failed to connect to: %s\n", networks[0].ssid);
    return false;
}

// Функция подключения к лучшей сети (для 2+ сетей)
bool connectToBestWiFiMultiple() {
    if (networkCount < 2) {
        return false;
    }
    
    Serial.println("\n=== Smart WiFi Connection (Multiple Networks) ===");
    
    // Сканируем сети
    bool scanSuccess = scanSpecificNetworks();
    
    // Сортируем сети (доступные с лучшим RSSI первыми)
    sortNetworksByRSSI();
    
    // Пробуем подключиться к найденным сетям
    for (int i = 0; i < networkCount; i++) {
        if (!networks[i].available) {
            continue;
        }
        
        Serial.printf("\n[%d/%d] Connecting to: %s (RSSI: %d dBm)\n", 
                     i+1, networkCount, networks[i].ssid, networks[i].rssi);
        
        String attemptName = String("WiFi ") + String(i+1) + ": ";
        
        if (connectToWiFi(networks[i].ssid, networks[i].password, attemptName.c_str(), 15000)) {
            Serial.printf("✓ Success! Connected to: %s\n", networks[i].ssid);
            Serial.printf("  IP Address: %s\n", WiFi.localIP().toString().c_str());
            return true;
        }
        
        Serial.printf("✗ Failed to connect to: %s\n", networks[i].ssid);
        delay(2000);
    }
    
    // Если не нашли сети при сканировании, пробуем прямое подключение
    Serial.println("\nNo networks found during scan, trying direct connection...");
    
    for (int i = 0; i < networkCount; i++) {
        Serial.printf("\nDirect attempt %d/%d: %s\n", 
                     i+1, networkCount, networks[i].ssid);
        
        String attemptName = String("Direct ") + String(i+1) + ": ";
        
        if (connectToWiFi(networks[i].ssid, networks[i].password, attemptName.c_str(), 10000)) {
            Serial.printf("✓ Direct connection successful: %s\n", networks[i].ssid);
            return true;
        }
        delay(1000);
    }
    
    Serial.println("Failed to connect to any configured network");
    return false;
}

// Основная функция для использования
bool autoConnectToWiFi() {
    Serial.println("\n=== Auto WiFi Connection ===");
    
    // 1. Читаем конфигурацию
    if (parseWiFiConfig() == 0) {
        Serial.println("No networks in wifi.ini");
        return false;
    }
    
    bool connected = false;
    
    // 2. В зависимости от количества сетей выбираем стратегию
    if (networkCount == 1) {
        // Для одной сети - сразу подключаемся
        connected = connectToSingleWiFi();
    } else {
        // Для нескольких сетей - сканируем и выбираем лучшую
        connected = connectToBestWiFiMultiple();
    }
    
    // 3. Освобождаем память после использования
    freeNetworksMemory();
    
    return connected;
}

  void InitWiFi(bool wifiAP) {
    /*
      wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
      cfg.rx_ba_win = 4;                    // Было 6
      cfg.cache_tx_buf_num = 2;             // МИНИМУМ: было 8-16  
      cfg.tx_buf_type = 0;                  // 0 = только динамические буферы
      cfg.static_tx_buf_num = 0;            // 0 = нет статических буферов
      cfg.dynamic_tx_buf_num = 4;           // Минимум динамических
      cfg.wifi_task_core_id = 1;            // Фиксировать ядро
      cfg.beacon_max_len = 100;             // Уменьшить макс. длину beacon
      esp_wifi_init(&cfg);
    */
    if (!wifiAP) {// изо всех сил пытаемся подключиться к wi-fi
        WiFi.mode(WIFI_STA);
        WiFi.setSleep(WIFI_PS_NONE);
        WiFi.setHostname(host);
        WiFi.setAutoReconnect(true);
        
        bool connected = false;
        
        #if BOARD == ESP32S3
            WiFi.setTxPower(WIFI_POWER_17dBm); 
        #endif      
        
        // 1. Автоподключение из wifi.ini со сканированием
        Serial.println("Attempt 1: Auto-connect from wifi.ini");
        connected = autoConnectToWiFi();
        if (connected) {
          // В случае успешного Autoconnect запоминаем сеть в NVS, на случай если в следующий раз wifi.ini пропадет (запишется только в случае изменения)
          strlcpy(SamSetup.SavedSSID, WiFi.SSID().c_str(), sizeof(SamSetup.SavedSSID));
          strlcpy(SamSetup.SavedPASS, current_pass.c_str(), sizeof(SamSetup.SavedPASS));
          save_profile();
        }
        // 2. Стандартная попытка (последняя сохраненная)
        if (!connected) {
            Serial.println("Attempt 2: Previous WiFi connection");
            if (SamSetup.disp == 2) {
                LD.printString_6x8("Saved SSID          ", 1, 6);
            }
            WiFi.begin(); // Пробуем предыдущее подключение
            PauseForConnect(10000);
            connected = (WiFi.status() == WL_CONNECTED);
        }
        
        // 3. Попытка из NVS
        if (!connected && SamSetup.SavedSSID[0] != '\0') {
            Serial.println("Attempt 3: NVS credentials");
            if (SamSetup.disp == 2) {
                LD.printString_6x8(("NVS SSID " + String(SamSetup.SavedSSID)).c_str(), 1, 6);
            }
            
            #if BOARD == ESP32S3
                WiFi.setTxPower(WIFI_POWER_15dBm); 
            #endif
            
            connected = connectToWiFi(SamSetup.SavedSSID, SamSetup.SavedPASS, 
                                     "Connecting to NVS WiFi ");
        }
        
        // 4. Попытка с сетью по умолчанию
        if (!connected) {
            Serial.println("Attempt 4: Default network");
            if (SamSetup.disp == 2) {
                LD.printString_6x8(("Def.SSID " + String(defaultSSID)).c_str(), 1, 6); 
            }
            connected = connectToWiFi(defaultSSID, defaultPass, 
                                     "Connecting to default WiFi ");
        }
        
        if (connected) {
            // Отображение информации о подключении
            StIP = WiFi.localIP().toString();
            
            if (SamSetup.disp == 2) {
                LD.printString_6x8((StIP + "    ").c_str(), 1, 7); 
                LD.printString_6x8("R    ", 1+16*6, 7);
                LD.printString_6x8("                    ", 1, 6);
                LD.printString_6x8((WiFi.SSID()).c_str(), 1, 6);
            }
            
            if (SamSetup.disp == 1) {
                LQ.setCursor(0,1);
                LQ.print("Connected to " + WiFi.SSID());
                LQ.setCursor(0,2);
                LQ.print("IP: " + StIP);
            }
            
            Serial.println();
            Serial.print(F("Connected to ")); 
            Serial.println(WiFi.SSID());    
            Serial.print(F("IP ")); 
            Serial.println(StIP);   
        }
    }
    
    #if BOARD == ESP32S3
        WiFi.setTxPower(WIFI_POWER_19dBm); 
    #endif
    
    // Если не удалось подключиться, запускаем AP режим
    if (WiFi.status() != WL_CONNECTED) {
        Serial.println("All connection attempts failed, starting AP mode");
        WiFi.setAutoReconnect(false); 
        WiFi.mode(WIFI_AP);
        WiFi.softAP("Samovarich", WiFiAP_Pass);
        
        Serial.println();
        Serial.println(F("Started as WiFi AP"));
        Serial.print(F("Name: Samovarich, Pass: ")); 
        Serial.print(WiFiAP_Pass); 
        Serial.println(F(",IP: 192.168.4.1"));
        
        StIP = "192.168.4.1";
        if (SamSetup.disp == 2) {
            LD.printString_6x8(F("IP: 192.168.4.1     "), 1, 7);
        } 
        if (SamSetup.disp == 1) {
                LQ.setCursor(0,1);
                LQ.print("AP MODE.            ");
                LQ.setCursor(0,2);
                LQ.print("IP: 192.168.4.1     ");
            }
    } else {
        WiFi.setAutoReconnect(true); 
    }
}
  void reset_wifi() {
    WiFi.disconnect(true);
    vTaskDelay(200/portTICK_PERIOD_MS);
    //Сбрасываем сохраненные настройки WiFi и переподключаемся
    InitWiFi(false);
  }
  void InitOTA() {
    if (SamSetup.OTA) {
        //Send OTA events to the browser
        ArduinoOTA.onStart([]() {
          if (SamSetup.PwrType == UDP_Pr ) UDPStab_Stop();
          String type;
          if (ArduinoOTA.getCommand() == U_FLASH)
            type = "Sketch";
          else {  // U_SPIFFS
            type = "Filesystem";
            SPIFFS.end();
          }
          type = type + " update start";
          events.send(type.c_str(), "ota");
        });
        ArduinoOTA.onEnd([]() {
          events.send(("Update End"), "ota");
        }); 
        ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
          //char p[32];
          //sprintf(p, "Progress: %u%%\n", (progress / (total / 100)));
          events.send(".", "ota");
        }); 
        ArduinoOTA.onError([](ota_error_t error) {
          if (error == OTA_AUTH_ERROR) events.send("Auth Failed", "ota");
          else if (error == OTA_BEGIN_ERROR)
            events.send(("Begin Failed"), "ota");
          else if (error == OTA_CONNECT_ERROR)
            events.send(("Connect Failed"), "ota");
          else if (error == OTA_RECEIVE_ERROR)
            events.send(("Recieve Failed"), "ota");
          else if (error == OTA_END_ERROR)
            events.send(("End Failed"), "ota");
        });
        ArduinoOTA.setHostname(SAMOVAR_HOST);
        ArduinoOTA.begin(); DbgMsg("OTA started.",1);
    }
  }
  void InitTelegram(){
    if (SamSetup.UseTg) {
      if (WiFi.status() == WL_CONNECTED && SamSetup.tg_token[0] != 0 && SamSetup.tg_chat_id[0] != 0) {
        delay(50);
        //DbgMsg("Ping..");
        //if (Ping.ping("212.237.16.93", 1)) {
        //  delay(50);
          DbgMsg("TG send Hello..");
          http_sync_request_get(String("/bot") + String(SamSetup.tg_token) + "/sendMessage?chat_id=" + SamSetup.tg_chat_id + "&text=" + urlEncode("Самоварыч готов к работе; IP=http://" + StIP), "212.237.16.93");
        //} else Serial.println(F("Error ping 212.237.16.93."));      
      } else if (SamSetup.tg_chat_id[0] != 0) {
        Serial.println(F("Проблема с отправкой сообщений в Телеграм."));
        }
      delay(50);
    }
  }
  void InitBlynk(){
    //Blynk.disconnect();
    if (SamSetup.UseBlynk) {
    DbgMsg(F("Connecting to Blynk"),1);  
    if (SamSetup.blynkauth[0] != 0 && WiFi.status() == WL_CONNECTED) {
    if (SamSetup.BlynkUrl[0]!='/r')
      Blynk.config(SamSetup.blynkauth, SamSetup.BlynkUrl, 8080);
    else
        Blynk.config(SamSetup.blynkauth); //"blynk-cloud.com" 80
    } 
        Blynk.connect(BLYNK_TIMEOUT_MS);
      DbgMsg(F("Blynk started"),1);
    }
  }
//------------Blynk
  void pause_withdrawal(bool PauseOn);
  void set_current_power(float power);
  void set_pump_speed(float speed, bool msg);
  void set_body_temp();
  String get_Samovar_Status();
  float get_speed_from_rate(float rate, uint16_t s_per_l);

  #include <BlynkSimpleEsp32.h>
    String run_lua_string(String lstr);
    WidgetTerminal terminal(V22);

    BLYNK_WRITE(V22) {
      String lstr = param.asStr();  // assigning incoming value from pin V22 to a variable
      terminal.println(lstr);
      lstr = run_lua_string(lstr);
      if (lstr.length() > 0) {
        terminal.println("ERR in lua: " + lstr);
      }
      else {
        terminal.println(F("Lua run complete"));
      }
      terminal.flush();
    }
  BLYNK_READ(V0) {
    vTaskDelay(2 / portTICK_PERIOD_MS);
    Blynk.virtualWrite(V0, SteamSensor.avgTemp);
    vTaskDelay(2 / portTICK_PERIOD_MS);
    Blynk.virtualWrite(V4, PowerOn);
    int i;
    int k;
    if (startval > 0 && startval < 5)
      i = 1;
    else
      i = 0;
    Blynk.virtualWrite(V3, i);
    vTaskDelay(2 / portTICK_PERIOD_MS);
    if (PauseOn)
      k = 1;
    else
      k = 0;
    Blynk.virtualWrite(V13, k);
  }
  BLYNK_READ(V1) {
    Blynk.virtualWrite(V1, PipeSensor.avgTemp);
  }
  BLYNK_READ(V2) {
    Blynk.virtualWrite(V2, WthdrwlProgress);
  }
  BLYNK_READ(V5) {
    Blynk.virtualWrite(V5, bme_pressure);
  }
  BLYNK_READ(V6) {
    Blynk.virtualWrite(V6, WaterSensor.avgTemp);
  }
  BLYNK_READ(V7) {
    Blynk.virtualWrite(V7, TankSensor.avgTemp);
  }
  BLYNK_READ(V8) {
    Blynk.virtualWrite(V8, get_liquid_volume_by_step(stepper.getCurrent()));
  }
  BLYNK_READ(V9) {
    Blynk.virtualWrite(V9, ActualVolumePerHour);
  }
  BLYNK_READ(V10) {
    Blynk.virtualWrite(V10, WthdrwTimeS + "; " + WthdrwTimeAllS);
  }
  BLYNK_READ(V11) {
    Blynk.virtualWrite(V11, StrCrt);
  }
  BLYNK_READ(V14) {
    Blynk.virtualWrite(V14, get_Samovar_Status());
  }
  BLYNK_READ(V15) {
    Blynk.virtualWrite(V15, ipst);
  }
  BLYNK_READ(V19) {
    Blynk.virtualWrite(V19, SAMOVAR_VERSION);
  }
    BLYNK_READ(V22) {
      Blynk.virtualWrite(V22, pressure_value);
    }
  BLYNK_READ(V21) {
      if (SamSetup.PwrType != NO_POVER_REG) {
      Blynk.virtualWrite(V21, "Тек:" + (String)current_power_volt + " Цель:" + (String) + target_power_volt);
    }
  }
  BLYNK_READ(V16) {
      if (SamSetup.PwrType != NO_POVER_REG) {
      Blynk.virtualWrite(V16, target_power_volt);
    }
  }
  BLYNK_WRITE(V16) {
      if (SamSetup.PwrType != NO_POVER_REG) {
      float Value16 = param.asFloat();  // assigning incoming value from pin V16 to a variable
      set_current_power(Value16);
    }
  }
  BLYNK_WRITE(V17) {
    float Value17 = param.asFloat();  // assigning incoming value from pin V17 to a variable
    set_pump_speed(get_speed_from_rate(Value17, Samovar_Mode == SAMOVAR_NBK_MODE ? SamSetup.NBK_StepperStepMl : SamSetup.StepperStepMl), true);
  }
  BLYNK_WRITE(V18) {
    set_body_temp();
  }
  BLYNK_WRITE(V12) {
    if (!PowerOn) return;
    int State = param.asInt();
    if (State == 1) {
      if (Samovar_Mode == SAMOVAR_BEER_MODE) {
        sam_command_sync = SAMOVAR_BEER_NEXT;
      } else if (Samovar_Mode == SAMOVAR_DISTILLATION_MODE) {
        sam_command_sync = SAMOVAR_DIST_NEXT;
      } else {
        sam_command_sync = SAMOVAR_START;
      }
    }
  }
  BLYNK_WRITE(V13) {
    pause_withdrawal(!PauseOn);
    t_min = 0;
    program_Wait = false;
  }
  BLYNK_WRITE(V3) {
    int Value3 = param.asInt();  // assigning incoming value from pin V3 to a variable
    if (Value3 == 1 && PowerOn) samovar_start();
    else
      sam_command_sync = SAMOVAR_RESET;
  }
  BLYNK_WRITE(V4) {
    //int Value4 = param.asInt();  // assigning incoming value from pin V4 to a variable
    if (Samovar_Mode == SAMOVAR_BEER_MODE && !PowerOn) {
      sam_command_sync = SAMOVAR_BEER;
    } else if (Samovar_Mode == SAMOVAR_BK_MODE && !PowerOn) {
      sam_command_sync = SAMOVAR_BK;
    } else if (Samovar_Mode == SAMOVAR_NBK_MODE && !PowerOn) {
      sam_command_sync = RUN_NBK;
    } else if (Samovar_Mode == SAMOVAR_DISTILLATION_MODE && !PowerOn) {
      sam_command_sync = SAMOVAR_DISTILLATION;
    } else
      sam_command_sync = SAMOVAR_POWER;
    //set_power(Value4);
  }
//------------MQTT
  char mqttstr[100] = "SMV/\0";
  char mqttstr1[100];
  void DbgMsg(const String& Msg, bool ln);
  void SendMsg(const String& m, MESSAGE_TYPE msg_type);
  void onMqttConnect(bool sessionPresent);
  void onMqttDisconnect(AsyncMqttClientDisconnectReason reason);
  void onMqttPublish(uint16_t packetId);
  void connectToMqtt();

  void initMqtt() {
    //if (mqttClient.connected()) mqttClient.disconnect();
    if (SamSetup.UseMQTT) {
      char buf[10];
      itoa(chipId, buf, 10);
      mqttClient.onConnect(onMqttConnect);
      mqttClient.onDisconnect(onMqttDisconnect);
      mqttClient.onPublish(onMqttPublish);
      mqttClient.setClientId(buf);
      //mqttClient.setClientId("1234");
      mqttClient.setMaxTopicLength(PAYLOADSIZE);
      mqttClient.setCredentials(SamSetup.MQTT_User, SamSetup.MQTT_Pass);
      mqttClient.setServer(SamSetup.MQTT_Serv, SamSetup.MQTT_Port);
      strcat(mqttstr, SamSetup.blynkauth);
      strcat(mqttstr, "/");

      if (strlen(SamSetup.blynkauth) < 30) send_mqtt = false; else send_mqtt = true;

      //  mqttClient.onSubscribe(onMqttSubscribe);
      //  mqttClient.onUnsubscribe(onMqttUnsubscribe);
      //  mqttClient.onMessage(onMqttMessage);

      connectToMqtt();
      vTaskDelay(500);
    }
  }
  void connectToMqtt() {
    DbgMsg("Connecting to MQTT...",1);
    //  uint8_t i;
    //  i = 0;
    mqttClient.connect();
    //  while (!mqttClient.connected()){
    //    delay(50);
    //    i++;
    //    if (i > 25) break;
    //  }
  }
  void onMqttConnect(bool sessionPresent) {
  DbgMsg("MQQT connected.",1);
  }
  void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
  DbgMsg("Disconnected from MQTT: " + String(static_cast<std::underlying_type<AsyncMqttClientDisconnectReason>::type>(reason)),1);
  }
  void onMqttPublish(uint16_t packetId) {
    //  Serial.println("Publish acknowledged.");
    //  Serial.print("  packetId: ");
    //  Serial.println(packetId);
  }
  void MqttSendMsg(const String &Str, const char *chart ) {
    if (!send_mqtt) return;
    strcpy(mqttstr1, mqttstr);
    strcat(mqttstr1, chart);
    static char payload[PAYLOADSIZE];

    //Версия сообщения
    strcat(mqttstr1, "/3");
    Str.toCharArray(payload, PAYLOADSIZE);
    uint16_t packetIdPub1 = mqttClient.publish(mqttstr1, 2, true, payload);
    if (packetIdPub1 == 0) {
      if (!mqttClient.connected()){
        mqttClient.connect();
      }
      packetIdPub1 = mqttClient.publish(mqttstr1, 2, true, payload);
    }
  }
//
