# Graphical script to talk to a NMEA bluetooth GPS, and display all # sorts of useful information from it. # # Shows where the satellites are in the sky, and what signal strength # they have (two different views) # Converts your position into OSGB 36 values, and then generates OS # easting and northing values + six figure grid ref # Also allows you to log your journeys to a file. In future, the logging # details will be configurable, and you'll be able send this to another # bluetooth device (eg a computer) using socket.bt_obex_send_file (TODO) # Optionally also logs the GSM location to the file used by stumblestore, # which you can later uplaod with stumblestore to http://gsmloc.org/ # # In future, should have a config pannel # In future, the OS co-ords stuff should be made more general, to handle # other countries # In future, some of the messages out to be translated into other languages # # For now, on the main screen, hit * to increase logging frequency, # to # decrease it, 0 to immediately log a point, and 8 to toggle logging # on and off. Use 5 to toggle stumblestore GSM logging on and off # On the Direction Of screen, use 1 and 3 to move between waypoints, 5 # to add a waypoint for the current location, and 8 to delete the # current waypoint ########### added: # On the MAP screen, use arrows to move map, select key to centre map at cursor, # 1 and 3 to move between waypoints, 5 # to add a waypoint for the current location, and 8 to delete the # current waypoint # On the Cipset control screen, use 1 or 3 key to select the type of chipset, # 0 to reboot chipset if supported, 5 to turn WAAS on/off if supported ########### # GPL # Contributions from Cashman Andrus and Christopher Schmit # # Nick Burch - v0.15 (29/07/2006) # + some features added by M. Bouska 4/9/2006 # this are marked with: ########### added: # Core imports - special ones occur later import appuifw import e32 import e32db import math import socket import time import os import sysinfo from location import gsm_location ########### added: from time import gmtime # All of our preferences live in a dictionary called 'pref' pref = {} # Default bluetooth address to connect to # If blank, will prompt you to pick one pref['def_gps_addr']='' # How many GGA sentences between logging # Set to 0 to prevent logging pref['gga_log_interval'] = 5 # Threshhold change in GGA sentence to log again # (lessens redundant entries while stationary) # Values for lat and long are in minutes of arc, as stored in # location['lat_dec'] and location['long_dec']. # eg 0.00005 is ~5.6 meters at the equator) # Value for alt is in meters. pref['gga_log_min_lat'] = 0.0 pref['gga_log_min_long'] = 0.0 pref['gga_log_min_alt'] = 0.0 #pref['gga_log_min_lat'] = 0.0001 #pref['gga_log_min_long'] = 0.0001 #pref['gga_log_min_alt'] = 6.0 # Where we store our data and settings pref['base_dir'] = 'e:\\System\\Apps\\NMEA_Info\\' # File to log GGA sentences into # May optionally contain macros for datetime elements, as used in # time.strftime, eg "file_%y-%m-%d_%H:%M.txt" # Should end in .txt, so the send script will spot them pref['gga_log_file'] = pref['base_dir'] + 'nmea_gga_log.txt' #pref['gga_log_file'] = pref['base_dir'] + 'nmea_gga_log_%y-%m-%d.txt' # File to log debug info into pref['debug_log_file'] = '' #pref['debug_log_file'] = pref['base_dir'] + 'nmea_debug_log_%y-%m-%d.txt' # DB file to hold waypoints for direction-of stuff pref['waypoints_db'] = pref['base_dir'] + 'waypoints.db' # Should we also log GSM+lat+long in the stumblestore log file? # See http://gsmloc.org/ for more details pref['gsmloc_logging'] = 0 # We want icons etc # Set this to 'large' if you want the whole screen used pref['app_screen'] = 'large' # Define title etc pref['app_title'] = "NMEA Info Disp" # Default location for "direction of" pref['direction_of_lat'] = '49.9538' pref['direction_of_long'] = '14.0505' pref['direction_of_name'] = '(default)' ########################################################################### ########### added: #### ## do we have to write some data to a gps global towrite towrite = 0 ####### ### ## text bufer for printig the gps output in Chipset - init page global texbuf texbuf = ['...','...','...','...','...','...','...','...','...','...','...','...','...','...'] global buflen buflen = 9 ### currently used schipset: gpsinit = {} gpsinit['WAAS'] = 0 gpsinit['reboot'] =0 gpsinit['chipset'] = 'Sirf' ############ list of supported chipsets: gpsinit['chiplist']=['Sirf','others'] ############## capabilities of chipsets: chipsetcapability = {} chipsetcapability['WAAS'] = ['Sirf'] chipsetcapability['reboot'] =['Sirf'] ################## variables using in map - view global vwindow vwindow={} vwindow['x'] = 14.0500 # E vwindow['y'] = 49.950 # N vwindow['scale'] = 0.0017 # 0.1' vwindow['type'] = "latlong" # latlong / eastnorthing vwindow['minscale'] = 0.000001 # maximal zoom vwindow['maxscale'] = 0.1 # minimal zoom xres = 176 yres = 208 #S60 resolution ############################################################################# # Ensure our helper libraries are found try: from geo_helper import * except ImportError: appuifw.note(u"geo_helper.py module wasn't found!\nDownload at http://gagravarr.org/code/", "error") print "\n" print "Error: geo_helper.py module wasn't found\n" print "Please download it from http://gagravarr.org/code/ and install, before using program" # Try to exit without a stack trace - doesn't always work! import sys sys.__excepthook__=None sys.excepthook=None sys.exit() ############################################################################# # Set the screen size, and title appuifw.app.screen=pref['app_screen'] appuifw.app.title=unicode(pref['app_title']) ############################################################################# # Ensure our data directory exists if not os.path.exists(pref['base_dir']): os.makedirs(pref['base_dir']) # Load the settings # TODO ############################################################################# waypoints = [] current_waypoint = 0 track = [] tracklen = 0 # Path to DB needs to be in unicode pref['waypoints_db'] = unicode(pref['waypoints_db']) def open_waypoints_db(): """Open the waypoints DB file, creating if needed""" global prefs db = e32db.Dbms() try: db.open(pref['waypoints_db']) except: # Doesn't exist yet db.create(pref['waypoints_db']) db.open(pref['waypoints_db']) db.execute(u"CREATE TABLE waypoints (name VARCHAR, lat FLOAT, long FLOAT, added TIMESTAMP)") return db def add_waypoint(name,lat,long): """Adds a waypoint to the database""" global waypoints global current_waypoint # Add to the db db = open_waypoints_db() ######################## the e32db.format_time() function is formating WRONG on my N70 (gives dd.mm.yy HH.MM instead of HH:MM !!) ############ so I modified this #sql = "INSERT INTO waypoints (name,lat,long,added) VALUES ('%s',%f,%f,#%s#)" % ( name, lat, long, e32db.format_time(time.time()) ) sql = "INSERT INTO waypoints (name,lat,long,added) VALUES ('%s',%f,%f,#%s#)" % ( name, lat, long, time.strftime('%d.%m.%Y %H:%M:%S') ) print sql db.execute( unicode(sql) ) db.close() # We would update the waypoints array, but that seems to cause a # s60 python crash! ##waypoints.append( (unicode(name), lat, long) ) ##current_waypoint = len(waypoints) - 1 current_waypoint = -1 def add_track(lat,long): global track global tracklen """Adds a next part of track to the database""" if lat[-1:] == 'S': lat = '-' + lat; if long[-1:] == 'W': long = '-'+ long; wgslat = float(lat[0:-1]) wgslong = float(long[0:-1]) track.append((wgslong,wgslat)) tracklen += 1 return tracklen def delete_current_waypoint(): """Deletes the current waypoint from the database""" global waypoints global current_waypoint if current_waypoint == 0: return name = waypoints[current_waypoint][0] long = str(waypoints[current_waypoint][2]) lat = str(waypoints[current_waypoint][1]) # Delete from the array for waypoint in waypoints: if waypoint[0] == name: waypoints.remove(waypoint) current_waypoint = 0 # Delete from the db db = open_waypoints_db() sql = "DELETE FROM waypoints WHERE name='%s' AND long=%s AND lat=%s" % ( name,long,lat ) print sql db.execute( unicode(sql) ) db.close() def load_waypoints(): """Loads our direction-of waypoints""" global waypoints global current_waypoint # First up, go with the default waypoints = [] waypoints.append( (pref['direction_of_name'],pref['direction_of_lat'],pref['direction_of_long']) ) # Now load from disk db = open_waypoints_db() dbv = e32db.Db_view() dbv.prepare(db, u"SELECT name, lat, long FROM waypoints ORDER BY name ASC") dbv.first_line() for i in range(dbv.count_line()): dbv.get_line() waypoints.append( (dbv.col(1), dbv.col(2), dbv.col(3)) ) dbv.next_line() db.close() # Load our direction-of waypoints load_waypoints() ############################################################################# # This is set to 0 to request a quit going = 1 # Our current location location = {} location['valid'] = 1 # Default to valid, in case no GGA/GLL sentences # Our current motion motion = {} # What satellites we're seeing satellites = {} # Warnings / errors disp_notices = '' disp_notices_count = 0 # Our last written location (used to detect position changes) last_location = {} # Our logging parameters gga_log_interval = 0 gga_log_count = 0 gga_log_fh = '' debug_log_fh = '' gsm_log_fh = '' ############################################################################# # Generate the checksum for some data # (Checksum is all the data XOR'd, then turned into hex) def generate_checksum(data): """Generate the NMEA checksum for the supplied data""" csum = 0 for c in data: csum = csum ^ ord(c) hex_csum = "%02x" % csum return hex_csum.upper() # Format a NMEA timestamp into something friendly def format_time(time): """Generate a friendly form of an NMEA timestamp""" hh = time[0:2] mm = time[2:4] ss = time[4:] return "%s:%s:%s UTC" % (hh,mm,ss) # Format a NMEA date into something friendly def format_date(date): """Generate a friendly form of an NMEA date""" months = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec') dd = date[0:2] mm = date[2:4] yy = date[4:6] yyyy = int(yy) + 2000 return "%s %s %d" % (dd, months[(int(mm)-1)], yyyy) # NMEA data is HHMM.nnnn where nnnn is decimal part of second def format_latlong(data): """Turn HHMM.nnnn into HH:MM.SS""" # Check to see if it's HMM.nnnn or HHMM.nnnn or HHHMM.nnnn if data[5:6] == '.': # It's HHHMM.nnnn hh_mm = data[0:3] + ":" + data[3:5] dddd = data[6:] elif data[3:4] == '.': # It's HMM.nnnn hh_mm = data[0:1] + ":" + data[1:3] dddd = data[4:] else: # Assume HHMM.nnnn hh_mm = data[0:2] + ":" + data[2:4] dddd = data[5:] # Turn from decimal into seconds, and strip off last 2 digits sec = int( float(dddd) / 100.0 * 60.0 / 100.0 ) return hh_mm + ":" + str(sec) def format_latlong_dec(data): """Turn HHMM.nnnn into HH.ddddd""" # Check to see if it's HMM.nnnn or HHMM.nnnn or HHHMM.nnnn if data[5:6] == '.': hours = data[0:3] mins = float(data[3:]) elif data[3:4] == '.': hours = data[0:1] mins = float(data[1:]) else: hours = data[0:2] mins = float(data[2:]) dec = mins / 60.0 * 100.0 # Cap at 6 digits - currently nn.nnnnnnnn dec = dec * 10000.0 str_dec = "%06d" % dec return hours + "." + str_dec ############################################################################# def readline(sock): """Read one single line from the socket""" line = "" while 1: char = sock.recv(1) if not char: break line += char if char == "\n": break return line ############ ####### ############################################################################### ########### added: def writeline(sock,line): """write one single line to the socket""" #i="" #for i in line: #sock.send(i,1) #return err sock.send(line) ############################################################################# def do_gga_location(data): """Get the location from a GGA sentence""" global location d = data.split(',') location['type'] = 'GGA' location['lat'] = "%s%s" % (format_latlong(d[1]),d[2]) location['long'] = "%s%s" % (format_latlong(d[3]),d[4]) location['lat_dec'] = "%s%s" % (format_latlong_dec(d[1]),d[2]) location['long_dec'] = "%s%s" % (format_latlong_dec(d[3]),d[4]) location['lat_raw'] = "%s%s" % (d[1],d[2]) location['long_raw'] = "%s%s" % (d[3],d[4]) location['alt'] = "%s %s" % (d[8],d[9]) location['time'] = format_time(d[0]) if d[5] == '0': location['valid'] = 0 else: location['valid'] = 1 def do_gll_location(data): """Get the location from a GLL sentence""" global location d = data.split(',') location['type'] = 'GLL' location['lat'] = "%s%s" % (format_latlong(d[0]),d[1]) location['long'] = "%s%s" % (format_latlong(d[2]),d[3]) location['lat_dec'] = "%s%s" % (format_latlong_dec(d[0]),d[1]) location['long_dec'] = "%s%s" % (format_latlong_dec(d[2]),d[3]) location['lat_raw'] = "%s%s" % (d[0],d[1]) location['long_raw'] = "%s%s" % (d[2],d[3]) location['time'] = format_time(d[4]) if d[5] == 'A': location['valid'] = 1 elif d[5] == 'V': location['valid'] = 0 def do_rmc_location(data): """Get the location from a RMC sentence""" global location d = data.split(',') location['type'] = 'RMC' location['lat'] = "%s%s" % (format_latlong(d[2]),d[3]) location['long'] = "%s%s" % (format_latlong(d[4]),d[5]) location['lat_dec'] = "%s%s" % (format_latlong_dec(d[2]),d[3]) location['long_dec'] = "%s%s" % (format_latlong_dec(d[4]),d[5]) location['lat_raw'] = "%s%s" % (d[2],d[3]) location['long_raw'] = "%s%s" % (d[4],d[5]) location['time'] = format_time(d[0]) ############################################################################# def do_gsv_satellite_view(data): """Get the list of satellites we can see from a GSV sentence""" global satellites d = data.split(',') # Are we starting a new set of sentences, or continuing one? full_view_in = d[0] sentence_no = d[1] tot_in_view = d[2] if int(sentence_no) == 1: satellites['building_list'] = [] # Loop over the satellites in the sentence, grabbing their data sats = d[3:] while len(sats) > 0: prn_num = sats[0] elevation = sats[1] azimuth = sats[2] sig_strength = sats[3] satellites[prn_num] = { 'prn':prn_num, 'elevation':elevation, 'azimuth':azimuth, 'sig_strength':sig_strength } satellites['building_list'].append(prn_num) sats = sats[4:] # Have we got all the details from this set? if sentence_no == full_view_in: satellites['in_view'] = satellites['building_list'] satellites['in_view'].sort() satellites['building_list'] = [] # All done def do_gsa_satellites_used(data): """Get the list of satellites we are using to get the fix""" global satellites d = data.split(',') sats = d[2:13] overall_dop = d[14] horiz_dop = d[15] vert_dop = d[16] while (len(sats) > 0) and (not sats[-1]): sats.pop() satellites['in_use'] = sats satellites['in_use'].sort() satellites['overall_dop'] = overall_dop satellites['horiz_dop'] = horiz_dop satellites['vert_dop'] = vert_dop def do_vtg_motion(data): """Get the current motion, from the VTG sentence""" global motion d = data.split(',') motion['speed'] = d[6] + " kmph" motion['true_heading'] = d[0] motion['mag_heading'] = '' if d[2] and int(d[2]) > 0: motion['mag_heading'] = d[2] ############################################################################# def expand_log_file_name(proto): """Expand a filename prototype, which optionally includes date and time macros.""" # eg "%y/%m/%d %H:%M" expanded = time.strftime(proto, time.localtime(time.time())) return expanded def rename_current_gga_log(new_name): """Swap the current position log, for one with the new name""" global pref close_gga_log() pref['gga_log_file'] = new_name init_gga_log() def init_gga_log(): """Initialize the position log, using pref information""" global pref global gga_log_count global gga_log_interval global gga_log_fh gga_log_count = 0 gga_log_interval = pref['gga_log_interval'] if pref['gga_log_file']: # Open the GGA log file, in append mode gga_log_fh = open(expand_log_file_name(pref['gga_log_file']),'a'); else: # Set the file handle to False gga_log_fh = '' def close_gga_log(): """Close the position log file, if it's open""" global gga_log_fh if gga_log_fh: gga_log_fh.flush() gga_log_fh.close() gga_log_fh = '' def init_debug_log(): """Initialise the debug log, using pref information""" global pref global debug_log_fh if pref['debug_log_file']: # Open the debug log file, in append mode debug_log_fh = open(expand_log_file_name(pref['debug_log_file']),'a') debug_log_fh.write("Debug Log Opened at %s\n" % time.strftime('%H:%M:%S, %Y-%m-%d', time.localtime(time.time()))) else: # Set the file handle to False debug_log_fh = '' def close_debug_log(): global debug_log_fh if debug_log_fh: debug_log_fh.write("Debug Log Closed at %s\n" % time.strftime('%H:%M:%S, %Y-%m-%d', time.localtime(time.time()))) debug_log_fh.close() debug_log_fh = '' def init_stumblestore_gsm_log(): """Initialise the stumblestore GSM log file""" global gsm_log_fh gsm_log_fh = open("E:\\gps.log",'a') def close_stumblestore_gsm_log(): global gsm_log_fh if gsm_log_fh: gsm_log_fh.close() gsm_log_fh = '' ############################################################################# def location_changed(location, last_location): """Checks to see if the location has changed (enough) since the last write""" if (not 'lat_dec' in location) or (not 'long_dec' in location): return 1 if (not 'lat_dec' in last_location) or (not 'long_dec' in last_location): return 1 llat = float(location['lat_dec'][:-1]) llong = float(location['long_dec'][:-1]) lalt = float(location['alt'][:-2]) plat = float(last_location['lat_dec'][:-1]) plong = float(last_location['long_dec'][:-1]) palt = float(last_location['alt'][:-2]) if (abs(llat-plat) < pref['gga_log_min_lat']) and (abs(llong-plong) < pref['gga_log_min_long']) and (abs(lalt-palt) < pref['gga_log_min_alt']): return 0 return 1 def gga_log(rawdata): """Periodically log GGA data to a file, optionally only if it has changed""" global pref global gga_log_count global gga_log_interval global gga_log_fh global location global last_location # If we have a fix, and the location has changed enough, and # we've waited long enough, write out the current position if location['valid']: gga_log_count = gga_log_count + 1 if gga_log_count >= gga_log_interval: gga_log_count = 0 if location_changed(location, last_location): if gga_log_fh: gga_log_fh.write(rawdata) if pref['gsmloc_logging']: gsm_stumblestore_log() # Save this location, so we can check changes from it last_location['lat_dec'] = location['lat_dec'] last_location['long_dec'] = location['long_dec'] last_location['alt'] = location['alt'] ###########added: print("Tracks curves elements:%s"%add_track(location['lat_dec'],location['long_dec'])) #add_track(location['lat_dec'],location['long_dec']) def debug_log(rawdata): """Log debug data to a file when requested (if enabled)""" global debug_log_fh if debug_log_fh: debug_log_fh.write(rawdata+"\n") def gsm_stumblestore_log(): """Log the GSM location + GPS location to the stumblestore log file""" global location global gsm_log_fh # Ensure we have our log file open if not gsm_log_fh: init_stumblestore_gsm_log() # Grab the details of what cell we're on cell = gsm_location() # Write this out gsm_log_fh.write("%s,%s,%s,%s,%s,%s,%s,%s\n"%(cell[0],cell[1],cell[2],cell[3],sysinfo.signal(),location['lat_raw'],location['long_raw'],time.time())) # Kick of logging, if required init_gga_log() init_debug_log() ############################################################################# ############ ######## ########### ######## ########### ################################################# ########### added: ######## function for choosing from list def choose(list,WHAT,direction): i=0 prev = list[0] for select in list: ret = select if i == 1: return select if ret == WHAT: i = i+1 if direction == -1: return prev prev = select return ret ########################### encapsulate data for gps: def encaps(sentence): return '$'+sentence+'*'+generate_checksum(sentence)+'\r\n' ######################## prepare data for gps def chipsetinit(): # at this time, only Sirf chipsets are supported, for iTrex should be used something like: PFST,REBOOT .. etc global gpsinit buf = "" if gpsinit['chipset'] in ['Sirf']: ######################## Sirf chipset initiation: if gpsinit['reboot'] == 1: gpsinit['WAAS'] == 0 ####### Sirf warm start buf += encaps('PSRF101,0,0,0,9600,0,1,12,2') ######## Sirf reset gps - cold start! #buf += encaps('PSRF101,0,0,0,9600,0,1,12,4') if gpsinit['WAAS'] == 1 : ####### Sirf WAAS on buf += encaps('PSRF151,01') else: ####### Sirf WAAS off buf += encaps('PSRF151,00') #Sirf -query 1 VTG sentence (use when broadcasting disabled) #buf += encaps('PSRF103,05,01,00,01') #Sirf -disable VTG broadcasting #buf += encaps('PSRF103,05,00,00,01') ###### Sirf enable VTG broadcasting buf += encaps('PSRF103,05,00,01,01') ####### Sirf enable GLL broadcasting buf += encaps('PSRF103,01,00,01,01') return buf ################## ########## ################## ########### ############################################################################ # Lock, so python won't exit during non canvas graphical stuff lock = e32.Ao_lock() def exit_key_pressed(): """Function called when the user requests exit""" global going going = 0 appuifw.app.exit_key_handler = None lock.signal() def callback(event): global gga_log_count global gga_log_interval global current_waypoint global waypoints global current_state global pref # If they're on the main page, handle changing logging frequency if current_state == 'main': if event['type'] == appuifw.EEventKeyDown: # * -> more frequently if event['scancode'] == 42: if gga_log_interval > 0: gga_log_interval -= 1; # # -> less frequently if event['scancode'] == 127: if gga_log_interval > 0: gga_log_interval += 1; # 0 -> log a point right now if event['scancode'] == 48: gga_log_count = gga_log_interval # 8 -> toggle on/off if event['scancode'] == 56: if gga_log_interval > 0: gga_log_interval = 0; else: gga_log_interval = 10; gga_log_count = 0; # 5 -> toggle stumblestore on/off if event['scancode'] == 53: if pref['gsmloc_logging']: pref['gsmloc_logging'] = 0 else: pref['gsmloc_logging'] = 1 if current_state == 'direction_of': if event['type'] == appuifw.EEventKeyUp: # 1 - prev waypoint if event['scancode'] == 49: current_waypoint = current_waypoint - 1 if current_waypoint < 0: current_waypoint = len(waypoints) - 1 # 3 - next waypoint if event['scancode'] == 51: current_waypoint = current_waypoint + 1 if current_waypoint >= len(waypoints): current_waypoint = 0 # 5 - make this a waypoint if event['scancode'] == 53: do_add_as_waypoint() # No redraw just yet return # 8 - remove this waypoint if event['scancode'] == 56: delete_current_waypoint() ##################### ######### ####################### ########### added: if current_state == 'settingGPS': global towrite global gpsinit if event['type'] == appuifw.EEventKeyDown: ####reboot if event['scancode'] == 48: ### key 0 if gpsinit['chipset'] in chipsetcapability['reboot']: towrite = 1 gpsinit['reboot']=1 gpsinit['WAAS']=0 texbuf[2]='Requesting GPS reboot ' if event['scancode'] == 53:#### WAAS ## key 5 if gpsinit['chipset'] in chipsetcapability['WAAS']: towrite = 1 gpsinit['WAAS']=1-gpsinit['WAAS'] texbuf[2]='Requesting WAAS change' if event['scancode'] == 49 :## change chipset type ## key 1 gpsinit['chipset']=choose(gpsinit['chiplist'],gpsinit['chipset'],-1) if event['scancode'] == 51 :## change chipset type ## key 3 gpsinit['chipset']=choose(gpsinit['chiplist'],gpsinit['chipset'],1) ########### added: if current_state == 'map': if event['type'] == appuifw.EEventKeyUp: if event['scancode'] == 14 :## move map left# key left vwindow['x'] += -10*vwindow['scale'] if event['scancode'] == 15 :## move map right ## key right vwindow['x'] += 10*vwindow['scale'] if event['scancode'] == 16 :## move map up# key up vwindow['y'] += 10*vwindow['scale'] if event['scancode'] == 17 :## move map down## key down vwindow['y'] += -10*vwindow['scale'] if event['scancode'] == 42 :## zoom in ## key * if vwindow['scale'] > vwindow['minscale']: vwindow['scale'] = vwindow['scale'] / 2 if event['scancode'] == 127 :## zoom out ## key # if vwindow['scale'] < vwindow['maxscale']: vwindow['scale'] = vwindow['scale'] *2 if event['scancode'] == 167: # centre screen at cursor # key SELECT: vwindow['x'] = float(wgs_long) vwindow['y'] = float(wgs_lat) if event['scancode'] == 53: # save cursors position as a waypoint: do_add_as_waypoint() if event['scancode'] == 49: # key 1 prev. waypoint current_waypoint = current_waypoint - 1 if current_waypoint < 0: current_waypoint = len(waypoints) - 1 if event['scancode'] == 51: # 3 - next waypoint current_waypoint = current_waypoint + 1 if current_waypoint >= len(waypoints): current_waypoint = 0 # 8 - remove this waypoint if event['scancode'] == 56: delete_current_waypoint() ################# # Whatever happens request a re-draw draw_state() def do_nothing(picked): """Does nothing""" def draw_main(): global location global motion global satellites global gps_addr global gga_log_interval global disp_notices global disp_notices_count global connected canvas.clear() yPos = 12 canvas.text( (0,yPos), u'GPS', 0x008000) if connected: canvas.text( (60,yPos), unicode(gps_addr)) else: canvas.text( (30,yPos), u"-waiting-"+unicode(gps_addr), 0xdd0000) yPos += 12 canvas.text( (0,yPos), u'Time:', 0x008000) if not location.has_key('time'): cur_time = u'(unavailable)' else: cur_time = unicode(location['time']) canvas.text( (60,yPos), cur_time) yPos += 12 ########### added: cas=gmtime() canvas.text( (0,yPos),u'sys. time:',0x008000) canvas.text( (60,yPos),u'%(hh)02d:%(mm)02d:%(ss)02d'%{'hh':cas[3],'mm':cas[4],'ss':cas[5]}) ########## yPos += 12 canvas.text( (0,yPos), u'Speed', 0x008000) if motion.has_key('speed'): cur_speed = unicode(motion['speed']) else: cur_speed = u'(unavailable)' canvas.text( (60,yPos), cur_speed) yPos += 12 canvas.text( (0,yPos), u'Heading', 0x008000) if motion.has_key('true_heading'): if motion.has_key('mag_heading') and motion['mag_heading']: mag = 'True: ' + motion['true_heading'] mag = mag + ' Mag: ' + motion['mag_heading'] else: mag = motion['true_heading'] + " deg" mag = unicode(mag) else: mag = u'(unavailable)' canvas.text( (60,yPos), mag) yPos += 12 canvas.text( (0,yPos), u'Location', 0x008000) if location.has_key('alt'): canvas.text( (105,yPos), unicode(location['alt']) ) if (not location.has_key('lat')) or (not location.has_key('long')): cur_loc = u'(unavailable)' else: if location['valid'] == 0: cur_loc = u'(invalid location)' else: cur_loc = unicode(location['lat']) + ' ' + unicode(location['long']) canvas.text( (10,yPos+12), cur_loc) yPos += 24 canvas.text( (0, yPos), u'Satellites in view', 0x008000) if satellites.has_key('in_view'): canvas.text( (105,yPos), unicode( len(satellites['in_view']) )) canvas.text( (10,yPos+12), unicode(' '.join(satellites['in_view'])) ) else: canvas.text( (10,yPos+12), u'(unavailable)') yPos += 24 canvas.text( (0, yPos), u'Satellites used', 0x008000) if satellites.has_key('in_use'): used = len(satellites['in_use']) if satellites.has_key('overall_dop'): used = str(used) + " err " + satellites['overall_dop'] canvas.text( (105,yPos), unicode(used) ) canvas.text( (10,yPos+12), unicode(' '.join(satellites['in_use'])) ) else: canvas.text( (10,yPos+12), u'(unavailable)') yPos += 24 canvas.text( (0, yPos), u'Logging locations', 0x008000) if gga_log_interval > 0: logging = unicode(gga_log_interval) + u' secs' else: logging = u'no' if pref['gsmloc_logging']: logging = logging + u' +GSM' canvas.text( (105,yPos), logging) if not disp_notices == '': yPos += 12 canvas.text( (0,yPos), unicode(disp_notices), 0x000080) disp_notices_count = disp_notices_count + 1 if disp_notices_count > 60: disp_notices = '' disp_notices_count = 0 def draw_sat_list(): global satellites canvas.clear() if not satellites.has_key('in_view'): canvas.text( (0,12), u'No satellites in view', 0x008000) appuifw.app.body=canvas return pos = 0 for sat in satellites['in_view']: pos = pos + 12 # Draw signal strength on back # Strength should be between 0 and 99 str_len = 0 if (not satellites[sat]['sig_strength'] == '') and (int(satellites[sat]['sig_strength']) > 0): str_len = int( 120.0 * float(satellites[sat]['sig_strength']) / 100.0 ) if str_len > 0: canvas.rectangle( [50,pos-10, 50+str_len,pos], outline=0xbb0000, fill=0xbb0000 ) # Draw info on front canvas.text( (0,pos), unicode('Sat ' + sat), 0x008000) canvas.text( (50,pos), unicode('e' + satellites[sat]['elevation'] + ' a' + satellites[sat]['azimuth'] + ' sig ' + satellites[sat]['sig_strength'] ) ) def draw_sat_view(): global satellites canvas.clear() if not satellites.has_key('in_view'): canvas.text( (0,12), u'No satellites in view', 0x008000) return # Draw the outer and inner circle canvas.ellipse([00,00,150,150], outline=0x000000, width=2) canvas.ellipse([45,45,105,105], outline=0x000000, width=1) # Draw on N-S, E-W canvas.line([75,00,75,150], outline=0x000000, width=1) canvas.line([0,75,150,75], outline=0x000000, width=1) canvas.text( (72,12), u'N' ) # Render each of the satelites # Elevation in deg, 0=edge, 90=centre # Azimuth in deg, 0=top, round clockwise for sat in satellites['in_view']: if not satellites[sat]['elevation']: continue if not satellites[sat]['azimuth']: continue # Where to draw the point x_pos = 75 - 2 # Offset so nice and central y_pos = 75 + 6 # Can't write at y=0, so offset everything elev = float(satellites[sat]['elevation']) / 360.0 * 2 * math.pi azim = float(satellites[sat]['azimuth']) / 360.0 * 2 * math.pi # azim gives us round the circle # elev gives us how far in or out # (elev=0 -> edge, elev=90 -> centre) radius = 75.0 * math.cos(elev) y_disp = radius * math.cos(azim) x_disp = radius * math.sin(azim) x_pos = x_pos + x_disp y_pos = y_pos - y_disp # 0 is at the top canvas.text( (x_pos,y_pos), unicode(sat), 0x008000 ) def draw_os_data(): global location # We pick up these values as we go wgs_height = 0 wgs_lat = None wgs_long = None canvas.clear() if (not location.has_key('lat')) or (not location.has_key('long')): canvas.text( (0,12), u'No location data available', 0x008000) return yPos = 12 canvas.text( (0,yPos), u'Location (WGS84)', 0x008000) if location.has_key('alt'): canvas.text( (105,yPos), unicode(location['alt']) ) # Remove ' M' wgs_height = location['alt'] wgs_height = wgs_height[0:-1] if wgs_height[-1:] == '': wgs_height = wgs_height[0:-1] if location['valid'] == 0: canvas.text( (10,yPos+12), u'(invalid location)' ) else: canvas.text( (10,yPos+12), unicode(location['lat']) ) canvas.text( (90,yPos+12), unicode(location['long']) ) yPos += 12 canvas.text( (10,yPos+12), unicode(location['lat_dec']) ) canvas.text( (90,yPos+12), unicode(location['long_dec']) ) # remove N/S E/W wgs_lat = location['lat_dec']; wgs_long = location['long_dec']; if wgs_lat[-1:] == 'S': wgs_lat = '-' + wgs_lat; if wgs_long[-1:] == 'W': wgs_long = '-' + wgs_long; wgs_lat = wgs_lat[0:-1] wgs_long = wgs_long[0:-1] # Convert these values from WGS 84 into OSGB 36 osgb_data = [] if (not wgs_lat == None) and (not wgs_long == None): osgb_data = turn_wgs84_into_osgb36(wgs_lat,wgs_long,wgs_height) # And display yPos += 24 canvas.text( (0,yPos), u'Location (OSGB 36)', 0x008000) if osgb_data == []: canvas.text( (10,yPos+12), u'(invalid location)' ) else: osgb_lat = "%02.06f" % osgb_data[0] osgb_long = "%02.06f" % osgb_data[1] canvas.text( (10,yPos+12), unicode(osgb_lat) ) canvas.text( (90,yPos+12), unicode(osgb_long) ) # And from OSG36 into easting and northing values en = [] if not osgb_data == []: en = turn_osgb36_into_eastingnorthing(osgb_data[0],osgb_data[1]) # And display yPos += 24 canvas.text( (0,yPos), u'OS Easting and Northing', 0x008000) if en == []: canvas.text( (10,yPos+12), u'(invalid location)' ) else: canvas.text( (10,yPos+12), unicode('E ' + str(int(en[0]))) ) canvas.text( (90,yPos+12), unicode('N ' + str(int(en[1]))) ) # Now do 6 figure grid ref yPos += 24 canvas.text( (0,yPos), u'OS 6 Figure Grid Ref', 0x008000) if en == []: canvas.text( (10,yPos+12), u'(invalid location)' ) else: six_fig = turn_easting_northing_into_six_fig(en[0],en[1]) canvas.text( (10,yPos+12), unicode(six_fig) ) def draw_direction_of(): global current_waypoint global new_waypoints global waypoints global location global motion global pref canvas.clear() if (not location.has_key('lat')) or (not location.has_key('long')): canvas.text( (0,12), u'No location data available', 0x008000) return if (not motion.has_key('true_heading')): canvas.text( (0,12), u'No movement data available', 0x008000) return # Do we need to refresh the list? if current_waypoint == -1: load_waypoints() current_waypoint = len(waypoints)-1 # Grab the waypoint of interest waypoint = waypoints[current_waypoint] # Ensure we're dealing with floats direction_of_lat = float(waypoint[1]) direction_of_long = float(waypoint[2]) wgs_lat = location['lat_dec']; wgs_long = location['long_dec']; if wgs_lat[-1:] == 'S': wgs_lat = '-' + wgs_lat; if wgs_long[-1:] == 'W': wgs_long = '-' + wgs_long; wgs_lat = wgs_lat[0:-1] wgs_long = wgs_long[0:-1] # How far is it to where we're going? dist_bearing = calculate_distance_and_bearing(wgs_lat,wgs_long,direction_of_lat,direction_of_long) if dist_bearing[0] > 100000: distance = "%4d km" % (dist_bearing[0]/1000.0) else: if dist_bearing[0] < 2000: distance = "%4d m" % dist_bearing[0] else: distance = "%3.02f km" % (dist_bearing[0]/1000.0) bearing = dist_bearing[1] if bearing < 0: bearing = bearing + 360 bearing = "%03d" % bearing ########### added if: if (motion['true_heading'] == "") or (motion['true_heading'] == None): #there are no data for heading draw_heading = 0 heading = "N/A" else: heading = "%03d" % float(motion['true_heading']) draw_heading = 1 # Display yPos = 12 canvas.text( (0,yPos), u'Location (WGS84)', 0x008000) if location['valid'] == 0: canvas.text( (10,yPos+12), u'(invalid location)' ) else: canvas.text( (10,yPos+12), unicode(location['lat_dec']) ) canvas.text( (90,yPos+12), unicode(location['long_dec']) ) # Where are we going? yPos += 24 canvas.text( (0,yPos), u'Heading to (WGS84)', 0x008000) heading_lat = "%02.06f" % direction_of_lat heading_long = "%02.06f" % direction_of_long canvas.text( (10,yPos+12), unicode(heading_lat) ) canvas.text( (90,yPos+12), unicode(heading_long) ) # Draw our big(ish) circle # radius of 45, centered on 55,95 canvas.ellipse([10,50,100,140], outline=0x000000, width=2) canvas.point([55,95], outline=0x000000, width=1) # And NS-EW lines canvas.line([10,95,100,95], outline=0x000000,width=1) canvas.line([55,50,55,140], outline=0x000000,width=1) # What't this waypoint called? canvas.text( (110,60), unicode(waypoint[0]), 0x000080) # How far, and what dir? canvas.text( (110,72), u'Distance', 0x008000) canvas.text( (110,84), unicode(distance) ) canvas.text( (110,96), u'Cur Dir', 0x008000) canvas.text( (110,108), unicode(heading) ) canvas.text( (110,120), u'Head In', 0x008000) canvas.text( (110,132), unicode(bearing) ) # Draw on the heading line ########### added if: if draw_heading == 1 : heading = float( motion['true_heading'] ) / 360.0 * 2.0 * math.pi heading_t_x = 45.0 * math.sin(heading) + 45 + 10 heading_t_y = -45.0 * math.cos(heading) + 45 + 50 heading_b_x = 45.0 * math.sin(heading + math.pi) + 45 + 10 heading_b_y = -45.0 * math.cos(heading + math.pi) + 45 + 50 canvas.line( (heading_b_x,heading_b_y,heading_t_x,heading_t_y), outline=0x008000, width=2) canvas.text( (heading_t_x-2,heading_t_y+4), u'H', 0x008000 ) # Draw on the aim-for line bearing = dist_bearing[1] / 360.0 * 2.0 * math.pi bearing_t_x = 45.0 * math.sin(bearing) + 45 + 10 bearing_t_y = -45.0 * math.cos(bearing) + 45 + 50 bearing_b_x = 45.0 * math.sin(bearing + math.pi) + 45 + 10 bearing_b_y = -45.0 * math.cos(bearing + math.pi) + 45 + 50 canvas.line( (bearing_b_x,bearing_b_y,bearing_t_x,bearing_t_y), outline=0x800000, width=2) canvas.text( (bearing_t_x-2,bearing_t_y+4), u'B', 0x800000 ) #################### ########## ################## ########### ########### added: def print_cursor(wgs_lat,wgs_long): curpos={} curpos['x1'] = 89 + int( (float(wgs_long) - vwindow['x'])/vwindow['scale'] ) curpos['y1'] = 100 - int( (float(wgs_lat) - vwindow['y'])/vwindow['scale'] ) if (curpos['x1'] < 0) or (curpos['x1'] > xres) or (curpos['y1'] < 0) or (curpos['y1']> yres): cursorvisible = 0 else: cursorvisible = 1 #curPos = cursor.image.get_rect() if (motion['true_heading'] == "") or (motion['true_heading'] == None) : cursorvisible = 0 if cursorvisible == 0 : return curpos['x2'] = int((curpos['x1']+(15*math.sin(2*math.pi*float(motion['true_heading']) / 360)))) curpos['y2'] = int((curpos['y1']-(15*math.cos(2*math.pi*float(motion['true_heading']) / 360)))) cur = canvas.line([curpos['x1'],curpos['y1'],curpos['x2'],curpos['y2']], outline=0x0000, width =1) cur = canvas.ellipse([curpos['x1']-2,curpos['y1']-2,curpos['x1']+2,curpos['y1']+2], outline = 0x000, width =2) def tan_mod(number): nrs = math.sin(number) nrc = math.cos(number) try: tan = nrs / abs(nrc) except: tan = 100 if tan > 100: tan = 100 if tan < -100: tan = -100 return tan def cotan_mod(number): nrs = math.sin(number) nrc = math.cos(number) try: cotan = nrc / abs(nrs) except: cotan = 100 if cotan > 200: cotan = 200 if cotan < -200: cotan = -200 return cotan def print_wpoint(wgs_lat,wgs_long,name,direction_of_lat,direction_of_long,direction_of_name): curpos = {} curpos['x1'] = 89 + int( (float(wgs_long) - vwindow['x'])/vwindow['scale'] ) curpos['y1'] = 100 - int( (float(wgs_lat) - vwindow['y'])/vwindow['scale'] ) if (curpos['x1'] < 0) or (curpos['x1'] > xres) or (curpos['y1'] < 0) or (curpos['y1']> 200): cursorvisible = 0 else: cursorvisible = 1 if cursorvisible == 0: if (name,wgs_lat,wgs_long) != (direction_of_name,direction_of_lat,direction_of_long): return else: #draw arrows to direction of #enumerate bearing, then use sin and cos to draw the lines poiting to the direction_of_point dist_bearing = calculate_distance_and_bearing(vwindow['y'],vwindow['x'],wgs_lat,wgs_long) bearing = dist_bearing[1] xx = tan_mod(math.pi*2*bearing / 360) yy = -cotan_mod(math.pi*2*bearing / 360) #canvas.line( [sign(xx)*86+87 ,int(yy*98) + 96,sign(xx)*86+87 ,int(yy*98) + 100],0xF00000,width = 3) #left and right line #canvas.line( [int(xx*87) + 85,sign(yy)*93+94 ,int(xx*87) + 89,sign(yy)*93+94 ],0xF00000,width = 3) #upper and under line canvas.line( [sign(xx)*86+87 ,int(yy*87) + 96,sign(xx)*86+87 ,int(yy*87) + 100],0xF00000,width = 3) #left and right line canvas.line( [int(xx*98) + 85,sign(yy)*93+94 ,int(xx*98) + 89,sign(yy)*93+94 ],0xF00000,width = 3) #upper and under line return name cur = canvas.ellipse([curpos['x1']-2,curpos['y1']-2,curpos['x1']+2,curpos['y1']+2],outline=0x0A0000,width = 1) ##### draw waypoints name: canvas.text( (curpos['x1']+4,curpos['y1']),u'%s'%name) if (name,wgs_lat,wgs_long) == (direction_of_name,direction_of_lat,direction_of_long): cur = canvas.ellipse([curpos['x1']-5,curpos['y1']-5,curpos['x1']+5,curpos['y1']+5],outline=0xF00000,width = 1) # def print_grid(): #poor optimalised for i in range (xres): coord = (i - 89)*vwindow['scale'] + vwindow['x'] if vwindow['scale'] < 0.0011: # print seconds: if (coord % (1.0/60.0)) < (vwindow['scale']): canvas.line([i,1,i,yres],outline=0x500000,width = 1) if vwindow['scale'] < 0.011: # print 10seconds: if (coord % (1.0/6.0)) < (vwindow['scale']): canvas.line([i,1,i,yres],outline=0x500000,width = 1) if (coord % 1) < (vwindow['scale']): # print minutes: canvas.line([i,1,i,yres],outline=0xA00000,width = 1) for i in range (yres): coord = (100-i)*vwindow['scale'] + vwindow['y'] if vwindow['scale'] < 0.0011: # print seconds: if (coord % (1.0/60.0)) < (vwindow['scale']): canvas.line([1,i,xres,i],outline=0x500000,width = 1) if vwindow['scale'] < 0.011: # print 10seconds: if (coord % (1.0/6.0)) < (vwindow['scale']): canvas.line([1,i,xres,i],outline=0x500000,width = 1) if (coord % 1) < (vwindow['scale']): canvas.line([1,i,xres,i],outline=0xA00000, width =1) def print_gridMOD(): #alternative to print_grid(), but also with large CPU time needs k = ((vwindow['scale']*(-89)+ vwindow['x'])) for i in range (xres): l = (vwindow['scale']*(i-88)+ vwindow['x']) if ((60*l)//1 > (60*k)//1) and (vwindow['scale'] < 0.0011): canvas.line([i,1,i,yres],outline=0xF00000,width = 1) # seconds if ((6*l//1) > (6*k)//1)and (vwindow['scale'] < 0.011): canvas.line([i,1,i,yres],outline=0xA00000,width = 1) # 10seconds if (l//1 > k//1): canvas.line([i,1,i,yres],outline=0x500000,width = 1) # degrees k = l k = ((vwindow['scale']*(-99)+ vwindow['y'])) for i in range (yres): l = (vwindow['scale']*(i-98)+ vwindow['y']) if ((60*l)//1 > (60*k)//1) and (vwindow['scale'] < 0.0011): canvas.line([1,yres-i,xres,yres-i],outline=0xF00000,width = 1) # seconds if ((6*l)//1 > (6*k)//1)and (vwindow['scale'] < 0.011): canvas.line([1,yres-i,xres,yres-i],outline=0xA00000,width = 1) # 10seconds if (l//1 > k//1): canvas.line([1,yres-i,xres,yres-i],outline=0x500000,width = 1) # degrees k = l def print_track(): global tracklen global vwindow curpos = {} if tracklen < 1: return curpos['x2'] = 89 + int( (track[0][0] - vwindow['x'])/vwindow['scale'] ) curpos['y2'] = 100 - int( (track[0][1] - vwindow['y'])/vwindow['scale'] ) for tr in range(tracklen): curpos['x1'] = 89 + int( (track[tr][0] - vwindow['x'])/vwindow['scale'] ) curpos['y1'] = 100 - int( (track[tr][1] - vwindow['y'])/vwindow['scale'] ) if (curpos['x1'] < 0) or (curpos['x1'] > xres) or (curpos['y1'] < 0) or (curpos['y1']> 200): cursorvisible = 0 #print("lat:%s ,long:%s "%(track[tr][0],track[tr][1])) else: cur = canvas.line([curpos['x1'],curpos['y1'],curpos['x2'],curpos['y2']], outline=0x000aaa, width =1) #print("x1:%s,y1:%s,x2:%s,y2:%s"%(curpos['x1'],curpos['y1'],curpos['x2'],curpos['y2'])) curpos['x2']=curpos['x1'] curpos['y2']=curpos['y1'] def draw_map(): global wgs_long global wgs_lat global current_waypoint global new_waypoints global waypoints global location global motion global pref text = str("") text2 = "" global tracklen canvas.clear() if (not location.has_key('lat')) or (not location.has_key('long')): canvas.text( (0,12), u'No location data available', 0x008000) return if (not motion.has_key('true_heading')): canvas.text( (0,12), u'No movement data available', 0x008000) return # to solve: this takes too much CPU, so the program often hooks #print_grid()# drawing the grid takes lot of CPU time print_track() #draw track, also takes a lot of CPU canvas.text( (0,12),u' %s, %s, %sm'%(location['lat'],location['long'],location['alt']) ) # Do we need to refresh the list? if current_waypoint == -1: load_waypoints() current_waypoint = len(waypoints)-1 # Grab the waypoint of interest waypoint = waypoints[current_waypoint] # Ensure we're dealing with floats direction_of_lat = float(waypoint[1]) direction_of_long = float(waypoint[2]) direction_of_name = str(waypoint[0]) # draw all visible waypoints: for wp in range(len(waypoints)): waypoint = waypoints[wp] text = print_wpoint(float(waypoint[1]),float(waypoint[2]),str(waypoint[0]),direction_of_lat,direction_of_long,direction_of_name) if (text != None): text2 = text #the direction_of waypoint is out of the screen, remember its name wgs_lat = location['lat_dec']; wgs_long = location['long_dec']; if wgs_lat[-1:] == 'S': wgs_lat = '-' + wgs_lat; if wgs_long[-1:] == 'W': wgs_long = '-' + wgs_long; wgs_lat = wgs_lat[0:-1] wgs_long = wgs_long[0:-1] curpos = {} print_cursor(wgs_lat,wgs_long) #print our position # draw the distance to direction_of waypoint information : # How far is it to where we're going? dist_bearing = calculate_distance_and_bearing(wgs_lat,wgs_long,direction_of_lat,direction_of_long) if dist_bearing[0] > 100000: distance = "%4d km" % (dist_bearing[0]/1000.0) else: if dist_bearing[0] < 2000: distance = "%4d m" % dist_bearing[0] else: distance = "%3.02f km" % (dist_bearing[0]/1000.0) text2 += " dist: %s,%s"%(distance,motion['speed']) canvas.text( (0,186),unicode(text2)) def draw_setGPS(): canvas.clear() canvas.text( (0,156),u'PRESS 1/3 to change chipset') canvas.text( (0,24),u'Current chipset:\" %s\"'%gpsinit['chipset'],0xF00000) if gpsinit['chipset'] in chipsetcapability['reboot']: canvas.text( (10,180),u'PRESS 0 for Reboot',0xF00000) if gpsinit['WAAS'] == 1 : waas = 'off' else: waas ='on' if gpsinit['chipset'] in chipsetcapability['WAAS']: canvas.text( (10,168),u'PRESS 5 for turn WAAS %s'%waas) if towrite == 1: yPos = 12 canvas.text( (0,yPos), u'initiatig %s chipset'%gpsinit['chipset'], 0x0A0000) else: yPos = 12 canvas.text( (0,yPos), u'idle', 0x008000) if (texbuf[1] == data): # no new incoming data, dont write to buffer return texbuf[0]=data for i in range (buflen+1): txt = unicode(texbuf[buflen-i],errors='ignore') canvas.text( (0,i*12+36), txt, 0x00A000) texbuf[buflen+1-i]=texbuf[buflen-i] ################## ############## #################### ############# # Handle config entry selections config_lb = "" def config_menu(): # Do nothing for now global config_lb global canvas appuifw.body = canvas # Select the right draw state current_state = 'main' def draw_state(): """Draw the currently selected screen""" global current_state if current_state == 'sat_list': draw_sat_list() elif current_state == 'sat_view': draw_sat_view() elif current_state == 'os_data': draw_os_data() elif current_state == 'direction_of': draw_direction_of() ########### added: elif current_state == 'settingGPS': draw_setGPS() ########### added: elif current_state == 'map': draw_map() else: draw_main() # Menu selectors def pick_main(): global current_state current_state = 'main' draw_state() ########### added: def pick_map(): global current_state current_state = 'map' draw_state() def pick_sat_list(): global current_state current_state = 'sat_list' draw_state() def pick_sat_view(): global current_state current_state = 'sat_view' draw_state() def pick_os_data(): global current_state current_state = 'os_data' draw_state() def pick_direction_of(): global current_state current_state = 'direction_of' draw_state() def pick_config(): """TODO: Make me work!""" global config_lb config_entries = [ u"GPS", u"Default GPS", u"Logging Interval", u"Default Logging" ] #config_lb = appuifw.Listbox(config_entries,config_menu) #appuifw.body = config_lb appuifw.note(u'Configuration menu not yet supported!\nEdit script header to configure',"info") def pick_upload(): """TODO: Implement me!""" appuifw.note(u'Please use upload_track.py\nSee http://gagravarr.org/code/', "info") def pick_new_file(): do_pick_new_file(u"_nmea.txt") def do_pick_new_file(def_name): global pref # Get new filename new_name = appuifw.query(u"Name for new file?", "text", def_name) if len(new_name) > 0: # Check it doesn't exist new_file_name = pref['base_dir'] + new_name if os.path.exists(new_file_name): appuifw.note(u"That file already exists", "error") pick_new_file(new_name) # Rename rename_current_gga_log(new_file_name) appuifw.note(u"Now logging to new file") ############### added: def sign(number): if number < 0 : return -1 return 1 def check_minutes(value, query): if (value % 1 != 0): return value str2 = "" if value == 0: str2 = " - for S/W" valuemm = appuifw.query(u'%s - minutes? %s'%(query,str2), 'text',unicode("0.0")) try: valuemm = float(valuemm) value += sign(value)*valuemm / 60 except: appuifw.note(u'Wrong value!%s'%valuemm,'info') return value if (valuemm % 1 == 0): valuess = appuifw.query(u'%s - seconds?'%query, 'text',unicode("0.0")) try: valuess = float(valuess) value += sign(value)*valuess / 360 except: appuifw.note(u'Wrong value!%s'%valuess,'info') return value def do_add_as_waypoint(): """Prompt for a name, then add a waypoint for the current location""" global location name = appuifw.query(u'Waypoint name?', 'text',unicode("Waypoint %s"%len(waypoints))) ########### modified if statement: if (name == None) or (name == ""): # appuifw.note(u'Wrong name!','info') else : ########## ########### added query for imput values #lat = location['lat_dec'] lat = appuifw.query(u'Latitude? (- for S)', 'text',unicode(location['lat_dec'])) #long = location['long_dec'] if lat[-1:] == 'S': lat = '-' + lat[0:-1]; if lat[-1:] == 'N': lat = lat[0:-1]; try: lat = float(lat) except: appuifw.note(u'Wrong value!%s'%lat,'info') return lat = check_minutes(lat, 'Latitude') long = appuifw.query(u'Longitude? (- for W)', 'text',unicode(location['long_dec'])) if long[-1:] == 'W': long = '-' + long[0:-1]; if long[-1:] == 'E': long = long[0:-1]; try: long = float(long) except: appuifw.note(u'Wrong value!%s'%long,'info') return long = check_minutes(long, 'Longitude') if (lat < - 90) or (lat > 90): appuifw.note(u'Wrong value! %s'%lat,'info') return if (long < - 180) or (lat > 180): appuifw.note(u'Wrong value!%s'%long,'info') return add_waypoint(name, lat, long) appuifw.note(u'Waypoint Added','info') ################ ######### ############### ########### added: def pick_GPS_init(): global current_state current_state = 'settingGPS' draw_state() ############################################################################# # Decide where to connect to if not pref['def_gps_addr'] == '': gps_addr = pref['def_gps_addr'] target=(gps_addr,1) # Alert them to the GPS we're going to connect to automatically appuifw.note(u"Will connect to GPS %s" % gps_addr, 'info') else: # Prompt them to select a bluetooth GPS gps_addr,services=socket.bt_discover() target=(gps_addr,services.values()[0]) # Not yet connected connected = 0 ############################################################################# # Enable these displays, no all prompts are over canvas=appuifw.Canvas(event_callback=callback, redraw_callback=lambda rect:draw_state()) appuifw.app.body=canvas # TODO: Make canvas and Listbox co-exist without crashing python appuifw.app.menu=[ (u'Main Screen',pick_main),(u'MAP',pick_map), (u'Satellite List',pick_sat_list), (u'Satellite View',pick_sat_view), (u'OS Data',pick_os_data), (u'Direction Of',pick_direction_of), (u'Upload',pick_upload), (u'Configuration',pick_config), (u'New Log File', pick_new_file), (u'Chipset control',pick_GPS_init)] ############################################################################# # Start the lock, so python won't exit during non canvas graphical stuff lock = e32.Ao_lock() # Loop while active appuifw.app.exit_key_handler = exit_key_pressed while going == 1: # Connect to the GPS, if we're not already connected if not connected: try: # Connect to the bluetooth GPS using the serial service sock = socket.socket(socket.AF_BT, socket.SOCK_STREAM) sock.connect(target) connected = 1 debug_log("CONNECTED to GPS: target=%s at %s" % (str(target), time.strftime('%H:%M:%S', time.localtime(time.time())))) disp_notices = "Connected to GPS." appuifw.note(u"Connected to the GPS") except socket.error, inst: connected = 0 disp_notices = "Connect to GPS failed. Retrying..." #appuifw.note(u"Could not connected to the GPS. Retrying in 5 seconds...") #time.sleep(5) continue ########### added: # If we are connected to the GPS, lets write when we have to if connected: if towrite == 1: try: err = writeline(sock,chipsetinit()) #sock.send(chipsetinit()) texbuf[1]='Data to GPS writed sucessfuly' except socket.error, inst: texbuf[1]='Writing to GPS failed' continue towrite = 0 gpsinit['reboot']=0 #################### #If we are connected to the GPS,read a line try: rawdata = readline(sock) except socket.error, inst: # GPS has disconnected, bummer connected = 0 debug_log("DISCONNECTED from GPS: socket.error %s at %s" % (str(inst), time.strftime('%H:%M:%S, %Y-%m-%d', time.localtime(time.time())))) location = {} location['valid'] = 1 appuifw.note(u"Disconnected from the GPS. Retrying...") continue # Try to process the data from the GPS # If it's gibberish, skip that line and move on # (Not all bluetooth GPSs are created equal....) try: data = rawdata.strip() # Discard fragmentary sentences - start with the last '$' startsign = rawdata.rfind('$') global data data = data[startsign:] ########### added: # Ensure it starts with $GP or $PS (other info) if not (data[0:3] in ('$GP','$PS')): continue # If it has a checksum, ensure that's correct # (Checksum follows *, and is XOR of everything from # the $ to the *, exclusive) if data[-3] == '*': exp_checksum = generate_checksum(data[1:-3]) if not exp_checksum == data[-2:]: disp_notices = "Invalid checksum %s, expecting %s" % (data[-2:], exp_checksum) continue # Strip the checksum data = data[:-3] # Grab the parts of the sentence talker = data[1:3] sentence_id = data[3:6] sentence_data = data[7:] # Do we need to re-draw the screen? redraw = 0 # The NMEA location sentences we're interested in are: # GGA - Global Positioning System Fix Data # GLL - Geographic Position # RMC - GPS Transit Data if sentence_id == 'GGA': do_gga_location(sentence_data) redraw = 1 # Log GGA packets periodically gga_log(rawdata) if sentence_id == 'GLL': do_gll_location(sentence_data) redraw = 1 if sentence_id == 'RMC': do_rmc_location(sentence_data) redraw = 1 # The NMEA satellite sentences we're interested in are: # GSV - Satellites in view # GSA - Satellites used for positioning if sentence_id == 'GSV': do_gsv_satellite_view(sentence_data) redraw = 1 if sentence_id == 'GSA': do_gsa_satellites_used(sentence_data) redraw = 1 # The NMEA motion sentences we're interested in are: # VTG - Track made good # (RMC - GPS Transit - only in knots) if sentence_id == 'VTG': do_vtg_motion(sentence_data) redraw = 1 ########### added: if sentence_id == 'RFT': redraw =1; #incoming other info # Catch exceptions cased by the GPS sending us crud except (RuntimeError, TypeError, NameError, ValueError, ArithmeticError, LookupError, AttributeError), inst: print "Exception: %s" % str(inst) debug_log("EXCEPTION: %s" % str(inst)) # Update the state display if redraw == 1: draw_state() else: # All done sock.close() close_gga_log() close_debug_log() close_stumblestore_gsm_log() print "All done" #appuifw.app.set_exit()