diff --git a/pyproject.toml b/pyproject.toml index bfd310a..f58aec0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,6 +64,7 @@ extra-dependencies = [ "nbsphinx", "taipy", "streamlit", + ] [tool.hatch.envs.docs.scripts] build = "sphinx-build -b html doc/ doc/_build" @@ -71,10 +72,11 @@ build = "sphinx-build -b html doc/ doc/_build" [tool.hatch.envs.serve] extra-dependencies = [ "streamlit", + "streamlit-analytics2", ] [tool.hatch.envs.serve.scripts] -prod = "streamlit run --server.port 8502 --server.baseUrlPath energy_forecast src/energy_forecast/dashboard/dashboard_streamlit.py" +prod = "streamlit run --server.port 8502 --server.baseUrlPath energy_forecast src/energy_forecast/dashboard/Accueil.py" [tool.coverage.run] source_pkgs = ["energy_forecast", "tests"] diff --git a/src/energy_forecast/dashboard/Accueil.py b/src/energy_forecast/dashboard/Accueil.py new file mode 100644 index 0000000..85cbe08 --- /dev/null +++ b/src/energy_forecast/dashboard/Accueil.py @@ -0,0 +1,21 @@ +import streamlit as st + +if __name__ == "__main__": + st.set_page_config( + page_title="Prévision ENR", + page_icon="🌞", + ) + + st.markdown("""# Bienvenue dans Energy Forecast! 🌞 +Cette application est une démonstration d'un tableau de bord de prévision énergétique simple. + +Il est divisé en trois sections: + +- Prévision météo +- Prévision énergétique +- Prévision de consommation +- Prédiction Tempo +""" + , unsafe_allow_html=True) + + st.sidebar.success("Sélectionnez une démo ci-dessus.") \ No newline at end of file diff --git a/src/energy_forecast/dashboard/dashboard_streamlit.py b/src/energy_forecast/dashboard/dashboard_streamlit.py deleted file mode 100644 index 30f54bb..0000000 --- a/src/energy_forecast/dashboard/dashboard_streamlit.py +++ /dev/null @@ -1,21 +0,0 @@ -import streamlit as st - -if __name__ == "__main__": - st.set_page_config( - page_title="ENR Forecast", - page_icon="🌞", - ) - - st.markdown("""# Welcome to Energy Forecast! 🌞 -This App is a demo of a simple energy forecast dashboard. - -It is divided into three sections: - -- Weather Forecast -- Energy Forecast -- Consumption Forecast -- Prediction Tempo -""" - , unsafe_allow_html=True) - - st.sidebar.success("Select a demo above.") \ No newline at end of file diff --git a/src/energy_forecast/dashboard/pages/1_weather.py "b/src/energy_forecast/dashboard/pages/1_M\303\251t\303\251o.py" similarity index 82% rename from src/energy_forecast/dashboard/pages/1_weather.py rename to "src/energy_forecast/dashboard/pages/1_M\303\251t\303\251o.py" index 1bd83cd..f141e2a 100644 --- a/src/energy_forecast/dashboard/pages/1_weather.py +++ "b/src/energy_forecast/dashboard/pages/1_M\303\251t\303\251o.py" @@ -3,6 +3,7 @@ import pandas as pd import streamlit as st import altair as alt +alt.renderers.set_embed_options(time_format_locale="fr-FR", format_locale="fr-FR") @memory.cache @@ -91,23 +92,27 @@ def compute_data_wind(date: str)->pd.DataFrame: return data if __name__ == "__main__": + st.title("Prévision meteo") + st.markdown("Cette page affiche les prévisions météorologiques pour les prochains jours." + " Les données sont obtenues à partir de [Météo France](https://www.meteofrance.com/).") date = pd.Timestamp.now().strftime("%Y-%m-%d") wind_data = compute_data_wind(date) + wind_barplot = alt.Chart(wind_data).mark_bar().encode( - y="wind_speed", - x="time" - ) + y=alt.Y("wind_speed:Q").title("Vitesse du vent (m/s)"), + x=alt.X("time:T").title("Date") + ).properties(title="Vitesse moyenne du vent en France.") st.altair_chart(wind_barplot, use_container_width=True ) sun_data = compute_data_sun(date) sun_barplot = alt.Chart(sun_data).mark_bar().encode( - y="sun_flux", - x="time" - ) + y=alt.Y("sun_flux:Q").title("Flux solaire (W/m^2)"), + x=alt.X("time:T").title("Date") + ).properties(title="Flux solaire moyen en France.") st.altair_chart(sun_barplot, use_container_width=True ) \ No newline at end of file diff --git a/src/energy_forecast/dashboard/pages/2_power_generation.py b/src/energy_forecast/dashboard/pages/2_Production.py similarity index 77% rename from src/energy_forecast/dashboard/pages/2_power_generation.py rename to src/energy_forecast/dashboard/pages/2_Production.py index 116e3d4..0898b99 100644 --- a/src/energy_forecast/dashboard/pages/2_power_generation.py +++ b/src/energy_forecast/dashboard/pages/2_Production.py @@ -9,6 +9,8 @@ import pandas as pd import streamlit as st import altair as alt +alt.renderers.set_embed_options(time_format_locale="fr-FR", format_locale="fr-FR") + @memory.cache def compute_data_pv_power(date: str)->pd.DataFrame: @@ -110,6 +112,7 @@ def compute_energy(date:str): energy = r.read_file() energy = energy[["Eolien", "Solaire"]] + energy.rename(columns={"Eolien": "Eolien Production", "Solaire": "PV Production"}, inplace=True) offset_days = 5 history_start = pd.Timestamp(date) - pd.Timedelta(f"{offset_days} days") energy = energy[history_start:] @@ -132,29 +135,34 @@ def compute_energy(date:str): energy = energy[energy["time"].dt.minute == 0] st.title("Prévision de production ENR") + st.markdown("Cette page affiche les prévisions de production d'énergie renouvelable pour la date sélectionnée." + " Les données sont obtenues à partir de [RTE](https://www.rte-france.com/eco2mix/la-production-delectricite-en-temps-reel).") + + + energy_long = energy.melt(id_vars="time", var_name="source", value_name="power") + eolen_long = energy_long[energy_long["source"].str.contains("Eolien")] + pv_long = energy_long[energy_long["source"].str.contains("PV")] + + eolen_title = alt.Title("Production Eolien", + subtitle="Production historique et prévisionnelle") - wind_history = alt.Chart(energy).mark_line().encode( - y="Eolien", - x="time" - ).interactive() - wind_prediction = alt.Chart(energy).mark_line(color="red").encode( - y="Eolien Prediction", - x="time" - ).interactive() - wind_barplot = wind_prediction + wind_history - st.altair_chart(wind_barplot, + eolen_chart = alt.Chart(eolen_long, title=eolen_title).mark_line().encode( + x=alt.X("time:T", title="Date"), + y=alt.Y("power:Q", title="Production (MW)"), + color=alt.Color("source:N", title="Type de production"), + ) + + st.altair_chart(eolen_chart, use_container_width=True ) - sun_history = alt.Chart(energy).mark_line().encode( - y="Solaire", - x="time" - ) - sun_prediction = alt.Chart(energy).mark_line(color="red").encode( - y="PV Prediction", - x="time" + sun_title = alt.Title("Production Solaire", + subtitle="Production historique et prévisionnelle") + sun_chart = alt.Chart(pv_long, title=sun_title).mark_line().encode( + x=alt.X("time:T", title="Date"), + y=alt.Y("power:Q", title="Production (MW)"), + color=alt.Color("source:N", title="Type de production"), ) - sun_barplot = sun_prediction + sun_history - st.altair_chart(sun_barplot, + st.altair_chart(sun_chart, use_container_width=True ) \ No newline at end of file diff --git a/src/energy_forecast/dashboard/pages/3_Consomation.py b/src/energy_forecast/dashboard/pages/3_Consomation.py new file mode 100644 index 0000000..cdee93b --- /dev/null +++ b/src/energy_forecast/dashboard/pages/3_Consomation.py @@ -0,0 +1,55 @@ +"""Create a Streamlit page to display the consumption forecast. + +The Consumption forecast is obtained from the :class:`energy_forecast.consumption_forecast.PredictionForecastAPI` class. +It uses RTE predictions. +""" + +from energy_forecast.consumption_forecast import PredictionForecastAPI +from energy_forecast import ROOT_DIR +import pandas as pd +import streamlit as st +import altair as alt +alt.renderers.set_embed_options(time_format_locale="fr-FR", format_locale="fr-FR") + +@st.cache +def get_weekly_forecast(secret: str)->pd.DataFrame: + """Get the weekly forecast for the total electricity consumption. + + Parameters + ---------- + secret : str + The secret key to access the RTE API. + + Returns + ------- + pd.DataFrame + The weekly forecast for the total electricity consumption. + The columns are ["time", "predicted_consumption"] + """ + consumption_forecast_api = PredictionForecastAPI(secret=secret) + consumption_forecast = consumption_forecast_api.get_weekly_forecast( + start_date=pd.Timestamp.now().date() + ).reset_index() + return consumption_forecast + +if __name__ == "__main__": + env_file = ROOT_DIR / ".env" + with env_file.open("r") as f: + secret = f.readline().strip().split("=", 1)[1] + consumption_forecast = get_weekly_forecast(secret) + + + st.title("Prévision de consomation electrique total") + st.markdown("Prévision de consomation electrique total pour la semaine prochaine" + " en utilisant les données de RTE.") + + title = alt.Title("Consomation electrique total prévue", anchor="start", + subtitle="France métropolitaine") + + consumption_chart = alt.Chart(consumption_forecast, title=title).mark_line().encode( + y=alt.Y("predicted_consumption:Q", title="Consomation electrique (MW)"), + x=alt.X("time:T", title="Date") + ) + st.altair_chart(consumption_chart, + use_container_width=True + ) \ No newline at end of file diff --git a/src/energy_forecast/dashboard/pages/3_consumption_prediction.py b/src/energy_forecast/dashboard/pages/3_consumption_prediction.py deleted file mode 100644 index cb8cf28..0000000 --- a/src/energy_forecast/dashboard/pages/3_consumption_prediction.py +++ /dev/null @@ -1,33 +0,0 @@ -"""Create a Streamlit page to display the consumption forecast. - -The Consumption forecast is obtained from the :class:`energy_forecast.consumption_forecast.PredictionForecastAPI` class. -It uses RTE predictions. -""" - -from energy_forecast.consumption_forecast import PredictionForecastAPI -from energy_forecast import ROOT_DIR -import pandas as pd -import streamlit as st -import altair as alt - -if __name__ == "__main__": - env_file = ROOT_DIR / ".env" - with env_file.open("r") as f: - secret = f.readline().strip().split("=", 1)[1] - - consumption_forecast_api = PredictionForecastAPI(secret=secret) - consumption_forecast = consumption_forecast_api.get_weekly_forecast( - start_date=pd.Timestamp.now().date() - ).reset_index() - - st.title("Prévision de consomation electrique total") - - - - consumption_chart = alt.Chart(consumption_forecast).mark_line().encode( - y="predicted_consumption", - x="time" - ).interactive() - st.altair_chart(consumption_chart, - use_container_width=True - ) \ No newline at end of file diff --git a/src/energy_forecast/dashboard/pages/4_prediction_tempo.py b/src/energy_forecast/dashboard/pages/4_Jours_Tempos.py similarity index 89% rename from src/energy_forecast/dashboard/pages/4_prediction_tempo.py rename to src/energy_forecast/dashboard/pages/4_Jours_Tempos.py index ca89dd3..257ebce 100644 --- a/src/energy_forecast/dashboard/pages/4_prediction_tempo.py +++ b/src/energy_forecast/dashboard/pages/4_Jours_Tempos.py @@ -12,6 +12,7 @@ for offset, col in zip(range(3), [col1, col2, col3]): text = f"Prévision pour le {today + pd.Timedelta(days=offset)}" - text += "\n\n

Jour Bleu

" + text += "\n\n

Jour Bleu

\n\n" # an html blue square the size of the column with the text and H1 in white - col.markdown(f"
{text}
", unsafe_allow_html=True) \ No newline at end of file + col.markdown(f"
{text}
\n", unsafe_allow_html=True) + col.markdown("\n") \ No newline at end of file