WiFiManager Invalid auth token

tzapu WiFiManager with blynk token

esp-01 (Invalid auth token) after reboot

my code

    #define BLYNK_PRINT Serial
    #include <ESP8266WiFi.h>
    #include <BlynkSimpleEsp8266.h>
    #include <ESP8266WebServer.h>
    #include <DNSServer.h>
    #include <WiFiManager.h>

    char blynk_token[33];

    void configModeCallback (WiFiManager *myWiFiManager) {
    }

    void setup()
    {
        Serial.begin(115200);
        WiFiManagerParameter custom_blynk_token("Blynk", "blynk token", blynk_token, 33);
        WiFiManager wifi;
        wifi.addParameter(&custom_blynk_token);
        wifi.autoConnect("Blynk");
        Blynk.config(custom_blynk_token.getValue());
    }

    void loop()
    {
      Blynk.run();

    }

serial logs

⸮*WM: Adding parameter
*WM: Blynk
*WM:
*WM: AutoConnect
*WM: Connecting as wifi client...
*WM: Using last saved values, should be faster
*WM: Connection result:
*WM: 0
*WM: SET AP STA
*WM:
*WM: Configuring access point...
*WM: Blynk
*WM: AP IP address:
*WM: 192.168.4.1
*WM: HTTP server started
*WM: Handle root
*WM: Handle root
*WM: Request redirected to captive portal
*WM: Request redirected to captive portal
*WM: Handle root
*WM: Request redirected to captive portal
*WM: Handle root
*WM: Request redirected to captive portal
*WM: Handle root
*WM: Request redirected to captive portal
*WM: Handle root
*WM: Handle root
*WM: Handle root
*WM: Handle root
*WM: Scan done
*WM: Pro-Syrian.com
*WM: -51
*WM: DemirT
*WM: -78
*WM: Sent config page
*WM: Request redirected to captive portal
*WM: Handle root
*WM: Request redirected to captive portal
*WM: Request redirected to captive portal
*WM: Request redirected to captive portal
*WM: WiFi save
*WM: Parameter
*WM: Blynk
*WM: de745e5d128647da853bb17127106bf7
*WM: Sent wifi save page
*WM: Connecting to new AP
*WM: Connecting as wifi client...
*WM: Connection result:
*WM: 3
[213913]
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ / '/
///_, /////_
/__/ v0.5.2 on ESP8266

[213915] Connecting to blynk-cloud.com:80
[214073] Ready (ping: 1ms).



serial logs
after reboot



> *WM: Blynk
> *WM:
> *WM: AutoConnect
> *WM: Connecting as wifi client...
> *WM: Using last saved values, should be faster
> *WM: Connection result:
> *WM: 3
> *WM: IP Address:
> *WM: 192.168.1.102
> [3680]
> ___ __ __
> / _ )/ /_ _____ / /__
> / _ / / // / _ / '/
> ///_, /////_
> /__/ v0.5.2 on ESP8266
> 
> [3687] Connecting to blynk-cloud.com:80
> [3831] Invalid auth token
> [8831] Connecting to blynk-cloud.com:80
> [8973] Invalid auth token
> [13974] Connecting to blynk-cloud.com:80
> [14113] Invalid auth token
> [19114] Connecting to blynk-cloud.com:80
> [19251] Invalid auth token
> [24252] Connecting to blynk-cloud.com:80
> [24390] Invalid auth token
> [29391] Connecting to blynk-cloud.com:80
> [29717] Invalid auth token
> [34718] Connecting to blynk-cloud.com:80
> [35149] Invalid auth token
> [40150] Connecting to blynk-cloud.com:80
> [40287] Invalid auth token
> [45288] Connecting to blynk-cloud.com:80
> [45424] Invalid auth token

Your posted code and serial output was not properly formatted… makes it hard to read… thus no one will bother :wink:

I fixed it for you… but read here to see how for the future.

Blynk - FTFC

Meens you are using an Invalid Auth Token… :stuck_out_tongue_winking_eye: Fix it :smile:

Make sure you are not adding any extra spaces or invisible characters from strange copy paste routines, etc.

Thank you sir
This error occurs only after rebooting

You can read the code again

And something appears to be changing (invalidating) that Auth when that happens

No thanks, I am good… I don’t use WiFiManager so the intrisities of how/why it works is lost on me anyhow :stuck_out_tongue:

@AbuJarrah I had the same problem and realised there was an extra space after the token id when I had pasted the token in the browser field. Once you paste the token, make sure it has just the 32 characters needed.

1 Like

The first time connects but after reboot this error appears

Is this exactly what happened to you?

[213915] Connecting to blynk-cloud.com:80
[214073] Ready (ping: 1ms).

serial logs
after reboot

> [3687] Connecting to blynk-cloud.com:80
> [3831] Invalid auth token

@AbuJarrah No. I did not have this issue. Once connected, it always reconnected without any issues.

Try writing the token to serial monitor and see if it is the same token it is trying to reconnect with as you had input. settings.token would be the variable, I think.

This happens while working on esp-01

When working with esp9266-12E it works without problems
Maybe it is the hardware that is causing the problem

It is connected to the Internet but auth token either is not stored or stored in the wrong way

@AbuJarrah I used ESP8266-12E and not ESP-01

This happens while working on esp-01

When working with esp9266-12E it works without problems
Maybe it is the hardware that is causing the problem

It is connected to the Internet but auth token either is not stored or stored in the wrong way

Do you know that you are responsible for saving the given parameter? I don’t see where you save the token in your code… and after save it… you must get the token from the place you save it for use it…

After reset if you didn’t save it… It will crash!

Maybe it’s this little detail that is causing you to fail or Blynk.config do that? (to save the value i mean) I think that no… So you need to use something like eeprom or a sd to save and retrieve the token…

The SSID and the password are saved into esp flash memory using AT comands internally

Sorry i deleted my post by a mistake and repost it with more information… check it one more time…

If you decided to use an SD here is an example:

To read the value…

#include <SD.h>
#define INIFileName "CONFIG"
#define PinSD 10
void Write_INI_Value(String INIFile,String KeyPath,String Key,String Value)
{
  String FullPath="/"+INIFile+"/"+KeyPath+"/";
  SD.mkdir(FullPath);
  File MyINI=SD.open(FullPath+Key+".txt",O_CREAT|O_TRUNC|O_WRITE);
  MyINI.println(Value);
  MyINI.flush();
  MyINI.close();
}
String Read_INI_Value(String INIFile,String KeyPath,String Key,String DefaultValue="UNKNOWN_KEY",bool CreateIfNotExists=false)
{
  String Value=DefaultValue;
  String FullPath="/"+INIFile+"/"+KeyPath+"/";
  File MyINI=SD.open(FullPath+Key+".txt",FILE_READ);
  if (MyINI)
  {
    Value="";
    while (MyINI.available()) Value+=(char) MyINI.read();
    MyINI.close();
  }
  else if (CreateIfNotExists) Write_INI_Value(INIFile,KeyPath,Key,Value);
  return Value;
}
void setup()
{
  Serial.begin(115200);
  Serial.println(F("Loading from SD"));
  if (!SD.begin(PinSD))
  {
    Serial.println(F("SD ERROR"));
    while(true);
  }
  else
  {
    String token=Read_INI_Value(INIFileName,"BLYNK","TOKEN");
    Serial.print("TOKEN: ");
    Serial.println(token);
  }
}
void loop()
{
  
}

To write the value:

#include <SD.h>
#define INIFileName "CONFIG"
#define PinSD 10
void Write_INI_Value(String INIFile,String KeyPath,String Key,String Value)
{
  String FullPath="/"+INIFile+"/"+KeyPath+"/";
  SD.mkdir(FullPath);
  File MyINI=SD.open(FullPath+Key+".txt",O_CREAT|O_TRUNC|O_WRITE);
  MyINI.println(Value);
  MyINI.flush();
  MyINI.close();
}
String Read_INI_Value(String INIFile,String KeyPath,String Key,String DefaultValue="UNKNOWN_KEY",bool CreateIfNotExists=false)
{
  String Value=DefaultValue;
  String FullPath="/"+INIFile+"/"+KeyPath+"/";
  File MyINI=SD.open(FullPath+Key+".txt",FILE_READ);
  if (MyINI)
  {
    Value="";
    while (MyINI.available()) Value+=(char) MyINI.read();
    MyINI.close();
  }
  else if (CreateIfNotExists) Write_INI_Value(INIFile,KeyPath,Key,Value);
  return Value;
}
void setup()
{
  Serial.begin(115200);
  Serial.println(F("Loading from SD"));
  if (!SD.begin(PinSD))
  {
    Serial.println(F("SD ERROR"));
    while(true);
  }
}
void loop()
{
//... after get the value...
    Write_INI_Value(INIFile,"BLYNK","TOKEN",Value);
}

Can you share your code Thank you

Just change WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 32);

To WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 34);

It “eats” the last digit of you token if use 32.

@ldb yes. The token has 32 characters and needs space for a null character I think at the end. The variable itself is defined as char[33] for that reason.

Didn’t read his initial code sorry… But had the same problem with tzapu example.

I tried a lot of codes but I encountered a lot of mistakes. Is there anyone who has tried this? Can anyone share their own code?
SmartSelectImage_2018-06-13-17-14-45
What is the file config.json
what is its contents
I need to raise it to esp8266-01
Or it can be created automatically

@AbuJarrah Have you tried the example programs? They work well. Have you registered the device with the blynk server and obtained the token? That token has to be pasted here without any padding or additions. All the config files are created automatically by WiFiManager.

Here is code that I use regularly.

#include <FS.h>                   //this needs to be first, or it all crashes and burns...

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager
#include <EEPROM.h>
#include <TimeLib.h>
#include <time.h> 
//#include <WidgetRTC.h>

//define colours needed
#define BLYNK_GREEN     "#23C48E"
#define BLYNK_BLUE      "#04C0F8"
#define BLYNK_YELLOW    "#ED9D00"
#define BLYNK_RED       "#D3435C"
#define BLYNK_DARK_BLUE "#5F7CD8"
#define PURPLE          "#800080"
#define BLUE_VIOLET     "#8A2BE2"
#define BROWN           "#A52A2A"
#define DARK_CYAN       "#008B8B"
#define DARK_MAGENTA    "#8B008B"
#define DARK_ORCHID     "#9932CC"
#define FUCHSIA         "#FF00FF"
#define MAROON          "#800000"
#define TEAL            "#008080"


/******************* Begin general declarations Section *******/
char auth[] = "yourtoken";
char firmware_ver_date[] = "NodeMCU1.0 ESP8266 Prodn v2.0.1 dtd 17 Feb 2018 ";
char device_type[] = "Device: Wifi 4 switch SSRD";

/******************* end general declarations Section *******/

/***************** Begin Terminal declarations Section **********/
// Attach virtual serial terminal to Virtual Pin V9. Common for
// 4 and 8 switch versions
WidgetTerminal terminal(V9);
char termtxt[12]=" ";
char prevcmd[12]=" ";

/****************** end Terminal declarations Section ***********/

/*************** Begin Timer/RTC declarations Section *******/
BlynkTimer timer;
//WidgetRTC rtc;
char Date[16];
char Time[16];
long startsecondswd;            //  start time in seconds
long stopsecondswd;             //  stop  time in seconds
long nowseconds;                // time now in seconds

int IsFirstConnect=1;
long FirstConnectTime;
String firstconnect_ts;
char time_stamp[80];
struct tm * ts;
time_t rawtime;
char dayname[4];
char monthname[4];
long uptime_secs=millis()/1000;
String last_check_time;
String current_check_time;

/* Vn_Sxhour/min. n is relay number. x is T for start and P for stop */
int  V1_SThour, V1_STmin, V1_SPhour, V1_SPmin;
int  V2_SThour, V2_STmin, V2_SPhour, V2_SPmin;
int  V3_SThour, V3_STmin, V3_SPhour, V3_SPmin;
int  V4_SThour, V4_STmin, V4_SPhour, V4_SPmin;

void requestTime() {
  Blynk.sendInternal("rtc", "sync");
}

BLYNK_WRITE(InternalPinRTC) {
  long t = param.asLong();
  setTime(t);
  Serial.print("\nUnix time: ");
  Serial.print(t);
  Serial.println();
  rawtime=t;
  char daystr[3]="";
  char timestr[6]="";
  char yearstr[5] = "";
  
  if (IsFirstConnect) 
  {
    FirstConnectTime=t;
    IsFirstConnect=0;
    Serial.print("First Connect: ");
    Serial.print(t);
    Serial.print(" :: ");
/* Needs <time.h> to be included. Can give out formatted time.*/
    ts = localtime ( &rawtime );
    strftime (time_stamp,80,"%a %I:%M %p %d %b %G %Z.",ts);
    Serial.println(time_stamp);
    firstconnect_ts=time_stamp;
  }
}

/*Routine to check schedules and act accordingly */
// call with timer every 30 seconds
void schedule_check() {
  rawtime=now();
  ts = localtime ( &rawtime );
  strftime (time_stamp,80,"%a %I:%M %p %d %b %G %Z.",ts);

  //check all starts  
  if ((hour() == V1_SThour) && (minute() == V1_STmin) && !(last_check_time == time_stamp)) {
    digitalWrite(14,1);
    Blynk.virtualWrite(V1,1);   
    Serial.println(time_stamp);
    Serial.println("Switch 1 started by timer"); 
    terminal.println(time_stamp);
    terminal.println("Switch 1 started by timer"); 
    terminal.flush();
  }
  
  if ((hour() == V2_SThour) && (minute() == V2_STmin) && !(last_check_time == time_stamp)) {
    digitalWrite(12,1);
    Blynk.virtualWrite(V2,1);    
    Serial.println(time_stamp);
    Serial.println("Switch 2 started by timer"); 
    terminal.println(time_stamp);
    terminal.println("Switch 2 started by timer");
    terminal.flush();
  }

  if ((hour() == V3_SThour) && (minute() == V3_STmin) && !(last_check_time == time_stamp)) {
    digitalWrite(4,1);
    Blynk.virtualWrite(V3,1); 
    Serial.println(time_stamp);
    Serial.println("Switch 3 started by timer"); 
    terminal.println(time_stamp);
    terminal.println("Switch 3 started by timer");
    terminal.flush();
  }

  if ((hour() == V4_SThour) && (minute() == V4_STmin) && !(last_check_time == time_stamp)) {
    digitalWrite(13,1);
    Blynk.virtualWrite(V4,1); 
    Serial.println(time_stamp);
    Serial.println("Switch 4 started by timer"); 
    terminal.println(time_stamp);
    terminal.println("Switch 4 started by timer");
    terminal.flush();
  }
  
  //check all stops
  if ((hour() == V1_SPhour) && (minute() == V1_SPmin) && !(last_check_time == time_stamp)) {
    digitalWrite(14,0);
    Blynk.virtualWrite(V1,0); 
    Serial.println(time_stamp);
    Serial.println("Switch 1 stopped by timer"); 
    terminal.println(time_stamp);
    terminal.println("Switch 1 stopped by timer");
    terminal.flush();
  }

  if ((hour() == V2_SPhour) && (minute() == V2_SPmin) && !(last_check_time == time_stamp)) {
    digitalWrite(12,0);
    Blynk.virtualWrite(V2,0);  
    Serial.println(time_stamp);
    Serial.println("Switch 2 stopped by timer"); 
    terminal.println(time_stamp);
    terminal.println("Switch 2 stopped by timer");
    terminal.flush();
  }

    if ((hour() == V3_SPhour) && (minute() == V3_SPmin) && !(last_check_time == time_stamp)) {
    digitalWrite(4,0);
    Blynk.virtualWrite(V3,0);    
    Serial.println(time_stamp);
    Serial.println("Switch 3 stopped by timer"); 
    terminal.println(time_stamp);
    terminal.println("Switch 3 stopped by timer");
    terminal.flush();
  }

  if ((hour() == V4_SPhour) && (minute() == V4_SPmin) && !(last_check_time == time_stamp)) {
    digitalWrite(13,0);
    Blynk.virtualWrite(V4,0);  
    Serial.println(time_stamp);
    Serial.println("Switch 4 stopped by timer"); 
    terminal.println(time_stamp);
    terminal.println("Switch 4 stopped by timer");
    terminal.flush();
  }
  last_check_time=time_stamp;
}

/**************** end Timer/RTC declarations Section ********/


/***************** Begin WiFi declarations Section **********/
WiFiManager wifiManager;
WiFiClient wifiClient;

/****************** end WiFi declarations Section ***********/

/********************** Begin EEPROM Section *****************/
#define EEPROM_SALT 12664
typedef struct {
  int   salt = EEPROM_SALT;
  char  blynkToken[33]  = "yourtoken";
  char  blynkServer[33] = "blynk-cloud.com";
  char  blynkPort[6]    = "8442";
} WMSettings;

WMSettings settings;

void eeprom_read()
{
  Serial.print("Values before reading EEPROM\n");
  Serial.print(settings.salt);
  Serial.print("::");
  Serial.print(settings.blynkToken);
  Serial.print("::");
  Serial.print(settings.blynkServer);
  Serial.print("::");
  Serial.print(settings.blynkPort);
  Serial.print("\n");

  //custom params
  EEPROM.begin(512);
  EEPROM.get(0, settings);
  EEPROM.end();

  Serial.print("Values after reading EEPROM\n");
  Serial.print(settings.salt);
  Serial.print("::");
  Serial.print(settings.blynkToken);
  Serial.print("::");
  Serial.print(settings.blynkServer);
  Serial.print("::");
  Serial.print(settings.blynkPort);
  Serial.print("\n");
  Serial.println(settings.blynkToken);
  Serial.println(settings.blynkServer);
  Serial.println(settings.blynkPort);
}

void eeprom_saveconfig()
{
    //save the custom parameters to FS
    Serial.println("Saving config to EEPROM");

    Serial.println(settings.blynkToken);
    Serial.println(settings.blynkServer);
    Serial.println(settings.blynkPort);

    EEPROM.begin(512);
    EEPROM.put(0, settings);
    EEPROM.commit();
    EEPROM.end();
}

/********************** end EEPROM Section *****************/


/********************** Begin LED Section *****************/
int BlynkLED=LED_BUILTIN;
int wifiLED=2;
int BlynkLEDstate=HIGH;
int wifiLEDstate=HIGH;

void wifiLEDoff()
  {
   digitalWrite(wifiLED, HIGH);
  }

void wifiLEDon()
  {
   digitalWrite(wifiLED, LOW);
  }

void BlynkLEDoff()
  {
   digitalWrite(BlynkLED, HIGH);
  }

void BlynkLEDon()
  {
   digitalWrite(BlynkLED, LOW);
  }

void BlynkLEDtoggle()
{
  digitalWrite(BlynkLED, !BlynkLEDstate);
  BlynkLEDstate=!BlynkLEDstate;
}

void wifiLEDtoggle()
{
  digitalWrite(wifiLED, !wifiLEDstate);
  wifiLEDstate=!wifiLEDstate;
}

/********************** end LED Section *****************/


/***************************************************************************************
BUTTONS HANDLING SECTION:
Map virtual pins to actual GPIOs. Helps abstract across boards to a common interface 
V0 is for all relays to turn on/off                                                      
Vn is for nth relay to turn on/off                                              
***************************************************************************************/

BLYNK_WRITE(V0)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V0 to a variable 
  Serial.print("\nV0 is set to ");
  Serial.println(pinValue);  
  if (pinValue) 
  {   
   digitalWrite(14, HIGH); 
   digitalWrite(4, HIGH);
   digitalWrite(12, HIGH); 
   digitalWrite(13, HIGH); 
  }
  else
  {
    digitalWrite(14, LOW); 
    digitalWrite(4, LOW);
    digitalWrite(12, LOW); 
    digitalWrite(13, LOW); 
  }
   Blynk.virtualWrite(V1, pinValue);
   Blynk.virtualWrite(V2, pinValue);
   Blynk.virtualWrite(V3, pinValue);
   Blynk.virtualWrite(V4, pinValue);
} 

BLYNK_WRITE(V1)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable 
  digitalWrite(14, pinValue); // GPIO2
  Serial.print("\nV1 is set to ");
  Serial.println(pinValue);
}

BLYNK_WRITE(V2)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V2 to a variable 
  digitalWrite(12, pinValue); // GPIO2
  Serial.print("\nV2 is set to ");
  Serial.println(pinValue);
}

BLYNK_WRITE(V3)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V3 to a variable 
  digitalWrite(4, pinValue);
  Serial.print("\nV3 is set to ");
  Serial.println(pinValue);
}

BLYNK_WRITE(V4)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V4 to a variable 
  digitalWrite(13, pinValue); 
  Serial.print("\nV4 is set to ");
  Serial.println(pinValue);
}

/***************************************************************************************
TIMER BUTTONS HANDLING SECTION:
V1n is for nth relay to turn on/off by timer imput
***************************************************************************************/

BLYNK_WRITE(V11)
{
  TimeInputParam t(param);
  V1_SThour = t.getStartHour();
  V1_STmin = t.getStartMinute();
  V1_SPhour = t.getStopHour();
  V1_SPmin = t.getStopMinute();
  Serial.print(hour());
  Serial.print(":");
  Serial.print(minute());
  Serial.print(" :: ");
  Serial.print("\nRelay 1 turn on @");
  Serial.print(V1_SThour);
  Serial.print(":");
  Serial.print(V1_STmin);
  Serial.print(" and off @");
  Serial.print(V1_SPhour);
  Serial.print(":");
  Serial.println(V1_SPmin); 
}

BLYNK_WRITE(V12)
{
  TimeInputParam t(param);
  V2_SThour = t.getStartHour();
  V2_STmin = t.getStartMinute();
  V2_SPhour = t.getStopHour();
  V2_SPmin = t.getStopMinute();
  Serial.print(hour());
  Serial.print(":");
  Serial.print(minute());
  Serial.print(" :: ");
  Serial.print("\nRelay 2 turn on @");
  Serial.print(V2_SThour);
  Serial.print(":");
  Serial.print(V2_STmin);
  Serial.print(" and off @");
  Serial.print(V2_SPhour);
  Serial.print(":");
  Serial.println(V2_SPmin); 
}

BLYNK_WRITE(V13)
{
  TimeInputParam t(param);
  V3_SThour = t.getStartHour();
  V3_STmin = t.getStartMinute();
  V3_SPhour = t.getStopHour();
  V3_SPmin = t.getStopMinute();
  Serial.print(hour());
  Serial.print(":");
  Serial.print(minute());
  Serial.print(" :: ");
  Serial.print("\nRelay 3 turn on @");
  Serial.print(V3_SThour);
  Serial.print(":");
  Serial.print(V3_STmin);
  Serial.print(" and off @");
  Serial.print(V3_SPhour);
  Serial.print(":");
  Serial.println(V3_SPmin); 
}

BLYNK_WRITE(V14)
{
  TimeInputParam t(param);
  V4_SThour = t.getStartHour();
  V4_STmin = t.getStartMinute();
  V4_SPhour = t.getStopHour();
  V4_SPmin = t.getStopMinute();
  Serial.print(hour());
  Serial.print(":");
  Serial.print(minute());
  Serial.print(" :: ");
  Serial.print("\nRelay 4 turn on @");
  Serial.print(V4_SThour);
  Serial.print(":");
  Serial.print(V4_STmin);
  Serial.print(" and off @");
  Serial.print(V4_SPhour);
  Serial.print(":");
  Serial.println(V4_SPmin); 
}

/*********************************************************************************
CONNECTION SECTION:
Has both Wifi and Blynk server connection segments
**********************************************************************************/
//WiFi connection segment
void configModeCallback (WiFiManager *myWiFiManager) {
  Serial.println("Entered config mode");
  Serial.println(WiFi.softAPIP());
  String ssid = "Mo4W-" + String(ESP.getChipId());
  Serial.print("\nSet up device as passwordless AP called "); 
  Serial.println(ssid);
  Serial.print("Blue LED next to ESP8266 will be lit in this phase");
  Serial.print("\nTurns off once configured WiFi connection is successfully established\n");

  //Serial.println(myWiFiManager->getConfigPortalSSID());
}

// This function tries to connect to the Blynk cloud using TCP if not connected
void connectBlynk()
{
  wifiClient.stop();
  //All LEDs off in this routine
  wifiLEDoff();
  BlynkLEDoff();
  if(!Blynk.connected() )
  {
    Serial.print("\nReconnecting to Blynk server");
    BlynkLEDoff();
    wifiClient.connect(settings.blynkServer, atoi(settings.blynkPort));
  }
  else
  {
    wifiLEDoff();
    BlynkLEDon();
  }
}

BLYNK_CONNECTED() {
  // Request the latest state from the server
  Serial.print("\nConnected to server");
  Blynk.syncVirtual(V1, V2, V3, V4, V11, V12, V13, V14);
  Serial.print("\nSyncAll done");
  wifiLEDoff();
  BlynkLEDon();
  requestTime();
  
  //Clear terminal
  terminal.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nReady");
  terminal.flush();

  Blynk.setProperty(V4, "color", FUCHSIA);
}

/**************************************************************************************
TERMINAL INTERACTION SECTION
Attached to Virtual Pin V9
Commands supported are help, info, time, upime, wifi, ver, ip, name, reboot, erase
**************************************************************************************/

BLYNK_WRITE(V9)
{
  int j=0;

  //convert keyed in text to lower case
  strcpy(termtxt,param.asStr());
  for(int i = 0; termtxt[i]; i++){
  termtxt[i] = tolower(termtxt[i]);
  }
  Serial.println(termtxt);

  if (String("help") == termtxt) {
         terminal.println("\nCommands are not case sensitive");
         terminal.println("Supported commands: help, info, time, uptime, wifi, ip, name, ver");
         j=1;
         strcpy(prevcmd,termtxt);
         terminal.flush();
    }
  if (String("info") == termtxt)  {
         terminal.print(device_type);
         terminal.println();
         j=1;
         strcpy(prevcmd,termtxt);
         terminal.flush();
    }
  if (String("time") == termtxt)  {
         terminal.print("\nTime: ");
         rawtime=now();
         ts = localtime ( &rawtime );
         strftime (time_stamp,80,"%a %I:%M %p %d %b %G %Z.",ts);
         terminal.println(time_stamp);
         Serial.println(time_stamp);
         j=1;
         strcpy(prevcmd,termtxt);
         terminal.flush();
    }
  if (String("uptime") == termtxt)  {
         int x, days, hours, minutes, months = 0;
         x=(millis()/1000);
         Serial.println(x);
         days = x / 60 / 60 / 24;
         hours = (x / 60 / 60) % 24;
         minutes = (x / 60) % 60;
         terminal.print("\nUp since ");
         terminal.println(firstconnect_ts);
         terminal.flush();
         terminal.print("Uptime: " );
         terminal.print(days);
         terminal.print("d:");
         terminal.print(hours);
         terminal.print("h:");
         terminal.print(minutes);
         terminal.println("m");
         j=1;
         strcpy(prevcmd,termtxt);
         terminal.flush();
    }
  if (String("wifi") == termtxt) {
         terminal.print("\nSSID: ");
         terminal.println(WiFi.SSID());
         j=1;
         strcpy(prevcmd,termtxt);
         terminal.flush();
    }
  if (String("ip") == termtxt) {
         terminal.print("\nName: ");
         terminal.println(WiFi.hostname());
         terminal.print("Device ip: ");
         terminal.println(WiFi.localIP());
         j=1;
         strcpy(prevcmd,termtxt);
         terminal.flush();         
    }
  if (String("name") == termtxt)  {
         terminal.print("\nName: ");
         terminal.println(WiFi.hostname());
         j=1;
         strcpy(prevcmd,termtxt);
         terminal.flush(); 
    } 
  if (String("clear") == termtxt)  {
         for (int i = 0; i <= 50; i++) 
          {
            terminal.println("");     // "clear screen" in app.
          }
         j=1;
         strcpy(prevcmd,termtxt);
         terminal.flush(); 
    }
  if (String("reboot") == termtxt)  {
         terminal.println("\npassword:");
         j=1;
         strcpy(prevcmd,termtxt);
         terminal.flush(); 
    }
  if (String("erase") == termtxt)  {
         terminal.println("\npassword:");
         j=1;
         strcpy(prevcmd,termtxt);
         terminal.flush(); 
    }
  if ((String("mohan") == termtxt) && (String("reboot") == prevcmd))  {
         ESP.reset(); 
    } 
  if ((String("maple") == termtxt) && (String("erase") == prevcmd))  {
         wifiManager.resetSettings();
         ESP.reset(); 
    }  
  if (String("ver") == termtxt)  {
         terminal.print("\nVer: ");
         terminal.println(firmware_ver_date);
         j=1;
         strcpy(prevcmd,termtxt);
         terminal.flush();
    } else {
         if (!j) {terminal.println("\nInvalid command");
         terminal.flush();
         }
    }
   Serial.print("prevcmd: ");
   Serial.println(prevcmd); 
//exit point of BLYNK_WRITE(V9) Terminal section
}

/**************************** SETUP and LOOP Sections *******************************/
void setup()
{
  // Debug console
  Serial.begin(115200);
  Serial.println();
  //set all pinmodes to output for relay control
  pinMode(14, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(16, OUTPUT);
  Serial.print("\nBooting firmware ");
  Serial.println(firmware_ver_date);
  Serial.print(device_type);
  Serial.print("\nModified by Mohan Sundaram\n");
  Serial.print("\nSetup done\n");
  wifiLEDon();
  
  //WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  //WiFiManager wifiManager;

  //Pass on to callback to denote entering webconfig portal mode
  wifiManager.setAPCallback(configModeCallback);

  //exit after config instead of connecting
  wifiManager.setBreakAfterConfig(true);

  //for testing only
  //wifiManager.resetSettings();

  eeprom_read();

  if (settings.salt != EEPROM_SALT) {
    Serial.println("Invalid settings in EEPROM, trying with defaults");
    WMSettings defaults;
    settings = defaults;
  }
  Serial.println("Settings after EEPROM SALT check");
  Serial.println(settings.blynkToken);
  Serial.println(settings.blynkServer);
  Serial.println(settings.blynkPort);

  //Set hostname for easy identification.
  String ssid = "Mo4W-" + String(ESP.getChipId());
  WiFi.hostname(ssid);
  
  
  WiFiManagerParameter custom_blynk_text("<br/><B/>Blynk configuration.");
  wifiManager.addParameter(&custom_blynk_text);

  WiFiManagerParameter custom_blynk_token("blynk-token", "blynk token", settings.blynkToken, 33);
  wifiManager.addParameter(&custom_blynk_token);

  //WiFiManagerParameter custom_blynk_server("blynk-server", "blynk server", settings.blynkServer, 33);
  //wifiManager.addParameter(&custom_blynk_server);

  //WiFiManagerParameter custom_blynk_port("blynk-port", "blynk port", settings.blynkPort, 6);
  //wifiManager.addParameter(&custom_blynk_port);

  //tries to connect to last known settings
  //if it does not connect it starts an access point with the specified name
  //here  "Mo4W-xxxxxx" with no password
  //and goes into a blocking loop awaiting configuration

  if (!wifiManager.autoConnect(ssid.c_str(), NULL)) {
    Serial.println("failed to connect, we should reset and see if it connects");
    delay(3000);
    ESP.reset();
    delay(5000);
  }

  strcpy(settings.blynkToken, custom_blynk_token.getValue());
  //strcpy(settings.blynkServer, custom_blynk_server.getValue());
  //strcpy(settings.blynkPort, custom_blynk_port.getValue());

  eeprom_saveconfig();
  wifiLEDoff();
  
  //if you get here you have connected to the WiFi
  Serial.print("connected to wifi Access Point configured....");
  Serial.print(WiFi.SSID());
  Serial.print("\nlocal ip: ");
  Serial.print(WiFi.localIP());
  Serial.print("\n");
  Blynk.config(settings.blynkToken);
  
  //check Blynk connect every 1 secnd
  timer.setInterval(1000L, connectBlynk);
  
  //check schedule every 30 seconds
  timer.setInterval(30000L, schedule_check);
  
  //Sync time every hour
  timer.setInterval(3600000L, requestTime);
}

void loop()
{
  Blynk.run();
  timer.run();
}