odxtools 6.6.1__py3-none-any.whl → 9.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- odxtools/__init__.py +7 -5
- odxtools/additionalaudience.py +3 -5
- odxtools/admindata.py +5 -7
- odxtools/audience.py +10 -13
- odxtools/basecomparam.py +3 -5
- odxtools/basicstructure.py +55 -241
- odxtools/cli/_parser_utils.py +16 -1
- odxtools/cli/_print_utils.py +169 -134
- odxtools/cli/browse.py +127 -103
- odxtools/cli/compare.py +114 -87
- odxtools/cli/decode.py +2 -1
- odxtools/cli/dummy_sub_parser.py +3 -1
- odxtools/cli/find.py +2 -1
- odxtools/cli/list.py +26 -16
- odxtools/cli/main.py +1 -0
- odxtools/cli/snoop.py +32 -6
- odxtools/codec.py +211 -0
- odxtools/commrelation.py +122 -0
- odxtools/companydata.py +5 -7
- odxtools/companydocinfo.py +7 -8
- odxtools/companyrevisioninfo.py +3 -5
- odxtools/companyspecificinfo.py +8 -9
- odxtools/comparam.py +4 -6
- odxtools/comparaminstance.py +14 -14
- odxtools/comparamspec.py +16 -54
- odxtools/comparamsubset.py +22 -62
- odxtools/complexcomparam.py +5 -7
- odxtools/compumethods/compucodecompumethod.py +63 -0
- odxtools/compumethods/compuconst.py +31 -0
- odxtools/compumethods/compudefaultvalue.py +27 -0
- odxtools/compumethods/compuinternaltophys.py +56 -0
- odxtools/compumethods/compuinversevalue.py +7 -0
- odxtools/compumethods/compumethod.py +94 -15
- odxtools/compumethods/compuphystointernal.py +56 -0
- odxtools/compumethods/compurationalcoeffs.py +20 -9
- odxtools/compumethods/compuscale.py +67 -32
- odxtools/compumethods/createanycompumethod.py +31 -172
- odxtools/compumethods/identicalcompumethod.py +31 -6
- odxtools/compumethods/limit.py +70 -36
- odxtools/compumethods/linearcompumethod.py +70 -181
- odxtools/compumethods/linearsegment.py +190 -0
- odxtools/compumethods/ratfunccompumethod.py +106 -0
- odxtools/compumethods/ratfuncsegment.py +87 -0
- odxtools/compumethods/scalelinearcompumethod.py +132 -26
- odxtools/compumethods/scaleratfunccompumethod.py +113 -0
- odxtools/compumethods/tabintpcompumethod.py +123 -92
- odxtools/compumethods/texttablecompumethod.py +117 -57
- odxtools/createanydiagcodedtype.py +10 -67
- odxtools/database.py +167 -87
- odxtools/dataobjectproperty.py +25 -32
- odxtools/decodestate.py +14 -17
- odxtools/description.py +47 -0
- odxtools/determinenumberofitems.py +4 -5
- odxtools/diagcodedtype.py +37 -106
- odxtools/diagcomm.py +24 -12
- odxtools/diagdatadictionaryspec.py +120 -96
- odxtools/diaglayercontainer.py +46 -54
- odxtools/diaglayers/basevariant.py +128 -0
- odxtools/diaglayers/basevariantraw.py +123 -0
- odxtools/diaglayers/diaglayer.py +432 -0
- odxtools/{diaglayerraw.py → diaglayers/diaglayerraw.py} +105 -120
- odxtools/diaglayers/diaglayertype.py +42 -0
- odxtools/diaglayers/ecushareddata.py +96 -0
- odxtools/diaglayers/ecushareddataraw.py +87 -0
- odxtools/diaglayers/ecuvariant.py +124 -0
- odxtools/diaglayers/ecuvariantraw.py +129 -0
- odxtools/diaglayers/functionalgroup.py +110 -0
- odxtools/diaglayers/functionalgroupraw.py +106 -0
- odxtools/{diaglayer.py → diaglayers/hierarchyelement.py} +273 -472
- odxtools/diaglayers/hierarchyelementraw.py +58 -0
- odxtools/diaglayers/protocol.py +64 -0
- odxtools/diaglayers/protocolraw.py +91 -0
- odxtools/diagnostictroublecode.py +8 -9
- odxtools/diagservice.py +57 -44
- odxtools/diagvariable.py +113 -0
- odxtools/docrevision.py +5 -7
- odxtools/dopbase.py +15 -15
- odxtools/dtcdop.py +170 -50
- odxtools/dynamicendmarkerfield.py +134 -0
- odxtools/dynamiclengthfield.py +47 -42
- odxtools/dyndefinedspec.py +177 -0
- odxtools/dynenddopref.py +38 -0
- odxtools/ecuvariantmatcher.py +6 -7
- odxtools/element.py +13 -15
- odxtools/encodestate.py +199 -22
- odxtools/endofpdufield.py +31 -18
- odxtools/environmentdata.py +8 -1
- odxtools/environmentdatadescription.py +198 -36
- odxtools/exceptions.py +11 -2
- odxtools/field.py +10 -10
- odxtools/functionalclass.py +3 -5
- odxtools/inputparam.py +3 -12
- odxtools/internalconstr.py +14 -5
- odxtools/isotp_state_machine.py +14 -6
- odxtools/leadinglengthinfotype.py +37 -18
- odxtools/library.py +66 -0
- odxtools/loadfile.py +64 -0
- odxtools/matchingparameter.py +3 -3
- odxtools/message.py +0 -7
- odxtools/minmaxlengthtype.py +61 -33
- odxtools/modification.py +3 -5
- odxtools/multiplexer.py +135 -75
- odxtools/multiplexercase.py +39 -18
- odxtools/multiplexerdefaultcase.py +15 -12
- odxtools/multiplexerswitchkey.py +4 -5
- odxtools/nameditemlist.py +33 -8
- odxtools/negoutputparam.py +3 -5
- odxtools/odxcategory.py +83 -0
- odxtools/odxlink.py +62 -53
- odxtools/odxtypes.py +93 -8
- odxtools/outputparam.py +5 -16
- odxtools/parameterinfo.py +219 -61
- odxtools/parameters/codedconstparameter.py +45 -32
- odxtools/parameters/createanyparameter.py +19 -193
- odxtools/parameters/dynamicparameter.py +25 -4
- odxtools/parameters/lengthkeyparameter.py +83 -25
- odxtools/parameters/matchingrequestparameter.py +48 -18
- odxtools/parameters/nrcconstparameter.py +76 -54
- odxtools/parameters/parameter.py +97 -73
- odxtools/parameters/parameterwithdop.py +41 -38
- odxtools/parameters/physicalconstantparameter.py +41 -20
- odxtools/parameters/reservedparameter.py +36 -18
- odxtools/parameters/systemparameter.py +74 -7
- odxtools/parameters/tableentryparameter.py +47 -7
- odxtools/parameters/tablekeyparameter.py +142 -55
- odxtools/parameters/tablestructparameter.py +79 -58
- odxtools/parameters/valueparameter.py +39 -21
- odxtools/paramlengthinfotype.py +56 -33
- odxtools/parentref.py +20 -3
- odxtools/physicaldimension.py +3 -8
- odxtools/progcode.py +26 -11
- odxtools/protstack.py +3 -5
- odxtools/py.typed +0 -0
- odxtools/relateddoc.py +7 -9
- odxtools/request.py +120 -10
- odxtools/response.py +123 -23
- odxtools/scaleconstr.py +14 -8
- odxtools/servicebinner.py +1 -1
- odxtools/singleecujob.py +12 -10
- odxtools/snrefcontext.py +29 -0
- odxtools/specialdata.py +3 -5
- odxtools/specialdatagroup.py +7 -9
- odxtools/specialdatagroupcaption.py +3 -6
- odxtools/standardlengthtype.py +80 -14
- odxtools/state.py +3 -5
- odxtools/statechart.py +13 -19
- odxtools/statetransition.py +8 -18
- odxtools/staticfield.py +107 -0
- odxtools/subcomponent.py +288 -0
- odxtools/swvariable.py +21 -0
- odxtools/table.py +9 -9
- odxtools/tablerow.py +30 -15
- odxtools/teammember.py +3 -5
- odxtools/templates/comparam-spec.odx-c.xml.jinja2 +4 -24
- odxtools/templates/comparam-subset.odx-cs.xml.jinja2 +5 -26
- odxtools/templates/diag_layer_container.odx-d.xml.jinja2 +15 -31
- odxtools/templates/{index.xml.xml.jinja2 → index.xml.jinja2} +1 -1
- odxtools/templates/macros/printAudience.xml.jinja2 +1 -1
- odxtools/templates/macros/printBaseVariant.xml.jinja2 +53 -0
- odxtools/templates/macros/printCompanyData.xml.jinja2 +4 -7
- odxtools/templates/macros/printComparam.xml.jinja2 +6 -4
- odxtools/templates/macros/printComparamRef.xml.jinja2 +5 -12
- odxtools/templates/macros/printCompuMethod.xml.jinja2 +147 -0
- odxtools/templates/macros/printDOP.xml.jinja2 +27 -137
- odxtools/templates/macros/printDescription.xml.jinja2 +18 -0
- odxtools/templates/macros/printDiagComm.xml.jinja2 +1 -1
- odxtools/templates/macros/printDiagLayer.xml.jinja2 +222 -0
- odxtools/templates/macros/printDiagVariable.xml.jinja2 +66 -0
- odxtools/templates/macros/printDynDefinedSpec.xml.jinja2 +48 -0
- odxtools/templates/macros/printDynamicEndmarkerField.xml.jinja2 +16 -0
- odxtools/templates/macros/printDynamicLengthField.xml.jinja2 +1 -1
- odxtools/templates/macros/printEcuSharedData.xml.jinja2 +30 -0
- odxtools/templates/macros/printEcuVariant.xml.jinja2 +53 -0
- odxtools/templates/macros/printEcuVariantPattern.xml.jinja2 +1 -1
- odxtools/templates/macros/printElementId.xml.jinja2 +8 -3
- odxtools/templates/macros/printEndOfPdu.xml.jinja2 +1 -1
- odxtools/templates/macros/printEnvDataDesc.xml.jinja2 +1 -1
- odxtools/templates/macros/printFunctionalClass.xml.jinja2 +1 -1
- odxtools/templates/macros/printFunctionalGroup.xml.jinja2 +40 -0
- odxtools/templates/macros/printHierarchyElement.xml.jinja2 +24 -0
- odxtools/templates/macros/printLibrary.xml.jinja2 +21 -0
- odxtools/templates/macros/printMux.xml.jinja2 +5 -3
- odxtools/templates/macros/printOdxCategory.xml.jinja2 +28 -0
- odxtools/templates/macros/printParam.xml.jinja2 +18 -19
- odxtools/templates/macros/printProtStack.xml.jinja2 +1 -1
- odxtools/templates/macros/printProtocol.xml.jinja2 +30 -0
- odxtools/templates/macros/printRequest.xml.jinja2 +1 -1
- odxtools/templates/macros/printResponse.xml.jinja2 +1 -1
- odxtools/templates/macros/printService.xml.jinja2 +3 -2
- odxtools/templates/macros/printSingleEcuJob.xml.jinja2 +5 -26
- odxtools/templates/macros/printSpecialData.xml.jinja2 +1 -1
- odxtools/templates/macros/printState.xml.jinja2 +1 -1
- odxtools/templates/macros/printStateChart.xml.jinja2 +1 -1
- odxtools/templates/macros/printStateTransition.xml.jinja2 +1 -1
- odxtools/templates/macros/printStaticField.xml.jinja2 +15 -0
- odxtools/templates/macros/printStructure.xml.jinja2 +1 -1
- odxtools/templates/macros/printSubComponent.xml.jinja2 +104 -0
- odxtools/templates/macros/printTable.xml.jinja2 +4 -5
- odxtools/templates/macros/printUnitSpec.xml.jinja2 +3 -5
- odxtools/uds.py +2 -10
- odxtools/unit.py +4 -8
- odxtools/unitgroup.py +3 -5
- odxtools/unitspec.py +17 -17
- odxtools/utils.py +38 -20
- odxtools/variablegroup.py +32 -0
- odxtools/version.py +2 -2
- odxtools/{write_pdx_file.py → writepdxfile.py} +22 -12
- odxtools/xdoc.py +3 -5
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/METADATA +44 -33
- odxtools-9.3.0.dist-info/RECORD +228 -0
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/WHEEL +1 -1
- odxtools/createcompanydatas.py +0 -17
- odxtools/createsdgs.py +0 -19
- odxtools/diaglayertype.py +0 -30
- odxtools/load_file.py +0 -13
- odxtools/load_odx_d_file.py +0 -6
- odxtools/load_pdx_file.py +0 -8
- odxtools/templates/macros/printVariant.xml.jinja2 +0 -208
- odxtools-6.6.1.dist-info/RECORD +0 -180
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/LICENSE +0 -0
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/entry_points.txt +0 -0
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
{#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
-#}
|
5
|
+
|
6
|
+
{%- import('macros/printElementId.xml.jinja2') as peid %}
|
7
|
+
{%- import('macros/printEcuVariantPattern.xml.jinja2') as pevp %}
|
8
|
+
|
9
|
+
{%- macro printSubComponentPattern(pat) %}
|
10
|
+
<SUB-COMPONENT-PATTERN>
|
11
|
+
<MATCHING-PARAMETERS>
|
12
|
+
{%- for mp in pat.matching_parameters %}
|
13
|
+
{{ pvp.printMatchingParameter(mp)|indent(4) }}
|
14
|
+
{%- endfor %}
|
15
|
+
</MATCHING-PARAMETERS>
|
16
|
+
</SUB-COMPONENT-PATTERN>
|
17
|
+
{%- endmacro %}
|
18
|
+
|
19
|
+
{%- macro printSubComponentParamConnector(conn) %}
|
20
|
+
<SUB-COMPONENT-PARAM-CONNECTOR{#- #} {{-peid.printElementIdAttribs(conn)}}>
|
21
|
+
{{ peid.printElementIdSubtags(conn)|indent(2) }}
|
22
|
+
<DIAG-COMM-SNREF {{- make_xml_attrib("SHORT-NAME", conn.diag_comm_snref ) }} />
|
23
|
+
{%- if conn.out_param_if_refs %}
|
24
|
+
<OUT-PARAM-IF-REFS>
|
25
|
+
{%- for snref in conn.out_param_if_refs %}
|
26
|
+
<OUT-PARAM-IF-SNREF SHORT-NAME="{{snref}}" />
|
27
|
+
{%- endfor %}
|
28
|
+
</OUT-PARAM-IF-REFS>
|
29
|
+
{%- endif %}
|
30
|
+
{%- if conn.in_param_if_refs %}
|
31
|
+
<IN-PARAM-IF-REFS>
|
32
|
+
{%- for snref in conn.in_param_if_refs %}
|
33
|
+
<IN-PARAM-IF-SNREF SHORT-NAME="{{snref}}" />
|
34
|
+
{%- endfor %}
|
35
|
+
</IN-PARAM-IF-REFS>
|
36
|
+
{%- endif %}
|
37
|
+
</SUB-COMPONENT-PARAM-CONNECTOR>
|
38
|
+
{%- endmacro %}
|
39
|
+
|
40
|
+
{%- macro printTableRowConnector(conn) %}
|
41
|
+
<TABLE-ROW-CONNECTOR>
|
42
|
+
{{ peid.printElementIdSubtags(conn)|indent(2) }}
|
43
|
+
<TABLE-REF ID-REF="{{ conn.table_ref.ref_id }}" />
|
44
|
+
<TABLE-ROW-SNREF {{- make_xml_attrib("SHORT-NAME", conn.table_row_snref ) }} />
|
45
|
+
</TABLE-ROW-CONNECTOR>
|
46
|
+
{%- endmacro %}
|
47
|
+
|
48
|
+
{%- macro printEnvDataConnector(conn) %}
|
49
|
+
<ENV-DATA-CONNECTOR>
|
50
|
+
{{ peid.printElementIdSubtags(conn)|indent(2) }}
|
51
|
+
<ENV-DATA-DESC-REF ID-REF="{{ conn.env_data_desc_ref.ref_id }}" />
|
52
|
+
<ENV-DATA-SNREF {{- make_xml_attrib("SHORT-NAME", conn.env_data_snref ) }} />
|
53
|
+
</ENV-DATA-CONNECTOR>
|
54
|
+
{%- endmacro %}
|
55
|
+
|
56
|
+
{%- macro printDtcConnector(conn) %}
|
57
|
+
<DTC-CONNECTOR>
|
58
|
+
{{ peid.printElementIdSubtags(conn)|indent(2) }}
|
59
|
+
<DTC-DOP-REF ID-REF="{{ conn.dtc_dop_ref.ref_id }}" />
|
60
|
+
<DOP-SNREF {{- make_xml_attrib("SHORT-NAME", conn.dtc_snref ) }} />
|
61
|
+
</DTC-CONNECTOR>
|
62
|
+
{%- endmacro %}
|
63
|
+
|
64
|
+
{%- macro printSubComponent(sc) %}
|
65
|
+
<SUB-COMPONENT{#- #} {{-peid.printElementIdAttribs(sc)}}
|
66
|
+
{{- make_xml_attrib("SEMANTIC", sc.semantic) }}>
|
67
|
+
{{ peid.printElementIdSubtags(sc)|indent(2) }}
|
68
|
+
{%- if sc.sub_component_patterns %}
|
69
|
+
<SUB-COMPONENT-PATTERNS>
|
70
|
+
{%- for scp in sc.sub_component_patterns %}
|
71
|
+
{{ printSubComponentPattern(scp)|indent(4) }}
|
72
|
+
{%- endfor %}
|
73
|
+
</SUB-COMPONENT-PATTERNS>
|
74
|
+
{%- endif %}
|
75
|
+
{%- if sc.sub_component_param_connectors %}
|
76
|
+
<SUB-COMPONENT-PARAM-CONNECTORS>
|
77
|
+
{%- for conn in sc.sub_component_param_connectors %}
|
78
|
+
{{ printSubComponentParamConnector(conn)|indent(4) }}
|
79
|
+
{%- endfor %}
|
80
|
+
</SUB-COMPONENT-PARAM-CONNECTORS>
|
81
|
+
{%- endif %}
|
82
|
+
{%- if sc.table_row_connectors %}
|
83
|
+
<TABLE-ROW-CONNECTORS>
|
84
|
+
{%- for conn in sc.table_row_connectors %}
|
85
|
+
{{ printTableRowConnector(conn)|indent(4) }}
|
86
|
+
{%- endfor %}
|
87
|
+
</TABLE-ROW-CONNECTORS>
|
88
|
+
{%- endif %}
|
89
|
+
{%- if sc.env_data_connectors %}
|
90
|
+
<ENV-DATA-CONNECTORS>
|
91
|
+
{%- for conn in sc.env_data_connectors %}
|
92
|
+
{{ printEnvDataConnector(conn)|indent(4) }}
|
93
|
+
{%- endfor %}
|
94
|
+
</ENV-DATA-CONNECTORS>
|
95
|
+
{%- endif %}
|
96
|
+
{%- if sc.dtc_connectors %}
|
97
|
+
<DTC-CONNECTORS>
|
98
|
+
{%- for conn in sc.dtc_connectors %}
|
99
|
+
{{ printDtcConnector(conn)|indent(4) }}
|
100
|
+
{%- endfor %}
|
101
|
+
</DTC-CONNECTORS>
|
102
|
+
{%- endif %}
|
103
|
+
</SUB-COMPONENT>
|
104
|
+
{%- endmacro %}
|
@@ -5,9 +5,10 @@
|
|
5
5
|
|
6
6
|
{%- import('macros/printElementId.xml.jinja2') as peid %}
|
7
7
|
{%- import('macros/printSpecialData.xml.jinja2') as psd %}
|
8
|
+
{%- import('macros/printDescription.xml.jinja2') as pd %}
|
8
9
|
|
9
10
|
{%- macro printTable(table) %}
|
10
|
-
<TABLE
|
11
|
+
<TABLE {{-peid.printElementIdAttribs(table)}}
|
11
12
|
{{-make_xml_attrib("SEMANTIC", table.semantic)}}>
|
12
13
|
{{ peid.printElementIdSubtags(table)|indent(1) }}
|
13
14
|
{%- if table.key_dop_ref %}
|
@@ -15,15 +16,13 @@
|
|
15
16
|
{%- endif %}
|
16
17
|
{%- for table_row in table.table_rows_raw %}
|
17
18
|
{%- if hasattr(table_row, "key") %}
|
18
|
-
<TABLE-ROW
|
19
|
+
<TABLE-ROW {{-peid.printElementIdAttribs(table_row)}}
|
19
20
|
{{-make_xml_attrib("SEMANTIC", table_row.semantic)}}>
|
20
21
|
<SHORT-NAME>{{table_row.short_name}}</SHORT-NAME>
|
21
22
|
{%- if table_row.long_name %}
|
22
23
|
<LONG-NAME>{{table_row.long_name|e}}</LONG-NAME>
|
23
24
|
{%- endif %}
|
24
|
-
{
|
25
|
-
<DESC>{{table_row.description}}</DESC>
|
26
|
-
{%- endif %}
|
25
|
+
{{ pd.printDescription(table_row.description) }}
|
27
26
|
<KEY>{{table_row.key|e}}</KEY>
|
28
27
|
{%- if table_row.dop_ref %}
|
29
28
|
<DATA-OBJECT-PROP-REF ID-REF="{{ table_row.dop_ref.ref_id }}" />
|
@@ -35,8 +35,7 @@
|
|
35
35
|
|
36
36
|
|
37
37
|
{%- macro printUnit(unit) -%}
|
38
|
-
<UNIT
|
39
|
-
{{-make_xml_attrib("OID", unit.oid)}}>
|
38
|
+
<UNIT {{-peid.printElementIdAttribs(unit)}}>
|
40
39
|
{{ peid.printElementIdSubtags(unit)|indent(1) }}
|
41
40
|
<DISPLAY-NAME>{{ unit.display_name }}</DISPLAY-NAME>
|
42
41
|
{%- if unit.factor_si_to_unit is not none %}
|
@@ -52,7 +51,7 @@
|
|
52
51
|
{%- endmacro -%}
|
53
52
|
|
54
53
|
{%- macro printUnitGroup(group) -%}
|
55
|
-
<UNIT-GROUP {
|
54
|
+
<UNIT-GROUP {{-make_xml_attrib("OID", group.oid)}}>
|
56
55
|
{{ peid.printElementIdSubtags(group)|indent(1) }}
|
57
56
|
<CATEGORY>{{ group.category.value }}</CATEGORY>
|
58
57
|
{%- if group.unit_refs %}
|
@@ -66,8 +65,7 @@
|
|
66
65
|
{%- endmacro -%}
|
67
66
|
|
68
67
|
{%- macro printPhysicalDimesion(dim) -%}
|
69
|
-
<PHYSICAL-DIMENSION
|
70
|
-
{{-make_xml_attrib("OID",dim.oid)}}>
|
68
|
+
<PHYSICAL-DIMENSION {{-peid.printElementIdAttribs(dim)}}>
|
71
69
|
{{ peid.printElementIdSubtags(dim)|indent(1) }}
|
72
70
|
{%- if dim.length_exp %}
|
73
71
|
<LENGTH-EXP>{{ dim.length_exp }}</LENGTH-EXP>
|
odxtools/uds.py
CHANGED
@@ -3,8 +3,6 @@ from enum import IntEnum
|
|
3
3
|
from itertools import chain
|
4
4
|
from typing import Optional
|
5
5
|
|
6
|
-
from deprecation import deprecated
|
7
|
-
|
8
6
|
import odxtools.obd as obd
|
9
7
|
|
10
8
|
|
@@ -62,13 +60,13 @@ _sid_to_name = {
|
|
62
60
|
0x85: "Control DTC Settings",
|
63
61
|
0x86: "Response on Event",
|
64
62
|
0x87: "Link Control",
|
65
|
-
0x22: "Read Data by Identifier
|
63
|
+
0x22: "Read Data by Identifier",
|
66
64
|
0x23: "Read Memory by Address",
|
67
65
|
0x24: "Read Scaling Data by Identifier",
|
68
66
|
0x2a: "Read Data by Periodic Identifier",
|
69
67
|
0x2c: "Dynamically Define Data Identifier",
|
70
68
|
0x2e: "Write Data by Identifier",
|
71
|
-
0x3d: "Write Memory by Address
|
69
|
+
0x3d: "Write Memory by Address",
|
72
70
|
0x14: "Clear Diagnostic Information",
|
73
71
|
0x19: "Read DTC Information",
|
74
72
|
0x2f: "Input Output Control by Identifier",
|
@@ -170,9 +168,3 @@ def is_response_pending(telegram_payload: bytes, request_sid: Optional[int] = No
|
|
170
168
|
|
171
169
|
# if all of the above applies, we received a "stay tuned" response
|
172
170
|
return True
|
173
|
-
|
174
|
-
|
175
|
-
# previous versions of odxtools had a typo here. hit happens!
|
176
|
-
@deprecated(details="use is_response_pending()")
|
177
|
-
def is_reponse_pending(telegram_payload: bytes, request_sid: Optional[int] = None) -> bool:
|
178
|
-
return is_reponse_pending(telegram_payload, request_sid)
|
odxtools/unit.py
CHANGED
@@ -1,17 +1,15 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import
|
3
|
+
from typing import Any, Dict, List, Optional
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .element import IdentifiableElement
|
7
7
|
from .exceptions import odxassert, odxrequire
|
8
8
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
9
9
|
from .physicaldimension import PhysicalDimension
|
10
|
+
from .snrefcontext import SnRefContext
|
10
11
|
from .utils import dataclass_fields_asdict
|
11
12
|
|
12
|
-
if TYPE_CHECKING:
|
13
|
-
from .diaglayer import DiagLayer
|
14
|
-
|
15
13
|
|
16
14
|
@dataclass
|
17
15
|
class Unit(IdentifiableElement):
|
@@ -55,7 +53,6 @@ class Unit(IdentifiableElement):
|
|
55
53
|
```
|
56
54
|
"""
|
57
55
|
display_name: str
|
58
|
-
oid: Optional[str]
|
59
56
|
factor_si_to_unit: Optional[float]
|
60
57
|
offset_si_to_unit: Optional[float]
|
61
58
|
physical_dimension_ref: Optional[OdxLinkRef]
|
@@ -66,7 +63,7 @@ class Unit(IdentifiableElement):
|
|
66
63
|
@staticmethod
|
67
64
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "Unit":
|
68
65
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
69
|
-
|
66
|
+
|
70
67
|
display_name = odxrequire(et_element.findtext("DISPLAY-NAME"))
|
71
68
|
|
72
69
|
def read_optional_float(element: ElementTree.Element, name: str) -> Optional[float]:
|
@@ -82,7 +79,6 @@ class Unit(IdentifiableElement):
|
|
82
79
|
|
83
80
|
return Unit(
|
84
81
|
display_name=display_name,
|
85
|
-
oid=oid,
|
86
82
|
factor_si_to_unit=factor_si_to_unit,
|
87
83
|
offset_si_to_unit=offset_si_to_unit,
|
88
84
|
physical_dimension_ref=physical_dimension_ref,
|
@@ -104,5 +100,5 @@ class Unit(IdentifiableElement):
|
|
104
100
|
f"The physical_dimension_ref must be resolved to a PhysicalDimension."
|
105
101
|
f" {self.physical_dimension_ref} referenced {self._physical_dimension}")
|
106
102
|
|
107
|
-
def _resolve_snrefs(self,
|
103
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
108
104
|
pass
|
odxtools/unitgroup.py
CHANGED
@@ -1,19 +1,17 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
3
|
from enum import Enum
|
4
|
-
from typing import
|
4
|
+
from typing import Any, Dict, List, Optional, cast
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
7
|
from .element import NamedElement
|
8
8
|
from .exceptions import odxraise, odxrequire
|
9
9
|
from .nameditemlist import NamedItemList
|
10
10
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
11
|
+
from .snrefcontext import SnRefContext
|
11
12
|
from .unit import Unit
|
12
13
|
from .utils import dataclass_fields_asdict
|
13
14
|
|
14
|
-
if TYPE_CHECKING:
|
15
|
-
from .diaglayer import DiagLayer
|
16
|
-
|
17
15
|
|
18
16
|
class UnitGroupCategory(Enum):
|
19
17
|
COUNTRY = "COUNTRY"
|
@@ -57,7 +55,7 @@ class UnitGroup(NamedElement):
|
|
57
55
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
58
56
|
self._units = NamedItemList[Unit]([odxlinks.resolve(ref) for ref in self.unit_refs])
|
59
57
|
|
60
|
-
def _resolve_snrefs(self,
|
58
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
61
59
|
pass
|
62
60
|
|
63
61
|
@property
|
odxtools/unitspec.py
CHANGED
@@ -1,19 +1,16 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import
|
3
|
+
from typing import Any, Dict, List
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
|
-
from .createsdgs import create_sdgs_from_et
|
7
6
|
from .nameditemlist import NamedItemList
|
8
7
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
9
8
|
from .physicaldimension import PhysicalDimension
|
9
|
+
from .snrefcontext import SnRefContext
|
10
10
|
from .specialdatagroup import SpecialDataGroup
|
11
11
|
from .unit import Unit
|
12
12
|
from .unitgroup import UnitGroup
|
13
13
|
|
14
|
-
if TYPE_CHECKING:
|
15
|
-
from .diaglayer import DiagLayer
|
16
|
-
|
17
14
|
|
18
15
|
@dataclass
|
19
16
|
class UnitSpec:
|
@@ -28,9 +25,9 @@ class UnitSpec:
|
|
28
25
|
"""
|
29
26
|
|
30
27
|
# TODO (?): Why are there type errors...
|
31
|
-
unit_groups:
|
32
|
-
units:
|
33
|
-
physical_dimensions:
|
28
|
+
unit_groups: NamedItemList[UnitGroup]
|
29
|
+
units: NamedItemList[Unit]
|
30
|
+
physical_dimensions: NamedItemList[PhysicalDimension]
|
34
31
|
sdgs: List[SpecialDataGroup]
|
35
32
|
|
36
33
|
def __post_init__(self) -> None:
|
@@ -41,15 +38,18 @@ class UnitSpec:
|
|
41
38
|
@staticmethod
|
42
39
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "UnitSpec":
|
43
40
|
|
44
|
-
unit_groups = [
|
41
|
+
unit_groups = NamedItemList([
|
45
42
|
UnitGroup.from_et(el, doc_frags) for el in et_element.iterfind("UNIT-GROUPS/UNIT-GROUP")
|
46
|
-
]
|
47
|
-
units =
|
48
|
-
|
43
|
+
])
|
44
|
+
units = NamedItemList(
|
45
|
+
[Unit.from_et(el, doc_frags) for el in et_element.iterfind("UNITS/UNIT")])
|
46
|
+
physical_dimensions = NamedItemList([
|
49
47
|
PhysicalDimension.from_et(el, doc_frags)
|
50
48
|
for el in et_element.iterfind("PHYSICAL-DIMENSIONS/PHYSICAL-DIMENSION")
|
49
|
+
])
|
50
|
+
sdgs = [
|
51
|
+
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
|
51
52
|
]
|
52
|
-
sdgs = create_sdgs_from_et(et_element.find("SDGS"), doc_frags)
|
53
53
|
|
54
54
|
return UnitSpec(
|
55
55
|
unit_groups=unit_groups,
|
@@ -76,10 +76,10 @@ class UnitSpec:
|
|
76
76
|
for sdg in self.sdgs:
|
77
77
|
sdg._resolve_odxlinks(odxlinks)
|
78
78
|
|
79
|
-
def _resolve_snrefs(self,
|
79
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
80
80
|
for unit in self.units:
|
81
|
-
unit._resolve_snrefs(
|
81
|
+
unit._resolve_snrefs(context)
|
82
82
|
for group in self.unit_groups:
|
83
|
-
group._resolve_snrefs(
|
83
|
+
group._resolve_snrefs(context)
|
84
84
|
for sdg in self.sdgs:
|
85
|
-
sdg._resolve_snrefs(
|
85
|
+
sdg._resolve_snrefs(context)
|
odxtools/utils.py
CHANGED
@@ -1,32 +1,50 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import dataclasses
|
3
3
|
import re
|
4
|
-
from typing import Any, Dict, Optional
|
5
|
-
|
4
|
+
from typing import TYPE_CHECKING, Any, Dict, Optional
|
5
|
+
|
6
|
+
if TYPE_CHECKING:
|
7
|
+
from .database import Database
|
8
|
+
from .diaglayers.diaglayer import DiagLayer
|
9
|
+
from .snrefcontext import SnRefContext
|
10
|
+
|
11
|
+
|
12
|
+
def retarget_snrefs(database: "Database",
|
13
|
+
diag_layer: "DiagLayer",
|
14
|
+
context: Optional["SnRefContext"] = None) -> None:
|
15
|
+
"""Re-resolve the short name references reachable by a
|
16
|
+
DiagLayer to this DiagLayer
|
17
|
+
|
18
|
+
This implies that after the SNREFs have been retargeted, accessing
|
19
|
+
the resolved objects via a different diagnostic layer might not be
|
20
|
+
correct. E.g.: If the ECU variants "V1" and "V2" are derived from
|
21
|
+
the base variant "BV", BV defines a short name reference to a data
|
22
|
+
object property called "Foo" and V1 and V2 both define a "Foo"
|
23
|
+
DOP, the reference in the base variant to Foo ought to be resolved
|
24
|
+
differently depending on whether it is accessed via V1 or
|
25
|
+
V2. Since odxtools resolves all references ahead of time, a fixed
|
26
|
+
variant has to be chosen. This method allows to switch the variant
|
27
|
+
to another one.
|
6
28
|
|
29
|
+
"""
|
30
|
+
from .snrefcontext import SnRefContext
|
7
31
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
The description is located underneath the DESC tag of an an ODX
|
12
|
-
element."""
|
13
|
-
|
14
|
-
if et_element is None:
|
15
|
-
return None
|
32
|
+
if context is None:
|
33
|
+
context = SnRefContext()
|
16
34
|
|
17
|
-
if
|
18
|
-
|
19
|
-
f"'{et_element.tag}' XML node. (Must be a 'DESC' node!)")
|
35
|
+
if context.database is None:
|
36
|
+
context.database = database
|
20
37
|
|
21
|
-
|
22
|
-
|
23
|
-
for e in et_element:
|
24
|
-
raw_string += ElementTree.tostring(e, encoding="unicode")
|
38
|
+
if context.diag_layer is None:
|
39
|
+
context.diag_layer = diag_layer
|
25
40
|
|
26
|
-
#
|
27
|
-
|
41
|
+
# retarget the objects "owned" by the layer itself
|
42
|
+
diag_layer._resolve_snrefs(context)
|
28
43
|
|
29
|
-
|
44
|
+
# retarget all parents of the current layer (if any)
|
45
|
+
if (parent_refs := getattr(diag_layer, "parent_refs", None)) is not None:
|
46
|
+
for pr in parent_refs:
|
47
|
+
retarget_snrefs(database, pr.layer, context)
|
30
48
|
|
31
49
|
|
32
50
|
def dataclass_fields_asdict(obj: Any) -> Dict[str, Any]:
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
import typing
|
3
|
+
from dataclasses import dataclass
|
4
|
+
from typing import TYPE_CHECKING, List, runtime_checkable
|
5
|
+
from xml.etree import ElementTree
|
6
|
+
|
7
|
+
from .element import IdentifiableElement, NamedElement
|
8
|
+
from .nameditemlist import NamedItemList
|
9
|
+
from .odxlink import OdxDocFragment
|
10
|
+
from .utils import dataclass_fields_asdict
|
11
|
+
|
12
|
+
if TYPE_CHECKING:
|
13
|
+
pass
|
14
|
+
|
15
|
+
|
16
|
+
@runtime_checkable
|
17
|
+
class HasVariableGroups(typing.Protocol):
|
18
|
+
|
19
|
+
@property
|
20
|
+
def variable_groups(self) -> NamedItemList["VariableGroup"]:
|
21
|
+
...
|
22
|
+
|
23
|
+
|
24
|
+
@dataclass
|
25
|
+
class VariableGroup(IdentifiableElement):
|
26
|
+
|
27
|
+
@staticmethod
|
28
|
+
def from_et(et_element: ElementTree.Element,
|
29
|
+
doc_frags: List[OdxDocFragment]) -> "VariableGroup":
|
30
|
+
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
|
31
|
+
|
32
|
+
return VariableGroup(**kwargs)
|
odxtools/version.py
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import datetime
|
3
3
|
import inspect
|
4
|
+
import mimetypes
|
4
5
|
import os
|
5
6
|
import time
|
6
7
|
import zipfile
|
7
|
-
from typing import Any, Dict,
|
8
|
+
from typing import Any, Dict, Optional
|
8
9
|
|
9
10
|
import jinja2
|
10
11
|
|
@@ -60,7 +61,6 @@ __templates_dir = os.path.sep.join([os.path.dirname(__module_filename), "templat
|
|
60
61
|
def write_pdx_file(
|
61
62
|
output_file_name: str,
|
62
63
|
database: Database,
|
63
|
-
auxiliary_content_specifiers: Optional[List[Tuple[str, bytes]]] = None,
|
64
64
|
templates_dir: str = __templates_dir,
|
65
65
|
) -> bool:
|
66
66
|
"""
|
@@ -68,9 +68,6 @@ def write_pdx_file(
|
|
68
68
|
"""
|
69
69
|
global odxdatabase
|
70
70
|
|
71
|
-
if auxiliary_content_specifiers is None:
|
72
|
-
auxiliary_content_specifiers = []
|
73
|
-
|
74
71
|
odxdatabase = database
|
75
72
|
|
76
73
|
file_index = []
|
@@ -96,12 +93,18 @@ def write_pdx_file(
|
|
96
93
|
# are written based on the database)
|
97
94
|
continue
|
98
95
|
|
99
|
-
template_file_mime_type =
|
96
|
+
template_file_mime_type = None
|
100
97
|
if template_file_name.endswith(".odx-cs"):
|
101
98
|
template_file_mime_type = "application/x-asam.odx.odx-cs"
|
102
99
|
elif template_file_name.endswith(".odx-d"):
|
103
100
|
template_file_mime_type = "application/x-asam.odx.odx-d"
|
104
101
|
|
102
|
+
guessed_mime_type, guessed_encoding = mimetypes.guess_type(template_file_name)
|
103
|
+
if template_file_mime_type is None and guessed_mime_type is not None:
|
104
|
+
template_file_mime_type = guessed_mime_type
|
105
|
+
else:
|
106
|
+
template_file_mime_type = "application/octet-stream"
|
107
|
+
|
105
108
|
in_path = [root]
|
106
109
|
in_path.append(template_file_name)
|
107
110
|
in_file_name = os.path.sep.join(in_path)
|
@@ -115,22 +118,29 @@ def write_pdx_file(
|
|
115
118
|
out_file.write(open(in_file_name, "rb").read())
|
116
119
|
|
117
120
|
# write the auxiliary files
|
118
|
-
for output_file_name,
|
121
|
+
for output_file_name, data_file in database.auxiliary_files.items():
|
119
122
|
file_cdate = datetime.datetime.fromtimestamp(time.time())
|
120
123
|
creation_date = file_cdate.strftime("%Y-%m-%dT%H:%M:%S")
|
121
124
|
|
122
|
-
mime_type =
|
123
|
-
if
|
125
|
+
mime_type = None
|
126
|
+
if output_file_name.endswith(".odx-cs"):
|
124
127
|
mime_type = "application/x-asam.odx.odx-cs"
|
125
|
-
elif
|
128
|
+
elif output_file_name.endswith(".odx-d"):
|
126
129
|
mime_type = "application/x-asam.odx.odx-d"
|
127
130
|
|
131
|
+
guessed_mime_type, guessed_encoding = mimetypes.guess_type(output_file_name)
|
132
|
+
if mime_type is None and guessed_mime_type is not None:
|
133
|
+
mime_type = guessed_mime_type
|
134
|
+
else:
|
135
|
+
mime_type = "application/octet-stream"
|
136
|
+
|
128
137
|
zf_name = os.path.basename(output_file_name)
|
129
138
|
with zf.open(zf_name, "w") as out_file:
|
130
139
|
file_index.append((zf_name, creation_date, mime_type))
|
131
|
-
out_file.write(
|
140
|
+
out_file.write(data_file.read())
|
132
141
|
|
133
142
|
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(templates_dir))
|
143
|
+
jinja_env.globals["getattr"] = getattr
|
134
144
|
jinja_env.globals["hasattr"] = hasattr
|
135
145
|
jinja_env.globals["odxraise"] = jinja2_odxraise_helper
|
136
146
|
jinja_env.globals["make_xml_attrib"] = make_xml_attrib
|
@@ -187,7 +197,7 @@ def write_pdx_file(
|
|
187
197
|
|
188
198
|
# write the index.xml file
|
189
199
|
vars["file_index"] = file_index
|
190
|
-
index_tpl = jinja_env.get_template("index.xml.
|
200
|
+
index_tpl = jinja_env.get_template("index.xml.jinja2")
|
191
201
|
text = index_tpl.render(**vars)
|
192
202
|
zf.writestr("index.xml", text)
|
193
203
|
|
odxtools/xdoc.py
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import
|
3
|
+
from typing import Any, Dict, List, Optional
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .element import NamedElement
|
7
7
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
8
|
+
from .snrefcontext import SnRefContext
|
8
9
|
from .utils import dataclass_fields_asdict
|
9
10
|
|
10
|
-
if TYPE_CHECKING:
|
11
|
-
from .diaglayer import DiagLayer
|
12
|
-
|
13
11
|
|
14
12
|
@dataclass
|
15
13
|
class XDoc(NamedElement):
|
@@ -45,5 +43,5 @@ class XDoc(NamedElement):
|
|
45
43
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
46
44
|
pass
|
47
45
|
|
48
|
-
def _resolve_snrefs(self,
|
46
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
49
47
|
pass
|