Il a quelque temps, nous avions réalisé une station météo en PHP basée sur le Yocto-Humidity. Nous vous proposons aujourd'hui une nouvelle version en C# qui améliore le concept en exploitant l'enregistreur de données intégré du Yocto-Meteo, qui est une version améliorée du produit utilisé pour l'article précédent.
Le principal problème de notre précédent exemple était que si le PC était éteint ou en cours de redémarrage, les données météorologiques n'étaient plus enregistrées. Dans un monde où les Windows updates sont monnaie courante, cela peut devenir pénible. L'idée est donc de déléguer l'enregistrement des données au module lui-même, plutôt que de le faire avec le PC qui affiche les données. Ainsi, même si au milieu de la nuit votre PC décide de redémarrer pour mettre à jour son OS et que la mise à jour plante (vécu!), le module continuera à enregistrer les données. Comme cela, quand vous aurez enfin pu faire redémarrer correctement votre OS 4 heures et 10 patchs plus tard, vous aurez quand même les données météo de ces 4 heures... C'est le premier avantage du data logger.
Le deuxième avantage est que, s'il n'est pas nécessaire d'avoir le graphique en permanence affiché, vous pouvez stopper votre application et laisser le module stocker les données tout seul sans utiliser de temps CPU sur votre machine.
Cela fait déjà un certain nombre d'articles que nous expliquons en détails nos programmes. Nous allons pour une fois nous concentrer sur l'utilisation du data logger.
La première étape est de démarrer l’enregistrement automatique des données. Nous supposerons que la variable datalogger est déjà initialisée correctement (en utilisant YDataLogger.FirstDataLogger() ou YDataLogger.FirstDataLogger()) et référence un objet YDataLogger.
Il faut tout d’abord configurer le module pour qu'il démarre l'enregistrement automatiquement dès qu'il est mis sous tension, même si le PC ne communique pas avec lui. Comme il s'agit d'un paramètre persistant, ceci se fait en 2 étapes:
dataLogger.module().saveToFlash();
On va ensuite mettre à jour l'heure du module: le module n'étant pas alimenté par une pile, il faut remettre l'heure à jour après chaque power off.
TimeSpan span = (now - new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime());
dataLogger.set_timeUTC((int)span.TotalSeconds);
Pour finir, l'appel set_recording(YDataLogger.RECORDING_ON) lance l'enregistrement de données.
A partir de ce moment, et tant que le module est alimenté, la mémoire flash du module va se remplir avec les nouvelles données.
Il faut maintenant récupérer les données du module. Il faut tout d’abord charger l'index de la mémoire flash:
{
YDataStream stream = dataStreams[i];
int progress = (i - startfrom) * 100 / (dataStreams.Count - startfrom);
backgroundWorker1.ReportProgress(progress, "Loading " + dataLogger.module());
// drop data that do not have a timestamp
long unixtime = stream.get_startTimeUTC();
if (unixtime == 0)
continue;
long utc = stream.get_startTimeUTC();
DateTime tstart = new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(utc);
Stopwatch sw = new Stopwatch();
DateTime tend = tstart.AddSeconds(stream.get_rowCount() * stream.get_dataSamplesInterval());
List<String> names = stream.get_columnNames();
int increment = 1;
if (stream.get_dataSamplesInterval() == 1)
{
// we take only one mesure per minute
increment = 60;
}
for (int row = 0; row < stream.get_rowCount(); row += increment)
{
long nbsec = unixtime + row * stream.get_dataSamplesInterval();
DateTime t = new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(nbsec);
TimeSpan delta = DateTime.Now - t;
if (delta.TotalDays > 2)
{
continue;
}
DataRow rowData = table.NewRow();
rowData["Time"] = t;
for (int c = 0; c < stream.get_columnCount(); c++)
{
switch (names[c])
{
case "temperature":
rowData["Temperature"] = stream.get_data(row, c);
break;
case "pressure":
rowData["Pressure"] = stream.get_data(row, c);
break;
case "humidity":
rowData["Humidity"] = stream.get_data(row, c);
break;
default:
continue;
}
}
table.Rows.Add(rowData);
}
}
Enfin, le plus gros du code consiste à dessiner le graphique sur l'interface en utilisant les données que l'on a chargées.
Et voilà un screeshot de l'application
Note: Cet exemple sera disponible dans la prochain version de la libraire