Sensor3/lib/patrix/mqtt.cpp
2024-04-12 10:34:35 +02:00

105 lines
2.7 KiB
C++

#include "mqtt.h"
#include <WiFiClient.h>
#include "PubSubClient.h"
#include "console.h"
#include "wifi.h"
#include "log.h"
#include "config.h"
#define CONNECT_TIMEOUT_MILLISECONDS 5000
#define MQTT_HOST "10.0.0.50"
#define TOPIC_LOG_FORMAT "log/%s"
#define TOPIC_CMD_FORMAT "cmd/%s"
#define TOPIC_DATA_FORMAT "data/%s/%s"
unsigned long mqttLastConnectTry = 0;
WiFiClient espClient;
PubSubClient mqtt(espClient);
char logTopic[64] = "log/UNSET";
char cmdTopic[64] = "cmd/UNSET";
bool mqttConnected = false;
void mqttSetup() {
snprintf(logTopic, sizeof logTopic, TOPIC_LOG_FORMAT, HOSTNAME);
snprintf(cmdTopic, sizeof cmdTopic, TOPIC_CMD_FORMAT, HOSTNAME);
}
void mqttDisconnect() {
if (mqttConnected) {
info("MQTT disconnecting");
mqtt.disconnect();
mqttConnected = false;
}
}
void mqttLoop() {
const bool connected = mqtt.loop();
yield();
if (mqttConnected != connected) {
if (!connected) {
error("MQTT DISCONNECTED");
}
mqttConnected = connected;
}
if (isWiFiConnected() && isTimeSet() && !connected && (mqttLastConnectTry == 0 || millis() - mqttLastConnectTry > CONNECT_TIMEOUT_MILLISECONDS)) {
String host = configGetString("MQTT_HOST", MQTT_HOST, false);
error("Connecting MQTT host: %s", host.c_str());
mqttLastConnectTry = millis();
mqtt.setServer(host.c_str(), 1883);
if (!mqtt.connect(HOSTNAME, logTopic, 0, false, "MQTT disconnected")) {
error("MQTT FAILED TO CONNECT");
return;
}
info("MQTT CONNECTED");
mqtt.setKeepAlive(10);
mqtt.setBufferSize(512);
mqtt.subscribe(cmdTopic);
mqtt.setCallback([](const char *topic, const uint8_t *bytes, const unsigned int length) {
char content[64];
if (length > sizeof content - 1) {
error("MQTT RECEIVE BUFFER OVERFLOW");
return;
}
memcpy(content, bytes, length);
content[length] = 0;
if (strcmp(topic, cmdTopic) == 0) {
info("MQTT CMD > %s", content);
consoleHandle(content);
}
});
}
}
void mqttPublishLog(const char *datetime, const char *header, const char *message) {
if (mqtt.beginPublish(logTopic, strlen(datetime) + strlen(header) + strlen(message), false)) {
mqtt.print(datetime);
mqtt.print(header);
mqtt.print(message);
mqtt.endPublish();
yield();
}
}
bool mqttPublishData(const char *name, const JsonDocument &doc) {
if (mqtt.connected()) {
char topic[128];
snprintf(topic, sizeof topic, TOPIC_DATA_FORMAT, HOSTNAME, name);
char payload[512];
const size_t size = serializeJson(doc, payload);
boolean result = mqtt.publish(topic, payload, size);
yield();
return result;
}
return false;
}