Wiringpi problème d'import php

Bonsoir,

J’ai un script python qui fait un import de la librairie wiringpi pour gérer les GPIO depuis Python.
Mon script tourne très bien quand je le lance en console.
Par contre, j’ai une page web php (/var/www/html) qui exécute le script Python, et ça bloque au niveau de l’import :

Pour faire simple, voici un script allégé :

#!/usr/bin/env python
print("BBB")
import wiringpi
print("AAA")

Et ma ligne php :

exec ( 'python /home/pi/Scripts/test.py', $output,$return_var );

Si je lance depuis la console, j’ai bien « BBB » et « AAA » qui s’affiche.
Si j’exécute la ligne php, je n’ai pas le « AAA »… Par contre, si je commente le « import wiringpi », ça passe…

D’où cela peut venir ?

Merci.

Bonjour ,

Quelle est la sortie du fichier error de php ?

Apache2 : /var/log/apache2/error.log
Nginx : /var/log/nginx/error.log

Il me semble que les ports GPIO sont accessibles que par un utilisateur devant être root. Votre script est executé par un utilisateur par défaut celui qui a été configuré lors de la compilation du daemon/serveur web (ex: www-data). Il va falloir procéder autrement pour pouvoir accèder aux ports GPIO, peut-être voir par ici…

https://www.raspberrypi.org/forums/viewtopic.php?t=73924

exec ( 'python /home/pi/Scripts/test.py', $output,$return_var ) || die("Erreure exec");

est-ce que « AAA » s’affiche ou Erreur exec…?

Activez les logs dans php.init, cela vous facilitera la tâche pour voir vos erreurs en sortie dans votre page html. (si cela n’est pas déjà fait)

Bonsoir hyt82909,

Merci pour ta réponse.
Dans le log d’erreur php, je n’ai strictement rien… J’ai activé les logs dans php.init, mais rien ne s’affiche…
Quand je mets la commande :
exec ( 'python /home/pi/Scripts/test.py', $output,$return_var ) || die("Erreure exec");
J’ai « Erreur exec » qui s’affiche.

Je pense bien que c’est une question de droits sur les port GPIO, je vais fouiller là dedans

Par contre, si je gère mes GPIO directement en bash, ça fonctionne depuis le php. Par exemple la commande

exec ( 'echo "1" > /sys/class/gpio/gpio23/value', $output,$return_var ) || die("Erreur exec");

m’affiche « Erreur exec », mais le GPIO23 a bien été mis à 1 !

Bonjour,

Normalement, je dis bien normalement car j’ai toujours vu cela uniquement, pour travailler avec perl, python etc sur un serveur web il faut utiliser les CGI (Common Gateway Interface — Wikipédia). Cela se fait en installant le nécessaire sur le serveur web et permet de définir l’execution de fichier avec une extension en fonction du langage choisi et de configurer plus ou moins automatiquement l’environnement d’exécution, ici python sur apache:

https://bruno.lsis.univ-tln.fr/python/cgi

L’intérêt en faisant cela et que le serveur a les variables d’environnements configurées et donc les chemins des librairies python sont trouvées et le script alors exécutable. Il est possible que votre problème vient de là si ce n’est pas à cause des droits root pour l’accès aux ports GPIO.

En fait par défaut votre serveur (si il est configuré avec php) va conprendre ce type d’url:
https://unsite.com/index.php ou https://unsite.com/index.html ...
pour qu’il comprenne ceci :
https://unsite.com/index.py
Il faut le configurer pour et pour cela on utilise les CGI.

Depuis la doc php :
http://php.net/manual/fr/function.exec.php
return_var
Si l'argument return_var est présent en plus du tableau output, alors le statut de retour d'exécution sera inscrit dans cette variable.

Que donne un :

exec ( 'python /home/pi/Scripts/test.py', $output,$return_var );
echo "ERREUR: ".$return_var.PHP_EOL; 
echo "BUFFER: ".$output.PHP_EOL;  

Puis votre script doit être à un endroit où le serveur à le droit d’accès. Actuellement /home/pi/Scripts/… est le chemin de votre utilisateur sous Linux alors que pour les serveurs webs en principe c’est plus par ici /var/www/ ou /var/www/html par défaut avec pour apache l’utilisateur et groupe www-data (vous ne m’avez pas spécifié le type de serveur que vous utilisez, ça faciliterai la tache pour vous aider) . Avez-vous fait ceci :

sudo chmod -R ug+rwx /home/pi/Scripts
sudo chmod -R o-rwx /home/pi/Scripts
sudo chown -R www-data:www-data /home/pi/Scripts

Autre chose importante , avez-vous fait ceci (en ajustant le nom de l’utilisateur et le groupe en fonction du votre):
Cette action n’est pas nécessaire si vous avez celle juste ci-dessus, -R spécifie une récursion

sudo chmod ug+rwx /home/pi/Scripts/test.py
sudo chmod o-rwx /home/pi/Scripts/test.py
sudo chown www-data:www-data /home/pi/Scripts/test.py

Votre exec est lancé en PHP et donc par le serveur web , l’utilisateur et le groupe du serveur web précisément. Donc si vous n’avez pas ajuster les droits comme il faut et assigné le bon propriétaire cela ne fonctionnera pas.

Pour vérifier les droits actuels sur un fichier/dossier sur linux:

ls -l /home/pi/Scripts
ls -l /home/pi/Scripts/test.py

vous devez avoir le bon utilisateur, le bon groupe et les droits (r=read, w=write, x=executable) sur les fichiers/dossiers, utilisateur et groupe correspondant au serveur et les droits en fonction de vos besoins, sachant que ‹ r › (read, lire, droit de lecture, droit de lire le fichier en français) est le minimum pour pouvoir avoir une sortie et voir quelque chose.

En php une commande system en appelant id vous donnera des informations :

system("id");

Puis observez la sortie dans votre page html/php.

Bonjour hyt82909,

Merci pour l’aide, mais ça ne fonctionne toujours pas. Voici les résultats des différents tests.
Pour info, mon serveur web est nginx.

exec ( 'python /home/pi/Scripts/test.py', $output,$return_var );
echo "ERREUR: ".$return_var.PHP_EOL; 
echo "BUFFER: ".$output.PHP_EOL;

me donne

ERREUR: 1 BUFFER: Array


La commande

system("id");

me donne

uid=33(www-data) gid=33(www-data) groups=33(www-data),20(dialout)

J’ai aussi testé d’ajouter www-data au groupe « gpio », mais rien ne change…

Concernant les CGI, j’avais déjà installé tout ce qu’il fallait et ça fonctionne pour des scripts simples, par exemple, si j’ai dans mon script cgi-bin/hello.py :

#!/usr/bin/env python
print "Content-type: text/html\n\n"
print "<h1>Hello World</h1>"

Et que je vais sur http://mon-serveur/cgi-bin/hello.py, ça m’affiche bien « Hello World ».
Par contre, si j’ai un fichier cgi-bin/test.py :

#!/usr/bin/env python
print "Content-type: text/html\n\n"
print "AAA"
import wiringpi
print "BBB"

Le script se stoppe au niveau de l’import et seulement AAA s’affiche. Si je commente l’import, alors BBB s’affiche…
J’ai donné tous les droits aux scripts Python pour www-data…

J’ai peut-être un début de réponse.
J’ai créé un utilisateur avec les mêmes droits que www-data, et quand j’exécuté le script en console avec python, j’ai une erreur au niveau de l’import :

ImportError: No module named wiringpi

Du coup j’ai l’impression que ma librairie s’est installée uniquement pour mon utilisateur pi…

Pour gérer les problèmes d’import :

try:
       import wiringpi
except ImportError:
      raise ImportError('wiringpi non trouvé')

Autre choix , utiliser wirinpi en php ? GitHub - WiringPi/WiringPi-PHP: PHP wrapper for WiringPi

Je testerai avec wirinpi du coup.
Entre temps, j’ai testé avec la librairie Rpi.GPIO et là ça a fonctionné ! C’était donc bien un problème lié à Wiringpi.