diff --git a/examples/multimatrix/MultiMatrixService.cpp b/examples/multimatrix/MultiMatrixService.cpp index 726b5db..cf34d9c 100644 --- a/examples/multimatrix/MultiMatrixService.cpp +++ b/examples/multimatrix/MultiMatrixService.cpp @@ -17,7 +17,8 @@ MultiMatrixService::MultiMatrixService(NodeContext& ctx, TaskManager& taskManage m_serial(std::make_unique(rxPin, txPin)), m_potentiometerPin(potentiometerPin), m_volume(DEFAULT_VOLUME), - m_playerReady(false) { + m_playerReady(false), + m_loopEnabled(false) { pinMode(m_potentiometerPin, INPUT); m_serial->begin(9600); @@ -46,8 +47,9 @@ void MultiMatrixService::registerEndpoints(ApiServer& api) { [this](AsyncWebServerRequest* request) { handleControlRequest(request); }, std::vector{ ParamSpec{String("action"), true, String("body"), String("string"), - {String("play"), String("stop"), String("pause"), String("resume"), String("next"), String("previous"), String("volume")}}, - ParamSpec{String("volume"), false, String("body"), String("numberRange"), {}, String("15")} + {String("play"), String("stop"), String("pause"), String("resume"), String("next"), String("previous"), String("volume"), String("loop")}}, + ParamSpec{String("volume"), false, String("body"), String("numberRange"), {}, String("15")}, + ParamSpec{String("loop"), false, String("body"), String("boolean"), {}} }); } @@ -59,6 +61,10 @@ uint8_t MultiMatrixService::getVolume() const { return m_volume; } +bool MultiMatrixService::isLoopEnabled() const { + return m_loopEnabled; +} + void MultiMatrixService::play() { if (!m_playerReady) { return; @@ -124,6 +130,20 @@ void MultiMatrixService::setVolume(uint8_t volume) { applyVolume(clampedVolume); } +void MultiMatrixService::setLoop(bool enabled) { + if (!m_playerReady) { + return; + } + m_loopEnabled = enabled; + if (enabled) { + m_player.enableLoop(); + } else { + m_player.disableLoop(); + } + publishEvent("loop"); + LOG_INFO("MultiMatrixService", String("Loop ") + (enabled ? "enabled" : "disabled")); +} + void MultiMatrixService::registerTasks() { m_taskManager.registerTask("multimatrix_potentiometer", POTENTIOMETER_SAMPLE_INTERVAL_MS, [this]() { pollPotentiometer(); }); @@ -137,17 +157,7 @@ void MultiMatrixService::pollPotentiometer() { const uint16_t rawValue = analogRead(static_cast(m_potentiometerPin)); const uint8_t targetVolume = calculateVolumeFromPotentiometer(rawValue); - // Debug: fire event on significant change if (targetVolume > m_volume + POT_VOLUME_EPSILON || targetVolume + POT_VOLUME_EPSILON < m_volume) { - StaticJsonDocument<128> debugDoc; - debugDoc["action"] = "pot_debug"; - debugDoc["raw"] = rawValue; - debugDoc["target"] = targetVolume; - debugDoc["current"] = m_volume; - String debugPayload; - serializeJson(debugDoc, debugPayload); - m_ctx.fire(EVENT_TOPIC, &debugPayload); - applyVolume(targetVolume); } } @@ -169,9 +179,10 @@ void MultiMatrixService::applyVolume(uint8_t targetVolume) { } void MultiMatrixService::handleStatusRequest(AsyncWebServerRequest* request) { - StaticJsonDocument<128> doc; + StaticJsonDocument<192> doc; doc["ready"] = m_playerReady; doc["volume"] = static_cast(m_volume); + doc["loop"] = m_loopEnabled; String json; serializeJson(doc, json); @@ -201,14 +212,23 @@ void MultiMatrixService::handleControlRequest(AsyncWebServerRequest* request) { } else { ok = false; } + } else if (action.equalsIgnoreCase("loop")) { + if (request->hasParam("loop", true)) { + String loopValue = request->getParam("loop", true)->value(); + bool enabled = loopValue.equalsIgnoreCase("true") || loopValue == "1"; + setLoop(enabled); + } else { + ok = false; + } } else { ok = false; } - StaticJsonDocument<192> resp; + StaticJsonDocument<256> resp; resp["success"] = ok; resp["ready"] = m_playerReady; resp["volume"] = static_cast(m_volume); + resp["loop"] = m_loopEnabled; if (!ok) { resp["message"] = "Invalid action"; } @@ -219,9 +239,10 @@ void MultiMatrixService::handleControlRequest(AsyncWebServerRequest* request) { } void MultiMatrixService::publishEvent(const char* action) { - StaticJsonDocument<128> doc; + StaticJsonDocument<192> doc; doc["action"] = action; doc["volume"] = static_cast(m_volume); + doc["loop"] = m_loopEnabled; String payload; serializeJson(doc, payload); m_ctx.fire(EVENT_TOPIC, &payload); diff --git a/examples/multimatrix/MultiMatrixService.h b/examples/multimatrix/MultiMatrixService.h index 188d465..b673126 100644 --- a/examples/multimatrix/MultiMatrixService.h +++ b/examples/multimatrix/MultiMatrixService.h @@ -18,6 +18,7 @@ public: bool isReady() const; uint8_t getVolume() const; + bool isLoopEnabled() const; void play(); void stop(); @@ -26,6 +27,7 @@ public: void next(); void previous(); void setVolume(uint8_t volume); + void setLoop(bool enabled); private: static constexpr uint16_t POTENTIOMETER_SAMPLE_INTERVAL_MS = 200; @@ -47,4 +49,5 @@ private: uint8_t m_potentiometerPin; uint8_t m_volume; bool m_playerReady; + bool m_loopEnabled; }; diff --git a/examples/multimatrix/data/public/index.html b/examples/multimatrix/data/public/index.html index c535e31..baf25c5 100644 --- a/examples/multimatrix/data/public/index.html +++ b/examples/multimatrix/data/public/index.html @@ -3,48 +3,335 @@ - Multi-Matrix Audio Control + Multi-Matrix Audio Player -
-

Multi-Matrix Audio

-
- - - - - - +
+
+

Multi-Matrix Audio

+
+ + Connecting... +
-
- - - 15 + +
+ + +
-
-

Player Status: Unknown

-

Volume: -

+ +
+ + +
+ +
+
+ 🔊 Volume + 15 +
+ +
+ +
+
+ 🔁 Loop Mode +
+
+
+