]> git.earman.xyz Git - sensor-watch.git/commitdiff
Day roll back repeat fix
authorDavid Volovskiy <devolov@gmail.com>
Sat, 3 Aug 2024 12:46:34 +0000 (08:46 -0400)
committerDavid Volovskiy <devolov@gmail.com>
Sat, 3 Aug 2024 13:39:02 +0000 (09:39 -0400)
movement/watch_faces/clock/clock_face.c
movement/watch_faces/clock/simple_clock_face.c
movement/watch_faces/settings/set_time_face.c
movement/watch_faces/settings/set_time_hackwatch_face.c
watch-library/shared/watch/watch_utility.c

index 68019d8582b3985a292ba6624faafe653231ceb1..f9ec58a90de5781938d54d9fc466c4cdc251d146 100644 (file)
@@ -280,27 +280,31 @@ void clock_face_resign(movement_settings_t *settings, void *context) {
     (void) context;
 }
 
-static void check_and_act_on_daylight_savings(bool dst_active, watch_date_time date_time) {
-    if (!dst_active) return;
-    uint8_t dst_result = is_dst(date_time);
-    switch (dst_result)
-    {
-    case DST_STARTED:
-        date_time.unit.hour = (date_time.unit.hour + 1) % 24;
-        break;
-    case DST_ENDING:
+static void check_and_act_on_daylight_savings(movement_settings_t *settings, watch_date_time date_time) {
+    if (!settings ->bit.dst_active) return;
+    uint8_t dst_result = get_dst_status(date_time);
+
+    if (settings ->bit.dst_skip_rolling_back && dst_result == DST_ENDED) {
+        settings ->bit.dst_skip_rolling_back = false;
+        return;
+    }
+    else if (dst_result == DST_ENDING && !settings ->bit.dst_skip_rolling_back) {
+        settings ->bit.dst_skip_rolling_back = true;
         date_time.unit.hour = (date_time.unit.hour + 24 - 1) % 24;
-        break;
-    default:
+        watch_rtc_set_date_time(date_time);
         return;
     }
-    watch_rtc_set_date_time(date_time);
+    else if (dst_result == DST_STARTING) {
+        date_time.unit.hour = (date_time.unit.hour + 1) % 24;
+        watch_rtc_set_date_time(date_time);
+        return;    
+    }
 }
 
 bool clock_face_wants_background_task(movement_settings_t *settings, void *context) {
     clock_state_t *state = (clock_state_t *) context;
     watch_date_time date_time = watch_rtc_get_date_time();
-    check_and_act_on_daylight_savings(settings->bit.dst_active, date_time);
+    check_and_act_on_daylight_savings(settings, date_time);
     if (!state->time_signal_enabled) return false;
 
     return date_time.unit.minute == 0;
index c0f837238646ca0cb61ea9dd5863125ae4bcf76c..a7e08a9da3fd5c81f09aeade84c104045118d911 100644 (file)
@@ -150,27 +150,31 @@ void simple_clock_face_resign(movement_settings_t *settings, void *context) {
     (void) context;
 }
 
-static void check_and_act_on_daylight_savings(bool dst_active, watch_date_time date_time) {
-    if (!dst_active) return;
-    uint8_t dst_result = is_dst(date_time);
-    switch (dst_result)
-    {
-    case DST_STARTED:
-        date_time.unit.hour = (date_time.unit.hour + 1) % 24;
-        break;
-    case DST_ENDING:
+static void check_and_act_on_daylight_savings(movement_settings_t *settings, watch_date_time date_time) {
+    if (!settings ->bit.dst_active) return;
+    uint8_t dst_result = get_dst_status(date_time);
+
+    if (settings ->bit.dst_skip_rolling_back && (dst_result == DST_ENDED)) {
+        settings ->bit.dst_skip_rolling_back = false;
+        return;
+    }
+    else if (dst_result == DST_ENDING && !settings ->bit.dst_skip_rolling_back) {
+        settings ->bit.dst_skip_rolling_back = true;
         date_time.unit.hour = (date_time.unit.hour + 24 - 1) % 24;
-        break;
-    default:
+        watch_rtc_set_date_time(date_time);
         return;
     }
-    watch_rtc_set_date_time(date_time);
+    else if (dst_result == DST_STARTING) {
+        date_time.unit.hour = (date_time.unit.hour + 1) % 24;
+        watch_rtc_set_date_time(date_time);
+        return;    
+    }
 }
 
 bool simple_clock_face_wants_background_task(movement_settings_t *settings, void *context) {
     simple_clock_state_t *state = (simple_clock_state_t *)context;
-    watch_date_time date_time = watch_rtc_get_date_time();
-    check_and_act_on_daylight_savings(settings->bit.dst_active, date_time);
+    date_time = watch_rtc_get_date_time();
+    check_and_act_on_daylight_savings(settings, date_time);
     if (!state->signal_enabled) return false;
 
     return date_time.unit.minute == 0;
index b16cb6d17b24c369142d3be18f2e392492fdbc74..3f7d0c76a1474814a4c88f0d1ea5cc7b28b8042d 100644 (file)
@@ -72,6 +72,7 @@ static void _handle_alarm_button(movement_settings_t *settings, watch_date_time
             break;
     }
     watch_rtc_set_date_time(date_time);
+    settings->bit.dst_skip_rolling_back = false;
 }
 
 static void _abort_quick_ticks() {
index bdd1b0a61ddabeae2b96d956594d44769e3ca449..be293abae543506c1e41a7af259314d7fbd9e177 100644 (file)
@@ -94,6 +94,7 @@ bool set_time_hackwatch_face_loop(movement_event_t event, movement_settings_t *s
                 }
                 date_time_settings.unit.second = 0;
                 watch_rtc_set_date_time(date_time_settings);
+                settings->bit.dst_skip_rolling_back = false;
             }
             break;
         case EVENT_ALARM_BUTTON_DOWN:
@@ -134,8 +135,10 @@ bool set_time_hackwatch_face_loop(movement_event_t event, movement_settings_t *s
                     }
                     break;
             }
-            if (current_page != 2) // Do not set time when we are at seconds, it was already set previously
+            if (current_page != 2) // Do not set time when we are at seconds, it was already set previously
                 watch_rtc_set_date_time(date_time_settings);
+                settings->bit.dst_skip_rolling_back = false;
+            }
             break;
         
         case EVENT_ALARM_LONG_UP://Setting seconds on long release
@@ -178,8 +181,10 @@ bool set_time_hackwatch_face_loop(movement_event_t event, movement_settings_t *s
                     if (settings->bit.time_zone > 40) settings->bit.time_zone = 0;
                     break;
             }
-            if (current_page != 2) // Do not set time when we are at seconds, it was already set previously
+            if (current_page != 2) // Do not set time when we are at seconds, it was already set previously
                 watch_rtc_set_date_time(date_time_settings);
+                settings->bit.dst_skip_rolling_back = false;
+            }
             //TODO: Do not update whole RTC, just what we are changing
             break;
         case EVENT_TIMEOUT:
index 1410e41413be219bcefda935324531412470eede..5938b60636bd0ce6f449d14e935d85ca404adfcc 100644 (file)
@@ -83,38 +83,43 @@ uint8_t is_leap(uint16_t y)
        return !(y%4) && ((y%100) || !(y%400));
 }
 
-uint8_t is_dst(watch_date_time date_time) {
-    uint8_t weekday_first_of_month;
+uint8_t get_dst_status(watch_date_time date_time) {
     watch_date_time dst_start_time;
     watch_date_time dst_end_time;
     uint32_t unix_dst_start_time;
     uint32_t unix_dst_end_time;
     uint32_t unix_curr_time;
 
+    dst_start_time.unit.year = date_time.unit.year;
     dst_start_time.unit.month = 3;
     dst_start_time.unit.hour = 2;
     dst_start_time.unit.minute = 0;
     dst_start_time.unit.second = 0;
-    weekday_first_of_month = watch_utility_get_iso8601_weekday_number(date_time.unit.year, dst_start_time.unit.month, 1);
-    dst_start_time.unit.day = 15 - weekday_first_of_month;
+    dst_start_time.unit.day = 15 - watch_utility_get_iso8601_weekday_number(dst_start_time.unit.year + WATCH_RTC_REFERENCE_YEAR, dst_start_time.unit.month, 1);
     unix_dst_start_time = watch_utility_date_time_to_unix_time(dst_start_time, 0);
 
+    dst_end_time.unit.year = date_time.unit.year;
     dst_end_time.unit.month = 11;
     dst_end_time.unit.hour = 2;
     dst_end_time.unit.minute = 0;
     dst_end_time.unit.second = 0;
-    weekday_first_of_month = watch_utility_get_iso8601_weekday_number(date_time.unit.year, dst_end_time.unit.month, 1);
-    dst_end_time.unit.day = 15 - weekday_first_of_month;
+    dst_end_time.unit.day = 15 - watch_utility_get_iso8601_weekday_number(dst_end_time.unit.year + WATCH_RTC_REFERENCE_YEAR, dst_end_time.unit.month, 1);
     unix_dst_end_time = watch_utility_date_time_to_unix_time(dst_end_time, 0);
 
+    if (date_time.unit.second > 45)  // In emu, it's been seen that we may trigger at 59sec rather than exactly 0 each time
+        date_time.unit.minute = (date_time.unit.minute + 1) % 60;
     date_time.unit.second = 0;
     unix_curr_time = watch_utility_date_time_to_unix_time(date_time, 0);
 
-    if (unix_curr_time == unix_dst_start_time) return DST_STARTED;
+    if (unix_curr_time == unix_dst_start_time) return DST_STARTING;
     if (unix_curr_time == unix_dst_end_time) return DST_ENDING;
     if (unix_curr_time > unix_dst_end_time || unix_curr_time < unix_dst_start_time) return DST_ENDED;
     return DST_OCCURRING;
-} 
+}
+
+bool dst_occurring(watch_date_time date_time) {
+    return get_dst_status(date_time) <= DST_OCCURRING;
+}
 
 uint16_t watch_utility_days_since_new_year(uint16_t year, uint8_t month, uint8_t day) {
     uint16_t DAYS_SO_FAR[] = {