Files
ESPGadget/30_interface_mqtt.ino

139 lines
4.5 KiB
C++

#ifdef ENABLE_MQTT
// sample schema's to use: https://www.home-assistant.io/integrations/light.mqtt/
#include <PubSubClient.h>
// 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