[TUTO] IFTTT : Puissance 10 V2
Publié : 04 nov. 2018, 22:14
Hello,
Edit 06/01/2019 : Pour info la première chose à faire avant de jouer avec les interactions c'est de désactiver les interactions automatiques qui sont activées par défaut dans la configuration Jeedom, ça évite ensuite beaucoup de comportements et d'actions non voulues ... c'est valable pour l'utilisation de ce tuto mais pas seulement, à partir du moment ou vous voulez utiliser les interactions de quelque façon que ce soit il vaut mieux le désactiver.
Voiçi une évolution du tuto "[TUTO] IFTTT : Avec et sans retour avec sécurisation des délais et astuces via 2 scénarios ..."
viewtopic.php?f=59&t=38301
Cette évolution permet de lancer maintenant des interactions multiples (Maximum 5), exemple :
- Allume la lumière du salon et éteins la cuisine
- Allume le salon et le couloir
- Ouvre les volets du salon et de la cuisine
- Ouvre les volets du salon et ferme les volets de la cuisine
- Ouvre la porte du garage et éteins le bureau
- Ferme la porte d'entrée et passe en mode nocturne et allume le salon
- Ouvre le portail et active l'alarme
- Ferme le garage et ouvre le portail
- ...
La V2 de cette évolution permet maintenant aussi de retravailler les retour lors d'interactions multiples :
J'en parle dans la deuxième partie ...
Cette évolution rassemble maintenant aussi les paramètres importants en début de code comme l'IP de votre jeedom et sa clé API, ainsi il ne faut plus aller les modifier en plein milieu du code.
Toutes les autres fonctionnalités sont évidemment encore supportées :
- Sécurisation des délais des applets IFTTT (pour qu'une demande qui n'a pas aboutie à 13H28 pour cause de perturbation des services google ou IFTTT ne s'exécute pas 3H14 plus tard, comme réouvrir la porte du garage une fois que vous êtes parti ... c'est encore arrivé à plusieurs membres il y a 2 jours)
- Correction de certains défaut de compréhension ou de syntaxe de Google ou d'IFTTT pour maximiser la reconnaissance du moteur d'interaction
- Utilisation avec retour simple IFTTT ou avec un vrai retour Jeedom
- Possibilité de choisir ou non quelle Google home doit effectuer le retour dans le cas d'un retour Jeedom
- Possibilité de s'isoler complètement d'IFTTT en désactivant simplement les scénarios
Prérequis globaux :
- Avoir un accès externe en HTTPS (très vivement conseillé) sur votre jeedom, pour ça il y a les tutos parlants de "let's encrypt" par exemple, si vous utilisez les DNS Jeedom alors pas de soucis, vous êtes déjà en HTTPS
- Avoir un compte IFTTT lié à votre compte Google Home et savoir se servir un minimum d'IFTTT, les tutos de bronche sont une merveille et restent une référence pour acquérir ces bases viewtopic.php?f=59&t=28590
Prérequis pour les retours personnalisés :
- Avoir un système TTS fonctionnel, d'autres tutos donnent toutes les infos pour mettre ça en place via l'excellent plugin "Google Cast" par exemple.
Prérequis pour adapter les commandes :
- Avoir quelques bases en "RegEx", ce format d'expression est également utilisé par jeedom dans son moteur d'interaction, la doc jeedom en parle succinctement, et on trouve des tutos plein le net, l'excellent site https://regexr.com/ permet entre autre de tester ses "RegEx" avant de les implémenter.
Donc reprenons le tuto précédent avec quelques adaptations :
Tout d'abord il faut créer un scénario "provoqué" que l'on va appeler "IFTTT" par exemple
On note l'ID du nouveau scénario car on en aura besoin plus tard pour l'IFTTT
Ensuite on ajoute un bloc de code comme ceci en y collant tout le code qui suit:
(Le code dans le screenshot ne correspond pas car par simple flemme j'ai repris ceux de l'autre tuto ...)
Les paramètres que l'utilisateur est susceptible de devoir adapter sont tous rassemblés en début de script.
Dans cette partie paramètres il ne faut pas oublier de remplacer "VotreIPJeedomLocale" et "VotreCléAPI" par les vôtres sur les deux premières lignes de paramètres .
Ensuite comme la compréhension de google n'est pas toujours parfaite et que certaines incompréhensions sont récurrentes, une liste des remplacements à faire dans la phrase reçue d'IFTTT pour corriger tout ça avant de l'envoyer au moteur d'interaction jeedom est disponible, vous pouvez y ajouter ou y supprimer des éléments en ajoutant des lignes à la suite ou en les commentant avec "//"
Respectez simplement le format
Ensuite pour donner une certaine "intelligence" aux interactions multiples je n'avais pas d'autre choix que de connaitres les principales commandes clés qui vont être utilisée par vos IFTTT et interactions, elles doivent donc être définies aussi en début de code dans la variable $keyCommandsREgEx.
C'est la partie la plus compliquée de ce tuto car comme expliqué dans les prérequis il faut avoir quelques bases en syntaxes RegEx (bases que je n'avais pas moi-même il y a encore 2 heures quand j'ai attaqué cette évolution sur mon installation ...)
Le code est assez largement commenté, et comme les commentaires le stipulent, connaître les commandes clé permet au script de reconstruire 2 ou plusieurs interactions à partir d'une interaction et d'une ou plusieurs autres incomplètes.
En effet, le script va chercher le mot " ET " pour découper une demande en plusieurs interactions et donc une demande du style "allume le salon et la cuisine" résulterait en une demande "allume le salon" et une deuxième demande "la cuisine", et évidemment la deuxième ne marcherais pas. Ce qui marcherait sans ça c'est "allume le salon et allume la cuisine" mais ce n'est pas une façon très naturelle de le demander ...
C'est donc là que les commandes clé au format RegEx entrent en jeux, le script va rechercher une des commandes clé connues dans la première partie de la demande d'interaction pour la mémoriser et l'utiliser ensuite pour reconstruire les interactions suivantes qui elles n'en comporteraient pas.
Évidemment cela n'empêche pas de dire "allume le salon et eteins la cuisine" vu qu'après la découpe en 2 demandes elles ont toutes les deux leur propre commande clé, pour l'une c'est "allume" et pour l'autre "eteins".
Demander "allume la cuisine et le salon et eteins les wc" marchera aussi.
Egalement il est possible de faire des demandes multiples même si leurs commandes clé ne sont pas connues comme par exemple :
"monte le son et coupe le chauffage", comme dans ce script la commande clé "monte" n'est pas connue, elle ne sera pas mémorisée et donc pas non plus utilisée pour compléter la deuxième qui n'a également pas de commande clé connue. Le résultat donnera simplement 2 demandes "monte le son" et "coupe le chauffage".
Il y a évidemment des cas particulier où le script aura du mal à s'en sortir comme par exemple "allume le salon et coupe le chauffage", comme "allume" fait partie des commandes clé connues mais que "coupe" n'en fait pas partie, le résultat va donner "allume le salon" et "allume coupe le chauffage", pour éviter celà il suffit d'ajouter "coupe" aux commandes clé connues.
Ce genre d'adaptation vous devrez les faire vous-même car ça dépend de vos habitudes et de vos propres commandes clé, je ne peux évidemment pas prévoir l'ensemble des possibilités.
Quelques détails sur la première des RegEx déjà incluses dans le code :
Cette RegEx va matcher les commandes suivantes :
- allume
- allumes
- allume la lumiere
- allume les lumieres
- allumes les lumiere
- allumes la lumieres
- allume les lumiere
- allume la lumieres
On voit donc que le pluriel ou le singulier sont sans importance et qu'il est possible de dire "allume" ou "allume la lumiere".
Dans ce cas il était important d'ajouter aussi "allume la lumière" car en ne connaissant que "allume" pour une demande comme "allume les lumières du salon et de la cuisine" ça aurait donné "allume les lumières du salon" et "allume de la cuisine" ce que jeedom aurait peut-être compris quand-même grâce à sa tolérance aux interactions mais pas certain. Si vous ne dites jamais "allume la lumière de ..." mais toujours "allume le ..." cela ne vous sert à rien, une RegEx "(allume)(s)?" était suffisante
Si vous modifiez cette $keyCommandsREgEx faites attention à bien respecter le format à chaque ligne "votreRegEX|". et à conserver le "\i" à la fin qui permet de rendre le RegEx insensible à la case (majuscules/minuscules). Le pipe "|"à la fin de chaque ligne du RegEx est en faite un "ou", j'ai volontairement découpé l'écriture de la RegEx sur plusieurs lignes pour en faciliter la lecture et la manipulation mais il s'agit en fait que d'une seule et même chaîne de caractère qui pourrait être écrite sur une seule ligne mais ça serait beaucoup moins lisible et manipulable.
Je pense avoir déjà mis pas mal de possibilités de RegEx dans ce script mais qui évidemment correspondent à mes interaction habituelles et surtout que je suis susceptible de demander de façon multiple, probablement qu'à l'usage je vais me rendre compte que certaines me manquent, c'est donc une variable qui va évoluer au fur et à mesure de l'évolution de l'installation et de l'usage au jour le jour.
Pour une interaction que vous êtes certain de ne jamais demander combinée à une autre il est évidemment inutile de l'inclure dans les commandes clé.
Ensuite vous trouverez 2 autres listes, une des mots clé au format RegEx à toujours supprimer des retours lors d'interactions multiples et une deuxième des mots clé de vos retours IFTTT au format RegEx que vous ne souhaitez pas voir répétés si l'interaction précédente utilisait déjà le même mais ça j'en parlerais dans la deuxième partie du tuto car cela ne concerne que les interactions avec retour TTS personnalisé et ce n'est pas utile pour les actions avec retour unique d'IFTTT.
Ensuite voici une simple applet IFTTT pour allumer n'importe quoi : Et son webhooks : Dans l'URL on mets cela, en remplaçant le nom de domaine par celui de votre accès externe à jeedom :
On règle la Method et le Content type comme sur l'image
Ensuite on va utiliser dans le body cette commande :
Egalement sans oublier de remplacer "VotreCléAPI" par la votre et "votreIDScenario" par l'ID du scénario créé précédemment.
Et c'est tout, IFTTT va maintenant envoyer la requête avec sa date et heure de création et sa phrase vers le scénario qui va analyser ces données pour éjecter les requêtes qui seraient "périmées", corriger quelques subtils détails dans la phrase pour bien aider le moteur d'interaction comme ça le faisait déjà dans le tuto viewtopic.php?f=59&t=32182#p555834, découper les demandes multiples, les compléter avec une relative intelligence et envoyer les demandes au moteur du core pour que les interaction soit exécutées par jeedom.
Edit 06/01/2019 : Pour info la première chose à faire avant de jouer avec les interactions c'est de désactiver les interactions automatiques qui sont activées par défaut dans la configuration Jeedom, ça évite ensuite beaucoup de comportements et d'actions non voulues ... c'est valable pour l'utilisation de ce tuto mais pas seulement, à partir du moment ou vous voulez utiliser les interactions de quelque façon que ce soit il vaut mieux le désactiver.
Voiçi une évolution du tuto "[TUTO] IFTTT : Avec et sans retour avec sécurisation des délais et astuces via 2 scénarios ..."
viewtopic.php?f=59&t=38301
Cette évolution permet de lancer maintenant des interactions multiples (Maximum 5), exemple :
- Allume la lumière du salon et éteins la cuisine
- Allume le salon et le couloir
- Ouvre les volets du salon et de la cuisine
- Ouvre les volets du salon et ferme les volets de la cuisine
- Ouvre la porte du garage et éteins le bureau
- Ferme la porte d'entrée et passe en mode nocturne et allume le salon
- Ouvre le portail et active l'alarme
- Ferme le garage et ouvre le portail
- ...
La V2 de cette évolution permet maintenant aussi de retravailler les retour lors d'interactions multiples :
J'en parle dans la deuxième partie ...
Cette évolution rassemble maintenant aussi les paramètres importants en début de code comme l'IP de votre jeedom et sa clé API, ainsi il ne faut plus aller les modifier en plein milieu du code.
Toutes les autres fonctionnalités sont évidemment encore supportées :
- Sécurisation des délais des applets IFTTT (pour qu'une demande qui n'a pas aboutie à 13H28 pour cause de perturbation des services google ou IFTTT ne s'exécute pas 3H14 plus tard, comme réouvrir la porte du garage une fois que vous êtes parti ... c'est encore arrivé à plusieurs membres il y a 2 jours)
- Correction de certains défaut de compréhension ou de syntaxe de Google ou d'IFTTT pour maximiser la reconnaissance du moteur d'interaction
- Utilisation avec retour simple IFTTT ou avec un vrai retour Jeedom
- Possibilité de choisir ou non quelle Google home doit effectuer le retour dans le cas d'un retour Jeedom
- Possibilité de s'isoler complètement d'IFTTT en désactivant simplement les scénarios
Prérequis globaux :
- Avoir un accès externe en HTTPS (très vivement conseillé) sur votre jeedom, pour ça il y a les tutos parlants de "let's encrypt" par exemple, si vous utilisez les DNS Jeedom alors pas de soucis, vous êtes déjà en HTTPS
- Avoir un compte IFTTT lié à votre compte Google Home et savoir se servir un minimum d'IFTTT, les tutos de bronche sont une merveille et restent une référence pour acquérir ces bases viewtopic.php?f=59&t=28590
Prérequis pour les retours personnalisés :
- Avoir un système TTS fonctionnel, d'autres tutos donnent toutes les infos pour mettre ça en place via l'excellent plugin "Google Cast" par exemple.
Prérequis pour adapter les commandes :
- Avoir quelques bases en "RegEx", ce format d'expression est également utilisé par jeedom dans son moteur d'interaction, la doc jeedom en parle succinctement, et on trouve des tutos plein le net, l'excellent site https://regexr.com/ permet entre autre de tester ses "RegEx" avant de les implémenter.
Donc reprenons le tuto précédent avec quelques adaptations :
Tout d'abord il faut créer un scénario "provoqué" que l'on va appeler "IFTTT" par exemple
On note l'ID du nouveau scénario car on en aura besoin plus tard pour l'IFTTT
Ensuite on ajoute un bloc de code comme ceci en y collant tout le code qui suit:
(Le code dans le screenshot ne correspond pas car par simple flemme j'ai repris ceux de l'autre tuto ...)
Code : Tout sélectionner
// IFTTT interface V2.0
// ------- Début des paramètres utilisateur -------
$IPJeedom = "VotreIPJeedomLocale";
$APIKey = "VotreCléAPI";
// Liste des remplacements à faire dans la phrase reçue d'IFTTT
// afin de corriger des défauts de comprehension récurents de Google Home
// et de modifier tout ce que vous souhaitez avant que la phrase ne soit
// transmise au moteur d'interaction
$IFTTTReplaceFromTo = [];
$IFTTTReplaceFromTo += [" anvers" => " en vert"]; //Correction de comprehension de Google home
$IFTTTReplaceFromTo += [" sans" => " 100"]; //Correction de comprehension de Google home
$IFTTTReplaceFromTo += [" sens" => " 100"]; //Correction de comprehension de Google home
$IFTTTReplaceFromTo += [" la atelier" => " l'atelier"]; //Correction de comprehension de Google home
$IFTTTReplaceFromTo += [" depuis" => " via "]; //permet de dire "depuis" ou "via" pour cibler la GH de retour
$IFTTTReplaceFromTo += [" dans " => " via "]; //permet de dire "dans" ou "via" pour cibler la GH de retour
// Liste des mots clé de toutes vos interractions IFTTT au format RegEx,
// Permet de recontruire les interractions multiples
// !!! Ne pas utiliser les caractères accentués !!!
// La liste est insensible à la case (majuscules/minuscules)
$keyCommandsREgEx = ("/".
"(allume)(s)?( (la|les) (lumiere)(s)?)?|".
"(etein)(s|t)?( (la|les) (lumiere)(s)?)?|".
"(ouvre)(s)?( (le|les) (volet)(s)?)?|".
"(ferme)(s)?( (le|les) (volet)(s)?)?|".
"(passe)(s)?|".
"(activite)|".
"(reduis)|".
"(augmente)(s)?|".
"(donne-moi l'etat)|".
"(donne-moi la temperature)|".
"(donne-moi l’hygrometrie)|".
"(mode)".
"/i"
);
// Liste des mots clé au format RegEx à toujours supprimer des retours lors d'interactions multiples.
// !!! Les caractères accentués ont leur importance !!! car le code ne supprime pas les accents pour que le TTS les reçoivent.
// La liste est insensible à la case (majuscules/minuscules).
// Il vous suffit de reprendre les différents mots clé que vous utilisez généralement pour marquer le début du retour de vos interactions.
$keyResponsesRemoveRegEx = ("/".
"(ok, )|".
"(très bien, )|".
"(d'accord, )".
"/i"
);
// Liste des mots clé de vos retours IFTTT au format RegEx que vous ne souhaitez pas voir répétés si l'interaction précédente utilisait déjà le même.
// !!! Les caractères accentués ont leur importance !!! car le code ne supprime pas les accents pour que le TTS les reçoivent.
// La liste est insensible à la case (majuscules/minuscules).
// Il vous suffit de reprendre les différentes clé de réponses que vous avez définies dans vos interactions.
$keyResponsesRegEx = ("/".
"(j'allume )( (la|les) (lumiere)(s)?)?|".
"(j'éteins )( (la|les) (lumiere)(s)?)?|".
"(j'ouvre )( (le|les) (volet)(s)?)?|".
"(je ferme )( (le|les) (volet)(s)?)?|".
"(la température )|".
"(il fait )|".
"(l’hygrométrie )".
"/i"
);
// ------- Fin des paramètres utilisateurs-------
$delimiterREgEx = "/ et /i"; // Délimiteur pour interractions multiples au format RegEx
$tags = $scenario->getTags(); // Récupération des tags passés en paramètre.
$scenario->setData("retour_interac","" ,false); //Vide la variable de retour
// Test si le TimeStamp est fourni en tag pour continuer.
if ($tags["#createdat#"]=="") {
$scenario->setLog("Exit, No TimeStamp"); //Log
} else {
// TimeStamp Fourni, on continue
$createdAtString=str_replace('"',"",$tags["#createdat#"]); //Suppression des "" en trop dans le tag
$createdAtTime=DateTime::createfromformat("M d, Y * h:ia", $createdAtString); //Convertion de la chaine IFTTT en DateTime
$scenario->setLog("IFTTT request Created at : ".$createdAtTime->format('Y-m-d H:i:s')); //Log
$actualDateTime=new DateTime(); //Récupération de la date et heure courante
$scenario->setLog("IFTTT request Received at : ".$actualDateTime->format('Y-m-d H:i:s')); //Log
$deltaSecs=$actualDateTime->getTimestamp() - $createdAtTime->getTimestamp(); //Calcul la différence entre les deux DateTime
$scenario->setLog("Elapsed : ".$deltaSecs." sec");//Log
// Test si la requête IFTTT a été faite dans les 90s précédentes
// 90s car IFTTT ne fourni pas les secondes, donc une requète créée à la 59ème seconde et reçue la seconde suivante
// donnera déjà un delta de 60s, +30s de tolérance = 90s
if ($deltaSecs>90) {
$scenario->setLog("IFTTT request too old"); //Log
} else {
// Délai OK, on continue
$scenario->setLog("IFTTT request time OK"); //Log
$scenario->setLog("Received Sentence : ".$tags["#phrase#"]); //Log
//Remplacement des caractères accentués
$a = array('À', 'Á', 'Â', 'Ä', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Î', 'Ï', 'Ô', 'Ö', 'Ù', 'Ú', 'Û', 'Ü', 'à', 'â', 'ç', 'è', 'é', 'ê', 'î', 'ï', 'ô', 'õ', 'ö', 'ù', 'ú', 'û', 'ü');
$b = array('A', 'A', 'A', 'A', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'O', 'O', 'U', 'U', 'U', 'U', 'a', 'a', 'c', 'e', 'e', 'e', 'i', 'i', 'o', 'o', 'o', 'u', 'u', 'u', 'u');
$tags["#phrase#"]=str_replace($a, $b, $tags["#phrase#"]);
// Ajout des corrections indispensables en plus des corrections definies par l'utilisateur
$IFTTTReplaceFromTo += ['"' => ""]; //suppression des "" en trop
$IFTTTReplaceFromTo += [" ' " => "'"]; //remplace " ' " par "'" correction de l'IFTTT
$IFTTTReplaceFromTo += [" - " => "-"]; //remplace " - " par "-" correction de l'IFTTT
// Correction de la phrase IFTTT pour aider les interaction
$tags["#phrase#"]=strtolower($tags["#phrase#"]); //tout en minuscules
$tags["#phrase#"]=str_ireplace(array_keys($IFTTTReplaceFromTo),$IFTTTReplaceFromTo,$tags["#phrase#"]); //effectue tous les remplacements
$scenario->setLog("Corrected Sentence : ".$tags["#phrase#"]); //Log
$scenario->setData("phrase",$tags["#phrase#"] ,false) ; //sauvegarde de la phrase dans une variable pour la suite avant urlencode
$interactArray = preg_split($delimiterREgEx,$tags["#phrase#"],5); //découpe de la phrase pour gerer les interactions multiples, maximum 5 interactions successives
$InteractCount = 0;
$KeyCommandMatches = [];
$LastKeyCommand = "";
$KeyResponsesMatches = [];
$LastKeyResponse = "";
// Traite les interactions multiples
foreach($interactArray as $interact) {
++$InteractCount;
$scenario->setLog("[Interact ".$InteractCount."] : ".$interact); //Log
// Trouve et mémorise la commande clé de l'interaction
if (preg_match ($keyCommandsREgEx, $interact, $KeyCommandMatches)) {
$LastKeyCommand = $KeyCommandMatches[0];
$scenario->setLog("[Interact ".$InteractCount."] - Key command found : ".$LastKeyCommand); //Log
} else {
// Aucune commande clé trouvée, complète avec la dernière commande clé connue
// Cela permet de dire "allume le salon et la cuisine" et de reconstruire deux interractions complètes "allume le salon" et "allume la cuisine"
if ($LastKeyCommand != "") {
$interact = $LastKeyCommand." ".$interact;
$scenario->setLog("[Interact ".$InteractCount."] - Reconstructed with last key command : ".$interact); //Log
}
}
$interactURLFormated=urlencode($interact); //encodage au format URL
//url d'appel interaction
$url="http://".$IPJeedom."/core/api/jeeApi.php?apikey=".$APIKey."&type=interact&query=".$interactURLFormated;
//Exécution et récupération de la réponse des intéractions
$scenario->setLog("[interact ".$InteractCount."] - Send sentence to interact engine"); //Log
$reponseInteract=file_get_contents($url);
$reponseInteract = preg_replace( "/\r|\n/", "", $reponseInteract ); //supprime les CR/LF issus du file_get_contents
$reponseInteract = preg_replace('/\s+/', " ", $reponseInteract ); //supprime les multiples espaces superflus issus du file_get_contents
$reponseInteract = ltrim(rtrim($reponseInteract)); //supprime les espaces en début et fin issus du file_get_contents
$scenario->setLog("[interact ".$InteractCount."] - Received response : ".$reponseInteract); //Log
$reponseInteract=str_replace(".","virgule",$reponseInteract); //remplace le "." par le mot "virgule" pour le retour TTS de valeurs décimales
// Recherhce des réponses clé
$SameKeyResponse = FALSE;
// Trouve et mémorise la réponse clé dans le retour de l'interaction
if (preg_match ($keyResponsesRegEx, $reponseInteract, $KeyResponsesMatches)) {
if ($KeyResponsesMatches[0] == $LastKeyResponse) {
// Réponse clé identique à la précédente
$SameKeyResponse = TRUE;
$scenario->setLog("[Interact ".$InteractCount."] - Same key response found : ".$LastKeyResponse); //Log
} else {
// Réponse clé différente de la précédente
$LastKeyResponse = $KeyResponsesMatches[0];
$SameKeyResponse = FALSE;
$scenario->setLog("[Interact ".$InteractCount."] - New key response found : ".$LastKeyResponse); //Log
}
} else {
// Pas de réponse clé trouvée, on efface la dernière mémorisée
$SameKeyResponse = FALSE;
$LastKeyResponse = "";
$scenario->setLog("[Interact ".$InteractCount."] - No key response found"); //Log
}
// Traitement des strings de réponse
if ($InteractCount == 1) {
$responseString = $reponseInteract; //Ajout de la première réponse à la string de réponse
$responseStringCorrected = $responseString; //Ajout de la première réponse à la string de réponses corrigées
}else {
//Ajout des réponses suivantes à la string de réponse sans traiter les réponses clé
$responseString = $responseString." et ".$reponseInteract;
// Suppression des mots clés à toujours supprimer des réponses suivantes
$reponseInteractCorrected = preg_replace($keyResponsesRemoveRegEx, "", $reponseInteract );
// Vérifie si il faut supprimer aussi la réponse clé
if ($SameKeyResponse == TRUE) {
//Ajoute la réponse suivante à la réponse corrigée en retirant la réponse clé
$responseStringCorrected = $responseStringCorrected." et ".str_replace($LastKeyResponse,"",$reponseInteractCorrected);
$scenario->setLog("[Interact ".$InteractCount."] - key response removed : ".$LastKeyResponse); //Log
}else {
//Ajoute la réponse suivante à la réponse corrigée sans supprimer la réponse clé
$responseStringCorrected = $responseStringCorrected." et ".$reponseInteractCorrected;
}
}
$reponseArray[] = $reponseInteract; //Ajout de la réponse au array de réponses
} //end foreach
//stockage des réponses dans une variable au format string pour post-traitement TTS par le scenario
$scenario->setData("retour_interac",$responseString ,false) ;
$scenario->setLog("All received responses : ".$responseString); //Log
//stockage des réponses corrigées dans une variable au format string pour post-traitement TTS par le scenario
$scenario->setData("retour_interac_corrige",$responseStringCorrected ,false) ;
$scenario->setLog("All received responses corrected : ".$responseStringCorrected); //Log
//stockage des réponses dans une variable au format "array de string" pour post-traitement TTS par le scenario
$scenario->setData("retour_interac_array",$reponseArray ,false) ;
}
}
Dans cette partie paramètres il ne faut pas oublier de remplacer "VotreIPJeedomLocale" et "VotreCléAPI" par les vôtres sur les deux premières lignes de paramètres .
Ensuite comme la compréhension de google n'est pas toujours parfaite et que certaines incompréhensions sont récurrentes, une liste des remplacements à faire dans la phrase reçue d'IFTTT pour corriger tout ça avant de l'envoyer au moteur d'interaction jeedom est disponible, vous pouvez y ajouter ou y supprimer des éléments en ajoutant des lignes à la suite ou en les commentant avec "//"
Respectez simplement le format
Code : Tout sélectionner
$IFTTTReplaceFromTo += ["texte à remplacer" => "texte de remplacement"];
C'est la partie la plus compliquée de ce tuto car comme expliqué dans les prérequis il faut avoir quelques bases en syntaxes RegEx (bases que je n'avais pas moi-même il y a encore 2 heures quand j'ai attaqué cette évolution sur mon installation ...)
Le code est assez largement commenté, et comme les commentaires le stipulent, connaître les commandes clé permet au script de reconstruire 2 ou plusieurs interactions à partir d'une interaction et d'une ou plusieurs autres incomplètes.
En effet, le script va chercher le mot " ET " pour découper une demande en plusieurs interactions et donc une demande du style "allume le salon et la cuisine" résulterait en une demande "allume le salon" et une deuxième demande "la cuisine", et évidemment la deuxième ne marcherais pas. Ce qui marcherait sans ça c'est "allume le salon et allume la cuisine" mais ce n'est pas une façon très naturelle de le demander ...
C'est donc là que les commandes clé au format RegEx entrent en jeux, le script va rechercher une des commandes clé connues dans la première partie de la demande d'interaction pour la mémoriser et l'utiliser ensuite pour reconstruire les interactions suivantes qui elles n'en comporteraient pas.
Évidemment cela n'empêche pas de dire "allume le salon et eteins la cuisine" vu qu'après la découpe en 2 demandes elles ont toutes les deux leur propre commande clé, pour l'une c'est "allume" et pour l'autre "eteins".
Demander "allume la cuisine et le salon et eteins les wc" marchera aussi.
Egalement il est possible de faire des demandes multiples même si leurs commandes clé ne sont pas connues comme par exemple :
"monte le son et coupe le chauffage", comme dans ce script la commande clé "monte" n'est pas connue, elle ne sera pas mémorisée et donc pas non plus utilisée pour compléter la deuxième qui n'a également pas de commande clé connue. Le résultat donnera simplement 2 demandes "monte le son" et "coupe le chauffage".
Il y a évidemment des cas particulier où le script aura du mal à s'en sortir comme par exemple "allume le salon et coupe le chauffage", comme "allume" fait partie des commandes clé connues mais que "coupe" n'en fait pas partie, le résultat va donner "allume le salon" et "allume coupe le chauffage", pour éviter celà il suffit d'ajouter "coupe" aux commandes clé connues.
Ce genre d'adaptation vous devrez les faire vous-même car ça dépend de vos habitudes et de vos propres commandes clé, je ne peux évidemment pas prévoir l'ensemble des possibilités.
Quelques détails sur la première des RegEx déjà incluses dans le code :
Code : Tout sélectionner
(allume)(s)?( (la|les) (lumiere)(s)?)?
- allume
- allumes
- allume la lumiere
- allume les lumieres
- allumes les lumiere
- allumes la lumieres
- allume les lumiere
- allume la lumieres
On voit donc que le pluriel ou le singulier sont sans importance et qu'il est possible de dire "allume" ou "allume la lumiere".
Dans ce cas il était important d'ajouter aussi "allume la lumière" car en ne connaissant que "allume" pour une demande comme "allume les lumières du salon et de la cuisine" ça aurait donné "allume les lumières du salon" et "allume de la cuisine" ce que jeedom aurait peut-être compris quand-même grâce à sa tolérance aux interactions mais pas certain. Si vous ne dites jamais "allume la lumière de ..." mais toujours "allume le ..." cela ne vous sert à rien, une RegEx "(allume)(s)?" était suffisante
Si vous modifiez cette $keyCommandsREgEx faites attention à bien respecter le format à chaque ligne "votreRegEX|". et à conserver le "\i" à la fin qui permet de rendre le RegEx insensible à la case (majuscules/minuscules). Le pipe "|"à la fin de chaque ligne du RegEx est en faite un "ou", j'ai volontairement découpé l'écriture de la RegEx sur plusieurs lignes pour en faciliter la lecture et la manipulation mais il s'agit en fait que d'une seule et même chaîne de caractère qui pourrait être écrite sur une seule ligne mais ça serait beaucoup moins lisible et manipulable.
Je pense avoir déjà mis pas mal de possibilités de RegEx dans ce script mais qui évidemment correspondent à mes interaction habituelles et surtout que je suis susceptible de demander de façon multiple, probablement qu'à l'usage je vais me rendre compte que certaines me manquent, c'est donc une variable qui va évoluer au fur et à mesure de l'évolution de l'installation et de l'usage au jour le jour.
Pour une interaction que vous êtes certain de ne jamais demander combinée à une autre il est évidemment inutile de l'inclure dans les commandes clé.
Ensuite vous trouverez 2 autres listes, une des mots clé au format RegEx à toujours supprimer des retours lors d'interactions multiples et une deuxième des mots clé de vos retours IFTTT au format RegEx que vous ne souhaitez pas voir répétés si l'interaction précédente utilisait déjà le même mais ça j'en parlerais dans la deuxième partie du tuto car cela ne concerne que les interactions avec retour TTS personnalisé et ce n'est pas utile pour les actions avec retour unique d'IFTTT.
Ensuite voici une simple applet IFTTT pour allumer n'importe quoi : Et son webhooks : Dans l'URL on mets cela, en remplaçant le nom de domaine par celui de votre accès externe à jeedom :
Code : Tout sélectionner
https://votreNomDeDomaine/core/api/jeeApi.php
Ensuite on va utiliser dans le body cette commande :
Code : Tout sélectionner
apikey=VotreCléAPI&type=scenario&id=votreIDScenario&action=start&tags=createdat%3D"{{CreatedAt}}"%20phrase%3D"allume {{TextField}}"
Et c'est tout, IFTTT va maintenant envoyer la requête avec sa date et heure de création et sa phrase vers le scénario qui va analyser ces données pour éjecter les requêtes qui seraient "périmées", corriger quelques subtils détails dans la phrase pour bien aider le moteur d'interaction comme ça le faisait déjà dans le tuto viewtopic.php?f=59&t=32182#p555834, découper les demandes multiples, les compléter avec une relative intelligence et envoyer les demandes au moteur du core pour que les interaction soit exécutées par jeedom.