summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'gps_python_html/gps_tracker_gui_v1.0.py')
-rw-r--r--gps_python_html/gps_tracker_gui_v1.0.py349
1 files changed, 349 insertions, 0 deletions
diff --git a/gps_python_html/gps_tracker_gui_v1.0.py b/gps_python_html/gps_tracker_gui_v1.0.py
new file mode 100644
index 0000000..295caa9
--- /dev/null
+++ b/gps_python_html/gps_tracker_gui_v1.0.py
@@ -0,0 +1,349 @@
1import time
2import serial
3import webbrowser
4import os
5from serial.tools import list_ports
6import datetime
7from tkinter import *
8from tkinter import ttk
9from tkinter import messagebox
10from tkinter.filedialog import askopenfilename
11from tkinter.filedialog import asksaveasfilename
12from serial.tools import list_ports
13import csv
14import re
15
16#
17# /******************************************************************************
18
19# @file gps_tracker_gui.py
20
21# @brief front end file
22
23# Group: WCS LPC
24# $Target Device: DEVICES $
25
26# ******************************************************************************
27# $License: BSD3 2016 $
28# ******************************************************************************
29# $Release Name: PACKAGE NAME $
30# $Release Date: PACKAGE RELEASE DATE $
31# *****************************************************************************/
32#
33
34class App:
35
36 # GLOBALS
37 nodes = []
38 known_addresses = []
39 gpsTurnedOn = FALSE
40 gpsStayOn = FALSE
41 ser = serial.Serial()
42 comport = ''
43 csvName = ''
44 append = FALSE
45 cancel = FALSE
46 serReads = [1]
47
48 # DEFINITIONS
49 class Node:
50 def __init__(self, address):
51 self.addr = address
52 self.gps = []
53
54 class Fix:
55 lat = ''
56 lng = ''
57 latDM = ''
58 lngDM = ''
59 alt = ''
60 rssi = ''
61 fixTime = '' # Time GPS fix was taken
62 plotTime = '' # Time fix is plotted
63
64 # FUNCTIONS
65 def writeData(self, addr, fix, overwrite_csv):
66 f = open('gpsdata.js', 'rb+')
67 f.seek(-1, 2)
68 f.truncate()
69 f.close()
70 f = open('gpsdata.js', 'r+')
71 f.seek(0, 2)
72 f.write('{ addr: ' + str(addr) + ', ' \
73 + 'lat: ' + fix.lat + ', ' \
74 + 'lng: ' + fix.lng + ', ' \
75 + 'alt: ' + fix.alt + ', ' \
76 + 'rssi: ' + fix.rssi + ', ' \
77 + 'time: \'' + fix.fixTime + '\' },\n]')
78 f.close()
79 now = datetime.datetime.utcnow()
80
81 #if(not overwrite_csv):
82 with open(self.csvName, 'a', newline='') as csvfile:
83 writer = csv.writer(csvfile)
84 writer.writerow((str(addr), fix.lat, fix.lng, fix.alt, fix.rssi, fix.fixTime, str(now.year) \
85 + '-' + str(now.month).zfill(2) \
86 + '-' + str(now.day).zfill(2), fix.latDM, fix.lngDM, fix.plotTime))
87
88 def addFix(self, addr, fix, overwrite_csv):
89 if addr not in self.known_addresses:
90 self.nodes.append(self.Node(addr))
91 self.known_addresses.append(addr)
92 self.nodes[self.known_addresses.index(addr)].gps.append(fix)
93 self.writeData(addr, fix, overwrite_csv)
94
95 def serialUpdate(self, event):
96 ports = sorted(list_ports.comports())
97 self.port_names = []
98 for i, port in enumerate(ports):
99 if "Application" in port.description:
100 self.port_names.append(port.device)
101 self.serialBox['values'] = self.port_names
102
103 def serialGet(self, event):
104 self.comport = self.serialBox.get()
105
106 def overwriteCSV(self, ow):
107 self.overwrite = TRUE
108 ow.destroy()
109
110 def appendCSV(self, ow):
111 self.overwrite = FALSE
112 ow.destroy()
113
114 def cancelCSV(self, ow):
115 self.cancel = TRUE
116 ow.destroy()
117
118 # MAIN PROGRAM FUNCTIONS
119 def startGPS(self):
120
121 self.serialBox.state = "disabled"
122
123 if(self.gpsTurnedOn == FALSE):
124 self.gpsTurnedOn = TRUE
125 self.overwrite = FALSE
126 self.cancel = FALSE
127
128 self.csvName = asksaveasfilename(initialdir = "/csv", title = "New csv File", defaultextension = ".csv",filetypes = (("csv files","*.csv"),("all files","*.*")))
129
130 # Overwrite or append file?
131 if os.path.isfile(self.csvName):
132 ow = Toplevel()
133 ow.title('Overwrite')
134 ow.geometry('300x100')
135 frame1 = Frame(ow)
136 frame2 = Frame(ow)
137 frame1.place(relx=0.05, rely=0.1, relheight=0.4, relwidth=0.9)
138 frame2.place(relx=0.05, rely=0.5, relheight=0.4, relwidth=0.9)
139
140 Label(frame1, text="Overwrite or append to existing file?").place(relx=0.5, rely=0, anchor=N)
141 Button(frame2, text='Overwrite', command=lambda: self.overwriteCSV(ow)).place(relx=0, relwidth=0.3, anchor=NW)
142 Button(frame2, text='Append', command=lambda: self.appendCSV(ow)).place(relx=0.5, relwidth=0.3, anchor=N)
143 Button(frame2, text='Cancel', command=lambda: self.cancelCSV(ow)).place(relx=1, relwidth=0.3, anchor=NE)
144 self.master.wait_window(ow)
145 else:
146 self.overwrite = TRUE
147
148 if self.cancel == FALSE:
149 if self.overwrite:
150 f = open(self.csvName, 'w')
151 f.truncate()
152 f.close()
153 with open(self.csvName, 'w', newline='') as csvfile:
154 writer = csv.writer(csvfile)
155 writer.writerow(('Node Address', 'Latitude (°)', 'Longitude (°)', \
156 'Altitude (m)', 'RSSI (dBm)', 'Time of Fix (UTC)', 'Date', \
157 'Latitude (DM)', 'Longitude (DM)', 'Time of Plot (UTC)'))
158
159 self.ser = serial.Serial(self.comport, 115200, timeout=0.5)
160
161 # Erase js file
162 f = open('gpsdata.js', 'r+')
163 f.truncate()
164 f.write('var gps = [\n]')
165 f.close()
166
167 webbrowser.open('cc13xx_map.html')
168
169 self.gpsStayOn = TRUE
170
171 else:
172 self.stopGPS()
173
174 if self.gpsStayOn:
175 in_str = ''
176
177 if self.ser.in_waiting > 0:
178 try:
179 in_byte = self.ser.read(1)
180
181 except:
182 self.stopGPS()
183
184 else:
185 in_str = in_byte.decode('utf-8')
186
187 if in_str == '$':
188 try:
189 in_byte = self.ser.read(18)
190
191 except TypeError as e:
192 in_str = ''
193 messagebox.showinfo('Error', 'COM Port Disconnected')
194 self.stopGPS()
195
196 else:
197 address = in_byte[0]
198 rssi = int.from_bytes(bytes([in_byte[1]]), byteorder='little', signed=True)
199 latDM = int.from_bytes(in_byte[2:4], byteorder='little', signed=True)
200 latm = int.from_bytes(in_byte[4:7], byteorder='little', signed=False)
201 lngDM = int.from_bytes(in_byte[7:9], byteorder='little', signed=True)
202 lngm = int.from_bytes(in_byte[9:12], byteorder='little', signed=False)
203 altA = int.from_bytes(in_byte[12:14], byteorder='little', signed=False)
204 alta = in_byte[14]
205 time = in_byte[15:]
206
207 gps = self.Fix()
208
209 latmstr = str(latm).zfill(6)
210 lngmstr = str(lngm).zfill(6)
211
212 gps.latDM = str(latDM)[0:-2] + ' ' + str(latDM)[-2:] + '.' + latmstr
213 gps.lngDM = str(lngDM)[0:-2] + ' ' + str(lngDM)[-2:] + '.' + lngmstr
214 gps.lat = str(latDM)[0:-2] \
215 + str(float(str(latDM)[-2:] \
216 + '.' + latmstr)/60)[1:10]
217 gps.lng = str(lngDM)[0:-2] \
218 + str(float(str(lngDM)[-2:] \
219 + '.' \
220 + lngmstr)/60)[1:10]
221 gps.alt = str(altA) + '.' + str(alta)
222 gps.fixTime = str(time[0]).zfill(2) + ':' \
223 + str(time[1]).zfill(2) + ':' \
224 + str(time[2]).zfill(2)
225 gps.rssi = str(rssi)
226
227 now = datetime.datetime.utcnow()
228 gps.plotTime = str(now.hour).zfill(2) + ':' \
229 + str(now.minute).zfill(2) + ':' \
230 + str(now.second).zfill(2)
231
232 self.addFix(address, gps, self.overwrite)
233
234 self.master.after(100, self.startGPS)
235 else:
236 self.gpsTurnedOn = FALSE
237
238 def stopGPS(self):
239 if self.gpsStayOn:
240 self.ser.close()
241 self.serialBox.set('')
242 self.serialBox.state = "enabled"
243 self.gpsStayOn = FALSE
244 self.csvName = ''
245
246 def saveCSV(self):
247 f_name = asksaveasfilename(initialdir="/", title="Filename to save as", \
248 defaultextension=".csv", \
249 filetypes=(("csv files", "*.csv"), ("all files", "*.*")))
250 with open(f_name, 'w', newline='') as csvfile:
251 writer = csv.writer(csvfile)
252 writer.writerow(('Node Address', 'Latitude (°)', 'Longitude (°)', 'Altitude (m)', \
253 'RSSI (dBm)', 'Time of Fix (UTC)', 'Date', 'Latitude (DM)', \
254 'Longitude (DM)', 'Time of Plot (UTC)'))
255 for n in self.nodes:
256 for fix in n.gps:
257 writer.writerow((str(n.addr), fix.lat, fix.lng, fix.alt, fix.rssi, \
258 fix.fixTime, str(now.year) + '-' + str(now.month).zfill(2) \
259 + '-' + str(now.day).zfill(2), fix.latDM, fix.lngDM, fix.plotTime))
260
261 def openCSV(self):
262 # Reset variables
263 self.nodes = []
264 self.known_addresses = []
265
266 f = open('gpsdata.js', 'r+')
267 f.truncate()
268 f.write('var gps = [\n]')
269 f.close()
270
271 f = open('gpsdata.js', 'rb+')
272 f.seek(-1, 2)
273 f.truncate()
274 f = open('gpsdata.js', 'r+')
275 f.seek(0, 2)
276
277 self.csvName = askopenfilename(initialdir="/csv", title="Select file to open", \
278 filetypes=(("csv files", "*.csv"), ("all files", "*.*")))
279 with open(self.csvName) as csvfile:
280 readCSV = csv.reader(csvfile)
281 for i, row in enumerate(readCSV):
282 if i > 0:
283 f.write('{ addr: ' + row[0] + ', ' \
284 + 'lat: ' + row[1] + ', ' \
285 + 'lng: ' + row[2] + ', ' \
286 + 'alt: ' + row[3] + ', ' \
287 + 'rssi: ' + row[4] + ', ' \
288 + 'time: \'' + row[5] + '\' },\n')
289 f.write(']')
290 f.close()
291 self.csvName = ''
292
293 webbrowser.open('cc13xx_map.html')
294
295 def __init__(self, master):
296
297 self.master = master
298 self.master.title('GPS Range Test')
299 self.master.resizable(width=False, height=False)
300 self.master.geometry("275x240")
301
302 #title = Label(root,text='TI CC13xx GPS to Map')
303 self.frame1 = Frame(root)
304 self.frame2 = Frame(root)
305 self.frame4 = Frame(root)
306 self.frame5 = Frame(root)
307
308 self.frame1.place(relx=0.1, rely=0.1, relheight=0.15, relwidth=0.8)
309 self.frame2.place(relx=0.1, rely=0.25, relheight=0.25, relwidth=0.8)
310 self.frame4.place(relx=0.1, rely=0.5, relheight=0.2, relwidth=0.8)
311 self.frame5.place(relx=0.1, rely=0.73, relheight=0.2, relwidth=0.8)
312
313 # title
314 self.Title = Label(self.frame1, text="TI CC13xx GPS Range Test", \
315 justify=CENTER, font=("Arial Bold", 10))
316 self.Title.pack(fill=BOTH)
317
318 # Buttons
319 self.bStart = Button(self.frame4, state=NORMAL, text="Start", \
320 command=self.startGPS).place(rely=0.15, relheight=.7, relwidth=.45)
321 self.bStop = Button(self.frame4, state=NORMAL, text="Stop", \
322 command=self.stopGPS).place(relx=0.55, rely=0.15, relheight=.7, relwidth=.45)
323 self.bOpen = Button(self.frame5, state=NORMAL, text="Open .csv", \
324 command=self.openCSV).place(rely=0.15, relheight=.7, relwidth=1)
325
326 # Get COM ports
327 self.port_names = []
328 ports = sorted(list_ports.comports())
329 for i, port in enumerate(ports):
330 if "Application" in port.description:
331 self.port_names.append(port.device)
332
333 # Com Ports Dropdown
334 self.serialLabel = Label(self.frame2, text="Serial Port", font=("Arial", 8))
335 self.serialLabel.place(rely=0)
336 self.serialBox = ttk.Combobox(self.frame2)
337 self.serialBox.bind("<<ComboboxSelected>>", self.serialGet)
338 self.serialBox.bind("<Button-1>", self.serialUpdate)
339 self.serialBox.place(rely=0.4, relwidth=1)
340 self.serialBox['values'] = self.port_names
341
342 # Create CSV Folder
343 if not os.path.isdir('csv'):
344 os.makedirs('csv')
345
346# Start GUI
347root = Tk()
348app = App(root)
349root.mainloop()