[idée plugin Zwave] vérification des ordres

Salut,

On est plusieurs à se pleindre du zwave malgré le fait que visiblement d’autres n’ont « aucuns problèmes ».

Plusieurs ont essayé pas mal de choses, conseillées sur les forums, pour rendre le maillage parfait, les plus acharnés ont aussi sûrement « développés » leurs propres palliatifs dans les scénarios.

Est-ce que quelqu’un ne pourrait pas se lancer dans la confection d’un plugin zwave qui permettrait de créer un équipement et de lui affecter des commandes et des informations pour, in fine, s’assurer qu’un ordre a bien été pris en compte par le receveur et que son état a donc bien changé. Dans le cas contraire, relancer rapidement l’ordre tout en vérifiant que la queue zwave reste proche de zéro.

Bref, sans chercher à relancer la polémique, pallier aux problématiques d’openzwave.

A+ et merci
Bison

Bonjour,

Pour ma part j’ai effectivement mis en place dans mon scénario des « tant que » ou je teste toutes les minutes (jusqu’à 5 fois) et j’ai l’impression que j’ai eu (un peu moins) d’ordres non passés par la suite… (je ne peux pas faire de statistique dessus car j’ai mis cette solution assez tard dans l’hiver):

J’ai amélioré également mon maillage Z-wave (très important je trouve)
Je sais que ce n’est pas la solution que tu cherches mais si ça peut aider…

Cordialement

Bonjour,
Peut-être que le plugin « thermostat » pourrait s’en charger, en répliquant les ordres ?
Avoir un radiateur qui fonctionne en ON alors que c’est pas la peine, c’est moche…
Se retrouver dans une piece à 23° alors que l’on a demandé 19° parce que le OFF n’a pas marché :frowning:
Je trouve dommage que le ZWAVE (openzwave) n’assure pas une qualité de service.
Dire que le retour d’êtat c’est génial, je veux bien, mais faut encore en faire quelque chose !
Cordialement,
Yofa

Salut yofa,

Oui mais là l’idée c’était justement de ne pas ajouter cette tâche à chaque plugins puisque bien sûr le problème ne se pose pas que pour les équipements de type chauffage mais avec l’ensemble des équipements Zwave.

Un plugin maitre pourrait surement se charger de ça mais personne n’a eu envie de se lancer là dedans.

Bison

Est-ce que le plugin « Zwave » pourrait « stocker » la dernière commande envoyée et un thread en cron vérifier régulièrement que l’état a été pris en compte et sinon relancer la commande?
J’ai pas beaucoup équipement, mais je me vois pas faire cela pour tous les équipements via des scenarios.

Salut!

J’utilise le zwave depuis le debut et je n’ai jamais eu de souci de trame perdue ou autre.

Je pense donc qu’il vaut mieux tenter de comprendre ce qui se passe sur vos réseaux et pourquoi vous perdez des trames plutot que demander à monter une usine à gaz

2 « J'aime »

il y a pleins de sujets qui traitent des soucis que certains rencontre avec le zwave.

Ça dépend de beaucoup de paramètres : le matériel sur lequel tourne Jeedom, le contrôleur, les modèles de modules employés dans son réseau, l’inclusion sécurisé ou non, le maillage et j’en oublie sûrement.

Personnellement je suis passé d’une VM sur NAS à une VM sur un mini-pc dédiée avec Proxmox et j’ai également changé le contrôleur. Oui, on dirait que ça va mieux mais il arrive encore de temps à autre que tel volet ne s’ouvre pas où que la lumière extérieure ne s’allume pas quand le portail s’ouvre.

J’entends les personnes qui disent comme toi qu’ils n’ont aucun problème et tant mieux mais il faut aussi entendre ceux qui ont des ratés dans l’envoi ou la réception des commandes malgré le fait de ne pas faire n’importe quoi comme placer son seul module à 160m du contrôleur :laughing:.

Par exemple avec le plugin Dakin et les ordres en wifi je n’ai jamais eu un seul raté en 1 an et demi.

Il y a forcément quelque part dans la librairie openzwave quelque chose de mal géré sinon personne ne se pleindrait.

Bref ce n’est pas une usine à gaz de s’assurer qu’un ordre arrive bien, c’est ce que fait le TCP depuis pas mal de temps. Le plugin zwave aurait sûrement le moyen d’intégrer cette vérification puisque le protocole zwave ne le fait pas.

Désolé, mais je n’y crois pas.

Oui, mais il faut voir l’effort d’analyse à mener (ce n’est pas aux utilisateurs de faire ça)

Il me reste encore des petits trucs qui ne vont pas (mais j’en ai marre de debugger) : en particuliers les ordres de changements de consignes avec les têtes thermostatiques Spirit qui ne passent pas toujours correctement !

Quand les modules Chacon (sans retour d’état) ont moins de ratés que les modules Z-Wave avec OpenZwave, il y a clairement un souci !

En WiFi, la question de savoir si l’ordre passe ne se pose même pas ! :smiley:

Retour au sujet :

  • Pour les commandes SANS retour d’état : il faudrait une répétition des ordres après 10s, 1min, 5min, 1h.
  • Pour les commandes AVEC retour d’état : il faudrait créer un état virtuel (état idéal) en plus de l’état réel actuel (retour d’état) ainsi qu’une commande info qui compare les 2. Si les 2 états sont différents pendant plus de 10s, 1min, 5min, 1h, on renvoie la commande (stockée dans l’état virtuel) avec une alerte en cas d’échec la 4ème fois au bout d’une heure

Dans un premier temps, on peut le faire manuellement au cas par cas pour les commandes critiques comme les consigne du chauffage.

Pour le chauffage, je sépare déjà les commandes envoyées des retours d’état (c’est lourd mais bon)
image

Pour la chaudière, c’était indispensable, car le retour d’état prend un peu de temps (je ne force pas le rafraîchissement et j’attends que la chaudière me renvoie la valeur d’elle-même)
image

Salut!

Un module hs met parfois la grouille dans le réseau.
Pas assez de module alimenté vs modules piles aussi.
Certains contrôleurs zwave pas top, perso avec le gen5 jamais eu de souci

Sinon j’ai mis en place un scénario avec ce code pour vérifier mes modules et savoir si jamais un est mort
Ca remonte la liste dans une variable jeedom zWave_ModuleError_01

//**********************************************************
// Parameters
//**********************************************************
$API_Key = api key du plugin zwave;
$time_now = time();
//**********************************************************


//**********************************************************
// Get list by element on error
//**********************************************************
$scenario->setLog('**********************************************************');
$scenario->setLog('***** Get list *****');
$scenario->setLog('**********************************************************');
$url_GetInfo = 'http://localhost:8083/network?apikey=' .$API_Key .'&type=info&info=getHealth';
$Error_Module = array();

$content = (file_get_contents($url_GetInfo));

$All_Info = json_decode($content, true);
$All_node = $All_Info["result"]["devices"];

//$scenario->setLog($content);

foreach($All_node as $Array_Key => $Array_value){
	$Alim = $Array_value["data"]["isListening"]["value"];
	if(($Alim == 0)){
		$Last_Info = $Array_value["data"]["lastReceived"]["updateTime"];
		$Wakeup_Interval = $Array_value["data"]["wakeup_interval"]["value"];
      	if(($Last_Info + ($Wakeup_Interval * 2)) < $time_now){
        	$scenario->setLog('Module :'.$Array_Key .' is on error' );
         												 $Module_Name = $Array_value["data"]["description"]["name"];
         												 $scenario->setLog('Module :'.$Module_Name .' is on error' );
          	$Error_Module[] = $Array_Key;
        }
	}
}

//**********************************************************
// Set variable for the next steps of the scenario
//**********************************************************
$scenario->setData("zWave_ModuleError_01", implode(',', $Error_Module));

Merci beaucoup @anon53349806

Résultat :

------------------------------------
[2020-11-19 11:36:10][SCENARIO] Start : Scenario lance manuellement.
[2020-11-19 11:36:10][SCENARIO] Exécution du sous-élément de type [action] : code
[2020-11-19 11:36:10][SCENARIO] Exécution d'un bloc code
[2020-11-19 11:36:10][SCENARIO] **********************************************************
[2020-11-19 11:36:10][SCENARIO] ***** Get list *****
[2020-11-19 11:36:10][SCENARIO] **********************************************************
[2020-11-19 11:36:14][SCENARIO] Module :130 is on error
[2020-11-19 11:36:14][SCENARIO] Module :Vanne Thermostatique Spiritz Cuisine is on error
[2020-11-19 11:36:14][SCENARIO] Module :131 is on error
[2020-11-19 11:36:14][SCENARIO] Module :Vanne Thermostatique Spiritz Salle is on error
[2020-11-19 11:36:14][SCENARIO] Module :132 is on error
[2020-11-19 11:36:14][SCENARIO] Module :Vanne Thermostatique Spiritz Chambre 1 is on error
[2020-11-19 11:36:14][SCENARIO] Module :133 is on error
[2020-11-19 11:36:14][SCENARIO] Module :Vanne Thermostatique Spiritz Bureau is on error
[2020-11-19 11:36:14][SCENARIO] Module :107 is on error
[2020-11-19 11:36:14][SCENARIO] Module :FGKF-601 Keyfob is on error
[2020-11-19 11:36:14][SCENARIO] Module :111 is on error
[2020-11-19 11:36:14][SCENARIO] Module :Vanne Thermostatique Spiritz Chambre 2 is on error
[2020-11-19 11:36:14][SCENARIO] Fin correcte du scénario

Mes 5 vannes Spirit sont en erreurs, mais elles fonctionnent. Elles ont juste un %OK entre 95% et 99%. Tout est OK dans la page santé Z-Wave. Je n’ai pas de module HS.

Bonjour à tous

nous avons tous eu des soucis avec ce protocole

Depuis quelques années, c’est stable chez moi, mon maillage est optimisé :

et j’ai quelques scripts qui tournent pour surveiller que le zwave ne partent pas en sucette.

mais j’ai aussi toujours des scenarios/virtuels qui vérifient que les demandes sont bien traitées, pour les prises par exemple.

Mais c’est vrais qu’un plugin, a qui on enverrait une commande en entrée et qui l’appliquerait avec un contrôle sur sa bonne exécution, au moins pour avoir une alerte si un nombre de commandes non validé est atteint, voir qui réappliquerait la commande x fois, serait pas une mauvaise idée.

1 « J'aime »

Salut,

C’est pas que le fait qu’un module soit HS qui posent un problème. Par exemple mon oeil fibaro qui bouffe les piles de façon importante, n’est JAMAIS vu comme HS… ça peut rester des jours entiers avec une info issue du cache (c’est ce qu’on voit dans les infos du plugin) et ça ne pose pas de souci au plugin. ça ne va même pas déclencher l’alerte des piles HS. Pourtant techniquement, la communication n’est pas possible…
Et niveau distance, entre la clé et l’oeil il y a 1,5m sans obstacle.

Je vais devoir faire la même chose. Un scenario qui se lance si le retour d’état est différent de la consigne stockée dans un virtuel.
Dommage que le plugin ne puisse pas gérer cela en natif.
C’est possible de le faire pour mon cas parce que:
1/ je connais mes différents devices (Qubino Fil Pilote)
2/ le code ne me fait pas peur

J’imagine que le soucis réside dans le protocole openzwave et dans la multitude de différents device et à peu près autant de façon de les activer…

Il faut définir un temps pendant lequel le retour d’état est autorisé à être différent de la consigne (ordre envoyé) avant d’exécuter le scénario, sinon ton scénario va se lancer à chaque changement d’état.

J’avais commencé à faire un bout de programme dans les fonctions personnalisées, je le re-testerai vite fait et le mettrais là en sachant qu’il y aura surement des coquilles et une façon de dev qui n’est pas celle d’un pro

1 « J'aime »

J’étais partis dans l’idée de vérifier, avec mes volets, si l’état avait bougé après avoir donné l’ordre.
A la vue des lectures de ce post, il aurait été plus malin de donner une cible. Bref ce n’est pas vraiment finalisé je voulais essayer un truc quand j’ai vu que personne ne réagissait à ce post du 2 avril.

La fonction à ajouter dans user.function.class.php :

    public static function ZwaveOrderCheck($_mycmd, $_mystate, $_mysleep='5') {
      $_mycmd = '#'.trim($_mycmd).'#';
      $_mycmdName = cmd::byString($_mycmd)->getHumanName();

      $_mystate = '#'.trim($_mystate).'#';
      $_mystateName = cmd::byString($_mystate)->getHumanName();
      $_statebefore = cmd::byString($_mystate)->execCmd();

      //log::add('zwaveordercheck', 'info', 'Lancement fonction ZwaveOrderCheck');
      
      log::add('zwaveordercheck', 'info', '[Action demandée] -> '.$_mycmdName);
      log::add('zwaveordercheck', 'info', '[Etat avant] -> '.$_mystateName.' : '.$_statebefore);

      // Information sur l'état de la Queue Zwave
      $networkState = openzwave::callOpenzwave('/network?type=info&info=getStatus');
      $queueSize=$networkState['result']['outgoingSendQueue'];
      //log::add('zwaveordercheck', 'info', '[Info] -> queuSize : '.$queueSize);

      $i = 0;
      $_stateafter = $_statebefore;

      while ($_stateafter == $_statebefore) { // Tant que la valeur de l'état après action est différente de l'état avant action, on recommence
        if ($queueSize == 0) {
          cmd::byString($_mycmd)->execCmd(); // Execution de la commande demandée
          if ($i > 1) {            
          	log::add('zwaveordercheck', 'warning', '[Action] -> '.$_mycmdName.' [execution '.$i.']');
          } else {
            log::add('zwaveordercheck', 'info', '[Action] -> '.$_mycmdName);
          }

          if ($i == 3) {
            break;
          } // Si 3 retry on abandonne
          
          sleep($_mysleep); // Stoppe pour $_mysleep secondes (5 par defaut)

          $_stateafter = cmd::byString($_mystate)->execCmd();
          log::add('zwaveordercheck', 'info', '[Etat après] -> '.$_mystateName.' : '.$_stateafter);
          
          $i++;
        } else {
          log::add('zwaveordercheck', 'info', '[Info] -> queuSize : '.$queueSize);
          sleep(1);
          // Information sur l'état de la Queue Zwave
    	  $networkState = openzwave::callOpenzwave('/network?type=info&info=getStatus');
      	  $queueSize=$networkState['result']['outgoingSendQueue'];
        }
      }
      

      if ($_stateafter == $_statebefore) {
        log::add('zwaveordercheck', 'warning', '[Info] -> '.$_mycmdName. ' ne semble pas avoir été éxécutée');
        return 0;
      } else {
        log::add('zwaveordercheck', 'info', '[Action éxécutée] -> '.$_mycmdName);
        return 1;
      }
      
    }

L’idée étant de lancer la commande de cette façon :

La commande pour un UP du volet donc : ZwaveOrderCheck([Bureau][Bureau][Up],[Bureau][Bureau][Etat],7)

On peux donc fournir 2 ou 3 paramètres :

  1. Le nom de la commande à lancer
  2. Le nom de l’état qui est à vérifier
  3. Le temps d’attente pour check si l’état a bougé (optionnel et défini à 5 secondes sinon)

Note : ne pas mettre le nom de la commande entre # sinon elle est interprétée avant d’arriver à la fonction, je n’ai pas trouvé le moyen de la récupérer sans cette feinte, surement un truc que je n’ai pas compris.

Pour les logs j’ai installé le plugin LogManager afin d’avoir une entrée « zwaveordercheck » bien distinct

Il y a assurément mieux à faire et c’est pour ça que je demandais si quelqu’un de plus calé ne voulais pas se lancer mais ça peut faire une base à quelqu’un qui s’y connait un peu mieux et qui voudrait l’améliorer :slight_smile:

1 « J'aime »

Bonjour @Bison,

Voici ma version pour mes fil pilote Qubino.
J’appelle la fonction « sendQubinoFilPiloteOrder([parent][objet][ordre]) » et le reste est calculé automatiquement.
Merci pour le travail que tu as fait, il m’a vraiment inspiré (la page blanche, c’est pas mon truc)
Merci pour l’utilisation de LogManager :wink:

Diff avec ta version:

  • Je n’envois pas d’ordre si l’équipement est déjà dans le bon état.
  • spécifique Qubino Fil Pilote
  • attends sleep x execution au lieu de sleep
  • usage de fonctions php
  • pas d’accents parce que moche dans mes logs serveur :frowning:
	public static function zwaveGetQueueSize() {
		//return 0; //si tout va bien dans le reseau
		// Information sur l'etat de la Queue Zwave
		$networkState = openzwave::callOpenzwave('/network?type=info&info=getStatus');
		$queueSize=$networkState['result']['outgoingSendQueue'];
		log::add('zwaveordercheck', 'debug', '[Debug] -> queueSize : '.$queueSize);
		return $queueSize;
	}

	public static function isQubinoFilPiloteStatusOk ($_mycmd) {
		$arraycmd = explode("][",$_mycmd);
		$mystate = '#'.trim($arraycmd[0]).']['.trim($arraycmd[1]).'][Etat]#';
		$mystateName = cmd::byString($mystate)->getHumanName();
		$state = cmd::byString($mystate)->execCmd();
		log::add('zwaveordercheck', 'info', '[Etat] -> '.$mystateName.' : '.$state);
		$cmd = substr($arraycmd[2], 0, $arraycmd[2].length-1);
        switch ($cmd) {
			case "Arret":
				$ret = ($state == 0) ? 1 : 0;
				break;
			case "Hors Gel":
				$ret = ($state == 20) ? 1 : 0;
				break;
			case "Eco":
				$ret = ($state == 30) ? 1 : 0;
				break;
			case "Confort -2":
				$ret = ($state == 40) ? 1 : 0;
				break;
			case "Confort -1":
				$ret = ($state == 50) ? 1 : 0;
				break;
			case "Confort":
				$ret = ($state>=100) ? 1 : 0;
				break;
		}
        return $ret;
	}

	public static function sendQubinoFilPiloteOrder($_mycmd, $_mysleep='5') {
		$_mycmd = trim($_mycmd);
		$cmd = '#'.$_mycmd.'#';
		try {
			$mycmdName = cmd::byString($cmd)->getHumanName();
        } catch (Exception $e) {
    		log::add('zwaveordercheck', 'info', 'Exception recue : '.  $e->getMessage());
            $mycmdName = $_mycmd;
		}
		log::add('zwaveordercheck', 'info', '[Action demandee] -> '.$mycmdName);
		$i = 0;
		while (!userFunction::isQubinoFilPiloteStatusOk($_mycmd) && $i < 4) { // Tant que la valeur de l'etat ne colle pas la commande, on recommence
			if (userFunction::zwaveGetQueueSize() == 0) {
				if ($i > 1) {
					log::add('zwaveordercheck', 'warning', '[Action] -> '.$mycmdName.' [execution '.$i.']');
				} else {
					log::add('zwaveordercheck', 'info', '[Action] -> '.$mycmdName);
				}
				cmd::byString($cmd)->execCmd(); // Execution de la commande demandee
				sleep($_mysleep*($i + 1)); // Stoppe pour $_mysleep * execution secondes
				$i++;
			} else {
				sleep(1);
			}
		}
		if ($i == 4) {
			log::add('zwaveordercheck', 'warning', '[Info] -> '.$mycmdName. ' ne semble pas avoir ete executee');
			return 0;
		} else {
			log::add('zwaveordercheck', 'info', '[Action executee] -> '.$mycmdName);
			return 1;
		}
	}
2 « J'aime »

Salut,

Bien joué ! Sympa d’avoir un retour.

Je me rend compte qu’il doit pas être simple de faire quelque chose qui s’adapte à tout les équipements Zwave parce que tu as du ajouter des éléments qui ne sont pas à gérer pour les volets par exemple.

Bonjour,

Merci pour ce bout de code mais… on le met ou ?
Ma commande est ainsi:
#[Dressing][Dressing (ZMNHJD1) (11)][Confort]#
Donc il faut rajouter le bloc code dans le core de Jeedom, et ensuite lancer une 2ème action (après la commande ci-dessus):
sendQubinoFilPiloteOrder(#[Dressing][Dressing (ZMNHJD1) (11)][Confort]#)
comment faire svp ?

Merci

@Livyo, désolé de ma réponse tardive
Dans mon Thermostat, je fais ainsi
sendQubinoFilPiloteOrder([Etage][Rad. Ch. Parents][Confort])