Calcul la moyenne dans le temps, mesures d'un seul capteur

Disponible sur https://secure.eedomus.com

Calcul la moyenne dans le temps, mesures d'un seul capteur

Messagepar Kepasub » 30 Nov 2023 19:17

Gráfico.png
comparaison graphique
Gráfico.png (199.34 Kio) Consulté 1188 fois
J’ai un capteur de luminosité, que j’utilise pour monter et descendre des volets roulants, en fonction de la température, la luminosité ou si oui ou non il pleut et avec du vent vers les fenêtres. Après trois ans à essayer de corriger les fortes variations de luminosité produites par les nuages , qui rendaient parfois folles les volets roulants, j’ai réussi à faire la moyenne du graphique de luminosité. maintenant, les stores roulants ne montent et baissent pas en continu.
Voici les étapes que j’ai prises :

- 1.- Télécharger de la boutique Eedomus, le witget "Horloge" (Horloge).

-2,- Télécharger le witget "Calculatrice mathématique" de la boutique Eedomus. Autant de witgets que nous désirons. (Exemple, Valeur 3 min; Valeur 6 min; Valeur 10 min; Valeur 20 min;Valeur moyenne).
Nous associerons chacun de ces widgets avec le widget du capteur à la moyenne (Dans mon cas, avec le capteur de luminosité).

-3.- Télécharger le Widget "Temps écoulé depuis..." de la boutique Eedomus.
Lors de la configuration de ce Widget, nous mettrons une fréquence de demande de 1 minute et nous le relierons au Widget "Horloge" pour lequel, nous introduirons le code API de l’Horloge, dans la variable 1 [VAR1]

-4.- Création de règles Nous créerons autant de règles que Valeurs nous voulons faire la moyenne, avec le schéma suivant :
Exemple pour quatre valeurs sur une période de 20 minutes:

- Nom : "Minuterie 3 min"
- Critères : Temps écoulé en min est égal à 3 min.
- Actions : Valeur 3 min Mise à jour

- Nom : "Minuterie 6 min"
- Critères : Temps écoulé en min est égal à 6 min.
- Actions : Valeur 6 min Mise à jour

- Nom : "Minuterie 10 min"
- Critères : Temps écoulé en min est égal à 10 min.
- Actions : Valeur 10 min Mise à jour

- Nom : "Minuterie 20 min"
- Critères : Temps écoulé en min est supérieur à 19 min.
- Actions : temps écoulé en min Mettre à jour
Valeur 20 min Mettre à jour
Horloge Mettre à jour
-5.- Enfin, dans le Widget 'Valeur moyenne', nous effectuerons le calcul que nous souhaitons, en utilisant les valeurs mémorisées du capteur en question.
Kepasub
 
Messages : 55
Inscription : 29 Oct 2022
Localisation : Durango , Vizcaya, Spain

Re: Calcul la moyenne dans le temps, mesures d'un seul capte

Messagepar tedharold » 22 Jan 2024 04:01

Thank you for sharing, everything seems much easier than I thought, thank you for the detailed and easy-to-understand instructions. suika game
tedharold
 
Messages : 1
Inscription : 22 Jan 2024

Re: Calcul la moyenne dans le temps, mesures d'un seul capte

Messagepar Kepasub » 27 Jan 2024 19:57

C'est un réel plaisir de partager mes modestes connaissances.
Kepasub
 
Messages : 55
Inscription : 29 Oct 2022
Localisation : Durango , Vizcaya, Spain

Re: Calcul la moyenne dans le temps, mesures d'un seul capte

Messagepar opa95 » 28 Jan 2024 09:27

Bonjour kepasub
Kepasub a écrit:C'est un réel plaisir de partager mes modestes connaissances.

As-tu réalisé l'ensemble comme ,le suggère le graphique présenté ou bien est-ce encore en cours de développement comme le suggère le futur employé dans la description?
Sinon, j'ai plusieurs scripts de ce genre, plus ou moins finalisés.
Le plus simple consiste à faire un filtre récursif (RII) qui ne nécessite la mise en mémoire que d'une seule valeur :
Resutat(t+deltaT) = ((1-a)*valeur(t)+a*resultat(t))
Si a=0 il n'y a pas de filtrage
Si a=0.5 il n'y a un filtrage modéré de l'ordre de deltaT
Si a=0.75 il n'y a pas un filtrage plus fort
Si a=1 il n'y a pas d'évolution
Tu peux tester facilement en chargeant tes valeurs de départ dans un tableur (excel,...) et testant l'effet du résultat.
Sinon, j'ai aussi des possibilités avec un filtre qui mémorise n valeurs (avec n mémoires) qui est une extension du calculateur mathématique du store.
Ces solutions, semblent nécessiter moins de plugins que ce tu suggère.
Cordialement :)
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 : 731
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: Calcul la moyenne dans le temps, mesures d'un seul capte

Messagepar opa95 » 28 Jan 2024 12:07

Bonjour kepasub
J'ai retrouvé le script lissage.
Il suffit de mettre un plugin HTTP (ou de charger "calculateur mathématique" et de remplacer l'appel au script par
http://localhost/script/?exec=lissage.php&periphId=[VAR1]&coeffs=[VAR2]&modes=[VAR3]
VAR1 : id du capteur exemple: 1549815
VAR2 : coeffs DT=deltat ',' KV=Kval ',' DC=Nbdecimales affichage exemple : KV=3,DT=60,DC=3
VAR3 : modes MO=auto/reset/init ',' V=ValeurInit si MO=init
KV Coefficient de lissage new = valeur/KV + old*(KV-1)/KV (1 par défaut, pas de lissage)
DT intervalle (secondes) entre 2 mesures (60 par défaut)
DC Nbdecimales affichées (3 par défaut)
MO mode (auto par défaut) ou reset (remise à zéro de la mémoire) ou init,xxx (remplit la mémoire avec xxx) : à faire en mode test
Voici le script à charger sous le nom lissage.php :)
Code : Tout sélectionner
<?php

define('EED_CMD','http://192.168.0.2/script/?exec=lissage.php&periphId=1549815&coeffs=DT=240,KV=288&eedomus_controller_module_id=1694423');
define('SAVE_PATH', 'temp/');
define('EEDGET_PATH', 'http://192.168.0.2/api/get?api_user=LSe1g8&api_secret=gY6topdBw6I94411');
//$arrgetValue = array('1694423'=>'{ "success": 1, "body":{"periph_id": "1694423", "name": "TExt Lissee SondesT", "last_value": "6.126", "last_value_text": "", "unit": " ", "battery": "", "last_value_change": "2021-02-28 11:34:22"}}');
// Recuperation des arguments et sauvegarde dans $eed_tabcmd (var globale)
define ('EED_REPCODE','|');// ou #{}!@$;()-+*
define('EED_SUBSTCODE','?');//code substitution des '"'
// V1.0 : lissage eedomus (2021/02/17)
// Opa95
/*
 *******************************************************************************
 * Lissage des valeurs par filtre recursif                                     *
 * Url de la requete :                                                         *
 *  http://localhost/script/?exec=lissage.php&periphId=[VAR1]&coeffs=[VAR2]&modes=[VAR3] *
 * VAR1 : temp_id                                                              *
 * VAR2 : coeffs  DT=deltat ',' KV=Kval ',' DC=Nbdecimales                     *
 * VAR3 : modes  MO=auto/reset/init ',' V=ValeurInit si MO=init                *
 * DT intervalle (secondes) entre 2 mesures                                    *
 * KV Coefficient de lissage new = valeur/KV + old*(KV-1)/KV                   *
 * Resultat                                                                    *
 * XPATH :                                                                     *
 *   //result=Valeur lissee                                                    *
 *   //value (change ou id)                                                    *
 *   //DT (KV ou DC)                                                           *
 *   //now (old ou new)                                                        *
 *******************************************************************************
 */
define('ELEMSEP', ',');define('KEYSEP', '=');// separateur cle - valeur
/************************* Fonctions de str2array.php **************************
 *******************************************************************************
 *Transformation chaine/array et array/chaine                                  *
 *Structure cle0=valeur0[,cle1=valeur1[,cle2=valeur2[,.....]]]                 *
 *definir define('ELEMSEP', ',');define('KEYSEP', '=');//separateur cle/valeur *
 *appels                                                                       *
 * $chaine=sdk_array2string($tableau,$elemsep=ELEMSEP,$keysep=KEYSEP)          *
 * $tab=sdk_array2string($chaine,chainedef='',$elemsep=ELEMSEP,$keysep=KEYSEP) *
 *  sdk_array2string recursif                                                  *
 ******************************************************************************
 */

  function sdk_array2json($tab,$lmsep=',',$ksep=':',$lmstr='"',$space=' ',$datastr=true){
    // equivalent à json_encode, fonctionne avec tableaux multidimensionnels
      $chaine='';
      if (count($tab)==0) return '{'.$chaine.'}';
      while (false!==$elem = current($tab)) {
        if ((is_string($elem)||is_numeric($elem))===false) {
          $bof=sdk_array2json($elem,$lmsep,$ksep,$lmstr,$space,$datastr);
          $chaine.=$lmstr.key($tab).$lmstr.$ksep.$bof.$lmsep;
        }
        else {
          $chaine.= $lmstr.key($tab).$lmstr.$ksep;
          if ($datastr||(($lmstr!='')&&!is_numeric($elem)))
            $chaine.=$lmstr.$elem.$lmstr.$lmsep;
          else $chaine.=$elem.$lmsep;
        }
        next($tab);
      }
      if ($space!=' ') $chaine=str_replace(' ',$space,$chaine);
      $chaine=str_replace('{}','[]',$chaine);
      $chaine=str_replace('"{','{',$chaine);
      $chaine=str_replace('}"','}',$chaine);
      $chaine='{'.trim($chaine,$lmsep).'}';
      return $chaine;
  }
 
//tableau depuis $chaine 'keyelem'.KEYSEP.'elem'.[ELEMSEP.'keyelem'.KEYSEP.'elem'...]
function sdk_string2array($chaine,$chainedef='',$elemsep=ELEMSEP,$keysep=KEYSEP){
  if (strlen($chainedef)>2){// appel recursif
    $tableau=sdk_string2array($chainedef,'',$elemsep,$keysep);
  }
  $bof=explode($elemsep,$chaine);
  if (false===strpos($chaine,$keysep)) return $bof;
  foreach($bof as $elem){
    $elem.=$keysep;
    if ((strlen($elem)>0)&&(strpos($elem,$keysep)>0)) {
      list($cle,$valeur)=explode($keysep,$elem);
      if($cle<>'') $tableau[$cle] = $valeur;
    }
  }
  return $tableau;
}

/********************* Fin de Fonctions de str2array.php***********************/
define('MOD_INIT','auto');//MO:auto,reset,init V:ValeurInit (actif si MO=init)
define('COEFFS_INIT','KV=1,DT=60,DC=3');//KV, DT, DC
//Recuperation des arguments

$periph_id =getArg('eedomus_controller_module_id');// id du programme appelant
$periphid = getArg('periphId');
$list_modes = getArg('modes');
$list_coeffs = getArg('coeffs');
// decodage parametres
$bof=getValue($periphid, true);
$data['value'] = $bof['value'];// eedomus n'accepte pas getValue(...)[Value]
$data['change'] = strtotime($bof['change']);
$data['periph_id'] = $bof['periph_id'];
//decodage coefficients
$coeffs=sdk_string2array($list_coeffs,COEFFS_INIT);
if ($coeffs['KV']<1) {$coeffs['KV']=1;};
//decodage modes
$modes=sdk_string2array($list_modes,MOD_INIT);
// Sauvegarde des valeurs pour reutilisation
$varname='lissage'.$periph_id;
$time=time();
$save='no';
$lastdatastr=loadVariable($varname);
$lastdata=sdk_json_decode($lastdatastr,true);
if (!array_key_exists('MO',$modes)) $modes['MO']=MOD_INIT;
if ((is_string($lastdata))||($modes['MO']!='auto')){
   $lastdata=$data;
  $lastdata['change']=$time;
  if ($modes['MO']=='init') {$lastdata['value']=$modes['V'];}
   $save='rst';
}

// valeur lissee (filtrage recursif)
if ($time-$lastdata['change']>=$coeffs['DT']) { //Echantillonage (secondes)
   $lastdata['value']=round((($coeffs['KV']-1)*$lastdata['value']+$data['value'])/$coeffs['KV'],$coeffs['DC']);
   $save='yes';
}
  $timestr='<time>'.PHP_EOL.'<now>'.$time.'</now>'.PHP_EOL.'<old>'.$lastdata['change'].'</old>'.PHP_EOL.'<new>'.$data['change'].'</new>'.PHP_EOL.'</time>'.PHP_EOL;
if ($save!='no') {
   $lastdata['change']=time();
  $savestr=sdk_array2json($lastdata);
  saveVariable($varname,$savestr);
}

$result=$lastdata['value'];
// Affichage des resultats
// Generation du XML
sdk_header('text/xml');
$xml = '<?xml version="1.0" encoding="ISO-8859-1"?>'.PHP_EOL;
$xml .= '<root>'.PHP_EOL;
$xml .= '<result>'.$result.'</result>'.PHP_EOL ;
$xml .= '<donnees>'.PHP_EOL.'<TX>'.$data['value'].'</TX>'.PHP_EOL.'<change>'.$data['change'].'</change>'.PHP_EOL.'<id>'.$data['periph_id'].'</id>'.PHP_EOL.'</donnees>'.PHP_EOL;
$xml .= $timestr;
$xml .= '<const>'.PHP_EOL.'<DT>'.$coeffs['DT'].'</DT>'.PHP_EOL.'<KV>'.$coeffs['KV'].'</KV>'.PHP_EOL.'<DC>'.$coeffs['DC'].'</DC>'.PHP_EOL.'<mode>'.$modes['MO'].'</mode>'.PHP_EOL.'<save>'.$save.'</save>'.PHP_EOL.'</const>'.PHP_EOL;
$xml .='</root>';   
echo $xml;
?>

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 : 731
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: Calcul la moyenne dans le temps, mesures d'un seul capte

Messagepar Kepasub » 28 Jan 2024 12:17

Merci pour tes conseils "opa95", mais je ne sais pas faire un programme écrit. C’est pourquoi je me contente d’utiliser la programmation spécifique fournie par Eedomus. Je te rappelle que pour avoir une variable relative au temps écoulé dans une année (calendrier en format m,d), j’ai eu besoin de ta précieuse collaboration, avec toutes les explications possibles.
Quant à la finalisation de mon exemple, il n’est pas en développement. Le graphique n’est pas un exemple théorique . Il est tiré d’un graphique réel, en comparant les valeurs prises par le capteur de luminosité et celles calculées par la méthode exposée.
En fait, je voulais que les stores ne montent pas et ne descendent pas en permanence, et c’est le cas depuis que je les utilise.
Encore une fois, merci pour vos commentaires, que je remercie vivement.
Salutations : Kepa
Kepasub
 
Messages : 55
Inscription : 29 Oct 2022
Localisation : Durango , Vizcaya, Spain


Retour vers Portail web "classique"

Qui est en ligne ?

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