WIMXUWI/GPS_Script: gpsData.py

File gpsData.py, 9.9 KB (added by dmeyer@cs.wisc.edu, 10 years ago)
Line 
1#----------------------------------------------------------------------
2# Includes
3#----------------------------------------------------------------------
4
5import gps, os, time, shlex, sys, subprocess, re, math
6
7from datetime import datetime
8from dateutil import zoneinfo
9
10#----------------------------------------------------------------------
11# Global Variables / Constants
12#----------------------------------------------------------------------
13
14# Global debug to output console
15DEBUG = True
16
17# Global to write the date and column headers
18WRITE_FILE_HEADER = True
19
20# Automatically connect even when disconnected
21AUTO_CONNECT = True
22
23# Global for which data set to get
24RUN_RSSI = True
25RUN_IPERF = False
26
27# Pause through loop
28PRESS_ANY_KEY = False
29
30# Directory constants - The name of the file is the date and time
31RSSI_DIRECTORY = "./rssi/"
32MBPS_DIRECTORY = "./mbps/"
33CREATE_DIRS_IF_NOT_EXIST = False
34
35# wimaxcu constants
36SCAN_RSSI_STRING = "RSSI        : "
37STATUS_LINK_RSSI_STRING = "RSSI      : "
38
39# Iperf server
40IPERF_SERVER = "iperf.wiscnet.net"
41
42#----------------------------------------------------------------------
43# Function:         iperf_from_server()
44# Parameters:       none.
45# Returns:          Overall value (mbps) from the command or -1
46# Description:      Runs iperf tcp test with the server address in the global variable.
47#  With the current command the output interval is set to every 2 seconds.  The first
48#  "0.0-" that is output from the iperf command is going to be 0.0-2.0 and the overall
49#  will be output by 0.0-10.x.  An example output of the average is below:
50#  [1860]  0.0-10.1 sec  1.43 MBytes  1.19 Mbits/sec
51#  So after we find the second "0.0-" we look for "Mbits/sec" and work backwards to
52#  get the overall throughput
53#----------------------------------------------------------------------
54def iperf_from_server():
55
56        # Local Variables
57        isSecond = False
58        mbps = -1
59
60        # Try running an iperf test and grab the overall Mbits/sec
61        p = subprocess.Popen(["iperf", "-c", IPERF_SERVER, "-i2"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
62
63        try:
64                for line in p.stdout.readlines():
65
66                        # Command outputs 0.0- twice, 2nd one contains the overall average
67                        if re.search("0.0-",line) and not isSecond:
68                                isSecond = True
69                        elif re.search("0.0-",line) and isSecond:
70
71                                # Found the second one, get the Mbits/sec and work backwards for the value
72                                idx = line.index("Mbits/sec")
73                                mbps = line[idx-5:idx-1]
74        except:
75                print 'Waiting for subprocess to end before exiting...'
76                p.communicate()
77                sys.exit()
78        return mbps
79
80#----------------------------------------------------------------------
81# Function:         rssi_wimaxcu_connected()
82# Parameters:       none.
83# Returns:          Overall rssi value from the "wimaxcu status link" command or -1
84# Description:      Runs the "wimaxcu status link" command and searches for the
85#  rssi output value.
86#----------------------------------------------------------------------
87def rssi_wimaxcu_connected():
88
89        # Local Variables
90        # Default return value if failed
91        rssi = -1
92
93        # Run wimaxcu status link
94        p = subprocess.Popen(["wimaxcu", "status", "link"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
95
96        for line in p.stdout.readlines():
97
98                # Look for the RSSI line
99                if re.search(STATUS_LINK_RSSI_STRING,line):
100
101                        # Found the rssi line, now have to find the index of the value
102                        idx = line.index(STATUS_LINK_RSSI_STRING) + len(STATUS_LINK_RSSI_STRING)
103
104                        # Only get the number, disregard the dB on the end of the output
105                        rssi = line[idx:idx+3]
106        return rssi
107
108#----------------------------------------------------------------------
109# Function:         get_rssi_from_scan(x)
110# Parameters:       x - String to search for the RSSI value
111# Returns:          RSSI value or -1
112# Description:      Searches x, a single line, for the output of the RSSI value.  The format it
113#  searches for is the output of the "wimaxcu scan" command.
114#----------------------------------------------------------------------
115def get_rssi_from_scan(x):
116
117        # Local Variables
118        rssi = -1
119
120        if re.search(SCAN_RSSI_STRING,x):
121                idx = x.index(SCAN_RSSI_STRING) + len(SCAN_RSSI_STRING)
122                rssi = x[idx:idx+3]
123        return rssi;
124
125#----------------------------------------------------------------------
126# Function:         wimaxcu_scan_geni()
127# Parameters:       None.
128# Returns:          RSSI value of the GENI network or -1
129# Description:      Runs the wimaxcu_scan command and searches the output for
130#  the GENI network.  If the GENI network is found, the RSSI value is returned.
131#  This is useful when multiple networks are listed under the scan.
132#----------------------------------------------------------------------
133def wimaxcu_scan_geni():
134
135        # Local Variables
136        rssi = -1
137        is_geni = False;
138        nsp = "";
139        ID = "";
140        signal = "";
141        rssi = "";
142        cinr = "";
143        NetworkType = "";
144        Activated = "";
145
146        # Run wimaxcu scan
147        p = subprocess.Popen(["wimaxcu", "scan"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
148
149        try:
150                while not is_geni:
151                        line = p.stdout.readline()
152                        if re.search("Network found.", line):
153                                nsp = p.stdout.readline()
154                                ID = p.stdout.readline()
155                                signal = p.stdout.readline()
156                                rssi = p.stdout.readline()
157                                cinr = p.stdout.readline()
158                                NetworkType = p.stdout.readline()
159                                Activated = p.stdout.readline()
160                                print '\tNetwork found:  ', nsp
161                        if re.search("NSP : GENI 4G", nsp):
162                                is_geni = True
163                        if not line:
164                                return -1;
165        except:
166                print 'Waiting for subprocess to end before exiting...'
167                p.communicate()
168                sys.exit()
169
170        p.communicate()
171        return get_rssi_from_scan(rssi)
172
173#----------------------------------------------------------------------
174# Function:         is_connected()
175# Parameters:       None.
176# Returns:          True or False if is connected to GENI network
177# Description:      Checks to see if rssi returned from the connected
178#  function returns -1 -> which means it is not connected
179#----------------------------------------------------------------------
180def is_connected():
181        return (rssi_wimaxcu_connected() != -1)
182
183#----------------------------------------------------------------------
184# Function:         wimaxcu_connect()
185# Parameters:       None.
186# Returns:          True or False if is connected to GENI network       
187# Description:      Checks to see if rssi returned from the connected
188#  function returns -1 -> which means it is not connected
189#----------------------------------------------------------------------
190def wimaxcu_connect():
191
192        # Local Variables
193        geni_network_found = False
194
195        while not geni_network_found:
196                print 'Scanning for GENI network...'
197                if wimaxcu_scan_geni() != -1:
198                        geni_network_found = True
199
200        # Run wimaxcu connect
201        print 'Connecting to GENI network...'
202        p = subprocess.Popen(["wimaxcu", "connect", "network", "51"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
203        output = p.communicate()
204        print output[0]
205        print 'GENI network connected'
206
207#----------------------------------------------------------------------
208# Function:         is_dir()
209# Parameters:       x - Path to check if it is a directory.
210# Returns:          None.
211# Description:      Checks to see if the path is a directory and prompts
212#  the user to create the directory if it is not already created.
213#----------------------------------------------------------------------
214def is_dir(x):
215        if not os.path.isdir(x):
216                print x + ' does not exist.'
217                if CREATE_DIRS_IF_NOT_EXIST:
218                        print 'Creating ' + x + 'directory.'
219                        os.makedirs(x)
220                        if os.path.isdir(x):
221                                return True
222                        else:
223                                return False
224        else:
225                return True;
226        return False
227
228#---------------------------------
229# Main Program Entrance
230#---------------------------------
231
232# Get the date and time
233now = datetime.now()
234
235# Initialize main program variables
236rssi_filename = RSSI_DIRECTORY + "{0}.txt".format(now.strftime("%Y-%m-%d_%H:%M"))
237mbps_filename = MBPS_DIRECTORY + "{0}.txt".format(now.strftime("%Y-%m-%d_%H:%M"))
238iperf_header_written = False
239rssi_header_written = False
240
241# Verify the RSSI and MBPS directory exist
242if not is_dir(RSSI_DIRECTORY):
243        sys.exit("Rssi directory does not exist and could not be created.")
244if not is_dir(MBPS_DIRECTORY):
245        sys.exit("Mbps directory does not exist and could not be created.")
246
247while 1:
248        if AUTO_CONNECT:
249                while not is_connected():
250                        wimaxcu_connect()
251        else:
252                if not is_connected():
253                        sys.exit('Please connect to the GENI network or enable AUTO_CONNECT.  Exiting...')
254
255        # Setup communication to GPS daemon
256        lat = 0
257        lon = 0
258        session = gps.gps(mode=gps.WATCH_NEWSTYLE)
259        session.poll()
260        session.stream()
261
262        # Wait until we get location information, takes a little bit of time
263        print 'Getting gps signal...'
264        while session.fix.latitude == lat:
265                session.poll(),time.sleep(1)
266        while session.fix.longitude == lon:
267                session.poll(),time.sleep(1)
268
269        lat = session.fix.latitude
270        lon = session.fix.longitude
271
272        # Check for valid signal, had nan once
273        if math.isnan(lat) or math.isnan(lon):
274                print 'Error getting GPS signal.'
275                sys.exit(lat)
276
277        session.poll()
278        lat = session.fix.latitude
279        lon = session.fix.longitude
280
281        if RUN_RSSI:
282                rssi = rssi_wimaxcu_connected()
283                # Write lat,long,dbm to a file
284                with open(rssi_filename, mode='a') as f:
285                        if WRITE_FILE_HEADER:
286                                if not rssi_header_written:
287                                        f.write("latitude,longitude,RSSI\n")
288                                        rssi_header_written = True
289                        f.write('{0},{1},{2}\n'.format(lat,lon,rssi))
290
291        session.poll()
292        lat = session.fix.latitude
293        lon = session.fix.longitude
294
295        if RUN_IPERF:
296                mbps = iperf_from_server()
297                # Write lat,long,dbm to a file
298                with open(mbps_filename, mode='a') as f:
299                        if WRITE_FILE_HEADER:
300                                if not iperf_header_written:
301                                        f.write("latitude,longitude,Mbps\n")
302                                        iperf_header_written = True
303                        f.write('{0},{1},{2}\n'.format(lat,lon,mbps))
304
305        # Print output to the console
306        if DEBUG:
307                print '------------------------------------'
308                print now.strftime("%Y-%m-%d %H:%M")
309                print 'latitude   ' , lat
310                print 'longitude  ' , lon
311                if RUN_RSSI:
312                        print 'rssi       ' , rssi
313                if RUN_IPERF:
314                        print 'mbps       ' , mbps
315                print '------------------------------------\n\n'
316
317        if PRESS_ANY_KEY:
318                raw_input('Hit enter for next location')
319
320        # Close the GPS session
321        session.close()
322