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