Added timer retry according to temperature being denied in the past

This commit is contained in:
Ray Jones 2020-05-09 19:17:21 +10:00
parent 7b36aa27f5
commit 24d8a4a7f1
16 changed files with 169 additions and 44 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Binary file not shown.

View File

@ -763,6 +763,7 @@ requestOn()
DebugPort.println("Start Request!"); DebugPort.println("Start Request!");
bool fuelOK = 2 != SmartError.checkfuelUsage(); bool fuelOK = 2 != SmartError.checkfuelUsage();
if(!fuelOK) { if(!fuelOK) {
DebugPort.println("Start denied - Low fuel");
return CDemandManager::eStartLowFuel; return CDemandManager::eStartLowFuel;
} }
bool LVCOK = 2 != SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue()); bool LVCOK = 2 != SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue());
@ -785,6 +786,7 @@ requestOn()
return startCode; return startCode;
} }
else { else {
DebugPort.println("Start denied - LVC");
return CDemandManager::eStartLVC; // LVC return CDemandManager::eStartLVC; // LVC
} }
} }
@ -795,6 +797,7 @@ void requestOff()
heaterOff(); heaterOff();
RTC_Store.setCyclicEngaged(false); // for cyclic mode RTC_Store.setCyclicEngaged(false); // for cyclic mode
RTC_Store.setFrostOn(false); // cancel active frost mode RTC_Store.setFrostOn(false); // cancel active frost mode
CTimerManager::cancelActiveTimer();
} }
void heaterOn() void heaterOn()
@ -1215,9 +1218,7 @@ void doStreaming()
doOTA(); doOTA();
#endif // USE_OTA #endif // USE_OTA
#if USE_WEBSERVER == 1 #if USE_WEBSERVER == 1
#ifdef OLD_WEBSOCKETHANDLER
bHaveWebClient = doWebServer(); bHaveWebClient = doWebServer();
#endif
#endif //USE_WEBSERVER #endif //USE_WEBSERVER
#if USE_MQTT == 1 #if USE_MQTT == 1
// most MQTT is managed via callbacks, but need some sundry housekeeping // most MQTT is managed via callbacks, but need some sundry housekeeping

View File

@ -414,8 +414,8 @@ CScreenManager::_loadScreens()
else if(NVstore.getUserSettings().menuMode == 2) { // no heater menu set else if(NVstore.getUserSettings().menuMode == 2) { // no heater menu set
menuloop.push_back(new CNoHeaterHomeMenuSelScreen(*_pDisplay, *this)); // No Heater Home menu settings screen menuloop.push_back(new CNoHeaterHomeMenuSelScreen(*_pDisplay, *this)); // No Heater Home menu settings screen
menuloop.push_back(new CMenuSelScreen(*_pDisplay, *this)); // Menu mode screen menuloop.push_back(new CMenuSelScreen(*_pDisplay, *this)); // Menu mode screen
if(getBoardRevision() != 0 && getBoardRevision() != BRD_V2_NOGPIO) // has GPIO support ? // if(getBoardRevision() != 0 && getBoardRevision() != BRD_V2_NOGPIO) // has GPIO support ?
menuloop.push_back(new CGPIOSetupScreen(*_pDisplay, *this)); // GPIO settings screen // menuloop.push_back(new CGPIOSetupScreen(*_pDisplay, *this)); // GPIO settings screen
} }
_Screens.push_back(menuloop); _Screens.push_back(menuloop);
@ -426,8 +426,8 @@ CScreenManager::_loadScreens()
menuloop.push_back(new CWebPageUpdateScreen(*_pDisplay, *this)); // Web Page update screen menuloop.push_back(new CWebPageUpdateScreen(*_pDisplay, *this)); // Web Page update screen
if(NVstore.getUserSettings().menuMode == 0) { if(NVstore.getUserSettings().menuMode == 0) {
menuloop.push_back(new CHourMeterScreen(*_pDisplay, *this)); // Hour Meter screen menuloop.push_back(new CHourMeterScreen(*_pDisplay, *this)); // Hour Meter screen
menuloop.push_back(new CWiFiScreen(*_pDisplay, *this));
} }
menuloop.push_back(new CWiFiScreen(*_pDisplay, *this));
menuloop.push_back(new CWiFiSTAScreen(*_pDisplay, *this)); menuloop.push_back(new CWiFiSTAScreen(*_pDisplay, *this));
menuloop.push_back(new CMQTTScreen(*_pDisplay, *this)); menuloop.push_back(new CMQTTScreen(*_pDisplay, *this));
menuloop.push_back(new CBTScreen(*_pDisplay, *this)); menuloop.push_back(new CBTScreen(*_pDisplay, *this));

View File

@ -199,8 +199,10 @@ CVersionInfoScreen::keyHandler(uint8_t event)
// UP press // UP press
if(event & key_Up) { if(event & key_Up) {
_rowSel++; if(NVstore.getUserSettings().menuMode != 2) {
UPPERLIMIT(_rowSel, 3); _rowSel++;
UPPERLIMIT(_rowSel, 3);
}
} }
// DOWN press // DOWN press
if(event & key_Down) { if(event & key_Down) {

View File

@ -35,6 +35,7 @@
#include "../Utility/helpers.h" #include "../Utility/helpers.h"
#include "../RTC/RTCStore.h" #include "../RTC/RTCStore.h"
#include "../Utility/DemandManager.h" #include "../Utility/DemandManager.h"
#include "../Protocol/Protocol.h"
// main array to hold information of which timer is active at any particular minute of the week // main array to hold information of which timer is active at any particular minute of the week
// LSBs are used for the timerID + 1 // LSBs are used for the timerID + 1
@ -42,6 +43,7 @@
uint8_t CTimerManager::_weekMap[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::_activeTimer = 0;
int CTimerManager::_cancelledTimer = 0;
int CTimerManager::_activeDow = 0; int CTimerManager::_activeDow = 0;
int CTimerManager::_nextTimer = 0; int CTimerManager::_nextTimer = 0;
int CTimerManager::_nextStart = 0; int CTimerManager::_nextStart = 0;
@ -58,6 +60,8 @@ bool CTimerManager::_timerChanged = false;
} \ } \
} }
#define START_ON_TEMPERATURE_DROP
// create a bitmap that describes the pattern of on/off times // create a bitmap that describes the pattern of on/off times
void void
CTimerManager::createMap(int timerMask, uint16_t* pTimerMap, uint16_t* pTimerIDs) CTimerManager::createMap(int timerMask, uint16_t* pTimerMap, uint16_t* pTimerIDs)
@ -266,15 +270,17 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
} }
if(newID) { if(newID) {
sTimer timer; if(_cancelledTimer != newID) {
// get timer settings sTimer timer;
int ID = (newID & 0xf) - 1; // get timer settings
NVstore.getTimerInfo(ID, timer); int ID = (newID & 0xf) - 1;
CDemandManager::setFromTimer(timer.temperature); NVstore.getTimerInfo(ID, timer);
DebugPort.printf("Start of timer interval, starting heater @ %dC\r\n", timer.temperature); CDemandManager::setFromTimer(timer.temperature);
requestOn(); DebugPort.printf("Start of timer interval, starting heater @ %dC\r\n", timer.temperature);
_activeDow = dow; // dow when timer interval start was detected requestOn();
retval = 1; _activeDow = dow; // dow when timer interval start was detected
retval = 1;
}
} }
else { else {
// if(!RTC_Store.getFrostOn() && !RTC_Store.getCyclicEngaged()) // if(!RTC_Store.getFrostOn() && !RTC_Store.getCyclicEngaged())
@ -283,13 +289,31 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
retval = 2; retval = 2;
CDemandManager::reload(); CDemandManager::reload();
DebugPort.printf("End of timer interval, stopping heater @ %dC\r\n", CDemandManager::getDegC()); DebugPort.printf("End of timer interval, stopping heater @ %dC\r\n", CDemandManager::getDegC());
_cancelledTimer = 0;
} }
_activeTimer = newID; _activeTimer = newID;
} }
#ifdef START_ON_TEMPERATURE_DROP
if((_activeTimer != 0) &&
(_activeTimer != _cancelledTimer) &&
(getHeaterInfo().getRunStateEx() == 0)) {
// heater is off, but timer is active and not cancelled
DebugPort.println("Timer re-attempting start");
requestOn();
}
#endif
findNextTimer(hour, minute, dow); findNextTimer(hour, minute, dow);
return retval; return retval;
} }
void
CTimerManager::cancelActiveTimer()
{
if(_activeTimer)
DebugPort.printf("User off caused timer #%d cancellation\r\n", _activeTimer & 0xf);
_cancelledTimer = _activeTimer;
}
int int
CTimerManager::findNextTimer(int hour, int minute, int dow) CTimerManager::findNextTimer(int hour, int minute, int dow)
{ {

View File

@ -52,8 +52,10 @@ public:
static void getTimer(int idx, sTimer& timerInfo); static void getTimer(int idx, sTimer& timerInfo);
static int setTimer(sTimer& timerInfo); static int setTimer(sTimer& timerInfo);
static bool hasTimerChanged() { return _timerChanged; }; static bool hasTimerChanged() { return _timerChanged; };
static void cancelActiveTimer();
private: private:
static int _activeTimer; static int _activeTimer;
static int _cancelledTimer;
static int _activeDow; static int _activeDow;
static int _prevState; static int _prevState;
static int _nextTimer; static int _nextTimer;

View File

@ -133,6 +133,7 @@ CDemandManager::checkStart()
// alows honour cyclic stop threshold - immediate suspend transition // alows honour cyclic stop threshold - immediate suspend transition
if(deltaT > stopDeltaT) { if(deltaT > stopDeltaT) {
DebugPort.println("Immediate switch to suspend mode, too warm");
return eStartSuspend; return eStartSuspend;
} }
} }
@ -142,11 +143,13 @@ CDemandManager::checkStart()
// temperature exceeded the allowed margin // temperature exceeded the allowed margin
// only deny start if actually using inbuilt thermostat mode // only deny start if actually using inbuilt thermostat mode
if(isThermostat()) { if(isThermostat()) {
DebugPort.println("Start denied, too warm");
return eStartTooWarm; // too warm - deny start return eStartTooWarm; // too warm - deny start
} }
} }
} }
DebugPort.println("Start allowed");
return eStartOK; // allow start return eStartOK; // allow start
} }

View File

@ -600,8 +600,8 @@ sCredentials::load()
validatedLoad("APpassword", APpassword, 31, "thereisnospoon"); validatedLoad("APpassword", APpassword, 31, "thereisnospoon");
validatedLoad("webUpdateUser", webUpdateUsername, 31, "Afterburner"); validatedLoad("webUpdateUser", webUpdateUsername, 31, "Afterburner");
validatedLoad("webUpdatePass", webUpdatePassword, 31, "BurnBabyBurn"); validatedLoad("webUpdatePass", webUpdatePassword, 31, "BurnBabyBurn");
validatedLoad("webUser", webUsername, 31, "Afterburner"); validatedLoad("webUser", webUsername, 31, "");
validatedLoad("webPass", webPassword, 31, "WebAccess"); validatedLoad("webPass", webPassword, 31, "");
preferences.end(); preferences.end();
} }

View File

@ -242,8 +242,8 @@ struct sCredentials : public CESP32_NVStorage {
strcpy(APpassword, "thereisnospoon"); strcpy(APpassword, "thereisnospoon");
strcpy(webUpdateUsername, "Afterburner"); strcpy(webUpdateUsername, "Afterburner");
strcpy(webUpdatePassword, "BurnBabyBurn"); strcpy(webUpdatePassword, "BurnBabyBurn");
strcpy(webUsername, "Afterburner"); strcpy(webUsername, "");
strcpy(webPassword, "WebAccess"); strcpy(webPassword, "");
}; };
void load(); void load();
void save(); void save();

View File

@ -84,9 +84,7 @@ HTTPSServer * secureServer;
#endif #endif
HTTPServer * insecureServer; HTTPServer * insecureServer;
HTTPServer * WSserver; HTTPServer * WSserver;
#if USE_SSL_LOOP_TASK == 1
void SSLloopTask(void *); void SSLloopTask(void *);
#endif
sBrowserUpload BrowserUpload; sBrowserUpload BrowserUpload;
#ifdef OLD_SERVER #ifdef OLD_SERVER
@ -100,6 +98,7 @@ bool bTxWebData = false;
bool bUpdateAccessed = false; // flag used to ensure browser update always starts via GET /update. direct accesses to POST /update will FAIL bool bUpdateAccessed = false; // flag used to ensure browser update always starts via GET /update. direct accesses to POST /update will FAIL
bool bFormatAccessed = false; bool bFormatAccessed = false;
bool bFormatPerformed = false; bool bFormatPerformed = false;
bool bStopWebServer = false;
long _SuppliedFileSize = 0; long _SuppliedFileSize = 0;
bool checkFile(File &file); bool checkFile(File &file);
@ -474,6 +473,8 @@ void initWebServer(void) {
// setup task to handle webserver // setup task to handle webserver
webSocketQueue = xQueueCreate(50, sizeof(char*) ); webSocketQueue = xQueueCreate(50, sizeof(char*) );
bStopWebServer = false;
xTaskCreate(SSLloopTask, xTaskCreate(SSLloopTask,
"Web server task", "Web server task",
8192, 8192,
@ -486,7 +487,8 @@ void initWebServer(void) {
} }
void SSLloopTask(void *) { void SSLloopTask(void *) {
for(;;) {
while(!bStopWebServer) {
WSserver->loop(); WSserver->loop();
insecureServer->loop(); insecureServer->loop();
#if USE_HTTPS == 1 #if USE_HTTPS == 1
@ -495,23 +497,32 @@ void SSLloopTask(void *) {
processWebsocketQueue(); processWebsocketQueue();
vTaskDelay(1); vTaskDelay(1);
} }
WSserver->stop();
insecureServer->stop();
#if USE_HTTPS == 1
secureServer->stop();
#endif
vTaskDelete(NULL);
bStopWebServer = false;
} }
// called by main sketch loop() // called by main sketch loop()
bool doWebServer(void) bool doWebServer(void)
{ {
#if USE_SSL_LOOP_TASK != 1
WSserver->loop();
insecureServer->loop();
#if USE_HTTPS == 1
secureServer->loop();
#endif
#endif
GetWebContent.manage(); GetWebContent.manage();
return true; return true;
} }
void stopWebServer()
{
DebugPort.println("Requesting web server stop");
bStopWebServer = true;
delay(100);
}
String getContentType(String filename) { // convert the file extension to the MIME type String getContentType(String filename) { // convert the file extension to the MIME type
if (filename.endsWith(".html")) return "text/html"; if (filename.endsWith(".html")) return "text/html";
else if (filename.endsWith(".css")) return "text/css"; else if (filename.endsWith(".css")) return "text/css";
@ -660,9 +671,6 @@ bool handleFileRead(String path, HTTPResponse *res) { // send the right file to
if(wr > 0) { if(wr > 0) {
done += wr; done += wr;
if(done > progressdot) { if(done > progressdot) {
#if USE_SSL_LOOP_TASK != 1
feedWatchdog();
#endif
DebugPort.print("."); DebugPort.print(".");
progressdot += 1024; progressdot += 1024;
} }
@ -1017,14 +1025,45 @@ function onformatClick() {
<div id='loaded_n_total' hidden></div> <div id='loaded_n_total' hidden></div>
)====="; )=====";
const char* wmConfigIndex = R"=====(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="-1">
<meta http-equiv="CACHE-CONTROL" content="NO-CACHE">
<script>
function init() {
setTimeout(function(){location.assign("/");},15000);
}
</script>
<title>Launching Afterburner Wifi Manager</title>
</head>
<body onload='javascript:init()'>
<h1>Launching Afterburner Wifi Manager</h1>
<p>
<h2>This page will automatically reload in 15 seconds, please wait.</h2>
<i>If auto reload fails, try manually refreshing the web page</i>
<h1>You may need to reconnect to the Afterburner's AP following the reboot</h1>
</body>
</html>
)=====";
void onWMConfig(HTTPRequest * req, httpsserver::HTTPResponse * res) void onWMConfig(HTTPRequest * req, httpsserver::HTTPResponse * res)
{ {
DebugPort.println("WEB: GET /wmconfig"); DebugPort.println("WEB: GET /wmconfig");
res->print("Start Config Portal - Retaining credential"); res->print(wmConfigIndex);
DebugPort.println("Starting web portal for wifi config"); DebugPort.println("Starting web portal for wifi config");
delay(500); wmReboot newMode(true);
wifiEnterConfigPortal(true, false, 3000); newMode.startPortal = true;
newMode.eraseCreds = false;
newMode.delay = 500;
scheduleWMreboot(newMode);
// delay(500);
// wifiEnterConfigPortal(true, false, 10000);
} }
@ -1033,8 +1072,13 @@ void onResetWifi(HTTPRequest * req, httpsserver::HTTPResponse * res)
DebugPort.println("WEB: GET /resetwifi"); DebugPort.println("WEB: GET /resetwifi");
res->print("Start Config Portal - Resetting Wifi credentials!"); res->print("Start Config Portal - Resetting Wifi credentials!");
DebugPort.println("diconnecting client and wifi, then rebooting"); DebugPort.println("diconnecting client and wifi, then rebooting");
delay(500); wmReboot newMode(true);
wifiEnterConfigPortal(true, true, 3000); newMode.startPortal = true;
newMode.eraseCreds = true;
newMode.delay = 500;
scheduleWMreboot(newMode);
// delay(500);
// wifiEnterConfigPortal(true, true, 3000);
} }
@ -1417,9 +1461,6 @@ void onUploadProgression(HTTPRequest * req, httpsserver::HTTPResponse * res)
} }
while (!parser->endOfField()) { while (!parser->endOfField()) {
#if USE_SSL_LOOP_TASK != 1
feedWatchdog(); // we get stuck here for a while, don't let the watchdog bite!
#endif
upload.currentSize = parser->read(upload.buf, HTTP_UPLOAD_BUFLEN); upload.currentSize = parser->read(upload.buf, HTTP_UPLOAD_BUFLEN);
sts = BrowserUpload.fragment(upload, res); sts = BrowserUpload.fragment(upload, res);
if(sts < 0) { if(sts < 0) {

View File

@ -27,6 +27,7 @@
void initWebServer(); void initWebServer();
bool doWebServer(); bool doWebServer();
void stopWebServer();
bool sendWebSocketString(const char* Str); bool sendWebSocketString(const char* Str);
bool isWebSocketClientChange(); bool isWebSocketClientChange();

View File

@ -22,6 +22,7 @@
// Should be working - Jimmy C // Should be working - Jimmy C
#include "BTCWifi.h" #include "BTCWifi.h"
#include "BTCWebServer.h"
#include "../Utility/DebugPort.h" #include "../Utility/DebugPort.h"
#include <DNSServer.h> #include <DNSServer.h>
#include "../OLED/ScreenManager.h" #include "../OLED/ScreenManager.h"
@ -46,6 +47,8 @@ char MACstr[2][20]; // MACstr[0] STA, MACstr[1] = AP
int wifiButtonState = 0; int wifiButtonState = 0;
unsigned long WifiReconnectHoldoff = 0; unsigned long WifiReconnectHoldoff = 0;
wmReboot pendingWMreboot;
extern CScreenManager ScreenManager; extern CScreenManager ScreenManager;
@ -164,6 +167,8 @@ bool initWifi()
// call from main sketch loop() // call from main sketch loop()
void doWiFiManager() void doWiFiManager()
{ {
manageWMreboot();
if(NVstore.getUserSettings().wifiMode) { if(NVstore.getUserSettings().wifiMode) {
wm.process(); wm.process();
@ -233,7 +238,8 @@ void wifiDisable(long rebootDelay)
void wifiEnterConfigPortal(bool state, bool erase, long rebootDelay, bool STAonly) void wifiEnterConfigPortal(bool state, bool erase, long rebootDelay, bool STAonly)
{ {
wm.disconnect(); stopWebServer();
wm.disconnect();
sUserSettings settings = NVstore.getUserSettings(); sUserSettings settings = NVstore.getUserSettings();
settings.wifiMode = STAonly ? 0x02 : 0x01; settings.wifiMode = STAonly ? 0x02 : 0x01;
@ -428,3 +434,22 @@ int isWifiButton()
{ {
return wifiButtonState; return wifiButtonState;
} }
void scheduleWMreboot(wmReboot& newMode)
{
pendingWMreboot = newMode;
}
void manageWMreboot()
{
if(pendingWMreboot.delay) {
long tDelta = millis() - pendingWMreboot.started;
if(tDelta > pendingWMreboot.delay) {
wifiEnterConfigPortal(pendingWMreboot.startPortal,
pendingWMreboot.eraseCreds,
3000);
pendingWMreboot.delay = 0;
}
}
}

View File

@ -24,6 +24,27 @@
#include <WiFi.h> #include <WiFi.h>
struct wmReboot {
bool startPortal;
bool eraseCreds;
unsigned long delay;
unsigned long started;
wmReboot(bool timenow = false) {
startPortal = false;
eraseCreds = false;
delay = 0;
started = timenow ? millis() : 0;
};
wmReboot& operator=(wmReboot& rhs) {
startPortal = rhs.startPortal;
eraseCreds = rhs.eraseCreds;
delay = rhs.delay;
started = rhs.started;
return *this;
};
};
void doWiFiManager(); void doWiFiManager();
bool initWifi(); bool initWifi();
const char* getWifiAPAddrStr(); const char* getWifiAPAddrStr();
@ -46,4 +67,7 @@ void wifiDisable(long rebootDelay = 7000);
void wifiFactoryDefault(); void wifiFactoryDefault();
int isWifiButton(); int isWifiButton();
void scheduleWMreboot(wmReboot& newMode);
void manageWMreboot();
#endif // __BTCWIFI_H__ #endif // __BTCWIFI_H__

View File

@ -64,7 +64,9 @@ void WebPageRequestCB(void* pClass, asyncHTTPrequest* request, int readyState)
CWebContentDL::CWebContentDL() CWebContentDL::CWebContentDL()
{ {
#ifdef DEBUG_WEBDL
_request.setDebug(true); _request.setDebug(true);
#endif
_request.onReadyStateChange(WebPageRequestCB, this); _request.onReadyStateChange(WebPageRequestCB, this);
_request.onData(WebPageDataCB, this); _request.onData(WebPageDataCB, this);
_queue = NULL; _queue = NULL;
@ -108,7 +110,7 @@ void CWebContentDL::get(const char* filename)
} }
// routine called regualrly by the "loop" task - ie not IRQL // routine called regualrly by the "loop" task - ie not IRQL
// it is no safe to write to SPIFFS in the AsyncTCP callbacks! // it is not safe to write to SPIFFS in the AsyncTCP callbacks!
void void
CWebContentDL::process() CWebContentDL::process()
{ {