Small MQTT Example



  • HI all,

    I am trying to get a small MQTT example running on LoPy (via connecting to Wifi). It seems there is an issue with imports of WLAN or so, I am getting the error that WLAN is not defined. Does anyone know what could be wrong here?

    from mqtt import MQTTClient
    import machine
    import time
    import pycom
    from network import WLAN

    def sub_cb(topic, msg):
    pycom.heartbeat(False)
    pycom.rgbled(0xff0000)
    time.sleep(1)
    pycom.rgbled(0x000000)
    pycom.heartbeat(True)

    wlan = WLAN(mode=WLAN.STA)
    wlan.connect("xxx", auth=(WLAN.WPA2, "xxx"), timeout=5000)

    while not wlan.isconnected():
    machine.idle()
    print("Connected to Wifi\n")

    client = MQTTClient("lopy", "io.adafruit.com",user="hansamann", password="xxx", port=1883)

    client.set_callback(sub_cb)
    client.connect()
    client.subscribe(topic="user/f/button")



  • @seb problems solved - the to_bytes method needs to be called with an additional 'little' parameter (little endian) and during each publish, the check_msg() method needs to be called.... works now.



  • I dont actually have any data going into MQTT I just ran the code you posted above to see if it was an error with parameters like you saw and I managed to subscribe without the error. Have you updated the firmware of the device since you received it as per: https://docs.pycom.io/chapter/gettingstarted/installation/firmwaretool.html ?



  • @seb Strange, I can connect and publish now but no subscription messages arrive.

    I seemd to have an issue with this line in subscribe (of the mqtt client):

    self.sock.write(qos.to_bytes(1))
    It seems to expect two variables, so I figured I can modify it to this:

    self.sock.write(qos.to_bytes(1, sys.byteorder))

    But it does not work - no bug or error, but my callback is not called (I hava a print in there, before I tried to flash the light... both did not work).

    Do I have recently ordered a LoPy and have LoPy1.0r - is that the issue? Is my device old?



  • @hansamann said in Small MQTT Example:

    from mqtt import MQTTClient
    import machine
    import time
    import pycom
    from network import WLAN
    def sub_cb(topic, msg):
    pycom.heartbeat(False)
    pycom.rgbled(0xff0000)
    time.sleep(1)
    pycom.rgbled(0x000000)
    pycom.heartbeat(True)
    wlan = WLAN(mode=WLAN.STA)
    wlan.connect("xxx", auth=(WLAN.WPA2, "xxx"), timeout=5000)
    while not wlan.isconnected():
    machine.idle()
    print("Connected to Wifi\n")
    client = MQTTClient("lopy", "io.adafruit.com",user="hansamann", password="xxx", port=1883)
    client.set_callback(sub_cb)
    client.connect()
    client.subscribe(topic="user/f/button")

    I just tried out accessing adafruit IO with your code and it worked fine for me. I got the mqtt library from here https://raw.githubusercontent.com/pycom/pycom-libraries/master/lib/mqtt/mqtt.py

    Just to note I changed my topic to be 'username/feeds/test' rather than '/f/' like you have.



  • thx, @misterlisty but I checked your code and most likely my mqtt.py is somehow broken. I've taken it from github, so I hope it is current.

    client = MQTTClient("wipy2", "io.adafruit.com",user="hansamann", password="xxx", port=1883)
    
    client.set_callback(sub_cb)
    client.connect()
    client.subscribe(topic="hansamann/f/button")
    

    This creates an error on line 139 of mqtt.py (see below). Sorry I am quite new to python, I cannot see what is wrong. QOS is optional and defaults to 0, so why does it not work?

    TypeError: function missing 1 positional arguments

        def subscribe(self, topic, qos=0):
            assert self.cb is not None, "Subscribe callback is not set"
            pkt = bytearray(b"\x82\0\0\0")
            self.pid += 1
            struct.pack_into("!BH", pkt, 1, 2 + 2 + len(topic) + 1, self.pid)
            #print(hex(len(pkt)), hexlify(pkt, ":"))
            self.sock.write(pkt)
            self._send_str(topic)
            self.sock.write(qos.to_bytes(1)) #line 139
            while 1:
                op = self.wait_msg()
                if op == 0x90:
                    resp = self.sock.read(4)
                    #print(resp)
                    assert resp[1] == pkt[2] and resp[2] == pkt[3]
                    if resp[3] == 0x80:
                        raise MQTTException(resp[3])
                    return
    


  • 1_1510902349073_main.py 0_1510902349072_boot.py

    Happy to share my code and welcome any feedback.

    Features:
    Ability to re-connect if wifi disconnects.
    Disable mqtt if not connected to internet
    Ability to re-connect to alternate wifi if the primary one dies.
    Includes a watchdog to ensure its always connected
    You can send it PON/POFF command to toggle a pin out thru mqtt
    Constantly sends an ON/OFF msg to the mqtt broker

    Enjoy, happy to help the community..i'm learning also

    Maybe ill put it on github if anyone is interested, we can improve as a community...



  • @hansamann
    will be better to provide whole error message
    and please format code sourouding it with triple ```


 

Hello World?

Pylife on Kickstarter - November 2018








Back Us On Kickstarter >

Pycom on Twitter