diff --git a/firmware/components/connectivity-manager/src/wifi_manager.c b/firmware/components/connectivity-manager/src/wifi_manager.c index 22fa15c..037fc9b 100644 --- a/firmware/components/connectivity-manager/src/wifi_manager.c +++ b/firmware/components/connectivity-manager/src/wifi_manager.c @@ -29,6 +29,31 @@ static EventGroupHandle_t s_wifi_event_group; static const char *TAG = "wifi_manager"; +static void wifi_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_LOGI(TAG, "WIFI_EVENT_STA_START: Connecting to AP..."); + esp_wifi_connect(); + } + else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) + { + ESP_LOGW(TAG, "WIFI_EVENT_STA_DISCONNECTED: Verbindung verloren, versuche erneut..."); + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } + 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, "IP_EVENT_STA_GOT_IP: IP-Adresse erhalten: " IPSTR, IP2STR(&event->ip_info.ip)); + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } + else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_LOST_IP) + { + ESP_LOGW(TAG, "IP_EVENT_STA_LOST_IP: IP-Adresse verloren!"); + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } +} + static void wifi_create_ap() { ESP_ERROR_CHECK(esp_wifi_stop()); @@ -58,6 +83,13 @@ void wifi_manager_init() ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); + // Default WiFi Station + esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta(); + + // Event Handler registrieren + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL)); + // Try to load stored WiFi configuration persistence_manager_t pm; char ssid[33] = {0}; @@ -97,9 +129,9 @@ void wifi_manager_init() EventBits_t bits; do { - esp_wifi_connect(); + ESP_LOGI(TAG, "Warte auf IP-Adresse (DHCP)..."); bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, - 5000 / portTICK_PERIOD_MS); + 10000 / portTICK_PERIOD_MS); if (bits & WIFI_CONNECTED_BIT) { led_behavior_t led_behavior = { @@ -108,7 +140,7 @@ void wifi_manager_init() .mode = LED_MODE_SOLID, }; led_status_set_behavior(led_behavior); - ESP_LOGI(TAG, "WiFi connection established successfully"); + ESP_LOGI(TAG, "WiFi connection established successfully (mit IP)"); break; } retries++; @@ -116,7 +148,9 @@ void wifi_manager_init() if (!(bits & WIFI_CONNECTED_BIT)) { - ESP_LOGW(TAG, "WiFi connection failed, switching to Access Point mode"); + ESP_LOGW(TAG, "WiFi connection failed (keine IP?), switching to Access Point mode"); + // AP-Netzwerkschnittstelle initialisieren, falls noch nicht geschehen + esp_netif_create_default_wifi_ap(); wifi_create_ap(); } } diff --git a/firmware/components/persistence-manager/include/persistence_manager.h b/firmware/components/persistence-manager/include/persistence_manager.h index e4305bd..4ddf322 100644 --- a/firmware/components/persistence-manager/include/persistence_manager.h +++ b/firmware/components/persistence-manager/include/persistence_manager.h @@ -28,6 +28,15 @@ extern "C" bool initialized; } persistence_manager_t; + /** + * @brief Erases the entire NVS flash (factory reset). + * + * Warning: This will remove all stored data and namespaces! + * + * @return esp_err_t ESP_OK on success, otherwise error code. + */ + esp_err_t persistence_manager_factory_reset(void); + /** * @brief Initialize the persistence manager with a given NVS namespace. * diff --git a/firmware/components/persistence-manager/src/persistence_manager.c b/firmware/components/persistence-manager/src/persistence_manager.c index af0309e..07d668d 100644 --- a/firmware/components/persistence-manager/src/persistence_manager.c +++ b/firmware/components/persistence-manager/src/persistence_manager.c @@ -1,9 +1,21 @@ + #include "persistence_manager.h" #include #include #define TAG "persistence_manager" +esp_err_t persistence_manager_factory_reset(void) +{ + // Erase the entire NVS flash (factory reset) + esp_err_t err = nvs_flash_erase(); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "Factory reset failed: %s", esp_err_to_name(err)); + } + return err; +} + esp_err_t persistence_manager_init(persistence_manager_t *pm, const char *nvs_namespace) { if (!pm) diff --git a/firmware/main/app_task.cpp b/firmware/main/app_task.cpp index 65eccf1..f910fcf 100644 --- a/firmware/main/app_task.cpp +++ b/firmware/main/app_task.cpp @@ -2,6 +2,7 @@ #include "analytics.h" #include "button_handling.h" +#include "common.h" #include "common/InactivityTracker.h" #include "hal/u8g2_esp32_hal.h" #include "i2c_checker.h" @@ -182,7 +183,55 @@ void app_task(void *args) return; } + // Display initialisieren, damit Info angezeigt werden kann setup_screen(); + + // BACK-Button prüfen und ggf. Einstellungen löschen (mit Countdown) + gpio_config_t io_conf = {}; + io_conf.intr_type = GPIO_INTR_DISABLE; + io_conf.mode = GPIO_MODE_INPUT; + io_conf.pin_bit_mask = (1ULL << BUTTON_BACK); + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + io_conf.pull_up_en = GPIO_PULLUP_ENABLE; + gpio_config(&io_conf); + + vTaskDelay(pdMS_TO_TICKS(10)); + if (gpio_get_level(BUTTON_BACK) == 0) + { + u8g2_SetFont(&u8g2, u8g2_font_ncenB08_tr); + for (int i = 5; i > 0; --i) + { + u8g2_ClearBuffer(&u8g2); + u8g2_DrawStr(&u8g2, 5, 20, "BACK gedrueckt!"); + u8g2_DrawStr(&u8g2, 5, 35, "Halte fuer Reset..."); + char buf[32]; + snprintf(buf, sizeof(buf), "Loesche in %d s", i); + u8g2_DrawStr(&u8g2, 5, 55, buf); + u8g2_SendBuffer(&u8g2); + vTaskDelay(pdMS_TO_TICKS(1000)); + if (gpio_get_level(BUTTON_BACK) != 0) + { + // Button losgelassen, abbrechen + break; + } + if (i == 1) + { + // After 5 seconds still pressed: perform factory reset + u8g2_ClearBuffer(&u8g2); + u8g2_DrawStr(&u8g2, 5, 30, "Alle Einstellungen "); + u8g2_DrawStr(&u8g2, 5, 45, "werden geloescht..."); + u8g2_SendBuffer(&u8g2); + persistence_manager_factory_reset(); + vTaskDelay(pdMS_TO_TICKS(1000)); + u8g2_ClearBuffer(&u8g2); + u8g2_DrawStr(&u8g2, 5, 35, "Fertig. Neustart..."); + u8g2_SendBuffer(&u8g2); + vTaskDelay(pdMS_TO_TICKS(1000)); + esp_restart(); + } + } + } + setup_buttons(); init_ui();