diff --git a/py-scripts/lf_ftp.py b/py-scripts/lf_ftp.py index 15be8ca2b..04961bfc4 100755 --- a/py-scripts/lf_ftp.py +++ b/py-scripts/lf_ftp.py @@ -1572,7 +1572,7 @@ def updating_webui_runningjson(self, obj): def my_monitor(self): dataset = [] - self.channel_list, self.mode_list, self.ssid_list, self.uc_avg, self.uc_max, self.url_data, self.uc_min, self.bytes_rd = [], [], [], [], [], [], [], [] + self.channel_list, self.mode_list, self.ssid_list, self.uc_avg, self.uc_max, self.url_data, self.uc_min, self.bytes_rd, self.rx_rate = [], [], [], [], [], [], [], [], [] if self.clients_type == "Virtual": response_port = self.json_get("/port/all") for interface in response_port['interfaces']: @@ -1606,6 +1606,7 @@ def my_monitor(self): uc_min_data = self.json_get("layer4/list?fields=uc-min") total_url_data = self.json_get("layer4/list?fields=total-urls") bytes_rd = self.json_get("layer4/list?fields=bytes-rd") + rx_rate_data = self.json_get("layer4/list?fields=rx rate (1m)") print(uc_avg_data) print(total_url_data) self.data_for_webui = {} @@ -1620,6 +1621,7 @@ def my_monitor(self): # reading uc-avg data in json format self.url_data.append(total_url_data['endpoint']['total-urls']) dataset.append(bytes_rd['endpoint']['bytes-rd']) + self.rx_rate.append(rx_rate_data['endpoint']['rx rate (1m)']) if self.dowebgui == "True": self.data_for_webui["url_data"] = self.url_data self.data_for_webui["start_time"] = self.data["start_time"] @@ -1654,6 +1656,11 @@ def my_monitor(self): if CX == created_cx: dataset.append(cx[CX]['bytes-rd']) self.bytes_rd = [float(f"{(i / 1000000): .4f}") for i in dataset] + for cx in rx_rate_data['endpoint']: + for CX in cx: + for created_cx in self.cx_list: + if CX == created_cx: + self.rx_rate.append(cx[CX]['rx rate (1m)']) if self.dowebgui == "True": # FOR WEB-UI // storing values in self which is used to update the csv at the end. self.data_for_webui["url_data"] = self.url_data diff --git a/py-scripts/lf_mixed_traffic.py b/py-scripts/lf_mixed_traffic.py index be84b0257..f38426f29 100755 --- a/py-scripts/lf_mixed_traffic.py +++ b/py-scripts/lf_mixed_traffic.py @@ -1044,7 +1044,9 @@ def qos_test_overall_virtual(qos_tos_virtual=None): port=self.port, number_template="0000", ap_name=ap_name, - num_stations=self.num_staions, + num_stations_2g=self.num_staions if "2.4G" in self.band else 0, + num_stations_5g=self.num_staions if "5G" in self.band else 0, + num_stations_6g=self.num_staions if "6G" in self.band else 0, sta_list=self.station_list, create_sta=False, name_prefix="TOS-", @@ -2029,7 +2031,10 @@ def generate_all_report(self, iot_summary=None): if res: self.data_set, self.load, res1 = qos_obj.generate_graph_data_set(res) qos_obj.tos = tos - qos_obj.generate_individual_graph(res1, self.lf_report_mt, qos_obj.connections_download_avg, qos_obj.connections_upload_avg, qos_obj.avg_drop_a, qos_obj.avg_drop_b) + if self.virtual: + qos_obj.generate_individual_graph(res1, self.lf_report_mt) + else: + qos_obj.generate_individual_graph(res1, self.lf_report_mt, qos_obj.connections_download_avg, qos_obj.connections_upload_avg, qos_obj.avg_drop_a, qos_obj.avg_drop_b) else: df_throughput = pd.DataFrame(self.res["throughput_table_df"]) self.lf_report_mt.set_table_dataframe(df_throughput) @@ -2065,8 +2070,11 @@ def generate_all_report(self, iot_summary=None): self.lf_report_mt.build_graph() # Helpful for testhouse when both QoS and multicast are checked, to avoid generating redundant RSSI heatmaps. multicast_exists = "5" in self.tests and self.get_live_view - qos_obj.generate_individual_graph(self.res, self.lf_report_mt, qos_obj.connections_download_avg, qos_obj.connections_upload_avg, qos_obj.avg_drop_a, - qos_obj.avg_drop_b, self.total_floors, multicast_exists) + if self.virtual: + qos_obj.generate_individual_graph(self.res, self.lf_report_mt) + else: + qos_obj.generate_individual_graph(self.res, self.lf_report_mt, qos_obj.connections_download_avg, qos_obj.connections_upload_avg, qos_obj.avg_drop_a, + qos_obj.avg_drop_b, self.total_floors, multicast_exists) if "3" in self.tests and self.ftp_test_status: # 3.FTP test reporting in mixed traffic self.lf_report_mt.set_obj_html(_obj_title="3. File Transfer Protocol (FTP) Test", _obj="") @@ -3295,7 +3303,10 @@ def main(): mixed_obj.ping_test_obj, mixed_obj.ping_test_status = t1_parent.recv() t1.join() if "2" in args.tests: - mixed_obj.qos_test_obj, mixed_obj.data_set, mixed_obj.load, mixed_obj.res, mixed_obj.qos_test_status = t2_parent.recv() + if mixed_obj.virtual: + mixed_obj.throughput_qos_obj, mixed_obj.data_set, mixed_obj.load, mixed_obj.res, mixed_obj.qos_test_status = t2_parent.recv() + else: + mixed_obj.qos_test_obj, mixed_obj.data_set, mixed_obj.load, mixed_obj.res, mixed_obj.qos_test_status = t2_parent.recv() t2.join() if "3" in args.tests: mixed_obj.ftp_test_obj, mixed_obj.ftp_test_status = t3_parent.recv() @@ -3372,7 +3383,7 @@ def __init__(self, client_dict_A, client_dict_B): start_id=args.sixg_start_id, all_sta=True) # updating num stations and station list virtual_station_list = sta_list_2g + sta_list_5g + sta_list_6g - logger.info("List of selected virtual stations:", virtual_station_list) + logger.info("List of selected virtual stations: {}".format(virtual_station_list)) mixed_obj.station_list = virtual_station_list mixed_obj.num_staions = args.twog_num_stations + args.fiveg_num_stations + args.sixg_num_stations if (args.use_default_config): @@ -3494,7 +3505,10 @@ def __init__(self, client_dict_A, client_dict_B): mixed_obj.ping_test_obj, mixed_obj.ping_test_status = t1_parent.recv() t1.join() if "2" in args.tests: - mixed_obj.qos_test_obj, mixed_obj.data_set, mixed_obj.load, mixed_obj.res, mixed_obj.qos_test_status = t2_parent.recv() + if mixed_obj.virtual: + mixed_obj.throughput_qos_obj, mixed_obj.data_set, mixed_obj.load, mixed_obj.res, mixed_obj.qos_test_status = t2_parent.recv() + else: + mixed_obj.qos_test_obj, mixed_obj.data_set, mixed_obj.load, mixed_obj.res, mixed_obj.qos_test_status = t2_parent.recv() t2.join() if "3" in args.tests: mixed_obj.ftp_test_obj, mixed_obj.ftp_test_status = t3_parent.recv() diff --git a/py-scripts/throughput_qos.py b/py-scripts/throughput_qos.py index 0d99ee80b..6d4bebb06 100755 --- a/py-scripts/throughput_qos.py +++ b/py-scripts/throughput_qos.py @@ -65,6 +65,7 @@ from datetime import datetime, timedelta import argparse +import logging import time import sys import os @@ -87,6 +88,8 @@ realm = importlib.import_module("py-json.realm") Realm = realm.Realm +logger = logging.getLogger(__name__) + class ThroughputQOS(Realm): def __init__(self, @@ -176,6 +179,7 @@ def __init__(self, self.direction = direction self.traffic_type = traffic_type self.tos = tos.split(",") + self.cx_endpoint_lookup_failed_logged = set() self.bands = bands.split(",") self.test_case = test_case self.number_template = number_template @@ -519,66 +523,110 @@ def evaluate_qos(self, connections_download, connections_upload, drop_a_per, dro temp = sta.rsplit('-', 1) temp = int(temp[1]) if temp in range(0, num_stations): - if int(self.cx_profile.side_b_min_bps) != 0: - tos_download[self.tos[0]].append(connections_download[sta]) - tos_drop_dict['rx_drop_a'][self.tos[0]].append(drop_a_per[temp]) - tx_b_download[self.tos[0]].append(int(f"{tx_endps_download['%s-B' % sta]['tx pkts ll']}")) - rx_a_download[self.tos[0]].append(int(f"{rx_endps_download['%s-A' % sta]['rx pkts ll']}")) - delay[self.tos[0]].append(rx_endps_download['%s-A' % sta]['delay']) - else: - tos_download[self.tos[0]].append(float(0)) - tos_drop_dict['rx_drop_a'][self.tos[0]].append(float(0)) - tx_b_download[self.tos[0]].append(int(0)) - rx_a_download[self.tos[0]].append(int(0)) - delay[self.tos[0]].append(int(0)) + try: + if int(self.cx_profile.side_b_min_bps) != 0: + tos_download[self.tos[0]].append(connections_download[sta]) + tos_drop_dict['rx_drop_a'][self.tos[0]].append(drop_a_per[temp]) + tx_b_download[self.tos[0]].append(int(f"{tx_endps_download['%s-B' % sta]['tx pkts ll']}")) + rx_a_download[self.tos[0]].append(int(f"{rx_endps_download['%s-A' % sta]['rx pkts ll']}")) + delay[self.tos[0]].append(rx_endps_download['%s-A' % sta]['delay']) + else: + tos_download[self.tos[0]].append(float(0)) + tos_drop_dict['rx_drop_a'][self.tos[0]].append(float(0)) + tx_b_download[self.tos[0]].append(int(0)) + rx_a_download[self.tos[0]].append(int(0)) + delay[self.tos[0]].append(int(0)) + # log "CX Not Found" once per occurrence instead of on every tick + except Exception: + if sta not in self.cx_endpoint_lookup_failed_logged: + logger.warning( + "%s-A/B : Endpoint Not Found\n" + "Endpoint keys: %s", + sta, + [key for endpoint in endps if isinstance(endpoint, dict) for key in endpoint], + ) + self.cx_endpoint_lookup_failed_logged.add(sta) elif temp in range(num_stations, 2 * num_stations): if len(self.tos) < 2: break else: - if int(self.cx_profile.side_b_min_bps) != 0: - tos_download[self.tos[1]].append(connections_download[sta]) - tos_drop_dict['rx_drop_a'][self.tos[1]].append(drop_a_per[temp]) - tx_b_download[self.tos[1]].append(int(f"{tx_endps_download['%s-B' % sta]['tx pkts ll']}")) - rx_a_download[self.tos[1]].append(int(f"{rx_endps_download['%s-A' % sta]['rx pkts ll']}")) - delay[self.tos[1]].append(rx_endps_download['%s-A' % sta]['delay']) - else: - tos_download[self.tos[1]].append(float(0)) - tos_drop_dict['rx_drop_a'][self.tos[1]].append(float(0)) - tx_b_download[self.tos[1]].append(int(0)) - rx_a_download[self.tos[1]].append(int(0)) - delay[self.tos[1]].append(int(0)) + try: + if int(self.cx_profile.side_b_min_bps) != 0: + tos_download[self.tos[1]].append(connections_download[sta]) + tos_drop_dict['rx_drop_a'][self.tos[1]].append(drop_a_per[temp]) + tx_b_download[self.tos[1]].append(int(f"{tx_endps_download['%s-B' % sta]['tx pkts ll']}")) + rx_a_download[self.tos[1]].append(int(f"{rx_endps_download['%s-A' % sta]['rx pkts ll']}")) + delay[self.tos[1]].append(rx_endps_download['%s-A' % sta]['delay']) + else: + tos_download[self.tos[1]].append(float(0)) + tos_drop_dict['rx_drop_a'][self.tos[1]].append(float(0)) + tx_b_download[self.tos[1]].append(int(0)) + rx_a_download[self.tos[1]].append(int(0)) + delay[self.tos[1]].append(int(0)) + # log "CX Not Found" once per occurrence instead of on every tick + except Exception: + if sta not in self.cx_endpoint_lookup_failed_logged: + logger.warning( + "%s-A/B : Endpoint Not Found\n" + "Endpoint keys: %s", + sta, + [key for endpoint in endps if isinstance(endpoint, dict) for key in endpoint], + ) + self.cx_endpoint_lookup_failed_logged.add(sta) elif temp in range(2 * num_stations, 3 * num_stations): if len(self.tos) < 3: break else: - if int(self.cx_profile.side_b_min_bps) != 0: - tos_download[self.tos[2]].append(connections_download[sta]) - tos_drop_dict['rx_drop_a'][self.tos[2]].append(drop_a_per[temp]) - tx_b_download[self.tos[2]].append(int(f"{tx_endps_download['%s-B' % sta]['tx pkts ll']}")) - rx_a_download[self.tos[2]].append(int(f"{rx_endps_download['%s-A' % sta]['rx pkts ll']}")) - delay[self.tos[2]].append(rx_endps_download['%s-A' % sta]['delay']) - else: - tos_download[self.tos[2]].append(float(0)) - tos_drop_dict['rx_drop_a'][self.tos[2]].append(float(0)) - tx_b_download[self.tos[2]].append(int(0)) - rx_a_download[self.tos[2]].append(int(0)) - delay[self.tos[2]].append(int(0)) + try: + if int(self.cx_profile.side_b_min_bps) != 0: + tos_download[self.tos[2]].append(connections_download[sta]) + tos_drop_dict['rx_drop_a'][self.tos[2]].append(drop_a_per[temp]) + tx_b_download[self.tos[2]].append(int(f"{tx_endps_download['%s-B' % sta]['tx pkts ll']}")) + rx_a_download[self.tos[2]].append(int(f"{rx_endps_download['%s-A' % sta]['rx pkts ll']}")) + delay[self.tos[2]].append(rx_endps_download['%s-A' % sta]['delay']) + else: + tos_download[self.tos[2]].append(float(0)) + tos_drop_dict['rx_drop_a'][self.tos[2]].append(float(0)) + tx_b_download[self.tos[2]].append(int(0)) + rx_a_download[self.tos[2]].append(int(0)) + delay[self.tos[2]].append(int(0)) + # log "CX Not Found" once per occurrence instead of on every tick + except Exception: + if sta not in self.cx_endpoint_lookup_failed_logged: + logger.warning( + "%s-A/B : Endpoint Not Found\n" + "Endpoint keys: %s", + sta, + [key for endpoint in endps if isinstance(endpoint, dict) for key in endpoint], + ) + self.cx_endpoint_lookup_failed_logged.add(sta) elif temp in range(3 * num_stations, 4 * num_stations): if len(self.tos) < 4: break else: - if int(self.cx_profile.side_b_min_bps) != 0: - tos_download[self.tos[3]].append(connections_download[sta]) - tos_drop_dict['rx_drop_a'][self.tos[3]].append(drop_a_per[temp]) - tx_b_download[self.tos[3]].append(int(f"{tx_endps_download['%s-B' % sta]['tx pkts ll']}")) - rx_a_download[self.tos[3]].append(int(f"{rx_endps_download['%s-A' % sta]['rx pkts ll']}")) - delay[self.tos[3]].append(rx_endps_download['%s-A' % sta]['delay']) - else: - tos_download[self.tos[3]].append(float(0)) - tos_drop_dict['rx_drop_a'][self.tos[3]].append(float(0)) - tx_b_download[self.tos[3]].append(int(0)) - rx_a_download[self.tos[3]].append(int(0)) - delay[self.tos[3]].append(int(0)) + try: + if int(self.cx_profile.side_b_min_bps) != 0: + tos_download[self.tos[3]].append(connections_download[sta]) + tos_drop_dict['rx_drop_a'][self.tos[3]].append(drop_a_per[temp]) + tx_b_download[self.tos[3]].append(int(f"{tx_endps_download['%s-B' % sta]['tx pkts ll']}")) + rx_a_download[self.tos[3]].append(int(f"{rx_endps_download['%s-A' % sta]['rx pkts ll']}")) + delay[self.tos[3]].append(rx_endps_download['%s-A' % sta]['delay']) + else: + tos_download[self.tos[3]].append(float(0)) + tos_drop_dict['rx_drop_a'][self.tos[3]].append(float(0)) + tx_b_download[self.tos[3]].append(int(0)) + rx_a_download[self.tos[3]].append(int(0)) + delay[self.tos[3]].append(int(0)) + # log "CX Not Found" once per occurrence instead of on every tick + except Exception: + if sta not in self.cx_endpoint_lookup_failed_logged: + logger.warning( + "%s-A/B : Endpoint Not Found\n" + "Endpoint keys: %s", + sta, + [key for endpoint in endps if isinstance(endpoint, dict) for key in endpoint], + ) + self.cx_endpoint_lookup_failed_logged.add(sta) tos_download.update({"bkQOS": float(f"{sum(tos_download['BK']):.2f}")}) tos_download.update({"beQOS": float(f"{sum(tos_download['BE']):.2f}")}) tos_download.update({"videoQOS": float(f"{sum(tos_download['VI']):.2f}")}) @@ -636,66 +684,110 @@ def evaluate_qos(self, connections_download, connections_upload, drop_a_per, dro temp = sta.rsplit('-', 1) temp = int(temp[1]) if temp in range(0, num_stations): - if int(self.cx_profile.side_a_min_bps) != 0: - tos_upload[self.tos[0]].append(connections_upload[sta]) - tos_drop_dict['rx_drop_b'][self.tos[0]].append(drop_b_per[temp]) - tx_b_upload[self.tos[0]].append(int(f"{tx_endps_upload['%s-B' % sta]['tx pkts ll']}")) - rx_a_upload[self.tos[0]].append(int(f"{rx_endps_upload['%s-A' % sta]['rx pkts ll']}")) - delay[self.tos[0]].append(rx_endps_upload['%s-A' % sta]['delay']) - else: - tos_upload[self.tos[0]].append(float(0)) - tos_drop_dict['rx_drop_b'][self.tos[0]].append(float(0)) - tx_b_upload[self.tos[0]].append(int(0)) - rx_a_upload[self.tos[0]].append(int(0)) - delay[self.tos[0]].append(int(0)) + try: + if int(self.cx_profile.side_a_min_bps) != 0: + tos_upload[self.tos[0]].append(connections_upload[sta]) + tos_drop_dict['rx_drop_b'][self.tos[0]].append(drop_b_per[temp]) + tx_b_upload[self.tos[0]].append(int(f"{tx_endps_upload['%s-B' % sta]['tx pkts ll']}")) + rx_a_upload[self.tos[0]].append(int(f"{rx_endps_upload['%s-A' % sta]['rx pkts ll']}")) + delay[self.tos[0]].append(rx_endps_upload['%s-A' % sta]['delay']) + else: + tos_upload[self.tos[0]].append(float(0)) + tos_drop_dict['rx_drop_b'][self.tos[0]].append(float(0)) + tx_b_upload[self.tos[0]].append(int(0)) + rx_a_upload[self.tos[0]].append(int(0)) + delay[self.tos[0]].append(int(0)) + # log "CX Not Found" once per occurrence instead of on every tick + except Exception: + if sta not in self.cx_endpoint_lookup_failed_logged: + logger.warning( + "%s-A/B : Endpoint Not Found\n" + "Endpoint keys: %s", + sta, + [key for endpoint in endps if isinstance(endpoint, dict) for key in endpoint], + ) + self.cx_endpoint_lookup_failed_logged.add(sta) elif temp in range(num_stations, 2 * num_stations): if len(self.tos) < 2: break else: - if int(self.cx_profile.side_a_min_bps) != 0: - tos_upload[self.tos[1]].append(connections_upload[sta]) - tos_drop_dict['rx_drop_b'][self.tos[1]].append(drop_b_per[temp]) - tx_b_upload[self.tos[1]].append(int(f"{tx_endps_upload['%s-B' % sta]['tx pkts ll']}")) - rx_a_upload[self.tos[1]].append(int(f"{rx_endps_upload['%s-A' % sta]['rx pkts ll']}")) - delay[self.tos[1]].append(rx_endps_upload['%s-A' % sta]['delay']) - else: - tos_upload[self.tos[1]].append(float(0)) - tos_drop_dict['rx_drop_b'][self.tos[1]].append(float(0)) - tx_b_upload[self.tos[1]].append(int(0)) - rx_a_upload[self.tos[1]].append(int(0)) - delay[self.tos[1]].append(int(0)) + try: + if int(self.cx_profile.side_a_min_bps) != 0: + tos_upload[self.tos[1]].append(connections_upload[sta]) + tos_drop_dict['rx_drop_b'][self.tos[1]].append(drop_b_per[temp]) + tx_b_upload[self.tos[1]].append(int(f"{tx_endps_upload['%s-B' % sta]['tx pkts ll']}")) + rx_a_upload[self.tos[1]].append(int(f"{rx_endps_upload['%s-A' % sta]['rx pkts ll']}")) + delay[self.tos[1]].append(rx_endps_upload['%s-A' % sta]['delay']) + else: + tos_upload[self.tos[1]].append(float(0)) + tos_drop_dict['rx_drop_b'][self.tos[1]].append(float(0)) + tx_b_upload[self.tos[1]].append(int(0)) + rx_a_upload[self.tos[1]].append(int(0)) + delay[self.tos[1]].append(int(0)) + # log "CX Not Found" once per occurrence instead of on every tick + except Exception: + if sta not in self.cx_endpoint_lookup_failed_logged: + logger.warning( + "%s-A/B : Endpoint Not Found\n" + "Endpoint keys: %s", + sta, + [key for endpoint in endps if isinstance(endpoint, dict) for key in endpoint], + ) + self.cx_endpoint_lookup_failed_logged.add(sta) elif temp in range(2 * num_stations, 3 * num_stations): if len(self.tos) < 3: break else: - if int(self.cx_profile.side_a_min_bps) != 0: - tos_upload[self.tos[2]].append(connections_upload[sta]) - tos_drop_dict['rx_drop_b'][self.tos[2]].append(drop_b_per[temp]) - tx_b_upload[self.tos[2]].append(int(f"{tx_endps_upload['%s-B' % sta]['tx pkts ll']}")) - rx_a_upload[self.tos[2]].append(int(f"{rx_endps_upload['%s-A' % sta]['rx pkts ll']}")) - delay[self.tos[2]].append(rx_endps_upload['%s-A' % sta]['delay']) - else: - tos_upload[self.tos[2]].append(float(0)) - tos_drop_dict['rx_drop_b'][self.tos[2]].append(float(0)) - tx_b_upload[self.tos[2]].append(int(0)) - rx_a_upload[self.tos[2]].append(int(0)) - delay[self.tos[2]].append(int(0)) + try: + if int(self.cx_profile.side_a_min_bps) != 0: + tos_upload[self.tos[2]].append(connections_upload[sta]) + tos_drop_dict['rx_drop_b'][self.tos[2]].append(drop_b_per[temp]) + tx_b_upload[self.tos[2]].append(int(f"{tx_endps_upload['%s-B' % sta]['tx pkts ll']}")) + rx_a_upload[self.tos[2]].append(int(f"{rx_endps_upload['%s-A' % sta]['rx pkts ll']}")) + delay[self.tos[2]].append(rx_endps_upload['%s-A' % sta]['delay']) + else: + tos_upload[self.tos[2]].append(float(0)) + tos_drop_dict['rx_drop_b'][self.tos[2]].append(float(0)) + tx_b_upload[self.tos[2]].append(int(0)) + rx_a_upload[self.tos[2]].append(int(0)) + delay[self.tos[2]].append(int(0)) + # log "CX Not Found" once per occurrence instead of on every tick + except Exception: + if sta not in self.cx_endpoint_lookup_failed_logged: + logger.warning( + "%s-A/B : Endpoint Not Found\n" + "Endpoint keys: %s", + sta, + [key for endpoint in endps if isinstance(endpoint, dict) for key in endpoint], + ) + self.cx_endpoint_lookup_failed_logged.add(sta) elif temp in range(3 * num_stations, 4 * num_stations): if len(self.tos) < 4: break else: - if int(self.cx_profile.side_a_min_bps) != 0: - tos_upload[self.tos[3]].append(connections_upload[sta]) - tos_drop_dict['rx_drop_b'][self.tos[3]].append(drop_b_per[temp]) - tx_b_upload[self.tos[3]].append(int(f"{tx_endps_upload['%s-B' % sta]['tx pkts ll']}")) - rx_a_upload[self.tos[3]].append(int(f"{rx_endps_upload['%s-A' % sta]['rx pkts ll']}")) - delay[self.tos[3]].append(rx_endps_upload['%s-A' % sta]['delay']) - else: - tos_upload[self.tos[3]].append(float(0)) - tos_drop_dict['rx_drop_b'][self.tos[3]].append(float(0)) - tx_b_upload[self.tos[3]].append(int(0)) - rx_a_upload[self.tos[3]].append(int(0)) - delay[self.tos[3]].append(int(0)) + try: + if int(self.cx_profile.side_a_min_bps) != 0: + tos_upload[self.tos[3]].append(connections_upload[sta]) + tos_drop_dict['rx_drop_b'][self.tos[3]].append(drop_b_per[temp]) + tx_b_upload[self.tos[3]].append(int(f"{tx_endps_upload['%s-B' % sta]['tx pkts ll']}")) + rx_a_upload[self.tos[3]].append(int(f"{rx_endps_upload['%s-A' % sta]['rx pkts ll']}")) + delay[self.tos[3]].append(rx_endps_upload['%s-A' % sta]['delay']) + else: + tos_upload[self.tos[3]].append(float(0)) + tos_drop_dict['rx_drop_b'][self.tos[3]].append(float(0)) + tx_b_upload[self.tos[3]].append(int(0)) + rx_a_upload[self.tos[3]].append(int(0)) + delay[self.tos[3]].append(int(0)) + # log "CX Not Found" once per occurrence instead of on every tick + except Exception: + if sta not in self.cx_endpoint_lookup_failed_logged: + logger.warning( + "%s-A/B : Endpoint Not Found\n" + "Endpoint keys: %s", + sta, + [key for endpoint in endps if isinstance(endpoint, dict) for key in endpoint], + ) + self.cx_endpoint_lookup_failed_logged.add(sta) tos_upload.update({"bkQOS": float(f"{sum(tos_upload['BK']):.2f}")}) tos_upload.update({"beQOS": float(f"{sum(tos_upload['BE']):.2f}")}) tos_upload.update({"videoQOS": float(f"{sum(tos_upload['VI']):.2f}")})