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] address\n\outb|outw|outl [--options] address data\n\
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_long\n");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 page\n",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 page\n",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_RAWIO\ncapability. 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 ("%d\n", data);elseprintf ("%x\n", data);} elseexit (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 string\n");exit (1);}if (*endp != '\0') {fprintf (stderr, "%s: trailing garbage after number\n", 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 coloramaclass 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=Truedef 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_CPUself.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=Trueelse:self.testResult=Falseself.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=Trueelse:self.testResult=Falseself.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=Trueelse:self.testResult=Falseself.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 modeos.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+1elif itemName=='VIN_5V':#5V电压vinvalue=float((int(vin)/2)*5)/100+0.4elif itemName=='VIN_3_3V':#3.3V电压vinvalue=float((int(vin)/20)*33)/100+0.3else:vinvalue=(float(vin)*10.9)/1000result=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 Trueelse: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 modeos.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 Trueelse: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 modeos.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 Trueelse: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("\033[1;32;43m" + str(log) + " \033[0m")self.logger.info(str(log))else:print("\033[1;31m" + str(log) + " \033[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=Truedef 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=Trueelse:self.testResult=Falseself.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 = Trueelse:self.testResult = Falseself.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 = 0redtep_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 Trueexcept Exception as e:self.ShowLog(str(e), False)return False# 读取CPU温度 itemName:项目名称def ReadCpuTemplate(self,cputmp1,cputmp2):try:CpuTemplate_ts1 = 0CpuTemplate_ts2 = 0cputmp1IsPass=Falsecputmp2IsPass=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 = Trueelse: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 = Trueelse: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 cputmp2IsPassexcept ValueError as e:self.ShowLog(str(e), False)return Falseexcept Exception as e:self.ShowLog(str(e), False)return False# 日志信息def ShowLog(self, log, isPass):if isPass == True:print("\033[1;32;43m" + str(log) + " \033[0m")self.logger.info(str(log))else:print("\033[1;31m" + str(log) + " \033[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=0self.testArgs.clear()#清空for hw in hw_uos_x86_testconfig:#self.hw_uos_x86_Titleargsvalues=hw.split('~')self.testArgs.append([self.hw_uos_x86_Title[i],argsvalues[0],argsvalues[1]])i+=1self.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=0self.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+=1self.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 = 0self.testArgs.clear()  # 清空for hw in hw_uos_x86_testconfig:# self.hw_uos_x86_Titleargsvalues = hw.split('~')self.testArgs.append([self.hw_uos_x86_Title[i], argsvalues[0], argsvalues[1]])i += 1self.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 = 0self.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 += 1self.TableAddCfgItem(self.testArgs)self.lbl_Get_SystemInfo.setText(self.os_version)#系統信息self.lbl_Get_CpuInfo.setText(self.cpu_architecture)#cpu框架信息#创建一个定时器来检查HW侦测是否PASSself.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中提取发行商IDmatch = re.search(r'Distributor ID:\s*([^\n\r]*)', 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 archreturn Trueexcept 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_versionself.cpu_architecture =os_versionreturn Trueexcept 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 Trueexcept 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):#绘制UIself.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.translateself.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 = Nonefor 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 = rowIndexbreaktestResult = '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()) // 2y = (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 Trueself.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 Trueexcept 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("\033[1;31m" + str(e) + " \033[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_())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/447934.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kingbase控制文件重建

背景&#xff1a; 测试版本&#xff1a;V008R006C005B0023 sys_control文件在数据目录的global下 若sys_control文件损坏或被删&#xff0c;会导致库无法启动 处理方式&#xff1a; 所在目录为数据目录 1、尝试dryrun touch global/sys_control sys_resetwal -l 00000001…

用Audio2Face导出Unity面部动画

开始之前说句话&#xff0c;新年前最后一篇文章了 一定别轻易保存任何内容&#xff0c;尤其是程序员不要轻易Ctrl S 在A2F去往Unity的路上&#xff0c;还要经历特殊Blender&#xff0c;自己电脑中已下载好的可能不是很好使。 如果想查看UE相关的可以跳转到下边这两篇链接 1. …

2024年第九届信号与图像处理国际会议(ICSIP 2024)

2024第九届信号与图像处理国际会议&#xff08;ICSIP 2024&#xff09;将于2024年7月12-14日在中国南京召开。ICSIP每年召开一次&#xff0c;在过去的七年中吸引了1200多名与会者&#xff0c;是展示信号和图像处理领域最新进展的领先国际会议之一。本次将汇集来自亚太国家、北美…

#10外部网页跳转vue3+SpringMVC解码GBK编码的参数

目录 1、背景 2、失败尝试之iconv-lite 2.1、安装和使用 2.2、遇到的问题 2.3、解决方案(vite-plugin-node-polyfills) 2.4、测试 3、成功尝试 3.1、前端参数读取方式 3.2、后端解码 1、背景 外部jsp页面中编码方式为GBK&#xff0c;跳转到vue页面时如果使用decodeURI…

C#,入门教程(33)——万能的数据接送者json

上一篇&#xff1a; C#&#xff0c;入门教程(32)——程序运行时的调试技巧与逻辑错误探针技术与源代码https://blog.csdn.net/beijinghorn/article/details/126014885 作为21世纪的编程者&#xff0c;无论你是前端还是后端&#xff0c;都逃不过“json”。 一、什么是 json&…

中耳分析时,鼓室图有哪几种分型?

做中耳分析时&#xff0c;鼓室图有哪几种分型&#xff1f; 目前&#xff0c;临床上最常用的鼓室图分型法是由Jerger提出的&#xff0c;主要分为A型、As型、Ad型、B型和C型五种类型。 A型 正常成人的鼓室图峰补偿静态声导纳值为0.3&#xff5e;1.6 mmho&#xff08;Silman等报…

【Linux】环境基础开发工具的使用之gcc详解(二)

前言&#xff1a;上一篇文章中我们讲解了Linux下的vim和yum的工具的使用&#xff0c;今天我们将在上一次的基础上进一步的讲解开放工具的时候。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:Linux的深度刨析 &#x1f448; &#x1f4a…

Jmeter学习系列之五:基础线程组(Thread Group)

前言 线程组是一系列线程的集合,每一个线程代表着一个正在使用应用程序的用户。在 jmeter 中,每个线程意味着模拟一个真实用户向服务器发起请求。 在 jmeter 中,线程组组件运行用户设置线程数量、初始化方式等等配置。 例如,如果你设置线程数为 100,那么 jmeter 将创建…

【python接口自动化】- PyMySQL数据连接

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

1E,Jarvis March

四个问题&#xff1a; 一&#xff0c;Jarvis March算法借鉴了什么算法&#xff1f; 二&#xff0c;如何确定初始点 三&#xff0c;如何获取凸包的边&#xff1f; 四&#xff0c;Jarvis March算法的好处在哪里&#xff1f; 首先看第一个问题&#xff0c; 一&#xff0c;Jarvis …

vue2 el-form 两个时间框(第一个时间框是只能选择当前时间,之前的是不允许选择,第二个时间框是第一个时间的当前的时间后30天后可以选择的)

<template><div id"app"><el-form :model"form"><el-form-item label"预签时间"><el-date-picker v-model"form.t2" type"date" placeholder"选择预签时间" changepreSigning/><…

从第一性原理看大模型Agent技术

引 一个乐观主义者的悲观估计 随着大规模模型技术的兴起&#xff0c;我们正处于一个崭新的智能时代的黎明。我们有一个大胆的预测&#xff0c;未来的5到10年将可能带来一场大变局&#xff1a;99%的开发、设计和文字工作将被AI接管。这不仅仅是一个想象&#xff0c;而是对未来可…