Resetting variable at midnight

So I got my Photon set up as a weather station,but I need to somehow make the variable that counts total rain reset at midnight (CET) to zero,else rain just adds up and never resets. What would be the best way to do that?

Check to see if the time.hours and time.Minutes match those of midnight, then act upon it?

2 Likes

The simplest check would be to do this

void loop() {
  static int previousDay = 0;
  if (Time.day() != previousDay) {
    previousDay = Time.day();
    // do the reset stuff
  }
  ...
}

This way you’ll reset whenever a new day is detected, irrespective how long your device has been occupied with other stuff. With a check for 00:00 you might miss the turn of day if your code just happened to block for exactly that minute (or would fire multiple times during that same minute).

3 Likes

Here’s my solution…both for a weather station resetting daily variables, and my computer room monitor performing a daily time synch:

if (Time.hour() == 12)                                // Everyday, Midnight?
{
    if (Time.minute() == 5 && dailyTimeSync == false)       // 12:05:00-59 am and haven't synched time?
    {
        Particle.syncTime();
        dailyTimeSync = true;
        emailIDIndex = 1;                                   // My "reset stuff"
        return;
    }
    else if (Time.minute() == 6)                            // Reset flag at 12:06:00-59
    {
        dailyTimeSync = false;
        return;
    }
}

I chose a small window (12:05:00-59) to allow for some variability in what’s going on at that moment. Over time it usually fires at 12:05:00. I handle the “multiple fire” issue by setting a flag that turns on when the initial resets are performed and the flag is reset at 12:06.

@ScruffR, wouldn’t your solution cause one potential problem during the initial startup? It seems that when the program starts initially, the “reset stuff” would occur immediately since previousDay != Time.day()? Going forward your solution is much cleaner than mine, but I can’t help but think the initial start could be a problem unless you waited until midnight to start the application for the first time.

Am I missing something obvious?

What data would there be to be lost on startup? If loop() never had run before, wouldn't all the variables be at their initial state anyway?
On the other hand you could still have previousDay declared gloabally and retained and then it'd even work after a reset and on first run you'd initialise it in setup() to previousDay = Time.day().

I see your point. I wasn’t thinking that when you startup, all of the normal variables are set to some initial value. In this case this would include rain levels, counters, etc.

I would agree that setting previousDay = Time.day() in setup() would be my choice. Not that it would cause any problems, but I still like knowing that regardless of the time of day you start the program, it won’t actually perform any “reset functions” until midnight of that first day and then at midnight going forward.

Thanks for clearing up my question.

On a similar note, I also have a need to perform a task on a particular day of the week, at a particular time. Right now, I’m having to check for the day of the week, the hour and then the minute. I prepare and send my email and set a flag indicating the email has been sent. I’m wondering if @ScruffR’s technique could help me reduce the amount of if statements. Here is the current code:

if (Time.weekday() == MONDAY)
{
    if (Time.hour() == 6)                                   // 6 am?
    {
        if (Time.minute() == 58 && weeklyEmailSent == false)        // 6:58:00-59am and haven't sent email?
        {
            sendAlertEmails(WEEKLYSTATUS);
            weeklyEmailSent = true;
        }
        else if (Time.minute() == 59)                       // Reset flag at 6:59:00-59am
            weeklyEmailSent = false;
    }
}
if (Time.weekday() == MONDAY && Time.hour() == 6)
{   
        if (Time.minute() == 58 && weeklyEmailSent == false)        // 6:58:00-59am and haven't sent email?
        {
            sendAlertEmails(WEEKLYSTATUS);
            weeklyEmailSent = true;
        }
        else if (Time.minute() == 59)                       // Reset flag at 6:59:00-59am
        {    
            weeklyEmailSent = false;
        }
}

This would save you one ‘if’.

True…thanks…always like to optimize whenever possible.

1 Like

If checking for a particular time I'd rather go with if (Time.local() % 86400 >= timeToAct && Time.day() != previousDay)for exactly the same reason as given above.

timeToAct would be hh* 3600 + mm*60 + ss.

When checking for timestamps and/or floating point values an equality check (==) should be avoided whenever possible. Opt for >=, <=, != or a range check.

You have to consider what initial values your variables have.
Fortunately all unitialised global variables get initialised to 0 by the compiler. But that is not the case for all languages and for local/automatic variables it's never the case. Hence you need to be aware of the fact and act accordingly.

1 Like

@ScruffR I wasn’t saying that I didn’t take into account initial values. I always initialize every variable, even when I know they are initialized by a particular compiler. I was saying that I didn’t stop to think that things like rain count wouldn’t have increased fast enough for your code to reset the value to 0 during the first run through of the code. But thanks for the reminder.

Not sure how that would happen or play a role.
When the system starts up at any arbitrary time during any given day, all accumulated values for that day are not telling the whole story of the day anyway.

I may just be missing the point. I was just assuming that the respective variables were initialised to 0 (irrespective whether by compiler or you). And in that case just resetting them to 0 again won't cause any harm.
But - of course - if the variables were retained or you did initialise them to some meaningful value retrieved from some other source (which wasn't part of the OP's question) the global variable initialised in setup() would be the way to go.

That's where answering in a thread without the full set of background info assumptions must be made.

I'm also somewhat confused by the discrepancy

vs.

Suggestion to prevent this code from continuously executing for 60 seconds:

else if (dailyTimeSync && Time.minute() == 6)   

Also I'm assuming you are checking if(Time.isAM()) somewhere before this code to prevent it from resetting at noon? This is why I prefer 24-hour mode :slight_smile:

2 Likes

@BDub I had actually already made that change to my code, but thanks for the suggestion. I had added a syslog statement inside the loop and noticed the syslog server started screaming with log entries. My first attempt was to limit the seconds from 30-59 and then I just changed it to match the flag as you listed above.

In my current code I do check for Time.hour() = 0.

1 Like