Exemplo n.º 1
0
 def _convert_value(self, raw_value):
     try:
         value = self._values[raw_value]
     except KeyError:
         untested()
         value = raw_value
     return value
Exemplo n.º 2
0
 def _convert_value(self, raw_value):
     try:
         value = self._values[raw_value]
     except KeyError:
         untested()
         value = raw_value
     return value
Exemplo n.º 3
0
def query_vehicle(interface):
    interface.open()
    interface.set_protocol(None)
    interface.connect_to_vehicle()

    responses = interface.send_request(OBDRequest(sid=0x01, pid=0x01))

    # Find the response(s) for ECUs that support emissions monitors
    ecus = []
    for r in responses:
        supported = [
            m for m in r.non_continuous_monitors
            if m in r.supported_monitors()
        ]
        if len(supported) > 0:
            ecus.append(r)

    # If the engine's off (none support monitors), just pick the first
    if len(ecus) == 0:
        ecus.append(responses[0])

    # Print the readiness status
    for ecu in ecus:
        if len(ecus) > 1:
            untested("multiple ECUs with supported monitors")
            print "ECU 0x%02X:" % response.header.tx_id
        check_readiness(ecu)

    interface.disconnect_from_vehicle()
    interface.close()
    return
Exemplo n.º 4
0
 def __init__(self, port, name=None, callback=None):
     """
     port -- a SerialPort instance corresponding to the port to which
         the ELM device is attached
     name -- the descriptive name of the interface
     callback -- a function to be called with status updates during
         long operations (such as connecting to a vehicle); the one
         argument sent to the callback is a string containing a status
         message
     
     The callback may also be set (or changed) later, via
     set_status_callback().
     """
     assert type(
         self
     ) != ELM32X, "ELM32X should only be instantiated via obd.interface.elm.create()"
     assert isinstance(port, obd.serialport.SerialPort)
     if name is None:
         untested()
         name = "%s compatible" % self.__class__.__name__
     Interface.__init__(self, port.name, name, callback)
     self.port = port
     self.interface_configured = False
     self.connected_to_vehicle = False
     return
Exemplo n.º 5
0
    def assemble_message(self, frames):
        """Return the reassembled bytes given the full set of received
        frames.

        Reassemble the data contained in the individual frames into
        the list of bytes comprising the complete message, excluding
        any frame headers or footers.
        
        frames -- the list of frames in the sequence
        """
        if self.pid() in self._sequence_lengths:
            # include the SID and PID only once, at the beginning of the
            # reassembled message
            result = self.data_bytes[self.SID:self.PID+1]  # SID+PID
            for frame in frames:
                if frame == None:
                    untested("missing frames in non-CAN SID 09 message")
                    # insert None for each missing byte in a missing frame
                    result += [None] * (len(self.data_bytes) - (self.MC+1))
                else:
                    result += frame.data_bytes[self.MC+1:]  # skip SID/PID/MessageCount
        else:
            assert len(frames) == 1
            assert self.pid() in [MC_VIN, MC_CALID, MC_CVN, MC_IPT, MC_ECUNAME]
            # MessageCount requests are single-frame messages and don't have
            # any sequence number to skip
            result = self.data_bytes[:]
        return result
Exemplo n.º 6
0
    def assemble_message(self, frames):
        """Return the reassembled bytes given the full set of received
        frames.

        Reassemble the data contained in the individual frames into
        the list of bytes comprising the complete message, excluding
        any frame headers or footers.
        
        frames -- the list of frames in the sequence
        """
        if self.pid() in self._sequence_lengths:
            # include the SID and PID only once, at the beginning of the
            # reassembled message
            result = self.data_bytes[self.SID:self.PID + 1]  # SID+PID
            for frame in frames:
                if frame == None:
                    untested("missing frames in non-CAN SID 09 message")
                    # insert None for each missing byte in a missing frame
                    result += [None] * (len(self.data_bytes) - (self.MC + 1))
                else:
                    result += frame.data_bytes[self.MC +
                                               1:]  # skip SID/PID/MessageCount
        else:
            assert len(frames) == 1
            assert self.pid() in [MC_VIN, MC_CALID, MC_CVN, MC_IPT, MC_ECUNAME]
            # MessageCount requests are single-frame messages and don't have
            # any sequence number to skip
            result = self.data_bytes[:]
        return result
Exemplo n.º 7
0
 def __init__(self,
              message="Interface was processing previous command",
              response=None):
     untested("interface busy exception")
     OBDException.__init__(self, message)
     self.response = response
     return
Exemplo n.º 8
0
def query_vehicle(interface):
    interface.open()
    interface.set_protocol(None)
    interface.connect_to_vehicle()

    responses = interface.send_request(OBDRequest(sid=0x01, pid=0x01))

    # Find the response(s) for ECUs that support emissions monitors
    ecus = []
    for r in responses:
        supported = [m for m in r.non_continuous_monitors
                     if m in r.supported_monitors()]
        if len(supported) > 0:
            ecus.append(r)

    # If the engine's off (none support monitors), just pick the first
    if len(ecus) == 0:
        ecus.append(responses[0])

    # Print the readiness status
    for ecu in ecus:
        if len(ecus) > 1:
            untested("multiple ECUs with supported monitors")
            print "ECU 0x%02X:" % response.header.tx_id
        check_readiness(ecu)

    interface.disconnect_from_vehicle()
    interface.close()
    return
Exemplo n.º 9
0
    def get_protocol(self):
        """Return the current protocol being used in communication with the
        vehicle.

        Raises an exception if not connected with a vehicle.
        """
        if not self.connected_to_vehicle:
            raise CommandNotSupported("Not connected to vehicle")
        response = self.at_cmd("ATDPN")
        # suppress any "automatic" prefix
        if len(response) > 1 and response.startswith("A"):
            response = response[1:]
        # get the protocol object identified by the response
        try:
            protocol = self._supported_protocols[response]
        except KeyError as e:
            untested("unknown protocol returned by ELM")
            raise InterfaceError("Unknown protocol %r" % response)
        # bark if the protocol changed out from under us
        if self._protocol_response is None:
            self._protocol_response = response
        else:
            if response != self._protocol_response:
                untested("unexpected change in protocol")
                raise InterfaceError("Protocol changed unexpectedly")
        # return a copy to prevent muddling the internal list
        return copy.copy(protocol)
Exemplo n.º 10
0
    def get_protocol(self):
        """Return the current protocol being used in communication with the
        vehicle.

        Raises an exception if not connected with a vehicle.
        """
        if not self.connected_to_vehicle:
            raise CommandNotSupported("Not connected to vehicle")
        response = self.at_cmd("ATDPN")
        # suppress any "automatic" prefix
        if len(response) > 1 and response.startswith("A"):
            response = response[1:]
        # get the protocol object identified by the response
        try:
            protocol = self._supported_protocols[response]
        except KeyError as e:
            untested("unknown protocol returned by ELM")
            raise InterfaceError("Unknown protocol %r" % response)
        # bark if the protocol changed out from under us
        if self._protocol_response is None:
            self._protocol_response = response
        else:
            if response != self._protocol_response:
                untested("unexpected change in protocol")
                raise InterfaceError("Protocol changed unexpectedly")
        # return a copy to prevent muddling the internal list
        return copy.copy(protocol)
Exemplo n.º 11
0
 def __init__(self, id):
     untested("ELM-specific exception")
     InterfaceError.__init__(
         self,
         message="Internal ELM error; contact interface vendor",
         raw=id)
     return
Exemplo n.º 12
0
 def __str__(self):
     if not self.value:
         untested("null DTC")
         return "None"
     numeric = (self.value & 0x3FFF)
     alpha = (self.value >> 14) & 3
     alpha = "PCBU"[alpha]
     return "%s%04X" % (alpha, numeric)
Exemplo n.º 13
0
 def __str__(self):
     if not self.value:
         untested("null DTC")
         return "None"
     numeric = (self.value & 0x3FFF)
     alpha = (self.value >> 14) & 3
     alpha = "PCBU"[alpha]
     return "%s%04X" % (alpha, numeric)
Exemplo n.º 14
0
 def sequence_length(self):
     """Return the number of frames in the sequence:  None
     since the length is not known.
     
     The length is not specified in any legacy SID $03 frame.
     """
     untested("non-CAN SID 03 sequence length")
     return None  # variable number of messages (frames) in a response
Exemplo n.º 15
0
 def sequence_length(self):
     """Return the number of frames in the sequence:  None
     since the length is not known.
     
     The length is not specified in any legacy SID $03 frame.
     """
     untested("non-CAN SID 03 sequence length")
     return None  # variable number of messages (frames) in a response
Exemplo n.º 16
0
 def _return_raw_frames(self, raw_frames):
     """Return the list of raw frames untouched, but raise an
     exception if there were any data errors.
     """
     for f in raw_frames:
         if None in f:
             untested("frames with data errors")
             raise DataError(raw=raw_frame)
     return raw_frames
Exemplo n.º 17
0
 def _return_raw_frames(self, raw_frames):
     """Return the list of raw frames untouched, but raise an
     exception if there were any data errors.
     """
     for f in raw_frames:
         if None in f:
             untested("frames with data errors")
             raise DataError(raw=raw_frame)
     return raw_frames
Exemplo n.º 18
0
 def _return_bus_messages(self, raw_frames):
     """Reassemble a list of raw frames into complete BusMessages and
     raise an exception if there were any data errors; otherwise
     return the list of bus messages.
     """
     bus_messages = self._process_obd_response(raw_frames)
     for r in bus_messages:
         if r.incomplete:
             untested("messages with bad frames")
             raise DataError(raw=bus_messages)
     return bus_messages
Exemplo n.º 19
0
 def _return_bus_messages(self, raw_frames):
     """Reassemble a list of raw frames into complete BusMessages and
     raise an exception if there were any data errors; otherwise
     return the list of bus messages.
     """
     bus_messages = self._process_obd_response(raw_frames)
     for r in bus_messages:
         if r.incomplete:
             untested("messages with bad frames")
             raise DataError(raw=bus_messages)
     return bus_messages
Exemplo n.º 20
0
 def _return_obd_responses(self, raw_frames):
     """Reassemble a list of raw frames into complete OBD responses,
     each represented as the appropriate Response subclass, and
     raise an exception if there were any data errors.  Otherwise
     return the list of OBD responses.
     """
     bus_messages = self._process_obd_response(raw_frames)
     obd_messages = [obd.message.create(m) for m in bus_messages]
     for r in obd_messages:
         if r.incomplete:
             untested("messages with bad frames")
             raise DataError(raw=obd_messages)
     return obd_messages
Exemplo n.º 21
0
 def _return_obd_responses(self, raw_frames):
     """Reassemble a list of raw frames into complete OBD responses,
     each represented as the appropriate Response subclass, and
     raise an exception if there were any data errors.  Otherwise
     return the list of OBD responses.
     """
     bus_messages = self._process_obd_response(raw_frames)
     obd_messages = [obd.message.create(m) for m in bus_messages]
     for r in obd_messages:
         if r.incomplete:
             untested("messages with bad frames")
             raise DataError(raw=obd_messages)
     return obd_messages
Exemplo n.º 22
0
 def set_protocol(self, protocol):
     """Select the protocol to use for communicating with the vehicle.
     This will disconnect any communication session with the vehicle
     already in progress.
     
     protocol -- the protocol to use, or None for automatic selection
         by the interface
     """
     if self.connected_to_vehicle: self.disconnect_from_vehicle()
     for key, value in self._supported_protocols.items():
         if value == protocol:
             self.at_cmd("ATTP %s" % key)
             break
     else:
         untested("unsupported protocol requested of ELM")
         raise ValueError("Unsupported protocol: %s" % str(protocol))
     return
Exemplo n.º 23
0
 def set_protocol(self, protocol):
     """Select the protocol to use for communicating with the vehicle.
     This will disconnect any communication session with the vehicle
     already in progress.
     
     protocol -- the protocol to use, or None for automatic selection
         by the interface
     """
     if self.connected_to_vehicle: self.disconnect_from_vehicle()
     for key, value in self._supported_protocols.items():
         if value == protocol:
             self.at_cmd("ATTP %s" % key)
             break
     else:
         untested("unsupported protocol requested of ELM")
         raise ValueError("Unsupported protocol: %s" % str(protocol))
     return
Exemplo n.º 24
0
 def _flush_frames(self):
     """Flush any pending messages and post them to the
     _complete_messages Queue.
     
     Messages may be pending because they are incomplete
     (e.g. a frame is missing) or because _received_obd_frame()
     was unable to determine that they were complete.
     
     This function should be called when it is determined
     that a response is complete.  In the case of discrete
     request/response transactions, this is often trivial.
     In the case of bus monitoring, more complex logic
     must be employed to determine when frames should be
     flushed.
     """
     try:
         # Iterate over all pending messages
         for frames, sequence_number, sequence_length in self._frames_received.values(
         ):
             # If the message is pending because it is incomplete
             if None in frames:
                 untested("flushing incomplete messages")
                 # Find the first received (non-None) frame, in case we missed the
                 # first frame(s).  The assertions check for bugs in received_frame().
                 for first_received in frames:
                     if first_received != None: break
                 else:
                     assert False, "message with no frames received"
             else:
                 # If the sequence length was known, the message should have been
                 # flushed as soon as it was complete.
                 sequence_length_known = (sequence_length is not None)
                 assert not sequence_length_known, "message not flushed upon completion"
                 first_received = frames[0]
             # Post the pending message
             header = first_received.header
             data = first_received.assemble_message(frames)
             bus_message = obd.message.BusMessage(header, data, frames)
             self._complete_messages.put(bus_message, False)
     finally:
         # Clear the pending messages
         self._frames_received = {}
     return
Exemplo n.º 25
0
 def _flush_frames(self):
     """Flush any pending messages and post them to the
     _complete_messages Queue.
     
     Messages may be pending because they are incomplete
     (e.g. a frame is missing) or because _received_obd_frame()
     was unable to determine that they were complete.
     
     This function should be called when it is determined
     that a response is complete.  In the case of discrete
     request/response transactions, this is often trivial.
     In the case of bus monitoring, more complex logic
     must be employed to determine when frames should be
     flushed.
     """
     try:
         # Iterate over all pending messages
         for frames, sequence_number, sequence_length in self._frames_received.values():
             # If the message is pending because it is incomplete
             if None in frames:
                 untested("flushing incomplete messages")
                 # Find the first received (non-None) frame, in case we missed the
                 # first frame(s).  The assertions check for bugs in received_frame().
                 for first_received in frames:
                     if first_received != None: break
                 else:
                     assert False, "message with no frames received"
             else:
                 # If the sequence length was known, the message should have been
                 # flushed as soon as it was complete.
                 sequence_length_known = (sequence_length is not None)
                 assert not sequence_length_known, "message not flushed upon completion"
                 first_received = frames[0]
             # Post the pending message
             header = first_received.header
             data = first_received.assemble_message(frames)
             bus_message = obd.message.BusMessage(header, data, frames)
             self._complete_messages.put(bus_message, False)
     finally:
         # Clear the pending messages
         self._frames_received = {}
     return
Exemplo n.º 26
0
 def __init__(self, port, name=None, callback=None):
     """
     port -- a SerialPort instance corresponding to the port to which
         the ELM device is attached
     name -- the descriptive name of the interface
     callback -- a function to be called with status updates during
         long operations (such as connecting to a vehicle); the one
         argument sent to the callback is a string containing a status
         message
     
     The callback may also be set (or changed) later, via
     set_status_callback().
     """
     assert type(self) != ELM32X, "ELM32X should only be instantiated via obd.interface.elm.create()"
     assert isinstance(port, obd.serialport.SerialPort)
     if name is None:
         untested()
         name = "%s compatible" % self.__class__.__name__
     Interface.__init__(self, port.name, name, callback)
     self.port = port
     self.interface_configured = False
     self.connected_to_vehicle = False
     return
Exemplo n.º 27
0
def create(identifier, argument_name=""):
    """Return the interface specified by the given identifier,
    raising an exception if the interface cannot be created.

    identifier -- the identifier specifying the desired interface;
        this might be the serial port to which the interface is
        attached, or some other identifier (such as a USB serial
        number) used to specify the desired interface.
    argument_name -- text returned in exception messages
        explaining how to specify the identifier, e.g. via
        a "--port" command-line option
        
    If identifier is None, try to detect the interface automatically.
    a) If enumeration is not supported, this will raise an OBDException.
    b) If more than one interface is detected, this will raise
        a ValueError exception listing the detected interfaces
    c) If no interfaces are detected, this will raise an
        InterfaceNotFound exception.
    """
    if identifier is not None:
        for class_ in _interface_classes:
            try:
                interface = class_.create(identifier)
                break
            except:
                pass
        else:
            message = "Unable to connect to scanner at %s; " % identifier
            message += "is it connected and powered?\n"
            raise InterfaceNotFound(message)
    else:
        if argument_name:
            select = " via %s" % argument_name
        else:
            untested("no argument name")
            select = ""
        select = "Please select an interface to use" + select
        try:
            interfaces = obd.interface.enumerate()
        except OBDException as e:
            untested("enumeration not supported")
            message = "%s.\n%s.\n" % (str(e), select)
            raise OBDException(message)
        if len(interfaces) < 1:
            message = "No scanners found; is one connected and powered?\n"
            raise InterfaceNotFound(message)
        if len(interfaces) > 1:
            untested("multiple interfaces")
            message = "%s:\n" % select
            for interface in interfaces:
                message += "  %s\n" % str(interface)
            raise ValueError(message)
        interface = interfaces[0]

    return interface
Exemplo n.º 28
0
def create(identifier, argument_name=""):
    """Return the interface specified by the given identifier,
    raising an exception if the interface cannot be created.

    identifier -- the identifier specifying the desired interface;
        this might be the serial port to which the interface is
        attached, or some other identifier (such as a USB serial
        number) used to specify the desired interface.
    argument_name -- text returned in exception messages
        explaining how to specify the identifier, e.g. via
        a "--port" command-line option
        
    If identifier is None, try to detect the interface automatically.
    a) If enumeration is not supported, this will raise an OBDException.
    b) If more than one interface is detected, this will raise
        a ValueError exception listing the detected interfaces
    c) If no interfaces are detected, this will raise an
        InterfaceNotFound exception.
    """
    if identifier is not None:
        for class_ in _interface_classes:
            try:
                interface = class_.create(identifier)
                break
            except:
                pass
        else:
            message = "Unable to connect to scanner at %s; " % identifier
            message += "is it connected and powered?\n"
            raise InterfaceNotFound(message)
    else:
        if argument_name:
            select = " via %s" % argument_name
        else:
            untested("no argument name")
            select = ""
        select = "Please select an interface to use" + select
        try:
            interfaces = obd.interface.enumerate()
        except OBDException as e:
            untested("enumeration not supported")
            message = "%s.\n%s.\n" % (str(e), select)
            raise OBDException(message)
        if len(interfaces) < 1:
            message = "No scanners found; is one connected and powered?\n"
            raise InterfaceNotFound(message)
        if len(interfaces) > 1:
            untested("multiple interfaces")
            message = "%s:\n" % select
            for interface in interfaces:
                message += "  %s\n" % str(interface)
            raise ValueError(message)
        interface = interfaces[0]

    return interface
Exemplo n.º 29
0
    def data_length(self):
        """Return the number of data bytes contained in the complete,
        reassembled sequence, or None if this frame has no such
        information.

        The length is only known for the SID $09 responses with a
        constant length assigned by specification.
        """
        untested("non-CAN SID 09 data length")
        try:
            frames = self._sequence_lengths[self.pid()]
            if frames:
                untested("known number of frames in non-CAN SID 09 message")
                length = frames * 4 + 2  # 4 data bytes per frame + SID/PID for message
            else:
                untested("variable number of frames in non-CAN SID 09 message")
                length = None  # variable number of bytes
        except KeyError:
            untested("non-CAN SID 09 MessageCount query")
            length = 3  # SID+PID + MessageCount byte for MessageCount requests
        return length
Exemplo n.º 30
0
    def data_length(self):
        """Return the number of data bytes contained in the complete,
        reassembled sequence, or None if this frame has no such
        information.

        The length is only known for the SID $09 responses with a
        constant length assigned by specification.
        """
        untested("non-CAN SID 09 data length")
        try:
            frames = self._sequence_lengths[self.pid()]
            if frames:
                untested("known number of frames in non-CAN SID 09 message")
                length = frames * 4 + 2  # 4 data bytes per frame + SID/PID for message
            else:
                untested("variable number of frames in non-CAN SID 09 message")
                length = None  # variable number of bytes
        except KeyError:
            untested("non-CAN SID 09 MessageCount query")
            length = 3  # SID+PID + MessageCount byte for MessageCount requests
        return length
Exemplo n.º 31
0
def create(port, callback=None, baud=None):
    """Create an instance of the appropriate ELM32X subclass at the
    given port
    
    port -- the SerialPort subclass to which the interface is attached
    callback -- the callback function used to provide status updates
        (default None)
    baud -- the baud rate to use, or None (default) to auto-detect
    """
    # Use the appropriate baud rate, auto-detecting if requested
    #print "Reached here"
    if baud:
        if port.get_baudrate() != baud:
            untested("specifying the baud rate for obd.interface.elm.create()")
            port.set_baudrate(baud)
    else:
        current_baud = ELM32X.detect_baudrate(port)
        if not current_baud:
            raise InterfaceError("Unable to connect to ELM; does it have power?")
    #print "Reached here"
    # Query the interface for its identity
    identifier = ELM32X._at_cmd(port, "ATI")
    if identifier.startswith("ATI\r"): identifier = identifier[4:]
    debug(identifier)
    chip_identifier, chip_version = identifier.split(" ")
    #print identifier
     
    # Check for extended command set
    extended = ELM32X._at_cmd(port, "STI")
    if extended.startswith("STI\r"): extended = extended[4:]
    if extended != "?":
        untested(extended)
        chip_identifier, chip_version = extended.rsplit(" ", 1)
    print extended
    # Create an instance of the appropriate ELM32X subclass
    try:
        elm_class = _classes[chip_identifier]
    except KeyError as e:
        untested("unknown ELM response to ATI")
        raise InterfaceError("Unknown response to ATI: %r" % identifier)
    interface = elm_class(port, chip_identifier, callback=callback)

    debug("%s detected on port %s at %d baud" %
          (chip_identifier, interface.port.name, interface.port.get_baudrate()))
    return interface
Exemplo n.º 32
0
def create(port, callback=None, baud=None):
    """Create an instance of the appropriate ELM32X subclass at the
    given port
    
    port -- the SerialPort subclass to which the interface is attached
    callback -- the callback function used to provide status updates
        (default None)
    baud -- the baud rate to use, or None (default) to auto-detect
    """
    # Use the appropriate baud rate, auto-detecting if requested
    if baud:
        if port.get_baudrate() != baud:
            untested("specifying the baud rate for obd.interface.elm.create()")
            port.set_baudrate(baud)
    else:
        current_baud = ELM32X.detect_baudrate(port)
        if not current_baud:
            raise InterfaceError(
                "Unable to connect to ELM; does it have power?")
    # Query the interface for its identity
    identifier = ELM32X._at_cmd(port, "ATI")
    if identifier.startswith("ATI\r"): identifier = identifier[4:]
    debug(identifier)
    chip_identifier, chip_version = identifier.split(" ")

    # Check for extended command set
    extended = ELM32X._at_cmd(port, "STI")
    if extended.startswith("STI\r"): extended = extended[4:]
    if extended != "?":
        untested(extended)
        chip_identifier, chip_version = extended.rsplit(" ", 1)

    # Create an instance of the appropriate ELM32X subclass
    try:
        elm_class = _classes[chip_identifier]
    except KeyError as e:
        untested("unknown ELM response to ATI")
        raise InterfaceError("Unknown response to ATI: %r" % identifier)
    interface = elm_class(port, chip_identifier, callback=callback)

    debug(
        "%s detected on port %s at %d baud" %
        (chip_identifier, interface.port.name, interface.port.get_baudrate()))
    return interface
Exemplo n.º 33
0
    def assemble_message(self, frames):
        """Return the reassembled bytes given the full set of received
        frames.

        Reassemble the data contained in the individual frames into
        the list of bytes comprising the complete message, excluding
        any frame headers or footers.
        
        frames -- the list of frames in the sequence
        """
        untested("non-CAN SID 03 reassembly")
        # include the SID only once, at the beginning of the reassembled message
        result = [self.data_bytes[self.SID]]  # SID
        for frame in frames:
            if frame == None:
                untested("handling missing frame")
                # insert None for each missing byte in a missing frame
                result += [None] * (len(self.data_bytes) - (self.SID+1))
            else:
                untested("assembling non-CAN frame")
                result += frame.data_bytes[self.SID+1:]  # DTCs in each message
        return result
Exemplo n.º 34
0
    def assemble_message(self, frames):
        """Return the reassembled bytes given the full set of received
        frames.

        Reassemble the data contained in the individual frames into
        the list of bytes comprising the complete message, excluding
        any frame headers or footers.
        
        frames -- the list of frames in the sequence
        """
        untested("non-CAN SID 03 reassembly")
        # include the SID only once, at the beginning of the reassembled message
        result = [self.data_bytes[self.SID]]  # SID
        for frame in frames:
            if frame == None:
                untested("handling missing frame")
                # insert None for each missing byte in a missing frame
                result += [None] * (len(self.data_bytes) - (self.SID + 1))
            else:
                untested("assembling non-CAN frame")
                result += frame.data_bytes[self.SID +
                                           1:]  # DTCs in each message
        return result
Exemplo n.º 35
0
 def __init__(self, message_data, offset, pid):
     untested("Diesel IPT response")
     Service09Response.__init__(self, message_data, offset, pid)
     if len(self.items) != 16:
         raise J1699Failure("IPT NODI != 16", raw=self)
     return
Exemplo n.º 36
0
 def __init__(self, message="Interface was processing previous command", response=None):
     untested("interface busy exception")
     OBDException.__init__(self, message)
     self.response = response
     return
Exemplo n.º 37
0
 def __init__(self, value):
     self.value = value
     if not self.value:
         untested("null DTC")
     return
Exemplo n.º 38
0
 def __init__(self, message_data, offset, pid):
     untested("Diesel IPT response")
     Service09Response.__init__(self, message_data, offset, pid)
     if len(self.items) != 16:
         raise J1699Failure("IPT NODI != 16", raw=self)
     return
Exemplo n.º 39
0
    def _read_response(self, previous_data=""):
        """Read ASCII OBD frames from the interface until the
        prompt is received, and return the list of frames.
        
        Raises an exception on any error (such as no data,
        buffer overflow, etc.)
        
        previous_data -- data previously read from the interface
            which should be considered part of the response
        """
        response = previous_data + self._read_until_prompt()
        response = response.strip("\r")
        lines = response.split("\r")
        for line in lines:
            # Raise exceptions for any errors
            if line == "?":
                raise CommandNotSupported()

            if line == "NO DATA":
                raise obd.exception.DataError(raw=line)
            if line.endswith("BUS BUSY") or line.endswith("DATA ERROR"):
                untested("data error")
                raise obd.exception.DataError(raw=line)
            if line.endswith("BUS ERROR") or line.endswith(
                    "FB ERROR") or line.endswith("LV RESET"):
                untested("bus error")
                raise obd.exception.BusError(raw=line)
            if line.endswith("CAN ERROR") or line.endswith("RX ERROR"):
                untested("protocol error")
                raise obd.exception.ProtocolError(raw=line)
            if line.endswith("BUFFER FULL"):
                untested("buffer overflow")
                raise obd.exception.BufferOverflowError()

            if line.find("<DATA ERROR") != -1:
                untested("frame data error")
                # Once we have a test case, we should probably simply replace
                # lines with bad bytes with "None" for each byte; then
                # process_obd_response or send_request will raise the error.
                raise obd.exception.DataError(raw=line)

            matched = re.search(r"ERR\d\d", line)
            if (matched):
                untested("internal ELM error"
                         )  # or does this only occur on connection?
                error = matched.group(0)
                if error == "ERR94":
                    # ERR94 is a fatal CAN error according to p.52-53 of the ELM327 datasheet
                    raise obd.exception.BusError(raw=line)
                raise ELM32XError(error)

        return lines
Exemplo n.º 40
0
 def __init__(self, message_data, offset, pid):
     untested()
     ValueResponse.__init__(self, message_data, offset, pid)
     return
Exemplo n.º 41
0
    def _read_response(self, previous_data=""):
        """Read ASCII OBD frames from the interface until the
        prompt is received, and return the list of frames.
        
        Raises an exception on any error (such as no data,
        buffer overflow, etc.)
        
        previous_data -- data previously read from the interface
            which should be considered part of the response
        """
        response = previous_data + self._read_until_prompt()
        response = response.strip("\r")
        lines = response.split("\r")
        for line in lines:
            # Raise exceptions for any errors
            if line == "?":
                raise CommandNotSupported()

            if line == "NO DATA":
                raise obd.exception.DataError(raw=line)            
            if line.endswith("BUS BUSY") or line.endswith("DATA ERROR"):
                untested("data error")
                raise obd.exception.DataError(raw=line)
            if line.endswith("BUS ERROR") or line.endswith("FB ERROR") or line.endswith("LV RESET"):
                untested("bus error")
                raise obd.exception.BusError(raw=line)
            if line.endswith("CAN ERROR") or line.endswith("RX ERROR"):
                untested("protocol error")
                raise obd.exception.ProtocolError(raw=line)
            if line.endswith("BUFFER FULL"):
                untested("buffer overflow")
                raise BufferOverflowError()

            if line.find("<DATA ERROR") != -1:
                untested("frame data error")
                # Once we have a test case, we should probably simply replace
                # lines with bad bytes with "None" for each byte; then
                # process_obd_response or send_request will raise the error.
                raise obd.exception.DataError(raw=line)

            matched = re.search(r"ERR\d\d", line)
            if (matched):
                untested("internal ELM error")  # or does this only occur on connection?
                error = matched.group(0)
                if error == "ERR94":
                    # ERR94 is a fatal CAN error according to p.52-53 of the ELM327 datasheet
                    raise obd.exception.BusError(raw=line)
                raise ELM32XError(error)

        return lines
Exemplo n.º 42
0
 def __init__(self, value):
     self.value = value
     if not self.value:
         untested("null DTC")
     return
Exemplo n.º 43
0
 def __init__(self, message):
     untested("bus error exception")
     VehicleException.__init__(self, "Probable wiring error: %s" % message)
     return
Exemplo n.º 44
0
 def __init__(self, id):
     untested("ELM-specific exception")
     InterfaceError.__init__(self, message="Internal ELM error; contact interface vendor", raw=id)
     return
Exemplo n.º 45
0
 def __init__(self, message_data, offset, pid):
     untested()
     ValueResponse.__init__(self, message_data, offset, pid)
     return