BLYNK
HOME       📲 GETTING STARTED       📗 DOCS       ❓HELP CENTER       👉 SKETCH BUILDER

Automatic Yard Sprinkler System

Hi fellow blynkers!
Thanks to @Costas code in this post, I’ve put together this:
Blynk App Demo
top part down to button Zone 5 OFF is output control, below Zone5 button is feedback telling you whether or not the zone actually turned on.
Code:

/////////************* **********/////////
//          Blynk Assignments           //
/////////************* **********/////////
/*
V0   - Mode Switch
VX   - Status LED :: Not working correctly, won't switch colors with app closed
V1X  - Manual Switch
V2X  - Auto Switch :: Time Input Channel
V3X  - Actual Valve State
V4X  - Channel Start Seconds
V5X  - Channel Stop Seconds
V90  - Blynk App Notifications Enable/Disable
V100 - Controller Status
V101 - NowSeconds
V102 - Mode on Controller 1=OFF 2=Manual 3=Auto
V103 - NotifyStatus : for debugging will delete
V105 - WiFi Signal Strength
Thanks to @Costas:
https://community.blynk.cc/t/time-input-widget-and-eventor/14868/16
*/
#include <blynk.h>
char auth[] = "****"; 
BlynkTimer timer;
char currentTime[9];
bool clockSync = false;
unsigned int nowseconds = 999;

int mode = 0;
int manuel1 = 0;
int manuel2 = 0;
int manuel3 = 0;
int manuel4 = 0;
int manuel5 = 0;
int auto1 = 0;
int auto2 = 0;
int auto3 = 0;
int auto4 = 0;
int auto5 = 0;
int alertstatus = 1;  //EEPROM location 1
int valve1state = 999;  //999 is error status
int valve2state = 999;
int valve3state = 999;
int valve4state = 999;
int valve5state = 999;


// Zone valves
#define valve1 2
#define valve2 3
#define valve3 4
#define valve4 5
#define valve5 6
#define valve6 7
#define valve7 8

//int counts = 0;

#define GREEN     "#008000"//"#23C48E"
#define BLUE      "#04C0F8"
#define YELLOW    "#ED9D00"
#define RED       "#FF033E" //"#D3435C"
#define DARK_BLUE "#5F7CD8"

WidgetLED led1(V1);
WidgetLED led2(V2);
WidgetLED led3(V3);
WidgetLED led4(V4);
WidgetLED led5(V5);

BLYNK_WRITE(V90)
{
  alertstatus = param.asInt();
  EEPROM.put(50, alertstatus);
}

/////////************* **********/////////
//             Mode Selection           //
/////////************* **********/////////

BLYNK_WRITE(V0) {
  switch (param.asInt())
  {
    case 1: // OFF
      //Serial.println("Item 1 selected");
      mode = 1;
      offmode();
      Blynk.virtualWrite(V100, "Mode: OFF");
      EEPROM.put(1, mode);//not used--may use if Wifi issues and blynk_connect fails
      break;
    case 2: // Manual Mode
      //Serial.println("Item 2 selected");
      mode = 2;
      manualmode();
      Blynk.virtualWrite(V100, "Mode: Manual");
      EEPROM.put(1, mode);
      //led1.setColor(BLYNK_GREEN);
      break;
    case 3: // Automatic Mode
      //Serial.println("Item 3 selected");
      mode = 3;
      automode();
      Blynk.virtualWrite(V100, "Mode: Automatic");
      EEPROM.put(1, mode);
      break;
    default:
      //Serial.println("Unknown item selected");
      mode = 999;
  }
}

/////////************* **********/////////
//             Manual Buttons           //
/////////************* **********/////////

BLYNK_WRITE(V11)
{
  manuel1 = param.asInt();
  if (mode == 2 || mode == 3)
  {
    if (manuel1 == 1)
    {
      digitalWrite(valve1, LOW);
      led1.setColor(GREEN);
      Blynk.virtualWrite(V100, "Zone 1 Turning On");
    }
    else
    {
      digitalWrite(valve1, HIGH);
      led1.setColor(RED);
      Blynk.virtualWrite(V100, "Zone 1 Turning Off");
    }
  }
  if (mode == 1)
  {
      Blynk.virtualWrite(V11, 0);
      Blynk.notify("Select Manual or Auto Mode");
  }
}

BLYNK_WRITE(V12)
{
  manuel2 = param.asInt();
  if (mode == 2 || mode == 3)
  {
    if (manuel2 == 1)
    {
      digitalWrite(valve2, LOW);
      led2.setColor(GREEN);
      Blynk.virtualWrite(V100, "Zone 2 Turning On");
    }
    else
    {
      digitalWrite(valve2, HIGH);
      led2.setColor(RED);
      Blynk.virtualWrite(V100, "Zone 2 Turning Off");
    }
  }
  if (mode == 1)
  {
      Blynk.virtualWrite(V12, 0);
      Blynk.notify("Select Manual or Auto Mode");
  }
}

BLYNK_WRITE(V13)
{
  manuel3 = param.asInt();
  if (mode == 2 || mode == 3)
  {
    if (manuel3 == 1)
    {
      digitalWrite(valve3, LOW);
      led3.setColor(GREEN);
      Blynk.virtualWrite(V100, "Zone 3 Turning On");
    }
    else
    {
      digitalWrite(valve3, HIGH);
      led3.setColor(RED);
      Blynk.virtualWrite(V100, "Zone 3 Turning Off");
    }
  }
  if (mode == 1)
  {
      Blynk.virtualWrite(V13, 0);
      Blynk.notify("Select Manual or Auto Mode");
  }
}

BLYNK_WRITE(V14)
{
  manuel4 = param.asInt();
  if (mode == 2 || mode == 3)
  {
    if (manuel4 == 1)
    {
      digitalWrite(valve4, LOW);
      led4.setColor(GREEN);
      Blynk.virtualWrite(V100, "Zone 4 Turning On");
    }
    else
    {
      digitalWrite(valve4, HIGH);
      led4.setColor(RED);
      Blynk.virtualWrite(V100, "Zone 4 Turning Off");
    }
  }
  if (mode == 1)
  {
      Blynk.virtualWrite(V14, 0);
      Blynk.notify("Select Manual or Auto Mode");
  }
}

BLYNK_WRITE(V15)
{
  manuel5 = param.asInt();
  if (mode == 2 || mode == 3)
  {
    if (manuel5 == 1)
    {
      digitalWrite(valve5, LOW);
      led5.setColor(GREEN);
      Blynk.virtualWrite(V100, "Zone 5 Turning On");
    }
    else
    {
      digitalWrite(valve5, HIGH);
      led5.setColor(RED);
      Blynk.virtualWrite(V100, "Zone 5 Turning Off");
    }
  }
  if (mode == 1)
  {
      Blynk.virtualWrite(V15, 0);
      Blynk.notify("Select Manual or Auto Mode");
  }
}

/////////************* **********/////////
//          Automatic Controls          //
/////////************* **********/////////

BLYNK_WRITE(V21) {   // Scheduler #X Time Input widget  
  TimeInputParam t(param);
  nowseconds = Time.local() % 86400;
  unsigned int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);  
  unsigned int stopseconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
  Blynk.virtualWrite(V41, startseconds);
  Blynk.virtualWrite(V51, stopseconds);
  int dayadjustment = -1;  
  if(Time.weekday() == 1){
    dayadjustment = 6; // needed for Sunday Time library is day 1 and Blynk is day 7
  }
  if(t.isWeekdaySelected((Time.weekday() + dayadjustment))){ //Time library starts week on Sunday, Blynk on Monday  
    //Schedule is ACTIVE today 
    if(nowseconds >= startseconds - 31 && nowseconds <= startseconds + 31 ){    // 62s on 60s timer ensures 1 trigger command is sent
      //led1.setColor(BLUE);
      Blynk.virtualWrite(V100, "Zone 1 Starting  AUTOMODE");
      Blynk.setProperty(V1, "color", BLUE);
      Blynk.virtualWrite(V11, HIGH);
      digitalWrite(valve1, LOW);
      if(alertstatus ==1) {Blynk.notify("Zone 1 Starting  AUTOMODE");}
    }                  
    if(nowseconds >= stopseconds - 31 && nowseconds <= stopseconds + 31 ){   // 62s on 60s timer ensures 1 trigger command is sent
      //led1.setColor(YELLOW);
      Blynk.virtualWrite(V100, "Zone 1 Stopping  AUTOMODE");
      Blynk.setProperty(V1, "color", YELLOW);
      Blynk.virtualWrite(V11, LOW);
      digitalWrite(valve1, HIGH);
      if(alertstatus == 1) {Blynk.notify("Zone 1 Stopping  AUTOMODE");}
    }               
  }
}

BLYNK_WRITE(V22) {   // Scheduler #X Time Input widget  
  TimeInputParam t(param);
  nowseconds = Time.local() % 86400;
  unsigned int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);  
  unsigned int stopseconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
  Blynk.virtualWrite(V42, startseconds);
  Blynk.virtualWrite(V52, stopseconds);
  int dayadjustment = -1;  
  if(Time.weekday() == 1){
    dayadjustment = 6; // needed for Sunday Time library is day 1 and Blynk is day 7
  }
  if(t.isWeekdaySelected((Time.weekday() + dayadjustment))){ //Time library starts week on Sunday, Blynk on Monday  
    //Schedule is ACTIVE today 
    if(nowseconds >= startseconds - 31 && nowseconds <= startseconds + 31 ){    // 62s on 60s timer ensures 1 trigger command is sent
      //led1.setColor(BLUE);
      Blynk.virtualWrite(V100, "Zone 2 Starting  AUTOMODE");
      Blynk.setProperty(V2, "color", BLUE);
      Blynk.virtualWrite(V12, HIGH);
      digitalWrite(valve2, LOW);
      if(alertstatus ==1) {Blynk.notify("Zone 2 Starting  AUTOMODE");}
    }                  
    if(nowseconds >= stopseconds - 31 && nowseconds <= stopseconds + 31 ){   // 62s on 60s timer ensures 1 trigger command is sent
      //led1.setColor(YELLOW);
      Blynk.virtualWrite(V100, "Zone 2 Stopping  AUTOMODE");
      Blynk.setProperty(V2, "color", YELLOW);
      Blynk.virtualWrite(V12, LOW);
      digitalWrite(valve2, HIGH);
      if(alertstatus == 1) {Blynk.notify("Zone 2 Stopping  AUTOMODE");}
    }               
  }
}

BLYNK_WRITE(V23) {   // Scheduler #X Time Input widget  
  TimeInputParam t(param);
  nowseconds = Time.local() % 86400;
  unsigned int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);  
  unsigned int stopseconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
  Blynk.virtualWrite(V43, startseconds);
  Blynk.virtualWrite(V53, stopseconds);
  int dayadjustment = -1;  
  if(Time.weekday() == 1){
    dayadjustment = 6; // needed for Sunday Time library is day 1 and Blynk is day 7
  }
  if(t.isWeekdaySelected((Time.weekday() + dayadjustment))){ //Time library starts week on Sunday, Blynk on Monday  
    //Schedule is ACTIVE today 
    if(nowseconds >= startseconds - 31 && nowseconds <= startseconds + 31 ){    // 62s on 60s timer ensures 1 trigger command is sent
      //led1.setColor(BLUE);
      Blynk.virtualWrite(V100, "Zone 3 Starting  AUTOMODE");
      Blynk.setProperty(V3, "color", BLUE);
      Blynk.virtualWrite(V13, HIGH);
      digitalWrite(valve3, LOW);
      if(alertstatus ==1) {Blynk.notify("Zone 3 Starting  AUTOMODE");}
    }                  
    if(nowseconds >= stopseconds - 31 && nowseconds <= stopseconds + 31 ){   // 62s on 60s timer ensures 1 trigger command is sent
      //led1.setColor(YELLOW);
      Blynk.virtualWrite(V100, "Zone 3 Stopping  AUTOMODE");
      Blynk.setProperty(V3, "color", YELLOW);
      Blynk.virtualWrite(V13, LOW);
      digitalWrite(valve3, HIGH);
      if(alertstatus == 1) {Blynk.notify("Zone 3 Stopping  AUTOMODE");}
    }               
  }
}

BLYNK_WRITE(V24) {   // Scheduler #X Time Input widget  
  TimeInputParam t(param);
  nowseconds = Time.local() % 86400;
  unsigned int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);  
  unsigned int stopseconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
  Blynk.virtualWrite(V44, startseconds);
  Blynk.virtualWrite(V54, stopseconds);
  int dayadjustment = -1;  
  if(Time.weekday() == 1){
    dayadjustment = 6; // needed for Sunday Time library is day 1 and Blynk is day 7
  }
  if(t.isWeekdaySelected((Time.weekday() + dayadjustment))){ //Time library starts week on Sunday, Blynk on Monday  
    //Schedule is ACTIVE today 
    if(nowseconds >= startseconds - 31 && nowseconds <= startseconds + 31 ){    // 62s on 60s timer ensures 1 trigger command is sent
      //led1.setColor(BLUE);
      Blynk.virtualWrite(V100, "Zone 4 Starting  AUTOMODE");
      Blynk.setProperty(V4, "color", BLUE);
      Blynk.virtualWrite(V14, HIGH);
      digitalWrite(valve4, LOW);
      if(alertstatus ==1) {Blynk.notify("Zone 4 Starting  AUTOMODE");}
    }                  
    if(nowseconds >= stopseconds - 31 && nowseconds <= stopseconds + 31 ){   // 62s on 60s timer ensures 1 trigger command is sent
      //led1.setColor(YELLOW);
      Blynk.virtualWrite(V100, "Zone 4 Stopping  AUTOMODE");
      Blynk.setProperty(V4, "color", YELLOW);
      Blynk.virtualWrite(V14, LOW);
      digitalWrite(valve4, HIGH);
      if(alertstatus == 1) {Blynk.notify("Zone 4 Stopping  AUTOMODE");}
    }               
  }
}

BLYNK_WRITE(V25) {   // Scheduler #X Time Input widget  
  TimeInputParam t(param);
  nowseconds = Time.local() % 86400;
  unsigned int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);  
  unsigned int stopseconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
  Blynk.virtualWrite(V45, startseconds);
  Blynk.virtualWrite(V55, stopseconds);
  int dayadjustment = -1;  
  if(Time.weekday() == 1){
    dayadjustment = 6; // needed for Sunday Time library is day 1 and Blynk is day 7
  }
  if(t.isWeekdaySelected((Time.weekday() + dayadjustment))){ //Time library starts week on Sunday, Blynk on Monday  
    //Schedule is ACTIVE today 
    if(nowseconds >= startseconds - 31 && nowseconds <= startseconds + 31 ){    // 62s on 60s timer ensures 1 trigger command is sent
      //led1.setColor(BLUE);
      Blynk.virtualWrite(V100, "Zone 5 Starting  AUTOMODE");
      Blynk.setProperty(V5, "color", BLUE);
      Blynk.virtualWrite(V15, HIGH);
      digitalWrite(valve5, LOW);
      if(alertstatus ==1) {Blynk.notify("Zone 5 Starting  AUTOMODE");}
    }                  
    if(nowseconds >= stopseconds - 31 && nowseconds <= stopseconds + 31 ){   // 62s on 60s timer ensures 1 trigger command is sent
      //led1.setColor(YELLOW);
      Blynk.virtualWrite(V100, "Zone 5 Stopping  AUTOMODE");
      Blynk.setProperty(V5, "color", YELLOW);
      Blynk.virtualWrite(V15, LOW);
      digitalWrite(valve5, HIGH);
      if(alertstatus == 1) {Blynk.notify("Zone 5 Stopping  AUTOMODE");}
    }               
  }
}

BLYNK_CONNECTED() {//get data stored in virtual pin V0 from server
  Blynk.syncVirtual(V0);
}

void setup() 
{
    Blynk.begin(auth);
    Time.zone(-5);   //-2.5
    timer.setInterval(60000L, activetoday);  // check every 60s if ON / OFF trigger time has been reached
    timer.setInterval(1000L, clockDisplay);  // check every second if time has been obtained from the server
    timer.setInterval(10000L, sendinfo);
    //Blynk.virtualWrite(V0, 2);
    pinMode(valve1, OUTPUT);
    pinMode(valve2, OUTPUT);
    pinMode(valve3, OUTPUT);
    pinMode(valve4, OUTPUT);
    pinMode(valve5, OUTPUT);
    pinMode(valve6, OUTPUT);
    pinMode(valve7, OUTPUT);
    //pinMode(valve8, OUTPUT);
    digitalWrite(valve1, HIGH);
    digitalWrite(valve2, HIGH);
    digitalWrite(valve3, HIGH);
    digitalWrite(valve4, HIGH);
    digitalWrite(valve5, HIGH);
    digitalWrite(valve6, HIGH);
    digitalWrite(valve7, HIGH);
    //digitalWrite(valve8, HIGH);
    firstrun();

}

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

void firstrun()
{
    EEPROM.get(50, alertstatus);
    Blynk.virtualWrite(V90, alertstatus);
}

void sendinfo()
{
    Blynk.virtualWrite(V100, Time.format("%r - %a %D"));
    Blynk.virtualWrite(V101, nowseconds);
    Blynk.virtualWrite(V102, mode);
    Blynk.virtualWrite(V103, alertstatus); //may delete
    WiFiSignal sig = WiFi.RSSI();
    float strength = sig.getStrength();
    Blynk.virtualWrite(V105, strength);
    
    
    valve1state = digitalRead(valve1);
    valve1state = map(valve1state, 0, 1, 1, 0);//to deal with backwards relay
    Blynk.virtualWrite(V31, valve1state);
    
    valve2state = digitalRead(valve2);
    valve2state = map(valve2state, 0, 1, 1, 0);//to deal with backwards relay
    Blynk.virtualWrite(V32, valve2state);
    
    valve3state = digitalRead(valve3);
    valve3state = map(valve3state, 0, 1, 1, 0);//to deal with backwards relay
    Blynk.virtualWrite(V33, valve3state);
    
    valve4state = digitalRead(valve4);
    valve4state = map(valve4state, 0, 1, 1, 0);//to deal with backwards relay
    Blynk.virtualWrite(V34, valve4state);
    
    valve5state = digitalRead(valve5);
    valve5state = map(valve5state, 0, 1, 1, 0);//to deal with backwards relay
    Blynk.virtualWrite(V35, valve5state);
}

void offmode()
{
    led1.off();
    led2.off();
    led3.off();
    led4.off();
    led5.off();
    
    Blynk.virtualWrite(V11, LOW);
    Blynk.virtualWrite(V12, LOW);
    Blynk.virtualWrite(V13, LOW);
    Blynk.virtualWrite(V14, LOW);
    Blynk.virtualWrite(V15, LOW);
    
    digitalWrite(valve1, HIGH);
    digitalWrite(valve2, HIGH);
    digitalWrite(valve3, HIGH);
    digitalWrite(valve4, HIGH);
    digitalWrite(valve5, HIGH);
}
void manualmode()
{
    led1.on();
    led2.on();
    led3.on();
    led4.on();
    led5.on();
    led1.setColor(RED);
    led2.setColor(RED);
    led3.setColor(RED);
    led4.setColor(RED);
    led5.setColor(RED);
    
    Blynk.virtualWrite(V11, LOW);
    Blynk.virtualWrite(V12, LOW);
    Blynk.virtualWrite(V13, LOW);
    Blynk.virtualWrite(V14, LOW);
    Blynk.virtualWrite(V15, LOW);
    
    digitalWrite(valve1, HIGH);
    digitalWrite(valve2, HIGH);
    digitalWrite(valve3, HIGH);
    digitalWrite(valve4, HIGH);
    digitalWrite(valve5, HIGH);
}

void automode()
{
    led1.on();
    led2.on();
    led3.on();
    led4.on();
    led5.on();
    led1.setColor(YELLOW);
    led2.setColor(YELLOW);
    led3.setColor(YELLOW);
    led4.setColor(YELLOW);
    led5.setColor(YELLOW);
    
    Blynk.virtualWrite(V11, LOW);
    Blynk.virtualWrite(V12, LOW);
    Blynk.virtualWrite(V13, LOW);
    Blynk.virtualWrite(V14, LOW);
    Blynk.virtualWrite(V15, LOW);
    
    digitalWrite(valve1, HIGH);
    digitalWrite(valve2, HIGH);
    digitalWrite(valve3, HIGH);
    digitalWrite(valve4, HIGH);
    digitalWrite(valve5, HIGH);
}


void activetoday(){  // check if schedule #1 should run today
if(mode == 3){
  if(Time.year() != 1970){
    Blynk.syncVirtual(V21);  // sync scheduler #1
    Blynk.syncVirtual(V22);
    Blynk.syncVirtual(V23);
    Blynk.syncVirtual(V24);
    Blynk.syncVirtual(V25);
  }
  }
}

void clockDisplay(){  // only needs to be done once after time sync
  if((Time.year() != 1970) && (clockSync == false)){ 
    sprintf(currentTime, "%02d:%02d:%02d", Time.hour(), Time.minute(), Time.second());
    Serial.println(currentTime);
    clockSync = true;
  } 
} 

Only trouble I’m having is led colors will not update when zones automaticlly turn on and blynk app is closed. More details here. I wonder if it’s not possible to Blynk.setProperty(V1, “color”, BLUE); inside blynk function?