233 lines
11 KiB
C++
233 lines
11 KiB
C++
/*
|
|
* ═══════════════════════════════════════════════════════════════════════════════════
|
|
* 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 <Arduino.h>
|
|
#include <AsyncMqttClient.h>
|
|
#include <ESPAsyncWebServer.h>
|
|
#include <AsyncUDP.h>
|
|
#include <ArduinoJson.h>
|
|
#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<uint8_t>& bellNumbers,
|
|
const std::vector<uint16_t>& 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.
|
|
};
|