Helper à 2 dimensions

Bonjour,

Transfuge de Jeedom, j’aurai besoin de déclarer des helpers en 2 dimensions :
Message = Texte, Rang
Ex : MsgPpe = « Pompe en défaut », 1
Explication : si le rang vaut 1, le TTS est émis, et je positionne le rang à 200.
Toutes les 1/2h j’ai un rappel de tout les message xxxxxx,200
SI la pompe n’est plus en défaut, le rang est positionné à 0
Ma question est comment déclarer ces helpers
Merci

Salut,

Comme ça moi j’ai pas vraiment compris le besoin.
Au delà de la description, attention à éviter de « dupliquer » ce que fait jeedom… il y a certainement moyen de faire autrement, voire mieux. D’où l’intérêt de repartir du besoin.

1 « J'aime »

Salut
Je pensais avoir été clair :grin:
J’ai une vingtaine de défaut, et je souhaite les annoncer en TTS : A l’apparition, et ensuite toute les 1/2h si toujours présent.
Pour cela j’avais des variables à 2 dimensions pour chaque défaut :
Edit : 3 dimensions : Etat, Texte de l’annonce , Répétition (200=Oui 0=Non)
ou « Répétition » valait 0 si pas de défaut, 1 lorsque le défaut apparait et 200 un fois que le TTS a été dit la première fois.

Pour cela sous Jeedom, j’avais 2 scénarios. Le premier pour traiter l’apparition :

$TotalMsg = 0;
$Annonce = "";
$Debug = false;	// Permet d'activer les log de Debug - true ou false
//$tags = $scenario->getTags();
//$Google = $tags["#destination#"];
$Parle = $scenario->getData('Ok_Parle');
if ($Parle == 1) {
    #récupération des défauts présents  (Etat, Texte de l'annonce , Répétition (200=Oui 0=Non))
    $Msg = array(
      array($scenario->getData('Msg_Pompe'), "La pompe filtration piscine est en défaut. ", 200),
      array($scenario->getData('Msg_Portail'), "Fermeture automatique du portail échouée. ", 200),
      array($scenario->getData('Msg_Garage'), "Le garage est resté ouvert. ", 200),
      array($scenario->getData('Msg_Poubelles'), "Pensez à sortir la poubelle. ", 0),
      array($scenario->getData('Msg_Congel_Buanderie'), "La température du congélateur de la buanderie est trop élevée. ", 200),
      array($scenario->getData('Msg_Déshumidificateur'), "Pensez à vider le déshumidificateur de la salle de cinéma. ", 200),	
      array($scenario->getData('Msg_MaL'), "La machine à laver est terminée. ", 0),	
      array($scenario->getData('Msg_Piscine_Haute'), "Le niveau de la piscine est trop haut. Pensez à la vider. ", 200),
      array($scenario->getData('Msg_Piscine_Basse'), "Le niveau de la piscine est trop bas. Pensez à la remplir. ", 200),
      array($scenario->getData('Msg_Piscine_Clapet'), "Le niveau de la piscine est anormal. Pensez à vérifier les clapets. ", 200),
      array($scenario->getData('Msg_Forage'), "La pompe du forage est en défaut. ", 200),
      array($scenario->getData('Msg_Bureau'), "La fenetre du bureau est restée ouverte. ", 200),
      array($scenario->getData('Msg_Ballon'), "Vérifiez la pression du ballon du forage.  ", 200),
      array($scenario->getData('Msg_Batterie_Piscine'), "Pensez à recharger la batterie de l'analyseur de la piscine. ", 200), 
      array($scenario->getData('Msg_Fenetres'), "Une fenetre est ouverte depuis plus de 15 minutes. ", 200),   
      array($scenario->getData('Msg_Justin_Batterie0'), "Tonte terminée. La batterie de Justin est vide. Retour à la base demandé. ", 200),
      array($scenario->getData('Msg_Justin_Batterie100'), "La batterie de Justin est rechargée. ", 0),      
      array($scenario->getData('Msg_Justin'), "Justin est en erreur et demande une intervention manuelle. ", 200),         
      array($scenario->getData('Msg_Justine_Batterie0'), "Tonte terminée. La batterie de Justine est vide. Retour à la base demandé. ", 200),
      array($scenario->getData('Msg_Justine_Batterie100'), "La batterie de Justine est rechargée. ", 0),      
      array($scenario->getData('Msg_Justine'), "Justine est en erreur et demande une intervention manuelle. ", 200),
      array($scenario->getData('Msg_Garage2'), "Le garage ne s'est pas fermé.", 200), 
      array($scenario->getData('Msg_Frigo_Cuisine'), "La température du congélateur de la cuisine est trop élevée. ", 200),    
    );

    # Test si défaut à annoncer
    for ($i=0; $i<count($Msg); $i++) { 
      if($Msg[$i][0] == 1) {   
        $TotalMsg = $TotalMsg + 1;
        $Annonce = $Annonce. $Msg[$i][1];
        //$scenario->setData('Msg_Journal',$Msg[$i][1]); # Archivage dans journal
        $scenario->setLog($Msg[$i][1]);
      }
      $Msg[$i][2] = $Msg[$i][0] * $Msg[$i][2];
      //$scenario->setLog($Msg[$i][1] ." Ancienne valeur = " .$Msg[$i][0] ."      Nouvelle valeur = " .$Msg[$i][2]);      
    }
    # Test si message à annoncer
    $MsgInst = $scenario->getData('Msg_Instantané');
    if (strlen($MsgInst)>1) {
      	$TotalMsg = $TotalMsg + 1;
      	$Annonce = $Annonce. $MsgInst;
    }

	# Annonce du message en vocal
	if ($TotalMsg > 0) {
      	if ($Debug == false) {
			//**************** Emission du message ************************
			$tags['#qui#'] = "cuisine";
			$tags['#texte#'] = $Annonce;
			$scenario = scenario::byString('#[Informations][Notifications][Parle]#');
			$scenario->setTags($tags);
			$scenario->launch();
        	$scenario->setLog("Message = " .$Annonce);
        }     
		# MAJ des variables du scénario
		$scenario->setData('Msg_Pompe',$Msg[0][2]);
		$scenario->setData('Msg_Portail',$Msg[1][2]);
		$scenario->setData('Msg_Garage',$Msg[2][2]);
		$scenario->setData('Msg_Poubelles',$Msg[3][2]);
		$scenario->setData('Msg_Congel_Buanderie',$Msg[4][2]);
		$scenario->setData('Msg_Déshumidificateur',$Msg[5][2]);
		$scenario->setData('Msg_MaL',$Msg[6][2]);
		$scenario->setData('Msg_Piscine_Haute',$Msg[7][2]);
		$scenario->setData('Msg_Piscine_Basse',$Msg[8][2]);
		$scenario->setData('Msg_Piscine_Clapet',$Msg[9][2]);
		$scenario->setdata('Msg_Forage',$Msg[10][2]);
		$scenario->setdata('Msg_Bureau',$Msg[11][2]);
		$scenario->setdata('Msg_Ballon',$Msg[12][2]);
      	$scenario->setdata('Msg_Batterie_Piscine',$Msg[13][2]);
      	$scenario->setdata('Msg_Fenetres',$Msg[14][2]);    
        $scenario->setdata('Msg_Justin_Batterie0',$Msg[15][2]);
        $scenario->setdata('Msg_Justin_Batterie100',$Msg[16][2]);      
      	$scenario->setdata('Msg_Justin',$Msg[17][2]);
        $scenario->setdata('Msg_Justine_Batterie0',$Msg[18][2]);
        $scenario->setdata('Msg_Justine_Batterie100',$Msg[19][2]);      
      	$scenario->setdata('Msg_Justine',$Msg[20][2]);
      	$scenario->setdata('Msg_Garage2',$Msg[21][2]); 
        $scenario->setData('Msg_Frigo_Cuisine',$Msg[22][2]);
		$scenario->setData('Msg_Instantané', "");
	}
}

Et un second pour les répétitions :

$TotalMsg = 0;
$Valeur = array();
$Debug = false;	// Permet d'activer les log de Debug - true ou false
# Récupération des défauts présents
$Valeur[0] = $scenario->getData('Msg_Pompe');
$Valeur[1] = $scenario->getData('Msg_Portail');
$Valeur[2] = $scenario->getData('Msg_Garage');
$Valeur[3] = $scenario->getData('Msg_Poubelles');
$Valeur[4] = $scenario->getData('Msg_Congel_Buanderie');
$Valeur[5] = $scenario->getData('Msg_Déshumidificateur');
$Valeur[6] = $scenario->getData('Msg_MaL');
$Valeur[7] = $scenario->getData('Msg_Piscine_Haute');
$Valeur[8] = $scenario->getData('Msg_Piscine_Basse');
$Valeur[9] = $scenario->getData('Msg_Piscine_Clapet');
$Valeur[10] = $scenario->getdata('Msg_Forage');
$Valeur[11] = $scenario->getdata('Msg_Bureau');
$Valeur[12] = $scenario->getdata('Msg_Ballon');
$Valeur[13] = $scenario->getdata('Msg_Batterie_Piscine');
$Valeur[14] = $scenario->getdata('Msg_Fenetres');
$Valeur[15] = $scenario->getdata('Msg_Justin_Batterie0');
$Valeur[16] = $scenario->getdata('Msg_Justin_Batterie100');
$Valeur[17] = $scenario->getdata('Msg_Justin');
$Valeur[18] = $scenario->getData('Msg_Garage2');
$Valeur[19] = $scenario->getdata('Msg_Gardena');
$Valeur[20] = $scenario->getData('Msg_Frigo_Cuisine');

// ********** Défaus inhibés **********
$Valeur[7] = 0;
$Valeur[8] = 0;
$Valeur[9] = 0;
// ************************************

# Test si défaut à répéter
for ($i=0; $i<count($Valeur); $i++) {
    if ($Debug) { $scenario->setLog(':: DEBUG :: Valeur avant ' . $i .' = ' .$Valeur[$i]); }
	if ($Valeur[$i] == 1 or $Valeur[$i] == 200) {
		$Valeur[$i] = 1;           # Message à répéter				
		$TotalMsg = $TotalMsg + 1;
	}
    if ($Debug) { $scenario->setLog(':: DEBUG :: Valeur apres ' . $i .' = ' .$Valeur[$i]); }
}
if ($Debug) { $scenario->setLog(':: DEBUG :: Nombre = ' .$TotalMsg); }
if ($TotalMsg > 0 and $Debug == false) {
	# MAJ des variables du scénario
	$scenario->setData('Msg_Pompe',$Valeur[0]);
	$scenario->setData('Msg_Portail',$Valeur[1]);
	$scenario->setData('Msg_Garage',$Valeur[2]);
	$scenario->setData('Msg_Poubelles',$Valeur[3]);
	$scenario->setData('Msg_Congel_Buanderie',$Valeur[4]);
	$scenario->setData('Msg_Déshumidificateur',$Valeur[5]);
	$scenario->setData('Msg_MaL',$Valeur[6]);
	$scenario->setData('Msg_Piscine_Haute',$Valeur[7]);
	$scenario->setData('Msg_Piscine_Basse',$Valeur[8]);
	$scenario->setData('Msg_Piscine_Clapet',$Valeur[9]);
	$scenario->setdata('Msg_Forage',$Valeur[10]);
	$scenario->setdata('Msg_Bureau',$Valeur[11]);
	$scenario->setdata('Msg_Ballon',$Valeur[12]);
  	$scenario->setdata('Msg_Batterie_Piscine',$Valeur[13]);
    $scenario->setdata('Msg_Fenetres',$Valeur[14]);
    $scenario->setdata('Msg_Justin_Batterie0',$Valeur[15]);
    $scenario->setdata('Msg_Justin_Batterie100',$Valeur[16]);
    $scenario->setdata('Msg_Justin',$Valeur[17]);
	$scenario->setData('Msg_Garage2',$Valeur[18]);
    $scenario->setdata('Msg_Gardena',$Valeur[19]);
    $scenario->setData('Msg_Frigo_Cuisine',$Valeur[20]);
}

J’aimerais faire l’équivalent sur HA

Pas pour moi en tout cas.
Là on dirait que tu t’es mis une sorte de base de messages pour tes notifications.
Mais bon c’et pas beaucoup plus clair quand même.

Ce qui est certain, c’est que là tu veux reproduire ce que fait jeedom.

Ce que je souhaite c’est annoncer le défaut à l’apparition, puis toutes les 1/2 heure si toujours présent.

Je cherche une solution pour faire cela avec HA, et je ne vois pas comment le coder.
Je suis prêt à faire un script pour chaque message si besoin.

Annoncer un message toutes les 1/2 c’est pas un souci en soit, mais ça n’explique pas l’ensemble de ce tu as fait.
Par exemple ton besoin pourrais être : tu as un liste qui mémorise toutes les erreurs, cette liste est mise à jour, quand l’erreur arrive et nettoyée quand l’erreur disparait. Toutes les 1/2 heures la liste est parcourue et les erreurs en cours annoncées avec un tableau de correspondance : SI CODE = 123 alors MESSAGE = « Erreur du pompe.. »

ça c’est un besoin . Et encore, c’est trop précis parce que ça explique déjà un peu le fonctionnement technique (liste, parcours etc).

Et donc comment la liste constitue etc (qui vérifie quoi) c’est aussi un autre besoin.

Accessoirement un helper de type input_text avec un contenu en JSON c’est un truc à N dimensions

1 « J'aime »

Et si…. tu passes par une automation ou tu définis les triggers de déclenchements (basés sur un state) à qui tu associe une id et ensuite en fonction du déclencheur/id tu mets en place des actions : message tts, init d’un binary_sensor à on pour flagger l’alerte …?

Il y a aussi surement une opportunité de regarder la partie scripts ?

Et en prime cet article pour démarrer avec les automations:

Olci

je me demande si avec un sensor template ça ne serait pas jouable

tu peux créer des sensors avec un état et des attributs

mais tu devras créer autant de sensors que tu as de device
mais d’apres ton script tu as utilisé la meme méthode pas que pûr ta pompe et ça fait clairement du boulot

mais je pense que c’est pas la bonne méthode et en fait je ne vois pas l’interet de ces 2 dimensions, tu a en fait juste un device qui a un état 0,1,200 en fait tu dois juste créer autant de helpers (entréesà que tu as de device avec un choix d’un de ces 3 états

en fait comme l’a dit @Pulpy-Luke vouloir refaire a l’identique ce que tu as dans jeedom c’est souvent une mauvaise idée

Ou tu fais une entité avec tous tes défauts en attribut, un pour chaque défaut et une autom qui les balaie toute les 30 min et qui check ceux qui sont a 1

Honnêtement je ne vois pas en quoi les solutions proposées ne sont pas suffisantes pour faire une notification avec des répétitions…

Il est très simple de faire une automatisation qui:

  • s’active à l’apparition d’un défaut pour notifier le nouveau défaut.
  • s’active toutes les 1/2h pour notifier tous les défauts « actifs ».

Sans avoir besoin de gérer un truc par défaut qui trace son activité…

Pour simplifier le code, passer un script de notif avec des paramètres, c’est la base, tu as des tas d’exemples sur le forum ou sur le portail.

Et sinon pour une liste à trois état (type de notif par exemple) un helper / Entrée de type liste déroulante est très bien… Voir par exemple la dernière video du Journal de Thomas: [YOUTUBE] Les Entrées dans Home Assistant ou attendre le 3eme article sur les automatisations (autopromo honteuse et assumée :rofl:)

Une liste déroulante pour chaque défaut avec l’état (OK, en défaut, en défaut déjà notifié) et tu viens tester sur l’état comme dit plus haut… Une etiquette défaut sur chacune de ces listes. Un trigger par cible comme il sera décrit dans l’article 2 sur les automatisations qui devrait sortir le 30/01 (autopromo honteuse et assumée suite :rofl:)…

2 « J'aime »

Ca me rappelle aussi beaucoup le piège du problème XY !

2 « J'aime »

Salut
Merci pour vos réponses. Du coup j’ai revu ma copie, et j’ai géré ça différemment.

  1. Je positionne un input_boolean (un par message ) lors de l’apparition du défaut
  2. Quand les conditions pour le TTS sont remplies (Présence dans la cuisine, pas la nuit, …), si la mémoire de ce message est off, je lis le TTS et je positionne un second input_boolean (mémoire pour le dire une seule fois)

A la disparition du defaut je remet les 2 input_boolean à off

En plus toutes les 1/2h je mets toutes les mémoire à off pour relancer le TTS

1 « J'aime »

A ce moment là pourquoi utiliser X input_boolean pour les X défauts ?

Tu fais une automatisation qui se lance toutes 1/2 heures.
Qui lit les défauts en live, vérifie tes conditions (présence etc) et les annonce … Quand le ou les défauts disparaissent, plus d’annonce.
Tu ajoutes un trigger en parallèle sur cette même automatisation pour l’exécuter dès ton arrivée.

Et si tu veux un vrai créneau de 30 minutes entre 2 annonces, un timer de 30 minutes que tu lances à la fin (prochain tour 30min après ton retour), il sert de trigger à la place d’un prog toutes les 1/2 heure…

Une trame de mon ami gemini à adapter/tester

alias: Annonce dynamique des défauts
description: Annonce vocale toutes les 30 min ou au retour si des défauts persistent

# --- LE DÉCLENCHEMENT ---
triggers:
  - entity_id: device_tracker.ton_telephone
    to: home
    id: presence        # Trigger 1 : Tu rentres à la maison
    trigger: state
  - event_type: timer.finished
    event_data:
      entity_id: timer.rappel_defauts
    id: rappel          # Trigger 2 : Les 30 minutes sont écoulées
    trigger: event

# --- LA SÉCURITÉ ---
conditions:
  - condition: state
    entity_id: device_tracker.ton_telephone
    state: home         # On ne continue que si tu es physiquement là (utile pour le trigger 'rappel')

# --- LE CŒUR LOGIQUE ---
actions:
  # 1. On scanne les capteurs et on crée une liste textuelle
  - variables:
      liste_defauts: >
        {% set d = [] %} 
        {% if is_state('binary_sensor.porte_garage', 'on') %} {% set d = d + ['la porte du garage'] %} {% endif %} 
        {% if is_state('binary_sensor.fuite_eau', 'on') %} {% set d = d + ["une fuite d'eau"] %} {% endif %} 
        {{ d }}

  # 2. Ton "IF" : Est-ce qu'on doit parler ?
  - if:
      - condition: template
        value_template: "{{ liste_defauts | count > 0 }}" # S'il y a au moins 1 défaut dans la liste
    then:
      - target:
          entity_id: media_player.salon
        data:
          message: >-
            Attention, il y a un problème avec : {{ liste_defauts | join(' et ') }}.
        action: tts.google_say

  # 3. La relance de la boucle
  - target:
      entity_id: timer.rappel_defauts
    data:
      duration: "00:30:00"
    action: timer.start
mode: restart # Si tu rentres pendant que le timer tourne, on reset tout et on recommence.
1 « J'aime »

Ce sujet a été automatiquement fermé après 2 jours. Aucune réponse n’est permise dorénavant.