Seuil de rentabilité et heure conseillée de démarrage d'un équipement avec une production et le tarif Tempo

Bonjour,

Utilisé pour mon besoin personnel et pour faire suite à une demande sur Community, je vous propose un tuto rapide pour déterminer le seuil de rentabilité permettant de savoir s’il vaut mieux faire tourner un appareil durant les heures de production solaire ou durant la nuit quand on a une tarification Tempo.

En bonus, une estimation de l’heure de démarrage pourrait être obtenue via plugin-solcast

:yin_yang: Comme plusieurs cerveaux valent mieux qu’un, n’hésitez pas à me dire si ce n’est pas juste et on pourra en discuter et y réfléchir pour améliorer ou corriger.

:warning: Prérequis :

J’utilise 2 scénarios :

  • SeuilRentabilité qui sera appelé par BestTimeslot
  • BestTimeslot qui appelera SeuilRentabilité

:arrow_right: Le scénario SeuilRentabilité (créer un bloc code et copier/coller le contenu) :

// --------------------------------------------------------------------------------------------------------------------------------
// Scénario utile pour les personnes ayant un contrat TEMPO
// Il retourne le besoin minimum de production en heure pleine pour atteindre un seul de rentabilité par rapport aux heures creuses
// Ce scénario est prévu pour être appelé depuis un autre en fournissant un tag puissance
//
// https://particulier.edf.fr/content/dam/2-Actifs/Documents/Offres/Grille_prix_Tarif_Bleu.pdf
// --------------------------------------------------------------------------------------------------------------------------------

// Paramétrage
$HCB = 12.96; // Bleu HC (cts € TTC/kWh)
$HPB = 16.09; // Bleu HP (cts € TTC/kWh)
$HCW = 14.86; // Blanc HC (cts € TTC/kWh)
$HPW = 18.94; // Blanc HP (cts € TTC/kWh)
$HCR = 15.68; // Rouge HC (cts € TTC/kWh)
$HPR = 75.62; // Rouge HP (cts € TTC/kWh)

$talon = 300; // Talon (en W)
$cmd_couleur_tempo = '#[xxxx][yyyy][Aujourdhui]#'; // Commande pour avoir l'information BLUE, WHITE ou RED
// Fin du paramétrage

$version = '03/11/2024 16:00' ;

$tags = $scenario->getTags();
 $scenario->setLog('|----------------------------------------------------------');
 $scenario->setLog('| Version du '.$version);
 $scenario->setLog('|  Talon : ' . $talon . ' Wh / ' . 'Puissance : ' . $tags['#puissance#'] . ' W');
 $scenario->setLog('|----------------------------------------------------------');

$puissance = round($tags['#puissance#']/1000);
$color = cmd::byString($cmd_couleur_tempo)->execCmd();
 $scenario->setLog('| .Couleur du jour : ' . $color);

if ($color == 'BLUE') {
 $prix_nuit = $puissance*$HCB;
 $conso = $prix_nuit/$HPB;
 $besoin_prod = round(1000*($puissance-$conso)+$talon);
  $scenario->setLog('| .Jour bleu - Besoin en production minimum : ' . $besoin_prod . ' Wh');
}
if ($color == 'WHITE') {
 $prix_nuit = $puissance*$HCW;
 $conso = $prix_nuit/$HPW;
 $besoin_prod = round(1000*($puissance-$conso)+$talon);
  $scenario->setLog('| .Jour blanc - Besoin en production minimum : ' . $besoin_prod . ' Wh');
}
if ($color == 'RED') {
 $prix_nuit = $puissance*$HCR;
 $conso = $prix_nuit/$HPR;
 $besoin_prod = round(1000*($puissance-$conso)+$talon);
  $scenario->setLog('| .Jour rouge - Besoin en production minimum : ' . $besoin_prod . ' Wh');
}
if ($color == 'UNDEFINED') {
 $besoin_prod = round($puissance);
  $scenario->setLog('| .Jour non défini (erreur)');
}
 $scenario->setLog('|----------------------------------------------------------');

$scenario->setReturn($besoin_prod);

Paramétrage statique :

  • Les prix du tarif Tempo. Les tarifs au 2 novembre 2024 sont ceux définis dans le code, il faudra modifier à chaque changement
  • Un talon permettant d’indiquer ce que consomme votre habitation dans la journée
  • La commande permettant de connaitre la couleur du jour. Elle doit envoyer BLUE, WHITE ou RED (c’est le cas avec plugin-rteecowatt par exemple)

Ce scénario prendra dynamiquement la puissance d’un équipement (que fournira BestTimeslot) et retournera la quantité de production que vos panneaux doivent produire pour qu’il soit plus intéressant de faire tourner cet équipement en journée durant les heures pleines que durant les heures creuses.

:arrow_right: Le scénario BestTimeslot (créer un bloc code et copier/coller le contenu) :

// --------------------------------------------------------------------------------------------------------------------------------
// Scénario appelant SeuilRentabilité avec une puissance pour connaitre le seuil de rentabilité
// Si le plugin SolCast est installé et les commandes configurées, il sera possible d'obtenir l'heure conseillée de démarrage
// --------------------------------------------------------------------------------------------------------------------------------

// Paramétrage obligatoire
$scenario_SeuilRentabilite = '#[xxxx][yyyy][SeuilRentabilité]#';
$puissance = 3000; // puissance (en W)
// Fin Paramétrage obligatoire

$version = '03/11/2024 16:00' ;

// Paramétrage optionnel si utilisation avec le plugin SolCast
$cmd_SolCast_Duree = '#[xxxx][yyyy][Durée de fonctionnement pour retour heure de démarrage]#';
$cmd_SolCast_HeureDemarrage = '#[xxxxx][yyyy][Heure de démarrage en fonction de la durée demandée]#';
$duree = 30; // Durée en minute
// Fin du paramétrage optionnel si utilisation avec le plugin SolCast


// -------------------------- NE PAS MODIFIER ----------------------------------
 $scenario->setLog('|----------------------------------------------------------');
$scenario->setLog('| Version du '.$version);
 $scenario->setLog('|  Durée : ' . $duree . ' minute(s) / ' . 'Puissance : ' . $puissance . ' kWh');
 $scenario->setLog('|----------------------------------------------------------');
$sc = scenario::byString($scenario_SeuilRentabilite);
$tags['#puissance#'] = $puissance;
$sc->setTags($tags);
$ProdMin = $sc->launch();
$tags['#ProdMin#'] = $ProdMin;
 $scenario->setLog('| .Seuil de rentabilité : ' . $ProdMin . ' Wh');

if ($cmd_SolCast_Duree != '' && $cmd_SolCast_HeureDemarrage != '') {
	cmd::byString($cmd_SolCast_Duree)->event($ProdMin . ';' . $duree);
	sleep(2);
	$Proposal = cmd::byString($cmd_SolCast_HeureDemarrage)->execCmd();
 	 $scenario->setLog('| .Heure de démarrage proposé par SolCast : ' . $Proposal);
	$tags['#Proposal#'] = $Proposal;
}
$scenario->setTags($tags);
 $scenario->setLog('|----------------------------------------------------------');

Paramétrage statique :

  • Le nom du scénario SeuilRentabilité
  • La puissance de l’appareil qui va tourner

Paramétrage optionnel :

  • La commande « Durée de fonctionnement pour retour heure de démarrage » du plugin-solcast
  • La commande « Heure de démarrage en fonction de la durée demandée » du plugin-solcast
  • La durée de fonctionnement de l’appareil en Watts

:information_source:
→ Si vous n’utilisez pas SolCast videz les chaines de caractères :

$cmd_SolCast_Duree = '';
$cmd_SolCast_HeureDemarrage = '';

→ Si vous utilisez SolCast le scénario retournera une suggestion d’heure (au format hhmm) en utilisant le seuil de rentabilité

C’est une base pour faciliter la mise en place et le test. Dans l’idée, le scénario SeuilRentabilité ne devrait pas être modifié. BestTimeslot est fait entièrement en bloc code mais c’est pour donner l’idée et il faudrait l’adapter à son utilisation en fournissant des données et en éxécutant des actions en dehors du bloc

2 « J'aime »

Merci @Bison pour ton tuto, on sent la maitrise du bloc code (et pas que).
Ca me sera bien utile pour mon projet.

Je galère un tout petit peu à m’y retrouver dans les deux blocs entre ce qui est de la puissance instantanée (W) et de l’énergie (Wh ou kWh).

Nous on achète de l’énergie (donc des kWh).
Dans le bloc du scénario SeuilRentabilité, il est indiqué dans les logs que $puissance porte bien son nom puisqu’est en Watt.
En revanche le talon qui est une puissance fixé à 300W, est ensuite indiqué comme une énergie de 300Wh

Ensuite quand tu calcules le tarif tu utilise une puissance * tarif : $prix_nuit = $puissance*$HCB;
Donc c’est comme si le code considère uniquement des durée d’1h pour les comparaisons.

Au final on dirait que la $duree n’est utilisée que pour trouver la meilleure heure de démarrage mais que le reste considère que c’est 1h.

Je peux me tromper mais je propose :

  • renommer le tag #puissance# en #energie_conso# pour plus de clarté,
  • Dans BestTimeslot, envoyer le tag : $tags['#energie_conso#'] = $puissance*$duree/60;, et envoyer la $duree dans le scenario SeuilRentabilité,
  • Ajouter la récupération du tag au premier scenario SeuilRentabilité : #duree#,
  • Dans SeuilRentabilité, remplacer $talon par $talon*$duree/60

Pour les tarifs, comme je m’en sers ailleurs, donc je pense utile de les récupérer dans des commandes infos :
D’abord je les rentre manuellement dans la configuration du plugin plugin-rteecowatt :


De cette manière je n’ai qu’un seul endroit à modifier et je galère pas à trouver dans quel scenario c’est présent, par contre pour les récupérer c’est un peu relou : les tarifs sortent sur la commande Json Cmd pour widget.
J’ai donc créé un virtuel avec 6 commandes info (1 par tarif) et un scénario récupère les tarifs dans le json et écrit les tarifs dans le virtuel.
Le scenario s’exécute sur un changement du json en question (donc 1 fois vers 11h27 et 1 fois à minuit).
Le scénario exécute ce bloc code:

$cmdJSON= cmd::byString("#[Maison][RETECOWATT][Json Cmd pour widget]#")->execCmd();
$scenario->setLog('cmdJSON : '.$cmdJSON);
$cmdJSON=str_replace('"', '"', $cmdJSON);
$scenario->setLog('cmdJSON nettoyé : '.$cmdJSON);
$cmdTAB=json_decode($cmdJSON,true);
    if (json_last_error() == JSON_ERROR_NONE) {
      	$scenario->setLog("Tarif Bleu HC : ".$cmdTAB["prices"]["HCJB"]);
		cmd::byString('#[Designs][virt - ECS solaire-tarifs Tempo][Tarif Bleu HC]#')->event($cmdTAB["prices"]["HCJB"]);
      	$scenario->setLog("Tarif Bleu HP : ".$cmdTAB["prices"]["HPJB"]);
		cmd::byString('#[Designs][virt - ECS solaire-tarifs Tempo][Tarif Bleu HP]#')->event($cmdTAB["prices"]["HPJB"]);
      	$scenario->setLog("Tarif Blanc HC : ".$cmdTAB["prices"]["HCJW"]);
		cmd::byString('#[Designs][virt - ECS solaire-tarifs Tempo][Tarif Blanc HC]#')->event($cmdTAB["prices"]["HCJW"]);
      	$scenario->setLog("Tarif Blanc HP : ".$cmdTAB["prices"]["HPJW"]);
		cmd::byString('#[Designs][virt - ECS solaire-tarifs Tempo][Tarif Blanc HP]#')->event($cmdTAB["prices"]["HPJW"]);
      	$scenario->setLog("Tarif Rouge HC : ".$cmdTAB["prices"]["HCJR"]);
		cmd::byString('#[Designs][virt - ECS solaire-tarifs Tempo][Tarif Rouge HC]#')->event($cmdTAB["prices"]["HCJR"]);
      	$scenario->setLog("Tarif Rouge HP : ".$cmdTAB["prices"]["HPJR"]);
		cmd::byString('#[Designs][virt - ECS solaire-tarifs Tempo][Tarif Rouge HP]#')->event($cmdTAB["prices"]["HPJR"]);
    }
    else $scenario->setLog('Json_decode error: ' .json_last_error_msg());

Et je récupère mon virtuel :

En espérant que ce sera utile à d’autres !

Hello,

Je me doutais bien qu’il y aurait un débat entre puissance et énergie :smile:.

Ici, sans parler de la justesse entre W et Wh, on cherche en premier lieu à savoir s’il est plus intéressant, par exemple de faire tourner un appareil de 1000 W durant la journée ou durant la nuit (je ne considère pas le talon pour l’exemple).

En journée si l’appareil tourne 1h il consommera 1 kWh et on paiera le prix en conséquence (disons 1€ au pif). S’il tourne la nuit il consommera aussi 1 kWh et on paiera moins cher (disons 0.5€ au pif).

Si l’appareil tourne 2h alors il aura consommé 2 fois plus et on paiera 2 fois plus (2€ la journée et 1€ la nuit).

Au final quelque soit la durée, le rapport entre le prix la journée et la nuit sera toujours le même.

Le besoin en production est donc toujours le même, quelque soit la durée, pour qu’il devienne plus intéressant de lancer la journée par rapport à la nuit. C’est mon seuil de rentabilité.

Par contre après la durée devient importante dans la mesure où il ne sera pas possible d’avoir une production X pendant 5h alors que ce sera possible pendant 1h30.

J’avais pas essayé de récupérer les prix depuis le plugin-rteecowatt, good job :+1:

Bonjour,
Il y a plus simple pour la récupération des prix directement dans la configuration de plugin-rteecowatt

$json = rteEcowatt::getTempoPricesJson();
$prices = json_decode($json,true);
$expDate = $prices["tempoExpirationDate"];
$HCJB = $prices["HCJB"];
$HPJB = $prices["HPJB"];
$HCJW = $prices["HCJW"];
$HPJW = $prices["HPJW"];
$HCJR = $prices["HCJR"];
$HPJR = $prices["HPJR"];

Voir aussi: Prix en texte avec virgule

3 « J'aime »

Excellent, je connaissais pas la commande getTempoPricesJson(); !

C’était pas évident à connaître sauf à aller éplucher le code du plugin de @jpty :slightly_smiling_face:

1 « J'aime »

LOL je suis un peu encµ|&*$ de mouches, I know !! :nerd_face:

Je pense que je comprends : ça te permet de vérifier rapidement en regardant le tableau de solcast si tu va produire suffisamment sur un créneau suffisant, et décider si c’est mieux en journée ou la nuit !

Petite précision :
$expdate peut contenir

UNDEFINED, OUTOFDATE ou la date d'expiration si encore valide.

Quelque soit la valeur d’$expdate les autres valeurs sont les prix renseignés dans la config du plugin.

Ah OK c’est son plugin, makes sense !
Merci pour l’astuce en tout cas !

1 « J'aime »

Mais si, il suffisait de poser la question. :innocent:

1 « J'aime »

C’est bien vrai ! J’avais fais ça avant l’arrivée des coûts dans le plugin et j’ai pas pris le temps de voir comment les récupérer en te demandant. Merci d’être intervenu ici :kissing_closed_eyes:

1 « J'aime »

Oui, en premier en regarde combien il faudrait produire pour que ce soit plus intéressant en journée (quelque soit la durée donc) et ensuite on regarde dans solcast si cette possibilité existe et à quel moment.

Got it ! :ok_hand:

Merci !
Evitera de venir éditer des scénarios un par un lors des changements de tarif…

Attention : bien saisir les tarifs dans la conf du plugin avec un POINT comme séparateur décimal.
Sinon les calculs seront pas bon.
(ne me demandez pas comment je m’en suis rendu compte…)

Bonjour,

Je n’ai pas de virgule sur mon pavé numérique :innocent:

Voici le bloc code pour transformer les prix en texte avec virgule en nombre décimaux

$json = rteEcowatt::getTempoPricesJson();
$prices = json_decode($json,true);
$expDate = $prices["tempoExpirationDate"];
$HCJB = str_replace(",",".",$prices["HCJB"]);
$HPJB = str_replace(",",".",$prices["HPJB"]);
$HCJW = str_replace(",",".",$prices["HCJW"]);
$HPJW = str_replace(",",".",$prices["HPJW"]);
$HCJR = str_replace(",",".",$prices["HCJR"]);
$HPJR = str_replace(",",".",$prices["HPJR"]);
1 « J'aime »

petit déterrage de ce sujet puisqu’il a été évoqué dans un autre post plus récent.

Je me suis un peu fait aider par mon copain Grok et on a fait ensemble un petit script pour récupérer les tarifs tempo par puissance souscrite (oui je sais à l’heure actuelle tous les bleu HC, HP ,… ont le même tarif). Ce script est à insérer dans un bloc code et affiche ces tarifs dans les logs, on peut donc aussi tout à fait utiliser ce script pour mettre à jour des commandes infos ou autre… Le pdf est un lien celui qui est utilisé dans l’excellent plugin rteEcowatt et à ce propos @jpty j’ai fait une PR sur ta branche dev pour récupération auto et remplissage des champs dans la page de configuration de ton plugin. Je n’ai jamais utilisé cette option et je viens de constater que les tarifs doivent être saisis en euros :wink:

Voici le script à coller dans un bloc code d’un scénario:

$pdfUrl = 'https://particulier.edf.fr/content/dam/2-Actifs/Documents/Offres/Grille_prix_Tarif_Bleu.pdf';

log::add('scenario', 'info', '[Tarifs Tempo] === DÉBUT récupération Option Tempo (avec pdftotext) ===');
log::add('scenario', 'info', '[Tarifs Tempo] Téléchargement du PDF...');

$pdfContent = @file_get_contents($pdfUrl);
if ($pdfContent === false) {
    log::add('scenario', 'error', '[Tarifs Tempo] Échec téléchargement du PDF');
    throw new Exception('Téléchargement échoué');
}

log::add('scenario', 'info', '[Tarifs Tempo] PDF téléchargé (' . strlen($pdfContent) . ' octets)');

// Fichier temporaire
$tempPdf = sys_get_temp_dir() . '/edf_tarif_bleu_tempo.pdf';
file_put_contents($tempPdf, $pdfContent);

// Extraction texte
$cmd = "pdftotext -layout '$tempPdf' - 2>/dev/null";
$text = shell_exec($cmd);

unlink($tempPdf); // Nettoyage

if (empty($text)) {
    log::add('scenario', 'error', '[Tarifs Tempo] pdftotext a échoué (poppler-utils installé ?)');
    throw new Exception('Extraction texte échouée');
}

log::add('scenario', 'info', '[Tarifs Tempo] Texte extrait avec succès – recherche section Option Tempo...');

$lines = explode("\n", $text);

$inTempo = false;
$found = false;

foreach ($lines as $line) {
    $line = trim(preg_replace('/\s+/', ' ', $line)); // Normalise espaces

    if (stripos($line, 'Option Tempo') !== false) {
        $inTempo = true;
        log::add('scenario', 'info', '[Tarifs Tempo] Section Option Tempo trouvée');
        continue;
    }

    // Ligne de données : puissance + 7 valeurs numériques avec virgule
    if ($inTempo && preg_match('/^(\d{1,2})\s+([0-9]{1,3},[0-9]{2})\s+([0-9]{1,3},[0-9]{2})\s+([0-9]{1,3},[0-9]{2})\s+([0-9]{1,3},[0-9]{2})\s+([0-9]{1,3},[0-9]{2})\s+([0-9]{1,3},[0-9]{2})\s+([0-9]{1,3},[0-9]{2})/', $line, $m)) {
        $puissance = $m[1] . ' kVA';
        $abo       = $m[2] . ' € TTC/mois';
        $bleuHC    = $m[3] . ' cts € TTC/kWh';
        $bleuHP    = $m[4] . ' cts € TTC/kWh';
        $blancHC   = $m[5] . ' cts € TTC/kWh';
        $blancHP   = $m[6] . ' cts € TTC/kWh';
        $rougeHC   = $m[7] . ' cts € TTC/kWh';
        $rougeHP   = $m[8] . ' cts € TTC/kWh';

        log::add('scenario', 'info', "[Tarifs Tempo] Puissance $puissance → Abo: $abo | Bleu HC: $bleuHC | Bleu HP: $bleuHP | Blanc HC: $blancHC | Blanc HP: $blancHP | Rouge HC: $rougeHC | Rouge HP: $rougeHP");

        $found = true;
    }

    // Fin de table (ajustable si besoin)
    if ($inTempo && stripos($line, 'Majoration') !== false) {
        break;
    }
}

if (!$found) {
    log::add('scenario', 'warning', '[Tarifs Tempo] Aucune donnée trouvée – vérifie le format du PDF');
}

log::add('scenario', 'info', '[Tarifs Tempo] === FIN de la récupération ===');

1 « J'aime »

Et si jamais pdfToText n’est pas installé sur votre jeedom (comme c’était le cas sur le mien) il faut aller dans réglages/système/configuration puis cliquer sur OS_DB puis « adminiqtration système » et enfin coller la ligne qui suit dans la case de saisie de la page:

sudo apt update && sudo apt install -y poppler-utils

image

Hello Noyax,

Merci pour la contribution.

Je pense qu’il faudrait par contre trouver une astuce pour ne pas le mettre en début de script afin qu’il ne soit pas traité à chaque demande d’un calcul de seuil de rentabilité.

Sinon il faut utiliser les lignes que jpty avait donné, ce qui permet de récupérer les prix directement au niveau du plugin rteEcowatt et donc d’éviter de faire le traitement potentiellement plusieurs fois par jour

Bonjour,

Je voudrai appliquer votre code (Scénario SeuilRentabilité) à une usage plus « simple » sur la base d’une HC/HP classique.
Clairement, je ne fais pas de code donc j’ai essayé de comprendre la logique. Sur cette base, je l’ai modifié en ce sens.

// --------------------------------------------------------------------------------------------------------------------------------
// Scénario utile pour les personnes ayant un contrat TEMPO
// Il retourne le besoin minimum de production en heure pleine pour atteindre un seul de rentabilité par rapport aux heures creuses
// Ce scénario est prévu pour être appelé depuis un autre en fournissant un tag puissance
//
// https://particulier.edf.fr/content/dam/2-Actifs/Documents/Offres/Grille_prix_Tarif_Bleu.pdf
// --------------------------------------------------------------------------------------------------------------------------------

// Paramétrage
$HC = 12.96; // HC (cts € TTC/kWh)
$HP = 16.09; // HP (cts € TTC/kWh)

$talon = 300; // Talon (en W)
$cmd_HC_HP = '#[xxxx][yyyy][Aujourdhui]#'; // Commande pour avoir l'information si on est en HC ou HP, à partir d'un scénario fait en amont
// Fin du paramétrage

$tags = $scenario->getTags();
 $scenario->setLog('|----------------------------------------------------------');
 $scenario->setLog('|  Talon : ' . $talon . ' Wh / ' . 'Puissance : ' . $tags['#puissance#'] . ' W');
 $scenario->setLog('|----------------------------------------------------------');

$puissance = round($tags['#puissance#']/1000);
$periode = cmd::byString($cmd_HC_HP)->execCmd();
 $scenario->setLog('| .Période : ' . $periode);

if ($periode == 'HC') {
 $prix_HC = $puissance*$HC;
 $conso = $prix_HC/$HP;
 $besoin_prod = round(1000*($puissance-$conso)+$talon);
  $scenario->setLog('| .HC - Besoin en production minimum : ' . $besoin_prod . ' Wh');
}
if ($periode == 'HP') {
 $prix_HP = $puissance*$HP;
 $conso = $prix_HP/$HC;
 $besoin_prod = round(1000*($puissance-$conso)+$talon);
  $scenario->setLog('| .HP - Besoin en production minimum : ' . $besoin_prod . ' Wh');
}
 $scenario->setLog('|----------------------------------------------------------');

$scenario->setReturn($besoin_prod);

Je vous laisse me dire si c’est ok ou si c’est complétement faux :sweat_smile:

Hello,

C’est même encore plus simple que ce que tu as adapté (mais bon dans l’idée tu t’en étais pas trop mal sortis).

Dans ton cas nul besoin de savoir si on est en HP ou HC, forcement tu veux juste connaitre le besoin en PROD durant les HP afin de savoir si ce ne serait pas mieux de faire tourner en HC. Donc pas besoin de if ($periode == 'xx'), le scenario sera à appeler pendant les HP.

Du coup ça donnerait ça :

// Paramétrage
$HC = 12.96; // HC (cts € TTC/kWh)
$HP = 16.09; // HP (cts € TTC/kWh)

$talon = 300; // Talon (en W)
// Fin du paramétrage

$tags = $scenario->getTags();
 $scenario->setLog('|----------------------------------------------------------');
 $scenario->setLog('|  Talon : ' . $talon . ' Wh / ' . 'Puissance : ' . $tags['#puissance#'] . ' W');
 $scenario->setLog('|----------------------------------------------------------');

$puissance = round($tags['#puissance#']/1000);

$prix_HC = $puissance*$HC;
$conso = $prix_HC/$HP;
$besoin_prod = round(1000*($puissance-$conso)+$talon);

 $scenario->setLog('| .Besoin en production minimum : ' . $besoin_prod . ' Wh');

 $scenario->setLog('|----------------------------------------------------------');

$scenario->setReturn($besoin_prod);