witnessmenow / Universal-Arduino-Telegram-Bot

Use Telegram on your Arduino (ESP8266 or Wifi-101 boards)
MIT License
1.12k stars 307 forks source link

Using WifiManager #213

Closed iPhilBln closed 3 years ago

iPhilBln commented 3 years ago

Hi dudes. We have problems with our connection if we use the WifiManager. So is it possible to use both of them in one sketch? Maybe its helpful to post our sketch.

/****************************************************************************************************************************
Autor: Philipp Mielke, Paul Eichner, Joe Fierek, Svenja Meißner
Projekt: smarter Briefkasten
Datum: 21.11.2020
*****************************************************************************************************************************/

// Use from 0 to 4. Higher number, more debugging messages and memory usage.
#define _WIFIMGR_LOGLEVEL_    3

#include <FS.h>

#include <ArduinoJson.h> 

#include <esp_wifi.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>

#include <WiFiMulti.h>
WiFiMulti wifiMulti;

  #define USE_SPIFFS      true

  #if USE_SPIFFS
    #include <SPIFFS.h>
    FS* filesystem =      &SPIFFS;
    #define FileFS        SPIFFS
    #define FS_Name       "SPIFFS"
  #else
    // Use FFat
    #include <FFat.h>
    FS* filesystem =      &FFat;
    #define FileFS        FFat
    #define FS_Name       "FFat"
  #endif

  #define ESP_getChipId()   ((uint32_t)ESP.getEfuseMac())

  #define LED_ON            HIGH
  #define LED_OFF           LOW

#define LED_BUILTIN       1         // Pin D1 mapped to pin GPIO1/ADC12 of ESP32, control on-board LED
#define PIN_LED           1         // Pin D1 mapped to pin GPIO1/ADC12 of ESP32, control on-board LED
#define REED              34        // Pin D34 mapped to reed contact
#define WifiReset         35        // Pin D35 mapped to wifi/reset button
#define RedLed            32        // Pin D32 mapped to the red led
#define GreenLed          33        // Pin D33 mapped to the green led
#define mosi              23        // Pin D23 mapped to mosi from rfid
#define rst               22        // Pin D22 mapped to reset from rfid
#define sda               21        // Pin D21 mapped to sda from rfid
#define miso              19        // Pin D19 mapped to miso from rfid
#define sck               18        // Pin D18 mapped to sck from rfid

#define PIN_D0            0         // Pin D0 mapped to pin GPIO0/BOOT/ADC11/TOUCH1 of ESP32
#define PIN_D1            1         // Pin D1 mapped to pin GPIO1/TX0 of ESP32
#define PIN_D2            2         // Pin D2 mapped to pin GPIO2/ADC12/TOUCH2 of ESP32
#define PIN_D3            3         // Pin D3 mapped to pin GPIO3/RX0 of ESP32
#define PIN_D4            4         // Pin D4 mapped to pin GPIO4/ADC10/TOUCH0 of ESP32
#define PIN_D5            5         // Pin D5 mapped to pin GPIO5/SPISS/VSPI_SS of ESP32
#define PIN_D6            6         // Pin D6 mapped to pin GPIO6/FLASH_SCK of ESP32
#define PIN_D7            7         // Pin D7 mapped to pin GPIO7/FLASH_D0 of ESP32
#define PIN_D8            8         // Pin D8 mapped to pin GPIO8/FLASH_D1 of ESP32
#define PIN_D9            9         // Pin D9 mapped to pin GPIO9/FLASH_D2 of ESP32

#define PIN_D10           10        // Pin D10 mapped to pin GPIO10/FLASH_D3 of ESP32
#define PIN_D11           11        // Pin D11 mapped to pin GPIO11/FLASH_CMD of ESP32
#define PIN_D12           12        // Pin D12 mapped to pin GPIO12/HSPI_MISO/ADC15/TOUCH5/TDI of ESP32
#define PIN_D13           13        // Pin D13 mapped to pin GPIO13/HSPI_MOSI/ADC14/TOUCH4/TCK of ESP32
#define PIN_D14           14        // Pin D14 mapped to pin GPIO14/HSPI_SCK/ADC16/TOUCH6/TMS of ESP32
#define PIN_D15           15        // Pin D15 mapped to pin GPIO15/HSPI_SS/ADC13/TOUCH3/TDO of ESP32
#define PIN_D16           16        // Pin D16 mapped to pin GPIO16/TX2 of ESP32
#define PIN_D17           17        // Pin D17 mapped to pin GPIO17/RX2 of ESP32     
#define PIN_D18           18        // Pin D18 mapped to pin GPIO18/VSPI_SCK of ESP32
#define PIN_D19           19        // Pin D19 mapped to pin GPIO19/VSPI_MISO of ESP32

#define PIN_D21           21        // Pin D21 mapped to pin GPIO21/SDA of ESP32
#define PIN_D22           22        // Pin D22 mapped to pin GPIO22/SCL of ESP32
#define PIN_D23           23        // Pin D23 mapped to pin GPIO23/VSPI_MOSI of ESP32
#define PIN_D24           24        // Pin D24 mapped to pin GPIO24 of ESP32
#define PIN_D25           25        // Pin D25 mapped to pin GPIO25/ADC18/DAC1 of ESP32
#define PIN_D26           26        // Pin D26 mapped to pin GPIO26/ADC19/DAC2 of ESP32
#define PIN_D27           27        // Pin D27 mapped to pin GPIO27/ADC17/TOUCH7 of ESP32     

#define PIN_D32           32        // Pin D32 mapped to pin GPIO32/ADC4/TOUCH9 of ESP32
#define PIN_D33           33        // Pin D33 mapped to pin GPIO33/ADC5/TOUCH8 of ESP32
#define PIN_D34           34        // Pin D34 mapped to pin GPIO34/ADC6 of ESP32

//Only GPIO pin < 34 can be used as output. Pins >= 34 can be only inputs
//See .../cores/esp32/esp32-hal-gpio.h/c
//#define digitalPinIsValid(pin)          ((pin) < 40 && esp32_gpioMux[(pin)].reg)
//#define digitalPinCanOutput(pin)        ((pin) < 34 && esp32_gpioMux[(pin)].reg)
//#define digitalPinToRtcPin(pin)         (((pin) < 40)?esp32_gpioMux[(pin)].rtc:-1)
//#define digitalPinToAnalogChannel(pin)  (((pin) < 40)?esp32_gpioMux[(pin)].adc:-1)
//#define digitalPinToTouchChannel(pin)   (((pin) < 40)?esp32_gpioMux[(pin)].touch:-1)
//#define digitalPinToDacChannel(pin)     (((pin) == 25)?0:((pin) == 26)?1:-1)

#define PIN_D35           35        // Pin D35 mapped to pin GPIO35/ADC7 of ESP32
#define PIN_D36           36        // Pin D36 mapped to pin GPIO36/ADC0/SVP of ESP32
#define PIN_D39           39        // Pin D39 mapped to pin GPIO39/ADC3/SVN of ESP32

#define PIN_RX0            3        // Pin RX0 mapped to pin GPIO3/RX0 of ESP32
#define PIN_TX0            1        // Pin TX0 mapped to pin GPIO1/TX0 of ESP32

#define PIN_SCL           22        // Pin SCL mapped to pin GPIO22/SCL of ESP32
#define PIN_SDA           21        // Pin SDA mapped to pin GPIO21/SDA of ESP32   

/* Trigger for inititating config mode is Pin D3 and also flash button on NodeMCU
   Flash button is convenient to use but if it is pressed it will stuff up the serial port device driver
   until the computer is rebooted on windows machines.
*/
const int TRIGGER_PIN   = PIN_D0;     // Pin D0 mapped to pin GPIO0/BOOT/ADC11/TOUCH1 of ESP32

const char* CONFIG_FILE = "/ConfigSW.json";

// Variables

#define SSID_MAX_LENGTH           32
#define PASSWORD_MAX_LENGTH       32

// Default Config Portal SID and Password
// SSID and PW for Config Portal

String DefaultPortalSSID = "Briefkasten"; //"ESP_" + String(ESP_getChipId(), HEX);
char PortalSSID[SSID_MAX_LENGTH + 1] = "Briefkasten Setup Portal";

// Use in case PortalSSID or PortalPassword is invalid (NULL)
String DefaultPortalPassword = "My" + DefaultPortalSSID;
char PortalPassword[PASSWORD_MAX_LENGTH + 1] = "Briefkastenfirma";

#define PortalSSID_Label       "PortalSSID"
#define PortalPassword_Label   "PortalPassword"

// SSID and PW for your Router
String Router_SSID;
String Router_Pass;

// From v1.1.0
// You only need to format the filesystem once
//#define FORMAT_FILESYSTEM       true
#define FORMAT_FILESYSTEM         false

#define MIN_AP_PASSWORD_SIZE    4

#define SSID_MAX_LEN            32
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
#define PASS_MAX_LEN            64

typedef struct
{
  char wifi_ssid[SSID_MAX_LEN];
  char wifi_pw  [PASS_MAX_LEN];
}  WiFi_Credentials;

typedef struct
{
  String wifi_ssid;
  String wifi_pw;
}  WiFi_Credentials_String;

#define NUM_WIFI_CREDENTIALS      2

typedef struct
{
  WiFi_Credentials  WiFi_Creds [NUM_WIFI_CREDENTIALS];
} WM_Config;

WM_Config         WM_config;

#define  CONFIG_FILENAME              F("/wifi_cred.dat")
//////

// Indicates whether ESP has WiFi credentials saved from previous session
bool initialConfig = false;

// Use false if you don't like to display Available Pages in Information Page of Config Portal
// Comment out or use true to display Available Pages in Information Page of Config Portal
// Must be placed before #include <ESP_WiFiManager.h>
#define USE_AVAILABLE_PAGES     true

// From v1.0.10 to permit disable/enable StaticIP configuration in Config Portal from sketch. Valid only if DHCP is used.
// You'll loose the feature of dynamically changing from DHCP to static IP, or vice versa
// You have to explicitly specify false to disable the feature.
//#define USE_STATIC_IP_CONFIG_IN_CP          false

// Use false to disable NTP config. Advisable when using Cellphone, Tablet to access Config Portal.
// See Issue 23: On Android phone ConfigPortal is unresponsive (https://github.com/khoih-prog/ESP_WiFiManager/issues/23)
#define USE_ESP_WIFIMANAGER_NTP     true

// Use true to enable CloudFlare NTP service. System can hang if you don't have Internet access while accessing CloudFlare
// See Issue #21: CloudFlare link in the default portal (https://github.com/khoih-prog/ESP_WiFiManager/issues/21)
#define USE_CLOUDFLARE_NTP          true

// New in v1.0.11
#define USING_CORS_FEATURE          true
//////

// Use USE_DHCP_IP == true for dynamic DHCP IP, false to use static IP which you have to change accordingly to your network
#if (defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP)
  // Force DHCP to be true
  #if defined(USE_DHCP_IP)
    #undef USE_DHCP_IP
  #endif
  #define USE_DHCP_IP     true
#else
  // You can select DHCP or Static IP here
  //#define USE_DHCP_IP     true
  #define USE_DHCP_IP     false
#endif

#if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) )
  // Use DHCP
  #warning Using DHCP IP
  IPAddress stationIP   = IPAddress(0, 0, 0, 0);
  IPAddress gatewayIP   = IPAddress(192, 168, 2, 1);
  IPAddress netMask     = IPAddress(255, 255, 255, 0);
#else
  // Use static IP
  #warning Using static IP
  #ifdef ESP32
    IPAddress stationIP   = IPAddress(192, 168, 2, 232);
  #else
    IPAddress stationIP   = IPAddress(192, 168, 2, 186);
  #endif

  IPAddress gatewayIP   = IPAddress(192, 168, 2, 1);
  IPAddress netMask     = IPAddress(255, 255, 255, 0);
#endif

#define USE_CONFIGURABLE_DNS      true

IPAddress dns1IP      = gatewayIP;
IPAddress dns2IP      = IPAddress(8, 8, 8, 8);

#include <ESP_WiFiManager.h>              //https://github.com/khoih-prog/ESP_WiFiManager

// Function Prototypes
uint8_t connectMultiWiFi(void);
bool    readConfigFile(void);
bool    writeConfigFile(void);

void heartBeatPrint(void)
{
  static int num = 1;

  if (WiFi.status() == WL_CONNECTED)
    Serial.print("\nYour are connected to your local WIFI!");        // H means connected to WiFi
  else
    Serial.print("Something went wrong!");        // F means not connected to WiFi

  if (num == 80)
  {
    Serial.println();
    num = 1;
  }
  else if (num++ % 10 == 0)
  {
    Serial.print(" ");
  }
}

void check_WiFi(void)
{
  if ( (WiFi.status() != WL_CONNECTED) )
  {
    Serial.println("\nWiFi lost. Call connect MultiWiFi in loop\n");
    connectMultiWiFi();
  }
}  

void check_status(void)
{
  static ulong checkstatus_timeout  = 0;
  static ulong checkwifi_timeout    = 0;

  static ulong current_millis;

#define WIFICHECK_INTERVAL    1000L
#define HEARTBEAT_INTERVAL    10000L

  current_millis = millis();

  // Check WiFi every WIFICHECK_INTERVAL (1) seconds.
  if ((current_millis > checkwifi_timeout) || (checkwifi_timeout == 0))
  {
    check_WiFi();
    checkwifi_timeout = current_millis + WIFICHECK_INTERVAL;
  }

  // Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
  if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
  {
    heartBeatPrint();
    checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
  }
}

void loadConfigData(void)
{
  File file = FileFS.open(CONFIG_FILENAME, "r");
  LOGERROR(F("LoadWiFiCfgFile "));

  if (file)
  {
    file.readBytes((char *) &WM_config, sizeof(WM_config));
    file.close();
    LOGERROR(F("OK"));
  }
  else
  {
    LOGERROR(F("failed"));
  }
}

void saveConfigData(void)
{
  File file = FileFS.open(CONFIG_FILENAME, "w");
  LOGERROR(F("SaveWiFiCfgFile "));

  if (file)
  {
    file.write((uint8_t*) &WM_config, sizeof(WM_config));
    file.close();
    LOGERROR(F("OK"));
  }
  else
  {
    LOGERROR(F("failed"));
  }
}

uint8_t connectMultiWiFi(void)
{
//#if ESP32
  // For ESP32, this better be 0 to shorten the connect time
  #define WIFI_MULTI_1ST_CONNECT_WAITING_MS       0

#define WIFI_MULTI_CONNECT_WAITING_MS           10L

  uint8_t status;

  LOGERROR(F("ConnectMultiWiFi with :"));

  if ( (Router_SSID != "") && (Router_Pass != "") )
  {
    LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
  }

  for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++)
  {
    // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8)
    if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) )
    {
      LOGERROR3(F("* Additional SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw );
    }
  }

  LOGERROR(F("Connecting MultiWifi..."));

  WiFi.mode(WIFI_STA);

#if !USE_DHCP_IP    
  #if USE_CONFIGURABLE_DNS  
    // Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
    WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);  
  #else
    // Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
    WiFi.config(stationIP, gatewayIP, netMask);
  #endif 
#endif

  int i = 0;
  status = wifiMulti.run();
  delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);

  while ( ( i++ < 10 ) && ( status != WL_CONNECTED ) )
  {
    status = wifiMulti.run();

    if ( status == WL_CONNECTED )
      break;
    else
      delay(WIFI_MULTI_CONNECT_WAITING_MS);
  }

  if ( status == WL_CONNECTED )
  {
    LOGERROR1(F("WiFi connected after time: "), i);
    LOGERROR3(F("SSID:"), WiFi.SSID(), F(",RSSI="), WiFi.RSSI());
    LOGERROR3(F("Channel:"), WiFi.channel(), F(",IP address:"), WiFi.localIP() );
  }
  else
    LOGERROR(F("WiFi not connected"));

  return status;
}

bool readConfigFile()
{
  // this opens the config file in read-mode
  File f = FileFS.open(CONFIG_FILE, "r");

  if (!f)
  {
    Serial.println("Configuration file not found");
    return false;
  }
  else
  {
    // we could open the file
    size_t size = f.size();
    // Allocate a buffer to store contents of the file.
    std::unique_ptr<char[]> buf(new char[size + 1]);

    // Read and store file contents in buf
    f.readBytes(buf.get(), size);
    // Closing file
    f.close();
    // Using dynamic JSON buffer which is not the recommended memory model, but anyway
    // See https://github.com/bblanchon/ArduinoJson/wiki/Memory%20model

#if (ARDUINOJSON_VERSION_MAJOR >= 6)
    DynamicJsonDocument json(1024);
    auto deserializeError = deserializeJson(json, buf.get());
    if ( deserializeError )
    {
      Serial.println("JSON parseObject() failed");
      return false;
    }
    serializeJson(json, Serial);
#else
    DynamicJsonBuffer jsonBuffer;
    // Parse JSON string
    JsonObject& json = jsonBuffer.parseObject(buf.get());
    // Test if parsing succeeds.
    if (!json.success())
    {
      Serial.println("JSON parseObject() failed");
      return false;
    }
    json.printTo(Serial);
#endif

    // Parse all config file parameters, override
    // local config variables with parsed values
    if (json.containsKey(PortalSSID_Label))
    {
      strcpy(PortalSSID, json[PortalSSID_Label]);
    }

    if (json.containsKey(PortalPassword_Label))
    {
      strcpy(PortalPassword, json[PortalPassword_Label]);
    }
  }
  Serial.println("\nConfig file was successfully parsed");
  return true;
}

bool writeConfigFile()
{
  Serial.println("Saving config file");

#if (ARDUINOJSON_VERSION_MAJOR >= 6)
  DynamicJsonDocument json(1024);
#else
  DynamicJsonBuffer jsonBuffer;
  JsonObject& json = jsonBuffer.createObject();
#endif

  // JSONify local configuration parameters
  json[PortalSSID_Label]      = PortalSSID;
  json[PortalPassword_Label]  = PortalPassword;

  // Open file for writing
  File f = FileFS.open(CONFIG_FILE, "w");

  if (!f)
  {
    Serial.println("Failed to open config file for writing");
    return false;
  }

#if (ARDUINOJSON_VERSION_MAJOR >= 6)
  serializeJsonPretty(json, Serial);
  // Write data to file and close it
  serializeJson(json, f);
#else
  json.prettyPrintTo(Serial);
  // Write data to file and close it
  json.printTo(f);
#endif

  f.close();

  Serial.println("\nConfig file was successfully saved");
  return true;
}

// Telegram BOT Token (Get from Botfather)
#define BOT_TOKEN "*********************************"

// Use @myidbot (IDBot) to find out the chat ID of an individual or a group
// Also note that you need to click "start" on a bot before it can
// message you
#define CHAT_ID "******************" 

WiFiClientSecure secured_client;
UniversalTelegramBot bot(BOT_TOKEN, secured_client);

unsigned long timerNachrichtStart = 0;  // die Zeit, zu der die Verzögerung begann
bool timerNachrichtLaeuft = false;      // true, wenn noch auf die Verzögerung gewartet wird

unsigned long timerWifiStart = 0;
bool timerWifiLaeuft = false;
int i;

// Setup function
void setup()
{
  // Put your setup code here, to run once
  Serial.begin(115200);
  while (!Serial);

  Serial.print("\nStarting Briefkasten Wifi Setup using " + String(FS_Name));
  Serial.println(" on " + String(ARDUINO_BOARD));

  // Initialize the LED digital pin as an output.
  pinMode(PIN_LED, OUTPUT);
  // Initialize trigger pins
  pinMode(TRIGGER_PIN, INPUT_PULLUP);
  pinMode(WifiReset, INPUT);
  pinMode(REED, INPUT);
  pinMode(RedLed, OUTPUT);
  pinMode(GreenLed, OUTPUT);

  digitalWrite(RedLed, HIGH);

  // Mount the filesystem
  if (FORMAT_FILESYSTEM)
  {
    Serial.println(F("Forced Formatting."));
    FileFS.format();
  }

  // Format FileFS if not yet
#ifdef ESP32
  if (!FileFS.begin(true))
#else
  if (!FileFS.begin())
#endif  
  {
    Serial.print(FS_Name);
    Serial.println(F(" failed! AutoFormatting."));

  }

  if (!readConfigFile())
  {
    Serial.println("Failed to read configuration file, using default values");
  }

  unsigned long startedAt = millis();

  //Local intialization. Once its business is done, there is no need to keep it around
  // Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
  //ESP_WiFiManager ESP_wifiManager;
  // Use this to personalize DHCP hostname (RFC952 conformed)
  ESP_WiFiManager ESP_wifiManager("Briefkasten WiFi Setup");

  ESP_wifiManager.setDebugOutput(true);

  // Use only to erase stored WiFi Credentials
  //resetSettings();
  //ESP_wifiManager.resetSettings();

  //set custom ip for portal
  //ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255, 255, 255, 0));

  ESP_wifiManager.setMinimumSignalQuality(-1);

  // From v1.0.10 only
  // Set config portal channel, default = 1. Use 0 => random channel from 1-13
  ESP_wifiManager.setConfigPortalChannel(0);
  //////

#if !USE_DHCP_IP 
  #if USE_CONFIGURABLE_DNS  
    // Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
    ESP_wifiManager.setSTAStaticIPConfig(stationIP, gatewayIP, netMask, dns1IP, dns2IP);  
  #else
    // Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
    ESP_wifiManager.setSTAStaticIPConfig(stationIP, gatewayIP, netMask);
  #endif 
#endif 

  // New from v1.1.1
#if USING_CORS_FEATURE
  ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
#endif

  // We can't use WiFi.SSID() in ESP32 as it's only valid after connected.
  // SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
  // Have to create a new function to store in EEPROM/SPIFFS for this purpose
  Router_SSID = ESP_wifiManager.WiFi_SSID();
  Router_Pass = ESP_wifiManager.WiFi_Pass();

  //Remove this line if you do not want to see WiFi password printed
  Serial.println("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);

  // From v1.1.0, Don't permit NULL password
  if ( (Router_SSID != "") && (Router_Pass != "") )
  {
    LOGERROR3(F("* Add SSID = "), Router_SSID, F(", PW = "), Router_Pass);
    wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str());

    ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout.
    Serial.println("Got stored Credentials. Timeout 120s for Config Portal");
  }
  else
  {
    Serial.println("Open Config Portal without Timeout: No stored Credentials.");

    initialConfig = true;
  }

  // From v1.1.0, Don't permit NULL password
  if (initialConfig)
  {
    Serial.println("We haven't got any access point credentials, so get them now");

    digitalWrite(PIN_LED, LED_ON); // Turn led on as we are in configuration mode.
    digitalWrite(RedLed, HIGH);

    //it starts an access point
    //and goes into a blocking loop awaiting configuration
    // If Invalid PortalSSID or PortalPassword => use default

    bool resultConfigPortal;

    if ( (PortalSSID[0] == 0) || (PortalPassword[0] == 0) )
    {
      resultConfigPortal = ESP_wifiManager.startConfigPortal((const char *) DefaultPortalSSID.c_str(), DefaultPortalPassword.c_str());
    }
    else
    {
      resultConfigPortal = ESP_wifiManager.startConfigPortal((const char *) PortalSSID, PortalPassword);
    }

    if (resultConfigPortal)
      Serial.println("WiFi connected...yeey :)");
    else
      Serial.println("Not connected to WiFi but continuing anyway.");

    // Stored  for later usage, from v1.1.0, but clear first
    memset(&WM_config, 0, sizeof(WM_config));

    for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++)
    {
      String tempSSID = ESP_wifiManager.getSSID(i);
      String tempPW   = ESP_wifiManager.getPW(i);

      if (strlen(tempSSID.c_str()) < sizeof(WM_config.WiFi_Creds[i].wifi_ssid) - 1)
        strcpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str());
      else
        strncpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str(), sizeof(WM_config.WiFi_Creds[i].wifi_ssid) - 1);

      if (strlen(tempPW.c_str()) < sizeof(WM_config.WiFi_Creds[i].wifi_pw) - 1)
        strcpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str());
      else
        strncpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str(), sizeof(WM_config.WiFi_Creds[i].wifi_pw) - 1);  

      // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8)
      if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) )
      {
        LOGERROR3(F("* Add SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw );
        wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw);
      }
    }

    saveConfigData();
  }

  digitalWrite(PIN_LED, LED_OFF); // Turn led off as we are not in configuration mode.
  //digitalWrite(RedLed, LOW);    //turn off the red led

  startedAt = millis();

  if (!initialConfig)
  {
    // Load stored data, the addAP ready for MultiWiFi reconnection
    loadConfigData();

    for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++)
    {
      // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8)
      if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) )
      {
        LOGERROR3(F("* Add SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw );
        wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw);
      }
    }

    if ( WiFi.status() != WL_CONNECTED ) 
    {
      Serial.println("ConnectMultiWiFi in setup");

      connectMultiWiFi();
    }
  }

  Serial.print("After waiting ");
  Serial.print((float) (millis() - startedAt) / 1000L);
  Serial.print(" secs more in setup(), connection result is ");

  if (WiFi.status() == WL_CONNECTED)
  {
    Serial.print("connected. Local IP: ");
    Serial.println(WiFi.localIP());
  }
  else
    Serial.println(ESP_wifiManager.getStatus(WiFi.status()));

  secured_client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // Add root certificate for api.telegram.org

  bot.sendMessage(CHAT_ID, "Bot started up", "");

  pinMode(REED, INPUT);
}

// Loop function

void loop()
{
    if(digitalRead(REED) == LOW && !timerNachrichtLaeuft)
  {
    timerNachrichtStart = millis();    // start delay
    timerNachrichtLaeuft = true;
    bot.sendMessage(CHAT_ID, "Sie haben Post!", "");
    Serial.print("Post\n");    
  } 

  // Überprüfen Sie, ob die Verzögerung abgelaufen ist
  if(timerNachrichtLaeuft && ((millis () - timerNachrichtStart) >= 30000)) 
  {
    timerNachrichtLaeuft = false; 
  }

  i = 0;
  digitalWrite(RedLed, LOW);
  digitalWrite(GreenLed, HIGH);
  timerWifiLaeuft = false;

  while(WiFi.status() != WL_CONNECTED)
  {
      digitalWrite(GreenLed, LOW);

      if(!timerWifiLaeuft)
      {
        digitalWrite(RedLed, !digitalRead(RedLed));
        timerWifiStart = millis();
        timerWifiLaeuft = true;    
      } 

      if(timerWifiLaeuft && ((millis() - timerWifiStart) >= 2000))
      {
        timerWifiLaeuft = false;
        Serial.print(timerWifiStart/1000L);
        Serial.print("Wifi is not connected.\n");
      }

      wifiMulti.run();

      // is configuration portal requested?
      if ((digitalRead(TRIGGER_PIN) == LOW) || (digitalRead(WifiReset) == HIGH))
      {
        Serial.println("\nConfiguration portal requested.");
        digitalWrite(PIN_LED, LED_ON); // turn the LED on by making the voltage LOW to tell us we are in configuration mode.
        digitalWrite(RedLed, HIGH);

        //Local intialization. Once its business is done, there is no need to keep it around
        ESP_WiFiManager ESP_wifiManager("Briefkasten WiFi Setup");

        //Check if there is stored WiFi router/password credentials.
        //If not found, device will remain in configuration mode until switched off via webserver.
        Serial.print("Opening configuration portal. ");

        Router_SSID = ESP_wifiManager.WiFi_SSID();
        Router_Pass = ESP_wifiManager.WiFi_Pass();

        // From v1.1.0, Don't permit NULL password
        if ( (Router_SSID != "") && (Router_Pass != "") )
        {
          ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout.
          Serial.println("Got stored Credentials. Timeout 120s");
        }
        else
          Serial.println("No stored Credentials. No timeout");

        // Extra parameters to be configured
        // After connecting, parameter.getValue() will get you the configured value
        // Format: <ID> <Placeholder text> <default value> <length> <custom HTML> <label placement>

        // Config Portal SSID - this is a straight forward string parameter
        ESP_WMParameter p_PortalSSID(PortalSSID_Label, "Portal_SSID", PortalSSID, SSID_MAX_LENGTH + 1);

        // Config Portal SSID - this is a straight forward string parameter
        ESP_WMParameter p_PortalPassword(PortalPassword_Label, "Portal_Password", PortalPassword, PASSWORD_MAX_LENGTH + 1);

        //add all parameters here
        ESP_wifiManager.addParameter(&p_PortalSSID);
        ESP_wifiManager.addParameter(&p_PortalPassword);

        // Sets timeout in seconds until configuration portal gets turned off.
        // If not specified device will remain in configuration mode until
        // switched off via webserver or device is restarted.
        //ESP_wifiManager.setConfigPortalTimeout(120);

        ESP_wifiManager.setMinimumSignalQuality(-1);

        // From v1.0.10 only
        // Set config portal channel, default = 1. Use 0 => random channel from 1-13
        ESP_wifiManager.setConfigPortalChannel(0);
        //////

        //set custom ip for portal
        //ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255, 255, 255, 0));

    #if !USE_DHCP_IP    
      #if USE_CONFIGURABLE_DNS  
        // Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
        ESP_wifiManager.setSTAStaticIPConfig(stationIP, gatewayIP, netMask, dns1IP, dns2IP);  
      #else
        // Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
        ESP_wifiManager.setSTAStaticIPConfig(stationIP, gatewayIP, netMask);
      #endif 
    #endif  

        // Start an access point and goes into a blocking loop awaiting configuration.
        // Once the user leaves the portal with the exit button
        // processing will continue

        static bool resultConfigPortal;
        if ( (PortalSSID[0] == 0) || (PortalPassword[0] == 0) )
        {
          resultConfigPortal = ESP_wifiManager.startConfigPortal((const char *) DefaultPortalSSID.c_str(), DefaultPortalPassword.c_str());
        }
        else
        {
          resultConfigPortal = ESP_wifiManager.startConfigPortal((const char *) PortalSSID, PortalPassword);
        }

        if (resultConfigPortal)
        {
          Serial.println("WiFi connected...yeey :)");
          Serial.print("Local IP: ");
          Serial.println(WiFi.localIP());
        }
        else
          Serial.println("Not connected to WiFi but continuing anyway.");

        // Only clear then save data if CP entered and with new valid Credentials
        // No CP => stored getSSID() = ""
        if ( String(ESP_wifiManager.getSSID(0)) != "" && String(ESP_wifiManager.getSSID(1)) != "" )
        {
          // Stored  for later usage, from v1.1.0, but clear first
          memset(&WM_config, 0, sizeof(WM_config));

          for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++)
          {
            String tempSSID = ESP_wifiManager.getSSID(i);
            String tempPW   = ESP_wifiManager.getPW(i);

            if (strlen(tempSSID.c_str()) < sizeof(WM_config.WiFi_Creds[i].wifi_ssid) - 1)
              strcpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str());
            else
              strncpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str(), sizeof(WM_config.WiFi_Creds[i].wifi_ssid) - 1);

            if (strlen(tempPW.c_str()) < sizeof(WM_config.WiFi_Creds[i].wifi_pw) - 1)
              strcpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str());
            else
              strncpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str(), sizeof(WM_config.WiFi_Creds[i].wifi_pw) - 1);  

            // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8)
            if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) )
            {
              LOGERROR3(F("* Add SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw );
              wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw);
            }
          }

          saveConfigData();
        }

        // Getting posted form values and overriding local variables parameters
        // Config file is written regardless the connection state
        strcpy(PortalSSID, p_PortalSSID.getValue());
        strcpy(PortalPassword, p_PortalPassword.getValue());

        // Writing JSON config file to flash for next boot
        writeConfigFile();

        digitalWrite(PIN_LED, LED_OFF); // Turn LED off as we are not in configuration mode.
        digitalWrite(RedLed, LOW);
      }
  }
}
miguerman commented 3 years ago

I am interested in this topic. I need to use Wifimanager with Universal arduino telegram. Can someone help

Leoruiz197 commented 3 years ago

hello friends i soved this problem using ESP8266

include

include

include

include

include

//NTP server

include

include

//Telegram bot

include

include

define BOT_TOKEN "YOUR API HERE" //API KEY telegram

//lista de permissao telegram

define SENDER_ID_COUNT 2

String validSenderIds[SENDER_ID_COUNT] = {"2222222", "1111111"};

//variaveis bot telegram uint32_t lastCheckTime = 0; const String STATS = "/status"; const String STATUSID = "/statusid"; const String START = "/start";

//configs bot telegram X509List cert(TELEGRAM_CERTIFICATE_ROOT); WiFiClientSecure secured_client; UniversalTelegramBot bot(BOT_TOKEN, secured_client);

//config NTP WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, "pool.ntp.org");

//wifiManager button

define TRIGGER_PIN 0

//variavel de millis atual uint32_t now;

void setup() {

ifdef DEBUG

Serial.begin(9600);

endif

sensor.begin(); //inicializacao sensor de temperatura

//definicao botao do wifiManeger pinMode(TRIGGER_PIN, INPUT);

//definicao de cliente telegram secured_client.setTrustAnchors(&cert);

}

void loop() { now = millis(); //captura milissegundo atual

if ( digitalRead(TRIGGER_PIN) == LOW ) { //wifiManeger OnDemand WiFiManager wifiManager;

if (!wifiManager.startConfigPortal(Dispositivo_ID)){
  printSerial("failed to connect and hit timeout",1);
  delay(3000);
  ESP.reset();
  delay(5000);
}
printSerial("connected...yeey :)",1);
//secured_client.setTrustAnchors(&cert);
for(int x = 0; x<SENDER_ID_COUNT; x++){ //apos conexao avisa o status do dispositivo via telegram
  handleStatus(validSenderIds[x]);
}

}

//loop Internet connected if (WiFi.status() == WL_CONNECTED){

//verifica novas mensagens no telegram
if (now - timer > intervalo){
  timer = now;
  int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
  handleNewMessages(numNewMessages);
}

} }

iPhilBln commented 3 years ago

I am interested in this topic. I need to use Wifimanager with Universal arduino telegram. Can someone help

we also solved our problem. at first its better you use the original wifiManager from tzapu which works very well with universal telegram bot. we used the development branch of wifiManager because we use the ESP32 but there are also examples for the ESP2688. we also seperated our code in different functions and call them into the loop if we need them. we've coded them in different tabs.

here are some snippets of our code:

Main page:

/****************************************************************************************************************************
Autor: Philipp Mielke, Paul Eichner, Joe Fierek, Svenja Meißner
Projekt: smarter Briefkasten
Datum: 07.03.2021
*****************************************************************************************************************************/

//initialisiert das Dateisystem indem die nötigen Bibliotheken eingebunden werden
#include <FS.h>                   //muss als Erstes angegeben werden
#include <SPIFFS.h>
FS* filesystem =      &SPIFFS;

//nötige Bibliotheken der verschiedenen Funktionen
//#include <DNSServer.h>
//#include <WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager
#include <WiFi.h>                 //https://github.com/esp8266/Arduino
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h> //https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot
#include <ArduinoJson.h>          //https://github.com/bblanchon/ArduinoJson
#include <MFRC522.h>              //library responsible for communicating with the module RFID-RC522
#include <SPI.h>                  //library responsible for communicating of SPI bus

//hier werden die nötigen Pins definiert
#define LED_BUILTIN       1         // Pin D1 mapped to pin GPIO1/ADC12 of ESP32, control on-board LED
#define schloss           12        // Pin D12 mapped to schloss
#define REED              34        // Pin D34 mapped to reed contact
#define WifiReset         35        // Pin D35 mapped to wifi/reset button
#define RedLed            32        // Pin D32 mapped to the red led
#define GreenLed          33        // Pin D33 mapped to the green led
#define mosi              23        // Pin D23 mapped to mosi from rfid
#define rst               22        // Pin D22 mapped to reset from rfid
#define sda               21        // Pin D21 mapped to sda from rfid
#define miso              19        // Pin D19 mapped to miso from rfid
#define sck               18        // Pin D18 mapped to sck from rfi

//wird für die Authentifizierung verwendet
MFRC522::MIFARE_Key key;

//Authentifizierung die den Statuscode zurückgibt
MFRC522::StatusCode status;

//definiert die Pins für das Modul RC522
MFRC522 mfrc522(sda, rst); 

WiFiClientSecure secured_client;

//Difinition der globen Variablen auf die alle Funktionen zugreifen können
char telegram_chatID[40];
char telegram_token[70];
char schloss_notfall[5] = "nein";
int card_uid[10][4] = {0, 0, 0, 0};

bool wifi_merker = false;                   //Anzeige, dass die Wifi Verbindung verloren wurde
bool telegram_init_fertig = false;          //wird benötigt um den Telegrambot einmalig in der Loopfunktion zu Initialisieren

unsigned long timer_wifi_start = 0;         //Zeit um die rote Led zu toggeln bei Wlan Ausfall während des Betriebs
bool timer_wifi_laeuft = false;             //true wenn noch auf die Verzögerung gewartet wird

bool daten_speichern = false;               //flag um die Daten zu speichern
bool wifi_verbindung_verloren = false;      //Flag um den User zu benachrichtigen, dass die Wifi Verbindung verloren wurde

unsigned long karte_eingelesen_start = 0;   //Zeit um die grüne Led zu togglen wenn eine Karte eingelesen wurde
bool karte_eingelesen_laeuft = false;       //Flag für den Timer nachdem eine Karte erfolgreich eingelesen wurde

unsigned long beginn_oeffnung = 0;          //Zeit zu der das das Schloss aufgegangen ist
bool timer_schloss_laeuft = false;          //Flag für den Timer, dass das Schloss offen ist

unsigned long wifi_setup_start = 0;         //Zeit zu der der WifiReset Button gedrückt wurde
bool wifi_setup_laeuft = false;             //Flag, dass der WifiReset Button gedrückt wurde

bool karte_gespeichert = false;             //Flag, wenn eine Karte gespeichert wurde
bool karte_geloescht = false;               //Flag, wenn eine Karte gelöscht wurde

unsigned long timerNachrichtStart = 0;      //Startzeit wann die Post eingegangen ist
bool timerNachrichtLaeuft = false;          // true, wenn noch auf die Verzögerung gewartet wird

const uint8_t SECTOR_COUNT = 16;      
const uint8_t BYTES_PER_BLOCK = 16;  

byte success_counter = 0;                   //Zähler für RFID Funktion
byte fail_status = 0;                       //Merker für den Fall, dass bei der RFID Einlesefunktion etwas schiefgegangen ist

byte karte_fertig_eingelesen = 0;           //Flag, die gesetzt wird, wenn die Karte fertig eingelesen ist

void setup() 
{
  Serial.begin(115200);
  while (!Serial);
  SPI.begin();

  //Initialisiert die Leds als Ausgänge
  pinMode(LED_BUILTIN, OUTPUT);  
  pinMode(RedLed, OUTPUT);
  pinMode(GreenLed, OUTPUT);
  //Initialisiert das Schloss als Ausgang
  pinMode(schloss, OUTPUT);

  //Initlialisiert die Eingänge
  pinMode(WifiReset, INPUT);
  pinMode(REED, INPUT);

  //Initilialisierung des MFRC522
  mfrc522.PCD_Init();                 

  digitalWrite(GreenLed, !LOW);
  digitalWrite(RedLed, !HIGH);

  //hier können beim Bootvorgang die Wifi/Telegram/RFID Einstellungen zurückgesetzt werden
  resetEinstellungen();

  //hier wird des Wifi Setup Portal aufgerufen
  wifiSettings();

  //wenn wir hier angekommen sind, ist der ESP mit dem Wifi verbunden
  //Serial.println("local ip");
  //Serial.println(WiFi.localIP());

  digitalWrite(RedLed, !LOW);
}

void loop() {

  if(!karte_gespeichert)
    digitalWrite(GreenLed, !HIGH);
  else
    digitalWrite(GreenLed, !LOW);

  if(!karte_geloescht)
    digitalWrite(RedLed, !LOW);
  else
    digitalWrite(RedLed, !HIGH);

  //Initialisierung des Telegram Bots
  //Benachrichtigung des Benutzers, dass der Bot online ist
  if(!telegram_init_fertig)
    telegramInit();

  //wenn alle Karten verloren gegangen sein sollten, lässt sich hiermit das Schloss
  //über den Wifi AP notfalls öffnen
  if(strcmp(schloss_notfall, "ja") == 0 || strcmp(schloss_notfall, "Ja") == 0 || timer_schloss_laeuft)
    schlossOeffnen("ja");

  //bei Posteingang wird die Nachricht per Telegram übermittelt 
  //Timer wird gestartet damit nur alle 30s eine Benachrichtigung erfolgt
  posteingang();

  //hiermit kann der Briefkasten per RFID Sender geöffnet werden
  //es können neue Karten angelernt werden
  //es können alte Karten gelöscht werden
  rfid();

  //überprüft den aktuellen Verbindungsstatus
  //rote Led blinkt mit 1Hz bei verlorener Verbindung
  //ebenfalls lässt sich das Wifi Setup Portal über den Wifi Taster öffnen
  //nach 10 Minuten startet der ESP automatisch neu und öffnet den AP
  wifiCheck();

  //wenn der WifiReset Taster für 10 Sekunden gedrückt gehalten wird lässt sich
  //auch während des Betriebs das WifiSetupPortal öffnen
  wifiSetup();
}

filesystem:

//speichert die Telegram Daten, RFID Card UIDs permanent im Dateisystem
//speichert den Wert um das Schloss notfalls über den AP zu öffnen
void datenSpeichern()
{
  //Serial.println("Json Datei wird gelöscht um die Daten neu zu speichern.");
  SPIFFS.remove("/config.json");

  File konfigurationsdatei = SPIFFS.open("/config.json", "w");
  if (!konfigurationsdatei) 
  {
    //Serial.println("Es konnte nicht auf das Dateisystem geschrieben werden.");
  }

  //Serial.println("Konfigurationsdatei wird gespeichert.");

  const size_t json_speicherplatz = JSON_ARRAY_SIZE(40)+1024;
  DynamicJsonDocument json(json_speicherplatz);

  json["telegram_chatID"] = telegram_chatID;
  json["telegram_token"] = telegram_token;
  json["schloss_notfall"] = schloss_notfall;
  for(int i = 0; i < 10;i++)
  {
    for(int j = 0; j < 4; j++)
    json["Card UIDs"][i][j] = card_uid[i][j];
  }

  //serializeJson(json, Serial);
  serializeJson(json, konfigurationsdatei);

  konfigurationsdatei.close();
  json.clear();
  //Serial.println();
}

//liest die Konfigurationsdatei im json Format vom Dateisystem
void datenLesen()
{
  //Serial.println("Dateisystem wird geladen...");

  if (SPIFFS.begin()) {
    //Serial.println("Dateisystem wurde geladen.");
    if (SPIFFS.exists("/config.json")) {
      //Datei existiert, wird gelesen und geladen
      //Serial.println("Die Konfigurationsdatei wird eingelesen.");
      File konfigurationsdatei = SPIFFS.open("/config.json", "r");
      if (konfigurationsdatei) {
        //Serial.println("Konfigurationsdatei wurde geöffnet.");
        size_t size = konfigurationsdatei.size();
        //reserviert Speicher um den Eingabestrom in der Datei zu speichern
        std::unique_ptr<char[]> buf(new char[size]);

        konfigurationsdatei.readBytes(buf.get(), size);

        const size_t json_speicherplatz = JSON_ARRAY_SIZE(40)+1024;

        DynamicJsonDocument json(json_speicherplatz);
        auto deserializeError = deserializeJson(json, buf.get());
        serializeJson(json, Serial);
        if (!deserializeError ) {

          //Serial.println("\nparsed json");
          strcpy(telegram_chatID, json["telegram_chatID"]);
          strcpy(telegram_token, json["telegram_token"]);
          strcpy(schloss_notfall, json["schloss_notfall"]);
          for(int i = 0; i < 10;i++)
          {
            for(int j = 0; j < 4; j++)
            card_uid[i][j] = json["Card UIDs"][i][j];
          }
          arrayAusgeben();
        } 
        else 
        {
          //Serial.println("Die Konfigurationsdatei konnte nicht geöffnet werden.");
        }
        konfigurationsdatei.close();
      }
    }
  } else {
    //Serial.println("Das Dateisystem konnte nicht geöffnet werden.");
  }
}

wifi code:

//hiermit können sämtliche Wifi Einstellungen, Telegramdaten und RFID Chips gelöscht werden
void resetEinstellungen()
{
  //hier können beim Bootvorgang die Wifi Einstellungen zurückgesetzt werden
  if(digitalRead(WifiReset) == HIGH)
  {
    //Serial.println("Alle Einstellungen werden zurückgesetzt.");
    WiFiManager wifiManager;
    wifiManager.resetSettings();
    //Serial.println("SPIFFS löschen.");
    SPIFFS.format();
    delay(1000);
    //Serial.println("Neustart.");
    ESP.restart();
    delay(5000);
  }
}

//Callback Funktion für die eigegebenen Wifi-Daten
void saveWifiCallback(){
  //Serial.println("[CALLBACK] saveCallback fired");
}

//Aufruf für den Wifi Accespoint um die Wifi und Telegram Daten einzutragen oder das Schloss im Notfall zu öffnen
void wifiSettings()
{
  digitalWrite(GreenLed, !LOW);
  digitalWrite(RedLed, !HIGH);

  //liest die aktuellen Daten vom Dateisystem
  datenLesen();

  //Extraparameter die über das Wifi Setup Portal übergeben werden können (global oder lokal im Setup)
  //nach erfolgreicher Verbindung können die Parameter mit parameter.getValue() abgerufen werden
  // id/name placeholder/prompt default length
  WiFiManagerParameter custom_telegram_chatID("telegram_chatID", "Telegram Chat ID", telegram_chatID, 40);
  WiFiManagerParameter custom_telegram_token("telegram_token", "Telegram Token", telegram_token, 70);
  WiFiManagerParameter custom_schloss_notfall("schloss_notfall", "Notfallöffnung des Schlosses", schloss_notfall, 5);

  //WiFiManager Initialisierung 
  WiFiManager wifiManager;

  //aktiviert den DarkMode als Theme
  wifiManager.setClass("invert");

  //speichern der Einstellungen aus dem Wifimanager und Benachrichtigung
  wifiManager.setSaveConfigCallback(saveWifiCallback);
  wifiManager.setBreakAfterConfig(true);

  //verhindert Race-Conditions mit der Wifi-Verbindung und dem WiFiManager
  //löst die Verbindung auf, bevor er sich wieder mit dem Wifi verbindet
  wifiManager.setCleanConnect(true);

  //Einstellungen für eine statische IP
  wifiManager.setAPStaticIPConfig(IPAddress(10, 1, 1, 1), IPAddress(10, 1, 1, 1), IPAddress(255, 255, 255, 0));

  //Einstellung um das aktuelle Land zu setzen
  wifiManager.setCountry("US"); 

  //hinzufügen der manuellen Parameter die im Wifi Setup Portal angezeigt werden
  wifiManager.addParameter(&custom_telegram_chatID);
  wifiManager.addParameter(&custom_telegram_token);
  wifiManager.addParameter(&custom_schloss_notfall);

  //Minimum der Signalqualität der vorhandenen Wifi Netzwerke die dem User angezeigt werden
  //standardmäßig 8%
  //wifiManager.setMinimumSignalQuality();

  //aktiviert das Timeout des Wifi Setup Portals um erneut zu starten
  //in Sekunden
  wifiManager.setTimeout(120);

  //holt sich die SSID und das Passwort, um sich mit dem bekannten Netzwerk zu verbinden
  //wenn das nicht funktioniert hat, wird der Accesspoint gestart mit dem spezifischen Namen und Passwort
  //hier:  AP:"Briefkasten Wifi Setup" Passwort:"Briefkastensetup"
  //blockt den rest des Codes solange das Wifi Setup Portal geöffnet ist
  //Bedingung ist, dass das SetupPortal nicht manuel aufgerufen werden soll
  if (digitalRead(WifiReset) == LOW && !wifi_setup_laeuft && !wifiManager.autoConnect("Briefkasten WiFi Setup", "Briefkastensetup")) 
  {  
    //Serial.println("Verbindung fehlgeschlagen und die Zeit ist abgelaufen.");
    delay(3000);
    //Restart des ESPs um es erneut zu versuchen
    ESP.restart();
    delay(1000);
  }

  //hierüber kann der AP auch während des Betriebs geöffnet werden
  if(digitalRead(WifiReset) == HIGH && wifi_setup_laeuft)
  {
    wifiManager.startConfigPortal("Briefkasten WiFi Setup", "Briefkastensetup");
  }

  //jetzt ist der Briefkasten online
  //Serial.println("Der Briefkasten ist online");

  //liest die aktuellen Parameter ein
  strcpy(telegram_chatID, custom_telegram_chatID.getValue());
  strcpy(telegram_token, custom_telegram_token.getValue());
  strcpy(schloss_notfall, custom_schloss_notfall.getValue());
  //Serial.println("Folgende Daten wurden vom AP gespeichert: ");
  //Serial.println("\ttelegram_chatID : " + String(telegram_chatID));
  //Serial.println("\ttelegram_token : " + String(telegram_token));
  //Serial.println("\tschloss_notfall : " + String(schloss_notfall));

  //speichert die aktualisierten Daten im Dateisystem ab
  datenSpeichern();
}

//Funktion um die aktuelle Wifi Verbindung zu überprüfen
//der ESP wird sich automatisch innerhalb von 10 Minuten mit der gespeicherten
//Wifi Verbindung erneut verbinden
//andernfalls startet er neu und baut einen Accesspoint auf
//bei vorlerener Verbindung lässt sich über den WifiReset Button der Accesspoint aufrufen
//die rote Led blinkt mit 1Hz
void wifiCheck()
{
  timer_wifi_laeuft = false;
  int i = 0;
  unsigned long wifi_lost = millis();
  while(WiFi.status() != WL_CONNECTED)
  {
    wifi_verbindung_verloren = true;
    telegram_init_fertig = false;
    digitalWrite(GreenLed, !LOW);
    if(!timer_wifi_laeuft)
    {
      digitalWrite(RedLed, !digitalRead(RedLed));
      timer_wifi_start = millis();
      timer_wifi_laeuft = true;    
    } 

    if(timer_wifi_laeuft && ((millis() - timer_wifi_start) >= 1000))
    {
      timer_wifi_laeuft = false;
      i++;
      if(i>9)
      {
        //Serial.println();
        //Serial.print(__DATE__);
        //Serial.print(" ");
        //Serial.print(__TIME__);
        //Serial.print(": ");
        //Serial.print("Wifi Verbindung wurde verloren.");
        i = 0;
      }
    }

    if(millis() - wifi_lost >= 600000)
      ESP.restart();

    if(digitalRead(WifiReset) == HIGH)
    {
      digitalWrite(RedLed, !HIGH);
      //Serial.println("Die Wifi Einstellungen werden geöffnet.");
      wifi_verbindung_verloren = false;

      //ruft den AP auf
      wifi_setup_laeuft = true;
      wifiSettings();
      wifi_setup_laeuft = false;
    } 
  }
}

//hierüber lässt sich das WifiSetupPortal auch während des Betriebs aufrufen
//dafür muss der WifiReset Taster 10 Sekunden gedrückt gehalten werden
void wifiSetup()
{
 if(digitalRead(WifiReset) == HIGH && !wifi_setup_laeuft)
 {
  wifi_setup_start = millis();
  wifi_setup_laeuft = true;
 }

 if(digitalRead(WifiReset) == HIGH && wifi_setup_laeuft && ((millis() - wifi_setup_start) >= 10000))
 {
  wifiSettings();
  wifi_setup_laeuft = false;
 }

 if(digitalRead(WifiReset) == LOW && wifi_setup_laeuft)
 {
  wifi_setup_laeuft = false;
 }
}

telegram bot:

//Funktion um mit dem Telegrambot Nachrichten zu senden 
void telegramMessage(const char* message)
{
  UniversalTelegramBot bot(telegram_token, secured_client);
  bot.sendMessage(telegram_chatID, message, "");
}

//Initialiserung des Telegrambots bei vorhandener Wifi Verbindung
void telegramInit()
{
  int zaehler = 0;
  bool timer = false;
  unsigned long timerStart = 0;

  //es wird gewartet solange keine Wifi Verbindung hergestellt ist
  //rote Led blinkt mit 5 Hz
  while(WiFi.status() != WL_CONNECTED)
  {
    digitalWrite(GreenLed, !LOW);
    if(!timer)
    {
      digitalWrite(RedLed, !digitalRead(RedLed));
      timerStart = millis();
      timer = true;    
    } 

    if(timer && ((millis() - timerStart) >= 200))
    {
      timer = false;
      zaehler++;
      if(zaehler>45)
      {
        //Serial.println("Wifi Verbindung wurde verloren.");
        zaehler = 0;
      }
    }
  }

  //root Zertifikat für api.telegram.org wird hinzugefügt
  secured_client.setCACert(TELEGRAM_CERTIFICATE_ROOT); 

  //holt sich die UTC Zeit via NTP
  //Serial.println("Retrieving time: ");
  configTime(0, 0, "pool.ntp.org");                    
  time_t now = time(nullptr);
  while (now < 24 * 3600)
  {
    //Serial.print(".");
    delay(100);
    now = time(nullptr);
  }
  //Serial.println(now);

  //jetzt ist der Bot online
  if(!wifi_verbindung_verloren)
    telegramMessage("Der Briefkasten ist online.");
  else
  {
    telegramMessage("Der Briefkasten hat zwischenzeitlich die Internetverbindung verloren und ist jetzt wieder online.\nBitte überprüfe, ob Post angekommen ist.");
    wifi_verbindung_verloren = false;
  }
  telegram_init_fertig = true;
}

You see, after any new wifi connection we initialize the telegram bot and send our messages with this function: telegramMessage("string to send the message you want");