diff --git a/Arduino/BTCDieselHeater/src/OLED/SetTimerScreen.cpp b/Arduino/BTCDieselHeater/src/OLED/SetTimerScreen.cpp index ff01a58..fcede54 100644 --- a/Arduino/BTCDieselHeater/src/OLED/SetTimerScreen.cpp +++ b/Arduino/BTCDieselHeater/src/OLED/SetTimerScreen.cpp @@ -161,8 +161,8 @@ CSetTimerScreen::keyHandler(uint8_t event) _colSel = 4; } else { // in config fields, save new settings - NVstore.setTimerInfo(_timerID, _timerInfo); - _conflictID = CTimerManager::conflictTest(_timerID); + // test if the setting conflict with an already defined timer + _conflictID = CTimerManager::conflictTest(_timerInfo); if(_conflictID) { _timerInfo.enabled = 0; // cancel enabled status _ConflictTime = millis() + 1500; @@ -174,7 +174,7 @@ CSetTimerScreen::keyHandler(uint8_t event) } _rowSel = 0; _colSel = 0; - NVstore.setTimerInfo(_timerID, _timerInfo); // may have got disabled + NVstore.setTimerInfo(_timerID, _timerInfo); // save, but timer may have got disabled NVstore.save(); } } diff --git a/Arduino/BTCDieselHeater/src/RTC/TimerManager.cpp b/Arduino/BTCDieselHeater/src/RTC/TimerManager.cpp index e9b1d5f..b9df8dc 100644 --- a/Arduino/BTCDieselHeater/src/RTC/TimerManager.cpp +++ b/Arduino/BTCDieselHeater/src/RTC/TimerManager.cpp @@ -36,7 +36,6 @@ void CTimerManager::createMap(int timerMask, uint16_t timerMap[24*60], uint16_t timerIDs[24*60]) { - int maxPoints = 24*60; memset(timerMap, 0, 24*60*sizeof(uint16_t)); memset(timerIDs, 0, 24*60*sizeof(uint16_t)); @@ -48,46 +47,99 @@ CTimerManager::createMap(int timerMask, uint16_t timerMap[24*60], uint16_t timer // get timer settings NVstore.getTimerInfo(timerID, timer); // and add info to map if enabled - if(timer.enabled) { - // create linear minute of day values for start & stop - // note that if stop < start, that is treated as a timer that rolls over midnight - int timestart = timer.start.hour * 60 + timer.start.min; // linear minute of day - int timestop = timer.stop.hour * 60 + timer.stop.min; - for(int dayMinute = 0; dayMinute < maxPoints; dayMinute++) { - for(int day = 0x01; day != 0x80; day <<= 1) { - if(timer.enabled & day || timer.enabled & 0x80) { // specific or everyday - uint16_t activeday = day; // may also hold non repeat flag later - if(!timer.repeat) { - // flag timers that should get cancelled - activeday |= (activeday << 8); // combine one shot status in MS byte - } - if(timestop > timestart) { - // treat normal start < stop times (within same day) - if((dayMinute >= timestart) && (dayMinute < timestop)) { - timerMap[dayMinute] |= activeday; - timerIDs[dayMinute] |= timerBit; - } - } - else { - // time straddles a day, start > stop, special treatment required - if(dayMinute >= timestart) { - // true from start until midnight - timerMap[dayMinute] |= activeday; - timerIDs[dayMinute] |= timerBit; - } - if(dayMinute < timestop) { - // after midnight, before stop time, i.e. next day - // adjust for next day, taking care to wrap week - if(day & 0x40) // last day of week? - activeday >>= 6; // roll back to start of week - else - activeday <<= 1; // next day - timerMap[dayMinute] |= activeday; - timerIDs[dayMinute] |= timerBit; - } - } + createMap(timer, timerMap, timerIDs); + // if(timer.enabled) { + // // create linear minute of day values for start & stop + // // note that if stop < start, that is treated as a timer that rolls over midnight + // int timestart = timer.start.hour * 60 + timer.start.min; // linear minute of day + // int timestop = timer.stop.hour * 60 + timer.stop.min; + // for(int dayMinute = 0; dayMinute < maxPoints; dayMinute++) { + // for(int day = 0x01; day != 0x80; day <<= 1) { + // if(timer.enabled & day || timer.enabled & 0x80) { // specific or everyday + // uint16_t activeday = day; // may also hold non repeat flag later + // if(!timer.repeat) { + // // flag timers that should get cancelled + // activeday |= (activeday << 8); // combine one shot status in MS byte + // } + // if(timestop > timestart) { + // // treat normal start < stop times (within same day) + // if((dayMinute >= timestart) && (dayMinute < timestop)) { + // timerMap[dayMinute] |= activeday; + // timerIDs[dayMinute] |= timerBit; + // } + // } + // else { + // // time straddles a day, start > stop, special treatment required + // if(dayMinute >= timestart) { + // // true from start until midnight + // timerMap[dayMinute] |= activeday; + // timerIDs[dayMinute] |= timerBit; + // } + // if(dayMinute < timestop) { + // // after midnight, before stop time, i.e. next day + // // adjust for next day, taking care to wrap week + // if(day & 0x40) // last day of week? + // activeday >>= 6; // roll back to start of week + // else + // activeday <<= 1; // next day + // timerMap[dayMinute] |= activeday; + // timerIDs[dayMinute] |= timerBit; + // } + // } + // } + // } + // } + // } + } + } +} + +// create a timer map, based only upon the supplied timer info +// the other form of createMap uses the NV stored timer info +void +CTimerManager::createMap(sTimer& timer, uint16_t timerMap[24*60], uint16_t timerIDs[24*60]) +{ + int maxPoints = 24*60; + int timerBit = 0x0001 << timer.timerID; + + if(timer.enabled) { + // create linear minute of day values for start & stop + // note that if stop < start, that is treated as a timer that rolls over midnight + int timestart = timer.start.hour * 60 + timer.start.min; // linear minute of day + int timestop = timer.stop.hour * 60 + timer.stop.min; + for(int dayMinute = 0; dayMinute < maxPoints; dayMinute++) { + for(int day = 0x01; day != 0x80; day <<= 1) { + if(timer.enabled & day || timer.enabled & 0x80) { // specific or everyday + uint16_t activeday = day; // may also hold non repeat flag later + if(!timer.repeat) { + // flag timers that should get cancelled + activeday |= (activeday << 8); // combine one shot status in MS byte + } + if(timestop > timestart) { + // treat normal start < stop times (within same day) + if((dayMinute >= timestart) && (dayMinute < timestop)) { + timerMap[dayMinute] |= activeday; + timerIDs[dayMinute] |= timerBit; } } + else { + // time straddles a day, start > stop, special treatment required + if(dayMinute >= timestart) { + // true from start until midnight + timerMap[dayMinute] |= activeday; + timerIDs[dayMinute] |= timerBit; + } + if(dayMinute < timestop) { + // after midnight, before stop time, i.e. next day + // adjust for next day, taking care to wrap week + if(day & 0x40) // last day of week? + activeday >>= 6; // roll back to start of week + else + activeday <<= 1; // next day + timerMap[dayMinute] |= activeday; + timerIDs[dayMinute] |= timerBit; + } + } } } } @@ -117,12 +169,17 @@ uint16_t selectedTimer[24*60]; uint16_t timerIDs[24*60]; int -CTimerManager::conflictTest(int timerID) +CTimerManager::conflictTest(sTimer& timerInfo) { - int selectedMask = 0x0001 << timerID; +// int timerID = timerInfo.timerID; + int selectedMask = 0x0001 << timerInfo.timerID; // bit mask for timer we are testing + int othersMask = 0x3fff & ~selectedMask; + + memset(selectedTimer, 0, sizeof(selectedTimer)); + + createMap(timerInfo, selectedTimer, timerIDs); // create a map from the supplied timer info (under test) + createMap(othersMask, otherTimers, timerIDs); // create a map for all other timers, and get their unique IDs - createMap(selectedMask, selectedTimer, timerIDs); // create a map for the nominated timer (under test) - createMap(0x3fff & ~selectedMask, otherTimers, timerIDs); // create a map for all other timers, and get their unique IDs for(int i=0; i< 24*60; i++) { if(otherTimers[i] & selectedTimer[i]) { // both have the same day bit set - CONFLICT! uint16_t timerBit = timerIDs[i]; diff --git a/Arduino/BTCDieselHeater/src/RTC/TimerManager.h b/Arduino/BTCDieselHeater/src/RTC/TimerManager.h index 58e3f62..1b2307a 100644 --- a/Arduino/BTCDieselHeater/src/RTC/TimerManager.h +++ b/Arduino/BTCDieselHeater/src/RTC/TimerManager.h @@ -33,11 +33,14 @@ #include +struct sTimer; + class CTimerManager { public: static void createMap(int timermask, uint16_t map[24*60], uint16_t timerIDs[24*60]); + static void createMap(sTimer& timer, uint16_t timerMap[24*60], uint16_t timerIDs[24*60]); static void condenseMap(uint16_t timerMap[24*60], int factor); - static int conflictTest(int timerID); + static int conflictTest(sTimer& timer); }; #endif //__TIMERMANAGER_H__ \ No newline at end of file diff --git a/Arduino/BTCDieselHeater/src/Utility/NVStorage.cpp b/Arduino/BTCDieselHeater/src/Utility/NVStorage.cpp index 7aa09ca..689b4a5 100644 --- a/Arduino/BTCDieselHeater/src/Utility/NVStorage.cpp +++ b/Arduino/BTCDieselHeater/src/Utility/NVStorage.cpp @@ -294,6 +294,7 @@ void CESP32HeaterStorage::loadTimer(int idx) { sTimer& timer = _calValues.timer[idx]; + timer.timerID = idx; char SectionName[16]; sprintf(SectionName, "timer%d", idx+1); preferences.begin(SectionName, false); diff --git a/Arduino/BTCDieselHeater/src/Utility/NVStorage.h b/Arduino/BTCDieselHeater/src/Utility/NVStorage.h index bca8bf6..c6452cc 100644 --- a/Arduino/BTCDieselHeater/src/Utility/NVStorage.h +++ b/Arduino/BTCDieselHeater/src/Utility/NVStorage.h @@ -78,10 +78,12 @@ struct sTimer { uint8_t enabled; // timer enabled - each bit is a day of week flag uint8_t repeat; // repeating timer uint8_t temperature; + uint8_t timerID; // numeric ID sTimer() { enabled = 0; repeat = false; temperature = 22; + timerID = 0; }; sTimer& operator=(const sTimer& rhs) { start = rhs.start; @@ -89,6 +91,7 @@ struct sTimer { enabled = rhs.enabled; repeat = rhs.repeat; temperature = rhs.temperature; + timerID = rhs.timerID; }; void init() { start.hour = 0;