#include "SerialService.h" #include #include #ifndef MqttService_h #define MqttService_h #define WIFI_FAIXA "100" const String TopicoRecepcao = "disp/tx/"; const String TopicoTransmissao = "disp/rx/"; unsigned long ultimaTentativaConexao = 0; // Tempo da última tentativa de conexão const unsigned long intervaloTentativa = 5000; // 5 segundos class MqttService { private: const char* server = "192.168." WIFI_FAIXA ".105"; int port = 1883; const char* user = ""; const char* password = ""; String mqtt_mod_id; // Alterado para String WiFiClient wifiClient; PubSubClient mqttClient; // Ponteiros para funções de callback void (*messageCallback)(ProtocoloSerial) = nullptr; public: bool MqttIsConnected = false; MqttService() : mqttClient(wifiClient) { mqttClient.setServer(server, port); mqttClient.setBufferSize(2048); mqttClient.setCallback([this](char* topic, byte* payload, unsigned int length) { this->processMessage(topic, payload, length); }); } void setModID(const String& mqtt_id) { mqtt_mod_id = mqtt_id; // Atribui diretamente a String } void setMessageCallback(void (*callback)(ProtocoloSerial)) { messageCallback = callback; } bool InicializarComunicacaoMqtt() { // Verifica se já passou o intervalo necessário para uma nova tentativa if (millis() - ultimaTentativaConexao < intervaloTentativa) { PrintTela("Aguardando para próxima tentativa de conexão MQTT..."); return MqttIsConnected; // Retorna o estado atual sem tentar reconectar } ultimaTentativaConexao = millis(); // Atualiza o tempo da última tentativa connect(); if (MqttIsConnected) { PrintTela("Tamanho máximo de mensagens: " + String(mqttClient.getBufferSize())); LimparMensagensRetidas(TopicoRecepcao + mqtt_mod_id); // Limpa mensagens retidas subscribe(TopicoRecepcao); } return MqttIsConnected; } void connect() { while (!mqttClient.connected()) { PrintTela("Conectando ao broker MQTT...", false); //if (mqttClient.connect(mqtt_mod_id.c_str(), user, password)) { if (mqttClient.connect(mqtt_mod_id.c_str())) { PrintTela("Conectado ao broker MQTT!"); MqttIsConnected = true; } else { PrintTela("Falha ao conectar, rc=", false); PrintTela((String)mqttClient.state()); MqttIsConnected = false; delay(2000); } } } void LimparMensagensRetidas(const String& topico) { if (mqttClient.connected()) { // Publica uma mensagem vazia com o flag Retain para limpar mensagens retidas if (mqttClient.publish(topico.c_str(), "", true)) { Serial.println("Mensagem retida limpa no tópico: " + topico); } else { Serial.println("Falha ao limpar mensagem retida no tópico: " + topico); } } else { Serial.println("Broker MQTT desconectado, não foi possível limpar mensagens retidas."); } } void subscribe(String topico) { String fullTopic = topico + mqtt_mod_id; // Concatena o ID ao tópico base mqttClient.subscribe(fullTopic.c_str()); PrintTela("Inscrito no tópico: ", false); PrintTela(fullTopic); } void unsubscribe(String topico) { String fullTopic = topico + mqtt_mod_id; // Concatena o ID ao tópico base mqttClient.unsubscribe(fullTopic.c_str()); // Remove a inscrição de cada tópico PrintTela("Desinscrito do tópico: ", false); PrintTela(fullTopic); } bool publish(String message) { String fullTopic = TopicoTransmissao + mqtt_mod_id; // Concatena o ID ao tópico base // Verifica se está conectado ao broker antes de tentar publicar if (mqttClient.connected()) { bool success = mqttClient.publish(fullTopic.c_str(), message.c_str(), true); // Publica a mensagem if (success) { PrintTela("Mensagem enviada com sucesso para ", false); } else { PrintTela("Falha ao enviar mensagem para ", false); } PrintTela(fullTopic, false); // Imprime o tópico completo para verificação PrintTela(": ", false); PrintTela(message); return success; } else { PrintTela("Erro: Conexão com o broker MQTT perdida. Tentando reconectar..."); InicializarComunicacaoMqtt(); // Tenta reconectar return false; } } void loop() { if (!mqttClient.connected() && millis() - ultimaTentativaConexao >= intervaloTentativa) { InicializarComunicacaoMqtt(); } mqttClient.loop(); } void EnviarDados(String Mod_ID, String Mensagem) { if (MqttIsConnected) { String ProtocoloEnvio = Mod_ID + SplitMessage + Mensagem; publish(ProtocoloEnvio); } } // Processa a mensagem recebida e aciona o callback correspondente void processMessage(char* topic, byte* payload, unsigned int length) { String topicStr(topic); String message; for (unsigned int i = 0; i < length; i++) { message += (char)payload[i]; } PrintTela("Mensagem recebida no tópico ", false); PrintTela(topicStr, false); PrintTela(": ", false); PrintTela(message); if (topicStr == TopicoRecepcao + mqtt_mod_id) { std::vector Partes = SplitString(message, SplitMessage); if (Partes.size() == 4) { ProtocoloSerial objeto; objeto.idMensagem = Partes[0].toInt(); objeto.Mod_ID = Partes[1]; objeto.funcao = (F_Code)(Partes[2].toInt()); objeto.protocolo = Partes[3]; if (mqtt_mod_id == objeto.Mod_ID && messageCallback) { messageCallback(objeto); } } } } }; #endif