tao_z
2022-08-07 a1a1c89b91fc9476c51981699aaa7c2bccdd8570
widgets/ShifterTool.py
@@ -4,7 +4,7 @@
from logging import exception
import threading
from typing import List
from can import BusABC, Message
from can import BusABC, Message, Logger, Listener
from udsoncan.client import Client
from udsoncan.exceptions import TimeoutException
import udsoncan
@@ -23,22 +23,23 @@
import datetime
from ShifterDefine import *
from multiprocessing import Process, Queue, Value, Pipe
from hexread import *
MAX_RCV_NUM = 20
APP_ADDR_LOCATION_OFFSET = 8
APP_LENGTH_LOCATION_OFFSET = 12
logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.ERROR)
consoleHandler.setLevel(logging.DEBUG)
fileHandler = logging.FileHandler('./log/ShiftTool.log',
                                  mode='a',
                                  encoding='UTF-8')
fileHandler.setLevel(logging.INFO)
fileHandler.setLevel(logging.DEBUG)
consoleHandler.setFormatter(formatter)
fileHandler.setFormatter(formatter)
@@ -236,11 +237,13 @@
        self.sendQueue = Queue()  # can layer send queue
        self.CANtoIsoTPQueue = Queue()  # CAN --> isotp
        self.shifter = ShifterClass()
        self.Vehicle = VehicleClass()
        self.devicedescription = HardwreDevice()
        self.windows = QtWidgets.QMainWindow()
        self.UI = Ui_MainWindow()
        self.UI.setupUi(window)
        self._dev_info = None
        self.dbc = cantools.database.load_file("DBC/SX7H.dbc")
        self.can_thread = threading.Thread(target=self.can_thread)
        self.TestPresentTimer = QtCore.QTimer()
        self.TestPresentTimer.timeout.connect(self.creat_testpresentReq)
@@ -253,6 +256,8 @@
            0x1c, 0x01, 0x06, 0x80, 0x1f, 0x01, 0x06, 0x80, 0xfb, 0x0a
        ]
        self.app_data: bytes = None
        self.start_timestamp = time.time()
        self.boot_logger = None
    def DeviceInit(self):
        self._usbcan = None
@@ -335,10 +340,18 @@
            seed[3])
        if level == 0x01:
            output_key_temp = 0x20AA097B
            output_key = struct.pack('BBBB', (output_key_temp >> 24) & 0xFF,
                                     (output_key_temp >> 16) & 0xFF,
                                     (output_key_temp >> 8) & 0xFF,
                                     output_key_temp & 0xFF)
            # output_key_temp = ((((temp_key >> 4) ^ temp_key)
            #                     << 3) ^ temp_key) & 0xFFFFFFFF
        elif level == 0x09:
            output_key_temp = 0x70237577
            output_key = struct.pack('BBBB', (output_key_temp >> 24) & 0xFF,
                                     (output_key_temp >> 16) & 0xFF,
                                     (output_key_temp >> 8) & 0xFF,
                                     output_key_temp & 0xFF)
            # _temp_y = ((temp_key << 24) & 0xFF000000) + ((temp_key << 8) &
            #                                              0xFF0000) + ((temp_key >> 8) & 0xFF00) + ((temp_key >> 24) & 0xFF)
            # _temp_z = 0
@@ -354,13 +367,21 @@
            #     _temp_z = _temp_z & 0xFFFFFFFF
            # output_key_temp = (((_temp_z << 24) & 0xFF000000) | ((_temp_z << 8) & 0xFF0000) | (
            #     (_temp_z >> 8) & 0xFF00) | ((_temp_z >> 24) & 0xFF))
        elif level == 0x7D:
            output_key_temp = 0xAB2F9F36099D81F3
            output_key = struct.pack(
                'BBBBBBBB', (output_key_temp >> 56) & 0xFF,
                (output_key_temp >> 48) & 0xFF, (output_key_temp >> 40) & 0xFF,
                (output_key_temp >> 32) & 0xFF, (output_key_temp >> 24) & 0xFF,
                (output_key_temp >> 16) & 0xFF, (output_key_temp >> 8) & 0xFF,
                output_key_temp & 0xFF)
        else:
            output_key_temp = temp_key
        output_key = struct.pack('BBBB', (output_key_temp >> 24) & 0xFF,
                                 (output_key_temp >> 16) & 0xFF,
                                 (output_key_temp >> 8) & 0xFF,
                                 output_key_temp & 0xFF)
            output_key = struct.pack('BBBB', (output_key_temp >> 24) & 0xFF,
                                     (output_key_temp >> 16) & 0xFF,
                                     (output_key_temp >> 8) & 0xFF,
                                     output_key_temp & 0xFF)
        return output_key
@@ -395,7 +416,15 @@
        msg.channel = 0
        msg.data = isotp_msg.data  # bytearray
        msg.is_extended_id = False
        msg.timestamp = time.time() - self.start_timestamp
        msg.is_error_frame = False
        msg.is_remote_frame = False
        self.Tool_send(msg)
    def Tool_send(self, msg: Message):
        self._usbcan.send(msg)
        if self.boot_logger is not None:
            self.boot_logger.on_message_received(msg)
    def WidgetsInit(self):
        # self.UI.setupUi(self)
@@ -430,9 +459,11 @@
        self.UI.comboBox_6.addItems(list(DID_dic.keys()))
        self.DID_display()
        self.UI.comboBox_6.activated.connect(self.DID_display)
        self.UI.comboBox_7.addItems(list(DTCGroup_dic.keys()))
        self.UI.comboBox_7.activated.connect(self.ClearDTC)
        self.UI.pushButton_31.clicked.connect(self.SecurityUnlockLevel_1)
        self.UI.pushButton_32.clicked.connect(self.SecurityUnlockLevel_3)
        self.UI.pushButton_32.clicked.connect(self.SecurityUnlockLevel_2)
        self.UI.pushButton_12.clicked.connect(self.ReadSupplyID)
        self.UI.pushButton_4.clicked.connect(self.ReadVIN)
@@ -455,6 +486,18 @@
        self.UI.pushButton_48.clicked.connect(self.start_programming)
        self.UI.pushButton_46.clicked.connect(self.loadAppfile)
        self.UI.radioButton_2.toggled.connect(self.SetFromBootFlag)
        self.UI.pushButton_47.clicked.connect(self.SetBootLog)
        # self.UI.comboBox_10.activated.connect(self.ReportByMask)
        self.UI.comboBox_11.addItems(list(ReportBymask_DTC.keys()))
        self.UI.comboBox_12.addItems(list(DTC_Dic.keys()))
        self.UI.comboBox_13.addItems(list(DTC_Control_dic.keys()))
        self.UI.comboBox_13.activated.connect(self.DTC_Control)
        self.UI.pushButton_49.clicked.connect(self.ReportSupportDTC)
        self.UI.comboBox_11.activated.connect(self.ReportByMask)
        self.UI.comboBox_12.activated.connect(self.ReportSnapshotByDTC)
    def _formatMsgData(self, index, item, received):
        '''msg data to list
@@ -488,7 +531,7 @@
            data.append('标准帧')
        data.append(' '.join(
            ['0x' + '{:0<2x}'.format(a).upper() for a in list(item.data)]))
            ['0x' + '{:0>2x}'.format(a).upper() for a in list(item.data)]))
        return data
    def can_thread_stop(self):
@@ -517,12 +560,15 @@
                                    msg[i])  # send msg to isotp
                            self.msgQueue.put(msg[i])
                            if self.boot_logger is not None:
                                self.boot_logger.on_message_received(msg[i])
                            # logger.info('time:'.format(msg[i].timestamp)+'Rx: ID=0x{:0<3x} '.format(msg[i].arbitration_id) + ' '.join(['0x' +
                            #    '{:0<2x}'.format(a).upper() for a in list(msg[i].data)]))
                            # send signal to update screen
                        g_signal.sig_MsgReceived.emit(num)
                # msgToSendCnt = self.sendQueue.qsize()
                # if msgToSendCnt > 0:
                #     msg = Message()
@@ -531,7 +577,7 @@
                #         msg = self.sendQueue.get()
                #         # logger.info('Tx: ID=0x{:0<3x} '.format(
                #         #     msg.arbitration_id)+'DLC={} '.format(msg.dlc)+'externd flag ={} '.format(msg.is_extended_id)+'remote frame:{} '.format(msg.is_remote_frame))
                #         self._usbcan.send(msg)
                #         self.Tool_send(msg)
    def send_dump(self):
        msg = Message()
        msg.arbitration_id = self.shifter.canid.phy_rxId
@@ -539,7 +585,22 @@
        msg.channel = 0
        msg.data = [0x02, 0x3e, 0x80, 0, 0, 0, 0, 0]
        msg.is_extended_id = False
        self._usbcan.send(msg)
        msg.is_remote_frame = False
        msg.is_error_frame = False
        msg.timestamp = time.time() - self.start_timestamp
        self.Tool_send(msg)
    def send_VehiclePosition(self, data=[]):
        msg = Message()
        msg.arbitration_id = 0x10
        msg.dlc = 8
        msg.channel = 0
        msg.data = data
        msg.is_extended_id = False
        msg.is_remote_frame = False
        msg.is_error_frame = False
        msg.timestamp = time.time() - self.start_timestamp
        self.Tool_send(msg)
    def open_close(self):
        if self._isOpen.value == 0:
@@ -551,7 +612,7 @@
                    TIMING_DICT.keys())[self.devicedescription.baudrate]
                self._usbcan = USBCAN(device_type=4,
                                      device_index=0,
                                      can_index=0,
                                      can_index=self.devicedescription.channel,
                                      bitrate=bitrate,
                                      can_filters=can_filters)
                if not self._usbcan.InitAndStart():
@@ -572,6 +633,9 @@
            self.needdisconnect.value = 1
            self._deviceOpenUpdate()
            self.TestPresentTimer.stop()
    def closeEvent(self, e):
        self.boot_logger.stop()
    def update_HardwareDevice(self):
@@ -615,6 +679,38 @@
        self.UI.pushButton_41.setStyleSheet(
            Style_dic[self.shifter.UnlockButton])
        self.UI.pushButton_40.setStyleSheet(Style_dic[self.shifter.Pbutton])
        #X2
        self.UI.pushButton_37.setStyleSheet(
            Style_dic[self.shifter.position == 2])
        #X1
        self.UI.pushButton_38.setStyleSheet(
            Style_dic[self.shifter.position == 3])
        #Z
        self.UI.pushButton_30.setStyleSheet(
            Style_dic[self.shifter.position == 0])
        #Y1
        self.UI.pushButton_33.setStyleSheet(
            Style_dic[self.shifter.position == 4])
        #Y2
        self.UI.pushButton_34.setStyleSheet(
            Style_dic[self.shifter.position == 5])
        #M
        self.UI.pushButton_39.setStyleSheet(
            Style_dic[self.shifter.position == 0xe])
        #M+
        self.UI.pushButton_35.setStyleSheet(
            Style_dic[self.shifter.position == 0xd])
        #M-
        self.UI.pushButton_36.setStyleSheet(
            Style_dic[self.shifter.position == 0xc])
        self.UI.pushButton_42.setStyleSheet(
            ColorStyle_dic[self.Vehicle.ShiftLeverPos == "P"])
        self.UI.pushButton_43.setStyleSheet(
            ColorStyle_dic[self.Vehicle.ShiftLeverPos == "D"])
        self.UI.pushButton_44.setStyleSheet(
            ColorStyle_dic[self.Vehicle.ShiftLeverPos == "N"])
        self.UI.pushButton_45.setStyleSheet(
            ColorStyle_dic[self.Vehicle.ShiftLeverPos == "R"])
    def _updateRootList(self):
        _dataSize = self.msgQueue.qsize()
@@ -625,11 +721,14 @@
        for i in range(_dataSize):
            receiveNum += 1
            msg = self.msgQueue.get()
            self.shifter.FramUnpack(msg.arbitration_id, msg.data)
            if msg.arbitration_id == 0x420:
                self.shifter.FramUnpack(msg.arbitration_id, msg.data)
                resp_data = self.Vehicle.ShiftLogic(self.shifter)
                self.send_VehiclePosition(resp_data)
            formateddata.append(self._formatMsgData(
                receiveNum, msg, True))  # return a data list
        self._insertDataSmooth(data=formateddata, datasize=_dataSize)
        # self.dispShiftstatus()
        self.dispShiftstatus()
    def _insertDataSmooth(self, data, datasize):
        # row = 6-datasize
@@ -661,16 +760,20 @@
    def sessioncontrol_req(self):
        sesson = self.UI.comboBox.currentIndex() + 1
        t = threading.Thread(target=self.udsclient.change_session,
                             args=(sesson, ))
        t.start()
        t.join()
        # self.udsclient.change_session(sesson)
        self.udsclient.change_session(sesson)
    # self.UI.comboBox_8.addItems(['0x01硬件复位', '0x03软件复位'])
    def MCUReset_req(self):
        req = 0x03 if self.UI.comboBox_8.currentData() == '0x01硬件复位' else 0x01
        req = 0x03 if self.UI.comboBox_8.currentText() == '0x01硬件复位' else 0x01
        self.udsclient.ecu_reset(req)
    def ClearDTC(self):
        self.udsclient.clear_dtc(
            group=DTCGroup_dic[self.UI.comboBox_7.currentText()])
    def DTC_Control(self):
        self.udsclient.control_dtc_setting(
            setting_type=DTC_Control_dic[self.UI.comboBox_13.currentText()])
    def Security_req(self):
        self.udsclient.unlock_security_access(1)
@@ -682,11 +785,18 @@
            self.UI.pushButton_31.setStyleSheet(
                "background-color:rgb(255, 85, 127)")
    def SecurityUnlockLevel_3(self):
    def SecurityUnlockLevel_2(self):
        data = self.udsclient.unlock_security_access(9)
        if data.positive:
            self.UI.pushButton_32.setStyleSheet(
                "background-color:rgb(255, 85, 127)")
    def SecurityUnlockLevel_3(self):
        data = self.udsclient.unlock_security_access(0x7d)
        if data.positive:
            self.UI.pushButton_32.setStyleSheet(
                "background-color:rgb(0, 128, 0)")
        return data
    def ReadSupplyID(self):
        data = self.ReadByDID(0xF18A)
@@ -723,7 +833,8 @@
        self.UI.lineEdit_2.clear()
        data = self.ReadByDID(tempdid)
        if data is not None and len(str(data[tempdid])):
            self.UI.lineEdit_2.setText(str(data[tempdid]) + ' ')
            # print(data[tempdid])
            self.UI.lineEdit_2.setText(data[tempdid])
    def WriteDataByID(self):
        tempdid = DID_dic[self.UI.comboBox_6.currentText()]
@@ -745,14 +856,23 @@
            req = 1
        else:
            req = 3
        self.udsclient.communication_control(control_type=0,
                                             communication_type=req)
        try:
            self.udsclient.communication_control(control_type=req,
                                                 communication_type=1)
        except Exception as e:
            self.disp_string('%s' % e)
    def StartCalibraiton(self):
        startcmd = bytearray([0x0, 0x0, 0x0, 0x0])
        if self.RequestRoutControl(0xFFAA, bytes(startcmd)):
            self.UI.pushButton_9.setStyleSheet(
                "background-color:rgb(255, 85, 127)")
        sesson = 3
        self.UI.comboBox.setCurrentIndex(sesson - 1)
        response = self.udsclient.change_session(sesson)
        if response.positive:
            response = self.SecurityUnlockLevel_3()
        if response.positive:
            startcmd = bytearray([0x8, 0x0, 0x0, 0x0])
            if self.RequestRoutControl(0xFFAA, bytes(startcmd)):
                self.UI.pushButton_9.setStyleSheet(
                    "background-color:rgb(255, 85, 127)")
    def Calibraiton_Z(self):
        calcmd = bytearray([0x1, 0x0, 0x0, 0x0])
@@ -761,43 +881,43 @@
                "background-color:rgb(255, 85, 127)")
    def Calibraiton_M(self):
        calcmd = bytearray([0x2, 0x0, 0x0, 0x0])
        calcmd = bytearray([0x0, 0x0, 0x0, 0x0])
        if self.RequestRoutControl(0xFFAA, bytes(calcmd)):
            self.UI.pushButton_13.setStyleSheet(
                "background-color:rgb(255, 85, 127)")
    def Calibraiton_MP(self):
        calcmd = bytearray([0x3, 0x0, 0x0, 0x0])
        calcmd = bytearray([0x2, 0x0, 0x0, 0x0])
        if self.RequestRoutControl(0xFFAA, bytes(calcmd)):
            self.UI.pushButton_18.setStyleSheet(
                "background-color:rgb(255, 85, 127)")
    def Calibraiton_MN(self):
        calcmd = bytearray([0x4, 0x0, 0x0, 0x0])
        calcmd = bytearray([0x3, 0x0, 0x0, 0x0])
        if self.RequestRoutControl(0xFFAA, bytes(calcmd)):
            self.UI.pushButton_22.setStyleSheet(
                "background-color:rgb(255, 85, 127)")
    def Calibraiton_X2(self):
        calcmd = bytearray([0x5, 0x0, 0x0, 0x0])
        calcmd = bytearray([0x4, 0x0, 0x0, 0x0])
        if self.RequestRoutControl(0xFFAA, bytes(calcmd)):
            self.UI.pushButton_24.setStyleSheet(
                "background-color:rgb(255, 85, 127)")
    def Calibraiton_X1(self):
        calcmd = bytearray([0x6, 0x0, 0x0, 0x0])
        calcmd = bytearray([0x5, 0x0, 0x0, 0x0])
        if self.RequestRoutControl(0xFFAA, bytes(calcmd)):
            self.UI.pushButton_26.setStyleSheet(
                "background-color:rgb(255, 85, 127)")
    def Calibraiton_Y1(self):
        calcmd = bytearray([0x7, 0x0, 0x0, 0x0])
        calcmd = bytearray([0x6, 0x0, 0x0, 0x0])
        if self.RequestRoutControl(0xFFAA, bytes(calcmd)):
            self.UI.pushButton_27.setStyleSheet(
                "background-color:rgb(255, 85, 127)")
    def Calibraiton_Y2(self):
        calcmd = bytearray([0x8, 0x0, 0x0, 0x0])
        calcmd = bytearray([0x7, 0x0, 0x0, 0x0])
        if self.RequestRoutControl(0xFFAA, bytes(calcmd)):
            self.UI.pushButton_28.setStyleSheet(
                "background-color:rgb(255, 85, 127)")
@@ -811,6 +931,68 @@
    def RequestRoutControl(self, routine_id, data):
        resp_1 = self.udsclient.start_routine(routine_id=routine_id, data=data)
        return resp_1.positive
    def ReportSupportDTC(self):
        resp_1 = self.udsclient.get_supported_dtc()
        if resp_1.positive:
            for i in range(len(resp_1.data) // 4):
                a = i * 4 + 2
                b = i * 4 + 3
                c = i * 4 + 4
                d = i * 4 + 5
                dtc_hex = resp_1.data[a] << 16 | resp_1.data[
                    b] << 8 | resp_1.data[c] << 0
                log = 'DTC:0x%.6x Status:0x%.2x ' % (
                    dtc_hex, resp_1.data[d]) + DTC_DescriptionDic[dtc_hex]
                for j in range(8):
                    if resp_1.data[d] >> j & 0x1:
                        log += ' bit%d' % j
                self.disp_string(log)
    def ReportByMask(self):
        mask = ReportBymask_DTC[self.UI.comboBox_11.currentText()]
        resp_1 = self.udsclient.get_dtc_by_status_mask(status_mask=mask)
        if resp_1.positive:
            for i in range(len(resp_1.data) // 4):
                a = i * 4 + 2
                b = i * 4 + 3
                c = i * 4 + 4
                d = i * 4 + 5
                dtc_hex = resp_1.data[a] << 16 | resp_1.data[
                    b] << 8 | resp_1.data[c] << 0
                log = 'DTC:0x%.2x%.2x%.2x Status:0x%.2x %s ' % (
                    resp_1.data[a], resp_1.data[b], resp_1.data[c],
                    resp_1.data[d], DTC_DescriptionDic[dtc_hex])
                for j in range(8):
                    if resp_1.data[d] >> j & 0x1:
                        log += 'bit%d ' % j
                self.disp_string(log)
    def ReportSnapshotByDTC(self):
        dtc = DTC_Dic[self.UI.comboBox_12.currentText()][
            self.UI.comboBox_12.currentIndex()]
        try:
            resp = self.udsclient.get_dtc_snapshot_by_dtc_number(
                dtc=dtc, record_number=1)
            if resp.positive:
                number_of_did = resp.data[6]
                status = resp.data[4]
                print(status)
                dtc = resp.service_data.dtcs[0]
                snapshots = dtc.snapshots
                # print(dtc.id)
                # print(dtc.status.get_byte())
                log = "DTC:0x%.6x Status:0x%.2x" % (dtc.id, status) + ' '
                # print(type(snapshots[0].did))
                # print(type(snapshots[0].data))
                for i in range(number_of_did):
                    log += (DTC_SanpshotDescriptionDic[snapshots[i].did] +
                            ':' + snapshots[i].data + ' ')
                self.disp_string(log)
                # print(snapshots[i].did, snapshots[i].data)
        except Exception as e:
            self.disp_string('%s' % e)
    def SetFromBootFlag(self):
        self.startfromboot = self.UI.radioButton_2.isChecked()
@@ -995,11 +1177,48 @@
        if fileName != '':
            self.UI.comboBox_4.addItem(fileName)
            self.UI.comboBox_4.setCurrentText(fileName)
            with open(fileName, 'rb') as fd:
                self.app_data = fd.read()
                drv_data_len = len(
                    self.drv_data) if self.drv_data is not None else 0
                app_data_len = len(
                    self.app_data) if self.app_data is not None else 0
                total_len = drv_data_len + app_data_len
                self.UI.progressBar.setRange(0, total_len)
            # with open(fileName, 'rb') as fd:
            #     self.app_data = fd.read()
            #     drv_data_len = len(
            #         self.drv_data) if self.drv_data is not None else 0
            #     app_data_len = len(
            #         self.app_data) if self.app_data is not None else 0
            #     total_len = drv_data_len + app_data_len
            #     self.UI.progressBar.setRange(0, total_len)
            # print(self.app_data)
            # print("===============================================")
            hex_read = Hex_read()
            hex_read.Open_file(fileName)
            self.app_data = hex_read.data
            drv_data_len = len(
                self.drv_data) if self.drv_data is not None else 0
            app_data_len = len(
                self.app_data) if self.app_data is not None else 0
            total_len = drv_data_len + app_data_len
            self.UI.progressBar.setRange(0, total_len)
    def SetBootLog(self):
        if self.in_programming:
            self.disp_string('## 正在编程中')
            return
        fileName, _ = QtWidgets.QFileDialog.getSaveFileName(
            None, 'comboBox_10', '.',
            'All Files (*);;ASC Files (*.asc);;Blf Files (*.blf)')
        if fileName != '':
            self.UI.comboBox_10.addItem(fileName)
            self.UI.comboBox_10.setCurrentText(fileName)
            print(fileName)
            self.boot_logger = Logger(fileName)
            # self.listener = [self.boot_logger]
            # with open(fileName, 'rb') as fd:
            #     self.app_data = fd.read()
            #     drv_data_len = len(
            #         self.drv_data) if self.drv_data is not None else 0
            #     app_data_len = len(
            #         self.app_data) if self.app_data is not None else 0
            #     total_len = drv_data_len + app_data_len
            #     self.UI.progressBar.setRange(0, total_len)