Add .gitignore, GitLab CI pipeline with test/lint/build/release stages, project documentation (README, LICENSE, CHANGELOG, CONTRIBUTING, SECURITY), PyInstaller packaging configuration with icon and version info, Python project configuration with dependencies, and complete application source including battery provider, device discovery, settings management, UI components, startup control, and comprehensive test suite
Logitech Battery Widget
An open-source Windows tray widget that displays battery information for connected Logitech mice, keyboards, and headsets. It discovers devices locally through HID and attempts a read-only Logitech HID++ battery query. Multiple devices are shown together. If Windows or a device does not expose a battery value, the widget says so instead of guessing.
Screenshot placeholder: A project screenshot will be added under
docs/screenshot.pngafter the first signed release build is visually verified on Windows 11.
Trust and privacy
- No network access, telemetry, analytics, updater, advertising, or runtime downloads.
- No administrator rights or UAC prompt.
- No hidden startup entry. "Start with Windows" changes only the current user's registry after an explicit click, and can be disabled from the same menu.
- The complete source and reproducible GitLab CI recipe are public so the behavior can be audited.
- Settings and logs stay in the documented per-user Windows folders.
See SECURITY.md for the full security model.
End-user installation
- Download
LogitechBatteryWidget.exefrom a GitLab release or build artifact. - Optionally verify its SHA-256 value against
LogitechBatteryWidget.exe.sha256. - Run the EXE. It is portable and does not install a service or driver.
- Use the tray menu to refresh, hide the widget, change settings, or explicitly enable startup.
The executable is produced by PyInstaller. Some antivirus products heuristically flag unsigned PyInstaller one-file programs. This can be a false positive; verify the checksum, inspect the CI job and source, or submit the file to VirusTotal. A detection should still be investigated rather than automatically ignored.
Local development
Requires Python 3.12+.
py -3.12 -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
python -m logitech_battery_widget.main
pytest
ruff check .
On Linux and macOS the UI starts with clearly named demo devices. This makes UI development possible without pretending that real Logitech hardware was detected.
Build
On Windows:
python -m pip install -r requirements.txt
pytest
ruff check .
pyinstaller --clean --noconfirm packaging/pyinstaller.spec
Get-FileHash dist/LogitechBatteryWidget.exe -Algorithm SHA256
The result is dist/LogitechBatteryWidget.exe, a console-free, UPX-disabled one-file executable.
GitLab CI executes the same dependency installation, tests, lint, and PyInstaller command on a
Windows runner and publishes the EXE plus checksum. Builds fail when tests fail.
Reproducible builds
- Check out the same commit on a clean Windows machine or isolated Windows runner.
- Install Python 3.12 and the exact packages from
requirements.txt. - Run the commands in Build.
- Compare the SHA-256 result. Exact bytes also depend on the same Python patch version, Windows SDK/runtime, and PyInstaller version; the GitLab job log records that environment.
No file is downloaded by the application itself. Dependency retrieval happens only while preparing the build environment.
Configuration
%APPDATA%\LogitechBatteryWidget\config.json contains:
| Key | Type | Meaning |
|---|---|---|
theme |
string | system, light, or dark |
always_on_top |
boolean | Keep the widget above normal windows |
window_x, window_y |
integer/null | Last widget position |
refresh_interval_seconds |
integer | Refresh period, clamped to 15-3600 |
log_level |
string | DEBUG, INFO, WARNING, ERROR, or CRITICAL |
Logs rotate at %LOCALAPPDATA%\LogitechBatteryWidget\logs\app.log (1 MB, three backups).
Device compatibility
Logitech exposes different protocols across receivers, Bluetooth devices, and product generations.
The widget supports HID++ battery features 0x1000 and 0x1004. A detected device can therefore
appear with N/A when its interface, firmware, Bluetooth stack, or receiver does not expose either
feature. Contributions with tested protocol captures are welcome; do not include serial numbers.
License
MIT. This project is independent and is not affiliated with or endorsed by Logitech. Logitech is a trademark of its respective owner.