def download_test_results_zip(): try: if len(app_variables.previous_mtr_results_file_locations) > 0: date_time = datetime.date.today().strftime("D%dM%mY%Y") return_zip_file = BytesIO() zip_name = "TestResults_" + gethostname() + "_" + date_time + ".zip" file_meta_data_list = [] names_of_files = [] file_to_zip = [] file_creation_dates = [] previous_mtr_results_file_locations = app_variables.previous_mtr_results_file_locations previous_iperf_results_file_locations = app_variables.previous_iperf_results_file_locations for file_location in (previous_mtr_results_file_locations + previous_iperf_results_file_locations): file_to_zip.append(app_generic_functions.get_file_content(file_location)) names_of_files.append(file_location.split("/")[-1]) file_creation_dates.append(time.localtime(os.path.getmtime(file_location))) for name, modification_date in zip(names_of_files, file_creation_dates): name_data = ZipInfo(name) name_data.date_time = modification_date name_data.compress_type = ZIP_DEFLATED file_meta_data_list.append(name_data) with ZipFile(return_zip_file, "w") as zip_file: for file_meta_data, file_content in zip(file_meta_data_list, file_to_zip): zip_file.writestr(file_meta_data, file_content) return_zip_file.seek(0) return send_file(return_zip_file, as_attachment=True, attachment_filename=zip_name) except Exception as error: primary_logger.error("Error zipping test results: " + str(error)) return render_template("message_return.html", URL="/", TextMessage="No Results Found")
def __init__(self): self.full_system_text = get_raspberry_pi_model() self.band_width_message = "Available Bandwidth:\n Unknown Mbps" if self.full_system_text == "Raspberry Pi 3 Model B Plus": self.band_width_message = "Available Bandwidth:\n up to 299 Mbps" elif self.full_system_text == "Raspberry Pi 4 Model B": self.band_width_message = "Available Bandwidth:\n up to 999 Mbps" try: os.system("raspi-config nonint do_spi 0") primary_logger.debug("Enabled SPI for WaveShare 2.7 E-Paper") except Exception as error: primary_logger.error("Error Enabling SPI for WaveShare 2.7 E-Paper: " + str(error)) self.display_in_use = False # GPIO key to Pin #s self.key1 = 5 self.key2 = 6 self.key3 = 13 self.key4 = 19 self.rpi_gpio_import = __import__('RPi.GPIO', fromlist=["setmode", "BCM", "setup", "IN", "PUD_UP", "input"]) self.epd2in7_import = __import__("supported_hardware.drivers.waveshare.epd2in7", fromlist=["EPD", "EPD_WIDTH", "EPD_HEIGHT"]) self.esp = self.epd2in7_import.EPD() self.esp.init() self.rpi_gpio_import.setmode(self.rpi_gpio_import.BCM) self.rpi_gpio_import.setup(self.key1, self.rpi_gpio_import.IN, pull_up_down=self.rpi_gpio_import.PUD_UP) self.rpi_gpio_import.setup(self.key2, self.rpi_gpio_import.IN, pull_up_down=self.rpi_gpio_import.PUD_UP) self.rpi_gpio_import.setup(self.key3, self.rpi_gpio_import.IN, pull_up_down=self.rpi_gpio_import.PUD_UP) self.rpi_gpio_import.setup(self.key4, self.rpi_gpio_import.IN, pull_up_down=self.rpi_gpio_import.PUD_UP)
def start_run_at_date(): app_variables.restart_run_once_test_server = 0 while not app_variables.restart_run_once_test_server: while not current_config.schedule_run_once_enabled: sleep(30) try: utc_now = datetime.utcnow() scheduled_runtime = datetime.strptime( current_config.schedule_run_once_at_time, "%Y-%m-%dT%H:%M") sleep_time = (scheduled_runtime - utc_now).total_seconds() if sleep_time > 0: total_sleep_time = 0 skip_test_runs = 0 primary_logger.info("Single Run Tests set to run in: " + str(sleep_time) + " Seconds") while total_sleep_time < sleep_time: sleep(5) total_sleep_time += 5 if app_variables.restart_run_once_test_server: skip_test_runs = 1 sleep_time = total_sleep_time if not skip_test_runs: run_commands.start_mtr() run_commands.start_iperf() else: primary_logger.warning( "Single Run Tests Date & Time has already passed, disabling Run Once Schedule" ) current_config.schedule_run_once_enabled = 0 current_config.write_config_to_file() except Exception as error: primary_logger.error("Single scheduled test run: " + str(error)) current_config.schedule_run_once_enabled = 0
def load_installed_hardware_from_file(self): """ Loads Installed Hardware configuration from local disk. """ log_msg = "Loading Installed Hardware Configuration from: " + file_locations.installed_hardware_file_location primary_logger.debug(log_msg) if os.path.isfile(file_locations.installed_hardware_file_location): try: config_file_lines = get_file_content( file_locations.installed_hardware_file_location).split( "\n") config_list = [] for line in config_file_lines: config_list.append(line.split("=")[0].strip()) self.installed_interactive_hw["WaveShare27"] = int( config_list[1]) except Exception as error: primary_logger.error( "Unable to load Installed Hardware configuration File: " + str(error)) self.write_installed_hardware_to_file() else: primary_logger.warning( "No Installed Hardware Configuration file found, saving default" ) self.write_installed_hardware_to_file()
def write_file_to_disk(file_location, file_content, open_type="w"): """ Writes provided file and content to local disk. """ try: write_file = open(file_location, open_type) write_file.write(file_content) write_file.close() except Exception as error: primary_logger.error("Unable to write to file " + file_location + ": " + str(error))
def get_disk_free_percent(): """ Return's root free disk space as a % in string format. """ try: statvfs = os.statvfs(file_locations.location_save_report_folder) free_bytes = statvfs.f_frsize * statvfs.f_bfree return_disk_usage = str(round(free_bytes / 1_000_000_000, 3)) except Exception as error: primary_logger.error("Linux System - Get Disk Usage % Error: " + str(error)) return_disk_usage = "Error" return return_disk_usage
def get_file_content(file_location, open_type="r"): """ Loads provided file and returns it's content. """ if os.path.isfile(file_location): try: loaded_file = open(file_location, open_type) file_content = loaded_file.read() loaded_file.close() except Exception as error: primary_logger.error("Unable to open file " + file_location + ": " + str(error)) file_content = "" return file_content
def __init__(self): app = Flask(__name__) Compress(app) app.register_blueprint(http_server_routes.http_routes) try: http_server = WSGIServer((flask_http_ip, flask_http_port), app) http_server.serve_forever() except Exception as error: primary_logger.error("HTTP Server error: " + str(error)) while True: sleep(600)
def save_iperf_results_to_file(): primary_logger.info("Saving iPerf 3 test results to file") try: text_time_sec = str(time.time()).split(".")[0] new_file_location = file_locations.location_save_report_folder + "/iperf-" + text_time_sec + ".txt" write_file_to_disk(new_file_location, app_variables.web_iperf_results) app_variables.previous_iperf_results_file_locations = app_variables.get_previous_results_file_names( test_type="iperf") app_variables.previous_iperf_results_total = len( app_variables.previous_iperf_results_file_locations) except Exception as error: primary_logger.error("Error saving iPerf 3 test results to file: " + str(error))
def load_config_from_file(self): """ Loads Primary configuration from local disk and set's accordingly. """ primary_logger.debug("Loading Primary Configuration from: " + file_locations.config_file_location) if os.path.isfile(file_locations.config_file_location): try: config_file_lines = get_file_content( file_locations.config_file_location).split("\n") config_list = [] for line in config_file_lines: config_list.append(line.split("=")[0].strip()) self.is_iperf_server = int(config_list[1]) self.remote_tester_ip = config_list[2] self.iperf_port = config_list[3] self.mtr_run_count = config_list[4] if len(config_list) > 4: if config_list[5].strip() == "0": self.schedule_run_every_minutes = 0 else: self.schedule_run_every_minutes = int(config_list[5]) if len(config_list) > 5: if config_list[6].strip() == "0": self.schedule_run_on_boot = 0 else: self.schedule_run_on_boot = int(config_list[6]) if self.schedule_run_every_minutes < 5: self.schedule_run_every_minutes = 5 if len(config_list) > 6: if config_list[7].strip() == "0": self.schedule_run_every_minutes_enabled = 0 else: self.schedule_run_every_minutes_enabled = int( config_list[7]) if len(config_list) > 7: if config_list[8].strip() == "0": self.schedule_run_once_enabled = 0 else: self.schedule_run_once_enabled = int( config_list[8]) self.schedule_run_once_at_time = config_list[9] except Exception as error: primary_logger.error( "Unable to load Configuration File, saving default: " + str(error)) self.write_config_to_file() else: primary_logger.warning( "No Configuration file found, saving default") self.write_config_to_file()
def get_os_name_version(): """ Returns sensors Operating System Name and Version. """ try: os_release_content_lines = get_file_content("/etc/os-release").split( "\n") os_release_name = "" for line in os_release_content_lines: name_and_value = line.split("=") if name_and_value[0].strip() == "PRETTY_NAME": os_release_name = name_and_value[1].strip()[1:-1] return os_release_name except Exception as error: primary_logger.error( "Linux System - Unable to get Raspbian OS Version: " + str(error)) return "Error retrieving OS information"
def start_iperf(): if not current_config.iperf_running: current_config.iperf_running = True iperf_text_results = "Ran at " + time.strftime("%d/%m/%y - %H:%M") + "\n(DD/MM/YY - HH:MM)\n\n" + \ current_config.get_iperf_command_str() + "\n\n" try: primary_logger.info("Starting iPerf 3 Test: " + current_config.get_iperf_command_str()) temp_results_text = get_subprocess_str_output( current_config.get_iperf_command_str())[2:-2] iperf_text_results += temp_results_text app_variables.raw_iperf_results = temp_results_text primary_logger.info("iPerf 3 Test Complete") except Exception as error: primary_logger.error("iPerf Command Error: " + str(error)) iperf_text_results += "Error Connecting to Remote Test Server" app_variables.raw_iperf_results = "Error Connecting to Remote Test Server" current_config.iperf_running = False app_variables.web_iperf_results = iperf_text_results save_iperf_results_to_file()
def clear_previous_test_results(): message1 = "Previous test results cleared" message2 = "" try: previous_mtr_results_file_locations = app_variables.previous_mtr_results_file_locations previous_iperf_results_file_locations = app_variables.previous_iperf_results_file_locations for file_location in (previous_mtr_results_file_locations + previous_iperf_results_file_locations): os.remove(file_location) app_variables.previous_mtr_results_file_locations = app_variables.get_previous_results_file_names() app_variables.previous_mtr_result_selected = 1 app_variables.previous_mtr_results_total = len(app_variables.previous_mtr_results_file_locations) app_variables.previous_mtr_result_selected_cached = app_variables.get_selected_previous_result() app_variables.previous_iperf_results_file_locations = app_variables.get_previous_results_file_names(test_type="iperf") app_variables.previous_iperf_result_selected = 1 app_variables.previous_iperf_results_total = len(app_variables.previous_iperf_results_file_locations) app_variables.previous_iperf_result_selected_cached = app_variables.get_selected_previous_result(test_type="iperf") except Exception as error: primary_logger.error("Error clearing test results: " + str(error)) message1 = "Error clearing previous test results" message2 = str(error) return render_template("message_return.html", URL="/", TextMessage=message1, TextMessage2=message2)
def get_iperf_message(self): cli_results = app_variables.raw_iperf_results if cli_results != "Error Connecting to Remote Test Server": iperf_results_lines = cli_results.strip().split("\n") try: send_results_list = self._get_mtr_or_iperf_real_list(iperf_results_lines[-4].split(" ")) receive_line_list = self._get_mtr_or_iperf_real_list(iperf_results_lines[-3].split(" ")) message = "iPerf3 Results\n Dest: " + current_config.remote_tester_ip + "\n" + \ self.band_width_message + \ "\nAmount Transferred:\n In: " + \ str(receive_line_list[-5]) + " " + str(receive_line_list[-4]) + "\n Out: " + \ str(send_results_list[-6]) + " " + str(send_results_list[-5]) + "\n" + \ "Average Bandwidth:\n In: " + \ str(receive_line_list[-3]) + " " + str(receive_line_list[-2]) + "\n Out: " + \ str(send_results_list[-4]) + " " + str(send_results_list[-3]) + "\n" + \ " Over: " + str(receive_line_list[-7]) + " " + str(receive_line_list[-6]) except Exception as error: primary_logger.error("WaveShare iPerf Display Error: " + str(error)) message = " iPerf3 Failed\n Remote Test Server\n Offline Or Bad Network\n" else: message = " iPerf3 Failed\n Remote Test Server\n Offline Or Bad Network\n" message += "\n\nDate: " + strftime("%d/%m/%y") + " (D/M/Y)\nTime: " + strftime("%H:%M") return message
def start_run_every_minutes(): if current_config.schedule_run_on_boot: run_commands.start_mtr() run_commands.start_iperf() if current_config.schedule_run_every_minutes < 5: primary_logger.warning("Scheduled times cannot be less then 5 minutes") current_config.schedule_run_every_minutes = 5 if current_config.schedule_run_every_minutes_enabled: log_msg = "Tests scheduled to run every " + str( current_config.schedule_run_every_minutes) + " minutes" primary_logger.info(log_msg) while True: try: if current_config.schedule_run_every_minutes_enabled: sleep(current_config.schedule_run_every_minutes * 60) run_commands.start_mtr() run_commands.start_iperf() else: sleep(300) except Exception as error: primary_logger.error("Error Running Scheduled Test: " + str(error))
def start_mtr(): if not current_config.mtr_running: current_config.mtr_running = True mtr_text_results = "Ran at " + time.strftime("%d/%m/%y - %H:%M") + "\n(DD/MM/YY - HH:MM)\n\n" + \ current_config.get_mtr_command_str() + "\n\n" try: primary_logger.info("Starting MTR Test: " + current_config.get_mtr_command_str()) temp_lines = get_subprocess_str_output( current_config.get_mtr_command_str()).strip().split("\n") temp_lines = temp_lines[1:] new_str = "" for line in temp_lines: new_str += line + "\n" mtr_text_results += new_str.strip()[:-2] app_variables.raw_mtr_results = new_str.strip()[:-2] primary_logger.info("MTR Test Complete") except Exception as error: primary_logger.error("MTR Command Error: " + str(error)) mtr_text_results += "Error Connecting to Remote Test Server" app_variables.raw_mtr_results = "Error Connecting to Remote Test Server" app_variables.web_mtr_results = mtr_text_results current_config.mtr_running = False save_mtr_results_to_file()
GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. """ import os import re import time import subprocess from threading import Thread from operations_modules import file_locations from operations_modules.logger import primary_logger try: import requests except Exception as import_error: primary_logger.error("Problem Importing Requests: " + str(import_error)) class CreateMonitoredThread: def __init__(self, function, args=None, thread_name="Generic Thread", max_restart_tries=5): self.is_running = True self.function = function self.args = args self.thread_name = thread_name self.current_restart_count = 0 self.max_restart_count = max_restart_tries