Création d'une bibliothèque uniformisée : M5lib

Conception et codage d'une bibliothèque commune à tous les M5Stack déployés dans le FabLab afin de rendre le déploiement, la maintenance et l'évolution plus simples et efficaces. Du fait sa relative complexité, il n'est pas garanti qu'elle fonctionne sur les M5Stack Core 1 (elle est optimisée pour les Core 2).

Présentation

Présentation Générale

La bibliothèque M5lib vise à uniformiser la gestion d’une flotte de M5 Core2 au sein d’un FabLab, facilitant le déploiement, l’évolution et la maintenance. Sa structure repose sur des concepts avancés de programmation orientée objet : factory design pattern et polymorphisme.  

Factory Design Pattern dans M5lib

Structure de Base

Objectif du Pattern

Le factory design pattern permet d’instancier dynamiquement le bon type d’objet dérivé (accueilservante, etc.) en fonction du contexte (par exemple, d’un paramètre de configuration ou d’une saisie utilisateur), tout en manipulant leur interface commune à travers des pointeurs ou références de type M5lib. Dans ce cas, cela veut dire que la déclaration du type d'objet dérivé dans le firmware du M5 permet automatiquement et de manière transparente d'adapter toutes les fonctions nécessaires au comportement de ce type de M5 (requêtes d'API, type d'emprunt...).

Avantages

Polymorphisme dans M5lib

Implémentation

Usage

Limites et inconvénients

Cette flexibilité du code ne vient pas sans compromis :

Structure

Dépendances

La librairie fait appel à de nombreuses librairies :

Structure de code

La bibliothèque M5lib est conçue pour uniformiser le comportement de plusieurs dispositifs M5Stack Core2 dans l'environnement du FabLab, chacun jouant un rôle défini (accueil, servante, machine, etc.). Elle repose sur une architecture orientée objet claire et modulaire, facilitant l’évolution, la maintenance et l'intégration au back-end (TimeTonic).

Structure de la Bibliothèque M5lib

1. Classe de base abstraite : M5lib

  • Représente l’interface commune à tous les types de M5.

  • Contient les méthodes de base utilisées par tous les modules : lecture de carte RFID (scancard), scan UHF (scanuhf), interaction utilisateur (showchoice, getuser), etc.

  • Déclare des méthodes virtuelles pures (polymorphisme) à implémenter dans les classes dérivées : uploadlog() et changestatus().

2. Classes dérivées spécialisées

Chaque type de M5 (défini dans M5type) possède une classe dédiée, dérivée de M5lib :

Classe Hérite de Spécificités
accueil M5lib Méthodes supplémentaires : entree(), sortie(), regcard().
Menu de motifs de visite.
servante M5lib Gère la traçabilité des servantes utilisées.
machine M5lib Pour l'enregistrement d’utilisation de machines.
ordinateur M5lib Associe cartes/scans à une session ordinateur précise.
materiel M5lib Permet le prêt/retour d’outils ou matériels via borrow().

Chaque classe surcharge au moins :

  • uploadlog: envoie les journaux d’usage à l’API TimeTonic avec une structure propre (identifiants de champs différents selon le type).

  • changestatus: placeholder actuel (pour la plupart renvoie 200) servant potentiellement à signaler un changement d’état matériel (ex : verrouillage machine, etc.).

3. Composants globaux manipulés

  • Périphériques :

    • MFRC522 mfrc522 : pour la lecture RFID classique (Mifare).

    • Unit_UHF_RFID uhf : pour les lectures UHF/EPC.

  • API & Données :

    • HTTPClient http : communication HTTP avec TimeTonic.

    • JsonDocument doc : stockage de la réponse JSON.

  • Accès réseau :

    • Configuration du Wi-Fi intégrée dans setupstd().

Résumé Visuel Simplifié

        +---------------------------+
        |           M5lib          |  <--- classe abstraite
        +---------------------------+
    /        |        |       |         \
   /         |        |       |          \
accueil   servante  machine ordinateur  materiel  <--- classes concrètes

Toutes implémentent :
    + uploadlog()
    + changestatus()

Chaque classe possède des méthodes propres, par exemple :
accueil fournit aussi :
    + entree()
    + sortie()
    + regcard()

Une évolution fluide : il suffit d’ajouter une nouvelle classe dérivée et d’enrichir la factory pour intégrer un nouveau comportement ou un nouveau rôle matériel dans le système du FabLab.

Structure détaillées

1. Classe Abstraite : M5lib

Classe de base commune à tous les types de M5. Elle définit les fonctionnalités fondamentales.

Fonctions membres

Fonction Rôle
setupstd() Effectue l'initialisation matérielle commune : écran, Wi-Fi, RFID, UHF. Attention : la fonction est lboquante tant que le M5 n'est pas connecté au réseau prédéfinit.
reducejson(String json) Réduit et structure le JSON de réponse de l’API TimeTonic pour simplifier l’accès aux champs utiles. Ne garde que le contenu de "fields" (endroit où est stocké entre autres les données demandées) et "rowInfos" (qui contient notamment le rowId des informations demandées)
scancard() Scanne une carte RFID classique, retourne l’UID du tag sous forme de String. Contient une UI intégrée. Attention : la fonction est bloquante tant qu'elle n'a pas lu une carte.
scanuhf(String* urfid) Scanne les tags RFID UHF via le module UHF externe, remplit le tableau passé en paramètre avec les EPC lues (max 200 EPC, ce qui est le max supporté par le module RFID UHF). Fonction actuellement inutilisée dans le code.
showchoice(String choices[]) Affiche sur l’écran un menu de sélection contenant les String du tableau passé en paramètre  : l’utilisateur peut naviguer puis valider un choix(jusqu’à 9 options), qui est retourné sous forme de String.
virtual int uploadlog(String card, String action, String other) = 0 Méthode virtuelle pure pour uploader un log dans la table correspondante au type de M5. Prend en paramètre une carte lue, l'action effectuée par l'utilisateur et un agument optionnel (au choix, le motif de la visite, l'ordinateur ou l'outil emprunté).
virtual int changestatus() = 0 Méthode virtuelle pure pour changer le statut d'emprunt/de présence (obsolète pour le moment car remplacé par automatisation TimeTonic).
getuser(String* user) Lance un scan RFID (avec scancard() ), puis interroge l’API TimeTonic pour récupérer le nom, prénom, et rowId de l'utilisateur scanné. Peuple ensuite le tableau passé en paramètre : [nom, prénom, tag RFID, rowId].
borrow() Gère tout le cycle d’emprunt et retour d’un matériel/machine/ordinateur : identification (avec un appel getuser() ), log (avec un appel uploadlog() ), et contrôle utilisateur (gestion par l'utilisateur de la durée de son emprunt, avec à nouveau un scan de carte et un upload de log à la fin de l'emprunt. Boucles if/else à chaque étape du cycle pour gérer chaque type d'erreur (API, utilisateur inconnu, etc...).
Attributs

2. Classes Dérivées

Chaque classe dérivée apporte des fonctionnalités propres à chaque typologie de M5 dans le FabLab.

a. Classe : accueil

Ajoute des méthodes spécifiques à la gestion d’accueil.

Fonction Rôle
int uploadlog(...) override Upload des logs d’accueil à l’API avec les bons id (table, champs...).
int changestatus() override Change le statut d’accueil (placeholder : actuellement valeur fixe pour compatibilité).
void entree() Gère la procédure d’entrée : identification (avec getuser), choix du motif de visite (avec showchoice), upload du log d’arrivée (avec uploadlog)
void sortie() Gère la sortie d’un utilisateur (avec getuser) et log cet évènement (avec uploadlog).
void regcard() Enregistre une nouvelle carte RFID (avec un scancard puis une requete d'API spécifique) pour un utilisateur après inscription sur Timetonic (liaison rangée TimeTonic <-> badge RFID). La requête d'API récupère la dernière rangée créée avec une vue filtrée (vue chronologique dans TimeTonic), il faut donc faire l'association de carte immédiatement après l'inscription.
Attributs spécifiques

String motifs[9]: Liste des motifs de visite disponibles à la sélection (préremplie pour plus de simplicité).String name : nom du M5, permet de définir l'action d'accueil effectuée : entrée, sortie ou 1ère inscription.

b. Classe : servante

Pour la traçabilité de l’usage des servantes.

Fonction Rôle
int uploadlog(...) override Upload des logs liés à l’utilisation d’une servante (carte, action, ""). L'argument other ne sert pas pour les servantes.
int changestatus() override Change le statut de la servante (obsolète, pour compatibilité).
Attributs spécifiques

c. Classe : machine

Gère l’utilisation des machines/outils fixes.

Fonction Rôle
int uploadlog(...) override Upload logs liés à l’utilisation d’une machine (carte utilisateur, action).
Attributs spécifiques

d. Classe : ordinateur

Gère le suivi de l'emprunt des ordinateurs portables.

Fonction Rôle
int uploadlog(...) override Upload logs spécifiques à l’usage d’un ordinateur (par exemple : session ouverte/fermée).
Attributs spécifiques

e. Classe : materiel

Gère les cycles d’emprunt et de retour d’outillage ou matériel divers.

Fonction Rôle
int uploadlog(...) override Upload logs liés à l’utilisation (emprunt/retour) de matériels.
Attributs spécifiques

3. Utilisation de méthodes virtual / override

Les méthodes uploadlog et changestatus sont définies comme virtual dans la base, et nécessaires à la personnalisation du comportement selon chaque situation FabLab : chaque classe dérivée implémente les appels API avec les bons identifiants et formats de données.

Avec cette structure, chaque fonction de M5lib remplit un rôle précis dans la gestion, la traçabilité, l’ajout de dispositifs et l’intégration back-end dans l’écosystème du FabLab.

UI

Afin de simplifier, d'uniformiser et de clarifier l'affichage de texte et de l'interface dans le M5, Une classe UI a été créé. Elle permet de simplifier l'implémentation de l'interface utilisateur dans toutes les fonctions interagissant avec celui-ci.

Structure

Méthodes

showchoice : UI de sélection de choix multiples (anciennement dans M5lib), retourne la String du choix sélectionné
titre : affichage de texte en gros centré (taille 4, 13 charactères maximum avant dépassement de l'écran)
soustitre : affichage de texte en moyen centré (taille 3, 17 charactères maximum)
corps : affichage de texte en  petit centré (taille 2, 26 charactères maximum)
feedback : vibration pour retour utilisateur, à appeler à chaque fois qu'un bouton est pressé