LoPy: socket send command



  • Following the example structure from: https://forum.pycom.io/topic/1574/sending-packets-with-lopy-lorawan, I was able to successfully join via OTAA my two boards( LoPy on PySense and FiPy on Pytrack) to LoRaWAN gateway( Multitech's Conduit AP) and post to portal.Senetco.io for TCP Socket data forward to my private site.
    Both boards are running identical ADC input/output to read battery voltage of the board, two temperature sensors and 3 other proprietor sensors, and my data looks something like this in hex:
    Battery Voltage: 110E,
    Temperature sensor1: E206
    Temperature sensor2: BD06
    Other Sensor1:96
    Other Sensor2:3F
    Other Sensor3:C7
    So I would like to club all the data as 110EE206BD06963FC700, where two trailing zeros at the end are for end_of_char for server side parsing. Using "import struct" and "struct.pack" followed by "socket send" I was able to successfully post maybe the first 3-4 bytes and not more, it truncates the rest and messes up the final send.
    Also, for now data is 10 byte length but I am planning to add few more sensors to the board so the eventual data will be about 20-30 byte length.
    Please advise!



  • @jcaron
    Thanks a lot , limiting the channels to 0-8 and 64 ( for join/accept) did the trick for now.



  • This post is deleted!


  • @dda In the US region, there are a lot of channels a gateway is supposed to listen on, but most usually only listen on a small subset due to hardware limitations. If the network does not correctly send the relevant info to the device, it will try sending on channels the gateway may not be listening on.

    The best solution is for the network to correctly send the relevant info, but the alternative is to disable channels on the LoPy (which depends on the actual gateway config).



  • @jcaron @robert-hh @jmarcelino
    Thanks, that definitely helped and I was able to compile and upload the program with no error. LoPy successfully joins/accepts the LoRaWAN gateway, I can see the join/accept on the Senetco portal. So, I modified the code to run the the send portion only in a while true loop every 10 minutes ( for now with the same data payload):

    send_interval=10
    seconds=60
    count=0
    while True:
        count+=1
        print( "Send data loop %d"%count)
        pycom.heartbeat(False)
        pycom.rgbled(0x32CD32) # LIMEGREEN LED  
        time.sleep(1)
        pycom.rgbled(0xffffff)  # White LED
        time.sleep(1)
        pycom.rgbled(0x32CD32) # LIMEGREEN LED  
        time.sleep(1)
        s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
        s.setsockopt(socket.SOL_LORA, socket.SO_DR, 3)
        s.setblocking(True)
        s.send(bytes([0x11,0x0E,0xE2,0x06,0xBD,0x06,0x34,0x34,0x34,0x00]))
        s.setblocking(False)
        data = s.recv(64)
        print(data)
        print(" Send data success....Entering sleep mode")
        pycom.heartbeat(True)
        time.sleep(send_interval*seconds)
    

    The uplink is hit and a miss, sometimes it uplinks the first time on power up and then nothing for hours, while on my output side its reporting that send has been successful every 10 minutes.



  • import config is just used for people who put the device-specific configuration parameters in a separate file called config.py... If you have all your parameters in your main script you don't need it.



  • @robert-hh @jcaron @jmarcelino
    Thank you, I edited the s.send to match your suggestion and is reflected in my code now.

    s.send(bytes([0x11,0x0E,0xE2,0x06,0xBD,0x06,0x34,0x34,0x34,0x00])).
    

    But, I continue to have problem with "import config", I searched the forum for that error, no one reported that except for one forum where a user reported error with "import network". It was suggested that the error be ignored and pymark code should take care of it at upload.

    Here are my errors at Run:

    >>>
    >>>
    ♦Traceback (most recent call last):
      File "<stdin>", line 8, in <module>
    ImportError: no module named 'config'
    ♦>
    MicroPython v1.8.6-849-83e2f7f on 2018-03-19; LoPy with ESP32
    Type "help()" for more information.
    >>>
    >>>
    

    Error at Upload

    Uploading project (main folder)...
    
    Reading file status
    Upload done, resetting board...
    No files to upload
    ets Jun  8 2016 00:22:57
    
    rst:0x7 (TG0WDT_SYS_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff8028,len:8
    load:0x3fff8030,len:1728
    load:0x4009fa00,len:0
    load:0x4009fa00,len:14584
    entry 0x400a059c
    Traceback (most recent call last):
      File "main.py", line 2, in <module>
    KeyError: __main__
    MicroPython v1.8.6-849-83e2f7f on 2018-03-19; LoPy with ESP32
    Type "help()" for more information.
    >>>
    

    I added "import config" to a simple LED code, which was previously working but with addition of import config even that file does not want to run/upload properly. Is this a version issue with Visual Studio 1.22.2 or Pymakr 0.1.7, my Python Environment is 3.6
    Thanks again for all your help.



  • @dda databytes is still the wrong format. Is has to by a string or a bytes array. In one of your previous posts, it had the right format already.

    P.S.: I re-edited your post to insert the lines with the three backticks (```). You added backquotes; hard to tell the difference.



  • @dda you can edit your previous posts. Also please edit them to add ``` before and after the code sections so they are properly formatted (python code is very sensitive to indentation, and it’s completely lost with the appropriate formatting).

    Also, do not try to join again, the LoRaWAN stack will retry by itself. Just wait for lora.has_joined() to become true.



  • This post is deleted!


  • @robert-hh @jcaron @jmarcelino

    Thank you @robert-hh & @jcaron .Per your suggestions, I did try adding a "manual" delay in my code posted earlier and the s.send error was resolved, but still no data post...maybe I WAS missing the window of time with the manual method. So I took the code you suggested and modified it.

    from network import LoRa
    import pycom
    import socket
    import binascii
    import struct
    import time
    import config
    lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.US915)
    # create an OTA authentication params
    dev_eui = binascii.unhexlify('00xxxxxxxxxxxx00')
    app_eui = binascii.unhexlify('00xxxxxxxxxxxx00'')
    app_key = binascii.unhexlify('53BF98xxxxxxxxxxxxxxxxxxxxxxxxxx')
    pycom.heartbeat(False)  # disable the blue blinking
    pycom.rgbled(0xffa500)  # make the LED light up Orange if the loop reaches here
    # join a network using OTAA**
    lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0)
    # wait until the module has joined the network
    join_wait = 0
    while True:
        time.sleep(2.5)
        if not lora.has_joined():
            join_wait += 1
            if join_wait == 5:
                lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0)
                join_wait = 0
        else:
            break
    # create a LoRa socket/ data rate / blocking
    s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
    s.setsockopt(socket.SOL_LORA, socket.SO_DR, 3)
    s.setblocking(True)
    # send this dummp data
    #databytes = 0x110EE206BD0634343400
    #s.send(databytes)
    s.send(bytes([0x11,0x0E,0xE2,0x06,0xBD,0x06,0x34,0x34,0x34,0x00]))
    s.setblocking(False)
    data = s.recv(64)
    print(data)
    pycom.rgbled(0x00ff00)  # make the LED light up Green if the loop reaches here
    

    I am running firmware 1.17.3.b1 on the LoPy board to which seems be the latest
    When I tried to Run and Upload the above program with VS Code 1.22.2, I get error for "import config" :as no module named 'config' .Following a similar post for import network error I assumed if I uploaded it it will be ignored, but does not seem to be the case. I also tried from lib import config.



  • @dda And, after a OTAA join request, you have to wait & check lora.has_joined() for a join confirm. That will arrive earliest 5 seconds after the request. See also the example at https://github.com/pycom/pycom-libraries/blob/master/examples/lorawan-nano-gateway/otaa_node_US915.py
    That's why you cannot send yet.



  • @robert-hh
    The error it seems is for the s.send, sorry new to this so excuse my brevity.

    from network import LoRa
    import socket
    import time
    import binascii
    import struct
     lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.US915)
    app_eui = binascii.unhexlify('00xxxxxxxxxxxx00')
     app_key=binascii.unhexlify('53BF98xxxxxxxxxxxxxxxxxxxxxxxxxx')
    lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0)
    s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
    s.setsockopt(socket.SOL_LORA, socket.SO_DR, 3)
    s.setblocking(True)
    s.send(bytes([0x11,0x0E,0xE2,0x06,0xBD,0x06,0x34,0x34,0x34,0x00]))
    

    At Run

    Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
    OSError: [Errno 100] ENETDOWN**
    s.setblocking(False)
    data = s.recv(64)
    print(data)
    


  • @dda Yes, I understand.- But if you do not run it from a local file, the line number for the error is always 1, which is not helpful.



  • @robert-hh
    Ran it as REPL on Visual Studio Code ver 1.21.1 "Terminal" and retried the same on Atom Terminal....same result.
    My understanding is if runs as REPL it should as *.py...so I was trying to make sure the code works, before loading it on the device file.



  • @dda is that code, already stored on the device in a file like mymodule.py, and the executed with import mymodule,
    or how do you try to run it?
    Just a note: In lorawan you will not receive anything earlier than 1 seconmd after sending. An to call s.recv() before the send has finished might be a problem. Maybe you try something like time.sleep(2) after sending.



  • @jmarcelino
    version 2 of the code:

    from network import LoRa
    import socket
    import time
    import binascii
    import struct
    lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.US915)
    app_eui = binascii.unhexlify('00xxxxxxxxxxxx00')
    app_key = binascii.unhexlify('53BF98xxxxxxxxxxxxxxxxxxxxxxxxxx')
    lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0)
    s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
    s.setsockopt(socket.SOL_LORA, socket.SO_DR, 3)
    s.setblocking(True)
    s.send(bytes([0x11,0x0E,0xE2,0x06,0xBD,0x06,0x34,0x34,0x34,0x00]))
    s.setblocking(False)
    data = s.recv(64)
    print(data)
    

    This code gives me :
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    OSError: [Errno 100] ENETDOWN

    The ENETDOWN error is for "The local network interface used to reach the destination is down."
    But, I see successful join and accept...but no uplink of data



  • @jmarcelino
    I have modified the code to hide some of the proprietor stuff and masked the app_key and app_key here is version 1 versions of the code:

    from network import LoRa
    import socket
    import time
    import binascii
    import struct
    lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.US915)
    app_eui = binascii.unhexlify('00xxxxxxxxxxxx00')
    app_key = binascii.unhexlify('53BF98xxxxxxxxxxxxxxxxxxxxxxxxxx')
    lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0)
    battvoltage=0x110E
    s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
    s.setsockopt(socket.SOL_LORA, socket.SO_DR, 3)
    s.setblocking(True)
    databytes=0x110EE206BD0634343400
    s.send(databytes)
    s.setblocking(False)
    data = s.recv(64)
    print(data)
    

    This code gives me :
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: object with buffer protocol required



  • Hi @dda

    Can you post the Python code you're using for your pack and also what is the JSON received at the Senet end?

    Thank you



Pycom on Twitter