LoPy4 publishing to TTN v3 via MQTT



  • Has anybody managed to get functioning sample code? Studied tutorial on TTN website, used their CLI tools mosquitto_sub and mosquitt_pub: got data with mosquitto_sub, but cannot publish with mosquitto_pub. Neither can I get my LoPy to submit any data. LoPy is connected via wlan to the internet.

    from mqtt import MQTTClient
    import time
    
    def sub_cb(topic, msg):
       print(msg)
    
    client = MQTTClient(
        'dev7',
        'nam1.cloud.thethings.network',
        user='app7@ttn',
        password='NNSXS.GC.....',
        port=1883)
    
    client.set_callback(sub_cb)
    client.connect()
    time.sleep(3)
    
    client.publish(topic='v3/app7@ttn/devices/dev7/up', msg='vu8=')
    

    After client.connect() I get the following response.

    0xc b'10:7e:00:04:4d:51:54:54:04:c2:00:00'
    b' \x02\x00\x00'
    

    But no reaction to the client.publish(...) part. Got any ideas?



  • Hmm, seems I cannot send sensor uplink data to TTN v3 via MQTT? How else would a LoPy4 module report to TTN if it only has WiFi connectivity to cloud?



  • After scratching my head for days and lot of testing I just want to document the findings, so others may get a head start.

    Some useful links for reference:
    TTN: MQTT Client - Describes in general how to subscribe and publish to TTN. Here you can also follow the link to the Mosquitto command line tools for testing connectivity to TTN.
    Ubuntu on WSL - If you need a Linux machine to play with the above on your Windows computer, one of the options is to install WSL (Windows Subsystem Linux) and it provides essentially a command prompt with Linux environment. With this you can open multiple Linux console windows for subscribe/publish observations.
    Cryptii.com - Offers a nice tool to verify your Base64 encoding for the message.
    Github fizista: umqtt.simple2 - MicroPython MQTT library that works on LoPy4 as well.
    Github fizista: umqtt.robust2 - Advanced MQTT concepts.

    After all the considerations for blocking/non-blocking resources I found these snippets from Wojciech Banaś worked pretty straight forward on my LoPy4. I've left out the code that prepares the Wifi connectivity. Assuming lib files are located in the umqtt subfolder of your project, this is the code to subscribe to TTN v3:

    import time
    from umqtt.simple2 import MQTTClient
    
    # Received messages from subscriptions will be delivered to this callback
    def sub_cb(topic, msg, retain, dup):
        print((topic, msg, retain, dup))
    
    blocking_method = False
    client = MQTTClient(
        'dev7',
        'nam1.cloud.thethings.network',
        user='app7@ttn',
        password='NNSXS.GCNX64NFC6OYQRVYMZZBQ2UT7DUYZ4AQW22QTOA.WVSKGGBTNDGA52OH4BERZPBPUSBS6TKSXLVTUNSCIFVJBOVG4KAA',
        port=1883)
    client.set_callback(sub_cb)
    client.connect()
    client.subscribe(topic='v3/app7@ttn/devices/dev7/#')
    print('--- connected and subscribed, waiting for data ---')
    while True:
        if blocking_method:
            # Blocking wait for message
            client.wait_msg()
        else:
            # Non-blocking wait for message
            client.check_msg()
            # Then need to sleep to avoid 100% CPU usage (in a real
            # app other useful actions would be performed instead)
            time.sleep(1)
    client.disconnect()
    

    And this code publishes to TTN v3:

    from umqtt.simple2 import MQTTClient
    
    client = MQTTClient(
        'dev7',
        'nam1.cloud.thethings.network',
        user='app7@ttn',
        password='NNSXS.GCNX64NFC6OYQRVYMZZBQ2UT7DUYZ4AQW22QTOA.WVSKGGBTNDGA52OH4BERZPBPUSBS6TKSXLVTUNSCIFVJBOVG4KAA',
        port=1883)
    client.connect()
    client.publish(topic='v3/app7@ttn/devices/dev7/down/push',
        msg='{"downlinks":[{"f_port": 2, "frm_payload": "vu8=", "priority": "NORMAL"}]}')
    client.disconnect()
    

    So the msg needs to have a specific format/content in order for TTN to accept your data. And the frm_payload needs to be valid Base64 encoded data, it seems.



  • Meanwhile I am able to subscribe and publish from a Unix console with

    mosquitto_sub -h "nam1.cloud.thethings.network" -p "8883" -u "app7@ttn" -P "NNSXS.GCNX64NFC6OYQRVYMZZBQ2UT7DUYZ4AQW22QTOA.WVSKGGBTNDGA52OH4BERZPBPUSBS6TKSXLVTUNSCIFVJBOVG4KAA" -t "#" -d
    

    and

    mosquitto_pub -h "nam1.cloud.thethings.network" -p "8883" -u "app7" -P "NNSXS.GCNX64NFC6OYQRVYMZZBQ2UT7DUYZ4AQW22QTOA.WVSKGGBTNDGA52OH4BERZPBPUSBS6TKSXLVTUNSCIFVJBOVG4KAA" -t "v3/app7@ttn/devices/dev7/down/push" -m '{"downlinks":[{"f_port": 2, "frm_payload": "vu8=", "priority": "NORMAL"}]}' -d
    

    The problem was the payload as it needs to be encoded Base64 or it gets dismissed to Nirvana without feedback.

    So I know I can communicate to TTN v3. But I cannot replicate the same functionality from a LoPy4 module using its WiFi connection. It seems to make a valid connect(), but then there is no reaction on the callback function!? Is there any additional setup required to bring that to life?



  • For easier testing here's the complete config.

    client = MQTTClient(
        'dev7',
        'nam1.cloud.thethings.network',
        user='app7@ttn',
        password='NNSXS.GCNX64NFC6OYQRVYMZZBQ2UT7DUYZ4AQW22QTOA.WVSKGGBTNDGA52OH4BERZPBPUSBS6TKSXLVTUNSCIFVJBOVG4KAA',
        port=1883)
    

Log in to reply
 

Pycom on Twitter