#include "TaskSchedulerManager.h" //Schedule part TaskSchedulerManagerHelper::Schedule::Schedule() : _days(0x7F), _months(0xFFF), _triggered(false), _triggerRightAway(true), _hasBeenTriggeredRightAway(false), _triggerType(TRIGGER_REPEAT), _mode(EVERY), _enabled(true), _millis(0), _everyMillis(1000), _dateTime(2000,0,0,0,0,0) { } TaskSchedulerManagerHelper::Schedule::Schedule(const TaskSchedulerManagerHelper::Schedule &Object) : _days(Object._days), _months(Object._months), _triggered(Object._triggered), _triggerRightAway(Object._triggerRightAway), _hasBeenTriggeredRightAway(Object._hasBeenTriggeredRightAway), _triggerType(Object._triggerType), _mode(Object._mode), _enabled(Object._enabled), _millis(Object._millis), _everyMillis(Object._everyMillis), _dateTime(Object._dateTime) { } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::scheduleBuilder() { return new TaskSchedulerManagerHelper::Schedule(); } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setMillis(uint32_t millis) { _everyMillis = millis; return this; } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setSeconds(uint32_t seconds) { if(seconds < 60) _dateTime = DateTime(_dateTime.year(), _dateTime.month(), _dateTime.day(), _dateTime.hour(), _dateTime.minute(), seconds); return TaskSchedulerManagerHelper::Schedule::setMillis(seconds*1000); } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setMinutes(uint32_t minutes) { if(minutes < 60) _dateTime = DateTime(_dateTime.year(), _dateTime.month(), _dateTime.day(), _dateTime.hour(), minutes, _dateTime.second()); return TaskSchedulerManagerHelper::Schedule::setSeconds(minutes*60); } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setHours(uint16_t hours) { if(hours < 24) _dateTime = DateTime(_dateTime.year(), _dateTime.month(), _dateTime.day(), hours, _dateTime.minute(), _dateTime.second()); return TaskSchedulerManagerHelper::Schedule::setMinutes(hours*60); } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setDateTime(DateTime &dateTime) { _dateTime = dateTime; return this; } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setDays(uint8_t days) { _days = days; return this; } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setMonths(uint16_t months) { _months = months; return this; } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setTriggerRightAway(boolean enabled) { _triggerRightAway = enabled; _hasBeenTriggeredRightAway = false; return this; } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setTriggerType(TriggerType triggerType) { _triggerType = triggerType; return this; } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setMode(Mode mode) { _mode = mode; return this; } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setEnabled(boolean enabled) { _enabled = enabled; return this; } void TaskSchedulerManagerHelper::Schedule::printDebug() { Serial.printf("###Schedule DEBUG###\nMillis -> %u\nTrigger right away -> %u\nTrigger type -> %u\nMode -> %u\nEnabled -> %u\nDays -> %u\nMonth -> >%u\n h : %u, m : %u, s : %u\n######\n",_everyMillis, _triggerRightAway, _triggerType, _mode, _enabled, _days, _months, _dateTime.hour(), _dateTime.minute(), _dateTime.second()); } // TaskScheduleManager part TaskSchedulerManager::TaskSchedulerManager() : _nextTaskIndexToBeRun(0), _rtcManager(NULL) { } TaskSchedulerManager::TaskSchedulerManager(RtcManager &rtcManager) : _nextTaskIndexToBeRun(0), _rtcManager(&rtcManager) { } boolean TaskSchedulerManager::addTask(const char *name, TaskSchedulerManagerHelper::Schedule *schedule, boolean (*taskRoutine)(void*), void *pData) { if(schedule == NULL)return false; schedule->_millis = millis(); boolean result = _taskDataDictio.add(name, new TaskData({*schedule, taskRoutine, pData})); delete schedule;schedule = NULL; return result; } boolean TaskSchedulerManager::addTask(uint16_t id, TaskSchedulerManagerHelper::Schedule *schedule, boolean (*taskRoutine)(void*), void *pData) { if(schedule == NULL)return false; schedule->_millis = millis(); boolean result = _taskDataDictio.add(id, new TaskData({*schedule, taskRoutine, pData})); delete schedule;schedule = NULL; return result; } boolean TaskSchedulerManager::removeTask(const char *name) { return _taskDataDictio.remove(name); } boolean TaskSchedulerManager::removeTask(uint16_t id) { return _taskDataDictio.remove(id); } void TaskSchedulerManager::enableTask(const char *name) { getTask(name)->setEnabled(true); } void TaskSchedulerManager::enableTask(uint16_t id) { getTask(id)->setEnabled(true); } void TaskSchedulerManager::disableTask(const char *name) { getTask(name)->setEnabled(false); } void TaskSchedulerManager::disableTask(uint16_t id) { getTask(id)->setEnabled(false); } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManager::getTask(const char *name) { return &(_taskDataDictio(name)->schedule); } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManager::getTask(uint16_t id) { char indiceToStr[10]; sprintf(indiceToStr,"%d", id); return &(_taskDataDictio(indiceToStr)->schedule); } void TaskSchedulerManager::clearTask() { _taskDataDictio.clear(); } void TaskSchedulerManager::run() { if(_taskDataDictio.count() == 0)return; if(_nextTaskIndexToBeRun >= _taskDataDictio.count())_nextTaskIndexToBeRun = 0; TaskData *p = _taskDataDictio.getAt(_nextTaskIndexToBeRun); if(p == NULL)//Shouldn't happen return; if(p->schedule._enabled) { if(p->schedule._mode == TaskSchedulerManagerHelper::Schedule::Mode::EVERY) { if(p->schedule._triggerRightAway && !p->schedule._hasBeenTriggeredRightAway)//Should it be executed right away ? { p->schedule._millis = millis(); p->schedule._hasBeenTriggeredRightAway = true; p->schedule._triggered = true; (*(p->taskRoutine))(p->pData); } else if(millis() - p->schedule._millis >= p->schedule._everyMillis) //Or should it be executed { p->schedule._millis = millis(); p->schedule._triggered = true; (*(p->taskRoutine))(p->pData); } } else //AT mode task { } } if(p->schedule._triggerType != TaskSchedulerManagerHelper::Schedule::TRIGGER_ONCE_AND_DELETE)_nextTaskIndexToBeRun++; else if(p->schedule._triggerType == TaskSchedulerManagerHelper::Schedule::TRIGGER_ONCE_AND_DELETE && !(p->schedule._triggered))_nextTaskIndexToBeRun++; else if(p->schedule._triggerType == TaskSchedulerManagerHelper::Schedule::TRIGGER_ONCE_AND_DELETE && p->schedule._triggered) //If the task has to be deleted after it has been executed and if it has, we delete it { _taskDataDictio.removeAt(_nextTaskIndexToBeRun); } } unsigned int TaskSchedulerManager::taskCount() { return _taskDataDictio.count(); } uint16_t TaskSchedulerManager::findFreeTaskId() { uint16_t idToTry(1); while(_taskDataDictio(idToTry) != NULL) { idToTry++; } return idToTry; }