DIY: Un système d’extinction propre pour Raspberry

J’ai monté un deuxième lecteur RuneAudio ce week-end, pour le rez-de-chaussée. La principale différence, hormis le boîtier physique, est la gestion de l’alimentation.

En effet, sur mon premier lecteur, basculer l’interrupteur coupe le courant brutalement au Raspberry, ce qui peut occasionner des corruptions du système de fichiers de la carte MicroSD (et l’expérience, sur à peine dix jours, montre que la base de données de MPD finit parfois corrompue).

Je voulais donc un système qui me permette d’allumer le Raspberry en basculant l’interrupteur, de l’éteindre proprement en re-basculant le même interrupteur, et de consommer zéro watt lorsqu’il est éteint.

La solution la plus simple que j’ai trouvé est un interrupteur capable de commander deux circuits distincts, tel que celui-ci ou celui-là (chercher DPST, « Double pole single throw »).

L’un des circuits de cet interrupteur coupera l’arrivée d’électricité à l’alimentation et sera mis en parallèle d’un relais contrôlé par le Raspberry, tandis que l’état du deuxième circuit, relié aux GPIO du Raspberry, sera surveillé par celui et déclenchera un shutdown propre.

Le schéma de câblage

Sur le schéma ci-dessus, le 220V est sur les fils bleu et marron ; le 5V sur les rouge et noir ; le contrôle du relais en orange, et celui du deuxième circuit de l’interrupteur en violet.

Nous allons écrire un petit script Python qui commencera par configurer la GPIO 5 en sortie, puis la passera à l’état haut, ce qui aura pour effet de fermer le relais. Ensuite, on configure la GPIO 27 en entrée, puis on lit son état dans une boucle infinie. Selon l’état, on continue d’attendre ou bien on éteint proprement.

# cat /root/power-control.py
import RPi.GPIO as GPIO
import os
import time
import sys

GPIO.setmode(GPIO.BCM)

#Setup de la broche de contrôle du relais pour le fermer
GPIO.setup(5, GPIO.OUT)
GPIO.output(5, GPIO.HIGH)

#Setup de la broche de surveillance de l'interrupteur
GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_UP)

#Boucle infinie de surveillance
while True:
state = GPIO.input(27)
if state == True:
#Interrupteur toujours sur ON
time.sleep(0.5)
else:
#Interrupteur sur OFF, déclenchement de l'extinction
os.system("/var/www/command/rune_shutdown poweroff")
os.system("shutdown -h now")
sys.exit(0)

Deux remarques :

  • Selon votre câblage et le type de relais, les GPIO.HIGH seront peut-être des LOW, à adapter.
  • On ne réouvre jamais le relais. Cela se fait tout seul, tard dans le processus de shutdown du Pi et cela a pour conséquence de l’éteindre immédiatement, donc autant ne pas le faire en avance.

Il reste à installer ce script en tant que service Systemd :

# cat /usr/lib/systemd /system/power-control.service
[Unit]
Description=Power control
After=multi-user.target

[Service]
Type=idle
ExecStart=/usr/bin/python /root/power-control.py

[Install]
WantedBy=multi-user.target

Et enfin, on l’active et on le démarre :

# systemctl enable power-control
# systemctl start power-control
# systemctl status power-control

Pour le reste de la configuration logicielle, c’est la même que dans ce premier article : Configuration de Runeaudio, un lecteur de musique réseau.

Quelques photos :

Devant

J’ai aussi fait une vidéo au montage hyper-propre sur le même sujet :