from FreeSimpleGUI import TIMEOUT_KEY, WIN_CLOSED import json import math import socket import subprocess import device_interaction as dev import gui use_client = False sending_param = {} #### ---- Constants GUI_TIMEOUT_INTERVAL = 5#505 - dev.WAIT_AFTER_SEND*1000 # GUI refresh time in milliseconds SAVE_POINTS_NUMBER = 1000 # Number of most recent data points kept in memory INITIAL_TEMPERATURE_1 = 28 # Set initial temperature for Laser 1 in Celsius: from -1 to 45 C ?? INITIAL_TEMPERATURE_2 = 28.9 # Set initial temperature for Laser 2 in Celsius: from -1 to 45 C ?? INITIAL_CURRENT_1 = 33 # 64.0879 max # Set initial current for Laser 1, in mA INITIAL_CURRENT_2 = 35 # 64.0879 max # Set initial current for Laser 2, in mA #### ---- Functions def start_task(prt): global sending_param dev.send_task_command(prt, sending_param) def stop_task(prt): global sending_param sending_param = {} dev.reset_port_settings(prt) dev.send_control_parameters(prt, params) def get_float(values, strId): value = 0.0 try: value = float(values[strId]) except: value = float("nan") window['-StartCycle-'].update(disabled = True) return value def shorten(i): return "{:.2f}".format(round(i, 2)) def set_initial_params(): params = {} params['Temp_1'] = INITIAL_TEMPERATURE_1 # Initial temperature for Laser 1 params['Temp_2'] = INITIAL_TEMPERATURE_2 # Initial temperature for Laser 2 params['ProportionalCoeff_1'] = int(10*256) # Proportional coefficient for temperature stabilizatoin for Laser 1 <-- ToDo (why int?) params['ProportionalCoeff_2'] = int(10*256) # Proportional coefficient for temperature stabilizatoin for Laser 2 <-- ToDo (why int?) params['IntegralCoeff_1'] = int(0.5*256) # Integral coefficient for temperature stabilizatoin for Laser 1 <-- ToDo (why int?) params['IntegralCoeff_2'] = int(0.5*256) # Integral coefficient for temperature stabilizatoin for Laser 2 <-- ToDo (why int?) params['Message_ID'] = "00FF" # Send Message ID (hex format) params['Iset_1'] = INITIAL_CURRENT_1 # Currency value array for Laser 1, in mA params['Iset_2'] = INITIAL_CURRENT_2 # Currency value array for Laser 2, in mA params['Min_Temp_1'] = INITIAL_TEMPERATURE_1 params['Max_Temp_1'] = 28 params['Min_Current_1'] = INITIAL_CURRENT_1 params['Max_Current_1'] = 70.0 #50 params['Delta_Temp_1'] = 0.05 params['Delta_Current_1'] = 0.05 params['Min_Temp_2'] = INITIAL_TEMPERATURE_2 params['Max_Temp_2'] = 28 params['Min_Current_2'] = INITIAL_CURRENT_2 params['Max_Current_2'] = 60 # 50 params['Delta_Temp_2'] = 0.05 params['Delta_Current_2'] = 0.05 params['Delta_Time'] = 50 params['Tau'] = 10 return params def update_data_lists(): saved_data.append(data) if len(saved_data)>SAVE_POINTS_NUMBER: saved_data.pop(0) draw_data.append(data) if len(draw_data)>gui.GRAPH_POINTS_NUMBER: draw_data.pop(0) ######## ---- Main program if __name__ == "__main__": saved_data = [] draw_data = [] params = set_initial_params() prt = dev.create_port_connection() if prt is None: print('Can\'t create connection. Closing program...') exit(1) # dev.request_state(prt) dev.send_control_parameters(prt, params) saved_data.append(dev.request_data(prt)) draw_data.append(saved_data[0]) window = gui.setup_gui(params) axes_signs = gui.sign_axes(window) current_and_temperature_settings_available = True disableStartButton = False if use_client: p = subprocess.Popen("path/to/oscilloscope.exe") sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sck.bind(("127.0.0.1", 9090)) sck.listen() conn, _ = sck.accept() while True: event, values = window.read(timeout=GUI_TIMEOUT_INTERVAL) enable_manual_settings = window['-EnableManualSettings-'].get() if current_and_temperature_settings_available: window['-EnableT1-'].update(disabled = enable_manual_settings) window['-EnableT2-'].update(disabled = enable_manual_settings) window['-EnableC1-'].update(disabled = enable_manual_settings) window['-EnableC2-'].update(disabled = enable_manual_settings) window['-InputMinT1-'].update(disabled = enable_manual_settings) window['-InputMaxT1-'].update(disabled = enable_manual_settings) window['-InputDeltaT1-'].update(disabled = enable_manual_settings) window['-InputMinT2-'].update(disabled = enable_manual_settings) window['-InputMaxT2-'].update(disabled = enable_manual_settings) window['-InputDeltaT2-'].update(disabled = enable_manual_settings) window['-InputMinC1-'].update(disabled = enable_manual_settings) window['-InputMaxC1-'].update(disabled = enable_manual_settings) window['-InputDeltaC1-'].update(disabled = enable_manual_settings) window['-InputMinC2-'].update(disabled = enable_manual_settings) window['-InputMaxC2-'].update(disabled = enable_manual_settings) window['-InputDeltaC2-'].update(disabled = enable_manual_settings) window['-InputT1-'].update(disabled = not enable_manual_settings) window['-InputT2-'].update(disabled = not enable_manual_settings) window['-InputI1-'].update(disabled = not enable_manual_settings) window['-InputI2-'].update(disabled = not enable_manual_settings) window['-StartCycle-'].update(disabled = not enable_manual_settings) if current_and_temperature_settings_available and not enable_manual_settings: enable_t1 = window['-EnableT1-'].get() enable_t2 = window['-EnableT2-'].get() enable_c1 = window['-EnableC1-'].get() enable_c2 = window['-EnableC2-'].get() sending_param['ProportionalCoeff_1'] = params['ProportionalCoeff_1'] sending_param['IntegralCoeff_1'] = params['IntegralCoeff_1'] sending_param['ProportionalCoeff_2'] = params['ProportionalCoeff_2'] sending_param['IntegralCoeff_2'] = params['IntegralCoeff_2'] if enable_t1 and \ not enable_t2 and \ not enable_c1 and \ not enable_c2: sending_param['TaskType'] = dev.cmd.TaskType.ChangeTemperatureLD1 sending_param['MinT1'] = get_float(values, '-InputMinT1-') sending_param['MaxT1'] = get_float(values, '-InputMaxT1-') sending_param['DeltaT1'] = get_float(values, '-InputDeltaT1-') sending_param['I1'] = get_float(values, '-InputI1-') sending_param['I2'] = get_float(values, '-InputI2-') sending_param['T2'] = get_float(values, '-InputT2-') sending_param['Dt'] = get_float(values ,'-InputDeltaTime-') sending_param['Tau'] = get_float(values ,'-InputTau-') disableStartButton = math.isnan(sending_param['MinT1']) or \ math.isnan(sending_param['MaxT1']) or \ math.isnan(sending_param['DeltaT1']) or \ math.isnan(sending_param['I1']) or \ math.isnan(sending_param['I2']) or \ math.isnan(sending_param['T2']) or \ math.isnan(sending_param['Dt']) or \ math.isnan(sending_param['Tau']) window['-EnableT2-'].update(disabled = enable_t1) window['-EnableC1-'].update(disabled = enable_t1) window['-EnableC2-'].update(disabled = enable_t1) enable_t2 = window['-EnableT2-'].get() enable_c1 = window['-EnableC1-'].get() enable_c2 = window['-EnableC2-'].get() window['-InputMinT1-'].update(disabled = not enable_t1) window['-InputMaxT1-'].update(disabled = not enable_t1) window['-InputDeltaT1-'].update(disabled = not enable_t1) window['-InputI1-'].update(disabled = not enable_t1) window['-InputI2-'].update(disabled = not enable_t1) window['-InputT2-'].update(disabled = not enable_t1) window['-InputMinT2-'].update(disabled = enable_t1) window['-InputMaxT2-'].update(disabled = enable_t1) window['-InputDeltaT2-'].update(disabled = enable_t1) window['-InputMinC1-'].update(disabled = enable_t1) window['-InputMaxC1-'].update(disabled = enable_t1) window['-InputDeltaC1-'].update(disabled = enable_t1) window['-InputMinC2-'].update(disabled = enable_t1) window['-InputMaxC2-'].update(disabled = enable_t1) window['-InputDeltaC2-'].update(disabled = enable_t1) window['-EnableManualSettings-'].update(disabled = True) elif enable_t2 and \ not enable_t1 and \ not enable_c1 and \ not enable_c2: sending_param['TaskType'] = dev.cmd.TaskType.ChangeTemperatureLD2 sending_param['MinT2'] = get_float(values, '-InputMinT2-') sending_param['MaxT2'] = get_float(values, '-InputMaxT2-') sending_param['DeltaT2'] = get_float(values, '-InputDeltaT2-') sending_param['I1'] = get_float(values, '-InputI1-') sending_param['I2'] = get_float(values, '-InputI2-') sending_param['T1'] = get_float(values, '-InputT1-') sending_param['Dt'] = get_float(values ,'-InputDeltaTime-') sending_param['Tau'] = get_float(values ,'-InputTau-') disableStartButton = math.isnan(sending_param['MinT2']) or \ math.isnan(sending_param['MaxT2']) or \ math.isnan(sending_param['DeltaT2']) or \ math.isnan(sending_param['I1']) or \ math.isnan(sending_param['I2']) or \ math.isnan(sending_param['T1']) or \ math.isnan(sending_param['Dt']) or \ math.isnan(sending_param['Tau']) window['-EnableT1-'].update(disabled = enable_t2) window['-EnableC1-'].update(disabled = enable_t2) window['-EnableC2-'].update(disabled = enable_t2) enable_t1 = window['-EnableT1-'].get() enable_c1 = window['-EnableC1-'].get() enable_c2 = window['-EnableC2-'].get() window['-InputMinT1-'].update(disabled = enable_t2) window['-InputMaxT1-'].update(disabled = enable_t2) window['-InputDeltaT1-'].update(disabled = enable_t2) window['-InputT1-'].update(disabled = not enable_t2) window['-InputI1-'].update(disabled = not enable_t2) window['-InputI2-'].update(disabled = not enable_t2) window['-InputMinT2-'].update(disabled = not enable_t2) window['-InputMaxT2-'].update(disabled = not enable_t2) window['-InputDeltaT2-'].update(disabled = not enable_t2) window['-InputMinC1-'].update(disabled = enable_t2) window['-InputMaxC1-'].update(disabled = enable_t2) window['-InputDeltaC1-'].update(disabled = enable_t2) window['-InputMinC2-'].update(disabled = enable_t2) window['-InputMaxC2-'].update(disabled = enable_t2) window['-InputDeltaC2-'].update(disabled = enable_t2) window['-EnableManualSettings-'].update(disabled = True) elif enable_c1 and \ not enable_c2 and \ not enable_t1 and \ not enable_t2: sending_param['TaskType'] = dev.cmd.TaskType.ChangeCurrentLD1 sending_param['MinC1'] = get_float(values, '-InputMinC1-') sending_param['MaxC1'] = get_float(values, '-InputMaxC1-') sending_param['DeltaC1'] = get_float(values, '-InputDeltaC1-') sending_param['T1'] = get_float(values, '-InputT1-') sending_param['T2'] = get_float(values, '-InputT2-') sending_param['I2'] = get_float(values, '-InputI2-') sending_param['Dt'] = get_float(values ,'-InputDeltaTime-') sending_param['Tau'] = get_float(values ,'-InputTau-') disableStartButton = math.isnan(sending_param['MinC1']) or \ math.isnan(sending_param['MaxC1']) or \ math.isnan(sending_param['DeltaC1']) or \ math.isnan(sending_param['T1']) or \ math.isnan(sending_param['T2']) or \ math.isnan(sending_param['I2']) or \ math.isnan(sending_param['Dt']) or \ math.isnan(sending_param['Tau']) window['-EnableT1-'].update(disabled = enable_c1) window['-EnableT2-'].update(disabled = enable_c1) window['-EnableC2-'].update(disabled = enable_c1) enable_t1 = window['-EnableT1-'].get() enable_t2 = window['-EnableT2-'].get() enable_c2 = window['-EnableC2-'].get() window['-InputMinT1-'].update(disabled = enable_c1) window['-InputMaxT1-'].update(disabled = enable_c1) window['-InputDeltaT1-'].update(disabled = enable_c1) window['-InputT1-'].update(disabled = not enable_c1) window['-InputT2-'].update(disabled = not enable_c1) window['-InputI2-'].update(disabled = not enable_c1) window['-InputMinT2-'].update(disabled = enable_c1) window['-InputMaxT2-'].update(disabled = enable_c1) window['-InputDeltaT2-'].update(disabled = enable_c1) window['-InputMinC1-'].update(disabled = not enable_c1) window['-InputMaxC1-'].update(disabled = not enable_c1) window['-InputDeltaC1-'].update(disabled = not enable_c1) window['-InputMinC2-'].update(disabled = enable_c1) window['-InputMaxC2-'].update(disabled = enable_c1) window['-InputDeltaC2-'].update(disabled = enable_c1) window['-EnableManualSettings-'].update(disabled = True) elif enable_c2 and \ not enable_c1 and \ not enable_t1 and \ not enable_t2: sending_param['TaskType'] = dev.cmd.TaskType.ChangeCurrentLD2 sending_param['MinC2'] = get_float(values, '-InputMinC2-') sending_param['MaxC2'] = get_float(values, '-InputMaxC2-') sending_param['DeltaC2'] = get_float(values, '-InputDeltaC2-') sending_param['T1'] = get_float(values, '-InputT1-') sending_param['T2'] = get_float(values, '-InputT2-') sending_param['I1'] = get_float(values, '-InputI1-') sending_param['Dt'] = get_float(values ,'-InputDeltaTime-') sending_param['Tau'] = get_float(values ,'-InputTau-') disableStartButton = math.isnan(sending_param['MinC2']) or \ math.isnan(sending_param['MaxC2']) or \ math.isnan(sending_param['DeltaC2']) or \ math.isnan(sending_param['T1']) or \ math.isnan(sending_param['T2']) or \ math.isnan(sending_param['I1']) or \ math.isnan(sending_param['Dt']) or \ math.isnan(sending_param['Tau']) window['-EnableT1-'].update(disabled = enable_c2) window['-EnableT2-'].update(disabled = enable_c2) window['-EnableC1-'].update(disabled = enable_c2) enable_t1 = window['-EnableT1-'].get() enable_t2 = window['-EnableT2-'].get() enable_c1 = window['-EnableC1-'].get() window['-InputMinT1-'].update(disabled = enable_c2) window['-InputMaxT1-'].update(disabled = enable_c2) window['-InputDeltaT1-'].update(disabled = enable_c2) window['-InputI1-'].update(disabled = not enable_c2) window['-InputT1-'].update(disabled = not enable_c2) window['-InputT2-'].update(disabled = not enable_c2) window['-InputMinT2-'].update(disabled = enable_c2) window['-InputMaxT2-'].update(disabled = enable_c2) window['-InputDeltaT2-'].update(disabled = enable_c2) window['-InputMinC1-'].update(disabled = enable_c2) window['-InputMaxC1-'].update(disabled = enable_c2) window['-InputDeltaC1-'].update(disabled = enable_c2) window['-InputMinC2-'].update(disabled = not enable_c2) window['-InputMaxC2-'].update(disabled = not enable_c2) window['-InputDeltaC2-'].update(disabled = not enable_c2) window['-EnableManualSettings-'].update(disabled = True) elif not enable_t1 and \ not enable_t2 and \ not enable_c1 and \ not enable_c2: sending_param = {} window['-EnableT1-'].update(disabled = False) window['-EnableT2-'].update(disabled = False) window['-EnableC1-'].update(disabled = False) window['-EnableC2-'].update(disabled = False) window['-InputMinT1-'].update(disabled = True) window['-InputMaxT1-'].update(disabled = True) window['-InputDeltaT1-'].update(disabled = True) window['-InputMinT2-'].update(disabled = True) window['-InputMaxT2-'].update(disabled = True) window['-InputDeltaT2-'].update(disabled = True) window['-InputMinC1-'].update(disabled = True) window['-InputMaxC1-'].update(disabled = True) window['-InputDeltaC1-'].update(disabled = True) window['-InputMinC2-'].update(disabled = True) window['-InputMaxC2-'].update(disabled = True) window['-InputDeltaC2-'].update(disabled = True) window['-InputT1-'].update(disabled = True) window['-InputT2-'].update(disabled = True) window['-InputI1-'].update(disabled = True) window['-InputI2-'].update(disabled = True) window['-EnableManualSettings-'].update(disabled = False) window['-InputDeltaTime-'].update(disabled = not enable_c1 and not enable_t1 and not enable_c2 and not enable_t2) window['-InputTau-'].update(disabled = not enable_c1 and not enable_t1 and not enable_c2 and not enable_t2) window['-StartCycle-'].update(disabled = not enable_c1 and not enable_t1 and not enable_c2 and not enable_t2 or disableStartButton) if event == WIN_CLOSED or event == '-EXIT-': if use_client: p.terminate() conn.close() sck.close() dev.reset_port_settings(prt) break elif event == '-StartCycle-': if not enable_manual_settings: window['-StopCycle-'].update(disabled = False) window['-StartCycle-'].update(disabled = True) window['-EnableT1-'].update(disabled = True) window['-EnableC1-'].update(disabled = True) window['-EnableT1-'].update(False) window['-EnableC1-'].update(False) window['-EnableT2-'].update(disabled = True) window['-EnableC2-'].update(disabled = True) window['-EnableT2-'].update(False) window['-EnableC2-'].update(False) window['-InputMinT1-'].update(disabled = True) window['-InputMaxT1-'].update(disabled = True) window['-InputDeltaT1-'].update(disabled = True) window['-InputMinT2-'].update(disabled = True) window['-InputMaxT2-'].update(disabled = True) window['-InputDeltaT2-'].update(disabled = True) window['-InputMinC1-'].update(disabled = True) window['-InputMaxC1-'].update(disabled = True) window['-InputDeltaC1-'].update(disabled = True) window['-InputMinC2-'].update(disabled = True) window['-InputMaxC2-'].update(disabled = True) window['-InputDeltaC2-'].update(disabled = True) window['-InputDeltaTime-'].update(disabled = True) window['-InputTau-'].update(disabled = True) window['-InputT1-'].update(disabled = True) window['-InputT2-'].update(disabled = True) window['-InputI1-'].update(disabled = True) window['-InputI2-'].update(disabled = True) current_and_temperature_settings_available = False # TODO get task parameters from gui and put its to params if use_client: jsondoc_str = json.dumps(sending_param) jsondoc = bytearray() jsondoc.extend(jsondoc_str.encode()) conn.sendall(jsondoc) start_task(prt) else: params['Temp_1'] = float(values['-InputT1-']) params['Temp_2'] = float(values['-InputT2-']) params['Iset_1'] = float(values['-InputI1-']) params['Iset_2'] = float(values['-InputI2-']) dev.send_control_parameters(prt, params) #print(sending_param) elif event == '-StopCycle-': window['-StopCycle-'].update(disabled = True) current_and_temperature_settings_available = True stop_task(prt) elif event == TIMEOUT_KEY: data = dev.request_data(prt) update_data_lists() window['-TOUT_1-'].update(gui.READ_TEMPERATURE_TEXT+' 1: '+shorten(data['Temp_1'])+' C') window['-TOUT_2-'].update(gui.READ_TEMPERATURE_TEXT+' 2: '+shorten(data['Temp_2'])+' C') window['-IOUT_1-'].update(gui.READ_CURRENT_TEXT+' 1: '+shorten(data['I1'])+' мА') window['-IOUT_2-'].update(gui.READ_CURRENT_TEXT+' 2: '+shorten(data['I2'])+' мА') window['-DateTime-'].update(data['datetime'].strftime('%d-%m-%Y %H:%M:%S:%f')[:-3]) window['-TTerm1-'].update('T терм 1: '+shorten(data['Temp_Ext_1'])+' C') window['-TTerm2-'].update('T терм 2: '+shorten(data['Temp_Ext_2'])+' C') window['-3V3-'].update('3V3: '+shorten(data['MON_3V3'])+' В') window['-5V1-'].update('5V1: '+shorten(data['MON_5V1'])+' В') window['-5V2-'].update('5V2: '+shorten(data['MON_5V2'])+' В') window['-7V0-'].update('7V0: '+shorten(data['MON_7V0'])+' В') window['-GraphT1-'].draw_line((len(draw_data)-1, draw_data[-2]['Temp_1']), (len(draw_data), draw_data[-1]['Temp_1']), color='yellow') window['-GraphT2-'].draw_line((len(draw_data)-1, draw_data[-2]['Temp_2']), (len(draw_data), draw_data[-1]['Temp_2']), color='yellow') window['-GraphI1-'].draw_line((len(draw_data)-1, draw_data[-2]['I1']), (len(draw_data), draw_data[-1]['I1']), color='yellow') window['-GraphI2-'].draw_line((len(draw_data)-1, draw_data[-2]['I2']), (len(draw_data), draw_data[-1]['I2']), color='yellow') # When graphs reach end of X scale, start scrolling if len(draw_data)>=gui.GRAPH_POINTS_NUMBER: # Scroll graphs window['-GraphT1-'].move(-1, 0) window['-GraphT2-'].move(-1, 0) window['-GraphI1-'].move(-1, 0) window['-GraphI2-'].move(-1, 0) # Scroll back graphs' labels for key, sgn in axes_signs.items(): window[key].MoveFigure(sgn[0], 1, 0) window[key].MoveFigure(sgn[1], 1, 0) window.close() dev.close_connection(prt)