Le répertoire top est nommé radiok
. Ce nom
qui peut être modifié est gardé dans la variable
d'environnement RADIOK_HOME
avec le chemin
qui mène à ce répertoire. Par exemple :
export RADIOK_HOME=/home/jplf/git/radiok
lib
contient les fichiers audio
utilisés comme feed back à certaines commandes.
vox
contient de code
d'analyse des commandes vocales. La première version
basée sur le traitement local est dans le
sous-répertoire ps
. La nouvelle version
utilisant le service google est dans le
sous-répertoire fr
.
bin
contient tous les
scripts bash
qui encapsulent les
commandes gérant mplayer
et l'application web.
run
stockent les fichiers
générés par l'application : log
files, pid, paramètres …
www/doc
contient ces pages
html avec les fichiers de style dans css
.
www/kontrol
est séparé en 2
sous-répertoires pour les parties cliente et serveur
de l'application web.
mplayer
qui
diffuse les flux radio sélectionnés mais pour simplifier un
peu son utilisation un paquet de scripts a été
développé. Ces scripts stockent des variables
d'environnement, des paramètres de configuration, etc. Ils
peuvent être utilisés tels quels pour contrôler la radio
pourvu qu'on soit connecté sur la raspberry. Néanmoins ils
ont d'abord été conçus pour être interfacés avec le serveur http.
mplayer(1)
. Il accepte les options
suivantes:
-h
affiche les options possibles et
la liste des identifiants de stations de radio.
-s
affiche le statut actuel du programme,
c'est-à-dire l'identifiant de la station et le pid du
process mplayer
.
-k
tue un process mplayer
qui
tournerait. Cette option lance le
script offair.sh
.
-l
donne la liste des stations de radio
gérées par l'application. La liste est une suite de
couples (clé, nom). La clé sert d'identifiant court, le
nom est plus explicite et peut être affiché sur une page web.
-t
permet de définir une durée pour
l'écoute de la radio.
La durée expirée mplayer
s'arrête.
Le temps doit être donné en minutes.
À l'origine ce script devait être simple. Il a grossi pour tenter de répondre à des besoins de plus en plus nombreux mais il aurait sans doute été plus judicieux de choisir un autre langage pour son écriture. Une future version pourrait être écrite en python par exemple.
mplayer
qui
tournent et met à jour les fichiers qui doivent l'être.
at(1)
mais non encore exécutés.
amixer(1)
et extrait le nombre en
pourcentage.
amixer(1)
avec la nouvelle valeur
en pourcentage ou avec un increment ou un decrement en
dB. La nouvelle valeur du volume est sauvegardée dans le
fichier run/volume
json
contenant un
certain nombre de paramètres décrivant l'état de l'application.
aplay(1)
et génère un son
avec un fichier de feedback stocké
dans lib/sounds
. Contrairement
à tell.sh
les fichiers son doivent être
enregistrés à l'avance.
say.sh
car
il est capable de générer du français correct à partir d'une
courte chaine de caractères.
whatusay
avec les options qui vont bien.
Le programme est lancé via screen(1)
ce qui
permet de récupérer en cas de besoin les messages envoyés
sur la sortie standard même si le terminal d'où est lancé le
script a disparu.
screen(1)
est utilisée pour récupérer
le terminal dans la plupart des situations.
cron(1)
au
reboot de la raspberry avec la requête @reboot
.
Comme la rpi n'a pas d'horloge sauvegardant le temps il est
nécessaire d'attendre un moment pour démarrer le serveur
web, sinon l'application prendra comme référence des temps le 1er
janvier 1970 ce qui est source de mauvaise surprise. En
attendant quelques minutes le démon ntp
a le
temps de mettre à jour l'horloge avec la valeur
fournie par les serveurs de temps trouvés sur l'internet.
Pour intéragir aisément avec le système une solution basée
sur le protocole http est toute indiquée. Une fois
implémentée on peut utiliser simplement un navigateur
internet pour démarrer, arrêter la radio, choisir une
station, mettre en service l'alarme. Il n'est plus
nécessaire de se connecter à la raspberry
par ssh
, on peut effectuer les opérations
depuis n'importe quel ordinateur relié au réseau.
Pour réaliser ce server web et l'installer sur la raspberry la technologie NodeJs a été choisie. Il y a maintenant un nombre très important de bibliothèques et de modules utilitaires pour cet environnement. La programmation se fait en javascript ce qui permet d'avoir des résultats très rapidement.
Le choix de cette technologie a été motivé par plusieurs raisons : c'est une technlogie qui a le vent en poupe, qui dispose de bibliothèques très riches, qui s'interface très facilement avec toute sorte d'environnement et qui est très performante. En revanche beaucoup d'outils sont très pauvrement documentés et il est nécessaire de faire parfois pas mal d'essai pour comprendre comment les utiliser correctement.
Naturellememt d'autres choix auraient été possibles pour
implémenter le serveur de contrôle : apache
et php
, tomcat
et jsp
, etc.
Le code se trouve dans le répertoire
www/kontrol
. Ce qui fait un peu fonction de
programme main
est dans le
fichier app.js
. Pour démarrer le serveur il
suffit de lancer : node app.js
. En fait pour
avoir les bons chemins de fichier il est préférable
d'utiliser le script bash start.sh
qui
vérifie les variables d'environnement avant de lancer
node
. L'application web est gérée par le
framework express. Ce
module fournit toutes les fonctions nécessaires à
l'implémentation d'une webapp. Malheureusement la
documentation en est particulièrement nulle mais avec
de la patience on arrive à faire ce qu'on veut.
Dans le sous-répertoire server
on trouve les
deux fichiers qui contiennent les procédures traitant les
requêtes arrivant au serveur.
/box/command/:parameter
.
start
, get_volume
, …) une
fonction callback est définie. Cette fonction effectue le
traitement, généralement le lancement d'un script bash, puis
renvoie au client une réponse qui est le résultat du
traitement.
La procédure la plus complexe concerne la gestion de
l'alarme. Le but est de déclencher à un moment déterminé
la radio. Pour utiliser l'application comme réveil-matin
il suffit de mettre en route mplayer
tous les
matins à une heure fixée. Ceci a d'abord été réalisé grâce
à un modulenode-cron
mais qui n'a plus
fonctionné après une mise à jour de
nodejs. L'implémentation actuelle manipule des
fichiers unix crontab(1)
et est
particulièrement robuste.
Ce deuxième fichier de code serveur contient les procédures
de traitement des commandes vocales. Le programme d'analyse
vocale whatusay
joue un rôle de client http
pour le serveur web. Il transmet les mots qu'il a compris
par une requête http préparée avec les fonctions de la bibliothèque
curl.
Dans vox.js
la requête
/vox/process/:word
reçu
de whatusay
est traitée en fonction du
paramètre word
: un script est exécuté pour
lancer mplayer
, régler le volume du son,
changer la station etc.
Pour plus de souplesse les mots du vocabulaire de commande
ont été groupés en synonymes.
Compte-tenu des temps de réponses parfois un peu longs
(plusieurs dizaines de secondes), dûs essentiellement au
remplissage du cache de mplayer
un retour
est donné à l'utilisateur sous forme de messages
enregistrés pour lui indiquer ce qui a été compris
correctement par le serveur ou compris de travers !
Outre les scripts bash et la commande vocale des pages web sont disponibles pour contrôler l'application. En les affichant dans un navigateur internet on peut également démarrer la radio, l'éteindre, choisir son heure de réveil, etc. en cliquant sur les boutons proposés.
Comme il se doit le code de cette interface se trouve dans le
sous-répertoire www/kontrol/client
.
Le style des pages html est défini dans le fichier
radiok.less
qu'il faut transformer avec la
commande lessc pour
créer la feuille de style radiok.css
.
Les pages web, en fait la page web puisqu'il n'y en a qu'une, sont manipulées par la bibliothèque AngularJS qui est un framework web développé par Google. La gestion des interactions fait aussi appel à la bibliothèque jQuery.
Le code javascript spécifique à l'application est
disponible dans le fichier main-module.js
dans le sous-répertoire js
. Ce code définit
la navigation - l'affichage - entre les différents
contenus : liste des stations, déclenchement de la radio,
état de l'application. Il gère les variables nécessaires à
l'application, envoie les requêtes au serveur http et
récupère les réponses du serveur.