88< link rel ="preload " href ="https://fonts.googleapis.com/css2?family=Exo:ital,wght@0,100..900;1,100..900&display=swap " as ="style " onload ="this.onload=null;this.rel='stylesheet' ">
99< noscript > < link href ="https://fonts.googleapis.com/css2?family=Exo:ital,wght@0,100..900;1,100..900&display=swap " rel ="stylesheet " type ="text/css "> </ noscript >
1010< link rel ="stylesheet " href ="/app.css ">
11+ < link rel ="preload " href ="/images/inverter-ok.svg " as ="image ">
12+ < link rel ="preload " href ="/images/solar-forecast.svg " as ="image ">
13+ < link rel ="preload " href ="/images/grid-ok.svg " as ="image ">
14+ < link rel ="preload " href ="/images/battery-mid.svg " as ="image ">
15+ < link rel ="preload " href ="/images/battery-full.svg " as ="image ">
1116< script src ="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js "> </ script >
1217< script src ="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0/dist/chartjs-adapter-date-fns.bundle.min.js "> </ script >
1318< style >
@@ -379,6 +384,16 @@ <h3>Global Control</h3>
379384let charts = { } ;
380385let ws ;
381386let todayPeakPv = 0 ;
387+ let currentDetail = null ;
388+ let detailRendered = false ;
389+ const imageCache = { } ;
390+ function preloadImage ( src ) {
391+ if ( imageCache [ src ] ) return imageCache [ src ] ;
392+ const img = new Image ( ) ;
393+ img . src = src ;
394+ imageCache [ src ] = img ;
395+ return img ;
396+ }
382397
383398function fmt ( num , digits = 1 ) {
384399 if ( num === undefined || num === null || Number . isNaN ( num ) ) return null ;
@@ -393,10 +408,10 @@ <h3>Global Control</h3>
393408 const d = new Date ( iso ) ;
394409 return d . toLocaleTimeString ( [ ] , { hour :'2-digit' , minute :'2-digit' , second :'2-digit' } ) ;
395410}
396- function val ( r , key ) {
397- if ( ! r || ! r . registers ) return undefined ;
411+ function val ( r , key , fallback ) {
412+ if ( ! r || ! r . registers ) return fallback ;
398413 const k = r . registers [ key ] ;
399- return k ? k . value : undefined ;
414+ return k && k . value !== undefined ? k . value : fallback ;
400415}
401416async function fetchJson ( url ) {
402417 const res = await fetch ( url ) ;
@@ -425,6 +440,9 @@ <h3>Global Control</h3>
425440 const pv2 = val ( r , 'pv2_power' ) || 0 ;
426441 const pvTotal = pv1 + pv2 ;
427442 if ( pvTotal > todayPeakPv ) todayPeakPv = pvTotal ;
443+ // Inject computed values so detail view can read them via data-reg
444+ if ( ! r . registers ) r . registers = { } ;
445+ r . registers . pv_total_power = { value : pvTotal , unit : 'W' } ;
428446 setText ( 'sa-solar-total' , fmtInt ( pvTotal ) + ' W' ) ;
429447 setText ( 'sa-solar-peak' , fmtInt ( todayPeakPv ) + ' W' ) ;
430448
@@ -437,22 +455,34 @@ <h3>Global Control</h3>
437455 const batV = val ( r , 'battery_voltage' ) ;
438456 const soc = val ( r , 'soc' ) ;
439457 const batP = val ( r , 'battery_power' ) || ( ( val ( r , 'discharge_power' ) || 0 ) - ( val ( r , 'charge_power' ) || 0 ) ) ;
458+ const gridIn = val ( r , 'grid_import_power' ) || 0 ;
459+ const gridOut = val ( r , 'grid_export_power' ) || 0 ;
460+ const loadPower = val ( r , 'load_power' ) || val ( r , 'total_load_power' ) || ( pvTotal + gridIn - gridOut + ( ( val ( r , 'discharge_power' ) || 0 ) - ( val ( r , 'charge_power' ) || 0 ) ) ) ;
461+ r . registers . load_power = { value : loadPower , unit : 'W' } ;
440462 setText ( 'sa-bat-v' , batV !== undefined ? fmt ( batV ) + ' V' : null ) ;
441463 setText ( 'sa-bat-soc' , soc !== undefined ? fmtInt ( soc ) + ' %' : null ) ;
442464 setText ( 'sa-bat-power' , batP !== undefined ? fmtInt ( batP ) + ' W' : null ) ;
443465
444- // Battery icon based on SOC
466+ // Battery icon based on SOC — only swap if the target actually changes
445467 if ( soc !== undefined ) {
446468 const img = document . getElementById ( 'img-battery' ) ;
447- const level = soc < 25 ? 'battery-mid.svg' : ( soc < 75 ? 'battery-mid.svg' : 'battery-full.svg' ) ;
448- // Preload before swap
449- const pre = new Image ( ) ;
450- pre . onload = ( ) => { if ( img ) img . src = pre . src ; } ;
451- pre . src = '/images/' + level ;
469+ if ( img ) {
470+ const level = soc < 25 ? 'battery-mid.svg' : ( soc < 75 ? 'battery-mid.svg' : 'battery-full.svg' ) ;
471+ const nextSrc = '/images/' + level ;
472+ const currentSrc = img . getAttribute ( 'src' ) ;
473+ if ( currentSrc !== nextSrc ) {
474+ const pre = preloadImage ( nextSrc ) ;
475+ if ( pre . complete ) {
476+ img . src = nextSrc ;
477+ } else {
478+ pre . onload = ( ) => { img . src = nextSrc ; } ;
479+ }
480+ }
481+ }
452482 }
453483
454484 // Gauges
455- const load = val ( r , 'load_power' ) || val ( r , 'total_load_power' ) || ( pvTotal + gridIn - gridOut + ( ( val ( r , 'discharge_power' ) || 0 ) - ( val ( r , 'charge_power' ) || 0 ) ) ) ;
485+ const load = val ( r , 'load_power' ) ;
456486 setGauge ( 'load' , load , 10000 ) ;
457487 setGauge ( 'solar' , pvTotal , 10000 ) ;
458488 setGauge ( 'grid' , gridIn - gridOut , 10000 ) ;
@@ -478,102 +508,120 @@ <h3>Global Control</h3>
478508function propsHtml ( rows ) {
479509 return rows . map ( ( [ l , v ] ) => `<div class="prop"><div class="prop-label">${ l } </div><div class="prop-value">${ v } </div></div>` ) . join ( '' ) ;
480510}
511+ function prop ( label , reg , opts = { } ) {
512+ const suffix = opts . suffix || '' ;
513+ const intAttr = opts . int ? 'data-int="1"' : '' ;
514+ const digitsAttr = opts . digits ? `data-digits="${ opts . digits } "` : '' ;
515+ const suffixAttr = suffix ? `data-suffix="${ suffix } "` : '' ;
516+ return `<div class="prop"><div class="prop-label">${ label } </div><div class="prop-value" data-reg="${ reg } " ${ intAttr } ${ digitsAttr } ${ suffixAttr } >${ suffix || '--' } </div></div>` ;
517+ }
481518function detailInverter ( r ) {
482- const out = [
483- [ 'AC Voltage (R/S/T)' , `${ fmt ( val ( r , 'ac_output_voltage_r' ) ) } / ${ fmt ( val ( r , 'ac_output_voltage_s' ) ) } / ${ fmt ( val ( r , 'ac_output_voltage_t' ) ) } V` ] ,
484- [ 'AC Power (R/S/T)' , `${ fmtInt ( val ( r , 'ac_output_power_r' ) ) } / ${ fmtInt ( val ( r , 'ac_output_power_s' ) ) } / ${ fmtInt ( val ( r , 'ac_output_power_t' ) ) } W` ] ,
485- [ 'EPS Power' , `${ fmtInt ( val ( r , 'eps_power' ) ) } W` ] ,
486- [ 'EPS Frequency' , `${ fmt ( val ( r , 'eps_frequency' ) , 2 ) } Hz` ] ,
487- [ 'State' , STATE_MAP [ val ( r , 'state' , 0 ) ] || val ( r , 'state' , 0 ) ] ,
488- [ 'Fault Code' , fmtInt ( val ( r , 'fault_code' , 0 ) ) ] ,
489- [ 'Warning Code' , fmtInt ( val ( r , 'warning_code' , 0 ) ) ] ,
490- [ 'Runtime' , fmtInt ( val ( r , 'runtime' ) ) + ' min' ]
491- ] ;
492- const temps = [
493- [ 'Inverter' , `${ fmt ( val ( r , 'temp_inverter' ) ) } °C` ] ,
494- [ 'Battery' , `${ fmt ( val ( r , 'temp_battery' ) ) } °C` ] ,
495- [ 'Radiator 1' , `${ fmt ( val ( r , 'temp_radiator_1' ) ) } °C` ] ,
496- [ 'Radiator 2' , `${ fmt ( val ( r , 'temp_radiator_2' ) ) } °C` ]
497- ] ;
498- return `<div class="detail-grid"><div class="card"><div class="card-section"><h3>Output</h3><div class="props">${ propsHtml ( out ) } </div></div></div><div class="card"><div class="card-section"><h3>Temperatures</h3><div class="props">${ propsHtml ( temps ) } </div></div></div></div>` ;
519+ return `<div class="detail-grid"><div class="card"><div class="card-section"><h3>Output</h3><div class="props">
520+ ${ prop ( 'AC Voltage R' , 'ac_output_voltage_r' , { suffix :' V' } ) }
521+ ${ prop ( 'AC Voltage S' , 'ac_output_voltage_s' , { suffix :' V' } ) }
522+ ${ prop ( 'AC Voltage T' , 'ac_output_voltage_t' , { suffix :' V' } ) }
523+ ${ prop ( 'AC Power R' , 'ac_output_power_r' , { suffix :' W' , int :1 } ) }
524+ ${ prop ( 'AC Power S' , 'ac_output_power_s' , { suffix :' W' , int :1 } ) }
525+ ${ prop ( 'AC Power T' , 'ac_output_power_t' , { suffix :' W' , int :1 } ) }
526+ ${ prop ( 'EPS Power' , 'eps_power' , { suffix :' W' , int :1 } ) }
527+ ${ prop ( 'EPS Frequency' , 'eps_frequency' , { suffix :' Hz' , digits :2 } ) }
528+ ${ prop ( 'Fault Code' , 'fault_code' , { int :1 } ) }
529+ ${ prop ( 'Warning Code' , 'warning_code' , { int :1 } ) }
530+ ${ prop ( 'Runtime' , 'runtime' , { suffix :' min' , int :1 } ) }
531+ </div></div></div><div class="card"><div class="card-section"><h3>Temperatures</h3><div class="props">
532+ ${ prop ( 'Inverter' , 'temp_inverter' , { suffix :' °C' } ) }
533+ ${ prop ( 'Battery' , 'temp_battery' , { suffix :' °C' } ) }
534+ ${ prop ( 'Radiator 1' , 'temp_radiator_1' , { suffix :' °C' } ) }
535+ ${ prop ( 'Radiator 2' , 'temp_radiator_2' , { suffix :' °C' } ) }
536+ </div></div></div></div>` ;
499537}
500538function detailBattery ( r ) {
501- const props = [
502- [ 'SOC' , `${ fmtInt ( val ( r , 'soc' ) ) } %` ] ,
503- [ 'SOH' , `${ fmtInt ( val ( r , 'soh' ) ) } %` ] ,
504- [ 'Voltage' , `${ fmt ( val ( r , 'battery_voltage' ) ) } V` ] ,
505- [ 'Current' , `${ fmt ( val ( r , 'battery_current' ) ) } A` ] ,
506- [ 'Power' , `${ fmtInt ( val ( r , 'battery_power' ) ) } W` ] ,
507- [ 'Capacity' , `${ fmt ( val ( r , 'battery_capacity' ) ) } Ah` ] ,
508- [ 'Cycles' , fmtInt ( val ( r , 'cycle_count' ) ) ] ,
509- [ 'Temp' , `${ fmt ( val ( r , 'temp_battery' ) ) } °C` ]
510- ] ;
511539 let cells = '' ;
512- for ( let i = 1 ; i <= 16 ; i ++ ) {
513- const v = val ( r , 'cell_' + i + '_voltage' ) ;
514- if ( v === undefined ) continue ;
515- cells += `<div class="prop"><div class="prop-label">Cell ${ i } </div><div class="prop-value">${ fmt ( v , 3 ) } V</div></div>` ;
516- }
517- return `<div class="detail-grid"><div class="card"><div class="card-section"><h3>Battery</h3><div class="props">${ propsHtml ( props ) } </div></div></div><div class="card"><div class="card-section"><h3>Cells</h3><div class="props">${ cells || '<div class="prop"><div class="prop-label">No cell data</div></div>' } </div></div></div></div>` ;
540+ for ( let i = 1 ; i <= 16 ; i ++ ) cells += prop ( `Cell ${ i } ` , `cell_${ i } _voltage` , { suffix :' V' , digits :3 } ) ;
541+ return `<div class="detail-grid"><div class="card"><div class="card-section"><h3>Battery</h3><div class="props">
542+ ${ prop ( 'SOC' , 'soc' , { suffix :' %' , int :1 } ) }
543+ ${ prop ( 'SOH' , 'soh' , { suffix :' %' , int :1 } ) }
544+ ${ prop ( 'Voltage' , 'battery_voltage' , { suffix :' V' } ) }
545+ ${ prop ( 'Current' , 'battery_current' , { suffix :' A' } ) }
546+ ${ prop ( 'Power' , 'battery_power' , { suffix :' W' , int :1 } ) }
547+ ${ prop ( 'Capacity' , 'battery_capacity' , { suffix :' Ah' } ) }
548+ ${ prop ( 'Cycles' , 'cycle_count' , { int :1 } ) }
549+ ${ prop ( 'Temp' , 'temp_battery' , { suffix :' °C' } ) }
550+ </div></div></div><div class="card"><div class="card-section"><h3>Cells</h3><div class="props">${ cells } </div></div></div></div>` ;
518551}
519552function detailGrid ( r ) {
520- const props = [
521- [ 'Voltage R/S/T' , `${ fmt ( val ( r , 'grid_voltage_r' ) ) } / ${ fmt ( val ( r , 'grid_voltage_s' ) ) } / ${ fmt ( val ( r , 'grid_voltage_t' ) ) } V` ] ,
522- [ 'Frequency' , `${ fmt ( val ( r , 'grid_frequency' ) , 2 ) } Hz` ] ,
523- [ 'Import Power' , `${ fmtInt ( val ( r , 'grid_import_power' ) ) } W` ] ,
524- [ 'Export Power' , `${ fmtInt ( val ( r , 'grid_export_power' ) ) } W` ] ,
525- [ 'Import Today' , `${ fmt ( val ( r , 'grid_energy_in_today' ) , 2 ) } kWh` ] ,
526- [ 'Export Today' , `${ fmt ( val ( r , 'grid_energy_out_today' ) , 2 ) } kWh` ]
527- ] ;
528- return `<div class="detail-grid"><div class="card"><div class="card-section"><h3>Grid</h3><div class="props">${ propsHtml ( props ) } </div></div></div></div>` ;
553+ return `<div class="detail-grid"><div class="card"><div class="card-section"><h3>Grid</h3><div class="props">
554+ ${ prop ( 'Voltage R' , 'grid_voltage_r' , { suffix :' V' } ) }
555+ ${ prop ( 'Voltage S' , 'grid_voltage_s' , { suffix :' V' } ) }
556+ ${ prop ( 'Voltage T' , 'grid_voltage_t' , { suffix :' V' } ) }
557+ ${ prop ( 'Frequency' , 'grid_frequency' , { suffix :' Hz' , digits :2 } ) }
558+ ${ prop ( 'Import Power' , 'grid_import_power' , { suffix :' W' , int :1 } ) }
559+ ${ prop ( 'Export Power' , 'grid_export_power' , { suffix :' W' , int :1 } ) }
560+ ${ prop ( 'Import Today' , 'grid_energy_in_today' , { suffix :' kWh' , digits :2 } ) }
561+ ${ prop ( 'Export Today' , 'grid_energy_out_today' , { suffix :' kWh' , digits :2 } ) }
562+ </div></div></div></div>` ;
529563}
530564function detailSolar ( r ) {
531- const pv1 = val ( r , 'pv1_power' ) || 0 ;
532- const pv2 = val ( r , 'pv2_power' ) || 0 ;
533- const props = [
534- [ 'Total PV Power' , `${ fmtInt ( pv1 + pv2 ) } W` ] ,
535- [ 'PV1 Power' , `${ fmtInt ( pv1 ) } W` ] ,
536- [ 'PV2 Power' , `${ fmtInt ( pv2 ) } W` ] ,
537- [ 'PV1 Voltage' , `${ fmt ( val ( r , 'pv1_voltage' ) ) } V` ] ,
538- [ 'PV2 Voltage' , `${ fmt ( val ( r , 'pv2_voltage' ) ) } V` ] ,
539- [ 'PV Energy Today' , `${ fmt ( val ( r , 'pv_energy_today' ) , 2 ) } kWh` ]
540- ] ;
541- return `<div class="detail-grid"><div class="card"><div class="card-section"><h3>Solar</h3><div class="props">${ propsHtml ( props ) } </div></div></div></div>` ;
565+ return `<div class="detail-grid"><div class="card"><div class="card-section"><h3>Solar</h3><div class="props">
566+ ${ prop ( 'Total PV Power' , 'pv_total_power' , { suffix :' W' , int :1 } ) }
567+ ${ prop ( 'PV1 Power' , 'pv1_power' , { suffix :' W' , int :1 } ) }
568+ ${ prop ( 'PV2 Power' , 'pv2_power' , { suffix :' W' , int :1 } ) }
569+ ${ prop ( 'PV1 Voltage' , 'pv1_voltage' , { suffix :' V' } ) }
570+ ${ prop ( 'PV2 Voltage' , 'pv2_voltage' , { suffix :' V' } ) }
571+ ${ prop ( 'PV Energy Today' , 'pv_energy_today' , { suffix :' kWh' , digits :2 } ) }
572+ </div></div></div></div>` ;
542573}
543574function detailLoad ( r ) {
544- const pv1 = val ( r , 'pv1_power' ) || 0 ;
545- const pv2 = val ( r , 'pv2_power' ) || 0 ;
546- const gridIn = val ( r , 'grid_import_power' ) || 0 ;
547- const gridOut = val ( r , 'grid_export_power' ) || 0 ;
548- const chargeP = val ( r , 'charge_power' ) || 0 ;
549- const dischargeP = val ( r , 'discharge_power' ) || 0 ;
550- const load = val ( r , 'load_power' ) || val ( r , 'total_load_power' ) || ( pv1 + pv2 + gridIn - gridOut + ( dischargeP - chargeP ) ) ;
551- const props = [
552- [ 'Total Load' , `${ fmtInt ( load ) } W` ] ,
553- [ 'EPS Power' , `${ fmtInt ( val ( r , 'eps_power' ) ) } W` ] ,
554- [ 'Load Energy Today' , `${ fmt ( val ( r , 'load_energy_today' ) , 2 ) } kWh` ] ,
555- [ 'EPS Energy Today' , `${ fmt ( val ( r , 'eps_energy_today' ) , 2 ) } kWh` ]
556- ] ;
557- return `<div class="detail-grid"><div class="card"><div class="card-section"><h3>Load</h3><div class="props">${ propsHtml ( props ) } </div></div></div></div>` ;
575+ return `<div class="detail-grid"><div class="card"><div class="card-section"><h3>Load</h3><div class="props">
576+ ${ prop ( 'Total Load' , 'load_power' , { suffix :' W' , int :1 } ) }
577+ ${ prop ( 'EPS Power' , 'eps_power' , { suffix :' W' , int :1 } ) }
578+ ${ prop ( 'Load Energy Today' , 'load_energy_today' , { suffix :' kWh' , digits :2 } ) }
579+ ${ prop ( 'EPS Energy Today' , 'eps_energy_today' , { suffix :' kWh' , digits :2 } ) }
580+ </div></div></div></div>` ;
558581}
559582function detailEnvironment ( r ) {
560- const props = [
561- [ 'Inverter Temp' , `${ fmt ( val ( r , 'temp_inverter' ) ) } °C` ] ,
562- [ 'Battery Temp' , `${ fmt ( val ( r , 'temp_battery' ) ) } °C` ] ,
563- [ 'Radiator 1' , `${ fmt ( val ( r , 'temp_radiator_1' ) ) } °C` ] ,
564- [ 'Radiator 2' , `${ fmt ( val ( r , 'temp_radiator_2' ) ) } °C` ] ,
565- [ 'Outside Temp' , `${ fmt ( val ( r , 'temp_outside' ) ) } °C` ]
566- ] ;
567- return `<div class="detail-grid"><div class="card"><div class="card-section"><h3>Environment</h3><div class="props">${ propsHtml ( props ) } </div></div></div></div>` ;
583+ return `<div class="detail-grid"><div class="card"><div class="card-section"><h3>Environment</h3><div class="props">
584+ ${ prop ( 'Inverter Temp' , 'temp_inverter' , { suffix :' °C' } ) }
585+ ${ prop ( 'Battery Temp' , 'temp_battery' , { suffix :' °C' } ) }
586+ ${ prop ( 'Radiator 1' , 'temp_radiator_1' , { suffix :' °C' } ) }
587+ ${ prop ( 'Radiator 2' , 'temp_radiator_2' , { suffix :' °C' } ) }
588+ ${ prop ( 'Outside Temp' , 'temp_outside' , { suffix :' °C' } ) }
589+ </div></div></div></div>` ;
568590}
569591
570592function showDetail ( name ) {
571593 const titles = { inverter :'Inverter' , battery :'Battery' , grid :'Grid' , solar :'Solar' , load :'Load' , environment :'Environment' } ;
572594 document . getElementById ( 'detail-title' ) . textContent = titles [ name ] || name ;
573- const fn = { inverter :detailInverter , battery :detailBattery , grid :detailGrid , solar :detailSolar , load :detailLoad , environment :detailEnvironment } [ name ] ;
574- document . getElementById ( 'detail-content' ) . innerHTML = fn ? fn ( liveData ) : '<p>No detail available.</p>' ;
595+ currentDetail = name ;
596+ detailRendered = false ;
597+ renderDetailHTML ( ) ;
575598 showPage ( 'detail' ) ;
576599}
600+ function renderDetailHTML ( ) {
601+ if ( ! currentDetail ) return ;
602+ const fn = { inverter :detailInverter , battery :detailBattery , grid :detailGrid , solar :detailSolar , load :detailLoad , environment :detailEnvironment } [ currentDetail ] ;
603+ const content = document . getElementById ( 'detail-content' ) ;
604+ if ( ! detailRendered ) {
605+ content . innerHTML = fn ? fn ( liveData ) : '<p>No detail available.</p>' ;
606+ detailRendered = true ;
607+ } else {
608+ // Only update text values to avoid image/text flicker; keep structure
609+ content . querySelectorAll ( '[data-reg]' ) . forEach ( el => {
610+ const v = val ( liveData , el . dataset . reg , null ) ;
611+ if ( v !== null && v !== undefined ) {
612+ const fmtFn = el . dataset . int ? fmtInt : ( el . dataset . digits ? ( n => fmt ( n , Number ( el . dataset . digits ) ) ) : fmt ) ;
613+ let text = fmtFn ( v ) ;
614+ if ( text === null || text === undefined ) text = '--' ;
615+ if ( el . dataset . suffix ) text += el . dataset . suffix ;
616+ el . textContent = text ;
617+ }
618+ } ) ;
619+ }
620+ }
621+ function updateDetail ( r ) {
622+ liveData = r ;
623+ renderDetailHTML ( ) ;
624+ }
577625
578626function createLineChart ( id , datasets , opts = { } ) {
579627 const ctx = document . getElementById ( id ) ;
@@ -805,10 +853,8 @@ <h3>Global Control</h3>
805853 try {
806854 const r = await fetchJson ( API + '/api/summary' ) ;
807855 renderMain ( r ) ;
808- if ( document . getElementById ( 'page-detail' ) . classList . contains ( 'active' ) ) {
809- const name = document . getElementById ( 'detail-title' ) . textContent . toLowerCase ( ) ;
810- const key = name === 'environment' ? 'environment' : ( name === 'solar' ? 'solar' : ( [ 'inverter' , 'battery' , 'grid' , 'load' ] . includes ( name ) ?name :'inverter' ) ) ;
811- showDetail ( key ) ;
856+ if ( currentDetail ) {
857+ updateDetail ( r ) ;
812858 }
813859 } catch ( e ) { console . error ( e ) ; }
814860}
@@ -876,7 +922,7 @@ <h3>Global Control</h3>
876922 refresh ( ) ;
877923 loadMainCharts ( ) ;
878924 connectWS ( ) ;
879- setInterval ( refresh , 5000 ) ;
925+ setInterval ( refresh , 15000 ) ;
880926} ) ;
881927</ script >
882928</ body >
0 commit comments