From 03dddba8d56cb611f49042dfeee10a29995c4596 Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Mon, 27 Mar 2023 20:33:56 +0200 Subject: [PATCH] Fix DST --- .idea/plant-badge.iml | 1 + requirements.txt | 1 + src/apps/plant.py | 8 ++++++-- src/dst.py | 22 ++++++++++++++++++++++ tasks.py | 15 +++++++++++++++ test/test_time.py | 38 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 src/dst.py create mode 100644 test/test_time.py diff --git a/.idea/plant-badge.iml b/.idea/plant-badge.iml index 507a284..34acb50 100644 --- a/.idea/plant-badge.iml +++ b/.idea/plant-badge.iml @@ -10,6 +10,7 @@ + diff --git a/requirements.txt b/requirements.txt index 55c4abe..8552e7c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ pre-commit requests Pillow pyyaml +pytest diff --git a/src/apps/plant.py b/src/apps/plant.py index 38d39ab..9c3419d 100644 --- a/src/apps/plant.py +++ b/src/apps/plant.py @@ -12,6 +12,7 @@ from badger_with_clock import Badger2040 from badger_os import get_battery_level import secrets +from dst import fix_dst from secrets import HA_BASE_URL, HA_ACCESS_TOKEN @@ -251,8 +252,7 @@ def display_header(text): display.text(text, 3, 4) # Display time - _, _, _, hour, minute, _, _ = display.rtc.datetime() - hour = (hour + 1) % 24 + hour, minute = get_time() time = f"{hour:02d}:{minute:02d}" time_offset = display.measure_text(time) + 3 display.text(time, WIDTH - time_offset, 4) @@ -264,4 +264,8 @@ def display_header(text): display.text(battery, WIDTH - time_offset - battery_offset, 4) +def get_time(): + return fix_dst(*display.rtc.datetime()) + + main() diff --git a/src/dst.py b/src/dst.py new file mode 100644 index 0000000..8f8eb3b --- /dev/null +++ b/src/dst.py @@ -0,0 +1,22 @@ +def fix_dst(year, month, day, hour, minute, second, dow): + last_sunday = get_last_sunday_date(day, dow) + past_last_sunday = day >= last_sunday + if ( + 4 <= month <= 9 + or (month == 3 and past_last_sunday) + or (month == 10 and not past_last_sunday) + ): + delta = 2 + else: + delta = 1 + hour = (hour + delta) % 24 + return hour, minute + + +def get_last_sunday_date(day, dow): + until_end_of_month = 31 - day + weeks_to_add = until_end_of_month // 7 + 1 + last_sunday = day + weeks_to_add * 7 - dow - 1 + if last_sunday > 31: + last_sunday -= 7 + return last_sunday diff --git a/tasks.py b/tasks.py index 23cf854..ef2c2be 100644 --- a/tasks.py +++ b/tasks.py @@ -1,4 +1,5 @@ import ast +import os import subprocess import time from pathlib import Path @@ -9,6 +10,7 @@ from invoke import task, Context BASE_DIR = Path(__file__).parent.resolve(strict=True) SRC_DIR = BASE_DIR / "src" +TESTS_DIR = BASE_DIR / "test" MICROPYTHON_DEPENDENCIES = [ # "github:miguelgrinberg/microdot/src/microdot.py", @@ -16,6 +18,19 @@ MICROPYTHON_DEPENDENCIES = [ ] +@task +def test(c: Context) -> None: + """Run tests.""" + with c.cd(BASE_DIR): + path = os.getenv("PYTHONPATH", "") + c.run( + "pytest", + pty=True, + echo=True, + env={"PYTHONPATH": f"{SRC_DIR}:{path}"}, + ) + + @task(name="list") def list_boards(c: Context) -> None: """List connected boards with mpremote.""" diff --git a/test/test_time.py b/test/test_time.py new file mode 100644 index 0000000..3203b55 --- /dev/null +++ b/test/test_time.py @@ -0,0 +1,38 @@ +import pytest + +from dst import fix_dst, get_last_sunday_date + + +@pytest.mark.parametrize( + "year, month, day, hour, minute, second, dow, expected", + [ + (2023, 3, 2, 17, 22, 0, 3, (18, 22)), + (2023, 3, 25, 17, 22, 0, 5, (18, 22)), + (2023, 3, 26, 17, 22, 0, 6, (19, 22)), + (2023, 3, 27, 17, 22, 0, 0, (19, 22)), + (2023, 3, 28, 17, 22, 0, 1, (19, 22)), + (2023, 10, 2, 17, 22, 0, 0, (19, 22)), + (2023, 10, 28, 17, 22, 0, 5, (19, 22)), + (2023, 10, 29, 17, 22, 0, 6, (18, 22)), + (2023, 10, 30, 17, 22, 0, 0, (18, 22)), + (2023, 10, 31, 17, 22, 0, 1, (18, 22)), + ], +) +def test_fix_dst(year, month, day, hour, minute, second, dow, expected): + assert fix_dst(year, month, day, hour, minute, second, dow) == expected + + +@pytest.mark.parametrize( + "day, dow, expected", + [ + (2, 3, 26), + (15, 2, 26), + (25, 5, 26), + (17, 0, 30), + (24, 5, 25), + (27, 0, 26), + (31, 2, 28), + ], +) +def test_get_last_sunday_date(day, dow, expected): + assert get_last_sunday_date(day, dow) == expected