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()