pi server realised
This commit is contained in:
@@ -89,6 +89,33 @@ void UserApp_TaskInit(void)
|
||||
|
||||
/* ---------- WebSocket callbacks ---------- */
|
||||
|
||||
static void rtc_sync_if_needed(const pi_stats_t *stats)
|
||||
{
|
||||
if (!stats->time_valid) return;
|
||||
|
||||
rtcTimeStruct_t rtc = {};
|
||||
Rtc_GetTime(&rtc);
|
||||
|
||||
/* Convert both to seconds-since-midnight for comparison */
|
||||
int pi_secs = stats->time_hour * 3600 + stats->time_minute * 60 + stats->time_second;
|
||||
int rtc_secs = rtc.hour * 3600 + rtc.minute * 60 + rtc.second;
|
||||
int delta = pi_secs - rtc_secs;
|
||||
if (delta < 0) delta = -delta;
|
||||
|
||||
/* Also check date mismatch as an immediate trigger */
|
||||
bool date_mismatch = (rtc.year != stats->time_year ||
|
||||
rtc.month != stats->time_month ||
|
||||
rtc.day != stats->time_day);
|
||||
|
||||
if (date_mismatch || delta > 60) {
|
||||
Rtc_SetTime(stats->time_year, stats->time_month, stats->time_day,
|
||||
stats->time_hour, stats->time_minute, stats->time_second);
|
||||
ESP_LOGI(TAG, "RTC synced from Pi: %04d-%02d-%02d %02d:%02d:%02d (drift: %ds)",
|
||||
stats->time_year, stats->time_month, stats->time_day,
|
||||
stats->time_hour, stats->time_minute, stats->time_second, delta);
|
||||
}
|
||||
}
|
||||
|
||||
static void ws_data_cb(const pi_stats_t *stats)
|
||||
{
|
||||
/* Check alert conditions */
|
||||
@@ -103,6 +130,9 @@ static void ws_data_cb(const pi_stats_t *stats)
|
||||
}
|
||||
}
|
||||
|
||||
/* Sync RTC if Pi time drifts from board clock */
|
||||
rtc_sync_if_needed(stats);
|
||||
|
||||
/* Update UI under LVGL lock */
|
||||
if (Lvgl_lock(100)) {
|
||||
dashboard_ui_update_stats(stats);
|
||||
|
||||
@@ -97,6 +97,30 @@ static void parse_stats_json(const char *data, int len)
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse local_time object for RTC sync */
|
||||
cJSON *lt = cJSON_GetObjectItem(root, "local_time");
|
||||
if (cJSON_IsObject(lt)) {
|
||||
cJSON *y = cJSON_GetObjectItem(lt, "y");
|
||||
cJSON *mo = cJSON_GetObjectItem(lt, "mo");
|
||||
cJSON *d = cJSON_GetObjectItem(lt, "d");
|
||||
cJSON *h = cJSON_GetObjectItem(lt, "h");
|
||||
cJSON *m = cJSON_GetObjectItem(lt, "m");
|
||||
cJSON *s = cJSON_GetObjectItem(lt, "s");
|
||||
if (y && mo && d && h && m && s) {
|
||||
s_stats.time_year = (uint16_t)y->valuedouble;
|
||||
s_stats.time_month = (uint8_t)mo->valuedouble;
|
||||
s_stats.time_day = (uint8_t)d->valuedouble;
|
||||
s_stats.time_hour = (uint8_t)h->valuedouble;
|
||||
s_stats.time_minute = (uint8_t)m->valuedouble;
|
||||
s_stats.time_second = (uint8_t)s->valuedouble;
|
||||
s_stats.time_valid = true;
|
||||
} else {
|
||||
s_stats.time_valid = false;
|
||||
}
|
||||
} else {
|
||||
s_stats.time_valid = false;
|
||||
}
|
||||
|
||||
s_stats.valid = true;
|
||||
xSemaphoreGive(s_stats_mutex);
|
||||
|
||||
|
||||
@@ -36,6 +36,15 @@ typedef struct {
|
||||
uint8_t service_count;
|
||||
uint32_t last_update; // timestamp from server
|
||||
bool valid; // set true after first successful parse
|
||||
|
||||
/* Broken-down local time from Pi for RTC sync */
|
||||
uint16_t time_year;
|
||||
uint8_t time_month;
|
||||
uint8_t time_day;
|
||||
uint8_t time_hour;
|
||||
uint8_t time_minute;
|
||||
uint8_t time_second;
|
||||
bool time_valid; // true when local_time object was parsed
|
||||
} pi_stats_t;
|
||||
|
||||
typedef void (*ws_data_callback_t)(const pi_stats_t *stats);
|
||||
|
||||
Reference in New Issue
Block a user