[{"content":"Lien GitLab TTGO Lien GitLab Flutter\nDescription Ce projet est une application Flutter qui permet de contrôler un microcontrôleur.\nIntroduction Ce projet a pour but d\u0026rsquo;utiliser une application Flutter pour lire des données comme des températures, des niveaux de lumières, d\u0026rsquo;en retirer des statistiques, et de contrôler des LED. Le projet peut être interprété comme le contrôle d\u0026rsquo;une maison connectée. Il est possible de définir un comportement automatique pour que les LED s\u0026rsquo;allument en fonction de seuil de température ou lumière.\nDémo Your browser doesn't support HTML5 video. Here is a link to the video instead. Fonctionnalités L\u0026rsquo;application flutter est disponible pour les systèmes Android. L\u0026rsquo;application est divisé en plusieurs pages principales :\nAccueil Profile voir les informations personnels modifier ses informations Température voir les statistiques des températures voir la température actuelle Luminosité voir le niveau de luminosité et son ambiance (Lumineux, sombre, etc) voir les statistiques sur les niveaux de luminosité Contrôle LED éteindre toutes les LED accéder au mode automatique et ses réglages activé le mode auto régler la vitesse, le statut des LED (Dé)connexion connexion Bluetooth du WiFi Les modifications des données sont transmises au service concerné. Si l\u0026rsquo;on fait une modification sur les informations personnelles, la base de données que j\u0026rsquo;héberge sur mon raspberry pi sera notifié. Si les modifications concernent le comportement des LED, le microcontrôleur fera les modifications nécessaires. Des graphiques sont fait à partir des données contenues dans la base de données. Pour accéder à la base de données, il faut avoir un accès internet.\nUtilisation du projet Application Flutter Le code source est disponible sur GitLab (Lien GitLab Flutter), il faut importer le projet sur Android Studio et soit utilisé une simulation d\u0026rsquo;Android ou d\u0026rsquo;utiliser tout simplement son téléphone Android. L\u0026rsquo;application utilise les dépendances suivantes :\nhttp : pour faire les requêtes à l’ESP mysql client : pour communiquer avec la base de données MySQL déployée avec Docker sur un RaspBerry Pi fl chart : pour tracer les différents graphes permission handler : pour les permissions avec le bluetooth shared preferences : pour ajouter des données persistantes dans les préférences flutter blue : pour utiliser le bluetooth TTGO Pour l\u0026rsquo;ESP32 TTGO T-Display, il faut refaire le montage selon le schéma que j\u0026rsquo;ai fourni.\nIl est nécessaire de télécharger plusieurs bibliothèques :\nTFT_eSPI : permet d\u0026rsquo;utiliser l\u0026rsquo;affichage de l\u0026rsquo;ESP WiFi : pour utiliser le WiFi WebServer : pour faire des requêtes HTTP ArduinoJson : pour passer des objets Json par l\u0026rsquo;API REST Preferences : pour conserver des données Arduino ESP32 OTA : permet de faire des mises à jour \u0026ldquo;Over The Air\u0026rdquo; sans avoir besoin de connecter l\u0026rsquo;ESP32 à un ordinateur Il ne reste plus qu\u0026rsquo;à téléverser le code source disponible (Lien GitLab TTGO) avec Arduino IDE avec les paramètres suivants :\nLancement Il faut juste brancher notre microntrôleur à une source d\u0026rsquo;alimentation avec une connection internet disponible, pareil pour notre appareil Android.\nImplémentation Cahier des charges L\u0026rsquo;objectif du projet est d\u0026rsquo;implémenter une API RESTful sur un capteur TTGO T-Display. L\u0026rsquo;API doit permettre de :\nlister les capteurs (température/lumière) connectés à l\u0026rsquo;ESP32 de récupérer les informations associées à ce ou ces capteurs de contrôler l\u0026rsquo;allumage, l\u0026rsquo;extinction, le changement d\u0026rsquo;état d\u0026rsquo;une LED connectée à l\u0026rsquo;ESP32 de définir un seuil permettant d\u0026rsquo;allumer/éteindre la LED en fonction de la valeur captée par un des capteurs connecté à l\u0026rsquo;ESP32 L\u0026rsquo;utilisation de l\u0026rsquo;écran intégré ainsi que des boutons pré-configurés sera un plus très apprécié dans l\u0026rsquo;évaluation de votre montage.\nPour l\u0026rsquo;application Flutter, l\u0026rsquo;objectif est de développer une interface utilisateur pour intreragir sur l\u0026rsquo;API RESTful pour le projet du capteur TTGO T-Display. Cette interface sert de pont entre l\u0026rsquo;utilisateur et le capteur permettant une interraction visuelle et intuitive avec les données et commandes du capteur.\nLes fonctionnalités requises sont les suivantes :\nAffichage de données des capteurs : l\u0026rsquo;application doit pouvoir lister et afficher les données des capteurs récupérées via l\u0026rsquo;API RESTful, en différents formats (textuel, graphes, etc) Contrôle de la LED : intégrer des commandes dans l\u0026rsquo;application pour contrôler l\u0026rsquo;allumage, l\u0026rsquo;extinction et le changement de la LED sur l\u0026rsquo;ESP32 Interface de réglage de seuil : créer une interface permettant à l\u0026rsquo;utilisateur de définir un seuil pour la (dés)activation de la LED basé sur les données des capteurs Interface de statistiques : créer une interface permettant à l\u0026rsquo;utilisateur de visualiser l\u0026rsquo;usage et la localisation Stockage des données : veillez à ce que les données soit persistées dans le backend au delà de leur streaming en temps réel Arduino TTGO T-Display Le but d\u0026rsquo;une API Rest est de faire des requête HTTP, Il faut que notre ESP32 soit capable de gérer les connexions et les requêtes qu’on va lui envoyer. On doit ajouter la bibliothèque WebServer et de prendre le port 80 (le port HTTP). Maintenant, il faut que les requêtes soient traitées : commencons par GET. Notre projet doit envoyé les données de température, de lumière, les informations sur les LED et les param`etres du mode automatique. Cette requête suivra cette forme : ”http://adresse/NOM DONNEE”. Dans la fonction server road(), on listera les chemins utilisés et les fonctions rattachés.\nChaque chemin aura une fonction de rattachée : • /temperature : récupère la température avec la fonction get temperature() • /light : r´ecupère la valeur de lumière avec la fonction get light() • /ledA, /ledB, /led : récupèrent les valeurs sur les LED avec les fonctions get ledA(), get ledB() et get led() • /ledAutoParams : récupère les données du mode automatique avec la fonction get auto()\nLes fonctions de récupération de données (GET) vont prendre la valeur du capteur ou de la led et les formater en JSON avec la bibliothèque ArduinoJson. Pour être sûr que l’objet JSON est bien vide avant d’écrire, on retire tout ce qu’il y a dedans avec la fonction clear(). Maintenant, on peut écrire ce qu’on veut envoyer comme donnée. Nous avons choisi d’envoyer le type (lumière, température, led, \u0026hellip;) et sa valeur. La température a déjà été converti en degrés Celsius. Il ne reste plus qu’à envoyer avec la fonction send() en spécifiant 200 (code du succès de l’envoi).\nLa récupération de la température est un peu particulière car il faut appliquer une formule. Celle que j\u0026rsquo;ai utilisé est celle de Steinhart-Hart qui consiste à prendre la valeur de résistance d\u0026rsquo;appliquer la formule suivante : T = A + B ∗ log(resistance) + C ∗ pow(log(resistance), 3) avec A,B,C des coefficients le résultat sera en Kelvin, il ne restera plus qu\u0026rsquo;à convertir en degrés Celsius. Pour obtenir les coefficients, vu que je n\u0026rsquo;avais pas le manuel utilisateur du capteur, j\u0026rsquo;ai dû les calculer. J\u0026rsquo;ai récupérer 3 valeurs de résistances en changeant la température : j\u0026rsquo;ai utilisé un verre remplie d\u0026rsquo;eau chaude, froide et j\u0026rsquo;ai le capteur en contact avec le verre en ayant au préalable mesuré sa température.\nL’utilisateur peut modifier l’état de la LED, les valeurs de seuil ou encore passer en mode automatique ou manuel, il faut que le serveur soit capable de gérer les requêtes POST. Il y a une différence de traitements entre les paramètres et le seuil pour le mode auto. Les paramètres sont les comportements des led : la vitesse de clignotement, allumé/éteint, etc. Le seuil sera la valeur de température ou la valeur de lumière que l’utilisateur aura décidé.\nL’ESP a un écran TFT, donc nous avons eu l’idée de faire un affichage des relevés des capteurs mais aussi des connexions. La première étape au démarrage du TTGO est la connexion Wifi ou la connexion bluetooth : un affichage dira qu’il attend une connexion. Avoir le mot de passe et le ssid d’un réseau wifi écrit en brut n’est vraiment pas sécurisé ni modulable : nous avons donc mis en place une configuration avec le BLE (Bluetooth Low Energy).\nAvoir le mot de passe et le ssid d’un réseau wifi écrit en brut n’est vraiment pas sécurisé ni modulable : nous avons donc mis en place une configuration avec le BLE (Bluetooth Low Energy). Le BLE est composé de services et de caractéristiques en interne. Il faut donc commencer par les définir avec des identifiants uniques (SERVICE UUID et CHARACTERISTIC UUID). Maintenant, il faut que l’ESP lance l’écoute et l’attente d’évènements : notre fonction connection bluetooth() permet cette configuration. Le nom de l\u0026rsquo;appareil est défini à ESP32 pour facilier la connexion. Il ne reste plus qu’à lancer le serveur BLE (la fonction start()) et de le mettre en écoute (fonction getAdvertising()).\nIl faut maintenant que le caractéristique est une fonction particulière à exécuter. Nous avons mis comme propriété sur le caractéristique l’écriture donc nous devons définir son comportement.\nLa première chose à faire est de récupérer la valeur que l’utilisateur aura envoyé donc le ssid et le mot de passe du wifi. Nous récupérons avec la fonction getValue() sur l’instance du caractéristique puis nous la convertissons en chaîıne de caractères. Nous savons que la valeur d’envoie sera séparée par une virgule donc nous faisons indexOf(’,’) pour séparer les deux mots. Il ne reste plus qu’à donner ces valeurs à la fonction connection wifi() et de vérifier si on peut se connecter ou non, la réponse sera un booléen. Si la connexion est bonne, on aura true sinon false. Le serveur sera toujours en attente de modification donc si l’utilisateur change de réseau, il pourra le changer.\nPour pouvoir faire les mises à jour Over The Air, il faut d’abord installer la bibliothèque Arduino ESP32 OTA, cette bibliothèque est en beta. On doit définir les différentes étapes. D’abord, il faut définir le comportement en fonction de l’état : onStart(), onEnd, onProgress() et onError() :\nonStart(), on regarde qu’est-ce qui est concerné par la mise à jour les fichiers (U SPIFFS) ou le programme lui-même (U FLASH). onEnd(), On fait juste une impression sur le monitor onProgress(), on fait un affichage pour connaître le pourcentage de progression de l’envoi onError(), renvoie les erreurs pendant la mise à jour Lorsque le TTGO redémarre, éteint ou est mis à jour le programme, toutes les données sont perdues. Ceci n’est pas préférable. Nous avons ainsi mis en place les préférences (qui est le remplacement de EEPROM). Nous avons opté pour cette solution car ce sont des petites données qui sont stockées mais l’utilisation de LitteFS aurait pu être possible. Ces données seront stockées dans une partie de sa mémoire non volatile interne (NVS). Nous avons besoin d’ajouter la bibliothèque Preferences.\nBase de données MySQL - Docker L’espace de données sur le TTGO est très restreint donc pour conserver les données, il faut trouver une alternative. La meilleure solution que nous avons trouvé est de déployer une base de données MySQL dans un conteneur Docker hébergé sur un Raspberry pi 4. Un script fait des requêtes régulière pour récupérer les données du capteur pour les mettre dans la base de données. Nous n’avons pas mis un accès directement à la base de données pour des questions de sécurités.\nLa base de données est composée de 3 tables :\nUser : qui regroupe toutes les informations sur un utilisateur lors de la création d’un compte Temperature : contient les données récupérées du thermistor à intervalle régulier Light : contient les données récupérées du photoresistor à intervalle régulier Pour pouvoir y accéder depuis l’extérieur et pas en local, nous avons configuré un ddns pour avoir un nom de domaine. De plus, il est préférable d’avoir un nom de domaine plutôt qu’une IP pour des raisons de sécurités et aussi parce que les IP des box changent et ainsi causer des problèmes de connexion à cette base de données si l’IP n’est plus la bonne. Il ne faut pas uniquement un DNS mais un DDNS qui est l’abréviation de Dynamic Domain Name System ce qui implique que l’IP peut changer régulièrement mais que le nom de domaine sera toujours valide. Pour faire ceci, nous avons utilisé No-Ip.\nApplication Flutter Nous avons créé tous les chemins possibles pour faciliter la navigation en les déclarant dans le main de l’application. De plus, en fonction de si l’utilisateur est connecté ou non, la page de début sera l’accueil ou la page de création de compte. Nous avons décidé de faire une application dans le style Lofi donc nous avons adapté le fond d’écran, les icônes et les couleurs de l’application. Tous vient des sites Freepik ou encore Flaticon.\nCréation de compte Avant tout, il faut que l’utilisateur se crée un compte. Tous les champs doivent être remplis sinon l’utilisateur ne pourra pas créer de compte.Si l’utilisateur a déjà un compte, il pourra toujours se connecter. L’utilisateur devra obligatoirement, lors de la création, remplir tous les champs et le même mot de passe pour passer la vérification. Lorsque tous les champs sont remplis par l’utilisateur, il ne reste plus qu’à rentrer les données dans la base de données. Si l’utilisateur existe, un message s’affiche pour le signaler à l’utilisateur sinon le compte sera créé avec succès. Un contrôleur sur chaque champ a été mis en place pour pouvoir récupérer les différentes données ainsi qu’une clef pour le formulaire. ’utilisateur sera ensuite redirigé vers la configuration de l’ESP avec le bluetooth.\nConnexion Si l’utilisateur a déjà un compte, il peut se connecter et avoir le choix de faire la configuration en laissant le bouton sur ”Faire la première connexion” qui le redirigera vers la connexion bluetooth sinon il ira sur l’écran d’accueil. Pour la connexion, l’utilisateur doit donner un email et son mot de passe qui seront vérifiés. Si l’utilisateur se trompe ou que son compte n’existe pas, il y aura alors un message d’informations.\nBluetooth Si l’utilisateur a fait une inscription ou se connecter pour reconfigurer les paramètres WiFi alors il arrivera sur cette page. Si l’utilisateur n’a pas le bluetooth d’activer sur son appareil, il aura cette page. Une fois que le Bluetooth est actif ainsi que la localisation (ce qui est n´ecessaire pour pouvoir faire les connexions BLE (Bluetooth Low Energy)) lorsqu’on appuie sur le bouton de recherche : on demande à l’utilisateur si l’application peut utiliser la localisation.\nSi l’appareil est détectable alors lors de la recherche il apparaîtra. Dans notre projet, sur l’ESP32, nous avons donné le nom de l’appareil ”Esp32”. Lorsqu’on appuie sur le bouton de recherche situé en bas à droite de l’écran quand il effectue une recherche qui dure quelques secondes son icône change d’une loupe à un carré.\nQuand l’application a pu faire la connexion à l’appareil alors on peut lister les services nécessaires. Le seul service d’actif sur l’ESP32 est celui de la connexion au WiFi. La liste des services ne s’affiche uniquement si on appuie sur le bouton Services. Si l’utilisateur ne veut pas se connecter à ce dernier alors il peut toujours se déconnecter en appuyant sur le bouton en haut à droite de la page.\nMaintenant que l’utilisateur est connecté, il peut accéder aux services et aux caractéristiques. Dans notre projet, nous avons mis en place une seul service et caractéristique, pour l’utiliser, il faut appuyer sur le bouton ”Connexion au WiFi” qui affichera une boîte de dialogue AlertDialog demandant le nom et le mot de passe. Si l’utilisateur se trompe sur le mot de passe ou le nom, le capteur enverra un échec de connexion et on pourra recommencer à donner les bonnes informations. Si la connexion au WiFi réussi alors l’utilisateur sera redirigé vers l’accueil.\nNous avons eu besoin d’utiliser la bibliothèque flutter blue. La première chose à faire pour faire des connexions à des appareils est de lister ceux qui sont disponibles. Si les appareils n’ont pas de nom on les listera avec le nom No Names sinon on affichera leur nom comme pour notre Esp32.\nPour chaque appareil, si on a réussi à se connecter, on doit lister ses services ainsi que les caractéristiques. Chaque service contient des caractéristiques. Ainsi dès que l’utilisateur appuie sur Services, on va récupérer les services de l’appareil qui seront donner à buildServiceTiles qui pour chaque service va lister ses caractéristiques. Dans notre cas, nous avons uniquement 1 seul service et le caractéristique qui permet de faire la connexion WiFi est le dernier ainsi nous affichons que le dernier.\nQuand l’utilisateur donne ses informations pour la connexion au WiFi une boîte de dialogue s’affiche. Nous avons mis des Controller pour récupérer les informations entrées. Une fois que les données sont récupérées, elles sont envoyées au microcontrolleur et l’application attendra une réponse d’échec ou de réussite de connexion. En fonction de la réponse, l’utilisateur devra soit entrer à nouveau les informations du WiFi sinon il sera redirigé vers l’accueil.\nAccueil Une fois que l’utilisateur s’est inscrit ou connecté, il sera sur la page d’accueil qui permet de naviguer vers les différentes fonctionnalités de l’application. Un tiroir permet d’accéder à toutes les pages disponibles. Pour que le menu soit cohérent, il a fallu adapter son apparence en modifiant la couleur par du deeporance[100] et des icônes personnalisés pris de la plateforme Flaticon.\nLe menu est divisé en 3 parties : une partie informations personnelles, une partie microcontrôleur et la dernière partie pour la déconnexion. Le menu est une liste de ListTile contenant l’icône, le texte et son comportement (la navigation qui utilisera le nom vu que nous les avons déclaré dans le main. Pour la d´econnexion, il s’agit d’effacer le jeton et l’email de l’utilisateur qui sont garder dans les préférences et de rediriger vers la page de connexion.\nProfile L’utilisateur peut consulter ses informations personnelles ou les modifier. Pour les modifier, il devra appuyer sur le bouton Engrenage situé en bas à droite de la page Profile. Lorsque l’utilisateur modifie son profil, il aura un message comme quoi l’action a bien été effectué.\nPour implémenter cette partie, d’abord il faut faire les connections et la requête de recupération des données de l’utilisateur. Lors de la connexion ou de l’inscription, un jeton est créé contenant le hashage du mot de passe de l’utilisateur et de son email, une variable conserve aussi l’email.\nPour la modification du profile, une requête de mise à jour doit être faite. Il est possible de modifier l’adresse email, cependant il faudra modifier celle qui est en mémoire dans l’application ainsi que de conserver une copie de l’ancienne adresse pour faire la requête. Une modification des préférences est aussi faite si l’email a été modifié. Les préférences sont utilisés pour conserver les donn´ees utile au fonctionnement lorsque l’application est arrêtée.\nTempérature L’utilisateur peut consulter les relevés par le thermistor. Sur la page de température, on peut voir la température qui est relevé toutes les 3 secondes. Le diagramme circulaire permet de faire les pourcentages sur le mois dernier en fonction des températures. Sur la page du graphique à ligne brisée relie toutes les valeurs que l’on a en base de données entre elle avec sur l’axe des abscisses la date et sur l’axe des ordonnées les températures en degré Celsius.\nLe logo utilisé a été téléchargé sur flavicon. Pour récupérer les données du capteur à intervalle régulier, il a fallu créer une fonction que l’on appelle au bout d’un certains temps. Nous avons créer la fonction getData qui fait une requête HTTP à notre microcontrôleur. La route pour effectuer cette requête est http://192.168.1.54/temperature. L’IP est visible mais c’est une adresse que nous avons fixé sur notre ESP32. Une fois la valeur récupérée, il faut lors de l’affichage restreindre la valeur à une seul décimale en utilisant la méthode toStringAsFixed.\nPour l’affichage du diagramme circulaire, qui n’est calculé qu’une seule fois vu que les valeurs du mois dernier ne bouge pas, on récupère les données de la table Temperature.\nIl ne reste plus qu’à trier les températures par unité. Par exemple, si nous avons des valeurs comme 17.8, 17.2, elles seront comptées pour des températures à 17. La fonction qui nous permet de faire ce tri est generateSections. Chaque section du diagramme aura une couleur définie aléatoirement avec la fonction getRandomColor.\nEn appuyant le bouton du graphe, situé en bas à droite de la page de Température, l’utilisateur est redirigé vers une autre page contenant un graphe à ligne brisée. Pour faire ce graphe, il a fallu d’abord récupéré les valeurs stockées dans la base de données dans la table Temperature, les traiter pour leur graphe et les mettre dans une liste de FlSpot. Il est possible de cliquer sur chaque point pour avoir les valeurs de températures.\nLumière Sur cette page, l’utilisateur peut consulter les valeurs récupérées sur le photoresistor de notre microcontrôleur. Il y a aussi un diagramme circulaires représentant les pourcentages des types d’ambiances sur le mois dernier. Le bouton graphe, situé en bas à gauche de la page renvoie vers le graphe des températures.\nPour implémenter la mise en place de cette page, il a fallu faire une requête HTTP pour avoir la valeur de lumière que l’on récupère toutes les 3 secondes dans notre cas. Sur la valeur que l’on récupère, on lui attribue un style d’ambiance qui sera Sombre, Faible, Modéré, Lumineux ou Très lumineux.\nPour le diagramme circulaire, il a fallu récupéré toutes les données dans la table Light. Une fois que les valeurs sont récupérées, il faut créer les sections ce que l’on fait dans la fonction generateSections. D’abord, on crée un Map avec nos 5 catégories (de Sombre à Très lumineux et pour chaque valeur que l’on aura récupéré, on vérifie dans quelle catégorie elle appartient et on incrémente la valeur du Map. Il ne reste plus qu’à faire les pourcentages et faire les sections du diagramme.\nContrôle des LED L’utilisateur peut contrôler la vitesse, et si la LED est allumée ou non. Il suffit juste d’appuyer sur le plus ou le moins pour r´eduire la vitesse ou l’augmenter. Des boutons Switch permet d’allumer ou d’éteindre la LED.\nIl faut récupérer les données des LED et de si le mode automatique est actif avec des requêtes HTTP, les fonctions qui permettent ceci sont getData et getAuto qui sont appelés toutes les 5 secondes.\nUne fois que nous avons récupéré les données, il ne reste plus qu’à lier les variables avec le comportement des boutons. Si le résultat de getAuto est ”on” alors le bouton sera actif. On aura la même logique pour savoir si la LED est allumée avec les résultats de getData, on affichera la vitesse de clignotement aussi. La vitesse de clignotement peut être modifiée en appuyant sur le plus et le moins. L’utilisateur peut maintenir le bouton car le comportement est géré, du moment que le bouton est maintenu la valeur incrémentera (ou décrémentera). Il faut appeler la fonction updateLedAState (pour la LED A rouge) ou updateLedBState (pour la LED B verte).\nRéglages des LED L’utilisateur peut régler le mode automatique en donnant le comportement qu’il attend (la vitesse de clignotement et si la LED est allumée/éteinte) et le seuil sur lequel il est sensé s’arrêter. La LED A - rouge sera allumé jusqu’à ce que le seuil de température soit atteint sinon elle s’éteindra. Même chose pour la lumière et la LED B - verte. Le bouton situé en haut nommé LED permet d’éteindre toutes les LED. Le bouton Auto permet de mettre le mode automatique sur les 2 LED ou sur aucune.\nToutes les informations sont récupérés avec la fonction getDataAuto et sont récupérés toutes les 5 secondes. La quantité de contrôle a nécessite que la page soit scrollable. Plusieurs fonctions permettent de mettre à jour les valeurs du mode automatique.\nupdateLedAutoT : permet d’activer ou désactiver le mode automatique de la LED température (LED rouge) updateLedAutoL : permet d’activer ou désactiver le mode automatique de la LED de lumière (LED verte) updateLedAllAuto : permet de mettre à jour les deux modes automatiques updateLedATemp : permet de mettre à jour le comportement de la LED Rouge. updateLedBLight : permet de mettre à jour le comportement de la LED verte updateSeuilTemp : permet de mettre à jour le seuil de température updateSeuilLight : permet de mettre à jour le seuil de lumière. Toutes ces fonctions utilisent des requêtes HTTP pour donner les informations ou récupérer sur l’ESP 32. ","date":"2023-09-30T00:00:00Z","image":"https://example.org/post/iot/background_hub5e10c7ed4c45b08c9b16b62fff9151c_4636037_120x120_fill_q75_box_smart1.jpg","permalink":"https://example.org/post/iot/","title":"IoT capteur TTGO T-Display - M2"},{"content":"Lien GitLab\nDescription Ce projet est une application Android pour consulter, postuler et gérer ses candidatures sur des offres d\u0026rsquo;emplois.\nIntroduction Ce projet est une application Android qui permet à un utilisateur soit de créer ses annonces soit de pouvoir postuler. Une gestion de candidatures est présente : un employeur peut consulter les candidatures qu\u0026rsquo;il a reçu ou un chercheur d\u0026rsquo;emploi peut consulter les informations qu\u0026rsquo;il a entré (CV, Lettre de motivation, etc).\nDémo Your browser doesn't support HTML5 video. Here is a link to the video instead. Connexion/Inscription/Modification de compte La connexion à la base de données de l’application permet à l’utilisateur de se connecter avec une adresse email et un mot de passe. Il lui suffit de sélectionner le rôle qui lui correspond, d’entrer son mail et son mot de passe utilisateur dans les champs correspondants pour accéder à la page de profil correspondante. La connexion d’un utilisateur est maintenue entre les lancements de l’application. Elle ne s’ar- rête que lorsque l’utilisateur se déconnecte manuellement depuis sa page de profil. Cette connexion est gérée par un système de jetons de connexion, qui conserve l’identifiant et le rôle de l’utilisateur connecté.\nS’il ne possède pas de compte, l’utilisateur peut également s’inscrire depuis la page de profil. Il lui suffit alors de renseigner les informations correspondantes selon son statut : s’il est chercheur d’emploi, employeur ou représentant d’une agence d’intérim. Il lui faudra ensuite renseigner un mot de passe et le confirmer, avant que les requêtes correspondant à la création de compte soient envoyées.\nDans le cadre de la gestion des utilisateurs, l’application permet aux utilisateurs de modifier leurs informations personnelles. Cette fonctionnalité est accessible depuis la page de Profil des utilisateurs, qui affiche toutes les informations liées à l’utilisateur via un appel à la base. Cette page permet à l’utilisateur de consulter ces informations, mais également d’accéder à la page de modification du profil. Les pages Mon profil et modification de profil s’adaptent également en fonction de l’utilisateur, ainsi les Employeurs auront une page plus complète avec les informations correspondantes. Le formulaire de modification est adapté au type d’utilisateur. Afin de faciliter la vie de l’utilisateur, les champs de la page de modification de profil sont préremplis via une requête SQL avec les valeurs actuelles présentes dans la base. Cela évite à l’utilisateur de devoir recopier toutes ses informations personnelles s’il souhaitait seulement, par exemple, ajouter son nouveau numéro de téléphone. Cette approche plus ergonomique allège signi- ficativement la modification du profil pour l’utilisateur.\nProfil Selon qu’il est connecté ou non et selon son rôle, un utilisateur verra apparaître des pages de profil différentes qui correspondent le mieux à ses permissions. Parmi les options présentées ci-dessus, les options Aide à la candidature et A propos de nous sont communes aux trois rôles d’utilisateur. Ces pages sont essentiellement informatives et ne comprennent aucune caractéristique technique\nAbonnements Lorsqu’un nouvel utilisateur s’inscrit, l’application va lui demander de choisir un type d’abonne- ment pour pouvoir utiliser Interima. Il en existe 6 différents, avec des avantages et un tarif associé. Le choix de l’abonnement est enregistré dans la base avec l’utilisateur qui lui est associé, et après avoir cliqué sur l’abonnement qu’il désire l’utilisateur est emmené sur une page de confirmation qui résume les caractéristiques et le tarif de son abonnement et lui permet de confirmer le choix de l’abonnement. Bien entendu, dans le cadre de notre projet d’étudiant, cette étape n’exige pas de réel moyen de paiement.\nAnnonces Tri des annonces en fonction de la géolocalisation Un utilisateur anonyme va voir en priorité les annonces les plus proches de sa position géogra- phique, s’il active la géolocalisation de son appareil sur l’application. La position de l’utilisateur est traquée via la permission d’accès à la géolocalisation de l’appareil. Une fois la position mise à jour, la distance entre l’utilisateur et les offres est calculée via les valeurs de longitude et de latitude, puis elles sont triées pour afficher en premier les offres à proximité. Passé le tri initial, les annonces sont mises à jour toutes les 10 secondes, si la position de l’utilisateur a changé d’au moins 10 mètres.\nRecherches par mot clé Nous avons implémenté un système de recherche par mots clé. Ce système est fonctionnel depuis la page de recherche de notre application, accessible via la barre de navigation présente en bas de chaque page. Un utilisateur connecté peut accéder à son historique des recherches.\nPartage d\u0026rsquo;annonce Un utilisateur anonyme peut partager une annonce depuis la page principale, depuis la page de recherche ou depuis la page complète d’une annonce. Pour l’instant, seul le partage par SMS possède une véritable logique métier.\nPublication d\u0026rsquo;annonce La publication d’une annonce est une fonctionnalité réservée aux utilisateurs de type Em- ployeur. Ainsi, l’activité de création d’offres n’est disponible que pour les utilisateurs de type Employeur. e choix de la date de début et de fin de l’offre utilisent un DatePickerDialog. es valeurs de longitude et latitude permettront de répertorier l’offre dans l’espace et de la recommander aux intérimaires proches. Malgré une tentative d’utiliser une API de Google pour déterminer la latitude et longitude à partir d’une adresse, nous avons eu des difficultés et l’implé- menter et choisi de requérir la latitude et la longitude directement.\nFavoris Notre application supporte un système de favoris qui permet aux utilisateurs de marquer les offres qui les intéressent, par exemple pour pouvoir candidater plus tard s’ils n’ont pas le temps de s’en occuper pour le moment. Pour favoriser une offre, un utilisateur de l’application clique sur le bouton marque-pages de l’annonce qui l’intéresse.\nCandidatures Envoi/réutilisation Un chercheur d’emploi peut candidater à une annonce depuis la liste des annonces, puis depuis la page complète de l’annonce choisie. En cliquant sur le bouton Candidater de cette dernière, le chercheur d’emploi est alors face à un choix : soit il peut rédiger une toute nouvelle candidature, soit il peut réutiliser les informations (notamment le CV et la lettre de motivation) d’une candidature précédent.\nGestion des candidatures Un chercheur d’emploi peut consulter ses candidatures depuis la page Mes candidatures de son profil. Pour chacune des candidatures, l’option Consulter permet de consulter la candidature entière ; on retrouve alors le titre de la candidature, le lien vers le CV et la lettre de motivation.\nEn revanche, un employeur ou une agence d’intérim peuvent consulter les candidatures qu’elles reçoivent des chercheurs d’emploi qui ont candidaté à leurs annonces. En plus de pouvoir consulter le détail de ces candidatures, elles peuvent également décider de l’accepter ou de la refuser.\nPartage Il est possible via notre application de partager une candidature via SMS. Pour l’instant, seul le partage par SMS possède une véritable logique métier.\nCahier des charges Dans le cadre de ce projet, nous avons été soumis à un cahier des charges. Parmi les fonctionnalités imposées par le cahier des charges, nous dressons une liste des fonctionnalités que nous avons implémentées lors de ce projet :\nconsultation des annonces en détail recherche d’annonces par mot clé connexion et inscription utilisateur page de profil partage d’annonces, de candidatures pages d’informations : aide à la candidature, section \u0026ldquo;A propos\u0026rdquo; fonctionnalités pour chercheur d’emploi : envoi d’une candidature sur une annonce ou candidature spontanée réutilisation d’une candidature consultation des candidatures envoyées consultation des CV et lettres de motivation associées aux candidatures consultation de l’historique des recherches mise en favoris d’annonces fonctionnalités pour employeur : publication d’annonces via formulaire consultation des offres publiées gestion des candidatures reçues sur les annonces (consultation, confirmation, refus) fonctionnalités pour agence d’intérim : publication d’annonces via formulaire et envoi de fichier JSON consultation des offres publiées gestion des candidatures reçues sur les annonces (consultation, confirmation, refus) Base de données sur Raspberry Pi et Docker Notre base de données suit le schéma suivant :\nPour que notre base de données soit accessible depuis n’importe quel appareil, nous devions trouver un moyen de la mettre en ligne. La démarche que nous avons choisi est d’utiliser un Raspberry Pi 4 qui fait tourner une image de MySQL avec Docker.\nUne configuration sur les volumes était nécessaire. En effet, la base de données pourrait s’arrêter suite à un problème de synchronisation avec une plateforme telle que Docker. Il nous faut alors des données persistantes, d’où l’utilité de créer des volumes. Les ports d’entrée et de sortie sont aussi spécifiés pour pouvoir faire les redirections correctement.\nUne fois que la base de données était fonctionnelle, il fallait configurer son accès depuis l’extérieur. Tout d’abord, dans le fichier SQL de création de la base, un utilisateur avec les droits de gestion a été créé pour pouvoir faire les différentes requêtes de gestion (insertions, mises à jour, \u0026hellip;). Ensuite, afin de pallier le problème des addresses IP dynamiques d’un modem, nous avons mis en place un DNS avec No-Ip. Ce site permet de récupérer les adresses IP d’une box Internet qui l’envoie à intervalles réguliers.\n","date":"2023-01-01T00:00:00Z","image":"https://example.org/post/interima/app_hu66066e329f89b82dc6b3375df0303330_169353_120x120_fill_box_smart1_3.png","permalink":"https://example.org/post/interima/","title":"Application d'intérim - M1"},{"content":"Lien GitLab\nDescription Ce projet est un site web permettant l\u0026rsquo;importation sur Solid et l\u0026rsquo;exploitation de données personnelles de Google, Instagram ou Facebook.\nIntroduction Ce projet permet d\u0026rsquo;importer les données que l\u0026rsquo;on récupère auprès de Google, Instagram ou Facebook sur un pod Solid. Nous avons ensuite plusieurs exploitations possibles à partir de ces données stoquées comme les informations générales de profil, les images, etc.\nSolid La technologie Solid (Social Linked Data) est une initiative créée par Tim Berner Lee pour le World Wide Web Consortium (W3C). Solid vise à redonner aux utilisateurs le contrôle total de leurs données personnelles en ligne. Cette technologie permet aussi de créer des espaces personnels de données, appelés ”Pods”, où les utilisateurs peuvent stocker, gérer et partager leurs informations de manière sécurisée.\nDans Solid, les données sont stockées sur des modules de données personnels, accessibles via le Web. Les agents ont le contrôle sur l\u0026rsquo;accès à leurs données sur ces modules. Les modules de données peuvent être connectés tant qu\u0026rsquo;il y a une connexion Internet et des contrôles d\u0026rsquo;accès appropriés.\nLes agents peuvent choisir librement parmi différents fournisseurs pour stocker leurs données. Actuellement, les principaux fournisseurs sont inrupt.net et solidcommunity.net.\nFonctionnalités Pour pouvoir utliser toutes les fonctionnalités de notre application, il faut d\u0026rsquo;abord faire la première étape sur la page principale : la connexion.\nAccueil Sur la page principale, nous avons plusieurs fonctionnalités :\nla connexion : L\u0026rsquo;utilisateur peut choisir de se connecter parmi différents fournisseurs pour stocker leurs données. Nous avons lister les principaux fournisseurs: inrupt.net et solidcommunity.net. Apres son choix, il sera redirigé vers le fournisseur.\nchanger le nom rattaché au Pod\ntrouver le nom d\u0026rsquo;un pod à partir du WebID (adresse d\u0026rsquo;un Pod)\nUn affichage des dossiers à la racine du pod est affiché\nAjouter sur le pod une archive ou un dossier des données du réseau conserné (Google, Facebook ou Instagram)\nVoir les données ajoutées au Pod en fonction du réseau sélectionné\nimage liste deroulante partie connexion Interprétations des données Calendrier Nous avons fait un affichage en calendrier pour les messages Facebook et Instagram ainsi que pour les mails de Google. En effet, nous avons opté de faire ceci car tous les utilisateurs n\u0026rsquo;activent pas forcément la géolocalisation, rendant l\u0026rsquo;exploitation de données de positions impossibles. On peut consulter le calendrier sur le mois, semaine, jour ou en liste.\nProfil Nous avons choisi de faire un onglet spécifique à la visualisation des informations personnelles. Il regroupe les noms, emails, date de naissance et autres informations.\nListes des activités Les \u0026ldquo;données de trafic\u0026rdquo; sont les informations générées lors de l\u0026rsquo;utilisation de réseaux (Ip, etc), ces données sont présentes dans la récupération fournie par Google. Nous avons donc fait un tableau avons les dates d\u0026rsquo;activités, l\u0026rsquo;adresse Ip et ce que l\u0026rsquo;appareil était en train de faire (Gmail, ect).\nPhotos Nous pouvons récupérés les photos sur Google et Instagram. Les métadonnées sont affichées lorsqu\u0026rsquo;on passe la souris sur l\u0026rsquo;image en question.\nMessages Nous avons exploité les messages de Facebook et donc refait le fil des différentes discussions en spécifiant le nom de la personne qui parle puit son message.\nDémo Your browser doesn't support HTML5 video. Here is a link to the video instead. Utilisation du projet Installations nodejs npm Lancement git clone https://gitlab.com/AlyssaShep/ter-espace-personnel-de-donnees.git npm install npm run build \u0026amp;\u0026amp; npm run start Ouvrez un navigateur à l\u0026rsquo;adresse : http://localhost:8080/\nImplémentation Interface utilisateur L\u0026rsquo;interface utilisateur (UI) est la couche visible de l\u0026rsquo;application, permettant aux utilisateurs d\u0026rsquo;interagir. Lors de la conception, nous avons pensé à faire une page de connexion au Pods pour obtenir le token permettant de faire les différentes opérations sur un Pod, sans ça, nous ne pouvons rien faire sur un Pod (récupération, modification, ajout de données\u0026hellip;). Par la suite, pendant la phase de développement, nous avons ajouté le formatage du nom du Pod et de faire une recherche de nom (pour savoir si un utilisateur avec ce nom là existe).\nAccueil Connexion Tout d\u0026rsquo;abord, pour pouvoir faire une opération sur notre Pod, il faut se connecter. Pour cette partie, nous utilisons \u0026lsquo;solid-client-authn-browser\u0026rsquo; d\u0026rsquo;Inrupt. Par la suite, il faut choisir avec quoi on va se connecter : \u0026lsquo;solidcommunity.net\u0026rsquo;, \u0026lsquo;inrupt.net\u0026rsquo;, \u0026lsquo;.inrupt.com\u0026rsquo; ou encore \u0026lsquo;solidweb.org\u0026rsquo;. La sélection se fait à partir d\u0026rsquo;une liste déroulante.\nCeci est possible grâce au code suivant. Cette fonction est utilisée pour initier le processus de connexion. Si l\u0026rsquo;utilisateur n\u0026rsquo;est pas déjà connecté, elle appelle la fonction \u0026rsquo;login()\u0026rsquo; pour effectuer la connexion. Elle spécifie également le nom du client et l\u0026rsquo;URL de redirection pour le processus de connexion.\nCette fonction est utilisée pour gérer la redirection après le processus de connexion. Elle appelle la fonction \u0026lsquo;handleIncomingRedirect()\u0026rsquo; pour terminer le processus de connexion en récupérant les informations de session. Si l\u0026rsquo;utilisateur est connecté avec succès, elle met à jour la page avec le statut de connexion et le WebID de l\u0026rsquo;utilisateur.\nModification/recherche du nom Nous avons mis en place une fonction permettant à l\u0026rsquo;utilisateur de modifier le nom de son Pod. Bien qu\u0026rsquo;optionnel, cela permet encore une fois à l\u0026rsquo;utilisateur un contrôle totale sur ses données.\nDe plus, nous avons décider de permettre à l\u0026rsquo;utilisateur d\u0026rsquo;afficher le nom de son Pod par son webID.\nAffichage des dossiers Nous avons une section qui permet de voir tous les dossiers présents à la racine de \u0026lsquo;Your storage\u0026rsquo; présent dans le Pod. En effet, pour la recherche, on a besoin du WebID du Pod et appliquer la fonction getSolidDataset de \u0026lsquo;@inrupt/solid-client\u0026rsquo; pour récupérer le jeu de données Solid associé à l\u0026rsquo;URL du Pod. Avec ce jeu de données, on utilise la fonction \u0026lsquo;getThingAll\u0026rsquo; pour obtenir tous les objets (ou ressources) contenus dedans. Puis, nous appliquons un filtre pour obtenir que les dossiers. Le filtre s\u0026rsquo;applique sur les url des objets obtenus (l\u0026rsquo;url d\u0026rsquo;un dossier finira par \u0026lsquo;/\u0026rsquo;).\nPuis, nous avons implémentés une fonction qui gère l\u0026rsquo;affichage de dossier. S\u0026rsquo;il n\u0026rsquo;y a pas de dossiers, un message d\u0026rsquo;informations nous le signalera sinon chaque dossiers présent sur le Pod seront listés de façon a ce que l\u0026rsquo;utilisateur sache toutes les données qu\u0026rsquo;il stocke pour le moment.\nAjout sur le pod Une autre section permet a l\u0026rsquo;utilisateur de prendre un fichier de n\u0026rsquo;importe quel type, un dossier ou une archive et de le mettre sur le Pod dans le dossier public.\nAffichage des fichiers dans un dossier Pod Enfin, dans la dernière section, nous avons un affichage des fichiers et sous-dossier présent sur un dossier contenant les données personnelles récoltées sur Google, Facebook ou encore Instagram. Le dossier en question doit porter le nom du réseau en question et doit être mis à la racine de \u0026lsquo;Your storage\u0026rsquo;.\nCette fonction est faite en 2 parties et est récursive. En effet, nous avons la même logique que pour la recherche de dossier mais l\u0026rsquo;url de recherche sera différent : le dossier du réseau étant dans public nous devons faire une recherche de sa présence dedans (UrlWithPublic).\nNous récuperons ensuite la liste des Url présents dans ce dernier. Cependant, si on ne faisait qu\u0026rsquo;un passage sur UrlWithPublic, nous aurions que la liste des objets présents et non TOUS les éléments. Ainsi, Nous récuperons tous les éléments de ces sous-dossiers par la fonction getAllInsideFolderRecursive. Si c\u0026rsquo;est un fichier, la fonction n\u0026rsquo;ajoutera que le lien du fichier sinon il bouclera jusqu\u0026rsquo;à ce qu\u0026rsquo;il tombe sur un fichier (parcours en profondeur). Comme les dossiers présents dans \u0026lsquo;Your storage\u0026rsquo;, une fonction d\u0026rsquo;affichage est présente. Et permet l\u0026rsquo;apparition d\u0026rsquo;un bouton \u0026lsquo;Voir les interprétations\u0026rsquo; et ainsi d\u0026rsquo;être redirigé vers les interprétations.\nInterprétations des données La seconde partie de ce projet étant l\u0026rsquo;interprétation des données, nous avons dans un premier temps dû analyser les données récupérés. Par interprétation des données on entend la mise en place d\u0026rsquo;une interface utilisateur permettant à ce dernier de parcourir l\u0026rsquo;ensemble de ses données de façon visuelle et interactive. Lorsque nous avons récupéré nos données personnelles sur ces réseaux, nous avons constatés que les formats des fichiers n\u0026rsquo;étaient pas tous les mêmes. Cela a représenté un grands défi à relever dans ce projet. En effet, pour les données Instagram et Facebook, nous avons exclusivement des fichiers JSON. Cependant, ce n\u0026rsquo;est pas le cas de Google. On retrouve au sein des données Google des formats de type : JSON, CSV, txt, ics, html, vcf, jpg \u0026hellip; Il y a une multitude de formats possibles, ce en partie à cause du Google Drive.\nDans un premier temps, nous pensions à convertir l\u0026rsquo;ensemble de nos fichier en RDF. Cependant, nous avons décidé de ne pas convertir nos données en RDF pour plusieurs raisons. Tout d\u0026rsquo;abord, à cause du nombres de formats indéterminés sur le Google Drive. De plus, Solid nous permet de déposer des données non RDF. Mais surtout à cause des formats majoritaires qui sont le JSON et le CSV. Sans oublier que chaque prédicat dans les fichiers RDF comportent des URI, ce qui peut très rapidement devenir compliqué à mettre en place.\nLe JSON est un format de données textuelles largement utilisé pour structurer et représenter des données de manière lisible par l\u0026rsquo;homme. Il est souvent utilisé dans le développement web et les API, car il est facilement interprétable par JavaScript et de nombreux autres langages de programmation. Le JSON prend en charge les structures de données complexes telles que les objets et les tableaux, et il est bien adapté pour représenter des hiérarchies de données avec des propriétés clés-valeurs.\nLe CSV quant à lui est un format de données tabulaire simple où chaque ligne représente un enregistrement et les valeurs sont séparées par des virgules (ou parfois par d\u0026rsquo;autres délimiteurs). Le CSV est largement utilisé pour échanger des données tabulaires entre différentes applications, notamment les feuilles de calcul, les bases de données et les outils d\u0026rsquo;analyse de données. Il est généralement plus léger en termes de taille de fichier que le JSON, ce qui peut être un avantage dans certains scénarios où l\u0026rsquo;espace est limité.\nAinsi, ces deux formats sont parfaits pour l\u0026rsquo;interprétation de données.\nCe sont donc les formats de données que nous avons choisis de conserver pour la mise en place de l\u0026rsquo;interprétation et de l\u0026rsquo;analyse de nos données.\nCalendrier Pour les données du calendrier, en fonction du réseau que l\u0026rsquo;on sélectionne, on ira chercher des informations différentes sur le Pod. Pour Google, ce sera les mails. Pour Facebook, les likes et pour Instagram, les commentaires.\nIl faut transformer ses données pour le calendrier. On utilise nos fonctions :\n\u0026ldquo;mboxToJson(..)\u0026rdquo; : tranforme les emails en Json\n\u0026ldquo;tranformGoogleMailForCalendar(..)\u0026rdquo; : prend le fichier Json résultat de la fonction précédente (mboXToJson(..)) et fait un affichage que l\u0026rsquo;on définit pour notre calendrier\n\u0026ldquo;transformCommentDataForCalendar(..)\u0026rdquo; : transforme les commentaires de Facebook ou Instagram sous format Json en notre affichage personnalisé pour le donner au calendrier\nUne fois qu\u0026rsquo;on a les informations sont transformés, on utlise les fonctions displayFileOnCalendar(..) pour faire l\u0026rsquo;affichage.\nProfil Pour l\u0026rsquo;affichage des informations des profils, on utilise notre fonction getFileProfil(..). Il faut d\u0026rsquo;abord recupérer les informations sur le Pod, puis on les traite.\nPour instagram, les informations sont fragmentées en 4 fichiers. On récupère aussi la photo de profil sur le Pod.\nPour Google, les informations ne sont pas fragmentées mais sont dans 1 seul fichier. La photo de profil est aussi sur un fichier à part.\nPour Facebook, les informations sont aussi dans 1 seul fichier.\nUne fois que les informations sont préparés, on les affiche sur la page de Profil.\nListe d\u0026rsquo;activité Notre fonction GetDevices(..) permet de récupérer, pour Google, 2 fichiers :\nla liste des services utilisés\nla liste des appareils\nIl reste plus qu\u0026rsquo;à afficher les données en tableau pour plus de clareté.\nPhotos Pour l\u0026rsquo;affichage des photos, on doit d\u0026rsquo;abord sélectionner le réseau que l\u0026rsquo;on souhaite voir grâce à la liste déroulante. Notre fonction \u0026ldquo;affichagePhotos(..)\u0026rdquo; va prendre les données consernées sur le Pod Solid puis va les afficher en ajoutant les images une à une sur la page.\nMessages Pour l\u0026rsquo;affichage des messages, on doit les récupérer du Pod Solid. Les données sont stockés sous le format Json. L\u0026rsquo;utilisateur peut sélectionner la conversation qu\u0026rsquo;il souhaite voir avec la liste déroulante. Les noms des conversations sont obtenus grâce à la fonction \u0026ldquo;getConversationName(..)\u0026rdquo;. Une fois la conversation sélectionné, on affiche les messages avec la fonction \u0026ldquo;getFacebookMessage(..)\u0026rdquo;. On extrait l\u0026rsquo;auteur, le message et la date du message. Puis on l\u0026rsquo;affiche avec \u0026ldquo;displayConversation(..)\u0026rdquo;.\n","date":"2023-01-01T00:00:00Z","image":"https://example.org/post/solid/solid_hu694d995a98ce01a581c1622f8a363499_80051_120x120_fill_box_smart1_3.png","permalink":"https://example.org/post/solid/","title":"Projet SOLID - M1"},{"content":"Lien GitLab\nDescription Ce projet est une interface textuelle qui calcule et affiche des statistiques (nombres de transactions, etc) extraites de la blockchain Bitcoin avec Rust.\nIntroduction Ce projet offre la découverte de deux univers ayant récemment émergés : la blockchain Bitcoin, et Rust. La thématique était de manipuler les registres de cette cryptomonnaies en utilisant un langage que nous ne connaissions pas. Ce projet a été fait en collaboration avec des enseignants de Polytech Montpellier.\nFonctionnalités L’interface graphique est accessible depuis un terminal UNIX, Windows, ou même depuis un terminal lancé dans un environnement de développement intégré. L’interface graphique est responsive : elle s’adapte quand l’utilisateur redimensionne la fenêtre. Celle ci est divisée en cinq onglets.\nl’onglet Présentation : présente brièvement le programme, rappelle les commandes que l’on peut faire pour lancer le programme autrement, aﬀiche les touches pour aﬀicher immédiatement l’aide ; l’onglet Blocs aﬀiche les informations générales d’un bloc : la taille du bloc, le nombre de transactions, la version, la racine de Merkle, l’horaire, les bits, le nonce, diverses statistiques (le volume d’échanges, la valeur moyenne et médiane, le premier et troisième quartile) ; l’onglet Transactions aﬀiche un graphique du nombre de transactions par bloc, l’onglet BTC aﬀiche un graphique de la plus grosse valeur par bloc, l’onglet Aide explique comment naviguer entre les onglets, et comment accéder aux différentes fonctionnalités. Nous avons aussi mis en place des barres de progressions sur l’exportation des données, la mise en place des données pour le terminal ainsi que pour le parseur avec le nom spécifique du lieu d’écriture ou de lecture. Au moment de l’écriture nous proposons plusieurs choix à l’utilisateur : json ou txt ou le choix de quitter l’écriture.\nNous avons donc opté pour un nuage de points. Celui-ci permet de voir les résultats sur tous les blocs en même temps. Il y a aussi la présence du repère avec les blocs (abscisses) et le nombre de blocs (ordonnées) ce qui permet d’avoir plus de recul et d’impact sur la totalité des blocs.\nDémo Your browser doesn't support HTML5 video. Here is a link to the video instead. Utilisation du projet Crates Nous avons utilisé les crates suivantes :\nchrono : une bibliothèque pour la gestion du temps qui permet d’interpréter l’heure Unix contenue dans l’en-tête des blocs crossterm : une bibliothèque pour manipuler un terminal hex-string : une structure qui facilite la convertion de vecteurs d’entiers vers des chaînes hexadécimales, et qui est particulièrement utile du fait que la base 16 est largement utilisée dans Bitcoin pour les repré- sentations de clés privées, clés publiques, signatures ou hashs, sha2 : une implémentation des fonctions de hachage de la famille SHA-2, qui permet d’utiliser la fonction SHA-256, nécessaire pour obtenir, entre autres, des identifiants de blocs ou de transactions, tui-rs : une bibliothèque qui permet de construire des interfaces utilisateur et des tableaux de bord dans un terminal, en les divisant en widgets aﬀichables, et qui permet également de définir et contrôler. Installations cmake pkg-config libssl libfreetype6-dev (Debian) libexpat1-dev (Debian) / libexpat libxcb-composite0-dev (Debian) / libxcb (Arch Linux) Debian sudo apt install cmake sudo apt install pkg-config libasound2-dev libssl-dev cmake libfreetype6-dev libexpat1-dev libxcb-composite0-dev Arch Linux sudo pacman -S cmake pkg-config libexpat libxcb Lancements Les fichiers blk.dat doivent être placés dans un dossier ./ins, et les fichiers d’exportation sont placés dans un dossier ./outs dans le projet. Il est possible de choisir le dossier contenant les fichiers à lire, le dossier contenant les fichiers à exporter, ou les deux à la fois, en lançant le programme ainsi :\ncargo run --release i ./dossier_à_lire/ cargo run --release o ./dossier_où_exporter/ cargo run --release io ./dossier_à_lire/ ./dossier_où_exporter/ Implémentation Cahier des charges Les fonctionnalités qui étaient à implémenter rentrent dans trois catégories\nDésérialiser les données contenues dans les fichiers blk.dat :\nLire les métadonnées de l’en-tête (version, hash du bloc précédent, etc.), Lire les transactions, Reconstruire l’arbre de Merkle ; Analyser les données :\nCompter le nombre de transactions contenues dans un bloc, Extraire les adresses, Rechercher la plus grande somme transférée, calculer la somme moyenne transférée en fonction d’une période, etc. ; Exporter les données via un affichage ou dans un fichier\nApproche Pour réaliser ce projet, nous avons tout d’abord mis en place un parseur capable de lire des fichiers blk.dat, les uns après les autres, de délimiter les différents champs contenus dans ce fichier, puis de stocker les données en mémoire, dans des structures au format approprié. Nous vérifions ensuite l’intégrité des données par le calcul de la racine de Merkle. Par la suite, l’analyse des données est faite depuis ces structures stockées en mémoire. Finalement, l’utilisateur peut visionner les données depuis une interface graphique intégrée au terminal.\nParseur Le parseur, notre module le plus important. Dans un premier temps, l’entièreté du fichier blk.dat est placée telle quelle dans un tampon en mémoire, ce qui offre plus de liberté pour déplacer un curseur en fonction d’un nombre variable d’octets. Puis, le module analyse octet par octet le tampon détermine sa taille, ses transactions, et enfin le stocke en mémoire dans une structure adaptée.\nUn fichier blk.dat est constitué de blocs mis les uns à la suite des autres. Chaque bloc est constitué de plusieurs champs de tailles et de types différents. Certains champs ont une taille fixe, comme les bits magiques qui annoncent le début d’un bloc et le type du réseau qui a été employé. Ses quatre octets sont toujours les mêmes parmi « f9beb4d9 », « 0b110907 » et « fabfb5da ». Pour obtenir les bits magiques, le parseur lit simplement les quatre premiers octets. En revanche, certains champs n’ont pas de taille fixe. C’est le cas du champs « Input Count » qui indique le nombre de transactions à venir. Ce nombre peut être un, comme mille. La taille du nombre de transactions étant variable, le parseur ne devra donc pas lire systématiquement le même nombre d’octets afin de le déterminer. Pour qu’il soit possible de deviner sa taille, l’« Input Count » utilise un système de préfixe. Si la valeur du premier octet (le préfixe) est supérieure à 0xfc, il faut se reporter à ce tableau :\nPréfixe Exemple Description\nPréfixe Exemple Description ≤ 0xfc 12 Lire zéro octet de plus ≤ 0xfd fd1234 Lire deux octets de plus ≤ 0xfe fe12345678 Lire quatre octets de plus ≤ 0xff ff 1234567890abcdef Lire huit octets de plus Le module lecture_frac gère également l’exportation des données vers des fichiers. Il permet d’exporter l’entièreté d’un fichier blk.dat vers un fichier json, en rendant ses données facilement compréhensibles, ou encore d’exporter toutes les adresses présentes depuis un fichier blk.dat vers un fichier txt.\nAutres modules Le module conversions contient une fonction de conversion entre satoshis et bitcoins, ainsi qu’une fonction qui permet un aﬀichage agréable de l’horaire. Le module merkle_tree contient les fonctions nécessaires au calcul de la racine de Merkle, et à l’aﬀichage de l’arbre reconstitué. Le module recherches offre plusieurs fonctions de recherche : une fonction qui recherche la plus grande somme transférée dans tout le fichier, une qui fait la même recherche mais pour chaque bloc, ainsi qu’une fonction qui calcule la somme des bitcoins échangés au cours d’un même journée passée en paramètre. Le module tris permet de trier en O(n log n) l’ensemble des blocs selon l’horaire qu’ils contiennent. Rappelons que lorsqu’on télécharge les blocs depuis un réseau Bitcoin, il arrive que certains blocs soient téléchargés dans le désordre. Enfin, le module Calculs contient les fonctions qui permettent l’extraction des clefs publiques, de leurs hashs, et des adresses. Multithreading Après la première mise en place du parseur, ce dernier était très lent. L’outil était également ralenti par le calcul de la racine de Merkle. Nous avons pu apporter des optimisations grâce à la mise en place de threads dans le module lecture_frac et dans le module merkle_tree.\nL’idée ici est qu’un thread travaille sur un certain nombre de blocs. Il faut donc compter le nombre de blocs du fichier, ainsi que leur longueur. Comme un bloc commence par les bits magiques, suivis de sa taille, il suﬀit de lire les huit premiers octets, et de déplacer le curseur en l’incrémentant avec la taille extraite. Cette dernière est également stockée dans un tableau dynamique d’entier. Ensuite, il faut vérifier que le nombre de threads est bien supérieur au nombre de blocs, afin de voir s’il y a une utilité de threader la lecture du fichier. Pour cela, on fait la division entre le nombre de blocs dans un fichier, et le nombre de threads qu’on veut donner. Finalement, il devient possible de répartir le nombre de blocs par threads.\n","date":"2022-01-01T00:00:00Z","image":"https://example.org/post/blockchain/intro_hu4d4df4c838bdc9039d2a3e44ffd7c8b5_37001_120x120_fill_box_smart1_3.png","permalink":"https://example.org/post/blockchain/","title":"Exploration de la blockchain Bitcoin avec Rust - L3"},{"content":"Lien GitLab\nIntroduction Ce site web permettait l\u0026rsquo;organisation manuelle de compétitions Esport (coupe, championnat, etc).\nDescription Le but de ce projet était de faire un site de gestionnaire de tournoi sur le sujet de notre choix en utilisant du PHP et d\u0026rsquo;autres technologies. Nous avons choisi le thème de l\u0026rsquo;Esport.\nNavigation Connexion/Inscription Evidemment, pour accéder à toutes les fonctionnalités, il faut être un utlisateur connecté. Nous avons les pages de connexion et d\u0026rsquo;inscription.\nPage d\u0026rsquo;accueil Nous avons commencés à implémenter la page d’accueil. En tant que page principale, elle doit permettre d’accéder à diverses autres pages. Nous avons donc intégré une \u0026ldquo;Sidebar\u0026rdquo; et un \u0026ldquo;Header\u0026rdquo;, qui sont d’ailleurs affichés sur la plupart des autres pages principales. Le Header permet de se connecter, se déconnecter, ou de s’inscrire. La Sidebar quant à elle permet d’accéder aux paramètres de compte, aux tournois, aux équipes, ainsi qu’à l’actualité et à un calendrier.\nCréation de tournois/équipes Pour les pages de création d’équipes et de tournois, nous avons notamment utilisé des scripts en JavaScript, pour restreindre et adapter les différents paramètres d’équipes et de compétitions en fonction de l’Esport choisi et du type de tournois.\nCalendrier L’une des fonctionnalité particulière du site que nous avons développé est un calendrier permettant d’afficher chacune des compétitions, soit sous la forme d’un calendrier mensuel, hebdomadaire ou encore sous la forme d’une liste. Un code couleur permet de différencier les compétitions passées, en cours et a venir. Afin d’implémenter ce calendrier, il a été nécessaire d’utiliser un plugin JQuery : Full- Calendar. L’une des principales difficultés avec ce dernier a été la gestion du visuel, ainsi que la personnalisation du calendrier. La façon de procéder est assez différente et se fait majoritairement dans le script du calendrier, ou encore dans le fichier récupérant les données. En effet, afin de permettre au plugin d’afficher les informations présentes dans la base de donnée, il a fallut les récupérer et les renvoyer au script a l’aide de la fonction json_ encode sans laquelle il était impossible d’afficher les informations.\nActualité L\u0026rsquo;onglet actualité permet de consulter les tournois en cours. Nous avons toutes les informations nécessaire tel que la date de début, la durée, le gestionnaire ou autres.\nMise en place Outils Avant toute réalisation, nous avons fait le design pour avoir une conduite de projet esthétique précise. Mon rôle dans ce projet était essentiellement le BackEnd mais c\u0026rsquo;est transformé en FullStack en donnant un coup de main au FrontEnd. J\u0026rsquo;avais aussi géré le dépôt Git en créant tout d\u0026rsquo;abord un GitFlow classique.\nNous avons créer une base de données avec plusieurs entités (Joueur, Equipe, Utilisateur,\u0026hellip;). Ces entités permettait d\u0026rsquo;avoir des comportements différents. Pour commencer à développer au mieux notre site, nous avons installé sur nos ordinateurs respectif Wamp ou Xamp (selon le système d’exploitation de chacun). Le but étant d’éviter en premier lieu de se connecter à un serveur externe, et, ainsi nous permettre de bénéficier de serveurs nécessaires à la visualisation du site (Ex : Interpréteur de script)\nCe projet n\u0026rsquo;a pas utilisé de framework pour le front et tout a été fait par notre équipe.\nSchématisation de la base de données Récapitulatif ","date":"2021-01-01T00:00:00Z","image":"https://example.org/post/tournoi-sportif/accueil_hue95412a5f91bb216da81d3c7048233bc_135793_120x120_fill_q75_box_smart1.JPG","permalink":"https://example.org/post/tournoi-sportif/","title":"Projet L2 - Tournoi Sportif"}]