diff --git a/README.md b/README.md index 384d242..a57d519 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,9 @@ Now available is the Pre Loaded Monitor Board Kit that comes ready to plug and p * Displays the print status from OctoPrint or Repetier Server * Option to display time and weather when printer is idle * Estimated time remaining +* Estimated End Time +* Current Layer +* Total Layers * Time Printing * Percentage complete * Progress bar @@ -24,6 +27,7 @@ Now available is the Pre Loaded Monitor Board Kit that comes ready to plug and p * Fully configurable from the web interface (not required to update Settings.h) * Supports OTA (loading firmware over WiFi connection on same LAN) * Basic Authentication to protect your settings +* Next Scheduled Update * Version 2.2 added the ability to update firmware through web interface from a compiled binary * Can query the Octoprint [PSU Control plugin](https://plugins.octoprint.org/plugins/psucontrol/) to enter clock or blank mode when PSU is off * Repetier support added in version 3.0 -- define in Settings.h diff --git a/printermonitor/OctoPrintClient.cpp b/printermonitor/OctoPrintClient.cpp index 832835b..012de4a 100644 --- a/printermonitor/OctoPrintClient.cpp +++ b/printermonitor/OctoPrintClient.cpp @@ -244,6 +244,27 @@ void OctoPrintClient::getPrinterJobResults() { printerData.bedTemp = (const char*)root2["temperature"]["bed"]["actual"]; printerData.bedTargetTemp = (const char*)root2["temperature"]["bed"]["target"]; + // Layer & Endtime + apiGetData = "GET /plugin/DisplayLayerProgress/values HTTP/1.1"; + printClient = getSubmitRequest(apiGetData); + if (printerData.error != "") { + return; + } + const size_t bufferSize3 = JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(10) + 550; + DynamicJsonBuffer jsonBuffer3(bufferSize3); + + // Parse JSON object + JsonObject& root3 = jsonBuffer3.parseObject(printClient); + if (!root3.success()) { + printerData.estimatedEndTime = ""; + printerData.currentLayer = ""; + return; + } + + printerData.estimatedEndTime = (const char*)root3["print"]["estimatedEndTime"]; + printerData.currentLayer = (const char*)root3["layer"]["current"]; + printerData.totalLayers = (const char*)root3["layer"]["total"]; + if (isPrinting()) { Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); } @@ -305,6 +326,21 @@ void OctoPrintClient::resetPrintData() { printerData.isPrinting = false; printerData.isPSUoff = false; printerData.error = ""; + printerData.currentLayer = ""; + printerData.totalLayers = ""; + printerData.estimatedEndTime = ""; +} + +String OctoPrintClient::getCurrentLayer(){ + return printerData.currentLayer; +} + +String OctoPrintClient::getTotalLayers(){ + return printerData.totalLayers; +} + +String OctoPrintClient::getEstimatedEndTime(){ + return printerData.estimatedEndTime; } String OctoPrintClient::getAveragePrintTime(){ diff --git a/printermonitor/OctoPrintClient.h b/printermonitor/OctoPrintClient.h index 1761ccc..1253e9a 100644 --- a/printermonitor/OctoPrintClient.h +++ b/printermonitor/OctoPrintClient.h @@ -59,6 +59,9 @@ private: String state; String toolTemp; String toolTargetTemp; + String currentLayer; + String totalLayers; + String estimatedEndTime; String filamentLength; String bedTemp; String bedTargetTemp; @@ -95,6 +98,9 @@ public: String getTempToolActual(); String getTempToolTarget(); String getFilamentLength(); + String getEstimatedEndTime(); + String getCurrentLayer(); + String getTotalLayers(); String getValueRounded(String value); String getError(); String getPrinterType(); diff --git a/printermonitor/RepetierClient.cpp b/printermonitor/RepetierClient.cpp index e547916..3b961b2 100644 --- a/printermonitor/RepetierClient.cpp +++ b/printermonitor/RepetierClient.cpp @@ -220,6 +220,27 @@ void RepetierClient::getPrinterJobResults() { printerData.bedTemp = (const char*) pr2["heatedBeds"][0]["tempRead"]; printerData.bedTargetTemp = (const char*) pr2["heatedBeds"][0]["tempSet"]; + // Layer & Endtime + apiGetData = "GET /plugin/DisplayLayerProgress/values HTTP/1.1"; + printClient = getSubmitRequest(apiGetData); + if (printerData.error != "") { + return; + } + const size_t bufferSize3 = JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(10) + 550; + DynamicJsonBuffer jsonBuffer3(bufferSize3); + + // Parse JSON object + JsonObject& root3 = jsonBuffer3.parseObject(printClient); + if (!root3.success()) { + printerData.estimatedEndTime = ""; + printerData.currentLayer = ""; + return; + } + + printerData.estimatedEndTime = (const char*)root3["print"]["estimatedEndTime"]; + printerData.currentLayer = (const char*)root3["layer"]["current"]; + printerData.totalLayers = (const char*)root3["layer"]["total"]; + if (printerData.isPrinting) { Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)"); } @@ -249,9 +270,24 @@ void RepetierClient::resetPrintData() { printerData.bedTargetTemp = ""; printerData.isPrinting = false; printerData.isPSUoff = false; + printerData.currentLayer = ""; + printerData.totalLayers = ""; + printerData.estimatedEndTime = ""; printerData.error = ""; } +String RepetierClient::getCurrentLayer(){ + return printerData.currentLayer; +} + +String RepetierClient::getTotalLayers(){ + return printerData.totalLayers; +} + +String RepetierClient::getEstimatedEndTime(){ + return printerData.estimatedEndTime; +} + String RepetierClient::getAveragePrintTime(){ return printerData.averagePrintTime; } diff --git a/printermonitor/RepetierClient.h b/printermonitor/RepetierClient.h index 7c92105..6a64ace 100644 --- a/printermonitor/RepetierClient.h +++ b/printermonitor/RepetierClient.h @@ -59,6 +59,9 @@ private: String state; String toolTemp; String toolTargetTemp; + String currentLayer; + String totalLayers; + String estimatedEndTime; String filamentLength; String bedTemp; String bedTargetTemp; @@ -92,6 +95,9 @@ public: boolean isPSUoff(); String getTempBedActual(); String getTempBedTarget(); + String getEstimatedEndTime(); + String getCurrentLayer(); + String getTotalLayers(); String getTempToolActual(); String getTempToolTarget(); String getFilamentLength(); diff --git a/printermonitor/printermonitor.ino b/printermonitor/printermonitor.ino index 8849850..316b3a4 100644 --- a/printermonitor/printermonitor.ino +++ b/printermonitor/printermonitor.ino @@ -59,15 +59,18 @@ 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 drawScreen4(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); +void drawScreen5(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 drawUpdate(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); void drawClockHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state); // Set the number of Frames supported -const int numberOfFrames = 3; +const int numberOfFrames = 5; FrameCallback frames[numberOfFrames]; -FrameCallback clockFrame[2]; +FrameCallback clockFrame[3]; boolean isClockOn = false; OverlayCallback overlays[] = { drawHeaderOverlay }; @@ -259,8 +262,11 @@ void setup() { frames[0] = drawScreen1; frames[1] = drawScreen2; frames[2] = drawScreen3; + frames[3] = drawScreen4; + frames[4] = drawScreen5; clockFrame[0] = drawClock; clockFrame[1] = drawWeather; + clockFrame[2] = drawUpdate; ui.setOverlays(overlays, numberOfOverlays); // Inital UI takes care of initalising the display too. @@ -751,7 +757,7 @@ String getFooter() { if (lastReportStatus != "") { html += " Report Status: " + lastReportStatus + "
"; } - html += " Version: " + String(VERSION) + "
"; + html += " Version: " + String(VERSION) + " Next Update: " + getTimeTillUpdate() + "
"; html += " Signal Strength: "; html += String(rssi) + "%"; html += ""; @@ -806,6 +812,12 @@ void displayPrinterStatus() { float fLength = float(filamentLength) / 1000; html += "Filament: " + String(fLength) + "m
"; } + if (printerClient.isPrinting()) { + html += "Layer: " + printerClient.getCurrentLayer() + " / " + printerClient.getTotalLayers() + "
"; + } + if (printerClient.isPrinting()) { + html += "Estimated Finish Time: " + printerClient.getEstimatedEndTime() + "
"; + } html += "Tool Temperature: " + printerClient.getTempToolActual() + "° C
"; if ( printerClient.getTempBedActual() != 0 ) { @@ -963,6 +975,44 @@ void drawScreen3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int display->drawString(64 + x, 14 + y, time); } +void drawScreen4(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { + + String layer = printerClient.getCurrentLayer(); + String totalLayers = printerClient.getTotalLayers(); + if (printerClient.getTotalLayers().toInt() >= 1000) { + display->setTextAlignment(TEXT_ALIGN_CENTER); + display->setFont(ArialMT_Plain_16); + + display->drawString(64 + x, 0 + y, "Layer"); + //display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(ArialMT_Plain_16); + + display->drawString(64 + x, 16 + y, layer + " / " + totalLayers); + } else { + display->setTextAlignment(TEXT_ALIGN_CENTER); + display->setFont(ArialMT_Plain_16); + + display->drawString(64 + x, 0 + y, "Layer"); + //display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(ArialMT_Plain_24); + + display->drawString(64 + x, 14 + y, layer + " / " + totalLayers); + } +} + +void drawScreen5(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { + + String EstimatedEnd = printerClient.getEstimatedEndTime(); + display->setTextAlignment(TEXT_ALIGN_CENTER); + display->setFont(ArialMT_Plain_16); + + display->drawString(64 + x, 0 + y, "End Time"); + //display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(ArialMT_Plain_24); + + display->drawString(64 + x, 14 + y, EstimatedEnd); +} + void drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { display->setTextAlignment(TEXT_ALIGN_CENTER); @@ -993,6 +1043,39 @@ void drawWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int display->drawString(86 + x, 0 + y, weatherClient.getWeatherIcon(0)); } +void drawUpdate(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, "Next Update:"); + //display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(ArialMT_Plain_24); + + display->drawString(64 + x, 14 + y, getTimeTillUpdate()); +} + +String getTimeTillUpdate() { + String rtnValue = ""; + + long timeToUpdate = (((minutesBetweenDataRefresh * 60) + lastEpoch) - timeClient.getCurrentEpoch()); + + int hours = numberOfHours(timeToUpdate); + int minutes = numberOfMinutes(timeToUpdate); + int seconds = numberOfSeconds(timeToUpdate); + + rtnValue += String(hours) + ":"; + if (minutes < 10) { + rtnValue += "0"; + } + rtnValue += String(minutes) + ":"; + if (seconds < 10) { + rtnValue += "0"; + } + rtnValue += String(seconds); + + return rtnValue; +} + String getTempSymbol() { return getTempSymbol(false); } diff --git a/printermonitor/printermonitor.ino.d1_mini.bin b/printermonitor/printermonitor.ino.d1_mini.bin new file mode 100644 index 0000000..a44dc05 Binary files /dev/null and b/printermonitor/printermonitor.ino.d1_mini.bin differ