Détecter coupure et arrêt de l'alimentation électrique via Lixee.Zlinky

Bonjour,

Je voudrais mettre en place une détection de coupure/retour du courant dans l’installation en passant par la surveillance du module Zlinky qui est par définition le 1er périphérique domotique derrière le compteur EDF.
J’ai vu des solutions basées sur la surveillance des onduleurs si ceux-ci sont connectés et remontent leurs statuts ou d’autres basées sur des ping d’équipements réseaux non secourus.

Le prérequis étant que Jeedom et son controleur Zigbee soient sous onduleur, je voudrais pour ma part essayer de tirer parti des évenements qui remontent dans le centre de message après avoir configuré une alerte communications sur le Lixee.


En cas de perte de communications, ce qui devrait être le cas avec une coupure EDF, il va y avoir un message du core spécifique au Lixee logué dans le centre de messages.
Je ne sais pas comment intercepter ce message pour déclencher un scénario. Quelqu’un aurait-il le début d’une piste ?
Idem pour la partie retour, comment détecter le retour ?
En variante, il y aurait aussi la date de dernière communication. De ce que j’ai compris, il y a 2 champs qui portent le même nom, celui qui est visible dans configuration avancée du périphérique et celui dans la colonne Dernière communication dans l’onglet Noeuds de la fenêtre réseaux Zigbee. Le plus à jour étant ce dernier. Mais dans le cas du Lixee, les valeurs sont très proches, donc accéder à l’une ou à l’autre pourrait le faire. Comment récupérer ses valeurs ?

Merci pour votre aide.

Bonjour,
Si ton Jeedom est derrière un onduleur et s’il dispose d’un port USB par exemple, tu peut le superviser, lui peut te donner la coupure de courant / retour en temps réel.
Il faut le plungin NUT et gérer d’une façon ou d’une autre, la supervision.
Perso, j’ai 4 onduleurs qui sont monitorés avec des alertes temps réel en cas de coupures de courant …

1 « J'aime »

Bonjour, il est tout a fait possible « d’intercepter » ce message, il suffit de configurer cette option dans la configuration :

Ensuite dans le scénario :

Bon dimanche.

2 « J'aime »

J’ai bien une poignée d’onduleurs, mais ceux qui sont communiquant sont derrières des machines Windows dont un serveur Hyper-V toujours allumé. Il faudrait que je trouve un agent qui tourne sous Windows 2022 et qui sache remonter son info vers la machine Jeedom. Les onduleurs avec USB sont des MERLIN GERIN Protection Center 675 USB.
Je pourrais aussi faire un jeu de chaises musicales et échanger de place certains onduleurs, mais sous Windows, ça me fera chuter la durée de la batterie, mes onduleurs non manageables étant les plus faibles.
De plus, le fait de monitorer les onduleurs me dira juste qu’il n’y a plus de courant sur le disjoncteur dont l’onduleur dépend. Des fois, j’ai des disjoncteurs qui sautent au retour du courant. Le lixee étant le plus près du compteur, c’est lui qui indique à coup sûr si EDF est ko ou pas.

Phpvarious, merci de ton intérêt pour ma question. Par contre, tu m’as perdu au second bloc si de ton scénario. Tu utilises jMQTT que je n’ai pas installé. Je pourrais l’installer mais je ne le connais pas et je vais devoir sortir les rames.
De plus, en utilisant ta solution, est-on capable de détecter le retour du courant ?
Je pense qu’idéalement, il faudrait pouvoir accéder à la valeur de Dernier message dans l’information du noeud


Car celle-ci n’est pas exploitable :
image

En faite le 1er Bloc Si permet de savoir si le message est de type « timeout », on pourrait aussi très bien imaginer le même scénario qui gèrerait aussi un warning …

Ensuite le second SI permet simplement de filtrer l’équipement qui est en timeout, j’ai mis un équipement d’exemple. mais pour ta part il faudra remplacer par ton équipement [piece][LiXee.ZLinky]

Non, pas possible avec cette exemple, mais sinon a l’aide d’un scénario (bloc code) et une variable (ou virtuel) , il est tout a fait possible d’arriver a tes fins. Mais celui-ci sera un peu plus complexe.

Si tu as plusieurs onduleurs, il faut en dédier un à Jeedom (pour le monitoring)
Ensuite, lorsqu’il y a une coupure de courant, l’onduleur déclenche un scenario (via NUT et une API sur Jeedom).
Du coup, tu as en temps réel l’état électrique de ton installation

Merci. J’ai capté pour le scenario. J’ai pas besoin de jMQTT.
Par contre, c’est vraiment le retour qui m’intéresse, car il faut que j’allume et éteigne une pelletée d’équipements qui ne conservent pas leur dernier état en cas de coupure.

Je te propose donc un bloc code :

  • déclencheur programmé.
Bloc code
$eqLogicId = 25; // id de l'équipement a surveiller

$eqLogic = eqLogic::byId($eqLogicId);
$tags['#timeout#'] = -1;
if (is_object($eqLogic)){
  $varStatus = $scenario->getData('timeout'.$eqLogicId,0);
  $prevStatus = $eqLogic->getStatus('timeout', 0);
  if ($prevStatus == 1 && $varStatus == 0) {
    $tags['#timeout#'] = 1;
    $scenario->setData('timeout'.$eqLogicId, 1);
  }
  else if ($prevStatus == 0 && $varStatus == 1) 
  {
    $tags['#timeout#'] = 0;
    $scenario->setData('timeout'.$eqLogicId, 0);
  }
}
$scenario->setTags($tags);

Celui-ci utilise une variable Jeedom, mais on peut très bien imaginer l’utilisation d’un virtuel.

1 « J'aime »

Merci à toi Phpvarious.
J’ai mis en place ton scenario.
Dans ton code, est-ce l’expression is_object($eqlogic)) qui permet de savoir si l’objet est toujours joignable ?
J’ai modifié un peu le code pour m’y retrouver avec tous ces timeout, n’étant pas familier avec ce langage.
Timeout_de_.$eqLogicId = la variable qui est définie dans Jeedom par ce scenario pour cet équipement (exemple ligne 6)
#timeout# = tag = « variable » dont la portée est uniquement dans le scenario (ligne 4)
timeout = valeur du timeout défini dans l’équipement (ligne 7)

$eqLogicId = 1509; // id de l'équipement a surveiller

$eqLogic = eqLogic::byId($eqLogicId);
$tags['#timeout#'] = -1;
if (is_object($eqLogic)){
  $varStatus = $scenario->getData('Timeout_de_'.$eqLogicId,0);
  $prevStatus = $eqLogic->getStatus('timeout', 0);
  if ($prevStatus == 1 && $varStatus == 0) {
    $tags['#timeout#'] = 1;
    $scenario->setData('Timeout_de_'.$eqLogicId, 1);
  }
  else if ($prevStatus == 0 && $varStatus == 1) 
  {
    $tags['#timeout#'] = 0;
    $scenario->setData('Timeout_de_'.$eqLogicId, 0);
  }
}
$scenario->setTags($tags);

Afin de mieux comprendre et suivre l’évolution des variables, comment fait-on pour forcer l’écriture du nom et du contenu des variables dans le log du scenario ?

$scenario->setLog("Status: $varStatus Précédent: $prevStatus");

Merci jpty.

$eqLogicId = 1509; // id de l'équipement a surveiller

$eqLogic = eqLogic::byId($eqLogicId);
$tags['#timeout#'] = -1;
//$Nom =  $eqLogic->getHumanName();
$Nom =  $eqLogic->getName();
$scenario->setLog("Equipement : $eqLogicId - $Nom");
if (is_object($eqLogic)){
  $varStatus = $scenario->getData('Timeout_de_'.$eqLogicId,0);
  $prevStatus = $eqLogic->getStatus('timeout', 0);
  $scenario->setLog("Status: $varStatus Précédent: $prevStatus");
  if ($prevStatus == 1 && $varStatus == 0) {
    $tags['#timeout#'] = 1;
    $scenario->setData('Timeout_de_'.$eqLogicId, 1);
  }
  else if ($prevStatus == 0 && $varStatus == 1) 
  {
    $tags['#timeout#'] = 0;
    $scenario->setData('Timeout_de_'.$eqLogicId, 0);
  }
}
$scenario->setTags($tags);

Question basique : on doit obligatoirement mettre dans une variable le résultat d’une commande pour l’afficher dans le log comme j’ai fait avec $Nom ? Il n’y a pas moyen de faire le setlog suivi de la bonne syntaxe pour écrire le getName() sans devoir créer une variable ?

Et n’y aurait-il pas une inversion des noms de variables ?
$varStatus = $scenario->getData(‹ Timeout_de_ ›.$eqLogicId,0); → C’est bien la variable qui est écrite dans Jeedom à la fin du script ? Si oui, c’est donc elle la précédente, non ?
$prevStatus = $eqLogic->getStatus(‹ timeout ›, 0); → valeur du timeout à l’instant t = status ?

J’ai trouvé une version serveur de NUT pour Windows, mais c’est très peu documenté pour arriver à la mettre en place proprement.
Serveur NUT sous Windows
C’est en allemand, j’essaye de comprendre mais je ne le pratique pas. Je suis arrivé à démarrer le service sous Windows mais pour l’instant rien de plus, je ne sais comment accéder aux infos déjà sous Windows… Alors, à distance via un plugin Nut ou Nut_Free…

Hello, je remet le même style de scénario, mais celui-ci un peu plus parlant dans les commentaires et les log en espérant que sa puisse t’aider dans la compréhension de celui-ci :

Bloc code
$eqLogicId = 25; // id de l'équipement a surveiller

$scenario->setLog('┌─────────────────── [ DEBUT BLOC CODE ] ───────────────────'); // log scénario
$eqLogic = eqLogic::byId($eqLogicId); // appel de la class eqLogic
$tags['#timeout#'] = -1; // on initie le tag a -1
if (is_object($eqLogic)){ // on verifie si l'eqLogic existe bien
  $scenario->setLog('| Verification de Timeout pour l\'équipement : '.$eqLogic->getHumanName().' (id = '.$eqLogic->getId().')'); // log scénario
  $varStatus = $scenario->getData('timeout'.$eqLogicId,0); // on récupère la variable Jeedom (si elle existe pas, on l'initie a 0)
  $eqStatus = $eqLogic->getStatus('timeout', 0); // on récupère l'état du timeout de l'équipement (empty ou 0 = ok, 1 = en timeout)
  
  if ($eqStatus == 1 && $varStatus == 0) { // Si l'équipement est en timeout et que la variable Jeedom n'est pas en timeout.
    ///////////////////////// ACTION EQUIPEMENT EN TIMEOUT ////////////////////
    $scenario->setLog('| Attention l\'équipement est en timeout ('.$eqStatus.')'); // log scénario
    // ici on aurait très bien pu exécuter une autre action (message, action sur une commande ...)
    $tags['#timeout#'] = 1; // on modifie le tag (pour la sortie) à 1.
    $scenario->setData('timeout'.$eqLogicId, 1); // on l'inscrit dans la variable Jeedom pour ne pas répéter lors du prochain lancement du scénario. 
  }
  else if ($eqStatus == 0 && $varStatus == 1) // Si l'équipement n'est pas en timeout et que la variable Jeedom est en timeout.
  {
    ///////////////////////// ACTION EQUIPEMENT SORTI DE TIMEOUT ////////////////////
    $scenario->setLog('| l\'équipement N\'est plus en timeout ('.$eqStatus.')'); // log scénario
    // ici on aurait très bien pu executer une autre action (message, action sur une commande ...)
    $tags['#timeout#'] = 0; // on modifie le tag (pour la sortie) à 1.
    $scenario->setData('timeout'.$eqLogicId, 0); // on l'inscrit dans la variable Jeedom pour ne pas répéter lors du prochain lancement du scénario. 
  }
  else
  {
    ////// ici on aurait pu ne rien faire, je l'ai rajouter, juste pour pouvoir écrire quelque chose dans le log du scénario
    if ($eqStatus == 1) {
      $scenario->setLog('| L\'équipement est en timeout ('.$eqStatus.') mais il a déja été notifié lors d\'un précédent lancement du scénario.'); // log scénario
    }
    else
    {
      $scenario->setLog('| L\'équipement n\'est pas en timeout ('.$eqStatus.') mais il a déja été notifié lors d\'un précédent lancement du scénario.'); // log scénario
    }
  }
}
else
{
  $scenario->setLog('| Attention il semble que l\'équipement portant l\'id '.$eqLogicId.' n\'existe pas !!!'); // log scénario
}
$scenario->setLog('└─────────────────── [ FIN BLOC CODE ]  ───────────────────');
$scenario->setTags($tags); // on enregistre les tag, pour pouvoir l'utiliser hors bloc code, comme ci-dessous.

Bonjour à tous,

Je m’incruste par ici, car j’ai aussi ce cas d’usage, mais je le gère différemment.

En effet, je trouve que les onduleurs ne sont pas forcément fiable pour remonter une perte et un retour du courant, car les valeurs remontées ne sont pas mis à jour fréquemment par le plugin nut et souvent trop tard à mon goût.

Donc, je me base sur la connectivité de 4 équipements sur des circuits électriques complètement différents et non ondulés, 2 en filaire et 2 en wifi.
Alors oui, les équipements en question sont en MQTT et remontent donc leur état de connectivité à travers le LWT (Last Will and Testament) sur 2 brokers, ça pourrait aussi être un simple ping sur leurs IP, mais le LWT est bien plus rapide à remonter.

Dans un virtuel, j’ai une commande info binaire « État secteur » où je fais un OU entre l’etat des 4 équipements : s’ils sont tous offline, je considère que le courant est coupé, si un est online, il y a du courant. A ça j’ai ajouté une commande info binaire « Maintenance », pour gérer le cas où je ne veux pas que la domotique détecte une coupure, il est dans le même OU. Je n’ai pas fait de commande info binaire « Simulation Coupure » qui aurait l’effet inverse, mais on peut aussi imaginer ça.

Ne reste plus qu’à faire un scénario sur changement de l’info « État secteur » et d’y mettre les actions sur perte et retour.

My 2 cents,
Bad

1 « J'aime »

Merci encore à toi pour la peine que tu t’es donnée à documenter ton code.
En début d’après-midi, j’ai eu avec l’« ancien code » 2 faux positifs. Il faut que je regarde ce que ça donne sur la durée, le script est relancé toutes les 5 minutes.

Merci @Bad pour ce retour , effectivement un simple virtuel pourrait suffire. :wink:.

@JC38

Faux positif ! j’ai un doute car le scénario se charge juste de récupérer l’info existante getStatus('timeout') et de faire une comparaison avec la variable jeedom, si tu as eu un message du scénario c’est que celle-ci a bien changé d’état.
Attention a bien adapter la valeur « Alertes Communications » dans la configuration de ton équipement, ne pas mettre une valeur trop basse.
Se qui semble étonnant c’est que tu applique le scenario sur l’équipement Zlinky, je suppose que tu as au moins une communication par minutes :thinking:.

Bonjour, Le plugin NUT se rafraîchit toutes les 15 minutes ce qui n’est pas gérable.
Par contre, lors d’une coupure ou au retour du courant, l’onduleur (NUT plus précisément) fait appel à une API de Jeedom et c’est instantané. C’est la solution la plus simple et fiable que j’ai trouvé.

L’alerte comm sur le Zlinky est réglée à 1 minute et le scenario tourne toutes les 5. Dommage, depuis j’ai effacé le centre du contenu des messages.
Ce soir, je viens de passer 1 update du plugin zigbee, j’ai vu que ça générait une alerte vis à vis du Zlinky, ce qui est normal si le daemon zigbee est ko. Par contre, côté dernier démarrage, il était horodaté à ce matin, donc les faux positifs de ce début d’après-midi n’étaient pas consécutifs à un arrêt/redémarrage du daemon sur cette période.

ce qu’il faut vérifier, c’est si le Zlinky communique bien dans ces 1 min, car sinon jeedom le passe en timeout.
Pour info jeedom utilise un Cron5 pour vérifier le last communication et ainsi passer l’équipement en timeout.
Ex: dernier com a 21:17 avec « alerte timeout » a 1min :
a 21:18, l’équipement ne sera pas encore en timeout (21h17 - 1min <= 21h17)
a 21h19, l’équipement ne sera pas encore en timeout, malgré que les 1mn soit dépassé, car la fonction du core (checkAlive()) qui fait ce contrôle ne s’est pas encore lancée
a 21h20 le cron5 s’exécute et part la même occasion lance la fonction checkAlive(), celle-ci vérifiera le lastcom en fonction de « alerte timeout » et mettra le timeout a 1.

Edit :
Attention il se peut que tu es le même soucis, je sais pas si sa joue sur le lastcommunication :