How to remote set any value (e.g. TimeAlarm)?

great! will do that, Thank you.

the validation method will need to run in setup right?

how is this method used in timeAlarms.

void getID()
    {
        Alarm.read(pumpSchedWedOn); 
    }

is it supposed to return a String? is it printf formatted value?

If you look at the TimeAlarms.cpp file, you’ll see that Alarm.read is defined like this,

 // return the value for the given alarm ID
    time_t TimeAlarmsClass::read(AlarmID_t ID)
    {
      if(isAllocated(ID))
        return Alarm[ID].value ;
      else 	
        return dtINVALID_TIME;  
    }

time_t is a numeric type, not a string. I don’t know why Alarm.read would be inside a method called getID, since it doesn’t get an id.

i got it to work now. Thank you for pointing out my mistake.

What would be a good implementation of the watchdog function to monitor time alarms? I have a few timers and alarms running in my program and they are fairly reliable but it would make sense if i could check for the loop function alarm.delay becoming unresponsive and initiating a reset. Any ideas??

I have the following alarms in my program now. I have increased the number of alarms in the h file to 10. It seems like every time i call to set an alarm it overwrites the earlier one. Can anyone help me understand whats happening here.

AlarmID_t fanIntervalTimer;
AlarmID_t fanRunTimer;
//Alarms for watering scheduler
AlarmID_t waterEveryMonday;
AlarmID_t waterEveryTuesday;
AlarmID_t waterEveryWednesday;
AlarmID_t waterEveryThursday;
AlarmID_t waterEveryFriday;
AlarmID_t waterEverySaturday;
AlarmID_t waterEverySunday;

Thats how the setter looks

else if (action == SET_LIGHTS_ONE)
        {
                //Sets the time for turning on the lights at Level1
                int onOff = atoi(arguments.substring(0,1));
                int hour = atoi(arguments.substring(1,3));
                int min = atoi(arguments.substring(3,5));
                tempLightOneRuntimeValue = atoi(arguments.substring(5));
                //Assign the values to their respective objects
                lightOneObj.onOff = onOff;
                lightOneObj.hour = hour;
                lightOneObj.min = min;
                lightOneObj.runTime = tempLightOneRuntimeValue;
                //Save the values to EEPROM
                EEPROM.put(EEPROM_lightOneTime,lightOneObj);
                //assign the saved values to turn the lights at level one on or off when onOff is 1 else when ofOff  is 0 turn off
                //Serial.println(timeCheck(hour,min));
                if(onOff)
                {
                        if (activeCheck(hour,min,tempLightOneRuntimeValue))
                        {
                                disableLightSchedules();
                                toggleLightOneOff();
                                lightsOneOn = Alarm.alarmRepeat(hour,min,0,setLightOne);
                                getLightSettings();
                                Serial.println("option 1 in light setter");
                                return (hour*10000 + min*100 + tempLightOneRuntimeValue);
                        }
                        else if (!activeCheck(hour,min,tempLightOneRuntimeValue))
                        {
                                disableLightSchedules();
                                toggleLightOneOff;
                                lightsOneOn = Alarm.alarmRepeat(hour,min,0,setLightOne);
                                toggleLightOneOn();
                                int runTime_l1 = runTimeRemaining(hour,min,tempLightOneRuntimeValue);
                                tmplightsOneOff = Alarm.timerOnce(runTime_l1,toggleLightOneOff);
                                getLightSettings();
                                Serial.println("option 2 in light setter");
                                return (hour*10000 + min*100 + tempLightOneRuntimeValue);
                        }

Hi @Ali

I confess I am not sure how your code is supposed to work. You seem to have a bunch of AlarmID_t type global variables to hold the alarms, but I can’t see where you are assigning them. You do create new alarms in the code you show in the variable lightsOneOn but how that gets into the globals I can’t see.

I think the point your are missing is that every time you call a method like Alarm.alarmRepeat() you are allocated a new alarm that uses one of your slots, if one is available. You should also be checking the return value of method calls to see if they worked–they will return a number less than 255 if it worked and 255 as a return value means that the call failed. The 255 constant is called dtINVALID_ALARM_ID if you want to use macro name.

You seem to have a bunch of AlarmID_t type global variables to hold the alarms, but I can’t see where you are assigning them. You do create new alarms in the code you show in the variable lightsOneOn but how that gets into the globals I can’t see.

AlarmID_t lightsOneOn;
AlarmID_t lightsOneOff;
//temporary timer for alaram when time.now > set time
AlarmID_t tmplightsOneOff;
AlarmID_t waterOneEverydayOn;
AlarmID_t waterOneOff;
AlarmID_t drainPumpOff;
//Alarm for fanRecycling```
AlarmID_t fanIntervalTimer;
AlarmID_t fanRunTimer;
//Alarms for watering scheduler
AlarmID_t waterEveryMonday;
AlarmID_t waterEveryTuesday;
AlarmID_t waterEveryWednesday;
AlarmID_t waterEveryThursday;
AlarmID_t waterEveryFriday;
AlarmID_t waterEverySaturday;
AlarmID_t waterEverySunday;

I did not copy paste correctly. Does this look ok now? Not all the Alarms have been assigned as yet. I am only using 5 to check how the program runs.

As I said above, every time you do the action in your setter code, you are creating a new alarm (if there is room), so just storing them in same global variable does not reuse them. Do you ever call Alarm.free(lightsOneOn); or similar to release a timer back into the pool?

i call it everytime i change settings

//Diable LightSchedules
void disableLightSchedules()
{
        Alarm.free(lightsOneOn);
        Alarm.free(lightsOneOff);
        Alarm.free(tmplightsOneOff);
}

What method do i use to return the Alarm_ID?

I have a method that combines all that were in the h file to give me a status

String readAlarmType(AlarmID_t name)
{
        int tz = timeZoneObj.value;
        String readTimeString;
        String typeOfAlarm;
        String dayName;
        time_t x = Alarm.read(name);
        int h = Time.hour(x) - tz;
        int m = Time.minute(x);
        uint8_t count = Alarm.count();
        bool isAllocated = Alarm.isAllocated(name);// returns true if this id is allocated
        bool isAlarm = Alarm.isAlarm(name);
        switch (Alarm.readType(name))
        {
1 Like

I understand the error in my implementation. I will re-write it Such that it updates disables or enables the alarms instead of creating new ones. I would still like to know how to read the values of the alarms. The only method that returns the ALARMID is the nextTrigger() and I haven’t got that to return anything but 255.

I sorted out the issue related to assigning the global variables and freeing them up before creating new ones. There is also an issue with the write function that’s described here Issue with a possible fix.
I made a function that gets details using all the debugging methods described in the h file. The alarms trigger and work fine for the first 24 hrs but after that they simply cease to exist. And i have seen this happen to OnceOnly timers and repeat Alarms that were called fine and returned true with time_t values and an ID as per the program. After the program is running for 24 hrs the values cease to exist once the call back is complete.

My first doubt would be memory issues. I have 2 other millis based timers running in the void loop. The max Alarms set in the h file were 20 and count() was 5. I am running the program on 2 photons and both have had this happen.

Any suggestion?

Hi @Ali,

Could you please share your final working code of scheduler?

If you share the code then it will be beneficial for other members of community as well.
Facing so many errors in my code/logic etc.

Can you share your code with me? I can help you fix it.

HI Ali!

You mentioned you were going to upload the whole code so other users could use it. I am working in a similar hydroponics system at home, and I would love to have the code to adapt to my purpose. Could you share it ?

Thank you very much! :slight_smile: