feat: Add per-subsystem log tags to all firmware modules
Refactored logging system to require a TAG as first argument on all LOG_* macros, enabling per-subsystem log filtering and cleaner output. Each subsystem now defines its own TAG (e.g. "BellEngine", "Player"). Also overhauled Logging.hpp/cpp with improved level control and output. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,8 @@
|
||||
// DEPENDENCY INCLUDES - Required system components
|
||||
// ═════════════════════════════════════════════════════════════════════════════════
|
||||
#include "BellEngine.hpp" // Header file with class definition
|
||||
|
||||
#define TAG "BellEngine"
|
||||
#include "../Player/Player.hpp" // Melody playback controller
|
||||
#include "../ConfigManager/ConfigManager.hpp" // Configuration and settings
|
||||
#include "../Telemetry/Telemetry.hpp" // System monitoring and analytics
|
||||
@@ -74,7 +76,7 @@ BellEngine::~BellEngine() {
|
||||
*
|
||||
*/
|
||||
void BellEngine::begin() {
|
||||
LOG_DEBUG("Initializing BellEngine...");
|
||||
LOG_DEBUG(TAG, "Initializing BellEngine...");
|
||||
|
||||
// Create engine task with HIGHEST priority on dedicated Core 1
|
||||
// This ensures maximum performance and timing precision
|
||||
@@ -88,7 +90,7 @@ void BellEngine::begin() {
|
||||
1 // 💻 Pin to Core 1 (dedicated)
|
||||
);
|
||||
|
||||
LOG_INFO("BellEngine initialized !");
|
||||
LOG_INFO(TAG, "BellEngine initialized !");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,7 +98,7 @@ void BellEngine::begin() {
|
||||
*/
|
||||
void BellEngine::setCommunicationManager(CommunicationRouter* commManager) {
|
||||
_communicationManager = commManager;
|
||||
LOG_DEBUG("BellEngine: Communication manager %s",
|
||||
LOG_DEBUG(TAG, "BellEngine: Communication manager %s",
|
||||
commManager ? "connected" : "disconnected");
|
||||
}
|
||||
|
||||
@@ -116,22 +118,22 @@ void BellEngine::setCommunicationManager(CommunicationRouter* commManager) {
|
||||
void BellEngine::start() {
|
||||
// Validate that melody data is ready before starting
|
||||
if (!_melodyDataReady.load()) {
|
||||
LOG_ERROR("Cannot start BellEngine: No melody data loaded");
|
||||
LOG_ERROR(TAG, "Cannot start BellEngine: No melody data loaded");
|
||||
return; // ⛔ Early exit if no melody data
|
||||
}
|
||||
|
||||
LOG_INFO("🚀 BellEngine Ignition - Starting precision playback");
|
||||
LOG_INFO(TAG, "🚀 BellEngine Ignition - Starting precision playback");
|
||||
_emergencyStop.store(false); // ✅ Clear any emergency stop state
|
||||
_engineRunning.store(true); // ✅ Activate the engine atomically
|
||||
}
|
||||
|
||||
void BellEngine::stop() {
|
||||
LOG_INFO("BellEngine - Stopping Gracefully");
|
||||
LOG_INFO(TAG, "BellEngine - Stopping Gracefully");
|
||||
_engineRunning.store(false);
|
||||
}
|
||||
|
||||
void BellEngine::emergencyStop() {
|
||||
LOG_INFO("BellEngine - 🛑 Forcing Stop Immediately");
|
||||
LOG_INFO(TAG, "BellEngine - 🛑 Forcing Stop Immediately");
|
||||
_emergencyStop.store(true);
|
||||
_engineRunning.store(false);
|
||||
emergencyShutdown();
|
||||
@@ -142,7 +144,7 @@ void BellEngine::setMelodyData(const std::vector<uint16_t>& melodySteps) {
|
||||
_melodySteps = melodySteps;
|
||||
_melodyDataReady.store(true);
|
||||
portEXIT_CRITICAL(&_melodyMutex);
|
||||
LOG_DEBUG("BellEngine - Loaded melody: %d steps", melodySteps.size());
|
||||
LOG_DEBUG(TAG, "BellEngine - Loaded melody: %d steps", melodySteps.size());
|
||||
}
|
||||
|
||||
void BellEngine::clearMelodyData() {
|
||||
@@ -150,7 +152,7 @@ void BellEngine::clearMelodyData() {
|
||||
_melodySteps.clear();
|
||||
_melodyDataReady.store(false);
|
||||
portEXIT_CRITICAL(&_melodyMutex);
|
||||
LOG_DEBUG("BellEngine - Melody data cleared");
|
||||
LOG_DEBUG(TAG, "BellEngine - Melody data cleared");
|
||||
}
|
||||
|
||||
// ================== CRITICAL TIMING SECTION ==================
|
||||
@@ -158,7 +160,7 @@ void BellEngine::clearMelodyData() {
|
||||
|
||||
void BellEngine::engineTask(void* parameter) {
|
||||
BellEngine* engine = static_cast<BellEngine*>(parameter);
|
||||
LOG_DEBUG("BellEngine - 🔥 Engine task started on Core %d with MAXIMUM priority", xPortGetCoreID());
|
||||
LOG_DEBUG(TAG, "BellEngine - 🔥 Engine task started on Core %d with MAXIMUM priority", xPortGetCoreID());
|
||||
|
||||
while (true) {
|
||||
if (engine->_engineRunning.load() && !engine->_emergencyStop.load()) {
|
||||
@@ -186,7 +188,7 @@ void BellEngine::engineLoop() {
|
||||
|
||||
// Pause handling AFTER complete loop - never interrupt mid-melody!
|
||||
while (_player.isPaused && _player.isPlaying && !_player.hardStop) {
|
||||
LOG_VERBOSE("BellEngine - ⏸️ Pausing between melody loops");
|
||||
LOG_VERBOSE(TAG, "BellEngine - ⏸️ Pausing between melody loops");
|
||||
vTaskDelay(pdMS_TO_TICKS(10)); // Wait during pause
|
||||
}
|
||||
|
||||
@@ -207,17 +209,17 @@ void BellEngine::playbackLoop() {
|
||||
portEXIT_CRITICAL(&_melodyMutex);
|
||||
|
||||
if (melodySteps.empty()) {
|
||||
LOG_ERROR("BellEngine - ❌ Empty melody in playback loop!");
|
||||
LOG_ERROR(TAG, "BellEngine - ❌ Empty melody in playback loop!");
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_DEBUG("BellEngine - 🎵 Starting melody loop (%d steps)", melodySteps.size());
|
||||
LOG_DEBUG(TAG, "BellEngine - 🎵 Starting melody loop (%d steps)", melodySteps.size());
|
||||
|
||||
// CRITICAL TIMING LOOP - Complete the entire melody without interruption
|
||||
for (uint16_t note : melodySteps) {
|
||||
// Emergency exit check (only emergency stops can interrupt mid-loop)
|
||||
if (_emergencyStop.load() || _player.hardStop) {
|
||||
LOG_DEBUG("BellEngine - Emergency exit from playback loop");
|
||||
LOG_DEBUG(TAG, "BellEngine - Emergency exit from playback loop");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -227,7 +229,7 @@ void BellEngine::playbackLoop() {
|
||||
// Precise timing delay - validate speed to prevent division by zero
|
||||
// I THINK this should be moved outside the Bell Engine
|
||||
if (_player.speed == 0) {
|
||||
LOG_ERROR("BellEngine - ❌ Invalid Speed (0) detected, stopping playback");
|
||||
LOG_ERROR(TAG, "BellEngine - ❌ Invalid Speed (0) detected, stopping playback");
|
||||
_player.hardStop = true;
|
||||
_engineRunning.store(false);
|
||||
return;
|
||||
@@ -242,9 +244,9 @@ void BellEngine::playbackLoop() {
|
||||
_player.onMelodyLoopCompleted(); // 🔥 Notify Player that melody actually finished!
|
||||
if ((_player.continuous_loop && _player.segment_duration == 0) || _player.total_duration == 0) {
|
||||
vTaskDelay(pdMS_TO_TICKS(500)); //Give Player time to pause/stop
|
||||
LOG_VERBOSE("BellEngine - Loop completed in SINGLE Mode - waiting for Player to handle pause/stop");
|
||||
LOG_VERBOSE(TAG, "BellEngine - Loop completed in SINGLE Mode - waiting for Player to handle pause/stop");
|
||||
}
|
||||
LOG_DEBUG("BellEngine - 🎵 Melody loop completed with PRECISION");
|
||||
LOG_DEBUG(TAG, "BellEngine - 🎵 Melody loop completed with PRECISION");
|
||||
|
||||
}
|
||||
|
||||
@@ -268,26 +270,26 @@ void BellEngine::activateNote(uint16_t note) {
|
||||
|
||||
// Additional safety check to prevent underflow crashes
|
||||
if (bellIndex >= 255) {
|
||||
LOG_ERROR("BellEngine - 🚨 UNDERFLOW ERROR: bellIndex underflow for noteIndex %d", noteIndex);
|
||||
LOG_ERROR(TAG, "BellEngine - 🚨 UNDERFLOW ERROR: bellIndex underflow for noteIndex %d", noteIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Bounds check (CRITICAL SAFETY)
|
||||
if (bellIndex >= 16) {
|
||||
LOG_ERROR("BellEngine - 🚨 BOUNDS ERROR: bellIndex %d >= 16", bellIndex);
|
||||
LOG_ERROR(TAG, "BellEngine - 🚨 BOUNDS ERROR: bellIndex %d >= 16", bellIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for duplicate bell firing in this note
|
||||
if (bellFired[bellIndex]) {
|
||||
LOG_DEBUG("BellEngine - ⚠️ DUPLICATE BELL: Skipping duplicate firing of bell %d for note %d", bellIndex, noteIndex);
|
||||
LOG_DEBUG(TAG, "BellEngine - ⚠️ DUPLICATE BELL: Skipping duplicate firing of bell %d for note %d", bellIndex, noteIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if bell is configured (OutputManager will validate this)
|
||||
uint8_t physicalOutput = _outputManager.getPhysicalOutput(bellIndex);
|
||||
if (physicalOutput == 255) {
|
||||
LOG_DEBUG("BellEngine - ⚠️ UNCONFIGURED: Bell %d not configured, skipping", bellIndex);
|
||||
LOG_DEBUG(TAG, "BellEngine - ⚠️ UNCONFIGURED: Bell %d not configured, skipping", bellIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -306,14 +308,14 @@ void BellEngine::activateNote(uint16_t note) {
|
||||
// Record telemetry
|
||||
_telemetry.recordBellStrike(bellIndex);
|
||||
|
||||
LOG_VERBOSE("BellEngine - 🔨 STRIKE! Note:%d → Bell:%d for %dms", noteIndex, bellIndex, durationMs);
|
||||
LOG_VERBOSE(TAG, "BellEngine - 🔨 STRIKE! Note:%d → Bell:%d for %dms", noteIndex, bellIndex, durationMs);
|
||||
}
|
||||
}
|
||||
|
||||
// 🚀 FIRE ALL BELLS SIMULTANEOUSLY!
|
||||
if (!bellDurations.empty()) {
|
||||
_outputManager.fireOutputsBatchForDuration(bellDurations);
|
||||
LOG_VERBOSE("BellEngine - 🔥 Batch Fired %d bells Simultaneously !", bellDurations.size());
|
||||
LOG_VERBOSE(TAG, "BellEngine - 🔥 Batch Fired %d bells Simultaneously !", bellDurations.size());
|
||||
|
||||
// 🔔 NOTIFY WEBSOCKET CLIENTS OF BELL DINGS!
|
||||
// * deactivated currently, since unstable and causes performance issues *
|
||||
@@ -339,7 +341,7 @@ void BellEngine::preciseDelay(uint32_t microseconds) {
|
||||
}
|
||||
|
||||
void BellEngine::emergencyShutdown() {
|
||||
LOG_INFO("BellEngine - 🚨 Emergency Shutdown - Notifying OutputManager");
|
||||
LOG_INFO(TAG, "BellEngine - 🚨 Emergency Shutdown - Notifying OutputManager");
|
||||
_outputManager.emergencyShutdown();
|
||||
}
|
||||
|
||||
@@ -364,10 +366,10 @@ void BellEngine::notifyBellsFired(const std::vector<uint8_t>& bellIndices) {
|
||||
// Send notification to WebSocket clients only (not MQTT)
|
||||
_communicationManager->broadcastToAllWebSocketClients(dingMsg);
|
||||
|
||||
LOG_DEBUG("BellEngine - 🔔 DING notification sent for %d bells", bellIndices.size());
|
||||
LOG_DEBUG(TAG, "BellEngine - 🔔 DING notification sent for %d bells", bellIndices.size());
|
||||
|
||||
} catch (...) {
|
||||
LOG_WARNING("BellEngine - ❌ Failed to send ding notification");
|
||||
LOG_WARNING(TAG, "BellEngine - ❌ Failed to send ding notification");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,20 +380,20 @@ void BellEngine::notifyBellsFired(const std::vector<uint8_t>& bellIndices) {
|
||||
bool BellEngine::isHealthy() const {
|
||||
// Check if engine task is created and running
|
||||
if (_engineTaskHandle == NULL) {
|
||||
LOG_DEBUG("BellEngine: Unhealthy - Task not created");
|
||||
LOG_DEBUG(TAG, "BellEngine: Unhealthy - Task not created");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if task is still alive
|
||||
eTaskState taskState = eTaskGetState(_engineTaskHandle);
|
||||
if (taskState == eDeleted || taskState == eInvalid) {
|
||||
LOG_DEBUG("BellEngine: Unhealthy - Task deleted or invalid");
|
||||
LOG_DEBUG(TAG, "BellEngine: Unhealthy - Task deleted or invalid");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if OutputManager is properly connected and healthy
|
||||
if (!_outputManager.isInitialized()) {
|
||||
LOG_DEBUG("BellEngine: Unhealthy - OutputManager not initialized");
|
||||
LOG_DEBUG(TAG, "BellEngine: Unhealthy - OutputManager not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user