Merge pull request #64 from Qrome/2.3

2.3
pull/69/head V2.3
Qrome 2018-12-15 09:42:44 -07:00 committed by GitHub
commit a6154ba2fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 77 additions and 19 deletions

View File

@ -39,7 +39,8 @@ SOFTWARE.
* Sample rate is every 10 seconds when printing * Sample rate is every 10 seconds when printing
* Fully configurable from the web interface (not required to update Settings.h) * Fully configurable from the web interface (not required to update Settings.h)
* Supports OTA (loading firmware over WiFi connection on same LAN) * Supports OTA (loading firmware over WiFi connection on same LAN)
* Basic Athentication to protect your settings * Basic Authentication to protect your settings
* Version 2.2 added the ability to update firmware through web interface from a compiled binary
* Video: https://youtu.be/niRv9SCgAPk * Video: https://youtu.be/niRv9SCgAPk
* Detailed build video by Chris Riley: https://youtu.be/Rm-l1FSuJpI * Detailed build video by Chris Riley: https://youtu.be/Rm-l1FSuJpI
@ -62,6 +63,11 @@ GND -> GND-
https://www.thingiverse.com/thing:2884823 -- for the 0.96" OLED Display https://www.thingiverse.com/thing:2884823 -- for the 0.96" OLED Display
https://www.thingiverse.com/thing:2934049 -- for the 1.3" OLED Display https://www.thingiverse.com/thing:2934049 -- for the 1.3" OLED Display
## Upgrading from version 2.2 or Higher
Version 2.2 introduced the ability to upgrade pre-compiled firmware from a binary file. In version 2.3 and on you should find binary files that can be uploaded to your printer monitor via the web interface. From the main menu in the web interface select "Firmware Update" and follow the prompts.
* **printermonitor.ino.d1_mini_SSD1306.bin** - compiled for Wemos D1 Mini for the smaller 0.96" SSD1306 OLED (default)
* **printermonitor.ino.d1_mini_SH1106.bin** - compiled for Wemos D1 Mini for the larger 1.3" SH1106 OLED
## Compiling and Loading to Wemos D1 Mini ## Compiling and Loading to Wemos D1 Mini
It is recommended to use Arduino IDE. You will need to configure Arduino IDE to work with the Wemos board and USB port and installed the required USB drivers etc. It is recommended to use Arduino IDE. You will need to configure Arduino IDE to work with the Wemos board and USB port and installed the required USB drivers etc.
* USB CH340G drivers: https://wiki.wemos.cc/downloads * USB CH340G drivers: https://wiki.wemos.cc/downloads

Binary file not shown.

Binary file not shown.

View File

@ -23,8 +23,9 @@ SOFTWARE.
#include "OpenWeatherMapClient.h" #include "OpenWeatherMapClient.h"
OpenWeatherMapClient::OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric) { OpenWeatherMapClient::OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric, String language) {
updateCityIdList(CityIDs, cityCount); updateCityIdList(CityIDs, cityCount);
updateLanguage(language);
myApiKey = ApiKey; myApiKey = ApiKey;
setMetric(isMetric); setMetric(isMetric);
} }
@ -33,9 +34,16 @@ void OpenWeatherMapClient::updateWeatherApiKey(String ApiKey) {
myApiKey = ApiKey; myApiKey = ApiKey;
} }
void OpenWeatherMapClient::updateLanguage(String language) {
lang = language;
if (lang == "") {
lang = "en";
}
}
void OpenWeatherMapClient::updateWeather() { void OpenWeatherMapClient::updateWeather() {
WiFiClient weatherClient; WiFiClient weatherClient;
String apiGetData = "GET /data/2.5/group?id=" + myCityIDs + "&units=" + units + "&cnt=1&APPID=" + myApiKey + " HTTP/1.1"; String apiGetData = "GET /data/2.5/group?id=" + myCityIDs + "&units=" + units + "&cnt=1&APPID=" + myApiKey + "&lang=" + lang + " HTTP/1.1";
Serial.println("Getting Weather Data"); Serial.println("Getting Weather Data");
Serial.println(apiGetData); Serial.println(apiGetData);

View File

@ -31,6 +31,7 @@ private:
String myCityIDs = ""; String myCityIDs = "";
String myApiKey = ""; String myApiKey = "";
String units = ""; String units = "";
String lang = "";
const char* servername = "api.openweathermap.org"; // remote server we will connect to const char* servername = "api.openweathermap.org"; // remote server we will connect to
String result; String result;
@ -57,10 +58,11 @@ private:
String roundValue(String value); String roundValue(String value);
public: public:
OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric); OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric, String language);
void updateWeather(); void updateWeather();
void updateWeatherApiKey(String ApiKey); void updateWeatherApiKey(String ApiKey);
void updateCityIdList(int CityIDs[], int cityCount); void updateCityIdList(int CityIDs[], int cityCount);
void updateLanguage(String language);
void setMetric(boolean isMetric); void setMetric(boolean isMetric);
String getWeatherResults(); String getWeatherResults();

View File

@ -68,6 +68,8 @@ String WeatherApiKey = ""; // Your API Key from http://openweathermap.org/
// Default City Location (use http://openweathermap.org/find to find city ID) // Default City Location (use http://openweathermap.org/find to find city ID)
int CityIDs[] = { 5304391 }; //Only USE ONE for weather marquee int CityIDs[] = { 5304391 }; //Only USE ONE for weather marquee
boolean IS_METRIC = false; // false = Imperial and true = Metric boolean IS_METRIC = false; // false = Imperial and true = Metric
// Languages: ar, bg, ca, cz, de, el, en, fa, fi, fr, gl, hr, hu, it, ja, kr, la, lt, mk, nl, pl, pt, ro, ru, se, sk, sl, es, tr, ua, vi, zh_cn, zh_tw
String WeatherLanguage = "en"; //Default (en) English
const int WEBSERVER_PORT = 80; // The port you can access this device on over HTTP 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]/ const boolean WEBSERVER_ENABLED = true; // Device will provide a web interface via http://[ip]:[port]/
@ -86,6 +88,9 @@ const int SCL_PIN = D5;
boolean INVERT_DISPLAY = false; // true = pins at top | false = pins at the bottom 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
// LED Settings
const int externalLight = LED_BUILTIN; // Set to unused pin, like D1, to disable use of built-in LED (LED_BUILTIN)
boolean ENABLE_OTA = true; // this will allow you to load firmware to the device over WiFi (see OTA for ESP8266) 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 String OTA_Password = ""; // Set an OTA password here -- leave blank if you don't want to be prompted for password
//****************************** //******************************

View File

@ -148,5 +148,5 @@ long TimeClient::getCurrentEpoch() {
} }
long TimeClient::getCurrentEpochWithUtcOffset() { long TimeClient::getCurrentEpochWithUtcOffset() {
return round(getCurrentEpoch() + 3600 * myUtcOffset + 86400L) % 86400L; return (long)round(getCurrentEpoch() + 3600 * myUtcOffset + 86400L) % 86400L;
} }

View File

@ -27,7 +27,7 @@ SOFTWARE.
#include "Settings.h" #include "Settings.h"
#define VERSION "2.2" #define VERSION "2.3"
#define HOSTNAME "OctMon-" #define HOSTNAME "OctMon-"
#define CONFIG "/conf.txt" #define CONFIG "/conf.txt"
@ -35,13 +35,11 @@ SOFTWARE.
/* Useful Constants */ /* Useful Constants */
#define SECS_PER_MIN (60UL) #define SECS_PER_MIN (60UL)
#define SECS_PER_HOUR (3600UL) #define SECS_PER_HOUR (3600UL)
#define SECS_PER_DAY (SECS_PER_HOUR * 24L)
/* Useful Macros for getting elapsed time */ /* Useful Macros for getting elapsed time */
#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN) #define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)
#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN) #define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN)
#define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR) #define numberOfHours(_time_) (_time_ / SECS_PER_HOUR)
#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY)
// Initialize the oled display for I2C_DISPLAY_ADDRESS // Initialize the oled display for I2C_DISPLAY_ADDRESS
// SDA_PIN and SCL_PIN // SDA_PIN and SCL_PIN
@ -88,7 +86,7 @@ OctoPrintClient printerClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, O
int printerCount = 0; int printerCount = 0;
// Weather Client // Weather Client
OpenWeatherMapClient weatherClient(WeatherApiKey, CityIDs, 1, IS_METRIC); OpenWeatherMapClient weatherClient(WeatherApiKey, CityIDs, 1, IS_METRIC, WeatherLanguage);
//declairing prototypes //declairing prototypes
void configModeCallback (WiFiManager *myWiFiManager); void configModeCallback (WiFiManager *myWiFiManager);
@ -131,9 +129,44 @@ String WEATHER_FORM = "<form class='w3-container' action='/updateweatherconfig'
"or full <a href='http://openweathermap.org/help/city_list.txt' target='_BLANK'>city list</a></label>" "or full <a href='http://openweathermap.org/help/city_list.txt' target='_BLANK'>city list</a></label>"
"<input class='w3-input w3-border w3-margin-bottom' type='text' name='city1' value='%CITY1%' onkeypress='return isNumberKey(event)'></p>" "<input class='w3-input w3-border w3-margin-bottom' type='text' name='city1' value='%CITY1%' onkeypress='return isNumberKey(event)'></p>"
"<p><input name='metric' class='w3-check w3-margin-top' type='checkbox' %METRIC%> Use Metric (Celsius)</p>" "<p><input name='metric' class='w3-check w3-margin-top' type='checkbox' %METRIC%> Use Metric (Celsius)</p>"
"<p>Weather Language <select class='w3-option w3-padding' name='language'>%LANGUAGEOPTIONS%</select></p>"
"<button class='w3-button w3-block w3-grey w3-section w3-padding' type='submit'>Save</button></form>" "<button class='w3-button w3-block w3-grey w3-section w3-padding' type='submit'>Save</button></form>"
"<script>function isNumberKey(e){var h=e.which?e.which:event.keyCode;return!(h>31&&(h<48||h>57))}</script>"; "<script>function isNumberKey(e){var h=e.which?e.which:event.keyCode;return!(h>31&&(h<48||h>57))}</script>";
String LANG_OPTIONS = "<option>ar</option>"
"<option>bg</option>"
"<option>ca</option>"
"<option>cz</option>"
"<option>de</option>"
"<option>el</option>"
"<option>en</option>"
"<option>fa</option>"
"<option>fi</option>"
"<option>fr</option>"
"<option>gl</option>"
"<option>hr</option>"
"<option>hu</option>"
"<option>it</option>"
"<option>ja</option>"
"<option>kr</option>"
"<option>la</option>"
"<option>lt</option>"
"<option>mk</option>"
"<option>nl</option>"
"<option>pl</option>"
"<option>pt</option>"
"<option>ro</option>"
"<option>ru</option>"
"<option>se</option>"
"<option>sk</option>"
"<option>sl</option>"
"<option>es</option>"
"<option>tr</option>"
"<option>ua</option>"
"<option>vi</option>"
"<option>zh_cn</option>"
"<option>zh_tw</option>";
String COLOR_THEMES = "<option>red</option>" String COLOR_THEMES = "<option>red</option>"
"<option>pink</option>" "<option>pink</option>"
"<option>purple</option>" "<option>purple</option>"
@ -159,9 +192,6 @@ String COLOR_THEMES = "<option>red</option>"
"<option>w3schools</option>"; "<option>w3schools</option>";
// 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() { void setup() {
Serial.begin(115200); Serial.begin(115200);
SPIFFS.begin(); SPIFFS.begin();
@ -404,6 +434,7 @@ void handleUpdateWeather() {
WeatherApiKey = server.arg("openWeatherMapApiKey"); WeatherApiKey = server.arg("openWeatherMapApiKey");
CityIDs[0] = server.arg("city1").toInt(); CityIDs[0] = server.arg("city1").toInt();
IS_METRIC = server.hasArg("metric"); IS_METRIC = server.hasArg("metric");
WeatherLanguage = server.arg("language");
writeSettings(); writeSettings();
isClockOn = false; // this will force a check for the display isClockOn = false; // this will force a check for the display
checkDisplay(); checkDisplay();
@ -488,7 +519,9 @@ void handleWeatherConfigure() {
checked = "checked='checked'"; checked = "checked='checked'";
} }
form.replace("%METRIC%", checked); form.replace("%METRIC%", checked);
String options = LANG_OPTIONS;
options.replace(">"+String(WeatherLanguage)+"<", " selected>"+String(WeatherLanguage)+"<");
form.replace("%LANGUAGEOPTIONS%", options);
server.sendContent(form); server.sendContent(form);
html = getFooter(); html = getFooter();
@ -599,6 +632,7 @@ String getHeader(boolean refresh) {
String html = "<!DOCTYPE HTML>"; String html = "<!DOCTYPE HTML>";
html += "<html><head><title>Printer Monitor</title><link rel='icon' href='data:;base64,='>"; html += "<html><head><title>Printer Monitor</title><link rel='icon' href='data:;base64,='>";
html += "<meta charset='UTF-8'>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1'>"; html += "<meta name='viewport' content='width=device-width, initial-scale=1'>";
if (refresh) { if (refresh) {
html += "<meta http-equiv=\"refresh\" content=\"30\">"; html += "<meta http-equiv=\"refresh\" content=\"30\">";
@ -682,14 +716,12 @@ void displayPrinterStatus() {
html += "Bed Temperature: " + printerClient.getTempBedActual() + "&#176; C<br>"; html += "Bed Temperature: " + printerClient.getTempBedActual() + "&#176; C<br>";
int val = printerClient.getProgressPrintTimeLeft().toInt(); int val = printerClient.getProgressPrintTimeLeft().toInt();
int days = elapsedDays(val);
int hours = numberOfHours(val); int hours = numberOfHours(val);
int minutes = numberOfMinutes(val); int minutes = numberOfMinutes(val);
int seconds = numberOfSeconds(val); int seconds = numberOfSeconds(val);
html += "Est. Print Time Left: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "<br>"; html += "Est. Print Time Left: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "<br>";
val = printerClient.getProgressPrintTime().toInt(); val = printerClient.getProgressPrintTime().toInt();
days = elapsedDays(val);
hours = numberOfHours(val); hours = numberOfHours(val);
minutes = numberOfMinutes(val); minutes = numberOfMinutes(val);
seconds = numberOfSeconds(val); seconds = numberOfSeconds(val);
@ -787,7 +819,6 @@ void drawScreen2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int
//display->setTextAlignment(TEXT_ALIGN_LEFT); //display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_24); display->setFont(ArialMT_Plain_24);
int val = printerClient.getProgressPrintTimeLeft().toInt(); int val = printerClient.getProgressPrintTimeLeft().toInt();
int days = elapsedDays(val);
int hours = numberOfHours(val); int hours = numberOfHours(val);
int minutes = numberOfMinutes(val); int minutes = numberOfMinutes(val);
int seconds = numberOfSeconds(val); int seconds = numberOfSeconds(val);
@ -804,7 +835,6 @@ void drawScreen3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int
//display->setTextAlignment(TEXT_ALIGN_LEFT); //display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_24); display->setFont(ArialMT_Plain_24);
int val = printerClient.getProgressPrintTime().toInt(); int val = printerClient.getProgressPrintTime().toInt();
int days = elapsedDays(val);
int hours = numberOfHours(val); int hours = numberOfHours(val);
int minutes = numberOfMinutes(val); int minutes = numberOfMinutes(val);
int seconds = numberOfSeconds(val); int seconds = numberOfSeconds(val);
@ -973,6 +1003,7 @@ void writeSettings() {
f.println("weatherKey=" + WeatherApiKey); f.println("weatherKey=" + WeatherApiKey);
f.println("CityID=" + String(CityIDs[0])); f.println("CityID=" + String(CityIDs[0]));
f.println("isMetric=" + String(IS_METRIC)); f.println("isMetric=" + String(IS_METRIC));
f.println("language=" + String(WeatherLanguage));
} }
f.close(); f.close();
readSettings(); readSettings();
@ -1077,10 +1108,16 @@ void readSettings() {
IS_METRIC = line.substring(line.lastIndexOf("isMetric=") + 9).toInt(); IS_METRIC = line.substring(line.lastIndexOf("isMetric=") + 9).toInt();
Serial.println("IS_METRIC=" + String(IS_METRIC)); Serial.println("IS_METRIC=" + String(IS_METRIC));
} }
if (line.indexOf("language=") >= 0) {
WeatherLanguage = line.substring(line.lastIndexOf("language=") + 9);
WeatherLanguage.trim();
Serial.println("WeatherLanguage=" + WeatherLanguage);
}
} }
fr.close(); fr.close();
printerClient.updateOctoPrintClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, OctoAuthUser, OctoAuthPass); printerClient.updateOctoPrintClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, OctoAuthUser, OctoAuthPass);
weatherClient.updateWeatherApiKey(WeatherApiKey); weatherClient.updateWeatherApiKey(WeatherApiKey);
weatherClient.updateLanguage(WeatherLanguage);
weatherClient.setMetric(IS_METRIC); weatherClient.setMetric(IS_METRIC);
weatherClient.updateCityIdList(CityIDs, 1); weatherClient.updateCityIdList(CityIDs, 1);
timeClient.setUtcOffset(UtcOffset); timeClient.setUtcOffset(UtcOffset);