195 lines
7.5 KiB
C++
195 lines
7.5 KiB
C++
// DUET API: https://reprap.org/wiki/RepRap_Firmware_Status_responses
|
|
// ArduinoJSON Assistant: https://arduinojson.org/v6/assistant/
|
|
|
|
#include "DuetClient.h"
|
|
|
|
DuetClient::DuetClient(GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient)
|
|
: BasePrinterClientImpl("Duet", globalDataController, debugController, jsonRequestClient) {
|
|
this->updatePrintClient();
|
|
}
|
|
|
|
void DuetClient::updatePrintClient() {
|
|
encodedAuth = "";
|
|
if (this->globalDataController->getPrinterAuthUser() != "") {
|
|
String userpass = this->globalDataController->getPrinterAuthUser() + ":" + this->globalDataController->getPrinterAuthPass();
|
|
base64 b64;
|
|
encodedAuth = b64.encode(userpass, true);
|
|
}
|
|
pollPsu = this->globalDataController->hasPrinterPsu();
|
|
}
|
|
|
|
boolean DuetClient::validate() {
|
|
boolean rtnValue = false;
|
|
printerData.error = "";
|
|
if ((this->globalDataController->getPrinterServer() == "") && (this->globalDataController->getPrinterHostName() == "")) {
|
|
printerData.error += "Server address or host name is required; ";
|
|
}
|
|
if (printerData.error == "") {
|
|
rtnValue = true;
|
|
}
|
|
return rtnValue;
|
|
}
|
|
|
|
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 = 2048; // according to ArduinoJson assistant
|
|
DynamicJsonDocument *jsonDoc;
|
|
if (!validate()) {
|
|
return;
|
|
}
|
|
|
|
// Req 1
|
|
this->debugController->printLn("Get Duet Data: " + this->getInstanceServerTarget() + ":" + String(this->getInstanceServerPort()));
|
|
jsonDoc = this->jsonRequestClient->requestJson(
|
|
PRINTER_REQUEST_GET,
|
|
this->getInstanceServerTarget(),
|
|
this->getInstanceServerPort(),
|
|
this->encodedAuth,
|
|
"/rr_status?type=1",
|
|
"",
|
|
bufferSize,
|
|
true
|
|
);
|
|
if (this->jsonRequestClient->getLastError() != "") {
|
|
this->debugController->printLn(this->jsonRequestClient->getLastError());
|
|
printerData.error = this->jsonRequestClient->getLastError();
|
|
printerData.state = PRINTER_STATE_OFFLINE;
|
|
printerData.isPrinting = false;
|
|
printerData.toolTemp = "";
|
|
printerData.toolTargetTemp = "";
|
|
printerData.bedTemp = "";
|
|
printerData.bedTargetTemp = "";
|
|
return;
|
|
}
|
|
|
|
printerData.state = this->translateState((const char*)(*jsonDoc)["status"]);
|
|
|
|
if (BasePrinterClientImpl::isOperational()) {
|
|
this->debugController->printLn("Status: " + printerData.state);
|
|
} else {
|
|
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
|
|
jsonDoc = this->jsonRequestClient->requestJson(
|
|
PRINTER_REQUEST_GET,
|
|
this->getInstanceServerTarget(),
|
|
this->getInstanceServerPort(),
|
|
this->encodedAuth,
|
|
"/rr_status?type=3",
|
|
"",
|
|
bufferSize,
|
|
true
|
|
);
|
|
if (this->jsonRequestClient->getLastError() != "") {
|
|
this->debugController->printLn(this->jsonRequestClient->getLastError());
|
|
printerData.error = this->jsonRequestClient->getLastError();
|
|
printerData.state = PRINTER_STATE_OFFLINE;
|
|
printerData.isPrinting = false;
|
|
printerData.toolTemp = "";
|
|
printerData.toolTargetTemp = "";
|
|
printerData.bedTemp = "";
|
|
printerData.bedTargetTemp = "";
|
|
return;
|
|
}
|
|
|
|
printerData.filamentLength = (const char*)(*jsonDoc)["result"]["status"]["job"]["print_stats"]["filament_used"];
|
|
printerData.progressPrintTime = (const char*)(*jsonDoc)["printDuration"];
|
|
printerData.fileName = (const char*)(*jsonDoc)["result"]["status"]["print_stats"]["filename"];
|
|
printerData.progressCompletion = (int)(*jsonDoc)["fractionPrinted"];
|
|
printerData.toolTemp = (int)(*jsonDoc)["temps"]["current"][1];
|
|
printerData.toolTargetTemp = (int)(*jsonDoc)["temps"]["tools"]["active"][0][0];
|
|
printerData.bedTemp = (int)(*jsonDoc)["temps"]["bed"]["current"];
|
|
printerData.bedTargetTemp = (int)(*jsonDoc)["temps"]["bed"]["active"];
|
|
float fileProgress = (float)(*jsonDoc)["fractionPrinted"];
|
|
printerData.progressFilepos = (const char*)(*jsonDoc)["filePosition"];
|
|
printerData.estimatedPrintTime = (float)(*jsonDoc)["file"];
|
|
|
|
/*
|
|
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());
|
|
|
|
if (BasePrinterClientImpl::isOperational()) {
|
|
this->debugController->printLn("Status: " + this->getStateAsText() + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)");
|
|
}
|
|
}
|
|
|
|
void DuetClient::getPrinterPsuState() {
|
|
/*// get the PSU state (if enabled and printer operational)
|
|
if (pollPsu && BasePrinterClientImpl::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;
|
|
DynamicJsonDocument jsonBuffer(bufferSize3);
|
|
|
|
// Parse JSON object
|
|
DeserializationError error = deserializeJson(jsonBuffer, printClient);
|
|
if (error) {
|
|
printerData.isPSUoff = false; // we do not know PSU state, so assume on
|
|
return;
|
|
}
|
|
|
|
String psu = (const char*)jsonBuffer["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
|
|
} */
|
|
}
|
|
|
|
|
|
/**
|
|
* 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;
|
|
}
|