Spaces:
Runtime error
Runtime error
| 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"] | |
| ) | |
| 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 | |
| ) | |