Merge pull request 'Add SNTP support' (#4) from feature/ntp-client into main
Reviewed-on: #4
This commit is contained in:
		
							
								
								
									
										27
									
								
								.vscode/c_cpp_properties.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								.vscode/c_cpp_properties.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
|   } | ||||
							
								
								
									
										8
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @ -17,7 +17,13 @@ | ||||
|         "type_traits": "c", | ||||
|         "cmath": "c", | ||||
|         "*.tcc": "c", | ||||
|         "*.inc": "c" | ||||
|         "*.inc": "c", | ||||
|         "safety.h": "c", | ||||
|         "event_groups.h": "c", | ||||
|         "string.h": "c", | ||||
|         "time.h": "c", | ||||
|         "timers.h": "c", | ||||
|         "nvs_flash.h": "c" | ||||
|     }, | ||||
|     "idf.openOcdConfigs": [ | ||||
|         "board/esp32-wrover-kit-3.3v.cfg" | ||||
|  | ||||
							
								
								
									
										20
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								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() | ||||
| @ -47,6 +49,16 @@ Safety <|-- HTTP_Metrics | ||||
|         +getSafetyState() | ||||
|     } | ||||
|  | ||||
|  | ||||
|     class Wifi{ | ||||
|         +initWifi() | ||||
|     } | ||||
|  | ||||
|     class Sntp{ | ||||
|         +initSntp() | ||||
|         +getSntpState() | ||||
|     } | ||||
|  | ||||
|     class Metrics{ | ||||
|         +initMetrics() | ||||
|         -taskMetrics() | ||||
|  | ||||
| @ -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 ".") | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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) | ||||
|         if (getSafetyState() != SAFETY_NO_ERROR) | ||||
|         { | ||||
|             // TODO: control the burner based on timetable | ||||
|             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); | ||||
|     } | ||||
|         else | ||||
|         { | ||||
|             ESP_LOGW(TAG, "Control not possible due to safety fault!"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										20
									
								
								main/main.c
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								main/main.c
									
									
									
									
									
								
							| @ -1,15 +1,5 @@ | ||||
| #include <stdio.h> | ||||
| #include "esp_log.h" | ||||
| #include "driver/i2c.h" | ||||
| #include <esp_system.h> | ||||
| #include <bmp280.h> | ||||
| #include <dht.h> | ||||
| #include <aht.h> | ||||
| #include <veml7700.h> | ||||
| #include <string.h> | ||||
| #include <freertos/FreeRTOS.h> | ||||
| #include <freertos/task.h> | ||||
| #include "freertos/timers.h" | ||||
| #include "nvs_flash.h" | ||||
|  | ||||
| #include "safety.h" | ||||
| @ -17,9 +7,8 @@ | ||||
| #include "outputs.h" | ||||
| #include "inputs.h" | ||||
| #include "control.h" | ||||
|  | ||||
| #define I2C_MASTER_SCL 19 | ||||
| #define I2C_MASTER_SDA 18 | ||||
| #include "wifi.h" | ||||
| #include "sntp.h" | ||||
|  | ||||
| static const char *TAG = "smart-oil-heater-control-system"; | ||||
|  | ||||
| @ -40,11 +29,14 @@ void app_main(void) | ||||
|     initOutputs(); | ||||
|     initInputs(); | ||||
|     initSafety(); | ||||
|     initWifi(); | ||||
|     initSntp(); | ||||
|     initControl(); | ||||
|     initMetrics(); | ||||
|  | ||||
|     while (1) | ||||
|     { | ||||
|         vTaskDelay(pdMS_TO_TICKS(2048)); | ||||
|         vTaskDelay(pdMS_TO_TICKS(1000)); | ||||
|         // Do nothing ;-) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										297
									
								
								main/metrics.c
									
									
									
									
									
								
							
							
						
						
									
										297
									
								
								main/metrics.c
									
									
									
									
									
								
							| @ -1,27 +1,17 @@ | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #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 <lwip/sockets.h> | ||||
| #include <lwip/sys.h> | ||||
| #include <lwip/api.h> | ||||
| #include <lwip/netdb.h> | ||||
| #include <time.h> | ||||
| #include <sys/time.h> | ||||
|  | ||||
| #include "metrics.h" | ||||
| #include "outputs.h" | ||||
| #include "inputs.h" | ||||
| #include "safety.h" | ||||
|  | ||||
| static EventGroupHandle_t s_wifi_event_group; | ||||
| #include "sntp.h" | ||||
|  | ||||
| static const char *TAG = "smart-oil-heater-control-system-metrics"; | ||||
|  | ||||
| @ -31,13 +21,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(); | ||||
|     setup_server(); | ||||
|  | ||||
|     BaseType_t taskCreated = xTaskCreate( | ||||
| @ -67,118 +55,113 @@ void taskMetrics(void *pvParameters) | ||||
|  | ||||
|         u16MetricCounter = 0U; | ||||
|  | ||||
|         /*Uptime*/ | ||||
|         strcpy(aMetrics[u16MetricCounter].caMetricName, "uptime_seconds"); | ||||
|         aMetrics[u16MetricCounter].fMetricValue = (esp_timer_get_time() / 1000000U); | ||||
|         /*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++; | ||||
|         } | ||||
|  | ||||
|         /*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++; | ||||
|  | ||||
| @ -189,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); | ||||
| @ -211,7 +224,22 @@ void vSetMetrics(sMetric *paMetrics, uint16_t u16Size) | ||||
|         for (uint16_t u16Index = 0U; u16Index < u16Size; u16Index++) | ||||
|         { | ||||
|             char caValueBuffer[64]; | ||||
|  | ||||
|             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); | ||||
| @ -225,93 +253,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) | ||||
|  | ||||
| @ -2,16 +2,24 @@ | ||||
|  | ||||
| #include <esp_http_server.h> | ||||
|  | ||||
| #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 | ||||
|  | ||||
| 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); | ||||
|  | ||||
							
								
								
									
										30
									
								
								main/sntp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								main/sntp.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| #include <time.h> | ||||
| #include <sys/time.h> | ||||
| #include <esp_sntp.h> | ||||
| #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; | ||||
| } | ||||
							
								
								
									
										11
									
								
								main/sntp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								main/sntp.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| #pragma once | ||||
|  | ||||
| typedef enum _SntpState | ||||
| { | ||||
|     SYNC_SUCCESSFUL, | ||||
|     SYNC_NOT_STARTED, | ||||
|     SYNC_FAILED, | ||||
| } eSntpState; | ||||
|  | ||||
| void initSntp(void); | ||||
| eSntpState getSntpState(void); | ||||
							
								
								
									
										108
									
								
								main/wifi.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								main/wifi.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,108 @@ | ||||
| #include <string.h> | ||||
| #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 <lwip/sockets.h> | ||||
|  | ||||
| #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); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										3
									
								
								main/wifi.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								main/wifi.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| #pragma once | ||||
|  | ||||
| void initWifi(void); | ||||
		Reference in New Issue
	
	Block a user