diff --git a/CHANGELOG.md b/CHANGELOG.md
index d0ec283..bd54e17 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -26,9 +26,10 @@ The name in the parenthesis after each element is the name used in the XML schem
#### XML - Calibration elements
* SwValues | AR:SW-VALUES
-* ValueGroup | VALUE-GROUP
+* ValueGroup | AR:VALUE-GROUP
+* SwAxisCont | AR:SW-AXIS-CONT
-## [v0.5.0]
+## [v0.5.0] - 2023-10-27
### Added
diff --git a/src/autosar/xml/element.py b/src/autosar/xml/element.py
index 6df353a..7e0ea34 100644
--- a/src/autosar/xml/element.py
+++ b/src/autosar/xml/element.py
@@ -2442,6 +2442,29 @@ def __init__(self,
raise TypeError(f"Invalid type for 'label': {str(type(label))}")
+class SwAxisCont(ARObject):
+ """
+ Complex-type AR:SW-AXIS-CONT
+ Type: Concrete
+ Tag variants: SW-AXIS-CONT
+ """
+
+ def __init__(self,
+ category: ar_enum.CalibrationAxisCategory | None = None,
+ unit_ref: UnitRef | None = None,
+ unit_display_name: SingleLanguageUnitNames | None = None,
+ sw_axis_index: int | str | None = None,
+ sw_array_size: ValueList | None = None,
+ sw_values_phys: SwValues | None = None) -> None:
+ self.category = category # .CATEGORY
+ self.unit_ref: UnitRef = None # .UNIT-REF
+ self._assign_optional('unit_ref', unit_ref, UnitRef)
+ self.unit_display_name = unit_display_name # .UNIT-DISPLAY-NAME"
+ self.sw_axis_index = sw_axis_index # .SW-AXIS-INDEX
+ self.sw_array_size = sw_array_size # .SW-ARRAYSIZE
+ self.sw_values_phys = sw_values_phys # .SW-VALUES-PHYS
+
+
# Constant and value specifications
diff --git a/src/autosar/xml/enumeration.py b/src/autosar/xml/enumeration.py
index 3fd860d..9bc5c7f 100644
--- a/src/autosar/xml/enumeration.py
+++ b/src/autosar/xml/enumeration.py
@@ -52,6 +52,22 @@ class ByteOrder(Enum):
OPAQUE = 2
+class CalibrationAxisCategory(Enum):
+ """
+ AR:CALPRM-AXIS-CATEGORY-ENUM--SIMPLE
+
+ For some reason the XML schema defines the
+ values of this eanum with both '_' and '-' separators.
+ Seems like a mistake.
+ """
+
+ COM_AXIS = 0
+ CURVE_AXIS = 1
+ FIX_AXIS = 2
+ RES_AXIS = 3
+ STD_AXIS = 4
+
+
class CompuScaleContent(Enum):
"""
Used internally to differentiate the
@@ -480,6 +496,18 @@ class VersionedTextValue:
"MOST-SIGNIFICANT-BYTE-LAST": ByteOrder.LITTLE_ENDIAN,
"OPAQUE": ByteOrder.OPAQUE,
},
+ "CalibrationAxisCategory": {
+ "COM_AXIS": CalibrationAxisCategory.COM_AXIS,
+ "COM-AXIS": CalibrationAxisCategory.COM_AXIS,
+ "CURVE_AXIS": CalibrationAxisCategory.CURVE_AXIS,
+ "CURVE-AXIS": CalibrationAxisCategory.CURVE_AXIS,
+ "FIX_AXIS": CalibrationAxisCategory.FIX_AXIS,
+ "FIX-AXIS": CalibrationAxisCategory.FIX_AXIS,
+ "RES_AXIS": CalibrationAxisCategory.RES_AXIS,
+ "RES-AXIS": CalibrationAxisCategory.RES_AXIS,
+ "STD_AXIS": CalibrationAxisCategory.STD_AXIS,
+ "STD-AXIS": CalibrationAxisCategory.STD_AXIS,
+ },
"DisplayPresentation": {
"PRESENTATION-CONTINUOUS": DisplayPresentation.CONTINUOUS,
"PRESENTATION-DISCRETE": DisplayPresentation.DISCRETE
@@ -740,6 +768,13 @@ def xml_to_enum(enum_type_name: str, xml_text: str, schema_version: int = ar_bas
"MOST-SIGNIFICANT-BYTE-LAST", # 1
"OPAQUE", # 2
],
+ "CalibrationAxisCategory": [
+ "COM-AXIS", # 0
+ "CURVE-AXIS", # 1
+ "FIX-AXIS", # 2
+ "RES-AXIS", # 3
+ "STD-AXIS" # 4
+ ],
"DisplayPresentation": [
"PRESENTATION-CONTINUOUS", # 0
"PRESENTATION-DISCRETE", # 1
diff --git a/src/autosar/xml/reader.py b/src/autosar/xml/reader.py
index cee6939..aa38c57 100644
--- a/src/autosar/xml/reader.py
+++ b/src/autosar/xml/reader.py
@@ -168,6 +168,7 @@ def __init__(self,
'SW-ARRAYSIZE': self._read_value_list,
# CalibrationData elements
'SW-VALUES-PHYS': self._read_sw_values,
+ 'SW-AXIS-CONT': self._read_sw_axis_cont,
# Reference elements
'PHYSICAL-DIMENSION-REF': self._read_physical_dimension_ref,
'APPLICATION-DATA-TYPE-REF': self._read_application_data_type_ref,
@@ -2230,6 +2231,45 @@ def _read_value_group(self, xml_element: ElementTree.Element) -> ar_element.Valu
element = ar_element.ValueGroup(**data)
return element
+ def _read_sw_axis_cont(self, xml_element: ElementTree.Element) -> ar_element.SwAxisCont:
+ """
+ Reads complex-type AR:SW-AXIS-CONT
+ Type: Concrete
+ """
+ data = {}
+ child_elements = ChildElementMap(xml_element)
+ self._read_sw_axis_cont_group(child_elements, data)
+ self._report_unprocessed_elements(child_elements)
+ element = ar_element.SwAxisCont(**data)
+ return element
+
+ def _read_sw_axis_cont_group(self, child_elements: ChildElementMap, data: dict) -> None:
+ """
+ Reads group AR:SW-AXIS-CONT
+ """
+ xml_child = child_elements.get("CATEGORY")
+ if xml_child is not None:
+ data["category"] = ar_enum.xml_to_enum("CalibrationAxisCategory", xml_child.text)
+ xml_child = child_elements.get("UNIT-REF")
+ if xml_child is not None:
+ data["unit_ref"] = self._read_unit_ref(xml_child)
+ xml_child = child_elements.get("UNIT-DISPLAY-NAME")
+ if xml_child is not None:
+ data["unit_display_name"] = self._read_single_language_unit_names(xml_child)
+ xml_child = child_elements.get("SW-AXIS-INDEX")
+ if xml_child is not None:
+ try:
+ value = int(xml_child.text)
+ except ValueError:
+ value = xml_child.text
+ data["sw_axis_index"] = value
+ xml_child = child_elements.get("SW-ARRAYSIZE")
+ if xml_child is not None:
+ data["sw_array_size"] = self._read_value_list(xml_child)
+ xml_child = child_elements.get("SW-VALUES-PHYS")
+ if xml_child is not None:
+ data["sw_values_phys"] = self._read_sw_values(xml_child)
+
# UNFINISHED ELEMENTS - NEEDS REFACTORING
def _read_sender_receiver_interface(self, xml_element: ElementTree.Element) -> None:
diff --git a/src/autosar/xml/writer.py b/src/autosar/xml/writer.py
index 2f44d2b..39a55bd 100644
--- a/src/autosar/xml/writer.py
+++ b/src/autosar/xml/writer.py
@@ -247,6 +247,7 @@ def __init__(self) -> None:
'ValueList': self._write_value_list,
# CalibrationData elements
'SwValues': self._write_sw_values,
+ 'SwAxisCont': self._write_sw_axis_cont,
# Reference elements
'PhysicalDimensionRef': self._write_physical_dimension_ref,
'ApplicationDataTypeRef': self._write_application_data_type_ref,
@@ -1905,3 +1906,35 @@ def _write_value_group(self, elem: ar_element.ValueGroup, tag: str) -> None:
self._write_multi_language_long_name(elem.label, "LABEL")
self._write_sw_values_group(elem)
self._leave_child()
+
+ def _write_sw_axis_cont(self, elem: ar_element.SwAxisCont) -> None:
+ """
+ Writes Complex-type SW-AXIS-CONT
+ Type: Concrete
+ """
+ assert isinstance(elem, ar_element.SwAxisCont)
+ tag = "SW-AXIS-CONT"
+ if elem.is_empty:
+ self._add_content(tag)
+ else:
+ self._add_child(tag)
+ self._write_sw_axis_cont_group(elem)
+ self._leave_child()
+
+ def _write_sw_axis_cont_group(self, elem: ar_element.SwAxisCont) -> None:
+ """
+ Writes group SW-AXIS-CONT
+ Type: Concrete
+ """
+ if elem.category is not None:
+ self._add_content("CATEGORY", ar_enum.enum_to_xml(elem.category))
+ if elem.unit_ref is not None:
+ self._write_unit_ref(elem.unit_ref)
+ if elem.unit_display_name is not None:
+ self._write_single_language_unit_names(elem.unit_display_name, "UNIT-DISPLAY-NAME")
+ if elem.sw_axis_index is not None:
+ self._add_content("SW-AXIS-INDEX", str(elem.sw_axis_index))
+ if elem.sw_array_size is not None:
+ self._write_value_list(elem.sw_array_size)
+ if elem.sw_values_phys is not None:
+ self._write_sw_values(elem.sw_values_phys)
diff --git a/tests/xml/test_calibration.py b/tests/xml/test_calibration.py
index cdd7583..854611e 100644
--- a/tests/xml/test_calibration.py
+++ b/tests/xml/test_calibration.py
@@ -165,5 +165,101 @@ def test_read_write_value_group_with_label(self):
self.assertEqual(child.values, [1, 2, "Value"])
+class TestSwAxisCont(unittest.TestCase):
+
+ def test_read_write_empty(self):
+ element = ar_element.SwAxisCont()
+ writer = autosar.xml.Writer()
+ xml = writer.write_str_elem(element)
+ self.assertEqual(xml, '')
+ reader = autosar.xml.Reader()
+ elem: ar_element.SwAxisCont = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.SwAxisCont)
+
+ def test_read_write_category(self):
+ element = ar_element.SwAxisCont(category=ar_enum.CalibrationAxisCategory.STD_AXIS)
+ writer = autosar.xml.Writer()
+ xml = '''
+ STD-AXIS
+'''
+
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.SwAxisCont = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.SwAxisCont)
+ self.assertEqual(elem.category, ar_enum.CalibrationAxisCategory.STD_AXIS)
+
+ def test_read_write_unit_ref(self):
+ element = ar_element.SwAxisCont(unit_ref=ar_element.UnitRef("/Units/MyUnit"))
+ writer = autosar.xml.Writer()
+ xml = '''
+ /Units/MyUnit
+'''
+
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.SwAxisCont = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.SwAxisCont)
+ self.assertEqual(str(elem.unit_ref), "/Units/MyUnit")
+
+ def test_read_write_unit_display_name(self):
+ unit_display_name = ar_element.SingleLanguageUnitNames("Km/h")
+ element = ar_element.SwAxisCont(unit_display_name=unit_display_name)
+ writer = autosar.xml.Writer()
+ xml = '''
+ Km/h
+'''
+
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.SwAxisCont = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.SwAxisCont)
+ self.assertEqual(str(elem.unit_display_name), "Km/h")
+
+ def test_read_write_sw_axis_index(self):
+ element = ar_element.SwAxisCont(sw_axis_index=1)
+ writer = autosar.xml.Writer()
+ xml = '''
+ 1
+'''
+
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.SwAxisCont = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.SwAxisCont)
+ self.assertEqual(elem.sw_axis_index, 1)
+
+ def test_read_write_sw_array_size(self):
+ element = ar_element.SwAxisCont(sw_array_size=ar_element.ValueList([1, 2]))
+ writer = autosar.xml.Writer()
+ xml = '''
+
+ 1
+ 2
+
+'''
+
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.SwAxisCont = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.SwAxisCont)
+ self.assertEqual(elem.sw_array_size.values, [1, 2])
+
+ def test_read_write_sw_values_phys(self):
+ element = ar_element.SwAxisCont(sw_values_phys=ar_element.SwValues(1))
+ writer = autosar.xml.Writer()
+ xml = '''
+
+ 1
+
+'''
+
+ self.assertEqual(writer.write_str_elem(element), xml)
+ reader = autosar.xml.Reader()
+ elem: ar_element.SwAxisCont = reader.read_str_elem(xml)
+ self.assertIsInstance(elem, ar_element.SwAxisCont)
+ self.assertEqual(elem.sw_values_phys.values, [1])
+
+
if __name__ == '__main__':
unittest.main()