Récupération de records absolus

Salut les jeedomiens!

je cherche à ajouter sur mon design météo les records absolus.
en cherchant j’ai vu 2 possibilités

history::getStatistique
// renvoi  (sum, count, std, variance, avg, min, max)

ou

maxBetween(#id#, '01-01-2020', now)

ça fonctionne mais je n’ai pas la date et heure de collecte de ce maximum/minimum.

Comment procédez vous pour récupérer le couple valeur + heure de collecte pour des min/max ?

merci beaucoup :smiley:

J’ai cherché pendant un moment et au final j’ai créé un scénario qui s’active a chaque changement de température et vérifie si on est sur un record. Si oui, il renseigne les valeurs et dates/heures. Ensuite j’affiche ça dans un tableau. Si y’a plus simple, je suis preneur.

Si vous mettez la fonction max dans une commande info, elle aura la valeur et la commande la date et heure de collecte ?

bonjour
je connais 2 possibilités scénario code
via requête sql
via api jeedom recherche date (getdate)
du resultat (getvalue) de la cmd mini,max (history::getStatistique)

si personne ne retrouve je mettrai se soir

2 « J'aime »

Hello.
merci pour les réponses.

au final j’ai commencé hier la méthode sql, j’ai vu que ça comme possibilité.

voilà le scénario/code

// By DDelec24
// https://community.jeedom.com/t/recuperations-de-records-absolus/27587
// Scénario programmé 3x par jour, dont un obligatoirement à 23h59
// pour balayer l'history du jour avant qu'il soit archivé
// CRON => 59 8,16,23 * * *

$cmdId = 89; // ID de la commande info température

/* ### Premier lancement du scenario, recherche dans les archives ### */
if($scenario->getData('v_rechercheRecordsArchives') != 1) {
    // Recherche dans l'historique le max
	$sqlMax = "SELECT value, datetime FROM historyArch WHERE cmd_id=$cmdId ORDER BY CAST(value as decimal(5,2)) DESC, datetime DESC LIMIT 1;";
	$resultMax = DB::Prepare($sqlMax, NULL, DB::FETCH_TYPE_ROW);
	$scenario->setLog(json_encode($resultMax));
	$scenario->setData('v_maxTemp', $resultMax['value']);	
	$scenario->setData('v_maxTempDate', $resultMax['datetime']);	

    // Recherche dans l'historique le min
	$sqlMin = "SELECT value, datetime FROM historyArch WHERE cmd_id=$cmdId ORDER BY CAST(value as decimal(5,2)) ASC, datetime DESC LIMIT 1;";
	$resultMin = DB::Prepare($sqlMin, NULL, DB::FETCH_TYPE_ROW);
	$scenario->setLog(json_encode($resultMin));
	$scenario->setData('v_minTemp', $resultMin['value']);	
	$scenario->setData('v_minTempDate', $resultMin['datetime']);

    // On marque qu'on a fait le premier lancement
	$scenario->setData('v_rechercheRecordsArchives', 1);
}

/* ### Désormais on recherche dans la table history du jour ### */

$currentMaxTemp = $scenario->getData('v_maxTemp');
$currentMinTemp = $scenario->getData('v_minTemp');
// Recherche dans l'historique le max
$sqlMax = "SELECT value, datetime FROM history WHERE cmd_id=$cmdId ORDER BY CAST(value as decimal(5,2)) DESC, datetime DESC LIMIT 1;";
$resultMax = DB::Prepare($sqlMax, NULL, DB::FETCH_TYPE_ROW);
if($resultMax['value'] > $currentMaxTemp) {
	$scenario->setData('v_maxTemp', $resultMax['value']);
	$scenario->setData('v_maxTempDate', $resultMax['datetime']);	
}

// Recherche dans l'historique le min
$sqlMin = "SELECT value, datetime FROM history WHERE cmd_id=$cmdId ORDER BY CAST(value as decimal(5,2)) ASC, datetime DESC LIMIT 1;";
$resultMin = DB::Prepare($sqlMin, NULL, DB::FETCH_TYPE_ROW);
if($resultMin['value'] < $currentMinTemp) {
	$scenario->setData('v_minTemp', $resultMin['value']);	
	$scenario->setData('v_minTempDate', $resultMin['datetime']);
}

ça peut s’appliquer et s’adapter pour plusieurs commandes via une boucle.
Au tout premier lancement il ira regarder dans historyArch (ce qui peut être assez long) mais les fois suivante il ira juste dans l’archive du jour pour mettre à jour les variables si nécessaire.

Si vous avez une suggestion d’amélioration pour optimiser les requêtes je dis pas non c’est pas mon fort ^^

1 « J'aime »

Bonjour,

J’utilise pour ma part ce type de requête afin de récupérer les minima/maxima de ma station météo.

Voici un exemple pour la pression atmosphérique ou l’ID de ma commande est 2733.

select datetime,value from history where  cmd_id = 2733 order by cast(value as decimal(10,2)) asc, datetime desc limit 1

Cette requête retourne la valeur la plus petite de la commande 2733 dans la table history.
Le tri supplémentaire « datetime desc » permet d’avoir la date la plus récente pour cette valeur. En effet, il est possible d’avoir plusieurs fois dans la table une même valeur et la BD retournera par défaut la plus ancienne.
L’option « limit 1 » permet de n’avoir qu’un seul résultat…

Remarque : tu indiques DECIMAL(5,2) dans ta requête SQL ce qui implique un chiffre avec 5 digits comportant 2 décimal. Ton chiffre maximum sera donc 999,99

2 « J'aime »

Yep je connais pas le comportement si on a -10,20 par exemple, si ça prend le moins en compte, signed unsigned… donc j’ai pas pris de risque :rofl:

ah bien vu le fait de faire du order by avec la limit! je restais bloqué sur lutilisation de MAX() et MIN()
C’est bon, je vais mettre mon code à jour au dessus

Merci du conseil !

Cette fonction ne tient pas compte si la valeur est négative ou positive:
select cast(1460.56465 as decimal(10,2)) retournera 1460.56
select cast(-1460.56465 as decimal(10,2)) retournera -1460.56

1 « J'aime »

il y a la fonction « union all » en sql
afin de cumulé history et historyarch

enfin je mets brut la base de l’autre methode

//$cmdId= cmd::byString("##")->getId();
$cmdId= cmd::byString("#[Dehors][Sondes Serres][Température]#")->getId();

$debut = date("Y-m-d H:i:s", strtotime("yesterday"));
// $fin = date("Y-m-d H:i:s", strtotime("-9 hour 15 min"));  
$fin = date("Y-m-d H:i:s", strtotime("-10 min"));  
$value = history::getStatistique($cmdId, $debut, $fin)["min"];
// $value = history::getStatistique($cmdId, $debut, $fin)["last"];

  $scenario->setLog($value);

$all = history::all($cmdId, $debut, $fin);
$first = $all[0]->getValue();
$firstdate = $all[0]->getDatetime();


for ($i = 0; $i < count($all); $i++) {
   $v = $all[$i];

  // recherche
 if($v->getValue() == '19.5' )  {
//      if($v->getValue() == $value )  {

  	$current = $v->getDatetime();
    $valeur = $v->getValue();
$scenario->setLog( "recherche : $current valeur : $valeur ");

}
    if($v->getValue() == $value )  {
      $current2 = $v->getDatetime();
  }
}
  $scenario->setLog("premier $first à $firstdate");


$scenario->setLog("mini $value à $current2");
//$date= date ("Y-m-d H:i:s", strtotime($current));
 //  $scenario->setLog($date);


son log

[2020-05-10 09:01:29][SCENARIO] Start : Scenario lance manuellement.
[2020-05-10 09:01:29][SCENARIO] Exécution du sous-élément de type [action] : code
[2020-05-10 09:01:29][SCENARIO] Exécution d’un bloc code
[2020-05-10 09:01:30][SCENARIO] 9.50
[2020-05-10 09:01:30][SCENARIO] recherche : 2020-05-09 18:00:00 valeur : 19.5
[2020-05-10 09:01:30][SCENARIO] premier 12.5 à 2020-05-09 00:00:00
[2020-05-10 09:01:30][SCENARIO] mini 9.50 à 2020-05-09 06:00:00
[2020-05-10 09:01:30][SCENARIO] Fin correcte du scénario

1 « J'aime »

Ce sujet a été automatiquement fermé après 24 heures suivant le dernier commentaire. Aucune réponse n’est permise dorénavant.