Fichier XML, données separée par des points virgules, comment les recuperer?

Bonjour,

Désolé si cette question à déjà été posé 50 fois, mes recherche n’ont rien donné.
Le régulateur de mon chauffe-eau solaire met à dispo les valeurs des différents capteurs et sorties dans un fichier XML, cependant celui-ci n’est pas structuré d’une façon conforme à la philosophie XML, du coup avec mon faible niveau je ne vois pas tout comment faire pour récupérer les valeurs qui m’intéresse

Concretement le fichier que me renvois le regulateur ressemble à ceci :

<response>
<rtcc>22:04:33 LU</rtcc>
<inAns>
0,8; 1,4; 39,5; 24,7; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0;
</inAns>
<survMm>0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;</survMm>
<cmdPos> 0; 0; 1; 8; 0; 0; 9; 4;</cmdPos>
<outStat>
0;100; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0;
</outStat>
<cptVals/>
</response>

Et par exemple, la valeur des 16 capteurs possibles, au lieux d’être dans 16 balises séparées, sont tous dans la même balise séparé par des point-virgule.

Si je fais une commande de script XML et que dans la requette je met « inAns » je récupère bien la valeur du premier capteur (ici 0.8)
Mais j’aimerais aussi pouvoir retrouver la valeur des capteurs suivant. Quelqu’un aurait un début de piste pour faire ça ?
Merci d’avance.

Tu peut nous montrer la partie de ton script qui récupère inAns
j’aimerai savoir si tu récupère un numérique ou un autre ?

Merci de te pencher sur mon problème. Je récupère un numérique mais c’est simplement avec un type XML du plug-in script… je n’entrave rien au PHP alors je serais bien incapable d’écrire la moindre ligne de code par moi même dans ce langage… même si j’imagine que pour mon problème se serait sans doute plus performant.

Bon tu récupéré une info en numérique mais elle est autre
en gros c’est une chaîne de caractères que tu va devoir décortiquer
met ton type en info autre et regarde si tu affiche bien:

0,8; 1,4; 39,5; 24,7; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0;

Une fois fait il faudra quand même passer par quelques ligne de décryptage dans un scenario.

Lors que tu en sera a ce point je t’aiderai si tu le désir.

Si je passe en type « autre » j’ai bien toute la ligne qui s’affiche.

En cherchant un peu sur le forum j’ai vu qu’il était possible de passer par un script en PHP qui vient mettre a jour les valeurs d’infos virtuels.
C’est ça qu’il me faudrait mais pour ça j’aurais besoin d’un exemple qui fait plus ou moins la même chose.

Je te prépare un exemple et je repasse ici !

Bon voilà la trame

le contenu du bloc code

$tags = $scenario->getTags(); // récuperation des tag
$marecup = $tags['#marecup#'];
$array = explode(';', $marecup);//decoposition des données en tableau
$x=1;
foreach ($array as $values)
{
	$tags["#val".$x."#"] = $values;// creation des tag
	$x	= $x + 1;
}
$scenario->setTags($tags); // affectation des tag val0 val1 val2 ... valx .....

reste à ta charge de mettre en déclancheur du scenario :
la commande info de ton plugin script

de remplacer 0,8; 1,4; 39,5; 24,7; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0;
par le nom de ta commande info

de remplacer et compléter sur les event TEST valeure 1,2,X par les nom de commandes d’un virtuel. (a faire si il n’existe pas)

en fin de désactiver l’action alerte qui n’est la que pour vérifier tes données.

Si c’est pas claire n’hésite pas.

Merci bien pour le bout de code, ça (plus d’autres exemples trouvé ici et là…) m’a permit de bricoler un script (oui à mon niveau c’est du bricolage…) qui permet de faire exactement ce que je voulais faire.

J’ai donc un virtuel avec 4 infos type numérique qui reprennent les 4 sondes de mon chauffe-eau solaire :
T_Capteur (température capteur solaire)
T_Extrerieur (température extérieur)
T_Ballon_Haut (température du haut du ballon de stockage)
T_Ballon_Bas (température du balle du ballon de stockage)
qui correspondent au 4 premières valeurs de mon ficher XML dans la balise « inAns »

Un script PHP du plug-in script se charge d’aller chercher le fichier XML et d’extraire les valeurs qui m’interesent pour mettre à jour les infos de mon virtuel

<?php
  require_once dirname(__FILE__) . '/../../../core/php/core.inc.php';
  //script pour récupérer les infos d'un Maxisun
  $url = 'http://192.168.0.9/status.xml';
	log::add('script','debug',$url );
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

	$datas = curl_exec($curl);
	curl_close($curl);
	
	$sondes = new SimpleXMLElement($datas);
$array = explode(';', $sondes->inAns);//decomposition des données en tableau
$x=1;
foreach ($array as $values)
{
	$capteur[$x] = $values;
	$x	= $x + 1;
}
$id = "#[Maison][CESI][T_Capteur]#";
if(isset($id))
	{
		cmd::byString($id)->event($capteur[1]);
	}
$id = "#[Maison][CESI][T_Exterieur]#";
if(isset($id))
	{
		cmd::byString($id)->event($capteur[2]);
	}
$id = "#[Maison][CESI][T_Ballon_Haut]#";
if(isset($id))
	{
		cmd::byString($id)->event($capteur[3]);
	}
$id = "#[Maison][CESI][T_Ballon_Bas]#";
if(isset($id))
	{
		cmd::byString($id)->event($capteur[4]);
	}
echo true;
?>

Alors oui, je sais c’est sâle, pas optimisé, ne gère pas les erreurs, etc… mais déjà ça fonctionne comme je le voulais alors pour moi c’est déjà formidable.
Si un pro du php passe par là et se sent de faire un code plus propre et plus robuste pour faire la même chose :hugs:

Alors par contre j’ai pas compris l’intérêt de passer par un scenario ?
C’est une recommandation de Jeedom de faire ça dans un scenario plutôt que dans un script ? ou c’est juste que pour un débutant comme moi c’est moins risqué de faire ça dans un scenario ?
Parce que dans cette approche, si je comprend bien, il faut un script type « XML » pour récupérer les valeurs, un scenario pour les mettre en forme, et un virtuel pour les afficher/exploiter…
A moins que le scenario puisse être autonome lui aussi pour récupérer le fichier XML ? dans ce cas ça peut éviter l’usage du plug-in script…
Bref, une petite explication sur la démarche m’aiderait sans doute à comprendre ce qu’il faut faire vs. ce qu’on peut faire.

Ben il y en a au moins une raison c’est de sortir du code par l’intermédiaire de tag les variables
qui sont de commandes infos tu peut ainsi modifier les noms des commandes sans avoir a modifier ton php.

mais a la final du php dans un script ou un bloc code fera la même chose …
le scenario t’apportera donc plus de souplesse dans l’utilisation des entrées et sorties !
les tag son la pour t’y aider.

Ton niveau est passé au niveau supérieur du coup il est pas si mal ton php :wink:

Salut,

$x	= $x + 1;

Plutôt :

$x++;

Facile celle là :wink:

Je ne l’avais pas fait comme ça pour une meilleur lecture mais c’est mieux …

et on peut aussi si il y a des calculs a faire utiliser :

floatval(str_replace (',','.',$values));

Ah mince j’avais pas vu que ça venait du bout de code que tu avais partagé :zipper_mouth_face:

Le scénario est très bien d’ailleurs en passant, plus flexible pour le même résultat.

Ça aurait été trop beau que ça fonctionne ainsi dans toutes les situations…
J’ai un problème avec les valeurs négatives :

- 1,9; 0,1; 37,4; 23,5; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0; 20,0;

Me renvoi « 0 » pour la première sonde et pas « -1.9 »
Sans doute un problème de type quelque part… mais qu’attends Jeedom pour afficher une valeur négative ?
merci d’avance

Tu a remplacer tes virgules par des points dans ton foreach ?
et transformer en nombre de type float !

$capteur[$x] = floatval(str_replace (',','.',$values));

Il faut aussi supprimer l’espace entre le - et le 1 pour que ça soit reconnu comme un nombre.

donc un

str_replace ('- ','-',$values)

Tous les espaces peuvent être supprimés:

str_replace (' ','',$values)

J’avais essayé le

$capteur[$x] = floatval(str_replace (',','.',$values));

Avant de poser la question et ça n’avait rien changé, mais effectivement ça doit être l’espace après le signe qui doit faire ch…
Merci pour la méthode car j’étais parti sur un truc beaucoup plus compliqué !

Voilà, ayant maintenant un script qui fonctionne même pour les valeurs négatives et ayant compris l’intérêt de passer un par un scénario, j’ai fait un essai et ça fonctionne impeccable. Même pas besoin de passer par un objet script pour récupérer le fichier XML; on peut le faire directement depuis le script du scénario, du coup ce n’est pas plus lourd que de passer par un script et c’est effectivement bien plus simple si ont dont modifier les affectations du virtuel. Petit raffinement supplémentaire, je suis passé par un tag pour passer l’adresse IP de l’appareil au script, ça n’apporte pas grand chose mais je voulais voir si ça fonctionne, et ça fonctionne !

$tags = $scenario->getTags(); // récuperation des tag
$ip = $tags['#ip_maxisun#'];

$url = 'http://'.$ip.'/status.xml';
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

	$datas = curl_exec($curl); //appel du fichier XML du Maxisun
	curl_close($curl);
	
	$sondes = new SimpleXMLElement($datas); //parser XML pour récuperation des valeurs des balises


$array = explode(';', $sondes->inAns);//decomposition des données des sondes (balise <inAns>) en tableau
$x=1;

foreach ($array as $values)
{
  	$values = str_replace(' ','',$values);
	$tags["#S".$x."#"] = floatval(str_replace (',','.',$values));// creation des tag
	$x++;
}
$scenario->setTags($tags); // affectation des tags

Sinon en passant par un objet script (si un jour ça peut aider qq1)

<?php
  require_once dirname(__FILE__) . '/../../../core/php/core.inc.php';
  //script pour récupérer les infos d'un Maxisun
  $url = 'http://192.168.0.9/status.xml';
	log::add('script','debug',$url );
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

	$datas = curl_exec($curl);
	curl_close($curl);
	
	$sondes = new SimpleXMLElement($datas);

$array = explode(';', $sondes->inAns);//decomposition des données en tableau
$x=1;
foreach ($array as $values)
{
  	$values = str_replace (' ','',$values);
	$capteur[$x] = floatval(str_replace (',','.',$values));// écriture des valeurs
	$x++;
}

$id = "#[Maison][CESI][T_Exterieur]#";
if(isset($id))
	{
		cmd::byString($id)->event($capteur[2]);
       
	}
$id = "#[Maison][CESI][T_Capteur]#";
if(isset($id))
	{
		cmd::byString($id)->event($capteur[1]);
       
	}
$id = "#[Maison][CESI][T_Ballon_Haut]#";
if(isset($id))
	{
		cmd::byString($id)->event($capteur[3]);
     
	}
$id = "#[Maison][CESI][T_Ballon_Bas]#";
if(isset($id))
	{
		cmd::byString($id)->event($capteur[4]);
       
	}

echo true;
?>

Merci pour le coup de main en tout cas.