http://qs321.pair.com?node_id=1176656


in reply to Logical ways to calculate being within two times

For completeness, and for a bit of content on the typically lower volume Sunday...

Set the time, called only once, upon initial loading of the webapp:

$api->set_light_times;

Sets the light timers... once on initialization of the app as a whole, and then again every time the light-off is triggered:

sub set_light_times { my ($self) = @_; my $on_at = $self->_config_light('on_at'); my $time = time; $time += 60 until localtime($time) =~ /$on_at:/; my $hrs = $self->_config_light('on_hours'); my $on_time = $time; my $off_time = $on_time + $hrs * 3600; my $now = time; # check if the until() loop set things beyond today's # on period if ($now > ($on_time - 86400) && $now < ($off_time - 86400)){ $on_time -= 24 * 3600; $off_time -= 24 * 3600; } $self->db()->update( 'light', 'value', $on_time, 'id', 'on_time' ); $self->db()->update( 'light', 'value', $off_time, 'id', 'off_time' ); }

...and the action logic itself:

sub action_light { my ($self) = @_; my $log = $log->child('action_light'); my $on_hours = $self->_config_light('on_hours'); my $aux = $self->_config_control('light_aux'); my $pin = $self->aux_pin($aux); my $on_time = $self->_config_light('on_time'); my $off_time = $self->_config_light('off_time'); my $now = time; if (($on_hours == 24) || ($now > $on_time && $now < $off_time)){ if (! $self->aux_state($aux)){ $self->aux_state($aux, ON); pin_mode($pin, OUTPUT); write_pin($pin, HIGH); } } elsif ($self->aux_state($aux)){ $self->aux_state($aux, OFF); pin_mode($pin, OUTPUT); write_pin($pin, LOW); $self->set_light_times; } }

Replies are listed 'Best First'.
Re^2: Logical ways to calculate being within two times
by BrowserUk (Patriarch) on Nov 28, 2016 at 19:47 UTC

    One possible caveat of the epoch time calculation.

    If you set a time that happens to coincide to the minute, with the subtraction of a leap second, then the until loop may never terminate.

    The solution is to add 30 rather than 60 each iteration.

    Of course, if your processor doesn't use NTP or some similar method to synchronise its system clock, the problem is probably moot.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
    In the absence of evidence, opinion is indistinguishable from prejudice.

      My experience says that leap seconds do not impact epoch time (note that after inserting 26 leap seconds, the epoch time at the top of a minute is still currently a multiple of 60, whether using UTC or not). And, when you think about it, they can't.

      Leap seconds are not scheduled very far in advance but epoch times for years in the future have been being used for years in the past. So leap seconds can't impact (Unix-style) epoch time values else past calculations of future dates would become inaccurate.

      - tye        

        My experience says that leap seconds do not impact epoch time ... And, when you think about it, they can't.

        You missed the point. I was not describing a problem with epoch times per se; but rather my method of deriving them.

        The loop relies upon hitting every minute so as to ensure it will terminate. When the required minute is reached.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re^2: Logical ways to calculate being within two times
by Anonymous Monk on Nov 28, 2016 at 23:46 UTC

    To guard against the infinite loop / leapsecond / 59 second minute

    my $failsafe = 0; $time += 60 until localtime($time) =~ /$on_at:/ or $failsafe++ > +10_000;

    Adjust the failsafe cutoff until its just large enough but not too large :) If it slows down this approach change it :) maybe use strptime

      That breaks the loop, but doesn't fix up the problem.

      Adding 30 instead of 60 prevents the problem completely and runs more quickly.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
      In the absence of evidence, opinion is indistinguishable from prejudice.

        Just came across this article this morning. Google is, instead of doing the leap second, is going to slow their clocks on their NTP servers by 0.0014% over the 10 hours before and 10 hours after the leap second.

        Also, they've opened up these servers to the public.

        ps. I changed my code with the 30 second modification.