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 !