summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--movement/watch_faces/complication/sunrise_sunset_face.c108
-rw-r--r--movement/watch_faces/complication/sunrise_sunset_face.h1
-rw-r--r--watch-library/shared/watch/watch_utility.c7
-rw-r--r--watch-library/shared/watch/watch_utility.h13
4 files changed, 99 insertions, 30 deletions
diff --git a/movement/watch_faces/complication/sunrise_sunset_face.c b/movement/watch_faces/complication/sunrise_sunset_face.c
index 5c47d5d0..bb44f418 100644
--- a/movement/watch_faces/complication/sunrise_sunset_face.c
+++ b/movement/watch_faces/complication/sunrise_sunset_face.c
@@ -33,23 +33,52 @@
#include "watch_utility.h"
#include "sunriset.h"
-static void _sunrise_sunset_face_update(movement_settings_t *settings) {
+static void _sunrise_sunset_face_update(movement_settings_t *settings, sunrise_sunset_state_t *state) {
char buf[14];
- double rise, set, minutes;
- // TODO: allow user to set location, using New York for now.
+ double rise, set, minutes, seconds;
+ bool show_next_match = false;
movement_location_t movement_location = (movement_location_t) watch_get_backup_data(1);
- // TODO: account for time zone, currently only operates in GMT.
- watch_date_time date_time = watch_rtc_get_date_time(); // the current date / time
+ // some locations for testing, can remove eventually
+ // NYC
+ // movement_location.bit.latitude = 4073; movement_location.bit.longitude = -7393;
+
+ // Seattle
+ // movement_location.bit.latitude = 4760; movement_location.bit.longitude = -12233;
+
+ // Pago Pago
+ // movement_location.bit.latitude = -1428; movement_location.bit.longitude = -17070;
+
+ // Fairbanks
+ // movement_location.bit.latitude = 6484; movement_location.bit.longitude = -14765;
+
+ // Auckland
+ // movement_location.bit.latitude = -3685; movement_location.bit.longitude = 17478;
+
+ if (movement_location.reg == 0) {
+ watch_display_string("RI no Loc", 0);
+ return;
+ }
+
+ 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
watch_date_time scratch_time; // scratchpad, contains different values at different times
- scratch_time.reg = date_time.reg;
+ scratch_time.reg = utc_now.reg;
+
+ // 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;
+ // sunriset returns the rise/set times as signed decimal hours in UTC.
+ // this can mean hours below 0 or above 31, which won't fit into a watch_date_time struct.
+ // to deal with this, we set aside the offset in hours, and add it back before converting it to a watch_date_time.
+ double hours_from_utc = ((double)movement_timezone_offsets[settings->bit.time_zone]) / 60.0;
+
+ // we loop twice because if it's after sunset today, we need to recalculate to display values for tomorrow.
for(int i = 0; i < 2; i++) {
uint8_t result = sun_rise_set(scratch_time.unit.year + WATCH_RTC_REFERENCE_YEAR, scratch_time.unit.month, scratch_time.unit.day, lon, lat, &rise, &set);
@@ -63,38 +92,53 @@ static void _sunrise_sunset_face_update(movement_settings_t *settings) {
}
watch_set_colon();
- // TODO: account for user's 12H/24H preference
- watch_set_indicator(WATCH_INDICATOR_24H);
+ if (settings->bit.clock_mode_24h) watch_set_indicator(WATCH_INDICATOR_24H);
+
+ rise += hours_from_utc;
+ set += hours_from_utc;
minutes = 60.0 * fmod(rise, 1);
+ seconds = 60.0 * fmod(minutes, 1);
scratch_time.unit.hour = floor(rise);
- scratch_time.unit.minute = floor(minutes);
- scratch_time.unit.second = 60.0 * fmod(minutes, 1);
+ if (seconds < 30) scratch_time.unit.minute = floor(minutes);
+ else scratch_time.unit.minute = ceil(minutes);
- if (utc_now.reg < scratch_time.reg) {
- // display today's sunrise, it hasn't happened yet
- scratch_time = watch_utility_date_time_convert_zone(scratch_time, 0, movement_timezone_offsets[settings->bit.time_zone] * 60);
- sprintf(buf, "rI%2d%2d%02d%02d", scratch_time.unit.day, scratch_time.unit.hour, scratch_time.unit.minute, scratch_time.unit.second);
- watch_display_string(buf, 0);
- return;
+ if (date_time.reg < scratch_time.reg || show_next_match) {
+ if (state->rise_index == 0 || show_next_match) {
+ if (!settings->bit.clock_mode_24h) {
+ if (watch_utility_convert_to_12_hour(&scratch_time)) watch_set_indicator(WATCH_INDICATOR_PM);
+ else watch_clear_indicator(WATCH_INDICATOR_PM);
+ }
+ sprintf(buf, "rI%2d%2d%02d ", scratch_time.unit.day, scratch_time.unit.hour, scratch_time.unit.minute);
+ watch_display_string(buf, 0);
+ return;
+ } else {
+ show_next_match = true;
+ }
}
minutes = 60.0 * fmod(set, 1);
+ seconds = 60.0 * fmod(minutes, 1);
scratch_time.unit.hour = floor(set);
- scratch_time.unit.minute = floor(minutes);
- scratch_time.unit.second = 60.0 * fmod(minutes, 1);
+ if (seconds < 30) scratch_time.unit.minute = floor(minutes);
+ else scratch_time.unit.minute = ceil(minutes);
- if (utc_now.reg < scratch_time.reg) {
- // display today's sunset, it hasn't happened yet
- scratch_time = watch_utility_date_time_convert_zone(scratch_time, 0, movement_timezone_offsets[settings->bit.time_zone] * 60);
- sprintf(buf, "SE%2d%02d%02d%02d", scratch_time.unit.day, scratch_time.unit.hour, scratch_time.unit.minute, scratch_time.unit.second);
- watch_display_string(buf, 0);
- return;
+ if (date_time.reg < scratch_time.reg || show_next_match) {
+ if (state->rise_index == 0 || show_next_match) {
+ if (!settings->bit.clock_mode_24h) {
+ if (watch_utility_convert_to_12_hour(&scratch_time)) watch_set_indicator(WATCH_INDICATOR_PM);
+ else watch_clear_indicator(WATCH_INDICATOR_PM);
+ }
+ sprintf(buf, "SE%2d%2d%02d ", scratch_time.unit.day, scratch_time.unit.hour, scratch_time.unit.minute);
+ watch_display_string(buf, 0);
+ return;
+ } else {
+ show_next_match = true;
+ }
}
-
- // it's after sunset. we need to display sunrise for tomorrow.
- uint32_t timestamp = watch_utility_date_time_to_unix_time(date_time, 0);
+ // it's after sunset. we need to display sunrise/sunset for tomorrow.
+ uint32_t timestamp = watch_utility_date_time_to_unix_time(utc_now, 0);
timestamp += 86400;
scratch_time = watch_utility_date_time_from_unix_time(timestamp, 0);
}
@@ -115,7 +159,7 @@ static int16_t _sunrise_sunset_face_latlon_from_struct(sunrise_sunset_lat_lon_se
static sunrise_sunset_lat_lon_settings_t _sunrise_sunset_face_struct_from_latlon(int16_t val) {
sunrise_sunset_lat_lon_settings_t retval;
- if (val < 0) retval.sign = 1;
+ retval.sign = val < 0;
val = abs(val);
retval.hundredths = val % 10;
val /= 10;
@@ -252,7 +296,7 @@ bool sunrise_sunset_face_loop(movement_event_t event, movement_settings_t *setti
switch (event.event_type) {
case EVENT_ACTIVATE:
- _sunrise_sunset_face_update(settings);
+ _sunrise_sunset_face_update(settings, state);
break;
case EVENT_LOW_ENERGY_UPDATE:
case EVENT_TICK:
@@ -276,7 +320,7 @@ bool sunrise_sunset_face_loop(movement_event_t event, movement_settings_t *setti
}
if (state->page == 0) {
movement_request_tick_frequency(1);
- _sunrise_sunset_face_update(settings);
+ _sunrise_sunset_face_update(settings, state);
}
break;
case EVENT_LIGHT_BUTTON_UP:
@@ -285,6 +329,9 @@ bool sunrise_sunset_face_loop(movement_event_t event, movement_settings_t *setti
if (state->page) {
_sunrise_sunset_face_advance_digit(state);
_sunrise_sunset_face_update_settings_display(event, context);
+ } else {
+ state->rise_index = (state->rise_index + 1) % 2;
+ _sunrise_sunset_face_update(settings, state);
}
break;
case EVENT_ALARM_LONG_PRESS:
@@ -311,5 +358,6 @@ void sunrise_sunset_face_resign(movement_settings_t *settings, void *context) {
sunrise_sunset_state_t *state = (sunrise_sunset_state_t *)context;
state->page = 0;
state->active_digit = 0;
+ state->rise_index = 0;
_sunrise_sunset_face_update_location_register(state);
}
diff --git a/movement/watch_faces/complication/sunrise_sunset_face.h b/movement/watch_faces/complication/sunrise_sunset_face.h
index 826d5e95..ca9a1f5a 100644
--- a/movement/watch_faces/complication/sunrise_sunset_face.h
+++ b/movement/watch_faces/complication/sunrise_sunset_face.h
@@ -41,6 +41,7 @@ typedef struct {
typedef struct {
uint8_t page;
+ uint8_t rise_index;
uint8_t active_digit;
bool location_changed;
sunrise_sunset_lat_lon_settings_t working_latitude;
diff --git a/watch-library/shared/watch/watch_utility.c b/watch-library/shared/watch/watch_utility.c
index 835076d9..dd11c0eb 100644
--- a/watch-library/shared/watch/watch_utility.c
+++ b/watch-library/shared/watch/watch_utility.c
@@ -151,6 +151,13 @@ watch_date_time watch_utility_date_time_convert_zone(watch_date_time date_time,
return watch_utility_date_time_from_unix_time(timestamp, destination_utc_offset);
}
+bool watch_utility_convert_to_12_hour(watch_date_time *date_time) {
+ bool is_pm = date_time->unit.hour > 11;
+ date_time->unit.hour %= 12;
+ if (date_time->unit.hour == 0) date_time->unit.hour = 12;
+ return is_pm;
+}
+
float watch_utility_thermistor_temperature(uint16_t value, bool highside, float b_coefficient, float nominal_temperature, float nominal_resistance, float series_resistance) {
float reading = (float)value;
diff --git a/watch-library/shared/watch/watch_utility.h b/watch-library/shared/watch/watch_utility.h
index 66af6ed5..dc0ebb6a 100644
--- a/watch-library/shared/watch/watch_utility.h
+++ b/watch-library/shared/watch/watch_utility.h
@@ -70,6 +70,19 @@ uint32_t watch_utility_date_time_to_unix_time(watch_date_time date_time, uint32_
*/
watch_date_time watch_utility_date_time_from_unix_time(uint32_t timestamp, uint32_t utc_offset);
+/** @brief Converts a watch_date_time for 12-hour display.
+ * @param date_time A pointer to the watch_date_time that you wish to convert for display. Note that this
+ * function will OVERWRITE the original date/time, rendering it invalid for date/time
+ * calculations. Midnight (hour 0) will become 12, and hours in the afternoon will wrap
+ * back around to values from 1-11.
+ * @return True if the value is in the afternoon. You can use this value to determine whether to set the
+ * PM indicator on the LCD.
+ * @note This function sort of abuses the watch_date_time struct; the date/time that results from calling
+ * this function is clamped to the hours of 1:00:00 AM through 12:59:59 PM. It no longer reflects a
+ * valid watch_date_time for writing to an RTC register.
+ */
+bool watch_utility_convert_to_12_hour(watch_date_time *date_time);
+
/** @brief Converts a time from a given time zone to another time zone.
* @param date_time The watch_date_time that you wish to convert
* @param origin_utc_offset The number of seconds from UTC in the origin time zone