MQTT Last Will not published (ESP8266 Adafruit MQTT Library)

Moderators: adafruit_support_bill, adafruit

Forum rules
If you're posting code, please make sure your code does not include your Adafruit IO Active Key or WiFi network credentials.
Locked
User avatar
jalo1234
 
Posts: 1
Joined: Thu May 19, 2022 4:29 pm

MQTT Last Will not published (ESP8266 Adafruit MQTT Library)

Post by jalo1234 »

I can't get the last will to execute. Here is my example code, it publishes "ON", but does not publish "OFF" when disconnected.
I used the example code from the learn page.
To debug this I also turned on the debug print and got no errors regarding will.
To debug further I modified the following in Adafruit_MQTT.cpp around line 722:

Code: Select all

if (will_topic && pgm_read_byte(will_topic) != 0) {
    DEBUG_PRINTLN(F("custom: setting will in string"));
    p = stringprint(p, will_topic);
    p = stringprint(p, will_payload);
  }
And it does print the new debug statement I added, meaning the data was added to the packet.
I now suspect I either missed some configuration on Adafruit IO, or there is some bug in the library or the platform.

Here's my example code:

Code: Select all


//CODE I HAD TO ADD MYSELF
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

#define WLAN_SSID "redacted"
#define WLAN_PASS "redacted"
#define MQTT_CONN_KEEPALIVE 15
#define MQTT_SERV "io.adafruit.com"
#define MQTT_PORT 1883
#define AIO_USERNAME "redacted"
#define MQTT_PASS "redacted"

WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, MQTT_SERV, MQTT_PORT, "clientFoo" ,AIO_USERNAME, MQTT_PASS);
//END CODE I HAD TO ADD


/****************************** Feeds ***************************************/
// Setup a feed called 'photocell' for publishing.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
const char PHOTOCELL_FEED[] PROGMEM = AIO_USERNAME "/feeds/photocell";
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, PHOTOCELL_FEED, MQTT_QOS_1);

// Define a will
const char WILL_FEED[] PROGMEM = AIO_USERNAME "/feeds/test";
Adafruit_MQTT_Publish lastwill = Adafruit_MQTT_Publish(&mqtt, WILL_FEED, MQTT_QOS_1);
/*************************** Sketch Code ************************************/

// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
// for some reason (only affects ESP8266, likely an arduino-builder bug).
void MQTT_connect();

void setup() {
  Serial.begin(115200);
  delay(10);

  Serial.println(F("Adafruit MQTT with Will demo"));

  // Connect to WiFi access point.
  Serial.println(); Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);

  WiFi.begin(WLAN_SSID, WLAN_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.println("WiFi connected");
  Serial.println("IP address: "); Serial.println(WiFi.localIP());

  // Setup MQTT will to set on/off to "OFF" when we disconnect (with added debug prints)
  if(mqtt.will(WILL_FEED, "OFF")){
    Serial.println("will set successfully");
    }
  else{
    Serial.println("will set fail");
    } 
}

uint32_t x=0;

void loop() {
  // 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();
  
  lastwill.publish("ON");  // make sure we publish ON first thing after connecting
  
  
  
  // Now we can publish stuff!
  Serial.print(F("\nSending photocell val "));
  Serial.print(x);
  Serial.print("...");
  if (! photocell.publish(x++)) {
    Serial.println(F("Failed"));
  } else {
    Serial.println(F("OK!"));
  }
  
  delay(5000);
}

// 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... ");

  uint8_t retries = 3;
  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
       retries--;
       if (retries == 0) {
         // basically die and wait for WDT to reset me
         while (1);
       }
  }
  Serial.println("MQTT Connected!");
}

User avatar
brubell
Learn User Page
 
Posts: 2011
Joined: Fri Jul 17, 2015 10:33 pm

Re: MQTT Last Will not published (ESP8266 Adafruit MQTT Libr

Post by brubell »

Please first check that:
  • The last will topic must match the normal IO MQTT topic format for feeds or group publishes.
    Last will is only published by the MQTT broker if the client fails to disconnect cleanly by sending the MQTT disconnect packet.
    Last will is only published by the MQTT broker if the the keep alive timeout expires, and the last will is not sent if your device reconnects within the timeout window. The Adafruit MQTT Library for Arduino has a default keep alive timeout of 5 minutes.

Locked
Forum rules
If you're posting code, please make sure your code does not include your Adafruit IO Active Key or WiFi network credentials.

Return to “Internet of Things: Adafruit IO and Wippersnapper”