My monitor speakers do not have an accessible on/off switch, so I have them wired to a WiFi smart plug (which I flashed with Tasmota). This application creates a tray icon that allows me to switch the speakers on and off. It also monitors the audio output, and if no sound output is detected for a while the speakers will be switched off. Since the speakers pull in around 100W each, this saves quite a bit of energy!
There is also an option to automatically change Windows' default audio output device when speakers are turned on and automatically turned off. In my case my display has (very poor) inbuild speakers, but they are still better than no audio.
- create and enter the virtual environment (name it
venv
for therun-in-background.bat
to work) - install the dependencies (
pip -r requirements.txt
) - copy
config-default.ini
toconfig.ini
, adjusting at least theBASEURL
- run
trayapp.py
, and potentially linkrun-in-background.bat
to yourshell:startup
directory.
It turns out it is impossible to receive Windows 10 shutdown notices from any application that is launched using pythonw.exe
. It seems the only solution to capture shutdowns is to use a Windows service. Hence service.py
contains a simple service that listens for shutdowns, standy and hibernation, and turns of the power to the speakers. It can also capture logoff and screen lock events, but these are currently not used.
- open the virtual environment in an elevated PS
- run
python venv\Scripts\pywin32_postinstall.py -install
(from SO) - run
python service.py --startup auto install
- open the Windows Services app to
- if the environment is installed in a home directory, the service needs to be started with that users' permissions
- start the service (or do this via
sc.exe start AutomaticSpeakerTurnOff
).
It seems that Windows 10 version upgrades remove the service. I had to repeat the four steps above when upgrading to 2004.
- pywin32 has changed how services are called / installed in a non-backwards compatible manner. Should upgrade at some point!
- investigate mhammond/pywin32#1450 (comment) - maybe we don't need the
sys.path.insert
logic