Time Inputs NewBlynk

As I prefer the old time input widget over automations and I need quite a lot automations as well, I tested the code beneath for using time inputs with Blynk. I found this code on the internet and it works well (even while I skipped a part).

However, I need some more timers, so I changed the code a bit. This worked well till 10 timers, but from timer no. 11 and above this does not work anymore, and I do not understand why. When setting up the timers this seems to work, but when the time as set up arrives nothing happens. And it does for the first 10 timers.

Am I missing something?

My code is below,

// Fill-in information from your Blynk Template here
#define BLYNK_TEMPLATE_ID "..."
#define BLYNK_TEMPLATE_NAME "...."
#define BLYNK_AUTH_TOKEN "..."

#define BLYNK_FIRMWARE_VERSION        "0.1.0"
#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG

#define APP_DEBUG

// Uncomment your board, or configure a custom board in Settings.h
//#define USE_SPARKFUN_BLYNK_BOARD
//#define USE_NODE_MCU_BOARD
//#define USE_WITTY_CLOUD_BOARD
#define USE_WEMOS_D1_MINI

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

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "...";
char pass[] = "....";

char auth[] = BLYNK_AUTH_TOKEN;
BlynkTimer timer;

// Aantal timers: pas ook onderstaande arrays aan en voeg Blynk_wrtie procedures toe bij wijzigingen!
bool led_set[11];
long timer_start_set[11] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
long timer_stop_set[11] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
unsigned char weekday_set[11];

bool led_status[11];
bool update_blynk_status[11];
bool led_timer_on_set[11];

long rtc_sec;
unsigned char day_of_week;

// #########################################################################################################


// ----- I SKIPPED THIS PART AS IT OCCURRED ALSO TO WORK WITHOUT ---------------------------------

/*
//----------------------------------------------------------------------------------------------
void UpdateSwitch (int i, int val)
{
    if ( led_timer_on_set[i] == 0 )
      led_set[i] = val;
    else
      update_blynk_status[i] = 1;
    Serial.println("");
    Serial.print("UpdateSwitch "); Serial.print(i); Serial.println(" uitgevoerd..."); 
}


//=====================================
BLYNK_WRITE(V0)   // KNOP 0
{
  int val = param.asInt();
  UpdateSwitch(0,val);

//  if ( led_timer_on_set[0] == 0 )
//    led_set[0] = val;
//  else
//    update_blynk_status[0] = 1;

}
//--------------------------------------

BLYNK_WRITE(V1)    // KNOP 1
{
  int val = param.asInt();
  UpdateSwitch(1,val);
}
//--------------------------------------
BLYNK_WRITE(V2)   // KNOP 2
{
  int val = param.asInt();
  UpdateSwitch(2,val);
}

//--------------------------------------
BLYNK_WRITE(V3)   // KNOP 3
{
  int val = param.asInt();
  UpdateSwitch(3,val);
}

//--------------------------------------
BLYNK_WRITE(V4)   // KNOP 4
{
  int val = param.asInt();
  UpdateSwitch(4,val);
}
//--------------------------------------
BLYNK_WRITE(V5)   // KNOP 5
{
  int val = param.asInt();
  UpdateSwitch(5,val);
}
//--------------------------------------
BLYNK_WRITE(V6)   // KNOP 6
{
  int val = param.asInt();
  UpdateSwitch(6,val);
}
//--------------------------------------
BLYNK_WRITE(V7)   // KNOP 7
{
  int val = param.asInt();
  UpdateSwitch(7,val);
}
//--------------------------------------
BLYNK_WRITE(V8)   // KNOP 8
{
  int val = param.asInt();
  UpdateSwitch(8,val);
}
//--------------------------------------
BLYNK_WRITE(V9)   // KNOP 9
{
  int val = param.asInt();
  UpdateSwitch(9,val);
}
//--------------------------------------
*/

// #########################################################################################################

void UpdateTimer(int i, BlynkParam param) // Instellen en weergeven nieuwe timerinstellingen
{

  unsigned char week_day;
 
  TimeInputParam t(param);
  //TimeInputParam t(TimeInput);

  Serial.println("");
  Serial.print("Nieuwe waarden voor timer no."); Serial.print(i); Serial.println(":");
    
  if (t.hasStartTime() && t.hasStopTime() ) 
  {
    timer_start_set[i] = (t.getStartHour() * 60 * 60) + (t.getStartMinute() * 60) + t.getStartSecond();
    timer_stop_set[i] = (t.getStopHour() * 60 * 60) + (t.getStopMinute() * 60) + t.getStopSecond();
    
    Serial.println(String("Start Time: ") +
                   t.getStartHour() + ":" +
                   t.getStartMinute() + ":" +
                   t.getStartSecond());
                   
    Serial.println(String("Stop Time: ") +
                   t.getStopHour() + ":" +
                   t.getStopMinute() + ":" +
                   t.getStopSecond());
                   
    for (int i = 1; i <= 7; i++) 
    {
      if (t.isWeekdaySelected(i)) 
      {
        week_day |= (0x01 << (i-1));
        Serial.println(String("Day ") + i + " is selected");
      }
      else
      {
        week_day &= (~(0x01 << (i-1)));
      }
    } 

    weekday_set[i] = week_day;
  }
  else
  {
    timer_start_set[i] = 0xFFFF;
    timer_stop_set[i] = 0xFFFF;
  }

}

//=====================================

BLYNK_WRITE(V1)  // TIMER 0
{
  UpdateTimer(0, param );
}
// ------------------------------------------
BLYNK_WRITE(V2)  // TIMER 1
{
  UpdateTimer(1, param );
}
// ------------------------------------------
BLYNK_WRITE(V3)  // TIMER 2
{
  UpdateTimer(2, param );
}
// ------------------------------------------
BLYNK_WRITE(V4)  // TIMER 3
{
  UpdateTimer(3, param );
}
// ------------------------------------------
BLYNK_WRITE(V5)  // TIMER 4
{
  UpdateTimer(4, param );
}
// ------------------------------------------
BLYNK_WRITE(V6)  // TIMER 5
{
  UpdateTimer(5, param );
}
// ------------------------------------------
BLYNK_WRITE(V7)  // TIMER 6
{
  UpdateTimer(6, param );
}
// ------------------------------------------
BLYNK_WRITE(V8)  // TIMER 7
{
  UpdateTimer(7, param );
}
// ------------------------------------------
BLYNK_WRITE(V9)  // TIMER 8
{
  UpdateTimer(8, param );
}
// ------------------------------------------
BLYNK_WRITE(V10)  // TIMER 9
{
  UpdateTimer(9, param );
}
// ------------------------------------------
BLYNK_WRITE(V11)  // TIMER 10 - THIS ONE DOES NOT WORK
{
  UpdateTimer(10, param );
}

// #########################################################################################################

BLYNK_WRITE(InternalPinRTC) 
{
  const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013
  unsigned long blynkTime = param.asLong(); 
  
  if (blynkTime >= DEFAULT_TIME) 
  {
    setTime(blynkTime);

    day_of_week = weekday();
  
    if ( day_of_week == 1 )
      day_of_week = 7;
    else
      day_of_week -= 1; 
    
    rtc_sec = (hour()*60*60) + (minute()*60) + second();

    Serial.print(String("RTC Server: ") + hour() + ":" + minute() + ":" + second());
    Serial.print(" - ");
    Serial.print(String("Day of Week: ") + weekday()); 
    Serial.print(" - ");    
    Serial.println(blynkTime);
    
  }
}

// #########################################################################################################
BLYNK_CONNECTED() 
{
  Blynk.sendInternal("rtc", "sync"); 
}

// #########################################################################################################
void checkTime() 
{
  Blynk.sendInternal("rtc", "sync"); 
}

// #########################################################################################################
void led_mng()
{
  bool time_set_overflow;
  bool led_status_buf[10];
  
  for (int i=0; i<10; i++)
  {
    led_status_buf[i] = led_status[i];
    time_set_overflow = 0;
    
    if ( timer_start_set[i] != 0xFFFF && timer_stop_set[i] != 0xFFFF)
    {
      if ( timer_stop_set[i] < timer_start_set[i] ) time_set_overflow = 1;

      if ((((time_set_overflow == 0 && (rtc_sec >= timer_start_set[i]) && (rtc_sec < timer_stop_set[i])) ||
        (time_set_overflow  && ((rtc_sec >= timer_start_set[i]) || (rtc_sec < timer_stop_set[i])))) && 
        (weekday_set[i] == 0x00 || (weekday_set[i] & (0x01 << (day_of_week - 1) )))) )
        {
          led_timer_on_set[i] = 1;
        }
        else
          led_timer_on_set[i] = 0;
    }
    else
      led_timer_on_set[i] = 0;

    if ( led_timer_on_set[i] )
    {
      led_status[i] = 1;
      led_set[i] = 0;
    }
    else
    {
      led_status[i] = led_set[i];
    }

    if ( led_status_buf[i] != led_status[i] )
      update_blynk_status[i] = 1;  
  }
}

// #########################################################################################################

void blynk_update() // Knopstatus updaten
{
  if ( update_blynk_status[0] )
  {
      update_blynk_status[0] = 0;
      //Blynk.virtualWrite(V0, led_status[0]);
      Serial.println("Timer 0 gewijzigd");
  }  

  if ( update_blynk_status[1] )
  {
      update_blynk_status[1] = 0;
      //Blynk.virtualWrite(V1, led_status[1]);
      Serial.println("Timer 1 gewijzigd");
  } 

  if ( update_blynk_status[2] )
  {
      update_blynk_status[2] = 0;
     // Blynk.virtualWrite(V2, led_status[2]);
  } 

    if ( update_blynk_status[3] )
  {
      update_blynk_status[3] = 0;
      //Blynk.virtualWrite(V3, led_status[3]);
  } 

    if ( update_blynk_status[4] )
  {
      update_blynk_status[4] = 0;
     // Blynk.virtualWrite(V4, led_status[4]);
  } 

    if ( update_blynk_status[5] )
  {
      update_blynk_status[5] = 0;
      //Blynk.virtualWrite(V5, led_status[5]);
  } 

    if ( update_blynk_status[6] )
  {
      update_blynk_status[6] = 0;
      //Blynk.virtualWrite(V6, led_status[6]);
  } 

    if ( update_blynk_status[7] )
  {
      update_blynk_status[7] = 0;
     // Blynk.virtualWrite(V7, led_status[7]);
      Serial.println("Timer 7 gewijzigd");
  } 

    if ( update_blynk_status[8] )
  {
      update_blynk_status[8] = 0;
      //Blynk.virtualWrite(V8, led_status[8]);
       Serial.println("Timer 8 gewijzigd");
  } 

    if ( update_blynk_status[9] )
  {
      update_blynk_status[9] = 0;
      //Blynk.virtualWrite(V9, led_status[9]);
      Serial.println("Timer 9 gewijzigd");
  } 


    if ( update_blynk_status[10] )
  {
      update_blynk_status[10] = 0;
      //Blynk.virtualWrite(V10, led_status[10]);
      Serial.println("Timer 10 gewijzigd");
  } 
  
}

// #########################################################################################################
void setup()
{
  Serial.begin(115200);
  delay(100);

  Blynk.begin(auth, ssid, pass);

  timer.setInterval(1000L, checkTime);

  Serial.println("Setup uitgevoerd...");
}

// #########################################################################################################
void loop() 
{ Blynk.run();
  timer.run();
  led_mng();
  blynk_update();
}

@Carlimero Please edit your post, using the pencil icon at the bottom, and add triple backticks at the beginning and end of your code so that it displays correctly.
Triple backticks look like this:
```

Copy and paste these if you can’t find the correct symbol on your keyboard.

Pete.

apostrophes (‘’') don’t work, @Carlimero; use backticks (```) to make the code scroll properly.
Thanks, Mike

I’m sorry, I used the normal ticks instead of the backticks…

The time inputs come on the Virtual pins V1 - V11, though the V11 is not working, even after increasing the array-lengths of

bool led_set[11];
long timer_start_set[11] =
long timer_stop_set[11] =
unsigned char weekday_set[11];
bool led_status[11];
bool update_blynk_status[11];
bool led_timer_on_set[11];

Here is the code again:

// Fill-in information from your Blynk Template here
#define BLYNK_TEMPLATE_ID "..."
#define BLYNK_TEMPLATE_NAME "...."
#define BLYNK_AUTH_TOKEN "..."

#define BLYNK_FIRMWARE_VERSION        "0.1.0"
#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG

#define APP_DEBUG

// Uncomment your board, or configure a custom board in Settings.h
//#define USE_SPARKFUN_BLYNK_BOARD
//#define USE_NODE_MCU_BOARD
//#define USE_WITTY_CLOUD_BOARD
#define USE_WEMOS_D1_MINI

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

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "...";
char pass[] = "....";

char auth[] = BLYNK_AUTH_TOKEN;
BlynkTimer timer;

// Aantal timers: pas ook onderstaande arrays aan en voeg Blynk_wrtie procedures toe bij wijzigingen!
bool led_set[11];
long timer_start_set[11] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
long timer_stop_set[11] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
unsigned char weekday_set[11];

bool led_status[11];
bool update_blynk_status[11];
bool led_timer_on_set[11];

long rtc_sec;
unsigned char day_of_week;

// #########################################################################################################


// ----- I SKIPPED THIS PART AS IT OCCURRED ALSO TO WORK WITHOUT ---------------------------------

/*
//----------------------------------------------------------------------------------------------
void UpdateSwitch (int i, int val)
{
    if ( led_timer_on_set[i] == 0 )
      led_set[i] = val;
    else
      update_blynk_status[i] = 1;
    Serial.println("");
    Serial.print("UpdateSwitch "); Serial.print(i); Serial.println(" uitgevoerd..."); 
}


//=====================================
BLYNK_WRITE(V0)   // KNOP 0
{
  int val = param.asInt();
  UpdateSwitch(0,val);

//  if ( led_timer_on_set[0] == 0 )
//    led_set[0] = val;
//  else
//    update_blynk_status[0] = 1;

}
//--------------------------------------

BLYNK_WRITE(V1)    // KNOP 1
{
  int val = param.asInt();
  UpdateSwitch(1,val);
}
//--------------------------------------
BLYNK_WRITE(V2)   // KNOP 2
{
  int val = param.asInt();
  UpdateSwitch(2,val);
}

//--------------------------------------
BLYNK_WRITE(V3)   // KNOP 3
{
  int val = param.asInt();
  UpdateSwitch(3,val);
}

//--------------------------------------
BLYNK_WRITE(V4)   // KNOP 4
{
  int val = param.asInt();
  UpdateSwitch(4,val);
}
//--------------------------------------
BLYNK_WRITE(V5)   // KNOP 5
{
  int val = param.asInt();
  UpdateSwitch(5,val);
}
//--------------------------------------
BLYNK_WRITE(V6)   // KNOP 6
{
  int val = param.asInt();
  UpdateSwitch(6,val);
}
//--------------------------------------
BLYNK_WRITE(V7)   // KNOP 7
{
  int val = param.asInt();
  UpdateSwitch(7,val);
}
//--------------------------------------
BLYNK_WRITE(V8)   // KNOP 8
{
  int val = param.asInt();
  UpdateSwitch(8,val);
}
//--------------------------------------
BLYNK_WRITE(V9)   // KNOP 9
{
  int val = param.asInt();
  UpdateSwitch(9,val);
}
//--------------------------------------
*/

// #########################################################################################################

void UpdateTimer(int i, BlynkParam param) // Instellen en weergeven nieuwe timerinstellingen
{

  unsigned char week_day;
 
  TimeInputParam t(param);
  //TimeInputParam t(TimeInput);

  Serial.println("");
  Serial.print("Nieuwe waarden voor timer no."); Serial.print(i); Serial.println(":");
    
  if (t.hasStartTime() && t.hasStopTime() ) 
  {
    timer_start_set[i] = (t.getStartHour() * 60 * 60) + (t.getStartMinute() * 60) + t.getStartSecond();
    timer_stop_set[i] = (t.getStopHour() * 60 * 60) + (t.getStopMinute() * 60) + t.getStopSecond();
    
    Serial.println(String("Start Time: ") +
                   t.getStartHour() + ":" +
                   t.getStartMinute() + ":" +
                   t.getStartSecond());
                   
    Serial.println(String("Stop Time: ") +
                   t.getStopHour() + ":" +
                   t.getStopMinute() + ":" +
                   t.getStopSecond());
                   
    for (int i = 1; i <= 7; i++) 
    {
      if (t.isWeekdaySelected(i)) 
      {
        week_day |= (0x01 << (i-1));
        Serial.println(String("Day ") + i + " is selected");
      }
      else
      {
        week_day &= (~(0x01 << (i-1)));
      }
    } 

    weekday_set[i] = week_day;
  }
  else
  {
    timer_start_set[i] = 0xFFFF;
    timer_stop_set[i] = 0xFFFF;
  }

}

//=====================================

BLYNK_WRITE(V1)  // TIMER 0
{
  UpdateTimer(0, param );
}
// ------------------------------------------
BLYNK_WRITE(V2)  // TIMER 1
{
  UpdateTimer(1, param );
}
// ------------------------------------------
BLYNK_WRITE(V3)  // TIMER 2
{
  UpdateTimer(2, param );
}
// ------------------------------------------
BLYNK_WRITE(V4)  // TIMER 3
{
  UpdateTimer(3, param );
}
// ------------------------------------------
BLYNK_WRITE(V5)  // TIMER 4
{
  UpdateTimer(4, param );
}
// ------------------------------------------
BLYNK_WRITE(V6)  // TIMER 5
{
  UpdateTimer(5, param );
}
// ------------------------------------------
BLYNK_WRITE(V7)  // TIMER 6
{
  UpdateTimer(6, param );
}
// ------------------------------------------
BLYNK_WRITE(V8)  // TIMER 7
{
  UpdateTimer(7, param );
}
// ------------------------------------------
BLYNK_WRITE(V9)  // TIMER 8
{
  UpdateTimer(8, param );
}
// ------------------------------------------
BLYNK_WRITE(V10)  // TIMER 9
{
  UpdateTimer(9, param );
}
// ------------------------------------------
BLYNK_WRITE(V11)  // TIMER 10 - THIS ONE DOES NOT WORK
{
  UpdateTimer(10, param );
}

// #########################################################################################################

BLYNK_WRITE(InternalPinRTC) 
{
  const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013
  unsigned long blynkTime = param.asLong(); 
  
  if (blynkTime >= DEFAULT_TIME) 
  {
    setTime(blynkTime);

    day_of_week = weekday();
  
    if ( day_of_week == 1 )
      day_of_week = 7;
    else
      day_of_week -= 1; 
    
    rtc_sec = (hour()*60*60) + (minute()*60) + second();

    Serial.print(String("RTC Server: ") + hour() + ":" + minute() + ":" + second());
    Serial.print(" - ");
    Serial.print(String("Day of Week: ") + weekday()); 
    Serial.print(" - ");    
    Serial.println(blynkTime);
    
  }
}

// #########################################################################################################
BLYNK_CONNECTED() 
{
  Blynk.sendInternal("rtc", "sync"); 
}

// #########################################################################################################
void checkTime() 
{
  Blynk.sendInternal("rtc", "sync"); 
}

// #########################################################################################################
void led_mng()
{
  bool time_set_overflow;
  bool led_status_buf[10];
  
  for (int i=0; i<10; i++)
  {
    led_status_buf[i] = led_status[i];
    time_set_overflow = 0;
    
    if ( timer_start_set[i] != 0xFFFF && timer_stop_set[i] != 0xFFFF)
    {
      if ( timer_stop_set[i] < timer_start_set[i] ) time_set_overflow = 1;

      if ((((time_set_overflow == 0 && (rtc_sec >= timer_start_set[i]) && (rtc_sec < timer_stop_set[i])) ||
        (time_set_overflow  && ((rtc_sec >= timer_start_set[i]) || (rtc_sec < timer_stop_set[i])))) && 
        (weekday_set[i] == 0x00 || (weekday_set[i] & (0x01 << (day_of_week - 1) )))) )
        {
          led_timer_on_set[i] = 1;
        }
        else
          led_timer_on_set[i] = 0;
    }
    else
      led_timer_on_set[i] = 0;

    if ( led_timer_on_set[i] )
    {
      led_status[i] = 1;
      led_set[i] = 0;
    }
    else
    {
      led_status[i] = led_set[i];
    }

    if ( led_status_buf[i] != led_status[i] )
      update_blynk_status[i] = 1;  
  }
}

// #########################################################################################################

void blynk_update() // Knopstatus updaten
{
  if ( update_blynk_status[0] )
  {
      update_blynk_status[0] = 0;
      //Blynk.virtualWrite(V0, led_status[0]);
      Serial.println("Timer 0 gewijzigd");
  }  

  if ( update_blynk_status[1] )
  {
      update_blynk_status[1] = 0;
      //Blynk.virtualWrite(V1, led_status[1]);
      Serial.println("Timer 1 gewijzigd");
  } 

  if ( update_blynk_status[2] )
  {
      update_blynk_status[2] = 0;
     // Blynk.virtualWrite(V2, led_status[2]);
  } 

    if ( update_blynk_status[3] )
  {
      update_blynk_status[3] = 0;
      //Blynk.virtualWrite(V3, led_status[3]);
  } 

    if ( update_blynk_status[4] )
  {
      update_blynk_status[4] = 0;
     // Blynk.virtualWrite(V4, led_status[4]);
  } 

    if ( update_blynk_status[5] )
  {
      update_blynk_status[5] = 0;
      //Blynk.virtualWrite(V5, led_status[5]);
  } 

    if ( update_blynk_status[6] )
  {
      update_blynk_status[6] = 0;
      //Blynk.virtualWrite(V6, led_status[6]);
  } 

    if ( update_blynk_status[7] )
  {
      update_blynk_status[7] = 0;
     // Blynk.virtualWrite(V7, led_status[7]);
      Serial.println("Timer 7 gewijzigd");
  } 

    if ( update_blynk_status[8] )
  {
      update_blynk_status[8] = 0;
      //Blynk.virtualWrite(V8, led_status[8]);
       Serial.println("Timer 8 gewijzigd");
  } 

    if ( update_blynk_status[9] )
  {
      update_blynk_status[9] = 0;
      //Blynk.virtualWrite(V9, led_status[9]);
      Serial.println("Timer 9 gewijzigd");
  } 


    if ( update_blynk_status[10] )
  {
      update_blynk_status[10] = 0;
      //Blynk.virtualWrite(V10, led_status[10]);
      Serial.println("Timer 10 gewijzigd");
  } 
  
}

// #########################################################################################################
void setup()
{
  Serial.begin(115200);
  delay(100);

  Blynk.begin(auth, ssid, pass);

  timer.setInterval(1000L, checkTime);

  Serial.println("Setup uitgevoerd...");
}

// #########################################################################################################
void loop() 
{ Blynk.run();
  timer.run();
  led_mng();
  blynk_update();
}

This for loop only processes values 0-9 so you need to increase the upper bound to allow your 11th array element to be processed.

I’m concerned about the structure of your code though. Having this in your void loop…

isn’t the correct way to structure your code.

Pete.

Thanks! That was some kind of stupid of me not seeing this!

What could potentially be the problem of this and how should I solve that?

You should read this…

Pete.

As I understand well, I should use something like:

BlynkTimer timer; 

void Voidloop()
{led_mng();
 blynk_update();
}

void setup()
{ //...
  // Rest of setup
  //...

 timer.setInterval(10L, Voidloop); 
}

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

Moreover I want to use the timer results (an array which has 0 values for timers that are not active at the moment and 1 values for the timers that are) and I want to send these results over MQTT / Nodered to other Wemos devices. Originally my plan was to change the void loop to:

void loop() 
{ 
  Blynk.run();
  timer.run();
  led_mng();
  blynk_update();

  if (!client.connected())   
     {
       reconnect();
     }
  client.loop();

}

Should I put the last 5 lines also in the void Voidloop() above then, or isn’t that working?

First of all, I’d avoid giving a function a name like Voidloop and secondly, why do you need to call this function 100 times per second?

If you’re using this with Node-Red and MQTT then you’re approaching the whole thing from totally the wrong angle.
You should be using the Blynk IoT contrib and getting the values from the time input widgets in Node-Red and doing all of your logic processing there, then simply sending command messages (on/off etc) to your Wemos devices via MQTT.

Pete.

I have been thinking about such an approach where I get the time input data as arrays in Nodered, but I did not know how to process this data into time actions there, whereas the timer program as I posted occured to work, thats why I decided to try it this way.

How you do it really depends on how you plan to use these eleven timers, whether you are using just the start and stop times, ort whether you’re also using days of the week, time zones, sun rise/set times etc.

Personally, I tend to use the Bigtimer node in Node-Red, and because I don’t tend to change my timers that often (or at least I tend to use sunrise and sunset times, so although they are constantly adjusting, no input is needed to achieve that) I tend to just edit the timers in the Node-Red flow.

Where I have used the Time input widget I’ve tended to use it to adjust my BigTimer nodes.

Having said that, the Time Input widget is handy, and can be used with Node-Red without too much work.
Much like in C++, the data comes in as an array and can be accessed as msg.arrayOfValues[0], msg.arrayOfValues[1] etc.

It’s probably best to store the start/end times in flow level variables, applying any timezone offset to them first.
Then use a repeating inject node every 1 second to trigger a function which compares that start/end times to the current time, and issues the correct MQTT command if an on or off event is needed.

Pete.

I’m sorry for the late reaction, I was not able to work on this project in the last week…

I tried to place the lines:

led_mng();
blynk_update();

out of the void loop and put them in a Blynk timer action, running once a second. It did not work, the timers are not activated anymore. What does the blynk_update() routine actually do? And should this one not be kept in the void loop?

In reaction on the last post: I’d like to use the timers in combination with the days of week option and want to be able to setup the times on my mobile phone from anywhere. Therefore I prefer the Blynk way instead of Bigtimer (as I understand I need to setup this from Nodered, so being at home at my computer). I think the days of week option results in quite a difficult programming task for a hobbiest like me…

I thougt it would also be possible as an alternative to leave the code as it is and use the node-red-contrib-blynk-iot in Nodered to pick up the timer actions and send them by MQTT to other devices to do actions on the desired times. I tested the result of one datastream (which is connected to a led on the Blynk screen acting on a timer-action) in Nodered (by placing a Write-event-node with a Debug-node), however I don’t get data on that debug node (probably since the timer actions are not working anymore when Nodered is involved). I also tested another virtual pin which is connected to an input button on the Blynk screen and there I get data in Nodered after pushing the button, however, the time-inputs stop working after deploying the nodes and when I restart the Wemos, the timers do work again, but the data does not come to Nodered as long as I do not deploy the nodes again. I don’t understand: I would expect the node-red-contrib-blynk-iot should not affect the working of my code as I did not change this code? Or does it?

Presumably that’s an issue with the way that you restructured your code, but as you’ve not posted the code it’s difficult to say what the issue is.

It’s your code, don’t you understand what it does?

The whole setup is rather clunky, and isn’t structured the way that I’d approach it. When using the time input widget you need to check if the current time has progressed to the point where either the start time or stop time has been reached, and take the appropriate action (turning a device on or off).
As the most granular time period that the time input widget can handle is one second, there’s no point in doing this check more frequently than once per second - via a Blynk timer.

The problem with your code is that it re-performers all of the necessary calculations for each timer every time blynk_update() is called.this is totally unnecessary, and the main calculations should only be performed when the widget is updated and the subsequent BLYNK_WRITE() callback is triggered.

Using basic start and stop times (no active day functionality) you need to know the start time in seconds since midnight, and the stop time in seconds since midnight.

You then need a routine to calculate the current time in seconds since midnight, and for each timer check whether the device should be on or off.
It’s neater to use a flag to track the current state of each of these devices being controlled, so that you don’t keep turning the device on every second, when it’s already turned on.
You may also want to apply some logic that checks if the stop time is earlier than the start time, because this will indicate that the timer spans a midnight time barrier, and handle the logic accordingly.
Then, if you want to use active days then you also add this test into the logic process for each timer.

Regardless of which approach you take, I’d hope that you’d be using ZeroTier or something similar to give you remote access to your Node-Red server.

I don’t understand the “leave the code as it is” comment.
If you use Node-Red then this code is redundant - the processing is done in Node-Red.

Two things here.

  1. if you’ve set-up your Node-Red connection to Blynk with the same Auth token that you are using on your device then only Node-Red or the device can be online at any one time. Take your device offline when you’re using that Node-Red connection.
  2. You need to set your debug node to Complete Message rather than just msg.payload to be able to see the array of data.

This is what I talked about in (1) above. Your Auth token can only be used for one connection at a time. If the Blynk server sees a new connection (from Node-Red say) then it will kick your other connection (the Wemos) off. Rebooting the Wemos will kick the Node-Red connection off.
That’s why it’s best not to run any Blynk code on your Wemos, only MQTT code.

Pete.

This is what you see in Node-Red when you set the Debug node to “Complete message object” and expand the data…

As I said before, msg.arrayOfValues contains five elements:

  1. Start time in seconds since midnight (28800 = 08:00)
  2. Stop time in seconds since midnight (68400 = 19:00)
  3. Timezone
  4. Days of the week selected
  5. Timezone offset in minutes based on the timezone selected and the timezone of the device

Only having the day numbers for the active days is a bit tricky to work with programatically, so I tend to turn them into a fully populated array, where the first element is a dummy value, and Mon-Sun are represented by elements 1-7, so that I can use the current day number to check if the timer is active today…

The code for this function looks like this…

var blynk_day_data = msg.arrayOfValues[3]; // the active days only from Blynk
var active_days = [`dummy`,true,true,true,true,true,true,true]; // initialise the array

active_days[1] = blynk_day_data.includes("1");
active_days[2] = blynk_day_data.includes("2");
active_days[3] = blynk_day_data.includes("3");
active_days[4] = blynk_day_data.includes("4");
active_days[5] = blynk_day_data.includes("5");
active_days[6] = blynk_day_data.includes("6");
active_days[7] = blynk_day_data.includes("7");

return [{payload: active_days}];

The easiest way to get the current day of the week is with the Date/Time formatter node set to output just the day of the week (“d”)…

Triggering the node produces the result of “5”, because it’s Friday today…

image

You can also calculate the current time in seconds since midnight using the Date/Time formatter node set to HH:mm:ss …

image

then use this function…

var current_time = msg.payload;
var arr = current_time.split(':');
var currrent_hour = parseInt(arr[0]);
var current_min = parseInt(arr[1]);
var current_sec = parseInt(arr[2]);

var current_seconds_since_midnight = (parseInt(currrent_hour) * 3600) + (parseInt(current_min) * 60) + (parseInt(current_sec))

return [{ payload: current_seconds_since_midnight}];

to give the result…

The current time was 12:19:37 which returns 44377 seconds since midnight.

Does this help understand how to use some of the data from Blynk to build a Node-Red flow that utilises the time input widget?

Pete.

Hello Pete,

Thank you very much for all of this information. I’ll investigate your proposals and let you know.

One thing that I surely don’t understand:

You wrote:

if you’ve set-up your Node-Red connection to Blynk with the same Auth token that you are using on your device then only Node-Red or the device can be online at any one time. Take your device offline when you’re using that Node-Red connection

But I would expect the device should be on the same Auth-token as Nodered, otherwise the data produced by the device is never reaching Nodered I would say. And when I want to put the produced data from the device through to Nodered all the time, they need to be online both I think? Or is there some other way?

You still seem to be stuck on the concept that the Wemos device is processing the time input data coming from Blynk.
If you want to use Node-Red with the Blynk IoT contrib then you would move that data processing into Node-Red, and not run any Blynk code on your Wemos.

The only way that data enters and leaves your Wemos should be via MQTT messages, which go to/from Node-Red. This way, your Wemos has no Blynk code, and no Auth token. It’s simply subscribed to MQTT topics which tell it to turn on/off relays to control the devices that being controlled.

In my home automation setup I have around thirty ESP8266 or ESP32 based devices. Some of these simply turn on or off a single light or socket. Others collect data such as outside weather information, or indoor temperature or humidity data. Others are connected to Nextion touch screens and allow data from these weather and temperature data to be displayed, and for devices to be controlled.
I also have RFID door entry devices, Infrared transmitters, 433MHz receivers and transmitters etc etc.
All of these devices just run MQTT code, and talk to Node-Red via MQTT messages.
If I want to turn a light on, I send an MQTT message to that light’s topic, and it responds to tell Node-Red that the light is now on.
If I want to open my gate, turn on my air conditioning, open my blinds etc etc then I do all of this via MQTT messages.

I can also do all of these things (turn on lights, open gates, contro my A/C etc) from Blynk, because I’ve translated the incoming Blynk virtual pin commands into MQTT messages that go to the appropriate devices.
I can also view the weather data, and inside temperature/humidity data, status of my lights etc in Blynk because I’ve developed Node-Red flows to send that data to virtual pins on Blynk so that it can be viewed on Supercharts, gauges etc.

But, Blynk knows nothing about all of thes ESP8266 and ESP32 devices, because they don’t run any Blynk code. The only “device” that Blynk sees is Node-Red, and that’s the only device that has an Auth token associated with it.

The great thing about this setup is that the code running on my ESP devices is generally very static, because all it does is listen for MQTT commands and feedback that the command has been received and understood (they do all send regular heartbeat info about uptime, RSSI etc, but this is standard code for each device).
If I want to change the logic so that devices work in different ways, maybe having one Blynk switch widget to turn on/off a group of devices, then all of that is done in Node-Red and the Blynk app. The code on the devices remains unchanged, because they just need to be subscribed to the same Node-Red topics and respond to the same MQTT messages in the same way as they did before.

Does this help?

Pete.

1 Like

I understand the straightforward way you set the whole thing up. As my programming skills are limited and I found the code for using the Blynk timer inputs I was thinking to do it as written in this scheme:

That means: an extra Wemos just for processing the time inputs and making some virtual pins high/low at specific moments and have other Wemos devices do the real work. But as I understand this approach isn’t working. Then I think there is no other way than skipping the Wemos between the mobile device and Nodered and try to get that working?

Or would it also be possible to keep the “time-processing Wemos” and have it sending the data over MQTT to Nodered?

Yes it would, but with that setup you wouldn’t use the Blynk IoT contrib in Node-Red.

The flaw in your diagram is where you say that you use the Wemos for processing time data but also say that you use the Node-Red Blynk IoT contrib for the Timer Actions.

The correct approach would be to use the Wemos to figure-out the whether each of your “slave” Wemos devices should be on or off based on the time input widget data, then send MQTT messages to them from your additional “Master” Wemos. This makes Node-Red redundant, and just uses your MQTT broker on the Pi (presumably Mosquitto).

The alternative approach, as discussed already, is to remove your additional “Master” Wemos from the equation, and do the processing entirely in Node-Red.

As I’m sure you realise, I use the Node-Red approach and that’s the approach I’d recommend for anyone else.

Trying to get your additional master Wemos talking to both Blynk and your MQTT broker is a bit tricky, but should be do-able. You would need to stop using Blynk.begin() and manually manage your WiFi connection, then use Blynk.config() and Blynk.connect(), then re-use your WiFi connection for the MQTT PubSubClient connection to your Mosquitto broker.

Your existing code is very badly written anyway, and it would need to be re-written in a much more efficient way if you were going to successfully maintain a connection to both Blynk and Mosquitto.

For someone with limited programming skills I think the Node-Red approach is probably easier to implement, but it depends how much effort you’re prepared to put in to it.

If you did go down the Node-Red route then it’s far easier to add-in additional things like Alexa voice control in future if that’s something that interests you.

Pete.

I tried the timestamp input in Nodered and used your code to get the day of week and the seconds after midnight, that was very helpful and I can use this data in the rest of the process I guess.

As I understand I’d best do the whole processing in Nodered and then send MQTT messages for actions to the slave Wemos devices. However, my knowledge of Java Script is totally zero, so doing all in Nodered will be too hard for me I guess. Moreover: besides the time inputs I also would like the possibilities to take the actions only when beiing at home or not at home (to be detected by another Wemos sending the result to Nodered) and / or switching only when the time input is high and it’s also dark enough outside (light measuring by another Wemos again). These extra options will make the programming in Nodered even harder and I guess the screen will get very messy also when I should do this for 11 timers…

Now I was thinking of the possibility to write the whole setup from the blynk switches to Nodered, send an array with all of these settings by MQTT to a Wemos, do all of the processing there, and send the results by MQTT to the slave Wemos devices via Nodered:

I’m aware that this is a probably unnecessarily complicated way to solve my project, however it gives me the possibility to do the coding mostly in Arduini-IDE. Are there any obstacles to be expected for this solution?

To send all the setup data from Nodered to the Wemos, I think I should put the values of all the virtual pins involved in an array and send this by MQTT to the Wemos. Another option would be placing all the data in line, send it as a string to the Wemos en split it there into the separate numbers (as these numbers will vary from 0 to 2 and I could send the seconds after midnight and the day number apart). Sending each value as a separate MQTT message is not useful I think, as this setup involves about 75 values. Sending a separate array or combined number for the settings of each timer would also be a possibulty. What is the way of putting the values of various virtual pins into an array and send this array by MQTT from nodered to the Wemos and does the Wemos recognize this as an array again? Or can I add a function for sending a result of (Vir1 + 10Vir2 + 100V3 + 1000*V4 …) etc to the Wemos?

Correct.

From what I’ve seen, your C++ coding skills aren’t great either, so it’s going to be a challenge for you either way. This will be made more difficult because PubSubClient used Char dats, which I personally find quite difficult to work with.

But, NodeJS isn’t really much different to C++, and it’s pretty easy to swap between the two languages because the syntax is so similar. You also have the advantage that you can use many of the standard nodes to do things for you, rather than doing everything in code. In the examples I gave earlier, I used the Date/Time formatter to give time data in a useable format, when actually that could have been done in code instead - but as you’re not much of a coder I used this example to soften the learning curve.

All of these things are quite straightforward, and are simply conditions that need to be tested in whatever system you choose to handle the logic processing it. It’s just far easier to do in Node-Red if this data is coming-in via MQTT than it is to offload that logic processing to a different device, then pass the results back to Node-Red and on to the devices via MQTT.

Other than the ones I’ve highlighted already no, I can’t think of any.

As far as the rest of your question is concerned, I’m not going to go down the rabbit hole of helping you figure-out the best way to do this with a Wemos as a secondary logic processor.
I’d be happy to help you get started with building your Node–Red and NodeJS skills, but if you go down your hybrid route then you’re on your own as far as support from me is concerned.

Pete.