knapsack scheduling algorithm

This commit is contained in:
2026-07-12 14:19:58 -04:00
parent 031da48ddd
commit 9e100d60d0
56 changed files with 1936 additions and 1286 deletions
+95 -87
View File
@@ -21,24 +21,24 @@ P2P_COE_REQUIRED_COLUMNS = [
"TC ID",
"Victim Band",
"6GHz Power Mode",
"5G Test Point",
"5G Channel",
"5G Bandwidth",
"5G RSSI",
"5G Direction",
"5G STA",
"6G Test Point",
"6G Channel",
"6G Bandwidth",
"6G RSSI",
"6G Direction",
"6G STA",
"2G Test Point",
"2G Channel",
"2G Bandwidth",
"2G RSSI",
"2G Direction",
"2G STA",
"5G_Test Point",
"5G_Channel",
"5G_Bandwidth",
"5G_RSSI",
"5G_Direction",
"5G_STA",
"6G_Test Point",
"6G_Channel",
"6G_Bandwidth",
"6G_RSSI",
"6G_Direction",
"6G_STA",
"2G_Test Point",
"2G_Channel",
"2G_Bandwidth",
"2G_RSSI",
"2G_Direction",
"2G_STA",
]
P3P_REQUIRED_COLUMNS = [
@@ -49,27 +49,27 @@ P3P_REQUIRED_COLUMNS = [
"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",
"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 = {
@@ -230,7 +230,6 @@ def _detect_csv_format(normalized_fieldnames: set[str]) -> str:
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, ...],
smb_credentials: dict[str, Any] | None = None,
@@ -476,11 +475,20 @@ def _victim_band_signature(row: dict[str, str]) -> tuple[str, ...] | None:
if band is None:
return None
prefix = f"{band} "
test_point = _normalize_value(_row_get(row, f"{prefix}Test Point"))
channel = _normalize_value(_row_get(row, f"{prefix}Channel"))
rssi = _normalize_value(_row_get(row, f"{prefix}RSSI"))
bandwidth = _normalize_value(_row_get(row, f"{prefix}Bandwidth"))
# Source CSVs may use either "5G_Test Point" or "5G Test Point" style headers.
prefixes = (f"{band}_", f"{band} ")
def _pick_value(suffix: str) -> str:
for prefix in prefixes:
value = _row_get(row, f"{prefix}{suffix}")
if _normalize_value(value):
return _normalize_value(value)
return ""
test_point = _pick_value("Test Point")
channel = _pick_value("Channel")
rssi = _pick_value("RSSI")
bandwidth = _pick_value("Bandwidth")
# Direction is intentionally ignored for COE pairing matching.
if not all([test_point, channel, rssi, bandwidth]):
@@ -515,61 +523,61 @@ def _normalize_yes_no(value: str | None) -> bool:
def _build_legacy_config(row: dict[str, str]) -> dict[str, dict[str, str | None]]:
return {
"5G": {
"test_point": _empty_to_none(_row_get(row, "5G Test Point")),
"channel": _empty_to_none(_row_get(row, "5G Channel")),
"bandwidth": _empty_to_none(_row_get(row, "5G Bandwidth")),
"rssi": _empty_to_none(_row_get(row, "5G RSSI")),
"direction": _empty_to_none(_row_get(row, "5G Direction")),
"sta": _empty_to_none(_row_get(row, "5G STA")),
"test_point": _empty_to_none(_row_get(row, "5G_Test Point")),
"channel": _empty_to_none(_row_get(row, "5G_Channel")),
"bandwidth": _empty_to_none(_row_get(row, "5G_Bandwidth")),
"rssi": _empty_to_none(_row_get(row, "5G_RSSI")),
"direction": _empty_to_none(_row_get(row, "5G_Direction")),
"sta": _empty_to_none(_row_get(row, "5G_STA")),
},
"6G": {
"power_mode": _empty_to_none(_row_get(row, "6GHz Power Mode")),
"test_point": _empty_to_none(_row_get(row, "6G Test Point")),
"channel": _empty_to_none(_row_get(row, "6G Channel")),
"bandwidth": _empty_to_none(_row_get(row, "6G Bandwidth")),
"rssi": _empty_to_none(_row_get(row, "6G RSSI")),
"direction": _empty_to_none(_row_get(row, "6G Direction")),
"sta": _empty_to_none(_row_get(row, "6G STA")),
"test_point": _empty_to_none(_row_get(row, "6G_Test Point")),
"channel": _empty_to_none(_row_get(row, "6G_Channel")),
"bandwidth": _empty_to_none(_row_get(row, "6G_Bandwidth")),
"rssi": _empty_to_none(_row_get(row, "6G_RSSI")),
"direction": _empty_to_none(_row_get(row, "6G_Direction")),
"sta": _empty_to_none(_row_get(row, "6G_STA")),
},
"2G": {
"test_point": _empty_to_none(_row_get(row, "2G Test Point")),
"channel": _empty_to_none(_row_get(row, "2G Channel")),
"bandwidth": _empty_to_none(_row_get(row, "2G Bandwidth")),
"rssi": _empty_to_none(_row_get(row, "2G RSSI")),
"direction": _empty_to_none(_row_get(row, "2G Direction")),
"sta": _empty_to_none(_row_get(row, "2G STA")),
"test_point": _empty_to_none(_row_get(row, "2G_Test Point")),
"channel": _empty_to_none(_row_get(row, "2G_Channel")),
"bandwidth": _empty_to_none(_row_get(row, "2G_Bandwidth")),
"rssi": _empty_to_none(_row_get(row, "2G_RSSI")),
"direction": _empty_to_none(_row_get(row, "2G_Direction")),
"sta": _empty_to_none(_row_get(row, "2G_STA")),
},
}
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")),
"STATION1": {
"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")),
"STATION2": {
"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")),
"STATION3": {
"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")),
},
}