Example #1
0
def load(f, **options):  # type: (typing.IO, **typing.Any) -> canmatrix.CanMatrix
    dbc_import_encoding = options.get("dbcImportEncoding", 'iso-8859-1')
    dbc_comment_encoding = options.get("dbcImportCommentEncoding", dbc_import_encoding)
    float_factory = options.get('float_factory', default_float_factory)

    i = 0

    follow_up = _FollowUps.NOTHING
    comment = ""
    signal = None  # type: typing.Optional[canmatrix.Signal]
    frame = None
    board_unit = None
    db = canmatrix.CanMatrix()
    frames_by_id = {}  # type: typing.Dict[int, canmatrix.Frame]

    def hash_arbitration_id(arbitration_id):  # type: (canmatrix.ArbitrationId) -> int
        return hash((arbitration_id.id, arbitration_id.extended))

    def get_frame_by_id(arbitration_id):  # type: (canmatrix.ArbitrationId) -> typing.Optional[canmatrix.Frame]
        try:
            return frames_by_id[hash_arbitration_id(arbitration_id)]
        except KeyError:
            return None

    def add_frame_by_id(new_frame):  # type: (canmatrix.Frame) -> None
        frames_by_id[hash_arbitration_id(new_frame.arbitration_id)] = new_frame

    for line in f:
        i = i + 1
        l = line.strip()
        if len(l) == 0:
            continue
        try:
        # if 1==1:
            if follow_up == _FollowUps.SIGNAL_COMMENT:
                try:
                    comment += "\n" + l.decode(dbc_comment_encoding).replace('\\"', '"')
                except:
                    logger.error("Error decoding line: %d (%s)" % (i, line))
                if re.match(r'.*" *;\Z',l.decode(dbc_import_encoding).strip()) is not None:
                    follow_up = _FollowUps.NOTHING
                    if signal is not None:
                        signal.add_comment(comment[:-1].strip()[:-1])
                continue
            elif follow_up == _FollowUps.FRAME_COMMENT:
                try:
                    comment += "\n" + l.decode(dbc_comment_encoding).replace('\\"', '"')
                except:
                    logger.error("Error decoding line: %d (%s)" % (i, line))
                if re.match(r'.*" *;\Z',l.decode(dbc_import_encoding).strip()) is not None:
                    follow_up = _FollowUps.NOTHING
                    if frame is not None:
                        frame.add_comment(comment[:-1].strip()[:-1])
                continue
            elif follow_up == _FollowUps.BOARD_UNIT_COMMENT:
                try:
                    comment += "\n" + \
                        l.decode(dbc_comment_encoding).replace('\\"', '"')
                except:
                    logger.error("Error decoding line: %d (%s)" % (i, line))
                if re.match(r'.*" *;\Z',l.decode(dbc_import_encoding).strip()) is not None:
                    follow_up = _FollowUps.NOTHING
                    if board_unit is not None:
                        board_unit.add_comment(comment[:-1].strip()[:-1])
                continue
            decoded = l.decode(dbc_import_encoding).strip()
            if decoded.startswith("BO_ "):
                regexp = re.compile(r"^BO_ ([^\ ]+) ([^\ ]+) *: ([^\ ]+) ([^\ ]+)")
                temp = regexp.match(decoded)
    #            db.frames.addFrame(Frame(temp.group(1), temp.group(2), temp.group(3), temp.group(4)))
                frame = canmatrix.Frame(temp.group(2), arbitration_id=int(temp.group(1)),
                                        size=int(temp.group(3)), transmitters=temp.group(4).split())
                db.frames.append(frame)
                add_frame_by_id(frame)
            elif decoded.startswith("SG_ "):
                pattern = r"^SG_ +(\w+) *: *(\d+)\|(\d+)@(\d+)([\+|\-]) *\(([0-9.+\-eE]+), *([0-9.+\-eE]+)\) *\[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] +\"(.*)\" +(.*)"
                regexp = re.compile(pattern)
                temp = regexp.match(decoded)
                regexp_raw = re.compile(pattern.encode(dbc_import_encoding))
                temp_raw = regexp_raw.match(l)
                if temp:
                    receiver = [b.strip() for b in temp.group(11).split(',')]

                    extras = {}  # type: typing.Dict[typing.Any, typing.Any]
#                    if float_factory is not None:
#                        extras['float_factory'] = float_factory

                    temp_signal = canmatrix.Signal(
                        temp.group(1),
                        start_bit=int(temp.group(2)),
                        size=int(temp.group(3)),
                        is_little_endian=(int(temp.group(4)) == 1),
                        is_signed=(temp.group(5) == '-'),
                        factor=temp.group(6),
                        offset=temp.group(7),
                        min=temp.group(8),
                        max=temp.group(9),
                        unit=temp_raw.group(10).decode(dbc_import_encoding),
                        receivers=receiver,
                        **extras
                    )
                    if not temp_signal.is_little_endian:
                        # startbit of motorola coded signals are MSB in dbc
                        temp_signal.set_startbit(int(temp.group(2)), bitNumbering=1)
                    frame.add_signal(temp_signal)
    #                db.frames.addSignalToLastFrame(tempSig)
                else:
                    pattern = r"^SG_ +(.+?) +(.+?) *: *(\d+)\|(\d+)@(\d+)([\+|\-]) *\(([0-9.+\-eE]+),([0-9.+\-eE]+)\) *\[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] +\"(.*)\" +(.*)"
                    regexp = re.compile(pattern)
                    regexp_raw = re.compile(pattern.encode(dbc_import_encoding))
                    temp = regexp.match(decoded)
                    temp_raw = regexp_raw.match(l)
                    receiver = [b.strip() for b in temp.group(12).split(',')]
                    multiplex = temp.group(2)  # type: str

                    is_complex_multiplexed = False

                    if multiplex == 'M':
                        multiplex = 'Multiplexor'
                    elif multiplex.endswith('M'):
                        is_complex_multiplexed = True
                        multiplex = multiplex[:-1]

                    if multiplex != 'Multiplexor':
                        try:
                            multiplex = int(multiplex[1:])
                        except:
                            raise Exception('error decoding line', line)

                    extras = {}
#                    if float_factory is not None:
#                        extras['float_factory'] = float_factory

                    temp_signal = canmatrix.Signal(
                        temp.group(1),
                        start_bit=int(temp.group(3)),
                        size=int(temp.group(4)),
                        is_little_endian=(int(temp.group(5)) == 1),
                        is_signed=(temp.group(6) == '-'),
                        factor=temp.group(7),
                        offset=temp.group(8),
                        min=temp.group(9),
                        max=temp.group(10),
                        unit=temp_raw.group(11).decode(dbc_import_encoding),
                        receivers=receiver,
                        multiplex=multiplex,
                        **extras
                    )

                    if is_complex_multiplexed:
                        temp_signal.is_multiplexer = True
                        temp_signal.multiplex = 'Multiplexor'

                    if not temp_signal.is_little_endian:
                        # startbit of motorola coded signals are MSB in dbc
                        temp_signal.set_startbit(int(temp.group(3)), bitNumbering=1)
                    frame.add_signal(temp_signal)

                    if is_complex_multiplexed:
                        frame.is_complex_multiplexed = True

            elif decoded.startswith("BO_TX_BU_ "):
                regexp = re.compile(r"^BO_TX_BU_ ([0-9]+) *: *(.+) *;")
                temp = regexp.match(decoded)
                frame = get_frame_by_id(canmatrix.ArbitrationId.from_compound_integer(int(temp.group(1))))
                for ecu_name in temp.group(2).split(','):
                    frame.add_transmitter(ecu_name)
            elif decoded.startswith("CM_ SG_ "):
                pattern = r"^CM_ +SG_ +(\w+) +(\w+) +\"(.*)\" *;"
                regexp = re.compile(pattern)
                regexp_raw = re.compile(pattern.encode(dbc_import_encoding))
                temp = regexp.match(decoded)
                temp_raw = regexp_raw.match(l)
                if temp:
                    frame = get_frame_by_id(canmatrix.ArbitrationId.from_compound_integer(int(temp.group(1))))
                    signal = frame.signal_by_name(temp.group(2))
                    if signal:
                        try:
                            signal.add_comment(temp_raw.group(3).decode(
                                dbc_comment_encoding).replace('\\"', '"'))
                        except:
                            logger.error(
                                "Error decoding line: %d (%s)" %
                                (i, line))
                else:
                    pattern = r"^CM_ +SG_ +(\w+) +(\w+) +\"(.*)"
                    regexp = re.compile(pattern)
                    regexp_raw = re.compile(pattern.encode(dbc_import_encoding))
                    temp = regexp.match(decoded)
                    temp_raw = regexp_raw.match(l)
                    if temp:
                        frame = get_frame_by_id(canmatrix.ArbitrationId.from_compound_integer(int(temp.group(1))))
                        signal = frame.signal_by_name(temp.group(2))
                        try:
                            comment = temp_raw.group(3).decode(
                                dbc_comment_encoding).replace('\\"', '"')
                        except:
                            logger.error(
                                "Error decoding line: %d (%s)" %
                                (i, line))
                        follow_up = _FollowUps.SIGNAL_COMMENT

            elif decoded.startswith("CM_ BO_ "):
                pattern = r"^CM_ +BO_ +(\w+) +\"(.*)\" *;"
                regexp = re.compile(pattern)
                regexp_raw = re.compile(pattern.encode(dbc_import_encoding))
                temp = regexp.match(decoded)
                temp_raw = regexp_raw.match(l)
                if temp:
                    frame = get_frame_by_id(canmatrix.ArbitrationId.from_compound_integer(int(temp.group(1))))
                    if frame:
                        try:
                            frame.add_comment(temp_raw.group(2).decode(
                                dbc_comment_encoding).replace('\\"', '"'))
                        except:
                            logger.error(
                                "Error decoding line: %d (%s)" %
                                (i, line))
                else:
                    pattern = r"^CM_ +BO_ +(\w+) +\"(.*)"
                    regexp = re.compile(pattern)
                    regexp_raw = re.compile(pattern.encode(dbc_import_encoding))
                    temp = regexp.match(decoded)
                    temp_raw = regexp_raw.match(l)
                    if temp:
                        frame = get_frame_by_id(canmatrix.ArbitrationId.from_compound_integer(int(temp.group(1))))
                        try:
                            comment = temp_raw.group(2).decode(
                                dbc_comment_encoding).replace('\\"', '"')
                        except:
                            logger.error(
                                "Error decoding line: %d (%s)" %
                                (i, line))
                        follow_up = _FollowUps.FRAME_COMMENT
            elif decoded.startswith("CM_ BU_ "):
                pattern = r"^CM_ +BU_ +(\w+) +\"(.*)\" *;"
                regexp = re.compile(pattern)
                regexp_raw = re.compile(pattern.encode(dbc_import_encoding))
                temp = regexp.match(decoded)
                temp_raw = regexp_raw.match(l)
                if temp:
                    board_unit = db.ecu_by_name(temp.group(1))
                    if board_unit:
                        try:
                            board_unit.add_comment(temp_raw.group(2).decode(
                                dbc_comment_encoding).replace('\\"', '"'))
                        except:
                            logger.error("Error decoding line: %d (%s)" % (i, line))
                else:
                    pattern = r"^CM_ +BU_ +(\w+) +\"(.*)"
                    regexp = re.compile(pattern)
                    regexp_raw = re.compile(pattern.encode(dbc_import_encoding))
                    temp = regexp.match(decoded)
                    temp_raw = regexp_raw.match(l)
                    if temp:
                        board_unit = db.ecu_by_name(temp.group(1))
                        if board_unit:
                            try:
                                comment = temp_raw.group(2).decode(
                                    dbc_comment_encoding).replace('\\"', '"')
                            except:
                                logger.error(
                                    "Error decoding line: %d (%s)" %
                                    (i, line))
                            follow_up = _FollowUps.BOARD_UNIT_COMMENT
            elif decoded.startswith("BU_:"):
                pattern = r"^BU_\:(.*)"
                regexp = re.compile(pattern)
                regexp_raw = re.compile(pattern.encode(dbc_import_encoding))
                temp = regexp.match(decoded)
                if temp:
                    my_temp_list = temp.group(1).split(' ')
                    for ele in my_temp_list:
                        if len(ele.strip()) > 1:
                            db.ecus.append(canmatrix.Ecu(ele))

            elif decoded.startswith("VAL_ "):
                regexp = re.compile(r"^VAL_ +(\w+) +(\w+) +(.*) *;")
                temp = regexp.match(decoded)
                if temp:
                    frame_id = temp.group(1)
                    signal_name = temp.group(2)
                    temp_list = list(canmatrix.utils.escape_aware_split(temp.group(3), '"'))

                    if frame_id.isnumeric():  # value for Frame
                        try:
                            frame = get_frame_by_id(canmatrix.ArbitrationId.from_compound_integer(int(frame_id)))
                            sg = frame.signal_by_name(signal_name)
                            for i in range(math.floor(len(temp_list) / 2)):
                                val = temp_list[i * 2 + 1]
                                val = val.replace('\\"', '"')
                                if sg:
                                    sg.add_values(temp_list[i * 2], val)
                        except:
                            logger.error("Error with Line: " + str(temp_list))
                    else:
                        logger.info("Warning: environment variables currently not supported")

            elif decoded.startswith("VAL_TABLE_ "):
                regexp = re.compile(r"^VAL_TABLE_ +(\w+) +(.*) *;")
                temp = regexp.match(decoded)
                if temp:
                    table_name = temp.group(1)
                    temp_list = temp.group(2).split('"')
                    value_hash = {}
                    try:
                        for i in range(math.floor(len(temp_list) / 2)):
                            val = temp_list[i * 2 + 1]
                            value_hash[temp_list[i * 2].strip()] = val.strip()
                    except:
                        logger.error("Error with Line: " + str(temp_list))
                    db.add_value_table(table_name, value_hash)
                else:
                    logger.debug(l)

            elif decoded.startswith("BA_DEF_") and decoded[7:].strip()[:3] in ["SG_", "BO_", "BU_", "EV_"]:
                substring = decoded[7:].strip()
                define_type = substring[:3]
                substring = substring[3:].strip()
                pattern = r"^\"(.+?)\" +(.+); *"
                regexp = re.compile(pattern)
                regexp_raw = re.compile(pattern.encode(dbc_import_encoding))
                temp = regexp.match(substring)
                substring_line = l[7:].strip()[3:].strip()
                temp_raw = regexp_raw.match(substring_line)
                if temp:
                    if define_type == "SG_":
                        db.add_signal_defines(temp.group(1), temp_raw.group(2).decode(dbc_import_encoding))
                    elif define_type == "BO_":
                        db.add_frame_defines(temp.group(1), temp_raw.group(2).decode(dbc_import_encoding))
                    elif define_type == "BU_":
                        db.add_ecu_defines(temp.group(1), temp_raw.group(2).decode(dbc_import_encoding))
                    elif define_type == "EV_":
                        db.add_env_defines(temp.group(1), temp_raw.group(2).decode(dbc_import_encoding))

            elif decoded.startswith("BA_DEF_ "):
                pattern = r"^BA_DEF_ +\"(.+?)\" +(.+) *;"
                regexp = re.compile(pattern)
                regexp_raw = re.compile(pattern.encode(dbc_import_encoding))
                temp = regexp.match(decoded)
                temp_raw = regexp_raw.match(l)
                if temp:
                    db.add_global_defines(temp.group(1),
                                          temp_raw.group(2).decode(dbc_import_encoding))

            elif decoded.startswith("BA_ "):
                regexp = re.compile(r"^BA_ +\".+?\" +(.+)")
                tempba = regexp.match(decoded)

                if tempba.group(1).strip().startswith("BO_ "):
                    regexp = re.compile(r"^BA_ +\"(.+?)\" +BO_ +(\d+) +(.+) *; *")
                    temp = regexp.match(decoded)
                    get_frame_by_id(canmatrix.ArbitrationId.from_compound_integer(int(temp.group(2)))).add_attribute(
                        temp.group(1), temp.group(3))
                elif tempba.group(1).strip().startswith("SG_ "):
                    regexp = re.compile(r"^BA_ +\"(.+?)\" +SG_ +(\d+) +(\w+) +(.+) *; *")
                    temp = regexp.match(decoded)
                    if temp is not None:
                        get_frame_by_id(canmatrix.ArbitrationId.from_compound_integer(int(temp.group(2)))).signal_by_name(
                            temp.group(3)).add_attribute(temp.group(1), temp.group(4))
                elif tempba.group(1).strip().startswith("EV_ "):
                    regexp = re.compile(r"^BA_ +\"(.+?)\" +EV_ +(\w+) +(.*) *; *")
                    temp = regexp.match(decoded)
                    if temp is not None:
                        db.add_env_attribute(temp.group(2), temp.group(1), temp.group(3))
                elif tempba.group(1).strip().startswith("BU_ "):
                    regexp = re.compile(r"^BA_ +\"(.*?)\" +BU_ +(\w+) +(.+) *; *")
                    temp = regexp.match(decoded)
                    db.ecu_by_name(
                        temp.group(2)).add_attribute(
                        temp.group(1),
                        temp.group(3))
                else:
                    regexp = re.compile(
                        r"^BA_ +\"([A-Za-z0-9\-_]+)\" +([\"\w\-\.]+) *; *")
                    temp = regexp.match(decoded)
                    if temp:
                        db.add_attribute(temp.group(1), temp.group(2))

            elif decoded.startswith("SIG_GROUP_ "):
                regexp = re.compile(r"^SIG_GROUP_ +(\w+) +(\w+) +(\w+) +\:(.*) *; *")
                temp = regexp.match(decoded)
                frame = get_frame_by_id(canmatrix.ArbitrationId.from_compound_integer(int(temp.group(1))))
                if frame is not None:
                    signal_array = temp.group(4).split(' ')
                    frame.add_signal_group(temp.group(2), temp.group(3), signal_array)  # todo wrong annotation in canmatrix? Id is a string?

            elif decoded.startswith("SIG_VALTYPE_ "):
                regexp = re.compile(r"^SIG_VALTYPE_ +(\w+) +(\w+)\s*\:(.*) *; *")
                temp = regexp.match(decoded)
                frame = get_frame_by_id(canmatrix.ArbitrationId.from_compound_integer(int(temp.group(1))))
                if frame:
                    signal = frame.signal_by_name(temp.group(2))
                    signal.is_float = True
    #                SIG_VALTYPE_ 0 float : 1;

            elif decoded.startswith("BA_DEF_DEF_ "):
                pattern = r"^BA_DEF_DEF_ +\"(.+?)\" +(.+?) *;"
                regexp = re.compile(pattern)
                regexp_raw = re.compile(pattern.encode(dbc_import_encoding))
                temp = regexp.match(decoded)
                temp_raw = regexp_raw.match(l)
                if temp:
                    db.add_define_default(temp.group(1),
                                          temp_raw.group(2).decode(dbc_import_encoding))
            elif decoded.startswith("SG_MUL_VAL_ "):
                pattern = r"^SG_MUL_VAL_ +([0-9]+) +([\w\-]+) +([\w\-]+) +(.*) *; *"
                regexp = re.compile(pattern)
                temp = regexp.match(decoded)
                if temp:
                    frame_id = temp.group(1)
                    signal_name = temp.group(2)
                    muxer_for_signal = temp.group(3)
                    mux_val_groups = temp.group(4).split(',')
                    frame = get_frame_by_id(canmatrix.ArbitrationId.from_compound_integer(int(frame_id)))
                    if frame is not None:
                        signal = frame.signal_by_name(signal_name)
                        frame.is_complex_multiplexed = True
                        signal.muxer_for_signal = muxer_for_signal
                        for muxVal in mux_val_groups:
                            mux_val_min, mux_val_max = muxVal.split("-")
                            mux_val_min_number = int(mux_val_min)
                            mux_val_max_number = int(mux_val_max)
                            signal.mux_val_grp.append([mux_val_min_number, mux_val_max_number])
            elif decoded.startswith("EV_ "):
                pattern = r"^EV_ +([\w\-\_]+?) *\: +([0-9]+) +\[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] +\"(.*?)\" +([0-9.+\-eE]+) +([0-9.+\-eE]+) +([\w\-]+?) +(.*); *"
                regexp = re.compile(pattern)
                temp = regexp.match(decoded)

                var_name = temp.group(1)
                var_type = temp.group(2)
                min_value = temp.group(3)
                max_value = temp.group(4)
                unit = temp.group(5)
                initial_value = temp.group(6)
                ev_id = temp.group(7)
                access_type = temp.group(8)
                access_nodes = temp.group(9).split(",")
                db.add_env_var(var_name, {"varType": var_type, "min": min_value, "max": max_value, "unit": unit,
                                          "initialValue": initial_value, "evId": ev_id, "accessType": access_type,
                                          "accessNodes": access_nodes})

        # else:
        except:
            print("error with line no: %d" % i)
            print(line)
# Backtracking
    env_var_names = list(db.env_vars.keys())
    for env_var_name in env_var_names:
        env_var = db.env_vars[env_var_name]
        if 'SystemEnvVarLongSymbol' in env_var.get("attributes", ""):
            long_name = env_var["attributes"]["SystemEnvVarLongSymbol"][1:-1]
            del(env_var["attributes"]["SystemEnvVarLongSymbol"])
            db.env_vars[long_name] = db.env_vars.pop(env_var_name)
    for ecu in db.ecus:
        if ecu.attributes.get("SystemNodeLongSymbol", None) is not None:
            ecu.name = ecu.attributes.get("SystemNodeLongSymbol")[1:-1]
            ecu.del_attribute("SystemNodeLongSymbol")
    for frame in db.frames:
        frame.cycle_time = int(float(frame.attributes.get("GenMsgCycleTime", 0)))
        if frame.attributes.get("SystemMessageLongSymbol", None) is not None:
            frame.name = frame.attributes.get("SystemMessageLongSymbol")[1:-1]
            frame.del_attribute("SystemMessageLongSymbol")
        # receiver is only given in the signals, so do propagate the receiver
        # to the frame:
        frame.update_receiver()
        # extended-flag is implicit in can id, thus repair this:
        # if frame.id > 0x80000000:
        #     frame.id -= 0x80000000
        #     frame.extended = 1

        for signal in frame.signals:
            signal.initial_value = float_factory(signal.attributes.get("GenSigStartValue", "0"))
            signal.cycle_time = int(signal.attributes.get("GenSigCycleTime", 0))
            if signal.attribute("SystemSignalLongSymbol") is not None:
                signal.name = signal.attribute("SystemSignalLongSymbol")[1:-1]
                signal.del_attribute("SystemSignalLongSymbol")
    for define in db.global_defines:
        if db.global_defines[define].type == "STRING":
            if define in db.attributes:
                db.attributes[define] = db.attributes[define][1:-1]
    for define in db.ecu_defines:
        if db.ecu_defines[define].type == "STRING":
            for ecu in db.ecus:
                if define in ecu.attributes:
                    ecu.attributes[define] = ecu.attributes[define][1:-1]
    for define in db.frame_defines:
        if db.frame_defines[define].type == "STRING":
            for frame in db.frames:
                if define in frame.attributes:
                    frame.attributes[define] = frame.attributes[define][1:-1]
    for define in db.signal_defines:
        if db.signal_defines[define].type == "STRING":
            for frame in db.frames:
                for signal in frame.signals:
                    if define in signal.attributes:
                        signal.attributes[define] = signal.attributes[define][1:-1]

    db.enum_attribs_to_values()
    for frame in db.frames:
        if "_FD" in frame.attributes.get("VFrameFormat", ""):
            frame.is_fd = True
        if "J1939PG" in frame.attributes.get("VFrameFormat", ""):
            frame.is_j1939 = True
    db.update_ecu_list()
    db.del_ecu("Vector__XXX")

#    db.del_frame_attributes(["GenMsgCycleTime"])
#    db.del_signal_attributes(["GenSigCycleTime"])
#    db.del_signal_attributes(["GenSigStartValue"])
#    if "GenMsgCycleTime" in db.frame_defines:
#        del (db.frame_defines["GenMsgCycleTime"])
#    if "GenSigCycleTime" in db.signal_defines:
#        del (db.signal_defines["GenSigCycleTime"])
#    if "GenSigStartValue" in db.signal_defines:
#        del (db.signal_defines["GenSigStartValue"])

    free_signals_dummy_frame = db.frame_by_name("VECTOR__INDEPENDENT_SIG_MSG")
    if free_signals_dummy_frame is not None and free_signals_dummy_frame.arbitration_id.id == 0x40000000:
        db.signals = free_signals_dummy_frame.signals
        db.del_frame(free_signals_dummy_frame)

    return db
Example #2
0
            attributes={},
            comment="",
        )

        # Add signals
        start_bit = 0
        for signal in frame_data["signals"]:
            # print(f"    Decoding signal {signal["name"]} ...")
            sig = canmatrix.Signal(
                name=signal["name"],
                start_bit=start_bit,
                size=signal["length"],
                is_float=False,
                is_little_endian=False,
                is_signed=False,
                factor=signal["scale"],
                offset=signal["offset"],
                min=signal["min"],
                max=signal["max"],
                receivers=[""],
            )
            start_bit += signal["length"]
            frame.add_signal(sig)
        frame.calc_dlc()

    dbc.add_frame(frame)

    dbc.add_ecu(canmatrix.Ecu(name=file.replace(".yaml", ""),
                              comment="potato"))

canmatrix.canmatrix.formats.dumpp({"": dbc}, "dbcs/dash.dbc")
Example #3
0
def load(f,
         **options):  # type: (typing.IO, **typing.Any) -> canmatrix.CanMatrix
    dbf_import_encoding = options.get("dbfImportEncoding", 'iso-8859-1')
    float_factory = options.get('float_factory', default_float_factory)
    is_j1939 = False
    db = canmatrix.CanMatrix()

    mode = ''
    for line in f:
        line = line.decode(dbf_import_encoding).strip()

        if mode == 'SignalDescription':
            if line.startswith("[END_DESC_SIG]") or line.startswith(
                    "[END_DESC]"):
                mode = ''
            else:
                (bo_id, tem_s, signal_name, comment) = line.split(' ', 3)
                comment = comment.replace('"', '').replace(';', '')
                db.frame_by_id(
                    canmatrix.ArbitrationId.from_compound_integer(
                        int(bo_id))).signal_by_name(signal_name).add_comment(
                            comment)

        if mode == 'BUDescription':
            if line.startswith("[END_DESC_NODE]") or line.startswith(
                    "[END_DESC]"):
                mode = ''
            else:
                (bu_name, comment) = line.split(' ', 1)
                comment = comment.replace('"', '').replace(';', '')
                db.ecu_by_name(bu_name).add_comment(comment)

        if mode == 'FrameDescription':
            if line.startswith("[END_DESC_MSG]") or line.startswith(
                    "[END_DESC]"):
                mode = ''
            else:
                (bo_id, tem_s, comment) = line.split(' ', 2)
                comment = comment.replace('"', '').replace(';', '')
                frame = db.frame_by_id(
                    canmatrix.ArbitrationId.from_compound_integer(int(bo_id)))
                if frame:
                    frame.add_comment(comment)

        elif mode == 'ParamMsgVal':
            if line.startswith("[END_PARAM_MSG_VAL]"):
                mode = ''
            else:
                (bo_id, tem_s, attrib, value) = line.split(',', 3)
                db.frame_by_id(
                    canmatrix.ArbitrationId.from_compound_integer(
                        int(bo_id))).add_attribute(attrib.replace('"', ''),
                                                   value.replace('"', ''))

        elif mode == 'ParamNodeVal':
            if line.startswith("[END_PARAM_NODE_VAL]"):
                mode = ''
            else:
                (bu, attrib, value) = line.split(',', 2)
                db.ecu_by_name(bu).add_attribute(attrib.replace('"', ''),
                                                 value[1:-1])

        elif mode == 'ParamNetVal':
            if line.startswith("[END_PARAM_NET_VAL]"):
                mode = ''
            else:
                (attrib, value) = line.split(',', 1)
                db.add_attribute(attrib.replace('"', ''), value[1:-1])

        elif mode == 'ParamSigVal':
            if line.startswith("[END_PARAM_SIG_VAL]"):
                mode = ''
            else:
                (bo_id, tem_s, signal_name, attrib, value) = line.split(',', 4)
                db.frame_by_id(canmatrix.ArbitrationId.from_compound_integer(int(bo_id)))\
                    .signal_by_name(signal_name)\
                    .add_attribute(attrib.replace('"', ''), value[1:-1])

        elif mode == 'ParamSig':
            if line.startswith("[END_PARAM_SIG]"):
                mode = ''
            else:
                (name, define, default) = decode_define(line)
                db.add_signal_defines(name, define)
                db.add_define_default(name, default)

        elif mode == 'ParamMsg':
            if line.startswith("[END_PARAM_MSG]"):
                mode = ''
            else:
                (name, define, default) = decode_define(line)
                db.add_frame_defines(name, define)
                db.add_define_default(name, default)

        elif mode == 'ParamNode':
            if line.startswith("[END_PARAM_NODE]"):
                mode = ''
            else:
                (name, define, default) = decode_define(line)
                db.add_ecu_defines(name, define)
                db.add_define_default(name, default)

        elif mode == 'ParamNet':
            if line.startswith("[END_PARAM_NET]"):
                mode = ''
            else:
                (name, define, default) = decode_define(line)
                db.add_global_defines(name, define)
                db.add_define_default(name, default)

        else:
            if line.startswith("[PROTOCOL]") and "J1939" in line:
                is_j1939 = True
            if line.startswith("[START_DESC_SIG]"):
                mode = 'SignalDescription'

            if line.startswith("[START_DESC_MSG]"):
                mode = 'FrameDescription'

            if line.startswith("[START_DESC_NODE]"):
                mode = 'BUDescription'

            if line.startswith("[START_PARAM_NODE_VAL]"):
                mode = 'ParamNodeVal'

            if line.startswith("[START_PARAM_NET_VAL]"):
                mode = 'ParamNetVal'

            if line.startswith("[START_PARAM_MSG_VAL]"):
                mode = 'ParamMsgVal'

            if line.startswith("[START_PARAM_SIG_VAL]"):
                mode = 'ParamSigVal'

            if line.startswith("[START_PARAM_SIG]"):
                mode = 'ParamSig'
            if line.startswith("[START_PARAM_MSG]"):
                mode = 'ParamMsg'
            if line.startswith("[START_PARAM_NODE]"):
                mode = 'ParamNode'
            if line.startswith("[START_PARAM_NET]"):
                mode = 'ParamNet'

            if line.startswith("[START_MSG]"):
                temp_str = line.strip()[11:].strip()
                temp_array = temp_str.split(',')
                (name, arb_id, size, n_signals, dummy) = temp_array[0:5]
                if len(temp_array) > 5:
                    extended = temp_array[5]
                else:
                    extended = None
                if len(temp_array) > 6:
                    transmitters = temp_array[6].split()
                else:
                    transmitters = list()
                new_frame = db.add_frame(
                    canmatrix.Frame(name,
                                    size=int(size),
                                    transmitters=transmitters))

                if is_j1939:
                    new_frame.arbitration_id.pgn = int(arb_id)
                else:
                    new_frame.arbitration_id = canmatrix.ArbitrationId.from_compound_integer(
                        int(arb_id))
                #   Frame(int(Id), name, size, transmitter))
                if extended == 'X':
                    logger.debug("Extended")
                    new_frame.arbitration_id.extended = True

            if line.startswith("[NODE]"):
                temp_str = line.strip()[6:].strip()
                bo_list = temp_str.split(',')
                for bo in bo_list:
                    db.add_ecu(canmatrix.Ecu(bo))

            if line.startswith("[START_SIGNALS]"):
                temp_str = line.strip()[15:].strip()
                temp_array = temp_str.split(',')
                (name, size, start_byte, start_bit, sign, max_val, min_val,
                 byteorder, offset, factor, unit, multiplex) = temp_array[0:12]
                min_val = float_factory(min_val)
                max_val = float_factory(max_val)
                factor = float_factory(factor)
                offset = float_factory(offset)

                if len(temp_array) > 12:
                    receiver = temp_array[12].split(',')
                else:
                    receiver = []

                if multiplex == 'M':
                    multiplex = 'Multiplexor'
                elif len(multiplex.strip()) > 0:
                    multiplex = int(multiplex[1:])
                else:
                    multiplex = None

                is_float = False
                is_signed = False

                if sign == "U":
                    is_signed = False
                elif sign == "F" or sign == "D":
                    is_float = True
                else:
                    is_signed = True
                start_bit = int(start_bit)
                start_bit += (int(start_byte) - 1) * 8

                new_signal = new_frame.add_signal(
                    canmatrix.Signal(name,
                                     start_bit=int(start_bit),
                                     size=int(size),
                                     is_little_endian=(int(byteorder) == 1),
                                     is_signed=is_signed,
                                     factor=factor,
                                     offset=offset,
                                     min=min_val * factor,
                                     max=max_val * factor,
                                     unit=unit,
                                     receivers=receiver,
                                     is_float=is_float,
                                     multiplex=multiplex))

                if int(byteorder) == 0:
                    # this is dummy here, because internal lsb is default - for now
                    new_signal.set_startbit(start_bit,
                                            bitNumbering=1,
                                            startLittle=True)

            if line.startswith("[VALUE_DESCRIPTION]"):
                temp_str = line.strip()[19:].strip()
                regexp = re.compile("\"(.+)\" *, *(.+)")
                temp = regexp.match(temp_str)

                if temp:
                    new_signal.add_values(value=temp.group(2),
                                          valueName=temp.group(1))

        for frame in db.frames:
            # receiver is only given in the signals, so do propagate the receiver to the frame:
            frame.update_receiver()
    db.enum_attribs_to_values()
    free_signals_dummy_frame = db.frame_by_name("VECTOR__INDEPENDENT_SIG_MSG")
    if free_signals_dummy_frame is not None and free_signals_dummy_frame.arbitration_id == 0x40000000:
        db.signals = free_signals_dummy_frame.signals
        db.del_frame(free_signals_dummy_frame)
    return db
Example #4
0
def load(f, **options):
    # type: (typing.IO, **typing.Any) -> typing.Dict[str, canmatrix.CanMatrix]
    float_factory = options.get("float_factory",
                                default_float_factory)  # type: typing.Callable
    dbs = {}  # type: typing.Dict[str, canmatrix.CanMatrix]
    tree = etree.parse(f)
    root = tree.getroot()
    namespace = "{" + tree.xpath('namespace-uri(.)') + "}"

    node_list = {}
    nodes = root.findall('./' + namespace + 'Node')
    buses = root.findall('./' + namespace + 'Bus')

    counter = 0
    for bus in buses:
        db = canmatrix.CanMatrix()
        db.add_frame_defines("GenMsgCycleTime", 'INT 0 65535')
        for node in nodes:
            db.ecus.append(canmatrix.Ecu(node.get('name')))
            node_list[node.get('id')] = node.get('name')

        messages = bus.findall('./' + namespace + 'Message')

        for message in messages:
            dlc = None
            # new_frame = Frame(int(message.get('id'), 16), message.get('name'), 1, None)
            new_frame = canmatrix.Frame(message.get('name'))

            if 'triggered' in message.attrib:
                new_frame.add_attribute("GenMsgCycleTime",
                                        message.get('interval'))

            if 'length' in message.attrib:
                dlc = int(message.get('length'))
                new_frame.size = dlc

            if 'format' in message.attrib and message.get(
                    'format') == "extended":
                new_frame.arbitration_id = canmatrix.ArbitrationId(
                    int(message.get('id'), 16), extended=True)
            else:
                new_frame.arbitration_id = canmatrix.ArbitrationId(
                    int(message.get('id'), 16), extended=False)

            multiplex = message.find('./' + namespace + 'Multiplex')
            if multiplex is not None:
                start_bit = 0
                if 'offset' in multiplex.attrib:
                    start_bit = int(multiplex.get('offset'))

                signal_size = 1
                if 'length' in multiplex.attrib:
                    signal_size = int(multiplex.get('length'))

                is_little_endian = True

                min_value = None
                max_value = None
                values = multiplex.find('./' + namespace + 'Value')
                if values is not None:
                    if 'min' in values.attrib:
                        min_value = float_factory(values.get('min'))
                    if 'max' in values.attrib:
                        max_value = float_factory(values.get('max'))

                unit = ""
                offset = float_factory('0')
                factor = float_factory('1')
                is_signed = False
                if 'type' in multiplex.attrib:
                    if multiplex.get('type') == 'signed':
                        is_signed = True

                receiver_names = []  # type: typing.List[str]
                consumers = multiplex.findall('./' + namespace + 'Consumer')
                for consumer in consumers:
                    node_refs = consumer.findall('./' + namespace + 'NodeRef')
                    for node_ref in node_refs:
                        receiver_names.append(node_list[node_ref.get('id')])
                new_signal = canmatrix.Signal(
                    multiplex.get('name'),
                    start_bit=int(start_bit),
                    size=int(signal_size),
                    is_little_endian=is_little_endian,
                    is_signed=is_signed,
                    factor=factor,
                    offset=offset,
                    unit=unit,
                    receivers=receiver_names,
                    multiplex='Multiplexor')

                if min_value is not None:
                    new_signal.min = min_value
                if max_value is not None:
                    new_signal.max = max_value

                if is_little_endian is False:
                    # motorola/big_endian set/convert startbit
                    new_signal.set_startbit(start_bit)
                notes = multiplex.findall('./' + namespace + 'Notes')
                comment = ""
                for note in notes:
                    comment += note.text
                new_signal.add_comment(comment)

                label_sets = multiplex.findall('./' + namespace + 'LabelSet')
                for label_set in label_sets:
                    labels = label_set.findall('./' + namespace + 'Label')
                    for label in labels:
                        name = label.get('name')
                        value = label.get('value')
                        new_signal.add_values(value, name)

                new_frame.add_signal(new_signal)

                mux_groups = multiplex.findall('./' + namespace + 'MuxGroup')
                for mux_group in mux_groups:
                    mux = mux_group.get('count')
                    signals = mux_group.findall('./' + namespace + 'Signal')
                    for signal in signals:
                        new_signal = parse_signal(signal, mux, namespace,
                                                  node_list, float_factory)
                        new_frame.add_signal(new_signal)

            signals = message.findall('./' + namespace + 'Signal')

            producers = message.findall('./' + namespace + 'Producer')
            for producer in producers:
                node_refs = producer.findall('./' + namespace + 'NodeRef')
                for node_ref in node_refs:
                    new_frame.add_transmitter(node_list[node_ref.get('id')])
            for signal in signals:
                new_signal = parse_signal(signal, None, namespace, node_list,
                                          float_factory)
                new_frame.add_signal(new_signal)

            notes = message.findall('./' + namespace + 'Notes')
            comment = ""
            for note in notes:
                if note.text is not None:
                    comment += note.text
            new_frame.add_comment(comment)

            if dlc is None:
                new_frame.calc_dlc()
            else:
                new_frame.size = dlc

            new_frame.update_receiver()
            db.add_frame(new_frame)
        name = bus.get('name')
        if not name:
            name = "CAN%d" % counter
            counter += 1
        dbs[name] = db
    return dbs
            comment="add comment here",
        )

        # Add signals
        start_bit = 0
        for signal_name, signal_data in frame_data["signals"].items():
            sig = canmatrix.Signal(
                name=signal_name,
                start_bit=start_bit,
                size=signal_data["length"],
                is_float=False,
                is_little_endian=False,
                is_signed=False,
                factor=signal_data["scale"],
                offset=signal_data["offset"],
                min=signal_data["min"],
                max=signal_data["max"],
                receivers=[rec_vals],
            )
            start_bit += signal_data["length"]
            frame.add_signal(sig)

        frame.calc_dlc()

    dbc.add_frame(frame)

    dbc.add_ecu(
        canmatrix.Ecu(name=board_name, comment="more comments can go here"))

canmatrix.canmatrix.formats.dumpp({"": dbc}, "dbcs/dash.dbc")
Example #6
0
def load(filename, **options):
    # type: (typing.BinaryIO, **str) -> canmatrix.CanMatrix
    # use xlrd excel reader if available, because its more robust
    if options.get('xlsxLegacy', False) is True:
        logger.error("xlsx: using legacy xlsx-reader - please get xlrd working for better results!")
    else:
        import canmatrix.formats.xls as xls_loader  # we need alias, otherwise we hide the globally imported canmatrix
        return xls_loader.load(filename, **options)

    # else use this hack to read xlsx
    motorola_bit_format = options.get("xlsMotorolaBitFormat", "msbreverse")

    sheet = read_xlsx(filename, sheet=1, header=True)
    db = canmatrix.CanMatrix()
    all_letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    letter_index = list(all_letters)
    letter_index += ["%s%s" % (a, b) for a in all_letters for b in all_letters]

    # Defines not imported...
    db.add_frame_defines("GenMsgDelayTime", 'INT 0 65535')
    db.add_frame_defines("GenMsgCycleTimeActive", 'INT 0 65535')
    db.add_frame_defines("GenMsgNrOfRepetitions", 'INT 0 65535')
    launch_types = []  # type: typing.List[str]

    db.add_signal_defines("GenSigSNA", 'STRING')

    ecu_start = ecu_end = 0
    if 'Byteorder' in list(sheet[0].values()):
        for key in sheet[0]:
            if sheet[0][key].strip() == 'Byteorder':
                ecu_start = letter_index.index(key) + 1
                break
    else:
        for key in sheet[0]:
            if sheet[0][key].strip() == 'Signal Not Available':
                ecu_start = letter_index.index(key) + 1

    for key in sheet[0]:
        if sheet[0][key].strip() == 'Value':
            ecu_end = letter_index.index(key)

    # ECUs:
    for x in range(ecu_start, ecu_end):
        db.add_ecu(canmatrix.Ecu(sheet[0][letter_index[x]]))

    # initialize:
    frame_id = None
    signal_name = ""
    signal_length = 8
    new_frame = None  # type: typing.Optional[canmatrix.Frame]
    new_signal = None  # type: typing.Optional[canmatrix.Signal]

    for row in sheet[1]:
        # ignore empty row
        if 'ID' not in row:
            continue
        # new frame detected
        if row['ID'] != frame_id:
            # new Frame
            frame_id = row['ID']
            frame_name = row['Frame Name']
            cycle_time = get_if_possible(row, 'Cycle Time [ms]', '0')
            launch_type = get_if_possible(row, 'Launch Type')
            dlc = 8
            # launch_param = get_if_possible(row, 'Launch Parameter', '0')
            # launch_param = str(int(launch_param))

            if frame_id.endswith("xh"):
                new_frame = canmatrix.Frame(frame_name, arbitration_id=int(frame_id[:-2], 16), size=dlc)
                new_frame.arbitration_id.extended = True
            else:
                new_frame = canmatrix.Frame(frame_name, arbitration_id=int(frame_id[:-1], 16), size=dlc)

            db.add_frame(new_frame)

            # eval launch_type
            if launch_type is not None:
                new_frame.add_attribute("GenMsgSendType", launch_type)
                if launch_type not in launch_types:
                    launch_types.append(launch_type)

            new_frame.cycle_time = cycle_time

        # new signal detected
        if 'Signal Name' in row and row['Signal Name'] != signal_name:
            receiver = []  # type: typing.List[str]
            start_byte = int(row["Signal Byte No."])
            start_bit = int(row['Signal Bit No.'])
            signal_name = row['Signal Name']
            signal_comment = get_if_possible(row, 'Signal Function')
            signal_length = int(row['Signal Length [Bit]'])
            # signal_default = get_if_possible(row, 'Signal Default')
            # signal_sna = get_if_possible(row, 'Signal Not Available')
            multiplex = None  # type: typing.Union[str, int, None]
            if signal_comment is not None and signal_comment.startswith('Mode Signal:'):
                multiplex = 'Multiplexor'
                signal_comment = signal_comment[12:]
            elif signal_comment is not None and signal_comment.startswith('Mode '):
                mux, signal_comment = signal_comment[4:].split(':', 1)
                multiplex = int(mux.strip())

            signal_byte_order = get_if_possible(row, 'Byteorder')
            if signal_byte_order is not None:
                if 'i' in signal_byte_order:
                    is_little_endian = True
                else:
                    is_little_endian = False
            else:
                is_little_endian = True  # Default Intel

            is_signed = False

            if signal_name != "-":
                for x in range(ecu_start, ecu_end):
                    ecu_name = sheet[0][letter_index[x]].strip()
                    ecu_sender_receiver = get_if_possible(row, ecu_name)
                    if ecu_sender_receiver is not None:
                        if 's' in ecu_sender_receiver:
                            new_frame.add_transmitter(ecu_name)
                        if 'r' in ecu_sender_receiver:
                            receiver.append(ecu_name)
                new_signal = canmatrix.Signal(signal_name,
                                              start_bit=(start_byte - 1) * 8 + start_bit,
                                              size=signal_length,
                                              is_little_endian=is_little_endian,
                                              is_signed=is_signed,
                                              receivers=receiver,
                                              multiplex=multiplex)
                if not is_little_endian:
                    # motorola
                    if motorola_bit_format == "msb":
                        new_signal.set_startbit(
                            (start_byte - 1) * 8 + start_bit, bitNumbering=1)
                    elif motorola_bit_format == "msbreverse":
                        new_signal.set_startbit((start_byte - 1) * 8 + start_bit)
                    else:  # motorola_bit_format == "lsb"
                        new_signal.set_startbit(
                            (start_byte - 1) * 8 + start_bit,
                            bitNumbering=1,
                            startLittle=True
                        )
                new_frame.add_signal(new_signal)
                new_signal.add_comment(signal_comment)
                # function = get_if_possible(row, 'Function / Increment Unit')
        value = get_if_possible(row, 'Value')
        value_name = get_if_possible(row, 'Name / Phys. Range')

        if value_name == 0 or value_name is None:
            value_name = "0"
        elif value_name == 1:
            value_name = "1"
        test = value_name
        # .encode('utf-8')

        factor = get_if_possible(row, 'Function / Increment Unit')
        if factor is not None:
            factor = factor.strip()
            if " " in factor and factor[0].isdigit():
                (factor, unit) = factor.split(" ", 1)
                factor = factor.strip()
                unit = unit.strip()
                new_signal.unit = unit
                new_signal.factor = float(factor)
            else:
                unit = factor.strip()
                new_signal.unit = unit
                new_signal.factor = 1

        if ".." in test:
            (mini, maxi) = test.strip().split("..", 2)
            try:
                new_signal.offset = new_signal.float_factory(mini)
                new_signal.min = new_signal.float_factory(mini)
                new_signal.max = new_signal.float_factory(maxi)
            except ValueError:
                new_signal.offset = 0
                new_signal.min = None
                new_signal.max = None

        elif len(value_name) > 0:
            if value is not None and value.strip():
                value_int = int(float(value))
                new_signal.add_values(value_int, value_name)
            maxi = pow(2, signal_length) - 1
            new_signal.max = float(maxi)
        else:
            new_signal.offset = 0
            new_signal.min = None
            new_signal.max = None

    # dlc-estimation / dlc is not in xls, thus calculate a minimum-dlc:
    for frame in db.frames:
        frame.update_receiver()
        frame.calc_dlc()

    launch_type_enum = "ENUM"
    for launch_type in launch_types:
        if len(launch_type) > 0:
            launch_type_enum += ' "' + launch_type + '",'
    db.add_frame_defines("GenMsgSendType", launch_type_enum[:-1])

    db.set_fd_type()
    return db
Example #7
0
def load(file, **options):
    # type: (typing.IO, **typing.Any) -> canmatrix.CanMatrix
    motorola_bit_format = options.get("xlsMotorolaBitFormat", "msbreverse")
    float_factory = options.get("float_factory", default_float_factory)

    additional_inputs = dict()
    wb = xlrd.open_workbook(file_contents=file.read())
    sh = wb.sheet_by_index(0)
    db = canmatrix.CanMatrix()

    # Defines not imported...
    # db.add_ecu_defines("NWM-Stationsadresse", 'HEX 0 63')
    # db.add_ecu_defines("NWM-Knoten", 'ENUM  "nein","ja"')
    db.add_frame_defines("GenMsgCycleTime", 'INT 0 65535')
    db.add_frame_defines("GenMsgDelayTime", 'INT 0 65535')
    db.add_frame_defines("GenMsgCycleTimeActive", 'INT 0 65535')
    db.add_frame_defines("GenMsgNrOfRepetitions", 'INT 0 65535')
    # db.addFrameDefines("GenMsgStartValue",  'STRING')
    launch_types = []  # type: typing.List[str]
    # db.addSignalDefines("GenSigStartValue", 'HEX 0 4294967295')
    db.add_signal_defines("GenSigSNA", 'STRING')

    # eval search for correct columns:
    index = {}
    for i in range(sh.ncols):
        value = sh.cell(0, i).value
        if value == "ID":
            index['ID'] = i
        elif "Frame Name" in value:
            index['frameName'] = i
        elif "Cycle" in value:
            index['cycle'] = i
        elif "Launch Type" in value:
            index['launchType'] = i
        elif "Launch Parameter" in value:
            index['launchParam'] = i
        elif "Signal Byte No." in value:
            index['startbyte'] = i
        elif "Signal Bit No." in value:
            index['startbit'] = i
        elif "Signal Name" in value:
            index['signalName'] = i
        elif "Signal Function" in value:
            index['signalComment'] = i
        elif "Signal Length" in value:
            index['signalLength'] = i
        elif "Signal Default" in value:
            index['signalDefault'] = i
        elif "Signal Not Ava" in value:
            index['signalSNA'] = i
        elif "Value" in value:
            index['Value'] = i
        elif "Name / Phys" in value:
            index['ValueName'] = i
        elif "Function /" in value:
            index['function'] = i
        elif "Byteorder" in value:
            index['byteorder'] = i
        else:
            if 'Value' in index and i > index['Value']:
                additional_inputs[i] = value

    if "byteorder" in index:
        index['ECUstart'] = index['byteorder'] + 1
    else:
        index['ECUstart'] = index['signalSNA'] + 1
    index['ECUend'] = index['Value']

    # ECUs:
    for x in range(index['ECUstart'], index['ECUend']):
        db.add_ecu(canmatrix.Ecu(sh.cell(0, x).value))

    # initialize:
    frame_id = None
    signal_name = ""
    new_frame = None

    for row_num in range(1, sh.nrows):
        # ignore empty row
        if len(sh.cell(row_num, index['ID']).value) == 0:
            break
        # new frame detected
        if sh.cell(row_num, index['ID']).value != frame_id:
            # new Frame
            frame_id = sh.cell(row_num, index['ID']).value
            frame_name = sh.cell(row_num, index['frameName']).value
            cycle_time = sh.cell(row_num, index['cycle']).value
            launch_type = sh.cell(row_num, index['launchType']).value
            dlc = 8
            launch_param = sh.cell(row_num, index['launchParam']).value
            try:
                launch_param = str(int(launch_param))
            except:
                launch_param = "0"

            new_frame = canmatrix.Frame(frame_name, size=dlc)
            if frame_id.endswith("xh"):
                new_frame.arbitration_id = canmatrix.ArbitrationId(
                    int(frame_id[:-2], 16), extended=True)
            else:
                new_frame.arbitration_id = canmatrix.ArbitrationId(
                    int(frame_id[:-2], 16), extended=False)
            db.add_frame(new_frame)

            # eval launch_type
            if launch_type is not None:
                new_frame.add_attribute("GenMsgSendType", launch_type)
                if launch_type not in launch_types:
                    launch_types.append(launch_type)

            # eval cycle time
            try:
                cycle_time = int(cycle_time)
            except:
                cycle_time = 0
            new_frame.add_attribute("GenMsgCycleTime", str(int(cycle_time)))

            for additional_index in additional_inputs:
                if "frame" in additional_inputs[additional_index]:
                    command_str = additional_inputs[additional_index].replace(
                        "frame", "new_frame")
                    command_str += "="
                    command_str += str(
                        sh.cell(row_num, additional_index).value)
                    exec(command_str)

        # new signal detected
        if sh.cell(row_num, index['signalName']).value != signal_name \
                and len(sh.cell(row_num, index['signalName']).value) > 0:
            # new Signal
            receiver = []
            start_byte = int(sh.cell(row_num, index['startbyte']).value)
            start_bit = int(sh.cell(row_num, index['startbit']).value)
            signal_name = sh.cell(row_num, index['signalName']).value
            signal_comment = sh.cell(row_num,
                                     index['signalComment']).value.strip()
            signal_length = int(sh.cell(row_num, index['signalLength']).value)
            signal_default = sh.cell(row_num, index['signalDefault']).value
            signal_sna = sh.cell(row_num, index['signalSNA']).value
            multiplex = None  # type: typing.Union[str, int, None]
            if signal_comment.startswith('Mode Signal:'):
                multiplex = 'Multiplexor'
                signal_comment = signal_comment[12:]
            elif signal_comment.startswith('Mode '):
                mux, signal_comment = signal_comment[4:].split(':', 1)
                multiplex = int(mux.strip())

            if index.get("byteorder", False):
                signal_byte_order = sh.cell(row_num, index['byteorder']).value

                if 'i' in signal_byte_order:
                    is_little_endian = True
                else:
                    is_little_endian = False
            else:
                is_little_endian = True  # Default Intel

            is_signed = False

            if signal_name != "-":
                for x in range(index['ECUstart'], index['ECUend']):
                    if 's' in sh.cell(row_num, x).value:
                        new_frame.add_transmitter(sh.cell(0, x).value.strip())
                    if 'r' in sh.cell(row_num, x).value:
                        receiver.append(sh.cell(0, x).value.strip())
                new_signal = canmatrix.Signal(
                    signal_name,
                    start_bit=(start_byte - 1) * 8 + start_bit,
                    size=int(signal_length),
                    is_little_endian=is_little_endian,
                    is_signed=is_signed,
                    receivers=receiver,
                    multiplex=multiplex)

                if not is_little_endian:
                    # motorola
                    if motorola_bit_format == "msb":
                        new_signal.set_startbit(
                            (start_byte - 1) * 8 + start_bit, bitNumbering=1)
                    elif motorola_bit_format == "msbreverse":
                        new_signal.set_startbit((start_byte - 1) * 8 +
                                                start_bit)
                    else:  # motorola_bit_format == "lsb"
                        new_signal.set_startbit(
                            (start_byte - 1) * 8 + start_bit,
                            bitNumbering=1,
                            startLittle=True)

                for additional_index in additional_inputs:  # todo explain this possibly dangerous code with eval
                    if "signal" in additional_inputs[additional_index]:
                        command_str = additional_inputs[
                            additional_index].replace("signal", "new_signal")
                        command_str += "="
                        command_str += str(
                            sh.cell(row_num, additional_index).value)
                        if len(str(sh.cell(row_num,
                                           additional_index).value)) > 0:
                            exec(command_str)

                new_frame.add_signal(new_signal)
                new_signal.add_comment(signal_comment)
                function = sh.cell(row_num, index['function']).value

        value = str(sh.cell(row_num, index['Value']).value)
        value_name = sh.cell(row_num, index['ValueName']).value

        if value_name == 0:
            value_name = "0"
        elif value_name == 1:
            value_name = "1"
        # .encode('utf-8')

        unit = ""

        factor = sh.cell(row_num, index['function']).value
        if isinstance(factor, past.builtins.basestring):
            factor = factor.strip()
            if " " in factor and factor[0].isdigit():
                (factor, unit) = factor.strip().split(" ", 1)
                factor = factor.strip()
                unit = unit.strip()
                new_signal.unit = unit
                try:
                    new_signal.factor = float_factory(factor)
                except:
                    logger.warning(
                        "Some error occurred while decoding scale of Signal %s: '%s'",
                        signal_name,
                        sh.cell(row_num, index['function']).value)
            else:
                unit = factor.strip()
                new_signal.unit = unit
                new_signal.factor = 1

        (mini, maxi, offset,
         value_table) = parse_value_name_column(value_name, value,
                                                new_signal.size, float_factory)
        if new_signal.min is None:
            new_signal.min = mini
        if new_signal.max is None:
            new_signal.max = maxi
        if new_signal.offset is None:
            new_signal.offset = offset
        if value_table is not None:
            for value, name in value_table.items():
                new_signal.add_values(value, name)

    for frame in db.frames:
        frame.update_receiver()
        frame.calc_dlc()

    launch_type_enum = "ENUM"
    launch_type_enum += ",".join([
        ' "{}"'.format(launch_type) for launch_type in launch_types
        if launch_type
    ])
    db.add_frame_defines("GenMsgSendType", launch_type_enum)

    db.set_fd_type()
    return db
#!/usr/bin/env python
# coding=utf-8
import codecs
import sys
sys.path.append('..')

import canmatrix
#
# create target Matrix
#

db = canmatrix.CanMatrix()

db.ecus.add(canmatrix.Ecu("testBU"))
db.ecus.add(canmatrix.Ecu("recBU"))

myFrame1 = canmatrix.Frame("canFdStandard1",
                           Id=1,
                           dlc=24,
                           is_fd=True,
                           transmitter=["testBU"])
myFrame2 = canmatrix.Frame("CanFdExtended2",
                           Id=2,
                           dlc=16,
                           extended=True,
                           is_fd=True,
                           transmitter=["testBU"])
myFrame3 = canmatrix.Frame("CanExtended3",
                           Id=3,
                           dlc=8,
                           extended=True,