diff --git a/Configs/Engine_cfg.yaml b/Configs/Engine_cfg.yaml index 0b6954a0..eba35b21 100644 --- a/Configs/Engine_cfg.yaml +++ b/Configs/Engine_cfg.yaml @@ -19,8 +19,8 @@ DBInfo: use_database: true -SerialCheckSafe: true -UsingScanner: true +SerialCheckSafe: false +UsingScanner: false # TestHandler: {name: Local, remoteip: localhost} # TestHandler: {name: SSH, username: , hostname: , remoteip: } @@ -33,47 +33,83 @@ PhysicalTest: desc_long: Check that the power and grounds are not shorted at the terminal, or between the inputs. desc_short: Measure resistance between power and ground + data_fields: + - name: Acceptable Value + critical: true + type: bool required: 1 - name: 1.5V Input Check desc_long: Check that resistance between across C906 or C908 is non-zero. desc_short: Check that the 1.5V input is not shorted. required: 1 + data_fields: + - name: Acceptable Value + critical: true + type: bool - name: 10V Input Check desc_long: Check that resistance between across C907 or C909 is non-zero. desc_short: Check that the 10V input is not shorted. required: 1 + data_fields: + - name: Acceptable Value + critical: true + type: bool - name: 1.2V Output Check desc_long: Check that resistance between across C904 or C904 or TP901 is non-zero. desc_short: Check that the 1.2V output is not shorted. required: 1 + data_fields: + - name: Acceptable Value + critical: true + type: bool - name: RX 2.5V Output Check desc_long: Check that resistance across C902 is non-zero. desc_short: Check that the RX 2.5V output is not shorted. required: 1 + data_fields: + - name: Acceptable Value + critical: true + type: bool - name: TX 2.5V Output Check desc_long: Check that resistance across either C903 or TP902 is non-zero. desc_short: Check that the TX 2.5V output is not shorted. required: 1 + data_fields: + - name: Acceptable Value + critical: true + type: bool - name: LDO Output desc_long: Measure the votlage across either R911 or TP901 and verify that it is appropriate. desc_short: Check that the LDO output voltage is around 1.2V required: 1 + data_fields: + - name: Acceptable Value + critical: true + type: bool - name: LinPol RX Check desc_long: Check that voltages across either R905 or R902 is 2.5V. desc_short: Check that the RX voltage from the linppol is operating correctly required: 1 + data_fields: + - name: Acceptable Value + critical: true + type: bool - name: LinPol TX Check desc_long: Measure the voltage across either TP902 or R906 or C903 is 2.5V. desc_short: Check that the TX voltage from the linppol is operating correctly required: 1 + data_fields: + - name: Acceptable Value + critical: true + type: bool Test: - TestClass: TestXPWR @@ -99,7 +135,7 @@ Test: TestScript: test_startup.py desc_long: Read lpgbt ids desc_short: Check ids - name: lpGBT ids + name: LPGBT ID required: 1 - TestClass: TestlpGBTcom diff --git a/PythonFiles/GUIConfig.py b/PythonFiles/GUIConfig.py index dbf70038..1db17ee7 100644 --- a/PythonFiles/GUIConfig.py +++ b/PythonFiles/GUIConfig.py @@ -39,8 +39,7 @@ def getNumPhysicalTest(self): # Returns the information necessary for physical test # Formatted as a dictionary def getPhysicalTestRequirements(self, num): - index = 0 - for ptest in self.board_cfg["PhysicalTest"]: + for index, ptest in enumerate(self.board_cfg["PhysicalTest"]): if index == num: return ptest diff --git a/PythonFiles/GUIWindow.py b/PythonFiles/GUIWindow.py index cff79c4d..59763f27 100644 --- a/PythonFiles/GUIWindow.py +++ b/PythonFiles/GUIWindow.py @@ -25,6 +25,7 @@ from PythonFiles.Scenes.AddUserScene import AddUserScene from PythonFiles.Scenes.PostScanScene import PostScanScene from PythonFiles.Scenes.PhysicalScenes.Inspection1 import Inspection1 +from PythonFiles.Scenes.PhysicalScenes.GenericPhysicalScene import GenericPhysicalScene from PythonFiles.update_config import update_config import webbrowser @@ -154,7 +155,7 @@ def create_test_frames(self, queue): # For the physical tests for test_idx,test in enumerate(physical_list): - self.test_frames.append(Inspection1(self, self.master_frame, self.data_holder, test_idx)) + self.test_frames.append(GenericPhysicalScene(self, self.master_frame, self.data_holder, test_idx, test)) self.test_frames[test_idx].grid(row=0, column=0) offset = offset + 1 @@ -411,6 +412,43 @@ def set_frame(self, _frame): ################################################# + def critical_failure_popup(self): + + logging.debug("GUIWindow: Critical test failed. Cannot proceed with testing") + + self.popup = tk.Toplevel() + self.popup.title("Critical Failure") + self.popup.geometry("300x150+500+300") + self.popup.grab_set() + + + frm_popup = tk.Frame(self.popup) + frm_popup.pack() + + lbl_popup = tk.Label( + frm_popup, + text = " This board has failed to pass\n a physical test. Cannot proceed.", + font = ('Arial', 13) + ) + lbl_popup.grid(column = 0, row = 0, columnspan = 2, pady = 25) + + def action(): + self.destroy_popup() + self.reset_board() + + btn_ok = tk.Button( + frm_popup, + width = 12, + height = 2, + text = "Exit", + font = ('Arial', 12), + relief = tk.RAISED, + command = lambda: action() + ) + btn_ok.grid(column = 0, row = 1, columnspan=2) + + + ################################################# def unable_to_exit(self): diff --git a/PythonFiles/Scenes/PhysicalScenes/GenericPhysicalScene.py b/PythonFiles/Scenes/PhysicalScenes/GenericPhysicalScene.py new file mode 100644 index 00000000..256aa8de --- /dev/null +++ b/PythonFiles/Scenes/PhysicalScenes/GenericPhysicalScene.py @@ -0,0 +1,239 @@ +import tkinter as tk +import tkinter.font as font + +class GenericPhysicalScene(tk.Frame): + + + def __init__(self, parent, master_frame, data_holder, test_idx, test_config): + super().__init__(master_frame, width=870, height=500) + + self.config = test_config + + self.test_name = "SOMETHING STRING" + self.data_holder = data_holder + + self.test_idx = test_idx + self.offset = 1 + self.values = {} + + + self.update_frame(parent) + + def create_btn_from_cfg(self, data_field): + + font_scene = ('Arial', 12) + font_scene_14 = ('Arial', 14) + + current_row = len(self.values.keys()) + self.offset + + if data_field['type'] == 'float': + lbl_tester = tk.Label( + self.frm_window, + text = "{}: ".format(data_field['name']), + font = font_scene + ) + lbl_tester.grid(row=current_row, column=1, pady=15 ) + + self.values[data_field['name']] = tk.StringVar() + + ent_tester = tk.Entry( + self.frm_window, + font = font_scene, + textvariable= self.values[data_field['name']], + ) + ent_tester.grid(row=current_row, column=2, pady=15 ) + + elif data_field['type'] == 'bool': + + self.values[data_field['name']] = tk.BooleanVar() + + c1 = tk.Checkbutton( + self.frm_window, + font = font_scene_14, + text='{}:'.format(data_field['name']), + variable= self.values[data_field['name']], + onvalue=1, + offvalue=0 + # command=print_selection + ) + c1.grid(row=current_row, column=1, pady=15 ) + + def update_frame(self, parent): + + # Creates a font to be more easily referenced later in the code + font_scene = ('Arial', 12) + font_scene_14 = ('Arial', 14) + + # Create a centralized window for information + self.frm_window = tk.Frame(self, width = 1105, height = 650) + self.frm_window.grid(column=0, row=0) + + # Create a label for the tester's name + lbl_tester = tk.Label( + self.frm_window, + text = "Tester: ", + font = font_scene + ) + lbl_tester.grid(row=0, column=0, pady=15 ) + + # Create an entry for the tester's name + ent_tester = tk.Entry( + self.frm_window, + font = font_scene + ) + ent_tester.insert(0, self.data_holder.data_dict['user_ID']) + ent_tester.grid(row=0, column=1, pady=15 ) + ent_tester.config(state = "disabled") + + # Create a label for the serial number box + lbl_snum = tk.Label( + self.frm_window, + text = "Serial Number: ", + font = font_scene + ) + lbl_snum.grid(row=0, column=2, pady=15 ) + + # Create a entry for the serial number box + ent_snum = tk.Entry( + self.frm_window, + font = font_scene + ) + ent_snum.insert(0, self.data_holder.data_dict['current_serial_ID']) + ent_snum.grid(row=0, column=3, pady=15) + ent_snum.config(state = "disabled") + + for data_field in self.config['data_fields']: + self.create_btn_from_cfg(data_field) + + # Create a button for confirming test + btn_confirm = tk.Button( + self.frm_window, + text = "Confirm", + relief = tk.RAISED, + command = lambda:self.btn_confirm_action(parent) + ) + btn_confirm.grid(row = 9, column= 1, pady= 50) + btn_confirm['font'] = font.Font(family = 'Arial', size = 13) + + + + # Create frame for logout button + nav_frame = tk.Frame(self) + nav_frame.grid(column = 1, row = 0, sticky = 'ne', padx =5) + + + # Create a rescan button + btn_rescan = tk.Button( + nav_frame, + text = "Change Boards", + relief = tk.RAISED, + command = lambda: self.btn_rescan_action(parent)) + btn_rescan.pack(anchor = 'ne', pady=15) + + # Create a logout button + btn_logout = tk.Button( + nav_frame, + text = "Logout", + relief = tk.RAISED, + command = lambda: self.btn_logout_action(parent)) + btn_logout.pack(anchor = 'se') + + # Creating the help button + btn_help = tk.Button( + nav_frame, + relief = tk.RAISED, + text = "Help", + command = lambda: self.help_action(parent) + ) + btn_help.pack(anchor = 's', padx = 10, pady = 10) + + + + + + # # # # # # # # # + + + self.grid_columnconfigure(4, weight=1) + self.grid_rowconfigure(0, weight=1) + + + self.frm_window.grid_propagate(0) + self.grid_propagate(0) + + ################################################# + + # Rescan button takes the user back to scanning in a new board + def btn_rescan_action(self, _parent): + _parent.set_frame_scan_frame() + + ################################################# + + # Back button action takes the user back to the scanning device + def btn_back_action(self, _parent): + pass + + ################################################# + + def update_data_holder(self): + + # Automatically passes the physical tests after completion + + self.data_holder.inspection_data[self.config['name']] = {} + for data_field in self.config['data_fields']: + self.data_holder.inspection_data[self.config['name']][data_field['name']] = self.values[data_field['name']].get() + #self.data_holder.add_inspection_to_comments() + + passed = True + for data_field in [x for x in self.config['data_fields'] if x['critical']]: + if data_field['type'] == 'float': + passed &= float(data_field['required_range']['max']) >= float(self.values[data_field['name']].get()) and float(data_field['required_range']['min']) <= float(self.values[data_field['name']].get()) + elif data_field['type'] == 'bool': + passed &= self.values[data_field['name']].get() + if not passed: break + + self.data_holder.data_lists['physical_results'][self.test_idx] = passed + + self.data_holder.print() + + return passed + + + ################################################# + + # Confirm button action takes the user to the test in progress scene + def btn_confirm_action(self, _parent): + + if self.update_data_holder(): + _parent.go_to_next_test() + else: + _parent.critical_failure_popup() + + + + # # # # # # # # # # # # # # # # # # # # # # # # # # # + # ++ GOAL CODE ++ # + # def confirm(): # + # set_frame_TIPS() # + # Runs_Test() # Might include multithread # + # Get_Results() # + # Update_Dataholder() # + # Go_To_Next_Test() # + # # # # # # # # # # # # # # # # # # # # # # # # # # # + pass + + ################################################# + + # functionality for the logout button + def btn_logout_action(self, _parent): + _parent.set_frame_login_frame() + + ################################################# + + + def remove_widgets(self, _parent): + for widget in self.winfo_children(): + widget.destroy() + + + diff --git a/PythonFiles/Scenes/ScanScene.py b/PythonFiles/Scenes/ScanScene.py index 4b836346..162d3250 100644 --- a/PythonFiles/Scenes/ScanScene.py +++ b/PythonFiles/Scenes/ScanScene.py @@ -149,6 +149,7 @@ def initialize_GUI(self, parent, master_frame): font = ('Arial', 16), textvariable= user_text, ) + self.ent_snum.insert(0,"320EL0300000032") self.ent_snum.pack(padx = 50) # Traces an input to show the submit button once text is inside the entry box diff --git a/PythonFiles/Scenes/SidebarScene.py b/PythonFiles/Scenes/SidebarScene.py index ac4aeab4..dd7daec1 100644 --- a/PythonFiles/Scenes/SidebarScene.py +++ b/PythonFiles/Scenes/SidebarScene.py @@ -138,12 +138,12 @@ def update_sidebar(self, _parent): font = btn_font, command = lambda i=i: self.btn_test_action(_parent, i) )) - self.test_btns[i+physical_offset].grid(column = 0, row = i + original_offset) + self.test_btns[i].grid(column = 0, row = i + original_offset) #print(self.data_holder.data_dict) - if self.data_holder.data_dict['physical{}_pass'.format(i+1+physical_offset)] == True: - self.test_btns[i+physical_offset].config(state = 'disabled') + if self.data_holder.data_dict['physical{}_pass'.format(i+1)] == True: + self.test_btns[i].config(state = 'disabled') physical_offset = physical_offset + 1