diff --git a/README.md b/README.md
index 3e7f920..d3e464d 100644
--- a/README.md
+++ b/README.md
@@ -41,6 +41,7 @@ SOFTWARE.
* Supports OTA (loading firmware over WiFi connection on same LAN)
* Basic Authentication to protect your settings
* 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
* Video: https://youtu.be/niRv9SCgAPk
* Detailed build video by Chris Riley: https://youtu.be/Rm-l1FSuJpI
diff --git a/printermonitor/OctoPrintClient.cpp b/printermonitor/OctoPrintClient.cpp
index b2879ca..4f669ad 100644
--- a/printermonitor/OctoPrintClient.cpp
+++ b/printermonitor/OctoPrintClient.cpp
@@ -21,13 +21,15 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
+/* 15 Jan 2019 : Owen Carter : Add psucontrol query via POST api call */
+
#include "OctoPrintClient.h"
-OctoPrintClient::OctoPrintClient(String ApiKey, String server, int port, String user, String pass) {
- updateOctoPrintClient(ApiKey, server, port, user, pass);
+OctoPrintClient::OctoPrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu) {
+ updateOctoPrintClient(ApiKey, server, port, user, pass, psu);
}
-void OctoPrintClient::updateOctoPrintClient(String ApiKey, String server, int port, String user, String pass) {
+void OctoPrintClient::updateOctoPrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu) {
server.toCharArray(myServer, 100);
myApiKey = ApiKey;
myPort = port;
@@ -37,6 +39,7 @@ void OctoPrintClient::updateOctoPrintClient(String ApiKey, String server, int po
base64 b64;
encodedAuth = b64.encode(userpass, true);
}
+ pollPsu = psu;
}
boolean OctoPrintClient::validate() {
@@ -58,7 +61,7 @@ WiFiClient OctoPrintClient::getSubmitRequest(String apiGetData) {
WiFiClient printClient;
printClient.setTimeout(5000);
- Serial.println("Getting Octoprint Data");
+ Serial.println("Getting Octoprint Data via GET");
Serial.println(apiGetData);
result = "";
if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection
@@ -109,18 +112,76 @@ WiFiClient OctoPrintClient::getSubmitRequest(String apiGetData) {
return printClient;
}
+WiFiClient OctoPrintClient::getPostRequest(String apiPostData, String apiPostBody) {
+ WiFiClient printClient;
+ printClient.setTimeout(5000);
+
+ Serial.println("Getting Octoprint 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 OctoPrint failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect
+ Serial.println();
+ resetPrintData();
+ printerData.error = "Connection to OctoPrint 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 OctoPrintClient::getPrinterJobResults() {
if (!validate()) {
return;
}
+ //**** get the Printer Job status
String apiGetData = "GET /api/job HTTP/1.1";
-
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);
@@ -148,7 +209,7 @@ void OctoPrintClient::getPrinterJobResults() {
if (isOperational()) {
Serial.println("Status: " + printerData.state);
} else {
- Serial.println("Printer Not Opperational");
+ Serial.println("Printer Not Operational");
}
//**** get the Printer Temps and Stat
@@ -183,8 +244,42 @@ void OctoPrintClient::getPrinterJobResults() {
if (isPrinting()) {
Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)");
}
+}
+
+void OctoPrintClient::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 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;
+ DynamicJsonBuffer jsonBuffer3(bufferSize3);
- printClient.stop(); //stop client
+ // 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
@@ -205,6 +300,7 @@ void OctoPrintClient::resetPrintData() {
printerData.bedTemp = "";
printerData.bedTargetTemp = "";
printerData.isPrinting = false;
+ printerData.isPSUoff = false;
printerData.error = "";
}
@@ -256,6 +352,10 @@ boolean OctoPrintClient::isPrinting() {
return printerData.isPrinting;
}
+boolean OctoPrintClient::isPSUoff() {
+ return printerData.isPSUoff;
+}
+
boolean OctoPrintClient::isOperational() {
boolean operational = false;
if (printerData.state == "Operational" || isPrinting()) {
@@ -292,4 +392,4 @@ String OctoPrintClient::getValueRounded(String value) {
float f = value.toFloat();
int rounded = (int)(f+0.5f);
return String(rounded);
-}
+}
diff --git a/printermonitor/OctoPrintClient.h b/printermonitor/OctoPrintClient.h
index 1d02836..3335536 100644
--- a/printermonitor/OctoPrintClient.h
+++ b/printermonitor/OctoPrintClient.h
@@ -21,6 +21,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
+/* 15 Jan 2019 : Owen Carter : Add psucontrol query via POST api call */
+
#pragma once
#include
Flip display orientation
" + "Use OctoPrint PSU control plugin for clock/blank
" "Clock Sync / Weather Refresh (minutes)
" "Theme Color
" "";
html += "Host Name: " + OctoPrintHostName + "
";
if (printerClient.getError() != "") {
- html += "Error: " + printerClient.getError() + "
";
+ html += "Status: Offline
";
+ html += "Reason: " + printerClient.getError() + "
";
+ } else {
+ html += "Status: " + printerClient.getState();
+ if (printerClient.isPSUoff() && HAS_PSU) {
+ html += ", PSU off";
+ }
+ html += "
";
}
- html += "Status: " + printerClient.getState() + "
";
-
+
if (printerClient.isPrinting()) {
html += "File: " + printerClient.getFileName() + "
";
float fileSize = printerClient.getFileSize().toFloat();
@@ -941,9 +960,17 @@ void drawClockHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
if (!IS_24HOUR) {
display->drawString(0, 48, timeClient.getAmPm());
display->setTextAlignment(TEXT_ALIGN_CENTER);
- display->drawString(64, 48, "offline");
+ if (printerClient.isPSUoff()) {
+ display->drawString(64, 47, "psu off");
+ } else {
+ display->drawString(64, 47, "offline");
+ }
} else {
- display->drawString(0,48, "offline");
+ if (printerClient.isPSUoff()) {
+ display->drawString(0, 47, "psu off");
+ } else {
+ display->drawString(0, 47, "offline");
+ }
}
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawRect(0, 43, 128, 2);
@@ -1004,6 +1031,7 @@ void writeSettings() {
f.println("CityID=" + String(CityIDs[0]));
f.println("isMetric=" + String(IS_METRIC));
f.println("language=" + String(WeatherLanguage));
+ f.println("hasPSU=" + String(HAS_PSU));
}
f.close();
readSettings();
@@ -1091,6 +1119,10 @@ void readSettings() {
INVERT_DISPLAY = line.substring(line.lastIndexOf("invertDisp=") + 11).toInt();
Serial.println("INVERT_DISPLAY=" + String(INVERT_DISPLAY));
}
+ if (line.indexOf("hasPSU=") >= 0) {
+ HAS_PSU = line.substring(line.lastIndexOf("hasPSU=") + 7).toInt();
+ Serial.println("HAS_PSU=" + String(HAS_PSU));
+ }
if (line.indexOf("isWeather=") >= 0) {
DISPLAYWEATHER = line.substring(line.lastIndexOf("isWeather=") + 10).toInt();
Serial.println("DISPLAYWEATHER=" + String(DISPLAYWEATHER));
@@ -1115,7 +1147,7 @@ void readSettings() {
}
}
fr.close();
- printerClient.updateOctoPrintClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, OctoAuthUser, OctoAuthPass);
+ printerClient.updateOctoPrintClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, OctoAuthUser, OctoAuthPass, HAS_PSU);
weatherClient.updateWeatherApiKey(WeatherApiKey);
weatherClient.updateLanguage(WeatherLanguage);
weatherClient.setMetric(IS_METRIC);
@@ -1167,7 +1199,7 @@ void checkDisplay() {
return;
}
} else if (DISPLAYCLOCK) {
- if (!printerClient.isOperational() && !isClockOn) {
+ if ((!printerClient.isOperational() || printerClient.isPSUoff()) && !isClockOn) {
Serial.println("Clock Mode is turned on.");
if (!DISPLAYWEATHER) {
ui.disableAutoTransition();
@@ -1181,7 +1213,7 @@ void checkDisplay() {
}
ui.setOverlays(clockOverlay, numberOfOverlays);
isClockOn = true;
- } else if (printerClient.isOperational() && isClockOn) {
+ } else if (printerClient.isOperational() && !printerClient.isPSUoff() && isClockOn) {
Serial.println("Printer Monitor is active.");
ui.setFrames(frames, numberOfFrames);
ui.setOverlays(overlays, numberOfOverlays);
@@ -1206,4 +1238,4 @@ void enableDisplay(boolean enable) {
Serial.println("Display was turned OFF: " + timeClient.getFormattedTime());
displayOffEpoch = lastEpoch;
}
-}
+}