From 1239ce0ae98e8dca06d62818d14be9eb88aa055d Mon Sep 17 00:00:00 2001 From: Chris I-B Date: Mon, 6 Jan 2025 13:43:17 -0500 Subject: [PATCH] Refactor the RTC module to move all of the weekday/month names into classes, add enum-like constants for their integer equivalents. Remove subseconds from the null clock. Remove references to local time offsets from docstrings --- .../experimental/clocks/clock_source.py | 10 +- .../experimental/clocks/null_clock.py | 3 +- software/firmware/experimental/rtc.py | 91 +++++++++++++------ 3 files changed, 66 insertions(+), 38 deletions(-) diff --git a/software/firmware/experimental/clocks/clock_source.py b/software/firmware/experimental/clocks/clock_source.py index c39a2ec64..a7f0d3568 100644 --- a/software/firmware/experimental/clocks/clock_source.py +++ b/software/firmware/experimental/clocks/clock_source.py @@ -1,16 +1,14 @@ """ Interface for interacting with realtime clock hardware. -For simplicity, we always assume that the external clock source is synchronized with UTC. This means -your I2C clocks should be set to UTC time, not local time. To configure the time zone offset, use -experimental_config to set the desired offset hours and minutes. For regions using Daylight Savings -time (most of North America, western Europe, Australia, and New Zealand, among others) you will -need to manually adjust your config file to keep local time properly adjusted. +For consistency, we always assume that the external clock source is synchronized with UTC. This means +your I2C clock should be set to UTC time, not local time. If you set your I2C clock to local time +some scripts may behave incorrectly. The Raspberry Pi Pico (and official variants like the Pico W, Pico 2, etc...) does NOT include a realtime clock. All RTC implementations rely on some external reference time, e.g. - external hardware (e.g. an I2C-supported external clock module) -- an wireless connection and an accessible NTP server +- a wireless connection and an accessible NTP server The external clock source must implement the ExternalClockSource class """ diff --git a/software/firmware/experimental/clocks/null_clock.py b/software/firmware/experimental/clocks/null_clock.py index f71a140f6..13d272736 100644 --- a/software/firmware/experimental/clocks/null_clock.py +++ b/software/firmware/experimental/clocks/null_clock.py @@ -25,7 +25,6 @@ def set_datetime(self, datetime): def datetime(self): t = ticks_ms() - ms = t % 1000 s = (t // 1000) % 60 m = (t // (1000 * 60)) % 60 h = (t // (1000 * 60 * 60)) % 24 @@ -34,4 +33,4 @@ def datetime(self): yy = 1970 wd = (4 + dd) % 7 # 1 jan 1970 was a thursday - return (yy, mm, dd, h, m, s + ms / 1000.0, wd) + return (yy, mm, dd, h, m, s, wd) diff --git a/software/firmware/experimental/rtc.py b/software/firmware/experimental/rtc.py index c009ff749..b45d933e5 100644 --- a/software/firmware/experimental/rtc.py +++ b/software/firmware/experimental/rtc.py @@ -12,35 +12,6 @@ import europi from experimental.experimental_config import RTC_NONE, RTC_DS1307, RTC_DS3231 -# Weekdays are represented by an integer 1-7 -# ISO 8601 specifies the week starts on Monday -WeekdayNames = { - 1: "Monday", - 2: "Tuesday", - 3: "Wednesday", - 4: "Thursday", - 5: "Friday", - 6: "Saturday", - 7: "Sunday", -} - -# Months are specified as an integer 1-12 -# Shortened names can be extracted using the first 3 letters -MonthNames = { - 1: "January", - 2: "February", - 3: "March", - 4: "April", - 5: "May", - 6: "June", - 7: "July", - 8: "August", - 9: "September", - 10: "October", - 11: "November", - 12: "December", -} - class DateTimeIndex: """ @@ -58,6 +29,66 @@ class DateTimeIndex: WEEKDAY = 6 +class Month: + """ + Container class for month names + """ + + JANUARY = 1 + FEBRUARY = 2 + MARCH = 3 + APRIL = 4 + MAY = 5 + JUNE = 6 + JULY = 7 + AUGUST = 8 + SEPTEMBER = 9 + OCTOBER = 10 + NOVEMBER = 11 + DECEMBER = 12 + + NAME = { + 1: "January", + 2: "February", + 3: "March", + 4: "April", + 5: "May", + 6: "June", + 7: "July", + 8: "August", + 9: "September", + 10: "October", + 11: "November", + 12: "December", + } + + +class Weekday: + """ + Container class for weekday names + + ISO 8601 specifies the week starts on Monday (1) and ends on Sunday (7) + """ + + MONDAY = 1 + TUESDAY = 2 + WEDNESDAY = 3 + THURSDAY = 4 + FRIDAY = 5 + SATURDAY = 6 + SUNDAY = 7 + + NAME = { + 1: "Monday", + 2: "Tuesday", + 3: "Wednesday", + 4: "Thursday", + 5: "Friday", + 6: "Saturday", + 7: "Sunday", + } + + class RealtimeClock: """ A continually-running clock that provides the day & date. @@ -90,7 +121,7 @@ def __str__(self): """ t = self.now() if len(t) > DateTimeIndex.WEEKDAY: - return f"{WeekdayNames[t[DateTimeIndex.WEEKDAY]]} {t[DateTimeIndex.YEAR]}/{t[DateTimeIndex.MONTH]:02}/{t[DateTimeIndex.DAY]:02} {t[DateTimeIndex.HOUR]:02}:{t[DateTimeIndex.MINUTE]:02}:{t[DateTimeIndex.SECOND]:02}" + return f"{Weekday.NAME[t[DateTimeIndex.WEEKDAY]]} {t[DateTimeIndex.YEAR]}/{t[DateTimeIndex.MONTH]:02}/{t[DateTimeIndex.DAY]:02} {t[DateTimeIndex.HOUR]:02}:{t[DateTimeIndex.MINUTE]:02}:{t[DateTimeIndex.SECOND]:02}" elif len(t) > DateTimeIndex.SECOND: return f"{t[DateTimeIndex.YEAR]}/{t[DateTimeIndex.MONTH]:02}/{t[DateTimeIndex.DAY]:02} {t[DateTimeIndex.HOUR]:02}:{t[DateTimeIndex.MINUTE]:02}:{t[DateTimeIndex.SECOND]:02}" else: