mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-05-01 11:02:56 +02:00
Add airtime math and per-minute packets-over-uptime display for repeaters. Closes #194.
This commit is contained in:
4
frontend/package-lock.json
generated
4
frontend/package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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 <span className="ml-1.5 font-normal text-muted-foreground">{children}</span>;
|
||||
}
|
||||
|
||||
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 (
|
||||
<RepeaterPane title="Telemetry" state={state} onRefresh={onRefresh} disabled={disabled}>
|
||||
{!data ? (
|
||||
@@ -21,8 +42,24 @@ export function TelemetryPane({
|
||||
<div className="space-y-2">
|
||||
<KvRow label="Battery" value={`${data.battery_volts.toFixed(3)}V`} />
|
||||
<KvRow label="Uptime" value={formatDuration(data.uptime_seconds)} />
|
||||
<KvRow label="TX Airtime" value={formatDuration(data.airtime_seconds)} />
|
||||
<KvRow label="RX Airtime" value={formatDuration(data.rx_airtime_seconds)} />
|
||||
<KvRow
|
||||
label="TX Airtime"
|
||||
value={
|
||||
<>
|
||||
{formatDuration(data.airtime_seconds)}
|
||||
{txPct && <Secondary>({txPct})</Secondary>}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<KvRow
|
||||
label="RX Airtime"
|
||||
value={
|
||||
<>
|
||||
{formatDuration(data.rx_airtime_seconds)}
|
||||
{rxPct && <Secondary>({rxPct})</Secondary>}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Separator className="my-1" />
|
||||
<KvRow label="Noise Floor" value={`${data.noise_floor_dbm} dBm`} />
|
||||
<KvRow label="Last RSSI" value={`${data.last_rssi_dbm} dBm`} />
|
||||
@@ -30,7 +67,17 @@ export function TelemetryPane({
|
||||
<Separator className="my-1" />
|
||||
<KvRow
|
||||
label="Packets"
|
||||
value={`${data.packets_received.toLocaleString()} rx / ${data.packets_sent.toLocaleString()} tx`}
|
||||
value={
|
||||
<>
|
||||
{data.packets_received.toLocaleString()} rx / {data.packets_sent.toLocaleString()}{' '}
|
||||
tx
|
||||
{rxPerMin && txPerMin && (
|
||||
<Secondary>
|
||||
(avg {rxPerMin} rx/min / {txPerMin} tx/min)
|
||||
</Secondary>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<KvRow
|
||||
label="Flood"
|
||||
|
||||
Reference in New Issue
Block a user