Script für konstante Graph-Namen und Autoregistrierung

Hallo,
ich habe / hatte das Problem, dass sich die Ergebnis-Dateinamen von einigen Graphen immer wieder änderten. Das trat insbesonders bei jedem Speichern z.B. nach Änderung von Einheiten-Strings o.ä. auf, wenn es sich um Multigraphen handelte, deren beteiligte Graphen selbst keine Graphen bauten, also rein virtuell waren / nur zur Datenerfassung dienten.

Besonders lästig ist dieses ständige Wechseln der Dateinamen, wenn man die Ergebnisse wiederum in andere Systeme oder Umgebungen einbinden will, weil der Name dann dort immer wieder angepaßt werden mußte. (Designer, eigene / andere Web-Server, Archivieren usw.)

Nachdem mir das heute vormittag zum wiederholten mal passierte, hab ich nachfolgende Lösung geschaffen, um künftig diesen Effekt ignorieren zu können.

Ich habe mir deshalb basierend auf
http://www.ipsymcon.de/forum/showpost.php?p=30003&postcount=10
ein Script gebaut, das zyklisch die vorgefundenen Ergebnis-Dateinamen des RRD-Moduls im WIIPS begutachtet und als Kopie in ein gesondertes Verzeichnis unter konstantem Dateinamen umbenennt und speichert.

Der Ziel-Dateiname ist dabei numerisch und identisch mit der Verwaltungs-ID des Graphen in WIIPS, hinten um das übliche „_day.png“ usw ergänzt. Also z.B. 12_day.png.

Die ID kann bei Sichtung innerhalb WIIPS in der URL des Grafik-Aufrufes als Parameter „…id=nn“ ermittelt werden (Identifikation der Grafik wird also intern auch so gemacht, sollte also das richtige Prinzip sein)

Bei Wechsel / Reset oder was auch immer des wohl zufällig generierten RDD-Datenbanknamens wird also künftig der Dateiname der Ergebnisse trotzdem konstant bleiben. Erst wenn man den Graphen als solchen neu anlegt, wirds wohl eine neue ID geben.

Nebenbei räumt das Script auch gleich ein wenig auf. Alle ehemals durch WIIPS geschriebenen Grafikdateien, die WIIPS selber inzwischen nicht mehr kennt, werden gelöscht (wenn das nicht gewollt ist: einfach auskommentieren. Es gibt nur einen „unlink“-Befehl im Script)

Dann werden außerdem die aktiven Graphen (so dort noch nicht bekannt) im IPS-Image-Pool registriert bzw (wenn bekannt) aktualisiert per IMGP_SendEvent. Hier greift die von Torro im o.g. Link vorgeschlagene Methode.

Und damit niemand meckert: Natürlich passiert das nur mit neu (seit letztem Lauf des Scripts) durch WIIPS aktualisierten oder angelegten Graphen. Die dazu notwendige Variable wird bei Bedarf genauso wie das Subverzeichnis zur Laufzeit angelegt.

Ich habe das Script im 15min-Abstand laufen, zusätzlich getriggert durch eine bei mir vorhandene Minuten-Timervariable auf die 3. Minute einer Stunde. Damit läuft es immer 3 Minuten nach dem Update der Graphen im WIIPS.

Die Include im Kopf ist unkritisch. Sie stellt lediglich den Scriptnamen ($myself) sowie ein Flag bzgl. Debugausgaben ($debug) bereit. Außerdem ist da eine function „loggen“ enthalten, die neben dem IPS-Log auch noch die Meldungen in SQL-Tabellen sowie kritische Dinge in Alarme packt. (die „Loggen“-Aufrufe notfalls auskommentieren / Strings per echo ausgeben o.ä.)

Ich dachte nur, daß der eine oder andere vielleicht vor ähnlicher Problematik steht, deshalb hier nun das Script:


<?
/*
*******************************
 IP-SYMCON Event Scripting
*******************************
File     : autoUpdateGraphs.ips.php
Trigger  : -
Interval : jede 3. Minute einer Stunde und dann alle 900 Sekunden (=15min), d.h. immer 3min nach Update durch WIIPS

Rel. 1   GW 27.11.2007

- vereinheitlicht automatisch die Dateinamen der Graphen
   - konstanter Dateiname, unabhängig vom ggf. wechselnden zugehörigen dbname
   - identisch zum URL-Parameter "ID=..." bei Aufruf in WIIPS
   - Name bleibt auch bei Wechsel des dbname gleich, z.B. nach speichern von Multigraphen, die nur virtuelle Graphen enthalten
   - mit gewohnter Namenserweiterung "_day", "_week", "_month", "_year"
   - neue Dateien auf ID-Basis in Subverzeichnis "graphs" (wird ggf. autom. angelegt) unterhalb "web_data/rrd/data/" als Kopie der dbname-basierenden Graphic-Dateien
- löschen im WIIPS nicht mehr verwendeter alter Graph-Dateien auf dbname-Basis (die, die keien ID im WIIPS mehr haben)

- für die seit letztem Run dieses Scripts seitens WIIPS aktualisierte Graph-Dateien / deren ID-basierende Dateien
  (Erkennung per timer-Variable "lastGraphUpdate.time", wird ggf. neu angelegt):
   - automatisches Registrieren im IPS-Image-Pool, so noch nicht erfolgt (als ID-Name ohne Pfad)
   - ansonsten aktualisieren des Image-Pools

- ggf. ToDo: Bereinigung der wiederum veralteten ID-basierender Namen im "graphs"-Unterverzeichnis
(für mich unnötig, weil ich die ID im lfd. Betrieb eher nicht ändern möchte / bei Fehlern die Dateien noch wiederfinden möchte)

auto-Event-Idee/Codezeilen: basierend auf Torro, 16.9.07, http://www.ipsymcon.de/forum/showpost.php?p=30003&postcount=10 ff
*/

// in der include: mein einheitliches Log-/Debug-/Alarm-Handling,
// definiert und steuert function "loggen" sowie Variablen "$myself" und "$debug"
include "_globals.ips.php";

$jetzt = time();  // als Variable für die ggf. notwendige Verwendung perpendikulärer Jetztzeit (siehe Snegow: Ring der Gegenzeit) :-)

// Variable zur Speicherung des Zeitstempels, wann dieses Script zuletzt lief
if (!IPS_VariableExists("lastGraphUpdate.time")) {   // wenn nicht existiert: Variable anlegen
   IPS_CreateVariable("lastGraphUpdate.time", "Integer");
   SetValueInteger("lastGraphUpdate.time", $jetzt);
}

$lastUpd = GetValueInteger("lastGraphUpdate.time");

$root = str_replace( '\\','/',IPS_GetKernelDir() );
$data = $root . "web_data/rrd/";
include $data."rrd.inc.php";
$data .= "data/";
$dircontent = scandir($data);
$anzahlU = 0;
$anzahlN = 0;
$anzahlD = 0;
foreach($dircontent as $filename) {
   if ($filename != '.' && $filename != '..') {
      if (substr($filename, -4) == ".png") {   // alle Bilddateien im Verzeichnis
         // Erkennung, ob Datei im WIIPS noch aktiv ist
         $aktivID = -1;
         list($dbKey, $rest)=explode("_", $filename, 2);
         foreach($graphs as $graph => $outkey) {
            $id=$graph;
            foreach($outkey as $key => $val) {
               if ((sizeof($dbKey) > 0) and ($key == "dbname") and ($val == $dbKey)) {
                  $aktivID = $id;
               }
            }
         }
         if ($aktivID > -1) { // Datei ist noch aktiv
            if ($debug) {loggen("aktiver WIIPS-Graph: ID=".$aktivID.": dbkey:".$dbKey."; file:".$filename, $myself);}
//            echo "ID:".$aktivID.": dbkey:".$dbKey."; file:".$filename.";
";

            // Subverzeichnis für namensstabile Graph-Files auf ID-Basis bedarfsweise anlegen
            $graphdir = $data."graphs/";
            if (!file_exists($graphdir)) {
               mkdir($graphdir);
            }
            // wenn dieses eine neue WIIPS-Graph-Datei seit letztem Update ist
            if ($lastUpd < filemtime($data.$filename) ) {
               $tname = $aktivID."_".$rest;   // Zielname bilden (Target-Name ohne Pfad)
               $tfname = $graphdir.$tname;    // Zielname bilden (Target-Name mit Pfad - Filename)
               copy ($data.$filename, $tfname);    // ...und Datei unter Zielname kopieren
               if (IMGP_ImageExists($tname)) {     // wenn Zieldatei im IPS bereits im Pool registriert ist
                  IMGP_SendEvent($tname);          // aktualisieren
                  $anzahlU++;
                  $hstr = "Image \"".$tname."\" aktualisiert (dbname=".$dbKey.")";
               } else {    // Image existiert noch nicht --> im Pool registrieren
                  IMGP_RegisterImage($tname, $tfname);
                  $anzahlN++;
                  $hstr = "Image \"".$tname."\" registriert (dbname=".$dbKey.")";
               }
               if ($debug) {loggen($hstr, $myself);}
            }
         } else {             // Datei nicht mehr aktiv --> kann gelöscht werden
            unlink ($data.$filename);
            $anzahlD++;
         }
      }
   }
}

SetValueInteger("lastGraphUpdate.time", $jetzt);

if ( $anzahlN + $anzahlU + $anzahlD > 0 ) {
   loggen("(".$anzahlN."/".$anzahlU."/".$anzahlD.") Graphen aktualisiert (New/Update/Delete)", $myself);
}

echo "fettich!
";
?>

Gruß Gerd

Hey, das hört sich klasse an.
Ich hab mich schon gar nicht mehr getraut irgendetwas an den Graphen zu ändern. Das werde ich am Wochenende implementieren.

Gruß
Klaus

Hallo gwanjek!
Respekt.:slight_smile:
Ich würde das auch gern nutzen.
Aaaber wo schreibe ich das Script hin?
Von was , wem wirds aufgerufen?

Schönen Tag :slight_smile:
Egon

Super script! Es sollte doch ausreichen das script laufen zu lassen, wenn sich an den WIIPS Graphen der Name ändert, d. h. nur wenn neu erstellt oder Parameter geändert. Ist da alle 15 Min nicht zuviel?

ich habs doch oben als Kommentar reingeschrieben…

Bei mir werden die Graphen alle 15min im WIIPS aktualisiert. Also lasse ich es auch alle 15min laufen. (im Script-Editor oben rechts „Events“ anklicken, dann im PopUp-Fenster unter „Timer Interval“ die Sekunden eintragen, die vergehen sollen, bis es wieder startet. Bei mir 900)

Um sicherzustellen, dass das nicht zeitgleich mit dem Erzeugen der Originalgraphen zusammenfällt, kann man noch einen anderen Weg gehen: Es auf die passenden Minuten triggern (bei mir jede 3., 18., 33. und 48. einer Stunde, also immer 3 min nach WIIPS). Ich habe sowieso aus einem anderen Zusammenhang her eine Minutenvariable, die ich dazu nehmen konnte (diese als Event-Variable bei „OnValue“ -mehrfach- registrieren, dann an der Variable selbst den Grenzwert eintragen bei dem getriggert werden soll, also 4 Einträge, je einer mit 3, 18, 33 und 48)

Wer so eine sich ständig aktualisierende Variable mit Minutenwert noch nicht hat:
Leider kennen die normalen Modi des IPS-Scheduler keine dedizierte Minute als Feuerbedingung, außer bei „once“. (klar kann man das mit „custom“ machen, aber wer das beherrscht, weiß eh wie das geht und brauch diesen Text nicht :slight_smile: ) --> Updatewunsch @paresy?

Diese Variable kann man sich durch ein weiteres Script bilden und aktualisieren lassen, das wie oben beschrieben an sich selbst alle 60sek oder durch den IPS-Scheduler minütlich getriggert wird.

Natürlich könnte man theoretisch auch das Original-Script selber minütlich aufrufen und dann eine große if-Bedingung drüber machen, ob auch grade die richtige Minute erreicht wurde. Da spicht aber gegen:

  • bei langsamer Hardware / viel Traffic könnte das Script vielleicht doch mal länger brauchen? Ich mag keine unnötigen mehrfach parallel laufenden Instanzen von Prozessen. Das bringt nur Ärger.

  • so ein Zeitwert-Trigger ist auch für anderes sehr nützlich, und sollte deshalb zentral im System bereitstehen. Bei mir gibts nicht nur die Minutenvariable, sondern für jeden Wert von Datum und Zeit eine, neben SA, SU, Wochentag (letztere auch als Timestamp), als Vergleichsbasis zur „Jetztzeit“ aus allen möglichen Scripts heraus (Jalousien runterfahren, Weihnachtslicht einschalten, Nachtschaltung Gewächshaus…). Aber Vorsicht: Wer das sekündlich triggert und in jeder Sekunde einfach alle Variablen neu setzt, sollte daran denken, das jedes Variablen-Schreiben ins Log kommt. Das explodiert dann und die Platte bekommt Schweißausbrüche! Also immer hübsch alte Werte auslesen (das wird nicht geloggt) neu jeden gebildeten mit dem passenden Altwert vergleichen und nur dann neu in Variable schreiben, wenn sich auch was geändert hat.

Bei einer Minutenvariable dürfte das aber noch unkritisch sein.

Der passende PHP-Befehl lautet:


   $mi=date("m", time());

im Designer z.B. mußt du dich schon entscheiden, ob du nun abc123xy_day.png oder 12_day.png als Grafikdatei einblenden willst. Und wenn die dann dort auch immer zeitnah aktuell zu sehen sein soll, muß logischerweise nachgezogen werden und die immer wieder alle 15min neu geschriebene Original-Grafikdatei umkopiert und diese per Event neu im IPS-Pool aktualisiert werden.

Genau das macht das Script

Edit:

Nochmal zum Verständnis: Das Script ersetzt nichts im WIIPS oder so, sondern behandelt lediglich die dort bereitgestellten Ergebnisse, um sie dann selber wieder zur Verwendung bereitzustellen. WIIPS arbeitet ganz normal weiter ohne irgendeine Änderung. Also muß es auch vom Zeitverhalten auf WIIPS abgestimmt laufen, es sei denn, Verzögerungen der Aktualisierung wären akzeptabel.