#pragma once // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Command Handling of incoming JSON commands. // Both MQTT and Websocket // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void replyOnWebSocket(AsyncWebSocketClient *client, String list); void updateRelayTimings(JsonVariant doc); void updateBellOutputs(JsonVariant doc); // Handles the incoming payload. Returns it into a "JsonDocument" format. JsonDocument payload2json(char * payload) { JsonDocument doc; DeserializationError error = deserializeJson(doc, payload); if (error) { Serial.print("deserializeJson() failed: "); Serial.println(error.c_str()); } return doc; } // Handles the JSON Commands void handleCommand(JsonDocument command, AsyncWebSocketClient *client = nullptr){ String cmd = command["cmd"]; JsonVariant contents = command["contents"]; if (cmd == "playback") { player.command(contents, client); } else if (cmd == "list_melodies") { String list = listFilesAsJson("/melodies"); PublishMqtt(list.c_str()); if (client) { replyOnWebSocket(client, list); // Only reply via WS if client exists Serial.println("Replying on WebSocket"); } } else if (cmd == "set_relay_timers") { updateRelayTimings(contents); } else if (cmd == "set_relay_outputs") { updateBellOutputs(contents); } else if (cmd == "download_melody") { addMelody(contents); // Prepare JSON response StaticJsonDocument<128> response; response["status"] = "OK"; response["type"] = "Download"; response["payload"] = nullptr; // Use null in JSON char jsonOut[256]; // Create Char Buffer serializeJson(response, jsonOut); // Serialize to Buffer replyOnWebSocket(client, jsonOut); // Reply on WebSocket } /* else if (cmd == "sync_time") { StaticJsonDocument<256> response; if (manualTimeSync(contents)){ response["status"] = "OK"; response["type"] = "time_set_response"; response["payload"] = "Time updated successfully"; } response["status"] = "ERROR"; response["type"] = "time_set_response"; response["payload"] = "Missing timestamp parameter"; char jsonOut[256]; serializeJson(response, jsonOut); replyOnWebSocket(client, jsonOut); } else if (cmd == "report_time") { StaticJsonDocument<256> response; DateTime now = rtc.now(); response["status"] = "OK"; response["type"] = "time_response"; response["timestamp"] = now.unixtime(); // Unix timestamp (seconds since 1970) // Also include human-readable format for debugging response["datetime"] = String(now.year()) + "-" + String(now.month()) + "-" + String(now.day()) + "T" + String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second()); char jsonOut[256]; serializeJson(response, jsonOut); replyOnWebSocket(client, jsonOut); } else if (cmd == "set_time") { StaticJsonDocument<256> response; if (contents.containsKey("timestamp")) { uint32_t timestamp = contents["timestamp"]; DateTime newTime = DateTime(timestamp); rtc.adjust(newTime); response["status"] = "OK"; response["type"] = "time_set"; LOG_DEBUG("Time updated from app."); } else { response["status"] = "ERROR"; response["type"] = "time_set"; response["message"] = "Missing or Wrong timestamp parameter"; LOG_ERROR("Set time command missing timestamp parameter"); } char jsonOut[256]; serializeJson(response, jsonOut); replyOnWebSocket(client, jsonOut); } */ else if (cmd == "ping") { StaticJsonDocument<128> response; response["status"] = "OK"; response["type"] = "pong"; char jsonOut[128]; // Create Char Buffer serializeJson(response, jsonOut); // Serialize to Buffer replyOnWebSocket(client, jsonOut); // Reply on WebSocket return; } else if (cmd == "report_status") { StaticJsonDocument<256> response; response["status"] = "OK"; response["type"] = "current_status"; response["is_playing"] = player.isPlaying; response["time_elapsed"] = millis() - player.startTime; char jsonOut[256]; // Create Char Buffer serializeJson(response, jsonOut); // Serialize to Buffer replyOnWebSocket(client, jsonOut); // Reply on WebSocket } else { LOG_WARNING("Unknown Command Received"); } }