loboris / MicroPython_ESP32_psRAM_LoBo

MicroPython for ESP32 with psRAM support
Other
831 stars 344 forks source link

add parameter for MQTT lwt #125

Closed Josverl closed 6 years ago

Josverl commented 6 years ago

Currently the MQTT client is hardcoded to request for a lwt on connect. several public mqtt services to not support this , and will reject the connection. (see also issue #81 ) See :

The only known workaround is currently to use the stock micropython mqtt modules.

To improve usability of the builtin module 2 parameters could be added :

from my understanding of the code, such a change could be made in modmqtt.c

modmqtt.c

STATIC mp_obj_t mqtt_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args)
{
...
    self->client->settings->auto_reconnect = args[ARG_reconnect].u_int;
    self->client->settings->keepalive = args[ARG_keepalive].u_int;
    self->client->settings->clean_session = args[ARG_cleansess].u_int;
    sprintf(self->client->settings->lwt_topic, "/lwt");
    sprintf(self->client->settings->lwt_msg, "offline");
    self->client->settings->lwt_qos = args[ARG_qos].u_int;
    self->client->settings->lwt_retain = args[ARG_retain].u_int;
…
}

mqtt_msg.c

mqtt_message_t* mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_info_t* info)
{
...

    if (info->will_topic != NULL && info->will_topic[0] != '\0')
    {
        if (append_string(connection, info->will_topic, strlen(info->will_topic)) < 0)
            return fail_message(connection);
        if (append_string(connection, info->will_message, info->will_length) < 0)
            return fail_message(connection);

        variable_header->flags |= MQTT_CONNECT_FLAG_WILL;
        if (info->will_retain)
            variable_header->flags |= MQTT_CONNECT_FLAG_WILL_RETAIN;
        variable_header->flags |= (info->will_qos & 3) << 3;
}
Josverl commented 6 years ago

Just to make sure I did a q&d change to modmqtt to hardcode both lwttopic and lwtmessage to empty strings; after doing that the mqtt client is indeed able to connect to thingspeak

#Do not set CleanSession flag to 0 --> cleansession=True)
client = network.mqtt(  'client_10713646',
                        "mqtt.thingspeak.com",
                        user='jos',
                        password=thingspeakMqttApiKey
                        ,cleansession=True)
client

Mqtt[client_10713646](Server: mqtt.thingspeak.com:1883, Status: Disconnected
     Client ID: mpy_mqtt_client, Clean session=True, Keepalive=120 sec, QoS=0, Retain=False, Secure=False
    )

>>> 
>>> client
Mqtt[client_10713646](Server: mqtt.thingspeak.com:1883, Status: Connected
     Client ID: mpy_mqtt_client, Clean session=True, Keepalive=120 sec, QoS=0, Retain=False, Secure=False
     Used stack: 1048/2048 + 412/2048
    )

>>> 
loboris commented 6 years ago

Thanks for the suggestions.

I'm planning mqtt module update for the next week, an I'll try to include your suggestions.

bdespatis commented 6 years ago

Great to know because I can only connect to CloudMQTT and my own mosquitto broker.

Tested for Ubidots and Adafruit, both [Mqtt client]: Connection refused, not authorized

It is working for CloudMQTT, test.mosquitto.org both MQTT and MQTT TLS

I have tried Josverl modmqtt.c, but I don't see a difference. I even tried :

>>> mqtt.config(lwt_topic="")
>>> mqtt.config(lwt_msg="")
>>> mqtt.start()
>>> W (822309) [Mqtt client]: Connection refused, not authorized

Update :

I was able to connect and send data to ThingSpeak, but not to Ubidots. I will reach to them to see why.

Benoit

loboris commented 6 years ago

The mqtt module was updated, the new mqtt library is now used which solves the issue. The Wiki is updated and includes an example to connect to ThingSpeak.