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 »