+#include "TimeClient.h"
+#include "OctoPrintClient.h"
+#include "OpenWeatherMapClient.h"
+#include "WeatherStationFonts.h"
+#include "FS.h"
+#include "SH1106Wire.h"
+#include "SSD1306Wire.h"
+#include "OLEDDisplayUi.h"
+
+//******************************
+// Start Settings
+//******************************
+
+// OctoPrint Monitoring -- Monitor your 3D printer OctoPrint Server
+String OctoPrintApiKey = ""; // ApiKey from your User Account on OctoPrint
+String OctoPrintHostName = "octopi";// Default 'octopi' -- or hostname if different (optional if your IP changes)
+String OctoPrintServer = ""; // IP or Address of your OctoPrint Server (DO NOT include http://)
+int OctoPrintPort = 80; // the port you are running your OctoPrint server on (usually 80);
+String OctoAuthUser = ""; // only used if you have haproxy or basic athentintication turned on (not default)
+String OctoAuthPass = ""; // only used with haproxy or basic auth (only needed if you must authenticate)
+
+// Weather Configuration
+boolean DISPLAYWEATHER = true; // true = show weather when not printing / false = no weather
+String WeatherApiKey = ""; // Your API Key from http://openweathermap.org/
+// Default City Location (use http://openweathermap.org/find to find city ID)
+int CityIDs[] = { 5304391 }; //Only USE ONE for weather marquee
+boolean IS_METRIC = false; // false = Imperial and true = Metric
+
+const int WEBSERVER_PORT = 80; // The port you can access this device on over HTTP
+const boolean WEBSERVER_ENABLED = true; // Device will provide a web interface via http://[ip]:[port]/
+char* www_username = "admin"; // User account for the Web Interface
+char* www_password = "password"; // Password for the Web Interface
+float UtcOffset = -7; // Hour offset from GMT for your timezone
+boolean IS_24HOUR = false; // 23:00 millitary 24 hour clock
+int minutesBetweenDataRefresh = 15;
+boolean DISPLAYCLOCK = true; // true = Show Clock when not printing / false = turn off display when not printing
+
+// Display Settings
+const int I2C_DISPLAY_ADDRESS = 0x3c; // I2C Address of your Display (usually 0x3c or 0x3d)
+const int SDA_PIN = D2;
+const int SCL_PIN = D5;
+boolean INVERT_DISPLAY = false; // 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 ENABLE_OTA = true; // this will allow you to load firmware to the device over WiFi (see OTA for ESP8266)
+String OTA_Password = ""; // Set an OTA password here -- leave blank if you don't want to be prompted for password
+//******************************
+// End Settings
+//******************************
+
String themeColor = "light-green"; // this can be changed later in the web interface.
From a91da219eec71ee94f758337e4fabbb6896d986a Mon Sep 17 00:00:00 2001
From: derpicknicker1 <10minutemail@web.de>
Date: Thu, 27 Sep 2018 09:35:42 +0200
Subject: [PATCH 5/7] changed (c)
---
printermonitor/printermonitor.ino | 2301 ++++++++++++++---------------
1 file changed, 1150 insertions(+), 1151 deletions(-)
diff --git a/printermonitor/printermonitor.ino b/printermonitor/printermonitor.ino
index 6b65082..52c22eb 100644
--- a/printermonitor/printermonitor.ino
+++ b/printermonitor/printermonitor.ino
@@ -1,1152 +1,1151 @@
- /** The MIT License (MIT)
-
-Copyright (c) 2018 David Payne
-Copyright (c) 2018 Florian Schütte
-
-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.
-*/
-
- /**********************************************
- * Edit Settings.h for personalization
- ***********************************************/
-
-#include "Settings.h"
-
-#define VERSION "2.1"
-
-#define HOSTNAME "OctMon-"
-#define CONFIG "/conf.txt"
-
-/* Useful Constants */
-#define SECS_PER_MIN (60UL)
-#define SECS_PER_HOUR (3600UL)
-#define SECS_PER_DAY (SECS_PER_HOUR * 24L)
-
-/* 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_DAY) / SECS_PER_HOUR)
-#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY)
-
-// Initialize the oled display for I2C_DISPLAY_ADDRESS
-// SDA_PIN and SCL_PIN
-#if defined(DISPLAY_SH1106)
- SH1106Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SCL_PIN);
-#else
- SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SCL_PIN); // this is the default
-#endif
-
-OLEDDisplayUi ui( &display );
-
-void drawProgress(OLEDDisplay *display, int percentage, String label);
-void drawOtaProgress(unsigned int, unsigned int);
-void drawScreen1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
-void drawScreen2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
-void drawScreen3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
-void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state);
-void drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
-void drawWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
-void drawClockHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state);
-
-// Set the number of Frames supported
-const int numberOfFrames = 3;
-FrameCallback frames[numberOfFrames];
-FrameCallback clockFrame[2];
-boolean isClockOn = false;
-
-OverlayCallback overlays[] = { drawHeaderOverlay };
-OverlayCallback clockOverlay[] = { drawClockHeaderOverlay };
-int numberOfOverlays = 1;
-
-// Time
-TimeClient timeClient(UtcOffset);
-long lastEpoch = 0;
-long firstEpoch = 0;
-long displayOffEpoch = 0;
-String lastMinute = "xx";
-String lastSecond = "xx";
-String lastReportStatus = "";
-boolean displayOn = true;
-
-// OctoPrint Client
-OctoPrintClient printerClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, OctoAuthUser, OctoAuthPass);
-int printerCount = 0;
-
-// Weather Client
-OpenWeatherMapClient weatherClient(WeatherApiKey, CityIDs, 1, IS_METRIC);
-
-//declairing prototypes
-void configModeCallback (WiFiManager *myWiFiManager);
-int8_t getWifiQuality();
-
-ESP8266WebServer server(WEBSERVER_PORT);
-
-String WEB_ACTIONS = " Home"
- " Configure"
- " Weather"
- " Reset Settings"
- " Forget WiFi"
- " About";
-
-String CHANGE_FORM = "";
-
-String WEATHER_FORM = ""
- "";
-
-String COLOR_THEMES = ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- "";
-
-
-// Change the externalLight to the pin you wish to use if other than the Built-in LED
-int externalLight = LED_BUILTIN; // LED_BUILTIN is is the built in LED on the Wemos
-
-void setup() {
- Serial.begin(115200);
- SPIFFS.begin();
- delay(10);
-
- //New Line to clear from start garbage
- Serial.println();
-
- // Initialize digital pin for LED (little blue light on the Wemos D1 Mini)
- pinMode(externalLight, OUTPUT);
-
- readSettings();
-
- // initialize dispaly
- display.init();
- if (INVERT_DISPLAY) {
- display.flipScreenVertically(); // connections at top of OLED display
- }
- display.clear();
- display.display();
-
- //display.flipScreenVertically();
- display.setFont(ArialMT_Plain_16);
- display.setTextAlignment(TEXT_ALIGN_CENTER);
- display.setContrast(255); // default is 255
- display.drawString(64, 5, "Printer Monitor\nBy Qrome\nV" + String(VERSION));
- display.display();
-
- //WiFiManager
- //Local intialization. Once its business is done, there is no need to keep it around
- WiFiManager wifiManager;
-
- // Uncomment for testing wifi manager
- //wifiManager.resetSettings();
- wifiManager.setAPCallback(configModeCallback);
-
- String hostname(HOSTNAME);
- hostname += String(ESP.getChipId(), HEX);
- if (!wifiManager.autoConnect((const char *)hostname.c_str())) {// new addition
- delay(3000);
- WiFi.disconnect(true);
- ESP.reset();
- delay(5000);
- }
-
- // You can change the transition that is used
- // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN
- ui.setFrameAnimation(SLIDE_LEFT);
- ui.setTargetFPS(30);
- ui.disableAllIndicators();
- ui.setFrames(frames, (numberOfFrames));
- frames[0] = drawScreen1;
- frames[1] = drawScreen2;
- frames[2] = drawScreen3;
- clockFrame[0] = drawClock;
- clockFrame[1] = drawWeather;
- ui.setOverlays(overlays, numberOfOverlays);
-
- // Inital UI takes care of initalising the display too.
- ui.init();
- if (INVERT_DISPLAY) {
- display.flipScreenVertically(); //connections at top of OLED display
- }
-
- // print the received signal strength:
- Serial.print("Signal Strength (RSSI): ");
- Serial.print(getWifiQuality());
- Serial.println("%");
-
- if (ENABLE_OTA) {
- ArduinoOTA.onStart([]() {
- Serial.println("Start");
- });
- ArduinoOTA.onEnd([]() {
- Serial.println("\nEnd");
- });
- ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
- Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
- });
- ArduinoOTA.onError([](ota_error_t error) {
- Serial.printf("Error[%u]: ", error);
- if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
- else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
- else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
- else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
- else if (error == OTA_END_ERROR) Serial.println("End Failed");
- });
- ArduinoOTA.setHostname((const char *)hostname.c_str());
- if (OTA_Password != "") {
- ArduinoOTA.setPassword(((const char *)OTA_Password.c_str()));
- }
- ArduinoOTA.begin();
- }
-
- if (WEBSERVER_ENABLED) {
- server.on("/", displayPrinterStatus);
- server.on("/systemreset", handleSystemReset);
- server.on("/forgetwifi", handleWifiReset);
- server.on("/updateconfig", handleUpdateConfig);
- server.on("/updateweatherconfig", handleUpdateWeather);
- server.on("/configure", handleConfigure);
- server.on("/configureweather", handleWeatherConfigure);
- server.onNotFound(redirectHome);
- // Start the server
- server.begin();
- Serial.println("Server started");
- // Print the IP address
- String webAddress = "http://" + WiFi.localIP().toString() + ":" + String(WEBSERVER_PORT) + "/";
- Serial.println("Use this URL : " + webAddress);
- display.clear();
- display.setTextAlignment(TEXT_ALIGN_CENTER);
- display.setFont(ArialMT_Plain_10);
- display.drawString(64, 10, "Web Interface On");
- display.drawString(64, 20, "You May Connect to IP");
- display.setFont(ArialMT_Plain_16);
- display.drawString(64, 30, WiFi.localIP().toString());
- display.drawString(64, 46, "Port: " + String(WEBSERVER_PORT));
- display.display();
- } else {
- Serial.println("Web Interface is Disabled");
- display.clear();
- display.setTextAlignment(TEXT_ALIGN_CENTER);
- display.setFont(ArialMT_Plain_10);
- display.drawString(64, 10, "Web Interface is Off");
- display.drawString(64, 20, "Enable in Settings.h");
- display.display();
- }
-
- flashLED(5, 500);
- findMDNS(); //go find Octoprint Server by the hostname
-}
-
-void findMDNS() {
- if (OctoPrintHostName == "") {
- return; // nothing to do here
- }
- // We now query our network for 'web servers' service
- // over tcp, and get the number of available devices
- int n = MDNS.queryService("http", "tcp");
- if (n == 0) {
- Serial.println("no services found - make sure OctoPrint server is turned on");
- return;
- }
- Serial.println("*** Looking for " + OctoPrintHostName + " over mDNS");
- for (int i = 0; i < n; ++i) {
- // Going through every available service,
- // we're searching for the one whose hostname
- // matches what we want, and then get its IP
- Serial.println("Found: " + MDNS.hostname(i));
- if (MDNS.hostname(i) == OctoPrintHostName) {
- IPAddress serverIp = MDNS.IP(i);
- OctoPrintServer = serverIp.toString();
- OctoPrintPort = MDNS.port(i); // save the port
- Serial.println("*** Found OctoPrint Server " + OctoPrintHostName + " http://" + OctoPrintServer + ":" + OctoPrintPort);
- writeSettings(); // update the settings
- }
- }
-}
-
-//************************************************************
-// Main Looop
-//************************************************************
-void loop() {
-
- //Get Time Update
- if((getMinutesFromLastRefresh() >= minutesBetweenDataRefresh) || lastEpoch == 0) {
- getUpdateTime();
- }
-
- if (lastMinute != timeClient.getMinutes() && !printerClient.isPrinting()) {
- // Check status every 60 seconds
- digitalWrite(externalLight, LOW);
- lastMinute = timeClient.getMinutes(); // reset the check value
- printerClient.getPrinterJobResults();
- digitalWrite(externalLight, HIGH);
- } else if (printerClient.isPrinting()) {
- if (lastSecond != timeClient.getSeconds() && timeClient.getSeconds().endsWith("0")) {
- lastSecond = timeClient.getSeconds();
- // every 10 seconds while printing get an update
- digitalWrite(externalLight, LOW);
- printerClient.getPrinterJobResults();
- digitalWrite(externalLight, HIGH);
- }
- }
-
- checkDisplay(); // Check to see if the printer is on or offline and change display.
-
- ui.update();
-
- if (WEBSERVER_ENABLED) {
- server.handleClient();
- }
- if (ENABLE_OTA) {
- ArduinoOTA.handle();
- }
-}
-
-void getUpdateTime() {
- digitalWrite(externalLight, LOW); // turn on the LED
- Serial.println();
-
- if (displayOn && DISPLAYWEATHER) {
- Serial.println("Getting Weather Data...");
- weatherClient.updateWeather();
- }
-
- Serial.println("Updating Time...");
- //Update the Time
- timeClient.updateTime();
- lastEpoch = timeClient.getCurrentEpoch();
- Serial.println("Local time: " + timeClient.getAmPmFormattedTime());
-
- digitalWrite(externalLight, HIGH); // turn off the LED
-}
-
-void handleSystemReset() {
- if (!server.authenticate(www_username, www_password)) {
- return server.requestAuthentication();
- }
- Serial.println("Reset System Configuration");
- if (SPIFFS.remove(CONFIG)) {
- redirectHome();
- ESP.restart();
- }
-}
-
-void handleUpdateWeather() {
- if (!server.authenticate(www_username, www_password)) {
- return server.requestAuthentication();
- }
- DISPLAYWEATHER = server.hasArg("isWeatherEnabled");
- WeatherApiKey = server.arg("openWeatherMapApiKey");
- CityIDs[0] = server.arg("city1").toInt();
- IS_METRIC = server.hasArg("metric");
- writeSettings();
- isClockOn = false; // this will force a check for the display
- checkDisplay();
- lastEpoch = 0;
- redirectHome();
-}
-
-void handleUpdateConfig() {
- boolean flipOld = INVERT_DISPLAY;
- if (!server.authenticate(www_username, www_password)) {
- return server.requestAuthentication();
- }
- OctoPrintApiKey = server.arg("octoPrintApiKey");
- OctoPrintHostName = server.arg("octoPrintHostName");
- OctoPrintServer = server.arg("octoPrintAddress");
- OctoPrintPort = server.arg("octoPrintPort").toInt();
- OctoAuthUser = server.arg("octoUser");
- OctoAuthPass = server.arg("octoPass");
- DISPLAYCLOCK = server.hasArg("isClockEnabled");
- IS_24HOUR = server.hasArg("is24hour");
- INVERT_DISPLAY = server.hasArg("invDisp");
- minutesBetweenDataRefresh = server.arg("refresh").toInt();
- themeColor = server.arg("theme");
- UtcOffset = server.arg("utcoffset").toFloat();
- String temp = server.arg("userid");
- temp.toCharArray(www_username, sizeof(temp));
- temp = server.arg("stationpassword");
- temp.toCharArray(www_password, sizeof(temp));
- writeSettings();
- findMDNS();
- printerClient.getPrinterJobResults();
- if (INVERT_DISPLAY != flipOld) {
- ui.init();
- if(INVERT_DISPLAY)
- display.flipScreenVertically();
- ui.update();
- }
- checkDisplay();
- lastEpoch = 0;
- redirectHome();
-}
-
-void handleWifiReset() {
- if (!server.authenticate(www_username, www_password)) {
- return server.requestAuthentication();
- }
- //WiFiManager
- //Local intialization. Once its business is done, there is no need to keep it around
- redirectHome();
- WiFiManager wifiManager;
- wifiManager.resetSettings();
- ESP.restart();
-}
-
-void handleWeatherConfigure() {
- if (!server.authenticate(www_username, www_password)) {
- return server.requestAuthentication();
- }
- digitalWrite(externalLight, LOW);
- String html = "";
-
- server.sendHeader("Cache-Control", "no-cache, no-store");
- server.sendHeader("Pragma", "no-cache");
- server.sendHeader("Expires", "-1");
- server.setContentLength(CONTENT_LENGTH_UNKNOWN);
- server.send(200, "text/html", "");
-
- html = getHeader();
- server.sendContent(html);
-
- String form = WEATHER_FORM;
- String isWeatherChecked = "";
- if (DISPLAYWEATHER) {
- isWeatherChecked = "checked='checked'";
- }
- form.replace("%IS_WEATHER_CHECKED%", isWeatherChecked);
- form.replace("%WEATHERKEY%", WeatherApiKey);
- form.replace("%CITYNAME1%", weatherClient.getCity(0));
- form.replace("%CITY1%", String(CityIDs[0]));
- String checked = "";
- if (IS_METRIC) {
- checked = "checked='checked'";
- }
- form.replace("%METRIC%", checked);
-
- server.sendContent(form);
-
- html = getFooter();
- server.sendContent(html);
- server.sendContent("");
- server.client().stop();
- digitalWrite(externalLight, HIGH);
-}
-
-void handleConfigure() {
- if (!server.authenticate(www_username, www_password)) {
- return server.requestAuthentication();
- }
- digitalWrite(externalLight, LOW);
- String html = "";
-
- server.sendHeader("Cache-Control", "no-cache, no-store");
- server.sendHeader("Pragma", "no-cache");
- server.sendHeader("Expires", "-1");
- server.setContentLength(CONTENT_LENGTH_UNKNOWN);
- server.send(200, "text/html", "");
-
- html = getHeader();
- server.sendContent(html);
-
- String form = CHANGE_FORM;
-
- form.replace("%OCTOKEY%", OctoPrintApiKey);
- form.replace("%OCTOHOST%", OctoPrintHostName);
- form.replace("%OCTOADDRESS%", OctoPrintServer);
- form.replace("%OCTOPORT%", String(OctoPrintPort));
- form.replace("%OCTOUSER%", OctoAuthUser);
- form.replace("%OCTOPASS%", OctoAuthPass);
- String isClockChecked = "";
- if (DISPLAYCLOCK) {
- isClockChecked = "checked='checked'";
- }
- form.replace("%IS_CLOCK_CHECKED%", isClockChecked);
- String is24hourChecked = "";
- if (IS_24HOUR) {
- is24hourChecked = "checked='checked'";
- }
- form.replace("%IS_24HOUR_CHECKED%", is24hourChecked);
- String isInvDisp = "";
- if (INVERT_DISPLAY) {
- isInvDisp = "checked='checked'";
- }
- form.replace("%IS_INVDISP_CHECKED%", isInvDisp);
- String options = "";
- options.replace(">"+String(minutesBetweenDataRefresh)+"<", " selected>"+String(minutesBetweenDataRefresh)+"<");
- form.replace("%OPTIONS%", options);
- String themeOptions = COLOR_THEMES;
- themeOptions.replace(">"+String(themeColor)+"<", " selected>"+String(themeColor)+"<");
- form.replace("%THEME_OPTIONS%", themeOptions);
- form.replace("%UTCOFFSET%", String(UtcOffset));
- form.replace("%USERID%", String(www_username));
- form.replace("%STATIONPASSWORD%", String(www_password));
-
- server.sendContent(form);
-
- html = getFooter();
- server.sendContent(html);
- server.sendContent("");
- server.client().stop();
- digitalWrite(externalLight, HIGH);
-}
-
-void displayMessage(String message) {
- digitalWrite(externalLight, LOW);
-
- server.sendHeader("Cache-Control", "no-cache, no-store");
- server.sendHeader("Pragma", "no-cache");
- server.sendHeader("Expires", "-1");
- server.setContentLength(CONTENT_LENGTH_UNKNOWN);
- server.send(200, "text/html", "");
- String html = getHeader();
- server.sendContent(String(html));
- server.sendContent(String(message));
- html = getFooter();
- server.sendContent(String(html));
- server.sendContent("");
- server.client().stop();
-
- digitalWrite(externalLight, HIGH);
-}
-
-void redirectHome() {
- // Send them back to the Root Directory
- server.sendHeader("Location", String("/"), true);
- server.sendHeader("Cache-Control", "no-cache, no-store");
- server.sendHeader("Pragma", "no-cache");
- server.sendHeader("Expires", "-1");
- server.send(302, "text/plain", "");
- server.client().stop();
-}
-
-String getHeader() {
- return getHeader(false);
-}
-
-String getHeader(boolean refresh) {
- String menu = WEB_ACTIONS;
-
- String html = "";
- html += "Printer Monitor";
- html += "";
- if (refresh) {
- html += "";
- }
- html += "";
- html += "";
- html += "";
- html += "";
- html += "";
- html += "";
- html += "";
- html += "
";
- return html;
-}
-
-String getFooter() {
- int8_t rssi = getWifiQuality();
- Serial.print("Signal Strength (RSSI): ");
- Serial.print(rssi);
- Serial.println("%");
- String html = "
";
- html += "
";
- html += "";
- html += "";
- return html;
-}
-
-void displayPrinterStatus() {
- digitalWrite(externalLight, LOW);
- String html = "";
-
- server.sendHeader("Cache-Control", "no-cache, no-store");
- server.sendHeader("Pragma", "no-cache");
- server.sendHeader("Expires", "-1");
- server.setContentLength(CONTENT_LENGTH_UNKNOWN);
- server.send(200, "text/html", "");
- server.sendContent(String(getHeader(true)));
-
- String displayTime = timeClient.getAmPmHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds() + " " + timeClient.getAmPm();
- if (IS_24HOUR) {
- displayTime = timeClient.getHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds();
- }
-
- html += "Time: " + displayTime + "
";
- html += "
";
- html += "Host Name: " + OctoPrintHostName + "
";
- if (printerClient.getError() != "") {
- html += "Error: " + printerClient.getError() + "
";
- }
- html += "Status: " + printerClient.getState() + "
";
-
- if (printerClient.isPrinting()) {
- html += "File: " + printerClient.getFileName() + "
";
- float fileSize = printerClient.getFileSize().toFloat();
- if (fileSize > 0) {
- fileSize = fileSize / 1024;
- html += "File Size: " + String(fileSize) + "KB
";
- }
- int filamentLength = printerClient.getFilamentLength().toInt();
- if (filamentLength > 0) {
- float fLength = float(filamentLength) / 1000;
- html += "Filament: " + String(fLength) + "m
";
- }
-
- html += "Tool Temperature: " + printerClient.getTempToolActual() + "° C
";
- html += "Bed Temperature: " + printerClient.getTempBedActual() + "° C
";
-
- int val = printerClient.getProgressPrintTimeLeft().toInt();
- int days = elapsedDays(val);
- int hours = numberOfHours(val);
- int minutes = numberOfMinutes(val);
- int seconds = numberOfSeconds(val);
- html += "Est. Print Time Left: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "
";
-
- val = printerClient.getProgressPrintTime().toInt();
- days = elapsedDays(val);
- hours = numberOfHours(val);
- minutes = numberOfMinutes(val);
- seconds = numberOfSeconds(val);
- html += "Printing Time: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "
";
- html += "";
- html += "
" + printerClient.getProgressCompletion() + "%
";
- } else {
- html += "
";
- }
-
- html += "
";
-
- server.sendContent(html); // spit out what we got
- html = "";
-
- if (DISPLAYWEATHER) {
- if (weatherClient.getCity(0) == "") {
- html += "Please Configure Weather API
";
- if (weatherClient.getError() != "") {
- html += "Weather Error: " + weatherClient.getError() + "
";
- }
- } else {
- html += "" + weatherClient.getCity(0) + ", " + weatherClient.getCountry(0) + "
";
- html += "
";
- html += "
";
- html += weatherClient.getHumidity(0) + "% Humidity
";
- html += weatherClient.getWind(0) + "
" + getSpeedSymbol() + " Wind
";
- html += "
";
- html += "
";
- html += weatherClient.getCondition(0) + " (" + weatherClient.getDescription(0) + ")
";
- html += weatherClient.getTempRounded(0) + getTempSymbol(true) + "
";
- html += " Map It!
";
- html += "
";
- }
-
- server.sendContent(html); // spit out what we got
- html = ""; // fresh start
- }
-
- server.sendContent(String(getFooter()));
- server.sendContent("");
- server.client().stop();
- digitalWrite(externalLight, HIGH);
-}
-
-void configModeCallback (WiFiManager *myWiFiManager) {
- Serial.println("Entered config mode");
- Serial.println(WiFi.softAPIP());
-
- display.clear();
- display.setTextAlignment(TEXT_ALIGN_CENTER);
- display.setFont(ArialMT_Plain_10);
- display.drawString(64, 0, "Wifi Manager");
- display.drawString(64, 10, "Please connect to AP");
- display.setFont(ArialMT_Plain_16);
- display.drawString(64, 23, myWiFiManager->getConfigPortalSSID());
- display.setFont(ArialMT_Plain_10);
- display.drawString(64, 42, "To setup Wifi connection");
- display.display();
-
- Serial.println("Wifi Manager");
- Serial.println("Please connect to AP");
- Serial.println(myWiFiManager->getConfigPortalSSID());
- Serial.println("To setup Wifi Configuration");
- flashLED(20, 50);
-}
-
-void flashLED(int number, int delayTime) {
- for (int inx = 0; inx < number; inx++) {
- delay(delayTime);
- digitalWrite(externalLight, LOW);
- delay(delayTime);
- digitalWrite(externalLight, HIGH);
- delay(delayTime);
- }
-}
-
-void drawScreen1(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, "Bed / Tool Temp");
- display->setTextAlignment(TEXT_ALIGN_LEFT);
- display->setFont(ArialMT_Plain_24);
- String bed = printerClient.getValueRounded(printerClient.getTempBedActual());
- String tool = printerClient.getValueRounded(printerClient.getTempToolActual());
- display->drawString(2 + x, 14 + y, bed + "°");
- display->drawString(64 + x, 14 + y, tool + "°");
-}
-
-void 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 days = elapsedDays(val);
- 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 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 days = elapsedDays(val);
- 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 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();
- }
- display->setFont(ArialMT_Plain_16);
- display->drawString(64 + x, 0 + y, OctoPrintHostName);
- display->setFont(ArialMT_Plain_24);
- display->drawString(64 + x, 17 + y, displayTime);
-}
-
-void 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 getTempSymbol() {
- return getTempSymbol(false);
-}
-
-String getTempSymbol(boolean forHTML) {
- String rtnValue = "F";
- if (IS_METRIC) {
- rtnValue = "C";
- }
- if (forHTML) {
- rtnValue = "°" + rtnValue;
- } else {
- rtnValue = "°" + rtnValue;
- }
- return rtnValue;
-}
-
-String getSpeedSymbol() {
- String rtnValue = "mph";
- if (IS_METRIC) {
- rtnValue = "kph";
- }
- return rtnValue;
-}
-
-String zeroPad(int value) {
- String rtnValue = String(value);
- if (value < 10) {
- rtnValue = "0" + rtnValue;
- }
- return rtnValue;
-}
-
-void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
- display->setColor(WHITE);
- display->setFont(ArialMT_Plain_16);
- String displayTime = timeClient.getAmPmHours() + ":" + timeClient.getMinutes();
- if (IS_24HOUR) {
- displayTime = timeClient.getHours() + ":" + timeClient.getMinutes();
- }
- display->setTextAlignment(TEXT_ALIGN_LEFT);
- display->drawString(0, 48, displayTime);
-
- if (!IS_24HOUR) {
- 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);
-
- drawRssi(display);
-}
-
-void drawClockHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
- display->setColor(WHITE);
- display->setFont(ArialMT_Plain_16);
- display->setTextAlignment(TEXT_ALIGN_LEFT);
- if (!IS_24HOUR) {
- display->drawString(0, 48, timeClient.getAmPm());
- display->setTextAlignment(TEXT_ALIGN_CENTER);
- display->drawString(64, 48, "offline");
- } else {
- display->drawString(0,48, "offline");
- }
- display->setTextAlignment(TEXT_ALIGN_LEFT);
- display->drawRect(0, 43, 128, 2);
-
- drawRssi(display);
-}
-
-void drawRssi(OLEDDisplay *display) {
-
-
- int8_t quality = 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);
- }
- }
- }
-}
-
-// converts the dBm to a range between 0 and 100%
-int8_t getWifiQuality() {
- int32_t dbm = WiFi.RSSI();
- if(dbm <= -100) {
- return 0;
- } else if(dbm >= -50) {
- return 100;
- } else {
- return 2 * (dbm + 100);
- }
-}
-
-
-void writeSettings() {
- // Save decoded message to SPIFFS file for playback on power up.
- File f = SPIFFS.open(CONFIG, "w");
- if (!f) {
- Serial.println("File open failed!");
- } else {
- Serial.println("Saving settings now...");
- f.println("UtcOffset=" + String(UtcOffset));
- f.println("octoKey=" + OctoPrintApiKey);
- f.println("octoHost=" + OctoPrintHostName);
- f.println("octoServer=" + OctoPrintServer);
- f.println("octoPort=" + String(OctoPrintPort));
- f.println("octoUser=" + OctoAuthUser);
- f.println("octoPass=" + OctoAuthPass);
- f.println("refreshRate=" + String(minutesBetweenDataRefresh));
- f.println("themeColor=" + themeColor);
- f.println("www_username=" + String(www_username));
- f.println("www_password=" + String(www_password));
- f.println("DISPLAYCLOCK=" + String(DISPLAYCLOCK));
- f.println("is24hour=" + String(IS_24HOUR));
- f.println("invertDisp=" + String(INVERT_DISPLAY));
- f.println("isWeather=" + String(DISPLAYWEATHER));
- f.println("weatherKey=" + WeatherApiKey);
- f.println("CityID=" + String(CityIDs[0]));
- f.println("isMetric=" + String(IS_METRIC));
- }
- f.close();
- readSettings();
- timeClient.setUtcOffset(UtcOffset);
-}
-
-void readSettings() {
- if (SPIFFS.exists(CONFIG) == false) {
- Serial.println("Settings File does not yet exists.");
- writeSettings();
- return;
- }
- File fr = SPIFFS.open(CONFIG, "r");
- String line;
- while(fr.available()) {
- line = fr.readStringUntil('\n');
-
- if (line.indexOf("UtcOffset=") >= 0) {
- UtcOffset = line.substring(line.lastIndexOf("UtcOffset=") + 10).toFloat();
- Serial.println("UtcOffset=" + String(UtcOffset));
- }
- if (line.indexOf("octoKey=") >= 0) {
- OctoPrintApiKey = line.substring(line.lastIndexOf("octoKey=") + 8);
- OctoPrintApiKey.trim();
- Serial.println("OctoPrintApiKey=" + OctoPrintApiKey);
- }
- if (line.indexOf("octoHost=") >= 0) {
- OctoPrintHostName = line.substring(line.lastIndexOf("octoHost=") + 9);
- OctoPrintHostName.trim();
- Serial.println("OctoPrintHostName=" + OctoPrintHostName);
- }
- if (line.indexOf("octoServer=") >= 0) {
- OctoPrintServer = line.substring(line.lastIndexOf("octoServer=") + 11);
- OctoPrintServer.trim();
- Serial.println("OctoPrintServer=" + OctoPrintServer);
- }
- if (line.indexOf("octoPort=") >= 0) {
- OctoPrintPort = line.substring(line.lastIndexOf("octoPort=") + 9).toInt();
- Serial.println("OctoPrintPort=" + String(OctoPrintPort));
- }
- if (line.indexOf("octoUser=") >= 0) {
- OctoAuthUser = line.substring(line.lastIndexOf("octoUser=") + 9);
- OctoAuthUser.trim();
- Serial.println("OctoAuthUser=" + OctoAuthUser);
- }
- if (line.indexOf("octoPass=") >= 0) {
- OctoAuthPass = line.substring(line.lastIndexOf("octoPass=") + 9);
- OctoAuthPass.trim();
- Serial.println("OctoAuthPass=" + OctoAuthPass);
- }
- if (line.indexOf("refreshRate=") >= 0) {
- minutesBetweenDataRefresh = line.substring(line.lastIndexOf("refreshRate=") + 12).toInt();
- Serial.println("minutesBetweenDataRefresh=" + String(minutesBetweenDataRefresh));
- }
- if (line.indexOf("themeColor=") >= 0) {
- themeColor = line.substring(line.lastIndexOf("themeColor=") + 11);
- themeColor.trim();
- Serial.println("themeColor=" + themeColor);
- }
- if (line.indexOf("www_username=") >= 0) {
- String temp = line.substring(line.lastIndexOf("www_username=") + 13);
- temp.trim();
- temp.toCharArray(www_username, sizeof(temp));
- Serial.println("www_username=" + String(www_username));
- }
- if (line.indexOf("www_password=") >= 0) {
- String temp = line.substring(line.lastIndexOf("www_password=") + 13);
- temp.trim();
- temp.toCharArray(www_password, sizeof(temp));
- Serial.println("www_password=" + String(www_password));
- }
- if (line.indexOf("DISPLAYCLOCK=") >= 0) {
- DISPLAYCLOCK = line.substring(line.lastIndexOf("DISPLAYCLOCK=") + 13).toInt();
- Serial.println("DISPLAYCLOCK=" + String(DISPLAYCLOCK));
- }
- if (line.indexOf("is24hour=") >= 0) {
- IS_24HOUR = line.substring(line.lastIndexOf("is24hour=") + 9).toInt();
- Serial.println("IS_24HOUR=" + String(IS_24HOUR));
- }
- if(line.indexOf("invertDisp=") >= 0) {
- INVERT_DISPLAY = line.substring(line.lastIndexOf("invertDisp=") + 11).toInt();
- Serial.println("INVERT_DISPLAY=" + String(INVERT_DISPLAY));
- }
- if (line.indexOf("isWeather=") >= 0) {
- DISPLAYWEATHER = line.substring(line.lastIndexOf("isWeather=") + 10).toInt();
- Serial.println("DISPLAYWEATHER=" + String(DISPLAYWEATHER));
- }
- if (line.indexOf("weatherKey=") >= 0) {
- WeatherApiKey = line.substring(line.lastIndexOf("weatherKey=") + 11);
- WeatherApiKey.trim();
- Serial.println("WeatherApiKey=" + WeatherApiKey);
- }
- if (line.indexOf("CityID=") >= 0) {
- CityIDs[0] = line.substring(line.lastIndexOf("CityID=") + 7).toInt();
- Serial.println("CityID: " + String(CityIDs[0]));
- }
- if (line.indexOf("isMetric=") >= 0) {
- IS_METRIC = line.substring(line.lastIndexOf("isMetric=") + 9).toInt();
- Serial.println("IS_METRIC=" + String(IS_METRIC));
- }
- }
- fr.close();
- printerClient.updateOctoPrintClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, OctoAuthUser, OctoAuthPass);
- weatherClient.updateWeatherApiKey(WeatherApiKey);
- weatherClient.setMetric(IS_METRIC);
- weatherClient.updateCityIdList(CityIDs, 1);
- timeClient.setUtcOffset(UtcOffset);
-}
-
-int getMinutesFromLastRefresh() {
- int minutes = (timeClient.getCurrentEpoch() - lastEpoch) / 60;
- return minutes;
-}
-
-int getMinutesFromLastDisplay() {
- int minutes = (timeClient.getCurrentEpoch() - displayOffEpoch) / 60;
- return minutes;
-}
-
-// Toggle on and off the display if user defined times
-void checkDisplay() {
- if (!displayOn && DISPLAYCLOCK) {
- enableDisplay(true);
- }
- if (displayOn && !(printerClient.isOperational() || printerClient.isPrinting()) && !DISPLAYCLOCK) {
- // Put Display to sleep
- display.clear();
- display.display();
- display.setFont(ArialMT_Plain_16);
- display.setTextAlignment(TEXT_ALIGN_CENTER);
- display.setContrast(255); // default is 255
- display.drawString(64, 5, "Printer Offline\nSleep Mode...");
- display.display();
- delay(5000);
- enableDisplay(false);
- Serial.println("Printer is offline going down to sleep...");
- return;
- } else if (!displayOn && !DISPLAYCLOCK) {
- if (printerClient.isOperational()) {
- // Wake the Screen up
- enableDisplay(true);
- display.clear();
- display.display();
- display.setFont(ArialMT_Plain_16);
- display.setTextAlignment(TEXT_ALIGN_CENTER);
- display.setContrast(255); // default is 255
- display.drawString(64, 5, "Printer Online\nWake up...");
- display.display();
- Serial.println("Printer is online waking up...");
- delay(5000);
- return;
- }
- } else if (DISPLAYCLOCK) {
- if (!printerClient.isOperational() && !isClockOn) {
- Serial.println("Clock Mode is turned on.");
- if (!DISPLAYWEATHER) {
- ui.disableAutoTransition();
- ui.setFrames(clockFrame, 1);
- clockFrame[0] = drawClock;
- } else {
- ui.enableAutoTransition();
- ui.setFrames(clockFrame, 2);
- clockFrame[0] = drawClock;
- clockFrame[1] = drawWeather;
- }
- ui.setOverlays(clockOverlay, numberOfOverlays);
- isClockOn = true;
- } else if (printerClient.isOperational() && isClockOn) {
- Serial.println("Printer Monitor is active.");
- ui.setFrames(frames, numberOfFrames);
- ui.setOverlays(overlays, numberOfOverlays);
- ui.enableAutoTransition();
- isClockOn = false;
- }
- }
-}
-
-void enableDisplay(boolean enable) {
- displayOn = enable;
- if (enable) {
- if (getMinutesFromLastDisplay() >= minutesBetweenDataRefresh) {
- // The display has been off longer than the minutes between refresh -- need to get fresh data
- lastEpoch = 0; // this should force a data pull
- displayOffEpoch = 0; // reset
- }
- display.displayOn();
- Serial.println("Display was turned ON: " + timeClient.getFormattedTime());
- } else {
- display.displayOff();
- Serial.println("Display was turned OFF: " + timeClient.getFormattedTime());
- displayOffEpoch = lastEpoch;
- }
+ /** 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.
+*/
+
+ /**********************************************
+ * Edit Settings.h for personalization
+ ***********************************************/
+
+#include "Settings.h"
+
+#define VERSION "2.1"
+
+#define HOSTNAME "OctMon-"
+#define CONFIG "/conf.txt"
+
+/* Useful Constants */
+#define SECS_PER_MIN (60UL)
+#define SECS_PER_HOUR (3600UL)
+#define SECS_PER_DAY (SECS_PER_HOUR * 24L)
+
+/* 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_DAY) / SECS_PER_HOUR)
+#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY)
+
+// Initialize the oled display for I2C_DISPLAY_ADDRESS
+// SDA_PIN and SCL_PIN
+#if defined(DISPLAY_SH1106)
+ SH1106Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SCL_PIN);
+#else
+ SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SCL_PIN); // this is the default
+#endif
+
+OLEDDisplayUi ui( &display );
+
+void drawProgress(OLEDDisplay *display, int percentage, String label);
+void drawOtaProgress(unsigned int, unsigned int);
+void drawScreen1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
+void drawScreen2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
+void drawScreen3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
+void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state);
+void drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
+void drawWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
+void drawClockHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state);
+
+// Set the number of Frames supported
+const int numberOfFrames = 3;
+FrameCallback frames[numberOfFrames];
+FrameCallback clockFrame[2];
+boolean isClockOn = false;
+
+OverlayCallback overlays[] = { drawHeaderOverlay };
+OverlayCallback clockOverlay[] = { drawClockHeaderOverlay };
+int numberOfOverlays = 1;
+
+// Time
+TimeClient timeClient(UtcOffset);
+long lastEpoch = 0;
+long firstEpoch = 0;
+long displayOffEpoch = 0;
+String lastMinute = "xx";
+String lastSecond = "xx";
+String lastReportStatus = "";
+boolean displayOn = true;
+
+// OctoPrint Client
+OctoPrintClient printerClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, OctoAuthUser, OctoAuthPass);
+int printerCount = 0;
+
+// Weather Client
+OpenWeatherMapClient weatherClient(WeatherApiKey, CityIDs, 1, IS_METRIC);
+
+//declairing prototypes
+void configModeCallback (WiFiManager *myWiFiManager);
+int8_t getWifiQuality();
+
+ESP8266WebServer server(WEBSERVER_PORT);
+
+String WEB_ACTIONS = " Home"
+ " Configure"
+ " Weather"
+ " Reset Settings"
+ " Forget WiFi"
+ " About";
+
+String CHANGE_FORM = "";
+
+String WEATHER_FORM = ""
+ "";
+
+String COLOR_THEMES = ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ "";
+
+
+// Change the externalLight to the pin you wish to use if other than the Built-in LED
+int externalLight = LED_BUILTIN; // LED_BUILTIN is is the built in LED on the Wemos
+
+void setup() {
+ Serial.begin(115200);
+ SPIFFS.begin();
+ delay(10);
+
+ //New Line to clear from start garbage
+ Serial.println();
+
+ // Initialize digital pin for LED (little blue light on the Wemos D1 Mini)
+ pinMode(externalLight, OUTPUT);
+
+ readSettings();
+
+ // initialize dispaly
+ display.init();
+ if (INVERT_DISPLAY) {
+ display.flipScreenVertically(); // connections at top of OLED display
+ }
+ display.clear();
+ display.display();
+
+ //display.flipScreenVertically();
+ display.setFont(ArialMT_Plain_16);
+ display.setTextAlignment(TEXT_ALIGN_CENTER);
+ display.setContrast(255); // default is 255
+ display.drawString(64, 5, "Printer Monitor\nBy Qrome\nV" + String(VERSION));
+ display.display();
+
+ //WiFiManager
+ //Local intialization. Once its business is done, there is no need to keep it around
+ WiFiManager wifiManager;
+
+ // Uncomment for testing wifi manager
+ //wifiManager.resetSettings();
+ wifiManager.setAPCallback(configModeCallback);
+
+ String hostname(HOSTNAME);
+ hostname += String(ESP.getChipId(), HEX);
+ if (!wifiManager.autoConnect((const char *)hostname.c_str())) {// new addition
+ delay(3000);
+ WiFi.disconnect(true);
+ ESP.reset();
+ delay(5000);
+ }
+
+ // You can change the transition that is used
+ // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN
+ ui.setFrameAnimation(SLIDE_LEFT);
+ ui.setTargetFPS(30);
+ ui.disableAllIndicators();
+ ui.setFrames(frames, (numberOfFrames));
+ frames[0] = drawScreen1;
+ frames[1] = drawScreen2;
+ frames[2] = drawScreen3;
+ clockFrame[0] = drawClock;
+ clockFrame[1] = drawWeather;
+ ui.setOverlays(overlays, numberOfOverlays);
+
+ // Inital UI takes care of initalising the display too.
+ ui.init();
+ if (INVERT_DISPLAY) {
+ display.flipScreenVertically(); //connections at top of OLED display
+ }
+
+ // print the received signal strength:
+ Serial.print("Signal Strength (RSSI): ");
+ Serial.print(getWifiQuality());
+ Serial.println("%");
+
+ if (ENABLE_OTA) {
+ ArduinoOTA.onStart([]() {
+ Serial.println("Start");
+ });
+ ArduinoOTA.onEnd([]() {
+ Serial.println("\nEnd");
+ });
+ ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
+ Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
+ });
+ ArduinoOTA.onError([](ota_error_t error) {
+ Serial.printf("Error[%u]: ", error);
+ if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
+ else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
+ else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
+ else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
+ else if (error == OTA_END_ERROR) Serial.println("End Failed");
+ });
+ ArduinoOTA.setHostname((const char *)hostname.c_str());
+ if (OTA_Password != "") {
+ ArduinoOTA.setPassword(((const char *)OTA_Password.c_str()));
+ }
+ ArduinoOTA.begin();
+ }
+
+ if (WEBSERVER_ENABLED) {
+ server.on("/", displayPrinterStatus);
+ server.on("/systemreset", handleSystemReset);
+ server.on("/forgetwifi", handleWifiReset);
+ server.on("/updateconfig", handleUpdateConfig);
+ server.on("/updateweatherconfig", handleUpdateWeather);
+ server.on("/configure", handleConfigure);
+ server.on("/configureweather", handleWeatherConfigure);
+ server.onNotFound(redirectHome);
+ // Start the server
+ server.begin();
+ Serial.println("Server started");
+ // Print the IP address
+ String webAddress = "http://" + WiFi.localIP().toString() + ":" + String(WEBSERVER_PORT) + "/";
+ Serial.println("Use this URL : " + webAddress);
+ display.clear();
+ display.setTextAlignment(TEXT_ALIGN_CENTER);
+ display.setFont(ArialMT_Plain_10);
+ display.drawString(64, 10, "Web Interface On");
+ display.drawString(64, 20, "You May Connect to IP");
+ display.setFont(ArialMT_Plain_16);
+ display.drawString(64, 30, WiFi.localIP().toString());
+ display.drawString(64, 46, "Port: " + String(WEBSERVER_PORT));
+ display.display();
+ } else {
+ Serial.println("Web Interface is Disabled");
+ display.clear();
+ display.setTextAlignment(TEXT_ALIGN_CENTER);
+ display.setFont(ArialMT_Plain_10);
+ display.drawString(64, 10, "Web Interface is Off");
+ display.drawString(64, 20, "Enable in Settings.h");
+ display.display();
+ }
+
+ flashLED(5, 500);
+ findMDNS(); //go find Octoprint Server by the hostname
+}
+
+void findMDNS() {
+ if (OctoPrintHostName == "") {
+ return; // nothing to do here
+ }
+ // We now query our network for 'web servers' service
+ // over tcp, and get the number of available devices
+ int n = MDNS.queryService("http", "tcp");
+ if (n == 0) {
+ Serial.println("no services found - make sure OctoPrint server is turned on");
+ return;
+ }
+ Serial.println("*** Looking for " + OctoPrintHostName + " over mDNS");
+ for (int i = 0; i < n; ++i) {
+ // Going through every available service,
+ // we're searching for the one whose hostname
+ // matches what we want, and then get its IP
+ Serial.println("Found: " + MDNS.hostname(i));
+ if (MDNS.hostname(i) == OctoPrintHostName) {
+ IPAddress serverIp = MDNS.IP(i);
+ OctoPrintServer = serverIp.toString();
+ OctoPrintPort = MDNS.port(i); // save the port
+ Serial.println("*** Found OctoPrint Server " + OctoPrintHostName + " http://" + OctoPrintServer + ":" + OctoPrintPort);
+ writeSettings(); // update the settings
+ }
+ }
+}
+
+//************************************************************
+// Main Looop
+//************************************************************
+void loop() {
+
+ //Get Time Update
+ if((getMinutesFromLastRefresh() >= minutesBetweenDataRefresh) || lastEpoch == 0) {
+ getUpdateTime();
+ }
+
+ if (lastMinute != timeClient.getMinutes() && !printerClient.isPrinting()) {
+ // Check status every 60 seconds
+ digitalWrite(externalLight, LOW);
+ lastMinute = timeClient.getMinutes(); // reset the check value
+ printerClient.getPrinterJobResults();
+ digitalWrite(externalLight, HIGH);
+ } else if (printerClient.isPrinting()) {
+ if (lastSecond != timeClient.getSeconds() && timeClient.getSeconds().endsWith("0")) {
+ lastSecond = timeClient.getSeconds();
+ // every 10 seconds while printing get an update
+ digitalWrite(externalLight, LOW);
+ printerClient.getPrinterJobResults();
+ digitalWrite(externalLight, HIGH);
+ }
+ }
+
+ checkDisplay(); // Check to see if the printer is on or offline and change display.
+
+ ui.update();
+
+ if (WEBSERVER_ENABLED) {
+ server.handleClient();
+ }
+ if (ENABLE_OTA) {
+ ArduinoOTA.handle();
+ }
+}
+
+void getUpdateTime() {
+ digitalWrite(externalLight, LOW); // turn on the LED
+ Serial.println();
+
+ if (displayOn && DISPLAYWEATHER) {
+ Serial.println("Getting Weather Data...");
+ weatherClient.updateWeather();
+ }
+
+ Serial.println("Updating Time...");
+ //Update the Time
+ timeClient.updateTime();
+ lastEpoch = timeClient.getCurrentEpoch();
+ Serial.println("Local time: " + timeClient.getAmPmFormattedTime());
+
+ digitalWrite(externalLight, HIGH); // turn off the LED
+}
+
+void handleSystemReset() {
+ if (!server.authenticate(www_username, www_password)) {
+ return server.requestAuthentication();
+ }
+ Serial.println("Reset System Configuration");
+ if (SPIFFS.remove(CONFIG)) {
+ redirectHome();
+ ESP.restart();
+ }
+}
+
+void handleUpdateWeather() {
+ if (!server.authenticate(www_username, www_password)) {
+ return server.requestAuthentication();
+ }
+ DISPLAYWEATHER = server.hasArg("isWeatherEnabled");
+ WeatherApiKey = server.arg("openWeatherMapApiKey");
+ CityIDs[0] = server.arg("city1").toInt();
+ IS_METRIC = server.hasArg("metric");
+ writeSettings();
+ isClockOn = false; // this will force a check for the display
+ checkDisplay();
+ lastEpoch = 0;
+ redirectHome();
+}
+
+void handleUpdateConfig() {
+ boolean flipOld = INVERT_DISPLAY;
+ if (!server.authenticate(www_username, www_password)) {
+ return server.requestAuthentication();
+ }
+ OctoPrintApiKey = server.arg("octoPrintApiKey");
+ OctoPrintHostName = server.arg("octoPrintHostName");
+ OctoPrintServer = server.arg("octoPrintAddress");
+ OctoPrintPort = server.arg("octoPrintPort").toInt();
+ OctoAuthUser = server.arg("octoUser");
+ OctoAuthPass = server.arg("octoPass");
+ DISPLAYCLOCK = server.hasArg("isClockEnabled");
+ IS_24HOUR = server.hasArg("is24hour");
+ INVERT_DISPLAY = server.hasArg("invDisp");
+ minutesBetweenDataRefresh = server.arg("refresh").toInt();
+ themeColor = server.arg("theme");
+ UtcOffset = server.arg("utcoffset").toFloat();
+ String temp = server.arg("userid");
+ temp.toCharArray(www_username, sizeof(temp));
+ temp = server.arg("stationpassword");
+ temp.toCharArray(www_password, sizeof(temp));
+ writeSettings();
+ findMDNS();
+ printerClient.getPrinterJobResults();
+ if (INVERT_DISPLAY != flipOld) {
+ ui.init();
+ if(INVERT_DISPLAY)
+ display.flipScreenVertically();
+ ui.update();
+ }
+ checkDisplay();
+ lastEpoch = 0;
+ redirectHome();
+}
+
+void handleWifiReset() {
+ if (!server.authenticate(www_username, www_password)) {
+ return server.requestAuthentication();
+ }
+ //WiFiManager
+ //Local intialization. Once its business is done, there is no need to keep it around
+ redirectHome();
+ WiFiManager wifiManager;
+ wifiManager.resetSettings();
+ ESP.restart();
+}
+
+void handleWeatherConfigure() {
+ if (!server.authenticate(www_username, www_password)) {
+ return server.requestAuthentication();
+ }
+ digitalWrite(externalLight, LOW);
+ String html = "";
+
+ server.sendHeader("Cache-Control", "no-cache, no-store");
+ server.sendHeader("Pragma", "no-cache");
+ server.sendHeader("Expires", "-1");
+ server.setContentLength(CONTENT_LENGTH_UNKNOWN);
+ server.send(200, "text/html", "");
+
+ html = getHeader();
+ server.sendContent(html);
+
+ String form = WEATHER_FORM;
+ String isWeatherChecked = "";
+ if (DISPLAYWEATHER) {
+ isWeatherChecked = "checked='checked'";
+ }
+ form.replace("%IS_WEATHER_CHECKED%", isWeatherChecked);
+ form.replace("%WEATHERKEY%", WeatherApiKey);
+ form.replace("%CITYNAME1%", weatherClient.getCity(0));
+ form.replace("%CITY1%", String(CityIDs[0]));
+ String checked = "";
+ if (IS_METRIC) {
+ checked = "checked='checked'";
+ }
+ form.replace("%METRIC%", checked);
+
+ server.sendContent(form);
+
+ html = getFooter();
+ server.sendContent(html);
+ server.sendContent("");
+ server.client().stop();
+ digitalWrite(externalLight, HIGH);
+}
+
+void handleConfigure() {
+ if (!server.authenticate(www_username, www_password)) {
+ return server.requestAuthentication();
+ }
+ digitalWrite(externalLight, LOW);
+ String html = "";
+
+ server.sendHeader("Cache-Control", "no-cache, no-store");
+ server.sendHeader("Pragma", "no-cache");
+ server.sendHeader("Expires", "-1");
+ server.setContentLength(CONTENT_LENGTH_UNKNOWN);
+ server.send(200, "text/html", "");
+
+ html = getHeader();
+ server.sendContent(html);
+
+ String form = CHANGE_FORM;
+
+ form.replace("%OCTOKEY%", OctoPrintApiKey);
+ form.replace("%OCTOHOST%", OctoPrintHostName);
+ form.replace("%OCTOADDRESS%", OctoPrintServer);
+ form.replace("%OCTOPORT%", String(OctoPrintPort));
+ form.replace("%OCTOUSER%", OctoAuthUser);
+ form.replace("%OCTOPASS%", OctoAuthPass);
+ String isClockChecked = "";
+ if (DISPLAYCLOCK) {
+ isClockChecked = "checked='checked'";
+ }
+ form.replace("%IS_CLOCK_CHECKED%", isClockChecked);
+ String is24hourChecked = "";
+ if (IS_24HOUR) {
+ is24hourChecked = "checked='checked'";
+ }
+ form.replace("%IS_24HOUR_CHECKED%", is24hourChecked);
+ String isInvDisp = "";
+ if (INVERT_DISPLAY) {
+ isInvDisp = "checked='checked'";
+ }
+ form.replace("%IS_INVDISP_CHECKED%", isInvDisp);
+ String options = "";
+ options.replace(">"+String(minutesBetweenDataRefresh)+"<", " selected>"+String(minutesBetweenDataRefresh)+"<");
+ form.replace("%OPTIONS%", options);
+ String themeOptions = COLOR_THEMES;
+ themeOptions.replace(">"+String(themeColor)+"<", " selected>"+String(themeColor)+"<");
+ form.replace("%THEME_OPTIONS%", themeOptions);
+ form.replace("%UTCOFFSET%", String(UtcOffset));
+ form.replace("%USERID%", String(www_username));
+ form.replace("%STATIONPASSWORD%", String(www_password));
+
+ server.sendContent(form);
+
+ html = getFooter();
+ server.sendContent(html);
+ server.sendContent("");
+ server.client().stop();
+ digitalWrite(externalLight, HIGH);
+}
+
+void displayMessage(String message) {
+ digitalWrite(externalLight, LOW);
+
+ server.sendHeader("Cache-Control", "no-cache, no-store");
+ server.sendHeader("Pragma", "no-cache");
+ server.sendHeader("Expires", "-1");
+ server.setContentLength(CONTENT_LENGTH_UNKNOWN);
+ server.send(200, "text/html", "");
+ String html = getHeader();
+ server.sendContent(String(html));
+ server.sendContent(String(message));
+ html = getFooter();
+ server.sendContent(String(html));
+ server.sendContent("");
+ server.client().stop();
+
+ digitalWrite(externalLight, HIGH);
+}
+
+void redirectHome() {
+ // Send them back to the Root Directory
+ server.sendHeader("Location", String("/"), true);
+ server.sendHeader("Cache-Control", "no-cache, no-store");
+ server.sendHeader("Pragma", "no-cache");
+ server.sendHeader("Expires", "-1");
+ server.send(302, "text/plain", "");
+ server.client().stop();
+}
+
+String getHeader() {
+ return getHeader(false);
+}
+
+String getHeader(boolean refresh) {
+ String menu = WEB_ACTIONS;
+
+ String html = "";
+ html += "Printer Monitor";
+ html += "";
+ if (refresh) {
+ html += "";
+ }
+ html += "";
+ html += "";
+ html += "";
+ html += "";
+ html += "";
+ html += "";
+ html += "";
+ html += "
";
+ return html;
+}
+
+String getFooter() {
+ int8_t rssi = getWifiQuality();
+ Serial.print("Signal Strength (RSSI): ");
+ Serial.print(rssi);
+ Serial.println("%");
+ String html = "
";
+ html += "
";
+ html += "";
+ html += "";
+ return html;
+}
+
+void displayPrinterStatus() {
+ digitalWrite(externalLight, LOW);
+ String html = "";
+
+ server.sendHeader("Cache-Control", "no-cache, no-store");
+ server.sendHeader("Pragma", "no-cache");
+ server.sendHeader("Expires", "-1");
+ server.setContentLength(CONTENT_LENGTH_UNKNOWN);
+ server.send(200, "text/html", "");
+ server.sendContent(String(getHeader(true)));
+
+ String displayTime = timeClient.getAmPmHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds() + " " + timeClient.getAmPm();
+ if (IS_24HOUR) {
+ displayTime = timeClient.getHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds();
+ }
+
+ html += "Time: " + displayTime + "
";
+ html += "
";
+ html += "Host Name: " + OctoPrintHostName + "
";
+ if (printerClient.getError() != "") {
+ html += "Error: " + printerClient.getError() + "
";
+ }
+ html += "Status: " + printerClient.getState() + "
";
+
+ if (printerClient.isPrinting()) {
+ html += "File: " + printerClient.getFileName() + "
";
+ float fileSize = printerClient.getFileSize().toFloat();
+ if (fileSize > 0) {
+ fileSize = fileSize / 1024;
+ html += "File Size: " + String(fileSize) + "KB
";
+ }
+ int filamentLength = printerClient.getFilamentLength().toInt();
+ if (filamentLength > 0) {
+ float fLength = float(filamentLength) / 1000;
+ html += "Filament: " + String(fLength) + "m
";
+ }
+
+ html += "Tool Temperature: " + printerClient.getTempToolActual() + "° C
";
+ html += "Bed Temperature: " + printerClient.getTempBedActual() + "° C
";
+
+ int val = printerClient.getProgressPrintTimeLeft().toInt();
+ int days = elapsedDays(val);
+ int hours = numberOfHours(val);
+ int minutes = numberOfMinutes(val);
+ int seconds = numberOfSeconds(val);
+ html += "Est. Print Time Left: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "
";
+
+ val = printerClient.getProgressPrintTime().toInt();
+ days = elapsedDays(val);
+ hours = numberOfHours(val);
+ minutes = numberOfMinutes(val);
+ seconds = numberOfSeconds(val);
+ html += "Printing Time: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "
";
+ html += "";
+ html += "
" + printerClient.getProgressCompletion() + "%
";
+ } else {
+ html += "
";
+ }
+
+ html += "
";
+
+ server.sendContent(html); // spit out what we got
+ html = "";
+
+ if (DISPLAYWEATHER) {
+ if (weatherClient.getCity(0) == "") {
+ html += "Please Configure Weather API
";
+ if (weatherClient.getError() != "") {
+ html += "Weather Error: " + weatherClient.getError() + "
";
+ }
+ } else {
+ html += "" + weatherClient.getCity(0) + ", " + weatherClient.getCountry(0) + "
";
+ html += "
";
+ html += "
";
+ html += weatherClient.getHumidity(0) + "% Humidity
";
+ html += weatherClient.getWind(0) + "
" + getSpeedSymbol() + " Wind
";
+ html += "
";
+ html += "
";
+ html += weatherClient.getCondition(0) + " (" + weatherClient.getDescription(0) + ")
";
+ html += weatherClient.getTempRounded(0) + getTempSymbol(true) + "
";
+ html += " Map It!
";
+ html += "
";
+ }
+
+ server.sendContent(html); // spit out what we got
+ html = ""; // fresh start
+ }
+
+ server.sendContent(String(getFooter()));
+ server.sendContent("");
+ server.client().stop();
+ digitalWrite(externalLight, HIGH);
+}
+
+void configModeCallback (WiFiManager *myWiFiManager) {
+ Serial.println("Entered config mode");
+ Serial.println(WiFi.softAPIP());
+
+ display.clear();
+ display.setTextAlignment(TEXT_ALIGN_CENTER);
+ display.setFont(ArialMT_Plain_10);
+ display.drawString(64, 0, "Wifi Manager");
+ display.drawString(64, 10, "Please connect to AP");
+ display.setFont(ArialMT_Plain_16);
+ display.drawString(64, 23, myWiFiManager->getConfigPortalSSID());
+ display.setFont(ArialMT_Plain_10);
+ display.drawString(64, 42, "To setup Wifi connection");
+ display.display();
+
+ Serial.println("Wifi Manager");
+ Serial.println("Please connect to AP");
+ Serial.println(myWiFiManager->getConfigPortalSSID());
+ Serial.println("To setup Wifi Configuration");
+ flashLED(20, 50);
+}
+
+void flashLED(int number, int delayTime) {
+ for (int inx = 0; inx < number; inx++) {
+ delay(delayTime);
+ digitalWrite(externalLight, LOW);
+ delay(delayTime);
+ digitalWrite(externalLight, HIGH);
+ delay(delayTime);
+ }
+}
+
+void drawScreen1(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, "Bed / Tool Temp");
+ display->setTextAlignment(TEXT_ALIGN_LEFT);
+ display->setFont(ArialMT_Plain_24);
+ String bed = printerClient.getValueRounded(printerClient.getTempBedActual());
+ String tool = printerClient.getValueRounded(printerClient.getTempToolActual());
+ display->drawString(2 + x, 14 + y, bed + "°");
+ display->drawString(64 + x, 14 + y, tool + "°");
+}
+
+void 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 days = elapsedDays(val);
+ 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 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 days = elapsedDays(val);
+ 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 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();
+ }
+ display->setFont(ArialMT_Plain_16);
+ display->drawString(64 + x, 0 + y, OctoPrintHostName);
+ display->setFont(ArialMT_Plain_24);
+ display->drawString(64 + x, 17 + y, displayTime);
+}
+
+void 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 getTempSymbol() {
+ return getTempSymbol(false);
+}
+
+String getTempSymbol(boolean forHTML) {
+ String rtnValue = "F";
+ if (IS_METRIC) {
+ rtnValue = "C";
+ }
+ if (forHTML) {
+ rtnValue = "°" + rtnValue;
+ } else {
+ rtnValue = "°" + rtnValue;
+ }
+ return rtnValue;
+}
+
+String getSpeedSymbol() {
+ String rtnValue = "mph";
+ if (IS_METRIC) {
+ rtnValue = "kph";
+ }
+ return rtnValue;
+}
+
+String zeroPad(int value) {
+ String rtnValue = String(value);
+ if (value < 10) {
+ rtnValue = "0" + rtnValue;
+ }
+ return rtnValue;
+}
+
+void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
+ display->setColor(WHITE);
+ display->setFont(ArialMT_Plain_16);
+ String displayTime = timeClient.getAmPmHours() + ":" + timeClient.getMinutes();
+ if (IS_24HOUR) {
+ displayTime = timeClient.getHours() + ":" + timeClient.getMinutes();
+ }
+ display->setTextAlignment(TEXT_ALIGN_LEFT);
+ display->drawString(0, 48, displayTime);
+
+ if (!IS_24HOUR) {
+ 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);
+
+ drawRssi(display);
+}
+
+void drawClockHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
+ display->setColor(WHITE);
+ display->setFont(ArialMT_Plain_16);
+ display->setTextAlignment(TEXT_ALIGN_LEFT);
+ if (!IS_24HOUR) {
+ display->drawString(0, 48, timeClient.getAmPm());
+ display->setTextAlignment(TEXT_ALIGN_CENTER);
+ display->drawString(64, 48, "offline");
+ } else {
+ display->drawString(0,48, "offline");
+ }
+ display->setTextAlignment(TEXT_ALIGN_LEFT);
+ display->drawRect(0, 43, 128, 2);
+
+ drawRssi(display);
+}
+
+void drawRssi(OLEDDisplay *display) {
+
+
+ int8_t quality = 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);
+ }
+ }
+ }
+}
+
+// converts the dBm to a range between 0 and 100%
+int8_t getWifiQuality() {
+ int32_t dbm = WiFi.RSSI();
+ if(dbm <= -100) {
+ return 0;
+ } else if(dbm >= -50) {
+ return 100;
+ } else {
+ return 2 * (dbm + 100);
+ }
+}
+
+
+void writeSettings() {
+ // Save decoded message to SPIFFS file for playback on power up.
+ File f = SPIFFS.open(CONFIG, "w");
+ if (!f) {
+ Serial.println("File open failed!");
+ } else {
+ Serial.println("Saving settings now...");
+ f.println("UtcOffset=" + String(UtcOffset));
+ f.println("octoKey=" + OctoPrintApiKey);
+ f.println("octoHost=" + OctoPrintHostName);
+ f.println("octoServer=" + OctoPrintServer);
+ f.println("octoPort=" + String(OctoPrintPort));
+ f.println("octoUser=" + OctoAuthUser);
+ f.println("octoPass=" + OctoAuthPass);
+ f.println("refreshRate=" + String(minutesBetweenDataRefresh));
+ f.println("themeColor=" + themeColor);
+ f.println("www_username=" + String(www_username));
+ f.println("www_password=" + String(www_password));
+ f.println("DISPLAYCLOCK=" + String(DISPLAYCLOCK));
+ f.println("is24hour=" + String(IS_24HOUR));
+ f.println("invertDisp=" + String(INVERT_DISPLAY));
+ f.println("isWeather=" + String(DISPLAYWEATHER));
+ f.println("weatherKey=" + WeatherApiKey);
+ f.println("CityID=" + String(CityIDs[0]));
+ f.println("isMetric=" + String(IS_METRIC));
+ }
+ f.close();
+ readSettings();
+ timeClient.setUtcOffset(UtcOffset);
+}
+
+void readSettings() {
+ if (SPIFFS.exists(CONFIG) == false) {
+ Serial.println("Settings File does not yet exists.");
+ writeSettings();
+ return;
+ }
+ File fr = SPIFFS.open(CONFIG, "r");
+ String line;
+ while(fr.available()) {
+ line = fr.readStringUntil('\n');
+
+ if (line.indexOf("UtcOffset=") >= 0) {
+ UtcOffset = line.substring(line.lastIndexOf("UtcOffset=") + 10).toFloat();
+ Serial.println("UtcOffset=" + String(UtcOffset));
+ }
+ if (line.indexOf("octoKey=") >= 0) {
+ OctoPrintApiKey = line.substring(line.lastIndexOf("octoKey=") + 8);
+ OctoPrintApiKey.trim();
+ Serial.println("OctoPrintApiKey=" + OctoPrintApiKey);
+ }
+ if (line.indexOf("octoHost=") >= 0) {
+ OctoPrintHostName = line.substring(line.lastIndexOf("octoHost=") + 9);
+ OctoPrintHostName.trim();
+ Serial.println("OctoPrintHostName=" + OctoPrintHostName);
+ }
+ if (line.indexOf("octoServer=") >= 0) {
+ OctoPrintServer = line.substring(line.lastIndexOf("octoServer=") + 11);
+ OctoPrintServer.trim();
+ Serial.println("OctoPrintServer=" + OctoPrintServer);
+ }
+ if (line.indexOf("octoPort=") >= 0) {
+ OctoPrintPort = line.substring(line.lastIndexOf("octoPort=") + 9).toInt();
+ Serial.println("OctoPrintPort=" + String(OctoPrintPort));
+ }
+ if (line.indexOf("octoUser=") >= 0) {
+ OctoAuthUser = line.substring(line.lastIndexOf("octoUser=") + 9);
+ OctoAuthUser.trim();
+ Serial.println("OctoAuthUser=" + OctoAuthUser);
+ }
+ if (line.indexOf("octoPass=") >= 0) {
+ OctoAuthPass = line.substring(line.lastIndexOf("octoPass=") + 9);
+ OctoAuthPass.trim();
+ Serial.println("OctoAuthPass=" + OctoAuthPass);
+ }
+ if (line.indexOf("refreshRate=") >= 0) {
+ minutesBetweenDataRefresh = line.substring(line.lastIndexOf("refreshRate=") + 12).toInt();
+ Serial.println("minutesBetweenDataRefresh=" + String(minutesBetweenDataRefresh));
+ }
+ if (line.indexOf("themeColor=") >= 0) {
+ themeColor = line.substring(line.lastIndexOf("themeColor=") + 11);
+ themeColor.trim();
+ Serial.println("themeColor=" + themeColor);
+ }
+ if (line.indexOf("www_username=") >= 0) {
+ String temp = line.substring(line.lastIndexOf("www_username=") + 13);
+ temp.trim();
+ temp.toCharArray(www_username, sizeof(temp));
+ Serial.println("www_username=" + String(www_username));
+ }
+ if (line.indexOf("www_password=") >= 0) {
+ String temp = line.substring(line.lastIndexOf("www_password=") + 13);
+ temp.trim();
+ temp.toCharArray(www_password, sizeof(temp));
+ Serial.println("www_password=" + String(www_password));
+ }
+ if (line.indexOf("DISPLAYCLOCK=") >= 0) {
+ DISPLAYCLOCK = line.substring(line.lastIndexOf("DISPLAYCLOCK=") + 13).toInt();
+ Serial.println("DISPLAYCLOCK=" + String(DISPLAYCLOCK));
+ }
+ if (line.indexOf("is24hour=") >= 0) {
+ IS_24HOUR = line.substring(line.lastIndexOf("is24hour=") + 9).toInt();
+ Serial.println("IS_24HOUR=" + String(IS_24HOUR));
+ }
+ if(line.indexOf("invertDisp=") >= 0) {
+ INVERT_DISPLAY = line.substring(line.lastIndexOf("invertDisp=") + 11).toInt();
+ Serial.println("INVERT_DISPLAY=" + String(INVERT_DISPLAY));
+ }
+ if (line.indexOf("isWeather=") >= 0) {
+ DISPLAYWEATHER = line.substring(line.lastIndexOf("isWeather=") + 10).toInt();
+ Serial.println("DISPLAYWEATHER=" + String(DISPLAYWEATHER));
+ }
+ if (line.indexOf("weatherKey=") >= 0) {
+ WeatherApiKey = line.substring(line.lastIndexOf("weatherKey=") + 11);
+ WeatherApiKey.trim();
+ Serial.println("WeatherApiKey=" + WeatherApiKey);
+ }
+ if (line.indexOf("CityID=") >= 0) {
+ CityIDs[0] = line.substring(line.lastIndexOf("CityID=") + 7).toInt();
+ Serial.println("CityID: " + String(CityIDs[0]));
+ }
+ if (line.indexOf("isMetric=") >= 0) {
+ IS_METRIC = line.substring(line.lastIndexOf("isMetric=") + 9).toInt();
+ Serial.println("IS_METRIC=" + String(IS_METRIC));
+ }
+ }
+ fr.close();
+ printerClient.updateOctoPrintClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, OctoAuthUser, OctoAuthPass);
+ weatherClient.updateWeatherApiKey(WeatherApiKey);
+ weatherClient.setMetric(IS_METRIC);
+ weatherClient.updateCityIdList(CityIDs, 1);
+ timeClient.setUtcOffset(UtcOffset);
+}
+
+int getMinutesFromLastRefresh() {
+ int minutes = (timeClient.getCurrentEpoch() - lastEpoch) / 60;
+ return minutes;
+}
+
+int getMinutesFromLastDisplay() {
+ int minutes = (timeClient.getCurrentEpoch() - displayOffEpoch) / 60;
+ return minutes;
+}
+
+// Toggle on and off the display if user defined times
+void checkDisplay() {
+ if (!displayOn && DISPLAYCLOCK) {
+ enableDisplay(true);
+ }
+ if (displayOn && !(printerClient.isOperational() || printerClient.isPrinting()) && !DISPLAYCLOCK) {
+ // Put Display to sleep
+ display.clear();
+ display.display();
+ display.setFont(ArialMT_Plain_16);
+ display.setTextAlignment(TEXT_ALIGN_CENTER);
+ display.setContrast(255); // default is 255
+ display.drawString(64, 5, "Printer Offline\nSleep Mode...");
+ display.display();
+ delay(5000);
+ enableDisplay(false);
+ Serial.println("Printer is offline going down to sleep...");
+ return;
+ } else if (!displayOn && !DISPLAYCLOCK) {
+ if (printerClient.isOperational()) {
+ // Wake the Screen up
+ enableDisplay(true);
+ display.clear();
+ display.display();
+ display.setFont(ArialMT_Plain_16);
+ display.setTextAlignment(TEXT_ALIGN_CENTER);
+ display.setContrast(255); // default is 255
+ display.drawString(64, 5, "Printer Online\nWake up...");
+ display.display();
+ Serial.println("Printer is online waking up...");
+ delay(5000);
+ return;
+ }
+ } else if (DISPLAYCLOCK) {
+ if (!printerClient.isOperational() && !isClockOn) {
+ Serial.println("Clock Mode is turned on.");
+ if (!DISPLAYWEATHER) {
+ ui.disableAutoTransition();
+ ui.setFrames(clockFrame, 1);
+ clockFrame[0] = drawClock;
+ } else {
+ ui.enableAutoTransition();
+ ui.setFrames(clockFrame, 2);
+ clockFrame[0] = drawClock;
+ clockFrame[1] = drawWeather;
+ }
+ ui.setOverlays(clockOverlay, numberOfOverlays);
+ isClockOn = true;
+ } else if (printerClient.isOperational() && isClockOn) {
+ Serial.println("Printer Monitor is active.");
+ ui.setFrames(frames, numberOfFrames);
+ ui.setOverlays(overlays, numberOfOverlays);
+ ui.enableAutoTransition();
+ isClockOn = false;
+ }
+ }
+}
+
+void enableDisplay(boolean enable) {
+ displayOn = enable;
+ if (enable) {
+ if (getMinutesFromLastDisplay() >= minutesBetweenDataRefresh) {
+ // The display has been off longer than the minutes between refresh -- need to get fresh data
+ lastEpoch = 0; // this should force a data pull
+ displayOffEpoch = 0; // reset
+ }
+ display.displayOn();
+ Serial.println("Display was turned ON: " + timeClient.getFormattedTime());
+ } else {
+ display.displayOff();
+ Serial.println("Display was turned OFF: " + timeClient.getFormattedTime());
+ displayOffEpoch = lastEpoch;
+ }
}
From 04ed5ae77dc0d0fecfd6e71887713f089e0ec9ed Mon Sep 17 00:00:00 2001
From: Chrome Legion
Date: Thu, 27 Sep 2018 08:07:53 -0700
Subject: [PATCH 6/7] Qrome - updated with ability to turn on or off Basic Auth
for web interface
---
README.md | 3 ++-
printermonitor/Settings.h | 5 +++--
printermonitor/printermonitor.ino | 34 +++++++++++++++++++++++--------
3 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/README.md b/README.md
index 803273b..c751ef5 100644
--- a/README.md
+++ b/README.md
@@ -109,7 +109,8 @@ Please do not feel obligated, but donations and tips are warmly welcomed. I hav
## Contributors
David Payne
-Daniel Eichhorn -- Author of the TimeClient class and OLEDDisplayUi .
+Daniel Eichhorn -- Author of the TimeClient class and OLEDDisplayUi
+Florian Schütte -- added flip display to web interface
Contributing to this software is warmly welcomed. You can do this basically by
forking from master, committing modifications and then making a pulling requests to be reviewed (follow the links above
diff --git a/printermonitor/Settings.h b/printermonitor/Settings.h
index dfa100e..5bf439c 100644
--- a/printermonitor/Settings.h
+++ b/printermonitor/Settings.h
@@ -70,6 +70,7 @@ boolean IS_METRIC = false; // false = Imperial and true = Metric
const int WEBSERVER_PORT = 80; // The port you can access this device on over HTTP
const boolean WEBSERVER_ENABLED = true; // Device will provide a web interface via http://[ip]:[port]/
+boolean IS_BASIC_AUTH = true; // true = require athentication to change configuration settings / false = no auth
char* www_username = "admin"; // User account for the Web Interface
char* www_password = "password"; // Password for the Web Interface
float UtcOffset = -7; // Hour offset from GMT for your timezone
@@ -82,7 +83,7 @@ const int I2C_DISPLAY_ADDRESS = 0x3c; // I2C Address of your Display (usually 0x
const int SDA_PIN = D2;
const int SCL_PIN = D5;
boolean INVERT_DISPLAY = false; // 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
+#define DISPLAY_SH1106 // Uncomment this line to use the SH1106 display -- SSD1306 is used by default and is most common
boolean ENABLE_OTA = true; // this will allow you to load firmware to the device over WiFi (see OTA for ESP8266)
String OTA_Password = ""; // Set an OTA password here -- leave blank if you don't want to be prompted for password
@@ -90,4 +91,4 @@ String OTA_Password = ""; // Set an OTA password here -- leave blank if you
// End Settings
//******************************
-String themeColor = "light-green"; // this can be changed later in the web interface.
+String themeColor = "light-green"; // this can be changed later in the web interface.
diff --git a/printermonitor/printermonitor.ino b/printermonitor/printermonitor.ino
index f827286..e3685cb 100644
--- a/printermonitor/printermonitor.ino
+++ b/printermonitor/printermonitor.ino
@@ -112,10 +112,11 @@ String CHANGE_FORM = "";
@@ -374,8 +375,15 @@ void getUpdateTime() {
digitalWrite(externalLight, HIGH); // turn off the LED
}
+boolean authentication() {
+ if (IS_BASIC_AUTH && (strlen(www_username) >= 1 && strlen(www_password) >= 1)) {
+ return server.authenticate(www_username, www_password);
+ }
+ return true; // Authentication not required
+}
+
void handleSystemReset() {
- if (!server.authenticate(www_username, www_password)) {
+ if (!authentication()) {
return server.requestAuthentication();
}
Serial.println("Reset System Configuration");
@@ -386,7 +394,7 @@ void handleSystemReset() {
}
void handleUpdateWeather() {
- if (!server.authenticate(www_username, www_password)) {
+ if (!authentication()) {
return server.requestAuthentication();
}
DISPLAYWEATHER = server.hasArg("isWeatherEnabled");
@@ -402,7 +410,7 @@ void handleUpdateWeather() {
void handleUpdateConfig() {
boolean flipOld = INVERT_DISPLAY;
- if (!server.authenticate(www_username, www_password)) {
+ if (!authentication()) {
return server.requestAuthentication();
}
OctoPrintApiKey = server.arg("octoPrintApiKey");
@@ -436,7 +444,7 @@ void handleUpdateConfig() {
}
void handleWifiReset() {
- if (!server.authenticate(www_username, www_password)) {
+ if (!authentication()) {
return server.requestAuthentication();
}
//WiFiManager
@@ -448,7 +456,7 @@ void handleWifiReset() {
}
void handleWeatherConfigure() {
- if (!server.authenticate(www_username, www_password)) {
+ if (!authentication()) {
return server.requestAuthentication();
}
digitalWrite(externalLight, LOW);
@@ -488,7 +496,7 @@ void handleWeatherConfigure() {
}
void handleConfigure() {
- if (!server.authenticate(www_username, www_password)) {
+ if (!authentication()) {
return server.requestAuthentication();
}
digitalWrite(externalLight, LOW);
@@ -533,6 +541,11 @@ void handleConfigure() {
themeOptions.replace(">"+String(themeColor)+"<", " selected>"+String(themeColor)+"<");
form.replace("%THEME_OPTIONS%", themeOptions);
form.replace("%UTCOFFSET%", String(UtcOffset));
+ String isUseSecurityChecked = "";
+ if (IS_BASIC_AUTH) {
+ isUseSecurityChecked = "checked='checked'";
+ }
+ form.replace("%IS_BASICAUTH_CHECKED%", isUseSecurityChecked);
form.replace("%USERID%", String(www_username));
form.replace("%STATIONPASSWORD%", String(www_password));
@@ -947,6 +960,7 @@ void writeSettings() {
f.println("octoPass=" + OctoAuthPass);
f.println("refreshRate=" + String(minutesBetweenDataRefresh));
f.println("themeColor=" + themeColor);
+ f.println("IS_BASIC_AUTH=" + String(IS_BASIC_AUTH));
f.println("www_username=" + String(www_username));
f.println("www_password=" + String(www_password));
f.println("DISPLAYCLOCK=" + String(DISPLAYCLOCK));
@@ -1015,6 +1029,10 @@ void readSettings() {
themeColor.trim();
Serial.println("themeColor=" + themeColor);
}
+ if (line.indexOf("IS_BASIC_AUTH=") >= 0) {
+ IS_BASIC_AUTH = line.substring(line.lastIndexOf("IS_BASIC_AUTH=") + 14).toInt();
+ Serial.println("IS_BASIC_AUTH=" + String(IS_BASIC_AUTH));
+ }
if (line.indexOf("www_username=") >= 0) {
String temp = line.substring(line.lastIndexOf("www_username=") + 13);
temp.trim();
@@ -1148,4 +1166,4 @@ void enableDisplay(boolean enable) {
Serial.println("Display was turned OFF: " + timeClient.getFormattedTime());
displayOffEpoch = lastEpoch;
}
-}
+}
From 2277c8805f981f15f80e6c211ea33dd22f0c4c9b Mon Sep 17 00:00:00 2001
From: Chrome Legion
Date: Sun, 25 Nov 2018 17:02:37 -0700
Subject: [PATCH 7/7] Qrome - fixed bug where ENABLE_OTA = false and crash on
MDNS call
---
printermonitor/printermonitor.ino | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/printermonitor/printermonitor.ino b/printermonitor/printermonitor.ino
index e3685cb..1f662f9 100644
--- a/printermonitor/printermonitor.ino
+++ b/printermonitor/printermonitor.ino
@@ -287,13 +287,13 @@ void setup() {
display.drawString(64, 20, "Enable in Settings.h");
display.display();
}
-
flashLED(5, 500);
findMDNS(); //go find Octoprint Server by the hostname
+ Serial.println("*** Leaving setup()");
}
void findMDNS() {
- if (OctoPrintHostName == "") {
+ if (OctoPrintHostName == "" || ENABLE_OTA == false) {
return; // nothing to do here
}
// We now query our network for 'web servers' service