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:
@@ -1,4 +1,6 @@
|
||||
#include "Player.hpp"
|
||||
|
||||
#define TAG "Player"
|
||||
#include "../Communication/CommunicationRouter/CommunicationRouter.hpp"
|
||||
#include "../BellEngine/BellEngine.hpp"
|
||||
#include "../Telemetry/Telemetry.hpp"
|
||||
@@ -85,7 +87,7 @@ Player::~Player() {
|
||||
}
|
||||
|
||||
void Player::begin() {
|
||||
LOG_INFO("Initializing Player with FreeRTOS Timer (saves 4KB RAM!)");
|
||||
LOG_INFO(TAG, "Initializing Player with FreeRTOS Timer (saves 4KB RAM!)");
|
||||
|
||||
// Create a periodic timer that fires every 500ms
|
||||
_durationTimerHandle = xTimerCreate(
|
||||
@@ -98,22 +100,22 @@ void Player::begin() {
|
||||
|
||||
if (_durationTimerHandle != NULL) {
|
||||
xTimerStart(_durationTimerHandle, 0);
|
||||
LOG_INFO("Player initialized successfully with timer");
|
||||
LOG_INFO(TAG, "Player initialized successfully with timer");
|
||||
} else {
|
||||
LOG_ERROR("Failed to create Player timer!");
|
||||
LOG_ERROR(TAG, "Failed to create Player timer!");
|
||||
}
|
||||
}
|
||||
|
||||
void Player::play() {
|
||||
if (_melodySteps.empty()) {
|
||||
LOG_ERROR("Cannot play: No melody loaded");
|
||||
LOG_ERROR(TAG, "Cannot play: No melody loaded");
|
||||
return;
|
||||
}
|
||||
|
||||
// 🔥 CRITICAL: Interrupt any active clock alerts - user playback has priority!
|
||||
if (_timekeeper) {
|
||||
_timekeeper->interruptActiveAlert();
|
||||
LOG_DEBUG("Player: Interrupted any active clock alerts");
|
||||
LOG_DEBUG(TAG, "Player: Interrupted any active clock alerts");
|
||||
}
|
||||
|
||||
if (_bellEngine) {
|
||||
@@ -125,7 +127,7 @@ void Player::play() {
|
||||
hardStop = false;
|
||||
startTime = segmentStartTime = millis();
|
||||
setStatus(PlayerStatus::PLAYING); // Update status and notify clients
|
||||
LOG_DEBUG("Plbck: PLAY");
|
||||
LOG_DEBUG(TAG, "Plbck: PLAY");
|
||||
}
|
||||
|
||||
void Player::forceStop() {
|
||||
@@ -142,7 +144,7 @@ void Player::forceStop() {
|
||||
_telemetry->saveStrikeCounters();
|
||||
}
|
||||
|
||||
LOG_DEBUG("Plbck: FORCE STOP");
|
||||
LOG_DEBUG(TAG, "Plbck: FORCE STOP");
|
||||
}
|
||||
|
||||
void Player::stop() {
|
||||
@@ -162,10 +164,10 @@ void Player::stop() {
|
||||
_telemetry->saveStrikeCounters();
|
||||
}
|
||||
|
||||
LOG_DEBUG("Plbck: STOP from PAUSED state");
|
||||
LOG_DEBUG(TAG, "Plbck: STOP from PAUSED state");
|
||||
} else {
|
||||
setStatus(PlayerStatus::STOPPING);
|
||||
LOG_DEBUG("Plbck: SOFT STOP (waiting for melody to complete)");
|
||||
LOG_DEBUG(TAG, "Plbck: SOFT STOP (waiting for melody to complete)");
|
||||
}
|
||||
// NOTE: The actual "stop" message is now sent in onMelodyLoopCompleted()
|
||||
// when the BellEngine actually finishes the current loop
|
||||
@@ -174,14 +176,14 @@ void Player::stop() {
|
||||
void Player::pause() {
|
||||
isPaused = true;
|
||||
setStatus(PlayerStatus::PAUSED);
|
||||
LOG_DEBUG("Plbck: PAUSE");
|
||||
LOG_DEBUG(TAG, "Plbck: PAUSE");
|
||||
}
|
||||
|
||||
void Player::unpause() {
|
||||
isPaused = false;
|
||||
segmentStartTime = millis();
|
||||
setStatus(PlayerStatus::PLAYING);
|
||||
LOG_DEBUG("Plbck: RESUME");
|
||||
LOG_DEBUG(TAG, "Plbck: RESUME");
|
||||
}
|
||||
|
||||
bool Player::command(JsonVariant data) {
|
||||
@@ -189,7 +191,7 @@ bool Player::command(JsonVariant data) {
|
||||
loadMelodyInRAM(); // Removed parameter - use internal storage
|
||||
|
||||
String action = data["action"];
|
||||
LOG_DEBUG("Incoming Command: %s", action.c_str());
|
||||
LOG_DEBUG(TAG, "Incoming Command: %s", action.c_str());
|
||||
|
||||
// Play or Stop Logic
|
||||
if (action == "play") {
|
||||
@@ -199,7 +201,7 @@ bool Player::command(JsonVariant data) {
|
||||
forceStop();
|
||||
return true;
|
||||
} else {
|
||||
LOG_WARNING("Unknown playback action: %s", action.c_str());
|
||||
LOG_WARNING(TAG, "Unknown playback action: %s", action.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -245,10 +247,10 @@ void Player::setMelodyAttributes(JsonVariant doc) {
|
||||
}
|
||||
|
||||
// Print Just for Debugging Purposes
|
||||
LOG_DEBUG("Set Melody Vars / Name: %s, UID: %s",
|
||||
LOG_DEBUG(TAG, "Set Melody Vars / Name: %s, UID: %s",
|
||||
name.c_str(), uid.c_str());
|
||||
LOG_DEBUG("URL: %s", url.c_str());
|
||||
LOG_DEBUG("Speed: %d, Per Segment Duration: %lu, Pause Duration: %lu, Total Duration: %d, Continuous: %s, Infinite: %s",
|
||||
LOG_DEBUG(TAG, "URL: %s", url.c_str());
|
||||
LOG_DEBUG(TAG, "Speed: %d, Per Segment Duration: %lu, Pause Duration: %lu, Total Duration: %d, Continuous: %s, Infinite: %s",
|
||||
speed, segment_duration, pause_duration, total_duration,
|
||||
continuous_loop ? "true" : "false", infinite_play ? "true" : "false");
|
||||
}
|
||||
@@ -258,13 +260,13 @@ void Player::loadMelodyInRAM() {
|
||||
|
||||
// 🎵 PRIORITY 1: Check if this is a built-in melody
|
||||
if (BuiltInMelodies::isBuiltInMelody(uidStr)) {
|
||||
LOG_INFO("Loading built-in melody: %s", uidStr.c_str());
|
||||
LOG_INFO(TAG, "Loading built-in melody: %s", uidStr.c_str());
|
||||
|
||||
if (BuiltInMelodies::loadBuiltInMelody(uidStr, _melodySteps)) {
|
||||
LOG_INFO("✅ Built-in melody loaded successfully: %d steps", _melodySteps.size());
|
||||
LOG_INFO(TAG, "✅ Built-in melody loaded successfully: %d steps", _melodySteps.size());
|
||||
return;
|
||||
} else {
|
||||
LOG_ERROR("Failed to load built-in melody: %s", uidStr.c_str());
|
||||
LOG_ERROR(TAG, "Failed to load built-in melody: %s", uidStr.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -274,8 +276,8 @@ void Player::loadMelodyInRAM() {
|
||||
|
||||
File bin_file = SD.open(filePath.c_str(), FILE_READ);
|
||||
if (!bin_file) {
|
||||
LOG_ERROR("Failed to open file: %s", filePath.c_str());
|
||||
LOG_ERROR("Check Servers for the File...");
|
||||
LOG_ERROR(TAG, "Failed to open file: %s", filePath.c_str());
|
||||
LOG_ERROR(TAG, "Check Servers for the File...");
|
||||
|
||||
// Try to download the file using FileManager
|
||||
if (_fileManager) {
|
||||
@@ -284,20 +286,20 @@ void Player::loadMelodyInRAM() {
|
||||
doc["melodys_uid"] = uid;
|
||||
|
||||
if (!_fileManager->addMelody(doc)) {
|
||||
LOG_ERROR("Failed to Download File. Check Internet Connection");
|
||||
LOG_ERROR(TAG, "Failed to Download File. Check Internet Connection");
|
||||
return;
|
||||
} else {
|
||||
bin_file = SD.open(filePath.c_str(), FILE_READ);
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR("FileManager not available for download");
|
||||
LOG_ERROR(TAG, "FileManager not available for download");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
size_t fileSize = bin_file.size();
|
||||
if (fileSize % 2 != 0) {
|
||||
LOG_ERROR("Invalid file size: %u (not a multiple of 2)", fileSize);
|
||||
LOG_ERROR(TAG, "Invalid file size: %u (not a multiple of 2)", fileSize);
|
||||
bin_file.close();
|
||||
return;
|
||||
}
|
||||
@@ -311,7 +313,7 @@ void Player::loadMelodyInRAM() {
|
||||
_melodySteps[i] = (high << 8) | low;
|
||||
}
|
||||
|
||||
LOG_INFO("Melody loaded successfully from SD: %d steps", _melodySteps.size());
|
||||
LOG_INFO(TAG, "Melody loaded successfully from SD: %d steps", _melodySteps.size());
|
||||
bin_file.close();
|
||||
}
|
||||
|
||||
@@ -341,7 +343,7 @@ bool Player::timeToStop(unsigned long now) {
|
||||
if (isPlaying && !infinite_play) {
|
||||
uint64_t stopTime = startTime + total_duration;
|
||||
if (now >= stopTime) {
|
||||
LOG_DEBUG("(TimerFunction) Total Run Duration Reached. Soft Stopping.");
|
||||
LOG_DEBUG(TAG, "(TimerFunction) Total Run Duration Reached. Soft Stopping.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -392,7 +394,7 @@ void Player::setStatus(PlayerStatus newStatus) {
|
||||
// 🔥 Use broadcastStatus() to send to BOTH WebSocket AND MQTT clients!
|
||||
_commManager->broadcastStatus(doc);
|
||||
|
||||
LOG_DEBUG("Status changed: %d → %d, broadcast sent with runTime: %llu",
|
||||
LOG_DEBUG(TAG, "Status changed: %d → %d, broadcast sent with runTime: %llu",
|
||||
(int)oldStatus, (int)newStatus, projectedRunTime);
|
||||
}
|
||||
}
|
||||
@@ -402,7 +404,7 @@ void Player::onMelodyLoopCompleted() {
|
||||
if (_status == PlayerStatus::STOPPING) {
|
||||
// We were in soft stop mode, now actually stop
|
||||
setStatus(PlayerStatus::STOPPED);
|
||||
LOG_DEBUG("Plbck: ACTUAL STOP (melody loop completed)");
|
||||
LOG_DEBUG(TAG, "Plbck: ACTUAL STOP (melody loop completed)");
|
||||
}
|
||||
|
||||
// Mark segment completion time
|
||||
@@ -413,9 +415,9 @@ void Player::onMelodyLoopCompleted() {
|
||||
bool Player::timeToPause(unsigned long now) {
|
||||
if (isPlaying && continuous_loop) {
|
||||
uint64_t timeToPause = segmentStartTime + segment_duration;
|
||||
LOG_DEBUG("PTL: %llu // NOW: %lu", timeToPause, now);
|
||||
LOG_DEBUG(TAG, "PTL: %llu // NOW: %lu", timeToPause, now);
|
||||
if (now >= timeToPause && !isPaused) {
|
||||
LOG_DEBUG("(TimerFunction) Segment Duration Reached. Pausing.");
|
||||
LOG_DEBUG(TAG, "(TimerFunction) Segment Duration Reached. Pausing.");
|
||||
pauseTime = now;
|
||||
return true;
|
||||
}
|
||||
@@ -428,7 +430,7 @@ bool Player::timeToResume(unsigned long now) {
|
||||
if (isPaused) {
|
||||
uint64_t timeToResume = segmentCmpltTime + pause_duration;
|
||||
if (now >= timeToResume) {
|
||||
LOG_DEBUG("(TimerFunction) Pause Duration Reached. Resuming");
|
||||
LOG_DEBUG(TAG, "(TimerFunction) Pause Duration Reached. Resuming");
|
||||
segmentStartTime = now; // Reset segment start time for next cycle
|
||||
return true;
|
||||
}
|
||||
@@ -466,35 +468,35 @@ uint64_t Player::calculateProjectedRunTime() const {
|
||||
bool Player::isHealthy() const {
|
||||
// Check if dependencies are properly set
|
||||
if (!_commManager) {
|
||||
LOG_DEBUG("Player: Unhealthy - Communication manager not set");
|
||||
LOG_DEBUG(TAG, "Player: Unhealthy - Communication manager not set");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_fileManager) {
|
||||
LOG_DEBUG("Player: Unhealthy - File manager not set");
|
||||
LOG_DEBUG(TAG, "Player: Unhealthy - File manager not set");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_bellEngine) {
|
||||
LOG_DEBUG("Player: Unhealthy - BellEngine not set");
|
||||
LOG_DEBUG(TAG, "Player: Unhealthy - BellEngine not set");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if timer is properly created
|
||||
if (_durationTimerHandle == NULL) {
|
||||
LOG_DEBUG("Player: Unhealthy - Duration timer not created");
|
||||
LOG_DEBUG(TAG, "Player: Unhealthy - Duration timer not created");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if timer is actually running
|
||||
if (xTimerIsTimerActive(_durationTimerHandle) == pdFALSE) {
|
||||
LOG_DEBUG("Player: Unhealthy - Duration timer not active");
|
||||
LOG_DEBUG(TAG, "Player: Unhealthy - Duration timer not active");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for consistent playback state
|
||||
if (isPlaying && (_status == PlayerStatus::STOPPED)) {
|
||||
LOG_DEBUG("Player: Unhealthy - Inconsistent playback state");
|
||||
LOG_DEBUG(TAG, "Player: Unhealthy - Inconsistent playback state");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user