#pragma once void setRelayDurations(JsonDocument& doc); void updateRelayTimings(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - // Handles the incoming payload. Returns it into a "JsonDocument" format. JsonDocument handleJSON(char * payload) { JsonDocument doc; DeserializationError error = deserializeJson(doc, payload); if (error) { Serial.print("deserializeJson() failed: "); Serial.println(error.c_str()); } return doc; } void replyOnWebSocket(AsyncWebSocketClient *client, String list) { client->text(list); } // Handles the JSON Commands void handleCommand(JsonDocument json, AsyncWebSocketClient *client = nullptr){ String cmd = json["cmd"]; JsonVariant contents = json["contents"]; if (cmd == "playback") { player.command(contents); } else if (cmd == "set_melody") { player.setMelodyAttributes(contents); player.loadMelodyInRAM(melody_steps); } 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 } } else if (cmd == "set_relay_timers") { updateRelayTimings(contents); } else if (cmd == "add_melody"){ addMelody(contents); } else { LOG_WARNING("Unknown Command Received"); } } // Subscribes to certain topics on the MQTT Server. void SuscribeMqtt() { String command = String("vesper/") + DEV_ID + "/control"; uint16_t command_id = mqttClient.subscribe(command.c_str(), 2); LOG_INFO("Subscribing to Command topic, QoS 2, packetId: %d", command_id); } // Handles incoming MQTT messages on subscribed topics. // Could move logic out of this into a dedicated function. void OnMqttReceived(char * topic, char * payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) { String command = String("vesper/") + DEV_ID + "/control"; // Don't know what this is. Check it out later. //String payloadContent = String(payload).substring(0, len); if (String(topic) == command){ JsonDocument json = handleJSON(payload); handleCommand(json); } } // Handles incoming WebSocket messages on subscribed topics. // Could move logic out of this into a dedicated function. void onWebSocketReceived(AsyncWebSocketClient *client, void *arg, uint8_t *data, size_t len) { AwsFrameInfo *info = (AwsFrameInfo*)arg; if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) { data[len] = '\0'; // Null-terminate the received data Serial.printf("Received message: %s\n", (char*)data); JsonDocument json = handleJSON((char*)data); handleCommand(json, client); } } void onWebSocketEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) { if (type == WS_EVT_DATA) { onWebSocketReceived(client, arg, data, len); } } // Publishes a message on the MQTT server. Message passed as an argument. void PublishMqtt(const char * data) { String topicData = String("vesper/") + DEV_ID + "/data"; mqttClient.publish(topicData.c_str(), 0, true, data); }