From fe05561415d487d297822845324ec7b3fd082118 Mon Sep 17 00:00:00 2001 From: Denis Arnst Date: Tue, 13 Jan 2026 13:24:25 +0100 Subject: [PATCH] Steelseries Gen2 uses absolute battery --- lib/devices/steelseries_arctis_nova_7.hpp | 50 +++++++++++++++++++---- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/lib/devices/steelseries_arctis_nova_7.hpp b/lib/devices/steelseries_arctis_nova_7.hpp index fcc585d..21d5929 100644 --- a/lib/devices/steelseries_arctis_nova_7.hpp +++ b/lib/devices/steelseries_arctis_nova_7.hpp @@ -27,13 +27,13 @@ namespace headsetcontrol { class SteelSeriesArctisNova7 : public protocols::SteelSeriesNovaDevice { public: static constexpr std::array SUPPORTED_PRODUCT_IDS { - 0x2202, // Arctis Nova 7 - 0x227e, // Arctis Nova 7 Wireless - 0x2206, // Arctis Nova 7x - 0x2258, // Arctis Nova 7x v2 - 0x220a, // Arctis Nova 7p - 0x223a, // Arctis Nova 7 Diablo IV - 0x227a // Arctis Nova 7 WoW Edition + 0x2202, // Arctis Nova 7 (discrete battery: 0-4) + 0x227e, // Arctis Nova 7 Wireless Gen 2 (percentage battery: 0-100) + 0x2206, // Arctis Nova 7x (discrete battery: 0-4) + 0x2258, // Arctis Nova 7x v2 (likely percentage battery: 0-100) + 0x220a, // Arctis Nova 7p (discrete battery: 0-4) + 0x223a, // Arctis Nova 7 Diablo IV (discrete battery: 0-4) + 0x227a // Arctis Nova 7 WoW Edition (discrete battery: 0-4) }; static constexpr int EQUALIZER_BANDS = 10; @@ -106,12 +106,44 @@ class SteelSeriesArctisNova7 : public protocols::SteelSeriesNovaDevice 4 → Gen 2 protocol (wouldn't be valid in discrete mode) + // + // TODO: Known edge case - Gen 2 at 1-4% battery while actively charging (status=0x01) + // will be misdetected as original protocol and show inflated percentage + // (1%→25%, 2%→50%, 3%→75%, 4%→100%). This is extremely rare because: + // - Requires plugging in exactly at 1-4% battery + // - At low battery, devices typically show status=0x03 (on battery) + // - Self-corrects once battery charges past 4% + // - Only lasts a few seconds/minutes + // Proper fix would require passing product_id to getBattery() method. + bool is_gen2_protocol = (data[3] == 0x02 || data[3] == 0x03) || (data[2] > 4); + enum battery_status status = BATTERY_AVAILABLE; - if (data[3] == 0x01) { + if (data[3] == 0x01 || data[3] == 0x02) { status = BATTERY_CHARGING; } - int level = map(data[2], 0, 4, 0, 100); + int level; + if (is_gen2_protocol) { + // Gen 2: Direct percentage reporting (0-100) in data[2] + level = data[2]; + } else { + // Original models: Discrete levels (0-4) that need mapping + level = map(data[2], 0, 4, 0, 100); + } + if (level > 100) level = 100;