From 3d7de0561415a7477abc4cd2177b61f977c7ee28 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Sun, 18 Jan 2026 16:26:05 +0100 Subject: [PATCH] read schema files for website Signed-off-by: Peter Siegmund --- .../components/api-server/src/api_handlers.c | 39 ++++++-- .../components/simulator/include/storage.h | 2 + .../components/simulator/src/simulator.cpp | 2 +- firmware/components/simulator/src/storage.cpp | 99 ++++++++++++------- 4 files changed, 98 insertions(+), 44 deletions(-) diff --git a/firmware/components/api-server/src/api_handlers.c b/firmware/components/api-server/src/api_handlers.c index 2c9485d..9c613c1 100644 --- a/firmware/components/api-server/src/api_handlers.c +++ b/firmware/components/api-server/src/api_handlers.c @@ -430,14 +430,41 @@ esp_err_t api_schema_get_handler(httpd_req_t *req) ESP_LOGI(TAG, "Requested schema: %s", filename); - // TODO: Read actual schema file from storage - // For now, return sample CSV data + // Schema-Datei lesen + char path[128]; + snprintf(path, sizeof(path), "%s", filename); + + int line_count = 0; + extern char **read_lines_filtered(const char *filename, int *out_count); + extern void free_lines(char **lines, int count); + char **lines = read_lines_filtered(path, &line_count); + set_cors_headers(req); httpd_resp_set_type(req, "text/csv"); - const char *sample_csv = "255,240,220,0,100,250\n" - "255,230,200,0,120,250\n" - "255,220,180,0,140,250\n"; - return httpd_resp_sendstr(req, sample_csv); + + if (!lines || line_count == 0) + { + return httpd_resp_sendstr(req, ""); + } + + // Gesamtlänge berechnen + size_t total_len = 0; + for (int i = 0; i < line_count; ++i) + total_len += strlen(lines[i]) + 1; + char *csv = malloc(total_len + 1); + char *p = csv; + for (int i = 0; i < line_count; ++i) + { + size_t l = strlen(lines[i]); + memcpy(p, lines[i], l); + p += l; + *p++ = '\n'; + } + *p = '\0'; + free_lines(lines, line_count); + esp_err_t res = httpd_resp_sendstr(req, csv); + free(csv); + return res; } esp_err_t api_schema_post_handler(httpd_req_t *req) diff --git a/firmware/components/simulator/include/storage.h b/firmware/components/simulator/include/storage.h index 81dd8a6..eefed8a 100644 --- a/firmware/components/simulator/include/storage.h +++ b/firmware/components/simulator/include/storage.h @@ -6,6 +6,8 @@ extern "C" #endif void initialize_storage(); void load_file(const char *filename); + char **read_lines_filtered(const char *filename, int *out_count); + void free_lines(char **lines, int count); #ifdef __cplusplus } #endif diff --git a/firmware/components/simulator/src/simulator.cpp b/firmware/components/simulator/src/simulator.cpp index 705725f..81211fc 100644 --- a/firmware/components/simulator/src/simulator.cpp +++ b/firmware/components/simulator/src/simulator.cpp @@ -148,7 +148,7 @@ static void initialize_light_items(void) persistence_manager_t persistence; persistence_manager_init(&persistence, "config"); int variant = persistence_manager_get_int(&persistence, "light_variant", 1); - snprintf(filename, sizeof(filename), "/spiffs/schema_%02d.csv", variant); + snprintf(filename, sizeof(filename), "schema_%02d.csv", variant); load_file(filename); persistence_manager_deinit(&persistence); diff --git a/firmware/components/simulator/src/storage.cpp b/firmware/components/simulator/src/storage.cpp index e8accfd..bb799c9 100644 --- a/firmware/components/simulator/src/storage.cpp +++ b/firmware/components/simulator/src/storage.cpp @@ -5,6 +5,8 @@ #include "simulator.h" #include #include +#include +#include static const char *TAG = "storage"; @@ -49,59 +51,82 @@ void initialize_storage() void load_file(const char *filename) { ESP_LOGI(TAG, "Loading file: %s", filename); - FILE *f = fopen(filename, "r"); - if (f == NULL) - { - ESP_LOGE(TAG, "Failed to open file for reading"); - return; - } - - char line[128]; + int line_count = 0; + char **lines = read_lines_filtered(filename, &line_count); uint8_t line_number = 0; - while (fgets(line, sizeof(line), f)) + for (int i = 0; i < line_count; ++i) { - char *pos = strchr(line, '\n'); - if (pos) - { - *pos = '\0'; - } - - if (strlen(line) == 0) - { - continue; - } - - char *trimmed = line; - while (*trimmed == ' ' || *trimmed == '\t') - { - trimmed++; - } - if (*trimmed == '#' || *trimmed == '\0') - { - continue; - } - char time[10] = {0}; int red, green, blue, white, brightness, saturation; - - int items_scanned = sscanf(line, "%d,%d,%d,%d,%d,%d", &red, &green, &blue, &white, &brightness, &saturation); + int items_scanned = + sscanf(lines[i], "%d,%d,%d,%d,%d,%d", &red, &green, &blue, &white, &brightness, &saturation); if (items_scanned == 6) { int total_minutes = line_number * 30; int hours = total_minutes / 60; int minutes = total_minutes % 60; - snprintf(time, sizeof(time), "%02d%02d", hours, minutes); - add_light_item(time, red, green, blue, white, brightness, saturation); line_number++; } else { - ESP_LOGW(TAG, "Could not parse line: %s", line); + ESP_LOGW(TAG, "Could not parse line: %s", lines[i]); } } - - fclose(f); + free_lines(lines, line_count); ESP_LOGI(TAG, "Finished loading file. Loaded %d entries.", line_number); } + +char **read_lines_filtered(const char *filename, int *out_count) +{ + char fullpath[128]; + snprintf(fullpath, sizeof(fullpath), "/spiffs/%s", filename[0] == '/' ? filename + 1 : filename); + FILE *f = fopen(fullpath, "r"); + if (!f) + { + ESP_LOGE(TAG, "Failed to open file: %s", fullpath); + *out_count = 0; + return NULL; + } + + size_t capacity = 16; + size_t count = 0; + char **lines = (char **)malloc(capacity * sizeof(char *)); + char line[256]; + while (fgets(line, sizeof(line), f)) + { + // Zeilenumbruch entfernen + char *pos = strchr(line, '\n'); + if (pos) + *pos = '\0'; + // Trim vorne + char *trimmed = line; + while (*trimmed == ' ' || *trimmed == '\t') + trimmed++; + // Leere oder Kommentarzeile überspringen + if (*trimmed == '\0' || *trimmed == '#') + continue; + // Trim hinten + size_t len = strlen(trimmed); + while (len > 0 && (trimmed[len - 1] == ' ' || trimmed[len - 1] == '\t')) + trimmed[--len] = '\0'; + // Kopieren + if (count >= capacity) + { + capacity *= 2; + lines = (char **)realloc(lines, capacity * sizeof(char *)); + } + lines[count++] = strdup(trimmed); + } + fclose(f); + *out_count = (int)count; + return lines; +} + +void free_lines(char **lines, int count) +{ + for (int i = 0; i < count; ++i) + free(lines[i]); + free(lines); +}