Extreme makeover to timer manager, now properly shows one shot next day timers in timer chart.
Added cursor showing time of day on Timer chart.
This commit is contained in:
parent
f154580eb2
commit
c1207e66ef
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
|
@ -132,4 +132,37 @@
|
|||
<varNfHeight>const uint8_t {0}Height</varNfHeight>
|
||||
<displayName>splash</displayName>
|
||||
</OutputConfiguration>
|
||||
<OutputConfiguration>
|
||||
<commentVariableName>true</commentVariableName>
|
||||
<commentCharVisualizer>true</commentCharVisualizer>
|
||||
<commentCharDescriptor>true</commentCharDescriptor>
|
||||
<commentStyle>Cpp</commentStyle>
|
||||
<bmpVisualizerChar>#</bmpVisualizerChar>
|
||||
<rotation>RotateNinety</rotation>
|
||||
<flipHorizontal>true</flipHorizontal>
|
||||
<flipVertical>false</flipVertical>
|
||||
<paddingRemovalHorizontal>Fixed</paddingRemovalHorizontal>
|
||||
<paddingRemovalVertical>Tighest</paddingRemovalVertical>
|
||||
<lineWrap>AtColumn</lineWrap>
|
||||
<bitLayout>RowMajor</bitLayout>
|
||||
<byteOrder>MsbFirst</byteOrder>
|
||||
<byteFormat>Hex</byteFormat>
|
||||
<byteLeadingString>0x</byteLeadingString>
|
||||
<generateLookupArray>true</generateLookupArray>
|
||||
<descCharWidth>DisplayInBits</descCharWidth>
|
||||
<descCharHeight>DisplayInBits</descCharHeight>
|
||||
<descFontHeight>DisplayInBits</descFontHeight>
|
||||
<generateLookupBlocks>false</generateLookupBlocks>
|
||||
<lookupBlocksNewAfterCharCount>80</lookupBlocksNewAfterCharCount>
|
||||
<descImgWidth>DisplayInBits</descImgWidth>
|
||||
<descImgHeight>DisplayInBits</descImgHeight>
|
||||
<generateSpaceCharacterBitmap>true</generateSpaceCharacterBitmap>
|
||||
<spaceGenerationPixels>2</spaceGenerationPixels>
|
||||
<varNfBitmaps>const uint8_t PROGMEM {0}Bitmaps </varNfBitmaps>
|
||||
<varNfCharInfo>const FONT_CHAR_INFO PROGMEM {0}Descriptors</varNfCharInfo>
|
||||
<varNfFontInfo>const FONT_INFO {0}FontInfo</varNfFontInfo>
|
||||
<varNfWidth>const uint8_t {0}Width</varNfWidth>
|
||||
<varNfHeight>const uint8_t {0}Height</varNfHeight>
|
||||
<displayName>Fonts</displayName>
|
||||
</OutputConfiguration>
|
||||
</ArrayOfOutputConfiguration>
|
|
@ -269,7 +269,6 @@ CScreenManager::begin(bool bNoClock)
|
|||
if(!bNoClock)
|
||||
menuloop.push_back(new CClockScreen(*_pDisplay, *this)); // clock
|
||||
menuloop.push_back(new CPrimingScreen(*_pDisplay, *this)); // mode / priming
|
||||
// menuloop.push_back(new CWiFiScreen(*_pDisplay, *this)); // comms info
|
||||
menuloop.push_back(new CGPIOInfoScreen(*_pDisplay, *this)); // GPIO info
|
||||
menuloop.push_back(new CMenuTrunkScreen(*_pDisplay, *this));
|
||||
_Screens.push_back(menuloop);
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "../Utility/macros.h"
|
||||
|
||||
|
||||
CSetClockScreen::CSetClockScreen(C128x64_OLED& display, CScreenManager& mgr) : CScreenHeader(display, mgr)
|
||||
CSetClockScreen::CSetClockScreen(C128x64_OLED& display, CScreenManager& mgr) : CScreen(display, mgr)
|
||||
{
|
||||
_initUI();
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ CSetClockScreen::CSetClockScreen(C128x64_OLED& display, CScreenManager& mgr) : C
|
|||
void
|
||||
CSetClockScreen::onSelect()
|
||||
{
|
||||
CScreenHeader::onSelect();
|
||||
CScreen::onSelect();
|
||||
_initUI();
|
||||
}
|
||||
|
||||
|
@ -68,18 +68,18 @@ CSetClockScreen::show()
|
|||
if(deltaT >= 0) {
|
||||
_nextT += 1000;
|
||||
|
||||
CScreenHeader::show(false);
|
||||
CScreen::show();
|
||||
_display.clearDisplay();
|
||||
|
||||
char str[16];
|
||||
int xPos, yPos;
|
||||
|
||||
_printInverted(0, 15, " Set Clock ", true);
|
||||
_showTitle("Set Clock");
|
||||
|
||||
const BTCDateTime& now = Clock.get();
|
||||
if(_rowSel == 0) {
|
||||
// update printable values
|
||||
working = now;
|
||||
// DELIBERATE DROP THROUGH HERE
|
||||
}
|
||||
|
||||
if(_SaveTime) {
|
||||
|
@ -90,12 +90,13 @@ CSetClockScreen::show()
|
|||
}
|
||||
}
|
||||
else {
|
||||
yPos = 28;
|
||||
yPos = 20;
|
||||
xPos = 6;
|
||||
// date
|
||||
if(_rowSel==0) {
|
||||
xPos = 20;
|
||||
xPos = 18;
|
||||
_printMenuText(xPos, yPos, working.dowStr());
|
||||
xPos = 20;
|
||||
}
|
||||
|
||||
sprintf(str, "%d", working.day());
|
||||
|
@ -107,7 +108,7 @@ CSetClockScreen::show()
|
|||
sprintf(str, "%d", working.year());
|
||||
_printMenuText(xPos, yPos, str, _rowSel==3);
|
||||
// time
|
||||
yPos = 40;
|
||||
yPos = 32;
|
||||
xPos = 26;
|
||||
sprintf(str, "%02d", working.hour());
|
||||
_printMenuText(xPos, yPos, str, _rowSel==4);
|
||||
|
@ -123,22 +124,23 @@ CSetClockScreen::show()
|
|||
_printMenuText(xPos, yPos, str, _rowSel==6);
|
||||
if(_rowSel>=1)
|
||||
_printMenuText(_display.width()-border, yPos, "SET", _rowSel==7, eRightJustify);
|
||||
}
|
||||
// navigation line
|
||||
xPos = _display.xCentre();
|
||||
if(_rowSel == 0) {
|
||||
yPos = 53;
|
||||
_printMenuText(_display.width(), yPos, "\030Edit", false, eRightJustify);
|
||||
_printMenuText(xPos, yPos, " Exit ", true, eCentreJustify);
|
||||
}
|
||||
else {
|
||||
_display.drawFastHLine(0, 52, 128, WHITE);
|
||||
_printMenuText(xPos, 56, "\033\032 Sel \030\031 Adj", false, eCentreJustify);
|
||||
if(_rowSel == 7) {
|
||||
_printMenuText(xPos, 56, "Save", false, eCentreJustify);
|
||||
|
||||
// navigation line
|
||||
xPos = _display.xCentre();
|
||||
if(_rowSel == 0) {
|
||||
yPos = 53;
|
||||
_printMenuText(_display.width(), yPos, "\030Edit", false, eRightJustify);
|
||||
_printMenuText(xPos, yPos, " Exit ", true, eCentreJustify);
|
||||
}
|
||||
else {
|
||||
_printMenuText(xPos, 56, "Abort", false, eCentreJustify);
|
||||
_display.drawFastHLine(0, 52, 128, WHITE);
|
||||
_printMenuText(xPos, 56, "\033\032 Sel \030\031 Adj", false, eCentreJustify);
|
||||
if(_rowSel == 7) {
|
||||
_printMenuText(xPos, 56, "Save", false, eCentreJustify);
|
||||
}
|
||||
else {
|
||||
_printMenuText(xPos, 56, "Abort", false, eCentreJustify);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ class C128x64_OLED;
|
|||
class CScreenManager;
|
||||
class CProtocol;
|
||||
|
||||
class CSetClockScreen : public CScreenHeader {
|
||||
class CSetClockScreen : public CScreen {
|
||||
int _rowSel;
|
||||
unsigned long _nextT;
|
||||
BTCDateTime working;
|
||||
|
|
|
@ -72,7 +72,7 @@ CSetTimerScreen::show()
|
|||
int xPos, yPos;
|
||||
|
||||
if(_rowSel == 0) {
|
||||
NVstore.getTimerInfo(_timerID, _timerInfo);
|
||||
NVstore.getTimerInfo(_timerID, _timerInfo); // ensure actual data when on base menu bar
|
||||
}
|
||||
sprintf(str, "Set Timer #%d", _timerID + 1);
|
||||
_showTitle(str);
|
||||
|
@ -156,34 +156,11 @@ CSetTimerScreen::keyHandler(uint8_t event)
|
|||
static bool bHeld = false;
|
||||
// handle initial key press
|
||||
if(event & keyPressed) {
|
||||
_repeatCount = 0;
|
||||
bHeld = false;
|
||||
// press CENTRE
|
||||
if(event & key_Centre) {
|
||||
if(_rowSel == 0) {
|
||||
_ScreenManager.selectMenu(CScreenManager::RootMenuLoop); // exit: return to clock screen
|
||||
}
|
||||
else if(_rowSel == 2) { // exit from per day settings
|
||||
_rowSel = 1;
|
||||
_colSel = 4;
|
||||
}
|
||||
else { // in config fields, save new settings
|
||||
// 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;
|
||||
_ScreenManager.reqUpdate();
|
||||
_rowSel = 1;
|
||||
_colSel = 4; // select enable/disable
|
||||
}
|
||||
else {
|
||||
_SaveTime = millis() + 1500;
|
||||
_ScreenManager.reqUpdate();
|
||||
_rowSel = 0;
|
||||
_colSel = 0;
|
||||
}
|
||||
CTimerManager::setTimer(_timerInfo);
|
||||
}
|
||||
// ON KEY RELEASE
|
||||
}
|
||||
// press LEFT - navigate fields, or screens
|
||||
if(event & key_Left) {
|
||||
|
@ -225,8 +202,14 @@ CSetTimerScreen::keyHandler(uint8_t event)
|
|||
|
||||
// handle held down keys
|
||||
if(event & keyRepeat) {
|
||||
_repeatCount++;
|
||||
bHeld = true;
|
||||
if(_rowSel == 1) {
|
||||
if(event & key_Centre) {
|
||||
_ScreenManager.reqUpdate();
|
||||
_rowSel = 0;
|
||||
_colSel = 0;
|
||||
}
|
||||
if(_colSel < 4) {
|
||||
// fast repeat of hour/minute adjustments by holding up or down keys
|
||||
if(event & key_Down) _adjust(-1);
|
||||
|
@ -244,9 +227,37 @@ CSetTimerScreen::keyHandler(uint8_t event)
|
|||
}
|
||||
|
||||
if(event & keyReleased) {
|
||||
if(!bHeld) {
|
||||
int maskDOW = 0x01 << _colSel;
|
||||
|
||||
if(!bHeld) {
|
||||
if(event & key_Centre) {
|
||||
if(_rowSel == 0) {
|
||||
_ScreenManager.selectMenu(CScreenManager::RootMenuLoop); // exit: return to clock screen
|
||||
}
|
||||
else if(_rowSel == 2) { // exit from per day settings
|
||||
_rowSel = 1;
|
||||
_colSel = 4;
|
||||
}
|
||||
else { // in config fields, save new settings
|
||||
// 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;
|
||||
_ScreenManager.reqUpdate();
|
||||
_rowSel = 1;
|
||||
_colSel = 4; // select enable/disable
|
||||
}
|
||||
else {
|
||||
_SaveTime = millis() + 1500;
|
||||
_ScreenManager.reqUpdate();
|
||||
_rowSel = 0;
|
||||
_colSel = 0;
|
||||
}
|
||||
CTimerManager::setTimer(_timerInfo);
|
||||
}
|
||||
}
|
||||
|
||||
int maskDOW = 0x01 << _colSel;
|
||||
// released DOWN - can only leave adjustment by using OK (centre button)
|
||||
if(event & key_Down) {
|
||||
// adjust selected item
|
||||
|
|
|
@ -33,6 +33,7 @@ class CProtocol;
|
|||
class CSetTimerScreen : public CScreen {
|
||||
int _rowSel;
|
||||
int _colSel;
|
||||
int _repeatCount;
|
||||
int _timerID;
|
||||
unsigned long _SaveTime;
|
||||
unsigned long _ConflictTime;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "../../lib/RTClib/RTClib.h"
|
||||
#include "fonts/MiniFont.h"
|
||||
#include "../RTC/TimerManager.h"
|
||||
#include "../RTC/Clock.h"
|
||||
|
||||
|
||||
static uint8_t condensed[7][120];
|
||||
|
@ -50,7 +51,6 @@ CTimerChartScreen::CTimerChartScreen(C128x64_OLED& display, CScreenManager& mgr,
|
|||
void
|
||||
CTimerChartScreen::onSelect()
|
||||
{
|
||||
CTimerManager::createMap();
|
||||
CTimerManager::condenseMap(condensed);
|
||||
}
|
||||
|
||||
|
@ -145,10 +145,27 @@ CTimerChartScreen::show()
|
|||
}
|
||||
}
|
||||
}
|
||||
cursor();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CTimerChartScreen::cursor()
|
||||
{
|
||||
static bool bShowWhite = true;
|
||||
// create masking based upon TODAY
|
||||
const BTCDateTime tNow = Clock.get();
|
||||
int dow = tNow.dayOfTheWeek();
|
||||
int todayTime = tNow.hour() * 60 + tNow.minute();
|
||||
|
||||
int yPos = 6 + 7*dow;
|
||||
int xPos = 9 + int(todayTime * 0.0833333); // 1/12
|
||||
|
||||
_display.drawFastVLine(xPos, yPos, 8, bShowWhite ? WHITE : BLACK);
|
||||
|
||||
bShowWhite = !bShowWhite;
|
||||
}
|
||||
|
||||
bool
|
||||
CTimerChartScreen::keyHandler(uint8_t event)
|
||||
|
|
|
@ -34,6 +34,7 @@ class CTimerChartScreen : public CScreen {
|
|||
int _colSel;
|
||||
int _instance;
|
||||
unsigned long _SaveTime;
|
||||
void cursor();
|
||||
|
||||
public:
|
||||
CTimerChartScreen(C128x64_OLED& display, CScreenManager& mgr, int instance);
|
||||
|
|
|
@ -68,9 +68,9 @@ DebugPort.println("Using millis() based psuedo \"Real Time Clock\"");
|
|||
|
||||
_nextRTCfetch = millis();
|
||||
|
||||
CTimerManager::createMap();
|
||||
|
||||
update();
|
||||
|
||||
CTimerManager::createMap();
|
||||
}
|
||||
|
||||
const BTCDateTime&
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "../Utility/NVStorage.h"
|
||||
#include "../Utility/helpers.h"
|
||||
|
||||
uint8_t CTimerManager::weekTimerIDs[7][CTimerManager::_dayMinutes]; // b[7] = repeat flag, b[3..0] = timer ID
|
||||
uint8_t CTimerManager::weekMap[7][CTimerManager::_dayMinutes]; // b[7] = repeat flag, b[3..0] = timer ID
|
||||
|
||||
int CTimerManager::activeTimer = 0;
|
||||
int CTimerManager::activeDow = 0;
|
||||
|
@ -42,6 +42,17 @@ int CTimerManager::nextTimer = 0;
|
|||
int CTimerManager::nextStart = 0;
|
||||
bool CTimerManager::timerChanged = false;
|
||||
|
||||
#define SET_MAPS() { \
|
||||
if(pTimerMap) { \
|
||||
pTimerMap[dayMinute] |= activeday; \
|
||||
if(pTimerIDs) \
|
||||
pTimerIDs[dayMinute] |= timerBit; \
|
||||
} \
|
||||
else { \
|
||||
weekMap[dow][dayMinute] = recordTimer; \
|
||||
} \
|
||||
}
|
||||
|
||||
// create a bitmap that describes the pattern of on/off times
|
||||
void
|
||||
CTimerManager::createMap(int timerMask, uint16_t* pTimerMap, uint16_t* pTimerIDs)
|
||||
|
@ -52,7 +63,8 @@ CTimerManager::createMap(int timerMask, uint16_t* pTimerMap, uint16_t* pTimerIDs
|
|||
memset(pTimerIDs, 0, _dayMinutes*sizeof(uint16_t));
|
||||
}
|
||||
else {
|
||||
memset(weekTimerIDs, 0, _dayMinutes*7*sizeof(uint8_t));
|
||||
DebugPort.println("Erasing weekMap");
|
||||
memset(weekMap, 0, _dayMinutes*7*sizeof(uint8_t));
|
||||
}
|
||||
|
||||
for(int timerID=0; timerID < 14; timerID++) {
|
||||
|
@ -74,15 +86,14 @@ CTimerManager::createMap(int timerMask, uint16_t* pTimerMap, uint16_t* pTimerIDs
|
|||
void
|
||||
CTimerManager::createMap(sTimer& timer, uint16_t* pTimerMap, uint16_t* pTimerIDs)
|
||||
{
|
||||
int timerBit = 0x0001 << timer.timerID;
|
||||
|
||||
const BTCDateTime tNow = Clock.get();
|
||||
int todayDoW = 1 << tNow.dayOfTheWeek();
|
||||
int todayTime = tNow.hour() * 60 + tNow.minute();
|
||||
if(createOneShotMap(timer, pTimerMap, pTimerIDs)) {
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
// create linear minutes of day values for start & stop
|
||||
// note that if stop < start, the timer rolls over midnight
|
||||
int timerBit = 0x0001 << timer.timerID; // bit required for timer ID map
|
||||
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 < _dayMinutes; dayMinute++) {
|
||||
|
@ -90,62 +101,43 @@ CTimerManager::createMap(sTimer& timer, uint16_t* pTimerMap, uint16_t* pTimerIDs
|
|||
int dayBit = 0x01 << dow;
|
||||
if(timer.enabled & dayBit || timer.enabled & 0x80) { // specific or everyday
|
||||
uint16_t activeday = dayBit; // may also hold non repeat flag later
|
||||
uint8_t recordTimer = (timer.timerID + 1) | (timer.repeat ? 0x80 : 0x00);
|
||||
uint8_t recordTimer = (timer.timerID + 1) | (timer.repeat ? 0x80 : 0x00); // full week timer ID map
|
||||
if(!timer.repeat) {
|
||||
// flag timers that should get cancelled
|
||||
activeday |= (activeday << 8); // combine one shot status in MS byte
|
||||
}
|
||||
if(timer.enabled == 0x80 && !timer.repeat) { // on-shot next occurrence timer
|
||||
if(todayTime > timestart) {
|
||||
}
|
||||
}
|
||||
|
||||
// SET_MAPS() macro saves values as below:
|
||||
//
|
||||
// activeday -> pTimerMap[dayMinute] (if pTimerMap != NULL)
|
||||
// timerBit -> pTimerID[dayMinute] (if pTimerMap != NULL AND pTimerID != NULL)
|
||||
// recordTimer -> weekMap[dow][dayMinute] (if pTimerMap == NULL)
|
||||
//
|
||||
if(timestop > timestart) {
|
||||
// treat normal start < stop times (within same day)
|
||||
if((dayMinute >= timestart) && (dayMinute < timestop)) {
|
||||
if(pTimerMap) {
|
||||
pTimerMap[dayMinute] |= activeday;
|
||||
if(pTimerIDs)
|
||||
pTimerIDs[dayMinute] |= timerBit;
|
||||
}
|
||||
else {
|
||||
weekTimerIDs[dow][dayMinute] = recordTimer;
|
||||
}
|
||||
SET_MAPS();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// time straddles a day, start > stop, special treatment required
|
||||
if(dayMinute >= timestart) {
|
||||
// true from start until midnight
|
||||
if(pTimerMap) {
|
||||
pTimerMap[dayMinute] |= activeday;
|
||||
if(pTimerIDs)
|
||||
pTimerIDs[dayMinute] |= timerBit;
|
||||
}
|
||||
else {
|
||||
weekTimerIDs[dow][dayMinute] = recordTimer;
|
||||
}
|
||||
SET_MAPS();
|
||||
}
|
||||
if(dayMinute < timestop) {
|
||||
// after midnight, before stop time, i.e. next day
|
||||
// adjust for next day, taking care to wrap week
|
||||
if(dow == 6) { // last day of week?
|
||||
activeday >>= 6; // roll back to start of week
|
||||
if(pTimerMap == NULL) {
|
||||
weekTimerIDs[0][dayMinute] = recordTimer;
|
||||
}
|
||||
dow = 0;
|
||||
// because activeday holds both cancel and day info, shift it
|
||||
activeday >>= 6; // roll back to start of week -
|
||||
}
|
||||
else {
|
||||
dow++;
|
||||
activeday <<= 1; // next day
|
||||
if(pTimerMap == NULL) {
|
||||
weekTimerIDs[dow+1][dayMinute] = recordTimer;
|
||||
}
|
||||
}
|
||||
if(pTimerMap) {
|
||||
pTimerMap[dayMinute] |= activeday;
|
||||
if(pTimerIDs)
|
||||
pTimerIDs[dayMinute] |= timerBit;
|
||||
}
|
||||
SET_MAPS();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -210,7 +202,7 @@ CTimerManager::condenseMap(uint8_t timerMap[7][120])
|
|||
uint8_t condense = 0;
|
||||
for(int subInterval = 0; subInterval < 12; subInterval++, dayMinute++) {
|
||||
if(!condense)
|
||||
condense = weekTimerIDs[dow][dayMinute];
|
||||
condense = weekMap[dow][dayMinute];
|
||||
}
|
||||
timerMap[dow][opIndex++] = condense;
|
||||
}
|
||||
|
@ -228,7 +220,7 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
|
|||
|
||||
int retval = 0;
|
||||
int dayMinute = (hour * 60) + minute;
|
||||
int newID = weekTimerIDs[dow][dayMinute];
|
||||
int newID = weekMap[dow][dayMinute];
|
||||
if(activeTimer != newID) {
|
||||
|
||||
DebugPort.printf("Timer ID change detected: %d", activeTimer & 0x0f);
|
||||
|
@ -292,8 +284,8 @@ CTimerManager::findNextTimer(int hour, int minute, int dow)
|
|||
|
||||
int limit = 24*60*7;
|
||||
while(limit--) {
|
||||
if(weekTimerIDs[dow][dayMinute] & 0x0f) {
|
||||
nextTimer = weekTimerIDs[dow][dayMinute];
|
||||
if(weekMap[dow][dayMinute] & 0x0f) {
|
||||
nextTimer = weekMap[dow][dayMinute];
|
||||
nextStart = dow*_dayMinutes + dayMinute;
|
||||
return nextTimer;
|
||||
}
|
||||
|
@ -352,3 +344,60 @@ CTimerManager::conflictTest(int ID)
|
|||
timerChanged = true;
|
||||
return conflictID;
|
||||
}
|
||||
|
||||
// special handling for next occurence of one-shot, non-repeating timers
|
||||
bool
|
||||
CTimerManager::createOneShotMap(sTimer& timer, uint16_t* pTimerMap, uint16_t* pTimerIDs)
|
||||
{
|
||||
if((timer.enabled == 0x80) && !timer.repeat) { // on-shot next occurrence timer
|
||||
DebugPort.printf("One shot, next occurence timer #%d\r\n", timer.timerID+1);
|
||||
int timerBit = 0x0001 << timer.timerID; // value required for full week map
|
||||
int timestart = timer.start.hour * 60 + timer.start.min; // linear minute of day
|
||||
int timestop = timer.stop.hour * 60 + timer.stop.min;
|
||||
// create masking based upon TODAY
|
||||
const BTCDateTime tNow = Clock.get();
|
||||
int dow = tNow.dayOfTheWeek();
|
||||
int todayTime = tNow.hour() * 60 + tNow.minute();
|
||||
// wrap to next day if start time falls behind current time
|
||||
if(todayTime >= timestart) {
|
||||
dow++;
|
||||
WRAPUPPERLIMIT(dow, 6, 0);
|
||||
}
|
||||
// create masks and record values for the assorted target arrays
|
||||
uint16_t activeday = 1 << dow; // set day bit
|
||||
activeday |= activeday << 8; // and set non repeat flag in MSB
|
||||
uint8_t recordTimer = (timer.timerID + 1);
|
||||
|
||||
// SET_MAPS() macro saves values as below:
|
||||
//
|
||||
// activeday -> pTimerMap[dayMinute] (if pTimerMap != NULL)
|
||||
// timerBit -> pTimerID[dayMinute] (if pTimerMap != NULL AND pTimerID != NULL)
|
||||
// recordTimer -> weekMap[dow][dayMinute] (if pTimerMap == NULL)
|
||||
//
|
||||
if(timestart < timestop) {
|
||||
// timer does not wrap midnight - easy linear workout :-)
|
||||
for(int dayMinute = timestart; dayMinute < timestop; dayMinute++) {
|
||||
SET_MAPS();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// timer rolls over midnight
|
||||
// fill map up from start time till end of day
|
||||
for(int dayMinute = timestart; dayMinute < _dayMinutes; dayMinute++) {
|
||||
SET_MAPS();
|
||||
}
|
||||
// advance to next day, wrapping if required
|
||||
dow++;
|
||||
WRAPUPPERLIMIT(dow, 6, 0);
|
||||
activeday = 1 << dow; // set day bit
|
||||
activeday |= activeday << 8; // and set non repeat flag in MSB
|
||||
// complete map from midnight till stop time
|
||||
for(int dayMinute = 0; dayMinute < timestop; dayMinute++) {
|
||||
SET_MAPS();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ struct sTimer;
|
|||
class CTimerManager {
|
||||
public:
|
||||
static const int _dayMinutes = 24*60;
|
||||
static bool createOneShotMap(sTimer& timer, uint16_t* timerMap = NULL, uint16_t* timerIDs = NULL);
|
||||
static void createMap(int timermask = 0x3fff, uint16_t* timerMap = NULL, uint16_t* timerIDs = NULL);
|
||||
static void createMap(sTimer& timer, uint16_t* timerMap = NULL, uint16_t* timerIDs = NULL);
|
||||
static void condenseMap(uint16_t timerMap[_dayMinutes], int factor);
|
||||
|
@ -56,7 +57,7 @@ private:
|
|||
static int prevState;
|
||||
static int nextTimer;
|
||||
static int nextStart;
|
||||
static uint8_t weekTimerIDs[7][_dayMinutes]; // b[7] = repeat flag, b[3..0] = timer ID
|
||||
static uint8_t weekMap[7][_dayMinutes]; // b[7] = repeat flag, b[3..0] = timer ID
|
||||
static bool timerChanged;
|
||||
};
|
||||
|
||||
|
|
|
@ -562,7 +562,7 @@ void updateJSONclients(bool report)
|
|||
getBluetoothClient().send( expand.c_str() );
|
||||
unsigned long tBT = millis() - tStart;
|
||||
bNewTimerInfo = true;
|
||||
DebugPort.printf("JSON times : %ld,%ld,%ld\r\n", tJSON, tBT, tWF);
|
||||
// DebugPort.printf("JSON times : %ld,%ld,%ld\r\n", tJSON, tBT, tWF);
|
||||
}
|
||||
}
|
||||
// request timer refesh upon clients
|
||||
|
@ -577,7 +577,9 @@ void updateJSONclients(bool report)
|
|||
root.set("TimerRefresh", 1);
|
||||
root.printTo(jsonStr, 800);
|
||||
|
||||
DebugPort.printf("JSON send: %s\r\n", jsonStr);
|
||||
if (report) {
|
||||
DebugPort.printf("JSON send: %s\r\n", jsonStr);
|
||||
}
|
||||
sendWebSocketString( jsonStr );
|
||||
std::string expand = jsonStr;
|
||||
Expand(expand);
|
||||
|
|
|
@ -63,7 +63,7 @@ CFuelGauge::Integrate(float Hz)
|
|||
float fuelDelta = _pumpStrokes - _lastStoredVal;
|
||||
bool bStoppedSave = (Hz == 0) && (_pumpStrokes != _lastStoredVal);
|
||||
if(fuelDelta > 10 || bStoppedSave) { // record fuel usage every 10 minutes, or every 10 strokes
|
||||
DebugPort.printf("Storing fuel gauge: %.2f strokes\r\n", _pumpStrokes);
|
||||
// DebugPort.printf("Storing fuel gauge: %.2f strokes\r\n", _pumpStrokes);
|
||||
RTC_Store.setFuelGauge(_pumpStrokes); // uses RTC registers to store this
|
||||
_lastStoredVal = _pumpStrokes;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue