diff --git a/gui/src/components/tracker/TrackerBattery.tsx b/gui/src/components/tracker/TrackerBattery.tsx index 0bf775a829..a9ccaa6f4e 100644 --- a/gui/src/components/tracker/TrackerBattery.tsx +++ b/gui/src/components/tracker/TrackerBattery.tsx @@ -2,11 +2,14 @@ import { useConfig } from '@/hooks/config'; import { useLocaleConfig } from '@/i18n/config'; import { BatteryIcon } from '@/components/commons/icon/BatteryIcon'; import { Typography } from '@/components/commons/Typography'; +import { Tooltip } from '@/components/commons/Tooltip'; export function TrackerBattery({ value, voltage, + runtime, disabled, + moreInfo = false, textColor = 'primary', }: { /** @@ -14,7 +17,9 @@ export function TrackerBattery({ */ value: number; voltage?: number | null; + runtime?: bigint | null; disabled?: boolean; + moreInfo?: boolean; textColor?: string; }) { const { currentLocales } = useLocaleConfig(); @@ -28,31 +33,49 @@ export function TrackerBattery({ }); const charging = (voltage || 0) > 4.3; - const showVoltage = voltage && config?.debug; + const debug = config?.debug || config?.devSettings.moreInfo; + const showVoltage = moreInfo && voltage && debug; return ( -
-
- -
- {((!charging || showVoltage) && ( -
- {!charging && ( - - {percentFormatter.format(value)} - - )} - {showVoltage && ( - - {voltageFormatter.format(voltage)}V - - )} -
- )) || ( -
-
+ {percentFormatter.format(value)} + > +
+
+
- )} -
+ {((!charging || showVoltage) && ( +
+ {!charging && runtime != null && runtime > 0 && ( + + {(runtime / BigInt(3600000000)).toString() + + 'h ' + + ( + (runtime % BigInt(3600000000)) / + BigInt(60000000) + ).toString() + + 'min'} + + )} + {!charging && (!runtime || debug) && ( + + {percentFormatter.format(value)} + + )} + {showVoltage && ( + + {voltageFormatter.format(voltage)}V + + )} +
+ )) || ( +
+
+
+ )} +
+
); } diff --git a/gui/src/components/tracker/TrackerCard.tsx b/gui/src/components/tracker/TrackerCard.tsx index 00dafabe04..a5e63d0a1e 100644 --- a/gui/src/components/tracker/TrackerCard.tsx +++ b/gui/src/components/tracker/TrackerCard.tsx @@ -51,7 +51,9 @@ function TrackerBig({ )}
@@ -119,6 +121,7 @@ function TrackerSmol({ )} diff --git a/gui/src/components/tracker/TrackersTable.tsx b/gui/src/components/tracker/TrackersTable.tsx index 1a4fdb022e..de165246cc 100644 --- a/gui/src/components/tracker/TrackersTable.tsx +++ b/gui/src/components/tracker/TrackersTable.tsx @@ -229,7 +229,9 @@ function Row({ )} @@ -329,7 +331,7 @@ export function TrackersTable({ const cols = [ 'minmax(150px, 1.5fr)', // Name 'minmax(100px, 1fr)', // Type - 'minmax(60px, 1fr)', // Battery + 'minmax(110px, 1fr)', // Battery '6rem', // Ping (w-24) 'minmax(60px, 1fr)', // TPS config?.devSettings?.preciseRotation ? '11rem' : '8rem', // Rotation 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 529f497460..c6545dd68e 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 @@ -317,6 +317,9 @@ public static int createDeviceData( HardwareStatus.addRssi(fbb, (short) tracker.getSignalStrength().floatValue()); } + if (tracker.getBatteryRemainingRuntime() != null) { + HardwareStatus.addBatteryRuntimeEstimate(fbb, tracker.getBatteryRemainingRuntime()); + } 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..0212b1982a 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 @@ -112,6 +112,7 @@ class Tracker @JvmOverloads constructor( val trackerFlexHandler: TrackerFlexHandler = TrackerFlexHandler(this) var batteryVoltage: Float? = null var batteryLevel: Float? = null + var batteryRemainingRuntime: Long? = null var ping: Int? = null var signalStrength: Int? = null var temperature: Float? = null 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 3ff51290cc..1e911b9446 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 @@ -138,6 +138,7 @@ class HIDCommon { } // Packet data + var runtime: Long? = null var batt: Int? = null var batt_v: Int? = null var temp: Int? = null @@ -221,6 +222,11 @@ class HIDCommon { } } + 5 -> { // runtime + // ulong as little endian + runtime = (dataReceived[i + 9].toUByte().toLong() shl 56) or (dataReceived[i + 8].toUByte().toLong() shl 48) or (dataReceived[i + 7].toUByte().toLong() shl 40) or (dataReceived[i + 6].toUByte().toLong() shl 32) or (dataReceived[i + 5].toUByte().toLong() shl 24) or (dataReceived[i + 4].toUByte().toLong() shl 16) or (dataReceived[i + 3].toUByte().toLong() shl 8) or dataReceived[i + 2].toUByte().toLong() + } + 6 -> { // data button = dataReceived[i + 2].toUByte().toInt() rssi = dataReceived[i + 15].toUByte().toInt() @@ -248,6 +254,9 @@ class HIDCommon { } // Assign data + if (runtime != null) { + tracker.batteryRemainingRuntime = runtime + } if (batt != null) { tracker.batteryLevel = if (batt == 128) 1f else (batt and 127).toFloat() } diff --git a/solarxr-protocol b/solarxr-protocol index b51232989c..3400a6e6dd 160000 --- a/solarxr-protocol +++ b/solarxr-protocol @@ -1 +1 @@ -Subproject commit b51232989cedc5a67f097c0b3fc8094ec7b37e1e +Subproject commit 3400a6e6dd4c66a0924b46b77445699d44a120e2