Advanced Time Input Blynk

Hi! I’m try to get this to work on a particle argon: https://community.blynk.cc/t/time-input-widget-and-eventor/14868/17

Here’s what I’ve got so far:

// This #include statement was automatically added by the Particle IDE.
#include <SparkTime.h>
UDP UDPClient;
SparkTime rtc;

 #include <blynk.h>
char auth[] = "***"; 
BlynkTimer timer;
WidgetTerminal terminal(V30);

//WidgetRTC rtc;

// Zone valves
#define valve1 3
#define valve2 4
#define valve3 5
#define valve4 7
#define valve5 8
int mode = 999;
int manuel1 = 0;
int lastmanuel1 = 3;
int auto1 = 0;
int lastauto1 = 3;
//int counts = 0;

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

WidgetLED led1(V1);

BLYNK_WRITE(V0) {
  switch (param.asInt())
  {
    case 1: // OFF
      //Serial.println("Item 1 selected");
      mode = 1;
      Blynk.virtualWrite(V25, mode);
      shutoffall();
      //led1.setColor(BLYNK_RED);
      break;
    case 2: // Manual Mode
      Serial.println("Item 2 selected");
      mode = 2;
      Blynk.virtualWrite(V25, mode);
      //led1.setColor(BLYNK_GREEN);
      break;
    case 3: // Automatic Mode
      Serial.println("Item 3 selected");
      mode = 3;
      Blynk.virtualWrite(V25, mode);
      break;
    default:
      Serial.println("Unknown item selected");
  }
}

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

BLYNK_WRITE(V21) {   // Scheduler #1 Time Input widget  
  TimeInputParam t(param);
  unsigned int nowseconds = ((hour() * 3600) + (minute() * 60) + second());
  unsigned int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);  
  unsigned int stopseconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
  int dayadjustment = -1;  
  if(weekday() == 1){
    dayadjustment = 6; // needed for Sunday Time library is day 1 and Blynk is day 7
  }
  if(t.isWeekdaySelected((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
      Blynk.virtualWrite(V0, 255);  // turn on virtual LED
      Serial.println("Schedule 1 started");
    }                  
    if(nowseconds >= stopseconds - 31 && nowseconds <= stopseconds + 31 ){   // 62s on 60s timer ensures 1 trigger command is sent
      Blynk.virtualWrite(V0, 0);   // turn OFF virtual LED
      Serial.println("Schedule 1 finished");
    }               
  }
}

/*BLYNK_WRITE(V21) {  // Called whenever setting Time Input Widget
  TimeInputParam t(param);
  int SThour = t.getStartHour();
  int STmin = t.getStartMinute();
  int STsec = t.getStartSecond();
  int SPhour = t.getStopHour();
  int SPmin = t.getStopMinute();
  int SPsec = t.getStopSecond();
  int now = millis();
  Blynk.virtualWrite(V25, now);
  terminal.println(SThour);
}*/


void setup() 
{
    Blynk.begin(auth);
    rtc.begin(&UDPClient, "north-america.pool.ntp.org");
    rtc.setTimeZone(-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(5000L, sendinfo);
    pinMode(valve1, OUTPUT);

}

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

void shutoffall()
{
    //shut it all down
}


void activetoday(){         // check if schedule #1 should run today
  if(year() != 1970){
    Blynk.syncVirtual(V1);  // sync scheduler #1  
  }
}

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

My problem: sprinklersystem.ino:88:36: ‘hour’ was not declared in this scope
Where can I go to learn about library’s and how they work? Or is that not my problem here?
I’ve tried the TimeLib.h , but couldn’t get it to work and blynk’s time library and RTCWidget doesn’t seem to be available on particle web IDE.

Thanks for taking the time to read through this!

Normally you won’t need SparkTime you can just use Time

Since you are using hour() (with parentheses) this must be a function and with the Time object it would be Time.hour() (same for minute() and second()).

And instead of doing this calculation

  unsigned int nowseconds = ((hour() * 3600) + (minute() * 60) + second());

just use

 unsigned int nowseconds = Time.local() % 86400;

Time.local() will give you the epoch time adjusted for your time zone (when you’ve set Time.zone() appropriately) and the modulo operation (%) will only take the seconds of the current day and discard the date part.

1 Like

Thanks for your help @ScruffR!! I’m getting somewhere now. I’ve got the time input turning on and off a relay now. One thing I don’t quit understand yet is why I’m getting the following:
With:

    Time.zone(-5);   //-2.5

This returns the correct seconds:

unsigned int nowseconds = Time.local() % 86400;

But this returns 5 hours to early:

Blynk.virtualWrite(V100, Time.format(Time.local(), "%r - %a %D"));

The only way to make this read out correct current time is to have -2.5 in time zone.
Any idea how I could get these 2 functions to play along with each other?
Complete Code:

#include <blynk.h>
char auth[] = "***"; 
BlynkTimer timer;
char currentTime[9];
bool clockSync = false;
WidgetTerminal terminal(V30);

// Zone valves
#define valve1 3
#define valve2 4
#define valve3 5
#define valve4 7
#define valve5 8
int mode = 999;
int manuel1 = 0;
int lastmanuel1 = 3;
int auto1 = 0;
int lastauto1 = 3;
//int counts = 0;

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

WidgetLED led1(V1);

BLYNK_WRITE(V0) {
  switch (param.asInt())
  {
    case 1: // OFF
      //Serial.println("Item 1 selected");
      mode = 1;
      Blynk.virtualWrite(V25, mode);
      shutoffall();
      //led1.setColor(BLYNK_RED);
      break;
    case 2: // Manual Mode
      Serial.println("Item 2 selected");
      mode = 2;
      Blynk.virtualWrite(V25, mode);
      //led1.setColor(BLYNK_GREEN);
      break;
    case 3: // Automatic Mode
      Serial.println("Item 3 selected");
      mode = 3;
      Blynk.virtualWrite(V25, mode);
      break;
    default:
      Serial.println("Unknown item selected");
  }
}

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

BLYNK_WRITE(V21) {   // Scheduler #1 Time Input widget  
  TimeInputParam t(param);
  //unsigned int nowseconds = ((hour() * 3600) + (minute() * 60) + second());
  unsigned int nowseconds = Time.local() % 86400;
  Blynk.virtualWrite(V25, nowseconds);
  unsigned int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);  
  unsigned int stopseconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
  Blynk.virtualWrite(V26, startseconds);
  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);
      digitalWrite(valve1, LOW);
      Blynk.virtualWrite(V9, 255);  // turn on virtual LED
      Blynk.notify("Schedule 1 started");
    }                  
    if(nowseconds >= stopseconds - 31 && nowseconds <= stopseconds + 31 ){   // 62s on 60s timer ensures 1 trigger command is sent
      led1.setColor(YELLOW);
      digitalWrite(valve1, HIGH);
      Blynk.virtualWrite(V9, 0);   // turn OFF virtual LED
      Blynk.notify("Schedule 1 finished");
    }               
  }
}

/*BLYNK_WRITE(V21) {  // Called whenever setting Time Input Widget
  TimeInputParam t(param);
  int SThour = t.getStartHour();
  int STmin = t.getStartMinute();
  int STsec = t.getStartSecond();
  int SPhour = t.getStopHour();
  int SPmin = t.getStopMinute();
  int SPsec = t.getStopSecond();
  int now = millis();
  Blynk.virtualWrite(V25, now);
  terminal.println(SThour);
}*/


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(5000L, sendinfo);
    pinMode(valve1, OUTPUT);

}

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

void sendinfo()
{
    Blynk.virtualWrite(V100, Time.format(Time.local(), "%r - %a %D"));
}

void shutoffall()
{
    //shut it all down
}


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

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;
  } 
} 

Blynk Setup:

1 Like

I wonder if this would work? or if it’ll cause other problems

  unsigned int nowseconds = Time.local() % 86400;
  nowseconds = nowseconds - 9000;

and Time.format() will again localize that.
If you only want Time.format() to format the current time then don’t pass in any time parameter.
Try this instead

Blynk.virtualWrite(V100, Time.format("%r - %a %D"));

On the other hand, if you need to formate a specific time (other than current), then you need to take the UTC time (via Time.now()) do your calculations with it and then format it.
Or when taking a timestamp from another source, you need to convert it into UTC before formatting (or as a workaround temporarily reset Time.zone(0.0), format and set the zone again).

2 Likes

Thanks @ScruffR and @lsfarm… . I gave been trying to get the complex timer to work before but have not been able to, so I have been using the simple timer instead.

I will see if I can manage from what I see here.

@lsfarm, quick question, are you using the free BLYNK version or the paid version?

Regards
Friedl.

I’ll give that a try @ScruffR. Thanks!!

@friedl_1977 I’m using the free version of Blynk

@lsfarm

Thanks… me too. I am thinking of signing up for the startup license at $166 as I need to delay some products is simply not possible using the free license.

I also looked into Nymea and IXON, both look feasible and aesthetically pleasing, but will require more a bot work to get going. You will go much further though on their free versions though.

Regards
Friedl.

Interesting links… Thanks!
I’ve seen blynk hint around at a cheaper “individual” license, but it will probably be awhile before anything happens on that note.
It’s kinda the pits for us guys stuck in the middle with ideas on how to solve a problem, but not quite enough resources to build a full blown Blynk, Particle system of our own.

Hi @lsfarm -

UX has been my challenge from the get go, I simply do not understand the pricing models. Blynk is tough, I have been trying to reason with them but to no avail.

Do you require mobile app? I have found Ubidots to work well if web dashboard is required. I need both from time to time, hence my appeal towards Nymea, but seem quite a bit of work to get off the ground. I signed up for some new beta at Blynk but have not heard back yet.