Anzeige nicht benutzter Variablen in den Scripten (Cross Referenz)

Moin,

aufgrund der zahlreichen Scripte und Funktionen kommt es bei Änderungen immer wieder vor, dass Variablen nun nicht mehr benutzt werden.

Gibt es Möglichkeiten diese festzustellen? Analog würde das auch für unbenutzte Funktionen gelten. Bei uns lief so etwas früher unter dem Begriff Cross Referenz. Außerdem konnte man den Compilern Optionen mitgeben, die entsprechende Daten lieferten.

Gruß
Hans

Moin Hans!

Woher soll IPS wissen, ob eine Variable bei dir noch für was gebraucht wird oder nicht.

Auch mit einem Skript stelle ich mir das eher umständlich und vlt. auch ungenau vor. Auf jeden Fall müssten die Instanz-Variablen von Aktoren ausgenommen werden. Dann müsste man in einem Skript erstmal alle Variablen auslesen und in ein Array schreiben, dann alle PHP-Skripte in IPS durchsuchen, ob die ID da irgendwo vor kommt, wenn nicht, dann ausgeben.
…ist spontan die einzige Möglichkeit die mir einfällt…

Grüße,
Chris

Moin Chris,

schnell wie immer :slight_smile: Bin mal gespannt wann du das erste Mal antwortest bevor man überhaupt die Frage gestellt hat :smiley:

Woher soll IPS wissen, ob eine Variable bei dir noch für was gebraucht wird oder nicht.

Einfache Frage, einfache Antwort: indem es nachschaut :rolleyes: Scripte hier mit 1.000 Zeilen sind ja schon selten. Was aber machst du, wenn du hunderttausende Codezeilen verwalten musst? :rolleyes: Von daher gab und gibt es solche Cross Referenzen, die ganze Bibliotheken bzw. Verzeichnisse durchsuchen und dir entsprechende Aufstellungen liefern.

Bei Variablen innerhalb eines Programms genügte ein Schalter in den Compiler Optionen und schon warf er dir die nicht benutzten Variablen raus :wink: Das wären hier die nicht benutzen Variablen innerhalb eines Scriptes. Schwieriger wäre es bei den IPS Variablen, da diese ja von allen Scripten benutzt werden können.

Dann müsste man in einem Skript erstmal alle Variablen auslesen und in ein Array schreiben, dann alle PHP-Skripte in IPS durchsuchen, ob die ID da irgendwo vor kommt, wenn nicht, dann ausgeben.
…ist spontan die einzige Möglichkeit die mir einfällt…

Das sehe ich dann genauso wie du. Bevor ich mir das allerdings antue bleiben die „Leichen“ eben erhalten und die Zeit wird in die Weiterentwicklung gesteckt :loveips:

Gruß
Hans

Das angesprochene „Problem“ ist ja kein IPS-Problem !! IPS benutzt zwar PHP, aber der Restmüll von nicht (mehr) benutzten Variablen, Konstanten und Funktionen tritt überall dort auf, wo PHP (oder eine andere Programmiersprache) verwendet wird.

Seht bzw. fragt doch mal in den diveren PHP-Foren nach, ob es nicht schon längst ein Tool für sowas gibt!

Viele Grüsse
Harald

Moin Harald,

du hast natürlich Recht damit, dass das kein grundsätzliches IPS/PHP Problem ist :slight_smile:

Dass es für die Suche innerhalb der Scripte eine Möglichkeit gibt kann ich mir gut vorstellen, nur dort habe ich das Problem eigentlich nicht.

Mittlerweile glaube ich, dass das Problem auch innerhalb von IPS auf massive Probleme stößt, da ja auch die HM Geräte über Variablen verfügen die man letztendlich nicht benutzt. Hinzu kommt, dass man ja auch fremde Scripte bzw. Module im Einsatz hat, was die Komplexität nochmals erhöhen würde. Dies gilt dann auch noch für Variable die per Script angelegt und später wieder automatisch gelöscht werden. Von daher dürfte eine sinnvolle Lösung nur schwer realisierbar sein und ich werde mich von dem Gedanken verabschieden :slight_smile:

Gruß
Hans

Du könntest dir zu den IPS Variablen zumindest auswerten, wann sie zuletzt geschrieben wurden, damit würdest du „alte“ Variablen sehen. Aber ob die benutzt werden oder nicht, kannst du dann nur selber bewerten ;).

Hi,

hatte nicht Raketenschnecke so etwas entwickelt?

Ich habe mir für Dokumentationszwecke mal was zusammen geschrieben, da kann man vielleicht drauf aufbauen.
Übersichtshalber öffne ich das dann in Excel.

<?
//******************************************************************************
// 	Information über alle Variablen:
//    	ID
//			Name
// 	   in welcher Kategorie
//    	benutzt in welchen Skripten
//    	in welchen Ereignis benutzt
//******************************************************************************

$dir = IPS_GetKernelDir();

$datei = fopen($dir."My Logs/Variablen.txt","wb");
if ($datei === false) return;

fwrite($datei, "VarID	VarName	Kategorie	Pfad	Ereignis
\r");
$objects=IPS_GetObjectList();  //alle Objekte
foreach ($objects as $object)
{
	$o=IPS_GetObject($object);
	if ($o["ObjectType"]==2)  //Objekt-Typ (0: Kategorie, 1: Instanz, 2: Variable, 3: Skript, 4: Ereignis, 5: Media, 6: Link)
	{
		//print_r(IPS_GetObject($object));
		$output = $o["ObjectID"]."	".$o["ObjectName"]."	";
		$pfad = IPS_GetLocation($o["ObjectID"]);
		$c = strrpos($pfad, "\\"); //am Ende den Variablennamen entfernen
		$pfad = substr($pfad, 0, $c);
		$output = $output.$pfad."	";

//jetzt noch zu jeder Variable die Scripts suchen, in denen sie benutzt wird
      $dir = IPS_GetKernelDir();
		$dir = $dir."scripts";

		$files = scandir($dir); //alle Dateien im Verzeichnis

		foreach ($files as $file)
		{
			if (is_file($file) == true) //nur Dateien auswerten (keine Dirs und . / ..)
			{
			   $text = file_get_contents($file, "", NULL, 1); //nur so gehts ab erster Zeile (erstes Zeichen fehlt)
				$search = (string)$o["ObjectID"];
				if (strpos($text, $search) !== false)
			   {
				   //echo $file;
				   $file = explode(".", $file); //Dateierweiteung abschneiden
				   if (is_numeric($file[0]))
					{
				   $n = IPS_GetObject((integer)$file[0]);
				   $name = $n["ObjectName"];
				   $output = $output." >>".$name."(".$file[0].")";
				   }
				   else
				   {
				   $output = $output." >>".$file[0];
				   }
			   }
			}
		}
		$output = $output."	";
//jetzt noch alle Ereignisse die mit der Variablen verknüpft sind
		$events = IPS_GetVariableEventList($o["ObjectID"]); //Array mit allen Events
		$eventsout = "";
		if ($events != false)   //nur ausführen wenn Event vorhanden
		{
		   $count = count($events);
		   $i = 0;
			while ($i != $count) //alle Events nacheinander ausgeben
			{
				$o=IPS_GetObject($events[$i]);
				$parent=$o["ParentID"];    //ParentID und dadurch den Namen abfragen
				$p=IPS_GetObject($parent);
				$pname = $p["ObjectName"]; //Name des Scripts das durch Event getriggert wird
				$event = $events[$i];
				$eventsout = $eventsout.$event.": ".$pname.", ";   //ID und Name ausgeben
				//echo $eventsout."
";
				$i = $i + 1;
			}
			$eventsout = rtrim($eventsout, ", ");	//Schönheitskorrektur -> letztes Komma u. Leerz. entfernen
		}
		$output = $output.$eventsout."
\r";
		fwrite($datei, $output);
	}
}
fclose($datei);
?>

Hallo Michael,

vielen Dank für das super Skript :slight_smile: Es bildet die perfekte Basis für solche Cross Referenzen zumal die Idee der Weiterverarbeitung in Excel umfangreiche Sortiermöglichkeiten bietet, so dass man schnell findet wonach man sucht.

Auch das Rausfiltern von HM Geräten und das Ignorieren von Skripten lässt sich so recht einfach realisieren.

Dann bin ich ja doch nicht der Einzige der so etwas haben wollte :smiley: Nochmals vielen Dank.

Gruß
Hans

Hallo ransi,

danke für das Script. Funktioniert super.

Habe nur die Zeile 13

$datei = fopen($dir.„logs_own\variablen.txt“,„wb“);

für Windows angepasst.

Wo hast Du denn den 2. (cr) Zeilenumbruch eingebaut?

Den würd ich gern entfernen. Oder besser noch das ganze gleich in eine .csv schreiben.

Hallo Wolfgang,

ich weis nicht was du meinst. Bei mir steht im Textfile jede Variable in einer Zeile.
Der Return wird in Zeile 80 geschrieben, vielleicht ist das Linefeed zuviel.

$output = $output.$eventsout."
\r";

Habe mir das auch noch für Scripte geschrieben.


<?
//******************************************************************************
// 	Information über alle Skripte:
//    	ID
//			Name
// 	   in welcher Kategorie
//    	benutzt in welchen Skripten
//******************************************************************************
$dir = IPS_GetKernelDir();
$path = $dir."\\scripts";
$datei = fopen($dir."My Logs/Skriptinfo.txt","wb");
if ($datei === false) return;

fwrite($datei, "SkriptID	SkriptName	Kategorie	aufgerufen in:
\r");

$objects=IPS_GetObjectList();
foreach ($objects as $object)
{
	$o=IPS_GetObject($object);
	if ($o["ObjectType"]==3)   // alle Skripte
	{
//		print_r(IPS_GetObject($object));
		$o=IPS_GetObject($object);
		$out = $o["ObjectID"]."	".$o["ObjectName"]."	";
		$pfad = IPS_GetLocation($o["ObjectID"]);
		$c = strrpos($pfad, "\\"); //am Ende den Variablennamen entfernen
		$pfad = substr($pfad, 0, $c);
		$out = $out.$pfad."	";
		$out = $out.search_all_files ($path, $o["ObjectID"])."
\r";
		fwrite($datei, $out);
		//echo $out;
	}
}
fclose($datei);

//******************************************************************************
// Durchsucht in einem Verzeichnis alle Dateien nach einem Text
//******************************************************************************
function search_all_files ($path, $string)
{
	$output = "";
	$files = scandir($path); //alle Dateien im Verzeichnis

	foreach ($files as $file)
	{
		if (is_file($file) == true) //nur Dateien auswerten (keine Dirs und . / ..)
		{
		   $text = file_get_contents($file, "", NULL, 1); //nur so gehts ab erster Zeile (erstes Zeichen fehlt)
//			$search = (string)$ID;
			if (strpos($text, (string)$string) !== false)
		   {
			   //echo $file;
			   $file = explode(".", $file); //Dateierweiteung abschneiden
			   if (is_numeric($file[0]))     //Dateiname ist ID
				{
			   $n = IPS_GetObject((integer)$file[0]); //aus ID klartext Name rausfinden
			   $name = $n["ObjectName"];
			   $output = $output." >>".$name."(".$file[0].")";
			   }
			   else
			   {
			   $output = $output." >>".$file[0];
			   }
		   }
		}
	}
	return $output;
}
//******************************************************************************
?>

Hallo ransi,

danke für die Info.

Nach dem ich „\r“ in Zeile 18 und 80 glöscht hab sind keine Leerzeilen mehr drin wenn ich mit Notepad++ oder Excel2013 öffne.

Ebenso in Deinem Script für die Scripte in Zeile 14 und 29.

Danke dafür.

Beide wirklich sehr hilfreich.

Einen hab ich noch:)


<?
//******************************************************************************
// 	Information über Dateien im Scriptordner ohne Script:
//    Anzahl Scripte
//		Anzahl Dateien im Scriptordner
// 	Files ohne zugehöriges Script
//******************************************************************************

$dir = IPS_GetKernelDir();

$datei = fopen($dir."My Logs/BadFiles.txt","wb");
if ($datei === false) return;

$dir = IPS_GetKernelDir();
$dir = $dir."scripts";

$scripts = array();

$objects=IPS_GetObjectList();  //alle Objekte
foreach ($objects as $object)
{
	$o=IPS_GetObject($object);
	if ($o["ObjectType"]==3)  //Objekt-Typ (0: Kategorie, 1: Instanz, 2: Variable, 3: Skript, 4: Ereignis, 5: Media, 6: Link)
	{
      $scriptfile = IPS_GetScriptFile($o["ObjectID"]);
		$scripts[] = $scriptfile;
	}
}
$scriptcnt = count($scripts);
fwrite($datei, $scriptcnt." Scripts
\r");
//print_r($scripts);
$files = scandir($dir); //alle Dateien im Verzeichnis
//print_r($files);
$filecnt = count($files);
fwrite($datei, $filecnt." Files

\r");
$badfiles = array_diff ($files, $scripts);
//print_r($badfiles);
fwrite($datei, "Files ohne Script:
\r");
$output = implode("
\r", $badfiles);
fwrite($datei, $output);
//echo $output."
";
//echo $matchcnt." Übereinstimmungen gefunden
\r";
fclose($datei);
?>

Hallo ransi,

und das macht was?

Ohne das jetzt getestet und zu verstehen versucht zu haben …

oh, steht ja im Intro … hatte runtergescrollt.

Hallo Michael,

da kann ich mich ja nur nochmals bedanken für diese nützlichen Hilfsmittel :slight_smile:

Bei deinem 1. Skript von den Dreien ist mir aufgefallen, dass in seltenen Fällen auf die Benutzung einer ID hingewiesen wird, bei der der String der ID im Text des Skriptes vorkommt. Darauf gekommen bin ich, als die Verwendung eines Heizkörperthermostates auf ein Harmony Skript für die PS3 verwies. Grund ist, dass der String in der Geräte ID von Harmony enthalten ist. Also technisch gesehen ist die Referenzierung korrekt :rolleyes: Mich stört das allerdings in keiner Weise und ich bin froh über die Tools :wink:

Gruß
Hans