HomeAssistantWindowsVolumeSync is a lightweight Windows tray application that synchronizes the Windows system master volume with a Home Assistant media player. Whenever the volume changes in Windows, the application detects it and sends the updated value to a Home Assistant webhook in real time.
This allows Windows hardware volume keys, app volume sliders, and external volume knobs to directly control your media player volume through Home Assistant.
- Event-driven volume detection - no polling, near-zero CPU usage
- Instant sync - volume changes are sent immediately to Home Assistant
- System tray integration - convenient pause/resume controls from the taskbar
- Starts automatically with Windows - runs in the background via the Windows startup registry
- Configurable - easy webhook endpoint configuration via the Settings window
- Universal compatibility - works with any Home Assistant media player
- Modern architecture - built using .NET 8 with Windows Forms
The service includes a system tray icon that appears in your Windows taskbar notification area, providing easy control over the volume sync:
- Right-click the icon to access the menu:
- Status - Shows whether the service is running or paused
- Pause/Resume - Temporarily pause or resume volume synchronization
- Exit - Stop the service
- Double-click the icon to see a status dialog
When paused, the service continues to monitor Windows volume changes but does not send updates to Home Assistant. This is useful if you want to temporarily control your media player directly from Home Assistant without interference from Windows volume changes.
The project includes a Python script (create_icon.py) to generate the system tray icon based on the Material Design Icons home-sound-out icon:
python create_icon.pyThis creates both app.ico and app.png files in the src directory. The PNG version is used by the application for the system tray icon.
- A working Home Assistant instance
- A media player entity (example: a speaker)
- Remote or LAN URL reachable from Windows
- Windows 11 or later
- .NET 8 Runtime or newer (or use self-contained deployment)
You must create a Home Assistant automation that responds to a webhook and sets the media player volume.
- Create a webhook-based automation
- Use the webhook ID:
homeassistant_windows_volume_sync - Configure the automation to:
- Read the JSON body
{ "volume": <number>, "mute": <boolean>, "target_media_player": <string> } - Convert volume to 0.0–1.0 (the number is 0–100)
- Use the
target_media_playerfrom the payload (or default to your media player) - Call
media_player.your_media_player
- Read the JSON body
After creating the automation, your webhook URL becomes:
https://<your-ha-url>/api/webhook/homeassistant_windows_volume_sync
Replace <your-ha-url> with your HA local URL or Nabu Casa remote address.
An example automation YAML is provided in the /HomeAssistant/automation.yaml file.
HomeAssistantWindowsVolumeSync/
├── src/
│ └── HomeAssistantWindowsVolumeSync/
│ ├── HomeAssistantWindowsVolumeSync.csproj
│ ├── Program.cs
│ ├── VolumeWatcherService.cs
│ ├── SystemTrayService.cs
│ ├── IHomeAssistantClient.cs
│ ├── HomeAssistantClient.cs
│ ├── appsettings.json
│ └── app.ico
├── tests/
│ └── HomeAssistantWindowsVolumeSync.Tests/
│ ├── HomeAssistantWindowsVolumeSync.Tests.csproj
│ └── HomeAssistantClientTests.cs
├── HomeAssistant/
│ └── automation.yaml
├── .vscode/
│ ├── launch.json
│ ├── tasks.json
│ ├── settings.json
│ └── extensions.json
├── copilot-instructions.md
├── README.md
└── LICENSE
The application provides two ways to configure settings:
| Setting | Settings Window | appsettings.json | Description |
|---|---|---|---|
| Home Assistant URL | ✓ | ✓ | Your Home Assistant base URL (e.g., https://your-home-assistant-url) |
| Webhook ID | ✓ | ✓ | The webhook identifier (default: homeassistant_windows_volume_sync) |
| Target Media Player | ✓ | ✓ | Your media player entity ID (e.g., media_player.your_media_player) |
| Run on Startup | ✓ | Enable/disable automatic startup with Windows | |
| Webhook Path | ✓ | API webhook path (default: /api/webhook/) |
|
| Strict TLS | ✓ | Enable/disable strict TLS certificate validation (default: true) |
|
| Debounce Timer | ✓ | Time in milliseconds to wait after the last volume change before sending the update (default: 100) |
|
| Health Check Timer | ✓ | Interval in milliseconds between connection health checks (default: 5000 - 5 seconds) |
|
| Health Check Retries | ✓ | Number of consecutive health check failures before marking as disconnected (default: 3) |
Settings Window (right-click system tray icon → Settings):
- Provides a user-friendly interface for common settings
- Changes are saved automatically and applied immediately
- Best for general configuration
appsettings.json (manual editing):
- Allows access to all settings including advanced options
- Requires manual file editing
- Best for advanced configuration and fine-tuning
Note: Changes made through the Settings window are saved automatically and applied immediately.
{
"HomeAssistant": {
"WebhookUrl": "https://your-home-assistant-url",
"WebhookPath": "/api/webhook/",
"WebhookId": "homeassistant_windows_volume_sync",
"TargetMediaPlayer": "media_player.your_media_player",
"StrictTLS": true,
"DebounceTimer": 100,
"HealthCheckTimer": 5000,
"HealthCheckRetries": 3
}
}The service supports comprehensive logging with different log levels and outputs. Logging is configured through appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"HomeAssistantWindowsVolumeSync": "Debug",
"Microsoft": "Warning",
"System.Net.Http.HttpClient": "Warning"
},
"Console": {
"LogLevel": {
"Default": "Debug"
}
},
"EventLog": {
"SourceName": "HomeAssistant Windows Volume Sync",
"LogName": "Application",
"LogLevel": {
"Default": "Information"
}
}
}
}Log Levels (from most to least verbose):
Trace: Extremely detailed diagnostic informationDebug: Detailed information useful for debuggingInformation: General informational messages about application flowWarning: Potentially harmful situations or unexpected eventsError: Error events that might still allow the application to continueCritical: Critical failures that require immediate attention
Log Outputs:
- Console: Logs appear in console window (when running in Debug mode or interactively)
- Debug: Logs appear in debugger output window during development
- EventLog: Logs written to Windows Event Viewer (Application log) when running as a service
- Startup Error Log: Fatal startup errors are written to
startup-error.login the application directory
Recommended Settings:
- Production: Use
Informationlevel to balance detail with performance - Development: Use
DebugorTracelevel for detailed troubleshooting - Troubleshooting: Temporarily set to
DebugorTrace, then back toInformationwhen resolved
Viewing Logs:
- Console logs: Visible when running in Debug mode or via
dotnet run - Event Viewer logs: Open Event Viewer → Windows Logs → Application → Filter by source "HomeAssistant Windows Volume Sync"
- Startup errors: Check
startup-error.logfile in the application directory if service fails to start
dotnet build src/HomeAssistantWindowsVolumeSync/HomeAssistantWindowsVolumeSync.csprojdotnet publish src/HomeAssistantWindowsVolumeSync -c Release -r win-x64 --self-contained false -o publishThis generates the application executable and required files in the publish/ output folder.
When you first run the application, Windows may display a "Windows protected your PC" SmartScreen warning. This is a normal security feature for applications that are not yet digitally signed.
- The application is not code-signed with a commercial certificate
- Windows SmartScreen protects users from potentially unsafe downloads
- This warning appears for all unsigned applications, including open-source software
- When you see the SmartScreen dialog, click "More info"
- Click "Run anyway"
- The application will start normally
- This is open-source software - you can review all the code in this repository
- The application only communicates with your Home Assistant instance (URL you configure)
- No telemetry, no external connections, no data collection
- The source code is available for security audits
If you prefer, you can:
- Build from source - Clone this repository and build it yourself using the instructions below
- Review the code - Inspect all source files before building
- Check releases - All releases are built from tagged commits you can verify
We are working on:
- Building reputation with Windows SmartScreen over time
- Potentially code-signing future releases (requires certificate investment)
- Alternative distribution methods
If you're comfortable with open-source software and have reviewed the code, you can safely run this application.
Note: This is a system tray application — it does not install as a Windows Service. Autostart is managed via the Windows startup registry (
HKCU\...\Run), exactly like other tray apps. No administrator privileges or PowerShell commands are required.
-
Extract the release zip to a permanent folder, for example:
C:\Program Files\HomeAssistantWindowsVolumeSync\ -
Run
HomeAssistantWindowsVolumeSync.exe. -
Right-click the tray icon in the taskbar notification area and select Settings.
-
Fill in your Home Assistant URL, Webhook ID, and Target Media Player entity ID.
-
Check "Run when Windows starts" to enable autostart.
-
Click Save. You're done.
- Right-click the tray icon → Exit to stop the application.
- In the Settings window, uncheck "Run when Windows starts" and save — this removes the autostart registry entry.
- Delete the installation folder.
dotnet test tests/HomeAssistantWindowsVolumeSync.Tests/HomeAssistantWindowsVolumeSync.Tests.csproj- Logs appear in Windows Event Viewer → Application Logs
- Ensure the webhook URL in
appsettings.jsonis correct - Confirm the HA automation webhook ID matches
- Check firewall rules if using HTTPS internally
- The service logs at the following levels:
- Debug: Volume change events
- Information: Service lifecycle events
- Warning: Configuration issues, failed HTTP requests
- Error: Exceptions and critical failures
- .NET 8 SDK
- Visual Studio Code (recommended) or Visual Studio 2022
- Open the project folder in VS Code
- Install recommended extensions when prompted
- Use the provided tasks for building and testing
Press F5 in VS Code to build and run the application in debug mode.
MIT License - see LICENSE for details.