Opengrid / static /index.html
K446's picture
Polish for hackathon submission: training evidence, two pipelines, UI, docs
e81353d
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="OpenGrid — Multi-Agent POMDP Power Grid Control Room with Safe RL">
<title>OpenGrid | Control Room</title>
<link href="https://api.fontshare.com/v2/css?f[]=bespoke-stencil@400,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/static/style.css?v=16">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<link rel="icon" href="/static/logo.png" type="image/png">
</head>
<body>
<!-- Loading Overlay -->
<div class="loading-overlay" id="loading">
<div class="loading-spinner"></div>
<div class="loading-text">OpenGrid — Initializing Control Room</div>
</div>
<!-- Alert Banner -->
<div class="alert-banner" id="alertBanner">
<span id="alertText"></span>
<button class="dismiss" onclick="dismissAlert()">Dismiss</button>
</div>
<!-- Main Layout -->
<div class="control-room">
<!-- ===== HEADER ===== -->
<header class="header">
<div class="header-brand">
<img src="/static/logo.png" alt="OpenGrid" class="logo-img" style="width:32px;height:32px;border-radius:6px;">
<div>
<h1>OpenGrid</h1>
<div class="sub">Multi-Agent Power Grid Control Room</div>
</div>
</div>
<div class="sim-badge">
<span class="dot"></span>
<span id="simStatus">READY</span>
</div>
<div class="header-stats">
<div class="header-stat">
<span class="label">Episode</span>
<span class="value normal" id="headerEpisode">--</span>
</div>
<div class="header-stat">
<span class="label">Step</span>
<span class="value" id="headerStep">0 / 50</span>
</div>
<div class="header-stat">
<span class="label">Frequency</span>
<span class="value normal" id="headerFreq">50.00 Hz</span>
</div>
<div class="header-stat">
<span class="label">Agents</span>
<span class="value normal" id="headerAgents">--</span>
</div>
<div class="header-stat">
<span class="label">Team Reward</span>
<span class="value" id="headerReward">0.00</span>
</div>
</div>
</header>
<!-- ===== TOOLBAR ===== -->
<div class="toolbar">
<div class="toolbar-section">
<span class="toolbar-label">PROCEDURAL</span>
<div class="task-group" id="proceduralTasks">
<!-- Populated by JS -->
</div>
</div>
<div class="toolbar-divider"></div>
<div class="toolbar-section">
<span class="toolbar-label">KARNATAKA</span>
<div class="task-group" id="karnatakaTasks">
<!-- Populated by JS -->
</div>
</div>
<div class="toolbar-divider"></div>
<div class="toolbar-section">
<span class="toolbar-label">CONTROLS</span>
<div class="controls-row">
<button class="ctrl-btn accent" id="btnReset" onclick="resetEpisode()">⟳ Reset</button>
<button class="ctrl-btn" id="btnStep" onclick="stepEpisode()">▶ Step</button>
<button class="ctrl-btn" id="btnAutoRun" onclick="toggleAutoRun()">⏩ Auto</button>
<button class="ctrl-btn" onclick="getGrade()">★ Grade</button>
</div>
</div>
<div class="toolbar-divider"></div>
<div class="toolbar-section">
<span class="toolbar-label">SCORE</span>
<div class="toolbar-score" id="episodeScore">--</div>
</div>
<div class="toolbar-section" style="margin-left:auto;">
<span class="toolbar-label">STEPS</span>
<span class="toolbar-value" id="totalSteps">0</span>
</div>
<div class="toolbar-section">
<span class="toolbar-label">BLACKOUT</span>
<span class="toolbar-value" id="blackoutStatus" style="color: var(--status-normal);">No</span>
</div>
</div>
<!-- ===== LEFT PANEL ===== -->
<aside class="left-panel">
<!-- Frequency Display -->
<div class="card freq-card">
<div class="card-title">
<span>Grid Frequency</span>
<span class="freq-nominal-tag">Nom 50.00 Hz</span>
</div>
<div class="freq-display">
<div class="freq-arc-container" id="freqArc"></div>
<div class="freq-readout">
<div class="freq-value-big" id="freqValueBig">50.00</div>
<div class="freq-unit">Hz</div>
</div>
<div class="freq-delta-row">
<div class="freq-delta-chip" id="freqDeltaChip">
<span class="freq-delta-arrow" id="freqDeltaArrow"></span>
<span id="freqDeltaText">Δ 0.000 Hz</span>
</div>
<div class="grid-condition normal" id="gridCondition">
<span class="cond-dot"></span>
<span id="gridConditionLabel">NORMAL</span>
</div>
</div>
</div>
</div>
<!-- System Summary -->
<div class="card">
<div class="card-title">System Summary</div>
<div class="stat-row highlight">
<span class="label">Total Generation</span>
<span class="value" id="totalGen">-- MW</span>
</div>
<div class="stat-row">
<span class="label">Total Load</span>
<span class="value" id="totalLoad">-- MW</span>
</div>
<div class="stat-row">
<span class="label">Net Balance</span>
<span class="value" id="netBalance">-- MW</span>
</div>
<div class="stat-row">
<span class="label">Lines Connected</span>
<span class="value" id="linesConnected">--</span>
</div>
<div class="stat-row">
<span class="label">Lines Overloaded</span>
<span class="value" id="linesOverloaded" style="color: var(--status-normal);">0</span>
</div>
</div>
<!-- Coordination -->
<div class="card">
<div class="card-title">Oversight Agent</div>
<div class="coord-score">
<div class="big-value" id="coordScore" style="color: var(--status-normal);">1.00</div>
<div style="font-size:10px; color: var(--text-secondary); margin-top:4px;">Coordination Score</div>
</div>
<div class="stat-row">
<span class="label">Conflicts</span>
<span class="value" id="conflicts">0</span>
</div>
<div class="stat-row">
<span class="label">Safety Corrections</span>
<span class="value" id="safetyCorrTotal">0</span>
</div>
<div class="stat-row">
<span class="label">Selfish Actions</span>
<span class="value" id="selfishActions">0</span>
</div>
</div>
<!-- Exception Log -->
<div class="card" style="flex:1; display:flex; flex-direction:column; overflow:hidden;">
<div class="card-title" style="color: var(--status-warning);">Exception Log</div>
<div class="alarm-log" id="alarmLog"></div>
</div>
</aside>
<!-- ===== CENTER PANEL (Grid Map) ===== -->
<main class="center-panel" id="centerPanel">
<div class="grid-map" id="gridMap"></div>
<!-- Map legend -->
<div class="map-legend">
<div class="legend-title">Legend</div>
<div class="legend-item"><span class="legend-dot" style="background:#00e5a0;"></span> Slack</div>
<div class="legend-item"><span class="legend-dot" style="background:#f5a623;"></span> Generator</div>
<div class="legend-item"><span class="legend-dot" style="background:#e94560;"></span> Load</div>
<div class="legend-item"><span class="legend-dot" style="background:#000000;"></span> Battery</div>
<div class="legend-item"><span class="legend-dot" style="background:#ffeb3b;"></span> Solar</div>
<div class="legend-item"><span class="legend-dot" style="background:#64ffda;"></span> Wind</div>
<div class="legend-line"><span class="legend-line-sample normal"></span> Normal</div>
<div class="legend-line"><span class="legend-line-sample warn"></span> Congested</div>
<div class="legend-line"><span class="legend-line-sample crit"></span> Overloaded</div>
<div id="agentLegendContainer" style="margin-top: 8px; border-top: 1px solid rgba(255,255,255,0.1); padding-top: 8px;"></div>
<div style="margin-top: 8px; font-size: 8px; color: var(--text-muted); font-style: italic;">
* Scroll to zoom for a clearer view
</div>
</div>
<div class="bus-tooltip" id="busTooltip">
<div class="tt-title" id="ttTitle">Bus 0</div>
<div class="tt-row"><span>Type</span><span class="tt-val" id="ttType">--</span></div>
<div class="tt-row"><span>Injection</span><span class="tt-val" id="ttInj">-- MW</span></div>
<div class="tt-row"><span>Zone</span><span class="tt-val" id="ttZone">--</span></div>
</div>
</main>
<!-- ===== RIGHT PANEL ===== -->
<aside class="right-panel">
<div class="card">
<div class="card-title">Agent Leaderboard</div>
<ul class="leaderboard" id="leaderboard"></ul>
</div>
<div id="agentCards"></div>
</aside>
<!-- ===== BOTTOM PANEL ===== -->
<footer class="bottom-panel">
<div class="bottom-card">
<div class="card-title">Reward History</div>
<div class="chart-area" id="rewardChart"></div>
</div>
<div class="bottom-card">
<div class="card-title">Frequency Trend</div>
<div class="chart-area" id="freqChart"></div>
</div>
<div class="bottom-card">
<div class="card-title">Generation Mix</div>
<div class="chart-area" id="genMixChart"></div>
</div>
</footer>
</div>
<script src="/static/app.js?v=20"></script>
</body>
</html>