TimeAlarms lib - changing alarm values

I have four RepeatAlarms that are supposed to go off every day, determined by hour and minute.

But I also want the user to change these alarms and disable them. I think I have figured it out, but I thought I might ask if this is the correct approach here since it saves me extensive testing.

void setAlarmTrigger(uint8_t alarmNumber, uint8_t hours, uint8_t minutes, bool enabled)
{
	time_t alarmValue = Alarm.read(alarmNumber);		//get alarm value as time_t
	tmElements_t tm;
	breakTime(alarmValue, tm);						//convert time_t to TimeElements
	tm.Hour = hours;								//changes values
	tm.Minute = minutes;
	alarmValue = makeTime(tm);					//convert back to time_t					

	Alarm.write(alarmNumber, alarmValue);				//change alarm

	if(enabled == false){						        //disable if necessary
		Alarm.disable(alarmNumber);
	}
}

I determined that alarmIDs are simply counted up from 0 and since RepeatAlarms shouldn't be freed, the ID should stay the same. Then I get the their time_t value, convert it to something readable, change the hours and minutes, change it back to time_t and write that value to the alarm.

time_t/TimeElements also contains the values for day, month and year, but since the alarm is supposed to trigger every day I don't need to set those to the current date, right? That's the thing I don't fully understand.

time_t also contains the values for day, month and year, but since the alarm is supposed to trigger every day I don't need to set those to the current time, right? That's the thing I don't fully understand.

No. The breakTime() function will populate all the fields in the tm instance. When you call makeTime() again, the modified AND unmodified fields of tm will be used to construct the new time_t instance.

Yeah, I get that part. I meant if it matters to TimeAlarm class whether the date is current. I guess not because if you don't change anything, it's supposed to trigger over and over :slight_smile:

I meant if it matters to TimeAlarm class whether the date is current.

You should look at the source code. My assumption (without having looked at the code) is that Alarm.read() will return the next time (and date) that it will fire.

I determined that alarmIDs are simply counted up from 0 and since RepeatAlarms shouldn't be freed, the ID should stay the same.

You can get the alarm ID for an alarm by reading it into a variable when the alarm is set, like this
ID = Alarm.alarmRepeat(value,  AlarmFunction);It would be safer to use the ID obtained like this than relying on the next number being allocated. It would also make your code more future proof.

Ah, cool, thanks. I changed the code accordingly :slight_smile:

EDIT:
Well, somehow it doesn't seem to be working. The newly created alarms work fine, but the changed ones don't trigger.

According to this, it should be possible:
http://forum.arduino.cc/index.php?topic=37693.30

Ok, I seem to have figured out a way to do it. Freeing the ID and creating an entirely new alarm works :slight_smile:

void setAlarmTrigger(uint8_t alarmNumber, struct AlarmSettings *alarm)
{
	 Alarm.free(alarm->ID);
	
	 void (*callback)();

	 switch(alarmNumber)
 	{
 		case 0:
 			callback = TriggerAlarm0;
 			break;
 		case 1:
 			callback = TriggerAlarm1;
			 break;
		case 2:
			callback = TriggerAlarm2;
			break;
		case 3:
			callback = TriggerAlarm3;
			break;
	}

	alarm->ID = Alarm.alarmRepeat(alarm->hours, alarm->minutes, 0, callback);
}

Creating the new function pointer is a bit cumbersome, but as long as it works it's ok :slight_smile: