USV-Datenlog in IPS einlesen

Hallo,
nachfolgend als Ergebnis der Orkan-Emma-Vorsorge des letzten Wochenendes (endlich mal USV in Betrieb genommen, falls Strom wieder ausfällt…), ein Script, dass das Datenlog einer USV (im konkreten Beispiel: Smart-UPS von APC) in IPS-Variablen einliest.

Edit:

Ergänzung: (APC-)USVs schreiben zwei Logs: Ein Datenlog und ein Eventlog. Dieser Artikel beinhaltet das Einlesen des Datenlogs. Hier dagegen ein Beispielscript zum Einlesen des Eventlogs der USV

Die Steuersoftware von APC heißt „Powerchute“ und kann in der Basic-Version von APC.com kostenfrei nach Registrierung runtergeladen werden. Aktuelle Version: 7.0.5 Build 108. Es gibt auch ein Patch für Vista, ansonsten ist die Basic-Version im LAN auch remote betreibbar (getrennte Agent-Server-Client-Architektur, auch mehrere USV-gepufferte Maschinen=Agents mit einem Powerchute-Server managebar)

Das Powerchute selbst, das natürlich erstmal als Hauptaufgabe das „geordnete Herunterfahren, falls Batterie dann auch leer ist“ usw. macht, legt zyklisch Daten-Records in ein Log auf den Server. Im Programm kann dazu u.a. der Bereinigungszyklus sowie die „Dichte der Signalaufzeichnung“ eingestellt werden. (Zitat Help-Datei: „From a minimum of 10 seconds, through a maximum of 59 minutes (20 minutes is the default).“

Was sind das für Daten:

Die APC-USVs haben bereits einen internen Temperatursensor (per Offset: Aussage zur umgebenden Raumtemp.). Weiterhin werden pro Record z.B. aufgezeichnet: anliegende Spannung, gelieferte Spannung, Batteriespannung, „Load“ also Last an der USV, Netzfrequenz usw. Ist natürlich alles für Serverraumüberwachung usw. gedacht, aber hier auch ganz nützlich, besonders wenn der IPS-Server „irgendwo klimarelevant untergebracht“ stehen sollte. …und man sowieso schon so eine USV zum Abfedern von Stromausfällen bzw. -aussetzern und -schwankungen in Betrieb hat.

Schließt man optionale APC-Sensoren an die USV an, kann man sogar Daten zur Feuchtigkeit und weitere externe Temp-Werte bekommen, die ebenfalls in dieses Log einfließen.

Mein Ziel ist vor allem, Aussagen zur Qualität der gelieferten Spannung zu bekommen. Z.B. ist es im regionalen Umfeld in letzter Zeit üblich geworden, statt 230V insbesonders nachts regelmäßig >240V zu liefern. Wenn man bedenkt, das die Rotation der Zähler-Scheibe spannungsabhängig zunimmt… Ich möchte (erstmal) zumindest ein Auge drauf haben können, wo sich IPS und WIIPS natürlich automatisch anbieten.

Das Log wird im folgenden Script zyklisch ausgelesen sowie recordweise (=alle Werte einer Zeile im Log) in Variablen gelegt. Die 4-Sekunden-Verzögerung („sleep(4)“) am Ende der Schleife bewirkt, dass bei evtl. mehreren zwischenzeitlich als „neu“ aufgelaufenen und zu verarbeitenden Records dazwischen genügend Zeit bleibt, um diese durch andere Scripts weiter zu verarbeiten (z.B. per „OnUpdate“ getriggert in Datenbank eintragen o.ä.)

Eine Besonderheit ist die Variable „UPS.Datalog.lastTs“. Diese hält den Zeitstempel (=Timestamp), bezogen auf die Record-Logzeit der letzten erfolgreich eingelesenen Log-Zeile. Also wenn die letzte erfolgreich gelesene Zeile den Zeitstempel „01.03.2008 10:38:15“ hatte, werden im nächsten Aufruf des Scripts nur nach darauf bezogen neueren Log-Zeilen gesucht und diese eingelesen.

Damit ist das Script derart robust, dass selbst ein Abbruch wegen maximaler Script-Laufzeit von 150(?) Sekunden nichts ausmacht. Im nächsten Zyklus macht es einfach beim nächsten Log-Record weiter.

Meine Funktion „SetValue()“ ist übrigens eine Vereinfachung bzgl. der unterschiedlichen Typen (Int, Boolean, Float, String), die darin automatisch erkannt werden. Außerdem werden auch gleich, wenn noch nicht vorhanden, passende Variablen im IPS anzulegen. Wenn ich Paresy richtig verstanden habe auf dem IPS-Together, ist das ja bei V2.0 dann ohnehin so.

Edit:

„SetValue()“ steht einen Beitrag tiefer!

Wer das nicht hat/will: einfach aus „SetValue()“ dann „SetValueFloat()“ oder „SetValueInteger()“ machen.

Ebenfalls in der Include-Datei „_globals.ips.php“:

  • semaset() und semareset() = Semaphoren-Handling
  • Bildung der Variable „$myself“ = Scriptname
    Wer es nicht braucht: einfach auskommentieren.

Viel Spass damit
Gerd


<?
/*
*******************************
 IP-SYMCON Event Scripting
*******************************
File     : readApcLog.ips.php
Trigger  : ---
Interval : Zyklus wie Zeitabstand UPS-Data-Log  (Default 20 min = 1200 Sec)

APC Powerchute Data Log einlesen

Rel. 1   GW    01.03.2008

*/

include "_globals.ips.php";
semaset($myself, 10000);

if (!IPS_VariableExists("UPS.Datalog.Path")) {    // wenn Variable fehlt: anlegen
   IPS_CreateVariable("UPS.Datalog.Path", "String");
   SetValueString("UPS.Datalog.Path", "c:\Programme\APC\PowerChute Business Edition\agent\DataLog");
}
$datei = GetValueString("UPS.Datalog.Path");

if (!IPS_VariableExists("UPS.Datalog.lastTs")) {    // wenn Variable fehlt: anlegen
   IPS_CreateVariable("UPS.Datalog.lastTs", "Integer");
   SetValueInteger("UPS.Datalog.lastTs", 0);
}
$lastTs = GetValueInteger("UPS.Datalog.lastTs");
$zTs = 0;

if (file_exists ($datei)) {
   $zeilen = liesFile($datei);
   foreach ($zeilen as $zeile) {
      $zeile = preg_replace("/\s+/", "|", $zeile);
//      echo $zeile."
";
      $dat = explode("|", $zeile);
      if (sizeof($dat) > 9) {
         if ((strpos($dat[0], "/") === 2) and (strpos($dat[1], ":") === 2)) {
            list($monat, $tag, $jahr) = explode("/", $dat[0]);
            list($stunde, $minute, $sekunde) = explode(":", $dat[1]);
            $zTs = mktime($stunde, $minute, $sekunde, $monat, $tag, $jahr);
//            echo $zTs."
";
            if ($zTs > $lastTs) {
//               echo makeFloat($dat[2])."
";
               SetValue("UPS.Data.MaxLineVoltage", makeFloat($dat[2]));
               SetValue("UPS.Data.MinLineVoltage", makeFloat($dat[3]));
               SetValue("UPS.Data.LineVoltage", makeFloat($dat[4]));
               SetValue("UPS.Data.OutputVoltage", makeFloat($dat[5]));
               SetValue("UPS.Data.BatteryVoltage", makeFloat($dat[6]));
               SetValue("UPS.Data.OutputFrequency", makeFloat($dat[7]));
               SetValue("UPS.Data.UpsLoad", makeFloat($dat[8]));
               SetValue("UPS.Data.UpsInternalTemperature", makeFloat($dat[9]));
               SetValue("UPS.Data.Ts", $zTs);
               SetValue("UPS.Data.Time", date("d.m.Y", $zTs)." ".date("H:i:s", $zTs));
               SetValue("UPS.Datalog.lastTs", $zTs);
               sleep(4);
            }
         }
      }
   }
}

semareset($myself);

function makeFloat($wert) {
   return floatval(preg_replace("/,/", ".", $wert));
}
?>

ok… Vielleicht auch in anderem Zusammenhang mal ganz nützlich. Deshalb hier nun die „SetValue()“-Funktion:

  • trägt übergebenen Wert in eine IPS-Variable ein
  • erkennt selber welchen Typ die einzutragene Variable haben muß
  • legt notfalls eine Variable an
  • erkennt Typkonflikte bei schon bestehenden Variablen --> Log / Returncode

ACHTUNG:

  • die Funktion „loggen()“ (4.letzte Zeile) anpassen oder notfalls auskommentieren

Viel Spass damit
Gerd


function SetValue ($var, $wert) {   // Variable setzen, wenn Variable fehlt: anlegen
// GW   1/2008
   $typErr = "";
   $strFlag = false;
   if (is_string($wert)) {
      $strFlag = true;
   }
   if ((!$strFlag) and (is_numeric($wert))) {
      if (is_int($wert)) {
         if (!IPS_VariableExists($var)) {
            IPS_CreateVariable($var, "Integer");
         }
         $vTyp = IPS_GetVariableType($var);
         if ($vTyp == "Integer") {
            SetValueInteger($var, $wert);
         } else {
            $typErr = "Integer";
         }
      } else {
         if (!IPS_VariableExists($var)) {
            IPS_CreateVariable($var, "Float");
         }
         $vTyp = IPS_GetVariableType($var);
         if ($vTyp == "Float") {
            SetValueFloat($var, $wert);
         } else {
            $typErr = "Float";
         }
      }
   } elseif ((!$strFlag) and (is_bool($wert))) {
      if (!IPS_VariableExists($var)) {
         IPS_CreateVariable($var, "Boolean");
      }
      $vTyp = IPS_GetVariableType($var);
      if ($vTyp == "Boolean") {
         SetValueBoolean($var, $wert);
      } else {
         $typErr = "Boolean";
      }
   } else {
      $strFlag = true;
   }
   if ($strFlag) {
      if (!IPS_VariableExists($var)) {
         IPS_CreateVariable($var, "String");
      }
      $vTyp = IPS_GetVariableType($var);
      if ($vTyp == "String") {
#echo $wert;
         SetValueString($var, $wert);
      } else {
         $typErr = "String";
      }
   }
   $rc = true;
   if (strlen($typErr) > 0) {
      loggen("Variable \"".$var."\" vom falschen Typ! Ist/Soll(Wert): ".$vTyp." / ".$typErr." (\"".$wert."\")", $myself);
      $rc = false;
   }
   return $rc;
}


Hallo Gerd

> (im konkreten Beispiel: Smart-UPS von APC)

Welches Modell hast Du denn genau?

VG
Stephan

Ich habe sie im Moment nicht vor der Nase, aber es war (soweit ich mich erinnere) eine Smart UPS 1000VA. Ist schon älter und Akku auch schon mal ausgetauscht, aber für die Software ist das egal.

Das Powerchute ist das aktuellste, am Wochenende frisch bei APC gezogen. Das kann auch mit anderen Modellen von USVs umgehen, z.B. auch die „Matix“-Modelle usw. In der Fa. und bei Kunden haben wir das Powerchute auch mit noch anderen USV-Versionen im Einsatz, sowohl Rack-Modelle als auch Standalone, große wie kleine.

Und erst das Powerchute holt und speichert ja die originalen Datenlogs, die ich dann mit dem Script ins IPS hole.

Notfalls wäre das Datenformat anzupassen sowie evtl. der Pfad. Aber (ohne 100%-Garantie): diese Daten-Dateien gab es in dieser Form auch schon vor 10 Jahren sogar schon unter Novell, zumindest inhaltlich (evtl. Spalten nur getauscht) auch in dieser Form, Arbeitsweise und Syntax.

Zu USV-Modellen anderer Hersteller kann ich jetzt nichts sagen, da ich diese nicht im Einsatz habe. Bietet sich nunmal an, das zentralisiert zu managen, ergo bleibts bei einem Hersteller. Aber wenn die zumindest eine Textdate mit Daten ablegen, sollte das ähnlich verarbeitbar sein. Und APC ist ja inzwischen auch für Privatuser erschwinglich und ohnehin sehr weit verbreitet.

Bezugsquelle USV z.B.: http://www.alternate.de (dort: Hardware / Energie / USV)

Gruß Gerd

Gruß Gerd

   $zeilen = liesFile($datei);

Machst du etwas besonderes bei „liesFile“?

Schade das du nicht alle notwendigen Funktionen mit angibst :(.

Danke für den Tipp. War nicht beabsichtigt es vorzuenthalten und ich habe es schlichtweg übersehen. Die Function liegt natürlich auch in der Include-Datei.

Ich bin es nunmal gewohnt, bestimmte Dinge zu zentralisieren, die ich an mehreren Stellen gebrauche. Dateien einlesen gehört da sicher dazu. Ist einfach eine Frage der Wartbarkeit von Software, sowas bedarfsweise nur an einer Stelle anpassen zu müssen.


function liesFile ($file) {
// Zeilenweises Einlesen einer Textdatei in ein Array
   $lines = array();
   if (file_exists ($file)) {
      $msg = file_get_contents($file);
      $lines = explode("
", $msg);    // nach Zeilenumbruch trennen
   }
   return $lines;
}


Danke, passt schon ;). Ordentliche Strukturierung/Programmierung ist erheblich übersichtlicher.

Allerdings führt der Start über „Execute“ zum Dauerläufer für die maximale Scriptlaufzeit.
Das muss ich mir heute Abend noch mal genauer ansehen.

Immerhin werde die Variablen gesetzt :).

Ähmmm… Nix „execute“:


include "_globals.ips.php"; 

Includes werden zur Laufzeit Bestandteil des laufenden Scripts, so als wenn der Code da vorher reinkopiert worden wäre…

Das Script selber hat einfach bei „Script Events“ ein Timer-Interval von 1200 Sekunden bekommen, schneller kommen vom Powerchut eh keine neuen Daten. Da gibt es auch keinen „Dauerläufer“, im Gegenteil, notfalls killt das die maximale PHP-Scriptlaufzeit ja sogar schon nach 150 Sekunden. Das wird aber auch nur „ausgereizt“, wenn viele neue Logeinträge nachzutragen sind, z.B. weil IPS aus war. Normalerweise liegt die Laufzeit im Bereich <1 Sekunde.

Nicht mißverstehen! Das „Powerchute“ ist ein eigener, von IPS unabhängiger Windows-Dienst mit eigener Client-Komponente zum Managen. Dieser stellt die Schnittstelle zwischen USV und Computer dar, nimmt also Befehle an von der USV, um z.B. den Rechner geordnet runterzufahren, wenn auch die USV-Batterie leer ist, oder weckt den Server wieder auf, sobald der Ladezustand das wieder erlaubt. „Nebenbei“ schreibt dieser Dienst auch besagtes Datenlog, im Defaultfall alle 20 Minuten eine Zeile.

Das o.g. Script arbeitet, IPS intern zyklisch gestartet, davon völlig unabhängig, und holt einfach zwischenzeitlich neu angefallene Daten ins IPS. Und das auch noch robust „Lücken aufarbeitend nach Ausfall“.

Sinn des Ganzen (neben IPS-Server-Anlagenüberwachung inkl. deren lokaler Temperatur): Daten zur im Haus anliegenden Stromversorgung bekommen, Spannung, Frequenz usw., und das über die gesamte Zeit, und direkt, wie es direkter nicht geht. Denn die USV liest sowas nunmal naturgemäß sehr genau :slight_smile:

Hallo Gerd,

es gibt in PHP die Funktion file(…).

Diese liest eine Datei zeilenweise in ein Array ein.

Mir scheint sie tut dasselbe wie Deine Funktion liesFile(…).

Ich selbst bin immer bestrebt vorhandene Funktionen zu verwenden, da diese meist wesentlich effizienter laufen als Skript-Code.

Gruß
HJH

tja, PHP ist für mich im Gegensatz zu anderen Sprachen eben immer noch Neuland. Da habe ich eben all die Befehle noch nicht „live drauf“. Aber bei dem, was da im Listing der Function noch zu sehen ist, mag das sogar zutreffen, das die nun im Verhalten identisch ist zu einer Function des Standard-Sprachumfanges.

Ich mache in der Function aber mehr, als hier im Print noch zu sehen ist, weil ich das andere rausgenommen habe, denn der Rest hat nichts mit der eigentlichen USV-Funktionalität zu tun. Stichwort: Datei ggf. nicht lokal sondern aus dem Netz holen und das auch noch evtl unterschieden nach LAN-Freigaben oder remote per FTP. Die Entscheidung darüber fällt anhand zur Laufzeit ermittelter Aussagen zur Systemumgebung und -konfiguration. Dafür gibt es sicher in Gänze keine „build in function“.

Anwendung findet die gleiche Function z.B. auch beim Verarbeiten von Bildern und AVIs, die CAMs zyklisch oder bei Bewegungserkennung ablegen. Und das kann schon mal woanders sein als auf der lokalen Maschine, die den Backgroundprozess durchführt (das Perl-Original auch noch zufällig verteilt bei Lastverteilung in Mehrserverumgebungen, Applikationsserver holen sich das dann selbstentscheidend von der Datei-Input-Maschine ab). Dazu kommt dann noch diverses Logging- und Fehlerhandling.

Bei USVs kann das m.E. auch zutreffen, denn es kann ja mehrere Maschinen geben, deren Datenlogs in ein IPS einfließen sollen.

Aber damit wollte ich den „Normalanwender“ nicht auch noch verwirren / mir die Option offenhalten, durch Verwendung dieser bei mir ja vorhandenen Function mir zumindest den Weg dazu bei dieser Anwendung nicht a priori zu verbauen.

Es macht (für mich) also sehr wohl Sinn, diese gesondert und zentralisiert in einer Include zu halten. Und jedem anderen steht es frei, das bei sich anzupassen.

Gruß Gerd

Das war schon klar, habe ich natürlich auch so gemacht.

Ich drücke zum Testen immer erstmal „execute“. :slight_smile:

Test mit leerer Logdatei führt zur sofortigen Beendigung.

Erster Test mit Inhalt, hier 4 Datensätze, beendet korrekt. Die weiteren auch.

Das wird aber nicht lange so weitergehen, denn wenn ich das Script richtig verstehe liest du immer die komplette Datei ein und verarbeitest das Datumsfeld. Ist ja auch klar, du willst ja nur die Neuen.

Zweiter Test mit 2000 Datensätzen (neuen) führt zum 150 Sekunden Timeout. Ist ja auch logisch, da 38*4 Sekunden mehr als 150 Sekunden sind.

Ich passe mal die Zeiten und Mengen aufeinander an, dann sollte es klappen.

Ich kann übrigens bei der Powerchute den Timer auf minimal 10 Sekunden stellen und die werden auch sofort ins Log geschrieben. Somit könnten schon Daten vor Ablauf der 1200 Sekunden kommen, sogar mehr wie das Script auf einmal verarbeiten kann ;).

Brauchst du nicht. Im nächsten Zyklus macht das Script da weiter in der Logdatei, wo es vorher abgebrochen war. Nach ein paar Zyklen pendelt sich das ein.

Die eigentliche Verarbeitungszeit pro Record ist vernachlässigbar, sagen wir mal 1 Sek. Zusammen mit der 4 Sek Wartzezeit im sleep() am Ende der Schleife sind das 5 Sek pro Record. Also bekommst du pro Scriptaufruf und Timeout von 150 Sek. 30 Records rein, bei einem Zuwachs von 1.

Doch, wird es. Im Powerchute stellt man auch ein, nach welcher Zeit sich das Log „hinten“ selbst bereinigt. Der kleinste Zyklus ist „täglich“. Damit ist eine stets konstante Länge vorgegeben. USVs sind glücklicherweise auf unüberwachten Langzeitbetrieb getrimmt :slight_smile:

Deswegen steht ja oben als Kommentar in Zeile 5:


/*
...
Interval : Zyklus wie Zeitabstand UPS-Data-Log  (Default 20 min = 1200 Sec) 
...
*/

Also: Zyklus des Scriptaufrufes an den im Powerchute eingestellten Daten-Schreib-Zyklus anpassen!

Das Script verarbeitet soviel Records, wie es schafft vor Timeout. Im Neuen Zyklus macht es weiter. Wenn du es also alle 180 Sekunden (3 Min) neu starten läßt bei Timeout von 150 Sekunden, arbeitet es (wieder bei 4 Sek. Sleep) 600 Records in der Stunde.

Ich bezweifle mal, das es sinnvoll ist, die Abtastrate für die anliegende Spannungs-Qualität derart hoch zu setzen. Es geht hier wie gesagt um das DATA-Log der USV, nicht etwa um das Event-Log, wo Ereignisse wie kurzzeitige Unter-/Überspannung, Selbsttest usw. drin stehen. Die kann man z.B. direkt aus dem Windows-Eventlog auslesen.

Warum also derart hochfrequent abtasten? Alle 10 Sekunden ändert sich die Umgebungstemp. nicht wirklich. Auch Spannungshöhe und -Frequenz haben größere Zyklen.

Weiterhin wenn z.B. Graphen im WIIPS erzeugt werden sollen, liegt die Abtastfrequenz des RRD-Datenloggers auch im Minutenbereich. Also würde ich die Inputwerte (ohne anderen triftigen Grund) nicht höherfrequent abtasten, da die überschüssig „zwischendurch reinkommenden“ dann ohnehin redundant wären und verloren gingen, ohne das sie verarbeitet würden.

Und selbst wenn es Anlass gäbe für noch höhere Abtastfrequenz:
Man kann ja noch das Sleep in der Schleife selber niedriger setzen oder auch ganz rausnehmen, welches bei mir nur dazu dient, anderen Scripts sicher ermöglichen, per Output-Variablen getriggert, die her reinkommenden Daten recordweise weiter zu verarbeiten, z.B. bei mir: in Datenbank zu schreiben.

Die Änderungszyklen der anliegenden Werte sind derart langsam, das man ohnehin alle Zeit der Welt hat, das auf diesen Weg sicherzustellen. Zwischendurch bleibt sogar Zeit genug, evtl. entstandene Lücken (mehrere unverarbeitete Records) aufzuarbeiten.

…Und dann könnte man sogar noch die maximale Scriptlaufzeit in der PHP.ini hochsetzen. Torro empfielt nach letztem WIIPS-Update da nun ohnehin 250 Sekunden. Aber vorsicht, da sind alle Scrupts von betroffen!

Gruß Gerd

Hier nun als Ergänzung zum bisher beschriebenen Einlesen des Datenlogs, das Einlesen des Eventlogs. Um Irritationen bzgl. meiner speziellen Anpassungen zu vermeiden, lege ich es hier als „Prinzipstudie“ mit „echo“-Ausgabe ab, die sich dann ja jeder selber an seine Bedürfnisse anpassen kann.

Es gibt zwar auch ein eventlog-File, aber das hat ein spezielles Datenformat. Einfacher ist es, die Events direkt aus dem Windows-Eventlog auszulesen. Die Abfrage in MS-SQL-Syntax filtert bereits nach USV-spezifischen Einträgen.

Gegebenenfalls ist der Inhalt der 1. Zeile
$apcname = „APCPBEAgent“;
dafür anzupassen.


$apcname = "APCPBEAgent";
$WMIService = new COM("WinMgmts://./root/cimv2");
$logItems = $WMIService->ExecQuery("SELECT * FROM Win32_NTLogEvent WHERE SourceName='".$apcname."'", "WQL", 0x10 | 0x20);
foreach ($logItems as $logItem) {
   echo $logItem->TimeGenerated . ': '.
        $logItem->EventCode . ': ' .
        $logItem->SourceName . ': ' .
        $logItem->EventType . ': ' .
        $logItem->Message. "
";
}

Als Ergebnis erscheinen die (gegenüber dem Datenlog in Anzahl viel weniger) Zeilen des Eventlogs, welches ebenfalls im Powerchute bezüglich seiner maximalen Länge konfigurierbar ist (aber hier: maximale Anzahl Records; logisch, da ja ein Tages- oder Wochenbezug der Ereignisse unbestimmt ist)

Hier das Beispiel, wie das Ergebnis mit obigem Script „roh eingelesen“ aussieht:


20080302224000.000000+060: 1002: APCPBEAgent: 3: "Communications Established"
20080302223953.000000+060: 3000: APCPBEAgent: 1: "Lost Communication With UPS"
20080302223952.000000+060: 1002: APCPBEAgent: 3: "Communications Established"
20080302223952.000000+060: 1001: APCPBEAgent: 3: "Monitoring Started"
20080301192304.000000+060: 1004: APCPBEAgent: 3: "UPS Self-Test Passed"
20080301182612.000000+060: 1002: APCPBEAgent: 3: "Communications Established"
20080301182612.000000+060: 1001: APCPBEAgent: 3: "Monitoring Started"

Da würden dann auch (so aufgetreten) die „momentary power sac“- oder „power failed, ups is switching to battery“-Meldungen erscheinen.

Prinzipiell reichen die Zeitstempel (TimeGenerated) sowie die Message. Aber ich habe der Vollständigkeit halber mal andere Werte stehen lassen, vielleicht braucht das jemand.

Ansonsten gibt es weitere Informationen zum Windows-Event-Log und seinen Feldern in der MS-Technet. Oder per Google.

Technet-Beispielin JScript (wegen der möglichen Parameter)

Leider habe ich noch keinen Weg gefunden, zum dieses oder andere Logs eventgesteuert ins IPS einzulesen, also nicht erst evtl. zeitverzögert bis zum nächsten Zyklus verzögert zu lesen, bzw. ohne die sinnlose Last, es ständig in kurzen Zyklen laufen lassen zu müssen, obwohl tagelang nichts auftritt.

Aber vielleicht hat da ja jemand anders eine Idee?

Andererseits hat Powerchut u.a. auch den Benachrichtigungs-Kanal „eMail“, der bei Angabe eines SMTP-Servers genau diese Meldungen als Events versendet, was mir wiederum ausreicht.

Gruß Gerd

Sehr interessant,
ich mache das schon eine Weile so, habe gerade vorgestern das Script angepasst. Von den hier genannten Problemen habe ich bisher nichts gemerkt. Zum Aufbereiten der Datei nehme ich $data = fgetcsv ($fp, 300, " ")

Visualisiert wird das ganze übrigens mit jpgraph.

Gruß
Maik

hallo,

da das script mit meinem ips (2.1) nichtmehr lief hier eine angepasste variante:
einziger nachteil: die werte kommen als string raus, alle variablen müssen von hand angelegt und verändert werden!


<?

//bitte setzen!

$datei='c:\Programme\APC\PowerChute Business Edition\agent\DataLog'; //Pfad zur DataLog von PowerChute
$leistungusv=700; //Wattzahl deiner USV (smart usv 1500 dann muss hier 1500 stehen) 


function liesFile ($file) {
// Zeilenweises Einlesen einer Textdatei in ein Array
   $lines = array();
   if (file_exists ($file)) {
      $msg = file_get_contents($file);
      $lines = explode("
", $msg);    // nach Zeilenumbruch trennen
   }
   return $lines;
}






$lastTs = GetValueInteger(16021 /*[USV auslesen\lastts]*/ );
$zTs = 0;

if (file_exists ($datei)) {
   $zeilen = liesFile($datei);
   foreach ($zeilen as $zeile) {
      $zeile = preg_replace("/\s+/", "|", $zeile);
//      echo $zeile."
";
      $dat = explode("|", $zeile);
      if (sizeof($dat) > 9) {
         if ((strpos($dat[0], "/") === 2) and (strpos($dat[1], ":") === 2)) {
            list($monat, $tag, $jahr) = explode("/", $dat[0]);
            list($stunde, $minute, $sekunde) = explode(":", $dat[1]);
            $zTs = mktime($stunde, $minute, $sekunde, $monat, $tag, $jahr);
//            echo $zTs."
";
            if ($zTs > $lastTs)
				{
//               echo makeFloat($dat[2])."
";
               SetValue(45037 /*[USV auslesen\maxV]*/ , $dat[2]);
               SetValue(11032 /*[USV auslesen\minV]*/ , $dat[3]);
               SetValue(34713 /*[USV auslesen\lineV]*/ ,$dat[4]);
               SetValue(51290 /*[USV auslesen\outV]*/ , $dat[5]);
               SetValue(31823 /*[USV auslesen\batV]*/ , $dat[6]);
               SetValue(36567 /*[USV auslesen\outFrequ]*/ ,$dat[7]);
               SetValue(42094 /*[USV auslesen\load]*/ ,$dat[8]);
               SetValue(39651 /*[USV auslesen	emp]*/ ,$dat[9]);
               SetValue(38005 /*[USV auslesen	s]*/ , $zTs);
               SetValue(59857 /*[USV auslesen	ime]*/ , date("d.m.Y", $zTs)." ".date("H:i:s", $zTs));
               SetValue(16021 /*[USV auslesen\lastts]*/  , $zTs);
               SetValue(48890 /*[USV auslesen\loadVA]*/  ,($dat[8]*($leistungusv/100)));
               SetValue(26175 /*[USV auslesen\akkustatus]*/  , ROUND($dat[6]/0.27,0));

               
               

            }
         }
      }
   }
}
?>

vieleicht hilft es jemandem
getestet mit einer smart ups 700 und selbst gelötetem kabel.

natürlich basiert das script zu fast 99,9 prozent auf dem originalscript

grüße
danny

also bei mir läuft das auch unter 2.2 und Win7 ohne Probleme…

Ok, die Variablen. Da habe ich mir natürlich eine Function geschrieben, die mit den alten Namen umgehen kann und notfalls Variable eben anlegt…

Was aber anzupasen war bei neuer Installation des Powerchutes: Im Agent (nicht in der Konsole) kann man einstellen, welche Spalten der Output-Datei mit welchen Werten gefüllt werden sollen. Und die Defaulteinstellug war: Alle auf „Disabled“

Da man natürlich erst nur in der Konsole sucht, dort dieser Punkt aber fehlt, kann das ganz schön verwirrend sein!

Aber sonst gab es bisher hier keine Probleme

Doch: APC hat die Lizenzbedingungen vom Powerchute geändert. Unter Win7 läuft nur noch V8.x und besser. Die Konsole gibt es bei V8 aber nur noch gegen Bares! Sprich: Kauflizenz!

Workaround:
Win7-Kiste als Sekundär-PC laufen lassen, also per hellgrauem SIMPLE signaling Kabel an Erweiterungs-Karte in USV (so man hat), und den Primär-Steuereingang (schwarzes SMART signaling Kabel) an eine XP-Machine, auf der auch die Vorversion (7.x) noch läuft, mit Konsole in der freien Basislizenz. Die andere Maschine mit dem V8-Agent wird in der V7-Konsole (bei mir) problemlos erkannt.

Die Konsole brauche ich vor allem, um per dem dort vorhandenen Scheduler die Anlage sauber von der USV aus geplant rebooten zu können, also notfalls auch von der einen Maschine aus, die andere, remote nicht mehr erreichbare, rebooten. Von einem anderen Kontinent aus macht das dann besonders Spaß :slight_smile: