function execute qui ne tient pas compte du return

Bonjour,

dans le plugin que j’ai développé, il y a plusieurs champs d’info et notamment un status.
Dans la function execute de cette info, je calcul le status en fonction de différents critères et je fini par un return $outputStatus;
Dans certains cas (indeterminer?) la valeur de l’info status est bien mise a jour mais dans d’autre cas non et je ne trouve pas pourquoi.
Voila un extrait de log :

ActualState : 0, consigne : 19, temp 19.1, hyst : 0.25, RefTemp : 21.7, tendance : down, coéfficent d’inertie : 30%, mode : Confort
Status « Arrêté » ==> Température pour chauffer : 19.635
Nouveau Status : 1
ActualState : 1, consigne : 19, temp 19, hyst : 0.25, RefTemp : 19, tendance : up, coéfficent d’inertie : 30%, mode : Confort
Status « Chauffage » ==> Température pour arreter : 19.175
Nouveau Status : 1
ActualState : 1, consigne : 19, temp 19.3, hyst : 0.25, RefTemp : 19, tendance : up, coéfficent d’inertie : 30%, mode : Confort
Status « Chauffage » ==> Température pour arreter : 19.175
Nouveau Status : 0
ActualState : 1, consigne : 19, temp 19.5, hyst : 0.25, RefTemp : 19, tendance : up, coéfficent d’inertie : 30%, mode : Confort
Status « Chauffage » ==> Température pour arreter : 19.175
Nouveau Status : 0
ActualState : 1, consigne : 19, temp 20, hyst : 0.25, RefTemp : 19, tendance : up, coéfficent d’inertie : 30%, mode : Confort

On voit par exemple ci dessus qu’au depart, le status est a 0 et que la valeur calculer est 1 (Nouveau Status : 1)
Ensuite on repasse dans la fonction, et la le status actuel est bien a 1 (ActualState : 1) donc c’est OK
Le status calculer reste 1 donc tous va bien
Ensuite on repasse dans la fonction, le status actuel est 1 et on calcul un nouveau status a 0.
Ensuite on repasse dans la fonction et la le status actuel est 1 (alors qu’il aurait du être a 0)

Voila le code la fonction au cas ou c’est nécessaire (j’ai enlever des parties pas utiliser de la fonction) :

case 'status':
        //Gestion de la température de référence (le pic haut ou bas)
        $mode = $this->getEqLogic()->getCmd('info', 'mode')->execCmd();
        $needSave = false;
        $actualState = $this->execCmd();
        //Pour réinitialiser l'enregistrement de l'historique
        $this->setCollectDate('');
        $outputStatus = $actualState;
        $actualTemp = $this->getEqLogic()->getCmd(null, 'associatedTemperatureSensor')->execCmd();
        $cmdSetPoint = $this->getEqLogic()->getCmd(null, 'adjustedSetPoint');
        if ($actualState && $cmdSetPoint->getConfiguration('RefTemp') > $actualTemp) {
          $cmdSetPoint->setConfiguration('RefTemp', $actualTemp);
          $needSave = true;
        } else if (!$actualState && $cmdSetPoint->getConfiguration('RefTemp') < $actualTemp) {
          $cmdSetPoint->setConfiguration('RefTemp', $actualTemp);
          $needSave = true;
        }

        $actualSetPoint = $cmdSetPoint->execCmd();
        $hysteresis = $this->getEqLogic()->getConfiguration('hysteresis');
        $inertiaFactor = $this->getEqLogic()->getConfiguration('inertiaFactor');
        if ($inertiaFactor < 0) $inertiaFactor = 0;
        if ($inertiaFactor > 90) $inertiaFactor = 90;

        log::add('boilerThermostat', 'debug', 'Thermostat : ' . $this->getEqLogic()->getHumanName() . ', ActualState : ' . $actualState . ', consigne : ' . $actualSetPoint .
          ', temp ' . $actualTemp . ', hyst : ' . $hysteresis . ', RefTemp : ' . $cmdSetPoint->getConfiguration('RefTemp') .
          ', tendance : ' . ($cmdSetPoint->getConfiguration('RefTemp') - $actualTemp > 0 ? 'down' : 'up') .
          ', coéfficent d\'inertie : ' . $inertiaFactor . '%' . ', mode : ' . $mode);

        $startHeatingTemp = $actualSetPoint - $hysteresis + ($cmdSetPoint->getConfiguration('RefTemp') - ($actualSetPoint - $hysteresis)) * $inertiaFactor / 100;
        $stopHeatingTemp = $actualSetPoint + $hysteresis - (($actualSetPoint + $hysteresis) - $cmdSetPoint->getConfiguration('RefTemp')) * $inertiaFactor / 100;

        if (!$actualState) {
          log::add('boilerThermostat', 'info', 'Thermostat : ' . $this->getEqLogic()->getHumanName() . ', Status "Arrêté" ==> Température pour chauffer : ' . $startHeatingTemp);
        } else {
          log::add('boilerThermostat', 'info', 'Thermostat : ' . $this->getEqLogic()->getHumanName() . ', Status "Chauffage" ==> Température pour arreter : ' . $stopHeatingTemp);
        }

        //Check if heating is necessary
        if ($mode == 'Off' || $this->getEqLogic()->getManagerState() == 0) {
          $displayParam = $cmdSetPoint->getDisplay('parameters');
          if ($displayParam['couleur'] != 'black') {
            $displayParam['couleur'] = 'black';
            $displayParam['fontcolor'] = 'black';
            $cmdSetPoint->setDisplay('parameters', $displayParam);
            //$cmdSetPoint->save();
            $needSave = true;
            $this->getEqLogic()->processChildActuators(2);
            //$this->getEqLogic()->getCmd(null, 'statusName')->event(__('Off', __FILE__));
            $this->getEqLogic()->CheckAndUpdateCmd('statusName', __('Off', __FILE__));
            $outputStatus = 0;
          }
        } else if (($actualTemp <= $actualSetPoint - $hysteresis
          || ($cmdSetPoint->getConfiguration('RefTemp') - $actualTemp > 0 &&
            $actualTemp <= $startHeatingTemp && $actualTemp <= $actualSetPoint + $hysteresis))) {
          if ($actualState == 0 || $actualState == '') {
            $displayParam = $cmdSetPoint->getDisplay('parameters');
            $displayParam['couleur'] = 'red';
            $displayParam['fontcolor'] = 'white';
            $cmdSetPoint->setDisplay('parameters', $displayParam);
            //$cmdSetPoint->save();
            $needSave = true;
            $this->getEqLogic()->processChildActuators(1);
            //$this->getEqLogic()->getCmd(null, 'statusName')->event(__('Chauffage', __FILE__));
            $this->getEqLogic()->CheckAndUpdateCmd('statusName', __('Chauffage', __FILE__));
          }
          $outputStatus = 1;
        }
        //Check if stop heating is necessary
        else if (($actualTemp >= $actualSetPoint + $hysteresis
          || ($cmdSetPoint->getConfiguration('RefTemp') - $actualTemp < 0 &&
            $actualTemp >= $stopHeatingTemp && $actualTemp >= $actualSetPoint - $hysteresis))) {
          $displayParam = $cmdSetPoint->getDisplay('parameters');
          if ($actualState == 1 || $actualState == '' || $displayParam['couleur'] == 'black') {
            $displayParam = $cmdSetPoint->getDisplay('parameters');
            $displayParam['couleur'] = 'grey';
            $displayParam['fontcolor'] = 'white';
            $cmdSetPoint->setDisplay('parameters', $displayParam);
            //$cmdSetPoint->save();
            $needSave = true;
            $this->getEqLogic()->processChildActuators(2);
            //$this->getEqLogic()->getCmd(null, 'statusName')->event(__('Arrêté', __FILE__));
            $this->getEqLogic()->CheckAndUpdateCmd('statusName', __('Arrêté', __FILE__));
          }
          $outputStatus = 0;
        }

        log::add('boilerThermostat', 'info', 'Thermostat : ' . $this->getEqLogic()->getHumanName() . ', Nouveau Status : ' . $outputStatus);

        if ($needSave) $cmdSetPoint->save();
        return $outputStatus;
        break;

Je suis dsl la fonction est un peu longue mais ne vous pencher pas trop sur la logique (un peu tordu surement car c’est ma logique ^^) car le resultat de $outputStatus est toujours correct dans la dernière ligne de log, mon problème est bien que cette valeur n’est pas prise en compte.

J’avais déjà eu des problème de ce type mais c’était lorsque j’utilisais execCmd() sans faire ensuite un setCollectDate(‹  ›); mais la je le fait.

Je pourrais surement faire un CheckAndUpdate sur la valeur mais est ce normal ? Sachant que ça fonctionnait bien avant (oui mais avant quoi?..) y’a t il eu des changements que j’aurais raté a ce niveau la?
J’ajoute de plus qu’un seul utilisateur me remonte ce pbm et qu’a piori je n’ai pas ce pbm chez moi.

Merci d’avance au courageux qui lieront ce post.
A+

Bonjour,

petite précision, le status est recalculer automatiquement sur changement de deux valeurs :

public function preSave()
  {
    switch ($this->getLogicalId()) {
      case 'status':
        $cmdAdjustedSetPoint = $this->getEqLogic()->getCmd(null, 'adjustedSetPoint');
        $cmdAssociatedTemperatureSensor = $this->getEqLogic()->getCmd(null, 'associatedTemperatureSensor');
        $this->setValue('#' . $cmdAdjustedSetPoint->getId() . '##' . $cmdAssociatedTemperatureSensor->getId() . '#');
        break;
...
...

Lorsque le changement vient d’un changement de cmdAdjustedSetPoint, pas de souci, la valeur est bien mise a jour (via la fonction défini dans le premier poste, rien de plus n’est fait)

Lorsque par contre c’est la valeur de cmdAssociatedTemperatureSensor qui change, malgré un recalcul correct dans la fonction du premier post, la valeur n’est pas mise a jour dans jeedom.

Pour info mais je ne sais pas si c’est utile, voila le code des fonctions excecute des deux cmd ci dessus :

public function execute($_options = array())
  {
    //log::add('boilerThermostat', 'info', 'execute '.$this->getLogicalId());
    switch ($this->getLogicalId()) {
      case 'associatedTemperatureSensor':
        return jeedom::evaluateExpression($this->getConfiguration('calcul'));
        break;

      case 'adjustedSetPoint':
        $resultat = round(jeedom::evaluateExpression($this->getConfiguration('calcul')), 1);
        if (!$resultat) $resultat = 0;
        if ($this->getEqLogic()->getManagerState()) {
          if ($this->getEqLogic()->getCmd('info', 'mode')->execCmd() != 'Off') $this->getEqLogic()->processChildActuators(0, $resultat);
          else $this->getEqLogic()->processChildActuators(0, 5);
        }
        return $resultat;
        break;

Nota : ces valeurs sont bien mise a jour elle et de ce que je vois elles se basent sur le même mécanisme.

A+

Bonjour,

sans forcement apporté une réponse précise a ce problème, quelqu’un sait il par quel bout prendre l’analyse?
En effet j’ai ajouter des traces dans le plugin, je vois bien que la fonction est appelé et que le resultat est correct mais Jeedom ne conserve pas la valeur défini dans le return de la fonction exécute pour l’info (du moins pas toujours, suivant la source de l’événement)

Par exemple quelqu’un sais t il dans quel source de Jeedom sont géré les événement et l’appel de la fonction execute d’une info sur changement de valeur de l’info defini dans le champs « value » de cette info?
Je pense que sur reception d’un evenement on regarde toutes les commandes qui ont dans le champs value l’ID de la commande qui genère l’evenement mais je ne trouve pas ou c’est fait.

A+

Bonjour,

je continue d’investiguer, donc j’en suis ici :
La mise a jour d’un valeur d’une info se fait via la fonction cmd::event. Cette fonction prend en argument un champ $_loop qui est par defaut a 1.
Ensuite dans le code on incrémente $_loop

Cette fonction gère la mise a jour/repetition puis a un moment vérifie si l’info mise a jour impact d’autre commande.
Donc la quand c’est lié a une commande de type info nommé $cmd, si $_loop > 1 on fait directement $cmd->event($cmd->execute(), null, $_loop);
sinon après avoir traité chaque commande, on lance listener::backgroundCalculDependencyCmd($this->getId());

Cette dernière fonction ca au final executer la commande :
$cmd->event($cmd->execute(), null, 2);
Sur chaque cmd dans le champs value contient l’id de la commande mise a jour initialement.

Donc d’après ce que je comprend, on va dans tous les cas appeler la function $cmd->execute(). C’est bien ce que je constate, la fonction est bien appeler mais la valeur n’est pas sauvegarder.

Donc on arrive dans la fonction event de la mise a jour du statut avec a priori les paramètres suivant :
event(0,null, 2) (ou plus que 2 si ça cascade d’autre choses)

A partir de la je ne vois pas ce qui pourrais clocher, j’imagine qu’il y a un problème de gestion du repeat mais je vois pas trop ou et je vois pas pourquoi une mise a jour via un evenement fonctionnerait mieux que via un autre.

Question bonus, lorsqu’on passe dans la fonction event, on fait tous un tas de calcul et gestion de « propagation » mais par quel mecanisme on sauvegarde la valeur ? Est ce avec ca :
$this->setCache(array(‹ value › => $value, ‹ valueDate › => $this->getValueDate()));

Merci
A+

Bonjour,

Plusieurs truc a tester :

  • mettre une valeur autre que 0 (ya encore des soucis dans jeedom avec la valeur 0, mais j’arrive pas a mettre la main dessus)
  • bien vérifier la répétition (tester avec toujours)
  • attention le champs value d’une commande est piegeur c’est pas la valeur de la commande qui est pas stockée en bdd mais en cache, donc tu peux pas la voir comme ca il faut regarder dans la configuraiton avancée de la commande

Merci pour le retour.

Difficile de faire des test car je ne reproduit pas le problème chez moi et un seul utilisateur a remonté ce cas (mais ça se reproduit systématiquement chez lui).

Petit résume :
J’ai une commande info (A) sur laquel j’ai fait un setValue avec l’ID de deux autres commandes d’info (B et C). Quand je dit ID, ca veut dire A->setValue(#IDB##IDC#);
Donc lorsque la valeur de B ou C change de valeur, la fonction A->event(A->execute()) est appeler.

Si fonction A->event(A->execute) est exécuté sur changement de B tout fonctionne bien, je vois bien dans mes traces une valeur correct et la fonction A->execCmd() tester après retourne bien la nouvelle valeur (que la valeur défini soit 1 ou 0).
Si par contre fonction A->event(A->execute) est exécuté sur changement de C , je vois toujours bien dans mes traces une valeur correct dans dans le return de la fonction execute mais la fonction A->execCmd() tester après ne retourne pas la nouvelle valeur (je n’ai vu le cas que pour un passage de 1 vers 0 mais peut être que ca ne fonctionne pas non plus de 0 vers 1).

Dans ce contexte, penses tu toujours qu’il soit nécessaire de tester avec une valeur autre que
0 (sachant que ca fonctionne suivant l’événement source).
Pour la répétition, je vais demandé a l’utilisateur de l’activé mais chez moi elle est en auto (et je constate que si elle ne change pas, l’événement n’est pas « transmis » ce qui me parait normal).
Je lui ai déjà demandé d’activer le log des evenements, si ce n’est pas concluant, on fera le test de la répétition.
Pour le champs value oui j’avais compris ça et quand je dit que la valeur n’est pas correct, c’est lors de l’appel de A->execCmd().

Merci
A+