How to send data using the GPy


#1

Hi all,

We just got our GPy from Pycom up and running online, connecting to the internet using LTE CAT M1.

How do we actually send data from the device to somewhere on the internet? Any help there?

We can send it through hologram I believe, or is that false?

Can we send it without using the hologram webhooks to our database?

Thanks!

below is the code used to initially connect on LTE-CAT M1

import time
from machine import RTC
from network import LTE

NTP_SERVER = "us.pool.ntp.org"

# Need to use global variables.
# If in each function you delare a new reference, functionality is broken
lte = LTE()
rtc = RTC()

# Returns a network.LTE object with an active Internet connection.
def getLTE():

    # If already used, the lte device will have an active connection.
    # If not, need to set up a new connection.
    if lte.isconnected():
        return lte

    # Modem does not connect successfully without first being reset.
    print("Resetting LTE modem ... ", end="")
    lte.send_at_cmd('AT^RESET')
    print("OK")
    time.sleep(1)
    #print(".\n")
    # While the configuration of the CGDCONT register survives resets,
    # the other configurations don't. So just set them all up every time.
    print("Configuring LTE ", end='')
    lte.send_at_cmd('AT+CGDCONT=1,"IP","hologram"')  # Changed this from origninal
    print(".", end='')
    lte.send_at_cmd('AT!="RRC::addscanfreq band=4 dl-earfcn=9410"') # changed band from 28 to 4. I dont know what earfcn=9410 is;
    print(".", end='')
    lte.send_at_cmd('AT+CFUN=1')
    print(" OK")

    # If correctly configured for carrier network, attach() should succeed.
    if not lte.isattached():
        print("Attaching to LTE network ", end='')
        lte.attach()
        while(True):
            if lte.isattached():
                print(" OK")
                break
            print('.', end='')
            time.sleep(1)

    # Once attached, connect() should succeed.
    if not lte.isconnected():
        print("Connecting on LTE network ", end='')
        lte.connect()
        while(True):
            if lte.isconnected():
                print(" OK")
                break
            print('.', end='')
            time.sleep(1)

    # Once connect() succeeds, any call requiring Internet access will
    # use the active LTE connection.
    return lte

# Clean disconnection of the LTE network is required for future
# successful connections without a complete power cycle between.
def endLTE():

    print("Disonnecting LTE ... ", end='')
    lte.disconnect()
    print("OK")
    time.sleep(1)
    print("Detaching LTE ... ", end='')
    lte.dettach()
    print("OK")

# Sets the internal real-time clock.
# Needs LTE for Internet access.
def setRTC():

    # Ensures LTE session is connected before attempting NTP sync.
    lte = getLTE()

    print("Updating RTC from {} ".format(NTP_SERVER), end='')
    rtc.ntp_sync(NTP_SERVER)
    while not rtc.synced():
        print('.', end='')
        time.sleep(1)
    print(' OK')

# Only returns an RTC object that has already been synchronised with an NTP server.
def getRTC():

    if not rtc.synced():
        setRTC()

    return rtc

# Program starts here.
try:
    print("Initially, the RTC is {}".format("set" if rtc.synced() else "unset"))
    rtc = getRTC()
    while(True):
        print("RTC is {}".format(rtc.now() if rtc.synced() else "unset"))
        time.sleep(5)
except Exception:
    pass # do nothing on error

finally:
    endLTE()

#2

Hey @Mattliddle,

I can’t speak directly to the GPy, but the Hologram SIM gives your device access to the internet. If you choose to you can do all the messaging outside of the Hologram platform. Otherwise, if you want to have the Dashboard be your SIM management and communications center and, like you suggest, use routes to then use that information in other services you can use our embedded api to get your data into the dashboard.

Here is a guide that goes over that process for the Arduino MKR 1400 which won’t be exactly the same process, but should have some themes in common with the GPy.

Best,
Maiky


#3

Thanks @Maiky

Those are exactly what I was looking for. Thank you so much!

Like you said, it’s not the exact same as the GPy, but I see similarities, and I think I can convert it over to micropython for my application. I’ll try it out and let you know.


#4

Sure thing @Mattliddle. Happy this was what you were looking for. Curious to see your results as hopefully those will help future users.

Best,
Maiky


#5

Hello,
I’m working on a similar project. I’ve been able to connect to LTE and to the hologram web socket, but I am unable to send the message. Here is the code I am using to set up the socket, but it throws an error when it gets to the s.send() line.

s = socket.socket()
s.connect(socket.getaddrinfo('cloudsocket.hologram.io', 9999)[0][-1])
s.send({"k":"ABCDWXYZ","d":"Hello, World!","t":"TOPIC1"})
print(s.recv(4096))
s.close()

#(that isn’t the actual devicekey that I am using, I generated one for my SIM card in the hologram dashboard)

I’d appreciate any help!


#6

@Maiky Thank you for sharing that Arduino example. I tried changing my s.send() from s.send({"k":"ABCDWXYZ","d":"Hello, World!","t":"TOPIC1"})
to
s.send("{\"k\":\"" + HOLOGRAM_API_KEY +"\",\"d\":\""+ HOLOGRAM_MESSAGE+ "\",\"t\":\""+HOLOGRAM_TOPIC+"\"}")
with
HOLOGRAM_API_KEY = “ABCDWXYZ”
HOLOGRAM_MESSAGE = “Hello, World!”
HOLOGRAM_TOPIC = “TOPIC1”

to match the Arduino example but it didn’t seem to make a difference. Do you (or anyone) have any suggestions?

@ChrisGammell, I saw that you made a number of comments in this post on Pycom’s forum. Did you ever have any success sending messages from your GPy to the Hologram Dashboard? Thanks!


#7

@AWalters I think I found the solution. After experimenting with it a bit, I think the hologram socket requires the data to be sent as a byte array in ASCII format. Is that correct @Maiky and @ChrisGammell ? The Python syntax can be a little tricky, but I think a little more documentation on what the hologram socket requires or more clarity would be helpful. It doesn’t state that data being sent needs to be a byte array in ASCII format. Perhaps I’m mistaken about that, but that’s the only way I could get it to work.

So if you break it up and put it into that proper format you can successfully send it. The main thing is getting the proper dns record element passed into the connect function and to then send the data as a byte array in ASCII format (see in the “Try” section closer to the bottom). Below, you can see the modified code. I also recommend for debugging, printing the error statements, when it fails and runs to the Exception.

import socket
import time
import pycom
from machine import RTC
from network import LTE
from network import WLAN

HOST = "cloudsocket.hologram.io"
PORT = 9999
DEVICE_KEY = "ABCDEFG"
TOPIC = "TOPIC1"

# # Need to use global variables.
# # If in each function you delare a new reference, functionality is broken
lte = LTE()

# Returns a network.LTE object with an active Internet connection.
def getLTE():
    # If already used, the lte device will have an active connection.
    # If not, need to set up a new connection.
    if lte.isconnected():
        return lte

    # Modem does not connect successfully without first being reset.
    print("Resetting LTE modem ... ", end="")
    lte.send_at_cmd('AT^RESET')
    print("OK")
    time.sleep(1)
    # While the configuration of the CGDCONT register survives resets,
    # the other configurations don't. So just set them all up every time.
    print("Configuring LTE ", end='')
    lte.send_at_cmd('AT+CGDCONT=1,"IP","hologram"')  # Changed this from origninal
    print(".", end='')
    lte.send_at_cmd('AT!="RRC::addscanfreq band=4 dl-earfcn=9410"') # changed band from 28 to 4. I dont know what earfcn=9410 is;
    print(".", end='')
    lte.send_at_cmd('AT+CFUN=1')
    print(" OK")

    # If correctly configured for carrier network, attach() should succeed.
    if not lte.isattached():
        print("Attaching to LTE network ", end='')
        lte.attach()
        while(True):
            if lte.isattached():
                print(" OK")
                #pycom.rgbled(0x00FF00)
                #time.sleep(.5)
                #pycom.rgbled(0x000000)
                break
            print('.', end='')
            time.sleep(1)

    # Once attached, connect() should succeed.
    if not lte.isconnected():
        print("Connecting on LTE network ", end='')
        lte.connect()
        while(True):
            if lte.isconnected():
                print(" OK")
                break
            print('.', end='')
            time.sleep(1)

    # Once connect() succeeds, any call requiring Internet access will
    # use the active LTE connection.
    return lte

# Clean disconnection of the LTE network is required for future
# successful connections without a complete power cycle between.
def endLTE():
    print("Disonnecting LTE ... ", end='')
    lte.disconnect()
    print("OK")
    time.sleep(1)
    print("Detaching LTE ... ", end='')
    lte.dettach()
    print("OK")
    
# Program starts here.
try:
    lte = getLTE()
    print(lte)
    s = socket.socket()
    print(s)

    dns_records = socket.getaddrinfo(HOST, PORT)
    print("got dns_records")
    print(dns_records)
    
    message = "Hello World!"
    
    for record in dns_records:
        try:
            s.connect(record[-1])
            print("connected")
            data = '{"k": "%s", "d": "%s", "t": "%s"}' % (DEVICE_KEY, message, TOPIC)
            s.send(bytes(data, 'ascii'))
            print("sent")
            result = s.recv(8).decode()
            print(result)
            s.close()
            break
        except Exception as err1:
            try:
                s.close()
            except:
                pass
            print(err1)
            continue

except Exception as err:
    print(err)
    try:
        s.close()
    except:
        pass

finally:
   endLTE()

#8

Hi, to help out here, this is all correct but I think it depends on your python version. Python 3 requires that you pass bytes objects into sockets while I think 2 uses strings. I think our API would accept ASCII or UTF8.


#9

Thank you for sharing that @Reuben. That sounds like it makes sense, the micropython for the GPy must require it then.

Thanks!