Print next race time in local time.
This commit is contained in:
1 parent
b67432ed5d
commit
f429f32890
2 files changed
+61
-16
No files matched your search
+55
-12
@@ -5,10 +5,36 @@
|
|||||||
#include "secrets.h"
|
#include "secrets.h"
|
||||||
#include "ArduinoJson.h"
|
#include "ArduinoJson.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "time.h"
|
||||||
|
|
||||||
|
extern "C" char *strptime(const char *__restrict, const char *__restrict, struct tm *__restrict); // Not exposed by headers?
|
||||||
|
|
||||||
|
// Portable replacement for missing timegm()
|
||||||
|
time_t timegm(struct tm *t) {
|
||||||
|
int year = t->tm_year + 1900;
|
||||||
|
int mon = t->tm_mon + 1; // 1 to 12
|
||||||
|
int day = t->tm_mday;
|
||||||
|
|
||||||
|
// Shift year/month to make March month 0 (simplifies leap year calculation)
|
||||||
|
int a = (14 - mon) / 12;
|
||||||
|
int y = year + 4800 - a;
|
||||||
|
int m = mon + 12 * a - 3;
|
||||||
|
|
||||||
|
// Calculate Julian Day Number
|
||||||
|
long jdn = day + (153 * m + 2) / 5 + 365L * y + y / 4 - y / 100 + y / 400 - 32045;
|
||||||
|
|
||||||
|
// Days since Unix epoch (1970-01-01 is JDN 2440588)
|
||||||
|
long days = jdn - 2440588;
|
||||||
|
|
||||||
|
return (time_t)(days * 86400L +
|
||||||
|
t->tm_hour * 3600L +
|
||||||
|
t->tm_min * 60L +
|
||||||
|
t->tm_sec);
|
||||||
|
}
|
||||||
|
|
||||||
struct session_info_t {
|
struct session_info_t {
|
||||||
char session_name[50];
|
char session_name[50];
|
||||||
char date_start[32];
|
struct tm date_start;
|
||||||
char circuit_short_name[50];
|
char circuit_short_name[50];
|
||||||
uint16_t session_key;
|
uint16_t session_key;
|
||||||
uint16_t meeting_key;
|
uint16_t meeting_key;
|
||||||
@@ -118,10 +144,24 @@ int parse_session_json(JsonArray sessions, session_info_t* target, const Semapho
|
|||||||
JsonObject nextRaceJson = sessions[0];
|
JsonObject nextRaceJson = sessions[0];
|
||||||
session_info_t localData;
|
session_info_t localData;
|
||||||
|
|
||||||
strptime();
|
struct tm utc_tm;
|
||||||
|
memset(&utc_tm, 0, sizeof(struct tm));
|
||||||
|
strptime(nextRaceJson[F("date_start")], "%Y-%m-%dT%H:%M:%S", &utc_tm);
|
||||||
|
|
||||||
|
// 2. Convert UTC struct tm to time_t Unix timestamp
|
||||||
|
time_t raw_time = timegm(&utc_tm);
|
||||||
|
|
||||||
|
// 3. Convert time_t to local struct tm
|
||||||
|
struct tm local_tm;
|
||||||
|
localtime_r(&raw_time, &localData.date_start);
|
||||||
|
|
||||||
|
char buffer[64];
|
||||||
|
strftime(buffer, sizeof(buffer), "%Y-%m-%d %I:%M:%S %p %Z", &local_tm);
|
||||||
|
Serial.print("");
|
||||||
|
Serial.print("Session local: ");
|
||||||
|
Serial.println(buffer);
|
||||||
|
|
||||||
const char* sessionName = nextRaceJson[F("session_name")];
|
const char* sessionName = nextRaceJson[F("session_name")];
|
||||||
const char* dateStart = nextRaceJson[F("date_start")];
|
|
||||||
const char* circuitName = nextRaceJson[F("circuit_short_name")];
|
const char* circuitName = nextRaceJson[F("circuit_short_name")];
|
||||||
|
|
||||||
localData.session_key = nextRaceJson[F("session_key")];
|
localData.session_key = nextRaceJson[F("session_key")];
|
||||||
@@ -132,15 +172,12 @@ int parse_session_json(JsonArray sessions, session_info_t* target, const Semapho
|
|||||||
|
|
||||||
localData.circuit_key = nextRaceJson[F("circuit_key")];
|
localData.circuit_key = nextRaceJson[F("circuit_key")];
|
||||||
if (localData.circuit_key == 0) return -1;
|
if (localData.circuit_key == 0) return -1;
|
||||||
|
if (localData.date_start.tm_year == 0) return -1;
|
||||||
|
|
||||||
if (sessionName != NULL) {
|
if (sessionName != NULL) {
|
||||||
strlcpy(localData.session_name, sessionName, sizeof(localData.session_name));
|
strlcpy(localData.session_name, sessionName, sizeof(localData.session_name));
|
||||||
cleanToASCIIInPlace(localData.session_name);
|
cleanToASCIIInPlace(localData.session_name);
|
||||||
} else return -1;
|
} else return -1;
|
||||||
if (dateStart != NULL) {
|
|
||||||
strlcpy(localData.date_start, dateStart, sizeof(localData.date_start));
|
|
||||||
cleanToASCIIInPlace(localData.date_start);
|
|
||||||
} else return -1;
|
|
||||||
if (circuitName != NULL) {
|
if (circuitName != NULL) {
|
||||||
strlcpy(localData.circuit_short_name, circuitName, sizeof(localData.circuit_short_name));
|
strlcpy(localData.circuit_short_name, circuitName, sizeof(localData.circuit_short_name));
|
||||||
cleanToASCIIInPlace(localData.circuit_short_name);
|
cleanToASCIIInPlace(localData.circuit_short_name);
|
||||||
@@ -231,11 +268,14 @@ void get_next_race(void *pvParameters) {
|
|||||||
if (err == DeserializationError::Ok) {
|
if (err == DeserializationError::Ok) {
|
||||||
JsonArray meetings = json.as<JsonArray>();
|
JsonArray meetings = json.as<JsonArray>();
|
||||||
if (meetings.size() != 0) {
|
if (meetings.size() != 0) {
|
||||||
parse_meeting_json(meetings, &race_data.meeting_info, &dataMutex);
|
if (parse_meeting_json(meetings, &race_data.meeting_info, &dataMutex) != 0) {
|
||||||
|
Serial.print("");
|
||||||
|
Serial.println(F("Failed to parse meeting data."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Serial.print("");
|
Serial.print("");
|
||||||
Serial.print("Failed to parse JSON response: ");
|
Serial.print(F("Failed to parse JSON response: "));
|
||||||
Serial.println(err.c_str());
|
Serial.println(err.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,11 +315,14 @@ void get_next_race(void *pvParameters) {
|
|||||||
if (err == DeserializationError::Ok) {
|
if (err == DeserializationError::Ok) {
|
||||||
JsonArray sessions = json.as<JsonArray>();
|
JsonArray sessions = json.as<JsonArray>();
|
||||||
if (sessions.size() != 0) {
|
if (sessions.size() != 0) {
|
||||||
parse_session_json(sessions, &race_data.session_info, &dataMutex);
|
if (parse_session_json(sessions, &race_data.session_info, &dataMutex) != 0) {
|
||||||
|
Serial.print("");
|
||||||
|
Serial.println(F("Failed to parse session data"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Serial.print("");
|
Serial.print("");
|
||||||
Serial.print("Failed to parse JSON response: ");
|
Serial.print(F("Failed to parse JSON response: "));
|
||||||
Serial.println(err.c_str());
|
Serial.println(err.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,7 +340,7 @@ void get_next_race(void *pvParameters) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
Serial.print("");
|
Serial.print("");
|
||||||
Serial.println("WiFi not connecteFormattedd.");
|
Serial.println(F("WiFi not connected."));
|
||||||
}
|
}
|
||||||
vTaskDelay(retryDelay);
|
vTaskDelay(retryDelay);
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -56,7 +56,7 @@ void wifi_connect() {
|
|||||||
|
|
||||||
void sync_time() {
|
void sync_time() {
|
||||||
if (WiFi.status() != WL_CONNECTED) {
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
Serial.println("Skipping NTP synchronization because WiFi is disconnected.");
|
Serial.println(F("Skipping NTP synchronization because WiFi is disconnected."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ void sync_time() {
|
|||||||
Serial.print("Time synchronized: ");
|
Serial.print("Time synchronized: ");
|
||||||
Serial.println(asctime(&timeinfo));
|
Serial.println(asctime(&timeinfo));
|
||||||
} else {
|
} else {
|
||||||
Serial.println("Failed to synchronize time within 10 seconds.");
|
Serial.println(F("Failed to synchronize time within 10 seconds."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,8 +115,10 @@ void display_loop(void *pvParameters) {
|
|||||||
|
|
||||||
Paint_Clear(WHITE);
|
Paint_Clear(WHITE);
|
||||||
|
|
||||||
if (local_data.session_info.date_start[0] != 0) {
|
if (local_data.session_info.date_start.tm_year != 0) {
|
||||||
Paint_DrawString_EN(10, 22, local_data.session_info.date_start, &Font16, WHITE, BLACK);
|
char date_buffer[30];
|
||||||
|
strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d %I:%M:%S %p %Z", &local_data.session_info.date_start);
|
||||||
|
Paint_DrawString_EN(10, 22, date_buffer, &Font16, WHITE, BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
Paint_DrawString_EN(10, 0, counterStr, &Font16, WHITE, BLACK);
|
Paint_DrawString_EN(10, 0, counterStr, &Font16, WHITE, BLACK);
|
||||||
|
|||||||
Reference in new issue
Block a user