Skip to content

Commit 7e105cc

Browse files
committed
lf_interop_ping_plotter.py : Add functionality to filter specified BSSID's to compare transitions and generate bandsteering graphs
- Filters data based on specified BSSIDs and analyzes their transitions across timestamps and position - Generates visual graphs and reports to highlight band steering behavior VERIFIED CLI : python3 lf_interop_ping_plotter.py --mgr 192.168.207.78 --real --ping_interval 1 --ping_duration 1m --server_ip 192.168.1.61 --use_default_config --robot_ip 127.0.0.1:5000 --coordinate 4,5 --target 8.8.8.8 --do_bandsteering --total_cycles 3 --bssids 94:A6:7E:74:26:33,94:A6:7E:74:26:22 Signed-off-by: Renusree-ct <renusree.rayavarapu@candelatech.com>
1 parent d6651cf commit 7e105cc

1 file changed

Lines changed: 132 additions & 2 deletions

File tree

py-scripts/lf_interop_ping_plotter.py

Lines changed: 132 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@
7777
python3 lf_interop_ping_plotter.py --mgr 192.168.207.78 --real --target 8.8.8.8 --ping_interval 1 --ping_duration 1m --use_default_config
7878
--robot_ip 192.168.204.76 --coordinate 3,4 --rotation 45,90
7979
80+
EXAMPLE-16:
81+
Command Line Interface to run ping plotter test with desired resources at desired points with bandsteering using robo
82+
python3 lf_interop_ping_plotter.py --mgr 192.168.207.78 --real --target 8.8.8.8 --ping_interval 1 --ping_duration 1m --use_default_config
83+
--robot_ip 192.168.204.76 --coordinate 3,4 --do_bandsteering --total_cycles 3 --bssids 94:A6:7E:74:26:33,94:A6:7E:74:26:22
84+
8085
8186
SCRIPT_CLASSIFICATION : Test
8287
@@ -100,7 +105,7 @@
100105
Copyright (C) 2020-2026 Candela Technologies Inc.
101106
'''
102107

103-
from lf_base_robo import RobotClass
108+
104109
import argparse
105110
import time
106111
import sys
@@ -123,10 +128,11 @@
123128

124129
from lf_base_interop_profile import RealDevice
125130
from datetime import datetime, timedelta
126-
from lf_graph import lf_bar_graph_horizontal
131+
from lf_graph import lf_bar_graph_horizontal, lf_bar_graph
127132
from lf_report import lf_report
128133
from station_profile import StationProfile
129134
from typing import List, Optional
135+
from collections import Counter
130136
# Importing DeviceConfig to apply device configurations for ADB devices and laptops
131137
DeviceConfig = importlib.import_module("py-scripts.DeviceConfig")
132138
from LANforge import LFUtils # noqa: E402
@@ -140,6 +146,7 @@
140146

141147
realm = importlib.import_module("py-json.realm")
142148
Realm = realm.Realm
149+
from lf_base_robo import RobotClass
143150

144151

145152
class Ping(Realm):
@@ -997,6 +1004,12 @@ def generate_report(self, result_json=None, result_dir='Ping_Plotter_Test_Report
9971004
'No of Devices': '{} (V:{}, A:{}, W:{}, L:{}, M:{})'.format(len(self.sta_list), len(self.sta_list) - len(self.real_sta_list), self.android, self.windows, self.linux, self.mac),
9981005
'Duration': self.duration
9991006
}
1007+
# if bandsteering is enabled
1008+
if self.do_bandsteering:
1009+
del test_setup_info["Duration"]
1010+
test_setup_info["Robot IP"] = self.robo_ip
1011+
test_setup_info["Selected Coordinates"] = ",".join(self.coordinate_list)
1012+
test_setup_info["no of cycles"] = self.total_cycles
10001013
# Test setup information table for devices in groups
10011014
else:
10021015
group_names = ', '.join(config_devices.keys())
@@ -1119,6 +1132,9 @@ def generate_report(self, result_json=None, result_dir='Ping_Plotter_Test_Report
11191132
})
11201133
report.set_table_dataframe(individual_report_df)
11211134
report.build_table()
1135+
# Extract bandsteering graphs
1136+
if self.do_bandsteering:
1137+
self.get_bandsteering_stats(report)
11221138

11231139
# packets sent vs received vs dropped
11241140
report.set_table_title(
@@ -2451,6 +2467,115 @@ def generate_report_robo(self, result_json=None, result_dir='Ping_Plotter_Test_R
24512467
if self.do_webUI:
24522468
self.copy_reports(report_path_date_time)
24532469

2470+
def get_bandsteering_stats(self, report=None):
2471+
"""
2472+
Retrieves and adds bandsteering statistics to the report.
2473+
2474+
This function processes the given dataframe to detect BSSID changes
2475+
(transitions) per device, maps them with corresponding channels,
2476+
and correlates them with robot movement (coordinates and timestamps).
2477+
It generates bar graphs for BSSID change counts and tabular reports
2478+
for band steering events.
2479+
2480+
Args:
2481+
report: Report object used to build graphs and tables.
2482+
df (pd.DataFrame): Input dataframe containing timestamp, BSSID,
2483+
channel, and coordinate data.
2484+
2485+
Returns:
2486+
None
2487+
"""
2488+
df = pd.read_csv("bandsteering_data.csv")
2489+
bssid_cols = [c for c in df.columns if c.startswith("BSSID")]
2490+
channel_cols = [c for c in df.columns if c.startswith("Channel")]
2491+
2492+
bssid_to_channel = {
2493+
bssid_col: next(
2494+
ch for ch in channel_cols
2495+
if ch.replace("Channel", "").strip() ==
2496+
bssid_col.replace("BSSID", "").strip()
2497+
)
2498+
for bssid_col in bssid_cols
2499+
}
2500+
2501+
# print("bssiddcolss",bssid_cols)
2502+
# print("bassidchannelcolss",bssid_to_channel)
2503+
for col in bssid_cols:
2504+
2505+
channel_col = bssid_to_channel[col]
2506+
2507+
# Detect BSSID changes
2508+
mask = df[col] != df[col].shift()
2509+
filtered_df = df.loc[mask]
2510+
2511+
if self.bssids:
2512+
filtered_df = df.loc[mask & df[col].isin(self.bssids)]
2513+
2514+
bssid_list = filtered_df[col].tolist()
2515+
channel_list = filtered_df[channel_col].tolist()
2516+
timestamp_list = filtered_df['TIMESTAMP'].tolist()
2517+
from_coordinate_list = filtered_df['From Coordinate'].tolist()
2518+
to_coordinate_list = filtered_df['To Coordinate'].tolist()
2519+
bssid_counts = Counter(bssid_list)
2520+
2521+
x_axis = list(bssid_counts.keys()) # BSSID values
2522+
y_axis = [[float(i)] for i in list(bssid_counts.values())]
2523+
if len(self.bssids) > 0:
2524+
x_axis = self.bssids
2525+
y_axis = [[float(bssid_counts.get(bssid, 0))] for bssid in self.bssids]
2526+
device_name = col.replace('BSSID ', '')
2527+
device_name = col.split()[-1]
2528+
report.set_obj_html(
2529+
_obj_title=f"BSSID change count of the {device_name}",
2530+
_obj=" ")
2531+
report.build_objective()
2532+
graph = lf_bar_graph(_data_set=y_axis,
2533+
_xaxis_name="BSSID",
2534+
_yaxis_name="Number of Changes",
2535+
# _xaxis_categories = [", ".join(x_axis)],
2536+
_xaxis_categories=[""],
2537+
_xaxis_label=x_axis,
2538+
_graph_image_name=f"bssid_change_count_{device_name}",
2539+
_label=x_axis,
2540+
_xaxis_step=1,
2541+
_graph_title=f"BSSID change count – {device_name}",
2542+
_title_size=16,
2543+
_color_edge='black',
2544+
_bar_width=0.15,
2545+
_figsize=(18, 6),
2546+
_legend_loc="best",
2547+
_legend_box=(1.0, 1.0),
2548+
_dpi=96,
2549+
_show_bar_value=True,
2550+
_enable_csv=True,
2551+
_color=['orange', 'lightcoral', 'steelblue', 'lightgrey'],
2552+
_color_name=['orange', 'lightcoral', 'steelblue', 'lightgrey'],
2553+
2554+
)
2555+
2556+
graph_png = graph.build_bar_graph()
2557+
report.set_graph_image(graph_png)
2558+
# need to move the graph image to the results directory
2559+
report.move_graph_image()
2560+
report.set_csv_filename(graph_png)
2561+
report.move_csv_file()
2562+
report.build_graph()
2563+
2564+
report.set_obj_html(
2565+
_obj_title=f"Band Steering Results for {device_name}",
2566+
_obj=" ")
2567+
report.build_objective()
2568+
table_df = {
2569+
"Timestamp": timestamp_list,
2570+
"BSSID": bssid_list,
2571+
"Channel": channel_list,
2572+
"From Coordinate": from_coordinate_list,
2573+
"To Coordinate": to_coordinate_list
2574+
}
2575+
table_df = pd.DataFrame(table_df)
2576+
report.set_table_dataframe(table_df)
2577+
report.build_table()
2578+
24542579

24552580
def validate_args(args):
24562581
# input sanity
@@ -2596,6 +2721,11 @@ def main():
25962721
python3 lf_interop_ping_plotter.py --mgr 192.168.207.78 --real --target 8.8.8.8 --ping_interval 1 --ping_duration 1m --use_default_config
25972722
--robot_ip 192.168.204.76 --coordinate 3,4 --rotation 45,90
25982723
2724+
EXAMPLE-16:
2725+
Command Line Interface to run ping plotter test with desired resources at desired points with bandsteering using robo
2726+
python3 lf_interop_ping_plotter.py --mgr 192.168.207.78 --real --target 8.8.8.8 --ping_interval 1 --ping_duration 1m --use_default_config
2727+
--robot_ip 192.168.204.76 --coordinate 3,4 --do_bandsteering --total_cycles 3 --bssids 94:A6:7E:74:26:33,94:A6:7E:74:26:22
2728+
25992729
26002730
26012731
SCRIPT_CLASSIFICATION : Test

0 commit comments

Comments
 (0)