MAJOR update. More like a Backup before things get Crazy

Added Websocket Support
Added Universal Message Handling for both MQTT and WS
Added Timekeeper Class, that handles Physical Clock and Scheduling
Added Bell Assignment Settings, Note to Bell mapping
This commit is contained in:
2025-09-05 19:27:13 +03:00
parent c1fa1d5e57
commit 101f9e7135
20 changed files with 10746 additions and 9766 deletions

View File

@@ -0,0 +1,120 @@
#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");
}
}