Shows the battery level of wireless devices in the Windows system tray. Each device gets its own icon: a battery ring with the device pictogram in the middle. No Synapse or other vendor software required.
While charging, the arc slowly "breathes":
Tested on real hardware:
| Device | Connection | How the battery is read |
|---|---|---|
| Razer Barracuda Pro (2.4 GHz) | 2.4 GHz dongle (1532:053a) | Its receiver publishes two collections and neither answers the standard Razer mouse request this app sends. The headset speaks the "PA" protocol instead: 64-byte vendor frames, P,A out and P,I back, battery command 0x21 with the level in the reply's data byte, charging 0x2A. Decoded from a USBPcap capture of Razer Synapse on a real unit (it read 34%), then confirmed on hardware with @phl23's own Barracuda Pro: the level tracks (27% at the test), charging follows the charger, and a switched-off headset reports "no link" rather than a stale value. Over Bluetooth Windows reports the level itself. |
| Razer BlackShark V2 Pro (2023) | 2.4 GHz receiver (1532:0555) | The headset's own "PA" protocol: output reports 0x02 on the vendor interface 0xFF00, remote mode 0xE1, commands 0x21 (battery) and 0x2A (charging) |
| WLmouse Beast X Max | 8K receiver (36A7:A880) and USB cable | Feature request 02 02 00 83; if there is no reply, the mouse heartbeat is used. Receiver and cable share one icon |
| G-Wolves WARG, HTS Plus (Pro), HTXU, Lycan, Fenrir Pro / Asym, HTX Mini | 8K receiver (33E4:3854) or USB cable | The same feature report exchange as the WLmouse mice (00 00 02 02 00 83 out, a1 ... 83 <charging> <battery%> back), which G-Wolves' web driver mouse.xyz uses for every mouse on this receiver. The request goes only to the collection that Windows reports with a 64-byte feature report (HidP_GetCaps), as the web driver chooses it. A sleeping mouse keeps its last value on a greyed icon. Unverified - no G-Wolves mouse was on hand |
| LAMZU Maya X | 8K dongle (373E:001E) or USB cable (373E:001C) | The same feature report exchange as the WLmouse and G-Wolves mice (00 00 02 02 00 83 out, a1 00 02 02 00 83 <charging> <battery %> back), on the vendor collection ffff:0000 of interface 2 only; protocol from Sheroune/lamzu-battery-monitory (MIT). Unverified on hardware here |
| Razer Basilisk V3 Pro, Razer Basilisk Ultimate (tested by users) | 2.4 GHz receiver | The standard Razer 90-byte feature report, as used by Synapse and OpenRazer: power class 0x07, commands 0x80 (battery) and 0x84 (charging) |
| Razer DeathAdder V4 Pro | 2.4 GHz receiver (1532:00BF) | Same mice protocol: transaction id 0x1F, command class 0x07, command 0x80 answers 02 1f 00 00 00 02 07 80 00 ab, and raw 0xAB = 171/255 = 67%, stable across polls and unchanged while Synapse runs. Idle, the mouse answers status 04 and keeps its last level on a greyed icon |
| Audeze Maxwell | 2.4 GHz dongle (3329:4B19) and USB-C cable (3329:4B1A) | The vendor collection (usage page 0xFF13): the sequence HeadsetControl uses, whose answer carries the battery as attribute 0x0CD6 (05 5D <len> 00 D6 0C <percent>). One packet is enough — the query for that attribute is answered with the marker on its own (0.19 s against 1.48 s for the whole sequence) — with the full sequence as the fallback. Dongle and cable are one headset and share one icon; charging is inferred from the cable answering, so the icon breathes while it sits on USB-C. With the headset switched off the dongle keeps answering with the last value it held, so the provider goes by the dongle's own product string — "Audeze Maxwell Dongle" with no headset linked, "Audeze Maxwell HID" with one — and reports nothing: the icon leaves the tray the way any switched-off device does |
| MCHOSE M7 Ultra | 2.4 GHz receiver (5253:1020) | The vendor collection (usage page 0xFF01; the sibling 0xFF0B never answers): feature report 0x11 (the shorter report, tried first) or 0x12 with command 0x06, every payload byte inverted, which returns 53 52 31 00 02 05 07 00 09 64 00 64 — vid 0x5253, model 0x31, firmware, flags, then the level and the charging byte (1 while charging). The request has to be repeated for each read, and the receiver only relays a real value while the mouse is awake: asleep it answers with zeros, so a silent mouse keeps its last level on a greyed icon. On the cable the mouse answers on its own PID (5253:0031, the number it reports as its model id) and the receiver goes quiet: both connections share one icon, and whichever one reports charging wins |
| MCHOSE G7 | USB (A8A5:2255, chip 'YJX-CHIP') | A different chip from the M7 Ultra, and a different protocol: a 65-byte output report 00 55 30 A5 0B 2E 01 01 01, answered by an input report starting AA 30 whose byte 8 is the level and byte 9 the charging flag. Written from @kek353's own monitor and the device dump in #8; only its 0xFF01 vendor collection is written to. Confirmed on @kek353's G7, which answers aa 30 a5 0b 0a 01 01 01 2e 00 00 00 — 46%, not charging, the same level their own tool shows — and again on its cable (aa 30 a5 3c 0a 01 01 01 2e 01 00 00, byte 9 = 1 while charging) with the PID unchanged, so a G7 keeps one icon on the dongle or on the cable. Only the AA 30 header is relied on: byte 3 differs between the two (0x0b against 0x3c). A level out of range is refused rather than shown |
| MCHOSE A7 V2 Ultra | 2.4 GHz receiver (3837:100B, RealTek strings) | The same protocol as the M7 Ultra on MCHOSE's newer vendor id, which the reference driver treats identically: the diagnostics in #4 show the same interface shape (collections 0xFF0B:0x104 and 0xFF01:0x01 on interface 2). The status read is documented on the shorter 0x11 report, so both report ids are tried, and the mouse is named from the receiver's own product string. Icon of its own, so it and an M7 Ultra stay two devices. Unverified — no A7 V2 Ultra was on hand, so a level out of range is refused rather than shown |
| HyperX Cloud II Wireless | 2.4 GHz dongle (03F0:0696, and 03F0:018B on the newer dongle revision) | The vendor collection, picked by usage page rather than position (0xFF90:0x0303): the dongle carries four collections on the one interface, so the first one is not the right one. A 52-byte output report 06 ff bb <command> 00 is answered by 20 bytes echoing the command: command 0x02 carries the level in byte 7 (voltage in bytes 5-6), command 0x03 reports charging in byte 4 - the same exchange HeadsetControl uses for these two product ids. Unverified - no Cloud II Wireless was on hand, so a reply that does not echo the command is ignored and a level above 100 refused rather than shown |
| HyperX Cloud III Wireless | 2.4 GHz dongle (03F0:05B7, and 03F0:0C9D which the reference also lists) | A different protocol from the Cloud II: the vendor collection is 0xFF13:0x0001, a 62-byte 66 <command> 00 ... packet goes out (0x66 is the report id) and 62 bytes come back whose second byte is either the command echo or the matching response id - 0x89/0x0D carries the level in byte 4 (only when byte 2 or 3 is non-zero), 0x8A/0x0C carries charging in byte 2 (0 not charging, 1 charging, 2 fully charged). Taken from LennardKittner/HyperHeadset, which lists this product id; that project also documents that some HyperX dongles accept these packets as feature reports only on Windows (write() fails with "Incorrect function" and the packet is retried with send_feature_report, which the diagnostics say either way). Unverified on hardware - no Cloud III Wireless was available here |
| GameSir G7 Pro; FlyDigi Vader Pro (tested by users) | 2.4 GHz receiver (shows up as an Xbox controller) | Windows.Gaming.Input battery report: exact percentage and charging state. XInput is the fallback (four levels only) |
| Sony DualShock 4 (PS4) | USB cable and Bluetooth (054C:09CC) | Read straight from the HID input report: exact percentage and charging state (USB byte 30, Bluetooth full report byte 32). Over Bluetooth, see the note below the table |
| Sony DualSense (PS5) | USB or Bluetooth | Read straight from the HID input report (USB byte 53, Bluetooth full report byte 54). Over Bluetooth, see the note below the table |
| Lofree Hyzen | 2.4 GHz dongle (388D:0025) | The transaction Lofree's own web driver (hyzen.lofree.tech) uses, on report 0x04 of the vendor collection 0xFF1C:0x92: start (00 00 01), the command, end (00 00 02), each acknowledged in byte 2. Command AA asks if the keyboard is online, command 1A returns the level in byte 7. As in the web driver, only the dongle is read, and not while the same keyboard is on its cable; no charging state. Unverified - no Lofree keyboard was on hand |
| Nintendo Switch Pro Controller, Joy-Con (L) / (R) | Bluetooth (057E:2009, 2006, 2007) | Byte 2 of the controller's own input report: level 0-8 in steps of 2 (full, medium, low, critical, empty) and the charging bit, shown as SDL shows it (level / 8, so 100 / 75 / 50 / 25 / 0 %) with the level name in the tooltip. When Steam has put the controller in the full mode, the 0x30 reports carry the byte and nothing is written; otherwise one read-only subcommand (0x02, request device info) is sent and its 0x21 reply carries the byte. The controller mode is never changed. USB is not read (the controller charges there). Unverified - no Switch controller was on hand, so a level above 8 is refused rather than shown |
ASUS ROG Gladius III Aimpoint and other ROG / TUF wireless mice (list in providers/asus.py) |
2.4 GHz receiver or USB cable (for example 0B05:1A72) | The battery command G-Helper uses: output report 0 12 07 (65 bytes) on the vendor collection of interface 0, answered by a report echoing 12 07 with the battery in byte 5 (a percentage, or a level 0-4 on older models such as the Chakram and Keris Wireless) and charging in byte 10. 0 without charging is standby, not empty, so it shows nothing; ff aa (command not known) and an all-zero reply are not read as a level. Receiver and cable share one icon. The OMNI receiver and models with other layouts are not included. Unverified - no ASUS mouse was on hand |
| Logitech G502 LIGHTSPEED, G502 X PLUS | Lightspeed receiver (046D:C539, 046D:C547) | HID++ 2.0 on the receiver's vendor interface: the device name (feature 0x0005) and the first battery feature the device supports (0x1004 unified battery, 0x1000 battery status or 0x1001 battery voltage; the G502 LIGHTSPEED reports voltage, converted to % with the Li-ion curve used by Solaar, the G502 X PLUS the unified battery percentage). The icon follows the device's unit id (feature 0x0003). Works alongside G HUB |
| SteelSeries Arctis Nova 7 | 2.4 GHz dongle (1038:22A1) | Output report 00 b0 on interface 3 (usage page 0xFFC0); the reply carries the level and the status (off / charging / on battery), as documented by HeadsetControl. Works alongside SteelSeries GG. The other Nova 7 variants and the Nova 5 / 5X use the same request and are included, but not tested |
SteelSeries Arctis Nova Pro Wireless (1038:12E0, 1038:12E5 X) |
Wireless base station, interface 3 or 4 | The same b0 exchange as the other Nova headsets, asked for with report id 06 instead of 00, as HeadsetControl asks for these base stations: the level is a nine-step code in byte 6 (shown as "about NN%") and the state in byte 15 (01 off / out of range, 02 cable charging, 08 on battery). A reply with any other state byte, a level code above 8 or fewer than 16 bytes is refused rather than shown. The request goes only to a vendor collection of these two ids; the diagnostics in #41 show 1038:12e5 exposing ffc0:0001 on interface 4 (plus a second vendor collection ff00:0001 there), so both are tried and the answering one is remembered. The reply layout is HeadsetControl's - not yet seen on hardware here |
| SteelSeries Rival 3 Wireless | 2.4 GHz dongle (1038:1830) | The mouse exchange on the same interface and the same 0xFFC0 configuration collection as the headsets, but not the b0 request: a 64-byte 00 aa 01 ... out, answered by a report carrying the level. The two references disagree about the reply and neither has been on hardware here, so both shapes are read: a reply that echoes aa (level in byte 1, charging in byte 3, as yurtemre7/steel-mouse reads it) and a 3-byte reply read the way flozz/rivalcfg does (level in byte 0, charging in byte 2, the same request and the same hidapi read). A leading report id byte of 0x00 is skipped, a level above 100 is refused in both shapes, and in the 3-byte shape the charging byte has to be 0 or 1 so a stray report cannot pass as a level - the diagnostics print the raw reply and say which shape was used. The collection is picked by usage page 0xFFC0 rather than by interface number, because the Rival 650 has it on interface 0 (rivalcfg issue #202). Works alongside SteelSeries GG; the Gen 2 revision (1038:1872) is included untested |
| SteelSeries Aerox 3 Wireless | 2.4 GHz dongle (1038:1838) | The receiver's battery query: it flags its configuration opcodes with 0x40 over their wired values, so the wired 92 stays silent and a 64-byte 00 d2 ... is answered by a report echoing d2. The level byte is the charging flag in bit 7 plus a 1..21 step value (or a direct percentage above 21), as yurtemre7/steel-mouse decodes it; the interface and the product id come from alloyctl's reverse engineering of this exact id, cross-checked against the capture notes at gort818/aerox3-wireless. A level byte of 0 means off or asleep rather than empty, and the 2.4 GHz link sleeps when the mouse is idle - it wakes on the next movement, so a poll that lands on a sleeping mouse simply shows nothing. Works alongside SteelSeries GG; the CS2 Dragon Lore edition (1038:1878) shares the protocol and is included untested The Aerox 5 Wireless (1038:1852, 185C, 1860) and Aerox 9 Wireless (1038:1858, 1874) in 2.4 GHz mode use the same battery exchange in rivalcfg (0x92 with the wireless flag 0x40, level (value - 1) * 5); the level is confirmed on an Aerox 9 Wireless by @AJD00m in #79 (d2 04 ... = 15 %, the same as SteelSeries GG), the charging bit is not tested yet |
| JBL Quantum 910 Wireless | 2.4 GHz dongle (0ECB:2088) | The receiver exposes one vendor collection, ff13:0001 (interface 5 on a real unit), and the headset pushes its own reports there; there is no request to send. The battery arrives as report 0x08 with the level in byte 1 - the pattern plugato/JBL_Baterry_Monitor confirmed on this USB id - and report 0x2f is the microphone mute state. The headset can stay quiet for long stretches, so the last level heard is kept and shown greyed out until something arrives. Confirmed on a real unit: the provider finds the receiver, matches its collection and shows the level as soon as the headset reports. That report is an event - on the unit tested it arrives when the headset is plugged into its charger (a capture read 95% at the moment JBL's own app said 95%), and pressing the buttons or the volume rocker does not produce it - so the last level heard is kept and shown greyed out until the next one. The receiver also pushes a power report (0x09 - byte 1 is 0x00 when the headset is switched off and 0x01 when it is on, confirmed on a real unit - plus a 0x02 frame); none of them is a level, and a headset last seen switched off says so in the diagnostics rather than only "nothing heard" |
| Keychron Ultra-Link 8K, Keychron M5 | 2.4 GHz receiver (3434:D028) and USB cable (3434:D048) | Keychron's vendor protocol on interface 4: a 64-byte feature report b3 06 (status), answered by a 64-byte input report b4 06 whose byte 20 is the level, retried up to three times. From csutcliff/keychron-battery-dkms, which implements it for these two ids. Unverified - no Keychron device was on hand, so a level above 100 is refused rather than shown |
| Pulsar X2 V2 Mini, ATK VXE R1 SE+, VXE R1 Pro Max | 2.4 GHz dongle (3554:F508, 373B:1085, 3554:F58A) and USB cable (3554:F507, 3554:F58F, 3554:F58C) | 17-byte big-endian frames, report id 0x08: command 0x04 asks for the power details and answers with the level in byte 6, the on-cable flag in byte 7 and millivolts in bytes 8-9, with a checksum (0x55 minus the sum of the first 16 bytes) in byte 16. From andrewrabert/python-pulsar-mouse-tool, which also backs the "HID: pulsar" driver in review for Linux; the Kysona M600 and VXE Dragonfly R1 Pro use the same protocol but their ids are not claimed here. The ATK/VXE control panel of the OpenMouse project (@openmouse/protocol, drivers/atk) lists the R1 Pro Max receiver as 3554:f58a and reads it with the same command 0x04 frame, opening the collection with usage page 0xFF02 and usage 0x0002 - the R1 Pro Max dongle has five other interface-1 collections and the first of them is not the one that answers, so that collection is now preferred; a collection whose output report cannot carry the 17-byte frame is skipped, because Windows refuses that write and the refusal looks exactly like a device that is switched off. The framing is also in G-Wolves' own web driver (mouse.xyz), whose Compx class sends the same report-0x08 frame with a checksum of 0x55 minus the sum of the payload. The R1 Pro Max is confirmed on hardware on both of its transports, by the reporter of #87: this provider read the mouse on its stock 1 kHz receiver, on the ff02:0002 collection, and on its cable the level agreed with ATK's own panel (hub.atk.pro) with the charging flag following the cable in both directions, so the cable id (3554:F58C) is read on hardware as well rather than only claimed from their report. A frame whose checksum does not match is refused rather than shown |
| Bluetooth devices, tested on the 1MORE SonoFlow headset (users also report Audio-Technica and JBL Tune 760NC headphones working) | Bluetooth (on by default, can be turned off in the menu) | The level Windows itself knows (DEVPKEY_Bluetooth_Battery). Only devices connected right now are shown: the link state comes from WinRT (BluetoothDevice.ConnectionStatus, the same source as Windows Settings). A device that is also read over HID keeps one icon: the HID reading wins and the Bluetooth copy is dropped |
| Astro A50 Gen 5 (Logitech 046D:0B1C) | Base station | The station's own vendor collection (usage page 0xFF32 / usage 0x0074): 64-byte reports, report id 0x02, 02 0c <len> 00 <cmd> <handle>. Battery command 0x06 answers with the level in byte 6 and byte 8 set while the headset sits on the dock (charging). The protocol is HeadsetControl's, reverse-engineered from G HUB captures and verified on this USB id; it is neither HID++ nor the A50 X's Centurion protocol. Unverified - no A50 was on hand, so a level out of 0..100 is refused rather than shown |
| Corsair Void v2 Wireless, Virtuoso Max Wireless, HS80 Max Wireless | Wireless receiver (1B1C:2A08, 1B1C:2A02, 1B1C:0A97) | The receiver's vendor collection on interface 4: 65-byte writes 00 02 <endpoint> 02 <cmd>, endpoint 0x08 the receiver and 0x09 the headset, and 64-byte replies. After a minimal wake handshake (the one HeadsetControl uses, which avoids the pop of switching the headset into software mode), battery command 0x0F answers with a 16-bit value in hundredths of a percent at bytes 4-5. Unverified - no Corsair headset was on hand; the receiver sometimes answers with something other than a level, so that is retried and then refused rather than shown |
PlayStation controllers over Bluetooth: a DualShock 4 or DualSense sends its battery level over Bluetooth only in its "full report" mode. Switching a controller into that mode makes it invisible to games that use DirectInput until it is turned off and on again (#96), so the app does not switch it: the level shows while Steam or a game has already put the controller in that mode, and otherwise the icon shows the controller without a level. If you do not play such games, turn on Preferences > PlayStation full mode (Bluetooth) to always see the level. Over USB the level is always shown.
Support for other devices is not guaranteed. The code already reads the other Razer wireless mice whose battery OpenRazer reads (Pro Click, Pro Click V2 and V2 Vertical, Naga, Viper, DeathAdder, Basilisk, Mamba, Lancehead and others; the list is KNOWN in providers/razer.py), includes protocols for some other WLmouse models, should read most other Logitech HID++ 2.0 mice and keyboards on a Lightspeed or Unifying receiver as well as the Logitech G533 / G535 / G633 / G635 / G733 / G933 / G935 / G PRO / G PRO X headsets and the other Arctis Nova 7 and Nova 5 models, reads the older Arctis 1 / 7 / 9 / Pro Wireless / 7+ and GameBuds the way HeadsetControl documents them, reads other Xbox-compatible controllers the same way as the GameSir G7 Pro and works with any Bluetooth device whose battery level Windows reports, but these have not been tested. New devices are added based on feedback and diagnostics logs: if yours is not detected or shows a wrong level, open an issue and attach the diagnostics report (see Troubleshooting).
Two limitations of the Maxwell support are worth stating rather than leaving to be discovered. Two Maxwells on one machine share a single icon: both endpoints report the serial 0000000000000000, so nothing distinguishes them over HID and only the first one is read. And the Xbox cable PID (3329:4B1E) is derived from the Xbox dongle (3329:4B18) by the same +1 offset that separates the PC dongle 3329:4B19 from its cable 3329:4B1A — it has not been measured against an Xbox model, so an Xbox cable may be read as 3329:4B18 and shown as not charging.
- Download
HaloBattery-<version>.zipfrom the Releases page. - Extract it somewhere permanent, e.g.
C:\Tools, so you getC:\Tools\HaloBattery\HaloBattery.exe, and runHaloBattery.exe. Keep the wholeHaloBatteryfolder together: the .exe needs the_internalfolder next to it. - Right-click the tray icon → Start with Windows.
The app checks GitHub for a new release once a day and, when there is one, adds Download vX.Y.Z… to the tray menu (it only opens the release page; nothing is installed for you). To update, close the app (tray menu → Exit) and replace the folder with the new one. If you used the old single-file HaloBattery.exe, delete it; Start with Windows follows the new copy automatically the first time you run it.
No Python or other dependencies required. Windows SmartScreen may warn about an unrecognized app on first launch, because the file is not code-signed: click More info → Run anyway. Some antivirus programs flag unsigned Python apps by mistake (typically a generic machine-learning detection with !ml in its name, such as Trojan:Win32/Sabsik.TE.A!ml). The release is built by GitHub Actions straight from this repository, and the build logs are public; if in doubt, run it from source (Option 2).
- Install Python 3.10+ with Add python.exe to PATH checked.
- Download or clone this repository somewhere permanent, e.g.
C:\Tools\HaloBattery. - Run
install_and_run.bat. - Right-click the tray icon → Start with Windows.
To build it yourself, run build_exe.bat; the result is the dist\HaloBattery folder with HaloBattery.exe inside.
Releases are built automatically: pushing a tag like v1.8.0 makes GitHub Actions build Halo Battery on Windows and attach HaloBattery-<version>.zip to the release (see .github/workflows/release.yml).
The icon is a battery ring with the device pictogram in the middle. The arc fills clockwise from the top.
- Centre: a headset, a mouse, a keyboard (a keycap with a K), an Xbox or PlayStation controller, or the Bluetooth rune. The pictogram can be turned off in the menu.
- Normal arc uses the taskbar colour: white on a dark taskbar, black on a light one. With MyDockFinder running, the colour follows its top menu bar instead, which switches with the wallpaper. With a transparent taskbar (e.g. TranslucentTB) pick Icon colour → White or Black in the menu.
- Amber arc: the level is close to the alert threshold. Red: at or below it.
- Green arc that slowly "breathes": charging. The animation can be turned off in the menu, leaving a plain green arc.
- Translucent icon: the mouse is asleep; it keeps its last level for 5 minutes. A device that is switched off disappears from the tray and comes back when it is switched on.
Hover over the icon to see the exact percentage. The low battery notification fires once and only again after the device has been charged.
Right-click a device icon to open its menu. It looks like a Windows 11 menu (acrylic background, rounded corners, the light or dark app theme) and is sharp at any display scale. If it does not work on your PC, set "fluent_menu": false in %APPDATA%\HaloBattery\config.json to get the classic Windows menu back.
- Rename…: give the device your own name (for example, two controllers with the same name). Reset name goes back to the device's own name.
- Icon: pick the pictogram of this device (Automatic, Mouse, Keyboard, Headset, Controller or Bluetooth), for example a controller over Bluetooth that shows the Bluetooth pictogram.
- Hide this device: remove its icon, for example for a controller that always reports 100%.
- Refresh now
- Preferences:
- Poll interval (15 s to 5 min) and Low battery alert (off, 10–30%): change them with the − and + buttons or the mouse wheel, the menu stays open
- Alert when fully charged (a notification once per charge, on by default)
- Windows Bluetooth devices, Device pictogram, Charging animation
- PlayStation full mode (Bluetooth) (off by default): always read the battery of a PS4 / PS5 controller over Bluetooth. Some games stop seeing the controller in that mode until it is turned off and on
- Icon colour: Automatic (the Windows theme, or MyDockFinder's menu bar while it is running), White or Black
- Start with Windows (per-user registry key, no admin rights needed)
- Check for updates: once a day, on by default; a notification and a Download vX.Y.Z… item appear when a new release is out
- Hidden devices (only when a device is hidden): click a device to show it again
- Diagnostics…: writes a detailed report and opens it
- Close Synapse, the WLmouse web driver and other battery tools: they may hold the receiver.
- Wake the mouse up by moving it.
- Run
probe.bator choose Diagnostics… from the tray menu. The report lists every HID device and the raw protocol replies. Attach it to an issue in this repository to get a new device supported. The report contains Bluetooth MAC addresses and device serial numbers; you may want to redact them before posting. - "python312.dll was not found", or Start with Windows says the app runs from a temporary folder: the app was started straight from the ZIP, or only
HaloBattery.exewas copied out of it. Extract the whole ZIP to a folder of its own (the_internalfolder must stay next to the .exe) and runHaloBattery.exefrom there.
Settings, the log and the diagnostics report live in %APPDATA%\HaloBattery.
The WLmouse protocol was reverse-engineered by @len0c (incconutwo/mouse-battery-tray, MIT). The MCHOSE protocol comes from the write-up by @alexfrih (alexfrih/mchose-linux, recovered from MCHOSE's own web driver), with the details this mouse forced noted in providers/mchose.py. The MCHOSE G7 protocol comes from @kek353's own monitor and the device dump they posted in #8. The BlackShark V2 Pro 2023 protocol comes from the OpenRazer driver (PR #2862). Razer PIDs and transaction IDs come from OpenRazer and RazerBatteryTaskbar.
MIT, see LICENSE.
