|
| 1 | +# custom_timeseries_table_config.py |
| 2 | +from reoptjl.timeseries_table_helpers import safe_get_list, safe_get_value, safe_get |
| 3 | + |
| 4 | +""" |
| 5 | +Timeseries Table Configuration |
| 6 | +=============================== |
| 7 | +This file defines configurations for timeseries Excel tables that display hourly or sub-hourly data. |
| 8 | +Each configuration specifies which columns to include and how to extract the data. |
| 9 | +
|
| 10 | +Naming Convention: |
| 11 | +------------------ |
| 12 | +Structure: custom_timeseries_<feature> |
| 13 | +
|
| 14 | +- `custom_timeseries_`: Prefix indicating a timeseries table configuration |
| 15 | +- `<feature>`: Descriptive name for the specific timeseries configuration |
| 16 | +
|
| 17 | +Examples: |
| 18 | +- custom_timeseries_energy_demand: Configuration for energy and demand rate timeseries |
| 19 | +- custom_timeseries_emissions: Configuration for emissions timeseries |
| 20 | +- custom_timeseries_loads: Configuration for load profiles |
| 21 | +
|
| 22 | +Guidelines: |
| 23 | +- Use lowercase letters and underscores |
| 24 | +- Keep names descriptive and concise |
| 25 | +- Each configuration is a list of column dictionaries |
| 26 | +
|
| 27 | +Column Dictionary Structure: |
| 28 | +----------------------------- |
| 29 | +Each column configuration should have: |
| 30 | +{ |
| 31 | + "label": str, # Column header text |
| 32 | + "key": str, # Unique identifier for the column |
| 33 | + "timeseries_path": str, # Dot-separated path to data in the results JSON (e.g., "outputs.ElectricLoad.load_series_kw") |
| 34 | + "is_base_column": bool, # True if column comes from first scenario only, False if repeated for all scenarios |
| 35 | + "units": str # Optional: Units to display in header (e.g., "($/kWh)", "(kW)") |
| 36 | +} |
| 37 | +
|
| 38 | +Note: Formatting (Excel number formats, column widths, colors) is handled in views.py, not in this configuration file. |
| 39 | +
|
| 40 | +Special Column Types: |
| 41 | +--------------------- |
| 42 | +1. DateTime column: Must have key="datetime" and will be auto-generated based on year and time_steps_per_hour |
| 43 | +2. Base columns: Set is_base_column=True for columns that only use data from the first run_uuid |
| 44 | +3. Scenario columns: Set is_base_column=False for columns that repeat for each run_uuid |
| 45 | +
|
| 46 | +Rate Name Headers: |
| 47 | +------------------ |
| 48 | +For scenario columns (is_base_column=False), the column header will automatically include the rate name |
| 49 | +from inputs.ElectricTariff.urdb_metadata.rate_name for each scenario. |
| 50 | +""" |
| 51 | + |
| 52 | +# Configuration for energy and demand rate timeseries |
| 53 | +# This configuration specifies which data fields to extract from the results. |
| 54 | +# Formatting (number formats, colors, widths) is handled in views.py |
| 55 | +custom_timeseries_energy_demand = [ |
| 56 | + { |
| 57 | + "label": "Date Timestep", |
| 58 | + "key": "datetime", |
| 59 | + "timeseries_path": lambda df: safe_get(df, "inputs.ElectricLoad.year"), # Used to generate datetime column based on year and time_steps_per_hour |
| 60 | + "is_base_column": True |
| 61 | + }, |
| 62 | + { |
| 63 | + "label": "Load (kW)", |
| 64 | + "key": "load_kw", |
| 65 | + "timeseries_path": lambda df: safe_get(df, "outputs.ElectricLoad.load_series_kw"), |
| 66 | + "is_base_column": True |
| 67 | + }, |
| 68 | + { |
| 69 | + "label": "Peak Monthly Load (kW)", |
| 70 | + "key": "peak_monthly_load_kw", |
| 71 | + "timeseries_path": lambda df: safe_get(df, "outputs.ElectricLoad.monthly_peaks_kw"), # 12-element array, needs special handling to repeat for each timestep |
| 72 | + "is_base_column": True |
| 73 | + }, |
| 74 | + { |
| 75 | + "label": "Energy Charge", |
| 76 | + "key": "energy_charge", |
| 77 | + "timeseries_path": lambda df: safe_get(df, "outputs.ElectricTariff.energy_rate_average_series"), |
| 78 | + "is_base_column": False, # Repeats for each scenario |
| 79 | + "units": "($/kWh)" |
| 80 | + }, |
| 81 | + { |
| 82 | + "label": "Demand Charge", |
| 83 | + "key": "demand_charge", |
| 84 | + "timeseries_path": lambda df: safe_get(df, "outputs.ElectricTariff.demand_rate_average_series"), |
| 85 | + "is_base_column": False, # Repeats for each scenario |
| 86 | + "units": "($/kW)" |
| 87 | + } |
| 88 | +] |
| 89 | + |
| 90 | +# Example configuration for emissions timeseries (can be expanded as needed) |
| 91 | +custom_timeseries_emissions = [ |
| 92 | + { |
| 93 | + "label": "Date Timestep", |
| 94 | + "key": "datetime", |
| 95 | + "timeseries_path": lambda df: safe_get(df, "inputs.ElectricLoad.year"), |
| 96 | + "is_base_column": True |
| 97 | + }, |
| 98 | + { |
| 99 | + "label": "Grid Emissions", |
| 100 | + "key": "grid_emissions", |
| 101 | + "timeseries_path": lambda df: safe_get(df, "inputs.ElectricUtility.emissions_factor_series_lb_CO2_per_kwh"), |
| 102 | + "is_base_column": True, |
| 103 | + "units": "(lb CO2/kWh)" |
| 104 | + }, |
| 105 | + { |
| 106 | + "label": "Grid Energy", |
| 107 | + "key": "grid_to_load", |
| 108 | + "timeseries_path": lambda df: safe_get(df, "outputs.ElectricUtility.electric_to_load_series_kw"), |
| 109 | + "is_base_column": False, |
| 110 | + "units": "(kWh)" |
| 111 | + } |
| 112 | +] |
| 113 | + |
| 114 | +# Example configuration for load profiles (can be expanded as needed) |
| 115 | +custom_timeseries_loads = [ |
| 116 | + { |
| 117 | + "label": "Date Timestep", |
| 118 | + "key": "datetime", |
| 119 | + "timeseries_path": lambda df: safe_get(df, "inputs.ElectricLoad.year"), |
| 120 | + "is_base_column": True |
| 121 | + }, |
| 122 | + { |
| 123 | + "label": "Total Load", |
| 124 | + "key": "total_load", |
| 125 | + "timeseries_path": lambda df: safe_get(df, "outputs.ElectricLoad.load_series_kw"), |
| 126 | + "is_base_column": True, |
| 127 | + "units": "(kW)" |
| 128 | + }, |
| 129 | + { |
| 130 | + "label": "Critical Load", |
| 131 | + "key": "critical_load", |
| 132 | + "timeseries_path": lambda df: safe_get(df, "outputs.ElectricLoad.critical_load_series_kw"), |
| 133 | + "is_base_column": True, |
| 134 | + "units": "(kW)" |
| 135 | + } |
| 136 | +] |
0 commit comments