diff --git a/ESPTimeCast_ESP32/ESPTimeCast_ESP32.ino b/ESPTimeCast_ESP32/ESPTimeCast_ESP32.ino
index f9c3ac0..6537766 100644
--- a/ESPTimeCast_ESP32/ESPTimeCast_ESP32.ino
+++ b/ESPTimeCast_ESP32/ESPTimeCast_ESP32.ino
@@ -891,6 +891,39 @@ void handleCaptivePortal(AsyncWebServerRequest *request) {
String normalizeWeatherDescription(String str) {
+ // Serbian Cyrillic → Latin
+ str.replace("а", "a");
+ str.replace("б", "b");
+ str.replace("в", "v");
+ str.replace("г", "g");
+ str.replace("д", "d");
+ str.replace("ђ", "dj");
+ str.replace("е", "e");
+ str.replace("ж", "z");
+ str.replace("з", "z");
+ str.replace("и", "i");
+ str.replace("ј", "j");
+ str.replace("к", "k");
+ str.replace("л", "l");
+ str.replace("љ", "lj");
+ str.replace("м", "m");
+ str.replace("н", "n");
+ str.replace("њ", "nj");
+ str.replace("о", "o");
+ str.replace("п", "p");
+ str.replace("р", "r");
+ str.replace("с", "s");
+ str.replace("т", "t");
+ str.replace("ћ", "c");
+ str.replace("у", "u");
+ str.replace("ф", "f");
+ str.replace("х", "h");
+ str.replace("ц", "c");
+ str.replace("ч", "c");
+ str.replace("џ", "dz");
+ str.replace("ш", "s");
+
+ // Latin diacritics → ASCII
str.replace("å", "a");
str.replace("ä", "a");
str.replace("à", "a");
@@ -981,17 +1014,19 @@ String normalizeWeatherDescription(String str) {
str.replace("ź", "z");
str.replace("ż", "z");
- str.toLowerCase();
+ str.toUpperCase();
+
String result = "";
for (unsigned int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
- if ((c >= 'a' && c <= 'z') || c == ' ') {
+ if ((c >= 'A' && c <= 'Z') || c == ' ') {
result += c;
}
}
return result;
}
+
bool isNumber(const char *str) {
for (int i = 0; str[i]; i++) {
if (!isdigit(str[i]) && str[i] != '.' && str[i] != '-') return false;
diff --git a/ESPTimeCast_ESP32/data/index.html b/ESPTimeCast_ESP32/data/index.html
index 4f2da1f..c77f1e9 100644
--- a/ESPTimeCast_ESP32/data/index.html
+++ b/ESPTimeCast_ESP32/data/index.html
@@ -441,6 +441,7 @@ textarea::placeholder {
+
diff --git a/ESPTimeCast_ESP32/days_lookup.h b/ESPTimeCast_ESP32/days_lookup.h
index 7b5dd7e..348821c 100644
--- a/ESPTimeCast_ESP32/days_lookup.h
+++ b/ESPTimeCast_ESP32/days_lookup.h
@@ -30,6 +30,7 @@ const DaysOfWeekMapping days_mappings[] = {
{ "ro", { "d&u&m", "l&u&n", "m&a&r", "m&i&e", "j&o&i", "v&i&n", "s&a&m" } },
{ "sk", { "n&e&d", "p&o&n", "u&t&o", "s&t&r", "s&t&v", "p&i&a", "s&o&b" } },
{ "sl", { "n&e&d", "p&o&n", "t&o&r", "s&r&e", "c&e&t", "p&e&t", "s&o&b" } },
+ { "sr", { "n&e&d", "p&o&n", "u&t&o", "s&r&e", "c&e&t", "p&e&t", "s&u&b" } },
{ "sv", { "s&o&n", "m&a&n", "t&i&s", "o&n&s", "t&o&r", "f&r&e", "l&o&r" } },
{ "sw", { "j&p&l", "j&u&m", "j&t&t", "j&t&n", "a&l&k", "i&j&m", "j&m&s" } },
{ "tr", { "p&a&z", "p&a&z", "s&a&l", "c&a&r", "p&e&r", "c&u&m", "c&u&m" } }
diff --git a/ESPTimeCast_ESP8266/ESPTimeCast_ESP8266.ino b/ESPTimeCast_ESP8266/ESPTimeCast_ESP8266.ino
index 2552087..8a98f36 100644
--- a/ESPTimeCast_ESP8266/ESPTimeCast_ESP8266.ino
+++ b/ESPTimeCast_ESP8266/ESPTimeCast_ESP8266.ino
@@ -888,9 +888,40 @@ void handleCaptivePortal(AsyncWebServerRequest *request) {
request->redirect(String("http://") + WiFi.softAPIP().toString() + "/");
}
-
-
String normalizeWeatherDescription(String str) {
+ // Serbian Cyrillic → Latin
+ str.replace("а", "a");
+ str.replace("б", "b");
+ str.replace("в", "v");
+ str.replace("г", "g");
+ str.replace("д", "d");
+ str.replace("ђ", "dj");
+ str.replace("е", "e");
+ str.replace("ж", "z");
+ str.replace("з", "z");
+ str.replace("и", "i");
+ str.replace("ј", "j");
+ str.replace("к", "k");
+ str.replace("л", "l");
+ str.replace("љ", "lj");
+ str.replace("м", "m");
+ str.replace("н", "n");
+ str.replace("њ", "nj");
+ str.replace("о", "o");
+ str.replace("п", "p");
+ str.replace("р", "r");
+ str.replace("с", "s");
+ str.replace("т", "t");
+ str.replace("ћ", "c");
+ str.replace("у", "u");
+ str.replace("ф", "f");
+ str.replace("х", "h");
+ str.replace("ц", "c");
+ str.replace("ч", "c");
+ str.replace("џ", "dz");
+ str.replace("ш", "s");
+
+ // Latin diacritics → ASCII
str.replace("å", "a");
str.replace("ä", "a");
str.replace("à", "a");
@@ -981,17 +1012,19 @@ String normalizeWeatherDescription(String str) {
str.replace("ź", "z");
str.replace("ż", "z");
- str.toLowerCase();
+ str.toUpperCase();
+
String result = "";
for (unsigned int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
- if ((c >= 'a' && c <= 'z') || c == ' ') {
+ if ((c >= 'A' && c <= 'Z') || c == ' ') {
result += c;
}
}
return result;
}
+
bool isNumber(const char *str) {
for (int i = 0; str[i]; i++) {
if (!isdigit(str[i]) && str[i] != '.' && str[i] != '-') return false;
@@ -1625,8 +1658,7 @@ void loop() {
// --- WEATHER DESCRIPTION Display Mode ---
if (displayMode == 2 && showWeatherDescription && weatherAvailable && weatherDescription.length() > 0) {
String desc = weatherDescription;
- desc.toUpperCase();
-
+
if (desc.length() > 8) {
if (!descScrolling) {
P.displayClear();
diff --git a/ESPTimeCast_ESP8266/data/index.html b/ESPTimeCast_ESP8266/data/index.html
index 4f2da1f..c77f1e9 100644
--- a/ESPTimeCast_ESP8266/data/index.html
+++ b/ESPTimeCast_ESP8266/data/index.html
@@ -441,6 +441,7 @@ textarea::placeholder {
+
diff --git a/ESPTimeCast_ESP8266/days_lookup.h b/ESPTimeCast_ESP8266/days_lookup.h
index 7b5dd7e..348821c 100644
--- a/ESPTimeCast_ESP8266/days_lookup.h
+++ b/ESPTimeCast_ESP8266/days_lookup.h
@@ -30,6 +30,7 @@ const DaysOfWeekMapping days_mappings[] = {
{ "ro", { "d&u&m", "l&u&n", "m&a&r", "m&i&e", "j&o&i", "v&i&n", "s&a&m" } },
{ "sk", { "n&e&d", "p&o&n", "u&t&o", "s&t&r", "s&t&v", "p&i&a", "s&o&b" } },
{ "sl", { "n&e&d", "p&o&n", "t&o&r", "s&r&e", "c&e&t", "p&e&t", "s&o&b" } },
+ { "sr", { "n&e&d", "p&o&n", "u&t&o", "s&r&e", "c&e&t", "p&e&t", "s&u&b" } },
{ "sv", { "s&o&n", "m&a&n", "t&i&s", "o&n&s", "t&o&r", "f&r&e", "l&o&r" } },
{ "sw", { "j&p&l", "j&u&m", "j&t&t", "j&t&n", "a&l&k", "i&j&m", "j&m&s" } },
{ "tr", { "p&a&z", "p&a&z", "s&a&l", "c&a&r", "p&e&r", "c&u&m", "c&u&m" } }