示例#1
0
 def get_rpm_upshift(self):
     config = ConfigParser(empty_lines_in_values=False,
                           inline_comment_prefixes=(";", ))
     config.read_string(self.get_file("drivetrain.ini"))
     try:
         return float(config["AUTO_SHIFTER"]["UP"])
     except:
         log("Failed to get rpm upshit value:")
         for info in exc_info():
             log(info)
         raise
示例#2
0
 def get_rpm_limiter(self):
     config = ConfigParser(empty_lines_in_values=False,
                           inline_comment_prefixes=(";", ))
     config.read_string(self.get_file("engine.ini"))
     try:
         return float(config["ENGINE_DATA"]["LIMITER"])
     except:
         log("Failed to get rpm limiter value:")
         for info in exc_info():
             log(info)
         raise
示例#3
0
 def __load_from_folder(self, path):
     """ Loads the car information by the data folder. """
     for file_name in os.listdir(path):
         file_path = "{}/{}".format(path, file_name)
         if os.path.isfile(file_path):
             try:
                 with open(file_path, "r") as r:
                     self.set_file(r.read(), file_name)
             except:
                 log("Failed to open file {}:".format(file_name))
                 for info in exc_info():
                     log(info)
示例#4
0
    def get_power_curve(self):
        """ Returns the rpm x power curve. """
        config = ConfigParser(empty_lines_in_values=False,
                              inline_comment_prefixes=(";", ))
        config.read_string(self.get_file("engine.ini"))

        try:
            return self.get_file(config["HEADER"]["POWER_CURVE"])
        except:
            log("Failed to get rpm power curve:")
            for info in exc_info():
                log(info)
            raise
示例#5
0
    def get_temp_curve(self, compound, wheel):
        """ Returns the compound temperature grip curve. """
        config = ConfigParser(empty_lines_in_values=False,
                              inline_comment_prefixes=(";", ))
        config.read_string(self.get_file("tyres.ini"))

        try:
            name = "THERMAL_{}".format(get_tire_name(compound, config, wheel))
            return self.get_file(config[name]["PERFORMANCE_CURVE"])
        except:
            log("Failed to get tire temperature curve {}:".format(compound))
            for info in exc_info():
                log(info)
            raise
示例#6
0
    def get_ideal_pressure(self, compound, wheel):
        """ Returns the compound ideal pressure. """
        config = ConfigParser(empty_lines_in_values=False,
                              inline_comment_prefixes=(";", ))
        config.read_string(self.get_file("tyres.ini"))

        try:
            name = get_tire_name(compound, config, wheel)
            return float(config[name]["PRESSURE_IDEAL"])
        except:
            log("Failed to get tire ideal pressure:")
            for info in exc_info():
                log(info)
            raise
示例#7
0
    def get_wear_curve(self, compound, wheel):
        """ Returns the compound wear curve. """
        config = ConfigParser(empty_lines_in_values=False,
                              inline_comment_prefixes=(";", ))
        config.read_string(self.get_file("tyres.ini"))

        try:
            name = get_tire_name(compound, config, wheel)
            return self.get_file(config[name]["WEAR_CURVE"])
        except:
            log("Failed to get tire wear curve {}:".format(compound))
            for info in exc_info():
                log(info)
            raise
示例#8
0
 def get_rpm_damage(self):
     config = ConfigParser(empty_lines_in_values=False,
                           inline_comment_prefixes=(";", ))
     config.read_string(self.get_file("engine.ini"))
     try:
         if config.has_option("DAMAGE", "RPM_THRESHOLD"):
             res = config["DAMAGE"]["RPM_THRESHOLD"]
         else:
             res = self.get_rpm_limiter() + 100
         return float(res)
     except:
         log("Failed to get rpm damage value:")
         for info in exc_info():
             log(info)
         raise
示例#9
0
    def get_power_curve(self):
        """ Returns the rpm x power curve. """
        config = ConfigParser(empty_lines_in_values=False,
                              inline_comment_prefixes=(";", ))
        config.read_string(self.get_file("engine.ini"))

        try:
            # Need to filter this file, thanks RSS
            file_content = self.get_file(config.get("HEADER", "POWER_CURVE"))
            return self.filter_mod_file_content(file_content)
        except:
            log("Failed to get rpm power curve:")
            for info in exc_info():
                log(info)
            raise
示例#10
0
    def get_wear_curve(self, compound, wheel):
        """ Returns the compound wear curve. """
        config = ConfigParser(empty_lines_in_values=False,
                              inline_comment_prefixes=(";", ))
        config.read_string(self.get_file("tyres.ini"))

        try:
            name = get_tire_name(compound, config, wheel)
            # Need to filter this file, thanks RSS
            file_content = self.get_file(config.get(name, "WEAR_CURVE"))
            return self.filter_mod_file_content(file_content)
        except:
            log("Failed to get tire wear curve {}:".format(compound))
            for info in exc_info():
                log(info)
            raise
示例#11
0
    def get_abs_hz(self):
        """ Returns the ABS active rate in Hz. """
        config = ConfigParser(empty_lines_in_values=False,
                              inline_comment_prefixes=(";", ))
        config.read_string(self.get_file("electronics.ini"))

        if config.has_option("ABS", "RATE_HZ"):
            try:
                return float(config.get("ABS", "RATE_HZ"))
            except:
                log("Failed to get ABS rate:")
                for info in exc_info():
                    log(info)
                raise
        else:
            return 0.0
示例#12
0
def get_tire_name(compound, config, wheel):
    """ Returns the compound session name on the tire.ini configuration file. """
    prefix = "FRONT{}" if wheel.is_front() else "REAR{}"

    for i in range(10):
        name = prefix.format("" if i == 0 else "_{}".format(i))
        # Check if the SHORT_NAME index exists for tire backward compatibility.
        if config.has_option(
                name, "SHORT_NAME") and config[name]["SHORT_NAME"] == compound:
            return name

    try:
        i = int(config["COMPOUND_DEFAULT"]["INDEX"])
        return prefix.format("" if i == 0 else "_{}".format(i))
    except:
        log("Failed to get tire name {}:".format(compound))
        for info in exc_info():
            log(info)
        raise
示例#13
0
    def __init__(self, path):
        """ Default constructor receives the ACD file path. """
        path_v = path.split("/")

        # Initiate the class fields.
        self.__car = path_v[-1]
        self.__content = bytearray()
        self.__content_size = len(self.__content)
        self.__files = OrderedDict()
        self.__key = generate_key(self.__car)

        # Verify if the data.acd exists to load car information.
        data_acd_path = "{}/data.acd".format(path)
        if os.path.isfile(data_acd_path):
            log("Loading from data.acd...")
            self.__load_from_file(data_acd_path)
        else:
            # If it don't, try to load from data folder.
            log("Loading from data folder...")
            self.__load_from_folder("{}/data".format(path))
示例#14
0
    def get_abs_slip_ratio_list(self):
        """ Returns the abs slip ratio list. """
        config = ConfigParser(empty_lines_in_values=False,
                              inline_comment_prefixes=(";", ))
        config.read_string(self.get_file("electronics.ini"))

        if config.has_option("ABS", "SLIP_RATIO_LIMIT") or config.has_option(
                "ABS", "SLIP_RATIO_LIMIT"):
            try:
                return self.get_file(config["ABS"]["CURVE"])
            except:
                log("Failed to get ABS slip ratio curve:")
                for info in exc_info():
                    log(info)
                log("Trying to get ratio limit:")
                try:
                    return "0|{}".format(config["ABS"]["SLIP_RATIO_LIMIT"])
                except:
                    log("Failed to get ABS slip ratio limit:")
                    for info in exc_info():
                        log(info)
                    return ""
        else:
            return ""
示例#15
0
def acMain(ac_version: str) -> None:
    """ Initiates the program. """
    global ACD_OBJ
    global CONFIGS
    global LT_VERSION

    log("Starting Live Telemetry {} on AC Python API version {}...".format(
        LT_VERSION, ac_version))

    log("Loading configs...")
    CONFIGS = Config(LT_VERSION)

    log("Loading {} info...".format(ac.getCarName(0)))
    ACD_OBJ = ACD("content/cars/{}".format(ac.getCarName(0)))
    log("Loaded correctly")

    log("Loading options window...")
    global OPTIONS_INFO
    OPTIONS_INFO = OptionsInfo(CONFIGS)
    ac.addOnClickedListener(
        OPTIONS_INFO.get_button_id("Camber"), on_click_camber)
    ac.addOnClickedListener(OPTIONS_INFO.get_button_id("Dirt"), on_click_dirt)
    ac.addOnClickedListener(
        OPTIONS_INFO.get_button_id("Height"), on_click_height)
    ac.addOnClickedListener(OPTIONS_INFO.get_button_id("Load"), on_click_load)
    ac.addOnClickedListener(OPTIONS_INFO.get_button_id("Lock"), on_click_lock)
    ac.addOnClickedListener(
        OPTIONS_INFO.get_button_id("Logging"), on_click_logging)
    ac.addOnClickedListener(OPTIONS_INFO.get_button_id(
        "Pressure"), on_click_pressure)
    ac.addOnClickedListener(
        OPTIONS_INFO.get_button_id("RPMPower"), on_click_rpm)
    ac.addOnClickedListener(OPTIONS_INFO.get_button_id("Size"), on_click_size)
    ac.addOnClickedListener(OPTIONS_INFO.get_button_id(
        "Suspension"), on_click_suspension)
    ac.addOnClickedListener(
        OPTIONS_INFO.get_button_id("Temps"), on_click_temps)
    ac.addOnClickedListener(OPTIONS_INFO.get_button_id("Tire"), on_click_tire)
    ac.addOnClickedListener(OPTIONS_INFO.get_button_id("Wear"), on_click_wear)

    log("Loading engine window...")
    global ENGINE_INFO
    ENGINE_INFO = EngineInfo(ACD_OBJ, CONFIGS)
    window_id = ENGINE_INFO.get_window_id()
    ac.addOnAppActivatedListener(window_id, on_activation)
    ac.addOnAppDismissedListener(window_id, on_dismiss)
    ac.addRenderCallback(ENGINE_INFO.get_window_id(), on_render_engine)

    log("Loading wheel windows...")
    global WHEEL_INFOS
    for index in range(4):
        info = WheelInfo(ACD_OBJ, CONFIGS, index)
        window_id = info.get_window_id()
        ac.addOnAppActivatedListener(window_id, on_activation)
        ac.addOnAppDismissedListener(window_id, on_dismiss)
        WHEEL_INFOS[info.get_id()] = info

    ac.addRenderCallback(WHEEL_INFOS["FL"].get_window_id(), on_render_fl)
    ac.addRenderCallback(WHEEL_INFOS["FR"].get_window_id(), on_render_fr)
    ac.addRenderCallback(WHEEL_INFOS["RL"].get_window_id(), on_render_rl)
    ac.addRenderCallback(WHEEL_INFOS["RR"].get_window_id(), on_render_rr)

    log("Live Telemetry started.")

    return "Live Telemetry"
示例#16
0
def acShutdown() -> None:
    """ Called when the session ends (or restarts). """
    log("Shutting down Live Telemetry...")

    global CONFIGS
    global ENGINE_INFO
    global OPTIONS_INFO
    global WHEEL_INFOS

    log("Saving options configurations...")
    CONFIGS.set_option("Camber", OPTIONS_INFO.get_option("Camber"))
    CONFIGS.set_option("Dirt", OPTIONS_INFO.get_option("Dirt"))
    CONFIGS.set_option("Height", OPTIONS_INFO.get_option("Height"))
    CONFIGS.set_option("Load", OPTIONS_INFO.get_option("Load"))
    CONFIGS.set_option("Lock", OPTIONS_INFO.get_option("Lock"))
    CONFIGS.set_option("Logging", OPTIONS_INFO.get_option("Logging"))
    CONFIGS.set_option("Pressure", OPTIONS_INFO.get_option("Pressure"))
    CONFIGS.set_option("RPMPower", OPTIONS_INFO.get_option("RPMPower"))
    CONFIGS.set_option("Size", OPTIONS_INFO.get_option("Size"))
    CONFIGS.set_option("Suspension", OPTIONS_INFO.get_option("Suspension"))
    CONFIGS.set_option("Temps", OPTIONS_INFO.get_option("Temps"))
    CONFIGS.set_option("Tire", OPTIONS_INFO.get_option("Tire"))
    CONFIGS.set_option("Wear", OPTIONS_INFO.get_option("Wear"))

    log("Saving windows configurations...")
    CONFIGS.set_window_active("EN", ENGINE_INFO.is_active())
    CONFIGS.set_window_position("EN", ENGINE_INFO.get_position())
    ENGINE_INFO.set_active(False)
    CONFIGS.set_window_position("OP", OPTIONS_INFO.get_position())
    for wheel_id in WHEEL_INFOS:
        info = WHEEL_INFOS[wheel_id]
        CONFIGS.set_window_active(wheel_id, info.is_active())
        CONFIGS.set_window_position(wheel_id, info.get_position())
        info.set_active(False)

    CONFIGS.save_config()

    if ENGINE_INFO.has_data_logged() or WHEEL_INFOS["FL"].has_data_logged() or WHEEL_INFOS["FL"].has_data_logged() or WHEEL_INFOS["RL"].has_data_logged() or WHEEL_INFOS["RR"].has_data_logged():
        log("Saving csv data...")
        for wheel_id in WHEEL_INFOS:
            info = WHEEL_INFOS[wheel_id]
            export_saved_log(info.get_data_log(), wheel_id)
        export_saved_log(ENGINE_INFO.get_data_log(), "EN")
    else:
        log("Deleting old csv data...")
        clear_logs()
    log("Live Telemetry ended.")
示例#17
0
    def __load_from_file(self, path):
        """ Loads the car information by the data.acd encrypted file. """

        # Read all the file into memory.
        try:
            with open(path, "rb") as rb:
                self.__content = bytearray(rb.read())
                self.__content_size = len(self.__content)
        except:
            log("Failed to open file {}:".format(path))
            for info in exc_info():
                log(info)

        if self.__content_size > 8:
            # Verify the "version" of the file.
            offset = 0
            dummy = unpack("l", self.__content[offset:offset + 4])[0]
            offset += 4
            if dummy < 0:
                # New cars, just pass the first 8 bytes.
                dummy = unpack("L", self.__content[offset:offset + 4])[0]
                offset += 4
            else:
                # Old cars don't have any version.
                offset = 0

            # Parse each inner file.
            while offset < self.__content_size:
                # Size of the file name.
                name_size = unpack("L", self.__content[offset:offset + 4])[0]
                offset += 4

                # File name.
                file_name = self.__content[offset:offset +
                                           name_size].decode("utf8")
                offset += name_size
                log(file_name)

                # File size.
                file_size = unpack("L", self.__content[offset:offset + 4])[0]
                offset += 4

                # Get the content and slices each 4 bytes.
                packed_content = self.__content[offset:offset +
                                                file_size * 4][::4]
                offset += file_size * 4

                # Decrypt the content of the file.
                decrypted_content = ""
                key_size = len(self.__key)
                for i in range(file_size):
                    code = packed_content[i] - ord(self.__key[i % key_size])
                    if code < 0:
                        log("Invalid unicode code '{}' in file: {} @ byte {}".
                            format(code, file_name, i))
                        log("Using '33' (!) to continue parsing file.")
                    decrypted_content += chr(33 if code < 0 else code)

                # Save the decrypted file.
                self.set_file(decrypted_content, file_name)
        elif self.__content_size > 0:
            log("File too small to decrypt: {} bytes.".format(
                self.__content_size))
示例#18
0
    def __init__(self, lt_version: str) -> None:
        """ Loads or creates the app configuration file. """

        self.__configs = ConfigParser()
        if path.isfile("apps/python/LiveTelemetry/cfg.ini"):
            self.__configs.read("apps/python/LiveTelemetry/cfg.ini")

        # If the config does not have it's version or is invalid, create a new one.
        try:
            config_version = self.get_version()
            if config_version != lt_version:
                log("Old config file. Could make things crash!")
                raise Exception("Old config file.")
        except:
            log("Creating new config file.")
            self.__configs["About"] = {"Version": lt_version}
            self.__configs["Options"] = {}
            self.__configs["Windows"] = {}
            self.__configs["Windows Positions"] = {}

            self.set_option("Camber", True)
            self.set_option("Dirt", True)
            self.set_option("Height", True)
            self.set_option("Load", True)
            self.set_option("Lock", True)
            self.set_option("Logging", False)
            self.set_option("Pressure", True)
            self.set_option("RPMPower", True)
            self.set_option("Size", "FHD")
            self.set_option("Suspension", True)
            self.set_option("Temps", True)
            self.set_option("Tire", True)
            self.set_option("Wear", True)

            self.set_window_active("EN", False)
            self.set_window_active("FL", False)
            self.set_window_active("FR", False)
            self.set_window_active("RL", False)
            self.set_window_active("RR", False)

            h = 720
            w = 1280
            docs_path = get_docs_path()

            if len(docs_path) > 0:
                try:
                    video = ConfigParser()
                    video.read(
                        "{}/Assetto Corsa/cfg/video.ini".format(docs_path))
                    h = int(video.get("VIDEO", "HEIGHT")) if video.has_option(
                        "VIDEO", "HEIGHT") else 720
                    w = int(video.get("VIDEO", "WIDTH")) if video.has_option(
                        "VIDEO", "WIDTH") else 1280
                except:
                    log("Could not get 'cfg/video.ini' video options, using default 1280x720 resolution:"
                        )
                    for info in exc_info():
                        log(info)

            self.set_window_position("EN",
                                     [floor((w - 360) / 2), h - 51 - 160])
            self.set_window_position("FL", [10, 80])
            self.set_window_position("FR", [w - 360 - 10, 80])
            self.set_window_position(
                "OP", [w - 395 - 50, floor((h - 195) / 2)])
            self.set_window_position("RL", [10, h - 163 - 80])
            self.set_window_position("RR", [w - 360 - 10, h - 163 - 80])
            self.save_config()