Pat <p...@obrienphoto.net> writes:

> I don't know why, but I'm fascinated with this small bit of code. I always 
> wondered how the archive interval runs on the 5th minute reliably (on a 
> vanilla install). It doesn't matter when you start weewx, it'll run on that 
> 5th minute interval. If I start weewx at 8:31, I'll get an archive (most 
> times) at 8:35. That got me thinking it's not a sleep, but something else. 

This sort of rounding code is remarkably tricky.

> So I dug and I found the magic timer a few months ago 
> <https://github.com/weewx/weewx/blob/master/bin/weewx/engine.py#L531>, but 
> I've been stuck on trying to understand the math behind it. Is someone able 
> to explain this in laymans terms? 
>
> Let's say these are the variables:
>
> int(self.engine._get_console_time() = 1567470965
> self.archive_interval = 300
>
> If I take a the console time (1567470965), divide it by 300, I get 5224903
> Then adding 1 is easy, I get 5224904
> Then multiplying this by 300 gives me the time ahead on the 5th minute, 
> or 1567471200
>
> I have no idea how or why that +1 alters the end result. It's just adding a 
> second to the timestamp.

The key points in this code are:

  The time is divided by the archive interval, to get a value that is in
  terms of (floating point) archive intervals since the epoch.

  This floating point archive interval value is converted to integer via
  what looks like a cast (to mee who knows C better than python).  I am
  guessing this is truncation.  So this gets an integer number of
  archive intervals.

  1 is added, but this is not 1 second, but 1 archive interval.  For the
  usual 5 min, this moves ahead 1 in the vairable, which represents 5
  minutes.

  Multiplying back by the archive interval converts a value in archive
  intervals since the epoch to seconds since the epoch.

Further trickiness:

  There is an asssumption that if the archive interval is 5 minutes,
  that means at 00:00:00 on a day and every 5 minutes thereafter.  This
  is how davis seems to do it (and that seems entirely sensible).

  There is no concern for leap seconds.  With the archive_delay guard
  time, and leap seconds being positive these days, that won't matter.

  If you were to call this when the time was exactly on a 5min boundary,
  it would return the next one, 5 min away, but if a second early, only
  one second in the future.  E.g input 091459, output 091500, input
  091500, output 092000.

  That seems to be what's intended, but perhaps one could subtract off
  the guard time if you wanted to do the loop processing if you could,
  so that if you started at 073509, you'd return 073500 and sample at
  073515.  But that's too clever for its own good, but it's 2x or 3x as
  hard to debug code as to write it, and if one wriets code at the limit
  of your cleverness one will never get it to work reliably!

  I hope the times are ints, so that we don't get into float/float and
  having that be very sensitive to exact rounding.  Even so the IEEE754
  spec is amazing and it's probably ok.

> (int( 1567470965 / 300) + 1) * 300 = 1567471200
>
> I think it's pretty cool how this works!

Indeed - a lot going on in one line to understand.

-- 
You received this message because you are subscribed to the Google Groups 
"weewx-development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to weewx-development+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/weewx-development/rmi5zmab3ex.fsf%40s1.lexort.com.

Reply via email to