MQTT connection and client.check_msg() problem

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
rodrigo1120
Posts: 1
Joined: Wed May 13, 2020 4:07 pm

MQTT connection and client.check_msg() problem

Post by rodrigo1120 » Wed May 13, 2020 4:15 pm

I'm using Adafruit IO switches to turn my nodeMCU lights ON and OFF. The following code works but for a limited period of time. 5 minutes after the connection into Adafruit IO it seems the client tries to reconnect and if this happens I lose my switch funcionality at my adafruit dashboard. Either if I try to turn on or off the LED on my dashboard, the nodeMCU does not responds accordingly. Here is the code used (I'm using micropython, pycharm and a Lolin v3 nodemcu)

Code: Select all

from machine import Pin
import sys
import os
import network
from umqtt.robust import MQTTClient

random_num = int.from_bytes(os.urandom(3), 'little')
mqtt_client_id = bytes('client_' + str(random_num), 'utf-8')

ADAFRUIT_LINK = b'io.adafruit.com'
ADAFRUIT_USERNAME = b'rodrigo1120'
ADAFRUIT_KEY = b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
ADAFRUIT_FEEDNAME1 = b'gpio16'
ADAFRUIT_FEEDNAME2 = b'gpio2'

ssid = "WIFI-SSID"
password = "WIFI-PASSWORD"

client = MQTTClient(client_id= mqtt_client_id,
                    server= ADAFRUIT_LINK,
                    user=ADAFRUIT_USERNAME,
                    password=ADAFRUIT_KEY)

mqtt_feedname1 = bytes('{:s}/feeds/{:s}'.format(ADAFRUIT_USERNAME, ADAFRUIT_FEEDNAME1), 'utf-8')
mqtt_feedname2 = bytes('{:s}/feeds/{:s}'.format(ADAFRUIT_USERNAME, ADAFRUIT_FEEDNAME2), 'utf-8')


def connect_to_ap():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        print('Connecting to {}'.format(ssid))
        wlan.connect(ssid, password)
        while not wlan.isconnected():
            pass
    print('Credentials: ', wlan.ifconfig())
    try:
        client.connect()
    except Exception as e:
        print('Could not connect to MQTT Server {}{}'.format(type(e).__name__, e))


def callback_routine(feed, msg):
    print('Received Data from: feed={}, msg={}'.format(feed, msg))
    if ADAFRUIT_FEEDNAME1 in feed:
        action = str(msg, 'utf-8')
        if action == 'ON':
            pin16.value(0)
        else:
            pin16.value(1)
        print('Action: {}'.format(action))
    if ADAFRUIT_FEEDNAME2 in feed:
        action = str(msg, 'utf-8')
        if action == 'ON':
            pin2.value(0)
        else:
            pin2.value(1)
        print('Action: {}'.format(action))


pin16 = Pin(16, Pin.OUT)
pin2 = Pin(2, Pin.OUT)
pin16.value(1)
pin2.value(1)


def main():
    connect_to_ap()
    while True:
        client.set_callback(callback_routine)
        client.subscribe(mqtt_feedname1)
        client.subscribe(mqtt_feedname2)
        try:
            client.wait_msg()
        except KeyboardInterrupt:
            print('Ctrl+C pressed, exiting')
            client.disconnect()
            sys.exit()


if __name__ == '__main__':
    main()

Here is a picture of my serial monitor with this problem: (I took this picture 15 minutes after I stopped using the adafruit IO switches)
Image

User avatar
pythoncoder
Posts: 4665
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: MQTT connection and client.check_msg() problem

Post by pythoncoder » Thu May 14, 2020 8:13 am

I'm not familiar with the Adafruit broker but it's possible that it times out after 5 minutes of inactivity. Your application is subscribe-only and the official MQTT driver is rather oversimplified. If no publications occur, the driver should send periodic MQTT Ping packets to keep the connection open. The official driver doesn't do this.

To prove (or disprove) the point, I'd try publishing once every two minutes.

You might want to consider this library which aims to be a more resilient and full-featured MQTT solution.
Peter Hinch

Post Reply