本文介绍: 【代码】Python+PyQt5+C Hw信息检测。

UI主界面:

C源代码:

/* I/O port access
 * Copyright (C) 2009 Red Hat Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

//#include <config.h>

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>

#include <sys/io.h>

static int op = 0;		/* Operation, 0 = read, 1 = write. */
static int size = 1;		/* Operation size in bytes. */
static int rcode = 0;		/* If set, inX exits with return value. */
static int rhex = 0;		/* If set, print result in hex. */

static struct option long_options[] = {
  { "code",  0, 0, 'c' },
  { "read",  0, 0, 'r' },
  { "size",  1, 0, 's' },
  { "write", 0, 0, 'w' },
  { "hex",   0, 0, 'x' },
  { NULL,    0, 0, 0   },
};
static const char *options = "crs:w";

static void
usage ()
{
  printf ("n
Usage:n
  inb|inw|inl [--options] addressn
  outb|outw|outl [--options] address datan
Options:n
--code    Exit with status code instead of printing value (inX only).n
--hex     Print hex instead of decimal (inX only).n
--read    Perform a read (in) operation.n
--write   Perform a write (out) operation.n
--size N  Set size to N bytes where N = 1, 2 or 4.n
n
For detailed information, see the manual page inb(1).n
");
}

static unsigned get_int_or_die (const char *);

int
main (int argc, char *argv[])
{
  int c, option_index;
  char *p;
  unsigned addr = 0;
  unsigned data = 0;

  /* Find out how the program was invoked. */
  p = strrchr (argv[0], '/');
  if (p == NULL) p = argv[0]; else p++;

  if (strncasecmp (p, "inb", 3) == 0) {
    op = 0; size = 1;
  } else if (strncasecmp (p, "outb", 4) == 0) {
    op = 1; size = 1;
  } else if (strncasecmp (p, "inw", 3) == 0) {
    op = 0; size = 2;
  } else if (strncasecmp (p, "outw", 4) == 0) {
    op = 1; size = 2;
  } else if (strncasecmp (p, "inl", 3) == 0) {
    op = 0; size = 4;
  } else if (strncasecmp (p, "outl", 4) == 0) {
    op = 1; size = 4;
  }

  /* Parse command line arguments. */
  while (1) {
    option_index = 0;
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 'c':
      rcode = 1;
      break;

    case 'r':
      op = 0;
      break;

    case 's':
      size = get_int_or_die (optarg);
      if (!(size == 1 || size == 2 || size == 4)) {
	fprintf (stderr, "%s: size can only be 1, 2 or 4.n", optarg);
	exit (1);
      }
      break;

    case 'w':
      op = 1;
      break;

    case 'x':
      rhex = 1;
      break;

    case 0:
      fprintf (stderr, "internal error in getopt_longn");
      exit (1);

    default:
      usage ();
      exit (1);
    }
  }

  /* Parse the address (for read/write) and data (for writes). */
  if (optind >= argc) {
  missing:
    fprintf (stderr, "%s: missing parameter, see --help or man pagen",
	     argv[0]);
    exit (1);
  }

  addr = get_int_or_die (argv[optind++]);

  if (op == 1) {
    if (optind >= argc) goto missing;
    data = get_int_or_die (argv[optind++]);
  }

  if (optind != argc) {
    fprintf (stderr,
	     "%s: extra parameters on command line, see --help or man pagen",
	     argv[0]);
    exit (1);
  }

  /* Raise our privilege level. */
  if (iopl (3) == -1) {
    fprintf (stderr, "iopl failed: You may need to run as root or give the process the CAP_SYS_RAWIOncapability. On non-x86 architectures, this operation probably isn't possible.n");
    perror ("iopl");
    exit (1);
  }

  /* Perform the operation. */
  switch (op) {
  case 0:
    switch (size) {
    case 1: data = inb (addr); break;
    case 2: data = inw (addr); break;
    case 4: data = inl (addr); break;
    }
    break;
  case 1:
    switch (size) {
    case 1: outb (data, addr); break;
    case 2: outw (data, addr); break;
    case 4: outl (data, addr); break;
    }
    break;
  }

  if (op == 0) {
    if (rcode == 0) {
      if (rhex == 0)
	printf ("%dn", data);
      else
	printf ("%xn", data);
    } else
      exit (data);
  }
  exit (0);
}

static unsigned
get_int_or_die (const char *str)
{
  char *endp;
  unsigned r;

  errno = 0;
  r = strtoul (str, &endp, 0);
  if ((errno == ERANGE && r == ULONG_MAX)
      || (errno != 0 && r == 0)) {
    perror (str);
    exit (1);
  }

  if (str == endp) {
    fprintf (stderr, "expecting a number, but found an empty stringn");
    exit (1);
  }
  if (*endp != '') {
    fprintf (stderr, "%s: trailing garbage after numbern", str);
    exit (1);
  }

  return r;
}

配置文件:

[HW_UOS_X86_FAN]
R_FAN_TAC1_READING=0x0D
R_FAN_TAC1_EXT_READING=0x18
R_FAN_TAC2_READING=0x0E
R_FAN_TAC2_EXT_READING=0x19
R_FAN_TAC3_READING=0x0F
R_FAN_TAC3_EXT_READING=0x1A
R_FAN_TAC4_LBS_READING=0x80
R_FAN_TAC4_MSB_READING=0x81
R_FAN5_READING_LSB=0x82
R_FAN5_READING_MSB=0x83

[HW_UOS_X86_TMPIN]
R_TMPIN1_READING=0x29
R_TMPIN2_READING=0x2A
R_TMPIN3_READING=0x2B

[HW_UOS_X86_Voltage]
R_VIN0_READING=0x20
R_VIN1_READING=0x21
R_VIN2_READING=0x22
R_VIN3_READING=0x23
R_VIN4_READING=0x24
R_VIN5_READING=0x25
R_VIN6_READING=0x26
R_VBAT_READING=0x28

[HW_UOS_X86_TestConfig]
CPUFAN=1000~2000
SYSFAN=1300~2000
CPUTMP=25~40
VIN_CPU=1.11~1.2
VIN_DIMM=1.20~1.330
VIN_12=12~12.7
VIN_5V=5~5.08
VIN_3_3V=3.3~3.5
VBAT=1.8~2.2

[HW_ARM_TestConfig]
CPUFAN=1300~3000
CPUTMP1=25~40
CPUTMP2=25~40

源代码:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'HWWinFrm.ui'
#
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QTimer, pyqtSlot, Qt
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QLabel
#pip install opencv-python PyQt5
from PyQt5 import *
from PyQt5.Qt import *
from PyQt5 import QtWidgets
from PyQt5 import QtGui
from PyQt5 import QtCore
import logging
import os
import json
import configparser
from PyQt5.QtCore import pyqtSignal
import sys
import subprocess
import inspect
from subprocess import Popen,PIPE
from colorama import Fore,Style
import re
#pip install colorama

class HW_UOS_X86(QtCore.QThread):
    test_result_signal = QtCore.pyqtSignal(tuple)  # 新增信号,传递一个包含设备路径和测试结果的元组
    finished_signal = QtCore.pyqtSignal()  # 新增信号,表示线程完成

    def __init__(self,parent=None):
        super(HW_UOS_X86, self).__init__(parent)
        self.is_running=True

    def run(self):
        self.config = configparser.ConfigParser()  # 创建对象
        self.FANControl = []  # 风扇控制器
        #self.SYSFANControl = []  # 风扇控制器
        self.TEMPINControl = []  # 温度控制器
        self.VINControl = []  # 电压控制器
        self.TestArgs = []  # 测试参数

        # 读取的参数
        self.r_FanValues = []  # 读取的风扇值
        self.r_TempValues = []  # 读取温度值
        self.r_VinValues = []  # 读取电压值
        self.testResult=True#测试结果
        self.parent().hwTestInfo=''#测试信息
        self.testStandardArgs = ''  # 测试准标参数

        # 读取配置
        self.config.read('./Conf/config.conf', encoding='utf-8')  # 读取配置文件,如果配置文件不存在创建

        # 读取风扇配置寄存器信息
        self.FANControl.append(self.config.get('HW_UOS_X86_FAN', 'R_FAN_TAC1_READING'))
        self.FANControl.append(self.config.get('HW_UOS_X86_FAN', 'R_FAN_TAC1_EXT_READING'))
        self.FANControl.append(self.config.get('HW_UOS_X86_FAN', 'R_FAN_TAC2_READING'))
        self.FANControl.append(self.config.get('HW_UOS_X86_FAN', 'R_FAN_TAC2_EXT_READING'))
        self.FANControl.append(self.config.get('HW_UOS_X86_FAN', 'R_FAN_TAC3_READING'))
        self.FANControl.append(self.config.get('HW_UOS_X86_FAN', 'R_FAN_TAC3_EXT_READING'))
        self.FANControl.append(self.config.get('HW_UOS_X86_FAN', 'R_FAN_TAC4_LBS_READING'))
        self.FANControl.append(self.config.get('HW_UOS_X86_FAN', 'R_FAN_TAC4_MSB_READING'))
        self.FANControl.append(self.config.get('HW_UOS_X86_FAN', 'R_FAN5_READING_LSB'))
        self.FANControl.append(self.config.get('HW_UOS_X86_FAN', 'R_FAN5_READING_MSB'))

        # 读取温度配置寄存器信息
        self.TEMPINControl.append(self.config.get('HW_UOS_X86_TMPIN', 'R_TMPIN1_READING'))

        # 读取电压配置寄存器信息
        self.VINControl.append(self.config.get('HW_UOS_X86_Voltage', 'R_VIN0_READING'))
        self.VINControl.append(self.config.get('HW_UOS_X86_Voltage', 'R_VIN1_READING'))
        self.VINControl.append(self.config.get('HW_UOS_X86_Voltage', 'R_VIN2_READING'))
        self.VINControl.append(self.config.get('HW_UOS_X86_Voltage', 'R_VIN3_READING'))
        self.VINControl.append(self.config.get('HW_UOS_X86_Voltage', 'R_VIN4_READING'))
        self.VINControl.append(self.config.get('HW_UOS_X86_Voltage', 'R_VIN5_READING'))
        self.VINControl.append(self.config.get('HW_UOS_X86_Voltage', 'R_VIN6_READING'))
        self.VINControl.append(self.config.get('HW_UOS_X86_Voltage', 'R_VBAT_READING'))

        # 读取的hw信息配置
        self.HwConfig_CPUFAN = []  # Hw配置CPU风扇信息
        self.HwConfig_CPUFAN.append(self.config.get('HW_UOS_X86_TestConfig', 'CPUFAN'))
        self.cpufan=self.HwConfig_CPUFAN[0].split('~')#cpu风扇转速参数

        self.HwConfig_SYSFAN=[]# HW配置系统风扇信息
        self.HwConfig_SYSFAN.append(self.config.get('HW_UOS_X86_TestConfig', 'SYSFAN'))
        self.sysfan = self.HwConfig_SYSFAN[0].split('~')  # cpu风扇转速参数

        # 读取温度信息配置
        self.HwConfig_Tmp = []  # Hw配置温度信息
        self.HwConfig_Tmp.append(self.config.get('HW_UOS_X86_TestConfig', 'CPUTMP'))
        self.cputmp=self.HwConfig_Tmp[0].split('~')#cpu温度参数

        # 读取电压信息配置
        self.HwConfig_Vin = []  # Hw配置电压信息
        self.HwConfig_Vin.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_CPU'))
        self.vincpu=self.HwConfig_Vin[0].split('~')
        self.HwConfig_Vin.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_DIMM'))
        self.vindimm=self.HwConfig_Vin[1].split('~')
        self.HwConfig_Vin.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_12'))
        self.vin_12=self.HwConfig_Vin[2].split('~')
        self.HwConfig_Vin.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_5V'))
        self.vin_5v=self.HwConfig_Vin[3].split('~')
        self.HwConfig_Vin.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_3_3V'))
        self.vin_3_3v=self.HwConfig_Vin[4].split('~')
        self.HwConfig_Vin.append(self.config.get('HW_UOS_X86_TestConfig', 'VBAT'))
        self.vbat=self.HwConfig_Vin[5].split('~')

        # 读取测试参数并比较
        self.ReadFanVlaues('R_FAN_TAC1',self.FANControl[0],self.FANControl[1],self.cpufan)
        #self.ReadFanVlaues('R_FAN_TAC2',self.FANControl[2],self.FANControl[3],self.cputmp)

        # 读取温度参数
        # print('Template_1:',self.TEMPINControl[0])
        self.ReadCpuTemplate('R_TMPIN1', self.TEMPINControl[0],self.cputmp)  # 读取TEMP1寄存器温度

        # 读取电压参数
        self.ReadVINvalues('VIN_CPU', self.VINControl[0],self.vincpu)  # 读取VIN_CPU
        self.ReadVINvalues('VIN_DIMM', self.VINControl[1],self.vindimm)  # 读取VINO寄存器电压
        self.ReadVINvalues('VIN_12', self.VINControl[2],self.vin_12)  # 读取VIN_12V寄存器电压
        self.ReadVINvalues('VIN_5V', self.VINControl[3],self.vin_5v)  # 读取VIN_5V寄存器电压
        self.ReadVINvalues('VIN_3_3V', self.VINControl[4],self.vin_3_3v)  # 读取VIN_3_3V寄存器电压
        self.ReadVINvalues('VBAT', self.VINControl[5],self.vbat)  # 读取VBAT寄存器电压
        #self.ReadVINvalues('R_VIN6', self.VINControl[6],)  # 读取VINO寄存器电压
        #self.ReadVINvalues('R_VBAT', self.VINControl[7],)  # 读取VINO寄存器电压


        #更新风扇信息
        for fanvalues in self.r_FanValues:#CPU风扇信息
            isPass = False
            #faninfo.append(fanvalues['itemName'])
            #faninfo.append(fanvalues['readValues'])
            #faninfo.append(fanvalues['testReuslt'])
            faninfo = [fanvalues['itemName'], fanvalues['readValues'], fanvalues['testReuslt']]
            if fanvalues['testReuslt']=='PASS':
                isPass=True
            else:
                self.testResult=False
            self.parent().TableAddItem(faninfo,isPass)
            self.parent().hwTestInfo+=f"{fanvalues['itemName']},{fanvalues['readValues']},{fanvalues['testReuslt']}|"

        #更新CPU温度信息
        for tempvalues in self.r_TempValues:#CPU温度信息
            isPass=False
            #tempinfo.append(tempvalues['itemName'])
            #tempinfo.append(tempvalues['readValues'])
            #tempinfo.append(tempvalues['testReuslt'])
            tempinfo = [tempvalues['itemName'],tempvalues['readValues'],tempvalues['testReuslt']]
            if tempvalues['testReuslt']=='PASS':
                isPass=True
            else:
                self.testResult=False
            self.parent().TableAddItem(tempinfo,isPass)
            self.parent().hwTestInfo += f"{tempvalues['itemName']},{tempvalues['readValues']},{tempvalues['testReuslt']}|"

        #更新各项电压信息
        for vim in self.r_VinValues:#电压信息
            isPass=False
            #viminfo.append(vim['itemName'])
            #viminfo.append(vim['readValues'])
            #viminfo.append(vim['testReuslt'])
            viminfo = [vim['itemName'],vim['readValues'],vim['testReuslt']]
            if vim['testReuslt']=='PASS':
                isPass=True
            else:
                self.testResult=False
            self.parent().TableAddItem(viminfo,isPass)
            self.parent().hwTestInfo += f"{vim['itemName']},{vim['readValues']},{vim['testReuslt']}|"
        self.parent().hwTestInfo=self.parent().hwTestInfo[:-1]
        self.finished_signal.emit()  # 线程完成时发出信号
        self.stop()
        self.parent().hwTestPass = self.testResult#回传测试结果

    def stop(self):
        self.is_running = False # 或者使用更安全的停止逻辑

    #读取电压信息
    def ReadVINvalues(self,itemName,sendsorData,argsvalues):
        try:
            vinvalue=0.0000
            #进行pnp mode
            os.system('./Hw_UOS_X86/port --write 0x2E 0x87')
            os.system('./Hw_UOS_X86/port --write 0x2E 0X01')
            os.system('./Hw_UOS_X86/port --write 0x2E 0X55')
            os.system('./Hw_UOS_X86/port --write 0x2E 0X55')

            #读取电压寄存器
            os.system('./Hw_UOS_X86/port --write 0x295 ' + sendsorData)  #传值
            redtep_l = Popen(['./Hw_UOS_X86/port --read 0x296'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
            # 获取子进程的输出
            stdout, stderr = redtep_l.communicate()
            #将输出转换成为字符串
            vin=stdout.decode("utf-8").strip()#获取的值
            if itemName=='VIN_12':#12V电压
                vinvalue=float((int(vin)/2)*12)/100+1
            elif itemName=='VIN_5V':#5V电压
                vinvalue=float((int(vin)/2)*5)/100+0.4
            elif itemName=='VIN_3_3V':#3.3V电压
                vinvalue=float((int(vin)/20)*33)/100+0.3
            else:
                vinvalue=(float(vin)*10.9)/1000
            result=round(vinvalue,4)

            if float(result)>float(argsvalues[0]) and float(result)<float(argsvalues[1]):
                self.r_TempValues.append({'itemName': itemName, 'readValues': str(float(result)) + ' V', 'testReuslt': 'PASS'})
                return True
            else:
                self.r_TempValues.append({'itemName': itemName, 'readValues': str(float(result)) + ' V', 'testReuslt': 'FAIL'})
                return False
            #self.r_VinValues.append({itemName:result})
            #return True
            #print("vin",float(vin))
        except Exception as e:
            self.ShowLog(str(e),False)
            return False

    # 读取CPU温度
    def ReadCpuTemplate(self, itemName, sensorData,argsvalues):
        try:
            cpuTemplate = 0
            # 进行pnp mode
            os.system('./Hw_UOS_X86/port --write 0x2E 0x87')
            os.system('./Hw_UOS_X86/port --write 0x2E 0X01')
            os.system('./Hw_UOS_X86/port --write 0x2E 0X55')
            os.system('./Hw_UOS_X86/port --write 0x2E 0X55')

            # 读取CPU 温度寄存器
            os.system('./Hw_UOS_X86/port --write 0x295 ' + sensorData)  # 传值
            redtep_l = Popen(['./Hw_UOS_X86/port --read 0x296'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
            # 获取子进程的输出
            stdout, stderr = redtep_l.communicate()
            # 将输出转换成为字符串
            tmp = stdout.decode("utf-8").strip()  # 获取的值
            if float(tmp)>float(argsvalues[0]) and float(tmp)<float(argsvalues[1]):
                self.r_TempValues.append({'itemName':itemName,'readValues':str(float(tmp))+' C','testReuslt':'PASS'})
                return True
            else:
                self.r_TempValues.append({'itemName': itemName, 'readValues': str(float(tmp)) + ' C', 'testReuslt': 'FAIL'})
                return False
            #self.r_TempValues.append({itemName: int(tmp)})
            # print('CpuTemp:',tmp)
        except Exception as e:
            self.ShowLog(str(e), False)
            return False

    #读取风扇转速
    def ReadFanVlaues(self,itemName,low,high,argsvalues):
        try:
            fanvalues = 0
            # redfan_h=0
            # fan_l=0
            # 进行pnp mode
            os.system('./Hw_UOS_X86/port --write 0x2E 0x87')
            os.system('./Hw_UOS_X86/port --write 0x2E 0X01')
            os.system('./Hw_UOS_X86/port --write 0x2E 0X55')
            os.system('./Hw_UOS_X86/port --write 0x2E 0X55')

            # 读取CPU FAN转速寄存器
            os.system('./Hw_UOS_X86/port --write 0x295 ' + low)  # 低点传值
            redfan_l = Popen(['./Hw_UOS_X86/port --read 0x296'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
            # 获取子进程的输出
            stdout, stderr = redfan_l.communicate()
            # 将输出转换成为字符串
            fan_l = stdout.decode("utf-8").strip()  # 低点值
            # print('fan_l',fan_l)

            os.system('./Hw_UOS_X86/port --write 0x295 ' + high)  # 高点传值
            redfan_h = Popen(['./Hw_UOS_X86/port --read 0x296'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
            # 获取子进程的输出
            stdout, stderr = redfan_h.communicate()
            # 将输出转换成字符串
            fan_h = stdout.decode("utf-8").strip()  # 高点值
            # print('fan_h',fan_h)

            fanvalues = 1350000 / ((int(fan_h) * 256 + int(fan_l)) * 2)
            # print(itemName,int(fanvalues),' RPM')

            if float(fanvalues)>float(self.cpufan[0]) and float(fanvalues)<float(self.cpufan[1]):
                self.r_FanValues.append({'itemName':itemName,'readValues':str(float(fanvalues))+'RPM','testReuslt':'PASS'})
                return True
            else:
                self.r_FanValues.append({'itemName': itemName, 'readValues': str(float(fanvalues)) + 'RPM', 'testReuslt': 'FAIL'})
                return False
            #self.r_FanValues.append({itemName:int(fanvalues)})
        except Exception as e:
            self.ShowLog(str(e),False)
            return False

    # 日志信息
    def ShowLog(self, log, isPass):
        if isPass == True:
            print("33[1;32;43m" + str(log) + " 33[0m")
            self.logger.info(str(log))
        else:
            print("33[1;31m" + str(log) + " 33[0m")
            self.logger.error(str(log))
            self.err=str(log)

class HW_UOS_Arm(QtCore.QThread):
    test_result_signal = QtCore.pyqtSignal(tuple)  # 新增信号,传递一个包含设备路径和测试结果的元组
    finished_signal = QtCore.pyqtSignal()  # 新增信号,表示线程完成

    def __init__(self,parent=None):
        self.is_running=True

    def run(self):
        self.config = configparser.ConfigParser()  # 创建对象
        self.r_FanVlaues = []  # 读取的风扇值
        self.r_TempValues = []  # 读取温度值
        self.err=''#错误信息
        self.testResult = True  # 测试结果
        self.parent().hwTestInfo = ''  # 测试信息

        # 读取配置
        self.config.read('./Conf/config.conf', encoding='utf-8')  # 读取配置文件,如果配置文件不存在创建

        # 读取的hw信息配置
        self.HwConfig_CPUFAN=[]#HW配置CPU风扇信息
        self.HwConfig_CPUFAN.append(self.config.get('HW_ARM_TestConfig', 'CPUFAN'))
        self.cpufanArgs=self.HwConfig_CPUFAN[0].split('~')#读取CPU风扇参数

        #读取温度信息
        self.HwConfig_Tmp = []  # Hw配置温度信息
        self.HwConfig_Tmp.append(self.config.get('HW_ARM_TestConfig', 'CPUTMP1'))
        self.cputmp1_Args=self.HwConfig_Tmp[0].split('~')#读取CPU温度1参数

        self.HwConfig_Tmp.append(self.config.get('HW_ARM_TestConfig', 'CPUTMP2'))
        self.cputmp2_Args=self.HwConfig_Tmp[1].split('~')#读取CPU温度2参数

        #读取寄存器风扇转速
        self.ReadFanValues('CPUFAN')#读取FAN1寄存器转速
        for fan in self.r_FanVlaues:

            isPass = False
            #faninfo.append(fan['itemName'])
            #faninfo.append(fan['readValues'])
            #faninfo.append(fan['testResult'])
            faninfo = [fan['itemName'],fan['readValues'],fan['testResult']]
            if fan['testResult']=='PASS':
                isPass=True
            else:
                self.testResult=False
            self.parent().TableAddItem(faninfo,isPass)
            self.parent().hwTestInfo+=f"{fan['itemName']},{fan['readValues']},{fan['testReuslt']}|"

        #读取CPU温度
        self.ReadCpuTemplate('CPUTMP1','CPUTMP2')#读取TMP1和TMP2温度值
        for template in self.r_TempValues:
            isPass=False
            #tmpinfo.append(template['itemName'])
            #tmpinfo.append(template['readValues'])
            #tmpinfo.append(template['testResult'])
            tmpinfo = [template['itemName'],template['readValues'],template['testResult']]
            if template['testResult']=='PASS':
                isPass = True
            else:
                self.testResult = False
            self.parent().TableAddItem(tmpinfo, isPass)
            self.parent().hwTestInfo += f"{template['itemName']},{template['readValues']},{template['testReuslt']}|"

        self.parent().hwTestInfo = self.parent().hwTestInfo[:-1]
        self.finished_signal.emit()  # 线程完成时发出信号
        self.stop()
        self.parent().hwTestPass = self.testResult  # 回传测试结果

    def stop(self):
        self.is_running = False # 或者使用更安全的停止逻辑

    # 正则表达式
    def extract_temperature(self, temp_string):
        match = re.search(r"(+?[d.]+)°?C", temp_string)
        if match:
            return float(match.group(1))
        else:
            raise ValueError("Invalid temperature string format: {}".format(temp_string))

    # 读取风扇转速 itemName:项目名称
    def ReadFanValues(self, itemName):
        try:
            fanvalues = 0
            redtep_h = Popen(["./Hw_UOS_Arm/getCpuFanFrq.sh"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
            # 获取子进程的输出
            stdout, stderr = redtep_h.communicate()
            # 将输出转换成字符串
            fanvalues = stdout.decode('utf-8').strip()  # 高点值
            if float(fanvalues)>float(self.cpufanArgs[0]) and float(fanvalues)<float(self.cpufanArgs[1]):
                self.r_FanVlaues.append({'itemName':itemName,'readValues':str(float(fanvalues))+'RPM','testResult':'PASS'})
            else:
                self.r_FanVlaues.append({'itemName': itemName, 'readValues': str(float(fanvalues)) + 'RPM', 'testResult': 'FAIL'})
            #self.r_FanVlaues.append({itemName: int(fanvalues)})
            return True
        except Exception as e:
            self.ShowLog(str(e), False)
            return False

    # 读取CPU温度 itemName:项目名称
    def ReadCpuTemplate(self,cputmp1,cputmp2):
        try:
            CpuTemplate_ts1 = 0
            CpuTemplate_ts2 = 0
            cputmp1IsPass=False
            cputmp2IsPass=False

            # 读取CPU_ts0温度
            redtep = Popen(['sensors | grep "ts0:" | head -n 1'], stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True)
            # 获取子进程的输出
            stdout, stderr = redtep.communicate()
            # 将输出转换成为字符串
            temp_str = stdout.decode("utf-8").strip()  # 获取的值
            print("Debug: Extracted CPU temperature string:", temp_str)
            CpuTemplate_ts1 = self.extract_temperature(temp_str)
            # CpuTemplate_ts1=tmp[tmp.find('+')+1:tmp.find('C')-1]

            # 添加调试信息
            if float(CpuTemplate_ts1)>float(self.cputmp1_Args[0]) and float(CpuTemplate_ts1)<float(self.cputmp1_Args[1]):
                self.r_TempValues.append({'itemName':cputmp1,'readValues':str(float(CpuTemplate_ts1))+' C','testResult':'PASS'})
                cputmp1IsPass = True
            else:
                self.r_TempValues.append({'itemName': cputmp1, 'readValues': str(float(CpuTemplate_ts1)) + ' C', 'testResult': 'FAIL'})
                cputmp1IsPass = False
            #self.r_TempValues.append({'CpuTemplate_ts0': CpuTemplate_ts1})

            # 读取CPU_ts1温度
            redtep = Popen(['sensors | grep "ts1:" | head -n 1'], stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True)
            # 获取子进程的输出
            stdout, stderr = redtep.communicate()
            # 将输出转换成为字符串
            temp_str = stdout.decode("utf-8").strip()  # 获取的值
            # CpuTemplate_ts2=tmp[tmp.find('+')+1:tmp.find('C')-1]
            CpuTemplate_ts2 = self.extract_temperature(temp_str)

            if float(CpuTemplate_ts2)>float(self.cputmp2_Args[0]) and float(CpuTemplate_ts2)<float(self.cputmp2_Args[1]):
                self.r_TempValues.append({'itemName': cputmp2, 'readValues': str(float(CpuTemplate_ts1)) + ' C', 'testResult': 'PASS'})
                cputmp2IsPass = True
            else:
                self.r_TempValues.append({'itemName': cputmp2, 'readValues': str(float(CpuTemplate_ts1)) + ' C', 'testResult': 'FAIL'})
                cputmp2IsPass = False
            #self.r_TempValues.append({'CpuTemplate_ts1': CpuTemplate_ts2})
            return cputmp1IsPass and cputmp2IsPass
        except ValueError as e:
            self.ShowLog(str(e), False)
            return False
        except Exception as e:
            self.ShowLog(str(e), False)
            return False

    # 日志信息
    def ShowLog(self, log, isPass):
        if isPass == True:
            print("33[1;32;43m" + str(log) + " 33[0m")
            self.logger.info(str(log))
        else:
            print("33[1;31m" + str(log) + " 33[0m")
            self.logger.error(str(log))
            self.err=str(log)

class Ui_Form(QWidget):
    updateTimer = pyqtSignal(bool)  # 时间线程启动器
    def __init__(self):
        super().__init__()
        self.config=configparser.ConfigParser()#创建对象
        self.itemName=''#项目名称
        self.testArgs=[]#测试参数信息
        self.testStandardArgs = ''  # 测试准标参数
        self.Err = ''  # 错误信息
        self.configRow=0#配置行数
        self.testDataRow=0#测试数据行数
        self.hwTestPass=False#测试结果
        self.hwTestInfo=''#hw测试信息
        self.cpu_architecture=''#CPU架構信息
        self.os_version=''#系統版本信息
        self.cfgArgs=[]#測試參數
        self.hw_uos_x86_Title = ['R_FAN_TAC1', 'R_TMPIN1', 'VIN_CPU', 'VIN_DIMM', 'VIN_12', 'VIN_5V', 'VIN_3_3V','VBAT']
        self.hw_uos_arm_Title = ['CPUFAN', 'CPUTMP1', 'CPUTMP2']

        # 生成日志信息
        self.logger = logging.getLogger('my_logger')  # 步骤1 创建日志记录器
        self.logger.setLevel(logging.DEBUG)  # 步骤2 将指定日志级别
        self.file_handler = logging.FileHandler('./log/log.txt')  # 步骤3 创建文件处理器
        self.formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')  # 步骤4 创建格式化器
        self.file_handler.setFormatter(self.formatter)  # 步骤4 将格式化器添加到处理器
        self.logger.addHandler(self.file_handler)  # 步骤5 将处理器添加到日志记录器

        # 读取配置
        self.config.read('./Conf/config.conf', encoding='utf-8')  # 读取配置文件,如果配置文件不存在则创建

        # 读取测试配置
        self.itemName = self.config.get('TestItemNameArrays', 'HwTest')  # 项目名称
        self.itemFailSleepExit = int(self.config.get('TestItemWinFrmSleepExit', 'HwTest'))  # 项目测试Fail延时退出
        self.testArgs = self.ReadJsonInfo('./Conf/TestArgs.json')  # 读取测试参数信息
        self.setupUi()

        self.lbl_CurrentSwTest.setText('配置信息读取中..')
        if self.ReadJsonTestArgs(self.itemName)==True:#讀取標準參數
            testArgs = []  # 测试参数
            testArgs = self.testStandardArgs.split('|')
            self.lbl_Set_SystemInfo_Args.setText(testArgs[0])
            self.lbl_Set_CpuInfo_Args.setText(testArgs[1])
        if self.get_os_version() and self.get_cpu_architecture():
            #print('osversion:',self.os_version.upper(),len(self.os_version))
            #print('cpuarchite:',self.cpu_architecture.upper(),len(self.cpu_architecture))
            #添加配置信息

            if self.os_version.upper()=='UOS' and self.cpu_architecture.upper()=='X86_64':
                hw_uos_x86_testconfig=[]
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'CPUFAN'))#CPU風扇值
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'CPUTMP')) #CPU溫度值
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_CPU')) #CPU電壓
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_DIMM')) #內存電壓
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_12')) #12V電壓
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_5V')) #5V電壓
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_3_3V')) #3.3V電壓
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'VBAT'))  #VBAT電壓
                #print(hw_uos_x86_testconfig)
                i=0
                self.testArgs.clear()#清空
                for hw in hw_uos_x86_testconfig:
                    #self.hw_uos_x86_Title
                    argsvalues=hw.split('~')
                    self.testArgs.append([self.hw_uos_x86_Title[i],argsvalues[0],argsvalues[1]])
                    i+=1
                self.TableAddCfgItem(self.testArgs)
            elif self.os_version.upper()=='UOS' and self.cpu_architecture.upper()!='X86_64':
                hw_uos_arm_testconfig=[]
                hw_uos_arm_testconfig.append(self.config.get('HW_ARM_TestConfig','CPUFAN'))#CPU風扇值
                hw_uos_arm_testconfig.append(self.config.get('HW_ARM_TestConfig','CPUTMP1'))#CPU1溫度
                hw_uos_arm_testconfig.append(self.config.get('HW_ARM_TestConfig', 'CPUTMP2'))#CPU2溫度
                i=0
                self.testArgs.clear()#清空
                for hw in hw_uos_arm_testconfig:
                    argsvalues=hw.split('~')
                    self.testArgs.append([self.hw_uos_arm_Title[i], argsvalues[0], argsvalues[1]])
                    i+=1
                self.TableAddCfgItem(self.testArgs)
            elif self.os_version.upper()!='UOS' and self.cpu_architecture.upper()=='X86_64':
                hw_uos_x86_testconfig = []
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'CPUFAN'))  # CPU風扇值
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'CPUTMP'))  # CPU溫度值
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_CPU'))  # CPU電壓
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_DIMM'))  # 內存電壓
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_12'))  # 12V電壓
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_5V'))  # 5V電壓
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'VIN_3_3V'))  # 3.3V電壓
                hw_uos_x86_testconfig.append(self.config.get('HW_UOS_X86_TestConfig', 'VBAT'))  # VBAT電壓
                # print(hw_uos_x86_testconfig)
                i = 0
                self.testArgs.clear()  # 清空
                for hw in hw_uos_x86_testconfig:
                    # self.hw_uos_x86_Title
                    argsvalues = hw.split('~')
                    self.testArgs.append([self.hw_uos_x86_Title[i], argsvalues[0], argsvalues[1]])
                    i += 1
                self.TableAddCfgItem(self.testArgs)
            elif self.os_version.upper()!= 'UOS' and self.cpu_architecture.upper()!= 'X86_64':
                hw_uos_arm_testconfig = []
                hw_uos_arm_testconfig.append(self.config.get('HW_ARM_TestConfig', 'CPUFAN'))  # CPU風扇值
                hw_uos_arm_testconfig.append(self.config.get('HW_ARM_TestConfig', 'CPUTMP1'))  # CPU1溫度
                hw_uos_arm_testconfig.append(self.config.get('HW_ARM_TestConfig', 'CPUTMP2'))  # CPU2溫度
                i = 0
                self.testArgs.clear()  # 清空
                for hw in hw_uos_arm_testconfig:
                    argsvalues = hw.split('~')
                    self.testArgs.append([self.hw_uos_arm_Title[i], argsvalues[0], argsvalues[1]])
                    i += 1
                self.TableAddCfgItem(self.testArgs)

            self.lbl_Get_SystemInfo.setText(self.os_version)#系統信息
            self.lbl_Get_CpuInfo.setText(self.cpu_architecture)#cpu框架信息

            #创建一个定时器来检查HW侦测是否PASS
            self.timer=QTimer(self)
            self.timer.setInterval(1000)#每秒检查一次
            self.timer.timeout.connect(self.check_Test)
            self.timer.start()

            # 连接信号到槽
            self.updateTimer.connect(self.handleTimer)

    # 校验是否完成测试
    def check_Test(self):
        if self.hwTestPass:
            self.UpdateJsonTestArgs(self.itemName,self.hwTestInfo,'PASS')#更新测试信息
            self.ShowLog('测试PASS',True)
            sys.exit(0)
        else:
            #self.updateTimer.emit(False)  # 重新启动定时器
            self.lbl_CurrentSwTest.setText('Hw信息侦测中..')
            self.start_analysis_threads()

    # 启动多线程
    def start_analysis_threads(self):
        # 创建多个线程
        self.finished_threads = 0  # 重置计数器
        self.analysis_threads = []  # 重置线程列表
        if self.cpu_architecture.upper()=='X86_64':
            thread=HW_UOS_X86(self)
            #thread.test_result_signal.connect(self.handle_test_result) #连接信号
            #thread.finished_signal.connect(self.thread_finished)
            thread.start()
        else:
            thread = HW_UOS_Arm(self)
            #thread.test_result_signal.connect(self.handle_test_result)  # 连接信号
            #thread.finished_signal.connect(self.thread_finished)
            thread.start()

    #獲取CPU架構信息
    def get_cpu_architecture(self):
        try:
            arch = subprocess.check_output(['lsb_release', '-a'], text=True).strip()

            def get_distributor_id(os_version_info):
                # 使用正则表达式从os_version_info中提取发行商ID
                match = re.search(r'Distributor ID:s*([^nr]*)', os_version_info)
                return match.group(1).strip() if match else "Unknown"

            self.os_version=get_distributor_id(arch)
            if self.os_version=="Unknown":
                return False
            #return arch
            return True
        except Exception as e:
            self.ShowLog(f"Error: {e}",False)
            return True
            #return f"Error: {e}"

    #獲取系統版本信息
    def get_os_version(self):
        try:
            # 尝试使用lsb_release命令
            os_version = subprocess.check_output(['uname', '-m'], text=True).strip()
            #return os_version
            self.cpu_architecture =os_version
            return True
        except subprocess.CalledProcessError:
            # 如果lsb_release不可用,则尝试读取/etc/os-release文件
            try:
                with open('/etc/os-release') as f:
                    #return f.read().strip()
                    self.cpu_architecture=f.read().strip()
                    return True
            except Exception as e:
                self.ShowLog(f"Error: {e}",False)
                return False
                #return f"Error: {e}"
    # 定义触发器
    def handleTimer(self, start):
        if start:
            self.timer.start()
        else:
            self.timer.stop()

    def setupUi(self):#绘制UI
        self.setObjectName("HwTest")
        self.resize(916, 837)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("IMAGE/风扇.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.setWindowIcon(icon)
        self.gridLayout = QtWidgets.QGridLayout(self)
        self.gridLayout.setObjectName("gridLayout")
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.lbl_Logo = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.lbl_Logo.setFont(font)
        self.lbl_Logo.setText("")
        self.lbl_Logo.setPixmap(QtGui.QPixmap("IMAGE/logo.jpg"))
        self.lbl_Logo.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_Logo.setObjectName("lbl_Logo")
        self.horizontalLayout_4.addWidget(self.lbl_Logo)
        self.label_2 = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_2.setFont(font)
        self.label_2.setStyleSheet("background-color: rgb(170, 170, 127);n"
"color: rgb(255, 255, 255);")
        self.label_2.setAlignment(QtCore.Qt.AlignCenter)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_4.addWidget(self.label_2)
        self.verticalLayout_2.addLayout(self.horizontalLayout_4)
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.lbl_CurrentSwTest = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.lbl_CurrentSwTest.setFont(font)
        self.lbl_CurrentSwTest.setStyleSheet("background-color: rgb(85, 255, 127);")
        self.lbl_CurrentSwTest.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_CurrentSwTest.setObjectName("lbl_CurrentSwTest")
        self.horizontalLayout_5.addWidget(self.lbl_CurrentSwTest)
        self.verticalLayout_2.addLayout(self.horizontalLayout_5)
        self.horizontalLayout_2.addLayout(self.verticalLayout_2)
        self.verticalLayout_3 = QtWidgets.QVBoxLayout()
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        self.label_6 = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_6.setFont(font)
        self.label_6.setStyleSheet("background-color: rgb(255, 170, 127);n"
"color: rgb(255, 255, 255);")
        self.label_6.setAlignment(QtCore.Qt.AlignCenter)
        self.label_6.setObjectName("label_6")
        self.horizontalLayout_6.addWidget(self.label_6)
        self.label_5 = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_5.setFont(font)
        self.label_5.setStyleSheet("background-color: rgb(255, 170, 127);n"
"color: rgb(255, 255, 255);")
        self.label_5.setAlignment(QtCore.Qt.AlignCenter)
        self.label_5.setObjectName("label_5")
        self.horizontalLayout_6.addWidget(self.label_5)
        self.label_4 = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_4.setFont(font)
        self.label_4.setStyleSheet("background-color: rgb(255, 170, 127);n"
"color: rgb(255, 255, 255);")
        self.label_4.setAlignment(QtCore.Qt.AlignCenter)
        self.label_4.setObjectName("label_4")
        self.horizontalLayout_6.addWidget(self.label_4)
        self.verticalLayout_3.addLayout(self.horizontalLayout_6)
        self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_7.setObjectName("horizontalLayout_7")
        self.label_9 = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_9.setFont(font)
        self.label_9.setAlignment(QtCore.Qt.AlignCenter)
        self.label_9.setObjectName("label_9")
        self.horizontalLayout_7.addWidget(self.label_9)
        self.lbl_Set_SystemInfo_Args = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.lbl_Set_SystemInfo_Args.setFont(font)
        self.lbl_Set_SystemInfo_Args.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_Set_SystemInfo_Args.setObjectName("lbl_Set_SystemInfo_Args")
        self.horizontalLayout_7.addWidget(self.lbl_Set_SystemInfo_Args)
        self.lbl_Set_CpuInfo_Args = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.lbl_Set_CpuInfo_Args.setFont(font)
        self.lbl_Set_CpuInfo_Args.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_Set_CpuInfo_Args.setObjectName("lbl_Set_CpuInfo_Args")
        self.horizontalLayout_7.addWidget(self.lbl_Set_CpuInfo_Args)
        self.verticalLayout_3.addLayout(self.horizontalLayout_7)
        self.horizontalLayout_8 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_8.setObjectName("horizontalLayout_8")
        self.label_12 = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_12.setFont(font)
        self.label_12.setAlignment(QtCore.Qt.AlignCenter)
        self.label_12.setObjectName("label_12")
        self.horizontalLayout_8.addWidget(self.label_12)
        self.lbl_Get_SystemInfo = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.lbl_Get_SystemInfo.setFont(font)
        self.lbl_Get_SystemInfo.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_Get_SystemInfo.setObjectName("lbl_Get_SystemInfo")
        self.horizontalLayout_8.addWidget(self.lbl_Get_SystemInfo)
        self.lbl_Get_CpuInfo = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.lbl_Get_CpuInfo.setFont(font)
        self.lbl_Get_CpuInfo.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_Get_CpuInfo.setObjectName("lbl_Get_CpuInfo")
        self.horizontalLayout_8.addWidget(self.lbl_Get_CpuInfo)
        self.verticalLayout_3.addLayout(self.horizontalLayout_8)
        self.horizontalLayout_2.addLayout(self.verticalLayout_3)
        self.verticalLayout.addLayout(self.horizontalLayout_2,1)
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.groupBox_2 = QtWidgets.QGroupBox(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.groupBox_2.setFont(font)
        self.groupBox_2.setStyleSheet("background-color: rgb(170, 170, 127);n"
"color: rgb(255, 170, 0);")
        self.groupBox_2.setAlignment(QtCore.Qt.AlignCenter)
        self.groupBox_2.setObjectName("groupBox_2")
        self.gridLayout_3 = QtWidgets.QGridLayout(self.groupBox_2)
        self.gridLayout_3.setObjectName("gridLayout_3")
        self.tableWidget = QtWidgets.QTableWidget(self.groupBox_2)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.tableWidget.setFont(font)
        self.tableWidget.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(3)
        self.tableWidget.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        self.gridLayout_3.addWidget(self.tableWidget, 0, 1, 1, 1)
        self.horizontalLayout.addWidget(self.groupBox_2)
        self.groupBox_3 = QtWidgets.QGroupBox(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.groupBox_3.setFont(font)
        self.groupBox_3.setStyleSheet("background-color: rgb(85, 255, 127);n"
"color: rgb(85, 170, 0);")
        self.groupBox_3.setAlignment(QtCore.Qt.AlignCenter)
        self.groupBox_3.setObjectName("groupBox_3")
        self.gridLayout_4 = QtWidgets.QGridLayout(self.groupBox_3)
        self.gridLayout_4.setObjectName("gridLayout_4")
        self.tableWidget_2 = QtWidgets.QTableWidget(self.groupBox_3)
        self.tableWidget_2.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.tableWidget_2.setObjectName("tableWidget_2")
        self.tableWidget_2.setColumnCount(3)
        self.tableWidget_2.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(2, item)
        self.gridLayout_4.addWidget(self.tableWidget_2, 0, 0, 1, 1)
        self.horizontalLayout.addWidget(self.groupBox_3)
        self.verticalLayout.addLayout(self.horizontalLayout,7)
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.groupBox = QtWidgets.QGroupBox(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.groupBox.setFont(font)
        self.groupBox.setStyleSheet("background-color: rgb(170, 170, 127);n"
"color: rgb(255, 255, 255);")
        self.groupBox.setObjectName("groupBox")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.lbl_TestLog = QtWidgets.QLabel(self.groupBox)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.lbl_TestLog.setFont(font)
        self.lbl_TestLog.setStyleSheet("background-color: rgb(0, 0, 0);n"
"color: rgb(255, 255, 127);")
        self.lbl_TestLog.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_TestLog.setObjectName("lbl_TestLog")
        self.gridLayout_2.addWidget(self.lbl_TestLog, 0, 0, 1, 1)
        self.horizontalLayout_3.addWidget(self.groupBox)
        self.verticalLayout.addLayout(self.horizontalLayout_3,2)
        self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)

        self.retranslateUi()
        QtCore.QMetaObject.connectSlotsByName(self)
        self.setWindowFlags(QtCore.Qt.WindowMinimizeButtonHint | QtCore.Qt.WindowCloseButtonHint)  # 只显示最小化按钮和关闭按钮

    def retranslateUi(self):
        _translate = QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate("Form", "HwTest"))
        self.label_2.setText(_translate("Form", "控制过程"))
        self.lbl_CurrentSwTest.setText(_translate("Form", "Wait..."))
        self.label_6.setText(_translate("Form", "环境信息"))
        self.label_5.setText(_translate("Form", "系统"))
        self.label_4.setText(_translate("Form", "CPU架构"))
        self.label_9.setText(_translate("Form", "配置参数"))
        self.lbl_Set_SystemInfo_Args.setText(_translate("Form", "N/A"))
        self.lbl_Set_CpuInfo_Args.setText(_translate("Form", "N/A"))
        self.label_12.setText(_translate("Form", "侦测参数"))
        self.lbl_Get_SystemInfo.setText(_translate("Form", "N/A"))
        self.lbl_Get_CpuInfo.setText(_translate("Form", "N/A"))
        self.groupBox_2.setTitle(_translate("Form", "【配置参数】"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("Form", "参数名称"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("Form", "参数【上限】"))
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText(_translate("Form", "参数【下限】"))

        self.tableWidget.setColumnWidth(0,140)
        self.tableWidget.setColumnWidth(1,140)
        self.tableWidget.setColumnWidth(2,140)
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)  # 表格状态只读
        self.tableWidget.clicked.connect(self.TestThread)  # 表单,单击事件

        self.groupBox_3.setTitle(_translate("Form", "【侦测结果】"))
        item = self.tableWidget_2.horizontalHeaderItem(0)
        item.setText(_translate("Form", "项目名称"))
        item = self.tableWidget_2.horizontalHeaderItem(1)
        item.setText(_translate("Form", "侦测值"))
        item = self.tableWidget_2.horizontalHeaderItem(2)
        item.setText(_translate("Form", "测试结果"))

        self.tableWidget_2.setColumnWidth(0, 140)
        self.tableWidget_2.setColumnWidth(1, 140)
        self.tableWidget_2.setColumnWidth(2, 140)
        self.tableWidget_2.setEditTriggers(QAbstractItemView.NoEditTriggers)  # 表格状态只读
        self.tableWidget_2.clicked.connect(self.TestThread)  # 表单,单击事件

        self.groupBox.setTitle(_translate("Form", "【日志】"))
        self.lbl_TestLog.setText(_translate("Form", "读取参数中..."))
        # 手动关闭窗口

    def TableAddItem(self, port, isPass):
        rowToUpdate = None
        for rowIndex in range(self.tableWidget_2.rowCount()):
            if self.tableWidget_2.item(rowIndex, 0):
                if self.tableWidget_2.item(rowIndex, 0).text() == port[0]:
                    rowToUpdate = rowIndex
                    break

        testResult = 'PASS' if isPass else 'FAIL'
        if rowToUpdate is not None:
            # 更新现有行
            self.tableWidget_2.item(rowToUpdate, 1).setText(port[1])
            self.tableWidget_2.item(rowToUpdate, 2).setText(testResult)
            if isPass:
                self.tableWidget_2.item(rowToUpdate, 2).setForeground(QtGui.QColor(51, 204, 51))
            else:
                self.tableWidget_2.item(rowToUpdate, 2).setForeground(QtGui.QColor(255, 51, 51))
        else:
            # 添加新行
            newRow = self.tableWidget_2.rowCount()
            self.tableWidget_2.insertRow(newRow)
            self.tableWidget_2.setRowCount(newRow + 1)

            self.tableWidget_2.setItem(newRow, 0, QTableWidgetItem(port[0]))
            self.tableWidget_2.setItem(newRow, 1, QTableWidgetItem(port[1]))
            self.tableWidget_2.setItem(newRow, 2, QTableWidgetItem(testResult))

            if isPass:
                self.tableWidget_2.item(newRow, 2).setForeground(QtGui.QColor(51, 204, 51))
            else:
                self.tableWidget_2.item(newRow, 2).setForeground(QtGui.QColor(255, 51, 51))

    # # TableAddItem 函数
    # def TableAddItem(self, port, isPass):
    #     # 检查数据是否已经在表格中
    #     rowToUpdate = None
    #     for rowIndex in range(self.tableWidget_2.rowCount()):
    #         if self.tableWidget_2.item(rowIndex, 0) and self.tableWidget_2.item(rowIndex, 2):
    #             if self.tableWidget_2.item(rowIndex, 0).text() == port[0] and self.tableWidget_2.item(rowIndex,2).text() == 'FAIL':
    #                 rowToUpdate = rowIndex
    #                 break
    #
    #     if rowToUpdate is not None:
    #         # 更新现有行
    #         testResult = 'PASS' if isPass else 'FAIL'
    #         # 确保单元格项存在
    #         if not self.tableWidget_2.item(rowToUpdate, 2):
    #             self.tableWidget_2.setItem(rowToUpdate, 2, QTableWidgetItem())
    #         self.tableWidget_2.item(rowToUpdate, 2).setText(testResult)
    #         if isPass:
    #             self.tableWidget_2.item(rowToUpdate, 2).setForeground(QtGui.QColor(51, 204, 51))
    #         else:
    #             self.tableWidget_2.item(rowToUpdate, 2).setForeground(QtGui.QColor(255, 51, 51))
    #     else:
    #         # 添加新行
    #         newRow = self.tableWidget_2.rowCount()
    #         self.tableWidget_2.insertRow(newRow)
    #         self.tableWidget_2.setRowCount(newRow + 1)
    #
    #         # 添加新行数据
    #         self.tableWidget_2.setItem(newRow, 0, QTableWidgetItem(port[0]))
    #         self.tableWidget_2.setItem(newRow, 1, QTableWidgetItem(port[1]))
    #         self.tableWidget_2.setItem(newRow, 2, QTableWidgetItem(port[2]))
    #
    #         if isPass:
    #             self.tableWidget_2.item(newRow, 2).setForeground(QtGui.QColor(51, 204, 51))
    #         else:
    #             self.tableWidget_2.item(newRow, 2).setForeground(QtGui.QColor(255, 51, 51))

    #添加配置信息
    def TableAddCfgItem(self,cfgArray):
        try:
            for cfg in cfgArray:
                newRow=self.tableWidget.rowCount()
                self.tableWidget.insertRow(newRow)
                self.tableWidget.setRowCount(newRow+1)#增加表格行数
                #添加数据到新行
                self.tableWidget.setItem(newRow,0,QTableWidgetItem(cfg[0]))#参数名称
                self.tableWidget.setItem(newRow,1,QTableWidgetItem(cfg[1]))#参数值上限
                self.tableWidget.setItem(newRow,2,QTableWidgetItem(cfg[2]))#参数值下限
        except Exception as e:
            self.ShowLog(f"Table Add CfgItem Info Err:{str(e)}", False)
            sys.exit(1)

    # 启动线重脚本
    def TestThread(self):
        pass
        # self.t_autoplay=Thread(target=self.Test)
        # self.t_autoplay.start()

    # 手动关闭窗口
    def closeEvent(self, event):
        # 告知线程停止运行
        sys.exit(1)

    # 定义一个函数使得函数窗口居中显示
    def Center(self):
        # 获取屏幕尺寸
        screen_geometry = app.desktop().availableGeometry()
        # 计算窗口居中位置
        x = (screen_geometry.width() - self.width()) // 2
        y = (screen_geometry.height() - self.height()) // 2
        # 设置窗口位置
        self.move(x, y)

    # 读取项目参数信息,itemName:项目名称
    def ReadJsonTestArgs(self, itemName):
        try:
            self.testArgs = self.ReadJsonInfo('./Conf/TestArgs.json')
            for js in self.testArgs:
                if itemName in js['ItemName']:
                    self.testStandardArgs = js['Standard']
                    return True
            self.ShowLog('Read TestArgs.json ItemName:' + itemName + ' Info Is Empty!!', False)
            sys.exit(1)
        except Exception as e:
            self.ShowLog("Read TestArgs.json ItemName:" + itemName + " Info Err:" + str(e), False)
            sys.exit(1)

    # 读取json信息
    def ReadJsonInfo(self, fileName):
        try:
            if os.path.exists(fileName):
                f = open(fileName, 'r', encoding='utf-8')
            return json.loads(f.read())
        except Exception as e:
            self.ShowLog("Read " + fileName + " Err:" + str(e), False)
            sys.exit(1)

    # 更新测试参数json,itemName:项目名称,readValue:读取值,testResult:测试结果
    def UpdateJsonTestArgs(self, itemName, readValue, testResult):
        try:
            updateTestArgs = []  # 更新的测试参数
            self.testArgs = self.ReadJsonInfo('./Conf/TestArgs.json')
            for js in self.testArgs:
                if itemName in js['ItemName']:
                    js['Read'] = readValue  # 读取的值
                    js['TestResult'] = testResult  # 测试结果
                    updateTestArgs.append(js)
                else:
                    updateTestArgs.append(js)
            with open("./Conf/TestArgs.json", "w") as write_file:
                json.dump(updateTestArgs, write_file)
            return True
        except Exception as e:
            self.ShowLog("Read TestArgs.json ItemName:" + itemName + " Info Err:" + str(e), False)
            sys.exit(1)

    # 打印的信息
    def ShowLog(self, log, isPass):
        try:
            if isPass == True:
                self.lbl_TestLog.setStyleSheet("background-color: rgb(85, 255, 127);color:green;")
                self.logger.info(str(log))
                self.lbl_TestLog.setText("TEST PASS")
            else:
                self.lbl_TestLog.setStyleSheet("background-color: rgb(85, 255, 127);color: red;")
                self.logger.error(str(log))
                self.lbl_TestLog.setText(log)
        except Exception as e:
            print("33[1;31m" + str(e) + " 33[0m")
            sys.exit(1)

if __name__=='__main__':
    app=QApplication(sys.argv)
    win=Ui_Form()
    win.Center()  # 居中
    win.show()
    #win.start_realtime_audio_processing()  # 启动实时音频处理
    sys.exit(app.exec_())

原文地址:https://blog.csdn.net/u013934107/article/details/135898482

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_64775.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注