示例#1
0
文件: obd_io.py 项目: alxnik/pyobd
def decrypt_dtc_code(code):
    """Returns the 5-digit DTC code from hex encoding"""
    dtc = []
    current = code
    for i in range(0,3):
        if len(current)<4:
            raise "Tried to decode bad DTC: %s" % code

        tc = obd_sensors.hex_to_int(current[0]) #typecode
        tc = tc >> 2
        if   tc == 0:
            type = "P"
        elif tc == 1:
            type = "C"
        elif tc == 2:
            type = "B"
        elif tc == 3:
            type = "U"
        else:
            raise tc

        dig1 = str(obd_sensors.hex_to_int(current[0]) & 3)
        dig2 = str(obd_sensors.hex_to_int(current[1]))
        dig3 = str(obd_sensors.hex_to_int(current[2]))
        dig4 = str(obd_sensors.hex_to_int(current[3]))
        dtc.append(type+dig1+dig2+dig3+dig4)
        current = current[4:]
    return dtc
示例#2
0
def decrypt_dtc_code(code):
    """Returns the 5-digit DTC code from hex encoding"""
    dtc = []
    current = code
    # for i in range(0,3):
    if len(current) < 4:
        return "NODATA"
        # raise Exception("Tried to decode bad DTC: %s" % code)

    # typecode is first half of first word of first byte - so need to bit shift to right by 2
    tc = obd_sensors.hex_to_int(current[0])  #typecode
    tc = tc >> 2
    if tc == 0:
        type = "P"
    elif tc == 1:
        type = "C"
    elif tc == 2:
        type = "B"
    elif tc == 3:
        type = "U"
    else:
        raise tc

    # digit 1 is the 2nd half of first word of first byte - grab only the last 2 bits by doing "& 0011"
    dig1 = str(obd_sensors.hex_to_int(current[0]) & 3)
    dig2 = str(obd_sensors.hex_to_int(current[1]))
    dig3 = str(obd_sensors.hex_to_int(current[2]))
    dig4 = str(obd_sensors.hex_to_int(current[3]))
    dtc.append(type + dig1 + dig2 + dig3 + dig4)
    dtc = ','.join(dtc)
    print "DTC from get_dtc(): " + dtc
    current = current[4:]
    return dtc
示例#3
0
文件: obd_io.py 项目: nesl/netcar
def decrypt_dtc_code(code):
    """Returns the 5-digit DTC code from hex encoding"""
    dtc = []
    current = code
    for i in range(0,3):
        if len(current)<4:
            raise "Tried to decode bad DTC: %s" % code

        tc = obd_sensors.hex_to_int(current[0]) #typecode
        tc = tc >> 2
        if   tc == 0:
            type = "P"
        elif tc == 1:
            type = "C"
        elif tc == 2:
            type = "B"
        elif tc == 3:
            type = "U"
        else:
            raise tc

        dig1 = str(obd_sensors.hex_to_int(current[0]) & 3)
        dig2 = str(obd_sensors.hex_to_int(current[1]))
        dig3 = str(obd_sensors.hex_to_int(current[2]))
        dig4 = str(obd_sensors.hex_to_int(current[3]))
        dtc.append(type+dig1+dig2+dig3+dig4)
        current = current[4:]
    return dtc
示例#4
0
    def get_dtc_f(self):
        """Returns a list of all pending DTC codes. Each element consists of
          a 2-tuple: (DTC code (string), Code description (string) )"""
        dtcLetters = ["P", "C", "B", "U"]
        r = self.sensor(1)[1]  #data
        dtcNumber = r[0]
        mil = r[1]
        DTCCodes = []

        #read mode 7
        self.send_command(GET_FREEZE_DTC_COMMAND)
        res = self.get_result()

        if res[:7] == "NODATA":  #no freeze frame
            return DTCCodes

        print "DTC freeze result:" + res
        for i in range(0, 3):
            val1 = hex_to_int(res[3 + i * 6:5 + i * 6])
            val2 = hex_to_int(
                res[6 + i * 6:8 +
                    i * 6])  #get DTC codes from response (3 DTC each 2 bytes)
            val = (val1 << 8) + val2  #DTC val as int

            if val == 0:  #skip fill of last packet
                break

            DTCStr = dtcLetters[(val & 0xC000) > 14] + str(
                (val & 0x3000) >> 12) + str((val & 0x0f00) >> 8) + str(
                    (val & 0x00f0) >> 4) + str(val & 0x000f)
            DTCCodes.append(["Passive", DTCStr])

        return DTCCodes
示例#5
0
    def get_dtc(self):
        """Returns a list of all pending DTC codes. Each element consists of
          a 2-tuple: (DTC code (string), Code description (string) )"""
        dtcLetters = ["P", "C", "B", "U"]
        r = self.sensor(1)[1]  #data
        dtcNumber = r[0]
        mil = r[1]
        DTCCodes = []

        print "Number of stored DTC:" + str(dtcNumber) + " MIL: " + str(mil)
        # get all DTC, 3 per mesg response
        for i in range(0, ((dtcNumber + 2) / 3)):
            self.send_command(GET_DTC_COMMAND)
            res = self.get_result()
            print "DTC result:" + res
            for i in range(0, 3):
                val1 = hex_to_int(res[3 + i * 6:5 + i * 6])
                val2 = hex_to_int(
                    res[6 + i * 6:8 + i *
                        6])  #get DTC codes from response (3 DTC each 2 bytes)
                val = (val1 << 8) + val2  #DTC val as int

                if val == 0:  #skip fill of last packet
                    break

                DTCStr = dtcLetters[(val & 0xC000) > 14] + str(
                    (val & 0x3000) >> 12) + str((val & 0x0f00) >> 8) + str(
                        (val & 0x00f0) >> 4) + str(val & 0x000f)

                DTCCodes.append(["Active", DTCStr])
        return DTCCodes
示例#6
0
def decrypt_dtc_code(code):
    """Returns the 5-digit DTC code from hex encoding"""
    dtc = ""
    print "decrypt_dtc_code_code " + code
    #if len(code)<4:
    #   os.popen('dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteInfoprint string:"ERROR: Tried to decode bad DTC"')
    #   raise "Tried to decode bad DTC: %s" % code

    tc = obd_sensors.hex_to_int(code[0]) #typecode
    tc = tc >> 2
    if   tc == 0:
        type = "P"
    elif tc == 1:
        type = "C"
    elif tc == 2:
        type = "B"
    elif tc == 3:
        type = "U"
    else:
        os.popen('dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteInfoprint string:"ERROR!"')
        raise tc

    dig1 = str(obd_sensors.hex_to_int(code[0]) & 3)
    dig2 = str(obd_sensors.hex_to_int(code[1]))
    dig3 = str(obd_sensors.hex_to_int(code[2]))
    dig4 = str(obd_sensors.hex_to_int(code[3]))

    dtc = type+dig1+dig2+dig3+dig4
    return dtc
示例#7
0
    def get_dtc(self):
        """Returns a list of all pending DTC codes. Each element consists of
          a 2-tuple: (DTC code (string), Code description (string) )"""
        dtcLetters = ["P", "C", "B", "U"]
        r = self.sensor(1)[1]  # data
        dtcNumber = r[0]
        mil = r[1]
        DTCCodes = []

        print "Number of stored DTC:" + str(dtcNumber) + " MIL: " + str(mil)
        # get all DTC, 3 per mesg response
        for i in range(0, ((dtcNumber + 2) / 3)):
            self.send_command(GET_DTC_COMMAND)
            res = self.get_result()
            print "DTC result:" + res
            for i in range(0, 3):
                val1 = hex_to_int(res[3 + i * 6 : 5 + i * 6])
                val2 = hex_to_int(res[6 + i * 6 : 8 + i * 6])  # get DTC codes from response (3 DTC each 2 bytes)
                val = (val1 << 8) + val2  # DTC val as int

                if val == 0:  # skip fill of last packet
                    break

                DTCStr = (
                    dtcLetters[(val & 0xC000) > 14]
                    + str((val & 0x3000) >> 12)
                    + str((val & 0x0F00) >> 8)
                    + str((val & 0x00F0) >> 4)
                    + str(val & 0x000F)
                )

                DTCCodes.append(["Active", DTCStr])

        # read mode 7
        self.send_command(GET_FREEZE_DTC_COMMAND)
        res = self.get_result()

        if res[:7] == "NO DATA":  # no freeze frame
            return DTCCodes

        print "DTC freeze result:" + res
        for i in range(0, 3):
            val1 = hex_to_int(res[3 + i * 6 : 5 + i * 6])
            val2 = hex_to_int(res[6 + i * 6 : 8 + i * 6])  # get DTC codes from response (3 DTC each 2 bytes)
            val = (val1 << 8) + val2  # DTC val as int

            if val == 0:  # skip fill of last packet
                break

            DTCStr = (
                dtcLetters[(val & 0xC000) > 14]
                + str((val & 0x3000) >> 12)
                + str((val & 0x0F00) >> 8)
                + str((val & 0x00F0) >> 4)
                + str(val & 0x000F)
            )
            DTCCodes.append(["Passive", DTCStr])

        return DTCCodes
示例#8
0
    def get_obd_data_bytes(self):
        """Internal use only: not a public interface"""
        retVal = {}
        byteCount = {}
        data = self.get_result()
        if data is None:
            return None

        for line in data:
            line = line.split(' ')  #Turn data into list of bytes
            if not self.prot_is_CAN:
                line = line[2:]
            ecu = line[0]
            if ecu not in retVal:
                retVal[ecu] = []
            if self.prot_is_CAN:
                if line[1][0] == '0':  #PCI Byte indicates single line response
                    byteCount[ecu] = int(
                        line[1][1])  #Second half of PCI byte is data length
                    line = line[2:]  #Remove ecu address and byte count
                    retVal[ecu] += line[0:byteCount[ecu]]  #Get the data

                if line[1][
                        0] == '1':  #PCI Byte indicates 1st frame of multiframe response
                    byteCount[ecu] = hex_to_int(line[1][1]) << 8 + hex_to_int(
                        line[2])  #PCI Byte extended 1 byte for byte count
                    retVal[ecu] += ['00'] * (byteCount[ecu] - len(retVal[ecu])
                                             )  #Fill out data with zeroes
                    retVal[ecu] = retVal[ecu][
                        0:byteCount[ecu]]  #Truncate list to byte count
                    line = line[3:]  #Remove ECU Address and Byte Count
                    i = 0
                    for data in line:
                        retVal[ecu][i] = data
                        i += 1
                if line[1][
                        0] == '2':  #PCI Byte indicates Next frame of multiframe response
                    i = hex_to_int(
                        line[1][1])  #Indicates frame # of multiframe response
                    i = i * 7 - 1
                    line = line[2:]
                    if ecu not in byteCount:
                        retVal[ecu] += ['00'] * (i + 7 - len(
                            retVal[ecu]))  #Next Frame came before 1st frame.
                        #Fill through this frame with zeroes.
                    for data in line:
                        if i < len(retVal[ecu]):
                            retVal[ecu][i] = data
                        else:
                            break
                        i += 1

            else:
                retVal[ecu] += line[1:]

        return retVal
示例#9
0
        def parse_get_dtc_data(res, DTCCodes, DTCType, dtcNumber=None):
            dtcLetters = ["P", "C", "B", "U"]
            for ecu in res:
                i = 0
                dataList = res[ecu]
                if ecu not in DTCCodes:
                    DTCCodes[ecu] = []

                while i < len(dataList):
                    #check Mode Response byte (Should be GET_DTC_RESPONSE(0x43))
                    if (self.prot_is_CAN and i == 0) or (not self.prot_is_CAN
                                                         and (i % 7) == 0):
                        if dataList[i] != GET_DTC_RESPONSE and dataList[
                                i] != GET_PENDING_DTC_RESPONSE:
                            self._notify_window.DebugEvent.emit(
                                1, 'Unexpected Response to GET_DTC (%s)' %
                                (dataList[i]))
                            break
                        i += 1

                    #For CAN, 1st byte is Number of DTCs
                    if self.prot_is_CAN and i == 1:
                        NumCodes = hex_to_int(dataList[i])
                        i += 1
                        if dtcNumber is not None and (NumCodes !=
                                                      dtcNumber[ecu]):
                            self._notify_window.DebugEvent.emit(
                                1,
                                'Expected Codes (%d) != Received Codes (%d)' %
                                (dtcNumber[ecu], NumCodes))

                    if i >= len(dataList):
                        break

                    val1 = hex_to_int(dataList[i])
                    val2 = hex_to_int(dataList[
                        i +
                        1])  #get DTC codes from response (3 DTC each 2 bytes)
                    val = (val1 << 8) + val2  #DTC val as int

                    i += 2

                    if val == 0:  #skip fill of last packet
                        continue

                    DTCStr = dtcLetters[(val & 0xC000) >> 14] + str(
                        (val & 0x3000) >> 12) + str(val & 0x0fff)
                    DTCCodes[ecu].append([DTCType, DTCStr])

            return DTCCodes
示例#10
0
def decrypt_dtc_code(code, nrOfDTC):
    """Returns the 5-digit DTC code from hex encoding"""
    dtc = []
    current = code
    type = ""
    newRow = 0
    if nrOfDTC != "NODATA":
        for i in range(0,nrOfDTC):
            if len(current)<4:
                print( "Tried to decode bad DTC: " + str(code))

            tc = obd_sensors.hex_to_int(current[0]) #typecode
            tc = tc >> 2
            if   tc == 0:
                type = "P"
            elif tc == 1:
                type = "C"
            elif tc == 2:
                type = "B"
            elif tc == 3:
                type = "U"
            else:
                print("raise tc")

            dig1 = str(obd_sensors.hex_to_int(current[0]) & 3)
            dig2 = str(obd_sensors.hex_to_int(current[1]))
            dig3 = str(obd_sensors.hex_to_int(current[2]))
            dig4 = str(obd_sensors.hex_to_int(current[3]))
            dtc.append(type+dig1+dig2+dig3+dig4)
            newRow+=1
            if newRow < 3:
                current = current[4:]
            else:
                current = current[6:]
                newRow=0
    return dtc
示例#11
0
     def get_dtc(self):
          print "get_dtc"
          """Returns a list of all pending DTC codes. Each element consists of
          a 2-tuple: (DTC code (string), Code description (string) )"""
          dtcLetters = ["P", "C", "B", "U"]
          r = self.sensor(1)[1] #data
          dtcNumber = r[0]
          mil = r[1]
          DTCCodes = []
          
          
          print "Number of stored DTC:" + str(dtcNumber) + " MIL: " + str(mil)
          # get all DTC, 3 per mesg response
          for i in range(0, ((dtcNumber+2)/3)):
            self.send_command(GET_DTC_COMMAND)
            res = self.get_result()
            print "DTC result:" + res
            for i in range(0, 3):
                DTC_raw = res[3+i*6:5+i*6] + res[6+i*6:8+i*6]
                if DTC_raw=="0000": #skip fill of last packet
                  break
                  
                DTCStr = decrypt_dtc_code(DTC_raw)
                DTCCodes.append(["Active",DTCStr])
          
          #read mode 7
          self.send_command(GET_FREEZE_DTC_COMMAND)
          res = self.get_result()
          
          if res[:7] == "NO DATA": #no freeze frame
            return DTCCodes
          
          print "DTC freeze result:" + res

          a=len(res)
          print "len(res): " + str(a)
          if a>9:

             for i in range(0, 3):
                 DTC_raw = res[3+i*6:5+i*6] + res[6+i*6:8+i*6]
                 if DTC_raw=="0000": #skip fill of last packet
                   break
                  
                 DTCStr = decrypt_dtc_code(DTC_raw)

                 #M se restituisce codici a 6 cifre invece che ha 5
                 if len(DTCStr)>5:
                    DTCStr = DTCStr[0]+DTCStr[2:]
                    print "DTCStr "+DTCStr

                 DTCCodes.append(["Passive",DTCStr])

          else:
              
             for i in range(0, 3):
                 val1 = hex_to_int(res[3+i*6:5+i*6])
                 val2 = hex_to_int(res[6+i*6:8+i*6]) #get DTC codes from response (3 DTC each 2 bytes)
                 val  = (val1<<8)+val2 #DTC val as int
                
                 if val==0: #skip fill of last packet
                   break
                   
                 DTCStr=dtcLetters[(val&0xC000)>14]+str((val&0x3000)>>12)+str(val&0x0fff)

                 #M se restituisce codici a 6 cifre invece che ha 5
                 if len(DTCStr)>5:
                    DTCStr = DTCStr[0]+DTCStr[2:]
                    print "DTCStr "+DTCStr

                 DTCCodes.append(["Passive",DTCStr])




          return DTCCodes
    def get_dtc(self):
        """Returns a list of all pending DTC codes. Each element consists of
          a 2-tuple: (DTC code (string), Code description (string) )"""
        outfile = open('captured.dtc.codes', 'a')
        outfile.write('--------------\n')
        dtcLetters = ["P", "C", "B", "U"]
        r = self.sensor(1)[1]  #data

        if r == "NODATA":
            outfile.close()
            return []

        print('r=' + str(r))
        outfile.write('Sensor: ' + str(r) + '\n')
        dtcNumber = r[0]
        mil = r[1]
        DTCCodes = []

        print("Number of stored DTC:" + str(dtcNumber) + " MIL: " + str(mil))
        outfile.write("Number of stored DTC:" + str(dtcNumber) + " MIL: " +
                      str(mil) + '\n')
        # get all DTC, 3 per mesg response
        for i in range(0, ((int(dtcNumber) + 2) / 3)):
            self.send_command(GET_DTC_COMMAND)
            res = self.get_result()
            # print "DTC result=" + res
            outfile.write("DTC result=" + res + '\n')
            outfile.flush()
            ressegment = res[4:]
            for i in range(0, 3):
                val1 = hex_to_int(ressegment[3 + i * 6:5 + i * 6])
                outfile.write('val1=' + str(val1) + '\n')
                val2 = hex_to_int(
                    ressegment[6 + i * 6:8 + i * 6]
                )  #get DTC codes from response (3 DTC each 2 bytes)
                outfile.write('val2=' + str(val2) + '\n')
                val = (val1 << 8) + val2  #DTC val as int
                outfile.write('val=' + str(val) + '\n')

                if val == 0:  #skip fill of last packet
                    break

                DTCStr = dtcLetters[(val & 0xC000) >> 14] + str(
                    (val & 0x3000) >> 12) + str((val & 0x0f00) >> 8) + str(
                        (val & 0x00f0) >> 4) + str(val & 0x000f)
                outfile.write('DTCStr=' + DTCStr + '\n')

                DTCCodes.append(["Active", DTCStr])

        #read mode 7
        self.send_command(GET_FREEZE_DTC_COMMAND)
        res = self.get_result()
        outfile.write("Read Mode 7:" + str(res) + '\n')
        outfile.flush()

        if res[:7] == "NO DATA":  #no freeze frame
            outfile.close()
            return DTCCodes

        # print "DTC freeze result=" + res
        outfile.write("DTC freeze result=" + res + '\n')
        ressegment = res[4:]
        for i in range(0, 3):
            val1 = hex_to_int(ressegment[3 + i * 6:5 + i * 6])
            outfile.write('val1=' + str(val1) + '\n')
            val2 = hex_to_int(
                ressegment[6 + i * 6:8 + i * 6]
            )  #get DTC codes from response (3 DTC each 2 bytes)
            outfile.write('val2=' + str(val2) + '\n')
            val = (val1 << 8) + val2  #DTC val as int
            outfile.write('val=' + str(val) + '\n')

            if val == 0:  #skip fill of last packet
                break

            DTCStr = dtcLetters[(val & 0xC000) >> 14] + str(
                (val & 0x3000) >> 12) + str((val & 0x0f00) >> 8) + str(
                    (val & 0x00f0) >> 4) + str(val & 0x000f)
            outfile.write('DTCStr=' + DTCStr + '\n')
            DTCCodes.append(["Passive", DTCStr])
            # outfile.write('Intermediate DTCCodes=' + str(DTCCodes) + '\n')

        outfile.write('DTCCodes=' + str(DTCCodes) + '\n')
        outfile.close()
        return DTCCodes