diff --git a/vesper/MQTT_Message_Handling.hpp b/vesper/MQTT_Message_Handling.hpp index 8745233..a052345 100644 --- a/vesper/MQTT_Message_Handling.hpp +++ b/vesper/MQTT_Message_Handling.hpp @@ -26,25 +26,20 @@ void SuscribeMqtt() { String topicRelayTimers = String("vesper/") + DEV_ID + "/control/settings/relayTimers"; uint16_t control_id = mqttClient.subscribe(topicPlayback.c_str(), 2); - Serial.print("Subscribing to Playback Control topic, QoS 2, packetId: "); - Serial.println(control_id); + LOG_INFO("Subscribing to Playback Control topic, QoS 2, packetId: %d", control_id); uint16_t set_melody_id = mqttClient.subscribe(topicSetMelody.c_str(), 2); - Serial.print("Subscribing to Set-Melody topic, QoS 2, packetId: "); - Serial.println(set_melody_id); + LOG_INFO("Subscribing to Set-Melody topic, QoS 2, packetId: %d", set_melody_id); - // doesn't work yet: + // doesn't work yet: uint16_t add_melody_id = mqttClient.subscribe(topicAddMelody.c_str(), 2); - Serial.print("Subscribing to Add-Melody topic, QoS 2, packetId: "); - Serial.println(add_melody_id); + LOG_INFO("Subscribing to Add-Melody topic, QoS 2, packetId: %d", add_melody_id); uint16_t add_schedule_id = mqttClient.subscribe(topicAddSchedule.c_str(), 2); - Serial.print("Subscribing to Add-Schedule topic, QoS 2, packetId: "); - Serial.println(add_schedule_id); + LOG_INFO("Subscribing to Add-Schedule topic, QoS 2, packetId: %d", add_schedule_id); uint16_t relay_timers_id = mqttClient.subscribe(topicRelayTimers.c_str(), 2); - Serial.print("Subscribing to Relay-Timers topic, QoS 2, packetId: "); - Serial.println(relay_timers_id); + LOG_INFO("Subscribing to Relay-Timers topic, QoS 2, packetId: %d", relay_timers_id); } @@ -72,7 +67,7 @@ void OnMqttReceived(char * topic, char * payload, AsyncMqttClientMessageProperti else if (String(topic) == topicAddMelody) { // Handle adding melody - Serial.println("Adding melody..."); + LOG_INFO("Adding melody..."); // You can call a function here to handle adding the melody } @@ -86,7 +81,7 @@ void OnMqttReceived(char * topic, char * payload, AsyncMqttClientMessageProperti else { // Handle unknown topics - Serial.println("Unknown topic received."); + LOG_WARNING("Unknown topic received."); } } diff --git a/vesper/MQTT_WiFi_Utilities.hpp b/vesper/MQTT_WiFi_Utilities.hpp index 7b2288e..84a11c2 100644 --- a/vesper/MQTT_WiFi_Utilities.hpp +++ b/vesper/MQTT_WiFi_Utilities.hpp @@ -14,21 +14,20 @@ String GetPayloadContent(char * data, size_t len) { void ConnectToMqtt() { - Serial.println("Connecting to MQTT..."); + LOG_INFO("Connecting to MQTT..."); mqttClient.connect(); } void OnMqttConnect(bool sessionPresent) { - Serial.println("Connected to MQTT."); - Serial.print("Session present: "); - Serial.println(sessionPresent); + LOG_INFO("Connected to MQTT."); + //LOG_INFO("Session present: %s", sessionPresent ? "Yes":"No"); SuscribeMqtt(); } void OnMqttDisconnect(AsyncMqttClientDisconnectReason reason) { - Serial.println("Disconnected from MQTT."); + LOG_WARNING("Disconnected from MQTT."); if(WiFi.isConnected()) { @@ -38,25 +37,17 @@ void OnMqttDisconnect(AsyncMqttClientDisconnectReason reason) void OnMqttSubscribe(uint16_t packetId, uint8_t qos) { - Serial.println("Subscribe acknowledged."); - Serial.print(" packetId: "); - Serial.println(packetId); - Serial.print(" qos: "); - Serial.println(qos); + LOG_INFO("Subscribe acknowledged. PacketID: %d / QoS: %d", packetId, qos); } void OnMqttUnsubscribe(uint16_t packetId) { - Serial.println("Unsubscribe acknowledged."); - Serial.print(" packetId: "); - Serial.println(packetId); + LOG_INFO("Unsubscribe Acknowledged. PacketID: %d",packetId); } void OnMqttPublish(uint16_t packetId) { - Serial.println("Publish acknowledged."); - Serial.print(" packetId: "); - Serial.println(packetId); + LOG_INFO("Publish Acknowledged. PacketID: %d", packetId); } void ConnectWiFi_STA(bool useStaticIP = false) @@ -74,11 +65,13 @@ void ConnectWiFi_STA(bool useStaticIP = false) Serial.print('.'); } - Serial.println(""); - Serial.print("Iniciado STA:\t"); - Serial.println(ssid); - Serial.print("IP address:\t"); - Serial.println(WiFi.localIP()); + if (LOG_LEVEL_ENABLED(LOG_LEVEL_INFO)){ + Serial.println(""); + Serial.print("Initiating STA:\t"); + Serial.println(ssid); + Serial.print("IP address:\t"); + Serial.println(WiFi.localIP()); + } } void ConnectWiFi_AP(bool useStaticIP = false) @@ -93,26 +86,27 @@ void ConnectWiFi_AP(bool useStaticIP = false) if(useStaticIP) WiFi.softAPConfig(ip, gateway, subnet); - Serial.println(""); - Serial.print("Iniciado AP:\t"); - Serial.println(ssid); - Serial.print("IP address:\t"); - Serial.println(WiFi.softAPIP()); + if (LOG_LEVEL_ENABLED(LOG_LEVEL_INFO)){ + Serial.println(""); + Serial.print("Iniciado AP:\t"); + Serial.println(ssid); + Serial.print("IP address:\t"); + Serial.println(WiFi.softAPIP()); + } } void WiFiEvent(WiFiEvent_t event) { - Serial.printf("[WiFi-event] event: %d\n", event); + LOG_INFO("[WiFi-event] event: %d\n", event); switch(event) { case ARDUINO_EVENT_WIFI_STA_GOT_IP: - Serial.println("WiFi connected"); - Serial.println("IP address: "); + Serial.print("[INFO] - WiFi connected. IP Address: "); Serial.println(WiFi.localIP()); ConnectToMqtt(); break; case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: - Serial.println("WiFi lost connection"); + LOG_WARNING("WiFi Lost Connection! :()"); xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi xTimerStart(wifiReconnectTimer, 0); break; diff --git a/vesper/PlaybackControls.hpp b/vesper/PlaybackControls.hpp index 6919f0a..ab62b4f 100644 --- a/vesper/PlaybackControls.hpp +++ b/vesper/PlaybackControls.hpp @@ -35,7 +35,7 @@ bool timeToStop(unsigned long now) { if (player.isPlaying) { uint64_t stopTime = player.startTime + player.duration; if (now >= stopTime) { - Serial.println("TIMER: Total Duration Reached"); + LOG_DEBUG("TIMER: Total Duration Reached"); return true; } } @@ -46,10 +46,9 @@ bool timeToStop(unsigned long now) { bool timeToPause(unsigned long now) { if (player.isPlaying && player.loop_duration > 0) { uint64_t pauseTimeLimit = player.loopStartTime + player.loop_duration; - Serial.printf("PTL: %lu // NOW: ",pauseTimeLimit); - Serial.println(now); + LOG_DEBUG("PTL: %lu // NOW: %d",pauseTimeLimit, now); if (now >= pauseTimeLimit && !player.isPaused) { - Serial.println("TIMER: Segment Duration Reached"); + LOG_DEBUG("TIMER: Segment Duration Reached"); player.pauseTime = now; return true; } @@ -62,7 +61,7 @@ bool timeToResume(unsigned long now) { if (player.isPaused) { uint64_t resumeTime = player.pauseTime + player.interval; if (now >= resumeTime) { - Serial.println("TIMER: Pause Duration Reached"); + LOG_DEBUG("TIMER: Pause Duration Reached"); return true; } } diff --git a/vesper/bellEngine.hpp b/vesper/bellEngine.hpp index d977919..af79eca 100644 --- a/vesper/bellEngine.hpp +++ b/vesper/bellEngine.hpp @@ -67,7 +67,7 @@ void loop_playback(std::vector &melody_steps) { vTaskDelay(pdMS_TO_TICKS(tempo)); } - Serial.println("SINGLE LOOP OVER."); + LOG_DEBUG("Single Loop Over."); //if (!player.isPlaying) break; // Stop playback only after completing the loop } } diff --git a/vesper/classes.hpp b/vesper/classes.hpp index 747ac98..fc3183e 100644 --- a/vesper/classes.hpp +++ b/vesper/classes.hpp @@ -24,36 +24,35 @@ public: isPlaying = true; hardStop = false; startTime = loopStartTime = millis(); - Serial.println("Plbck: PLAY"); + LOG_DEBUG("Plbck: PLAY"); } void forceStop() { hardStop = true; isPlaying = false; - Serial.println("Plbck: FORCE STOP"); + LOG_DEBUG("Plbck: FORCE STOP"); } void stop() { hardStop = false; isPlaying = false; - Serial.println("Plbck: STOP"); + LOG_DEBUG("Plbck: STOP"); } void pause() { isPaused = true; - Serial.println("Plbck: PAUSE"); + LOG_DEBUG("Plbck: PAUSE"); } void unpause() { isPaused = false; loopStartTime = millis(); - Serial.println("Plbck: RESUME"); + LOG_DEBUG("Plbck: RESUME"); } // Handles Incoming Commands to PLAY or STOP void command(char * command){ - Serial.print("INCOMING COMMAND: "); - Serial.println(command); + LOG_DEBUG("Incoming Command: %s",command); if (command[0] == '1') { play(); PublishMqtt("OK - PLAY"); @@ -88,7 +87,7 @@ public: loop_duration = doc["loop_dur"].as(); } // Print Just for Debugging Purposes - Serial.printf("Name: %s, ID: %d, Total Duration: %lu, Loop Duration: %lu, Interval: %d, Speed: %d, Inf: %s\n", + LOG_DEBUG("Name: %s, ID: %d, Total Duration: %lu, Loop Duration: %lu, Interval: %d, Speed: %d, Inf: %s\n", name.c_str(), id, duration, @@ -102,13 +101,12 @@ public: // Loads the Selected melody from a .bin file, into RAM void loadMelodyInRAM(std::vector &melody_steps) { + LOG_INFO("Loading Melody."); std::string filePath = "/" + name + ".bin"; - Serial.println("New Melody Selected !!!"); - Serial.println("Reading data from file..."); File bin_file = SPIFFS.open(filePath.c_str(), "r"); if (!bin_file) { - Serial.println("Failed to Open File"); + LOG_ERROR("Failed to Open File"); return; } @@ -116,22 +114,14 @@ public: size_t steps = fileSize / 2; melody_steps.resize(steps); - Serial.print("Opened File ! Size: "); - Serial.print(fileSize); - Serial.print(" Steps: "); - Serial.println(steps); + LOG_DEBUG("Opened File, size: %zu - Steps: %zu",fileSize,steps) for (size_t i=0; i doc; // Adjust size based on expected JSON complexity DeserializationError error = deserializeJson(doc, file); file.close(); if (error) { - Serial.printf("Failed to parse JSON: %s\n", error.c_str()); + LOG_ERROR("Failed to parse JSON: %s\n", error.c_str()); return; } - Serial.println("- - - SERIALIZE JSON - - -"); - serializeJsonPretty(doc, Serial); - Serial.println("- - - - END JSON - - - -"); + if (LOG_LEVEL_ENABLED(LOG_LEVEL_DEBUG)){ + String jsonString; + serializeJsonPretty(doc, jsonString); + LOG_DEBUG("Serialized JSON: /n%s",jsonString.c_str()); + } // Extract entries for the current day std::string currentDay = getDay(); dailySchedule.clear(); // Clear previous day's schedule - Serial.printf("Current Day: %s\n", currentDay.c_str()); + LOG_DEBUG("Current Day: %s\n", currentDay.c_str()); if (doc.containsKey(currentDay.c_str())) { - Serial.println("doc contains key!"); + LOG_DEBUG("Doc contains key!"); // Check if the current day contains a single object or an array JsonVariant dayVariant = doc[currentDay.c_str()]; @@ -215,8 +207,8 @@ private: schedule.duration = entry["duration"]; dailySchedule.push_back(schedule); - Serial.printf("Added Entry - Melody: %s, Hour: %d, Minute: %d, Speed: %d, Duration: %d\n", - schedule.mel.c_str(), schedule.hour, schedule.minute, schedule.speed, schedule.duration); + LOG_INFO("Added Entry - Melody: %s, Hour: %d, Minute: %d, Speed: %d, Duration: %d\n", + schedule.mel.c_str(), schedule.hour, schedule.minute, schedule.speed, schedule.duration); } } else if (dayVariant.is()) { // Handle case where the day contains a single object @@ -229,13 +221,13 @@ private: schedule.duration = entry["duration"]; dailySchedule.push_back(schedule); - Serial.printf("Added Single Entry - Melody: %s, Hour: %d, Minute: %d, Speed: %d, Duration: %d\n", + LOG_INFO("Added Single Entry - Melody: %s, Hour: %d, Minute: %d, Speed: %d, Duration: %d\n", schedule.mel.c_str(), schedule.hour, schedule.minute, schedule.speed, schedule.duration); } else { - Serial.println("Invalid data format for the current day."); + LOG_WARNING("Invalid data format for the current day."); } } else { - Serial.println("No schedule found for today."); + LOG_INFO("No schedule found for today."); } } @@ -249,12 +241,12 @@ private: if (!alreadyTriggered) { // First time at midnight, trigger the event alreadyTriggered = true; - Serial.println("New day detected, returning true."); + LOG_DEBUG("New day detected, returning true."); loadDailySchedule(); return true; } else { // It's still midnight, but we've already triggered - Serial.println("Already triggered for today, returning false."); + LOG_DEBUG("Already triggered for today, returning false."); return false; } } else { @@ -291,7 +283,7 @@ public: // Prints the time, NOW. void printTimeNow(){ - Serial.printf("Current Time: %s %s, %u - %02u:%02u:%02u\n", + LOG_INFO("Current Time: %s %s, %u - %02u:%02u:%02u\n", getMonth().c_str(), // Month as a string getDay().c_str(), // Day as a string getYear(), // Year as an integer @@ -306,18 +298,17 @@ public: } void checkAndRunSchedule(Player & player) { - + LOG_DEBUG("Running daily schedule check"); for (auto it = dailySchedule.begin(); it != dailySchedule.end(); ) { - Serial.println("Running daily schedule check"); if (now.hour == it->hour && now.minute == it->minute) { - Serial.printf("Entry Exists, returning True!"); + LOG_DEBUG("Entry Exists, Calling program."); StaticJsonDocument<200> jsonDoc; jsonDoc["name"] = it->mel.c_str(); jsonDoc["speed"] = it->speed; jsonDoc["duration"] = it->duration; jsonDoc["loop_dur"] = 0; jsonDoc["internal"] = 0; - Serial.printf("name: %s speed: %d duration: %d",it->mel.c_str(), it->speed, it->duration); + //LOG_INFO("Entry Found. Name: %s Speed: %d Duration: %d",it->mel.c_str(), it->speed, it->duration); if (!player.isPlaying){ player.setMelodyAttributes(jsonDoc); player.loadMelodyInRAM(melody_steps); @@ -326,7 +317,7 @@ public: } } else { - Serial.printf("No Entry, returning False!"); + LOG_DEBUG("Entry's time doesn't match. Skipping."); ++it; } } diff --git a/vesper/functions.hpp b/vesper/functions.hpp index 7c97312..c621eb7 100644 --- a/vesper/functions.hpp +++ b/vesper/functions.hpp @@ -16,24 +16,25 @@ void updateRelayTimings(JsonDocument doc) { String key = String("b") + (i + 1); // Generate "b1", "b2", ... if (doc.containsKey(key)) { relayDurations[i] = doc[key].as(); - Serial.printf("Relay %d duration set to %d ms\n", i + 1, relayDurations[i]); + LOG_DEBUG("Relay %d duration s1et to %d ms\n", i + 1, relayDurations[i]); } else { - Serial.printf("Relay %d not found in JSON payload. Keeping previous duration: %d ms\n", i + 1, relayDurations[i]); + LOG_DEBUG("Relay %d not found in JSON payload. Keeping previous duration: %d ms\n", i + 1, relayDurations[i]); } } saveRelayTimings(); + LOG_INFO("Updated Relay Timings.") } // Save file "fileName" with data: "data" void savefile(const char* fileName, const char* data) { File file = SPIFFS.open(fileName, "w"); if (!file) { - Serial.println("Failed to open file!"); + LOG_ERROR("Failed to open file!"); return; } file.print(data); file.close(); - Serial.printf("File %s saved successfully.\n", fileName); + LOG_INFO("File %s saved successfully.\n", fileName); } // Saves Relay Durations from RAM, into a file @@ -49,7 +50,7 @@ void saveRelayTimings() { char buffer[512]; size_t len = serializeJson(doc, buffer, sizeof(buffer)); if (len == 0) { - Serial.println("Failed to serialize JSON."); + LOG_ERROR("Failed to serialize JSON."); return; } @@ -78,7 +79,7 @@ void loadRelayTimings() { // Open the file for reading File file = SPIFFS.open("/settings/relayTimings.json", "r"); if (!file) { - Serial.println("Settings file not found. Using default relay timings."); + LOG_ERROR("Settings file not found. Using default relay timings."); return; } @@ -86,7 +87,7 @@ void loadRelayTimings() { StaticJsonDocument<512> doc; // Adjust size if needed DeserializationError error = deserializeJson(doc, file); if (error) { - Serial.println("Failed to parse settings file. Using default relay timings."); + LOG_ERROR("Failed to parse settings file. Using default relay timings."); file.close(); return; } @@ -96,7 +97,7 @@ void loadRelayTimings() { String key = String("b") + (i + 1); if (doc.containsKey(key)) { relayDurations[i] = doc[key].as(); - Serial.printf("Loaded relay %d duration: %d ms\n", i + 1, relayDurations[i]); + LOG_DEBUG("Loaded relay %d duration: %d ms\n", i + 1, relayDurations[i]); } } @@ -109,7 +110,7 @@ void updateSchedule(JsonDocument doc) { // Ensure fileName exists and is valid if (!fileName || strlen(fileName) == 0) { - Serial.println("Invalid JSON payload: Missing or invalid 'file' field"); + LOG_ERROR("Invalid JSON payload: Missing or invalid 'file' field"); return; } @@ -119,9 +120,9 @@ void updateSchedule(JsonDocument doc) { if (dataString.length() > 0) { savefile(fileName, dataString.c_str()); - Serial.printf("File '%s' updated successfully.\n", fileName); + LOG_INFO("File '%s' updated successfully.\n", fileName); } else { - Serial.println("Invalid JSON payload: Unable to serialize 'data'"); + LOG_DEBUG("Invalid JSON payload: Unable to serialize 'data'"); } timekeeper.refreshDailySchedule(); } diff --git a/vesper/logging.hpp b/vesper/logging.hpp new file mode 100644 index 0000000..fb1b557 --- /dev/null +++ b/vesper/logging.hpp @@ -0,0 +1,37 @@ +// Define Log Levels +#define LOG_LEVEL_NONE 0 // No logs +#define LOG_LEVEL_ERROR 1 // Errors only +#define LOG_LEVEL_WARNING 2 // Warnings and errors +#define LOG_LEVEL_INFO 3 // Info, warnings, and errors +#define LOG_LEVEL_DEBUG 4 // All logs (full debugging) + +// Set the active log level +#define ACTIVE_LOG_LEVEL LOG_LEVEL_DEBUG + +// Check if the log level is enabled +#define LOG_LEVEL_ENABLED(level) (ACTIVE_LOG_LEVEL >= level) + +// Macro to control logging based on the active level +#if LOG_LEVEL_ENABLED(LOG_LEVEL_ERROR) + #define LOG_ERROR(...) { Serial.print("[ERROR] - "); Serial.printf(__VA_ARGS__); Serial.println(); } +#else + #define LOG_ERROR(...) // No logging if level is not enabled +#endif + +#if LOG_LEVEL_ENABLED(LOG_LEVEL_WARNING) + #define LOG_WARNING(...) { Serial.print("[WARNING] - "); Serial.printf(__VA_ARGS__); Serial.println(); } +#else + #define LOG_WARNING(...) // No logging if level is not enabled +#endif + +#if LOG_LEVEL_ENABLED(LOG_LEVEL_INFO) + #define LOG_INFO(...) { Serial.print("[INFO] - "); Serial.printf(__VA_ARGS__); Serial.println(); } +#else + #define LOG_INFO(...) // No logging if level is not enabled +#endif + +#if LOG_LEVEL_ENABLED(LOG_LEVEL_DEBUG) + #define LOG_DEBUG(...) { Serial.print("[DEBUG] - "); Serial.printf(__VA_ARGS__); Serial.println(); } +#else + #define LOG_DEBUG(...) // No logging if level is not enabled +#endif diff --git a/vesper/vesper.ino b/vesper/vesper.ino index 8f56b7b..6bfa5c2 100644 --- a/vesper/vesper.ino +++ b/vesper/vesper.ino @@ -14,7 +14,9 @@ TODO List: - Add */ +#include "logging.hpp" +#include #include #include #include @@ -67,10 +69,10 @@ void setup() } // Initialize SPIFFS if (!SPIFFS.begin(true)) { // 'true' means format SPIFFS if initialization fails - Serial.println("Failed to mount SPIFFS"); + LOG_ERROR("Failed to mount SPIFFS"); while(true) delay(10); } - Serial.println("SPIFFS mounted successfully"); + LOG_INFO("SPIFFS mounted successfully"); delay(50); // Initialize RTC if (!rtc.begin()) { @@ -79,7 +81,7 @@ void setup() } if (! rtc.isrunning()) { - Serial.println("RTC is NOT running, let's set the time!"); + LOG_INFO("RTC is NOT running, let's set the time!"); // When time needs to be set on a new device, or after a power loss, the // following line sets the RTC to the date & time this sketch was compiled rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); @@ -104,7 +106,7 @@ void setup() if (schedulerTimer != NULL) { xTimerStart(schedulerTimer, 0); } else { - Serial.println("Failed to create timer!"); + LOG_ERROR("Failed to create timer!"); } timekeeper.refreshDailySchedule();