diff --git a/firmware/components/analytics/CMakeLists.txt b/firmware/components/analytics/CMakeLists.txt deleted file mode 100644 index 4d1d66f..0000000 --- a/firmware/components/analytics/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -idf_component_register(SRCS - src/analytics.c - INCLUDE_DIRS "include" - REQUIRES - rmaker_common - esp_insights - rmaker_common -) - -target_add_binary_data(${COMPONENT_TARGET} "insights_auth_key.txt" TEXT) diff --git a/firmware/components/analytics/src/analytics.c b/firmware/components/analytics/src/analytics.c deleted file mode 100644 index 7779144..0000000 --- a/firmware/components/analytics/src/analytics.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "analytics.h" - -#include -#include - -extern const char insights_auth_key_start[] asm("_binary_insights_auth_key_txt_start"); -extern const char insights_auth_key_end[] asm("_binary_insights_auth_key_txt_end"); - -void analytics_init(void) -{ - esp_insights_config_t config = { - .log_type = ESP_DIAG_LOG_TYPE_ERROR | ESP_DIAG_LOG_TYPE_EVENT | ESP_DIAG_LOG_TYPE_WARNING, - .node_id = NULL, - .auth_key = insights_auth_key_start, - .alloc_ext_ram = true, - }; - - esp_insights_init(&config); - - esp_rmaker_time_sync_init(NULL); -} diff --git a/firmware/components/connectivity-manager/CMakeLists.txt b/firmware/components/connectivity-manager/CMakeLists.txt index 807d5b7..5de433a 100644 --- a/firmware/components/connectivity-manager/CMakeLists.txt +++ b/firmware/components/connectivity-manager/CMakeLists.txt @@ -9,8 +9,7 @@ idf_component_register(SRCS bt driver nvs_flash - esp_insights - analytics + skuld led-manager bifrost ) diff --git a/firmware/components/connectivity-manager/src/wifi_manager.c b/firmware/components/connectivity-manager/src/wifi_manager.c index f54d085..a84d5fe 100644 --- a/firmware/components/connectivity-manager/src/wifi_manager.c +++ b/firmware/components/connectivity-manager/src/wifi_manager.c @@ -1,12 +1,11 @@ #include "wifi_manager.h" -#include "analytics.h" +#include "skuld/skuld.h" #include "bifrost/api_server.h" #include "dns_hijack.h" #include "led_status.h" #include "persistence_manager.h" #include -#include #include #include #include @@ -59,7 +58,7 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t e { ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; ESP_LOGI(TAG, "IP_EVENT_STA_GOT_IP: IP-Adresse erhalten: " IPSTR, IP2STR(&event->ip_info.ip)); - analytics_init(); + skuld_init(); xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_LOST_IP) diff --git a/firmware/components/skuld/CMakeLists.txt b/firmware/components/skuld/CMakeLists.txt new file mode 100644 index 0000000..866789a --- /dev/null +++ b/firmware/components/skuld/CMakeLists.txt @@ -0,0 +1,9 @@ +idf_component_register(SRCS + src/skuld.c + INCLUDE_DIRS "include" + PRIV_REQUIRES + lwip + esp_http_client + nvs_flash + cjson +) diff --git a/firmware/components/analytics/include/analytics.h b/firmware/components/skuld/include/skuld/skuld.h similarity index 70% rename from firmware/components/analytics/include/analytics.h rename to firmware/components/skuld/include/skuld/skuld.h index 32cf960..6884497 100644 --- a/firmware/components/analytics/include/analytics.h +++ b/firmware/components/skuld/include/skuld/skuld.h @@ -3,5 +3,5 @@ #include __BEGIN_DECLS -void analytics_init(void); +void skuld_init(void); __END_DECLS diff --git a/firmware/components/skuld/src/skuld.c b/firmware/components/skuld/src/skuld.c new file mode 100644 index 0000000..58e2531 --- /dev/null +++ b/firmware/components/skuld/src/skuld.c @@ -0,0 +1,149 @@ +#include "skuld/skuld.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SKULD_TZ_API_URL "https://api.firmware-hq.dev/v1/timezone" +#define SKULD_NVS_NAMESPACE "skuld" +#define SKULD_NVS_KEY_TZ "tz_posix" +#define SKULD_DEFAULT_TZ "CET-1CEST,M3.5.0,M10.5.0/3" +#define SKULD_TZ_MAX_LEN 64 + +static const char *TAG = "skuld"; + +extern const char isrgrootx1_pem_start[] asm("_binary_isrgrootx1_pem_start"); + +static void on_time_synced(struct timeval *tv) +{ + struct tm timeinfo; + char buf[32]; + localtime_r(&tv->tv_sec, &timeinfo); + strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", &timeinfo); + ESP_LOGI(TAG, "Time synchronized: %s", buf); +} + +static void nvs_save_tz(const char *tz_posix) +{ + nvs_handle_t handle; + if (nvs_open(SKULD_NVS_NAMESPACE, NVS_READWRITE, &handle) != ESP_OK) { + return; + } + nvs_set_str(handle, SKULD_NVS_KEY_TZ, tz_posix); + nvs_commit(handle); + nvs_close(handle); +} + +static bool nvs_load_tz(char *buf, size_t buf_len) +{ + nvs_handle_t handle; + if (nvs_open(SKULD_NVS_NAMESPACE, NVS_READONLY, &handle) != ESP_OK) { + return false; + } + esp_err_t err = nvs_get_str(handle, SKULD_NVS_KEY_TZ, buf, &buf_len); + nvs_close(handle); + return err == ESP_OK; +} + +static bool fetch_tz_from_api(char *out_buf, size_t out_len) +{ + static char response[256]; + int response_len = 0; + + esp_http_client_config_t config = { + .url = SKULD_TZ_API_URL, + .cert_pem = isrgrootx1_pem_start, + .timeout_ms = 5000, + }; + + esp_http_client_handle_t client = esp_http_client_init(&config); + if (!client) { + return false; + } + + esp_err_t err = esp_http_client_open(client, 0); + if (err != ESP_OK) { + ESP_LOGW(TAG, "HTTP open failed: %s", esp_err_to_name(err)); + esp_http_client_cleanup(client); + return false; + } + + esp_http_client_fetch_headers(client); + + if (esp_http_client_get_status_code(client) != 200) { + ESP_LOGW(TAG, "Timezone API returned HTTP %d", esp_http_client_get_status_code(client)); + esp_http_client_close(client); + esp_http_client_cleanup(client); + return false; + } + + response_len = esp_http_client_read(client, response, sizeof(response) - 1); + esp_http_client_close(client); + esp_http_client_cleanup(client); + + if (response_len <= 0) { + return false; + } + response[response_len] = '\0'; + + cJSON *json = cJSON_Parse(response); + if (!json) { + ESP_LOGW(TAG, "Failed to parse JSON response"); + return false; + } + + bool success = false; + const cJSON *posix_tz = cJSON_GetObjectItemCaseSensitive(json, "posix_tz"); + if (cJSON_IsString(posix_tz) && posix_tz->valuestring) { + strncpy(out_buf, posix_tz->valuestring, out_len - 1); + out_buf[out_len - 1] = '\0'; + success = true; + } else { + ESP_LOGW(TAG, "posix_tz not found in response"); + } + + cJSON_Delete(json); + return success; +} + +static void apply_timezone(const char *tz_posix) +{ + setenv("TZ", tz_posix, 1); + tzset(); + ESP_LOGI(TAG, "Timezone set: %s", tz_posix); +} + +void skuld_init(void) +{ + char tz_buf[SKULD_TZ_MAX_LEN] = {0}; + + if (fetch_tz_from_api(tz_buf, sizeof(tz_buf))) { + nvs_save_tz(tz_buf); + ESP_LOGI(TAG, "Timezone from API: %s", tz_buf); + } else if (nvs_load_tz(tz_buf, sizeof(tz_buf))) { + ESP_LOGI(TAG, "Timezone from NVS: %s", tz_buf); + } else { + strncpy(tz_buf, SKULD_DEFAULT_TZ, sizeof(tz_buf) - 1); + ESP_LOGW(TAG, "Timezone fallback: %s", tz_buf); + } + + apply_timezone(tz_buf); + + if (esp_sntp_enabled()) { + ESP_LOGI(TAG, "SNTP already initialized."); + return; + } + + esp_sntp_setoperatingmode(SNTP_OPMODE_POLL); + esp_sntp_setservername(0, "pool.ntp.org"); + sntp_set_sync_interval(CONFIG_LWIP_SNTP_UPDATE_DELAY); + sntp_set_time_sync_notification_cb(on_time_synced); + esp_sntp_init(); + + ESP_LOGI(TAG, "SNTP initialized, re-sync every %d min.", CONFIG_LWIP_SNTP_UPDATE_DELAY / 60000); +} diff --git a/firmware/main/CMakeLists.txt b/firmware/main/CMakeLists.txt index 10052e0..4738dbc 100755 --- a/firmware/main/CMakeLists.txt +++ b/firmware/main/CMakeLists.txt @@ -10,7 +10,6 @@ idf_component_register(SRCS heimdall hermes mercedes - analytics connectivity-manager led-manager persistence-manager @@ -22,7 +21,6 @@ idf_component_register(SRCS esp_event esp_wifi app_update - rmaker_common driver my_mqtt_client ) diff --git a/firmware/main/idf_component.yml b/firmware/main/idf_component.yml index 7d8e0f2..1f0f9d0 100755 --- a/firmware/main/idf_component.yml +++ b/firmware/main/idf_component.yml @@ -4,4 +4,3 @@ dependencies: # u8g2_hal: # git: https://github.com/mkfrey/u8g2-hal-esp-idf.git espressif/button: ^4.1.6 - espressif/esp_insights: ^1.3.2 diff --git a/firmware/main/src/app_task.cpp b/firmware/main/src/app_task.cpp index a508094..aefe2b7 100644 --- a/firmware/main/src/app_task.cpp +++ b/firmware/main/src/app_task.cpp @@ -1,5 +1,4 @@ #include "app_task.h" -#include "analytics.h" #include "button_handling.h" #include "common.h" #include "hal/u8g2_esp32_hal.h" @@ -17,8 +16,6 @@ #include #include -#include -#include #include #include #include @@ -61,11 +58,11 @@ static void setup_screen(void) u8g2_Setup_sh1106_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8g2_esp32_i2c_byte_cb, u8g2_esp32_gpio_and_delay_cb); u8x8_SetI2CAddress(&u8g2.u8x8, DISPLAY_I2C_ADDRESS << 1); - ESP_DIAG_EVENT(TAG, "u8g2_InitDisplay"); + ESP_LOGI(TAG, "u8g2_InitDisplay"); u8g2_InitDisplay(&u8g2); vTaskDelay(pdMS_TO_TICKS(10)); - ESP_DIAG_EVENT(TAG, "u8g2_SetPowerSave"); + ESP_LOGI(TAG, "u8g2_SetPowerSave"); u8g2_SetPowerSave(&u8g2, 0); vTaskDelay(pdMS_TO_TICKS(10)); diff --git a/firmware/main/src/button_handling.c b/firmware/main/src/button_handling.c index 588ea56..1a8fc23 100644 --- a/firmware/main/src/button_handling.c +++ b/firmware/main/src/button_handling.c @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -39,7 +38,7 @@ static void button_event_cb(void *arg, void *usr_data) uint8_t gpio_num = data->gpio; const char *button_name = button_names[data->index]; - ESP_DIAG_EVENT(TAG, "Button %s pressed (GPIO %d)", button_name, gpio_num); + ESP_LOGI(TAG, "Button %s pressed (GPIO %d)", button_name, gpio_num); if (xQueueSend(buttonQueue, &gpio_num, 0) != pdTRUE) { @@ -76,7 +75,7 @@ void setup_buttons(void) return; } - ESP_DIAG_EVENT(TAG, "Button queue created successfully"); + ESP_LOGI(TAG, "Button queue created successfully"); for (int i = 0; i < sizeof(gpios) / sizeof(gpios[0]); i++) { init_button(gpios[i], i); diff --git a/firmware/main/src/i2c_checker.c b/firmware/main/src/i2c_checker.c index e088073..a451dd4 100644 --- a/firmware/main/src/i2c_checker.c +++ b/firmware/main/src/i2c_checker.c @@ -2,7 +2,6 @@ #include "hal/u8g2_esp32_hal.h" #include -#include #include static const char *TAG = "i2c_checker"; @@ -57,7 +56,7 @@ esp_err_t i2c_bus_scan_and_check(void) { ESP_LOGW(TAG, "Failed to delete I2C master bus: %s", esp_err_to_name(del_err)); } - ESP_DIAG_EVENT(TAG, "I2C master bus deleted."); + ESP_LOGI(TAG, "I2C master bus deleted."); return err; } diff --git a/firmware/main/src/main.cpp b/firmware/main/src/main.cpp index 9a3ebd8..e65affe 100644 --- a/firmware/main/src/main.cpp +++ b/firmware/main/src/main.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/firmware/partitions.csv b/firmware/partitions.csv index 1ebe7ab..c8c0eb0 100644 --- a/firmware/partitions.csv +++ b/firmware/partitions.csv @@ -1,8 +1,6 @@ # Name , Type , SubType , Offset , Size , Flags nvs , data , nvs , 0x9000 , 16k , -otadata , data , ota , , 8k , phy_init , data , phy , , 4k , -ota_0 , app , ota_0 , 0x10000 , 1536K , -ota_1 , app , ota_1 , , 1536K , -storage , data , spiffs , , 832K , -fctry , data , nvs , , 24k , +app , app , factory , 0x10000 , 2048K , +storage , data , spiffs , , 1856K , +fctry , data , nvs , 0x3E0000, 24k , diff --git a/firmware/sdkconfig.defaults b/firmware/sdkconfig.defaults index 9b6485d..c111034 100755 --- a/firmware/sdkconfig.defaults +++ b/firmware/sdkconfig.defaults @@ -17,27 +17,12 @@ CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y -CONFIG_ESP_INSIGHTS_ENABLED=y -CONFIG_ESP_INSIGHTS_META_VERSION_10=n - -CONFIG_DIAG_ENABLE_METRICS=y -CONFIG_DIAG_ENABLE_HEAP_METRICS=y -CONFIG_DIAG_ENABLE_WIFI_METRICS=y -CONFIG_DIAG_ENABLE_VARIABLES=y -CONFIG_DIAG_ENABLE_NETWORK_VARIABLES=y - -# Core dump -CONFIG_ESP32_ENABLE_COREDUMP=y -CONFIG_ESP32_ENABLE_COREDUMP_TO_UART=y -CONFIG_ESP32_COREDUMP_DATA_FORMAT_ELF=y -CONFIG_ESP32_COREDUMP_CHECKSUM_CRC32=y -CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM=64 -CONFIG_ESP32_CORE_DUMP_STACK_SIZE=1024 - -CONFIG_ESP_RMAKER_DEF_TIMEZONE="Europe/Berlin" - -# LWIP +# LWIP / SNTP CONFIG_LWIP_LOCAL_HOSTNAME="system-control" +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +CONFIG_LWIP_SNTP_UPDATE_DELAY=14400000 +CONFIG_LWIP_SNTP_STARTUP_DELAY=y +CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 # ESP PSRAM CONFIG_SPIRAM=y @@ -56,3 +41,7 @@ CONFIG_MQTT_CLIENT_PASSWORD="3jHLhNPLcn_dPrukrpMJ" # Compiler Options CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y + +# Certificate Bundle +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y