Spät-Frühlings-Putz IPS bevor die Version 4 kommt

Ich räume gerade mein IPS etwas auf… man kennt das ja mit shit in - shit out und ich möchte für die neue Version alten Ballast abwerfen etc.

Was ich über die Suche und in den bestehenden Scriptsammlungen nicht fand und hierbei helfen würde…

  • Weiss jemand wie man alle Script nach dem „Variable existiert nicht“ Tag durchsuchen kann? (Ist ja nur ein Kommentar und mit Suchen in allen Dateien wird es nicht gefunden. Entsprechende Scripte werfen bei der Ausführung einen Fehler aber das wäre hier nicht die Frage)?
  • Weiss jemand, wie ich Code der bei Events hinterlegt ist durchsuchen kann? Zum einen nach der selben Sache wie im vorhergehenden Punkt und zum anderen um festzustellen ob nbsp nicht mehr existierende Scripte aufgerufen werden etc. also eine Art Fehlerauswertung?

Hi!

Ich verwende zur Fehler-Auswertung/Erkennung und zum Aufräumen im IPS dieses Skript von Horst:
Fehlerhafte Objekte / Skripte auflisten

Falls ich etwas dran geändert habe, hier die aktuelle Version, welche ich im Einsatz habe:

<?php
// --------------------------------------------------------------------------------------------------
// WebFront-freundliche HTML-Ausgabe aller defekten Instanzen, Skripte und Links
// --------------------------------------------------------------------------------------------------

// Variablen-ID zur Speicherung der Meldung.
$ContentVariableID = 12345;  // Hier die ID einer String Variable mit Variablenprofil "~HTMLBox" eintragen
// --------------------------------------------------------------------------------------------------

$content = '';

$instanceStatusCodes = array(
    100 => 'module base status',
    101 => 'module is being created',
    102 => 'module created and running',
    103 => 'module is being deleted',
    104 => 'module is not beeing used',
    200 => 'instance error',
    201 => 'instance could not be created'
);

$errorCount = 0;

$ids = IPS_GetInstanceList();
foreach ($ids as $id) {
  if ($id != "40588") {
    $instance = IPS_GetInstance($id);
    if ($instance['InstanceStatus'] > 103) {
        if ($errorCount == 0) {
            $content .= '<b>Defekte Instanzen:</b><br />'."
";
        }
        $errorCount++;
        $content .= '<span style="color: '.($instance['InstanceStatus'] >= 200 ? 'red' : 'grey').';">#'.$id.': '.IPS_GetLocation($id).': '.$instanceStatusCodes[$instance['InstanceStatus']].'</span><br />'."
";
    }
  }
}

if ($errorCount > 0) {
    $content .= '<br />'."
";
    $errorCount = 0;
}
$ids = IPS_GetScriptList();
foreach ($ids as $id) {
    $script = IPS_GetScript($id);
    if ($script['IsBroken']) {
        if ($errorCount == 0) {
            $content .= '<b>Defekte Skripte:</b><br />'."
";
        }
        $errorCount++;
        $content .= '<span style="color: red;">#'.$id.': '.IPS_GetLocation($id).'</span><br />'."
";
    }
}

if ($errorCount > 0) {
    $content .= '<br />'."
";
    $errorCount = 0;
}
$ids = IPS_GetLinkList();
foreach ($ids as $id) {
    $link = IPS_GetLink($id);
    if (!IPS_ObjectExists($link['LinkChildID'])) {
        if ($errorCount == 0) {
            $content .= '<b>Defekte Links:</b><br />'."
";
        }
        $errorCount++;
        $content .= '<span style="color: red;">#'.$id.': '.IPS_GetLocation($id).'</span><br />'."
";
    }
}

$printContent = true;

if (IPS_VariableExists((int)$ContentVariableID)) {
    $variable = IPS_GetVariable($ContentVariableID);
    if ($variable['VariableValue']['ValueType'] === 3) {
        $printContent = false;
        SetValueString($ContentVariableID, $content);
    }
}

if ($printContent) {
    echo $content;
}
?>

Damit kann man sehr gut erkennen, ob Skripte nicht funktionieren oder Instanzen Fehler haben usw…

Grüße,
Chris

Ist auch richtig; da erst wenn du den Code in der Konsole öffnest, Diese nach den IDs und dem dazugehörigen Objekt im Baum sucht.
Hast du das Script also nicht im Editor geöffnet, nachdem es das Objekt nicht mehr gab, steht noch immer der ‚alte‘ falsche Kommentar dahinter.

Das, bzw. so ähnlich, hattest du doch schon mal gefragt :confused:
Zbsp $IPS_TARGET -> $_IPS[‚TARGET‘] in Ereigniscode ändern

Hier war das Hilfsscript:
IP-Symcon 2.5/2.6 - Hilfsskripte - Seite 3

Wobei du dann in $search dann einfach das reinscheibst, wonach er suchen soll.
Ob es dort eine Zahl gibt welche eine InstanzID sein könnte, und ob es die überhaupt gibt… ist schon aufwändiger.


$search = Array('$IPS_SENDER', '$IPS_SELF', '$IPS_VALUE', '$IPS_VARIABLE', '$IPS_INSTANCE',
                      '$IPS_EVENT', '$IPS_TRIGGER', '$IPS_OLDVALUE', '$IPS_TARGET', '$IPS_LINK',
                     '$IPS_REMOTE_ADDR', '$IPS_DIRECTION', '$IPS_DURATION', '$IPS_COMPONENT',
                     '$IPS_REMOTE_HOST', '$IPS_STATUS', '$IPS_STATUSTEXT' );

$eventIDs = IPS_GetEventList();
$found = false;
$anzahl = 0;

foreach($eventIDs as $id)
{
    if($id != $_IPS['SELF'])
   {
      $event = IPS_GetEvent($id);
      $data = $event['EventScript'];
      foreach($search as $befehl)
      {
         if(!(strpos($data, $befehl) === false))
            {
            $found = true;
            $anzahl++;
            echo "Event: ".IPS_GetName($id)." #".$id.", Systemvariable: ".$befehl.", gefunden.
";
         }
      }
    }
} 

Michael

@Bayaro
Super Script, vielen Dank! Die entsprechenden Schritte laufen aber schon routinemässig fast täglich bei mir und sind halt keine Lösung für die beiden Punkte.

@Michael
Hast Recht, anderer Anwendungsfall und deshalb über die Suche nicht gefunden aber die Lösung passt zu meinem Punkt Nr.2 natürlich auch und ist eine Lösung, Merci beaucoup!

Fall Nr.1 und eigentlich auch der wirkliche Knackpunkt für Fall Nr. 2 nämlich feststellen, ob eine ID (Script, Variable etc.) effektiv noch existiert hab ich mal etwas gesehen, da muss ich vielleicht nochmals suchen im Forum. Das Vorgehen der Konsole mit dem Kommentar ist mir klar und dementsprechend muss es ja eine Routine geben, die die Existenz prüft und das geht vermutlich sehr einfach. Schwieriger ist es wohl nbsp die Events nach ID’s zu parsen und an dieses existenzprüfteil zu übergeben und die Faulen Eier anzuzeigen… das wäre aber cool und ein Tipp für ein Script das man nbsp täglich laufen lassen kann (wie Threadprüfung) und Altlasten meldet. Ich denke so was lässt sich mit mittlerem Aufwand machen, wenn aber einer so was schon in der Schatzkiste hätte… :-)))))

So ein Skript wäre gar nicht so wild, aber da würden alle 5stelligen Zahlen als Fehler ausgespuckt werden, weil alle Fälle kann man wohl schlecht beachten. Davor oder danach ein + oder - wäre ja noch einfach. Aber da gibt es sicher viiiiiele Fälle, wo eine 5stellige Zahl keine ObjektID ist.

Von daher, meiner Meinung nach, eher ein schlechter Weg…

Grüße,
Chris

ok… vielleicht eine subjektive Geschichte und je nach Installation anders… aber in meinem Scripten setze ich glaube ich nirgends oder vielleicht ganz selten einmal etwas auf einen 5 stelligen Wert, fix über ein Script.

Dann will ich das mal nicht vorenthalten. Ein Script, dass jeglichen Event-Code ausliest der in IPS vorhanden ist und nach ID’s durchsucht, die es in IPS nicht mehr gibt. Der zweite Schritt, ein Script das sämtliche IPS-Scripts durchsucht und nach dem ähnlichen Muster nach nicht existierenden ID’s durchsucht dürfte damit noch ein Kinderspiel sein. Das einzige was man da für das Pattern sicher noch ergänzen sollte ist IPS_Sleep ausfiltern, das ist realistisch das einige hier eine 5 stellige Zahl dahinter setzen. Publizier ich dann sonst in ein paar Stunden auch noch. Bei mir waren alle gemeldeten Einträge (leider doch fast 25:-)pfui pfui) tatsächliche Fehler und keine fixen Werte. Wer aber viele fixe Werte setzt, der wird halt ein paar Fehlerwarnung erhalten die halt keine Fehler sind. Bei den Events hat das wohl kaum einer, bei der Durchsuchung aller Scripts könnte das dann eher passieren.(Anzeichen dafür wenn einer im Scripteditor öfters den grünen Kommentar anstatt bei richtigen Objekt-Ids bei fixen werten sieht)


$eventIDs = IPS_GetEventList();

foreach($eventIDs as $id)
{
	if($id != $_IPS['SELF'])
	{
	   $event = IPS_GetEvent($id);
	   $data = $event['EventScript'];

		if ( preg_match( '/(?<![0-9])[0-9]{5}(?![0-9])/', $data, $matches ) )
		{
			foreach($matches as $key => $val) {
	         if($val != "")
	         {
	         //	print_r( $val."
");
		         if(@IPS_GetObject((int)$val) == false)
		         {
		         	echo "Event: ".IPS_GetName($id)." #".$id.", Variable: ".$val.", gefunden.
";
		         }
	         }
	      }
		}
	 }
}

Danke für dein Skript :slight_smile:

Hier noch eine kleine Ergänzung, damit man auch eine Ausgabe bekommt (wie bei mir :D), wenn alles ok ist :slight_smile:

<?
$eventIDs = IPS_GetEventList();
$eventCheck = 0;  // Temp-Zähler-Variable > nicht verändern!

foreach($eventIDs as $id)
{
	if($id != $_IPS['SELF'])
	{
	   $event = IPS_GetEvent($id);
	   $data = $event['EventScript'];
		$location = IPS_GetLocation($id);

		if ( preg_match_all( '/(?<![0-9])[0-9]{5}(?![0-9])/', $data, $matches ) )
		{
			foreach($matches as $key => $val) {
	         if($val)
	         {
					foreach($val as $key => $val2) {
						if($val2!="")
	         		{
				         if(@IPS_GetObject((int)$val2) == false)
				         {
echo "Event: ".IPS_GetName($id)." #".$id.", Variable: ".$val2.", gefunden unter ".$location." .
";
$eventCheck++;
				         }
							//echo $val2."
";
	         		}
	         	}
	         }
	      }
		}
	}
}

if ($eventCheck == 0) {
	echo "Es wurden KEINE fehlerhaften Events gefunden!";
}
else {
	echo "Es wurden $eventCheck fehlerhafte Events gefunden!";
}
?>

Grüße,
Chris

Das du keinen Fehler erhalten hast… könnte daran liegen, dass es noch einen Fehler im Script gab. Es wurde von jedem Script immer nur die erste vorhandene Variable ausgewertet und nicht alle in dem Script vorhandenen. Hier folgt nun das richtige Script, dachte bei mir irgendwie läuft das Teil schon mega schnell für so viele Einträge… mit ein paar Querchecks wars dann klar. Zudem ist die Version noch erweitert um die Location, sprich es wird angezeigt wo sich das Objekt befindet wo eine fehlende/falsche ID vermutet wird. Einfach ausführen. Falls jemand doch falsch identifizierte Variablen hat oder solche die sehr viel vorkommen, kann er diese unter if($val2!="") einfach mit ausschliessen also zbp if($val2!=""&&$val2!=„12231“)


$eventIDs = IPS_GetEventList();

foreach($eventIDs as $id)
{
	if($id != $_IPS['SELF'])
	{
	   $event = IPS_GetEvent($id);
	   $data = $event['EventScript'];
		$location = IPS_GetLocation($id);

		if ( preg_match_all( '/(?<![0-9])[0-9]{5}(?![0-9])/', $data, $matches ) )
		{
			foreach($matches as $key => $val) {
	         if($val)
	         {
					foreach($val as $key => $val2) {
						if($val2!="")
	         		{
				         if(@IPS_GetObject((int)$val2) == false)
				         {
echo "Event: ".IPS_GetName($id)." #".$id.", Variable: ".$val2.", gefunden unter ".$location." .
";
				         }
							//echo $val2."
";
	         		}
	         	}
	         }
	      }
		}
	}
}

Nö, trotzdem keine fehlerhaften Events :smiley: :stuck_out_tongue:

Habe mein Skript im Post davor mal ausgetauscht gegen dein aktuelles + Ergänzung.

Danke und Grüße,
Chris

Ok… nun kriegst aber sicher auch die ein paar Ergebnisse Chris… Das wäre fast unmöglich, dass wenn alle Scripts durchsucht werden du gaaar keine Fehleinträge hast. Bei mir hat der erste Teil bereits mit dem durchsuchen der Eventscript sehr geholfen, teils waren es Tippfehler bei der Variablen ID, teils Leichen die noch weg müssen.

Noch kurz zu dem zweiten Teil wo alle Scripts durchsucht werden. Bei mir kamen am Anfang einige Ergebnisse, das ist richtig. Ich habe deswegen einige Verzeichnisse ausgeschlossen bei der Suche, dass kann man über die Location die ich mitgebe gut machen. Als Beispiel habe ich eine Art Papierkorb… das ist der Ordner XXRECYCLED und da hat es natürlich Variablen/IDs drin, die gelöscht sind und er mir nicht anzeigen muss, oder dann gibt es den Ordner Program wo die eigentlichen Scripts von den grossen Meistern drin sind… die schliess ich auch mal aus. Kann man aber immer noch später prüfen. Hab damit auch schon einige Fehler aussortiert.


$ids = IPS_GetScriptList();
$eventCheck = 0;

foreach ($ids as $id)
{
 	$script = IPS_GetScript($id);
   $data = IPS_GetScriptContent ($id);
	$location = IPS_GetLocation($id);

	if ( preg_match_all( '/(?<![0-9])[0-9]{5}(?![0-9])/', $data, $matches ) )
	{
		foreach($matches as $key => $val) {
         if($val)
         {
				foreach($val as $key => $val2) {
					if($val2!="" && $val2!="13204"&& substr($location, 0, 10)!="XXRECYCLED" && substr($location, 0, 11)!="SCRIPT\TEST"&& substr($location, 0, 7)!="Program"&& substr($location, 0, 5)!="SONOS"&& substr($location, 0, 24)!="SCRIPT\GRAPH GOOGLECHART")
         		{
			         if(@IPS_GetObject((int)$val2) == false)
			         {
			         	echo "Event: ".IPS_GetName($id)." #".$id.", Variable: ".$val2.", gefunden unter ".$location." .
";
			         	$eventCheck++;
			         }
						//echo $val2."
";
         		}
         	}
         }
      }
	}
}


if ($eventCheck == 0) {
    echo "Es wurden KEINE fehlerhaften Events gefunden!";
}
else {
    echo "Es wurden $eventCheck fehlerhafte Events gefunden!";
}

Ja, das Skript wirft mir leider Seitenweise Müll raus :frowning: Alles entweder 5stellige Zahlen in URLs, Port-Nummern, Teile einer Instanzid (diese langen in geschweiften Klammern), Postleitzahlen, Beispiel-IDs in Install-Skripten, Beispiel-IDs in Beispiel-Skripten, …

Aber nicht ein echter Fehler :cool:

Sehr aufwendig in meinem Fall, weil eben hunderte „Falschmeldungen“ kommen, aber immerhin weiß ich jetzt, dass alle meine Sachen OK sind :slight_smile: Aber für öfter ist das nichts g Da müsste doch noch einiges ausgeschlossen werden, um die Falschmeldungen wenigstens deutlich zu reduzieren :slight_smile: Entweder durch Angabe der Parent-IDs die ausgelassen werden sollen, oder irgendwie so die Richtung.

Trotzdem Danke! :slight_smile:

Grüße,
Chris

Muß man nicht so Ernst nehmen, kreidet Einem auch geremte Zahlen als fehlende Variable an…

//Meldet sich mit diesem String: 29321,1,192.168.0.19,3,1

Event: Auslesen des WiFi uP Modul #42022, Variable: 29321, gefunden unter uP_WiFi_relais\Auslesen des WiFi uP Modul .

Zu dem WiFi uP-Modul erzähle ich demnächst was, ein HiLight :wink:

Gruß Helmut

Edit: Chris hat es schon erwähnt

:slight_smile: Lustig Chris bei mir genau umgekehrt,wenn ich die Verzeichnisse wie meinen Papierkorb und Program sowie Google Charts auslasse kommen etwa 30 Meldungen. Die putz ich grad durch. Wenn du zbsp die ganzen Webscripts in nem Ordner sortiert hast kannst du den auslassen. Sonst gibt’s nur eins, das Pattern erweitern oder das ganze Ignorieren.:slight_smile: die große Aktion mach ich auch nur einmalig, die Eventpruefung lass ich mal wöchentlich drin.

Da hat jeder einfach viel zu viel verschiedene Sachen. Sowas für die Allgemeinheit skripten dürfte eher schwer werden.

Aber so passt das schon ganz gut, einmal durchschauen im Jahr, paar Sachen ausnehmen und fertig :slight_smile:

Grüße,
Chris

Finde ich für eine manuelle Kontrolle sehr praktisch, trotz den unvermeidlichen Fehlern.
Mal ganz faul: Eine Funktion um eben z.B. IPS_Sleep(XXXXX) auszufiltern wäre cool.

Danke für das Script, kjb

So Sachen müsste man dann wohl mit preg_match (RegEx) rausfiltern. Auch so „Einschränkungen“, ob davor oder danach ein + oder - ist, oder davor oder danach allgemein noch direkt was steht, weil das ist dann meist eine URL oder sonstwas.

Aber das ist mir zuviel Aufwand für quasi nichts. Also überlasse ich das euch :smiley:

Grüße,
Chris

Geht mir auch so. Für einmal pro Jahr lohnt sich das für mich nicht.
Bei mir ist es recht offensichtlich, welches Falschmeldungen sind.

Hab aber immerhin einen echten Fehler gefunden, der hätte mich mal überraschen können, weil er eine Fehlfunktion hätte melden sollen im Ernstfall. Hat sich insofern schon gelohnt.

Gruss, kjb