[go: nahoru, domu]

Skip to content

Commit

Permalink
Merge pull request cantools#240 from Daimler/multilang_descriptions
Browse files Browse the repository at this point in the history
implement multi-lingual message and signal descriptions
  • Loading branch information
eerimoq committed Dec 1, 2020
2 parents 173ba03 + 3ae062d commit 32bc872
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 49 deletions.
60 changes: 31 additions & 29 deletions cantools/database/can/formats/arxml.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ def __init__(self, root, strict):
self.autosar_version_minor = 0 if m.group(2) is None else int(m.group(2)[1:])
self.autosar_version_patch = 0 if m.group(3) is None else int(m.group(3)[1:])

if self.autosar_version_major != 4 and self.autosar_version_major != 3:
raise ValueError('This class only supports AUTOSAR versions 3 and 4')
if self.autosar_version_major != 4:
raise ValueError('This class only supports AUTOSAR version 4')

self._arxml_reference_cache = {}

Expand Down Expand Up @@ -132,7 +132,7 @@ def _load_message(self, can_frame_triggering):
frame_id = self._load_message_frame_id(can_frame_triggering)
length = self._load_message_length(can_frame)
is_extended_frame = self._load_message_is_extended_frame(can_frame_triggering)
comment = self._load_message_comment(can_frame)
comments = self._load_message_comments(can_frame)

# ToDo: senders

Expand Down Expand Up @@ -181,13 +181,13 @@ def _load_message(self, can_frame_triggering):
send_type=None,
cycle_time=cycle_time,
signals=signals,
comment=comment,
comment=comments,
bus_name=None,
strict=self._strict)

def _load_message_name(self, can_frame_triggering):
return self._get_unique_arxml_child(can_frame_triggering,
"SHORT-NAME").text
'SHORT-NAME').text

def _load_message_frame_id(self, can_frame_triggering):
return int(self._get_unique_arxml_child(can_frame_triggering,
Expand All @@ -205,15 +205,16 @@ def _load_message_is_extended_frame(self, can_frame_triggering):
return False if can_addressing_mode is None \
else can_addressing_mode.text == 'EXTENDED'

def _load_message_comment(self, can_frame):
# This extracts a single language. Support for multi languages
# will be implemented in the near future.
l_2 = self._get_unique_arxml_child(can_frame, ['DESC', 'L-2'])
def _load_message_comments(self, can_frame):
result = {}

if l_2 is not None:
return l_2.text
else:
for l_2 in self._get_arxml_children(can_frame, ['DESC', '*L-2']):
lang = l_2.attrib.get('L', 'EN')
result[lang] = l_2.text

if len(result) == 0:
return None
return result

def _load_signal(self, i_signal_to_i_pdu_mapping):
"""Load given signal and return a signal object.
Expand All @@ -227,7 +228,7 @@ def _load_signal(self, i_signal_to_i_pdu_mapping):
offset = 0
unit = None
choices = None
comment = None
comments = None
receivers = []
decimal = SignalDecimal(Decimal(factor), Decimal(offset))

Expand All @@ -248,7 +249,7 @@ def _load_signal(self, i_signal_to_i_pdu_mapping):
if system_signal is not None:
# Unit and comment.
unit = self._load_signal_unit(system_signal)
comment = self._load_signal_comment(system_signal)
comments = self._load_signal_comments(system_signal)

# Minimum, maximum, factor, offset and choices.
minimum, maximum, factor, offset, choices = \
Expand All @@ -271,7 +272,7 @@ def _load_signal(self, i_signal_to_i_pdu_mapping):
maximum=maximum,
unit=unit,
choices=choices,
comment=comment,
comment=comments,
is_float=is_float,
decimal=decimal)

Expand Down Expand Up @@ -309,15 +310,16 @@ def _load_signal_unit(self, system_signal):

return None if res is None else res.text

def _load_signal_comment(self, system_signal):
# This extracts a single language. Support for multi languages
# will be implemented in the near future.
l_2 = self._get_unique_arxml_child(system_signal, ['DESC', 'L-2'])
def _load_signal_comments(self, system_signal):
result = {}

if l_2 is not None:
return l_2.text
else:
for l_2 in self._get_arxml_children(system_signal, ['DESC', '*L-2']):
lang = l_2.attrib.get('L', 'EN')
result[lang] = l_2.text

if len(result) == 0:
return None
return result

def _load_minimum(self, minimum, decimal):
if minimum is not None:
Expand Down Expand Up @@ -560,7 +562,7 @@ def _get_arxml_children(self, base_elems, children_location):
# CAN cluster, where each conditional, each the physical
# channel and its individual frame triggerings can be
# references
loader.get_arxml_children(can_cluster,
loader._get_arxml_children(can_cluster,
[
'CAN-CLUSTER-VARIANTS',
'*&CAN-CLUSTER-CONDITIONAL',
Expand Down Expand Up @@ -768,7 +770,7 @@ def load_message(self, com_i_pdu):
# Default values.
interval = None
senders = []
comment = None
comments = None

# Name, frame id, length and is_extended_frame.
name = com_i_pdu.find(SHORT_NAME_XPATH, NAMESPACES).text
Expand Down Expand Up @@ -814,7 +816,7 @@ def load_message(self, com_i_pdu):

return None

# ToDo: interval, senders, comment
# ToDo: interval, senders, comments

# Find all signals in this message.
signals = []
Expand Down Expand Up @@ -842,7 +844,7 @@ def load_message(self, com_i_pdu):
send_type=None,
cycle_time=interval,
signals=signals,
comment=comment,
comment=comments,
bus_name=None,
strict=self.strict)

Expand Down Expand Up @@ -896,7 +898,7 @@ def load_signal(self, xpath):
offset = 0
unit = None
choices = None
comment = None
comments = None
receivers = []
decimal = SignalDecimal(Decimal(factor), Decimal(offset))

Expand Down Expand Up @@ -934,7 +936,7 @@ def load_signal(self, xpath):
return None

# ToDo: minimum, maximum, factor, offset, unit, choices,
# comment and receivers.
# comments and receivers.

return Signal(name=name,
start=bit_position,
Expand All @@ -948,7 +950,7 @@ def load_signal(self, xpath):
maximum=maximum,
unit=unit,
choices=choices,
comment=comment,
comment=comments,
is_float=is_float,
decimal=decimal)

Expand Down
38 changes: 34 additions & 4 deletions cantools/database/can/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,19 @@ def __init__(self,
self._length = length
self._signals = signals
self._signals.sort(key=start_bit)
self._comment = comment

# if the 'comment' argument is a string, we assume that is an
# english comment. this is slightly hacky because the
# function's behavior depends on the type of the passed
# argument, but it is quite convenient...
if isinstance(comment, str):
# use the first comment in the dictionary as "The" comment
self._comments = { None: comment }
else:
# assume that we have either no comment at all or a
# multi-lingual dictionary
self._comments = comment

self._senders = senders if senders else []
self._send_type = send_type
self._cycle_time = cycle_time
Expand Down Expand Up @@ -220,13 +232,31 @@ def signal_groups(self, value):
def comment(self):
"""The message comment, or ``None`` if unavailable.
Note that we implicitly try to return the comment's language
to be English comment if multiple languages were specified.
"""
if self._comments is None:
return None
elif self._comments.get(None) is not None:
return self._comments.get(None)

return self._comment
return self._comments.get('EN', None)

@property
def comments(self):
"""The dictionary with the descriptions of the message in multiple languages. ``None`` if unavailable.
"""
return self._comments

@comment.setter
def comment(self, value):
self._comment = value
self._comments = { None: value }

@comments.setter
def comments(self, value):
self._comments = value

@property
def senders(self):
Expand Down Expand Up @@ -910,4 +940,4 @@ def __repr__(self):
self._frame_id,
self._is_extended_frame,
self._length,
"'" + self._comment + "'" if self._comment is not None else None)
self._comments)
39 changes: 35 additions & 4 deletions cantools/database/can/signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,19 @@ def __init__(self,
self._unit = unit
self._choices = choices
self._dbc = dbc_specifics
self._comment = comment

# if the 'comment' argument is a string, we assume that is an
# english comment. this is slightly hacky because the
# function's behavior depends on the type of the passed
# argument, but it is quite convenient...
if isinstance(comment, str):
# use the first comment in the dictionary as "The" comment
self._comments = { None: comment }
else:
# assume that we have either no comment at all or a
# multi-lingual dictionary
self._comments = comment

self._receivers = [] if receivers is None else receivers
self._is_multiplexer = is_multiplexer
self._multiplexer_ids = multiplexer_ids
Expand Down Expand Up @@ -334,13 +346,32 @@ def dbc(self, value):
def comment(self):
"""The signal comment, or ``None`` if unavailable.
Note that we implicitly try to return the comment's language
to be English comment if multiple languages were specified.
"""
if self._comments is None:
return None
elif self._comments.get(None) is not None:
return self._comments.get(None)

return self._comments.get('EN', None)

return self._comment
@property
def comments(self):
"""The dictionary with the descriptions of the signal in multiple
languages. ``None`` if unavailable.
"""
return self._comments

@comment.setter
def comment(self, value):
self._comment = value
self._comments = { None: value }

@comments.setter
def comments(self, value):
self._comments = value

@property
def receivers(self):
Expand Down Expand Up @@ -431,4 +462,4 @@ def __repr__(self):
self._multiplexer_ids,
choices,
self._spn,
"'" + self._comment + "'" if self._comment is not None else None)
self._comments)
9 changes: 8 additions & 1 deletion tests/files/arxml/system-4.2.arxml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@
<ELEMENTS>
<CAN-FRAME>
<SHORT-NAME>Message1</SHORT-NAME>
<DESC><L-2 L="FOR-ALL">Comment1</L-2></DESC>
<DESC>
<L-2 L="EN">Comment1</L-2>
<L-2 L="DE">Kommentar1</L-2>
</DESC>
<FRAME-LENGTH>6</FRAME-LENGTH>
<PDU-TO-FRAME-MAPPINGS>
<PDU-TO-FRAME-MAPPING>
Expand Down Expand Up @@ -289,6 +292,10 @@
<ELEMENTS>
<SYSTEM-SIGNAL>
<SHORT-NAME>Signal1</SHORT-NAME>
<DESC>
<L-2 L="EN">Signal comment!</L-2>
<L-2 L="DE">Signalkommentar!</L-2>
</DESC>
<PHYSICAL-PROPS>
<SW-DATA-DEF-PROPS-VARIANTS>
<SW-DATA-DEF-PROPS-CONDITIONAL>
Expand Down
Loading

0 comments on commit 32bc872

Please sign in to comment.