Send multiple dataids in one data request
This commit is contained in:
parent
f34a4f2733
commit
a3213ce6e2
@ -150,6 +150,9 @@ class ECU:
|
||||
|
||||
self.elm.start_session( self.ecudata['startDiagReq'] )
|
||||
|
||||
if self.ecudata['pin'].lower()=='can' and self.DataIds:
|
||||
self.elm.checkPerformaceLevel(self.DataIds)
|
||||
|
||||
print "Done"
|
||||
|
||||
global ecudump
|
||||
@ -347,8 +350,9 @@ class ECU:
|
||||
else:
|
||||
initScreen = chr(27)+"[2J"+chr(27)+"[;H"
|
||||
|
||||
|
||||
csvf = 0
|
||||
self.elm.currentScreenDataIds = []
|
||||
|
||||
mask = False
|
||||
masks = []
|
||||
datarefsToRemove = []
|
||||
@ -386,6 +390,7 @@ class ECU:
|
||||
if mod_globals.opt_csv and mod_globals.ext_cur_DTC == '000000':
|
||||
# prepare to csv save
|
||||
self.minimumrefreshrate = 0
|
||||
mod_globals.opt_perform = True
|
||||
csvline = "sep=\\t\n"
|
||||
csvline += u"Time"
|
||||
nparams = 0
|
||||
@ -527,6 +532,8 @@ class ECU:
|
||||
time.sleep(tb + self.minimumrefreshrate - tc)
|
||||
tb = tc
|
||||
|
||||
self.elm.currentScreenDataIds = self.getDataIds(self.elm.rsp_cache.keys(), self.DataIds)
|
||||
|
||||
if kb.kbhit():
|
||||
c = kb.getch()
|
||||
if len(c)!=1: continue
|
||||
@ -1026,6 +1033,23 @@ class ECU:
|
||||
map[key] = label
|
||||
|
||||
return map
|
||||
|
||||
def getDataIds(self, cache, dataids):
|
||||
dataIdsList = []
|
||||
if self.elm.performanceModeLevel == 1:
|
||||
return dataIdsList
|
||||
|
||||
for key in cache:
|
||||
if key.startswith('22'):
|
||||
if key[2:] in dataids.keys():
|
||||
dataIdsList.append(dataids[key[2:]])
|
||||
|
||||
chunk_size = self.elm.performanceModeLevel
|
||||
if dataIdsList:
|
||||
# split dataIdsList into chunks based on the performace level
|
||||
return [dataIdsList[offset:offset+chunk_size] for offset in range(0, len(dataIdsList), chunk_size)]
|
||||
|
||||
return dataIdsList
|
||||
|
||||
def bukva( bt, l, sign = False ):
|
||||
S1 = chr((bt-l) % 26 + ord('A'))
|
||||
|
@ -58,8 +58,14 @@ def executeService( service, elm, status = [], param = "", cache = False ):
|
||||
#tb = time.time() #start time
|
||||
#tc = tb
|
||||
|
||||
sentDataIdentifires = [] #dataids sent in one 22 request, nedded for a response parse
|
||||
performanceMode = mod_globals.opt_perform and elm.performanceModeLevel > 1
|
||||
|
||||
commandToSend = service.startReq
|
||||
|
||||
|
||||
if performanceMode and elm.currentScreenDataIds:
|
||||
commandToSend, sentDataIdentifires = prepareComplexRequest(service.startReq, elm.currentScreenDataIds)
|
||||
|
||||
if len(service.params)>0: # but I support only one and do not support SnapShot
|
||||
if service.params[0]['type']=='DTC':
|
||||
param = mod_globals.ext_cur_DTC
|
||||
@ -78,6 +84,9 @@ def executeService( service, elm, status = [], param = "", cache = False ):
|
||||
rsp = rspStrip( rsp, commandToSend )
|
||||
first_rsp = rsp
|
||||
|
||||
if performanceMode and sentDataIdentifires:
|
||||
first_rsp = parseComplexResponse(elm, service.simpleRsp, rsp, sentDataIdentifires)
|
||||
|
||||
#print "Status:", status
|
||||
#print "Delay:",localDelay,
|
||||
#print "startReq ", service.startReq
|
||||
@ -151,6 +160,43 @@ def executeService( service, elm, status = [], param = "", cache = False ):
|
||||
print "\nSomething went wrong. Counter reached maximum value.\n"
|
||||
return ""
|
||||
|
||||
def prepareComplexRequest(request, screenDataIds):
|
||||
commandToSend = request
|
||||
sentDataIdentifires = []
|
||||
screenDataIdsNumber = len(screenDataIds[0])
|
||||
|
||||
if screenDataIdsNumber > 1:
|
||||
firstDataId = screenDataIds[0][0].id
|
||||
if firstDataId == request[2:]:
|
||||
commandToSend = request[:2]
|
||||
for did in screenDataIds[0]:
|
||||
commandToSend += did.id
|
||||
|
||||
sentDataIdentifires = screenDataIds.pop(0)
|
||||
|
||||
return commandToSend, sentDataIdentifires
|
||||
|
||||
def parseComplexResponse(elm, positiveRsp, response, sentDataIds):
|
||||
first_rsp = ''
|
||||
posInResp = 2
|
||||
byteLength = 2
|
||||
sentDataIdsLength = len(sentDataIds)
|
||||
|
||||
for i in range(sentDataIdsLength):
|
||||
dataId = response[posInResp:posInResp + 2 * byteLength]
|
||||
posInResp += 2 * byteLength
|
||||
didDataLength = int(sentDataIds[i].dataBitLength)/8
|
||||
didData = response[posInResp: posInResp + didDataLength * byteLength]
|
||||
posInResp += didDataLength * byteLength
|
||||
if i == 0:
|
||||
first_rsp = positiveRsp + dataId + didData
|
||||
|
||||
resp = positiveRsp + dataId + didData
|
||||
resp = ' '.join(a+b for a,b in zip(resp[::2], resp[1::2]))
|
||||
|
||||
elm.rsp_cache['22' + dataId] = resp
|
||||
|
||||
return first_rsp
|
||||
|
||||
class ecu_service:
|
||||
|
||||
|
@ -12,6 +12,7 @@ import string
|
||||
import threading
|
||||
import socket
|
||||
from datetime import datetime
|
||||
from collections import OrderedDict
|
||||
|
||||
try:
|
||||
import androidhelper as android
|
||||
@ -517,6 +518,7 @@ class ELM:
|
||||
lastCMDtime = 0 # time when last command was sent to bus
|
||||
portTimeout = 5 # timeout of port (com or tcp)
|
||||
elmTimeout = 0 # timeout set by ATST
|
||||
performanceModeLevel = 1 # number of dataids, that can be sent in one 22 request
|
||||
|
||||
# error counters
|
||||
error_frame = 0
|
||||
@ -536,7 +538,8 @@ class ELM:
|
||||
startSession = ""
|
||||
lastinitrsp = ""
|
||||
|
||||
rsp_cache = {} # cashes responses for current screen
|
||||
currentScreenDataIds = [] #dataids displayed on current screen
|
||||
rsp_cache = OrderedDict() # cashes responses for current screen
|
||||
l1_cache = {} # save number of frames in responces
|
||||
notSupportedCommands = {} # save them to not slow down polling
|
||||
ecudump = {} # for demo only. contains responses for all 21xx and 22xxxx requests
|
||||
@ -620,7 +623,7 @@ class ELM:
|
||||
""" Clear L2 cache before screen update
|
||||
"""
|
||||
#print 'Clearing L2 cache'
|
||||
self.rsp_cache = {}
|
||||
self.rsp_cache = OrderedDict()
|
||||
|
||||
# if not mod_globals.opt_demo:
|
||||
# self.rsp_cache = {}
|
||||
@ -1926,7 +1929,7 @@ class ELM:
|
||||
|
||||
self.check_answer (self.cmd ("at at 1")) # reset adaptive timing step 3
|
||||
self.check_answer (self.cmd ("at cra " + RXa))
|
||||
|
||||
|
||||
self.check_adapter ()
|
||||
|
||||
def init_iso(self):
|
||||
@ -2006,6 +2009,24 @@ class ELM:
|
||||
self.check_answer(self.cmd("81")) # start session
|
||||
|
||||
self.check_adapter ()
|
||||
|
||||
#check if ELM uderstand full Single Frame with desired response length
|
||||
def checkPerformaceLevel(self, dataids):
|
||||
performanceLevels = [3, 2]
|
||||
|
||||
for level in performanceLevels:
|
||||
if len(dataids) >= level:
|
||||
paramToSend = ''
|
||||
frameLength = '{:02X}'.format(1 + level * 2)
|
||||
|
||||
for i in range(level):
|
||||
paramToSend += dataids.keys()[i]
|
||||
cmd = frameLength + '22' + paramToSend + '1'
|
||||
|
||||
resp = self.send_raw(cmd)
|
||||
if not '?' in resp and resp[2:4] != '7F':
|
||||
self.performanceModeLevel = level
|
||||
return
|
||||
|
||||
def reset_elm(self):
|
||||
self.cmd ("at z")
|
||||
|
@ -32,6 +32,7 @@ opt_can2 = False #can connected to pins 13 and 12
|
||||
opt_ddtxml = ""
|
||||
opt_stn = False
|
||||
opt_sd = False #separate doc files
|
||||
opt_perform = False
|
||||
|
||||
dumpName = ""
|
||||
|
||||
|
@ -237,7 +237,9 @@ def optParser():
|
||||
else:
|
||||
print "Development MODE"
|
||||
mod_globals.opt_dev = True
|
||||
mod_globals.opt_devses = options.dev
|
||||
mod_globals.opt_devses = options.dev
|
||||
if mod_globals.os == 'android':
|
||||
mod_globals.opt_perform = True
|
||||
|
||||
def main():
|
||||
'''Main function'''
|
||||
|
Loading…
x
Reference in New Issue
Block a user