WebRadioRéveilWifi -5-
Par makoto doushite le samedi, 3 mars 2018, 16:09 - Raspberry Pi - Lien permanent
L'Horloge/Réveil étant fin prête, il est temps de réviser la configuration de la WebRadio.
J'ai tout repris de zero… C'est qu'il s'est passé pas mal de temps depuis les premières expérimentations, et pas mal de version de Raspbian sont passées sous les ponts !
Pour rappel, j'ai décidé d'articuler la WebRadio autour d'un Raspberry Pi 1 (où Rpi zeroW car le 1 n'est plus en vente), de quelques boutons d'interactions, d'une cellule infrarouge et d'un écran LCD (facultatif) bon marché type radar de recul.
- On va ici étudier la partie software, la partie hardware concernant le câblage des GPIO, relais et interfaçage horloge, pilotée par le programme mpc.py venant au prochain billet.
1 - Installer et configurer Raspbian Lite :
- Télécharger Raspbian Lite https://www.raspberrypi.org/downloads/raspbian/
- Déployer l'image sur une carte SD depuis un système GNU/Linux, avec la commande DD
(attention, of=/dev/sdx à adapter pour la cible de votre carte SD, en cas d'erreur risque d'effacement d'un disque dur non désiré)
dd bs=4M if=2017-11-29-raspbian-stretch-lite.img of=/dev/sdx; sync
- Placer la carte SD dans le Raspberry, et le mettre sous tension.
Exécuter raspi-config, et configurer tous les trucs comme on veut, notamment les variables locales (time zone, clavier, etc), et surtout le login automatique de l'utilisateur.
sudo raspi-config
Après le reboot, pour rappel :
Login : pi
Pass : raspberry
- Effectuer les mises à jour :
sudo apt update sudo apt upgrade
- Mettre les fichiers temporaires en ram pour économiser sur la durée de vie la la carte SD.
sudo nano /etc/fstab
tmpfs /tmp tmpfs defaults,size=256M 0 0 tmpfs /var/tmp tmpfs defaults,size=256M 0 0 tmpfs /var/log tmpfs defaults,size=256M 0 0
- Pour configurer le wifi, éditer le fichier /etc/wpa_supplicant/wpa_supplicant.conf et modifier comme suit la section wlan0 : (ou par raspi-config)
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=FR
network={
ssid="le nom du réseau wi-fi"
psk="le mot de passe du réseau wi-fi"
}
- Relancer ensuite le réseau avec la commande :
sudo service networking restart
- Pour régler la résolution d'écran afin de l'adapter au petit écran type radar de recul :
sudo nano /boot/config.txt
framebuffer_width=320 framebuffer_height=240
- Configurer la sortie sonore sur le jack plutôt que le HDMI (par défaut) :
amixer cset numid=3 1
- Régler le niveau sonore, puis sauvegarder les modifications :
alsamixer sudo alsactl store 0
2 - Les logiciels pour la WebRadio :
- Installer le lecteur de musique, le pilotage GPIO et la synthèse vocale :
sudo apt install mpd mpc wiringpi espeak
- Configuration du lecteur mpc/mpd, éditer :
sudo nano /etc/mpd.conf
Indiquer les chemins où seront stockés les playlists et les fichiers mp3 :
music_directory "/home/pi/music" playlist_directory "/home/pi/playlists"
Puis relancer le service mpd
sudo service mpd restart
- Écriture d'une playlist de station de radio :
Créer un fichier portant l’extension .m3u avec simplement la liste des URL des stations radio
nano /home/pi/playlists/radio.m3u
# StahlRadio - Metal - http://stahlradio.de/ http://streamplus52.leonex.de:22810/; # Radio Metal - http://www.radiometal.com/ http://stream.radiometal.com:8010 # EBM Radio - Industrial, Futurepop, Synthipop, Dark Wave, Gothic, ... et Depeche Mode http://ebm-radio.org:9000/ebm.ogg # japanfm http://radio.japanfm.fr/japan # TSF Jazz http://tsfjazz.ice.infomaniak.ch:80/tsfjazz-high # Radio Neo - Français http://stream.radioneo.org:8000/;chat.mp3 # Radio Equinoxe - Electo - http://radioequinoxe.com/radio/liens-decoute/ http://www.radioking.com/play/radio-equinoxe/76118
- Écriture d'une playlist de fichier mp3 :
Créer un fichier portant l’extension .m3u avec simplement la liste des fichiers mp3 (stockés dans le dossier /home/pi/music)
nano /home/pi/playlists/FarCryBloodDragon.m3u
01. Rex Colt.mp3 02. Blood Dragon Theme.mp3 03. HELO-73.mp3 04. Warzone.mp3 05. Moment of Calm.mp3 06. Dr Elizabeth Darling.mp3 07. Power Core.mp3 08. Protektor.mp3 09. Sloan.mp3 10. Sloan's Assault.mp3 11. Blood Scope.mp3 12. Combat I.mp3 13. Combat II.mp3 14. Combat III.mp3 15. Katana.mp3 16. Omega Force.mp3 17. Nest.mp3 18. Rex's Escape.mp3 19. Love Theme.mp3 20. Sleeping Dragon.mp3
- Et attention, pour que les fichiers mp3 soient pris en compte, il est nécessaire de scanner le dossier « music », sinon les mp3 ne fonctionneront pas !!
mpc update
- La config est prête, voici le programme python mpc.py qui exploite tout ça pour fournir le service :
#!/usr/bin/env python2.7
# coding: utf-8
# on importe les modules nécessaires
import time
import os, sys
import RPi.GPIO as GPIO
import subprocess
import socket
# on met RPi.GPIO en mode notation BCM (numéro des pins)
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# on initialise les GPIO en mode "écoute" (GPIO1 sur la nappe)
GPIO.setup(17, GPIO.OUT, initial = GPIO.LOW) # GPIO0 - pin11 - Relais Ampli
#GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP) # GPIO1 - pin12 - LIRC
GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_UP) # GPIO2 - pin13 - Station suivante
GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_UP) # GPIO3 - pin15 - PowerOFF
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP) # GPIO4 - pin16 - Station précédente
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP) # GPIO5 - pin18 - LCD ON/OFF
GPIO.setup(25, GPIO.IN, pull_up_down=GPIO.PUD_UP) # GPIO6 - pin22 - Play/pause/stop ne fonctionne plus à cause de la tempo 1H
GPIO.setup(4, GPIO.OUT, initial = GPIO.LOW) # GPIO7 - pin7 - Relais LCD
long_press = 1
very_long_press = 3
site = 'www.google.fr'
# Nettoyage lecteur média
os.system('mpc clear')
def is_connected(REMOTE_SERVER):
try:
# see if we can resolve the host name -- tells us if there is a DNS listening
host = socket.gethostbyname(REMOTE_SERVER)
# connect to the host -- tells us if the host is actually reachable
s = socket.create_connection((host, 80), 2)
return True
except:
pass
return False
# Chargement de la playlist
if is_connected(site):
# print "Site disponible"
os.system('mpc load radio')
else:
# print "Site indisponible"
os.system('mpc load foo')
# au bout de QUelques minutes, stopper la lecture
heure=0
fin=9999999999
# fonction qui sera appelée quand on appuiera sur le bouton 25
def bouton25(a):
global fin
button_press_timer = 0
GPIO.remove_event_detect(25) # empéche le bouton d'etre détecté x fois de plus
while True:
if(GPIO.input(a) == GPIO.LOW ): # bouton appuyé
button_press_timer += 0.2 # incrémente tant que le bouton est maintenu
else: # bouton relaché
if (button_press_timer > very_long_press):
# Arret du lecteur media
os.system("espeak 'Arrêt de la wéb-radio !' -v fr+f5 -s150 -p 75 -a 300") # Voix synthétique
subprocess.call(["mpc stop"], shell=True)
GPIO.output(17, GPIO.LOW) # relais ampli OFF
elif (button_press_timer > long_press):
# Pause du lecteur media
os.system("espeak 'playlist Far Cry Blood Dragon' -v en+f5 -s150 -p 75 -a 300")
os.system('mpc clear')
os.system('mpc load FarCryBloodDragon')
os.system('mpc play')
elif (button_press_timer > 0):
# Lecture du lecteur media
GPIO.output(17, GPIO.HIGH) # relais ampli ON
os.system('mpc clear')
# Chargement de la playlist
if is_connected(site):
# print "Site disponible"
os.system('mpc load radio')
os.system("espeak 'lecture' -v fr+f5 -s150 -p 75 -a 300")
os.system('mpc play 2')
fin=time.time()+3600 # attend 1h - 3600
fin=round(fin)
else:
#print "Site indisponible"
os.system('mpc load foo')
os.system("espeak 'lecture' -v fr+f5 -s150 -p 75 -a 300")
os.system('mpc play')
fin=time.time()+3600 # attend 1h - 3600
fin=round(fin)
button_press_timer = 0
time.sleep(0.2)
# fonction qui sera appelée quand on appuiera sur le bouton 27
def bouton27(channel):
# entrée suivante du lecteur media
os.system("espeak 'station suivante' -v fr+f5 -s150 -p 75 -a 300")
os.system("mpc next")
# fonction qui sera appelée quand on appuiera sur le bouton 23
def bouton23(channel):
# entrée précédente du lecteur media
os.system("espeak 'station précédente' -v fr+f5 -s150 -p 75 -a 300")
os.system("mpc prev")
# fonction qui sera appelée quand on appuiera sur le bouton 22
def bouton22(channel):
os.system("sudo poweroff")
# fonction qui sera appelée quand on appuiera sur le bouton 24
def bouton24(b):
global fin
button_press_timer = 0
GPIO.remove_event_detect(24) # empéche le bouton d'etre détecté x fois de plus
while True:
if(GPIO.input(b) == GPIO.LOW ): # bouton appuyé
button_press_timer += 0.2 # incrémente tant que le bouton est maintenu
else: # bouton relaché
if (button_press_timer > long_press):
GPIO.output(4, GPIO.LOW) # relais LCD OFF
os.system("espeak 'Éteindre lécran LCD' -v fr+f5 -s150 -p 75 -a 300")
GPIO.output(17, GPIO.LOW) # relais ampli OFF
elif (button_press_timer > 0):
os.system('mpc stop') # stop la radio
GPIO.output(4, GPIO.HIGH) # relais LCD ON
GPIO.output(17, GPIO.HIGH) # relais ampli ON
os.system("espeak 'Allumage de lécran LCD' -v fr+f5 -s150 -p 75 -a 300")
fin=time.time()+3600 # attend 1h - 3600
fin=round(fin)
button_press_timer = 0
time.sleep(0.2)
# on met le bouton en écoute
GPIO.add_event_detect(27, GPIO.FALLING, callback=bouton27, bouncetime=200)
GPIO.add_event_detect(22, GPIO.FALLING, callback=bouton22, bouncetime=200)
GPIO.add_event_detect(23, GPIO.FALLING, callback=bouton23, bouncetime=100)
GPIO.add_event_detect(24, GPIO.FALLING, callback=bouton24, bouncetime=200)
GPIO.add_event_detect(25, GPIO.FALLING, callback=bouton25, bouncetime=200)
# on lance une boucle infinie, pour garder le script actif
while True:
if (heure>=fin):
os.system("mpc stop")
GPIO.output(17, GPIO.LOW) # relais ampli OFF
GPIO.output(4, GPIO.LOW) # relais LCD OFF
fin=9999999999
else:
heure=time.time()
heure=round(heure)
# une petite pause entre chaque boucle, afin de réduire la charge sur le CPU
time.sleep(2)
# on réinitialise les ports GPIO en sortie de script
GPIO.cleanup()
- Le fonctionnement est simple :
- Le bouton 25 pour allumer et éteindre la radio, ou lancer une playlist mp3, par des appuies plus ou moins long (l'ampli audio est géré automatiquement).
- Le bouton 27 pour passer à la station radio suivante.
- Le bouton 23 pour passer à la station radio précédente.
- Et enfin, le bouton 24 pour allumer et éteindre l'écran LCD (et l'ampli audio).
- Lorsque la radio est allumée, soit par l'alarme de l'horloge, ou par le bouton 25, elle fonctionne durant 1h avant de s'éteindre. Idem pour l'écran LCD.
- Si internet n'est pas disponible, la radio bascule sur une playlist mp3 de secours.
- Pour démarrer automatiquement le programme python dés le démarrage du Raspberry, créer un service pistart.service :
sudo nano /etc/systemd/system/RadioReveil.service
[Unit] Description=Démarre le script de la webradio [Service] ExecStart=/usr/bin/python /home/pi/mpc.py [Install] WantedBy=multi-user.target
- Installer le service :
sudo systemctl --system daemon-reload sudo systemctl enable RadioReveil.service
- Pour manipuler le service :
sudo systemctl status RadioReveil.service sudo systemctl start RadioReveil.service
3 - Installer et configurer Kodi :
Le médiacenter est facultatif, il ouvre cependant sur une galaxie de possibilités…
sudo apt-get install kodi
- Pour lancer Kodi automatiquement après l'autologin, éditer le fichier .profile :
nano ~/.profile
Et ajouter les lignes suivantes à la fin :
tty=`tty`
# Start Kodi only if login in tty1
if [ $tty = '/dev/tty1' ]; then
kodi
fi
- On prendra soins de configurer Kodi dans la résolution vidéo minimale (640x480), mais au vu de la faible résolution de l'écran LCD, il s'avère nécessaire d'afficher de grande police de caractère.
Pour cela éditer :
nano .kodi/addons/skin.confluence/720p/Font.xml
À la sous section <Name> font13, augmenter la valeur <Size> à 50 (initialement réglée à 20).
<name>font13</name> <filename>Roboto-Regular.ttf</filename> <size>50</size>
À la sous section <Name> fontContextMenu', augmenter la valeur <Size>'' à 50 (initialement réglée à 18).
<name>fontContextMenu</name> <filename>Roboto-Regular.ttf</filename> <size>50</size>
À la sous section <Name> font12_title, augmenter la valeur <Size> à 50 (initialement réglée à 17).
<name>font12_title</name> <filename>Roboto-Bold.ttf</filename> <size>50</size>
4 - La télécommande infra-rouge :
Utile au médiacenter, cette partie est donc également facultative !
- Installer le soft de gestion de l'infrarouge :
sudo apt-get install lirc
- Éditer hardware.conf pour régler les paramètres de LIRC :
sudo nano /etc/lirc/hardware.conf
######################################################## # /etc/lirc/hardware.conf # # Arguments which will be used when launching lircd LIRCD_ARGS="--uinput" # Don't start lircmd even if there seems to be a good config file # START_LIRCMD=false # Don't start irexec, even if a good config file seems to exist. # START_IREXEC=false #Try to load appropriate kernel modules LOAD_MODULES=true # Run "lircd --driver=help" for a list of supported drivers. DRIVER="default" # usually /dev/lirc0 is the correct setting for systems using udev DEVICE="/dev/lirc0" MODULES="lirc_rpi" # Default configuration files for your hardware if any LIRCD_CONF="" LIRCMD_CONF="" ########################################################
- Activer le module sur le RpiPi en éditant config.txt
sudo nano /boot/config.txt
Dé-commenter la ligne (sans autre argument, c'est le GPIO18 qui sera écouté par le module, sinon pour par exemple le GPIO23, on indiquera dtoverlay=lirc-rpi,gpio_in_pin=23) et redémarrer le RpiPi.
dtoverlay=lirc-rpi
- Pour tester si les commandes infrarouge sont bien reçues :
sudo killall lircd sudo mode2 -d /dev/lirc0
Si jamais le programme ça répond ceci :
Using driver devinput on device /dev/lirc0 Trying device: /dev/lirc0 Using device: /dev/lirc0 Partial read 8 bytes on /dev/lirc0
Alors on est en présence d'une Raspbian stretch (9), lircd buggée, pour corriger le problème, lancer le script :
sudo /usr/share/lirc/lirc-old2new
- À chaque appuie sur une touche de la télécommande, devrait s'afficher ce genre de truc :
space 1223 pulse 281 space 1193 pulse 350 space 1199 pulse 264 space 1901
- Bien, maintenant on va identifier la télécommande et associer chacun de ses boutons à une touche du clavier. Le programme va demander d'appuyer anarchiquement sur toutes les touches, puis de nommer les touches une à une. La syntaxe à respecter pour les noms est disponible en exécutant :
irrecord --list-namespace
Il est temps de procéder :
sudo irrecord -d /dev/lirc0 telecommande
Suivre la procédure indiquée par le programme…
J'ai choisis ces touches du clavier, qui correspondent aux raccourcis clavier les plus utile de Kodi, pour la simple raison que ça fonctionnera directement ! Pas la peine de configurer quoi que ce soit dans Kodi !
KEY_Up
KEY_Down
KEY_Right
KEY_Left
KEY_Enter
KEY_C (click droit)
KEY_PageUp
KEY_Esc (retour menu principal)
KEY_Back (retour menu précédent)
KEY_Rewind
KEY_Stop
KEY_PlayPause
KEY_FastForward
- Voici le contenu de telecommande.lircd.conf' qui a été créé, le déplacer dans /etc/lirc/lircd.conf.d/ pour qu'il soit pris en compte par lirc''
begin remote
name remoteLongue
bits 16
flags SPACE_ENC|CONST_LENGTH
eps 30
aeps 100
header 9053 4449
one 609 1642
zero 609 514
ptrail 608
repeat 9051 2202
pre_data_bits 16
pre_data 0x807F
gap 108017
toggle_bit_mask 0x0
begin codes
KEY_Up 0x10EF
KEY_Down 0x08F7
KEY_Right 0x807F
KEY_Left 0x30CF
KEY_C 0xA05F
KEY_PageUp 0xB04F
KEY_Back 0x20DF
KEY_Rewind 0x708F
KEY_Stop 0x8877
KEY_PlayPause 0x50AF
KEY_FastForward 0x48B7
KEY_Enter 0x00FF
end codes
end remote
- Reste à redémarrer le service LIRC
sudo service lircd restart
- Un moyen simple de savoir si ça marche, c'est de simplement appuyer sur les touches de la télécommande, ça devrait agir dans la console GNU/Linux ![1]
Par exemple la touche correspondant à KEY_C affichera le caractère C, normal quoi, puisque LIRC permet ainsi d'assigner l'entièreté des touches du clavier, et plus encore.
- Au lancement de Kodi la télécommande devrait fonctionner
Si ce n'est pas le cas, ressortir et vérifier que le processus lircd tourne bien.
ps -A | grep lirc
À suivre…
Note
[1] La console tty de votre choix connecté en HDMI, ça ne fonctionne pas depuis ssh !











