p3p implementation
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
/backend/.venv
|
/backend/.venv
|
||||||
/backend/__pycache__
|
/backend/__pycache__
|
||||||
/backend/_run_sched_test.py
|
/backend/_run_sched_test.py
|
||||||
|
/backend/output.txt
|
||||||
IMPLEMENTATIONPLAN.md
|
IMPLEMENTATIONPLAN.md
|
||||||
scheduler.db
|
scheduler.db
|
||||||
scheduler.db*
|
scheduler.db*
|
||||||
@@ -121,6 +121,7 @@ def compile_schedule_endpoint(request: CompileScheduleRequest) -> dict[str, Any]
|
|||||||
has_coe_pair=t.has_coe_pair,
|
has_coe_pair=t.has_coe_pair,
|
||||||
coe_pairing=t.coe_pairing or [],
|
coe_pairing=t.coe_pairing or [],
|
||||||
config=t.config,
|
config=t.config,
|
||||||
|
throttled=t.throttled,
|
||||||
estimated_minutes=t.estimated_minutes,
|
estimated_minutes=t.estimated_minutes,
|
||||||
priority=t.priority,
|
priority=t.priority,
|
||||||
raw_payload=t.raw_payload or {},
|
raw_payload=t.raw_payload or {},
|
||||||
|
|||||||
+44
-34
@@ -1,71 +1,81 @@
|
|||||||
Priority,Index,Throttled,Rotation,TC ID,Band,6GHz Power Mode,Station 1 Test Point,Station 1 Channel,Station 1 Bandwidth,Station 1 RSSI,Station 1 Direction,Station 1 Rate,Station 1 STA,Station 2 Test Point,Station 2 Channel,Station 2 Bandwidth,Station 2 RSSI,Station 2 Direction,Station 2 Rate,Station 2 STA,Station 3 Test Point,Station 3 Channel,Station 3 Bandwidth,Station 3 RSSI,Station 3 Direction,Station 3 Rate,Station 3 STA
|
Priority,Index,Throttled,Rotation,TC ID,Band,6GHz Power Mode,Station 1 Test Point,Station 1 Channel,Station 1 Bandwidth,Station 1 RSSI,Station 1 Direction,Station 1 Rate,Station 1 STA,Station 2 Test Point,Station 2 Channel,Station 2 Bandwidth,Station 2 RSSI,Station 2 Direction,Station 2 Rate,Station 2 STA,Station 3 Test Point,Station 3 Channel,Station 3 Bandwidth,Station 3 RSSI,Station 3 Direction,Station 3 Rate,Station 3 STA
|
||||||
P2,1,Yes,R3,P3PRXBETH001,5G,LPI,T1F,36,80,-76,UL,22Mbps,STA63,T1I,36,80,-76,UL,22Mbps,STA64,T2J,36,80,-76,UL,11Mbps,STA65
|
|
||||||
P2,2,Yes,R3,P3PRXBETH002,5G,LPI,T1F,100,80,-76,UL,22Mbps,STA63,T1I,100,80,-76,UL,22Mbps,STA64,T2J,100,80,-76,UL,11Mbps,STA65
|
|
||||||
P2,3,Yes,R3,P3PRXBETH003,5G,LPI,T1F,161,80,-76,UL,22Mbps,STA63,T1I,161,80,-76,UL,22Mbps,STA64,T2J,161,80,-76,UL,11Mbps,STA65
|
|
||||||
P2,4,Yes,R1,P3PRXBETH004,6G,LPI,T2A,5,160,-79,UL,22Mbps,STA63,T1L,5,160,-79,UL,22Mbps,STA64,T2O,5,160,-79,UL,11Mbps,STA65
|
P2,4,Yes,R1,P3PRXBETH004,6G,LPI,T2A,5,160,-79,UL,22Mbps,STA63,T1L,5,160,-79,UL,22Mbps,STA64,T2O,5,160,-79,UL,11Mbps,STA65
|
||||||
P2,5,Yes,R1,P3PRXBETH005,6G,LPI,T2A,133,160,-79,UL,22Mbps,STA63,T1L,133,160,-79,UL,22Mbps,STA64,T2O,133,160,-79,UL,11Mbps,STA65
|
P2,5,Yes,R1,P3PRXBETH005,6G,LPI,T2A,133,160,-79,UL,22Mbps,STA63,T1L,133,160,-79,UL,22Mbps,STA64,T2O,133,160,-79,UL,11Mbps,STA65
|
||||||
P2,6,Yes,R1,P3PRXBETH006,6G,LPI,T2A,197,160,-79,UL,22Mbps,STA63,T1L,197,160,-79,UL,22Mbps,STA64,T2O,197,160,-79,UL,11Mbps,STA65
|
P2,6,Yes,R1,P3PRXBETH006,6G,LPI,T2A,197,160,-79,UL,22Mbps,STA63,T1L,197,160,-79,UL,22Mbps,STA64,T2O,197,160,-79,UL,11Mbps,STA65
|
||||||
P2,7,Yes,R2,P3PRXBETH007,2G,LPI,T3E,6,20,-70,UL,22Mbps,STA63,T1P,6,20,-70,UL,22Mbps,STA64,T2Q,6,20,-70,UL,11Mbps,STA65
|
|
||||||
P2,8,Yes,R1,P3PRXBETH008,6G,SP,T2A,5,320,-79,UL,22Mbps,STA63,T1L,5,320,-79,UL,22Mbps,STA64,T2O,5,320,-79,UL,11Mbps,STA65
|
|
||||||
P2,9,Yes,R1,P3PRXBETH009,6G,LPI,T2A,133,320,-79,UL,22Mbps,STA63,T1L,133,320,-79,UL,22Mbps,STA64,T2O,133,320,-79,UL,11Mbps,STA65
|
P2,9,Yes,R1,P3PRXBETH009,6G,LPI,T2A,133,320,-79,UL,22Mbps,STA63,T1L,133,320,-79,UL,22Mbps,STA64,T2O,133,320,-79,UL,11Mbps,STA65
|
||||||
P2,1,No,R3,P3PRXBEUT001,5G,LPI,T1F,36,80,-76,UL,Unlimited,STA63,T1I,36,80,-76,UL,Unlimited,STA64,T2J,36,80,-76,UL,Unlimited,STA65
|
|
||||||
P2,2,No,R3,P3PRXBEUT002,5G,LPI,T1F,100,80,-76,UL,Unlimited,STA63,T1I,100,80,-76,UL,Unlimited,STA64,T2J,100,80,-76,UL,Unlimited,STA65
|
|
||||||
P2,3,No,R3,P3PRXBEUT003,5G,LPI,T1F,161,80,-76,UL,Unlimited,STA63,T1I,161,80,-76,UL,Unlimited,STA64,T2J,161,80,-76,UL,Unlimited,STA65
|
|
||||||
P2,4,No,R1,P3PRXBEUT004,6G,LPI,T2A,5,160,-79,UL,Unlimited,STA63,T1L,5,160,-79,UL,Unlimited,STA64,T2O,5,160,-79,UL,Unlimited,STA65
|
P2,4,No,R1,P3PRXBEUT004,6G,LPI,T2A,5,160,-79,UL,Unlimited,STA63,T1L,5,160,-79,UL,Unlimited,STA64,T2O,5,160,-79,UL,Unlimited,STA65
|
||||||
P2,5,No,R1,P3PRXBEUT005,6G,LPI,T2A,133,160,-79,UL,Unlimited,STA63,T1L,133,160,-79,UL,Unlimited,STA64,T2O,133,160,-79,UL,Unlimited,STA65
|
P2,5,No,R1,P3PRXBEUT005,6G,LPI,T2A,133,160,-79,UL,Unlimited,STA63,T1L,133,160,-79,UL,Unlimited,STA64,T2O,133,160,-79,UL,Unlimited,STA65
|
||||||
P2,6,No,R1,P3PRXBEUT006,6G,LPI,T2A,197,160,-79,UL,Unlimited,STA63,T1L,197,160,-79,UL,Unlimited,STA64,T2O,197,160,-79,UL,Unlimited,STA65
|
P2,6,No,R1,P3PRXBEUT006,6G,LPI,T2A,197,160,-79,UL,Unlimited,STA63,T1L,197,160,-79,UL,Unlimited,STA64,T2O,197,160,-79,UL,Unlimited,STA65
|
||||||
P2,7,No,R2,P3PRXBEUT007,2G,LPI,T3E,6,20,-70,UL,Unlimited,STA63,T1P,6,20,-70,UL,Unlimited,STA64,T2Q,6,20,-70,UL,Unlimited,STA65
|
|
||||||
P2,8,No,R1,P3PRXBEUT008,6G,SP,T2A,5,320,-79,UL,Unlimited,STA63,T1L,5,320,-79,UL,Unlimited,STA64,T2O,5,320,-79,UL,Unlimited,STA65
|
|
||||||
P2,9,No,R1,P3PRXBEUT009,6G,LPI,T2A,133,320,-79,UL,Unlimited,STA63,T1L,133,320,-79,UL,Unlimited,STA64,T2O,133,320,-79,UL,Unlimited,STA65
|
P2,9,No,R1,P3PRXBEUT009,6G,LPI,T2A,133,320,-79,UL,Unlimited,STA63,T1L,133,320,-79,UL,Unlimited,STA64,T2O,133,320,-79,UL,Unlimited,STA65
|
||||||
|
P2,4,Yes,R1,P3PTXBETH004,6G,LPI,T2A,5,160,-79,DL,22Mbps,STA63,T1L,5,160,-79,DL,22Mbps,STA64,T2O,5,160,-79,DL,11Mbps,STA65
|
||||||
|
P2,5,Yes,R1,P3PTXBETH005,6G,LPI,T2A,133,160,-79,DL,22Mbps,STA63,T1L,133,160,-79,DL,22Mbps,STA64,T2O,133,160,-79,DL,11Mbps,STA65
|
||||||
|
P2,6,Yes,R1,P3PTXBETH006,6G,LPI,T2A,197,160,-79,DL,22Mbps,STA63,T1L,197,160,-79,DL,22Mbps,STA64,T2O,197,160,-79,DL,11Mbps,STA65
|
||||||
|
P2,9,Yes,R1,P3PTXBETH009,6G,LPI,T2A,133,320,-79,DL,22Mbps,STA63,T1L,133,320,-79,DL,22Mbps,STA64,T2O,133,320,-79,DL,11Mbps,STA65
|
||||||
|
P2,4,No,R1,P3PTXBEUT004,6G,LPI,T2A,5,160,-79,DL,Unlimited,STA63,T1L,5,160,-79,DL,Unlimited,STA64,T2O,5,160,-79,DL,Unlimited,STA65
|
||||||
|
P2,5,No,R1,P3PTXBEUT005,6G,LPI,T2A,133,160,-79,DL,Unlimited,STA63,T1L,133,160,-79,DL,Unlimited,STA64,T2O,133,160,-79,DL,Unlimited,STA65
|
||||||
|
P2,6,No,R1,P3PTXBEUT006,6G,LPI,T2A,197,160,-79,DL,Unlimited,STA63,T1L,197,160,-79,DL,Unlimited,STA64,T2O,197,160,-79,DL,Unlimited,STA65
|
||||||
|
P2,9,No,R1,P3PTXBEUT009,6G,LPI,T2A,133,320,-79,DL,Unlimited,STA63,T1L,133,320,-79,DL,Unlimited,STA64,T2O,133,320,-79,DL,Unlimited,STA65
|
||||||
P2,1,Yes,R1,P3PRXAXTH001,5G,LPI,T1F,36,80,-76,UL,22Mbps,STA56,T1I,36,80,-76,UL,22Mbps,STA58,T2J,36,80,-76,UL,11Mbps,STA59
|
P2,1,Yes,R1,P3PRXAXTH001,5G,LPI,T1F,36,80,-76,UL,22Mbps,STA56,T1I,36,80,-76,UL,22Mbps,STA58,T2J,36,80,-76,UL,11Mbps,STA59
|
||||||
P2,2,Yes,R1,P3PRXAXTH002,5G,LPI,T1F,100,80,-76,UL,22Mbps,STA56,T1I,100,80,-76,UL,22Mbps,STA58,T2J,100,80,-76,UL,11Mbps,STA59
|
P2,2,Yes,R1,P3PRXAXTH002,5G,LPI,T1F,100,80,-76,UL,22Mbps,STA56,T1I,100,80,-76,UL,22Mbps,STA58,T2J,100,80,-76,UL,11Mbps,STA59
|
||||||
P2,3,Yes,R1,P3PRXAXTH003,5G,LPI,T1F,161,80,-76,UL,22Mbps,STA56,T1I,161,80,-76,UL,22Mbps,STA58,T2J,161,80,-76,UL,11Mbps,STA59
|
P2,3,Yes,R1,P3PRXAXTH003,5G,LPI,T1F,161,80,-76,UL,22Mbps,STA56,T1I,161,80,-76,UL,22Mbps,STA58,T2J,161,80,-76,UL,11Mbps,STA59
|
||||||
P2,4,Yes,R2,P3PRXAXTH004,6G,LPI,T2A,5,160,-79,UL,22Mbps,STA56,T1L,5,160,-79,UL,22Mbps,STA58,T2O,5,160,-79,UL,11Mbps,STA59
|
|
||||||
P2,5,Yes,R2,P3PRXAXTH005,6G,LPI,T2A,133,160,-79,UL,22Mbps,STA56,T1L,133,160,-79,UL,22Mbps,STA58,T2O,133,160,-79,UL,11Mbps,STA59
|
|
||||||
P2,6,Yes,R2,P3PRXAXTH006,6G,LPI,T2A,197,160,-79,UL,22Mbps,STA56,T1L,197,160,-79,UL,22Mbps,STA58,T2O,197,160,-79,UL,11Mbps,STA59
|
|
||||||
P2,7,Yes,R3,P3PRXAXTH007,2G,LPI,T3E,6,20,-70,UL,22Mbps,STA56,T1P,6,20,-70,UL,22Mbps,STA58,T2Q,6,20,-70,UL,11Mbps,STA59
|
|
||||||
P2,8,Yes,R2,P3PRXAXTH008,6G,SP,T2A,5,320,-79,UL,22Mbps,STA56,T1L,5,320,-79,UL,22Mbps,STA58,T2O,5,320,-79,UL,11Mbps,STA59
|
|
||||||
P2,9,Yes,R2,P3PRXAXTH009,6G,LPI,T2A,133,320,-79,UL,22Mbps,STA56,T1L,133,320,-79,UL,22Mbps,STA58,T2O,133,320,-79,UL,11Mbps,STA59
|
|
||||||
P2,1,No,R1,P3PRXAXUT001,5G,LPI,T1F,36,80,-76,UL,Unlimited,STA56,T1I,36,80,-76,UL,Unlimited,STA58,T2J,36,80,-76,UL,Unlimited,STA59
|
P2,1,No,R1,P3PRXAXUT001,5G,LPI,T1F,36,80,-76,UL,Unlimited,STA56,T1I,36,80,-76,UL,Unlimited,STA58,T2J,36,80,-76,UL,Unlimited,STA59
|
||||||
P2,2,No,R1,P3PRXAXUT002,5G,LPI,T1F,100,80,-76,UL,Unlimited,STA56,T1I,100,80,-76,UL,Unlimited,STA58,T2J,100,80,-76,UL,Unlimited,STA59
|
P2,2,No,R1,P3PRXAXUT002,5G,LPI,T1F,100,80,-76,UL,Unlimited,STA56,T1I,100,80,-76,UL,Unlimited,STA58,T2J,100,80,-76,UL,Unlimited,STA59
|
||||||
P2,3,No,R1,P3PRXAXUT003,5G,LPI,T1F,161,80,-76,UL,Unlimited,STA56,T1I,161,80,-76,UL,Unlimited,STA58,T2J,161,80,-76,UL,Unlimited,STA59
|
P2,3,No,R1,P3PRXAXUT003,5G,LPI,T1F,161,80,-76,UL,Unlimited,STA56,T1I,161,80,-76,UL,Unlimited,STA58,T2J,161,80,-76,UL,Unlimited,STA59
|
||||||
P2,4,No,R2,P3PRXAXUT004,6G,LPI,T2A,5,160,-79,UL,Unlimited,STA56,T1L,5,160,-79,UL,Unlimited,STA58,T2O,5,160,-79,UL,Unlimited,STA59
|
|
||||||
P2,5,No,R2,P3PRXAXUT005,6G,LPI,T2A,133,160,-79,UL,Unlimited,STA56,T1L,133,160,-79,UL,Unlimited,STA58,T2O,133,160,-79,UL,Unlimited,STA59
|
|
||||||
P2,6,No,R2,P3PRXAXUT006,6G,LPI,T2A,197,160,-79,UL,Unlimited,STA56,T1L,197,160,-79,UL,Unlimited,STA58,T2O,197,160,-79,UL,Unlimited,STA59
|
|
||||||
P2,7,No,R3,P3PRXAXUT007,2G,LPI,T3E,6,20,-70,UL,Unlimited,STA56,T1P,6,20,-70,UL,Unlimited,STA58,T2Q,6,20,-70,UL,Unlimited,STA59
|
|
||||||
P2,8,No,R2,P3PRXAXUT008,6G,SP,T2A,5,320,-79,UL,Unlimited,STA56,T1L,5,320,-79,UL,Unlimited,STA58,T2O,5,320,-79,UL,Unlimited,STA59
|
|
||||||
P2,9,No,R2,P3PRXAXUT009,6G,LPI,T2A,133,320,-79,UL,Unlimited,STA56,T1L,133,320,-79,UL,Unlimited,STA58,T2O,133,320,-79,UL,Unlimited,STA59
|
|
||||||
P2,1,Yes,R1,P3PTXAXTH001,5G,LPI,T1F,36,80,-76,DL,22Mbps,STA56,T1I,36,80,-76,DL,22Mbps,STA58,T2J,36,80,-76,DL,11Mbps,STA59
|
P2,1,Yes,R1,P3PTXAXTH001,5G,LPI,T1F,36,80,-76,DL,22Mbps,STA56,T1I,36,80,-76,DL,22Mbps,STA58,T2J,36,80,-76,DL,11Mbps,STA59
|
||||||
P2,2,Yes,R1,P3PTXAXTH002,5G,LPI,T1F,100,80,-76,DL,22Mbps,STA56,T1I,100,80,-76,DL,22Mbps,STA58,T2J,100,80,-76,DL,11Mbps,STA59
|
P2,2,Yes,R1,P3PTXAXTH002,5G,LPI,T1F,100,80,-76,DL,22Mbps,STA56,T1I,100,80,-76,DL,22Mbps,STA58,T2J,100,80,-76,DL,11Mbps,STA59
|
||||||
P2,3,Yes,R1,P3PTXAXTH003,5G,LPI,T1F,161,80,-76,DL,22Mbps,STA56,T1I,161,80,-76,DL,22Mbps,STA58,T2J,161,80,-76,DL,11Mbps,STA59
|
P2,3,Yes,R1,P3PTXAXTH003,5G,LPI,T1F,161,80,-76,DL,22Mbps,STA56,T1I,161,80,-76,DL,22Mbps,STA58,T2J,161,80,-76,DL,11Mbps,STA59
|
||||||
P2,4,Yes,R2,P3PTXAXTH004,6G,LPI,T2A,5,160,-79,DL,22Mbps,STA56,T1L,5,160,-79,DL,22Mbps,STA58,T2O,5,160,-79,DL,11Mbps,STA59
|
|
||||||
P2,5,Yes,R2,P3PTXAXTH005,6G,LPI,T2A,133,160,-79,DL,22Mbps,STA56,T1L,133,160,-79,DL,22Mbps,STA58,T2O,133,160,-79,DL,11Mbps,STA59
|
|
||||||
P2,6,Yes,R2,P3PTXAXTH006,6G,LPI,T2A,197,160,-79,DL,22Mbps,STA56,T1L,197,160,-79,DL,22Mbps,STA58,T2O,197,160,-79,DL,11Mbps,STA59
|
|
||||||
P2,7,Yes,R3,P3PTXAXTH007,2G,LPI,T3E,6,20,-70,DL,22Mbps,STA56,T1P,6,20,-70,DL,22Mbps,STA58,T2Q,6,20,-70,DL,11Mbps,STA59
|
|
||||||
P2,8,Yes,R2,P3PTXAXTH008,6G,SP,T2A,5,320,-79,DL,22Mbps,STA56,T1L,5,320,-79,DL,22Mbps,STA58,T2O,5,320,-79,DL,11Mbps,STA59
|
|
||||||
P2,9,Yes,R2,P3PTXAXTH009,6G,LPI,T2A,133,320,-79,DL,22Mbps,STA56,T1L,133,320,-79,DL,22Mbps,STA58,T2O,133,320,-79,DL,11Mbps,STA59
|
|
||||||
P2,1,No,R1,P3PTXAXUT001,5G,LPI,T1F,36,80,-76,DL,Unlimited,STA56,T1I,36,80,-76,DL,Unlimited,STA58,T2J,36,80,-76,DL,Unlimited,STA59
|
P2,1,No,R1,P3PTXAXUT001,5G,LPI,T1F,36,80,-76,DL,Unlimited,STA56,T1I,36,80,-76,DL,Unlimited,STA58,T2J,36,80,-76,DL,Unlimited,STA59
|
||||||
P2,2,No,R1,P3PTXAXUT002,5G,LPI,T1F,100,80,-76,DL,Unlimited,STA56,T1I,100,80,-76,DL,Unlimited,STA58,T2J,100,80,-76,DL,Unlimited,STA59
|
P2,2,No,R1,P3PTXAXUT002,5G,LPI,T1F,100,80,-76,DL,Unlimited,STA56,T1I,100,80,-76,DL,Unlimited,STA58,T2J,100,80,-76,DL,Unlimited,STA59
|
||||||
P2,3,No,R1,P3PTXAXUT003,5G,LPI,T1F,161,80,-76,DL,Unlimited,STA56,T1I,161,80,-76,DL,Unlimited,STA58,T2J,161,80,-76,DL,Unlimited,STA59
|
P2,3,No,R1,P3PTXAXUT003,5G,LPI,T1F,161,80,-76,DL,Unlimited,STA56,T1I,161,80,-76,DL,Unlimited,STA58,T2J,161,80,-76,DL,Unlimited,STA59
|
||||||
|
P2,4,Yes,R1,P3PRXACTH004,2G,LPI,T3E,6,20,-70,UL,22Mbps,STA4,T1P,6,20,-70,UL,22Mbps,STA5,T2Q,6,20,-70,UL,11Mbps,STA6
|
||||||
|
P2,4,No,R1,P3PRXACUT004,2G,LPI,T3E,6,20,-70,UL,Unlimited,STA4,T1P,6,20,-70,UL,Unlimited,STA5,T2Q,6,20,-70,UL,Unlimited,STA6
|
||||||
|
P2,4,Yes,R1,P3PTXACTH004,2G,LPI,T3E,6,20,-70,DL,22Mbps,STA4,T1P,6,20,-70,DL,22Mbps,STA5,T2Q,6,20,-70,DL,11Mbps,STA6
|
||||||
|
P2,4,No,R1,P3PTXACUT004,2G,LPI,T3E,6,20,-70,DL,Unlimited,STA4,T1P,6,20,-70,DL,Unlimited,STA5,T2Q,6,20,-70,DL,Unlimited,STA6
|
||||||
|
P2,7,Yes,R2,P3PRXBETH007,2G,LPI,T3E,6,20,-70,UL,22Mbps,STA63,T1P,6,20,-70,UL,22Mbps,STA64,T2Q,6,20,-70,UL,11Mbps,STA65
|
||||||
|
P2,7,No,R2,P3PRXBEUT007,2G,LPI,T3E,6,20,-70,UL,Unlimited,STA63,T1P,6,20,-70,UL,Unlimited,STA64,T2Q,6,20,-70,UL,Unlimited,STA65
|
||||||
|
P2,7,Yes,R2,P3PTXBETH007,2G,LPI,T3E,6,20,-70,DL,22Mbps,STA63,T1P,6,20,-70,DL,22Mbps,STA64,T2Q,6,20,-70,DL,11Mbps,STA65
|
||||||
|
P2,7,No,R2,P3PTXBEUT007,2G,LPI,T3E,6,20,-70,DL,Unlimited,STA63,T1P,6,20,-70,DL,Unlimited,STA64,T2Q,6,20,-70,DL,Unlimited,STA65
|
||||||
|
P2,4,Yes,R2,P3PRXAXTH004,6G,LPI,T2A,5,160,-79,UL,22Mbps,STA56,T1L,5,160,-79,UL,22Mbps,STA58,T2O,5,160,-79,UL,11Mbps,STA59
|
||||||
|
P2,5,Yes,R2,P3PRXAXTH005,6G,LPI,T2A,133,160,-79,UL,22Mbps,STA56,T1L,133,160,-79,UL,22Mbps,STA58,T2O,133,160,-79,UL,11Mbps,STA59
|
||||||
|
P2,6,Yes,R2,P3PRXAXTH006,6G,LPI,T2A,197,160,-79,UL,22Mbps,STA56,T1L,197,160,-79,UL,22Mbps,STA58,T2O,197,160,-79,UL,11Mbps,STA59
|
||||||
|
P2,9,Yes,R2,P3PRXAXTH009,6G,LPI,T2A,133,320,-79,UL,22Mbps,STA56,T1L,133,320,-79,UL,22Mbps,STA58,T2O,133,320,-79,UL,11Mbps,STA59
|
||||||
|
P2,4,No,R2,P3PRXAXUT004,6G,LPI,T2A,5,160,-79,UL,Unlimited,STA56,T1L,5,160,-79,UL,Unlimited,STA58,T2O,5,160,-79,UL,Unlimited,STA59
|
||||||
|
P2,5,No,R2,P3PRXAXUT005,6G,LPI,T2A,133,160,-79,UL,Unlimited,STA56,T1L,133,160,-79,UL,Unlimited,STA58,T2O,133,160,-79,UL,Unlimited,STA59
|
||||||
|
P2,6,No,R2,P3PRXAXUT006,6G,LPI,T2A,197,160,-79,UL,Unlimited,STA56,T1L,197,160,-79,UL,Unlimited,STA58,T2O,197,160,-79,UL,Unlimited,STA59
|
||||||
|
P2,9,No,R2,P3PRXAXUT009,6G,LPI,T2A,133,320,-79,UL,Unlimited,STA56,T1L,133,320,-79,UL,Unlimited,STA58,T2O,133,320,-79,UL,Unlimited,STA59
|
||||||
|
P2,4,Yes,R2,P3PTXAXTH004,6G,LPI,T2A,5,160,-79,DL,22Mbps,STA56,T1L,5,160,-79,DL,22Mbps,STA58,T2O,5,160,-79,DL,11Mbps,STA59
|
||||||
|
P2,5,Yes,R2,P3PTXAXTH005,6G,LPI,T2A,133,160,-79,DL,22Mbps,STA56,T1L,133,160,-79,DL,22Mbps,STA58,T2O,133,160,-79,DL,11Mbps,STA59
|
||||||
|
P2,6,Yes,R2,P3PTXAXTH006,6G,LPI,T2A,197,160,-79,DL,22Mbps,STA56,T1L,197,160,-79,DL,22Mbps,STA58,T2O,197,160,-79,DL,11Mbps,STA59
|
||||||
|
P2,9,Yes,R2,P3PTXAXTH009,6G,LPI,T2A,133,320,-79,DL,22Mbps,STA56,T1L,133,320,-79,DL,22Mbps,STA58,T2O,133,320,-79,DL,11Mbps,STA59
|
||||||
P2,4,No,R2,P3PTXAXUT004,6G,LPI,T2A,5,160,-79,DL,Unlimited,STA56,T1L,5,160,-79,DL,Unlimited,STA58,T2O,5,160,-79,DL,Unlimited,STA59
|
P2,4,No,R2,P3PTXAXUT004,6G,LPI,T2A,5,160,-79,DL,Unlimited,STA56,T1L,5,160,-79,DL,Unlimited,STA58,T2O,5,160,-79,DL,Unlimited,STA59
|
||||||
P2,5,No,R2,P3PTXAXUT005,6G,LPI,T2A,133,160,-79,DL,Unlimited,STA56,T1L,133,160,-79,DL,Unlimited,STA58,T2O,133,160,-79,DL,Unlimited,STA59
|
P2,5,No,R2,P3PTXAXUT005,6G,LPI,T2A,133,160,-79,DL,Unlimited,STA56,T1L,133,160,-79,DL,Unlimited,STA58,T2O,133,160,-79,DL,Unlimited,STA59
|
||||||
P2,6,No,R2,P3PTXAXUT006,6G,LPI,T2A,197,160,-79,DL,Unlimited,STA56,T1L,197,160,-79,DL,Unlimited,STA58,T2O,197,160,-79,DL,Unlimited,STA59
|
P2,6,No,R2,P3PTXAXUT006,6G,LPI,T2A,197,160,-79,DL,Unlimited,STA56,T1L,197,160,-79,DL,Unlimited,STA58,T2O,197,160,-79,DL,Unlimited,STA59
|
||||||
P2,7,No,R3,P3PTXAXUT007,2G,LPI,T3E,6,20,-70,DL,Unlimited,STA56,T1P,6,20,-70,DL,Unlimited,STA58,T2Q,6,20,-70,DL,Unlimited,STA59
|
|
||||||
P2,8,No,R2,P3PTXAXUT008,6G,SP,T2A,5,320,-79,DL,Unlimited,STA56,T1L,5,320,-79,DL,Unlimited,STA58,T2O,5,320,-79,DL,Unlimited,STA59
|
|
||||||
P2,9,No,R2,P3PTXAXUT009,6G,LPI,T2A,133,320,-79,DL,Unlimited,STA56,T1L,133,320,-79,DL,Unlimited,STA58,T2O,133,320,-79,DL,Unlimited,STA59
|
P2,9,No,R2,P3PTXAXUT009,6G,LPI,T2A,133,320,-79,DL,Unlimited,STA56,T1L,133,320,-79,DL,Unlimited,STA58,T2O,133,320,-79,DL,Unlimited,STA59
|
||||||
P2,1,Yes,R2,P3PRXACTH001,5G,LPI,T1F,36,80,-76,UL,22Mbps,STA4,T1I,36,80,-76,UL,22Mbps,STA5,T2J,36,80,-76,UL,11Mbps,STA6
|
P2,1,Yes,R2,P3PRXACTH001,5G,LPI,T1F,36,80,-76,UL,22Mbps,STA4,T1I,36,80,-76,UL,22Mbps,STA5,T2J,36,80,-76,UL,11Mbps,STA6
|
||||||
P2,2,Yes,R2,P3PRXACTH002,5G,LPI,T1F,100,80,-76,UL,22Mbps,STA4,T1I,100,80,-76,UL,22Mbps,STA5,T2J,100,80,-76,UL,11Mbps,STA6
|
P2,2,Yes,R2,P3PRXACTH002,5G,LPI,T1F,100,80,-76,UL,22Mbps,STA4,T1I,100,80,-76,UL,22Mbps,STA5,T2J,100,80,-76,UL,11Mbps,STA6
|
||||||
P2,3,Yes,R2,P3PRXACTH003,5G,LPI,T1F,161,80,-76,UL,22Mbps,STA4,T1I,161,80,-76,UL,22Mbps,STA5,T2J,161,80,-76,UL,11Mbps,STA6
|
P2,3,Yes,R2,P3PRXACTH003,5G,LPI,T1F,161,80,-76,UL,22Mbps,STA4,T1I,161,80,-76,UL,22Mbps,STA5,T2J,161,80,-76,UL,11Mbps,STA6
|
||||||
P2,4,Yes,R1,P3PRXACTH004,2G,LPI,T3E,6,20,-70,UL,22Mbps,STA4,T1P,6,20,-70,UL,22Mbps,STA5,T2Q,6,20,-70,UL,11Mbps,STA6
|
|
||||||
P2,1,No,R2,P3PRXACUT001,5G,LPI,T1F,36,80,-76,UL,Unlimited,STA4,T1I,36,80,-76,UL,Unlimited,STA5,T2J,36,80,-76,UL,Unlimited,STA6
|
P2,1,No,R2,P3PRXACUT001,5G,LPI,T1F,36,80,-76,UL,Unlimited,STA4,T1I,36,80,-76,UL,Unlimited,STA5,T2J,36,80,-76,UL,Unlimited,STA6
|
||||||
P2,2,No,R2,P3PRXACUT002,5G,LPI,T1F,100,80,-76,UL,Unlimited,STA4,T1I,100,80,-76,UL,Unlimited,STA5,T2J,100,80,-76,UL,Unlimited,STA6
|
P2,2,No,R2,P3PRXACUT002,5G,LPI,T1F,100,80,-76,UL,Unlimited,STA4,T1I,100,80,-76,UL,Unlimited,STA5,T2J,100,80,-76,UL,Unlimited,STA6
|
||||||
P2,3,No,R2,P3PRXACUT003,5G,LPI,T1F,161,80,-76,UL,Unlimited,STA4,T1I,161,80,-76,UL,Unlimited,STA5,T2J,161,80,-76,UL,Unlimited,STA6
|
P2,3,No,R2,P3PRXACUT003,5G,LPI,T1F,161,80,-76,UL,Unlimited,STA4,T1I,161,80,-76,UL,Unlimited,STA5,T2J,161,80,-76,UL,Unlimited,STA6
|
||||||
P2,4,No,R1,P3PRXACUT004,2G,LPI,T3E,6,20,-70,UL,Unlimited,STA4,T1P,6,20,-70,UL,Unlimited,STA5,T2Q,6,20,-70,UL,Unlimited,STA6
|
|
||||||
P2,1,Yes,R2,P3PTXACTH001,5G,LPI,T1F,36,80,-76,DL,22Mbps,STA4,T1I,36,80,-76,DL,22Mbps,STA5,T2J,36,80,-76,DL,11Mbps,STA6
|
P2,1,Yes,R2,P3PTXACTH001,5G,LPI,T1F,36,80,-76,DL,22Mbps,STA4,T1I,36,80,-76,DL,22Mbps,STA5,T2J,36,80,-76,DL,11Mbps,STA6
|
||||||
P2,2,Yes,R2,P3PTXACTH002,5G,LPI,T1F,100,80,-76,DL,22Mbps,STA4,T1I,100,80,-76,DL,22Mbps,STA5,T2J,100,80,-76,DL,11Mbps,STA6
|
P2,2,Yes,R2,P3PTXACTH002,5G,LPI,T1F,100,80,-76,DL,22Mbps,STA4,T1I,100,80,-76,DL,22Mbps,STA5,T2J,100,80,-76,DL,11Mbps,STA6
|
||||||
P2,3,Yes,R2,P3PTXACTH003,5G,LPI,T1F,161,80,-76,DL,22Mbps,STA4,T1I,161,80,-76,DL,22Mbps,STA5,T2J,161,80,-76,DL,11Mbps,STA6
|
P2,3,Yes,R2,P3PTXACTH003,5G,LPI,T1F,161,80,-76,DL,22Mbps,STA4,T1I,161,80,-76,DL,22Mbps,STA5,T2J,161,80,-76,DL,11Mbps,STA6
|
||||||
P2,4,Yes,R1,P3PTXACTH004,2G,LPI,T3E,6,20,-70,DL,22Mbps,STA4,T1P,6,20,-70,DL,22Mbps,STA5,T2Q,6,20,-70,DL,11Mbps,STA6
|
|
||||||
P2,1,No,R2,P3PTXACUT001,5G,LPI,T1F,36,80,-76,DL,Unlimited,STA4,T1I,36,80,-76,DL,Unlimited,STA5,T2J,36,80,-76,DL,Unlimited,STA6
|
P2,1,No,R2,P3PTXACUT001,5G,LPI,T1F,36,80,-76,DL,Unlimited,STA4,T1I,36,80,-76,DL,Unlimited,STA5,T2J,36,80,-76,DL,Unlimited,STA6
|
||||||
P2,2,No,R2,P3PTXACUT002,5G,LPI,T1F,100,80,-76,DL,Unlimited,STA4,T1I,100,80,-76,DL,Unlimited,STA5,T2J,100,80,-76,DL,Unlimited,STA6
|
P2,2,No,R2,P3PTXACUT002,5G,LPI,T1F,100,80,-76,DL,Unlimited,STA4,T1I,100,80,-76,DL,Unlimited,STA5,T2J,100,80,-76,DL,Unlimited,STA6
|
||||||
P2,3,No,R2,P3PTXACUT003,5G,LPI,T1F,161,80,-76,DL,Unlimited,STA4,T1I,161,80,-76,DL,Unlimited,STA5,T2J,161,80,-76,DL,Unlimited,STA6
|
P2,3,No,R2,P3PTXACUT003,5G,LPI,T1F,161,80,-76,DL,Unlimited,STA4,T1I,161,80,-76,DL,Unlimited,STA5,T2J,161,80,-76,DL,Unlimited,STA6
|
||||||
P2,4,No,R1,P3PTXACUT004,2G,LPI,T3E,6,20,-70,DL,Unlimited,STA4,T1P,6,20,-70,DL,Unlimited,STA5,T2Q,6,20,-70,DL,Unlimited,STA6
|
P2,1,Yes,R3,P3PRXBETH001,5G,LPI,T1F,36,80,-76,UL,22Mbps,STA63,T1I,36,80,-76,UL,22Mbps,STA64,T2J,36,80,-76,UL,11Mbps,STA65
|
||||||
|
P2,2,Yes,R3,P3PRXBETH002,5G,LPI,T1F,100,80,-76,UL,22Mbps,STA63,T1I,100,80,-76,UL,22Mbps,STA64,T2J,100,80,-76,UL,11Mbps,STA65
|
||||||
|
P2,3,Yes,R3,P3PRXBETH003,5G,LPI,T1F,161,80,-76,UL,22Mbps,STA63,T1I,161,80,-76,UL,22Mbps,STA64,T2J,161,80,-76,UL,11Mbps,STA65
|
||||||
|
P2,1,No,R3,P3PRXBEUT001,5G,LPI,T1F,36,80,-76,UL,Unlimited,STA63,T1I,36,80,-76,UL,Unlimited,STA64,T2J,36,80,-76,UL,Unlimited,STA65
|
||||||
|
P2,2,No,R3,P3PRXBEUT002,5G,LPI,T1F,100,80,-76,UL,Unlimited,STA63,T1I,100,80,-76,UL,Unlimited,STA64,T2J,100,80,-76,UL,Unlimited,STA65
|
||||||
|
P2,3,No,R3,P3PRXBEUT003,5G,LPI,T1F,161,80,-76,UL,Unlimited,STA63,T1I,161,80,-76,UL,Unlimited,STA64,T2J,161,80,-76,UL,Unlimited,STA65
|
||||||
|
P2,1,Yes,R3,P3PTXBETH001,5G,LPI,T1F,36,80,-76,DL,22Mbps,STA63,T1I,36,80,-76,DL,22Mbps,STA64,T2J,36,80,-76,DL,11Mbps,STA65
|
||||||
|
P2,2,Yes,R3,P3PTXBETH002,5G,LPI,T1F,100,80,-76,DL,22Mbps,STA63,T1I,100,80,-76,DL,22Mbps,STA64,T2J,100,80,-76,DL,11Mbps,STA65
|
||||||
|
P2,3,Yes,R3,P3PTXBETH003,5G,LPI,T1F,161,80,-76,DL,22Mbps,STA63,T1I,161,80,-76,DL,22Mbps,STA64,T2J,161,80,-76,DL,11Mbps,STA65
|
||||||
|
P2,1,No,R3,P3PTXBEUT001,5G,LPI,T1F,36,80,-76,DL,Unlimited,STA63,T1I,36,80,-76,DL,Unlimited,STA64,T2J,36,80,-76,DL,Unlimited,STA65
|
||||||
|
P2,2,No,R3,P3PTXBEUT002,5G,LPI,T1F,100,80,-76,DL,Unlimited,STA63,T1I,100,80,-76,DL,Unlimited,STA64,T2J,100,80,-76,DL,Unlimited,STA65
|
||||||
|
P2,3,No,R3,P3PTXBEUT003,5G,LPI,T1F,161,80,-76,DL,Unlimited,STA63,T1I,161,80,-76,DL,Unlimited,STA64,T2J,161,80,-76,DL,Unlimited,STA65
|
||||||
|
P2,7,Yes,R3,P3PRXAXTH007,2G,LPI,T1D,6,20,-70,UL,22Mbps,STA56,T1P,6,20,-70,UL,22Mbps,STA58,T2Q,6,20,-70,UL,11Mbps,STA59
|
||||||
|
P2,7,No,R3,P3PRXAXUT007,2G,LPI,T1D,6,20,-70,UL,Unlimited,STA56,T1P,6,20,-70,UL,Unlimited,STA58,T2Q,6,20,-70,UL,Unlimited,STA59
|
||||||
|
P2,7,Yes,R3,P3PTXAXTH007,2G,LPI,T1D,6,20,-70,DL,22Mbps,STA56,T1P,6,20,-70,DL,22Mbps,STA58,T2Q,6,20,-70,DL,11Mbps,STA59
|
||||||
|
P2,7,No,R3,P3PTXAXUT007,2G,LPI,T1D,6,20,-70,DL,Unlimited,STA56,T1P,6,20,-70,DL,Unlimited,STA58,T2Q,6,20,-70,DL,Unlimited,STA59
|
||||||
|
|||||||
|
+24
-6
@@ -31,6 +31,7 @@ class TestRecord:
|
|||||||
priority: int
|
priority: int
|
||||||
victim_band: str | None
|
victim_band: str | None
|
||||||
config: dict[str, dict[str, str | None]]
|
config: dict[str, dict[str, str | None]]
|
||||||
|
throttled: bool
|
||||||
estimated_minutes: int
|
estimated_minutes: int
|
||||||
status: str = "pending"
|
status: str = "pending"
|
||||||
excluded: bool = False
|
excluded: bool = False
|
||||||
@@ -81,6 +82,7 @@ def init_db(db_path: str | Path = DB_PATH) -> None:
|
|||||||
priority INTEGER NOT NULL CHECK (priority BETWEEN 1 AND 5),
|
priority INTEGER NOT NULL CHECK (priority BETWEEN 1 AND 5),
|
||||||
victim_band TEXT,
|
victim_band TEXT,
|
||||||
config_json TEXT,
|
config_json TEXT,
|
||||||
|
throttled INTEGER NOT NULL DEFAULT 0,
|
||||||
estimated_minutes INTEGER NOT NULL,
|
estimated_minutes INTEGER NOT NULL,
|
||||||
status TEXT NOT NULL CHECK (status IN ('pending', 'completed', 'failed', 'invalid')),
|
status TEXT NOT NULL CHECK (status IN ('pending', 'completed', 'failed', 'invalid')),
|
||||||
excluded INTEGER NOT NULL DEFAULT 0,
|
excluded INTEGER NOT NULL DEFAULT 0,
|
||||||
@@ -137,6 +139,7 @@ def init_db(db_path: str | Path = DB_PATH) -> None:
|
|||||||
_ensure_column(conn, "tests", "config_json", "TEXT")
|
_ensure_column(conn, "tests", "config_json", "TEXT")
|
||||||
_ensure_column(conn, "tests", "victim_band", "TEXT")
|
_ensure_column(conn, "tests", "victim_band", "TEXT")
|
||||||
_ensure_column(conn, "tests", "excluded", "INTEGER NOT NULL DEFAULT 0")
|
_ensure_column(conn, "tests", "excluded", "INTEGER NOT NULL DEFAULT 0")
|
||||||
|
_ensure_column(conn, "tests", "throttled", "INTEGER NOT NULL DEFAULT 0")
|
||||||
|
|
||||||
# Seed runtime defaults for schedule estimation.
|
# Seed runtime defaults for schedule estimation.
|
||||||
conn.execute(
|
conn.execute(
|
||||||
@@ -159,9 +162,9 @@ def upsert_tests(records: list[TestRecord], db_path: str | Path = DB_PATH) -> in
|
|||||||
"""
|
"""
|
||||||
INSERT INTO tests(
|
INSERT INTO tests(
|
||||||
test_id, device, test_type, rotation, rx_tx, has_coe_pair,
|
test_id, device, test_type, rotation, rx_tx, has_coe_pair,
|
||||||
coe_pairing_json, config_json, priority, victim_band, estimated_minutes, status, excluded, raw_payload
|
coe_pairing_json, config_json, priority, victim_band, throttled, estimated_minutes, status, excluded, raw_payload
|
||||||
)
|
)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
ON CONFLICT(test_id, device) DO UPDATE SET
|
ON CONFLICT(test_id, device) DO UPDATE SET
|
||||||
test_type = excluded.test_type,
|
test_type = excluded.test_type,
|
||||||
device = excluded.device,
|
device = excluded.device,
|
||||||
@@ -172,6 +175,7 @@ def upsert_tests(records: list[TestRecord], db_path: str | Path = DB_PATH) -> in
|
|||||||
config_json = excluded.config_json,
|
config_json = excluded.config_json,
|
||||||
priority = excluded.priority,
|
priority = excluded.priority,
|
||||||
victim_band = excluded.victim_band,
|
victim_band = excluded.victim_band,
|
||||||
|
throttled = excluded.throttled,
|
||||||
estimated_minutes = excluded.estimated_minutes,
|
estimated_minutes = excluded.estimated_minutes,
|
||||||
status = excluded.status,
|
status = excluded.status,
|
||||||
excluded = excluded.excluded,
|
excluded = excluded.excluded,
|
||||||
@@ -190,6 +194,7 @@ def upsert_tests(records: list[TestRecord], db_path: str | Path = DB_PATH) -> in
|
|||||||
json.dumps(r.config),
|
json.dumps(r.config),
|
||||||
r.priority,
|
r.priority,
|
||||||
r.victim_band,
|
r.victim_band,
|
||||||
|
int(r.throttled),
|
||||||
r.estimated_minutes,
|
r.estimated_minutes,
|
||||||
r.status,
|
r.status,
|
||||||
int(r.excluded),
|
int(r.excluded),
|
||||||
@@ -260,13 +265,24 @@ def _entry_value(entry: dict[str, str | None], key: str) -> str:
|
|||||||
return _normalize_text(entry.get(key) or entry.get(key.capitalize()) or entry.get(key.upper()))
|
return _normalize_text(entry.get(key) or entry.get(key.capitalize()) or entry.get(key.upper()))
|
||||||
|
|
||||||
|
|
||||||
|
def _record_power_mode(record: TestRecord) -> str:
|
||||||
|
power_mode = _entry_value(_band_entry(record.config, "6G"), "power_mode")
|
||||||
|
if power_mode:
|
||||||
|
return power_mode
|
||||||
|
|
||||||
|
raw_payload = record.raw_payload or {}
|
||||||
|
return _normalize_text(raw_payload.get("6GHz Power Mode"))
|
||||||
|
|
||||||
|
|
||||||
def _match_any_band_value(record: TestRecord, key: str, token_suffix: str) -> bool:
|
def _match_any_band_value(record: TestRecord, key: str, token_suffix: str) -> bool:
|
||||||
if not token_suffix:
|
if not token_suffix:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
target_num = _extract_signed_int(token_suffix)
|
target_num = _extract_signed_int(token_suffix)
|
||||||
target_compact = _normalize_compact(token_suffix)
|
target_compact = _normalize_compact(token_suffix)
|
||||||
for band in ("5G", "6G", "2G"):
|
keys = ("Station 1", "Station 2", "Station 3") if record.test_type == "P3P" else ("5G", "6G", "2G")
|
||||||
|
|
||||||
|
for band in keys:
|
||||||
entry = _band_entry(record.config, band)
|
entry = _band_entry(record.config, band)
|
||||||
value = _entry_value(entry, key)
|
value = _entry_value(entry, key)
|
||||||
if not value:
|
if not value:
|
||||||
@@ -289,7 +305,7 @@ def _matches_atomic_exclusion_token(record: TestRecord, token: str) -> bool:
|
|||||||
test_type = _normalize_text(record.test_type)
|
test_type = _normalize_text(record.test_type)
|
||||||
rotation = _normalize_text(record.rotation)
|
rotation = _normalize_text(record.rotation)
|
||||||
victim_band = _normalize_text(record.victim_band)
|
victim_band = _normalize_text(record.victim_band)
|
||||||
power_mode = _entry_value(_band_entry(record.config, "6G"), "power_mode")
|
power_mode = _record_power_mode(record)
|
||||||
known_devices = {_normalize_text(DUT), _normalize_text(REF)}
|
known_devices = {_normalize_text(DUT), _normalize_text(REF)}
|
||||||
|
|
||||||
if token in {"LPI", "SP"}:
|
if token in {"LPI", "SP"}:
|
||||||
@@ -343,7 +359,7 @@ def list_schedulable_tests(db_path: str | Path = DB_PATH, rule: str = "") -> lis
|
|||||||
SELECT
|
SELECT
|
||||||
test_id, device, test_type, rotation, rx_tx, has_coe_pair,
|
test_id, device, test_type, rotation, rx_tx, has_coe_pair,
|
||||||
config_json, victim_band,
|
config_json, victim_band,
|
||||||
coe_pairing_json, priority, estimated_minutes,
|
coe_pairing_json, priority, throttled, estimated_minutes,
|
||||||
excluded, status, raw_payload
|
excluded, status, raw_payload
|
||||||
FROM tests
|
FROM tests
|
||||||
WHERE excluded = 0
|
WHERE excluded = 0
|
||||||
@@ -365,6 +381,7 @@ def list_schedulable_tests(db_path: str | Path = DB_PATH, rule: str = "") -> lis
|
|||||||
priority=int(row["priority"]),
|
priority=int(row["priority"]),
|
||||||
victim_band=row["victim_band"],
|
victim_band=row["victim_band"],
|
||||||
config=json.loads(row["config_json"] or "{}"),
|
config=json.loads(row["config_json"] or "{}"),
|
||||||
|
throttled=bool(row["throttled"]),
|
||||||
estimated_minutes=int(row["estimated_minutes"]),
|
estimated_minutes=int(row["estimated_minutes"]),
|
||||||
status=row["status"],
|
status=row["status"],
|
||||||
excluded=bool(row["excluded"]),
|
excluded=bool(row["excluded"]),
|
||||||
@@ -384,7 +401,7 @@ def list_tests_for_device(device: str, db_path: str | Path = DB_PATH) -> list[Te
|
|||||||
SELECT
|
SELECT
|
||||||
test_id, device, test_type, rotation, rx_tx, has_coe_pair,
|
test_id, device, test_type, rotation, rx_tx, has_coe_pair,
|
||||||
config_json, victim_band,
|
config_json, victim_band,
|
||||||
coe_pairing_json, priority, estimated_minutes,
|
coe_pairing_json, priority, throttled, estimated_minutes,
|
||||||
excluded, status, raw_payload
|
excluded, status, raw_payload
|
||||||
FROM tests
|
FROM tests
|
||||||
WHERE device = ?
|
WHERE device = ?
|
||||||
@@ -406,6 +423,7 @@ def list_tests_for_device(device: str, db_path: str | Path = DB_PATH) -> list[Te
|
|||||||
priority=int(row["priority"]),
|
priority=int(row["priority"]),
|
||||||
victim_band=row["victim_band"],
|
victim_band=row["victim_band"],
|
||||||
config=json.loads(row["config_json"] or "{}"),
|
config=json.loads(row["config_json"] or "{}"),
|
||||||
|
throttled=bool(row["throttled"]),
|
||||||
estimated_minutes=int(row["estimated_minutes"]),
|
estimated_minutes=int(row["estimated_minutes"]),
|
||||||
status=row["status"],
|
status=row["status"],
|
||||||
excluded=bool(row["excluded"]),
|
excluded=bool(row["excluded"]),
|
||||||
|
|||||||
+12
-3
@@ -73,16 +73,25 @@ def _same_test_points_for_overlap(
|
|||||||
|
|
||||||
def _build_station_testpoint_map(config: dict[str, dict[str, str | None]]) -> dict[str, str]:
|
def _build_station_testpoint_map(config: dict[str, dict[str, str | None]]) -> dict[str, str]:
|
||||||
station_to_testpoint: dict[str, str] = {}
|
station_to_testpoint: dict[str, str] = {}
|
||||||
for band in ("5G", "6G", "2G"):
|
|
||||||
entry = config.get(band) or {}
|
def _add_entry(entry: dict[str, str | None]) -> None:
|
||||||
testpoint = _norm(entry.get("test_point") or entry.get("Testpoint"))
|
testpoint = _norm(entry.get("test_point") or entry.get("Testpoint"))
|
||||||
sta_raw = _norm(entry.get("sta") or entry.get("STA"))
|
sta_raw = _norm(entry.get("sta") or entry.get("STA"))
|
||||||
if not testpoint or not sta_raw:
|
if not testpoint or not sta_raw:
|
||||||
continue
|
return
|
||||||
for sta in sta_raw.split(","):
|
for sta in sta_raw.split(","):
|
||||||
sta_clean = _norm(sta)
|
sta_clean = _norm(sta)
|
||||||
if sta_clean:
|
if sta_clean:
|
||||||
station_to_testpoint[sta_clean] = testpoint
|
station_to_testpoint[sta_clean] = testpoint
|
||||||
|
|
||||||
|
for band in ("5G", "6G", "2G"):
|
||||||
|
entry = config.get(band) or {}
|
||||||
|
_add_entry(entry)
|
||||||
|
|
||||||
|
for station_key in ("Station 1", "Station 2", "Station 3"):
|
||||||
|
entry = config.get(station_key) or {}
|
||||||
|
_add_entry(entry)
|
||||||
|
|
||||||
return station_to_testpoint
|
return station_to_testpoint
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
-2515
File diff suppressed because it is too large
Load Diff
+151
-22
@@ -5,7 +5,7 @@ from pathlib import Path
|
|||||||
|
|
||||||
from db import DEVICE_DUT, DEVICE_REF, TestRecord
|
from db import DEVICE_DUT, DEVICE_REF, TestRecord
|
||||||
|
|
||||||
REQUIRED_COLUMNS = [
|
P2P_COE_REQUIRED_COLUMNS = [
|
||||||
"Priority",
|
"Priority",
|
||||||
"Index",
|
"Index",
|
||||||
"Interferer",
|
"Interferer",
|
||||||
@@ -34,6 +34,37 @@ REQUIRED_COLUMNS = [
|
|||||||
"2G STA",
|
"2G STA",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
P3P_REQUIRED_COLUMNS = [
|
||||||
|
"Priority",
|
||||||
|
"Index",
|
||||||
|
"Throttled",
|
||||||
|
"Rotation",
|
||||||
|
"TC ID",
|
||||||
|
"Band",
|
||||||
|
"6GHz Power Mode",
|
||||||
|
"Station 1 Test Point",
|
||||||
|
"Station 1 Channel",
|
||||||
|
"Station 1 Bandwidth",
|
||||||
|
"Station 1 RSSI",
|
||||||
|
"Station 1 Direction",
|
||||||
|
"Station 1 Rate",
|
||||||
|
"Station 1 STA",
|
||||||
|
"Station 2 Test Point",
|
||||||
|
"Station 2 Channel",
|
||||||
|
"Station 2 Bandwidth",
|
||||||
|
"Station 2 RSSI",
|
||||||
|
"Station 2 Direction",
|
||||||
|
"Station 2 Rate",
|
||||||
|
"Station 2 STA",
|
||||||
|
"Station 3 Test Point",
|
||||||
|
"Station 3 Channel",
|
||||||
|
"Station 3 Bandwidth",
|
||||||
|
"Station 3 RSSI",
|
||||||
|
"Station 3 Direction",
|
||||||
|
"Station 3 Rate",
|
||||||
|
"Station 3 STA",
|
||||||
|
]
|
||||||
|
|
||||||
RUNTIME_DEFAULTS = {
|
RUNTIME_DEFAULTS = {
|
||||||
"P2P": 80,
|
"P2P": 80,
|
||||||
"COE": 115,
|
"COE": 115,
|
||||||
@@ -50,28 +81,84 @@ class CsvValidationError(ValueError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def parse_target_csv(csv_path: str | Path) -> ParseResult:
|
def _columns_missing(normalized_fieldnames: set[str], required_columns: list[str]) -> list[str]:
|
||||||
path = Path(csv_path)
|
return [
|
||||||
|
column
|
||||||
|
for column in required_columns
|
||||||
|
if column.strip().upper() not in normalized_fieldnames
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _detect_csv_format(normalized_fieldnames: set[str]) -> str:
|
||||||
|
p2p_coe_missing = _columns_missing(normalized_fieldnames, P2P_COE_REQUIRED_COLUMNS)
|
||||||
|
if not p2p_coe_missing:
|
||||||
|
return "p2p_coe"
|
||||||
|
|
||||||
|
p3p_missing = _columns_missing(normalized_fieldnames, P3P_REQUIRED_COLUMNS)
|
||||||
|
if not p3p_missing:
|
||||||
|
return "p3p"
|
||||||
|
|
||||||
|
raise CsvValidationError(
|
||||||
|
"CSV format not recognized. Missing columns for P2P/COE format: "
|
||||||
|
f"{', '.join(p2p_coe_missing)}; missing columns for P3P format: {', '.join(p3p_missing)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_target_csv(csv_path: str | Path | list[str | Path] | tuple[str | Path, ...]) -> ParseResult:
|
||||||
|
paths = _resolve_csv_paths(csv_path)
|
||||||
|
all_tests: list[TestRecord] = []
|
||||||
|
all_warnings: list[str] = []
|
||||||
|
seen_test_keys: set[tuple[str, str]] = set()
|
||||||
|
|
||||||
|
for path in paths:
|
||||||
|
parsed = _parse_single_csv(path)
|
||||||
|
all_warnings.extend(parsed.warnings)
|
||||||
|
for record in parsed.tests:
|
||||||
|
key = (record.test_id, record.device)
|
||||||
|
if key in seen_test_keys:
|
||||||
|
all_warnings.append(
|
||||||
|
f"File {path.name}: duplicate test/device '{record.test_id}/{record.device}', record skipped."
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
seen_test_keys.add(key)
|
||||||
|
all_tests.append(record)
|
||||||
|
|
||||||
|
return ParseResult(tests=all_tests, warnings=all_warnings)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _resolve_csv_paths(csv_path: str | Path | list[str | Path] | tuple[str | Path, ...]) -> list[Path]:
|
||||||
|
if isinstance(csv_path, (str, Path)):
|
||||||
|
paths = [Path(csv_path)]
|
||||||
|
else:
|
||||||
|
paths = [Path(item) for item in csv_path]
|
||||||
|
|
||||||
|
resolved_paths: list[Path] = []
|
||||||
|
for path in paths:
|
||||||
|
if path.is_dir():
|
||||||
|
resolved_paths.extend(sorted(path.glob("*.csv")))
|
||||||
|
else:
|
||||||
|
resolved_paths.append(path)
|
||||||
|
|
||||||
|
if not resolved_paths:
|
||||||
|
raise FileNotFoundError("No CSV files found to parse.")
|
||||||
|
|
||||||
|
for path in resolved_paths:
|
||||||
if not path.exists():
|
if not path.exists():
|
||||||
raise FileNotFoundError(f"CSV file not found: {path}")
|
raise FileNotFoundError(f"CSV file not found: {path}")
|
||||||
|
|
||||||
|
return resolved_paths
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_single_csv(path: Path) -> ParseResult:
|
||||||
with path.open("r", encoding="utf-8-sig", newline="") as handle:
|
with path.open("r", encoding="utf-8-sig", newline="") as handle:
|
||||||
reader = csv.DictReader(handle)
|
reader = csv.DictReader(handle)
|
||||||
if not reader.fieldnames:
|
if not reader.fieldnames:
|
||||||
raise CsvValidationError("CSV is missing a header row.")
|
raise CsvValidationError("CSV is missing a header row.")
|
||||||
|
|
||||||
normalized_fieldnames = {name.strip().upper() for name in reader.fieldnames if name}
|
normalized_fieldnames = {name.strip().upper() for name in reader.fieldnames if name}
|
||||||
|
csv_format = _detect_csv_format(normalized_fieldnames)
|
||||||
# Check for required columns
|
|
||||||
missing_columns = [
|
|
||||||
c
|
|
||||||
for c in REQUIRED_COLUMNS
|
|
||||||
if c.strip().upper() not in normalized_fieldnames
|
|
||||||
]
|
|
||||||
if missing_columns:
|
|
||||||
raise CsvValidationError(
|
|
||||||
f"CSV is missing required columns: {', '.join(missing_columns)}"
|
|
||||||
)
|
|
||||||
|
|
||||||
tests: list[TestRecord] = []
|
tests: list[TestRecord] = []
|
||||||
warnings: list[str] = []
|
warnings: list[str] = []
|
||||||
@@ -82,24 +169,26 @@ def parse_target_csv(csv_path: str | Path) -> ParseResult:
|
|||||||
for row_num, row in enumerate(reader, start=2):
|
for row_num, row in enumerate(reader, start=2):
|
||||||
test_id = (row.get("TC ID") or "").strip()
|
test_id = (row.get("TC ID") or "").strip()
|
||||||
if not test_id:
|
if not test_id:
|
||||||
warnings.append(f"Row {row_num}: missing TC ID, row skipped.")
|
warnings.append(f"File {path.name}, row {row_num}: missing TC ID, row skipped.")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if test_id in seen_test_ids:
|
if test_id in seen_test_ids:
|
||||||
warnings.append(f"Row {row_num}: duplicate TC ID '{test_id}', row skipped.")
|
warnings.append(f"File {path.name}, row {row_num}: duplicate TC ID '{test_id}', row skipped.")
|
||||||
continue
|
continue
|
||||||
seen_test_ids.add(test_id)
|
seen_test_ids.add(test_id)
|
||||||
|
|
||||||
|
throttled = _normalize_yes_no(_row_get(row, "Throttled")) if csv_format == "p3p" else False
|
||||||
test_type = _infer_test_type(test_id)
|
test_type = _infer_test_type(test_id)
|
||||||
rx_tx = _infer_rx_tx(test_id)
|
rx_tx = _infer_rx_tx(test_id)
|
||||||
rotation = _empty_to_none(_row_get(row, "Rotation"))
|
rotation = _empty_to_none(_row_get(row, "Rotation"))
|
||||||
has_coe_pair = _normalize_yes_no(_row_get(row, "COE Pair"))
|
has_coe_pair = _normalize_yes_no(_row_get(row, "COE Pair")) if csv_format == "p2p_coe" else False
|
||||||
config = _build_config(row)
|
config = _build_config(row, csv_format)
|
||||||
signature = _victim_band_signature(row)
|
signature = _victim_band_signature(row) if csv_format == "p2p_coe" else None
|
||||||
estimated_minutes = RUNTIME_DEFAULTS.get(test_type)
|
estimated_minutes = RUNTIME_DEFAULTS.get(test_type)
|
||||||
victim_band = _normalize_victim_band(_row_get(row, "Victim Band"))
|
victim_band_source = "Victim Band" if csv_format == "p2p_coe" else "Band"
|
||||||
|
victim_band = _normalize_victim_band(_row_get(row, victim_band_source))
|
||||||
|
|
||||||
# Default priority based on test type and COE pairing
|
# Default priority based on test type and COE pairing.
|
||||||
if test_type == "P2P":
|
if test_type == "P2P":
|
||||||
priority = 2 if has_coe_pair else 3
|
priority = 2 if has_coe_pair else 3
|
||||||
elif test_type == "COE":
|
elif test_type == "COE":
|
||||||
@@ -118,6 +207,7 @@ def parse_target_csv(csv_path: str | Path) -> ParseResult:
|
|||||||
priority=priority,
|
priority=priority,
|
||||||
victim_band=victim_band,
|
victim_band=victim_band,
|
||||||
config=config,
|
config=config,
|
||||||
|
throttled=throttled,
|
||||||
estimated_minutes=estimated_minutes,
|
estimated_minutes=estimated_minutes,
|
||||||
status="pending",
|
status="pending",
|
||||||
excluded=False,
|
excluded=False,
|
||||||
@@ -155,6 +245,7 @@ def parse_target_csv(csv_path: str | Path) -> ParseResult:
|
|||||||
priority=record.priority,
|
priority=record.priority,
|
||||||
victim_band=record.victim_band,
|
victim_band=record.victim_band,
|
||||||
config=record.config,
|
config=record.config,
|
||||||
|
throttled=record.throttled,
|
||||||
estimated_minutes=record.estimated_minutes,
|
estimated_minutes=record.estimated_minutes,
|
||||||
status=record.status,
|
status=record.status,
|
||||||
excluded=record.excluded,
|
excluded=record.excluded,
|
||||||
@@ -252,7 +343,7 @@ def _normalize_yes_no(value: str | None) -> bool:
|
|||||||
return _normalize_value(value) == "YES"
|
return _normalize_value(value) == "YES"
|
||||||
|
|
||||||
|
|
||||||
def _build_config(row: dict[str, str]) -> dict[str, dict[str, str | None]]:
|
def _build_legacy_config(row: dict[str, str]) -> dict[str, dict[str, str | None]]:
|
||||||
return {
|
return {
|
||||||
"5G": {
|
"5G": {
|
||||||
"test_point": _empty_to_none(_row_get(row, "5G Test Point")),
|
"test_point": _empty_to_none(_row_get(row, "5G Test Point")),
|
||||||
@@ -282,6 +373,44 @@ def _build_config(row: dict[str, str]) -> dict[str, dict[str, str | None]]:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _build_p3p_config(row: dict[str, str]) -> dict[str, dict[str, str | None]]:
|
||||||
|
return {
|
||||||
|
"Station 1": {
|
||||||
|
"test_point": _empty_to_none(_row_get(row, "Station 1 Test Point")),
|
||||||
|
"channel": _empty_to_none(_row_get(row, "Station 1 Channel")),
|
||||||
|
"bandwidth": _empty_to_none(_row_get(row, "Station 1 Bandwidth")),
|
||||||
|
"rssi": _empty_to_none(_row_get(row, "Station 1 RSSI")),
|
||||||
|
"direction": _empty_to_none(_row_get(row, "Station 1 Direction")),
|
||||||
|
"rate": _empty_to_none(_row_get(row, "Station 1 Rate")),
|
||||||
|
"sta": _empty_to_none(_row_get(row, "Station 1 STA")),
|
||||||
|
},
|
||||||
|
"Station 2": {
|
||||||
|
"test_point": _empty_to_none(_row_get(row, "Station 2 Test Point")),
|
||||||
|
"channel": _empty_to_none(_row_get(row, "Station 2 Channel")),
|
||||||
|
"bandwidth": _empty_to_none(_row_get(row, "Station 2 Bandwidth")),
|
||||||
|
"rssi": _empty_to_none(_row_get(row, "Station 2 RSSI")),
|
||||||
|
"direction": _empty_to_none(_row_get(row, "Station 2 Direction")),
|
||||||
|
"rate": _empty_to_none(_row_get(row, "Station 2 Rate")),
|
||||||
|
"sta": _empty_to_none(_row_get(row, "Station 2 STA")),
|
||||||
|
},
|
||||||
|
"Station 3": {
|
||||||
|
"test_point": _empty_to_none(_row_get(row, "Station 3 Test Point")),
|
||||||
|
"channel": _empty_to_none(_row_get(row, "Station 3 Channel")),
|
||||||
|
"bandwidth": _empty_to_none(_row_get(row, "Station 3 Bandwidth")),
|
||||||
|
"rssi": _empty_to_none(_row_get(row, "Station 3 RSSI")),
|
||||||
|
"direction": _empty_to_none(_row_get(row, "Station 3 Direction")),
|
||||||
|
"rate": _empty_to_none(_row_get(row, "Station 3 Rate")),
|
||||||
|
"sta": _empty_to_none(_row_get(row, "Station 3 STA")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _build_config(row: dict[str, str], csv_format: str) -> dict[str, dict[str, str | None]]:
|
||||||
|
if csv_format == "p3p":
|
||||||
|
return _build_p3p_config(row)
|
||||||
|
return _build_legacy_config(row)
|
||||||
|
|
||||||
|
|
||||||
def _row_get(row: dict[str, str], key: str) -> str | None:
|
def _row_get(row: dict[str, str], key: str) -> str | None:
|
||||||
if key in row:
|
if key in row:
|
||||||
return row.get(key)
|
return row.get(key)
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class SchedulerTest:
|
|||||||
has_coe_pair: bool
|
has_coe_pair: bool
|
||||||
coe_pairing: list[str]
|
coe_pairing: list[str]
|
||||||
config: dict[str, dict[str, str | None]]
|
config: dict[str, dict[str, str | None]]
|
||||||
|
throttled: bool
|
||||||
estimated_minutes: int
|
estimated_minutes: int
|
||||||
priority: int
|
priority: int
|
||||||
raw_payload: dict[str, Any]
|
raw_payload: dict[str, Any]
|
||||||
|
|||||||
Reference in New Issue
Block a user