Rework of the complete structure for multiply displays

pull/125/head
Robert Stein 2020-12-12 00:08:29 +01:00
parent 8918e8e4b5
commit 96d5e390da
67 changed files with 1835 additions and 2331 deletions

BIN
nextion-ui/SegoeUi64BNum.zi Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
nextion-ui/icons/211.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
nextion-ui/icons/212.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
nextion-ui/icons/230.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
nextion-ui/icons/231.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
nextion-ui/icons/500d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
nextion-ui/icons/500n.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
nextion-ui/icons/501.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
nextion-ui/icons/502.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
nextion-ui/icons/600d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
nextion-ui/icons/600n.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
nextion-ui/icons/601.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
nextion-ui/icons/602.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
nextion-ui/icons/611.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
nextion-ui/icons/721d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
nextion-ui/icons/721n.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
nextion-ui/icons/741.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
nextion-ui/icons/800d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
nextion-ui/icons/800n.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
nextion-ui/icons/801d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
nextion-ui/icons/801n.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
nextion-ui/icons/802d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
nextion-ui/icons/802n.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
nextion-ui/icons/803.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
nextion-ui/icons/804.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 956 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
nextion-ui/img/Welcome.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

65
printermonitor/Debug.cpp Normal file
View File

@ -0,0 +1,65 @@
#include "Debug.h"
#include <SoftwareSerial.h>
Debug::Debug() {
}
void Debug::initialize() {
Serial.begin(115200);
delay(10);
Serial.println();
}
void Debug::print(char *data) {
Serial.print(data);
}
void Debug::print(String data) {
Serial.print(data);
}
void Debug::print(int8_t data) {
Serial.print(data);
}
void Debug::printF(char *data, unsigned int uInt) {
Serial.printf(data, uInt);
}
void Debug::printLn(char *data) {
Serial.println(data);
}
void Debug::printLn(int8_t data) {
Serial.println(data);
}
void Debug::printLn(String data) {
Serial.println(data);
}
void Debug::printLn(long int data) {
Serial.println(data);
}
/********************************************
void serialDebugSetup() {
#ifndef USE_NEXTION_DISPLAY
#endif
}
#define NOP __asm__ __volatile__ ("nop\n\t")
#ifndef USE_NEXTION_DISPLAY
#define serialDebugPrint(data)
#define serialDebugPrintF(data, args) Serial.printf(data, args)
#define serialDebugPrintLn(data) Serial.println(data)
#else
#define serialDebugPrint(data) NOP
#define serialDebugPrintLn(data) NOP
#endif
*/

18
printermonitor/Debug.h Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include <ESP8266WiFi.h>
class Debug {
public:
Debug();
void initialize();
void print(char *data);
void print(String data);
void print(int8_t data);
void printF(char *data, unsigned int uInt);
void printLn(char *data);
void printLn(String data);
void printLn(long int data);
void printLn(int8_t data);
};

View File

@ -27,7 +27,8 @@ SOFTWARE.
#include "DuetClient.h"
DuetClient::DuetClient(String ApiKey, String server, int port, String user, String pass, boolean psu) {
DuetClient::DuetClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle) {
this->debugHandle = debugHandle;
updatePrintClient(ApiKey, server, port, user, pass, psu);
}
@ -63,8 +64,8 @@ WiFiClient DuetClient::getSubmitRequest(String apiGetData) {
WiFiClient printClient;
printClient.setTimeout(5000);
Serial.println("Getting Duet Data via GET");
Serial.println(apiGetData);
this->debugHandle->printLn("Getting Duet Data via GET");
this->debugHandle->printLn(apiGetData);
result = "";
if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection
printClient.println(apiGetData);
@ -77,16 +78,16 @@ WiFiClient DuetClient::getSubmitRequest(String apiGetData) {
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();
this->debugHandle->printLn("Connection to " + String(myServer) + ":" + String(myPort) + " failed.");
this->debugHandle->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();
this->debugHandle->printLn("Connection to Duet failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect
this->debugHandle->printLn("");
resetPrintData();
printerData.error = "Connection to Duet failed: " + String(myServer) + ":" + String(myPort);
return printClient;
@ -96,8 +97,8 @@ WiFiClient DuetClient::getSubmitRequest(String apiGetData) {
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);
this->debugHandle->print("Unexpected response: ");
this->debugHandle->printLn(status);
printerData.state = "";
printerData.error = "Response: " + String(status);
return printClient;
@ -106,7 +107,7 @@ WiFiClient DuetClient::getSubmitRequest(String apiGetData) {
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
if (!printClient.find(endOfHeaders)) {
Serial.println(F("Invalid response"));
this->debugHandle->printLn("Invalid response");
printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort);
printerData.state = "";
}
@ -118,8 +119,8 @@ WiFiClient DuetClient::getPostRequest(String apiPostData, String apiPostBody) {
WiFiClient printClient;
printClient.setTimeout(5000);
Serial.println("Getting Duet Data via POST");
Serial.println(apiPostData + " | " + apiPostBody);
this->debugHandle->printLn("Getting Duet Data via POST");
this->debugHandle->printLn(apiPostData + " | " + apiPostBody);
result = "";
if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection
printClient.println(apiPostData);
@ -137,16 +138,16 @@ WiFiClient DuetClient::getPostRequest(String apiPostData, String apiPostBody) {
printClient.println();
printClient.println(apiPostBody);
if (printClient.println() == 0) {
Serial.println("Connection to " + String(myServer) + ":" + String(myPort) + " failed.");
Serial.println();
this->debugHandle->printLn("Connection to " + String(myServer) + ":" + String(myPort) + " failed.");
this->debugHandle->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();
this->debugHandle->printLn("Connection to Duet failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect
this->debugHandle->printLn("");
resetPrintData();
printerData.error = "Connection to Duet failed: " + String(myServer) + ":" + String(myPort);
return printClient;
@ -156,8 +157,8 @@ WiFiClient DuetClient::getPostRequest(String apiPostData, String apiPostBody) {
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);
this->debugHandle->print("Unexpected response: ");
this->debugHandle->printLn(status);
printerData.state = "";
printerData.error = "Response: " + String(status);
return printClient;
@ -166,7 +167,7 @@ WiFiClient DuetClient::getPostRequest(String apiPostData, String apiPostBody) {
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
if (!printClient.find(endOfHeaders)) {
Serial.println(F("Invalid response"));
this->debugHandle->print("Invalid response");
printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort);
printerData.state = "";
}
@ -190,7 +191,7 @@ void DuetClient::getPrinterJobResults() {
// Parse JSON object
JsonObject& root = jsonBuffer.parseObject(printClient);
if (!root.success()) {
Serial.println("Duet Data Parsing failed: " + String(myServer) + ":" + String(myPort));
this->debugHandle->printLn("Duet Data Parsing failed: " + String(myServer) + ":" + String(myPort));
printerData.error = "Duet Data Parsing failed: " + String(myServer) + ":" + String(myPort);
printerData.state = "";
return;
@ -210,9 +211,9 @@ void DuetClient::getPrinterJobResults() {
if (isOperational()) {
Serial.println("Status: " + printerData.state);
this->debugHandle->printLn("Status: " + printerData.state);
} else {
Serial.println("Printer Not Operational");
this->debugHandle->printLn("Printer Not Operational");
}
//**** get the Printer Temps and Stat
@ -246,10 +247,10 @@ void DuetClient::getPrinterJobResults() {
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 ");
this->debugHandle->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 + "%)");
this->debugHandle->printLn("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)");
}
}

View File

@ -29,8 +29,10 @@ SOFTWARE.
#include <ESP8266WiFi.h>
#include "libs/ArduinoJson/ArduinoJson.h"
#include <base64.h>
#include "Debug.h"
#include "PrinterClientInterface.h"
class DuetClient {
class DuetClient : public PrinterClientInterface {
private:
char myServer[100];
@ -70,13 +72,14 @@ private:
} PrinterStruct;
PrinterStruct printerData;
Debug *debugHandle;
public:
DuetClient(String PrinterApiKey, String server, int port, String user, String pass, boolean psu);
DuetClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle);
void getPrinterJobResults();
void getPrinterPsuState();
void updatePrintClient(String PrinterApiKey, String server, int port, String user, String pass, boolean psu);
void updatePrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu);
String getAveragePrintTime();
String getEstimatedPrintTime();

21
printermonitor/Global.h Normal file
View File

@ -0,0 +1,21 @@
/**
* Main includes we are needing
*/
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>
#include <ESP8266HTTPUpdateServer.h>
#include "TimeClient.h"
#include "KlipperClient.h"
#include "DuetClient.h"
#include "RepetierClient.h"
#include "OctoPrintClient.h"
#include "OpenWeatherMapClient.h"
#include "WeatherStationFonts.h"
#include "NextionDisplayClient.h"
#include "OledDisplayClient.h"
#include "WebServer.h"
#include "FS.h"
#include "Debug.h"

View File

@ -27,7 +27,8 @@ SOFTWARE.
#include "KlipperClient.h"
KlipperClient::KlipperClient(String ApiKey, String server, int port, String user, String pass, boolean psu) {
KlipperClient::KlipperClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle) {
this->debugHandle = debugHandle;
updatePrintClient(ApiKey, server, port, user, pass, psu);
}
@ -63,8 +64,8 @@ WiFiClient KlipperClient::getSubmitRequest(String apiGetData) {
WiFiClient printClient;
printClient.setTimeout(5000);
Serial.println("Getting Klipper Data via GET");
Serial.println(apiGetData);
this->debugHandle->printLn("Getting Klipper Data via GET");
this->debugHandle->printLn(apiGetData);
result = "";
if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection
printClient.println(apiGetData);
@ -77,16 +78,16 @@ WiFiClient KlipperClient::getSubmitRequest(String apiGetData) {
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();
this->debugHandle->printLn("Connection to " + String(myServer) + ":" + String(myPort) + " failed.");
this->debugHandle->printLn("");
resetPrintData();
printerData.error = "Connection to " + String(myServer) + ":" + String(myPort) + " failed.";
return printClient;
}
}
else {
Serial.println("Connection to Klipper failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect
Serial.println();
this->debugHandle->printLn("Connection to Klipper failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect
this->debugHandle->printLn("");
resetPrintData();
printerData.error = "Connection to Klipper failed: " + String(myServer) + ":" + String(myPort);
return printClient;
@ -96,8 +97,8 @@ WiFiClient KlipperClient::getSubmitRequest(String apiGetData) {
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);
this->debugHandle->print("Unexpected response: ");
this->debugHandle->printLn(status);
printerData.state = "";
printerData.error = "Response: " + String(status);
return printClient;
@ -106,7 +107,7 @@ WiFiClient KlipperClient::getSubmitRequest(String apiGetData) {
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
if (!printClient.find(endOfHeaders)) {
Serial.println(F("Invalid response"));
this->debugHandle->printLn("Invalid response");
printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort);
printerData.state = "";
}
@ -118,8 +119,8 @@ WiFiClient KlipperClient::getPostRequest(String apiPostData, String apiPostBody)
WiFiClient printClient;
printClient.setTimeout(5000);
Serial.println("Getting Klipper Data via POST");
Serial.println(apiPostData + " | " + apiPostBody);
this->debugHandle->printLn("Getting Klipper Data via POST");
this->debugHandle->printLn(apiPostData + " | " + apiPostBody);
result = "";
if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection
printClient.println(apiPostData);
@ -137,16 +138,16 @@ WiFiClient KlipperClient::getPostRequest(String apiPostData, String apiPostBody)
printClient.println();
printClient.println(apiPostBody);
if (printClient.println() == 0) {
Serial.println("Connection to " + String(myServer) + ":" + String(myPort) + " failed.");
Serial.println();
this->debugHandle->printLn("Connection to " + String(myServer) + ":" + String(myPort) + " failed.");
this->debugHandle->printLn("");
resetPrintData();
printerData.error = "Connection to " + String(myServer) + ":" + String(myPort) + " failed.";
return printClient;
}
}
else {
Serial.println("Connection to Klipper failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect
Serial.println();
this->debugHandle->printLn("Connection to Klipper failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect
this->debugHandle->printLn("");
resetPrintData();
printerData.error = "Connection to Klipper failed: " + String(myServer) + ":" + String(myPort);
return printClient;
@ -156,8 +157,8 @@ WiFiClient KlipperClient::getPostRequest(String apiPostData, String apiPostBody)
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);
this->debugHandle->print("Unexpected response: ");
this->debugHandle->printLn(status);
printerData.state = "";
printerData.error = "Response: " + String(status);
return printClient;
@ -166,7 +167,7 @@ WiFiClient KlipperClient::getPostRequest(String apiPostData, String apiPostBody)
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
if (!printClient.find(endOfHeaders)) {
Serial.println(F("Invalid response"));
this->debugHandle->printLn("Invalid response");
printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort);
printerData.state = "";
}
@ -190,7 +191,7 @@ void KlipperClient::getPrinterJobResults() {
// Parse JSON object
JsonObject& root = jsonBuffer.parseObject(printClient);
if (!root.success()) {
Serial.println("Klipper Data Parsing failed: " + String(myServer) + ":" + String(myPort));
this->debugHandle->printLn("Klipper Data Parsing failed: " + String(myServer) + ":" + String(myPort));
printerData.error = "Klipper Data Parsing failed: " + String(myServer) + ":" + String(myPort);
printerData.state = "";
return;
@ -209,9 +210,9 @@ void KlipperClient::getPrinterJobResults() {
printerData.state = (const char*)root["result"]["status"]["print_stats"]["state"];
if (isOperational()) {
Serial.println("Status: " + printerData.state);
this->debugHandle->printLn("Status: " + printerData.state);
} else {
Serial.println("Printer Not Operational");
this->debugHandle->printLn("Printer Not Operational");
}
//**** get the Printer Temps and Stat
@ -246,7 +247,7 @@ void KlipperClient::getPrinterJobResults() {
printerData.bedTargetTemp = (const char*)root2["result"]["status"]["heater_bed"]["target"];
if (isPrinting()) {
Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)");
this->debugHandle->printLn("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)");
}
}

View File

@ -29,8 +29,10 @@ SOFTWARE.
#include <ESP8266WiFi.h>
#include "libs/ArduinoJson/ArduinoJson.h"
#include <base64.h>
#include "Debug.h"
#include "PrinterClientInterface.h"
class KlipperClient {
class KlipperClient : public PrinterClientInterface {
private:
char myServer[100];
@ -70,10 +72,10 @@ private:
} PrinterStruct;
PrinterStruct printerData;
Debug *debugHandle;
public:
KlipperClient(String ApiKey, String server, int port, String user, String pass, boolean psu);
KlipperClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle);
void getPrinterJobResults();
void getPrinterPsuState();
void updatePrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu);

View File

@ -1,414 +0,0 @@
/** 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 */
#include "KlipperPrintClient.h"
KlipperPrintClient::KlipperPrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu) {
updatePrintClient(ApiKey, server, port, user, pass, psu);
}
void KlipperPrintClient::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 KlipperPrintClient::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 KlipperPrintClient::getSubmitRequest(String apiGetData) {
WiFiClient printClient;
printClient.setTimeout(5000);
Serial.println("Getting Octoprint 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 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;
}
WiFiClient KlipperPrintClient::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 KlipperPrintClient::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);
// Parse JSON object
JsonObject& root = jsonBuffer.parseObject(printClient);
if (!root.success()) {
Serial.println("OctoPrint Data Parsing failed: " + String(myServer) + ":" + String(myPort));
printerData.error = "OctoPrint Data Parsing failed: " + String(myServer) + ":" + String(myPort);
printerData.state = "";
return;
}
printerData.averagePrintTime = (const char*)root["job"]["averagePrintTime"];
printerData.estimatedPrintTime = (const char*)root["job"]["estimatedPrintTime"];
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["progress"]["completion"];
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["state"];
if (isOperational()) {
Serial.println("Status: " + printerData.state);
} else {
Serial.println("Printer Not Operational");
}
//**** get the Printer Temps and Stat
apiGetData = "GET /api/printer?exclude=sd,history HTTP/1.1";
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["temperature"]["bed"]["target"];
return;
}
String printing = (const char*)root2["state"]["flags"]["printing"];
if (printing == "true") {
printerData.isPrinting = true;
} else {
printerData.isPrinting = false;
}
printerData.toolTemp = (const char*)root2["temperature"]["tool0"]["actual"];
printerData.toolTargetTemp = (const char*)root2["temperature"]["tool0"]["target"];
printerData.bedTemp = (const char*)root2["temperature"]["bed"]["actual"];
printerData.bedTargetTemp = (const char*)root2["temperature"]["bed"]["target"];
if (isPrinting()) {
Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)");
}
}
void KlipperPrintClient::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);
// 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 KlipperPrintClient::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 KlipperPrintClient::getAveragePrintTime(){
return printerData.averagePrintTime;
}
String KlipperPrintClient::getEstimatedPrintTime() {
return printerData.estimatedPrintTime;
}
String KlipperPrintClient::getFileName() {
return printerData.fileName;
}
String KlipperPrintClient::getFileSize() {
return printerData.fileSize;
}
String KlipperPrintClient::getLastPrintTime(){
return printerData.lastPrintTime;
}
String KlipperPrintClient::getProgressCompletion() {
return String(printerData.progressCompletion.toInt());
}
String KlipperPrintClient::getProgressFilepos() {
return printerData.progressFilepos;
}
String KlipperPrintClient::getProgressPrintTime() {
return printerData.progressPrintTime;
}
String KlipperPrintClient::getProgressPrintTimeLeft() {
String rtnValue = printerData.progressPrintTimeLeft;
if (getProgressCompletion() == "100") {
rtnValue = "0"; // Print is done so this should be 0 this is a fix for OctoPrint
}
return rtnValue;
}
String KlipperPrintClient::getState() {
return printerData.state;
}
boolean KlipperPrintClient::isPrinting() {
return printerData.isPrinting;
}
boolean KlipperPrintClient::isPSUoff() {
return printerData.isPSUoff;
}
boolean KlipperPrintClient::isOperational() {
boolean operational = false;
if (printerData.state == "Operational" || isPrinting()) {
operational = true;
}
return operational;
}
String KlipperPrintClient::getTempBedActual() {
return printerData.bedTemp;
}
String KlipperPrintClient::getTempBedTarget() {
return printerData.bedTargetTemp;
}
String KlipperPrintClient::getTempToolActual() {
return printerData.toolTemp;
}
String KlipperPrintClient::getTempToolTarget() {
return printerData.toolTargetTemp;
}
String KlipperPrintClient::getFilamentLength() {
return printerData.filamentLength;
}
String KlipperPrintClient::getError() {
return printerData.error;
}
String KlipperPrintClient::getValueRounded(String value) {
float f = value.toFloat();
int rounded = (int)(f+0.5f);
return String(rounded);
}
String KlipperPrintClient::getPrinterType() {
return printerType;
}
int KlipperPrintClient::getPrinterPort() {
return myPort;
}
String KlipperPrintClient::getPrinterName() {
return printerData.printerName;
}
void KlipperPrintClient::setPrinterName(String printer) {
printerData.printerName = printer;
}

View File

@ -1,104 +0,0 @@
/** 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 */
#pragma once
#include <ESP8266WiFi.h>
#include "libs/ArduinoJson/ArduinoJson.h"
#include <base64.h>
class KlipperPrintClient {
private:
char myServer[100];
int myPort = 80;
String myApiKey = "";
String encodedAuth = "";
boolean pollPsu;
const String printerType = "OctoPrint";
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:
KlipperPrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu);
void getPrinterJobResults();
void getPrinterPsuState();
void updatePrintClient(String ApiKey, 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);
};

10
printermonitor/Macros.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
/* Useful Constants */
#define SECS_PER_MIN (60UL)
#define SECS_PER_HOUR (3600UL)
/* Useful Macros for getting elapsed time */
#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)
#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN)
#define numberOfHours(_time_) (_time_ / SECS_PER_HOUR)

View File

@ -0,0 +1,50 @@
#include "NextionDisplayClient.h"
NextionDisplayClient::NextionDisplayClient(byte rxPin, byte txPin, PrinterClientInterface *printerClient) {
this->printerClient = printerClient;
this->softwareSerialPort = new SoftwareSerial(rxPin, txPin);
this->softwareSerialPort->begin(9600);
}
void NextionDisplayClient::postSetup() {
}
void NextionDisplayClient::showPageInit(String printerTypeName, String softwareVersion) {
String command("version.txt=");
command += "\"for " + printerTypeName + " V" + softwareVersion + "\"";
this->sendCommand("page 0");
this->sendCommand(command.c_str());
}
void NextionDisplayClient::showPageApMode(String protalSsid) {
String commandHostName("WifiHostname.txt=");
String commandQrCode("WifiScancode.txt=");
commandHostName += "\"" + protalSsid + "\"";
commandQrCode += "\"WIFI:S:" + protalSsid + ";T:WPA;P:;;\"";
this->sendCommand("page 1");
this->sendCommand(commandHostName.c_str());
this->sendCommand(commandQrCode.c_str());
}
void NextionDisplayClient::showPageWeather() {
this->sendCommand("page 2");
}
void NextionDisplayClient::showPagePrinter() {
this->sendCommand("page 3");
}
void NextionDisplayClient::sendCommand(const char* cmd) {
while (this->softwareSerialPort->available())
{
this->softwareSerialPort->read();
}
this->softwareSerialPort->print(cmd);
this->softwareSerialPort->write(0xFF);
this->softwareSerialPort->write(0xFF);
this->softwareSerialPort->write(0xFF);
}

View File

@ -0,0 +1,26 @@
#pragma once
#include <ESP8266WiFi.h>
#include "libs/ArduinoJson/ArduinoJson.h"
#include <base64.h>
#include "Debug.h"
#include <SoftwareSerial.h>
#include "PrinterClientInterface.h"
#include "Macros.h"
class NextionDisplayClient {
private:
SoftwareSerial *softwareSerialPort;
PrinterClientInterface *printerClient;
public:
NextionDisplayClient(byte rxPin, byte txPin, PrinterClientInterface *printerClient);
void postSetup();
void showPageInit(String printerTypeName, String softwareVersion);
void showPageApMode(String protalSsid);
void showPageWeather();
void showPagePrinter();
private:
void sendCommand(const char* cmd);
};

View File

@ -26,7 +26,8 @@ SOFTWARE.
#include "OctoPrintClient.h"
OctoPrintClient::OctoPrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu) {
OctoPrintClient::OctoPrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle) {
this->debugHandle = debugHandle;
updatePrintClient(ApiKey, server, port, user, pass, psu);
}
@ -62,8 +63,8 @@ WiFiClient OctoPrintClient::getSubmitRequest(String apiGetData) {
WiFiClient printClient;
printClient.setTimeout(5000);
Serial.println("Getting Octoprint Data via GET");
Serial.println(apiGetData);
this->debugHandle->printLn("Getting Octoprint Data via GET");
this->debugHandle->printLn(apiGetData);
result = "";
if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection
printClient.println(apiGetData);
@ -76,16 +77,16 @@ WiFiClient OctoPrintClient::getSubmitRequest(String apiGetData) {
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();
this->debugHandle->printLn("Connection to " + String(myServer) + ":" + String(myPort) + " failed.");
this->debugHandle->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();
this->debugHandle->printLn("Connection to OctoPrint failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect
this->debugHandle->printLn("");
resetPrintData();
printerData.error = "Connection to OctoPrint failed: " + String(myServer) + ":" + String(myPort);
return printClient;
@ -95,8 +96,8 @@ WiFiClient OctoPrintClient::getSubmitRequest(String apiGetData) {
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);
this->debugHandle->print("Unexpected response: ");
this->debugHandle->printLn(status);
printerData.state = "";
printerData.error = "Response: " + String(status);
return printClient;
@ -105,7 +106,7 @@ WiFiClient OctoPrintClient::getSubmitRequest(String apiGetData) {
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
if (!printClient.find(endOfHeaders)) {
Serial.println(F("Invalid response"));
this->debugHandle->printLn("Invalid response");
printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort);
printerData.state = "";
}
@ -117,8 +118,8 @@ WiFiClient OctoPrintClient::getPostRequest(String apiPostData, String apiPostBod
WiFiClient printClient;
printClient.setTimeout(5000);
Serial.println("Getting Octoprint Data via POST");
Serial.println(apiPostData + " | " + apiPostBody);
this->debugHandle->printLn("Getting Octoprint Data via POST");
this->debugHandle->printLn(apiPostData + " | " + apiPostBody);
result = "";
if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection
printClient.println(apiPostData);
@ -136,16 +137,16 @@ WiFiClient OctoPrintClient::getPostRequest(String apiPostData, String apiPostBod
printClient.println();
printClient.println(apiPostBody);
if (printClient.println() == 0) {
Serial.println("Connection to " + String(myServer) + ":" + String(myPort) + " failed.");
Serial.println();
this->debugHandle->printLn("Connection to " + String(myServer) + ":" + String(myPort) + " failed.");
this->debugHandle->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();
this->debugHandle->printLn("Connection to OctoPrint failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect
this->debugHandle->printLn("");
resetPrintData();
printerData.error = "Connection to OctoPrint failed: " + String(myServer) + ":" + String(myPort);
return printClient;
@ -155,8 +156,8 @@ WiFiClient OctoPrintClient::getPostRequest(String apiPostData, String apiPostBod
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);
this->debugHandle->print("Unexpected response: ");
this->debugHandle->printLn(status);
printerData.state = "";
printerData.error = "Response: " + String(status);
return printClient;
@ -165,7 +166,7 @@ WiFiClient OctoPrintClient::getPostRequest(String apiPostData, String apiPostBod
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
if (!printClient.find(endOfHeaders)) {
Serial.println(F("Invalid response"));
this->debugHandle->printLn("Invalid response");
printerData.error = "Invalid response from " + String(myServer) + ":" + String(myPort);
printerData.state = "";
}
@ -189,7 +190,7 @@ void OctoPrintClient::getPrinterJobResults() {
// Parse JSON object
JsonObject& root = jsonBuffer.parseObject(printClient);
if (!root.success()) {
Serial.println("OctoPrint Data Parsing failed: " + String(myServer) + ":" + String(myPort));
this->debugHandle->printLn("OctoPrint Data Parsing failed: " + String(myServer) + ":" + String(myPort));
printerData.error = "OctoPrint Data Parsing failed: " + String(myServer) + ":" + String(myPort);
printerData.state = "";
return;
@ -208,9 +209,9 @@ void OctoPrintClient::getPrinterJobResults() {
printerData.state = (const char*)root["state"];
if (isOperational()) {
Serial.println("Status: " + printerData.state);
this->debugHandle->printLn("Status: " + printerData.state);
} else {
Serial.println("Printer Not Operational");
this->debugHandle->printLn("Printer Not Operational");
}
//**** get the Printer Temps and Stat
@ -245,7 +246,7 @@ void OctoPrintClient::getPrinterJobResults() {
printerData.bedTargetTemp = (const char*)root2["temperature"]["bed"]["target"];
if (isPrinting()) {
Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)");
this->debugHandle->printLn("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)");
}
}

View File

@ -28,8 +28,10 @@ SOFTWARE.
#include <ESP8266WiFi.h>
#include "libs/ArduinoJson/ArduinoJson.h"
#include <base64.h>
#include "Debug.h"
#include "PrinterClientInterface.h"
class OctoPrintClient {
class OctoPrintClient : public PrinterClientInterface {
private:
char myServer[100];
@ -69,10 +71,11 @@ private:
} PrinterStruct;
PrinterStruct printerData;
Debug *debugHandle;
public:
OctoPrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu);
OctoPrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle);
void getPrinterJobResults();
void getPrinterPsuState();
void updatePrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu);

View File

@ -0,0 +1,170 @@
#include "OledDisplayClient.h"
OledDisplayClient::OledDisplayClient(byte sdaPin, byte sclPin, byte i2cAddress, bool isSh1106, bool invertDisplay, PrinterClientInterface *printerClient) {
this->printerClient = printerClient;
if(isSh1106) {
this->display = new SH1106Wire(i2cAddress, sdaPin, sclPin);
} else {
this->display = new SSD1306Wire(i2cAddress, sdaPin, sclPin);
}
this->ui = new OLEDDisplayUi(this->display);
this->invertDisplay = invertDisplay;
this->display->init();
if (invertDisplay) {
this->display->flipScreenVertically(); // connections at top of OLED display
}
this->display->clear();
this->display->display();
//this->overlays[0] = drawHeaderOverlay;
//this->clockOverlay[0] = drawClockHeaderOverlay;
}
void OledDisplayClient::postSetup() {
static OledDisplayClient* obj = this;
// You can change the transition that is used
// SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN
this->ui->setFrameAnimation(SLIDE_LEFT);
this->ui->setTargetFPS(30);
this->ui->disableAllIndicators();
this->ui->setFrames(this->frames, (3));
this->frames[0] = [](OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { obj->drawScreen1(display, state, x, y); };
this->frames[1] = [](OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { obj->drawScreen2(display, state, x, y); };
this->frames[2] = [](OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { obj->drawScreen3(display, state, x, y); };
this->clockFrame[0] = [](OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { obj->drawClock(display, state, x, y); };
this->clockFrame[1] = [](OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { obj->drawWeather(display, state, x, y); };
this->ui->setOverlays(this->overlays, 1);
// Inital UI takes care of initalising the display too.
this->ui->init();
if (this->invertDisplay) {
this->display->flipScreenVertically(); //connections at top of OLED display
}
}
void OledDisplayClient::showPageInit(String printerTypeName, String softwareVersion) {
this->display->setTextAlignment(TEXT_ALIGN_CENTER);
this->display->setContrast(255); // default is 255
this->display->setFont(ArialMT_Plain_16);
this->display->drawString(64, 1, "Printer Monitor");
this->display->setFont(ArialMT_Plain_10);
this->display->drawString(64, 18, "for " + printerTypeName);
this->display->setFont(ArialMT_Plain_16);
this->display->drawString(64, 30, "By Qrome");
this->display->drawString(64, 46, "V" + softwareVersion);
this->display->display();
}
void OledDisplayClient::showPageApMode(String protalSsid) {
this->display->clear();
this->display->setTextAlignment(TEXT_ALIGN_CENTER);
this->display->setFont(ArialMT_Plain_10);
this->display->drawString(64, 0, "Wifi Manager");
this->display->drawString(64, 10, "Please connect to AP");
this->display->setFont(ArialMT_Plain_16);
this->display->drawString(64, 26, protalSsid);
this->display->setFont(ArialMT_Plain_10);
this->display->drawString(64, 46, "To setup Wifi connection");
this->display->display();
}
void OledDisplayClient::showPageWeather() {
}
void OledDisplayClient::showPagePrinter() {
}
void OledDisplayClient::drawScreen1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
String bed = this->printerClient->getValueRounded(this->printerClient->getTempBedActual());
String tool = this->printerClient->getValueRounded(printerClient->getTempToolActual());
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(ArialMT_Plain_16);
if (bed != "0") {
display->drawString(29 + x, 0 + y, "Tool");
display->drawString(89 + x, 0 + y, "Bed");
} else {
display->drawString(64 + x, 0 + y, "Tool Temp");
}
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_24);
if (bed != "0") {
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawString(12 + x, 14 + y, tool + "°");
display->drawString(74 + x, 14 + y, bed + "°");
} else {
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->drawString(64 + x, 14 + y, tool + "°");
}
}
void OledDisplayClient::drawScreen2(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, "Time Remaining");
//display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_24);
int val = printerClient->getProgressPrintTimeLeft().toInt();
int hours = numberOfHours(val);
int minutes = numberOfMinutes(val);
int seconds = numberOfSeconds(val);
String time = zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds);
display->drawString(64 + x, 14 + y, time);
}
void OledDisplayClient::drawScreen3(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, "Printing Time");
//display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_24);
int val = printerClient->getProgressPrintTime().toInt();
int hours = numberOfHours(val);
int minutes = numberOfMinutes(val);
int seconds = numberOfSeconds(val);
String time = zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds);
display->drawString(64 + x, 14 + y, time);
}
void OledDisplayClient::drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
/*display->setTextAlignment(TEXT_ALIGN_CENTER);
String displayTime = timeClient.getAmPmHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds();
if (IS_24HOUR) {
displayTime = timeClient.getHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds();
}
String displayName = PrinterHostName;
if (printerClient.getPrinterType() == "Repetier") {
displayName = printerClient.getPrinterName();
}
display->setFont(ArialMT_Plain_16);
display->drawString(64 + x, 0 + y, displayName);
display->setFont(ArialMT_Plain_24);
display->drawString(64 + x, 17 + y, displayTime); */
}
void OledDisplayClient::drawWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
/*display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_24);
display->drawString(0 + x, 0 + y, weatherClient.getTempRounded(0) + getTempSymbol());
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_24);
display->setFont(ArialMT_Plain_16);
display->drawString(0 + x, 24 + y, weatherClient.getCondition(0));
display->setFont((const uint8_t*)Meteocons_Plain_42);
display->drawString(86 + x, 0 + y, weatherClient.getWeatherIcon(0));*/
}
String OledDisplayClient::zeroPad(int value) {
String rtnValue = String(value);
if (value < 10) {
rtnValue = "0" + rtnValue;
}
return rtnValue;
}

View File

@ -0,0 +1,43 @@
#pragma once
#include <ESP8266WiFi.h>
#include <base64.h>
#include "Debug.h"
#include "SH1106Wire.h"
#include "SSD1306Wire.h"
#include "OLEDDisplayUi.h"
#include "PrinterClientInterface.h"
#include "Macros.h"
class OledDisplayClient {
private:
OLEDDisplay *display;
OLEDDisplayUi *ui;
bool invertDisplay = false;
FrameCallback frames[3];
FrameCallback clockFrame[2];
boolean isClockOn = false;
OverlayCallback overlays[1];
OverlayCallback clockOverlay[1];
PrinterClientInterface *printerClient;
public:
OledDisplayClient(byte sdaPin, byte sclPin, byte i2cAddress, bool isSh1106, bool invertDisplay, PrinterClientInterface *printerClient);
void postSetup();
void showPageInit(String printerTypeName, String softwareVersion);
void showPageApMode(String protalSsid);
void showPageWeather();
void showPagePrinter();
private:
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 drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
void drawWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
String zeroPad(int value);
};

View File

@ -23,7 +23,8 @@ SOFTWARE.
#include "OpenWeatherMapClient.h"
OpenWeatherMapClient::OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric, String language) {
OpenWeatherMapClient::OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric, String language, Debug *debugHandle) {
this->debugHandle = debugHandle;
updateCityIdList(CityIDs, cityCount);
updateLanguage(language);
myApiKey = ApiKey;
@ -45,8 +46,8 @@ void OpenWeatherMapClient::updateWeather() {
WiFiClient weatherClient;
String apiGetData = "GET /data/2.5/group?id=" + myCityIDs + "&units=" + units + "&cnt=1&APPID=" + myApiKey + "&lang=" + lang + " HTTP/1.1";
Serial.println("Getting Weather Data");
Serial.println(apiGetData);
this->debugHandle->printLn("Getting Weather Data");
this->debugHandle->printLn(apiGetData);
result = "";
if (weatherClient.connect(servername, 80)) { //starts client connection, checks for connection
weatherClient.println(apiGetData);
@ -56,29 +57,29 @@ void OpenWeatherMapClient::updateWeather() {
weatherClient.println();
}
else {
Serial.println("connection for weather data failed"); //error message if no client connect
Serial.println();
this->debugHandle->printLn("connection for weather data failed"); //error message if no client connect
this->debugHandle->printLn("");
return;
}
while(weatherClient.connected() && !weatherClient.available()) delay(1); //waits for data
Serial.println("Waiting for data");
this->debugHandle->printLn("Waiting for data");
// Check HTTP status
char status[32] = {0};
weatherClient.readBytesUntil('\r', status, sizeof(status));
Serial.println("Response Header: " + String(status));
this->debugHandle->printLn("Response Header: " + String(status));
if (strcmp(status, "HTTP/1.1 200 OK") != 0) {
Serial.print(F("Unexpected response: "));
Serial.println(status);
this->debugHandle->print("Unexpected response: ");
this->debugHandle->printLn(status);
return;
}
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
if (!weatherClient.find(endOfHeaders)) {
Serial.println(F("Invalid response"));
this->debugHandle->printLn("Invalid response");
return;
}
@ -90,7 +91,7 @@ void OpenWeatherMapClient::updateWeather() {
// Parse JSON object
JsonObject& root = jsonBuffer.parseObject(weatherClient);
if (!root.success()) {
Serial.println(F("Weather Data Parsing failed!"));
this->debugHandle->printLn("Weather Data Parsing failed!");
weathers[0].error = "Weather Data Parsing failed!";
return;
}
@ -98,10 +99,10 @@ void OpenWeatherMapClient::updateWeather() {
weatherClient.stop(); //stop client
if (root.measureLength() <= 150) {
Serial.println("Error Does not look like we got the data. Size: " + String(root.measureLength()));
this->debugHandle->printLn("Error Does not look like we got the data. Size: " + String(root.measureLength()));
weathers[0].cached = true;
weathers[0].error = (const char*)root["message"];
Serial.println("Error: " + weathers[0].error);
this->debugHandle->printLn("Error: " + weathers[0].error);
return;
}
int count = root["cnt"];
@ -120,19 +121,19 @@ void OpenWeatherMapClient::updateWeather() {
weathers[inx].description = (const char*)root["list"][inx]["weather"][0]["description"];
weathers[inx].icon = (const char*)root["list"][inx]["weather"][0]["icon"];
Serial.println("lat: " + weathers[inx].lat);
Serial.println("lon: " + weathers[inx].lon);
Serial.println("dt: " + weathers[inx].dt);
Serial.println("city: " + weathers[inx].city);
Serial.println("country: " + weathers[inx].country);
Serial.println("temp: " + weathers[inx].temp);
Serial.println("humidity: " + weathers[inx].humidity);
Serial.println("condition: " + weathers[inx].condition);
Serial.println("wind: " + weathers[inx].wind);
Serial.println("weatherId: " + weathers[inx].weatherId);
Serial.println("description: " + weathers[inx].description);
Serial.println("icon: " + weathers[inx].icon);
Serial.println();
this->debugHandle->printLn("lat: " + weathers[inx].lat);
this->debugHandle->printLn("lon: " + weathers[inx].lon);
this->debugHandle->printLn("dt: " + weathers[inx].dt);
this->debugHandle->printLn("city: " + weathers[inx].city);
this->debugHandle->printLn("country: " + weathers[inx].country);
this->debugHandle->printLn("temp: " + weathers[inx].temp);
this->debugHandle->printLn("humidity: " + weathers[inx].humidity);
this->debugHandle->printLn("condition: " + weathers[inx].condition);
this->debugHandle->printLn("wind: " + weathers[inx].wind);
this->debugHandle->printLn("weatherId: " + weathers[inx].weatherId);
this->debugHandle->printLn("description: " + weathers[inx].description);
this->debugHandle->printLn("icon: " + weathers[inx].icon);
this->debugHandle->printLn("");
}
}

View File

@ -24,6 +24,7 @@ SOFTWARE.
#pragma once
#include <ESP8266WiFi.h>
#include "libs/ArduinoJson/ArduinoJson.h"
#include "Debug.h"
class OpenWeatherMapClient {
@ -57,8 +58,10 @@ private:
String roundValue(String value);
Debug *debugHandle;
public:
OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric, String language);
OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric, String language, Debug *debugHandle);
void updateWeather();
void updateWeatherApiKey(String ApiKey);
void updateCityIdList(int CityIDs[], int cityCount);

View File

@ -0,0 +1,29 @@
#pragma once
class PrinterClientInterface {
public:
virtual String getAveragePrintTime() = 0;
virtual String getEstimatedPrintTime() = 0;
virtual String getFileName() = 0;
virtual String getFileSize() = 0;
virtual String getLastPrintTime() = 0;
virtual String getProgressCompletion() = 0;
virtual String getProgressFilepos() = 0;
virtual String getProgressPrintTime() = 0;
virtual String getProgressPrintTimeLeft() = 0;
virtual String getState() = 0;
virtual boolean isPrinting() = 0;
virtual boolean isOperational() = 0;
virtual boolean isPSUoff() = 0;
virtual String getTempBedActual() = 0;
virtual String getTempBedTarget() = 0;
virtual String getTempToolActual() = 0;
virtual String getTempToolTarget() = 0;
virtual String getFilamentLength() = 0;
virtual String getValueRounded(String value) = 0;
virtual String getError() = 0;
virtual String getPrinterType() = 0;
virtual int getPrinterPort() = 0;
virtual String getPrinterName() = 0;
virtual void setPrinterName(String printer) = 0;
};

View File

@ -27,7 +27,8 @@ SOFTWARE.
#include "RepetierClient.h"
RepetierClient::RepetierClient(String ApiKey, String server, int port, String user, String pass, boolean psu) {
RepetierClient::RepetierClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle) {
this->debugHandle = debugHandle;
updatePrintClient(ApiKey, server, port, user, pass, psu);
}
@ -63,8 +64,8 @@ WiFiClient RepetierClient::getSubmitRequest(String apiGetData) {
WiFiClient printClient;
printClient.setTimeout(5000);
Serial.println("Getting Repetier Data via GET");
Serial.println(apiGetData);
this->debugHandle->printLn("Getting Repetier Data via GET");
this->debugHandle->printLn(apiGetData);
result = "";
if (printClient.connect(myServer, myPort)) { //starts client connection, checks for connection
printClient.println(apiGetData);
@ -77,40 +78,20 @@ WiFiClient RepetierClient::getSubmitRequest(String apiGetData) {
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();
this->debugHandle->printLn("Connection to " + String(myServer) + ":" + String(myPort) + " failed.");
this->debugHandle->printLn("");
resetPrintData();
printerData.error = "Connection to " + String(myServer) + ":" + String(myPort) + " failed.";
return printClient;
}
}
else {
Serial.println("Connection to Repetier failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect
Serial.println();
this->debugHandle->printLn("Connection to Repetier failed: " + String(myServer) + ":" + String(myPort)); //error message if no client connect
this->debugHandle->printLn("");
resetPrintData();
printerData.error = "Connection to Repetier 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) {
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;
}
@ -133,16 +114,16 @@ void RepetierClient::getPrinterJobResults() {
if (!root.success()) {
printerData.error = "Repetier Data Parsing failed: " + String(myServer) + ":" + String(myPort);
Serial.println(printerData.error);
this->debugHandle->printLn(printerData.error);
printerData.state = "";
return;
}
int inx = 0;
int count = root.size();
Serial.println("Size of root: " + String(count));
this->debugHandle->printLn("Size of root: " + String(count));
for (int i = 0; i < count; i++) {
Serial.println("Printer: " + String((const char*)root[i]["slug"]));
this->debugHandle->printLn("Printer: " + String((const char*)root[i]["slug"]));
if (String((const char*)root[i]["slug"]) == printerData.printerName) {
inx = i;
break;
@ -182,13 +163,13 @@ void RepetierClient::getPrinterJobResults() {
}
if (printerData.isPrinting) {
Serial.println("Printing: " + printerData.fileName);
this->debugHandle->printLn("Printing: " + printerData.fileName);
}
if (isOperational()) {
Serial.println("Status: " + printerData.state);
this->debugHandle->printLn("Status: " + printerData.state);
} else {
Serial.println("Printer Not Operational");
this->debugHandle->printLn("Printer Not Operational");
}
//**** get the Printer Temps and Stat
@ -221,7 +202,7 @@ void RepetierClient::getPrinterJobResults() {
printerData.bedTargetTemp = (const char*) pr2["heatedBeds"][0]["tempSet"];
if (printerData.isPrinting) {
Serial.println("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)");
this->debugHandle->printLn("Status: " + printerData.state + " " + printerData.fileName + "(" + printerData.progressCompletion + "%)");
}
}

View File

@ -28,8 +28,10 @@ SOFTWARE.
#include <ESP8266WiFi.h>
#include "libs/ArduinoJson/ArduinoJson.h"
#include <base64.h>
#include "Debug.h"
#include "PrinterClientInterface.h"
class RepetierClient {
class RepetierClient : public PrinterClientInterface {
private:
char myServer[100];
@ -69,10 +71,10 @@ private:
} PrinterStruct;
PrinterStruct printerData;
Debug *debugHandle;
public:
RepetierClient(String ApiKey, String server, int port, String user, String pass, boolean psu);
RepetierClient(String ApiKey, String server, int port, String user, String pass, boolean psu, Debug *debugHandle);
void getPrinterJobResults();
void getPrinterPsuState();
void updatePrintClient(String ApiKey, String server, int port, String user, String pass, boolean psu);

View File

@ -1,23 +1,3 @@
#include <doxygen.h>
#include <NexButton.h>
#include <NexConfig.h>
#include <NexCrop.h>
#include <NexGauge.h>
#include <NexHardware.h>
#include <NexHotspot.h>
#include <NexObject.h>
#include <NexPage.h>
#include <NexPicture.h>
#include <NexProgressBar.h>
#include <NexSlider.h>
#include <NexText.h>
#include <NexTimer.h>
#include <Nextion.h>
#include <NexTouch.h>
#include <NexVar.h>
#include <NexWaveform.h>
#include <SoftwareSerial.h>
/** The MIT License (MIT)
Copyright (c) 2018 David Payne
@ -59,34 +39,19 @@ SOFTWARE.
* the Web Interface.
******************************************************************************/
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>
#include <ESP8266HTTPUpdateServer.h>
#include "TimeClient.h"
#include "KlipperClient.h"
#include "DuetClient.h"
#include "RepetierClient.h"
#include "OctoPrintClient.h"
#include "OpenWeatherMapClient.h"
#include "WeatherStationFonts.h"
#include "FS.h"
#include "SH1106Wire.h"
#include "SSD1306Wire.h"
#include "OLEDDisplayUi.h"
#ifndef __SETTINGS_H__
#define __SETTINGS_H__
//******************************
// Start Settings
//******************************
// ESP32/ESP8266 compatibility!
//#define USE_ESP8266
#define USE_ESP8266
// OctoPrint / Repetier / Klipper/ 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_KLIPPER_CLIENT // Uncomment this line to use the Duet Printer Server -- OctoPrint is used by default and is most common
//#define USE_DUET_CLIENT // Uncomment this line to use the Duet Printer Server -- OctoPrint is used by default and is most common
#define USE_KLIPPER_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
@ -121,18 +86,25 @@ boolean DISPLAYCLOCK = true; // true = Show Clock when not printing / false =
// Display Settings
#define USE_NEXTION_DISPLAY
#ifdef USE_NEXTION_DISPLAY
#ifdef USE_ESP8266
const int TX_PIN = 5;
const int RX_PIN = 4;
#else
const int TX_PIN = D1;
const int RX_PIN = D2;
#endif
#else
const int I2C_DISPLAY_ADDRESS = 0x3c; // I2C Address of your Display (usually 0x3c or 0x3d)
#ifdef USE_ESP8266
const int SDA_PIN = 21;
const int SCL_PIN = 22; // original code D5 -- Monitor Easy Board use D1
const int SDA_PIN = 5;
const int SCL_PIN = 4; // original code D5 -- Monitor Easy Board use D1
#else
const int SDA_PIN = D1;
const int SCL_PIN = D2; // original code D5 -- Monitor Easy Board use D1
#endif
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
boolean DISPLAY_SH1106 = false; // true = to use the SH1106 display | false = SSD1306 is used by default and is most common
#endif
// LED Settings
@ -151,3 +123,8 @@ String OTA_Password = ""; // Set an OTA password here -- leave blank if you
//******************************
String themeColor = "light-green"; // this can be changed later in the web interface.
#define HOSTNAME "PrintMon-"
#define CONFIG "/conf.txt"
#define VERSION "4.0"
#endif

View File

@ -27,15 +27,17 @@ Modified by David Payne for use in the Scrolling Marquee
#include "TimeClient.h"
TimeClient::TimeClient(float utcOffset) {
myUtcOffset = utcOffset;
TimeClient::TimeClient(float utcOffset, boolean is24Hour, Debug *debugHandle) {
this->debugHandle = debugHandle;
this->myUtcOffset = utcOffset;
this->is24Hour = is24Hour;
}
void TimeClient::updateTime() {
WiFiClient client;
if (!client.connect(ntpServerName, httpPort)) {
Serial.println("connection failed");
this->debugHandle->printLn("connection failed");
return;
}
@ -46,7 +48,7 @@ void TimeClient::updateTime() {
int repeatCounter = 0;
while(!client.available() && repeatCounter < 10) {
delay(1000);
Serial.println(".");
this->debugHandle->printLn(".");
repeatCounter++;
}
@ -61,14 +63,14 @@ void TimeClient::updateTime() {
// example:
// date: Thu, 19 Nov 2015 20:25:40 GMT
if (line.startsWith("DATE: ")) {
Serial.println(line.substring(23, 25) + ":" + line.substring(26, 28) + ":" +line.substring(29, 31));
this->debugHandle->printLn(line.substring(23, 25) + ":" + line.substring(26, 28) + ":" +line.substring(29, 31));
int parsedHours = line.substring(23, 25).toInt();
int parsedMinutes = line.substring(26, 28).toInt();
int parsedSeconds = line.substring(29, 31).toInt();
Serial.println(String(parsedHours) + ":" + String(parsedMinutes) + ":" + String(parsedSeconds));
this->debugHandle->printLn(String(parsedHours) + ":" + String(parsedMinutes) + ":" + String(parsedSeconds));
localEpoc = (parsedHours * 60 * 60 + parsedMinutes * 60 + parsedSeconds);
Serial.println(localEpoc);
this->debugHandle->printLn(localEpoc);
localMillisAtUpdate = millis();
client.stop();
}
@ -150,3 +152,7 @@ long TimeClient::getCurrentEpoch() {
long TimeClient::getCurrentEpochWithUtcOffset() {
return (long)round(getCurrentEpoch() + 3600 * myUtcOffset + 86400L) % 86400L;
}
boolean TimeClient::isHour24() {
return this->is24Hour;
}

View File

@ -30,6 +30,7 @@ Modified by David Payne for use in the Scrolling Marquee
#pragma once
#include <ESP8266WiFi.h>
#include "Debug.h"
#define NTP_PACKET_SIZE 48
@ -42,9 +43,11 @@ class TimeClient {
const char* ntpServerName = "www.google.com";
const int httpPort = 80;
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
bool is24Hour;
Debug *debugHandle;
public:
TimeClient(float utcOffset);
TimeClient(float utcOffset, boolean is24Hour, Debug *debugHandle);
void updateTime();
void setUtcOffset(float utcOffset);
@ -57,6 +60,6 @@ class TimeClient {
String getAmPmFormattedTime();
long getCurrentEpoch();
long getCurrentEpochWithUtcOffset();
boolean isHour24();
};

View File

@ -0,0 +1,94 @@
#pragma once
static const char WEB_ACTIONS[] PROGMEM = "<a class='w3-bar-item w3-button' href='/'><i class='fa fa-home'></i> Home</a>"
"<a class='w3-bar-item w3-button' href='/configure'><i class='fa fa-cog'></i> Configure</a>"
"<a class='w3-bar-item w3-button' href='/configureweather'><i class='fa fa-cloud'></i> Weather</a>"
"<a class='w3-bar-item w3-button' href='/systemreset' onclick='return confirm(\"Do you want to reset to default settings?\")'><i class='fa fa-undo'></i> Reset Settings</a>"
"<a class='w3-bar-item w3-button' href='/forgetwifi' onclick='return confirm(\"Do you want to forget to WiFi connection?\")'><i class='fa fa-wifi'></i> Forget WiFi</a>"
"<a class='w3-bar-item w3-button' href='/update'><i class='fa fa-wrench'></i> Firmware Update</a>"
"<a class='w3-bar-item w3-button' href='https://github.com/Qrome' target='_blank'><i class='fa fa-question-circle'></i> About</a>";
String CHANGE_FORM = ""; // moved to config to make it dynamic
static const char CLOCK_FORM[] PROGMEM = "<hr><p><input name='isClockEnabled' class='w3-check w3-margin-top' type='checkbox' %IS_CLOCK_CHECKED%> Display Clock when printer is off</p>"
"<p><input name='is24hour' class='w3-check w3-margin-top' type='checkbox' %IS_24HOUR_CHECKED%> Use 24 Hour Clock (military time)</p>"
"<p><input name='invDisp' class='w3-check w3-margin-top' type='checkbox' %IS_INVDISP_CHECKED%> Flip display orientation</p>"
"<p><input name='useFlash' class='w3-check w3-margin-top' type='checkbox' %USEFLASH%> Flash System LED on Service Calls</p>"
"<p><input name='hasPSU' class='w3-check w3-margin-top' type='checkbox' %HAS_PSU_CHECKED%> Use OctoPrint PSU control plugin for clock/blank</p>"
"<p>Clock Sync / Weather Refresh (minutes) <select class='w3-option w3-padding' name='refresh'>%OPTIONS%</select></p>";
static const char THEME_FORM[] PROGMEM = "<p>Theme Color <select class='w3-option w3-padding' name='theme'>%THEME_OPTIONS%</select></p>"
"<p><label>UTC Time Offset</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='utcoffset' value='%UTCOFFSET%' maxlength='12'></p><hr>"
"<p><input name='isBasicAuth' class='w3-check w3-margin-top' type='checkbox' %IS_BASICAUTH_CHECKED%> Use Security Credentials for Configuration Changes</p>"
"<p><label>User ID (for this interface)</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='userid' value='%USERID%' maxlength='20'></p>"
"<p><label>Password </label><input class='w3-input w3-border w3-margin-bottom' type='password' name='stationpassword' value='%STATIONPASSWORD%'></p>"
"<button class='w3-button w3-block w3-grey w3-section w3-padding' type='submit'>Save</button></form>";
static const char WEATHER_FORM[] PROGMEM = "<form class='w3-container' action='/updateweatherconfig' method='get'><h2>Weather Config:</h2>"
"<p><input name='isWeatherEnabled' class='w3-check w3-margin-top' type='checkbox' %IS_WEATHER_CHECKED%> Display Weather when printer is off</p>"
"<label>OpenWeatherMap API Key (get from <a href='https://openweathermap.org/' target='_BLANK'>here</a>)</label>"
"<input class='w3-input w3-border w3-margin-bottom' type='text' name='openWeatherMapApiKey' value='%WEATHERKEY%' maxlength='60'>"
"<p><label>%CITYNAME1% (<a href='http://openweathermap.org/find' target='_BLANK'><i class='fa fa-search'></i> Search for City ID</a>) "
"<input class='w3-input w3-border w3-margin-bottom' type='text' name='city1' value='%CITY1%' onkeypress='return isNumberKey(event)'></p>"
"<p><input name='metric' class='w3-check w3-margin-top' type='checkbox' %METRIC%> Use Metric (Celsius)</p>"
"<p>Weather Language <select class='w3-option w3-padding' name='language'>%LANGUAGEOPTIONS%</select></p>"
"<button class='w3-button w3-block w3-grey w3-section w3-padding' type='submit'>Save</button></form>"
"<script>function isNumberKey(e){var h=e.which?e.which:event.keyCode;return!(h>31&&(h<48||h>57))}</script>";
static const char LANG_OPTIONS[] PROGMEM = "<option>ar</option>"
"<option>bg</option>"
"<option>ca</option>"
"<option>cz</option>"
"<option>de</option>"
"<option>el</option>"
"<option>en</option>"
"<option>fa</option>"
"<option>fi</option>"
"<option>fr</option>"
"<option>gl</option>"
"<option>hr</option>"
"<option>hu</option>"
"<option>it</option>"
"<option>ja</option>"
"<option>kr</option>"
"<option>la</option>"
"<option>lt</option>"
"<option>mk</option>"
"<option>nl</option>"
"<option>pl</option>"
"<option>pt</option>"
"<option>ro</option>"
"<option>ru</option>"
"<option>se</option>"
"<option>sk</option>"
"<option>sl</option>"
"<option>es</option>"
"<option>tr</option>"
"<option>ua</option>"
"<option>vi</option>"
"<option>zh_cn</option>"
"<option>zh_tw</option>";
static const char COLOR_THEMES[] PROGMEM = "<option>red</option>"
"<option>pink</option>"
"<option>purple</option>"
"<option>deep-purple</option>"
"<option>indigo</option>"
"<option>blue</option>"
"<option>light-blue</option>"
"<option>cyan</option>"
"<option>teal</option>"
"<option>green</option>"
"<option>light-green</option>"
"<option>lime</option>"
"<option>khaki</option>"
"<option>yellow</option>"
"<option>amber</option>"
"<option>orange</option>"
"<option>deep-orange</option>"
"<option>blue-grey</option>"
"<option>brown</option>"
"<option>grey</option>"
"<option>dark-grey</option>"
"<option>black</option>"
"<option>w3schools</option>";

View File

@ -0,0 +1,349 @@
#include "WebServer.h"
static const char WEB_ACTIONS[] PROGMEM = "<a class='w3-bar-item w3-button' href='/'><i class='fa fa-home'></i> Home</a>"
"<a class='w3-bar-item w3-button' href='/configure'><i class='fa fa-cog'></i> Configure</a>"
"<a class='w3-bar-item w3-button' href='/configureweather'><i class='fa fa-cloud'></i> Weather</a>"
"<a class='w3-bar-item w3-button' href='/systemreset' onclick='return confirm(\"Do you want to reset to default settings?\")'><i class='fa fa-undo'></i> Reset Settings</a>"
"<a class='w3-bar-item w3-button' href='/forgetwifi' onclick='return confirm(\"Do you want to forget to WiFi connection?\")'><i class='fa fa-wifi'></i> Forget WiFi</a>"
"<a class='w3-bar-item w3-button' href='/update'><i class='fa fa-wrench'></i> Firmware Update</a>"
"<a class='w3-bar-item w3-button' href='https://github.com/Qrome' target='_blank'><i class='fa fa-question-circle'></i> About</a>";
static const char CLOCK_FORM[] PROGMEM = "<hr><p><input name='isClockEnabled' class='w3-check w3-margin-top' type='checkbox' %IS_CLOCK_CHECKED%> Display Clock when printer is off</p>"
"<p><input name='is24hour' class='w3-check w3-margin-top' type='checkbox' %IS_24HOUR_CHECKED%> Use 24 Hour Clock (military time)</p>"
"<p><input name='invDisp' class='w3-check w3-margin-top' type='checkbox' %IS_INVDISP_CHECKED%> Flip display orientation</p>"
"<p><input name='useFlash' class='w3-check w3-margin-top' type='checkbox' %USEFLASH%> Flash System LED on Service Calls</p>"
"<p><input name='hasPSU' class='w3-check w3-margin-top' type='checkbox' %HAS_PSU_CHECKED%> Use OctoPrint PSU control plugin for clock/blank</p>"
"<p>Clock Sync / Weather Refresh (minutes) <select class='w3-option w3-padding' name='refresh'>%OPTIONS%</select></p>";
static const char THEME_FORM[] PROGMEM = "<p>Theme Color <select class='w3-option w3-padding' name='theme'>%THEME_OPTIONS%</select></p>"
"<p><label>UTC Time Offset</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='utcoffset' value='%UTCOFFSET%' maxlength='12'></p><hr>"
"<p><input name='isBasicAuth' class='w3-check w3-margin-top' type='checkbox' %IS_BASICAUTH_CHECKED%> Use Security Credentials for Configuration Changes</p>"
"<p><label>User ID (for this interface)</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='userid' value='%USERID%' maxlength='20'></p>"
"<p><label>Password </label><input class='w3-input w3-border w3-margin-bottom' type='password' name='stationpassword' value='%STATIONPASSWORD%'></p>"
"<button class='w3-button w3-block w3-grey w3-section w3-padding' type='submit'>Save</button></form>";
static const char WEATHER_FORM[] PROGMEM = "<form class='w3-container' action='/updateweatherconfig' method='get'><h2>Weather Config:</h2>"
"<p><input name='isWeatherEnabled' class='w3-check w3-margin-top' type='checkbox' %IS_WEATHER_CHECKED%> Display Weather when printer is off</p>"
"<label>OpenWeatherMap API Key (get from <a href='https://openweathermap.org/' target='_BLANK'>here</a>)</label>"
"<input class='w3-input w3-border w3-margin-bottom' type='text' name='openWeatherMapApiKey' value='%WEATHERKEY%' maxlength='60'>"
"<p><label>%CITYNAME1% (<a href='http://openweathermap.org/find' target='_BLANK'><i class='fa fa-search'></i> Search for City ID</a>) "
"<input class='w3-input w3-border w3-margin-bottom' type='text' name='city1' value='%CITY1%' onkeypress='return isNumberKey(event)'></p>"
"<p><input name='metric' class='w3-check w3-margin-top' type='checkbox' %METRIC%> Use Metric (Celsius)</p>"
"<p>Weather Language <select class='w3-option w3-padding' name='language'>%LANGUAGEOPTIONS%</select></p>"
"<button class='w3-button w3-block w3-grey w3-section w3-padding' type='submit'>Save</button></form>"
"<script>function isNumberKey(e){var h=e.which?e.which:event.keyCode;return!(h>31&&(h<48||h>57))}</script>";
static const char LANG_OPTIONS[] PROGMEM = "<option>ar</option>"
"<option>bg</option>"
"<option>ca</option>"
"<option>cz</option>"
"<option>de</option>"
"<option>el</option>"
"<option>en</option>"
"<option>fa</option>"
"<option>fi</option>"
"<option>fr</option>"
"<option>gl</option>"
"<option>hr</option>"
"<option>hu</option>"
"<option>it</option>"
"<option>ja</option>"
"<option>kr</option>"
"<option>la</option>"
"<option>lt</option>"
"<option>mk</option>"
"<option>nl</option>"
"<option>pl</option>"
"<option>pt</option>"
"<option>ro</option>"
"<option>ru</option>"
"<option>se</option>"
"<option>sk</option>"
"<option>sl</option>"
"<option>es</option>"
"<option>tr</option>"
"<option>ua</option>"
"<option>vi</option>"
"<option>zh_cn</option>"
"<option>zh_tw</option>";
static const char COLOR_THEMES[] PROGMEM = "<option>red</option>"
"<option>pink</option>"
"<option>purple</option>"
"<option>deep-purple</option>"
"<option>indigo</option>"
"<option>blue</option>"
"<option>light-blue</option>"
"<option>cyan</option>"
"<option>teal</option>"
"<option>green</option>"
"<option>light-green</option>"
"<option>lime</option>"
"<option>khaki</option>"
"<option>yellow</option>"
"<option>amber</option>"
"<option>orange</option>"
"<option>deep-orange</option>"
"<option>blue-grey</option>"
"<option>brown</option>"
"<option>grey</option>"
"<option>dark-grey</option>"
"<option>black</option>"
"<option>w3schools</option>";
WebServer::WebServer(ESP8266WebServer *serverHandle, Debug *debugHandle, PrinterClientInterface *printerClient, TimeClient *timeClient, String themeColor, String swVersion, boolean hasPsu) {
this->serverHandle = serverHandle;
this->themeColor = themeColor;
this->debugHandle = debugHandle;
this->swVersion = swVersion;
this->printerClient = printerClient;
this->timeClient = timeClient;
this->hostName = "";
this->hasPsu = hasPsu;
this->isBasicAuth = false;
this->wwwUsername = "";
this->wwwPassword = "";
}
void WebServer::setHostname(String hostName) {
this->hostName = hostName;
}
void WebServer::redirectHome() {
// Send them back to the Root Directory
this->serverHandle->sendHeader("Location", String("/"), true);
this->serverHandle->sendHeader("Cache-Control", "no-cache, no-store");
this->serverHandle->sendHeader("Pragma", "no-cache");
this->serverHandle->sendHeader("Expires", "-1");
this->serverHandle->send(302, "text/plain", "");
this->serverHandle->client().stop();
}
String WebServer::getHeader() {
return this->getHeader(false);
}
String WebServer::getHeader(boolean refresh) {
String menu = FPSTR(WEB_ACTIONS);
String html = "<!DOCTYPE HTML>";
html += "<html><head><title>Printer Monitor</title><link rel='icon' href='data:;base64,='>";
html += "<meta charset='UTF-8'>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1'>";
if (refresh) {
html += "<meta http-equiv=\"refresh\" content=\"30\">";
}
html += "<link rel='stylesheet' href='https://www.w3schools.com/w3css/4/w3.css'>";
html += "<link rel='stylesheet' href='https://www.w3schools.com/lib/w3-theme-" + this->themeColor + ".css'>";
html += "<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'>";
html += "</head><body>";
html += "<nav class='w3-sidebar w3-bar-block w3-card' style='margin-top:88px' id='mySidebar'>";
html += "<div class='w3-container w3-theme-d2'>";
html += "<span onclick='closeSidebar()' class='w3-button w3-display-topright w3-large'><i class='fa fa-times'></i></span>";
html += "<div class='w3-cell w3-left w3-xxxlarge' style='width:60px'><i class='fa fa-cube'></i></div>";
html += "<div class='w3-padding'>Menu</div></div>";
html += menu;
html += "</nav>";
html += "<header class='w3-top w3-bar w3-theme'><button class='w3-bar-item w3-button w3-xxxlarge w3-hover-theme' onclick='openSidebar()'><i class='fa fa-bars'></i></button><h2 class='w3-bar-item'>Printer Monitor</h2></header>";
html += "<script>";
html += "function openSidebar(){document.getElementById('mySidebar').style.display='block'}function closeSidebar(){document.getElementById('mySidebar').style.display='none'}closeSidebar();";
html += "</script>";
html += "<br><div class='w3-container w3-large' style='margin-top:88px'>";
return html;
}
String WebServer::getFooter() {
int8_t rssi = this->getWifiQuality();
this->debugHandle->print("Signal Strength (RSSI): ");
this->debugHandle->print(rssi);
this->debugHandle->printLn("%");
String html = "<br><br><br>";
html += "</div>";
html += "<footer class='w3-container w3-bottom w3-theme w3-margin-top'>";
if (this->lastReportStatus != "") {
html += "<i class='fa fa-external-link'></i> Report Status: " + this->lastReportStatus + "<br>";
}
html += "<i class='fa fa-paper-plane-o'></i> Version: " + this->swVersion + "<br>";
html += "<i class='fa fa-rss'></i> Signal Strength: ";
html += String(rssi) + "%";
html += "</footer>";
html += "</body></html>";
return html;
}
void WebServer::displayPrinterStatus() {
String html = "";
this->serverHandle->sendHeader("Cache-Control", "no-cache, no-store");
this->serverHandle->sendHeader("Pragma", "no-cache");
this->serverHandle->sendHeader("Expires", "-1");
this->serverHandle->setContentLength(CONTENT_LENGTH_UNKNOWN);
this->serverHandle->send(200, "text/html", "");
this->serverHandle->sendContent(String(this->getHeader(true)));
String displayTime = this->timeClient->getAmPmHours() + ":" + this->timeClient->getMinutes() + ":" + this->timeClient->getSeconds() + " " + this->timeClient->getAmPm();
if (this->timeClient->isHour24()) {
displayTime = this->timeClient->getHours() + ":" + this->timeClient->getMinutes() + ":" + this->timeClient->getSeconds();
}
html += "<div class='w3-cell-row' style='width:100%'><h2>" + this->printerClient->getPrinterType() + " Monitor</h2></div><div class='w3-cell-row'>";
html += "<div class='w3-cell w3-container' style='width:100%'><p>";
if (this->printerClient->getPrinterType() == "Repetier") {
html += "Printer Name: " + this->printerClient->getPrinterName() + " <a href='/configure' title='Configure'><i class='fa fa-cog'></i></a><br>";
} else {
html += "Host Name: " + this->hostName + " <a href='/configure' title='Configure'><i class='fa fa-cog'></i></a><br>";
}
if (this->printerClient->getError() != "") {
html += "Status: Offline<br>";
html += "Reason: " + this->printerClient->getError() + "<br>";
} else {
html += "Status: " + this->printerClient->getState();
if (this->printerClient->isPSUoff() && this->hasPsu) {
html += ", PSU off";
}
html += "<br>";
}
if (this->printerClient->isPrinting()) {
html += "File: " + this->printerClient->getFileName() + "<br>";
float fileSize = this->printerClient->getFileSize().toFloat();
if (fileSize > 0) {
fileSize = fileSize / 1024;
html += "File Size: " + String(fileSize) + "KB<br>";
}
int filamentLength = this->printerClient->getFilamentLength().toInt();
if (filamentLength > 0) {
float fLength = float(filamentLength) / 1000;
html += "Filament: " + String(fLength) + "m<br>";
}
html += "Tool Temperature: " + this->printerClient->getTempToolActual() + "&#176; C<br>";
if ( this->printerClient->getTempBedActual() != 0 ) {
html += "Bed Temperature: " + this->printerClient->getTempBedActual() + "&#176; C<br>";
}
int val = this->printerClient->getProgressPrintTimeLeft().toInt();
int hours = numberOfHours(val);
int minutes = numberOfMinutes(val);
int seconds = numberOfSeconds(val);
html += "Est. Print Time Left: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "<br>";
val = this->printerClient->getProgressPrintTime().toInt();
hours = numberOfHours(val);
minutes = numberOfMinutes(val);
seconds = numberOfSeconds(val);
html += "Printing Time: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "<br>";
html += "<style>#myProgress {width: 100%;background-color: #ddd;}#myBar {width: " + this->printerClient->getProgressCompletion() + "%;height: 30px;background-color: #4CAF50;}</style>";
html += "<div id=\"myProgress\"><div id=\"myBar\" class=\"w3-medium w3-center\">" + this->printerClient->getProgressCompletion() + "%</div></div>";
} else {
html += "<hr>";
}
html += "</p></div></div>";
html += "<div class='w3-cell-row' style='width:100%'><h2>Time: " + displayTime + "</h2></div>";
this->serverHandle->sendContent(html); // spit out what we got
html = "";
/*
if (DISPLAYWEATHER) {
if (weatherClient.getCity(0) == "") {
html += "<p>Please <a href='/configureweather'>Configure Weather</a> API</p>";
if (weatherClient.getError() != "") {
html += "<p>Weather Error: <strong>" + weatherClient.getError() + "</strong></p>";
}
} else {
html += "<div class='w3-cell-row' style='width:100%'><h2>" + weatherClient.getCity(0) + ", " + weatherClient.getCountry(0) + "</h2></div><div class='w3-cell-row'>";
html += "<div class='w3-cell w3-left w3-medium' style='width:120px'>";
html += "<img src='http://openweathermap.org/img/w/" + weatherClient.getIcon(0) + ".png' alt='" + weatherClient.getDescription(0) + "'><br>";
html += weatherClient.getHumidity(0) + "% Humidity<br>";
html += weatherClient.getWind(0) + " <span class='w3-tiny'>" + getSpeedSymbol() + "</span> Wind<br>";
html += "</div>";
html += "<div class='w3-cell w3-container' style='width:100%'><p>";
html += weatherClient.getCondition(0) + " (" + weatherClient.getDescription(0) + ")<br>";
html += weatherClient.getTempRounded(0) + getTempSymbol(true) + "<br>";
html += "<a href='https://www.google.com/maps/@" + weatherClient.getLat(0) + "," + weatherClient.getLon(0) + ",10000m/data=!3m1!1e3' target='_BLANK'><i class='fa fa-map-marker' style='color:red'></i> Map It!</a><br>";
html += "</p></div></div>";
}
this->serverHandle->sendContent(html); // spit out what we got
html = ""; // fresh start
}*/
this->serverHandle->sendContent(String(getFooter()));
this->serverHandle->sendContent("");
this->serverHandle->client().stop();
}
void WebServer::displayMessage(String message) {
this->serverHandle->sendHeader("Cache-Control", "no-cache, no-store");
this->serverHandle->sendHeader("Pragma", "no-cache");
this->serverHandle->sendHeader("Expires", "-1");
this->serverHandle->setContentLength(CONTENT_LENGTH_UNKNOWN);
this->serverHandle->send(200, "text/html", "");
String html = this->getHeader();
this->serverHandle->sendContent(String(html));
this->serverHandle->sendContent(String(message));
html = this->getFooter();
this->serverHandle->sendContent(String(html));
this->serverHandle->sendContent("");
this->serverHandle->client().stop();
}
void WebServer::setAuthentication(boolean enableBasicAuth, char *username, char *password) {
this->isBasicAuth = enableBasicAuth;
this->wwwUsername = username;
this->wwwPassword = password;
}
boolean WebServer::authentication() {
if (this->isBasicAuth && (strlen(this->wwwUsername) >= 1 && strlen(this->wwwPassword) >= 1)) {
return this->serverHandle->authenticate(this->wwwUsername, this->wwwPassword);
}
return true; // Authentication not required
}
void WebServer::handleWifiReset() {
if (!this->authentication()) {
return this->serverHandle->requestAuthentication();
}
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
this->redirectHome();
WiFiManager wifiManager;
wifiManager.resetSettings();
ESP.restart();
}
void WebServer::handleSystemReset() {
if (!this->authentication()) {
return this->serverHandle->requestAuthentication();
}
this->debugHandle->printLn("Reset System Configuration");
//if (SPIFFS.remove(CONFIG)) {
this->redirectHome();
ESP.restart();
//}
}
int8_t WebServer::getWifiQuality() {
int32_t dbm = WiFi.RSSI();
if(dbm <= -100) {
return 0;
} else if(dbm >= -50) {
return 100;
} else {
return 2 * (dbm + 100);
}
}
String WebServer::zeroPad(int value) {
String rtnValue = String(value);
if (value < 10) {
rtnValue = "0" + rtnValue;
}
return rtnValue;
}

View File

@ -0,0 +1,45 @@
#pragma once
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include "Debug.h"
#include "PrinterClientInterface.h"
#include "TimeClient.h"
#include "Macros.h"
class WebServer {
private:
ESP8266WebServer *serverHandle;
String themeColor;
Debug *debugHandle;
String lastReportStatus;
String swVersion;
String hostName;
TimeClient *timeClient;
PrinterClientInterface *printerClient;
boolean hasPsu;
boolean isBasicAuth;
char *wwwUsername;
char *wwwPassword;
public:
WebServer(ESP8266WebServer *serverHandle, Debug *debugHandle, PrinterClientInterface *printerClient, TimeClient *timeClient, String themeColor, String swVersion, boolean hasPsu);
void setHostname(String hostName);
void redirectHome();
String getHeader();
String getHeader(boolean refresh);
String getFooter();
void displayPrinterStatus();
void displayMessage(String message);
void setAuthentication(boolean enableBasicAuth, char *username, char *password);
boolean authentication();
void handleSystemReset();
void handleWifiReset();
int8_t getWifiQuality();
String zeroPad(int value);
};

File diff suppressed because it is too large Load Diff