pulkin / micropython

MicroPython implementation on Ai-Thinker GPRS module A9 (RDA8955)
https://micropython.org
MIT License
103 stars 31 forks source link

[Enhancement] Implementation of a Standard IP GPS Communication Protocol #49

Closed sebi5361 closed 4 years ago

sebi5361 commented 4 years ago

Do you plan to implement a standard IP GPS communication protocol to interface the A9G board with a standard GPS tracking server? Available protocols supported by GPS tracking software Traccar are listed here. Should this be implemented in C++ or in MicroPython? Do you know the simplest standard protocol existing?

pulkin commented 4 years ago

That's an interesting activity to approach: a big library with a bunch of reporting protocols. It definitely should be written in python as separate lib (for other ports to benefit from it) and Traccar already implemented it in java. Their server also could be used to test protocols.

You may even approach Traccar or other business with this idea, though more research is needed.

Regarding simple protocols, you could look at Box for example. I am not an expert in all this: you may try asking them directly (and advertise the module at the same time).

sebi5361 commented 4 years ago

I have written this post on the Traccar forum, and I might try to implement a simple communication protocol...

sebi5361 commented 4 years ago

Here is the little code that explains how to send GPS locations to a Traccar GPS tracking server, using OsmAnd, an HTTP-based GPS communication protocol:

import cellular
import gps
import socket

ID = 1234567 # Same arbitrary number as in Traccar
url = "demo.traccar.org"
port = 5055

cellular.gprs("internet", "", "") # Adjust with your APN credentials

gps.on()
loc = gps.get_location()

s = socket.socket()
s.connect((url, port))
s.send(bytes('POST /?id={}&lat={}&lon={} HTTP/1.1\r\nHost: {}:{}\r\n\r\n'.format(ID, loc[0], loc[1], url, port), 'utf8'))
s.recv(50) # Should be b'HTTP/1.1 200 OK\r\ncontent-length: 0\r\n\r\n'

s.close()
gps.off()
cellular.gprs(False)

You can add it to the example folder...

pulkin commented 4 years ago

Thanks, I will!

sebi5361 commented 4 years ago

While experimenting, I have noticed a few bugs (that do not occur on an ESP8266):

sebi5361 commented 4 years ago

Behaviors of those commands on an ESP8266 with the latest firmware are:

pulkin commented 4 years ago

Added (and tested) the example: 023c913be74b03da262e6df1c55bb9937b6a2f3b

sebi5361 commented 4 years ago

Can you explain me the main difference between s.write(...), s.read(...) and s.send(...), s.recv(...)? It is not that clear to me which ones I should use...

sebi5361 commented 4 years ago

For better readability, I opened a separate post regarding those bugs and am closing this post.

pulkin commented 4 years ago

I do not think there is much difference between send-write (recv-read) in micropython. It is just that the API has socket_makefile which has to return a file-like object with read and write. In mpy it returns self: this is why sockets implement all file-like methods in addition to send and recv. I.e. for compatibility reasons.

sebi5361 commented 4 years ago

Even more simple is a variant of the code based on urequests rather than socket:

import urequests
assert urequests.post("http://{}:{}/?id={}&lat={}&lon={}".format(url, port, ID, *gps.get_location())).status_code == 200
sebi5361 commented 4 years ago

When sending multiples locations over time, the main difference between those two approaches is that:

Which approach do you think is the best?