Parser xml pour motherboard monitor

Description

cette source réalise un graphique à partir du log XML de MotherBoard Monitor 5.
Les infos les plus récentes sont à gauche, directement visibles.
J'en ai eu l'idée grâce à une source écrite en VB, mais qui ne me satisfaisait
pas du tout (Firefox n'aimant pas tellement le VB).
Cette source m'a permis d'apprendre le XML et la création d'images.
Ainsi, le code présenté doit encore pouvoir être optimisé ;)

Source / Exemple :


// barre.php
<?php
// script de création de la barre pour l'histogramme.
// la hauteur "h" et les couleurs "r" "v" "b" sont passées en paramètre via GET
// la largeur est fixée à 10 pixels, taille minimum pour que la température s'affiche avec les 2 chiffres

header ("Content-type: image/png");
// la hauteur est multipliée par 2, car trop petite sinon
$im = imagecreatetruecolor (10, 2*$_GET['h']) or die ("Impossible de créer un flux d'image GD");

$color = imagecolorallocate($im, $_GET['r'],$_GET['v'],$_GET['b']);

imagefill($im,0,0,$color);

// affichage de la température (hauteur) en bas de la barre
$text_color = imagecolorallocate ($im, 255, 255, 255);
imagestring ($im, 1, 0, 2*$_GET['h']-10,  $_GET['h'], $text_color);

imagepng ($im);
imagedestroy ($im);
?>

// le parser XML
<!--

script réalisé par oXid_FoX
http://oxid-fox.site.voila.fr

-->
<html>
     <head>
          <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
          <meta http-equiv="expires" content="0">
          <meta http-equiv="cache-control" content="no-cache">
          <meta http-equiv="pragma" content="no-cache">
          <title>
               Températures
          </title>
          <style type="text/css">
          <!--
          /*on règle la bordure de l'image ici*/
          img {
               margin-left: 1px;
          }
          -->
          </style>

     </head>
     <body>
     <div>
<?php

//******************************************************************************
// PARTIE A PERSONNALISER

// emplacement du fichier XML à lire.
// ce fichier peut être sur un réseau local, sur le même PC...
$fichier_source = "http://oxid/files/mbmtemp14/MBM5_period_Log.xml";

// NOM des sondes de température présentes dans le log.
// le nom de la variable globale est à respecter !
// la prochaine sonde doit se nommer "nom_temp4", "nom_temp5" ...
$GLOBALS["nom_temp1"] = "T_Boitier";
$GLOBALS["nom_temp2"] = "T_Diode";
$GLOBALS["nom_temp3"] = "T_Socket";

// COULEURS des graphs de températures.
// une sonde de température aura un graphique individuel.
// valeurs en RVB, ne changer que les chiffres.
// si il y a plus de sondes, la couleur de la prochaine sera $couleur[4]=...
$couleur[1] = "&amp;r=51&amp;v=51&amp;b=255";
$couleur[2] = "&amp;r=255&amp;v=51&amp;b=51";
$couleur[3] = "&amp;r=0&amp;v=225&amp;b=0";

// NOM des ventilateurs présents dans le log.
// même remarque que pour les températures.
$GLOBALS["nom_fan1"] = "F_CPU";
$GLOBALS["nom_fan2"] = "F_Case";
$GLOBALS["nom_fan3"] = "F_Alim";

// fréquence de rafraichissement du log (paramétré dans MBM) en minutes.
$freq = 5;

// FIN DE LA PERSONNALISATION
//******************************************************************************

// création du tableaux des températures
$nb_temp=1;
while (isset($GLOBALS["nom_temp$nb_temp"])){
     $GLOBALS["tab_temp$nb_temp"] = array();
     $nb_temp++;
}
define("NB_TEMP",$nb_temp-1);

// création du tableau des vitesses de rotation de ventilateurs
$nb_fan=1;
while (isset($GLOBALS["nom_fan$nb_fan"])){
     $GLOBALS["tab_fan$nb_fan"] = array();
     $nb_fan++;
}
define("NB_FAN",$nb_fan-1);

// création des tableaux des dates et heures
$GLOBALS["tab_date"] = array();
$GLOBALS["tab_time"] = array();

// fonction qui renvoie les chiffres contenus dans une chaine
// ex: strtonum (46dfg) renverra 46.
function strtonum ($str){
     $i = 0 ;
     $ret = "";

     while ($i != strlen($str)){
          if ($str[$i] >= "0" && $str[$i] <= "9")
               $ret = $ret.$str[$i];

          $i++;
     }
     return $ret;
}

// DEBUT TRAITEMENT XML

// créée un analyseur XML (utilise une instance de parseur XML)
$xml_parseur = xml_parser_create ();

// la fonction chargée de gérer l'événement "balise ouvrante"
// le premier argument est l'identifiant de l'instance du parseur,
// le second est le nom de la balise rencontrée (pour une balise <Debut> sa valeur sera "Debut")
// le troisième est un tableau associatif contenant tous les noms des attributs de cet élément et leur valeur.
// --
// fonction très importante puisque toutes les infos sont en attribut.
// c'est cette fonction qui va remplir les tableaux avec les valeurs adéquates.
function ouverture ($parser, $name, $attrs){
     if ($name == "Log"){
          if (sizeof($attrs)) {
               // date et heure
               $GLOBALS["tab_date"][] = $attrs["Date"];
               $GLOBALS["tab_time"][] = $attrs["Time"];

               // températures
               $i=1;
               while ($i <= NB_TEMP){
                    $GLOBALS["tab_temp$i"][] = strtonum($attrs[$GLOBALS["nom_temp$i"]]);
                    $i++;
               }

               // ventilateurs
               $i=1;
               while ($i <= NB_FAN){
                    $GLOBALS["tab_fan$i"][] = strtonum($attrs[$GLOBALS["nom_fan$i"]]);
                    $i++;
               }
          }
     }
}

// la fermeture d'une balise XML
// Le prototype est le même que pour le gestionnaire d'événement associé aux balises ouvrantes
// --
// fonction inutile ici.
function fermeture ($parser, $name){
//     if ($name == "MBM_INTERVAL"){
//          include("tps_generation_fin.php");
//     }
     return TRUE;
}

// lorsque du texte est trouvé hors des balises
// le deuxième argument est le texte retourné par le gestionnaire d'événement
// --
// fonction inutile ici.
function texte ($parser, $data_text){
     return $data_text;
}

// une fonction par défaut
// --
// fonction inutile ici.
function defaut (){
     return TRUE;
}

// définit les fonctions associées à l'ouverture et à la fermeture d'une balise XML
xml_set_element_handler($xml_parseur, "ouverture", "fermeture");

// définit la fonction associée à la rencontre de texte en dehors ou entre les balises XML
xml_set_character_data_handler($xml_parseur, "texte");

// permet d'associer une fonction par défaut aux événements non traités
xml_set_default_handler($xml_parseur,"defaut");

// permet de définir des options de parsage.
// ici, on garde la sensibilité à la casse.
xml_parser_set_option($xml_parseur, XML_OPTION_CASE_FOLDING, 0);

// Pour parser un fichier XML, il suffit de l'ouvrir en lecture, puis de faire appel à la fonction xml_parse() :
$fp = fopen($fichier_source, "r") or die("Fichier introuvable. L'analyse est suspendue.");

// lecture du fichier XML
while ($fdata = fread($fp, 2048)){
     // si le document XML n'est pas bien formé la fonction xml_parse() renvoie la valeur false
	xml_parse($xml_parseur, $fdata, feof($fp)) or die(
		sprintf("Erreur XML : %s à la ligne %d\n",
		// permet d'afficher l'erreur qui a été générée
		xml_error_string(xml_get_error_code($xml_parseur)),
		// et le numéro de la ligne du fichier XML où elle se trouve
		xml_get_current_line_number($xml_parseur))
		);
}

// libération de la ressource associée au parser
xml_parser_free($xml_parseur);

// FIN TRAITEMENT XML

// infos sur la dernière MAJ du log.
echo "Dernière mise à jour le ".$GLOBALS["tab_date"][0]." à ".$GLOBALS["tab_time"][0]." - actualisé toutes les $freq min.";

// affiche le nombre d'entrées dans le log
echo "<p>".count($GLOBALS["tab_date"])." entrées dans le log.</p>\n";

// affichage des graphs des températures
echo "<nobr>";
$num=1;
while ($num <= NB_TEMP){
     echo "\n<div class=\"oXcadre\"><p>\n";
     $i=0;

     // création du graph
     while ($i < count($GLOBALS["tab_temp$num"])){
          // création de la barre du graphique
          echo "<img src=\"barre.php?h="
               // hauteur de la barre
               .$GLOBALS["tab_temp$num"][$i]
               // couleur de cette barre
               ."$couleur[$num]\""
               // largeur définie en HTML
               ." width=\"10\""
               // création de l'infobulle de cette barre : date, heure ...
               ." title=\"".$GLOBALS["tab_date"][$i]." à ".$GLOBALS["tab_time"][$i];
               // on vérifie d'abord qu'il existe des ventilos
               if (NB_FAN > 0) {
                    echo " - Ventilateurs :";
                    $j=1;
                    while ($j <= NB_FAN){
                         // ... et vitesse de rotation des ventilateurs (en RPM)
                         // substr(,2) pour supprimer "F_" (marque du capteur)
                         echo " ".substr($GLOBALS["nom_fan$j"],2).":".$GLOBALS["tab_fan$j"][$i]." RPM";
                         $j++;
                    }
               }
               // infobulle testée et fonctionnelle sous IE > 6 et FF > 1
               echo "\" />";

          // affichage d'un espace pour séparer les jours
          // le isset() est là pour éviter l'erreur de NOTICE lors du dépassage des bornes du tableau
          if (isset($GLOBALS["tab_date"][$i+1]))
               if ($GLOBALS["tab_date"][$i] <> $GLOBALS["tab_date"][$i+1])
                    echo "&nbsp;";

          $i++;
     }

     // afichage du nom de la sonde de température
     // substr(,2) pour supprimer "T_" (marque du capteur de température)
     echo "<br />".substr($GLOBALS["nom_temp$num"],2)."\n</p></div>";
     $num++;
}
echo "\n</nobr>\n";

?>
</div>

     </body>
</html>

Conclusion :


REMARQUE
la lib GD2 doit être activée dans le php.ini !
elle se trouve dans la section "Dynamic Extensions" (à peu près au milieu du fichier)
et la ligne "extension=php_gd2.dll" doit être présente sans les guillements, et sans
point virgule devant.

Tout le nécessaire est fourni dans le zip:
barre.php => le code des barres d'histogramme.
mbm.php => le parseur XML, en gros, la page qui fait tout!
MBM5_period_Log.xml => un extrait de mon log
mbm_xml_php.png => la capture d'écran réalisée avec le log fourni
infos.txt => ce fichier

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

Du même auteur (oXid_FoX)