Articles - Logiciel & scripts

Proof Of Concept - Manipulation du jukebox Pioneer via le web

  |   127  |  Poster commentaire  |  Logiciel & scripts
Problématique : comment piloter à distance le changeur Pioneer ? Tout est histoire de protocole… le problème étant que si on décide de concevoir une application web dynamique pour manipuler le jukebox, seuls des appels via AJAX ou WebSockets sont possibles. Ce qui implique une solution de "passerelle" entre le port Série du Jukebox et le monde réseau Ethernet et même web (HTTP) :

CAC-V3000 <---> ???? <---> Navigateur web



Matériellement parlant



3 solutions sont possibles :


Solution matérielle retenue : Raspberry Pi 1 B+ (en stock).

Logiciellement (avec le Raspberry Pi)



Plusieurs solutions sont possibles :

ser2net



http://techtinkering.com/2013/04/02/connecting-to-a-remote-serial-port-over-tcpip/

C'est un démon qui sous Linux permet de « rerouter » un port série /dev/ttyUSB0 vers un socket TCP. Testé avec succès, mais hélas ne convient par pour des appels HTTP, ser2net travaille de façon brute. C’est parfait pour du Telnet (Putty / MobaXterm) mais ça ne fait pas serveur web.

Script "pivot" en PHP



Méthode sale du pauvre qui fonctionne, mais pas top. Installation d'une Rasbian, de apache2 et de PHP7.0. Essai avec un script PHP maison (ici scmd.php – SingleCoMmanD) se charge de prendre une commande (par exemple 1PS?A) en paramètre d’URL (méthode GET) et de l’écrire sur le port série. Ensuite on lit le port série, récupère la ligne de réponse 1PSXXXXXXXX et renvoie le résultat. Avantage : hyper facile à mettre en œuvre. Inconvénient : Très lent. Les tests montrent un temps de réponse de 300 à 420ms de latence pour traiter une commande.




La réponse met plus de 400ms à arriver ce qui est trop long même en ayant optimisé le code au maximum. Ce qui posera souci pour l’affichage du temps (écoulé, restant). Il est à signaler que localement via les outils picocom ou minicom ce temps n’est pas observé, la réponse est instantanée même à 9600 bauds par seconde.

Le problème provient à la fois de Apache (qui lance un processus PHP à chaque fois pour chaque appel de page) mais aussi de PHP lui-même : on ne peut pas conserver en mémoire des objets persistants, notamment la connexion au port série. De ce fait à chaque appel de scmd.php on doit rouvrir le port série et le refermer, ce qui explique ce délai. PHP est donc à oublier. Il faut trouver un logiciel de type serveur web qui accepte d’avoir une connexion persistante vers le port série.

Script "pivot" en nodeJS



Installation de Node.JS et des modules ws et serialport. :


Tant qu'on y est autant passer pas les websocket plutôt que de renvoyer une "pseudo-page" de réponse texte. Les essais semblent nettement plus concluants, on tombe à moins de 55ms. Cette voie est donc à suivre sans hésiter.






Il n'y a plus qu'à blinder le code (try/catch), ajouter quelques contrôles, ajouter un timeout pour l'attente du port série, tout angliciser, accepter des commandes multiples par appel et JSONifier le tout. To be continued...

Mise à jour le 18/10/2018



J'ai essayé de comprendre pourquoi PHP pouvait être aussi lent. Pour cela j'ai comparé avec un vrai PC de. Ce sont les mêmes scripts installés sur les deux machines. Dans les captures d'écran suivantes, l'IP 192.168.0.6 correspond au Rasbperry Pi. L'IP 192.168.0.4 correspond au Thinkcentre M91p sous un Debian 9.5 que j'ai utilisé pour mes essais. Pour commencer j'ai activé opCache sur le Raspi, mais hélas cela ne fait pas mieux :




On voit le nombre de cache hits grossir mais hélas toujours 320ms. Idem avec PHP-FPM (FastCGI). Au final j'ai trouvé, je me suis fait trollé par le Prolific PL-2303. Avec le Thinkcentre je retrouve exactement cette même latence en PHP quand le Pioneer est relié via cet adaptateur USB Prolific (/dev/ttyUSB0). J'ai donc essayé avec le port série du PC (/dev/ttyS0), et bizarrement les temps sont nettement plus courts (81ms VS 380ms) :



Cette latence "d'ouverture du port" doit certainement provenir du pilote pl2303 lui-même. Au final cela n'a d'importance que pour une version PHP du service offert, cela ne change en rien pour nodeJS puisque le port reste ouvert pour chaque requête. La version nodeJS étant plus puissante et simple à implémenter c'est celle qui sera conservée pour développer l'application. Mais je filerais aussi la version PHP qui peut intéresser certains programmeurs puisqu'en fait les soucis de performances ne proviennent pas du langage comme je le pensais, cette solution reste alors valable pour de plus petits projets.

Reste à tester :
  • Si cette latence est présente aussi sur d'autres adaptateurs avec des puces FTDI.
  • Dans le cas d'un Raspi : savoir si le port UART interne via le GPIO fait la même chose, mais il faut un module MAX232 pour convertir de TTL vers RS232 (+-12V) et inverseur pour tester.


Dans tous les cas cela posera problème pour le Raspberry Pi si je dois héberger la base de données Postgres plus l'application web dessus, et pas sûr que les 512Mo tiennent. Même avec un overclock à 900Mhz le script nodeJS met plus de 12 secondes à s'initialiser et à être prêt. Alors que c'est instantané sur le Pentium G630. Visiblement c'est connu. Un passage à la version 3 voire carrément y mettre un vrai PC sera nécessaire. Sinon il faudra le cantonner à un rôle de pivot.

Un petit schéma fait avec LibreOffice Draw :