def __init__(self): """Constructor.""" threading.Thread.__init__(self, daemon=True) self.__queue = queue.Queue() self.__cb = defcallback self.__subscriptions = set() self.__curov = None self.__deftopic = None self.__connected = False self.__connect_pending = False self.__host = None self.__qos = 0 self.__doreconnect = True # if host set, try to connect on startup # check system config for overrides if metarace.sysconf.has_option('telegraph', 'host'): self.__host = metarace.sysconf.get('telegraph', 'host') if metarace.sysconf.has_option('telegraph', 'deftopic'): # note: this may be overidden by application self.__deftopic = metarace.sysconf.get('telegraph', 'deftopic') if metarace.sysconf.has_option('telegraph', 'qos'): self.__qos = strops.confopt_posint(metarace.sysconf.get( 'telegraph', 'qos'),0) if self.__qos > 2: LOG.info('Invalid QOS %r set to %r', self.__qos, 2) self.__qos = 2 # create mqtt client self.__client = mqtt.Client() if metarace.sysconf.has_option('telegraph', 'debug'): if strops.confopt_bool(metarace.sysconf.get('telegraph', 'debug')): LOG.debug('Enabling mqtt/paho debug') mqlog = logging.getLogger('metarace.telegraph.mqtt') mqlog.setLevel(logging.DEBUG) self.__client.enable_logger(mqlog) if metarace.sysconf.has_option('telegraph', 'usetls'): if strops.confopt_bool(metarace.sysconf.get('telegraph', 'usetls')): LOG.debug('Enabling TLS connection') self.__client.tls_set() username = None password = None if metarace.sysconf.has_option('telegraph', 'username'): username = metarace.sysconf.get('telegraph', 'username') if metarace.sysconf.has_option('telegraph', 'password'): password = metarace.sysconf.get('telegraph', 'password') if username and password: self.__client.username_pw_set(username, password) self.__client.reconnect_delay_set(2, 16) self.__client.on_message = self.__on_message self.__client.on_connect = self.__on_connect self.__client.on_disconnect = self.__on_disconnect self.__running = False
def loadconfig(self): """Load race config from disk.""" self.riders.clear() cr = ConfigParser.ConfigParser({ 'startlist': '', 'id': EVENT_ID, 'showinfo': 'No', 'events': '', 'autospec': '', 'evnicks': '' }) cr.add_section('event') cr.add_section('riders') # no need fr omnium?? if os.path.isfile(self.configpath): self.log.debug('Attempting to read config from ' + repr(self.configpath)) cr.read(self.configpath) #self.autospec = cr.get('event', 'autospec') for r in cr.get('event', 'startlist').split(): self.addrider(r) ## TODO : load/save comment for rider self.info_expand.set_expanded( strops.confopt_bool(cr.get('event', 'showinfo'))) self.events = strops.reformat_bibserlist(cr.get('event', 'events')) self.nicknames = cr.get('event', 'evnicks').split() self.recalculate() if not self.onestart: if self.autospec: self.meet.autostart_riders(self, self.autospec) # After load complete - check config and report. This ensures # an error message is left on top of status stack. This is not # always a hard fail and the user should be left to determine # an appropriate outcome. eid = cr.get('event', 'id') if eid and eid != EVENT_ID: self.log.error('Event configuration mismatch: ' + repr(eid) + ' != ' + repr(EVENT_ID))
def loadconfig(self): """Load config from disk.""" cr = jsonconfig.config({ u'track_announce': { u'remoteport': u'', u'remoteuser': u'', u'remotechan': u'#agora', u'fontsize': unicode(FONTSIZE), u'fullscreen': False, u'motd': MOTD } }) cr.add_section(u'track_announce') cwfilename = metarace.default_file(CONFIGFILE) # read in sysdefaults before checking for config file cr.merge(metarace.sysconf, u'track_announce') # check for config file try: with open(cwfilename, 'rb') as f: cr.read(f) except Exception as e: print(u'Reading app config: ' + repr(e)) self.motd = cr.get(u'track_announce', u'motd') self.fullscreen = strops.confopt_bool( cr.get(u'track_announce', u'fullscreen')) self.remoteport = cr.get(u'track_announce', u'remoteport') self.remotechan = cr.get(u'track_announce', u'remotechan') self.remoteuser = cr.get(u'track_announce', u'remoteuser') self.io.set_portstr(portstr=self.remoteport, channel=self.remotechan) if self.remoteuser: print(u'Enabled remote control by: ' + repr(self.remoteuser)) else: print(u'Promiscuous remote control enabled.')
def loadconfig(self): """Load config from disk.""" cr = jsonconfig.config({u'road_announce':{ u'remoteport':u'', u'remoteuser':u'', u'remotechan':u'#agora', u'autoscroll':False, u'timetick':12, u'fontsize':20, u'fullscreen':False, u'groupcol':True, u'catcol':True, u'bunchmap':True, u'search':False, u'maxlaptime':'2:00', u'motd':MOTD}}) cr.add_section(u'road_announce') cwfilename = metarace.default_file(CONFIGFILE) # read in sysdefaults before checking for config file cr.merge(metarace.sysconf, u'road_announce') # re-set log file if self.loghandler is not None: self.log.removeHandler(self.loghandler) self.loghandler.close() self.loghandler = None self.loghandler = logging.FileHandler( os.path.join(self.configpath, LOGFILE)) self.loghandler.setLevel(LOGHANDLER_LEVEL) self.loghandler.setFormatter(logging.Formatter( '%(asctime)s %(levelname)s:%(name)s: %(message)s')) self.log.addHandler(self.loghandler) # check for config file try: with open(cwfilename, 'rb') as f: cr.read(f) except Exception as e: self.log.error(u'Reading app config: ' + repr(e)) self.fontsize = strops.confopt_posint(cr.get(u'road_announce', u'fontsize'), FONTSIZE) fnszstr = str(self.fontsize)+'px' self.font = pango.FontDescription(FONTFACE + ' ' + fnszstr) self.motd = cr.get(u'road_announce', u'motd') if strops.confopt_bool(cr.get(u'road_announce', u'fullscreen')): self.window.fullscreen() self.remoteport = cr.get(u'road_announce', u'remoteport') self.remotechan = cr.get(u'road_announce', u'remotechan') self.remoteuser = cr.get(u'road_announce', u'remoteuser') self.io.set_portstr(portstr=self.remoteport, channel=self.remotechan) if self.remoteuser: self.log.info(u'Enabled remote control by: ' + repr(self.remoteuser)) else: self.log.info(u'Promiscuous remote control enabled.') self.lbl_header.modify_font(self.font) self.elap_lbl.modify_font(self.font) self.search_lbl.modify_font(self.font) self.search_entry.modify_font(self.font) self.view.modify_font(self.font) self.iview.modify_font(self.font) self.fin_rank.modify_font(self.font) self.fin_label.modify_font(self.font) self.fin_rider.modify_font(self.font) self.fin_time.modify_font(self.font) self.int_rank.modify_font(self.font) self.int_label.modify_font(self.font) self.int_rider.modify_font(self.font) self.int_time.modify_font(self.font)
def loadconfig(self): """Load race config from disk.""" self.contests.clear() deftimetype = '200m' defdistance = '200' defdistunits = 'metres' self.seedsrc = None # default is no seed info cr = jsonconfig.config({ u'event': { u'id': EVENT_ID, u'contests': ['Heat 1', 'Heat 2', 'Heat 3'], u'timerstat': None, u'showinfo': True, u'comment': [], u'autospec': u'' }, u'contests': {} }) cr.add_section(u'event') cr.add_section(u'contests') try: with open(self.configpath, 'rb') as f: cr.read(f) except Exception as e: self.log.error(u'Reading event config: ' + unicode(e)) # event metas self.info_expand.set_expanded( strops.confopt_bool(cr.get(u'event', u'showinfo'))) #self.autospec = cr.get(u'event', u'autospec') self.comment = cr.get(u'event', u'comment') self.onestart = False self.set_elapsed() #places = strops.reformat_placelist(cr.get(u'event',u'ctrl_places')) #self.ctrl_places.set_text(places) #self.placexfer(places) #if places: # self.doscbplaces = False # only show places on board if not set # self.setfinished() #else: if self.autospec: self.meet.autostart_riders(self, self.autospec, infocol=self.seedsrc) if self.evtype in ['handicap', 'keirin'] or self.inomnium: self.reorder_handicap() # restore contests oft = 0 curactive = -1 for c in cr.get(u'event', u'contests'): if cr.has_option(u'contests', c): res = cr.get(u'contests', c) ft = tod.str2tod(res[4]) if ft or res[5]: self.onestart = True # at least one run so far else: if curactive == -1: curactive = oft astr = '' if res[0]: astr = self.rider_name(res[0]) bstr = '' if res[2]: bstr = self.rider_name(res[2]) nr = [ c, res[0], astr, res[1], res[2], bstr, res[3], ft, res[5], res[6] ] self.add_contest(c, nr) else: self.add_contest(c) oft += 1 if not self.onestart and self.autospec: self.del_riders() self.meet.autostart_riders(self, self.autospec) self.current_contest_combo.set_active(curactive) eid = cr.get('event', 'id') if eid and eid != EVENT_ID: self.log.error('Event configuration mismatch: ' + repr(eid) + ' != ' + repr(EVENT_ID))
def loadconfig(self): """Load config from disk.""" cr = jsonconfig.config({u'irtt_start':{ u'uscbsrv':'', u'channel':USCBSRV_CHANNEL, u'fullscreen':False, u'timer':'', u'backlightlow':0.25, u'backlighthigh':1.0, u'backlightdev':None, u'syncthresh':DEFAUDIOSYNCTHRESH, u'startlist':u'startlist.csv'}}) cr.add_section(u'irtt_start') # check for config file cfile = metarace.default_file(CONFIGFILE) # read in sysdefaults before checking for config file cr.merge(metarace.sysconf, u'irtt_start') try: self.log.info(u'Reading config from: ' +repr(cfile)) with open(cfile, 'rb') as f: cr.read(f) except Exception as e: self.log.error(u'Reading config: ' + unicode(e)) if strops.confopt_bool(cr.get(u'irtt_start', u'fullscreen')): self.window.fullscreen() # set timer port tport = cr.get(u'irtt_start', u'timer') self.timer.setport(tport) self.timer.sane() self.timer.keylock() self.timer.setcb(self.starttrig) self.timer.armlock(True) # always re-armlock self.timer.arm(timy.CHAN_START) # load backlight parameters self.backlightdev = cr.get(u'irtt_start', u'backlightdev') self.backlightlow = strops.confopt_float(cr.get(u'irtt_start', u'backlightlow'),0.25) self.backlighthigh = strops.confopt_float(cr.get(u'irtt_start', u'backlighthigh'),1.0) if os.path.exists(self.backlightdev): try: with open(os.path.join(self.backlightdev,u'max_brightness'), 'rb') as bf: mbstr = bf.read() self.backlightmax = strops.confopt_posint(mbstr,20) self.backlightdev = os.path.join(self.backlightdev, u'brightness') self.log.info(u'Using backlight dev ' + repr(self.backlightdev) + u'; Max={0}, Low={1}%, High={2}%'.format( self.backlightmax, int(100.0*self.backlightlow), int(100.0*self.backlighthigh))) except Exception as e: self.log.error(u'Reading from backlight device: ' + repr(e)) self.backlightdev = None else: self.log.info(u'Backlight control not configured.') self.backlightdev = None # audio sync thresh self.syncthresh = strops.confopt_posint( cr.get(u'irtt_start', u'syncthresh'), DEFAUDIOSYNCTHRESH) self.log.info(u'Sync threshold set to: {0:0.3f}s'.format( float(self.syncthresh)*1e-9)) # set sender port nhost = cr.get(u'irtt_start', u'uscbsrv') nchannel = cr.get(u'irtt_start', u'channel') self.scb.set_portstr(nhost, nchannel) # load riders datafile = cr.get(u'irtt_start', u'startlist') try: rlist = [] with open(datafile,'rb') as f: cr = ucsv.UnicodeReader(f) for r in cr: key = None st = None bib = u'' series = u'' name = u'' next = None # load rider info # start, no, series, name, cat if len(r) > 0 and r[0] not in NOHDR: # time & no provided st = tod.str2tod(r[0]) if len(r) > 1: # got bib bib = r[1] if len(r) > 2: # got series series = r[2] if len(r) > 3: # got name name = u' '.join([r[1],r[3]]) if st is not None: # enough data to add a starter key = tod2key(st) nr = [st, bib, series, name, next] self.ridermap[key] = nr rlist.append(key) # sort startlist and build list linkages curoft = tod2key(tod.tod(u'now')) self.currider = None rlist.sort() prev = None for r in rlist: if prev is not None: self.ridermap[prev][4] = r # prev -> next prev = r if self.currider is None and r > curoft: self.currider = r rvec = self.ridermap[r] stxt = tod.tod(r).meridian() sno = rvec[1] sname = rvec[3] self.log.info(u'Setting first rider to: ' + u','.join([sno, sname]) + u' @ ' + stxt) # last link will be None except Exception as e: # always an error - there must be startlist to continue self.log.error(u'Error loading from startlist: ' + unicode(e))
def loadconfig(self): """Load config from disk.""" cr = jsonconfig.config({ u'road_announce': { u'remoteport': u'', u'remoteuser': u'', u'remotechan': u'#agora', u'autoscroll': False, u'timetick': 12, u'fontsize': 20, u'minelevrange': 300.0, u'fullscreen': False, u'groupcol': True, u'catcol': True, u'bunchmap': True, u'showtrack': False, u'search': False, u'maxlaptime': '2:00', u'motd': MOTD } }) cr.add_section(u'road_announce') cwfilename = metarace.default_file(CONFIGFILE) # read in sysdefaults before checking for config file cr.merge(metarace.sysconf, u'road_announce') # re-set log file if self.loghandler is not None: self.log.removeHandler(self.loghandler) self.loghandler.close() self.loghandler = None self.loghandler = logging.FileHandler( os.path.join(self.configpath, LOGFILE)) self.loghandler.setLevel(LOGHANDLER_LEVEL) self.loghandler.setFormatter( logging.Formatter( '%(asctime)s %(levelname)s:%(name)s: %(message)s')) self.log.addHandler(self.loghandler) # check for config file try: with open(cwfilename, 'rb') as f: cr.read(f) except Exception as e: self.log.error(u'Reading app config: ' + repr(e)) self.timetick = strops.confopt_posint( cr.get(u'road_announce', u'timetick'), TIMETICK) self.fontsize = strops.confopt_posint( cr.get(u'road_announce', u'fontsize'), FONTSIZE) maxlap = tod.str2tod(cr.get(u'road_announce', u'maxlaptime')) if maxlap is not None: self.maxlaptime = maxlap self.motd = cr.get(u'road_announce', u'motd') if strops.confopt_bool(cr.get(u'road_announce', u'fullscreen')): self.window.fullscreen() if strops.confopt_bool(cr.get(u'road_announce', u'search')): self.search_ent.show() self.search_ent.set_sensitive(True) self.showtrack = strops.confopt_bool( cr.get(u'road_announce', u'showtrack')) if self.showtrack: self.track_area.show() autoscroll = strops.confopt_bool( cr.get(u'road_announce', u'autoscroll')) if autoscroll != self.autoscroll: self.autoscroll = True self.scrollcnt = 0 glib.timeout_add(SCROLLDELAY, self.doautoscroll) self.remoteport = cr.get(u'road_announce', u'remoteport') self.remotechan = cr.get(u'road_announce', u'remotechan') self.remoteuser = cr.get(u'road_announce', u'remoteuser') self.io.set_portstr(portstr=self.remoteport, channel=self.remotechan) if self.remoteuser: self.log.info(u'Enabled remote control by: ' + repr(self.remoteuser)) else: self.log.info(u'Promiscuous remote control enabled.') if not strops.confopt_bool(cr.get(u'road_announce', 'groupcol')): self.view.get_column(5).set_visible(False) if not strops.confopt_bool(cr.get(u'road_announce', 'catcol')): self.view.get_column(3).set_visible(False) if not strops.confopt_bool(cr.get(u'road_announce', 'bunchmap')): self.map_area.hide() fnszstr = str(self.fontsize) + 'px' self.lbl_header.modify_font( pango.FontDescription(FONTFACE + ' ' + fnszstr)) self.elap_lbl.modify_font( pango.FontDescription(FONTFACE + ' ' + fnszstr)) self.gap_lbl.modify_font( pango.FontDescription(FONTFACE + ' ' + fnszstr)) self.search_entry.modify_font( pango.FontDescription(FONTFACE + ' ' + fnszstr)) self.lbl_resultmsg.modify_font( pango.FontDescription(FONTFACE + ' ' + fnszstr)) self.view.modify_font(pango.FontDescription(FONTFACE + ' ' + fnszstr)) zrangemin = strops.confopt_float( cr.get(u'road_announce', u'minelevrange'), 200.0) routefile = metarace.default_file(u'route.dat') self.profile = None self.zmin = None self.zmax = None self.dmax = None if os.path.exists(routefile): print(u'loading profile...') self.profile = [] with open(routefile, 'rb') as f: dmax = 0.0 xmin = -1.0 xmax = 1.0 ymin = -1.0 ymax = 1.0 zmin = 90000.0 zmax = -100.0 for l in f: r = l.split() t = strops.confopt_float(r[1]) x = strops.confopt_float(r[2]) y = strops.confopt_float(r[3]) z = strops.confopt_float(r[4]) d = strops.confopt_float(r[6]) if z < zmin: zmin = z if z > zmax: zmax = z if x < xmin: xmin = x if x > xmax: xmax = x if y < ymin: ymin = y if y > ymax: ymax = y if d > dmax: dmax = d self.profile.append([t, z, d, x, y]) self.zmin = zmin self.zmax = zmax self.xmin = xmin self.xmax = xmax self.ymin = ymin self.ymax = ymax self.dmax = dmax erange = zmax - zmin # profile min elevation range if erange < zrangemin: self.zmin -= 0.5 * (zrangemin - erange) self.zmax = self.zmin + zrangemin #print(repr([zmin,zmax,dmax])) routemeta = metarace.default_file(u'route.json') rjdat = jsonconfig.config() if os.path.exists(routemeta): with open(routemeta, 'rb') as g: rjdat.read(g) bbmin = rjdat.get(u'route', u'mapmin') bbmax = rjdat.get(u'route', u'mapmax') self.track_bbox = [[bbmin[u'x'], bbmin[u'y']], [bbmax[u'x'], bbmax[u'y']]]