[TUTO] Application web dynamique

Proposer ou rechercher un tutoriel concernant le Raspberry Pi

Modérateur : Francois

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

Re: [TUTO] Application web dynamique

Messagepar Bud Spencer » jeu. 13 oct. 2016 21:02

Fichiers lecon n° 4

Le fichier gauge.min.js va dans le directory '/public' ainsi que le répertoire 'fonts' (../public/fonts/) qui contient les 2 polices de caractères nécessaire à la jauge. Le fichier myweb.js va toujours a la racine du projet et le html dans 'templates'

lecon4.zip
(516.51 Kio) Téléchargé 234 fois

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

Re: [TUTO] Application web dynamique

Messagepar Bud Spencer » dim. 16 oct. 2016 13:39

Objet Json

Un truc sympa avec le javascript, c’est la facilité avec laquelle on passe et on traite les données au format Json (forcement, c’est fait pour). Depuis le début, on passait l'objet 'credit', mais rien n'empêche d'en passer plusieurs. Pour l’exemple j’ai installé un nouveau petit package qui permet de récupérer les informations des points de montages et de les retourner en Json. Ici pas de JavaScript coté client, ce n’est que du html simple et le rendering est fait entièrement coté serveur par ejs. Cela donne aussi l'exemple simple qui permet d'ajouter des routes (adresse de page) pour appeler des pages différentes

Pour installer le nouveau package (toujours depuis le répertoire racine du projet) :
npm install node-df

Dans le code serveur, ajoutez le require de node_df puis, une nouvelle route avec la fonction qui va ‘renderiser’ le template df.html en lui passant le résultat de df.
lecon5_1.png
lecon5_1.png (9.29 Kio) Vu 2129 fois


Ajoutez la page df.html et l'image pxfushia.png (lecon5.zip) dans les bon répertoires et appelez la page http://adressedupi:port/df . Voilà, vous avez maintenant un df –h graphique et accessible depuis n’importe quel navigateur sur votre réseau. Cool non ? ;)
lecon5_2.png
lecon5_2.png (79.96 Kio) Vu 2129 fois


Je ne vous mets pas le code serveur, tout ce qu'il y a à ajouter dedans se résume a la fonction écrite plus haut et n'importe quel autre serveur de leçon précédente fait l'affaire. Le fichier df.html va toujours dans templates et l'image pxfushia.png va bien sur dans les statiques (/public).
lecon5.zip
(1.16 Kio) Téléchargé 214 fois


plus d'info sur le package df-node ici -> https://www.npmjs.com/package/node-df

guillaume9344
Raspinaute
Messages : 618
Enregistré le : mar. 6 janv. 2015 20:44
Localisation : finistere

Re: [TUTO] Application web dynamique

Messagepar guillaume9344 » dim. 16 oct. 2016 19:23

Ca s'étoffe tout cà , dite donc. J 'ai pas encore eu le temps de tout expérimenter , mais je lis chaque épisode avec intérets. Et il prévus un fichier complé à la fin , comme un cours ou un gros tuto?
@+
rpi b+ ,osmc, motioneyes
rpi 2 raspbian , server minecraft 24h/24 , utilisation gpio
orange pi pc debian ,utilisation gpio, motion cam

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

Re: [TUTO] Application web dynamique

Messagepar Bud Spencer » lun. 17 oct. 2016 20:31

guillaume9344 a écrit :Ca s'étoffe tout cà , dite donc. J 'ai pas encore eu le temps de tout expérimenter , mais je lis chaque épisode avec intérets. Et il prévus un fichier complé à la fin , comme un cours ou un gros tuto?
@+

Pour l’instant, je fais surtout des tout petits exemples très ciblés et concrets pour ne pas embrouiller les débutants avec des codes trop long et incompréhensible. J’ai toujours été convaincu que de petits exemples simples que l’on peut essayer et triturer sont 100 fois plus formateurs que du code trop long rendu illisible par la surcharge de commentaires souvent nuisibles. Pour l’instant je me suis contenté de ‘scriptounets à usage unique’ mais il arrivera un moment où je ferais sans doute la démo d’une vraie application multifonctionnelle qui regroupera entre autre tous les points vus jusque-là. Il me reste à trouver l’idée de cette application mais j’y réfléchi . D'ailleurs si il y à des idées d'applis qui pourrait être représentative, je suis a votre écoute. Ca pourrait servir de fil rouge pour la suite de ce tuto.


Oooopssss :
Dans la leçon n° 5 je voulais surtout montrer la notion de données structurées JSon mais les choses sont tellement simple et rapide à faire que j’ai un peu mangé la démo en oubliant la partie majeur ou je voulais en venir. Pour réparer cet oubli, voilà ce que je vous propose :
Ajouter donc la fonction suivante dans le code de votre serveur (si vous avez déjà declaré df, pas la peine de remettre la ligne var df = require...) :
lecon5_3.png
lecon5_3.png (8.61 Kio) Vu 2100 fois

Puis utiliser votre navigateur pour appeler la nouvelle route http://adressedupi:port/df_json .

Vous allez recevoir en retour une chaine de caractères qui contient un tableau des données de df au format JSon.
Même si il n’en a pas toutes les fonctionnalités, vous venez de créer la fonction GET d’un Web Services de type REST (*) JSon en seulement 3 lignes de codes. Non seulement le serveur peut ‘renderiser’ des pages web et dialoguer en temps réel avec elles, mais il sait aussi fournir, avec une très grandes facilité, des données dans un format standard à n’importe quel client développé avec n’importe quel langage. Un Web Services peut fournir des données, mais aussi servir d’interface (au sens liaison) pour en modifier, en ajouter ou en supprimer mais … step by step, nous parlerons ça plus tard ;)

(*)Representational State Transfer : https://fr.wikipedia.org/wiki/Service_web

guillaume9344
Raspinaute
Messages : 618
Enregistré le : mar. 6 janv. 2015 20:44
Localisation : finistere

Re: [TUTO] Application web dynamique

Messagepar guillaume9344 » lun. 17 oct. 2016 21:27

Tout a fais d accord pour les scriptounets, a vrais dire je pensai plus a une compile de tous les postes, pour une lecture plus facile.
et encore bravo pour le travail.
rpi b+ ,osmc, motioneyes
rpi 2 raspbian , server minecraft 24h/24 , utilisation gpio
orange pi pc debian ,utilisation gpio, motion cam

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

Re: [TUTO] Application web dynamique

Messagepar Bud Spencer » mer. 26 oct. 2016 21:40

Continuons (hé non, je ne vous ai pas oublié ;) … )

Pour cette nouvelle leçon, je vous ai fait un petit exemple qui utilise les GPIOs . Il existe une multitude de pack nodejs plus ou moins fonctionnels pour ça et après en avoir testé plusieurs pour vous, j’en ai sélectionné un qui semble pas mal, vu qu’il utilise la fameuse lib winring-pi. Personnellement, je ne l’utilise pas puisque j’ai développé depuis longtemps mon propre wrapper qui interface integralement la lib bcm2835 et que je publierais peut être le jour ou la flemme me lâchera et que je trouverais le temps d’écrire une notice.

J’aurais pu me contenter d’un simple blinck led, mais je voulais traiter les sorties, mais aussi les entrés. J’ai donc créé des couples. Chaque couple de périphérique utilise une sortie et une entré pour la piloter. L’idée c’est de dire que quand on appuis sur un bouton on inverse l’état de sa sortie respective (jour/nuit okaiiiii ? ) mais que cette action puisse se faire soit depuis le bouton ‘hardware’ ou depuis un bouton ‘software’ avec exactement le même effet et que quel que soit la méthode, l’interface graphique et le composant ‘physique’ soit mis à jour en temps réel.

Comme vous avez forcement tout compris des leçons précédentes, je me suis permis d’en inclure 2 dans celle-ci. En plus de traiter des GPIO, j’ai inclus un exemple de lecture de fichier json pour la configuration. On peut donc, à souhait, ajouter ou supprimer des ‘périphériques’ sans avoir à modifier les codes sources qui eux sont totalement dynamique aussi bien coté client que serveur.

Pour le rendering et les échanges temps réel entre les clients et le serveur, rien de nouveau et tout est déjà démontré dans les leçons précédentes.

Pour utiliser cet exemple, il faut ajouter un nouveau package pour les GPIO avec la commande (toujours depuis le dir racine du projet...) :
$ npm install wiring-pi

Ensuite copiez les fichiers fournis dans le zip aux bons endroits dans votre arborescence projet
(le fichier .js et le .json a la racine du projet, le html dans templates et les .png dans public)

Pour l’exemple, on est à bord d’un avion (ok, un tout petit avion alors :mrgreen: …) et on peut contrôler les 2 moteurs et l’éclairage de la cabine. Si vous avez peur de voler avec ça, éditez le fichier de config (config.json que vous avez bien sur mis dans le répertoire racine du projet) et adaptez le pour en faire un aspirateur. Pour la partie hardware, pas besoin d'avoir un Airbus A320, une simple led (avec résistance) sur les sorties et un bouton (avec capa d’anti rebond) sur les entrés suffit pour tester (schéma sur demande, mais bon …)

Pour lancer le serveur, vous devez utiliser une commande sudo (GPIO oblige) : sudo node monweb.js
Vous pouvez maintenant piloter vos leds avec chaque bouton respectif ou depuis un navigateur. Dans tous les cas, tous les navigateurs connectés ainsi que les leds physiques sont misent à jour en temps réel et quand un nouveau client se connecte, il est automatiquement à jour dès sont arrivé.
lecon6_1.png
lecon6_1.png (63.37 Kio) Vu 2065 fois


Vous voulez ajouter l’éclairage des toilettes ? Pas de problème. Ajouter l’objet suivant dans le tableau de config.
lecon6_3.png
lecon6_3.png (12.17 Kio) Vu 2065 fois


Redémarrez votre serveur et actualisez vos clients et voila. C'est désormais vous qui commandez la lumière des 'chiottes' :mrgreen: :lol:
lecon6_2.png
lecon6_2.png (66.52 Kio) Vu 2065 fois


Exceptionnellement, j’ai mis un peu de commentaire dans le code. Vous noterez qu’il ni a pas de routine de pooling pour lire l’état des boutons. J’ai utilisé la fonction wiringPiISR qui permet de s’abonner à des interruptions sur les entrés. J’ai aussi mis une route ‘/perif’ qui permet de récupérer la config et l’état actuel des perifs dans une structure json et une instruction qui permet d’avoir le monitoring des changements dans la console du serveur. Le code reste malgré tout très explicite aussi bien pour le serveur que pour la page html et une simple lecture de ceux ci vous permettra de comprendre le fonctionnement.

Vous trouverez des infos sur le package node wiring-pi à l’adresse : https://github.com/eugeneware/wiring-pi
Une petite combine quand vous avez de gros fichiers Json et que vous avez la flemme de chercher les erreurs. Vous pouvez les passer par cette moulinette pour voir si ils sont cohérants : http://jsonlint.com/#

Il ne me reste qu’à vous souhaiter ‘bon vol’ ;)
Modifié en dernier par Bud Spencer le dim. 6 nov. 2016 10:05, modifié 2 fois.

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

Re: [TUTO] Application web dynamique

Messagepar Bud Spencer » mer. 26 oct. 2016 21:49

Fichiers Lecon n° 6

UPDATE 27/05/2017

A plusieurs reprises, des testeurs ont eu des petits soucis de linkage avec cette lecon et socket.io (lire suite du tuto). Pour résoudre ce problème, je met donc à jour ce fichier de leçon 6 auquel j'ai ajouté un fichier de package (info sur npm init en page 4 du tuto). Pour installer cette leçon, il vous suffit donc de copier le contenu du zip dans un répertoire vide qui sera la racine de votre projet, puis de vous placer dans ce répertoire et juste taper la comme 'npm install'. Cela aura pour effet de créer le sous répertoire 'node_modules' localement et cela installera automatiquement tous les packages nécessaires (le pi doit etre connecté au net évidement).

Avant cela, je ne saurais vous recommander de mettre à jour nodejs et npm (voir à la page 6 du tuto)

lecon6.zip
(29.72 Kio) Téléchargé 273 fois
Modifié en dernier par Bud Spencer le sam. 27 mai 2017 08:44, modifié 2 fois.

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

Re: [TUTO] Application web dynamique

Messagepar Bud Spencer » sam. 29 oct. 2016 16:06

Conclusion

Dès la première leçon, j’avais notifié que NodeJS n’était pas un serveur web. Nous avons néanmoins pu constater jusque-là qu’il savait parfaitement remplir ce rôle. Bien sur tout n'a pas été traité ici et pour cause. NodeJs c'est plus de 60000 package npm public et rien ne vous empêche de faire les vôtres. Base de données, io de toutes sortes, tout protocole réseaux et j'en passe, tout est possible.

Si on prend 99% des cas de programmation qui suscitent de la réflexion sur les forums PI, on peut vite en déduire ceci :
Langage de programmation = python et GUI = TK.

Forcément, si devoir se coltiner 100 lignes de code pour dessiner une pauvre fenêtre et interfacer les évents d’un bouton avec une fonction cela peut faire rigoler un développeur expérimenté, on se rend vite compte que ça ne fait pas marrer le débutant. Résultat, l’équation change et devient :
Langage de programmation = python et GUI = HTML

Et si on décompose l’équation, en général on a : python + Apache + PHP + Javascript
Cette solution est très bien ‘vendue’. Faite l’essai de rechercher les mots suivant sur ce site :

Apache : 196 résultats, Nginx : 53, Lighttpd 52
NodeJs : 10 résultats et si on enlève ceux que j’ai écrit, on passe à seulement 4

On pourrait donc penser qu’un serveur php/cgi qui exécute des scripts python est la bonne solution alors qu’en fait, c’est juste la pire qui n’a même pas le mérite d’être simple à implémenter. Juste pour vous en convaincre, essayez de faire la même chose que ce que font les ridicules exemples de ce tuto avec une solution pareille (bonne chance ...). La simple équation ‘NodeJS + JavaScript’ peut à elle seule balayer tout ça d’un revers de main et en faire beaucoup plus avec une simplicité déconcertante. Faut-il encore le savoir.

Sans plus parler de web, restons dans la simple hypothèse d’un petit script console pour comparer cette fois ci python et JavaScript. Pas d’invention, je vais prendre un exemple simple auquel j’ai répondu cette semaine. 2RJ voulait juste un exemple python et comme ça commençait à partir dans tous les sens avec des questions de batch et de sysfs, je lui ai écrit les 3 lignes de code qu’il voulait et basta. Ce qui m’a interpellé, c’est que 2RJ qui ni connaissait rien en programmation (suffit de voir comment une simple faute de frappe dans mon code l’a bloqué) savait quand même une chose : Il voulait faire en python. On lui a dit que c’était le langage le plus simple et le plus adapté au PI, donc forcément il fonce tout droit dedans. Voilà donc le code python que je lui ai donné et en dessous, pour l'exemple équivalent en que j'aurais écrit pour NodeJS :
cncl1.png
cncl1.png (28.81 Kio) Vu 2028 fois


Finalement, a bien y regarder l’un n’est pas plus compliqué que l’autre et que l’on lance l’un ou l’autre, le résultat sera le même. Et pourtant ces 2 exemples sont fondamentalement différents. L’idée était juste d’afficher l’état de la sonde dans la console toute les 10 minutes, ok, ça c’est fait. Mais 2RJ il va revenir. Supposons que sa prochaine étape soit d’avoir une alarme genre lampe qui clignote depuis une sortie pour l’avertir quand il ni a plus d’eau. Puis pour dire que l’on va encore plus loin, il veut pouvoir depuis sa console ouvrir et fermer une électrovanne pour remplir. C'est pas le projet du siècle et avec NodeJS, ça pourrait se résumer à ce simple code :
cncl2.png
cncl2.png (48.54 Kio) Vu 1999 fois


Si vous en êtes capable, essayez maintenant de faire la même chose en python et regardez ou ça vous mène. Quand vous en serez là, on pourrait imaginer d'autres options, comme par exemple contrôler automatiquement l’électrovanne pour le remplissage et pourquoi pas ajouter l’écriture d’un fichier qui loguerais la quantité d’eau ajouté par jour, et de façon complètement indépendante gérer de la même façon une autre cuve, mais d’ici la …

On met ici le doigt sur la plus singulière particularité de NodeJS. Il est asynchrone et mono-thread. Il ne sait faire qu’une seule chose à la fois, mais il le fait très vite et tout son fonctionnements repose sur des évènements (callback). Il lance des fonctions puis passe faire autre chose pendant qu’elles laisses du temps de libre. Quand une fonction à terminée son job, il traite au besoin le résultat.

Quel que soit le langage utilisé il y a toujours moyens de créer des threads asynchrones qui vont générer des évènements mais cela devient très vite très complexe et c’est même souvent hors de portée pour la plupart des débutants ou développeurs ‘hobbyistes’. Hormis la simplicité offerte pour créer des applications web avec le même langage coté client et serveur, NodeJs permet de réaliser très simplement tout un tas des choses qu’il serait extrêmement compliqué à faire avec d’autres langage. En fait, on ne peut même pas dire que JavaScript est mieux ou moins bien que d’autres solutions comme python, c, c++, java ect … Il est simplement fondamentalement différent.

Comme je l’ai écrit au départ, il ne s’agissait pas ici pas de faire un cours de programmation ni d’expliquer le fonctionnement si particulier NodeJS. Il existe pour ça des milliers de sites traitants du langage javascript et de NodeJS. Le but c’était juste de présenter la solution pour la faire un peu plus connaître et croyez-moi, ça en vaut vraiment la peine. Si vous prenez le temps de vous y intéresser, vous verrez que vous pouvez aussi facilement créer de vraie application desktop multi-plateforme distribuable avec des outils comme Node-WebKit ou des applications mobiles tout aussi portable avec entre autre Apache-Cordova. On parle même dans les ‘milieux autorisés’ d’une interface graphique multi-os …

Pour finir, n'allez pas croire que je suis un fan de NodeJS qui pense que c’est mieux ou moins bien qu'autre chose. A vrai dire je n’utilise que rarement cette solution. Mon job me porte plus sur des développements de grosses solutions pro. dans d’autres langages. Comme beaucoup de développeurs pro, j’ai longtemps regardé le javascript comme un langage minable tout juste bon faire clignoter des images dans des pages web. Pendant ce temps JavaScript a continué son petit bonhomme de chemin et a grandi et il faut bien admettre désormais qu’il est devenu une véritable alternative que l’on ne peut plus ignorer.

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

Re: [TUTO] Application web dynamique

Messagepar Bud Spencer » dim. 13 nov. 2016 12:31

J’avais décidé d’arrêter ce tuto ici. Le but principal était de présenter une technique et je pense que les quelques leçons précédentes étaient suffisamment explicites. Ceci dit rien n’empêche de faire vivre ce post avec de nouveaux exemples ou d’avoir des retours sur différents packages npm, sur des astuces de programmation ou d’autres voies permettant d’interagir entre un programme et une GHI html. Pour fêter les 1500 vues du Tuto, voila donc une nouvelle petite leçon :)

Dans la panoplie des outils qui permettent de faire de l’interaction entre une page html cliente qui sert de GUI et un serveur qui a le rôle 'back office métier', NodeJS et SocketIO sont très efficace, mais ce n’est pas la seule solution.
Si par exemple vous avez passé beaucoup de temps à faire un programme python ou bash ou je ne sais quoi d’autre avec sortie console, vous pouvez tout à fait interagir avec depuis une page html sans avoir a le recoder complet en JavaScript pour NodeJS. Pour ca, on peut par exemple utiliser un websocket pour rediriger les entrées/sorties de la console depuis/vers une page HTML. Cela peut permettre d’utiliser toute la facilité de l’HTML et de JavaScript pour dessiner une belle interface graphique pour votre programme existant et même y avoir accès sans serveur web.

Pour l’exemple, je vais reprendre le petit code 2RJ du post précèdent qui au départ, n’était pas destiné à une page web. J’ai juste ajouté le flush() de la sortie et modifié le timing pour lire l’état de la gpio toute les secondes.
lecon7_1.png
lecon7_1.png (20.1 Kio) Vu 1813 fois

Lançons le script :

Code : Tout sélectionner

$ python 2rj.py


On peut modifier l’état de la GPIO 18 avec un simple bout de fil entre celle-ci et une broche GND et voir son état (0 ou 1) dans la console. (CTRL+C pour arrêter le programme).

Installons maintenant un websocket.


J’ai choisi Websocketd qui est un websocket très simple d’utilisation et qui va faire office de proxy entre les stdin/stdout de votre application et la page web. Il suffit juste de le mettre dans le même répertoire que l'application et de le lancer en passant le script en paramètre. Donc depuis le même répertoire que le script utilisez la commande suivante (votre Pi doit évidemment être connecté au net, sinon il faudra récupérer websocketd depuis une autre machine et le copier manuellement) :

Téléchargement de websocketd

Code : Tout sélectionner

$ wget http://github.com/joewalnes/websocketd/releases/download/v0.2.11/websocketd-0.2.11-linux_arm.zip

Dézippage (si vous n’avez pas unzip sur votre systeme -> sudo apt-get install unzip )

Code : Tout sélectionner

$ unzip websocketd-0.2.11-linux_arm.zip

Demarrage :

Code : Tout sélectionner

$ ./websocketd --port=8080 python 2rj.py


Créons maintenant une petite page html qui va nous servir de GUI :
lecon7_2.png
lecon7_2.png (45.05 Kio) Vu 1813 fois


Et chargeons la dans le navigateur:
lecon7_3.png
lecon7_3.png (13.08 Kio) Vu 1813 fois


On peut maintenant suivre l'état de la GPIO en temps réel dans une magnifique page web :)

Ici j'ai chargé la page directement sans utiliser de serveur web, mais la page pourrait être distribuée par n'importe quel webserver (Apache, Nginx, NodeJS ou même directement depuis votre application python ...).

WebSocketd existe aussi bien pour linux, windows, osx ect .... et peut supporter pratiquement n'importe quel application console (python, java, c#, php, c ...) et vous trouverez toutes les infos dessus ici -> http://websocketd.com

pajRLE
Messages : 9
Enregistré le : mar. 29 nov. 2016 14:01

Re: [TUTO] Application web dynamique

Messagepar pajRLE » mar. 29 nov. 2016 14:11

Bonjour
Excellent tuto.
Je suis débutant et j'essaye de comprendre les différentes leçons.
Celle qui m'interesse le plus est la leçon 6 qui introduit les GPIOs.
J'ai un petit problème car je pense à une erreur dans le fichier myweb.js
Il semble qu'il manque une partie de code au niveau de l'initialisation des périphériques, j'ai ceci:

//initialisation des périphériques
for (var i = 0;i < config.perif.length;i++)
{
wpi.pinMode(config.perif[i].out,wpi.OUTPUT);
wpi.pinMode(config.perif[i].inp,wpi.INPUT);
wpi.pullUpDnControl(config.perif[i].inp,wpi.PUD_UP);

//positionement de la property etat du perif
config.perif[i].etat= wpi.digitalRead(config.perif[i].out);

//abonnement aux interupt. front descendant sur les inputs
wpi.wiringPiISR(config.perif[i].inp,wpi.INT_EDGE_FALLING,function()
{
for (var i = 0;i < config.perif.length;i++)
{//recherche le l'input à low
if (wpi.digitalRead(config.perif[i].inp) == 0)
{
//appel de changement d'etat de l'output
changeGPIO(config.perif[i].iden);
}
}
}); l'afficga
}

Je pense qu'il manque quelque chose au niveau de la ligne "l'afficga".
Par avance merci
Cordialement
Patrice


Retourner vers « Tutoriels »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité