Skip to content

Add Ch Util, TX airtime and uptime to Device Info panel#1010

Open
wittrup wants to merge 2 commits intomeshtastic:mainfrom
wittrup:feature/device-metrics
Open

Add Ch Util, TX airtime and uptime to Device Info panel#1010
wittrup wants to merge 2 commits intomeshtastic:mainfrom
wittrup:feature/device-metrics

Conversation

@wittrup
Copy link
Copy Markdown

@wittrup wittrup commented Feb 16, 2026

This PR surfaces additional DeviceMetrics fields in the Device Info panel:

  • Channel Utilization
  • TX Airtime
  • Uptime

Telemetry from TELEMETRY_APP is merged into node.deviceMetrics so it aligns with existing battery/voltage handling.

Includes:

  • i18n labels
  • Improved uptime formatting (no zero-value segments)
  • No breaking changes

@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 16, 2026

@wittrup is attempting to deploy a commit to the Meshtastic Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Feb 16, 2026

CLA assistant check
All committers have signed the CLA.

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands the Device Info panel to surface additional DeviceMetrics fields (Channel Utilization, TX Airtime, and Uptime) and wires telemetry updates into node.deviceMetrics so the UI can display them alongside existing battery/voltage data.

Changes:

  • Persist telemetry-derived deviceMetrics into the node DB on telemetry packets.
  • Extend the UI DeviceMetrics type and plumb the new metrics through SidebarDeviceInfoPanel.
  • Add i18n labels and improve uptime formatting to omit zero-value segments.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/web/src/core/subscriptions.ts Updates nodeDB nodes with incoming telemetry metrics.
packages/web/src/components/types.ts Extends UI DeviceMetrics to include channel utilization, TX airtime, and uptime seconds.
packages/web/src/components/generic/Uptime.tsx Updates uptime formatting to skip zero-value segments.
packages/web/src/components/Sidebar.tsx Passes additional metrics into DeviceInfoPanel.
packages/web/src/components/DeviceInfoPanel.tsx Renders new device info rows for channel util, TX airtime, and uptime.
packages/web/public/i18n/locales/en/ui.json Adds English labels for the new device info rows.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +133 to +134
airUtilTx !== undefined
? `${(airUtilTx).toFixed(1)}%`
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

airUtilTx is typed as number | null | undefined, but this check only excludes undefined. If it is null, calling .toFixed(1) will throw at runtime. Guard with typeof airUtilTx === "number" (or airUtilTx != null) before formatting.

Suggested change
airUtilTx !== undefined
? `${(airUtilTx).toFixed(1)}%`
typeof airUtilTx === "number"
? `${airUtilTx.toFixed(1)}%`

Copilot uses AI. Check for mistakes.
Comment on lines +140 to +145
value:
uptimeSeconds !== undefined ? (
<Uptime seconds={uptimeSeconds} />
) : (
"N/A"
)
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uptimeSeconds is typed as number | null | undefined, but this only checks !== undefined. If uptimeSeconds is null, it will be passed to <Uptime seconds={...} /> (expects a number) and can break formatting/rendering. Also, InfoDisplayItem.value is typed as string | number | null, but this branch assigns a React element; either render uptime as a string or widen the value type to React.ReactNode (and ensure the render path supports it).

Suggested change
value:
uptimeSeconds !== undefined ? (
<Uptime seconds={uptimeSeconds} />
) : (
"N/A"
)
customComponent:
uptimeSeconds != null ? <Uptime seconds={uptimeSeconds} /> : undefined,
value: uptimeSeconds != null ? null : "N/A",

Copilot uses AI. Check for mistakes.
Comment on lines +44 to +51
connection.events.onTelemetryPacket.subscribe((packet) => {
const metrics = packet.data.variant.value;
const existing = nodeDB.getNode(packet.from);
nodeDB.addNode({
...(existing ?? {}),
num: packet.from,
deviceMetrics: { ...metrics },
});
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This handler assumes packet.data.variant.value is always DeviceMetrics. Telemetry packets typically have multiple variant.case values (e.g. device/environment/power metrics). Without checking packet.data.variant.case before assigning into node.deviceMetrics, non-device telemetry variants could overwrite deviceMetrics with the wrong shape. Add an explicit guard (e.g. only update when variant.case === "deviceMetrics").

Copilot uses AI. Check for mistakes.
Comment on lines +31 to 40
},
"channelUtil": {
"title": "Ch Util"
},
"airUtilTx": {
"title": "TX Airtime"
},
"uptime": {
"title": "Uptime"
}
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New sidebar.deviceInfo.* UI labels were added only to en/ui.json. Other locales’ ui.json files don’t contain these keys, so non-English UIs will likely display the raw i18n key. Either add the corresponding entries to the other locale ui.json files or provide default/fallback strings in the t(...) calls for these new labels.

Copilot uses AI. Check for mistakes.
Comment on lines +125 to +126
channelUtilization !== undefined
? `${(channelUtilization).toFixed(1)}%`
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

channelUtilization is typed as number | null | undefined, but this check only excludes undefined. If it is null, calling .toFixed(1) will throw at runtime. Prefer guarding with typeof channelUtilization === "number" (or channelUtilization != null) before formatting, and fall back to N/A otherwise.

Suggested change
channelUtilization !== undefined
? `${(channelUtilization).toFixed(1)}%`
typeof channelUtilization === "number"
? `${channelUtilization.toFixed(1)}%`

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants