J’ai eu un nouveau vieux portable
Ce portable est plutôt « vieux » comparé au matériel neuf et rutilant d’aujourd’hui, mais il coche toutes les cases pour moi.
- Il était bon marché (pour moi, c’était du surplus d’une entreprise)
- Il a un bon processeur
11th Gen Intel(R) Core(TM) i7-11850H @ 2.50GHz - Il a beaucoup de RAM (16G et un slot libre)
- Ce modèle, ou un modèle assez similaire, est certifié Ubuntu (cela signifie qu’une équipe chez Ubuntu a pris le temps de vérifier que chaque version de leur système fonctionne sur ces machines et a même apporté des modifications à leur noyau oem pour accommoder les bizarreries dues au fait que Lenovo prend trop de libertés avec l’interprétation des standards)
Live USB
L’image Live d’Ubuntu est magnifique et fonctionne d’emblée avec tout ce que mon portable a à offrir (23.10 au moment où j’écris ceci). Maintenant, c’est là que le plaisir commence.
Mon portable a une touche muet dotée d’une led ; la led s’allume quand le portable est en sourdine, et il en va de même pour celle du micro coupé.
Cela fonctionne parfaitement sur l’image live, mais une fois installé, seul le voyant du micro coupé fonctionne.
Or : j’ai bel et bien arraché snapd d’Ubuntu, donc j’ai peut-être perturbé le déroulement normal des choses.
Après avoir lu un peu, je n’ai pas pu comprendre pourquoi cela ne fonctionnait pas ; le mécanisme du noyau qui le fait fonctionner est bien là et je peux même déclencher la led à la main :
# This turns on the led
echo 1 | sudo tee /sys/class/leds/platform\:\:mute/brightness
J’ai passé quelques heures à essayer diverses solutions et à tenter de comprendre ce qui était différent dans l’image live, sans succès ; les gens qui assemblent cette image sont bien plus malins que moi.
La solution bon marché
Il s’avère que l’on peut s’abonner à pulse audio et écouter les événements, alors j’ai écrit un petit daemon systemd pour allumer/éteindre la led.
Pour cela, j’ai d’abord dû ajouter une règle udev pour la rendre inscriptible sans sudo.
J’ai placé ce fichier dans /etc/udev/rules.d/99-mute_led.rules
ACTION=="add", SUBSYSTEM=="leds", KERNEL=="platform::mute", RUN+="/bin/chmod a+w /sys/class/leds/%k/brightness"Ensuite, j’ai écrit un script python qui faisait l’abonnement à pulse ; j’ai utilisé une bibliothèque pratique
requirements.txt
pulsectl==23.5.2#!/usr/bin/env python
import time
from pulsectl import Pulse, PulseLoopStop
# This is the name for my laptop, a Thinkpad X1 Extreme Gen 4
SINK_NAME="alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp__sink"
def get_sink_number(pulse):
"""
return the index for the sink we care about
"""
return pulse.get_sink_by_name(SINK_NAME).index
def set_led_brightness(sink_number, is_muted):
"""
set the status of the led according to the mute status
"""
# Determine the LED brightness value based on mute status
brightness = 0 if not is_muted else 1
with open('/sys/class/leds/platform::mute/brightness', 'w') as led:
led.write(f'{brightness}')
def main():
with Pulse("mute-led-listener") as pulse:
sink_number = get_sink_number(pulse)
def mute_button(ev):
"""
callback to be invoked every time an event matches the set match
we only raise a loop stop exception to trigger the event loop to
exit, we cannot perform pulse operations while the loop is running.
"""
if ev.index == sink_number:
raise PulseLoopStop
pulse.event_mask_set("sink")
pulse.event_callback_set(mute_button)
while True:
# Lock until we have an event match.
pulse.event_listen()
# Get mute status for our sink
is_muted = pulse.get_sink_by_name(SINK_NAME).mute == 1
# Set LED brightness based on mute status
set_led_brightness(sink_number, is_muted)
# Then we will begin the listener again and only trigger next time button is pressed
if __name__ == "__main__":
main()Note : Vérifiez si le nom du périphérique fonctionne pour vous, vous pouvez le vérifier à l’aide de l’outil pactl.
Et j’ai relié le tout avec un daemon systemd
$HOME/.local/share/systemd/user/led-control.service
# $HOME/.local/share/systemd/user/led-control.service
[Unit]
Description=LED Control Service
[Service]
Type=simple
ExecStart=/home/hduran/vimconfig/thinkpad/venv/bin/python /home/hduran/vimconfig/thinkpad/mute_led_helper.py
[Install]
WantedBy=default.targetNote : Le chemin de python est un peu bizarre parce que j’ai créé un virtualenv pour cela (vous devriez faire de même si vous voulez installer ce paquet, plutôt que de l’installer à l’échelle du système)
Après cela, vous devez exécuter :
systemctl --user enable led-control.service
systemctl --user start led-control.service