From d1cb50cf98038b66f5a5a4ed4f025065dcb411132dee0ac591dffc372a54ecc9 Mon Sep 17 00:00:00 2001 From: localhorst Date: Mon, 16 Dec 2024 22:12:29 +0100 Subject: [PATCH 1/5] some idea --- main/main.c | 56 +++++++++++++++++++++++++++++++++++++++++++++----- main/metrics.c | 2 ++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/main/main.c b/main/main.c index 1ee85ff..a1f6628 100644 --- a/main/main.c +++ b/main/main.c @@ -11,6 +11,9 @@ #include #include "freertos/timers.h" #include "nvs_flash.h" +#include +#include +#include #include "safety.h" #include "metrics.h" @@ -23,6 +26,39 @@ static const char *TAG = "smart-oil-heater-control-system"; +// Function to wait for time synchronization +void obtain_time() +{ + time_t now = 0; + struct tm timeinfo = {0}; + + // Wait for the time to be set + // while (timeinfo.tm_year < (2020 - 1900)) + { + ESP_LOGI(TAG, "Waiting for system time to be set..."); + vTaskDelay(2000 / portTICK_PERIOD_MS); + time(&now); + localtime_r(&now, &timeinfo); + } + + ESP_LOGI(TAG, "System time is set."); +} + +// Function to print the current time +void print_current_time() +{ + time_t now; + struct tm timeinfo; + + time(&now); + localtime_r(&now, &timeinfo); + + char strftime_buf[64]; + strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo); + + ESP_LOGI(TAG, "Current time: %s", strftime_buf); +} + void app_main(void) { ESP_LOGI(TAG, "starting ..."); @@ -37,14 +73,24 @@ void app_main(void) ESP_ERROR_CHECK(ret); // TODO: Error handling! - initOutputs(); - initInputs(); - initSafety(); - initControl(); + //initOutputs(); + //initInputs(); + //initSafety(); + //initControl(); initMetrics(); + esp_sntp_setoperatingmode(SNTP_OPMODE_POLL); + esp_sntp_setservername(0, "10.1.0.1"); // Set NTP server + esp_sntp_init(); + while (1) { - vTaskDelay(pdMS_TO_TICKS(2048)); + vTaskDelay(pdMS_TO_TICKS(10000U)); + + // Obtain the current time + obtain_time(); + + // Print the current time + print_current_time(); } } \ No newline at end of file diff --git a/main/metrics.c b/main/metrics.c index c7cce67..2823dbb 100644 --- a/main/metrics.c +++ b/main/metrics.c @@ -38,6 +38,8 @@ esp_err_t get_metrics_handler(httpd_req_t *req); void initMetrics(void) { connect_wifi(); + return; + setup_server(); BaseType_t taskCreated = xTaskCreate( -- 2.47.1 From 15b74c91f46607e68c9141f99794ecfbc2d3ffbdb34ebee64735eda090a10e65 Mon Sep 17 00:00:00 2001 From: localhorst Date: Tue, 17 Dec 2024 22:26:04 +0100 Subject: [PATCH 2/5] set server and cleanup --- .vscode/c_cpp_properties.json | 27 +++++++++++++++++++++ main/main.c | 45 +++++++++++++---------------------- 2 files changed, 44 insertions(+), 28 deletions(-) create mode 100644 .vscode/c_cpp_properties.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..0546715 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,27 @@ +{ + "configurations": [ + { + "name": "ESP-IDF", + "compilerPath": "${default}", + "compileCommands": "${workspaceFolder}/build/compile_commands.json", + "includePath": [ + "${config:idf.espIdfPath}/components/**", + "${config:idf.espIdfPathWin}/components/**", + "${config:idf.espAdfPath}/components/**", + "${config:idf.espAdfPathWin}/components/**", + "${workspaceFolder}/**" + ], + "browse": { + "path": [ + "${config:idf.espIdfPath}/components", + "${config:idf.espIdfPathWin}/components", + "${config:idf.espAdfPath}/components/**", + "${config:idf.espAdfPathWin}/components/**", + "${workspaceFolder}" + ], + "limitSymbolsToIncludedHeaders": false + } + } + ], + "version": 4 + } \ No newline at end of file diff --git a/main/main.c b/main/main.c index a1f6628..8751ec7 100644 --- a/main/main.c +++ b/main/main.c @@ -26,24 +26,6 @@ static const char *TAG = "smart-oil-heater-control-system"; -// Function to wait for time synchronization -void obtain_time() -{ - time_t now = 0; - struct tm timeinfo = {0}; - - // Wait for the time to be set - // while (timeinfo.tm_year < (2020 - 1900)) - { - ESP_LOGI(TAG, "Waiting for system time to be set..."); - vTaskDelay(2000 / portTICK_PERIOD_MS); - time(&now); - localtime_r(&now, &timeinfo); - } - - ESP_LOGI(TAG, "System time is set."); -} - // Function to print the current time void print_current_time() { @@ -59,6 +41,13 @@ void print_current_time() ESP_LOGI(TAG, "Current time: %s", strftime_buf); } +// SNTP Callback function +void time_sync_notification_cb(struct timeval *tv) +{ + ESP_LOGI(TAG, "SNTP synchronization completed! Unix Time: %lld", tv->tv_sec); + ESP_LOGI(TAG, "Time synchronization callback called."); +} + void app_main(void) { ESP_LOGI(TAG, "starting ..."); @@ -73,24 +62,24 @@ void app_main(void) ESP_ERROR_CHECK(ret); // TODO: Error handling! - //initOutputs(); - //initInputs(); - //initSafety(); - //initControl(); + // initOutputs(); + // initInputs(); + // initSafety(); + // initControl(); initMetrics(); esp_sntp_setoperatingmode(SNTP_OPMODE_POLL); - esp_sntp_setservername(0, "10.1.0.1"); // Set NTP server + esp_sntp_setservername(0, "10.1.0.1"); // Set first NTP server local router + + sntp_set_time_sync_notification_cb(time_sync_notification_cb); // Register the SNTP time sync callback esp_sntp_init(); while (1) { - vTaskDelay(pdMS_TO_TICKS(10000U)); - - // Obtain the current time - obtain_time(); - + vTaskDelay(pdMS_TO_TICKS(1000)); // Print the current time print_current_time(); + + ESP_LOGI(TAG, "SNTP Server 0 reachability: %i", esp_sntp_getreachability(0)); } } \ No newline at end of file -- 2.47.1 From 0b9f5e2997506ba70b30d4775b23176ff6281cf4b02b4602da8d2d1a634a8787 Mon Sep 17 00:00:00 2001 From: localhorst Date: Thu, 19 Dec 2024 18:58:05 +0100 Subject: [PATCH 3/5] own wifi module --- .vscode/settings.json | 5 +- README.md | 10 ++++ main/CMakeLists.txt | 4 +- main/main.c | 16 ++++--- main/metrics.c | 104 ---------------------------------------- main/metrics.h | 2 - main/sntp.c | 0 main/sntp.h | 0 main/wifi.c | 108 ++++++++++++++++++++++++++++++++++++++++++ main/wifi.h | 3 ++ 10 files changed, 137 insertions(+), 115 deletions(-) create mode 100644 main/sntp.c create mode 100644 main/sntp.h create mode 100644 main/wifi.c create mode 100644 main/wifi.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 884c37d..34ff52a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,7 +17,10 @@ "type_traits": "c", "cmath": "c", "*.tcc": "c", - "*.inc": "c" + "*.inc": "c", + "safety.h": "c", + "event_groups.h": "c", + "string.h": "c" }, "idf.openOcdConfigs": [ "board/esp32-wrover-kit-3.3v.cfg" diff --git a/README.md b/README.md index 9b900e1..f0dbad7 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,16 @@ Safety <|-- HTTP_Metrics +getSafetyState() } + + class Wifi{ + +initWifi() + } + + class SNTP{ + +initSntp() + +getSntpState() + } + class Metrics{ +initMetrics() -taskMetrics() diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index fda1709..cef8b5e 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,7 +1,9 @@ -idf_component_register(SRCS "main.c" +idf_component_register(SRCS "sntp.c" "wifi.c" "main.c" "metrics.c" "inputs.c" "outputs.c" "control.c" "safety.c" + "wifi.c" + "sntp.c" INCLUDE_DIRS ".") diff --git a/main/main.c b/main/main.c index 8751ec7..a34a9bc 100644 --- a/main/main.c +++ b/main/main.c @@ -20,6 +20,7 @@ #include "outputs.h" #include "inputs.h" #include "control.h" +#include "wifi.h" #define I2C_MASTER_SCL 19 #define I2C_MASTER_SDA 18 @@ -65,21 +66,22 @@ void app_main(void) // initOutputs(); // initInputs(); // initSafety(); + initWifi(); // initControl(); - initMetrics(); + // initMetrics(); - esp_sntp_setoperatingmode(SNTP_OPMODE_POLL); - esp_sntp_setservername(0, "10.1.0.1"); // Set first NTP server local router + // esp_sntp_setoperatingmode(SNTP_OPMODE_POLL); + // esp_sntp_setservername(0, "10.1.0.1"); // Set first NTP server local router - sntp_set_time_sync_notification_cb(time_sync_notification_cb); // Register the SNTP time sync callback - esp_sntp_init(); + // sntp_set_time_sync_notification_cb(time_sync_notification_cb); // Register the SNTP time sync callback + // esp_sntp_init(); while (1) { vTaskDelay(pdMS_TO_TICKS(1000)); // Print the current time - print_current_time(); + // print_current_time(); - ESP_LOGI(TAG, "SNTP Server 0 reachability: %i", esp_sntp_getreachability(0)); + // ESP_LOGI(TAG, "SNTP Server 0 reachability: %i", esp_sntp_getreachability(0)); } } \ No newline at end of file diff --git a/main/metrics.c b/main/metrics.c index 2823dbb..1a3886d 100644 --- a/main/metrics.c +++ b/main/metrics.c @@ -1,28 +1,15 @@ -#include -#include #include #include "esp_timer.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "esp_system.h" -#include "spi_flash_mmap.h" #include "esp_wifi.h" -#include "esp_event.h" -#include "freertos/event_groups.h" #include "esp_log.h" -#include "esp_netif.h" -#include -#include -#include -#include #include "metrics.h" #include "outputs.h" #include "inputs.h" #include "safety.h" -static EventGroupHandle_t s_wifi_event_group; - static const char *TAG = "smart-oil-heater-control-system-metrics"; char caHtmlResponse[HTML_RESPONSE_SIZE]; @@ -31,15 +18,11 @@ static sMetric aMetrics[METRIC_MAX_COUNT]; static uint16_t u16MetricCounter = 0U; void taskMetrics(void *pvParameters); -void connect_wifi(void); httpd_handle_t setup_server(void); esp_err_t get_metrics_handler(httpd_req_t *req); void initMetrics(void) { - connect_wifi(); - return; - setup_server(); BaseType_t taskCreated = xTaskCreate( @@ -227,93 +210,6 @@ void vSetMetrics(sMetric *paMetrics, uint16_t u16Size) } } -static void event_handler(void *arg, esp_event_base_t event_base, - int32_t event_id, void *event_data) -{ - if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) - { - esp_wifi_connect(); - } - else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) - { - esp_wifi_connect(); - ESP_LOGI(TAG, "Retry to connect to the AP"); - } - else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) - { - ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; - ESP_LOGI(TAG, "Got ip:" IPSTR, IP2STR(&event->ip_info.ip)); - xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); - } -} - -void connect_wifi(void) -{ - s_wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_netif_init()); - ESP_ERROR_CHECK(esp_event_loop_create_default()); - - esp_netif_t *my_sta = esp_netif_create_default_wifi_sta(); - esp_netif_dhcpc_stop(my_sta); - esp_netif_ip_info_t ip_info; - ip_info.ip.addr = ipaddr_addr(CONFIG_STATIC_IP_ADDR); - ip_info.gw.addr = ipaddr_addr(CONFIG_STATIC_GATEWAY_IP_ADDR); - ip_info.netmask.addr = ipaddr_addr(CONFIG_STATIC_IP_NETMASK); - esp_netif_set_ip_info(my_sta, &ip_info); - - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - esp_event_handler_instance_t instance_any_id; - esp_event_handler_instance_t instance_got_ip; - ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, - ESP_EVENT_ANY_ID, - &event_handler, - NULL, - &instance_any_id)); - ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, - IP_EVENT_STA_GOT_IP, - &event_handler, - NULL, - &instance_got_ip)); - - wifi_config_t wifi_config = { - .sta = { - .ssid = CONFIG_SSID, - .password = CONFIG_WIFI_PASSWORD, - .threshold.authmode = WIFI_AUTH_WPA2_PSK, - }, - }; - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); - - ESP_ERROR_CHECK(esp_wifi_start()); - - ESP_ERROR_CHECK(esp_wifi_set_max_tx_power(78)); // Set max power to 19.5 dBm (78 in units of 0.25 dBm) - ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_MIN_MODEM)); // Use power-saving mode - - ESP_LOGI(TAG, "wifi_init_sta finished."); - - EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, - WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, - pdFALSE, - pdFALSE, - portMAX_DELAY); - - if (bits & WIFI_CONNECTED_BIT) - { - ESP_LOGI(TAG, "Connected to ap SSID:%s", CONFIG_SSID); - } - else if (bits & WIFI_FAIL_BIT) - { - ESP_LOGI(TAG, "Failed to connect to SSID:%s", CONFIG_SSID); - } - else - { - ESP_LOGE(TAG, "Unexpected event"); - } - vEventGroupDelete(s_wifi_event_group); -} - esp_err_t get_metrics_handler(httpd_req_t *req) { if (xSemaphoreTakeRecursive(xMutexAccessMetricResponse, pdMS_TO_TICKS(5000)) == pdTRUE) diff --git a/main/metrics.h b/main/metrics.h index 7e8a161..ad7dd23 100644 --- a/main/metrics.h +++ b/main/metrics.h @@ -2,8 +2,6 @@ #include -#define WIFI_CONNECTED_BIT BIT0 -#define WIFI_FAIL_BIT BIT1 #define HTML_RESPONSE_SIZE 1024U #define METRIC_NAME_MAX_SIZE 256U #define METRIC_MAX_COUNT 64U diff --git a/main/sntp.c b/main/sntp.c new file mode 100644 index 0000000..473a0f4 diff --git a/main/sntp.h b/main/sntp.h new file mode 100644 index 0000000..473a0f4 diff --git a/main/wifi.c b/main/wifi.c new file mode 100644 index 0000000..d1fd0c1 --- /dev/null +++ b/main/wifi.c @@ -0,0 +1,108 @@ +#include +#include "esp_timer.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_wifi.h" +#include "esp_event.h" +#include "freertos/event_groups.h" +#include "esp_log.h" +#include "esp_netif.h" +#include + +#include "wifi.h" + +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +static const char *TAG = "smart-oil-heater-control-system-wifi"; + +static EventGroupHandle_t s_wifi_event_group; +static void event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data); + +void initWifi(void) +{ + s_wifi_event_group = xEventGroupCreate(); + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + esp_netif_t *my_sta = esp_netif_create_default_wifi_sta(); + esp_netif_dhcpc_stop(my_sta); + esp_netif_ip_info_t ip_info; + ip_info.ip.addr = ipaddr_addr(CONFIG_STATIC_IP_ADDR); + ip_info.gw.addr = ipaddr_addr(CONFIG_STATIC_GATEWAY_IP_ADDR); + ip_info.netmask.addr = ipaddr_addr(CONFIG_STATIC_IP_NETMASK); + esp_netif_set_ip_info(my_sta, &ip_info); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + esp_event_handler_instance_t instance_any_id; + esp_event_handler_instance_t instance_got_ip; + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &event_handler, + NULL, + &instance_any_id)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &event_handler, + NULL, + &instance_got_ip)); + + wifi_config_t wifi_config = { + .sta = { + .ssid = CONFIG_SSID, + .password = CONFIG_WIFI_PASSWORD, + .threshold.authmode = WIFI_AUTH_WPA2_PSK, + }, + }; + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + + ESP_ERROR_CHECK(esp_wifi_start()); + + ESP_ERROR_CHECK(esp_wifi_set_max_tx_power(78)); // Set max power to 19.5 dBm (78 in units of 0.25 dBm) + ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_MIN_MODEM)); // Use power-saving mode + + ESP_LOGI(TAG, "wifi_init_sta finished."); + + EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, + WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, + pdFALSE, + pdFALSE, + portMAX_DELAY); + + if (bits & WIFI_CONNECTED_BIT) + { + ESP_LOGI(TAG, "Connected to ap SSID:%s", CONFIG_SSID); + } + else if (bits & WIFI_FAIL_BIT) + { + ESP_LOGI(TAG, "Failed to connect to SSID:%s", CONFIG_SSID); + } + else + { + ESP_LOGE(TAG, "Unexpected event"); + } + vEventGroupDelete(s_wifi_event_group); +} + +static void event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) + { + esp_wifi_connect(); + } + else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) + { + esp_wifi_connect(); + ESP_LOGI(TAG, "Retry to connect to the AP"); + } + else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) + { + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + ESP_LOGI(TAG, "Got ip:" IPSTR, IP2STR(&event->ip_info.ip)); + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } +} \ No newline at end of file diff --git a/main/wifi.h b/main/wifi.h new file mode 100644 index 0000000..380c625 --- /dev/null +++ b/main/wifi.h @@ -0,0 +1,3 @@ +#pragma once + +void initWifi(void); \ No newline at end of file -- 2.47.1 From e5bb620a37860eb37a96eafe35154eb2a629c44b363bba41859bd2030981c1be Mon Sep 17 00:00:00 2001 From: localhorst Date: Thu, 19 Dec 2024 20:33:51 +0100 Subject: [PATCH 4/5] sntp module --- .vscode/settings.json | 5 +++- README.md | 12 +++++---- main/Kconfig.projbuild | 3 +++ main/control.c | 21 +++++++++------ main/main.c | 61 ++++++------------------------------------ main/metrics.c | 18 +++++++++++++ main/sntp.c | 30 +++++++++++++++++++++ main/sntp.h | 11 ++++++++ 8 files changed, 94 insertions(+), 67 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 34ff52a..b007ac5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,7 +20,10 @@ "*.inc": "c", "safety.h": "c", "event_groups.h": "c", - "string.h": "c" + "string.h": "c", + "time.h": "c", + "timers.h": "c", + "nvs_flash.h": "c" }, "idf.openOcdConfigs": [ "board/esp32-wrover-kit-3.3v.cfg" diff --git a/README.md b/README.md index f0dbad7..bdafc6b 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,15 @@ classDiagram Inputs <|-- Control Outputs <|-- Control +Sntp <|-- Control Inputs <|-- Safety Outputs <|--|> Safety -Inputs <|-- HTTP_Metrics -Outputs <|-- HTTP_Metrics -Control <|-- HTTP_Metrics -Safety <|-- HTTP_Metrics +Inputs <|-- Metrics +Outputs <|-- Metrics +Control <|-- Metrics +Safety <|-- Metrics +Sntp <|-- Metrics class Inputs{ +initInputs() @@ -52,7 +54,7 @@ Safety <|-- HTTP_Metrics +initWifi() } - class SNTP{ + class Sntp{ +initSntp() +getSntpState() } diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 990fa8e..c855f47 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -15,5 +15,8 @@ menu "Smart Oil Heating Control System" config STATIC_GATEWAY_IP_ADDR string "Static IPv4 gateway address" default "192.168.0.1" + config SNTP_SERVER_IP_ADDR + string "SNTP IPv4 server address" + default "192.168.0.1" endmenu diff --git a/main/control.c b/main/control.c index 0b64e78..42f89f8 100644 --- a/main/control.c +++ b/main/control.c @@ -5,6 +5,7 @@ #include "outputs.h" #include "inputs.h" #include "safety.h" +#include "sntp.h" #define PERIODIC_INTERVAL 1U // run safety checks every 1sec @@ -40,16 +41,20 @@ void taskControl(void *pvParameters) { vTaskDelay(PERIODIC_INTERVAL * 1000U / portTICK_PERIOD_MS); - if (getSafetyState() == SAFETY_NO_ERROR) - { - // TODO: control the burner based on timetable - - setCirculationPumpState(DISABLED); - setBurnerState(ENABLED); - } - else + if (getSafetyState() != SAFETY_NO_ERROR) { ESP_LOGW(TAG, "Control not possible due to safety fault!"); + continue; } + + if (getSntpState() != SYNC_SUCCESSFUL) + { + ESP_LOGW(TAG, "Control not possible due to sntp fault!"); + continue; + } + + // TODO: control the burner based on timetable + setCirculationPumpState(DISABLED); + setBurnerState(ENABLED); } } \ No newline at end of file diff --git a/main/main.c b/main/main.c index a34a9bc..82c2d63 100644 --- a/main/main.c +++ b/main/main.c @@ -1,19 +1,6 @@ -#include #include "esp_log.h" -#include "driver/i2c.h" #include -#include -#include -#include -#include -#include -#include -#include -#include "freertos/timers.h" #include "nvs_flash.h" -#include -#include -#include #include "safety.h" #include "metrics.h" @@ -21,34 +8,10 @@ #include "inputs.h" #include "control.h" #include "wifi.h" - -#define I2C_MASTER_SCL 19 -#define I2C_MASTER_SDA 18 +#include "sntp.h" static const char *TAG = "smart-oil-heater-control-system"; -// Function to print the current time -void print_current_time() -{ - time_t now; - struct tm timeinfo; - - time(&now); - localtime_r(&now, &timeinfo); - - char strftime_buf[64]; - strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo); - - ESP_LOGI(TAG, "Current time: %s", strftime_buf); -} - -// SNTP Callback function -void time_sync_notification_cb(struct timeval *tv) -{ - ESP_LOGI(TAG, "SNTP synchronization completed! Unix Time: %lld", tv->tv_sec); - ESP_LOGI(TAG, "Time synchronization callback called."); -} - void app_main(void) { ESP_LOGI(TAG, "starting ..."); @@ -63,25 +26,17 @@ void app_main(void) ESP_ERROR_CHECK(ret); // TODO: Error handling! - // initOutputs(); - // initInputs(); - // initSafety(); + initOutputs(); + initInputs(); + initSafety(); initWifi(); - // initControl(); - // initMetrics(); - - // esp_sntp_setoperatingmode(SNTP_OPMODE_POLL); - // esp_sntp_setservername(0, "10.1.0.1"); // Set first NTP server local router - - // sntp_set_time_sync_notification_cb(time_sync_notification_cb); // Register the SNTP time sync callback - // esp_sntp_init(); + initSntp(); + initControl(); + initMetrics(); while (1) { vTaskDelay(pdMS_TO_TICKS(1000)); - // Print the current time - // print_current_time(); - - // ESP_LOGI(TAG, "SNTP Server 0 reachability: %i", esp_sntp_getreachability(0)); + // Do nothing ;-) } } \ No newline at end of file diff --git a/main/metrics.c b/main/metrics.c index 1a3886d..dcb90cf 100644 --- a/main/metrics.c +++ b/main/metrics.c @@ -4,11 +4,14 @@ #include "freertos/task.h" #include "esp_wifi.h" #include "esp_log.h" +#include +#include #include "metrics.h" #include "outputs.h" #include "inputs.h" #include "safety.h" +#include "sntp.h" static const char *TAG = "smart-oil-heater-control-system-metrics"; @@ -57,6 +60,21 @@ void taskMetrics(void *pvParameters) aMetrics[u16MetricCounter].fMetricValue = (esp_timer_get_time() / 1000000U); u16MetricCounter++; + /*SNTP Status*/ + strcpy(aMetrics[u16MetricCounter].caMetricName, "sntp_status"); + aMetrics[u16MetricCounter].fMetricValue = getSntpState(); + u16MetricCounter++; + + /*System time + time_t now; + struct tm timeinfo; + time(&now); + localtime_r(&now, &timeinfo); + strcpy(aMetrics[u16MetricCounter].caMetricName, "system_unixtime"); + aMetrics[u16MetricCounter].fMetricValue = (float) now; + u16MetricCounter++; + */ + /*Wifi RSSI*/ wifi_ap_record_t ap; esp_wifi_sta_get_ap_info(&ap); diff --git a/main/sntp.c b/main/sntp.c index 473a0f4..638bfa4 100644 --- a/main/sntp.c +++ b/main/sntp.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include "esp_log.h" + +#include "sntp.h" + +static const char *TAG = "smart-oil-heater-control-system-sntp"; +static eSntpState sntpState = SYNC_NOT_STARTED; +void time_sync_notification_cb(struct timeval *tv); + +void initSntp(void) +{ + esp_sntp_setoperatingmode(SNTP_OPMODE_POLL); + esp_sntp_setservername(0, CONFIG_SNTP_SERVER_IP_ADDR); + + sntp_set_time_sync_notification_cb(time_sync_notification_cb); + esp_sntp_init(); +} + +eSntpState getSntpState(void) +{ + return sntpState; +} + +void time_sync_notification_cb(struct timeval *tv) +{ + ESP_LOGI(TAG, "SNTP synchronization! Unix Time: %lld", tv->tv_sec); + sntpState = SYNC_SUCCESSFUL; +} diff --git a/main/sntp.h b/main/sntp.h index 473a0f4..4feb88b 100644 --- a/main/sntp.h +++ b/main/sntp.h @@ -0,0 +1,11 @@ +#pragma once + +typedef enum _SntpState +{ + SYNC_SUCCESSFUL, + SYNC_NOT_STARTED, + SYNC_FAILED, +} eSntpState; + +void initSntp(void); +eSntpState getSntpState(void); \ No newline at end of file -- 2.47.1 From bf8038d9e291166e5343b8b841a8356c500f076fb5fa514d5455eee4cb4a9dc8 Mon Sep 17 00:00:00 2001 From: localhorst Date: Thu, 19 Dec 2024 21:15:09 +0100 Subject: [PATCH 5/5] cleanup and sort metrics --- main/metrics.c | 211 +++++++++++++++++++++++++++---------------------- main/metrics.h | 10 +++ 2 files changed, 128 insertions(+), 93 deletions(-) diff --git a/main/metrics.c b/main/metrics.c index dcb90cf..e0c8719 100644 --- a/main/metrics.c +++ b/main/metrics.c @@ -55,133 +55,113 @@ void taskMetrics(void *pvParameters) u16MetricCounter = 0U; - /*Uptime*/ - strcpy(aMetrics[u16MetricCounter].caMetricName, "uptime_seconds"); - aMetrics[u16MetricCounter].fMetricValue = (esp_timer_get_time() / 1000000U); - u16MetricCounter++; + /*Circulation Pump State*/ + if (getCirculationPumpState() == ENABLED) + { + strcpy(aMetrics[u16MetricCounter].caMetricName, "circulation_pump_enabled"); + aMetrics[u16MetricCounter].type = INTEGER_U8; + aMetrics[u16MetricCounter].u8MetricValue = 1U; + u16MetricCounter++; + } + else + { + strcpy(aMetrics[u16MetricCounter].caMetricName, "circulation_pump_enabled"); + aMetrics[u16MetricCounter].type = INTEGER_U8; + aMetrics[u16MetricCounter].u8MetricValue = 0U; + u16MetricCounter++; + } - /*SNTP Status*/ - strcpy(aMetrics[u16MetricCounter].caMetricName, "sntp_status"); - aMetrics[u16MetricCounter].fMetricValue = getSntpState(); - u16MetricCounter++; - - /*System time - time_t now; - struct tm timeinfo; - time(&now); - localtime_r(&now, &timeinfo); - strcpy(aMetrics[u16MetricCounter].caMetricName, "system_unixtime"); - aMetrics[u16MetricCounter].fMetricValue = (float) now; - u16MetricCounter++; - */ - - /*Wifi RSSI*/ - wifi_ap_record_t ap; - esp_wifi_sta_get_ap_info(&ap); - // printf("WiFi RSSI: %d\n", ap.rssi); - strcpy(aMetrics[u16MetricCounter].caMetricName, "wifi_rssi"); - aMetrics[u16MetricCounter].fMetricValue = ap.rssi; + /*Burner Error State*/ + strcpy(aMetrics[u16MetricCounter].caMetricName, "burner_fault_pending"); + aMetrics[u16MetricCounter].type = INTEGER_U8; + aMetrics[u16MetricCounter].u8MetricValue = getBurnerError(); u16MetricCounter++; /*Burner State*/ if (getBurnerState() == ENABLED) { strcpy(aMetrics[u16MetricCounter].caMetricName, "burner_enabled"); - aMetrics[u16MetricCounter].fMetricValue = 1.0f; + aMetrics[u16MetricCounter].type = INTEGER_U8; + aMetrics[u16MetricCounter].u8MetricValue = 1U; u16MetricCounter++; } else { strcpy(aMetrics[u16MetricCounter].caMetricName, "burner_enabled"); - aMetrics[u16MetricCounter].fMetricValue = 0.0f; - u16MetricCounter++; - } - - /*Circulation Pump State*/ - if (getCirculationPumpState() == ENABLED) - { - strcpy(aMetrics[u16MetricCounter].caMetricName, "circulation_pump_enabled"); - aMetrics[u16MetricCounter].fMetricValue = 1.0f; - u16MetricCounter++; - } - else - { - strcpy(aMetrics[u16MetricCounter].caMetricName, "circulation_pump_enabled"); - aMetrics[u16MetricCounter].fMetricValue = 0.0f; - u16MetricCounter++; - } - - /*Burner Error State*/ - if (getBurnerError() == FAULT) - { - strcpy(aMetrics[u16MetricCounter].caMetricName, "burner_fault_pending"); - aMetrics[u16MetricCounter].fMetricValue = 1.0f; - u16MetricCounter++; - } - else - { - strcpy(aMetrics[u16MetricCounter].caMetricName, "burner_fault_pending"); - aMetrics[u16MetricCounter].fMetricValue = 0.0f; + aMetrics[u16MetricCounter].type = INTEGER_U8; + aMetrics[u16MetricCounter].u8MetricValue = 0U; u16MetricCounter++; } /*Chamber Temperature*/ strcpy(aMetrics[u16MetricCounter].caMetricName, "chamber_temperature"); + aMetrics[u16MetricCounter].type = FLOAT; aMetrics[u16MetricCounter].fMetricValue = getChamberTemperature().fCurrentValue; u16MetricCounter++; - /*Outdoor Temperature*/ - strcpy(aMetrics[u16MetricCounter].caMetricName, "outdoor_temperature"); - aMetrics[u16MetricCounter].fMetricValue = getOutdoorTemperature().fCurrentValue; - u16MetricCounter++; - - /*Chamber Temperature*/ - strcpy(aMetrics[u16MetricCounter].caMetricName, "inlet_flow_temperature"); - aMetrics[u16MetricCounter].fMetricValue = getInletFlowTemperature().fCurrentValue; - u16MetricCounter++; - - /*Chamber Temperature*/ - strcpy(aMetrics[u16MetricCounter].caMetricName, "return_flow_temperature"); - aMetrics[u16MetricCounter].fMetricValue = getReturnFlowTemperature().fCurrentValue; - u16MetricCounter++; - /*Chamber Temperature Average 10s*/ strcpy(aMetrics[u16MetricCounter].caMetricName, "chamber_temperature_avg10"); + aMetrics[u16MetricCounter].type = FLOAT; aMetrics[u16MetricCounter].fMetricValue = getChamberTemperature().average10s.fValue; u16MetricCounter++; - /*Outdoor Temperature Average 10s*/ - strcpy(aMetrics[u16MetricCounter].caMetricName, "outdoor_temperature_avg10"); - aMetrics[u16MetricCounter].fMetricValue = getOutdoorTemperature().average10s.fValue; - u16MetricCounter++; - - /*Chamber Temperature Average 10s*/ - strcpy(aMetrics[u16MetricCounter].caMetricName, "inlet_flow_temperature_avg10"); - aMetrics[u16MetricCounter].fMetricValue = getInletFlowTemperature().average10s.fValue; - u16MetricCounter++; - - /*Chamber Temperature Average 10s*/ - strcpy(aMetrics[u16MetricCounter].caMetricName, "return_flow_temperature_avg10"); - aMetrics[u16MetricCounter].fMetricValue = getReturnFlowTemperature().average10s.fValue; - u16MetricCounter++; - /*Chamber Temperature Average 60s*/ strcpy(aMetrics[u16MetricCounter].caMetricName, "chamber_temperature_avg60"); + aMetrics[u16MetricCounter].type = FLOAT; aMetrics[u16MetricCounter].fMetricValue = getChamberTemperature().average60s.fValue; u16MetricCounter++; + /*Inlet Flow Temperature*/ + strcpy(aMetrics[u16MetricCounter].caMetricName, "inlet_flow_temperature"); + aMetrics[u16MetricCounter].type = FLOAT; + aMetrics[u16MetricCounter].fMetricValue = getInletFlowTemperature().fCurrentValue; + u16MetricCounter++; + + /*Inlet Flow Temperature Average 10s*/ + strcpy(aMetrics[u16MetricCounter].caMetricName, "inlet_flow_temperature_avg10"); + aMetrics[u16MetricCounter].type = FLOAT; + aMetrics[u16MetricCounter].fMetricValue = getInletFlowTemperature().average10s.fValue; + u16MetricCounter++; + + /*Inlet Flow Temperature Average 60s*/ + strcpy(aMetrics[u16MetricCounter].caMetricName, "inlet_flow_temperature_avg60"); + aMetrics[u16MetricCounter].type = FLOAT; + aMetrics[u16MetricCounter].fMetricValue = getInletFlowTemperature().average60s.fValue; + u16MetricCounter++; + + /*Outdoor Temperature*/ + strcpy(aMetrics[u16MetricCounter].caMetricName, "outdoor_temperature"); + aMetrics[u16MetricCounter].type = FLOAT; + aMetrics[u16MetricCounter].fMetricValue = getOutdoorTemperature().fCurrentValue; + u16MetricCounter++; + + /*Outdoor Temperature Average 10s*/ + strcpy(aMetrics[u16MetricCounter].caMetricName, "outdoor_temperature_avg10"); + aMetrics[u16MetricCounter].type = FLOAT; + aMetrics[u16MetricCounter].fMetricValue = getOutdoorTemperature().average10s.fValue; + u16MetricCounter++; + /*Outdoor Temperature Average 60s*/ strcpy(aMetrics[u16MetricCounter].caMetricName, "outdoor_temperature_avg60"); + aMetrics[u16MetricCounter].type = FLOAT; aMetrics[u16MetricCounter].fMetricValue = getOutdoorTemperature().average60s.fValue; u16MetricCounter++; - /*Chamber Temperature Average 60s*/ - strcpy(aMetrics[u16MetricCounter].caMetricName, "inlet_flow_temperature_avg60"); - aMetrics[u16MetricCounter].fMetricValue = getInletFlowTemperature().average60s.fValue; + /*Return Flow Temperature*/ + strcpy(aMetrics[u16MetricCounter].caMetricName, "return_flow_temperature"); + aMetrics[u16MetricCounter].type = FLOAT; + aMetrics[u16MetricCounter].fMetricValue = getReturnFlowTemperature().fCurrentValue; u16MetricCounter++; - /*Chamber Temperature Average 60s*/ + /*Return Flow Temperature Average 10s*/ + strcpy(aMetrics[u16MetricCounter].caMetricName, "return_flow_temperature_avg10"); + aMetrics[u16MetricCounter].type = FLOAT; + aMetrics[u16MetricCounter].fMetricValue = getReturnFlowTemperature().average10s.fValue; + u16MetricCounter++; + + /*Return Flow Temperature Average 60s*/ strcpy(aMetrics[u16MetricCounter].caMetricName, "return_flow_temperature_avg60"); + aMetrics[u16MetricCounter].type = FLOAT; aMetrics[u16MetricCounter].fMetricValue = getReturnFlowTemperature().average60s.fValue; u16MetricCounter++; @@ -192,13 +172,43 @@ void taskMetrics(void *pvParameters) { strcpy(aMetrics[u16MetricCounter].caMetricName, aChecks[i].name); strcat(aMetrics[u16MetricCounter].caMetricName, "_status"); - aMetrics[u16MetricCounter].fMetricValue = aChecks[i].status; + aMetrics[u16MetricCounter].type = INTEGER_U8; + aMetrics[u16MetricCounter].u8MetricValue = aChecks[i].status; u16MetricCounter++; } - /*Safety state*/ + /*Safety State*/ strcpy(aMetrics[u16MetricCounter].caMetricName, "safety_state"); - aMetrics[u16MetricCounter].fMetricValue = getSafetyState(); + aMetrics[u16MetricCounter].type = INTEGER_U8; + aMetrics[u16MetricCounter].u8MetricValue = getSafetyState(); + u16MetricCounter++; + + /*SNTP Status*/ + strcpy(aMetrics[u16MetricCounter].caMetricName, "sntp_status"); + aMetrics[u16MetricCounter].type = INTEGER_U8; + aMetrics[u16MetricCounter].u8MetricValue = getSntpState(); + u16MetricCounter++; + + /*System Time*/ + time_t now; + time(&now); + strcpy(aMetrics[u16MetricCounter].caMetricName, "system_unixtime"); + aMetrics[u16MetricCounter].type = INTEGER_64; + aMetrics[u16MetricCounter].i64MetricValue = now; + u16MetricCounter++; + + /*Uptime*/ + strcpy(aMetrics[u16MetricCounter].caMetricName, "uptime_seconds"); + aMetrics[u16MetricCounter].type = INTEGER_64; + aMetrics[u16MetricCounter].i64MetricValue = (esp_timer_get_time() / 1000000U); + u16MetricCounter++; + + /*Wifi RSSI*/ + wifi_ap_record_t ap; + esp_wifi_sta_get_ap_info(&ap); + strcpy(aMetrics[u16MetricCounter].caMetricName, "wifi_rssi"); + aMetrics[u16MetricCounter].type = INTEGER_64; + aMetrics[u16MetricCounter].i64MetricValue = ap.rssi; u16MetricCounter++; vSetMetrics(aMetrics, u16MetricCounter); @@ -214,7 +224,22 @@ void vSetMetrics(sMetric *paMetrics, uint16_t u16Size) for (uint16_t u16Index = 0U; u16Index < u16Size; u16Index++) { char caValueBuffer[64]; - sprintf(caValueBuffer, " %f", paMetrics[u16Index].fMetricValue); + + switch (paMetrics[u16Index].type) + { + case FLOAT: + sprintf(caValueBuffer, " %f", paMetrics[u16Index].fMetricValue); + break; + case INTEGER_64: + sprintf(caValueBuffer, " %lli", paMetrics[u16Index].i64MetricValue); + break; + case INTEGER_U8: + sprintf(caValueBuffer, " %u", paMetrics[u16Index].u8MetricValue); + break; + default: + break; + } + // printf("%s\n", caValueBuffer); strcat(caHtmlResponse, paMetrics[u16Index].caMetricName); strcat(caHtmlResponse, caValueBuffer); diff --git a/main/metrics.h b/main/metrics.h index ad7dd23..b02342a 100644 --- a/main/metrics.h +++ b/main/metrics.h @@ -6,10 +6,20 @@ #define METRIC_NAME_MAX_SIZE 256U #define METRIC_MAX_COUNT 64U +typedef enum _MetricValueType +{ + FLOAT, + INTEGER_U8, + INTEGER_64, +} eMetricValueType; + typedef struct _metric { char caMetricName[METRIC_NAME_MAX_SIZE]; + eMetricValueType type; float fMetricValue; + uint8_t u8MetricValue; + int64_t i64MetricValue; } sMetric; void initMetrics(void); -- 2.47.1