Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hourly chime disable at night #451

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
18 changes: 18 additions & 0 deletions movement/movement.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ of debounce time.
#define MOVEMENT_DEFAULT_LED_DURATION 1
#endif

// Default to not always chiming every hour
#ifndef MOVEMENT_DEFAULT_HOURLY_CHIME_ALWAYS
#define MOVEMENT_DEFAULT_HOURLY_CHIME_ALWAYS 0
#endif

// Default to beginning a chime at 7am
#ifndef MOVEMENT_DEFAULT_HOURLY_CHIME_START
#define MOVEMENT_DEFAULT_HOURLY_CHIME_START 1
#endif

// Default to beginning a chime at 9pm
#ifndef MOVEMENT_DEFAULT_HOURLY_CHIME_END
#define MOVEMENT_DEFAULT_HOURLY_CHIME_END 1
#endif

// Default to no set location latitude
#ifndef MOVEMENT_DEFAULT_LATITUDE
#define MOVEMENT_DEFAULT_LATITUDE 0
Expand Down Expand Up @@ -430,6 +445,9 @@ void app_init(void) {
movement_state.settings.bit.to_interval = MOVEMENT_DEFAULT_TIMEOUT_INTERVAL;
movement_state.settings.bit.le_interval = MOVEMENT_DEFAULT_LOW_ENERGY_INTERVAL;
movement_state.settings.bit.led_duration = MOVEMENT_DEFAULT_LED_DURATION;
movement_state.settings.bit.hourly_chime_always = MOVEMENT_DEFAULT_HOURLY_CHIME_ALWAYS;
movement_state.settings.bit.hourly_chime_start = MOVEMENT_DEFAULT_HOURLY_CHIME_START;
movement_state.settings.bit.hourly_chime_end = MOVEMENT_DEFAULT_HOURLY_CHIME_END;
movement_state.location.bit.latitude = MOVEMENT_DEFAULT_LATITUDE;
movement_state.location.bit.longitude = MOVEMENT_DEFAULT_LONGITUDE;
movement_state.birthdate.bit.year = MOVEMENT_DEFAULT_BIRTHDATE_YEAR;
Expand Down
21 changes: 20 additions & 1 deletion movement/movement.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ typedef union {
bool clock_mode_24h : 1; // indicates whether clock should use 12 or 24 hour mode.
bool use_imperial_units : 1; // indicates whether to use metric units (the default) or imperial.
bool alarm_enabled : 1; // indicates whether there is at least one alarm enabled.
uint8_t reserved : 6; // room for more preferences if needed.
bool hourly_chime_always : 1; // if true, then ignore the
uint8_t hourly_chime_start : 2; // 0: 6am; 1: 7am; 2: 10am; 3: 12pm or sunrise in long and lat set;
uint8_t hourly_chime_end : 2; // 0: 8pm; 1: 9pm; 2: 10pm; 3: 12am or sunset in long and lat set;
bool reserved : 1; // room for more preferences if needed.
} bit;
uint32_t reg;
} movement_settings_t;
Expand Down Expand Up @@ -318,4 +321,20 @@ void movement_play_alarm_beeps(uint8_t rounds, BuzzerNote alarm_note);

uint8_t movement_claim_backup_register(void);

static const uint8_t Hourly_Chime_Start[] =
{
6, // 6am
7, // 7am
10, // 10am
12 // 12pm if no long and lat set; sunset otherwise
};

static const uint8_t Hourly_Chime_End[] =
{
20, // 8pm
21, // 9pm
22, // 10pm
00 // 12am if no long and lat set; sunrise otherwise
};

#endif // MOVEMENT_H_
25 changes: 25 additions & 0 deletions movement/movement_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,29 @@ const watch_face_t watch_faces[] = {
#define MOVEMENT_DEFAULT_BIRTHDATE_MONTH 0
#define MOVEMENT_DEFAULT_BIRTHDATE_DAY 0

/* Set if the watch will chime every hour and ignorethe start and end chimes
* Valid values are:
* 0: Use the Start and End values
* 1: Chime every hour
*/
#define MOVEMENT_DEFAULT_HOURLY_CHIME_ALWAYS 0

/* When hourly chiming should begin (MOVEMENT_DEFAULT_HOURLY_CHIME_ALWAYS must be 0)
* Valid values are:
* 0: 6am
* 1: 7am
* 2: 10am
* 3: 12pm or sunrise in long and lat set;
*/
#define MOVEMENT_DEFAULT_HOURLY_CHIME_START 1

/* When hourly chiming should end (MOVEMENT_DEFAULT_HOURLY_CHIME_ALWAYS must be 0)
* Valid values are:
* 0: 8pm
* 1: 9pm
* 2: 10pm
* 3: 12am or sunset in long and lat set;
*/
#define MOVEMENT_DEFAULT_HOURLY_CHIME_END 1

#endif // MOVEMENT_CONFIG_H_
52 changes: 51 additions & 1 deletion movement/watch_faces/clock/clock_face.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "watch.h"
#include "watch_utility.h"
#include "watch_private_display.h"
#include "sunriset.h"

// 2.2 volts will happen when the battery has maybe 5-10% remaining?
// we can refine this later.
Expand All @@ -52,6 +53,50 @@ typedef struct {
bool battery_low;
} clock_state_t;

static uint8_t _time_to_chime_hour(double time, double hours_from_utc, bool use_end_of_hour) {
time += hours_from_utc;
uint8_t hour_to_start = (uint8_t)time;
double minutes = (time - hour_to_start) * 60;
if (!use_end_of_hour) return hour_to_start;
if (minutes >= 0.5)
hour_to_start = (hour_to_start + 1) % 24;
return hour_to_start;
}

static void _get_chime_times(watch_date_time date_time, movement_settings_t *settings, uint8_t *start_hour, uint8_t *end_hour) {
uint8_t init_val = 0xFF;
uint8_t hourly_chime_start = settings->bit.hourly_chime_start;
uint8_t hourly_chime_end = settings->bit.hourly_chime_end;
*start_hour = (hourly_chime_start == 3) ? init_val : Hourly_Chime_Start[hourly_chime_start];
*end_hour = (hourly_chime_end == 3) ? init_val : Hourly_Chime_End[hourly_chime_end];
if (hourly_chime_start != 3 && hourly_chime_end != 3) {
return;
}
int16_t tz = movement_timezone_offsets[settings->bit.time_zone];
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, tz * 60, 0); // the current date / time in UTC
movement_location_t movement_location = (movement_location_t) watch_get_backup_data(1);
if (movement_location.reg == 0) {
return;
}
double rise, set;
uint8_t rise_hour, set_hour;
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 hours_from_utc = ((double)tz) / 60.0;
uint8_t 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) {
return;
}
rise_hour = _time_to_chime_hour(rise, hours_from_utc, true);
set_hour = _time_to_chime_hour(set, hours_from_utc, false);
if (*start_hour == init_val) *start_hour = rise_hour;
if (*end_hour == init_val) *end_hour = set_hour;
if (*start_hour == 0) *start_hour = 24;
if (*end_hour == 0) *end_hour = 24;
}

static bool clock_is_in_24h_mode(movement_settings_t *settings) {
#ifdef CLOCK_FACE_24H_ONLY
return true;
Expand Down Expand Up @@ -285,6 +330,11 @@ bool clock_face_wants_background_task(movement_settings_t *settings, void *conte
if (!state->time_signal_enabled) return false;

watch_date_time date_time = watch_rtc_get_date_time();
if (date_time.unit.minute != 0) return false;
if (settings->bit.hourly_chime_always) return true;
uint8_t chime_start, chime_end;
_get_chime_times(date_time, settings, &chime_start, &chime_end);
if ((24 >= chime_start && date_time.unit.hour < chime_start) || (24 >= chime_end && date_time.unit.hour >= chime_end)) return false;

return date_time.unit.minute == 0;
return true;
}
52 changes: 51 additions & 1 deletion movement/watch_faces/clock/minute_repeater_decimal_face.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,51 @@
#include "watch.h"
#include "watch_utility.h"
#include "watch_private_display.h"
#include "sunriset.h"

static uint8_t _time_to_chime_hour(double time, double hours_from_utc, bool use_end_of_hour) {
time += hours_from_utc;
uint8_t hour_to_start = (uint8_t)time;
double minutes = (time - hour_to_start) * 60;
if (!use_end_of_hour) return hour_to_start;
if (minutes >= 0.5)
hour_to_start = (hour_to_start + 1) % 24;
return hour_to_start;
}

static void _get_chime_times(watch_date_time date_time, movement_settings_t *settings, uint8_t *start_hour, uint8_t *end_hour) {
uint8_t init_val = 0xFF;
uint8_t hourly_chime_start = settings->bit.hourly_chime_start;
uint8_t hourly_chime_end = settings->bit.hourly_chime_end;
*start_hour = (hourly_chime_start == 3) ? init_val : Hourly_Chime_Start[hourly_chime_start];
*end_hour = (hourly_chime_end == 3) ? init_val : Hourly_Chime_End[hourly_chime_end];
if (hourly_chime_start != 3 && hourly_chime_end != 3) {
return;
}
int16_t tz = movement_timezone_offsets[settings->bit.time_zone];
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, tz * 60, 0); // the current date / time in UTC
movement_location_t movement_location = (movement_location_t) watch_get_backup_data(1);
if (movement_location.reg == 0) {
return;
}
double rise, set;
uint8_t rise_hour, set_hour;
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 hours_from_utc = ((double)tz) / 60.0;
uint8_t 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) {
return;
}
rise_hour = _time_to_chime_hour(rise, hours_from_utc, true);
set_hour = _time_to_chime_hour(set, hours_from_utc, false);
if (*start_hour == init_val) *start_hour = rise_hour;
if (*end_hour == init_val) *end_hour = set_hour;
if (*start_hour == 0) *start_hour = 24;
if (*end_hour == 0) *end_hour = 24;
}

void mrd_play_hour_chime(void) {
watch_buzzer_play_note(BUZZER_NOTE_C6, 75);
Expand Down Expand Up @@ -233,6 +278,11 @@ bool minute_repeater_decimal_face_wants_background_task(movement_settings_t *set
if (!state->signal_enabled) return false;

watch_date_time date_time = watch_rtc_get_date_time();
if (date_time.unit.minute != 0) return false;
if (settings->bit.hourly_chime_always) return true;
uint8_t chime_start, chime_end;
_get_chime_times(date_time, settings, &chime_start, &chime_end);
if ((24 >= chime_start && date_time.unit.hour < chime_start) || (24 >= chime_end && date_time.unit.hour >= chime_end)) return false;

return date_time.unit.minute == 0;
return true;
}
52 changes: 51 additions & 1 deletion movement/watch_faces/clock/repetition_minute_face.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,51 @@
#include "watch.h"
#include "watch_utility.h"
#include "watch_private_display.h"
#include "sunriset.h"

static uint8_t _time_to_chime_hour(double time, double hours_from_utc, bool use_end_of_hour) {
time += hours_from_utc;
uint8_t hour_to_start = (uint8_t)time;
double minutes = (time - hour_to_start) * 60;
if (!use_end_of_hour) return hour_to_start;
if (minutes >= 0.5)
hour_to_start = (hour_to_start + 1) % 24;
return hour_to_start;
}

static void _get_chime_times(watch_date_time date_time, movement_settings_t *settings, uint8_t *start_hour, uint8_t *end_hour) {
uint8_t init_val = 0xFF;
uint8_t hourly_chime_start = settings->bit.hourly_chime_start;
uint8_t hourly_chime_end = settings->bit.hourly_chime_end;
*start_hour = (hourly_chime_start == 3) ? init_val : Hourly_Chime_Start[hourly_chime_start];
*end_hour = (hourly_chime_end == 3) ? init_val : Hourly_Chime_End[hourly_chime_end];
if (hourly_chime_start != 3 && hourly_chime_end != 3) {
return;
}
int16_t tz = movement_timezone_offsets[settings->bit.time_zone];
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, tz * 60, 0); // the current date / time in UTC
movement_location_t movement_location = (movement_location_t) watch_get_backup_data(1);
if (movement_location.reg == 0) {
return;
}
double rise, set;
uint8_t rise_hour, set_hour;
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 hours_from_utc = ((double)tz) / 60.0;
uint8_t 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) {
return;
}
rise_hour = _time_to_chime_hour(rise, hours_from_utc, true);
set_hour = _time_to_chime_hour(set, hours_from_utc, false);
if (*start_hour == init_val) *start_hour = rise_hour;
if (*end_hour == init_val) *end_hour = set_hour;
if (*start_hour == 0) *start_hour = 24;
if (*end_hour == 0) *end_hour = 24;
}

void play_hour_chime(void) {
watch_buzzer_play_note(BUZZER_NOTE_C6, 75);
Expand Down Expand Up @@ -216,6 +261,11 @@ bool repetition_minute_face_wants_background_task(movement_settings_t *settings,
if (!state->signal_enabled) return false;

watch_date_time date_time = watch_rtc_get_date_time();
if (date_time.unit.minute != 0) return false;
if (settings->bit.hourly_chime_always) return true;
uint8_t chime_start, chime_end;
_get_chime_times(date_time, settings, &chime_start, &chime_end);
if ((24 >= chime_start && date_time.unit.hour < chime_start) || (24 >= chime_end && date_time.unit.hour >= chime_end)) return false;

return date_time.unit.minute == 0;
return true;
}
52 changes: 51 additions & 1 deletion movement/watch_faces/clock/simple_clock_bin_led_face.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,51 @@
#include "watch.h"
#include "watch_utility.h"
#include "watch_private_display.h"
#include "sunriset.h"

static uint8_t _time_to_chime_hour(double time, double hours_from_utc, bool use_end_of_hour) {
time += hours_from_utc;
uint8_t hour_to_start = (uint8_t)time;
double minutes = (time - hour_to_start) * 60;
if (!use_end_of_hour) return hour_to_start;
if (minutes >= 0.5)
hour_to_start = (hour_to_start + 1) % 24;
return hour_to_start;
}

static void _get_chime_times(watch_date_time date_time, movement_settings_t *settings, uint8_t *start_hour, uint8_t *end_hour) {
uint8_t init_val = 0xFF;
uint8_t hourly_chime_start = settings->bit.hourly_chime_start;
uint8_t hourly_chime_end = settings->bit.hourly_chime_end;
*start_hour = (hourly_chime_start == 3) ? init_val : Hourly_Chime_Start[hourly_chime_start];
*end_hour = (hourly_chime_end == 3) ? init_val : Hourly_Chime_End[hourly_chime_end];
if (hourly_chime_start != 3 && hourly_chime_end != 3) {
return;
}
int16_t tz = movement_timezone_offsets[settings->bit.time_zone];
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, tz * 60, 0); // the current date / time in UTC
movement_location_t movement_location = (movement_location_t) watch_get_backup_data(1);
if (movement_location.reg == 0) {
return;
}
double rise, set;
uint8_t rise_hour, set_hour;
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 hours_from_utc = ((double)tz) / 60.0;
uint8_t 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) {
return;
}
rise_hour = _time_to_chime_hour(rise, hours_from_utc, true);
set_hour = _time_to_chime_hour(set, hours_from_utc, false);
if (*start_hour == init_val) *start_hour = rise_hour;
if (*end_hour == init_val) *end_hour = set_hour;
if (*start_hour == 0) *start_hour = 24;
if (*end_hour == 0) *end_hour = 24;
}

static void _update_alarm_indicator(bool settings_alarm_enabled, simple_clock_bin_led_state_t *state) {
state->alarm_enabled = settings_alarm_enabled;
Expand Down Expand Up @@ -217,6 +262,11 @@ bool simple_clock_bin_led_face_wants_background_task(movement_settings_t *settin
if (!state->signal_enabled) return false;

watch_date_time date_time = watch_rtc_get_date_time();
if (date_time.unit.minute != 0) return false;
if (settings->bit.hourly_chime_always) return true;
uint8_t chime_start, chime_end;
_get_chime_times(date_time, settings, &chime_start, &chime_end);
if ((24 >= chime_start && date_time.unit.hour < chime_start) || (24 >= chime_end && date_time.unit.hour >= chime_end)) return false;

return date_time.unit.minute == 0;
return true;
}
Loading