diff --git a/printermonitor/OctoPrintClient.cpp b/printermonitor/OctoPrintClient.cpp index ccf9ed7..028e265 100644 --- a/printermonitor/OctoPrintClient.cpp +++ b/printermonitor/OctoPrintClient.cpp @@ -394,3 +394,7 @@ String OctoPrintClient::getValueRounded(String value) { int rounded = (int)(f+0.5f); return String(rounded); } + +String OctoPrintClient::getPrinterType() { + return printerType; +} diff --git a/printermonitor/OctoPrintClient.h b/printermonitor/OctoPrintClient.h index 8f147ce..d4410a1 100644 --- a/printermonitor/OctoPrintClient.h +++ b/printermonitor/OctoPrintClient.h @@ -37,6 +37,7 @@ private: String myApiKey = ""; String encodedAuth = ""; boolean pollPsu; + const String printerType = "OctoPrint"; void resetPrintData(); boolean validate(); @@ -95,4 +96,5 @@ public: String getFilamentLength(); String getValueRounded(String value); String getError(); + String getPrinterType(); }; diff --git a/printermonitor/RepetierClient.cpp b/printermonitor/RepetierClient.cpp index 75604c3..36fe0b1 100644 --- a/printermonitor/RepetierClient.cpp +++ b/printermonitor/RepetierClient.cpp @@ -1,341 +1,345 @@ -/** 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 */ -/* 07 April 2019 : Jon Smith : Redesigned this class for Repetier Server */ - -#include "RepetierClient.h" - -RepetierClient::RepetierClient(String ApiKey, String server, int port, String user, String pass, boolean psu) { - updatePrintClient(ApiKey, server, port, user, pass, psu); -} - -void RepetierClient::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 RepetierClient::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 RepetierClient::getSubmitRequest(String apiGetData) { - WiFiClient printClient; - printClient.setTimeout(5000); - - Serial.println("Getting Repetier 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 Repetier failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect - Serial.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, "Host: 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; -} - - -void RepetierClient::getPrinterJobResults() { - if (!validate()) { - return; - } - //**** get the Printer Job status - String apiGetData = "GET /printer/api/?a=listPrinter"; - 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 - JsonArray& root = jsonBuffer.parseArray(printClient); - - - if (!root.success()) { - Serial.println("Repetier Data Parsing failed: " + String(myServer) + ":" + String(myPort)); - printerData.error = "Repetier Data Parsing failed: " + String(myServer) + ":" + String(myPort); - printerData.state = ""; - return; - } - - ///Selecting First printer - JsonObject& pr = root[0]; - - //printerData.averagePrintTime = (const char*)pr[""]; - printerData.estimatedPrintTime = (const char*)pr["printTime"]; - printerData.fileName = (const char*) pr["job"]; - printerData.fileSize = (const char*) pr["totalLines"]; - //printerData.filamentLength = (const char*) pr[""]; - printerData.state = (const char*) pr["online"]; - //printerData.lastPrintTime = (const char*) pr[""]; - printerData.progressCompletion = (const char*) pr["done"]; - printerData.progressFilepos = (const char*) pr["linesSend"]; - printerData.progressPrintTime = (const char*) pr["printedTimeComp"]; - -//Figure out Time Left - long timeTot=0; - long timeElap=0; - long timeLeft=0; - if (printerData.estimatedPrintTime != "" ) { - timeTot = atol(pr["printTime"]); - } - if (printerData.progressPrintTime != "") { - timeElap= atol(pr["printedTimeComp"]); - } - timeLeft = timeTot-timeElap; - printerData.progressPrintTimeLeft = String(timeLeft); - - String printing = (const char*) pr["job"]; - if (printing != "none") { - printerData.isPrinting = true; - } else { - printerData.isPrinting=false; - } - - Serial.println("PT: " + printerData.progressPrintTime); - Serial.println("PTC: " + printerData.estimatedPrintTime); - Serial.println("ST: " + printerData.lastPrintTime); - Serial.println("TimeLeft: " + printerData.progressPrintTimeLeft); - - if (printerData.isPrinting) { - Serial.println("I think I am printing"); - } - - if (isOperational()) { - Serial.println("Status: " + printerData.state); - } else { - Serial.println("Printer Not Operational"); - } - - //**** get the Printer Temps and Stat - apiGetData = "GET /printer/api/?a=stateList"; - 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); - - //Select printer - String slug=(const char*) pr["slug"]; - JsonObject& pr2 = root2[slug]; - - if (!root2.success()) { - printerData.isPrinting = false; - printerData.toolTemp = ""; - printerData.toolTargetTemp = ""; - printerData.bedTemp = ""; - printerData.bedTargetTemp = (const char*) pr2["heatBeds"][0]["tempSet"]; - return; - } - - printerData.toolTemp = (const char*) pr2["extruder"][0]["tempRead"]; - printerData.toolTargetTemp = (const char*) pr2["extruder"][0]["tempSet"]; - printerData.bedTemp = (const char*) pr2["heatedBeds"][0]["tempRead"]; - printerData.bedTargetTemp = (const char*) pr2["heatedBeds"][0]["tempSet"]; - - if (printerData.isPrinting) { - Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); - } -} - -void RepetierClient::getPrinterPsuState() { - //**** get the PSU state (if enabled and printer operational) - //Not implemented in Repetier Server AFAIK -} - -// Reset all PrinterData -void RepetierClient::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 RepetierClient::getAveragePrintTime(){ - return printerData.averagePrintTime; -} - -String RepetierClient::getEstimatedPrintTime() { - return printerData.estimatedPrintTime; -} - -String RepetierClient::getFileName() { - return printerData.fileName; -} - -String RepetierClient::getFileSize() { - return printerData.fileSize; -} - -String RepetierClient::getLastPrintTime(){ - return printerData.lastPrintTime; -} - -String RepetierClient::getProgressCompletion() { - return String(printerData.progressCompletion.toInt()); -} - -String RepetierClient::getProgressFilepos() { - return printerData.progressFilepos; -} - -String RepetierClient::getProgressPrintTime() { - return printerData.progressPrintTime; -} - -String RepetierClient::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 RepetierClient::getState() { - return printerData.state; -} - -boolean RepetierClient::isPrinting() { - return printerData.isPrinting; -} - -boolean RepetierClient::isPSUoff() { - return printerData.isPSUoff; -} - -boolean RepetierClient::isOperational() { - boolean operational = false; - if (printerData.state == "Operational" || isPrinting()) { - operational = true; - } - return operational; -} - -String RepetierClient::getTempBedActual() { - return printerData.bedTemp; -} - -String RepetierClient::getTempBedTarget() { - return printerData.bedTargetTemp; -} - -String RepetierClient::getTempToolActual() { - return printerData.toolTemp; -} - -String RepetierClient::getTempToolTarget() { - return printerData.toolTargetTemp; -} - -String RepetierClient::getFilamentLength() { - return printerData.filamentLength; -} - -String RepetierClient::getError() { - return printerData.error; -} - -String RepetierClient::getValueRounded(String value) { - float f = value.toFloat(); - int rounded = (int)(f+0.5f); - return String(rounded); -} +/** 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 */ +/* 07 April 2019 : Jon Smith : Redesigned this class for Repetier Server */ + +#include "RepetierClient.h" + +RepetierClient::RepetierClient(String ApiKey, String server, int port, String user, String pass, boolean psu) { + updatePrintClient(ApiKey, server, port, user, pass, psu); +} + +void RepetierClient::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 RepetierClient::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 RepetierClient::getSubmitRequest(String apiGetData) { + WiFiClient printClient; + printClient.setTimeout(5000); + + Serial.println("Getting Repetier 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 Repetier failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect + Serial.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, "Host: 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; +} + + +void RepetierClient::getPrinterJobResults() { + if (!validate()) { + return; + } + //**** get the Printer Job status + String apiGetData = "GET /printer/api/?a=listPrinter"; + 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 + JsonArray& root = jsonBuffer.parseArray(printClient); + + + if (!root.success()) { + Serial.println("Repetier Data Parsing failed: " + String(myServer) + ":" + String(myPort)); + printerData.error = "Repetier Data Parsing failed: " + String(myServer) + ":" + String(myPort); + printerData.state = ""; + return; + } + + ///Selecting First printer + JsonObject& pr = root[0]; + + //printerData.averagePrintTime = (const char*)pr[""]; + printerData.estimatedPrintTime = (const char*)pr["printTime"]; + printerData.fileName = (const char*) pr["job"]; + printerData.fileSize = (const char*) pr["totalLines"]; + //printerData.filamentLength = (const char*) pr[""]; + printerData.state = (const char*) pr["online"]; + //printerData.lastPrintTime = (const char*) pr[""]; + printerData.progressCompletion = (const char*) pr["done"]; + printerData.progressFilepos = (const char*) pr["linesSend"]; + printerData.progressPrintTime = (const char*) pr["printedTimeComp"]; + +//Figure out Time Left + long timeTot=0; + long timeElap=0; + long timeLeft=0; + if (printerData.estimatedPrintTime != "" ) { + timeTot = atol(pr["printTime"]); + } + if (printerData.progressPrintTime != "") { + timeElap= atol(pr["printedTimeComp"]); + } + timeLeft = timeTot-timeElap; + printerData.progressPrintTimeLeft = String(timeLeft); + + String printing = (const char*) pr["job"]; + if (printing != "none") { + printerData.isPrinting = true; + } else { + printerData.isPrinting=false; + } + + Serial.println("PT: " + printerData.progressPrintTime); + Serial.println("PTC: " + printerData.estimatedPrintTime); + Serial.println("ST: " + printerData.lastPrintTime); + Serial.println("TimeLeft: " + printerData.progressPrintTimeLeft); + + if (printerData.isPrinting) { + Serial.println("I think I am printing"); + } + + if (isOperational()) { + Serial.println("Status: " + printerData.state); + } else { + Serial.println("Printer Not Operational"); + } + + //**** get the Printer Temps and Stat + apiGetData = "GET /printer/api/?a=stateList"; + 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); + + //Select printer + String slug=(const char*) pr["slug"]; + JsonObject& pr2 = root2[slug]; + + if (!root2.success()) { + printerData.isPrinting = false; + printerData.toolTemp = ""; + printerData.toolTargetTemp = ""; + printerData.bedTemp = ""; + printerData.bedTargetTemp = (const char*) pr2["heatBeds"][0]["tempSet"]; + return; + } + + printerData.toolTemp = (const char*) pr2["extruder"][0]["tempRead"]; + printerData.toolTargetTemp = (const char*) pr2["extruder"][0]["tempSet"]; + printerData.bedTemp = (const char*) pr2["heatedBeds"][0]["tempRead"]; + printerData.bedTargetTemp = (const char*) pr2["heatedBeds"][0]["tempSet"]; + + if (printerData.isPrinting) { + Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); + } +} + +void RepetierClient::getPrinterPsuState() { + //**** get the PSU state (if enabled and printer operational) + //Not implemented in Repetier Server AFAIK +} + +// Reset all PrinterData +void RepetierClient::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 RepetierClient::getAveragePrintTime(){ + return printerData.averagePrintTime; +} + +String RepetierClient::getEstimatedPrintTime() { + return printerData.estimatedPrintTime; +} + +String RepetierClient::getFileName() { + return printerData.fileName; +} + +String RepetierClient::getFileSize() { + return printerData.fileSize; +} + +String RepetierClient::getLastPrintTime(){ + return printerData.lastPrintTime; +} + +String RepetierClient::getProgressCompletion() { + return String(printerData.progressCompletion.toInt()); +} + +String RepetierClient::getProgressFilepos() { + return printerData.progressFilepos; +} + +String RepetierClient::getProgressPrintTime() { + return printerData.progressPrintTime; +} + +String RepetierClient::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 RepetierClient::getState() { + return printerData.state; +} + +boolean RepetierClient::isPrinting() { + return printerData.isPrinting; +} + +boolean RepetierClient::isPSUoff() { + return printerData.isPSUoff; +} + +boolean RepetierClient::isOperational() { + boolean operational = false; + if (printerData.state == "Operational" || isPrinting()) { + operational = true; + } + return operational; +} + +String RepetierClient::getTempBedActual() { + return printerData.bedTemp; +} + +String RepetierClient::getTempBedTarget() { + return printerData.bedTargetTemp; +} + +String RepetierClient::getTempToolActual() { + return printerData.toolTemp; +} + +String RepetierClient::getTempToolTarget() { + return printerData.toolTargetTemp; +} + +String RepetierClient::getFilamentLength() { + return printerData.filamentLength; +} + +String RepetierClient::getError() { + return printerData.error; +} + +String RepetierClient::getValueRounded(String value) { + float f = value.toFloat(); + int rounded = (int)(f+0.5f); + return String(rounded); +} + +String RepetierClient::getPrinterType() { + return printerType; +} diff --git a/printermonitor/RepetierClient.h b/printermonitor/RepetierClient.h index ed862d5..f6e6b1c 100644 --- a/printermonitor/RepetierClient.h +++ b/printermonitor/RepetierClient.h @@ -37,6 +37,7 @@ private: String myApiKey = ""; String encodedAuth = ""; boolean pollPsu; + const String printerType = "Repetier"; void resetPrintData(); boolean validate(); @@ -95,4 +96,5 @@ public: String getFilamentLength(); String getValueRounded(String value); String getError(); + String getPrinterType(); }; diff --git a/printermonitor/printermonitor.ino b/printermonitor/printermonitor.ino index 635a914..52834fd 100644 --- a/printermonitor/printermonitor.ino +++ b/printermonitor/printermonitor.ino @@ -87,10 +87,8 @@ boolean displayOn = true; // Printer Client #if defined(USE_REPETIER_CLIENT) RepetierClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); - String printerType = "Repetier"; #else OctoPrintClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); - String printerType = "OctoPrint"; #endif int printerCount = 0; @@ -113,12 +111,12 @@ String WEB_ACTIONS = " About"; String CHANGE_FORM = "