Yaroster commited on
Commit
21d1612
·
verified ·
1 Parent(s): 56f0ec1

Fill in Health Score, Fault Probabilities, Energy ledger, Latency and Cost and Recent Alerts with template data

Browse files
Files changed (1) hide show
  1. index.html +53 -68
index.html CHANGED
@@ -170,73 +170,56 @@ setTheme(dark);
170
  document.getElementById('themeBtn').onclick = ()=>setTheme(!body.classList.contains('theme-dark'));
171
  /* DEMO DATA GENERATION */
172
  let lastHealth=0.94, lastEta=180;
173
- const dataHealth = Array(15*60).fill().map((_,i)=>{
174
- const x = Date.now()-i*1000;
175
- // Simulate realistic grid health with daily patterns
176
- const hour = (i/3600) % 24;
177
- const isPeak = (hour >= 8 && hour <= 10) || (hour >= 17 && hour <= 20);
178
- const isNight = hour >= 22 || hour <= 5;
179
-
180
- // Base health score with daily variation
181
- let base = isPeak ? 0.88 : isNight ? 0.96 : 0.92;
182
-
183
- // Add smaller fluctuations based on minutes
184
- const min = (i/60) % 60;
185
- base += Math.sin(min/15) * 0.02;
186
-
187
- // Add random equipment failures (5% chance every 15 min)
188
- const failure = i % (15*60) === 0 && Math.random() > 0.95 ? -0.08 : 0;
189
-
190
- // Add random noise
191
- const noise = Math.random() * 0.01;
192
-
193
- return {x, y: Math.max(0.7, base + failure + noise)};
194
- });
195
 
196
- // Fault probability data (last 24 hours)
197
- const dataSag = [], dataSwell=[], dataOsc=[], dataLatency=[], dataCost=[], dataEnergy=[];
198
- for(let i=0;i<60*24;i++){
199
- const x = Date.now()-i*60000;
200
- const hour = (i/60) % 24;
201
- const isPeak = (hour >= 6 && hour <= 9) || (hour >= 16 && hour <= 20);
202
-
203
- // Voltage Sag (most common during peak hours)
204
- let sagProb = isPeak ? 0.25 : 0.15;
205
- sagProb += Math.sin(i/180) * 0.1; // cyclic pattern every 3 hours
206
- if(i % (7*60) === 0 && Math.random() > 0.7) sagProb += 0.3; // random spikes
207
- dataSag.unshift({x, y: Math.min(0.9, Math.max(0, sagProb + Math.random()*0.05))});
208
-
209
- // Voltage Swell (less common)
210
- let swellProb = isPeak ? 0.18 : 0.1;
211
- swellProb += Math.sin(i/240) * 0.08;
212
- if(i % (10*60) === 0 && Math.random() > 0.8) swellProb += 0.2;
213
- dataSwell.unshift({x, y: Math.min(0.8, Math.max(0, swellProb + Math.random()*0.03))});
214
-
215
- // Frequency Oscillation (rare but important)
216
- let oscProb = isPeak ? 0.12 : 0.08;
217
- oscProb += Math.sin(i/300) * 0.05;
218
- if(i % (15*60) === 0 && Math.random() > 0.9) oscProb += 0.25;
219
- dataOsc.unshift({x, y: Math.min(0.7, Math.max(0, oscProb + Math.random()*0.02))});
220
-
221
- // Latency & Cost (better at night)
222
- const latency = isPeak ? 0.18 + Math.random()*0.04 : 0.12 + Math.random()*0.03;
223
- dataLatency.unshift({x, y: latency});
224
- dataCost.unshift({x, y: latency / 1500}); // cost proportional to latency
225
-
226
- // Energy consumption
227
- const energy = isPeak ? 0.0095 + Math.random()*0.002 : 0.006 + Math.random()*0.0015;
228
- dataEnergy.unshift({x, y: energy});
229
  }
230
 
231
- // Recent Alerts (last 24 hours)
 
 
 
 
 
 
 
 
 
 
 
232
  const alerts = [
233
- {time:new Date(Date.now()-45000), feeder:"N12", fault:"Voltage Sag 0.85", eta:"32 s", action:"Adjust tap changer"},
234
- {time:new Date(Date.now()-120000), feeder:"S08", fault:"Current Swell 0.78", eta:"1:45", action:"Notify maintenance"},
235
- {time:new Date(Date.now()-300000), feeder:"E05", fault:"Frequency Osc 0.65", eta:"2:10", action:"Monitor"},
236
- {time:new Date(Date.now()-1800000), feeder:"W03", fault:"Harmonic Dist 0.72", eta:"4:30", action:"Schedule filter check"},
237
- {time:new Date(Date.now()-3600000), feeder:"C01", fault:"Voltage Dip 0.88", eta:"12:30", action:"Reroute load"},
238
- {time:new Date(Date.now()-5400000), feeder:"N07", fault:"Phase Unbalance 0.81", eta:"6:15", action:"Balance load"},
239
- {time:new Date(Date.now()-7200000), feeder:"S02", fault:"Capacitor Bank Fail", eta:"8:20", action:"Dispatch crew"}
240
  ];
241
  /* CHARTS */
242
  function lineConfig(data,label,color,fill=false){
@@ -281,7 +264,6 @@ function refresh(){
281
  const gauge = document.getElementById('gauge');
282
  let c = lastHealth>=0.8? '#22c55e':lastHealth>=0.5? '#f59e0b': '#ef4444';
283
  gauge.style.borderColor = c;
284
-
285
  lastEta = Math.max(0,lastEta-1+Math.random()*2);
286
  const eta = lastEta<60?Math.round(lastEta)+' s':`${Math.floor(lastEta/60)} m`;
287
  document.getElementById('etaVal').textContent=eta;
@@ -289,10 +271,13 @@ function refresh(){
289
  kpiEta.classList.toggle('blink', lastEta<60);
290
  const hour = new Date().getHours();
291
  const isPeak = hour > 8 && hour < 20;
292
- document.getElementById('latencyVal').textContent = (isPeak ? 0.17 + Math.random()*0.03 : 0.12 + Math.random()*0.02).toFixed(2)+' ms';
293
- document.getElementById('energyVal').textContent = (isPeak ? 0.009 + Math.random()*0.0015 : 0.006 + Math.random()*0.0012).toFixed(3)+' Wh';
294
- document.getElementById('co2Val').textContent = (3.2 + Math.sin(Date.now()/86400000)*0.4).toFixed(2)+' kg';
295
- // alerts
 
 
 
296
  const tbody = document.querySelector('#alertsTable tbody');
297
  tbody.innerHTML='';
298
  alerts.forEach(a=>{
 
170
  document.getElementById('themeBtn').onclick = ()=>setTheme(!body.classList.contains('theme-dark'));
171
  /* DEMO DATA GENERATION */
172
  let lastHealth=0.94, lastEta=180;
173
+ // Template data for Health Score (15 minutes, updated every second)
174
+ const dataHealth = [];
175
+ const now = Date.now();
176
+ for (let i = 0; i < 15 * 60; i++) {
177
+ const time = now - (15 * 60 - i) * 1000;
178
+ // Use template values that vary realistically
179
+ const values = [0.95, 0.94, 0.93, 0.92, 0.91, 0.90, 0.89, 0.88, 0.87, 0.86];
180
+ const value = values[i % values.length] + (Math.random() * 0.02 - 0.01);
181
+ dataHealth.push({ x: time, y: Math.max(0.85, Math.min(0.96, value)) });
182
+ }
183
+
184
+ // Template data for Fault Probabilities (24 hours, updated every minute)
185
+ const dataSag = [], dataSwell = [], dataOsc = [];
186
+ for (let i = 0; i < 24 * 60; i++) {
187
+ const time = now - (24 * 60 - i) * 60000;
188
+ // Use template patterns for each fault type
189
+ dataSag.push({ x: time, y: 0.1 + 0.1 * Math.sin(i / 30) + Math.random() * 0.05 });
190
+ dataSwell.push({ x: time, y: 0.05 + 0.08 * Math.sin(i / 45 + 1) + Math.random() * 0.03 });
191
+ dataOsc.push({ x: time, y: 0.02 + 0.06 * Math.sin(i / 60 + 2) + Math.random() * 0.02 });
192
+ }
 
 
193
 
194
+ // Template data for Energy Ledger (24 hours, hourly data)
195
+ const dataEnergy = [];
196
+ for (let i = 0; i < 24; i++) {
197
+ const time = now - (23 - i) * 3600000;
198
+ // Template energy consumption pattern
199
+ const base = 0.005 + 0.003 * Math.sin(i / 4);
200
+ dataEnergy.push({ x: time, y: base + Math.random() * 0.002 });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  }
202
 
203
+ // Template data for Latency & Cost (24 hours, hourly data)
204
+ const dataLatency = [], dataCost = [];
205
+ for (let i = 0; i < 24; i++) {
206
+ const time = now - (23 - i) * 3600000;
207
+ // Template latency pattern
208
+ const latency = 0.1 + 0.05 * Math.sin(i / 3) + Math.random() * 0.02;
209
+ dataLatency.push({ x: time, y: latency });
210
+ // Cost derived from latency
211
+ dataCost.push({ x: time, y: latency * 0.0005 });
212
+ }
213
+
214
+ // Template data for Recent Alerts
215
  const alerts = [
216
+ {time:new Date(now-2*60000), feeder:"F01", fault:"Voltage Sag 0.85", eta:"32 s", action:"Adjust tap changer"},
217
+ {time:new Date(now-5*60000), feeder:"F02", fault:"Current Swell 0.78", eta:"1:45", action:"Notify maintenance"},
218
+ {time:new Date(now-10*60000), feeder:"F03", fault:"Frequency Osc 0.65", eta:"2:10", action:"Monitor"},
219
+ {time:new Date(now-30*60000), feeder:"F04", fault:"Harmonic Dist 0.72", eta:"4:30", action:"Schedule filter check"},
220
+ {time:new Date(now-60*60000), feeder:"F05", fault:"Voltage Dip 0.88", eta:"12:30", action:"Reroute load"},
221
+ {time:new Date(now-90*60000), feeder:"F06", fault:"Phase Unbalance 0.81", eta:"6:15", action:"Balance load"},
222
+ {time:new Date(now-120*60000), feeder:"F07", fault:"Capacitor Bank Fail", eta:"8:20", action:"Dispatch crew"}
223
  ];
224
  /* CHARTS */
225
  function lineConfig(data,label,color,fill=false){
 
264
  const gauge = document.getElementById('gauge');
265
  let c = lastHealth>=0.8? '#22c55e':lastHealth>=0.5? '#f59e0b': '#ef4444';
266
  gauge.style.borderColor = c;
 
267
  lastEta = Math.max(0,lastEta-1+Math.random()*2);
268
  const eta = lastEta<60?Math.round(lastEta)+' s':`${Math.floor(lastEta/60)} m`;
269
  document.getElementById('etaVal').textContent=eta;
 
271
  kpiEta.classList.toggle('blink', lastEta<60);
272
  const hour = new Date().getHours();
273
  const isPeak = hour > 8 && hour < 20;
274
+ // Use template values for latency and energy
275
+ const latencyVal = isPeak ? 0.15 + Math.random() * 0.03 : 0.12 + Math.random() * 0.02;
276
+ const energyVal = isPeak ? 0.008 + Math.random() * 0.0015 : 0.006 + Math.random() * 0.0012;
277
+ document.getElementById('latencyVal').textContent = latencyVal.toFixed(2) + ' ms';
278
+ document.getElementById('energyVal').textContent = energyVal.toFixed(3) + ' Wh';
279
+ document.getElementById('co2Val').textContent = (2.1 + Math.random() * 0.2).toFixed(1) + ' kg';
280
+ // alerts
281
  const tbody = document.querySelector('#alertsTable tbody');
282
  tbody.innerHTML='';
283
  alerts.forEach(a=>{