Skip to content

Commit

Permalink
Added ECU reset plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
Cedric PAILLE committed Jun 30, 2017
1 parent 45ce62b commit f239b7f
Show file tree
Hide file tree
Showing 13 changed files with 905 additions and 24 deletions.
4 changes: 4 additions & 0 deletions ddt4all.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,10 @@ def __init__(self, parent = None):

category = plug.category
name = plug.plugin_name
need_hw = plug.need_hw

#if options.simulation_mode and need_hw:
# continue

if not category in category_menus:
category_menus[category] = plugins_menu.addMenu(category)
Expand Down
28 changes: 25 additions & 3 deletions ecu.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ def build_data_stream(self, data):
else:
raise KeyError('Data %s does not exist' % k)

if v in data.items:
v = hex(data.items[v])[2:].upper()

data.setValue(v, data_stream, datatitem, self.ecu_file.endianness)

return data_stream
Expand Down Expand Up @@ -624,6 +627,13 @@ def getDisplayValue(self, elm_data, dataitem, ecu_endian):

return str(res)

def getIntValue(self, resp, dataitem, ecu_endian):
val = self.getHexValue(resp, dataitem, ecu_endian)
if val is None:
return None

return int("0x"+val, 16)

def getHexValue(self, resp, dataitem, ecu_endian):
little_endian = False

Expand Down Expand Up @@ -718,7 +728,12 @@ def __init__(self, data, isfile=False):
if not data:
return

if isfile and '.json' in str(data):
if isfile:
if not os.path.exists(data):
if os.path.exists("./ecus/" + data + ".xml"):
data = "./ecus/" + data + ".xml"

if isfile and '.json' in data:
data2 = "./json/" + data
if os.path.exists(data):
jsfile = open(data, "r")
Expand All @@ -730,8 +745,12 @@ def __init__(self, data, isfile=False):
jsfile.close()
else:
# Zipped json here
zf = zipfile.ZipFile('ecu.zip', mode='r')
jsdata = zf.read(data)
if os.path.exists('ecu.zip'):
zf = zipfile.ZipFile('ecu.zip', mode='r')
if data in zf.namelist():
jsdata = zf.read(data)
else:
print "Cannot found file ", data

ecudict = json.loads(jsdata)

Expand Down Expand Up @@ -766,6 +785,9 @@ def __init__(self, data, isfile=False):
self.data[k] = Ecu_data(v, k)
else:
if isfile:
if not os.path.exists(data):
print "Cannot load ECU file", data
return
xdom = xml.dom.minidom.parse(data)
self.xmldoc = xdom.documentElement
else:
Expand Down
9 changes: 7 additions & 2 deletions package.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,21 @@ def zipdir(dirname):
print "Adding source file %s" % file
zip.write(file)

files = glob.glob("plugins/*.py")
for file in files:
print "Adding plugin file %s" % file
zip.write(file)

zip.write("ecu.zip")
zip.write("DDT4ALL.BAT")
zip.write("json/")
zip.write("logs/")
zip.write("ecus/")

zipdir("./Python27")
zipdir("./importlib")
zipdir("./serial")
zipdir("./icons")
#zipdir("./json")
zipdir("./locale")
zipdir("./crcmod")

zip.close()
17 changes: 6 additions & 11 deletions plugins/card_programming.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,21 @@

plugin_name = "Megane/Scenic II card programming"
category = "Keys"
need_hw = True


def get_isk(ecu, ecu_response = None):
isk_data_name = u'ISK Code'
request_ab_frame_name = u'Trame AB: Trame réservée'

# ECU Request
abframe_request = ecu.requests[request_ab_frame_name]

return abframe_request.get_values_from_stream(ecu_response)[isk_data_name]
def get_isk(ecu, ecu_response):
ecu_response = ecu_response.replace(' ', '').strip()
return ecu_response[19 * 2:25 * 2]


def plugin_entry():
megane_ecu = ecu.Ecu_file("./plugins/ecu_def/UCH_Megane.json", True)
megane_ecu = ecu.Ecu_file("UCH_84_J84_03_60.json", True)

# Request gathering
start_session_request = megane_ecu.requests[u'Start Diagnostic Session']
after_sale_request = megane_ecu.requests[u'ACCEDER AU MODE APRES-VENTE']
learn_key_request = megane_ecu.requests[u'APPRENDRE BADGE']
tester_present_request = megane_ecu.requests[u'Tester present']
#tester_present_request = megane_ecu.requests[u'Tester present']

# First generate a list of bytes representing the frame to be sent to the ELM
# A template of it is available in the 'sentbytes' member of an 'Ecu_request' class
Expand Down
105 changes: 105 additions & 0 deletions plugins/clio3_eps_reset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# -*- coding: utf-8 -*-

# (c) 2017


import PyQt4.QtGui as gui
import PyQt4.QtCore as core
import ecu
import options
import elm

plugin_name = "Modus/Clio III EPS Reset"
category = "EPS Tools"
need_hw = True


class Virginizer(gui.QDialog):
def __init__(self):
super(Virginizer, self).__init__()
self.clio_eps = ecu.Ecu_file("DAE_J77_X85_Gen2___v3.7.json", True)
layout = gui.QVBoxLayout()
infos = gui.QLabel("Modus/Clio III EPS VIRGINIZER<br><font color='red'>THIS PLUGIN WILL RESET EPS IMMO DATA<br>GO AWAY IF YOU HAVE NO IDEA OF WHAT IT MEANS</font")
infos.setAlignment(core.Qt.AlignHCenter)
check_button = gui.QPushButton("Check EPS Virgin")
self.status_check = gui.QLabel("Waiting")
self.status_check.setAlignment(core.Qt.AlignHCenter)
self.virginize_button = gui.QPushButton("Virginize EPS")
layout.addWidget(infos)
layout.addWidget(check_button)
layout.addWidget(self.status_check)
layout.addWidget(self.virginize_button)
self.setLayout(layout)
self.virginize_button.setEnabled(False)
self.virginize_button.clicked.connect(self.reset_ecu)
check_button.clicked.connect(self.check_virgin_status)
self.ecu_connect()

def ecu_connect(self):
short_addr = elm.get_can_addr(self.clio_eps.ecu_send_id)
ecu_conf = {'idTx': self.clio_eps.ecu_send_id, 'idRx':
self.clio_eps.ecu_recv_id, 'ecuname': ""}
if not options.simulation_mode:
options.elm.set_can_addr(short_addr, ecu_conf)
else:
print "Connect to ", self.clio_eps.ecu_send_id, self.clio_eps.ecu_recv_id

def check_virgin_status(self):
virgin_data_name = u"Dongle status"
virigin_check_request = self.clio_eps.requests[u'RDBLI - System Frame']
virgin_data_bit = virigin_check_request.dataitems[virgin_data_name]
virgin_ecu_data = self.clio_eps.data[virgin_data_name]

request_stream = virigin_check_request.build_data_stream({})
request_stream = " ".join(request_stream)

self.start_diag_session_fb()
if options.simulation_mode:
# Simulate virgin ECU
# Blank bit is 4th byte (0=learnt, 1=blank,3=not operational)
elmstream = "62 01 64 00 00 00 00 00 00 00 00 00 00 FF 00"
# Simulate coded ECU
elmstream = "62 01 64 00 00 00 00 00 00 00 00 00 00 00 00"
print "Send request stream", request_stream
else:
elmstream = options.elm.request(request_stream)

if elmstream == "WRONG RESPONSE":
self.virginize_button.setEnabled(False)
self.status_check.setText("<font color='red'>Communication problem</font>")
return

value = virgin_ecu_data.getIntValue(elmstream, virgin_data_bit, self.clio_eps.endianness)
virgin = value == 0

if virgin:
self.virginize_button.setEnabled(False)
self.status_check.setText("<font color='green'>EPS virgin</font>")
return
else:
self.virginize_button.setEnabled(True)
self.status_check.setText("<font color='red'>EPS coded</font>")
return

def start_diag_session_fb(self):
sds_request = self.clio_eps.requests[u"SDS - Start Diagnostic $FB"]
sds_stream = " ".join(sds_request.build_data_stream({}))
if options.simulation_mode:
print "SdSFB stream", sds_stream
return
options.elm.start_session_can(sds_stream)

def reset_ecu(self):
reset_request = self.clio_eps.requests[u"WDBLI - Erase of Dongle_ID code"]
reset_stream = " ".join(reset_request.build_data_stream({}))
self.start_diag_session_fb()
if options.simulation_mode:
print "Reset stream", reset_stream
return
# Reset can only be done in study diag session
options.elm.request(reset_stream)


def plugin_entry():
v = Virginizer()
v.exec_()
111 changes: 111 additions & 0 deletions plugins/clio4_eps_reset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# -*- coding: utf-8 -*-

# (c) 2017


import PyQt4.QtGui as gui
import PyQt4.QtCore as core
import ecu
import options
import elm

plugin_name = "Clio IV EPS Reset"
category = "EPS Tools"
need_hw = True


class Virginizer(gui.QDialog):
def __init__(self):
super(Virginizer, self).__init__()
self.clio_eps = ecu.Ecu_file("EPS_X98.json", True)
layout = gui.QVBoxLayout()
infos = gui.QLabel("Clio IV EPS VIRGINIZER<br><font color='red'>THIS PLUGIN WILL RESET EPS IMMO DATA<br>GO AWAY IF YOU HAVE NO IDEA OF WHAT IT MEANS</font")
infos.setAlignment(core.Qt.AlignHCenter)
check_button = gui.QPushButton("Check EPS Virgin")
self.status_check = gui.QLabel("Waiting")
self.status_check.setAlignment(core.Qt.AlignHCenter)
self.virginize_button = gui.QPushButton("Virginize EPS")
layout.addWidget(infos)
layout.addWidget(check_button)
layout.addWidget(self.status_check)
layout.addWidget(self.virginize_button)
self.setLayout(layout)
self.virginize_button.setEnabled(False)
self.virginize_button.clicked.connect(self.reset_ecu)
check_button.clicked.connect(self.check_virgin_status)
self.ecu_connect()

def ecu_connect(self):
short_addr = elm.get_can_addr(self.clio_eps.ecu_send_id)
ecu_conf = {'idTx': self.clio_eps.ecu_send_id, 'idRx':
self.clio_eps.ecu_recv_id, 'ecuname': ""}
if not options.simulation_mode:
options.elm.set_can_addr(short_addr, ecu_conf)
else:
print "Connect to ", self.clio_eps.ecu_send_id, self.clio_eps.ecu_recv_id

def check_virgin_status(self):
virgin_data_name = u"DongleState"
virigin_check_request = self.clio_eps.requests[u'DataRead.DongleState']
virgin_data_bit = virigin_check_request.dataitems[virgin_data_name]
virgin_ecu_data = self.clio_eps.data[virgin_data_name]

request_stream = virigin_check_request.build_data_stream({})
request_stream = " ".join(request_stream)

self.start_diag_session_fa()
if options.simulation_mode:
# Simulate virgin ECU
# Blank bit is 4th byte (0=learnt, 1=blank,3=not operational)
elmstream = "62 01 64 00 00 00 00 00 00 00 00 00 00 FF 00"
# Simulate coded ECU
elmstream = "62 01 64 00 00 00 00 00 00 00 00 00 00 00 00"
print "Send request stream", request_stream
else:
elmstream = options.elm.request(request_stream)

if elmstream == "WRONG RESPONSE":
self.virginize_button.setEnabled(False)
self.status_check.setText("<font color='red'>Communication problem</font>")
return

value = virgin_ecu_data.getIntValue(elmstream, virgin_data_bit, self.clio_eps.endianness)
virgin = value == 1
not_operational = value == 3

if not_operational:
self.virginize_button.setEnabled(False)
self.status_check.setText("<font color='green'>EPS not operational</font>")
return

if virgin:
self.virginize_button.setEnabled(False)
self.status_check.setText("<font color='green'>EPS virgin</font>")
return
else:
self.virginize_button.setEnabled(True)
self.status_check.setText("<font color='red'>EPS coded</font>")
return

def start_diag_session_fa(self):
sds_request = self.clio_eps.requests[u"StartDiagnosticSession.supplierSession"]
sds_stream = " ".join(sds_request.build_data_stream({}))
if options.simulation_mode:
print "SdSFA stream", sds_stream
return
options.elm.start_session_can(sds_stream)

def reset_ecu(self):
reset_request = self.clio_eps.requests[u"SRBLID.DongleBlanking.Request"]
reset_stream = " ".join(reset_request.build_data_stream({u'Dongle.Code': '1976'}))
self.start_diag_session_fa()
if options.simulation_mode:
print "Reset stream", reset_stream
return
# Reset can only be done in study diag session
options.elm.request(reset_stream)


def plugin_entry():
v = Virginizer()
v.exec_()
Loading

0 comments on commit f239b7f

Please sign in to comment.