9n
- fix for wifi adapters with short connection timeout - sorting car models - more accurate dump diff - typos in README
This commit is contained in:
parent
508667b9e9
commit
bd5ab19260
13
README.md
13
README.md
@ -1,5 +1,5 @@
|
|||||||
# PYREN
|
# pyren
|
||||||
pyren is a program for geting diagnostic data from Renault cars by ELM327 adapter. It works in two modes and with two types of databases accordingly.
|
pyren is a program for getting diagnostic data from Renault cars by ELM327 adapter. It works in two modes and with two types of databases accordingly.
|
||||||
Compatible with Windows, Linux, MacOS and Android(only CLIP mode under Android)
|
Compatible with Windows, Linux, MacOS and Android(only CLIP mode under Android)
|
||||||
|
|
||||||
## CLIP mode
|
## CLIP mode
|
||||||
@ -48,10 +48,9 @@ cd c:\CLIP\Data\GenAppli\
|
|||||||
dir
|
dir
|
||||||
```
|
```
|
||||||
This directory should contains at least the next subdirectories
|
This directory should contains at least the next subdirectories
|
||||||
*EcuRenault
|
* EcuRenault
|
||||||
*Location
|
* Location
|
||||||
*Vehicles
|
* Vehicles
|
||||||
*BVMEXTRACTION (required for doc_maker.py)
|
|
||||||
|
|
||||||
Install pyren
|
Install pyren
|
||||||
```
|
```
|
||||||
@ -95,7 +94,7 @@ sl4a/scripts
|
|||||||
|- EcuRenault
|
|- EcuRenault
|
||||||
|- Location
|
|- Location
|
||||||
|- Vehicles
|
|- Vehicles
|
||||||
|- pyren
|
|- pyren
|
||||||
| |- pyren.py
|
| |- pyren.py
|
||||||
... ...
|
... ...
|
||||||
| |- <other modules>
|
| |- <other modules>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# PYREN
|
# pyren
|
||||||
pyren is a program for geting diagnostic data from Renault cars by ELM327 adapter. It works in two modes and with two types of databases accordingly.
|
pyren is a program for getting diagnostic data from Renault cars by ELM327 adapter. It works in two modes and with two types of databases accordingly.
|
||||||
Compatible with Windows, Linux, MacOS and Android(only CLIP mode under Android)
|
Compatible with Windows, Linux, MacOS and Android(only CLIP mode under Android)
|
||||||
|
|
||||||
## CLIP mode
|
## CLIP mode
|
||||||
@ -48,10 +48,9 @@ cd c:\CLIP\Data\GenAppli\
|
|||||||
dir
|
dir
|
||||||
```
|
```
|
||||||
This directory should contains at least the next subdirectories
|
This directory should contains at least the next subdirectories
|
||||||
*EcuRenault
|
* EcuRenault
|
||||||
*Location
|
* Location
|
||||||
*Vehicles
|
* Vehicles
|
||||||
*BVMEXTRACTION (required for doc_maker.py)
|
|
||||||
|
|
||||||
Install pyren
|
Install pyren
|
||||||
```
|
```
|
||||||
@ -95,7 +94,7 @@ sl4a/scripts
|
|||||||
|- EcuRenault
|
|- EcuRenault
|
||||||
|- Location
|
|- Location
|
||||||
|- Vehicles
|
|- Vehicles
|
||||||
|- pyren
|
|- pyren
|
||||||
| |- pyren.py
|
| |- pyren.py
|
||||||
... ...
|
... ...
|
||||||
| |- <other modules>
|
| |- <other modules>
|
||||||
|
@ -260,7 +260,7 @@ class DDT_MON():
|
|||||||
if fid in self.f2r.keys() and fid in self.frames.keys():
|
if fid in self.f2r.keys() and fid in self.frames.keys():
|
||||||
val = self.decu.getValue(d, False, self.f2r[fid], self.frames[fid]['data'])
|
val = self.decu.getValue(d, False, self.f2r[fid], self.frames[fid]['data'])
|
||||||
else:
|
else:
|
||||||
val = 'None'
|
val = mod_globals.none_val
|
||||||
self.datas[d] = val
|
self.datas[d] = val
|
||||||
|
|
||||||
clearScreen()
|
clearScreen()
|
||||||
@ -457,7 +457,8 @@ def main():
|
|||||||
mon.framefilter = mon.framefilter[:-1]
|
mon.framefilter = mon.framefilter[:-1]
|
||||||
mon.setFilter( mon.framefilter )
|
mon.setFilter( mon.framefilter )
|
||||||
else:
|
else:
|
||||||
mon.framefilter = mon.framefilter + '<' + str(ord(c)) + '>'
|
pass
|
||||||
|
#mon.framefilter = mon.framefilter + '<' + str(ord(c)) + '>'
|
||||||
|
|
||||||
time.sleep( 0.03 )
|
time.sleep( 0.03 )
|
||||||
ct = time.time()
|
ct = time.time()
|
||||||
|
@ -842,7 +842,35 @@ class DDTECU():
|
|||||||
cmdPatt = cmdPatt[0:sb*2] + value + cmdPatt[(sb+bytes)*2:]
|
cmdPatt = cmdPatt[0:sb*2] + value + cmdPatt[(sb+bytes)*2:]
|
||||||
|
|
||||||
return cmdPatt
|
return cmdPatt
|
||||||
|
|
||||||
|
def getValueForConfig_second_cmd(self, d, first_cmd):
|
||||||
|
# sometimes the same parameter may be accesible thru 2E and 3B
|
||||||
|
|
||||||
|
res = 'ERROR'
|
||||||
|
rcmd = ''
|
||||||
|
for c in self.requests.keys():
|
||||||
|
if c == first_cmd: continue
|
||||||
|
if d in self.requests[c].ReceivedDI.keys():
|
||||||
|
rcmd = c
|
||||||
|
break
|
||||||
|
|
||||||
|
if rcmd == '':
|
||||||
|
return 'ERROR'
|
||||||
|
|
||||||
|
if self.datas[d].BytesASCII:
|
||||||
|
res = self.getValue(d, request=self.requests[rcmd])
|
||||||
|
else:
|
||||||
|
gh = self.getHex(d, request=self.requests[rcmd])
|
||||||
|
if gh != mod_globals.none_val:
|
||||||
|
res = '0x' + gh
|
||||||
|
else:
|
||||||
|
res = gh
|
||||||
|
|
||||||
|
#debug
|
||||||
|
#print 'getValueForConfig_second_cmd', d, self.requests[rcmd].SentBytes, res
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
def getValueForConfig(self, d):
|
def getValueForConfig(self, d):
|
||||||
|
|
||||||
res = 'ERROR'
|
res = 'ERROR'
|
||||||
@ -861,6 +889,9 @@ class DDTECU():
|
|||||||
else:
|
else:
|
||||||
res = gh
|
res = gh
|
||||||
|
|
||||||
|
if ( res==mod_globals.none_val ): #try to find second command
|
||||||
|
res = self.getValueForConfig_second_cmd(d,rcmd)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def makeConf( self, indump = False ):
|
def makeConf( self, indump = False ):
|
||||||
@ -885,15 +916,28 @@ class DDTECU():
|
|||||||
for di in r.SentDI.values ():
|
for di in r.SentDI.values ():
|
||||||
d = di.Name
|
d = di.Name
|
||||||
|
|
||||||
val = self.getValueForConfig( d )
|
|
||||||
|
|
||||||
if indump:
|
if indump:
|
||||||
if d in self.req4data.keys ():
|
if d in self.req4data.keys ():
|
||||||
|
first_cmd = self.req4data[d]
|
||||||
i_r_cmd = self.requests[self.req4data[d]].SentBytes
|
i_r_cmd = self.requests[self.req4data[d]].SentBytes
|
||||||
if i_r_cmd not in self.elm.ecudump.keys() or \
|
if i_r_cmd not in self.elm.ecudump.keys() or \
|
||||||
(i_r_cmd in self.elm.ecudump.keys() and self.elm.ecudump[i_r_cmd]==''):
|
(i_r_cmd in self.elm.ecudump.keys() and self.elm.ecudump[i_r_cmd]==''):
|
||||||
continue
|
#try to find second
|
||||||
|
second_is = False
|
||||||
|
for c in self.requests.keys():
|
||||||
|
if c == first_cmd: continue
|
||||||
|
if d in self.requests[c].ReceivedDI.keys():
|
||||||
|
#self.req4data[d] = c # may be removed
|
||||||
|
second_is = True
|
||||||
|
break
|
||||||
|
if not second_is:
|
||||||
|
continue
|
||||||
|
|
||||||
|
val = self.getValueForConfig( d )
|
||||||
|
|
||||||
|
#debug
|
||||||
|
#print '>', d,'=',val
|
||||||
|
|
||||||
if 'ERROR' in val:
|
if 'ERROR' in val:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -939,7 +983,13 @@ class DDTECU():
|
|||||||
config.append (sendCmd)
|
config.append (sendCmd)
|
||||||
|
|
||||||
sentValues.clear ()
|
sentValues.clear ()
|
||||||
|
|
||||||
|
#debug
|
||||||
|
#print config
|
||||||
|
#print '*'*50
|
||||||
|
#print conf_v
|
||||||
|
#print '*'*50
|
||||||
|
|
||||||
return config, conf_v
|
return config, conf_v
|
||||||
|
|
||||||
def bukva( self, bt, l, sign=False):
|
def bukva( self, bt, l, sign=False):
|
||||||
|
@ -106,7 +106,7 @@ class InfoDialog (tkSimpleDialog.Dialog):
|
|||||||
def hnid_func(self):
|
def hnid_func(self):
|
||||||
self.txt.delete('1.0', tk.END)
|
self.txt.delete('1.0', tk.END)
|
||||||
for t in self.orig_text.split('---\n'):
|
for t in self.orig_text.split('---\n'):
|
||||||
if 'None' not in t:
|
if mod_globals.none_val not in t:
|
||||||
self.txt.insert(tk.END, t + '---\n')
|
self.txt.insert(tk.END, t + '---\n')
|
||||||
|
|
||||||
class ListDialog (tkSimpleDialog.Dialog):
|
class ListDialog (tkSimpleDialog.Dialog):
|
||||||
@ -585,14 +585,27 @@ class DDTScreen (tk.Frame):
|
|||||||
self.root.after_cancel(self.jid)
|
self.root.after_cancel(self.jid)
|
||||||
self.decu.rotaryRunAlloved.clear()
|
self.decu.rotaryRunAlloved.clear()
|
||||||
|
|
||||||
(conf_2, cv_2) = self.decu.makeConf()
|
(conf_2, cv_2_tmp) = self.decu.makeConf()
|
||||||
|
|
||||||
|
cv_2 = copy.deepcopy(cv_2_tmp)
|
||||||
|
|
||||||
|
#clear memory
|
||||||
|
del (conf_2)
|
||||||
|
del (cv_2_tmp)
|
||||||
|
|
||||||
savedMode = mod_globals.opt_demo
|
savedMode = mod_globals.opt_demo
|
||||||
mod_globals.opt_demo = True
|
mod_globals.opt_demo = True
|
||||||
saveDumpName = mod_globals.dumpName
|
saveDumpName = mod_globals.dumpName
|
||||||
self.decu.loadDump(fname)
|
self.decu.loadDump(fname)
|
||||||
|
|
||||||
(conf_1, cv_1) = self.decu.makeConf(indump = True)
|
(conf_1, cv_1_tmp) = self.decu.makeConf(indump = True)
|
||||||
|
|
||||||
|
cv_1 = copy.deepcopy(cv_1_tmp)
|
||||||
|
|
||||||
|
# clear memory
|
||||||
|
del (conf_1)
|
||||||
|
del (cv_1_tmp)
|
||||||
|
|
||||||
du_1 = copy.deepcopy (self.decu.elm.ecudump)
|
du_1 = copy.deepcopy (self.decu.elm.ecudump)
|
||||||
|
|
||||||
mod_globals.dumpName = saveDumpName
|
mod_globals.dumpName = saveDumpName
|
||||||
@ -602,6 +615,12 @@ class DDTScreen (tk.Frame):
|
|||||||
else:
|
else:
|
||||||
self.decu.clearELMcache()
|
self.decu.clearELMcache()
|
||||||
|
|
||||||
|
#debug
|
||||||
|
#print cv_2
|
||||||
|
#print '#'*100
|
||||||
|
#print cv_1
|
||||||
|
#print '#'*100
|
||||||
|
|
||||||
aK = list(set(cv_1) | set(cv_2))
|
aK = list(set(cv_1) | set(cv_2))
|
||||||
|
|
||||||
# show confirmation dialog if approve is True
|
# show confirmation dialog if approve is True
|
||||||
@ -610,20 +629,28 @@ class DDTScreen (tk.Frame):
|
|||||||
xText += '> ' + self.dumpName2str(mod_globals.dumpName) + '\n\n'
|
xText += '> ' + self.dumpName2str(mod_globals.dumpName) + '\n\n'
|
||||||
else:
|
else:
|
||||||
xText += '> Current ECU state\n'
|
xText += '> Current ECU state\n'
|
||||||
|
|
||||||
|
#debug
|
||||||
|
#print du_1
|
||||||
|
|
||||||
flag = True
|
flag = True
|
||||||
for i in aK:
|
for i in aK:
|
||||||
if i in self.decu.req4data.keys ():
|
if i in self.decu.req4data.keys ():
|
||||||
i_r_cmd = self.decu.requests[self.decu.req4data[i]].SentBytes
|
i_r_cmd = self.decu.requests[self.decu.req4data[i]].SentBytes
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
#debug
|
||||||
|
#print '>', i, i_r_cmd
|
||||||
|
|
||||||
if (i not in cv_1.keys()) or (i not in cv_2.keys()) or cv_1[i]!=cv_2[i]:
|
if (i not in cv_1.keys()) or (i not in cv_2.keys()) or cv_1[i]!=cv_2[i]:
|
||||||
flag = False
|
flag = False
|
||||||
xText += ("-"*30+ "\n%s\n" % (i))
|
xText += ("-"*30+ "\n%s\n" % (i))
|
||||||
|
|
||||||
if i_r_cmd not in du_1.keys() or du_1[i_r_cmd]=='':
|
if i in cv_1.keys() and cv_1[i] != '':
|
||||||
xText += "< None\n"
|
|
||||||
elif i in cv_1.keys() and cv_1[i] != '':
|
|
||||||
xText += "< %s\n" % (cv_1[i])
|
xText += "< %s\n" % (cv_1[i])
|
||||||
|
elif i_r_cmd not in du_1.keys() or du_1[i_r_cmd]=='':
|
||||||
|
xText += "< None\n"
|
||||||
else:
|
else:
|
||||||
xText += "< ERROR\n"
|
xText += "< ERROR\n"
|
||||||
|
|
||||||
@ -645,8 +672,6 @@ class DDTScreen (tk.Frame):
|
|||||||
|
|
||||||
# request to update dInputs
|
# request to update dInputs
|
||||||
self.update_dInputs()
|
self.update_dInputs()
|
||||||
del (conf_1)
|
|
||||||
del (conf_2)
|
|
||||||
del (cv_1)
|
del (cv_1)
|
||||||
del (cv_2)
|
del (cv_2)
|
||||||
del (du_1)
|
del (du_1)
|
||||||
@ -1411,7 +1436,7 @@ class DDTScreen (tk.Frame):
|
|||||||
|
|
||||||
if xText not in self.dValue.keys ():
|
if xText not in self.dValue.keys ():
|
||||||
self.dValue[xText] = tk.StringVar ()
|
self.dValue[xText] = tk.StringVar ()
|
||||||
self.dValue[xText].set ('None')
|
self.dValue[xText].set (mod_globals.none_val)
|
||||||
|
|
||||||
obj = tk.Label (frame, text=self.dValue[xText], relief=tk.GROOVE, borderwidth=1, font=lFont,
|
obj = tk.Label (frame, text=self.dValue[xText], relief=tk.GROOVE, borderwidth=1, font=lFont,
|
||||||
textvariable=self.dValue[xText])
|
textvariable=self.dValue[xText])
|
||||||
@ -1707,7 +1732,7 @@ class DDTScreen (tk.Frame):
|
|||||||
|
|
||||||
if xText not in self.dValue.keys():
|
if xText not in self.dValue.keys():
|
||||||
self.dValue[xText] = tk.StringVar()
|
self.dValue[xText] = tk.StringVar()
|
||||||
self.dValue[xText].set('None')
|
self.dValue[xText].set(mod_globals.none_val)
|
||||||
|
|
||||||
obj = tk.Label(frame, text=self.dValue[xText], relief=tk.GROOVE, borderwidth=1, font=lFont,
|
obj = tk.Label(frame, text=self.dValue[xText], relief=tk.GROOVE, borderwidth=1, font=lFont,
|
||||||
textvariable=self.dValue[xText])
|
textvariable=self.dValue[xText])
|
||||||
|
@ -197,6 +197,20 @@ class Port:
|
|||||||
if self.ka_timer:
|
if self.ka_timer:
|
||||||
self.ka_timer.cancel ()
|
self.ka_timer.cancel ()
|
||||||
|
|
||||||
|
def reinit(self):
|
||||||
|
'''
|
||||||
|
Need for wifi adapters with short connection timeout
|
||||||
|
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
|
if self.portType != 1: return
|
||||||
|
|
||||||
|
self.hdr.close()
|
||||||
|
self.hdr = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
self.hdr.setsockopt (socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||||
|
self.hdr.connect ((self.ipaddr, self.tcpprt))
|
||||||
|
self.hdr.setblocking (True)
|
||||||
|
|
||||||
'''
|
'''
|
||||||
def elm_at_KeepAlive(self):
|
def elm_at_KeepAlive(self):
|
||||||
|
|
||||||
@ -1000,7 +1014,8 @@ class ELM:
|
|||||||
self.lf.write ("#[" + tmstr + "]" + "KeepAlive\n")
|
self.lf.write ("#[" + tmstr + "]" + "KeepAlive\n")
|
||||||
self.lf.flush ()
|
self.lf.flush ()
|
||||||
|
|
||||||
# send keepalive
|
# send keepalive
|
||||||
|
self.port.reinit() #experimental
|
||||||
self.send_cmd (self.startSession)
|
self.send_cmd (self.startSession)
|
||||||
self.lastCMDtime = time.time () # for not to get into infinite loop
|
self.lastCMDtime = time.time () # for not to get into infinite loop
|
||||||
|
|
||||||
@ -1711,6 +1726,8 @@ class ELM:
|
|||||||
# sys.exit()
|
# sys.exit()
|
||||||
|
|
||||||
def init_can(self):
|
def init_can(self):
|
||||||
|
|
||||||
|
self.port.reinit()
|
||||||
|
|
||||||
self.currentprotocol = "can"
|
self.currentprotocol = "can"
|
||||||
self.currentaddress = "7e0" # do not tuch
|
self.currentaddress = "7e0" # do not tuch
|
||||||
@ -1797,6 +1814,9 @@ class ELM:
|
|||||||
self.check_adapter ()
|
self.check_adapter ()
|
||||||
|
|
||||||
def init_iso(self):
|
def init_iso(self):
|
||||||
|
|
||||||
|
self.port.reinit()
|
||||||
|
|
||||||
self.currentprotocol = "iso"
|
self.currentprotocol = "iso"
|
||||||
self.currentsubprotocol = ""
|
self.currentsubprotocol = ""
|
||||||
self.currentaddress = ""
|
self.currentaddress = ""
|
||||||
|
@ -80,9 +80,11 @@ class ScanEcus:
|
|||||||
DOMTree = xml.dom.minidom.parse(file)
|
DOMTree = xml.dom.minidom.parse(file)
|
||||||
vh = DOMTree.documentElement
|
vh = DOMTree.documentElement
|
||||||
if vh.hasAttribute("defaultText"):
|
if vh.hasAttribute("defaultText"):
|
||||||
vehiclename = vh.getAttribute("defaultText")
|
vehiclename = vh.getAttribute("defaultText").strip()
|
||||||
vehTypeCode = vh.getAttribute("vehTypeCode")
|
vehTypeCode = vh.getAttribute("vehTypeCode").strip()
|
||||||
self.vhcls.append([vehiclename,file,vehTypeCode])
|
vehTCOM = int(vh.getAttribute("TCOM"))
|
||||||
|
vehindexTopo = int(vh.getAttribute("indexTopo"))
|
||||||
|
self.vhcls.append([vehiclename,file,vehTypeCode,vehTCOM,vehindexTopo])
|
||||||
|
|
||||||
def scanAllEcus(self):
|
def scanAllEcus(self):
|
||||||
'''scan all ecus. If savedEcus.p exists then load it and return'''
|
'''scan all ecus. If savedEcus.p exists then load it and return'''
|
||||||
@ -586,8 +588,9 @@ class ScanEcus:
|
|||||||
self.allecus[name]["ids"] = idtt
|
self.allecus[name]["ids"] = idtt
|
||||||
|
|
||||||
def chooseModel(self, num):
|
def chooseModel(self, num):
|
||||||
|
|
||||||
for row in self.vhcls:
|
# sorted by [vehiclename,file,vehTypeCode,vehTCOM,vehindexTopo]
|
||||||
|
for row in sorted( self.vhcls, key=lambda k : k[1]):
|
||||||
self.models.append( row[2]+" "+row[0] )
|
self.models.append( row[2]+" "+row[0] )
|
||||||
|
|
||||||
if num==0 or num>len(self.models):
|
if num==0 or num>len(self.models):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user