| .gitignore | ||
| a | ||
| AGENTS.md | ||
| luz-musica.py | ||
| Makefile | ||
| music-light.env.example | ||
| README.md | ||
| requirements.txt | ||
music-light
luz-musica.py changes a Home Assistant light to match the active media artwork.
Requirements
python3python3-venvplayerctl- Python packages from
requirements.txt
On Ubuntu/Debian:
sudo apt-get update
sudo apt-get install -y python3 python3-venv playerctl
Setup
Create a virtual environment and install dependencies:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
pip install -r requirements.txt
Configuration
For local runs, edit the constants at the top of luz-musica.py or export environment variables:
HA_URLHA_TOKENLIGHT_ENTITY
You can also tune:
BRIGHTNESS_PCTSATURATION_BOOSTMIN_SATURATIONMIN_VALUEREQUEST_TIMEOUT
Network control settings:
CONTROL_HOST: bind address for the control API, default0.0.0.0CONTROL_PORT: bind port for the control API, default8765CONTROL_TOKEN: optional shared token required for control requests
Run
source .venv/bin/activate
python luz-musica.py
Or use the Makefile:
make run
Ubuntu User Service
Install and start the script as a systemd --user service:
make install-service
The install target:
- creates
.venvand installsrequirements.txt - copies
music-light.env.exampleto~/.config/music-light/envif it does not exist - writes
~/.config/systemd/user/music-light.service - enables and starts the service
Edit the service environment file with your Home Assistant settings:
nano ~/.config/music-light/env
make restart-service
Manage the service with:
make status-service
make logs-service
make restart-service
make stop-service
make start-service
Remove the service:
make uninstall-service
This is installed as a user service because playerctl needs access to the desktop user's MPRIS session.
Home Assistant Control
The running script exposes a small HTTP API that Home Assistant can call over the local network:
GET /statusPOST /pausePOST /resumePOST /toggle
When paused, the systemd service stays running but the script stops changing the light. When resumed, it forces an update from the current track.
Example requests from another machine on the same network:
curl http://ubuntu-host:8765/status
curl -X POST http://ubuntu-host:8765/pause
curl -X POST http://ubuntu-host:8765/resume
curl -X POST http://ubuntu-host:8765/toggle
If you set CONTROL_TOKEN, include it as a header:
curl -X POST -H "X-Music-Light-Token: your-token" http://ubuntu-host:8765/toggle
Home Assistant configuration.yaml example:
rest_command:
music_light_pause:
url: "http://ubuntu-host:8765/pause"
method: post
music_light_resume:
url: "http://ubuntu-host:8765/resume"
method: post
music_light_toggle:
url: "http://ubuntu-host:8765/toggle"
method: post
With CONTROL_TOKEN:
rest_command:
music_light_toggle:
url: "http://ubuntu-host:8765/toggle"
method: post
headers:
X-Music-Light-Token: "your-token"
Create Home Assistant scripts so they can be shown as dashboard buttons:
script:
pause_music_light:
alias: Pause Music Light
sequence:
- service: rest_command.music_light_pause
resume_music_light:
alias: Resume Music Light
sequence:
- service: rest_command.music_light_resume
toggle_music_light:
alias: Toggle Music Light
sequence:
- service: rest_command.music_light_toggle
Then add script.pause_music_light, script.resume_music_light, or script.toggle_music_light to a Home Assistant dashboard as button cards.
Troubleshooting
- If nothing is playing, or
playerctlcannot read metadata, the loop sleeps and retries. - If
mpris:artUrlis missing, the script logs it and waits for the next track change. - If Home Assistant is unreachable or returns an error, the script logs the exception and retries.
- If the service cannot see the media player, make sure it is running under the same logged-in desktop user.
- If Home Assistant cannot reach the control API, check the Ubuntu host firewall and confirm
CONTROL_HOST=0.0.0.0.