Merge pull request #10 from adafruit/3.1.1

MQTT 3.1.1 Support
This commit is contained in:
Todd Treece 2015-10-22 14:36:35 -04:00
commit 97afcf92c5
11 changed files with 399 additions and 157 deletions

View File

@ -70,50 +70,85 @@ static uint8_t *stringprint_P(uint8_t *p, const char *s, uint16_t maxlen=0) {
// Adafruit_MQTT Definition ////////////////////////////////////////////////////
Adafruit_MQTT::Adafruit_MQTT(const char *server, uint16_t port, const char *cid,
const char *user, const char *pass) {
Adafruit_MQTT::Adafruit_MQTT(const char *server,
uint16_t port,
const char *cid,
const char *user,
const char *pass) {
servername = server;
portnum = port;
clientid = cid;
username = user;
password = pass;
// reset subscriptions
for (uint8_t i=0; i<MAXSUBSCRIPTIONS; i++) {
subscriptions[i] = 0;
}
packet_id_counter = 0;
}
Adafruit_MQTT::Adafruit_MQTT(const __FlashStringHelper *server, uint16_t port, const __FlashStringHelper *cid,
const __FlashStringHelper *user, const __FlashStringHelper *pass) {
Adafruit_MQTT::Adafruit_MQTT(const __FlashStringHelper *server,
uint16_t port,
const __FlashStringHelper *cid,
const __FlashStringHelper *user,
const __FlashStringHelper *pass) {
servername = (const char *)server;
portnum = port;
clientid = (const char *)cid;
username = (const char *)user;
password = (const char *)pass;
// reset subscriptions
for (uint8_t i=0; i<MAXSUBSCRIPTIONS; i++) {
subscriptions[i] = 0;
}
packet_id_counter = 0;
}
/*
Adafruit_MQTT::Adafruit_MQTT(char *server, uint16_t port, char *cid, char *user, char *pass) {
strncpy(servername, server, SERVERNAME_SIZE);
servername[SERVERNAME_SIZE-1] = 0;
Adafruit_MQTT::Adafruit_MQTT(const char *server,
uint16_t port,
const char *user,
const char *pass) {
servername = server;
portnum = port;
serverip = 0;
clientid = "";
username = user;
password = pass;
strncpy(clientid, cid, CLIENTID_SIZE);
clientid[CLIENTID_SIZE-1] = 0;
// reset subscriptions
for (uint8_t i=0; i<MAXSUBSCRIPTIONS; i++) {
subscriptions[i] = 0;
}
strncpy(username, user, USERNAME_SIZE);
username[USERNAME_SIZE-1] = 0;
packet_id_counter = 0;
}
Adafruit_MQTT::Adafruit_MQTT(const __FlashStringHelper *server,
uint16_t port,
const __FlashStringHelper *user,
const __FlashStringHelper *pass) {
servername = (const char *)server;
portnum = port;
clientid = "";
username = (const char *)user;
password = (const char *)pass;
// reset subscriptions
for (uint8_t i=0; i<MAXSUBSCRIPTIONS; i++) {
subscriptions[i] = 0;
}
packet_id_counter = 0;
strncpy(password, pass, PASSWORD_SIZE);
password[PASSWORD_SIZE-1] = 0;
}
*/
int8_t Adafruit_MQTT::connect() {
// Connect to the server.
@ -144,13 +179,18 @@ int8_t Adafruit_MQTT::connect() {
if (!sendPacket(buffer, len))
return -1;
// Get SUBACK
len = readPacket(buffer, 5, CONNECT_TIMEOUT_MS);
DEBUG_PRINT(F("SUBACK:\t"));
DEBUG_PRINTBUFFER(buffer, len);
if ((len != 5) || (buffer[0] != (MQTT_CTRL_SUBACK << 4))) {
return 6; // failure to subscribe
}
// Check for SUBACK if using MQTT 3.1.1 or higher
// TODO: The Server is permitted to start sending PUBLISH packets matching the
// Subscription before the Server sends the SUBACK Packet.
// if(MQTT_PROTOCOL_LEVEL > 3) {
// len = readPacket(buffer, 5, CONNECT_TIMEOUT_MS);
// DEBUG_PRINT(F("SUBACK:\t"));
// DEBUG_PRINTBUFFER(buffer, len);
// if ((len != 5) || (buffer[0] != (MQTT_CTRL_SUBACK << 4))) {
// return 6; // failure to subscribe
// }
// }
}
return 0;
@ -169,6 +209,18 @@ const __FlashStringHelper* Adafruit_MQTT::connectErrorString(int8_t code) {
}
}
bool Adafruit_MQTT::disconnect() {
// Construct and send disconnect packet.
uint8_t len = disconnectPacket(buffer);
if (! sendPacket(buffer, len))
DEBUG_PRINTLN(F("Unable to send disconnect packet"));
return disconnectServer();
}
bool Adafruit_MQTT::publish(const char *topic, const char *data, uint8_t qos) {
// Construct and send publish packet.
uint8_t len = publishPacket(buffer, topic, data, qos);
@ -186,6 +238,22 @@ bool Adafruit_MQTT::publish(const char *topic, const char *data, uint8_t qos) {
return true;
}
bool Adafruit_MQTT::will(const char *topic, const char *payload, uint8_t qos, uint8_t retain) {
if (connected()) {
DEBUG_PRINT(F("Will defined after connect"));
return false;
}
will_topic = topic;
will_payload = payload;
will_qos = qos;
will_retain = retain;
return true;
}
bool Adafruit_MQTT::subscribe(Adafruit_MQTT_Subscribe *sub) {
uint8_t i;
// see if we are already subscribed
@ -209,6 +277,50 @@ bool Adafruit_MQTT::subscribe(Adafruit_MQTT_Subscribe *sub) {
return false;
}
bool Adafruit_MQTT::unsubscribe(Adafruit_MQTT_Subscribe *sub) {
uint8_t i;
// see if we are already subscribed
for (i=0; i<MAXSUBSCRIPTIONS; i++) {
if (subscriptions[i] == sub) {
DEBUG_PRINTLN(F("Found matching subscription and attempting to unsubscribe."));
// Construct and send unsubscribe packet.
uint8_t len = unsubscribePacket(buffer, subscriptions[i]->topic);
// sending unsubscribe failed
if (! sendPacket(buffer, len))
return false;
// if QoS for this subscription is 1 or 2, we need
// to wait for the unsuback to confirm unsubscription
if(subscriptions[i]->qos > 0 && MQTT_PROTOCOL_LEVEL > 3) {
// wait for UNSUBACK
len = readPacket(buffer, 5, CONNECT_TIMEOUT_MS);
DEBUG_PRINT(F("UNSUBACK:\t"));
DEBUG_PRINTBUFFER(buffer, len);
if ((len != 5) || (buffer[0] != (MQTT_CTRL_UNSUBACK << 4))) {
return false; // failure to unsubscribe
}
}
subscriptions[i] = 0;
return true;
}
}
// subscription not found, so we are unsubscribed
return true;
}
Adafruit_MQTT_Subscribe *Adafruit_MQTT::readSubscription(int16_t timeout) {
uint8_t i, topiclen, datalen;
@ -256,18 +368,27 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::readSubscription(int16_t timeout) {
return subscriptions[i];
}
bool Adafruit_MQTT::ping(uint8_t times) {
while (times) {
void Adafruit_MQTT::flushIncoming(uint16_t timeout) {
// flush input!
DEBUG_PRINTLN(F("Flushing input buffer"));
while (readPacket(buffer, MAXBUFFERSIZE, timeout));
}
bool Adafruit_MQTT::ping(uint8_t num) {
flushIncoming(100);
while (num--) {
// Construct and send ping packet.
uint8_t len = pingPacket(buffer);
if (!sendPacket(buffer, len))
return false;
continue;
// Process ping reply.
len = readPacket(buffer, 2, PING_TIMEOUT_MS);
if (buffer[0] == (MQTT_CTRL_PINGRESP << 4))
return true;
}
return false;
}
@ -287,31 +408,64 @@ uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) {
p+=2;
// fill in packet[1] last
#if (MQTT_PROTOCOL_LEVEL == 4)
p = stringprint_P(p, PSTR("MQTT"));
#elif (MQTT_PROTOCOL_LEVEL == 3)
p = stringprint_P(p, PSTR("MQIsdp"));
#if MQTT_PROTOCOL_LEVEL == 3
p = stringprint_P(p, PSTR("MQIsdp"));
#elif MQTT_PROTOCOL_LEVEL == 4
p = stringprint_P(p, PSTR("MQTT"));
#else
#error "No MQTT version selected!"
#error "MQTT level not supported"
#endif
p[0] = MQTT_PROTOCOL_LEVEL;
p++;
// always clean the session
p[0] = MQTT_CONN_CLEANSESSION;
// set the will flags if needed
if (will_topic && pgm_read_byte(will_topic) != 0) {
p[0] |= MQTT_CONN_WILLFLAG;
if(will_qos == 1)
p[0] |= MQTT_CONN_WILLQOS_1;
else if(will_qos == 2)
p[0] |= MQTT_CONN_WILLQOS_2;
if(will_retain == 1)
p[0] |= MQTT_CONN_WILLRETAIN;
}
if (pgm_read_byte(username) != 0)
p[0] |= MQTT_CONN_USERNAMEFLAG;
if (pgm_read_byte(password) != 0)
p[0] |= MQTT_CONN_PASSWORDFLAG;
p++;
// TODO: add WILL support?
p[0] = MQTT_CONN_KEEPALIVE >> 8;
p++;
p[0] = MQTT_CONN_KEEPALIVE & 0xFF;
p++;
p = stringprint_P(p, clientid, 23); // Limit client ID to first 23 characters.
if(MQTT_PROTOCOL_LEVEL == 3) {
p = stringprint_P(p, clientid, 23); // Limit client ID to first 23 characters.
} else {
if (pgm_read_byte(clientid) != 0) {
p = stringprint_P(p, clientid);
} else {
p[0] = 0x0;
p++;
p[0] = 0x0;
p++;
DEBUG_PRINTLN(F("SERVER GENERATING CLIENT ID"));
}
}
if (will_topic && pgm_read_byte(will_topic) != 0) {
p = stringprint_P(p, will_topic);
p = stringprint_P(p, will_payload);
}
if (pgm_read_byte(username) != 0) {
p = stringprint_P(p, username);
@ -337,6 +491,16 @@ uint8_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic,
// fill in packet[1] last
p+=2;
// add packet identifier. used for checking PUBACK in QOS > 0
if(qos > 0) {
p[0] = (packet_id_counter >> 8) & 0xFF;
p[1] = packet_id_counter & 0xFF;
p+=2;
// increment the packet id
packet_id_counter++;
}
p = stringprint_P(p, topic);
memcpy(p, data, strlen(data));
@ -357,11 +521,14 @@ uint8_t Adafruit_MQTT::subscribePacket(uint8_t *packet, const char *topic,
// fill in packet[1] last
p+=2;
// put in a message id,
p[0] = 0xAD;
p[1] = 0xAF;
// packet identifier. used for checking SUBACK
p[0] = (packet_id_counter >> 8) & 0xFF;
p[1] = packet_id_counter & 0xFF;
p+=2;
// increment the packet id
packet_id_counter++;
p = stringprint_P(p, topic);
p[0] = qos;
@ -374,6 +541,33 @@ uint8_t Adafruit_MQTT::subscribePacket(uint8_t *packet, const char *topic,
return len;
}
uint8_t Adafruit_MQTT::unsubscribePacket(uint8_t *packet, const char *topic) {
uint8_t *p = packet;
uint16_t len;
p[0] = MQTT_CTRL_UNSUBSCRIBE << 4 | 0x1;
// fill in packet[1] last
p+=2;
// packet identifier. used for checking UNSUBACK
p[0] = (packet_id_counter >> 8) & 0xFF;
p[1] = packet_id_counter & 0xFF;
p+=2;
// increment the packet id
packet_id_counter++;
p = stringprint_P(p, topic);
len = p - packet;
packet[1] = len-2; // don't include the 2 bytes of fixed header data
DEBUG_PRINTLN(F("MQTT unsubscription packet:"));
DEBUG_PRINTBUFFER(buffer, len);
return len;
}
uint8_t Adafruit_MQTT::pingPacket(uint8_t *packet) {
packet[0] = MQTT_CTRL_PINGREQ << 4;
packet[1] = 0;
@ -382,6 +576,13 @@ uint8_t Adafruit_MQTT::pingPacket(uint8_t *packet) {
return 2;
}
uint8_t Adafruit_MQTT::disconnectPacket(uint8_t *packet) {
packet[0] = MQTT_CTRL_DISCONNECT << 4;
packet[1] = 0;
DEBUG_PRINTLN(F("MQTT disconnect packet:"));
DEBUG_PRINTBUFFER(buffer, 2);
return 2;
}
// Adafruit_MQTT_Publish Definition ////////////////////////////////////////////

View File

@ -48,20 +48,27 @@
// Use 3 (MQTT 3.0) or 4 (MQTT 3.1.1)
#define MQTT_PROTOCOL_LEVEL 4
#define MQTT_CTRL_CONNECT 0x01
#define MQTT_CTRL_CONNECTACK 0x02
#define MQTT_CTRL_PUBLISH 0x03
#define MQTT_CTRL_SUBSCRIBE 0x08
#define MQTT_CTRL_SUBACK 0x09
#define MQTT_CTRL_PINGREQ 0x0C
#define MQTT_CTRL_PINGRESP 0x0D
#define MQTT_CTRL_CONNECT 0x1
#define MQTT_CTRL_CONNECTACK 0x2
#define MQTT_CTRL_PUBLISH 0x3
#define MQTT_CTRL_PUBACK 0x4
#define MQTT_CTRL_PUBREC 0x5
#define MQTT_CTRL_PUBREL 0x6
#define MQTT_CTRL_PUBCOMP 0x7
#define MQTT_CTRL_SUBSCRIBE 0x8
#define MQTT_CTRL_SUBACK 0x9
#define MQTT_CTRL_UNSUBSCRIBE 0xA
#define MQTT_CTRL_UNSUBACK 0xB
#define MQTT_CTRL_PINGREQ 0xC
#define MQTT_CTRL_PINGRESP 0xD
#define MQTT_CTRL_DISCONNECT 0xE
#define MQTT_QOS_1 0x1
#define MQTT_QOS_0 0x0
#define CONNECT_TIMEOUT_MS 3000
#define PUBLISH_TIMEOUT_MS 500
#define PING_TIMEOUT_MS 500
#define PING_TIMEOUT_MS 500
// Adjust as necessary, in seconds. Default to 5 minutes.
#define MQTT_CONN_KEEPALIVE 300
@ -71,15 +78,15 @@
// 23 char client ID.
#define MAXBUFFERSIZE (125)
#define MQTT_CONN_USERNAMEFLAG 0x80
#define MQTT_CONN_PASSWORDFLAG 0x40
#define MQTT_CONN_WILLRETAIN 0x20
#define MQTT_CONN_WILLQOS 0x08
#define MQTT_CONN_WILLFLAG 0x04
#define MQTT_CONN_CLEANSESSION 0x02
#define MQTT_CONN_USERNAMEFLAG 0x80
#define MQTT_CONN_PASSWORDFLAG 0x40
#define MQTT_CONN_WILLRETAIN 0x20
#define MQTT_CONN_WILLQOS_1 0x08
#define MQTT_CONN_WILLQOS_2 0x18
#define MQTT_CONN_WILLFLAG 0x04
#define MQTT_CONN_CLEANSESSION 0x02
// how many subscriptions we want to be able to
// track
// how many subscriptions we want to be able to track
#define MAXSUBSCRIPTIONS 5
// how much data we save in a subscription object
@ -93,10 +100,24 @@ class Adafruit_MQTT_Subscribe; // forward decl
class Adafruit_MQTT {
public:
Adafruit_MQTT(const char *server, uint16_t port, const char *cid,
const char *user, const char *pass);
Adafruit_MQTT(const __FlashStringHelper *server, uint16_t port, const __FlashStringHelper *cid,
const __FlashStringHelper *user, const __FlashStringHelper *pass);
Adafruit_MQTT(const char *server,
uint16_t port,
const char *cid,
const char *user,
const char *pass);
Adafruit_MQTT(const __FlashStringHelper *server,
uint16_t port,
const __FlashStringHelper *cid,
const __FlashStringHelper *user,
const __FlashStringHelper *pass);
Adafruit_MQTT(const char *server,
uint16_t port,
const char *user,
const char *pass);
Adafruit_MQTT(const __FlashStringHelper *server,
uint16_t port,
const __FlashStringHelper *user,
const __FlashStringHelper *pass);
virtual ~Adafruit_MQTT() {}
// Connect to the MQTT server. Returns 0 on success, otherwise an error code
@ -118,13 +139,20 @@ class Adafruit_MQTT {
// Serial.println without any further processing.
const __FlashStringHelper* connectErrorString(int8_t code);
// Disconnect from the MQTT server. Returns true if disconnected, false
// otherwise.
virtual bool disconnect() = 0; // Subclasses need to fill this in!
// Sends MQTT disconnect packet and calls disconnectServer()
bool disconnect();
// Return true if connected to the MQTT server, otherwise false.
virtual bool connected() = 0; // Subclasses need to fill this in!
// Set MQTT last will topic, payload, QOS, and retain. This needs
// to be called before connect() because it is sent as part of the
// connect control packet.
bool will(const char *topic, const char *payload, uint8_t qos = 0, uint8_t retain = 0);
bool will(const __FlashStringHelper *topic, const char *payload, uint8_t qos = 0, uint8_t retain = 0) {
return will((const char *)topic, payload, qos, retain);
}
// Publish a message to a topic using the specified QoS level. Returns true
// if the message was published, false otherwise.
// The topic must be stored in PROGMEM. It can either be a
@ -140,15 +168,17 @@ class Adafruit_MQTT {
// is made is not currently supported.
bool subscribe(Adafruit_MQTT_Subscribe *sub);
// Unsubscribe from a previously subscribed MQTT topic.
bool unsubscribe(Adafruit_MQTT_Subscribe *sub);
// Check if any subscriptions have new messages. Will return a reference to
// an Adafruit_MQTT_Subscribe object which has a new message. Should be called
// in the sketch's loop function to ensure new messages are recevied. Note
// that subscribe should be called first for each topic that receives messages!
Adafruit_MQTT_Subscribe *readSubscription(int16_t timeout=0);
// Ping the server to ensure the connection is still alive. Returns true if
// successful, otherwise false.
bool ping(uint8_t t);
// Ping the server to ensure the connection is still alive.
bool ping(uint8_t n = 1);
protected:
// Interface that subclasses need to implement:
@ -156,6 +186,9 @@ class Adafruit_MQTT {
// Connect to the server and return true if successful, false otherwise.
virtual bool connectServer() = 0;
// Disconnect from the MQTT server. Returns true if disconnected, false otherwise.
virtual bool disconnectServer() = 0; // Subclasses need to fill this in!
// Send data to the server specified by the buffer and length of data.
virtual bool sendPacket(uint8_t *buffer, uint8_t len) = 0;
@ -172,15 +205,24 @@ class Adafruit_MQTT {
const char *clientid;
const char *username;
const char *password;
const char *will_topic;
const char *will_payload;
uint8_t will_qos;
uint8_t will_retain;
uint8_t buffer[MAXBUFFERSIZE]; // one buffer, used for all incoming/outgoing
uint16_t packet_id_counter;
private:
Adafruit_MQTT_Subscribe *subscriptions[MAXSUBSCRIPTIONS];
void flushIncoming(uint16_t timeout);
// Functions to generate MQTT packets.
uint8_t connectPacket(uint8_t *packet);
uint8_t disconnectPacket(uint8_t *packet);
uint8_t publishPacket(uint8_t *packet, const char *topic, const char *payload, uint8_t qos);
uint8_t subscribePacket(uint8_t *packet, const char *topic, uint8_t qos);
uint8_t unsubscribePacket(uint8_t *packet, const char *topic);
uint8_t pingPacket(uint8_t *packet);
};

View File

@ -43,6 +43,12 @@ class Adafruit_MQTT_CC3000 : public Adafruit_MQTT {
cc3000(cc3k)
{}
Adafruit_MQTT_CC3000(Adafruit_CC3000 *cc3k, const char *server, uint16_t port,
const char *user, const char *pass):
Adafruit_MQTT(server, port, user, pass),
cc3000(cc3k)
{}
bool connectServer() {
uint32_t ip = 0;
@ -81,7 +87,7 @@ class Adafruit_MQTT_CC3000 : public Adafruit_MQTT {
return mqttclient.connected();
}
bool disconnect() {
bool disconnectServer() {
if (connected()) {
return (mqttclient.close() == 0);
}

View File

@ -33,7 +33,7 @@ bool Adafruit_MQTT_Client::connectServer() {
return r != 0;
}
bool Adafruit_MQTT_Client::disconnect() {
bool Adafruit_MQTT_Client::disconnectServer() {
// Stop connection if connected and return success (stop has no indication of
// failure).
if (client->connected()) {

View File

@ -36,14 +36,19 @@
class Adafruit_MQTT_Client : public Adafruit_MQTT {
public:
Adafruit_MQTT_Client(Client *client, const char *server, uint16_t port,
const char *cid, const char *user,
const char *pass):
const char *cid, const char *user, const char *pass):
Adafruit_MQTT(server, port, cid, user, pass),
client(client)
{}
Adafruit_MQTT_Client(Client *client, const char *server, uint16_t port,
const char *user, const char *pass):
Adafruit_MQTT(server, port, user, pass),
client(client)
{}
bool connectServer();
bool disconnect();
bool disconnectServer();
bool connected();
uint16_t readPacket(uint8_t *buffer, uint8_t maxlen, int16_t timeout,
bool checkForValidPubPacket = false);

View File

@ -41,6 +41,12 @@ class Adafruit_MQTT_FONA : public Adafruit_MQTT {
fona(f)
{}
Adafruit_MQTT_FONA(Adafruit_FONA *f, const char *server, uint16_t port,
const char *user, const char *pass):
Adafruit_MQTT(server, port, user, pass),
fona(f)
{}
bool connectServer() {
char server[40];
strncpy_P(server, servername, 40);
@ -51,7 +57,7 @@ class Adafruit_MQTT_FONA : public Adafruit_MQTT {
return fona->TCPconnect(server, portnum);
}
bool disconnect() {
bool disconnectServer() {
return fona->TCPclose();
}

View File

@ -45,18 +45,14 @@
// Setup the main CC3000 class, just like a normal CC3000 sketch.
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT);
// Store the MQTT server, client ID, username, and password in flash memory.
// Store the MQTT server, username, and password in flash memory.
// This is required for using the Adafruit MQTT library.
const char MQTT_SERVER[] PROGMEM = AIO_SERVER;
// Set a unique MQTT client ID using the AIO key + the date and time the sketch
// was compiled (so this should be unique across multiple devices for a user,
// alternatively you can manually set this to a GUID or other random value).
const char MQTT_CLIENTID[] PROGMEM = __TIME__ AIO_USERNAME;
const char MQTT_USERNAME[] PROGMEM = AIO_USERNAME;
const char MQTT_PASSWORD[] PROGMEM = AIO_KEY;
// Setup the CC3000 MQTT class by passing in the CC3000 class and MQTT server and login details.
Adafruit_MQTT_CC3000 mqtt(&cc3000, MQTT_SERVER, AIO_SERVERPORT, MQTT_CLIENTID, MQTT_USERNAME, MQTT_PASSWORD);
Adafruit_MQTT_CC3000 mqtt(&cc3000, MQTT_SERVER, AIO_SERVERPORT, MQTT_USERNAME, MQTT_PASSWORD);
// You don't need to change anything below this line!
#define halt(s) { Serial.println(F( s )); while(1); }
@ -109,16 +105,6 @@ void loop() {
// function definition further below.
MQTT_connect();
// Try to ping the MQTT server
/*
if (! mqtt.ping(3) ) {
// MQTT pings failed, let's reconnect by forcing a watchdog reset.
Serial.println("Ping fail! Resetting...");
Watchdog.enable(8000);
delay(10000);
}
*/
// this is our 'wait for incoming subscription packets' busy subloop
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(1000))) {
@ -137,6 +123,12 @@ void loop() {
} else {
Serial.println(F("OK!"));
}
// ping the server to keep the mqtt connection alive
if(! mqtt.ping()) {
Serial.println(F("MQTT Ping failed."));
}
}
// Function to connect and reconnect as necessary to the MQTT server.

View File

@ -35,18 +35,14 @@
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
// Store the MQTT server, client ID, username, and password in flash memory.
// Store the MQTT server, username, and password in flash memory.
// This is required for using the Adafruit MQTT library.
const char MQTT_SERVER[] PROGMEM = AIO_SERVER;
// Set a unique MQTT client ID using the AIO key + the date and time the sketch
// was compiled (so this should be unique across multiple devices for a user,
// alternatively you can manually set this to a GUID or other random value).
const char MQTT_CLIENTID[] PROGMEM = __TIME__ AIO_USERNAME;
const char MQTT_USERNAME[] PROGMEM = AIO_USERNAME;
const char MQTT_PASSWORD[] PROGMEM = AIO_KEY;
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, AIO_SERVERPORT, MQTT_CLIENTID, MQTT_USERNAME, MQTT_PASSWORD);
Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, AIO_SERVERPORT, MQTT_USERNAME, MQTT_PASSWORD);
/****************************** Feeds ***************************************/
@ -94,14 +90,6 @@ void loop() {
// function definition further below.
MQTT_connect();
// Try to ping the MQTT server
/*
if (! mqtt.ping(3) ) {
// MQTT pings failed, lets reconnect
Serial.println("Ping fail!");
}
*/
// this is our 'wait for incoming subscription packets' busy subloop
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(1000))) {
@ -121,7 +109,13 @@ void loop() {
Serial.println(F("OK!"));
}
// ping the server to keep the mqtt connection alive
if(! mqtt.ping()) {
mqtt.disconnect();
}
delay(1000);
}
// Function to connect and reconnect as necessary to the MQTT server.

View File

@ -92,13 +92,6 @@ void loop() {
// function definition further below.
MQTT_connect();
// Try to ping the MQTT server
if (! mqtt.ping(3) ) {
// MQTT pings failed, let's reconnect by forcing a watchdog reset.
Serial.println("Ping fail! Resetting...");
delay(10000);
}
// this is our 'wait for incoming subscription packets' busy subloop
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(1000))) {
@ -117,6 +110,12 @@ void loop() {
} else {
Serial.println(F("OK!"));
}
// ping the server to keep the mqtt connection alive
if(! mqtt.ping()) {
mqtt.disconnect();
}
}
// Function to connect and reconnect as necessary to the MQTT server.

View File

@ -52,18 +52,14 @@ Adafruit_FONA fona = Adafruit_FONA(FONA_RST);
/************ Global State (you don't need to change this!) ******************/
// Store the MQTT server, client ID, username, and password in flash memory.
// Store the MQTT server, username, and password in flash memory.
// This is required for using the Adafruit MQTT library.
const char MQTT_SERVER[] PROGMEM = AIO_SERVER;
// Set a unique MQTT client ID using the AIO key + the date and time the sketch
// was compiled (so this should be unique across multiple devices for a user,
// alternatively you can manually set this to a GUID or other random value).
const char MQTT_CLIENTID[] PROGMEM = __TIME__ AIO_USERNAME;
const char MQTT_USERNAME[] PROGMEM = AIO_USERNAME;
const char MQTT_PASSWORD[] PROGMEM = AIO_KEY;
// Setup the FONA MQTT class by passing in the FONA class and MQTT server and login details.
Adafruit_MQTT_FONA mqtt(&fona, MQTT_SERVER, AIO_SERVERPORT, MQTT_CLIENTID, MQTT_USERNAME, MQTT_PASSWORD);
Adafruit_MQTT_FONA mqtt(&fona, MQTT_SERVER, AIO_SERVERPORT, MQTT_USERNAME, MQTT_PASSWORD);
// You don't need to change anything below this line!
#define halt(s) { Serial.println(F( s )); while(1); }
@ -117,30 +113,10 @@ void loop() {
// Make sure to reset watchdog every loop iteration!
Watchdog.reset();
// check if we're still connected
if (!fona.TCPconnected() || (txfailures >= MAXTXFAILURES)) {
Serial.println(F("Connecting to MQTT..."));
int8_t ret, retries = 5;
while (retries && (ret = mqtt.connect()) != 0) {
Serial.println(mqtt.connectErrorString(ret));
Serial.println(F("Retrying MQTT connection"));
retries--;
if (retries == 0) halt("Resetting system");
delay(5000);
}
Serial.println(F("MQTT Connected!"));
txfailures = 0;
}
// Try to ping the MQTT server
/*
if (! mqtt.ping(3) ) {
// MQTT pings failed, lets reconnect
Serial.println("Ping fail!");
}
*/
// Ensure the connection to the MQTT server is alive (this will make the first
// connection and automatically reconnect when disconnected). See the MQTT_connect
// function definition further below.
MQTT_connect();
// this is our 'wait for incoming subscription packets' busy subloop
Adafruit_MQTT_Subscribe *subscription;
@ -162,4 +138,31 @@ void loop() {
Serial.println(F("OK!"));
txfailures = 0;
}
// ping the server to keep the mqtt connection alive
if(! mqtt.ping()) {
Serial.println(F("MQTT Ping failed."));
}
}
// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
int8_t ret;
// Stop if already connected.
if (mqtt.connected()) {
return;
}
Serial.print("Connecting to MQTT... ");
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
}
Serial.println("MQTT Connected!");
}

View File

@ -35,18 +35,14 @@
// Create a YunClient instance to communicate using the Yun's brighe & Linux OS.
YunClient client;
// Store the MQTT server, client ID, username, and password in flash memory.
// Store the MQTT server, username, and password in flash memory.
// This is required for using the Adafruit MQTT library.
const char MQTT_SERVER[] PROGMEM = AIO_SERVER;
// Set a unique MQTT client ID using the AIO key + the date and time the sketch
// was compiled (so this should be unique across multiple devices for a user,
// alternatively you can manually set this to a GUID or other random value).
const char MQTT_CLIENTID[] PROGMEM = __TIME__ AIO_USERNAME;
const char MQTT_USERNAME[] PROGMEM = AIO_USERNAME;
const char MQTT_PASSWORD[] PROGMEM = AIO_KEY;
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, AIO_SERVERPORT, MQTT_CLIENTID, MQTT_USERNAME, MQTT_PASSWORD);
Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, AIO_SERVERPORT, MQTT_USERNAME, MQTT_PASSWORD);
/****************************** Feeds ***************************************/
@ -78,14 +74,6 @@ void loop() {
// function definition further below.
MQTT_connect();
// Try to ping the MQTT server
/*
if (! mqtt.ping(3) ) {
// MQTT pings failed, lets reconnect
Console.println("Ping fail!");
}
*/
// this is our 'wait for incoming subscription packets' busy subloop
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(1000))) {
@ -105,7 +93,13 @@ void loop() {
Console.println(F("OK!"));
}
// ping the server to keep the mqtt connection alive
if(! mqtt.ping()) {
Serial.println(F("MQTT Ping failed."));
}
delay(1000);
}
// Function to connect and reconnect as necessary to the MQTT server.