CRON manuel d'un scénario X dans le CODE d'un scénario Y

Tags: #<Tag:0x00007f5928319628>

Bonjour,

Je ne parviens pas à programmer le lancement d’un scénario via la création manuelle d’une entrée dans le CRON.

J’obtiens cette erreur à l’exécution:
55

Voici le détail de la tâche:
36 !
38

En vous remerciant d’avance pour votre aide

Pourquoi faire cela?
Ce n’est juste pas du tout la façon de procéder

Et Pourquoi utiliser un bloc code ?
N’était-ce pas possible avec les autres blocs ? A première vue, si.

Bonjour Mips et merci de vous pencher sur le sujet,

J’ai créé un ensemble de scénarios, “Modes”, entrées “Agenda” et “Google Agenda” pour gérer le chauffage de mes pièces avec des vannes Zwave. Certaines pièces disposent de plusieurs vannes et je m’arrange pour la consigne soit la même pour toutes les vannes d’une même pièce.

Je gère des modes automatiques (“Eco”, “Confort” et “Abaissement”) avec des T° de consigne par pièce différentes pour ces modes selon qu’il s’agit d’une pièce d’eau ou d’une pièce de vie, …

Je gère également un mode manuel (changement manuel de la consigne sur 1 vanne) qui reporte automatiquement la consigne sur les autres vannes de la même pièce et planifie un retour au mode précédent 2 heures plus tard.

J’aurais bien sûr pu gérer cela avec un ensemble de scénarios pour 1 pièce et le dupliquer/adapter pour chaque pièce mais j’ai préféré travailler avec un ensemble de variables qui défini la configuration des différentes pièces de sorte que 1 seul et même ensemble suffit auquel soit on passe en “tags” la pièce et le mode que l’on souhaite activer, soit qui se déclenche sur une action de modification manuelle sur les vannes.

J’ai trouvé plus simple et intéressant de travailler dans du code pour ce faire.

Si la problématique du cron pouvait être réglée par un bloc “Dans 2h -> Faire…” pour 1 pièce, l’usage du même scénario pour toutes les pièces me mettais face au problème que l’exécution du bloc “Dans…” commence par supprimer l’éventuel cron d’un appel précédent.

Cela commence à poser problème quand on change manuellement la T° dans 2 pièces différentes. Car le retour au mode précédent ne s’exécute pour que la pièce où la T° a été modifiée en dernier lieu.

J’ai contourné le problème en passant en retour du code un N° de pièce et en multipliant en conséquence les blocs “Dans…” selon le N° retourné. (If tag(Num Pièce) = i alors DANS… lancer le scénario X avec les paramètre Pièce Mode …)…

Cependant, j’ai tenté de gérer dans le code la création dans CRONTAB de ces exécutions et c’est ce à quoi je m’achoppe actuellement d’où ma question…

En espérant ne pas avoir été trop long :wink:

j’ai pas tous compris
mais pour la question ci-joint un vieux scénario (@tonegred) qui te permettra de comprendre le changement de cron

se vieux scénario modifie le cron +/- x mn des scénario id lié au levée/couché de soleil

/******************************************************************************/

//Configuration
$Debug = false;   // Permet d'activer les log de Debug - true ou false

$latitude = 45.0667; 
$longitude = 3.7333;
$zenith = 90;
$Variable_Lever = "HeureLever"; // Le nom de votre Variable pour le levé
$Variable_Coucher = "HeureCoucher"; // Le Nom de votre Variable pour le couché

$cmdDif = "#[météo][Le soleil][dif]#";
/******************************************************************************/

// Déclaration des ID Scénarios à mettre à jour pour Lever Soleil
$IdScenaLever = array(
//   "41:+10",   // Scénario Led TV
//   "51:-10",           // Scénario Lum Hall Entrée
   "05"    // Scénario Lever
);

// Déclaration des ID Scénarios à mettre à jour pour Coucher Soleil
$IdScenaCoucher = array(
   "12:+15",       // Scénario Couché +15
//   "12:-10",          // Scénario Lum Hall Entrée
   "06"             // Scénario Coucher
);

/******************************************************************************/

// Lever Soleil

$Lever_Soleil = date_sunrise(time(), SUNFUNCS_RET_STRING, $latitude, $longitude, $zenith, date("Z",time())/3600);
$Lever_Soleil_Value = explode(":", $Lever_Soleil);
$hier = strtotime("yesterday");
$Lever_Soleil_hier = date_sunrise($hier, SUNFUNCS_RET_STRING, $latitude, $longitude, $zenith, date("Z",time())/3600);
// $Lever_Soleil_hier = str_replace(":", "",$Lever_Soleil_hier);

// Stockage du Lever de Soleil dans sa Variable
$scenario->setData($Variable_Lever, $Lever_Soleil_Value[0].$Lever_Soleil_Value[1]);
if ($Debug) { $scenario->setLog(':: DEBUG :: Sauvegarde : ' . $Lever_Soleil_Value[0].$Lever_Soleil_Value[1] . ' Dans Variable : ' . $Variable_Lever); }

// Initialisation du Tableau
$TbLever = 0;

// Exécution des Modifications Cron pour chaque Element du Tableau
if ($Debug) { $scenario->setLog(':: DEBUG :: Nombre ID pour Lever : ' . count($IdScenaLever)); }
if (count($IdScenaLever) > 0) {
   foreach ($IdScenaLever as $IdScenaLeverValue) {

      if ($Debug) { $scenario->setLog('-------------------------------------------------------------------------------'); }

      if (strstr($IdScenaLeverValue, ':')) {

         // Récupèration Heures et Minutes séparés
         $IdScenaLeverValue = explode(':', $IdScenaLeverValue);
         if ($Debug) { $scenario->setLog(':: DEBUG :: Id Scena : ' . $IdScenaLeverValue[0] . ' - Décalage Horaire : ' . $IdScenaLeverValue[1]); }

         // Conversion en secondes de L'heure et minute du Lever Soleil
         $ConvertHeureLever = ((($Lever_Soleil_Value[0] * 60)*60) + ($Lever_Soleil_Value[1] * 60));
         if ($Debug) { $scenario->setLog(':: DEBUG :: Heure Lever en Seconde : '.$ConvertHeureLever); }

         // Vérification d'un décalage horaire
         if (strstr($IdScenaLeverValue[1], '+')) {
            // Incrémentation des minutes converties en secondes
            $ConvertHeureLever += substr($IdScenaLeverValue[1], 1)*60;
            if ($Debug) { $scenario->setLog(':: DEBUG :: ConvertHeureLever secondes (+) : ' . $ConvertHeureLever); }
         }
         else if (strstr($IdScenaLeverValue[1], '-')) {
            // Décrémentation des minutes converties en secondes
            $ConvertHeureLever -= substr($IdScenaLeverValue[1], 1)*60;
            if ($Debug) { $scenario->setLog(':: DEBUG :: ConvertHeureLever secondes (-) : ' . $ConvertHeureLever); }
         } else {
            $scenario->setLog(":: ERROR : Pas d'indicateur d'addition ou de soustraction !");
         }

         $NewHeureLever = intval($ConvertHeureLever / 3600);
         $NewMinuteLever = intval(($ConvertHeureLever % 3600) / 60);
         $IdScenaToEdit = intval($IdScenaLeverValue[0]);

         if ($Debug) { $scenario->setLog(':: DEBUG :: NewHeureLever : ' . $NewHeureLever); }
         if ($Debug) { $scenario->setLog(':: DEBUG :: NewMinuteLever : ' . $NewMinuteLever); }

      } else {

         if ($Debug) { $scenario->setLog(':: DEBUG :: Id Scena : ' . $IdScenaLeverValue[0]); }

         $NewHeureLever = $Lever_Soleil_Value[0];
         $NewMinuteLever = $Lever_Soleil_Value[1];
         $IdScenaToEdit = $IdScenaLeverValue;

         if ($Debug) { $scenario->setLog(':: DEBUG :: NewHeureLever : ' . $NewHeureLever); }
         if ($Debug) { $scenario->setLog(':: DEBUG :: NewMinuteLever : ' . $NewMinuteLever); }
      }

      $Scenario = scenario::byId($IdScenaToEdit);

      if (is_object($Scenario)) {
         if ($Scenario->getMode() != 'schedule') {
            $Scenario->setMode('schedule');
         }

         $Schedule = $Scenario->getSchedule();
         $Scenario->setSchedule($NewMinuteLever . ' ' . $NewHeureLever . ' * * *');
         $Scenario->save();
      }

      $TbLever++;
   }
} else { $scenario->setLog(":: LOG : Pas de Scénario à modifier pour le Lever de Soleil !"); }

if ($Debug) { $scenario->setLog('-------------------------------------------------------------------------------'); }

// Coucher Soleil
$Coucher_Soleil = date_sunset(time(), SUNFUNCS_RET_STRING, $latitude, $longitude, $zenith, date("Z",time())/3600);
$Coucher_Soleil_Value = explode(":", $Coucher_Soleil);
$Coucher_Soleil_hier = date_sunset($hier, SUNFUNCS_RET_STRING, $latitude, $longitude, $zenith, date("Z",time())/3600);
//$Coucher_Soleil_hier = str_replace(":", "",$Coucher_Soleil_hier);

// Stockage du Coucher de Soleil dans sa Variable
$scenario->setData($Variable_Coucher, $Coucher_Soleil_Value[0].$Coucher_Soleil_Value[1]);
if ($Debug) { $scenario->setLog(':: DEBUG :: Sauvegarde : ' . $Coucher_Soleil_Value[0].$Coucher_Soleil_Value[1] . ' Dans Variable : ' . $Variable_Coucher); }

// Initialisation du Tableau
$TbCoucher = 0;

// Exécution des Modifications Cron pour chaque Element du Tableau
if ($Debug) { $scenario->setLog(':: DEBUG :: Nombre ID pour Coucher : ' . count($IdScenaCoucher)); }
if (count($IdScenaCoucher) > 0) {
   foreach ($IdScenaCoucher as $IdScenaCoucherValue) {

      if ($Debug) { $scenario->setLog('-------------------------------------------------------------------------------'); }

      if (strstr($IdScenaCoucherValue, ':')) {

         // Récupèration Heures et Minutes séparés
         $IdScenaCoucherValue = explode(':', $IdScenaCoucherValue);
         if ($Debug) { $scenario->setLog(':: DEBUG :: Id Scena : ' . $IdScenaCoucherValue[0] . ' - Décalage Horaire : ' . $IdScenaCoucherValue[1]); }

         // Conversion en secondes de L'heure et minute du Coucher Soleil
         $ConvertHeureCoucher = ((($Coucher_Soleil_Value[0] * 60)*60) + ($Coucher_Soleil_Value[1] * 60));
         if ($Debug) { $scenario->setLog(':: DEBUG :: Heure Coucher en Seconde : '.$ConvertHeureCoucher); }

         // Vérification d'un décalage horaire
         if (strstr($IdScenaCoucherValue[1], '+')) {
            // Incrémentation des minutes converties en secondes
            $ConvertHeureCoucher += substr($IdScenaCoucherValue[1], 1)*60;
            if ($Debug) { $scenario->setLog(':: DEBUG :: ConvertHeureCoucher secondes (+) : ' . $ConvertHeureCoucher); }
         }
         else if (strstr($IdScenaCoucherValue[1], '-')) {
            // Décrémentation des minutes converties en secondes
            $ConvertHeureCoucher -= substr($IdScenaCoucherValue[1], 1)*60;
            if ($Debug) { $scenario->setLog(':: DEBUG :: ConvertHeureCoucher secondes (-) : ' . $ConvertHeureCoucher); }
         }
         else {
            $scenario->setLog(":: ERROR : Pas d'indicateur d'addition ou de soustraction !");
         }

         $NewHeureCoucher = intval($ConvertHeureCoucher / 3600);
         $NewMinuteCoucher = intval(($ConvertHeureCoucher % 3600) / 60);
         $IdScenaToEdit = intval($IdScenaCoucherValue[0]);

         if ($Debug) { $scenario->setLog(':: DEBUG :: NewHeureCoucher : ' . $NewHeureCoucher); }
         if ($Debug) { $scenario->setLog(':: DEBUG :: NewMinuteCoucher : ' . $NewMinuteCoucher); }
      } else {
         if ($Debug) { $scenario->setLog(':: DEBUG :: Id Scena : ' . $IdScenaCoucherValue[0]); }

         $NewHeureCoucher = $Coucher_Soleil_Value[0];
         $NewMinuteCoucher = $Coucher_Soleil_Value[1];
         $IdScenaToEdit = $IdScenaCoucherValue;

         if ($Debug) { $scenario->setLog(':: DEBUG :: NewHeureCoucher : ' . $NewHeureCoucher); }
         if ($Debug) { $scenario->setLog(':: DEBUG :: NewMinuteCoucher : ' . $NewMinuteCoucher); }
      }

      $Scenario = scenario::byId($IdScenaToEdit);

      if (is_object($Scenario)) {
         if ($Scenario->getMode() != 'schedule') {
            $Scenario->setMode('schedule');
         }

         $Schedule = $Scenario->getSchedule();
         $Scenario->setSchedule($NewMinuteCoucher . ' ' . $NewHeureCoucher . ' * * *');
         $Scenario->save();
      }

      $idCoucher++;
   }
} else { $scenario->setLog(":: LOG : Pas de Scénario à modifier pour le Coucher de Soleil !"); }

$scenario->setLog('Levée - Couchée Soleil : '.$Lever_Soleil_Value[0].$Lever_Soleil_Value[1].' - '.$Coucher_Soleil_Value[0].$Coucher_Soleil_Value[1]);
$scenario->setLog('Levée - Couchée Soleil  hier : '.$Lever_Soleil_hier.' - '.$Coucher_Soleil_hier);

$deltajour = gmdate("gi",strtotime($Coucher_Soleil) - strtotime($Lever_Soleil));
$deltahier = gmdate("gi",strtotime($Coucher_Soleil_hier) - strtotime($Lever_Soleil_hier));
$deltadif = ($deltajour) - ($deltahier);

$scenario->setLog("différence hier : ".$deltahier);
$scenario->setLog("différence jour : ".$deltajour);
$scenario->setLog("différence : ".$deltadif." mn");
$cmd = cmd::byString($cmdDif)->event($deltadif);

Après pour le chauffage j’utilise le code en fin de prez d’équipement toutes les minutes
https://forum.jeedom.com/viewtopic.php?f=133&t=11227&hilit=maxcube&sid=370ca862794491519c9f9ddda725d16b
légère adaptation set point, difftime,…

$temperatures = array("Salle a manger]",
                      "Cuisine]",
//                      "Chambre Adrien]",
//                      "Chambre Lisa]",
                      "Chambre Ami]",
);

$chaudiere = 0;
// $scenario->setData("chaudiere", $chaudiere);

$cmd_chaudiere = "#[Nouveau Chauffage][Chaudiére][Chaudiére]#";
$cmd = cmd::byString($cmd_chaudiere)->event(($chaudiere));

foreach ($temperatures as $temperature) {
$consigne_cmd = cmd::byString('#[Nouveau Chauffage][Gestion Chauffage][Consignes ' . $temperature . '#');
$setpoint = $consigne_cmd->execCmd();  
$temp_cmd = cmd::byString('#[Nouveau Chauffage][Gestion Chauffage][' . $temperature . '#');
$temp = $temp_cmd->execCmd();
    $temp_difftime = ((new DateTime(date("Y-m-d H:i:s")))->getTimestamp() - (new DateTime($temp_cmd->getCollectDate()))->getTimestamp());
  if ($temp != 0 && $temp < $setpoint - 0.3 && $temp_difftime < 600) {
    $eq = explode("/", str_replace("[", "", str_replace("]", "", str_replace("][", "/", $thermostat))));
    $scenario->setData("last_heat_" . strtolower(str_replace(" ", "_", $eq[0])), date("Y-m-d H:i:s"));
    $chaudiere += $setpoint - $temp;
  }
   $scenario->setLog("sonde : [$temperature température : [$temp] consigne : [$setpoint] temp_difftime : [$temp_difftime]");
  }
$cmd = cmd::byString($cmd_chaudiere)->event(($chaudiere));

// $scenario->setData("chaudiere", $chaudiere);
$scenario->setLog("chaudiere : $chaudiere");

qui me donne le total des différences consignes/températures
et si > 0.4
– si éteind depuis + 5 mn == en marche

lastChangeStateDuration(#[Nouveau Chauffage][Etat chaudiéres][circulateur]#, 0) > 300

Bonjour et merci pour la proposition d’aide,

Je vois bien la façon de procéder mais en bref, ce que souhaiterais et qui pourrait je pense m’être utile dans d’autres situations (je commence sur Jeedom) c’est de pouvoir lancer un scénario à partir d’un code.

J’ai essayé comme ceci

  $cron = new cron();
  $cron->setClass('scenario');
  $cron->setFunction('doIn');
  $cron->setOption(array('scenario_id' => 21, 'scenarioElement_id' => 115,'second' => date('s'), 'tags' => array("#Pièce#" => "Sejour","#Mode#" => "Confort", "#Chgt#" => "O")));
  $cron->setLastRun(date('Y-m-d H:i:s'));
  $cron->setOnce(1);
  $next = strtotime('+ ' . '1' . ' min');
  $cron->setSchedule(date('i', $next) . ' ' . date('H', $next) . ' ' . date('d', $next) . ' ' . date('m', $next) . ' * ' . date('Y', $next));
  $cron->save();

qui donne dans le détail du CRON

doIn
Scénario : Chauffage Chgt Mode

CODE
(code)
$tags = $scenario->getTags();
$Piece = str_replace(’’’, ‘’, $tags[’#Pièce#’]);
$Mode = $tags[’#Mode#’];
$Chgt = $tags[’#Chgt#’];

$scenario->setLog(‘Pièce: $Piece, Mode: $Mode, Chgt: .$Chgt’);

if ($Mode <> ‘Eco’) {

$Consigne = $scenario->getData('Chauffage Température ‘.$Mode.’ '.$Piece);

$scenario->setData('Chauffage Mode '.$Piece, $Mode);
$scenario->setData('Chauffage Consigne '.$Piece,$Consigne);
}

if (($scenario->getData('Chauffage Occupation '.$Piece) == ‘N’ and $Mode == ‘Eco’)

… avec

(option)
{“scenario_id”:21,“scenarioElement_id”:115,“second”:“20”,“tags”:{"#Pi\u00e8ce#":“Sejour”,"#Mode#":“Confort”,"#Chgt#":“O”}}

… qui ressemble à s’y méprendre au lancement d’un scénario avec un bloc “DANS…” (c’est sur les options d’un bloc DANS que j’ai basé la création du CRON).

Sauf qu’à l’exécution, j’obtiens l’erreur

Date et heure Source Description Action Occurrences
2020-01-11 13:09:16 scenario Erreur sur scenario::doIn() : Call to a member function execute() on bool

Donc si quelqu’un peut m’aider à comprendre pourquoi ça cloche, je suis preneur.

Grand merci d’avance!