Adding to repo
This commit is contained in:
158
30_interface_mqtt.ino
Normal file
158
30_interface_mqtt.ino
Normal file
@@ -0,0 +1,158 @@
|
||||
#ifdef ENABLE_MQTT
|
||||
|
||||
/*
|
||||
* Define a function newcmd in your module to be able to accept mqtt commands
|
||||
* Syntax and parameters are like this:
|
||||
*/
|
||||
void newcmd(String cmd);
|
||||
void module_message(const String& shorttopic, const String& message);
|
||||
|
||||
#include <PubSubClient.h>
|
||||
|
||||
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
|
||||
PubSubClient mqtt(net);
|
||||
String deviceprefix;
|
||||
|
||||
const char* fingerprint = "EA:2A:2B:80:C1:00:57:35:66:26:FF:FC:FA:27:EA:5F:3D:91:5A:F9";
|
||||
|
||||
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 WifiMQTTconnect() {
|
||||
|
||||
if(WiFi.status() != WL_CONNECTED) {
|
||||
PRINTLN_SERIAL("Wifi not connected, connecting...");
|
||||
WiFi.mode(WIFI_STA); // Weird MQTT connection bug, https://github.com/knolleary/pubsubclient/issues/138#issuecomment-326113915
|
||||
WiFi.begin(WLAN_SSID, WLAN_PASS);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
PRINTLN_SERIAL("Waiting for Wifi...");
|
||||
delay(500);
|
||||
}
|
||||
settings.ip = WiFi.localIP().toString();
|
||||
PRINTLN_SERIAL("Wifi connected");
|
||||
}
|
||||
|
||||
PRINT_SERIAL("Setting time using SNTP");
|
||||
configTime(-5 * 3600, 0, "pool.ntp.org", "time.nist.gov");
|
||||
now = time(nullptr);
|
||||
while (now < 1510592825) {
|
||||
delay(500);
|
||||
APPEND_SERIAL(".");
|
||||
now = time(nullptr);
|
||||
}
|
||||
APPENDLN_SERIAL(" done!");
|
||||
struct tm timeinfo;
|
||||
gmtime_r(&now, &timeinfo);
|
||||
PRINT_SERIAL("Current time: ");
|
||||
APPENDLN_SERIAL(asctime(&timeinfo));
|
||||
net.setInsecure(); // verification options set to none
|
||||
mqtt.setServer(MQTT_SERVER, MQTT_SERVERPORT);
|
||||
mqtt.setCallback(mqtt_callback);
|
||||
|
||||
if(!mqtt.connected()) {
|
||||
while (!mqtt.connected()) {
|
||||
PRINTLN_SERIAL("MQTT not connected, connecting...");
|
||||
|
||||
// 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");
|
||||
} else {
|
||||
PRINTLN_SERIAL("MQTT connection failed, rc=" + String(mqtt.state()) + "...");
|
||||
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", "Booting up " + settings.name + " running v" + FW_VERSION + " at " + settings.ip);
|
||||
mqtt_publish(deviceprefix + "log", "Free Heap: " + String(ESP.getFreeHeap()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void mqtt_setup() {
|
||||
PRINTLN_SERIAL(devname + "initialising module MQTT");
|
||||
}
|
||||
|
||||
void mqtt_loop() {
|
||||
long currentMillis = millis();
|
||||
|
||||
// Check for MQTT instructions
|
||||
if(!mqtt.connected()) {
|
||||
WifiMQTTconnect();
|
||||
} 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
|
||||
Reference in New Issue
Block a user