diff --git a/printermonitor/OctoPrintClient.h b/printermonitor/OctoPrintClient.h old mode 100755 new mode 100644 diff --git a/printermonitor/OpenWeatherMapClient.cpp b/printermonitor/OpenWeatherMapClient.cpp index f7c66cd..2710c9b 100644 --- a/printermonitor/OpenWeatherMapClient.cpp +++ b/printermonitor/OpenWeatherMapClient.cpp @@ -22,6 +22,7 @@ SOFTWARE. */ #include "OpenWeatherMapClient.h" +#include OpenWeatherMapClient::OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric, String language) { updateCityIdList(CityIDs, cityCount); @@ -31,6 +32,7 @@ OpenWeatherMapClient::OpenWeatherMapClient(String ApiKey, int CityIDs[], int cit } void OpenWeatherMapClient::updateWeatherApiKey(String ApiKey) { + ApiKey.trim(); myApiKey = ApiKey; } @@ -42,101 +44,110 @@ void OpenWeatherMapClient::updateLanguage(String language) { } void OpenWeatherMapClient::updateWeather() { - WiFiClient weatherClient; - String apiGetData = "GET /data/2.5/group?id=" + myCityIDs + "&units=" + units + "&cnt=1&APPID=" + myApiKey + "&lang=" + lang + " HTTP/1.1"; + WiFiClientSecure weatherClient; + weatherClient.setTimeout(15000); + weatherClient.setInsecure(); + #ifdef ESP8266 + weatherClient.setBufferSizes(1024, 512); + #endif - Serial.println("Obteniendo datos de clima"); - 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("conexión fallida al obtener datos del clima"); //error message if no client connect - Serial.println(); + String firstId = myCityIDs; + int comma = firstId.indexOf(','); + if (comma > 0) firstId.remove(comma); + + myApiKey.trim(); + + String path = "/data/2.5/weather?id=" + firstId + + "&units=" + units + + "&appid=" + myApiKey + + "&lang=" + lang; + + Serial.println("\n[OWM] GET " + path); + + if (!weatherClient.connect(servername, 443)) { + Serial.println("[OWM] Conexión TLS fallida"); + weathers[0].cached = true; + weathers[0].error = "TLS connect fail"; return; } - while(weatherClient.connected() && !weatherClient.available()) delay(1); //waits for data - - Serial.println("Esperando por datos"); + weatherClient.print(String("GET ") + path + " HTTP/1.1\r\n" + + "Host: " + String(servername) + "\r\n" + + "User-Agent: ESP8266-OWM/1.0\r\n" + + "Connection: close\r\n\r\n"); - // 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); + String statusLine = weatherClient.readStringUntil('\n'); + statusLine.trim(); + Serial.println("[OWM] " + statusLine); + if (!statusLine.startsWith("HTTP/1.1 ")) { + weathers[0].cached = true; + weathers[0].error = "Invalid HTTP"; + return; + } + int httpCode = statusLine.substring(9, 12).toInt(); + + if (!weatherClient.find("\r\n\r\n")) { + Serial.println("[OWM] No end-of-headers"); + weathers[0].cached = true; + weathers[0].error = "Bad headers"; return; } - // Skip HTTP headers - char endOfHeaders[] = "\r\n\r\n"; - if (!weatherClient.find(endOfHeaders)) { - Serial.println(F("Respuesta no válida")); - return; - } - - const size_t bufferSize = 710; + const size_t bufferSize = 4096; DynamicJsonBuffer jsonBuffer(bufferSize); - - weathers[0].cached = false; - weathers[0].error = ""; - // Parse JSON object JsonObject& root = jsonBuffer.parseObject(weatherClient); if (!root.success()) { - Serial.println(F("Fallo al parsear los datos del clima!")); - weathers[0].error = "Fallo al parsear los datos del clima!"; - return; - } - - weatherClient.stop(); //stop client - - if (root.measureLength() <= 150) { - Serial.println("Error No parece que hayamos obtenido los datos. Tamaño: " + String(root.measureLength())); + Serial.println("[OWM] JSON parse FAIL"); weathers[0].cached = true; - weathers[0].error = (const char*)root["message"]; - Serial.println("Error: " + weathers[0].error); + weathers[0].error = "JSON parse fail"; 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 cod = root["cod"].is() ? (const char*)root["cod"] : String((int)root["cod"]); + if (cod != "200") { + weathers[0].cached = true; + weathers[0].error = root["message"].is() ? (const char*)root["message"] : "cod!=200"; + Serial.println("[OWM] API error: " + weathers[0].error); + return; } + + JsonObject& main = root["main"]; + JsonObject& wind = root["wind"]; + JsonObject& sys = root["sys"]; + JsonArray& wArr = root["weather"]; + + weathers[0].lat = String((double)root["coord"]["lat"]); + weathers[0].lon = String((double)root["coord"]["lon"]); + weathers[0].dt = String((long) root["dt"]); + weathers[0].city = root["name"].is() ? (const char*)root["name"] : ""; + weathers[0].country = sys["country"].is() ? (const char*)sys["country"] : ""; + weathers[0].temp = String((double)main["temp"]); + weathers[0].humidity = String((int) main["humidity"]); + weathers[0].wind = String((double)wind["speed"]); + + if (wArr.size() > 0) { + JsonObject& w0 = wArr[0]; + weathers[0].condition = w0["main"].is() ? (const char*)w0["main"] : ""; + weathers[0].description = w0["description"].is() ? (const char*)w0["description"] : ""; + weathers[0].weatherId = String((int)w0["id"]); + weathers[0].icon = w0["icon"].is() ? (const char*)w0["icon"] : ""; + } else { + weathers[0].condition = ""; + weathers[0].description = ""; + weathers[0].weatherId = ""; + weathers[0].icon = ""; + } + + weathers[0].cached = false; + weathers[0].error = ""; + + Serial.println("[OWM] OK city=" + weathers[0].city + + " temp=" + weathers[0].temp + + " icon=" + weathers[0].icon); } + + String OpenWeatherMapClient::roundValue(String value) { float f = value.toFloat(); int rounded = (int)(f+0.5f); diff --git a/printermonitor/OpenWeatherMapClient.cpp.bak b/printermonitor/OpenWeatherMapClient.cpp.bak new file mode 100644 index 0000000..f7c66cd --- /dev/null +++ b/printermonitor/OpenWeatherMapClient.cpp.bak @@ -0,0 +1,311 @@ +/** 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, String language) { + updateCityIdList(CityIDs, cityCount); + updateLanguage(language); + myApiKey = ApiKey; + setMetric(isMetric); +} + +void OpenWeatherMapClient::updateWeatherApiKey(String ApiKey) { + myApiKey = ApiKey; +} + +void OpenWeatherMapClient::updateLanguage(String language) { + lang = language; + if (lang == "") { + lang = "es"; + } +} + +void OpenWeatherMapClient::updateWeather() { + WiFiClient weatherClient; + String apiGetData = "GET /data/2.5/group?id=" + myCityIDs + "&units=" + units + "&cnt=1&APPID=" + myApiKey + "&lang=" + lang + " HTTP/1.1"; + + Serial.println("Obteniendo datos de clima"); + 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("conexión fallida al obtener datos del clima"); //error message if no client connect + Serial.println(); + return; + } + + while(weatherClient.connected() && !weatherClient.available()) delay(1); //waits for data + + Serial.println("Esperando por datos"); + + // 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("Respuesta no válida")); + 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("Fallo al parsear los datos del clima!")); + weathers[0].error = "Fallo al parsear los datos del clima!"; + return; + } + + weatherClient.stop(); //stop client + + if (root.measureLength() <= 150) { + Serial.println("Error No parece que hayamos obtenido los datos. Tamaño: " + 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; +} diff --git a/printermonitor/OpenWeatherMapClient.h b/printermonitor/OpenWeatherMapClient.h old mode 100755 new mode 100644 diff --git a/printermonitor/RepetierClient.h b/printermonitor/RepetierClient.h old mode 100755 new mode 100644 diff --git a/printermonitor/TimeClient.cpp b/printermonitor/TimeClient.cpp old mode 100755 new mode 100644 diff --git a/printermonitor/TimeClient.h b/printermonitor/TimeClient.h old mode 100755 new mode 100644 diff --git a/printermonitor/WeatherStationFonts.h b/printermonitor/WeatherStationFonts.h old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/ArduinoJson.h b/printermonitor/libs/ArduinoJson/ArduinoJson.h old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/CHANGELOG.md b/printermonitor/libs/ArduinoJson/CHANGELOG.md old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/CMakeLists.txt b/printermonitor/libs/ArduinoJson/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/CONTRIBUTING.md b/printermonitor/libs/ArduinoJson/CONTRIBUTING.md old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/LICENSE.md b/printermonitor/libs/ArduinoJson/LICENSE.md old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/README.md b/printermonitor/libs/ArduinoJson/README.md old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/SUPPORT.md b/printermonitor/libs/ArduinoJson/SUPPORT.md old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/appveyor.yml b/printermonitor/libs/ArduinoJson/appveyor.yml old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/banner.svg b/printermonitor/libs/ArduinoJson/banner.svg old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/keywords.txt b/printermonitor/libs/ArduinoJson/keywords.txt old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson.h b/printermonitor/libs/ArduinoJson/src/ArduinoJson.h old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Configuration.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Configuration.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/Encoding.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/Encoding.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/JsonBufferAllocated.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/JsonBufferAllocated.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/JsonFloat.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/JsonFloat.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/JsonInteger.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/JsonInteger.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/JsonVariantAs.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/JsonVariantAs.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/JsonVariantContent.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/JsonVariantContent.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/JsonVariantDefault.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/JsonVariantDefault.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/JsonVariantType.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/JsonVariantType.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/List.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/List.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/ListConstIterator.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/ListConstIterator.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/ListIterator.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/ListIterator.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/ListNode.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/ListNode.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/NonCopyable.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/NonCopyable.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/ReferenceType.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/ReferenceType.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/ValueSaver.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Data/ValueSaver.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Deserialization/Comments.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Deserialization/Comments.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Deserialization/JsonParser.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Deserialization/JsonParser.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Deserialization/JsonParserImpl.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Deserialization/JsonParserImpl.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Deserialization/StringWriter.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Deserialization/StringWriter.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/DynamicJsonBuffer.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/DynamicJsonBuffer.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonArray.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonArray.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonArrayImpl.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonArrayImpl.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonArraySubscript.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonArraySubscript.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonBuffer.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonBuffer.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonBufferBase.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonBufferBase.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonBufferImpl.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonBufferImpl.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonObject.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonObject.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonObjectImpl.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonObjectImpl.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonObjectSubscript.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonObjectSubscript.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonPair.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonPair.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonVariant.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonVariant.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonVariantBase.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonVariantBase.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonVariantCasts.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonVariantCasts.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonVariantComparisons.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonVariantComparisons.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonVariantImpl.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonVariantImpl.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonVariantOr.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonVariantOr.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonVariantSubscripts.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/JsonVariantSubscripts.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Polyfills/attributes.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Polyfills/attributes.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Polyfills/ctype.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Polyfills/ctype.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Polyfills/isFloat.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Polyfills/isFloat.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Polyfills/isInteger.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Polyfills/isInteger.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Polyfills/math.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Polyfills/math.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Polyfills/parseFloat.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Polyfills/parseFloat.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Polyfills/parseInteger.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Polyfills/parseInteger.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/RawJson.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/RawJson.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/DummyPrint.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/DummyPrint.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/DynamicStringBuilder.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/DynamicStringBuilder.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/FloatParts.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/FloatParts.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/IndentedPrint.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/IndentedPrint.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/JsonPrintable.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/JsonPrintable.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/JsonSerializer.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/JsonSerializer.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/JsonSerializerImpl.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/JsonSerializerImpl.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/JsonWriter.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/JsonWriter.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/Prettyfier.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/Prettyfier.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/StaticStringBuilder.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/StaticStringBuilder.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/StreamPrintAdapter.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/Serialization/StreamPrintAdapter.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/StaticJsonBuffer.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/StaticJsonBuffer.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/StringTraits/ArduinoStream.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/StringTraits/ArduinoStream.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/StringTraits/CharPointer.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/StringTraits/CharPointer.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/StringTraits/FlashString.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/StringTraits/FlashString.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/StringTraits/StdStream.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/StringTraits/StdStream.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/StringTraits/StdString.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/StringTraits/StdString.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/StringTraits/StringTraits.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/StringTraits/StringTraits.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/EnableIf.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/EnableIf.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/FloatTraits.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/FloatTraits.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsArray.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsArray.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsBaseOf.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsBaseOf.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsChar.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsChar.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsConst.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsConst.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsIntegral.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsIntegral.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsSame.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsSame.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsVariant.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/IsVariant.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/RemoveConst.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/RemoveConst.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/RemoveReference.hpp b/printermonitor/libs/ArduinoJson/src/ArduinoJson/TypeTraits/RemoveReference.hpp old mode 100755 new mode 100644 diff --git a/printermonitor/printermonitor.ino b/printermonitor/printermonitor.ino index 27aa348..f91ac5e 100644 --- a/printermonitor/printermonitor.ino +++ b/printermonitor/printermonitor.ino @@ -24,14 +24,14 @@ SOFTWARE. // Additional Contributions: /* 15 Jan 2019 : Owen Carter : Add psucontrol option and processing */ /* 18 Feb 2022 : Robert von Könemann @vknmnn : Lets us select Moonraker + fix usage of AMPM/24Hrs time */ - +/* 17 Sep 2025 : Eduardo Romero @eduardorq : Fix Weather API request parse data and Spanish translation */ /********************************************** * Edit Settings.h for personalization ***********************************************/ #include "Settings.h" -#define VERSION "3.0" +#define VERSION "3.1" #define HOSTNAME "PrintMon-" #define CONFIG "/conf.txt" @@ -115,7 +115,7 @@ static const char WEB_ACTIONS[] PROGMEM = " Usar reloj 24 Horas

" "

Voltear la orientación de la pantalla

" "

Activar LED de WiFi

" @@ -577,10 +577,10 @@ void handleConfigure() { server.sendContent(html); CHANGE_FORM = "

Configuración:

" - "

" + "

" "

"; if (printerClient.getPrinterType() == "OctoPrint") { - CHANGE_FORM += "

"; + CHANGE_FORM += "

"; } CHANGE_FORM += "

" "

" @@ -855,8 +855,11 @@ void displayPrinterStatus() { } else { html += "

" + weatherClient.getCity(0) + ", " + weatherClient.getCountry(0) + "

"; html += "
"; - html += "" + weatherClient.getDescription(0) + "
"; - html += weatherClient.getHumidity(0) + "% Humedad
"; + html += "";
+      html += weatherClient.getDescription(0);
+      html += "
";html += weatherClient.getHumidity(0) + "% Humedad
"; html += weatherClient.getWind(0) + " " + getSpeedSymbol() + " Viento
"; html += "
"; html += "

"; diff --git a/printermonitor/printermonitor.ino.bak b/printermonitor/printermonitor.ino.bak new file mode 100644 index 0000000..77db194 --- /dev/null +++ b/printermonitor/printermonitor.ino.bak @@ -0,0 +1,1376 @@ +/** The MIT License (MIT) + +Copyright (c) 2018 David Payne + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +// Additional Contributions: +/* 15 Jan 2019 : Owen Carter : Add psucontrol option and processing */ +/* 18 Feb 2022 : Robert von Könemann @vknmnn : Lets us select Moonraker + fix usage of AMPM/24Hrs time */ +/* 17 Sep 2025 : Eduardo Romero @eduardorq : Fix Weather API request data and Spanish translation */ + /********************************************** + * Edit Settings.h for personalization + ***********************************************/ + +#include "Settings.h" + +#define VERSION "3.1" + +#define HOSTNAME "PrintMon-" +#define CONFIG "/conf.txt" + +/* Useful Constants */ +#define SECS_PER_MIN (60UL) +#define SECS_PER_HOUR (3600UL) + +/* Useful Macros for getting elapsed time */ +#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN) +#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN) +#define numberOfHours(_time_) (_time_ / SECS_PER_HOUR) + +// 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; + +// Printer Client +#if defined(USE_REPETIER_CLIENT) + RepetierClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); +#elif defined(USE_MOONRAKER_CLIENT) + MoonrakerClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); +#else + OctoPrintClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); +#endif +int printerCount = 0; + +// Weather Client +OpenWeatherMapClient weatherClient(WeatherApiKey, CityIDs, 1, IS_METRIC, WeatherLanguage); + +//declairing prototypes +void configModeCallback (WiFiManager *myWiFiManager); +int8_t getWifiQuality(); + +ESP8266WebServer server(WEBSERVER_PORT); +ESP8266HTTPUpdateServer serverUpdater; + +static const char WEB_ACTIONS[] PROGMEM = " Inicio" + " Configuración" + " Clima" + " Restablecer configuración" + " Olvidar WiFi" + " Actualizar Firmware" + " Sobre"; + +String CHANGE_FORM = ""; // moved to config to make it dynamic + +static const char CLOCK_FORM[] PROGMEM = "


Mostrar reloj cuando la impresora esté apagada

" + "

Usar reloj 24 Horas

" + "

Voltear la orientación de la pantalla

" + "

Activar LED de WiFi

" + "

Utilizar complemento de control OctoPrint PSU para reloj/blanco

" + "

Actualizar datos del clima

"; + +static const char THEME_FORM[] PROGMEM = "

Color de plantilla

" + "


" + "

Utilice credenciales de seguridad para cambios de configuración

" + "

" + "

" + ""; + +static const char WEATHER_FORM[] PROGMEM = "

Configuración del clima:

" + "

Mostrar el clima cuando la impresora está apagada

" + "" + "" + "

" + "

Usar Métrica (Celsius)

" + "

Idioma del clima

" + "
" + ""; + +static const char LANG_OPTIONS[] PROGMEM = "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; + +static const char COLOR_THEMES[] PROGMEM = "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; + + +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); + + //Some Defaults before loading from Config.txt + PrinterPort = printerClient.getPrinterPort(); + + readSettings(); + + // initialize display + display.init(); + if (INVERT_DISPLAY) { + display.flipScreenVertically(); // connections at top of OLED display + } + display.clear(); + display.display(); + + //display.flipScreenVertically(); + + display.setTextAlignment(TEXT_ALIGN_CENTER); + display.setContrast(255); // default is 255 + display.setFont(ArialMT_Plain_16); + display.drawString(64, 1, "Printer Monitor"); + display.setFont(ArialMT_Plain_10); + display.drawString(64, 18, "for " + printerClient.getPrinterType()); + display.setFont(ArialMT_Plain_16); + display.drawString(64, 30, "By Qrome"); + display.drawString(64, 46, "V" + 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("Intensidad de la señal (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("Autentificación fallida"); + else if (error == OTA_BEGIN_ERROR) Serial.println("Inicio fallido"); + else if (error == OTA_CONNECT_ERROR) Serial.println("Conexión fallida"); + else if (error == OTA_RECEIVE_ERROR) Serial.println("Recepción fallida"); + else if (error == OTA_END_ERROR) Serial.println("Finalización fallida"); + }); + 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); + serverUpdater.setup(&server, "/update", www_username, www_password); + // Start the server + server.begin(); + Serial.println("Servidor iniciado"); + // Print the IP address + String webAddress = "http://" + WiFi.localIP().toString() + ":" + String(WEBSERVER_PORT) + "/"; + Serial.println("Use esta URL : " + webAddress); + display.clear(); + display.setTextAlignment(TEXT_ALIGN_CENTER); + display.setFont(ArialMT_Plain_10); + display.drawString(64, 10, "Entorno web iniciado"); + display.drawString(64, 20, "Debe conectar a la IP"); + display.setFont(ArialMT_Plain_16); + display.drawString(64, 30, WiFi.localIP().toString()); + display.drawString(64, 46, "Puerto: " + String(WEBSERVER_PORT)); + display.display(); + } else { + Serial.println("Entorno web Deshabilitado"); + display.clear(); + display.setTextAlignment(TEXT_ALIGN_CENTER); + display.setFont(ArialMT_Plain_10); + display.drawString(64, 10, "Entorno web deshabilitado"); + display.drawString(64, 20, "Activado en Settings.h"); + display.display(); + } + flashLED(5, 100); + findMDNS(); //go find Printer Server by the hostname + Serial.println("*** Leaving setup()"); +} + +void findMDNS() { + if (PrinterHostName == "" || ENABLE_OTA == false) { + 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("sin servicio - compruebe que el servidor de la impresora esté encendido"); + return; + } + Serial.println("*** Buscando " + PrinterHostName + " en 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) == PrinterHostName) { + IPAddress serverIp = MDNS.IP(i); + PrinterServer = serverIp.toString(); + PrinterPort = MDNS.port(i); // save the port + Serial.println("*** Servidor de impresora encontrado " + PrinterHostName + " http://" + PrinterServer + ":" + PrinterPort); + writeSettings(); // update the settings + } + } +} + +//************************************************************ +// Main Loop +//************************************************************ +void loop() { + + //Get Time Update + if((getMinutesFromLastRefresh() >= minutesBetweenDataRefresh) || lastEpoch == 0) { + getUpdateTime(); + } + + if (lastMinute != timeClient.getMinutes() && !printerClient.isPrinting()) { + // Check status every 60 seconds + ledOnOff(true); + lastMinute = timeClient.getMinutes(); // reset the check value + printerClient.getPrinterJobResults(); + printerClient.getPrinterPsuState(); + ledOnOff(false); + } else if (printerClient.isPrinting()) { + if (lastSecond != timeClient.getSeconds() && timeClient.getSeconds().endsWith("0")) { + lastSecond = timeClient.getSeconds(); + // every 10 seconds while printing get an update + ledOnOff(true); + printerClient.getPrinterJobResults(); + printerClient.getPrinterPsuState(); + ledOnOff(false); + } + } + + 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() { + ledOnOff(true); // turn on the LED + Serial.println(); + + if (displayOn && DISPLAYWEATHER) { + Serial.println("Obteniendo datos del clima..."); + weatherClient.updateWeather(); + } + + Serial.println("Actualizando..."); + //Update the Time + timeClient.updateTime(); + lastEpoch = timeClient.getCurrentEpoch(); + + if (IS_24HOUR) { + Serial.println("Local time: " + timeClient.getFormattedTime()); + } else { + Serial.println("Local time: " + timeClient.getAmPmFormattedTime()); + } + + ledOnOff(false); // 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 (!authentication()) { + return server.requestAuthentication(); + } + Serial.println("Reiniciar configuración del sistema"); + if (SPIFFS.remove(CONFIG)) { + redirectHome(); + ESP.restart(); + } +} + +void handleUpdateWeather() { + if (!authentication()) { + return server.requestAuthentication(); + } + DISPLAYWEATHER = server.hasArg("isWeatherEnabled"); + WeatherApiKey = server.arg("openWeatherMapApiKey"); + CityIDs[0] = server.arg("city1").toInt(); + IS_METRIC = server.hasArg("metric"); + WeatherLanguage = server.arg("language"); + writeSettings(); + isClockOn = false; // this will force a check for the display + checkDisplay(); + lastEpoch = 0; + redirectHome(); +} + +void handleUpdateConfig() { + boolean flipOld = INVERT_DISPLAY; + if (!authentication()) { + return server.requestAuthentication(); + } + if (server.hasArg("printer")) { + printerClient.setPrinterName(server.arg("printer")); + } + PrinterApiKey = server.arg("PrinterApiKey"); + PrinterHostName = server.arg("PrinterHostName"); + PrinterServer = server.arg("PrinterAddress"); + PrinterPort = server.arg("PrinterPort").toInt(); + PrinterAuthUser = server.arg("octoUser"); + PrinterAuthPass = server.arg("octoPass"); + DISPLAYCLOCK = server.hasArg("isClockEnabled"); + IS_24HOUR = server.hasArg("is24hour"); + INVERT_DISPLAY = server.hasArg("invDisp"); + USE_FLASH = server.hasArg("useFlash"); + HAS_PSU = server.hasArg("hasPSU"); + 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(); + printerClient.getPrinterPsuState(); + if (INVERT_DISPLAY != flipOld) { + ui.init(); + if(INVERT_DISPLAY) + display.flipScreenVertically(); + ui.update(); + } + checkDisplay(); + lastEpoch = 0; + redirectHome(); +} + +void handleWifiReset() { + if (!authentication()) { + 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 (!authentication()) { + return server.requestAuthentication(); + } + ledOnOff(true); + 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 = FPSTR(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); + String options = FPSTR(LANG_OPTIONS); + options.replace(">"+String(WeatherLanguage)+"<", " selected>"+String(WeatherLanguage)+"<"); + form.replace("%LANGUAGEOPTIONS%", options); + server.sendContent(form); + + html = getFooter(); + server.sendContent(html); + server.sendContent(""); + server.client().stop(); + ledOnOff(false); +} + +void handleConfigure() { + if (!authentication()) { + return server.requestAuthentication(); + } + ledOnOff(true); + 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); + + CHANGE_FORM = "

Configuración:

" + "

" + "

"; + if (printerClient.getPrinterType() == "OctoPrint") { + CHANGE_FORM += "

"; + } + CHANGE_FORM += "

" + "

" + "

" + "

"; + if (printerClient.getPrinterType() == "Repetier") { + CHANGE_FORM += "" + "

" + ""; + } else { + CHANGE_FORM += "

"; + } + CHANGE_FORM += "

" + "

"; + + + + if (printerClient.getPrinterType() == "Repetier") { + html = ""; + + server.sendContent(html); + } else { + html = ""; + server.sendContent(html); + } + + String form = CHANGE_FORM; + + form.replace("%OCTOKEY%", PrinterApiKey); + form.replace("%OCTOHOST%", PrinterHostName); + form.replace("%OCTOADDRESS%", PrinterServer); + form.replace("%OCTOPORT%", String(PrinterPort)); + form.replace("%OCTOUSER%", PrinterAuthUser); + form.replace("%OCTOPASS%", PrinterAuthPass); + + server.sendContent(form); + + form = FPSTR(CLOCK_FORM); + + 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 isFlashLED = ""; + if (USE_FLASH) { + isFlashLED = "checked='checked'"; + } + form.replace("%USEFLASH%", isFlashLED); + String hasPSUchecked = ""; + if (HAS_PSU) { + hasPSUchecked = "checked='checked'"; + } + form.replace("%HAS_PSU_CHECKED%", hasPSUchecked); + + String options = ""; + options.replace(">"+String(minutesBetweenDataRefresh)+"<", " selected>"+String(minutesBetweenDataRefresh)+"<"); + form.replace("%OPTIONS%", options); + + server.sendContent(form); + + form = FPSTR(THEME_FORM); + + String themeOptions = FPSTR(COLOR_THEMES); + 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)); + + server.sendContent(form); + + html = getFooter(); + server.sendContent(html); + server.sendContent(""); + server.client().stop(); + ledOnOff(false); +} + +void displayMessage(String message) { + ledOnOff(true); + + 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(); + + ledOnOff(false); +} + +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 = FPSTR(WEB_ACTIONS); + + String html = ""; + html += "Printer Monitor"; + html += ""; + html += ""; + if (refresh) { + html += ""; + } + html += ""; + html += ""; + html += ""; + html += ""; + html += ""; + html += "

Printer Monitor

"; + html += ""; + html += "
"; + return html; +} + +String getFooter() { + int8_t rssi = getWifiQuality(); + Serial.print("Intensidad de la señal (RSSI): "); + Serial.print(rssi); + Serial.println("%"); + String html = "


"; + html += "
"; + html += "
"; + if (lastReportStatus != "") { + html += " Report Status: " + lastReportStatus + "
"; + } + html += " Version: " + String(VERSION) + "
"; + html += " Intensidad de la señal: "; + html += String(rssi) + "%"; + html += "
"; + html += ""; + return html; +} + +void displayPrinterStatus() { + ledOnOff(true); + 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; + if (IS_24HOUR) { + displayTime = timeClient.getHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds(); + } else { + displayTime = timeClient.getAmPmHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds() + " " + timeClient.getAmPm(); + } + + html += "

" + printerClient.getPrinterType() + " Monitor

"; + html += "

"; + if (printerClient.getPrinterType() == "Repetier") { + html += "Printer Name: " + printerClient.getPrinterName() + "
"; + } else { + html += "Nombre de host: " + PrinterHostName + "
"; + } + + if (printerClient.getError() != "") { + html += "Estado: Desconectado
"; + html += "Motivo: " + printerClient.getError() + "
"; + } else { + html += "Estado: " + printerClient.getState(); + if (printerClient.isPSUoff() && HAS_PSU) { + html += ", PSU off"; + } + html += "
"; + } + + 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 += "Filamento: " + String(fLength) + "m
"; + } + + html += "Temperatura boquilla: " + printerClient.getTempToolActual() + "° C
"; + if ( printerClient.getTempBedActual() != 0 ) { + html += "Temperatura cama: " + printerClient.getTempBedActual() + "° C
"; + } + + int val = printerClient.getProgressPrintTimeLeft().toInt(); + int hours = numberOfHours(val); + int minutes = numberOfMinutes(val); + int seconds = numberOfSeconds(val); + html += "Est. Print Time Left: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "
"; + + val = printerClient.getProgressPrintTime().toInt(); + hours = numberOfHours(val); + minutes = numberOfMinutes(val); + seconds = numberOfSeconds(val); + html += "Tiempo imprimiendo: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "
"; + html += ""; + html += "

" + printerClient.getProgressCompletion() + "%
"; + } else { + html += "
"; + } + + html += "

"; + + html += "

Hora: " + displayTime + "

"; + + server.sendContent(html); // spit out what we got + html = ""; + + if (DISPLAYWEATHER) { + if (weatherClient.getCity(0) == "") { + html += "

Por favor Configure clima API

"; + if (weatherClient.getError() != "") { + html += "

Clima Error: " + weatherClient.getError() + "

"; + } + } else { + html += "

" + weatherClient.getCity(0) + ", " + weatherClient.getCountry(0) + "

"; + html += "
"; + html += "" + weatherClient.getDescription(0) + "
"; + html += weatherClient.getHumidity(0) + "% Humedad
"; + html += weatherClient.getWind(0) + " " + getSpeedSymbol() + " Viento
"; + 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(); + ledOnOff(false); +} + +void configModeCallback (WiFiManager *myWiFiManager) { + Serial.println("Modo configuración"); + Serial.println(WiFi.softAPIP()); + + display.clear(); + display.setTextAlignment(TEXT_ALIGN_CENTER); + display.setFont(ArialMT_Plain_10); + display.drawString(64, 0, "Configure la Wifi"); + display.drawString(64, 10, "Conecte al punto de acceso"); + display.setFont(ArialMT_Plain_16); + display.drawString(64, 26, myWiFiManager->getConfigPortalSSID()); + display.setFont(ArialMT_Plain_10); + display.drawString(64, 46, "y configure la wifi"); + display.display(); + + Serial.println("Configure en Monitor"); + Serial.println("Conecte al punto de acceso"); + Serial.println(myWiFiManager->getConfigPortalSSID()); + Serial.println("y configure la wifi"); + flashLED(20, 50); +} + +void ledOnOff(boolean value) { + if (USE_FLASH) { + if (value) { + digitalWrite(externalLight, LOW); // LED ON + } else { + digitalWrite(externalLight, HIGH); // LED OFF + } + } +} + +void flashLED(int number, int delayTime) { + for (int inx = 0; inx <= number; inx++) { + delay(delayTime); + digitalWrite(externalLight, LOW); // ON + delay(delayTime); + digitalWrite(externalLight, HIGH); // OFF + delay(delayTime); + } +} + +void drawScreen1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { + String bed = printerClient.getValueRounded(printerClient.getTempBedActual()); + String tool = printerClient.getValueRounded(printerClient.getTempToolActual()); + display->setTextAlignment(TEXT_ALIGN_CENTER); + display->setFont(ArialMT_Plain_16); + if (bed != "0") { + display->drawString(29 + x, 0 + y, "Boquilla"); + display->drawString(89 + x, 0 + y, "Cama"); + } else { + display->drawString(64 + x, 0 + y, "Temperatura boquilla"); + } + display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(ArialMT_Plain_24); + if (bed != "0") { + display->setTextAlignment(TEXT_ALIGN_LEFT); + display->drawString(12 + x, 14 + y, tool + "°"); + display->drawString(74 + x, 14 + y, bed + "°"); + } else { + display->setTextAlignment(TEXT_ALIGN_CENTER); + display->drawString(64 + x, 14 + y, tool + "°"); + } +} + +void 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, "Tiempo restante"); + //display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(ArialMT_Plain_24); + int val = printerClient.getProgressPrintTimeLeft().toInt(); + int hours = numberOfHours(val); + int minutes = numberOfMinutes(val); + int seconds = numberOfSeconds(val); + + String time = zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds); + display->drawString(64 + x, 14 + y, time); +} + +void 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, "Tiempo impresión"); + //display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(ArialMT_Plain_24); + int val = printerClient.getProgressPrintTime().toInt(); + int hours = numberOfHours(val); + int minutes = numberOfMinutes(val); + int seconds = numberOfSeconds(val); + + String time = zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds); + display->drawString(64 + x, 14 + y, time); +} + +void drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { + display->setTextAlignment(TEXT_ALIGN_CENTER); + + String displayTime; + if (IS_24HOUR) { + displayTime = timeClient.getHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds(); + } else { + displayTime = timeClient.getAmPmHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds(); + } + String displayName = PrinterHostName; + if (printerClient.getPrinterType() == "Repetier") { + displayName = printerClient.getPrinterName(); + } + display->setFont(ArialMT_Plain_16); + display->drawString(64 + x, 0 + y, displayName); + display->setFont(ArialMT_Plain_24); + display->drawString(64 + x, 17 + y, displayTime); +} + +void 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; + if (IS_24HOUR) { + displayTime = timeClient.getHours() + ":" + timeClient.getMinutes(); + } else { + displayTime = timeClient.getAmPmHours() + ":" + 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); + if (printerClient.isPSUoff()) { + display->drawString(64, 47, "psu off"); + } else if (printerClient.getState() == "Operational") { + display->drawString(64, 47, "Conectado"); + } else { + display->drawString(64, 47, "Desconectado"); + } + } else { + if (printerClient.isPSUoff()) { + display->drawString(0, 47, "psu off"); + } else if (printerClient.getState() == "Operational") { + display->drawString(0, 47, "Conectado"); + } else { + display->drawString(0, 47, "Desconectado"); + } + } + 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("Falló al abrir el archivo!"); + } else { + Serial.println("Guardando configuración..."); + f.println("UtcOffset=" + String(UtcOffset)); + f.println("printerApiKey=" + PrinterApiKey); + f.println("printerHostName=" + PrinterHostName); + f.println("printerServer=" + PrinterServer); + f.println("printerPort=" + String(PrinterPort)); + f.println("printerName=" + printerClient.getPrinterName()); + f.println("printerAuthUser=" + PrinterAuthUser); + f.println("printerAuthPass=" + PrinterAuthPass); + 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)); + f.println("is24hour=" + String(IS_24HOUR)); + f.println("invertDisp=" + String(INVERT_DISPLAY)); + f.println("USE_FLASH=" + String(USE_FLASH)); + f.println("isWeather=" + String(DISPLAYWEATHER)); + f.println("weatherKey=" + WeatherApiKey); + f.println("CityID=" + String(CityIDs[0])); + f.println("isMetric=" + String(IS_METRIC)); + f.println("language=" + String(WeatherLanguage)); + f.println("hasPSU=" + String(HAS_PSU)); + } + 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("printerApiKey=") >= 0) { + PrinterApiKey = line.substring(line.lastIndexOf("printerApiKey=") + 14); + PrinterApiKey.trim(); + Serial.println("PrinterApiKey=" + PrinterApiKey); + } + if (line.indexOf("printerHostName=") >= 0) { + PrinterHostName = line.substring(line.lastIndexOf("printerHostName=") + 16); + PrinterHostName.trim(); + Serial.println("PrinterHostName=" + PrinterHostName); + } + if (line.indexOf("printerServer=") >= 0) { + PrinterServer = line.substring(line.lastIndexOf("printerServer=") + 14); + PrinterServer.trim(); + Serial.println("PrinterServer=" + PrinterServer); + } + if (line.indexOf("printerPort=") >= 0) { + PrinterPort = line.substring(line.lastIndexOf("printerPort=") + 12).toInt(); + Serial.println("PrinterPort=" + String(PrinterPort)); + } + if (line.indexOf("printerName=") >= 0) { + String printer = line.substring(line.lastIndexOf("printerName=") + 12); + printer.trim(); + printerClient.setPrinterName(printer); + Serial.println("PrinterName=" + printerClient.getPrinterName()); + } + if (line.indexOf("printerAuthUser=") >= 0) { + PrinterAuthUser = line.substring(line.lastIndexOf("printerAuthUser=") + 16); + PrinterAuthUser.trim(); + Serial.println("PrinterAuthUser=" + PrinterAuthUser); + } + if (line.indexOf("printerAuthPass=") >= 0) { + PrinterAuthPass = line.substring(line.lastIndexOf("printerAuthPass=") + 16); + PrinterAuthPass.trim(); + Serial.println("PrinterAuthPass=" + PrinterAuthPass); + } + 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("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(); + 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("USE_FLASH=") >= 0) { + USE_FLASH = line.substring(line.lastIndexOf("USE_FLASH=") + 10).toInt(); + Serial.println("USE_FLASH=" + String(USE_FLASH)); + } + if (line.indexOf("hasPSU=") >= 0) { + HAS_PSU = line.substring(line.lastIndexOf("hasPSU=") + 7).toInt(); + Serial.println("HAS_PSU=" + String(HAS_PSU)); + } + 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)); + } + if (line.indexOf("language=") >= 0) { + WeatherLanguage = line.substring(line.lastIndexOf("language=") + 9); + WeatherLanguage.trim(); + Serial.println("WeatherLanguage=" + WeatherLanguage); + } + } + fr.close(); + printerClient.updatePrintClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); + weatherClient.updateWeatherApiKey(WeatherApiKey); + weatherClient.updateLanguage(WeatherLanguage); + 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.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, "Apagando impresora\nModo hibernación..."); + display.display(); + delay(5000); + enableDisplay(false); + Serial.println("Impresora apagada..."); + 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, "Impresora encendido\nEncendiendo..."); + display.display(); + Serial.println("Impresora encendida..."); + delay(5000); + return; + } + } else if (DISPLAYCLOCK) { + if ((!printerClient.isPrinting() || printerClient.isPSUoff()) && !isClockOn) { + Serial.println("Modo reloj."); + 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.isPrinting() && !printerClient.isPSUoff() && isClockOn) { + Serial.println("Monito de impresora activado."); + 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("Pantalla encendida: " + timeClient.getFormattedTime()); + } else { + display.displayOff(); + Serial.println("Pantalla apagada: " + timeClient.getFormattedTime()); + displayOffEpoch = lastEpoch; + } +}