139 lines
4.5 KiB
C++
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
|