From 077f3d5552a96fed0ee2f73e91a4763b1ec33962 Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Fri, 19 May 2023 17:16:10 +0100 Subject: [PATCH] Allow alarms to be day-specific --- README.md | 2 +- components/alarms/alarm_store.h | 1 + components/alarms/alarms.c | 57 ++++++++++++++++++++++++++++----- components/time/time_manager.h | 1 + 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9d1b887..ebf99f6 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Networked bedside clock utilising an ESP32-SOLO-1. - [x] SNTP synchronisation - [x] Snooze and dismiss buttons - [x] Multiple alarms -- [ ] Alarm conditions (e.g. weekday / weekend) +- [x] Alarm conditions (e.g. weekday / weekend) - [ ] IPv6 support ## Firmware diff --git a/components/alarms/alarm_store.h b/components/alarms/alarm_store.h index 2341940..9867576 100644 --- a/components/alarms/alarm_store.h +++ b/components/alarms/alarm_store.h @@ -14,6 +14,7 @@ typedef struct { bool set; Time time; + bool days[WEEK_DAY_COUNT]; } Alarm; extern Alarm alarms[CONFIG_MAX_ALARMS]; diff --git a/components/alarms/alarms.c b/components/alarms/alarms.c index be68026..da64218 100644 --- a/components/alarms/alarms.c +++ b/components/alarms/alarms.c @@ -41,12 +41,13 @@ static Time in_minutes(unsigned minutes) return time; } -static bool add_alarm(Time time) +static bool add_alarm(Time time, bool days[WEEK_DAY_COUNT]) { for (unsigned i = 0; i < CONFIG_MAX_ALARMS; ++i) { if (!alarms[i].set) { alarms[i].set = true; alarms[i].time = time; + memcpy(alarms[i].days, days, WEEK_DAY_COUNT * sizeof(bool)); alarm_store_save(); return true; } @@ -145,7 +146,8 @@ static void check_alarms(Time now) for (unsigned i = 0; i < CONFIG_MAX_ALARMS; ++i) { if (!alarms[i].set) continue; - if (passed_since_last_check(alarms[i].time, now)) + if (passed_since_last_check(alarms[i].time, now) + && alarms[i].days[get_week_day()]) activate(&alarms[i]); } @@ -163,15 +165,40 @@ static void check_alarms(Time now) xSemaphoreGive(state_mutex); } +static bool read_dayspec(const char *dayspec, bool days_out[WEEK_DAY_COUNT]) +{ + if (strlen(dayspec) != WEEK_DAY_COUNT) + return false; + for (unsigned i = 0; i < WEEK_DAY_COUNT; ++i) { + if (dayspec[i] == 'x') + days_out[i] = true; + else if (dayspec[i] == '-') + days_out[i] = false; + else + return false; + } + return true; +} + +static void format_dayspec( + bool days[WEEK_DAY_COUNT], char dayspec_out[WEEK_DAY_COUNT + 1]) +{ + for (unsigned i = 0; i < WEEK_DAY_COUNT; ++i) + dayspec_out[i] = days[i] ? 'x' : '-'; + dayspec_out[WEEK_DAY_COUNT] = '\0'; +} + static int command_func(int argc, char **argv) { if (argc == 1) { + char dayspec[WEEK_DAY_COUNT + 1]; for (unsigned i = 0; i < CONFIG_MAX_ALARMS; ++i) { if (!alarms[i].set) continue; + format_dayspec(alarms[i].days, dayspec); printf( - "[%2u] %02u:%02u\n", i, alarms[i].time.hour, - alarms[i].time.minute); + "[%2u] %02u:%02u %s\n", i, alarms[i].time.hour, + alarms[i].time.minute, dayspec); } return 0; } else if (argc == 2 && strcmp(argv[1], "clear") == 0) { @@ -186,7 +213,17 @@ static int command_func(int argc, char **argv) printf("Invalid time\n"); return 1; } - if (!add_alarm(time)) { + bool days[WEEK_DAY_COUNT]; + if (argc == 4) { + if (!read_dayspec(argv[3], days)) { + printf("Invalid dayspec\n"); + return 1; + } + } else { + for (unsigned i = 0; i < WEEK_DAY_COUNT; ++i) + days[i] = true; + } + if (!add_alarm(time, days)) { printf("Max number of alarms already set.\n"); return 1; } @@ -223,9 +260,13 @@ void alarms_init(void) add_time_callback(check_alarms); console_register( - "alarms", "List, add and remove alarms", - "alarms OR alarms add OR alarms remove OR alarms " - "", + "alarms", + "List, add and remove alarms\n\nIf a dayspec is specified, it " + "should be a sequence of 'x's and '-'s (for enabled or disabled " + "respectively). For example: \"*-*-*--\" means Mondays, Wednesdays " + "and Fridays only.", + "alarms OR alarms add [dayspec] OR alarms remove OR " + "alarms ", command_func); state_mutex = xSemaphoreCreateMutex(); diff --git a/components/time/time_manager.h b/components/time/time_manager.h index cafabda..736f1a1 100644 --- a/components/time/time_manager.h +++ b/components/time/time_manager.h @@ -26,6 +26,7 @@ typedef enum { WEEK_DAY_FRIDAY, WEEK_DAY_SATURDAY, WEEK_DAY_SUNDAY, + WEEK_DAY_COUNT, } WeekDay; typedef void (*TimeCallback)(Time now);