#pragma once #include #include #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); } }