Alarms are complicated

I’ve always found it surprising how simple things end up being complicated. Take adding alarms to my Connected Little Boxes…. I want to have alarms that I can set in the device. When an alarm time is reached I want the device to perform an assigned action, perhaps make a sound, drive a servo or change the colour of a light. This is simple I say to myself. And I write a function to celebrate:

bool atAlarmTime(struct ClockAlarm *alarm, struct clockReading *reading)
{
    if (alarm->hour != reading->hour)
    {
        return false;
    }

    if (alarm->minute != reading->minute)
    {
        return false;
    }

    return true;
}

The function will return true when the clock reaches the alarm time. I can use this to trigger whatever action is bound to the alarm. Simple.

Well, not really. My program will be repeatedly checking the alarm to see if it has triggered. So if I just use the above function I will find that an alarm will trigger continuously for the entire alarm minute when it due. And what about when I turn the device on or change the time? Do I want it to ignore “past” alarms or not? If my device was controlling a heating system I’d want it to respond to an alarm even to turn the heating on even if that event was in the past. Otherwise I’d turn the system on at 12:00 and freeze because the event that turned on the boiler was set to 7:00am.

I’ve ended up setting up options and flags and writing code that spins through the set alarms looking for ones that should have been triggered and triggering them if that is what the user wants. Yep. Alarms are complicated.