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