]> git.earman.xyz Git - sensor-watch.git/commitdiff
day_night_percentage_face: Calculate rise/set/daylen only once per day.
authorWesley Aptekar-Cassels <me@wesleyac.com>
Thu, 9 Nov 2023 22:21:35 +0000 (17:21 -0500)
committerWesley Aptekar-Cassels <me@wesleyac.com>
Thu, 9 Nov 2023 22:21:35 +0000 (17:21 -0500)
movement/watch_faces/clock/day_night_percentage_face.c
movement/watch_faces/clock/day_night_percentage_face.h

index ed62653ffd88fa7e573e5160d4ef02041e65b09b..eaeeeb9162964a75e3348b1dddc1678ef412e0fd 100644 (file)
 #include "watch_utility.h"
 #include "sunriset.h"
 
+// fmod but handle negatives right
+static double better_fmod(double x, double y) {
+    return fmod(fmod(x, y) + y, y);
+}
+
+static void recalculate(watch_date_time utc_now, day_night_percentage_state_t *state) {
+    movement_location_t movement_location = (movement_location_t) watch_get_backup_data(1);
+
+    if (movement_location.reg == 0) {
+        state->result = -2;
+        return;
+    }
+
+    // Weird quirky unsigned things were happening when I tried to cast these directly to doubles below.
+    // it looks redundant, but extracting them to local int16's seemed to fix it.
+    int16_t lat_centi = (int16_t)movement_location.bit.latitude;
+    int16_t lon_centi = (int16_t)movement_location.bit.longitude;
+
+    double lat = (double)lat_centi / 100.0;
+    double lon = (double)lon_centi / 100.0;
+
+    state->daylen = day_length(utc_now.unit.year + WATCH_RTC_REFERENCE_YEAR, utc_now.unit.month, utc_now.unit.day, lon, lat);
+
+    state->result = sun_rise_set(utc_now.unit.year + WATCH_RTC_REFERENCE_YEAR, utc_now.unit.month, utc_now.unit.day, lon, lat, &state->rise, &state->set);
+}
+
 void day_night_percentage_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) {
     (void) settings;
     (void) watch_face_index;
-    (void) context_ptr;
+
+    if (*context_ptr == NULL) {
+        *context_ptr = malloc(sizeof(day_night_percentage_state_t));
+        day_night_percentage_state_t *state = (day_night_percentage_state_t *)*context_ptr;
+        watch_date_time utc_now = watch_utility_date_time_convert_zone(watch_rtc_get_date_time(), movement_timezone_offsets[settings->bit.time_zone] * 60, 0);
+        recalculate(utc_now, state);
+    }
 }
 
 void day_night_percentage_face_activate(movement_settings_t *settings, void *context) {
@@ -40,52 +72,34 @@ void day_night_percentage_face_activate(movement_settings_t *settings, void *con
     (void) context;
 }
 
-// fmod but handle negatives right
-static double better_fmod(double x, double y) {
-    return fmod(fmod(x, y) + y, y);
-}
-
 bool day_night_percentage_face_loop(movement_event_t event, movement_settings_t *settings, void *context) {
-    (void) context;
+    day_night_percentage_state_t *state = (day_night_percentage_state_t *)context;
+
+    char buf[12];
+    watch_date_time date_time = watch_rtc_get_date_time();
+    watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60, 0);
 
     switch (event.event_type) {
         case EVENT_ACTIVATE:
         case EVENT_TICK:
         case EVENT_LOW_ENERGY_UPDATE:
-            {
-            movement_location_t movement_location = (movement_location_t) watch_get_backup_data(1);
+            if ((utc_now.unit.hour == 0 && utc_now.unit.minute == 0 && utc_now.unit.second == 0) || state->result == -2) {
+                recalculate(utc_now, state);
+            }
 
-            if (movement_location.reg == 0) {
+            if (state->result == -2) {
                 watch_display_string("    no Loc", 0);
-                return true;
+                break;
             }
 
-            watch_date_time date_time = watch_rtc_get_date_time(); // the current local date / time
-            watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60, 0); // the current date / time in UTC
-
-            // Weird quirky unsigned things were happening when I tried to cast these directly to doubles below.
-            // it looks redundant, but extracting them to local int16's seemed to fix it.
-            int16_t lat_centi = (int16_t)movement_location.bit.latitude;
-            int16_t lon_centi = (int16_t)movement_location.bit.longitude;
-
-            double lat = (double)lat_centi / 100.0;
-            double lon = (double)lon_centi / 100.0;
-
-            double daylen = day_length(utc_now.unit.year + WATCH_RTC_REFERENCE_YEAR, utc_now.unit.month, utc_now.unit.day, lon, lat);
-
-            double rise, set;
-            char buf[12];
-
-            int result = sun_rise_set(utc_now.unit.year + WATCH_RTC_REFERENCE_YEAR, utc_now.unit.month, utc_now.unit.day, lon, lat, &rise, &set);
-
-            if (result != 0) {
-                sprintf(buf, "%s%2dEtrnal", result == 1 ? "DA" : "NI", date_time.unit.day);
+            if (state->result != 0) {
+                sprintf(buf, "%s%2dEtrnal", state->result == 1 ? "DA" : "NI", date_time.unit.day);
                 watch_display_string(buf, 0);
             } else {
                 double day_hours_decimal = utc_now.unit.hour + (utc_now.unit.minute + (utc_now.unit.second / 60.0)) / 60.0;
 
-                double day_percentage = (24.0 - better_fmod(rise - day_hours_decimal, 24.0)) / daylen;
-                double night_percentage = (24.0 - better_fmod(set - day_hours_decimal, 24.0)) / (24 - daylen);
+                double day_percentage = (24.0 - better_fmod(state->rise - day_hours_decimal, 24.0)) / state->daylen;
+                double night_percentage = (24.0 - better_fmod(state->set - day_hours_decimal, 24.0)) / (24 - state->daylen);
 
                 uint16_t percentage;
                 char day_night[3];
@@ -106,7 +120,6 @@ bool day_night_percentage_face_loop(movement_event_t event, movement_settings_t
             }
 
             break;
-            }
         default:
             return movement_default_loop_handler(event, settings);
     }
index 9155745b54580bca457d8772ef59913c0891af1f..c5865329c7e10d014bd8658fb35a53337564aeb3 100644 (file)
  * location register with some other face.
  */
 
-typedef struct {} day_night_percentage_state_t;
+typedef struct {
+    int result; // -1, 0, 1: result from sun_rise_set, -2: no location set
+    double rise;
+    double set;
+    double daylen;
+} day_night_percentage_state_t;
 
 void day_night_percentage_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr);
 void day_night_percentage_face_activate(movement_settings_t *settings, void *context);