From 696faf4f9f6699615bd8d217a3052da44c241829 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Sun, 21 Sep 2025 15:41:22 +0100 Subject: [PATCH] Add translations --- printermonitor/I18N.cpp | 162 +++ printermonitor/I18N.h | 55 + printermonitor/OpenWeatherMapClient.cpp.bak | 311 ----- printermonitor/Settings.h | 3 + printermonitor/data/i18n/de.json | 122 ++ printermonitor/data/i18n/en.json | 122 ++ printermonitor/data/i18n/es.json | 122 ++ printermonitor/data/i18n/fr.json | 122 ++ printermonitor/data/i18n/it.json | 122 ++ printermonitor/data/i18n/ja.json | 122 ++ printermonitor/data/i18n/ko.json | 122 ++ printermonitor/data/i18n/nl.json | 122 ++ printermonitor/data/i18n/no.json | 122 ++ printermonitor/data/i18n/pt.json | 122 ++ printermonitor/data/i18n/ru.json | 122 ++ printermonitor/data/i18n/uk.json | 122 ++ printermonitor/data/i18n/zh.json | 122 ++ printermonitor/printermonitor.ino | 350 +++-- printermonitor/printermonitor.ino.bak | 1376 ------------------- 19 files changed, 2025 insertions(+), 1818 deletions(-) create mode 100644 printermonitor/I18N.cpp create mode 100644 printermonitor/I18N.h delete mode 100644 printermonitor/OpenWeatherMapClient.cpp.bak create mode 100644 printermonitor/data/i18n/de.json create mode 100644 printermonitor/data/i18n/en.json create mode 100644 printermonitor/data/i18n/es.json create mode 100644 printermonitor/data/i18n/fr.json create mode 100644 printermonitor/data/i18n/it.json create mode 100644 printermonitor/data/i18n/ja.json create mode 100644 printermonitor/data/i18n/ko.json create mode 100644 printermonitor/data/i18n/nl.json create mode 100644 printermonitor/data/i18n/no.json create mode 100644 printermonitor/data/i18n/pt.json create mode 100644 printermonitor/data/i18n/ru.json create mode 100644 printermonitor/data/i18n/uk.json create mode 100644 printermonitor/data/i18n/zh.json delete mode 100644 printermonitor/printermonitor.ino.bak diff --git a/printermonitor/I18N.cpp b/printermonitor/I18N.cpp new file mode 100644 index 0000000..39be51b --- /dev/null +++ b/printermonitor/I18N.cpp @@ -0,0 +1,162 @@ +/** 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: +/* 17 Sep 2025 : Eduardo Romero @eduardorq : Add translations */ + +#include "I18N.h" + +String I18N::s_lang = "en"; +String I18N::s_json = ""; + +static void replaceAllInPlace(String& s, const String& from, const String& to) { + if (from.length() == 0) return; + int idx = 0; + while ((idx = s.indexOf(from, idx)) >= 0) { + s = s.substring(0, idx) + to + s.substring(idx + from.length()); + idx += to.length(); + } +} + +static inline bool isSpace(char c) { + return c==' ' || c=='\t' || c=='\r' || c=='\n'; +} + +// Devuelve el path /i18n/.json +String I18N::pathFor(const String& lang) { + String l = lang; l.trim(); + if (l.length() == 0) l = "en"; + return String("/i18n/") + l + ".json"; +} + +bool I18N::findKV(const String& key, String& outVal) { + if (s_json.length() == 0) return false; + + String needle = "\"" + key + "\""; + int pos = s_json.indexOf(needle); + if (pos < 0) return false; + + pos += needle.length(); + while (pos < (int)s_json.length() && isSpace(s_json[pos])) pos++; + if (pos >= (int)s_json.length() || s_json[pos] != ':') return false; + pos++; + while (pos < (int)s_json.length() && isSpace(s_json[pos])) pos++; + if (pos >= (int)s_json.length() || s_json[pos] != '\"') return false; + pos++; // dentro del valor + + String val; + bool escaped = false; + for (; pos < (int)s_json.length(); ++pos) { + char c = s_json[pos]; + if (escaped) { + val += c; + escaped = false; + } else { + if (c == '\\') { + escaped = true; + } else if (c == '\"') { + outVal = val; + return true; + } else { + val += c; + } + } + } + return false; +} + +// Carga /i18n/.json desde SPIFFS +bool I18N::load(const String& langCode) { + String path = pathFor(langCode); + File f = SPIFFS.open(path, "r"); + if (!f) { + Serial.println(I18N::t("i18n.file.cant_open") + path); + return false; + } + + s_json = ""; + const size_t CHUNK = 512; + std::unique_ptr buf(new char[CHUNK + 1]); + while (true) { + size_t n = f.readBytes(buf.get(), CHUNK); + if (n == 0) break; + buf[n] = '\0'; + s_json += buf.get(); + if (s_json.length() > 32768) { // límite de seguridad + break; + } + } + f.close(); + + s_lang = langCode; + Serial.println(I18N::t("i18n.file.loaded") + path + " (" + String(s_json.length()) + " bytes)"); + return (s_json.length() > 0); +} + +String I18N::t(const String& key) { + String out; + if (findKV(key, out)) return out; + return key; // fallback +} + +bool I18N::has(const String& key) { + String tmp; + return findKV(key, tmp); +} + +String I18N::tr(const String& key, const String pairs[][2], size_t count) { + String base = t(key); + for (size_t i = 0; i < count; ++i) { + String ph = "{" + String(pairs[i][0]) + "}"; + replaceAllInPlace(base, ph, pairs[i][1]); + } + return base; +} + +// Sustituye tokens {{ clave }} dentro de una cadena. +// Si no existe la clave, deja el token. +void I18N::apply(String& s) { + int start = 0; + while (true) { + int open = s.indexOf("{{", start); + if (open < 0) break; + int close = s.indexOf("}}", open + 2); + if (close < 0) break; + + String key = s.substring(open + 2, close); + key.trim(); + + String val = I18N::t(key); + if (val.length() == 0 || val == key) { + start = close + 2; // sin traducción, saltar + continue; + } + + s = s.substring(0, open) + val + s.substring(close + 2); + start = open + val.length(); + } +} + +String I18N::current() { + return s_lang; +} diff --git a/printermonitor/I18N.h b/printermonitor/I18N.h new file mode 100644 index 0000000..7802ca6 --- /dev/null +++ b/printermonitor/I18N.h @@ -0,0 +1,55 @@ +/** 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: +/* 17 Sep 2025 : Eduardo Romero @eduardorq : Add translations */ + +#pragma once +#include +#include + +class I18N { +public: + // Load /i18n/.json (p.ej. "es" => "/i18n/es.json") + static bool load(const String& langCode); + + static String t(const String& key); + + // With placeholders: pairs = {{"printer","Ender3"},{"value","42"}} + static String tr(const String& key, const String pairs[][2], size_t count); + + static bool has(const String& key); + + static void apply(String& s); + + static String current(); + +private: + // Estado interno + static String s_lang; + static String s_json; + + // Utilidades internas + static String pathFor(const String& lang); + static bool findKV(const String& key, String& outVal); +}; diff --git a/printermonitor/OpenWeatherMapClient.cpp.bak b/printermonitor/OpenWeatherMapClient.cpp.bak deleted file mode 100644 index f7c66cd..0000000 --- a/printermonitor/OpenWeatherMapClient.cpp.bak +++ /dev/null @@ -1,311 +0,0 @@ -/** 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/Settings.h b/printermonitor/Settings.h index ceca414..df801c4 100644 --- a/printermonitor/Settings.h +++ b/printermonitor/Settings.h @@ -115,3 +115,6 @@ String OTA_Password = ""; // Set an OTA password here -- leave blank if you //****************************** String themeColor = "light-blue"; // this can be changed later in the web interface. + +// Idioma de la interfaz (web + OLED). Valores: en, es, fr, de, it, zh, ja, nl, no, pt, ru, uk, ko +String UiLanguage = "en"; diff --git a/printermonitor/data/i18n/de.json b/printermonitor/data/i18n/de.json new file mode 100644 index 0000000..f7c2227 --- /dev/null +++ b/printermonitor/data/i18n/de.json @@ -0,0 +1,122 @@ +{ + "app.by": "By Qrome", + "app.file.setup.notexist": "Settings File does not yet exists.", + "app.for": "for {name}", + "app.reset_settings": "Reset settings", + "app.setup.mode": "Setup mode", + "app.setup.openfile": "Can't open file", + "app.setup.save.settings": "Saving settings...", + "app.title": "Printer Monitor", + "app.version": "Version", + "app.web.disabled": "Web UI disabled", + "app.web.enable_in_settings": "Enable it in Settings.h", + "app.web.must_connect": "Connect to this IP", + "app.web.port": "Port", + "app.web.started": "Web UI started", + "btn.configure": "Configure", + "cfg.clock.show_when_off": "Show clock when printer is off", + "cfg.clock.use_24h": "Use 24-hour clock", + "cfg.display.flip": "Flip display orientation", + "cfg.display.off": "Display off", + "cfg.display.on": "Dispclay on", + "cfg.header": "Settings:", + "cfg.monitor.activated": "Printer monitor activated.", + "cfg.printer.api_key": "API Key (from ", + "cfg.printer.hostname": "Hostname", + "cfg.printer.ip": "IP (no http://)", + "cfg.printer.pass": "Password", + "cfg.printer.port": "Port", + "cfg.printer.user": "Username (for haproxy or basic auth)", + "cfg.psu.use": "Use OctoPrint PSU Control for clock/blank", + "cfg.save": "Save", + "cfg.security.password": "Password", + "cfg.security.use_basic": "Use security credentials for changes", + "cfg.security.user_id": "User ID (for this UI)", + "cfg.settings.ui_language": "Language", + "cfg.setup.ap": "Connect to acces point", + "cfg.setup.monitor": "Setup in monitor", + "cfg.setup.repetier_title": "Repetier", + "cfg.setup.wifi": "Wifi setup", + "cfg.setup.wifi2": "and setup wifi", + "cfg.test.conn": "Test connection", + "cfg.test.conn_json": "Test connection + JSON API response", + "cfg.theme.color": "Theme color", + "cfg.timezone": "Timezone", + "cfg.weather.refresh": "Weather refresh", + "cfg.wifi.led": "WiFi LED", + "clock.local_time": "Local time: ", + "clock.time": "Time", + "clock.updating": "Updating...", + "filament.m": "Filament", + "file": "File", + "file.size_kb": "File Size", + "hostname": "Hostname", + "i18n.file.cant_open": "[I18N] Can't open file: ", + "i18n.file.loaded": "[I18N] File loaded: ", + "map.it": "Map It!", + "mdns.in_mdns": " in mDNS", + "mdns.not_service": "No service, check that the printer server is on", + "mdns.printer_serve.found": "*** Printer server found ", + "mdns.searching": "*** Searching ", + "menu.about": "About", + "menu.configure": "Settings", + "menu.forget_wifi": "Forget WiFi", + "menu.home": "Home", + "menu.reset": "Factory reset", + "menu.title": "Menu", + "menu.update": "Update firmware", + "menu.weather": "Weather", + "ota.end": "End", + "ota.error.auth": "Auth error", + "ota.error.begin": "Begin error", + "ota.error.connect": "Connect error", + "ota.error.end": "End error", + "ota.error.receive": "Receive error", + "ota.progress": "Progress", + "ota.start": "Start", + "printer.monitor": "Printer Monitor", + "psu.off": "psu off", + "reason": "Reason", + "state.connected": "Connected", + "state.disconnected": "Disconnected", + "state.operational": "Operational", + "status": "Status", + "temp.bed": "Bed Temp", + "temp.nozzle": "Nozzle Temp", + "time.left": "Time Left", + "time.printed": "Time Printed", + "time.printing": "Printing Time", + "time.remaining": "Est. Print Time Left", + "ui.bed": "Bed", + "ui.bed_temp_title": "Bed Temp", + "ui.clock.mode": "Clock mode.", + "ui.connecting": "Connecting...", + "ui.nozzle": "Nozzle", + "ui.nozzle_temp_title": "Nozzle Temp", + "ui.printer.mode": "Printer monitor ON.", + "ui.printer_off": "Printer Off", + "ui.printer_on": "Printer On", + "ui.tool_temp_title": "Tool Temp", + "ui.turning_off": "Turning off printer\nSleep mode...", + "ui.turning_on": "Printer on\nWaking up...", + "wcfg.api_key.label": "OpenWeatherMap API Key (get it ", + "wcfg.api_key.label_here": "here", + "wcfg.city_id.label": "Location ID", + "wcfg.city_id.search": "Find location ID", + "wcfg.header": "Weather settings:", + "wcfg.language": "Weather language", + "wcfg.metric": "Use Metric (Celsius)", + "wcfg.show_when_off": "Show weather when printer is off", + "weather.city_label": "City", + "weather.condition": "Condition", + "weather.configure_link": "Configure Weather", + "weather.error": "Weather Error", + "weather.feels_like": "Feels like", + "weather.get_data": "Obtaining weather data...", + "weather.humidity": "Humidity", + "weather.please": "Please", + "weather.wind": "Wind", + "web.hostname": "Hostname", + "web.printername": "Printer name", + "wifi.signal": "Signal strength" +} \ No newline at end of file diff --git a/printermonitor/data/i18n/en.json b/printermonitor/data/i18n/en.json new file mode 100644 index 0000000..02ea04c --- /dev/null +++ b/printermonitor/data/i18n/en.json @@ -0,0 +1,122 @@ +{ + "app.title": "Printer Monitor", + "app.for": "for {name}", + "app.by": "By Qrome", + "app.version": "Version", + "app.web.started": "Web UI started", + "app.web.must_connect": "Connect to this IP", + "app.web.port": "Port", + "app.web.disabled": "Web UI disabled", + "app.web.enable_in_settings": "Enable it in Settings.h", + "menu.title": "Menu", + "menu.home": "Home", + "menu.configure": "Settings", + "menu.weather": "Weather", + "menu.reset": "Factory reset", + "menu.forget_wifi": "Forget WiFi", + "menu.update": "Update firmware", + "menu.about": "About", + "printer.monitor": "Printer Monitor", + "hostname": "Hostname", + "status": "Status", + "reason": "Reason", + "state.connected": "Connected", + "state.disconnected": "Disconnected", + "state.operational": "Operational", + "psu.off": "psu off", + "file": "File", + "file.size_kb": "File Size", + "filament.m": "Filament", + "temp.nozzle": "Nozzle Temp", + "temp.bed": "Bed Temp", + "time.remaining": "Est. Print Time Left", + "time.printing": "Printing Time", + "time.left": "Time Left", + "time.printed": "Time Printed", + "clock.time": "Time", + "weather.city_label": "City", + "weather.humidity": "Humidity", + "weather.wind": "Wind", + "weather.feels_like": "Feels like", + "weather.condition": "Condition", + "weather.configure_link": "Configure Weather", + "weather.error": "Weather Error", + "weather.please": "Please", + "map.it": "Map It!", + "ui.nozzle": "Nozzle", + "ui.bed": "Bed", + "ui.nozzle_temp_title": "Nozzle Temp", + "ui.bed_temp_title": "Bed Temp", + "ui.tool_temp_title": "Tool Temp", + "ui.connecting": "Connecting...", + "cfg.header": "Settings:", + "cfg.printer.api_key": "API Key (from ", + "cfg.printer.hostname": "Hostname", + "cfg.printer.ip": "IP (no http://)", + "cfg.printer.port": "Port", + "cfg.printer.user": "Username (for haproxy or basic auth)", + "cfg.printer.pass": "Password", + "cfg.settings.ui_language": "Language", + "cfg.test.conn": "Test connection", + "cfg.test.conn_json": "Test connection + JSON API response", + "cfg.clock.show_when_off": "Show clock when printer is off", + "cfg.clock.use_24h": "Use 24-hour clock", + "cfg.display.flip": "Flip display orientation", + "cfg.wifi.led": "WiFi LED", + "cfg.psu.use": "Use OctoPrint PSU Control for clock/blank", + "cfg.weather.refresh": "Weather refresh", + "cfg.theme.color": "Theme color", + "cfg.timezone": "Timezone", + "cfg.security.use_basic": "Use security credentials for changes", + "cfg.security.user_id": "User ID (for this UI)", + "cfg.security.password": "Password", + "cfg.setup.wifi": "Wifi setup", + "cfg.setup.wifi2": "and setup wifi", + "cfg.setup.ap": "Connect to acces point", + "cfg.setup.repetier_title": "Repetier", + "cfg.save": "Save", + "wcfg.header": "Weather settings:", + "wcfg.show_when_off": "Show weather when printer is off", + "wcfg.api_key.label": "OpenWeatherMap API Key (get it ", + "wcfg.api_key.label_here": "here", + "wcfg.city_id.label": "Location ID", + "wcfg.city_id.search": "Find location ID", + "wcfg.metric": "Use Metric (Celsius)", + "wcfg.language": "Weather language", + "wifi.signal": "Signal strength", + "ui.turning_off": "Turning off printer\nSleep mode...", + "ui.printer_off": "Printer Off", + "ui.printer_on": "Printer On", + "ui.turning_on": "Printer on\nWaking up...", + "ui.clock.mode": "Clock mode.", + "ui.printer.mode": "Printer monitor ON.", + "web.hostname": "Hostname", + "web.printername": "Printer name", + "btn.configure": "Configure", + "i18n.file.cant_open": "[I18N] Can't open file: ", + "i18n.file.loaded": "[I18N] File loaded: ", + "app.setup.mode": "Setup mode", + "app.setup.openfile": "Can't open file", + "app.setup.save.settings": "Saving settings...", + "app.file.setup.notexist": "Settings File does not yet exists.", + "cfg.setup.monitor": "Setup in monitor", + "cfg.monitor.activated": "Printer monitor activated.", + "cfg.display.on": "Dispclay on", + "cfg.display.off": "Display off", + "ota.start": "Start", + "ota.end": "End", + "ota.progress": "Progress", + "ota.error.auth": "Auth error", + "ota.error.begin": "Begin error", + "ota.error.connect": "Connect error", + "ota.error.receive": "Receive error", + "ota.error.end": "End error", + "mdns.not_service": "No service, check that the printer server is on", + "mdns.in_mdns": " in mDNS", + "mdns.searching": "*** Searching ", + "mdns.printer_serve.found": "*** Printer server found ", + "weather.get_data": "Obtaining weather data...", + "clock.updating": "Updating...", + "clock.local_time": "Local time: ", + "app.reset_settings": "Reset settings" +} diff --git a/printermonitor/data/i18n/es.json b/printermonitor/data/i18n/es.json new file mode 100644 index 0000000..f28bf4f --- /dev/null +++ b/printermonitor/data/i18n/es.json @@ -0,0 +1,122 @@ +{ + "app.by": "Por Qrome", + "app.file.setup.notexist": "El archivo de configuración aún no existe.", + "app.for": "por {name}", + "app.reset_settings": "Restablecer configuración", + "app.setup.mode": "Modo configuración", + "app.setup.openfile": "No se puede abrir el archivo", + "app.setup.save.settings": "Guardando configuración...", + "app.title": "Monitor de Impresora", + "app.version": "Versión", + "app.web.disabled": "Interfaz web deshabilitada", + "app.web.enable_in_settings": "Actívela en Settings.h", + "app.web.must_connect": "Conéctese a esta IP", + "app.web.port": "Puerto", + "app.web.started": "Interfaz web iniciada", + "btn.configure": "Configuración", + "cfg.clock.show_when_off": "Mostrar reloj cuando la impresora esté apagada", + "cfg.clock.use_24h": "Usar formato 24 horas", + "cfg.display.flip": "Voltear orientación de pantalla", + "cfg.display.off": "Pantalla apagada", + "cfg.display.on": "Pantalla encendida", + "cfg.header": "Configuración:", + "cfg.monitor.activated": "Monitor de impresora activado.", + "cfg.printer.api_key": "API Key (from ", + "cfg.printer.hostname": "Nombre de host", + "cfg.printer.ip": "IP (sin http://)", + "cfg.printer.pass": "Contraseña", + "cfg.printer.port": "Puerto", + "cfg.printer.user": "Usuario (para haproxy o auth básica)", + "cfg.psu.use": "Usar PSU Control de OctoPrint para reloj/negro", + "cfg.save": "Guardar", + "cfg.security.password": "Contraseña", + "cfg.security.use_basic": "Use credenciales de seguridad para cambios", + "cfg.security.user_id": "ID de usuario (para este acceso)", + "cfg.settings.ui_language": "Idioma", + "cfg.setup.ap": "Conectar al punto de acceso", + "cfg.setup.monitor": "Configuración en monitor", + "cfg.setup.repetier_title": "Repetidor", + "cfg.setup.wifi": "Configuración wifi", + "cfg.setup.wifi2": "y configuración wifi", + "cfg.test.conn": "Probar conexión", + "cfg.test.conn_json": "Prueba de conexión + respuesta JSON de la API", + "cfg.theme.color": "Color del tema", + "cfg.timezone": "Huso horario", + "cfg.weather.refresh": "Refrescar clima", + "cfg.wifi.led": "WiFi LED", + "clock.local_time": "Hora local: ", + "clock.time": "Hora", + "clock.updating": "Actualizando...", + "filament.m": "Filamento", + "file": "Archivo", + "file.size_kb": "Tamaño de archivo", + "hostname": "Nombre de host", + "i18n.file.cant_open": "[I18N] No se puede abrir fichero: ", + "i18n.file.loaded": "[I18N] Fichero cargado: ", + "map.it": "Abrir mapa", + "mdns.in_mdns": " en mDNS", + "mdns.not_service": "Sin servicio, compruebe si su servidor de impresora está encendido", + "mdns.printer_serve.found": "*** Servidor de impresora encontrado ", + "mdns.searching": "*** Buscando ", + "menu.about": "Acerca de", + "menu.configure": "Configuración", + "menu.forget_wifi": "Olvidar WiFi", + "menu.home": "Inicio", + "menu.reset": "Resetear", + "menu.title": "Menú", + "menu.update": "Actualizar firmware", + "menu.weather": "Clima", + "ota.end": "Fianaliza", + "ota.error.auth": "Error de autentificación", + "ota.error.begin": "Error deinicio", + "ota.error.connect": "Error de conexión", + "ota.error.end": "Error de finalizado", + "ota.error.receive": "Error de recepción", + "ota.progress": "Progreso", + "ota.start": "Inicio", + "printer.monitor": "Monitor de Impresora", + "psu.off": "psu off", + "reason": "Motivo", + "state.connected": "Conectado", + "state.disconnected": "Desconectado", + "state.operational": "Operacional", + "status": "Estado", + "temp.bed": "Temp. de cama", + "temp.nozzle": "Temp. de extrusor", + "time.left": "Tiempo restante", + "time.printed": "Tiempo impreso", + "time.printing": "Tiempo imrpimiendo", + "time.remaining": "Tiempo estimado pdte.", + "ui.bed": "Cama", + "ui.bed_temp_title": "Temp. Cama", + "ui.clock.mode": "Modo reloj.", + "ui.connecting": "Conectando...", + "ui.nozzle": "Boquilla", + "ui.nozzle_temp_title": "Temp. Extrusor", + "ui.printer.mode": "Monito de imrpesora encendido.", + "ui.printer_off": "Impresora apagada", + "ui.printer_on": "Impresora encendida", + "ui.tool_temp_title": "Tool Temp", + "ui.turning_off": "Apagando impresora\nModo suspensión...", + "ui.turning_on": "Encendiendo impresora\nDespertando...", + "wcfg.api_key.label": "OpenWeatherMap API Key (conseguir ", + "wcfg.api_key.label_here": "aquí", + "wcfg.city_id.label": "ID de ciudad", + "wcfg.city_id.search": "Encontrar ID de ciudad", + "wcfg.header": "Configuración de clima:", + "wcfg.language": "Idioma del clima", + "wcfg.metric": "Usar Métrico (Celsius)", + "wcfg.show_when_off": "Mostrar el clima cuando la impresora esté apagada", + "weather.city_label": "Ciudad", + "weather.condition": "Estimación", + "weather.configure_link": "Configurar clima", + "weather.error": "Error del clima", + "weather.feels_like": "Sensación térmica", + "weather.get_data": "Obteniendo datos climatológicos...", + "weather.humidity": "Humedad", + "weather.please": "Por favor", + "weather.wind": "Viento", + "web.hostname": "Nombre de host", + "web.printername": "Nombre de impresora", + "wifi.signal": "Intensidad de la señal" +} diff --git a/printermonitor/data/i18n/fr.json b/printermonitor/data/i18n/fr.json new file mode 100644 index 0000000..f7c2227 --- /dev/null +++ b/printermonitor/data/i18n/fr.json @@ -0,0 +1,122 @@ +{ + "app.by": "By Qrome", + "app.file.setup.notexist": "Settings File does not yet exists.", + "app.for": "for {name}", + "app.reset_settings": "Reset settings", + "app.setup.mode": "Setup mode", + "app.setup.openfile": "Can't open file", + "app.setup.save.settings": "Saving settings...", + "app.title": "Printer Monitor", + "app.version": "Version", + "app.web.disabled": "Web UI disabled", + "app.web.enable_in_settings": "Enable it in Settings.h", + "app.web.must_connect": "Connect to this IP", + "app.web.port": "Port", + "app.web.started": "Web UI started", + "btn.configure": "Configure", + "cfg.clock.show_when_off": "Show clock when printer is off", + "cfg.clock.use_24h": "Use 24-hour clock", + "cfg.display.flip": "Flip display orientation", + "cfg.display.off": "Display off", + "cfg.display.on": "Dispclay on", + "cfg.header": "Settings:", + "cfg.monitor.activated": "Printer monitor activated.", + "cfg.printer.api_key": "API Key (from ", + "cfg.printer.hostname": "Hostname", + "cfg.printer.ip": "IP (no http://)", + "cfg.printer.pass": "Password", + "cfg.printer.port": "Port", + "cfg.printer.user": "Username (for haproxy or basic auth)", + "cfg.psu.use": "Use OctoPrint PSU Control for clock/blank", + "cfg.save": "Save", + "cfg.security.password": "Password", + "cfg.security.use_basic": "Use security credentials for changes", + "cfg.security.user_id": "User ID (for this UI)", + "cfg.settings.ui_language": "Language", + "cfg.setup.ap": "Connect to acces point", + "cfg.setup.monitor": "Setup in monitor", + "cfg.setup.repetier_title": "Repetier", + "cfg.setup.wifi": "Wifi setup", + "cfg.setup.wifi2": "and setup wifi", + "cfg.test.conn": "Test connection", + "cfg.test.conn_json": "Test connection + JSON API response", + "cfg.theme.color": "Theme color", + "cfg.timezone": "Timezone", + "cfg.weather.refresh": "Weather refresh", + "cfg.wifi.led": "WiFi LED", + "clock.local_time": "Local time: ", + "clock.time": "Time", + "clock.updating": "Updating...", + "filament.m": "Filament", + "file": "File", + "file.size_kb": "File Size", + "hostname": "Hostname", + "i18n.file.cant_open": "[I18N] Can't open file: ", + "i18n.file.loaded": "[I18N] File loaded: ", + "map.it": "Map It!", + "mdns.in_mdns": " in mDNS", + "mdns.not_service": "No service, check that the printer server is on", + "mdns.printer_serve.found": "*** Printer server found ", + "mdns.searching": "*** Searching ", + "menu.about": "About", + "menu.configure": "Settings", + "menu.forget_wifi": "Forget WiFi", + "menu.home": "Home", + "menu.reset": "Factory reset", + "menu.title": "Menu", + "menu.update": "Update firmware", + "menu.weather": "Weather", + "ota.end": "End", + "ota.error.auth": "Auth error", + "ota.error.begin": "Begin error", + "ota.error.connect": "Connect error", + "ota.error.end": "End error", + "ota.error.receive": "Receive error", + "ota.progress": "Progress", + "ota.start": "Start", + "printer.monitor": "Printer Monitor", + "psu.off": "psu off", + "reason": "Reason", + "state.connected": "Connected", + "state.disconnected": "Disconnected", + "state.operational": "Operational", + "status": "Status", + "temp.bed": "Bed Temp", + "temp.nozzle": "Nozzle Temp", + "time.left": "Time Left", + "time.printed": "Time Printed", + "time.printing": "Printing Time", + "time.remaining": "Est. Print Time Left", + "ui.bed": "Bed", + "ui.bed_temp_title": "Bed Temp", + "ui.clock.mode": "Clock mode.", + "ui.connecting": "Connecting...", + "ui.nozzle": "Nozzle", + "ui.nozzle_temp_title": "Nozzle Temp", + "ui.printer.mode": "Printer monitor ON.", + "ui.printer_off": "Printer Off", + "ui.printer_on": "Printer On", + "ui.tool_temp_title": "Tool Temp", + "ui.turning_off": "Turning off printer\nSleep mode...", + "ui.turning_on": "Printer on\nWaking up...", + "wcfg.api_key.label": "OpenWeatherMap API Key (get it ", + "wcfg.api_key.label_here": "here", + "wcfg.city_id.label": "Location ID", + "wcfg.city_id.search": "Find location ID", + "wcfg.header": "Weather settings:", + "wcfg.language": "Weather language", + "wcfg.metric": "Use Metric (Celsius)", + "wcfg.show_when_off": "Show weather when printer is off", + "weather.city_label": "City", + "weather.condition": "Condition", + "weather.configure_link": "Configure Weather", + "weather.error": "Weather Error", + "weather.feels_like": "Feels like", + "weather.get_data": "Obtaining weather data...", + "weather.humidity": "Humidity", + "weather.please": "Please", + "weather.wind": "Wind", + "web.hostname": "Hostname", + "web.printername": "Printer name", + "wifi.signal": "Signal strength" +} \ No newline at end of file diff --git a/printermonitor/data/i18n/it.json b/printermonitor/data/i18n/it.json new file mode 100644 index 0000000..f7c2227 --- /dev/null +++ b/printermonitor/data/i18n/it.json @@ -0,0 +1,122 @@ +{ + "app.by": "By Qrome", + "app.file.setup.notexist": "Settings File does not yet exists.", + "app.for": "for {name}", + "app.reset_settings": "Reset settings", + "app.setup.mode": "Setup mode", + "app.setup.openfile": "Can't open file", + "app.setup.save.settings": "Saving settings...", + "app.title": "Printer Monitor", + "app.version": "Version", + "app.web.disabled": "Web UI disabled", + "app.web.enable_in_settings": "Enable it in Settings.h", + "app.web.must_connect": "Connect to this IP", + "app.web.port": "Port", + "app.web.started": "Web UI started", + "btn.configure": "Configure", + "cfg.clock.show_when_off": "Show clock when printer is off", + "cfg.clock.use_24h": "Use 24-hour clock", + "cfg.display.flip": "Flip display orientation", + "cfg.display.off": "Display off", + "cfg.display.on": "Dispclay on", + "cfg.header": "Settings:", + "cfg.monitor.activated": "Printer monitor activated.", + "cfg.printer.api_key": "API Key (from ", + "cfg.printer.hostname": "Hostname", + "cfg.printer.ip": "IP (no http://)", + "cfg.printer.pass": "Password", + "cfg.printer.port": "Port", + "cfg.printer.user": "Username (for haproxy or basic auth)", + "cfg.psu.use": "Use OctoPrint PSU Control for clock/blank", + "cfg.save": "Save", + "cfg.security.password": "Password", + "cfg.security.use_basic": "Use security credentials for changes", + "cfg.security.user_id": "User ID (for this UI)", + "cfg.settings.ui_language": "Language", + "cfg.setup.ap": "Connect to acces point", + "cfg.setup.monitor": "Setup in monitor", + "cfg.setup.repetier_title": "Repetier", + "cfg.setup.wifi": "Wifi setup", + "cfg.setup.wifi2": "and setup wifi", + "cfg.test.conn": "Test connection", + "cfg.test.conn_json": "Test connection + JSON API response", + "cfg.theme.color": "Theme color", + "cfg.timezone": "Timezone", + "cfg.weather.refresh": "Weather refresh", + "cfg.wifi.led": "WiFi LED", + "clock.local_time": "Local time: ", + "clock.time": "Time", + "clock.updating": "Updating...", + "filament.m": "Filament", + "file": "File", + "file.size_kb": "File Size", + "hostname": "Hostname", + "i18n.file.cant_open": "[I18N] Can't open file: ", + "i18n.file.loaded": "[I18N] File loaded: ", + "map.it": "Map It!", + "mdns.in_mdns": " in mDNS", + "mdns.not_service": "No service, check that the printer server is on", + "mdns.printer_serve.found": "*** Printer server found ", + "mdns.searching": "*** Searching ", + "menu.about": "About", + "menu.configure": "Settings", + "menu.forget_wifi": "Forget WiFi", + "menu.home": "Home", + "menu.reset": "Factory reset", + "menu.title": "Menu", + "menu.update": "Update firmware", + "menu.weather": "Weather", + "ota.end": "End", + "ota.error.auth": "Auth error", + "ota.error.begin": "Begin error", + "ota.error.connect": "Connect error", + "ota.error.end": "End error", + "ota.error.receive": "Receive error", + "ota.progress": "Progress", + "ota.start": "Start", + "printer.monitor": "Printer Monitor", + "psu.off": "psu off", + "reason": "Reason", + "state.connected": "Connected", + "state.disconnected": "Disconnected", + "state.operational": "Operational", + "status": "Status", + "temp.bed": "Bed Temp", + "temp.nozzle": "Nozzle Temp", + "time.left": "Time Left", + "time.printed": "Time Printed", + "time.printing": "Printing Time", + "time.remaining": "Est. Print Time Left", + "ui.bed": "Bed", + "ui.bed_temp_title": "Bed Temp", + "ui.clock.mode": "Clock mode.", + "ui.connecting": "Connecting...", + "ui.nozzle": "Nozzle", + "ui.nozzle_temp_title": "Nozzle Temp", + "ui.printer.mode": "Printer monitor ON.", + "ui.printer_off": "Printer Off", + "ui.printer_on": "Printer On", + "ui.tool_temp_title": "Tool Temp", + "ui.turning_off": "Turning off printer\nSleep mode...", + "ui.turning_on": "Printer on\nWaking up...", + "wcfg.api_key.label": "OpenWeatherMap API Key (get it ", + "wcfg.api_key.label_here": "here", + "wcfg.city_id.label": "Location ID", + "wcfg.city_id.search": "Find location ID", + "wcfg.header": "Weather settings:", + "wcfg.language": "Weather language", + "wcfg.metric": "Use Metric (Celsius)", + "wcfg.show_when_off": "Show weather when printer is off", + "weather.city_label": "City", + "weather.condition": "Condition", + "weather.configure_link": "Configure Weather", + "weather.error": "Weather Error", + "weather.feels_like": "Feels like", + "weather.get_data": "Obtaining weather data...", + "weather.humidity": "Humidity", + "weather.please": "Please", + "weather.wind": "Wind", + "web.hostname": "Hostname", + "web.printername": "Printer name", + "wifi.signal": "Signal strength" +} \ No newline at end of file diff --git a/printermonitor/data/i18n/ja.json b/printermonitor/data/i18n/ja.json new file mode 100644 index 0000000..f7c2227 --- /dev/null +++ b/printermonitor/data/i18n/ja.json @@ -0,0 +1,122 @@ +{ + "app.by": "By Qrome", + "app.file.setup.notexist": "Settings File does not yet exists.", + "app.for": "for {name}", + "app.reset_settings": "Reset settings", + "app.setup.mode": "Setup mode", + "app.setup.openfile": "Can't open file", + "app.setup.save.settings": "Saving settings...", + "app.title": "Printer Monitor", + "app.version": "Version", + "app.web.disabled": "Web UI disabled", + "app.web.enable_in_settings": "Enable it in Settings.h", + "app.web.must_connect": "Connect to this IP", + "app.web.port": "Port", + "app.web.started": "Web UI started", + "btn.configure": "Configure", + "cfg.clock.show_when_off": "Show clock when printer is off", + "cfg.clock.use_24h": "Use 24-hour clock", + "cfg.display.flip": "Flip display orientation", + "cfg.display.off": "Display off", + "cfg.display.on": "Dispclay on", + "cfg.header": "Settings:", + "cfg.monitor.activated": "Printer monitor activated.", + "cfg.printer.api_key": "API Key (from ", + "cfg.printer.hostname": "Hostname", + "cfg.printer.ip": "IP (no http://)", + "cfg.printer.pass": "Password", + "cfg.printer.port": "Port", + "cfg.printer.user": "Username (for haproxy or basic auth)", + "cfg.psu.use": "Use OctoPrint PSU Control for clock/blank", + "cfg.save": "Save", + "cfg.security.password": "Password", + "cfg.security.use_basic": "Use security credentials for changes", + "cfg.security.user_id": "User ID (for this UI)", + "cfg.settings.ui_language": "Language", + "cfg.setup.ap": "Connect to acces point", + "cfg.setup.monitor": "Setup in monitor", + "cfg.setup.repetier_title": "Repetier", + "cfg.setup.wifi": "Wifi setup", + "cfg.setup.wifi2": "and setup wifi", + "cfg.test.conn": "Test connection", + "cfg.test.conn_json": "Test connection + JSON API response", + "cfg.theme.color": "Theme color", + "cfg.timezone": "Timezone", + "cfg.weather.refresh": "Weather refresh", + "cfg.wifi.led": "WiFi LED", + "clock.local_time": "Local time: ", + "clock.time": "Time", + "clock.updating": "Updating...", + "filament.m": "Filament", + "file": "File", + "file.size_kb": "File Size", + "hostname": "Hostname", + "i18n.file.cant_open": "[I18N] Can't open file: ", + "i18n.file.loaded": "[I18N] File loaded: ", + "map.it": "Map It!", + "mdns.in_mdns": " in mDNS", + "mdns.not_service": "No service, check that the printer server is on", + "mdns.printer_serve.found": "*** Printer server found ", + "mdns.searching": "*** Searching ", + "menu.about": "About", + "menu.configure": "Settings", + "menu.forget_wifi": "Forget WiFi", + "menu.home": "Home", + "menu.reset": "Factory reset", + "menu.title": "Menu", + "menu.update": "Update firmware", + "menu.weather": "Weather", + "ota.end": "End", + "ota.error.auth": "Auth error", + "ota.error.begin": "Begin error", + "ota.error.connect": "Connect error", + "ota.error.end": "End error", + "ota.error.receive": "Receive error", + "ota.progress": "Progress", + "ota.start": "Start", + "printer.monitor": "Printer Monitor", + "psu.off": "psu off", + "reason": "Reason", + "state.connected": "Connected", + "state.disconnected": "Disconnected", + "state.operational": "Operational", + "status": "Status", + "temp.bed": "Bed Temp", + "temp.nozzle": "Nozzle Temp", + "time.left": "Time Left", + "time.printed": "Time Printed", + "time.printing": "Printing Time", + "time.remaining": "Est. Print Time Left", + "ui.bed": "Bed", + "ui.bed_temp_title": "Bed Temp", + "ui.clock.mode": "Clock mode.", + "ui.connecting": "Connecting...", + "ui.nozzle": "Nozzle", + "ui.nozzle_temp_title": "Nozzle Temp", + "ui.printer.mode": "Printer monitor ON.", + "ui.printer_off": "Printer Off", + "ui.printer_on": "Printer On", + "ui.tool_temp_title": "Tool Temp", + "ui.turning_off": "Turning off printer\nSleep mode...", + "ui.turning_on": "Printer on\nWaking up...", + "wcfg.api_key.label": "OpenWeatherMap API Key (get it ", + "wcfg.api_key.label_here": "here", + "wcfg.city_id.label": "Location ID", + "wcfg.city_id.search": "Find location ID", + "wcfg.header": "Weather settings:", + "wcfg.language": "Weather language", + "wcfg.metric": "Use Metric (Celsius)", + "wcfg.show_when_off": "Show weather when printer is off", + "weather.city_label": "City", + "weather.condition": "Condition", + "weather.configure_link": "Configure Weather", + "weather.error": "Weather Error", + "weather.feels_like": "Feels like", + "weather.get_data": "Obtaining weather data...", + "weather.humidity": "Humidity", + "weather.please": "Please", + "weather.wind": "Wind", + "web.hostname": "Hostname", + "web.printername": "Printer name", + "wifi.signal": "Signal strength" +} \ No newline at end of file diff --git a/printermonitor/data/i18n/ko.json b/printermonitor/data/i18n/ko.json new file mode 100644 index 0000000..f7c2227 --- /dev/null +++ b/printermonitor/data/i18n/ko.json @@ -0,0 +1,122 @@ +{ + "app.by": "By Qrome", + "app.file.setup.notexist": "Settings File does not yet exists.", + "app.for": "for {name}", + "app.reset_settings": "Reset settings", + "app.setup.mode": "Setup mode", + "app.setup.openfile": "Can't open file", + "app.setup.save.settings": "Saving settings...", + "app.title": "Printer Monitor", + "app.version": "Version", + "app.web.disabled": "Web UI disabled", + "app.web.enable_in_settings": "Enable it in Settings.h", + "app.web.must_connect": "Connect to this IP", + "app.web.port": "Port", + "app.web.started": "Web UI started", + "btn.configure": "Configure", + "cfg.clock.show_when_off": "Show clock when printer is off", + "cfg.clock.use_24h": "Use 24-hour clock", + "cfg.display.flip": "Flip display orientation", + "cfg.display.off": "Display off", + "cfg.display.on": "Dispclay on", + "cfg.header": "Settings:", + "cfg.monitor.activated": "Printer monitor activated.", + "cfg.printer.api_key": "API Key (from ", + "cfg.printer.hostname": "Hostname", + "cfg.printer.ip": "IP (no http://)", + "cfg.printer.pass": "Password", + "cfg.printer.port": "Port", + "cfg.printer.user": "Username (for haproxy or basic auth)", + "cfg.psu.use": "Use OctoPrint PSU Control for clock/blank", + "cfg.save": "Save", + "cfg.security.password": "Password", + "cfg.security.use_basic": "Use security credentials for changes", + "cfg.security.user_id": "User ID (for this UI)", + "cfg.settings.ui_language": "Language", + "cfg.setup.ap": "Connect to acces point", + "cfg.setup.monitor": "Setup in monitor", + "cfg.setup.repetier_title": "Repetier", + "cfg.setup.wifi": "Wifi setup", + "cfg.setup.wifi2": "and setup wifi", + "cfg.test.conn": "Test connection", + "cfg.test.conn_json": "Test connection + JSON API response", + "cfg.theme.color": "Theme color", + "cfg.timezone": "Timezone", + "cfg.weather.refresh": "Weather refresh", + "cfg.wifi.led": "WiFi LED", + "clock.local_time": "Local time: ", + "clock.time": "Time", + "clock.updating": "Updating...", + "filament.m": "Filament", + "file": "File", + "file.size_kb": "File Size", + "hostname": "Hostname", + "i18n.file.cant_open": "[I18N] Can't open file: ", + "i18n.file.loaded": "[I18N] File loaded: ", + "map.it": "Map It!", + "mdns.in_mdns": " in mDNS", + "mdns.not_service": "No service, check that the printer server is on", + "mdns.printer_serve.found": "*** Printer server found ", + "mdns.searching": "*** Searching ", + "menu.about": "About", + "menu.configure": "Settings", + "menu.forget_wifi": "Forget WiFi", + "menu.home": "Home", + "menu.reset": "Factory reset", + "menu.title": "Menu", + "menu.update": "Update firmware", + "menu.weather": "Weather", + "ota.end": "End", + "ota.error.auth": "Auth error", + "ota.error.begin": "Begin error", + "ota.error.connect": "Connect error", + "ota.error.end": "End error", + "ota.error.receive": "Receive error", + "ota.progress": "Progress", + "ota.start": "Start", + "printer.monitor": "Printer Monitor", + "psu.off": "psu off", + "reason": "Reason", + "state.connected": "Connected", + "state.disconnected": "Disconnected", + "state.operational": "Operational", + "status": "Status", + "temp.bed": "Bed Temp", + "temp.nozzle": "Nozzle Temp", + "time.left": "Time Left", + "time.printed": "Time Printed", + "time.printing": "Printing Time", + "time.remaining": "Est. Print Time Left", + "ui.bed": "Bed", + "ui.bed_temp_title": "Bed Temp", + "ui.clock.mode": "Clock mode.", + "ui.connecting": "Connecting...", + "ui.nozzle": "Nozzle", + "ui.nozzle_temp_title": "Nozzle Temp", + "ui.printer.mode": "Printer monitor ON.", + "ui.printer_off": "Printer Off", + "ui.printer_on": "Printer On", + "ui.tool_temp_title": "Tool Temp", + "ui.turning_off": "Turning off printer\nSleep mode...", + "ui.turning_on": "Printer on\nWaking up...", + "wcfg.api_key.label": "OpenWeatherMap API Key (get it ", + "wcfg.api_key.label_here": "here", + "wcfg.city_id.label": "Location ID", + "wcfg.city_id.search": "Find location ID", + "wcfg.header": "Weather settings:", + "wcfg.language": "Weather language", + "wcfg.metric": "Use Metric (Celsius)", + "wcfg.show_when_off": "Show weather when printer is off", + "weather.city_label": "City", + "weather.condition": "Condition", + "weather.configure_link": "Configure Weather", + "weather.error": "Weather Error", + "weather.feels_like": "Feels like", + "weather.get_data": "Obtaining weather data...", + "weather.humidity": "Humidity", + "weather.please": "Please", + "weather.wind": "Wind", + "web.hostname": "Hostname", + "web.printername": "Printer name", + "wifi.signal": "Signal strength" +} \ No newline at end of file diff --git a/printermonitor/data/i18n/nl.json b/printermonitor/data/i18n/nl.json new file mode 100644 index 0000000..f7c2227 --- /dev/null +++ b/printermonitor/data/i18n/nl.json @@ -0,0 +1,122 @@ +{ + "app.by": "By Qrome", + "app.file.setup.notexist": "Settings File does not yet exists.", + "app.for": "for {name}", + "app.reset_settings": "Reset settings", + "app.setup.mode": "Setup mode", + "app.setup.openfile": "Can't open file", + "app.setup.save.settings": "Saving settings...", + "app.title": "Printer Monitor", + "app.version": "Version", + "app.web.disabled": "Web UI disabled", + "app.web.enable_in_settings": "Enable it in Settings.h", + "app.web.must_connect": "Connect to this IP", + "app.web.port": "Port", + "app.web.started": "Web UI started", + "btn.configure": "Configure", + "cfg.clock.show_when_off": "Show clock when printer is off", + "cfg.clock.use_24h": "Use 24-hour clock", + "cfg.display.flip": "Flip display orientation", + "cfg.display.off": "Display off", + "cfg.display.on": "Dispclay on", + "cfg.header": "Settings:", + "cfg.monitor.activated": "Printer monitor activated.", + "cfg.printer.api_key": "API Key (from ", + "cfg.printer.hostname": "Hostname", + "cfg.printer.ip": "IP (no http://)", + "cfg.printer.pass": "Password", + "cfg.printer.port": "Port", + "cfg.printer.user": "Username (for haproxy or basic auth)", + "cfg.psu.use": "Use OctoPrint PSU Control for clock/blank", + "cfg.save": "Save", + "cfg.security.password": "Password", + "cfg.security.use_basic": "Use security credentials for changes", + "cfg.security.user_id": "User ID (for this UI)", + "cfg.settings.ui_language": "Language", + "cfg.setup.ap": "Connect to acces point", + "cfg.setup.monitor": "Setup in monitor", + "cfg.setup.repetier_title": "Repetier", + "cfg.setup.wifi": "Wifi setup", + "cfg.setup.wifi2": "and setup wifi", + "cfg.test.conn": "Test connection", + "cfg.test.conn_json": "Test connection + JSON API response", + "cfg.theme.color": "Theme color", + "cfg.timezone": "Timezone", + "cfg.weather.refresh": "Weather refresh", + "cfg.wifi.led": "WiFi LED", + "clock.local_time": "Local time: ", + "clock.time": "Time", + "clock.updating": "Updating...", + "filament.m": "Filament", + "file": "File", + "file.size_kb": "File Size", + "hostname": "Hostname", + "i18n.file.cant_open": "[I18N] Can't open file: ", + "i18n.file.loaded": "[I18N] File loaded: ", + "map.it": "Map It!", + "mdns.in_mdns": " in mDNS", + "mdns.not_service": "No service, check that the printer server is on", + "mdns.printer_serve.found": "*** Printer server found ", + "mdns.searching": "*** Searching ", + "menu.about": "About", + "menu.configure": "Settings", + "menu.forget_wifi": "Forget WiFi", + "menu.home": "Home", + "menu.reset": "Factory reset", + "menu.title": "Menu", + "menu.update": "Update firmware", + "menu.weather": "Weather", + "ota.end": "End", + "ota.error.auth": "Auth error", + "ota.error.begin": "Begin error", + "ota.error.connect": "Connect error", + "ota.error.end": "End error", + "ota.error.receive": "Receive error", + "ota.progress": "Progress", + "ota.start": "Start", + "printer.monitor": "Printer Monitor", + "psu.off": "psu off", + "reason": "Reason", + "state.connected": "Connected", + "state.disconnected": "Disconnected", + "state.operational": "Operational", + "status": "Status", + "temp.bed": "Bed Temp", + "temp.nozzle": "Nozzle Temp", + "time.left": "Time Left", + "time.printed": "Time Printed", + "time.printing": "Printing Time", + "time.remaining": "Est. Print Time Left", + "ui.bed": "Bed", + "ui.bed_temp_title": "Bed Temp", + "ui.clock.mode": "Clock mode.", + "ui.connecting": "Connecting...", + "ui.nozzle": "Nozzle", + "ui.nozzle_temp_title": "Nozzle Temp", + "ui.printer.mode": "Printer monitor ON.", + "ui.printer_off": "Printer Off", + "ui.printer_on": "Printer On", + "ui.tool_temp_title": "Tool Temp", + "ui.turning_off": "Turning off printer\nSleep mode...", + "ui.turning_on": "Printer on\nWaking up...", + "wcfg.api_key.label": "OpenWeatherMap API Key (get it ", + "wcfg.api_key.label_here": "here", + "wcfg.city_id.label": "Location ID", + "wcfg.city_id.search": "Find location ID", + "wcfg.header": "Weather settings:", + "wcfg.language": "Weather language", + "wcfg.metric": "Use Metric (Celsius)", + "wcfg.show_when_off": "Show weather when printer is off", + "weather.city_label": "City", + "weather.condition": "Condition", + "weather.configure_link": "Configure Weather", + "weather.error": "Weather Error", + "weather.feels_like": "Feels like", + "weather.get_data": "Obtaining weather data...", + "weather.humidity": "Humidity", + "weather.please": "Please", + "weather.wind": "Wind", + "web.hostname": "Hostname", + "web.printername": "Printer name", + "wifi.signal": "Signal strength" +} \ No newline at end of file diff --git a/printermonitor/data/i18n/no.json b/printermonitor/data/i18n/no.json new file mode 100644 index 0000000..f7c2227 --- /dev/null +++ b/printermonitor/data/i18n/no.json @@ -0,0 +1,122 @@ +{ + "app.by": "By Qrome", + "app.file.setup.notexist": "Settings File does not yet exists.", + "app.for": "for {name}", + "app.reset_settings": "Reset settings", + "app.setup.mode": "Setup mode", + "app.setup.openfile": "Can't open file", + "app.setup.save.settings": "Saving settings...", + "app.title": "Printer Monitor", + "app.version": "Version", + "app.web.disabled": "Web UI disabled", + "app.web.enable_in_settings": "Enable it in Settings.h", + "app.web.must_connect": "Connect to this IP", + "app.web.port": "Port", + "app.web.started": "Web UI started", + "btn.configure": "Configure", + "cfg.clock.show_when_off": "Show clock when printer is off", + "cfg.clock.use_24h": "Use 24-hour clock", + "cfg.display.flip": "Flip display orientation", + "cfg.display.off": "Display off", + "cfg.display.on": "Dispclay on", + "cfg.header": "Settings:", + "cfg.monitor.activated": "Printer monitor activated.", + "cfg.printer.api_key": "API Key (from ", + "cfg.printer.hostname": "Hostname", + "cfg.printer.ip": "IP (no http://)", + "cfg.printer.pass": "Password", + "cfg.printer.port": "Port", + "cfg.printer.user": "Username (for haproxy or basic auth)", + "cfg.psu.use": "Use OctoPrint PSU Control for clock/blank", + "cfg.save": "Save", + "cfg.security.password": "Password", + "cfg.security.use_basic": "Use security credentials for changes", + "cfg.security.user_id": "User ID (for this UI)", + "cfg.settings.ui_language": "Language", + "cfg.setup.ap": "Connect to acces point", + "cfg.setup.monitor": "Setup in monitor", + "cfg.setup.repetier_title": "Repetier", + "cfg.setup.wifi": "Wifi setup", + "cfg.setup.wifi2": "and setup wifi", + "cfg.test.conn": "Test connection", + "cfg.test.conn_json": "Test connection + JSON API response", + "cfg.theme.color": "Theme color", + "cfg.timezone": "Timezone", + "cfg.weather.refresh": "Weather refresh", + "cfg.wifi.led": "WiFi LED", + "clock.local_time": "Local time: ", + "clock.time": "Time", + "clock.updating": "Updating...", + "filament.m": "Filament", + "file": "File", + "file.size_kb": "File Size", + "hostname": "Hostname", + "i18n.file.cant_open": "[I18N] Can't open file: ", + "i18n.file.loaded": "[I18N] File loaded: ", + "map.it": "Map It!", + "mdns.in_mdns": " in mDNS", + "mdns.not_service": "No service, check that the printer server is on", + "mdns.printer_serve.found": "*** Printer server found ", + "mdns.searching": "*** Searching ", + "menu.about": "About", + "menu.configure": "Settings", + "menu.forget_wifi": "Forget WiFi", + "menu.home": "Home", + "menu.reset": "Factory reset", + "menu.title": "Menu", + "menu.update": "Update firmware", + "menu.weather": "Weather", + "ota.end": "End", + "ota.error.auth": "Auth error", + "ota.error.begin": "Begin error", + "ota.error.connect": "Connect error", + "ota.error.end": "End error", + "ota.error.receive": "Receive error", + "ota.progress": "Progress", + "ota.start": "Start", + "printer.monitor": "Printer Monitor", + "psu.off": "psu off", + "reason": "Reason", + "state.connected": "Connected", + "state.disconnected": "Disconnected", + "state.operational": "Operational", + "status": "Status", + "temp.bed": "Bed Temp", + "temp.nozzle": "Nozzle Temp", + "time.left": "Time Left", + "time.printed": "Time Printed", + "time.printing": "Printing Time", + "time.remaining": "Est. Print Time Left", + "ui.bed": "Bed", + "ui.bed_temp_title": "Bed Temp", + "ui.clock.mode": "Clock mode.", + "ui.connecting": "Connecting...", + "ui.nozzle": "Nozzle", + "ui.nozzle_temp_title": "Nozzle Temp", + "ui.printer.mode": "Printer monitor ON.", + "ui.printer_off": "Printer Off", + "ui.printer_on": "Printer On", + "ui.tool_temp_title": "Tool Temp", + "ui.turning_off": "Turning off printer\nSleep mode...", + "ui.turning_on": "Printer on\nWaking up...", + "wcfg.api_key.label": "OpenWeatherMap API Key (get it ", + "wcfg.api_key.label_here": "here", + "wcfg.city_id.label": "Location ID", + "wcfg.city_id.search": "Find location ID", + "wcfg.header": "Weather settings:", + "wcfg.language": "Weather language", + "wcfg.metric": "Use Metric (Celsius)", + "wcfg.show_when_off": "Show weather when printer is off", + "weather.city_label": "City", + "weather.condition": "Condition", + "weather.configure_link": "Configure Weather", + "weather.error": "Weather Error", + "weather.feels_like": "Feels like", + "weather.get_data": "Obtaining weather data...", + "weather.humidity": "Humidity", + "weather.please": "Please", + "weather.wind": "Wind", + "web.hostname": "Hostname", + "web.printername": "Printer name", + "wifi.signal": "Signal strength" +} \ No newline at end of file diff --git a/printermonitor/data/i18n/pt.json b/printermonitor/data/i18n/pt.json new file mode 100644 index 0000000..f7c2227 --- /dev/null +++ b/printermonitor/data/i18n/pt.json @@ -0,0 +1,122 @@ +{ + "app.by": "By Qrome", + "app.file.setup.notexist": "Settings File does not yet exists.", + "app.for": "for {name}", + "app.reset_settings": "Reset settings", + "app.setup.mode": "Setup mode", + "app.setup.openfile": "Can't open file", + "app.setup.save.settings": "Saving settings...", + "app.title": "Printer Monitor", + "app.version": "Version", + "app.web.disabled": "Web UI disabled", + "app.web.enable_in_settings": "Enable it in Settings.h", + "app.web.must_connect": "Connect to this IP", + "app.web.port": "Port", + "app.web.started": "Web UI started", + "btn.configure": "Configure", + "cfg.clock.show_when_off": "Show clock when printer is off", + "cfg.clock.use_24h": "Use 24-hour clock", + "cfg.display.flip": "Flip display orientation", + "cfg.display.off": "Display off", + "cfg.display.on": "Dispclay on", + "cfg.header": "Settings:", + "cfg.monitor.activated": "Printer monitor activated.", + "cfg.printer.api_key": "API Key (from ", + "cfg.printer.hostname": "Hostname", + "cfg.printer.ip": "IP (no http://)", + "cfg.printer.pass": "Password", + "cfg.printer.port": "Port", + "cfg.printer.user": "Username (for haproxy or basic auth)", + "cfg.psu.use": "Use OctoPrint PSU Control for clock/blank", + "cfg.save": "Save", + "cfg.security.password": "Password", + "cfg.security.use_basic": "Use security credentials for changes", + "cfg.security.user_id": "User ID (for this UI)", + "cfg.settings.ui_language": "Language", + "cfg.setup.ap": "Connect to acces point", + "cfg.setup.monitor": "Setup in monitor", + "cfg.setup.repetier_title": "Repetier", + "cfg.setup.wifi": "Wifi setup", + "cfg.setup.wifi2": "and setup wifi", + "cfg.test.conn": "Test connection", + "cfg.test.conn_json": "Test connection + JSON API response", + "cfg.theme.color": "Theme color", + "cfg.timezone": "Timezone", + "cfg.weather.refresh": "Weather refresh", + "cfg.wifi.led": "WiFi LED", + "clock.local_time": "Local time: ", + "clock.time": "Time", + "clock.updating": "Updating...", + "filament.m": "Filament", + "file": "File", + "file.size_kb": "File Size", + "hostname": "Hostname", + "i18n.file.cant_open": "[I18N] Can't open file: ", + "i18n.file.loaded": "[I18N] File loaded: ", + "map.it": "Map It!", + "mdns.in_mdns": " in mDNS", + "mdns.not_service": "No service, check that the printer server is on", + "mdns.printer_serve.found": "*** Printer server found ", + "mdns.searching": "*** Searching ", + "menu.about": "About", + "menu.configure": "Settings", + "menu.forget_wifi": "Forget WiFi", + "menu.home": "Home", + "menu.reset": "Factory reset", + "menu.title": "Menu", + "menu.update": "Update firmware", + "menu.weather": "Weather", + "ota.end": "End", + "ota.error.auth": "Auth error", + "ota.error.begin": "Begin error", + "ota.error.connect": "Connect error", + "ota.error.end": "End error", + "ota.error.receive": "Receive error", + "ota.progress": "Progress", + "ota.start": "Start", + "printer.monitor": "Printer Monitor", + "psu.off": "psu off", + "reason": "Reason", + "state.connected": "Connected", + "state.disconnected": "Disconnected", + "state.operational": "Operational", + "status": "Status", + "temp.bed": "Bed Temp", + "temp.nozzle": "Nozzle Temp", + "time.left": "Time Left", + "time.printed": "Time Printed", + "time.printing": "Printing Time", + "time.remaining": "Est. Print Time Left", + "ui.bed": "Bed", + "ui.bed_temp_title": "Bed Temp", + "ui.clock.mode": "Clock mode.", + "ui.connecting": "Connecting...", + "ui.nozzle": "Nozzle", + "ui.nozzle_temp_title": "Nozzle Temp", + "ui.printer.mode": "Printer monitor ON.", + "ui.printer_off": "Printer Off", + "ui.printer_on": "Printer On", + "ui.tool_temp_title": "Tool Temp", + "ui.turning_off": "Turning off printer\nSleep mode...", + "ui.turning_on": "Printer on\nWaking up...", + "wcfg.api_key.label": "OpenWeatherMap API Key (get it ", + "wcfg.api_key.label_here": "here", + "wcfg.city_id.label": "Location ID", + "wcfg.city_id.search": "Find location ID", + "wcfg.header": "Weather settings:", + "wcfg.language": "Weather language", + "wcfg.metric": "Use Metric (Celsius)", + "wcfg.show_when_off": "Show weather when printer is off", + "weather.city_label": "City", + "weather.condition": "Condition", + "weather.configure_link": "Configure Weather", + "weather.error": "Weather Error", + "weather.feels_like": "Feels like", + "weather.get_data": "Obtaining weather data...", + "weather.humidity": "Humidity", + "weather.please": "Please", + "weather.wind": "Wind", + "web.hostname": "Hostname", + "web.printername": "Printer name", + "wifi.signal": "Signal strength" +} \ No newline at end of file diff --git a/printermonitor/data/i18n/ru.json b/printermonitor/data/i18n/ru.json new file mode 100644 index 0000000..f7c2227 --- /dev/null +++ b/printermonitor/data/i18n/ru.json @@ -0,0 +1,122 @@ +{ + "app.by": "By Qrome", + "app.file.setup.notexist": "Settings File does not yet exists.", + "app.for": "for {name}", + "app.reset_settings": "Reset settings", + "app.setup.mode": "Setup mode", + "app.setup.openfile": "Can't open file", + "app.setup.save.settings": "Saving settings...", + "app.title": "Printer Monitor", + "app.version": "Version", + "app.web.disabled": "Web UI disabled", + "app.web.enable_in_settings": "Enable it in Settings.h", + "app.web.must_connect": "Connect to this IP", + "app.web.port": "Port", + "app.web.started": "Web UI started", + "btn.configure": "Configure", + "cfg.clock.show_when_off": "Show clock when printer is off", + "cfg.clock.use_24h": "Use 24-hour clock", + "cfg.display.flip": "Flip display orientation", + "cfg.display.off": "Display off", + "cfg.display.on": "Dispclay on", + "cfg.header": "Settings:", + "cfg.monitor.activated": "Printer monitor activated.", + "cfg.printer.api_key": "API Key (from ", + "cfg.printer.hostname": "Hostname", + "cfg.printer.ip": "IP (no http://)", + "cfg.printer.pass": "Password", + "cfg.printer.port": "Port", + "cfg.printer.user": "Username (for haproxy or basic auth)", + "cfg.psu.use": "Use OctoPrint PSU Control for clock/blank", + "cfg.save": "Save", + "cfg.security.password": "Password", + "cfg.security.use_basic": "Use security credentials for changes", + "cfg.security.user_id": "User ID (for this UI)", + "cfg.settings.ui_language": "Language", + "cfg.setup.ap": "Connect to acces point", + "cfg.setup.monitor": "Setup in monitor", + "cfg.setup.repetier_title": "Repetier", + "cfg.setup.wifi": "Wifi setup", + "cfg.setup.wifi2": "and setup wifi", + "cfg.test.conn": "Test connection", + "cfg.test.conn_json": "Test connection + JSON API response", + "cfg.theme.color": "Theme color", + "cfg.timezone": "Timezone", + "cfg.weather.refresh": "Weather refresh", + "cfg.wifi.led": "WiFi LED", + "clock.local_time": "Local time: ", + "clock.time": "Time", + "clock.updating": "Updating...", + "filament.m": "Filament", + "file": "File", + "file.size_kb": "File Size", + "hostname": "Hostname", + "i18n.file.cant_open": "[I18N] Can't open file: ", + "i18n.file.loaded": "[I18N] File loaded: ", + "map.it": "Map It!", + "mdns.in_mdns": " in mDNS", + "mdns.not_service": "No service, check that the printer server is on", + "mdns.printer_serve.found": "*** Printer server found ", + "mdns.searching": "*** Searching ", + "menu.about": "About", + "menu.configure": "Settings", + "menu.forget_wifi": "Forget WiFi", + "menu.home": "Home", + "menu.reset": "Factory reset", + "menu.title": "Menu", + "menu.update": "Update firmware", + "menu.weather": "Weather", + "ota.end": "End", + "ota.error.auth": "Auth error", + "ota.error.begin": "Begin error", + "ota.error.connect": "Connect error", + "ota.error.end": "End error", + "ota.error.receive": "Receive error", + "ota.progress": "Progress", + "ota.start": "Start", + "printer.monitor": "Printer Monitor", + "psu.off": "psu off", + "reason": "Reason", + "state.connected": "Connected", + "state.disconnected": "Disconnected", + "state.operational": "Operational", + "status": "Status", + "temp.bed": "Bed Temp", + "temp.nozzle": "Nozzle Temp", + "time.left": "Time Left", + "time.printed": "Time Printed", + "time.printing": "Printing Time", + "time.remaining": "Est. Print Time Left", + "ui.bed": "Bed", + "ui.bed_temp_title": "Bed Temp", + "ui.clock.mode": "Clock mode.", + "ui.connecting": "Connecting...", + "ui.nozzle": "Nozzle", + "ui.nozzle_temp_title": "Nozzle Temp", + "ui.printer.mode": "Printer monitor ON.", + "ui.printer_off": "Printer Off", + "ui.printer_on": "Printer On", + "ui.tool_temp_title": "Tool Temp", + "ui.turning_off": "Turning off printer\nSleep mode...", + "ui.turning_on": "Printer on\nWaking up...", + "wcfg.api_key.label": "OpenWeatherMap API Key (get it ", + "wcfg.api_key.label_here": "here", + "wcfg.city_id.label": "Location ID", + "wcfg.city_id.search": "Find location ID", + "wcfg.header": "Weather settings:", + "wcfg.language": "Weather language", + "wcfg.metric": "Use Metric (Celsius)", + "wcfg.show_when_off": "Show weather when printer is off", + "weather.city_label": "City", + "weather.condition": "Condition", + "weather.configure_link": "Configure Weather", + "weather.error": "Weather Error", + "weather.feels_like": "Feels like", + "weather.get_data": "Obtaining weather data...", + "weather.humidity": "Humidity", + "weather.please": "Please", + "weather.wind": "Wind", + "web.hostname": "Hostname", + "web.printername": "Printer name", + "wifi.signal": "Signal strength" +} \ No newline at end of file diff --git a/printermonitor/data/i18n/uk.json b/printermonitor/data/i18n/uk.json new file mode 100644 index 0000000..f7c2227 --- /dev/null +++ b/printermonitor/data/i18n/uk.json @@ -0,0 +1,122 @@ +{ + "app.by": "By Qrome", + "app.file.setup.notexist": "Settings File does not yet exists.", + "app.for": "for {name}", + "app.reset_settings": "Reset settings", + "app.setup.mode": "Setup mode", + "app.setup.openfile": "Can't open file", + "app.setup.save.settings": "Saving settings...", + "app.title": "Printer Monitor", + "app.version": "Version", + "app.web.disabled": "Web UI disabled", + "app.web.enable_in_settings": "Enable it in Settings.h", + "app.web.must_connect": "Connect to this IP", + "app.web.port": "Port", + "app.web.started": "Web UI started", + "btn.configure": "Configure", + "cfg.clock.show_when_off": "Show clock when printer is off", + "cfg.clock.use_24h": "Use 24-hour clock", + "cfg.display.flip": "Flip display orientation", + "cfg.display.off": "Display off", + "cfg.display.on": "Dispclay on", + "cfg.header": "Settings:", + "cfg.monitor.activated": "Printer monitor activated.", + "cfg.printer.api_key": "API Key (from ", + "cfg.printer.hostname": "Hostname", + "cfg.printer.ip": "IP (no http://)", + "cfg.printer.pass": "Password", + "cfg.printer.port": "Port", + "cfg.printer.user": "Username (for haproxy or basic auth)", + "cfg.psu.use": "Use OctoPrint PSU Control for clock/blank", + "cfg.save": "Save", + "cfg.security.password": "Password", + "cfg.security.use_basic": "Use security credentials for changes", + "cfg.security.user_id": "User ID (for this UI)", + "cfg.settings.ui_language": "Language", + "cfg.setup.ap": "Connect to acces point", + "cfg.setup.monitor": "Setup in monitor", + "cfg.setup.repetier_title": "Repetier", + "cfg.setup.wifi": "Wifi setup", + "cfg.setup.wifi2": "and setup wifi", + "cfg.test.conn": "Test connection", + "cfg.test.conn_json": "Test connection + JSON API response", + "cfg.theme.color": "Theme color", + "cfg.timezone": "Timezone", + "cfg.weather.refresh": "Weather refresh", + "cfg.wifi.led": "WiFi LED", + "clock.local_time": "Local time: ", + "clock.time": "Time", + "clock.updating": "Updating...", + "filament.m": "Filament", + "file": "File", + "file.size_kb": "File Size", + "hostname": "Hostname", + "i18n.file.cant_open": "[I18N] Can't open file: ", + "i18n.file.loaded": "[I18N] File loaded: ", + "map.it": "Map It!", + "mdns.in_mdns": " in mDNS", + "mdns.not_service": "No service, check that the printer server is on", + "mdns.printer_serve.found": "*** Printer server found ", + "mdns.searching": "*** Searching ", + "menu.about": "About", + "menu.configure": "Settings", + "menu.forget_wifi": "Forget WiFi", + "menu.home": "Home", + "menu.reset": "Factory reset", + "menu.title": "Menu", + "menu.update": "Update firmware", + "menu.weather": "Weather", + "ota.end": "End", + "ota.error.auth": "Auth error", + "ota.error.begin": "Begin error", + "ota.error.connect": "Connect error", + "ota.error.end": "End error", + "ota.error.receive": "Receive error", + "ota.progress": "Progress", + "ota.start": "Start", + "printer.monitor": "Printer Monitor", + "psu.off": "psu off", + "reason": "Reason", + "state.connected": "Connected", + "state.disconnected": "Disconnected", + "state.operational": "Operational", + "status": "Status", + "temp.bed": "Bed Temp", + "temp.nozzle": "Nozzle Temp", + "time.left": "Time Left", + "time.printed": "Time Printed", + "time.printing": "Printing Time", + "time.remaining": "Est. Print Time Left", + "ui.bed": "Bed", + "ui.bed_temp_title": "Bed Temp", + "ui.clock.mode": "Clock mode.", + "ui.connecting": "Connecting...", + "ui.nozzle": "Nozzle", + "ui.nozzle_temp_title": "Nozzle Temp", + "ui.printer.mode": "Printer monitor ON.", + "ui.printer_off": "Printer Off", + "ui.printer_on": "Printer On", + "ui.tool_temp_title": "Tool Temp", + "ui.turning_off": "Turning off printer\nSleep mode...", + "ui.turning_on": "Printer on\nWaking up...", + "wcfg.api_key.label": "OpenWeatherMap API Key (get it ", + "wcfg.api_key.label_here": "here", + "wcfg.city_id.label": "Location ID", + "wcfg.city_id.search": "Find location ID", + "wcfg.header": "Weather settings:", + "wcfg.language": "Weather language", + "wcfg.metric": "Use Metric (Celsius)", + "wcfg.show_when_off": "Show weather when printer is off", + "weather.city_label": "City", + "weather.condition": "Condition", + "weather.configure_link": "Configure Weather", + "weather.error": "Weather Error", + "weather.feels_like": "Feels like", + "weather.get_data": "Obtaining weather data...", + "weather.humidity": "Humidity", + "weather.please": "Please", + "weather.wind": "Wind", + "web.hostname": "Hostname", + "web.printername": "Printer name", + "wifi.signal": "Signal strength" +} \ No newline at end of file diff --git a/printermonitor/data/i18n/zh.json b/printermonitor/data/i18n/zh.json new file mode 100644 index 0000000..f7c2227 --- /dev/null +++ b/printermonitor/data/i18n/zh.json @@ -0,0 +1,122 @@ +{ + "app.by": "By Qrome", + "app.file.setup.notexist": "Settings File does not yet exists.", + "app.for": "for {name}", + "app.reset_settings": "Reset settings", + "app.setup.mode": "Setup mode", + "app.setup.openfile": "Can't open file", + "app.setup.save.settings": "Saving settings...", + "app.title": "Printer Monitor", + "app.version": "Version", + "app.web.disabled": "Web UI disabled", + "app.web.enable_in_settings": "Enable it in Settings.h", + "app.web.must_connect": "Connect to this IP", + "app.web.port": "Port", + "app.web.started": "Web UI started", + "btn.configure": "Configure", + "cfg.clock.show_when_off": "Show clock when printer is off", + "cfg.clock.use_24h": "Use 24-hour clock", + "cfg.display.flip": "Flip display orientation", + "cfg.display.off": "Display off", + "cfg.display.on": "Dispclay on", + "cfg.header": "Settings:", + "cfg.monitor.activated": "Printer monitor activated.", + "cfg.printer.api_key": "API Key (from ", + "cfg.printer.hostname": "Hostname", + "cfg.printer.ip": "IP (no http://)", + "cfg.printer.pass": "Password", + "cfg.printer.port": "Port", + "cfg.printer.user": "Username (for haproxy or basic auth)", + "cfg.psu.use": "Use OctoPrint PSU Control for clock/blank", + "cfg.save": "Save", + "cfg.security.password": "Password", + "cfg.security.use_basic": "Use security credentials for changes", + "cfg.security.user_id": "User ID (for this UI)", + "cfg.settings.ui_language": "Language", + "cfg.setup.ap": "Connect to acces point", + "cfg.setup.monitor": "Setup in monitor", + "cfg.setup.repetier_title": "Repetier", + "cfg.setup.wifi": "Wifi setup", + "cfg.setup.wifi2": "and setup wifi", + "cfg.test.conn": "Test connection", + "cfg.test.conn_json": "Test connection + JSON API response", + "cfg.theme.color": "Theme color", + "cfg.timezone": "Timezone", + "cfg.weather.refresh": "Weather refresh", + "cfg.wifi.led": "WiFi LED", + "clock.local_time": "Local time: ", + "clock.time": "Time", + "clock.updating": "Updating...", + "filament.m": "Filament", + "file": "File", + "file.size_kb": "File Size", + "hostname": "Hostname", + "i18n.file.cant_open": "[I18N] Can't open file: ", + "i18n.file.loaded": "[I18N] File loaded: ", + "map.it": "Map It!", + "mdns.in_mdns": " in mDNS", + "mdns.not_service": "No service, check that the printer server is on", + "mdns.printer_serve.found": "*** Printer server found ", + "mdns.searching": "*** Searching ", + "menu.about": "About", + "menu.configure": "Settings", + "menu.forget_wifi": "Forget WiFi", + "menu.home": "Home", + "menu.reset": "Factory reset", + "menu.title": "Menu", + "menu.update": "Update firmware", + "menu.weather": "Weather", + "ota.end": "End", + "ota.error.auth": "Auth error", + "ota.error.begin": "Begin error", + "ota.error.connect": "Connect error", + "ota.error.end": "End error", + "ota.error.receive": "Receive error", + "ota.progress": "Progress", + "ota.start": "Start", + "printer.monitor": "Printer Monitor", + "psu.off": "psu off", + "reason": "Reason", + "state.connected": "Connected", + "state.disconnected": "Disconnected", + "state.operational": "Operational", + "status": "Status", + "temp.bed": "Bed Temp", + "temp.nozzle": "Nozzle Temp", + "time.left": "Time Left", + "time.printed": "Time Printed", + "time.printing": "Printing Time", + "time.remaining": "Est. Print Time Left", + "ui.bed": "Bed", + "ui.bed_temp_title": "Bed Temp", + "ui.clock.mode": "Clock mode.", + "ui.connecting": "Connecting...", + "ui.nozzle": "Nozzle", + "ui.nozzle_temp_title": "Nozzle Temp", + "ui.printer.mode": "Printer monitor ON.", + "ui.printer_off": "Printer Off", + "ui.printer_on": "Printer On", + "ui.tool_temp_title": "Tool Temp", + "ui.turning_off": "Turning off printer\nSleep mode...", + "ui.turning_on": "Printer on\nWaking up...", + "wcfg.api_key.label": "OpenWeatherMap API Key (get it ", + "wcfg.api_key.label_here": "here", + "wcfg.city_id.label": "Location ID", + "wcfg.city_id.search": "Find location ID", + "wcfg.header": "Weather settings:", + "wcfg.language": "Weather language", + "wcfg.metric": "Use Metric (Celsius)", + "wcfg.show_when_off": "Show weather when printer is off", + "weather.city_label": "City", + "weather.condition": "Condition", + "weather.configure_link": "Configure Weather", + "weather.error": "Weather Error", + "weather.feels_like": "Feels like", + "weather.get_data": "Obtaining weather data...", + "weather.humidity": "Humidity", + "weather.please": "Please", + "weather.wind": "Wind", + "web.hostname": "Hostname", + "web.printername": "Printer name", + "wifi.signal": "Signal strength" +} \ No newline at end of file diff --git a/printermonitor/printermonitor.ino b/printermonitor/printermonitor.ino index f91ac5e..99c5529 100644 --- a/printermonitor/printermonitor.ino +++ b/printermonitor/printermonitor.ino @@ -24,12 +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 */ +/* 17 Sep 2025 : Eduardo Romero @eduardorq : Fix Weather API request parse data and translations */ /********************************************** * Edit Settings.h for personalization ***********************************************/ #include "Settings.h" +#include "I18N.h" + #define VERSION "3.1" @@ -85,6 +87,9 @@ String lastSecond = "xx"; String lastReportStatus = ""; boolean displayOn = true; +unsigned long DIAG_LAST = 0; +bool I18N_TRIED = false; // para intentar el load() una sola vez desde loop() + // Printer Client #if defined(USE_REPETIER_CLIENT) RepetierClient printerClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); @@ -105,39 +110,39 @@ 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"; +static const char WEB_ACTIONS[] PROGMEM = "{{menu.home}}" + " {{menu.configure}}" + " {{menu.weather}}" + " {{menu.reset}}" + " {{menu.forget_wifi}}" + " {{menu.update}}" + " {{menu.about}}"; 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 CLOCK_FORM[] PROGMEM = "

{{cfg.clock.show_when_off}}

" + "

{{cfg.clock.use_24h}}

" + "

{{cfg.display.flip}}

" + "

{{cfg.wifi.led}}

" + "

{{cfg.psu.use}}

" + "

{{cfg.weather.refresh}}

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

Color de plantilla

" - "


" - "

Utilice credenciales de seguridad para cambios de configuración

" - "

" - "

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

{{cfg.theme.color}}

" + "


" + "

{{cfg.security.use_basic}}

" + "

" + "

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

Configuración del clima:

" - "

Mostrar el clima cuando la impresora está apagada

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

{{wcfg.header}}

" + "

{{wcfg.show_when_off}}

" + "" "" - "

" - "

Usar Métrica (Celsius)

" - "

Idioma del clima

" - "
" + "

{{wcfg.metric}}

" + "

{{wcfg.language}}

" + "" ""; static const char LANG_OPTIONS[] PROGMEM = "" @@ -197,24 +202,25 @@ 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(); + if (!I18N::load(UiLanguage)) { + I18N::load("en"); + } + // initialize display display.init(); if (INVERT_DISPLAY) { @@ -228,7 +234,8 @@ void setup() { display.setTextAlignment(TEXT_ALIGN_CENTER); display.setContrast(255); // default is 255 display.setFont(ArialMT_Plain_16); - display.drawString(64, 1, "Printer Monitor"); + display.drawString(64, 1, I18N::t("app.title")); + display.setFont(ArialMT_Plain_10); display.drawString(64, 18, "for " + printerClient.getPrinterType()); display.setFont(ArialMT_Plain_16); @@ -273,27 +280,33 @@ void setup() { } // print the received signal strength: - Serial.print("Intensidad de la señal (RSSI): "); + Serial.print(I18N::t("wifi.signal")+" (RSSI): "); Serial.print(getWifiQuality()); Serial.println("%"); + // NOTA: usa un code de 2 letras "es" o "en" + if (!I18N::load(WeatherLanguage)) { + I18N::load("en"); + } + if (ENABLE_OTA) { ArduinoOTA.onStart([]() { - Serial.println("Start"); + Serial.println(I18N::t("ota.start")); }); ArduinoOTA.onEnd([]() { - Serial.println("\nEnd"); + Serial.println("\n"+I18N::t("ota.end")); }); ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { - Serial.printf("Progress: %u%%\r", (progress / (total / 100))); + Serial.print(I18N::t("ota.progress")); + Serial.printf(": %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"); + if (error == OTA_AUTH_ERROR) Serial.println(I18N::t("ota.error.auth")); + else if (error == OTA_BEGIN_ERROR) Serial.println(I18N::t("ota.error.begin")); + else if (error == OTA_CONNECT_ERROR) Serial.println(I18N::t("ota.error.connect")); + else if (error == OTA_RECEIVE_ERROR) Serial.println(I18N::t("ota.error.receive")); + else if (error == OTA_END_ERROR) Serial.println(I18N::t("ota.error.end")); }); ArduinoOTA.setHostname((const char *)hostname.c_str()); if (OTA_Password != "") { @@ -314,26 +327,26 @@ void setup() { serverUpdater.setup(&server, "/update", www_username, www_password); // Start the server server.begin(); - Serial.println("Servidor iniciado"); + Serial.println(I18N::t("app.web.started")); // Print the IP address String webAddress = "http://" + WiFi.localIP().toString() + ":" + String(WEBSERVER_PORT) + "/"; - Serial.println("Use esta URL : " + webAddress); + Serial.println(I18N::t("app.web.must_connect")+": " + 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.drawString(64, 10, I18N::t("app.web.started")); + display.drawString(64, 20, I18N::t("app.web.must_connect")); display.setFont(ArialMT_Plain_16); display.drawString(64, 30, WiFi.localIP().toString()); - display.drawString(64, 46, "Puerto: " + String(WEBSERVER_PORT)); + display.drawString(64, 46, I18N::t("app.web.port")+": " + String(WEBSERVER_PORT)); display.display(); } else { - Serial.println("Entorno web Deshabilitado"); + Serial.println(I18N::t("app.web.disabled")); 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.drawString(64, 10, I18N::t("app.web.disabled")); + display.drawString(64, 20, I18N::t("app.web.enable_in_settings")); display.display(); } flashLED(5, 100); @@ -341,6 +354,24 @@ void setup() { Serial.println("*** Leaving setup()"); } +void diagI18N() { + // intenta cargar solo una vez + if (!I18N_TRIED) { + I18N_TRIED = true; + Serial.println("[diag] I18N::load('en')..."); + bool ok = I18N::load("en"); // fuerza "en" para descartar WeatherLanguage + Serial.println(String("[diag] load -> ") + (ok ? "OK" : "FAIL")); + Serial.println("[diag] current=" + I18N::current()); + } + + // (opcional) dibuja una línea en la OLED para ver si cambia + display.setTextAlignment(TEXT_ALIGN_LEFT); + display.setFont(ArialMT_Plain_10); + display.drawString(0, 56, I18N::t("state.disconnected")); + display.display(); +} + + void findMDNS() { if (PrinterHostName == "" || ENABLE_OTA == false) { return; // nothing to do here @@ -349,10 +380,10 @@ void findMDNS() { // 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"); + Serial.println(I18N::t("mdns.not_service")); return; } - Serial.println("*** Buscando " + PrinterHostName + " en mDNS"); + Serial.println(I18N::t("mdns.searching") + PrinterHostName + I18N::t("mdns.in_mdns")); for (int i = 0; i < n; ++i) { // Going through every available service, // we're searching for the one whose hostname @@ -362,7 +393,7 @@ void findMDNS() { 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); + Serial.println(I18N::t("mdns.printer_server.found") + PrinterHostName + " http://" + PrinterServer + ":" + PrinterPort); writeSettings(); // update the settings } } @@ -372,7 +403,13 @@ void findMDNS() { // Main Loop //************************************************************ void loop() { - + // --- Diag cíclico cada 5s --- + if (millis() - DIAG_LAST > 5000UL) { + DIAG_LAST = millis(); + diagI18N(); + yield(); // alimenta el watchdog + } + //Get Time Update if((getMinutesFromLastRefresh() >= minutesBetweenDataRefresh) || lastEpoch == 0) { getUpdateTime(); @@ -413,19 +450,19 @@ void getUpdateTime() { Serial.println(); if (displayOn && DISPLAYWEATHER) { - Serial.println("Obteniendo datos del clima..."); + Serial.println(I18N::t("weather.get_data")); weatherClient.updateWeather(); } - Serial.println("Actualizando..."); + Serial.println(I18N::t("clock.updating")); //Update the Time timeClient.updateTime(); lastEpoch = timeClient.getCurrentEpoch(); if (IS_24HOUR) { - Serial.println("Local time: " + timeClient.getFormattedTime()); + Serial.println(I18N::t("clock.local_time") + timeClient.getFormattedTime()); } else { - Serial.println("Local time: " + timeClient.getAmPmFormattedTime()); + Serial.println(I18N::t("clock.local_time") + timeClient.getAmPmFormattedTime()); } ledOnOff(false); // turn off the LED @@ -442,7 +479,7 @@ void handleSystemReset() { if (!authentication()) { return server.requestAuthentication(); } - Serial.println("Reiniciar configuración del sistema"); + Serial.println(I18N::t("app.reset_settings")); if (SPIFFS.remove(CONFIG)) { redirectHome(); ESP.restart(); @@ -453,6 +490,7 @@ void handleUpdateWeather() { if (!authentication()) { return server.requestAuthentication(); } + Serial.println(server.arg("language")); DISPLAYWEATHER = server.hasArg("isWeatherEnabled"); WeatherApiKey = server.arg("openWeatherMapApiKey"); CityIDs[0] = server.arg("city1").toInt(); @@ -470,6 +508,17 @@ void handleUpdateConfig() { if (!authentication()) { return server.requestAuthentication(); } + + if (server.hasArg("uilang")) { + UiLanguage = server.arg("uilang"); + if (!I18N::load(UiLanguage)) { + I18N::load("en"); + } + ui.init(); + if (INVERT_DISPLAY) display.flipScreenVertically(); + ui.update(); + } + if (server.hasArg("printer")) { printerClient.setPrinterName(server.arg("printer")); } @@ -535,6 +584,7 @@ void handleWeatherConfigure() { server.sendContent(html); String form = FPSTR(WEATHER_FORM); + I18N::apply(form); String isWeatherChecked = ""; if (DISPLAYWEATHER) { isWeatherChecked = "checked='checked'"; @@ -549,6 +599,7 @@ void handleWeatherConfigure() { } form.replace("%METRIC%", checked); String options = FPSTR(LANG_OPTIONS); + I18N::apply(options); options.replace(">"+String(WeatherLanguage)+"<", " selected>"+String(WeatherLanguage)+"<"); form.replace("%LANGUAGEOPTIONS%", options); server.sendContent(form); @@ -576,27 +627,51 @@ void handleConfigure() { html = getHeader(); server.sendContent(html); - CHANGE_FORM = "

Configuración:

" - "

" + String uiLangOptions = + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; + + uiLangOptions.replace("value='" + UiLanguage + "'>", + "value='" + UiLanguage + "' selected>"); + + String uiLangBlock = + + + + CHANGE_FORM = "

{{cfg.header}}

" + "

" "

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

"; + CHANGE_FORM += "

"; } - CHANGE_FORM += "

" + CHANGE_FORM += "

" "

" - "

" + "

" "

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

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

"; + CHANGE_FORM += "

"; } - CHANGE_FORM += "

" - "

"; - - + CHANGE_FORM += "

" + "

"; + CHANGE_FORM += "

"; + + I18N::apply(CHANGE_FORM); + if (printerClient.getPrinterType() == "Repetier") { html = ""; server.sendContent(html); } @@ -630,7 +705,7 @@ void handleConfigure() { server.sendContent(form); form = FPSTR(CLOCK_FORM); - + I18N::apply(form); String isClockChecked = ""; if (DISPLAYCLOCK) { isClockChecked = "checked='checked'"; @@ -664,8 +739,10 @@ void handleConfigure() { server.sendContent(form); form = FPSTR(THEME_FORM); + I18N::apply(form); String themeOptions = FPSTR(COLOR_THEMES); + I18N::apply(themeOptions); themeOptions.replace(">"+String(themeColor)+"<", " selected>"+String(themeColor)+"<"); form.replace("%THEME_OPTIONS%", themeOptions); form.replace("%UTCOFFSET%", String(UtcOffset)); @@ -721,9 +798,10 @@ String getHeader() { String getHeader(boolean refresh) { String menu = FPSTR(WEB_ACTIONS); + I18N::apply(menu); String html = ""; - html += "Printer Monitor"; + html += "{{app.title}}"; html += ""; html += ""; if (refresh) { @@ -737,20 +815,21 @@ String getHeader(boolean refresh) { html += "
"; html += ""; html += "
"; - html += "
Menu
"; + html += "
{{ menu.title }}
"; html += menu; html += ""; - html += "

Printer Monitor

"; + html += "

{{ printer.monitor }}

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


"; @@ -759,11 +838,12 @@ String getFooter() { if (lastReportStatus != "") { html += " Report Status: " + lastReportStatus + "
"; } - html += " Version: " + String(VERSION) + "
"; - html += " Intensidad de la señal: "; + html += " {{app.version}}: " + String(VERSION) + "
"; + html += " {{wifi.signal}}: "; html += String(rssi) + "%"; html += ""; html += ""; + I18N::apply(html); return html; } @@ -788,45 +868,45 @@ void displayPrinterStatus() { html += "

" + printerClient.getPrinterType() + " Monitor

"; html += "

"; if (printerClient.getPrinterType() == "Repetier") { - html += "Printer Name: " + printerClient.getPrinterName() + "
"; + html += "{{web.printername}}: " + printerClient.getPrinterName() + "
"; } else { - html += "Nombre de host: " + PrinterHostName + "
"; + html += "{{web.hostname}}: " + PrinterHostName + "
"; } if (printerClient.getError() != "") { - html += "Estado: Desconectado
"; - html += "Motivo: " + printerClient.getError() + "
"; + html += "{{status}}: {{ state.disconnected }}
"; + html += "{{reason}}: " + printerClient.getError() + "
"; } else { - html += "Estado: " + printerClient.getState(); + html += "{{status}}: " + printerClient.getState(); if (printerClient.isPSUoff() && HAS_PSU) { - html += ", PSU off"; + html += ", {{psu.off}}"; } html += "
"; } if (printerClient.isPrinting()) { - html += "File: " + printerClient.getFileName() + "
"; + html += "{{file}}: " + printerClient.getFileName() + "
"; float fileSize = printerClient.getFileSize().toFloat(); if (fileSize > 0) { fileSize = fileSize / 1024; - html += "File Size: " + String(fileSize) + "KB
"; + html += "{{file.size_kb}}: " + String(fileSize) + "KB
"; } int filamentLength = printerClient.getFilamentLength().toInt(); if (filamentLength > 0) { float fLength = float(filamentLength) / 1000; - html += "Filamento: " + String(fLength) + "m
"; + html += "{{filament.m}}: " + String(fLength) + "m
"; } - html += "Temperatura boquilla: " + printerClient.getTempToolActual() + "° C
"; + html += "{{ui.nozzle}: " + printerClient.getTempToolActual() + "° C
"; if ( printerClient.getTempBedActual() != 0 ) { - html += "Temperatura cama: " + printerClient.getTempBedActual() + "° C
"; + html += "{{ui.bed}}: " + 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) + "
"; + html += "{{time.remaining}}: " + zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds) + "
"; val = printerClient.getProgressPrintTime().toInt(); hours = numberOfHours(val); @@ -841,17 +921,18 @@ void displayPrinterStatus() { html += "

"; - html += "

Hora: " + displayTime + "

"; - + html += "

{{clock.time}}: " + displayTime + "

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

Por favor Configure clima API

"; + html += "

{{weather.please}} {{weather.configure_link}} API

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

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

"; + html += "

{{weather.error}}: " + weatherClient.getError() + "

"; } + I18N::apply(html); } else { html += "

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

"; html += "
"; @@ -859,16 +940,16 @@ void displayPrinterStatus() { html += weatherClient.getIcon(0); html += "@2x.png' alt='"; html += weatherClient.getDescription(0); - html += "'>
";html += weatherClient.getHumidity(0) + "% Humedad
"; - html += weatherClient.getWind(0) + " " + getSpeedSymbol() + " Viento
"; + html += "'>
";html += weatherClient.getHumidity(0) + "% {{weather.humidity}}
"; + html += weatherClient.getWind(0) + " " + getSpeedSymbol() + " {{weather.wind}}
"; html += "
"; html += "

"; html += weatherClient.getCondition(0) + " (" + weatherClient.getDescription(0) + ")
"; html += weatherClient.getTempRounded(0) + getTempSymbol(true) + "
"; - html += " Map It!
"; + html += " {{map.it}}
"; html += "

"; + I18N::apply(html); } - server.sendContent(html); // spit out what we got html = ""; // fresh start } @@ -880,24 +961,24 @@ void displayPrinterStatus() { } void configModeCallback (WiFiManager *myWiFiManager) { - Serial.println("Modo configuración"); + Serial.println(I18N::t("app.setup.mode")); 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.drawString(64, 0, I18N::t("cfg.setup.wifi")); + display.drawString(64, 10, I18N::t("cfg.setup.ap")); 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.drawString(64, 46, I18N::t("cfg.setup.wifi2")); display.display(); - Serial.println("Configure en Monitor"); - Serial.println("Conecte al punto de acceso"); + Serial.println(I18N::t("cfg.setup.monitor")); + Serial.println(I18N::t("cfg.setup.ap")); Serial.println(myWiFiManager->getConfigPortalSSID()); - Serial.println("y configure la wifi"); + Serial.println(I18N::t("cfg.setup.wifi2")); flashLED(20, 50); } @@ -927,10 +1008,10 @@ void drawScreen1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int 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"); + display->drawString(29 + x, 0 + y, I18N::t("ui.nozzle")); + display->drawString(89 + x, 0 + y, I18N::t("ui.bed")); } else { - display->drawString(64 + x, 0 + y, "Temperatura boquilla"); + display->drawString(64 + x, 0 + y, I18N::t("ui.nozzle_temp_title")); } display->setTextAlignment(TEXT_ALIGN_LEFT); display->setFont(ArialMT_Plain_24); @@ -948,7 +1029,7 @@ void drawScreen2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int display->setTextAlignment(TEXT_ALIGN_CENTER); display->setFont(ArialMT_Plain_16); - display->drawString(64 + x, 0 + y, "Tiempo restante"); + display->drawString(64 + x, 0 + y, I18N::t("time.left")); //display->setTextAlignment(TEXT_ALIGN_LEFT); display->setFont(ArialMT_Plain_24); int val = printerClient.getProgressPrintTimeLeft().toInt(); @@ -964,7 +1045,7 @@ void drawScreen3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int display->setTextAlignment(TEXT_ALIGN_CENTER); display->setFont(ArialMT_Plain_16); - display->drawString(64 + x, 0 + y, "Tiempo impresión"); + display->drawString(64 + x, 0 + y, I18N::t("time.printing")); //display->setTextAlignment(TEXT_ALIGN_LEFT); display->setFont(ArialMT_Plain_24); int val = printerClient.getProgressPrintTime().toInt(); @@ -986,7 +1067,7 @@ void drawClock(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16 displayTime = timeClient.getAmPmHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds(); } String displayName = PrinterHostName; - if (printerClient.getPrinterType() == "Repetier") { + if (printerClient.getPrinterType() == I18N::t("cfg.setup.repetier_title")) { displayName = printerClient.getPrinterName(); } display->setFont(ArialMT_Plain_16); @@ -1083,24 +1164,24 @@ void drawClockHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) { 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"); + display->drawString(64, 47, I18N::t("psu.off")); + } else if (printerClient.getState() == I18N::t("state.operational")) { + display->drawString(64, 47, I18N::t("state.connected")); } else { - display->drawString(64, 47, "Desconectado"); + display->drawString(64, 47, I18N::t("state.disconnected")); } } else { if (printerClient.isPSUoff()) { - display->drawString(0, 47, "psu off"); - } else if (printerClient.getState() == "Operational") { - display->drawString(0, 47, "Conectado"); + display->drawString(0, 47, I18N::t("psu.off")); + } else if (printerClient.getState() == I18N::t("state.operational")) { + display->drawString(0, 47, I18N::t("state.connected")); } else { - display->drawString(0, 47, "Desconectado"); + display->drawString(0, 47, I18N::t("state.disconnected")); } } display->setTextAlignment(TEXT_ALIGN_LEFT); display->drawRect(0, 43, 128, 2); - + drawRssi(display); } @@ -1134,9 +1215,9 @@ 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!"); + Serial.println(I18N::t("app.setup.file")); } else { - Serial.println("Guardando configuración..."); + Serial.println(I18N::t("app.setup.save.settings")); f.println("UtcOffset=" + String(UtcOffset)); f.println("printerApiKey=" + PrinterApiKey); f.println("printerHostName=" + PrinterHostName); @@ -1160,6 +1241,7 @@ void writeSettings() { f.println("isMetric=" + String(IS_METRIC)); f.println("language=" + String(WeatherLanguage)); f.println("hasPSU=" + String(HAS_PSU)); + f.println("uiLanguage=" + UiLanguage); } f.close(); readSettings(); @@ -1168,7 +1250,7 @@ void writeSettings() { void readSettings() { if (SPIFFS.exists(CONFIG) == false) { - Serial.println("Settings File does not yet exists."); + Serial.println(I18N::t("app.file.setup.notexist")); writeSettings(); return; } @@ -1283,6 +1365,12 @@ void readSettings() { WeatherLanguage.trim(); Serial.println("WeatherLanguage=" + WeatherLanguage); } + if (line.indexOf("uiLanguage=") >= 0) { + UiLanguage = line.substring(line.lastIndexOf("uiLanguage=") + 11); + UiLanguage.trim(); + Serial.println("UiLanguage=" + UiLanguage); + } + } fr.close(); printerClient.updatePrintClient(PrinterApiKey, PrinterServer, PrinterPort, PrinterAuthUser, PrinterAuthPass, HAS_PSU); @@ -1315,11 +1403,11 @@ void checkDisplay() { 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.drawString(64, 5, I18N::t("ui.turning_off")); display.display(); delay(5000); enableDisplay(false); - Serial.println("Impresora apagada..."); + Serial.println(I18N::t("ui.printer_off")); return; } else if (!displayOn && !DISPLAYCLOCK) { if (printerClient.isOperational()) { @@ -1330,15 +1418,15 @@ void checkDisplay() { display.setFont(ArialMT_Plain_16); display.setTextAlignment(TEXT_ALIGN_CENTER); display.setContrast(255); // default is 255 - display.drawString(64, 5, "Impresora encendido\nEncendiendo..."); + display.drawString(64, 5, I18N::t("ui.turning_on")); display.display(); - Serial.println("Impresora encendida..."); + Serial.println(I18N::t("ui.printer_on")); delay(5000); return; } } else if (DISPLAYCLOCK) { if ((!printerClient.isPrinting() || printerClient.isPSUoff()) && !isClockOn) { - Serial.println("Modo reloj."); + Serial.println(I18N::t("ui.clock.mode")); if (!DISPLAYWEATHER) { ui.disableAutoTransition(); ui.setFrames(clockFrame, 1); @@ -1352,7 +1440,7 @@ void checkDisplay() { ui.setOverlays(clockOverlay, numberOfOverlays); isClockOn = true; } else if (printerClient.isPrinting() && !printerClient.isPSUoff() && isClockOn) { - Serial.println("Monito de impresora activado."); + Serial.println(I18N::t("cfg.monitor.activated")); ui.setFrames(frames, numberOfFrames); ui.setOverlays(overlays, numberOfOverlays); ui.enableAutoTransition(); @@ -1370,10 +1458,10 @@ void enableDisplay(boolean enable) { displayOffEpoch = 0; // reset } display.displayOn(); - Serial.println("Pantalla encendida: " + timeClient.getFormattedTime()); + Serial.println(I18N::t("cfg.display.on")+": " + timeClient.getFormattedTime()); } else { display.displayOff(); - Serial.println("Pantalla apagada: " + timeClient.getFormattedTime()); + Serial.println(I18N::t("cfg.display.off")+": " + timeClient.getFormattedTime()); displayOffEpoch = lastEpoch; } } diff --git a/printermonitor/printermonitor.ino.bak b/printermonitor/printermonitor.ino.bak deleted file mode 100644 index 77db194..0000000 --- a/printermonitor/printermonitor.ino.bak +++ /dev/null @@ -1,1376 +0,0 @@ -/** 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; - } -}