printer-monitor/src/Display/OledDisplay.cpp

362 lines
16 KiB
C++

#include "OledDisplay.h"
OledDisplay::OledDisplay(OLEDDisplay *oledDisplay, GlobalDataController *globalDataController, DebugController *debugController) {
this->globalDataController = globalDataController;
this->debugController = debugController;
this->oledDisplay = oledDisplay;
this->ui = new OLEDDisplayUi(oledDisplay);
}
void OledDisplay::preSetup() {
this->oledDisplay->init();
if (this->globalDataController->isDisplayInverted()) {
this->oledDisplay->flipScreenVertically(); // connections at top of OLED display
}
this->oledDisplay->clear();
this->oledDisplay->display();
}
void OledDisplay::postSetup() {
static OledDisplay* obj = this;
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->overlays[0] = [](OLEDDisplay *display, OLEDDisplayUiState* state) { obj->drawHeaderOverlay(display, state); };
this->clockOverlay[0] = [](OLEDDisplay *display, OLEDDisplayUiState* state) { obj->drawClockHeaderOverlay(display, state); };
// 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(frames, (3));
this->ui->setOverlays(overlays, 1);
// Inital UI takes care of initalising the display too.
this->ui->init();
if (this->globalDataController->isDisplayInverted()) {
this->oledDisplay->flipScreenVertically(); // connections at top of OLED display
}
}
void OledDisplay::handleUpdate() {
this->checkDisplay();
this->ui->update();
}
void OledDisplay::flipDisplayUpdate() {
this->ui->init();
if (this->globalDataController->isDisplayInverted()) {
this->oledDisplay->flipScreenVertically(); // connections at top of OLED display
}
this->ui->update();
}
void OledDisplay::showBootScreen() {
this->oledDisplay->setTextAlignment(TEXT_ALIGN_CENTER);
this->oledDisplay->setContrast(255); // default is 255
this->oledDisplay->setFont(ArialMT_Plain_16);
this->oledDisplay->drawString(64, 1, "Printer Monitor");
this->oledDisplay->setFont(ArialMT_Plain_10);
this->oledDisplay->drawString(64, 18, "for " + this->globalDataController->getPrinterClient()->getPrinterType());
this->oledDisplay->setFont(ArialMT_Plain_16);
this->oledDisplay->drawString(64, 30, "By Qrome");
this->oledDisplay->drawString(64, 46, "V" + this->globalDataController->getVersion());
this->oledDisplay->display();
}
void OledDisplay::showApAccessScreen(String apSsid, String apIp) {
this->oledDisplay->clear();
this->oledDisplay->setTextAlignment(TEXT_ALIGN_CENTER);
this->oledDisplay->setFont(ArialMT_Plain_10);
this->oledDisplay->drawString(64, 0, "Wifi Manager");
this->oledDisplay->drawString(64, 10, "Please connect to AP");
this->oledDisplay->setFont(ArialMT_Plain_16);
this->oledDisplay->drawString(64, 26, apSsid);
this->oledDisplay->setFont(ArialMT_Plain_10);
this->oledDisplay->drawString(64, 46, "To setup Wifi connection");
this->oledDisplay->display();
}
void OledDisplay::showWebserverSplashScreen(bool isEnabled) {
if (isEnabled) {
String webAddress = "http://" + WiFi.localIP().toString() + ":" + String(this->globalDataController->getWebserverPort()) + "/";
this->debugController->printLn("Use this URL : " + webAddress);
this->oledDisplay->clear();
this->oledDisplay->setTextAlignment(TEXT_ALIGN_CENTER);
this->oledDisplay->setFont(ArialMT_Plain_10);
this->oledDisplay->drawString(64, 10, "Web Interface On");
this->oledDisplay->drawString(64, 20, "You May Connect to IP");
this->oledDisplay->setFont(ArialMT_Plain_16);
this->oledDisplay->drawString(64, 30, WiFi.localIP().toString());
this->oledDisplay->drawString(64, 46, "Port: " + String(this->globalDataController->getWebserverPort()));
this->oledDisplay->display();
} else {
this->debugController->printLn("Web Interface is Disabled");
this->oledDisplay->clear();
this->oledDisplay->setTextAlignment(TEXT_ALIGN_CENTER);
this->oledDisplay->setFont(ArialMT_Plain_10);
this->oledDisplay->drawString(64, 10, "Web Interface is Off");
this->oledDisplay->drawString(64, 20, "Enable in Settings.h");
this->oledDisplay->display();
}
}
void OledDisplay::checkDisplay() {
BasePrinterClient *printerClient = this->globalDataController->getPrinterClient();
if (!this->displayOn && this->globalDataController->getDisplayClock()) {
this->enableDisplay(true);
}
if (this->displayOn && !printerClient->isPrinting() && !this->globalDataController->getDisplayClock()) {
// Put Display to sleep
this->oledDisplay->clear();
this->oledDisplay->display();
this->oledDisplay->setFont(ArialMT_Plain_16);
this->oledDisplay->setTextAlignment(TEXT_ALIGN_CENTER);
this->oledDisplay->setContrast(255); // default is 255
this->oledDisplay->drawString(64, 5, "Printer Offline\nSleep Mode...");
this->oledDisplay->display();
delay(5000);
this->enableDisplay(false);
this->debugController->printLn("Printer is offline going down to sleep...");
return;
} else if (!this->displayOn && !this->globalDataController->getDisplayClock()) {
if (printerClient->isOperational()) {
// Wake the Screen up
this->enableDisplay(true);
this->oledDisplay->clear();
this->oledDisplay->display();
this->oledDisplay->setFont(ArialMT_Plain_16);
this->oledDisplay->setTextAlignment(TEXT_ALIGN_CENTER);
this->oledDisplay->setContrast(255); // default is 255
this->oledDisplay->drawString(64, 5, "Printer Online\nWake up...");
this->oledDisplay->display();
this->debugController->printLn("Printer is online waking up...");
delay(5000);
return;
}
} else if (this->globalDataController->getDisplayClock()) {
if ((!printerClient->isPrinting() || printerClient->isPSUoff()) && !this->isClockOn) {
this->debugController->printLn("Clock Mode is turned on.");
if (!DISPLAYWEATHER) {
this->ui->disableAutoTransition();
this->ui->setFrames(clockFrame, 1);
} else {
this->ui->enableAutoTransition();
this->ui->setFrames(clockFrame, 2);
}
this->ui->setOverlays(clockOverlay, 1);
this->isClockOn = true;
} else if (printerClient->isPrinting() && !printerClient->isPSUoff() && this->isClockOn) {
this->debugController->printLn("Printer Monitor is active.");
this->ui->setFrames(frames, 3);
this->ui->setOverlays(overlays, 1);
this->ui->enableAutoTransition();
isClockOn = false;
}
}
}
void OledDisplay::enableDisplay(boolean enable) {
this->displayOn = enable;
TimeClient * timeClient = this->globalDataController->getTimeClient();
if (enable) {
if (timeClient->getMinutesFromLast(this->displayOffEpoch) >= this->globalDataController->getClockResyncMinutes()) {
// The display has been off longer than the minutes between refresh -- need to get fresh data
timeClient->resetLastEpoch();
this->displayOffEpoch = 0; // reset
}
this->oledDisplay->displayOn();
this->debugController->printLn(
"Display was turned ON: " + timeClient->getFormattedTime()
);
} else {
this->oledDisplay->displayOff();
this->debugController->printLn(
"Display was turned OFF: " + timeClient->getFormattedTime()
);
this->displayOffEpoch = timeClient->getLastEpoch();
}
}
void OledDisplay::drawScreen1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
BasePrinterClient *printerClient = this->globalDataController->getPrinterClient();
String bed = printerClient->getValueRounded(printerClient->getTempBedActual());
String tool = 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 OledDisplay::drawScreen2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
BasePrinterClient *printerClient = this->globalDataController->getPrinterClient();
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 = this->globalDataController->numberOfHours(val);
int minutes = this->globalDataController->numberOfMinutes(val);
int seconds = this->globalDataController->numberOfSeconds(val);
String time = this->globalDataController->zeroPad(hours) + ":" +
this->globalDataController->zeroPad(minutes) + ":" +
this->globalDataController->zeroPad(seconds);
display->drawString(64 + x, 14 + y, time);
}
void OledDisplay::drawScreen3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
BasePrinterClient *printerClient = this->globalDataController->getPrinterClient();
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 = this->globalDataController->numberOfHours(val);
int minutes = this->globalDataController->numberOfMinutes(val);
int seconds = this->globalDataController->numberOfSeconds(val);
String time = this->globalDataController->zeroPad(hours) + ":" +
this->globalDataController->zeroPad(minutes) + ":" +
this->globalDataController->zeroPad(seconds);
display->drawString(64 + x, 14 + y, time);
}
void OledDisplay::drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
TimeClient * timeClient = this->globalDataController->getTimeClient();
BasePrinterClient *printerClient = this->globalDataController->getPrinterClient();
display->setTextAlignment(TEXT_ALIGN_CENTER);
String displayTime = timeClient->getAmPmHours() + ":" + timeClient->getMinutes() + ":" + timeClient->getSeconds();
if (this->globalDataController->getClockIs24h()) {
displayTime = timeClient->getHours() + ":" + timeClient->getMinutes() + ":" + timeClient->getSeconds();
}
String displayName = this->globalDataController->getPrinterHostName();
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 OledDisplay::drawWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
OpenWeatherMapClient *weatherClient = this->globalDataController->getWeatherClient();
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_24);
display->drawString(0 + x, 0 + y, weatherClient->getTempRounded(0) + weatherClient->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));
}
void OledDisplay::drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
TimeClient * timeClient = this->globalDataController->getTimeClient();
BasePrinterClient *printerClient = this->globalDataController->getPrinterClient();
display->setColor(WHITE);
display->setFont(ArialMT_Plain_16);
String displayTime = timeClient->getAmPmHours() + ":" + timeClient->getMinutes();
if (this->globalDataController->getClockIs24h()) {
displayTime = timeClient->getHours() + ":" + timeClient->getMinutes();
}
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawString(0, 48, displayTime);
if (!this->globalDataController->getClockIs24h()) {
String ampm = timeClient->getAmPm();
display->setFont(ArialMT_Plain_10);
display->drawString(39, 54, ampm);
}
display->setFont(ArialMT_Plain_16);
display->setTextAlignment(TEXT_ALIGN_LEFT);
String percent = String(printerClient->getProgressCompletion()) + "%";
display->drawString(64, 48, percent);
// Draw indicator to show next update
int updatePos = (printerClient->getProgressCompletion().toFloat() / float(100)) * 128;
display->drawRect(0, 41, 128, 6);
display->drawHorizontalLine(0, 42, updatePos);
display->drawHorizontalLine(0, 43, updatePos);
display->drawHorizontalLine(0, 44, updatePos);
display->drawHorizontalLine(0, 45, updatePos);
this->drawRssi(display);
}
void OledDisplay::drawClockHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
TimeClient * timeClient = this->globalDataController->getTimeClient();
BasePrinterClient *printerClient = this->globalDataController->getPrinterClient();
display->setColor(WHITE);
display->setFont(ArialMT_Plain_16);
display->setTextAlignment(TEXT_ALIGN_LEFT);
int printerStateDrawXPos = 0;
if (!this->globalDataController->getClockIs24h()) {
display->drawString(0, 48, timeClient->getAmPm());
display->setTextAlignment(TEXT_ALIGN_CENTER);
printerStateDrawXPos = 64;
}
if (printerClient->isPSUoff()) {
display->drawString(printerStateDrawXPos, 47, "psu off");
} else if (printerClient->getState() == "Operational") {
display->drawString(printerStateDrawXPos, 47, "online");
} else {
display->drawString(printerStateDrawXPos, 47, "offline");
}
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawRect(0, 43, 128, 2);
this->drawRssi(display);
}
void OledDisplay::drawRssi(OLEDDisplay *display) {
int8_t quality = this->globalDataController->getWifiQuality();
for (int8_t i = 0; i < 4; i++) {
for (int8_t j = 0; j < 3 * (i + 2); j++) {
if (quality > i * 25 || j == 0) {
display->setPixel(114 + 4 * i, 63 - j);
}
}
}
}