Added DemandManager, removing TimerManager from direct temperature demand control aspects
Likewise moved demand adjustments into DemandManager.
This commit is contained in:
parent
9839571893
commit
67998747d7
|
@ -119,6 +119,7 @@
|
|||
#include <FreeRTOS.h>
|
||||
#include "RTC/TimerManager.h"
|
||||
#include "Utility/GetLine.h"
|
||||
#include "Utility/DemandManager.h"
|
||||
|
||||
// SSID & password now stored in NV storage - these are still the default values.
|
||||
//#define AP_SSID "Afterburner"
|
||||
|
@ -155,7 +156,6 @@ void checkDebugCommands();
|
|||
void manageCyclicMode();
|
||||
void manageFrostMode();
|
||||
void manageHumidity();
|
||||
int checkStartTemp();
|
||||
void doStreaming();
|
||||
void heaterOn();
|
||||
void heaterOff();
|
||||
|
@ -519,11 +519,9 @@ void setup() {
|
|||
pHourMeter->init(bESP32PowerUpInit || RTC_Store.getBootInit()); // ensure persistent memory variable are reset after powerup, or OTA update
|
||||
RTC_Store.setBootInit(false);
|
||||
|
||||
// bug fix: was not applying saved set points!
|
||||
// reqDemand(RTC_Store.getDesiredTemp());
|
||||
CTimerManager::setWorkingTemperature(RTC_Store.getDesiredTemp());
|
||||
CTimerManager::setWorkingPumpHz(RTC_Store.getDesiredPump());
|
||||
|
||||
// apply saved set points!
|
||||
CDemandManager::reload();
|
||||
|
||||
// Check for solo DS18B20
|
||||
// store it's serial number as the primary sensor
|
||||
// This allows seamless standard operation, and marks the iniital sensor
|
||||
|
@ -952,7 +950,7 @@ void manageCyclicMode()
|
|||
const sCyclicThermostat& cyclic = NVstore.getUserSettings().cyclic;
|
||||
if(cyclic.Stop && RTC_Store.getCyclicEngaged()) { // cyclic mode enabled, and user has started heater
|
||||
int stopDeltaT = cyclic.Stop + 1; // bump up by 1 degree - no point invoking at 1 deg over!
|
||||
float deltaT = getTemperatureSensor() - getDemandDegC();
|
||||
float deltaT = getTemperatureSensor() - CDemandManager::getDegC();
|
||||
// DebugPort.printf("Cyclic=%d bUserOn=%d deltaT=%d\r\n", cyclic, bUserON, deltaT);
|
||||
|
||||
// ensure we cancel user ON mode if heater throws an error
|
||||
|
@ -1024,31 +1022,6 @@ void manageHumidity()
|
|||
}
|
||||
}
|
||||
|
||||
int checkStartTemp()
|
||||
{
|
||||
int stopDeltaT = 0;
|
||||
int cyclicstop = NVstore.getUserSettings().cyclic.Stop;
|
||||
if(cyclicstop) { // cyclic mode enabled
|
||||
stopDeltaT = cyclicstop + 1; // bump up by 1 degree - no point invoking at 1 deg over!
|
||||
}
|
||||
|
||||
float deltaT = getTemperatureSensor() - getDemandDegC();
|
||||
|
||||
if(deltaT > stopDeltaT) {
|
||||
if(cyclicstop) {
|
||||
DebugPort.printf("CYCLIC MODE: Skipping directly to suspend, deltaT > +%d\r\n", stopDeltaT);
|
||||
heaterOff(); // over temp - request heater stop
|
||||
return -2;
|
||||
}
|
||||
else {
|
||||
// too warm - deny start
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void initBlueWireSerial()
|
||||
{
|
||||
|
@ -1080,35 +1053,35 @@ bool validateFrame(const CProtocol& frame, const char* name)
|
|||
}
|
||||
|
||||
|
||||
// return values:
|
||||
// 0: OK
|
||||
// -1: too warm
|
||||
// -2: suspended
|
||||
// -3: Low Voltage Cutout
|
||||
// -4: Insufficent fuel
|
||||
int requestOn(bool checkTemp)
|
||||
CDemandManager::eStartCode
|
||||
requestOn()
|
||||
{
|
||||
DebugPort.println("Start Request!");
|
||||
bool fuelOK = 2 != SmartError.checkfuelUsage();
|
||||
if(!fuelOK) {
|
||||
return -4;
|
||||
return CDemandManager::eStartLowFuel;
|
||||
}
|
||||
bool LVCOK = 2 != SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue());
|
||||
if(bHasHtrData && LVCOK) {
|
||||
RTC_Store.setCyclicEngaged(true); // for cyclic mode
|
||||
RTC_Store.setFrostOn(false); // cancel frost mode
|
||||
// only start if below appropriate temperature threshold, raised for cyclic mode
|
||||
int denied = checkStartTemp();
|
||||
if(!checkTemp || !denied) {
|
||||
// int denied = checkStartTemp();
|
||||
CDemandManager::eStartCode startCode = CDemandManager::checkStart();
|
||||
if(startCode == CDemandManager::eStartOK) {
|
||||
heaterOn();
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return denied;
|
||||
if(startCode == CDemandManager::eStartSuspend) {
|
||||
SmartError.inhibit(true); // ensure our suspend does not get immediately cancelled by prior error sitting in system!
|
||||
DebugPort.printf("CYCLIC MODE: Skipping directly to suspend, deltaT > +%d\r\n", NVstore.getUserSettings().cyclic.Stop+1);
|
||||
heaterOff(); // over temp - request heater stop
|
||||
}
|
||||
}
|
||||
return startCode;
|
||||
}
|
||||
else {
|
||||
return -3; // LVC
|
||||
return CDemandManager::eStartLVC; // LVC
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1133,110 +1106,6 @@ void heaterOff()
|
|||
}
|
||||
|
||||
|
||||
bool reqDemand(uint8_t newDemand, bool save)
|
||||
{
|
||||
if(bHasOEMController)
|
||||
return false;
|
||||
|
||||
uint8_t max = DefaultBTCParams.getTemperature_Max();
|
||||
uint8_t min = DefaultBTCParams.getTemperature_Min();
|
||||
if(newDemand >= max)
|
||||
newDemand = max;
|
||||
if(newDemand <= min)
|
||||
newDemand = min;
|
||||
|
||||
// set and save the demand to NV storage
|
||||
// note that we now maintain fixed Hz and Thermostat set points seperately
|
||||
if(getThermostatModeActive()) {
|
||||
CTimerManager::setWorkingTemperature(newDemand);
|
||||
}
|
||||
else {
|
||||
CTimerManager::setWorkingPumpHz(newDemand);
|
||||
}
|
||||
|
||||
ScreenManager.reqUpdate();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool reqDemandDelta(int delta)
|
||||
{
|
||||
uint8_t newDemand;
|
||||
if(getThermostatModeActive()) {
|
||||
newDemand = CTimerManager::getWorkingTemperature() + delta;
|
||||
}
|
||||
else {
|
||||
newDemand = CTimerManager::getWorkingPumpHz() + delta;
|
||||
}
|
||||
|
||||
return reqDemand(newDemand);
|
||||
}
|
||||
|
||||
bool reqThermoToggle()
|
||||
{
|
||||
return setThermostatMode(getThermostatModeActive() ? 0 : 1);
|
||||
}
|
||||
|
||||
bool setThermostatMode(uint8_t val)
|
||||
{
|
||||
if(bHasOEMController)
|
||||
return false;
|
||||
|
||||
sUserSettings settings = NVstore.getUserSettings();
|
||||
if(INBOUNDS(val, 0, 1))
|
||||
settings.useThermostat = val;
|
||||
NVstore.setUserSettings(settings);
|
||||
return true;
|
||||
}
|
||||
|
||||
void setDegFMode(bool state)
|
||||
{
|
||||
sUserSettings settings = NVstore.getUserSettings();
|
||||
settings.degF = state ? 0x01 : 0x00;
|
||||
NVstore.setUserSettings(settings);
|
||||
}
|
||||
|
||||
|
||||
bool getThermostatModeActive()
|
||||
{
|
||||
if(bHasOEMController) {
|
||||
return getHeaterInfo().isThermostat();
|
||||
}
|
||||
else {
|
||||
return NVstore.getUserSettings().useThermostat != 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool getExternalThermostatModeActive()
|
||||
{
|
||||
#if USE_JTAG == 0
|
||||
return GPIOin.usesExternalThermostat() && (NVstore.getUserSettings().ThermostatMethod == 3);
|
||||
#else
|
||||
//CANNOT USE GPIO WITH JTAG DEBUG
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool getExternalThermostatOn()
|
||||
{
|
||||
#if USE_JTAG == 0
|
||||
return GPIOin.getState(1);
|
||||
#else
|
||||
//CANNOT USE GPIO WITH JTAG DEBUG
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* getExternalThermostatHoldTime()
|
||||
{
|
||||
#if USE_JTAG == 0
|
||||
return GPIOin.getExtThermHoldTime();
|
||||
#else
|
||||
//CANNOT USE GPIO WITH JTAG DEBUG
|
||||
return "00:00";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void checkDisplayUpdate()
|
||||
{
|
||||
// only update OLED when not processing blue wire
|
||||
|
@ -1265,39 +1134,6 @@ void forceBootInit()
|
|||
RTC_Store.setBootInit();
|
||||
}
|
||||
|
||||
uint8_t getDemandDegC()
|
||||
{
|
||||
return CTimerManager::getWorkingTemperature();
|
||||
}
|
||||
|
||||
void setDemandDegC(uint8_t val)
|
||||
{
|
||||
uint8_t max = DefaultBTCParams.getTemperature_Max();
|
||||
uint8_t min = DefaultBTCParams.getTemperature_Min();
|
||||
BOUNDSLIMIT(val, min, max);
|
||||
CTimerManager::setWorkingTemperature(val);
|
||||
}
|
||||
|
||||
uint8_t getDemandPump()
|
||||
{
|
||||
return CTimerManager::getWorkingPumpHz();
|
||||
}
|
||||
|
||||
|
||||
float getTemperatureDesired()
|
||||
{
|
||||
if(bHasOEMController) {
|
||||
return getHeaterInfo().getHeaterDemand();
|
||||
}
|
||||
else {
|
||||
if(getThermostatModeActive()) {
|
||||
return CTimerManager::getWorkingTemperature();
|
||||
}
|
||||
else {
|
||||
return CTimerManager::getWorkingPumpHz(); // timer manager will return pump Hz, as demand value, not real Hz
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float getTemperatureSensor(int source)
|
||||
{
|
||||
|
@ -1307,62 +1143,6 @@ float getTemperatureSensor(int source)
|
|||
|
||||
}
|
||||
|
||||
void setPumpMin(float val)
|
||||
{
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
tuning.setPmin(val);
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
}
|
||||
|
||||
void setPumpMax(float val)
|
||||
{
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
tuning.setPmax(val);
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
}
|
||||
|
||||
void setFanMin(uint16_t cVal)
|
||||
{
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
if(INBOUNDS(cVal, 500, 5000))
|
||||
tuning.Fmin = cVal;
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
}
|
||||
|
||||
void setFanMax(uint16_t cVal)
|
||||
{
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
if(INBOUNDS(cVal, 500, 5000))
|
||||
tuning.Fmax = cVal;
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
}
|
||||
|
||||
void setFanSensor(uint8_t cVal)
|
||||
{
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
if(INBOUNDS(cVal, 1, 2))
|
||||
tuning.fanSensor = cVal;
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
}
|
||||
|
||||
void setSystemVoltage(float val) {
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
tuning.setSysVoltage(val);
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
}
|
||||
|
||||
void setGlowDrive(uint8_t val) {
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
if(INBOUNDS(val, 1, 6))
|
||||
tuning.glowDrive = val;
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
}
|
||||
|
||||
|
||||
void saveNV()
|
||||
{
|
||||
NVstore.save();
|
||||
}
|
||||
|
||||
const CProtocolPackage& getHeaterInfo()
|
||||
{
|
||||
|
@ -1874,8 +1654,6 @@ void doStreaming()
|
|||
|
||||
KeyPad.update(); // scan keypad - key presses handler via callback functions!
|
||||
|
||||
Bluetooth.check(); // check for Bluetooth activity
|
||||
|
||||
#if USE_JTAG == 0
|
||||
//CANNOT USE GPIO WITH JTAG DEBUG
|
||||
GPIOin.manage();
|
||||
|
@ -1883,6 +1661,8 @@ void doStreaming()
|
|||
GPIOalg.manage();
|
||||
#endif
|
||||
|
||||
Bluetooth.check(); // check for Bluetooth activity
|
||||
|
||||
// manage changes in Bluetooth connection status
|
||||
if(Bluetooth.isConnected()) {
|
||||
if(!bBTconnected) {
|
||||
|
|
|
@ -253,7 +253,7 @@ CBluetoothHC05::foldbackDesiredTemp()
|
|||
StaticJsonBuffer<32> jsonBuffer; // create a JSON buffer on the stack
|
||||
JsonObject& root = jsonBuffer.createObject(); // create object to add JSON commands to
|
||||
|
||||
if(foldbackModerator.addJson("TempDesired", getTemperatureDesired(), root)) {
|
||||
if(foldbackModerator.addJson("TempDesired", CDemandManager::getDemand(), root)) {
|
||||
char opStr[32];
|
||||
root.printTo(opStr);
|
||||
send(opStr);
|
||||
|
|
|
@ -70,10 +70,11 @@ CBasicScreen::show()
|
|||
long tDelta = millis() - _showAbortTime;
|
||||
if(tDelta < 0) {
|
||||
switch(_abortreason) {
|
||||
case -1: strcpy(msg, "Ignored - too warm!"); break;
|
||||
case -2: strcpy(msg, "Suspended - too warm!"); break;
|
||||
case -3: strcpy(msg, "Ignored - low voltage!"); break;
|
||||
case -4: strcpy(msg, "Ignored - fuel empty!"); break;
|
||||
case CDemandManager::eStartOK: strcpy(msg, "Start OK!"); break;
|
||||
case CDemandManager::eStartTooWarm: strcpy(msg, "Ignored - too warm!"); break;
|
||||
case CDemandManager::eStartSuspend: strcpy(msg, "Suspended - too warm!"); break;
|
||||
case CDemandManager::eStartLVC: strcpy(msg, "Ignored - low voltage!"); break;
|
||||
case CDemandManager::eStartLowFuel: strcpy(msg, "Ignored - fuel empty!"); break;
|
||||
}
|
||||
// centre message at bottom of screen
|
||||
_printMenuText(_display.xCentre(), _display.height() - _display.textHeight(), msg, false, eCentreJustify);
|
||||
|
@ -120,12 +121,12 @@ CBasicScreen::show()
|
|||
case 0:
|
||||
// Show current heat demand setting
|
||||
|
||||
if(getThermostatModeActive()) {
|
||||
if(getExternalThermostatModeActive()) {
|
||||
if(CDemandManager::isThermostat()) {
|
||||
if(CDemandManager::isExtThermostatMode()) {
|
||||
sprintf(msg, "External @ %.1fHz", getHeaterInfo().getPump_Fixed());
|
||||
}
|
||||
else {
|
||||
float fTemp = getTemperatureDesired();
|
||||
float fTemp = CDemandManager::getDegC();
|
||||
if(NVstore.getUserSettings().degF) {
|
||||
fTemp = fTemp * 9 / 5 + 32;
|
||||
sprintf(msg, "Setpoint = %.0f`F", fTemp);
|
||||
|
@ -267,7 +268,7 @@ CBasicScreen::keyHandler(uint8_t event)
|
|||
repeatCount = -1; // prevent double handling
|
||||
if(NVstore.getUserSettings().menuMode < 2) {
|
||||
_showModeTime = millis() + 5000;
|
||||
_nModeSel = getThermostatModeActive() ? 0 : 1;
|
||||
_nModeSel = CDemandManager::isThermostat() ? 0 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +300,7 @@ CBasicScreen::keyHandler(uint8_t event)
|
|||
if(repeatCount > 3) {
|
||||
repeatCount = -1;
|
||||
_abortreason = requestOn();
|
||||
if(_abortreason) {
|
||||
if(_abortreason != CDemandManager::eStartOK) {
|
||||
_showAbortTime = millis() + 5000;
|
||||
}
|
||||
}
|
||||
|
@ -317,7 +318,7 @@ CBasicScreen::keyHandler(uint8_t event)
|
|||
// release DOWN key to reduce set demand, provided we are not in mode select
|
||||
if(NVstore.getUserSettings().menuMode < 2) {
|
||||
if(event & key_Down) {
|
||||
if(reqDemandDelta(-1)) {
|
||||
if(CDemandManager::deltaDemand(-1)) {
|
||||
_showSetModeTime = millis() + 5000;
|
||||
_bShowOtherSensors = 0;
|
||||
_feedbackType = 0;
|
||||
|
@ -328,7 +329,7 @@ CBasicScreen::keyHandler(uint8_t event)
|
|||
}
|
||||
// release UP key to increase set demand, provided we are not in mode select
|
||||
if(event & key_Up) {
|
||||
if(reqDemandDelta(+1)) {
|
||||
if(CDemandManager::deltaDemand(+1)) {
|
||||
_showSetModeTime = millis() + 5000;
|
||||
_bShowOtherSensors = 0;
|
||||
_feedbackType = 0;
|
||||
|
@ -350,8 +351,7 @@ CBasicScreen::keyHandler(uint8_t event)
|
|||
else {
|
||||
_showModeTime = millis() + 5000;
|
||||
_nModeSel = 0;
|
||||
setThermostatMode(1); // set the new mode
|
||||
NVstore.save();
|
||||
CDemandManager::setThermostatMode(1); // set the new mode
|
||||
}
|
||||
_ScreenManager.reqUpdate();
|
||||
}
|
||||
|
@ -367,8 +367,7 @@ CBasicScreen::keyHandler(uint8_t event)
|
|||
else {
|
||||
_showModeTime = millis() + 5000;
|
||||
_nModeSel = 1;
|
||||
setThermostatMode(0); // set the new mode
|
||||
NVstore.save();
|
||||
CDemandManager::setThermostatMode(0); // set the new mode
|
||||
}
|
||||
_ScreenManager.reqUpdate();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include "ScreenHeader.h"
|
||||
#include "../Utility/DemandManager.h"
|
||||
|
||||
class C128x64_OLED;
|
||||
class CScreenManager;
|
||||
|
@ -31,7 +32,7 @@ class CBasicScreen : public CScreenHeader
|
|||
unsigned long _showSetModeTime;
|
||||
unsigned long _showModeTime;
|
||||
unsigned long _showAbortTime;
|
||||
int _abortreason;
|
||||
CDemandManager::eStartCode _abortreason;
|
||||
uint8_t _bShowOtherSensors;
|
||||
uint8_t _feedbackType;
|
||||
uint8_t _nModeSel;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "../Utility/NVStorage.h"
|
||||
#include "../Utility/FuelGauge.h"
|
||||
#include "../RTC/RTCStore.h"
|
||||
#include "../Utility/DemandManager.h"
|
||||
|
||||
|
||||
#define MINIFONT miniFontInfo
|
||||
|
@ -98,13 +99,13 @@ CDetailedScreen::show()
|
|||
float desiredT = 0;
|
||||
float fPump = 0;
|
||||
if((runstate && (runstate <= 5)) || (runstate == 9) || _showTarget) { // state 9 = manufactured "heating glow plug"
|
||||
if(getThermostatModeActive() && !getExternalThermostatModeActive()) {
|
||||
desiredT = getTemperatureDesired();
|
||||
if(CDemandManager::isThermostat() && !CDemandManager::isExtThermostatMode()) {
|
||||
desiredT = CDemandManager::getDemand();
|
||||
}
|
||||
else {
|
||||
fPump = getHeaterInfo().getPump_Fixed();
|
||||
if(NVstore.getUserSettings().cyclic.isEnabled())
|
||||
desiredT = getDemandDegC();
|
||||
desiredT = CDemandManager::getDegC();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,9 +235,8 @@ CDetailedScreen::keyHandler(uint8_t event)
|
|||
if(event & key_Down) {
|
||||
if(_keyRepeatCount > 1) { // held Down - toggle thermo/fixed mode
|
||||
_keyRepeatCount = -1; // prevent double handling
|
||||
if(reqThermoToggle()) {
|
||||
if(CDemandManager::toggleThermostat()) {
|
||||
_showTarget = millis() + 3500;
|
||||
NVstore.save();
|
||||
}
|
||||
else _reqOEMWarning();
|
||||
}
|
||||
|
@ -256,11 +256,17 @@ CDetailedScreen::keyHandler(uint8_t event)
|
|||
if(event & keyReleased) {
|
||||
if(_keyRepeatCount == 0) { // short Up press - lower target
|
||||
if(event & key_Up) {
|
||||
if(reqDemandDelta(+1)) _showTarget = millis() + 3500;
|
||||
if(CDemandManager::deltaDemand(+1)) {
|
||||
_showTarget = millis() + 3500;
|
||||
_ScreenManager.reqUpdate();
|
||||
}
|
||||
else _reqOEMWarning();
|
||||
}
|
||||
if(event & key_Down) { // short Down press - lower target
|
||||
if(reqDemandDelta(-1)) _showTarget = millis() + 3500;
|
||||
if(CDemandManager::deltaDemand(-1)) {
|
||||
_showTarget = millis() + 3500;
|
||||
_ScreenManager.reqUpdate();
|
||||
}
|
||||
else _reqOEMWarning();
|
||||
}
|
||||
if(event & key_Centre) { // short Centre press - show target
|
||||
|
@ -333,8 +339,8 @@ CDetailedScreen::showThermometer(float fDesired, float fActual, float fPump)
|
|||
// draw target setting
|
||||
// may be suppressed if not in normal start or run state
|
||||
if((fDesired != 0) || (fPump != 0)) {
|
||||
if(getThermostatModeActive() && getExternalThermostatModeActive()) {
|
||||
const char* pTimeStr = getExternalThermostatHoldTime();
|
||||
if(CDemandManager::isThermostat() && CDemandManager::isExtThermostatMode()) {
|
||||
const char* pTimeStr = CDemandManager::getExtThermostatHoldTime();
|
||||
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
|
||||
|
@ -343,7 +349,7 @@ CDetailedScreen::showThermometer(float fDesired, float fActual, float fPump)
|
|||
}
|
||||
else
|
||||
_drawBitmap(X_TARGET_ICON-1, Y_TARGET_ICON+2, ExtThermo2IconInfo); // draw external input #2 icon
|
||||
if(getExternalThermostatOn())
|
||||
if(CDemandManager::isExtThermostatOn())
|
||||
_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
|
||||
|
|
|
@ -260,9 +260,11 @@ CFuelMixtureScreen::_adjustSetting(int dir)
|
|||
void
|
||||
CFuelMixtureScreen::_saveNV()
|
||||
{
|
||||
setPumpMin(adjPump[0]);
|
||||
setPumpMax(adjPump[1]);
|
||||
setFanMin(adjFan[0]);
|
||||
setFanMax(adjFan[1]);
|
||||
saveNV();
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
tuning.setPmin(adjPump[0]);
|
||||
tuning.setPmax(adjPump[1]);
|
||||
tuning.setFmin(adjFan[0]);
|
||||
tuning.setFmax(adjFan[1]);
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
NVstore.save();
|
||||
}
|
||||
|
|
|
@ -231,8 +231,10 @@ CHeaterSettingsScreen::_adjust(int dir)
|
|||
void
|
||||
CHeaterSettingsScreen::_saveNV()
|
||||
{
|
||||
setSystemVoltage(float(_sysVoltage));
|
||||
setFanSensor(_fanSensor);
|
||||
setGlowDrive(_glowDrive);
|
||||
saveNV();
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
tuning.setSysVoltage(float(_sysVoltage));
|
||||
tuning.setFanSensor(_fanSensor);
|
||||
tuning.setGlowDrive(_glowDrive);
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
NVstore.save();
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "KeyPad.h"
|
||||
#include "../Utility/helpers.h"
|
||||
#include "../Protocol/Protocol.h"
|
||||
#include "../Utility/NVStorage.h"
|
||||
|
||||
|
||||
CInheritSettingsScreen::CInheritSettingsScreen(C128x64_OLED& display, CScreenManager& mgr) : CPasswordScreen(display, mgr)
|
||||
|
@ -122,13 +123,15 @@ CInheritSettingsScreen::keyHandler(uint8_t event)
|
|||
void
|
||||
CInheritSettingsScreen::_copySettings()
|
||||
{
|
||||
setPumpMin(getHeaterInfo().getPump_Min());
|
||||
setPumpMax(getHeaterInfo().getPump_Max());
|
||||
setFanMin(getHeaterInfo().getFan_Min());
|
||||
setFanMax(getHeaterInfo().getFan_Max());
|
||||
setFanSensor(getHeaterInfo().getFan_Sensor());
|
||||
setSystemVoltage(getHeaterInfo().getSystemVoltage());
|
||||
saveNV();
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
tuning.setPmin(getHeaterInfo().getPump_Min());
|
||||
tuning.setPmax(getHeaterInfo().getPump_Max());
|
||||
tuning.setFmin(getHeaterInfo().getFan_Min());
|
||||
tuning.setFmax(getHeaterInfo().getFan_Max());
|
||||
tuning.fanSensor = getHeaterInfo().getFan_Sensor();
|
||||
tuning.setSysVoltage(getHeaterInfo().getSystemVoltage());
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
NVstore.save();
|
||||
_enableStoringMessage();
|
||||
_nAdoptSettings = 0; // will cause return to main menu after storing message expires
|
||||
}
|
|
@ -136,7 +136,7 @@ CPrimingScreen::show()
|
|||
}
|
||||
else {
|
||||
// follow actual heater settings
|
||||
if(getThermostatModeActive()) {
|
||||
if(CDemandManager::isThermostat()) {
|
||||
_drawBitmap(loc.xPos, midline, NVstore.getUserSettings().degF ? ThermostatDegFIconInfo : ThermostatDegCIconInfo);
|
||||
}
|
||||
else {
|
||||
|
@ -243,7 +243,7 @@ CPrimingScreen::keyHandler(uint8_t event)
|
|||
_colSel = 0;
|
||||
switch(_paramSel) {
|
||||
case 1:
|
||||
_colSel = getThermostatModeActive() ? 0 : 1;
|
||||
_colSel = CDemandManager::isThermostat() ? 0 : 1;
|
||||
break;
|
||||
case 2:
|
||||
_colSel = NVstore.getUserSettings().degF ? 1 : 0;
|
||||
|
@ -270,7 +270,7 @@ CPrimingScreen::keyHandler(uint8_t event)
|
|||
_colSel = NVstore.getUserSettings().degF ? 1 : 0;
|
||||
break;
|
||||
case 1:
|
||||
_colSel = getThermostatModeActive() ? 0 : 1;
|
||||
_colSel = CDemandManager::isThermostat() ? 0 : 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -285,19 +285,17 @@ CPrimingScreen::keyHandler(uint8_t event)
|
|||
switch(_paramSel) {
|
||||
case 0:
|
||||
_paramSel = 1;
|
||||
_colSel = getThermostatModeActive() ? 0 : 1;
|
||||
_colSel = CDemandManager::isThermostat() ? 0 : 1;
|
||||
break;
|
||||
case 1:
|
||||
_colSel++;
|
||||
WRAPLIMITS(_colSel, 0, 1);
|
||||
setThermostatMode(_colSel == 0);
|
||||
saveNV();
|
||||
CDemandManager::setThermostatMode(_colSel == 0);
|
||||
break;
|
||||
case 2:
|
||||
_colSel++;
|
||||
WRAPLIMITS(_colSel, 0, 1);
|
||||
setDegFMode(_colSel != 0);
|
||||
saveNV();
|
||||
CDemandManager::setDegFMode(_colSel != 0);
|
||||
break;
|
||||
case 3:
|
||||
if(_resetConfirm) {
|
||||
|
@ -330,14 +328,12 @@ CPrimingScreen::keyHandler(uint8_t event)
|
|||
case 1:
|
||||
_colSel--;
|
||||
WRAPLIMITS(_colSel, 0, 1);
|
||||
setThermostatMode(_colSel == 0);
|
||||
saveNV();
|
||||
CDemandManager::setThermostatMode(_colSel == 0);
|
||||
break;
|
||||
case 2:
|
||||
_colSel--;
|
||||
WRAPLIMITS(_colSel, 0, 1);
|
||||
setDegFMode(_colSel != 0);
|
||||
saveNV();
|
||||
CDemandManager::setDegFMode(_colSel != 0);
|
||||
break;
|
||||
case 3:
|
||||
_colSel--;
|
||||
|
|
|
@ -43,16 +43,17 @@ CSmartError::reset()
|
|||
// we use inhibit when we manually command the heater off during preheat
|
||||
// otherwise we'll register an ignition fail event
|
||||
void
|
||||
CSmartError::inhibit()
|
||||
CSmartError::inhibit(bool reseterror)
|
||||
{
|
||||
_bInhibit = true;
|
||||
// m_Error = 0;
|
||||
if(reseterror)
|
||||
_Error = 0;
|
||||
}
|
||||
|
||||
// accept a fresh heater frame
|
||||
// inpsect the advertised run state, tracking when and how it transitions out
|
||||
// of preheat especially.
|
||||
// abnormal transitions are registered and becoem our smart m_Error
|
||||
// abnormal transitions are registered and becoem our smart '_Error'
|
||||
// In addition, the hetaer frame has the ErrState updated to track the
|
||||
// smart error, providing no heater error exists!
|
||||
void
|
||||
|
|
|
@ -28,7 +28,7 @@ class CSmartError {
|
|||
public:
|
||||
CSmartError();
|
||||
void reset();
|
||||
void inhibit();
|
||||
void inhibit(bool reseterror=false);
|
||||
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
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
#include "TxManage.h"
|
||||
#include "../Utility/NVStorage.h"
|
||||
#include "../Utility/helpers.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "../Utility/DemandManager.h"
|
||||
#include "freertos/freertos.h"
|
||||
|
||||
//#define DEBUG_THERMOSTAT
|
||||
|
||||
|
@ -181,19 +182,19 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
|
|||
float tActual = getTemperatureSensor();
|
||||
int8_t s8Temp = (int8_t)(tActual + 0.5);
|
||||
m_TxFrame.setTemperature_Actual(s8Temp); // use current temp, for now
|
||||
m_TxFrame.setHeaterDemand(getDemandDegC());
|
||||
m_TxFrame.setHeaterDemand(CDemandManager::getDegC());
|
||||
m_TxFrame.setThermostatModeProtocol(1); // assume using thermostat control for now
|
||||
|
||||
if(!getThermostatModeActive()) {
|
||||
if(!CDemandManager::isThermostat()) {
|
||||
m_TxFrame.setThermostatModeProtocol(0); // not using any form of thermostat control
|
||||
m_TxFrame.setHeaterDemand(getDemandPump()); // set fixed Hz demand instead
|
||||
m_TxFrame.setHeaterDemand(CDemandManager::getPumpHz()); // set fixed Hz demand instead
|
||||
m_TxFrame.setTemperature_Actual(0); // must force actual to 0 for Hz mode
|
||||
}
|
||||
else if(NVstore.getUserSettings().ThermostatMethod) {
|
||||
uint8_t ThermoMode = NVstore.getUserSettings().ThermostatMethod; // get the METHOD of thermostat control
|
||||
float Window = NVstore.getUserSettings().ThermostatWindow;
|
||||
float tCurrent = getTemperatureSensor();
|
||||
float tDesired = float(getDemandDegC());
|
||||
float tDesired = float(CDemandManager::getDegC());
|
||||
float tDelta = tCurrent - tDesired;
|
||||
float fTemp;
|
||||
#ifdef DEBUG_THERMOSTAT
|
||||
|
@ -203,8 +204,8 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
|
|||
switch(ThermoMode) {
|
||||
|
||||
case 3: // GPIO controlled thermostat mode
|
||||
if(getExternalThermostatModeActive()) {
|
||||
if(getExternalThermostatOn()) {
|
||||
if(CDemandManager::isExtThermostatMode()) {
|
||||
if(CDemandManager::isExtThermostatOn()) {
|
||||
s8Temp = m_TxFrame.getTemperature_Max(); // input active (contact closure) - max burn
|
||||
}
|
||||
else {
|
||||
|
@ -232,11 +233,11 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
|
|||
s8Temp = (int8_t)(tActual + 0.5); // use rounded actual unless within window
|
||||
if(fabs(tDelta) < Window) {
|
||||
// hold at desired if inside window
|
||||
s8Temp = getDemandDegC();
|
||||
s8Temp = CDemandManager::getDegC();
|
||||
}
|
||||
else if(fabs(tDelta) <= 1.0) {
|
||||
// force outside if delta is <= 1 but greater than window
|
||||
s8Temp = getDemandDegC() + ((tDelta > 0) ? 1 : -1);
|
||||
s8Temp = CDemandManager::getDegC() + ((tDelta > 0) ? 1 : -1);
|
||||
}
|
||||
m_TxFrame.setTemperature_Actual(s8Temp);
|
||||
#ifdef DEBUG_THERMOSTAT
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "../Utility/NVStorage.h"
|
||||
#include "../Utility/helpers.h"
|
||||
#include "../RTC/RTCStore.h"
|
||||
#include "../Utility/DemandManager.h"
|
||||
|
||||
// main array to hold information of which timer is active at any particular minute of the week
|
||||
// LSBs are used for the timerID + 1
|
||||
|
@ -44,8 +45,6 @@ int CTimerManager::_activeTimer = 0;
|
|||
int CTimerManager::_activeDow = 0;
|
||||
int CTimerManager::_nextTimer = 0;
|
||||
int CTimerManager::_nextStart = 0;
|
||||
uint8_t CTimerManager::_workingTemperature = 22;
|
||||
uint8_t CTimerManager::_workingPumpHz = 22;
|
||||
bool CTimerManager::_timerChanged = false;
|
||||
|
||||
#define SET_MAPS() { \
|
||||
|
@ -271,11 +270,8 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
|
|||
// get timer settings
|
||||
int ID = (newID & 0xf) - 1;
|
||||
NVstore.getTimerInfo(ID, timer);
|
||||
if (timer.temperature) {
|
||||
_workingTemperature = timer.temperature;
|
||||
_workingPumpHz = timer.temperature;
|
||||
}
|
||||
DebugPort.printf("Start of timer interval, starting heater @ %dC\r\n", _workingTemperature);
|
||||
CDemandManager::setFromTimer(timer.temperature);
|
||||
DebugPort.printf("Start of timer interval, starting heater @ %dC\r\n", timer.temperature);
|
||||
requestOn();
|
||||
_activeDow = dow; // dow when timer interval start was detected
|
||||
retval = 1;
|
||||
|
@ -285,9 +281,8 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
|
|||
if(!RTC_Store.getFrostOn())
|
||||
requestOff();
|
||||
retval = 2;
|
||||
_workingTemperature = RTC_Store.getDesiredTemp();
|
||||
_workingPumpHz = RTC_Store.getDesiredPump();
|
||||
DebugPort.printf("End of timer interval, stopping heater & %dC\r\n", _workingTemperature);
|
||||
CDemandManager::reload();
|
||||
DebugPort.printf("End of timer interval, stopping heater @ %dC\r\n", CDemandManager::getDegC());
|
||||
}
|
||||
_activeTimer = newID;
|
||||
}
|
||||
|
@ -426,49 +421,3 @@ CTimerManager::createOneShotMap(sTimer& timer, uint16_t* pTimerMap, uint16_t* pT
|
|||
return false;
|
||||
}
|
||||
|
||||
// Concept of timer working temperature is that when a timer runs, it installs
|
||||
// the programmed temperature for that timer as the new set point.
|
||||
// When the timer stops, it reverts to the usual user set temperature.
|
||||
//
|
||||
// BUT, if a timer is running, the working temperature is updated with the new demand
|
||||
// and the user temperature is also changed accordingly.
|
||||
// The programmed timer temeprature is not altered and wil lrecur in the future when that time runs.
|
||||
uint8_t
|
||||
CTimerManager::getWorkingTemperature()
|
||||
{
|
||||
return _workingTemperature;
|
||||
}
|
||||
|
||||
void
|
||||
CTimerManager::setWorkingTemperature(uint8_t newDegC)
|
||||
{
|
||||
if(getThermostatModeActive()) {
|
||||
_workingTemperature = newDegC;
|
||||
RTC_Store.setDesiredTemp(newDegC);
|
||||
}
|
||||
else {
|
||||
_workingPumpHz = newDegC;
|
||||
RTC_Store.setDesiredPump(newDegC);
|
||||
}
|
||||
}
|
||||
|
||||
// Concept of timer working pump Hz is that when a timer runs, it installs
|
||||
// the programmed temperature for that timer as the new set point.
|
||||
// That is then converted by the heater into Hz
|
||||
// When the timer stops, it reverts to the usual user set temperature.
|
||||
//
|
||||
// BUT, if a timer is running, the working temperature is updated with the new demand
|
||||
// and the user temperature is also changed accordingly.
|
||||
// The programmed timer temeprature is not altered and wil lrecur in the future when that time runs.
|
||||
uint8_t
|
||||
CTimerManager::getWorkingPumpHz()
|
||||
{
|
||||
return _workingPumpHz;
|
||||
}
|
||||
|
||||
void
|
||||
CTimerManager::setWorkingPumpHz(uint8_t newDemand)
|
||||
{
|
||||
_workingPumpHz = newDemand;
|
||||
RTC_Store.setDesiredPump(newDemand);
|
||||
}
|
|
@ -52,13 +52,7 @@ public:
|
|||
static void getTimer(int idx, sTimer& timerInfo);
|
||||
static int setTimer(sTimer& timerInfo);
|
||||
static bool hasTimerChanged() { return _timerChanged; };
|
||||
static uint8_t getWorkingTemperature();
|
||||
static uint8_t getWorkingPumpHz();
|
||||
static void setWorkingTemperature(uint8_t newDegC);
|
||||
static void setWorkingPumpHz(uint8_t newDemand);
|
||||
private:
|
||||
static uint8_t _workingTemperature;
|
||||
static uint8_t _workingPumpHz;
|
||||
static int _activeTimer;
|
||||
static int _activeDow;
|
||||
static int _prevState;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "HourMeter.h"
|
||||
#include "TempSense.h"
|
||||
#include "BoardDetect.h"
|
||||
#include "DemandManager.h"
|
||||
|
||||
extern CModerator MQTTmoderator;
|
||||
|
||||
|
@ -166,7 +167,7 @@ bool makeJSONString(CModerator& moderator, char* opStr, int len)
|
|||
}
|
||||
}
|
||||
}
|
||||
bSend |= moderator.addJson("TempDesired", getTemperatureDesired(), root);
|
||||
bSend |= moderator.addJson("TempDesired", CDemandManager::getDemand(), root);
|
||||
bSend |= moderator.addJson("TempMode", NVstore.getUserSettings().degF, root);
|
||||
if(NVstore.getUserSettings().menuMode < 2) {
|
||||
bSend |= moderator.addJson("TempMin", getHeaterInfo().getTemperature_Min(), root);
|
||||
|
@ -176,7 +177,7 @@ bool makeJSONString(CModerator& moderator, char* opStr, int len)
|
|||
bSend |= moderator.addJson("RunString", getHeaterInfo().getRunStateStr(), root); // verbose it up!
|
||||
bSend |= moderator.addJson("ErrorState", getHeaterInfo().getErrState(), root );
|
||||
bSend |= moderator.addJson("ErrorString", getHeaterInfo().getErrStateStrEx(), root); // verbose it up!
|
||||
bSend |= moderator.addJson("Thermostat", getThermostatModeActive(), root );
|
||||
bSend |= moderator.addJson("Thermostat", CDemandManager::isThermostat(), root );
|
||||
bSend |= moderator.addJson("PumpFixed", getHeaterInfo().getPump_Fixed(), root );
|
||||
bSend |= moderator.addJson("PumpMin", getHeaterInfo().getPump_Min(), root );
|
||||
bSend |= moderator.addJson("PumpMax", getHeaterInfo().getPump_Max(), root );
|
||||
|
@ -214,7 +215,7 @@ bool makeJSONStringEx(CModerator& moderator, char* opStr, int len)
|
|||
if(stop) stop++; // deliver effective threshold, not internal working value
|
||||
bSend |= moderator.addJson("ThermostatOvertemp", stop, root);
|
||||
bSend |= moderator.addJson("ThermostatUndertemp", NVstore.getUserSettings().cyclic.Start, root);
|
||||
bSend |= moderator.addJson("CyclicTemp", getDemandDegC(), root); // actual pivot point for cyclic mode
|
||||
bSend |= moderator.addJson("CyclicTemp", CDemandManager::getDegC(), root); // actual pivot point for cyclic mode, follows desired temp in thermostat mode
|
||||
bSend |= moderator.addJson("CyclicOff", stop, root); // threshold of over temp for cyclic mode
|
||||
bSend |= moderator.addJson("CyclicOn", NVstore.getUserSettings().cyclic.Start, root); // threshold of under temp for cyclic mode
|
||||
bSend |= moderator.addJson("FrostOn", NVstore.getUserSettings().FrostOn, root); // temp drops below this, auto start - 0 = disable
|
||||
|
@ -306,7 +307,7 @@ bool makeJSONStringGPIO(CModerator& moderator, char* opStr, int len)
|
|||
bSend |= moderator.addJson("GPmodeAnlg", GPIOalgNames[info.algMode], root);
|
||||
}
|
||||
bSend |= moderator.addJson("ExtThermoTmout", (uint32_t)NVstore.getUserSettings().ExtThermoTimeout, root);
|
||||
const char* stop = getExternalThermostatHoldTime();
|
||||
const char* stop = CDemandManager::getExtThermostatHoldTime();
|
||||
if(stop)
|
||||
bSend |= moderator.addJson("ExtThermoStop", stop, root);
|
||||
else
|
||||
|
|
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* This file is part of the "bluetoothheater" distribution
|
||||
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
|
||||
*
|
||||
* Copyright (C) 2020 Ray Jones <ray@mrjones.id.au>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CDemandManager
|
||||
//
|
||||
// This provides management of the heater temperature or pump demands
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "DemandManager.h"
|
||||
#include "NVStorage.h"
|
||||
#include "helpers.h"
|
||||
#include "../RTC/RTCStore.h"
|
||||
#include "../Protocol/Protocol.h"
|
||||
|
||||
// Concept of timer operation:
|
||||
//
|
||||
// The volatile variables _setDegC & _setPumpHz are altered when a timer runs.
|
||||
// The timer installs the programmed timer value as the new set point.
|
||||
// But if the timer value is zero, no change takes place.
|
||||
//
|
||||
// _setPumpHz will match _setDegC.
|
||||
// _setPumpHz is converted into Hz based using the interploation that is
|
||||
// performed inside the heater ECU according to Max/min temp & pump settings.
|
||||
//
|
||||
// When the timer interval expires, the volatile values revert back to the stored
|
||||
// RTC memory values.
|
||||
//
|
||||
// Exception.
|
||||
// If a timer is running and the user alters the setting, according to the current
|
||||
// thermostat state _setDegC or _setPumpHz are updated with the new demand and the
|
||||
// associated RTC memory value is also updated accordingly.
|
||||
// When the timer completes, it continues with the same value.
|
||||
// The programmed timer temperature is not altered by the user adjusting the running
|
||||
// setting and the same setpoint will recur in the future when that timer runs again.
|
||||
|
||||
uint8_t CDemandManager::_setDegC = 22;
|
||||
uint8_t CDemandManager::_setPumpHz = 22;
|
||||
|
||||
|
||||
uint8_t
|
||||
CDemandManager::getDegC()
|
||||
{
|
||||
return _setDegC;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
CDemandManager::getPumpHz()
|
||||
{
|
||||
return _setPumpHz; // value lies in the typical range of 8-35 - interpolated by heater to real Hz
|
||||
}
|
||||
|
||||
|
||||
// set a new temperature setpoint, also saving it to non volatile RTC memory (battery backed RAM)
|
||||
void
|
||||
CDemandManager::setDegC(uint8_t newDegC)
|
||||
{
|
||||
BOUNDSLIMIT(newDegC, NVstore.getHeaterTuning().Tmin, NVstore.getHeaterTuning().Tmax);
|
||||
|
||||
_setDegC = newDegC;
|
||||
RTC_Store.setDesiredTemp(newDegC);
|
||||
}
|
||||
|
||||
// set a new pump setpoint, also saving it to non volatile RTC memory (battery backed RAM)
|
||||
void
|
||||
CDemandManager::setPumpHz(uint8_t newDemand)
|
||||
{
|
||||
// Pump demands use the same range as temperature demands :-)
|
||||
BOUNDSLIMIT(newDemand, NVstore.getHeaterTuning().Tmin, NVstore.getHeaterTuning().Tmax);
|
||||
|
||||
_setPumpHz = newDemand;
|
||||
RTC_Store.setDesiredPump(newDemand);
|
||||
}
|
||||
|
||||
// set a transient setpoint for use by prgrammed timer starts
|
||||
// setpoints only change if timer temperature is actually defined
|
||||
void
|
||||
CDemandManager::setFromTimer(uint8_t timerDemand)
|
||||
{
|
||||
if(timerDemand) {
|
||||
_setPumpHz = timerDemand;
|
||||
_setDegC = timerDemand;
|
||||
}
|
||||
}
|
||||
|
||||
// revert setpoints to stored RTC memory values
|
||||
void
|
||||
CDemandManager::reload()
|
||||
{
|
||||
_setDegC = RTC_Store.getDesiredTemp();
|
||||
_setPumpHz = RTC_Store.getDesiredPump();
|
||||
}
|
||||
|
||||
|
||||
// test the ambient temperature and check if it satisfies a start condition when running
|
||||
// in thermostat mode
|
||||
// If running in Fixed Hz, the start is not denied, but cyclic suspend may be engaged
|
||||
CDemandManager::eStartCode
|
||||
CDemandManager::checkStart()
|
||||
{
|
||||
// create a deny start temperature margin
|
||||
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
|
||||
float deltaT = getTemperatureSensor() - getDegC();
|
||||
|
||||
if(deltaT > stopDeltaT) {
|
||||
// temperature exceeded the allowed margin
|
||||
if(cyclicstop) {
|
||||
// using cyclic mode - suggest immediate cyclic suspend
|
||||
return eStartSuspend;
|
||||
}
|
||||
else {
|
||||
// only deny start if actually using thermostat mode
|
||||
if(isThermostat()) {
|
||||
return eStartTooWarm; // too warm - deny start
|
||||
}
|
||||
}
|
||||
}
|
||||
return eStartOK; // allow start
|
||||
}
|
||||
|
||||
|
||||
// generic method adjust the active heter demand.
|
||||
// thi may be Pump Hz or desired temeperature, dependent upon if thermostat mode is active
|
||||
bool
|
||||
CDemandManager::setDemand(uint8_t newDemand)
|
||||
{
|
||||
if(hasOEMcontroller())
|
||||
return false;
|
||||
|
||||
// bounds operate over the same range for either mode
|
||||
BOUNDSLIMIT(newDemand, NVstore.getHeaterTuning().Tmin, NVstore.getHeaterTuning().Tmax);
|
||||
|
||||
// set and save the demand to NV storage
|
||||
// note that we now maintain fixed Hz and Thermostat set points seperately
|
||||
if(isThermostat()) {
|
||||
setDegC(newDemand);
|
||||
}
|
||||
else {
|
||||
setPumpHz(newDemand);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CDemandManager::deltaDemand(int delta)
|
||||
{
|
||||
if(hasOEMcontroller())
|
||||
return false;
|
||||
|
||||
uint8_t newDemand;
|
||||
if(isThermostat()) {
|
||||
newDemand = getDegC() + delta;
|
||||
setDegC(newDemand);
|
||||
}
|
||||
else {
|
||||
newDemand = getPumpHz() + delta;
|
||||
setPumpHz(newDemand);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CDemandManager::toggleThermostat()
|
||||
{
|
||||
return setThermostatMode(isThermostat() ? 0 : 1);
|
||||
}
|
||||
|
||||
bool
|
||||
CDemandManager::setThermostatMode(uint8_t val, bool save)
|
||||
{
|
||||
if(hasOEMcontroller())
|
||||
return false;
|
||||
|
||||
sUserSettings settings = NVstore.getUserSettings();
|
||||
settings.useThermostat = val ? 0x01 : 0x00;
|
||||
NVstore.setUserSettings(settings);
|
||||
if(save)
|
||||
NVstore.save();
|
||||
return true;
|
||||
}
|
||||
|
||||
// set system to show degF or degC
|
||||
void
|
||||
CDemandManager::setDegFMode(bool state)
|
||||
{
|
||||
sUserSettings settings = NVstore.getUserSettings();
|
||||
settings.degF = state ? 0x01 : 0x00;
|
||||
NVstore.setUserSettings(settings);
|
||||
NVstore.save();
|
||||
}
|
||||
|
||||
// return tru is using a thermostat mode
|
||||
bool
|
||||
CDemandManager::isThermostat()
|
||||
{
|
||||
if(hasOEMcontroller()) {
|
||||
return getHeaterInfo().isThermostat();
|
||||
}
|
||||
else {
|
||||
return NVstore.getUserSettings().useThermostat != 0;
|
||||
}
|
||||
}
|
||||
|
||||
// generic get demand for Pump Hz or degC, as would be used in the value sent to the heater
|
||||
uint8_t
|
||||
CDemandManager::getDemand()
|
||||
{
|
||||
if(hasOEMcontroller()) {
|
||||
return getHeaterInfo().getHeaterDemand();
|
||||
}
|
||||
else {
|
||||
if(isThermostat()) {
|
||||
return getDegC();
|
||||
}
|
||||
else {
|
||||
return getPumpHz(); // timer manager will return pump Hz, as demand value, not real Hz
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return true if external thermostat mode is active
|
||||
bool
|
||||
CDemandManager::isExtThermostatMode()
|
||||
{
|
||||
#if USE_JTAG == 0
|
||||
return GPIOin.usesExternalThermostat() && (NVstore.getUserSettings().ThermostatMethod == 3);
|
||||
#else
|
||||
//CANNOT USE GPIO WITH JTAG DEBUG
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// return true if external thermosat is closed
|
||||
bool
|
||||
CDemandManager::isExtThermostatOn()
|
||||
{
|
||||
#if USE_JTAG == 0
|
||||
return GPIOin.getState(1);
|
||||
#else
|
||||
//CANNOT USE GPIO WITH JTAG DEBUG
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char*
|
||||
CDemandManager::getExtThermostatHoldTime()
|
||||
{
|
||||
#if USE_JTAG == 0
|
||||
return GPIOin.getExtThermHoldTime();
|
||||
#else
|
||||
//CANNOT USE GPIO WITH JTAG DEBUG
|
||||
return "00:00";
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* This file is part of the "bluetoothheater" distribution
|
||||
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
|
||||
*
|
||||
* Copyright (C) 2020 Ray Jones <ray@mrjones.id.au>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CDemandManager
|
||||
//
|
||||
// This provides management of the heater temperature or pump demands
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __DEMANDMANAGER_H__
|
||||
#define __DEMANDMANAGER_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct sTimer;
|
||||
|
||||
class CDemandManager {
|
||||
|
||||
private:
|
||||
static uint8_t _setDegC;
|
||||
static uint8_t _setPumpHz;
|
||||
|
||||
public:
|
||||
enum eStartCode { eStartOK=0,
|
||||
eStartTooWarm=-1,
|
||||
eStartSuspend=-2,
|
||||
eStartLVC=-3,
|
||||
eStartLowFuel=-4
|
||||
};
|
||||
static uint8_t getDegC(); // absolute degC value to use
|
||||
static uint8_t getPumpHz(); // absolute Pump Hz value to use - scaled to fit temp range
|
||||
static uint8_t getDemand(); // can be pump Hz or degC, depending upon thermostat mode
|
||||
static void setDegC(uint8_t newDegC); // set and save absolute degC value to use
|
||||
static void setPumpHz(uint8_t newDemand); // set and save absolute scaled pump Hz value to use
|
||||
static bool setDemand(uint8_t newDemand); // set and save demand, according to thermostat mode
|
||||
static bool deltaDemand(int delta); // nudge demand
|
||||
static void setFromTimer(uint8_t newDemand); // set voltile degC and PumpHz, for timer starts
|
||||
static void reload(); // reload stored RTC values
|
||||
static eStartCode checkStart(); // test if start allowed
|
||||
static bool toggleThermostat();
|
||||
static bool setThermostatMode(uint8_t val, bool save = true);
|
||||
static void setDegFMode(bool state);
|
||||
static bool isThermostat();
|
||||
static bool isExtThermostatMode();
|
||||
static bool isExtThermostatOn();
|
||||
static const char* getExtThermostatHoldTime();
|
||||
};
|
||||
|
||||
#endif //__DEMANDMANAGER_H__
|
|
@ -88,6 +88,12 @@ sHeaterTuning::setPmax(float val)
|
|||
Pmax = cVal;
|
||||
}
|
||||
|
||||
void
|
||||
sHeaterTuning::setFanSensor(int val)
|
||||
{
|
||||
if(INBOUNDS(val, 1, 2))
|
||||
fanSensor = val;
|
||||
}
|
||||
|
||||
void
|
||||
sHeaterTuning::setSysVoltage(float fVal)
|
||||
|
@ -98,6 +104,13 @@ sHeaterTuning::setSysVoltage(float fVal)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
sHeaterTuning::setGlowDrive(uint8_t val) {
|
||||
if(INBOUNDS(val, 1, 6))
|
||||
glowDrive = val;
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
sHeaterTuning::getLVC() const
|
||||
{
|
||||
|
|
|
@ -128,7 +128,11 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
|||
float getPmax() const;
|
||||
void setPmin(float val);
|
||||
void setPmax(float val);
|
||||
void setFmin(int val) { Fmin = val; };
|
||||
void setFmax(int val) { Fmax = val; };
|
||||
void setFanSensor(int val);
|
||||
void setSysVoltage(float val);
|
||||
void setGlowDrive(uint8_t val);
|
||||
float getLVC() const;
|
||||
};
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "BTC_JSON.h"
|
||||
#include "../WiFi/BTCWebServer.h"
|
||||
#include "FuelGauge.h"
|
||||
|
||||
#include "DemandManager.h"
|
||||
|
||||
// a class to track the blue wire receive / transmit states
|
||||
// class CommStates
|
||||
|
@ -107,10 +107,11 @@ void DecodeCmd(const char* cmd, String& payload)
|
|||
{
|
||||
int val;
|
||||
if(strcmp("TempDesired", cmd) == 0) {
|
||||
if( !reqDemand(payload.toInt(), false) ) { // this request is blocked if OEM controller active
|
||||
if( !CDemandManager::setDemand(payload.toInt()) ) { // this request is blocked if OEM controller active
|
||||
resetJSONmoderator("TempDesired");
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if(strcmp("Run", cmd) == 0) {
|
||||
refreshMQTT();
|
||||
if(payload == "1") {
|
||||
|
@ -128,20 +129,47 @@ void DecodeCmd(const char* cmd, String& payload)
|
|||
requestOff();
|
||||
}
|
||||
}
|
||||
*/
|
||||
else if((strcmp("RunState", cmd) == 0) || (strcmp("Run", cmd) == 0)) {
|
||||
refreshMQTT();
|
||||
if(payload.toInt()) {
|
||||
CDemandManager::eStartCode result = requestOn();
|
||||
switch(result) {
|
||||
case CDemandManager::eStartOK: sendJSONtext("{\"StartString\":\"\"}"); break;
|
||||
case CDemandManager::eStartTooWarm: sendJSONtext("{\"StartString\":\"Ambient too warm!\"}"); break;
|
||||
case CDemandManager::eStartSuspend: sendJSONtext("{\"StartString\":\"Immediate Cyclic suspension!\"}"); break;
|
||||
case CDemandManager::eStartLVC: sendJSONtext("{\"StartString\":\"Battery below LVC!\"}"); break;
|
||||
case CDemandManager::eStartLowFuel: sendJSONtext("{\"StartString\":\"Fuel Empty!\"}"); break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
requestOff();
|
||||
}
|
||||
}
|
||||
else if(strcmp("PumpMin", cmd) == 0) {
|
||||
setPumpMin(payload.toFloat());
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
tuning.setPmin(payload.toFloat());
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
}
|
||||
else if(strcmp("PumpMax", cmd) == 0) {
|
||||
setPumpMax(payload.toFloat());
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
tuning.setPmax(payload.toFloat());
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
}
|
||||
else if(strcmp("FanMin", cmd) == 0) {
|
||||
setFanMin(payload.toInt());
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
if(INBOUNDS(payload.toInt(), 500, 5000))
|
||||
tuning.setFmin(payload.toInt());
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
}
|
||||
else if(strcmp("FanMax", cmd) == 0) {
|
||||
setFanMax(payload.toInt());
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
if(INBOUNDS(payload.toInt(), 500, 5000))
|
||||
tuning.setFmax(payload.toInt());
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
}
|
||||
else if(strcmp("CyclicTemp", cmd) == 0) {
|
||||
setDemandDegC(payload.toInt()); // directly set demandDegC
|
||||
CDemandManager::setDegC(payload.toInt()); // directly set demandDegC
|
||||
}
|
||||
else if((strcmp("CyclicOff", cmd) == 0) || (strcmp("ThermostatOvertemp", cmd) == 0)) {
|
||||
sUserSettings us = NVstore.getUserSettings();
|
||||
|
@ -171,7 +199,7 @@ void DecodeCmd(const char* cmd, String& payload)
|
|||
NVstore.setUserSettings(settings);
|
||||
}
|
||||
else if(strcmp("Thermostat", cmd) == 0) {
|
||||
if(!setThermostatMode(payload.toInt())) { // this request is blocked if OEM controller active
|
||||
if(!CDemandManager::setThermostatMode(payload.toInt(), false)) { // this request is blocked if OEM controller active
|
||||
resetJSONmoderator("ThermoStat");
|
||||
}
|
||||
}
|
||||
|
@ -183,7 +211,7 @@ void DecodeCmd(const char* cmd, String& payload)
|
|||
}
|
||||
else if(strcmp("NVsave", cmd) == 0) {
|
||||
if(payload.toInt() == 8861)
|
||||
saveNV();
|
||||
NVstore.save();
|
||||
}
|
||||
else if(strcmp("Watchdog", cmd) == 0) {
|
||||
doJSONwatchdog(payload.toInt());
|
||||
|
@ -214,7 +242,9 @@ void DecodeCmd(const char* cmd, String& payload)
|
|||
refreshMQTT();
|
||||
}
|
||||
else if(strcmp("SystemVoltage", cmd) == 0) {
|
||||
setSystemVoltage(payload.toFloat());
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
tuning.setSysVoltage(payload.toFloat());
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
}
|
||||
else if(strcmp("TimerDays", cmd) == 0) {
|
||||
// value encoded as "ID Days,Days"
|
||||
|
@ -243,7 +273,9 @@ void DecodeCmd(const char* cmd, String& payload)
|
|||
resetJSONTimerModerator(payload.toInt());
|
||||
}
|
||||
else if(strcmp("FanSensor", cmd) == 0) {
|
||||
setFanSensor(payload.toInt());
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
tuning.setFanSensor(payload.toInt());
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
}
|
||||
else if(strcmp("IQuery", cmd) == 0) {
|
||||
resetJSONIPmoderator(); // force IP params to be sent
|
||||
|
|
|
@ -24,40 +24,21 @@
|
|||
#define __BTC_HELPERS_H__
|
||||
|
||||
#include "UtilClasses.h"
|
||||
#include "DemandManager.h"
|
||||
|
||||
class CTempSense;
|
||||
struct sGPIO;
|
||||
|
||||
extern void forceBootInit();
|
||||
|
||||
extern int requestOn(bool checkTemp=true);
|
||||
extern CDemandManager::eStartCode requestOn();
|
||||
extern void requestOff();
|
||||
extern bool reqDemandDelta(int delta);
|
||||
extern bool reqDemand(uint8_t newTemp, bool save=true);
|
||||
extern bool reqThermoToggle();
|
||||
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();
|
||||
extern void setDemandDegC(uint8_t val);
|
||||
extern uint8_t getDemandPump();
|
||||
|
||||
extern float getTemperatureSensor(int source = 0);
|
||||
extern void setPumpMin(float);
|
||||
extern void setPumpMax(float);
|
||||
extern void setFanMin(uint16_t);
|
||||
extern void setFanMax(uint16_t);
|
||||
extern void setFanSensor(uint8_t cVal);
|
||||
extern void setDateTime(const char* newTime);
|
||||
extern void setDate(const char* newTime);
|
||||
extern void setTime(const char* newTime);
|
||||
extern void setGlowDrive(uint8_t val);
|
||||
extern void saveNV();
|
||||
extern void setSystemVoltage(float val);
|
||||
extern void interpretJsonCommand(char* pLine);
|
||||
extern void resetWebModerator();
|
||||
extern void resetFuelGauge();
|
||||
|
@ -81,7 +62,6 @@ extern void checkFOTA();
|
|||
extern void setUploadSize(long val);
|
||||
extern void getGPIOinfo(sGPIO& info);
|
||||
extern void simulateGPIOin(uint8_t newKey);
|
||||
extern void setDegFMode(bool state);
|
||||
extern float getBatteryVoltage(bool fast);
|
||||
extern float getGlowVolts();
|
||||
extern float getGlowCurrent();
|
||||
|
|
|
@ -38,46 +38,29 @@
|
|||
#include "../Protocol/Protocol.h"
|
||||
#include "../Utility/BTC_JSON.h"
|
||||
#include "../Utility/TempSense.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "../Utility/DemandManager.h"
|
||||
#include "freertos/freertos.h"
|
||||
|
||||
extern void DecodeCmd(const char* cmd, String& payload);
|
||||
|
||||
#define USE_RTOS_MQTTTIMER
|
||||
//#define USE_LOCAL_MQTTSTRINGS
|
||||
//#define MQTT_DBG_RAWBYTES
|
||||
|
||||
//IPAddress testMQTTserver(5, 196, 95, 208); // test.mosquito.org
|
||||
//IPAddress testMQTTserver(18, 194, 98, 249); // broker.hivemq.com
|
||||
|
||||
AsyncMqttClient MQTTclient;
|
||||
char topicnameJSONin[128];
|
||||
char topicnameCmd[128];
|
||||
CModerator MQTTmoderator; // for basic MQTT interface
|
||||
CModerator BasicMQTTmoderator; // for basic MQTT interface
|
||||
unsigned long MQTTrestart = 0;
|
||||
char statusTopic[128];
|
||||
TimerHandle_t mqttReconnectTimer = NULL;
|
||||
SemaphoreHandle_t mqttSemaphore = NULL;
|
||||
|
||||
void subscribe(const char* topic);
|
||||
|
||||
|
||||
#ifdef USE_LOCAL_MQTTSTRINGS
|
||||
char mqttHost[128];
|
||||
char mqttUser[32];
|
||||
char mqttPass[32];
|
||||
#endif
|
||||
char statusTopic[128];
|
||||
|
||||
#ifdef USE_RTOS_MQTTTIMER
|
||||
TimerHandle_t mqttReconnectTimer = NULL;
|
||||
QueueHandle_t mqttQueue = NULL;
|
||||
#else
|
||||
unsigned long mqttReconnect = 0;
|
||||
#endif
|
||||
|
||||
void connectToMqtt() {
|
||||
#ifdef USE_RTOS_MQTTTIMER
|
||||
xTimerStop(mqttReconnectTimer, 0);
|
||||
#else
|
||||
mqttReconnect = 0;
|
||||
#endif
|
||||
if(!MQTTclient.connected()) {
|
||||
DebugPort.println("MQTT: Connecting...");
|
||||
if(NVstore.getMQTTinfo().enabled) {
|
||||
|
@ -86,24 +69,16 @@ void connectToMqtt() {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_RTOS_MQTTTIMER
|
||||
// timer callbacks are called from ISRL
|
||||
// this code MUST run from IRAM, and then safest to pass the event down thru a queue to user code
|
||||
// ALL callback code MUST run from IRAM, safest to pass the event down thru a queue to user code
|
||||
void IRAM_ATTR callbackMQTTreconnect() {
|
||||
BaseType_t awoken;
|
||||
int flag = 1;
|
||||
xQueueSendFromISR(mqttQueue, &flag, &awoken);
|
||||
xSemaphoreGiveFromISR(mqttSemaphore, &awoken);
|
||||
}
|
||||
#endif
|
||||
|
||||
void onMqttConnect(bool sessionPresent)
|
||||
{
|
||||
#ifdef USE_RTOS_MQTTTIMER
|
||||
xTimerStop(mqttReconnectTimer, 0);
|
||||
#else
|
||||
mqttReconnect = 0;
|
||||
#endif
|
||||
|
||||
|
||||
DebugPort.println("MQTT: Connected to broker.");
|
||||
// DebugPort.printf("Session present: %d\r\n", sessionPresent);
|
||||
|
@ -137,12 +112,6 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties
|
|||
{
|
||||
// handle message arrived
|
||||
DebugPort.printf("MQTT: onMessage %s ", topic);
|
||||
#ifdef MQTT_DBG_RAWBYTES
|
||||
for(int i=0; i<len; i++) {
|
||||
DebugPort.printf("0x%02X ", payload[i]);
|
||||
}
|
||||
DebugPort.println();
|
||||
#endif
|
||||
// string may not neccesarily be null terminated, make sure it is
|
||||
char szPayload[1024];
|
||||
int maxlen = sizeof(szPayload)-1;
|
||||
|
@ -162,7 +131,7 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties
|
|||
}
|
||||
else if(strcmp(topic, statusTopic) == 0) { // check if incoming topic is our general status
|
||||
if(strcmp(szPayload, "1") == 0) {
|
||||
// MQTTmoderator.reset();
|
||||
// BasicMQTTmoderator.reset();
|
||||
MQTTclient.publish(statusTopic, NVstore.getMQTTinfo().qos, true, "online");
|
||||
}
|
||||
}
|
||||
|
@ -184,11 +153,7 @@ void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
|
|||
|
||||
if (WiFi.isConnected()) {
|
||||
if(NVstore.getMQTTinfo().enabled) {
|
||||
#ifdef USE_RTOS_MQTTTIMER
|
||||
xTimerStart(mqttReconnectTimer, 0);
|
||||
#else
|
||||
mqttReconnect = millis() + 5000;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,16 +166,12 @@ void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
|
|||
|
||||
bool mqttInit()
|
||||
{
|
||||
#ifdef USE_RTOS_MQTTTIMER
|
||||
#ifndef BLOCK_MQTT_RECON
|
||||
if(mqttReconnectTimer==NULL)
|
||||
// mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(20000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
|
||||
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(20000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(callbackMQTTreconnect));
|
||||
if(mqttQueue == NULL)
|
||||
mqttQueue = xQueueCreate(10, 4);
|
||||
#endif
|
||||
#else
|
||||
mqttReconnect = 0;
|
||||
if(mqttSemaphore == NULL) {
|
||||
mqttSemaphore = xSemaphoreCreateBinary();
|
||||
}
|
||||
#endif
|
||||
MQTTrestart = 0;
|
||||
|
||||
|
@ -229,25 +190,13 @@ bool mqttInit()
|
|||
|
||||
const sMQTTparams params = NVstore.getMQTTinfo();
|
||||
if(params.enabled) {
|
||||
#ifdef USE_LOCAL_MQTTSTRINGS
|
||||
strncpy(mqttHost, params.host, 127);
|
||||
strncpy(mqttUser, params.username, 31);
|
||||
strncpy(mqttPass, params.password, 31);
|
||||
mqttHost[127] = 0;
|
||||
mqttUser[31] = 0;
|
||||
mqttPass[31] = 0;
|
||||
DebugPort.printf("MQTT: setting broker to %s:%d\r\n", mqttHost, params.port);
|
||||
DebugPort.printf("MQTT: %s/%s\r\n", mqttUser, mqttPass);
|
||||
MQTTclient.setServer(mqttHost, params.port);
|
||||
MQTTclient.setCredentials(mqttUser, mqttPass);
|
||||
#else
|
||||
// the client only stores a pointer - this must not be a volatile memory location!
|
||||
// - NO STACK vars!!!
|
||||
DebugPort.printf("MQTT: setting broker to %s:%d\r\n", NVstore.getMQTTinfo().host, NVstore.getMQTTinfo().port);
|
||||
MQTTclient.setServer(NVstore.getMQTTinfo().host, NVstore.getMQTTinfo().port);
|
||||
DebugPort.printf("MQTT: %s/%s\r\n", NVstore.getMQTTinfo().username, NVstore.getMQTTinfo().password);
|
||||
MQTTclient.setCredentials(NVstore.getMQTTinfo().username, NVstore.getMQTTinfo().password);
|
||||
#endif
|
||||
|
||||
static bool setCallbacks = false;
|
||||
// callbacks should only be added once (vector of callbacks in client!)
|
||||
if(!setCallbacks) {
|
||||
|
@ -275,18 +224,6 @@ bool mqttPublishJSON(const char* str)
|
|||
return false;
|
||||
}
|
||||
|
||||
/*void kickMQTT() {
|
||||
if (WiFi.isConnected()) {
|
||||
if(NVstore.getMQTTinfo().enabled) {
|
||||
#ifdef USE_RTOS_MQTTTIMER
|
||||
xTimerStart(mqttReconnectTimer, 0);
|
||||
#else
|
||||
mqttReconnect = millis() + 5000;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
void doMQTT()
|
||||
{
|
||||
// manage restart of MQTT
|
||||
|
@ -300,32 +237,17 @@ void doMQTT()
|
|||
|
||||
// most MQTT is managed via callbacks!!!
|
||||
if(NVstore.getMQTTinfo().enabled) {
|
||||
#ifdef USE_RTOS_MQTTTIMER
|
||||
int flag;
|
||||
if(xQueueReceive(mqttQueue, &flag, 0)) {
|
||||
DebugPort.println("MQTT connect request via queue");
|
||||
|
||||
// test if MQTT start timeout has expired
|
||||
if(xSemaphoreTake(mqttSemaphore, 0)) {
|
||||
DebugPort.println("MQTT connect request via semaphore");
|
||||
connectToMqtt();
|
||||
}
|
||||
#else
|
||||
if(mqttReconnect) {
|
||||
long tDelta = millis() - mqttReconnect;
|
||||
if(tDelta > 0) {
|
||||
mqttReconnect = 0;
|
||||
connectToMqtt();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_RTOS_MQTTTIMER
|
||||
#ifndef BLOCK_MQTT_RECON
|
||||
if (!MQTTclient.connected() && WiFi.isConnected() && !xTimerIsTimerActive(mqttReconnectTimer)) {
|
||||
DebugPort.println("Starting MQTT timer");
|
||||
xTimerStart(mqttReconnectTimer, 0);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
if (!MQTTclient.connected() && WiFi.isConnected() && mqttReconnect==0) {
|
||||
mqttReconnect = millis() + 5000;
|
||||
DebugPort.println("Starting MQTT timer");
|
||||
xTimerStart(mqttReconnectTimer, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -341,7 +263,7 @@ bool isMQTTconnected() {
|
|||
void pubTopic(const char* name, int value)
|
||||
{
|
||||
if(MQTTclient.connected()) {
|
||||
if(MQTTmoderator.shouldSend(name, value)) {
|
||||
if(BasicMQTTmoderator.shouldSend(name, value)) {
|
||||
const sMQTTparams params = NVstore.getMQTTinfo();
|
||||
char topic[128];
|
||||
sprintf(topic, "%s/sts/%s", getTopicPrefix(), name);
|
||||
|
@ -355,7 +277,7 @@ void pubTopic(const char* name, int value)
|
|||
void pubTopic(const char* name, float value)
|
||||
{
|
||||
if(MQTTclient.connected()) {
|
||||
if(MQTTmoderator.shouldSend(name, value)) {
|
||||
if(BasicMQTTmoderator.shouldSend(name, value)) {
|
||||
const sMQTTparams params = NVstore.getMQTTinfo();
|
||||
char topic[128];
|
||||
sprintf(topic, "%s/sts/%s", getTopicPrefix(), name);
|
||||
|
@ -369,7 +291,7 @@ void pubTopic(const char* name, float value)
|
|||
void pubTopic(const char* name, const char* payload)
|
||||
{
|
||||
if(MQTTclient.connected()) {
|
||||
if(MQTTmoderator.shouldSend(name, payload)) {
|
||||
if(BasicMQTTmoderator.shouldSend(name, payload)) {
|
||||
const sMQTTparams params = NVstore.getMQTTinfo();
|
||||
char topic[128];
|
||||
sprintf(topic, "%s/sts/%s", getTopicPrefix(), name);
|
||||
|
@ -415,11 +337,11 @@ void updateMQTT()
|
|||
pubTopic("Temp4Current", "n/a");
|
||||
}
|
||||
}
|
||||
pubTopic("TempDesired", getTemperatureDesired());
|
||||
pubTopic("TempDesired", CDemandManager::getDemand());
|
||||
pubTopic("TempBody", getHeaterInfo().getTemperature_HeatExchg());
|
||||
pubTopic("ErrorState", getHeaterInfo().getErrState());
|
||||
pubTopic("ErrorString", getHeaterInfo().getErrStateStrEx()); // verbose it up!
|
||||
pubTopic("Thermostat", getThermostatModeActive());
|
||||
pubTopic("Thermostat", CDemandManager::isThermostat());
|
||||
pubTopic("PumpFixed", getHeaterInfo().getPump_Fixed() );
|
||||
pubTopic("PumpActual", getHeaterInfo().getPump_Actual());
|
||||
pubTopic("FanRPM", getFanSpeed());
|
||||
|
@ -433,7 +355,7 @@ void updateMQTT()
|
|||
|
||||
void refreshMQTT()
|
||||
{
|
||||
MQTTmoderator.reset();
|
||||
BasicMQTTmoderator.reset();
|
||||
}
|
||||
|
||||
void subscribe(const char* topic)
|
||||
|
|
|
@ -29,7 +29,6 @@ bool mqttInit();
|
|||
void doMQTT();
|
||||
bool mqttPublishJSON(const char* str);
|
||||
void connectToMqtt();
|
||||
//void kickMQTT();
|
||||
bool isMQTTconnected();
|
||||
const char* getTopicPrefix();
|
||||
|
||||
|
|
Loading…
Reference in New Issue