Comment faire revivre ce périphérique de l’âge des Nabaztag pour piloter un Mac :
Une histoire avec du C/C++, une dose de Bash et un peu d’AppleScript (osascript) et une bidouille
avec VLC
A. On commence à penser le truc sur le linuX…
L’idée : c’est de piloter le périphérique depuis un Linux mais exécuter des commandes sur d’autres machines. Pour piloter les Macs, j’utilise des scripts AppleScript lancés au travers d’un tunnel SSH.
1. Je me base sur le projet reflektor que je compile sur le linuX…
2. Ce projet écrit en C fabrique un fichier caché (.reflektor_do) dans le répertoire de l’utilisateur avec l’ID des Tags et la commande à exécuter :
show d0021a053b453906:/home/user/mirror/actions_do.sh show d0021a053b368906 hide
d0021a053b453906:/home/user/mirror/actions_do.sh hide d0021a053b368906 hide
3. Je monte un script Bash qui récupère les appels et obtient les actions ainsi que les ID des Tags :
#!/bin/bash
action=$1
tagid=$2
# Tag Blue
if [ "$action" == "show" ] && [ "$tagid" == "d0021a053b368906" ]; then
ssh user@mac "osascript -e 'tell application \"iTunes\" to play'"
fi
Cela fonctionne parfaitement ! les appels SSH sont rapides.
Un problème tout de même : le Mir:ror reste allumé !! Je peux le désactiver dans le code C du software mais c’est fixe 🙁 et le retourner tous les soirs… c’est pas gagné…
A faire par la suite :
• Soit : Apprendre à éteindre un port USB sur le LinuX,
• Soit : Utiliser node.js pour envoyer des commandes au Mir:ror avec la bibliothèque node-hid.
B. On repense le truc mais cette fois sur le Mac…
En plaçant le système dans le mac, je pilote mieux les actions et peux couper le Mir:ror en éteignant le Mac.
1. J’utilise cette fois ci le projet hdiapi ainsi qu’une partie des modifications trouvés sur ce site .
2. Cette fois ci, le projet en C++ permet de fabriquer l’exécutable hidtest.
3. J’apporte quelques modification au fichier hidtest avant de compiler :
# buf[1] Permet d'avoir l'action
# buf[8] Permet de récupérer une une partie de l'ID du TAG pour l'identifier
if (buf[1] == 1 && buf[8] == 5) {
printf(" IN 5");
system("~/Library/\"Application Support\"/Mirror/actions_do.sh show blue");
}
...
4. Je garde presque le script précédent pour récupérer les appels et obtientir les actions ainsi que les ID des Tags :
#!/bin/bash
action=$1
tagname=$2
# Lancer une radio dans un VLC sans interface, récupérer le PID pour
# pouvoir détruire l'instance lorsque le Tag est caché.
# VLC -I http => Pas d'interface graphique, juste l'interface http.
# VLC --http-host 127.0.0.1:8085 => Permet de router le port de ce VLC du 8080 par
# défaut vers le 8085 de manière à ne pas la voir dans l'appli Mobile.
if [ "$action" == "show" ] && [ "$tagname" == "blue" ]; then
PROGRAM="/Application/VLC.app/Contents/MacOS/VLC -I http --http-host 127.0.0.1:8085 http://...mp3"
$PROGRAM &
echo $! > /tmp/vlc.pid
fi
if [ "$action" == "hide" ] && [ "$tagname" == "blue" ]; then
PID=$(cat /tmp/vlc.pid)
kill -15 $PID
fi
5. Je fabrique un service de lancement pour le mac avec Lingon. A placer dans Library/LaunchAgents de l’utilisateur :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>fr.lcprod.mirror</string>
<key>ProgramArguments</key>
<array>
<string>__chemin_vers_hidtest</string>
</array>
<key>QueueDirectories</key>
<array/>
<key>RunAtLoad</key>
<true/>
<key>StartOnMount</key>
<false/>
<key>WatchPaths</key>
<array/>
</dict>
</plist>
Cela fonctionne aussi très bien !
J’aurais tout de même aimé pouvoir récupérer à partir de hditest l’ID complet du Tag !
(Je me base sur une extraction d’un bit de la chaîne.)
Problème en C++ : Impossible de récupérer dynamiquement d’ID pour le transmettre au script Shell : Comment convertir un int en char en C++ ……….