akono-app-v4 / callbacks /tab_chargedécharge_callbacks.py
mzufferey
0610
1a02e7a
import sys
import pandas as pd
from dash.dependencies import Input, Output
from matplotlib.pyplot import xlabel
from plotly.subplots import make_subplots
from settings import *
from utils_fcts import *
from app_settings import *
import plotly.express as px
def register_callbacks(app):
############################### ###############################
############################### CALL BACKS STAT tab-stat
############################### ###############################
#
# dayPdata_columns = get_daydata_columns("P")
# dayIdata_columns = get_daydata_columns("I")
# timedata_columns = get_timedata_columns()
# timecols2show = [x for x in timedata_columns if not showcols_settings[x] == "NA"]
# dayPcols2show = [x for x in dayPdata_columns if not x == db_daycol]
# dayIcols2show = [x for x in dayIdata_columns if not x == db_daycol]
timecols2show = list(showcols_settings.keys())#x for x in timedata_columns if not showcols_settings[x] == "NA"]
dayIcols2show = list(dayIcols_settings.keys())#[x for x in dayIdata_columns if not x == db_daycol]
######################################################################
# graphes BSP
######################################################################
@app.callback(
[Output('subtab-bsp-content', 'children'),
Output('confirm-dialog-subbsp', 'displayed'),
Output('confirm-dialog-subbsp', 'message'),
Output('subbsp-range-info', 'children')],
[Input('show-bsp-btn', 'n_clicks')],
[
State('range-picker-stat', 'start_date'),
State('range-picker-stat', 'end_date'),
State('statperiod-dropdown', 'value'),
State('stored_timeDB', 'data'),
State('stored_dayDB', 'data')
]
)
def display_bsp_graph(n_clicks,start_date, end_date, selected_period, time_db, day_db):
selected_db = dbTime_name
selected_col = "FOO"
# df = pd.DataFrame(time_db)
dayI_df = pd.DataFrame(day_db)
dayI_df = dayI_df.sort_values(by=db_daycol)
if n_clicks is None or n_clicks == 0:
return ["", False, "", ""]
if not selected_db or not selected_col :
return [ "", True, "Sélectionnez des données", ""]
if selected_period == "stat_perso" and (not start_date or not end_date):
return ["", True, "Sélectionnez une période", ""]
if selected_period == "stat_perso":
start_date = datetime.strptime(start_date, '%Y-%m-%d').date()
end_date = datetime.strptime(end_date, '%Y-%m-%d').date()
else:
#start_date, end_date = get_startrange_date_vLatest(df[db_timecol], selected_period)
start_date, end_date = get_startrange_date_vLatest(dayI_df[db_daycol], selected_period)
date_info = f"Zoom sur les données du {start_date} au {end_date}"
# if selected_db == dbTime_name:
# xcol = db_timecol
# else:
# xcol = db_daycol
# if selected_db == dbDayI_name:
# for col in dayI_cols:
# df[col] = df[col + "_1"].fillna(0) + df[col + "_2"].fillna(0)
div_container = []
# df = df.sort_values(by=xcol)
#dayI_df = pd.DataFrame(day_db)
#start_date, end_date = get_startrange_date_vLatest(dayI_df[db_daycol], selected_period)
#dayI_df = dayI_df.sort_values(by=db_daycol)
## le "throughput energy" journalier I7007 [AH] BSP
# Le bilan des Ah chargé et déchargé du jour I7008-I7007 BSP
# Pour la Batterie : champs fixe sans lien avec le segment temporel affiché
# le "throughput energy" total: Somme I7007 [AH] BSP
# Rendement de batterie:( I7008/I7007) *100 BSP
# Nombre de cycle (à 50%) tot I7007/90 arrondi 0BSP
IvarBSP = [x for x in dayIcols_settings.keys() if
dayIcols_settings[x]["source"] == "BSP" and
x in dayI_df.columns ]
### I7007 et I7008 ; seulement valeur dans colonne 1
emptycols = [x for x in IvarBSP if "_2" in x]
assert dayI_df[emptycols].isna().all().all()
IvarBSP_toplot = [x for x in IvarBSP if "_1" in x]
assert len(IvarBSP_toplot) == 2
dayI_df = dayI_df[[db_daycol]+IvarBSP_toplot]
## grpahe 5 différence entre 7007 et 7008
# Calcul des zones colorées
df=dayI_df.copy()
df['day'] = pd.to_datetime(df['day'])
df.set_index('day', inplace=True)
#df.to_pickle('df_charge_décharge.pkl')
# print("db_daycol = " + db_daycol)
# print("start_date = " + str(start_date))
# print("end_date = " + str(end_date))
# print("IvarBSP_toplot[0] = " + IvarBSP_toplot[0])
# print("IvarBSP_toplot[1] = " + IvarBSP_toplot[1])
plot5 = get_intersectLines_plot(df, db_daycol,
col1=IvarBSP_toplot[0],
col2=IvarBSP_toplot[1],
startDate= start_date, endDate=end_date)
plot5.update_layout(
yaxis_title='Ah chargés/déchargés'
)
div_container.append(dcc.Graph(id = "ivarbsp_intersectarea",
figure=plot5,config= {
'scrollZoom': True # Activer le zoom avec la molette
}))
plot5_desc = get_plotdesc(IvarBSP_toplot[0], col2=IvarBSP_toplot[1], db=dbDayI_name)
div_container.append(dcc.Markdown(plot5_desc,
dangerously_allow_html=True))
df = dayI_df.copy()
plot6 = get_stacked_cmpgraph(df, db_daycol, IvarBSP_toplot[0],IvarBSP_toplot[1],
settingsdict=dayIcols_settings,
startDate = start_date, endDate = end_date)
plot6[0].update_layout(
yaxis_title='Ah chargé/déchargé'
)
fig6 = plot6[0]
fig6.update_layout(
title = "Bilan des Ah chargés et déchargés " +
f'(<b>{IvarBSP_toplot[0]}</b> et <b>{IvarBSP_toplot[1]}</b>)',
yaxis_title="Ah chargés/déchargés"
)
div_container.append(dcc.Graph(id='ivarbsp_area', figure=fig6,config= {
'scrollZoom': True # Activer le zoom avec la molette
}))
div_container.append(dcc.Markdown(plot6[1],
dangerously_allow_html=True))
# # Rendement de batterie:( I7008/I7007) *100 BSP
df=dayI_df.copy()
df['delta'] = df["I7008_1"] - df["I7007_1"]
df['rendement'] = (df["I7008_1"] / df["I7007_1"]) * 100
df['rendement_pos'] = df['rendement'] - 100
df['rendement_neg'] = df['rendement'] - 100
# Créer les sous-graphiques
figRel = make_subplots(rows=2, cols=1, shared_xaxes=True,
subplot_titles=("Delta", "Rendement"))
# Tracer 'delta' (graphique du haut)
figRel.add_trace(go.Scatter(x=df.index, y=df['delta'],
mode='lines', name='Delta',
line=dict(color='black')), row=1, col=1)
# Ajouter les zones de fond pour 'delta'
figRel.add_shape(type="rect", xref="x", yref="y",
x0=df.index.min(), y0=0, x1=df.index.max(), y1=df['delta'].max(),
fillcolor="rgba(255, 0, 0, 0.2)", layer="below", row=1, col=1)
figRel.add_shape(type="rect", xref="x", yref="y",
x0=df.index.min(), y0=df['delta'].min(), x1=df.index.max(), y1=0,
fillcolor="rgba(0, 0, 255, 0.2)", layer="below", row=1, col=1)
# Tracer les barres de 'rendement' (graphique du bas)
figRel.add_trace(go.Bar(x=df.index, y=np.where(df['rendement'] >= 100, df['rendement_pos'], 0),
name='Rendement > 100', marker=dict(color='red')), row=2, col=1)
figRel.add_trace(go.Bar(x=df.index, y=np.where(df['rendement'] < 100, df['rendement_neg'], 0),
name='Rendement < 100', marker=dict(color='blue')), row=2, col=1)
# Mise à jour de la mise en page
figRel.update_layout(
title_text="<b>Delta (I7008_1-I7007_1) et Rendement (100*I7008_1/I7007_1)</b>",
height=1000,
xaxis=dict(title=''),#db_daycol.title()),
yaxis=dict(title='Delta', zerolinecolor='gray'),
yaxis2=dict(title='Rendement', zerolinecolor='gray', zerolinewidth=2),
barmode='overlay' # Superposer les barres
)
figRel.update_xaxes(range=[start_date, end_date])
figRel_desc = get_plotdesc("I7007_1" ,"I7008_1",db=dbDayI_name)
# Ajouter le graphique à l'application Dash
div_container.append(dcc.Graph(id='ivarbsp_rendement', figure=figRel,config= {
'scrollZoom': True # Activer le zoom avec la molette
}))
div_container.append(dcc.Markdown(figRel_desc,
dangerously_allow_html=True))
# Nombre de cycle (à 50%) tot I7007/90 arrondi 0BSP
# update : c'est juste une valeur
nCyclesText = "<h4>Nombre de cycles à 50%</h4>"
nCyclesText += "( = somme I7007_1/90) "
df=dayI_df.copy()
nCycles = round(sum(df["I7007_1"])/90)
nCyclesText += "<h3># cycles = "+ str(nCycles) + "</h3>"
div_container.append(dcc.Markdown(nCyclesText,
dangerously_allow_html=True))
# df['cycles'] = round(df["I7007_1"]/90)
#
# figCycles = go.Figure()
#
# figCycles.add_trace(go.Bar(x=df[db_daycol], y=df['cycles'],
# name='Cycles', marker=dict(color='darkblue')))
#
# figCycles.update_layout(
# title="<b>Nombre de cycles à 50% I7007_1/90</b>",
# title_font=dict(size=20),
# xaxis_title=db_daycol.title(),
# yaxis_title="I7007_1/90")
#
# figCycles.update_xaxes(range=[start_date, end_date])
#
#
# figCycles_desc = get_plotdesc("I7007_1" ,db=dbDayI_name)
# # Ajouter le graphique à l'application Dash
# div_container.append(dcc.Graph(id='ivarbsp_nbcycles', figure=figCycles,config= {
# 'scrollZoom': True # Activer le zoom avec la molette
# }))
# div_container.append(dcc.Markdown(figCycles_desc,
# dangerously_allow_html=True))
df = pd.DataFrame(time_db)
df = df.sort_values(by=db_timecol)
df_day = df[(pd.to_datetime(df[db_timecol]).dt.time >=
datetime.strptime("08:00", "%H:%M").time()) &
(pd.to_datetime(df[db_timecol]).dt.time <
datetime.strptime("18:00", "%H:%M").time())]
df_night = df[(pd.to_datetime(df[db_timecol]).dt.time >=
datetime.strptime("18:00", "%H:%M").time()) |
(pd.to_datetime(df[db_timecol]).dt.time <
datetime.strptime("08:00", "%H:%M").time())]
barplot_data = pd.DataFrame({
'Période': ['Global', 'Jour', 'Nuit'],
'Moyenne Temp': [df[tempTbatcol].mean(),
df_day[tempTbatcol].mean(),
df_night[tempTbatcol].mean()]
})
fig_barplot = px.bar(barplot_data, x='Période', y='Moyenne Temp', title='Moyenne de TempTbatcol')
fig_barplot.update_xaxes(range=[start_date, end_date])
div_container.append(dcc.Markdown("<h3>Température batterie</h3>",
dangerously_allow_html=True))
div_container.append(dcc.Graph(id='ivarbsp_tmpbat', figure=fig_barplot,config= {
'scrollZoom': True # Activer le zoom avec la molette
}))
return [div_container, False, "", date_info]