]> git.earman.xyz Git - sensor-watch.git/commitdiff
movement internal time is now UTC
authorjoeycastillo <joeycastillo@utexas.edu>
Sat, 5 Oct 2024 05:27:07 +0000 (01:27 -0400)
committerjoeycastillo <joeycastillo@utexas.edu>
Sat, 5 Oct 2024 14:36:58 +0000 (10:36 -0400)
movement.c
movement.h
movement_config.h
watch-faces/clock/beats_face.c
watch-faces/clock/clock_face.c
watch-faces/clock/world_clock_face.c
watch-faces/complication/advanced_alarm_face.c
watch-faces/complication/countdown_face.c
watch-faces/complication/sunrise_sunset_face.c
watch-faces/sensor/voltage_face.c
watch-faces/settings/set_time_face.c

index 27d55e4250b25c3780e9f7a3b3dd904d30ecdbda..dd3091aead3255ac23ccdf584fa273a948a7a6ed 100644 (file)
@@ -32,6 +32,7 @@
 #include <stdio.h>
 #include "app.h"
 #include "watch.h"
+#include "watch_utility.h"
 #include "usb.h"
 #include "watch_usb_cdc.h"
 #include "watch_private.h"
@@ -70,6 +71,19 @@ void yield(void) {
     tud_task();
     cdc_task();
 }
+
+static udatetime_t _movement_convert_date_time_to_udate(watch_date_time date_time) {
+    return (udatetime_t) {
+        .date.dayofmonth = date_time.unit.day,
+        .date.dayofweek = dayofweek(UYEAR_FROM_YEAR(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR), date_time.unit.month, date_time.unit.day),
+        .date.month = date_time.unit.month,
+        .date.year = UYEAR_FROM_YEAR(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR),
+        .time.hour = date_time.unit.hour,
+        .time.minute = date_time.unit.minute,
+        .time.second = date_time.unit.second
+    };
+}
+
 static inline void _movement_reset_inactivity_countdown(void) {
     movement_state.le_mode_ticks = movement_le_inactivity_deadlines[movement_state.settings.bit.le_interval];
     movement_state.timeout_ticks = movement_timeout_inactivity_deadlines[movement_state.settings.bit.to_interval];
@@ -314,22 +328,24 @@ uint8_t movement_claim_backup_register(void) {
 
 int32_t movement_get_current_timezone_offset_for_zone(uint8_t zone_index) {
     watch_date_time date_time = watch_rtc_get_date_time();
-    uzone_t time_zone;
-    uoffset_t offset;
-    udatetime_t udate_time = {
-        .date.dayofmonth = date_time.unit.day,
-        .date.dayofweek = dayofweek(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR - UYEAR_OFFSET, date_time.unit.month, date_time.unit.day),
-        .date.month = date_time.unit.month,
-        .date.year = date_time.unit.year + WATCH_RTC_REFERENCE_YEAR - UYEAR_OFFSET,
-        .time.hour = date_time.unit.hour,
-        .time.minute = date_time.unit.minute,
-        .time.second = date_time.unit.second
-    };
+    udatetime_t udate_time = _movement_convert_date_time_to_udate(watch_rtc_get_date_time());
+    uzone_t local_zone;
+
+    // first unpack the zone to get the baseline offset
+    unpack_zone(&zone_defns[zone_index], "", &local_zone);
 
-    unpack_zone(&zone_defns[zone_index], "", &time_zone);
-    get_current_offset(&time_zone, &udate_time, &offset);
+    // offset the UTC time by that amount to get the local standard time
+    date_time = watch_utility_date_time_convert_zone(date_time, 0, local_zone.offset.hours * 3600 + local_zone.offset.minutes * 60);
+
+    // if local zone has DST rules, we need to see if DST applies.
+    if (local_zone.rules_len) {
+        udate_time = _movement_convert_date_time_to_udate(date_time);
+        uoffset_t offset;
+        get_current_offset(&local_zone, &udate_time, &offset);
+        return offset.hours * 3600 + offset.minutes * 60;
+    }
 
-    return offset.hours * 3600 + offset.minutes * 60;
+    return local_zone.offset.hours * 3600 + local_zone.offset.minutes * 60;
 }
 
 int32_t movement_get_current_timezone_offset(void) {
@@ -344,6 +360,26 @@ void movement_set_timezone_index(uint8_t value) {
     movement_state.settings.bit.time_zone = value;
 }
 
+watch_date_time movement_get_utc_date_time(void) {
+    return watch_rtc_get_date_time();
+}
+
+watch_date_time movement_get_date_time_in_zone(uint8_t zone_index) {
+    int32_t offset = movement_get_current_timezone_offset_for_zone(zone_index);
+    return watch_utility_date_time_convert_zone(watch_rtc_get_date_time(), 0, offset);
+}
+
+watch_date_time movement_get_local_date_time(void) {
+    watch_date_time date_time = watch_rtc_get_date_time();
+    return watch_utility_date_time_convert_zone(date_time, 0, movement_get_current_timezone_offset());
+}
+
+void movement_set_local_date_time(watch_date_time date_time) {
+    int32_t current_offset = movement_get_current_timezone_offset();
+    watch_date_time utc_date_time = watch_utility_date_time_convert_zone(date_time, current_offset, 0);
+    watch_rtc_set_date_time(utc_date_time);
+}
+
 bool movement_button_should_sound(void) {
     return movement_state.settings.bit.button_should_sound;
 }
index d024179c70f5051ea27d51b07e4015e7c2510a23..72ac9d7c0f5d00b7ff01672bb7db3f4a4f41f4fd 100644 (file)
@@ -337,6 +337,12 @@ int32_t movement_get_current_timezone_offset(void);
 int32_t movement_get_timezone_index(void);
 void movement_set_timezone_index(uint8_t value);
 
+watch_date_time movement_get_utc_date_time(void);
+watch_date_time movement_get_local_date_time(void);
+watch_date_time movement_get_date_time_in_zone(uint8_t zone_index);
+
+void movement_set_local_date_time(watch_date_time date_time);
+
 bool movement_button_should_sound(void);
 void movement_set_button_should_sound(bool value);
 
index 94564d95fe9df10584c1d6471235277e6aef9035..349de1eaf5e9002d734162f31f4693f46e05e47e 100644 (file)
@@ -29,6 +29,7 @@
 
 const watch_face_t watch_faces[] = {
     clock_face,
+    world_clock_face,
     sunrise_sunset_face,
     beats_face,
     advanced_alarm_face,
index f0e34a9864c3f8e4add4b808fc1f9ef41691188b..b2bde552ebec5ae7d0239ce488e698c8663187fe 100644 (file)
@@ -57,7 +57,7 @@ bool beats_face_loop(movement_event_t event, void *context) {
     switch (event.event_type) {
         case EVENT_ACTIVATE:
         case EVENT_TICK:
-            date_time = watch_rtc_get_date_time();
+            date_time = movement_get_local_date_time();
             centibeats = clock2beats(date_time.unit.hour, date_time.unit.minute, date_time.unit.second, event.subsecond, movement_get_current_timezone_offset());
             if (centibeats == state->last_centibeat_displayed) {
                 // we missed this update, try again next subsecond
@@ -73,7 +73,7 @@ bool beats_face_loop(movement_event_t event, void *context) {
             break;
         case EVENT_LOW_ENERGY_UPDATE:
             if (!watch_sleep_animation_is_running()) watch_start_sleep_animation(432);
-            date_time = watch_rtc_get_date_time();
+            date_time = movement_get_local_date_time();
             centibeats = clock2beats(date_time.unit.hour, date_time.unit.minute, date_time.unit.second, event.subsecond, movement_get_current_timezone_offset());
             sprintf(buf, "%4lu  ", centibeats / 100);
 
index 05280c913b6f609588f5df1347d86b1f6bc7b52f..0fb63451380b335491b59cdb2ec616ea9e9d9cb9 100644 (file)
@@ -245,11 +245,11 @@ bool clock_face_loop(movement_event_t event, void *context) {
     switch (event.event_type) {
         case EVENT_LOW_ENERGY_UPDATE:
             clock_start_tick_tock_animation();
-            clock_display_low_energy(watch_rtc_get_date_time());
+            clock_display_low_energy(movement_get_local_date_time());
             break;
         case EVENT_TICK:
         case EVENT_ACTIVATE:
-            current = watch_rtc_get_date_time();
+            current = movement_get_local_date_time();
 
             clock_display_clock(state, current);
 
@@ -282,7 +282,7 @@ movement_watch_face_advisory_t clock_face_advise(void *context) {
     clock_state_t *state = (clock_state_t *) context;
 
     if (state->time_signal_enabled) {
-        watch_date_time date_time = watch_rtc_get_date_time();
+        watch_date_time date_time = movement_get_local_date_time();
         retval.wants_background_task = date_time.unit.minute == 0;
     }
 
index 5e34fd481abee1d74ba624709e5cb15362f721c8..4e7cb7b9790d3a5f627b8985ca1850b6506c9bb2 100644 (file)
@@ -42,11 +42,6 @@ void world_clock_face_setup(uint8_t watch_face_index, void ** context_ptr) {
         memset(*context_ptr, 0, sizeof(world_clock_state_t));
         world_clock_state_t *state = (world_clock_state_t *)*context_ptr;
         state->settings.bit.timezone_index = 15;
-        uint8_t backup_register = movement_claim_backup_register();
-        if (backup_register) {
-            state->settings.reg = watch_get_backup_data(backup_register);
-            state->backup_register = backup_register;
-        }
     }
 }
 
@@ -72,8 +67,7 @@ static bool world_clock_face_do_display_mode(movement_event_t event, world_clock
             // fall through
         case EVENT_TICK:
         case EVENT_LOW_ENERGY_UPDATE:
-            date_time = watch_rtc_get_date_time();
-            date_time = watch_utility_date_time_convert_zone(date_time, movement_get_current_timezone_offset(), state->current_offset);
+            date_time = movement_get_date_time_in_zone(state->settings.bit.timezone_index);
             previous_date_time = state->previous_date_time;
             state->previous_date_time = date_time.reg;
             if ((date_time.reg >> 6) == (previous_date_time >> 6) && event.event_type != EVENT_LOW_ENERGY_UPDATE) {
index 19edb249eb41a66f53692623c20b30030594e737..ea012a508250cc00fde573d4128af1316f21b8e9 100644 (file)
@@ -156,7 +156,7 @@ static void _alarm_update_alarm_enabled(alarm_state_t *state) {
             break;
             } else {
                 if (!now_init) {
-                    now = watch_rtc_get_date_time();
+                    now = movement_get_local_date_time();
                     now_init = true;
                     weekday_idx = _get_weekday_idx(now);
                     now_minutes_of_day = now.unit.hour * 60 + now.unit.minute;
@@ -244,7 +244,7 @@ movement_watch_face_advisory_t advanced_alarm_face_advise(void *context) {
     alarm_state_t *state = (alarm_state_t *)context;
     movement_watch_face_advisory_t retval = { 0 };
 
-    watch_date_time now = watch_rtc_get_date_time();
+    watch_date_time now = movement_get_local_date_time();
     // just a failsafe: never fire more than one alarm within a minute
     if (state->alarm_handled_minute == now.unit.minute) return retval;
     state->alarm_handled_minute = now.unit.minute;
index 1f088c4c3e985893834289111d8cb8b4eda9d6b5..34ea4341bbec60267d4257a8d3b115a522246808 100644 (file)
@@ -69,7 +69,7 @@ static void schedule_countdown(countdown_state_t *state) {
 
     // Calculate the new state->now_ts but don't update it until we've updated the target - 
     // avoid possible race where the old target is compared to the new time and immediately triggers
-    uint32_t new_now = watch_utility_date_time_to_unix_time(watch_rtc_get_date_time(), movement_get_current_timezone_offset());
+    uint32_t new_now = watch_utility_date_time_to_unix_time(movement_get_utc_date_time(), movement_get_current_timezone_offset());
     state->target_ts = watch_utility_offset_timestamp(new_now, state->hours, state->minutes, state->seconds);
     state->now_ts = new_now;
     watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->target_ts, movement_get_current_timezone_offset());
@@ -196,7 +196,7 @@ void countdown_face_setup(uint8_t watch_face_index, void ** context_ptr) {
 void countdown_face_activate(void *context) {
     countdown_state_t *state = (countdown_state_t *)context;
     if(state->mode == cd_running) {
-        watch_date_time now = watch_rtc_get_date_time();
+        watch_date_time now = movement_get_utc_date_time();
         state->now_ts = watch_utility_date_time_to_unix_time(now, movement_get_current_timezone_offset());
         watch_set_indicator(WATCH_INDICATOR_SIGNAL);
     }
index 95cddfbae15b681a15b7166eeda96a84cc9cb485..474fe9d7aabb163be563993ea7cf631e8cee2a7c 100644 (file)
@@ -62,7 +62,7 @@ static void _sunrise_sunset_face_update(sunrise_sunset_state_t *state) {
         return;
     }
 
-    watch_date_time date_time = watch_rtc_get_date_time(); // the current local date / time
+    watch_date_time date_time = movement_get_local_date_time(); // the current local date / time
     watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, movement_get_current_timezone_offset(), 0); // the current date / time in UTC
     watch_date_time scratch_time; // scratchpad, contains different values at different times
     scratch_time.reg = utc_now.reg;
@@ -338,7 +338,7 @@ bool sunrise_sunset_face_loop(movement_event_t event, void *context) {
                 // if entering low energy mode, start tick animation
                 if (event.event_type == EVENT_LOW_ENERGY_UPDATE && !watch_sleep_animation_is_running()) watch_start_sleep_animation(1000);
                 // check if we need to update the display
-                watch_date_time date_time = watch_rtc_get_date_time();
+                watch_date_time date_time = movement_get_local_date_time();
                 if (date_time.reg >= state->rise_set_expires.reg) {
                     // and on the off chance that this happened before EVENT_TIMEOUT snapped us back to rise/set 0, go back now
                     state->rise_index = 0;
index b532c9d0b0f110a03b5d32efd28bcd77c4c1f0f6..b172ec6b50e7cff0ebb7f683dc7e53b4d31824a0 100644 (file)
@@ -53,7 +53,7 @@ bool voltage_face_loop(movement_event_t event, void *context) {
             _voltage_face_update_display();
             break;
         case EVENT_TICK:
-            date_time = watch_rtc_get_date_time();
+            date_time = movement_get_local_date_time();
             if (date_time.unit.second % 5 == 4) {
                 watch_set_indicator(WATCH_INDICATOR_SIGNAL);
             } else if (date_time.unit.second % 5 == 0) {
index 70450e524dff18f21df4cff0f68141fb8e97d3b0..a1c41c978b6408c476d0440e3b5896050ca450e2 100644 (file)
@@ -66,7 +66,7 @@ static void _handle_alarm_button(watch_date_time date_time, uint8_t current_page
     }
     if (date_time.unit.day > days_in_month(date_time.unit.month, date_time.unit.year + WATCH_RTC_REFERENCE_YEAR))
         date_time.unit.day = 1;
-    watch_rtc_set_date_time(date_time);
+    movement_set_local_date_time(date_time);
 }
 
 static void _abort_quick_ticks() {
@@ -90,7 +90,7 @@ void set_time_face_activate(void *context) {
 
 bool set_time_face_loop(movement_event_t event, void *context) {
     uint8_t current_page = *((uint8_t *)context);
-    watch_date_time date_time = watch_rtc_get_date_time();
+    watch_date_time date_time = movement_get_local_date_time();
 
     switch (event.event_type) {
         case EVENT_TICK: