diff --git a/gui/public/i18n/en/translation.ftl b/gui/public/i18n/en/translation.ftl index a02c9dab35..7ee1809323 100644 --- a/gui/public/i18n/en/translation.ftl +++ b/gui/public/i18n/en/translation.ftl @@ -331,6 +331,7 @@ tracker-table-column-name = Name tracker-table-column-type = Type tracker-table-column-battery = Battery tracker-table-column-ping = Ping +tracker-table-column-packet_loss = Packet Loss tracker-table-column-tps = TPS tracker-table-column-temperature = Temp. °C tracker-table-column-linear-acceleration = Accel. X/Y/Z @@ -370,6 +371,10 @@ tracker-infos-magnetometer-status-v1 = { $status -> [ENABLED] Enabled } +tracker-infos-packet_loss = Packet Loss +tracker-infos-packets_lost = Packets Lost +tracker-infos-packets_received = Packets Received + ## Tracker settings tracker-settings-back = Go back to trackers list tracker-settings-title = Tracker settings diff --git a/gui/src/components/tracker/TrackerSettings.tsx b/gui/src/components/tracker/TrackerSettings.tsx index ead4288e2b..ff01405f38 100644 --- a/gui/src/components/tracker/TrackerSettings.tsx +++ b/gui/src/components/tracker/TrackerSettings.tsx @@ -367,6 +367,34 @@ export function TrackerSettingsPage() { {tracker?.device?.hardwareInfo?.networkProtocolVersion || '--'} + {tracker?.device?.hardwareStatus?.packetsReceived !== null && ( + <> +
+ + {l10n.getString('tracker-infos-packet_loss')} + + + {((tracker?.device?.hardwareStatus?.packetLoss ?? 0) * 100).toFixed(0)}% + +
+
+ + {l10n.getString('tracker-infos-packets_lost')} + + + {tracker?.device?.hardwareStatus?.packetsLost ?? '0'} + +
+
+ + {l10n.getString('tracker-infos-packets_received')} + + + {tracker?.device?.hardwareStatus?.packetsReceived ?? '0'} + +
+ + )} {tracker?.tracker && ( diff --git a/gui/src/components/tracker/TrackerWifi.tsx b/gui/src/components/tracker/TrackerWifi.tsx index 319833a199..6ebc32d3f0 100644 --- a/gui/src/components/tracker/TrackerWifi.tsx +++ b/gui/src/components/tracker/TrackerWifi.tsx @@ -1,15 +1,24 @@ import { WifiIcon } from '@/components/commons/icon/WifiIcon'; import { Typography } from '@/components/commons/Typography'; +import { Tooltip } from '@/components/commons/Tooltip'; export function TrackerWifi({ rssi, ping, rssiShowNumeric, disabled, + packetLoss, + packetsLost, + packetsReceived, + showPacketLoss = false, textColor = 'primary', }: { rssi: number | null; ping: number | null; + packetLoss?: number | null; + packetsLost?: number | null; + packetsReceived?: number | null; + showPacketLoss?: boolean; rssiShowNumeric?: boolean; disabled?: boolean; textColor?: string; @@ -31,6 +40,17 @@ export function TrackerWifi({ {rssi} dBm )} + {showPacketLoss && packetsReceived != null && ( + } + > + {`${((packetLoss ?? 0) * 100).toFixed(0)}% (${packetsLost ?? 0} / ${packetsReceived})`} + + )} )) || (
diff --git a/gui/src/components/tracker/TrackersTable.tsx b/gui/src/components/tracker/TrackersTable.tsx index 1a4fdb022e..e5bf67ceb0 100644 --- a/gui/src/components/tracker/TrackersTable.tsx +++ b/gui/src/components/tracker/TrackersTable.tsx @@ -243,6 +243,10 @@ function Row({ ping={device?.hardwareStatus?.ping} disabled={tracker.status === TrackerStatusEnum.DISCONNECTED} textColor={fontColor} + showPacketLoss + packetLoss={device.hardwareStatus.packetLoss} + packetsLost={device.hardwareStatus.packetsLost} + packetsReceived={device.hardwareStatus.packetsReceived} /> )} @@ -330,7 +334,7 @@ export function TrackersTable({ 'minmax(150px, 1.5fr)', // Name 'minmax(100px, 1fr)', // Type 'minmax(60px, 1fr)', // Battery - '6rem', // Ping (w-24) + '8rem', // Ping (w-24) 'minmax(60px, 1fr)', // TPS config?.devSettings?.preciseRotation ? '11rem' : '8rem', // Rotation 'minmax(60px, 1fr)', // Temp @@ -354,6 +358,7 @@ export function TrackersTable({
+
diff --git a/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilder.java b/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilder.java index 3c256ff2fd..db7ffdd3d2 100644 --- a/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilder.java +++ b/server/core/src/main/java/dev/slimevr/protocol/datafeed/DataFeedBuilder.java @@ -310,6 +310,17 @@ public static int createDeviceData( HardwareStatus.addRssi(fbb, (short) tracker.getSignalStrength().floatValue()); } + if (tracker.getPacketLoss() != null) { + HardwareStatus.addPacketLoss(fbb, tracker.getPacketLoss()); + } + + if (tracker.getPacketsLost() != null) { + HardwareStatus.addPacketsLost(fbb, tracker.getPacketsLost()); + } + + if (tracker.getPacketsReceived() != null) { + HardwareStatus.addPacketsReceived(fbb, tracker.getPacketsReceived()); + } int hardwareDataOffset = HardwareStatus.endHardwareStatus(fbb); int hardwareInfoOffset = DataFeedBuilder.createHardwareInfo(fbb, device); diff --git a/server/core/src/main/java/dev/slimevr/tracking/trackers/Tracker.kt b/server/core/src/main/java/dev/slimevr/tracking/trackers/Tracker.kt index 6392d2f7c1..d13dbd9374 100644 --- a/server/core/src/main/java/dev/slimevr/tracking/trackers/Tracker.kt +++ b/server/core/src/main/java/dev/slimevr/tracking/trackers/Tracker.kt @@ -116,6 +116,9 @@ class Tracker @JvmOverloads constructor( var signalStrength: Int? = null var temperature: Float? = null var button: Int? = null + var packetsReceived: Int? = null + var packetsLost: Int? = null + var packetLoss: Float? = null var customName: String? = null var magStatus: MagnetometerStatus = magStatus private set diff --git a/server/core/src/main/java/dev/slimevr/tracking/trackers/hid/HIDCommon.kt b/server/core/src/main/java/dev/slimevr/tracking/trackers/hid/HIDCommon.kt index 23d0a27ba1..371c6be68f 100644 --- a/server/core/src/main/java/dev/slimevr/tracking/trackers/hid/HIDCommon.kt +++ b/server/core/src/main/java/dev/slimevr/tracking/trackers/hid/HIDCommon.kt @@ -153,6 +153,10 @@ class HIDCommon { var svr_status: Int? = null // var status: Int? = null // raw status from tracker var rssi: Int? = null + var packets_received: Int? = null + var packets_lost: Int? = null + var windows_hit: Int? = null + var windows_missed: Int? = null // Tracker packets when (packetType) { @@ -207,6 +211,10 @@ class HIDCommon { 3 -> { // status svr_status = dataReceived[i + 2].toUByte().toInt() // status = dataReceived[i + 3].toUByte().toInt() + packets_received = dataReceived[i + 4].toUByte().toInt() + packets_lost = dataReceived[i + 5].toUByte().toInt() + windows_hit = dataReceived[i + 6].toUByte().toInt() + windows_missed = dataReceived[i + 7].toUByte().toInt() rssi = dataReceived[i + 15].toUByte().toInt() } @@ -296,6 +304,11 @@ class HIDCommon { if (rssi != null) { tracker.signalStrength = -rssi } + if (packets_received != null && packets_lost != null) { + tracker.packetsReceived = packets_received + tracker.packetsLost = packets_lost + tracker.packetLoss = if (packets_lost == 0) 0.0f else packets_lost.toFloat() / (packets_received + packets_lost).toFloat() + } // Assign rotation and acceleration if (packetType == 1 || packetType == 4) { diff --git a/solarxr-protocol b/solarxr-protocol index b0147eeffa..7fb914e6d3 160000 --- a/solarxr-protocol +++ b/solarxr-protocol @@ -1 +1 @@ -Subproject commit b0147eeffaa97a16400de174383c91be2ec31ab5 +Subproject commit 7fb914e6d3d05e6574eb93618b7c295d092dec0d