diff --git a/nextion-ui/SegoeUi64BNum.zi b/nextion-ui/SegoeUi64BNum.zi new file mode 100644 index 0000000..a37ce8b Binary files /dev/null and b/nextion-ui/SegoeUi64BNum.zi differ diff --git a/nextion-ui/SegoeUiBlack96Temp.zi b/nextion-ui/SegoeUiBlack96Temp.zi new file mode 100644 index 0000000..c126899 Binary files /dev/null and b/nextion-ui/SegoeUiBlack96Temp.zi differ diff --git a/nextion-ui/hmi-data.HMI b/nextion-ui/hmi-data.HMI index 7cd9341..9fd3acd 100644 Binary files a/nextion-ui/hmi-data.HMI and b/nextion-ui/hmi-data.HMI differ diff --git a/nextion-ui/icons/211.png b/nextion-ui/icons/211.png new file mode 100644 index 0000000..0a5a3d6 Binary files /dev/null and b/nextion-ui/icons/211.png differ diff --git a/nextion-ui/icons/212.png b/nextion-ui/icons/212.png new file mode 100644 index 0000000..b7cabfb Binary files /dev/null and b/nextion-ui/icons/212.png differ diff --git a/nextion-ui/icons/230.png b/nextion-ui/icons/230.png new file mode 100644 index 0000000..e1c6f5d Binary files /dev/null and b/nextion-ui/icons/230.png differ diff --git a/nextion-ui/icons/231.png b/nextion-ui/icons/231.png new file mode 100644 index 0000000..6fa9d96 Binary files /dev/null and b/nextion-ui/icons/231.png differ diff --git a/nextion-ui/icons/500d.png b/nextion-ui/icons/500d.png new file mode 100644 index 0000000..10273eb Binary files /dev/null and b/nextion-ui/icons/500d.png differ diff --git a/nextion-ui/icons/500n.png b/nextion-ui/icons/500n.png new file mode 100644 index 0000000..8e89be5 Binary files /dev/null and b/nextion-ui/icons/500n.png differ diff --git a/nextion-ui/icons/501.png b/nextion-ui/icons/501.png new file mode 100644 index 0000000..5723499 Binary files /dev/null and b/nextion-ui/icons/501.png differ diff --git a/nextion-ui/icons/502.png b/nextion-ui/icons/502.png new file mode 100644 index 0000000..8deff2b Binary files /dev/null and b/nextion-ui/icons/502.png differ diff --git a/nextion-ui/icons/600d.png b/nextion-ui/icons/600d.png new file mode 100644 index 0000000..37221b2 Binary files /dev/null and b/nextion-ui/icons/600d.png differ diff --git a/nextion-ui/icons/600n.png b/nextion-ui/icons/600n.png new file mode 100644 index 0000000..96e8644 Binary files /dev/null and b/nextion-ui/icons/600n.png differ diff --git a/nextion-ui/icons/601.png b/nextion-ui/icons/601.png new file mode 100644 index 0000000..f9b0b6d Binary files /dev/null and b/nextion-ui/icons/601.png differ diff --git a/nextion-ui/icons/602.png b/nextion-ui/icons/602.png new file mode 100644 index 0000000..3cc7695 Binary files /dev/null and b/nextion-ui/icons/602.png differ diff --git a/nextion-ui/icons/611.png b/nextion-ui/icons/611.png new file mode 100644 index 0000000..9bc00df Binary files /dev/null and b/nextion-ui/icons/611.png differ diff --git a/nextion-ui/icons/721d.png b/nextion-ui/icons/721d.png new file mode 100644 index 0000000..94acaf9 Binary files /dev/null and b/nextion-ui/icons/721d.png differ diff --git a/nextion-ui/icons/721n.png b/nextion-ui/icons/721n.png new file mode 100644 index 0000000..fbf9760 Binary files /dev/null and b/nextion-ui/icons/721n.png differ diff --git a/nextion-ui/icons/741.png b/nextion-ui/icons/741.png new file mode 100644 index 0000000..81b666d Binary files /dev/null and b/nextion-ui/icons/741.png differ diff --git a/nextion-ui/icons/800d.png b/nextion-ui/icons/800d.png new file mode 100644 index 0000000..e9b69cd Binary files /dev/null and b/nextion-ui/icons/800d.png differ diff --git a/nextion-ui/icons/800n.png b/nextion-ui/icons/800n.png new file mode 100644 index 0000000..79371f3 Binary files /dev/null and b/nextion-ui/icons/800n.png differ diff --git a/nextion-ui/icons/801d.png b/nextion-ui/icons/801d.png new file mode 100644 index 0000000..5a18d1f Binary files /dev/null and b/nextion-ui/icons/801d.png differ diff --git a/nextion-ui/icons/801n.png b/nextion-ui/icons/801n.png new file mode 100644 index 0000000..b5f342f Binary files /dev/null and b/nextion-ui/icons/801n.png differ diff --git a/nextion-ui/icons/802d.png b/nextion-ui/icons/802d.png new file mode 100644 index 0000000..d28f972 Binary files /dev/null and b/nextion-ui/icons/802d.png differ diff --git a/nextion-ui/icons/802n.png b/nextion-ui/icons/802n.png new file mode 100644 index 0000000..647088b Binary files /dev/null and b/nextion-ui/icons/802n.png differ diff --git a/nextion-ui/icons/803.png b/nextion-ui/icons/803.png new file mode 100644 index 0000000..ea621b9 Binary files /dev/null and b/nextion-ui/icons/803.png differ diff --git a/nextion-ui/icons/804.png b/nextion-ui/icons/804.png new file mode 100644 index 0000000..4297951 Binary files /dev/null and b/nextion-ui/icons/804.png differ diff --git a/nextion-ui/icons/air-quality.png b/nextion-ui/icons/air-quality.png new file mode 100644 index 0000000..930921b Binary files /dev/null and b/nextion-ui/icons/air-quality.png differ diff --git a/nextion-ui/icons/humidity.png b/nextion-ui/icons/humidity.png new file mode 100644 index 0000000..944c6fd Binary files /dev/null and b/nextion-ui/icons/humidity.png differ diff --git a/nextion-ui/icons/pressure.png b/nextion-ui/icons/pressure.png new file mode 100644 index 0000000..f4bad19 Binary files /dev/null and b/nextion-ui/icons/pressure.png differ diff --git a/nextion-ui/icons/temperature.png b/nextion-ui/icons/temperature.png new file mode 100644 index 0000000..d8267a0 Binary files /dev/null and b/nextion-ui/icons/temperature.png differ diff --git a/nextion-ui/img/ShowWeatherAndClock - AirQuality.png b/nextion-ui/img/ShowWeatherAndClock - AirQuality.png new file mode 100644 index 0000000..fd0ad17 Binary files /dev/null and b/nextion-ui/img/ShowWeatherAndClock - AirQuality.png differ diff --git a/nextion-ui/img/ShowWeatherAndClock - Blank.png b/nextion-ui/img/ShowWeatherAndClock - Blank.png new file mode 100644 index 0000000..2f9611d Binary files /dev/null and b/nextion-ui/img/ShowWeatherAndClock - Blank.png differ diff --git a/nextion-ui/img/ShowWeatherAndClock - Humidity.png b/nextion-ui/img/ShowWeatherAndClock - Humidity.png new file mode 100644 index 0000000..fffcc56 Binary files /dev/null and b/nextion-ui/img/ShowWeatherAndClock - Humidity.png differ diff --git a/nextion-ui/img/ShowWeatherAndClock - Pressure.png b/nextion-ui/img/ShowWeatherAndClock - Pressure.png new file mode 100644 index 0000000..c0851c4 Binary files /dev/null and b/nextion-ui/img/ShowWeatherAndClock - Pressure.png differ diff --git a/nextion-ui/img/ShowWeatherAndClock - Temp.png b/nextion-ui/img/ShowWeatherAndClock - Temp.png new file mode 100644 index 0000000..0d54d29 Binary files /dev/null and b/nextion-ui/img/ShowWeatherAndClock - Temp.png differ diff --git a/nextion-ui/img/Welcome.png b/nextion-ui/img/Welcome.png new file mode 100644 index 0000000..5ce3fe5 Binary files /dev/null and b/nextion-ui/img/Welcome.png differ diff --git a/nextion-ui/img/weather_cloud.png b/nextion-ui/img/weather_cloud.png new file mode 100644 index 0000000..70f4dff Binary files /dev/null and b/nextion-ui/img/weather_cloud.png differ diff --git a/nextion-ui/ui-template-design.xd b/nextion-ui/ui-template-design.xd index 50338ba..1f4de5d 100644 Binary files a/nextion-ui/ui-template-design.xd and b/nextion-ui/ui-template-design.xd differ diff --git a/printermonitor/Debug.cpp b/printermonitor/Debug.cpp new file mode 100644 index 0000000..bcc0005 --- /dev/null +++ b/printermonitor/Debug.cpp @@ -0,0 +1,65 @@ +#include "Debug.h" +#include + + +Debug::Debug() { +} + +void Debug::initialize() { + Serial.begin(115200); + delay(10); + Serial.println(); +} + +void Debug::print(char *data) { + Serial.print(data); +} + +void Debug::print(String data) { + Serial.print(data); +} + +void Debug::print(int8_t data) { + Serial.print(data); +} + +void Debug::printF(char *data, unsigned int uInt) { + Serial.printf(data, uInt); +} + +void Debug::printLn(char *data) { + Serial.println(data); +} + +void Debug::printLn(int8_t data) { + Serial.println(data); +} + +void Debug::printLn(String data) { + Serial.println(data); +} + +void Debug::printLn(long int data) { + Serial.println(data); +} + + +/******************************************** + +void serialDebugSetup() { +#ifndef USE_NEXTION_DISPLAY + +#endif +} + +#define NOP __asm__ __volatile__ ("nop\n\t") + +#ifndef USE_NEXTION_DISPLAY +#define serialDebugPrint(data) +#define serialDebugPrintF(data, args) Serial.printf(data, args) +#define serialDebugPrintLn(data) Serial.println(data) +#else +#define serialDebugPrint(data) NOP +#define serialDebugPrintLn(data) NOP +#endif +*/ diff --git a/printermonitor/Debug.h b/printermonitor/Debug.h new file mode 100644 index 0000000..046b209 --- /dev/null +++ b/printermonitor/Debug.h @@ -0,0 +1,18 @@ +#pragma once +#include + +class Debug { +public: + Debug(); + void initialize(); + void print(char *data); + void print(String data); + void print(int8_t data); + + void printF(char *data, unsigned int uInt); + + void printLn(char *data); + void printLn(String data); + void printLn(long int data); + void printLn(int8_t data); +}; diff --git a/printermonitor/DuetClient.cpp b/printermonitor/DuetClient.cpp index 6667b98..fb75cb7 100644 --- a/printermonitor/DuetClient.cpp +++ b/printermonitor/DuetClient.cpp @@ -27,7 +27,8 @@ SOFTWARE. #include "DuetClient.h" -DuetClient::DuetClient(String ApiKey, String server, int port, String user, String pass, boolean psu) { +DuetClient::DuetClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle) { + this->debugHandle = debugHandle; updatePrintClient(ApiKey, server, port, user, pass, psu); } @@ -63,8 +64,8 @@ WiFiClient DuetClient::getSubmitRequest(String apiGetData) { WiFiClient printClient; printClient.setTimeout(5000); - Serial.println("Getting Duet Data via GET"); - Serial.println(apiGetData); + this->debugHandle->printLn("Getting Duet Data via GET"); + this->debugHandle->printLn(apiGetData); result = ""; if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection printClient.println(apiGetData); @@ -77,16 +78,16 @@ WiFiClient DuetClient::getSubmitRequest(String apiGetData) { printClient.println("User-Agent: ArduinoWiFi/1.1"); printClient.println("Connection: close"); if (printClient.println() == 0) { - Serial.println("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); - Serial.println(); + this->debugHandle->printLn("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); + this->debugHandle->printLn(""); resetPrintData(); printerData.error = "Connection to " + String(myServer) + ":" + String(myPort) + " failed."; return printClient; } } else { - Serial.println("Connection to Duet failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect - Serial.println(); + this->debugHandle->printLn("Connection to Duet failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect + this->debugHandle->printLn(""); resetPrintData(); printerData.error = "Connection to Duet failed: " + String(myServer) + ":" + String(myPort); return printClient; @@ -96,8 +97,8 @@ WiFiClient DuetClient::getSubmitRequest(String apiGetData) { char status[32] = {0}; printClient.readBytesUntil('\r', status, sizeof(status)); if (strcmp(status, "HTTP/1.1 200 OK") != 0 && strcmp(status, "HTTP/1.1 409 CONFLICT") != 0) { - Serial.print(F("Unexpected response: ")); - Serial.println(status); + this->debugHandle->print("Unexpected response: "); + this->debugHandle->printLn(status); printerData.state = ""; printerData.error = "Response: " + String(status); return printClient; @@ -106,7 +107,7 @@ WiFiClient DuetClient::getSubmitRequest(String apiGetData) { // Skip HTTP headers char endOfHeaders[] = "\r\n\r\n"; if (!printClient.find(endOfHeaders)) { - Serial.println(F("Invalid response")); + this->debugHandle->printLn("Invalid response"); printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort); printerData.state = ""; } @@ -118,8 +119,8 @@ WiFiClient DuetClient::getPostRequest(String apiPostData, String apiPostBody) { WiFiClient printClient; printClient.setTimeout(5000); - Serial.println("Getting Duet Data via POST"); - Serial.println(apiPostData + " | " + apiPostBody); + this->debugHandle->printLn("Getting Duet Data via POST"); + this->debugHandle->printLn(apiPostData + " | " + apiPostBody); result = ""; if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection printClient.println(apiPostData); @@ -137,16 +138,16 @@ WiFiClient DuetClient::getPostRequest(String apiPostData, String apiPostBody) { printClient.println(); printClient.println(apiPostBody); if (printClient.println() == 0) { - Serial.println("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); - Serial.println(); + this->debugHandle->printLn("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); + this->debugHandle->printLn(""); resetPrintData(); printerData.error = "Connection to " + String(myServer) + ":" + String(myPort) + " failed."; return printClient; } } else { - Serial.println("Connection to Duet failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect - Serial.println(); + this->debugHandle->printLn("Connection to Duet failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect + this->debugHandle->printLn(""); resetPrintData(); printerData.error = "Connection to Duet failed: " + String(myServer) + ":" + String(myPort); return printClient; @@ -156,8 +157,8 @@ WiFiClient DuetClient::getPostRequest(String apiPostData, String apiPostBody) { char status[32] = {0}; printClient.readBytesUntil('\r', status, sizeof(status)); if (strcmp(status, "HTTP/1.1 200 OK") != 0 && strcmp(status, "HTTP/1.1 409 CONFLICT") != 0) { - Serial.print(F("Unexpected response: ")); - Serial.println(status); + this->debugHandle->print("Unexpected response: "); + this->debugHandle->printLn(status); printerData.state = ""; printerData.error = "Response: " + String(status); return printClient; @@ -166,7 +167,7 @@ WiFiClient DuetClient::getPostRequest(String apiPostData, String apiPostBody) { // Skip HTTP headers char endOfHeaders[] = "\r\n\r\n"; if (!printClient.find(endOfHeaders)) { - Serial.println(F("Invalid response")); + this->debugHandle->print("Invalid response"); printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort); printerData.state = ""; } @@ -190,7 +191,7 @@ void DuetClient::getPrinterJobResults() { // Parse JSON object JsonObject& root = jsonBuffer.parseObject(printClient); if (!root.success()) { - Serial.println("Duet Data Parsing failed: " + String(myServer) + ":" + String(myPort)); + this->debugHandle->printLn("Duet Data Parsing failed: " + String(myServer) + ":" + String(myPort)); printerData.error = "Duet Data Parsing failed: " + String(myServer) + ":" + String(myPort); printerData.state = ""; return; @@ -210,9 +211,9 @@ void DuetClient::getPrinterJobResults() { if (isOperational()) { - Serial.println("Status: " + printerData.state); + this->debugHandle->printLn("Status: " + printerData.state); } else { - Serial.println("Printer Not Operational"); + this->debugHandle->printLn("Printer Not Operational"); } //**** get the Printer Temps and Stat @@ -246,10 +247,10 @@ void DuetClient::getPrinterJobResults() { printerData.bedTemp = (const char*)root2["temps"]["bed"]["current"]; printerData.bedTargetTemp = (const char*)root2["temps"]["bed"]["active"]; - Serial.println("temps: " + printerData.toolTemp + " 1 " + printerData.toolTargetTemp + " 2 " + printerData.bedTemp + " 3 " + printerData.bedTargetTemp + " 4 "); + this->debugHandle->printLn("temps: " + printerData.toolTemp + " 1 " + printerData.toolTargetTemp + " 2 " + printerData.bedTemp + " 3 " + printerData.bedTargetTemp + " 4 "); if (isPrinting()) { - Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); + this->debugHandle->printLn("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); } } diff --git a/printermonitor/DuetClient.h b/printermonitor/DuetClient.h index 47a832d..2e30ebf 100644 --- a/printermonitor/DuetClient.h +++ b/printermonitor/DuetClient.h @@ -29,8 +29,10 @@ SOFTWARE. #include #include "libs/ArduinoJson/ArduinoJson.h" #include +#include "Debug.h" +#include "PrinterClientInterface.h" -class DuetClient { +class DuetClient : public PrinterClientInterface { private: char myServer[100]; @@ -70,13 +72,14 @@ private: } PrinterStruct; PrinterStruct printerData; + Debug *debugHandle; public: - DuetClient(String PrinterApiKey, String server, int port, String user, String pass, boolean psu); + DuetClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle); void getPrinterJobResults(); void getPrinterPsuState(); - void updatePrintClient(String PrinterApiKey, String server, int port, String user, String pass, boolean psu); + void updatePrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu); String getAveragePrintTime(); String getEstimatedPrintTime(); diff --git a/printermonitor/Global.h b/printermonitor/Global.h new file mode 100644 index 0000000..ed81388 --- /dev/null +++ b/printermonitor/Global.h @@ -0,0 +1,21 @@ +/** + * Main includes we are needing + */ +#include +#include +#include +#include +#include +#include +#include "TimeClient.h" +#include "KlipperClient.h" +#include "DuetClient.h" +#include "RepetierClient.h" +#include "OctoPrintClient.h" +#include "OpenWeatherMapClient.h" +#include "WeatherStationFonts.h" +#include "NextionDisplayClient.h" +#include "OledDisplayClient.h" +#include "WebServer.h" +#include "FS.h" +#include "Debug.h" diff --git a/printermonitor/KlipperClient.cpp b/printermonitor/KlipperClient.cpp index 1860ce9..0d3a2b4 100644 --- a/printermonitor/KlipperClient.cpp +++ b/printermonitor/KlipperClient.cpp @@ -27,7 +27,8 @@ SOFTWARE. #include "KlipperClient.h" -KlipperClient::KlipperClient(String ApiKey, String server, int port, String user, String pass, boolean psu) { +KlipperClient::KlipperClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle) { + this->debugHandle = debugHandle; updatePrintClient(ApiKey, server, port, user, pass, psu); } @@ -63,8 +64,8 @@ WiFiClient KlipperClient::getSubmitRequest(String apiGetData) { WiFiClient printClient; printClient.setTimeout(5000); - Serial.println("Getting Klipper Data via GET"); - Serial.println(apiGetData); + this->debugHandle->printLn("Getting Klipper Data via GET"); + this->debugHandle->printLn(apiGetData); result = ""; if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection printClient.println(apiGetData); @@ -77,16 +78,16 @@ WiFiClient KlipperClient::getSubmitRequest(String apiGetData) { printClient.println("User-Agent: ArduinoWiFi/1.1"); printClient.println("Connection: close"); if (printClient.println() == 0) { - Serial.println("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); - Serial.println(); + this->debugHandle->printLn("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); + this->debugHandle->printLn(""); resetPrintData(); printerData.error = "Connection to " + String(myServer) + ":" + String(myPort) + " failed."; return printClient; } } else { - Serial.println("Connection to Klipper failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect - Serial.println(); + this->debugHandle->printLn("Connection to Klipper failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect + this->debugHandle->printLn(""); resetPrintData(); printerData.error = "Connection to Klipper failed: " + String(myServer) + ":" + String(myPort); return printClient; @@ -96,8 +97,8 @@ WiFiClient KlipperClient::getSubmitRequest(String apiGetData) { char status[32] = {0}; printClient.readBytesUntil('\r', status, sizeof(status)); if (strcmp(status, "HTTP/1.1 200 OK") != 0 && strcmp(status, "HTTP/1.1 409 CONFLICT") != 0) { - Serial.print(F("Unexpected response: ")); - Serial.println(status); + this->debugHandle->print("Unexpected response: "); + this->debugHandle->printLn(status); printerData.state = ""; printerData.error = "Response: " + String(status); return printClient; @@ -106,7 +107,7 @@ WiFiClient KlipperClient::getSubmitRequest(String apiGetData) { // Skip HTTP headers char endOfHeaders[] = "\r\n\r\n"; if (!printClient.find(endOfHeaders)) { - Serial.println(F("Invalid response")); + this->debugHandle->printLn("Invalid response"); printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort); printerData.state = ""; } @@ -118,8 +119,8 @@ WiFiClient KlipperClient::getPostRequest(String apiPostData, String apiPostBody) WiFiClient printClient; printClient.setTimeout(5000); - Serial.println("Getting Klipper Data via POST"); - Serial.println(apiPostData + " | " + apiPostBody); + this->debugHandle->printLn("Getting Klipper Data via POST"); + this->debugHandle->printLn(apiPostData + " | " + apiPostBody); result = ""; if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection printClient.println(apiPostData); @@ -137,16 +138,16 @@ WiFiClient KlipperClient::getPostRequest(String apiPostData, String apiPostBody) printClient.println(); printClient.println(apiPostBody); if (printClient.println() == 0) { - Serial.println("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); - Serial.println(); + this->debugHandle->printLn("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); + this->debugHandle->printLn(""); resetPrintData(); printerData.error = "Connection to " + String(myServer) + ":" + String(myPort) + " failed."; return printClient; } } else { - Serial.println("Connection to Klipper failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect - Serial.println(); + this->debugHandle->printLn("Connection to Klipper failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect + this->debugHandle->printLn(""); resetPrintData(); printerData.error = "Connection to Klipper failed: " + String(myServer) + ":" + String(myPort); return printClient; @@ -156,8 +157,8 @@ WiFiClient KlipperClient::getPostRequest(String apiPostData, String apiPostBody) char status[32] = {0}; printClient.readBytesUntil('\r', status, sizeof(status)); if (strcmp(status, "HTTP/1.1 200 OK") != 0 && strcmp(status, "HTTP/1.1 409 CONFLICT") != 0) { - Serial.print(F("Unexpected response: ")); - Serial.println(status); + this->debugHandle->print("Unexpected response: "); + this->debugHandle->printLn(status); printerData.state = ""; printerData.error = "Response: " + String(status); return printClient; @@ -166,7 +167,7 @@ WiFiClient KlipperClient::getPostRequest(String apiPostData, String apiPostBody) // Skip HTTP headers char endOfHeaders[] = "\r\n\r\n"; if (!printClient.find(endOfHeaders)) { - Serial.println(F("Invalid response")); + this->debugHandle->printLn("Invalid response"); printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort); printerData.state = ""; } @@ -190,7 +191,7 @@ void KlipperClient::getPrinterJobResults() { // Parse JSON object JsonObject& root = jsonBuffer.parseObject(printClient); if (!root.success()) { - Serial.println("Klipper Data Parsing failed: " + String(myServer) + ":" + String(myPort)); + this->debugHandle->printLn("Klipper Data Parsing failed: " + String(myServer) + ":" + String(myPort)); printerData.error = "Klipper Data Parsing failed: " + String(myServer) + ":" + String(myPort); printerData.state = ""; return; @@ -209,9 +210,9 @@ void KlipperClient::getPrinterJobResults() { printerData.state = (const char*)root["result"]["status"]["print_stats"]["state"]; if (isOperational()) { - Serial.println("Status: " + printerData.state); + this->debugHandle->printLn("Status: " + printerData.state); } else { - Serial.println("Printer Not Operational"); + this->debugHandle->printLn("Printer Not Operational"); } //**** get the Printer Temps and Stat @@ -246,7 +247,7 @@ void KlipperClient::getPrinterJobResults() { printerData.bedTargetTemp = (const char*)root2["result"]["status"]["heater_bed"]["target"]; if (isPrinting()) { - Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); + this->debugHandle->printLn("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); } } diff --git a/printermonitor/KlipperClient.h b/printermonitor/KlipperClient.h index ea4c2f1..7f1689d 100644 --- a/printermonitor/KlipperClient.h +++ b/printermonitor/KlipperClient.h @@ -29,8 +29,10 @@ SOFTWARE. #include #include "libs/ArduinoJson/ArduinoJson.h" #include +#include "Debug.h" +#include "PrinterClientInterface.h" -class KlipperClient { +class KlipperClient : public PrinterClientInterface { private: char myServer[100]; @@ -70,10 +72,10 @@ private: } PrinterStruct; PrinterStruct printerData; - + Debug *debugHandle; public: - KlipperClient(String ApiKey, String server, int port, String user, String pass, boolean psu); + KlipperClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle); void getPrinterJobResults(); void getPrinterPsuState(); void updatePrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu); diff --git a/printermonitor/KlipperPrintClient.cpp b/printermonitor/KlipperPrintClient.cpp deleted file mode 100644 index 2cba1b1..0000000 --- a/printermonitor/KlipperPrintClient.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/** The MIT License (MIT) - -Copyright (c) 2018 David Payne - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -// Additional Contributions: -/* 15 Jan 2019 : Owen Carter : Add psucontrol query via POST api call */ - -#include "KlipperPrintClient.h" - -KlipperPrintClient::KlipperPrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu) { - updatePrintClient(ApiKey, server, port, user, pass, psu); -} - -void KlipperPrintClient::updatePrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu) { - server.toCharArray(myServer, 100); - myApiKey = ApiKey; - myPort = port; - encodedAuth = ""; - if (user != "") { - String userpass = user + ":" + pass; - base64 b64; - encodedAuth = b64.encode(userpass, true); - } - pollPsu = psu; -} - -boolean KlipperPrintClient::validate() { - boolean rtnValue = false; - printerData.error = ""; - if (String(myServer) == "") { - printerData.error += "Server address is required; "; - } - if (myApiKey == "") { - printerData.error += "ApiKey is required; "; - } - if (printerData.error == "") { - rtnValue = true; - } - return rtnValue; -} - -WiFiClient KlipperPrintClient::getSubmitRequest(String apiGetData) { - WiFiClient printClient; - printClient.setTimeout(5000); - - Serial.println("Getting Octoprint Data via GET"); - Serial.println(apiGetData); - result = ""; - if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection - printClient.println(apiGetData); - printClient.println("Host: " + String(myServer) + ":" + String(myPort)); - printClient.println("X-Api-Key: " + myApiKey); - if (encodedAuth != "") { - printClient.print("Authorization: "); - printClient.println("Basic " + encodedAuth); - } - printClient.println("User-Agent: ArduinoWiFi/1.1"); - printClient.println("Connection: close"); - if (printClient.println() == 0) { - Serial.println("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); - Serial.println(); - resetPrintData(); - printerData.error = "Connection to " + String(myServer) + ":" + String(myPort) + " failed."; - return printClient; - } - } - else { - Serial.println("Connection to OctoPrint failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect - Serial.println(); - resetPrintData(); - printerData.error = "Connection to OctoPrint failed: " + String(myServer) + ":" + String(myPort); - return printClient; - } - - // Check HTTP status - char status[32] = {0}; - printClient.readBytesUntil('\r', status, sizeof(status)); - if (strcmp(status, "HTTP/1.1 200 OK") != 0 && strcmp(status, "HTTP/1.1 409 CONFLICT") != 0) { - Serial.print(F("Unexpected response: ")); - Serial.println(status); - printerData.state = ""; - printerData.error = "Response: " + String(status); - return printClient; - } - - // Skip HTTP headers - char endOfHeaders[] = "\r\n\r\n"; - if (!printClient.find(endOfHeaders)) { - Serial.println(F("Invalid response")); - printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort); - printerData.state = ""; - } - - return printClient; -} - -WiFiClient KlipperPrintClient::getPostRequest(String apiPostData, String apiPostBody) { - WiFiClient printClient; - printClient.setTimeout(5000); - - Serial.println("Getting Octoprint Data via POST"); - Serial.println(apiPostData + " | " + apiPostBody); - result = ""; - if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection - printClient.println(apiPostData); - printClient.println("Host: " + String(myServer) + ":" + String(myPort)); - printClient.println("Connection: close"); - printClient.println("X-Api-Key: " + myApiKey); - if (encodedAuth != "") { - printClient.print("Authorization: "); - printClient.println("Basic " + encodedAuth); - } - printClient.println("User-Agent: ArduinoWiFi/1.1"); - printClient.println("Content-Type: application/json"); - printClient.print("Content-Length: "); - printClient.println(apiPostBody.length()); - printClient.println(); - printClient.println(apiPostBody); - if (printClient.println() == 0) { - Serial.println("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); - Serial.println(); - resetPrintData(); - printerData.error = "Connection to " + String(myServer) + ":" + String(myPort) + " failed."; - return printClient; - } - } - else { - Serial.println("Connection to OctoPrint failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect - Serial.println(); - resetPrintData(); - printerData.error = "Connection to OctoPrint failed: " + String(myServer) + ":" + String(myPort); - return printClient; - } - - // Check HTTP status - char status[32] = {0}; - printClient.readBytesUntil('\r', status, sizeof(status)); - if (strcmp(status, "HTTP/1.1 200 OK") != 0 && strcmp(status, "HTTP/1.1 409 CONFLICT") != 0) { - Serial.print(F("Unexpected response: ")); - Serial.println(status); - printerData.state = ""; - printerData.error = "Response: " + String(status); - return printClient; - } - - // Skip HTTP headers - char endOfHeaders[] = "\r\n\r\n"; - if (!printClient.find(endOfHeaders)) { - Serial.println(F("Invalid response")); - printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort); - printerData.state = ""; - } - - return printClient; -} - -void KlipperPrintClient::getPrinterJobResults() { - if (!validate()) { - return; - } - //**** get the Printer Job status - String apiGetData = "GET /api/job HTTP/1.1"; - WiFiClient printClient = getSubmitRequest(apiGetData); - if (printerData.error != "") { - return; - } - const size_t bufferSize = JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 2*JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(6) + 710; - DynamicJsonBuffer jsonBuffer(bufferSize); - - // Parse JSON object - JsonObject& root = jsonBuffer.parseObject(printClient); - if (!root.success()) { - Serial.println("OctoPrint Data Parsing failed: " + String(myServer) + ":" + String(myPort)); - printerData.error = "OctoPrint Data Parsing failed: " + String(myServer) + ":" + String(myPort); - printerData.state = ""; - return; - } - - printerData.averagePrintTime = (const char*)root["job"]["averagePrintTime"]; - printerData.estimatedPrintTime = (const char*)root["job"]["estimatedPrintTime"]; - printerData.fileName = (const char*)root["job"]["file"]["name"]; - printerData.fileSize = (const char*)root["job"]["file"]["size"]; - printerData.lastPrintTime = (const char*)root["job"]["lastPrintTime"]; - printerData.progressCompletion = (const char*)root["progress"]["completion"]; - printerData.progressFilepos = (const char*)root["progress"]["filepos"]; - printerData.progressPrintTime = (const char*)root["progress"]["printTime"]; - printerData.progressPrintTimeLeft = (const char*)root["progress"]["printTimeLeft"]; - printerData.filamentLength = (const char*)root["job"]["filament"]["tool0"]["length"]; - printerData.state = (const char*)root["state"]; - - if (isOperational()) { - Serial.println("Status: " + printerData.state); - } else { - Serial.println("Printer Not Operational"); - } - - //**** get the Printer Temps and Stat - apiGetData = "GET /api/printer?exclude=sd,history HTTP/1.1"; - printClient = getSubmitRequest(apiGetData); - if (printerData.error != "") { - return; - } - const size_t bufferSize2 = 3*JSON_OBJECT_SIZE(2) + 2*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(9) + 300; - DynamicJsonBuffer jsonBuffer2(bufferSize2); - - // Parse JSON object - JsonObject& root2 = jsonBuffer2.parseObject(printClient); - if (!root2.success()) { - printerData.isPrinting = false; - printerData.toolTemp = ""; - printerData.toolTargetTemp = ""; - printerData.bedTemp = ""; - printerData.bedTargetTemp = (const char*)root2["temperature"]["bed"]["target"]; - return; - } - - String printing = (const char*)root2["state"]["flags"]["printing"]; - if (printing == "true") { - printerData.isPrinting = true; - } else { - printerData.isPrinting = false; - } - printerData.toolTemp = (const char*)root2["temperature"]["tool0"]["actual"]; - printerData.toolTargetTemp = (const char*)root2["temperature"]["tool0"]["target"]; - printerData.bedTemp = (const char*)root2["temperature"]["bed"]["actual"]; - printerData.bedTargetTemp = (const char*)root2["temperature"]["bed"]["target"]; - - if (isPrinting()) { - Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); - } -} - -void KlipperPrintClient::getPrinterPsuState() { - //**** get the PSU state (if enabled and printer operational) - if (pollPsu && isOperational()) { - if (!validate()) { - printerData.isPSUoff = false; // we do not know PSU state, so assume on. - return; - } - String apiPostData = "POST /api/plugin/psucontrol HTTP/1.1"; - String apiPostBody = "{\"command\":\"getPSUState\"}"; - WiFiClient printClient = getPostRequest(apiPostData,apiPostBody); - if (printerData.error != "") { - printerData.isPSUoff = false; // we do not know PSU state, so assume on. - return; - } - const size_t bufferSize3 = JSON_OBJECT_SIZE(2) + 300; - DynamicJsonBuffer jsonBuffer3(bufferSize3); - - // Parse JSON object - JsonObject& root3 = jsonBuffer3.parseObject(printClient); - if (!root3.success()) { - printerData.isPSUoff = false; // we do not know PSU state, so assume on - return; - } - - String psu = (const char*)root3["isPSUOn"]; - if (psu == "true") { - printerData.isPSUoff = false; // PSU checked and is on - } else { - printerData.isPSUoff = true; // PSU checked and is off, set flag - } - printClient.stop(); //stop client - } else { - printerData.isPSUoff = false; // we are not checking PSU state, so assume on - } -} - -// Reset all PrinterData -void KlipperPrintClient::resetPrintData() { - printerData.averagePrintTime = ""; - printerData.estimatedPrintTime = ""; - printerData.fileName = ""; - printerData.fileSize = ""; - printerData.lastPrintTime = ""; - printerData.progressCompletion = ""; - printerData.progressFilepos = ""; - printerData.progressPrintTime = ""; - printerData.progressPrintTimeLeft = ""; - printerData.state = ""; - printerData.toolTemp = ""; - printerData.toolTargetTemp = ""; - printerData.filamentLength = ""; - printerData.bedTemp = ""; - printerData.bedTargetTemp = ""; - printerData.isPrinting = false; - printerData.isPSUoff = false; - printerData.error = ""; -} - -String KlipperPrintClient::getAveragePrintTime(){ - return printerData.averagePrintTime; -} - -String KlipperPrintClient::getEstimatedPrintTime() { - return printerData.estimatedPrintTime; -} - -String KlipperPrintClient::getFileName() { - return printerData.fileName; -} - -String KlipperPrintClient::getFileSize() { - return printerData.fileSize; -} - -String KlipperPrintClient::getLastPrintTime(){ - return printerData.lastPrintTime; -} - -String KlipperPrintClient::getProgressCompletion() { - return String(printerData.progressCompletion.toInt()); -} - -String KlipperPrintClient::getProgressFilepos() { - return printerData.progressFilepos; -} - -String KlipperPrintClient::getProgressPrintTime() { - return printerData.progressPrintTime; -} - -String KlipperPrintClient::getProgressPrintTimeLeft() { - String rtnValue = printerData.progressPrintTimeLeft; - if (getProgressCompletion() == "100") { - rtnValue = "0"; // Print is done so this should be 0 this is a fix for OctoPrint - } - return rtnValue; -} - -String KlipperPrintClient::getState() { - return printerData.state; -} - -boolean KlipperPrintClient::isPrinting() { - return printerData.isPrinting; -} - -boolean KlipperPrintClient::isPSUoff() { - return printerData.isPSUoff; -} - -boolean KlipperPrintClient::isOperational() { - boolean operational = false; - if (printerData.state == "Operational" || isPrinting()) { - operational = true; - } - return operational; -} - -String KlipperPrintClient::getTempBedActual() { - return printerData.bedTemp; -} - -String KlipperPrintClient::getTempBedTarget() { - return printerData.bedTargetTemp; -} - -String KlipperPrintClient::getTempToolActual() { - return printerData.toolTemp; -} - -String KlipperPrintClient::getTempToolTarget() { - return printerData.toolTargetTemp; -} - -String KlipperPrintClient::getFilamentLength() { - return printerData.filamentLength; -} - -String KlipperPrintClient::getError() { - return printerData.error; -} - -String KlipperPrintClient::getValueRounded(String value) { - float f = value.toFloat(); - int rounded = (int)(f+0.5f); - return String(rounded); -} - -String KlipperPrintClient::getPrinterType() { - return printerType; -} - -int KlipperPrintClient::getPrinterPort() { - return myPort; -} - -String KlipperPrintClient::getPrinterName() { - return printerData.printerName; -} - -void KlipperPrintClient::setPrinterName(String printer) { - printerData.printerName = printer; -} diff --git a/printermonitor/KlipperPrintClient.h b/printermonitor/KlipperPrintClient.h deleted file mode 100644 index abd8023..0000000 --- a/printermonitor/KlipperPrintClient.h +++ /dev/null @@ -1,104 +0,0 @@ -/** The MIT License (MIT) - -Copyright (c) 2018 David Payne - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -// Additional Contributions: -/* 15 Jan 2019 : Owen Carter : Add psucontrol query via POST api call */ - -#pragma once -#include -#include "libs/ArduinoJson/ArduinoJson.h" -#include - -class KlipperPrintClient { - -private: - char myServer[100]; - int myPort = 80; - String myApiKey = ""; - String encodedAuth = ""; - boolean pollPsu; - const String printerType = "OctoPrint"; - - void resetPrintData(); - boolean validate(); - WiFiClient getSubmitRequest(String apiGetData); - WiFiClient getPostRequest(String apiPostData, String apiPostBody); - - String result; - - typedef struct { - String averagePrintTime; - String estimatedPrintTime; - String fileName; - String fileSize; - String lastPrintTime; - String progressCompletion; - String progressFilepos; - String progressPrintTime; - String progressPrintTimeLeft; - String state; - String toolTemp; - String toolTargetTemp; - String filamentLength; - String bedTemp; - String bedTargetTemp; - boolean isPrinting; - boolean isPSUoff; - String error; - String printerName; - } PrinterStruct; - - PrinterStruct printerData; - - -public: - KlipperPrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu); - void getPrinterJobResults(); - void getPrinterPsuState(); - void updatePrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu); - - String getAveragePrintTime(); - String getEstimatedPrintTime(); - String getFileName(); - String getFileSize(); - String getLastPrintTime(); - String getProgressCompletion(); - String getProgressFilepos(); - String getProgressPrintTime(); - String getProgressPrintTimeLeft(); - String getState(); - boolean isPrinting(); - boolean isOperational(); - boolean isPSUoff(); - String getTempBedActual(); - String getTempBedTarget(); - String getTempToolActual(); - String getTempToolTarget(); - String getFilamentLength(); - String getValueRounded(String value); - String getError(); - String getPrinterType(); - int getPrinterPort(); - String getPrinterName(); - void setPrinterName(String printer); -}; diff --git a/printermonitor/Macros.h b/printermonitor/Macros.h new file mode 100644 index 0000000..e399ff2 --- /dev/null +++ b/printermonitor/Macros.h @@ -0,0 +1,10 @@ +#pragma once + +/* Useful Constants */ +#define SECS_PER_MIN (60UL) +#define SECS_PER_HOUR (3600UL) + +/* Useful Macros for getting elapsed time */ +#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN) +#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN) +#define numberOfHours(_time_) (_time_ / SECS_PER_HOUR) diff --git a/printermonitor/NextionDisplayClient.cpp b/printermonitor/NextionDisplayClient.cpp new file mode 100644 index 0000000..9383724 --- /dev/null +++ b/printermonitor/NextionDisplayClient.cpp @@ -0,0 +1,50 @@ +#include "NextionDisplayClient.h" + +NextionDisplayClient::NextionDisplayClient(byte rxPin, byte txPin, PrinterClientInterface *printerClient) { + this->printerClient = printerClient; + this->softwareSerialPort = new SoftwareSerial(rxPin, txPin); + this->softwareSerialPort->begin(9600); +} + +void NextionDisplayClient::postSetup() { +} + +void NextionDisplayClient::showPageInit(String printerTypeName, String softwareVersion) { + String command("version.txt="); + command += "\"for " + printerTypeName + " V" + softwareVersion + "\""; + this->sendCommand("page 0"); + this->sendCommand(command.c_str()); +} + +void NextionDisplayClient::showPageApMode(String protalSsid) { + String commandHostName("WifiHostname.txt="); + String commandQrCode("WifiScancode.txt="); + commandHostName += "\"" + protalSsid + "\""; + commandQrCode += "\"WIFI:S:" + protalSsid + ";T:WPA;P:;;\""; + this->sendCommand("page 1"); + this->sendCommand(commandHostName.c_str()); + this->sendCommand(commandQrCode.c_str()); +} + +void NextionDisplayClient::showPageWeather() { + this->sendCommand("page 2"); +} + +void NextionDisplayClient::showPagePrinter() { + this->sendCommand("page 3"); +} + + + + +void NextionDisplayClient::sendCommand(const char* cmd) { + while (this->softwareSerialPort->available()) + { + this->softwareSerialPort->read(); + } + + this->softwareSerialPort->print(cmd); + this->softwareSerialPort->write(0xFF); + this->softwareSerialPort->write(0xFF); + this->softwareSerialPort->write(0xFF); +} diff --git a/printermonitor/NextionDisplayClient.h b/printermonitor/NextionDisplayClient.h new file mode 100644 index 0000000..9f4b6e0 --- /dev/null +++ b/printermonitor/NextionDisplayClient.h @@ -0,0 +1,26 @@ +#pragma once +#include +#include "libs/ArduinoJson/ArduinoJson.h" +#include +#include "Debug.h" +#include +#include "PrinterClientInterface.h" +#include "Macros.h" + +class NextionDisplayClient { +private: + SoftwareSerial *softwareSerialPort; + PrinterClientInterface *printerClient; + +public: + NextionDisplayClient(byte rxPin, byte txPin, PrinterClientInterface *printerClient); + void postSetup(); + + void showPageInit(String printerTypeName, String softwareVersion); + void showPageApMode(String protalSsid); + void showPageWeather(); + void showPagePrinter(); + +private: + void sendCommand(const char* cmd); +}; diff --git a/printermonitor/OctoPrintClient.cpp b/printermonitor/OctoPrintClient.cpp index 832835b..2a6d60c 100644 --- a/printermonitor/OctoPrintClient.cpp +++ b/printermonitor/OctoPrintClient.cpp @@ -26,7 +26,8 @@ SOFTWARE. #include "OctoPrintClient.h" -OctoPrintClient::OctoPrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu) { +OctoPrintClient::OctoPrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle) { + this->debugHandle = debugHandle; updatePrintClient(ApiKey, server, port, user, pass, psu); } @@ -62,8 +63,8 @@ WiFiClient OctoPrintClient::getSubmitRequest(String apiGetData) { WiFiClient printClient; printClient.setTimeout(5000); - Serial.println("Getting Octoprint Data via GET"); - Serial.println(apiGetData); + this->debugHandle->printLn("Getting Octoprint Data via GET"); + this->debugHandle->printLn(apiGetData); result = ""; if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection printClient.println(apiGetData); @@ -76,16 +77,16 @@ WiFiClient OctoPrintClient::getSubmitRequest(String apiGetData) { printClient.println("User-Agent: ArduinoWiFi/1.1"); printClient.println("Connection: close"); if (printClient.println() == 0) { - Serial.println("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); - Serial.println(); + this->debugHandle->printLn("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); + this->debugHandle->printLn(""); resetPrintData(); printerData.error = "Connection to " + String(myServer) + ":" + String(myPort) + " failed."; return printClient; } } else { - Serial.println("Connection to OctoPrint failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect - Serial.println(); + this->debugHandle->printLn("Connection to OctoPrint failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect + this->debugHandle->printLn(""); resetPrintData(); printerData.error = "Connection to OctoPrint failed: " + String(myServer) + ":" + String(myPort); return printClient; @@ -95,8 +96,8 @@ WiFiClient OctoPrintClient::getSubmitRequest(String apiGetData) { char status[32] = {0}; printClient.readBytesUntil('\r', status, sizeof(status)); if (strcmp(status, "HTTP/1.1 200 OK") != 0 && strcmp(status, "HTTP/1.1 409 CONFLICT") != 0) { - Serial.print(F("Unexpected response: ")); - Serial.println(status); + this->debugHandle->print("Unexpected response: "); + this->debugHandle->printLn(status); printerData.state = ""; printerData.error = "Response: " + String(status); return printClient; @@ -105,7 +106,7 @@ WiFiClient OctoPrintClient::getSubmitRequest(String apiGetData) { // Skip HTTP headers char endOfHeaders[] = "\r\n\r\n"; if (!printClient.find(endOfHeaders)) { - Serial.println(F("Invalid response")); + this->debugHandle->printLn("Invalid response"); printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort); printerData.state = ""; } @@ -117,8 +118,8 @@ WiFiClient OctoPrintClient::getPostRequest(String apiPostData, String apiPostBod WiFiClient printClient; printClient.setTimeout(5000); - Serial.println("Getting Octoprint Data via POST"); - Serial.println(apiPostData + " | " + apiPostBody); + this->debugHandle->printLn("Getting Octoprint Data via POST"); + this->debugHandle->printLn(apiPostData + " | " + apiPostBody); result = ""; if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection printClient.println(apiPostData); @@ -136,16 +137,16 @@ WiFiClient OctoPrintClient::getPostRequest(String apiPostData, String apiPostBod printClient.println(); printClient.println(apiPostBody); if (printClient.println() == 0) { - Serial.println("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); - Serial.println(); + this->debugHandle->printLn("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); + this->debugHandle->printLn(""); resetPrintData(); printerData.error = "Connection to " + String(myServer) + ":" + String(myPort) + " failed."; return printClient; } } else { - Serial.println("Connection to OctoPrint failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect - Serial.println(); + this->debugHandle->printLn("Connection to OctoPrint failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect + this->debugHandle->printLn(""); resetPrintData(); printerData.error = "Connection to OctoPrint failed: " + String(myServer) + ":" + String(myPort); return printClient; @@ -155,8 +156,8 @@ WiFiClient OctoPrintClient::getPostRequest(String apiPostData, String apiPostBod char status[32] = {0}; printClient.readBytesUntil('\r', status, sizeof(status)); if (strcmp(status, "HTTP/1.1 200 OK") != 0 && strcmp(status, "HTTP/1.1 409 CONFLICT") != 0) { - Serial.print(F("Unexpected response: ")); - Serial.println(status); + this->debugHandle->print("Unexpected response: "); + this->debugHandle->printLn(status); printerData.state = ""; printerData.error = "Response: " + String(status); return printClient; @@ -165,7 +166,7 @@ WiFiClient OctoPrintClient::getPostRequest(String apiPostData, String apiPostBod // Skip HTTP headers char endOfHeaders[] = "\r\n\r\n"; if (!printClient.find(endOfHeaders)) { - Serial.println(F("Invalid response")); + this->debugHandle->printLn("Invalid response"); printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort); printerData.state = ""; } @@ -189,7 +190,7 @@ void OctoPrintClient::getPrinterJobResults() { // Parse JSON object JsonObject& root = jsonBuffer.parseObject(printClient); if (!root.success()) { - Serial.println("OctoPrint Data Parsing failed: " + String(myServer) + ":" + String(myPort)); + this->debugHandle->printLn("OctoPrint Data Parsing failed: " + String(myServer) + ":" + String(myPort)); printerData.error = "OctoPrint Data Parsing failed: " + String(myServer) + ":" + String(myPort); printerData.state = ""; return; @@ -208,9 +209,9 @@ void OctoPrintClient::getPrinterJobResults() { printerData.state = (const char*)root["state"]; if (isOperational()) { - Serial.println("Status: " + printerData.state); + this->debugHandle->printLn("Status: " + printerData.state); } else { - Serial.println("Printer Not Operational"); + this->debugHandle->printLn("Printer Not Operational"); } //**** get the Printer Temps and Stat @@ -245,7 +246,7 @@ void OctoPrintClient::getPrinterJobResults() { printerData.bedTargetTemp = (const char*)root2["temperature"]["bed"]["target"]; if (isPrinting()) { - Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); + this->debugHandle->printLn("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); } } diff --git a/printermonitor/OctoPrintClient.h b/printermonitor/OctoPrintClient.h index 1761ccc..e91acd5 100644 --- a/printermonitor/OctoPrintClient.h +++ b/printermonitor/OctoPrintClient.h @@ -28,8 +28,10 @@ SOFTWARE. #include #include "libs/ArduinoJson/ArduinoJson.h" #include +#include "Debug.h" +#include "PrinterClientInterface.h" -class OctoPrintClient { +class OctoPrintClient : public PrinterClientInterface { private: char myServer[100]; @@ -69,10 +71,11 @@ private: } PrinterStruct; PrinterStruct printerData; + Debug *debugHandle; public: - OctoPrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu); + OctoPrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle); void getPrinterJobResults(); void getPrinterPsuState(); void updatePrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu); diff --git a/printermonitor/OledDisplayClient.cpp b/printermonitor/OledDisplayClient.cpp new file mode 100644 index 0000000..4e486c1 --- /dev/null +++ b/printermonitor/OledDisplayClient.cpp @@ -0,0 +1,170 @@ +#include "OledDisplayClient.h" + + +OledDisplayClient::OledDisplayClient(byte sdaPin, byte sclPin, byte i2cAddress, bool isSh1106, bool invertDisplay, PrinterClientInterface *printerClient) { + this->printerClient = printerClient; + if(isSh1106) { + this->display = new SH1106Wire(i2cAddress, sdaPin, sclPin); + } else { + this->display = new SSD1306Wire(i2cAddress, sdaPin, sclPin); + } + this->ui = new OLEDDisplayUi(this->display); + this->invertDisplay = invertDisplay; + + this->display->init(); + if (invertDisplay) { + this->display->flipScreenVertically(); // connections at top of OLED display + } + this->display->clear(); + this->display->display(); + + //this->overlays[0] = drawHeaderOverlay; + //this->clockOverlay[0] = drawClockHeaderOverlay; +} + +void OledDisplayClient::postSetup() { + static OledDisplayClient* obj = this; + // You can change the transition that is used + // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN + this->ui->setFrameAnimation(SLIDE_LEFT); + this->ui->setTargetFPS(30); + this->ui->disableAllIndicators(); + this->ui->setFrames(this->frames, (3)); + this->frames[0] = [](OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { obj->drawScreen1(display, state, x, y); }; + this->frames[1] = [](OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { obj->drawScreen2(display, state, x, y); }; + this->frames[2] = [](OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { obj->drawScreen3(display, state, x, y); }; + this->clockFrame[0] = [](OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { obj->drawClock(display, state, x, y); }; + this->clockFrame[1] = [](OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { obj->drawWeather(display, state, x, y); }; + this->ui->setOverlays(this->overlays, 1); + + // Inital UI takes care of initalising the display too. + this->ui->init(); + if (this->invertDisplay) { + this->display->flipScreenVertically(); //connections at top of OLED display + } +} + +void OledDisplayClient::showPageInit(String printerTypeName, String softwareVersion) { + this->display->setTextAlignment(TEXT_ALIGN_CENTER); + this->display->setContrast(255); // default is 255 + this->display->setFont(ArialMT_Plain_16); + this->display->drawString(64, 1, "Printer Monitor"); + this->display->setFont(ArialMT_Plain_10); + this->display->drawString(64, 18, "for " + printerTypeName); + this->display->setFont(ArialMT_Plain_16); + this->display->drawString(64, 30, "By Qrome"); + this->display->drawString(64, 46, "V" + softwareVersion); + this->display->display(); +} + +void OledDisplayClient::showPageApMode(String protalSsid) { + this->display->clear(); + this->display->setTextAlignment(TEXT_ALIGN_CENTER); + this->display->setFont(ArialMT_Plain_10); + this->display->drawString(64, 0, "Wifi Manager"); + this->display->drawString(64, 10, "Please connect to AP"); + this->display->setFont(ArialMT_Plain_16); + this->display->drawString(64, 26, protalSsid); + this->display->setFont(ArialMT_Plain_10); + this->display->drawString(64, 46, "To setup Wifi connection"); + this->display->display(); +} + +void OledDisplayClient::showPageWeather() { +} + +void OledDisplayClient::showPagePrinter() { +} + +void OledDisplayClient::drawScreen1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { + String bed = this->printerClient->getValueRounded(this->printerClient->getTempBedActual()); + String tool = this->printerClient->getValueRounded(printerClient->getTempToolActual()); + display->setTextAlignment(TEXT_ALIGN_CENTER); + display->setFont(ArialMT_Plain_16); + if (bed != "0") { + display->drawString(29 + x, 0 + y, "Tool"); + display->drawString(89 + x, 0 + y, "Bed"); + } else { + display->drawString(64 + x, 0 + y, "Tool Temp"); + } + display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(ArialMT_Plain_24); + if (bed != "0") { + display->setTextAlignment(TEXT_ALIGN_LEFT); + display->drawString(12 + x, 14 + y, tool + "°"); + display->drawString(74 + x, 14 + y, bed + "°"); + } else { + display->setTextAlignment(TEXT_ALIGN_CENTER); + display->drawString(64 + x, 14 + y, tool + "°"); + } +} + +void OledDisplayClient::drawScreen2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { + display->setTextAlignment(TEXT_ALIGN_CENTER); + display->setFont(ArialMT_Plain_16); + + display->drawString(64 + x, 0 + y, "Time Remaining"); + //display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(ArialMT_Plain_24); + int val = printerClient->getProgressPrintTimeLeft().toInt(); + int hours = numberOfHours(val); + int minutes = numberOfMinutes(val); + int seconds = numberOfSeconds(val); + + String time = zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds); + display->drawString(64 + x, 14 + y, time); +} + +void OledDisplayClient::drawScreen3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { + display->setTextAlignment(TEXT_ALIGN_CENTER); + display->setFont(ArialMT_Plain_16); + + display->drawString(64 + x, 0 + y, "Printing Time"); + //display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(ArialMT_Plain_24); + int val = printerClient->getProgressPrintTime().toInt(); + int hours = numberOfHours(val); + int minutes = numberOfMinutes(val); + int seconds = numberOfSeconds(val); + + String time = zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds); + display->drawString(64 + x, 14 + y, time); +} + +void OledDisplayClient::drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { + /*display->setTextAlignment(TEXT_ALIGN_CENTER); + + String displayTime = timeClient.getAmPmHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds(); + if (IS_24HOUR) { + displayTime = timeClient.getHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds(); + } + String displayName = PrinterHostName; + if (printerClient.getPrinterType() == "Repetier") { + displayName = printerClient.getPrinterName(); + } + display->setFont(ArialMT_Plain_16); + display->drawString(64 + x, 0 + y, displayName); + display->setFont(ArialMT_Plain_24); + display->drawString(64 + x, 17 + y, displayTime); */ +} + +void OledDisplayClient::drawWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { + /*display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(ArialMT_Plain_24); + display->drawString(0 + x, 0 + y, weatherClient.getTempRounded(0) + getTempSymbol()); + display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(ArialMT_Plain_24); + + display->setFont(ArialMT_Plain_16); + display->drawString(0 + x, 24 + y, weatherClient.getCondition(0)); + display->setFont((const uint8_t*)Meteocons_Plain_42); + display->drawString(86 + x, 0 + y, weatherClient.getWeatherIcon(0));*/ +} + +String OledDisplayClient::zeroPad(int value) { + String rtnValue = String(value); + if (value < 10) { + rtnValue = "0" + rtnValue; + } + return rtnValue; +} diff --git a/printermonitor/OledDisplayClient.h b/printermonitor/OledDisplayClient.h new file mode 100644 index 0000000..a8a9b19 --- /dev/null +++ b/printermonitor/OledDisplayClient.h @@ -0,0 +1,43 @@ +#pragma once +#include +#include +#include "Debug.h" +#include "SH1106Wire.h" +#include "SSD1306Wire.h" +#include "OLEDDisplayUi.h" +#include "PrinterClientInterface.h" +#include "Macros.h" + +class OledDisplayClient { +private: + OLEDDisplay *display; + OLEDDisplayUi *ui; + bool invertDisplay = false; + + FrameCallback frames[3]; + FrameCallback clockFrame[2]; + boolean isClockOn = false; + + OverlayCallback overlays[1]; + OverlayCallback clockOverlay[1]; + + PrinterClientInterface *printerClient; + +public: + OledDisplayClient(byte sdaPin, byte sclPin, byte i2cAddress, bool isSh1106, bool invertDisplay, PrinterClientInterface *printerClient); + void postSetup(); + + void showPageInit(String printerTypeName, String softwareVersion); + void showPageApMode(String protalSsid); + void showPageWeather(); + void showPagePrinter(); + +private: + void drawScreen1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); + void drawScreen2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); + void drawScreen3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); + void drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); + void drawWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); + + String zeroPad(int value); +}; diff --git a/printermonitor/OpenWeatherMapClient.cpp b/printermonitor/OpenWeatherMapClient.cpp index e3c7874..415cc5d 100644 --- a/printermonitor/OpenWeatherMapClient.cpp +++ b/printermonitor/OpenWeatherMapClient.cpp @@ -1,311 +1,312 @@ -/** The MIT License (MIT) - -Copyright (c) 2018 David Payne - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "OpenWeatherMapClient.h" - -OpenWeatherMapClient::OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric, String language) { - updateCityIdList(CityIDs, cityCount); - updateLanguage(language); - myApiKey = ApiKey; - setMetric(isMetric); -} - -void OpenWeatherMapClient::updateWeatherApiKey(String ApiKey) { - myApiKey = ApiKey; -} - -void OpenWeatherMapClient::updateLanguage(String language) { - lang = language; - if (lang == "") { - lang = "en"; - } -} - -void OpenWeatherMapClient::updateWeather() { - WiFiClient weatherClient; - String apiGetData = "GET /data/2.5/group?id=" + myCityIDs + "&units=" + units + "&cnt=1&APPID=" + myApiKey + "&lang=" + lang + " HTTP/1.1"; - - Serial.println("Getting Weather Data"); - Serial.println(apiGetData); - result = ""; - if (weatherClient.connect(servername, 80)) { //starts client connection, checks for connection - weatherClient.println(apiGetData); - weatherClient.println("Host: " + String(servername)); - weatherClient.println("User-Agent: ArduinoWiFi/1.1"); - weatherClient.println("Connection: close"); - weatherClient.println(); - } - else { - Serial.println("connection for weather data failed"); //error message if no client connect - Serial.println(); - return; - } - - while(weatherClient.connected() && !weatherClient.available()) delay(1); //waits for data - - Serial.println("Waiting for data"); - - // Check HTTP status - char status[32] = {0}; - weatherClient.readBytesUntil('\r', status, sizeof(status)); - Serial.println("Response Header: " + String(status)); - if (strcmp(status, "HTTP/1.1 200 OK") != 0) { - Serial.print(F("Unexpected response: ")); - Serial.println(status); - return; - } - - // Skip HTTP headers - char endOfHeaders[] = "\r\n\r\n"; - if (!weatherClient.find(endOfHeaders)) { - Serial.println(F("Invalid response")); - return; - } - - const size_t bufferSize = 710; - DynamicJsonBuffer jsonBuffer(bufferSize); - - weathers[0].cached = false; - weathers[0].error = ""; - // Parse JSON object - JsonObject& root = jsonBuffer.parseObject(weatherClient); - if (!root.success()) { - Serial.println(F("Weather Data Parsing failed!")); - weathers[0].error = "Weather Data Parsing failed!"; - return; - } - - weatherClient.stop(); //stop client - - if (root.measureLength() <= 150) { - Serial.println("Error Does not look like we got the data. Size: " + String(root.measureLength())); - weathers[0].cached = true; - weathers[0].error = (const char*)root["message"]; - Serial.println("Error: " + weathers[0].error); - return; - } - int count = root["cnt"]; - - for (int inx = 0; inx < count; inx++) { - weathers[inx].lat = (const char*)root["list"][inx]["coord"]["lat"]; - weathers[inx].lon = (const char*)root["list"][inx]["coord"]["lon"]; - weathers[inx].dt = (const char*)root["list"][inx]["dt"]; - weathers[inx].city = (const char*)root["list"][inx]["name"]; - weathers[inx].country = (const char*)root["list"][inx]["sys"]["country"]; - weathers[inx].temp = (const char*)root["list"][inx]["main"]["temp"]; - weathers[inx].humidity = (const char*)root["list"][inx]["main"]["humidity"]; - weathers[inx].condition = (const char*)root["list"][inx]["weather"][0]["main"]; - weathers[inx].wind = (const char*)root["list"][inx]["wind"]["speed"]; - weathers[inx].weatherId = (const char*)root["list"][inx]["weather"][0]["id"]; - weathers[inx].description = (const char*)root["list"][inx]["weather"][0]["description"]; - weathers[inx].icon = (const char*)root["list"][inx]["weather"][0]["icon"]; - - Serial.println("lat: " + weathers[inx].lat); - Serial.println("lon: " + weathers[inx].lon); - Serial.println("dt: " + weathers[inx].dt); - Serial.println("city: " + weathers[inx].city); - Serial.println("country: " + weathers[inx].country); - Serial.println("temp: " + weathers[inx].temp); - Serial.println("humidity: " + weathers[inx].humidity); - Serial.println("condition: " + weathers[inx].condition); - Serial.println("wind: " + weathers[inx].wind); - Serial.println("weatherId: " + weathers[inx].weatherId); - Serial.println("description: " + weathers[inx].description); - Serial.println("icon: " + weathers[inx].icon); - Serial.println(); - - } -} - -String OpenWeatherMapClient::roundValue(String value) { - float f = value.toFloat(); - int rounded = (int)(f+0.5f); - return String(rounded); -} - -void OpenWeatherMapClient::updateCityIdList(int CityIDs[], int cityCount) { - myCityIDs = ""; - for (int inx = 0; inx < cityCount; inx++) { - if (CityIDs[inx] > 0) { - if (myCityIDs != "") { - myCityIDs = myCityIDs + ","; - } - myCityIDs = myCityIDs + String(CityIDs[inx]); - } - } -} - -void OpenWeatherMapClient::setMetric(boolean isMetric) { - if (isMetric) { - units = "metric"; - } else { - units = "imperial"; - } -} - -String OpenWeatherMapClient::getWeatherResults() { - return result; -} - -String OpenWeatherMapClient::getLat(int index) { - return weathers[index].lat; -} - -String OpenWeatherMapClient::getLon(int index) { - return weathers[index].lon; -} - -String OpenWeatherMapClient::getDt(int index) { - return weathers[index].dt; -} - -String OpenWeatherMapClient::getCity(int index) { - return weathers[index].city; -} - -String OpenWeatherMapClient::getCountry(int index) { - return weathers[index].country; -} - -String OpenWeatherMapClient::getTemp(int index) { - return weathers[index].temp; -} - -String OpenWeatherMapClient::getTempRounded(int index) { - return roundValue(getTemp(index)); -} - -String OpenWeatherMapClient::getHumidity(int index) { - return weathers[index].humidity; -} - -String OpenWeatherMapClient::getHumidityRounded(int index) { - return roundValue(getHumidity(index)); -} - -String OpenWeatherMapClient::getCondition(int index) { - return weathers[index].condition; -} - -String OpenWeatherMapClient::getWind(int index) { - return weathers[index].wind; -} - -String OpenWeatherMapClient::getWindRounded(int index) { - return roundValue(getWind(index)); -} - -String OpenWeatherMapClient::getWeatherId(int index) { - return weathers[index].weatherId; -} - -String OpenWeatherMapClient::getDescription(int index) { - return weathers[index].description; -} - -String OpenWeatherMapClient::getIcon(int index) { - return weathers[index].icon; -} - -boolean OpenWeatherMapClient::getCached() { - return weathers[0].cached; -} - -String OpenWeatherMapClient::getMyCityIDs() { - return myCityIDs; -} - -String OpenWeatherMapClient::getError() { - return weathers[0].error; -} - -String OpenWeatherMapClient::getWeatherIcon(int index) -{ - int id = getWeatherId(index).toInt(); - String W = ")"; - switch(id) - { - case 800: W = "B"; break; - case 801: W = "Y"; break; - case 802: W = "H"; break; - case 803: W = "H"; break; - case 804: W = "Y"; break; - - case 200: W = "0"; break; - case 201: W = "0"; break; - case 202: W = "0"; break; - case 210: W = "0"; break; - case 211: W = "0"; break; - case 212: W = "0"; break; - case 221: W = "0"; break; - case 230: W = "0"; break; - case 231: W = "0"; break; - case 232: W = "0"; break; - - case 300: W = "R"; break; - case 301: W = "R"; break; - case 302: W = "R"; break; - case 310: W = "R"; break; - case 311: W = "R"; break; - case 312: W = "R"; break; - case 313: W = "R"; break; - case 314: W = "R"; break; - case 321: W = "R"; break; - - case 500: W = "R"; break; - case 501: W = "R"; break; - case 502: W = "R"; break; - case 503: W = "R"; break; - case 504: W = "R"; break; - case 511: W = "R"; break; - case 520: W = "R"; break; - case 521: W = "R"; break; - case 522: W = "R"; break; - case 531: W = "R"; break; - - case 600: W = "W"; break; - case 601: W = "W"; break; - case 602: W = "W"; break; - case 611: W = "W"; break; - case 612: W = "W"; break; - case 615: W = "W"; break; - case 616: W = "W"; break; - case 620: W = "W"; break; - case 621: W = "W"; break; - case 622: W = "W"; break; - - case 701: W = "M"; break; - case 711: W = "M"; break; - case 721: W = "M"; break; - case 731: W = "M"; break; - case 741: W = "M"; break; - case 751: W = "M"; break; - case 761: W = "M"; break; - case 762: W = "M"; break; - case 771: W = "M"; break; - case 781: W = "M"; break; - - default:break; - } - return W; +/** The MIT License (MIT) + +Copyright (c) 2018 David Payne + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "OpenWeatherMapClient.h" + +OpenWeatherMapClient::OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric, String language, Debug *debugHandle) { + this->debugHandle = debugHandle; + updateCityIdList(CityIDs, cityCount); + updateLanguage(language); + myApiKey = ApiKey; + setMetric(isMetric); +} + +void OpenWeatherMapClient::updateWeatherApiKey(String ApiKey) { + myApiKey = ApiKey; +} + +void OpenWeatherMapClient::updateLanguage(String language) { + lang = language; + if (lang == "") { + lang = "en"; + } +} + +void OpenWeatherMapClient::updateWeather() { + WiFiClient weatherClient; + String apiGetData = "GET /data/2.5/group?id=" + myCityIDs + "&units=" + units + "&cnt=1&APPID=" + myApiKey + "&lang=" + lang + " HTTP/1.1"; + + this->debugHandle->printLn("Getting Weather Data"); + this->debugHandle->printLn(apiGetData); + result = ""; + if (weatherClient.connect(servername, 80)) { //starts client connection, checks for connection + weatherClient.println(apiGetData); + weatherClient.println("Host: " + String(servername)); + weatherClient.println("User-Agent: ArduinoWiFi/1.1"); + weatherClient.println("Connection: close"); + weatherClient.println(); + } + else { + this->debugHandle->printLn("connection for weather data failed"); //error message if no client connect + this->debugHandle->printLn(""); + return; + } + + while(weatherClient.connected() && !weatherClient.available()) delay(1); //waits for data + + this->debugHandle->printLn("Waiting for data"); + + // Check HTTP status + char status[32] = {0}; + weatherClient.readBytesUntil('\r', status, sizeof(status)); + this->debugHandle->printLn("Response Header: " + String(status)); + if (strcmp(status, "HTTP/1.1 200 OK") != 0) { + this->debugHandle->print("Unexpected response: "); + this->debugHandle->printLn(status); + return; + } + + // Skip HTTP headers + char endOfHeaders[] = "\r\n\r\n"; + if (!weatherClient.find(endOfHeaders)) { + this->debugHandle->printLn("Invalid response"); + return; + } + + const size_t bufferSize = 710; + DynamicJsonBuffer jsonBuffer(bufferSize); + + weathers[0].cached = false; + weathers[0].error = ""; + // Parse JSON object + JsonObject& root = jsonBuffer.parseObject(weatherClient); + if (!root.success()) { + this->debugHandle->printLn("Weather Data Parsing failed!"); + weathers[0].error = "Weather Data Parsing failed!"; + return; + } + + weatherClient.stop(); //stop client + + if (root.measureLength() <= 150) { + this->debugHandle->printLn("Error Does not look like we got the data. Size: " + String(root.measureLength())); + weathers[0].cached = true; + weathers[0].error = (const char*)root["message"]; + this->debugHandle->printLn("Error: " + weathers[0].error); + return; + } + int count = root["cnt"]; + + for (int inx = 0; inx < count; inx++) { + weathers[inx].lat = (const char*)root["list"][inx]["coord"]["lat"]; + weathers[inx].lon = (const char*)root["list"][inx]["coord"]["lon"]; + weathers[inx].dt = (const char*)root["list"][inx]["dt"]; + weathers[inx].city = (const char*)root["list"][inx]["name"]; + weathers[inx].country = (const char*)root["list"][inx]["sys"]["country"]; + weathers[inx].temp = (const char*)root["list"][inx]["main"]["temp"]; + weathers[inx].humidity = (const char*)root["list"][inx]["main"]["humidity"]; + weathers[inx].condition = (const char*)root["list"][inx]["weather"][0]["main"]; + weathers[inx].wind = (const char*)root["list"][inx]["wind"]["speed"]; + weathers[inx].weatherId = (const char*)root["list"][inx]["weather"][0]["id"]; + weathers[inx].description = (const char*)root["list"][inx]["weather"][0]["description"]; + weathers[inx].icon = (const char*)root["list"][inx]["weather"][0]["icon"]; + + this->debugHandle->printLn("lat: " + weathers[inx].lat); + this->debugHandle->printLn("lon: " + weathers[inx].lon); + this->debugHandle->printLn("dt: " + weathers[inx].dt); + this->debugHandle->printLn("city: " + weathers[inx].city); + this->debugHandle->printLn("country: " + weathers[inx].country); + this->debugHandle->printLn("temp: " + weathers[inx].temp); + this->debugHandle->printLn("humidity: " + weathers[inx].humidity); + this->debugHandle->printLn("condition: " + weathers[inx].condition); + this->debugHandle->printLn("wind: " + weathers[inx].wind); + this->debugHandle->printLn("weatherId: " + weathers[inx].weatherId); + this->debugHandle->printLn("description: " + weathers[inx].description); + this->debugHandle->printLn("icon: " + weathers[inx].icon); + this->debugHandle->printLn(""); + + } +} + +String OpenWeatherMapClient::roundValue(String value) { + float f = value.toFloat(); + int rounded = (int)(f+0.5f); + return String(rounded); +} + +void OpenWeatherMapClient::updateCityIdList(int CityIDs[], int cityCount) { + myCityIDs = ""; + for (int inx = 0; inx < cityCount; inx++) { + if (CityIDs[inx] > 0) { + if (myCityIDs != "") { + myCityIDs = myCityIDs + ","; + } + myCityIDs = myCityIDs + String(CityIDs[inx]); + } + } +} + +void OpenWeatherMapClient::setMetric(boolean isMetric) { + if (isMetric) { + units = "metric"; + } else { + units = "imperial"; + } +} + +String OpenWeatherMapClient::getWeatherResults() { + return result; +} + +String OpenWeatherMapClient::getLat(int index) { + return weathers[index].lat; +} + +String OpenWeatherMapClient::getLon(int index) { + return weathers[index].lon; +} + +String OpenWeatherMapClient::getDt(int index) { + return weathers[index].dt; +} + +String OpenWeatherMapClient::getCity(int index) { + return weathers[index].city; +} + +String OpenWeatherMapClient::getCountry(int index) { + return weathers[index].country; +} + +String OpenWeatherMapClient::getTemp(int index) { + return weathers[index].temp; +} + +String OpenWeatherMapClient::getTempRounded(int index) { + return roundValue(getTemp(index)); +} + +String OpenWeatherMapClient::getHumidity(int index) { + return weathers[index].humidity; +} + +String OpenWeatherMapClient::getHumidityRounded(int index) { + return roundValue(getHumidity(index)); +} + +String OpenWeatherMapClient::getCondition(int index) { + return weathers[index].condition; +} + +String OpenWeatherMapClient::getWind(int index) { + return weathers[index].wind; +} + +String OpenWeatherMapClient::getWindRounded(int index) { + return roundValue(getWind(index)); +} + +String OpenWeatherMapClient::getWeatherId(int index) { + return weathers[index].weatherId; +} + +String OpenWeatherMapClient::getDescription(int index) { + return weathers[index].description; +} + +String OpenWeatherMapClient::getIcon(int index) { + return weathers[index].icon; +} + +boolean OpenWeatherMapClient::getCached() { + return weathers[0].cached; +} + +String OpenWeatherMapClient::getMyCityIDs() { + return myCityIDs; +} + +String OpenWeatherMapClient::getError() { + return weathers[0].error; +} + +String OpenWeatherMapClient::getWeatherIcon(int index) +{ + int id = getWeatherId(index).toInt(); + String W = ")"; + switch(id) + { + case 800: W = "B"; break; + case 801: W = "Y"; break; + case 802: W = "H"; break; + case 803: W = "H"; break; + case 804: W = "Y"; break; + + case 200: W = "0"; break; + case 201: W = "0"; break; + case 202: W = "0"; break; + case 210: W = "0"; break; + case 211: W = "0"; break; + case 212: W = "0"; break; + case 221: W = "0"; break; + case 230: W = "0"; break; + case 231: W = "0"; break; + case 232: W = "0"; break; + + case 300: W = "R"; break; + case 301: W = "R"; break; + case 302: W = "R"; break; + case 310: W = "R"; break; + case 311: W = "R"; break; + case 312: W = "R"; break; + case 313: W = "R"; break; + case 314: W = "R"; break; + case 321: W = "R"; break; + + case 500: W = "R"; break; + case 501: W = "R"; break; + case 502: W = "R"; break; + case 503: W = "R"; break; + case 504: W = "R"; break; + case 511: W = "R"; break; + case 520: W = "R"; break; + case 521: W = "R"; break; + case 522: W = "R"; break; + case 531: W = "R"; break; + + case 600: W = "W"; break; + case 601: W = "W"; break; + case 602: W = "W"; break; + case 611: W = "W"; break; + case 612: W = "W"; break; + case 615: W = "W"; break; + case 616: W = "W"; break; + case 620: W = "W"; break; + case 621: W = "W"; break; + case 622: W = "W"; break; + + case 701: W = "M"; break; + case 711: W = "M"; break; + case 721: W = "M"; break; + case 731: W = "M"; break; + case 741: W = "M"; break; + case 751: W = "M"; break; + case 761: W = "M"; break; + case 762: W = "M"; break; + case 771: W = "M"; break; + case 781: W = "M"; break; + + default:break; + } + return W; } diff --git a/printermonitor/OpenWeatherMapClient.h b/printermonitor/OpenWeatherMapClient.h index 9a8a44b..7289af8 100644 --- a/printermonitor/OpenWeatherMapClient.h +++ b/printermonitor/OpenWeatherMapClient.h @@ -24,6 +24,7 @@ SOFTWARE. #pragma once #include #include "libs/ArduinoJson/ArduinoJson.h" +#include "Debug.h" class OpenWeatherMapClient { @@ -56,9 +57,11 @@ private: weather weathers[5]; String roundValue(String value); + + Debug *debugHandle; public: - OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric, String language); + OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric, String language, Debug *debugHandle); void updateWeather(); void updateWeatherApiKey(String ApiKey); void updateCityIdList(int CityIDs[], int cityCount); diff --git a/printermonitor/PrinterClientInterface.h b/printermonitor/PrinterClientInterface.h new file mode 100644 index 0000000..ec5d82f --- /dev/null +++ b/printermonitor/PrinterClientInterface.h @@ -0,0 +1,29 @@ +#pragma once + +class PrinterClientInterface { +public: + virtual String getAveragePrintTime() = 0; + virtual String getEstimatedPrintTime() = 0; + virtual String getFileName() = 0; + virtual String getFileSize() = 0; + virtual String getLastPrintTime() = 0; + virtual String getProgressCompletion() = 0; + virtual String getProgressFilepos() = 0; + virtual String getProgressPrintTime() = 0; + virtual String getProgressPrintTimeLeft() = 0; + virtual String getState() = 0; + virtual boolean isPrinting() = 0; + virtual boolean isOperational() = 0; + virtual boolean isPSUoff() = 0; + virtual String getTempBedActual() = 0; + virtual String getTempBedTarget() = 0; + virtual String getTempToolActual() = 0; + virtual String getTempToolTarget() = 0; + virtual String getFilamentLength() = 0; + virtual String getValueRounded(String value) = 0; + virtual String getError() = 0; + virtual String getPrinterType() = 0; + virtual int getPrinterPort() = 0; + virtual String getPrinterName() = 0; + virtual void setPrinterName(String printer) = 0; +}; diff --git a/printermonitor/RepetierClient.cpp b/printermonitor/RepetierClient.cpp index e547916..c8c6126 100644 --- a/printermonitor/RepetierClient.cpp +++ b/printermonitor/RepetierClient.cpp @@ -27,7 +27,8 @@ SOFTWARE. #include "RepetierClient.h" -RepetierClient::RepetierClient(String ApiKey, String server, int port, String user, String pass, boolean psu) { +RepetierClient::RepetierClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle) { + this->debugHandle = debugHandle; updatePrintClient(ApiKey, server, port, user, pass, psu); } @@ -63,8 +64,8 @@ WiFiClient RepetierClient::getSubmitRequest(String apiGetData) { WiFiClient printClient; printClient.setTimeout(5000); - Serial.println("Getting Repetier Data via GET"); - Serial.println(apiGetData); + this->debugHandle->printLn("Getting Repetier Data via GET"); + this->debugHandle->printLn(apiGetData); result = ""; if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection printClient.println(apiGetData); @@ -77,40 +78,20 @@ WiFiClient RepetierClient::getSubmitRequest(String apiGetData) { printClient.println("User-Agent: ArduinoWiFi/1.1"); printClient.println("Connection: close"); if (printClient.println() == 0) { - Serial.println("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); - Serial.println(); + this->debugHandle->printLn("Connection to " + String(myServer) + ":" + String(myPort) + " failed."); + this->debugHandle->printLn(""); resetPrintData(); printerData.error = "Connection to " + String(myServer) + ":" + String(myPort) + " failed."; return printClient; } } else { - Serial.println("Connection to Repetier failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect - Serial.println(); + this->debugHandle->printLn("Connection to Repetier failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect + this->debugHandle->printLn(""); resetPrintData(); printerData.error = "Connection to Repetier failed: " + String(myServer) + ":" + String(myPort); return printClient; } -/* - // Check HTTP status - char status[32] = {0}; - printClient.readBytesUntil('\r', status, sizeof(status)); - if (strcmp(status, "HTTP/1.1 200 OK") != 0) { - Serial.print(F("Unexpected response: ")); - Serial.println(status); - printerData.state = ""; - printerData.error = "Response: " + String(status); - return printClient; - } - - // Skip HTTP headers - char endOfHeaders[] = "\r\n\r\n"; - if (!printClient.find(endOfHeaders)) { - Serial.println(F("Invalid response")); - printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort); - printerData.state = ""; - } -*/ return printClient; } @@ -133,16 +114,16 @@ void RepetierClient::getPrinterJobResults() { if (!root.success()) { printerData.error = "Repetier Data Parsing failed: " + String(myServer) + ":" + String(myPort); - Serial.println(printerData.error); + this->debugHandle->printLn(printerData.error); printerData.state = ""; return; } int inx = 0; int count = root.size(); - Serial.println("Size of root: " + String(count)); + this->debugHandle->printLn("Size of root: " + String(count)); for (int i = 0; i < count; i++) { - Serial.println("Printer: " + String((const char*)root[i]["slug"])); + this->debugHandle->printLn("Printer: " + String((const char*)root[i]["slug"])); if (String((const char*)root[i]["slug"]) == printerData.printerName) { inx = i; break; @@ -182,13 +163,13 @@ void RepetierClient::getPrinterJobResults() { } if (printerData.isPrinting) { - Serial.println("Printing: " + printerData.fileName); + this->debugHandle->printLn("Printing: " + printerData.fileName); } if (isOperational()) { - Serial.println("Status: " + printerData.state); + this->debugHandle->printLn("Status: " + printerData.state); } else { - Serial.println("Printer Not Operational"); + this->debugHandle->printLn("Printer Not Operational"); } //**** get the Printer Temps and Stat @@ -221,7 +202,7 @@ void RepetierClient::getPrinterJobResults() { printerData.bedTargetTemp = (const char*) pr2["heatedBeds"][0]["tempSet"]; if (printerData.isPrinting) { - Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); + this->debugHandle->printLn("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); } } diff --git a/printermonitor/RepetierClient.h b/printermonitor/RepetierClient.h index 7c92105..06d8bf4 100644 --- a/printermonitor/RepetierClient.h +++ b/printermonitor/RepetierClient.h @@ -28,8 +28,10 @@ SOFTWARE. #include #include "libs/ArduinoJson/ArduinoJson.h" #include +#include "Debug.h" +#include "PrinterClientInterface.h" -class RepetierClient { +class RepetierClient : public PrinterClientInterface { private: char myServer[100]; @@ -69,10 +71,10 @@ private: } PrinterStruct; PrinterStruct printerData; - + Debug *debugHandle; public: - RepetierClient(String ApiKey, String server, int port, String user, String pass, boolean psu); + RepetierClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle); void getPrinterJobResults(); void getPrinterPsuState(); void updatePrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu); diff --git a/printermonitor/Settings.h b/printermonitor/Settings.h index b40cee5..d8e46d3 100644 --- a/printermonitor/Settings.h +++ b/printermonitor/Settings.h @@ -1,23 +1,3 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - /** The MIT License (MIT) Copyright (c) 2018 David Payne @@ -59,34 +39,19 @@ SOFTWARE. * the Web Interface. ******************************************************************************/ -#include -#include -#include -#include -#include -#include -#include "TimeClient.h" -#include "KlipperClient.h" -#include "DuetClient.h" -#include "RepetierClient.h" -#include "OctoPrintClient.h" -#include "OpenWeatherMapClient.h" -#include "WeatherStationFonts.h" -#include "FS.h" -#include "SH1106Wire.h" -#include "SSD1306Wire.h" -#include "OLEDDisplayUi.h" +#ifndef __SETTINGS_H__ +#define __SETTINGS_H__ //****************************** // Start Settings //****************************** // ESP32/ESP8266 compatibility! -//#define USE_ESP8266 +#define USE_ESP8266 // OctoPrint / Repetier / Klipper/ Duet Monitoring -- Monitor your 3D OctoPrint or Repetier Server -#define USE_DUET_CLIENT // Uncomment this line to use the Duet Printer Server -- OctoPrint is used by default and is most common -//#define USE_KLIPPER_CLIENT // Uncomment this line to use the Duet Printer Server -- OctoPrint is used by default and is most common +//#define USE_DUET_CLIENT // Uncomment this line to use the Duet Printer Server -- OctoPrint is used by default and is most common +#define USE_KLIPPER_CLIENT // Uncomment this line to use the Duet Printer Server -- OctoPrint is used by default and is most common //#define USE_REPETIER_CLIENT // Uncomment this line to use the Repetier Printer Server -- OctoPrint is used by default and is most common String PrinterApiKey = ""; // ApiKey from your User Account on OctoPrint / Repetier @@ -121,18 +86,25 @@ boolean DISPLAYCLOCK = true; // true = Show Clock when not printing / false = // Display Settings #define USE_NEXTION_DISPLAY #ifdef USE_NEXTION_DISPLAY + #ifdef USE_ESP8266 + const int TX_PIN = 5; + const int RX_PIN = 4; + #else + const int TX_PIN = D1; + const int RX_PIN = D2; + #endif #else const int I2C_DISPLAY_ADDRESS = 0x3c; // I2C Address of your Display (usually 0x3c or 0x3d) #ifdef USE_ESP8266 - const int SDA_PIN = 21; - const int SCL_PIN = 22; // original code D5 -- Monitor Easy Board use D1 + const int SDA_PIN = 5; + const int SCL_PIN = 4; // original code D5 -- Monitor Easy Board use D1 #else const int SDA_PIN = D1; const int SCL_PIN = D2; // original code D5 -- Monitor Easy Board use D1 #endif - boolean INVERT_DISPLAY = true; // true = pins at top | false = pins at the bottom - //#define DISPLAY_SH1106 // Uncomment this line to use the SH1106 display -- SSD1306 is used by default and is most common + boolean INVERT_DISPLAY = true; // true = pins at top | false = pins at the bottom + boolean DISPLAY_SH1106 = false; // true = to use the SH1106 display | false = SSD1306 is used by default and is most common #endif // LED Settings @@ -151,3 +123,8 @@ String OTA_Password = ""; // Set an OTA password here -- leave blank if you //****************************** String themeColor = "light-green"; // this can be changed later in the web interface. +#define HOSTNAME "PrintMon-" +#define CONFIG "/conf.txt" +#define VERSION "4.0" + +#endif diff --git a/printermonitor/TimeClient.cpp b/printermonitor/TimeClient.cpp index b0753e0..c2b166b 100644 --- a/printermonitor/TimeClient.cpp +++ b/printermonitor/TimeClient.cpp @@ -1,152 +1,158 @@ -/**The MIT License (MIT) - -Copyright (c) 2015 by Daniel Eichhorn - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -/* -Modified by David Payne for use in the Scrolling Marquee -*/ - -#include "TimeClient.h" - -TimeClient::TimeClient(float utcOffset) { - myUtcOffset = utcOffset; -} - -void TimeClient::updateTime() { - WiFiClient client; - - if (!client.connect(ntpServerName, httpPort)) { - Serial.println("connection failed"); - return; - } - - // This will send the request to the server - client.print(String("GET / HTTP/1.1\r\n") + - String("Host: www.google.com\r\n") + - String("Connection: close\r\n\r\n")); - int repeatCounter = 0; - while(!client.available() && repeatCounter < 10) { - delay(1000); - Serial.println("."); - repeatCounter++; - } - - String line; - - int size = 0; - client.setNoDelay(false); - while(client.connected()) { - while((size = client.available()) > 0) { - line = client.readStringUntil('\n'); - line.toUpperCase(); - // example: - // date: Thu, 19 Nov 2015 20:25:40 GMT - if (line.startsWith("DATE: ")) { - Serial.println(line.substring(23, 25) + ":" + line.substring(26, 28) + ":" +line.substring(29, 31)); - int parsedHours = line.substring(23, 25).toInt(); - int parsedMinutes = line.substring(26, 28).toInt(); - int parsedSeconds = line.substring(29, 31).toInt(); - Serial.println(String(parsedHours) + ":" + String(parsedMinutes) + ":" + String(parsedSeconds)); - - localEpoc = (parsedHours * 60 * 60 + parsedMinutes * 60 + parsedSeconds); - Serial.println(localEpoc); - localMillisAtUpdate = millis(); - client.stop(); - } - } - } - -} - -void TimeClient::setUtcOffset(float utcOffset) { - myUtcOffset = utcOffset; -} - -String TimeClient::getHours() { - if (localEpoc == 0) { - return "--"; - } - int hours = ((getCurrentEpochWithUtcOffset() % 86400L) / 3600) % 24; - if (hours < 10) { - return "0" + String(hours); - } - return String(hours); // print the hour (86400 equals secs per day) - -} -String TimeClient::getMinutes() { - if (localEpoc == 0) { - return "--"; - } - int minutes = ((getCurrentEpochWithUtcOffset() % 3600) / 60); - if (minutes < 10 ) { - // In the first 10 minutes of each hour, we'll want a leading '0' - return "0" + String(minutes); - } - return String(minutes); -} -String TimeClient::getSeconds() { - if (localEpoc == 0) { - return "--"; - } - int seconds = getCurrentEpochWithUtcOffset() % 60; - if ( seconds < 10 ) { - // In the first 10 seconds of each minute, we'll want a leading '0' - return "0" + String(seconds); - } - return String(seconds); -} - -String TimeClient::getAmPmHours() { - int hours = getHours().toInt(); - if (hours >= 13) { - hours = hours - 12; - } - if (hours == 0) { - hours = 12; - } - return String(hours); -} - -String TimeClient::getAmPm() { - int hours = getHours().toInt(); - String ampmValue = "AM"; - if (hours >= 12) { - ampmValue = "PM"; - } - return ampmValue; -} - -String TimeClient::getFormattedTime() { - return getHours() + ":" + getMinutes() + ":" + getSeconds(); -} - -String TimeClient::getAmPmFormattedTime() { - return getAmPmHours() + ":" + getMinutes() + " " + getAmPm(); -} - -long TimeClient::getCurrentEpoch() { - return localEpoc + ((millis() - localMillisAtUpdate) / 1000); -} - -long TimeClient::getCurrentEpochWithUtcOffset() { - return (long)round(getCurrentEpoch() + 3600 * myUtcOffset + 86400L) % 86400L; +/**The MIT License (MIT) + +Copyright (c) 2015 by Daniel Eichhorn + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/* +Modified by David Payne for use in the Scrolling Marquee +*/ + +#include "TimeClient.h" + +TimeClient::TimeClient(float utcOffset, boolean is24Hour, Debug *debugHandle) { + this->debugHandle = debugHandle; + this->myUtcOffset = utcOffset; + this->is24Hour = is24Hour; +} + +void TimeClient::updateTime() { + WiFiClient client; + + if (!client.connect(ntpServerName, httpPort)) { + this->debugHandle->printLn("connection failed"); + return; + } + + // This will send the request to the server + client.print(String("GET / HTTP/1.1\r\n") + + String("Host: www.google.com\r\n") + + String("Connection: close\r\n\r\n")); + int repeatCounter = 0; + while(!client.available() && repeatCounter < 10) { + delay(1000); + this->debugHandle->printLn("."); + repeatCounter++; + } + + String line; + + int size = 0; + client.setNoDelay(false); + while(client.connected()) { + while((size = client.available()) > 0) { + line = client.readStringUntil('\n'); + line.toUpperCase(); + // example: + // date: Thu, 19 Nov 2015 20:25:40 GMT + if (line.startsWith("DATE: ")) { + this->debugHandle->printLn(line.substring(23, 25) + ":" + line.substring(26, 28) + ":" +line.substring(29, 31)); + int parsedHours = line.substring(23, 25).toInt(); + int parsedMinutes = line.substring(26, 28).toInt(); + int parsedSeconds = line.substring(29, 31).toInt(); + this->debugHandle->printLn(String(parsedHours) + ":" + String(parsedMinutes) + ":" + String(parsedSeconds)); + + localEpoc = (parsedHours * 60 * 60 + parsedMinutes * 60 + parsedSeconds); + this->debugHandle->printLn(localEpoc); + localMillisAtUpdate = millis(); + client.stop(); + } + } + } + +} + +void TimeClient::setUtcOffset(float utcOffset) { + myUtcOffset = utcOffset; +} + +String TimeClient::getHours() { + if (localEpoc == 0) { + return "--"; + } + int hours = ((getCurrentEpochWithUtcOffset() % 86400L) / 3600) % 24; + if (hours < 10) { + return "0" + String(hours); + } + return String(hours); // print the hour (86400 equals secs per day) + +} +String TimeClient::getMinutes() { + if (localEpoc == 0) { + return "--"; + } + int minutes = ((getCurrentEpochWithUtcOffset() % 3600) / 60); + if (minutes < 10 ) { + // In the first 10 minutes of each hour, we'll want a leading '0' + return "0" + String(minutes); + } + return String(minutes); +} +String TimeClient::getSeconds() { + if (localEpoc == 0) { + return "--"; + } + int seconds = getCurrentEpochWithUtcOffset() % 60; + if ( seconds < 10 ) { + // In the first 10 seconds of each minute, we'll want a leading '0' + return "0" + String(seconds); + } + return String(seconds); +} + +String TimeClient::getAmPmHours() { + int hours = getHours().toInt(); + if (hours >= 13) { + hours = hours - 12; + } + if (hours == 0) { + hours = 12; + } + return String(hours); +} + +String TimeClient::getAmPm() { + int hours = getHours().toInt(); + String ampmValue = "AM"; + if (hours >= 12) { + ampmValue = "PM"; + } + return ampmValue; +} + +String TimeClient::getFormattedTime() { + return getHours() + ":" + getMinutes() + ":" + getSeconds(); +} + +String TimeClient::getAmPmFormattedTime() { + return getAmPmHours() + ":" + getMinutes() + " " + getAmPm(); +} + +long TimeClient::getCurrentEpoch() { + return localEpoc + ((millis() - localMillisAtUpdate) / 1000); +} + +long TimeClient::getCurrentEpochWithUtcOffset() { + return (long)round(getCurrentEpoch() + 3600 * myUtcOffset + 86400L) % 86400L; +} + +boolean TimeClient::isHour24() { + return this->is24Hour; } diff --git a/printermonitor/TimeClient.h b/printermonitor/TimeClient.h index dee7601..9c69b48 100644 --- a/printermonitor/TimeClient.h +++ b/printermonitor/TimeClient.h @@ -30,6 +30,7 @@ Modified by David Payne for use in the Scrolling Marquee #pragma once #include +#include "Debug.h" #define NTP_PACKET_SIZE 48 @@ -42,9 +43,11 @@ class TimeClient { const char* ntpServerName = "www.google.com"; const int httpPort = 80; byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets - + bool is24Hour; + Debug *debugHandle; + public: - TimeClient(float utcOffset); + TimeClient(float utcOffset, boolean is24Hour, Debug *debugHandle); void updateTime(); void setUtcOffset(float utcOffset); @@ -57,6 +60,6 @@ class TimeClient { String getAmPmFormattedTime(); long getCurrentEpoch(); long getCurrentEpochWithUtcOffset(); + boolean isHour24(); }; - diff --git a/printermonitor/WebConstants.h b/printermonitor/WebConstants.h new file mode 100644 index 0000000..ad151f9 --- /dev/null +++ b/printermonitor/WebConstants.h @@ -0,0 +1,94 @@ +#pragma once + +static const char WEB_ACTIONS[] PROGMEM = " Home" + " Configure" + " Weather" + " Reset Settings" + " Forget WiFi" + " Firmware Update" + " About"; + +String CHANGE_FORM = ""; // moved to config to make it dynamic + +static const char CLOCK_FORM[] PROGMEM = "

Display Clock when printer is off

" + "

Use 24 Hour Clock (military time)

" + "

Flip display orientation

" + "

Flash System LED on Service Calls

" + "

Use OctoPrint PSU control plugin for clock/blank

" + "

Clock Sync / Weather Refresh (minutes)

"; + +static const char THEME_FORM[] PROGMEM = "

Theme Color

" + "


" + "

Use Security Credentials for Configuration Changes

" + "

" + "

" + ""; + +static const char WEATHER_FORM[] PROGMEM = "

Weather Config:

" + "

Display Weather when printer is off

" + "" + "" + "

" + "

Use Metric (Celsius)

" + "

Weather Language

" + "
" + ""; + +static const char LANG_OPTIONS[] PROGMEM = "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; + +static const char COLOR_THEMES[] PROGMEM = "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; diff --git a/printermonitor/WebServer.cpp b/printermonitor/WebServer.cpp new file mode 100644 index 0000000..0b617f7 --- /dev/null +++ b/printermonitor/WebServer.cpp @@ -0,0 +1,349 @@ +#include "WebServer.h" + +static const char WEB_ACTIONS[] PROGMEM = " Home" + " Configure" + " Weather" + " Reset Settings" + " Forget WiFi" + " Firmware Update" + " About"; + +static const char CLOCK_FORM[] PROGMEM = "

Display Clock when printer is off

" + "

Use 24 Hour Clock (military time)

" + "

Flip display orientation

" + "

Flash System LED on Service Calls

" + "

Use OctoPrint PSU control plugin for clock/blank

" + "

Clock Sync / Weather Refresh (minutes)

"; + +static const char THEME_FORM[] PROGMEM = "

Theme Color

" + "


" + "

Use Security Credentials for Configuration Changes

" + "

" + "

" + ""; + +static const char WEATHER_FORM[] PROGMEM = "

Weather Config:

" + "

Display Weather when printer is off

" + "" + "" + "

" + "

Use Metric (Celsius)

" + "

Weather Language

" + "
" + ""; + +static const char LANG_OPTIONS[] PROGMEM = "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; + +static const char COLOR_THEMES[] PROGMEM = "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; + +WebServer::WebServer(ESP8266WebServer *serverHandle, Debug *debugHandle, PrinterClientInterface *printerClient, TimeClient *timeClient, String themeColor, String swVersion, boolean hasPsu) { + this->serverHandle = serverHandle; + this->themeColor = themeColor; + this->debugHandle = debugHandle; + this->swVersion = swVersion; + this->printerClient = printerClient; + this->timeClient = timeClient; + this->hostName = ""; + this->hasPsu = hasPsu; + this->isBasicAuth = false; + this->wwwUsername = ""; + this->wwwPassword = ""; +} + +void WebServer::setHostname(String hostName) { + this->hostName = hostName; +} + +void WebServer::redirectHome() { + // Send them back to the Root Directory + this->serverHandle->sendHeader("Location", String("/"), true); + this->serverHandle->sendHeader("Cache-Control", "no-cache, no-store"); + this->serverHandle->sendHeader("Pragma", "no-cache"); + this->serverHandle->sendHeader("Expires", "-1"); + this->serverHandle->send(302, "text/plain", ""); + this->serverHandle->client().stop(); +} + +String WebServer::getHeader() { + return this->getHeader(false); +} + +String WebServer::getHeader(boolean refresh) { + String menu = FPSTR(WEB_ACTIONS); + + String html = ""; + html += "Printer Monitor"; + html += ""; + html += ""; + if (refresh) { + html += ""; + } + html += ""; + html += ""; + html += ""; + html += ""; + html += ""; + html += "

Printer Monitor

"; + html += ""; + html += "
"; + return html; +} + +String WebServer::getFooter() { + int8_t rssi = this->getWifiQuality(); + this->debugHandle->print("Signal Strength (RSSI): "); + this->debugHandle->print(rssi); + this->debugHandle->printLn("%"); + String html = "


"; + html += "
"; + html += "
"; + if (this->lastReportStatus != "") { + html += " Report Status: " + this->lastReportStatus + "
"; + } + html += " Version: " + this->swVersion + "
"; + html += " Signal Strength: "; + html += String(rssi) + "%"; + html += "
"; + html += ""; + return html; +} + +void WebServer::displayPrinterStatus() { + String html = ""; + + this->serverHandle->sendHeader("Cache-Control", "no-cache, no-store"); + this->serverHandle->sendHeader("Pragma", "no-cache"); + this->serverHandle->sendHeader("Expires", "-1"); + this->serverHandle->setContentLength(CONTENT_LENGTH_UNKNOWN); + this->serverHandle->send(200, "text/html", ""); + this->serverHandle->sendContent(String(this->getHeader(true))); + + String displayTime = this->timeClient->getAmPmHours() + ":" + this->timeClient->getMinutes() + ":" + this->timeClient->getSeconds() + " " + this->timeClient->getAmPm(); + if (this->timeClient->isHour24()) { + displayTime = this->timeClient->getHours() + ":" + this->timeClient->getMinutes() + ":" + this->timeClient->getSeconds(); + } + + html += "

" + this->printerClient->getPrinterType() + " Monitor

"; + html += "

"; + if (this->printerClient->getPrinterType() == "Repetier") { + html += "Printer Name: " + this->printerClient->getPrinterName() + "
"; + } else { + html += "Host Name: " + this->hostName + "
"; + } + + if (this->printerClient->getError() != "") { + html += "Status: Offline
"; + html += "Reason: " + this->printerClient->getError() + "
"; + } else { + html += "Status: " + this->printerClient->getState(); + if (this->printerClient->isPSUoff() && this->hasPsu) { + html += ", PSU off"; + } + html += "
"; + } + + if (this->printerClient->isPrinting()) { + html += "File: " + this->printerClient->getFileName() + "
"; + float fileSize = this->printerClient->getFileSize().toFloat(); + if (fileSize > 0) { + fileSize = fileSize / 1024; + html += "File Size: " + String(fileSize) + "KB
"; + } + int filamentLength = this->printerClient->getFilamentLength().toInt(); + if (filamentLength > 0) { + float fLength = float(filamentLength) / 1000; + html += "Filament: " + String(fLength) + "m
"; + } + + html += "Tool Temperature: " + this->printerClient->getTempToolActual() + "° C
"; + if ( this->printerClient->getTempBedActual() != 0 ) { + html += "Bed Temperature: " + this->printerClient->getTempBedActual() + "° C
"; + } + + int val = this->printerClient->getProgressPrintTimeLeft().toInt(); + int hours = numberOfHours(val); + int minutes = numberOfMinutes(val); + int seconds = numberOfSeconds(val); + html += "Est. Print Time Left: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "
"; + + val = this->printerClient->getProgressPrintTime().toInt(); + hours = numberOfHours(val); + minutes = numberOfMinutes(val); + seconds = numberOfSeconds(val); + html += "Printing Time: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "
"; + html += ""; + html += "

" + this->printerClient->getProgressCompletion() + "%
"; + } else { + html += "
"; + } + + html += "

"; + + html += "

Time: " + displayTime + "

"; + + this->serverHandle->sendContent(html); // spit out what we got + html = ""; + + /* + if (DISPLAYWEATHER) { + if (weatherClient.getCity(0) == "") { + html += "

Please Configure Weather API

"; + if (weatherClient.getError() != "") { + html += "

Weather Error: " + weatherClient.getError() + "

"; + } + } else { + html += "

" + weatherClient.getCity(0) + ", " + weatherClient.getCountry(0) + "

"; + html += "
"; + html += "" + weatherClient.getDescription(0) + "
"; + html += weatherClient.getHumidity(0) + "% Humidity
"; + html += weatherClient.getWind(0) + " " + getSpeedSymbol() + " Wind
"; + html += "
"; + html += "

"; + html += weatherClient.getCondition(0) + " (" + weatherClient.getDescription(0) + ")
"; + html += weatherClient.getTempRounded(0) + getTempSymbol(true) + "
"; + html += " Map It!
"; + html += "

"; + } + + this->serverHandle->sendContent(html); // spit out what we got + html = ""; // fresh start + }*/ + + this->serverHandle->sendContent(String(getFooter())); + this->serverHandle->sendContent(""); + this->serverHandle->client().stop(); +} + + +void WebServer::displayMessage(String message) { + this->serverHandle->sendHeader("Cache-Control", "no-cache, no-store"); + this->serverHandle->sendHeader("Pragma", "no-cache"); + this->serverHandle->sendHeader("Expires", "-1"); + this->serverHandle->setContentLength(CONTENT_LENGTH_UNKNOWN); + this->serverHandle->send(200, "text/html", ""); + String html = this->getHeader(); + this->serverHandle->sendContent(String(html)); + this->serverHandle->sendContent(String(message)); + html = this->getFooter(); + this->serverHandle->sendContent(String(html)); + this->serverHandle->sendContent(""); + this->serverHandle->client().stop(); +} + +void WebServer::setAuthentication(boolean enableBasicAuth, char *username, char *password) { + this->isBasicAuth = enableBasicAuth; + this->wwwUsername = username; + this->wwwPassword = password; +} + +boolean WebServer::authentication() { + if (this->isBasicAuth && (strlen(this->wwwUsername) >= 1 && strlen(this->wwwPassword) >= 1)) { + return this->serverHandle->authenticate(this->wwwUsername, this->wwwPassword); + } + return true; // Authentication not required +} + +void WebServer::handleWifiReset() { + if (!this->authentication()) { + return this->serverHandle->requestAuthentication(); + } + //WiFiManager + //Local intialization. Once its business is done, there is no need to keep it around + this->redirectHome(); + WiFiManager wifiManager; + wifiManager.resetSettings(); + ESP.restart(); +} + +void WebServer::handleSystemReset() { + if (!this->authentication()) { + return this->serverHandle->requestAuthentication(); + } + this->debugHandle->printLn("Reset System Configuration"); + //if (SPIFFS.remove(CONFIG)) { + this->redirectHome(); + ESP.restart(); + //} +} + +int8_t WebServer::getWifiQuality() { + int32_t dbm = WiFi.RSSI(); + if(dbm <= -100) { + return 0; + } else if(dbm >= -50) { + return 100; + } else { + return 2 * (dbm + 100); + } +} + +String WebServer::zeroPad(int value) { + String rtnValue = String(value); + if (value < 10) { + rtnValue = "0" + rtnValue; + } + return rtnValue; +} diff --git a/printermonitor/WebServer.h b/printermonitor/WebServer.h new file mode 100644 index 0000000..e7c37ed --- /dev/null +++ b/printermonitor/WebServer.h @@ -0,0 +1,45 @@ +#pragma once +#include +#include +#include +#include "Debug.h" +#include "PrinterClientInterface.h" +#include "TimeClient.h" +#include "Macros.h" + +class WebServer { +private: + ESP8266WebServer *serverHandle; + String themeColor; + Debug *debugHandle; + String lastReportStatus; + String swVersion; + String hostName; + TimeClient *timeClient; + PrinterClientInterface *printerClient; + boolean hasPsu; + + boolean isBasicAuth; + char *wwwUsername; + char *wwwPassword; + +public: + WebServer(ESP8266WebServer *serverHandle, Debug *debugHandle, PrinterClientInterface *printerClient, TimeClient *timeClient, String themeColor, String swVersion, boolean hasPsu); + + void setHostname(String hostName); + + void redirectHome(); + String getHeader(); + String getHeader(boolean refresh); + String getFooter(); + + void displayPrinterStatus(); + void displayMessage(String message); + + void setAuthentication(boolean enableBasicAuth, char *username, char *password); + boolean authentication(); + void handleSystemReset(); + void handleWifiReset(); + int8_t getWifiQuality(); + String zeroPad(int value); +}; diff --git a/printermonitor/printermonitor.ino b/printermonitor/printermonitor.ino index e82ca7b..000b758 100644 --- a/printermonitor/printermonitor.ino +++ b/printermonitor/printermonitor.ino @@ -28,57 +28,23 @@ SOFTWARE. /********************************************** * Edit Settings.h for personalization ***********************************************/ - #include "Settings.h" -#define VERSION "3.0" -#define HOSTNAME "PrintMon-" -#define CONFIG "/conf.txt" -/* Useful Constants */ -#define SECS_PER_MIN (60UL) -#define SECS_PER_HOUR (3600UL) -/* Useful Macros for getting elapsed time */ -#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN) -#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN) -#define numberOfHours(_time_) (_time_ / SECS_PER_HOUR) -#if USE_NEXTION_DISPLAY -#else - // Initialize the oled display for I2C_DISPLAY_ADDRESS - // SDA_PIN and SCL_PIN - #if defined(DISPLAY_SH1106) - SH1106Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SCL_PIN); - #else - SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SCL_PIN); // this is the default - #endif - OLEDDisplayUi ui( &display ); - void drawProgress(OLEDDisplay *display, int percentage, String label); - void drawOtaProgress(unsigned int, unsigned int); - void drawScreen1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); - void drawScreen2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); - void drawScreen3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); - void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state); - void drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); - void drawWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); - void drawClockHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state); -#endif -// Set the number of Frames supported -const int numberOfFrames = 3; -FrameCallback frames[numberOfFrames]; -FrameCallback clockFrame[2]; -boolean isClockOn = false; -OverlayCallback overlays[] = { drawHeaderOverlay }; -OverlayCallback clockOverlay[] = { drawClockHeaderOverlay }; -int numberOfOverlays = 1; + +#include "Global.h" + +// Debug output +Debug *debugHandle = new Debug(); // Time -TimeClient timeClient(UtcOffset); +TimeClient timeClient(UtcOffset, IS_24HOUR, debugHandle); long lastEpoch = 0; long firstEpoch = 0; long displayOffEpoch = 0; @@ -89,163 +55,61 @@ boolean displayOn = true; // Printer Client #if defined(USE_REPETIER_CLIENT) - RepetierClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); + RepetierClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU, debugHandle); #elif defined(USE_KLIPPER_CLIENT) - KlipperClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); + KlipperClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU, debugHandle); #elif defined(USE_DUET_CLIENT) - DuetClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); + DuetClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU, debugHandle); #else - OctoPrintClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); + OctoPrintClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU, debugHandle); #endif int printerCount = 0; // Weather Client -OpenWeatherMapClient weatherClient(WeatherApiKey, CityIDs, 1, IS_METRIC, WeatherLanguage); - -//declairing prototypes -void configModeCallback (WiFiManager *myWiFiManager); -int8_t getWifiQuality(); +OpenWeatherMapClient weatherClient(WeatherApiKey, CityIDs, 1, IS_METRIC, WeatherLanguage, debugHandle); +// Webserver ESP8266WebServer server(WEBSERVER_PORT); ESP8266HTTPUpdateServer serverUpdater; +WebServer webServer(&server, debugHandle, &printerClient, &timeClient, themeColor, String(VERSION), HAS_PSU); -static const char WEB_ACTIONS[] PROGMEM = " Home" - " Configure" - " Weather" - " Reset Settings" - " Forget WiFi" - " Firmware Update" - " About"; +// Display +#ifdef USE_NEXTION_DISPLAY + NextionDisplayClient displayHandle(RX_PIN, TX_PIN, &printerClient); +#else + OledDisplayClient displayHandle(SDA_PIN, SCL_PIN, I2C_DISPLAY_ADDRESS, DISPLAY_SH1106, INVERT_DISPLAY, &printerClient); +#endif -String CHANGE_FORM = ""; // moved to config to make it dynamic +//declairing prototypes +void configModeCallback(WiFiManager *myWiFiManager); +int8_t getWifiQuality(); +void flashLED(int number, int delayTime); +void ledOnOff(boolean value); +void readSettings(); +void writeSettings(); -static const char CLOCK_FORM[] PROGMEM = "

Display Clock when printer is off

" - "

Use 24 Hour Clock (military time)

" - "

Flip display orientation

" - "

Flash System LED on Service Calls

" - "

Use OctoPrint PSU control plugin for clock/blank

" - "

Clock Sync / Weather Refresh (minutes)

"; - -static const char THEME_FORM[] PROGMEM = "

Theme Color

" - "


" - "

Use Security Credentials for Configuration Changes

" - "

" - "

" - ""; - -static const char WEATHER_FORM[] PROGMEM = "

Weather Config:

" - "

Display Weather when printer is off

" - "" - "" - "

" - "

Use Metric (Celsius)

" - "

Weather Language

" - "
" - ""; - -static const char LANG_OPTIONS[] PROGMEM = "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - ""; - -static const char COLOR_THEMES[] PROGMEM = "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - ""; - +//************************************************************ +// Setup +//************************************************************ void setup() { - Serial.begin(115200); + debugHandle->initialize(); + webServer.setAuthentication(IS_BASIC_AUTH, www_username, www_password); SPIFFS.begin(); - delay(10); - - //New Line to clear from start garbage - Serial.println(); - + // Initialize digital pin for LED (little blue light on the Wemos D1 Mini) pinMode(externalLight, OUTPUT); - //Some Defaults before loading from Config.txt + // Some Defaults before loading from Config.txt and load PrinterPort = printerClient.getPrinterPort(); - readSettings(); - // initialize display - display.init(); - if (INVERT_DISPLAY) { - display.flipScreenVertically(); // connections at top of OLED display - } - display.clear(); - display.display(); - - //display.flipScreenVertically(); - - display.setTextAlignment(TEXT_ALIGN_CENTER); - display.setContrast(255); // default is 255 - display.setFont(ArialMT_Plain_16); - display.drawString(64, 1, "Printer Monitor"); - display.setFont(ArialMT_Plain_10); - display.drawString(64, 18, "for " + printerClient.getPrinterType()); - display.setFont(ArialMT_Plain_16); - display.drawString(64, 30, "By Qrome"); - display.drawString(64, 46, "V" + String(VERSION)); - display.display(); - - //WiFiManager - //Local intialization. Once its business is done, there is no need to keep it around - WiFiManager wifiManager; + // Show boot screen + displayHandle.showPageInit(printerClient.getPrinterType(), String(VERSION)); - // Uncomment for testing wifi manager - //wifiManager.resetSettings(); + // WiFiManager - Local intialization. Once its business is done, there is no need to keep it around + WiFiManager wifiManager; + //wifiManager.resetSettings(); // Uncomment for testing wifi manager wifiManager.setAPCallback(configModeCallback); String hostname(HOSTNAME); @@ -256,48 +120,32 @@ void setup() { ESP.reset(); delay(5000); } - - // You can change the transition that is used - // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN - ui.setFrameAnimation(SLIDE_LEFT); - ui.setTargetFPS(30); - ui.disableAllIndicators(); - ui.setFrames(frames, (numberOfFrames)); - frames[0] = drawScreen1; - frames[1] = drawScreen2; - frames[2] = drawScreen3; - clockFrame[0] = drawClock; - clockFrame[1] = drawWeather; - ui.setOverlays(overlays, numberOfOverlays); - - // Inital UI takes care of initalising the display too. - ui.init(); - if (INVERT_DISPLAY) { - display.flipScreenVertically(); //connections at top of OLED display - } - - // print the received signal strength: - Serial.print("Signal Strength (RSSI): "); - Serial.print(getWifiQuality()); - Serial.println("%"); + // Display PostSetup + displayHandle.postSetup(); + + // print the received signal strength: + debugHandle->print("Signal Strength (RSSI): "); + debugHandle->print(getWifiQuality()); + debugHandle->printLn("%"); + if (ENABLE_OTA) { ArduinoOTA.onStart([]() { - Serial.println("Start"); + debugHandle->printLn("Start"); }); ArduinoOTA.onEnd([]() { - Serial.println("\nEnd"); + debugHandle->printLn("\nEnd"); }); ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { - Serial.printf("Progress: %u%%\r", (progress / (total / 100))); + debugHandle->printF("Progress: %u%%\r", (progress / (total / 100))); }); ArduinoOTA.onError([](ota_error_t error) { - Serial.printf("Error[%u]: ", error); - if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); - else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); - else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); - else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); - else if (error == OTA_END_ERROR) Serial.println("End Failed"); + debugHandle->printF("Error[%u]: ", error); + if (error == OTA_AUTH_ERROR) debugHandle->printLn("Auth Failed"); + else if (error == OTA_BEGIN_ERROR) debugHandle->printLn("Begin Failed"); + else if (error == OTA_CONNECT_ERROR) debugHandle->printLn("Connect Failed"); + else if (error == OTA_RECEIVE_ERROR) debugHandle->printLn("Receive Failed"); + else if (error == OTA_END_ERROR) debugHandle->printLn("End Failed"); }); ArduinoOTA.setHostname((const char *)hostname.c_str()); if (OTA_Password != "") { @@ -307,102 +155,54 @@ void setup() { } if (WEBSERVER_ENABLED) { - server.on("/", displayPrinterStatus); - server.on("/systemreset", handleSystemReset); - server.on("/forgetwifi", handleWifiReset); - server.on("/updateconfig", handleUpdateConfig); - server.on("/updateweatherconfig", handleUpdateWeather); - server.on("/configure", handleConfigure); - server.on("/configureweather", handleWeatherConfigure); - server.onNotFound(redirectHome); - serverUpdater.setup(&server, "/update", www_username, www_password); + webServer.setHostname(hostname); + server.on("/", []() { webServer.displayPrinterStatus(); }); + server.on("/systemreset", []() { webServer.handleSystemReset(); }); + server.on("/forgetwifi", []() { webServer.handleWifiReset(); }); + //server.on("/updateconfig", handleUpdateConfig); + //server.on("/updateweatherconfig", handleUpdateWeather); + //server.on("/configure", handleConfigure); + //server.on("/configureweather", handleWeatherConfigure); + server.onNotFound([]() { webServer.redirectHome(); }); + //serverUpdater.setup(&server, "/update", www_username, www_password); // Start the server server.begin(); - Serial.println("Server started"); + debugHandle->printLn("Server started"); // Print the IP address String webAddress = "http://" + WiFi.localIP().toString() + ":" + String(WEBSERVER_PORT) + "/"; - Serial.println("Use this URL : " + webAddress); - display.clear(); - display.setTextAlignment(TEXT_ALIGN_CENTER); - display.setFont(ArialMT_Plain_10); - display.drawString(64, 10, "Web Interface On"); - display.drawString(64, 20, "You May Connect to IP"); - display.setFont(ArialMT_Plain_16); - display.drawString(64, 30, WiFi.localIP().toString()); - display.drawString(64, 46, "Port: " + String(WEBSERVER_PORT)); - display.display(); + debugHandle->printLn("Use this URL : " + webAddress); + //display.clear(); + //display.setTextAlignment(TEXT_ALIGN_CENTER); + //display.setFont(ArialMT_Plain_10); + //display.drawString(64, 10, "Web Interface On"); + //display.drawString(64, 20, "You May Connect to IP"); + //display.setFont(ArialMT_Plain_16); + //display.drawString(64, 30, WiFi.localIP().toString()); + //display.drawString(64, 46, "Port: " + String(WEBSERVER_PORT)); + //display.display(); } else { - Serial.println("Web Interface is Disabled"); - display.clear(); - display.setTextAlignment(TEXT_ALIGN_CENTER); - display.setFont(ArialMT_Plain_10); - display.drawString(64, 10, "Web Interface is Off"); - display.drawString(64, 20, "Enable in Settings.h"); - display.display(); + debugHandle->printLn("Web Interface is Disabled"); + //display.clear(); + //display.setTextAlignment(TEXT_ALIGN_CENTER); + //display.setFont(ArialMT_Plain_10); + //display.drawString(64, 10, "Web Interface is Off"); + //display.drawString(64, 20, "Enable in Settings.h"); + //display.display(); } flashLED(5, 100); findMDNS(); //go find Printer Server by the hostname - Serial.println("*** Leaving setup()"); + debugHandle->printLn("*** Leaving setup()"); } -void findMDNS() { - if (PrinterHostName == "" || ENABLE_OTA == false) { - return; // nothing to do here - } - // We now query our network for 'web servers' service - // over tcp, and get the number of available devices - int n = MDNS.queryService("http", "tcp"); - if (n == 0) { - Serial.println("no services found - make sure Printer server is turned on"); - return; - } - Serial.println("*** Looking for " + PrinterHostName + " over mDNS"); - for (int i = 0; i < n; ++i) { - // Going through every available service, - // we're searching for the one whose hostname - // matches what we want, and then get its IP - Serial.println("Found: " + MDNS.hostname(i)); - if (MDNS.hostname(i) == PrinterHostName) { - IPAddress serverIp = MDNS.IP(i); - PrinterServer = serverIp.toString(); - PrinterPort = MDNS.port(i); // save the port - Serial.println("*** Found Printer Server " + PrinterHostName + " http://" + PrinterServer + ":" + PrinterPort); - writeSettings(); // update the settings - } - } -} //************************************************************ // Main Loop //************************************************************ void loop() { - - //Get Time Update - if((getMinutesFromLastRefresh() >= minutesBetweenDataRefresh) || lastEpoch == 0) { - getUpdateTime(); - } - if (lastMinute != timeClient.getMinutes() && !printerClient.isPrinting()) { - // Check status every 60 seconds - ledOnOff(true); - lastMinute = timeClient.getMinutes(); // reset the check value - printerClient.getPrinterJobResults(); - printerClient.getPrinterPsuState(); - ledOnOff(false); - } else if (printerClient.isPrinting()) { - if (lastSecond != timeClient.getSeconds() && timeClient.getSeconds().endsWith("0")) { - lastSecond = timeClient.getSeconds(); - // every 10 seconds while printing get an update - ledOnOff(true); - printerClient.getPrinterJobResults(); - printerClient.getPrinterPsuState(); - ledOnOff(false); - } - } - checkDisplay(); // Check to see if the printer is on or offline and change display. - - ui.update(); + //displayHandle.showPageInit(); + //delay(1000); if (WEBSERVER_ENABLED) { server.handleClient(); @@ -412,702 +212,50 @@ void loop() { } } -void getUpdateTime() { - ledOnOff(true); // turn on the LED - Serial.println(); - if (displayOn && DISPLAYWEATHER) { - Serial.println("Getting Weather Data..."); - weatherClient.updateWeather(); + + + + + + + + + + +//************************************************************ +// MDNS for printers +//************************************************************ +void findMDNS() { + if (PrinterHostName == "" || ENABLE_OTA == false) { + return; // nothing to do here } - - Serial.println("Updating Time..."); - //Update the Time - timeClient.updateTime(); - lastEpoch = timeClient.getCurrentEpoch(); - Serial.println("Local time: " + timeClient.getAmPmFormattedTime()); - - ledOnOff(false); // turn off the LED -} - -boolean authentication() { - if (IS_BASIC_AUTH && (strlen(www_username) >= 1 && strlen(www_password) >= 1)) { - return server.authenticate(www_username, www_password); - } - return true; // Authentication not required -} - -void handleSystemReset() { - if (!authentication()) { - return server.requestAuthentication(); + // We now query our network for 'web servers' service + // over tcp, and get the number of available devices + int n = MDNS.queryService("http", "tcp"); + if (n == 0) { + debugHandle->printLn("no services found - make sure Printer server is turned on"); + return; } - Serial.println("Reset System Configuration"); - if (SPIFFS.remove(CONFIG)) { - redirectHome(); - ESP.restart(); - } -} - -void handleUpdateWeather() { - if (!authentication()) { - return server.requestAuthentication(); - } - DISPLAYWEATHER = server.hasArg("isWeatherEnabled"); - WeatherApiKey = server.arg("openWeatherMapApiKey"); - CityIDs[0] = server.arg("city1").toInt(); - IS_METRIC = server.hasArg("metric"); - WeatherLanguage = server.arg("language"); - writeSettings(); - isClockOn = false; // this will force a check for the display - checkDisplay(); - lastEpoch = 0; - redirectHome(); -} - -void handleUpdateConfig() { - boolean flipOld = INVERT_DISPLAY; - if (!authentication()) { - return server.requestAuthentication(); - } - if (server.hasArg("printer")) { - printerClient.setPrinterName(server.arg("printer")); - } - PrinterApiKey = server.arg("PrinterApiKey"); - PrinterHostName = server.arg("PrinterHostName"); - PrinterServer = server.arg("PrinterAddress"); - PrinterPort = server.arg("PrinterPort").toInt(); - PrinterAuthUser = server.arg("octoUser"); - PrinterAuthPass = server.arg("octoPass"); - DISPLAYCLOCK = server.hasArg("isClockEnabled"); - IS_24HOUR = server.hasArg("is24hour"); - INVERT_DISPLAY = server.hasArg("invDisp"); - USE_FLASH = server.hasArg("useFlash"); - HAS_PSU = server.hasArg("hasPSU"); - minutesBetweenDataRefresh = server.arg("refresh").toInt(); - themeColor = server.arg("theme"); - UtcOffset = server.arg("utcoffset").toFloat(); - String temp = server.arg("userid"); - temp.toCharArray(www_username, sizeof(temp)); - temp = server.arg("stationpassword"); - temp.toCharArray(www_password, sizeof(temp)); - writeSettings(); - findMDNS(); - printerClient.getPrinterJobResults(); - printerClient.getPrinterPsuState(); - if (INVERT_DISPLAY != flipOld) { - ui.init(); - if(INVERT_DISPLAY) - display.flipScreenVertically(); - ui.update(); - } - checkDisplay(); - lastEpoch = 0; - redirectHome(); -} - -void handleWifiReset() { - if (!authentication()) { - return server.requestAuthentication(); - } - //WiFiManager - //Local intialization. Once its business is done, there is no need to keep it around - redirectHome(); - WiFiManager wifiManager; - wifiManager.resetSettings(); - ESP.restart(); -} - -void handleWeatherConfigure() { - if (!authentication()) { - return server.requestAuthentication(); - } - ledOnOff(true); - String html = ""; - - server.sendHeader("Cache-Control", "no-cache, no-store"); - server.sendHeader("Pragma", "no-cache"); - server.sendHeader("Expires", "-1"); - server.setContentLength(CONTENT_LENGTH_UNKNOWN); - server.send(200, "text/html", ""); - - html = getHeader(); - server.sendContent(html); - - String form = FPSTR(WEATHER_FORM); - String isWeatherChecked = ""; - if (DISPLAYWEATHER) { - isWeatherChecked = "checked='checked'"; - } - form.replace("%IS_WEATHER_CHECKED%", isWeatherChecked); - form.replace("%WEATHERKEY%", WeatherApiKey); - form.replace("%CITYNAME1%", weatherClient.getCity(0)); - form.replace("%CITY1%", String(CityIDs[0])); - String checked = ""; - if (IS_METRIC) { - checked = "checked='checked'"; - } - form.replace("%METRIC%", checked); - String options = FPSTR(LANG_OPTIONS); - options.replace(">"+String(WeatherLanguage)+"<", " selected>"+String(WeatherLanguage)+"<"); - form.replace("%LANGUAGEOPTIONS%", options); - server.sendContent(form); - - html = getFooter(); - server.sendContent(html); - server.sendContent(""); - server.client().stop(); - ledOnOff(false); -} - -void handleConfigure() { - if (!authentication()) { - return server.requestAuthentication(); - } - ledOnOff(true); - String html = ""; - - server.sendHeader("Cache-Control", "no-cache, no-store"); - server.sendHeader("Pragma", "no-cache"); - server.sendHeader("Expires", "-1"); - server.setContentLength(CONTENT_LENGTH_UNKNOWN); - server.send(200, "text/html", ""); - - html = getHeader(); - server.sendContent(html); - - CHANGE_FORM = "

Station Config:

" - "

" - "

"; - if (printerClient.getPrinterType() == "OctoPrint") { - CHANGE_FORM += "

"; - } - CHANGE_FORM += "

" - "

" - "

" - "

"; - if (printerClient.getPrinterType() == "Repetier") { - CHANGE_FORM += "" - "

" - ""; - } else { - CHANGE_FORM += "

"; - } - CHANGE_FORM += "

" - "

"; - - - - if (printerClient.getPrinterType() == "Repetier") { - html = ""; - - server.sendContent(html); - } else { - html = ""; - server.sendContent(html); - } - - String form = CHANGE_FORM; - - form.replace("%OCTOKEY%", PrinterApiKey); - form.replace("%OCTOHOST%", PrinterHostName); - form.replace("%OCTOADDRESS%", PrinterServer); - form.replace("%OCTOPORT%", String(PrinterPort)); - form.replace("%OCTOUSER%", PrinterAuthUser); - form.replace("%OCTOPASS%", PrinterAuthPass); - - server.sendContent(form); - - form = FPSTR(CLOCK_FORM); - - String isClockChecked = ""; - if (DISPLAYCLOCK) { - isClockChecked = "checked='checked'"; - } - form.replace("%IS_CLOCK_CHECKED%", isClockChecked); - String is24hourChecked = ""; - if (IS_24HOUR) { - is24hourChecked = "checked='checked'"; - } - form.replace("%IS_24HOUR_CHECKED%", is24hourChecked); - String isInvDisp = ""; - if (INVERT_DISPLAY) { - isInvDisp = "checked='checked'"; - } - form.replace("%IS_INVDISP_CHECKED%", isInvDisp); - String isFlashLED = ""; - if (USE_FLASH) { - isFlashLED = "checked='checked'"; - } - form.replace("%USEFLASH%", isFlashLED); - String hasPSUchecked = ""; - if (HAS_PSU) { - hasPSUchecked = "checked='checked'"; - } - form.replace("%HAS_PSU_CHECKED%", hasPSUchecked); - - String options = ""; - options.replace(">"+String(minutesBetweenDataRefresh)+"<", " selected>"+String(minutesBetweenDataRefresh)+"<"); - form.replace("%OPTIONS%", options); - - server.sendContent(form); - - form = FPSTR(THEME_FORM); - - String themeOptions = FPSTR(COLOR_THEMES); - themeOptions.replace(">"+String(themeColor)+"<", " selected>"+String(themeColor)+"<"); - form.replace("%THEME_OPTIONS%", themeOptions); - form.replace("%UTCOFFSET%", String(UtcOffset)); - String isUseSecurityChecked = ""; - if (IS_BASIC_AUTH) { - isUseSecurityChecked = "checked='checked'"; - } - form.replace("%IS_BASICAUTH_CHECKED%", isUseSecurityChecked); - form.replace("%USERID%", String(www_username)); - form.replace("%STATIONPASSWORD%", String(www_password)); - - server.sendContent(form); - - html = getFooter(); - server.sendContent(html); - server.sendContent(""); - server.client().stop(); - ledOnOff(false); -} - -void displayMessage(String message) { - ledOnOff(true); - - server.sendHeader("Cache-Control", "no-cache, no-store"); - server.sendHeader("Pragma", "no-cache"); - server.sendHeader("Expires", "-1"); - server.setContentLength(CONTENT_LENGTH_UNKNOWN); - server.send(200, "text/html", ""); - String html = getHeader(); - server.sendContent(String(html)); - server.sendContent(String(message)); - html = getFooter(); - server.sendContent(String(html)); - server.sendContent(""); - server.client().stop(); - - ledOnOff(false); -} - -void redirectHome() { - // Send them back to the Root Directory - server.sendHeader("Location", String("/"), true); - server.sendHeader("Cache-Control", "no-cache, no-store"); - server.sendHeader("Pragma", "no-cache"); - server.sendHeader("Expires", "-1"); - server.send(302, "text/plain", ""); - server.client().stop(); -} - -String getHeader() { - return getHeader(false); -} - -String getHeader(boolean refresh) { - String menu = FPSTR(WEB_ACTIONS); - - String html = ""; - html += "Printer Monitor"; - html += ""; - html += ""; - if (refresh) { - html += ""; - } - html += ""; - html += ""; - html += ""; - html += ""; - html += ""; - html += "

Printer Monitor

"; - html += ""; - html += "
"; - return html; -} - -String getFooter() { - int8_t rssi = getWifiQuality(); - Serial.print("Signal Strength (RSSI): "); - Serial.print(rssi); - Serial.println("%"); - String html = "


"; - html += "
"; - html += "
"; - if (lastReportStatus != "") { - html += " Report Status: " + lastReportStatus + "
"; - } - html += " Version: " + String(VERSION) + "
"; - html += " Signal Strength: "; - html += String(rssi) + "%"; - html += "
"; - html += ""; - return html; -} - -void displayPrinterStatus() { - ledOnOff(true); - String html = ""; - - server.sendHeader("Cache-Control", "no-cache, no-store"); - server.sendHeader("Pragma", "no-cache"); - server.sendHeader("Expires", "-1"); - server.setContentLength(CONTENT_LENGTH_UNKNOWN); - server.send(200, "text/html", ""); - server.sendContent(String(getHeader(true))); - - String displayTime = timeClient.getAmPmHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds() + " " + timeClient.getAmPm(); - if (IS_24HOUR) { - displayTime = timeClient.getHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds(); - } - - html += "

" + printerClient.getPrinterType() + " Monitor

"; - html += "

"; - if (printerClient.getPrinterType() == "Repetier") { - html += "Printer Name: " + printerClient.getPrinterName() + "
"; - } else { - html += "Host Name: " + PrinterHostName + "
"; - } - - if (printerClient.getError() != "") { - html += "Status: Offline
"; - html += "Reason: " + printerClient.getError() + "
"; - } else { - html += "Status: " + printerClient.getState(); - if (printerClient.isPSUoff() && HAS_PSU) { - html += ", PSU off"; - } - html += "
"; - } - - if (printerClient.isPrinting()) { - html += "File: " + printerClient.getFileName() + "
"; - float fileSize = printerClient.getFileSize().toFloat(); - if (fileSize > 0) { - fileSize = fileSize / 1024; - html += "File Size: " + String(fileSize) + "KB
"; - } - int filamentLength = printerClient.getFilamentLength().toInt(); - if (filamentLength > 0) { - float fLength = float(filamentLength) / 1000; - html += "Filament: " + String(fLength) + "m
"; - } - - html += "Tool Temperature: " + printerClient.getTempToolActual() + "° C
"; - if ( printerClient.getTempBedActual() != 0 ) { - html += "Bed Temperature: " + printerClient.getTempBedActual() + "° C
"; - } - - int val = printerClient.getProgressPrintTimeLeft().toInt(); - int hours = numberOfHours(val); - int minutes = numberOfMinutes(val); - int seconds = numberOfSeconds(val); - html += "Est. Print Time Left: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "
"; - - val = printerClient.getProgressPrintTime().toInt(); - hours = numberOfHours(val); - minutes = numberOfMinutes(val); - seconds = numberOfSeconds(val); - html += "Printing Time: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "
"; - html += ""; - html += "

" + printerClient.getProgressCompletion() + "%
"; - } else { - html += "
"; - } - - html += "

"; - - html += "

Time: " + displayTime + "

"; - - server.sendContent(html); // spit out what we got - html = ""; - - if (DISPLAYWEATHER) { - if (weatherClient.getCity(0) == "") { - html += "

Please Configure Weather API

"; - if (weatherClient.getError() != "") { - html += "

Weather Error: " + weatherClient.getError() + "

"; - } - } else { - html += "

" + weatherClient.getCity(0) + ", " + weatherClient.getCountry(0) + "

"; - html += "
"; - html += "" + weatherClient.getDescription(0) + "
"; - html += weatherClient.getHumidity(0) + "% Humidity
"; - html += weatherClient.getWind(0) + " " + getSpeedSymbol() + " Wind
"; - html += "
"; - html += "

"; - html += weatherClient.getCondition(0) + " (" + weatherClient.getDescription(0) + ")
"; - html += weatherClient.getTempRounded(0) + getTempSymbol(true) + "
"; - html += " Map It!
"; - html += "

"; - } - - server.sendContent(html); // spit out what we got - html = ""; // fresh start - } - - server.sendContent(String(getFooter())); - server.sendContent(""); - server.client().stop(); - ledOnOff(false); -} - -void configModeCallback (WiFiManager *myWiFiManager) { - Serial.println("Entered config mode"); - Serial.println(WiFi.softAPIP()); - - display.clear(); - display.setTextAlignment(TEXT_ALIGN_CENTER); - display.setFont(ArialMT_Plain_10); - display.drawString(64, 0, "Wifi Manager"); - display.drawString(64, 10, "Please connect to AP"); - display.setFont(ArialMT_Plain_16); - display.drawString(64, 26, myWiFiManager->getConfigPortalSSID()); - display.setFont(ArialMT_Plain_10); - display.drawString(64, 46, "To setup Wifi connection"); - display.display(); - - Serial.println("Wifi Manager"); - Serial.println("Please connect to AP"); - Serial.println(myWiFiManager->getConfigPortalSSID()); - Serial.println("To setup Wifi Configuration"); - flashLED(20, 50); -} - -void ledOnOff(boolean value) { - if (USE_FLASH) { - if (value) { - digitalWrite(externalLight, LOW); // LED ON - } else { - digitalWrite(externalLight, HIGH); // LED OFF + debugHandle->printLn("*** Looking for " + PrinterHostName + " over mDNS"); + for (int i = 0; i < n; ++i) { + // Going through every available service, + // we're searching for the one whose hostname + // matches what we want, and then get its IP + debugHandle->printLn("Found: " + MDNS.hostname(i)); + if (MDNS.hostname(i) == PrinterHostName) { + IPAddress serverIp = MDNS.IP(i); + PrinterServer = serverIp.toString(); + PrinterPort = MDNS.port(i); // save the port + debugHandle->printLn("*** Found Printer Server " + PrinterHostName + " http://" + PrinterServer + ":" + PrinterPort); + writeSettings(); // update the settings } } } -void flashLED(int number, int delayTime) { - for (int inx = 0; inx <= number; inx++) { - delay(delayTime); - digitalWrite(externalLight, LOW); // ON - delay(delayTime); - digitalWrite(externalLight, HIGH); // OFF - delay(delayTime); - } -} - -void drawScreen1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { - String bed = printerClient.getValueRounded(printerClient.getTempBedActual()); - String tool = printerClient.getValueRounded(printerClient.getTempToolActual()); - display->setTextAlignment(TEXT_ALIGN_CENTER); - display->setFont(ArialMT_Plain_16); - if (bed != "0") { - display->drawString(29 + x, 0 + y, "Tool"); - display->drawString(89 + x, 0 + y, "Bed"); - } else { - display->drawString(64 + x, 0 + y, "Tool Temp"); - } - display->setTextAlignment(TEXT_ALIGN_LEFT); - display->setFont(ArialMT_Plain_24); - if (bed != "0") { - display->setTextAlignment(TEXT_ALIGN_LEFT); - display->drawString(12 + x, 14 + y, tool + "°"); - display->drawString(74 + x, 14 + y, bed + "°"); - } else { - display->setTextAlignment(TEXT_ALIGN_CENTER); - display->drawString(64 + x, 14 + y, tool + "°"); - } -} - -void drawScreen2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { - display->setTextAlignment(TEXT_ALIGN_CENTER); - display->setFont(ArialMT_Plain_16); - - display->drawString(64 + x, 0 + y, "Time Remaining"); - //display->setTextAlignment(TEXT_ALIGN_LEFT); - display->setFont(ArialMT_Plain_24); - int val = printerClient.getProgressPrintTimeLeft().toInt(); - int hours = numberOfHours(val); - int minutes = numberOfMinutes(val); - int seconds = numberOfSeconds(val); - - String time = zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds); - display->drawString(64 + x, 14 + y, time); -} - -void drawScreen3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { - display->setTextAlignment(TEXT_ALIGN_CENTER); - display->setFont(ArialMT_Plain_16); - - display->drawString(64 + x, 0 + y, "Printing Time"); - //display->setTextAlignment(TEXT_ALIGN_LEFT); - display->setFont(ArialMT_Plain_24); - int val = printerClient.getProgressPrintTime().toInt(); - int hours = numberOfHours(val); - int minutes = numberOfMinutes(val); - int seconds = numberOfSeconds(val); - - String time = zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds); - display->drawString(64 + x, 14 + y, time); -} - -void drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { - display->setTextAlignment(TEXT_ALIGN_CENTER); - - String displayTime = timeClient.getAmPmHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds(); - if (IS_24HOUR) { - displayTime = timeClient.getHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds(); - } - String displayName = PrinterHostName; - if (printerClient.getPrinterType() == "Repetier") { - displayName = printerClient.getPrinterName(); - } - display->setFont(ArialMT_Plain_16); - display->drawString(64 + x, 0 + y, displayName); - display->setFont(ArialMT_Plain_24); - display->drawString(64 + x, 17 + y, displayTime); -} - -void drawWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { - display->setTextAlignment(TEXT_ALIGN_LEFT); - display->setFont(ArialMT_Plain_24); - display->drawString(0 + x, 0 + y, weatherClient.getTempRounded(0) + getTempSymbol()); - display->setTextAlignment(TEXT_ALIGN_LEFT); - display->setFont(ArialMT_Plain_24); - - display->setFont(ArialMT_Plain_16); - display->drawString(0 + x, 24 + y, weatherClient.getCondition(0)); - display->setFont((const uint8_t*)Meteocons_Plain_42); - display->drawString(86 + x, 0 + y, weatherClient.getWeatherIcon(0)); -} - -String getTempSymbol() { - return getTempSymbol(false); -} - -String getTempSymbol(boolean forHTML) { - String rtnValue = "F"; - if (IS_METRIC) { - rtnValue = "C"; - } - if (forHTML) { - rtnValue = "°" + rtnValue; - } else { - rtnValue = "°" + rtnValue; - } - return rtnValue; -} - -String getSpeedSymbol() { - String rtnValue = "mph"; - if (IS_METRIC) { - rtnValue = "kph"; - } - return rtnValue; -} - -String zeroPad(int value) { - String rtnValue = String(value); - if (value < 10) { - rtnValue = "0" + rtnValue; - } - return rtnValue; -} - -void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) { - display->setColor(WHITE); - display->setFont(ArialMT_Plain_16); - String displayTime = timeClient.getAmPmHours() + ":" + timeClient.getMinutes(); - if (IS_24HOUR) { - displayTime = timeClient.getHours() + ":" + timeClient.getMinutes(); - } - display->setTextAlignment(TEXT_ALIGN_LEFT); - display->drawString(0, 48, displayTime); - - if (!IS_24HOUR) { - String ampm = timeClient.getAmPm(); - display->setFont(ArialMT_Plain_10); - display->drawString(39, 54, ampm); - } - - display->setFont(ArialMT_Plain_16); - display->setTextAlignment(TEXT_ALIGN_LEFT); - String percent = String(printerClient.getProgressCompletion()) + "%"; - display->drawString(64, 48, percent); - - // Draw indicator to show next update - int updatePos = (printerClient.getProgressCompletion().toFloat() / float(100)) * 128; - display->drawRect(0, 41, 128, 6); - display->drawHorizontalLine(0, 42, updatePos); - display->drawHorizontalLine(0, 43, updatePos); - display->drawHorizontalLine(0, 44, updatePos); - display->drawHorizontalLine(0, 45, updatePos); - - drawRssi(display); -} - -void drawClockHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) { - display->setColor(WHITE); - display->setFont(ArialMT_Plain_16); - display->setTextAlignment(TEXT_ALIGN_LEFT); - if (!IS_24HOUR) { - display->drawString(0, 48, timeClient.getAmPm()); - display->setTextAlignment(TEXT_ALIGN_CENTER); - if (printerClient.isPSUoff()) { - display->drawString(64, 47, "psu off"); - } else if (printerClient.getState() == "Operational") { - display->drawString(64, 47, "online"); - } else { - display->drawString(64, 47, "offline"); - } - } else { - if (printerClient.isPSUoff()) { - display->drawString(0, 47, "psu off"); - } else if (printerClient.getState() == "Operational") { - display->drawString(0, 47, "online"); - } else { - display->drawString(0, 47, "offline"); - } - } - display->setTextAlignment(TEXT_ALIGN_LEFT); - display->drawRect(0, 43, 128, 2); - - drawRssi(display); -} - -void drawRssi(OLEDDisplay *display) { - - - int8_t quality = getWifiQuality(); - for (int8_t i = 0; i < 4; i++) { - for (int8_t j = 0; j < 3 * (i + 2); j++) { - if (quality > i * 25 || j == 0) { - display->setPixel(114 + 4 * i, 63 - j); - } - } - } -} - -// converts the dBm to a range between 0 and 100% +//************************************************************ +// Converts the dBm to a range between 0 and 100% +//************************************************************ int8_t getWifiQuality() { int32_t dbm = WiFi.RSSI(); if(dbm <= -100) { @@ -1119,14 +267,194 @@ int8_t getWifiQuality() { } } +//************************************************************ +// Wifi config mode +//************************************************************ +void configModeCallback(WiFiManager *myWiFiManager) { + debugHandle->printLn("Entered config mode"); + debugHandle->printLn(WiFi.softAPIP().toString()); + displayHandle.showPageApMode(myWiFiManager->getConfigPortalSSID()); + + + debugHandle->printLn("Wifi Manager"); + debugHandle->printLn("Please connect to AP"); + debugHandle->printLn(myWiFiManager->getConfigPortalSSID()); + debugHandle->printLn("To setup Wifi Configuration"); + flashLED(20, 50); +} + +//************************************************************ +// Flash LED +//************************************************************ +void flashLED(int number, int delayTime) { + for (int inx = 0; inx <= number; inx++) { + delay(delayTime); + digitalWrite(externalLight, LOW); // ON + delay(delayTime); + digitalWrite(externalLight, HIGH); // OFF + delay(delayTime); + } +} + +//************************************************************ +// Toggle LED +//************************************************************ +void ledOnOff(boolean value) { + if (USE_FLASH) { + if (value) { + digitalWrite(externalLight, LOW); // LED ON + } else { + digitalWrite(externalLight, HIGH); // LED OFF + } + } +} + +//************************************************************ +// Read settings from internal eeprom +//************************************************************ +void readSettings() { + if (SPIFFS.exists(CONFIG) == false) { + debugHandle->printLn("Settings File does not yet exists."); + writeSettings(); + return; + } + File fr = SPIFFS.open(CONFIG, "r"); + String line; + while(fr.available()) { + line = fr.readStringUntil('\n'); + + if (line.indexOf("UtcOffset=") >= 0) { + UtcOffset = line.substring(line.lastIndexOf("UtcOffset=") + 10).toFloat(); + debugHandle->printLn("UtcOffset=" + String(UtcOffset)); + } + if (line.indexOf("printerApiKey=") >= 0) { + PrinterApiKey = line.substring(line.lastIndexOf("printerApiKey=") + 14); + PrinterApiKey.trim(); + debugHandle->printLn("PrinterApiKey=" + PrinterApiKey); + } + if (line.indexOf("printerHostName=") >= 0) { + PrinterHostName = line.substring(line.lastIndexOf("printerHostName=") + 16); + PrinterHostName.trim(); + debugHandle->printLn("PrinterHostName=" + PrinterHostName); + } + if (line.indexOf("printerServer=") >= 0) { + PrinterServer = line.substring(line.lastIndexOf("printerServer=") + 14); + PrinterServer.trim(); + debugHandle->printLn("PrinterServer=" + PrinterServer); + } + if (line.indexOf("printerPort=") >= 0) { + PrinterPort = line.substring(line.lastIndexOf("printerPort=") + 12).toInt(); + debugHandle->printLn("PrinterPort=" + String(PrinterPort)); + } + if (line.indexOf("printerName=") >= 0) { + String printer = line.substring(line.lastIndexOf("printerName=") + 12); + printer.trim(); + printerClient.setPrinterName(printer); + debugHandle->printLn("PrinterName=" + printerClient.getPrinterName()); + } + if (line.indexOf("printerAuthUser=") >= 0) { + PrinterAuthUser = line.substring(line.lastIndexOf("printerAuthUser=") + 16); + PrinterAuthUser.trim(); + debugHandle->printLn("PrinterAuthUser=" + PrinterAuthUser); + } + if (line.indexOf("printerAuthPass=") >= 0) { + PrinterAuthPass = line.substring(line.lastIndexOf("printerAuthPass=") + 16); + PrinterAuthPass.trim(); + debugHandle->printLn("PrinterAuthPass=" + PrinterAuthPass); + } + if (line.indexOf("refreshRate=") >= 0) { + minutesBetweenDataRefresh = line.substring(line.lastIndexOf("refreshRate=") + 12).toInt(); + debugHandle->printLn("minutesBetweenDataRefresh=" + String(minutesBetweenDataRefresh)); + } + if (line.indexOf("themeColor=") >= 0) { + themeColor = line.substring(line.lastIndexOf("themeColor=") + 11); + themeColor.trim(); + debugHandle->printLn("themeColor=" + themeColor); + } + if (line.indexOf("IS_BASIC_AUTH=") >= 0) { + IS_BASIC_AUTH = line.substring(line.lastIndexOf("IS_BASIC_AUTH=") + 14).toInt(); + debugHandle->printLn("IS_BASIC_AUTH=" + String(IS_BASIC_AUTH)); + webServer.setAuthentication(IS_BASIC_AUTH, www_username, www_password); + } + if (line.indexOf("www_username=") >= 0) { + String temp = line.substring(line.lastIndexOf("www_username=") + 13); + temp.trim(); + temp.toCharArray(www_username, sizeof(temp)); + debugHandle->printLn("www_username=" + String(www_username)); + webServer.setAuthentication(IS_BASIC_AUTH, www_username, www_password); + } + if (line.indexOf("www_password=") >= 0) { + String temp = line.substring(line.lastIndexOf("www_password=") + 13); + temp.trim(); + temp.toCharArray(www_password, sizeof(temp)); + debugHandle->printLn("www_password=" + String(www_password)); + webServer.setAuthentication(IS_BASIC_AUTH, www_username, www_password); + } + if (line.indexOf("DISPLAYCLOCK=") >= 0) { + DISPLAYCLOCK = line.substring(line.lastIndexOf("DISPLAYCLOCK=") + 13).toInt(); + debugHandle->printLn("DISPLAYCLOCK=" + String(DISPLAYCLOCK)); + } + if (line.indexOf("is24hour=") >= 0) { + IS_24HOUR = line.substring(line.lastIndexOf("is24hour=") + 9).toInt(); + debugHandle->printLn("IS_24HOUR=" + String(IS_24HOUR)); + } +#ifndef USE_NEXTION_DISPLAY + if(line.indexOf("invertDisp=") >= 0) { + INVERT_DISPLAY = line.substring(line.lastIndexOf("invertDisp=") + 11).toInt(); + debugHandle->printLn("INVERT_DISPLAY=" + String(INVERT_DISPLAY)); + } +#endif + if(line.indexOf("USE_FLASH=") >= 0) { + USE_FLASH = line.substring(line.lastIndexOf("USE_FLASH=") + 10).toInt(); + debugHandle->printLn("USE_FLASH=" + String(USE_FLASH)); + } + if (line.indexOf("hasPSU=") >= 0) { + HAS_PSU = line.substring(line.lastIndexOf("hasPSU=") + 7).toInt(); + debugHandle->printLn("HAS_PSU=" + String(HAS_PSU)); + } + if (line.indexOf("isWeather=") >= 0) { + DISPLAYWEATHER = line.substring(line.lastIndexOf("isWeather=") + 10).toInt(); + debugHandle->printLn("DISPLAYWEATHER=" + String(DISPLAYWEATHER)); + } + if (line.indexOf("weatherKey=") >= 0) { + WeatherApiKey = line.substring(line.lastIndexOf("weatherKey=") + 11); + WeatherApiKey.trim(); + debugHandle->printLn("WeatherApiKey=" + WeatherApiKey); + } + if (line.indexOf("CityID=") >= 0) { + CityIDs[0] = line.substring(line.lastIndexOf("CityID=") + 7).toInt(); + debugHandle->printLn("CityID: " + String(CityIDs[0])); + } + if (line.indexOf("isMetric=") >= 0) { + IS_METRIC = line.substring(line.lastIndexOf("isMetric=") + 9).toInt(); + debugHandle->printLn("IS_METRIC=" + String(IS_METRIC)); + } + if (line.indexOf("language=") >= 0) { + WeatherLanguage = line.substring(line.lastIndexOf("language=") + 9); + WeatherLanguage.trim(); + debugHandle->printLn("WeatherLanguage=" + WeatherLanguage); + } + } + fr.close(); + printerClient.updatePrintClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); + weatherClient.updateWeatherApiKey(WeatherApiKey); + weatherClient.updateLanguage(WeatherLanguage); + weatherClient.setMetric(IS_METRIC); + weatherClient.updateCityIdList(CityIDs, 1); + timeClient.setUtcOffset(UtcOffset); +} + +//************************************************************ +// Save settings to internal eeprom +//************************************************************ void writeSettings() { // Save decoded message to SPIFFS file for playback on power up. File f = SPIFFS.open(CONFIG, "w"); if (!f) { - Serial.println("File open failed!"); + debugHandle->printLn("File open failed!"); } else { - Serial.println("Saving settings now..."); + debugHandle->printLn("Saving settings now..."); f.println("UtcOffset=" + String(UtcOffset)); f.println("printerApiKey=" + PrinterApiKey); f.println("printerHostName=" + PrinterHostName); @@ -1142,7 +470,9 @@ void writeSettings() { f.println("www_password=" + String(www_password)); f.println("DISPLAYCLOCK=" + String(DISPLAYCLOCK)); f.println("is24hour=" + String(IS_24HOUR)); +#ifndef USE_NEXTION_DISPLAY f.println("invertDisp=" + String(INVERT_DISPLAY)); +#endif f.println("USE_FLASH=" + String(USE_FLASH)); f.println("isWeather=" + String(DISPLAYWEATHER)); f.println("weatherKey=" + WeatherApiKey); @@ -1155,215 +485,3 @@ void writeSettings() { readSettings(); timeClient.setUtcOffset(UtcOffset); } - -void readSettings() { - if (SPIFFS.exists(CONFIG) == false) { - Serial.println("Settings File does not yet exists."); - writeSettings(); - return; - } - File fr = SPIFFS.open(CONFIG, "r"); - String line; - while(fr.available()) { - line = fr.readStringUntil('\n'); - - if (line.indexOf("UtcOffset=") >= 0) { - UtcOffset = line.substring(line.lastIndexOf("UtcOffset=") + 10).toFloat(); - Serial.println("UtcOffset=" + String(UtcOffset)); - } - if (line.indexOf("printerApiKey=") >= 0) { - PrinterApiKey = line.substring(line.lastIndexOf("printerApiKey=") + 14); - PrinterApiKey.trim(); - Serial.println("PrinterApiKey=" + PrinterApiKey); - } - if (line.indexOf("printerHostName=") >= 0) { - PrinterHostName = line.substring(line.lastIndexOf("printerHostName=") + 16); - PrinterHostName.trim(); - Serial.println("PrinterHostName=" + PrinterHostName); - } - if (line.indexOf("printerServer=") >= 0) { - PrinterServer = line.substring(line.lastIndexOf("printerServer=") + 14); - PrinterServer.trim(); - Serial.println("PrinterServer=" + PrinterServer); - } - if (line.indexOf("printerPort=") >= 0) { - PrinterPort = line.substring(line.lastIndexOf("printerPort=") + 12).toInt(); - Serial.println("PrinterPort=" + String(PrinterPort)); - } - if (line.indexOf("printerName=") >= 0) { - String printer = line.substring(line.lastIndexOf("printerName=") + 12); - printer.trim(); - printerClient.setPrinterName(printer); - Serial.println("PrinterName=" + printerClient.getPrinterName()); - } - if (line.indexOf("printerAuthUser=") >= 0) { - PrinterAuthUser = line.substring(line.lastIndexOf("printerAuthUser=") + 16); - PrinterAuthUser.trim(); - Serial.println("PrinterAuthUser=" + PrinterAuthUser); - } - if (line.indexOf("printerAuthPass=") >= 0) { - PrinterAuthPass = line.substring(line.lastIndexOf("printerAuthPass=") + 16); - PrinterAuthPass.trim(); - Serial.println("PrinterAuthPass=" + PrinterAuthPass); - } - if (line.indexOf("refreshRate=") >= 0) { - minutesBetweenDataRefresh = line.substring(line.lastIndexOf("refreshRate=") + 12).toInt(); - Serial.println("minutesBetweenDataRefresh=" + String(minutesBetweenDataRefresh)); - } - if (line.indexOf("themeColor=") >= 0) { - themeColor = line.substring(line.lastIndexOf("themeColor=") + 11); - themeColor.trim(); - Serial.println("themeColor=" + themeColor); - } - if (line.indexOf("IS_BASIC_AUTH=") >= 0) { - IS_BASIC_AUTH = line.substring(line.lastIndexOf("IS_BASIC_AUTH=") + 14).toInt(); - Serial.println("IS_BASIC_AUTH=" + String(IS_BASIC_AUTH)); - } - if (line.indexOf("www_username=") >= 0) { - String temp = line.substring(line.lastIndexOf("www_username=") + 13); - temp.trim(); - temp.toCharArray(www_username, sizeof(temp)); - Serial.println("www_username=" + String(www_username)); - } - if (line.indexOf("www_password=") >= 0) { - String temp = line.substring(line.lastIndexOf("www_password=") + 13); - temp.trim(); - temp.toCharArray(www_password, sizeof(temp)); - Serial.println("www_password=" + String(www_password)); - } - if (line.indexOf("DISPLAYCLOCK=") >= 0) { - DISPLAYCLOCK = line.substring(line.lastIndexOf("DISPLAYCLOCK=") + 13).toInt(); - Serial.println("DISPLAYCLOCK=" + String(DISPLAYCLOCK)); - } - if (line.indexOf("is24hour=") >= 0) { - IS_24HOUR = line.substring(line.lastIndexOf("is24hour=") + 9).toInt(); - Serial.println("IS_24HOUR=" + String(IS_24HOUR)); - } - if(line.indexOf("invertDisp=") >= 0) { - INVERT_DISPLAY = line.substring(line.lastIndexOf("invertDisp=") + 11).toInt(); - Serial.println("INVERT_DISPLAY=" + String(INVERT_DISPLAY)); - } - if(line.indexOf("USE_FLASH=") >= 0) { - USE_FLASH = line.substring(line.lastIndexOf("USE_FLASH=") + 10).toInt(); - Serial.println("USE_FLASH=" + String(USE_FLASH)); - } - if (line.indexOf("hasPSU=") >= 0) { - HAS_PSU = line.substring(line.lastIndexOf("hasPSU=") + 7).toInt(); - Serial.println("HAS_PSU=" + String(HAS_PSU)); - } - if (line.indexOf("isWeather=") >= 0) { - DISPLAYWEATHER = line.substring(line.lastIndexOf("isWeather=") + 10).toInt(); - Serial.println("DISPLAYWEATHER=" + String(DISPLAYWEATHER)); - } - if (line.indexOf("weatherKey=") >= 0) { - WeatherApiKey = line.substring(line.lastIndexOf("weatherKey=") + 11); - WeatherApiKey.trim(); - Serial.println("WeatherApiKey=" + WeatherApiKey); - } - if (line.indexOf("CityID=") >= 0) { - CityIDs[0] = line.substring(line.lastIndexOf("CityID=") + 7).toInt(); - Serial.println("CityID: " + String(CityIDs[0])); - } - if (line.indexOf("isMetric=") >= 0) { - IS_METRIC = line.substring(line.lastIndexOf("isMetric=") + 9).toInt(); - Serial.println("IS_METRIC=" + String(IS_METRIC)); - } - if (line.indexOf("language=") >= 0) { - WeatherLanguage = line.substring(line.lastIndexOf("language=") + 9); - WeatherLanguage.trim(); - Serial.println("WeatherLanguage=" + WeatherLanguage); - } - } - fr.close(); - printerClient.updatePrintClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); - weatherClient.updateWeatherApiKey(WeatherApiKey); - weatherClient.updateLanguage(WeatherLanguage); - weatherClient.setMetric(IS_METRIC); - weatherClient.updateCityIdList(CityIDs, 1); - timeClient.setUtcOffset(UtcOffset); -} - -int getMinutesFromLastRefresh() { - int minutes = (timeClient.getCurrentEpoch() - lastEpoch) / 60; - return minutes; -} - -int getMinutesFromLastDisplay() { - int minutes = (timeClient.getCurrentEpoch() - displayOffEpoch) / 60; - return minutes; -} - -// Toggle on and off the display if user defined times -void checkDisplay() { - if (!displayOn && DISPLAYCLOCK) { - enableDisplay(true); - } - if (displayOn && !printerClient.isPrinting() && !DISPLAYCLOCK) { - // Put Display to sleep - display.clear(); - display.display(); - display.setFont(ArialMT_Plain_16); - display.setTextAlignment(TEXT_ALIGN_CENTER); - display.setContrast(255); // default is 255 - display.drawString(64, 5, "Printer Offline\nSleep Mode..."); - display.display(); - delay(5000); - enableDisplay(false); - Serial.println("Printer is offline going down to sleep..."); - return; - } else if (!displayOn && !DISPLAYCLOCK) { - if (printerClient.isOperational()) { - // Wake the Screen up - enableDisplay(true); - display.clear(); - display.display(); - display.setFont(ArialMT_Plain_16); - display.setTextAlignment(TEXT_ALIGN_CENTER); - display.setContrast(255); // default is 255 - display.drawString(64, 5, "Printer Online\nWake up..."); - display.display(); - Serial.println("Printer is online waking up..."); - delay(5000); - return; - } - } else if (DISPLAYCLOCK) { - if ((!printerClient.isPrinting() || printerClient.isPSUoff()) && !isClockOn) { - Serial.println("Clock Mode is turned on."); - if (!DISPLAYWEATHER) { - ui.disableAutoTransition(); - ui.setFrames(clockFrame, 1); - clockFrame[0] = drawClock; - } else { - ui.enableAutoTransition(); - ui.setFrames(clockFrame, 2); - clockFrame[0] = drawClock; - clockFrame[1] = drawWeather; - } - ui.setOverlays(clockOverlay, numberOfOverlays); - isClockOn = true; - } else if (printerClient.isPrinting() && !printerClient.isPSUoff() && isClockOn) { - Serial.println("Printer Monitor is active."); - ui.setFrames(frames, numberOfFrames); - ui.setOverlays(overlays, numberOfOverlays); - ui.enableAutoTransition(); - isClockOn = false; - } - } -} - -void enableDisplay(boolean enable) { - displayOn = enable; - if (enable) { - if (getMinutesFromLastDisplay() >= minutesBetweenDataRefresh) { - // The display has been off longer than the minutes between refresh -- need to get fresh data - lastEpoch = 0; // this should force a data pull - displayOffEpoch = 0; // reset - } - display.displayOn(); - Serial.println("Display was turned ON: " + timeClient.getFormattedTime()); - } else { - display.displayOff(); - Serial.println("Display was turned OFF: " + timeClient.getFormattedTime()); - displayOffEpoch = lastEpoch; - } -}