Instruction PHP pour créer une nouvelle ligne dans history

Bonsoir,

Dans un bloc code de scénario j’utilise des instructions event ou addHistoryValue pour ajouter des lignes dans history. Mais ces instructions mettent à jour la ligne dans history si elle existe déjà.

Je cherche donc (et je ne trouve pas…) une instruction (ou un paramètre des instructions que j’utilise déjà…) qui permette d’ajouter une ligne une première fois mais qui ne mette pas cette ligne à jour si elle existe déjà.

J’avais un lien vers la liste des instructions de l’API PHP mais ve lien e fonctionne plus et je n’arive pas à retrouver cette liste…

Merci pour votre aide.

Marc

Bonjour,

Tout dépend du « Mode de lissage » défini dans la configuration des commandes.
image

  • Avec lissage Aucun, une nouvelle ligne est créée à chaque valeur avec l’heure actuelle. Lors de l’archivage chaque nuit, les valeurs sont conservées à l’identique.
    image

  • Avec les autres Modes de lissage, les nouvelles valeurs sont lissées par tranche de 5 minutes. Les valeurs sont lissées par tranche d’une heure lors de l’archivage.
    image

Bonjour,

Non désolé, ce n’est pas ça, le mode de lissage est bien à « Aucun », mais si la ligne existe déjà dans history celle-ci est mise à jour par une nouvelle exécution des instructions que j’utilise actuellement.

EDIT ; je précise que l’id et datetime ne varient pas lors des exécutions suivantes. Je parle bien de history. Je ne m’occupe pas de historyarch, c’est le boulot automatique de Jeedom

Je cherche une autre instruction ou un paramètre à ajouter aux instructions que j’utilise actuellement.

Merci pour ton aide.

Quels paramètres utilisez-vous sur les fonctions event et addHistoryValue ?

Si le paramètre $_datetime est initialisé, la date dans history est forcée. S’il est null, l’heure actuelle est utilisée.

Voici ma programmation

$histoProdPV = cmd::byId($cmdIdCompteurProdPVOpt);

$histoProdPV->event($indexProdPVOpt,$date);
OU
$histoProdPV->addHistoryValue($indexProdPVOpt,$date);

Donc la date est forcée et écrase la valeur précédente de la même heure.
En mettant $histoProdPV->addHistoryValue($indexProdPVOpt);, l’heure actuelle sera utilisée dans history.

Mais JE VEUX forcer la date à la valeur que mon scénario à déterminer…
Je veux créer cette ligne à LA date et LA valeur déterminées par le scénario. Mais il se peut que plus tard le même contexte se présente et dans ce cas je ne veux pas que la ligne soit mise à jour, c’est à dire que LA valeur de la ligne ne soit pas modifiée.
Je pourrais arriver à ce résultat en détectant la répétition du contexte… Mais j’espérais pouvoir trouver un moyen, une instruction ou un paramètre qui bloque la mise à jour d’une ligne existante. En SQL la différence entre INSERT et UPDATE…

S’il y a une fonction qui fait ce que vous voulez, je ne la connais pas.
A voir dans les fichiers core/class/cmd.class.php et core/class/history.class.php si elle existe.

OK, merci pour votre aide.

Il faut que je retrouve comment tester la réussite ou la non réussite d’accès à une ligne peut-être déjà existante dans history…

Vous n’auriez pas le lien html vers le catalogue des instructions de l’API PHP de Jeedom ? Celui que j’ai n’est plus bon

Il y a ça: API Documentation mais c’est beaucoup moins complet que le code source. :wink:

NB: history::save semble faire REPLACE INTO

Salut,

En gros tu dois vérifier la présence ou non d’une valeur en historique à la même date/heure avant d’ajouter ta valeur en historique, tu dois pouvoir t’en sortir avec quelque chose dans cette idée :

$histoProdPV = cmd::byId($cmdIdCompteurProdPVOpt);

if (!is_object($history = history::byCmdIdAtDatetime($cmdIdCompteurProdPVOpt, $date) || $history->getDatetime() != $date) {
  $histoProdPV->addHistoryValue($indexProdPVOpt,$date);
}

Merci pour le lien jpty !!!

Bonsoir et merci Salviaf,

Oui, c’est tout à fait ce que je vais devoir faire.
Je vais essayer de décrypter le début de l’instruction, pas sûr que j’y arrive…
SI (je ne comprends pas le début du test) la date de la ligne history est différente de $date alors je crée une nouvelle ligne dans history

J’étudie, je teste, je te dis…

J’ai testé en forçant $date avec la valeur existante dans history et en forçant la valeur de $indexProdPVOpt à 5000 puis à 6000
Le teste « != $date » est toujours vrai et donc la ligne déjà existante dans history est mise à jour.
Mais comme je ne comprends pas la première partie du teste "!=’ je suis paumé…
Précision : $history vaut « toujours » 1

Bonjour,

Ça fonctionne mieux en sortant l’affectation du test.

$history = history::byCmdIdAtDatetime($cmdIdCompteurProdPVOpt, $date);
if (!is_object($history) || (is_object($history) && $history->getDatetime() != $date)) {
  $histoProdPV->addHistoryValue($indexProdPVOpt,$date);
}

history::byCmdIdAtDatetime retourne la dernière history avant $date → donc test si datetime != $date à faire

Attention cmd::event() appelle cmd::addHistoryValue()

Bonjour jpty,

Pour tester et essayer de comprendre le fonctionnement des instructions, j’ai ajouté cela en toute fin de scénario :

$history = history::byCmdIdAtDatetime($cmdIdCompteurProdPVOpt,$date);
$scenario->setLog("history : ".$history);

La présence du paramètre .$history dans $scenario-> bloque complètement l’alimentation du Log du scénario. J’en déduis que le contenu de $history n’est pas affichable…

Quant à l’instruction suivante, je ne comprends pas la partie 1 du test « != »
Autrement dit, je ne comprends pas :

!is_object($history) || (is_object($history) && $history->getDatetime()

Pourriez-vous me la décrypter ?

Merci pour votre aide !

  • history est un objet. Il faut le transformer en chaine pour setLog
$scenario->setLog("History Object: " .print_r($history,true));

image

ou utiliser les fonctions pour accéder au contenu de l’objet:

  $scenario->setLog("Cmd_id : " .$history->getCmd_id());
  $scenario->setLog("Histo Datetime : " .$history->getDatetime());
  $scenario->setLog("Value : " .$history->getValue());
  $scenario->setLog("Tablename : " .$history->getTableName());

image

  • Pour le test :
!is_object($history) // history n'est pas un objet: commande non historisée ou sans historique pour l'instant
      || // ou
(is_object($history) && $history->getDatetime() != $date) // history est un objet et sa date est différente de $date

history::byCmdIdAtDatetime retourne la dernière history <= $date → le test si datetime != $date est nécessaire

1 « J'aime »

A partir du moment où on passe dans le OU il n’est pas nécessaire de revérifier is_object($history), si ?

Avec OU les 2 « cotés » du ou sont évalués.

Bah oui, je suis c*n fatigué :wink: