Advertisement
Guest User

main.py

a guest
May 30th, 2025
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 41.48 KB | Software | 0 0
  1. __version__ = '1.94'
  2.  
  3. from pythonui import Ui_MainWindow
  4. from PyQt5 import QtGui, QtWidgets
  5. import FunctionGenerator
  6. import threads_calibration
  7. import threads_sweep
  8. import threads_console
  9. import threads_ampwarmup
  10. import probe_class
  11. import os
  12. import csv #used to pull amp type from cal file
  13. import amp_class #Amp
  14. import time
  15. #import warning_sys_class
  16. from datetime import datetime
  17. import _GLOBALS
  18.  
  19. #AMP_WARMUPTIME = amp_class.AMP_WARMUPTIME #Amp
  20. #AMP_WARMUPTIME = _GLOBALS.AMP_WARMUPTIME_MINS
  21.  
  22. #DEBUG = True #True to send additional terminal outputs: Production this value is false
  23. #START_PWR = -10 #adjust start power to -10 cut down on time needed to find the right dbm from siggen to amp
  24.  
  25. '''
  26. TESTAMP = "uhf" # change to the amp that needs testing, provides default settings in the Ui option vhf, uhf, shf->AMP_DICT
  27. TESTAMPGAIN = False
  28.  
  29. AMP_DICT = {"uhf":[50, 3000, 6000,"Horn"],
  30.            "vhf":[50, 500,  1000],
  31.            "shf":[50, 7000, 8000,""]}
  32. '''
  33.  
  34. #class: UI
  35. #This class inherits the Ui_Mainwindow class from "python.ui" file to enable updating the pythonui without having to copy code.
  36. #This class also adds more functionality that is outside the scope of the Pyqt5 Designer software.
  37.  
  38. class Ui(QtWidgets.QMainWindow,Ui_MainWindow):
  39.    
  40.     def __init__(self):
  41.         super().__init__()
  42.         self.setupUi(self)
  43.         self.update_COMPorts()
  44.         self.filename = ""
  45.         self.versionsw = "SWVer: "+__version__
  46.         self.swver.setText("SWVer: "+__version__)
  47.                
  48.         sys.stdout = threads_console.Stream(newText=self.reportDebug)
  49.        
  50.         #Connecting button clicks with functions
  51.        
  52.         #Equipment Tab buttons
  53.         self.COMRefresh.clicked.connect(self.update_COMPorts)
  54.         self.OpenPorts.clicked.connect(self.equipment_open_ports)
  55.         self.Equipment_closeButton.clicked.connect(self.equipment_close_ports)
  56.         self.DebugFile_button.clicked.connect(self.logfile_location)
  57.         self.DebugLogCheck.clicked.connect(self.debugcheck)
  58.        
  59.        
  60.         #Calibration Tab buttons
  61.         self.Mod_box.currentIndexChanged.connect(self.update_modulation)
  62.         self.CalFile.clicked.connect(self.save_file_location)
  63.         self.CalButton.clicked.connect(self.start_cal)
  64.         self.CalPause.clicked.connect(self.pause_cal)
  65.         self.CalResume.clicked.connect(self.resume_cal)
  66.         self.threads_ampwarmup = threads_ampwarmup # why???? we are not doing this for any other import???????
  67.         self.amp_cdwn_timer = ""
  68.        
  69.         #Sweeper Tab buttons
  70.         self.Sweepfile_button.clicked.connect(self.sweep_file)
  71.         self.SweepButton.clicked.connect(self.start_sweep)
  72.         self.SweepResume.clicked.connect(self.resume_sweep)
  73.         self.SweepPause.clicked.connect(self.pause_sweep)
  74.         self.QuitSweep.clicked.connect(self.finished_sweep)
  75.         self.SweepLog_Button.clicked.connect(self.SweepLog_location)
  76.        
  77.         #Field Probe Tab
  78.         self.COMRefresh_2.clicked.connect(self.update_COMPorts)
  79.         self.StartFB_Button_2.clicked.connect(self.equipment_open_fp_port)
  80.         self.CloseFB_Button_2.clicked.connect(self.equipment_close_fp_port)
  81.        
  82.        
  83.         #setting defaults for boxes in the Ui
  84.         self.Mod_box.setCurrentIndex(0) #1000Hz 80% depth by default
  85.         self.Cal_FieldStrength_Box.setValue(10.5) #10.5Vm by default
  86.         self.Gentype_combo.setCurrentIndex(2)
  87.        
  88.         #C:\Users\SVC-ADCRFLAB\Documents\EMCChamberDev\Projects
  89.         #self.DebugLog_text.setText(DEBUGLOG_PATH) #"/Projects"
  90.         #self.total_seconds(int) #AttributeError: 'Ui' object has no attribute 'total_seconds' in threads warmup
  91.         #self.testbutton.clicked.connect(self.test_button)
  92.         self.DEBUG = _GLOBALS.DEBUG
  93.        
  94.         self.equipment_amp = "" #selection of amps if no amp selected then we will turn then all off or on.
  95.        
  96.         if self.DEBUG:    
  97.             if _GLOBALS.TESTAMP in _GLOBALS.AMP_DICT:
  98.                 self.Cal_step_box.setValue(_GLOBALS.AMP_DICT[_GLOBALS.TESTAMP][0])
  99.                 self.Cal_startfreq_box.setValue(_GLOBALS.AMP_DICT[_GLOBALS.TESTAMP][1])
  100.                 self.Cal_endfreq_box.setValue(_GLOBALS.AMP_DICT[_GLOBALS.TESTAMP][2])
  101.             else:
  102.                 print("Amp does not exist")
  103.                
  104.         self.TESTAMPGAIN = _GLOBALS.TESTAMPGAIN # curretnly unused but is to convert the standard gain level to 0 in amp_class
  105.         self.amp_in_use = True #Amp in use flag, once an amp is chosen in cal or sweep modes
  106.     def test_button(self):
  107.        
  108.         self.Sweep_status.setText("RF On")
  109.         self.Sweep_status.setStyleSheet("""QLineEdit { background-color: yellow; color: red }""")
  110.        
  111.     #function: start_cal
  112.     #description: This function initializes and creates a separate thread for the calibration sequence to run in.
  113.     #A seperate thread is necessary to have the User Interface continue to update and have the Pause/Resume button function
  114.    
  115.     def start_cal(self):
  116.         print("clicked start Calibration")
  117.        
  118.        
  119.         self.CalPause.setEnabled(True)
  120.         self.CalButton.setEnabled(False)
  121.  
  122.         self.Status.setText("RF On")
  123.         self.Status.setStyleSheet("""QLineEdit { background-color: yellow; color: red }""")
  124.        
  125.         self.Mod_shape_box.setEnabled(False)
  126.         self.Mod_freq_box.setEnabled(False)            
  127.         self.Mod_depth_box.setEnabled(False)
  128.        
  129.        
  130.         mod_index = self.Mod_box.currentIndex()
  131.         mod_shape = self.Mod_shape_box.currentIndex()
  132.         mod_freq = self.Mod_freq_box.value()
  133.         mod_depth = self.Mod_depth_box.value()
  134.        
  135.         start_freq = self.Cal_startfreq_box.value()
  136.         end_freq = self.Cal_endfreq_box.value()
  137.  
  138.         #kill amps not in use
  139.         if start_freq > 79 and end_freq < 1001: #Amp
  140.             print("===kill uhf===")
  141.             self.amp_in_use = False #we don't need the use data for the amps we are turning off amp class
  142.             self.equipment_uhf_amp.off(self.amp_in_use)
  143.             print("===kill shf===")
  144.             self.equipment_shf_amp.off(self.amp_in_use)
  145.             print("===RFon vhf===")
  146.             self.amp_in_use = True #we do want the use data for the amps we using amp class
  147.             self.equipment_vhf_amp.on() #RFon
  148.             self.equipment_amp = "vhf" #4 cal file
  149.         elif start_freq > 999 and end_freq < 6001: #Amp
  150.             print("===kill vhf===")
  151.             self.amp_in_use = False #we don't need the use data for the amps we are turning off amp class
  152.             self.equipment_vhf_amp.off(self.amp_in_use)
  153.             print("===kill shf===")
  154.             self.equipment_shf_amp.off(self.amp_in_use)
  155.             print("===RFon uhf===")
  156.             self.amp_in_use = True #we do want the use data for the amps we using amp class
  157.             self.equipment_uhf_amp.on() #RFon
  158.             self.equipment_amp = "uhf" #4 cal file
  159.         elif start_freq > 5999 and end_freq < 18000: #Amp
  160.             print("===kill vhf===")
  161.             self.amp_in_use = False #we don't need the use data for the amps we are turning off amp class
  162.             self.equipment_vhf_amp.off(self.amp_in_use)
  163.             print("===kill uhf===")
  164.             self.equipment_uhf_amp.off(self.amp_in_use)
  165.             print("===RFon shf===")
  166.             self.amp_in_use = True #we do want the use data for the amps we using amp class
  167.             self.equipment_shf_amp.on() #RFon
  168.             self.equipment_amp = "shf" #4 cal file
  169.        
  170.  
  171.            
  172.         if self.amp_warmup_calc(): #Amp
  173.             #print("AmpWarmUpCalc 101 = ", self.amp_warmup_calc())
  174.             self.Status.setStyleSheet("""QLineEdit { background-color: yellow; color: red }""")
  175.             self.Status.setText("WARM UP")
  176.          
  177.             if self.DEBUG:
  178.                 print("Starting AmpWarming in cal")
  179.            
  180.             #self.jnk = threads_ampwarmup.cntdwn_amp_warmuptime
  181.                
  182.             if self.threads_ampwarmup.cntdwn_amp_warmuptime.start(self, _GLOBALS.AMP_WARMUPTIME_MINS, 00):
  183.                 #emit example:
  184.                 #self.get_thread.amp_cdwn_timer.connect(self.reportAmpTimer) #Added to connect the timer to calibration tab
  185.                 print("warm up completed")
  186.         #else:    
  187.             #Done with Warmup
  188.                 self.Status.setText("RF On")
  189.                 self.Status.setStyleSheet("""QLineEdit { background-color: red; color: yellow }""")    
  190.                 self.equipment_siggen.rf_on()
  191.                
  192.         start_power = _GLOBALS.SIGGEN_START_PWR
  193.         targetfield = self.Cal_FieldStrength_Box.value() #moved below We need away to emit this value from threads calibration for the proximity fields
  194.         step_size = self.Cal_step_box.value()
  195.         self.create_filename()
  196.         file_name = self.Savelocation_box.text() + "/" +self.filename
  197.         tolerance =self.Tolerance_box.value()
  198.  
  199.         #def __init__(self,step,endfreq,startfreq,siggen,rfpower,fieldprobe,targetfield,tolerance,file_name,mod_box,mod_shape,mod_freq,mod_depth,prox_flag):
  200.         #initializing the variables needed for the calibration thread
  201.         self.get_thread = threads_calibration.calibration_thread(step_size,end_freq,start_freq,self.equipment_siggen,start_power,self.equipment_probe,targetfield,tolerance,file_name,mod_index,mod_shape,mod_freq,mod_depth,self.Prox_fields_box.currentIndex())
  202.        
  203.         #connecting the signals to front UI elements or functions to update
  204.         self.get_thread.finished_signal.connect(self.finished_cal)
  205.         self.get_thread.progress_signal.connect(self.reportProgress)
  206.         self.get_thread.estimated_time_signal.connect(self.reportTime)
  207.         self.get_thread.current_freq_signal.connect(self.reportFreq)
  208.         self.get_thread.measuredfield_signal.connect(self.reportField)
  209.         self.get_thread.rfpower_signal.connect(self.reportPower)
  210.         self.get_thread.batvolt_signal.connect(self.reportBat)
  211.  
  212.         #emit example:
  213.         self.get_thread.amp_cdwn_timer_signal.connect(self.reportAmpTimer_Cal) #Added to connect the timer to calibration tab
  214.            
  215.         self.get_thread.start()
  216.          
  217.        
  218.     #Function: create_filename
  219.     #this function creates a filename based on the inputs from the user on the UI and the current date/time
  220.     #added field_probe_sn & amp_type to the output files    
  221.     def create_filename(self):
  222.         orientation = self.Orientation.currentText()  
  223.         start_freq = str(self.Cal_startfreq_box.value())
  224.         end_freq = str(self.Cal_endfreq_box.value())
  225.         step_size = str(self.Cal_step_box.value())
  226.         target_field = str(self.Cal_FieldStrength_Box.value())
  227.        
  228.         field_probe_sn = "fpsn#" #place holder for field probe serial number
  229.         amp_type = self.equipment_amp
  230.         # datetime object containing current date and time
  231.         now = datetime.now()
  232.         # dd/mm/YY H:M:S
  233.         dt_string = now.strftime("%d-%b-%Y_%H%M")
  234.        
  235.         filename = "_" + orientation[0] + start_freq + "-" + end_freq + "MHz-" + step_size +"s-" + target_field + "Vm_" + dt_string +".csv"
  236.         self.filename = filename
  237.        
  238.         file_name = self.Savelocation_box.text() + "/" +self.filename
  239.         print(file_name)
  240.        
  241.         cal_pos = self.Cal_Position_Box.currentText()
  242.         comments = self.Comments_box.text()
  243.        
  244.         if os.path.isfile(file_name) == False:
  245.             file1 = open(file_name,'a+')
  246.             file1.write('Frequency(MHz),Sig.Gen.Power(dBm),Field Probe Measurement(V/m),Target FIeld (V/m),Mod_shape,Mod_freq(Hz),Mod_depth(%),Cal Pos:'+ cal_pos + ',' + field_probe_sn +',' + amp_type +','+comments)
  247.             file1.write("\n")
  248.             print("created file"+file_name)
  249.             file1.close()
  250.      
  251.        
  252.     def pause_cal(self):
  253.         self.get_thread.stop_signal = True
  254.         print("paused")
  255.         self.Status.setText("Paused")
  256.         self.Status.setStyleSheet("""QLineEdit { background-color: green; color: white }""")
  257.        
  258.         self.CalPause.setEnabled(False)
  259.         self.CalResume.setEnabled(True)
  260.        
  261.        
  262.     def resume_cal(self):
  263.         self.get_thread.stop_signal = False
  264.         self.equipment_siggen.rf_on()
  265.         print("resumed")
  266.         self.Status.setText("RF On")
  267.         self.Status.setStyleSheet("""QLineEdit { background-color: yellow; color: red }""")
  268.        
  269.         self.CalPause.setEnabled(True)
  270.         self.CalResume.setEnabled(False)
  271.        
  272.        
  273.     def finished_cal(self):
  274.         self.equipment_siggen.rf_off()
  275.         self.get_thread.quit()
  276.        
  277.         self.Status.setText("Completed")
  278.         self.Status.setStyleSheet("""QLineEdit { background-color: green; color: white }""")
  279.         self.CalPause.setEnabled(False)
  280.         self.CalButton.setEnabled(True)
  281.        
  282.        
  283.     def quit_cal(self):
  284.         self.pause_cal(self)
  285.  
  286. #############################################
  287.     #Sweep thread functions
  288.    
  289.     def start_sweep(self):
  290.         print("clicked start Sweep button")
  291.        
  292.         self.SweepButton.setEnabled(False)
  293.         self.SweepPause.setEnabled(True)
  294.         self.Dwell_box.setEnabled(False)
  295.         self.QuitSweep.setEnabled(True)
  296.        
  297.        
  298.         self.sweepfile = self.Sweepfile_box.text()
  299.         #sweepfile = self.sweepfile
  300.         #find the amp list in header
  301.         #sweepfile_header_lst = file_get_headers_lst(sweepfile)
  302.         #created a function for this but can't use it???????????????????
  303.         file_path =  self.sweepfile
  304.         print("opening file:", file_path)
  305.         try:
  306.             with open(file_path, 'r') as file:
  307.                 csv_reader = csv.reader(file)
  308.                 header_list = next(csv_reader)
  309.                
  310.         except FileNotFoundError:
  311.             print(f"Error: File not found at '{file_path}'")
  312.                
  313.         except Exception as e:
  314.             print(f"An error occurred: {e}")
  315.                
  316.         finally:
  317.             print("done")
  318.         #can't figure out why this doesn't work!!!!!!!!!!!!!!!!!!!!!!!        
  319.         #header_list = file_get_headers_lst(self.sweepfile)
  320.                
  321.        
  322. #---------------
  323.         self.equipment_amp = header_list[9] #assign the amp for both debug and playback logs
  324.        
  325.         if self.equipment_amp:
  326.  
  327.             #kill amps not in use
  328.             if self.equipment_amp == "vhf": #Amp
  329.                 print("===kill uhf===")
  330.                 self.equipment_uhf_amp.off(self.amp_in_use)
  331.                 print("===kill shf===")
  332.                 self.equipment_shf_amp.off(self.amp_in_use)
  333.                 print("===RFon vhf===")
  334.                 self.equipment_vhf_amp.on() #RFon
  335.                 self.equipment_amp = "vhf" #4 cal file
  336.            
  337.             elif self.equipment_amp == "uhf": #Amp
  338.                 print("===kill vhf===")
  339.                 self.equipment_vhf_amp.off(self.amp_in_use)
  340.                 print("===kill shf===")
  341.                 self.equipment_shf_amp.off(self.amp_in_use)
  342.                 print("===RFon uhf===")
  343.                 self.equipment_uhf_amp.on() #RFon
  344.                 self.equipment_amp = "uhf" #4 cal file
  345.            
  346.             elif self.equipment_amp == "shf": #Amp
  347.                 print("===kill vhf===")
  348.                 self.equipment_vhf_amp.off(self.amp_in_use)
  349.                 print("===kill uhf===")
  350.                 self.equipment_uhf_amp.off(self.amp_in_use)
  351.                 print("===RFon shf===")
  352.                 self.equipment_shf_amp.on() #RFon
  353.                 self.equipment_amp = "shf" #4 cal file
  354.         else:
  355.             print("amp selection error in cal file:", self.equipment_amp)
  356.            
  357.        
  358.         #depreciated - threads_ampwarmup.py
  359.         if self.amp_warmup_calc(): #Amp not(self.amp_warmup) inverted logic with threads warmup
  360.            
  361.             print("Starting warmup in sweeper")
  362.             self.Sweep_status.setText("WARMUP: ")
  363.             self.Sweep_status.setStyleSheet("""QLineEdit { background-color: red; color: white }""")
  364.             threads_ampwarmup.cntdwn_amp_warmuptime.start(self, _GLOBALS.AMP_WARMUPTIME_MINS, 00)
  365.         else:
  366.             self.Sweep_status.setText("RF On")
  367.             self.Sweep_status.setStyleSheet("""QLineEdit { background-color: red; color: white }""")
  368.            
  369.         #print("skipped over amp warmup() sweeper", self.sweepfile)
  370.         self.sweeplog =self.SweepLog_Box.text()
  371.         dwell = self.Dwell_box.value()
  372.        
  373.         #def __init__(self,dwell,inputfile,siggen,fieldprobe,modenable,outputfile,swver):
  374.         self.get_sweep = threads_sweep.sweep_thread(dwell, self.sweepfile, self.equipment_siggen,self.equipment_probe,self.Modenable_box.isChecked(),self.sweeplog,self.versionsw)
  375.        
  376.         self.get_sweep.finished_signal.connect(self.finished_sweep)
  377.         self.get_sweep.progress_signal.connect(self.reportProgress_Sweep)
  378.         self.get_sweep.estimated_time_signal.connect(self.reportTime_Sweep)
  379.         self.get_sweep.current_freq_signal.connect(self.reportFreq_Sweep)
  380.         self.get_sweep.rfpower_signal.connect(self.reportPower_Sweep)
  381.         self.get_sweep.modshape_signal.connect(self.reportModshape_Sweep)
  382.         self.get_sweep.modfreq_signal.connect(self.reportModfreq_Sweep)
  383.         self.get_sweep.moddepth_signal.connect(self.reportModdepth_Sweep)
  384.         self.get_sweep.measuredfield_signal.connect(self.reportProbe_Sweep)
  385.        
  386.        
  387.        
  388.         self.get_sweep.start()
  389.          
  390.        
  391.     def pause_sweep(self):
  392.         print("paused")
  393.         self.Sweep_status.setText("Paused")
  394.         self.Sweep_status.setStyleSheet("""QLineEdit { background-color: red; color: white }""")
  395.         self.equipment_siggen.rf_off()
  396.        
  397.         self.get_sweep.pause_signal = True
  398.         self.SweepPause.setEnabled(False)
  399.         self.SweepResume.setEnabled(True)
  400.  
  401.    
  402.     def resume_sweep(self):
  403.         print("resumed sweep")
  404.         self.equipment_siggen.rf_on()
  405.         self.Sweep_status.setText("RF On")
  406.         self.Sweep_status.setStyleSheet("""QLineEdit { background-color: red; color: yellow }""") #R2 mod changed coler to red/yellow
  407.        
  408.         self.get_sweep.pause_signal= False
  409.         self.SweepPause.setEnabled(True)
  410.         self.SweepResume.setEnabled(False)
  411.  
  412.     def finished_sweep(self):
  413.         self.equipment_siggen.rf_off()
  414.         self.get_sweep.stop_signal = False
  415.         self.get_sweep.quit()
  416.              
  417.         self.Sweep_status.setText("Completed")
  418.         self.Sweep_status.setStyleSheet("""QLineEdit { background-color: green; color: black }""")
  419.         self.SweepPause.setEnabled(False)
  420.         self.SweepButton.setEnabled(True)
  421.         self.SweepResume.setEnabled(False)
  422.         self.QuitSweep.setEnabled(False)
  423.         self.Dwell_box.setEnabled(True)
  424.  
  425.     def start_fp(self):
  426.         #print("clicked start Field Probe") We have no need to log anything in Field Probe Tab, Ref Only
  427.        
  428.         '''
  429.        self.CalPause.setEnabled(True)
  430.        self.CalButton.setEnabled(False)
  431.  
  432.        self.Status.setText("RF On")
  433.        self.Status.setStyleSheet("""QLineEdit { background-color: yellow; color: red }""")
  434.        
  435.        self.Mod_shape_box.setEnabled(False)
  436.        self.Mod_freq_box.setEnabled(False)            
  437.        self.Mod_depth_box.setEnabled(False)
  438.      
  439.        
  440.        mod_index = self.Mod_box.currentIndex()
  441.        mod_shape = self.Mod_shape_box.currentIndex()
  442.        mod_freq = self.Mod_freq_box.value()
  443.        mod_depth = self.Mod_depth_box.value()
  444.        
  445.        start_freq = self.Cal_startfreq_box.value()
  446.        end_freq = self.Cal_endfreq_box.value()
  447.  
  448.        #kill amps not in use
  449.        if start_freq > 79 and end_freq < 1001: #Amp
  450.            print("===kill uhf===")
  451.            self.amp_in_use = False #we don't need the use data for the amps we are turning off amp class
  452.            self.equipment_uhf_amp.off(self.amp_in_use)
  453.            print("===kill shf===")
  454.            self.equipment_shf_amp.off(self.amp_in_use)
  455.            print("===RFon vhf===")
  456.            self.amp_in_use = True #we do want the use data for the amps we using amp class
  457.            self.equipment_vhf_amp.on() #RFon
  458.            self.equipment_amp = "vhf" #4 cal file
  459.        elif start_freq > 999 and end_freq < 6001: #Amp
  460.            print("===kill vhf===")
  461.            self.amp_in_use = False #we don't need the use data for the amps we are turning off amp class
  462.            self.equipment_vhf_amp.off(self.amp_in_use)
  463.            print("===kill shf===")
  464.            self.equipment_shf_amp.off(self.amp_in_use)
  465.            print("===RFon uhf===")
  466.            self.amp_in_use = True #we do want the use data for the amps we using amp class
  467.            self.equipment_uhf_amp.on() #RFon
  468.            self.equipment_amp = "uhf" #4 cal file
  469.        elif start_freq > 5999 and end_freq < 18000: #Amp
  470.            print("===kill vhf===")
  471.            self.amp_in_use = False #we don't need the use data for the amps we are turning off amp class
  472.            self.equipment_vhf_amp.off(self.amp_in_use)
  473.            print("===kill uhf===")
  474.            self.equipment_uhf_amp.off(self.amp_in_use)
  475.            print("===RFon shf===")
  476.            self.amp_in_use = True #we do want the use data for the amps we using amp class
  477.            self.equipment_shf_amp.on() #RFon
  478.            self.equipment_amp = "shf" #4 cal file
  479.        
  480.  
  481.            
  482.        if self.amp_warmup_calc(): #Amp
  483.            #print("AmpWarmUpCalc 101 = ", self.amp_warmup_calc())
  484.            self.Status.setStyleSheet("""QLineEdit { background-color: yellow; color: red }""")
  485.            self.Status.setText("WARM UP")
  486.          
  487.            if self.DEBUG:
  488.                print("Starting AmpWarming in cal")
  489.            
  490.            #self.jnk = threads_ampwarmup.cntdwn_amp_warmuptime
  491.                
  492.            if self.threads_ampwarmup.cntdwn_amp_warmuptime.start(self, _GLOBALS.AMP_WARMUPTIME_MINS, 00):
  493.                #emit example:
  494.                #self.get_thread.amp_cdwn_timer.connect(self.reportAmpTimer) #Added to connect the timer to calibration tab
  495.                print("warm up completed")
  496.        #else:    
  497.            #Done with Warmup
  498.                self.Status.setText("RF On")
  499.                self.Status.setStyleSheet("""QLineEdit { background-color: red; color: yellow }""")    
  500.                self.equipment_siggen.rf_on()
  501.                
  502.        start_power = _GLOBALS.SIGGEN_START_PWR
  503.        '''
  504.         targetfield = self.Cal_FieldStrength_Box.value() #moved below We need away to emit this value from threads calibration for the proximity fields
  505.         '''
  506.        step_size = self.Cal_step_box.value()
  507.        self.create_filename()
  508.        file_name = self.Savelocation_box.text() + "/" +self.filename
  509.        tolerance =self.Tolerance_box.value()
  510.  
  511.        #def __init__(self,step,endfreq,startfreq,siggen,rfpower,fieldprobe,targetfield,tolerance,file_name,mod_box,mod_shape,mod_freq,mod_depth,prox_flag):
  512.        #initializing the variables needed for the calibration thread
  513.        self.get_thread = threads_calibration.calibration_thread(step_size,end_freq,start_freq,self.equipment_siggen,start_power,self.equipment_probe,targetfield,tolerance,file_name,mod_index,mod_shape,mod_freq,mod_depth,self.Prox_fields_box.currentIndex())
  514.        
  515.        #connecting the signals to front UI elements or functions to update
  516.        self.get_thread.finished_signal.connect(self.finished_cal)
  517.        self.get_thread.progress_signal.connect(self.reportProgress)
  518.        self.get_thread.estimated_time_signal.connect(self.reportTime)
  519.        self.get_thread.current_freq_signal.connect(self.reportFreq)
  520.        '''
  521.         self.get_thread.measuredfield_signal.connect(self.reportField)
  522.        
  523.         '''
  524.        self.get_thread.rfpower_signal.connect(self.reportPower)
  525.        '''
  526.        
  527.         self.get_thread.batvolt_signal.connect(self.reportBat)
  528.  
  529.         '''
  530.        #emit example:
  531.        self.get_thread.amp_cdwn_timer_signal.connect(self.reportAmpTimer_Cal) #Added to connect the timer to calibration tab
  532.        '''
  533.        
  534.         self.get_thread.start()
  535.  
  536.        
  537.     ###############################################################################################        
  538.     #The following "report" functions update the User interface with information as the program is running.
  539.     #The functions take the signal emitted by a thread and gives the User Interface information.
  540.    
  541.     #------ I think this first group of reports for emits is for the Cal Tab
  542.     #------ future: maybe rename each report for it's tab so it's clearer
  543.    
  544.     """
  545.    Â Â Â The following group of functions are for updating
  546.       the Ui Calibration Tab
  547.    """
  548.  
  549.     def reportFinished(self,finished):
  550.         self.Status.setText("Complete")
  551.         self.Status.setStyleSheet("""QLineEdit { background-color: green; color: white }""")
  552.    
  553.     def reportProgress(self,progress):
  554.         print("Progress is " + str(progress))
  555.         self.progressBar.setProperty("value", int(progress))
  556.          
  557.     def reportTime(self,time):
  558.         timestring = str(time) +"mins"
  559.         self.TextEstimatedTime.setText(timestring)
  560.      
  561.     def reportFreq(self,freq):
  562.         self.Cal_Freq_Box.setText(str(freq))
  563.          
  564.     def reportField(self,field):
  565.         self.Cal_Probe_strength_box.setText(str(field))
  566.          
  567.     def reportPower(self,power):
  568.         self.Cal_siggen_box.setText(str(power))
  569.    
  570.     #Narda or ETS Probe Bat Low
  571.     def reportBat(self,bat):
  572.         self.Text_BatV.setText(str(bat)+" V")
  573.         if self.Probetype_combo.currentText() == "Narda":
  574.             if bat < 2.05:
  575.                 self.Status.setText("BAT LOW")
  576.                 self.Status.setStyleSheet("""QLineEdit { background-color: yellow; color: red }""") #when bat low
  577.        
  578.         elif self.Probetype_combo.currentText() == "ETS":
  579.             if bat < 4.0:
  580.                 self.Status.setText("BAT LOW")
  581.                 self.Status.setStyleSheet("""QLineEdit { background-color: yellow; color: red }""") #when bat low
  582.                
  583.        
  584.     def reportDebug(self, text):
  585.         cursor = self.DebugOutput.textCursor()
  586.         cursor.movePosition(QtGui.QTextCursor.End)
  587.         cursor.insertText(text)
  588.         self.DebugOutput.setTextCursor(cursor)
  589.         self.DebugOutput.ensureCursorVisible()
  590.        
  591.         if self.DebugLogCheck.isChecked():
  592.             filestring = self.DebugLog_text.text() + '/'+'debug.txt'
  593.             sys.stdout.logenable = True
  594.             sys.stdout.logfile= filestring
  595.            
  596.             file1 = open(filestring,'a+')
  597.             file1.write(str(text))
  598.             file1.close()
  599.    
  600.     #emit example:    
  601.     def reportAmpTimer_Cal(self,amp_cdwn_timer): #added to send cnt down to Ui
  602.         self.a_cdwn_t = "Start In:",str(amp_cdwn_timer) # need to adjust the font size
  603.         self.Status.setStyleSheet("""QLineEdit { background-color: yellow; color: red }""")
  604.         self.Status.setText(str(amp_cdwn_timer))        
  605.        
  606.     #------ this sencond group of reports for emits is for the Sweep Tab
  607.     """
  608.    Â Â Â The following group of functions are for updating
  609.       the Ui Sweep Tab
  610.    """    
  611.     def reportProgress_Sweep(self,progress):
  612.         print("Progress is " + str(progress))
  613.         self.Sweep_progressbar.setProperty("value", int(progress))
  614.        
  615.     def reportTime_Sweep(self,time):
  616.         timestring = str(time) +"mins"
  617.         self.SweepEstimatedTime_text.setText(timestring)
  618.        
  619.     def reportFreq_Sweep(self,freq):
  620.         self.Sweep_freq_box.setText(str(freq))
  621.        
  622.     def reportPower_Sweep(self,power):
  623.         self.Sweep_siggen_box.setText(str(power))
  624.        
  625.     def reportModshape_Sweep(self,shape):
  626.         self.Sweep_modshape_box.setText(shape)
  627.        
  628.     def reportModfreq_Sweep(self,freq):
  629.         self.Sweep_modfreq_box.setText(str(freq))
  630.    
  631.     def reportModdepth_Sweep(self,depth):
  632.         self.Sweep_moddepth_box.setText(str(depth))
  633.        
  634.     def reportProbe_Sweep(self,field):
  635.         self.Sweep_FieldProbe_box.setText(str(field))
  636.  
  637.      
  638.     #############################################################################################
  639.    
  640.    
  641.     #*******************************************************************************************
  642.     #The following functions update the front user interface
  643.    
  644.     #Function: save_file_location
  645.     #this function creates a popup directory search to get a save directory
  646.     def save_file_location (self):
  647.         fname = QtWidgets.QFileDialog.getExistingDirectory()
  648.         print ("save file location updated to "+fname)
  649.         self.Savelocation_box.setText(fname)
  650.        
  651.     #Function: sweep_file
  652.     #This funcion creates a pop file search to get a file for sweep parameters
  653.     def sweep_file(self):
  654.         fname = QtWidgets.QFileDialog.getOpenFileName()[0] #Sweep files will be kept in C:\Users\SVC-ADCRFLAB\Documents\EMC Chamber Software\Cal
  655.         print ("sweep file updated to " + fname)
  656.         self.Sweepfile_box.setText(fname)
  657.    
  658.     def SweepLog_location(self):
  659.         fname = QtWidgets.QFileDialog.getExistingDirectory() #sweep logs base directory to open up in C:\Users\SVC-ADCRFLAB\Documents\EMC Chamber Software\Projects\ by user/project name
  660.         print ("log file location updated to "+fname)
  661.         self.SweepLog_Box.setText(fname)    
  662.        
  663.     def logfile_location(self):
  664.         fname = QtWidgets.QFileDialog.getExistingDirectory() #debug log will be kept automatically the same dir as sweeplog
  665.         print ("log file location updated to "+fname)
  666.         self.DebugLog_text.setText(fname)
  667.    
  668.     def debugcheck(self):
  669.         if self.DebugLogCheck.isChecked():
  670.             self.DebugLog_text.setEnabled(False)
  671.             self.DebugFile_button.setEnabled(False)
  672.         else:
  673.             self.DebugLog_text.setEnabled(True)
  674.             self.DebugFile_button.setEnabled(True)
  675.    
  676.    
  677.     #Function: update_COMPorts
  678.     #This function clears the COM Ports for the siggen and probe.
  679.     #Then it gets an updated list of the connected COM items and adds them to the list.
  680.     def update_COMPorts(self):
  681.          self.FieldProbe_combo.clear()
  682.          #self.FieldProbe_combo_2.clear() #wtf
  683.          p = probe_class.COM_list()
  684.                  
  685.          for COM in p:
  686.              self.FieldProbe_combo.addItem(str(COM))
  687.              #self.FieldProbe_combo_2.addItem(str(COM)) #wtf
  688.              
  689.          self.Siggen_combo.clear()
  690.          visa_devices = FunctionGenerator.visa_devices()
  691.          print(visa_devices)
  692.          
  693.          if visa_devices:
  694.              for visas in visa_devices:
  695.                  self.Siggen_combo.addItem(visas)
  696.    
  697.     def update_fp_COMPorts(self):
  698.          self.FieldProbe_combo_2.clear()
  699.          p = probe_class.COM_list()
  700.                  
  701.          for COM in p:
  702.              self.FieldProbe_combo_2.addItem(str(COM))
  703.          '''    
  704.         self.Siggen_combo.clear()
  705.         visa_devices = FunctionGenerator.visa_devices()
  706.        
  707.         if visa_devices:
  708.             for visas in visa_devices:
  709.                 self.Siggen_combo.addItem(visas)
  710.        '''
  711.     #Function: update_modulation
  712.     #This function enables/disables the modulation selection boxes based on the index
  713.     def update_modulation(self):
  714.         print ("modulation box changed to "+self.Mod_box.currentText())
  715.         if ( self.Mod_box.currentIndex() >= 1):
  716.             self.Mod_shape_box.setEnabled(True)
  717.             self.Mod_freq_box.setEnabled(True)            
  718.             self.Mod_depth_box.setEnabled(True)
  719.            
  720.         elif (self.Mod_box.currentIndex() == 0):
  721.             self.Mod_shape_box.setEnabled(False)
  722.             self.Mod_freq_box.setEnabled(False)            
  723.             self.Mod_depth_box.setEnabled(False)
  724.  
  725.    
  726.  
  727.     #open ports button on Equipment Tab
  728.     def equipment_open_ports(self):
  729.         x = str(self.FieldProbe_combo.currentText())
  730.         y = x.split(":")
  731.        
  732.         #Amp
  733.         #we probably should check to make sure each amp is connected or toss an error and or notify operator
  734.         #Open all three Amps & use the warmup gain constant which shold = 20 min. The intent is to start them all automatically,
  735.         #because we want to minimize the wait time to RF On, either sweep or calibration
  736.         self.equipment_vhf_amp = amp_class.pwramps("search", "vhf", _GLOBALS.AMP_GAIN) #Amp
  737.         self.equipment_uhf_amp = amp_class.pwramps("search", "uhf", _GLOBALS.AMP_GAIN) #Amp
  738.         self.equipment_shf_amp = amp_class.pwramps("search", "shf", _GLOBALS.AMP_GAIN) #Amp
  739.  
  740.         self.dtAmpLog = datetime.now() #Amp
  741.        
  742.        
  743.        
  744.         print("Amp DT Sartup at : "+ str(self.dtAmpLog)) #Amp log the time for start up
  745.         #Field Probe Selection
  746.         if self.Probetype_combo.currentIndex() != 0 and self.FieldProbeActive.isChecked() == False:
  747.             self.equipment_probe = probe_class.fieldprobe(y[0],self.Probetype_combo.currentText())
  748.            
  749.             if self.equipment_probe.probe:
  750.                 self.FieldProbe_status.setText("Opened " + y[0])
  751.                 print(self.equipment_probe.probe.isOpen())
  752.                
  753.                 probe_info = self.equipment_probe.Probe_info()
  754.                 #[probe_model,sw_rev,probe_sn,cal_date]
  755.                 self.Text_Model.setText(probe_info[0])
  756.                 self.Text_SN.setText(probe_info[1])
  757.                 self.Text_CalDate.setText(probe_info[2])
  758.                
  759.                 self.FieldProbe_combo.setEnabled(False)
  760.                 self.FieldProbeActive.setChecked(True)
  761.                 self.FieldProbeActive_2.setChecked(True)
  762.                 self.FieldProbe_status.setStyleSheet("""QLineEdit { background-color: green; color: white }""")
  763.                                
  764.             else:
  765.                 self.FieldProbe_status.setText("unable to open COM Port")
  766.                 self.FieldProbe_status.setStyleSheet("""QLineEdit { background-color: red; color: white }""")
  767.                 self.FieldProbeActive.setChecked(False)
  768.            
  769.            
  770.            
  771.         #Generator Selection        
  772.         if self.Gentype_combo.currentIndex() != 0 and self.SigGenActive.isChecked() == False:
  773.             self.equipment_siggen = FunctionGenerator.Func_gen(self.Siggen_combo.currentText(),self.Gentype_combo.currentText())
  774.             if self.equipment_siggen.Siggen:
  775.                 self.Siggen_status.setText("opened " + self.Siggen_combo.currentText())
  776.                
  777.                 self.Siggen_combo.setEnabled(False)
  778.                 self.SigGenActive.setChecked(True)
  779.                 self.SigGenActive_2.setChecked(True)
  780.                 self.Siggen_status.setStyleSheet("""QLineEdit { background-color: green; color: white }""")
  781.                          
  782.             else:
  783.                 self.SigGenActive.setChecked(False)
  784.                 self.SigGenActive_2.setChecked(False)
  785.                 self.Siggen_status.setStyleSheet("""QLineEdit { background-color: red; color: white }""")
  786.                
  787.         if self.SigGenActive.isChecked():
  788.             if self.FieldProbeActive.isChecked():
  789.                 self.CalButton.setEnabled(True)
  790.                 self.OpenPorts.setEnabled(False)
  791.                 self.SweepButton.setEnabled(True)
  792.         z = str(self.FieldProbe_c)
  793.  
  794.     #Start Fp button on field prbee Tab
  795.     def equipment_open_fp_port(self):
  796.         x = str(self.FieldProbe_combo_2.currentIndex())   #.currentText())
  797.         z = str(self.FieldProbe_)
  798.         y = x.split(":")
  799.        
  800.         #Field Probe Selection
  801.         if self.Probetype_combo_2.currentIndex() != 0 and self.FieldProbeActive.isChecked() == False:
  802.             self.equipment_probe_2 = probe_class.fieldprobe(y[0],self.Probetype_combo_2.currentText())
  803.            
  804.             if self.equipment_probe_2.probe:
  805.                 self.FieldProbe_status_2.setText("Opened " + y[0])
  806.                 #print(self.equipment_probe_2.probe.isOpen())
  807.                
  808.                 probe_info = self.equipment_probe_2.Probe_info()
  809.                 #[probe_model,sw_rev,probe_sn,cal_date]
  810.                 self.Text_Model_2.setText(probe_info[0])
  811.                 self.Text_SN_2.setText(probe_info[1])
  812.                 self.Text_CalDate_2.setText(probe_info[2])
  813.                
  814.                 self.FieldProbe_combo_2.setEnabled(False)
  815.                 self.FieldProbeActive_2.setChecked(True)
  816.             '''                  
  817.            else:
  818.                self.FieldProbe_status_2.setText("unable to open COM Port")
  819.                self.FieldProbe_status_2.setStyleSheet("""QLineEdit { background-color: red; color: white }""")
  820.                self.FieldProbeActive_2.setChecked(False)
  821.            '''    
  822.     #This is the warmup time for the amps based on the time logged for power on  i.e dtAmpLog
  823.     #We are creating a class thread to feed back the count down to the UI
  824.     #depreciated for threads ampwarmup
  825.     def amp_warmup_calc(self): #Amp
  826.         if self.DEBUG:    
  827.             print("In amp_warmup_calc() dtlog = ", self.dtAmpLog)
  828.         time.sleep(1)
  829.         temp = datetime.now()
  830.  
  831.         diff = temp - self.dtAmpLog
  832.         diff = diff.total_seconds()/60
  833.        
  834.         if self.DEBUG:
  835.             print("In amp_warmup_calc() dtlog diff =", diff)
  836.         #timer_format = '{:02d}:{:02d}'.format(mins, secs)
  837.         #print(diff)
  838.        
  839.         if diff < _GLOBALS.AMP_WARMUPTIME_MINS:
  840.             #print("amp_warmup_calc() true")
  841.             self.Status.setText("WARM UP")
  842.             self.Status.setStyleSheet("""QLineEdit { background-color: yellow; color: red }""")
  843.             return True
  844.         else: #This does not seem to be needed
  845.             #print("amp_warmup_calc() false")
  846.             return False
  847.        
  848.     def equipment_close_ports(self):
  849.         if self.FieldProbeActive.isChecked():
  850.             self.equipment_probe.Close_probe()
  851.             self.FieldProbe_combo.setEnabled(True)
  852.             self.OpenPorts.setEnabled(True)
  853.             self.FieldProbeActive.setChecked(False)
  854.             self.FieldProbeActive_2.setChecked(False)
  855.             self.FieldProbe_status.setText("Closed Port")
  856.             self.FieldProbe_status.setStyleSheet("""QLineEdit { background-color: red; color: white }""")
  857.        
  858.         if self.SigGenActive.isChecked():
  859.             self.Siggen_status.setText("Closed Port")
  860.             self.Siggen_status.setStyleSheet("""QLineEdit { background-color: red; color: white }""")
  861.             self.Siggen_combo.setEnabled(True)
  862.             self.SigGenActive.setChecked(False)
  863.             self.SigGenActive_2.setChecked(False)
  864.             self.SweepButton.setEnabled(False)
  865.        
  866.  
  867.        
  868.         #kill all amps
  869.         if self.equipment_amp == "vhf":
  870.             self.equipment_vhf_amp.off(self.amp_in_use) #Amp
  871.         elif self.equipment_amp == "uhf":
  872.             self.equipment_uhf_amp.off(self.amp_in_use) #Amp
  873.         elif self.equipment_amp =="shf":
  874.             self.equipment_shf_amp.off(self.amp_in_use) #Amp
  875.         else:
  876.             self.amp_in_use = False
  877.             self.equipment_vhf_amp.off(self.amp_in_use) #Amp
  878.             self.equipment_uhf_amp.off(self.amp_in_use) #Amp
  879.             self.equipment_shf_amp.off(self.amp_in_use) #Amp
  880.  
  881.     def equipment_close_fp_port(self):
  882.         if self.FieldProbeActive_2.isChecked():
  883.             self.equipment_probe_2.Close_probe()
  884.             self.FieldProbe_combo_2.setEnabled(True)
  885.             self.StartFB_Button_2.setEnabled(True)
  886.             #self.FieldProbeActive_2.setChecked(False)
  887.             #self.FieldProbeActive_2_2.setChecked(False)
  888.  
  889.        
  890.  
  891. #-------Opens a CSV file and returns the first line as a list.
  892. # used to fetch the header of the cal file but not used because it seems to be out of scope??
  893.     def file_get_headers_lst(file_path):
  894.        
  895.         print("opening file:", file_path)
  896.         try:
  897.             with open(file_path, 'r') as file:
  898.                 csv_reader = csv.reader(file)
  899.                 header_list = next(csv_reader)
  900.                 return header_list
  901.         except FileNotFoundError:
  902.             print(f"Error: File not found at '{file_path}'")
  903.             return None    
  904.         except Exception as e:
  905.             print(f"An error occurred: {e}")
  906.             return None    
  907.         finally:
  908.             print("done---------------------------------------------------")
  909.  
  910.  
  911.     #**********************************************************************************************
  912.     #kill equipment and update the UI
  913.     def closeEvent(self, event):
  914.         """Shuts down application on close."""
  915.         # Return standard output to defaults.
  916.         sys.stdout = sys.__stdout__
  917.         super().closeEvent(event)
  918.        
  919.  
  920.         #kill sig gen
  921.         if self.SigGenActive.isChecked():
  922.             self.equipment_siggen.rf_off()
  923.  
  924.        
  925.         #kill all amps
  926.         if self.equipment_amp == "vhf":
  927.             self.equipment_vhf_amp.off(self.amp_in_use) #Amp
  928.         elif self.equipment_amp == "uhf":
  929.             self.equipment_uhf_amp.off(self.amp_in_use) #Amp
  930.         elif self.equipment_amp =="shf":
  931.             self.equipment_shf_amp.off(self.amp_in_use) #Amp
  932.         else:
  933.             self.amp_in_use = False
  934.             self.equipment_vhf_amp.off(self.amp_in_use) #Amp
  935.             self.equipment_uhf_amp.off(self.amp_in_use) #Amp
  936.             self.equipment_shf_amp.off(self.amp_in_use) #Amp
  937.            
  938.        
  939.         #kill field probe
  940.         self.equipment_probe.Close_probe()
  941.        
  942. if __name__ == "__main__":
  943.     import sys
  944.     app = QtWidgets.QApplication(sys.argv)
  945.     ui = Ui()
  946.     ui.show()
  947.    
  948.     sys.exit(app.exec_())
Tags: python
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement