def _maketeams(team_numbers): f = open(ABS_DATA_DIR) teams = [Team(t, partner=i < 3) for i, t in enumerate(team_numbers)] for line in f: splitline = line.split(',') t = splitline[TEAM] if t in team_numbers: try: teams[team_numbers.index(t)].addline(splitline) except IndexError as e: printing.printf('Incomplete line in data: ', style=printing.ERROR, log=True, logtag='Team.addline.error') printing.printf(line, style=printing.YELLOW, log=True, logtag='Team.addline.error') log('Team.addline.error', str(e)) except Exception as e: printing.printf('Unknown error in strategy request: ', style=printing.ERROR, log=True, logtag='Team.addline.error') printing.printf(str(e), style=printing.ERROR, log=True, logtag='Team.addline.error') printing.printf('On line: ' + line, style=printing.YELLOW, log=True, logtag='Team.addline.error') return teams
def main(): log('server.main', '+' * 20) log('server.main', 'Server started') print_header() datactl.makefile() printing.printf('Waiting for connections', style=printing.STATUS, log=True, logtag='server.main') Thread(target=handleinput).start() socketctl.init() Thread(target=socketctl.connect).start() while True: try: datactl.update() except KeyboardInterrupt: # Make sure everything made it into the data file datactl.update() socketctl.close() log('server.main', 'Server stopped') log('server.main', '-' * 20) # Quit everything (closes all the many threads) osexit(1)
def close(): for sock in clients: sock[0].close() printing.printf('Closed connection with', MAC_DICT.get(sock[1], sock[1]), style=printing.STATUS) clients.clear() server_sock.close() printing.printf('Closed server', style=printing.STATUS)
def connect(): # Wait for connection client_sock, client_info = server_sock.accept() # Connect to device printing.printf('Accepted connection from', MAC_DICT.get(client_info[0], client_info[0]), style=printing.CONNECTED) clients.append((client_sock, client_info[0])) # Start reading it Thread(target=lambda: read(client_sock, client_info[0])).start() # Stay open for connections connect()
def _run(command): try: process = sub.Popen(command, shell=True, stdout=sub.PIPE, stderr=sub.PIPE) return process.communicate() except Exception as e: printing.printf('Unknown exception on system._run(' + command + '):', end=' ', style=printing.ERROR, log=True, logtag='system._run.error') printing.printf(e, style=printing.ERROR)
def _read(sock, info): try: # Receive data data = sock.recv(SIZE) str_data = data.decode() if str_data.strip(): log('socketctl._read.raw', str_data) # Submit the data to be parsed and added to the file addtoqueue(str_data, MAC_DICT.get(info, info)) # Wait for the next match _read(sock, info) except (ConnectionResetError, TimeoutError): printing.printf('Disconnected from', MAC_DICT.get(info, info), style=printing.DISCONNECTED, log=True, logtag='socketctl._read') sock.close() clients.remove((sock, info)) except OSError: printing.printf('Disconnected from', MAC_DICT.get(info, info), '(OSError function not implemented)', style=printing.DISCONNECTED, log=True, logtag='socketctl._read') sock.close() clients.remove((sock, info)) except Exception as e: printing.printf('Unknown error from', MAC_DICT.get(info, info), end=' ', style=printing.DISCONNECTED, log=True, logtag='socketctl._read.error') print(e) try: printing.printf(str(e), style=printing.ERROR, log=True, logtag='socketctl._read.error') except TypeError: printing.printf('Can\'t log the error', log=True, logtag='socketctl._read.error') sock.close() clients.remove((sock, info))
def parsedata(data, info): t = 'Data' for line in data.split('\n'): line = line.strip() if line[:len(EDIT_TRIGGER)] == EDIT_TRIGGER: removefromdatafile(line[len(EDIT_TRIGGER):]) t = 'Edit' elif line: addtodatafile(line) match = line.split(',') printing.printf(t + ' from ' + match[NAME] + ' on ' + info + ' for team ' + match[TEAM] + ' in match ' + match[MATCH], style=printing.NEW_DATA) t = 'Data'
def _summarize(line, info, action='Data'): try: match = line.split(',') printing.printf( action + ' from ' + match[NAME] + ' on ' + info + ' for team ' + match[TEAM] + ' in match ' + match[MATCH], style=printing.NEW_DATA if action == 'Data' else printing.EDIT, log=True, logtag='datactl._summarize') except IndexError: printing.printf('Incomplete line:', line, style=printing.ERROR, log=True, logtag='datactl._summarize.error')
def gethostMAC(): out = '' try: out = _run('hcitool dev') return out[0].decode('utf8').split('\n')[1].split()[1] except IndexError: if out[0]: printing.printf('No bluetooth adapter available', style=printing.ERROR, log=True, logtag='system.gethostMAC.error') else: printing.printf( 'hcitool not found, please install it or edit system.py to use something else', style=printing.ERROR, log=True, logtag='system.gethostMAC.error')
def handleinput(): i = input() if i in ('q', 'quit'): printing.printf('Are you sure you want to quit? (y/n)', style=printing.QUIT, end=' ') q = input() if q == 'y': interrupt_main() elif i in ('d', 'data', 'drive', 'flash drive', 'u', 'update', 'dump', 'data dump'): datactl.driveupdaterequest() elif i in ('s', 'strat', 'match strat', 'strategy', 'match strategy'): # noinspection PyUnusedLocal teams = [input("Our alliance: ") for i in range(3) ] + [input("Other alliance: ") for i in range(3)] printing.printf(datactl.getdata(teams), style=printing.DATA_OUTPUT) Thread(target=handleinput).start()
def main(): print_header() datactl.makefile() printing.printf('Waiting for connections', style=printing.STATUS) Thread(target=handleinput).start() socketctl.init() Thread(target=socketctl.connect).start() while True: try: datactl.update() except KeyboardInterrupt: datactl.update() socketctl.close() osexit(1)
def handleinput(): i = input() ii = i.split() if i in ('q', 'quit'): printing.printf('Are you sure you want to quit? (y/n)', style=printing.QUIT, end=' ') q = input() if q == 'y': interrupt_main() elif i in ('d', 'data', 'drive', 'flash drive', 'u', 'update', 'dump', 'data dump'): datactl.driveupdaterequest() elif i in ('s', 'strat', 'match strat', 'strategy', 'match strategy'): # noinspection PyUnusedLocal teams = [input("Our alliance: ") for i in range(3) ] + [input("Other alliance: ") for i in range(3)] printing.printf(summarize.strategy(teams), style=printing.DATA_OUTPUT) elif i in ('missing', 'm', 'count', 'msng'): datactl.findmissing() elif len(ii): if ii[0] in ('sum', 'summary', 'detail', 'info', 'detailed', 'full', 'ds', 'dcomp', 'dc'): [printing.printf(q) for q in summarize.detailed_summary(ii[1:])] elif ii[0] in ('qsum', 'quick', 'brief', 'qsummary', 'qinfo', 'qk', 'qs', 'comp', 'c'): [printing.printf(q) for q in summarize.quick_summary(ii[1:])] Thread(target=handleinput).start()
def read(sock, info): try: # Receive data data = sock.recv(SIZE) str_data = data.decode() addtoqueue(str_data, MAC_DICT.get(info, info)) # Wait for the next match read(sock, info) except ConnectionResetError: printing.printf('Disconnected from', MAC_DICT.get(info, info), style=printing.DISCONNECTED) sock.close() clients.remove((sock, info)) except TimeoutError: printing.printf('Timeout on ' + MAC_DICT.get(info, info) + ', restarting sock.recv (this is probably fine, ' 'though it shouldn\'t be happening)') read(sock, info)
def copy(fin, fout): printing.printf('Copying ' + fin + ' to ' + fout + ' ...', end=' ', style=printing.FLASH_DRIVE) p = _run('sudo cp ' + fin + ' ' + fout) if p[1]: printing.printf('Error copying: ' + p[1].decode('utf-8'), style=printing.ERROR) else: printing.printf('Copying successful' + stdoutmessage(p[0]), style=printing.FLASH_DRIVE)
def unmount(): printing.printf('Unmounting drive from ' + MEDIA_DIR + ' ...', end=' ', style=printing.FLASH_DRIVE) p = _run('sudo umount ' + MEDIA_DIR) if p[1]: printing.printf('Error unmounting: ' + p[1].decode('utf-8'), style=printing.ERROR) else: printing.printf('Unmounting successful, remove device' + stdoutmessage(p[0]), style=(printing.GREEN, printing.HIGHLIGHT))
def copy(fin, fout): printing.printf('Copying ' + fin + ' to ' + fout + ' ...', end=' ', style=printing.FLASH_DRIVE, log=True, logtag='system.copy') p = _run('sudo cp ' + fin + ' ' + fout) if p[1]: printing.printf('Error copying: ' + p[1].decode('utf-8'), style=printing.ERROR, log=True, logtag='system.copy.error') else: printing.printf('Copying successful' + _stdoutmessage(p[0]), style=printing.FLASH_DRIVE, log=True, logtag='system.copy')
def mount(): devs = checkdev() if not devs: return False dev = devs[0] printing.printf('Found drive at ' + dev + ', attempting to mount to ' + MEDIA_DIR + ' ...', end=' ', style=printing.FLASH_DRIVE) p = _run('sudo mount ' + dev + ' ' + MEDIA_DIR) if p[1]: printing.printf('Error mounting: ' + p[1].decode('utf-8'), style=printing.ERROR) return False else: printing.printf('Mounting successful' + stdoutmessage(p[0]), style=printing.FLASH_DRIVE) return True
def unmount(): printing.printf('Unmounting drive from ' + MEDIA_DIR + ' ...', end=' ', style=printing.FLASH_DRIVE, log=True, logtag='system.unmount') p = _run('sudo umount ' + MEDIA_DIR) if p[1]: printing.printf('Error unmounting: ' + p[1].decode('utf-8'), style=printing.ERROR, log=True, logtag='system.unmount.error') else: printing.printf('Unmounting successful, remove device' + _stdoutmessage(p[0]), style=printing.FLASH_DRIVE_SUCCESS, log=True, logtag='system.unmount')
def gethostMAC(): try: return _run('hcitool dev')[0].decode('utf8').split('\n')[1].split()[1] except IndexError: printing.printf('No bluetooth adapter available', style=printing.ERROR)
def print_header(width=None): # Fill width of screen if not width: width = get_terminal_size(fallback=(100, 24))[0] logo = LOGO.replace('\n', '\n' + ' ' * int((width - 50) / 2)) printing.printf(logo, style=printing.LOGO) printing.printf(('{:^' + str(width) + '}').format('FRC Team 449: The Blair Robot Project'), style=printing.HEADER) printing.printf('=' * width, style=printing.HEADER) printing.printf(('{:^' + str(width) + '}').format('Bluetooth Scouting Server'), style=printing.TITLE) printing.printf() printing.printf(('{:^' + str(width) + '}').format('Runs with Python3 on Linux'), style=printing.INSTRUCTIONS) printing.printf(('{:^' + str(width) + '}').format('Written by Carter Wilson, 2019'), style=printing.INSTRUCTIONS) printing.printf('-' * width + '\n', style=printing.INSTRUCTIONS) printing.printf('Instructions for use:', style=printing.INSTRUCTIONS) tw = TextWrapper(width=width) printing.printf(tw.fill( 'This server is intended for use with the Team 449 scouting app (and strategy app) for android.') + '\n' + tw.fill('On each scouting tablet, please launch the scouting app, select your device name from the ' 'popup, and press connect. If there is no popup, press the Bluetooth icon in the top right ' 'corner of the app.') + '\n' + tw.fill('When connected, you should receive a popup in the app informing you that a connection was ' 'made, as well as output from this server with the name of the device.') + '\n' + tw.fill('To retrieve the data file for data analysis, plug in a USB flash drive, wait for output ' 'saying that it was mounted, the data was copied, and it was unmounted, then remove it.') + '\n' + tw.fill( 'If the drive does not get detected/updated, it may be because there is no new data since you ' 'last updated it. If you would still like to update it (if, for example, you switched flash ' 'drives), just type d, data, u, or update into the server.') + '\n' + tw.fill( 'To retrieve data for strategy, type "s" and hit enter, then enter the team numbers.') + '\n' + tw.fill('To quit the server, type "q" or "quit" and press enter, confirm that you want to ' 'quit, and wait for the server to close.'), style=printing.INSTRUCTIONS) printing.printf() printing.printf('-' * width + '\n\n', style=printing.UNDERLINE)