Intérations dans scénario via un bloc code - depuis 4.3.X (6-8)?

Bonjour à tous,

Préambule : Jeedom en 4.3.8 et tous les plugins à jours

J’ai poussé les différentes versions de la la 4.3 sur les derniers jours.
J’ai depuis plusieurs années un scénario qui tourne toutes les 5 minutes pour exécuter le bloc code suivant qui a vocation à analyser le temps d’allumage de certaines commandes et de me proposer, via un ask sous telegram l’extinction automatique ou la mise en place d’un délai supplémentaire :

function demande($cmd_id,$question,$reponse,$variable_reponse,$timeout) {
	$options_cmd = array('title' => '', 'message' => $question, 'answer' => explode(';', $reponse), 'timeout' => $timeout, 'variable' => $variable_reponse);
	$cmd = cmd::byString($cmd_id);
	$cmd->setCache('ask::variable', $variable_reponse);
	$cmd->setCache('ask::endtime', strtotime('now') + $timeout);
	$cmd->execCmd($options_cmd);
	$occurence = 0;
	$value = '';
	while (true){
		$dataStore = dataStore::byTypeLinkIdKey('scenario', -1, $variable_reponse);
		if (is_object($dataStore)){
			$value = $dataStore->getValue();
		}                          
		if ($value != ''){
			break;
		}
		if ($occurence > $timeout){
			break;
		}
		$occurence++;
		sleep(1);
	}
	if ($value == ''){
		$value = 'Aucune réponse';
		$cmd->setCache('ask::variable', 'none');
		$dataStore = dataStore::byTypeLinkIdKey('scenario', -1, $variable_reponse);
		$dataStore->setValue($value);
		$dataStore->save();
	}
	return $value;
}

//Récupération du demandeur
$tags = $scenario->getTags();// Récupération des tags passés
(empty($tags['#TelegramSource#'])) ? $tags['#TelegramSource#'] = '#[Communication][Telegram][idtelegram]#' : null;// Vérification de l'existance du tag, si ce dernier n'existe pas, on le crée avec la valeur souhaité.
$cmdmsg_id = $tags['#TelegramSource#'];

$fonctions_suivies = array();
$fonctions_suivies[] = '#[Bureau][FWP][Etat]#';
$fonctions_suivies[] = '#[Salle à manger][FWP][Etat]#';
$fonctions_suivies[] = '#[Salle de bain][FWP][Etat]#';
$fonctions_suivies[] = '#[Extérieur][FGD212][Etat]#';
$fonctions_suivies[] = '#[Zone Nuit][QZMNHSD][Etat]#';
$fonctions_suivies[] = '#[Salon][QZMNHSD][Etat]#';
$fonctions_suivies[] = '#[Cuisine][QZMNHSD][Etat]#';
$fonctions_suivies[] = '#[Cuisine][FGS213-Table][Etat]#';
$fonctions_suivies[] = '#[Cuisine][FGS213-Evier][Etat]#';
$fonctions_suivies[] = '#[Grenier][VMC][Etat2]#';

$seuil_heures = array();
$seuil_heures[] = 3;
$seuil_heures[] = 3;
$seuil_heures[] = 3;
$seuil_heures[] = 15/60;
$seuil_heures[] = 10/60;
$seuil_heures[] = 3;
$seuil_heures[] = 3;
$seuil_heures[] = 3;
$seuil_heures[] = 3;
$seuil_heures[] = 5;

$fonctions_suivies_txt = array();
$fonctions_suivies_txt[] = 'La prise de l\'imprimante';
$fonctions_suivies_txt[] = 'La base de l\'aspirateur';
$fonctions_suivies_txt[] = 'La base de la brosse à dents';
$fonctions_suivies_txt[] = 'La lumière de dehors';
$fonctions_suivies_txt[] = 'Les spots du couloir';
$fonctions_suivies_txt[] = 'Les spots du salon';
$fonctions_suivies_txt[] = 'Les spots de la cuisine';
$fonctions_suivies_txt[] = 'La lumière de la table de la cuisine';
$fonctions_suivies_txt[] = 'La lumière de l\'évier de la cuisine';
$fonctions_suivies_txt[] = 'La VMC de l\'extension';

$i=0;
foreach($fonctions_suivies as $cmd_string) {
	$cmd = cmd::byString($cmd_string);
	$cmd_id = $cmd->getId();
	$cmd_name = $cmd->getHumanName();
	$cmd_subtype = $cmd->getSubType();
	$value = $cmd->execCmd();
	$eqlogic_id = $cmd->getEqLogic_id();
	$eqlogic = eqLogic::byId($eqlogic_id);
		$eqlogic_name = $eqlogic->getName();
		$eqlogic_object = substr($eqlogic->getHumanName(),1,strlen($eqlogic->getHumanName())-1-2-strlen($eqlogic_name)-1);
			$eqlogic_name2 = str_replace(' ','',$eqlogic_name);
			$eqlogic_object2 = str_replace(' ','',$eqlogic_object);
	// Calcul durée On
	$duree_on = 0;
	if ($cmd_subtype == 'binary' && $value == 1) {
		$duree_on = scenarioExpression::laststateduration($cmd_id,1);
	} else if ($cmd_subtype == 'numeric' && $value >= 1) {
		$duree_on = scenarioExpression::lastChangeStateDuration($cmd_id,0) - scenarioExpression::lastStateDuration($cmd_id,0);
	}
	// Si dépassement du seuil : action
	if ($duree_on > $seuil_heures[$i]*60*60) {
		$scenario->setLog('- Allumage de ' . $cmd_name . ' depuis ' . $duree_on . ' secondes (seuil : ' . $seuil_heures[$i]*60*60 . ').');
		$variable_reponse = 'Suivi_'. $eqlogic_object2 . '_' . $eqlogic_name2; // nom de la variable qui stockera la réponse
		$variable_compteur = $variable_reponse . '_compteur';
		// Si compteur actif est supérieur à la dernière diminution de 5 minutes, on modifie le compteur sinon action
		if ($scenario->getData($variable_compteur) > (5 / 60)) {
			$scenario->setData($variable_compteur,round($scenario->getData($variable_compteur) - 1 * 5 / 60,4));
		} else if ($cmd_name <> '[Salle de bain][Brosse à dents][Etat]' || ($cmd_string == '[Salle de bain][Brosse à dents][Etat]' && (date('Hi')>0620 && date('Hi')<2240))) {
			$scenario->removeData($variable_reponse);
			//Paramètres du ask
			if ($i == 4 || $i == 5 || $i == 6) {
				$question = $fonctions_suivies_txt[$i] . ' sont allumés depuis plus de ' . $seuil_heures[$i] . 'h. Souhaitez-vous les éteindre ?';
			} else {
				$question = $fonctions_suivies_txt[$i] . ' est allumée depuis plus de ' . $seuil_heures[$i] . 'h. Souhaitez-vous l\'éteindre ?';
            }
			$reponse = 'Oui;Non';
			$timeout = '60'; // time out pour la réponse

			$scenario->setData($variable_reponse,'');//On vide la variable
			$value = demande($cmdmsg_id,$question,$reponse,$variable_reponse,$timeout);

			//Traitement de la reponse
			if ($value == 'Aucune réponse' || $value == 'Oui'){
				$cmd = cmd::byString('#[' . $eqlogic_object . '][' . $eqlogic_name . '][Off]#');
				$cmd->execCmd();

				$msg = 'J\'ai éteint ' . strtolower($fonctions_suivies_txt[$i]) . '.';
				$cmd = cmd::byString($cmdmsg_id);
				$cmd->execCmd($options=array('title'=> "empty=1",'message'=> $msg), $cache=0);
				$scenario->removeData($variable_reponse);
			} else if ($value == 'Non'){
				$scenario->removeData($variable_reponse);
				//Paramètres du ask
				$question = 'Pendant combien d\'heures souhaitez-vous reporter le suivi ?';
				$reponse = '1;2;3;4;5;6';
				$variable_reponse = $variable_compteur;
				$timeout = '60'; // time out pour la réponse 

				$scenario->setData($variable_reponse,'');//On vide la variable
				$value = demande($cmdmsg_id,$question,$reponse,$variable_reponse,$timeout);

				//Traitement de la reponse
				if ($value == 'Aucune réponse'){
					$msg = 'Mise en place d\'un délai d\'1 heure.';
					$cmd = cmd::byString($cmdmsg_id);
					$cmd->execCmd($options=array('title'=> "empty=1",'message'=> $msg), $cache=0);
				} else {
					if ($scenario->getData($variable_reponse) == 1) {
						$msg = 'Mise en place d\'un délai d\'1 heure.';
                    } else {$msg = 'Mise en place d\'un délai de ' . $scenario->getData($variable_reponse) . ' heures.';}
					$cmd = cmd::byString($cmdmsg_id);
					$cmd->execCmd($options=array('title'=> "empty=1",'message'=> $msg), $cache=0);
				}
            }
        }
	}
	$i++;
}
  1. Il y a en premier lieu la définition de la fonction « demande » qui correspond à la fonction ask de jeedom.
  2. Ensuite la définition des paramètres de mes commandes suivies
  3. La boucle pour chacune des commandes suivies avec l’appel de la fonction « demande »

Je ne peux plus répondre aux ask sous telegram, j’ai systématiquement le message « désolé je n’ai pas compris » comme si jeedom n’attendais pas la réponse à sa demande initiale et l’interprète comme une nouvelle interaction non prévue donc incomprise.

J’ai regardé les pages :
https://doc.jeedom.com/fr_FR/dev/core4.0
https://doc.jeedom.com/fr_FR/dev/core4.1
https://doc.jeedom.com/fr_FR/dev/core4.2
https://doc.jeedom.com/fr_FR/dev/core4.3
Mais je ne vois rien qui pourrait me générer des interférences.

Par contre dans le changelog 4.3.8 :
https://doc.jeedom.com/fr_FR/core/4.3/changelog
On parle de la fonction ask.
Il me semblait avoir vu des articles en parler en amont de la 4.3.8 mais je ne retrouve rien du coup j’ai un doute.

Dans ma discussion telegram, je sais que j’ai répondu à un ask le 24/10 et que cela a correctement fonctionné mais qu’hier (28/10 23h donc en 4.3.8), je ne pouvais plus y répondre.

Avez-vous des pistes ?
Est-ce l’ajout de sécurité des ask qui nécessiterait une modification de mon bloc code ici présent (et mes autres scénarios qui sont sur ce principe ?

Merci pour votre aide

1 « J'aime »

Bonjour,
Il semble qu’il y est eu une modification dans la class cmd :

il faut mettre en cache les réponses possible :
$cmd->setCache('ask::answer', $options_cmd['answer']);
car maintenant le Core fait une vérification de la réponse par rapport a celles misent en cache

1 « J'aime »

Parfait @Phpvarious
Testé sur le scénario à l’instant, cela fonctionne en ajoutant cette ligne sans autre modification.
Je teste mes autres scénarios maintenant.
Merci :slight_smile:

Bonjour,

Mais pourquoi récrire la fonction ?
Il faut appeler la fonction du core et ne pas dupliquer le code

Bonjour,

j’ai le même soucis avec mes 3 scénarios qui utilisent le ask (les poubelles et la relève du courrier)

je n’ai rien modifié, juste fais la mise a jour du core.
Que veux tu dire par "

je n’ai rien touché à mes scénario mais effectivement j’ai le droit au fameux désolé je n’ai pas compris, que se soit avec télégram ou JeedomConnect

merci de ton aide et bon we

Je ne sais pas. Je répondais à @Caelion.
Je n’ai pas vu votre scénario donc peu probable que ma réponse vous soit utile.

Ok merci. je vais ouvrir un autre sujet du coup

bonne journée

Bonsoir Mips,
Comment appeler la fonction dans un bloc code ?
J’avais récupérer cette fonction il y a un moment et j’avais trouvé cela pratique pour éviter de passer entre bloc code puis commande ask en mode visuel puis à nouveau bloc code.
Je veux bien prendre ton conseil :slight_smile:

Pas possible en faite :rofl:

Juste un petit ‹ détail › qui créer une erreur dans la class scenarioExpression lorsque qu’on l’appel en dehors de la class scenario
Je vais faire un PR pour éviter cette erreur.

Edit :

Edit2 :
Validé et testé en Alpha…

3 « J'aime »

Ce sujet a été automatiquement fermé après 24 heures suivant le dernier commentaire. Aucune réponse n’est permise dorénavant.