import panel as pn import pandas as pd import os from consts import INVERTER_ID_MAPPING, TEMPERATURE_COLUMNS_TO_USE, CURRENT, IRRADIANCE, VOLTAGE, POWER_DC, POWER_AC, T_AMBIENT, T_MODULE, T_HEATSINK, T_CPU, T_BOARD from plotting import ( create_heatmap, create_iv_plot_with_power_curves, create_iv_plot, create_iv_plot_with_power_and_temperature_curves, create_iv_plot_with_temperature_curves, ) # Function to load chunked data based on month selection def load_timeseries_data_for_month(month): start_date = pd.to_datetime(month).strftime('%Y-%m-01') end_date = (pd.to_datetime(month) + pd.offsets.MonthEnd()).strftime('%Y-%m-%d') file_name = f"enel_timeseries_data_{start_date}_{end_date}.csv" if not os.path.exists(file_name): return None return pd.read_csv(file_name, index_col=0, header=[0, 1, 2], parse_dates=True) def load_other_features_data_for_month(month): start_date = pd.to_datetime(month).strftime('%Y-%m-01') end_date = (pd.to_datetime(month) + pd.offsets.MonthEnd()).strftime('%Y-%m-%d') file_name = f"enel_other_features_data_{start_date}_{end_date}.csv" if not os.path.exists(file_name): return None return pd.read_csv(file_name, index_col=0, header=0, parse_dates=True) # Define the available months months = pd.date_range(start='2022-09-01', end='2023-08-31', freq='MS').strftime('%Y-%m').tolist() kpi_data = pd.read_csv( r"kpi_data.csv", index_col=0, header=0, parse_dates=True ) daily_timeseries_data = pd.read_csv( r"daily_aggregated_timeseries_data.csv", index_col=0, header=0, parse_dates=True, ) # Initialize Panel extension pn.extension("plotly") # Widgets for selecting month and columns month_selector = pn.widgets.Select( name='Choose a Month', options=months, ) inverter_ids = pn.widgets.MultiSelect( name="Inverter IDs", value=[list(INVERTER_ID_MAPPING.keys())[0]], options=list(INVERTER_ID_MAPPING.keys()), size=8, ) # Line Plots plot_power_curves = pn.widgets.Checkbox(name="Plot P-dc and P-ac", value=False) plot_temperature_curves = pn.widgets.Checkbox(name="Plot Temperatures", value=False) # Heatmaps heatmap_pr = pn.widgets.Checkbox(name="Heat Map PR", value=False) heatmap_sy = pn.widgets.Checkbox(name="Heat Map SY", value=False) heatmap_current = pn.widgets.Checkbox(name="Heat Map - Current", value=False) heatmap_voltage = pn.widgets.Checkbox(name="Heat Map - Voltage", value=False) heatmap_power = pn.widgets.Checkbox(name="Heat Map - Power", value=False) heatmap_irradiance = pn.widgets.Checkbox(name="Heat Map - Irradiance", value=False) heatmap_temperature = pn.widgets.Checkbox( name="Heat Map - Temperature Heatsink", value=False ) # Create a loading spinner loading_spinner = pn.indicators.LoadingSpinner(width=50, height=50) # Global variables to store loaded data loaded_timeseries_data = None loaded_other_features_data = None loaded_month = None # Panel interactive functions @pn.depends( month_selector.param.value, inverter_ids.param.value, plot_power_curves.param.value, plot_temperature_curves.param.value ) def update_iv_plot(inverter_ids, plot_power_curves, plot_temperature_curves, selected_month): global loaded_timeseries_data, loaded_other_features_data, loaded_month if not selected_month: return pn.pane.Markdown("Please select a month to load data.") if loaded_month != selected_month: loaded_timeseries_data = load_timeseries_data_for_month(selected_month) loaded_other_features_data = load_other_features_data_for_month(selected_month) loaded_month = selected_month if loaded_timeseries_data is None or loaded_other_features_data is None: return pn.pane.Markdown("No data available for the selected month.") if not inverter_ids: return pn.pane.Markdown("No Inverters selected for Plotting.") else: # Plot IV + Power + Temperature Curves if plot_power_curves and plot_temperature_curves: return create_iv_plot_with_power_and_temperature_curves( loaded_timeseries_data, loaded_other_features_data, inverter_ids ) # Plot IV + Temperature Curves elif (not plot_power_curves) and plot_temperature_curves: return create_iv_plot_with_temperature_curves( loaded_timeseries_data, loaded_other_features_data, inverter_ids ) # Plot IV + Power Curves elif plot_power_curves and (not plot_temperature_curves): return create_iv_plot_with_power_curves(loaded_timeseries_data, inverter_ids) # Plot only IV Curves else: return create_iv_plot(loaded_timeseries_data, inverter_ids) @pn.depends(heatmap_pr.param.value) def update_heatmap_pr(heatmap_pr): if heatmap_pr: pr_df = kpi_data.filter(like="pr") pr_df.columns = [i.split("-")[1] for i in pr_df.columns] pr_heatmap = create_heatmap(pr_df, "PR Heatmap") return pn.Row(pr_heatmap) return pn.pane.Markdown("") @pn.depends(heatmap_sy.param.value) def update_heatmap_sy(heatmap_sy): if heatmap_sy: sy_df = kpi_data.filter(like="daily_specific_yield") sy_df.columns = [i.split("-")[1] for i in sy_df.columns] sy_heatmap = create_heatmap(sy_df, "SY Heatmap") return pn.Row(sy_heatmap) return pn.pane.Markdown("") @pn.depends(heatmap_current.param.value) def update_heatmap_current(heatmap_current): if heatmap_current: current_df = daily_timeseries_data.filter(like="I") current_df.columns = [i.split("-")[1] for i in current_df.columns] current_heatmap = create_heatmap(current_df, "Current Heatmap") return pn.Row(current_heatmap) return pn.pane.Markdown("") @pn.depends(heatmap_voltage.param.value) def update_heatmap_voltage(heatmap_voltage): if heatmap_voltage: voltage_df = daily_timeseries_data.filter(like="V") voltage_df.columns = [i.split("-")[1] for i in voltage_df.columns] voltage_heatmap = create_heatmap(voltage_df, "Voltage Heatmap") return pn.Row(voltage_heatmap) return pn.pane.Markdown("") @pn.depends(heatmap_power.param.value) def update_heatmap_power(heatmap_power): if heatmap_power: power_df = daily_timeseries_data.filter(like="P") power_df.columns = [i.split("-")[1] for i in power_df.columns] power_heatmap = create_heatmap(power_df, "Power Heatmap") return pn.Row(power_heatmap) return pn.pane.Markdown("") @pn.depends(heatmap_irradiance.param.value) def update_heatmap_irradiance(heatmap_irradiance): if heatmap_irradiance: irradiance_df = daily_timeseries_data.filter(like="G") irradiance_df.columns = [i.split("-")[1] for i in irradiance_df.columns] irradiance_heatmap = create_heatmap(irradiance_df, "Irradiance Heatmap") return pn.Row(irradiance_heatmap) return pn.pane.Markdown("") @pn.depends(heatmap_temperature.param.value) def update_heatmap_temperature(heatmap_temperature): if heatmap_temperature: temp_df = daily_timeseries_data.filter(like="THeatSink") temp_df.columns = [i.split("-")[1] for i in temp_df.columns] temp_heatmap = create_heatmap(temp_df, "T-Heatsink Heatmap") return pn.Row(temp_heatmap) return pn.pane.Markdown("") # Create dashboard layout dashboard = pn.Column( "# ENEL Dashboard", month_selector, # IV Plots pn.Row( pn.Column(inverter_ids, plot_power_curves, plot_temperature_curves), pn.panel(update_iv_plot, sizing_mode="stretch_width"), ), # Heatmaps pn.Row( pn.Column(heatmap_pr), pn.panel(update_heatmap_pr, sizing_mode="stretch_width") ), pn.Row( pn.Column(heatmap_sy), pn.panel(update_heatmap_sy, sizing_mode="stretch_width") ), pn.Row( pn.Column(heatmap_current), pn.panel(update_heatmap_current, sizing_mode="stretch_width"), ), pn.Row( pn.Column(heatmap_voltage), pn.panel(update_heatmap_voltage, sizing_mode="stretch_width"), ), pn.Row( pn.Column(heatmap_power), pn.panel(update_heatmap_power, sizing_mode="stretch_width"), ), pn.Row( pn.Column(heatmap_irradiance), pn.panel(update_heatmap_irradiance, sizing_mode="stretch_width"), ), pn.Row( pn.Column(heatmap_temperature), pn.panel(update_heatmap_temperature, sizing_mode="stretch_width"), ), ) # Serve the dashboard dashboard.servable()