@@ -245,6 +245,55 @@ function mapWledStatusText(statusRaw) {
245245 }
246246}
247247
248+ function mapBatteryStatusText ( statusRaw ) {
249+ const status = String ( statusRaw || '' ) . trim ( ) . toUpperCase ( ) ;
250+ switch ( status ) {
251+ case 'NORMAL' :
252+ return 'normal' ;
253+ case 'LOW' :
254+ return 'low' ;
255+ case 'DISCONNECTED' :
256+ return 'disconnected' ;
257+ default :
258+ return status ? status . toLowerCase ( ) : 'unknown' ;
259+ }
260+ }
261+
262+ function formatBatteryVoltage ( voltageRaw , disconnected ) {
263+ if ( disconnected ) {
264+ return '--' ;
265+ }
266+ const voltage = Number ( voltageRaw ) ;
267+ if ( ! Number . isFinite ( voltage ) || voltage <= 0 ) {
268+ return '--' ;
269+ }
270+ return voltage . toFixed ( 3 ) + ' V' ;
271+ }
272+
273+ function updateTopBatteryCapacity ( percentRaw , disconnected , low , forceOffline ) {
274+ const valueEl = document . getElementById ( 'topBatteryCapacity' ) ;
275+ if ( ! valueEl ) {
276+ return ;
277+ }
278+
279+ let percent = NaN ;
280+ if ( Number . isFinite ( percentRaw ) ) {
281+ percent = Math . max ( 0 , Math . min ( 100 , Math . round ( percentRaw ) ) ) ;
282+ }
283+
284+ const hasPercent = ! forceOffline && ! disconnected && Number . isFinite ( percent ) ;
285+ const displayText = hasPercent ? String ( percent ) + '%' : '--' ;
286+ valueEl . textContent = displayText ;
287+ valueEl . classList . remove ( 'topnav-meta__value--ok' , 'topnav-meta__value--warn' , 'topnav-meta__value--muted' ) ;
288+ if ( ! hasPercent ) {
289+ valueEl . classList . add ( 'topnav-meta__value--muted' ) ;
290+ } else if ( low ) {
291+ valueEl . classList . add ( 'topnav-meta__value--warn' ) ;
292+ } else {
293+ valueEl . classList . add ( 'topnav-meta__value--ok' ) ;
294+ }
295+ }
296+
248297function parseJsonSafe ( res ) {
249298 return res . text ( ) . then ( function ( t ) {
250299 if ( ! t ) {
@@ -598,15 +647,19 @@ function refreshEStopStatus() {
598647 const switchState = document . getElementById ( 'switchState' ) ;
599648 const rawEl = document . getElementById ( 'switchRaw' ) ;
600649 const channelEl = document . getElementById ( 'espNowChannelRuntime' ) ;
601- const peerStatusEl = document . getElementById ( 'peerStatus' ) ;
602650 const routeStatusEl = document . getElementById ( 'routeStatus' ) ;
603651 const packetEl = document . getElementById ( 'packetCount' ) ;
604652 const wledEl = document . getElementById ( 'wledStatus' ) ;
653+ const batteryVoltageEl = document . getElementById ( 'batteryVoltage' ) ;
654+ const batteryStateEl = document . getElementById ( 'batteryState' ) ;
605655
606656 const pressed = ! ! data . pressed ;
607657 const routeCount = Number ( data . routeCount || 0 ) ;
608658 const pressedRouteCount = Number ( data . pressedRouteCount || 0 ) ;
609- const configuredPeerCount = Number ( data . configuredPeerCount || 0 ) ;
659+ const batteryStatusRaw = String ( data . batteryStatus || '' ) . toUpperCase ( ) ;
660+ const batteryDisconnected = batteryStatusRaw === 'DISCONNECTED' ;
661+ const batteryLow = batteryStatusRaw === 'LOW' ;
662+ const batteryPercentRaw = Number ( data . batteryPercent ) ;
610663
611664 setPillState ( switchState , pressed ? 'PRESSED (STOP)' : 'RELEASED' , ! pressed ) ;
612665
@@ -629,27 +682,26 @@ function refreshEStopStatus() {
629682 setPillState ( routeStatusEl , String ( pressedRouteCount ) + '/' + String ( routeCount ) + ' active' , routeOk ) ;
630683 }
631684
632- if ( routeCount === 0 ) {
633- setPillState ( peerStatusEl , 'not configured' , false ) ;
634- } else if ( configuredPeerCount === routeCount ) {
635- setPillState ( peerStatusEl , String ( configuredPeerCount ) + '/' + String ( routeCount ) + ' online' , true ) ;
636- } else if ( configuredPeerCount > 0 ) {
637- setPillState ( peerStatusEl , String ( configuredPeerCount ) + '/' + String ( routeCount ) + ' online' , false ) ;
638- } else {
639- setPillState ( peerStatusEl , 'waiting' , false ) ;
640- }
641-
642685 const wledText = mapWledStatusText ( data . wledStatus ) ;
643686 const wledOk = wledText === 'ready' || wledText === 'pressed preset active' || wledText === 'released preset active' || wledText === 'restored' ;
644687 setPillState ( wledEl , wledText , wledOk ) ;
645688
689+ const batteryVoltageText = formatBatteryVoltage ( data . batteryVoltage , batteryDisconnected ) ;
690+ const batteryStatusText = mapBatteryStatusText ( batteryStatusRaw ) ;
691+ const batteryOk = ! batteryDisconnected && ! batteryLow ;
692+ setPillState ( batteryVoltageEl , batteryVoltageText , batteryOk ) ;
693+ setPillState ( batteryStateEl , batteryStatusText , batteryOk ) ;
694+ updateTopBatteryCapacity ( batteryPercentRaw , batteryDisconnected , batteryLow , false ) ;
695+
646696 applyRouteRuntimeStatus ( data . routes ) ;
647697 } )
648698 . catch ( function ( ) {
649699 setPillState ( document . getElementById ( 'switchState' ) , 'offline' , false ) ;
650- setPillState ( document . getElementById ( 'peerStatus' ) , 'offline' , false ) ;
651700 setPillState ( document . getElementById ( 'routeStatus' ) , 'offline' , false ) ;
652701 setPillState ( document . getElementById ( 'wledStatus' ) , 'offline' , false ) ;
702+ setPillState ( document . getElementById ( 'batteryVoltage' ) , 'offline' , false ) ;
703+ setPillState ( document . getElementById ( 'batteryState' ) , 'offline' , false ) ;
704+ updateTopBatteryCapacity ( NaN , true , false , true ) ;
653705 } ) ;
654706}
655707
0 commit comments