Station météo: affichage

Station météo: affichage

La semaine dernière, on a réalisé une station météo solaire qui poste ses données sur xyvely. C'est pratique, mais cela serait quand même plus simple de pouvoir consulter ces données sans avoir à allumer un ordinateur. Cette semaine, on vous propose d'afficher ces données directement sur un écran Yoctopuce. Cela demande un peu de programmation, mais rien d'insurmontable. Si vous voulez, on peut programmer ça ensemble...



Architecture

L'architecture est identique à celle utilisée pour le lecteur de flux RSS. On va donc utiliser un écran Yoctopuce que l'on va raccorder à un YoctoHub-Ethernet. Le YoctoHub-Ethernet et le YoctoHub-Wireless vont être configurés pour se connecter à un serveur PHP qui fera tourner un script assurant le transfert d'informations.

Le schéma complet de l'installation station météo + écran
Le schéma complet de l'installation station météo + écran



La programmation

On exploite ici la possibilité qu'ont les hubs Yoctopuce de se connecter à un serveur pour y lancer l'exécution d'un script PHP. Cette technique, appelée HTTP callback, qui permet de traverser sans encombre les filtres NAT des routeurs ADSL. Du point de vue du programmeur, tout est transparent: le code est identique à du code qui ferait tourner des modules connectés en local.

On aimerait afficher les données du Yocto-Meteo de la station météo, mais quitte à utiliser un écran graphique, autant en profiter pour tracer un graphique. Ce qui pose la question de l'historique des données. On pourrait utiliser le data logger du Yocto-Meteo, mais y accéder à travers une connexion HTTP callback risque d'être très lent. On va donc procéder de manière classique avec une base de données mySQL. Vous avez donc besoin d'un serveur PHP et d'une base mySQL, c'est en général le minimum syndical qu'offre chaque hébergeur de site web. Vous pouvez aussi utiliser un framework PHP/mysql comme easyPHP ou Mamp sur une de vos machines.

La base de données

On crée simplement une table qui permet de stocker l'historique des données de la station météo et on la nomme weather. Cette table a la structure suivante:

ColonneTypeUtilisation
timestampentierdate/heure de la mesure
temperaturedoublevaleurs de température
humiditydoublevaleurs d'humidité
pressuredoublevaleurs de pression
feedentiergestion de plusieurs flux parallèles


On a juste rajouté une petite subtilité: un numéro de feed qui permettra d'utiliser plusieurs exemplaires de l'installation en parallèle.

Initialisation

L'initialisation du script consiste à inclure les librairies Yoctopuce nécessaires, à créer la connexion à la base, et à initialiser l'API Yoctopuce.

// Yoctopuce includes
include("yocto_api.php");
include("yocto_temperature.php");
include("yocto_humidity.php");
include("yocto_pressure.php");
include("yocto_display.php");
include("yocto_wakeupmonitor.php");
include("yocto_network.php");

// database connection, replace with your own credentials
$conn = mysql_connect(DB_SERVER,DB_USER,DB_PASSWORD);
$res = mysql_select_db(DB_NAME);

// API init, note de the "callback" parameter for HTTP callback  mode
if (yRegisterHub("callback",$errmsg)!=YAPI_SUCCESS) die($errmsg);




Pour rester compact, on a décidé d'utiliser le même script pour l'envoi des données par la station météo et la récupération des données pour l'écran. On se base sur la présence du capteur de température et de l'écran pour savoir quoi faire.

Envoi des données

On détecte qui, de l'écran ou la station météo, a appelé le script en se basant sur la présence de la fonction yTemperature, il suffit alors de récupérer les valeurs des différents capteurs et de les stocker dans la base de données.

$tempSensor=YFindTemperature("METEO.temperature");
$humSenor=YFindHumidity("METEO.humidity");
$pressSensor=YFindPressure("METEO.pressure");
$monitor=YFirstWakeUpMonitor();

if ($tempSensor->isOnline())
 {
   $temp = $tempSensor->get_currentValue();
   $hum  = $humSenor->get_currentValue();
   $pre  = $pressSensor->get_currentValue();
   $timestamp = time();
    mysql_query("insert into weather "
               ."(timestamp,temperature,humidity,pressure,feed) "
               ."values ($timestamp,$temp,$hum,$pre,$feed)");
   ...



Une fois les valeurs stockées dans la base, on peut demander au YoctoHub-Wireless de la station météo de se rendormir jusqu'à la prochaine mesure pour économiser de l'énergie, cela évite d'avoir à attendre qu'il s'éteigne automatiquement.

   if (!is_null($monitor)) $monitor->sleep(1);



Affichage sur l'écran

La partie affichage est basée sur la présence ou non d'un écran. Pour que l'affichage soit propre, on va utiliser une technique de double buffering: on va afficher une couche, et dessiner dans une autre invisible. Et une fois le dessin terminé, on permute le contenu des couches. Ici on va travailler avec les couches 3 et 4.

if ($display->isOnline())
 {
   // fetch data from database, group  by 15 min clusters
   $result = mysql_query("select * from weather where feed=$feed and timestamp>".($timestamp-60*15*128)." order by timestamp");
   if (!$result ) die(mysql_error());

   //..
   //code to group data by 15 minutes clusters
   //and compute max/min values
   //..

   $width=  $display->get_displayWidth();
   $height= $display->get_displayHeight();

   // we will use double buffering
   $layer4 = $display->get_displayLayer(4);
   $layer4->reset();
   $layer4->hide();
   ..



On affiche les valeurs de pression et de température. Un point important: le capteur de pression du Yocto-Meteo donne une pression absolue, alors qu'on est plutôt intéressés par la pression barométrique qui, elle, est normalisée par rapport à la pression standard au niveau de la mer, il faut donc réaliser une correction qui dépend de l'altitude de la station météo ainsi que de la température ambiante.

    ..
   // altitude correction
   $Z = 500;  // weather station altitude, in meters
   if (isset($_GET['alt']))  $Z = intval($_GET['alt']);
   // display humidity and pressure in the corners
   $tempK = $lastTemp + 273.15; // temperature in deg K
   $barometricPress=round($lastPress*pow(($tempK+0.0065*$Z)/$tempK,5.2561));

   // display humitity and pressure in the corners
   $layer4->selectFont('Small.yfm');
   $layer4->drawText(0,0,Y_ALIGN_TOP_LEFT,'P:'.$barometricPress);
   $layer4->drawText(0,$height-1,Y_ALIGN_BOTTOM_LEFT,$lastHum.'%');
   ..




On trace le graphique de la température en utilisant de simples lineTo

   // draws the graph
   $i=0;
   if ($history[$i]["count"]>0)
   $layer4->moveTo( $width-15 ,
                    round(($height/2)-($history[$i]["temp"]-$middle)*2));
   for ($i=1;$i<sizeof($history);$i++)
     if ($history[$i]["count"]>0)
       $layer4->lineTo($width -$i-15,
                       round($height/2-($history[$i]["temp"]-$middle)*2));



Finalement, on affiche la température en gros au milieu de l'écran. Comme la température a toutes les chances de se superposer au graphique, on crée une bordure noire autour des chiffres en dessinant d'abord la température en noir, mais légèrement décalée et enfin la température en "blanc" au centre.

   ...
   $layer4->selectColorPen(0);
   $layer4->drawText($width/2-1,$height/2,Y_ALIGN_CENTER, $lastTemp);
   $layer4->drawText($width/2+1,$height/2,Y_ALIGN_CENTER, $lastTemp);
   $layer4->drawText($width/2,$height/2+1,Y_ALIGN_CENTER, $lastTemp);
   $layer4->drawText($width/2,$height/2-1,Y_ALIGN_CENTER, $lastTemp);
   $layer4->selectColorPen(0xffff);
   $layer4->drawText($width/2,$height/2,Y_ALIGN_CENTER, $lastTemp);
   ...



Et enfin on permute les couches, ainsi la mise à jour de l'écran donnera l'impression d'être instantanée.

 $display->swapLayerContent(3,4);



Et voilà, c'est fini. En réalité, le code est légèrement plus long: on a volontairement sauté quelques parties pas forcément très intéressantes dans le cadre de cet article. Mais vous pouvez télécharger le code complet ici.

Il ne reste plus qu'à configurer le hub de la station météo et le hub de l'écran pour qu'ils appellent ce script à intervalle réguler.

Les deux hubs sont configurés pour appeler notre script
Les deux hubs sont configurés pour appeler notre script



Il ne reste plus qu'à laisser la station météo et l'écran vivre leur vie, et au bout de quelques temps, on voit le graphe se construire.

Une capture d'écran
Une capture d'écran



Voici le résultat sur une journée en time lapse, à raison d'une photo par minute.

  



Vous remarquerez que rien ne vous empêche de placer la station météo à un coin de la planète et l'écran à un autre, la seule contrainte est d'avoir une connectivité réseau. Vous pouvez aussi faire le contraire et brancher un Yocto-Meteo et un écran sur le même YoctoHub-Ethernet.

Commenter aucun commentaire Retour au blog












Yoctopuce, get your stuff connected.