Tidied JSON/MQTT topic command decode into UtilClasses.cpp

This commit is contained in:
Ray Jones 2019-09-21 09:58:51 +10:00
parent 6e86571a19
commit de9417ff73
7 changed files with 418 additions and 625 deletions

View file

@ -382,10 +382,10 @@ void setup() {
NVstore.init();
NVstore.load();
initMQTTJSONmoderator(); // prevents JSON for MQTT unless requested
initIPJSONmoderator(); // prevents JSON for IP unless requested
initTimerJSONmoderator(); // prevents JSON for timers unless requested
initSysModerator();
initJSONMQTTmoderator(); // prevents JSON for MQTT unless requested
initJSONIPmoderator(); // prevents JSON for IP unless requested
initJSONTimermoderator(); // prevents JSON for timers unless requested
initJSONSysModerator();
KeyPad.begin(keyLeft_pin, keyRight_pin, keyCentre_pin, keyUp_pin, keyDown_pin);
@ -1653,13 +1653,13 @@ void doStreaming()
Bluetooth.check(); // check for Bluetooth activity
GPIOin.manage();
GPIOout.manage();
GPIOout.manage();
GPIOalg.manage();
// manage changes in Bluetooth connection status
if(Bluetooth.isConnected()) {
if(!bBTconnected) {
resetJSONmoderator(); // force full send upon BT client connect
resetAllJSONmoderators(); // force full send upon BT client connect
}
bBTconnected = true;
}
@ -1668,7 +1668,7 @@ void doStreaming()
}
// manage changes in number of wifi clients
if(isWebSocketClientChange()) {
resetJSONmoderator(); // force full send upon number of Wifi clients change
resetAllJSONmoderators(); // force full send upon increase of Wifi clients
}
DebugPort.handle(); // keep telnet spy alive
@ -1725,12 +1725,12 @@ float getGlowCurrent()
#endif
}
float getFanSpeed()
int getFanSpeed()
{
#ifdef RAW_SAMPLES
return getHeaterInfo().getFan_Actual();
#else
return FilteredSamples.Fan.getValue();
return (int)FilteredSamples.Fan.getValue();
#endif
}

View file

@ -50,7 +50,6 @@ CModerator SysModerator;
bool bTriggerSysParams = false;
bool bTriggerDateTime = false;
void validateTimer(int ID);
void Expand(std::string& str);
bool makeJSONString(CModerator& moderator, char* opStr, int len);
bool makeJSONStringEx(CModerator& moderator, char* opStr, int len);
@ -61,6 +60,43 @@ bool makeJSONStringMQTT(CModerator& moderator, char* opStr, int len);
bool makeJSONStringIP(CModerator& moderator, char* opStr, int len);
void DecodeCmd(const char* cmd, String& payload);
void triggerJSONTimeUpdate()
{
bTriggerDateTime = true;
}
void resetJSONTimerModerator(int timerID)
{
if(timerID)
TimerModerator.reset(timerID-1);
else
TimerModerator.reset();
}
void resetJSONIPmoderator()
{
IPmoderator.reset(); // force IP params to be sent
}
void resetJSONmoderator(const char* name)
{
if(name)
JSONmoderator.reset(name);
else
JSONmoderator.reset();
}
void resetJSONSysModerator()
{
SysModerator.reset(); // force MQTT params to be sent
bTriggerSysParams = true;
}
void resetJSONMQTTmoderator()
{
MQTTJSONmoderator.reset(); // force MQTT params to be sent
}
void interpretJsonCommand(char* pLine)
{
if(strlen(pLine) == 0)
@ -81,276 +117,6 @@ void interpretJsonCommand(char* pLine)
String payload(it->value.as<const char*>());
DecodeCmd(it->key, payload);
/*
if(strcmp("TempDesired", it->key) == 0) {
if( !reqDemand(it->value.as<uint8_t>(), false) ) { // this request is blocked if OEM controller active
JSONmoderator.reset("TempDesired");
}
}
else if(strcmp("RunState", it->key) == 0) {
if(it->value.as<uint8_t>()) {
requestOn();
}
else {
requestOff();
}
}
else if(strcmp("PumpMin", it->key) == 0) {
setPumpMin(it->value.as<float>());
}
else if(strcmp("PumpMax", it->key) == 0) {
setPumpMax(it->value.as<float>());
}
else if(strcmp("FanMin", it->key) == 0) {
setFanMin(it->value.as<uint16_t>());
}
else if(strcmp("FanMax", it->key) == 0) {
setFanMax(it->value.as<uint16_t>());
}
else if(strcmp("CyclicTemp", it->key) == 0) {
setDemandDegC(it->value.as<uint8_t>()); // directly set demandDegC
}
else if((strcmp("CyclicOff", it->key) == 0) || (strcmp("ThermostatOvertemp", it->key) == 0)) {
sUserSettings us = NVstore.getUserSettings();
us.cyclic.Stop = it->value.as<int8_t>();
if(INBOUNDS(us.cyclic.Stop, 0, 10)) {
if(us.cyclic.Stop > 1)
us.cyclic.Stop--; // internal uses a 1 offset
NVstore.setUserSettings(us);
}
}
else if((strcmp("CyclicOn", it->key) == 0) || (strcmp("ThermostatUndertemp", it->key) == 0)) {
sUserSettings us = NVstore.getUserSettings();
us.cyclic.Start = it->value.as<int8_t>();
if(INBOUNDS(us.cyclic.Start, -20, 0))
NVstore.setUserSettings(us);
}
else if(strcmp("ThermostatMethod", it->key) == 0) {
sUserSettings settings = NVstore.getUserSettings();
settings.ThermostatMethod = it->value.as<uint8_t>();
if(INBOUNDS(settings.ThermostatMethod, 0, 3))
NVstore.setUserSettings(settings);
}
else if(strcmp("ThermostatWindow", it->key) == 0) {
sUserSettings settings = NVstore.getUserSettings();
settings.ThermostatWindow = it->value.as<float>();
if(INBOUNDS(settings.ThermostatWindow, 0.2f, 10.f))
NVstore.setUserSettings(settings);
}
else if(strcmp("Thermostat", it->key) == 0) {
if(!setThermostatMode(it->value.as<uint8_t>())) { // this request is blocked if OEM controller active
JSONmoderator.reset("ThermoStat");
}
}
else if(strcmp("ExtThermoTmout", it->key) == 0) {
sUserSettings us = NVstore.getUserSettings();
us.ExtThermoTimeout = it->value.as<long>();
if(INBOUNDS(us.ExtThermoTimeout, 0, 3600000))
NVstore.setUserSettings(us);
}
else if(strcmp("NVsave", it->key) == 0) {
if(it->value.as<int>() == 8861)
saveNV();
}
else if(strcmp("Watchdog", it->key) == 0) {
doJSONwatchdog(it->value.as<int>());
}
else if(strcmp("DateTime", it->key) == 0) {
setDateTime(it->value.as<const char*>());
bTriggerDateTime = true;
}
else if(strcmp("Date", it->key) == 0) {
setDate(it->value.as<const char*>());
bTriggerDateTime = true;
}
else if(strcmp("Time", it->key) == 0) {
setTime(it->value.as<const char*>());
bTriggerDateTime = true;
}
else if(strcmp("Time12hr", it->key) == 0) {
sUserSettings us = NVstore.getUserSettings();
us.clock12hr = it->value.as<uint8_t>() ? 1 : 0;
NVstore.setUserSettings(us);
NVstore.save();
}
else if(strcmp("PumpPrime", it->key) == 0) {
reqPumpPrime(it->value.as<uint8_t>());
}
else if(strcmp("Refresh", it->key) == 0) {
resetJSONmoderator();
refreshMQTT();
}
else if(strcmp("SystemVoltage", it->key) == 0) {
setSystemVoltage(it->value.as<float>());
}
else if(strcmp("TimerDays", it->key) == 0) {
// value encoded as "ID Days,Days"
decodeJSONTimerDays(it->value.as<const char*>());
}
else if(strcmp("TimerStart", it->key) == 0) {
// value encoded as "ID HH:MM"
decodeJSONTimerTime(0, it->value.as<const char*>());
}
else if(strcmp("TimerStop", it->key) == 0) {
// value encoded as "ID HH:MM"
decodeJSONTimerTime(1, it->value.as<const char*>());
}
else if(strcmp("TimerRepeat", it->key) == 0) {
// value encoded as "ID val"
decodeJSONTimerNumeric(0, it->value.as<const char*>());
}
else if(strcmp("TimerTemp", it->key) == 0) {
decodeJSONTimerNumeric(1, it->value.as<const char*>());
}
else if(strcmp("TimerConflict", it->key) == 0) {
validateTimer(it->value.as<int>());
}
// request specific timer refresh
else if((strcmp("TQuery", it->key) == 0) || (strcmp("TimerRefresh", it->key) == 0) ) {
int timerID = it->value.as<int>();
if(timerID)
TimerModerator.reset(timerID-1);
else
TimerModerator.reset();
}
else if(strcmp("FanSensor", it->key) == 0) {
setFanSensor(it->value.as<uint8_t>());
}
else if(strcmp("IQuery", it->key) == 0) {
IPmoderator.reset(); // force IP params to be sent
}
// system info
else if(strcmp("SQuery", it->key) == 0) {
SysModerator.reset(); // force MQTT params to be sent
bTriggerSysParams = true;
}
// MQTT parameters
else if(strcmp("MQuery", it->key) == 0) {
MQTTJSONmoderator.reset(); // force MQTT params to be sent
}
else if(strcmp("MEn", it->key) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
info.enabled = it->value.as<uint8_t>();
NVstore.setMQTTinfo(info);
}
else if(strcmp("MPort", it->key) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
info.port = it->value.as<uint16_t>();
NVstore.setMQTTinfo(info);
}
else if(strcmp("MHost", it->key) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.host, it->value.as<const char*>(), 127);
info.host[127] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("MUser", it->key) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.username, it->value.as<const char*>(), 31);
info.username[31] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("MPasswd", it->key) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.password, it->value.as<const char*>(), 31);
info.password[31] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("MQoS", it->key) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
info.qos = it->value.as<uint8_t>();
if(INBOUNDS(info.qos, 0, 2)) {
NVstore.setMQTTinfo(info);
}
}
else if(strcmp("MTopic", it->key) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.topic, it->value.as<const char*>(), 31);
info.topic[31] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("UploadSize", it->key) == 0) {
setUploadSize(it->value.as<long>());
}
else if(strcmp("GPout1", it->key) == 0) {
setGPIOout(0, it->value.as<uint8_t>() ? true : false);
}
else if(strcmp("GPout2", it->key) == 0) {
setGPIOout(1, it->value.as<uint8_t>() ? true : false);
}
else if(strcmp("GPin1", it->key) == 0) {
simulateGPIOin(it->value.as<uint8_t>() ? 0x01 : 0x00); // simulate key 1 press
}
else if(strcmp("GPin2", it->key) == 0) {
simulateGPIOin(it->value.as<uint8_t>() ? 0x02 : 0x00); // simulate key 2 press
}
else if(strcmp("JSONpack", it->key) == 0) {
sUserSettings us = NVstore.getUserSettings();
uint8_t packed = it->value.as<uint8_t>() ? 0x00 : 0x01;
us.JSON.LF = packed;
us.JSON.padding = packed;
us.JSON.singleElement = packed;
NVstore.setUserSettings(us);
NVstore.save();
resetJSONmoderator();
}
else if(strcmp("TempMode", it->key) == 0) {
sUserSettings us = NVstore.getUserSettings();
us.degF = it->value.as<uint8_t>() ? 0x01 : 0x00;
NVstore.setUserSettings(us);
NVstore.save();
}
else if(strcmp("PumpCount", it->key) == 0) { // reset fuel gauge
int Count = it->value.as<int>();
if(Count == 0) {
resetFuelGauge();
}
}
else if(strcmp("PumpCal", it->key) == 0) {
sHeaterTuning ht = NVstore.getHeaterTuning();
ht.pumpCal = it->value.as<float>();
if(INBOUNDS(ht.pumpCal, 0.001, 1)) {
NVstore.setHeaterTuning(ht);
}
}
else if(strcmp("TempOffset", it->key) == 0) {
sHeaterTuning ht = NVstore.getHeaterTuning();
ht.tempOfs = it->value.as<float>();
if(INBOUNDS(ht.tempOfs, -10.0, +10.0)) {
NVstore.setHeaterTuning(ht);
}
}
else if(strcmp("LowVoltCutout", it->key) == 0) {
float fCal = it->value.as<float>();
bool bOK = false;
if(NVstore.getHeaterTuning().sysVoltage == 120)
bOK |= (fCal == 0) || INBOUNDS(fCal, 10.0, 12.5);
else
bOK |= (fCal == 0) || INBOUNDS(fCal, 20.0, 25.0);
if(bOK) {
sHeaterTuning ht = NVstore.getHeaterTuning();
ht.lowVolts = uint8_t(fCal * 10);
NVstore.setHeaterTuning(ht);
}
}*/
else if(strcmp("SMenu", it->key) == 0) {
sUserSettings us = NVstore.getUserSettings();
us.menuMode = it->value.as<uint8_t>();
if(us.menuMode <=2) {
NVstore.setUserSettings(us);
NVstore.save();
switch(us.menuMode) {
case 0: DebugPort.println("Invoking Full menu control mode"); break;
case 1: DebugPort.println("Invoking Basic menu mode"); break;
case 2: DebugPort.println("Invoking cut back No Heater mode"); break;
}
reloadScreens();
}
}
else if(strcmp("SysHourMeters", it->key) == 0) {
pHourMeter->resetHard();
}
}
}
@ -701,39 +467,39 @@ void updateJSONclients(bool report)
}
void resetJSONmoderator()
void resetAllJSONmoderators()
{
JSONmoderator.reset();
#ifdef SALWAYS_SEND_TIMERS
TimerModerator.reset();
#else
initTimerJSONmoderator();
initJSONTimermoderator();
#endif
initMQTTJSONmoderator();
initIPJSONmoderator();
initSysModerator();
initJSONMQTTmoderator();
initJSONIPmoderator();
initJSONSysModerator();
GPIOmoderator.reset();
}
void initMQTTJSONmoderator()
void initJSONMQTTmoderator()
{
char jsonStr[800];
makeJSONStringMQTT(MQTTJSONmoderator, jsonStr, sizeof(jsonStr));
}
void initIPJSONmoderator()
void initJSONIPmoderator()
{
char jsonStr[800];
makeJSONStringIP(IPmoderator, jsonStr, sizeof(jsonStr));
}
void initSysModerator()
void initJSONSysModerator()
{
char jsonStr[800];
makeJSONStringSysInfo(SysModerator, jsonStr, sizeof(jsonStr));
}
void initTimerJSONmoderator()
void initJSONTimermoderator()
{
char jsonStr[800];
for(int tmr=0; tmr<14; tmr++)
@ -766,266 +532,3 @@ void Expand(std::string& str)
}
}
void DecodeCmd(const char* cmd, String& payload)
{
if(strcmp("TempDesired", cmd) == 0) {
if( !reqDemand(payload.toInt(), false) ) { // this request is blocked if OEM controller active
JSONmoderator.reset("TempDesired");
}
}
else if(strcmp("Run", cmd) == 0) {
refreshMQTT();
if(payload == "1") {
requestOn();
}
else if(payload == "0") {
requestOff();
}
}
else if(strcmp("RunState", cmd) == 0) {
if(payload.toInt()) {
requestOn();
}
else {
requestOff();
}
}
else if(strcmp("PumpMin", cmd) == 0) {
setPumpMin(payload.toFloat());
}
else if(strcmp("PumpMax", cmd) == 0) {
setPumpMax(payload.toFloat());
}
else if(strcmp("FanMin", cmd) == 0) {
setFanMin(payload.toInt());
}
else if(strcmp("FanMax", cmd) == 0) {
setFanMax(payload.toInt());
}
else if(strcmp("CyclicTemp", cmd) == 0) {
setDemandDegC(payload.toInt()); // directly set demandDegC
}
else if((strcmp("CyclicOff", cmd) == 0) || (strcmp("ThermostatOvertemp", cmd) == 0)) {
sUserSettings us = NVstore.getUserSettings();
us.cyclic.Stop = payload.toInt();
if(INBOUNDS(us.cyclic.Stop, 0, 10)) {
if(us.cyclic.Stop > 1)
us.cyclic.Stop--; // internal uses a 1 offset
NVstore.setUserSettings(us);
}
}
else if((strcmp("CyclicOn", cmd) == 0) || (strcmp("ThermostatUndertemp", cmd) == 0)) {
sUserSettings us = NVstore.getUserSettings();
us.cyclic.Start = payload.toInt();
if(INBOUNDS(us.cyclic.Start, -20, 0))
NVstore.setUserSettings(us);
}
else if(strcmp("ThermostatMethod", cmd) == 0) {
sUserSettings settings = NVstore.getUserSettings();
settings.ThermostatMethod = payload.toInt();
if(INBOUNDS(settings.ThermostatMethod, 0, 3))
NVstore.setUserSettings(settings);
}
else if(strcmp("ThermostatWindow", cmd) == 0) {
sUserSettings settings = NVstore.getUserSettings();
settings.ThermostatWindow = payload.toFloat();
if(INBOUNDS(settings.ThermostatWindow, 0.2f, 10.f))
NVstore.setUserSettings(settings);
}
else if(strcmp("Thermostat", cmd) == 0) {
if(!setThermostatMode(payload.toInt())) { // this request is blocked if OEM controller active
JSONmoderator.reset("ThermoStat");
}
}
else if(strcmp("ExtThermoTmout", cmd) == 0) {
sUserSettings us = NVstore.getUserSettings();
us.ExtThermoTimeout = payload.toInt();
if(INBOUNDS(us.ExtThermoTimeout, 0, 3600000))
NVstore.setUserSettings(us);
}
else if(strcmp("NVsave", cmd) == 0) {
if(payload.toInt() == 8861)
saveNV();
}
else if(strcmp("Watchdog", cmd) == 0) {
doJSONwatchdog(payload.toInt());
}
else if(strcmp("DateTime", cmd) == 0) {
setDateTime(payload.c_str());
bTriggerDateTime = true;
}
else if(strcmp("Date", cmd) == 0) {
setDate(payload.c_str());
bTriggerDateTime = true;
}
else if(strcmp("Time", cmd) == 0) {
setTime(payload.c_str());
bTriggerDateTime = true;
}
else if(strcmp("Time12hr", cmd) == 0) {
sUserSettings us = NVstore.getUserSettings();
us.clock12hr = payload.toInt() ? 1 : 0;
NVstore.setUserSettings(us);
NVstore.save();
}
else if(strcmp("PumpPrime", cmd) == 0) {
reqPumpPrime(payload.toInt());
}
else if(strcmp("Refresh", cmd) == 0) {
resetJSONmoderator();
refreshMQTT();
}
else if(strcmp("SystemVoltage", cmd) == 0) {
setSystemVoltage(payload.toFloat());
}
else if(strcmp("TimerDays", cmd) == 0) {
// value encoded as "ID Days,Days"
decodeJSONTimerDays(payload.c_str());
}
else if(strcmp("TimerStart", cmd) == 0) {
// value encoded as "ID HH:MM"
decodeJSONTimerTime(0, payload.c_str());
}
else if(strcmp("TimerStop", cmd) == 0) {
// value encoded as "ID HH:MM"
decodeJSONTimerTime(1, payload.c_str());
}
else if(strcmp("TimerRepeat", cmd) == 0) {
// value encoded as "ID val"
decodeJSONTimerNumeric(0, payload.c_str());
}
else if(strcmp("TimerTemp", cmd) == 0) {
decodeJSONTimerNumeric(1, payload.c_str());
}
else if(strcmp("TimerConflict", cmd) == 0) {
validateTimer(payload.toInt());
}
// request specific timer refresh
else if((strcmp("TQuery", cmd) == 0) || (strcmp("TimerRefresh", cmd) == 0) ) {
int timerID = payload.toInt();
if(timerID)
TimerModerator.reset(timerID-1);
else
TimerModerator.reset();
}
else if(strcmp("FanSensor", cmd) == 0) {
setFanSensor(payload.toInt());
}
else if(strcmp("IQuery", cmd) == 0) {
IPmoderator.reset(); // force IP params to be sent
}
// system info
else if(strcmp("SQuery", cmd) == 0) {
SysModerator.reset(); // force MQTT params to be sent
bTriggerSysParams = true;
}
// MQTT parameters
else if(strcmp("MQuery", cmd) == 0) {
MQTTJSONmoderator.reset(); // force MQTT params to be sent
}
else if(strcmp("MEn", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
info.enabled = payload.toInt();
NVstore.setMQTTinfo(info);
}
else if(strcmp("MPort", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
info.port = payload.toInt();
NVstore.setMQTTinfo(info);
}
else if(strcmp("MHost", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.host, payload.c_str(), 127);
info.host[127] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("MUser", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.username, payload.c_str(), 31);
info.username[31] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("MPasswd", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.password, payload.c_str(), 31);
info.password[31] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("MQoS", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
info.qos = payload.toInt();
if(INBOUNDS(info.qos, 0, 2)) {
NVstore.setMQTTinfo(info);
}
}
else if(strcmp("MTopic", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.topic, payload.c_str(), 31);
info.topic[31] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("UploadSize", cmd) == 0) {
setUploadSize(payload.toInt());
}
else if(strcmp("GPout1", cmd) == 0) {
setGPIOout(0, payload.toInt() ? true : false);
}
else if(strcmp("GPout2", cmd) == 0) {
setGPIOout(1, payload.toInt() ? true : false);
}
else if(strcmp("GPin1", cmd) == 0) {
simulateGPIOin(payload.toInt() ? 0x01 : 0x00); // simulate key 1 press
}
else if(strcmp("GPin2", cmd) == 0) {
simulateGPIOin(payload.toInt() ? 0x02 : 0x00); // simulate key 2 press
}
else if(strcmp("JSONpack", cmd) == 0) {
sUserSettings us = NVstore.getUserSettings();
uint8_t packed = payload.toInt() ? 0x00 : 0x01;
us.JSON.LF = packed;
us.JSON.padding = packed;
us.JSON.singleElement = packed;
NVstore.setUserSettings(us);
NVstore.save();
resetJSONmoderator();
}
else if(strcmp("TempMode", cmd) == 0) {
sUserSettings us = NVstore.getUserSettings();
us.degF = payload.toInt() ? 0x01 : 0x00;
NVstore.setUserSettings(us);
NVstore.save();
}
else if(strcmp("PumpCount", cmd) == 0) { // reset fuel gauge
int Count = payload.toInt();
if(Count == 0) {
resetFuelGauge();
}
}
else if(strcmp("PumpCal", cmd) == 0) {
sHeaterTuning ht = NVstore.getHeaterTuning();
ht.pumpCal = payload.toFloat();
if(INBOUNDS(ht.pumpCal, 0.001, 1)) {
NVstore.setHeaterTuning(ht);
}
}
else if(strcmp("TempOffset", cmd) == 0) {
sHeaterTuning ht = NVstore.getHeaterTuning();
ht.tempOfs = payload.toFloat();
if(INBOUNDS(ht.tempOfs, -10.0, +10.0)) {
NVstore.setHeaterTuning(ht);
}
}
else if(strcmp("LowVoltCutout", cmd) == 0) {
float fCal = payload.toFloat();
bool bOK = false;
if(NVstore.getHeaterTuning().sysVoltage == 120)
bOK |= (fCal == 0) || INBOUNDS(fCal, 10.0, 12.5);
else
bOK |= (fCal == 0) || INBOUNDS(fCal, 20.0, 25.0);
if(bOK) {
sHeaterTuning ht = NVstore.getHeaterTuning();
ht.lowVolts = uint8_t(fCal * 10);
NVstore.setHeaterTuning(ht);
}
}
}

View file

@ -28,10 +28,18 @@
extern char defaultJSONstr[64];
void updateJSONclients(bool report);
void initMQTTJSONmoderator();
void initIPJSONmoderator();
void initTimerJSONmoderator();
void initSysModerator();
void initJSONMQTTmoderator();
void initJSONIPmoderator();
void initJSONTimermoderator();
void initJSONSysModerator();
void triggerJSONTimeUpdate();
void resetAllJSONmoderators();
void resetJSONmoderator(const char* name);
void resetJSONTimerModerator(int timerID);
void resetJSONIPmoderator();
void resetJSONSysModerator();
void resetJSONMQTTmoderator();
void validateTimer(int ID);
template<class T>
const char* createJSON(const char* name, T value)

View file

@ -22,6 +22,10 @@
#include <Arduino.h>
#include "../Protocol/Protocol.h"
#include "UtilClasses.h"
#include "NVStorage.h"
#include "HourMeter.h"
#include "macros.h"
#include "BTC_JSON.h"
// a class to track the blue wire receive / transmit states
@ -96,3 +100,280 @@ CProfile::elapsed(bool reset/* = false*/)
return retval;
}
void DecodeCmd(const char* cmd, String& payload)
{
if(strcmp("TempDesired", cmd) == 0) {
if( !reqDemand(payload.toInt(), false) ) { // this request is blocked if OEM controller active
resetJSONmoderator("TempDesired");
}
}
else if(strcmp("Run", cmd) == 0) {
refreshMQTT();
if(payload == "1") {
requestOn();
}
else if(payload == "0") {
requestOff();
}
}
else if(strcmp("RunState", cmd) == 0) {
if(payload.toInt()) {
requestOn();
}
else {
requestOff();
}
}
else if(strcmp("PumpMin", cmd) == 0) {
setPumpMin(payload.toFloat());
}
else if(strcmp("PumpMax", cmd) == 0) {
setPumpMax(payload.toFloat());
}
else if(strcmp("FanMin", cmd) == 0) {
setFanMin(payload.toInt());
}
else if(strcmp("FanMax", cmd) == 0) {
setFanMax(payload.toInt());
}
else if(strcmp("CyclicTemp", cmd) == 0) {
setDemandDegC(payload.toInt()); // directly set demandDegC
}
else if((strcmp("CyclicOff", cmd) == 0) || (strcmp("ThermostatOvertemp", cmd) == 0)) {
sUserSettings us = NVstore.getUserSettings();
us.cyclic.Stop = payload.toInt();
if(INBOUNDS(us.cyclic.Stop, 0, 10)) {
if(us.cyclic.Stop > 1)
us.cyclic.Stop--; // internal uses a 1 offset
NVstore.setUserSettings(us);
}
}
else if((strcmp("CyclicOn", cmd) == 0) || (strcmp("ThermostatUndertemp", cmd) == 0)) {
sUserSettings us = NVstore.getUserSettings();
us.cyclic.Start = payload.toInt();
if(INBOUNDS(us.cyclic.Start, -20, 0))
NVstore.setUserSettings(us);
}
else if(strcmp("ThermostatMethod", cmd) == 0) {
sUserSettings settings = NVstore.getUserSettings();
settings.ThermostatMethod = payload.toInt();
if(INBOUNDS(settings.ThermostatMethod, 0, 3))
NVstore.setUserSettings(settings);
}
else if(strcmp("ThermostatWindow", cmd) == 0) {
sUserSettings settings = NVstore.getUserSettings();
settings.ThermostatWindow = payload.toFloat();
if(INBOUNDS(settings.ThermostatWindow, 0.2f, 10.f))
NVstore.setUserSettings(settings);
}
else if(strcmp("Thermostat", cmd) == 0) {
if(!setThermostatMode(payload.toInt())) { // this request is blocked if OEM controller active
resetJSONmoderator("ThermoStat");
}
}
else if(strcmp("ExtThermoTmout", cmd) == 0) {
sUserSettings us = NVstore.getUserSettings();
us.ExtThermoTimeout = payload.toInt();
if(INBOUNDS(us.ExtThermoTimeout, 0, 3600000))
NVstore.setUserSettings(us);
}
else if(strcmp("NVsave", cmd) == 0) {
if(payload.toInt() == 8861)
saveNV();
}
else if(strcmp("Watchdog", cmd) == 0) {
doJSONwatchdog(payload.toInt());
}
else if(strcmp("DateTime", cmd) == 0) {
setDateTime(payload.c_str());
triggerJSONTimeUpdate();
}
else if(strcmp("Date", cmd) == 0) {
setDate(payload.c_str());
triggerJSONTimeUpdate();
}
else if(strcmp("Time", cmd) == 0) {
setTime(payload.c_str());
triggerJSONTimeUpdate();
}
else if(strcmp("Time12hr", cmd) == 0) {
sUserSettings us = NVstore.getUserSettings();
us.clock12hr = payload.toInt() ? 1 : 0;
NVstore.setUserSettings(us);
NVstore.save();
}
else if(strcmp("PumpPrime", cmd) == 0) {
reqPumpPrime(payload.toInt());
}
else if(strcmp("Refresh", cmd) == 0) {
resetAllJSONmoderators();
refreshMQTT();
}
else if(strcmp("SystemVoltage", cmd) == 0) {
setSystemVoltage(payload.toFloat());
}
else if(strcmp("TimerDays", cmd) == 0) {
// value encoded as "ID Days,Days"
decodeJSONTimerDays(payload.c_str());
}
else if(strcmp("TimerStart", cmd) == 0) {
// value encoded as "ID HH:MM"
decodeJSONTimerTime(0, payload.c_str());
}
else if(strcmp("TimerStop", cmd) == 0) {
// value encoded as "ID HH:MM"
decodeJSONTimerTime(1, payload.c_str());
}
else if(strcmp("TimerRepeat", cmd) == 0) {
// value encoded as "ID val"
decodeJSONTimerNumeric(0, payload.c_str());
}
else if(strcmp("TimerTemp", cmd) == 0) {
decodeJSONTimerNumeric(1, payload.c_str());
}
else if(strcmp("TimerConflict", cmd) == 0) {
validateTimer(payload.toInt());
}
// request specific timer refresh
else if((strcmp("TQuery", cmd) == 0) || (strcmp("TimerRefresh", cmd) == 0) ) {
resetJSONTimerModerator(payload.toInt());
}
else if(strcmp("FanSensor", cmd) == 0) {
setFanSensor(payload.toInt());
}
else if(strcmp("IQuery", cmd) == 0) {
resetJSONIPmoderator(); // force IP params to be sent
}
// system info
else if(strcmp("SQuery", cmd) == 0) {
resetJSONSysModerator(); // force system params to be sent
}
// MQTT parameters
else if(strcmp("MQuery", cmd) == 0) {
resetJSONMQTTmoderator(); // force MQTT params to be sent
}
else if(strcmp("MEn", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
info.enabled = payload.toInt();
NVstore.setMQTTinfo(info);
}
else if(strcmp("MPort", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
info.port = payload.toInt();
NVstore.setMQTTinfo(info);
}
else if(strcmp("MHost", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.host, payload.c_str(), 127);
info.host[127] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("MUser", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.username, payload.c_str(), 31);
info.username[31] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("MPasswd", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.password, payload.c_str(), 31);
info.password[31] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("MQoS", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
info.qos = payload.toInt();
if(INBOUNDS(info.qos, 0, 2)) {
NVstore.setMQTTinfo(info);
}
}
else if(strcmp("MTopic", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.topic, payload.c_str(), 31);
info.topic[31] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("UploadSize", cmd) == 0) {
setUploadSize(payload.toInt());
}
else if(strcmp("GPout1", cmd) == 0) {
setGPIOout(0, payload.toInt() ? true : false);
}
else if(strcmp("GPout2", cmd) == 0) {
setGPIOout(1, payload.toInt() ? true : false);
}
else if(strcmp("GPin1", cmd) == 0) {
simulateGPIOin(payload.toInt() ? 0x01 : 0x00); // simulate key 1 press
}
else if(strcmp("GPin2", cmd) == 0) {
simulateGPIOin(payload.toInt() ? 0x02 : 0x00); // simulate key 2 press
}
else if(strcmp("JSONpack", cmd) == 0) {
sUserSettings us = NVstore.getUserSettings();
uint8_t packed = payload.toInt() ? 0x00 : 0x01;
us.JSON.LF = packed;
us.JSON.padding = packed;
us.JSON.singleElement = packed;
NVstore.setUserSettings(us);
NVstore.save();
resetAllJSONmoderators();
}
else if(strcmp("TempMode", cmd) == 0) {
sUserSettings us = NVstore.getUserSettings();
us.degF = payload.toInt() ? 0x01 : 0x00;
NVstore.setUserSettings(us);
NVstore.save();
}
else if(strcmp("PumpCount", cmd) == 0) { // reset fuel gauge
int Count = payload.toInt();
if(Count == 0) {
resetFuelGauge();
}
}
else if(strcmp("PumpCal", cmd) == 0) {
sHeaterTuning ht = NVstore.getHeaterTuning();
ht.pumpCal = payload.toFloat();
if(INBOUNDS(ht.pumpCal, 0.001, 1)) {
NVstore.setHeaterTuning(ht);
}
}
else if(strcmp("TempOffset", cmd) == 0) {
sHeaterTuning ht = NVstore.getHeaterTuning();
ht.tempOfs = payload.toFloat();
if(INBOUNDS(ht.tempOfs, -10.0, +10.0)) {
NVstore.setHeaterTuning(ht);
}
}
else if(strcmp("LowVoltCutout", cmd) == 0) {
float fCal = payload.toFloat();
bool bOK = false;
if(NVstore.getHeaterTuning().sysVoltage == 120)
bOK |= (fCal == 0) || INBOUNDS(fCal, 10.0, 12.5);
else
bOK |= (fCal == 0) || INBOUNDS(fCal, 20.0, 25.0);
if(bOK) {
sHeaterTuning ht = NVstore.getHeaterTuning();
ht.lowVolts = uint8_t(fCal * 10);
NVstore.setHeaterTuning(ht);
}
}
else if(strcmp("SMenu", cmd) == 0) {
sUserSettings us = NVstore.getUserSettings();
us.menuMode = payload.toInt();
if(us.menuMode <=2) {
NVstore.setUserSettings(us);
NVstore.save();
switch(us.menuMode) {
case 0: DebugPort.println("Invoking Full menu control mode"); break;
case 1: DebugPort.println("Invoking Basic menu mode"); break;
case 2: DebugPort.println("Invoking cut back No Heater mode"); break;
}
reloadScreens();
}
}
else if(strcmp("SysHourMeters", cmd) == 0) {
pHourMeter->resetHard();
}
}

View file

@ -59,7 +59,6 @@ extern void saveNV();
extern void setSystemVoltage(float val);
extern void interpretJsonCommand(char* pLine);
extern void resetWebModerator();
extern void resetJSONmoderator();
extern void resetFuelGauge();
extern const char* getBlueWireStatStr();
extern bool hasOEMcontroller();
@ -85,7 +84,7 @@ extern void setDegFMode(bool state);
extern float getBatteryVoltage(bool fast);
extern float getGlowVolts();
extern float getGlowCurrent();
extern float getFanSpeed();
extern int getFanSpeed();
extern int sysUptime();
extern void doJSONwatchdog(int topup);
extern void reloadScreens();

View file

@ -33,6 +33,7 @@
#include "../Utility/NVStorage.h"
#include "../Utility/Moderator.h"
#include "../Protocol/Protocol.h"
#include "../Utility/BTC_JSON.h"
extern void DecodeCmd(const char* cmd, String& payload);
@ -109,7 +110,7 @@ void onMqttConnect(bool sessionPresent)
MQTTclient.subscribe(lcltopic, NVstore.getMQTTinfo().qos);
#endif
resetJSONmoderator();
resetAllJSONmoderators();
}
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total)
@ -292,7 +293,7 @@ bool isMQTTconnected() {
}
void checkTopic(const char* name, int value)
void pubTopic(const char* name, int value)
{
if(MQTTclient.connected()) {
if(MQTTmoderator.shouldSend(name, value)) {
@ -306,7 +307,7 @@ void checkTopic(const char* name, int value)
}
}
void checkTopic(const char* name, float value)
void pubTopic(const char* name, float value)
{
if(MQTTclient.connected()) {
if(MQTTmoderator.shouldSend(name, value)) {
@ -320,7 +321,7 @@ void checkTopic(const char* name, float value)
}
}
void checkTopic(const char* name, const char* payload)
void pubTopic(const char* name, const char* payload)
{
if(MQTTclient.connected()) {
if(MQTTmoderator.shouldSend(name, payload)) {
@ -334,28 +335,26 @@ void checkTopic(const char* name, const char* payload)
void updateMQTT()
{
checkTopic("RunState", getHeaterInfo().getRunStateEx());
// checkTopic("Run", getHeaterInfo().getRunStateEx() ? "{\"RunState\":1}" : "{\"RunState\":0}");
// checkTopic("RunSts", getHeaterInfo().getRunStateEx() ? "1" : "0");
checkTopic("Run", getHeaterInfo().getRunStateEx() ? "1" : "0");
checkTopic("RunString", getHeaterInfo().getRunStateStr());
pubTopic("RunState", getHeaterInfo().getRunStateEx());
pubTopic("Run", getHeaterInfo().getRunStateEx() ? "1" : "0");
pubTopic("RunString", getHeaterInfo().getRunStateStr());
float tidyTemp = getTemperatureSensor();
tidyTemp = int(tidyTemp * 10 + 0.5) * 0.1f; // round to 0.1 resolution
checkTopic("TempCurrent", tidyTemp);
checkTopic("TempDesired", getTemperatureDesired());
checkTopic("TempBody", getHeaterInfo().getTemperature_HeatExchg());
checkTopic("ErrorState", getHeaterInfo().getErrState());
checkTopic("ErrorString", getHeaterInfo().getErrStateStrEx()); // verbose it up!
checkTopic("Thermostat", getThermostatModeActive());
checkTopic("PumpFixed", getHeaterInfo().getPump_Fixed() );
checkTopic("PumpActual", getHeaterInfo().getPump_Actual());
checkTopic("FanRPM", getFanSpeed());
checkTopic("InputVoltage", getBatteryVoltage(false));
checkTopic("GlowVoltage", getGlowVolts());
checkTopic("GlowCurrent", getGlowCurrent());
pubTopic("TempCurrent", tidyTemp);
pubTopic("TempDesired", getTemperatureDesired());
pubTopic("TempBody", getHeaterInfo().getTemperature_HeatExchg());
pubTopic("ErrorState", getHeaterInfo().getErrState());
pubTopic("ErrorString", getHeaterInfo().getErrStateStrEx()); // verbose it up!
pubTopic("Thermostat", getThermostatModeActive());
pubTopic("PumpFixed", getHeaterInfo().getPump_Fixed() );
pubTopic("PumpActual", getHeaterInfo().getPump_Actual());
pubTopic("FanRPM", getFanSpeed());
pubTopic("InputVoltage", getBatteryVoltage(false));
pubTopic("GlowVoltage", getGlowVolts());
pubTopic("GlowCurrent", getGlowCurrent());
sGPIO info;
getGPIOinfo(info);
checkTopic("GPanlg", info.algVal * 100 / 4096);
pubTopic("GPanlg", info.algVal * 100 / 4096);
}
void refreshMQTT()

View file

@ -86,12 +86,12 @@ void build500Response(String& content, String file);
void initWebServer(void) {
if (MDNS.begin("Afterburner")) {
DebugPort.println("MDNS responder started");
}
server.on("/wmconfig", onWMConfig);
server.on("/resetwifi", onResetWifi);
if (MDNS.begin("Afterburner")) {
DebugPort.println("MDNS responder started");
}
server.on("/wmconfig", onWMConfig);
server.on("/resetwifi", onResetWifi);
server.on("/erase", HTTP_POST, onErase); // erase file from SPIFFS
// Magical code originally shamelessly lifted from Arduino WebUpdate example, then greatly modified
@ -115,7 +115,7 @@ void initWebServer(void) {
DebugPort.println("WEB: GET /formatnow - ILLEGAL - root redirect");
rootRedirect();
});
server.on("/formatnow", HTTP_POST, onFormatNow); // access via POST is legal, but only if bFormatAccess == true
server.on("/formatnow", HTTP_POST, onFormatNow); // access via POST is legal, but only if bFormatAccess == true
server.on("/reboot", HTTP_GET, onReboot); // access via POST is legal, but only if bFormatAccess == true
server.on("/reboot", HTTP_POST, onDoReboot); // access via POST is legal, but only if bFormatAccess == true
@ -130,12 +130,12 @@ void initWebServer(void) {
}
});
server.begin();
server.begin();
webSocket.begin();
webSocket.onEvent(webSocketEvent);
webSocket.begin();
webSocket.onEvent(webSocketEvent);
DebugPort.println("HTTP server started");
DebugPort.println("HTTP server started");
}
@ -438,8 +438,8 @@ function onformatClick() {
void onWMConfig()
{
DebugPort.println("WEB: GET /wmconfig");
server.send(200, "text/plain", "Start Config Portal - Retaining credential");
DebugPort.println("Starting web portal for wifi config");
server.send(200, "text/plain", "Start Config Portal - Retaining credential");
DebugPort.println("Starting web portal for wifi config");
delay(500);
wifiEnterConfigPortal(true, false, 3000);
}
@ -447,8 +447,8 @@ void onWMConfig()
void onResetWifi()
{
DebugPort.println("WEB: GET /resetwifi");
server.send(200, "text/plain", "Start Config Portal - Resetting Wifi credentials!");
DebugPort.println("diconnecting client and wifi, then rebooting");
server.send(200, "text/plain", "Start Config Portal - Resetting Wifi credentials!");
DebugPort.println("diconnecting client and wifi, then rebooting");
delay(500);
wifiEnterConfigPortal(true, true, 3000);
}
@ -462,7 +462,7 @@ void onNotFound()
String message;
build404Response(message, path);
server.send(404, "text/html", message);
server.send(404, "text/html", message);
}
void rootRedirect()
@ -477,7 +477,7 @@ bool sendWebSocketString(const char* Str)
CProfile profile;
#endif
if(webSocket.connectedClients()) {
if(webSocket.connectedClients()) {
#ifdef WEBTIMES
unsigned long tCon = profile.elapsed(true);
@ -491,52 +491,55 @@ bool sendWebSocketString(const char* Str)
DebugPort.printf("Websend times : %ld,%ld\r\n", tCon, tWeb);
#endif
return true;
}
return true;
}
return false;
}
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
if (type == WStype_TEXT) {
bRxWebData = true;
char cmd[256];
memset(cmd, 0, 256);
for (int i = 0; i < length && i < 256; i++) {
cmd[i] = payload[i];
}
interpretJsonCommand(cmd); // send to the main heater controller decode routine
if (type == WStype_TEXT) {
bRxWebData = true;
char cmd[256];
memset(cmd, 0, 256);
for (int i = 0; i < length && i < 256; i++) {
cmd[i] = payload[i];
}
interpretJsonCommand(cmd); // send to the main heater controller decode routine
}
}
bool isWebSocketClientChange()
{
static int prevNumClients = -1;
static int prevNumClients = -1;
int numClients = webSocket.connectedClients();
if(numClients != prevNumClients) {
prevNumClients = numClients;
DebugPort.println("Changed number of web clients, should reset JSON moderator");
return true;
}
int numClients = webSocket.connectedClients();
if(numClients != prevNumClients) {
bool retval = numClients > prevNumClients;
prevNumClients = numClients;
if(retval) {
DebugPort.println("Increased number of web socket clients, should reset JSON moderator");
return true;
}
}
return false;
}
bool hasWebClientSpoken(bool reset)
{
bool retval = bRxWebData;
if(reset)
bRxWebData = false;
return retval;
bool retval = bRxWebData;
if(reset)
bRxWebData = false;
return retval;
}
bool hasWebServerSpoken(bool reset)
{
bool retval = bTxWebData;
if(reset)
bTxWebData = false;
return retval;
bool retval = bTxWebData;
if(reset)
bTxWebData = false;
return retval;
}
void setUploadSize(long val)
@ -911,7 +914,7 @@ void onFormatNow()
DebugPort.println("WEB: POST /formatnow");
String confirm = server.arg("confirm"); // get request argument value by name
if(confirm == "yes" && bFormatAccessed) { // confirm user agrees, and we did pass thru /formatspiffs first
DebugPort.println("Formatting SPIFFS partition");
DebugPort.println("Formatting SPIFFS partition");
SPIFFS.format(); // re-format the SPIFFS partition
bFormatPerformed = true;
}
@ -936,7 +939,7 @@ void onDoReboot()
DebugPort.println("WEB: POST /reboot");
String confirm = server.arg("reboot"); // get request argument value by name
if(confirm == "yes") { // confirm user agrees, and we did pass thru /formatspiffs first
DebugPort.println("Rebooting via /reboot");
DebugPort.println("Rebooting via /reboot");
ESP.restart();
}
}
@ -986,7 +989,7 @@ void onRename()
String oldname = server.arg("oldname"); // get request argument value by name
String newname = server.arg("newname"); // get request argument value by name
if(oldname != "" && newname != "") {
DebugPort.printf("Renaming %s to %s\r\n", oldname.c_str(), newname.c_str());
DebugPort.printf("Renaming %s to %s\r\n", oldname.c_str(), newname.c_str());
SPIFFS.rename(oldname.c_str(), newname.c_str());
checkSplashScreenUpdate();
}