slotUI/SlotCli.py

changeset 77
cede78304992
parent 74
173d0863a804
child 78
d9126a55295c
--- a/slotUI/SlotCli.py	Sun Dec 11 13:54:14 2011 +0100
+++ b/slotUI/SlotCli.py	Sun Dec 11 17:34:40 2011 +0100
@@ -4,19 +4,23 @@
 Command line interface
 """
 
-from freeslot import Blackbox
+from freeslot import Blackbox, LOGLEVEL
 from optparse import OptionParser
+from operator import itemgetter
 import sys
 from copy import copy
 import curses
 
-VERSION = "1.2"
+VERSION = "1.3"
 MAXSLOTS = 6
 TERM = {
     "caption": "\033[1;37m\033[1;44m",
     "text": "\033[1;30m",
     }
 
+# disable debug log output
+LOGLEVEL = 10
+
 class SlotCli():
     def __init__(self):
         self.box = Blackbox()
@@ -29,6 +33,9 @@
             "fuel": 0,
             "position": 0,
             "drive": 0,
+            "status": "Idle",
+            "clk": 0,
+            "car": 0,
             }
 
         self.slot = [
@@ -36,26 +43,47 @@
             copy(self.slot_dummy), copy(self.slot_dummy),
             copy(self.slot_dummy), copy(self.slot_dummy),
             ]
+        self.reset_slots()
+        self.sysclk = 0.00
+
+    def reset_slots(self):
+        idx = 0
+        for slt in self.slot:
+            slt["laps"] = 0
+            slt["last"] = 0.00
+            slt["best"] = 0.00
+            slt["fuel"] = 0
+            slt["position"] = idx
+            slt["car"] = idx # used for sort order calculation
+            slt["status"] = self.slot_dummy["status"]
+            slt["clk"] = 0
+            idx += 1
 
     def update_positions(self):
-        for idx in range(MAXSLOTS):
-            self.slot[idx]["position"] = idx + 1
-        # TODO
+        order1 = sorted(self.slot, key=itemgetter(
+            "clk"))
+        order2 = sorted(self.slot, key=itemgetter(
+            "laps"), reverse=True)
+        idx = 1
+        for tst in order2:
+            self.slot[tst["car"]]["position"] = idx
+            idx += 1
 
     def render_slots(self):
         self.update_positions()
         self.scr.addstr(3,0,
-            "Pos | #/Name          | Laps | Best   | Last   | Fuel |",
+            "Pos | #/Name            | Laps | Best     | Last     | Fuel | Status    ",
             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%% |" % (
+                "%3i | %i %15s | %4i | %7.2fs | %7.2fs | %3i%% | %10s" % (
                 self.slot[idx]["position"],
-                self.slot[idx]["name"],
+                self.slot[idx]["car"] + 1, self.slot[idx]["name"],
                 self.slot[idx]["laps"],
                 self.slot[idx]["best"],
                 self.slot[idx]["last"],
                 self.slot[idx]["fuel"],
+                self.slot[idx]["status"],
                 ) )
 
     def cleartop(self):
@@ -90,6 +118,9 @@
         Live Monitor on the console
         Keyboard loop to control it???
         """
+        # clear garbage in UART rx buffer
+        while self.box.com.readline() != "": pass
+
         self.monitor_init()
         self.scr = curses.initscr()
         curses.start_color()
@@ -132,17 +163,22 @@
             # is there something in the rx buffer?
             rx = self.box.com.readline()
             if rx != "":
+                self.scr.addstr(10,0,
+                    "Last RX: %19s" % rx, curses.color_pair(2))
+                self.scr.refresh()
                 # we have received something
                 data = rx.split(":")
                 if rx[:2] == "L:":
                     # update lap time info
+                    l = int(data[2], 16)
                     slot = int(data[3]) - 1
-                    t = int(data[4], 16)
-                    l = int(data[2], 16)
-                    t /= 2000.00
+                    t = int(data[4], 16) / 2000.00
+                    self.sysclk = int(data[5], 16) / 2000.00
                     self.slot[slot]["laps"] = l
                     self.slot[slot]["last"] = t
+                    self.slot[slot]["clk"] = self.sysclk
                     if (self.slot[slot]["best"] > t) or (self.slot[slot]["best"] == 0): self.slot[slot]["best"] = t
+                    self.slot[slot]["status"] = "IN-RACE"
                     self.render_slots()
 
                 if rx[:2] == "F:":
@@ -150,9 +186,51 @@
                     slot = int(data[1])
                     f = int(data[2], 16)
                     f = f / 100 # fuel in percent
+                    self.sysclk = int(data[3], 16) / 2000.00
                     self.slot[slot]["fuel"] = f
                     self.render_slots()
 
+                if rx[:1] == "~":
+                    # jumpstart occured
+                    slot = int(rx[1:2])
+                    t = int(data[1], 16) / 2000.00
+                    self.slot[slot]["jumpstart"] = t
+                    self.slot[slot]["status"] = "Jumpstart!"
+
+                if rx[:3] == "RW:":
+                    # ResponseWire packet, do nothing at the moment, just decode
+                    slot = int(data[1])
+                    devtype = int(data[2])
+                    sender = int(data[3], 16)
+                    status = int(data[4], 16)
+                    self.sysclk = int(data[5], 16)
+                    if (devtype == 4):
+                        # pitlane sent something
+                        if (status == 5): self.slot[slot]["status"] = "PITLANE"
+                        if (status == 6): self.slot[slot]["status"] = "IN-RACE"
+
+                    self.render_slots()
+
+                if rx == "!RACE PREPARE":
+                    # reset current race status
+                    # and display PREPARE PHASE
+                    for slot in range(MAXSLOTS):
+                        self.slot[slot]["status"] = "Prepare"
+
+                if rx == "!RACE START":
+                    for slot in range(MAXSLOTS):
+                        if self.slot[slot]["status"] == "~~~~~~~~~~":
+                            self.slot[slot]["status"] = "Idle"
+
+                if rx == "!COUNTDOWN":
+                    # countdown initiated
+                    for slot in range(MAXSLOTS):
+                        self.slot[slot]["status"] = "~~~~~~~~~~"
+
+                self.scr.addstr(10,31,
+                    "Race Timer: %7.3f min" % (self.sysclk / 60),
+                    curses.color_pair(2))
+
                 self.scr.refresh()
 
         # terminate

mercurial