Initial Fedora brightness automation setup
This commit is contained in:
522
docs/hp-firefly-fedora-brightness-notes.md
Normal file
522
docs/hp-firefly-fedora-brightness-notes.md
Normal file
@@ -0,0 +1,522 @@
|
||||
# HP Firefly G11 unter Fedora – finaler sauberer Stand
|
||||
|
||||
## Ziel
|
||||
Saubere gemeinsame Helligkeitssteuerung für:
|
||||
|
||||
- internes Display über `intel_backlight`
|
||||
- externen Monitor über `ddcutil`
|
||||
|
||||
sowie automatische Helligkeitsregelung über den vorhandenen Ambient-Light-Sensor mit `wluma`.
|
||||
|
||||
Finale Logik:
|
||||
- **internes Display ist Master**
|
||||
- `wluma` regelt nur noch `intel_backlight`
|
||||
- der externe Monitor wird automatisch auf denselben Prozentwert nachgezogen
|
||||
- die manuellen Helligkeitstasten zeigen ein GNOME/Adwaita-passendes OSD
|
||||
- dadurch können intern und extern nicht mehr durch zwei unabhängige `wluma`-Regelungen auseinanderlaufen
|
||||
|
||||
---
|
||||
|
||||
## Finaler Ist-Zustand
|
||||
|
||||
### Was aktuell funktioniert
|
||||
- Das interne Display hängt als normales Backlight unter:
|
||||
- `intel_backlight`
|
||||
- Der externe Monitor `HG342PCB` am Thunderbolt-Dock ist per `ddcutil` erreichbar.
|
||||
- Die gemeinsamen Button-Skripte regeln jetzt:
|
||||
- intern per `brightnessctl`
|
||||
- zeigen ein lokales GTK/libadwaita-OSD
|
||||
- extern folgt automatisch über `external-brightness-sync.service`
|
||||
- `wluma.service` läuft als User-Service nach dem Login.
|
||||
- `wluma` nutzt nur noch das interne `intel_backlight`.
|
||||
- `external-brightness-sync.service` spiegelt den internen Prozentwert automatisch auf den externen Monitor per `ddcutil`.
|
||||
|
||||
### Aktueller Nachweis
|
||||
```bash
|
||||
systemctl --user status wluma.service
|
||||
systemctl --user status external-brightness-sync.service
|
||||
brightnessctl -l
|
||||
sudo ddcutil detect
|
||||
sudo ddcutil getvcp 10
|
||||
```
|
||||
|
||||
Erwarteter sauberer Zustand:
|
||||
in `brightnessctl -l`:
|
||||
- `intel_backlight`
|
||||
|
||||
und in `sudo ddcutil detect`:
|
||||
- `Display 1`
|
||||
- `I2C bus: /dev/i2c-16`
|
||||
- `Model: HG342PCB`
|
||||
|
||||
---
|
||||
|
||||
## Warum dieser Stand der richtige ist
|
||||
|
||||
### 1. Internes und externes Display laufen jetzt über zwei stabile Wege
|
||||
Das interne Panel läuft weiter über `intel_backlight`.
|
||||
Der externe Monitor wird über das Thunderbolt-Dock direkt per `ddcutil` angesprochen.
|
||||
|
||||
Damit ist die gemeinsame Steuerung wieder stabil, auch wenn intern und extern technisch über unterschiedliche Wege laufen.
|
||||
|
||||
Wichtig:
|
||||
Es gibt nur noch eine automatische Regelinstanz. `wluma` regelt das interne Panel, der Sync-Dienst übernimmt die Spiegelung nach extern.
|
||||
|
||||
### 2. Das Thunderbolt-Dock reicht DDC/CI sauber durch, `ddcci_backlight` war hier aber nicht der richtige Weg
|
||||
Mit dem neuen Dock ist der Monitor nachweislich über `ddcutil` auf `card1-DP-5` / `/dev/i2c-16` erreichbar.
|
||||
Die frühere `ddcci3`-Lösung über `/sys/class/backlight` war für dieses Setup dagegen nicht stabil nutzbar.
|
||||
|
||||
Der saubere Endstand ist deshalb:
|
||||
|
||||
- **intern: `brightnessctl`**
|
||||
- **extern: `ddcutil`**
|
||||
- **kein aggressives Hotplug-Refresh über `ddcci`**
|
||||
|
||||
### 3. GNOME Auto Brightness war nicht funktionsfähig
|
||||
Der Ambient-Light-Sensor funktioniert eindeutig, aber GNOME hat die Helligkeit sichtbar nicht geregelt.
|
||||
Deshalb ist `wluma` jetzt die saubere automatische Lösung auf Basis des Sensors.
|
||||
|
||||
---
|
||||
|
||||
## Aktive Komponenten
|
||||
|
||||
### Als User aktiv
|
||||
|
||||
#### wluma-Service
|
||||
```text
|
||||
~/.config/systemd/user/wluma.service
|
||||
```
|
||||
|
||||
#### wluma-Konfiguration
|
||||
```text
|
||||
~/.config/wluma/config.toml
|
||||
```
|
||||
|
||||
#### Gemeinsame Helligkeitsskripte
|
||||
```text
|
||||
~/.local/bin/brightness-osd
|
||||
~/.local/bin/brightness-ddcutil-hg342pcb
|
||||
~/.local/bin/brightness-down-all
|
||||
~/.local/bin/brightness-up-all
|
||||
```
|
||||
|
||||
#### Externer Sync-Dienst
|
||||
```text
|
||||
~/.local/bin/brightness-sync-hg342pcb
|
||||
~/.config/systemd/user/external-brightness-sync.service
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Finaler Inhalt der wichtigen Dateien
|
||||
|
||||
### 1. `~/.local/bin/brightness-ddcutil-hg342pcb`
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
MODEL="${BRIGHTNESS_DDCUTIL_MODEL:-HG342PCB}"
|
||||
STEP="${BRIGHTNESS_DDCUTIL_STEP:-10}"
|
||||
DISPLAY_NUM="${BRIGHTNESS_DDCUTIL_DISPLAY:-1}"
|
||||
BUS_NUM="${BRIGHTNESS_DDCUTIL_BUS:-16}"
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $(basename "$0") up|down" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
up) delta="+" ;;
|
||||
down) delta="-" ;;
|
||||
*) echo "Usage: $(basename "$0") up|down" >&2; exit 2 ;;
|
||||
esac
|
||||
|
||||
run_ddcutil() {
|
||||
if sudo -n ddcutil --bus "$BUS_NUM" getvcp 10 >/dev/null 2>&1; then
|
||||
sudo -n ddcutil --bus "$BUS_NUM" "$@"
|
||||
return
|
||||
fi
|
||||
|
||||
if sudo -n ddcutil --display "$DISPLAY_NUM" getvcp 10 >/dev/null 2>&1; then
|
||||
sudo -n ddcutil --display "$DISPLAY_NUM" "$@"
|
||||
return
|
||||
fi
|
||||
|
||||
if sudo -n ddcutil --model "$MODEL" getvcp 10 >/dev/null 2>&1; then
|
||||
sudo -n ddcutil --model "$MODEL" "$@"
|
||||
return
|
||||
fi
|
||||
|
||||
if ddcutil --bus "$BUS_NUM" getvcp 10 >/dev/null 2>&1; then
|
||||
ddcutil --bus "$BUS_NUM" "$@"
|
||||
return
|
||||
fi
|
||||
|
||||
if ddcutil --display "$DISPLAY_NUM" getvcp 10 >/dev/null 2>&1; then
|
||||
ddcutil --display "$DISPLAY_NUM" "$@"
|
||||
return
|
||||
fi
|
||||
|
||||
if ddcutil --model "$MODEL" getvcp 10 >/dev/null 2>&1; then
|
||||
ddcutil --model "$MODEL" "$@"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "External HG342PCB was not reachable via ddcutil on bus ${BUS_NUM}." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
run_ddcutil setvcp 10 "$delta" "$STEP" >/dev/null
|
||||
```
|
||||
|
||||
### 2. `~/.local/bin/brightness-down-all`
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
brightnessctl -q -d intel_backlight set 10%-
|
||||
/home/jan/.local/bin/brightness-osd || true
|
||||
```
|
||||
|
||||
### 3. `~/.local/bin/brightness-up-all`
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
brightnessctl -q -d intel_backlight set +10%
|
||||
/home/jan/.local/bin/brightness-osd || true
|
||||
```
|
||||
|
||||
### 4. `~/.local/bin/brightness-osd`
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
```
|
||||
|
||||
Dieses Skript zeigt ein kleines GTK4/libadwaita-OSD am oberen Bildschirmrand mit:
|
||||
- Adwaita-Icon `display-brightness-symbolic`
|
||||
- Prozentwert der internen Master-Helligkeit
|
||||
- Fortschrittsbalken
|
||||
|
||||
Das OSD ist einzeilig und kompakt. Wenn mehrere Tastendrücke schnell hintereinander kommen, wird der laufende OSD-Prozess aktualisiert und der Ausblend-Timer verlängert; dadurch verschwindet es nicht mehr zwischen zwei Helligkeitsänderungen.
|
||||
|
||||
Für echte Positionierung am oberen Bildschirmrand unter GNOME Wayland wird dieses Fedora-Paket benötigt:
|
||||
|
||||
```bash
|
||||
sudo dnf install -y gtk4-layer-shell
|
||||
```
|
||||
|
||||
Ohne `gtk4-layer-shell` darf GNOME/Wayland ein normales GTK-Fenster nicht zuverlässig oben positionieren; dann fällt das Skript auf die normale GTK-Fensterposition zurück.
|
||||
|
||||
### 5. `~/.config/wluma/config.toml`
|
||||
```toml
|
||||
[als.iio]
|
||||
path = "/sys/bus/iio/devices"
|
||||
thresholds = { 0 = "night", 20 = "dark", 80 = "dim", 250 = "normal", 500 = "bright", 800 = "outdoors" }
|
||||
|
||||
[[output.backlight]]
|
||||
name = "eDP-1"
|
||||
path = "/sys/class/backlight/intel_backlight"
|
||||
capturer = "none"
|
||||
```
|
||||
|
||||
### 6. `~/.local/bin/brightness-sync-hg342pcb`
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
MODEL="${BRIGHTNESS_DDCUTIL_MODEL:-HG342PCB}"
|
||||
DISPLAY_NUM="${BRIGHTNESS_DDCUTIL_DISPLAY:-1}"
|
||||
BUS_NUM="${BRIGHTNESS_DDCUTIL_BUS:-16}"
|
||||
BACKLIGHT_PATH="${BRIGHTNESS_SYNC_BACKLIGHT:-/sys/class/backlight/intel_backlight}"
|
||||
INTERVAL="${BRIGHTNESS_SYNC_INTERVAL:-1}"
|
||||
MIN_PERCENT="${BRIGHTNESS_SYNC_MIN_PERCENT:-1}"
|
||||
|
||||
brightness_percent() {
|
||||
local current max percent
|
||||
|
||||
current="$(<"${BACKLIGHT_PATH}/brightness")"
|
||||
max="$(<"${BACKLIGHT_PATH}/max_brightness")"
|
||||
percent="$(( (current * 100 + max / 2) / max ))"
|
||||
|
||||
if (( percent < MIN_PERCENT )); then
|
||||
percent="$MIN_PERCENT"
|
||||
elif (( percent > 100 )); then
|
||||
percent=100
|
||||
fi
|
||||
|
||||
printf '%s\n' "$percent"
|
||||
}
|
||||
|
||||
run_ddcutil() {
|
||||
if sudo -n ddcutil --bus "$BUS_NUM" getvcp 10 >/dev/null 2>&1; then
|
||||
sudo -n ddcutil --bus "$BUS_NUM" "$@"
|
||||
return
|
||||
fi
|
||||
|
||||
if sudo -n ddcutil --display "$DISPLAY_NUM" getvcp 10 >/dev/null 2>&1; then
|
||||
sudo -n ddcutil --display "$DISPLAY_NUM" "$@"
|
||||
return
|
||||
fi
|
||||
|
||||
if sudo -n ddcutil --model "$MODEL" getvcp 10 >/dev/null 2>&1; then
|
||||
sudo -n ddcutil --model "$MODEL" "$@"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "External ${MODEL} was not reachable via sudo -n ddcutil." >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
last_percent=""
|
||||
|
||||
while true; do
|
||||
percent="$(brightness_percent)"
|
||||
|
||||
if [[ "$percent" != "$last_percent" ]]; then
|
||||
if run_ddcutil setvcp 10 "$percent" >/dev/null; then
|
||||
last_percent="$percent"
|
||||
fi
|
||||
fi
|
||||
|
||||
sleep "$INTERVAL"
|
||||
done
|
||||
```
|
||||
|
||||
### 7. `~/.config/systemd/user/wluma.service`
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Adjust screen brightness automatically with wluma
|
||||
PartOf=graphical-session.target
|
||||
After=graphical-session.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/wluma
|
||||
Restart=always
|
||||
PrivateNetwork=true
|
||||
PrivateMounts=false
|
||||
|
||||
[Install]
|
||||
WantedBy=graphical-session.target
|
||||
```
|
||||
|
||||
### 8. `~/.config/systemd/user/external-brightness-sync.service`
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Mirror internal panel brightness to external HG342PCB
|
||||
PartOf=graphical-session.target
|
||||
After=graphical-session.target wluma.service
|
||||
|
||||
[Service]
|
||||
ExecStart=%h/.local/bin/brightness-sync-hg342pcb
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
|
||||
[Install]
|
||||
WantedBy=graphical-session.target
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dienste – finaler Soll-Zustand
|
||||
|
||||
### Aktiv
|
||||
```bash
|
||||
systemctl --user status wluma.service
|
||||
systemctl --user status external-brightness-sync.service
|
||||
```
|
||||
|
||||
Erwartet:
|
||||
- `wluma.service`: `active (running)`
|
||||
- `external-brightness-sync.service`: `active (running)`
|
||||
|
||||
### Nicht mehr Teil der Lösung
|
||||
Diese Komponenten gehören **nicht** mehr zur finalen Lösung:
|
||||
|
||||
- `ddcci-attach.service`
|
||||
- `/usr/local/sbin/ddcci-attach-hg342pcb`
|
||||
- `ddcci-refresh.service`
|
||||
- `/usr/local/sbin/ddcci-refresh`
|
||||
- `/etc/udev/rules.d/99-ddcci-hotplug.rules`
|
||||
|
||||
Der Grund:
|
||||
Mit dem Thunderbolt-Dock funktioniert die externe Steuerung sauber über `ddcutil`; die `ddcci`-Backlight-Variante wird dafür nicht mehr benötigt.
|
||||
|
||||
---
|
||||
|
||||
## Cleanup alter / falscher Komponenten
|
||||
|
||||
### Falls noch vorhanden: `ddcci-refresh` entfernen
|
||||
```bash
|
||||
sudo systemctl disable --now ddcci-refresh.service 2>/dev/null || true
|
||||
sudo rm -f /etc/systemd/system/ddcci-refresh.service
|
||||
sudo rm -f /usr/local/sbin/ddcci-refresh
|
||||
sudo rm -f /etc/udev/rules.d/99-ddcci-hotplug.rules
|
||||
sudo systemctl daemon-reload
|
||||
sudo udevadm control --reload-rules
|
||||
```
|
||||
|
||||
### Alte `ddcci`-Komponenten können entfernt werden
|
||||
Die ältere `ddcci`-/`ddcci_backlight`-Variante ist **nicht mehr der finale Stand**.
|
||||
Final ist jetzt die Hybrid-Variante über:
|
||||
|
||||
- `intel_backlight` für intern
|
||||
- `ddcutil` für extern
|
||||
|
||||
---
|
||||
|
||||
## Bedienung im Alltag
|
||||
|
||||
### Manuell beide Displays heller / dunkler
|
||||
```bash
|
||||
/home/jan/.local/bin/brightness-down-all
|
||||
/home/jan/.local/bin/brightness-up-all
|
||||
```
|
||||
|
||||
### Reaktionsverhalten
|
||||
Das interne Display reagiert praktisch sofort.
|
||||
Der externe Monitor reagiert typischerweise leicht verzögert, oft ungefähr nach einer Sekunde.
|
||||
|
||||
Das ist bei `ddcutil` normal, weil zuerst DDC/CI-Kommunikation mit dem Monitor über das Dock stattfindet.
|
||||
Etwas schneller könnte es eventuell mit `--noverify` werden, das ist aber weniger robust und daher aktuell nicht Teil des finalen Stands.
|
||||
|
||||
### GNOME-Shortcuts
|
||||
Wenn dafür Benutzerkürzel in GNOME gesetzt werden, immer den **vollen Pfad** verwenden:
|
||||
|
||||
```text
|
||||
/home/jan/.local/bin/brightness-down-all
|
||||
/home/jan/.local/bin/brightness-up-all
|
||||
```
|
||||
|
||||
Nicht `~/.local/bin/...`, weil das im GNOME-Shortcut-Feld unzuverlässig sein kann.
|
||||
|
||||
---
|
||||
|
||||
## wluma und externer Sync – aktueller realer Zustand
|
||||
|
||||
### Wichtig
|
||||
`wluma` läuft automatisch nach dem Login und steuert nur das interne Display:
|
||||
|
||||
```bash
|
||||
systemctl --user status wluma.service
|
||||
```
|
||||
|
||||
Der externe Monitor wird durch diesen User-Service nachgezogen:
|
||||
|
||||
```bash
|
||||
systemctl --user status external-brightness-sync.service
|
||||
```
|
||||
|
||||
### Verhalten
|
||||
`wluma` nutzt weiter den adaptiven Lernmodus, aber nur auf `intel_backlight`.
|
||||
Der externe Sync-Dienst liest einmal pro Sekunde den internen Prozentwert aus:
|
||||
|
||||
```text
|
||||
/sys/class/backlight/intel_backlight/brightness
|
||||
/sys/class/backlight/intel_backlight/max_brightness
|
||||
```
|
||||
|
||||
und setzt denselben Prozentwert extern per:
|
||||
|
||||
```bash
|
||||
sudo -n ddcutil --bus 16 setvcp 10 <prozent>
|
||||
```
|
||||
|
||||
Das bedeutet:
|
||||
- `wluma` entscheidet die Helligkeit nur einmal, am internen Panel
|
||||
- extern folgt automatisch
|
||||
- manuelle Änderungen über die gemeinsamen Skripte bleiben ebenfalls synchron
|
||||
- bei einem Replug des externen Monitors kann ein `systemctl --user restart external-brightness-sync.service` sinnvoll sein
|
||||
|
||||
### Praktische Folge
|
||||
Wenn du möchtest, dass `wluma` besser wird, dann im Alltag in verschiedenen Lichtsituationen die Helligkeit mit deinen gemeinsamen Skripten nachregeln. Daraus lernt `wluma` die interne Master-Helligkeit; extern wird automatisch mitgezogen.
|
||||
|
||||
---
|
||||
|
||||
## Sensorstatus
|
||||
|
||||
Der Ambient-Light-Sensor funktioniert sauber.
|
||||
|
||||
Nachgewiesen durch:
|
||||
- `monitor-sensor` zeigt deutliche Lux-Änderungen
|
||||
- `gsettings get org.gnome.settings-daemon.plugins.power ambient-enabled` war `true`
|
||||
- `iio-sensor-proxy` läuft
|
||||
|
||||
Das Problem lag daher **nicht** am Sensor, sondern an GNOME Auto Brightness.
|
||||
|
||||
---
|
||||
|
||||
## Was bei Problemen sinnvoll ist
|
||||
|
||||
### 1. Prüfen, ob intern und extern erreichbar sind
|
||||
```bash
|
||||
ls -l /sys/class/backlight
|
||||
brightnessctl -l
|
||||
sudo ddcutil --bus 16 getvcp 10
|
||||
```
|
||||
|
||||
### 2. Dienste prüfen
|
||||
```bash
|
||||
systemctl --user status wluma.service
|
||||
systemctl --user status external-brightness-sync.service
|
||||
```
|
||||
|
||||
### 3. Dienste neu starten
|
||||
```bash
|
||||
systemctl --user restart wluma.service
|
||||
systemctl --user restart external-brightness-sync.service
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Was aktuell bewusst **nicht** gemacht wird
|
||||
|
||||
- kein aggressives `delete_device` / `new_device` im laufenden Betrieb
|
||||
- keine Hotplug-Automatik mit `ddcci-refresh`
|
||||
- keine udev-Regel, die `ddcci` ständig neu erzeugt
|
||||
- kein Verlassen auf GNOME Auto Brightness
|
||||
- keine unabhängige `wluma`-Regelung für den externen Monitor
|
||||
|
||||
Der Grund ist reine Stabilität:
|
||||
Interner Master plus externer DDC/CI-Sync vermeidet Drift zwischen den Displays.
|
||||
|
||||
---
|
||||
|
||||
## Kurzfazit
|
||||
|
||||
### Final sauber gelöst
|
||||
- intern läuft über `intel_backlight`
|
||||
- extern läuft über `ddcutil` auf Bus 16
|
||||
- `wluma` läuft automatisch nach dem Login und steuert nur intern
|
||||
- `external-brightness-sync.service` zieht den externen Monitor automatisch nach
|
||||
- der ALS-Sensor funktioniert und wird von `wluma` genutzt
|
||||
|
||||
### Final bewusst verworfen
|
||||
- externes Display direkt von `wluma` regeln lassen
|
||||
- `ddcci-refresh`
|
||||
- Hotplug-Delete/Recreate-Automatik
|
||||
- GNOME Auto Brightness als eigentliche Endlösung
|
||||
|
||||
---
|
||||
|
||||
## Schnellbefehle
|
||||
|
||||
### Status
|
||||
```bash
|
||||
systemctl --user status wluma.service
|
||||
systemctl --user status external-brightness-sync.service
|
||||
ls /sys/class/backlight
|
||||
brightnessctl -l
|
||||
sudo ddcutil --bus 16 getvcp 10
|
||||
```
|
||||
|
||||
### Manuelle gemeinsame Steuerung
|
||||
```bash
|
||||
/home/jan/.local/bin/brightness-down-all
|
||||
/home/jan/.local/bin/brightness-up-all
|
||||
```
|
||||
|
||||
### Dienste neu starten
|
||||
```bash
|
||||
systemctl --user restart wluma.service
|
||||
systemctl --user restart external-brightness-sync.service
|
||||
```
|
||||
Reference in New Issue
Block a user