我如何创建一个停止按钮,它会立即终止 python 运行函数

问题描述 投票:0回答:0

问题 - 我有一个 python 函数,它从 excel 读取值,进行计算并将数据写回 excel。在 sg.window 我需要创建一个停止按钮,它会立即终止 python 运行进程。
为什么我需要 - 我的 python 函数将在 .exe 文件中创建,因此用户不能使用 KeyboardInterrupt 和 control+c,这就是为什么我需要创建一个按钮。
我试过 - 我做了一些方法来使用线程,但它没有帮助尝试线程,停止按钮没有停止,也许我做错了什么。我对此知之甚少。请帮我。 愿意使用其他方法和想法

import PySimpleGUI as sg
import time
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import numpy as np
from peak_shave.peak_shave_reader import Peakshave_Reader
from Seb.profit_calculator_dataclass_neu import *
from peak_shave.raw_data_setup_profit_calculator import Raw_data_from_Peak_shave, peak_shave_final_data



def Python_profitcalculator_simulation(file_path):  

    progress_bar.update(10) # 10% of progress for funtion loads
    excel_workbook = Peakshave_Reader(file_path)
    progress_bar.update(20) # 20% of progress for excel sheet load

    
    # Reading Peak_shave excel

    Pv_Profile_Raw = Raw_data_from_Peak_shave.PV_profile_raw(excel_workbook)
    Load_Profile_raw = Raw_data_from_Peak_shave.Load_profile_raw(excel_workbook)
    Investtabelle_Raw = Raw_data_from_Peak_shave.Investtabelle_raw_data(excel_workbook)
    battery_raw_Eingabe_Übersicht_sheet = Raw_data_from_Peak_shave.Raw_data_from_Eingabe_Übersicht_sheet(excel_workbook)
    battery_raw_Simulation_sheet = Raw_data_from_Peak_shave.Raw_data_from_Simulation_sheet(excel_workbook)
    battery_raw_AdvanceSettingsDatabase_sheet = Raw_data_from_Peak_shave.Raw_data_from_AdvanceSettingsDatabase_sheet(excel_workbook)
    battery_raw_Wirtschaftlichkeitsmatrix_sheet = Raw_data_from_Peak_shave.Raw_data_from_Wirtschaftlichkeitsmatrix_sheet(excel_workbook)
    Wirtschaftlichkeitsmatrix_Raw = Raw_data_from_Peak_shave.wirtschaftlichkeitsmatrix_sheet_batteriekonfigurationen_values(excel_workbook)

    # Convertion of values in SI unit

    PV_Profile = peak_shave_final_data.PV_profile_conversion(Pv_Profile_Raw)
    Load_Profile = peak_shave_final_data.Load_profile_conversion(Load_Profile_raw)

    Eingabe_Übersicht_sheet = peak_shave_final_data.Eingabe_Übersicht_conversion(battery_raw_Eingabe_Übersicht_sheet)
    Simulation_sheet = peak_shave_final_data.Simulation_convertsion(battery_raw_Simulation_sheet)
    AdvanceSettingsDatabase_sheet = peak_shave_final_data.AdvanceSettingsDatabase_conversion(battery_raw_AdvanceSettingsDatabase_sheet)
    Wirtschaftlichkeitsmatrix_sheet = peak_shave_final_data.Wirtschaftlichkeitsmatrix_conversion(battery_raw_Wirtschaftlichkeitsmatrix_sheet)
    Wirtschaftlichkeitsmatrix_battery_configuration = peak_shave_final_data.Wirtschaftlichkeitsmatrix_SIunit_converter(Wirtschaftlichkeitsmatrix_Raw)

    #profile setup for simulation
    p_pv = np.array(PV_Profile['PV_profile'])
    p_load = np.array(Load_Profile['Load_profile'])*-1
   
    progress_bar.update(30) # 30% of progress for required values read from excel sheet
    #general input
    technical_input = dict(
    p_cut_consumption_W = Eingabe_Übersicht_sheet.P_cut_consumption_W,
    PV_W_peak = Eingabe_Übersicht_sheet.PV_Pinstall,
    cp_rate = Eingabe_Übersicht_sheet.Cp_rate,
    bat_capacity_E_Wh = Eingabe_Übersicht_sheet.Battery_energy_nominal,
    DoD_pu = Simulation_sheet.DoD,
    p_reserve_W = Eingabe_Übersicht_sheet.Battery_Pmax_reserve,
    efficiency = Eingabe_Übersicht_sheet.Battery_efficiency,
    SOC_target_pu = Eingabe_Übersicht_sheet.Battery_soll_soc_1,
    SOC_reserve_pu = Eingabe_Übersicht_sheet.Battery_reserve_soc_1
    )
    eco_input = dict(
    cost_pv_per_kWp = Eingabe_Übersicht_sheet.Investment_cost_PV,
    cost_bat = Eingabe_Übersicht_sheet.Investment_cost_battery,
    equity = Eingabe_Übersicht_sheet.Equity_share,
    duration_funding_years = Eingabe_Übersicht_sheet.Financing_period,
    duration_operation_years = Eingabe_Übersicht_sheet.Observation_period
    )

    general = {
    'technical_input' : technical_input,
    'eco_input' : eco_input
    }

    #advanced input
    tech_param = dict(
    SOC_start_pu= AdvanceSettingsDatabase_sheet.Battery_soc_start,
    degradation = AdvanceSettingsDatabase_sheet.Degredation,
    pv_deg_per_year = AdvanceSettingsDatabase_sheet.PV_degradation_per_year, #/a
    bat_deg_per_year = AdvanceSettingsDatabase_sheet.Battery_degradation
    )
    maintanance_spare = dict(
    maintained = AdvanceSettingsDatabase_sheet.Maintained,
    pv_maintain_per_akWp = AdvanceSettingsDatabase_sheet.Maintenance_cost_PV, 
    bat_maintain_per_akWh = AdvanceSettingsDatabase_sheet.Maintenance_cost_battery, 
    pv_spare_per_akWp = AdvanceSettingsDatabase_sheet.PV_spare_per_kWp,
    bat_spare_per_akWh = AdvanceSettingsDatabase_sheet.Bat_spare_per_kWh
    )
    insurance = dict(
    pv_insured = AdvanceSettingsDatabase_sheet.Consider_insurance_PV,
    pv_insurance_per_akWp = AdvanceSettingsDatabase_sheet.PV_insurance, #/kWp * a
    bat_insured = AdvanceSettingsDatabase_sheet.Consider_insurance_bat,
    bat_insurance_per_akWh = AdvanceSettingsDatabase_sheet.Battery_insurance #/kWp * a
    )
    finance = dict(
    borrowed_interest = AdvanceSettingsDatabase_sheet.Borrowing_rate
    )
    tax = dict(
    corporate_tax = AdvanceSettingsDatabase_sheet.Corporate_tax,
    trade_tax = AdvanceSettingsDatabase_sheet.Trade_tax
    )
    discount = dict(
    discounted = AdvanceSettingsDatabase_sheet.Consider_discounting,
    discounting = AdvanceSettingsDatabase_sheet.Discount
    )
    price_per_unit = dict(
    cost_current_jbd_below_per_kWh = AdvanceSettingsDatabase_sheet.Electricity_price_jbd_above_per_kWp,
    cost_current_jbd_above_per_kWh = AdvanceSettingsDatabase_sheet.Electricity_price_jbd_below_per_kWp,
    cost_power_jbd_below_per_kW = Eingabe_Übersicht_sheet.Power_price_jbd_above_per_kWp,
    cost_power_jbd_above_per_kW = Eingabe_Übersicht_sheet.Power_price_jbd_below_per_kWp,
    revenue_injected_current_per_kWh = Eingabe_Übersicht_sheet.Feedin_with_PPA_Direct_feedin_PV,
    staggering_current_per_year = AdvanceSettingsDatabase_sheet.Electricity_price_increase_rate
    )
    lease = dict(
    leased = AdvanceSettingsDatabase_sheet.Consider_lease,
    needed_space_pv_ha_per_MWp = AdvanceSettingsDatabase_sheet.PV_space_requirement,
    needed_space_bat_ha_per_MWh = AdvanceSettingsDatabase_sheet.Battery_space_requirement,
    lease_pv_per_ha = AdvanceSettingsDatabase_sheet.PV_lease,
    lease_bat_per_ha = AdvanceSettingsDatabase_sheet.Battery_lease
    )

    advanced = {
    'tech_param': tech_param,
    'maintanance_spare' : maintanance_spare,
    'insurance' : insurance,
    'finance' : finance,
    'tax' : tax,
    'discount' : discount,
    'price_per_unit' : price_per_unit,
    'lease' : lease
    }

    #other input not important
    other_input = dict(
    abschreibung_pv = 25_000,
    abschreibung_bat = 13_750.66
    )

    profit_calc_params = {
    'general' : general,
    'advanced' : advanced,
    'other_input' : other_input
    }

    
    W_matrix = {'energy_column_1': Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_1,
    'energy_column_2' : Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_2,
    'energy_column_3': Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_3,
    'energy_column_4' :Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_4,
    'energy_column_5': Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_5,
    'energy_column_6': Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_6,
    'energy_column_7' : Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_7,
    'energy_column_8' : Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_8,
    'energy_column_9' : Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_9,
    'energy_column_10' : Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_10}

    W_matrix_bool = {'energy_column_1': Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_1_bool,
    'energy_column_2' : Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_2_bool,
    'energy_column_3': Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_3_bool,
    'energy_column_4' :Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_4_bool,
    'energy_column_5': Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_5_bool,
    'energy_column_6': Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_6_bool,
    'energy_column_7' : Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_7_bool,
    'energy_column_8' : Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_8_bool,
    'energy_column_9' : Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_9_bool,
    'energy_column_10' : Wirtschaftlichkeitsmatrix_battery_configuration.energy_column_10_bool}


    W_matrix_C_rate = {'C_Rate_row_1' : Wirtschaftlichkeitsmatrix_battery_configuration.C_Rate_row_1,
    'C_Rate_row_2' : Wirtschaftlichkeitsmatrix_battery_configuration.C_Rate_row_2,
    'C_Rate_row_3' : Wirtschaftlichkeitsmatrix_battery_configuration.C_Rate_row_3,
    'C_Rate_row_4' : Wirtschaftlichkeitsmatrix_battery_configuration.C_Rate_row_4,
    'C_Rate_row_5' : Wirtschaftlichkeitsmatrix_battery_configuration.C_Rate_row_5}

    W_matrix_C_rate_bool = {'C_Rate_row_1' : Wirtschaftlichkeitsmatrix_battery_configuration.C_Rate_row_1_bool,
    'C_Rate_row_2' : Wirtschaftlichkeitsmatrix_battery_configuration.C_Rate_row_2_bool,
    'C_Rate_row_3' : Wirtschaftlichkeitsmatrix_battery_configuration.C_Rate_row_3_bool,
    'C_Rate_row_4' : Wirtschaftlichkeitsmatrix_battery_configuration.C_Rate_row_4_bool,
    'C_Rate_row_5' : Wirtschaftlichkeitsmatrix_battery_configuration.C_Rate_row_5_bool}

   
    # Investtabelle battery cost setup
    bats = []
    for key in W_matrix:
        if W_matrix_bool[key] == 'berechnen':
            bats.append(W_matrix[key])

    rates = []
    for key in W_matrix_C_rate:
        if W_matrix_C_rate_bool[key] == 'berechnen':
            rates.append(W_matrix_C_rate[key])

    investtable = pd.DataFrame(index = rates, columns = bats)
    for bat in bats:
        for rate in rates:
            if Eingabe_Übersicht_sheet.Battery_type == 'Generisch':
                battery_type_key = 'PB300'
            else:
                battery_type_key = Eingabe_Übersicht_sheet.Battery_type
            try:
                investtable[bat][rate] = Investtabelle_Raw[Eingabe_Übersicht_sheet.Battery_module][battery_type_key][Eingabe_Übersicht_sheet.Installation_site]['energy'+'_'+str(int(bat/1000))+'_C_rate_'+str(rate)]
            except KeyError: 
                investtable[bat][rate]= 0
                print("KeyError:", rate)

    battery_type = Eingabe_Übersicht_sheet.Battery_type
    SOC_res1 = Eingabe_Übersicht_sheet.Battery_reserve_soc_1
    SOC_res2 = Eingabe_Übersicht_sheet.Battery_reserve_soc_2
    SOC1_max = Wirtschaftlichkeitsmatrix_sheet.Soll_soc_1_max
    SOC1_min = Wirtschaftlichkeitsmatrix_sheet.Soll_soc_1_min
    SOC2_max = Wirtschaftlichkeitsmatrix_sheet.Soll_soc_2_max
    SOC2_min = Wirtschaftlichkeitsmatrix_sheet.Soll_soc_2_min
    SOC_step_percent = Wirtschaftlichkeitsmatrix_sheet.Step_size_soc
    accuracy = Wirtschaftlichkeitsmatrix_sheet.Break_off_precision_peakshaving
    finanzierung = Wirtschaftlichkeitsmatrix_sheet.Financing
    
    SOC_start = AdvanceSettingsDatabase_sheet.Battery_soc_start
    year_list = get_year_list(Eingabe_Übersicht_sheet.Battery_soll_soc_2_start,Eingabe_Übersicht_sheet.Battery_soll_soc_2_end)

    timestep =0.25 #=15min

    progress_bar.update(50) # 50% of progress for pre process done and simulation is starting

    # Simulation
    amount_SOCs = Wirtschaftlichkeitsmatrix_sheet.Number_of_SOCs
    algorithm = Wirtschaftlichkeitsmatrix_sheet.Algorithm_for_12_SOCs
    simulation = Wirtschaftlichkeitsmatrix_sheet.Year_simulation_of_the_best_system

    if amount_SOCs == 2:
        w_matrix, wartung = w_matrix_modular_excel(p_load, p_pv,0,SOC_res1, SOC_res2, SOC_start, SOC1_min, SOC1_max,  SOC2_min, SOC2_max,SOC_step_percent, accuracy, Wirtschaftlichkeitsmatrix_sheet.Consideration_case,finanzierung,bats,rates, profit_calc_params, investtable, battery_type,year_list, timestep)
    else:
        if algorithm == 'dispatcher':
            algo = 1
        elif algorithm == 'brute-force':
            algo = 2
        else: 
            algo = 3
        w_matrix = w_matrix_modular_monthly(algo, p_load, p_pv, SOC_start, SOC1_min, SOC1_max,  SOC_step_percent, Wirtschaftlichkeitsmatrix_sheet.Consideration_case,finanzierung,bats,rates, profit_calc_params, investtable, battery_type, timestep)
    
    system,bat_capacity_E,c_rate = get_most_profitable_system(w_matrix)


    progress_bar.update(80) # 80% of progress for Simulation done and writing results

    if simulation == 'EXCEL' and amount_SOCs == 2:
        Peakshave_Reader.write_Best_system_to_excel(excel_workbook,matrix_data=system,bat_energie=bat,c_rate=c_rate)
        Peakshave_Reader.write_matrixdata_SOCs_to_excel(excel_workbook,number_of_SOCs=amount_SOCs,Profit_calculator_matrix_result=w_matrix)
        ##just write the data back,  no simulatioon
    elif simulation == 'BETSI':
        pass
        #results = GlobalFactory
        #write it back
    else:
        results = do_simulation_with_numba(p_load, p_pv, system, bat_capacity_E, c_rate, battery_type, SOC_start, year_list)
        Peakshave_Reader.write_Best_system_to_excel(excel_workbook,matrix_data=system,bat_energie=bat,c_rate=c_rate)
        Peakshave_Reader.write_data_to_excel(excel_workbook,data=results)
        Peakshave_Reader.write_matrixdata_SOCs_to_excel(excel_workbook,number_of_SOCs=amount_SOCs,Profit_calculator_matrix_result=w_matrix)
        #write it back
    progress_bar.update(100) # 100% process completed


# Define GUI layout
layout = [[sg.Text("Select Excel file:")], # For title
          [sg.Input(key="-FILE-"), sg.FileBrowse(file_types=(("Excel Files", "*.xlsb"),))], # Browse button configuration
          [sg.ProgressBar(100, orientation='h', size=(20, 20), key='-PROGRESS-')], # progress bar configuration
          [sg.Button("Process"), sg.Button("Stop")]] # cancel button & process button configuration 

# Create GUI window
window = sg.Window("Peak Shave Simualtion", layout ,icon="C:\Env\Profit_calculator\Tricera-logo.ico") # main window configuration
progress_bar = window['-PROGRESS-']

# Event loop
while True:
    event, values = window.read()
    if event == sg.WIN_CLOSED or event == 'Cancel': # if closed or click on cancel button window will close
        break
    elif event == 'Process': 
        file_path = values['-FILE-']
        start_time = time.time()
        Python_profitcalculator_simulation(file_path)
        end_time = time.time()
        sg.popup(f"Processing complete!\nSimulation total time: {(f'{((end_time - start_time)/60):.2f} minutes' if (end_time - start_time) >= 60 else f'{(end_time - start_time):.2f} seconds')}")

        break
    elif event == 'Stop':
    **What should i write here**

# Close GUI window
window.close()
python python-multithreading pysimplegui kill-process
© www.soinside.com 2019 - 2024. All rights reserved.