Trvalo mi to trochu déle, protože s časem jsem mezi půlkama. A protože myšlenka triviální systemd jednotky se změnila v testovací horor. Vypadá to, že jsem narazil na bug v systemd. Normálně se soubory hlídají pomocí
jednotky path. Avšak zrovna na toto to nefunguje. Jak je vidět v
manuálu ty soubory se hlídají pomocí
inotify generované jádrem. Jednoduchý test nám ukáže, že jádro posílá události dál:
udevadm monitor -u -p
a odpojíme nebo připojíme napájení. A jak je vidět, jádro to pěkně hlásí kam má. Tak se koukneme na inotify. Buď si něco napíšeme v céčku podle man inotify, nebo si nainstalujeme inotify-tools a použijem z toho jeden příkaz:
inotifywait -m /sys/class/power_supply/AC/online
Yes, inotify pracuje jak má, avšak systemd to ignoruje.
V tomto případě máme dvě čisté možnosti jak dál a nespočet prasáren které by to také zvládli, jen by žrali ze systémových prostředků nějaké to procento procesoru. Takže první možnost je napsat si udev pravidlo, k němu systemd službu a samozřejmě ještě skript. Druhá možnost je o dost jednodušší. Poupravíme Tvou systemd službu a přepíšeme skript. Napíšu rovnou výsledné soubory. Ještě než to nakopíruješ je třeba zastavit a vypnout původní službu:
sudo systemctl stop display_refresh_rate_changer.service
sudo systemctl disable display_refresh_rate_changer.service
sudo systemctl daemon-reload
Pak přepíšeš display_refresh_rate_changer.service :
[Unit]
Description=Change Display Refresh Rate based on AC online
[Service]
# ta pomlčka na začátku cesty ke skriptu je správně!
ExecStart=-/home/user/.scripts/display_refresh_rate_changer/display_refresh_rate_changer.sh
[Install]
WantedBy=graphical.target
A skript /home/user/.scripts/display_refresh_rate_changer/display_refresh_rate_changer.sh :
#! /usr/bin/env bash
#Vytvoří nekonečnou smyčku. Dvojtečka v bash vždy produkuje výstup true.
#Protože je to built-in, tak je to lepší než použít externí program (třeba true)
while :
do
#Všechny výstupy musí být zahozeny. Skripty v systemd nesmí nic produkovat na standardní výstup.
#Ani nepotřebujeme znát výsledek výstupu. Skript stojí a čeká na event close na souboru.
#Jakmile event nastane skript pokračuje dál.
inotifywait -q -e 'close' /sys/class/power_supply/AC/online &> /dev/null
#Přečte obsah souboru a matematicky ho porovná s jedničkou
# $(<soubor) je built-in konstrukce bash. Není třeba externí program cat
if [ $(</sys/class/power_supply/AC/online) -eq 1 ]
then
#Větev pokud je napájení připojeno
#Následující řádek na ostrý provoz zakomentovat
echo "Jsem online $(date)" >> /var/log/display_refresh_rate_changer
xrandr --rate 144.00
else
#Větev kde je napájení vypnuto
#Následující řádek na ostrý provoz zakomentovat
echo "Nejsem online $(date)" >> /var/log/display_refresh_rate_changer
xrandr --rate 60.00
fi
done
Nejdřív si ten skript spusť jen tak
cd /home/user/.scripts/display_refresh_rate_changer/
sudo ./display_refresh_rate_changer.sh
A zkoušej jestli to dělá co má. Pokud ne, napiš podrobnosti. Skript ukončíš klávesovou zkratkou ctrl+c
Pokud funguje otestujem systemd službu jestli je to syntakticky dobře napsané:
systemd-analyze verify display_refresh_rate_changer.service
Když to nic nevypíše tak službu zapneme na test:
sudo systemctl start display_refresh_rate_changer.service
Odpoj a připoj napájení. Mělo by to fungovat. A tak si službu aktivuj aby se spouštěla pokaždé po startu:
sudo systemctl enable display_refresh_rate_changer.service
Něco k tomu skriptu. Zapisuje ti do logu /var/log/display_refresh_rate_changer událost. Jak je napsáno, pokud bude vše ok, je lepší dle instrukcí to deaktivovat zakomentováním dvou řádků. Při příštím spuštění systému už to zapisovat nebude. Usoudil jsem, dle prvotního dotazu, že bude jednodušší a hlavně účinnější testovat jestli je připojen zdroj než v jakém statusu je momentálně baterie.
No a já ještě projedu systemd.path u vývojářů a pokud na to ještě nenarazili nahlásím chybu.