BIG FIXES: External thermostat start denied if internal thermostat too high

Pump priming from web page only worked once - was because prime command was never released from heater.
This commit is contained in:
Ray Jones 2020-05-06 10:41:26 +10:00
parent 3129a88cb9
commit 97f3433158
9 changed files with 69 additions and 42 deletions

View file

@ -202,7 +202,7 @@ CSecuritySetup SecurityMenu;
TaskHandle_t handleWatchdogTask; TaskHandle_t handleWatchdogTask;
TaskHandle_t handleBlueWireTask; TaskHandle_t handleBlueWireTask;
extern TaskHandle_t handleSSLTask; extern TaskHandle_t handleWebServerTask;
// these variables will persist over a soft reboot. // these variables will persist over a soft reboot.
__NOINIT_ATTR float persistentRunTime; __NOINIT_ATTR float persistentRunTime;
@ -647,7 +647,7 @@ bool checkTemperatureSensors()
DebugPort.printf(" Arduino: %d\r\n", uxTaskGetStackHighWaterMark(NULL)); DebugPort.printf(" Arduino: %d\r\n", uxTaskGetStackHighWaterMark(NULL));
DebugPort.printf(" BlueWire: %d\r\n", uxTaskGetStackHighWaterMark(handleBlueWireTask)); DebugPort.printf(" BlueWire: %d\r\n", uxTaskGetStackHighWaterMark(handleBlueWireTask));
DebugPort.printf(" Watchdog: %d\r\n", uxTaskGetStackHighWaterMark(handleWatchdogTask)); DebugPort.printf(" Watchdog: %d\r\n", uxTaskGetStackHighWaterMark(handleWatchdogTask));
DebugPort.printf(" SSL loop: %d\r\n", uxTaskGetStackHighWaterMark(handleSSLTask)); DebugPort.printf(" SSL loop: %d\r\n", uxTaskGetStackHighWaterMark(handleWebServerTask));
} }
TempSensor.readSensors(); TempSensor.readSensors();

View file

@ -53,6 +53,7 @@ CProtocol HeaterFrame2; // data packet received from heater in resp
// CSmartError SmartError; // CSmartError SmartError;
CProtocolPackage reportHeaterData; CProtocolPackage reportHeaterData;
CProtocolPackage primaryHeaterData; CProtocolPackage primaryHeaterData;
char dbgMsg[BLUEWIRE_MSGQUEUESIZE];
static bool bHasOEMController = false; static bool bHasOEMController = false;
static bool bHasOEMLCDController = false; static bool bHasOEMLCDController = false;
@ -142,9 +143,8 @@ void BlueWireTask(void*) {
if(RxTimeElapsed >= moderator) { if(RxTimeElapsed >= moderator) {
moderator += 10; moderator += 10;
if(bReportRecyleEvents) { if(bReportRecyleEvents) {
char msg[32]; sprintf(dbgMsg, "%ldms - ", RxTimeElapsed);
sprintf(msg, "%ldms - ", RxTimeElapsed); pushDebugMsg(dbgMsg);
pushDebugMsg(msg);
} }
if(CommState.is(CommStates::OEMCtrlRx)) { if(CommState.is(CommStates::OEMCtrlRx)) {
bHasOEMController = false; bHasOEMController = false;
@ -208,9 +208,8 @@ void BlueWireTask(void*) {
if(BlueWireRxData.available() && (RxTimeElapsed > (RX_DATA_TIMOUT+10))) { if(BlueWireRxData.available() && (RxTimeElapsed > (RX_DATA_TIMOUT+10))) {
if(bReportOEMresync) { if(bReportOEMresync) {
char msg[64]; sprintf(dbgMsg, "Re-sync'd with OEM Controller. %ldms Idle time.\r\n", RxTimeElapsed);
sprintf(msg, "Re-sync'd with OEM Controller. %ldms Idle time.\r\n", RxTimeElapsed); pushDebugMsg(dbgMsg);
pushDebugMsg(msg);
} }
bHasHtrData = false; bHasHtrData = false;
@ -395,12 +394,11 @@ bool validateFrame(const CProtocol& frame, const char* name)
{ {
if(!frame.verifyCRC(pushDebugMsg)) { if(!frame.verifyCRC(pushDebugMsg)) {
// Bad CRC - restart blue wire Serial port // Bad CRC - restart blue wire Serial port
char msg[128]; sprintf(dbgMsg, "\007Bad CRC detected for %s frame - restarting blue wire's serial port\r\n", name);
sprintf(msg, "\007Bad CRC detected for %s frame - restarting blue wire's serial port\r\n", name); pushDebugMsg(dbgMsg);
pushDebugMsg(msg); dbgMsg[0] = 0; // empty string
msg[0] = 0; // empty string DebugReportFrame("BAD CRC:", frame, "\r\n", dbgMsg);
DebugReportFrame("BAD CRC:", frame, "\r\n", msg); pushDebugMsg(dbgMsg);
pushDebugMsg(msg);
#ifdef REBOOT_BLUEWIRE #ifdef REBOOT_BLUEWIRE
initBlueWireSerial(); initBlueWireSerial();
#endif #endif
@ -415,7 +413,7 @@ void DebugReportFrame(const char* hdr, const CProtocol& Frame, const char* ftr,
{ {
strcat(msg, hdr); // header strcat(msg, hdr); // header
for(int i=0; i<24; i++) { for(int i=0; i<24; i++) {
char str[16]; char str[8];
sprintf(str, " %02X", Frame.Data[i]); // build 2 dig hex values sprintf(str, " %02X", Frame.Data[i]); // build 2 dig hex values
strcat(msg, str); // and print strcat(msg, str); // and print
} }
@ -478,7 +476,7 @@ const char* getBlueWireStatStr()
void reqPumpPrime(bool on) void reqPumpPrime(bool on)
{ {
DefaultBTCParams.setPump_Prime(on); TxManage.reqPrime(on);
} }

View file

@ -431,20 +431,21 @@ CProtocolPackage::setRefTime()
_timeStamp.setRefTime(); _timeStamp.setRefTime();
}*/ }*/
char dbgFrameMsg[192];
void void
CProtocolPackage::reportFrames(bool isOEM, std::function<void(const char*)> pushMsg) CProtocolPackage::reportFrames(bool isOEM, std::function<void(const char*)> pushMsg)
{ {
char msg[192]; dbgFrameMsg[0] = 0;
msg[0] = 0; _timeStamp.report(dbgFrameMsg); // absolute time
_timeStamp.report(msg); // absolute time
if(isOEM) { if(isOEM) {
DebugReportFrame("OEM:", Controller, TERMINATE_OEM_LINE ? "\r\n" : " ", msg); DebugReportFrame("OEM:", Controller, TERMINATE_OEM_LINE ? "\r\n" : " ", dbgFrameMsg);
} }
else { else {
DebugReportFrame("BTC:", Controller, TERMINATE_BTC_LINE ? "\r\n" : " ", msg); DebugReportFrame("BTC:", Controller, TERMINATE_BTC_LINE ? "\r\n" : " ", dbgFrameMsg);
} }
DebugReportFrame("HTR:", Heater, "\r\n", msg); DebugReportFrame("HTR:", Heater, "\r\n", dbgFrameMsg);
pushMsg(msg); pushMsg(dbgFrameMsg);
} }
int int

View file

@ -36,6 +36,7 @@ void
CSmartError::reset() CSmartError::reset()
{ {
_prevRunState = 0; _prevRunState = 0;
_prevPumpHz = 0;
_Error = 0; _Error = 0;
_bInhibit = false; _bInhibit = false;
} }
@ -61,14 +62,15 @@ CSmartError::monitor(const CProtocol& heaterFrame)
{ {
if(heaterFrame.verifyCRC(NULL)) { // check but don't report dodgy frames to debug if(heaterFrame.verifyCRC(NULL)) { // check but don't report dodgy frames to debug
// only accept valid heater frames! // only accept valid heater frames!
monitor(heaterFrame.getRunState()); _monitor(heaterFrame.getRunState());
_monitorPriming(heaterFrame.getRunState(), heaterFrame.getPump_Actual());
} }
} }
// test the new run state value, comparing to previous // test the new run state value, comparing to previous
// detect abnormal transitions // detect abnormal transitions
void void
CSmartError::monitor(uint8_t newRunState) CSmartError::_monitor(uint8_t newRunState)
{ {
// check if moving away from heater Idle state (S0) // check if moving away from heater Idle state (S0)
// especially useful if an OEM controller exists // especially useful if an OEM controller exists
@ -209,3 +211,15 @@ CSmartError::checkfuelUsage(bool throwfault)
} }
return retval; return retval;
} }
void
CSmartError::_monitorPriming(uint8_t runState, uint8_t pumpHz)
{
if(runState == 0 && pumpHz == 0 && _prevPumpHz != 0) {
TxManage.reqPrime(false); // cancel pump priming request upon heater auto stopping priming
}
if(runState != 0) {
TxManage.reqPrime(false); // ALWAYS cancel pump priming request upon heater running
}
_prevPumpHz = pumpHz;
}

View file

@ -23,14 +23,16 @@
class CSmartError { class CSmartError {
uint8_t _prevRunState; uint8_t _prevRunState;
uint8_t _prevPumpHz;
uint8_t _Error; uint8_t _Error;
bool _bInhibit; bool _bInhibit;
void _monitorPriming(uint8_t runState, uint8_t pumpHz);
void _monitor(uint8_t runstate);
public: public:
CSmartError(); CSmartError();
void reset(); void reset();
void inhibit(bool reseterror=false); void inhibit(bool reseterror=false);
void monitor(const CProtocol& heaterFrame); void monitor(const CProtocol& heaterFrame);
void monitor(uint8_t runstate);
int checkVolts(float volts, float plugI, bool throwfault=true); // 0 = OK, 1 = within 0.5V of LVC, 2 = under LVC int checkVolts(float volts, float plugI, bool throwfault=true); // 0 = OK, 1 = within 0.5V of LVC, 2 = under LVC
int checkfuelUsage(bool throwfault=true); int checkfuelUsage(bool throwfault=true);
uint8_t getError(); uint8_t getError();

View file

@ -70,6 +70,7 @@ CTxManage::CTxManage(int TxGatePin, HardwareSerial& serial) :
_rawCommand = 0; _rawCommand = 0;
m_HWTimer = NULL; m_HWTimer = NULL;
_callback = NULL; _callback = NULL;
_prime = false;
} }
// static function used for the tx gate termination // static function used for the tx gate termination
@ -178,6 +179,8 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
m_TxFrame.setAltitude(3500); // default height - yes it is weird, but that's what the simple controllers send! m_TxFrame.setAltitude(3500); // default height - yes it is weird, but that's what the simple controllers send!
} }
m_TxFrame.setPump_Prime(_prime);
float tActual = getTemperatureSensor(); float tActual = getTemperatureSensor();
int8_t s8Temp = (int8_t)(tActual + 0.5); int8_t s8Temp = (int8_t)(tActual + 0.5);
m_TxFrame.setTemperature_Actual(s8Temp); // use current temp, for now m_TxFrame.setTemperature_Actual(s8Temp); // use current temp, for now
@ -338,3 +341,8 @@ CTxManage::CheckTx(unsigned long timenow)
return m_nStartTime == 0; // returns true when done return m_nStartTime == 0; // returns true when done
} }
void
CTxManage::reqPrime(bool on)
{
_prime = on;
}

View file

@ -28,6 +28,7 @@ class CTxManage
const int m_nFrontPorch = 0; const int m_nFrontPorch = 0;
int m_sysUpdate; int m_sysUpdate;
std::function<void(const char*)> _callback; std::function<void(const char*)> _callback;
bool _prime;
public: public:
CTxManage(int TxGatePin, HardwareSerial& serial); CTxManage(int TxGatePin, HardwareSerial& serial);
@ -42,6 +43,7 @@ public:
static void IRAM_ATTR callbackGateTerminate(); static void IRAM_ATTR callbackGateTerminate();
void queueSysUpdate(); // use to implant NV settings into heater void queueSysUpdate(); // use to implant NV settings into heater
void setCallback(std::function<void(const char*)> fn) { _callback = fn; }; void setCallback(std::function<void(const char*)> fn) { _callback = fn; };
void reqPrime(bool on);
private: private:
HardwareSerial& m_BlueWireSerial; HardwareSerial& m_BlueWireSerial;

View file

@ -123,28 +123,30 @@ CDemandManager::checkStart()
// create a deny start temperature margin // create a deny start temperature margin
int stopDeltaT = 0; int stopDeltaT = 0;
int cyclicstop = NVstore.getUserSettings().cyclic.Stop;
if(cyclicstop) { // cyclic mode enabled
// if cylic mode, raise the margin by the cyclic stop range
stopDeltaT = cyclicstop + 1; // bump up by 1 degree - no point invoking cyclic at 1 deg over!
}
// determine temperature error vs desired thermostat value // determine temperature error vs desired thermostat value
float deltaT = getTemperatureSensor() - getDegC(); float deltaT = getTemperatureSensor() - getDegC();
if(deltaT > stopDeltaT) { int cyclicstop = NVstore.getUserSettings().cyclic.Stop;
// temperature exceeded the allowed margin if(cyclicstop) { // cyclic mode enabled
if(cyclicstop) { // if cyclic mode, raise the margin by the cyclic stop range
// using cyclic mode - suggest immediate cyclic suspend stopDeltaT = cyclicstop + 1; // bump up by 1 degree - no point invoking cyclic at 1 deg over!
// alows honour cyclic stop threshold - immediate suspend transition
if(deltaT > stopDeltaT) {
return eStartSuspend; return eStartSuspend;
} }
else { }
// only deny start if actually using thermostat mode
if(!isExtThermostatMode()) {
if(deltaT > stopDeltaT) {
// temperature exceeded the allowed margin
// only deny start if actually using inbuilt thermostat mode
if(isThermostat()) { if(isThermostat()) {
return eStartTooWarm; // too warm - deny start return eStartTooWarm; // too warm - deny start
} }
} }
} }
return eStartOK; // allow start return eStartOK; // allow start
} }

View file

@ -77,9 +77,9 @@ void streamFileCoreSSL(const size_t fileSize, const String & fileName, const Str
void processWebsocketQueue(); void processWebsocketQueue();
QueueHandle_t webSocketQueue = NULL; QueueHandle_t webSocketQueue = NULL;
TaskHandle_t handleWebServerTask;
#if USE_HTTPS == 1 #if USE_HTTPS == 1
SSLCert* pCert; SSLCert* pCert;
TaskHandle_t handleSSLTask;
HTTPSServer * secureServer; HTTPSServer * secureServer;
#endif #endif
HTTPServer * insecureServer; HTTPServer * insecureServer;
@ -403,7 +403,7 @@ void initWebServer(void) {
16384, 16384,
NULL, NULL,
TASK_PRIORITY_SSL_CERT, // low priority as this blocks BIG time TASK_PRIORITY_SSL_CERT, // low priority as this blocks BIG time
&handleSSLTask); &handleWebServerTask);
while(!xSemaphoreTake(SSLSemaphore, 250)) { while(!xSemaphoreTake(SSLSemaphore, 250)) {
ScreenManager.showBootWait(1); ScreenManager.showBootWait(1);
@ -476,12 +476,12 @@ void initWebServer(void) {
// setup task to handle webserver // setup task to handle webserver
webSocketQueue = xQueueCreate(50, sizeof(char*) ); webSocketQueue = xQueueCreate(50, sizeof(char*) );
xTaskCreate(SSLloopTask, xTaskCreate(SSLloopTask,
"SSLloopTask", "Web server task",
8192, 8192,
// 16384, // 16384,
NULL, NULL,
TASK_PRIORITY_SSL_LOOP, // low priority as this potentially blocks BIG time TASK_PRIORITY_SSL_LOOP, // low priority as this potentially blocks BIG time
&handleSSLTask); &handleWebServerTask);
DebugPort.println("HTTP task started"); DebugPort.println("HTTP task started");
} }