Qrome - Added Weather display and some cleanup
parent
b1fa89a492
commit
f0562880e8
|
|
@ -0,0 +1,303 @@
|
||||||
|
/** 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "OpenWeatherMapClient.h"
|
||||||
|
|
||||||
|
OpenWeatherMapClient::OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric) {
|
||||||
|
updateCityIdList(CityIDs, cityCount);
|
||||||
|
myApiKey = ApiKey;
|
||||||
|
setMetric(isMetric);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenWeatherMapClient::updateWeatherApiKey(String ApiKey) {
|
||||||
|
myApiKey = ApiKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenWeatherMapClient::updateWeather() {
|
||||||
|
WiFiClient weatherClient;
|
||||||
|
String apiGetData = "GET /data/2.5/group?id=" + myCityIDs + "&units=" + units + "&cnt=1&APPID=" + myApiKey + " HTTP/1.1";
|
||||||
|
|
||||||
|
Serial.println("Getting Weather Data");
|
||||||
|
Serial.println(apiGetData);
|
||||||
|
result = "";
|
||||||
|
if (weatherClient.connect(servername, 80)) { //starts client connection, checks for connection
|
||||||
|
weatherClient.println(apiGetData);
|
||||||
|
weatherClient.println("Host: " + String(servername));
|
||||||
|
weatherClient.println("User-Agent: ArduinoWiFi/1.1");
|
||||||
|
weatherClient.println("Connection: close");
|
||||||
|
weatherClient.println();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Serial.println("connection for weather data failed"); //error message if no client connect
|
||||||
|
Serial.println();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(weatherClient.connected() && !weatherClient.available()) delay(1); //waits for data
|
||||||
|
|
||||||
|
Serial.println("Waiting for data");
|
||||||
|
|
||||||
|
// Check HTTP status
|
||||||
|
char status[32] = {0};
|
||||||
|
weatherClient.readBytesUntil('\r', status, sizeof(status));
|
||||||
|
Serial.println("Response Header: " + String(status));
|
||||||
|
if (strcmp(status, "HTTP/1.1 200 OK") != 0) {
|
||||||
|
Serial.print(F("Unexpected response: "));
|
||||||
|
Serial.println(status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip HTTP headers
|
||||||
|
char endOfHeaders[] = "\r\n\r\n";
|
||||||
|
if (!weatherClient.find(endOfHeaders)) {
|
||||||
|
Serial.println(F("Invalid response"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t bufferSize = 710;
|
||||||
|
DynamicJsonBuffer jsonBuffer(bufferSize);
|
||||||
|
|
||||||
|
weathers[0].cached = false;
|
||||||
|
weathers[0].error = "";
|
||||||
|
// Parse JSON object
|
||||||
|
JsonObject& root = jsonBuffer.parseObject(weatherClient);
|
||||||
|
if (!root.success()) {
|
||||||
|
Serial.println(F("Weather Data Parsing failed!"));
|
||||||
|
weathers[0].error = "Weather Data Parsing failed!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
weatherClient.stop(); //stop client
|
||||||
|
|
||||||
|
if (root.measureLength() <= 150) {
|
||||||
|
Serial.println("Error Does not look like we got the data. Size: " + String(root.measureLength()));
|
||||||
|
weathers[0].cached = true;
|
||||||
|
weathers[0].error = (const char*)root["message"];
|
||||||
|
Serial.println("Error: " + weathers[0].error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int count = root["cnt"];
|
||||||
|
|
||||||
|
for (int inx = 0; inx < count; inx++) {
|
||||||
|
weathers[inx].lat = (const char*)root["list"][inx]["coord"]["lat"];
|
||||||
|
weathers[inx].lon = (const char*)root["list"][inx]["coord"]["lon"];
|
||||||
|
weathers[inx].dt = (const char*)root["list"][inx]["dt"];
|
||||||
|
weathers[inx].city = (const char*)root["list"][inx]["name"];
|
||||||
|
weathers[inx].country = (const char*)root["list"][inx]["sys"]["country"];
|
||||||
|
weathers[inx].temp = (const char*)root["list"][inx]["main"]["temp"];
|
||||||
|
weathers[inx].humidity = (const char*)root["list"][inx]["main"]["humidity"];
|
||||||
|
weathers[inx].condition = (const char*)root["list"][inx]["weather"][0]["main"];
|
||||||
|
weathers[inx].wind = (const char*)root["list"][inx]["wind"]["speed"];
|
||||||
|
weathers[inx].weatherId = (const char*)root["list"][inx]["weather"][0]["id"];
|
||||||
|
weathers[inx].description = (const char*)root["list"][inx]["weather"][0]["description"];
|
||||||
|
weathers[inx].icon = (const char*)root["list"][inx]["weather"][0]["icon"];
|
||||||
|
|
||||||
|
Serial.println("lat: " + weathers[inx].lat);
|
||||||
|
Serial.println("lon: " + weathers[inx].lon);
|
||||||
|
Serial.println("dt: " + weathers[inx].dt);
|
||||||
|
Serial.println("city: " + weathers[inx].city);
|
||||||
|
Serial.println("country: " + weathers[inx].country);
|
||||||
|
Serial.println("temp: " + weathers[inx].temp);
|
||||||
|
Serial.println("humidity: " + weathers[inx].humidity);
|
||||||
|
Serial.println("condition: " + weathers[inx].condition);
|
||||||
|
Serial.println("wind: " + weathers[inx].wind);
|
||||||
|
Serial.println("weatherId: " + weathers[inx].weatherId);
|
||||||
|
Serial.println("description: " + weathers[inx].description);
|
||||||
|
Serial.println("icon: " + weathers[inx].icon);
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::roundValue(String value) {
|
||||||
|
float f = value.toFloat();
|
||||||
|
int rounded = (int)(f+0.5f);
|
||||||
|
return String(rounded);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenWeatherMapClient::updateCityIdList(int CityIDs[], int cityCount) {
|
||||||
|
myCityIDs = "";
|
||||||
|
for (int inx = 0; inx < cityCount; inx++) {
|
||||||
|
if (CityIDs[inx] > 0) {
|
||||||
|
if (myCityIDs != "") {
|
||||||
|
myCityIDs = myCityIDs + ",";
|
||||||
|
}
|
||||||
|
myCityIDs = myCityIDs + String(CityIDs[inx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenWeatherMapClient::setMetric(boolean isMetric) {
|
||||||
|
if (isMetric) {
|
||||||
|
units = "metric";
|
||||||
|
} else {
|
||||||
|
units = "imperial";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getWeatherResults() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getLat(int index) {
|
||||||
|
return weathers[index].lat;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getLon(int index) {
|
||||||
|
return weathers[index].lon;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getDt(int index) {
|
||||||
|
return weathers[index].dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getCity(int index) {
|
||||||
|
return weathers[index].city;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getCountry(int index) {
|
||||||
|
return weathers[index].country;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getTemp(int index) {
|
||||||
|
return weathers[index].temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getTempRounded(int index) {
|
||||||
|
return roundValue(getTemp(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getHumidity(int index) {
|
||||||
|
return weathers[index].humidity;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getHumidityRounded(int index) {
|
||||||
|
return roundValue(getHumidity(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getCondition(int index) {
|
||||||
|
return weathers[index].condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getWind(int index) {
|
||||||
|
return weathers[index].wind;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getWindRounded(int index) {
|
||||||
|
return roundValue(getWind(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getWeatherId(int index) {
|
||||||
|
return weathers[index].weatherId;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getDescription(int index) {
|
||||||
|
return weathers[index].description;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getIcon(int index) {
|
||||||
|
return weathers[index].icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean OpenWeatherMapClient::getCached() {
|
||||||
|
return weathers[0].cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getMyCityIDs() {
|
||||||
|
return myCityIDs;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getError() {
|
||||||
|
return weathers[0].error;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OpenWeatherMapClient::getWeatherIcon(int index)
|
||||||
|
{
|
||||||
|
int id = getWeatherId(index).toInt();
|
||||||
|
String W = ")";
|
||||||
|
switch(id)
|
||||||
|
{
|
||||||
|
case 800: W = "B"; break;
|
||||||
|
case 801: W = "Y"; break;
|
||||||
|
case 802: W = "H"; break;
|
||||||
|
case 803: W = "H"; break;
|
||||||
|
case 804: W = "Y"; break;
|
||||||
|
|
||||||
|
case 200: W = "0"; break;
|
||||||
|
case 201: W = "0"; break;
|
||||||
|
case 202: W = "0"; break;
|
||||||
|
case 210: W = "0"; break;
|
||||||
|
case 211: W = "0"; break;
|
||||||
|
case 212: W = "0"; break;
|
||||||
|
case 221: W = "0"; break;
|
||||||
|
case 230: W = "0"; break;
|
||||||
|
case 231: W = "0"; break;
|
||||||
|
case 232: W = "0"; break;
|
||||||
|
|
||||||
|
case 300: W = "R"; break;
|
||||||
|
case 301: W = "R"; break;
|
||||||
|
case 302: W = "R"; break;
|
||||||
|
case 310: W = "R"; break;
|
||||||
|
case 311: W = "R"; break;
|
||||||
|
case 312: W = "R"; break;
|
||||||
|
case 313: W = "R"; break;
|
||||||
|
case 314: W = "R"; break;
|
||||||
|
case 321: W = "R"; break;
|
||||||
|
|
||||||
|
case 500: W = "R"; break;
|
||||||
|
case 501: W = "R"; break;
|
||||||
|
case 502: W = "R"; break;
|
||||||
|
case 503: W = "R"; break;
|
||||||
|
case 504: W = "R"; break;
|
||||||
|
case 511: W = "R"; break;
|
||||||
|
case 520: W = "R"; break;
|
||||||
|
case 521: W = "R"; break;
|
||||||
|
case 522: W = "R"; break;
|
||||||
|
case 531: W = "R"; break;
|
||||||
|
|
||||||
|
case 600: W = "W"; break;
|
||||||
|
case 601: W = "W"; break;
|
||||||
|
case 602: W = "W"; break;
|
||||||
|
case 611: W = "W"; break;
|
||||||
|
case 612: W = "W"; break;
|
||||||
|
case 615: W = "W"; break;
|
||||||
|
case 616: W = "W"; break;
|
||||||
|
case 620: W = "W"; break;
|
||||||
|
case 621: W = "W"; break;
|
||||||
|
case 622: W = "W"; break;
|
||||||
|
|
||||||
|
case 701: W = "M"; break;
|
||||||
|
case 711: W = "M"; break;
|
||||||
|
case 721: W = "M"; break;
|
||||||
|
case 731: W = "M"; break;
|
||||||
|
case 741: W = "M"; break;
|
||||||
|
case 751: W = "M"; break;
|
||||||
|
case 761: W = "M"; break;
|
||||||
|
case 762: W = "M"; break;
|
||||||
|
case 771: W = "M"; break;
|
||||||
|
case 781: W = "M"; break;
|
||||||
|
|
||||||
|
default:break;
|
||||||
|
}
|
||||||
|
return W;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
/** 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
class OpenWeatherMapClient {
|
||||||
|
|
||||||
|
private:
|
||||||
|
String myCityIDs = "";
|
||||||
|
String myApiKey = "";
|
||||||
|
String units = "";
|
||||||
|
|
||||||
|
const char* servername = "api.openweathermap.org"; // remote server we will connect to
|
||||||
|
String result;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
String lat;
|
||||||
|
String lon;
|
||||||
|
String dt;
|
||||||
|
String city;
|
||||||
|
String country;
|
||||||
|
String temp;
|
||||||
|
String humidity;
|
||||||
|
String condition;
|
||||||
|
String wind;
|
||||||
|
String weatherId;
|
||||||
|
String description;
|
||||||
|
String icon;
|
||||||
|
boolean cached;
|
||||||
|
String error;
|
||||||
|
} weather;
|
||||||
|
|
||||||
|
weather weathers[5];
|
||||||
|
|
||||||
|
String roundValue(String value);
|
||||||
|
|
||||||
|
public:
|
||||||
|
OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric);
|
||||||
|
void updateWeather();
|
||||||
|
void updateWeatherApiKey(String ApiKey);
|
||||||
|
void updateCityIdList(int CityIDs[], int cityCount);
|
||||||
|
void setMetric(boolean isMetric);
|
||||||
|
|
||||||
|
String getWeatherResults();
|
||||||
|
|
||||||
|
String getLat(int index);
|
||||||
|
String getLon(int index);
|
||||||
|
String getDt(int index);
|
||||||
|
String getCity(int index);
|
||||||
|
String getCountry(int index);
|
||||||
|
String getTemp(int index);
|
||||||
|
String getTempRounded(int index);
|
||||||
|
String getHumidity(int index);
|
||||||
|
String getHumidityRounded(int index);
|
||||||
|
String getCondition(int index);
|
||||||
|
String getWind(int index);
|
||||||
|
String getWindRounded(int index);
|
||||||
|
String getWeatherId(int index);
|
||||||
|
String getDescription(int index);
|
||||||
|
String getIcon(int index);
|
||||||
|
boolean getCached();
|
||||||
|
String getMyCityIDs();
|
||||||
|
String getWeatherIcon(int index);
|
||||||
|
String getError();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -42,6 +42,8 @@ SOFTWARE.
|
||||||
#include <ArduinoOTA.h>
|
#include <ArduinoOTA.h>
|
||||||
#include "TimeClient.h"
|
#include "TimeClient.h"
|
||||||
#include "OctoPrintClient.h"
|
#include "OctoPrintClient.h"
|
||||||
|
#include "OpenWeatherMapClient.h"
|
||||||
|
#include "WeatherStationFonts.h"
|
||||||
#include "FS.h"
|
#include "FS.h"
|
||||||
#include "SH1106Wire.h"
|
#include "SH1106Wire.h"
|
||||||
#include "SSD1306Wire.h"
|
#include "SSD1306Wire.h"
|
||||||
|
|
@ -59,13 +61,20 @@ int OctoPrintPort = 80; // the port you are running your OctoPrint server
|
||||||
String OctoAuthUser = ""; // only used if you have haproxy or basic athentintication turned on (not default)
|
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)
|
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 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]/
|
||||||
char* www_username = "admin"; // User account for the Web Interface
|
char* www_username = "admin"; // User account for the Web Interface
|
||||||
char* www_password = "password"; // Password for the Web Interface
|
char* www_password = "password"; // Password for the Web Interface
|
||||||
float UtcOffset = -7; // Hour offset from GMT for your timezone
|
float UtcOffset = -7; // Hour offset from GMT for your timezone
|
||||||
boolean IS_24HOUR = false; // 23:00 millitary 24 hour clock
|
boolean IS_24HOUR = false; // 23:00 millitary 24 hour clock
|
||||||
int minutesBetweenDataRefresh = 60;
|
int minutesBetweenDataRefresh = 15;
|
||||||
boolean DISPLAYCLOCK = true; // true = Show Clock when not printing / false = turn off display when not printing
|
boolean DISPLAYCLOCK = true; // true = Show Clock when not printing / false = turn off display when not printing
|
||||||
|
|
||||||
// Display Settings
|
// Display Settings
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -27,7 +27,7 @@ SOFTWARE.
|
||||||
|
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
#define VERSION "1.7"
|
#define VERSION "2.0"
|
||||||
|
|
||||||
#define HOSTNAME "OctMon-"
|
#define HOSTNAME "OctMon-"
|
||||||
#define CONFIG "/conf.txt"
|
#define CONFIG "/conf.txt"
|
||||||
|
|
@ -60,12 +60,13 @@ void drawScreen2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int
|
||||||
void drawScreen3(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 drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state);
|
||||||
void drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
|
void drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
|
||||||
|
void drawWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
|
||||||
void drawClockHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state);
|
void drawClockHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state);
|
||||||
|
|
||||||
// Set the number of Frames supported
|
// Set the number of Frames supported
|
||||||
const int numberOfFrames = 3;
|
const int numberOfFrames = 3;
|
||||||
FrameCallback frames[numberOfFrames];
|
FrameCallback frames[numberOfFrames];
|
||||||
FrameCallback clockFrame[1];
|
FrameCallback clockFrame[2];
|
||||||
boolean isClockOn = false;
|
boolean isClockOn = false;
|
||||||
|
|
||||||
OverlayCallback overlays[] = { drawHeaderOverlay };
|
OverlayCallback overlays[] = { drawHeaderOverlay };
|
||||||
|
|
@ -86,57 +87,71 @@ boolean displayOn = true;
|
||||||
OctoPrintClient printerClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, OctoAuthUser, OctoAuthPass);
|
OctoPrintClient printerClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, OctoAuthUser, OctoAuthPass);
|
||||||
int printerCount = 0;
|
int printerCount = 0;
|
||||||
|
|
||||||
|
// Weather Client
|
||||||
|
OpenWeatherMapClient weatherClient(WeatherApiKey, CityIDs, 1, IS_METRIC);
|
||||||
|
|
||||||
//declairing prototypes
|
//declairing prototypes
|
||||||
void configModeCallback (WiFiManager *myWiFiManager);
|
void configModeCallback (WiFiManager *myWiFiManager);
|
||||||
int8_t getWifiQuality();
|
int8_t getWifiQuality();
|
||||||
|
|
||||||
ESP8266WebServer server(WEBSERVER_PORT);
|
ESP8266WebServer server(WEBSERVER_PORT);
|
||||||
|
|
||||||
const String WEB_ACTIONS = "<a class='w3-bar-item w3-button' href='/'><i class='fa fa-home'></i> Home</a>"
|
String WEB_ACTIONS = "<a class='w3-bar-item w3-button' href='/'><i class='fa fa-home'></i> Home</a>"
|
||||||
"<a class='w3-bar-item w3-button' href='/configure'><i class='fa fa-cog'></i> Configure</a>"
|
"<a class='w3-bar-item w3-button' href='/configure'><i class='fa fa-cog'></i> Configure</a>"
|
||||||
"<a class='w3-bar-item w3-button' href='/systemreset' onclick='return confirm(\"Do you want to reset to default settings?\")'><i class='fa fa-undo'></i> Reset Settings</a>"
|
"<a class='w3-bar-item w3-button' href='/configureweather'><i class='fa fa-cloud'></i> Weather</a>"
|
||||||
"<a class='w3-bar-item w3-button' href='/forgetwifi' onclick='return confirm(\"Do you want to forget to WiFi connection?\")'><i class='fa fa-wifi'></i> Forget WiFi</a>"
|
"<a class='w3-bar-item w3-button' href='/systemreset' onclick='return confirm(\"Do you want to reset to default settings?\")'><i class='fa fa-undo'></i> Reset Settings</a>"
|
||||||
"<a class='w3-bar-item w3-button' href='https://github.com/Qrome' target='_blank'><i class='fa fa-question-circle'></i> About</a>";
|
"<a class='w3-bar-item w3-button' href='/forgetwifi' onclick='return confirm(\"Do you want to forget to WiFi connection?\")'><i class='fa fa-wifi'></i> Forget WiFi</a>"
|
||||||
|
"<a class='w3-bar-item w3-button' href='https://github.com/Qrome' target='_blank'><i class='fa fa-question-circle'></i> About</a>";
|
||||||
|
|
||||||
const String CHANGE_FORM = "<form class='w3-container' action='/updateconfig' method='get'><h2>Station Config:</h2>"
|
String CHANGE_FORM = "<form class='w3-container' action='/updateconfig' method='get'><h2>Station Config:</h2>"
|
||||||
"<p><label>OctoPrint API Key (get from your server)</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='octoPrintApiKey' value='%OCTOKEY%' maxlength='60'></p>"
|
"<p><label>OctoPrint API Key (get from your server)</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='octoPrintApiKey' value='%OCTOKEY%' maxlength='60'></p>"
|
||||||
"<p><label>OctoPrint Host Name (usually octopi)</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='octoPrintHostName' value='%OCTOHOST%' maxlength='60'></p>"
|
"<p><label>OctoPrint Host Name (usually octopi)</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='octoPrintHostName' value='%OCTOHOST%' maxlength='60'></p>"
|
||||||
"<p><label>OctoPrint Address (do not include http://)</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='octoPrintAddress' value='%OCTOADDRESS%' maxlength='60'></p>"
|
"<p><label>OctoPrint Address (do not include http://)</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='octoPrintAddress' value='%OCTOADDRESS%' maxlength='60'></p>"
|
||||||
"<p><label>OctoPrint Port</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='octoPrintPort' value='%OCTOPORT%' maxlength='5' onkeypress='return isNumberKey(event)'></p>"
|
"<p><label>OctoPrint Port</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='octoPrintPort' value='%OCTOPORT%' maxlength='5' onkeypress='return isNumberKey(event)'></p>"
|
||||||
"<p><label>OctoPrint User (only needed if you have haproxy or basic auth turned on)</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='octoUser' value='%OCTOUSER%' maxlength='30'></p>"
|
"<p><label>OctoPrint User (only needed if you have haproxy or basic auth turned on)</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='octoUser' value='%OCTOUSER%' maxlength='30'></p>"
|
||||||
"<p><label>OctoPrint Password </label><input class='w3-input w3-border w3-margin-bottom' type='password' name='octoPass' value='%OCTOPASS%'></p><hr>"
|
"<p><label>OctoPrint Password </label><input class='w3-input w3-border w3-margin-bottom' type='password' name='octoPass' value='%OCTOPASS%'></p><hr>"
|
||||||
"<p><input name='isClockEnabled' class='w3-check w3-margin-top' type='checkbox' %IS_CLOCK_CHECKED%> Display Clock when printer is off</p>"
|
"<p><input name='isClockEnabled' class='w3-check w3-margin-top' type='checkbox' %IS_CLOCK_CHECKED%> Display Clock when printer is off</p>"
|
||||||
"<p><input name='is24hour' class='w3-check w3-margin-top' type='checkbox' %IS_24HOUR_CHECKED%> Use 24 Hour Clock (military time)</p>"
|
"<p><input name='is24hour' class='w3-check w3-margin-top' type='checkbox' %IS_24HOUR_CHECKED%> Use 24 Hour Clock (military time)</p>"
|
||||||
"<p>Time Refresh (minutes) <select class='w3-option w3-padding' name='refresh'>%OPTIONS%</select></p>"
|
"<p>Clock Sync / Weather Refresh (minutes) <select class='w3-option w3-padding' name='refresh'>%OPTIONS%</select></p>"
|
||||||
"<p>Theme Color <select class='w3-option w3-padding' name='theme'>%THEME_OPTIONS%</select></p>"
|
"<p>Theme Color <select class='w3-option w3-padding' name='theme'>%THEME_OPTIONS%</select></p>"
|
||||||
"<p><label>UTC Time Offset</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='utcoffset' value='%UTCOFFSET%' maxlength='12'></p><hr>"
|
"<p><label>UTC Time Offset</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='utcoffset' value='%UTCOFFSET%' maxlength='12'></p><hr>"
|
||||||
"<p><label>User ID (for this interface)</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='userid' value='%USERID%' maxlength='20'></p>"
|
"<p><label>User ID (for this interface)</label><input class='w3-input w3-border w3-margin-bottom' type='text' name='userid' value='%USERID%' maxlength='20'></p>"
|
||||||
"<p><label>Password </label><input class='w3-input w3-border w3-margin-bottom' type='password' name='stationpassword' value='%STATIONPASSWORD%'></p>"
|
"<p><label>Password </label><input class='w3-input w3-border w3-margin-bottom' type='password' name='stationpassword' value='%STATIONPASSWORD%'></p>"
|
||||||
"<button class='w3-button w3-block w3-grey w3-section w3-padding' type='submit'>Save</button></form>";
|
"<button class='w3-button w3-block w3-grey w3-section w3-padding' type='submit'>Save</button></form>";
|
||||||
|
|
||||||
const String COLOR_THEMES = "<option>red</option>"
|
String WEATHER_FORM = "<form class='w3-container' action='/updateweatherconfig' method='get'><h2>Weather Config:</h2>"
|
||||||
"<option>pink</option>"
|
"<p><input name='isWeatherEnabled' class='w3-check w3-margin-top' type='checkbox' %IS_WEATHER_CHECKED%> Display Weather when printer is off</p>"
|
||||||
"<option>purple</option>"
|
"<label>OpenWeahterMap API Key (get from <a href='https://openweathermap.org/' target='_BLANK'>here</a>)</label>"
|
||||||
"<option>deep-purple</option>"
|
"<input class='w3-input w3-border w3-margin-bottom' type='text' name='openWeatherMapApiKey' value='%WEATHERKEY%' maxlength='60'>"
|
||||||
"<option>indigo</option>"
|
"<p><label>%CITYNAME1% (<a href='http://openweathermap.org/find' target='_BLANK'><i class='fa fa-search'></i> Search for City ID</a>)</label>"
|
||||||
"<option>blue</option>"
|
"<input class='w3-input w3-border w3-margin-bottom' type='text' name='city1' value='%CITY1%' onkeypress='return isNumberKey(event)'></p>"
|
||||||
"<option>light-blue</option>"
|
"<p><input name='metric' class='w3-check w3-margin-top' type='checkbox' %METRIC%> Use Metric (Celsius)</p>"
|
||||||
"<option>cyan</option>"
|
"<button class='w3-button w3-block w3-grey w3-section w3-padding' type='submit'>Save</button></form>"
|
||||||
"<option>teal</option>"
|
"<script>function isNumberKey(e){var h=e.which?e.which:event.keyCode;return!(h>31&&(h<48||h>57))}</script>";
|
||||||
"<option>green</option>"
|
|
||||||
"<option>light-green</option>"
|
String COLOR_THEMES = "<option>red</option>"
|
||||||
"<option>lime</option>"
|
"<option>pink</option>"
|
||||||
"<option>khaki</option>"
|
"<option>purple</option>"
|
||||||
"<option>yellow</option>"
|
"<option>deep-purple</option>"
|
||||||
"<option>amber</option>"
|
"<option>indigo</option>"
|
||||||
"<option>orange</option>"
|
"<option>blue</option>"
|
||||||
"<option>deep-orange</option>"
|
"<option>light-blue</option>"
|
||||||
"<option>blue-grey</option>"
|
"<option>cyan</option>"
|
||||||
"<option>brown</option>"
|
"<option>teal</option>"
|
||||||
"<option>grey</option>"
|
"<option>green</option>"
|
||||||
"<option>dark-grey</option>"
|
"<option>light-green</option>"
|
||||||
"<option>black</option>"
|
"<option>lime</option>"
|
||||||
"<option>w3schools</option>";
|
"<option>khaki</option>"
|
||||||
|
"<option>yellow</option>"
|
||||||
|
"<option>amber</option>"
|
||||||
|
"<option>orange</option>"
|
||||||
|
"<option>deep-orange</option>"
|
||||||
|
"<option>blue-grey</option>"
|
||||||
|
"<option>brown</option>"
|
||||||
|
"<option>grey</option>"
|
||||||
|
"<option>dark-grey</option>"
|
||||||
|
"<option>black</option>"
|
||||||
|
"<option>w3schools</option>";
|
||||||
|
|
||||||
|
|
||||||
// Change the externalLight to the pin you wish to use if other than the Built-in LED
|
// Change the externalLight to the pin you wish to use if other than the Built-in LED
|
||||||
|
|
@ -197,6 +212,7 @@ void setup() {
|
||||||
frames[1] = drawScreen2;
|
frames[1] = drawScreen2;
|
||||||
frames[2] = drawScreen3;
|
frames[2] = drawScreen3;
|
||||||
clockFrame[0] = drawClock;
|
clockFrame[0] = drawClock;
|
||||||
|
clockFrame[1] = drawWeather;
|
||||||
ui.setOverlays(overlays, numberOfOverlays);
|
ui.setOverlays(overlays, numberOfOverlays);
|
||||||
|
|
||||||
// Inital UI takes care of initalising the display too.
|
// Inital UI takes care of initalising the display too.
|
||||||
|
|
@ -240,7 +256,9 @@ void setup() {
|
||||||
server.on("/systemreset", handleSystemReset);
|
server.on("/systemreset", handleSystemReset);
|
||||||
server.on("/forgetwifi", handleWifiReset);
|
server.on("/forgetwifi", handleWifiReset);
|
||||||
server.on("/updateconfig", handleUpdateConfig);
|
server.on("/updateconfig", handleUpdateConfig);
|
||||||
|
server.on("/updateweatherconfig", handleUpdateWeather);
|
||||||
server.on("/configure", handleConfigure);
|
server.on("/configure", handleConfigure);
|
||||||
|
server.on("/configureweather", handleWeatherConfigure);
|
||||||
server.onNotFound(redirectHome);
|
server.onNotFound(redirectHome);
|
||||||
// Start the server
|
// Start the server
|
||||||
server.begin();
|
server.begin();
|
||||||
|
|
@ -340,6 +358,11 @@ void getUpdateTime() {
|
||||||
digitalWrite(externalLight, LOW); // turn on the LED
|
digitalWrite(externalLight, LOW); // turn on the LED
|
||||||
Serial.println();
|
Serial.println();
|
||||||
|
|
||||||
|
if (displayOn && DISPLAYWEATHER) {
|
||||||
|
Serial.println("Getting Weather Data...");
|
||||||
|
weatherClient.updateWeather();
|
||||||
|
}
|
||||||
|
|
||||||
Serial.println("Updating Time...");
|
Serial.println("Updating Time...");
|
||||||
//Update the Time
|
//Update the Time
|
||||||
timeClient.updateTime();
|
timeClient.updateTime();
|
||||||
|
|
@ -360,6 +383,21 @@ void handleSystemReset() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() {
|
void handleUpdateConfig() {
|
||||||
if (!server.authenticate(www_username, www_password)) {
|
if (!server.authenticate(www_username, www_password)) {
|
||||||
return server.requestAuthentication();
|
return server.requestAuthentication();
|
||||||
|
|
@ -399,6 +437,46 @@ void handleWifiReset() {
|
||||||
ESP.restart();
|
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() {
|
void handleConfigure() {
|
||||||
if (!server.authenticate(www_username, www_password)) {
|
if (!server.authenticate(www_username, www_password)) {
|
||||||
return server.requestAuthentication();
|
return server.requestAuthentication();
|
||||||
|
|
@ -415,7 +493,7 @@ void handleConfigure() {
|
||||||
html = getHeader();
|
html = getHeader();
|
||||||
server.sendContent(html);
|
server.sendContent(html);
|
||||||
|
|
||||||
String form = String(CHANGE_FORM);
|
String form = CHANGE_FORM;
|
||||||
|
|
||||||
form.replace("%OCTOKEY%", OctoPrintApiKey);
|
form.replace("%OCTOKEY%", OctoPrintApiKey);
|
||||||
form.replace("%OCTOHOST%", OctoPrintHostName);
|
form.replace("%OCTOHOST%", OctoPrintHostName);
|
||||||
|
|
@ -436,14 +514,14 @@ void handleConfigure() {
|
||||||
String options = "<option>10</option><option>15</option><option>20</option><option>30</option><option>60</option>";
|
String options = "<option>10</option><option>15</option><option>20</option><option>30</option><option>60</option>";
|
||||||
options.replace(">"+String(minutesBetweenDataRefresh)+"<", " selected>"+String(minutesBetweenDataRefresh)+"<");
|
options.replace(">"+String(minutesBetweenDataRefresh)+"<", " selected>"+String(minutesBetweenDataRefresh)+"<");
|
||||||
form.replace("%OPTIONS%", options);
|
form.replace("%OPTIONS%", options);
|
||||||
String themeOptions = String(COLOR_THEMES);
|
String themeOptions = COLOR_THEMES;
|
||||||
themeOptions.replace(">"+String(themeColor)+"<", " selected>"+String(themeColor)+"<");
|
themeOptions.replace(">"+String(themeColor)+"<", " selected>"+String(themeColor)+"<");
|
||||||
form.replace("%THEME_OPTIONS%", themeOptions);
|
form.replace("%THEME_OPTIONS%", themeOptions);
|
||||||
form.replace("%UTCOFFSET%", String(UtcOffset));
|
form.replace("%UTCOFFSET%", String(UtcOffset));
|
||||||
form.replace("%USERID%", String(www_username));
|
form.replace("%USERID%", String(www_username));
|
||||||
form.replace("%STATIONPASSWORD%", String(www_password));
|
form.replace("%STATIONPASSWORD%", String(www_password));
|
||||||
|
|
||||||
server.sendContent(String(form));
|
server.sendContent(form);
|
||||||
|
|
||||||
html = getFooter();
|
html = getFooter();
|
||||||
server.sendContent(html);
|
server.sendContent(html);
|
||||||
|
|
@ -486,7 +564,7 @@ String getHeader() {
|
||||||
}
|
}
|
||||||
|
|
||||||
String getHeader(boolean refresh) {
|
String getHeader(boolean refresh) {
|
||||||
String menu = String(WEB_ACTIONS);
|
String menu = WEB_ACTIONS;
|
||||||
|
|
||||||
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,='>";
|
||||||
|
|
@ -586,8 +664,32 @@ void displayPrinterStatus() {
|
||||||
html += "<div id=\"myProgress\"><div id=\"myBar\" class=\"w3-medium w3-center\">" + printerClient.getProgressCompletion() + "%</div></div>";
|
html += "<div id=\"myProgress\"><div id=\"myBar\" class=\"w3-medium w3-center\">" + printerClient.getProgressCompletion() + "%</div></div>";
|
||||||
html += "</p></div></div>";
|
html += "</p></div></div>";
|
||||||
|
|
||||||
server.sendContent(String(html)); // spit out what we got
|
server.sendContent(html); // spit out what we got
|
||||||
|
html = "";
|
||||||
|
|
||||||
|
if (DISPLAYWEATHER) {
|
||||||
|
if (weatherClient.getCity(0) == "") {
|
||||||
|
html += "<p>Please <a href='/configureweather'>Configure Weahter</a> API</p>";
|
||||||
|
if (weatherClient.getError() != "") {
|
||||||
|
html += "<p>Weather Error: <strong>" + weatherClient.getError() + "</strong></p>";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
html += "<div class='w3-cell-row' style='width:100%'><h2>" + weatherClient.getCity(0) + ", " + weatherClient.getCountry(0) + "</h2></div><div class='w3-cell-row'>";
|
||||||
|
html += "<div class='w3-cell w3-left w3-medium' style='width:120px'>";
|
||||||
|
html += "<img src='http://openweathermap.org/img/w/" + weatherClient.getIcon(0) + ".png' alt='" + weatherClient.getDescription(0) + "'><br>";
|
||||||
|
html += weatherClient.getHumidity(0) + "% Humidity<br>";
|
||||||
|
html += weatherClient.getWind(0) + " <span class='w3-tiny'>" + getSpeedSymbol() + "</span> Wind<br>";
|
||||||
|
html += "</div>";
|
||||||
|
html += "<div class='w3-cell w3-container' style='width:100%'><p>";
|
||||||
|
html += weatherClient.getCondition(0) + " (" + weatherClient.getDescription(0) + ")<br>";
|
||||||
|
html += weatherClient.getTempRounded(0) + getTempSymbol(true) + "<br>";
|
||||||
|
html += "<a href='https://www.google.com/maps/@" + weatherClient.getLat(0) + "," + weatherClient.getLon(0) + ",10000m/data=!3m1!1e3' target='_BLANK'><i class='fa fa-map-marker' style='color:red'></i> Map It!</a><br>";
|
||||||
|
html += "</p></div></div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
server.sendContent(html); // spit out what we got
|
||||||
|
html = ""; // fresh start
|
||||||
|
}
|
||||||
|
|
||||||
server.sendContent(String(getFooter()));
|
server.sendContent(String(getFooter()));
|
||||||
server.sendContent("");
|
server.sendContent("");
|
||||||
|
|
@ -683,6 +785,44 @@ void drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16
|
||||||
display->drawString(64 + x, 10 + y, displayTime);
|
display->drawString(64 + x, 10 + 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 zeroPad(int value) {
|
||||||
String rtnValue = String(value);
|
String rtnValue = String(value);
|
||||||
if (value < 10) {
|
if (value < 10) {
|
||||||
|
|
@ -734,7 +874,7 @@ void drawClockHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
|
||||||
display->drawString(64, 48, "offline");
|
display->drawString(64, 48, "offline");
|
||||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
|
|
||||||
display->drawRect(0, 41, 128, 2);
|
display->drawRect(0, 43, 128, 2);
|
||||||
|
|
||||||
drawRssi(display);
|
drawRssi(display);
|
||||||
}
|
}
|
||||||
|
|
@ -785,6 +925,10 @@ void writeSettings() {
|
||||||
f.println("www_password=" + String(www_password));
|
f.println("www_password=" + String(www_password));
|
||||||
f.println("DISPLAYCLOCK=" + String(DISPLAYCLOCK));
|
f.println("DISPLAYCLOCK=" + String(DISPLAYCLOCK));
|
||||||
f.println("is24hour=" + String(IS_24HOUR));
|
f.println("is24hour=" + String(IS_24HOUR));
|
||||||
|
f.println("isWeather=" + String(DISPLAYWEATHER));
|
||||||
|
f.println("weatherKey=" + WeatherApiKey);
|
||||||
|
f.println("CityID=" + String(CityIDs[0]));
|
||||||
|
f.println("isMetric=" + String(IS_METRIC));
|
||||||
}
|
}
|
||||||
f.close();
|
f.close();
|
||||||
readSettings();
|
readSettings();
|
||||||
|
|
@ -864,9 +1008,29 @@ void readSettings() {
|
||||||
IS_24HOUR = line.substring(line.lastIndexOf("is24hour=") + 9).toInt();
|
IS_24HOUR = line.substring(line.lastIndexOf("is24hour=") + 9).toInt();
|
||||||
Serial.println("IS_24HOUR=" + String(IS_24HOUR));
|
Serial.println("IS_24HOUR=" + String(IS_24HOUR));
|
||||||
}
|
}
|
||||||
|
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();
|
fr.close();
|
||||||
printerClient.updateOctoPrintClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, OctoAuthUser, OctoAuthPass);
|
printerClient.updateOctoPrintClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, OctoAuthUser, OctoAuthPass);
|
||||||
|
weatherClient.updateWeatherApiKey(WeatherApiKey);
|
||||||
|
weatherClient.setMetric(IS_METRIC);
|
||||||
|
weatherClient.updateCityIdList(CityIDs, 1);
|
||||||
timeClient.setUtcOffset(UtcOffset);
|
timeClient.setUtcOffset(UtcOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -916,9 +1080,16 @@ void checkDisplay() {
|
||||||
} else if (DISPLAYCLOCK) {
|
} else if (DISPLAYCLOCK) {
|
||||||
if (!printerClient.isOperational() && !isClockOn) {
|
if (!printerClient.isOperational() && !isClockOn) {
|
||||||
Serial.println("Clock Mode is turned on.");
|
Serial.println("Clock Mode is turned on.");
|
||||||
ui.disableAutoTransition();
|
if (!DISPLAYWEATHER) {
|
||||||
ui.setFrames(clockFrame, 1);
|
ui.disableAutoTransition();
|
||||||
clockFrame[0] = drawClock;
|
ui.setFrames(clockFrame, 1);
|
||||||
|
clockFrame[0] = drawClock;
|
||||||
|
} else {
|
||||||
|
ui.enableAutoTransition();
|
||||||
|
ui.setFrames(clockFrame, 2);
|
||||||
|
clockFrame[0] = drawClock;
|
||||||
|
clockFrame[1] = drawWeather;
|
||||||
|
}
|
||||||
ui.setOverlays(clockOverlay, numberOfOverlays);
|
ui.setOverlays(clockOverlay, numberOfOverlays);
|
||||||
isClockOn = true;
|
isClockOn = true;
|
||||||
} else if (printerClient.isOperational() && isClockOn) {
|
} else if (printerClient.isOperational() && isClockOn) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue