diff --git a/src/Afterburner.cpp b/src/Afterburner.cpp index 8552265..0eda133 100644 --- a/src/Afterburner.cpp +++ b/src/Afterburner.cpp @@ -123,8 +123,8 @@ #define RX_DATA_TIMOUT 50 const int FirmwareRevision = 30; -const int FirmwareSubRevision = 4; -const char* FirmwareDate = "18 Aug 2019"; +const int FirmwareSubRevision = 5; +const char* FirmwareDate = "26 Aug 2019"; #ifdef ESP32 @@ -1043,6 +1043,11 @@ bool getExternalThermostatOn() return GPIOin.getState(1); } +const char* getExternalThermostatHoldTime() +{ + return GPIOin.getExtThermHoldTime(); +} + void checkDisplayUpdate() { diff --git a/src/OLED/DetailedScreen.cpp b/src/OLED/DetailedScreen.cpp index a1d6ce8..672f9b8 100644 --- a/src/OLED/DetailedScreen.cpp +++ b/src/OLED/DetailedScreen.cpp @@ -330,11 +330,19 @@ CDetailedScreen::showThermometer(float fDesired, float fActual, float fPump) // may be suppressed if not in normal start or run state if((fDesired != 0) || (fPump != 0)) { if(getThermostatModeActive() && getExternalThermostatModeActive()) { - _drawBitmap(X_TARGET_ICON-1, Y_TARGET_ICON, ExtThermo2IconInfo); // draw external input #2 icon - if(getExternalThermostatOn()) - _drawBitmap(X_TARGET_ICON-2, Y_TARGET_ICON+9, CloseIconInfo); // draw external input #2 icon + const char* pTimeStr = getExternalThermostatHoldTime(); + if(pTimeStr) { + CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font + _drawBitmap(X_TARGET_ICON-1, Y_TARGET_ICON+2, ExtThermo2IconInfo); // draw external input #2 icon + _printMenuText(X_TARGET_ICON+(TargetIconInfo.width/2)-1, Y_TARGET_ICON-4, pTimeStr, false, eCentreJustify); + _drawBitmap(X_TARGET_ICON-8, Y_TARGET_ICON-4, miniStopIconInfo); // draw stop icon + } else - _drawBitmap(X_TARGET_ICON-2, Y_TARGET_ICON+9, OpenIconInfo); // draw external input #2 icon + _drawBitmap(X_TARGET_ICON-1, Y_TARGET_ICON+2, ExtThermo2IconInfo); // draw external input #2 icon + if(getExternalThermostatOn()) + _drawBitmap(X_TARGET_ICON-2, Y_TARGET_ICON+10, CloseIconInfo); // draw external input #2 icon + else + _drawBitmap(X_TARGET_ICON-2, Y_TARGET_ICON+10, OpenIconInfo); // draw external input #2 icon } else { _drawBitmap(X_TARGET_ICON, Y_TARGET_ICON, TargetIconInfo); // draw target icon diff --git a/src/OLED/GPIOSetupScreen.cpp b/src/OLED/GPIOSetupScreen.cpp index 06791f0..46bfafa 100644 --- a/src/OLED/GPIOSetupScreen.cpp +++ b/src/OLED/GPIOSetupScreen.cpp @@ -113,9 +113,9 @@ CGPIOSetupScreen::show() _printMenuText(Column1, Line2, msgText, _rowSel == 2); if(_GPIOparams.in2Mode == CGPIOin2::Thermostat) { - const char* modeStr = "---"; + _drawBitmap(Column1 + 13, Line2-2, TimerIconInfo); + const char* modeStr = "No"; switch(_ExtHold) { -// case 0: modeStr = "Psv"; break; case 60000: modeStr = "1m"; break; case 120000: modeStr = "2m"; break; case 300000: modeStr = "5m"; break; @@ -125,7 +125,7 @@ CGPIOSetupScreen::show() case 1800000: modeStr = "30m"; break; case 3600000: modeStr = "1hr"; break; } - _printMenuText(Column1 + 18, Line2, modeStr, _rowSel == 3); + _printMenuText(Column1 + 29, Line2, modeStr, _rowSel == 3); } } @@ -205,7 +205,7 @@ CGPIOSetupScreen::animate() break; case 3: _display.drawFastHLine(0, 52, 128, WHITE); - pMsg = " Input 2: External thermostat. Start heater upon closure, stop after open for specified period. "; + pMsg = " Input 2: External thermostat heater control. Start heater upon closure, stop after open for specified period. "; _scrollMessage(56, pMsg, _scrollChar); break; case 4: @@ -292,6 +292,10 @@ CGPIOSetupScreen::keyHandler(uint8_t event) } } if(event & key_Down) { + if(_rowSel == 10) { + _rowSel = 0; // abort save + } + else { _scrollChar = 0; _rowSel--; if((_rowSel == 3) && (_GPIOparams.in2Mode != CGPIOin2::Thermostat)) @@ -299,6 +303,7 @@ CGPIOSetupScreen::keyHandler(uint8_t event) if((_rowSel == 1) && (getBoardRevision() == BRD_V2_GPIO_NOALG)) // GPIO but NO analog support _rowSel--; // force skip if analog input is not supported by PCB LOWERLIMIT(_rowSel, 0); + } } // UP press if(event & key_Up) { diff --git a/src/Utility/BTC_GPIO.cpp b/src/Utility/BTC_GPIO.cpp index 08e1dd4..a7270a6 100644 --- a/src/Utility/BTC_GPIO.cpp +++ b/src/Utility/BTC_GPIO.cpp @@ -178,7 +178,15 @@ CGPIOin2::_doThermostat(bool active) _OffHoldoff = (millis() + NVstore.getUserSettings().ExtThermoTimeout) | 1; DebugPort.printf("thermostat contact opened - will stop in %ldms\r\n", NVstore.getUserSettings().ExtThermoTimeout); } - if(!active) { + if(active) { + _OffHoldoff = 0; + int runstate = getHeaterInfo().getRunStateEx(); + int errstate = getHeaterInfo().getErrState(); + if(runstate == 0 && errstate == 0) { + requestOn(); // request heater to start upon closure of thermostat input (may have shutdown before contact closed again) + } + } + else { if(_OffHoldoff) { long tDelta = millis() - _OffHoldoff; if(tDelta >= 0) { @@ -193,6 +201,23 @@ CGPIOin2::_doThermostat(bool active) // handling actually performed at Tx Manage for setting the fuel rate } +const char* +CGPIOin2::getExtThermTime() +{ + if((_OffHoldoff == 0) || (NVstore.getUserSettings().ThermostatMethod != 3) || (NVstore.getUserSettings().ExtThermoTimeout == 0)) + return NULL; + + long tDelta = _OffHoldoff - millis(); + if(tDelta < 0) + return NULL; + + long secs = tDelta / 1000; + long mins = secs / 60; + secs -= mins * 60; + static char timeStr[8]; + sprintf(timeStr, "%02ld:%02ld", mins, secs); + return timeStr; +} CGPIOin::CGPIOin() diff --git a/src/Utility/BTC_GPIO.h b/src/Utility/BTC_GPIO.h index a81cd83..40a724e 100644 --- a/src/Utility/BTC_GPIO.h +++ b/src/Utility/BTC_GPIO.h @@ -68,6 +68,7 @@ public: void begin(Modes mode); void manage(bool active); Modes getMode() const; + const char* getExtThermTime(); private: Modes _Mode; bool _prevActive; @@ -94,6 +95,9 @@ public: bool usesExternalThermostat() const { return (_Input2.getMode() == CGPIOin2::Thermostat); }; + const char* getExtThermHoldTime() { + return _Input2.getExtThermTime(); + } }; class CGPIOout1 { diff --git a/src/Utility/helpers.h b/src/Utility/helpers.h index 1ce5c26..d1287f4 100644 --- a/src/Utility/helpers.h +++ b/src/Utility/helpers.h @@ -38,6 +38,7 @@ extern bool setThermostatMode(uint8_t); extern bool getThermostatModeActive(); // OEM: actual mode from blue wire, BTC: or our NV extern bool getExternalThermostatModeActive(); extern bool getExternalThermostatOn(); +extern const char* getExternalThermostatHoldTime(); extern void reqPumpPrime(bool on); extern float getTemperatureDesired(); // OEM: the advertised value, BTC our setpoint extern uint8_t getDemandDegC();