BUG FIX: bad clientID due to bad MQTT library - causes disconnects with multiple AB's on one broker!
IMPROVEMENT: MQTT reconnect implemented.
This commit is contained in:
parent
fdf4e9af99
commit
3e4ce429c7
|
@ -37,7 +37,8 @@ AsyncMqttClient::AsyncMqttClient()
|
||||||
_client.onPoll([](void* obj, AsyncClient* c) { (static_cast<AsyncMqttClient*>(obj))->_onPoll(c); }, this);
|
_client.onPoll([](void* obj, AsyncClient* c) { (static_cast<AsyncMqttClient*>(obj))->_onPoll(c); }, this);
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
sprintf(_generatedClientId, "esp32%06x", ESP.getEfuseMac());
|
// WHY OH WHY WON'T THE DEV DO THIS FIX (original is %06x - 32bits, excludes the important unique bits!)
|
||||||
|
sprintf(_generatedClientId, "esp32%06llx", ESP.getEfuseMac());
|
||||||
_xSemaphore = xSemaphoreCreateMutex();
|
_xSemaphore = xSemaphoreCreateMutex();
|
||||||
#elif defined(ESP8266)
|
#elif defined(ESP8266)
|
||||||
sprintf(_generatedClientId, "esp8266%06x", ESP.getChipId());
|
sprintf(_generatedClientId, "esp8266%06x", ESP.getChipId());
|
||||||
|
|
|
@ -123,8 +123,8 @@
|
||||||
#define RX_DATA_TIMOUT 50
|
#define RX_DATA_TIMOUT 50
|
||||||
|
|
||||||
const int FirmwareRevision = 31;
|
const int FirmwareRevision = 31;
|
||||||
const int FirmwareSubRevision = 0;
|
const int FirmwareSubRevision = 1;
|
||||||
const char* FirmwareDate = "31 Aug 2019";
|
const char* FirmwareDate = "1 Sep 2019";
|
||||||
|
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
|
@ -1624,7 +1624,8 @@ void doStreaming()
|
||||||
bHaveWebClient = doWebServer();
|
bHaveWebClient = doWebServer();
|
||||||
#endif //USE_WEBSERVER
|
#endif //USE_WEBSERVER
|
||||||
#if USE_MQTT == 1
|
#if USE_MQTT == 1
|
||||||
// MQTT is managed via callbacks!!!
|
// most MQTT is managed via callbacks, but need some sundry housekeeping
|
||||||
|
doMQTT();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "../cfg/BTCConfig.h"
|
#include "../cfg/BTCConfig.h"
|
||||||
|
|
||||||
#if USE_MQTT == 1
|
#if USE_MQTT == 1
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "ABMqtt.h"
|
#include "ABMqtt.h"
|
||||||
#include "../../lib/async-mqtt-client/src/AsyncMqttClient.h"
|
#include "../../lib/async-mqtt-client/src/AsyncMqttClient.h"
|
||||||
|
@ -13,37 +14,68 @@
|
||||||
#include "../Utility/DebugPort.h"
|
#include "../Utility/DebugPort.h"
|
||||||
#include "../Utility/NVStorage.h"
|
#include "../Utility/NVStorage.h"
|
||||||
|
|
||||||
//IPAddress testMQTTserver(5, 196, 95, 208); // test.mosquito.org
|
#define USE_RTOS_MQTTTIMER
|
||||||
IPAddress testMQTTserver(18, 194, 98, 249); // broker.hivemq.com
|
//#define USE_LOCAL_MQTTSTRINGS
|
||||||
|
|
||||||
|
//IPAddress testMQTTserver(5, 196, 95, 208); // test.mosquito.org
|
||||||
|
//IPAddress testMQTTserver(18, 194, 98, 249); // broker.hivemq.com
|
||||||
|
|
||||||
AsyncMqttClient MQTTclient;
|
AsyncMqttClient MQTTclient;
|
||||||
TimerHandle_t mqttReconnectTimer = NULL;
|
|
||||||
char topicnameJSONin[128];
|
char topicnameJSONin[128];
|
||||||
|
|
||||||
|
#ifdef USE_LOCAL_MQTTSTRINGS
|
||||||
|
char mqttHost[128];
|
||||||
|
char mqttUser[32];
|
||||||
|
char mqttPass[32];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_RTOS_MQTTTIMER
|
||||||
|
TimerHandle_t mqttReconnectTimer = NULL;
|
||||||
|
#else
|
||||||
|
unsigned long mqttReconnect = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
void connectToMqtt() {
|
void connectToMqtt() {
|
||||||
DebugPort.println("MQTT: Connecting...");
|
#ifdef USE_RTOS_MQTTTIMER
|
||||||
MQTTclient.connect();
|
xTimerStop(mqttReconnectTimer, 0);
|
||||||
|
#else
|
||||||
|
mqttReconnect = 0;
|
||||||
|
#endif
|
||||||
|
if(!MQTTclient.connected()) {
|
||||||
|
DebugPort.println("MQTT: Connecting...");
|
||||||
|
if(NVstore.getMQTTinfo().enabled) {
|
||||||
|
MQTTclient.connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onMqttConnect(bool sessionPresent)
|
void onMqttConnect(bool sessionPresent)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_RTOS_MQTTTIMER
|
||||||
|
xTimerStop(mqttReconnectTimer, 0);
|
||||||
|
#else
|
||||||
|
mqttReconnect = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
DebugPort.println("MQTT: Connected to broker.");
|
DebugPort.println("MQTT: Connected to broker.");
|
||||||
// DebugPort.printf("Session present: %d\r\n", sessionPresent);
|
// DebugPort.printf("Session present: %d\r\n", sessionPresent);
|
||||||
|
|
||||||
const sMQTTparams params = NVstore.getMQTTinfo();
|
// create the topicname we use to accept incoming JSON
|
||||||
char topic[128];
|
DebugPort.printf("MQTT: base topic name \"%s\"\r\n", NVstore.getMQTTinfo().topic);
|
||||||
DebugPort.printf("MQTT: base topic name \"%s\"\r\n", params.topic);
|
sprintf(topicnameJSONin, "%s/JSONin", NVstore.getMQTTinfo().topic);
|
||||||
sprintf(topicnameJSONin, "%s/JSONin", params.topic);
|
// subscribe to that topic
|
||||||
DebugPort.printf("MQTT: Subscribing to \"%s\"\r\n", topicnameJSONin);
|
DebugPort.printf("MQTT: Subscribing to \"%s\"\r\n", topicnameJSONin);
|
||||||
MQTTclient.subscribe(topicnameJSONin, params.qos);
|
MQTTclient.subscribe(topicnameJSONin, NVstore.getMQTTinfo().qos);
|
||||||
|
|
||||||
// spit out an "I'm here" message
|
// spit out an "I'm here" message
|
||||||
sprintf(topic, "%s/Status", params.topic);
|
char lcltopic[128];
|
||||||
MQTTclient.publish(topic, params.qos, true, "onMqttConnect");
|
sprintf(lcltopic, "%s/Status", NVstore.getMQTTinfo().topic);
|
||||||
|
MQTTclient.publish(lcltopic, NVstore.getMQTTinfo().qos, true, "onMqttConnect");
|
||||||
|
|
||||||
#ifdef MQTT_DBG_LOOPBACK
|
#ifdef MQTT_DBG_LOOPBACK
|
||||||
// testo - loopback
|
// testo - loopback
|
||||||
sprintf(topic, "%s/JSONout", params.topic);
|
sprintflcl(topic, "%s/JSONout", NVstore.getMQTTinfo().topic);
|
||||||
MQTTclient.subscribe(topic, params.qos);
|
MQTTclient.subscribe(lcltopic, NVstore.getMQTTinfo().qos);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
resetJSONmoderator();
|
resetJSONmoderator();
|
||||||
|
@ -73,11 +105,28 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
|
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
|
||||||
DebugPort.println("MQTT: Disconnected!");
|
DebugPort.print("MQTT: Disconnected, reason: ");
|
||||||
|
// ref: DisconnectReasons.hpp
|
||||||
|
switch(reason) {
|
||||||
|
case AsyncMqttClientDisconnectReason::TCP_DISCONNECTED: DebugPort.println("TCP disconnected"); break;
|
||||||
|
case AsyncMqttClientDisconnectReason::MQTT_UNACCEPTABLE_PROTOCOL_VERSION: DebugPort.println("protocol version"); break;
|
||||||
|
case AsyncMqttClientDisconnectReason::MQTT_IDENTIFIER_REJECTED: DebugPort.println("Identifier rejected"); break;
|
||||||
|
case AsyncMqttClientDisconnectReason::MQTT_SERVER_UNAVAILABLE: DebugPort.println("Server unavailable"); break;
|
||||||
|
case AsyncMqttClientDisconnectReason::MQTT_MALFORMED_CREDENTIALS: DebugPort.println("Malformed credentials"); break;
|
||||||
|
case AsyncMqttClientDisconnectReason::MQTT_NOT_AUTHORIZED: DebugPort.println("No authorised"); break;
|
||||||
|
case AsyncMqttClientDisconnectReason::ESP8266_NOT_ENOUGH_SPACE: DebugPort.println("Not enough space"); break;
|
||||||
|
case AsyncMqttClientDisconnectReason::TLS_BAD_FINGERPRINT: DebugPort.println("Bad TLS fingerprint"); break;
|
||||||
|
}
|
||||||
|
|
||||||
// if (WiFi.isConnected()) {
|
if (WiFi.isConnected()) {
|
||||||
// xTimerStart(mqttReconnectTimer, 0);
|
if(NVstore.getMQTTinfo().enabled) {
|
||||||
// }
|
#ifdef USE_RTOS_MQTTTIMER
|
||||||
|
xTimerStart(mqttReconnectTimer, 0);
|
||||||
|
#else
|
||||||
|
mqttReconnect = millis() + 5000;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
|
void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
|
||||||
|
@ -88,37 +137,57 @@ void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
|
||||||
|
|
||||||
bool mqttInit()
|
bool mqttInit()
|
||||||
{
|
{
|
||||||
// if(mqttReconnectTimer==NULL)
|
#ifdef USE_RTOS_MQTTTIMER
|
||||||
// mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
|
if(mqttReconnectTimer==NULL)
|
||||||
|
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
|
||||||
|
#else
|
||||||
|
mqttReconnect = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
memset(topicnameJSONin, 0, sizeof(topicnameJSONin));
|
memset(topicnameJSONin, 0, sizeof(topicnameJSONin));
|
||||||
|
|
||||||
|
MQTTclient.disconnect(true);
|
||||||
|
long escape = millis() + 10000;
|
||||||
|
while(MQTTclient.connected()) {
|
||||||
|
long tDelta = millis()-escape;
|
||||||
|
if(tDelta > 0) {
|
||||||
|
DebugPort.println("MQTT: TIMEOUT waiting for broker disconnect");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const sMQTTparams params = NVstore.getMQTTinfo();
|
const sMQTTparams params = NVstore.getMQTTinfo();
|
||||||
if(params.enabled) {
|
if(params.enabled) {
|
||||||
if(strlen(params.host)) {
|
#ifdef USE_LOCAL_MQTTSTRINGS
|
||||||
MQTTclient.disconnect();
|
strncpy(mqttHost, params.host, 127);
|
||||||
long escape = millis() + 10000;
|
strncpy(mqttUser, params.username, 31);
|
||||||
while(MQTTclient.connected()) {
|
strncpy(mqttPass, params.password, 31);
|
||||||
long tDelta = millis()-escape;
|
mqttHost[127] = 0;
|
||||||
if(tDelta > 0) {
|
mqttUser[31] = 0;
|
||||||
DebugPort.println("MQTT: TIMEOUT waiting for broker disconnect");
|
mqttPass[31] = 0;
|
||||||
break;
|
DebugPort.printf("MQTT: setting broker to %s:%d\r\n", mqttHost, params.port);
|
||||||
}
|
DebugPort.printf("MQTT: %s/%s\r\n", mqttUser, mqttPass);
|
||||||
}
|
MQTTclient.setServer(mqttHost, params.port);
|
||||||
DebugPort.printf("MQTT: setting broker to %s:%d\r\n", params.host, params.port);
|
MQTTclient.setCredentials(mqttUser, mqttPass);
|
||||||
MQTTclient.setServer(params.host, params.port);
|
#else
|
||||||
MQTTclient.setCredentials(params.username, params.password);
|
// the client only stores a pointer - this must not be a volatile memory location!
|
||||||
static bool setCallbacks = false;
|
// - NO STACK vars!!!
|
||||||
// callbacks should only be added once (vector of callbacks in client!)
|
DebugPort.printf("MQTT: setting broker to %s:%d\r\n", NVstore.getMQTTinfo().host, NVstore.getMQTTinfo().port);
|
||||||
if(!setCallbacks) {
|
MQTTclient.setServer(NVstore.getMQTTinfo().host, NVstore.getMQTTinfo().port);
|
||||||
MQTTclient.onConnect(onMqttConnect);
|
DebugPort.printf("MQTT: %s/%s\r\n", NVstore.getMQTTinfo().username, NVstore.getMQTTinfo().password);
|
||||||
MQTTclient.onMessage(onMqttMessage);
|
MQTTclient.setCredentials(NVstore.getMQTTinfo().username, NVstore.getMQTTinfo().password);
|
||||||
MQTTclient.onDisconnect(onMqttDisconnect);
|
#endif
|
||||||
MQTTclient.onSubscribe(onMqttSubscribe);
|
static bool setCallbacks = false;
|
||||||
setCallbacks = true;
|
// callbacks should only be added once (vector of callbacks in client!)
|
||||||
}
|
if(!setCallbacks) {
|
||||||
MQTTclient.connect();
|
MQTTclient.onConnect(onMqttConnect);
|
||||||
return true;
|
MQTTclient.onMessage(onMqttMessage);
|
||||||
|
MQTTclient.onDisconnect(onMqttDisconnect);
|
||||||
|
MQTTclient.onSubscribe(onMqttSubscribe);
|
||||||
|
setCallbacks = true;
|
||||||
}
|
}
|
||||||
|
// connection takes pplace via delayed start method
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -135,5 +204,44 @@ bool mqttPublishJSON(const char* str)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kickMQTT() {
|
||||||
|
if (WiFi.isConnected()) {
|
||||||
|
if(NVstore.getMQTTinfo().enabled) {
|
||||||
|
#ifdef USE_RTOS_MQTTTIMER
|
||||||
|
xTimerStart(mqttReconnectTimer, 0);
|
||||||
|
#else
|
||||||
|
mqttReconnect = millis() + 5000;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void doMQTT()
|
||||||
|
{
|
||||||
|
// most MQTT is managed via callbacks!!!
|
||||||
|
if(NVstore.getMQTTinfo().enabled) {
|
||||||
|
#ifndef USE_RTOS_MQTTTIMER
|
||||||
|
if(mqttReconnect) {
|
||||||
|
long tDelta = millis() - mqttReconnect;
|
||||||
|
if(tDelta > 0) {
|
||||||
|
mqttReconnect = 0;
|
||||||
|
connectToMqtt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_RTOS_MQTTTIMER
|
||||||
|
if (!MQTTclient.connected() && WiFi.isConnected() && !xTimerIsTimerActive(mqttReconnectTimer)) {
|
||||||
|
xTimerStart(mqttReconnectTimer, 0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (!MQTTclient.connected() && WiFi.isConnected() && mqttReconnect==0) {
|
||||||
|
mqttReconnect = millis() + 5000;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -5,7 +5,11 @@
|
||||||
|
|
||||||
|
|
||||||
bool mqttInit();
|
bool mqttInit();
|
||||||
|
void doMQTT();
|
||||||
bool mqttPublishJSON(const char* str);
|
bool mqttPublishJSON(const char* str);
|
||||||
|
void connectToMqtt();
|
||||||
|
void kickMQTT();
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue