77ethers commited on
Commit
2ab05b1
·
verified ·
1 Parent(s): 40a8adc

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. gridops/server/static/index.html +112 -82
gridops/server/static/index.html CHANGED
@@ -356,11 +356,52 @@
356
  .tp-med .tp-name { color: var(--yellow); }
357
  .tp-hard .tp-name { color: var(--red); }
358
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359
  .intro-card .btn-start {
360
- width: 100%; padding: 16px;
361
  background: linear-gradient(135deg, var(--cyan-dim), var(--cyan));
362
  color: #000; border: none; border-radius: 8px;
363
- font-family: inherit; font-size: 15px; font-weight: 800;
364
  cursor: pointer; letter-spacing: 2px;
365
  text-transform: uppercase;
366
  transition: all 0.2s;
@@ -368,7 +409,7 @@
368
  .btn-start:hover { transform: translateY(-2px); box-shadow: 0 8px 30px rgba(6,182,212,0.4); }
369
 
370
  .intro-card .shortcut-hint {
371
- text-align: center; margin-top: 10px;
372
  font-size: 10px; color: var(--text-dim);
373
  }
374
 
@@ -393,93 +434,70 @@
393
  <h1>GRID<span>OPS</span></h1>
394
  </div>
395
 
396
- <div class="tagline">Community Microgrid Bridge Operator</div>
397
-
398
- <div class="story">
399
- <p>
400
- Imagine you're in charge of keeping the lights on for <strong>100 homes</strong> in an Indian city during a brutal summer. You have four energy sources:
401
- </p>
402
- <p style="margin-left:8px; line-height: 2.0;">
403
- <span class="highlight">&#9728;&#65039; Rooftop solar</span> &mdash; free energy, but only when the sun is up<br>
404
- <strong>&#128267; Community battery</strong> &mdash; 500 kWh storage, you decide when to charge or discharge<br>
405
- <span class="danger">&#9981; Diesel generator</span> &mdash; Rs 25/kWh + Rs 100 startup. Last resort.<br>
406
- <strong>&#9889; National grid</strong> &mdash; auto-imports/exports what's left over (capped at 200 kW)
407
- </p>
408
- <p>Every hour you make <strong>3 decisions</strong>:</p>
409
- <p style="margin-left:8px; line-height: 2.0;">
410
- &#128267; <strong>Battery</strong> &mdash; charge it (store cheap energy) or discharge it (cover peaks)<br>
411
- &#9981; <strong>Diesel</strong> &mdash; turn it on for emergency power (expensive!)<br>
412
- &#127968; <strong>Demand shed</strong> &mdash; ask residents to use less (but 100% rebounds next hour)
413
- </p>
414
- </div>
415
 
416
- <div class="the-catch">
417
- <div class="catch-title">The catch</div>
418
- At <strong>8 PM every evening</strong>, everyone turns on their AC. Demand hits <strong>250 kW</strong>.
419
- But the grid connection maxes out at <strong>200 kW</strong>. That's a <strong>50 kW gap</strong>.
420
- Your battery can cover it &mdash; <em>if you charged it during the day</em>.
421
- If it's empty because you discharged it for profit?
422
- <span style="color:var(--red);font-weight:700">Blackout. Rs 150/kWh penalty.</span>
423
- On a heatwave day, demand spikes to <strong>375 kW</strong> and you'll need <em>everything</em>
424
- &mdash; battery, diesel, shedding &mdash; just to survive.
425
- </div>
426
 
427
- <div class="controls-preview">
428
- <div class="cp-item">
429
- <span class="cp-icon">&#128267;</span>
430
- <div class="cp-name">Battery</div>
431
- <div class="cp-desc">Charge or discharge. -100 to +100 kW. Rs 2.5/kWh degradation.</div>
432
- </div>
433
- <div class="cp-item">
434
- <span class="cp-icon">&#9981;</span>
435
- <div class="cp-name">Diesel</div>
436
- <div class="cp-desc">Emergency backup. Rs 25/kWh + Rs 100 startup cost.</div>
437
- </div>
438
- <div class="cp-item">
439
- <span class="cp-icon">&#127968;</span>
440
- <div class="cp-name">Demand Shed</div>
441
- <div class="cp-desc">Ask residents to cut usage. Up to 20%. 100% rebounds next hour! Rs 40/kWh.</div>
442
  </div>
443
- </div>
444
 
445
- <div class="the-catch" style="border-color: rgba(6,182,212,0.3); background: rgba(6,182,212,0.05); margin-bottom: 20px;">
446
- <div class="catch-title" style="color: var(--cyan);">The grid is your safety net</div>
447
- The national grid <strong>automatically</strong> absorbs whatever is left over &mdash;
448
- importing when you're short, exporting when you have surplus. But it's capped at
449
- <strong>200 kW</strong>. If your community needs more than that, you'd better have
450
- battery charge, diesel, or demand shedding ready.
451
- </div>
452
-
453
- <div style="font-size:11px;color:var(--text-dim);text-transform:uppercase;letter-spacing:2px;margin-bottom:8px;">Your score is graded on</div>
454
- <div class="scoring">
455
- <div class="sc-item">
456
- <div class="sc-pct" style="color:var(--cyan)">60%</div>
457
- <div class="sc-what">Cost Savings</div>
458
- </div>
459
- <div class="sc-item">
460
- <div class="sc-pct" style="color:var(--green)">20%</div>
461
- <div class="sc-what">Reliability</div>
462
  </div>
463
- <div class="sc-item">
464
- <div class="sc-pct" style="color:#22d3ee">20%</div>
465
- <div class="sc-what">Green Score</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
466
  </div>
 
467
  </div>
468
 
469
- <div style="font-size:11px;color:var(--text-dim);text-transform:uppercase;letter-spacing:2px;margin-bottom:8px;">3 escalating tasks</div>
470
- <div class="tasks-preview">
471
- <div class="tp-item tp-easy">
472
- <div class="tp-name">Task 1: Normal Summer</div>
473
- <div class="tp-desc">Clear skies. Smooth prices. Learn the daily cycle.</div>
474
- </div>
475
- <div class="tp-item tp-med">
476
- <div class="tp-name">Task 2: Heatwave</div>
477
- <div class="tp-desc">Day 2 heatwave. +30% demand. Price spikes. Battery decisions from Day 1 matter.</div>
478
- </div>
479
- <div class="tp-item tp-hard">
480
- <div class="tp-name">Task 3: Crisis</div>
481
- <div class="tp-desc">3-day heatwave. Solar drops 30%. Limited diesel. Survival mode.</div>
482
- </div>
483
  </div>
484
 
485
  <button class="btn-start" id="btnStart">Start Operating</button>
@@ -1109,6 +1127,18 @@ document.getElementById('introOverlay').addEventListener('keydown', e => {
1109
  resetEnv();
1110
  }
1111
  });
 
 
 
 
 
 
 
 
 
 
 
 
1112
  document.getElementById('btnStart').focus();
1113
  </script>
1114
  </body>
 
356
  .tp-med .tp-name { color: var(--yellow); }
357
  .tp-hard .tp-name { color: var(--red); }
358
 
359
+ /* Slide cards */
360
+ .slide-track {
361
+ display: flex; gap: 16px; overflow-x: auto; scroll-snap-type: x mandatory;
362
+ padding: 8px 0 16px; -webkit-overflow-scrolling: touch;
363
+ scrollbar-width: thin; scrollbar-color: var(--cyan-dim) transparent;
364
+ }
365
+ .slide-track::-webkit-scrollbar { height: 5px; }
366
+ .slide-track::-webkit-scrollbar-thumb { background: var(--cyan-dim); border-radius: 3px; }
367
+ .slide-card {
368
+ flex: 0 0 100%; scroll-snap-align: center;
369
+ padding: 28px 32px; border-radius: 14px;
370
+ border: 1px solid var(--border);
371
+ background: rgba(17,24,39,0.85);
372
+ display: flex; gap: 24px; align-items: center;
373
+ min-height: 160px;
374
+ }
375
+ .slide-card .sc-visual {
376
+ flex: 0 0 140px; height: 120px;
377
+ border-radius: 10px;
378
+ display: flex; align-items: center; justify-content: center;
379
+ font-size: 48px;
380
+ position: relative; overflow: hidden;
381
+ }
382
+ .slide-card .sc-content { flex: 1; min-width: 0; }
383
+ .slide-card .sc-step {
384
+ font-size: 10px; text-transform: uppercase; letter-spacing: 2px;
385
+ color: var(--cyan); margin-bottom: 6px;
386
+ }
387
+ .slide-card .sc-title { font-size: 18px; font-weight: 700; color: var(--text); margin-bottom: 8px; line-height: 1.3; }
388
+ .slide-card .sc-body { font-size: 13px; color: var(--text-dim); line-height: 1.7; }
389
+ .slide-card .sc-body strong { color: var(--cyan); font-weight: 600; }
390
+ .slide-card .sc-body .warn { color: var(--red); font-weight: 600; }
391
+ .slide-dots {
392
+ display: flex; justify-content: center; gap: 8px; margin-bottom: 16px;
393
+ }
394
+ .slide-dots .dot {
395
+ width: 8px; height: 8px; border-radius: 50%;
396
+ background: var(--border); transition: background 0.2s;
397
+ }
398
+ .slide-dots .dot.active { background: var(--cyan); }
399
+
400
  .intro-card .btn-start {
401
+ width: 100%; padding: 14px;
402
  background: linear-gradient(135deg, var(--cyan-dim), var(--cyan));
403
  color: #000; border: none; border-radius: 8px;
404
+ font-family: inherit; font-size: 14px; font-weight: 800;
405
  cursor: pointer; letter-spacing: 2px;
406
  text-transform: uppercase;
407
  transition: all 0.2s;
 
409
  .btn-start:hover { transform: translateY(-2px); box-shadow: 0 8px 30px rgba(6,182,212,0.4); }
410
 
411
  .intro-card .shortcut-hint {
412
+ text-align: center; margin-top: 8px;
413
  font-size: 10px; color: var(--text-dim);
414
  }
415
 
 
434
  <h1>GRID<span>OPS</span></h1>
435
  </div>
436
 
437
+ <div class="tagline">An OpenEnv RL environment for Indian community microgrid operation</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
 
439
+ <!-- Sliding cards -->
440
+ <div class="slide-track" id="slideTrack">
 
 
 
 
 
 
 
 
441
 
442
+ <!-- Card 1: The Scenario -->
443
+ <div class="slide-card">
444
+ <div class="sc-visual" style="background:linear-gradient(135deg, rgba(6,182,212,0.15), rgba(59,130,246,0.1)); border:1px solid rgba(6,182,212,0.2);">
445
+ <div style="text-align:center;">
446
+ <div style="font-size:36px;">&#127968;</div>
447
+ <div style="font-size:10px;color:var(--cyan);margin-top:4px;font-weight:600;">100 HOMES</div>
448
+ <div style="font-size:8px;color:var(--text-dim);">3 days &middot; 72 hours</div>
449
+ </div>
450
+ </div>
451
+ <div class="sc-content">
452
+ <div class="sc-step">The Scenario</div>
453
+ <div class="sc-title">You run a community microgrid in India during summer</div>
454
+ <div class="sc-body">Every hour for 3 days, you decide how to use the <strong>battery</strong>, <strong>diesel</strong>, and <strong>demand response</strong> &mdash; while the national grid automatically covers whatever is left over.</div>
455
+ </div>
 
456
  </div>
 
457
 
458
+ <!-- Card 2: Your Resources -->
459
+ <div class="slide-card">
460
+ <div class="sc-visual" style="background:linear-gradient(135deg, rgba(234,179,8,0.12), rgba(34,197,94,0.08)); border:1px solid rgba(234,179,8,0.2);">
461
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;padding:8px;">
462
+ <div style="text-align:center;"><div style="font-size:22px;">&#9728;&#65039;</div><div style="font-size:7px;color:var(--yellow);">SOLAR</div></div>
463
+ <div style="text-align:center;"><div style="font-size:22px;">&#128267;</div><div style="font-size:7px;color:var(--blue);">BATTERY</div></div>
464
+ <div style="text-align:center;"><div style="font-size:22px;">&#9981;</div><div style="font-size:7px;color:var(--orange);">DIESEL</div></div>
465
+ <div style="text-align:center;"><div style="font-size:22px;">&#9889;</div><div style="font-size:7px;color:var(--green);">GRID</div></div>
466
+ </div>
467
+ </div>
468
+ <div class="sc-content">
469
+ <div class="sc-step">Your Resources</div>
470
+ <div class="sc-title">Choose the right energy source to match demand</div>
471
+ <div class="sc-body"><strong>Solar</strong> is free but only shines during the day. <strong>Battery</strong> stores 500 kWh &mdash; you decide when to charge or use it. <strong>Diesel</strong> is expensive (Rs 25/kWh). <strong>Grid</strong> auto-fills the gap up to 200 kW.</div>
472
+ </div>
 
 
473
  </div>
474
+
475
+ <!-- Card 3: Your Goal -->
476
+ <div class="slide-card">
477
+ <div class="sc-visual" style="background:linear-gradient(135deg, rgba(34,197,94,0.12), rgba(6,182,212,0.08)); border:1px solid rgba(34,197,94,0.2);">
478
+ <div style="text-align:center;">
479
+ <div style="font-size:28px;color:var(--green);font-weight:800;">&#8595; &#8377;</div>
480
+ <div style="display:flex;gap:4px;justify-content:center;margin-top:8px;">
481
+ <div style="background:var(--green);width:40px;height:6px;border-radius:3px;opacity:0.8;"></div>
482
+ <div style="background:var(--yellow);width:25px;height:6px;border-radius:3px;opacity:0.8;"></div>
483
+ <div style="background:var(--cyan);width:25px;height:6px;border-radius:3px;opacity:0.8;"></div>
484
+ </div>
485
+ <div style="font-size:7px;color:var(--text-dim);margin-top:4px;">50% cost &middot; 25% lights &middot; 25% green</div>
486
+ </div>
487
+ </div>
488
+ <div class="sc-content">
489
+ <div class="sc-step">Your Goal</div>
490
+ <div class="sc-title">Lose as little money as possible while keeping lights on</div>
491
+ <div class="sc-body">Switch between energy sources smartly. Buy grid power <strong>cheap at night</strong>, use free solar during the day, and discharge battery during <strong>expensive evening peaks</strong>. Blackouts cost <span class="warn">Rs 150/kWh</span> &mdash; keep them near zero.</div>
492
+ </div>
493
  </div>
494
+
495
  </div>
496
 
497
+ <div class="slide-dots" id="slideDots">
498
+ <div class="dot active"></div>
499
+ <div class="dot"></div>
500
+ <div class="dot"></div>
 
 
 
 
 
 
 
 
 
 
501
  </div>
502
 
503
  <button class="btn-start" id="btnStart">Start Operating</button>
 
1127
  resetEnv();
1128
  }
1129
  });
1130
+ // Slide dot indicators
1131
+ const slideTrack = document.getElementById('slideTrack');
1132
+ const dots = document.querySelectorAll('#slideDots .dot');
1133
+ if (slideTrack && dots.length) {
1134
+ slideTrack.addEventListener('scroll', () => {
1135
+ const idx = Math.round(slideTrack.scrollLeft / slideTrack.clientWidth);
1136
+ dots.forEach((d, i) => d.classList.toggle('active', i === idx));
1137
+ });
1138
+ dots.forEach((d, i) => d.addEventListener('click', () => {
1139
+ slideTrack.scrollTo({ left: i * slideTrack.clientWidth, behavior: 'smooth' });
1140
+ }));
1141
+ }
1142
  document.getElementById('btnStart').focus();
1143
  </script>
1144
  </body>