Dans cet article, je voudrais expliquer en détail la structure de données utilisée pour gérer les appareils et les valeurs mesurées. Toutes les définitions de structure se trouvent dans le fichier de bibliothèque AT_Database.h.
Lorsqu'un appareil est enregistré, ses caractéristiques sont enregistrées dans la liste des appareils. La liste des appareils est un tableau de blocs de données avec la structure suivante:
typedef // définition de périphérique
struct ATDEVICE {
uint8_t activ = 0; // le périphérique défini ici existe
uint8_t service = 0; // 0 = Préparation ESP-Now si d'autres services plus tard
// être implémenté
uint8_t id [6] = {0,0,0,0}; // Adresse MAC de l'appareil
uint16_t bits de périphérique = 0; // Champ de bits avec informations sur l'appareil et transmission de données
Nom de chaîne = ""; // nom de l'appareil
Chaîne last = ""; // Horodatage du dernier transfert de données réussi
};
Le numéro de périphérique sert d'index dans ce tableau. La classe AT_Database définit une liste de périphériques pour 32 périphériques. Pour sauvegarder les données de l'appareil de façon permanente, elles sont enregistrées dans le système de fichiers SPIF dans le flash de l'ESP32.
Les fonctions suivantes de la classe sont utilisées pour travailler avec la liste des périphériques:
-
boolean readDevices (String fileName); Lit la liste des appareils à partir d'un fichier avec un nom fileName dans le SPIFFS. Renvoie false si une erreur s'est produite.
-
boolean writeDevices (String fileName); Écrit la liste des appareils dans un fichier avec un nom fileName dans le SPIFFS. Renvoie false si une erreur s'est produite.
- boolean clearDevices (String fileName); Supprime tous les appareils et enregistre le résultat sous fileName dans le SPIFFS. Renvoie false si une erreur s'est produite.
- int16_t findDevice (uint8_t id [6]); Cette fonction recherche un appareil avec celui spécifié dans la liste des appareils id (Adresse MAC). La fonction renvoie l'index, c'est-à-dire le numéro d'appareil de l'appareil. -1 signifie que l'appareil n'est pas dans la liste des appareils.
- String getDeviceId (uint8_t device); Renvoie l'ID de l'appareil avec le numéro de l'appareil appareil en arrière.
Si des valeurs mesurées pour un appareil enregistré arrivent, elles sont enregistrées dans le tableau des résultats. Le tableau de résultats se compose d'éléments de la structure suivante:
typedef // Structure de stockage des valeurs mesurées
struct ATCURVALUES {
uint8_t valide; // La structure contient une valeur mesurée valide
étape uint8_t; // est utilisé pour enregistrer les étapes de traitement
type uint8_t; // Le type de la mesure stockée
uint8_t unit; // L'unité de la mesure stockée
valeur uint8_t [4]; // quatre octets avec une valeur mesurée, entier 32 bits ou flottant
// selon le type. Le type booléen utilise uniquement le premier octet
};
La classe AT_Database réserve de l'espace mémoire pour une table de résultats avec 256 entrées (32 périphériques avec jusqu'à huit canaux chacun). L'index de ce tableau est calculé à partir du numéro de périphérique et du numéro de canal.
Index = numéro d'appareil * 32 + numéro de canal
Les fonctions suivantes de la classe AT_Database fonctionnent avec la table de résultats:
- void setResult (index uint8_t, données ATDATAPACKET); Cette fonction met à jour les données à la position d'index avec les valeurs de la structure de données. La structure ATDATAPACKET a été définie dans la bibliothèque ATMessageBuffer et est également utilisée pour la transmission de données.
- ATCURVALUES getResult (index uint16_t); Cette fonction renvoie la structure décrite ci-dessus pour le résultat à l'indice de position dans le tableau des résultats.
- void setStep (étape uint8_t, index uint16_t); L'étape de traitement du résultat à la position d'index dans la table de résultats est définie sur l'étape de valeur.
- String getValueString (index uint16_t, précision uint8_t, booléen useunit); Renvoie la valeur du résultat à la position d'index dans la table de résultats sous forme de chaîne. Le paramètre de précision spécifie le nombre de décimales pour les valeurs flottantes. Si le paramètre useunit est vrai, le nom de l'unité est ajouté à la chaîne.
- uint8_t getBooleanValue (index uint16_t); Renvoie le booléen du résultat à l'emplacement d'index sous la forme 0 ou 1. Utile uniquement pour le type booléen.
- boolean isValueOutput (index uint16_t); Renvoie vrai si le type du résultat à l'emplacement d'index est un type de sortie, c'est-à-dire contient des données qui sont envoyées du centre de contrôle à l'appareil. (par exemple interrupteur).
- boolean isSwitchOut (index uint16_t); Semblable à la fonction précédente, il ne renvoie true que s'il s'agit d'un commutateur:
- boolean isValueZero (index uint16_t); Renvoie vrai si la valeur du résultat à l'index est exactement 0.
- void toggleResult (index uint16_t); Bascule le résultat à l'index vo 0 sur 1 ou vice versa. Utile uniquement pour le type booléen.
- int8_t getResponse (périphérique int16_t, tampon uint8_t *, taille uint8_t *);Examine tous les résultats avec un type de sortie pour le périphérique et remplit une mémoire tampon avec un paquet de messages terminé, qui peut ensuite être transféré vers le périphérique. La taille du paramètre contient la taille maximale du tampon et après que la fonction retourne la taille du tampon réellement utilisée. La valeur de retour est le nombre de paquets de données trouvés ou -1 si la taille du tampon était trop petite.
Une autre structure3 de cette bibliothèque est utilisée pour contrôler l'affichage des résultats sur l'écran. Il y a une liste de pages. Chaque page contient 8 entrées de widget avec la structure suivante:
typedef // Définition d'un widget Diosplay
struct ATDISPLAYWIDGET {
uint16_t source; // Index du résultat attribué
état uint8_t; // Statut 0 = non utilisé, 1 = utilisé, 2 = espace réservé, 3 = masqué
uint8_t size; // taille du widget 0 = 240x30,1 = 240x60 gauche
// 2 = 120x60 à droite 3 = 120x60
type uint8_t; // type de widget, actuellement seulement 0 = simple
uint16_t bgcolor; // couleur de fond normale
uint16_t bgcolorOn; // couleur d'arrière-plan des boutons lorsqu'ils sont activés
uint16_t fontcolor; // couleur de police
image uint8_t; // index d'une image (pas encore utilisé)
précision uint8_t; // Nombre de décimales pour les valeurs mesurées
Étiquette de chaîne = ""; // lettrage
};
La classe AT_Database réserve l'espace pour 32 pages avec jusqu'à huit widgets chacune. Les fonctions suivantes fonctionnent avec ce tableau: #
- int16_t getFreeSlot (page uint8_t, taille uint8_t); Cette fonction renvoie l'index d'un widget sur la page avec la taille size, qui a toujours de l'espace ou -1 s'il n'y a pas d'espace sur la page.
- ATDISPLAYPAGE getPage (page uint8_t); Renvoie une liste de tous les widgets de la page.
La fonction
boolean registerDev (String deviceId, AT_MessageBuffer msg);
enregistre un périphérique avec l'ID deviceId s'il n'a pas encore été enregistré. Le paramètre msg contient une structure AT_Messagebuffer avec les dernières données reçues par ce périphérique. Pour chaque canal de cet appareil, une entrée est remplie dans le tableau des résultats et un espace est recherché pour un widget d'affichage sur la première page de la page possible. La taille du widget est définie sur 30 x 240 pixels et tous les paramètres sont remplis avec des valeurs par défaut. Cela garantit qu'un appareil nouvellement enregistré peut afficher tous ses canaux. Dans les versions ultérieures du centre de contrôle, ces paramètres d'affichage peuvent ensuite être modifiés individuellement à l'aide d'une configuration.
Je pense donc que cela suffit avec la théorie, mais il est important pour moi que vous compreniez également la structure du système afin de trouver plus facilement les erreurs et éventuellement de développer des extensions vous-même.