Archivhandler - ersten geloggten Wert ermitteln

Hallo,

wie kann man in einem Script aus dem Archiv von einem Datenpunkt einfach den Zeitstempel vom ersten geloggten Wert ermitteln, wenn mehr als 10000 Datensätze geloggt sind?

die Funktion AC_GetAggregationVariables liefert als Startdatum den ersten Wert von allen Variablen.
die Funktion AC_GetLoggedValues ist auf 10000 Datensätze beschränkt.

gibt es hier eine fertige Funktion, oder muss ich hier eine Iteration machen, bis weniger als 10.000 Datensätze retourniert werden.
(in der Echtdatenbank habe ich bei einem Datensatz ca 600.000 Werte (Wetterstation Temperatur) über mehr als 10 Jahre)

wäre super, wenn es hier eine Funktion gäbe, die den Zeitstempel richtig ermittelt und diesen Wert im Archiv auch richtig anzeigt.

lg
Wolfgang

hier mein Testscript. (schreibt eine Übersicht über alle Archiv-Variablen in eine HTML Box)


<?

class ContainerItem 
{
    public $AnzahlWerte = 0;
    public $Size = 0;
    public $varName = "  *** deleted ***";
    public $varPath = "  *** deleted ***";
    public $id = 0;
    public $erstesDatum = "";
    public $letztesDatum = "";
    public $AggregationType = "";
    public $visible = "";
    public $loggingAktiv = "";
    public $type = "";

    //-------------------------------------------------------------------------------    
    function __construct($item) 
    {
        $this->id = $item['VariableID'];
        $this->AnzahlWerte = $item['RecordCount'];
        $this->letztesDatum = date("Y-m-d   H:i:s", $item['LastTime']);
        $this->erstesDatum = date("Y-m-d H:i:s", $item['FirstTime']);

        $val = AC_GetLoggedValues (32753, $this->id, 0,0, 0);  
        if (sizeof($val) > 0)
        {
            $tempdate = $val[sizeof($val)-1];
            $this->erstesDatum = date("Y-m-d H:i:s", $tempdate['TimeStamp']);
        }

        if ($item['AggregationType'] == 0) 
            $this->AggregationType = "Std.";
        else
            $this->AggregationType = "Z.";

        if ($item['AggregationVisible']) 
            $this->visible = "Ja";
        else
            $this->visible = "NOT Visible";

        if ($item['AggregationActive']) 
            $this->loggingAktiv = "ja";
        else
            $this->loggingAktiv = "NEIN";

        $this->Size = round(floatval($item['RecordSize'] / 1024),1);

        if (IPS_VariableExists($this->id))
        {
            $xx = IPS_GetVariable($this->id);
            if ($xx["VariableType"] == 0) $this->type = "Bool";
            if ($xx["VariableType"] == 1) $this->type = "Int";
            if ($xx["VariableType"] == 2) $this->type = "Float";
            if ($xx["VariableType"] == 3) $this->type = "String";
            $this->varPath = IPS_GetLocation($this->id);
            $this->varName = IPS_GetName($this->id);
        } /* endif */
    }
    //-------------------------------------------------------------------------------
    function AsHTML() 
    {
        $HTML  = "<tr>";
        $HTML .= "<td>" . $this->id . "</td>";
        $HTML .= "<td>" . $this->varPath . "</td>";
        $HTML .= '<td style="text-align:right">' . $this->AnzahlWerte . "</td>";
        $HTML .= '<td style="text-align:right">' . sprintf("%.1f", $this->Size) . "&nbsp&nbsp&nbsp</td>";        
        $HTML .= "<td>" . $this->type . "</td>";
        $HTML .= "<td>" . $this->AggregationType . "</td>";
        $HTML .= "<td>" . $this->visible . "</td>";
        $HTML .= "<td>" . $this->loggingAktiv . "</td>";
        $HTML .= "<td>" . $this->erstesDatum . "</td>";
        $HTML .= "<td>" . $this->letztesDatum . "</td>";
        $HTML .= "</tr>";
        return $HTML;       
    }
} 

class Run
{
    public $liste = array();

    function __construct() 
    {
        $archivID = 32753;
        $vars = AC_GetAggregationVariables($archivID, false);
        foreach ($vars as $var) 
        {
            $item = new ContainerItem($var);
            $this->liste[] = $item;
        } 
        arsort ($this->liste);
    } 

    function Run()
    {
        $HTML = "<table width='100%' border='0' align='center'>";
        $HTML .= "<tr>";
        $HTML .= "<td>Objekt-ID</td>";
        $HTML .= "<td>Datenpunkt</td>";
        $HTML .= '<td style="text-align:right">Anzahl</td>';
        $HTML .= '<td style="text-align:right">Size [kB]</td>';
        $HTML .= "<td>Typ</td>";
        $HTML .= "<td>Aggr.Typ</td>";
        $HTML .= "<td>Sichtbar</td>";
        $HTML .= "<td>Log</td>";
        $HTML .= "<td>von</td>";
        $HTML .= "<td>bis</td>";
        $HTML .= "</tr>";

        foreach ($this->liste as $value) 
        {
            $HTML .= $value->AsHTML();
        }
        $HTML .= "</table>";

        SetValueString(29933, $HTML);
    }
}

$run = new Run();
$run->Run();

Archiv Anfang:

Anzeige ArchivVerwaltung:

ermittelte Werte mit AC_GetLoggedValues

Das ist leider eine Operation die nicht so effektiv lösbar ist. Die beste Idee, welche ich hätte, wäre im Archiv per AC_GetAggregationVariables die Variable raus zu suchen und dir dort die FirstTime anzusehen. Das sollte deine Suche dann eingrenzen, sodass du mit dem 10000er Limit zurecht kommst und nicht mehrere Anfragen machst. (Das solltest du definitiv nicht machen, da du dann alle Daten auf der Platte komplett durchsucht und dies immer „teuerer“ wird je mehr Daten du hast)

paresy

Hallo paresy,
vielen Dank für die Info.
Ich habs leider nur iterativ lösen können.
Vielleicht gibts mal eine richtige offizielle Funktion dafür. Dieser Wert wird in der Archiv-Übersicht ja auch falsch angezeigt.
Bei mir ist das auch nicht zeitkritisch, da das Script nur 1x am Tag aufgerufen wird und die Daten am Raspberry Pi 4 auf einer SSD liegen.

Info: ich brauche den ersten Zeitstempel zum Prüfen von meinem Datenbank-Cleanup. Ich logge fast alles im Archiv mit und lösche die meisten Daten automatisch nach max 3 Monaten wieder. (abhängig vom Variablenprofil).
Nur die Wetterstationsdaten und Energiezähler dürfen länger in der Datenbank bleiben.

Ich habs jetzt mal so implementiert:


$val = AC_GetLoggedValues (32753, $this->id, 0,0, 0);  // ersten Datensatz, 
if (sizeof($val) > 0)
{
    $tempdate = $val[sizeof($val)-1];

    // Check Limit --> rekursiv start ermitteln
    if (sizeof($val) >= 10000)   
    {
        $tempdate = $this->GetFirst($tempdate['TimeStamp']);
    }
	
........


function GetFirst($end)
{
    $rc = "";
    $i = 100;  // max 100 iterations
    while ($i--)
    {
        $val = AC_GetLoggedValues (32753, $this->id, 0,$end, 10000); 
        $rc = $val[sizeof($val)-1];
        $end = $rc['TimeStamp'];            
        if (sizeof($val) <10000)   
        {
            return $rc;
        }
    }
    return $rc;
}	

lg
Wolfgang