In my project I have several ESP32 devices participating in an IoT solution based on MQTT. I have a Mosquitto instance running on an RPi 3. I will have info about the status of all the ESP devices broad-casted : when a device becomes active, it will publish a message telling it is "Online", when the device becomes inactive, there must be a message send telling the device is "Offline". I try to accomplish this by setting an LWT in the connection data of the device. However, there are some troubles with this:
- If I set the keepAliveInterval of the connectData to 0, the LWT message will never be published...
- if I set the keepAliveInterval to 60 seconds (the default in MQTTPacket_connectData_initializer), then when there is no activity on the ESP device fore more than 60 seconds the device logs off and the LWT is published....
How can I make this work, having the LWT send only if the ESP device is effectively disconnected (or powered off) ?
my code (still a Work in Progress) :
Code: Select all
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <stdio.h>
#include <inttypes.h>
#include "MQTTClient.h"
#include "sdkconfig.h"
static char tag[] = "mqtt_paho";
static unsigned char sendBuf[1000];
static unsigned char readBuf[1000];
Network network;
MQTTClient client;
#include "IoTMQTTMessageQueueItem.h"
void task_paho(void *ignore) {
ESP_LOGI(tag, "Starting ...");
int rc;
NetworkInit(&network);
ESP_LOGI(tag, "::NetworkConnect ...");
NetworkConnect(&network, "192.168.1.105", 1883);
ESP_LOGI(tag, "::MQTTClientInit ...");
MQTTClientInit(&client, &network,
1000, // command_timeout_ms
sendBuf, //sendbuf,
sizeof(sendBuf), //sendbuf_size,
readBuf, //readbuf,
sizeof(readBuf) //readbuf_size
);
union
{
uint64_t llmac;
uint8_t mac[6];
} mac_t;
ESP_ERROR_CHECK(esp_efuse_mac_get_default(mac_t.mac));
char szMac[21];
snprintf(szMac, sizeof(szMac), "%" PRIu64, mac_t.llmac);
MQTTString clientId = MQTTString_initializer;
clientId.cstring = szMac;
char szStatusTopic[256];
snprintf(szStatusTopic, sizeof(szStatusTopic), "TBTIoT/Devices/%s/Status", szMac);
MQTTString willTopic = MQTTString_initializer;
willTopic.cstring = szStatusTopic;
MQTTString willMessage = MQTTString_initializer;
willMessage.cstring = "Offline";
MQTTPacket_willOptions willOptions = MQTTPacket_willOptions_initializer;
willOptions.topicName = willTopic;
willOptions.message = willMessage;
willOptions.retained = true;
willOptions.qos = QOS0;
MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
data.clientID = clientId;
data.willFlag = 1;
data.MQTTVersion = 4;
data.keepAliveInterval = 0;
data.cleansession = 1;
data.will = willOptions;
ESP_LOGI(tag, "::MQTTConnect ...");
rc = MQTTConnect(&client, &data);
if (rc != SUCCESS)
{
ESP_LOGE(tag, "MQTTConnect: %d", rc);
}
MQTTMessage statusMessage;
statusMessage.qos = QOS0;
statusMessage.retained = true;
statusMessage.dup = 0;
statusMessage.id = 0;
statusMessage.payload = "Online";
statusMessage.payloadlen = strlen("Online");
ESP_LOGI(tag, "::MQTTPublish ...");
rc = MQTTPublish(&client, szStatusTopic, &statusMessage);
if (rc != SUCCESS)
{
ESP_LOGE(tag, "::MQTTPublish: %d", rc);
}
ESP_LOGI(tag, "::MQTTSubscribe ...");
rc = MQTTSubscribe(&client, "#", QOS0, IoTMQTTMessageHandler_func);
if (rc != SUCCESS)
{
ESP_LOGE(tag, "::MQTTSubscribe: %d", rc);
}
while(1)
{
MQTTYield(&client, 1000);
}
vTaskDelete(NULL);
}
Paul.