From 83f1dfa8db8e3be7bd63949cdd90fe8a982f53d8 Mon Sep 17 00:00:00 2001 From: Matthias Grimm Date: Sun, 6 Dec 2020 17:23:14 -0600 Subject: [PATCH] Initial Duet implementation Inintial rudimentary Duet implementation --- printermonitor/DuetClient.cpp | 418 ++++++++++++++++++++++++++++++ printermonitor/DuetClient.h | 105 ++++++++ printermonitor/Settings.h | 15 +- printermonitor/printermonitor.ino | 3 + printermonitor/request-2.json | 157 +++++++++++ printermonitor/request-3.json | 107 ++++++++ 6 files changed, 799 insertions(+), 6 deletions(-) create mode 100644 printermonitor/DuetClient.cpp create mode 100644 printermonitor/DuetClient.h create mode 100644 printermonitor/request-2.json create mode 100644 printermonitor/request-3.json diff --git a/printermonitor/DuetClient.cpp b/printermonitor/DuetClient.cpp new file mode 100644 index 0000000..6667b98 --- /dev/null +++ b/printermonitor/DuetClient.cpp @@ -0,0 +1,418 @@ +/** 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 */ +/* 12/6/20 : Matthias Grimm : Add Duet Monitor */ + +#include "DuetClient.h" + +DuetClient::DuetClient(String ApiKey, String server, int port, String user, String pass, boolean psu) { + updatePrintClient(ApiKey, server, port, user, pass, psu); +} + +void DuetClient::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 DuetClient::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 DuetClient::getSubmitRequest(String apiGetData) { + WiFiClient printClient; + printClient.setTimeout(5000); + + Serial.println("Getting Duet 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 Duet failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect + Serial.println(); + resetPrintData(); + printerData.error = "Connection to Duet 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 DuetClient::getPostRequest(String apiPostData, String apiPostBody) { + WiFiClient printClient; + printClient.setTimeout(5000); + + Serial.println("Getting Duet 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 Duet failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect + Serial.println(); + resetPrintData(); + printerData.error = "Connection to Duet 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 DuetClient::getPrinterJobResults() { + if (!validate()) { + return; + } + //**** get the Printer Job status + String apiGetData = "GET rr_status?type=3"; + 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("Duet Data Parsing failed: " + String(myServer) + ":" + String(myPort)); + printerData.error = "Duet Data Parsing failed: " + String(myServer) + ":" + String(myPort); + printerData.state = ""; + return; + } + + printerData.averagePrintTime = (const char*)root["job"]["averagePrintTime"]; + printerData.estimatedPrintTime = (const char*)root["printDuration"]; + 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["fractionPrinted"]; + 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["status"]; + + + if (isOperational()) { + Serial.println("Status: " + printerData.state); + } else { + Serial.println("Printer Not Operational"); + } + + //**** get the Printer Temps and Stat + apiGetData = "GET /rr_status?type=2"; + 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["temps"]["bed"]["active"]; + return; + } + + String printing = (const char*)root2["status"]; + if (printing == "I") { + printerData.isPrinting = true; + } else { + printerData.isPrinting = false; + } + printerData.toolTemp = (const char*)root2["temps"]["tools"]["active"][0]; + printerData.toolTargetTemp = (const char*)root2["temps"]["current"][1]; + 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 "); + + if (isPrinting()) { + Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); + } +} + +void DuetClient::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"; + 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 DuetClient::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 DuetClient::getAveragePrintTime(){ + return printerData.averagePrintTime; +} + +String DuetClient::getEstimatedPrintTime() { + return printerData.estimatedPrintTime; +} + +String DuetClient::getFileName() { + return printerData.fileName; +} + +String DuetClient::getFileSize() { + return printerData.fileSize; +} + +String DuetClient::getLastPrintTime(){ + return printerData.lastPrintTime; +} + +String DuetClient::getProgressCompletion() { + return String(printerData.progressCompletion.toInt()); +} + +String DuetClient::getProgressFilepos() { + return printerData.progressFilepos; +} + +String DuetClient::getProgressPrintTime() { + return printerData.progressPrintTime; +} + +String DuetClient::getProgressPrintTimeLeft() { + String rtnValue = printerData.progressPrintTimeLeft; + if (getProgressCompletion() == "100") { + rtnValue = "0"; // Print is done so this should be 0 this is a fix for Duet + } + return rtnValue; +} + +String DuetClient::getState() { + return printerData.state; +} + +boolean DuetClient::isPrinting() { + return printerData.isPrinting; +} + +boolean DuetClient::isPSUoff() { + return printerData.isPSUoff; +} + +boolean DuetClient::isOperational() { + boolean operational = false; + if (printerData.state == "Operational" || isPrinting()) { + operational = true; + } + return operational; +} + +String DuetClient::getTempBedActual() { + return printerData.bedTemp; +} + +String DuetClient::getTempBedTarget() { + return printerData.bedTargetTemp; +} + +String DuetClient::getTempToolActual() { + return printerData.toolTemp; +} + +String DuetClient::getTempToolTarget() { + return printerData.toolTargetTemp; +} + +String DuetClient::getFilamentLength() { + return printerData.filamentLength; +} + +String DuetClient::getError() { + return printerData.error; +} + +String DuetClient::getValueRounded(String value) { + float f = value.toFloat(); + int rounded = (int)(f+0.5f); + return String(rounded); +} + +String DuetClient::getPrinterType() { + return printerType; +} + +int DuetClient::getPrinterPort() { + return myPort; +} + +String DuetClient::getPrinterName() { + return printerData.printerName; +} + +void DuetClient::setPrinterName(String printer) { + printerData.printerName = printer; +} diff --git a/printermonitor/DuetClient.h b/printermonitor/DuetClient.h new file mode 100644 index 0000000..47a832d --- /dev/null +++ b/printermonitor/DuetClient.h @@ -0,0 +1,105 @@ +/** 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 */ +/* 12/6/20 : Matthias Grimm : Add Duet Monitor */ + +#pragma once +#include +#include "libs/ArduinoJson/ArduinoJson.h" +#include + +class DuetClient { + +private: + char myServer[100]; + int myPort = 80; + String myApiKey = ""; + String encodedAuth = ""; + boolean pollPsu; + const String printerType = "Duet"; + + 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: + DuetClient(String PrinterApiKey, String server, int port, String user, String pass, boolean psu); + void getPrinterJobResults(); + void getPrinterPsuState(); + void updatePrintClient(String PrinterApiKey, 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/Settings.h b/printermonitor/Settings.h index a149b82..a283311 100644 --- a/printermonitor/Settings.h +++ b/printermonitor/Settings.h @@ -23,6 +23,7 @@ SOFTWARE. // Additional Contributions: /* 15 Jan 2019 : Owen Carter : Add psucontrol setting */ +/* 12/6/20 : Matthias Grimm : Add Duet Monitor */ /****************************************************************************** * Printer Monitor is designed for the Wemos D1 ESP8266 @@ -45,6 +46,7 @@ SOFTWARE. #include #include #include "TimeClient.h" +#include "DuetClient.h" #include "RepetierClient.h" #include "OctoPrintClient.h" #include "OpenWeatherMapClient.h" @@ -58,10 +60,11 @@ SOFTWARE. // Start Settings //****************************** -// OctoPrint / Repetier Monitoring -- Monitor your 3D OctoPrint or Repetier Server +// OctoPrint / Repetier / 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_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 -String PrinterHostName = "octopi";// Default 'octopi' -- or hostname if different (optional if your IP changes) +String PrinterHostName = "";// Default 'octopi' -- or hostname if different (optional if your IP changes) String PrinterServer = ""; // IP or Address of your OctoPrint / Repetier Server (DO NOT include http://) int PrinterPort = 80; // the port you are running your OctoPrint / Repetier server on (usually 80); String PrinterAuthUser = ""; // only used if you have haproxy or basic athentintication turned on (not default) @@ -71,7 +74,7 @@ String PrinterAuthPass = ""; // only used with haproxy or basic auth (only boolean DISPLAYWEATHER = true; // true = show weather when not printing / false = no weather String WeatherApiKey = ""; // Your API Key from http://openweathermap.org/ // Default City Location (use http://openweathermap.org/find to find city ID) -int CityIDs[] = { 5304391 }; //Only USE ONE for weather marquee +int CityIDs[] = { 4923482 }; //Only USE ONE for weather marquee boolean IS_METRIC = false; // false = Imperial and true = Metric // Languages: ar, bg, ca, cz, de, el, en, fa, fi, fr, gl, hr, hu, it, ja, kr, la, lt, mk, nl, pl, pt, ro, ru, se, sk, sl, es, tr, ua, vi, zh_cn, zh_tw String WeatherLanguage = "en"; //Default (en) English @@ -84,7 +87,7 @@ char* www_username = "admin"; // User account for the Web Interface char* www_password = "password"; // Password for the Web Interface // Date and Time -float UtcOffset = -7; // Hour offset from GMT for your timezone +float UtcOffset = -6; // Hour offset from GMT for your timezone boolean IS_24HOUR = false; // 23:00 millitary 24 hour clock int minutesBetweenDataRefresh = 15; boolean DISPLAYCLOCK = true; // true = Show Clock when not printing / false = turn off display when not printing @@ -92,8 +95,8 @@ boolean DISPLAYCLOCK = true; // true = Show Clock when not printing / false = // Display Settings const int I2C_DISPLAY_ADDRESS = 0x3c; // I2C Address of your Display (usually 0x3c or 0x3d) const int SDA_PIN = D2; -const int SCL_PIN = D5; // original code D5 -- Monitor Easy Board use D1 -boolean INVERT_DISPLAY = false; // true = pins at top | false = pins at the bottom +const int SCL_PIN = D1; // original code D5 -- Monitor Easy Board use D1 +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 // LED Settings diff --git a/printermonitor/printermonitor.ino b/printermonitor/printermonitor.ino index 8849850..470aa3a 100644 --- a/printermonitor/printermonitor.ino +++ b/printermonitor/printermonitor.ino @@ -23,6 +23,7 @@ SOFTWARE. // Additional Contributions: /* 15 Jan 2019 : Owen Carter : Add psucontrol option and processing */ +/* 12/6/20 : Matthias Grimm : Add Duet Monitor */ /********************************************** * Edit Settings.h for personalization @@ -87,6 +88,8 @@ boolean displayOn = true; // Printer Client #if defined(USE_REPETIER_CLIENT) RepetierClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); +#elif defined(USE_DUET_CLIENT) + DuetClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); #else OctoPrintClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); #endif diff --git a/printermonitor/request-2.json b/printermonitor/request-2.json new file mode 100644 index 0000000..f88a7be --- /dev/null +++ b/printermonitor/request-2.json @@ -0,0 +1,157 @@ +{ + "status": "I", + "coords": { + "axesHomed": [ + 0, + 0, + 0 + ], + "wpl": 1, + "xyz": [ + 0.000, + 0.000, + 0.000 + ], + "machine": [ + 0.000, + 0.000, + 0.000 + ], + "extr": [ + 0.0 + ] + }, + "speeds": { + "requested": 0.0, + "top": 0.0 + }, + "currentTool": 0, + "params": { + "atxPower": -1, + "fanPercent": [ + 0, + 100, + 100 + ], + "fanNames": [ + "Parts Cooler", + "Hotend Cooler", + "Board Cooler" + ], + "speedFactor": 100.0, + "extrFactors": [ + 100.0 + ], + "babystep": 0.000 + }, + "seq": 1, + "sensors": { + "probeValue": 0, + "fanRPM": [ + -1, + -1, + -1 + ] + }, + "temps": { + "bed": { + "current": 22.7, + "active": 0.0, + "standby": 0.0, + "state": 0, + "heater": 0 + }, + "current": [ + 22.7, + 30.0 + ], + "state": [ + 0, + 2 + ], + "names": [ + "", + "" + ], + "tools": { + "active": [ + [ + 30.0 + ] + ], + "standby": [ + [ + 0.0 + ] + ] + }, + "extra": [ + { + "name": "*DRIVERS", + "temp": 0.0 + }, + { + "name": "*MCU", + "temp": 36.6 + } + ] + }, + "time": 27989.0, + "coldExtrudeTemp": 160.0, + "coldRetractTemp": 90.0, + "compensation": "None", + "controllableFans": 1, + "tempLimit": 285.0, + "endstops": 0, + "firmwareName": "RepRapFirmware for Duet 2 WiFi/Ethernet", + "firmwareVersion": "3.2-beta4", + "geometry": "coreXY", + "axes": 3, + "totalAxes": 3, + "axisNames": "XYZ", + "volumes": 2, + "mountedVolumes": 1, + "mode": "FFF", + "name": "Sapphire", + "probe": { + "threshold": 500, + "height": 2.28, + "type": 9 + }, + "tools": [ + { + "number": 0, + "heaters": [ + 1 + ], + "drives": [ + 0 + ], + "axisMap": [ + [ + 0 + ], + [ + 1 + ] + ], + "fans": 1, + "filament": "Atomic Red PLA", + "offsets": [ + 0.00, + 0.00, + 0.00 + ] + } + ], + "mcutemp": { + "min": 19.4, + "cur": 36.5, + "max": 37.1 + }, + "vin": { + "min": 23.9, + "cur": 24.1, + "max": 24.3 + } +} \ No newline at end of file diff --git a/printermonitor/request-3.json b/printermonitor/request-3.json new file mode 100644 index 0000000..0dc80fb --- /dev/null +++ b/printermonitor/request-3.json @@ -0,0 +1,107 @@ +{ + "status": "I", + "coords": { + "axesHomed": [ + 0, + 0, + 0 + ], + "wpl": 1, + "xyz": [ + 0.000, + 0.000, + 0.000 + ], + "machine": [ + 0.000, + 0.000, + 0.000 + ], + "extr": [ + 0.0 + ] + }, + "speeds": { + "requested": 0.0, + "top": 0.0 + }, + "currentTool": 0, + "params": { + "atxPower": -1, + "fanPercent": [ + 0, + 100, + 100 + ], + "speedFactor": 100.0, + "extrFactors": [ + 100.0 + ], + "babystep": 0.000 + }, + "seq": 0, + "sensors": { + "probeValue": 0, + "fanRPM": [ + -1, + -1, + -1 + ] + }, + "temps": { + "bed": { + "current": 22.1, + "active": 0.0, + "standby": 0.0, + "state": 0, + "heater": 0 + }, + "current": [ + 22.1, + 21.5 + ], + "state": [ + 0, + 2 + ], + "tools": { + "active": [ + [ + 0.0 + ] + ], + "standby": [ + [ + 0.0 + ] + ] + }, + "extra": [ + { + "name": "*DRIVERS", + "temp": 0.0 + }, + { + "name": "*MCU", + "temp": 36.2 + } + ] + }, + "time": 12265.0, + "currentLayer": 0, + "currentLayerTime": 0.0, + "extrRaw": [ + 0.0 + ], + "fractionPrinted": 0.0, + "filePosition": 0, + "firstLayerDuration": 0.0, + "firstLayerHeight": 0.00, + "printDuration": 0.0, + "warmUpDuration": 0.0, + "timesLeft": { + "file": 0.0, + "filament": 0.0, + "layer": 0.0 + } +} \ No newline at end of file