diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 95cb3a4..61eff51 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "remoteterm-meshcore-frontend", - "version": "3.11.0", + "version": "3.11.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "remoteterm-meshcore-frontend", - "version": "3.11.0", + "version": "3.11.3", "dependencies": { "@codemirror/lang-python": "^6.2.1", "@codemirror/theme-one-dark": "^6.1.3", diff --git a/frontend/src/components/repeater/RepeaterTelemetryPane.tsx b/frontend/src/components/repeater/RepeaterTelemetryPane.tsx index 7d3a5fb..7440116 100644 --- a/frontend/src/components/repeater/RepeaterTelemetryPane.tsx +++ b/frontend/src/components/repeater/RepeaterTelemetryPane.tsx @@ -1,7 +1,23 @@ +import type { ReactNode } from 'react'; import { Separator } from '../ui/separator'; import { RepeaterPane, NotFetched, KvRow, formatDuration } from './repeaterPaneShared'; import type { RepeaterStatusResponse, PaneState } from '../../types'; +function Secondary({ children }: { children: ReactNode }) { + return {children}; +} + +function formatAirtimePercent(airtimeSec: number, uptimeSec: number): string | null { + if (uptimeSec <= 0) return null; + return `${((airtimeSec / uptimeSec) * 100).toFixed(2)}%`; +} + +function formatPerMinute(count: number, uptimeSec: number): string | null { + if (uptimeSec <= 0) return null; + const rate = (count * 60) / uptimeSec; + return rate >= 10 ? rate.toFixed(0) : rate.toFixed(1); +} + export function TelemetryPane({ data, state, @@ -13,6 +29,11 @@ export function TelemetryPane({ onRefresh: () => void; disabled?: boolean; }) { + const txPct = data ? formatAirtimePercent(data.airtime_seconds, data.uptime_seconds) : null; + const rxPct = data ? formatAirtimePercent(data.rx_airtime_seconds, data.uptime_seconds) : null; + const rxPerMin = data ? formatPerMinute(data.packets_received, data.uptime_seconds) : null; + const txPerMin = data ? formatPerMinute(data.packets_sent, data.uptime_seconds) : null; + return ( {!data ? ( @@ -21,8 +42,24 @@ export function TelemetryPane({
- - + + {formatDuration(data.airtime_seconds)} + {txPct && ({txPct})} + + } + /> + + {formatDuration(data.rx_airtime_seconds)} + {rxPct && ({rxPct})} + + } + /> @@ -30,7 +67,17 @@ export function TelemetryPane({ + {data.packets_received.toLocaleString()} rx / {data.packets_sent.toLocaleString()}{' '} + tx + {rxPerMin && txPerMin && ( + + (avg {rxPerMin} rx/min / {txPerMin} tx/min) + + )} + + } />