75 lines
2.2 KiB
C++

#pragma once
#include <AsyncMqttClient.h>
#include <ArduinoJson.h>
#define MAIN_TOPIC "homeassistant/+/" MAIN_DEVICE_ID "/#"
namespace Mqtt {
AsyncMqttClient client;
Task tReConnect(TASK_MINUTE, TASK_FOREVER, []{
Serial.println("Connecting to MQTT...");
client.connect();
});
void disconnect() {
client.unsubscribe(MAIN_TOPIC);
client.disconnect();
}
uint16_t publish(const char* topic, const char* message) {
return client.publish(topic, 0, true, message);
}
void publishInit() {
static bool firstTime = true;
if (firstTime) {
Component::components.forEach([](Component* c) { c->publishConfig(); });
AbstractBuilder::deleteAll();
firstTime = false;
}
}
void publishCleanupConfig() {
#if MQTT_CLEANUP
Component::components.forEach([](Component* c) { c->publishCleanupConfig(); });
#endif
}
void onMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
char msg[len + 1];
memcpy(msg, payload, len);
msg[len] = 0;
auto strTopic = string{ topic };
auto cmd = Command::mapCommands[strTopic];
if (cmd) cmd->onCommand(msg);
cmd = StateConfig::mapStateTopics[strTopic];
if (cmd) {
cmd->onCommand(msg);
StateConfig::mapStateTopics.erase(strTopic);
}
}
void setup(Scheduler* ts = nullptr, void(*onConnected)() = nullptr, void(*onDisconnected)() = nullptr) {
if (ts) ts->addTask(tReConnect);
Ha::publisher = publish;
client.onConnect([onConnected](bool sessionPresent) {
publishInit();
client.subscribe(MAIN_TOPIC, 0);
tReConnect.disable();
Serial.println("Connected to MQTT");
if (onConnected) onConnected();
});
client.onDisconnect([onDisconnected](AsyncMqttClientDisconnectReason reason) {
tReConnect.enableDelayed();
Serial.println("Disconnected from MQTT");
if (onDisconnected) onDisconnected();
});
client.onMessage(onMessage);
client.setServer(MQTT_HOST, MQTT_PORT);
}
}