Repository navigation
Preferences: "Sound with the low battery alert" (off by default), repeats every 5 min while low, for full-screen games (#66), unit tests - #137
Conversation
Preferences > "Sound with the low battery alert", off by default. When
the low battery alert fires, also play Windows' own "Windows Battery
Low.wav" ("Windows Battery Critical.wav" at 5 % or less) from
%WINDIR%\Media, asynchronously, with a system sound as fallback. It
repeats every 5 minutes while the device stays at or below the alert
level, awake and off the charger. The decision is a pure helper,
low_battery_sound(), covered by unit tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QmGsnjgXs8VbKmmxLkPsf6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QmGsnjgXs8VbKmmxLkPsf6
|
Thanks for this! PR #107 and a batch of other PRs were just merged into main (the listen-only PlayStation handling from e80dfd1 is kept, and |
|
Trial-merged against today's
Suite passes with that (443 tests, including the new sound test). |
Resolved CHANGELOG.md (bullet under Unreleased/Added), README.md, the Preferences menu and its order test: "Sound with the low battery alert" goes after main's "Estimated time left" and "Quiet while gaming". The sound uses main's per-device level (low_for), is reset with the alert when a device is hidden, its type turned off or its level changed, and still plays while Quiet while gaming holds the notification (new tests for both). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QmGsnjgXs8VbKmmxLkPsf6
|
Merged |
This change adds an optional sound to the low battery alert (#66). The option is Preferences > Sound with the low battery alert. It is off by default, so the app does not change for current users. When the option is on, the low battery alert also plays a Windows sound. The sound plays again every 5 minutes while the device stays low.
1. Why
Users in full-screen games do not see the low battery notification. Example: a user plays a full-screen game with a wireless headset at 25 %. The level drops to 20 %. The app shows the "Low battery" notification, but the game hides it. The user does not know about the low battery until the headset turns off.
2. Change
halo_battery.pyw:low_soundinDEFAULTS(defaultFalse).load_config()accepts only a boolean for it, as for the other switches.pystraymenu.low_battery_sound(level, charging, online, low, last, now). It returns"low","critical"orNone. It returns a sound when the device is at or below the alert level, online and not charging, and when no sound played in the lastLOW_SOUND_REPEAT(300 s). AtCRITICAL_LEVEL(5 %) or below, it returns"critical".play_low_sound(kind). It plays%WINDIR%\Media\Windows Battery Low.wavorWindows Battery Critical.wavwithSND_FILENAME | SND_ASYNC | SND_NODEFAULT. If the file is missing, it plays theSystemExclamationorSystemHandalias withSND_ALIAS | SND_ASYNC.SND_ASYNCmakes sure that the poll thread does not wait. An error fromwinsoundgoes to the log only.App.check_alert()calls the newApp.check_low_sound()after the existing notification code. The first sound plays together with the notification. When the device charges or goes above the alert level + 5 % (the existing re-arm rule), the repeat timer resets. The sound stops when the device charges, goes above the alert level, goes offline or goes away, or when the user turns the option off.README.md: the new item is in the Preferences list of "Tray menu".CHANGELOG.md: entry under[Unreleased]>### Added.Not in this change (possible follow-up): a custom sound file, and the "3 times at a 1 minute interval" repeat for the critical level from the issue. The repeat interval is a constant, not a setting.
Overlap with #107 (open): #107 changes
check_alert()(per-device alert levellow_for(st), andself.notify()holds notifications while a game is full screen). #107 does not add a sound. A trial merge of this branch with #107 mergescheck_alert()without a conflict, andcheck_low_sound()then uses the per-device level. The sound does not go throughself.notify(), so "Quiet while gaming" does not hold it. This is the purpose of #66. The only new conflict is in the Preferences item list, next to "Alert when fully charged", where #107 adds "Estimated time left" and "Quiet while gaming".mainand #107 already conflict in the same block.3. Tests
New file
tests/test_low_sound.py:LowSoundDecisionTests(the pure helper):test_repeat_is_five_minutes,test_first_alert_plays_the_low_sound,test_repeats_after_five_minutes,test_not_before_five_minutes,test_critical_sound_at_5_percent_or_below,test_no_sound_while_charging,test_no_sound_above_the_threshold,test_no_sound_when_offline_or_level_unknown,test_no_sound_when_the_low_battery_alert_is_off.LowSoundWiringTests(winsoundreplaced by a mock):test_off_by_default,test_alert_plays_windows_battery_low_async,test_critical_level_plays_windows_battery_critical,test_missing_file_falls_back_to_a_system_sound,test_repeats_every_five_minutes_while_low,test_stops_when_charging_and_starts_again_after,test_stops_above_the_threshold,test_stops_while_offline,test_stops_when_the_option_is_turned_off,test_a_sound_error_does_not_break_the_poll,test_setting_is_in_preferences_and_toggles,test_setting_is_read_from_the_settings_file.tests/test_hide_rename.py: the test harness setslow_sound_at, and the pinned Preferences list has the new item.Suite:
python -m unittest discover -s tests: 262 tests, OK.Mutation check: 19 mutations of the new code (default on, each condition of the helper, the 300 s and 5 % constants, the flags, the fallback, the
try/except, the timer reset, the call incheck_alert(), the option check, the timestamp, the menu item). The new tests catch all 19.Manual check on Windows 11:
play_low_sound("low")returns in 0.002 s and plays the sound.Base and other PRs
mainate80dfd1. Closes Feature Request: Empty Battery Warning Sound Alert with a Repeat and Interval Feature #66.CHANGELOG.mdwith the other open PRs (the same[Unreleased]lines). With Tray: device type switches (#96), per-device alert level, time left, percentage icon, quiet while gaming (#76), status file; Audeze stuck dongle and 0% at power-on, unit tests #107: the Preferences list next to "Alert when fully charged", where Tray: device type switches (#96), per-device alert level, time left, percentage icon, quiet while gaming (#76), status file; Audeze stuck dongle and 0% at power-on, unit tests #107 adds its own items.check_alert()merges without a conflict, and then the sound uses the per-device alert level of Tray: device type switches (#96), per-device alert level, time left, percentage icon, quiet while gaming (#76), status file; Audeze stuck dongle and 0% at power-on, unit tests #107.