POST HTTP vers virtuel Jeedom

Bonjour,

J’utilise le plugin Fronius pour recouper la production de mes panneaux solaire, mais le plugin ne récupère pas toute les information et les données ne s’actualisent que toute les minutes.

J’ai commencé a faire un script pour récupérer les infos manquante via JSON mais j’ai le même problème au niveau de l’actualisation des données.

L’onduleur permet de faire un PUSH (toute les 10sec) des valeurs JSON via un POST HTTP ou en déposant un fichier sur un FTP.
Ça serait une bonne solution pour envoyer de façon plus régulières certaines infos comme la puissance des panneaux qui floctuent pas mal en une minute.
Mais comment récupérer les infos du POST HTTP et les injecter dans virtuel ? J’ai chercher un peux partout mais je trouve aucune piste.

Voila a quoi ressemble la requette POST HTTP

{
   "Body" : {
      "Data" : {
         "DAY_ENERGY" : {
            "Unit" : "Wh",
            "Value" : 10496
         },
         "DeviceStatus" : {
            "ErrorCode" : 0,
            "LEDColor" : 2,
            "LEDState" : 0,
            "MgmtTimerRemainingTime" : -1,
            "StateToReset" : false,
            "StatusCode" : 7
         },
         "FAC" : {
            "Unit" : "Hz",
            "Value" : 49.939999999999998
         },
         "IAC" : {
            "Unit" : "A",
            "Value" : 0.11
         },
         "IDC" : {
            "Unit" : "A",
            "Value" : 0.52000000000000002
         },
         "PAC" : {
            "Unit" : "W",
            "Value" : 8
         },
         "TOTAL_ENERGY" : {
            "Unit" : "Wh",
            "Value" : 25018
         },
         "UAC" : {
            "Unit" : "V",
            "Value" : 234.19999999999999
         },
         "UDC" : {
            "Unit" : "V",
            "Value" : 67.200000000000003
         },
         "YEAR_ENERGY" : {
            "Unit" : "Wh",
            "Value" : 25018.5
         }
      }
   },
   "Head" : {
      "RequestArguments" : {
         "DataCollection" : "CommonInverterData",
         "DeviceClass" : "Inverter",
         "DeviceId" : "1",
         "Scope" : "Device"
      },
      "Status" : {
         "Code" : 0,
         "Reason" : "",
         "UserMessage" : ""
      },
      "Timestamp" : "2020-03-23T18:53:43+01:00"
   }
}

Merci pour votre aide

Je pense qu’il falloir passer par un script php. Je viens de faire un essai. Avec le plugin JeeXplorer, j’ai créé un fichier json.php à la racine (répertoire html). Là j’y ai collé ce script :

<?php

$json = '{
   "Body" : {
      "Data" : {
         "DAY_ENERGY" : {
            "Unit" : "Wh",
            "Value" : 10498
         },
         "DeviceStatus" : {
            "ErrorCode" : 0,
            "LEDColor" : 2,
            "LEDState" : 0,
            "MgmtTimerRemainingTime" : -1,
            "StateToReset" : false,
            "StatusCode" : 7
         },
         "FAC" : {
            "Unit" : "Hz",
            "Value" : 49.939999999999998
         },
         "IAC" : {
            "Unit" : "A",
            "Value" : 0.11
         },
         "IDC" : {
            "Unit" : "A",
            "Value" : 0.52000000000000002
         },
         "PAC" : {
            "Unit" : "W",
            "Value" : 8
         },
         "TOTAL_ENERGY" : {
            "Unit" : "Wh",
            "Value" : 25018
         },
         "UAC" : {
            "Unit" : "V",
            "Value" : 234.19999999999999
         },
         "UDC" : {
            "Unit" : "V",
            "Value" : 67.200000000000003
         },
         "YEAR_ENERGY" : {
            "Unit" : "Wh",
            "Value" : 25018.5
         }
      }
   },
   "Head" : {
      "RequestArguments" : {
         "DataCollection" : "CommonInverterData",
         "DeviceClass" : "Inverter",
         "DeviceId" : "1",
         "Scope" : "Device"
      },
      "Status" : {
         "Code" : 0,
         "Reason" : "",
         "UserMessage" : ""
      },
      "Timestamp" : "2020-03-23T18:53:43+01:00"
   }
}';


// Converts it into a PHP object
$data = json_decode($json);

// Show data
echo $data->Body->Data->DAY_ENERGY->Value; 
echo "\n"; 

file_get_contents("http://localhost/core/api/jeeApi.php?apikey=CLE_API&type=virtual&id=49551&value=".$data->Body->Data->DAY_ENERGY->Value);


?>

Il faut bien sûr changer la clé API et l’ID du virtuel.

En ouvrant http://IP_JEEDOM/json.php, la valeur de DAY_ENERGY doit apparaître et ça met à jour le virtuel.

Après, je ne peux pas tester plus loin. En lisant cet article : PHP: Get POST JSON, il faudrait juste mettre à jour une ligne ce qui donnerait quelque chose comme ça :

<?php

# Get JSON as a string
$json = file_get_contents('php://input');

// Converts it into a PHP object
$data = json_decode($json);

file_get_contents("http://localhost/core/api/jeeApi.php?apikey=CLE_API&type=virtual&id=49551&value=".$data->Body->Data->DAY_ENERGY->Value);

?>

Il suffira ensuite de multiplier la dernière ligne autant que fois que nécessaire.

Juste faire attention à la charge tout de même, parce que 10s c’est quand même hyper fréquent.

Bonjour @seb821,

J’ai pas mal avancé également de mon coté, j’ai fait le choix d’utiliser le plugin « http remote event » qui me permet d’avoir des équipements ce mettant a jour via requette post http.

Il me restait donc a gérer la partie script pour mettre a jour les valeurs de mes virtuels. Voila mon code, qui dois surement pouvoir être optimisé mais qui a le mérite de bien fonctionner et de ne pas alourdir mon serveur.

//On enregistre le declencheur dans une variable
$trigger=$scenario->getRealTrigger();
$cmdtrigger=cmd::byString($trigger)->getName();
//$scennario->setLog("lancement du scenario par : $cmdtrigger"); //debug


if ($sc->getTrigger('#[Energie][PostHTTP|Fronius-CurrentDataPowerflow][CurrentDataPowerflow]#')) {
	$cmd = cmd::byString("#[Energie][PostHTTP|Fronius-CurrentDataPowerflow][CurrentDataPowerflow]#");
	$CurrentDataPowerflow = $cmd->execCmd();

	// On le décode
	$CurrentDataPowerflow = utf8_encode($CurrentDataPowerflow);
//  	$scenario->setLog('Data :'.$CurrentDataPowerflow); //debug
	$results = json_decode($CurrentDataPowerflow, true);
  
	if(is_array($results)){
		// on créé les variable
		$E_Day = $results['Body']['Site']['E_Day'];
		$E_Total = $results['Body']['Site']['E_Total'];
		$E_Year = $results['Body']['Site']['E_Year'];
		$Mode = $results['Body']['Site']['Mode'];
		$P_Akku = $results['Body']['Site']['P_Akku'];
		$P_Grid = $results['Body']['Site']['P_Grid'];
		$P_Load = $results['Body']['Site']['P_Load'];
		$P_PV = $results['Body']['Site']['P_PV'];
		$rel_Autonomy = $results['Body']['Site']['rel_Autonomy'];
		$rel_SelfConsumption = $results['Body']['Site']['rel_SelfConsumption'];

//		$scenario->setLog('E_Day: '.$E_Day .', E_Total: '.$E_Total .', E_Year: '.$E_Year .', Mode: '.$Mode .', P_Akku: '.$P_Akku .', P_Grid: '.$P_Grid .', P_Load: '.$P_Load .', P_PV: '.$P_PV .', rel_Autonomy: '.$rel_Autonomy .', rel_SelfConsumption: '.$rel_SelfConsumption); //debug
    
		// on met a jour les info du virtuel
		cmd::byString('#[Energie][P|Fronius-CurrentDataPowerflow][E_Day]#')->event(($E_Day));
    	cmd::byString('#[Energie][P|Fronius-CurrentDataPowerflow][E_Total]#')->event(($E_Total));
    	cmd::byString('#[Energie][P|Fronius-CurrentDataPowerflow][E_Year]#')->event(($E_Year));
 		cmd::byString('#[Energie][P|Fronius-CurrentDataPowerflow][Meter_Location]#')->event(($Meter_Location));
		cmd::byString('#[Energie][P|Fronius-CurrentDataPowerflow][Mode]#')->event(($Mode));
    	cmd::byString('#[Energie][P|Fronius-CurrentDataPowerflow][P_Akku]#')->event(($P_Akku));
    	cmd::byString('#[Energie][P|Fronius-CurrentDataPowerflow][P_Grid]#')->event(($P_Grid));
 		cmd::byString('#[Energie][P|Fronius-CurrentDataPowerflow][P_Load]#')->event(($P_Load));
    	cmd::byString('#[Energie][P|Fronius-CurrentDataPowerflow][P_PV]#')->event(($P_PV));
    	cmd::byString('#[Energie][P|Fronius-CurrentDataPowerflow][rel_Autonomy]#')->event(($rel_Autonomy));
 		cmd::byString('#[Energie][P|Fronius-CurrentDataPowerflow][rel_SelfConsumption]#')->event(($rel_SelfConsumption));
    }


} else if ($sc->getTrigger('#[Energie][PostHTTP|Fronius-CurrentDataMeter][CurrentDataMeter]#')) {
  	$cmd = cmd::byString("#[Energie][PostHTTP|Fronius-CurrentDataMeter][CurrentDataMeter]#");
	$CurrentDataMeter = $cmd->execCmd();

  // On le décode
	$CurrentDataMeter = utf8_encode($CurrentDataMeter);
//	$scenario->setLog('CurrentDataMeter :'.$CurrentDataMeter); //debug
	$results = json_decode($CurrentDataMeter, true);
  
	if(is_array($results)){
		// on crré les variable
		$Current_AC_Phase_1 = $results['Body']['0']['Current_AC_Phase_1'];
		$Current_AC_Sum = $results['Body']['0']['Current_AC_Sum'];
		$EnergyReactive_VArAC_Phase_1_Consumed = $results['Body']['0']['EnergyReactive_VArAC_Phase_1_Consumed'];
		$EnergyReactive_VArAC_Phase_1_Produced = $results['Body']['0']['EnergyReactive_VArAC_Phase_1_Produced'];
		$EnergyReactive_VArAC_Sum_Consumed = $results['Body']['0']['EnergyReactive_VArAC_Sum_Consumed'];
		$EnergyReactive_VArAC_Sum_Produced = $results['Body']['0']['EnergyReactive_VArAC_Sum_Produced'];
		$EnergyReal_WAC_Minus_Absolute = $results['Body']['0']['EnergyReal_WAC_Minus_Absolute'];
		$EnergyReal_WAC_Phase_1_Consumed = $results['Body']['0']['EnergyReal_WAC_Phase_1_Consumed'];
		$EnergyReal_WAC_Phase_1_Produced = $results['Body']['0']['EnergyReal_WAC_Phase_1_Produced'];
		$EnergyReal_WAC_Plus_Absolute = $results['Body']['0']['EnergyReal_WAC_Plus_Absolute'];
		$EnergyReal_WAC_Sum_Consumed = $results['Body']['0']['EnergyReal_WAC_Sum_Consumed'];
		$EnergyReal_WAC_Sum_Produced = $results['Body']['0']['EnergyReal_WAC_Sum_Produced'];
		$Frequency_Phase_Average = $results['Body']['0']['Frequency_Phase_Average'];
		$Meter_Location_Current = $results['Body']['0']['Meter_Location_Current'];
		$PowerApparent_S_Phase_1 = $results['Body']['0']['PowerApparent_S_Phase_1'];
		$PowerApparent_S_Sum = $results['Body']['0']['PowerApparent_S_Sum'];
		$PowerFactor_Phase_1 = $results['Body']['0']['PowerFactor_Phase_1'];
		$PowerFactor_Sum = $results['Body']['0']['PowerFactor_Sum'];
		$PowerReactive_Q_Phase_1 = $results['Body']['0']['PowerReactive_Q_Phase_1'];
		$PowerReactive_Q_Sum = $results['Body']['0']['PowerReactive_Q_Sum'];
		$PowerReal_P_Phase_1 = $results['Body']['0']['PowerReal_P_Phase_1'];
		$PowerReal_P_Sum = $results['Body']['0']['PowerReal_P_Sum'];
		$TimeStamp = $results['Body']['0']['TimeStamp'];
      
//		$scenario->setLog('Current_AC_Phase_1: '.$Current_AC_Phase_1 .', Current_AC_Sum: '.$Current_AC_Sum .', EnergyReactive_VArAC_Phase_1_Consumed: '.$EnergyReactive_VArAC_Phase_1_Consumed .', EnergyReactive_VArAC_Phase_1_Produced: '.$EnergyReactive_VArAC_Phase_1_Produced .', EnergyReactive_VArAC_Sum_Consumed: '.$EnergyReactive_VArAC_Sum_Consumed .', EnergyReactive_VArAC_Sum_Produced: '.$EnergyReactive_VArAC_Sum_Produced .', EnergyReal_WAC_Minus_Absolute: '.$EnergyReal_WAC_Minus_Absolute .', EnergyReal_WAC_Phase_1_Consumed: '.$EnergyReal_WAC_Phase_1_Consumed .', EnergyReal_WAC_Phase_1_Produced: '.$EnergyReal_WAC_Phase_1_Produced .', EnergyReal_WAC_Plus_Absolute: '.$EnergyReal_WAC_Plus_Absolute .', EnergyReal_WAC_Sum_Consumed: '.$EnergyReal_WAC_Sum_Consumed .', EnergyReal_WAC_Sum_Produced: '.$EnergyReal_WAC_Sum_Produced .', Frequency_Phase_Average: '.$Frequency_Phase_Average .', Meter_Location_Current: '.$Meter_Location_Current .', PowerApparent_S_Phase_1: '.$PowerApparent_S_Phase_1 .', PowerFactor_Sum: '.$PowerFactor_Sum .', PowerFactor_Phase_1: '.$PowerFactor_Phase_1 .', PowerFactor_Sum: '.$PowerFactor_Sum .', PowerReactive_Q_Phase_1: '.$PowerReactive_Q_Phase_1 .', PowerFactor_Sum: '.$PowerFactor_Sum .', PowerReactive_Q_Phase_1: '.$PowerReactive_Q_Phase_1 .', PowerReactive_Q_Sum: '.$PowerReactive_Q_Sum .', PowerReal_P_Phase_1: '.$PowerReal_P_Phase_1 .', PowerReal_P_Sum: '.$PowerReal_P_Sum .', TimeStamp: '.$TimeStamp); //debug
      
      
		// on met a jour les info du virtuel
		cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][Current_AC_Phase_1]#')->event(($Current_AC_Phase_1));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][Current_AC_Sum]#')->event(($Current_AC_Sum));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][EnergyReactive_VArAC_Phase_1_Consumed]#')->event(($EnergyReactive_VArAC_Phase_1_Consumed));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][EnergyReactive_VArAC_Phase_1_Produced]#')->event(($EnergyReactive_VArAC_Phase_1_Produced));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][EnergyReactive_VArAC_Sum_Consumed]#')->event(($EnergyReactive_VArAC_Sum_Consumed));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][EnergyReactive_VArAC_Sum_Produced]#')->event(($EnergyReactive_VArAC_Sum_Produced));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][EnergyReal_WAC_Minus_Absolute]#')->event(($EnergyReal_WAC_Minus_Absolute));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][EnergyReal_WAC_Phase_1_Consumed]#')->event(($EnergyReal_WAC_Phase_1_Consumed));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][EnergyReal_WAC_Phase_1_Produced]#')->event(($EnergyReal_WAC_Phase_1_Produced));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][EnergyReal_WAC_Plus_Absolute]#')->event(($PWLedstate));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][EnergyReal_WAC_Sum_Consumed]#')->event(($EnergyReal_WAC_Sum_Consumed));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][EnergyReal_WAC_Sum_Produced]#')->event(($EnergyReal_WAC_Sum_Produced));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][Frequency_Phase_Average]#')->event(($Frequency_Phase_Average));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][Meter_Location_Current]#')->event(($Meter_Location_Current));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][PowerApparent_S_Phase_1]#')->event(($PowerApparent_S_Phase_1));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][PowerApparent_S_Sum]#')->event(($PowerApparent_S_Sum));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][PowerFactor_Phase_1]#')->event(($PowerFactor_Phase_1));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][PowerFactor_Sum]#')->event(($PowerFactor_Sum));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][PowerReactive_Q_Phase_1]#')->event(($PowerReactive_Q_Phase_1));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][PowerReactive_Q_Sum]#')->event(($PowerReactive_Q_Sum));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][PowerReal_P_Phase_1]#')->event(($PowerReal_P_Phase_1));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][PowerReal_P_Sum]#')->event(($PowerReal_P_Sum));
      	cmd::byString('#[Energie][P|Fronius-CurrentDataMeter][TimeStamp]#')->event(($TimeStamp));
    }

} else if ($sc->getTrigger('#[Energie][PostHTTP|Fronius-CurrentDataInverter][CurrentDataInverter]#')) {
	$cmd = cmd::byString("#[Energie][PostHTTP|Fronius-CurrentDataInverter][CurrentDataInverter]#");
	$CurrentDataInverter = $cmd->execCmd();

	// On le décode
	$CurrentDataInverter = utf8_encode($CurrentDataInverter);
//  	$scenario->setLog('PostData :'.$CurrentDataInverter); //debug
	$results = json_decode($CurrentDataInverter, true);
  
	if(is_array($results)){
		// on crré les variable
		$DAY_ENERGY = $results['Body']['DAY_ENERGY']['Values']['1'];
		$PAC = $results['Body']['PAC']['Values']['1'];
		$TOTAL_ENERGY = $results['Body']['TOTAL_ENERGY']['Values']['1'];
		$YEAR_ENERGY = $results['Body']['YEAR_ENERGY']['Values']['1'];

//		$scenario->setLog('DAY_ENERGY: '.$DAY_ENERGY .', PAC: '.$PAC .', TOTAL_ENERGY: '.$TOTAL_ENERGY .', YEAR_ENERGY: '.$YEAR_ENERGY); //debug
    
		// on met a jour les info du virtuel
		cmd::byString('#[Energie][P|Fronius-CurrentDataInverter][DAY_ENERGY]#')->event(($DAY_ENERGY));
    	cmd::byString('#[Energie][P|Fronius-CurrentDataInverter][PAC]#')->event(($PAC));
    	cmd::byString('#[Energie][P|Fronius-CurrentDataInverter][TOTAL_ENERGY]#')->event(($TOTAL_ENERGY));
 		cmd::byString('#[Energie][P|Fronius-CurrentDataInverter][YEAR_ENERGY]#')->event(($YEAR_ENERGY));
    }
 
} else if ($sc->getTrigger('user') || $sc->getTrigger('schedule')) {
  
}

Concernant la charge, je tourne sur une VM bien dimensionné, donc peux de crainte de ce coté la pour le moment mais je vais surveiller.

Merci

Je ne connaissais pas ce plugin. Bonne solution en effet avec le scénario derrière. Plus simple à maintenir.

Bonjour @Alpine_Z et @seb821,

je voudrais aussi utiliser le plugin « http remote event » pour recevoir et traiter une requête POST, je n’ai pas encore acheté le plugin mais en lisant sa documentation il semble qu’il ne traite que les requetes GET.

Pourriez-vous détailler comment l’utiliser avec une requete POST ? Je ne vois pas bien la liaison avec le script.

Merci d’avance,
AgP

Bonsoir @agp.com

Je te confirme que j’utilise bien le plugin http remote event pour traiter les requêtes POST de mon onduleur. Je retraite les données via un script mais ce n’est pas obligatoire.

Voila le screenshot de la config http post de mon onduleur

Le virtuel sert, dans mon cas, seulement a stoker les donnée le temps que le scénario les découpes pour mettre a jour de nouveau virtuel.

Merci pour ta réponse @Alpine_Z,

Pourrais-tu me montrer la fin de l’URL complete (aprés l’apikey) ?

Mon soucis est surtout pour comprendre au niveau du plugin « Http remote event », comment tu récupères les infos du « body » de la requête POST ?

Dans la doc du plugin il montre ca :

Avec donc les données en get uniquement (dans l’URL) et non en post (dans le body).

Il y a d’autres options du plugin pour gérer le post qu’il n’a pas documenté dans la doc ?

Merci !

@agp.com

Voila l’url que j’utilise depuis mon onduleur : /core/api/jeeApi.php?apikey=xxxxxxxxxxx&type=httpRemoteEvent&eqId=337

Et la capture de l’équipement

:

Ok merci !

Donc si je comprend bien, tu utilises « Http remove event » pour détecter la réception de ton push, et ton script permet ensuite de lire le corps de ta requête HTTP Post qui elle contient les infos qui t’intéressent, c’est bien ça ?

Exactement

1 « J'aime »

Bonjour,

Recherchant un moyen de récupérer des informations d’une requête POST je suis tombé sur ce sujet.

Je ne comprends pas bien comment le plugin http remote event vous permet de récupérer le corps de la requête http POST. Le principe de ce plugin est normalement d’affecter des valeurs extraites de l’URL, y a-t-il une astuce qui permet d’affecter à une commande le corps de la requête ? Qui serait ensuite traité par un scénario pour en extraire les données ?

Je vous remercie pour votre aide.

Bonjour,

HTTP remote event affecte justement toute les infos de la requête post a un évent Jeedom. Mon script lit l’évent et le découpe en plusieurs évent, ce qui me permet d’avoir un virtuel contenant toute les infos de mon onduleur.

Bonjour,

Je pensais que le plugin http remote event ne faisait que les extractions des paramètres GET. Je viens de tester et il y a bien par défaut une commande « post data » qui permet de récupérer le corps de la requête POST !

Merci pour votre aide.