Digi XBee Cellular to Ubidots using MicroPython

Hi,

I am working with this tutorial utilizing the new Digi XBee 3 Cellular LTE-M/NB-IoT modem (set to use LTE-M only) and I can successfully send data to Ubidots as expected.

The issue I am experiencing is even on a 15 second send interval to Ubidots I am timing out after about the first 3 sends.

Is there a more up to date or more efficient sent protocol than what is detailed in the tutorial I linked?

I have a similar gateway device utilizing the Particle.io platform and it handles the send interval I am seeking just fine utilizing the Ubidots ubidots(TOKEN, UBI_TCP); protocol.

Here is a screenshot showing the results of a successful send:

Thank you!

I am not sure if there is a more efficient way to handle connections with this particular device, but the example that you have just followed is based on the official tutorial by Digikey that you may find here, so I’d suppose that it is the proper way to send bytes through TCP. Have you tried increasing the socket timeout by invoking the settimeout() method?

@jotathebest thank you for the link. and reference to settimeout().

Is it possible that I am connecting and closing the socket to many times in a short period of time?

I did get a ENFILE (no sockets are available) error after trying settimeout(0) which sets the socket timeout to zero (non-blocking) and a few

Do I have to go through the socket connect, and close sequence for each data push or can a socket be left open for say 15 seconds or so in case multiple sends need to occur during the open socket session.

EDIT:
It takes ~65-68 seconds for the dump_socket(s) to complete.

The closest I have gotten to getting it to continue to run is setting s.settimeout(0) and closing the socket right after the s.send(request) and commenting out the dump_socket(s).

Thank you

Appreciated @Backpacker87, as I do not know the detail of your code, I would not be sure to say if this is the issue that you are experiencing. For the sake of your research, all IoT devices able to implement TCP connections have a limited number of available sockets, e.g, the photon by Particle devices has 4 available sockets. All these devices usually expose a way to free sockets through a method of the socket instance and, as a good firmware practice, any socket that you open should be closed after getting a server response or a timeout.

I am not familiar with this particular Digikey device, but following their docs, you should invoke the collect() method to free any unused socket.

My advice, for your particular issue and as I am not familiar with your device, is to try to reach directly with the DigiKey support team, as this is not related to our platform. Anyway, feel free to write here your doubts and I will be happy to be helpful in any tech way that I may contribute to solving your issue.

All the best

@jotathebest, thank you very much for your thoughful response.

Blockquote
as a good firmware practice, any socket that you open should be closed after getting a server response or a timeout.

Thanks, this is very helpful to know.

One last question regarding

It takes ~65-68 seconds for the dump_socket(s) to complete. This is being called like so:

def sendUbidotsData(device_label, token, body):
    print("Label %s data %s" % (device_label, body))
    s = usocket.socket()
    s.connect(("industrial.api.ubidots.com", 80))
    s.settimeout(0)
    request = bytes(
        'POST /api/v1.6/devices/%s HTTP/1.1\r\nHost: industrial.api.ubidots.com\r\nX-Auth-Token: %s\r\nContent-Type: application/json\r\nContent-Length: %s\r\n\r\n%s\r\n' % (
            device_label, token, len(body), body), 'utf8')
    ticks1 = time.ticks_ms()
    s.send(request)
    dump_socket(s)
    ticks2 = time.ticks_ms()
    diff = str(time.ticks_diff(ticks2, ticks1)/1000)
    print("time to send (sec): " + diff)

What would be an approximate response time to expect, I would imagine that 65-68 seconds seems way to long. FYI The dump_socket(s) is implemented in the same way as the Ubidots sample.

def dump_socket(s):
    try:
        while True:
            data = s.recv(100)
            if data:
                print(str(data, 'utf8'), end='')
            else:
                print('')  # end with newline
                s.close()
                break
    except:
        s.close()
        raise

Thank you.

that’s something that depends on several factors:

  • Network connection availability
  • Network bandwidth
  • Device processing power
  • Socket packet size
  • Iot protocol (HTTP, UDP, TCP, MQTT)

For example, a packet size of 200 bytes, using TCP, would need more time to be sent to Ubidots than a packet of 100 bytes, so you would need to set a higher timeout based on your packet size. Also, if you are sending data using GPRS and a 2G or 3G network, data upload may take more time to be delivered. These sorts of considerations are out of our scope and management. At my side, for example, with an ethernet connection, to send a single dot takes me ~1 second:

this time would change at your device side, based on the parameters of my previous explanation.

Said this, besides 65 - 68 seconds may seem a high time, depending on your particular device env conditions, may not.

@jotathebest thank you very much for your response it is helpful!