#ifdef ENABLE_MQTT // sample schema's to use: https://www.home-assistant.io/integrations/light.mqtt/ #include // Setup the MQTT client class by passing in the WiFi client PubSubClient mqtt(net); String deviceprefix; long logtimerMillis = 0; void mqtt_subscribe(const String& topic) { mqtt.subscribe(topic.c_str()); PRINTLN_SERIAL("Subscribed to " + topic); } void mqtt_publish(const String& topic, const String& message) { mqtt.publish(topic.c_str(), message.c_str()); PRINTLN_SERIAL("Published " + topic + ": " + message); } /* * Callback routine is called when a topic we subscribed to got a message */ void mqtt_callback(char* topic, byte* payload, unsigned int length) { String fulltopic((char*)0); String shorttopic((char*)0); String message((char*)0); fulltopic.reserve(strlen(topic)); fulltopic = String(topic); // If deviceprefix is in topic, subtract it // Could do a similar thing for grouptopics if we implement them shorttopic.reserve(strlen(topic)); shorttopic = String(topic); shorttopic.replace(deviceprefix, ""); // Decode message into string message.reserve(length); for (int i = 0; i < length; i++) { message += (char)payload[i]; } PRINT_SERIAL(F("Received MQTT ")); APPEND_SERIAL(fulltopic); APPEND_SERIAL(F(": ")); APPENDLN_SERIAL(message); // Deal with global topic messages if(fulltopic.equals(MQTT_PREFIX "ping")) { mqtt_publish(deviceprefix + "pong", "This is " + settings.name + " v" + FW_VERSION + " at " + settings.ip); // Next quietly ignore all the things we send out ourselves } else if(shorttopic.equals(F("pong"))) { // Ignore quietly //NOP; // delay 62.5ns on a 16MHz AtMega } else if(shorttopic.equals(F("log"))) { // Ignore quietly //NOP; // delay 62.5ns on a 16MHz AtMega // And now to add a catchall to hand off to other module } else { module_message(shorttopic, message); } } void mqtt_connect() { /* bool success= false; success = net.connect(MQTT_SERVER, MQTT_SERVERPORT); if (success) { PRINTLN_SERIAL("Connection complete, valid cert, valid fingerprint."); } else { PRINTLN_SERIAL("Connection failed!"); } */ PRINTLN_SERIAL("prepare mqtt connect check net.status: " + String(net.status())); mqtt.setServer(MQTT_SERVER, MQTT_SERVERPORT); mqtt.setCallback(mqtt_callback); PRINTLN_SERIAL("before mqtt connect check net.status: " + String(net.status())); while (!mqtt.connected()) { PRINTLN_SERIAL("MQTT not connected, connecting..."); PRINTLN_SERIAL("while mqtt connecting check net.status: " + String(net.status())); // Attempt to connect // Note - the default maximum packet size is 128 bytes. If the // combined length of clientId, username and password exceed this, // you will need to increase the value of MQTT_MAX_PACKET_SIZE in // PubSubClient.h if (mqtt.connect(settings.name.c_str(), MQTT_USERNAME, MQTT_PASSWORD)) { PRINTLN_SERIAL("MQTT connected"); PRINTLN_SERIAL("mqtt just connected check net.status: " + String(net.status())); } else { PRINTLN_SERIAL("MQTT connection failed, rc=" + String(mqtt.state()) + "..."); PRINTLN_SERIAL("mqtt failed connected check net.status: " + String(net.status())); delay(10000); // @@@FIXME@@@ delays are not cool } // (re)subscribe to the topics we need deviceprefix = MQTT_PREFIX; deviceprefix = deviceprefix + settings.name + "/"; mqtt_subscribe(MQTT_PREFIX "ping"); // global topic: send a ping, and we will respond with some device info mqtt_subscribe(deviceprefix + "#"); mqtt_publish(deviceprefix + "log", "Connected " + settings.name + " running v" + FW_VERSION + " at " + settings.ip); mqtt_publish(deviceprefix + "log", "Free Heap: " + String(ESP.getFreeHeap())); PRINTLN_SERIAL("after mqtt connect check net.status: " + String(net.status())); } } void mqtt_setup() { PRINTLN_SERIAL("Initialising MQTT"); } void mqtt_loop() { long currentMillis = millis(); // Check for MQTT instructions if(!mqtt.connected()) { mqtt_connect(); } else { mqtt.loop(); // every 5 minutes (300000 milliseconds) if(currentMillis - logtimerMillis > 300000) { // reset timer logtimerMillis = currentMillis; // log something mqtt_publish(deviceprefix + "log", "Free Heap: " + String(ESP.getFreeHeap())); } } } #endif