Added state flags for all printer clients

pull/125/head
Robert Stein 2020-12-15 06:44:14 +01:00
parent d736cd31c0
commit 80bb11a87e
9 changed files with 130 additions and 220 deletions

View File

@ -5,6 +5,13 @@
#include "Debug.h" #include "Debug.h"
#include "../Network/JsonRequestClient.h" #include "../Network/JsonRequestClient.h"
#define PRINTER_STATE_OFFLINE (int)-2
#define PRINTER_STATE_ERROR (int)-1
#define PRINTER_STATE_STANDBY (int)0
#define PRINTER_STATE_PRINTING (int)1
#define PRINTER_STATE_PAUSED (int)2
#define PRINTER_STATE_COMPLETED (int)3
class BasePrinterClient { class BasePrinterClient {
public: public:
virtual void getPrinterJobResults(); virtual void getPrinterJobResults();
@ -20,7 +27,8 @@ public:
virtual String getProgressFilepos() = 0; virtual String getProgressFilepos() = 0;
virtual String getProgressPrintTime() = 0; virtual String getProgressPrintTime() = 0;
virtual String getProgressPrintTimeLeft() = 0; virtual String getProgressPrintTimeLeft() = 0;
virtual String getState() = 0; virtual int getState() = 0;
virtual String getStateAsText() = 0;
virtual boolean isPrinting() = 0; virtual boolean isPrinting() = 0;
virtual boolean isOperational() = 0; virtual boolean isOperational() = 0;
virtual boolean isPSUoff() = 0; virtual boolean isPSUoff() = 0;

View File

@ -23,7 +23,7 @@ void BasePrinterClientImpl::resetPrintData() {
this->printerData.progressFilepos = ""; this->printerData.progressFilepos = "";
this->printerData.progressPrintTime = ""; this->printerData.progressPrintTime = "";
this->printerData.progressPrintTimeLeft = ""; this->printerData.progressPrintTimeLeft = "";
this->printerData.state = ""; this->printerData.state = PRINTER_STATE_OFFLINE;
this->printerData.toolTemp = ""; this->printerData.toolTemp = "";
this->printerData.toolTargetTemp = ""; this->printerData.toolTargetTemp = "";
this->printerData.filamentLength = ""; this->printerData.filamentLength = "";
@ -74,10 +74,28 @@ String BasePrinterClientImpl::getProgressPrintTimeLeft() {
return rtnValue; return rtnValue;
} }
String BasePrinterClientImpl::getState() { int BasePrinterClientImpl::getState() {
return printerData.state; return printerData.state;
} }
String BasePrinterClientImpl::getStateAsText() {
switch (this->getState())
{
case PRINTER_STATE_ERROR:
return "Error";
case PRINTER_STATE_STANDBY:
return "Standby";
case PRINTER_STATE_PRINTING:
return "Printing";
case PRINTER_STATE_PAUSED:
return "Paused";
case PRINTER_STATE_COMPLETED:
return "Completed";
default:
return "Offline";
}
}
boolean BasePrinterClientImpl::isPrinting() { boolean BasePrinterClientImpl::isPrinting() {
return printerData.isPrinting; return printerData.isPrinting;
} }
@ -88,7 +106,7 @@ boolean BasePrinterClientImpl::isPSUoff() {
boolean BasePrinterClientImpl::isOperational() { boolean BasePrinterClientImpl::isOperational() {
boolean operational = false; boolean operational = false;
if (printerData.state == "I" || isPrinting()) { if ((printerData.state != PRINTER_STATE_OFFLINE) || isPrinting()) {
operational = true; operational = true;
} }
return operational; return operational;

View File

@ -20,7 +20,7 @@ protected:
String progressFilepos; String progressFilepos;
String progressPrintTime; String progressPrintTime;
String progressPrintTimeLeft; String progressPrintTimeLeft;
String state; int state;
String toolTemp; String toolTemp;
String toolTargetTemp; String toolTargetTemp;
String filamentLength; String filamentLength;
@ -53,7 +53,8 @@ public:
String getProgressFilepos(); String getProgressFilepos();
String getProgressPrintTime(); String getProgressPrintTime();
String getProgressPrintTimeLeft(); String getProgressPrintTimeLeft();
String getState(); int getState();
String getStateAsText();
boolean isPrinting(); boolean isPrinting();
boolean isOperational(); boolean isOperational();
boolean isPSUoff(); boolean isPSUoff();
@ -69,6 +70,7 @@ public:
String getPrinterName(); String getPrinterName();
void setPrinterName(String printer); void setPrinterName(String printer);
protected: protected:
String getInstanceServerTarget(); String getInstanceServerTarget();
int getInstanceServerPort(); int getInstanceServerPort();

View File

@ -1,4 +1,4 @@
// Moonraker API: https://github.com/Arksine/moonraker/blob/master/docs/web_api.md // DUET API: https://reprap.org/wiki/RepRap_Firmware_Status_responses
// ArduinoJSON Assistant: https://arduinojson.org/v6/assistant/ // ArduinoJSON Assistant: https://arduinojson.org/v6/assistant/
#include "DuetClient.h" #include "DuetClient.h"
@ -30,9 +30,6 @@ boolean DuetClient::validate() {
return rtnValue; return rtnValue;
} }
void DuetClient::getPrinterJobResults() { void DuetClient::getPrinterJobResults() {
// const size_t bufferSize = JSON_ARRAY_SIZE(4) + JSON_OBJECT_SIZE(1) + 4*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(9) + 426; // const size_t bufferSize = JSON_ARRAY_SIZE(4) + JSON_OBJECT_SIZE(1) + 4*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(9) + 426;
const size_t bufferSize = 2048; // according to ArduinoJson assistant const size_t bufferSize = 2048; // according to ArduinoJson assistant
@ -56,7 +53,7 @@ void DuetClient::getPrinterJobResults() {
if (this->jsonRequestClient->getLastError() != "") { if (this->jsonRequestClient->getLastError() != "") {
this->debugController->printLn(this->jsonRequestClient->getLastError()); this->debugController->printLn(this->jsonRequestClient->getLastError());
printerData.error = this->jsonRequestClient->getLastError(); printerData.error = this->jsonRequestClient->getLastError();
printerData.state = ""; printerData.state = PRINTER_STATE_OFFLINE;
printerData.isPrinting = false; printerData.isPrinting = false;
printerData.toolTemp = ""; printerData.toolTemp = "";
printerData.toolTargetTemp = ""; printerData.toolTargetTemp = "";
@ -65,22 +62,25 @@ void DuetClient::getPrinterJobResults() {
return; return;
} }
printerData.state = (const char*)(*jsonDoc)["status"]; printerData.state = this->translateState((const char*)(*jsonDoc)["status"]);
if (printerData.state == "P") {
printerData.isPrinting = true;
} else {
printerData.isPrinting = false;
}
if (BasePrinterClientImpl::isOperational()) { if (BasePrinterClientImpl::isOperational()) {
this->debugController->printLn("Status: " + printerData.state); this->debugController->printLn("Status: " + printerData.state);
} else { } else {
this->debugController->printLn("Printer Not Operational"); this->debugController->printLn("Printer Not Operational");
} }
if (printerData.state == PRINTER_STATE_PRINTING) {
printerData.isPrinting = true;
} else {
// We dont printing, so abort function here
printerData.isPrinting = false;
return;
}
// Req 2 // Req 2
if (printerData.state == "P") { jsonDoc = this->jsonRequestClient->requestJson(
jsonDoc = this->jsonRequestClient->requestJson(
PRINTER_REQUEST_GET, PRINTER_REQUEST_GET,
this->getInstanceServerTarget(), this->getInstanceServerTarget(),
this->getInstanceServerPort(), this->getInstanceServerPort(),
@ -93,7 +93,7 @@ void DuetClient::getPrinterJobResults() {
if (this->jsonRequestClient->getLastError() != "") { if (this->jsonRequestClient->getLastError() != "") {
this->debugController->printLn(this->jsonRequestClient->getLastError()); this->debugController->printLn(this->jsonRequestClient->getLastError());
printerData.error = this->jsonRequestClient->getLastError(); printerData.error = this->jsonRequestClient->getLastError();
printerData.state = ""; printerData.state = PRINTER_STATE_OFFLINE;
printerData.isPrinting = false; printerData.isPrinting = false;
printerData.toolTemp = ""; printerData.toolTemp = "";
printerData.toolTargetTemp = ""; printerData.toolTargetTemp = "";
@ -119,100 +119,9 @@ void DuetClient::getPrinterJobResults() {
*/ */
float totalPrintTime = printerData.progressPrintTime.toFloat() / fileProgress; float totalPrintTime = printerData.progressPrintTime.toFloat() / fileProgress;
printerData.progressPrintTimeLeft = String(totalPrintTime - printerData.progressPrintTime.toFloat()); printerData.progressPrintTimeLeft = String(totalPrintTime - printerData.progressPrintTime.toFloat());
}
// // Req 3
// jsonDoc = this->jsonRequestClient->requestJson(
// PRINTER_REQUEST_GET,
// this->getInstanceServerTarget(),
// this->getInstanceServerPort(),
// this->encodedAuth,
// "/printer/objects/query?toolhead&virtual_sdcard",
// "",
// bufferSize,
// true
// );
// if (this->jsonRequestClient->getLastError() != "") {
// this->debugController->printLn(this->jsonRequestClient->getLastError());
// printerData.error = this->jsonRequestClient->getLastError();
// printerData.state = "";
// printerData.isPrinting = false;
// printerData.toolTemp = "";
// printerData.toolTargetTemp = "";
// printerData.bedTemp = "";
// printerData.bedTargetTemp = "";
// return;
// }
// float fileProgress = (float)(*jsonDoc)["result"]["status"]["virtual_sdcard"]["progress"];
// printerData.progressFilepos = (const char*)(*jsonDoc)["result"]["status"]["virtual_sdcard"]["file_position"];
// printerData.estimatedPrintTime = (float)(*jsonDoc)["result"]["status"]["toolhead"]["estimated_print_time"];
// /*
// printerData.progressPrintTimeLeft : No metadata is available, print duration and progress can be used to calculate the ETA:
// */
// float totalPrintTime = printerData.progressPrintTime.toFloat() / fileProgress;
// printerData.progressPrintTimeLeft = String(totalPrintTime - printerData.progressPrintTime.toFloat());
// // &webhooks&virtual_sdcard&print_stats
/*
printerData.averagePrintTime = (int)jsonBuffer["result"]["status"]["toolhead"]["averagePrintTime"];
// printerData.fileSize = (const char*)jsonBuffer["job"]["file"]["size"];
printerData.lastPrintTime = (const char*)jsonBuffer["job"]["lastPrintTime"];
;
*/
/**
printerData.progressPrintTimeLeft :
If no metadata is available, print duration and progress can be used to calculate the ETA:
// assume "result" is the response from the status query
let vsd = result.status.virtual_sdcard;
let pstats = result.status.print_stats;
let total_time = pstats.print_duration / vsd.progress;
let eta = total_time - pstats.print_duration; */
/*
// get the fileseize
apiGetData = "GET /server/files/metadata?filename=" + printerData.fileName;
printClient = getSubmitRequest(apiGetData);
if (printerData.error != "") {
return;
}
const size_t bufferSize2 = JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(8) + 128;
DynamicJsonDocument jsonBuffer2(bufferSize2);
// Parse JSON object
DeserializationError error2 = deserializeJson(jsonBuffer2, printClient);
if (error2) {
printerData.isPrinting = false;
printerData.toolTemp = "";
printerData.toolTargetTemp = "";
printerData.bedTemp = "";
printerData.bedTargetTemp = (int)jsonBuffer["result"]["status"]["heater_bed"]["target"];
return;
}
String printing = (const char*)jsonBuffer["result"]["status"]["print_stats"]["state"];
printerData.fileSize = (long)jsonBuffer2["result"]["size"];
*/
if (BasePrinterClientImpl::isOperational()) { if (BasePrinterClientImpl::isOperational()) {
this->debugController->printLn("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); this->debugController->printLn("Status: " + this->getStateAsText() + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)");
} }
} }
@ -251,3 +160,35 @@ void DuetClient::getPrinterPsuState() {
printerData.isPSUoff = false; // we are not checking PSU state, so assume on printerData.isPSUoff = false; // we are not checking PSU state, so assume on
} */ } */
} }
/**
* We translate the avail states
* - C (configuration file is being processed)
* - I (idle, no movement or code is being performed)
* - B (busy, live movement is in progress or a macro file is being run)
* - P (printing a file)
* - D (decelerating, pausing a running print)
* - S (stopped, live print has been paused)
* - R (resuming a paused print)
* - H (halted, after emergency stop)
* - F (flashing new firmware)
* - T (changing tool, new in 1.17b)
*/
int DuetClient::translateState(String stateText) {
stateText.toLowerCase();
stateText.trim();
if (stateText == "i" || stateText == "t" || stateText == "b" || stateText == "c" || stateText == "f" || stateText == "t") {
return PRINTER_STATE_STANDBY;
}
if (stateText == "p" || stateText == "r") {
return PRINTER_STATE_PRINTING;
}
if (stateText == "d" || stateText == "s") {
return PRINTER_STATE_PAUSED;
}
if (stateText == "h") {
return PRINTER_STATE_ERROR;
}
return PRINTER_STATE_OFFLINE;
}

View File

@ -18,4 +18,6 @@ public:
void getPrinterJobResults() override; void getPrinterJobResults() override;
void getPrinterPsuState() override; void getPrinterPsuState() override;
void updatePrintClient() override; void updatePrintClient() override;
int translateState(String stateText);
}; };

View File

@ -30,9 +30,6 @@ boolean KlipperClient::validate() {
return rtnValue; return rtnValue;
} }
void KlipperClient::getPrinterJobResults() { void KlipperClient::getPrinterJobResults() {
// const size_t bufferSize = JSON_ARRAY_SIZE(4) + JSON_OBJECT_SIZE(1) + 4*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(9) + 426; // const size_t bufferSize = JSON_ARRAY_SIZE(4) + JSON_OBJECT_SIZE(1) + 4*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(9) + 426;
const size_t bufferSize = 1536; // according to ArduinoJson assistant const size_t bufferSize = 1536; // according to ArduinoJson assistant
@ -56,7 +53,7 @@ void KlipperClient::getPrinterJobResults() {
if (this->jsonRequestClient->getLastError() != "") { if (this->jsonRequestClient->getLastError() != "") {
this->debugController->printLn(this->jsonRequestClient->getLastError()); this->debugController->printLn(this->jsonRequestClient->getLastError());
printerData.error = this->jsonRequestClient->getLastError(); printerData.error = this->jsonRequestClient->getLastError();
printerData.state = ""; printerData.state = PRINTER_STATE_OFFLINE;
printerData.isPrinting = false; printerData.isPrinting = false;
printerData.toolTemp = ""; printerData.toolTemp = "";
printerData.toolTargetTemp = ""; printerData.toolTargetTemp = "";
@ -65,25 +62,27 @@ void KlipperClient::getPrinterJobResults() {
return; return;
} }
printerData.state = (const char*)(*jsonDoc)["result"]["status"]["print_stats"]["state"]; printerData.state = this->translateState((const char*)(*jsonDoc)["result"]["status"]["print_stats"]["state"]);
printerData.filamentLength = (const char*)(*jsonDoc)["result"]["status"]["job"]["print_stats"]["filament_used"]; printerData.filamentLength = (const char*)(*jsonDoc)["result"]["status"]["job"]["print_stats"]["filament_used"];
printerData.progressPrintTime = (const char*)(*jsonDoc)["result"]["status"]["print_stats"]["print_duration"]; printerData.progressPrintTime = (const char*)(*jsonDoc)["result"]["status"]["print_stats"]["print_duration"];
printerData.fileName = (const char*)(*jsonDoc)["result"]["status"]["print_stats"]["filename"]; printerData.fileName = (const char*)(*jsonDoc)["result"]["status"]["print_stats"]["filename"];
if (printerData.state == "printing") {
printerData.isPrinting = true;
} else {
printerData.isPrinting = false;
}
if (BasePrinterClientImpl::isOperational()) { if (BasePrinterClientImpl::isOperational()) {
this->debugController->printLn("Status: " + printerData.state); this->debugController->printLn("Status: " + printerData.state);
} else { } else {
this->debugController->printLn("Printer Not Operational"); this->debugController->printLn("Printer Not Operational");
} }
if (printerData.state == PRINTER_STATE_PRINTING) {
printerData.isPrinting = true;
} else {
// We dont printing, so abort function here
printerData.isPrinting = false;
return;
}
// Req 2 // Req 2
if (printerData.state == "printing") { jsonDoc = this->jsonRequestClient->requestJson(
jsonDoc = this->jsonRequestClient->requestJson(
PRINTER_REQUEST_GET, PRINTER_REQUEST_GET,
this->getInstanceServerTarget(), this->getInstanceServerTarget(),
this->getInstanceServerPort(), this->getInstanceServerPort(),
@ -96,7 +95,7 @@ void KlipperClient::getPrinterJobResults() {
if (this->jsonRequestClient->getLastError() != "") { if (this->jsonRequestClient->getLastError() != "") {
this->debugController->printLn(this->jsonRequestClient->getLastError()); this->debugController->printLn(this->jsonRequestClient->getLastError());
printerData.error = this->jsonRequestClient->getLastError(); printerData.error = this->jsonRequestClient->getLastError();
printerData.state = ""; printerData.state = PRINTER_STATE_OFFLINE;
printerData.isPrinting = false; printerData.isPrinting = false;
printerData.toolTemp = ""; printerData.toolTemp = "";
printerData.toolTargetTemp = ""; printerData.toolTargetTemp = "";
@ -120,99 +119,8 @@ void KlipperClient::getPrinterJobResults() {
float totalPrintTime = printerData.progressPrintTime.toFloat() / fileProgress; float totalPrintTime = printerData.progressPrintTime.toFloat() / fileProgress;
printerData.progressPrintTimeLeft = String(totalPrintTime - printerData.progressPrintTime.toFloat()); printerData.progressPrintTimeLeft = String(totalPrintTime - printerData.progressPrintTime.toFloat());
}
// // Req 3
// jsonDoc = this->jsonRequestClient->requestJson(
// PRINTER_REQUEST_GET,
// this->getInstanceServerTarget(),
// this->getInstanceServerPort(),
// this->encodedAuth,
// "/printer/objects/query?toolhead&virtual_sdcard",
// "",
// bufferSize,
// true
// );
// if (this->jsonRequestClient->getLastError() != "") {
// this->debugController->printLn(this->jsonRequestClient->getLastError());
// printerData.error = this->jsonRequestClient->getLastError();
// printerData.state = "";
// printerData.isPrinting = false;
// printerData.toolTemp = "";
// printerData.toolTargetTemp = "";
// printerData.bedTemp = "";
// printerData.bedTargetTemp = "";
// return;
// }
// float fileProgress = (float)(*jsonDoc)["result"]["status"]["virtual_sdcard"]["progress"];
// printerData.progressFilepos = (const char*)(*jsonDoc)["result"]["status"]["virtual_sdcard"]["file_position"];
// printerData.estimatedPrintTime = (float)(*jsonDoc)["result"]["status"]["toolhead"]["estimated_print_time"];
// /*
// printerData.progressPrintTimeLeft : No metadata is available, print duration and progress can be used to calculate the ETA:
// */
// float totalPrintTime = printerData.progressPrintTime.toFloat() / fileProgress;
// printerData.progressPrintTimeLeft = String(totalPrintTime - printerData.progressPrintTime.toFloat());
// // &webhooks&virtual_sdcard&print_stats
/*
printerData.averagePrintTime = (int)jsonBuffer["result"]["status"]["toolhead"]["averagePrintTime"];
// printerData.fileSize = (const char*)jsonBuffer["job"]["file"]["size"];
printerData.lastPrintTime = (const char*)jsonBuffer["job"]["lastPrintTime"];
;
*/
/**
printerData.progressPrintTimeLeft :
If no metadata is available, print duration and progress can be used to calculate the ETA:
// assume "result" is the response from the status query
let vsd = result.status.virtual_sdcard;
let pstats = result.status.print_stats;
let total_time = pstats.print_duration / vsd.progress;
let eta = total_time - pstats.print_duration; */
/*
// get the fileseize
apiGetData = "GET /server/files/metadata?filename=" + printerData.fileName;
printClient = getSubmitRequest(apiGetData);
if (printerData.error != "") {
return;
}
const size_t bufferSize2 = JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(8) + 128;
DynamicJsonDocument jsonBuffer2(bufferSize2);
// Parse JSON object
DeserializationError error2 = deserializeJson(jsonBuffer2, printClient);
if (error2) {
printerData.isPrinting = false;
printerData.toolTemp = "";
printerData.toolTargetTemp = "";
printerData.bedTemp = "";
printerData.bedTargetTemp = (int)jsonBuffer["result"]["status"]["heater_bed"]["target"];
return;
}
String printing = (const char*)jsonBuffer["result"]["status"]["print_stats"]["state"];
printerData.fileSize = (long)jsonBuffer2["result"]["size"];
*/
if (BasePrinterClientImpl::isOperational()) { if (BasePrinterClientImpl::isOperational()) {
this->debugController->printLn("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); this->debugController->printLn("Status: " + this->getStateAsText() + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)");
} }
} }
@ -251,3 +159,32 @@ void KlipperClient::getPrinterPsuState() {
printerData.isPSUoff = false; // we are not checking PSU state, so assume on printerData.isPSUoff = false; // we are not checking PSU state, so assume on
} */ } */
} }
/**
* We translate the avail states
* - "standby": No print in progress
* - "printing": The printer is currently printing
* - "paused": A print in progress has been paused
* - "error": The print exited with an error. print_stats.message contains a related error message
* - "complete": The last print has completed
*/
int KlipperClient::translateState(String stateText) {
stateText.toLowerCase();
stateText.trim();
if (stateText == "standby") {
return PRINTER_STATE_STANDBY;
}
if (stateText == "printing") {
return PRINTER_STATE_PRINTING;
}
if (stateText == "paused") {
return PRINTER_STATE_PAUSED;
}
if (stateText == "complete") {
return PRINTER_STATE_COMPLETED;
}
if (stateText == "error") {
return PRINTER_STATE_ERROR;
}
return PRINTER_STATE_OFFLINE;
}

View File

@ -18,4 +18,6 @@ public:
void getPrinterJobResults() override; void getPrinterJobResults() override;
void getPrinterPsuState() override; void getPrinterPsuState() override;
void updatePrintClient() override; void updatePrintClient() override;
int translateState(String stateText);
}; };

View File

@ -339,7 +339,7 @@ void OledDisplay::drawClockHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiStat
} }
if (printerClient->isPSUoff()) { if (printerClient->isPSUoff()) {
display->drawString(printerStateDrawXPos, 47, "psu off"); display->drawString(printerStateDrawXPos, 47, "psu off");
} else if (printerClient->getState() == "Operational") { } else if (printerClient->getState() != PRINTER_STATE_OFFLINE) {
display->drawString(printerStateDrawXPos, 47, "online"); display->drawString(printerStateDrawXPos, 47, "online");
} else { } else {
display->drawString(printerStateDrawXPos, 47, "offline"); display->drawString(printerStateDrawXPos, 47, "offline");

View File

@ -182,7 +182,7 @@ void WebServer::displayPrinterStatus() {
html += "Status: Offline<br>"; html += "Status: Offline<br>";
html += "Reason: " + printerClient->getError() + "<br>"; html += "Reason: " + printerClient->getError() + "<br>";
} else { } else {
html += "Status: " + printerClient->getState(); html += "Status: " + printerClient->getStateAsText();
if (printerClient->isPSUoff() && this->globalDataController->hasPrinterPsu()) { if (printerClient->isPSUoff() && this->globalDataController->hasPrinterPsu()) {
html += ", PSU off"; html += ", PSU off";
} }