Après avoir vu la présentation « Wake up the geek way! » de Gaël Pasgrimaud à PSES 2015 dans laquelle il nous présente son logiciel-réveil configurable via IRC et qui ne sonne pas si Gaël a causé sur IRC avant l'heure programmée, j'ai eu l'idée de me faire un réveil aléatoire.
Aléatoire sur une plage d'horaire définie. L'idée derrière, c'est est de privilégier un réveil naturel (sommeil léger, tout ça, on est toujours un peu réveillé inconsciemment dans une plage horaire autour de l'heure de réveil que notre cerveau assimile par habitude) sur un réveil en force comme le fait généralement un réveil. Tout ça sans utiliser de capteurs et des bidules connectés cheppaquoi. Alors oui, si je me couche plus tard (ou plus tôt), ça n'empêchera pas le réveil de me réveiller brutalement. Forcément, y'a des jours où l'aléatoire tombe pas au bon moment.
À la différence de Gaël, je n'ai pas dev' un bout de python qui a la classe (simplement parce que la lib panoramisk n'est pas packagée dans Debian et que j'ai pas trouvé d'équivalent potable) mais j'ai choisi de le faire en mode adminsys et crade. Et vu que j'ai appris des choses sur le fonctionnement d'Asterisk bah ça m'a bien plu.
Asterisk, le serveur VOIP standard, est capable d'exécuter des appels téléphoniques tout seul simplement en lui fournissant un fichier texte qui décrit l'appel à effectuer dans /var/spool/asterisk/outgoing . Mieux que ça, Asterisk ce sert du mtime (date de dernière modif') de ce fichier pour déterminer la date et l'heure à laquelle l'appel doit être effectué ! Bref, tout simple. On notera que tout ce mécanisme repose sur inotify. Voir https://wiki.asterisk.org/wiki/display/AST/Asterisk+Call+Files
L'idée est donc la suivante : placer un script en cron.daily (qui sera exécuté tous les jours à 6h25) qui placera un fichier dans /var/spool/asterisk/outgoing avec un mtime tiré au sort. Asterisk me téléphonera sur mon 06. Évidemment, sur mon 06, je configure une sonnerie différente pour le numéro de la ligne SIP utilisée par Asterisk histoire d'être réveillé en douceur. Si je décroche, Asterisk raccroche et considére qu'il a terminé son boulot. Si je ne réponds pas ou que je rejette l'appel, on a l'équivalent d'un snooze : Asterisk me téléphonera à nouveau dans 15 minutes (paramètrable).
La première étape, c'est la configuration d'Asterisk (je pars du principe qu'Asterisk est déjà configuré / en état de marche sinon, voir ici : http://shaarli.guiguishow.info/?vHS3rA )
Vu que c'est Asterisk lui-même qui passera l'appel, il est inutile de créer un nouveau compte utilisateur dans sip.conf ;
Dans extensions.conf, il faut créer une nouvelle extension qui décrit le déroulement de l'appel. Le fichier dans /var/spool/asterisk/outgoing demande un appel mais ne dit pas ce qu'il faut faire ensuite, lorsque l'interlocuteur répond : jouer un son, raccrocher, dire quelque chose avec la synthèse vocale, proposer plusieurs choix, etc. ? Perso, je veux juste qu'Asterisk raccroche :
[Wake-Up]
exten => s,1,wait(1) ; On attend 1 seconde.
exten => s,2,Hangup(16) ; On raccroche. 16 est le code de retour qui, en SIP, indique que l'appel s'est terminé normalement, comme attendu
sip reload
depuis la console Asterisk ou sudo systemctl reload asterisk
;
La deuxième étape, c'est de créer notre cronfile (/etc/cron.daily/reveil ):
#!bin/bash
cat<<EOF > /tmp/reveil.call
Channel: SIP/<utilisateur_sip.conf OU numero_tel@ligne_SIP_sip.conf>
Callerid: WakeUpCall ; Le nom qui s'affichera si l'appel est effectué en SIP (sinon c'est le numéro de la ligne SIP…)
MaxRetries: 3 ; Combien de fois Asterisk doit essayer de re-téléphoner si l'appel est rejetté ou si pas de réponse ? En plus de l'appel initial.
RetryTime: 900 ; Combien de temps entre chaque re-essai ? Ici 15 minutes. Ce qui nous fait un snooze de 15 minutes.
WaitTime: 45 ; Combien de temps Asterisk doit-il attendre avant de déclarer que l'appel est un échec ? Ici 45 secondes. Attention : si le numéro appelé à un répondeur, il faut une durée d'appel inférieure au déclenchement du répondeur sinon l'appel sera considéré comme un succès même si c'est votre répondeur qui répond. ;)
Context: Wake-Up ; Contexte, extension et priorité dans l'extension. Ce que l'on a défini dans extensions.conf. On peut remplacer tout ça par « Application / Data » pour exécuter une application tiers.
Extension: s
Priority: 1
EOF
# Asterisk a besoin de modifier mtime pour programmer le retry
# du call. chmod 777 + proprio = root ne fonctionne pas…
chown asterisk:asterisk /tmp/reveil.call
# On veut que le réveil sonne entre 8h00 et 9h59
touch -d "$(shuf -i8-9 -n1):$(shuf -i0-59 -n1):00" /tmp/reveil.call
# mv pour garder datetime + proprio
mv /tmp/reveil.call /var/spool/asterisk/outgoing/
Dans mon cas, l'appel s'effectue en VOIP, en utilisant CSIPSimple sur mon ordiphone. L'appel ne passe jamais par le réseau commuté donc ça ne coûte rien.
Voilà pour un usage bateau. On peut aller plus loin et créer une extension qui, quand elle est déclenchée via un appel, supprime l'alarme pour la journée. Ainsi, si vous êtes réveillé avant l'heure programmée, vous désactivez le réveil en un appel. :D