Complete Rebuild, with Subsystems for each component. RTOS Tasks. (help by Claude)
This commit is contained in:
232
vesper/src/Communication/Communication.hpp
Normal file
232
vesper/src/Communication/Communication.hpp
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* ═══════════════════════════════════════════════════════════════════════════════════
|
||||
* 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.
|
||||
};
|
||||
Reference in New Issue
Block a user