208 lines
8.5 KiB
C
Executable File
208 lines
8.5 KiB
C
Executable File
#include <stdio.h>
|
||
#include <string.h>
|
||
#include "freertos/FreeRTOS.h"
|
||
#include "freertos/task.h"
|
||
#include "esp_system.h"
|
||
#include "esp_log.h"
|
||
#include "esp_task_wdt.h"
|
||
#include "nvs.h"
|
||
|
||
// Project modules
|
||
#include "config.h"
|
||
#include "motor_control.h"
|
||
#include "state_manager.h"
|
||
#include "wifi_manager.h"
|
||
#include "http_server.h"
|
||
|
||
// Task handles for watchdog
|
||
static TaskHandle_t main_task_handle = NULL;
|
||
|
||
// Initialize watchdog timer
|
||
void init_watchdog(void) {
|
||
ESP_LOGI(SYSTEM_TAG, "Setting up watchdog monitoring...");
|
||
|
||
// Get current task handle and add to watchdog
|
||
main_task_handle = xTaskGetCurrentTaskHandle();
|
||
esp_err_t result = esp_task_wdt_add(main_task_handle);
|
||
|
||
if (result == ESP_OK) {
|
||
ESP_LOGI(SYSTEM_TAG, "Main task added to watchdog monitoring");
|
||
} else if (result == ESP_ERR_INVALID_ARG) {
|
||
ESP_LOGI(SYSTEM_TAG, "Task already monitored by watchdog");
|
||
} else {
|
||
ESP_LOGW(SYSTEM_TAG, "Watchdog not available: %s", esp_err_to_name(result));
|
||
main_task_handle = NULL; // Disable watchdog feeding
|
||
}
|
||
}
|
||
|
||
// Feed the watchdog
|
||
void feed_watchdog(void) {
|
||
if (main_task_handle != NULL) {
|
||
esp_err_t result = esp_task_wdt_reset();
|
||
if (result != ESP_OK) {
|
||
MOTOR_LOGD(SYSTEM_TAG, "Watchdog reset failed: %s", esp_err_to_name(result));
|
||
}
|
||
}
|
||
}
|
||
|
||
void app_main(void)
|
||
{
|
||
ESP_LOGI(SYSTEM_TAG, "Starting Maxxfan HTTP Controller with State Preservation!");
|
||
|
||
// Initialize state manager (includes NVS initialization)
|
||
ESP_LOGI(SYSTEM_TAG, "Initializing state manager...");
|
||
esp_err_t ret = state_manager_init();
|
||
if (ret != ESP_OK) {
|
||
ESP_LOGE(SYSTEM_TAG, "Failed to initialize state manager: %s", esp_err_to_name(ret));
|
||
return;
|
||
}
|
||
|
||
// Initialize watchdog timer
|
||
init_watchdog();
|
||
|
||
// Initialize motor control system
|
||
ESP_LOGI(SYSTEM_TAG, "Initializing motor control system...");
|
||
ret = motor_control_init();
|
||
if (ret != ESP_OK) {
|
||
ESP_LOGE(SYSTEM_TAG, "Failed to initialize motor control: %s", esp_err_to_name(ret));
|
||
return;
|
||
}
|
||
|
||
// Load saved state and restore motor if appropriate
|
||
ESP_LOGI(SYSTEM_TAG, "Loading saved state and applying restoration logic...");
|
||
esp_err_t load_result = state_manager_load_and_restore();
|
||
if (load_result == ESP_OK) {
|
||
ESP_LOGI(SYSTEM_TAG, "✓ State loaded and restoration logic applied");
|
||
} else if (load_result == ESP_ERR_NVS_NOT_FOUND) {
|
||
ESP_LOGI(SYSTEM_TAG, "ℹ️ No saved state found, using defaults");
|
||
} else {
|
||
ESP_LOGW(SYSTEM_TAG, "⚠️ Failed to load state: %s", esp_err_to_name(load_result));
|
||
}
|
||
|
||
// Initialize WiFi manager
|
||
ESP_LOGI(SYSTEM_TAG, "Initializing WiFi manager...");
|
||
ret = wifi_manager_init();
|
||
if (ret != ESP_OK) {
|
||
ESP_LOGE(SYSTEM_TAG, "Failed to initialize WiFi manager: %s", esp_err_to_name(ret));
|
||
return;
|
||
}
|
||
|
||
// Connect to WiFi using default credentials
|
||
ESP_LOGI(SYSTEM_TAG, "Connecting to WiFi network: %s", WIFI_SSID);
|
||
ret = wifi_manager_connect_default();
|
||
if (ret != ESP_OK) {
|
||
ESP_LOGE(SYSTEM_TAG, "Failed to start WiFi connection: %s", esp_err_to_name(ret));
|
||
return;
|
||
}
|
||
|
||
// Wait for WiFi connection (with timeout)
|
||
ESP_LOGI(SYSTEM_TAG, "Waiting for WiFi connection...");
|
||
esp_err_t wifi_result = wifi_manager_wait_for_connection(30000); // 30 second timeout
|
||
if (wifi_result == ESP_OK) {
|
||
char ip_str[16];
|
||
wifi_manager_get_ip_string(ip_str, sizeof(ip_str));
|
||
wifi_info_t wifi_info;
|
||
wifi_manager_get_info(&wifi_info);
|
||
|
||
ESP_LOGI(SYSTEM_TAG, "✓ WiFi connected successfully!");
|
||
ESP_LOGI(SYSTEM_TAG, " SSID: %s", wifi_info.ssid);
|
||
ESP_LOGI(SYSTEM_TAG, " IP Address: %s", ip_str);
|
||
ESP_LOGI(SYSTEM_TAG, " Signal Strength: %d dBm", wifi_info.rssi);
|
||
} else if (wifi_result == ESP_ERR_TIMEOUT) {
|
||
ESP_LOGW(SYSTEM_TAG, "⚠️ WiFi connection timeout - continuing with limited functionality");
|
||
} else {
|
||
ESP_LOGW(SYSTEM_TAG, "⚠️ WiFi connection failed - continuing with limited functionality");
|
||
}
|
||
|
||
// Start HTTP server (even if WiFi failed, for debugging)
|
||
ESP_LOGI(SYSTEM_TAG, "Starting web server...");
|
||
ret = http_server_init();
|
||
if (ret == ESP_OK) {
|
||
ESP_LOGI(SYSTEM_TAG, "✓ Web server started successfully");
|
||
} else {
|
||
ESP_LOGE(SYSTEM_TAG, "✗ Failed to start web server: %s", esp_err_to_name(ret));
|
||
}
|
||
|
||
// Report final system state after initialization
|
||
const motor_state_t* final_state = motor_get_state();
|
||
wifi_info_t final_wifi_info;
|
||
wifi_manager_get_info(&final_wifi_info);
|
||
char final_ip_str[16];
|
||
wifi_manager_get_ip_string(final_ip_str, sizeof(final_ip_str));
|
||
|
||
ESP_LOGI(SYSTEM_TAG, "=== SYSTEM INITIALIZATION COMPLETE ===");
|
||
ESP_LOGI(SYSTEM_TAG, "Reset Reason: %s", state_manager_get_reset_reason_string());
|
||
ESP_LOGI(SYSTEM_TAG, "Watchdog Reset: %s", state_manager_was_watchdog_reset() ? "YES" : "NO");
|
||
|
||
// Motor status
|
||
ESP_LOGI(SYSTEM_TAG, "Motor: mode=%s, target=%d%%, current=%d%%, state=%s",
|
||
motor_mode_to_string(final_state->mode), final_state->target_speed,
|
||
final_state->current_speed, motor_state_to_string(final_state->state));
|
||
|
||
if (final_state->mode != MOTOR_OFF && final_state->target_speed > 0) {
|
||
ESP_LOGI(SYSTEM_TAG, "🔄 Motor restored to: %s @ %d%%",
|
||
motor_mode_to_string(final_state->mode), final_state->target_speed);
|
||
} else {
|
||
ESP_LOGI(SYSTEM_TAG, "⏸️ Motor remains OFF");
|
||
}
|
||
|
||
motor_mode_t last_on_mode;
|
||
int last_on_speed;
|
||
motor_get_last_on_state(&last_on_mode, &last_on_speed);
|
||
ESP_LOGI(SYSTEM_TAG, "Last ON state: %s @ %d%%",
|
||
motor_mode_to_string(last_on_mode), last_on_speed);
|
||
ESP_LOGI(SYSTEM_TAG, "User turned off: %s", motor_get_user_turned_off() ? "YES" : "NO");
|
||
|
||
// WiFi status
|
||
ESP_LOGI(SYSTEM_TAG, "WiFi: status=%s, SSID=%s, IP=%s, RSSI=%d dBm",
|
||
wifi_manager_status_to_string(final_wifi_info.status),
|
||
final_wifi_info.ssid, final_ip_str, final_wifi_info.rssi);
|
||
|
||
// Connection statistics
|
||
uint32_t total_attempts, successful_connections;
|
||
esp_err_t last_wifi_error;
|
||
wifi_manager_get_stats(&total_attempts, &successful_connections, &last_wifi_error);
|
||
ESP_LOGI(SYSTEM_TAG, "WiFi Stats: %lu attempts, %lu successful", total_attempts, successful_connections);
|
||
|
||
// HTTP server statistics
|
||
uint32_t total_requests, active_connections, last_request_time;
|
||
http_server_get_stats(&total_requests, &active_connections, &last_request_time);
|
||
ESP_LOGI(SYSTEM_TAG, "HTTP Server: running=%s, requests=%lu",
|
||
http_server_is_running() ? "YES" : "NO", total_requests);
|
||
|
||
ESP_LOGI(SYSTEM_TAG, "Saved state exists: %s", state_manager_has_saved_state() ? "YES" : "NO");
|
||
ESP_LOGI(SYSTEM_TAG, "=====================================");
|
||
|
||
ESP_LOGI(SYSTEM_TAG, "=== Enhanced Maxxfan Controller Ready! ===");
|
||
ESP_LOGI(SYSTEM_TAG, "Features: State Preservation, Direction Safety, Motor Ramping, ON Button");
|
||
ESP_LOGI(SYSTEM_TAG, "Safety: %d-second cooldown for direction changes", DIRECTION_CHANGE_COOLDOWN_MS / 1000);
|
||
ESP_LOGI(SYSTEM_TAG, "Memory: Remembers settings after power loss (except watchdog resets)");
|
||
ESP_LOGI(SYSTEM_TAG, "WiFi: Enhanced connection management with auto-reconnect");
|
||
ESP_LOGI(SYSTEM_TAG, "State Manager: Enhanced NVS operations with validation and recovery");
|
||
ESP_LOGI(SYSTEM_TAG, "HTTP Server: Modular web server with comprehensive API");
|
||
|
||
if (wifi_manager_is_connected()) {
|
||
ESP_LOGI(SYSTEM_TAG, "🌐 Open your browser and go to: http://%s", final_ip_str);
|
||
} else {
|
||
ESP_LOGI(SYSTEM_TAG, "⚠️ WiFi not connected - check network settings");
|
||
}
|
||
|
||
// Main loop - reset watchdog periodically and update motor cooldown
|
||
uint32_t loop_count = 0;
|
||
while (1) {
|
||
feed_watchdog();
|
||
|
||
// Update motor cooldown time for status reporting
|
||
motor_update_cooldown_time();
|
||
|
||
// Periodic WiFi status logging (every 30 seconds)
|
||
if (++loop_count % 10 == 0) {
|
||
wifi_status_t current_status = wifi_manager_get_status();
|
||
if (current_status != WIFI_STATUS_CONNECTED) {
|
||
ESP_LOGW(SYSTEM_TAG, "WiFi status: %s", wifi_manager_status_to_string(current_status));
|
||
}
|
||
}
|
||
|
||
vTaskDelay(pdMS_TO_TICKS(WATCHDOG_FEED_INTERVAL_MS));
|
||
}
|
||
} |