Allow alarms to be day-specific
This commit is contained in:
parent
00e96f12f0
commit
077f3d5552
@ -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
|
||||||
|
@ -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];
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user