Skip to content

Commit 971932c

Browse files
committed
Creating the .exe and some refinements in the dashboard
1 parent 38f061e commit 971932c

6 files changed

Lines changed: 140 additions & 57 deletions

File tree

dashboard/pages/home.py

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
"""Home page — project selector."""
22

3+
import shutil
4+
from pathlib import Path
5+
36
import dash_bootstrap_components as dbc
47
from dash import html, dcc, Input, Output, State, callback, no_update, ALL, ctx
8+
59
import data_loader as dl
10+
from config import INPUT_ROOT
611

712

813
def layout(*args):
@@ -37,9 +42,10 @@ def layout(*args):
3742
html.Hr(),
3843

3944
dbc.Row([
40-
dbc.Col(html.H5("Create New Project"), width=12),
45+
# Clone existing project
4146
dbc.Col([
42-
dbc.Label("Clone from existing project"),
47+
html.H5("Clone Existing Project", className="mb-3"),
48+
dbc.Label("Source project"),
4349
dcc.Dropdown(
4450
id="clone-source",
4551
options=[{"label": f, "value": f} for f in folders],
@@ -52,6 +58,25 @@ def layout(*args):
5258
dbc.Button("Create Project", id="clone-btn", color="success"),
5359
html.Div(id="clone-result", className="mt-2"),
5460
], width=4),
61+
62+
dbc.Col(width=1),
63+
64+
# Import from local folder
65+
dbc.Col([
66+
html.H5("Import from Local Folder", className="mb-3"),
67+
dbc.Label("Folder path"),
68+
dbc.InputGroup([
69+
dbc.Input(id="import-path", placeholder="C:\\path\\to\\your\\project",
70+
className="mb-0"),
71+
dbc.Button([html.I(className="bi bi-folder2-open")],
72+
id="import-browse-btn", color="outline-secondary"),
73+
], className="mb-2"),
74+
dbc.Input(id="import-name",
75+
placeholder="Project name in EPM (e.g. data_namibia)",
76+
className="mb-2"),
77+
dbc.Button("Import Project", id="import-btn", color="primary"),
78+
html.Div(id="import-result", className="mt-2"),
79+
], width=4),
5580
]),
5681
])
5782

@@ -90,3 +115,50 @@ def clone_project(n, source, name):
90115
if ok:
91116
return dbc.Alert(f"Project '{name}' created successfully.", color="success")
92117
return dbc.Alert("Failed — folder already exists or source not found.", color="danger")
118+
119+
120+
@callback(
121+
Output("import-path", "value"),
122+
Input("import-browse-btn", "n_clicks"),
123+
prevent_initial_call=True,
124+
)
125+
def browse_folder(n):
126+
if not n:
127+
return no_update
128+
try:
129+
import tkinter as tk
130+
from tkinter import filedialog
131+
root = tk.Tk()
132+
root.withdraw()
133+
root.wm_attributes("-topmost", True)
134+
folder = filedialog.askdirectory(title="Select EPM project folder")
135+
root.destroy()
136+
return folder if folder else no_update
137+
except Exception:
138+
return no_update
139+
140+
141+
@callback(
142+
Output("import-result", "children"),
143+
Input("import-btn", "n_clicks"),
144+
State("import-path", "value"),
145+
State("import-name", "value"),
146+
prevent_initial_call=True,
147+
)
148+
def import_project(n, src_path, name):
149+
if not src_path or not name:
150+
return dbc.Alert("Please select a folder and enter a project name.", color="warning")
151+
name = name.strip()
152+
if not name.startswith("data_"):
153+
name = "data_" + name
154+
src = Path(src_path)
155+
if not src.exists():
156+
return dbc.Alert(f"Folder not found: {src_path}", color="danger")
157+
dest = INPUT_ROOT / name
158+
if dest.exists():
159+
return dbc.Alert(f"Project '{name}' already exists in EPM.", color="warning")
160+
try:
161+
shutil.copytree(str(src), str(dest))
162+
return dbc.Alert(f"Project '{name}' imported successfully.", color="success")
163+
except Exception as e:
164+
return dbc.Alert(f"Import failed: {e}", color="danger")

dashboard/pages/input_manager.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,8 @@ def layout(active_project=None):
324324
return html.Div([
325325
html.H4("Input Manager", className="mb-1"),
326326
html.P("Select a section to view and edit input data.",
327-
className="text-muted mb-4", style={"fontSize": "0.85rem"}),
327+
className="text-muted mb-2", style={"fontSize": "0.85rem"}),
328+
html.Div(id="im-no-project-warning"),
328329

329330
# Section cards
330331
html.Div(
@@ -347,11 +348,17 @@ def layout(active_project=None):
347348
# ---------------------------------------------------------------------------
348349

349350
@callback(
350-
Output("im-section-cards", "children"),
351-
Output("im-file-browser", "children"),
351+
Output("im-section-cards", "children"),
352+
Output("im-file-browser", "children"),
353+
Output("im-no-project-warning", "children"),
352354
Input("store-active-project", "data"),
353355
)
354356
def refresh(folder):
355-
cards = dbc.Row([_section_card(s, folder) for s in SECTIONS], className="g-3")
357+
cards = dbc.Row([_section_card(s, folder) for s in SECTIONS], className="g-3")
356358
browser = _file_browser(folder)
357-
return cards, browser
359+
warning = dbc.Alert(
360+
[html.I(className="bi bi-exclamation-triangle-fill me-2"),
361+
"No project selected — please select a project from the dropdown above before editing."],
362+
color="warning", className="py-2 mb-3", style={"fontSize": "0.85rem"},
363+
) if not folder else None
364+
return cards, browser, warning

epm/input/data_eapp/pSettings.csv

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,71 @@
1-
Parameter,Abbreviation,Value
1+
Parameter,Abbreviation,Value
22
,,
3-
Enable capacity expansion decisions,fEnableCapacityExpansion,1
4-
Activate 8760-hour dispatch chronology,fDispatchMode,0
3+
Enable capacity expansion decisions,fEnableCapacityExpansion,1.0
4+
Activate 8760-hour dispatch chronology,fDispatchMode,0.0
55
,,
66
PARAMETERS,,
77
"Weighted Average Cost of Capital (WACC), %",WACC,0.06
88
"Discount rate, %",DR,0.06
9-
"Cost of unserved energy per MWh, $",VoLL,1000
10-
"Cost of reserve shortfall per MW, $",ReserveVoLL,60000
11-
"Spin Reserve vOLL per MWh, $",SpinReserveVoLL,60
12-
"Cost of surplus power per MWh, $",CostSurplus,5
13-
"Cost of curtailment per MWh, $",CostCurtail,0
14-
"Cost of curtailment per MWh, $",CO2backstop,300
15-
"Cost of Climate backstop techno per ton CO2, $",H2UnservedCost,3000
9+
"Cost of unserved energy per MWh, $",VoLL,1000.0
10+
"Cost of reserve shortfall per MW, $",ReserveVoLL,60000.0
11+
"Spin Reserve vOLL per MWh, $",SpinReserveVoLL,60.0
12+
"Cost of surplus power per MWh, $",CostSurplus,5.0
13+
"Cost of curtailment per MWh, $",CostCurtail,0.0
14+
"Cost of curtailment per MWh, $",CO2backstop,300.0
15+
"Cost of Climate backstop techno per ton CO2, $",H2UnservedCost,3000.0
1616
,,
1717
INTERCONNECTION,,
1818
INTERNAL,,
19-
Activate exchange between internal zone,fEnableInternalExchange,1
20-
Remove transfer limits between internal zone,fRemoveInternalTransferLimit,0
21-
Allow expansion of transfer limits,fAllowTransferExpansion,1
19+
Activate exchange between internal zone,fEnableInternalExchange,1.0
20+
Remove transfer limits between internal zone,fRemoveInternalTransferLimit,0.0
21+
Allow expansion of transfer limits,fAllowTransferExpansion,1.0
2222
EXTERNAL,,
23-
Activate exchange between external zone,fEnableExternalExchange,1
24-
"Maximum external import share, %",sMaxHourlyImportExternalShare,1
25-
"Maximum external export share, %",sMaxHourlyExportExternalShare,1
23+
Activate exchange between external zone,fEnableExternalExchange,1.0
24+
"Maximum external import share, %",sMaxHourlyImportExternalShare,1.0
25+
"Maximum external export share, %",sMaxHourlyExportExternalShare,1.0
2626
,,
2727
OPTIONAL FEATURES,,
28-
Include carbon price ,fEnableCarbonPrice,0
29-
Include energy efficiency,fEnableEnergyEfficiency,0
30-
Include CSP optimization,fEnableCSP,0
31-
Include Storage operation,fEnableStorage,1
28+
Include carbon price ,fEnableCarbonPrice,0.0
29+
Include energy efficiency,fEnableEnergyEfficiency,0.0
30+
Include CSP optimization,fEnableCSP,0.0
31+
Include Storage operation,fEnableStorage,1.0
3232
Initial state of charge for batteries (%),InitialSOCforBattery,0.5
33-
Retire plants on economic grounds,fEnableEconomicRetirement,0
34-
Use less detailed demand definition,fUseSimplifiedDemand,1
33+
Retire plants on economic grounds,fEnableEconomicRetirement,0.0
34+
Use less detailed demand definition,fUseSimplifiedDemand,1.0
3535
Fractional tolerance around system peak load used to identify hours considered ‘near-peak,sPeakLoadProximityThreshold,
3636
,,
3737
PLANNING RESERVES,,
38-
Include transmission lines when assessing country planning reserves,fCountIntercoForReserves,1
39-
Apply planning reserve constraint,fApplyPlanningReserveConstraint,1
38+
Include transmission lines when assessing country planning reserves,fCountIntercoForReserves,1.0
39+
Apply planning reserve constraint,fApplyPlanningReserveConstraint,1.0
4040
"System planning reserve margin, %",sReserveMarginPct,0.1
4141
,,
4242
SPINNING RESERVES,,
43-
Apply country spinning reserve contraints,fApplyCountrySpinReserveConstraint,1
44-
Apply system spinning reserve contraints,fApplySystemSpinReserveConstraint,0
43+
Apply country spinning reserve contraints,fApplyCountrySpinReserveConstraint,1.0
44+
Apply system spinning reserve contraints,fApplySystemSpinReserveConstraint,0.0
4545
"Spinning (country and system) reserve needs for VRE, %",sVREForecastErrorPct,0.15
46-
"Contribution of transmission lines to country spinning reserves need, %",sIntercoReserveContributionPct,0
46+
"Contribution of transmission lines to country spinning reserves need, %",sIntercoReserveContributionPct,0.0
4747
,,
4848
H2,,
49-
Allow capex trajectory H2,fEnableCapexTrajectoryH2,0
50-
Include H2 production,fEnableH2Production,0
49+
Allow capex trajectory H2,fEnableCapexTrajectoryH2,0.0
50+
Include H2 production,fEnableH2Production,0.0
5151
,,
5252
POLICY,,
53-
Apply country CO2 constraint,fApplyCountryCo2Constraint,0
54-
Apply system CO2 constraints,fApplySystemCo2Constraint,0
55-
Minimum share of RE (%),sMinRenewableSharePct,0
53+
Apply country CO2 constraint,fApplyCountryCo2Constraint,0.0
54+
Apply system CO2 constraints,fApplySystemCo2Constraint,0.0
55+
Minimum share of RE (%),sMinRenewableSharePct,0.0
5656
RE share target year,sRenewableTargetYear,
57-
Apply fuel constraints,fApplyFuelConstraint,0
58-
Apply max capital constraint,fApplyCapitalConstraint,0
57+
Apply fuel constraints,fApplyFuelConstraint,0.0
58+
Apply max capital constraint,fApplyCapitalConstraint,0.0
5959
"Total maximum capital investments, $ billion",sMaxCapitalInvestment,
6060
,,
6161
PLANTS,,
62-
Apply min generation for all hours,fApplyMinGenShareAllHours,0
63-
Apply ramp constraints,fApplyRampConstraint,0
64-
Apply min generation constraint (only dispatch),fApplyMinGenCommitment,0
65-
Include minimum up/down time constraints (only dispatch),fApplyMUDT,0
66-
Apply startup cost (only dispatch),fApplyStartupCost,0
62+
Apply min generation for all hours,fApplyMinGenShareAllHours,0.0
63+
Apply ramp constraints,fApplyRampConstraint,0.0
64+
Apply min generation constraint (only dispatch),fApplyMinGenCommitment,0.0
65+
Include minimum up/down time constraints (only dispatch),fApplyMUDT,0.0
66+
Apply startup cost (only dispatch),fApplyStartupCost,0.0
6767
,,
6868
INPUT TREATMENTS,,
69-
Auto-fill missing hydro availability,EPM_FILL_HYDRO_AVAILABILITY,1
70-
Auto-fill missing hydro CAPEX,EPM_FILL_HYDRO_CAPEX,1
71-
Auto-fill ROR profiles from pAvailability,EPM_FILL_ROR_FROM_AVAILABILITY,1
69+
Auto-fill missing hydro availability,EPM_FILL_HYDRO_AVAILABILITY,1.0
70+
Auto-fill missing hydro CAPEX,EPM_FILL_HYDRO_CAPEX,1.0
71+
Auto-fill ROR profiles from pAvailability,EPM_FILL_ROR_FROM_AVAILABILITY,1.0

installer/epm.exe

32 KB
Binary file not shown.

installer/installer.ps1

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function Write-Step { Write-Host ""; Write-Host ">>> $args" -ForegroundColor Cya
1111
function Write-Ok { Write-Host " OK: $args" -ForegroundColor Green }
1212
function Write-Warn { Write-Host " !! $args" -ForegroundColor Yellow }
1313
function Write-Err { Write-Host " ERROR: $args" -ForegroundColor Red }
14-
function Stop-Install { Read-Host "Press Enter to exit"; exit 1 }
14+
function Stop-Install { Write-Host "Press Enter to exit..."; $null = Read-Host; exit 1 }
1515

1616
Clear-Host
1717
Write-Host "=============================================" -ForegroundColor Yellow
@@ -24,7 +24,6 @@ Write-Host "=============================================" -ForegroundColor Yell
2424
Write-Step "Choose installation folder"
2525
Write-Host " Press Enter for default: $env:USERPROFILE\EPM" -ForegroundColor Gray
2626
$userInput = Read-Host " Folder"
27-
2827
if ($userInput -eq "") {
2928
$INSTALL_DIR = "$env:USERPROFILE\EPM"
3029
} else {
@@ -53,11 +52,15 @@ if ($git) {
5352
# --- Step 3: Clone ---
5453

5554
Write-Step "Cloning EPM repository"
56-
if (Test-Path $INSTALL_DIR) {
55+
$isGitRepo = Test-Path (Join-Path $INSTALL_DIR ".git")
56+
if ($isGitRepo) {
5757
Write-Warn "Folder exists - pulling latest changes..."
58-
& git -C "$INSTALL_DIR" pull origin $REPO_BRANCH
58+
& git -C "$INSTALL_DIR" pull --quiet origin $REPO_BRANCH
5959
} else {
60-
& git clone --branch $REPO_BRANCH $REPO_URL "$INSTALL_DIR"
60+
if (Test-Path $INSTALL_DIR) {
61+
Write-Warn "Folder exists but is not a git repo - cloning into it..."
62+
}
63+
& git clone --quiet --branch $REPO_BRANCH $REPO_URL "$INSTALL_DIR"
6164
if ($LASTEXITCODE -ne 0) {
6265
Write-Err "Clone failed. Check your internet connection."
6366
Stop-Install
@@ -212,5 +215,6 @@ Write-Host " EPM installed at : $INSTALL_DIR"
212215
Write-Host " Launch the dashboard by double-clicking:"
213216
Write-Host " 'Launch EPM Dashboard' on your Desktop"
214217
Write-Host ""
215-
Read-Host "Press Enter to exit"
218+
Write-Host "Press Enter to exit..."
219+
$null = Read-Host
216220
exit 0

installer/setup.iss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ Source: "installer.ps1"; DestDir: "{tmp}"; Flags: deleteafterinstall
2828

2929
[Run]
3030
Filename: "powershell.exe"; \
31-
Parameters: "-ExecutionPolicy Bypass -NonInteractive -File ""{tmp}\installer.ps1"""; \
31+
Parameters: "-ExecutionPolicy Bypass -File ""{tmp}\installer.ps1"""; \
3232
Description: "Run EPM setup"; \
33-
Flags: runhidden waituntilterminated
33+
Flags: waituntilterminated
3434

3535
[Messages]
3636
WelcomeLabel1=Welcome to EPM Setup

0 commit comments

Comments
 (0)