ESP32_ChinaDieselHeater_Con.../Arduino/BTCDieselHeater/src/Utility/NVStorage.h
Ray Jones ce8299609b Split PumpDemand and Temperature demands so Fixed Hz mode works cleanly, especially with Linear Hz thermostat and Cyclic mode.
Cyclic mode, if enabled, is now shown on detailed screen, bracketing its range
Shifted helpers.h into src/Utility - made far more logical sense!

Fancy pants slash screen :-D
2019-06-16 09:09:29 +10:00

362 lines
8.9 KiB
C++

/*
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 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/>.
*
*/
#ifndef __BTC_NV_STORAGE_H__
#define __BTC_NV_STORAGE_H__
#include "GPIO.h"
#include "NVCore.h"
#include "../Utility/helpers.h"
#include "../RTC/Timers.h" // for sTimer
void toggle(bool& ref);
void toggle(uint8_t& ref);
struct sHeaterTuning : public CESP32_NVStorage {
uint8_t Pmin;
uint8_t Pmax;
uint16_t Fmin;
uint16_t Fmax;
uint8_t sysVoltage;
uint8_t fanSensor;
uint8_t glowDrive;
bool valid() {
bool retval = true;
retval &= Pmin < 100;
retval &= Pmax < 150;
retval &= Fmin < 5000;
retval &= Fmax < 6000;
retval &= sysVoltage == 120 || sysVoltage == 240;
retval &= fanSensor == 1 || fanSensor == 2;
retval &= INBOUNDS(glowDrive, 1, 6);
return retval;
};
void init() {
Pmin = 14;
Pmax = 45;
Fmin = 1500;
Fmax = 4500;
sysVoltage = 120;
fanSensor = 1;
glowDrive = 5;
};
void load();
void save();
sHeaterTuning& operator=(const sHeaterTuning& rhs) {
Pmin = rhs.Pmin;
Pmax = rhs.Pmax;
Fmin = rhs.Fmin;
Fmax = rhs.Fmax;
sysVoltage = rhs.sysVoltage;
fanSensor = rhs.fanSensor;
glowDrive = rhs.glowDrive;
return *this;
}
float getPmin() const;
float getPmax() const;
void setPmin(float val);
void setPmax(float val);
void setSysVoltage(float val);
};
struct sHomeMenuActions {
uint8_t onTimeout;
uint8_t onStart;
uint8_t onStop;
bool valid() {
bool retval = true;
retval &= onTimeout < 4;
retval &= onStart < 4;
retval &= onStop < 4;
return retval;
}
void init() {
onTimeout = 0;
onStart = 0;
onStop = 0;
}
sHomeMenuActions& operator=(const sHomeMenuActions& rhs) {
onTimeout = rhs.onTimeout;
onStart = rhs.onStart;
onStop = rhs.onStop;
return *this;
}
};
struct sCyclicThermostat {
int8_t Stop;
int8_t Start;
bool valid() {
bool retval = true;
retval &= INBOUNDS(Start, -10, 0);
retval &= INBOUNDS(Stop, 0, 10);
return retval;
}
void init() {
Start = -1;
Stop = 0;
}
bool isEnabled() const {
return Stop != 0;
}
sCyclicThermostat& operator=(const sCyclicThermostat& rhs) {
Stop = rhs.Stop;
Start = rhs.Start;
return *this;
}
};
struct sJSONoptions {
int8_t singleElement;
int8_t LF;
int8_t padding;
bool valid() {
bool retval = true;
retval &= singleElement <= 1;
retval &= LF <= 1;
retval &= padding <= 1;
return retval;
}
void init() {
singleElement = 0;
LF = 0;
padding = 0;
}
sJSONoptions& operator=(const sJSONoptions& rhs) {
singleElement = rhs.singleElement;
LF = rhs.LF;
padding = rhs.padding;
return *this;
}
};
struct sCredentials : public CESP32_NVStorage {
char SSID[32];
char APpassword[32];
char webUpdateUsername[32];
char webUpdatePassword[32];
void init() {
strcpy(SSID, "Afterburner");
strcpy(APpassword, "thereisnospoon");
strcpy(webUpdateUsername, "Afterburner");
strcpy(webUpdatePassword, "BurnBabyBurn");
};
void load();
void save();
bool valid();
sCredentials& operator=(const sCredentials& rhs) {
strcpy(SSID, rhs.SSID);
strcpy(APpassword, rhs.APpassword);
strcpy(webUpdateUsername, rhs.webUpdateUsername);
strcpy(webUpdatePassword, rhs.webUpdatePassword);
return *this;
}
};
struct sMQTTparams : public CESP32_NVStorage {
uint8_t enabled;
uint16_t port;
char host[128];
char username[32];
char password[32];
void init() {
enabled = false;
port = 1234;
memset(host, 0, 128);
memset(username, 0, 32);
memset(password, 0, 32);
}
sMQTTparams& operator=(const sMQTTparams& rhs) {
enabled = rhs.enabled;
port = rhs.port;
memcpy(host, rhs.host, 128);
memcpy(username, rhs.username, 32);
memcpy(password, rhs.password, 32);
host[127] = 0;
username[31] = 0;
password[31] = 0;
return *this;
}
void load();
void save();
bool valid();
};
struct sUserSettings : public CESP32_NVStorage {
long dimTime;
long menuTimeout;
uint8_t demandDegC;
uint8_t demandPump;
uint8_t degF;
uint8_t ThermostatMethod; // 0: standard heater, 1: Narrow Hysterisis, 2:Managed Hz mode
float ThermostatWindow;
uint8_t useThermostat;
uint8_t enableWifi;
uint8_t enableOTA;
uint16_t FrameRate;
sCyclicThermostat cyclic;
sHomeMenuActions HomeMenu;
sGPIOparams GPIO;
sJSONoptions JSON;
bool valid() {
bool retval = true;
retval &= INBOUNDS(dimTime, -600000, 600000); // +/- 10 mins
retval &= INBOUNDS(menuTimeout, 0, 300000); // 5 mins
retval &= INBOUNDS(demandDegC, 8, 35);
retval &= INBOUNDS(demandPump, 8, 35);
retval &= (degF == 0) || (degF == 1);
retval &= (ThermostatMethod & 0x03) < 3; // only modes 0, 1 or 2
retval &= INBOUNDS(ThermostatWindow, 0.2f, 10.f);
retval &= useThermostat < 2;
retval &= (enableWifi == 0) || (enableWifi == 1);
retval &= (enableOTA == 0) || (enableOTA == 1);
retval &= GPIO.inMode < 4;
retval &= GPIO.outMode < 3;
retval &= INBOUNDS(FrameRate, 300, 1500);
retval &= cyclic.valid();
retval &= HomeMenu.valid();
retval &= JSON.valid();
return retval;
}
void init() {
dimTime = 60000;
menuTimeout = 60000;
demandDegC = 22;
demandPump = 22;
degF = 0;
ThermostatMethod = 0;
ThermostatWindow = 1.0;
useThermostat = 1;
enableWifi = 1;
enableOTA = 1;
GPIO.inMode = GPIOinNone;
GPIO.outMode = GPIOoutNone;
GPIO.algMode = GPIOalgNone;
FrameRate = 1000;
cyclic.init();
HomeMenu.init();
JSON.init();
};
void load();
void save();
sUserSettings& operator=(const sUserSettings& rhs) {
dimTime = rhs.dimTime;
menuTimeout = rhs.menuTimeout;
demandDegC = rhs.demandDegC;
demandPump = rhs.demandPump;
degF = rhs.degF;
ThermostatMethod = rhs.ThermostatMethod;
ThermostatWindow = rhs.ThermostatWindow;
useThermostat = rhs.useThermostat;
enableWifi = rhs.enableWifi;
enableOTA = rhs.enableOTA;
GPIO.inMode = rhs.GPIO.inMode;
GPIO.outMode = rhs.GPIO.outMode;
GPIO.algMode = rhs.GPIO.algMode;
FrameRate = rhs.FrameRate;
cyclic = rhs.cyclic;
HomeMenu = rhs.HomeMenu;
JSON = rhs.JSON;
return *this;
}
};
// the actual data stored to NV memory
struct sNVStore {
sHeaterTuning heaterTuning;
sUserSettings userSettings;
sTimer timer[14];
sMQTTparams MQTT;
sCredentials Credentials;
bool valid();
void init();
sNVStore& operator=(const sNVStore& rhs) {
heaterTuning = rhs.heaterTuning;
userSettings = rhs.userSettings;
for(int i = 0; i < 14; i++)
timer[i] = rhs.timer[i];
MQTT = rhs.MQTT;
Credentials = rhs.Credentials;
return *this;
}
};
class CHeaterStorage /*: public CESP32_NVStorage*/ {
protected:
sNVStore _calValues;
public:
CHeaterStorage();
virtual ~CHeaterStorage() {};
// TODO: These are only here to allow building without fully
// fleshing out NV storage for Due, Mega etc
// these should be removed once complete (pure virtual)
virtual void init() {};
virtual void load() {};
virtual void save() {};
const sCyclicThermostat& getCyclicMode() const;
const sMQTTparams& getMQTTinfo() const;
const sGPIOparams& getGPIOparams() const;
const sHomeMenuActions& getHomeMenu() const;
const sCredentials& getCredentials() const;
const sUserSettings& getUserSettings() const;
const sHeaterTuning& getHeaterTuning() const;
void setCyclicMode(const sCyclicThermostat& val);
void setGPIOparams(const sGPIOparams& params);
void setHomeMenu(const sHomeMenuActions& val);
void getTimerInfo(int idx, sTimer& timerInfo);
void setTimerInfo(int idx, const sTimer& timerInfo);
void setMQTTinfo(const sMQTTparams& info);
void setCredentials(const sCredentials& info);
CHeaterStorage& operator=(const CHeaterStorage& rhs) {
_calValues = rhs._calValues;
}
void setUserSettings(const sUserSettings& info);
void setHeaterTuning(const sHeaterTuning& info);
};
class CESP32HeaterStorage : public CHeaterStorage {
public:
CESP32HeaterStorage();
virtual ~CESP32HeaterStorage();
void init();
void load();
void save();
};
extern CHeaterStorage& NVstore;
#endif // __BTC_NV_STORAGE_H__