From c51e17e96c8c1808b15ce28a58916ada687053dd Mon Sep 17 00:00:00 2001 From: Advaith Menon Date: Tue, 25 Nov 2025 10:14:45 -0500 Subject: [PATCH] Finish RTC Clock * Get up-to-date time from timehttp.bp4k.net --- main/task_lcd.c | 9 ++-- main/task_wifi.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 120 insertions(+), 5 deletions(-) diff --git a/main/task_lcd.c b/main/task_lcd.c index 97de30d..9ac5b64 100644 --- a/main/task_lcd.c +++ b/main/task_lcd.c @@ -259,12 +259,13 @@ void lcd_clock_loop(gl_display_t *disp) { while (1) { struct gt_btn_msg_t *btnmsg; time_t tm = time(NULL); + struct tm *timest = localtime(&tm); char txt[12]; // snprintf(txt, 10, "%lld", (long long) tm); - snprintf(txt, 12, "%02lld:%02lld %s", - tm / (60 * 60) % 12, - tm / 60 % 60, - (tm / (60 * 60) % 24 > 12) ? "PM" : "AM"); + snprintf(txt, 12, "%02d:%02d %s", + timest->tm_hour % 12 == 0 ? 12 : timest->tm_hour % 12, + timest->tm_min, + (timest->tm_hour > 12) ? "PM" : "AM"); /*gl_txt_Italic(disp, 1);*/ uint16_t chw = txt_strw(disp, txt); gl_gfx_MoveTo(disp, (LCD_WIDTH / 2) - (chw / 2), (LCD_HEIGHT / 2) diff --git a/main/task_wifi.c b/main/task_wifi.c index c68bea4..c40c657 100644 --- a/main/task_wifi.c +++ b/main/task_wifi.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" @@ -23,6 +24,7 @@ #define WIFI_SSID_SIZE 16 #define WIFI_PASS_SIZE 32 +#define RTC_UPDATE_TIME 600 #define EXAMPLE_ESP_MAXIMUM_RETRY 3 @@ -39,7 +41,7 @@ /* Constants that aren't configurable in menuconfig */ #define WEB_SERVER "timehttp.bp4k.net" #define WEB_PORT "80" -#define WEB_PATH "/" +#define WEB_PATH "/?epoch=1" static const char *TAG = "task_wifi"; @@ -56,6 +58,7 @@ static EventGroupHandle_t s_wifi_event_group; /* local fns */ int get_wifi_creds(char *username, size_t usz, char *password, size_t psz); void wifi_init_sta(char *username, char *password); +void http_get_task(void); void task_wifi_time(void *pvParams) { @@ -91,6 +94,7 @@ void task_wifi_time(void *pvParams) { ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); wifi_init_sta(wifi_ssid, wifi_pass); + http_get_task(); vTaskDelete(NULL); } @@ -235,3 +239,113 @@ void wifi_init_sta(char *username, char *password) { ESP_EARLY_LOGE(TAG, "UNEXPECTED EVENT"); } } + + +void http_get_task() +{ + const struct addrinfo hints = { + .ai_family = AF_INET, + .ai_socktype = SOCK_STREAM, + }; + struct addrinfo *res; + struct in_addr *addr; + int s, r; + char recv_buf[64]; + + char rnrn[4]; + int8_t dosave = -1; + char tmbuf[16]; + + while(1) { + int err = getaddrinfo(WEB_SERVER, WEB_PORT, &hints, &res); + + if(err != 0 || res == NULL) { + ESP_LOGE(TAG, "DNS lookup failed err=%d res=%p", err, res); + vTaskDelay(1000 / portTICK_PERIOD_MS); + continue; + } + + /* Code to print the resolved IP. + + Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */ + addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; + ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", inet_ntoa(*addr)); + + s = socket(res->ai_family, res->ai_socktype, 0); + if(s < 0) { + ESP_LOGE(TAG, "... Failed to allocate socket."); + freeaddrinfo(res); + vTaskDelay(1000 / portTICK_PERIOD_MS); + continue; + } + ESP_LOGI(TAG, "... allocated socket"); + + if(connect(s, res->ai_addr, res->ai_addrlen) != 0) { + ESP_LOGE(TAG, "... socket connect failed errno=%d", errno); + close(s); + freeaddrinfo(res); + vTaskDelay(4000 / portTICK_PERIOD_MS); + continue; + } + + ESP_LOGI(TAG, "... connected"); + freeaddrinfo(res); + + if (write(s, REQUEST, strlen(REQUEST)) < 0) { + ESP_LOGE(TAG, "... socket send failed"); + close(s); + vTaskDelay(4000 / portTICK_PERIOD_MS); + continue; + } + ESP_LOGI(TAG, "... socket send success"); + + struct timeval receiving_timeout; + receiving_timeout.tv_sec = 5; + receiving_timeout.tv_usec = 0; + if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &receiving_timeout, + sizeof(receiving_timeout)) < 0) { + ESP_LOGE(TAG, "... failed to set socket receiving timeout"); + close(s); + vTaskDelay(4000 / portTICK_PERIOD_MS); + continue; + } + ESP_LOGI(TAG, "... set socket receiving timeout success"); + + /* Read HTTP response */ + do { + bzero(recv_buf, sizeof(recv_buf)); + r = read(s, recv_buf, sizeof(recv_buf)-1); + for(int i = 0; i < r; i++) { + putchar(recv_buf[i]); + if (dosave) + rnrn[3] = rnrn[2]; + rnrn[2] = rnrn[1]; + rnrn[1] = rnrn[0]; + rnrn[0] = recv_buf[i]; + + if (!strncmp(rnrn, "\r\n", 2)) dosave = 0; + + if (dosave > -1 && dosave < 15) { + tmbuf[dosave++] = recv_buf[i]; + } + } + } while(r > 0); + tmbuf[dosave - 1] = '\0'; + + ESP_LOGI(TAG, "... done reading from socket. Last read return=%d errno=%d.", r, errno); + close(s); + + time_t tm = (time_t) atol(tmbuf + 2); + ESP_EARLY_LOGI(TAG, "the time is: <<%d>>", (int) tm); + + struct timeval timestruct = { + .tv_sec = tm - 60 * 60 * 5 + }; + if (settimeofday(×truct, NULL)) + ESP_EARLY_LOGE(TAG, "failed to update time"); + + vTaskDelay(pdMS_TO_TICKS(RTC_UPDATE_TIME * 1000)); + ESP_LOGI(TAG, "Starting again!"); + dosave = -1; + } +} -- 2.47.3