diff --git a/Arduino/BTCDieselHeater/BTCWebServer.cpp b/Arduino/BTCDieselHeater/BTCWebServer.cpp index 3e141f2..6102421 100644 --- a/Arduino/BTCDieselHeater/BTCWebServer.cpp +++ b/Arduino/BTCDieselHeater/BTCWebServer.cpp @@ -28,64 +28,17 @@ #include "pins.h" #include "Index.h" #include -#include - +#include "Moderator.h" WebServer server(80); WebSocketsServer webSocket = WebSocketsServer(81); -bool bRxWebData = false; + +bool bRxWebData = false; // flags for OLED animation bool bTxWebData = false; DynamicJsonBuffer jsonBuffer(512); // create a JSON buffer on the heap -class CModerator { - std::map fMemory; - std::map iMemory; -public: - bool check(const char* name, float value); - bool check(const char* name, int value); - void reset(); -}; - -void -CModerator::reset() -{ - // install invalid values, retain maps (memory defrag reasons) - for(auto it = fMemory.begin(); it != fMemory.end(); ++it) it->second = -100; - for(auto it = iMemory.begin(); it != iMemory.end(); ++it) it->second = -100; -} - -bool -CModerator::check(const char* name, float value) -{ - bool retval = true; - auto it = fMemory.find(name); - if(it != fMemory.end()) { - retval = it->second != value; - it->second = value; - } - else { - fMemory[name] = value; - } - return retval; -} - -bool -CModerator::check(const char* name, int value) -{ - bool retval = true; - auto it = iMemory.find(name); - if(it != iMemory.end()) { - retval = it->second != value; - it->second = value; - } - else { - iMemory[name] = value; - } - return retval; -} - -CModerator Moderator; +CModerator Moderator; // check for settings that are not actually changing, avoid sending these const int led = 13; @@ -145,26 +98,27 @@ bool doWebServer(void) { if(numClients) { if(millis() > lastTx) { // moderate the delivery of new messages - we simply cannot send every pass of the main loop! lastTx = millis() + 100; - bool bSend = false; - JsonObject& root = jsonBuffer.createObject(); - float tidyTemp = int(getActualTemperature() * 10) * 0.1f; // round to 0.1 resolution (hopefully!) - if(Moderator.check("CurrentTemp", tidyTemp)) { + JsonObject& root = jsonBuffer.createObject(); // create object to add JSON commands to + + Moderator.shouldSend(false); // reset global should send flag + + float tidyTemp = int(getActualTemperature() * 10) * 0.1f; // round to 0.1 resolution + if( Moderator.shouldSend("CurrentTemp", tidyTemp) ) root.set("CurrentTemp", tidyTemp); - bSend = true; - } - if(Moderator.check("RunState", getHeaterInfo().getRunState())) { + + if( Moderator.shouldSend("RunState", getHeaterInfo().getRunState() ) ) root.set("RunState", getHeaterInfo().getRunState()); - bSend = true; - } - if(Moderator.check("DesiredTemp", getHeaterInfo().getTemperature_Desired())) { + + if( Moderator.shouldSend("DesiredTemp", getHeaterInfo().getTemperature_Desired() ) ) root.set("DesiredTemp", getHeaterInfo().getTemperature_Desired()); - bSend = true; - } + + if( Moderator.shouldSend("ErrorState", getHeaterInfo().getErrState() ) ) + root.set("ErrorState", getHeaterInfo().getErrState()); - if(bSend) { - bTxWebData = true; - String jsonToSend; + if( Moderator.shouldSend() ) { // test global should send flags + bTxWebData = true; // OLED tx data animation flag + char jsonToSend[512]; root.printTo(jsonToSend); webSocket.broadcastTXT(jsonToSend); } @@ -249,4 +203,3 @@ void interpretJsonCommand(char* pLine) } } } - diff --git a/Arduino/BTCDieselHeater/Moderator.cpp b/Arduino/BTCDieselHeater/Moderator.cpp new file mode 100644 index 0000000..12b474c --- /dev/null +++ b/Arduino/BTCDieselHeater/Moderator.cpp @@ -0,0 +1,70 @@ +#include "Moderator.h" + +void +CModerator::shouldSend(bool set) +{ + _bShouldSend = false; +} + +bool +CModerator::shouldSend() +{ + return _bShouldSend; +} + +void +CModerator::reset() +{ + // install invalid values, retain maps (memory defrag reasons) + for(auto it = fMemory.begin(); it != fMemory.end(); ++it) it->second = -100; + for(auto it = iMemory.begin(); it != iMemory.end(); ++it) it->second = -100; + for(auto it = cMemory.begin(); it != cMemory.end(); ++it) it->second = -100; +} + +bool +CModerator::shouldSend(const char* name, float value) +{ + bool retval = true; + auto it = fMemory.find(name); + if(it != fMemory.end()) { + retval = it->second != value; + it->second = value; + } + else { + fMemory[name] = value; + } + _bShouldSend |= retval; + return retval; +} + +bool +CModerator::shouldSend(const char* name, int value) +{ + bool retval = true; + auto it = iMemory.find(name); + if(it != iMemory.end()) { + retval = it->second != value; + it->second = value; + } + else { + iMemory[name] = value; + } + _bShouldSend |= retval; + return retval; +} + +bool +CModerator::shouldSend(const char* name, unsigned char value) +{ + bool retval = true; + auto it = cMemory.find(name); + if(it != cMemory.end()) { + retval = it->second != value; + it->second = value; + } + else { + cMemory[name] = value; + } + _bShouldSend |= retval; + return retval; +} diff --git a/Arduino/BTCDieselHeater/Moderator.h b/Arduino/BTCDieselHeater/Moderator.h new file mode 100644 index 0000000..2eb5143 --- /dev/null +++ b/Arduino/BTCDieselHeater/Moderator.h @@ -0,0 +1,20 @@ +#ifndef __BTC_MODERATOR_H__ +#define __BTC_MODERATOR_H__ + +#include + +class CModerator { + bool _bShouldSend; + std::map fMemory; + std::map iMemory; + std::map cMemory; +public: + void shouldSend(bool reset); + bool shouldSend(); + bool shouldSend(const char* name, float value); + bool shouldSend(const char* name, int value); + bool shouldSend(const char* name, unsigned char value); + void reset(); +}; + +#endif // __BTC_MODERATOR_H__ diff --git a/Arduino/BTCDieselHeater/mainpage.cpp b/Arduino/BTCDieselHeater/mainpage.cpp index 9ddad22..8bfe46b 100644 --- a/Arduino/BTCDieselHeater/mainpage.cpp +++ b/Arduino/BTCDieselHeater/mainpage.cpp @@ -15,11 +15,11 @@ const char* MAIN_PAGE PROGMEM = R"=====( for(key in heater) { switch(key) { case "CurrentTemp": - console.log("Actual temp = ", heater.CurrentTemp); + console.log("JSON Rx: CurrentTemp:", heater.CurrentTemp); document.getElementById("TempCurrent").innerHTML = heater.CurrentTemp; break; case "RunState": - console.log("Runstate = ", heater.RunState); + console.log("JSON Rx: RunState:", heater.RunState); if (heater.RunState == 0) { document.getElementById("myonoffswitch").checked = false; document.getElementById("myonoffswitch").style = "block"; @@ -32,10 +32,13 @@ const char* MAIN_PAGE PROGMEM = R"=====( } break; case "DesiredTemp": - console.log("Desired temp = ", heater.DesiredTemp); + console.log("JSON Rx: DesiredTemp:", heater.DesiredTemp); document.getElementById("slide").value = heater.DesiredTemp; document.getElementById("sliderAmount").innerHTML = heater.DesiredTemp; break; + case "ErrorState": + console.log("JSON Rx: ErrorState:", heater.ErrorState); + break; } } } @@ -82,7 +85,7 @@ function OnOffCheck(){ var checkBox = document.getElementById("myonoffswitch"); // Send a message to the Devel console of web browser for debugging - console.log(document.getElementById("myonoffswitch").checked); + console.log("OnOffCheck:", document.getElementById("myonoffswitch").checked); // If the checkbox is checked, display the output text // We also need to send a message back into the esp as we cannot directly run Arduino Functions from within the javascript @@ -94,7 +97,7 @@ function OnOffCheck(){ const cmd = { RunState: 1 }; var str = JSON.stringify(cmd); - console.log("Sending: ", str); + console.log("JSON Tx:", str); Socket.send(str); } else{ @@ -104,7 +107,7 @@ function OnOffCheck(){ const cmd = { RunState: 0 }; var str = JSON.stringify(cmd); - console.log("Sending: ", str); + console.log("JSON Tx:", str); Socket.send(str); } } @@ -112,13 +115,11 @@ function OnOffCheck(){ function onSlide(newVal) { document.getElementById("sliderAmount").innerHTML = newVal; - console.log("Sending desired temp", newVal); - const cmd = { DesiredTemp: 0 }; cmd.DesiredTemp = newVal; var str = JSON.stringify(cmd); - console.log("Sending: ", str); + console.log("JSON Tx:", str); Socket.send(str); }