taotoolkit 1.1.9__tar.gz → 2.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/PKG-INFO +2 -2
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/pyproject.toml +2 -2
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/taotoolkit/__init__.py +1 -1
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/taotoolkit/tao_camDvt.py +31 -30
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/taotoolkit/tao_cmdTool.py +2 -2
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/taotoolkit/tao_common.py +80 -6
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/taotoolkit/tao_device.py +205 -86
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/taotoolkit/tao_flash.py +4 -4
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/taotoolkit/tao_tuning.py +216 -109
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/taotoolkit.egg-info/PKG-INFO +2 -2
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/taotoolkit.egg-info/requires.txt +1 -1
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/README.md +0 -0
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/setup.cfg +0 -0
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/taotoolkit/asrVrf.py +0 -0
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/taotoolkit/tao_vrfTool.py +0 -0
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/taotoolkit.egg-info/SOURCES.txt +0 -0
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/taotoolkit.egg-info/dependency_links.txt +0 -0
- {taotoolkit-1.1.9 → taotoolkit-2.0.1}/taotoolkit.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: taotoolkit
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.1
|
|
4
4
|
Summary: Tao ToolKit
|
|
5
5
|
Author-email: taotaoli <taotaoli@asrmicro.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -19,7 +19,7 @@ Requires-Dist: beautifulsoup4>=4.10.0
|
|
|
19
19
|
Requires-Dist: pyyaml>=6.0.3
|
|
20
20
|
Requires-Dist: pywinpty>=3.0.5; platform_system == "Windows"
|
|
21
21
|
Provides-Extra: uiautomator
|
|
22
|
-
Requires-Dist: uiautomator2>=2.0.
|
|
22
|
+
Requires-Dist: uiautomator2>=2.0.1; extra == "uiautomator"
|
|
23
23
|
|
|
24
24
|
# TAO - Toolkit
|
|
25
25
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "taotoolkit"
|
|
7
|
-
version = "
|
|
7
|
+
version = "2.0.1"
|
|
8
8
|
description = "Tao ToolKit"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -29,5 +29,5 @@ dependencies = [
|
|
|
29
29
|
|
|
30
30
|
[project.optional-dependencies]
|
|
31
31
|
uiautomator = [
|
|
32
|
-
"uiautomator2>=2.0.
|
|
32
|
+
"uiautomator2>=2.0.1",
|
|
33
33
|
]
|
|
@@ -20,6 +20,7 @@ from .tao_common import (
|
|
|
20
20
|
loge,
|
|
21
21
|
logi,
|
|
22
22
|
renameFile,
|
|
23
|
+
sleep,
|
|
23
24
|
normalize_args,
|
|
24
25
|
register_command,
|
|
25
26
|
)
|
|
@@ -62,7 +63,7 @@ class CamDvt(asrCamOp):
|
|
|
62
63
|
def checkAeChannel(self):
|
|
63
64
|
cmd = f"{self.tuning_assistant} 127.0.0.1 t 3000 3000 3000 r m0_g0 CAECFilter m_pLumaRLong 5 7"
|
|
64
65
|
try:
|
|
65
|
-
out, _ = pCmd(cmd)
|
|
66
|
+
out, _ = pCmd(cmd, sleep_s=1.0)
|
|
66
67
|
cmdResult = re.split("[ \n,]+", out)[2]
|
|
67
68
|
|
|
68
69
|
if is_number(cmdResult):
|
|
@@ -79,7 +80,7 @@ class CamDvt(asrCamOp):
|
|
|
79
80
|
"""
|
|
80
81
|
|
|
81
82
|
cmd = f"{self.tuning_assistant} 127.0.0.1 t 3000 3000 3000 gv"
|
|
82
|
-
out, _ = pCmd(cmd)
|
|
83
|
+
out, _ = pCmd(cmd, sleep_s=1.0)
|
|
83
84
|
if "successfully" in out:
|
|
84
85
|
timestamp = time.strftime("%Y%m%d_%H%M%S", time.localtime())
|
|
85
86
|
outPath = os.path.join(os.getcwd(), folderName + timestamp)
|
|
@@ -128,7 +129,7 @@ class CamDvt(asrCamOp):
|
|
|
128
129
|
total = (gainMax - gainMin) // step + 1
|
|
129
130
|
for i in range(gainMin, gainMax + 1, step):
|
|
130
131
|
self.writeIsp("CAECFilter", "m_pTotalGainManual", 0, 0, i)
|
|
131
|
-
|
|
132
|
+
sleep(0.1)
|
|
132
133
|
luma = self.readIsp("CAECFilter", "m_pLumaMatrixLong", 5, 7, True)
|
|
133
134
|
info = "m_pExpTimeManual(us) = %d m_pTotalGainManual(Q8) = %d luma = %f %d/%d" % (
|
|
134
135
|
ExpTimeManual,
|
|
@@ -139,7 +140,7 @@ class CamDvt(asrCamOp):
|
|
|
139
140
|
)
|
|
140
141
|
cur += 1
|
|
141
142
|
logi(info)
|
|
142
|
-
|
|
143
|
+
sleep(0.1)
|
|
143
144
|
self.__filterEnable(1, 1, 1, 1, 1, 1)
|
|
144
145
|
|
|
145
146
|
# debug API
|
|
@@ -156,17 +157,17 @@ class CamDvt(asrCamOp):
|
|
|
156
157
|
total = (expMax - expMin) // step + 1
|
|
157
158
|
for i in range(expMin, expMax + 1, step):
|
|
158
159
|
self.writeIsp("CAECFilter", "m_pExpTimeManual", 0, 0, i)
|
|
159
|
-
|
|
160
|
+
sleep(0.1)
|
|
160
161
|
luma = self.readIsp("CAECFilter", "m_pLumaMatrixLong", 5, 7, True)
|
|
161
162
|
|
|
162
163
|
logi(f"m_pExpTimeManual(us) = {i} m_pTotalGainManual(Q8) = {gainManual} luma = {luma} {cur}/{total}")
|
|
163
164
|
cur += 1
|
|
164
|
-
#
|
|
165
|
+
# sleep(0.1)
|
|
165
166
|
self.__filterEnable(1, 1, 1, 1, 1, 1)
|
|
166
167
|
|
|
167
168
|
def __getLumaWithGain(self, gain: int):
|
|
168
169
|
self.writeIsp("CAECFilter", "m_pTotalGainManual", 0, 0, gain)
|
|
169
|
-
|
|
170
|
+
sleep(0.6)
|
|
170
171
|
if self.aeChl == 3:
|
|
171
172
|
r = self.readIsp("CAECFilter", "m_pLumaRLong", 5, 7, True, strict=True)
|
|
172
173
|
g = self.readIsp("CAECFilter", "m_pLumaGLong", 5, 7, True, strict=True)
|
|
@@ -180,7 +181,7 @@ class CamDvt(asrCamOp):
|
|
|
180
181
|
|
|
181
182
|
def __getLumaWithExp(self, exp: int):
|
|
182
183
|
self.writeIsp("CAECFilter", "m_pExpTimeManual", 0, 0, exp)
|
|
183
|
-
|
|
184
|
+
sleep(0.6)
|
|
184
185
|
if self.aeChl == 3:
|
|
185
186
|
r = self.readIsp("CAECFilter", "m_pLumaRLong", 5, 7, True, strict=True)
|
|
186
187
|
g = self.readIsp("CAECFilter", "m_pLumaGLong", 5, 7, True, strict=True)
|
|
@@ -208,7 +209,7 @@ class CamDvt(asrCamOp):
|
|
|
208
209
|
inVrf,
|
|
209
210
|
outVrf,
|
|
210
211
|
)
|
|
211
|
-
pCmd(cmd)
|
|
212
|
+
pCmd(cmd, sleep_s=1.0)
|
|
212
213
|
removeFile(inVrf)
|
|
213
214
|
vrfObj = asrVrf.Vrf()
|
|
214
215
|
vrfObj.Read(outVrf)
|
|
@@ -286,14 +287,14 @@ class CamDvt(asrCamOp):
|
|
|
286
287
|
def __getGainLumaWithVrf(self, gain: int, exp: int):
|
|
287
288
|
self.writeIsp("CAECFilter", "m_pTotalGainManual", 0, 0, gain)
|
|
288
289
|
# self.writeIsp("CAECFilter", "m_pExpTimeManual", 0, 0, exp)
|
|
289
|
-
|
|
290
|
+
sleep(0.2)
|
|
290
291
|
vrfName = "gain" + str(gain) + "_exp" + str(exp) + ".vrf"
|
|
291
292
|
return self.getVrfMean(self.outPath, vrfName, True)
|
|
292
293
|
|
|
293
294
|
def __getExpLumaWithVrf(self, gain: int, exp: int):
|
|
294
295
|
# self.writeIsp("CAECFilter", "m_pTotalGainManual", 0, 0, gain)
|
|
295
296
|
self.writeIsp("CAECFilter", "m_pExpTimeManual", 0, 0, exp)
|
|
296
|
-
|
|
297
|
+
sleep(0.2)
|
|
297
298
|
vrfName = "gain" + str(gain) + "_exp" + str(exp) + ".vrf"
|
|
298
299
|
return self.getVrfMean(self.outPath, vrfName, True)
|
|
299
300
|
|
|
@@ -410,7 +411,7 @@ class CamDvt(asrCamOp):
|
|
|
410
411
|
f.write(writeStr)
|
|
411
412
|
logi(writeStr)
|
|
412
413
|
|
|
413
|
-
|
|
414
|
+
sleep(1)
|
|
414
415
|
|
|
415
416
|
def __aeExpScanVrf(self, blcTest: bool):
|
|
416
417
|
"""
|
|
@@ -451,7 +452,7 @@ class CamDvt(asrCamOp):
|
|
|
451
452
|
f.write(writeStr)
|
|
452
453
|
logi(writeStr)
|
|
453
454
|
|
|
454
|
-
|
|
455
|
+
sleep(1)
|
|
455
456
|
|
|
456
457
|
def __aeGainScanStat(self):
|
|
457
458
|
"""
|
|
@@ -504,7 +505,7 @@ class CamDvt(asrCamOp):
|
|
|
504
505
|
f.write(writeStr)
|
|
505
506
|
logi(writeStr.replace("\n", "").replace("\r", ""))
|
|
506
507
|
|
|
507
|
-
|
|
508
|
+
sleep(1)
|
|
508
509
|
|
|
509
510
|
def __aeExpScanStat(self):
|
|
510
511
|
"""
|
|
@@ -557,7 +558,7 @@ class CamDvt(asrCamOp):
|
|
|
557
558
|
f.write(writeStr)
|
|
558
559
|
logi(writeStr.replace("\n", "").replace("\r", ""))
|
|
559
560
|
|
|
560
|
-
|
|
561
|
+
sleep(1)
|
|
561
562
|
|
|
562
563
|
def calibrateAE(self):
|
|
563
564
|
m_pExpIndexLong = self.readIsp("CAECFilter", "m_pExpIndexLong", 0, 0, False)
|
|
@@ -877,8 +878,8 @@ class CamDvt(asrCamOp):
|
|
|
877
878
|
gainMax = self.readIsp("CAECFilter", "m_pMaxAnaGain")
|
|
878
879
|
print("gainMin(Q8)=", gainMin, "gainMax(Q8)=", gainMax)
|
|
879
880
|
self.writeIsp("CAECFilter", "m_bManualAEEnable", 0, 0, 1)
|
|
880
|
-
pCmd("adb shell rm data/vendor/camera/*", 1)
|
|
881
|
-
pCmd("adb shell setprop persist.vendor.camera.enable.capturedump 1", 0.5)
|
|
881
|
+
pCmd("adb shell rm data/vendor/camera/*", sleep_s=1)
|
|
882
|
+
pCmd("adb shell setprop persist.vendor.camera.enable.capturedump 1", sleep_s=0.5)
|
|
882
883
|
# outPath = os.path.join(self.outPath, "raw")
|
|
883
884
|
outPath = self.outPath
|
|
884
885
|
if not os.path.exists(outPath):
|
|
@@ -888,12 +889,12 @@ class CamDvt(asrCamOp):
|
|
|
888
889
|
print("gain(Q8)=", gain)
|
|
889
890
|
self.writeIsp("CAECFilter", "m_pTotalGainManual", 0, 0, gain)
|
|
890
891
|
self.writeIsp("CAECFilter", "m_pAnaGainManual", 0, 0, gain)
|
|
891
|
-
|
|
892
|
+
sleep(0.2)
|
|
892
893
|
vrfName = "gain_" + str(gain // 256) + ".vrf"
|
|
893
894
|
self.dumpVrf(outPath, vrfName)
|
|
894
895
|
# pCmd("adb shell input keyevent 27",sleep_s=5)
|
|
895
896
|
|
|
896
|
-
|
|
897
|
+
sleep(1)
|
|
897
898
|
|
|
898
899
|
def gainScanVrf(self):
|
|
899
900
|
"""
|
|
@@ -904,8 +905,8 @@ class CamDvt(asrCamOp):
|
|
|
904
905
|
gainMax = self.readIsp("CAECFilter", "m_pMaxAnaGain")
|
|
905
906
|
print("gainMin(Q8)=", gainMin, "gainMax(Q8)=", gainMax)
|
|
906
907
|
self.writeIsp("CAECFilter", "m_bManualAEEnable", 0, 0, 0)
|
|
907
|
-
pCmd("adb shell rm data/vendor/camera/*", 1)
|
|
908
|
-
pCmd("adb shell setprop persist.vendor.camera.enable.capturedump 1", 0.5)
|
|
908
|
+
pCmd("adb shell rm data/vendor/camera/*", sleep_s=1)
|
|
909
|
+
pCmd("adb shell setprop persist.vendor.camera.enable.capturedump 1", sleep_s=0.5)
|
|
909
910
|
# outPath = os.path.join(self.outPath, "raw")
|
|
910
911
|
outPath = self.outPath
|
|
911
912
|
if not os.path.exists(outPath):
|
|
@@ -917,12 +918,12 @@ class CamDvt(asrCamOp):
|
|
|
917
918
|
self.writeIsp("CAECFilter", "m_pMaxAnaGain", 0, 0, gain)
|
|
918
919
|
self.writeIsp("CAECFilter", "m_pMinTotalGain", 0, 0, gain)
|
|
919
920
|
self.writeIsp("CAECFilter", "m_pMaxTotalGain", 0, 0, gain)
|
|
920
|
-
|
|
921
|
+
sleep(0.2)
|
|
921
922
|
vrfName = "gain_" + str(gain // 256) + ".vrf"
|
|
922
923
|
self.dumpVrf(outPath, vrfName)
|
|
923
924
|
# pCmd("adb shell input keyevent 27",sleep_s=5)
|
|
924
925
|
|
|
925
|
-
|
|
926
|
+
sleep(1)
|
|
926
927
|
|
|
927
928
|
def afScan(self):
|
|
928
929
|
"""
|
|
@@ -946,7 +947,7 @@ class CamDvt(asrCamOp):
|
|
|
946
947
|
for i in range(startPosition, endPosition + 1, step):
|
|
947
948
|
self.writeIsp("CAFFilter", "m_nManualMotorPosition", 0, 0, i)
|
|
948
949
|
self.writeIsp("CAFFilter", "m_bMotorManualTrigger", 0, 0, 1)
|
|
949
|
-
|
|
950
|
+
sleep(1)
|
|
950
951
|
m_pRTFVList = self.readIsp("CAFFilter", "m_pRTFVList", 0, 0, False)
|
|
951
952
|
|
|
952
953
|
writeStr = "%d/%d position = %d FV = %d \n" % (cur, total, i, m_pRTFVList)
|
|
@@ -954,11 +955,11 @@ class CamDvt(asrCamOp):
|
|
|
954
955
|
f.write(writeStr)
|
|
955
956
|
logi(writeStr.replace("\n", "").replace("\r", ""))
|
|
956
957
|
|
|
957
|
-
|
|
958
|
+
sleep(1)
|
|
958
959
|
|
|
959
960
|
def dumpPDVrf(self, outPath: str, posCode: str):
|
|
960
961
|
cmd = f"{self.tuning_assistant} 127.0.0.1 t 3000 3000 3000 dp m0_g0 {outPath} 1"
|
|
961
|
-
out = pCmd(cmd)
|
|
962
|
+
out = pCmd(cmd, sleep_s=1.0)
|
|
962
963
|
|
|
963
964
|
# 使用正则表达式查找关键词之间的字符串
|
|
964
965
|
keyword1 = "ID="
|
|
@@ -999,7 +1000,7 @@ class CamDvt(asrCamOp):
|
|
|
999
1000
|
for i in range(startPosition, endPosition + 1, step):
|
|
1000
1001
|
self.writeIsp("CAFFilter", "m_nManualMotorPosition", 0, 0, i)
|
|
1001
1002
|
self.writeIsp("CAFFilter", "m_bMotorManualTrigger", 0, 0, 1)
|
|
1002
|
-
|
|
1003
|
+
sleep(2)
|
|
1003
1004
|
# outPath = os.path.join(self.outPath, "raw")
|
|
1004
1005
|
outPath = self.outPath
|
|
1005
1006
|
if not os.path.exists(outPath):
|
|
@@ -1011,15 +1012,15 @@ class CamDvt(asrCamOp):
|
|
|
1011
1012
|
self.dumpVrf(outPath, str(i) + ".vrf")
|
|
1012
1013
|
logi(f"position = {i} {cur}/{total}")
|
|
1013
1014
|
cur += 1
|
|
1014
|
-
|
|
1015
|
+
sleep(1)
|
|
1015
1016
|
|
|
1016
1017
|
def afDvt(self):
|
|
1017
1018
|
"""
|
|
1018
1019
|
光源需直流无频闪,照度800lux, 50cm距离细节丰富的chart
|
|
1019
1020
|
"""
|
|
1020
1021
|
|
|
1021
|
-
pCmd("adb shell input keyevent KEYCODE_HOME", 3)
|
|
1022
|
-
pCmd("adb shell am start -a android.media.action.STILL_IMAGE_CAMERA", 2)
|
|
1022
|
+
pCmd("adb shell input keyevent KEYCODE_HOME", sleep_s=3)
|
|
1023
|
+
pCmd("adb shell am start -a android.media.action.STILL_IMAGE_CAMERA", sleep_s=2)
|
|
1023
1024
|
|
|
1024
1025
|
self.__filterEnable(0, 1, 0, 0, 0, 0)
|
|
1025
1026
|
|
|
@@ -556,7 +556,7 @@ def CLI_videoCut(args=None):
|
|
|
556
556
|
v2 = f"lark_scene{scene}"
|
|
557
557
|
for i in range(5):
|
|
558
558
|
cmd = f'ffmpeg -i {v1}_{i}.mp4 -i {v2}_{i}.mp4 -filter_complex "[0:v][1:v]hstack=inputs=2" -c:v libx264 -crf 18 -preset slow scene{scene}_{i}.mp4'
|
|
559
|
-
oCmd(cmd, showCmd=True, logLevel="info")
|
|
559
|
+
oCmd(cmd, sleep_s=1.0, showCmd=True, logLevel="info")
|
|
560
560
|
|
|
561
561
|
|
|
562
562
|
def CLI_video2jpg(argsList):
|
|
@@ -569,7 +569,7 @@ def CLI_video2jpg(argsList):
|
|
|
569
569
|
os.makedirs(os.path.join(os.path.curdir, args.out), exist_ok=True)
|
|
570
570
|
cmd = f"ffmpeg -i {args.path} -r {args.fps} -f image2 {args.out}/image-%3d.bmp"
|
|
571
571
|
logi(f"video2jpg cmd: {cmd}")
|
|
572
|
-
oCmd(cmd, showCmd=True, logLevel="info")
|
|
572
|
+
oCmd(cmd, sleep_s=1.0, showCmd=True, logLevel="info")
|
|
573
573
|
|
|
574
574
|
|
|
575
575
|
_COMMAND_REGISTRY = {}
|
|
@@ -7,6 +7,7 @@ import re
|
|
|
7
7
|
import subprocess
|
|
8
8
|
import sys
|
|
9
9
|
import time
|
|
10
|
+
import atexit
|
|
10
11
|
from functools import wraps
|
|
11
12
|
from datetime import datetime
|
|
12
13
|
from typing import Callable, Dict, List, Optional, Any
|
|
@@ -145,8 +146,64 @@ def iExit(msg: str) -> None:
|
|
|
145
146
|
sys.exit(0)
|
|
146
147
|
|
|
147
148
|
|
|
149
|
+
# ── 命令耗时埋点 ─────────────────────────────────────────
|
|
150
|
+
# 环境变量 TAO_TIMING=1 开启, 进程退出时自动打印汇总;
|
|
151
|
+
# elapsed 只统计命令真实执行时间, sleep_s / 直接 sleep() 单独统计, 便于区分"设备慢"与"等待多"
|
|
152
|
+
_TIMING_ENABLED = os.environ.get("TAO_TIMING", "").strip().lower() not in ("", "0", "false", "off")
|
|
153
|
+
_timingRecords: List[Dict[str, Any]] = []
|
|
154
|
+
_timingSleeps: List[float] = []
|
|
155
|
+
|
|
156
|
+
|
|
148
157
|
def sleep(seconds: float) -> None:
|
|
149
158
|
time.sleep(seconds)
|
|
159
|
+
if _TIMING_ENABLED:
|
|
160
|
+
_timingSleeps.append(seconds)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def timingCtrl(enabled: bool) -> None:
|
|
164
|
+
"""开关命令耗时埋点"""
|
|
165
|
+
global _TIMING_ENABLED
|
|
166
|
+
_TIMING_ENABLED = enabled
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _timingAdd(kind: str, cmd: str, elapsed: float, sleep_s: float) -> None:
|
|
170
|
+
if _TIMING_ENABLED:
|
|
171
|
+
_timingRecords.append({"kind": kind, "cmd": cmd, "elapsed": elapsed, "sleep": sleep_s})
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def timingReport(top=10, reset=False) -> Dict[str, Any]:
|
|
175
|
+
"""打印并返回耗时统计: 命令真实耗时、sleep 耗时及占比、最慢的 top 条命令"""
|
|
176
|
+
totalCmd = sum(r["elapsed"] for r in _timingRecords)
|
|
177
|
+
totalSleep = sum(r["sleep"] for r in _timingRecords) + sum(_timingSleeps)
|
|
178
|
+
total = totalCmd + totalSleep
|
|
179
|
+
stat = {
|
|
180
|
+
"count": len(_timingRecords),
|
|
181
|
+
"sleepCalls": len(_timingSleeps),
|
|
182
|
+
"cmdTime": totalCmd,
|
|
183
|
+
"sleepTime": totalSleep,
|
|
184
|
+
"totalTime": total,
|
|
185
|
+
"sleepRatio": (totalSleep / total) if total else 0.0,
|
|
186
|
+
"slowest": sorted(_timingRecords, key=lambda r: r["elapsed"], reverse=True)[:top],
|
|
187
|
+
}
|
|
188
|
+
if _timingRecords or _timingSleeps:
|
|
189
|
+
print(
|
|
190
|
+
f"[timing] 命令数={stat['count']} 直接sleep={stat['sleepCalls']}次 命令耗时={totalCmd:.2f}s "
|
|
191
|
+
f"sleep耗时={totalSleep:.2f}s sleep占比={stat['sleepRatio'] * 100:.1f}%"
|
|
192
|
+
)
|
|
193
|
+
for index, r in enumerate(stat["slowest"], 1):
|
|
194
|
+
print(f"[timing] {index:>2}. {r['elapsed'] * 1000:>8.1f}ms sleep={r['sleep']:.1f}s {r['kind']} {r['cmd'][:100]}")
|
|
195
|
+
if reset:
|
|
196
|
+
_timingRecords.clear()
|
|
197
|
+
_timingSleeps.clear()
|
|
198
|
+
return stat
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def _timingAtExit() -> None:
|
|
202
|
+
if _TIMING_ENABLED and (_timingRecords or _timingSleeps):
|
|
203
|
+
timingReport()
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
atexit.register(_timingAtExit)
|
|
150
207
|
|
|
151
208
|
|
|
152
209
|
sysVersion = sys.platform
|
|
@@ -326,7 +383,7 @@ def parseDeviceInfo(info: str) -> Dict[str, str]:
|
|
|
326
383
|
|
|
327
384
|
def pCmd(
|
|
328
385
|
cmd: str,
|
|
329
|
-
sleep_s=
|
|
386
|
+
sleep_s=0.0, # 默认不等待, 需要等待的调用请显式传 sleep_s
|
|
330
387
|
showCmd=False,
|
|
331
388
|
shell=False,
|
|
332
389
|
splitCmd=True,
|
|
@@ -347,6 +404,7 @@ def pCmd(
|
|
|
347
404
|
logCallInfo(cmd)
|
|
348
405
|
else:
|
|
349
406
|
logCallDebug(cmd)
|
|
407
|
+
t0 = time.perf_counter()
|
|
350
408
|
try:
|
|
351
409
|
if splitCmd:
|
|
352
410
|
proc = subprocess.Popen(
|
|
@@ -369,8 +427,10 @@ def pCmd(
|
|
|
369
427
|
# env=os.environ.copy(),
|
|
370
428
|
)
|
|
371
429
|
except subprocess.TimeoutExpired:
|
|
430
|
+
_timingAdd("pCmd", cmd, time.perf_counter() - t0, 0.0)
|
|
372
431
|
return "", f"Command '{cmd}' timed out after {timeOut} seconds"
|
|
373
432
|
except subprocess.CalledProcessError as e:
|
|
433
|
+
_timingAdd("pCmd", cmd, time.perf_counter() - t0, 0.0)
|
|
374
434
|
return "", f"Command '{cmd}' failed with error: {e.stderr}"
|
|
375
435
|
out = ""
|
|
376
436
|
error = ""
|
|
@@ -379,12 +439,15 @@ def pCmd(
|
|
|
379
439
|
out, error = proc.communicate(timeout=timeOut)
|
|
380
440
|
except subprocess.TimeoutExpired:
|
|
381
441
|
logCallErr(f"{cmd} timeout", "error")
|
|
442
|
+
_timingAdd("pCmd", cmd, time.perf_counter() - t0, 0.0)
|
|
382
443
|
if not ignoreTimeOut:
|
|
383
444
|
exit()
|
|
384
445
|
else:
|
|
385
446
|
return "None", "None"
|
|
386
447
|
|
|
387
|
-
|
|
448
|
+
elapsed = time.perf_counter() - t0
|
|
449
|
+
time.sleep(sleep_s)
|
|
450
|
+
_timingAdd("pCmd", cmd, elapsed, sleep_s)
|
|
388
451
|
if checkErr:
|
|
389
452
|
checkMsg(error, "error")
|
|
390
453
|
checkMsg(out, "failed")
|
|
@@ -398,6 +461,8 @@ def pCmd(
|
|
|
398
461
|
logCallInfo(error)
|
|
399
462
|
return out, error
|
|
400
463
|
else:
|
|
464
|
+
elapsed = time.perf_counter() - t0
|
|
465
|
+
_timingAdd("pCmd", cmd, elapsed, 0.0)
|
|
401
466
|
return "None", "None"
|
|
402
467
|
|
|
403
468
|
|
|
@@ -449,7 +514,7 @@ def rCmdRealtime(
|
|
|
449
514
|
|
|
450
515
|
def rCmd(
|
|
451
516
|
cmd: str,
|
|
452
|
-
sleep_s=
|
|
517
|
+
sleep_s=0.0, # 默认不等待, 需要等待的调用请显式传 sleep_s
|
|
453
518
|
showCmd=False,
|
|
454
519
|
shell=False,
|
|
455
520
|
splitCmd=True,
|
|
@@ -468,6 +533,7 @@ def rCmd(
|
|
|
468
533
|
logCallInfo(cmd, callStack=3)
|
|
469
534
|
else:
|
|
470
535
|
logCallDebug(cmd, callStack=3)
|
|
536
|
+
t0 = time.perf_counter()
|
|
471
537
|
try:
|
|
472
538
|
if splitCmd:
|
|
473
539
|
result = subprocess.run(
|
|
@@ -490,11 +556,15 @@ def rCmd(
|
|
|
490
556
|
timeout=timeOut,
|
|
491
557
|
)
|
|
492
558
|
except subprocess.TimeoutExpired:
|
|
559
|
+
_timingAdd("rCmd", cmd, time.perf_counter() - t0, 0.0)
|
|
493
560
|
return "", f"Command '{cmd}' timed out after {timeOut} seconds"
|
|
494
561
|
except subprocess.CalledProcessError as e:
|
|
562
|
+
_timingAdd("rCmd", cmd, time.perf_counter() - t0, 0.0)
|
|
495
563
|
return "", f"Command '{cmd}' failed with error: {e.stderr}"
|
|
496
564
|
|
|
497
|
-
|
|
565
|
+
elapsed = time.perf_counter() - t0
|
|
566
|
+
time.sleep(sleep_s)
|
|
567
|
+
_timingAdd("rCmd", cmd, elapsed, sleep_s)
|
|
498
568
|
if checkErr:
|
|
499
569
|
checkMsg(result.stderr, "error")
|
|
500
570
|
checkMsg(result.stderr, "failed")
|
|
@@ -510,7 +580,8 @@ def rCmd(
|
|
|
510
580
|
return result.stdout, result.stderr
|
|
511
581
|
|
|
512
582
|
|
|
513
|
-
def oCmd(cmd: str, sleep_s=
|
|
583
|
+
def oCmd(cmd: str, sleep_s=0.0, showCmd=False, logLevel="debug"):
|
|
584
|
+
"""执行系统命令; 默认不等待, 需要等待的调用请显式传 sleep_s"""
|
|
514
585
|
if showCmd:
|
|
515
586
|
if logLevel == "warn":
|
|
516
587
|
logCallWarn(cmd, callStack=3)
|
|
@@ -520,5 +591,8 @@ def oCmd(cmd: str, sleep_s=1.0, showCmd=False, logLevel="debug"):
|
|
|
520
591
|
logCallInfo(cmd, callStack=3)
|
|
521
592
|
else:
|
|
522
593
|
logCallDebug(cmd, callStack=3)
|
|
594
|
+
t0 = time.perf_counter()
|
|
523
595
|
os.system(cmd)
|
|
524
|
-
|
|
596
|
+
elapsed = time.perf_counter() - t0
|
|
597
|
+
time.sleep(sleep_s)
|
|
598
|
+
_timingAdd("oCmd", cmd, elapsed, sleep_s)
|