Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor code for node mapped attributes. #589

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 49 additions & 27 deletions cantools/database/can/formats/dbc.py
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ def get_value(attribute):
return ba


def _dump_attributes_rel(database, sort_signals):
def _dump_attributes_rel(database):
ba_rel = []

def get_value(attribute):
Expand All @@ -854,28 +854,26 @@ def get_value(attribute):

return result

if database.dbc is not None and database.dbc.attributes_rel is not None:
attributes_rel = database.dbc.attributes_rel
for frame_id, element in attributes_rel.items():
if "signal" in element:
for signal_name, signal_lst in element['signal'].items():
for node_name, node_dict in signal_lst['node'].items():
for attribute in node_dict.values():
ba_rel.append(f'BA_REL_ "{attribute.definition.name}" '
f'BU_SG_REL_ '
f'{node_name} '
f'SG_ '
f'{frame_id} '
f'{signal_name} '
f'{get_value(attribute)};')
elif "node" in element:
for node_name, node_dict in element['node'].items():
for message in database.messages:
for signal in message.signals:
if signal.dbc is not None and signal.dbc.attributes_rel is not None:
for node_name, node_dict in signal.dbc.attributes_rel.items():
for attribute in node_dict.values():
ba_rel.append(f'BA_REL_ "{attribute.definition.name}" '
f'BU_BO_REL_ '
f'BU_SG_REL_ '
f'{node_name} '
f'{frame_id} '
f'SG_ '
f'{get_dbc_frame_id(message)} '
f'{signal.name} '
f'{get_value(attribute)};')
if message.dbc is not None and message.dbc.attributes_rel is not None:
for node_name, node_dict in message.dbc.attributes_rel.items():
for attribute in node_dict.values():
ba_rel.append(f'BA_REL_ "{attribute.definition.name}" '
f'BU_BO_REL_ '
f'{node_name} '
f'{get_dbc_frame_id(message)} '
f'{get_value(attribute)};')

return ba_rel

Expand Down Expand Up @@ -1339,7 +1337,8 @@ def _load_signals(tokens,
signal_types,
signal_multiplexer_values,
frame_id_dbc,
multiplexer_signal):
multiplexer_signal,
attributes_rel):
signal_to_multiplexer = {}

try:
Expand All @@ -1361,6 +1360,16 @@ def get_attributes(frame_id_dbc, signal):
except KeyError:
return None

def get_attributes_rel(frame_id_dbc, signal):
"""Get node mapped message attributes for given signal.

"""

try:
return attributes_rel[frame_id_dbc]['signal'][signal]['node']
except KeyError:
return None

def get_comment(frame_id_dbc, signal):
"""Get comment for given signal.

Expand Down Expand Up @@ -1495,7 +1504,8 @@ def get_signal_spn(frame_id_dbc, name):
unit=(None if signal[19] == '' else signal[19]),
spn=get_signal_spn(frame_id_dbc, signal[1][0]),
dbc_specifics=DbcSpecifics(get_attributes(frame_id_dbc, signal[1][0]),
definitions),
definitions,
attributes_rel=get_attributes_rel(frame_id_dbc, signal[1][0])),
comment=get_comment(frame_id_dbc,
signal[1][0]),
is_multiplexer=get_is_multiplexer(signal),
Expand All @@ -1518,7 +1528,8 @@ def _load_messages(tokens,
strict,
bus_name,
signal_groups,
sort_signals):
sort_signals,
attributes_rel):
"""Load messages.

"""
Expand All @@ -1533,6 +1544,15 @@ def get_attributes(frame_id_dbc):
except KeyError:
return None

def get_attributes_rel(frame_id_dbc):
"""Get Node mapped attributes for given message.
"""

try:
return attributes_rel[frame_id_dbc]['node']
except KeyError:
return None

def get_comment(frame_id_dbc):
"""Get comment for given message.

Expand Down Expand Up @@ -1674,7 +1694,8 @@ def get_signal_groups(frame_id_dbc):
signal_types,
signal_multiplexer_values,
frame_id_dbc,
multiplexer_signal)
multiplexer_signal,
attributes_rel)

messages.append(
Message(frame_id=frame_id,
Expand All @@ -1685,7 +1706,8 @@ def get_signal_groups(frame_id_dbc):
send_type=get_send_type(frame_id_dbc),
cycle_time=get_cycle_time(frame_id_dbc),
dbc_specifics=DbcSpecifics(get_attributes(frame_id_dbc),
definitions),
definitions,
attributes_rel = get_attributes_rel(frame_id_dbc)),
signals=signals,
comment=get_comment(frame_id_dbc),
strict=strict,
Expand Down Expand Up @@ -1888,7 +1910,7 @@ def dump_string(database: InternalDatabase,
ba_def_def = _dump_attribute_definition_defaults(database)
ba_def_def_rel = _dump_attribute_definition_defaults_rel(database)
ba = _dump_attributes(database, sort_attribute_signals, sort_attributes)
ba_rel = _dump_attributes_rel(database, sort_attribute_signals)
ba_rel = _dump_attributes_rel(database)
val = _dump_choices(database, sort_attribute_signals, sort_choices)
sig_group = _dump_signal_groups(database)
sig_mux_values = _dump_signal_mux_values(database)
Expand Down Expand Up @@ -2026,15 +2048,15 @@ def load_string(string: str, strict: bool = True,
strict,
bus.name if bus else None,
signal_groups,
sort_signals)
sort_signals,
attributes_rel)
nodes = _load_nodes(tokens, comments, attributes, attribute_definitions)
version = _load_version(tokens)
environment_variables = _load_environment_variables(tokens, comments, attributes)
dbc_specifics = DbcSpecifics(attributes.get('database', None),
attribute_definitions,
environment_variables,
value_tables,
attributes_rel,
attribute_rel_definitions)

return InternalDatabase(messages,
Expand Down
6 changes: 3 additions & 3 deletions cantools/database/can/formats/dbc_specifics.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ def __init__(self,
attribute_definitions=None,
environment_variables=None,
value_tables=None,
attributes_rel=None,
attribute_definitions_rel=None):
attribute_definitions_rel=None,
attributes_rel=None):
if attributes is None:
attributes = OrderedDict()

Expand Down Expand Up @@ -78,7 +78,7 @@ def environment_variables(self):

@property
def attributes_rel(self):
"""The DBC specific attribute rel as dictionary..
"""The DBC specific attribute rel as dictionary.

"""

Expand Down
26 changes: 11 additions & 15 deletions tests/test_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -5908,26 +5908,22 @@ def test_bus_comment_bare(self):
def test_relation_attributes(self):
filename = 'tests/files/dbc/attributes_relation.dbc'
db = cantools.database.load_file(filename)
for _key, frame in db.dbc.attributes_rel.items():
signal = frame.get("signal")
if "signal_1" in signal.keys():
rel_attributes = signal["signal_1"]["node"]["ECU2"]
first_timeout_attr = rel_attributes["SigFirstTimeoutTime"]
timeout_attr = rel_attributes["SigTimeoutTime"]
self.assertEqual(first_timeout_attr.value, 24000)
self.assertEqual(timeout_attr.value, 6000)
break
msg = db.get_message_by_name('Message_1')
sig = msg.get_signal_by_name('signal_1')
rel_attributes = sig.dbc.attributes_rel["ECU2"]
first_timeout_attr = rel_attributes["SigFirstTimeoutTime"]
timeout_attr = rel_attributes["SigTimeoutTime"]
self.assertEqual(first_timeout_attr.value, 24000)
self.assertEqual(timeout_attr.value, 6000)
self.assert_dbc_dump(db, filename)

def test_relation_message_attributes(self):
filename = 'tests/files/dbc/BU_BO_REL_Message.dbc'
db = cantools.database.load_file(filename)
for _key, frame in db.dbc.attributes_rel.items():
node = frame.get("node")
rel_attributes = node["ECU1"]
msg_attr = rel_attributes["MsgProject"]
self.assertEqual(msg_attr.value, 2)
break
msg = db.get_message_by_name('message_1')
rel_attributes = msg.dbc.attributes_rel["ECU1"]
msg_attr = rel_attributes["MsgProject"]
self.assertEqual(msg_attr.value, 2)
self.assert_dbc_dump(db, filename)

def test_cache_prune_choices(self):
Expand Down