Updates to BellEngine, ClientManager, ConfigManager, and Telemetry Logging
This commit is contained in:
@@ -131,7 +131,7 @@ void BellEngine::stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BellEngine::emergencyStop() {
|
void BellEngine::emergencyStop() {
|
||||||
LOG_INFO("BellEngine 🛑 EMERGENCY STOP ACTIVATED");
|
LOG_INFO("BellEngine - 🛑 Forcing Stop Immediately");
|
||||||
_emergencyStop.store(true);
|
_emergencyStop.store(true);
|
||||||
_engineRunning.store(false);
|
_engineRunning.store(false);
|
||||||
emergencyShutdown();
|
emergencyShutdown();
|
||||||
@@ -142,7 +142,7 @@ void BellEngine::setMelodyData(const std::vector<uint16_t>& melodySteps) {
|
|||||||
_melodySteps = melodySteps;
|
_melodySteps = melodySteps;
|
||||||
_melodyDataReady.store(true);
|
_melodyDataReady.store(true);
|
||||||
portEXIT_CRITICAL(&_melodyMutex);
|
portEXIT_CRITICAL(&_melodyMutex);
|
||||||
LOG_DEBUG("BellEngine loaded melody: %d steps", melodySteps.size());
|
LOG_DEBUG("BellEngine - Loaded melody: %d steps", melodySteps.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BellEngine::clearMelodyData() {
|
void BellEngine::clearMelodyData() {
|
||||||
@@ -150,7 +150,7 @@ void BellEngine::clearMelodyData() {
|
|||||||
_melodySteps.clear();
|
_melodySteps.clear();
|
||||||
_melodyDataReady.store(false);
|
_melodyDataReady.store(false);
|
||||||
portEXIT_CRITICAL(&_melodyMutex);
|
portEXIT_CRITICAL(&_melodyMutex);
|
||||||
LOG_DEBUG("BellEngine melody data cleared");
|
LOG_DEBUG("BellEngine - Melody data cleared");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================== CRITICAL TIMING SECTION ==================
|
// ================== CRITICAL TIMING SECTION ==================
|
||||||
@@ -158,7 +158,7 @@ void BellEngine::clearMelodyData() {
|
|||||||
|
|
||||||
void BellEngine::engineTask(void* parameter) {
|
void BellEngine::engineTask(void* parameter) {
|
||||||
BellEngine* engine = static_cast<BellEngine*>(parameter);
|
BellEngine* engine = static_cast<BellEngine*>(parameter);
|
||||||
LOG_DEBUG("🔥 BellEngine task started on Core %d with MAXIMUM priority", xPortGetCoreID());
|
LOG_DEBUG("BellEngine - 🔥 Engine task started on Core %d with MAXIMUM priority", xPortGetCoreID());
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (engine->_engineRunning.load() && !engine->_emergencyStop.load()) {
|
if (engine->_engineRunning.load() && !engine->_emergencyStop.load()) {
|
||||||
@@ -186,7 +186,7 @@ void BellEngine::engineLoop() {
|
|||||||
|
|
||||||
// Pause handling AFTER complete loop - never interrupt mid-melody!
|
// Pause handling AFTER complete loop - never interrupt mid-melody!
|
||||||
while (_player.isPaused && _player.isPlaying && !_player.hardStop) {
|
while (_player.isPaused && _player.isPlaying && !_player.hardStop) {
|
||||||
LOG_DEBUG("⏸️ Pausing between melody loops");
|
LOG_VERBOSE("BellEngine - ⏸️ Pausing between melody loops");
|
||||||
vTaskDelay(pdMS_TO_TICKS(10)); // Wait during pause
|
vTaskDelay(pdMS_TO_TICKS(10)); // Wait during pause
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,17 +207,17 @@ void BellEngine::playbackLoop() {
|
|||||||
portEXIT_CRITICAL(&_melodyMutex);
|
portEXIT_CRITICAL(&_melodyMutex);
|
||||||
|
|
||||||
if (melodySteps.empty()) {
|
if (melodySteps.empty()) {
|
||||||
LOG_ERROR("Empty melody in playback loop!");
|
LOG_ERROR("BellEngine - ❌ Empty melody in playback loop!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("🎵 Starting melody loop (%d steps)", melodySteps.size());
|
LOG_DEBUG("BellEngine - 🎵 Starting melody loop (%d steps)", melodySteps.size());
|
||||||
|
|
||||||
// CRITICAL TIMING LOOP - Complete the entire melody without interruption
|
// CRITICAL TIMING LOOP - Complete the entire melody without interruption
|
||||||
for (uint16_t note : melodySteps) {
|
for (uint16_t note : melodySteps) {
|
||||||
// Emergency exit check (only emergency stops can interrupt mid-loop)
|
// Emergency exit check (only emergency stops can interrupt mid-loop)
|
||||||
if (_emergencyStop.load() || _player.hardStop) {
|
if (_emergencyStop.load() || _player.hardStop) {
|
||||||
LOG_DEBUG("Emergency exit from playback loop");
|
LOG_DEBUG("BellEngine - Emergency exit from playback loop");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,8 +225,9 @@ void BellEngine::playbackLoop() {
|
|||||||
activateNote(note);
|
activateNote(note);
|
||||||
|
|
||||||
// Precise timing delay - validate speed to prevent division by zero
|
// Precise timing delay - validate speed to prevent division by zero
|
||||||
|
// I THINK this should be moved outside the Bell Engine
|
||||||
if (_player.speed == 0) {
|
if (_player.speed == 0) {
|
||||||
LOG_ERROR("❌ Invalid speed=0 detected, stopping playback");
|
LOG_ERROR("BellEngine - ❌ Invalid Speed (0) detected, stopping playback");
|
||||||
_player.hardStop = true;
|
_player.hardStop = true;
|
||||||
_engineRunning.store(false);
|
_engineRunning.store(false);
|
||||||
return;
|
return;
|
||||||
@@ -241,9 +242,9 @@ void BellEngine::playbackLoop() {
|
|||||||
_player.onMelodyLoopCompleted(); // 🔥 Notify Player that melody actually finished!
|
_player.onMelodyLoopCompleted(); // 🔥 Notify Player that melody actually finished!
|
||||||
if ((_player.continuous_loop && _player.segment_duration == 0) || _player.total_duration == 0) {
|
if ((_player.continuous_loop && _player.segment_duration == 0) || _player.total_duration == 0) {
|
||||||
vTaskDelay(pdMS_TO_TICKS(500)); //Give Player time to pause/stop
|
vTaskDelay(pdMS_TO_TICKS(500)); //Give Player time to pause/stop
|
||||||
LOG_VERBOSE("Melody loop completed for SINGLE Mode - waiting for Player to handle pause/stop");
|
LOG_VERBOSE("BellEngine - Loop completed in SINGLE Mode - waiting for Player to handle pause/stop");
|
||||||
}
|
}
|
||||||
LOG_DEBUG("🎵 Melody loop completed with PRECISION");
|
LOG_DEBUG("BellEngine - 🎵 Melody loop completed with PRECISION");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,26 +268,26 @@ void BellEngine::activateNote(uint16_t note) {
|
|||||||
|
|
||||||
// Additional safety check to prevent underflow crashes
|
// Additional safety check to prevent underflow crashes
|
||||||
if (bellIndex >= 255) {
|
if (bellIndex >= 255) {
|
||||||
LOG_ERROR("🚨 UNDERFLOW ERROR: bellIndex underflow for noteIndex %d", noteIndex);
|
LOG_ERROR("BellEngine - 🚨 UNDERFLOW ERROR: bellIndex underflow for noteIndex %d", noteIndex);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bounds check (CRITICAL SAFETY)
|
// Bounds check (CRITICAL SAFETY)
|
||||||
if (bellIndex >= 16) {
|
if (bellIndex >= 16) {
|
||||||
LOG_ERROR("🚨 BOUNDS ERROR: bellIndex %d >= 16", bellIndex);
|
LOG_ERROR("BellEngine - 🚨 BOUNDS ERROR: bellIndex %d >= 16", bellIndex);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for duplicate bell firing in this note
|
// Check for duplicate bell firing in this note
|
||||||
if (bellFired[bellIndex]) {
|
if (bellFired[bellIndex]) {
|
||||||
LOG_DEBUG("⚠️ DUPLICATE BELL: Skipping duplicate firing of bell %d for note %d", bellIndex, noteIndex);
|
LOG_DEBUG("BellEngine - ⚠️ DUPLICATE BELL: Skipping duplicate firing of bell %d for note %d", bellIndex, noteIndex);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if bell is configured (OutputManager will validate this)
|
// Check if bell is configured (OutputManager will validate this)
|
||||||
uint8_t physicalOutput = _outputManager.getPhysicalOutput(bellIndex);
|
uint8_t physicalOutput = _outputManager.getPhysicalOutput(bellIndex);
|
||||||
if (physicalOutput == 255) {
|
if (physicalOutput == 255) {
|
||||||
LOG_DEBUG("⚠️ UNCONFIGURED: Bell %d not configured, skipping", bellIndex);
|
LOG_DEBUG("BellEngine - ⚠️ UNCONFIGURED: Bell %d not configured, skipping", bellIndex);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,14 +306,14 @@ void BellEngine::activateNote(uint16_t note) {
|
|||||||
// Record telemetry
|
// Record telemetry
|
||||||
_telemetry.recordBellStrike(bellIndex);
|
_telemetry.recordBellStrike(bellIndex);
|
||||||
|
|
||||||
LOG_VERBOSE("🔨 STRIKE! Note:%d → Bell:%d for %dms", noteIndex, bellIndex, durationMs);
|
LOG_VERBOSE("BellEngine - 🔨 STRIKE! Note:%d → Bell:%d for %dms", noteIndex, bellIndex, durationMs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🚀 FIRE ALL BELLS SIMULTANEOUSLY!
|
// 🚀 FIRE ALL BELLS SIMULTANEOUSLY!
|
||||||
if (!bellDurations.empty()) {
|
if (!bellDurations.empty()) {
|
||||||
_outputManager.fireOutputsBatchForDuration(bellDurations);
|
_outputManager.fireOutputsBatchForDuration(bellDurations);
|
||||||
LOG_VERBOSE("🔥🔥 BATCH FIRED %d bells SIMULTANEOUSLY!", bellDurations.size());
|
LOG_VERBOSE("BellEngine - 🔥 Batch Fired %d bells Simultaneously !", bellDurations.size());
|
||||||
|
|
||||||
// 🔔 NOTIFY WEBSOCKET CLIENTS OF BELL DINGS!
|
// 🔔 NOTIFY WEBSOCKET CLIENTS OF BELL DINGS!
|
||||||
// * deactivated currently, since unstable and causes performance issues *
|
// * deactivated currently, since unstable and causes performance issues *
|
||||||
@@ -338,7 +339,7 @@ void BellEngine::preciseDelay(uint32_t microseconds) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BellEngine::emergencyShutdown() {
|
void BellEngine::emergencyShutdown() {
|
||||||
LOG_INFO("🚨 EMERGENCY SHUTDOWN - Using OutputManager");
|
LOG_INFO("BellEngine - 🚨 Emergency Shutdown - Notifying OutputManager");
|
||||||
_outputManager.emergencyShutdown();
|
_outputManager.emergencyShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,10 +364,10 @@ void BellEngine::notifyBellsFired(const std::vector<uint8_t>& bellIndices) {
|
|||||||
// Send notification to WebSocket clients only (not MQTT)
|
// Send notification to WebSocket clients only (not MQTT)
|
||||||
_communicationManager->broadcastToAllWebSocketClients(dingMsg);
|
_communicationManager->broadcastToAllWebSocketClients(dingMsg);
|
||||||
|
|
||||||
LOG_DEBUG("🔔 DING notification sent for %d bells", bellIndices.size());
|
LOG_DEBUG("BellEngine - 🔔 DING notification sent for %d bells", bellIndices.size());
|
||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
LOG_ERROR("Failed to send ding notification");
|
LOG_WARNING("BellEngine - ❌ Failed to send ding notification");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,30 +2,30 @@
|
|||||||
#include "../Logging/Logging.hpp"
|
#include "../Logging/Logging.hpp"
|
||||||
|
|
||||||
ClientManager::ClientManager() {
|
ClientManager::ClientManager() {
|
||||||
LOG_INFO("Client Manager Component - Initialized");
|
LOG_INFO("Client Manager initialized !");
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientManager::~ClientManager() {
|
ClientManager::~ClientManager() {
|
||||||
_clients.clear();
|
_clients.clear();
|
||||||
LOG_INFO("Client Manager Component - Destroyed");
|
LOG_INFO("Client Manager destroyed");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientManager::addClient(AsyncWebSocketClient* client, DeviceType deviceType) {
|
void ClientManager::addClient(AsyncWebSocketClient* client, DeviceType deviceType) {
|
||||||
if (!isValidClient(client)) {
|
if (!isValidClient(client)) {
|
||||||
LOG_ERROR("Cannot add invalid client");
|
LOG_WARNING("Client Manager - Cannot add invalid client");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t clientId = client->id();
|
uint32_t clientId = client->id();
|
||||||
_clients[clientId] = ClientInfo(client, deviceType);
|
_clients[clientId] = ClientInfo(client, deviceType);
|
||||||
|
|
||||||
LOG_INFO("Client #%u added as %s device", clientId, deviceTypeToString(deviceType));
|
LOG_INFO("Client Manager - Client #%u added as %s device", clientId, deviceTypeToString(deviceType));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientManager::removeClient(uint32_t clientId) {
|
void ClientManager::removeClient(uint32_t clientId) {
|
||||||
auto it = _clients.find(clientId);
|
auto it = _clients.find(clientId);
|
||||||
if (it != _clients.end()) {
|
if (it != _clients.end()) {
|
||||||
LOG_INFO("Client #%u removed (%s device)", clientId,
|
LOG_INFO("Client Manager - Client #%u removed (%s device)", clientId,
|
||||||
deviceTypeToString(it->second.deviceType));
|
deviceTypeToString(it->second.deviceType));
|
||||||
_clients.erase(it);
|
_clients.erase(it);
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ void ClientManager::updateClientType(uint32_t clientId, DeviceType deviceType) {
|
|||||||
if (it != _clients.end()) {
|
if (it != _clients.end()) {
|
||||||
DeviceType oldType = it->second.deviceType;
|
DeviceType oldType = it->second.deviceType;
|
||||||
it->second.deviceType = deviceType;
|
it->second.deviceType = deviceType;
|
||||||
LOG_INFO("Client #%u type updated from %s to %s", clientId,
|
LOG_INFO("Client Manager - Client #%u type updated from %s to %s", clientId,
|
||||||
deviceTypeToString(oldType), deviceTypeToString(deviceType));
|
deviceTypeToString(oldType), deviceTypeToString(deviceType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,11 +72,11 @@ bool ClientManager::sendToClient(uint32_t clientId, const String& message) {
|
|||||||
if (it != _clients.end() && isValidClient(it->second.client)) {
|
if (it != _clients.end() && isValidClient(it->second.client)) {
|
||||||
it->second.client->text(message);
|
it->second.client->text(message);
|
||||||
updateClientLastSeen(clientId);
|
updateClientLastSeen(clientId);
|
||||||
LOG_DEBUG("Message sent to client #%u: %s", clientId, message.c_str());
|
LOG_DEBUG("Client Manager - Message sent to client #%u: %s", clientId, message.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_WARNING("Failed to send message to client #%u - client not found or invalid", clientId);
|
LOG_WARNING("Client Manager - Failed to send message to client #%u - client not found or invalid", clientId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ void ClientManager::sendToMasterClients(const String& message) {
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_DEBUG("Message sent to %d master client(s): %s", count, message.c_str());
|
LOG_DEBUG("Client Manager - Message sent to %d master client(s): %s", count, message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientManager::sendToSecondaryClients(const String& message) {
|
void ClientManager::sendToSecondaryClients(const String& message) {
|
||||||
@@ -103,7 +103,7 @@ void ClientManager::sendToSecondaryClients(const String& message) {
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_DEBUG("Message sent to %d secondary client(s): %s", count, message.c_str());
|
LOG_DEBUG("Client Manager - Message sent to %d secondary client(s): %s", count, message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientManager::broadcastToAll(const String& message) {
|
void ClientManager::broadcastToAll(const String& message) {
|
||||||
@@ -115,14 +115,14 @@ void ClientManager::broadcastToAll(const String& message) {
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_DEBUG("Message broadcasted to %d client(s): %s", count, message.c_str());
|
LOG_DEBUG("Client Manager - Message broadcasted to %d client(s): %s", count, message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientManager::cleanupDisconnectedClients() {
|
void ClientManager::cleanupDisconnectedClients() {
|
||||||
auto it = _clients.begin();
|
auto it = _clients.begin();
|
||||||
while (it != _clients.end()) {
|
while (it != _clients.end()) {
|
||||||
if (!isValidClient(it->second.client)) {
|
if (!isValidClient(it->second.client)) {
|
||||||
LOG_DEBUG("Cleaning up disconnected client #%u", it->first);
|
LOG_DEBUG("Client Manager - Cleaning up disconnected client #%u", it->first);
|
||||||
it->second.isConnected = false;
|
it->second.isConnected = false;
|
||||||
it = _clients.erase(it);
|
it = _clients.erase(it);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ void ConfigManager::initializeCleanDefaults() {
|
|||||||
// Set MQTT user to deviceUID for unique identification
|
// Set MQTT user to deviceUID for unique identification
|
||||||
mqttConfig.user = deviceConfig.deviceUID;
|
mqttConfig.user = deviceConfig.deviceUID;
|
||||||
|
|
||||||
LOG_INFO("ConfigManager: Clean defaults initialized with auto-generated identifiers");
|
LOG_DEBUG("ConfigManager - Clean defaults initialized with auto-generated identifiers");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigManager::generateNetworkIdentifiers() {
|
void ConfigManager::generateNetworkIdentifiers() {
|
||||||
@@ -36,7 +36,7 @@ void ConfigManager::generateNetworkIdentifiers() {
|
|||||||
networkConfig.apSsid = "BellSystems-Setup-" + deviceConfig.deviceUID;
|
networkConfig.apSsid = "BellSystems-Setup-" + deviceConfig.deviceUID;
|
||||||
|
|
||||||
|
|
||||||
LOG_INFO("ConfigManager: Generated hostname: %s, AP SSID: %s",
|
LOG_DEBUG("ConfigManager - Generated hostname: %s, AP SSID: %s",
|
||||||
networkConfig.hostname.c_str(), networkConfig.apSsid.c_str());
|
networkConfig.hostname.c_str(), networkConfig.apSsid.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,11 +49,11 @@ void ConfigManager::createDefaultBellConfig() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigManager::begin() {
|
bool ConfigManager::begin() {
|
||||||
LOG_INFO("ConfigManager: Starting clean deployment-ready initialization");
|
LOG_INFO("ConfigManager - ✅ Initializing...");
|
||||||
|
|
||||||
// Step 1: Initialize NVS for device identity (factory-set, permanent)
|
// Step 1: Initialize NVS for device identity (factory-set, permanent)
|
||||||
if (!initializeNVS()) {
|
if (!initializeNVS()) {
|
||||||
LOG_ERROR("ConfigManager: NVS initialization failed, using empty defaults");
|
LOG_ERROR("ConfigManager - ❌ NVS initialization failed, using empty defaults");
|
||||||
} else {
|
} else {
|
||||||
// Load device identity from NVS (deviceUID, hwType, hwVersion)
|
// Load device identity from NVS (deviceUID, hwType, hwVersion)
|
||||||
loadDeviceIdentityFromNVS();
|
loadDeviceIdentityFromNVS();
|
||||||
@@ -64,54 +64,52 @@ bool ConfigManager::begin() {
|
|||||||
|
|
||||||
// Step 3: Initialize SD card for user-configurable settings
|
// Step 3: Initialize SD card for user-configurable settings
|
||||||
if (!ensureSDCard()) {
|
if (!ensureSDCard()) {
|
||||||
LOG_ERROR("ConfigManager: SD Card initialization failed, using defaults");
|
LOG_ERROR("ConfigManager - ❌ SD Card initialization failed, using defaults");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 5: Load update servers list
|
// Step 5: Load update servers list
|
||||||
if (!loadUpdateServers()) {
|
if (!loadUpdateServers()) {
|
||||||
LOG_WARNING("ConfigManager: Could not load update servers - using fallback only");
|
LOG_WARNING("ConfigManager - ⚠️ Could not load update servers - using fallback only");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 6: Load user-configurable settings from SD (and create if missing)
|
|
||||||
loadFromSD();
|
|
||||||
|
|
||||||
// Load network config, save defaults if not found
|
// Load network config, save defaults if not found
|
||||||
if (!loadNetworkConfig()) {
|
if (!loadNetworkConfig()) {
|
||||||
LOG_INFO("ConfigManager: Creating default network config file");
|
LOG_WARNING("ConfigManager - ⚠️ Creating default network config file");
|
||||||
saveNetworkConfig();
|
saveNetworkConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load bell durations, save defaults if not found
|
// Load bell durations, save defaults if not found
|
||||||
if (!loadBellDurations()) {
|
if (!loadBellDurations()) {
|
||||||
LOG_INFO("ConfigManager: Creating default bell durations file");
|
LOG_WARNING("ConfigManager - ⚠️ Creating default bell durations file");
|
||||||
saveBellDurations();
|
saveBellDurations();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load bell outputs, save defaults if not found
|
// Load bell outputs, save defaults if not found
|
||||||
if (!loadBellOutputs()) {
|
if (!loadBellOutputs()) {
|
||||||
LOG_INFO("ConfigManager: Creating default bell outputs file");
|
LOG_WARNING("ConfigManager - ⚠️ Creating default bell outputs file");
|
||||||
saveBellOutputs();
|
saveBellOutputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load clock config, save defaults if not found
|
// Load clock config, save defaults if not found
|
||||||
if (!loadClockConfig()) {
|
if (!loadClockConfig()) {
|
||||||
LOG_INFO("ConfigManager: Creating default clock config file");
|
LOG_WARNING("ConfigManager - ⚠️ Creating default clock config file");
|
||||||
saveClockConfig();
|
saveClockConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load clock state, save defaults if not found
|
// Load clock state, save defaults if not found
|
||||||
if (!loadClockState()) {
|
if (!loadClockState()) {
|
||||||
LOG_INFO("ConfigManager: Creating default clock state file");
|
LOG_WARNING("ConfigManager - ⚠️ Creating default clock state file");
|
||||||
saveClockState();
|
saveClockState();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loadGeneralConfig()) {
|
if (!loadGeneralConfig()) {
|
||||||
LOG_INFO("ConfigManager: Creating default general config file");
|
LOG_WARNING("ConfigManager - ⚠️ Creating default general config file");
|
||||||
saveGeneralConfig();
|
saveGeneralConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("ConfigManager: Initialization complete - UID: %s, Hostname: %s",
|
LOG_INFO("ConfigManager - ✅ Initialization Complete ! UID: %s, Hostname: %s",
|
||||||
deviceConfig.deviceUID.c_str(), networkConfig.hostname.c_str());
|
deviceConfig.deviceUID.c_str(), networkConfig.hostname.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -123,29 +121,29 @@ bool ConfigManager::begin() {
|
|||||||
bool ConfigManager::initializeNVS() {
|
bool ConfigManager::initializeNVS() {
|
||||||
esp_err_t err = nvs_flash_init();
|
esp_err_t err = nvs_flash_init();
|
||||||
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
LOG_WARNING("ConfigManager: NVS partition truncated, erasing...");
|
LOG_WARNING("ConfigManager - ⚠️ NVS partition truncated, erasing...");
|
||||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||||
err = nvs_flash_init();
|
err = nvs_flash_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
LOG_ERROR("ConfigManager: Failed to initialize NVS flash: %s", esp_err_to_name(err));
|
LOG_ERROR("ConfigManager - ❌ Failed to initialize NVS flash: %s", esp_err_to_name(err));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &nvsHandle);
|
err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &nvsHandle);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
LOG_ERROR("ConfigManager: Failed to open NVS handle: %s", esp_err_to_name(err));
|
LOG_ERROR("ConfigManager - ❌ Failed to open NVS handle: %s", esp_err_to_name(err));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("ConfigManager: NVS initialized successfully");
|
LOG_DEBUG("ConfigManager - NVS initialized successfully");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigManager::loadDeviceIdentityFromNVS() {
|
bool ConfigManager::loadDeviceIdentityFromNVS() {
|
||||||
if (nvsHandle == 0) {
|
if (nvsHandle == 0) {
|
||||||
LOG_ERROR("ConfigManager: NVS not initialized, cannot load device identity");
|
LOG_ERROR("ConfigManager - ❌ NVS not initialized, cannot load device identity");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +179,7 @@ bool ConfigManager::loadDeviceIdentityFromNVS() {
|
|||||||
|
|
||||||
String ConfigManager::readNVSString(const char* key, const String& defaultValue) {
|
String ConfigManager::readNVSString(const char* key, const String& defaultValue) {
|
||||||
if (nvsHandle == 0) {
|
if (nvsHandle == 0) {
|
||||||
LOG_WARNING("ConfigManager: NVS not initialized, returning default for key: %s", key);
|
LOG_ERROR("ConfigManager - ❌ NVS not initialized, returning default for key: %s", key);
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,12 +187,12 @@ String ConfigManager::readNVSString(const char* key, const String& defaultValue)
|
|||||||
esp_err_t err = nvs_get_str(nvsHandle, key, NULL, &required_size);
|
esp_err_t err = nvs_get_str(nvsHandle, key, NULL, &required_size);
|
||||||
|
|
||||||
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||||
LOG_DEBUG("ConfigManager: NVS key '%s' not found, using default: %s", key, defaultValue.c_str());
|
LOG_DEBUG("ConfigManager - NVS key '%s' not found, using default: %s", key, defaultValue.c_str());
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
LOG_ERROR("ConfigManager: Error reading NVS key '%s': %s", key, esp_err_to_name(err));
|
LOG_ERROR("ConfigManager - ❌ Error reading NVS key '%s': %s", key, esp_err_to_name(err));
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +200,7 @@ String ConfigManager::readNVSString(const char* key, const String& defaultValue)
|
|||||||
err = nvs_get_str(nvsHandle, key, buffer, &required_size);
|
err = nvs_get_str(nvsHandle, key, buffer, &required_size);
|
||||||
|
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
LOG_ERROR("ConfigManager: Error reading NVS value for key '%s': %s", key, esp_err_to_name(err));
|
LOG_ERROR("ConfigManager - ❌ Error reading NVS value for key '%s': %s", key, esp_err_to_name(err));
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
@@ -210,13 +208,10 @@ String ConfigManager::readNVSString(const char* key, const String& defaultValue)
|
|||||||
String result = String(buffer);
|
String result = String(buffer);
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
|
||||||
LOG_DEBUG("ConfigManager: Read NVS key '%s': %s", key, result.c_str());
|
LOG_VERBOSE("ConfigManager - Read NVS key '%s': %s", key, result.c_str());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// REMOVED: writeNVSString() - Production firmware MUST NOT write to NVS
|
|
||||||
// All device identity is factory-set and read-only in production firmware
|
|
||||||
|
|
||||||
// ════════════════════════════════════════════════════════════════════════════
|
// ════════════════════════════════════════════════════════════════════════════
|
||||||
// STANDARD SD CARD FUNCTIONALITY
|
// STANDARD SD CARD FUNCTIONALITY
|
||||||
// ════════════════════════════════════════════════════════════════════════════
|
// ════════════════════════════════════════════════════════════════════════════
|
||||||
@@ -224,21 +219,16 @@ String ConfigManager::readNVSString(const char* key, const String& defaultValue)
|
|||||||
bool ConfigManager::ensureSDCard() {
|
bool ConfigManager::ensureSDCard() {
|
||||||
if (!sdInitialized) {
|
if (!sdInitialized) {
|
||||||
sdInitialized = SD.begin(hardwareConfig.sdChipSelect);
|
sdInitialized = SD.begin(hardwareConfig.sdChipSelect);
|
||||||
|
if (!sdInitialized) {
|
||||||
|
LOG_ERROR("ConfigManager - ❌ SD Card not available");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return sdInitialized;
|
return sdInitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigManager::loadFromSD() {
|
|
||||||
if (!ensureSDCard()) {
|
|
||||||
LOG_ERROR("ConfigManager: Cannot load from SD - SD not available");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LOG_INFO("ConfigManager: Using default configuration");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConfigManager::saveToSD() {
|
bool ConfigManager::saveToSD() {
|
||||||
if (!ensureSDCard()) {
|
if (!ensureSDCard()) {
|
||||||
LOG_ERROR("ConfigManager: Cannot save to SD - SD not available");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,7 +242,6 @@ bool ConfigManager::saveToSD() {
|
|||||||
// Device configuration now only handles firmware version (identity is in NVS)
|
// Device configuration now only handles firmware version (identity is in NVS)
|
||||||
bool ConfigManager::saveDeviceConfig() {
|
bool ConfigManager::saveDeviceConfig() {
|
||||||
if (!ensureSDCard()) {
|
if (!ensureSDCard()) {
|
||||||
LOG_ERROR("ConfigManager: Cannot save device config - SD not available");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,12 +252,12 @@ bool ConfigManager::saveDeviceConfig() {
|
|||||||
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
||||||
|
|
||||||
if (len == 0 || len >= sizeof(buffer)) {
|
if (len == 0 || len >= sizeof(buffer)) {
|
||||||
LOG_ERROR("ConfigManager: Failed to serialize device config JSON");
|
LOG_ERROR("ConfigManager - ❌ Failed to serialize device config JSON");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveFileToSD("/settings", "deviceConfig.json", buffer);
|
saveFileToSD("/settings", "deviceConfig.json", buffer);
|
||||||
LOG_INFO("ConfigManager: Device config saved - FwVer: %s", deviceConfig.fwVersion.c_str());
|
LOG_DEBUG("ConfigManager - Device config saved - FwVer: %s", deviceConfig.fwVersion.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +266,7 @@ bool ConfigManager::loadDeviceConfig() {
|
|||||||
|
|
||||||
File file = SD.open("/settings/deviceConfig.json", FILE_READ);
|
File file = SD.open("/settings/deviceConfig.json", FILE_READ);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
LOG_WARNING("ConfigManager: Device config file not found - using firmware version default");
|
LOG_WARNING("ConfigManager - ⚠️ Device config file not found - using firmware version default");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,13 +275,13 @@ bool ConfigManager::loadDeviceConfig() {
|
|||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
LOG_ERROR("ConfigManager: Failed to parse device config from SD: %s", error.c_str());
|
LOG_ERROR("ConfigManager - ❌ Failed to parse device config from SD: %s", error.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc.containsKey("fwVersion")) {
|
if (doc.containsKey("fwVersion")) {
|
||||||
deviceConfig.fwVersion = doc["fwVersion"].as<String>();
|
deviceConfig.fwVersion = doc["fwVersion"].as<String>();
|
||||||
LOG_INFO("ConfigManager: Firmware version loaded from SD: %s", deviceConfig.fwVersion.c_str());
|
LOG_VERBOSE("ConfigManager - Firmware version loaded from SD: %s", deviceConfig.fwVersion.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -300,22 +289,22 @@ bool ConfigManager::loadDeviceConfig() {
|
|||||||
|
|
||||||
bool ConfigManager::isHealthy() const {
|
bool ConfigManager::isHealthy() const {
|
||||||
if (!sdInitialized) {
|
if (!sdInitialized) {
|
||||||
LOG_DEBUG("ConfigManager: Unhealthy - SD card not initialized");
|
LOG_VERBOSE("ConfigManager - ⚠️ Unhealthy - SD card not initialized");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deviceConfig.deviceUID.isEmpty()) {
|
if (deviceConfig.deviceUID.isEmpty()) {
|
||||||
LOG_DEBUG("ConfigManager: Unhealthy - Device UID not set (factory configuration required)");
|
LOG_VERBOSE("ConfigManager - ⚠️ Unhealthy - Device UID not set (factory configuration required)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deviceConfig.hwType.isEmpty()) {
|
if (deviceConfig.hwType.isEmpty()) {
|
||||||
LOG_DEBUG("ConfigManager: Unhealthy - Hardware type not set (factory configuration required)");
|
LOG_VERBOSE("ConfigManager - ⚠️ Unhealthy - Hardware type not set (factory configuration required)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (networkConfig.hostname.isEmpty()) {
|
if (networkConfig.hostname.isEmpty()) {
|
||||||
LOG_DEBUG("ConfigManager: Unhealthy - Hostname not generated (initialization issue)");
|
LOG_VERBOSE("ConfigManager - ⚠️ Unhealthy - Hostname not generated (initialization issue)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,13 +316,12 @@ bool ConfigManager::isHealthy() const {
|
|||||||
// Bell configuration methods remain unchanged...
|
// Bell configuration methods remain unchanged...
|
||||||
bool ConfigManager::loadBellDurations() {
|
bool ConfigManager::loadBellDurations() {
|
||||||
if (!ensureSDCard()) {
|
if (!ensureSDCard()) {
|
||||||
LOG_ERROR("ConfigManager: SD Card not initialized. Using default bell durations.");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
File file = SD.open("/settings/relayTimings.json", FILE_READ);
|
File file = SD.open("/settings/relayTimings.json", FILE_READ);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
LOG_WARNING("ConfigManager: Settings file not found on SD. Using default bell durations.");
|
LOG_WARNING("ConfigManager - ⚠️ Settings file not found on SD. Using default bell durations.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +330,7 @@ bool ConfigManager::loadBellDurations() {
|
|||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
LOG_ERROR("ConfigManager: Failed to parse settings from SD. Using default bell durations.");
|
LOG_ERROR("ConfigManager - ❌ Failed to parse settings from SD. Using default bell durations.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,7 +341,7 @@ bool ConfigManager::loadBellDurations() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("ConfigManager: Bell durations loaded from SD");
|
LOG_DEBUG("ConfigManager - Bell durations loaded from SD");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,24 +358,23 @@ bool ConfigManager::saveBellDurations() {
|
|||||||
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
||||||
|
|
||||||
if (len == 0 || len >= sizeof(buffer)) {
|
if (len == 0 || len >= sizeof(buffer)) {
|
||||||
LOG_ERROR("ConfigManager: Failed to serialize bell durations JSON");
|
LOG_ERROR("ConfigManager - ❌ Failed to serialize bell durations JSON");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveFileToSD("/settings", "relayTimings.json", buffer);
|
saveFileToSD("/settings", "relayTimings.json", buffer);
|
||||||
LOG_INFO("ConfigManager: Bell durations saved to SD");
|
LOG_DEBUG("ConfigManager - Bell durations saved to SD");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigManager::loadBellOutputs() {
|
bool ConfigManager::loadBellOutputs() {
|
||||||
if (!ensureSDCard()) {
|
if (!ensureSDCard()) {
|
||||||
LOG_ERROR("ConfigManager: SD Card not initialized. Using default bell outputs (1:1 mapping).");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
File file = SD.open("/settings/bellOutputs.json", FILE_READ);
|
File file = SD.open("/settings/bellOutputs.json", FILE_READ);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
LOG_WARNING("ConfigManager: Bell outputs file not found on SD. Using default 1:1 mapping.");
|
LOG_WARNING("ConfigManager - ⚠️ Bell outputs file not found on SD. Using default 1:1 mapping.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,7 +383,7 @@ bool ConfigManager::loadBellOutputs() {
|
|||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
LOG_ERROR("ConfigManager: Failed to parse bell outputs from SD. Using defaults.");
|
LOG_ERROR("ConfigManager - ❌ Failed to parse bell outputs from SD. Using defaults.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,7 +394,7 @@ bool ConfigManager::loadBellOutputs() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("ConfigManager: Bell outputs loaded from SD");
|
LOG_DEBUG("ConfigManager - Bell outputs loaded from SD");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,12 +411,12 @@ bool ConfigManager::saveBellOutputs() {
|
|||||||
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
||||||
|
|
||||||
if (len == 0 || len >= sizeof(buffer)) {
|
if (len == 0 || len >= sizeof(buffer)) {
|
||||||
LOG_ERROR("ConfigManager: Failed to serialize bell outputs JSON");
|
LOG_ERROR("ConfigManager - ❌ Failed to serialize bell outputs JSON");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveFileToSD("/settings", "bellOutputs.json", buffer);
|
saveFileToSD("/settings", "bellOutputs.json", buffer);
|
||||||
LOG_INFO("ConfigManager: Bell outputs saved to SD");
|
LOG_DEBUG("ConfigManager - Bell outputs saved to SD");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,7 +427,7 @@ void ConfigManager::updateBellDurations(JsonVariant doc) {
|
|||||||
bellConfig.durations[i] = doc[key].as<uint16_t>();
|
bellConfig.durations[i] = doc[key].as<uint16_t>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_INFO("ConfigManager: Updated bell durations");
|
LOG_DEBUG("ConfigManager - Updated bell durations");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigManager::updateBellOutputs(JsonVariant doc) {
|
void ConfigManager::updateBellOutputs(JsonVariant doc) {
|
||||||
@@ -448,10 +435,10 @@ void ConfigManager::updateBellOutputs(JsonVariant doc) {
|
|||||||
String key = String("b") + (i + 1);
|
String key = String("b") + (i + 1);
|
||||||
if (doc.containsKey(key)) {
|
if (doc.containsKey(key)) {
|
||||||
bellConfig.outputs[i] = doc[key].as<uint16_t>() - 1;
|
bellConfig.outputs[i] = doc[key].as<uint16_t>() - 1;
|
||||||
LOG_VERBOSE("ConfigManager: Bell %d output set to %d", i + 1, bellConfig.outputs[i]);
|
LOG_VERBOSE("ConfigManager - Bell %d output set to %d", i + 1, bellConfig.outputs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_INFO("ConfigManager: Updated bell outputs");
|
LOG_DEBUG("ConfigManager - Updated bell outputs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -482,7 +469,6 @@ void ConfigManager::setBellOutput(uint8_t bellIndex, uint16_t output) {
|
|||||||
|
|
||||||
void ConfigManager::saveFileToSD(const char* dirPath, const char* filename, const char* data) {
|
void ConfigManager::saveFileToSD(const char* dirPath, const char* filename, const char* data) {
|
||||||
if (!ensureSDCard()) {
|
if (!ensureSDCard()) {
|
||||||
LOG_ERROR("ConfigManager: SD Card not initialized!");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,13 +482,13 @@ void ConfigManager::saveFileToSD(const char* dirPath, const char* filename, cons
|
|||||||
|
|
||||||
File file = SD.open(fullPath.c_str(), FILE_WRITE);
|
File file = SD.open(fullPath.c_str(), FILE_WRITE);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
LOG_ERROR("ConfigManager: Failed to open file: %s", fullPath.c_str());
|
LOG_ERROR("ConfigManager - ❌ Failed to open file: %s", fullPath.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
file.print(data);
|
file.print(data);
|
||||||
file.close();
|
file.close();
|
||||||
LOG_INFO("ConfigManager: File %s saved successfully", fullPath.c_str());
|
LOG_VERBOSE("ConfigManager - File %s saved successfully", fullPath.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clock configuration methods and other remaining methods follow the same pattern...
|
// Clock configuration methods and other remaining methods follow the same pattern...
|
||||||
@@ -525,7 +511,7 @@ void ConfigManager::updateClockOutputs(JsonVariant doc) {
|
|||||||
if (doc.containsKey("pauseDuration")) {
|
if (doc.containsKey("pauseDuration")) {
|
||||||
clockConfig.pauseDuration = doc["pauseDuration"].as<uint16_t>();
|
clockConfig.pauseDuration = doc["pauseDuration"].as<uint16_t>();
|
||||||
}
|
}
|
||||||
LOG_INFO("ConfigManager: Updated Clock outputs to: C1: %d / C2: %d, Pulse: %dms, Pause: %dms",
|
LOG_DEBUG("ConfigManager - Updated Clock outputs to: C1: %d / C2: %d, Pulse: %dms, Pause: %dms",
|
||||||
clockConfig.c1output, clockConfig.c2output, clockConfig.pulseDuration, clockConfig.pauseDuration);
|
clockConfig.c1output, clockConfig.c2output, clockConfig.pulseDuration, clockConfig.pauseDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,7 +531,7 @@ void ConfigManager::updateClockAlerts(JsonVariant doc) {
|
|||||||
if (doc.containsKey("quarterBell")) {
|
if (doc.containsKey("quarterBell")) {
|
||||||
clockConfig.quarterBell = doc["quarterBell"].as<uint8_t>();
|
clockConfig.quarterBell = doc["quarterBell"].as<uint8_t>();
|
||||||
}
|
}
|
||||||
LOG_INFO("ConfigManager: Updated Clock alerts");
|
LOG_DEBUG("ConfigManager - Updated Clock alerts");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigManager::updateClockBacklight(JsonVariant doc) {
|
void ConfigManager::updateClockBacklight(JsonVariant doc) {
|
||||||
@@ -561,7 +547,7 @@ void ConfigManager::updateClockBacklight(JsonVariant doc) {
|
|||||||
if (doc.containsKey("offTime")) {
|
if (doc.containsKey("offTime")) {
|
||||||
clockConfig.backlightOffTime = doc["offTime"].as<String>();
|
clockConfig.backlightOffTime = doc["offTime"].as<String>();
|
||||||
}
|
}
|
||||||
LOG_INFO("ConfigManager: Updated Clock backlight");
|
LOG_DEBUG("ConfigManager - Updated Clock backlight");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigManager::updateClockSilence(JsonVariant doc) {
|
void ConfigManager::updateClockSilence(JsonVariant doc) {
|
||||||
@@ -589,7 +575,7 @@ void ConfigManager::updateClockSilence(JsonVariant doc) {
|
|||||||
clockConfig.nighttimeSilenceOffTime = nighttime["offTime"].as<String>();
|
clockConfig.nighttimeSilenceOffTime = nighttime["offTime"].as<String>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_INFO("ConfigManager: Updated Clock silence");
|
LOG_DEBUG("ConfigManager - Updated Clock silence");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigManager::loadClockConfig() {
|
bool ConfigManager::loadClockConfig() {
|
||||||
@@ -597,7 +583,7 @@ bool ConfigManager::loadClockConfig() {
|
|||||||
|
|
||||||
File file = SD.open("/settings/clockConfig.json", FILE_READ);
|
File file = SD.open("/settings/clockConfig.json", FILE_READ);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
LOG_WARNING("ConfigManager: Clock config file not found - using defaults");
|
LOG_WARNING("ConfigManager - ⚠️ Clock config file not found - using defaults");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -606,7 +592,7 @@ bool ConfigManager::loadClockConfig() {
|
|||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
LOG_ERROR("ConfigManager: Failed to parse clock config from SD: %s", error.c_str());
|
LOG_ERROR("ConfigManager - ❌ Failed to parse clock config from SD: %s", error.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -615,7 +601,7 @@ bool ConfigManager::loadClockConfig() {
|
|||||||
if (doc.containsKey("pulseDuration")) clockConfig.pulseDuration = doc["pulseDuration"].as<uint16_t>();
|
if (doc.containsKey("pulseDuration")) clockConfig.pulseDuration = doc["pulseDuration"].as<uint16_t>();
|
||||||
if (doc.containsKey("pauseDuration")) clockConfig.pauseDuration = doc["pauseDuration"].as<uint16_t>();
|
if (doc.containsKey("pauseDuration")) clockConfig.pauseDuration = doc["pauseDuration"].as<uint16_t>();
|
||||||
|
|
||||||
LOG_INFO("ConfigManager: Clock config loaded");
|
LOG_DEBUG("ConfigManager - Clock config loaded");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -632,12 +618,12 @@ bool ConfigManager::saveClockConfig() {
|
|||||||
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
||||||
|
|
||||||
if (len == 0 || len >= sizeof(buffer)) {
|
if (len == 0 || len >= sizeof(buffer)) {
|
||||||
LOG_ERROR("ConfigManager: Failed to serialize clock config JSON");
|
LOG_ERROR("ConfigManager - ❌ Failed to serialize clock config JSON");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveFileToSD("/settings", "clockConfig.json", buffer);
|
saveFileToSD("/settings", "clockConfig.json", buffer);
|
||||||
LOG_INFO("ConfigManager: Clock config saved");
|
LOG_DEBUG("ConfigManager - Clock config saved");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,7 +632,7 @@ bool ConfigManager::loadClockState() {
|
|||||||
|
|
||||||
File file = SD.open("/settings/clockState.json", FILE_READ);
|
File file = SD.open("/settings/clockState.json", FILE_READ);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
LOG_WARNING("ConfigManager: Clock state file not found - using defaults");
|
LOG_WARNING("ConfigManager - ⚠️ Clock state file not found - using defaults");
|
||||||
clockConfig.physicalHour = 0;
|
clockConfig.physicalHour = 0;
|
||||||
clockConfig.physicalMinute = 0;
|
clockConfig.physicalMinute = 0;
|
||||||
clockConfig.nextOutputIsC1 = true;
|
clockConfig.nextOutputIsC1 = true;
|
||||||
@@ -659,7 +645,7 @@ bool ConfigManager::loadClockState() {
|
|||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
LOG_ERROR("ConfigManager: Failed to parse clock state from SD: %s", error.c_str());
|
LOG_ERROR("ConfigManager - ❌ Failed to parse clock state from SD: %s", error.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,7 +654,7 @@ bool ConfigManager::loadClockState() {
|
|||||||
clockConfig.nextOutputIsC1 = doc["nextIsC1"].as<bool>();
|
clockConfig.nextOutputIsC1 = doc["nextIsC1"].as<bool>();
|
||||||
clockConfig.lastSyncTime = doc["lastSyncTime"].as<uint32_t>();
|
clockConfig.lastSyncTime = doc["lastSyncTime"].as<uint32_t>();
|
||||||
|
|
||||||
LOG_INFO("ConfigManager: Clock state loaded");
|
LOG_DEBUG("ConfigManager - Clock state loaded");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -685,12 +671,12 @@ bool ConfigManager::saveClockState() {
|
|||||||
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
||||||
|
|
||||||
if (len == 0 || len >= sizeof(buffer)) {
|
if (len == 0 || len >= sizeof(buffer)) {
|
||||||
LOG_ERROR("ConfigManager: Failed to serialize clock state JSON");
|
LOG_ERROR("ConfigManager - ❌ Failed to serialize clock state JSON");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveFileToSD("/settings", "clockState.json", buffer);
|
saveFileToSD("/settings", "clockState.json", buffer);
|
||||||
LOG_DEBUG("ConfigManager: Clock state saved");
|
LOG_VERBOSE("ConfigManager - Clock state saved");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,7 +685,7 @@ bool ConfigManager::loadUpdateServers() {
|
|||||||
|
|
||||||
File file = SD.open("/settings/updateServers.json", FILE_READ);
|
File file = SD.open("/settings/updateServers.json", FILE_READ);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
LOG_INFO("ConfigManager: Update servers file not found - using fallback only");
|
LOG_DEBUG("ConfigManager - Update servers file not found - using fallback only");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -708,7 +694,7 @@ bool ConfigManager::loadUpdateServers() {
|
|||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
LOG_ERROR("ConfigManager: Failed to parse update servers JSON: %s", error.c_str());
|
LOG_ERROR("ConfigManager - ❌ Failed to parse update servers JSON: %s", error.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,7 +711,7 @@ bool ConfigManager::loadUpdateServers() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("ConfigManager: Loaded %d update servers from SD card", updateServers.size());
|
LOG_DEBUG("ConfigManager - Loaded %d update servers from SD card", updateServers.size());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -742,7 +728,7 @@ void ConfigManager::updateTimeConfig(long gmtOffsetSec, int daylightOffsetSec) {
|
|||||||
timeConfig.gmtOffsetSec = gmtOffsetSec;
|
timeConfig.gmtOffsetSec = gmtOffsetSec;
|
||||||
timeConfig.daylightOffsetSec = daylightOffsetSec;
|
timeConfig.daylightOffsetSec = daylightOffsetSec;
|
||||||
saveToSD();
|
saveToSD();
|
||||||
LOG_INFO("ConfigManager: TimeConfig updated - GMT offset %ld sec, DST offset %d sec",
|
LOG_DEBUG("ConfigManager - TimeConfig updated - GMT offset %ld sec, DST offset %d sec",
|
||||||
gmtOffsetSec, daylightOffsetSec);
|
gmtOffsetSec, daylightOffsetSec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,7 +742,7 @@ void ConfigManager::updateNetworkConfig(const String& hostname, bool useStaticIP
|
|||||||
networkConfig.dns1 = dns1;
|
networkConfig.dns1 = dns1;
|
||||||
networkConfig.dns2 = dns2;
|
networkConfig.dns2 = dns2;
|
||||||
saveNetworkConfig(); // Save immediately to SD
|
saveNetworkConfig(); // Save immediately to SD
|
||||||
LOG_INFO("ConfigManager: NetworkConfig updated - Hostname: %s, Static IP: %s, IP: %s",
|
LOG_DEBUG("ConfigManager - NetworkConfig updated - Hostname: %s, Static IP: %s, IP: %s",
|
||||||
hostname.c_str(), useStaticIP ? "enabled" : "disabled", ip.toString().c_str());
|
hostname.c_str(), useStaticIP ? "enabled" : "disabled", ip.toString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -769,7 +755,7 @@ bool ConfigManager::loadNetworkConfig() {
|
|||||||
|
|
||||||
File file = SD.open("/settings/networkConfig.json", FILE_READ);
|
File file = SD.open("/settings/networkConfig.json", FILE_READ);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
LOG_INFO("ConfigManager: Network config file not found - using auto-generated hostname and DHCP");
|
LOG_DEBUG("ConfigManager - Network config file not found - using auto-generated hostname and DHCP");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,7 +764,7 @@ bool ConfigManager::loadNetworkConfig() {
|
|||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
LOG_ERROR("ConfigManager: Failed to parse network config from SD: %s", error.c_str());
|
LOG_ERROR("ConfigManager - ❌ Failed to parse network config from SD: %s", error.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -787,7 +773,7 @@ bool ConfigManager::loadNetworkConfig() {
|
|||||||
String customHostname = doc["hostname"].as<String>();
|
String customHostname = doc["hostname"].as<String>();
|
||||||
if (!customHostname.isEmpty()) {
|
if (!customHostname.isEmpty()) {
|
||||||
networkConfig.hostname = customHostname;
|
networkConfig.hostname = customHostname;
|
||||||
LOG_INFO("ConfigManager: Custom hostname loaded from SD: %s", customHostname.c_str());
|
LOG_DEBUG("ConfigManager - Custom hostname loaded from SD: %s", customHostname.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -831,7 +817,7 @@ bool ConfigManager::loadNetworkConfig() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("ConfigManager: Network config loaded - Hostname: %s, Static IP: %s",
|
LOG_DEBUG("ConfigManager - Network config loaded - Hostname: %s, Static IP: %s",
|
||||||
networkConfig.hostname.c_str(),
|
networkConfig.hostname.c_str(),
|
||||||
networkConfig.useStaticIP ? "enabled" : "disabled");
|
networkConfig.useStaticIP ? "enabled" : "disabled");
|
||||||
|
|
||||||
@@ -858,12 +844,12 @@ bool ConfigManager::saveNetworkConfig() {
|
|||||||
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
||||||
|
|
||||||
if (len == 0 || len >= sizeof(buffer)) {
|
if (len == 0 || len >= sizeof(buffer)) {
|
||||||
LOG_ERROR("ConfigManager: Failed to serialize network config JSON");
|
LOG_ERROR("ConfigManager - ❌ Failed to serialize network config JSON");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveFileToSD("/settings", "networkConfig.json", buffer);
|
saveFileToSD("/settings", "networkConfig.json", buffer);
|
||||||
LOG_INFO("ConfigManager: Network config saved to SD");
|
LOG_DEBUG("ConfigManager - Network config saved to SD");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -873,12 +859,11 @@ bool ConfigManager::saveNetworkConfig() {
|
|||||||
|
|
||||||
bool ConfigManager::resetAllToDefaults() {
|
bool ConfigManager::resetAllToDefaults() {
|
||||||
|
|
||||||
LOG_WARNING("═══════════════════════════════════════════════════════════════════════════");
|
LOG_INFO("═══════════════════════════════════════════════════════════════════════════");
|
||||||
LOG_WARNING(" 🏭 RESET SETTINGS TO DEFAULTS INITIATED");
|
LOG_INFO(" 🏭 RESET SETTINGS TO DEFAULTS INITIATED");
|
||||||
LOG_WARNING("═══════════════════════════════════════════════════════════════════════════");
|
LOG_INFO("═══════════════════════════════════════════════════════════════════════════");
|
||||||
|
|
||||||
if (!ensureSDCard()) {
|
if (!ensureSDCard()) {
|
||||||
LOG_ERROR("❌ ConfigManager: Cannot perform reset - SD card not available");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -894,7 +879,7 @@ bool ConfigManager::resetAllToDefaults() {
|
|||||||
"/settings/deviceConfig.json",
|
"/settings/deviceConfig.json",
|
||||||
"/settings/networkConfig.json",
|
"/settings/networkConfig.json",
|
||||||
"/settings/relayTimings.json",
|
"/settings/relayTimings.json",
|
||||||
"/settings/bellOutputs.json", // <-- ADD THIS LINE
|
"/settings/bellOutputs.json",
|
||||||
"/settings/clockConfig.json",
|
"/settings/clockConfig.json",
|
||||||
"/settings/clockState.json",
|
"/settings/clockState.json",
|
||||||
"/settings/updateServers.json"
|
"/settings/updateServers.json"
|
||||||
@@ -902,22 +887,22 @@ bool ConfigManager::resetAllToDefaults() {
|
|||||||
|
|
||||||
int numFiles = sizeof(settingsFiles) / sizeof(settingsFiles[0]);
|
int numFiles = sizeof(settingsFiles) / sizeof(settingsFiles[0]);
|
||||||
|
|
||||||
LOG_WARNING("🗑️ Step 1: Deleting %d configuration files...", numFiles);
|
LOG_DEBUG("ConfigManager - Step 1: Deleting %d configuration files...", numFiles);
|
||||||
|
|
||||||
for (int i = 0; i < numFiles; i++) {
|
for (int i = 0; i < numFiles; i++) {
|
||||||
const char* filepath = settingsFiles[i];
|
const char* filepath = settingsFiles[i];
|
||||||
|
|
||||||
if (SD.exists(filepath)) {
|
if (SD.exists(filepath)) {
|
||||||
if (SD.remove(filepath)) {
|
if (SD.remove(filepath)) {
|
||||||
LOG_DEBUG("✅ Deleted: %s", filepath);
|
LOG_VERBOSE("ConfigManager - ✅ Deleted: %s", filepath);
|
||||||
filesDeleted++;
|
filesDeleted++;
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("❌ Failed to delete: %s", filepath);
|
LOG_ERROR("ConfigManager - ❌ Failed to delete: %s", filepath);
|
||||||
filesFailed++;
|
filesFailed++;
|
||||||
allDeleted = false;
|
allDeleted = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("⏩ Skip (not found): %s", filepath);
|
LOG_VERBOSE("ConfigManager - Skip (not found): %s", filepath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -926,7 +911,7 @@ bool ConfigManager::resetAllToDefaults() {
|
|||||||
// ════════════════════════════════════════════════════════════════════════════
|
// ════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
if (SD.exists("/melodies")) {
|
if (SD.exists("/melodies")) {
|
||||||
LOG_WARNING("🗑️ Step 2: Deleting melody files...");
|
LOG_DEBUG("ConfigManager - Step 2: Deleting melody files...");
|
||||||
|
|
||||||
File melodiesDir = SD.open("/melodies");
|
File melodiesDir = SD.open("/melodies");
|
||||||
if (melodiesDir && melodiesDir.isDirectory()) {
|
if (melodiesDir && melodiesDir.isDirectory()) {
|
||||||
@@ -939,10 +924,10 @@ bool ConfigManager::resetAllToDefaults() {
|
|||||||
|
|
||||||
if (!entry.isDirectory()) {
|
if (!entry.isDirectory()) {
|
||||||
if (SD.remove(entryPath.c_str())) {
|
if (SD.remove(entryPath.c_str())) {
|
||||||
LOG_DEBUG("✅ Deleted melody: %s", entryPath.c_str());
|
LOG_VERBOSE("ConfigManager - ✅ Deleted melody: %s", entryPath.c_str());
|
||||||
melodiesDeleted++;
|
melodiesDeleted++;
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("❌ Failed to delete melody: %s", entryPath.c_str());
|
LOG_ERROR("ConfigManager - ❌ Failed to delete melody: %s", entryPath.c_str());
|
||||||
melodiesFailed++;
|
melodiesFailed++;
|
||||||
allDeleted = false;
|
allDeleted = false;
|
||||||
}
|
}
|
||||||
@@ -956,33 +941,33 @@ bool ConfigManager::resetAllToDefaults() {
|
|||||||
|
|
||||||
// Try to remove the empty directory
|
// Try to remove the empty directory
|
||||||
if (SD.rmdir("/melodies")) {
|
if (SD.rmdir("/melodies")) {
|
||||||
LOG_DEBUG("✅ Deleted /melodies directory");
|
LOG_VERBOSE("ConfigManager - ✅ Deleted /melodies directory");
|
||||||
} else {
|
} else {
|
||||||
LOG_WARNING("⚠️ Could not delete /melodies directory (may not be empty)");
|
LOG_WARNING("ConfigManager - ⚠️ Could not delete /melodies directory (may not be empty)");
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_WARNING(" 🎵 Melodies deleted: %d, failed: %d", melodiesDeleted, melodiesFailed);
|
LOG_DEBUG("ConfigManager - Melodies deleted: %d, failed: %d", melodiesDeleted, melodiesFailed);
|
||||||
filesDeleted += melodiesDeleted;
|
filesDeleted += melodiesDeleted;
|
||||||
filesFailed += melodiesFailed;
|
filesFailed += melodiesFailed;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("⏩ /melodies directory not found");
|
LOG_VERBOSE("ConfigManager - /melodies directory not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ════════════════════════════════════════════════════════════════════════════
|
// ════════════════════════════════════════════════════════════════════════════
|
||||||
// SUMMARY
|
// SUMMARY
|
||||||
// ════════════════════════════════════════════════════════════════════════════
|
// ════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
LOG_WARNING("═══════════════════════════════════════════════════════════════════════════");
|
LOG_INFO("═══════════════════════════════════════════════════════════════════════════");
|
||||||
LOG_WARNING("📄 Full reset summary:");
|
LOG_INFO("ConfigManager - Full reset summary:");
|
||||||
LOG_WARNING(" ✅ Files deleted: %d", filesDeleted);
|
LOG_INFO("ConfigManager - ✅ Files deleted: %d", filesDeleted);
|
||||||
LOG_WARNING(" ❌ Files failed: %d", filesFailed);
|
LOG_INFO("ConfigManager - ❌ Files failed: %d", filesFailed);
|
||||||
LOG_WARNING(" 🔄 Total processed: %d", filesDeleted + filesFailed);
|
LOG_INFO("ConfigManager - 🔄 Total processed: %d", filesDeleted + filesFailed);
|
||||||
LOG_WARNING("═══════════════════════════════════════════════════════════════════════════");
|
LOG_INFO("═══════════════════════════════════════════════════════════════════════════");
|
||||||
|
|
||||||
LOG_WARNING("✅ RESET TO DEFAULT COMPLETE");
|
LOG_INFO("ConfigManager - ✅ RESET TO DEFAULT COMPLETE");
|
||||||
LOG_WARNING("🔄 Device will boot with default settings on next restart");
|
LOG_INFO("ConfigManager - 🔄 Device will boot with default settings on next restart");
|
||||||
LOG_WARNING("🆔 Device identity (UID) preserved");
|
LOG_INFO("ConfigManager - 🆔 Device identity (UID) preserved");
|
||||||
|
|
||||||
return allDeleted;
|
return allDeleted;
|
||||||
}
|
}
|
||||||
@@ -1078,21 +1063,21 @@ String ConfigManager::getAllSettingsAsJson() const {
|
|||||||
|
|
||||||
bool ConfigManager::setSerialLogLevel(uint8_t level) {
|
bool ConfigManager::setSerialLogLevel(uint8_t level) {
|
||||||
if (level > 5) { // Max level is VERBOSE (5)
|
if (level > 5) { // Max level is VERBOSE (5)
|
||||||
LOG_WARNING("ConfigManager: Invalid serial log level %d, valid range is 0-5", level);
|
LOG_WARNING("ConfigManager - ⚠️ Invalid serial log level %d, valid range is 0-5", level);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
generalConfig.serialLogLevel = level;
|
generalConfig.serialLogLevel = level;
|
||||||
LOG_INFO("ConfigManager: Serial log level set to %d", level);
|
LOG_DEBUG("ConfigManager - Serial log level set to %d", level);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigManager::setSdLogLevel(uint8_t level) {
|
bool ConfigManager::setSdLogLevel(uint8_t level) {
|
||||||
if (level > 5) { // Max level is VERBOSE (5)
|
if (level > 5) { // Max level is VERBOSE (5)
|
||||||
LOG_WARNING("ConfigManager: Invalid SD log level %d, valid range is 0-5", level);
|
LOG_WARNING("ConfigManager - ⚠️ Invalid SD log level %d, valid range is 0-5", level);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
generalConfig.sdLogLevel = level;
|
generalConfig.sdLogLevel = level;
|
||||||
LOG_INFO("ConfigManager: SD log level set to %d", level);
|
LOG_DEBUG("ConfigManager - SD log level set to %d", level);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1101,7 +1086,7 @@ bool ConfigManager::loadGeneralConfig() {
|
|||||||
|
|
||||||
File file = SD.open("/settings/generalConfig.json", FILE_READ);
|
File file = SD.open("/settings/generalConfig.json", FILE_READ);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
LOG_WARNING("ConfigManager: General config file not found - using defaults");
|
LOG_WARNING("ConfigManager - ⚠️ General config file not found - using defaults");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1110,7 +1095,7 @@ bool ConfigManager::loadGeneralConfig() {
|
|||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
LOG_ERROR("ConfigManager: Failed to parse general config from SD: %s", error.c_str());
|
LOG_ERROR("ConfigManager - ❌ Failed to parse general config from SD: %s", error.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1121,7 +1106,7 @@ bool ConfigManager::loadGeneralConfig() {
|
|||||||
generalConfig.sdLogLevel = doc["sdLogLevel"].as<uint8_t>();
|
generalConfig.sdLogLevel = doc["sdLogLevel"].as<uint8_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("ConfigManager: General config loaded - Serial log level: %d, SD log level: %d",
|
LOG_DEBUG("ConfigManager - General config loaded - Serial log level: %d, SD log level: %d",
|
||||||
generalConfig.serialLogLevel, generalConfig.sdLogLevel);
|
generalConfig.serialLogLevel, generalConfig.sdLogLevel);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1137,11 +1122,11 @@ bool ConfigManager::saveGeneralConfig() {
|
|||||||
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
||||||
|
|
||||||
if (len == 0 || len >= sizeof(buffer)) {
|
if (len == 0 || len >= sizeof(buffer)) {
|
||||||
LOG_ERROR("ConfigManager: Failed to serialize general config JSON");
|
LOG_ERROR("ConfigManager - ❌ Failed to serialize general config JSON");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveFileToSD("/settings", "generalConfig.json", buffer);
|
saveFileToSD("/settings", "generalConfig.json", buffer);
|
||||||
LOG_INFO("ConfigManager: General config saved");
|
LOG_DEBUG("ConfigManager - General config saved");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -287,7 +287,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool begin();
|
bool begin();
|
||||||
|
|
||||||
void loadFromSD();
|
|
||||||
bool saveToSD();
|
bool saveToSD();
|
||||||
|
|
||||||
// Configuration access (read-only getters)
|
// Configuration access (read-only getters)
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ void Telemetry::telemetryTask(void* parameter) {
|
|||||||
if (isPlaying || telemetry->coolingActive) {
|
if (isPlaying || telemetry->coolingActive) {
|
||||||
telemetry->checkBellLoads();
|
telemetry->checkBellLoads();
|
||||||
}
|
}
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000)); // Run every 1s
|
vTaskDelay(pdMS_TO_TICKS(1000)); // Run every 1s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user