Exemple #1
0
    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
Exemple #2
0
    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))
Exemple #3
0
    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.')
Exemple #4
0
    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)
Exemple #5
0
    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))
Exemple #6
0
    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))
Exemple #7
0
    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']]]