# %% 
# Bestimmung Energie pro Teil bzw. Zyklus
# Vorgehen: 10 Teile pro 15 minuten -> Bestimmung Energie pro 15 minuten Zyklus -> Leistung*15 Minuten durch 10 Teile 
# Prüfung via Energy of the power state?

#manual Calculation with raw data
import pandas as pd

# Load the dataset (replace 'your_dataset.csv' with the actual file name)
data = pd.read_csv('Data310823_merge.csv')

# Make sure the 'Timestamp' column is in the datetime format
data['Timestamp'] = pd.to_datetime(data['Timestamp'])

# Define the start and end of the cycle (replace with the actual timestamps)
cycle_start = '2023-08-31 05:29:00'
cycle_end = '2023-08-31 05:44:00'

# Convert the cycle start and end to datetime
cycle_start = pd.to_datetime(cycle_start)
cycle_end = pd.to_datetime(cycle_end)

# Filter the dataset to only include the data within the cycle
cycle_data = data[(data['Timestamp'] >= cycle_start) & (data['Timestamp'] <= cycle_end)].copy()

cycle_data.loc[:, 'Time_diff'] = cycle_data['Timestamp'].diff().dt.total_seconds().fillna(0)
# Power in Watt to kWatt and Time in seconds =  Energy in kWs
cycle_data.loc[:, 'Energy'] = (cycle_data['Pges']/1000) * cycle_data['Time_diff']  

# Sum up the total energy in the cycle
total_energy_kWs = cycle_data['Energy'].sum()  # Energy in kilowatt-seconds (kWs)
total_energy_kWh = total_energy_kWs / 3600  # Convert kWs to kilowatt-hours (kWh)
total_energy_part = total_energy_kWh / 10 # Energy per part -> 10 Parts per cycle

print(f'Total energy consumed in the cycle: {total_energy_kWh} kWh')
print(f'Total energy consumed per Part: {total_energy_part} kWh')



# %% 
#  Calculate Storage Cpacity
import pandas as pd

import matplotlib.pyplot as plt

Energy_per_part = total_energy_part #0.059 # kWh
dauer_schicht = 8 # stunden
output_storage_size_min = 20 # Rohteile 30 min Produktion möglich
output_storage_size_soll =  40 # Teile für 1 h (Dauerproduktion)
output_storage_size_max =  output_storage_size_soll*dauer_schicht #320 Teile
print(f"Material Storage max: {output_storage_size_max} Pieces")

Energy_max_storage = output_storage_size_max*Energy_per_part
print(f"Material Storage Capacity max: {Energy_max_storage} kWh")

Energy_min_storage = output_storage_size_min*Energy_per_part
print(f"Material Storage Capacity min: {Energy_min_storage} kWh")

Energy_Flex_Potenzial = Energy_max_storage-Energy_min_storage # kWh 
print(f"Material Flex Potenzial Capacity: {Energy_Flex_Potenzial} kWh")

# Initial Energy Content
E_init_min = output_storage_size_min*Energy_per_part
print(f"Initial Energy Content Minimum {E_init_min} kWh")
E_init_max = output_storage_size_soll*Energy_per_part
print(f"Initial Energy Content Maximum {E_init_max} kWh") # defniert auf sollwert 40 Teile


print(f"Target Energy Content soll mit Initial Energy Content identisch sein")


print(f"Eloss_max = {0} %/h") # Es fallen keine Teile vom Band

# Supply System 
Supply_system = "EMAG GT with Factor 1.0"
print(f"Supplier of storage is: {Supply_system}")

# Calculation of Drain
E_Drain = 'Depends from production plan' # Wie viele Teile pro schicht gefertigt werden müssen
print(f"E_Drain is: {E_Drain}")

t_cycle = 15 # min
parts_per_cycle = 10 # Teile in Zyklus
#   (Speichergröße in Teilen / Teile Pro Zyklus)*Zykluszeit / 60 umrechnung in Stunden
max_flex_duration = (output_storage_size_max/parts_per_cycle)*t_cycle / 60 # 

print(f"Maximization of flex duration with Storage is: {max_flex_duration} h")

# %%
#  PLOT FLEX SPACE EMAG GT + Storage 
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.colors as mcolors

def plot_machine(ax, leistung, dauer, aenderungsrate, unabhaengigkeit, cmap, norm):
    heat = plt.cm.gray(norm(unabhaengigkeit))
    #heat = plt.cm.plasma(unabhaengigkeit)
    
    # Plot the top surface
    Z = aenderungsrate * np.ones_like(leistung)
    ax.plot_surface(leistung, dauer, Z, color=heat,shade=False)#, alpha=1)
    
    # Plot the bottom surface
    Z = np.zeros_like(leistung)
    ax.plot_surface(leistung, dauer, Z, color=heat,shade=False, alpha=0.5)
    
    # Plot vertical edges to create a 3D volume
    for i in [0, 1]:
        for j in [0, 1]:
            ax.plot([leistung[i, j], leistung[i, j]], 
                    [dauer[i, j], dauer[i, j]], 
                    [0, aenderungsrate], 
                    color=heat)
# Daten berechnet aus EFDM 1 
leistung = np.array([[0.2, 2.289], [0.2, 2.289]]) # Power state max von WZM GT
dauer = np.array([[max_flex_duration, max_flex_duration], [0, 0]]) # Holding Duration max / min in h 
aenderungsrate1 = 0.320 # Gradienten eintragen
unabhaengigkeit1 = 0.4 #lagged Correlation Wert


#plt.rcParams['font.size'] = 12

# Erstellen des Plots für WZM
fig = plt.figure(figsize=(10, 10))
cmap = plt.cm.plasma
norm = mcolors.Normalize(vmin=0, vmax=1)

# Plot für Maschine 1
ax = fig.add_subplot(111, projection='3d')
plot_machine(ax, leistung, dauer, aenderungsrate1, unabhaengigkeit1, cmap, norm)
#ax.set_title("WZM EMAG GT")

# Skalierung anpassen
ax.set_xlim([0, 3]) #Power
ax.set_ylim([0, 10]) # Dauer
ax.set_zlim([0, 0.6]) # Changerate



# Labels setzen
ax.set_xlabel('Power in kW', fontsize=16)
ax.set_ylabel('Duration in h',fontsize=16)
ax.set_zlabel(r'$\nabla$P in kW/s',fontsize=16)
ax.tick_params(axis='both', labelsize=16) 
plt.tight_layout(pad=0.1)

plt.savefig("flexspace_emag_storage.svg", format='svg')
#plt.savefig('flexspace_emag_storage.png')

plt.show()

