def read_until_string(self, str): """Pretend to read from the port until the given string is detected or the read times out. Return the previously recorded result. """ timestamp, parameters = self.next_log("read-until") # extract the argument, result, and status status = None if parameters.endswith("]"): pos = parameters.rindex(" [") status = parameters[pos + 2:-1] parameters = parameters[:pos] log_str, log_result = [eval(p) for p in parameters.split(" = ", 1)] if log_str != str: warn("%d: read-until(%r) != log(%r)" % (self.line_number, str, log_str)) if self.mimic_timing: time.sleep(timestamp - self.timestamp) self.timestamp = timestamp if status == "interval-expired": raise exception.IntervalTimeout(response=log_result) if status == "timeout-expired": raise exception.ReadTimeout(response=log_result) return log_result
def read_until_string(self, str): """Read from the port until the given string is detected or the read times out, whichever comes first. str -- the string to await Raises an IntervalTimeout exception if the polling interval expires without receiving any data. Raises a ReadTimeout exception if the read timout expires before the given string is encountered. See set_timeout for more details. """ buffer = "" interval = self.interval try: while True: remaining = self.timeout - time.time() if (remaining <= 0): raise exception.ReadTimeout(response=buffer) # make sure the read() doesn't go beyond the timeout if remaining < interval and interval >= self.MAX_READ_OVERRUN: interval = remaining / 2.0 self.port.setTimeout(interval) # read() times out after the polling interval set by set_timeout() c = self.port.read(1) if len(c) == 0 and interval == self.interval: # stop if the read timed out without data raise exception.IntervalTimeout(response=buffer) # FIXME: move 0x00 test to ELM327 if c == '\x00': continue # per note on p.6 of ELM327 data sheet buffer += c if (buffer.endswith(str)): break finally: # if we temporarily dialed down the port's timeout to avoid # galloping past the timeout, restore it to its previous value if interval != self.interval: self.port.setTimeout(self.interval) return buffer