tuanpmt / esp8266mqttclient Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
Hi, I am appreciate your Project ,so I want do some contribution, to feedback some question I meet.
I git clone this project to control my ESP8266 board,
if only use mqtt.onData event,it work fine,
but I add a publish call in onData function, the publish not send, other Subscriber can not receive which topic publish. the board also not jump exception.
and the mqtt.onPublish function also not call, I am confused with this, am i use wrong?
mqtt.onData([](String topic, String data, bool cont) {
Serial.printf("Data received, topic: %s, data: %s\r\n", topic.c_str(), data.c_str());
//mqtt.unSubscribe("/qos0");
Serial.printf("%s \r\n", data.c_str());
if (data.compareTo("1") == 0 || data.compareTo("ON") == 0)
{
digitalWrite(PIN_RELAY1, HIGH );
digitalWrite(PIN_RELAY2, HIGH );
mqtt.publish("homeassistant/switch/irrigation/state", "ON", 0, 0); //**actually not work**
//mqtt.publish("123", "ON", 0, 0);
digitalWrite(LED_BUILTIN, LOW); //LED ON
//delay(200);
}
//delay(1000); //delay 1 second
if (data.compareTo("0") == 0 || data.compareTo("OFF") == 0)
{
digitalWrite(PIN_RELAY1, LOW );
digitalWrite(PIN_RELAY2, LOW );
mqtt.publish("homeassistant/switch/irrigation/state", "OFF", 0, 0); // **actually not work**
//mqtt.publish("123", "OFF" , 0, 0);
digitalWrite(LED_BUILTIN, HIGH); //LED OUT
}
});
Serial.println("mqtt OnSub: ");
mqtt.onSubscribe([](int sub_id) {
Serial.printf("Subscribe topic id: %d ok\r\n", sub_id);
mqtt.publish("/qos0", "qos0", 0, 0); // **but this publish WORK FINE! i am so confused**
});
Serial.println("mqtt OnPub: ");
mqtt.onPublish([](int pub_id) { //**this function never call, i don't know why**
Serial.printf("onPublish return id: %d \r\n", pub_id);
});
So i use another esp8266 mqtt client PubSubClient, and it work fine.
void callback(char* topic, byte* payload, unsigned int length) {//call back function with PubSubClient
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
String s = "";
for (int i = 0; i < length; i++) {
s = s + (char)payload[i];
}
Serial.println(s);
// Switch on the LED if an 1 was received as first character
if (s == "ON") {
digitalWrite(LED_BUILTIN, LOW); // Turn the LED on (Note that LOW is the voltage level
// but actually the LED is on; this is because
// it is active low on the ESP-01)
client.publish("homeassistant/switch/irrigation/state", (char*)s.c_str());
} else {
digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off by making the voltage HIGH
client.publish("homeassistant/switch/irrigation/state", (char*)s.c_str());
}
}
It seems that the _isSecure
member does exist in the base class as well as the derived MQTTWSTraits
this leads to inconsistencies.
I assume this is not by intention?
Im look for a solution that makes mqtt comunnication over secure websocket and I wonder if this library covers this area.
Thanks a lot for you work.
Just tried a very simple ESP8266 sketch, subscribing to "#", and using MQTT.fx to publish topic "Hello", with an empty payload. It reliably crashes out just after the LOG statement in ESP8266MQTTClient.cpp line 344.
Running on Lolin D1 Mini, ESP8266 libraries 2.4.2.
Hi,
I test the code "MQTTOverWebsocketClient" and this works fine on ports 8080 and 8090 of "test.mosquitto.org" (without encryption)
But I need to use MQTT over Websockets with TLS and authentication.
I'm using the broker "test.mosquitto.org", port 8091, to test this. But I'm not succeeding.
How can I adapt the code to implement TLS?
I try add (the same of example "MQTTSecureClient") :
String fingerprint = "7E 36 22 01 F9 7E 99 2F C5 DB 3D BE AC 48 67 5B 5D 47 94 D2";
and add :
configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");
mqtt.onSecure([](WiFiClientSecure *client, String host) {
Serial.printf("Verify: %s\r\n", host.c_str());
return client->verify(fingerprint.c_str(), host.c_str());
});
but the connection is not established.
can someone help me find a solution to implement MQTT over WebSockets with TLS?
Thank you.
Jorge
Hi, I see in ESP8266MQTTClient.cpp the following memory allocations for in and out buffers:
_state.in_buffer = (uint8_t *)malloc(DEFAULT_MQTT_BUFFER_SIZE_BYTES);
if(_state.in_buffer == NULL) {
LOG("Not enought memory\r\n");
return false;
}
_state.in_buffer_length = DEFAULT_MQTT_BUFFER_SIZE_BYTES;
_state.out_buffer = (uint8_t *)malloc(DEFAULT_MQTT_BUFFER_SIZE_BYTES);
if(_state.in_buffer == NULL) {
free(_state.in_buffer);
LOG("Not enought memory\r\n");
return false;
}
I believe the last check over in_buffer should be done over out_buffer, and also both mallocs() should be freed. Please correct me if i'm wrong...
Thanks, rgds,
Richard
ESP8266MQTTClient/src/uri_parser.c
Line 75 in 252c4ca
The tolower
will make the password invalid, if the password contain uppercase characters.
I was getting a constant WDT reset in my application due an endless loop in the function processRead(). There were two problems: an invalid message type (0) following a MQTT_MSG_TYPE_PINGRESP and length = 0 on MQTT_MSG_TYPE_PINGRESP. I don´t know what´s causing that conditions, but the function implementation can lead to an endless loop in case of an unexpected message content. I’m not sure, but I believe that the package may be discarded when a ping response is received. I also believe that´s important to limit the number of times that the loop can be performed. I don´t know if 10 times is enough, but it´s working for me.
To fix, I changed the code (bold) as bellow:
int MQTTClient::processRead()
{
**// change begin aonm
#define MAXREADRETRY 10 // limit of read retries
int retry = 0; // count read retries
// change end aonm**
*
*
*
case MQTT_MSG_TYPE_PINGRESP:
LOG("MQTT_MSG_TYPE_PINGRESP\r\n");
// Ignore
**// change begin aonm
return 0; //discard remaining data
// change end aonm**
break;
**// change begin aonm
default: // Trap invalid message types
LOG("Invalid message type %i\r\n", msg_type);
return 0;
// change end aonm**
}
if(_state.message_length < _state.message_length_read) {
_state.message_length_read -= _state.message_length;
_state.in_buffer += _state.message_length;
**// change begin aonm
retry++;
if (retry > MAXREADRETRY) {
return 0;
}
// change end aonm**
goto PROCESS_READ_AGAIN;
}
return 1;
}
Http header names are not case sensitive, bool MQTTWSTraits::connect(WiFiClient* clientIn, const char* host, int port, const char *path)
does a case sensitive coparison of the headers (temp.startsWith("upgrade: websocket")
.
If a client sends the header in different casing as expected, the websocket connection will fail.
Hi,
I see there's no option for sending a disconnect packet to broker. This can be useful for sharing same broker connections among clients.
My 2 cents:
In ESP8266MQTTClient.cpp add:
bool MQTTClient::disconnect(void)
{
sendDisconnect();
free(_state.in_buffer);
free(_state.out_buffer);
LOG("[MQTT_client] disconnect!\n");
return true;
}
void MQTTClient::sendDisconnect()
{
_state.outbound_message = mqtt_msg_disconnect(&_state.connection);
_state.pending_msg_type = mqtt_get_type(_state.outbound_message->data);
_state.pending_msg_id = mqtt_get_id(_state.outbound_message->data,
_state.outbound_message->length);
LOG("Sending MQTT_MSG_TYPE_DISCONNECT\r\n");
_transportTraits->write(_tcp.get(), _state.outbound_message->data,
_state.outbound_message->length);
}
And their corresponding function declarations in header file:
bool disconnect();
void sendDisconnect();
Rgds,
Richard
hello
i have used this libray but the esp8266 go to crash.
can I help me please?
this is the code
`#include <ESP8266MQTTClient.h>
#include <ESP8266WiFi.h>
MQTTClient mqtt;
String fingerprint = "finger print ";
String host = "192.168.1.227";
// WiFi card example
char ssid[] = "gdfgdfgg"; // your SSID
char pass[] = "gfdgdfggdfgfdgdgfdgfdgd"; // your SSID Password
void setup() {
Serial.begin(115200);
WiFi.begin(ssid,pass );
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
mqtt.onSecure([](WiFiClientSecure *client, String host) {
Serial.printf("Verify: %s\r\n", host.c_str());
return client->verify(fingerprint.c_str(), host.c_str());
});
//topic, data, data is continuing
mqtt.onData([](String topic, String data, bool cont) {
Serial.printf("Data received, topic: %s, data: %s\r\n", topic.c_str(), data.c_str());
mqtt.unSubscribe("/qos0");
});
mqtt.onSubscribe([](int sub_id) {
Serial.printf("Subscribe topic id: %d ok\r\n", sub_id);
mqtt.publish("/qos0", "qos0", 0, 0);
});
mqtt.onConnect([]() {
Serial.printf("MQTT: Connected\r\n");
mqtt.subscribe("/qos0", 0);
});
mqtt.begin("mqtts://davide:[email protected]:8883" , {.lwtTopic = "hello", .lwtMsg = "offline", .lwtQos = 0, .lwtRetain = 0});
//mqtt.begin("mqtts://test.mosquitto.org:8883", {.lwtTopic = "hello", .lwtMsg = "offline", .lwtQos = 0, .lwtRetain = 0});
//mqtt.begin("mqtts://user:[email protected]:8883");
//mqtt.begin("mqtts://user:[email protected]:8883#clientId");
}
void loop() {
mqtt.handle();`
and this the error log
`Panic C:\Users\davide\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2\cores\esp8266\abi.cpp:92 __throw_bad_function_call
ctx: cont
sp: 3fff0870 end: 3fff0a90 offset: 01b0
stack>>>
3fff0a20: 00000000 00000000 00000000 40206098
3fff0a30: feefeffe 3ffef60c 00000000 40206710
3fff0a40: 00000000 00000000 3ffef60c 4020385d
3fff0a50: 00000000 00000000 3ffef60c 40203c3d
3fff0a60: 00000000 00000000 3ffefa5d 40203048
3fff0a70: feefeffe 00000000 3ffefa5d 402068ac
3fff0a80: feefeffe feefeffe 3ffefa70 4010070c
<<<stack<<<
ets Jan 8 2013,rst cause:2, boot mode:(3,6)
load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v0c897c37
~ld`
thanks in advantage.
Davide
Hello,
I was trying to test your library and got a compilation error. I tested with your 'MQTTSecureClient.ino' example.
Full Error Log:
ESP8266MQTTClient error log.txt
And I tried compiling only the library with no MQTT functions, and had the same error.
Because a new release has not been published, installing this library via the Arduino IDE results in the WDT reset error as described in #6.
In bool MQTTClient::begin(String uri, LwtOptions lwt, int keepalive, bool clean_session)
the puri->path
is added to the existing _path
, this leads to paths that start with at //
eg //mqtt
.
Arduino IDE 1.8.12
Esp8266 Framework 2.7.0
ESP8266MQTTClient 1.0.5
Run Sample MQTTClient.ino
#include <ESP8266MQTTClient.h>
#include <ESP8266WiFi.h>
MQTTClient mqtt;
void setup() {
Serial.begin(115200);
// WiFi.begin("ssid", "pass");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
//topic, data, data is continuing
mqtt.onData([](String topic, String data, bool cont) {
Serial.printf("Data received, topic: %s, data: %s\r\n", topic.c_str(), data.c_str());
mqtt.unSubscribe("/qos0");
});
mqtt.onSubscribe([](int sub_id) {
Serial.printf("Subscribe topic id: %d ok\r\n", sub_id);
mqtt.publish("/qos0", "qos0", 0, 0);
});
mqtt.onConnect([]() {
Serial.printf("MQTT: Connected\r\n");
Serial.printf("Subscribe id: %d\r\n", mqtt.subscribe("/qos0", 0));
// mqtt.subscribe("/qos1", 1);
// mqtt.subscribe("/qos2", 2);
});
mqtt.begin("mqtt://test.mosquitto.org:1883");
// mqtt.begin("mqtt://test.mosquitto.org:1883", {.lwtTopic = "hello", .lwtMsg = "offline", .lwtQos = 0, .lwtRetain = 0});
// mqtt.begin("mqtt://user:[email protected]:1883");
// mqtt.begin("mqtt://user:[email protected]:1883#clientId");
}
void loop() {
mqtt.handle();
}
User exception (panic/abort/assert)
Abort called
>>>stack>>>
ctx: cont
sp: 3fffff00 end: 3fffffc0 offset: 0000
3fffff00: 3fffdad0 3ffee7d8 00000020 401009b7
3fffff10: 000000fe 00000000 00000000 00000000
3fffff20: 00000000 00000000 00000000 00000080
3fffff30: 3ffef6a0 0000001d 00000001 3ffee988
3fffff40: 3fffdad0 00000000 3ffee7d8 4020723e
3fffff50: 00000000 40201e94 80ffff90 40207250
3fffff60: 00000000 8000001e 3fffff90 40211048
3fffff70: 3fffdad0 00000000 3ffee7d8 401000dc
3fffff80: 3fffdad0 00000000 3ffee7d8 40202b01
3fffff90: 3ffef800 00000000 3ffee948 40201ed8
3fffffa0: feefeffe 00000000 3ffee948 40206ea8
3fffffb0: feefeffe feefeffe 3ffe84e4 40100c79
<<<stack<<<
ets Jan 8 2013,rst cause:2, boot mode:(3,6)
I tried to comply a sketch that i wrote based on the examples, but something went wrong. Here are my sketch:
#include <ESP8266WiFi.h>
#include <ESP8266MQTTClient.h>
MQTTClient mqtt;
/************************* WiFi Access Point *********************************/
#define WLAN_SSID "xxx"
#define WLAN_PASS "xxx"
/************************* Adafruit.io Setup *********************************/
#define SERVER "xxx"
#define PORT "xxx"
#define USERNAME "xxx"
#define PASS "xxx"
#define CLIENT_ID "ESP01"
#define LWT {.lwtTopic = "xxx", .lwtMsg = "xxx", .lwtQos = 0, .lwtRetain = 0}
#define KEEP_ALIVE 60000
#define CLEAN_SESSION 1
void setup() {
WiFi.mode(WIFI_STA);
Serial.begin(57600);
Wifi_begin();
//topic, data, data is continuing
mqtt.onData([](String topic, String data, bool cont) {
Serial.printf("Data received, topic: %s, data: %s\r\n", topic.c_str(), data.c_str());
mqtt.unSubscribe("/qos0");
});
mqtt.onSubscribe([](int sub_id) {
Serial.printf("Subscribe topic id: %d ok\r\n", sub_id);
mqtt.publish("/qos0", "qos0", 0, 0);
});
mqtt.onConnect([]() {
Serial.printf("MQTT: Connected\r\n");
Serial.printf("Subscribe id: %d\r\n", mqtt.subscribe("/qos0", 0));
// mqtt.subscribe("/qos1", 1);
// mqtt.subscribe("/qos2", 2);
});
mqtt.begin("mqtt://" USERNAME ":" PASS "@" SERVER ":" PORT "#" CLIENT_ID , LWT, KEEP_ALIVE, CLEAN_SESSION);
}
void loop() {
mqtt.handle();
}
void Wifi_begin() {
// Connect to WiFi access point.
Serial.println();
Serial.print(F("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());
}
and this is the error message:
Am I missing or misunderstanding something?
mqtt.begin is not working
MQTTClient mqtt;
mqtt.begin("mqtt://test.mosquitto.org:1883");
Hence following command goes to infinite loop. & produces stack
mqtt.handle();
so I added a Boolean flag onConnect() command &
boolean flag = true;
…
mqtt.onConnect([]() {
…. ;
flag=false;
});
…..
void loop()
{
if(!flag);
{
…
mqtt.handle();
}
else
{
Serial.println("Mqtt not connected...");
delay(5000);
}
}
### stack_traced
Decoding 12 results
0x4010020c: _umm_free at C:\Users\Amit Suani\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\cores\esp8266\umm_malloc/umm_malloc.c line 1295
0x401009e8: free at C:\Users\Amit Suani\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\cores\esp8266\umm_malloc/umm_malloc.c line 1755
0x402069f8: axTLS::WiFiClientSecure::stop() at C:\Users\Amit Suani\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\libraries\ESP8266WiFi\src/WiFiClientSecureAxTLS.cpp line 312 (discriminator 1)
0x40206a14: _GLOBAL__sub_I__ZN7BearSSL16WiFiClientSecure14_bearssl_stackE at WiFiClientSecureBearSSL.cpp line ?
0x4010020c: umm_free at C:\Users\Amit Suani\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\cores\esp8266\umm_malloc/umm_malloc.c line 1295
0x401009e8: free at C:\Users\Amit Suani\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\cores\esp8266\umm_malloc/umm_malloc.c line 1755
0x40207085: MQTTClient::begin(String, LwtOptions, int, bool) at C:\Users\Amit Suani\Documents\Arduino\libraries\ESP8266MQTTClient\src/ESP8266MQTTClient.cpp line 275
0x40203d59: ArduinoJson::Internals::JsonParser ::Reader, ArduinoJson::Internals::StringWriter >::eat(char) at C:\Users\Amit Suani\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Deserialization/JsonParser.hpp line 42
: (inlined by) ArduinoJson::Internals::JsonParser ::Reader, ArduinoJson::Internals::StringWriter >::parseObject() at C:\Users\Amit Suani\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Deserialization/JsonParserImpl.hpp line 94
0x40204139: ArduinoJson::Internals::FloatParts ::FloatParts(float) at C:\Users\Amit Suani\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Deserialization/../Serialization/../Serialization/FloatParts.hpp line 34
0x40203550: postTransmission() at D:\php\Modbus Master\mqttclient_esp8266/mqttclient_esp8266.ino line 53
0x40207264: MQTTClient::deliverPublish(unsigned char*) at C:\Users\Amit Suani\Documents\Arduino\libraries\ESP8266MQTTClient\src/ESP8266MQTTClient.cpp line 275
-0x40100a49: cont_wrapper at C:\Users\Amit Suani\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\cores\esp8266/cont.S line 81
It could be great to change the "connected()" member to public.
Currently, I have to save the state of the client using the connected and disconnected callbacks.
Just forgot to add:
void MQTTClient::onDisconnect(THandlerFunction fn) { _disconnected_cb = fn; }
in file ESP8266MQTTClient.cpp
In example:
https://github.com/tuanpmt/ESP8266MQTTClient/blob/master/examples/MQTTClient/MQTTClient.ino#L32
The last will message is set up without referring to the keepalive argument as specified in:
https://github.com/tuanpmt/ESP8266MQTTClient/blob/master/src/ESP8266MQTTClient.cpp#L72
The example should probably be changed to include the keepalive (& cleansession), so predictable behaviour can be expected with the last will messages. Otherwise, the last will msg seems to be sent and printed in the topic before any other messages, whenever the connection is created.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.