2929# #
3030########################################################################
3131
32+ import re
3233import serial
3334import time
3435from .protocols import *
35- from .utils import strip , numBitsSet
36+ from .utils import numBitsSet
3637from .debug import debug
3738
3839
@@ -126,20 +127,28 @@ def __init__(self, portname, baudrate=38400):
126127
127128
128129 # -------------- 0100 (first command, SEARCH protocols) --------------
130+ # TODO: rewrite this using a "wait for prompt character"
131+ # rather than a fixed wait period
129132 r0100 = self .__send ("0100" , delay = 3 ) # give it a second (or three) to search
130133
131134
132135 # ------------------- ATDPN (list protocol number) -------------------
133136 r = self .__send ("ATDPN" )
134- r = strip (r )
137+
138+ if not r :
139+ self .__error ("Describe protocol command didn't return " )
140+ return
141+
142+ p = r [0 ]
143+
135144 # suppress any "automatic" prefix
136- r = r [1 :] if (len (r ) > 1 and r .startswith ("A" )) else r [:- 1 ]
145+ p = p [1 :] if (len (p ) > 1 and p .startswith ("A" )) else p [:- 1 ]
137146
138- if r not in self ._SUPPORTED_PROTOCOLS :
147+ if p not in self ._SUPPORTED_PROTOCOLS :
139148 self .__error ("ELM responded with unknown protocol" )
140149 return
141150
142- self .__protocol = self ._SUPPORTED_PROTOCOLS [r ]()
151+ self .__protocol = self ._SUPPORTED_PROTOCOLS [p ]()
143152
144153
145154 # Now that a protocol has been selected, we can figure out
@@ -155,16 +164,13 @@ def __init__(self, portname, baudrate=38400):
155164 debug ("Connection successful" )
156165 self .__connected = True
157166
158- def __isok (self , data , expectEcho = False ):
159- if not data :
160- return False
161- lines = list (map (str .strip , filter (None , data .split ('\r \n ' ))))
162- if len (lines ) < 2 :
167+ def __isok (self , lines , expectEcho = False ):
168+ if not lines :
163169 return False
164170 if expectEcho :
165- return len (lines ) == 3 and lines [1 ] == 'OK' and lines [ 2 ] == '> '
171+ return len (lines ) == 2 and lines [1 ] == 'OK'
166172 else :
167- return len (lines ) == 2 and lines [0 ] == 'OK' and lines [ 1 ] == '> '
173+ return len (lines ) == 1 and lines [0 ] == 'OK'
168174
169175
170176 def __find_primary_ecu (self , messages ):
@@ -296,7 +302,7 @@ def __write(self, cmd):
296302 cmd += "\r \n " # terminate
297303 self .__port .flushOutput ()
298304 self .__port .flushInput ()
299- self .__port .write (cmd .encode ())
305+ self .__port .write (cmd .encode ()) # turn the string into bytes
300306 debug ("write: " + repr (cmd ))
301307 else :
302308 debug ("cannot perform __write() when unconnected" , True )
@@ -307,7 +313,7 @@ def __read(self):
307313 "low-level" read function
308314
309315 accumulates characters until the prompt character is seen
310- returns the raw string
316+ returns a list of [/r/n] delimited strings
311317 """
312318
313319 attempts = 2
@@ -328,11 +334,11 @@ def __read(self):
328334 continue
329335
330336 # end on chevron (ELM prompt character)
331- if c == ">" :
337+ if c == b'>' :
332338 break
333339
334340 # skip null characters (ELM spec page 9)
335- if c == '\x00 ' :
341+ if c == b '\x00 ' :
336342 continue
337343
338344 buffer += c # whatever is left must be part of the response
@@ -341,4 +347,13 @@ def __read(self):
341347 return ""
342348
343349 debug ("read: " + repr (buffer ))
344- return buffer .decode ()
350+
351+ # convert bytes into a standard string
352+ raw = buffer .decode ()
353+
354+ # splits into lines
355+ # removes empty lines
356+ # removes trailing spaces
357+ lines = [ s .strip () for s in re .split ("[\r \n ]" , raw ) if bool (s ) ]
358+
359+ return lines
0 commit comments