mirror of
https://github.com/mfactory-osaka/ESPTimeCast.git
synced 2026-02-19 11:54:56 -05:00
Added seconds to clock without the days of the week
Added seconds to clock without the days of the week. Blinking colon toggle changed to Animated seconds. Correct days of the week for German language. Geolocation changed to ip-api.com
This commit is contained in:
@@ -1612,28 +1612,43 @@ void loop() {
|
||||
const char *const *daysOfTheWeek = getDaysOfWeek(language);
|
||||
const char *daySymbol = daysOfTheWeek[timeinfo.tm_wday];
|
||||
|
||||
char timeStr[9];
|
||||
|
||||
// build base HH:MM first ---
|
||||
char baseTime[9];
|
||||
if (twelveHourToggle) {
|
||||
int hour12 = timeinfo.tm_hour % 12;
|
||||
if (hour12 == 0) hour12 = 12;
|
||||
sprintf(timeStr, " %d:%02d", hour12, timeinfo.tm_min);
|
||||
sprintf(baseTime, "%d:%02d", hour12, timeinfo.tm_min);
|
||||
} else {
|
||||
sprintf(timeStr, " %02d:%02d", timeinfo.tm_hour, timeinfo.tm_min);
|
||||
sprintf(baseTime, "%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min);
|
||||
}
|
||||
|
||||
char timeSpacedStr[20];
|
||||
// add seconds only if colon blink enabled AND weekday hidden ---
|
||||
char timeWithSeconds[12];
|
||||
if (!showDayOfWeek && colonBlinkEnabled) {
|
||||
// Remove any leading space from baseTime
|
||||
const char *trimmedBase = baseTime;
|
||||
if (baseTime[0] == ' ') trimmedBase++; // skip leading space
|
||||
sprintf(timeWithSeconds, "%s:%02d", trimmedBase, timeinfo.tm_sec);
|
||||
} else {
|
||||
strcpy(timeWithSeconds, baseTime); // no seconds
|
||||
}
|
||||
|
||||
// keep spacing logic the same ---
|
||||
char timeSpacedStr[24];
|
||||
int j = 0;
|
||||
for (int i = 0; timeStr[i] != '\0'; i++) {
|
||||
timeSpacedStr[j++] = timeStr[i];
|
||||
if (timeStr[i + 1] != '\0') {
|
||||
for (int i = 0; timeWithSeconds[i] != '\0'; i++) {
|
||||
timeSpacedStr[j++] = timeWithSeconds[i];
|
||||
if (timeWithSeconds[i + 1] != '\0') {
|
||||
timeSpacedStr[j++] = ' ';
|
||||
}
|
||||
}
|
||||
timeSpacedStr[j] = '\0';
|
||||
|
||||
// build final string ---
|
||||
String formattedTime;
|
||||
if (showDayOfWeek) {
|
||||
formattedTime = String(daySymbol) + " " + String(timeSpacedStr);
|
||||
formattedTime = String(daySymbol) + " " + String(timeSpacedStr);
|
||||
} else {
|
||||
formattedTime = String(timeSpacedStr);
|
||||
}
|
||||
@@ -1700,7 +1715,9 @@ void loop() {
|
||||
} else {
|
||||
// NTP and weather are OK — show time
|
||||
String timeString = formattedTime;
|
||||
if (colonBlinkEnabled && !colonVisible) {
|
||||
|
||||
// --- MOD: colon blinks only when weekday is shown ---
|
||||
if (showDayOfWeek && colonBlinkEnabled && !colonVisible) {
|
||||
timeString.replace(":", " ");
|
||||
}
|
||||
P.print(timeString);
|
||||
|
||||
@@ -502,7 +502,7 @@ textarea::placeholder {
|
||||
</label>
|
||||
|
||||
<label style="display: flex; align-items: center; margin-top: 1.75rem; justify-content: space-between;">
|
||||
<span style="margin-right: 0.5em;">Blinking Colon:</span>
|
||||
<span style="margin-right: 0.5em;">Animated Seconds:</span>
|
||||
<span class="toggle-switch">
|
||||
<input type="checkbox" id="colonBlinkEnabled" name="colonBlinkEnabled" onchange="setColonBlink(this.checked)">
|
||||
<span class="toggle-slider"></span>
|
||||
@@ -629,7 +629,6 @@ textarea::placeholder {
|
||||
|
||||
<div class="footer">
|
||||
Project by: <a href="https://www.instagram.com/mfactory.osaka" target="_blank" rel="noopener noreferrer">M-Factory</a><br>
|
||||
Location data by: <a href="https://www.geoplugin.com/" target="_blank">GeoPlugin</a>
|
||||
</div>
|
||||
|
||||
<div id="savingMessage"></div>
|
||||
@@ -1224,35 +1223,38 @@ function setDimmingFieldsEnabled(enabled) {
|
||||
}
|
||||
|
||||
function getLocation() {
|
||||
fetch('http://www.geoplugin.net/json.gp')
|
||||
fetch('http://ip-api.com/json/')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
document.getElementById('openWeatherCity').value = data.geoplugin_latitude;
|
||||
document.getElementById('openWeatherCountry').value = data.geoplugin_longitude;
|
||||
// Update your latitude/longitude fields
|
||||
document.getElementById('openWeatherCity').value = data.lat;
|
||||
document.getElementById('openWeatherCountry').value = data.lon;
|
||||
|
||||
// Determine the label to show on the button
|
||||
const button = document.getElementById('geo-button');
|
||||
let label = data.geoplugin_city;
|
||||
if (!label) label = data.geoplugin_region;
|
||||
if (!label) label = data.geoplugin_countryName;
|
||||
let label = data.city;
|
||||
if (!label) label = data.regionName;
|
||||
if (!label) label = data.country;
|
||||
if (!label) label = "Location Found";
|
||||
|
||||
button.textContent = "Location: " + label;
|
||||
button.disabled = true;
|
||||
button.classList.add('geo-disabled');
|
||||
|
||||
console.log("Location fetched via GeoPlugin. Consider crediting them: https://www.geoplugin.com/");
|
||||
console.log("Location fetched via ip-api.com. Free service: http://ip-api.com/");
|
||||
})
|
||||
.catch(error => {
|
||||
alert(
|
||||
"Failed to guess your location.\n\n" +
|
||||
"This may happen if:\n" +
|
||||
"- You are using an AdBlocker (GeoPlugin might be blocked)\n" +
|
||||
"- You are using an AdBlocker\n" +
|
||||
"- There is a network issue\n" +
|
||||
"- The website might be temporarily down.\n\n" +
|
||||
"You can visit https://openweathermap.org/find to manually search for your city and get latitude/longitude."
|
||||
"- The service might be temporarily down.\n\n" +
|
||||
"You can visit https://openweathermap.org/find to manually search for your city and get latitude/longitude."
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -10,7 +10,7 @@ const DaysOfWeekMapping days_mappings[] = {
|
||||
{ "af", { "s&u&n", "m&a&a", "d&i&n", "w&o&e", "d&o&n", "v&r&y", "s&o&n" } },
|
||||
{ "cs", { "n&e&d", "p&o&n", "u&t&e", "s&t&r", "c&t&v", "p&a&t", "s&o&b" } },
|
||||
{ "da", { "s&o&n", "m&a&n", "t&i&r", "o&n&s", "t&o&r", "f&r&e", "l&o&r" } },
|
||||
{ "de", { "s&o&n", "m&o&n", "d&i&e", "m&i&t", "d&o&n", "f&r&e", "s&a&m" } },
|
||||
{ "de", { "s&o", "m&o", "d&i", "m&i", "d&o", "f&r", "s&a" } },
|
||||
{ "en", { "s&u&n", "m&o&n", "t&u&e", "w&e&d", "t&h&u", "f&r&i", "s&a&t" } },
|
||||
{ "eo", { "d&i&m", "l&u&n", "m&a&r", "m&e&r", "j&a&u", "v&e&n", "s&a&b" } },
|
||||
{ "es", { "d&o&m", "l&u&n", "m&a&r", "m&i&e", "j&u&e", "v&i&e", "s&a&b" } },
|
||||
|
||||
@@ -52,7 +52,7 @@ MD_MAX72XX::fontType_t mFactory[] PROGMEM =
|
||||
1, 128, // 46 - '.'
|
||||
15, 130, 246, 238, 130, 254, 250, 130, 250, 254, 130, 234, 234, 246, 254, 124, // 47 - '/'
|
||||
3, 126, 129, 126, // 48 - '0'
|
||||
2, 2, 255, // 49 - '1'
|
||||
3, 130, 255, 128, // 49 - '1'
|
||||
3, 194, 177, 142, // 50 - '2'
|
||||
3, 66, 137, 118, // 51 - '3'
|
||||
3, 15, 8, 255, // 52 - '4'
|
||||
|
||||
@@ -1604,32 +1604,45 @@ void loop() {
|
||||
weatherFetchInitiated = false;
|
||||
shouldFetchWeatherNow = false;
|
||||
}
|
||||
|
||||
const char *const *daysOfTheWeek = getDaysOfWeek(language);
|
||||
const char *daySymbol = daysOfTheWeek[timeinfo.tm_wday];
|
||||
|
||||
char timeStr[9];
|
||||
// build base HH:MM first ---
|
||||
char baseTime[9];
|
||||
if (twelveHourToggle) {
|
||||
int hour12 = timeinfo.tm_hour % 12;
|
||||
if (hour12 == 0) hour12 = 12;
|
||||
sprintf(timeStr, " %d:%02d", hour12, timeinfo.tm_min);
|
||||
sprintf(baseTime, "%d:%02d", hour12, timeinfo.tm_min);
|
||||
} else {
|
||||
sprintf(timeStr, " %02d:%02d", timeinfo.tm_hour, timeinfo.tm_min);
|
||||
sprintf(baseTime, "%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min);
|
||||
}
|
||||
|
||||
char timeSpacedStr[20];
|
||||
// add seconds only if colon blink enabled AND weekday hidden ---
|
||||
char timeWithSeconds[12];
|
||||
if (!showDayOfWeek && colonBlinkEnabled) {
|
||||
// Remove any leading space from baseTime
|
||||
const char *trimmedBase = baseTime;
|
||||
if (baseTime[0] == ' ') trimmedBase++; // skip leading space
|
||||
sprintf(timeWithSeconds, "%s:%02d", trimmedBase, timeinfo.tm_sec);
|
||||
} else {
|
||||
strcpy(timeWithSeconds, baseTime); // no seconds
|
||||
}
|
||||
|
||||
// keep spacing logic the same ---
|
||||
char timeSpacedStr[24];
|
||||
int j = 0;
|
||||
for (int i = 0; timeStr[i] != '\0'; i++) {
|
||||
timeSpacedStr[j++] = timeStr[i];
|
||||
if (timeStr[i + 1] != '\0') {
|
||||
for (int i = 0; timeWithSeconds[i] != '\0'; i++) {
|
||||
timeSpacedStr[j++] = timeWithSeconds[i];
|
||||
if (timeWithSeconds[i + 1] != '\0') {
|
||||
timeSpacedStr[j++] = ' ';
|
||||
}
|
||||
}
|
||||
timeSpacedStr[j] = '\0';
|
||||
|
||||
// build final string ---
|
||||
String formattedTime;
|
||||
if (showDayOfWeek) {
|
||||
formattedTime = String(daySymbol) + " " + String(timeSpacedStr);
|
||||
formattedTime = String(daySymbol) + " " + String(timeSpacedStr);
|
||||
} else {
|
||||
formattedTime = String(timeSpacedStr);
|
||||
}
|
||||
@@ -1647,8 +1660,6 @@ void loop() {
|
||||
advanceDisplayMode();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --- CLOCK Display Mode ---
|
||||
if (displayMode == 0) {
|
||||
P.setCharSpacing(0);
|
||||
@@ -1696,7 +1707,9 @@ void loop() {
|
||||
} else {
|
||||
// NTP and weather are OK — show time
|
||||
String timeString = formattedTime;
|
||||
if (colonBlinkEnabled && !colonVisible) {
|
||||
|
||||
// --- MOD: colon blinks only when weekday is shown ---
|
||||
if (showDayOfWeek && colonBlinkEnabled && !colonVisible) {
|
||||
timeString.replace(":", " ");
|
||||
}
|
||||
P.print(timeString);
|
||||
|
||||
@@ -502,7 +502,7 @@ textarea::placeholder {
|
||||
</label>
|
||||
|
||||
<label style="display: flex; align-items: center; margin-top: 1.75rem; justify-content: space-between;">
|
||||
<span style="margin-right: 0.5em;">Blinking Colon:</span>
|
||||
<span style="margin-right: 0.5em;">Animated Seconds:</span>
|
||||
<span class="toggle-switch">
|
||||
<input type="checkbox" id="colonBlinkEnabled" name="colonBlinkEnabled" onchange="setColonBlink(this.checked)">
|
||||
<span class="toggle-slider"></span>
|
||||
@@ -629,7 +629,6 @@ textarea::placeholder {
|
||||
|
||||
<div class="footer">
|
||||
Project by: <a href="https://www.instagram.com/mfactory.osaka" target="_blank" rel="noopener noreferrer">M-Factory</a><br>
|
||||
Location data by: <a href="https://www.geoplugin.com/" target="_blank">GeoPlugin</a>
|
||||
</div>
|
||||
|
||||
<div id="savingMessage"></div>
|
||||
@@ -1224,35 +1223,38 @@ function setDimmingFieldsEnabled(enabled) {
|
||||
}
|
||||
|
||||
function getLocation() {
|
||||
fetch('http://www.geoplugin.net/json.gp')
|
||||
fetch('http://ip-api.com/json/')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
document.getElementById('openWeatherCity').value = data.geoplugin_latitude;
|
||||
document.getElementById('openWeatherCountry').value = data.geoplugin_longitude;
|
||||
// Update your latitude/longitude fields
|
||||
document.getElementById('openWeatherCity').value = data.lat;
|
||||
document.getElementById('openWeatherCountry').value = data.lon;
|
||||
|
||||
// Determine the label to show on the button
|
||||
const button = document.getElementById('geo-button');
|
||||
let label = data.geoplugin_city;
|
||||
if (!label) label = data.geoplugin_region;
|
||||
if (!label) label = data.geoplugin_countryName;
|
||||
let label = data.city;
|
||||
if (!label) label = data.regionName;
|
||||
if (!label) label = data.country;
|
||||
if (!label) label = "Location Found";
|
||||
|
||||
button.textContent = "Location: " + label;
|
||||
button.disabled = true;
|
||||
button.classList.add('geo-disabled');
|
||||
|
||||
console.log("Location fetched via GeoPlugin. Consider crediting them: https://www.geoplugin.com/");
|
||||
console.log("Location fetched via ip-api.com. Free service: http://ip-api.com/");
|
||||
})
|
||||
.catch(error => {
|
||||
alert(
|
||||
"Failed to guess your location.\n\n" +
|
||||
"This may happen if:\n" +
|
||||
"- You are using an AdBlocker (GeoPlugin might be blocked)\n" +
|
||||
"- You are using an AdBlocker\n" +
|
||||
"- There is a network issue\n" +
|
||||
"- The website might be temporarily down.\n\n" +
|
||||
"You can visit https://openweathermap.org/find to manually search for your city and get latitude/longitude."
|
||||
"- The service might be temporarily down.\n\n" +
|
||||
"You can visit https://openweathermap.org/find to manually search for your city and get latitude/longitude."
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -10,7 +10,7 @@ const DaysOfWeekMapping days_mappings[] = {
|
||||
{ "af", { "s&u&n", "m&a&a", "d&i&n", "w&o&e", "d&o&n", "v&r&y", "s&o&n" } },
|
||||
{ "cs", { "n&e&d", "p&o&n", "u&t&e", "s&t&r", "c&t&v", "p&a&t", "s&o&b" } },
|
||||
{ "da", { "s&o&n", "m&a&n", "t&i&r", "o&n&s", "t&o&r", "f&r&e", "l&o&r" } },
|
||||
{ "de", { "s&o&n", "m&o&n", "d&i&e", "m&i&t", "d&o&n", "f&r&e", "s&a&m" } },
|
||||
{ "de", { "s&o", "m&o", "d&i", "m&i", "d&o", "f&r", "s&a" } },
|
||||
{ "en", { "s&u&n", "m&o&n", "t&u&e", "w&e&d", "t&h&u", "f&r&i", "s&a&t" } },
|
||||
{ "eo", { "d&i&m", "l&u&n", "m&a&r", "m&e&r", "j&a&u", "v&e&n", "s&a&b" } },
|
||||
{ "es", { "d&o&m", "l&u&n", "m&a&r", "m&i&e", "j&u&e", "v&i&e", "s&a&b" } },
|
||||
|
||||
@@ -52,7 +52,7 @@ MD_MAX72XX::fontType_t mFactory[] PROGMEM =
|
||||
1, 128, // 46 - '.'
|
||||
15, 130, 246, 238, 130, 254, 250, 130, 250, 254, 130, 234, 234, 246, 254, 124, // 47 - '/'
|
||||
3, 126, 129, 126, // 48 - '0'
|
||||
2, 2, 255, // 49 - '1'
|
||||
3, 130, 255, 128, // 49 - '1'
|
||||
3, 194, 177, 142, // 50 - '2'
|
||||
3, 66, 137, 118, // 51 - '3'
|
||||
3, 15, 8, 255, // 52 - '4'
|
||||
|
||||
Reference in New Issue
Block a user