Les objectifs fondamentaux de cette SAÉ sont :

  • apprendre à créer une application avec une structuration "professionnelle", permettant d'implémenter les fonctionnalités de façon parallèle et incrémentale, mais également de pouvoir ajouter des fonctionnalités facilement, sans remettre le reste de l'application en question.
  • apprendre à partir d'un code existant pour créer une application.

 

C'est pourquoi un certain nombre de contraintes et libertés existent quant à l'implémentation de votre sujet, listées ci-dessous.


Structuration du code

Toutes les parties de votre application doivent avoir une structure similaire à celle utilisée dans le prototype. Cela signifie entre autre que :

  • le serveur API node doit être modulaire, donc avec des sous-répertoires différenciés pour les modèles, les contrôleurs, les routes, les "communs", etc. bref, comme dans le prototype.
  • le serveur Java de centralisation de donnée doit être basé sur une hiérarchie de classes similaire à celle du prototype, notamment tout ce qui concerne :
    • la création d'un thread par client, qui se partagent tous un objet permettant d'accéder à la BdD
    • l'accès à la Bdd, soit directement, soit via l'API node, grâce à des classes implémentant une interface répertoriant les méthodes d'accès à la BdD.

En revanche, le nombre, nom et contenu des fichiers va dépendre fortement de votre sujet et ne doit pas reprendre tel quel ceux du prototype. Par exemple, les schémas et modèle mongoose de l'API sont juste un exemple adapté au prototype mais il va falloir créer vos propres schéma et modèle. De même pour les routes et les contrôleurs, ou encore les méthodes d'accès à la BdD déclarée dans l'interface DataDriver du serveur Java.

 

Base de données

Les données sont forcément stockées dans une (éventuellement plusieurs) bases de type mongodb. Dans l'idéal, il devrait y avoir deux serveurs mongod, un pour le développement, un pour la production. Si vous arrivez à mettre en place une telle configuration tant mieux. Sinon, pour simplifier, utilisez simplement des bases différentes au sein du même serveur afin de différencier les bases pour le développement, de celle de la production.

Comme les service doivent être dockerisés, il est utile d'utiliser dès le début du développement une version docker de mongodb. Cependant, comme la version dockerisée écoute sur le même port que la version basique (à savoir le port 27017), le passage de l'une à l'autre est transparent pour les autres parties de l'application.

La base de données de développement doit pouvoir être initialisée avec des données "de test". Cela peut se faire via des scripts, ou simplement via l'API lorsqu'elle se lance (cf. db.init.js dans le prototype)

 

API Node

Les routes de l'API doivent être basées sur un protocole REST, qui soit cohérent avec les "normes habituelles", avec des échanges de données au format JSON :

  • récupérer des informations : requête GET avec les paramètres donnés dans la partie query et/ou dans la route elle-même,
  • créer/enregistrer des informations : requête POST, les données sont dans le corps de la requête,
  • mettre à jour une information (par ex, un document dans une collection) : requête PUT, les données étant dans le corps de la requête,
  • mettre à jour une partie d'information (par ex, certains champs d'un document dans une collection) : requête PATCH, les données étant dans le corps de la requête,
  • supprimer une/des informations : requête DELETE avec quelles infos donné dans la partie query et/ou dans la route elle-même et./ou dans le corpts de la requête.

Les réponses de l'API doivent suivre le principe utilisé dans le prototype, à savoir renvoyer des objets avec un format unique du type { error : err_num, status: http_status, data: answer }. A noter que le prototype contient un système de gestion des erreurs relativement poussé et donc un peu fastidieux à mettre en place. Vous n'êtes pas strictement obligés de réutiliser ce système mais cela reste une bonne idée, notamment car cela facilite le déboguage du front-end.

L'API utilise forcément mongoose comme couche d'interface entre l'API et la base mongo. Cela nécessite donc de créer des schéma et des modèles mongoose en fonction de vos besoins applicatifs. A noter que le front-end va nécessiter une gestion des utilisateurs et de leur droits d'accès à certaines fonctionnalités. Il font donc créer un (ou des) schémas et modèles pour gérer les utilisateurs et leurs droits.

Les routes d'accès utilisées par le serveur de centralisation des données n'ont pas besoin d'être protégées par un système d'authentification (même si ce n'est pas sécuritaire du tout). En revanche, cela doit être le cas pour les routes "privilégiées" qui vont être utilisées par le front-end vuejs. Selon votre sujet, il peut bien entendu également exister des routes "publiques", sans authentification, qui seront utilisées par le front-end.

L'API doit pouvoir être lancée en mode développement ou bien en mode production, notamment pour accéder à des BdD différentes. Les principes de mise en place de cette différenciation sont laissés libres mais il est fortement conseillé de suivre des exemples glanés sur le net. Ces 2 versions doivent être dockerisées.

 

Serveur Java de centralisation des données

Le serveur doit être basé uniquement sur TCP pour recevoir des requêtes de la part des µC ou des serveurs d'analyse. Il n'est donc pas possible d'utiliser une surcouche de protocole (par ex, HTTP) pour recevoir des requêtes.

Le mode de communication avec les clients est de base en texte mais il peut également se faire en binaire si besoin. Par exemple, si un µC doit envoyer une image, celle-ci est en fait un simple tableau d'octets. Il n'y a donc aucune raison de convertir ce tableau en un format texte. Il est envoyé directement sous forme binaire. Pour ce genre de situation, il suffit de créer un protocole adapté, qui commence par une requête textuelle qui indique qu'un certain volume de données binaire va être ensuite envoyé. Le problème est de savoir gérer un envoi et une réception binaire correctement, mais vos référents sont là pour vous guider.

Le protocole de communication est forcément basé sur des requêtes, qui doivent avoir une façon cohérente de passer leurs paramètres au serveur, mais aussi dans la façon de répondre. Le prototype se base sur des retours de type "OK" ou bien "ERR ...", mais vous êtes libres d'utiliser un autre format pour les réponses (par exemple du JSON, XML, ...). De plus, le protocole doit s'efforcer de prendre en compte le plus grand nombre de situations d'erreur dans les requêtes, afin de faciliter le déboguage du code des µC.

Dans le prototype, l'accès à la BdD via l'API node est fait grâce aux classes basiques fournies par l'API. Vous êtes libre d'utiliser une autre solution, faisant par exemple appel à des packages de classes tierces. Cependant, si vous faîtes ce choix, ne prenez pas des packages issus d'obscurs projet, en version 0.0.2. Choisissez uniquement des packages pérennes, avec un bon suivi et une bonne documentation. En effet, une entreprise ne peut pas se permettre d'utiliser des choses instables ou sans avenir. De plus, vous devrez argumenter sur votre choix lors des évaluations.

Pour l'accès à la BdD de façon directe, il est obligatoire d'utiliser les .jar officiels fournis par mongodb, dont une version est fournie avec le prototype. Cependant, si vous travaillez dans un environnement "maven compliant" (genre Idea), il est aussi possible d'écrire un pom.xml pour aller chercher directement les .jar dans les dépôts et les relier à votre projet. C'est un peu plus simple que l'installation manuelle, mais cela implique de passer par maven. Enfin, vous devez utiliser le principe des POJO prou faire vos transactions avec la BdD.

Toutes les routes possibles de l'API node concernant l'enregistrement de données dans la BdD doivent être accessibles par le serveur de centralisation. Ce n'est pas le cas pour leurs équivalents en accès direct. Il est demandé d'en implémenter au moins un tiers, mais si vous en faîtes plus, cela constituera un bonus dans l'évaluation.

 

Micro-contrôleurs

Les µC doivent forcément être des esp32 et/ou esp8266.

Ils doivent tous obtenir une adresse IP aurpès d'un même point d'accès Wifi (=AP).

Conseils

Vous pouvez créer un AP simplement avec :

  • votre téléphone portable avec un partage de connexion.
  • votre box adsl/fibre, qui généralement fait office de point d'accès wifi. 

Dans ces deux cas, il faut absolument que la machine sur laquelle tourne le serveur de centralisation de données soit connectée au même AP, pour être dans le même réseau que les µCs. La problématique est que les adresses IP vont être attribuées par le téléphone/box via DHCP et ne sont donc pas forcément fixes. Vu que les µC doivent se connecter en TCP à l'adresse du serveur, il faut donc connaître cette adresse (par ex, grâce à ifconfig) pour l'utiliser dans les sketch arduino. Si l'adresse change au cours du temps, alors les sketch doivent être modifiés. Cependant, si l'AP est votre box, il est normalement possible de la configurer pour donner toujours la même adresse à votre ordinateur serveur. Quand l'AP est un mobile, c'est à priori impossible.

Il est également possible de configurer votre ordinateur portable comme AP, mais cela marche plus ou moins bien.

  • votre ordinateur portable sur lequel tourne le serveur de centralisation. Sous Linux deban/ubuntu, il suffit d'utiliser le Gestionnaire Réseau :
    • cliquer sur le + vert pour créer une nouvelle connexion, puis choisir Wifi et cliquer sur Créer
    • dans l'onglet Wifi, donner un ssid, choisir comme mode Hotspot, sélectionner éventuellement le périphérique représentant la carte wifi
    • dans l'onglet Sécurité Wifi, choisir WPA/WPA2/..., et donner un mot de passe de connexion.
    • cliquer sur enregistrer, puis rebooter la machine.
    • après redémarrage, la liste des réseau disponibles devrait contenir votre hotspot.
 

 

Une fois une adresse IP obtenue, ils se connectent et communiquent uniquement avec le serveur de centralisation de données, principalement en mode texte, mais, selon les sujets, également avec des suites d'octets.

Les sketchs du prototype sont juste un exemple, dédié au prototype. Pour votre sujet, le contenu des sketch pourra être radicalement différent. Par exemple, il n'y aura peut être pas besoin d'avoir de l'auto-enregistrement, de la mise en sommeil profond, de stockage des données non envoyées sur une micro-sd, etc. En revanche, il y aura forcément les parties de connexion à l'AP et au serveur de centralisation, qui seront similaires à celles du prototype.

De plus, afin de respecter l'objectif n°1 de la SAÉ, il est demandé que le code soit bien structuré et conçu, comme dans le prototype. Entre autres :

  • les pins utilisées sont définies par des #define,
  • si certains paramètres de l'application peuvent être modifiables mais nécessaire lors du boot, il faut les enregistrer en flash, plutôt qu'en dur dans le code,
  • un découpage en fonctions de taille raisonnable,
  • l'utilisation d'interruption dès que c'est possible, plutôt que de vérifier l'état d'une pin régulièrement,
  • toujours vérifier l'état de la connexion avant un envoi.
  • etc.

 

Mobile et serveur d'analyse multimédia

La seule contrainte est qu'après analyse de données reçue via un dispositif mobile (téléphone, tablette, ...), le serveur d'analyse doit envoyer ses résultats au serveur de centralisation de données afin de les stocker. Il ne doit pas demander directement à la BdD ou bien à l'API node. Pour le reste, vous êtes libre de faire une application native ou hybride pour mobile, de choisir le langage de programmation du serveur ainsi que le protocole utilisé pour communiquer avec le mobile.

En revanche, vous devez vous efforcer de suivre l'objectif n°1 de la SAÉ : structurer vos codes de façon modulaire, avec une architecture logicielle qui permette de les maintenir et les étendre facilement.

 

Front-end vuejs

Le front-end doit être créé en vuejs. Vous êtes libre d'utiliser la v2 ou v3 de vuejs, avec vue-cli ou bien vite comme gestionnaire de projet. En revanche, vous devez au minimum utiliser les plugin vue-router et vuex (ou pinia si vous êtes en vuejs v3).

Pour le côté graphique, il n'est pas impératif d'avoir un aspect travaillé, tel qu'on peut l'obtenir avec vuetify. Vous pouvez donc utiliser les balises html de base ou tout autre bibliothèque de composants graphiques. En revanche, il est important de concevoir votre front-end pour que son utilisation et navigation soient ergonomiques. Et comme pour les autres parties, la structuration du code doit permettre de maintenir et étendre facilement l'application. C'est pourquoi, il est très fortement conseillé de reprendre la structuration vue en seconde année, avec notamment la création de différents services d'accès aux données, une centralisation des données utiles à plusieurs composants dans le store, des actions du store faisant appels aux services, etc.

Le front-end doit impérativement proposer un mécanisme d'authentification, qui permet aux utilisateurs d'accéder (ou pas) aux fonctionnalités du front selon leurs droits. L'authentification doit se faire auprès de l'API. Elle doit au minimum prendre la forme d'un id de session renvoyé au front et stocké en cookie ou en mémoire. Cet id doit être renvoyé à chaque requête mais il doit avoir une durée de vie limitée. Vous pouvez également utiliser les principes vus en 2ème année, à base de jwt, ou encore un autre système. A vous de décider.

La front-end doit proposer plusieurs composants affichant des statistiques et graphiques, calculés à partir de données issues de la BdD mongo et récupérées via l'API. Le contenu et la forme visuelle de ces statistiques/graphiques est laissée libre. Cela veut donc dire que vous pouvez utiliser n'importe quel bibliothèque JS pour les produire. Pour information, la bibliothèque la plus complète existant à l'heure actuelle est D3js. Malheureusement, elle n'est pas spécialement simple à utiliser car en gros, elle impose de construire des svg grâce à du code JS. Cela dit, savoir manier D3js est sans doute un atout sur un CV :-)

En environnement de développement, l'accès au front-end peut se faire directement en utilisant les scripts fournis par vue-cli (c.a.d. npm run serve) ou vite. En revanche, la version de production doit être servie par un vrai serveur http. Pour cela, vous avez globalement deux choix : installer un serveur type apache ou utiliser l'API node (cf. documentation express.static()). Comme le front-end est spécialement fait pour utiliser l'API, la deuxième solution est plus logique. Si vous partez sur un serveur apache séparé, il faudra que lui aussi soit dockerisé.