Update for v1.0.9

This commit is contained in:
James Deng 2024-07-20 11:42:38 +08:00
parent a2c1d15e40
commit 66bb1f6cd6
7 changed files with 644 additions and 53 deletions

View file

@ -8,6 +8,7 @@
"ddr_size": "DDR容量",
"emmc_size": "eMMC容量",
"ssd_size": "SSD容量",
"hdmi_model": "HDMI型号",
"run_all_button": "运行",
"run_selected_button": "运行选择",
"stop_button": "停止",
@ -26,7 +27,17 @@
"playback_button": "回放",
"speed_button": "速度",
"pass_button": "通过",
"fail_button": "失败"
"fail_button": "失败",
"lcd": "LCD屏",
"lcd_backlight": "LCD背光",
"aging_test": "老化测试",
"aging_duration": "老化时长(小时)",
"aging_cancel": "取消",
"wifi": "WiFi",
"wifi_mac": "WiFi Mac",
"cpu_temp": "CPU温度"
},
"en": {
"title": "Factory Test",
@ -37,6 +48,7 @@
"ddr_size": "DDR size",
"emmc_size": "eMMC size",
"ssd_size": "SSD size",
"hdmi_model": "HDMI model",
"run_all_button": "Run",
"run_selected_button": "Run Selected",
"stop_button": "Stop",
@ -55,6 +67,16 @@
"playback_button": "Playback",
"speed_button": "Speed",
"pass_button": "Pass",
"fail_button": "Fail"
"fail_button": "Fail",
"lcd": "LCD Screen",
"lcd_backlight": "LCD backlight",
"aging_test": "Aging test",
"aging_duration": "Aging duration (hours)",
"aging_cancel": "Cancel",
"wifi": "WiFi",
"wifi_mac": "WiFi Mac",
"cpu_temp": "CPU_Temp"
}
}

View file

@ -4,7 +4,7 @@ This is the "View" of the MVC world.
"""
from PyQt5.QtCore import Qt, QTimer, QUrl
from PyQt5.QtGui import QColor, QPixmap, QImage
from PyQt5.QtGui import QColor, QPixmap, QImage, QPalette
from PyQt5.QtWidgets import (
QMainWindow,
QFrame,
@ -12,13 +12,18 @@ from PyQt5.QtWidgets import (
QVBoxLayout,
QGridLayout,
QLabel,
QCheckBox,
QComboBox,
QProgressBar,
QProgressDialog,
QPushButton,
QGroupBox,
QTableWidget,
QAbstractItemView,
QStatusBar,
QTableWidgetItem,
QHeaderView
QHeaderView,
QSlider
)
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
from PyQt5.QtMultimediaWidgets import QVideoWidget
@ -36,6 +41,8 @@ from cricket.model import TestMethod, TestCase, TestModule
from cricket.executor import Executor
from cricket.lang import SimpleLang
PASS_COLOR = '#28C025'
FAIL_COLOR = '#E32C2E'
# Display constants for test status
STATUS = {
@ -94,6 +101,12 @@ class MainWindow(QMainWindow, SimpleLang):
self.test_list = {}
self.run_status = {}
self.executor = {}
self.usb_list = []
self.set_brightness()
self.wifi_mac_Ok = False
self.root = root
self.setWindowTitle(self.get_text('title'))
@ -114,7 +127,7 @@ class MainWindow(QMainWindow, SimpleLang):
######################################################
# Internal GUI layout methods.
######################################################
def _setup_main_content(self):
'''
The button toolbar runs as a horizontal area at the top of the GUI.
@ -127,31 +140,7 @@ class MainWindow(QMainWindow, SimpleLang):
self.content_layout = QVBoxLayout(self.content)
# Information
info = QFrame(self.content)
info_layout = QGridLayout(info)
cpu_model = QLabel(f'{self.get_text("cpu_model")}: {self._get_CPU_model()}', info)
info_layout.addWidget(cpu_model, 0, 0)
cpu_freq = QLabel(f'{self.get_text("cpu_freq")}: {self._get_CPU_freq()} GHz', info)
info_layout.addWidget(cpu_freq, 0, 1)
ddr_size = QLabel(f'{self.get_text("ddr_size")}: {self._get_DDR_size()} GB', info)
info_layout.addWidget(ddr_size, 0, 2)
emmc_size = QLabel(f'{self.get_text("emmc_size")}: {self._get_eMMC_size()} GB', info)
info_layout.addWidget(emmc_size, 0, 3)
ssd_size = QLabel(f'{self.get_text("ssd_size")}: {self._get_SSD_size()} GB', info)
info_layout.addWidget(ssd_size, 0, 4)
product_name = QLabel(f'{self.get_text("product_name")}: {self._get_product_name()}', info)
info_layout.addWidget(product_name, 0, 5)
fw_version = QLabel(f'{self.get_text("fw_version")}: {self._get_fw_version()}', info)
info_layout.addWidget(fw_version, 0, 6)
self.content_layout.addWidget(info)
self._setup_info()
# toolbar
toolbar = QFrame(self.content)
@ -195,8 +184,9 @@ class MainWindow(QMainWindow, SimpleLang):
self.tests = QFrame(self.content)
self.tests_layout = QGridLayout(self.tests)
self._setup_test_table('auto', 0, 0, 4, 1)
self._setup_test_table('manual', 4, 0, 3, 1)
self._setup_test_table('auto', 0, 0, 5, 1)
self._setup_usb_frame(5, 0, 1, 1)
self._setup_test_table('manual', 6, 0, 4, 1)
camera_box = QGroupBox(self.get_text('camera'), self.tests)
camera_box_layout = QVBoxLayout(camera_box)
@ -206,29 +196,22 @@ class MainWindow(QMainWindow, SimpleLang):
camera_box_layout.addWidget(video_widget)
# others
self.others_box = QGroupBox(self.get_text('others'), self.tests)
others_box_layout = QVBoxLayout(self.others_box)
self._setup_others()
# item
self.others_item = QFrame(self.others_box)
self.others_item_layout = QHBoxLayout(self.others_item)
others_box_layout.addWidget(self.others_item)
self.tests_layout.addWidget(camera_box, 0, 1, 6, 1)
self.tests_layout.addWidget(self.others_box, 6, 1, 4, 1)
sn = self._get_sn()
if sn:
self._setup_sn_qrcode(sn)
self.tests_layout.setRowStretch(0, 6)
self.tests_layout.setRowStretch(1, 6)
self.tests_layout.setRowStretch(2, 6)
self.tests_layout.setRowStretch(3, 6)
self.tests_layout.setRowStretch(4, 6)
self.tests_layout.setRowStretch(5, 6)
self.tests_layout.addWidget(camera_box, 0, 1, 4, 1)
self.tests_layout.addWidget(self.others_box, 4, 1, 3, 1)
self.tests_layout.setRowStretch(0, 4)
self.tests_layout.setRowStretch(1, 4)
self.tests_layout.setRowStretch(2, 4)
self.tests_layout.setRowStretch(3, 4)
self.tests_layout.setRowStretch(4, 3)
self.tests_layout.setRowStretch(5, 3)
self.tests_layout.setRowStretch(6, 3)
self.tests_layout.setRowStretch(6, 4)
self.tests_layout.setRowStretch(7, 4)
self.tests_layout.setRowStretch(8, 4)
self.tests_layout.setRowStretch(9, 4)
self.tests_layout.setColumnStretch(0, 1)
self.tests_layout.setColumnStretch(1, 1)
@ -237,6 +220,42 @@ class MainWindow(QMainWindow, SimpleLang):
# set main content to window
self.setCentralWidget(self.content)
def _setup_info(self):
info = QFrame(self.content)
info_layout = QGridLayout(info)
cpu_model = QLabel(f'{self.get_text("cpu_model")}: {self._get_CPU_model()}', info)
info_layout.addWidget(cpu_model, 0, 0)
cpu_freq = QLabel(f'{self.get_text("cpu_freq")}: {self._get_CPU_freq()} GHz', info)
info_layout.addWidget(cpu_freq, 0, 1)
self.cpu_temp = QLabel(f'{self.get_text("cpu_temp")}: {self._get_CPU_Temp()} °C', info)
self._cpu_temp_timer = QTimer(self)
self._cpu_temp_timer.timeout.connect(self.on_cpuTempUpdate)
self._cpu_temp_timer.start(1000)
info_layout.addWidget(self.cpu_temp, 0, 2)
ddr_size = QLabel(f'{self.get_text("ddr_size")}: {self._get_DDR_size()} GB', info)
info_layout.addWidget(ddr_size, 0, 3)
emmc_size = QLabel(f'{self.get_text("emmc_size")}: {self._get_eMMC_size()} GB', info)
info_layout.addWidget(emmc_size, 0, 4)
ssd_size = QLabel(f'{self.get_text("ssd_size")}: {self._get_SSD_size()} GB', info)
info_layout.addWidget(ssd_size, 0, 5)
self.hdmi_model = QLabel(f'{self.get_text("hdmi_model")}: None', info)
info_layout.addWidget(self.hdmi_model, 0, 6)
product_name = QLabel(f'{self.get_text("product_name")}: {self._get_product_name()}', info)
info_layout.addWidget(product_name, 0, 7)
fw_version = QLabel(f'{self.get_text("fw_version")}: {self._get_fw_version()}', info)
info_layout.addWidget(fw_version, 0, 8)
self.content_layout.addWidget(info)
def _setup_test_table(self, name, row, column, row_span, column_span):
module = import_module(name)
@ -267,6 +286,185 @@ class MainWindow(QMainWindow, SimpleLang):
self.tests_layout.addWidget(box, row, column, row_span, column_span)
def _setup_others(self):
self.others_box = QGroupBox(self.get_text('others'), self.tests)
self.others_box_layout = QVBoxLayout(self.others_box)
# Comment the code below if you don't need it
# item
self._setup_others_item()
# status
self._setup_others_status()
def _setup_others_item(self):
self.others_item = QFrame(self.others_box)
self.others_item_layout = QHBoxLayout(self.others_item)
self.others_box_layout.addWidget(self.others_item)
self._setup_others_test()
self._setup_wifi_mac()
sn = self._get_sn()
if sn:
self._setup_sn_qrcode(sn)
def _setup_others_test(self):
others_test = QFrame(self.others_item)
others_test_layout = QVBoxLayout(others_test)
# lcd
lcd_frame = QFrame(others_test)
lcd_frame.setAutoFillBackground(True)
lcd_frame.setPalette(QPalette(QColor('darkgray')))
lcd_layout = QHBoxLayout(lcd_frame)
# lcd_button = QPushButton(self.get_text('lcd'), lcd_frame)
# lcd_button.clicked.connect(self.cmd_lcd)
# lcd_layout.addWidget(lcd_button)
# lcd backlight
backlight_label = QLabel(self.get_text('lcd_backlight')+" :", lcd_frame)
backlight_label.setAlignment( Qt.AlignVCenter)
lcd_layout.addWidget(backlight_label)
# Create a slider
lcd_slider = QSlider(Qt.Horizontal, lcd_frame)
lcd_slider.setRange(0, 255)
lcd_slider.setValue(128)
lcd_slider.valueChanged.connect(self.set_brightness)
lcd_layout.addWidget(lcd_slider)
label_brightness = QLabel("128", lcd_frame)
label_brightness.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
label_brightness.setFixedWidth(24)
lcd_slider.valueChanged.connect(lambda value: label_brightness.setText(str(value)))
lcd_layout.addWidget(label_brightness)
others_test_layout.addWidget(lcd_frame)
# aging test
aging_test = QFrame(others_test)
aging_test.setAutoFillBackground(True)
aging_test.setPalette(QPalette(QColor('darkgray')))
aging_test_layout = QVBoxLayout(aging_test)
self.aging_button = QPushButton(self.get_text('aging_test'), aging_test)
self.aging_button.setAutoFillBackground(True)
self.aging_button.clicked.connect(self.cmd_aging)
aging_test_layout.addWidget(self.aging_button)
aging_item = QFrame(aging_test)
aging_item_layout = QHBoxLayout(aging_item)
self.cpu_aging = QCheckBox('CPU', aging_item)
self.cpu_aging.setChecked(True)
aging_item_layout.addWidget(self.cpu_aging)
self.ddr_aging = QCheckBox('DDR', aging_item)
self.ddr_aging.setChecked(True)
aging_item_layout.addWidget(self.ddr_aging)
self.gpu_aging = QCheckBox('GPU', aging_item)
self.gpu_aging.setChecked(True)
aging_item_layout.addWidget(self.gpu_aging)
self.vpu_aging = QCheckBox('VPU', aging_item)
self.vpu_aging.setChecked(True)
aging_item_layout.addWidget(self.vpu_aging)
aging_test_layout.addWidget(aging_item)
aging_duration = QFrame(aging_test)
aging_duration_layout = QHBoxLayout(aging_duration)
aging_duration_label = QLabel(f'{self.get_text("aging_duration")}: ', aging_duration)
aging_duration_layout.addWidget(aging_duration_label)
self.aging_duration_choice = QComboBox(aging_test)
self.aging_duration_choice.addItems(['4', '8', '12', '24'])
self.aging_duration_choice.setCurrentText('8')
aging_duration_layout.addWidget(self.aging_duration_choice)
aging_test_layout.addWidget(aging_duration)
others_test_layout.addWidget(aging_test)
self.others_item_layout.addWidget(others_test)
def _setup_wifi_mac(self):
mac = self._get_wifi_mac()
if mac:
self._setup_wifi_mac_qrcode(mac)
else:
QTimer.singleShot(2000, self._setup_wifi_mac)
# wifi signal part
def _setup_others_status(self):
self.others_status = QFrame(self.others_box)
self.others_status_layout = QHBoxLayout(self.others_status)
self.others_box_layout.addWidget(self.others_status)
self._setup_wifi_view()
def _setup_wifi_view(self):
wifi = QFrame(self.others_status)
wifi_layout = QGridLayout(wifi)
self.others_status_layout.addWidget(wifi)
wifi_label = QLabel(f'{self.get_text("wifi")}: ', wifi)
wifi_label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
wifi_layout.addWidget(wifi_label, 0, 0)
self.wifi_signal_level = QProgressBar(wifi)
self.wifi_signal_level.setAlignment(Qt.AlignLeft)
self.wifi_signal_level.setMaximum(5)
wifi_layout.addWidget(self.wifi_signal_level, 0, 1)
QTimer.singleShot(3000, lambda: self.on_wifiStatusUpdate())
# [start] Check the usb to see if the device is inserted
def usb_loop(self, label, usb_path):
while True:
if os.path.exists(usb_path):
label.setPalette(QPalette(QColor(PASS_COLOR)))
else:
label.setPalette(QPalette(QColor(255, 255,255)))
time.sleep(1)
def _add_usb_test(self, text: str, row: int, column: int, path: str):
label = QLabel(text, self.usb_frame)
label.setAutoFillBackground(True)
label.setPalette(QPalette(QColor('white')))
label.setAlignment(Qt.AlignCenter)
self.usb_frame_layout.addWidget(label, row, column)
self.usb_list.append(label)
thread = threading.Thread(target=self.usb_loop, args=(label, path))
thread.start()
def _setup_usb_frame(self, row, column, row_span, column_span):
self.usb_frame = QFrame(self.tests)
self.usb_frame_layout = QGridLayout(self.usb_frame)
self._add_usb_test('USB A口 (左上) 2.0', 0, 0,
'/sys/bus/usb/devices/usb2/2-1/2-1.1/product')
self._add_usb_test('USB A口 (左上) 3.0', 1, 0,
'/sys/bus/usb/devices/usb3/3-1/3-1.1/product')
self._add_usb_test('USB A口 (左下) 2.0', 0, 1,
'/sys/bus/usb/devices/usb2/2-1/2-1.4/product')
self._add_usb_test('USB A口 (左下) 3.0', 1, 1,
'/sys/bus/usb/devices/usb3/3-1/3-1.4/product')
self._add_usb_test('USB A口 (右上) 2.0', 0, 2,
'/sys/bus/usb/devices/usb2/2-1/2-1.3/product')
self._add_usb_test('USB A口 (右上) 3.0', 1, 2,
'/sys/bus/usb/devices/usb3/3-1/3-1.3/product')
self._add_usb_test('USB A口 (右下) 2.0', 0, 3,
'/sys/bus/usb/devices/usb2/2-1/2-1.2/product')
self._add_usb_test('USB A口 (右下) 3.0', 1, 3,
'/sys/bus/usb/devices/usb3/3-1/3-1.2/product')
self.tests_layout.addWidget(self.usb_frame, row, column, row_span, column_span)
# [end] Check the usb to see if the device is inserted
def _create_qrcode(self, data):
qr = qrcode.QRCode(
version=1,
@ -291,11 +489,25 @@ class MainWindow(QMainWindow, SimpleLang):
sn_qrcode_layout.addWidget(qr_label)
sn_label = QLabel(f'{self.get_text("sn")}: {sn}', sn_qrcode)
sn_label.setAlignment(Qt.AlignTop | Qt.AlignHCenter)
sn_qrcode_layout.addWidget(sn_label)
self.others_item_layout.addWidget(sn_qrcode)
def _setup_wifi_mac_qrcode(self, mac):
mac_qrcode = QFrame(self.others_item)
mac_qrcode_layout = QVBoxLayout(mac_qrcode)
qr_label = QLabel(mac_qrcode)
qr_label.setAlignment(Qt.AlignCenter)
qr_label.setPixmap(self._create_qrcode(mac))
mac_qrcode_layout.addWidget(qr_label)
mac_label = QLabel(f'{self.get_text("wifi_mac")}: {mac}', mac_qrcode)
mac_label.setAlignment(Qt.AlignTop | Qt.AlignHCenter)
mac_qrcode_layout.addWidget(mac_label)
self.others_item_layout.addWidget(mac_qrcode)
######################################################
# Handlers for setting a new project
######################################################
@ -368,6 +580,9 @@ class MainWindow(QMainWindow, SimpleLang):
pipeline = 'gst-pipeline: spacemitsrc location=/opt/factorytest/res/camtest_sensor0_mode0.json close-dmabuf=1 ! videoconvert ! video/x-raw,format=BGRx ! autovideosink sync=0'
self.media_player.setMedia(QMediaContent(QUrl(pipeline)))
self.media_player.play()
self.hdmi_thread = threading.Thread(target=self.hdmi_loop)
self.hdmi_thread.start()
self.audio_thread = threading.Thread(target=lambda: self.audio_loop())
self.audio_thread.start()
@ -375,6 +590,28 @@ class MainWindow(QMainWindow, SimpleLang):
self.cmd_run_all()
self.root.exec_()
def hdmi_loop(self):
card = '/sys/class/drm/card2-HDMI-A-1'
if os.path.exists(card):
while True:
with open(f'{card}/status', 'r') as f:
status = f.readline().strip()
if status == 'connected':
break
time.sleep(1)
cmd = f'cat {card}/edid | edid-decode'
edid_proc = subprocess.run(cmd, shell=True, capture_output=True, text=True)
for line in edid_proc.stdout.splitlines():
if line.strip().startswith('Manufacturer'):
manufacturer = line.strip().split(':')[1].strip()
if line.strip().startswith('Model'):
model = line.strip().split(':')[1].strip()
self.hdmi_model.setText(f'{self.get_text("hdmi_model")}: {manufacturer} {model}')
def _play_wav(self, device, volume, path):
cmd = f'amixer -c 1 cset numid=1,iface=MIXER,name="DAC Playback Volume" {volume}'
@ -419,10 +656,35 @@ class MainWindow(QMainWindow, SimpleLang):
self._play_wav(device, playback_volume, stop_play_file)
time.sleep(duration)
# lcd part
# def update_lcd_color(self):
# color = self.lcd_color_list[self.lcd_color_index % len(self.lcd_color_list)]
# self.lcd_color_index += 1
# self.setPalette(QPalette(QColor(color)))
def set_brightness(self, brightness = 128):
path = '/sys/devices/platform/soc/soc:lcd_backlight/backlight/soc:lcd_backlight/brightness'
try:
with open(path, 'w') as f:
f.write(f'{brightness}')
except:
pass
# def keyPressEvent(self, event):
# super().keyPressEvent(event)
# def mousePressEvent(self, event):
# super().mousePressEvent(event)
######################################################
# User commands
######################################################
# def cmd_lcd(self):
# self.on_lcdTest = True
# self.content.setVisible(False)
# self.lcd_color_index = 0
# self.update_lcd_color()
def cmd_poweroff(self):
self.media_player.stop()
self.stop()
@ -469,6 +731,168 @@ class MainWindow(QMainWindow, SimpleLang):
not self.executor[module].is_running):
self.run(module, labels=labels)
# aging part
def _convert_seconds(self, seconds):
hours = seconds // 3600
minutes = (seconds % 3600) // 60
remaining_seconds = seconds % 60
return hours, minutes, remaining_seconds
def update_aging_hints(self, error: str = None):
hours, minutes, seconds = self._convert_seconds(self.aging_elapse)
hints = '正在进行老化测试...\n'
hints += f'计划老化 {self.aging_duration_choice.currentText()} 小时\n'
hints += f'已老化 {hours} 小时 {minutes}{seconds}\n'
if error:
hints += error
self.aging_dialog.setLabelText(hints)
def start_aging_test(self):
self.cpu_aging_proc = None
self.ddr_aging_proc = None
self.gpu_aging_proc = None
self.vpu_aging_proc = None
if self.cpu_aging.isChecked():
print('start cpu aging test')
cmd = 'stress-ng --cpu 4 --cpu-method all --cpu-load 50 --metrics-brief'
self.cpu_aging_proc = subprocess.Popen(cmd, shell=True,
start_new_session= True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if self.ddr_aging.isChecked():
print('start ddr aging test')
cmd = '/opt/factorytest/utils/memtester.sh'
self.ddr_aging_proc = subprocess.Popen(cmd, shell=True,
start_new_session= True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if self.gpu_aging.isChecked():
print('start gpu aging test')
cmd = 'glmark2-es2-wayland --off-screen --run-forever > /tmp/glmark2.log'
self.gpu_aging_proc = subprocess.Popen(cmd, shell=True,
start_new_session= True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if self.vpu_aging.isChecked():
print('start vpu aging tesht')
cmd = '/opt/factorytest/utils/vpu.sh'
self.vpu_aging_proc = subprocess.Popen(cmd, shell=True,
start_new_session= True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
def on_agingTestUpdate(self):
self.aging_elapse += 1
self.aging_dialog.setValue(self.aging_elapse)
error_modules = []
if self.cpu_aging.isChecked():
if self.cpu_aging_proc and self.cpu_aging_proc.poll():
if self.cpu_aging_proc.returncode != 0:
print('cpu aging test fail')
error_modules.append('CPU')
self.cpu_aging_proc = None
if self.ddr_aging.isChecked():
if self.ddr_aging_proc and self.ddr_aging_proc.poll():
if self.ddr_aging_proc.returncode != 0:
print('ddr aging test fail')
error_modules.append('DDR')
self.ddr_aging_proc = None
if self.gpu_aging.isChecked():
if self.gpu_aging_proc and self.gpu_aging_proc.poll():
if self.gpu_aging_proc.returncode != 0:
print('gpu aging test fail')
error_modules.append('GPU')
self.gpu_aging_proc = None
if self.vpu_aging.isChecked():
if self.vpu_aging_proc and self.vpu_aging_proc.poll():
if self.vpu_aging_proc.returncode != 0:
print('vpu aging test fail')
error_modules.append('VPU')
self.vpu_aging_proc = None
if error_modules:
error = ', '.join(error_modules) + '老化测试异常'
self.aging_pass = False
self.aging_timer.stop()
else:
error = '一切正常'
self.update_aging_hints(error)
if self.aging_elapse >= self.aging_duration and not error_modules:
self.aging_dialog.close()
def stop_aging_test(self):
if self.cpu_aging.isChecked():
print('stop cpu aging test')
if self.cpu_aging_proc and not self.cpu_aging_proc.poll():
self.cpu_aging_proc.kill()
self.cpu_aging_proc.wait()
self.cpu_aging_proc = None
if self.ddr_aging.isChecked():
print('stop ddr aging test')
if self.ddr_aging_proc and not self.ddr_aging_proc.poll():
self.ddr_aging_proc.kill()
self.ddr_aging_proc.wait()
self.ddr_aging_proc = None
if self.gpu_aging.isChecked():
print('stop gpu aging test')
if self.gpu_aging_proc and not self.gpu_aging_proc.poll():
self.gpu_aging_proc.kill()
self.gpu_aging_proc.wait()
self.gpu_aging_proc = None
if self.vpu_aging.isChecked():
print('stop vpu aging test')
if self.vpu_aging_proc and not self.vpu_aging_proc.poll():
self.vpu_aging_proc.kill()
self.vpu_aging_proc.wait()
self.vpu_aging_proc = None
def cmd_aging(self):
self.aging_duration = int(self.aging_duration_choice.currentText()) * 3600
self.aging_elapse = 0
self.aging_pass = True
self.aging_dialog = QProgressDialog('', f'{self.get_text("aging_cancel")}',
0, self.aging_duration, self)
self.aging_dialog.setWindowTitle(self.get_text('aging_test'))
self.update_aging_hints()
self.aging_dialog.setValue(0)
self.aging_dialog.setAutoClose(True)
self.aging_dialog.setAutoReset(False)
self.aging_dialog.setAutoFillBackground(True)
self.aging_dialog.setPalette(QPalette(QColor('yellow')))
self.aging_dialog.resize(320, 200)
self.start_aging_test()
self.aging_timer = QTimer(self.aging_dialog)
self.aging_timer.timeout.connect(self.on_agingTestUpdate)
self.aging_timer.start(1000)
rc = self.aging_dialog.exec_()
print(rc)
self.aging_timer.stop()
self.stop_aging_test()
if self.aging_elapse >= self.aging_duration and self.aging_pass:
self.aging_button.setPalette(QPalette(QColor(PASS_COLOR)))
else:
self.aging_button.setPalette(QPalette(QColor(FAIL_COLOR)))
######################################################
# GUI Callbacks
######################################################
@ -478,6 +902,77 @@ class MainWindow(QMainWindow, SimpleLang):
# update "run selected" button enabled state
self.set_selected_button_state()
# wifi signal part
def on_wifiStatusUpdate(self):
self.set_wifi_signal_level()
QTimer.singleShot(3000, lambda: self.on_wifiStatusUpdate())
def set_wifi_signal_level(self):
ssid, signal_level = self._get_strongest_wifi()
if not ssid:
return
if signal_level <= -100:
self.wifi_signal_level.setStyleSheet('QProgressBar { text-align: center; } QProgressBar::chunk { background-color: %s; }' % FAIL_COLOR)
value = 1
elif signal_level <= -88: # (-100, -88]
self.wifi_signal_level.setStyleSheet('QProgressBar { text-align: center; } QProgressBar::chunk { background-color: %s; }' % FAIL_COLOR)
value = 2
elif signal_level <= -77: # (-88, -77]
self.wifi_signal_level.setStyleSheet('QProgressBar { text-align: center; } QProgressBar::chunk { background-color: %s; }' % FAIL_COLOR)
value = 3
elif signal_level <= -55: # (-77, -55]
self.wifi_signal_level.setStyleSheet('QProgressBar { text-align: center; } QProgressBar::chunk { background-color: %s; }' % PASS_COLOR)
value = 4
else: # > -55
self.wifi_signal_level.setStyleSheet('QProgressBar { text-align: center; } QProgressBar::chunk { background-color: %s; }' % PASS_COLOR)
value = 5
self.wifi_signal_level.setFormat(f'{ssid}: {signal_level}')
self.wifi_signal_level.setValue(value)
def _get_strongest_wifi(self):
strongest_signal_level = -2147483648
strongest_ssid = None
timeout = 10
cmd = 'wpa_cli scan'
scan = subprocess.run(cmd, capture_output=True, text=True, shell=True, timeout=timeout)
if scan.returncode != 0:
return strongest_ssid, strongest_signal_level
cmd = 'wpa_cli scan_results'
proc = subprocess.run(cmd, capture_output=True, text=True, shell=True, timeout=timeout)
if proc.returncode != 0:
return strongest_ssid, strongest_signal_level
for line in proc.stdout.splitlines():
if not line.strip() or line.startswith('Selected interface') or line.startswith('bssid'):
continue
parts = line.split('\t')
if len(parts) < 5:
continue
signal_level = int(parts[2])
ssid = parts[4]
if signal_level > strongest_signal_level:
strongest_signal_level = signal_level
strongest_ssid = ssid
return strongest_ssid, strongest_signal_level
# wifi mac part
def _get_wifi_mac(self):
cmd = 'ifconfig wlan0'
proc = subprocess.run(cmd, capture_output=True, text=True, shell=True, timeout=2)
for line in proc.stdout.splitlines():
pattern = 'HWaddr'
if line.find(pattern) > 0:
return line.split(pattern)[1].strip()
def _get_sn(self):
path = '/proc/device-tree/serial-number'
if os.path.exists(path):
@ -524,6 +1019,39 @@ class MainWindow(QMainWindow, SimpleLang):
with open('/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq', 'r') as f:
return round(int(f.readline().strip()) / 1000 / 1000, 1)
# cpu temp part
def on_cpuTempUpdate(self):
self.cpu_temp.setText(f'{self.get_text("cpu_temp")}: {self._get_CPU_Temp()} °C')
def _get_CPU_Temp(self):
thermal_base_path = "/sys/class/thermal/"
ret = "None"
try:
# Traverse the thermal_zone* directory
for zone in os.listdir(thermal_base_path):
zone_path = os.path.join(thermal_base_path, zone)
type_path = os.path.join(zone_path, "type")
# Check whether the type file exists
if os.path.isfile(type_path):
with open(type_path, 'r') as type_file:
type_content = type_file.read().strip()
# Check whether the type file content matches
if type_content == "cluster0_thermal":
temp_path = os.path.join(zone_path, "temp")
if os.path.isfile(temp_path):
with open(temp_path, 'r') as temp_file:
temp_content = temp_file.read().strip()
temp_content = int(temp_content)//1000
ret = str(temp_content)
except Exception as e:
print(f"An error occurred when getting cpu temperature: {e}")
return ret
def on_nodeStatusUpdate(self, node):
"Event handler: a node on the tree has received a status update"
module = node.path.split('.')[0]

Binary file not shown.

1
res/yuv420p_w1280_h720_30f.yuv Executable file

File diff suppressed because one or more lines are too long

10
utils/memtester.sh Executable file
View file

@ -0,0 +1,10 @@
#!/bin/bash
test_size=100M
test_loop=1
while true
do
memtester $test_size $test_loop
[ $? -eq 0 ] || exit -1
done

30
utils/vpu.sh Executable file
View file

@ -0,0 +1,30 @@
#!/bin/bash -e
log="/tmp/vpu-test.log"
h264="h264_w1920_h1080_f25_r4_p1_8bit_54f_11mb_high_cabac.264"
decode_yuv="/tmp/decode.yuv"
decode_md5="e59c9318e3f733d016ebfcdec98a95fb"
yuv="yuv420p_w1280_h720_30f.yuv"
encode_264="/tmp/encode.264"
encode_md5="55ceae7750bdc3906dd427e221c0317b"
while true
do
rm -f $log
# decode routine
echo "`date`" >> $log
rm -f $decode_yuv
mvx_decoder -f raw /opt/factorytest/res/h264_w1920_h1080_f25_r4_p1_8bit_54f_11mb_high_cabac.264 $decode_yuv >> $log
[ -f $decode_yuv ] || exit -1
md5=`md5sum $decode_yuv | awk '{ print $1 }'`
[ "$md5" == "$decode_md5" ] || exit -1
# encode routine
echo "`date`" >> $log
rm -f $encode_264
mvx_encoder -f raw -w 1280 -h 720 /opt/factorytest/res/yuv420p_w1280_h720_30f.yuv $encode_264 >> $log
[ -f $encode_264 ] || exit -1
md5=`md5sum $encode_264 | awk '{ print $1 }'`
[ "$md5" == "$encode_md5" ] || exit -1
done