#pragma once #define DEBUGLOG_DEFAULT_LOG_LEVEL_DEBUG #include #include #include #include #include #include #include #include typedef std::string topic_t; typedef std::function action_t; // the actions receive a JsonObject containing the received message typedef std::map action_map_t; class MQTTwrapper { private: const std::map stateMap = { {-4, "MQTT_CONNECTION_TIMEOUT"}, {-3, "MQTT_CONNECTION_LOST"}, {-2, "MQTT_CONNECT_FAILED"}, {-1, "MQTT_DISCONNECTED"}, {0, "MQTT_CONNECTED"}, {1, "MQTT_CONNECT_BAD_PROTOCOL"}, {2, "MQTT_CONNECT_BAD_CLIENT_ID"}, {3, "MQTT_CONNECT_UNAVAILABLE"}, {4, "MQTT_CONNECT_BAD_CREDENTIALS"}, {5, "MQTT_CONNECT_UNAUTHORIZED"} }; private: static MQTTwrapper * getInstance(MQTTwrapper *inst = nullptr) { static std::unique_ptr m_instance; if (inst) m_instance.reset(inst); if (m_instance) return m_instance.get(); return nullptr; } public: MQTTwrapper(); ~MQTTwrapper(); const bool connect(); const bool disconnect(); const bool connected(); const bool subscribe(topic_t topic, action_t action); const bool unsubscribe(topic_t topic); const bool publish(topic_t topic, const ArduinoJson::JsonDocument obj); private: static void callback(char *topic, uint8_t *payload, unsigned int length); // C-style callback only to invoke onMessage void onMessage(const std::string topic, const std::string message); // infinite loop to call the client loop method in a taskHandle static void clientLoop(void *params); private: const Config &m_config; action_map_t m_actionMap; NetworkClient m_tcp; PubSubClient m_client; TaskHandle_t m_loopHandle; };