GPS Event [2] – Object
After some tinkering I was able to cook up some Python code to get the GPS data. So, a Magellan Meridian Gold GPS is connected over the serial port to a PC running Windows XP and Python. The Python version I am using is 2.52 and if you want to play with the code you may want to install the pySerial library before starting.
First, here is the result—cut & paste—from Python Shell.
<event>
<head>
<id>91ce7524-3336-4619-a9a0-e8ee32d2f609</id>
<type>GPS</type>
<time_stamp>2008-12-30T20:19:31Z</time_stamp>
<entity>DS_GPS_001</entity>
</head>
<body>
<latitude>43 38.8317 N</latitude>
<longitude>079 23.8942 W</longitude>
<speed>00.0</speed>
<course>000.0</course>
<valid>True</valid>
</body>
</event>
<event>
<head>
<id>aed3e5b7-f98a-49d1-b950-4434331df8ae</id>
<type>GPS</type>
<time_stamp>2008-12-30T20:19:42Z</time_stamp>
<entity>DS_GPS_001</entity>
</head>
<body>
<latitude>43 38.8289 N</latitude>
<longitude>079 23.8965 W</longitude>
<speed>00.0</speed>
<course>000.0</course>
<valid>True</valid>
</body>
</event>
The program reads the serial port every 10-12 seconds, extracts the position and speed data from a $GPRMC message and packages the data into XML form of an event object.
The Python code has two modules (files), the first one— gps_event_template.py —contains only a template for XML and JSON strings; the main module— gps_event.py —has all the working code.
The template has placeholders—like $time_stamp_here$ —which are simply later replaced by GPS data.
gps_event_template.py
XML & JSON templates for GPS event
"""
def xml_template():
"""<?xml version="1.0" encoding="UTF-8"?>
<event>
<head>
<id>$id_here$</id>
<type>$type_here$</type>
<time_stamp>$time_stamp_here$</time_stamp>
<entity>$entity_here$</entity>
</head>
<body>
<latitude>$latitude_here$</latitude>
<longitude>$longitude_here$</longitude>
<speed>$speed_here$</speed>
<course>$course_here$</course>
<valid>$valid_here$</valid>
</body>
</event>
"""
def json_template():
"""{
"event":{
"head":{"id":"$id_here$",
"type":"$type_here$",
"time_stamp":"$time_stamp_here$",
"entity":"$entity_here$"
},
"body":{"latitude":"$latitude_here$",
"longitude":"$longitude_here$",
"speed":"$speed_here$",
"course":"$course_here$",
"valid":"$valid_here$"
}
}
}
"""
def compress_template(s):
""" Compress XML or JSON template """
rli = {'{ ':'{', ' }':'}', ', "':',"', '> <':'><'}
st = ' '.join(s.split())
for (k, v) in rli.items():
st = st.replace(k, v)
return st
if __name__ == "__main__":
print xml_template.__doc__
print json_template.__doc__
print compress_template(xml_template.__doc__)
print compress_template(json_template.__doc__)
Here is the main module; if running from Python Shell, start this one. Python is an easy read, so you should not have trouble following. The sendToCep(xst) function simply prints the XML to the Shell; I need to tinker with the CEP server before implementing this one. Keep in mind that this is a blog-as-you-go project.
gps_event.py
Reads position and speed data from Magellan Meridian Gold GPS
--connected on COM 1-- every 10-12 seconds.
Packages GPS data into XML and sends to a CEP server.
"""
from datetime import datetime
import time
import serial
import uuid
import gps_event_template
import gps_aws
ser = serial.Serial()
ser_mode = True
sample_delay = 10
msg_cnt = 1
obj = {'id':'','type':'GPS','time_stamp':'','entity':'DS_GPS_001',
'latitude':'', 'longitude':'','speed':'', 'course':'', 'valid':''}
def gps_main():
""" Read GPS every 10-12 seconds, send XML to CEP """
(ser.port, ser.baudrate, ser.timeout) = (0, 4800, 4)
ser.open()
try:
while 1:
st = readGps()
if st:
sendToCep(st)
else:
# break
pass
time.sleep(sample_delay)
finally:
ser.close()
return '*** ABORTING gps_event.py ***'
def readGps():
""" Read GPS, create XML if valid reading """
global ser_mode
ser.flushInput()
li = readCom(ser_mode)
if li[0] == '$GPRMC':
obj['id'] = str(uuid.uuid4())
parseGpsData(li)
st = makeOutputString(fmt = 'X', pretty = 0)
else:
st = None
return st
def makeOutputString(fmt = 'X', pretty = 0):
""" Make XML or JSON string """
if fmt == 'J':
st = gps_event_template.json_template.__doc__
else:
st = gps_event_template.xml_template.__doc__
if pretty == 0:
st = gps_event_template.compress_template(st)
for (k,v) in obj.items():
st = st.replace('$%s_here$'%(k,), v)
return st
def parseGpsData(li):
""" Parse GPS list to object """
obj['time_stamp'] = make_ts(li[1],li[9])
obj['latitude'] = make_ll(li[3],li[4])
obj['longitude'] = make_ll(li[5],li[6])
obj['course'] = li[8]
obj['speed'] = li[7]
obj['valid'] = 'True' if li[2] == 'A' else 'False'
def readCom(sm = False):
""" Read COM port, split GPS string to a list """
(i, st) = (0, ['?'])
while (i <25):
i = i + 1
if sm:
ln = ser.readline()
else:
ln = "$GPRMC,172021.20,A,4338.8243,N,"
ln = ln + "07923.9149,W,00.0,000.0,291208,11,W*48"
if ln:
s1 = ln.split(",")
# print s1
if s1[0] == '$GPRMC':
st = s1
break
return st
def make_ts(tim, dte):
""" Make time-stamp """
return datetime(int('20' + dte[4:]), int(dte[2:4]), int(dte [0:2]),
int(tim[0:2]), int(tim[2:4]), int(tim[4:6])).isoformat() + 'Z'
def make_ll(c, s):
""" Make lattitude and longitude """
i = len(c) - 7
return ' '.join([c[:i], c[i:], s])
def sendToCep(xst):
""" Send XML string to EP/CEP/BUS """
print xst # just print for now
if __name__ == "__main__":
print gps_main()
So the next step is a CEP server—install, configure, communicate, do something with.
To be continued.
Column 2 : Bookmarks for December 31st:
[...] Damir Systems Inc. » Blog Archive » GPS Event [2] - My intrepid other half, bored over the holidays, teaches himself Python, hacks his GPS and starts experimenting with pushing the data into CEP. Posted by Sandy Kemsley on Wednesday, December 31, 2008, at 12:00 pm. Filed under Links. Follow any responses to this post with its comments RSS feed. You can post a comment or trackback from your blog. [...]
2008-12-31, 17:00 UTC