def __init__(self): self.finish_labels = [] self.finish_initialised = False self.replay_initialised = False self.replay_asc = False self.replay_rgb=255 self.session=Value() self.cursor=Value() self.cursor.setValue(False) self.session_draw=Value() self.session_draw.setValue(-1) self.ui_row_height = Value(-1) self.numberOfLaps=0 self.rowHeight=36 self.window = Window(name="ACTV Timer", icon=False, width=228, height=42, texture="") self.lbl_session_info=Label(self.window.app,"Loading").setSize(154, self.rowHeight).setPos(self.rowHeight, 0).setFontSize(26).setAlign("center").setBgColor(rgb([55, 55, 55], bg = True)).setBgOpacity(0.64) self.lbl_session_title=Label(self.window.app,"P").setSize(self.rowHeight, self.rowHeight).setPos(0, 0).setFontSize(26).setAlign("center").setBgColor(Colors.red(bg = True)).setBgOpacity(0.64) self.lbl_session_single=Label(self.window.app,"Loading").setSize(190, self.rowHeight).setPos(0, 0).setFontSize(26).setAlign("center").setBgColor(rgb([55, 55, 55], bg = True)).setBgOpacity(0.64).setColor(Colors.white()).setVisible(0) self.lbl_session_border=Label(self.window.app,"").setSize(154+self.rowHeight, 1).setPos(0, self.rowHeight+1).setBgColor(Colors.red(bg = True)).setBgOpacity(0.7).setVisible(1) trackFilePath = "content/tracks/"+ ac.getTrackName(0) + "/ui/" if ac.getTrackConfiguration(0) != "": trackFilePath += ac.getTrackConfiguration(0) + "/ui_track.json" else: trackFilePath += "ui_track.json" if os.path.exists(trackFilePath): with open(trackFilePath) as data_file: data = json.load(data_file) self.trackName = data["name"] if len(self.trackName) > 12: if self.trackName[12] == " " or self.trackName[12] == "-": self.trackName = self.trackName[:12] else: self.trackName = self.trackName[:12] #cut multiword space = self.trackName.rfind(" ") dash = self.trackName.rfind("-") if space > 0: self.trackName = self.trackName[:space] elif dash > 0: self.trackName = self.trackName[:dash] else: self.trackName = ac.getTrackName(0) if len(self.trackName) > 12: self.trackName = self.trackName[:12] self.loadCFG()
def acMain(ac_version): global DRIVER, TRACK, CAR, WINDOW, LAP_LABELS, LAP_VALID_INDICATOR DRIVER = ac.getDriverName(DRIVER_ID_SELF) TRACK = '%s-%s' % (ac.getTrackName(DRIVER_ID_SELF), ac.getTrackConfiguration(DRIVER_ID_SELF)) CAR = ac.getCarName(DRIVER_ID_SELF) ac.console('Initialize %s: driver %s on %s in %s' % (NAME, DRIVER, TRACK, CAR)) WINDOW = ac.newApp(NAME) ac.setSize(WINDOW, *SIZE) ac.setTitle(NAME) if ac.addOnAppActivatedListener(WINDOW, onActivate) == -1: ac.console('Failed to add listener activate') if ac.addOnAppDismissedListener(WINDOW, onDeactivate) == -1: ac.console('Failed to add listener deactivate') i = 0 while i < LAP_COUNT: label = ac.addLabel(WINDOW, 'Waiting for lap time...') LAP_LABELS.append(label) i += 1 LAP_VALID_INDICATOR = ac.addLabel(WINDOW, 'Clean') refreshLapDisplay() return NAME
def load(self, main_file, file_name): try: self.track_name = ac.getTrackName(0) self.layout = ac.getTrackConfiguration(0) self.file_name = self.track_name + "_" + self.layout + "-" + file_name self.path = os.path.abspath(main_file).replace("\\",'/').replace( os.path.basename(main_file),'')+"data/"+self.file_name+".json" with open(self.path) as data_file: self.data = json.load(data_file) self.mode = {"pos": [self.Camera_Data()], "time": [self.Camera_Data()]} #self.mode = {} #modes for self.key0, self.val0 in self.data.items(): if self.key0 != "pit_spline" and self.key0 != "track_spline": self.mode[self.key0] = [] #cameras for self.i in range(len(self.data[self.key0])): self.mode[self.key0].append(self.Camera_Data()) #cameras attributes for self.key1, self.val1 in self.data[self.key0][self.i].items(): if self.key1 != "keyframes": self.mode[self.key0][self.i].set_attr(self.key1, self.val1) else: #keyframes self.mode[self.key0][self.i].keyframes = [] for self.j in range(len(self.data[self.key0][self.i]["keyframes"])): self.mode[self.key0][self.i].add_keyframe() #keyframes value for self.key2, self.val2 in self.data[self.key0][self.i]["keyframes"][self.j].items(): if self.key2 != "interpolation": self.mode[self.key0][self.i].keyframes[self.j].set_attr(self.key2, self.val2) else: #interpolation for self.key3, self.val3 in self.data[self.key0][self.i]["keyframes"][self.j]["interpolation"].items(): self.mode[self.key0][self.i].keyframes[self.j].interpolation[self.key3] = self.val3 self.pit_spline = {"the_x":[], "loc_x":[], "loc_y":[], "loc_z":[], "rot_x":[], "rot_y":[], "rot_z":[]} self.track_spline = {"the_x":[], "loc_x":[], "loc_y":[], "loc_z":[], "rot_x":[], "rot_y":[], "rot_z":[]} for self.key, self.val in self.data["pit_spline"].items(): for self.i in range(len(self.val)): self.pit_spline[self.key].append(self.val[self.i]) for self.key, self.val in self.data["track_spline"].items(): for self.i in range(len(self.val)): self.track_spline[self.key].append(self.val[self.i]) return True except Exception as e: debug(e) return False
def loadDRSZones(): zones = [] try: track_name = ac.getTrackName(0) track_config = ac.getTrackConfiguration(0) if track_config is not None: drsIni = "content\\tracks\\%s\\%s\\%s" % (track_name, track_config, "data\\drs_zones.ini") else: drsIni = "content\\tracks\\%s\\%s" % (track_name, "data\\drs_zones.ini") drsExists = os.path.isfile(drsIni) if drsExists: config = configparser.ConfigParser() config.read(drsIni) for zone in config.sections(): zone_info = { "detection": float(config[zone]['DETECTION']), "start": float(config[zone]['START']), "end": float(config[zone]['END']) } zones.append(zone_info) else: ac.console(APP_NAME + ": could not find drs_zones.ini file") return False except Exception as e: ac.console(APP_NAME + ": Error in loadDrsZones: %s" % e) return zones
def acMain(ac_version): """Main function that is invoked by Assetto Corsa.""" global NOTIFICATION, LAPTIME_LABELS app = ac.newApp("AC-Ranking") ac.setSize(app, 400, 300) NOTIFICATION = ac.addLabel(app, '') ac.setPosition(NOTIFICATION, 15, 20) ac.setSize(NOTIFICATION, 190, 20) auth = read_auth() validate_token(auth['user'], auth['token']) validate_token_button = ac.addButton(app, 'Validate token') ac.setPosition(validate_token_button, 20, 40) ac.setSize(validate_token_button, 120, 20) ac.addOnClickedListener(validate_token_button, validate_token_button_func) refresh_button = ac.addButton(app, '\u21BB') ac.setPosition(refresh_button, 300, 5) ac.setSize(refresh_button, 15, 18) ac.addOnClickedListener(refresh_button, refresh_button_func) LAPTIME_LABELS = tuple(ac.addLabel(app, '#' + str(i)) for i in range(10)) for index, label in enumerate(LAPTIME_LABELS): ac.setSize(label, 120, 20) ac.setPosition(label, 200, (index * 20) + 50) get_laptimes(ac.getCarName(0), ac.getTrackName(0), ac.getTrackConfiguration(0) or None) return "ACR"
def marshall(self): """Simple comma seperated transmission, client will need to be aware of positions of various data items Add any new data items to the end so existing apps are not affected """ try: data = ["x02"] #start token data.extend(ac.getCarState(0, acsys.CS.CurrentTyresCoreTemp)) #0-3 - Core tyre temperatures, Degrees celcius data.extend(info.physics.tyreWear) #4-7 #tyre wear data.extend(ac.getCarState(0, acsys.CS.DynamicPressure)) #8-11 pressure of each tyre in PSI data.extend(ac.getCarState(0, acsys.CS.TyreDirtyLevel)) #12-15 amount of dirt on each tyre data.append(ac.getCarState(0, acsys.CS.SpeedMS)) #16 speed in metres/sec data.append(ac.getCarState(0, acsys.CS.Gear)) #17 gear number data.append(ac.getCarState(0, acsys.CS.BestLap)) #18 best lap time in ms data.append(ac.getCarState(0, acsys.CS.RPM)) #19 rpm data.append(ac.getCarState(0, acsys.CS.LapCount)) #20 lap count data.append(ac.getCarState(0, acsys.CS.LapInvalidated)) #21 is lap invalid? 0-no, 1-yes data.append(ac.getCarState(0, acsys.CS.LapTime)) #22 current lap time in ms data.append(ac.getCarState(0, acsys.CS.LastLap)) #23 last lap in ms data.append(ac.getCarState(0, acsys.CS.PerformanceMeter)) #24 delta time in ms from best lap?? (haven't checked) data.append(ac.getCarState(0, acsys.CS.Steer)) #25 steering rotation in radians data.append(ac.getCarName(0)) #26 name of car being driven by player data.append(ac.getTrackName(0)) #27 track name data.append("x04") #end token except Exception as e: ac.console("{}".format(e)) return ",".join(str(v) for v in data).encode()
def onRender(*args): global prev_p, k, f_loc, started, passed_half, finished, n track_name = ac.getTrackName(0) basename = "%s_%i.csv"%(track_name, n) f_loc = os.path.join(os.path.dirname(os.path.realpath(__file__)), basename) if (k == 20): x,y,z = ac.getCarState(ac.getCarsCount() - 1,acsys.CS.WorldPosition) p = ac.getCarState(ac.getCarsCount() - 1,acsys.CS.NormalizedSplinePosition) if not started: if prev_p > 0.5 and p < 0.5: started = True prev_p = p else: if prev_p > 0.5 and p < 0.5: n += 1 prev_p = p return prev_p = p uiElements.update(x,y,z) f = open(f_loc, "a") f.write("{0:.5f}, {1:.5f}, {2:.5f}, {3: .5f}\n".format(x,y,z,p)) f.close() k=0 k +=1
def setup_replay_file(drivers, nLaps): filename = "replay_%s_%s.txt" % (ac.getCarName(0), ac.getTrackName(0)) replay_file = open(FC.REPLAY_DIR + filename, "w") data = "START %d %d " % (len(drivers), nLaps) for d in drivers: data += "%d;%s " % (d.starting_position, d.tyre) replay_file.write(data+'\n') return replay_file
def acMain(ac_version): try: global multiLapsApp, configApp, config global showHeader, fontSize, opacity, showBorder global lapDisplayedCount, showDelta, deltaColor, redAt, greenAt global reference, showCurrent, showReference, showTotal global updateTime, logLaps, logBest, lockBest global trackName, trackConf, carName, bestLapFile global nurbTourist if ac_version < 1.0: return "MultiLaps" config = configparser.ConfigParser() config.read("apps/python/MultiLaps/MultiLaps_config/config.ini") showHeader = config.getint("SETTINGS", "showHeader") fontSize = config.getint("SETTINGS", "fontSize") opacity = config.getint("SETTINGS", "opacity") showBorder = config.getint("SETTINGS", "showBorder") lapDisplayedCount = config.getint("SETTINGS", "lapDisplayedCount") showDelta = config.getint("SETTINGS", "showDelta") deltaColor = config.get("SETTINGS", "deltaColor") redAt = config.getint("SETTINGS", "redAt") greenAt = config.getint("SETTINGS", "greenAt") reference = config.get("SETTINGS", "reference") showCurrent = config.getint("SETTINGS", "showCurrent") showTotal = config.getint("SETTINGS", "showTotal") showReference = config.getint("SETTINGS", "showReference") updateTime = config.getint("SETTINGS", "updateTime") logLaps = config.getint("SETTINGS", "logLaps") logBest = config.get("SETTINGS", "logBest") lockBest = config.getint("SETTINGS", "lockBest") trackName = ac.getTrackName(0) trackConf = ac.getTrackConfiguration(0) carName = ac.getCarName(0) if trackConf == "": bestLapFile = "apps/python/MultiLaps/MultiLaps_bestlap/{0} - {1}.ini".format( trackName, carName) else: bestLapFile = "apps/python/MultiLaps/MultiLaps_bestlap/{0} [{1}] - {2}.ini".format( trackName, trackConf, carName) if trackName == "ks_nordschleife" and trackConf == "touristenfahrten": nurbTourist = True multiLapsApp = MultiLaps("MultiLaps", "Laps") multiLapsApp.refreshParameters() ac.addRenderCallback(multiLapsApp.window, onRenderCallback) configApp = MultiLaps_config("MultiLaps_config", "MultiLaps config", fontSizeConfig, 0) configApp.updateView() return "MultiLaps" except Exception as e: ac.log("MultiLaps: Error in acMain: %s" % e)
def remove_file(self, main_file, file_name): try: self.track_name = ac.getTrackName(0) self.layout = ac.getTrackConfiguration(0) self.file_name = self.track_name + "_" + self.layout + "-" + file_name self.path = os.path.abspath(main_file).replace("\\",'/').replace( os.path.basename(main_file),'')+"data/"+self.file_name+".json" os.remove(self.path) except Exception as e: debug(e)
def get_delta_file_path(self): track_file_path = Config.get_user_documents_path( ) + "plugins/actv_deltas/default" if not os.path.exists(track_file_path): os.makedirs(track_file_path) track_file_path += "/" + ac.getTrackName(0) if ac.getTrackConfiguration(0) != "": track_file_path += "_" + ac.getTrackConfiguration(0) track_file_path += "_" + ac.getCarName(0) + ".delta" return track_file_path
def onStartup(self, ac_version): self.steam_id = steamID() self.ac_version = ac_version driver = ac.getDriverName(0) car = ac.getCarName(0) track = ac.getTrackName(0) track_config = ac.getTrackConfiguration(0) self.session = Session(ac_version, driver, car, track, track_config) self.latestPos = getCoords() self.latestUpdate = datetime.datetime.now()
def get_delta_file_path(self): track_file_path = os.path.join(os.path.expanduser("~"), "Documents", "Assetto Corsa", "plugins", "actv_deltas", "default") if not os.path.exists(track_file_path): os.makedirs(track_file_path) track_file_path += "/" + ac.getTrackName(0) if ac.getTrackConfiguration(0) != "": track_file_path += "_" + ac.getTrackConfiguration(0) track_file_path += "_" + ac.getCarName(0) + ".delta" return track_file_path
def getDeltaFilePath(self): trackFilePath = os.path.join( os.path.expanduser("~"), "Documents", "Assetto Corsa", "plugins", "actv_deltas", "default" ) if not os.path.exists(trackFilePath): os.makedirs(trackFilePath) trackFilePath += "/" + ac.getTrackName(0) if ac.getTrackConfiguration(0) != "": trackFilePath += "_" + ac.getTrackConfiguration(0) trackFilePath += "_" + ac.getCarName(0) + ".delta" return trackFilePath
def UpdateScores(): global server_connection_ok, client_version params = "?track=" + ac.getTrackName(0) + "-" + ac.getTrackConfiguration( 0) + "&mode=drift&client_version=" + str(client_version) scorejson = GetScoresFromServer(params) scores = '' for (key) in scorejson: scores += key + ':' + scorejson[key]['score'] + '\n' ac.setText(scorelabel, scores) server_connection_ok = 1 #ac.console("update scores"); return
def onActivate(*args): global logPrefix, multisplitapp ac.console(logPrefix + "onActivate()") try: trackName = ac.getTrackName(0) trackConfig = ac.getTrackConfiguration(0) multisplitapp = Multisplit(trackName, trackConfig) #ac.setText(label1, multisplitapp.getInfoText()) except: printExceptionInfo("onActivate")
def startTelemetry(): global logPrefix, telemetrySession telemetrySession = TelemetrySession() trackName = ac.getTrackName(0) trackConfig = ac.getTrackConfiguration(0) trackLength = ac.getTrackLength(0) carName = ac.getCarName(0) telemetrySession.start(carName=carName, trackName=trackName, trackConfig=trackConfig, trackLength=trackLength)
def prepare(self): self.track = ac.getTrackName(0) #now we'll build the slots, so we later know every single (possible) car carIds = range(0, ac.getCarsCount(), 1) for carId in carIds: #first we'll check wether there is a car for this id; as soon it returns -1 #it's over carModel = str(ac.getCarName(carId)) if carModel == '-1': break else: maxSlotId = carId driverName = ac.getDriverName(carId) self.cars.append(helipicapewcar.HeliPicaPewCar(carId, driverName, carModel))
def load_replay_file(drivers): '''Load replay data into a dictionary that follows the following structure {'LAP_NUMBER': [[TIME [UPDATE DATA]], [TIME [UPDATE DATA]], ... ] 'FL' : {'LAP_NUMBER' : [[TIME, DRIVER_ID, FASTEST_LAP], [TIME, DRIVER_ID, FASTEST_LAP]...] } } ''' try: filename = "replay_%s_%s.txt" % (ac.getCarName(0), ac.getTrackName(0)) with open(FC.REPLAY_DIR + filename, "r") as rf: data = {} line = next(rf).split() if line[0] != "START": ac.log("Replay file doesnt start with 'START' tag.") return totalDrivers = int(line[1]) data['totalDrivers'] = totalDrivers data['nLaps'] = int(line[2]) for i in range(3, 3+totalDrivers): line[i] = line[i].split(';') drivers[i-3].starting_position = int(line[i][0]) drivers[i-3].tyre = line[i][1] for line in rf: line = line.split() if line[0] == "U": # normal update update = [float(line[2])] for i in range(3, 3+totalDrivers): line[i] = line[i].split(';') update.append([int(line[i][0]), float(line[i][1]), line[i][2], int(line[i][3]), bool(int(line[i][4])), int(line[i][5])]) if int(line[1]) not in data: data[int(line[1])] = [] data[int(line[1])].append(update) elif line[0] == "FL": laps, time = line[1].split(';') id, fastest_lap = line[2].split(';') if 'FL' not in data: data['FL'] = {} if int(laps) not in data['FL']: data['FL'][int(laps)] = [] data['FL'][int(laps)].append([float(time), int(id), float(fastest_lap)]) else: ac.log("Replay file has wrong tag '%s'." % line[0]) return return data except FileNotFoundError: ac.log("Replay File not found.")
def startLogging(self): if self.outputFile != None: return ac.console('Start') tmpFile = open('D:\logger_' + datetime.now().strftime('%Y%m%d_%H%M') + '.log', mode = 'w') tmpFile.write('Course : {}\n'.format(ac.getTrackName(self.carId))) tmpFile.write('Layout : {}\n'.format(ac.getTrackConfiguration(self.carId))) tmpFile.write('Car Id : {}\n'.format(self.carId)) tmpFile.write('Driver : {}\n'.format(ac.getDriverName(self.carId))) tmpFile.write('Driver : {}\n'.format(ac.getCarName(self.carId))) tmpFile.write('\n') tmpFile.write('\t'.join(['lapCount', 'lapTime', 'distance', 'speed', 'throttle', \ 'brake', 'gear', 'RPM', 'steer', 'x', 'y', 'z\n'])) self.outputFile = tmpFile
def SendCurrentScore(): global highscore, storeDriftScore if highscore < storeDriftScore: highscore = storeDriftScore data = { "name": ac.getDriverName(0), "track": ac.getTrackName(0) + "-" + ac.getTrackConfiguration(0), "mode": "drift", "score": str(storeDriftScore), "car": ac.getCarName(0) } t = threading.Thread(target=SendScore, args=(data, )) #t.daemon = True t.start() resetDriftScoring() #ac.console("current score sent: "+str(storeDriftScore)) return
def SendLapScore(): global lastLapCumulativeScore, cumulativescore, driftScoreAtStartLine currentDrift = round(ac.getCarState(0, acsys.CS.InstantDrift)) lapscore = cumulativescore - lastLapCumulativeScore + currentDrift - driftScoreAtStartLine # + currentDrift - driftScoreAtStartLine driftScoreAtStartLine = currentDrift lastLapCumulativeScore = cumulativescore data = { "name": ac.getDriverName(0), "track": ac.getTrackName(0) + "-" + ac.getTrackConfiguration(0), "mode": "OneLapDrifting", "car": ac.getCarName(0), "score": str(lapscore), "laptime": str(ac.getCarState(0, acsys.CS.LastLap)) } t = threading.Thread(target=SendScore, args=(data, )) t.start() #SendScore(data); return
def SendSessionData(): #send cumulatice score global cumulativescore, server_connection_ok, sessionDataSent if sessionDataSent > 0: return sessionDataSent = sessionDataSent + 1 if server_connection_ok == 0: return session = info.graphics.session session_string = "other" laps = ac.getCarState(0, acsys.CS.LapCount) if laps < 1: laps = 1 if session == 0: session_string = "practise" if session == 1: session_string = "qualify" if session == 2: session_string = "race" data = { "name": ac.getDriverName(0), "track": ac.getTrackName(0) + "-" + ac.getTrackConfiguration(0), "mode": session_string, "car": ac.getCarName(0), "score": str(cumulativescore), "laps": str(laps), "bestlap": str(info.graphics.iBestTime), "average_score_per_lap": str(cumulativescore / laps), "score_per_km": str(cumulativescore / (info.graphics.distanceTraveled / 1000)) } SendScore(data) return
def acMain(ac_version): global appWindow, trackname, tracklength, l_lapcount, l_distance, l_fuel, conn, c appWindow = ac.newApp("acOdometer") ac.setSize(appWindow, 142, 142) l_lapcount = ac.addLabel(appWindow, "Laps: Outlap") ac.setPosition(l_lapcount, 3, 30) l_distance = ac.addLabel(appWindow, "Kilometers: Outlap") ac.setPosition(l_distance, 3, 45) l_fuel = ac.addLabel(appWindow, "Fuel used: 0") ac.setPosition(l_fuel, 3, 60) trackname = ac.getTrackName(0) carname = ac.getCarName(0) t = int(time.time()) c.execute("INSERT INTO session('date', 'track', 'car') values (?, ?, ?)", (t, trackname, carname)) # Commited atomically at end of session ac.log("*************************** NEW SESSION\n********* " + trackname) ac.log("acOdometer loaded, racing {} which has {:.3f} miles per lap".format(trackname, tracklength[trackname])) ac.console("acOdometer loaded, racing {} which has {:.3f} kilometers per lap.".format(trackname, tracklength[trackname])) return "acOdometer"
def save_delta(self): reference_lap = list(self.referenceLap) reference_lap_time = self.referenceLapTime.value if len(reference_lap) > 0: try: times = [] for l in reference_lap: times.append((l.sector, l.time)) data_file = { 'lap': reference_lap_time, 'times': times, 'track': ac.getTrackName(0), 'config': ac.getTrackConfiguration(0), 'car': ac.getCarName(0), 'user': ac.getDriverName(0) } file = self.get_delta_file_path() with gzip.open(file, 'wt') as outfile: json.dump(data_file, outfile) except: Log.w("Error tower")
def acMain(ac_version): global session # Create session object session = Session(ac, acsys) session.app_size_x = app_size_x session.app_size_y = app_size_y session.freq = FREQ session.trackname = ac.getTrackName(0) session.carname = ac.getCarName(0) # Initialise UI: ui = UI(session) session.ui = ui # Load best lap time if it exists for current track and car session.load_best_lap() # Create first lap session.new_lap(ac.getCarState(0, acsys.CS.LapCount)) return "Racing Line"
def saveDelta(self): # ac.log(str(time.time())+" saveDelta start:") referenceLap = list(self.referenceLap) # referenceLap=self.referenceLap referenceLapTime = self.referenceLapTime.value if len(referenceLap) > 0: try: times = [] for l in referenceLap: times.append((l.sector, l.time)) data_file = { "lap": referenceLapTime, "times": times, "track": ac.getTrackName(0), "config": ac.getTrackConfiguration(0), "car": ac.getCarName(0), "user": ac.getDriverName(0), } file = self.getDeltaFilePath() with gzip.open(file, "wt") as outfile: json.dump(data_file, outfile) except: Log.w("Error tower")
def __save(self, main_file, name): try: self.file_name = name self.file_name = self.file_name.replace("-", "_") self.file_name = self.file_name.replace(".", "_") self.track_name = ac.getTrackName(0) self.layout = ac.getTrackConfiguration(0) self.file_name = self.track_name + "_" + self.layout + "-" + self.file_name self.path = os.path.abspath(main_file).replace("\\",'/').replace( os.path.basename(main_file),'')+"data/"+self.file_name+".json" self.data = {} #modes self.data["pit_spline"] = self.pit_spline self.data["track_spline"] = self.track_spline for self.key0, self.val0 in self.mode.items(): self.data[self.key0] = {} self.data[self.key0] = [] #cameras for self.i in range(len(self.mode[self.key0])): self.data[self.key0].append({}) #cameras attributes for self.key1, self.val1 in vars(self.mode[self.key0][self.i]).items(): if self.key1 != "keyframes": self.data[self.key0][self.i][self.key1] = self.val1 # if self.key1 == "spline": # self.data[self.key0][self.i]["spline"] = {} # for self.key2, self.val2 in self.mode[self.key0][self.i].spline.items(): # for self.k in range(len(self.mode[self.key0][self.i].spline["the_x"])): # self.data[self.key0][self.i]["spline"][self.key2] = self.val2[self.k] if self.key1 == "keyframes": #keyframes self.data[self.key0][self.i]["keyframes"] = [] for self.j in range(len(self.mode[self.key0][self.i].keyframes)): self.data[self.key0][self.i]["keyframes"].append({}) #keyframes attributes for self.key2, self.val2 in vars(self.mode[self.key0][self.i].keyframes[self.j]).items(): if self.key2 != "interpolation": if self.val2 != None: self.data[self.key0][self.i]["keyframes"][self.j][self.key2] = self.val2 else: #interpolation values: self.data[self.key0][self.i]["keyframes"][self.j]["interpolation"] = {} for self.key3, self.val3 in self.mode[self.key0][self.i].keyframes[self.j].interpolation.items(): if self.val3 != None: self.data[self.key0][self.i]["keyframes"][self.j]["interpolation"][self.key3] = self.val3 with open(self.path,"w") as output_file: json.dump(self.data, output_file, indent=2) return True except Exception as e: debug(e) return False
def load_track_name(): """Loads name of track""" global track_name track_name = ac.getTrackName(0)
def acMain(ac_version): global DRS_ALLOWED_CARS, SOUND_ON, SERVERS global tyreLabels, tyrePressureLabels global drsLabel, ersLabel, ersModeLabel, ersRecoveryLabel, fuelLabel, drsPenaltyLabel, drsPenaltyBackgroundLabel global drsZones, totalDrivers, trackLength, drsAvailableZones, driversList global carValue, trackConfigValue, trackValue global compounds, modCompounds carValue = ac.getCarName(0) trackValue = ac.getTrackName(0) trackConfigValue = ac.getTrackConfiguration(0) settings = configparser.ConfigParser() settings.read("apps/python/%s/config.ini" % APP_NAME) if settings.has_section('CARS'): DRS_ALLOWED_CARS.extend( [c for c in settings['CARS'] if settings['CARS'][c] == '1']) if settings.has_section('SETTINGS'): SOUND_ON = True if 'sound' in settings['SETTINGS'] and settings[ 'SETTINGS']['sound'] == '1' else False if settings.has_section('SERVERS'): SERVERS = list(settings['SERVERS'].values()) drsZones = loadDRSZones() totalDrivers = ac.getCarsCount() trackLength = getTrackLength() driversList = [Driver(i, len(drsZones)) for i in range(totalDrivers)] drsAvailableZones = [False] * len(drsZones) compounds = configparser.ConfigParser() compounds.read(COMPOUNDSPATH + "compounds.ini") modCompounds = configparser.ConfigParser() modCompounds.read(COMPOUNDSPATH + carValue + ".ini") ac.initFont(0, FONT_NAME, 0, 0) appWindow = ac.newApp(APP_NAME) ac.setTitle(appWindow, "") ac.drawBorder(appWindow, 0) ac.setIconPosition(appWindow, 0, -10000) ac.setSize(appWindow, 280, 70) ac.setBackgroundOpacity(appWindow, 0.2) # ================================================================================================================= # TYRE LABELS # ================================================================================================================= tyreLabelFL = ac.addLabel(appWindow, "") tyreLabelFR = ac.addLabel(appWindow, "") tyreLabelRL = ac.addLabel(appWindow, "") tyreLabelRR = ac.addLabel(appWindow, "") tyreLabels = [tyreLabelFL, tyreLabelFR, tyreLabelRL, tyreLabelRR] for label in tyreLabels: ac.setFontSize(label, 15) ac.setFontColor(label, 0, 0, 0, 1) ac.setFontAlignment(label, "center") ac.setSize(label, 15, 23) tyrePressureLabelFL = ac.addLabel(appWindow, "PFL") tyrePressureLabelFR = ac.addLabel(appWindow, "PFR") tyrePressureLabelRL = ac.addLabel(appWindow, "PRL") tyrePressureLabelRR = ac.addLabel(appWindow, "PRR") tyrePressureLabels = [ tyrePressureLabelFL, tyrePressureLabelFR, tyrePressureLabelRL, tyrePressureLabelRR ] for label in tyrePressureLabels: ac.setFontSize(label, 15) ac.setFontColor(label, 0.86, 0.86, 0.86, 1) ac.setCustomFont(label, FONT_NAME, 0, 0) ac.setFontAlignment(tyrePressureLabels[0], "right") ac.setFontAlignment(tyrePressureLabels[1], "left") ac.setFontAlignment(tyrePressureLabels[2], "right") ac.setFontAlignment(tyrePressureLabels[3], "left") #position all the labels tlpx = 180 tlpy = 10 ac.setPosition(tyreLabels[0], tlpx + 5, tlpy + 0) ac.setPosition(tyreLabels[1], tlpx + 25, tlpy + 0) ac.setPosition(tyreLabels[2], tlpx + 5, tlpy + 28) ac.setPosition(tyreLabels[3], tlpx + 25, tlpy + 28) ac.setPosition(tyrePressureLabels[0], tlpx, tlpy + 2) ac.setPosition(tyrePressureLabels[1], tlpx + 43, tlpy + 2) ac.setPosition(tyrePressureLabels[2], tlpx, tlpy + 30) ac.setPosition(tyrePressureLabels[3], tlpx + 43, tlpy + 30) # ================================================================================================================= # ERS MODES LABELS # ================================================================================================================= elpx = 15 elpy = 10 ersModeLabel = ac.addLabel(appWindow, "🗲0") ac.setPosition(ersModeLabel, elpx + 50, elpy) ac.setFontSize(ersModeLabel, 18) ac.setCustomFont(ersModeLabel, FONT_NAME, 0, 0) ac.setFontColor(ersModeLabel, 1.0, 1.0, 0.2, 1) ac.setFontAlignment(ersModeLabel, "left") ersRecoveryLabel = ac.addLabel(appWindow, "") ac.setPosition(ersRecoveryLabel, elpx + 85, elpy) ac.setFontSize(ersRecoveryLabel, 18) ac.setCustomFont(ersRecoveryLabel, FONT_NAME, 0, 0) ac.setFontColor(ersRecoveryLabel, 1.0, 1.0, 0.2, 1) ac.setFontAlignment(ersRecoveryLabel, "left") ersLabel = ac.addLabel(appWindow, "ERS:") ac.setPosition(ersLabel, elpx, elpy) ac.setFontSize(ersLabel, 18) ac.setCustomFont(ersLabel, FONT_NAME, 0, 0) ac.setFontColor(ersLabel, 1.0, 1.0, 0.2, 1) ac.setFontAlignment(ersLabel, "left") # ================================================================================================================= # FUEL LABEL # ================================================================================================================= fuelLabel = ac.addLabel(appWindow, "💧 --.- Laps") ac.setPosition(fuelLabel, 15, 36) ac.setFontSize(fuelLabel, 18) ac.setCustomFont(fuelLabel, FONT_NAME, 0, 0) ac.setFontColor(fuelLabel, 0.86, 0.86, 0.86, 1) ac.setFontAlignment(fuelLabel, "left") # ================================================================================================================= # DRS LABELS # ================================================================================================================= drsLabel = ac.addLabel(appWindow, "") ac.setPosition(drsLabel, -70, 0) ac.setSize(drsLabel, 70, 70) ac.setVisible(drsLabel, 0) drsPenaltyBackgroundLabel = ac.addLabel(appWindow, "") ac.setPosition(drsPenaltyBackgroundLabel, 0, 70) ac.setSize(drsPenaltyBackgroundLabel, 280, 25) ac.setBackgroundTexture(drsPenaltyBackgroundLabel, DRS_PENALTY_TEXTURE) ac.setVisible(drsPenaltyBackgroundLabel, 0) drsPenaltyLabel = ac.addLabel(appWindow, "") ac.setPosition(drsPenaltyLabel, 150, 70) ac.setFontSize(drsPenaltyLabel, 18) ac.setCustomFont(drsPenaltyLabel, FONT_NAME, 0, 1) ac.setFontColor(drsPenaltyLabel, 0.86, 0.86, 0.86, 1) ac.setFontAlignment(drsPenaltyLabel, "center") ac.setVisible(drsPenaltyLabel, 0) # Announce Start timer = threading.Timer(10, announceStart) timer.start() return APP_NAME
def _get_track_name(): track = ac.getTrackName(0) track_config = ac.getTrackConfiguration(0) if track_config: track = '{}-{}'.format(track, track_config) return track
def __init__(self): self.rowHeight=36 self.lastLapInPit = 0 self.lastLapInvalidated = 0 self.situation = 0 self.carsCount=0 self.lbl_timing_height = 0 self.lbl_position_height = 0 self.lbl_position_text=Value("") self.currentVehicule=Value(-1) self.ui_row_height = Value(-1) self.cursor=Value(False) self.fastestLap=Value(0) self.fastestLap2=Value(0) self.fastestPos=1 self.lastLap=0 self.lastLapStart=10000 self.sector_delay = 5000 self.lastTimeInPit=0 self.visible_end = 0 self.lastLapTime = 0 self.nameOffset=0 self.nameOffsetValue=Value(0) self.lapCanBeInvalidated=True self.fastestLapBorderActive = False self.firstLapStarted=False self.minLapCount=1 self.sectorCount=-1 self.lapTimesArray = [] self.driversLap = [] track=ac.getTrackName(0) config=ac.getTrackConfiguration(0) if track.find("ks_nordschleife")>=0 and config.find("touristenfahrten")>=0: self.minLapCount=0 self.lastLapInvalidated = -1 elif track.find("drag1000")>=0 or track.find("drag400")>=0: self.minLapCount=0 self.lastLapInvalidated = -1 self.fastestLapSectors = [0,0,0,0,0,0] self.session=Value(-1) #self.session.setValue() self.window = Window(name="ACTV Info", icon=False, width=332, height=self.rowHeight*2, texture="") self.lbl_driver_name=Label(self.window.app,"").setSize(284, self.rowHeight).setPos(0, 0).setBgColor(rgb([20, 20, 20], bg = True)).setBgOpacity(0.8).setVisible(0) self.lbl_driver_name2=Label(self.window.app,"Loading").setSize(284, self.rowHeight).setPos(14, 0).setFontSize(26).setAlign("left").setVisible(0) self.lbl_driver_name_visible=Value() self.lbl_driver_name_visible_fin=Value(0) self.lbl_driver_name_text=Value("") self.lbl_position_visible=Value(0) self.lbl_timing_text=Value() self.race_fastest_lap=Value(0) #self.race_fastest_lap.setValue(0) self.race_fastest_lap_driver=Value() self.lbl_timing_visible=Value(0) self.lbl_timing=Label(self.window.app,"Loading").setSize(284, self.rowHeight).setPos(0, self.rowHeight).setFontSize(26).setAlign("left").setBgColor(rgb([55, 55, 55], bg = True)).setBgOpacity(0.64).setVisible(0) self.lbl_split=Label(self.window.app,"Loading").setSize(220, self.rowHeight).setPos(10, self.rowHeight).setFontSize(26).setAlign("right").setVisible(0) self.lbl_fastest_split=Label(self.window.app,"Loading").setSize(220, self.rowHeight).setPos(48, self.rowHeight).setFontSize(26).setAlign("right").setVisible(0) self.info_position=Label(self.window.app,"0").setSize(self.rowHeight, self.rowHeight).setPos(0, 0).setFontSize(26).setAlign("center").setBgColor(Colors.red(bg = True)).setBgOpacity(1).setVisible(0) self.info_position_lead=Label(self.window.app,"1").setSize(self.rowHeight, self.rowHeight).setPos(246, self.rowHeight).setFontSize(26).setAlign("center").setBgColor(Colors.red(bg = True)).setBgOpacity(1).setVisible(0) car = ac.getCarName(0) self.lbl_border=Label(self.window.app,"").setSize(284, 1).setPos(0, self.rowHeight).setBgColor(Colors.colorFromCar(car)).setBgOpacity(0.7).setVisible(0) self.loadCFG() self.info_position.setAnimationSpeed("o", 0.1) self.info_position_lead.setAnimationSpeed("o", 0.1) self.lbl_split.setAnimationSpeed("a", 0.1) self.lbl_fastest_split.setAnimationSpeed("a", 0.1)
def getTrackName(): return ac.getTrackName(0)
def acMain(ac_version): global appWindow, l_sockstat global ego_stat, env_stat, s, ai_lane, fileDest global sct, mon_select, monitor global csvfile, writer, starttime appWindow = ac.newApp(appName) ac.setTitle(appWindow, appName) ac.setSize(appWindow, width, height) global trackName trackName = ac.getTrackName(0) global trackConfig trackConfig = ac.getTrackConfiguration(0) global trackLength trackLength = ac.getTrackLength(0) ac.console(str(trackLength)) ego_stat = { 'trackName': trackName, 'trackConfig': trackConfig, 'gas': None, 'brake': None, 'steerAngle': None, 'velocity': [None, None, None], 'accG': [None, None, None], 'wheelSlip': [None, None, None, None], 'wheelLoad': [None, None, None, None], 'heading': None, 'pitch': None, 'roll': None, 'localAngularVel': [None, None, None], 'localVelocity': [None, None, None], 'normalizedCarPosition': None, 'carCoordinates': [None, None, None], 'surfaceGrip': None, 'env_stat': {}, 'time': 0, 'numCars': None } env_stat = { 'velocity': [None, None, None], 'normalizedCarPosition': None, 'carCoordinates': [None, None, None] } fileDest = os.path.join(os.getcwd(), 'content', 'tracks', trackName, 'ai', 'fast_lane.ai') if not trackConfig == "" and os.path.isdir("content/tracks/%s/%s/ai" % (trackName, trackConfig)): fileDest = os.path.join(os.getcwd(), 'content', 'tracks', trackName, trackConfig, 'ai', 'fast_lane.ai') csvfile = open('apps/python/aclab_py/log.csv', 'w') writer = csv.DictWriter(csvfile, fieldnames=list(ego_stat.keys())) writer.writeheader() # ai_lane = acParse(fileDest) ac.console(fileDest) l_sockstat = ac.addLabel(appWindow, "waiting for client...") ac.setPosition(l_sockstat, 0, 30) sct = mss.mss() monitor = sct.monitors[mon_select] # get data of monitor desired monitor = sct.adj_monitor(monitor) return appName
def __init__(self, app, x, y): self.AverageFuelPerLap = 0.0 self.FuelLastLap = 0.0 self.completedLaps = 0.0 self.fuelAtLapStart = 0.0 self.distanceTraveledAtStart = 0.0 self.fuelAtStart = 0.0 self.lastFuelMeasurement = 0.0 self.lastDistanceTraveled = 0.0 self.counter = 0 self.updatecounter = 0 self.inifilepath = inidir + self.getValidFileName(ac.getCarName(0)) +"_" + self.getValidFileName(ac.getTrackName(0)) + self.getValidFileName(ac.getTrackConfiguration(0)) + ".ini" ##initialize labels self.remainingLabel = ac.addLabel(app, "remainingLabel") self.averageFuelPerLapLabel = ac.addLabel(app, "averageFuelPerLapLabel") self.lapsLeftLabel = ac.addLabel(app, "lapsLeftLabel") self.averageFuelPer100kmLabel = ac.addLabel(app, "averageFuelPer100km") self.instFuelLabel = ac.addLabel(app, "instFuel") ##set label positions ac.setPosition(self.remainingLabel, x, y) ac.setPosition(self.averageFuelPerLapLabel, x + 208, y) ac.setPosition(self.lapsLeftLabel, 150 - x, y) ac.setPosition(self.averageFuelPer100kmLabel, x + 208, y + 19) ac.setPosition(self.instFuelLabel, 150 - x, y + 19) ##set label alignments ac.setFontAlignment(self.remainingLabel, "left") ac.setFontAlignment(self.averageFuelPerLapLabel, "left") ac.setFontAlignment(self.lapsLeftLabel, "right") ac.setFontAlignment(self.averageFuelPer100kmLabel, "left") ac.setFontAlignment(self.instFuelLabel, "right") ##set font size ac.setFontSize(self.remainingLabel, 32) ac.setFontSize(self.averageFuelPerLapLabel, 16) ac.setFontSize(self.lapsLeftLabel, 16) ac.setFontSize(self.averageFuelPer100kmLabel, 16) ac.setFontSize(self.instFuelLabel, 16) if os.path.exists(self.inifilepath): f = open(self.inifilepath, "r") self.AverageFuelPerLap = float(f.readline()[6:]) f.close() ac.setText(self.remainingLabel, "--- l") ac.setText(self.averageFuelPerLapLabel, "--- l/lap") ac.setText(self.lapsLeftLabel, "--- laps") if milesPerGallon: ac.setText(self.averageFuelPer100kmLabel, "--- mpg") else: ac.setText(self.averageFuelPer100kmLabel, "--- l/100km") ac.setText(self.instFuelLabel, "--- inst.")
tspeed_session = 0 l_tspeed_session = 0 l_tspeed_llap = 0 l_tspeed_clap = 0 l_q = 0 l_fuel = 0 l_session_type = 0 session_type = 0 # 0 = practice, 1 = quali, 2 = race, updates each graphic step session = [ 'Practice', 'Qualify', 'Race', 'Hotlap', 'Time Attack', 'Drift', 'Drag' ] #Session ID drivername = ac.getDriverName(0) #info.static.playerName drivername = drivername.replace(" ", "") trackname = ac.getTrackName(0) #info.static.track carname = ac.getCarName(0) #info.static.carModel currenttime = datetime.datetime.now().strftime('%Y%m%d%H%M%S') sessionid = "{a}_{b}_{c}_{d}".format(a=drivername, b=currenttime, c=trackname, d=carname) #Output file name and directory definition try: sessionstarttime = datetime.datetime.now().strftime(' %b, %d, %Y %H %M %S') targetdir = os.path.dirname(__file__) + '/TESTS/' targetname = "{d}Session from {t}.txt".format(d=targetdir, t=sessionstarttime) #targetfile = open(targetname,"w") #use this file to run tests on outputs except Exception as e:
def getGeneralData(): res = dict() res['trackName'] = ac.getTrackName(0) res['trackConfiguration'] = ac.getTrackConfiguration(0) res['carCount'] = ac.getCarsCount() return res
def __init__(self): self.window = Window(name="ACTV CP Delta", width=180, height=300) self.cursor = Value(False) self.session = Value(-1) self.performance = Value(0) self.spline = Value(0) self.currentVehicle = Value(-1) self.laptime = Value(0) self.TimeLeftUpdate = Value(0) self.referenceLap = [] self.referenceLapTime = Value(0) self.lastLapTime = Value(0) self.lapCount = 0 self.performance_display = 0 self.current_car_class = Value("") self.lastLapIsValid = True self.best_lap_time = 0 self.visual_timeout = -1 self.currentLap = [] self.drivers_info = [] self.deltaLoaded = False self.thread_save = False self.last_yellow_flag_end = False self.standings = None self.rowHeight = Value(-1) self.is_multiplayer = ac.getServerIP() != '' self.numCars = self.cars_count = ac.getCarsCount() self.font_size = 16 self.is_touristenfahrten = False track = ac.getTrackName(0) config = ac.getTrackConfiguration(0) if track.find("ks_nordschleife") >= 0 and config.find( "touristenfahrten") >= 0: self.is_touristenfahrten = True self.current_lap_others = [] self.spline_others = [] self.drivers_lap_count = [] self.reference_lap_time_others = [] for i in range(self.cars_count): self.drivers_lap_count.append(Value(0)) self.spline_others.append(Value(0)) self.current_lap_others.append([]) self.reference_lap_time_others.append([]) self.last_lap_start = [-1] * self.cars_count self.lbl_flag = Label(self.window.app)\ .set(w=77, h=50, x=1, y=-80, background=Colors.white(bg=True), opacity=1) self.lbl_number_bg = Label(self.window.app)\ .set(w=77, h=0, x=0, y=0, background=Colors.white(bg=True), opacity=1, visible=1) self.lbl_number_text = Label(self.window.app, "000")\ .set(w=77, h=0, x=0, y=0, opacity=0, color=Colors.black_txt(), font_size=26, align="center", visible=1) self.lbl_name_bg = Label(self.window.app)\ .set(w=77, h=0, x=0, y=0, opacity=1, visible=1) self.lbl_name_text = Label(self.window.app, "PLY")\ .set(w=77, h=0, x=0, y=0, opacity=0, font_size=26, align="center", visible=1) self.lbl_position_text_shadow = Label(self.window.app, "0")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="right", visible=1) self.lbl_position_text = Label(self.window.app, "0")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="right", visible=1) self.lbl_position_text_multi_shadow = Label(self.window.app, "0")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="right", visible=1) self.lbl_position_text_multi = Label(self.window.app, "0")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="right", visible=1) self.lbl_position_total_text_shadow = Label(self.window.app, "/0")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="left", visible=1) self.lbl_position_total_text = Label(self.window.app, "/0")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="left", visible=1) self.lbl_position_total_text_multi_shadow = Label(self.window.app, "/0")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="left", visible=1) self.lbl_position_total_text_multi = Label(self.window.app, "/0")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="left", visible=1) self.lbl_delta_bg = Label(self.window.app)\ .set(w=77, h=0, x=0, y=0, opacity=0, background=Colors.delta_neutral(), visible=1) self.lbl_current_time_bg = Label(self.window.app)\ .set(w=77, h=0, x=0, y=0, opacity=1, visible=1) self.lbl_current_time_text = Label(self.window.app, "--:--.---")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="left", visible=1) self.lbl_best_time_title_bg = Label(self.window.app)\ .set(w=0, h=0, x=0, y=0, opacity=1, visible=1) self.lbl_best_title_text = Label(self.window.app, "BEST")\ .set(w=77, h=0, x=0, y=0, opacity=0, font_size=26, align="left", visible=1) self.lbl_best_time_text = Label(self.window.app, "--:--.---")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="right", visible=1) self.lbl_last_title_bg = Label(self.window.app)\ .set(w=0, h=0, x=0, y=0, opacity=1, visible=1) self.lbl_last_title_text = Label(self.window.app, "LAST")\ .set(w=77, h=0, x=0, y=0, opacity=0, font_size=26, align="left", visible=1) self.lbl_last_time_text = Label(self.window.app, "--:--.---")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="right", visible=1) self.lbl_prediction_title_bg = Label(self.window.app)\ .set(w=0, h=0, x=0, y=0, opacity=1, visible=1) self.lbl_prediction_title_text = Label(self.window.app, "PRED")\ .set(w=77, h=0, x=0, y=0, opacity=0, font_size=26, align="left", visible=1) self.lbl_prediction_time_text = Label(self.window.app, "--:--.---")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="right", visible=1) self.lbl_delta_text = Label(self.window.app, "+0.00")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, color=Colors.black_txt(), align="center", visible=1) self.lbl_laps_completed_text_shadow = Label(self.window.app, "0")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="right", visible=1) self.lbl_laps_completed_text = Label(self.window.app, "0")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="right", visible=1) self.lbl_laps_text_shadow = Label(self.window.app, "LAPS")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="left", visible=1) self.lbl_laps_text = Label(self.window.app, "LAPS")\ .set(w=0, h=0, x=0, y=0, opacity=0, font_size=26, align="left", visible=1) self.btn_reset = Button(self.window.app, self.on_reset_press)\ .setPos(90, 68).setSize(120, 20)\ .setText("Reset saved lap")\ .setAlign("center")\ .setBgColor(rgb([255, 12, 12], bg=True))\ .setVisible(0) self.btn_import_from = Button(self.window.app, self.on_import_from_press)\ .setPos(90, 68).setSize(120, 20)\ .setText("Import Delta")\ .setAlign("center")\ .setBgColor(rgb([255, 12, 12], bg=True))\ .setVisible(0) self.load_cfg()