Add Ubuntu user service support
This commit is contained in:
parent
2b47db77eb
commit
0d61eb6311
5 changed files with 95 additions and 5 deletions
|
|
@ -10,6 +10,7 @@ This repo is a single Python script (`luz-musica.py`) that:
|
||||||
- System dependency: `playerctl` must be installed and your player must expose MPRIS metadata.
|
- System dependency: `playerctl` must be installed and your player must expose MPRIS metadata.
|
||||||
- Python deps: `requests`, `Pillow`.
|
- Python deps: `requests`, `Pillow`.
|
||||||
- Run: `python3 luz-musica.py`
|
- Run: `python3 luz-musica.py`
|
||||||
|
- Service install: `make install-service` creates and starts a `systemd --user` unit on Ubuntu.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
|
|
@ -27,6 +28,12 @@ Create a venv and install Python deps:
|
||||||
Then run:
|
Then run:
|
||||||
- `python luz-musica.py`
|
- `python luz-musica.py`
|
||||||
|
|
||||||
|
## Ubuntu service
|
||||||
|
- The service is installed as `~/.config/systemd/user/music-light.service`.
|
||||||
|
- The service loads optional environment overrides from `~/.config/music-light/env`.
|
||||||
|
- Use `make status-service`, `make logs-service`, `make restart-service`, and `make uninstall-service`.
|
||||||
|
- Keep it as a user service because `playerctl` needs access to the logged-in desktop user's MPRIS session.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
Edit constants at the top of `luz-musica.py`:
|
Edit constants at the top of `luz-musica.py`:
|
||||||
- `HA_URL`, `HA_TOKEN`, `LIGHT_ENTITY`
|
- `HA_URL`, `HA_TOKEN`, `LIGHT_ENTITY`
|
||||||
|
|
|
||||||
36
Makefile
36
Makefile
|
|
@ -1,7 +1,12 @@
|
||||||
PY ?= python3
|
PY ?= python3
|
||||||
VENV ?= .venv
|
VENV ?= .venv
|
||||||
|
SERVICE_NAME ?= music-light.service
|
||||||
|
SYSTEMD_USER_DIR ?= $(HOME)/.config/systemd/user
|
||||||
|
SERVICE_FILE := $(SYSTEMD_USER_DIR)/$(SERVICE_NAME)
|
||||||
|
CONFIG_DIR ?= $(HOME)/.config/music-light
|
||||||
|
ENV_FILE ?= $(CONFIG_DIR)/env
|
||||||
|
|
||||||
.PHONY: venv deps run
|
.PHONY: venv deps run service-env install-service uninstall-service start-service stop-service restart-service status-service logs-service
|
||||||
|
|
||||||
venv:
|
venv:
|
||||||
$(PY) -m venv $(VENV)
|
$(PY) -m venv $(VENV)
|
||||||
|
|
@ -13,3 +18,32 @@ deps: venv
|
||||||
run: deps
|
run: deps
|
||||||
$(VENV)/bin/python luz-musica.py
|
$(VENV)/bin/python luz-musica.py
|
||||||
|
|
||||||
|
service-env:
|
||||||
|
install -d $(CONFIG_DIR)
|
||||||
|
test -f $(ENV_FILE) || install -m 600 music-light.env.example $(ENV_FILE)
|
||||||
|
|
||||||
|
install-service: deps service-env
|
||||||
|
install -d $(SYSTEMD_USER_DIR)
|
||||||
|
printf '%s\n' '[Unit]' 'Description=Music Light album-art color sync' 'After=graphical-session.target' 'Wants=graphical-session.target' '' '[Service]' 'Type=simple' 'WorkingDirectory=$(CURDIR)' 'Environment=PYTHONUNBUFFERED=1' 'Environment=PLAYERCTL_BIN=/usr/bin/playerctl' 'EnvironmentFile=-%h/.config/music-light/env' 'ExecStart=$(abspath $(VENV))/bin/python $(CURDIR)/luz-musica.py' 'Restart=always' 'RestartSec=5' '' '[Install]' 'WantedBy=default.target' > $(SERVICE_FILE)
|
||||||
|
systemctl --user daemon-reload
|
||||||
|
systemctl --user enable --now $(SERVICE_NAME)
|
||||||
|
|
||||||
|
uninstall-service:
|
||||||
|
systemctl --user disable --now $(SERVICE_NAME) || true
|
||||||
|
rm -f $(SERVICE_FILE)
|
||||||
|
systemctl --user daemon-reload
|
||||||
|
|
||||||
|
start-service:
|
||||||
|
systemctl --user start $(SERVICE_NAME)
|
||||||
|
|
||||||
|
stop-service:
|
||||||
|
systemctl --user stop $(SERVICE_NAME)
|
||||||
|
|
||||||
|
restart-service:
|
||||||
|
systemctl --user restart $(SERVICE_NAME)
|
||||||
|
|
||||||
|
status-service:
|
||||||
|
systemctl --user status $(SERVICE_NAME)
|
||||||
|
|
||||||
|
logs-service:
|
||||||
|
journalctl --user -u $(SERVICE_NAME) -f
|
||||||
|
|
|
||||||
43
README.md
43
README.md
|
|
@ -29,7 +29,7 @@ pip install -r requirements.txt
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
Edit the constants at the top of `luz-musica.py`:
|
For local runs, edit the constants at the top of `luz-musica.py` or export environment variables:
|
||||||
|
|
||||||
- `HA_URL`
|
- `HA_URL`
|
||||||
- `HA_TOKEN`
|
- `HA_TOKEN`
|
||||||
|
|
@ -56,8 +56,49 @@ Or use the Makefile:
|
||||||
make run
|
make run
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Ubuntu User Service
|
||||||
|
|
||||||
|
Install and start the script as a `systemd --user` service:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make install-service
|
||||||
|
```
|
||||||
|
|
||||||
|
The install target:
|
||||||
|
|
||||||
|
- creates `.venv` and installs `requirements.txt`
|
||||||
|
- copies `music-light.env.example` to `~/.config/music-light/env` if 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:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nano ~/.config/music-light/env
|
||||||
|
make restart-service
|
||||||
|
```
|
||||||
|
|
||||||
|
Manage the service with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make status-service
|
||||||
|
make logs-service
|
||||||
|
make restart-service
|
||||||
|
make stop-service
|
||||||
|
make start-service
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove the service:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make uninstall-service
|
||||||
|
```
|
||||||
|
|
||||||
|
This is installed as a user service because `playerctl` needs access to the desktop user's MPRIS session.
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
- If nothing is playing, or `playerctl` cannot read metadata, the loop sleeps and retries.
|
- If nothing is playing, or `playerctl` cannot read metadata, the loop sleeps and retries.
|
||||||
- If `mpris:artUrl` is missing, the script logs it and waits for the next track change.
|
- If `mpris:artUrl` is 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 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.
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,12 @@ from urllib.parse import parse_qs, urlparse
|
||||||
import requests
|
import requests
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
HA_URL = "http://127.0.0.1:8123"
|
HA_URL = os.environ.get("HA_URL", "http://127.0.0.1:8123")
|
||||||
HA_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkZjM1MmRhNjg1ZWM0MGJiYTc4YTZlNWY3ZmQ0YTA1YSIsImlhdCI6MTc3NjI4MTI0MiwiZXhwIjoyMDkxNjQxMjQyfQ.rR0Kfwk5Smr06_9KJSDn3YPXiRlokEZZFiAa_naNs78"
|
HA_TOKEN = os.environ.get(
|
||||||
LIGHT_ENTITY = "light.luzsala_luz_sala"
|
"HA_TOKEN",
|
||||||
|
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkZjM1MmRhNjg1ZWM0MGJiYTc4YTZlNWY3ZmQ0YTA1YSIsImlhdCI6MTc3NjI4MTI0MiwiZXhwIjoyMDkxNjQxMjQyfQ.rR0Kfwk5Smr06_9KJSDn3YPXiRlokEZZFiAa_naNs78",
|
||||||
|
)
|
||||||
|
LIGHT_ENTITY = os.environ.get("LIGHT_ENTITY", "light.luzsala_luz_sala")
|
||||||
|
|
||||||
# Ajustes visuais
|
# Ajustes visuais
|
||||||
BRIGHTNESS_PCT = 70
|
BRIGHTNESS_PCT = 70
|
||||||
|
|
|
||||||
5
music-light.env.example
Normal file
5
music-light.env.example
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Uncomment and edit these values to override the defaults from luz-musica.py.
|
||||||
|
# HA_URL=http://127.0.0.1:8123
|
||||||
|
# HA_TOKEN=replace-with-your-home-assistant-token
|
||||||
|
# LIGHT_ENTITY=light.luzsala_luz_sala
|
||||||
|
# PLAYERCTL_BIN=/usr/bin/playerctl
|
||||||
Loading…
Add table
Add a link
Reference in a new issue