Allow alarms to be day-specific

This commit is contained in:
Camden Dixie O'Brien 2023-05-19 17:16:10 +01:00
parent 00e96f12f0
commit 077f3d5552
4 changed files with 52 additions and 9 deletions

View File

@ -12,7 +12,7 @@ Networked bedside clock utilising an ESP32-SOLO-1.
- [x] SNTP synchronisation - [x] SNTP synchronisation
- [x] Snooze and dismiss buttons - [x] Snooze and dismiss buttons
- [x] Multiple alarms - [x] Multiple alarms
- [ ] Alarm conditions (e.g. weekday / weekend) - [x] Alarm conditions (e.g. weekday / weekend)
- [ ] IPv6 support - [ ] IPv6 support
## Firmware ## Firmware

View File

@ -14,6 +14,7 @@
typedef struct { typedef struct {
bool set; bool set;
Time time; Time time;
bool days[WEEK_DAY_COUNT];
} Alarm; } Alarm;
extern Alarm alarms[CONFIG_MAX_ALARMS]; extern Alarm alarms[CONFIG_MAX_ALARMS];

View File

@ -41,12 +41,13 @@ static Time in_minutes(unsigned minutes)
return time; 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) { for (unsigned i = 0; i < CONFIG_MAX_ALARMS; ++i) {
if (!alarms[i].set) { if (!alarms[i].set) {
alarms[i].set = true; alarms[i].set = true;
alarms[i].time = time; alarms[i].time = time;
memcpy(alarms[i].days, days, WEEK_DAY_COUNT * sizeof(bool));
alarm_store_save(); alarm_store_save();
return true; return true;
} }
@ -145,7 +146,8 @@ static void check_alarms(Time now)
for (unsigned i = 0; i < CONFIG_MAX_ALARMS; ++i) { for (unsigned i = 0; i < CONFIG_MAX_ALARMS; ++i) {
if (!alarms[i].set) if (!alarms[i].set)
continue; 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]); activate(&alarms[i]);
} }
@ -163,15 +165,40 @@ static void check_alarms(Time now)
xSemaphoreGive(state_mutex); 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) static int command_func(int argc, char **argv)
{ {
if (argc == 1) { if (argc == 1) {
char dayspec[WEEK_DAY_COUNT + 1];
for (unsigned i = 0; i < CONFIG_MAX_ALARMS; ++i) { for (unsigned i = 0; i < CONFIG_MAX_ALARMS; ++i) {
if (!alarms[i].set) if (!alarms[i].set)
continue; continue;
format_dayspec(alarms[i].days, dayspec);
printf( printf(
"[%2u] %02u:%02u\n", i, alarms[i].time.hour, "[%2u] %02u:%02u %s\n", i, alarms[i].time.hour,
alarms[i].time.minute); alarms[i].time.minute, dayspec);
} }
return 0; return 0;
} else if (argc == 2 && strcmp(argv[1], "clear") == 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"); printf("Invalid time\n");
return 1; 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"); printf("Max number of alarms already set.\n");
return 1; return 1;
} }
@ -223,9 +260,13 @@ void alarms_init(void)
add_time_callback(check_alarms); add_time_callback(check_alarms);
console_register( console_register(
"alarms", "List, add and remove alarms", "alarms",
"alarms OR alarms add <hh:mm> OR alarms remove <index> OR alarms " "List, add and remove alarms\n\nIf a dayspec is specified, it "
"<clear>", "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 <hh:mm> [dayspec] OR alarms remove <index> OR "
"alarms <clear>",
command_func); command_func);
state_mutex = xSemaphoreCreateMutex(); state_mutex = xSemaphoreCreateMutex();

View File

@ -26,6 +26,7 @@ typedef enum {
WEEK_DAY_FRIDAY, WEEK_DAY_FRIDAY,
WEEK_DAY_SATURDAY, WEEK_DAY_SATURDAY,
WEEK_DAY_SUNDAY, WEEK_DAY_SUNDAY,
WEEK_DAY_COUNT,
} WeekDay; } WeekDay;
typedef void (*TimeCallback)(Time now); typedef void (*TimeCallback)(Time now);