/* * ═══════════════════════════════════════════════════════════════════════════════════ * COMMUNICATION.HPP - Multi-Protocol Communication Manager v3.0 * ═══════════════════════════════════════════════════════════════════════════════════ * * 📡 THE COMMUNICATION HUB OF VESPER 📡 * * This class manages all external communication protocols including MQTT, * WebSocket, and UDP discovery. It provides a unified interface for * grouped command handling and status reporting across multiple protocols. * * 🏗️ ARCHITECTURE: * • Multi-protocol support with unified grouped command processing * • Multi-client WebSocket support with device type identification * • Automatic connection management and reconnection * • Unified response system for consistent messaging * • Thread-safe operation with proper resource management * • Batch command support for efficient configuration * * 📡 SUPPORTED PROTOCOLS: * • MQTT: Primary control interface with auto-reconnection * • WebSocket: Real-time multi-client web interface communication * • UDP Discovery: Auto-discovery service for network scanning * * 📱 CLIENT MANAGEMENT: * • Support for multiple WebSocket clients (master/secondary devices) * • Client type identification and targeted messaging * • Automatic cleanup of disconnected clients * • Broadcast capabilities for status updates * * 🔄 MESSAGE ROUTING: * • Commands accepted from both MQTT and WebSocket * • Responses sent only to originating protocol/client * • Status broadcasts sent to all WebSocket clients + MQTT * • Grouped command processing for all protocols * * 📋 VERSION: 3.0 (Grouped commands + batch processing) * 📅 DATE: 2025 * 👨‍💻 AUTHOR: Advanced Bell Systems * ═══════════════════════════════════════════════════════════════════════════════════ */ #pragma once #include #include #include #include #include #include "ResponseBuilder.hpp" #include "../ClientManager/ClientManager.hpp" class ConfigManager; class OTAManager; class Player; class FileManager; class Timekeeper; class Networking; class FirmwareValidator; class Communication { public: // Message source identification for response routing enum class MessageSource { MQTT, WEBSOCKET }; struct MessageContext { MessageSource source; uint32_t clientId; // Only used for WebSocket messages MessageContext(MessageSource src, uint32_t id = 0) : source(src), clientId(id) {} }; explicit Communication(ConfigManager& configManager, OTAManager& otaManager, Networking& networking, AsyncMqttClient& mqttClient, AsyncWebServer& server, AsyncWebSocket& webSocket, AsyncUDP& udp); ~Communication(); void begin(); void setPlayerReference(Player* player) { _player = player; } void setFileManagerReference(FileManager* fm) { _fileManager = fm; } void setTimeKeeperReference(Timekeeper* tk) { _timeKeeper = tk; } void setFirmwareValidatorReference(FirmwareValidator* fv) { _firmwareValidator = fv; } void setupUdpDiscovery(); // Public methods for timer callbacks void connectToMqtt(); void subscribeMqtt(); // Status methods bool isMqttConnected() const { return _mqttClient.connected(); } bool hasActiveWebSocketClients() const { return _clientManager.hasClients(); } size_t getWebSocketClientCount() const { return _clientManager.getClientCount(); } // Response methods - unified response system void sendResponse(const String& response, const MessageContext& context); void sendSuccessResponse(const String& type, const String& payload, const MessageContext& context); void sendErrorResponse(const String& type, const String& message, const MessageContext& context); // Broadcast methods - for status updates that go to everyone void broadcastStatus(const String& statusMessage); void broadcastStatus(const JsonDocument& statusJson); void broadcastToMasterClients(const String& message); void broadcastToSecondaryClients(const String& message); void broadcastToAllWebSocketClients(const String& message); void broadcastToAllWebSocketClients(const JsonDocument& message); void publishToMqtt(const String& data); // ═══════════════════════════════════════════════════════════════════════════════ // HEALTH CHECK METHOD // ═══════════════════════════════════════════════════════════════════════════════ /** @brief Check if Communication is in healthy state */ bool isHealthy() const; // Bell overload notification void sendBellOverloadNotification(const std::vector& bellNumbers, const std::vector& bellLoads, const String& severity); // Network connection callbacks (called by Networking) void onNetworkConnected(); void onNetworkDisconnected(); // Static instance for callbacks static Communication* _instance; private: // Dependencies ConfigManager& _configManager; OTAManager& _otaManager; Networking& _networking; AsyncMqttClient& _mqttClient; AsyncWebServer& _server; AsyncWebSocket& _webSocket; AsyncUDP& _udp; Player* _player; FileManager* _fileManager; Timekeeper* _timeKeeper; FirmwareValidator* _firmwareValidator; // Client manager ClientManager _clientManager; // State TimerHandle_t _mqttReconnectTimer; // Reusable JSON documents static StaticJsonDocument<2048> _parseDocument; // MQTT methods void initMqtt(); static void onMqttConnect(bool sessionPresent); static void onMqttDisconnect(AsyncMqttClientDisconnectReason reason); static void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total); static void onMqttSubscribe(uint16_t packetId, uint8_t qos); static void onMqttUnsubscribe(uint16_t packetId); static void onMqttPublish(uint16_t packetId); // WebSocket methods void initWebSocket(); static void onWebSocketEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len); void onWebSocketConnect(AsyncWebSocketClient* client); void onWebSocketDisconnect(AsyncWebSocketClient* client); void onWebSocketReceived(AsyncWebSocketClient* client, void* arg, uint8_t* data, size_t len); void handleClientIdentification(AsyncWebSocketClient* client, JsonDocument& command); // Command processing - unified for both MQTT and WebSocket with grouped commands JsonDocument parsePayload(char* payload); void handleCommand(JsonDocument& command, const MessageContext& context); // ═════════════════════════════════════════════════════════════════════════════════ // GROUPED COMMAND HANDLERS // ═════════════════════════════════════════════════════════════════════════════════ // System commands void handleSystemCommand(JsonVariant contents, const MessageContext& context); void handleSystemInfoCommand(JsonVariant contents, const MessageContext& context); void handlePlaybackCommand(JsonVariant contents, const MessageContext& context); void handleFileManagerCommand(JsonVariant contents, const MessageContext& context); void handleRelaySetupCommand(JsonVariant contents, const MessageContext& context); void handleClockSetupCommand(JsonVariant contents, const MessageContext& context); // System sub-commands void handlePingCommand(const MessageContext& context); void handleStatusCommand(const MessageContext& context); void handleIdentifyCommand(JsonVariant contents, const MessageContext& context); void handleGetDeviceTimeCommand(const MessageContext& context); void handleGetClockTimeCommand(const MessageContext& context); // Firmware management commands void handleCommitFirmwareCommand(const MessageContext& context); void handleRollbackFirmwareCommand(const MessageContext& context); void handleGetFirmwareStatusCommand(const MessageContext& context); // Network configuration command void handleSetNetworkConfigCommand(JsonVariant contents, const MessageContext& context); // File Manager sub-commands void handleListMelodiesCommand(const MessageContext& context); void handleDownloadMelodyCommand(JsonVariant contents, const MessageContext& context); void handleDeleteMelodyCommand(JsonVariant contents, const MessageContext& context); // Relay Setup sub-commands void handleSetRelayTimersCommand(JsonVariant contents, const MessageContext& context); void handleSetRelayOutputsCommand(JsonVariant contents, const MessageContext& context); // Clock Setup sub-commands void handleSetClockOutputsCommand(JsonVariant contents, const MessageContext& context); void handleSetClockTimingsCommand(JsonVariant contents, const MessageContext& context); void handleSetClockAlertsCommand(JsonVariant contents, const MessageContext& context); void handleSetClockBacklightCommand(JsonVariant contents, const MessageContext& context); void handleSetClockSilenceCommand(JsonVariant contents, const MessageContext& context); void handleSetRtcTimeCommand(JsonVariant contents, const MessageContext& context); void handleSetPhysicalClockTimeCommand(JsonVariant contents, const MessageContext& context); void handlePauseClockUpdatesCommand(JsonVariant contents, const MessageContext& context); void handleSetClockEnabledCommand(JsonVariant contents, const MessageContext& context); // Utility methods String getPayloadContent(char* data, size_t len); int extractBellNumber(const String& key); // Extract bell number from "b1", "c1", etc. };