Fonction archive() de la class history

Bonjour,

Si j’ai bien compris, c’est la fonction archive() de la class history qui copie les enregistrements de la table history vers la table historyArch en éliminant les enregistrements qui se suivent et qui ont la même valeur.

Elle semble être lancée par la tâche cron :

Capture d’écran du 2022-01-09 22-58-06

j’ai lancé cette fonction manuellement dans un bloc code et je vois que les doublons ne sont pas supprimés.

history::archive();

J’ai aussi fait un script dans un bloc code de scénario pour voir le nombre d’enregistrements d’une commande qui aurait dû être éliminé.

$historys = history::all('8015');
$i = 0;
foreach ($historys as $key => $history) {
/*
  if ($key > 9) {
    break;
  }
*/
  if (is_object($historys[$key+1])) {
    $scenario->setLog($history->getDatetime() . ' ' . $history->getValue() . ' ---> ' . $historys[$key+1]->getDatetime() . ' ' . $historys[$key+1]->getValue());
    if ($history->getValue() === $historys[$key+1]->getValue()) {
      //$history->remove();
      $i++;
    }
  }
}
$reste = $key - $i;
$scenario->setLog("Nb Enregistrements à effacer $i/$key existants");
$scenario->setLog("Il restera après effacement $reste enregistrements");

Avec la fin du log :

[2022-01-10 00:32:52][SCENARIO] 2022-01-10 00:29:26 614839 ---> 2022-01-10 00:29:56 614839
[2022-01-10 00:32:52][SCENARIO] 2022-01-10 00:29:56 614839 ---> 2022-01-10 00:30:01 614839
[2022-01-10 00:32:52][SCENARIO] 2022-01-10 00:30:01 614839 ---> 2022-01-10 00:30:26 614839
[2022-01-10 00:32:52][SCENARIO] 2022-01-10 00:30:26 614839 ---> 2022-01-10 00:30:56 614839
[2022-01-10 00:32:52][SCENARIO] 2022-01-10 00:30:56 614839 ---> 2022-01-10 00:31:03 614839
[2022-01-10 00:32:52][SCENARIO] 2022-01-10 00:31:03 614839 ---> 2022-01-10 00:31:26 614839
[2022-01-10 00:32:52][SCENARIO] 2022-01-10 00:31:26 614839 ---> 2022-01-10 00:31:56 614839
[2022-01-10 00:32:52][SCENARIO] 2022-01-10 00:31:56 614839 ---> 2022-01-10 00:32:22 614839
[2022-01-10 00:32:52][SCENARIO] 2022-01-10 00:32:22 614839 ---> 2022-01-10 00:32:26 614839
[2022-01-10 00:32:52][SCENARIO] Nb Enregistrements à effacer 1527604/1597021 existants
[2022-01-10 00:32:52][SCENARIO] Il restera après effacement 69417 enregistrements

Jeedom v4.1.28
Merci pour vos avis.

1 « J'aime »

Bonjour,
il me semble que le mode de lissage rentre en jeu, il faudrait aussi voir la valeur de ce paramètre pour la cmd 815.

1 « J'aime »

La commande info 8015 est un index de compteur donc je n’ai pas mis de lissage.
Il y a un an d’historique.

Capture d’écran du 2022-01-10 10-10-13

Bonjour,
Je suis peut être un peu naïf mais ce ne sont pas de vrais doublons puisqu’ils ne sont pas enregistrés à la même date/heure?
Sauf en cas de lissage il n’y a pas re raison de les supprimer car ils font bien partie de l’historique…
PS; d’où tiens tu que l’archivage de l’historique supprime les doublons?

1 « J'aime »

Je n’ai pas une connaissance suffisante du PHP et je ne suis pas développeur donc je tâtonne.
Cet extrait de code me laisse penser que l’enregistrement est copié dans la table historyArch si la valeur de l’enregistrement précédent est différente de celle de l’enregistrement en cours que je nomme avec un abus de langage en "doublon".

Mais à la vue de la remarque de @Phpvarious :

Le mode de lissage à "Aucun" ne doit donc pas passer dans cette boucle.

Ici, c’est un bon contre exemple.
On ne lisse pas un index de compteur.
L’index est remonté entre 3 et 4 fois par minute dans Jeedom.
Sur des périodes de plusieurs heures, l’index ne change pas.
Quel est l’intérêt de garder toutes ces valeurs intermédiaires, à part encombrer la base de données.

@Jeandhom :
Pour le code ce n’est pas moi qui te jetterai la pierre! Mon âge avançant, apprendre n’est pas vraiment un problème mais se souvenir le devient…
A priori JEEDOM ne sait pas que c’est un index de compteur… On pourrait être intéressé à conserver les dates de remontée de la valeur. D’ailleurs d’après la doc sur une info bininaire JEEDOM n’archive que les dates.
Bon d’accord là je chipote :smiling_imp:

1 « J'aime »

J’ai poursuivi le code pour voir l’impact sur l’ensemble de mon historique.

$totI = 0;
$totKey = 0;
$totCmd = 0;
$histoCmds = cmd::allHistoryCmd();
foreach ($histoCmds as $histoCmd) {
  if ($histoCmd->getConfiguration('historizeMode') == 'none') {
    $totCmd++;
    $scenario->setLog($histoCmd->getId() . ' ---> ' . $histoCmd->getHumanName());
    $historys = history::all($histoCmd->getId());
    $i = 0;
    $key = 0;
    foreach ($historys as $key => $history) {
      /*
      if ($key > 9) {
        break;
      }
      */
      if (is_object($historys[$key+1])) {
        //$scenario->setLog($history->getDatetime() . ' ' . $history->getValue() . ' ---> ' . $historys[$key+1]->getDatetime() . ' ' . $historys[$key+1]->getValue());
        if ($history->getValue() === $historys[$key+1]->getValue()) {
          //$history->remove();
          $i++;
        }
      }
    }
    $reste = $key - $i;
    $scenario->setLog("Nb Enregistrements à effacer $i/$key existants");
    $scenario->setLog("Il restera après effacement $reste enregistrements");
    $totI = $totI + $i;
    $totKey = $totKey + $key;
  }
}
$totReste = $totKey - $totI;
$scenario->setLog("-------------------------------------------------------------------");
$scenario->setLog("Nb Enregistrements à effacer $totI/$totKey existants");
$scenario->setLog("Il restera après effacement $totReste enregistrements");
$scenario->setLog("Nb de commandes historisées : $totCmd");

Mode sans lissage :

[2022-01-10 18:28:09][SCENARIO] Nb Enregistrements à effacer 12353970/17159360 existants
[2022-01-10 18:28:09][SCENARIO] Il restera après effacement 4805390 enregistrements
[2022-01-10 18:28:09][SCENARIO] Nb de commandes historisées : 179

Tous les modes :

[2022-01-10 18:31:13][SCENARIO] Nb Enregistrements à effacer 12475906/18045576 existants
[2022-01-10 18:31:13][SCENARIO] Il restera après effacement 5569670 enregistrements
[2022-01-10 18:31:13][SCENARIO] Nb de commandes historisées : 375

Bonjour,
après avoir analysé la fonction un peu plus précisément, je constate une « anomalie » au niveau de la ligne 203 :

						if($cmd->getConfiguration('historizeMode', 'avg') == 'none'){
							for ($i = 0; $i < $countHistory; $i++) {
								$history[$i]->setTableName('historyArch');
								$history[$i]->save();
							}
						}else{
							if($countHistory > 1){
								for ($i = 1; $i < $countHistory; $i++) {
									if ($history[$i]->getValue() != $history[$i - 1]->getValue()) {
										$history[$i]->setTableName('historyArch');
										$history[$i]->save();
									}
								}
							}
							$history[0]->setTableName('historyArch');
							$history[0]->save();
						}

on constate que lorsqu’une commande est de type numérique sans lissage, celle-ci rentre dans la 1ère condition, donc aucun traitement des répétions de la valeur.
Il me semble que la bonne pratique aurait été de remplacer le comparateur de cette ligne :
if($cmd->getConfiguration('historizeMode', 'avg') == 'none'){
par
if($cmd->getConfiguration('historizeMode', 'avg') != 'none'){

Si une personne de l’équipe Jeedom passe par la pour confirmer :wink:
Bonne journée

1 « J'aime »

Bonjour
C’est exactement ce qu’on veut si pas de lissage on ne touche pas aux données donc pas de traitement des doublons

Merci Loïc pour ta réponse,
donc pour résumer si j’ai bien compris :

  • Si on a une valeur numérique.
  • Qu’on ne souhaites pas que cette valeur soit modifiée (donc pas avg/max/min) donc forcement « Aucun ».
    il n’est pas prévu d’avoir un traitement sur la suppression des valeurs répétitive lors de l’exécution de la fonction history().

Si mon analyse ci-dessus est correct, ne peut-on pas plutôt intégrer dans cette fonction history() une condition qui inclurai la configuration du « repeatEventManagement », comme ca pour les commandes dont la gestion des répétitions sont sur « Oui » on touche pas au doublon, et pour « non » on supprime les doublons ?

Merci.

1 « J'aime »

Oui c’est ça, pour ta proposition pourquoi bpas je l’ajouterai au évolution possible de la 4.3

2 « J'aime »

Perso je vois pas bien l’interet … :roll_eyes:

Je suis d’accord qu’il n’y a pas une énorme importance, mais c’est toujours des valeurs de moins dans l’historique, a mon sens quand on met la gestion de répétition a « non » je ne voit pas l’intérêt de stocker ces valeurs en bdd.

1 « J'aime »

J’avais imaginé le dédoublement du mode de lissage "jamais" en "jamais avec doublon" et "jamais sans doublon" mais ton idée est bien meilleure.

Merci pour ton éventuelle prise en compte.
Ce serait bien que cela soit aussi appliqué pour les infos binaires et autres.

Si c’est appliqué ça sera surement pour tout oui. Par contre il n’y aura pas de nouvelles options.

Si la répétition est non les valeurs sont pas en db normalement …
Et si tu réduit les valeurs plusieurs fonctions ne marcherons plus …

1 « J'aime »

Surtout pas, la proposition de @Phpvarious est bien meilleure.

Arf, effectivement tu as raison lorsque la commande est exécuté par « jeedom.cmd.execute »
la répétition des valeurs est bien prise en compte lors de l’archivage.
J’ai basé tous mes essais sur une commande perso d’un virtuel qui est maj par un event d’un scénario, et dans ce cas, il n’y a plus de gestion de répétition et toutes les infos sont donc envoyées en bdd.

1 « J'aime »

Pour moi avec le plugin-jmqtt, tout rentre en base de donnée.

Peu être le plugins qui ne gère pas le repeat … si il fait un publish et évent derrière c’est pas du retour d’état.