Application web générique

Vous souhaitez piloter votre framboise à partir d'une page web ? Ou mieux encore à partir d'un smartphone ou d'une tablette Android ? Venez donc visiter cette rubrique...

Modérateur : Francois

Répondre
McpCan
Messages : 2
Enregistré le : dim. 17 janv. 2021 21:20

Application web générique

Message par McpCan » lun. 18 janv. 2021 22:43

Bonjour à tous! :)

Je plante le décor!

J'ai pour idée de réaliser des applications web pour interagir via les GPIO sur le Raspberry comme beaucoup de monde !
J'ai des bases en HTML, PHP, CSS et JS pour ce qui est de la partie web.
Habituellement et via mon métier, je programme des microcontrôleurs en langage C et en assembleur.

Je m'interroge sur comment un programme "WEB" peut continuer à scruter les entrées/sorties pour le traitement alors que la page web est affichée.
Après réflexion, le programme principal doit forcément être en arrière plan et non via la page web car cela voudrait dire qu'il faut avoir la page web ouverte en permanence avec un script qui tourne en permanence sur un autre ordinateur.

Voici mes questions :

Le programme qui agit sur les E/S peut il être en C sur le Raspberry ou doit il être systématiquement en python? Je ne connais pas le langage python mais si c'est plus simple et plus courant pourquoi pas!

Comment par exemple récupérer des variables du programme C/Python pour l'afficher en temps réel sur une page web d'un autre ordinateur? J'ai entendu parler de AJAX qui serait le principe de base mais aussi de NodeJS, JQuery, NPM... Je trouve que ça part dans tous les sens! J'ai l'impression qu'il faut 50 lignes de codes et 4 fichiers différents pour faire une requête AJAX :|

C'est si compliqué de faire une requête AJAX avec juste...JS/AJAX?

Avez vous des exemples très basique pour une requête AJAX d'une variable python

J'ai trouvé des exemples mais aucun ne fonctionnait, pourtant des requêtes AJAX, c'est hyper courant!

Dur de partir de zéro!

Pour que l'on se comprenne, imaginons que je souhaite activer une sortie GPIO si la température du processeur (/opt/vc/bin/vcgencmd measure_temp) est supérieur à 30°C et afficher en temps réel la valeur de température sur une page web via un ordinateur sur le réseau.
Cette application exemple devrait englober toutes mes questions :)

Une fois que j'aurais réussi à faire ça, j'aurais des bonnes bases pour continuer avec l'I2C, PWM, etc... Mais une chose à la fois :D

Un grand merci d'avoir lu mon texte :)

A bientôt, passez une bonne nuit.

Bud Spencer
Raspinaute
Messages : 979
Enregistré le : lun. 15 août 2016 21:38

Re: Application web générique

Message par Bud Spencer » mar. 19 janv. 2021 08:46

Tu trouveras toutes les réponses à toutes tes questions en lisant ça :

Application Web Dynamique avec NodeJS :
viewtopic.php?f=44&t=3033

Application MVC Asp , Razor, Blazor ect avec .Net (core)
viewtopic.php?f=42&t=5449
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

smog
Messages : 25
Enregistré le : mar. 24 nov. 2020 08:03

Re: Application web générique

Message par smog » mar. 19 janv. 2021 08:53

Je ne vais pas répondre de manière complète à ta question, mais juste t'apporter un peu de ma (faible) expérience personnelle... En attendant que les pros t'en disent plus (édit : Maître Bud Spencer est déjà passé, suis plutôt ses conseils !!)

AJAX te permet de lancer du JS de façon asynchrone, c'est-à-dire que ça ne stoppe pas le reste de l'interprétation du code de ta page WEB. Le JS "dans" AJAX te permet de rafraîchir une partie de ta page WEB (par exemple le contenu d'une balise) sans que tu aies besoin de rafraîchir le reste de la page (évitant ainsi, par exemple, une perte de données saisies par l'utilisateur sur une autre partie de la page, ou bien une simple perte de temps de rechargement de l'intégralité de la page).
Bon, j'imagine que ça, tu le sais déjà.
Simplement tu peux, dans ta requête AJAX (via l'objet XMLHttpRequest), exécuter par exemple un script PHP qui renverra du texte, un JSON ou un XML : ce contenu peut être le résultat de la lecture d'un port GPIO.
C'est ce "retour" que tu feras afficher à l'intérieur d'une balise HTML.

Je pense que tu as pu voir cet exemple sur framboise.fr, qui illustre le principe (même s'il ne fait pas une lecture de donnée d'un capteur, il commande les GPIO, ce qui est intéressant à comprendre) :
https://www.framboise314.fr/une-interfa ... rry-pi-12/

Je n'ai jamais utilisé Python avec AJAX, pour moi c'est du Python orienté serveur qui permet de mixer les deux. Mais là je ne peux t'en dire plus.

Sinon, si tu utilises des scripts en C ou Python qui peuvent renvoyer des variables, il y a CGI qui est assez simple (tu récupères la ou les chaînes de caractère envoyée(s) par le script). Mais c'est un peu vieux et lourd comme méthode, il doit y avoir plus adapté comme le montre Bud. Mais depuis un script C ou Python qui envoie des chaines, ça a l'avantage d'être rapide à mettre en œuvre.

Bud Spencer
Raspinaute
Messages : 979
Enregistré le : lun. 15 août 2016 21:38

Re: Application web générique

Message par Bud Spencer » jeu. 21 janv. 2021 12:23

Ajax c'est bien, mais ce n’est pas une solution viable pour ce genre de chose. Ça fonctionne mais c’est très lourd, très limité et plein d’inconvénients. On peut s’en satisfaire s’il ni a qu’un seul client pas trop exigeant et que seul lui peut agir sur les gpios. Ca peut aussi le faire pour par exemple recupérer périodiquement des données qui ont beaucoup d’inertie ou qui ne changent pas sans arrêt comme la température d’une pièces, le niveau d’une cuve ect … En fait, ca le fait comme ca peu si on ne sait pas comment faire autrement et que l'on est pas trop gourmand sur le besoin et sur la fiabilité.

Imaginez un script ou un programme (en python, en c, en bash, en polonais ou en n’importe quoi d’autre …) qui positionne ou inverse l’état d’une sortie GPIO et qui retourne l’état résultant. Votre script coté serveur web reçoit une requête (envoyé par le client avec Ajax) qui lui demande d’exécuter ce programme (genre une fonction shell_exec() en php) et de retourner le résultat au client pour que ce dernier mette son affichage à jour. Pas de problème, ça fonctionne.

Maintenant, on a 2 clients. L’un demande un changement d’état et pendant qu’il reçoit la réponse, l’autre client demande lui aussi un changement. Résultat, le premier se retrouve avec un état qui n’est pas le bon. Je ne sais pas pour vous, mais perso, une solution qui me donne 50% de chance d’afficher la bonne valeur d‘un état boolean, ce n’est pas une solution, c’est un problème

Autre cas avec un seul client qui veut connaitre l’état d’une entrée susceptible de changer souvent. Pour ça, le client appel régulièrement sa fonction Ajax avec un timer. Ici aussi, rien ne garantit qu’entre le moment où l’on a reçu la dernière réponse et jusqu’à la prochaine demande, l’état n’a pas changé. En fait on ne connait l’état de l’entrée qu’au moment précis où le script distant a été exécuté.

Pour minimiser ces inconvénients, je vois souvent que ceux qui utilisent ces méthodes ont tendance à interroger de plus en plus souvent le serveur. En effet, si on interroge toutes les secondes par exemple, on sera toujours plus près de la vérité qu’en interrogeant toutes les minutes … sauf qu’à chaque demande, c’est un nouveau process instancié par le serveur, et finalement de la charge cpu mangé pour rien surtout si l’état retourné est le même que le précédent. Je sais bien que la plupart d‘entre vous ne programmez que des bricoles que seul vous utilisez périodiquement, mais imaginez ce genre de chose avec plusieurs ( …dizaines … centaines …) de clients qui envois toutes les secondes une requête vers le serveur et ce dernier qui passe son temps à créer des process pour aller lire l’état d’une gpio et répondre individuellement à chacun… En plus on ne parle ici que de la lecture d’une gpio, qu’est ce que cela serait si le script ou programme exécuté devait lire tout un tas de capteurs et positionner tout autant de sortie avant de finir ?

Ajax sert avec succès dans beaucoup de cas, mais pour ce genre de chose, c’est tout à fait inadapté parce que ce n’est juste pas fait pour ça. Le problème principale d’Ajax dans ce cas d’usage, c’est que la demande ne peut être faite que par le client et la réponse ne s‘adresse lui seul.

Dans le contexte, l’idéal serait qu’à chaque fois qu’une gpio change d’état (à la demande d’un client ou par n’importe quel autre procédé), tous les clients reçoivent l’information en temps réel et se mettre à jour sans rien à voir à demander au serveur. Cela soulagerait le serveur qui ne recevrait plus toutes ces requêtes incessantes, qui n’aurait plus à exécuter sans cesse de nouveau process et qui n’enverrait qu’un seul broadcast pour tous ses clients seulement quand l’état changerait. Cela soulagerait aussi tous les clients qui n’auraient pas à interroger sans cesse le serveur et traiter toutes les réponses quelles soit utiles ou pas. On pourrait même aller jusqu’à imaginer un petit programme unique qui ferait office de serveur web et qui serait capable d’agir en lecture et écriture sur les GPIO sans exécuter d’autre programmes externes. Il pourrait même aller demander périodiquement des données à d’autres serveurs sur le net (api météo ou autre), a une base de données mise à jour par d’autre procédés, interroger d’autre appareils (post serie, wifi, rf ….) ect … et alimenter en temps réel tous ses clients connectés avec des donnés à jour. Si en plus on pouvait faire tout ça avec infiniment moins de code en consommant infiniment moins de ressources et en plus avec des performances hallucinantes, ce serait génial non ?

Et bien c’est tout simplement ce qui est exposé dans les 2 tutos que je vous ai cité plus haut. Si vous êtes débutant genre petit script occasionnel et un peu de web a l’occase, je vous recommande vivement NodeJs. Pour moi ça reste le meilleur rapport possibilités / facilités / performances pour ce genre d‘application sur le PI et tout ça avec seulement du JavaScript. Si par contre vous avez déjà un peu de bouteille en programmation et que la poo vous est familière (que ce soit en c++, java ou autre), alors n’hésitez pas et tournez vous vers .Net (core) 5. Vous pouvez aussi faire le meme genre de chose avec python en utilisant un framework comme flask ou django par contre, attention avec les updates (...) et prévoyez beaucoup plus de code sans attendre même niveau de performance
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

destroyedlolo
Raspinaute
Messages : 1483
Enregistré le : dim. 10 mai 2015 18:44
Localisation : Dans la campagne à côté d'Annecy
Contact :

Re: Application web générique

Message par destroyedlolo » jeu. 21 janv. 2021 18:54

Salut,

Le plus simple est évidement d'utiliser une solution avec un serveur web intégré : NodeJS évidemment, mais aussi Lua, C voir meme Python.

Cependant, pour répondre a tes questions :
McpCan a écrit :
lun. 18 janv. 2021 22:43
Je m'interroge sur comment un programme "WEB" peut continuer à scruter les entrées/sorties pour le traitement alors que la page web est affichée.
Générer une page HTML n'est pas très consommateur en ressource et l'affichage se fait dans le navigateur donc par un autre process.
En clair, tu peux faire comme tu le fais sur ton microP : une boucle qui scanne régulièrement les E/S et génère de temps en temps une nouvelle page.
McpCan a écrit :
lun. 18 janv. 2021 22:43
Pour que l'on se comprenne, imaginons que je souhaite activer une sortie GPIO si la température du processeur (/opt/vc/bin/vcgencmd measure_temp) est supérieur à 30°C et afficher en temps réel la valeur de température sur une page web via un ordinateur sur le réseau.
Cette application exemple devrait englober toutes mes questions :)
Version crade :
tu crée une page PHP qui s'auto-rafraichie genre toute les 30 secondes et qui récupère l'info (lecture de pseudo fichier, lancement de la commande vcgencmd, voir comme par pipe ou socket), affiche le résultat et génère une action si nécessaire. Simple, mais pas très efficace et surtout ingérable si tu as plusieurs clients car il faudra que tu gères les conflits.

Version plus compliquée mais plus efficace :
tu crée une page statique+JS qui interroge par websocket un démon qui fera la récupération des données et les actions. L'avantage est que c'est le websocket qui commande le rafraichissement de la page lorsque nécessaire.

Version plus complète : MQTT.
Tu crées une page statique+JS pour récupérer les infos par MQTT (il y a des framework qui font tout le gras a ta place). C'est un dérivé des websocket mais le protocole fait que tu n'as pas a te soucier du nombre de clients.
Évidemment, c'est plus compliqué niveau archi car il faut avoir un broker MQTT sur le réseau, mais une fois que t'y a gouté, les communications point a point te sembleront tellement fade, et surtout, ca résout beaucoup de pb lorsqu'il y a plusieurs consomateurs :D
McpCan a écrit :
lun. 18 janv. 2021 22:43
Le programme qui agit sur les E/S peut il être en C sur le Raspberry ou doit il être systématiquement en python?
Non, ils sont gérés par le kernel donc ca se fait très bien en C, Lua, voir meme shell avec l'ancienne API : par exemple (https://www.iot-programmer.com/index.ph ... io?start=1)
Sysfs est dépréciés dans les kernels récents mais toujours présent : il a été remplacé par un autre truc mais je n'ai pas trouvé (pas trop chercher non plus) de docs bitables.

A+
  • BananaPI : Gentoo, disque SATA de 2 To
  • Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
  • Multimedia par DNLA
  • Et pleins d'idées ... et bien sûr, pas assez de temps.
Un descriptif de ma domotique 100% fait maison.

Répondre

Retourner vers « Des interfaces pour le Raspberry Pi »