Fri, 09 Dec 2011 22:15:50 +0100
pitlane response enter/exit pitlane, led lit when car is in pitlane
#!/usr/bin/env python """ Freeslot project Command line interface """ from freeslot import Blackbox from optparse import OptionParser import sys from copy import copy import curses VERSION = "1.2" MAXSLOTS = 6 TERM = { "caption": "\033[1;37m\033[1;44m", "text": "\033[1;30m", } class SlotCli(): def __init__(self): self.box = Blackbox() self.box.connect() self.slot_dummy = { "name": "Unnamed", "laps": 0, "last": 0.00, "best": 0.00, "fuel": 0, "position": 0, "drive": 0, } self.slot = [ copy(self.slot_dummy), copy(self.slot_dummy), copy(self.slot_dummy), copy(self.slot_dummy), copy(self.slot_dummy), copy(self.slot_dummy), ] def update_positions(self): for idx in range(MAXSLOTS): self.slot[idx]["position"] = idx + 1 # TODO def render_slots(self): self.update_positions() self.scr.addstr(3,0, "Pos | #/Name | Laps | Best | Last | Fuel |", curses.color_pair(2)) for idx in range(MAXSLOTS): self.scr.addstr((3 + self.slot[idx]["position"]), 0, "%3i | %15s | %4i | %5.2fs | %5.2fs | %3i%% |" % ( self.slot[idx]["position"], self.slot[idx]["name"], self.slot[idx]["laps"], self.slot[idx]["best"], self.slot[idx]["last"], self.slot[idx]["fuel"], ) ) def cleartop(self): self.scr.addstr(0,0, "%80s" % "Live monitor running, press keys to control or (q)uit") self.scr.addstr(1,0, "%80s" % " ") def readName(self, slot): self.scr.nodelay(0) # enable delay on readkey curses.echo() self.scr.addstr(0,0, "Enter Name for Controller %i [%s]:" % ( slot + 1, self.slot[slot]["name"]), curses.color_pair(1)) self.scr.refresh() name = self.scr.getstr(1,0, 15) if name != "": self.slot[slot]["name"] = name self.cleartop() self.scr.refresh() curses.noecho() self.scr.nodelay(1) # disable delay on readkey def monitor(self): """ Live Monitor on the console Keyboard loop to control it??? """ self.scr = curses.initscr() curses.start_color() curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK) # standard text curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLUE) # label curses.noecho() # disable key echo curses.cbreak() # do not buffer keypresses self.scr.keypad(1) # enable special keys self.scr.nodelay(1) # disable delay on readkey self.cleartop() self.render_slots() self.scr.refresh() while 1: key = self.scr.getch() if key == ord('q'): break elif key == ord(' '): self.cyclemode() elif key == ord('1'): self.readName(0) elif key == ord('2'): self.readName(1) elif key == ord('3'): self.readName(2) elif key == ord('4'): self.readName(3) elif key == ord('5'): self.readName(4) elif key == ord('6'): self.readName(5) elif key == ord('a'): if self.slot[4]["drive"] > 0: self.slot[4]["drive"] -= 1 cli.box.speedminimum(4, self.slot[4]["drive"]) elif key == ord('s'): if self.slot[4]["drive"] < 16: self.slot[4]["drive"] += 1 cli.box.speedminimum(4, self.slot[4]["drive"]) elif key == ord('y'): if self.slot[5]["drive"] > 0: self.slot[5]["drive"] -= 1 cli.box.speedminimum(5, self.slot[5]["drive"]) elif key == ord('x'): if self.slot[5]["drive"] < 16: self.slot[5]["drive"] += 1 cli.box.speedminimum(5, self.slot[4]["drive"]) # is there something in the rx buffer? rx = self.box.com.readline() if rx != "": # we have received something data = rx.split(":") if rx[:2] == "L:": # update lap time info slot = int(data[3]) - 1 t = int(data[4], 16) l = int(data[2], 16) t /= 2000.00 self.slot[slot]["laps"] = l self.slot[slot]["last"] = t if (self.slot[slot]["best"] > t) or (self.slot[slot]["best"] == 0): self.slot[slot]["best"] = t self.render_slots() if rx[:2] == "F:": # update fuel level slot = int(data[1]) f = int(data[2], 16) f = f / 100 # fuel in percent self.slot[slot]["fuel"] = f self.render_slots() self.scr.refresh() # terminate curses.nocbreak() self.scr.keypad(0) curses.echo() curses.endwin() return None def cyclemode(self): pass if __name__ == "__main__": parser = OptionParser(version="%prog " + VERSION) parser.add_option("--live", dest="live", action="store_true", default=False, help="Run Live monitor on console", metavar="[0-5]") parser.add_option("--carid", dest="carid", help="Required for programming a car directly", metavar="[0-5]") parser.add_option("--fuel", dest="fuel", help="Set maximum CAR fuel level", metavar="[0-15]") parser.add_option("--brake", dest="brake", help="Set CAR brake strength", metavar="[0-15]") parser.add_option("--speed", dest="speed", help="Set maximum CAR speed", metavar="[0-15]") parser.add_option("--blink", dest="blink", help="Set car lights blinking state", metavar="[on|off]") parser.add_option("--limit", dest="limit", help="Controlled SPEED LIMIT (15 = no limit)", metavar="[0-15]") parser.add_option("--drive", dest="drive", help="Controlled SPEED MINIMUM (0 = disabled)", metavar="[0-15]") (options, args) = parser.parse_args() cli = SlotCli() # should a CLI function be started? if options.live: # start the live monitor cli.monitor() sys.exit(0) # check commandline if we have to program something if not options.carid: print "Option --carid is required for all car programming commands!\nUse --help to get a list of available commands" sys.exit(1) if options.fuel: print "setFuel: " + cli.box.progcar(int(options.carid), "fuel", int(options.fuel)) if options.speed: print "setSpeed: " + cli.box.progcar(int(options.carid), "speed", int(options.speed)) if options.brake: print "setBrake: " + cli.box.progcar(int(options.carid), "brake", int(options.brake)) if options.blink: state = False if options.blink == "on": state = True print "setBlink: " + cli.box.blinkcar(int(options.carid), state) if options.limit: print "Change Speed Limit: " + cli.box.speedlimit(int(options.carid), int(options.limit)) if options.drive: print "Change minimum Speed drive: " + cli.box.speedminimum(int(options.carid), int(options.drive))