def __init__(self, linelen=32): """Constructor.""" threading.Thread.__init__(self) self.running = False self._curpace = 0.1 self.il = None try: import irclib self.ih = irclib.IRC() self.il = irclib except ImportError: self.ih = fakeirc() self.ic = self.ih.server() self.np = tod.tod('now')+tod.tod('30') # self ping timeeout self.name = 'uSCBsrv' self.rdbuf = '' self.wrbuf = '' self.chanstatus = False self.host = USCBSRV_HOST self.port = USCBSRV_PORT self.channel = USCBSRV_CHANNEL self.srvnick = USCBSRV_SRVNICK self.doreconnect = False self.connect_pending = False self.dumbcnt = 0 self.curov = None self.linelen = linelen self.queue = Queue.Queue() self.log = logging.getLogger('scbdo.uscbsrv') self.log.setLevel(logging.DEBUG)
def race_info_time_edit_activate_cb(self, button): """Display race timing edit dialog.""" ostx = '' oftx = '' if self.start is not None: ostx = self.start.rawtime(4) if self.finish is not None: oftx = self.finish.rawtime(4) (ret, stxt, ftxt) = uiutil.edit_times_dlg(self.meet.window, ostx, oftx) if ret == 1: try: stod = None if stxt: stod = tod.tod(stxt, 'MANU', 'C0i') self.meet.timer.printline(' ' + str(stod)) ftod = None if ftxt: ftod = tod.tod(ftxt, 'MANU', 'C1i') self.meet.timer.printline(' ' + str(ftod)) self.set_start(stod) self.set_finish(ftod) self.set_elapsed() if self.start is not None and self.finish is not None: self.log_elapsed() self.log.info('Updated race times.') except (decimal.InvalidOperation, ValueError), v: self.log.error('Error updating times: ' + str(v)) glib.idle_add(self.delayed_announce)
def procmsg(self, msg): """Read IPX wheeltime event and insert as tod into command queue.""" s = msg.strip() if (len(s) == 36 or len(s) == 38) and s[1] == 'a': sum = ipico_lrc(s) lrc = int(s[34:36], 16) if sum == lrc: #tagid=s[4:16] ## NOTE: Using 'shortform' tag ids if s[4:10] == '058001': # match id prefix tagid=(s[10:16]).lower() timestr = '{0}:{1}:{2}.{3:02}'.format(s[26:28], s[28:30], s[30:32], int(s[32:34], 16)) self.cqueue.put_nowait(('RFID', tod.tod(timestr, 'RFID', '', tagid))) else: self.log.warn('Spurious tag id: ' + s[4:10] + ' :: ' + s[10:16]) else: self.log.warn('Incorrect char sum message skipped: ' + hex(sum) + ' != ' + hex(lrc)) elif len(s) == 30 and s[0:8] == 'ab010a2c': sum = ipico_lrc(s, 28) lrc = int(s[28:30], 16) if sum == lrc: timestr = '{0}:{1}:{2}.{3:02}'.format(s[16:18], s[18:20], s[20:22], int(s[22:24], 16)) self.cqueue.put_nowait(('RFID', tod.tod(timestr, 'RFID', '', 'trig'))) #self.log.debug('TRIG MSG: ' + repr(s)) else: self.log.warn('Incorrect char sum message skipped: ' + hex(sum) + ' != ' + hex(lrc)) else: self.log.debug('Non RFID message: ' + repr(msg))
def procmsg(self, msg): """Read IPX wheeltime event and insert as tod into command queue.""" s = msg.strip() if (len(s) == 36 or len(s) == 38) and s[1] == 'a': sum = ipico_lrc(s) lrc = int(s[34:36], 16) if sum == lrc: #tagid=s[4:16] ## NOTE: Using 'shortform' tag ids if s[4:10] == '058001': # match id prefix tagid = (s[10:16]).lower() timestr = '{0}:{1}:{2}.{3:02}'.format( s[26:28], s[28:30], s[30:32], int(s[32:34], 16)) self.cqueue.put_nowait( ('RFID', tod.tod(timestr, 'RFID', '', tagid))) else: self.log.warn('Spurious tag id: ' + s[4:10] + ' :: ' + s[10:16]) else: self.log.warn('Incorrect char sum message skipped: ' + hex(sum) + ' != ' + hex(lrc)) elif len(s) == 30 and s[0:8] == 'ab010a2c': sum = ipico_lrc(s, 28) lrc = int(s[28:30], 16) if sum == lrc: timestr = '{0}:{1}:{2}.{3:02}'.format(s[16:18], s[18:20], s[20:22], int(s[22:24], 16)) self.cqueue.put_nowait( ('RFID', tod.tod(timestr, 'RFID', '', 'trig'))) #self.log.debug('TRIG MSG: ' + repr(s)) else: self.log.warn('Incorrect char sum message skipped: ' + hex(sum) + ' != ' + hex(lrc)) else: self.log.debug('Non RFID message: ' + repr(msg))
def run(self): """Called via threading.Thread.start().""" self.running = True self.log.debug('Starting') self.ic.add_global_handler('privmsg', self.privmsg_cb, -10) self.ic.add_global_handler('join', self.channel_join_cb, -10) self.ic.add_global_handler('part', self.channel_part_cb, -10) self.ic.add_global_handler('kick', self.channel_part_cb, -10) ##self.ic.add_global_handler('all_events', self.irc_event_cb, 0) while self.running: try: self.ih.process_once(0) if self.host != '': # irc process phase if not self.connected() or self.doreconnect: self.doreconnect = False if not self.connect_pending: self.chanstatus = False self._reconnect() # keepalive ping now = tod.tod('now') if now > self.np: self.ic.ctcp('PING', self.srvnick, str(int(time.time()))) self.np = now + tod.tod('60') else: time.sleep(5) # queue process phase - queue empty exception breaks loop while True: m = self.queue.get_nowait() self.queue.task_done() if m[0] == 'MSG' and self.host != '': ## TODO : split message > 450 ? self.ic.privmsg(self.channel, unt4.encode(m[1])) elif m[0] == 'EXIT': self.log.debug('Request to close : ' + str(m[1])) self.running = False elif m[0] == 'PORT': if not self.connect_pending: self.doreconnect = True self._pacing(0.0) except Queue.Empty: time.sleep(self._pacing()) # pacing except Exception as e: self.log.error('Exception: ' + str(type(e)) + str(e)) self.connect_pending = False self.dumbcnt += 1 if self.dumbcnt > 2: self.host = '' self.log.debug('Not connected.') time.sleep(2.0) self.ic.close() self.log.info('Exiting')
def set_elapsed(self): """Update the elapsed time field.""" if self.start is not None and self.finish is not None: self.time_lbl.set_text((self.finish - self.start).timestr(0)) elif self.start is not None: # Note: uses 'local start' for RT self.time_lbl.set_text((tod.tod('now') - self.lstart).timestr(0)) elif self.timerstat == 'armstart': self.time_lbl.set_text(tod.tod(0).timestr(0)) else: self.time_lbl.set_text('')
def set_elapsed(self): """Update elapsed time in race ui and announcer.""" if self.start is not None and self.finish is not None: et = self.finish - self.start self.time_lbl.set_text(et.timestr(3)) elif self.start is not None: # Note: uses 'local start' for RT self.time_lbl.set_text((tod.tod('now') - self.lstart).timestr(1)) elif self.timerstat == 'armstart': self.time_lbl.set_text(tod.tod(0).timestr(1)) else: self.time_lbl.set_text('')
def on_start(self, curoft): for i in self.unstarters: if curoft + tod.tod('10') == self.unstarters[i]: self.log.info('about to load rider ' + i) (bib, series) = strops.bibstr2bibser(i) #!!! TODO -> use bib.ser ? self.sl.setrider(bib, series) self.sl.toarmstart() self.meet.timer.arm(0) self.start_unload = self.unstarters[i] + tod.tod('10') glib.timeout_add_seconds(180, self.add_starter, i) break
def clearplaces(self): """Zero internal model for recalculate.""" for r in self.riders: r[COL_PLACE] = '' r[COL_TOTAL] = 0 r[COL_TIME] = tod.tod(0) r[COL_POINTS] = []
def timeout(self): """Update status buttons and time of day clock button.""" if not self.running: return False else: # update pc ToD label self.clock_label.set_text( tod.tod('now').rawtime(places=0,zeros=True)) # call into race timeout handler if self.curevent is not None: self.curevent.timeout() else: # otherwise collent and discard any pending events while self.rfu.response() is not None: pass while self.timer.response() is not None: pass # lastly display RFU status button nstat = self.rfu.connected() if nstat != self.rfustat: if nstat: self.menu_rfustat_img.set_from_stock( gtk.STOCK_CONNECT, gtk.ICON_SIZE_LARGE_TOOLBAR) else: self.menu_rfustat_img.set_from_stock( gtk.STOCK_DISCONNECT, gtk.ICON_SIZE_LARGE_TOOLBAR) self.rfustat = nstat return True
def do_places(self): """Show race result on scoreboard.""" self.placexfer(self.ctrl_places.get_text()) self.meet.scbwin = None self.timerwin = False ts = None tp = 'Time:' if self.start is not None and self.finish is None: self.finish = tod.tod('now') self.set_elapsed() if self.timetype == '200m': tp = '200m:' et = self.time_lbl.get_text() if et is not None and et != '': ts = et self.meet.scbwin = scbwin.scbtable(self.meet.scb, self.meet.racenamecat(self.event), SCB_RESULT_FMT, self.results[0:4], timepfx=tp, timestr=ts, pagesz=5) self.meet.scbwin.reset() # !! is this a bug? what if there are no places/time yet? self.setfinished()
def timeout(self): """Update status buttons and time of day clock button.""" if not self.running: return False else: # update pc ToD label self.clock_label.set_text( tod.tod('now').rawtime(places=0, zeros=True)) # call into race timeout handler if self.curevent is not None: self.curevent.timeout() else: # otherwise collent and discard any pending events while self.rfu.response() is not None: pass while self.timer.response() is not None: pass # lastly display RFU status button nstat = self.rfu.connected() if nstat != self.rfustat: if nstat: self.menu_rfustat_img.set_from_stock( gtk.STOCK_CONNECT, gtk.ICON_SIZE_LARGE_TOOLBAR) else: self.menu_rfustat_img.set_from_stock( gtk.STOCK_DISCONNECT, gtk.ICON_SIZE_LARGE_TOOLBAR) self.rfustat = nstat return True
def result_export(self, f): """Export result for use with other systems.""" cr = csv.writer(f) cr.writerow(['no', 'rider', 'email', 'laps', 'Split 1', 'Lap 1', 'Split 2', 'Lap 2', 'Split 3', 'Lap 3', 'Split 4', 'Lap 4']) # set the start time st = tod.tod(0) if self.start is not None: st = self.start # scan start list for r in self.riders: res = [r[COL_BIB], r[COL_NAMESTR], r[COL_COMMENT], str(len(r[COL_RFSEEN]))] # scan lap splits lt = st for split in r[COL_RFSEEN]: laptime = split - lt lapstr = laptime.rawtime(0) splitstr = split.rawtime(0) if laptime < self.minlap: self.log.warn('Suspect lap for rider ' + repr(r[COL_BIB]) + ':' + lapstr) res.append(splitstr) res.append(lapstr) lt = split # emit row cr.writerow(res)
def __init__(self): threading.Thread.__init__(self) self.running = False self.cb = None self.ih = irclib.IRC() self.ic = self.ih.server() self.np = tod.tod('now')+tod.tod('30') self.hasconnnected = False self.rdbuf = '' self.doreconnect = False self.chanstatus = False self.host = USCBSRV_HOST self.port = USCBSRV_PORT self.channel = USCBSRV_CHANNEL self.cltnick = USCBSRV_CLTNICK self.srvnick = USCBSRV_SRVNICK self._curpace = 0.0
def __init__(self): threading.Thread.__init__(self) self.running = False self.cb = None self.ih = irclib.IRC() self.ic = self.ih.server() self.np = tod.tod("now") + tod.tod("30") self.hasconnnected = False self.rdbuf = "" self.doreconnect = False self.chanstatus = False self.host = USCBSRV_HOST self.port = USCBSRV_PORT self.channel = USCBSRV_CHANNEL self.cltnick = USCBSRV_CLTNICK self.srvnick = USCBSRV_SRVNICK self._curpace = 0.0
def starttrig(self, e): """React to start trigger.""" if self.timerstat == 'armstart': self.start = e self.lstart = tod.tod('now') self.setrunning() if self.timetype == '200m': self.armfinish()
def set_finished(self): """Update event status to finished.""" self.timerstat = 'finished' self.meet.rfu.dearm() uiutil.buttonchg(self.meet.stat_but, uiutil.bg_none, 'Finished') self.meet.stat_but.set_sensitive(False) if self.finish is None: self.set_finish(tod.tod('now')) self.set_elapsed()
def menu_clock_timeout(self): """Update time of day on clock button.""" if not self.running: return False else: tt = tod.tod('now').rawtime(places=0,zeros=True) self.clock_label.set_text(tt) #self.announce.postxt(0,72,tt) return True
def menu_clock_timeout(self): """Update time of day on clock button.""" if not self.running: return False else: tt = tod.tod('now').rawtime(places=0, zeros=True) self.clock_label.set_text(tt) #self.announce.postxt(0,72,tt) return True
def __init__(self, meet, event, ui=True): self.meet = meet self.event = event # Note: now a treerowref self.evno = meet.edb.getvalue(event, eventdb.COL_EVNO) self.series = meet.edb.getvalue(event, eventdb.COL_SERIES) self.configpath = os.path.join(self.meet.configpath, 'event_' + self.evno) self.log = logging.getLogger('scbdo.sportif') self.log.setLevel(logging.DEBUG) self.log.debug('opening event: ' + str(self.evno)) # race run time attributes self.readonly = not ui self.start = None self.lstart = None self.finish = None self.winopen = True self.timerstat = 'idle' self.minlap = tod.tod('20:00.0') self.riders = gtk.ListStore(gobject.TYPE_STRING, # BIB = 0 gobject.TYPE_STRING, # NAMESTR = 1 gobject.TYPE_STRING, # CAT = 2 gobject.TYPE_STRING, # COMMENT = 3 gobject.TYPE_PYOBJECT, # RFTIME = 4 gobject.TYPE_PYOBJECT) # RFSEEN = 5 b = gtk.Builder() b.add_from_file(os.path.join(scbdo.UI_PATH, 'sportif.ui')) # !! destroy?? self.frame = b.get_object('race_vbox') self.frame.connect('destroy', self.shutdown) # meta info pane self.title_namestr = b.get_object('title_namestr') self.set_titlestr() self.time_lbl = b.get_object('time_lbl') self.time_lbl.modify_font(pango.FontDescription("monospace bold")) # results pane t = gtk.TreeView(self.riders) t.set_reorderable(True) t.set_rules_hint(True) t.show() uiutil.mkviewcoltxt(t, 'No.', COL_BIB, calign=1.0) uiutil.mkviewcoltxt(t, 'Rider', COL_NAMESTR, expand=True) uiutil.mkviewcoltxt(t, 'Comment', COL_COMMENT, cb=self.editcol_cb, width=120) b.get_object('race_result_win').add(t) if ui: # connect signal handlers b.connect_signals(self) self.meet.edb.editevent(event, winopen=True) self.meet.rfu.arm()
def run(self): """Called via threading.Thread.start().""" self.running = True self.ic.add_global_handler("pubmsg", self.unt_msg_cb, -10) self.ic.add_global_handler("pubnotice", self.unt_msg_cb, -10) self.ic.add_global_handler("join", self.channel_join_cb, -10) self.ic.add_global_handler("part", self.channel_part_cb, -10) self.ic.add_global_handler("kick", self.channel_part_cb, -10) self.ic.add_global_handler("nicknameinuse", self.nicknameinuse_cb, -10) # self.ic.add_global_handler('all_events', self.irc_event_cb, 0) while self.running: try: self.ih.process_once(0) if not self.ic.is_connected() or self.doreconnect: self.doreconnect = False self.chanstatus = False time.sleep(2) self._reconnect() # skip over preliminary connect chatter ready to # poll channel status - avoids double channel join if self.hasconnnected: self.ih.process_once(0) self.ih.process_once(0) self.ih.process_once(0) self.ih.process_once(0) self.ih.process_once(0) self.ih.process_once(0) self.ih.process_once(0) self.ih.process_once(1) else: self.hasconnnected = True if not self.in_channel(): time.sleep(2) self._rejoin() now = tod.tod("now") if now > self.np: self.ic.ctcp("PING", self.cltnick, str(int(time.time()))) self.np = now + tod.tod("30") time.sleep(self._pacing()) except Exception as e: # TODO : FIX HERE? print("Exception from uscbio: " + str(e))
def run(self): """Called via threading.Thread.start().""" self.running = True self.ic.add_global_handler('pubmsg', self.unt_msg_cb, -10) self.ic.add_global_handler('pubnotice', self.unt_msg_cb, -10) self.ic.add_global_handler('join', self.channel_join_cb, -10) self.ic.add_global_handler('part', self.channel_part_cb, -10) self.ic.add_global_handler('kick', self.channel_part_cb, -10) self.ic.add_global_handler('nicknameinuse', self.nicknameinuse_cb, -10) #self.ic.add_global_handler('all_events', self.irc_event_cb, 0) while self.running: try: self.ih.process_once(0) if not self.ic.is_connected() or self.doreconnect: self.doreconnect = False self.chanstatus = False time.sleep(2) self._reconnect() # skip over preliminary connect chatter ready to # poll channel status - avoids double channel join if self.hasconnnected: self.ih.process_once(0) self.ih.process_once(0) self.ih.process_once(0) self.ih.process_once(0) self.ih.process_once(0) self.ih.process_once(0) self.ih.process_once(0) self.ih.process_once(1) else: self.hasconnnected = True if not self.in_channel(): time.sleep(2) self._rejoin() now = tod.tod('now') if now > self.np: self.ic.ctcp('PING', self.cltnick, str(int(time.time()))) self.np = now + tod.tod('30') time.sleep(self._pacing()) except Exception as e: # TODO : FIX HERE? print ('Exception from uscbio: ' + str(e))
def addrider(self, bib=''): """Add specified rider to race model.""" nr=[bib, '', '', '', '', 0, tod.tod(0), '', []] if bib == '' or self.getrider(bib) is None: dbr = self.meet.rdb.getrider(bib, self.series) if dbr is not None: for i in range(1,5): nr[i] = self.meet.rdb.getvalue(dbr, i) return self.riders.append(nr) else: return None
def slow_timeout(self): """Update slow changing aspects of race.""" if not self.winopen: return False if self.timerstat == 'running': nowoft = (tod.tod('now') - self.lstart).truncate(0) if self.sl.getstatus() == 'idle': if nowoft.timeval % 10 == tod.tod('0'): # every ten. self.on_start(nowoft) else: if nowoft == self.start_unload: self.sl.toidle() # after manips, then re-set start time self.sl.set_time(nowoft.timestr(0)) # maintain expiry of 'not finishing' set -> ~120 secs after start # loads starters into start channel and arm # clear starters from start channel pass
def addrider(self, bib=''): """Add specified rider to race model.""" nr = [bib, '', '', '', '', 0, tod.tod(0), '', []] if bib == '' or self.getrider(bib) is None: dbr = self.meet.rdb.getrider(bib, self.series) if dbr is not None: for i in range(1, 5): nr[i] = self.meet.rdb.getvalue(dbr, i) return self.riders.append(nr) else: return None
def key_event(self, widget, event): """Collect key events on main window and send to race.""" if event.type == gtk.gdk.KEY_PRESS: key = gtk.gdk.keyval_name(event.keyval) or 'None' if event.state & gtk.gdk.CONTROL_MASK: key = key.lower() if key in ['0', '1', '2', '3', '4', '5', '6', '7']: self.timer.trig(int(key), tod.tod('now')) return True if self.curevent is not None: return self.curevent.key_event(widget, event) return False
def key_event(self, widget, event): """Collect key events on main window and send to race.""" if event.type == gtk.gdk.KEY_PRESS: key = gtk.gdk.keyval_name(event.keyval) or 'None' if event.state & gtk.gdk.CONTROL_MASK: key = key.lower() if key in ['0','1','2','3','4','5','6','7']: self.timer.trig(int(key), tod.tod('now')) return True if self.curevent is not None: return self.curevent.key_event(widget, event) return False
def key_event(self, widget, event): """Collect key events on main window and send to race.""" if event.type == gtk.gdk.KEY_PRESS: key = gtk.gdk.keyval_name(event.keyval) or "None" if event.state & gtk.gdk.CONTROL_MASK: key = key.lower() if key in ["0", "1", "2", "3", "4", "5", "6", "7"]: self.timer.trig(int(key), tod.tod("now")) return True if self.curevent is not None: return self.curevent.key_event(widget, event) return False
def toload(self, bib=None): """Load timer.""" self.status = 'load' self.starttod = None self.recovtod = tod.tod(0) self.finishtod = None self.set_time() self.lap = 0 self.set_lap() self.splits = [] if bib is not None: self.setrider(bib) uiutil.buttonchg(self.b, uiutil.bg_none, 'Ready')
def toload(self, bib=None): """Load timer.""" self.status = "load" self.starttod = None self.recovtod = tod.tod(0) self.finishtod = None self.set_time() self.lap = 0 self.set_lap() self.splits = [] if bib is not None: self.setrider(bib) uiutil.buttonchg(self.b, uiutil.bg_none, "Ready")
def append_rider(self, msg): sr = msg.split(chr(unt4.US)) if len(sr) == 5: rftime = tod.str2tod(sr[4]) if rftime is not None: if len(self.riders) == 0: # Case 1: Starting a new lap self.cur_lap = (rftime - self.cur_split).truncate(0) self.cur_split = rftime.truncate(0) self.cur_bunchid = 0 self.cur_bunchcnt = 1 self.last_time = rftime nr = [ sr[0], sr[1], sr[2], sr[3], self.cur_lap.rawtime(0), self.cur_bunchcnt, COLOURMAP[self.cur_bunchid][0], rftime, ] elif rftime < self.last_time or rftime - self.last_time < tod.tod("1.12"): # Case 2: Same bunch self.last_time = rftime self.cur_bunchcnt += 1 nr = [sr[0], sr[1], sr[2], sr[3], "", self.cur_bunchcnt, COLOURMAP[self.cur_bunchid][0], rftime] else: # Case 3: New bunch self.riders.append(["", "", "", "", "", "", "#fefefe", None]) self.cur_bunchid = (self.cur_bunchid + 1) % COLOURMAPLEN self.cur_bunchcnt = 1 self.last_time = rftime nr = [ sr[0], sr[1], sr[2], sr[3], "+" + (rftime - self.cur_split).rawtime(0), self.cur_bunchcnt, COLOURMAP[self.cur_bunchid][0], rftime, ] else: # Informative non-timeline record nr = [sr[0], sr[1], sr[2], sr[3], "", "", "#fefefe", None] self.riders.append(nr) self.map_redraw() # update src map self.map_area.queue_draw() # queue copy to screen
def result_report(self): """Return a result report.""" ret = [] # set the start time st = tod.tod(0) if self.start is not None: st = self.start # resort -> ?? # scan registered riders for r in self.riders: ret.append(self.fmt_rider_result(r, st)) return ret
def toidle(self): """Set timer state to idle.""" self.status = 'idle' self.bib = None self.bibent.set_text('') self.bibent.set_sensitive(True) self.serent.set_sensitive(True) self.biblbl.set_text('') self.starttod = None self.recovtod = tod.tod(0) self.finishtod = None self.lap = 0 self.set_lap() self.splits = [] self.set_time() uiutil.buttonchg(self.b, uiutil.bg_none, 'Idle')
def query_rider(self, bib=None): """List info on selected rider in the scratchpad.""" # set the start time st = tod.tod(0) if self.start is not None: st = self.start # get the rider r = self.getrider(bib) if r is not None: self.meet.scratch_log(self.fmt_rider_result(r, st)) else: self.log.info('Rider = ' + repr(bib) + ' not in startlist.') return False # allow push via idle_add(...
def start_trig(self, t): """Register start trigger.""" if self.timerstat == 'running': # check lane to apply pulse. if self.sl.getstatus() == 'armstart': i = self.getiter(self.sl.bibent.get_text(), self.sl.serent.get_text()) if i is not None: self.settimes(i, tst=t) self.sl.torunning() else: self.log.error('Missing rider at start') self.sl.toidle() pass elif self.timerstat == 'armstart': self.set_syncstart(t, tod.tod('now'))
def toidle(self): """Set timer state to idle.""" self.status = "idle" self.bib = None self.bibent.set_text("") self.bibent.set_sensitive(True) self.serent.set_sensitive(True) self.biblbl.set_text("") self.starttod = None self.recovtod = tod.tod(0) self.finishtod = None self.lap = 0 self.set_lap() self.splits = [] self.set_time() uiutil.buttonchg(self.b, uiutil.bg_none, "Idle")
def trig(self, channel=0, t=None): """Create a fake timing event. Parameters: channel -- timing channel to 'fake' t -- a tod object. If omitted, tod('now') is used Fake events are still subject to arming, but they are not sent to the attached Timy. While fake events are logged with a TIMER label, they will not appear on the Timy receipt unless printed explicitly. """ if t is None: t = tod.tod('now') self.cqueue.put_nowait(('TRIG', int(channel), t))
def menu_clock_timeout(self): """Update status buttons and time of day clock button.""" if not self.running: return False else: # check wheeltime connection nstat = self.rfu.connected() if nstat != self.rfustat: if nstat: self.menu_rfustat_img.set_from_stock(gtk.STOCK_CONNECT, gtk.ICON_SIZE_BUTTON) else: self.menu_rfustat_img.set_from_stock(gtk.STOCK_DISCONNECT, gtk.ICON_SIZE_BUTTON) self.rfustat = nstat self.clock_label.set_text(tod.tod("now").rawtime(places=0, zeros=True)) if self.curevent is not None: # call into race 'slow' self.curevent.slow_timeout() # timeout return True
def append_rider(self, msg): sr = msg.split(chr(unt4.US)) if len(sr) == 5: rftime = tod.str2tod(sr[4]) if rftime is not None: if len(self.riders) == 0: # Case 1: Starting a new lap self.cur_lap = (rftime-self.cur_split).truncate(0) self.cur_split = rftime.truncate(0) self.cur_bunchid = 0 self.cur_bunchcnt = 1 self.last_time = rftime nr=[sr[0],sr[1],sr[2],sr[3], self.cur_lap.rawtime(0), self.cur_bunchcnt, COLOURMAP[self.cur_bunchid][0], rftime] elif rftime < self.last_time or rftime - self.last_time < tod.tod('1.12'): # Case 2: Same bunch self.last_time = rftime self.cur_bunchcnt += 1 nr=[sr[0],sr[1],sr[2],sr[3], '', self.cur_bunchcnt, COLOURMAP[self.cur_bunchid][0], rftime] else: # Case 3: New bunch self.riders.append(['','','','','','','#fefefe',None]) self.cur_bunchid = (self.cur_bunchid + 1)%COLOURMAPLEN self.cur_bunchcnt = 1 self.last_time = rftime nr=[sr[0],sr[1],sr[2],sr[3], '+' + (rftime - self.cur_split).rawtime(0), self.cur_bunchcnt, COLOURMAP[self.cur_bunchid][0], rftime] else: # Informative non-timeline record nr=[sr[0],sr[1],sr[2],sr[3], '', '', '#fefefe',None] self.riders.append(nr) self.map_redraw() # update src map self.map_area.queue_draw() # queue copy to screen
def parse_impulse(self, msg): """Return tod object from timing msg or None.""" ret = None msg = msg.rstrip() if len(msg) > 2: # failsafe for [-2:] tsum slice tsum = timy_getsum(msg[-2:]) csum = timy_checksum(msg[0:len(msg) - 2]) if tsum == csum: e = msg.split() if len(e) == 4: ret = tod.tod(timeval=e[2], index=e[0], chan=e[1]) else: self.log.error('Invalid message: ' + repr(msg)) else: self.log.error('Corrupt message: ' + repr(msg)) self.log.error('Checksum failed: 0x%02X != 0x%02X', tsum, csum) else: self.log.warn('Short message: ' + repr(msg)) return ret
def menu_clock_timeout(self): """Update status buttons and time of day clock button.""" if not self.running: return False else: # check wheeltime connection nstat = self.rfu.connected() if nstat != self.rfustat: if nstat: self.menu_rfustat_img.set_from_stock( gtk.STOCK_CONNECT, gtk.ICON_SIZE_BUTTON) else: self.menu_rfustat_img.set_from_stock( gtk.STOCK_DISCONNECT, gtk.ICON_SIZE_BUTTON) self.rfustat = nstat self.clock_label.set_text( tod.tod('now').rawtime(places=0, zeros=True)) if self.curevent is not None: # call into race 'slow' self.curevent.slow_timeout() # timeout return True
def parse_impulse(self, msg): """Return tod object from timing msg or None.""" ret = None msg = msg.rstrip() if len(msg) > 2: # failsafe for [-2:] tsum slice tsum = timy_getsum(msg[-2:]) csum = timy_checksum(msg[0:len(msg) - 2]) if tsum == csum: e = msg.split() if len(e) == 4: ret = tod.tod(timeval = e[2], index = e[0], chan = e[1]) else: self.log.error('Invalid message: ' + repr(msg)) else: self.log.error('Corrupt message: ' + repr(msg)) self.log.error('Checksum failed: 0x%02X != 0x%02X', tsum, csum) else: self.log.warn('Short message: ' + repr(msg)) return ret
def timeout(self): """Respond to timing events.""" if not self.winopen: return False # Collect any queued timing impulses e = self.meet.timer.response() while e is not None: chan = e.chan[0:2] if chan == 'C0': self.start_trig(e) elif chan == 'C1': self.fin_trig(e) e = self.meet.timer.response() # Collect any RFID triggers e = self.meet.rfu.response() while e is not None: self.rfid_trig(e) e = self.meet.rfu.response() if self.timerstat == 'running': nowoft = (tod.tod('now') - self.lstart).truncate(0) # !!! Update stopwatch? or in fast timeout? return True
def do_places(self): """Show race result on scoreboard.""" self.placexfer(self.ctrl_places.get_text()) self.meet.scbwin = None self.timerwin = False ts = None tp = 'Time:' if self.start is not None and self.finish is None: self.finish = tod.tod('now') self.set_elapsed() if self.timetype == '200m': tp = '200m:' et = self.time_lbl.get_text() if et is not None and et != '': ts = et self.meet.scbwin = scbwin.scbtable(self.meet.scb, self.meet.racenamecat(self.event), SCB_RESULT_FMT, self.results[0:4], timepfx=tp, timestr=ts,pagesz=5) self.meet.scbwin.reset() # !! is this a bug? what if there are no places/time yet? self.setfinished()
def result_export(self, f): """Export result for use with other systems.""" cr = csv.writer(f) cr.writerow([ 'no', 'rider', 'email', 'laps', 'Split 1', 'Lap 1', 'Split 2', 'Lap 2', 'Split 3', 'Lap 3', 'Split 4', 'Lap 4' ]) # set the start time st = tod.tod(0) if self.start is not None: st = self.start # scan start list for r in self.riders: res = [ r[COL_BIB], r[COL_NAMESTR], r[COL_COMMENT], str(len(r[COL_RFSEEN])) ] # scan lap splits lt = st for split in r[COL_RFSEEN]: laptime = split - lt lapstr = laptime.rawtime(0) splitstr = split.rawtime(0) if laptime < self.minlap: self.log.warn('Suspect lap for rider ' + repr(r[COL_BIB]) + ':' + lapstr) res.append(splitstr) res.append(lapstr) lt = split # emit row cr.writerow(res)
def entry_set_now(self, button, entry=None): """Enter the 'now' time in the provided entry.""" entry.set_text(tod.tod('now').timestr()) entry.activate()