Code robustness #2

Merged
mars3142 merged 3 commits from feature/code_robustness into main 2025-12-24 22:53:20 +00:00
2 changed files with 73 additions and 11 deletions
Showing only changes of commit fa05783fb9 - Show all commits

View File

@@ -11,12 +11,14 @@ namespace LightMenuItem
{
constexpr auto ACTIVATE = 0; ///< ID for the light activation toggle
constexpr auto MODE = 1; ///< ID for the light mode selection
constexpr auto VARIANT = 2; ///< ID for the light variant selection
} // namespace LightMenuItem
namespace LightMenuOptions
{
constexpr auto LIGHT_ACTIVE = "light_active";
constexpr auto LIGHT_MODE = "light_mode";
constexpr auto LIGHT_VARIANT = "light_variant";
} // namespace LightMenuOptions
LightMenu::LightMenu(menu_options_t *options) : Menu(options), m_options(options)
@@ -40,6 +42,17 @@ LightMenu::LightMenu(menu_options_t *options) : Menu(options), m_options(options
mode_value = m_options->persistenceManager->GetValue(LightMenuOptions::LIGHT_MODE, mode_value);
}
addSelection(LightMenuItem::MODE, "Modus", items, mode_value);
std::vector<std::string> variants;
variants.emplace_back("1");
variants.emplace_back("2");
variants.emplace_back("3");
int variant_value = 2;
if (m_options && m_options->persistenceManager)
{
variant_value = m_options->persistenceManager->GetValue(LightMenuOptions::LIGHT_VARIANT, variant_value);
}
addSelection(LightMenuItem::VARIANT, "Variante", variants, variant_value);
}
void LightMenu::onButtonPressed(const MenuItem &menuItem, const ButtonType button)
@@ -82,6 +95,23 @@ void LightMenu::onButtonPressed(const MenuItem &menuItem, const ButtonType butto
break;
}
case LightMenuItem::VARIANT: {
// Change light variant using left/right buttons
const auto item = switchValue(menuItem, button);
if (button == ButtonType::LEFT || button == ButtonType::RIGHT)
{
const auto value = getItem(item.getId()).getIndex() + 1;
if (m_options && m_options->persistenceManager)
{
m_options->persistenceManager->SetValue(LightMenuOptions::LIGHT_VARIANT, value);
m_options->persistenceManager->Save();
}
start_simulation();
}
break;
}
default:
// Handle unknown menu items (no action required)
break;

View File

@@ -7,6 +7,7 @@
#include <esp_heap_caps.h>
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
#include <freertos/task.h>
#include <math.h>
#include <stdint.h>
@@ -24,6 +25,15 @@ static char *time_to_string(int hhmm)
}
static TaskHandle_t simulation_task_handle = NULL;
static SemaphoreHandle_t simulation_mutex = NULL;
static void ensure_mutex_initialized(void)
{
if (simulation_mutex == NULL)
{
simulation_mutex = xSemaphoreCreateMutex();
}
}
// The struct is extended with a 'next' pointer to form a linked list.
typedef struct light_item_node_t
@@ -131,14 +141,14 @@ void cleanup_light_items(void)
static void initialize_light_items(void)
{
if (head != NULL)
{
ESP_LOGI(TAG, "Light schedule already initialized.");
return;
}
cleanup_light_items();
initialize_storage();
load_file("/spiffs/schema_03.csv");
static char filename[30];
auto persistence = PersistenceManager();
int variant = persistence.GetValue("light_variant", 1);
snprintf(filename, sizeof(filename), "/spiffs/schema_%02d.csv", variant);
load_file(filename);
if (head == NULL)
{
@@ -256,6 +266,11 @@ void simulate_cycle(void *args)
if (cycle_duration_minutes <= 0)
{
ESP_LOGE(TAG, "Invalid cycle duration: %d minutes. Must be positive.", cycle_duration_minutes);
if (simulation_mutex != NULL && xSemaphoreTake(simulation_mutex, portMAX_DELAY) == pdTRUE)
{
simulation_task_handle = NULL;
xSemaphoreGive(simulation_mutex);
}
vTaskDelete(NULL);
return;
}
@@ -355,12 +370,29 @@ void start_simulation_task(void)
void stop_simulation_task(void)
{
if (simulation_task_handle != NULL)
ensure_mutex_initialized();
if (xSemaphoreTake(simulation_mutex, portMAX_DELAY) == pdTRUE)
{
vTaskDelete(simulation_task_handle);
simulation_task_handle = NULL;
if (simulation_task_handle != NULL)
{
TaskHandle_t handle_to_delete = simulation_task_handle;
simulation_task_handle = NULL;
xSemaphoreGive(simulation_mutex);
// Prüfe ob der Task noch existiert bevor er gelöscht wird
eTaskState state = eTaskGetState(handle_to_delete);
if (state != eDeleted && state != eInvalid)
{
vTaskDelete(handle_to_delete);
}
}
else
{
xSemaphoreGive(simulation_mutex);
}
}
};
}
void start_simulation(void)
{