update to read from db
This commit is contained in:
@@ -233,8 +233,8 @@ export default function TestTable({ tests = [], allTests = [], isLoading }) {
|
|||||||
<tr key={r.station} className="text-slate-300">
|
<tr key={r.station} className="text-slate-300">
|
||||||
<td className="pr-6 py-0.5 text-cyan-400 font-medium">STA{r.station}</td>
|
<td className="pr-6 py-0.5 text-cyan-400 font-medium">STA{r.station}</td>
|
||||||
<td className="pr-6 py-0.5 text-right">{r.tput} Mbps</td>
|
<td className="pr-6 py-0.5 text-right">{r.tput} Mbps</td>
|
||||||
<td className="pr-6 py-0.5 text-right">{r.dlRssi} dBm</td>
|
<td className="pr-6 py-0.5 text-right">{r.dlRssi ?? '-'} dBm</td>
|
||||||
<td className="py-0.5 text-right">{r.ulRssi} dBm</td>
|
<td className="py-0.5 text-right">{r.ulRssi ?? '-'} dBm</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
+143
@@ -1,5 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import threading
|
import threading
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
@@ -150,6 +151,148 @@ def mark_completed(test_id, device, completed_at, duration_seconds, tput_results
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_measurement_metrics(db_file_path):
|
||||||
|
conn = sqlite3.connect(db_file_path)
|
||||||
|
conn.row_factory = sqlite3.Row
|
||||||
|
try:
|
||||||
|
tput_rows = conn.execute(
|
||||||
|
"""
|
||||||
|
SELECT CAST(ROUND(AVG(IXC_avg_tput),0)AS INT) AS avg_tput, COM_Dst_endpoint
|
||||||
|
FROM MEASUREMENT
|
||||||
|
WHERE IXC_avg_tput IS NOT NULL
|
||||||
|
GROUP BY COM_Dst_endpoint
|
||||||
|
"""
|
||||||
|
).fetchall()
|
||||||
|
|
||||||
|
rssi_rows = conn.execute(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
COM_Dst_endpoint,
|
||||||
|
|
||||||
|
CAST(
|
||||||
|
AVG(
|
||||||
|
CASE
|
||||||
|
WHEN COM_Dst_endpoint = 'STA4' THEN
|
||||||
|
(
|
||||||
|
(CASE WHEN STA_rssi IS NOT NULL AND STA_rssi != 0 AND STA_rssi >= -199 THEN STA_rssi END) +
|
||||||
|
(CASE WHEN STA_all_rssi_0 IS NOT NULL AND STA_all_rssi_0 != 0 AND STA_all_rssi_0 >= -199 THEN STA_all_rssi_0 END) +
|
||||||
|
(CASE WHEN STA_all_rssi_1 IS NOT NULL AND STA_all_rssi_1 != 0 AND STA_all_rssi_1 >= -199 THEN STA_all_rssi_1 END) +
|
||||||
|
(CASE WHEN STA_all_rssi_2 IS NOT NULL AND STA_all_rssi_2 != 0 AND STA_all_rssi_2 >= -199 THEN STA_all_rssi_2 END)
|
||||||
|
) * 1.0 /
|
||||||
|
NULLIF(
|
||||||
|
(STA_rssi IS NOT NULL AND STA_rssi != 0 AND STA_rssi >= -199) +
|
||||||
|
(STA_all_rssi_0 IS NOT NULL AND STA_all_rssi_0 != 0 AND STA_all_rssi_0 >= -199) +
|
||||||
|
(STA_all_rssi_1 IS NOT NULL AND STA_all_rssi_1 != 0 AND STA_all_rssi_1 >= -199) +
|
||||||
|
(STA_all_rssi_2 IS NOT NULL AND STA_all_rssi_2 != 0 AND STA_all_rssi_2 >= -199),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
WHEN COM_Dst_endpoint IN ('STA56', 'STA63') THEN
|
||||||
|
CASE
|
||||||
|
WHEN STA_rssi IS NOT NULL AND STA_rssi != 0 AND STA_rssi >= -199
|
||||||
|
THEN STA_rssi
|
||||||
|
END
|
||||||
|
END
|
||||||
|
) AS INTEGER
|
||||||
|
) AS dl_rssi,
|
||||||
|
|
||||||
|
CAST(
|
||||||
|
AVG(
|
||||||
|
(
|
||||||
|
(CASE WHEN AP_sta_rssi_0 IS NOT NULL AND AP_sta_rssi_0 != 0 AND AP_sta_rssi_0 >= -199 THEN AP_sta_rssi_0 END) +
|
||||||
|
(CASE WHEN AP_sta_rssi_1 IS NOT NULL AND AP_sta_rssi_1 != 0 AND AP_sta_rssi_1 >= -199 THEN AP_sta_rssi_1 END) +
|
||||||
|
(CASE WHEN AP_sta_rssi_2 IS NOT NULL AND AP_sta_rssi_2 != 0 AND AP_sta_rssi_2 >= -199 THEN AP_sta_rssi_2 END) +
|
||||||
|
(CASE WHEN AP_sta_rssi_3 IS NOT NULL AND AP_sta_rssi_3 != 0 AND AP_sta_rssi_3 >= -199 THEN AP_sta_rssi_3 END)
|
||||||
|
) * 1.0 /
|
||||||
|
NULLIF(
|
||||||
|
(AP_sta_rssi_0 IS NOT NULL AND AP_sta_rssi_0 != 0 AND AP_sta_rssi_0 >= -199) +
|
||||||
|
(AP_sta_rssi_1 IS NOT NULL AND AP_sta_rssi_1 != 0 AND AP_sta_rssi_1 >= -199) +
|
||||||
|
(AP_sta_rssi_2 IS NOT NULL AND AP_sta_rssi_2 != 0 AND AP_sta_rssi_2 >= -199) +
|
||||||
|
(AP_sta_rssi_3 IS NOT NULL AND AP_sta_rssi_3 != 0 AND AP_sta_rssi_3 >= -199),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
) AS INTEGER
|
||||||
|
) AS ul_rssi
|
||||||
|
|
||||||
|
FROM MEASUREMENT
|
||||||
|
GROUP BY COM_Dst_endpoint
|
||||||
|
"""
|
||||||
|
).fetchall()
|
||||||
|
|
||||||
|
elapsed_row = conn.execute(
|
||||||
|
"""
|
||||||
|
WITH first_last AS (
|
||||||
|
SELECT
|
||||||
|
(SELECT COM_time FROM MEASUREMENT ORDER BY rowid ASC LIMIT 1) AS start_time,
|
||||||
|
(SELECT COM_time FROM MEASUREMENT ORDER BY rowid DESC LIMIT 1) AS end_time
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
ROUND(
|
||||||
|
CASE
|
||||||
|
WHEN end_sec >= start_sec THEN
|
||||||
|
end_sec - start_sec
|
||||||
|
ELSE
|
||||||
|
(end_sec - start_sec) + 86400
|
||||||
|
END
|
||||||
|
) AS elapsed_seconds
|
||||||
|
FROM (
|
||||||
|
SELECT
|
||||||
|
(strftime('%H', start_time) * 3600 +
|
||||||
|
strftime('%M', start_time) * 60 +
|
||||||
|
strftime('%S', start_time)) AS start_sec,
|
||||||
|
|
||||||
|
(strftime('%H', end_time) * 3600 +
|
||||||
|
strftime('%M', end_time) * 60 +
|
||||||
|
strftime('%S', end_time)) AS end_sec
|
||||||
|
FROM first_last
|
||||||
|
);
|
||||||
|
"""
|
||||||
|
).fetchone()
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
result = {"duration_seconds": None, "tputResults": []}
|
||||||
|
|
||||||
|
if elapsed_row and elapsed_row["elapsed_seconds"] is not None:
|
||||||
|
result["duration_seconds"] = int(elapsed_row["elapsed_seconds"])
|
||||||
|
|
||||||
|
rssi_by_endpoint = {
|
||||||
|
row["COM_Dst_endpoint"]: {
|
||||||
|
"dl_rssi": row["dl_rssi"],
|
||||||
|
"ul_rssi": row["ul_rssi"],
|
||||||
|
}
|
||||||
|
for row in rssi_rows
|
||||||
|
if row["COM_Dst_endpoint"] not in (None, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
tput_results = []
|
||||||
|
for row in tput_rows:
|
||||||
|
dst_endpoint = row["COM_Dst_endpoint"]
|
||||||
|
if dst_endpoint in (None, ""):
|
||||||
|
continue
|
||||||
|
|
||||||
|
match = re.search(r"STA\s*0*(\d+)", str(dst_endpoint), re.IGNORECASE)
|
||||||
|
if not match:
|
||||||
|
continue
|
||||||
|
|
||||||
|
avg_tput = row["avg_tput"]
|
||||||
|
if avg_tput is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
rssi_values = rssi_by_endpoint.get(dst_endpoint, {})
|
||||||
|
|
||||||
|
tput_results.append(
|
||||||
|
{
|
||||||
|
"station": int(match.group(1)),
|
||||||
|
"tput": int(avg_tput),
|
||||||
|
"dlRssi": rssi_values.get("dl_rssi"),
|
||||||
|
"ulRssi": rssi_values.get("ul_rssi"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
result["tputResults"] = sorted(tput_results, key=lambda item: item["station"])
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def set_coe_pair(test_row_id, coe_pair):
|
def set_coe_pair(test_row_id, coe_pair):
|
||||||
json_value = json.dumps(coe_pair or [])
|
json_value = json.dumps(coe_pair or [])
|
||||||
with _tx():
|
with _tx():
|
||||||
|
|||||||
@@ -68,27 +68,3 @@ def parse_timestamp(filename):
|
|||||||
return f"{year}-{month}-{day}T{hour}:{minute}:{second}"
|
return f"{year}-{month}-{day}T{hour}:{minute}:{second}"
|
||||||
|
|
||||||
|
|
||||||
def parse_elapsed_time(time_str):
|
|
||||||
match = re.match(r"^(\d+):(\d{2}):(\d{2})\.(\d+)$", time_str)
|
|
||||||
if not match:
|
|
||||||
return None
|
|
||||||
|
|
||||||
hours, minutes, seconds, fraction = match.groups()
|
|
||||||
return int(hours) * 3600 + int(minutes) * 60 + int(seconds) + float(f"0.{fraction}")
|
|
||||||
|
|
||||||
|
|
||||||
def parse_tput_rssi(line):
|
|
||||||
match = re.search(
|
|
||||||
r"STA(\d+) over angles >> AVG IxChariot TPUT: (\d+) Mbps, AVG DL RSSI: (-?\d+) dBm, AVG UL RSSI: (-?\d+) dBm",
|
|
||||||
line,
|
|
||||||
)
|
|
||||||
if not match:
|
|
||||||
return None
|
|
||||||
|
|
||||||
station, tput, dl_rssi, ul_rssi = match.groups()
|
|
||||||
return {
|
|
||||||
"station": int(station),
|
|
||||||
"tput": int(tput),
|
|
||||||
"dlRssi": int(dl_rssi),
|
|
||||||
"ulRssi": int(ul_rssi),
|
|
||||||
}
|
|
||||||
|
|||||||
+31
-33
@@ -1,10 +1,12 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import threading
|
import threading
|
||||||
|
import tempfile
|
||||||
import smbclient
|
import smbclient
|
||||||
|
|
||||||
from db_py import (
|
from db_py import (
|
||||||
clear_tests,
|
clear_tests,
|
||||||
|
extract_measurement_metrics,
|
||||||
get_config,
|
get_config,
|
||||||
mark_completed,
|
mark_completed,
|
||||||
reset_all_results_state,
|
reset_all_results_state,
|
||||||
@@ -13,11 +15,9 @@ from db_py import (
|
|||||||
upsert_test,
|
upsert_test,
|
||||||
)
|
)
|
||||||
from parser import (
|
from parser import (
|
||||||
parse_elapsed_time,
|
|
||||||
parse_result_filename,
|
parse_result_filename,
|
||||||
parse_target_filename,
|
parse_target_filename,
|
||||||
parse_timestamp,
|
parse_timestamp,
|
||||||
parse_tput_rssi,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -431,26 +431,20 @@ def process_result_dir(results_dir, result_dir_name):
|
|||||||
result_dir_path = _join_path(results_dir, result_dir_name)
|
result_dir_path = _join_path(results_dir, result_dir_name)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
log_files = [
|
files = [entry.name for entry in _iter_dir_entries(result_dir_path) if entry.is_file()]
|
||||||
entry.name
|
|
||||||
for entry in _iter_dir_entries(result_dir_path)
|
|
||||||
if entry.is_file()
|
|
||||||
and entry.name.endswith(".txt")
|
|
||||||
and test_id in entry.name
|
|
||||||
]
|
|
||||||
except OSError as exc:
|
except OSError as exc:
|
||||||
print(f"[scanner] Cannot read result dir {result_dir_name}: {exc}")
|
print(f"[scanner] Cannot read result dir {result_dir_name}: {exc}")
|
||||||
return
|
return
|
||||||
|
|
||||||
if not log_files:
|
measurement_db = next((name for name in files if name.lower() == "measurement.db"), None)
|
||||||
print(f"[scanner] completed (no log yet): {test_id}")
|
if not measurement_db:
|
||||||
|
print(f"[scanner] completed (no measurement.db yet): {test_id}")
|
||||||
mark_completed(test_id, device, None, None)
|
mark_completed(test_id, device, None, None)
|
||||||
return
|
return
|
||||||
|
|
||||||
latest_log = sorted(log_files)[-1]
|
db_path = _join_path(result_dir_path, measurement_db)
|
||||||
log_path = _join_path(result_dir_path, latest_log)
|
completed_at = parse_timestamp(result_dir_name)
|
||||||
completed_at = parse_timestamp(latest_log)
|
data = extract_measurement_data(db_path)
|
||||||
data = extract_log_data(log_path)
|
|
||||||
|
|
||||||
'''print(
|
'''print(
|
||||||
f"[scanner] completed: {test_id} device={device} "
|
f"[scanner] completed: {test_id} device={device} "
|
||||||
@@ -472,25 +466,29 @@ def parse_deleted_result_dir_name(dir_name):
|
|||||||
return test_id, device
|
return test_id, device
|
||||||
|
|
||||||
|
|
||||||
def extract_log_data(log_file_path):
|
def extract_measurement_data(db_file_path):
|
||||||
elapsed_regex = re.compile(r"\[.*?INFO\]\s+Elapsed time\s*:\s*([\d]+:[\d]{2}:[\d]{2}\.[\d]+)")
|
|
||||||
tput_regex = re.compile(
|
|
||||||
r"\[.*?INFO\]\s+STA(\d+) over angles >> AVG IxChariot TPUT: (\d+) Mbps, AVG DL RSSI: (-?\d+) dBm, AVG UL RSSI: (-?\d+) dBm"
|
|
||||||
)
|
|
||||||
|
|
||||||
result = {"duration_seconds": None, "tputResults": []}
|
result = {"duration_seconds": None, "tputResults": []}
|
||||||
try:
|
local_db_path = None
|
||||||
for line in _read_text_lines(log_file_path):
|
|
||||||
time_match = elapsed_regex.search(line)
|
|
||||||
if time_match:
|
|
||||||
result["duration_seconds"] = parse_elapsed_time(time_match.group(1))
|
|
||||||
continue
|
|
||||||
|
|
||||||
if tput_regex.search(line):
|
try:
|
||||||
parsed = parse_tput_rssi(line)
|
source_db_path = _normalize_input_path(db_file_path)
|
||||||
if parsed:
|
if _is_unc_path(source_db_path):
|
||||||
result["tputResults"].append(parsed)
|
_register_smb_session_if_needed(source_db_path)
|
||||||
except OSError as exc:
|
with smbclient.open_file(source_db_path, mode="rb") as src_fh:
|
||||||
print(f"[scanner] Cannot read log file {log_file_path}: {exc}")
|
with tempfile.NamedTemporaryFile(delete=False, suffix=".db") as tmp_fh:
|
||||||
|
tmp_fh.write(src_fh.read())
|
||||||
|
local_db_path = tmp_fh.name
|
||||||
|
source_db_path = local_db_path
|
||||||
|
|
||||||
|
result = extract_measurement_metrics(source_db_path)
|
||||||
|
|
||||||
|
except (OSError, ValueError, Exception) as exc:
|
||||||
|
print(f"[scanner] Cannot read measurement db {db_file_path}: {exc}")
|
||||||
|
finally:
|
||||||
|
if local_db_path:
|
||||||
|
try:
|
||||||
|
os.remove(local_db_path)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
Reference in New Issue
Block a user