Boutons complément de fioul

Échangez ici vos astuces sur la gestion des règles eedomus

Boutons complément de fioul

Messagepar Jyves » 14 Août 2024 16:16

Bonjour à tous !
Ça fait quelques jours que je me fais des noeuds au cerveau.
J’ai réussi à faire un compteur de consommation de fioul (quotidien, mensuel, annuel, et fioul restant).
Maintenant, ce que je souhaite faire, c’est créer un actionneur avec 4 boutons. +500, +1000, +1500, et cuve remplie 2000l).
Mais comme je suis nul en programmation, j’ai besoin de conseils.
Merci d’avance !
IMG_0438.jpeg
IMG_0438.jpeg (220.19 Kio) Consulté 4180 fois
IMG_0437.jpeg
IMG_0437.jpeg (292.63 Kio) Consulté 4180 fois
Jyves
 
Messages : 54
Inscription : 28 Mai 2020

Re: Boutons complément de fioul

Messagepar opa95 » 14 Août 2024 18:59

Bonjour Jyves
Jyves a écrit:Bonjour à tous !
Ça fait quelques jours que je me fais des noeuds au cerveau.
J’ai réussi à faire un compteur de consommation de fioul (quotidien, mensuel, annuel, et fioul restant).
Maintenant, ce que je souhaite faire, c’est créer un actionneur avec 4 boutons. +500, +1000, +1500, et cuve remplie 2000l).
Mais comme je suis nul en programmation, j’ai besoin de conseils.
Merci d’avance !

Il faut que tu crées un device (calculator) "Cuve" de code xxxxxxxx et que tu modifies tes anciens "calculator" en remplaçant dans ta formule 2000-device(3310001) par device(xxxxxxxx)-device(3310001).
Ensuite il faut gérer le remplissage de "cuve" en lui créant des valeurs 0, 500, 1000,1500, 2000
a chaque valeur tu peux affecter la commande
http://localhost/script/?exec=calculato ... (xxxxxxxxx)+500 (si ça plante avec le symbole "+" essaie de le remplacer par "%2b".
si tu avais besoin de plusieurs fois 500 à plusieurs mois d'intervalle, il faut repasser par la valeur 0 pour laquelle tu ne mets rien dans la commande.
Si tu veux que les commandes aient l'air plus neutres, tu pourrait adjoindre une règle qui remet automatiquement à 0 l'etat.
Peut-etre faudrait-il deux devices, un qui garde en mémoire l'état de la cuve et un qui assure le remplissage.
Il faudrait réfléchir plus longuement pour avoir la bonne solution.
Tiens nous au courant (éventuellement en mp si ça devient trop technique) :)
eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 870
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: Boutons complément de fioul

Messagepar opa95 » 14 Août 2024 20:14

Bonsoir Jyves
Pour avancer, il faut un peu plus d'informations sur ton dispositif.
De quelles données disposes-tu pour tes consommations : un débitmètre de consommation ou bien un totalisateur qui indique le nombre de litres consommés depuis l'instant initial?
Comment as-tu obtenu tes diverses valeurs de consommation (annuelle, mensuelle,...)?
:)
eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 870
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: Boutons complément de fioul

Messagepar Jyves » 14 Août 2024 20:43

Merci du temps que tu passes pour mon problème.
Pour obtenir ces données, j’ai installé une pince amperemetrique sur la phase de la pompe à fioul.
Dès qu’elle est active, j’ai un compteur de temps qui s’active. Ensuite je fais un calcul pour convertir les minutes en litres.
Pièces jointes
IMG_0439.jpeg
IMG_0439.jpeg (269.6 Kio) Consulté 4165 fois
Jyves
 
Messages : 54
Inscription : 28 Mai 2020

Re: Boutons complément de fioul

Messagepar Jyves » 15 Août 2024 01:28

J'ai essayé en créant un actionneur http avec les
http://localhost/script/?exec=calculato ... (xxxxxxxxx)+500
http://localhost/script/?exec=calculato ... (xxxxxxxxx)+1000
http://localhost/script/?exec=calculato ... (xxxxxxxxx)+1500
http://localhost/script/?exec=calculato ... (xxxxxxxxx)+2000

Le problème, c'est que le calculateur lit les valeurs brut du device actionneur

Ou alors j'ai mal compris.

Capture.JPG
Capture.JPG (29.98 Kio) Consulté 4156 fois
Jyves
 
Messages : 54
Inscription : 28 Mai 2020

Re: Boutons complément de fioul

Messagepar opa95 » 15 Août 2024 15:54

Bonjour Jyves
Jyves a écrit:J'ai essayé en créant un actionneur http avec les
http://localhost/script/?exec=calculato ... (xxxxxxxxx)+500
http://localhost/script/?exec=calculato ... (xxxxxxxxx)+1000
http://localhost/script/?exec=calculato ... (xxxxxxxxx)+1500
http://localhost/script/?exec=calculato ... (xxxxxxxxx)+2000
Le problème, c'est que le calculateur lit les valeurs brut du device actionneur
Ou alors j'ai mal compris.

J'ai réalisé quelque chose qui marche.
J'ai crée un capteur http "Cuve", un actionneur http "Remplissage" et une règle pour le remplissage.
J'ai pris une version légèrement modifiée de "calculator.php" qui est totalement compatible avec celle du store (correction d'un bug) et création d'une variable ('last') et de 2 opérateurs ('<' et '>').
Il suffit de le charger à la place de la version actuelle.
Pour la "cuve" : l'appel est inchangé
last contient la dernière valeur du capteur (contenu de la cuve ou de n'importe calcul précédent) :
le XPATH sera donc last-device(xxxx) au lieu de 2000-device(xxxx).
Pour le remplissage, on crée un actionneur http
V1 : id_cuve
V2 : contenance max de la cuve (2000)
On crée les valeurs admissibles avec les commandes
(attention dans la chaine, remplacer "+" par "%2b", eedomus maltraite le "+")
Les commandes "Vide" et "Plein" imposent les valeurs 0 ou max (2000)
Les commandes 500,1000,1500 ajoutent les valeurs correspondantes (valeur limite du contenu 2000)
La commande 0 n'est pas activable et est automatiquement affichée après un remplissage pour éviter une double ration en cas d'erreur.
Pour initialiser à une valeur quelconque, il suffit de remplir VAR3 avec la valeur voulue, de sauver et de cliquer sur Init (on peut cacher Init, en temps normal pour éviter les maneuvres intempestives).
Ensuite, on crée une règle pour le remplissage

Pour la gestion de ta cuve, il est possible que tu observe des dérives entre ta consommation estimée et la consommation réelle car tu ne disposes pas d'un totalisateur réel, mais tu estimes les volumes par le produit du débit instantané par le temps estimé : tout dépend donc de la précision du débit et des durées réelles. Si les durées réelles sont courtes, on peut accumuler les erreurs. Dans ce cas, tu peux essayer d'intégrer la consommation en utilisant par exemple : "Fonction intégrale d'un capteur" du STORE (rubrique utilitaire Web) de Merguez07 & dommarion.

Dis-moi s'il y a un problème :)
Actionneur
Actionneur.png
Actionneur
Actionneur.png (12.59 Kio) Consulté 4036 fois

Valeurs Actionneur
Actionneur-valeurs.png
Valeurs Actionneur
Actionneur-valeurs.png (56.18 Kio) Consulté 4036 fois

Règle Actionneur
Remplissage.png
Règle actionneur
Remplissage.png (23.72 Kio) Consulté 4036 fois
eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 870
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: Boutons complément de fioul

Messagepar opa95 » 15 Août 2024 16:10

(suite)
Dans les valeurs de l'actionneur, il faut remplacer calculator-init.php par calculator.php : oubli de modif après le test :(
eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 870
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: Boutons complément de fioul

Messagepar opa95 » 15 Août 2024 18:50

(fin?)
Décidément, les JO m'ont fatigués ou distrait : il manque la source du script "calculator.php" :?
Code : Tout sélectionner
<?php
// appel : http://localhost/script/?exec=calculator.php&formula=[VAR1]&id=xxxxxx
// ou http://localhost/script/?exec=calculator.php&formula=[VAR1]
//par défaut id=controller_id
//Résultat /result (ou //result)

// Get formula from VAR1
$formula = getArg("formula");
// Get id from VAR2
$controller_id = getArg("id",false,"");
//eedomus_controller_module_id
if ($controller_id === "") $controller_id = getArg("eedomus_controller_module_id");
$mem = 'last_'.$controller_id;
$last = loadVariable($mem);
if ($last === "") {$last=0;saveVariable($mem,$last);}

if (!isset($formula)) $formula = "0";

// Create an object to compute the formula
$evaleedomus = new sdk_EvalMath;

// basic evaluation:
$result = $evaleedomus->sdk_evaluate($formula);
saveVariable($mem,$result);

@sdk_header('text/xml');
echo "<result>".$result."</result>";
/*
Script développé par :
Mickael VIALAT - http://www.planete-domotique.com

Basé sur l'excellent travail de Miles Kaufmann : EvalMath Class
Merci de partager toute modification ou amélioration de ce script avec la communauté eedomus
sur le forum : http://forum.eedomus.com
Modifications opa95
correction tests "internal error 2" et "3" : "===" au lieu de "=="
  if (($op2 = $stack->sdk_pop())==null) return ... (initialement lignes 298)
  if (($op1 = $stack->sdk_pop())==null) return ... (initialement lignes 299)
  suppression pow(), utiliser l'opérateur ^
Création variable $last : dernière valeur calculée ('mem_'id_device)
Opérateurs '>' (min) et '<' (max) : a<b -> min(a,b) et a>b -> max(a,b)
Fonctions utilisables : 'device', 'abs', 'acos', 'asin', 'atan', 'cos', 'deg2rad', 'exp', 'floor', 'log', 'rad2deg', 'rand', 'round', 'sin', 'sqrt');
Opérateurs utilisables : '+', '-', '*', '/', '^', '_','<','>'
Variables utilisables : pi,e,last
Version 1.0.1
================================================================================
EvalMath - PHP Class to safely evaluate math expressions
Copyright (C) 2005 Miles Kaufmann <http://www.twmagic.com/>
================================================================================
LICENSE
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are
    met:
   
    1   Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
    2.  Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
    3.  The name of the author may not be used to endorse or promote
        products derived from this software without specific prior written
        permission.
   
    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.

*/

class sdk_EvalMath {

    var $suppress_errors = false;
    var $last_error = null;
   
    var $v = array('e'=>2.71,'pi'=>3.14,'last'=>0); // variables (and constants)
    var $f = array(); // user-defined functions
    var $vb = array('e', 'pi','last'); // constants
    var $fb = array(  // built-in functions
        'device', 'abs', 'acos', 'asin', 'atan', 'cos', 'deg2rad', 'exp', 'floor', 'log', 'rad2deg', 'rand', 'round', 'sin', 'sqrt');
       
    var $devicetab = array(); // user-defined functions
   
    function sdk_EvalMath()
    {
        global $last;
        // make the variables a little more accurate
        $this->v['pi'] = pi();
        $this->v['e'] = exp(1);
        $this->v['last'] = $last;
    }
   
    function sdk_evaluate($expr)
    {
        $this->last_error = null;
       
        $expr = trim($expr);
       
        if (substr($expr, -1, 1) == ';') $expr = substr($expr, 0, strlen($expr)-1); // strip semicolons at the end

        $arr =  $this->sdk_nfx($expr);

        return $this->sdk_pfx($arr); // straight up evaluation, woo
    }
   

    //===================== HERE BE INTERNAL METHODS ====================\\

    // Convert infix to postfix notation
    function sdk_nfx($expr)
    {
        $index = 0;
        $stack = new sdk_EvalMathStack;

        $output = array(); // postfix form of expression, to be passed to pfx()
        $expr = trim(strtolower($expr));
       
        $ops   = array('+', '-', '*', '/', '^', '_','<','>');
        $ops_r = array('+'=>0,'-'=>0,'*'=>0,'/'=>0,'^'=>1,'_','<'=>0,'>'=>0); // right-associative operator? 
        $ops_p = array('+'=>0,'-'=>0,'*'=>1,'/'=>1,'^'=>2,'_'=>1,'<'=>0,'>'=>0); // operator precedence
       
        $expecting_op = false; // we use this in syntax-checking the expression
                               // and determining when a - is a negation
   
   
        if (preg_match("/[^\w\s+*^\/()\.,-<>]/", $expr, $matches))
        { // make sure the characters are all good
            return $this->sdk_trigger("illegal character '{$matches[0]}'");
        }
   
        while(1)
        { // 1 Infinite Loop ;)
            $op = substr($expr, $index, 1); // get the first character at the current index
           
            // find out if we're currently at the beginning of a number/variable/function/parenthesis/operand
            $ex = preg_match('/^([a-z]\w*\(?|\d+(?:\.\d*)?|\.\d+|\()/', substr($expr, $index), $match);
           
            //===============
            if ($op == '-'  && !$expecting_op)
            { // is it a negation instead of a minus?
                $stack->sdk_push('_'); // put a negation on the stack
                $index++;
            }
            else
            if ($op == '_')
            { // we have to explicitly deny this, because it's legal on the stack
                return $this->sdk_trigger("illegal character '_'"); // but not in the input expression
            }
            else
            if ((in_array($op, $ops) || $ex) && $expecting_op)
            { // are we putting an operator on the stack?
                if ($ex) { // are we expecting an operator but have a number/variable/function/opening parethesis?
                    $op = '*'; $index--; // it's an implicit multiplication
                }
                // heart of the algorithm:
                while($stack->count > 0 && ($o2 = $stack->sdk_last()) && in_array($o2, $ops) && ($ops_r[$op] ? $ops_p[$op] < $ops_p[$o2] : $ops_p[$op] <= $ops_p[$o2]))
                {
                    $output[] = $stack->sdk_pop(); // pop stuff off the stack into the output
                }
                // many thanks: http://en.wikipedia.org/wiki/Reverse_Polish_notation#The_algorithm_in_detail
                $stack->sdk_push($op); // finally put OUR operator onto the stack
                $index++;
                $expecting_op = false;
            //===============
            }
            else
            if ($op == ')' && $expecting_op)
            { // ready to close a parenthesis?

                while (($o2 = $stack->sdk_pop()) != '(')
                { // pop off the stack back to the last (
                    if ($o2==null) return $this->sdk_trigger("unexpected ')'");
                    else $output[] = $o2;
                }
               
                if (preg_match("/^([a-z]\w*)\($/", $stack->sdk_last(2), $matches))
                { // did we just close a function?
                    $fnn = $matches[1]; // get the function name
                    $arg_count = $stack->sdk_pop(); // see how many arguments there were (cleverly stored on the stack, thank you)
                    $output[] = $stack->sdk_pop(); // pop the function and push onto the output
                    if (in_array($fnn, $this->fb))
                    { // check the argument count
                        if($arg_count > 1)
                            return $this->sdk_trigger("too many arguments ($arg_count given, 1 expected)");
                    }
                    else
                    { // did we somehow push a non-function on the stack? this should never happen
                        return $this->sdk_trigger("internal error 1");
                    }
                }
               
                $index++;
            //===============
            }
            else
            if ($op == ','  &&  $expecting_op)
            { // did we just finish a function argument?

                while (($o2 = $stack->sdk_pop()) != '(')
                {
                    if ($o2==null) return $this->sdk_trigger("unexpected ','"); // oops, never had a (
                    else $output[] = $o2; // pop the argument expression stuff and push onto the output
                }
                // make sure there was a function
                if (!preg_match("/^([a-z]\w*)\($/", $stack->sdk_last(2), $matches))
                    return $this->sdk_trigger("unexpected ','");
                $stack->sdk_push($stack->sdk_pop()+1); // increment the argument count
                $stack->sdk_push('('); // put the ( back on, we'll need to pop back to it again
                $index++;
                $expecting_op = false;
            //===============
            }
            else
            if ($op == '('  &&  !$expecting_op)
            {
                $stack->sdk_push('('); // that was easy
                $index++;
                $allow_neg = true;
            //===============
            }
            else
            if ($ex  && !$expecting_op)
            { // do we now have a function/variable/number?
                $expecting_op = true;
                $val = $match[1];
               
                if (preg_match("/^([a-z]\w*)\($/", $val, $matches))
                { // may be func, or variable w/ implicit multiplication against parentheses...
                    if (in_array($matches[1], $this->fb) or array_key_exists($matches[1], $this->f))
                    { // it's a func
                        $stack->sdk_push($val);
                        $stack->sdk_push(1);
                        $stack->sdk_push('(');
                        $expecting_op = false;
                    }
                    else
                    { // it's a var w/ implicit multiplication
                        $val = $matches[1];
                        $output[] = $val;
                    }
                }
                else
                { // it's a plain old var or num
                    $output[] = $val;
                }
               
                $index += strlen($val);
            //===============
            }
            else
            if ($op == ')')
            { // miscellaneous error checking
                return $this->sdk_trigger("unexpected ')'");
            }
            else
            if (in_array($op, $ops) && !$expecting_op)
            {
                return $this->sdk_trigger("unexpected operator '$op'");
            }
            else
            { // I don't even want to know what you did to get here
                return $this->sdk_trigger("an unexpected error occured");
            }
           
            if ($index == strlen($expr))
            {
                if (in_array($op, $ops))
                { // did we end with an operator? bad.
                    return $this->sdk_trigger("operator '$op' lacks operand");
                }
                else
                    break;
            }
           
            while (substr($expr, $index, 1) == ' ')
            { // step the index past whitespace (pretty much turns whitespace
                $index++;                             // into implicit multiplication if no operator is there)
            }
       
        }
       
        while (($op = $stack->sdk_pop())!=null)
        { // pop everything off the stack and push onto output
            if ($op == '(') return $this->sdk_trigger("expecting ')'"); // if there are (s on the stack, ()s were unbalanced
            $output[] = $op;
        }
       
        return $output;
    }
   
    function sdk_device($val)
    {
        $valtab = getValue($val);
        if (isset($valtab['value']))
            return $valtab['value'];
        else
            return 0;
    }

    // evaluate postfix notation
    function sdk_pfx($tokens, $vars = array())
    {
        if ($tokens == false) return false;
   
        $stack = new sdk_EvalMathStack;
       
        foreach ($tokens as $token)
        { // nice and easy
            // if the token is a binary operator, pop two values off the stack, do the operation, and push the result back on
            if (in_array($token, array('+', '-', '*', '/', '^','>','<')))
            {
                if (($op2 = $stack->sdk_pop())===null) return $this->sdk_trigger("internal error 2");
                if (($op1 = $stack->sdk_pop())===null) return $this->sdk_trigger("internal error 3");
                switch ($token) {
                    case '+':
                        $stack->sdk_push($op1+$op2); break;
                    case '-':
                        $stack->sdk_push($op1-$op2); break;
                    case '*':
                        $stack->sdk_push($op1*$op2); break;
                    case '/':
                        if ($op2 == 0) return $this->sdk_trigger("division by zero");
                        $stack->sdk_push($op1/$op2); break;
                    case '^':
                        $stack->sdk_push(pow($op1, $op2)); break;
                    case '<':
                        $stack->sdk_push(min($op1, $op2)); break;
                    case '>':
                        $stack->sdk_push(max($op1, $op2)); break;
                }
            // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on
            }
            else
            if ($token == "_")
            {
                $stack->sdk_push(-1*$stack->sdk_pop());
            // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on
            }
            else
            if (preg_match("/^([a-z]\w*)\($/", $token, $matches))
            { // it's a function!
                $fnn = $matches[1];
                if (in_array($fnn, $this->fb)) { // built-in function:
                    if (($op1 = $stack->sdk_pop())==null) return $this->sdk_trigger("internal error 4");
                    $fnn = preg_replace("/^arc/", "a", $fnn); // for the 'arc' trig synonyms

                    switch ($fnn)
                    {
                    case "device" :
                      $stack->sdk_push($this->sdk_device($op1));
                      break;
                    case "abs":
                      $stack->sdk_push(abs($op1));
                      break;
                    case "acos":
                      $stack->sdk_push(acos($op1));
                      break;
                    case "asin":
                      $stack->sdk_push(asin($op1));
                      break;
                    case "atan":
                      $stack->sdk_push(atan($op1));
                      break;
                    case "cos":
                      $stack->sdk_push(cos($op1));
                      break;
                    case "deg2rad":
                      $stack->sdk_push(deg2rad($op1));
                      break;
                    case "exp":
                      $stack->sdk_push(exp($op1));
                      break;
                    case "floor":
                      $stack->sdk_push(floor($op1));
                      break;
                    case "log":
                      $stack->sdk_push(log($op1));
                      break;
                    case "rad2deg":
                      $stack->sdk_push(rad2deg($op1));
                      break;
                    case "rand":
                      $stack->sdk_push(rand($op1));
                      break;
                    case "round":
                      $stack->sdk_push(round($op1));
                      break;
                    case "sin":
                      $stack->sdk_push(sin($op1));
                      break;
                    case "sqrt":
                      $stack->sdk_push(sqrt($op1));
                      break;
                    }

                }
                else
                if (array_key_exists($fnn, $this->f))
                { // user function
                    // get args
                    $args = array();
                    for ($i = count($this->f[$fnn]['args'])-1; $i >= 0; $i--)
                    {
                        if (($args[$this->f[$fnn]['args'][$i]] = $stack->sdk_pop())==null) return $this->sdk_trigger("internal error 5");
                    }
                   
                    $stack->sdk_push($this->sdk_pfx($this->f[$fnn]['func'], $args)); // yay... recursion!!!!
                }
            // if the token is a number or variable, push it on the stack
            }
            else
            {
                if (is_numeric($token))
                {
                    $stack->sdk_push($token);
                }
                else
                if (array_key_exists($token, $this->v))
                {
                    $stack->sdk_push($this->v[$token]);
                }
                else
                if (array_key_exists($token, $vars))
                {
                    $stack->sdk_push($vars[$token]);
                }
                else
                {
                    return $this->sdk_trigger("undefined variable '$token'");
                }
            }
        }

        // when we're out of tokens, the stack should have a single element, the final result
        if ($stack->count != 1) return $this->sdk_trigger("internal error 6");
       
        return $stack->sdk_pop();
    }
   
    // trigger an error, but nicely, if need be
    function sdk_trigger($msg)
    {
        $this->last_error = $msg;
       
        if (!$this->suppress_errors) echo $msg;
        return false;
    }
}

class sdk_EvalMathStack
{

    var $stack = array();
    var $count = 0;
   
    function sdk_push($val)
    {
        $this->stack[$this->count] = $val;
        $this->count++;
    }
   
    function sdk_pop()
    {
        if ($this->count > 0)
        {
            $this->count--;
            return $this->stack[$this->count];
        }
        return null;
    }
   
    function sdk_last($n=1)
    {
        if (isset($this->stack[$this->count-$n]))
        {
          return $this->stack[$this->count-$n];
        }
        return;
    }


?>

eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 870
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: Boutons complément de fioul

Messagepar Jyves » 15 Août 2024 19:19

Wahou !!! Merci merci merci !
Je teste ça cette nuit.

Ma seule question pour le moment: comment remplacer le script ?
Si c’est facile à trouver sur internet, t’embête pas à répondre, je vais chercher cette nuit.

Encore merci. Je te tiens au courant si ça marche pour moi.
Jyves
 
Messages : 54
Inscription : 28 Mai 2020

Re: Boutons complément de fioul

Messagepar opa95 » 15 Août 2024 20:06

Bonsoir Jyves
Jyves a écrit:Wahou !!! Merci merci merci !
Je teste ça cette nuit.

Ma seule question pour le moment: comment remplacer le script ?
Si c’est facile à trouver sur internet, t’embête pas à répondre, je vais chercher cette nuit.

Encore merci. Je te tiens au courant si ça marche pour moi.

Ça m'a bien amusé :)
Tu peux sélectionner le device http que tu as créé ou copié pour "calculatrice.php" et cliquer sur le nom pour ouvrir la fenêtre du device.
Tu peux alors cliquer sur "editer", puis remplacer tout le contenu de la fenêtre par le nouveau texte.
Tu cliques ensuite sur enregistrer et c'est bon.
Si tu veux modifier des instructions, je te recommande de copier le contenu entier quelque part car il n'est pas impossible que le transfert se passe mal et tu auras perdu tes motifs.
Généralement je préfère utiliser mon éditeur php externe pour modifier un script et le transférer ensuite.
Pour faire une modification de la source, sans ouvrir la fenêtre du device, il faut sauver la source sous le nom "calculator.php", puis ouvrir la fenêtre http://ip_box/script/
Ensuite tu cliques sur "parcourir", sélectionnes le fichier à copier et l'envoies.
Le programme est vérifié sur le site externe d'eedomus, puis transféré sur ta box.
Il se peut que la box demande une connexion, tu acceptes et tu peux redemander la page de script (il ne devrait plus redemander la connexion pendant longtemps).
Si le script utilise des variables internes que l'on veut effacer, il faut effacer l'ancien script avant de charger le nouveau. :)
eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 870
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: Boutons complément de fioul

Messagepar Jyves » 16 Août 2024 02:50

Je pense avoir quasiment tout bon, mais ça ne fonctionne pas. Ca me retourne une erreur "valeur non numérique", et en détail: <result>-3.945</result> (-1 -la conso depuis la mise en place du compteur 2.945)
Peux-tu me faire un screen de la configuration du capteur http "cuve" ? Je pense merder à ce niveau.

Le device 3311981 étant l'actionneur remplissage
Le device 3310001 étant le totaliseur

Capture2.JPG
Capture2.JPG (42.02 Kio) Consulté 3959 fois
Jyves
 
Messages : 54
Inscription : 28 Mai 2020

Re: Boutons complément de fioul

Messagepar opa95 » 16 Août 2024 08:38

Bonjour Jyves
Jyves a écrit:Je pense avoir quasiment tout bon, mais ça ne fonctionne pas. Ca me retourne une erreur "valeur non numérique", et en détail: <result>-3.945</result> (-1 -la conso depuis la mise en place du compteur 2.945)
Peux-tu me faire un screen de la configuration du capteur http "cuve" ? Je pense merder à ce niveau.

Le device 3311981 étant l'actionneur remplissage
Le device 3310001 étant le totaliseur

La pièce jointe Capture2.JPG n’est plus disponible

Le XPATH ne change pas : /result (comme sur l'original)
VAR1 : Formule de calcul (comme sur l'original)
Dans ton cas: last-device(3310001) soit : ancienne valeur-valeur prélevée

Le Remplissage n'est actif que quand on agit sur le bouton et son fonctionnement est réglé par la règle.
Valeurs de remplissage :
URL : http://localhost/script/?exec=calculator.php
Paramètres : &id=[VAR1]&formula=(last%2b[RAW_VALUE])<[VAR2]
VAR1 contient l'id de la cuve, envoyée au script "calculator.php" pour faire croire que la commande vient de la cuve
la formule envoyée est (last+[RAW_VALUE])<2000 autrement dit : min( "ancien contenu" + "valeur associée au bouton",2000) donc valeur totale toujours inférieure à 2000
VAR2 contient la contenance de la cuve (2000), pour limiter la valeur maximale
En fait les parenthèses de la formule ne sont pas nécessaires :
formula=last%2b[RAW_VALUE]<[VAR2] fonctionne car l'opération "+" (%2b) est effectuée avant de faire l'opération "<"
formula=1000+1500<2000 -> 2000 équivalent à (1000+1500)<2000 -> min(2500,2000) -> 2000
formula=1000+(1500<500) -> 1500 -> 1000+min(1500,500) -> 1000+500 -> 1500
:)
Cuve.png
cuve
Cuve.png (27.42 Kio) Consulté 3905 fois
eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 870
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: Boutons complément de fioul

Messagepar Jyves » 16 Août 2024 10:30

Ça marche !!! Enfin presque…
Ma consommation total actuelle est de 3.2 litres.

Lorsque je fais « init » (que j’ai réglé à 600 pour le test), cuve m’affiche 596.8 puis une seconde après 593.6. Et lorsque j’ajoute 500, cuve m’affiche 1087.2 (593.6+500-3.2-3.2)

À chaque fois qu’il y a une mise à jour de remplissage, il me soustrait 2x ma consommation totale actuelle. De plus, la valeur de « cuve » se met à jour uniquement lorsqu’on modifie le remplissage, mais pas quand il y a eu une consommation de fioul il me semble (j’ai pas encore consommé de fioul entre le moment où ça marche (presque) et maintenant) ? Si c’est le cas, dans la règle qui met à jour la cuve, j’ajoute le critère « ou si la valeur de la consommation totale change » ?

De plus, si j’ai compris le fonctionnement, cuve va m’afficher à chaque mise à jour, la dernière valeur moins la consommation totale. C’est à dire (par exemple) 593.6 - 3.2, puis 590.4 - 3.3 et ainsi de suite. Elle va vite se vider ma cuve ! :o
Jyves
 
Messages : 54
Inscription : 28 Mai 2020

Re: Boutons complément de fioul

Messagepar opa95 » 16 Août 2024 11:07

Bonjour Jyves
Jyves a écrit:Ça marche !!! Enfin presque…
Ma consommation total actuelle est de 3.2 litres.

Lorsque je fais « init » (que j’ai réglé à 600 pour le test), cuve m’affiche 596.8 puis une seconde après 593.6. Et lorsque j’ajoute 500, cuve m’affiche 1087.2 (593.6+500-3.2-3.2)

La partie script fonctionne donc bien.
En fait, il ne faut pas soustraire de la cuve la consommation annuelle actuelle, mais seulement le nombre de litres non encore comptabilisés : VAR1 last-device(pince ampèremétrique)*k : k étant le facteur qui transforme les ampères ou volts en litres/minute qui va donner un nombre de litres si tu fait une lecture toutes les minutes, sinon à chaque lecture (toutes les minutes) tu vas retirer le total annuel consommé.
Un fois cela corrigé, il est possible que init fasse le travail 2 fois.
Le plus sur serait de mettre une mémoire tampon "buffer".
La "pince" remplit une variable d'état "buffer" à chaque lecture.
Le "compteur quotidien" est activé toutes les minutes pour être mis à jour à partir du "buffer".
Les autres compteurs (y compris la cuve) ont une fréquence de 0, sont calculés a partir du "buffer" et sont déclenchés par une règle :
Si le "compteur quotidien" change de valeur
Action :
"compteur mensuel" mettre à jour
"compteur annuel" mettre à jour
"cuve" mettre à jour
"buffer" mettre à 0 (init ajoutera des 0)

Si ta pince le permet, il pourrait être plus simple de mettre dans eedomus le gain (fenêtre de la pince) à la valeur correcte pour obtenir directement une valeur en litres/minute. :)
eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 870
Inscription : 04 Fév 2019
Localisation : Val d'Oise


Retour vers Règles et programmations

Qui est en ligne ?

Utilisateurs parcourant ce forum : Aucun utilisateur inscrit et 8 invité(s)

cron