-
Notifications
You must be signed in to change notification settings - Fork 18
/
odis2vcp.py
165 lines (129 loc) · 5.9 KB
/
odis2vcp.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/usr/bin/python
# ODIS2VCP
# Dataset extractor
# Converts datasets from ODIS XML format to VCP XML format
# by Jille
from xml.dom.minidom import *
import binascii, argparse, sys
import xml.etree.cElementTree as ET
# variables
dataset_counter = 0
extracted_dataset_counter = 0
version = "1.0"
# parse arguments
ap = argparse.ArgumentParser(description="ODIS2VCP Dataset extractor v%s" % version)
ap.add_argument("-i", "--in", required=True, help="Input file path")
ap.add_argument("-f", "--fmt", required=False, help="Output format: vcp (default) or raw.")
ap.add_argument("-d", "--desc", required=True, help="Output file description. E.g. \"Seat Leon 2016\" ")
args = vars(ap.parse_args())
file_output_format = args['fmt']
file_prefix = args['desc']
input_file = args['in']
# extract dataset to a raw export of the dataset
def extract_to_raw(dataset, filename, diagnostic_address):
global extracted_dataset_counter
extracted_dataset_counter=extracted_dataset_counter+1
filename = diagnostic_address + " " + filename + ".bin"
print(" Extracting raw data to \"%s\"" % filename)
print()
output_file = open(filename,"wb")
binary_data = binascii.unhexlify(dataset)
output_file.write(binary_data)
output_file.close()
# extract dataset to VCP dataset XML format
def convert_to_vcp(dataset_data, diagnostic_address, start_address, zdc_name, zdc_version, login, filename):
global extracted_dataset_counter
extracted_dataset_counter=extracted_dataset_counter+1
doc = Document();
root = doc.createElement("SW-CNT")
doc.appendChild(root)
ident = doc.createElement("IDENT")
root.appendChild(ident)
login_data = doc.createElement("LOGIN")
dateiid = doc.createElement("DATEIID")
version_inhalt = doc.createElement("VERSION-INHALT")
ident.appendChild(login_data)
ident.appendChild(dateiid)
ident.appendChild(version_inhalt)
login_data.appendChild (doc.createTextNode(login))
dateiid.appendChild (doc.createTextNode(zdc_name))
version_inhalt.appendChild (doc.createTextNode(zdc_version))
datasets = doc.createElement("DATENBEREICHE")
root.appendChild(datasets)
dataset = doc.createElement("DATENBEREICH")
datasets.appendChild (dataset)
dataname = zdc_name + " address - " + start_address
dataset_name = doc.createElement("DATEN-NAME")
dataset.appendChild (dataset_name)
dataset_name.appendChild(doc.createTextNode(zdc_name))
dataset_format = doc.createElement("DATEN-FORMAT-NAME")
dataset.appendChild (dataset_format)
dataset_format.appendChild(doc.createTextNode("DFN_HEX"))
dataset_start = doc.createElement("START-ADR")
dataset.appendChild (dataset_start)
dataset_start.appendChild(doc.createTextNode(start_address))
dataset_raw = dataset_data.replace("0x","")
dataset_raw = dataset_raw.replace(",","")
#some quick and dirty calculations to determine the right size and string format for file size
dataset_size_calc = len(dataset_raw.encode('utf-8'))
dataset_size_calc = dataset_size_calc/2
dataset_size_calc = hex(int(dataset_size_calc))
dataset_size_calc = str(dataset_size_calc)
dataset_size = doc.createElement("GROESSE-DEKOMPRIMIERT")
dataset.appendChild (dataset_size)
dataset_size.appendChild(doc.createTextNode(dataset_size_calc))
data_data = doc.createElement("DATEN")
dataset.appendChild (data_data)
data_data.appendChild(doc.createTextNode(dataset_data))
# write xml data
filename = diagnostic_address + " VCP " + filename + ".xml"
print(" Extracting VCP data to \"%s\"" % filename)
print()
doc.writexml( open(filename, 'w'),
indent=" ",
addindent=" ",
newl='\n')
# Parse single OE XML file
# Print detail of each dataset in small OE XML file
def parse_small_oe_file():
global dataset_counter
# Open XML document using minidom parser
DOMTree = xml.dom.minidom.parse(input_file) #todo: use file input argument
collection = DOMTree.documentElement
#get data from XML
parameter_datas = collection.getElementsByTagName("PARAMETER_DATA")
for parameter_data in parameter_datas:
if parameter_data.hasAttribute("DIAGNOSTIC_ADDRESS"):
diagnostic_address = parameter_data.getAttribute("DIAGNOSTIC_ADDRESS")
diagnostic_address = diagnostic_address.replace ("0x00","")
print(" Module: %s" % diagnostic_address)
if parameter_data.hasAttribute("START_ADDRESS"):
start_address = parameter_data.getAttribute("START_ADDRESS")
print(" Start_Address: %s" % start_address)
if parameter_data.hasAttribute("ZDC_NAME"):
zdc_name = parameter_data.getAttribute("ZDC_NAME")
print(" ZDC Name: %s" % zdc_name)
if parameter_data.hasAttribute("ZDC_VERSION"):
zdc_version = parameter_data.getAttribute("ZDC_VERSION")
print(" ZDC version: %s" % zdc_version)
if parameter_data.hasAttribute("LOGIN"):
login = parameter_data.getAttribute("LOGIN")
print(" Login: %s" % login)
#set filename, e.g. 19 ZL12345 - Seat Leon 2016
filename = start_address + " " + zdc_name + " - " + file_prefix
dataset_counter=dataset_counter+1
dataset = parameter_data.childNodes[0].data
#clean the data from all the 0x and commas
if file_output_format == "raw":
dataset = dataset.replace('0x','')
dataset = dataset.replace(",","")
extract_to_raw(dataset,filename,diagnostic_address)
else:
convert_to_vcp(dataset, diagnostic_address, start_address, zdc_name, zdc_version, login, filename)
# run the parser.
parse_small_oe_file()
print()
if file_output_format == "raw":
print(" %s of %s datasets extracted to %s format" % (extracted_dataset_counter, dataset_counter, file_output_format))
else:
print(" %s of %s datasets extracted to VCP format" % (extracted_dataset_counter, dataset_counter))