BUG FIX: Web update was broken due to watchdog timeout - added onProgress to FOTA - all good now
Returned to compact timer icon, press centre button to see start/stop times in base menus Version info screen refactored to show available version number New splash screen now presented upon display for a short time after upload or rename to /splash.bmp
This commit is contained in:
parent
ac091fa6d8
commit
08d0307fc8
|
@ -7,7 +7,6 @@
|
|||
|
||||
#include <Arduino.h>
|
||||
#include "esp32fota.h"
|
||||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <Update.h>
|
||||
|
@ -146,6 +145,7 @@ void esp32FOTA::execOTA()
|
|||
|
||||
if ( _onComplete != NULL) {
|
||||
if(!_onComplete(contentLength)) {
|
||||
Serial.println("ESP32FOTA: OnComplete handler returned false");
|
||||
Update.abort();
|
||||
}
|
||||
}
|
||||
|
@ -259,10 +259,12 @@ bool esp32FOTA::execHTTPcheck()
|
|||
|
||||
if (plversion > _firwmareVersion && fwtype == _firwmareType)
|
||||
{
|
||||
_newVersion = plversion;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_newVersion = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -289,6 +291,16 @@ String esp32FOTA::getDeviceID()
|
|||
return thisID;
|
||||
}
|
||||
|
||||
/**
|
||||
* onProgress, set a callback called during upload, passed directly thru to OTA Updater class
|
||||
* @access public
|
||||
* @param {[type]} void (*func)(size_t, size_t)
|
||||
*/
|
||||
void esp32FOTA::onProgress( std::function<void(size_t, size_t)> func ) {
|
||||
Update.onProgress(func);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* onComplete, set a callback after upload is completed, but not yet verified
|
||||
* @access public
|
||||
|
|
|
@ -19,14 +19,17 @@ public:
|
|||
bool execHTTPcheck();
|
||||
bool useDeviceID;
|
||||
String checkURL;
|
||||
void onProgress( std::function<void(size_t, size_t)> func );
|
||||
void onComplete( std::function<bool(int)> func );
|
||||
void onSuccess( std::function<void()> func );
|
||||
void onFail( std::function<void()> func );
|
||||
int getNewVersion() { return _newVersion; };
|
||||
private:
|
||||
String getHeaderValue(String header, String headerName);
|
||||
String getDeviceID();
|
||||
String _firwmareType;
|
||||
int _firwmareVersion;
|
||||
int _newVersion;
|
||||
String _host;
|
||||
String _bin;
|
||||
int _port;
|
||||
|
|
|
@ -123,8 +123,8 @@
|
|||
#define RX_DATA_TIMOUT 50
|
||||
|
||||
const int FirmwareRevision = 30;
|
||||
const int FirmwareSubRevision = 1;
|
||||
const char* FirmwareDate = "30 Jul 2019";
|
||||
const int FirmwareSubRevision = 2;
|
||||
const char* FirmwareDate = "3 Aug 2019";
|
||||
|
||||
|
||||
#ifdef ESP32
|
||||
|
@ -1434,6 +1434,7 @@ void feedWatchdog()
|
|||
DebugPort.printf("WD time = %lld\r\n", timeRem); // print longer WD intervals
|
||||
|
||||
timerWrite(watchdogTimer, 0); //reset timer (feed watchdog)
|
||||
timerAlarmWrite(watchdogTimer, 15000000, false); //set time in uS must be fed within this time or reboot
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -109,6 +109,7 @@ CBasicScreen::show()
|
|||
}
|
||||
}
|
||||
if((_showModeTime == 0) && _showSetModeTime) {
|
||||
showHeaderDetail(true);
|
||||
long tDelta = millis() - _showSetModeTime;
|
||||
if(tDelta < 0) {
|
||||
switch(_feedbackType) {
|
||||
|
@ -143,6 +144,7 @@ CBasicScreen::show()
|
|||
}
|
||||
if((_showModeTime == 0) && (_showSetModeTime == 0)) {
|
||||
showRunState();
|
||||
showHeaderDetail(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ CClockScreen::CClockScreen(C128x64_OLED& display, CScreenManager& mgr) : CScreen
|
|||
bool
|
||||
CClockScreen::show()
|
||||
{
|
||||
showHeaderDetail(true);
|
||||
|
||||
CScreenHeader::show(false);
|
||||
|
||||
const BTCDateTime& now = Clock.get();
|
||||
|
|
|
@ -82,6 +82,8 @@ CDetailedScreen::CDetailedScreen(C128x64_OLED& display, CScreenManager& mgr) : C
|
|||
bool
|
||||
CDetailedScreen::show()
|
||||
{
|
||||
showHeaderDetail(_showTarget != 0);
|
||||
|
||||
CScreenHeader::show(false);
|
||||
|
||||
int runstate = getHeaterInfo().getRunStateEx();
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
CScreenHeader::CScreenHeader(C128x64_OLED& disp, CScreenManager& mgr) : CScreen(disp, mgr)
|
||||
{
|
||||
_colon = false;
|
||||
_hdrDetail = false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -100,6 +101,14 @@ CScreenHeader::show(bool erase)
|
|||
return true;
|
||||
}
|
||||
|
||||
void crackVer(char* msg, int newVer)
|
||||
{
|
||||
int major = (int)(newVer * 0.01);
|
||||
int minor = newVer - major*100;
|
||||
float prtMajor = major * 0.1;
|
||||
sprintf(msg, "V%.1f.%d", prtMajor, minor);
|
||||
}
|
||||
|
||||
// Animate IN/OUT arrows against the WiFi icon, according to actual web server traffic:
|
||||
// an IN (down) arrow is drawn if incoming data has been detected.
|
||||
// an OUT (up) arrow is drawn if outgoing data has been sent.
|
||||
|
@ -120,62 +129,72 @@ CScreenHeader::animate()
|
|||
// animate timer icon,
|
||||
// inserting an update icon if new firmware available from internet web server
|
||||
_animateCount++;
|
||||
_batteryCount++;
|
||||
WRAPUPPERLIMIT(_animateCount, 9, 0);
|
||||
WRAPUPPERLIMIT(_batteryCount, 5, 0);
|
||||
if(isUpdateAvailable(true)) {
|
||||
WRAPUPPERLIMIT(_animateCount, 11, 0);
|
||||
int newVer = isUpdateAvailable(true);
|
||||
if(newVer) {
|
||||
int xPos = X_TIMER_ICON - 3;
|
||||
int yPos = Y_TIMER_ICON;
|
||||
char msg[16];
|
||||
CTransientFont AF(_display, &miniFontInfo); // temporarily use a mini font
|
||||
switch(_animateCount) {
|
||||
case 0:
|
||||
case 2:
|
||||
_display.fillRect(xPos, yPos, TimerIconInfo.width+3, TimerIconInfo.height, BLACK);
|
||||
_display.fillRect(xPos-2, yPos+12, 21, 5, BLACK); // erase annotation
|
||||
break;
|
||||
case 1:
|
||||
_drawBitmap(xPos+6, yPos, UpdateIconInfo);
|
||||
crackVer(msg, newVer);
|
||||
_printMenuText(xPos+19, yPos+12, msg, false, eRightJustify);
|
||||
break;
|
||||
case 2:
|
||||
_display.fillRect(xPos, yPos, TimerIconInfo.width+3, TimerIconInfo.height, BLACK);
|
||||
break;
|
||||
case 3:
|
||||
_display.fillRect(xPos-8, yPos+12, 30, 5, BLACK); // erase version annotation
|
||||
default:
|
||||
showTimers();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int xPos = X_BATT_ICON;
|
||||
int yPos = Y_BATT_ICON;
|
||||
showTimers();
|
||||
}
|
||||
|
||||
switch(_batteryCount) {
|
||||
case 0:
|
||||
// establish battery icon flash pattern
|
||||
// > 0.5 over LVC - solid
|
||||
// < 0.5 over LVC - slow flash
|
||||
// < LVC - fast flash
|
||||
_batteryWarn = SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue(), false);
|
||||
|
||||
_batteryCount++;
|
||||
WRAPUPPERLIMIT(_batteryCount, 5, 0);
|
||||
int xPos = X_BATT_ICON;
|
||||
int yPos = Y_BATT_ICON;
|
||||
switch(_batteryCount) {
|
||||
case 0:
|
||||
// establish battery icon flash pattern
|
||||
// > 0.5 over LVC - solid
|
||||
// < 0.5 over LVC - slow flash
|
||||
// < LVC - fast flash
|
||||
_batteryWarn = SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue(), false);
|
||||
|
||||
showBatteryIcon(getBatteryVoltage(true));
|
||||
break;
|
||||
case 1:
|
||||
if(_batteryWarn == 2)
|
||||
_display.fillRect(xPos, yPos, BatteryIconInfo.width, BatteryIconInfo.height, BLACK);
|
||||
break;
|
||||
case 2:
|
||||
if(_batteryWarn == 2)
|
||||
showBatteryIcon(getBatteryVoltage(true));
|
||||
break;
|
||||
case 1:
|
||||
if(_batteryWarn == 2)
|
||||
_display.fillRect(xPos, yPos, BatteryIconInfo.width, BatteryIconInfo.height, BLACK);
|
||||
break;
|
||||
case 2:
|
||||
if(_batteryWarn == 2)
|
||||
showBatteryIcon(getBatteryVoltage(true));
|
||||
break;
|
||||
case 3:
|
||||
if(_batteryWarn) // works for either < LVC, or < LVC+0.5
|
||||
_display.fillRect(xPos, yPos, BatteryIconInfo.width, BatteryIconInfo.height, BLACK);
|
||||
break;
|
||||
case 4:
|
||||
if(_batteryWarn == 2)
|
||||
showBatteryIcon(getBatteryVoltage(true));
|
||||
break;
|
||||
case 5:
|
||||
if(_batteryWarn == 2)
|
||||
_display.fillRect(xPos, yPos, BatteryIconInfo.width, BatteryIconInfo.height, BLACK);
|
||||
break;
|
||||
break;
|
||||
case 3:
|
||||
if(_batteryWarn) // works for either < LVC, or < LVC+0.5
|
||||
_display.fillRect(xPos, yPos, BatteryIconInfo.width, BatteryIconInfo.height, BLACK);
|
||||
break;
|
||||
case 4:
|
||||
if(_batteryWarn == 2)
|
||||
showBatteryIcon(getBatteryVoltage(true));
|
||||
break;
|
||||
case 5:
|
||||
if(_batteryWarn == 2)
|
||||
_display.fillRect(xPos, yPos, BatteryIconInfo.width, BatteryIconInfo.height, BLACK);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
showWifiIcon();
|
||||
|
@ -295,21 +314,36 @@ CScreenHeader::showBatteryIcon(float voltage)
|
|||
int
|
||||
CScreenHeader::showTimers()
|
||||
{
|
||||
int nextTimer = CTimerManager::getNextTimer();
|
||||
int nextTimer = CTimerManager::getNextTimer(); // timer ID and repeat flag info of next scheduled timer
|
||||
if(nextTimer) {
|
||||
int xPos = X_TIMER_ICON;
|
||||
_drawBitmap(xPos, Y_TIMER_ICON, LargeTimerIconInfo);
|
||||
if(nextTimer & 0x80)
|
||||
_drawBitmap(xPos-3, Y_TIMER_ICON, VerticalRepeatIconInfo);
|
||||
|
||||
CTransientFont AF(_display, &miniFontInfo); // temporarily use a mini font
|
||||
if((nextTimer & 0x0f) >= 10)
|
||||
_display.setCursor(xPos+4, Y_TIMER_ICON+8);
|
||||
else
|
||||
_display.setCursor(xPos+6, Y_TIMER_ICON+8);
|
||||
_display.print(nextTimer & 0x0f);
|
||||
_drawBitmap(xPos, Y_TIMER_ICON, TimerIconInfo);
|
||||
if(nextTimer & 0x80)
|
||||
_drawBitmap(xPos-3, Y_TIMER_ICON, verticalRepeatIconInfo);
|
||||
if(_hdrDetail) {
|
||||
sTimer timerInfo;
|
||||
char msg[8];
|
||||
int activeTimer = CTimerManager::getActiveTimer();
|
||||
if(activeTimer) {
|
||||
CTimerManager::getTimer((activeTimer - 1) & 0xf, timerInfo);
|
||||
sprintf(msg, "%02d:%02d", timerInfo.stop.hour, timerInfo.stop.min);
|
||||
_drawBitmap(xPos-5, Y_TIMER_ICON+12, miniStopIconInfo, WHITE, BLACK);
|
||||
}
|
||||
else {
|
||||
CTimerManager::getTimer((nextTimer - 1) & 0xf, timerInfo);
|
||||
sprintf(msg, "%02d:%02d", timerInfo.start.hour, timerInfo.start.min);
|
||||
_drawBitmap(xPos-5, Y_TIMER_ICON+12, miniStartIconInfo, WHITE, BLACK);
|
||||
}
|
||||
CTransientFont AF(_display, &miniFontInfo); // temporarily use a mini font
|
||||
_printMenuText(xPos-1, Y_TIMER_ICON+12, msg);
|
||||
}
|
||||
else {
|
||||
_display.fillRect(X_TIMER_ICON-5, Y_TIMER_ICON+12, 21, 5, BLACK); // erase annotation
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
_display.fillRect(X_TIMER_ICON-3, Y_TIMER_ICON, TimerIconInfo.width+3, TimerIconInfo.height, BLACK); // erase icon
|
||||
_display.fillRect(X_TIMER_ICON-5, Y_TIMER_ICON+12, 21, 5, BLACK); // erase annotation
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ class CScreenHeader : public CScreen {
|
|||
sScreenholdoff _UpAnnotation;
|
||||
sScreenholdoff _DnAnnotation;
|
||||
bool _colon;
|
||||
bool _hdrDetail;
|
||||
uint8_t _animateCount;
|
||||
uint8_t _batteryCount;
|
||||
uint8_t _batteryWarn;
|
||||
|
@ -53,6 +54,7 @@ protected:
|
|||
void showBatteryIcon(float voltage);
|
||||
int showTimers();
|
||||
virtual void showTime(); // x location depends upon how many timers are active
|
||||
void showHeaderDetail(bool state) { _hdrDetail = state; };
|
||||
public:
|
||||
CScreenHeader(C128x64_OLED& disp, CScreenManager& mgr);
|
||||
bool show(bool erase);
|
||||
|
|
|
@ -76,6 +76,8 @@ struct sBMPhdr {
|
|||
};
|
||||
#pragma pack (pop)
|
||||
|
||||
extern CScreenManager ScreenManager;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// splash creen created using image2cpp http://javl.github.io/image2cpp/
|
||||
// Settings:
|
||||
|
@ -248,7 +250,7 @@ void loadSplashScreen(uint8_t* image)
|
|||
}
|
||||
}
|
||||
|
||||
void storeSplashScreenFile()
|
||||
void checkSplashScreenUpdate()
|
||||
{
|
||||
if(SPIFFS.exists("/splash.bmp")) { // If a splash.bmp file was uploaded
|
||||
File file = SPIFFS.open("/splash.bmp", "rb"); // Open it
|
||||
|
@ -327,8 +329,10 @@ void storeSplashScreenFile()
|
|||
} while(0);
|
||||
|
||||
file.close();
|
||||
|
||||
SPIFFS.remove("/splash.bmp");
|
||||
|
||||
ScreenManager.showSplash();
|
||||
delay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,18 +382,7 @@ CScreenManager::begin(bool bNoClock)
|
|||
#endif
|
||||
|
||||
// replace adafruit splash screen
|
||||
_pDisplay->clearDisplay();
|
||||
uint8_t splash[1024];
|
||||
loadSplashScreen(splash);
|
||||
_pDisplay->drawBitmap(0, 0, splash, 128, 64, WHITE);
|
||||
// _pDisplay->drawBitmap(0, 0, DieselSplash, 128, 64, WHITE);
|
||||
_pDisplay->setCursor(90, 56);
|
||||
CTransientFont AF(*_pDisplay, &segoeUI_Italic_7ptFontInfo); // temporarily use a midi font
|
||||
_pDisplay->setTextColor(WHITE);
|
||||
_pDisplay->print(getVersionStr());
|
||||
|
||||
// Show initial display buffer contents on the screen --
|
||||
_pDisplay->display();
|
||||
showSplash();
|
||||
|
||||
delay(2000);
|
||||
|
||||
|
@ -767,3 +760,19 @@ CScreenManager::_dim(bool state)
|
|||
_pDisplay->dim(state);
|
||||
}
|
||||
|
||||
void
|
||||
CScreenManager::showSplash()
|
||||
{
|
||||
_pDisplay->clearDisplay();
|
||||
uint8_t splash[1024];
|
||||
loadSplashScreen(splash);
|
||||
_pDisplay->drawBitmap(0, 0, splash, 128, 64, WHITE);
|
||||
// _pDisplay->drawBitmap(0, 0, DieselSplash, 128, 64, WHITE);
|
||||
_pDisplay->setCursor(90, 56);
|
||||
CTransientFont AF(*_pDisplay, &segoeUI_Italic_7ptFontInfo); // temporarily use a midi font
|
||||
_pDisplay->setTextColor(WHITE);
|
||||
_pDisplay->print(getVersionStr());
|
||||
|
||||
// Show initial display buffer contents on the screen --
|
||||
_pDisplay->display();
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
void showOTAMessage(int percent, eOTAmodes updateType);
|
||||
void clearDisplay();
|
||||
void bumpTimeout();
|
||||
void showSplash();
|
||||
};
|
||||
|
||||
#endif // __SCREEN_MANAGER_H__
|
||||
|
|
|
@ -82,25 +82,43 @@ CVersionInfoScreen::show()
|
|||
// animation of update available via animate() if firmware update is available on web server
|
||||
_showTitle("Version Information");
|
||||
|
||||
_drawBitmap(13, 12, FirmwareIconInfo);
|
||||
_printMenuText(46, 15, getVersionStr());
|
||||
_printMenuText(46, 26, getVersionDate());
|
||||
|
||||
_drawBitmap(23, 34, HardwareIconInfo);
|
||||
_drawBitmap(8, 12, FirmwareIconInfo);
|
||||
_printMenuText(41, 15, getVersionStr());
|
||||
_printMenuText(41, 26, getVersionDate());
|
||||
int newVer = isUpdateAvailable();
|
||||
// if(newVer) {
|
||||
// char msg[32];
|
||||
// int major = (int)(newVer * 0.01);
|
||||
// int minor = newVer - major*100;
|
||||
// float prtMajor = major * 0.1;
|
||||
// sprintf(msg, "V%.1f.%d", prtMajor, minor);
|
||||
// _printMenuText(128, 15, msg, false, eRightJustify);
|
||||
// }
|
||||
_drawBitmap(18, 34, HardwareIconInfo);
|
||||
int PCB = getBoardRevision();
|
||||
sprintf(msg, "V%.1f", float(PCB)*0.1f);
|
||||
_printMenuText(46, 38, msg);
|
||||
_printMenuText(41, 38, msg);
|
||||
if(PCB == 20) {
|
||||
_printMenuText(108, 38, "Analog", false, eCentreJustify);
|
||||
_display.drawLine(88, 42, 127, 42, WHITE);
|
||||
}
|
||||
if(PCB == 22) {
|
||||
_printMenuText(114, 38, "GPIO", false, eCentreJustify);
|
||||
_display.drawLine(94, 42, 121, 42, WHITE);
|
||||
}
|
||||
|
||||
_printMenuText(_display.xCentre(), 53, " \021 \020 ", true, eCentreJustify);
|
||||
if(_rowSel == 1 && isUpdateAvailable()) {
|
||||
if(_rowSel == 1 && newVer) {
|
||||
// prompt 'Get Update' for new firmware available and first UP press from home
|
||||
_printMenuText(_display.xCentre(), 53, "Get Update", false, eCentreJustify);
|
||||
char msg[32];
|
||||
int major = (int)(newVer * 0.01);
|
||||
int minor = newVer - major*100;
|
||||
float prtMajor = major * 0.1;
|
||||
sprintf(msg, "Get V%.1f.%d update", prtMajor, minor);
|
||||
_printMenuText(_display.xCentre(), 53, " ", true, eCentreJustify);
|
||||
_printMenuText(_display.xCentre(), 53, msg, false, eCentreJustify);
|
||||
}
|
||||
else {
|
||||
_printMenuText(_display.xCentre(), 53, " \021 \020 ", true, eCentreJustify);
|
||||
_printMenuText(_display.xCentre(), 53, "Exit", false, eCentreJustify);
|
||||
}
|
||||
}
|
||||
|
@ -114,12 +132,12 @@ CVersionInfoScreen::show()
|
|||
}
|
||||
else if(_rowSel == 20) {
|
||||
// firmware update confirmation screen
|
||||
_printInverted(_display.xCentre(), 0, " Firmware update ", true, eCentreJustify);
|
||||
_showTitle("Firmware update");
|
||||
_printMenuText(_display.xCentre(), 35, "Press UP to", false, eCentreJustify);
|
||||
_printMenuText(_display.xCentre(), 43, "confirm download", false, eCentreJustify);
|
||||
}
|
||||
else {
|
||||
_printInverted(_display.xCentre(), 0, " Factory Default ", true, eCentreJustify);
|
||||
_showTitle("Factory Default");
|
||||
if(_rowSel == 10) {
|
||||
// factory default confirmation screen
|
||||
_printMenuText(_display.xCentre(), 35, "Press UP to", false, eCentreJustify);
|
||||
|
@ -149,12 +167,27 @@ CVersionInfoScreen::animate()
|
|||
if(_rowSel <= 1 && isUpdateAvailable()) {
|
||||
// show ascending up arrow if firmware update is available on web server
|
||||
_animateCount++;
|
||||
WRAPUPPERLIMIT(_animateCount, 5, 0);
|
||||
int ypos = 11 + 15 - 7 - _animateCount;
|
||||
WRAPUPPERLIMIT(_animateCount, 3, 0);
|
||||
/* int ypos = 11 + 16 - 7 - _animateCount;
|
||||
_display.fillRect(0, 11, 10, 21, BLACK);
|
||||
_display.drawBitmap(2, ypos, WifiOutIconInfo.pBitmap, WifiOutIconInfo.width, 7, WHITE); // upload arrow - from web to afterburner
|
||||
_display.fillRect(1, 11, 7, 2, WHITE); // top bar
|
||||
_drawBitmap(0, 11+16, WWWIconInfo); // www icon
|
||||
_display.fillRect(1, 12, 7, 2, WHITE); // top bar
|
||||
_drawBitmap(0, 11+17, WWWIconInfo); // www icon*/
|
||||
|
||||
int newVer = isUpdateAvailable();
|
||||
if((_animateCount & 0x02) && newVer) {
|
||||
char msg[32];
|
||||
int major = (int)(newVer * 0.01);
|
||||
int minor = newVer - major*100;
|
||||
float prtMajor = major * 0.1;
|
||||
sprintf(msg, "V%.1f.%d", prtMajor, minor);
|
||||
_printMenuText(128, 15, msg, false, eRightJustify);
|
||||
_drawBitmap(118, 24, UpdateIconInfo);
|
||||
}
|
||||
else {
|
||||
_display.fillRect(82, 15, 46, 7, BLACK);
|
||||
_display.fillRect(118, 24, 9, 10, BLACK);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -420,8 +420,6 @@ const uint8_t repeatIcon [] PROGMEM = {
|
|||
0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
0x00, 0x02, // #
|
||||
0x00, 0x02, // #
|
||||
0xf0, 0x04, // #### #
|
||||
|
@ -430,12 +428,27 @@ const uint8_t repeatIcon [] PROGMEM = {
|
|||
0x98, 0x30, // # # ##
|
||||
0x07, 0xc0 // #####
|
||||
};
|
||||
const BITMAP_INFO RepeatIconInfo(15, 15, repeatIcon);
|
||||
const BITMAP_INFO RepeatIconInfo(15, 13, repeatIcon);
|
||||
|
||||
// 'repeat', 5x11px
|
||||
const uint8_t verticalRepeatIcon [] PROGMEM = {
|
||||
0x78, // ####
|
||||
0x38, // ###
|
||||
0x38, // ###
|
||||
0x48, // # #
|
||||
0x80, // #
|
||||
0x80, // #
|
||||
0x80, // #
|
||||
0x80, // #
|
||||
0x80, // #
|
||||
0x40, // #
|
||||
0x40, // #
|
||||
0x20, // #
|
||||
};
|
||||
const BITMAP_INFO verticalRepeatIconInfo(5, 11, verticalRepeatIcon);
|
||||
|
||||
// 'timerID1', 15x15px
|
||||
const uint8_t timerID1Icon [] PROGMEM = {
|
||||
0x00, 0x00, //
|
||||
0x00, 0x00, //
|
||||
0x07, 0xc0, // #####
|
||||
0x09, 0x20, // # # #
|
||||
0x11, 0x10, // # # #
|
||||
|
@ -450,7 +463,7 @@ const uint8_t timerID1Icon [] PROGMEM = {
|
|||
0x00, 0x00, //
|
||||
0x00, 0x00 //
|
||||
};
|
||||
const BITMAP_INFO TimerId1IconInfo(15, 15, timerID1Icon);
|
||||
const BITMAP_INFO TimerId1IconInfo(15, 13, timerID1Icon);
|
||||
|
||||
// 'timerID2', 15x15px
|
||||
const uint8_t timerID2Icon [] PROGMEM = {
|
||||
|
@ -474,23 +487,19 @@ const BITMAP_INFO TimerId2IconInfo(15, 15, timerID2Icon);
|
|||
|
||||
// 'timer', 15x15px
|
||||
const uint8_t timerIcon [] PROGMEM = {
|
||||
0x00, 0x00, //
|
||||
0x00, 0x00, //
|
||||
0x07, 0xc0, // #####
|
||||
0x09, 0x20, // # # #
|
||||
0x11, 0x10, // # # #
|
||||
0x21, 0x08, // # # #
|
||||
0x21, 0x08, // # # #
|
||||
0x21, 0x08, // # #### #
|
||||
0x21, 0xE8, // # #### #
|
||||
0x20, 0x08, // # #
|
||||
0x20, 0x08, // # #
|
||||
0x10, 0x10, // # #
|
||||
0x08, 0x20, // # #
|
||||
0x07, 0xc0, // #####
|
||||
0x00, 0x00, //
|
||||
0x00, 0x00 //
|
||||
};
|
||||
const BITMAP_INFO TimerIconInfo(15, 15, timerIcon);
|
||||
const BITMAP_INFO TimerIconInfo(15, 11, timerIcon);
|
||||
|
||||
// 'large timer', 15x15px
|
||||
const uint8_t largeTimerIcon[] PROGMEM =
|
||||
|
@ -513,7 +522,7 @@ const uint8_t largeTimerIcon[] PROGMEM =
|
|||
};
|
||||
const BITMAP_INFO LargeTimerIconInfo(15, 15, largeTimerIcon);
|
||||
|
||||
const uint8_t PROGMEM verticalRepeatIcon [] =
|
||||
const uint8_t PROGMEM verticalLargeRepeatIcon [] =
|
||||
{
|
||||
0x78, // ####
|
||||
0x38, // ###
|
||||
|
@ -531,7 +540,7 @@ const uint8_t PROGMEM verticalRepeatIcon [] =
|
|||
0x20, // #
|
||||
0x20, // #
|
||||
};
|
||||
const BITMAP_INFO VerticalRepeatIconInfo(5, 15, verticalRepeatIcon);
|
||||
const BITMAP_INFO VerticalRepeatLargeIconInfo(5, 15, verticalLargeRepeatIcon);
|
||||
|
||||
const uint8_t PROGMEM GPIO1OFFIcon[] =
|
||||
{
|
||||
|
@ -687,6 +696,16 @@ const uint8_t PROGMEM startIcon[] =
|
|||
};
|
||||
const BITMAP_INFO StartIconInfo(5, 9, startIcon);
|
||||
|
||||
const uint8_t PROGMEM miniStartIcon[] =
|
||||
{
|
||||
0x80, // #
|
||||
0xC0, // ##
|
||||
0xE0, // ###
|
||||
0xC0, // ##
|
||||
0x80, // #
|
||||
};
|
||||
const BITMAP_INFO miniStartIconInfo(3, 5, miniStartIcon);
|
||||
|
||||
|
||||
const uint8_t PROGMEM stopIcon[] =
|
||||
{
|
||||
|
@ -701,6 +720,16 @@ const uint8_t PROGMEM stopIcon[] =
|
|||
};
|
||||
const BITMAP_INFO StopIconInfo(6, 8, stopIcon);
|
||||
|
||||
const uint8_t PROGMEM miniStopIcon[] =
|
||||
{
|
||||
0x00, //
|
||||
0xE0, // ###
|
||||
0xE0, // ###
|
||||
0xE0, // ###
|
||||
0x00, //
|
||||
};
|
||||
const BITMAP_INFO miniStopIconInfo(3, 5, miniStopIcon);
|
||||
|
||||
const uint8_t PROGMEM displayTimeoutIcon[] =
|
||||
{
|
||||
0xFF, 0xE1, 0xFF, // ########### #########
|
||||
|
|
|
@ -73,8 +73,9 @@ extern const BITMAP_INFO RepeatIconInfo;
|
|||
extern const BITMAP_INFO TimerId1IconInfo;
|
||||
extern const BITMAP_INFO TimerId2IconInfo;
|
||||
extern const BITMAP_INFO TimerIconInfo;
|
||||
extern const BITMAP_INFO verticalRepeatIconInfo;
|
||||
extern const BITMAP_INFO LargeTimerIconInfo;
|
||||
extern const BITMAP_INFO VerticalRepeatIconInfo;
|
||||
extern const BITMAP_INFO VerticalLargeRepeatIconInfo;
|
||||
|
||||
extern const BITMAP_INFO CrossLgIconInfo;
|
||||
extern const BITMAP_INFO CrossIconInfo
|
||||
|
@ -94,9 +95,11 @@ extern const BITMAP_INFO BulbOffIconInfo;
|
|||
|
||||
// Bitmap for start
|
||||
extern const BITMAP_INFO StartIconInfo;
|
||||
extern const BITMAP_INFO miniStartIconInfo;
|
||||
|
||||
// Bitmap sizes for stop
|
||||
extern const BITMAP_INFO StopIconInfo;
|
||||
extern const BITMAP_INFO miniStopIconInfo;
|
||||
|
||||
// Bitmap for displayTimeout
|
||||
extern const BITMAP_INFO DisplayTimeoutIconInfo;
|
||||
|
|
|
@ -165,6 +165,9 @@ const uint8_t miniFontBitmaps[] PROGMEM =
|
|||
0x88, // # #
|
||||
0x70, // ###
|
||||
|
||||
// @81 ':' (1 pixel wide)
|
||||
0x50, // # #
|
||||
|
||||
};
|
||||
|
||||
// Character descriptors for a 3x5 font
|
||||
|
@ -183,7 +186,7 @@ const FONT_CHAR_INFO miniFontDescriptors[] PROGMEM =
|
|||
{3, 5, 22}, // '7'
|
||||
{3, 5, 25}, // '8'
|
||||
{3, 5, 28}, // '9'
|
||||
{0, 0, 0}, // ':'
|
||||
{1, 5, 81}, // ':'
|
||||
{0, 0, 0}, // ';'
|
||||
{0, 0, 0}, // '<'
|
||||
{0, 0, 0}, // '='
|
||||
|
|
|
@ -71,6 +71,7 @@ DebugPort.println("Using millis() based psuedo \"Real Time Clock\"");
|
|||
update();
|
||||
|
||||
CTimerManager::createMap();
|
||||
CTimerManager::findNextTimer(_currentTime.hour(), _currentTime.minute(), _currentTime.dayOfTheWeek());
|
||||
}
|
||||
|
||||
const BTCDateTime&
|
||||
|
|
|
@ -34,22 +34,25 @@
|
|||
#include "../Utility/NVStorage.h"
|
||||
#include "../Utility/helpers.h"
|
||||
|
||||
uint8_t CTimerManager::weekMap[7][CTimerManager::_dayMinutes]; // b[7] = repeat flag, b[3..0] = timer ID
|
||||
// main array to hold information of which timer is active at any particular minute of the week
|
||||
// LSBs are used for the timerID + 1
|
||||
// MSB is set if the timer repeats
|
||||
uint8_t CTimerManager::_weekMap[7][CTimerManager::_dayMinutes]; // b[7] = repeat flag, b[3..0] = timer ID
|
||||
|
||||
int CTimerManager::activeTimer = 0;
|
||||
int CTimerManager::activeDow = 0;
|
||||
int CTimerManager::nextTimer = 0;
|
||||
int CTimerManager::nextStart = 0;
|
||||
bool CTimerManager::timerChanged = false;
|
||||
int CTimerManager::_activeTimer = 0;
|
||||
int CTimerManager::_activeDow = 0;
|
||||
int CTimerManager::_nextTimer = 0;
|
||||
int CTimerManager::_nextStart = 0;
|
||||
bool CTimerManager::_timerChanged = false;
|
||||
|
||||
#define SET_MAPS() { \
|
||||
if(pTimerMap) { \
|
||||
pTimerMap[dayMinute] |= activeday; \
|
||||
pTimerMap[dayMinute] |= activeday; \
|
||||
if(pTimerIDs) \
|
||||
pTimerIDs[dayMinute] |= timerBit; \
|
||||
} \
|
||||
else { \
|
||||
weekMap[dow][dayMinute] = recordTimer; \
|
||||
_weekMap[dow][dayMinute] = recordTimer; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -64,7 +67,7 @@ CTimerManager::createMap(int timerMask, uint16_t* pTimerMap, uint16_t* pTimerIDs
|
|||
}
|
||||
else {
|
||||
DebugPort.println("Erasing weekMap");
|
||||
memset(weekMap, 0, _dayMinutes*7*sizeof(uint8_t));
|
||||
memset(_weekMap, 0, _dayMinutes*7*sizeof(uint8_t));
|
||||
}
|
||||
|
||||
for(int timerID=0; timerID < 14; timerID++) {
|
||||
|
@ -202,12 +205,12 @@ CTimerManager::condenseMap(uint8_t timerMap[7][120])
|
|||
uint8_t condense = 0;
|
||||
for(int subInterval = 0; subInterval < 12; subInterval++, dayMinute++) {
|
||||
if(!condense)
|
||||
condense = weekMap[dow][dayMinute];
|
||||
condense = _weekMap[dow][dayMinute];
|
||||
}
|
||||
timerMap[dow][opIndex++] = condense;
|
||||
}
|
||||
}
|
||||
timerChanged = false;
|
||||
_timerChanged = false;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -220,26 +223,26 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
|
|||
|
||||
int retval = 0;
|
||||
int dayMinute = (hour * 60) + minute;
|
||||
int newID = weekMap[dow][dayMinute];
|
||||
if(activeTimer != newID) {
|
||||
int newID = _weekMap[dow][dayMinute];
|
||||
if(_activeTimer != newID) {
|
||||
|
||||
DebugPort.printf("Timer ID change detected: %d", activeTimer & 0x0f);
|
||||
if(activeTimer & 0x80) DebugPort.print("(repeating)");
|
||||
DebugPort.printf("Timer ID change detected: %d", _activeTimer & 0x0f);
|
||||
if(_activeTimer & 0x80) DebugPort.print("(repeating)");
|
||||
DebugPort.printf(" -> %d", newID & 0x0f);
|
||||
if(newID & 0x80) DebugPort.print("(repeating)");
|
||||
DebugPort.println("");
|
||||
|
||||
if(activeTimer) {
|
||||
if(_activeTimer) {
|
||||
// deal with expired timer
|
||||
DebugPort.println("Handling expired timer cleanup");
|
||||
|
||||
if(activeTimer & 0x80) {
|
||||
if(_activeTimer & 0x80) {
|
||||
DebugPort.println("Expired timer repeats, leaving definition alone");
|
||||
}
|
||||
else { // non repeating timer
|
||||
// delete one shot timer - note that this may require ticking off each day as they appear
|
||||
DebugPort.printf("Expired timer does not repeat - Cancelling %d\r\n", activeTimer);
|
||||
int ID = activeTimer & 0x0f;
|
||||
DebugPort.printf("Expired timer does not repeat - Cancelling %d\r\n", _activeTimer);
|
||||
int ID = _activeTimer & 0x0f;
|
||||
if(ID) {
|
||||
ID--;
|
||||
sTimer timer;
|
||||
|
@ -250,8 +253,8 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
|
|||
timer.enabled = 0; // ouright cancel anyday timer
|
||||
}
|
||||
else {
|
||||
DebugPort.printf("Cancelling specific day idx %d\r\n", activeDow);
|
||||
timer.enabled &= ~(0x01 << activeDow); // cancel specific day that started the timer
|
||||
DebugPort.printf("Cancelling specific day idx %d\r\n", _activeDow);
|
||||
timer.enabled &= ~(0x01 << _activeDow); // cancel specific day that started the timer
|
||||
}
|
||||
NVstore.setTimerInfo(ID, timer);
|
||||
NVstore.save();
|
||||
|
@ -263,7 +266,7 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
|
|||
if(newID) {
|
||||
DebugPort.println("Start of timer interval, starting heater");
|
||||
requestOn();
|
||||
activeDow = dow; // dow when timer interval start was detected
|
||||
_activeDow = dow; // dow when timer interval start was detected
|
||||
retval = 1;
|
||||
}
|
||||
else {
|
||||
|
@ -271,7 +274,7 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
|
|||
requestOff();
|
||||
retval = 2;
|
||||
}
|
||||
activeTimer = newID;
|
||||
_activeTimer = newID;
|
||||
}
|
||||
findNextTimer(hour, minute, dow);
|
||||
return retval;
|
||||
|
@ -284,10 +287,10 @@ CTimerManager::findNextTimer(int hour, int minute, int dow)
|
|||
|
||||
int limit = 24*60*7;
|
||||
while(limit--) {
|
||||
if(weekMap[dow][dayMinute] & 0x0f) {
|
||||
nextTimer = weekMap[dow][dayMinute];
|
||||
nextStart = dow*_dayMinutes + dayMinute;
|
||||
return nextTimer;
|
||||
if(_weekMap[dow][dayMinute] & 0x0f) {
|
||||
_nextTimer = _weekMap[dow][dayMinute];
|
||||
_nextStart = dow*_dayMinutes + dayMinute;
|
||||
return _nextTimer;
|
||||
}
|
||||
dayMinute++;
|
||||
if(dayMinute == _dayMinutes) {
|
||||
|
@ -296,16 +299,23 @@ CTimerManager::findNextTimer(int hour, int minute, int dow)
|
|||
WRAPUPPERLIMIT(dow, 6, 0);
|
||||
}
|
||||
}
|
||||
nextTimer = 0;
|
||||
_nextTimer = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
CTimerManager::getNextTimer()
|
||||
{
|
||||
return nextTimer;
|
||||
return _nextTimer;
|
||||
}
|
||||
|
||||
int
|
||||
CTimerManager::getActiveTimer()
|
||||
{
|
||||
return _activeTimer;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CTimerManager::getTimer(int idx, sTimer& timerInfo)
|
||||
{
|
||||
|
@ -320,7 +330,7 @@ CTimerManager::setTimer(sTimer& timerInfo)
|
|||
NVstore.save();
|
||||
createMap();
|
||||
manageTime(0,0,0);
|
||||
timerChanged = true;
|
||||
_timerChanged = true;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -341,7 +351,7 @@ CTimerManager::conflictTest(int ID)
|
|||
}
|
||||
createMap();
|
||||
manageTime(0,0,0);
|
||||
timerChanged = true;
|
||||
_timerChanged = true;
|
||||
return conflictID;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,17 +48,18 @@ public:
|
|||
static int manageTime(int hour, int minute, int dow);
|
||||
static int findNextTimer(int hour, int minute, int dow);
|
||||
static int getNextTimer();
|
||||
static int getActiveTimer();
|
||||
static void getTimer(int idx, sTimer& timerInfo);
|
||||
static int setTimer(sTimer& timerInfo);
|
||||
static bool hasTimerChanged() { return timerChanged; };
|
||||
static bool hasTimerChanged() { return _timerChanged; };
|
||||
private:
|
||||
static int activeTimer;
|
||||
static int activeDow;
|
||||
static int prevState;
|
||||
static int nextTimer;
|
||||
static int nextStart;
|
||||
static uint8_t weekMap[7][_dayMinutes]; // b[7] = repeat flag, b[3..0] = timer ID
|
||||
static bool timerChanged;
|
||||
static int _activeTimer;
|
||||
static int _activeDow;
|
||||
static int _prevState;
|
||||
static int _nextTimer;
|
||||
static int _nextStart;
|
||||
static uint8_t _weekMap[7][_dayMinutes]; // b[7] = repeat flag, b[3..0] = timer ID
|
||||
static bool _timerChanged;
|
||||
};
|
||||
|
||||
#endif //__TIMERMANAGER_H__
|
|
@ -72,7 +72,7 @@ extern bool setGPIOout(int channel, bool state);
|
|||
extern bool getGPIOout(int channel);
|
||||
extern bool toggleGPIOout(int channel);
|
||||
extern void feedWatchdog();
|
||||
extern bool isUpdateAvailable(bool test=true);
|
||||
extern int isUpdateAvailable(bool test=true);
|
||||
extern void checkFOTA();
|
||||
extern void setUploadSize(long val);
|
||||
extern void getGPIOinfo(sGPIO& info);
|
||||
|
|
|
@ -49,7 +49,7 @@ extern const char* updateIndex;
|
|||
extern const char* formatDoneContent;
|
||||
extern const char* rebootIndex;
|
||||
|
||||
extern void storeSplashScreenFile();
|
||||
extern void checkSplashScreenUpdate();
|
||||
|
||||
sBrowserUpload BrowserUpload;
|
||||
WebServer server(80);
|
||||
|
@ -695,7 +695,7 @@ void onUploadCompletion()
|
|||
// completion functionality
|
||||
if(BrowserUpload.isSPIFFSupload()) {
|
||||
if(BrowserUpload.isOK()) {
|
||||
storeSplashScreenFile();
|
||||
checkSplashScreenUpdate();
|
||||
DebugPort.println("WEB: SPIFFS OK");
|
||||
server.send(200, "text/plain", "OK - File uploaded to SPIFFS");
|
||||
// javascript reselects the /update page!
|
||||
|
@ -988,6 +988,7 @@ void onRename()
|
|||
if(oldname != "" && newname != "") {
|
||||
DebugPort.printf("Renaming %s to %s\r\n", oldname.c_str(), newname.c_str());
|
||||
SPIFFS.rename(oldname.c_str(), newname.c_str());
|
||||
checkSplashScreenUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,9 +31,13 @@
|
|||
#include "../Utility/MODBUS-CRC16.h"
|
||||
#include "esp_ota_ops.h"
|
||||
|
||||
#define TESTFOTA
|
||||
|
||||
|
||||
bool CheckFirmwareCRC(int filesize);
|
||||
bool CheckFirmwareCRC0(int filesize);
|
||||
void onSuccess();
|
||||
void onWebProgress(size_t progress, size_t total);
|
||||
|
||||
esp32FOTA FOTA("afterburner-fota-http", int(getVersion()*1000));
|
||||
unsigned long FOTAtime = millis() + 60000; // initial check in a minutes time
|
||||
|
@ -113,9 +117,14 @@ void DoOTA()
|
|||
// FOTAtime = millis() + 600000; // 10 minutes
|
||||
FOTAtime = millis() + 3600000; // 1 hour
|
||||
if ((WiFi.status() == WL_CONNECTED)) { // bug workaround in FOTA where execHTTPcheck does not return false in this condition
|
||||
FOTA.onProgress(onWebProgress); // important - keeps watchdog fed
|
||||
FOTA.onComplete(CheckFirmwareCRC0); // upload complete, but not yet verified
|
||||
FOTA.onSuccess(onSuccess);
|
||||
#ifdef TESTFOTA
|
||||
FOTA.checkURL = "http://www.mrjones.id.au/afterburner/fota/fotatest.json";
|
||||
#else
|
||||
FOTA.checkURL = "http://www.mrjones.id.au/afterburner/fota/fota.json";
|
||||
#endif
|
||||
DebugPort.println("Checking for new firmware...");
|
||||
if(FOTA.execHTTPcheck()) {
|
||||
DebugPort.println("New firmware available on web server!");
|
||||
|
@ -133,10 +142,16 @@ void DoOTA()
|
|||
}
|
||||
};
|
||||
|
||||
bool isUpdateAvailable(bool test)
|
||||
int isUpdateAvailable(bool test)
|
||||
{
|
||||
if(test) {
|
||||
return FOTAauth == 1;
|
||||
// return FOTAauth == 1;
|
||||
if(FOTAauth == 1) {
|
||||
return FOTA.getNewVersion();
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -228,3 +243,16 @@ void onSuccess()
|
|||
{
|
||||
forceBootInit();
|
||||
}
|
||||
|
||||
void onWebProgress(size_t progress, size_t total)
|
||||
{
|
||||
feedWatchdog();
|
||||
int percent = (progress / (total / 100));
|
||||
static int prevPC = 0;
|
||||
if(percent != prevPC) {
|
||||
prevPC = percent;
|
||||
DebugPort.printf("Progress: %u%%\r", percent);
|
||||
DebugPort.handle(); // keep telnet spy alive
|
||||
ShowOTAScreen(percent, eOTAWWW);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue