EC2 Default User
add ref
f98e2d7
Raw
History Blame Contribute Delete
8.67 kB
import io
import os
import pandas as pd
import streamlit as st
from openpyxl import Workbook
from openpyxl.utils.dataframe import dataframe_to_rows
from streamlit_extras.stylable_container import stylable_container
from WattFieldsCommon.constants import PATH_APP_FOLDER, PATH_IMG_FOLDER
from WattFieldsCommon.optim_analytics import (
generate_df_block_temporal_analysis,
generate_df_spatial_analysis,
generate_df_temporal_analysis,
generate_run_df_summary,
generate_df_gstd_block
)
def setup_st_config_with_navbar(page_title, add_navbar=True):
PATH_LOGO = os.path.join(PATH_IMG_FOLDER, "logo.png")
st.logo(PATH_LOGO, icon_image=PATH_LOGO, size="large")
st.set_page_config(layout="wide", page_title=page_title)
st.markdown(
"""
<style>
/* Adjust font size for tabs */
.stTabs [data-baseweb="tab-list"] button [data-testid="stMarkdownContainer"] p {
font-size: 1.2rem;
}
/* Center the tab container */
.stTabs [data-baseweb="tab-list"] {
justify-content: center; /* Centers the tabs horizontally */
}
/* Optional: Add padding for the main container */
.block-container {
padding-top: 2.8rem;
padding-bottom: 4rem;
padding-left: 5rem;
padding-right: 5rem;
}
</style>
""",
unsafe_allow_html=True,
)
if add_navbar:
with stylable_container(
"green",
css_styles="""
button {
width: 100%;
box-shadow: transparent 0 0 0 5px,rgba(18, 18, 18, .1) 0 6px 20px;
color: #121212;
line-height: 0.2;
align-items: center;
padding: 1rem 1.4rem;
text-align: center;
transition: box-shadow .2s,-webkit-box-shadow .2s;
}""",
):
col1, col2, col3 = st.columns(3)
if col2.button("Revenir à la carte des sites"):
st.switch_page(os.path.join(PATH_APP_FOLDER, "pages", "carte_sites.py"))
def get_first_end_index_anti_tracking(df_weekly_blocks):
df_weekly_blocks_at = df_weekly_blocks[
df_weekly_blocks["weekly_strategy_choice"] == "anti-tracking"
]
return list(df_weekly_blocks_at["block_first_time_index"]), list(
df_weekly_blocks_at["block_last_time_index"]
)
@st.cache_data
def generate_dfs_and_excel_file(run, simu_config, ref_agri_run, ref_pv_run):
# Generate all metrics / data associated to a specific run, cache them to gain some time
ref_agri_yield = ref_agri_run["general_metrics"]["average_agri_yield"]
ref_pv_energy = ref_pv_run["general_metrics"]["average_pv_energy"]
PV_PNOM = simu_config["SolarFarmBifacial"]["panel_peak_power"]
df_summary = generate_run_df_summary(
dict_run=run,
ref_agri_yield=ref_agri_yield,
ref_pv_energy=ref_pv_energy,
surface_panel=simu_config["SolarFarmBifacial"]["panel_surface"],
pv_module_pnom=PV_PNOM,
planting_date=simu_config["WeatherData"]["planting_date"],
)
df_temporal_analysis = generate_df_temporal_analysis(
dict_run=run, dict_ref_agri_run=ref_agri_run
)
df_spatial_analysis = generate_df_spatial_analysis(dict_run=run,
dict_ref_agri_run=ref_agri_run)
df_block_temporal_analysis = generate_df_block_temporal_analysis(
dict_run=run, ref_pv_run=ref_pv_run, pv_module_pnom=PV_PNOM
)
df_block_temporal_analysis["weekly_collected_ac_energy_per_peak_power"] = (
df_block_temporal_analysis["weekly_collected_ac_energy"] / PV_PNOM
)
df_block_temporal_analysis_for_excel = df_block_temporal_analysis.copy()
df_block_temporal_analysis_for_excel["block_first_time_index"] = (
df_block_temporal_analysis_for_excel["block_first_time_index"].dt.tz_localize(None)
)
df_block_temporal_analysis_for_excel["block_middle_time_index"] = (
df_block_temporal_analysis_for_excel["block_middle_time_index"].dt.tz_localize(None)
)
df_block_temporal_analysis_for_excel["block_last_time_index"] = (
df_block_temporal_analysis_for_excel["block_last_time_index"].dt.tz_localize(None)
)
df_summary_for_excel = df_summary.copy()
df_summary_for_excel.loc["ref_agri_average_yield"] = ref_agri_run["general_metrics"][
"average_agri_yield"
]
df_summary_for_excel.loc["ref_pv_average_energy_per_peak"] = round(
ref_pv_run["general_metrics"]["average_pv_energy"]
/ (simu_config["SolarFarmBifacial"]["panel_peak_power"] / 1000),
2,
)
df_summary_for_excel.loc["PV"] = "- - - - - - - - - - - - - - - - - - - -"
df_summary_for_excel.loc["AGRI"] = "- - - - - - - - - - - - - - - - - - - -"
df_summary_for_excel.loc["AUTRES"] = "- - - - - - - - - - - - - - - - - - - -"
df_summary_for_excel = df_summary_for_excel.loc[
[ff for ff in df_summary_for_excel.index if ff not in ["collected_ac_energy"]]
]
df_summary_for_excel = df_summary_for_excel.reset_index()
df_gstd_blocks = generate_df_gstd_block(run, df_temporal_analysis = df_temporal_analysis, dict_ref_agri_run = ref_agri_run)
description = {
"PV": " - - - - - - - - - - - - - - - - - - - - - -",
"normalized_collected_ac_energy": "Rendement agricole du run / Rendement agricole du run de reference (en %)",
"collected_ac_energy_per_meter2": "Energie totale recoltee pour un metre carre de surface pv (en KWh / m2)",
"collected_ac_energy_per_peak_power": "Energie totale recoltee divisee par la puissance crete du panneau (en kWh/kW-Crete)",
"ref_pv_average_energy_per_peak": "REFERENCE PV : Energie AC recoltee pour un panneau avec une strategie full-backtracking (en kWh/kW-Crete)",
"AGRI": " - - - - - - - - - - - - - - - - - - - - - -",
"agri_average_yield": "Rendement moyen agricole (en Tonnes/Hectare)",
"normalized_agri_average_yield": "Rendement agricole du run / Rendement agricole du run de reference (en %)",
"ref_agri_average_yield": "REFERENCE AGRI : Rendement agricole de la simulation de reference (sans panneaux PV) (en Tonnes/Hectare)",
"AUTRES": " - - - - - - - - - - - - - - - - - - - - - -",
"run_duration": "Duree totale du run (= duree DSSAT la plus longue sur toutes les rangees) (en jours)",
"nb_block_anti-tracking": "Nombre de semaines avec une strategie d'anti-tracking pour le panneau (en nombre de semaines)",
}
df_description = pd.Series(description).to_frame().reset_index()
df_merged = df_description.merge(df_summary_for_excel, how="outer", on="index")
right_order = list(description.keys())
df_merged = df_merged.rename(
columns={"index": "Nom de la variable", "0_x": "Description", "0_y": "Valeur"}
)
df_merged = df_merged.set_index("Nom de la variable").loc[right_order].reset_index()
df_hourly_tracker_angle = run['df_hourly_orientation_planning']
df_hourly_tracker_angle.fillna(0, inplace=True)
df_hourly_tracker_angle_for_excel = df_hourly_tracker_angle.copy()
df_hourly_tracker_angle_for_excel['REF_BACKTRACKING_tracker_theta'] = ref_pv_run['df_hourly_orientation_planning']['tracker_theta']
df_hourly_tracker_angle_for_excel.index = df_hourly_tracker_angle_for_excel.index.strftime('%Y-%m-%dT%H:%M:%S')
wb = Workbook()
sheet1 = wb.active
sheet1.title = "RECAP"
for r in dataframe_to_rows(df_merged, index=True, header=True):
sheet1.append(r)
sheet2 = wb.create_sheet("ANALYSE_SPATIALE")
for r in dataframe_to_rows(df_spatial_analysis, index=True, header=True):
sheet2.append(r)
sheet3 = wb.create_sheet("ANALYSE_TEMPORELLE")
for r in dataframe_to_rows(df_temporal_analysis, index=True, header=True):
sheet3.append(r)
sheet4 = wb.create_sheet("PRODUCTION_ELECTRIQUE")
for r in dataframe_to_rows(df_block_temporal_analysis_for_excel, index=False, header=True):
sheet4.append(r)
sheet5 = wb.create_sheet("ANGLE DU TRACKER")
for r in dataframe_to_rows(df_hourly_tracker_angle_for_excel, index=True, header=True):
sheet5.append(r)
sheet6 = wb.create_sheet("GSTD BLOCKS")
for r in dataframe_to_rows(df_gstd_blocks, index=True, header=True):
sheet6.append(r)
excel_file = io.BytesIO()
wb.save(excel_file)
excel_file.seek(0)
return (
excel_file,
df_summary,
df_temporal_analysis,
df_spatial_analysis,
df_block_temporal_analysis,
df_hourly_tracker_angle
)