wwvbtk: Use datetime for timekeeping

I don't know if it's *better* but `WWVBMinuteIERS(*key)` rubbed me
the wrong way.
This commit is contained in:
Jeff Epler 2025-04-20 13:26:40 +02:00
parent aae3828270
commit 4e0d7a9743

View file

@ -6,8 +6,8 @@
# SPDX-License-Identifier: GPL-3.0-only # SPDX-License-Identifier: GPL-3.0-only
from __future__ import annotations from __future__ import annotations
import datetime
import functools import functools
import time
from tkinter import Canvas, TclError, Tk from tkinter import Canvas, TclError, Tk
from typing import TYPE_CHECKING, Any from typing import TYPE_CHECKING, Any
@ -66,24 +66,22 @@ def main(colors: list[str], size: int, min_size: int | None) -> None: # noqa: P
if min_size is None: if min_size is None:
min_size = size min_size = size
def deadline_ms(deadline: float) -> int: def deadline_ms(deadline: datetime.datetime) -> int:
"""Compute the number of ms until a deadline""" """Compute the number of ms until a deadline"""
now = time.time() now = datetime.datetime.now(datetime.timezone.utc)
return int(max(0, deadline - now) * 1000) return int(max(0, (deadline - now).total_seconds()) * 1000)
def wwvbtick() -> Generator[tuple[float, wwvb.AmplitudeModulation], None, None]: def wwvbtick() -> Generator[tuple[datetime.datetime, wwvb.AmplitudeModulation]]:
"""Yield consecutive values of the WWVB amplitude signal, going from minute to minute""" """Yield consecutive values of the WWVB amplitude signal, going from minute to minute"""
timestamp = time.time() // 60 * 60 timestamp = datetime.datetime.now(datetime.timezone.utc).replace(second=0, microsecond=0)
while True: while True:
tt = time.gmtime(timestamp) timecode = wwvb.WWVBMinuteIERS.from_datetime(timestamp).as_timecode()
key = tt.tm_year, tt.tm_yday, tt.tm_hour, tt.tm_min
timecode = wwvb.WWVBMinuteIERS(*key).as_timecode()
for i, code in enumerate(timecode.am): for i, code in enumerate(timecode.am):
yield timestamp + i, code yield timestamp + datetime.timedelta(seconds=i), code
timestamp = timestamp + 60 timestamp = timestamp + datetime.timedelta(seconds=60)
def wwvbsmarttick() -> Generator[tuple[float, wwvb.AmplitudeModulation], None, None]: def wwvbsmarttick() -> Generator[tuple[datetime.datetime, wwvb.AmplitudeModulation]]:
"""Yield consecutive values of the WWVB amplitude signal """Yield consecutive values of the WWVB amplitude signal
.. but deal with time progressing unexpectedly, such as when the .. but deal with time progressing unexpectedly, such as when the
@ -94,10 +92,10 @@ def main(colors: list[str], size: int, min_size: int | None) -> None: # noqa: P
""" """
while True: while True:
for stamp, code in wwvbtick(): for stamp, code in wwvbtick():
now = time.time() now = datetime.datetime.now(datetime.timezone.utc)
if stamp < now - 60: if stamp < now - datetime.timedelta(seconds=60):
break break
if stamp < now - 1: if stamp < now - datetime.timedelta(seconds=1):
continue continue
yield stamp, code yield stamp, code
@ -137,7 +135,7 @@ def main(colors: list[str], size: int, min_size: int | None) -> None: # noqa: P
yield deadline_ms(stamp) yield deadline_ms(stamp)
led_on(code) led_on(code)
app.update() app.update()
yield deadline_ms(stamp + 0.2 + 0.3 * int(code)) yield deadline_ms(stamp + datetime.timedelta(seconds=0.2 + 0.3 * int(code)))
led_off(code) led_off(code)
app.update() app.update()