Status von Events abfragen

Zeigt bitte einmal ein var_dump von IPS_GetMedia(24448)
Michael

Hi,
Edit: war blödsinn.

Ralf

Array
(
[MediaID] => 24448
[MediaType] => 1
[MediaFile] => media/24448.jpg
[MediaUpdated] => 1623512741
[MediaIsCached] => 1
[MediaCRC] => 36FFBDA2
[MediaSize] => 1120318
[MediaIsAvailable] => 1
)

Bei 1, also Cache an und keine Datei :wink:
Michael

Hi,
Meldung ausgeben in diesem Fall? Ich dachte so in etwa „noch nicht gespeichert“ hinter Dateinamen?

Ralf

Folgende Datei ist ohne Fehler:

Array
(
    [MediaID] => 18387
    [MediaType] => 1
    [MediaFile] => media/18387.jpg
    [MediaUpdated] => 1622786885
    [MediaIsCached] => 1
    [MediaCRC] => BB3C8CE8
    [MediaSize] => 1093555
    [MediaIsAvailable] => 1
)

Hi,
ist klar. Die ist gecached aber auch schon gespeichert, d.h. die Datei existiert schon auf der Festplatte. die andere Datei existiert bisher nur im RAM, d.h. sie gibt es nicht mehr falls IPS abstürzt. Von was/wem wurde die 1. Datei erzeugt?

Ralf

Beide Dateien sind Teil des BildArchiv Moduls, wobei die erste Datei von Samstagmittag ist und bisher kein Neustart war. Die zweite Datei ist älter.

Der Michael hat natürlich wie immer recht, vom ersten Bild gibt es noch keine Datei, vom Zweiten schon, da hatte ich Symcon schon mal neu gestartet.

Hey… Ich liege auch Mal daneben :laughing:

Wusste das nur, weil ich selber schon häufiger in diese Falle getappt bin. :shushing_face:

Hi,
ich habe nochmal was bei den Medien gemacht. Es wird rot angezeigt wenn was fehlt und gelb wenn was fehlt aber gecached und available ist. Hier nochmal das gesamte Script:

<?php
declare(strict_types=1);
error_reporting(E_ERROR | E_PARSE | E_NOTICE);

$SMTP = 33517;          // SMTP Instanz falls Mail erwünscht
$htmlString = 29692; // ID einer Stringvariablen mit HTML-Box Profil
$checkErrorCount = 11096; // ID einer Integervariablen für Fehleranzahl
$kernelStart = 15191; // ID einer Intergervariablen mit ~UnixTimeStamp als Profil

// Array mit IDs von Instanzen füllen die ignoriert werden sollen, z.B. weil die Batterie entfernt wurde.
//$ignore = array( 0 ) ;

$ignore = array( 48618, 
                 16529,
                 57977
               );

// Variable A: Typ String, Profil ~HTML-Box
// Variable B: Typ  Integer
// Variable C: Typ  Integer, Profil ~UnixTimestamp

$startTime = IPS_GetKernelStartTime();

$errorText = '';
$mailText = '';
$errorTotal = 0;

// Transactions
$now = time();

// Threads
$threadList = IPS_GetScriptThreadList();
$threadCount = 0;
foreach ($threadList as $t => $i) {
    $thread = IPS_GetScriptThread($i);
    $ScriptID = $thread['ScriptID'];
    if ($ScriptID != 0) {
        $threadCount++;
    }
}

// Timer
$timerCount = 0;
$timer1MinCount = 0;
$timer5MinCount = 0;
$timerList = IPS_GetTimerList();
foreach ($timerList as $t) {
    $timer = IPS_GetTimer($t);
    $next_run = $timer['NextRun'];
    if ($next_run == 0) {
        continue;
    }
    $timerCount++;
    $delay = $next_run - $now;
    if ($delay < 60) {
        $timer1MinCount++;
    } elseif ($delay < 300) {
        $timer5MinCount++;
    }
}

$instanceStatusCodes = [
    101 => 'Instanz wird erstellt',
    102 => 'Instanz ist aktiv',
    103 => 'Instanz wird gelöscht',
    104 => 'Instanz ist inaktiv',
    105 => 'Instanz wurde nicht erzeugt',
];

// Instanzen
$instanceList = IPS_GetInstanceList();
$instanceCount = count($instanceList);
$instanceError = 0;
$instanceError = 0;
foreach ($instanceList as $id) {
    $key = array_search($id, $ignore);
    if (is_bool($key)){
        $instance = IPS_GetInstance($id);
        if ($instance['InstanceStatus'] <= 104) {
            continue;
        }
        if ($instanceError == 0) {
            $errorText .= '<b>Defekte Instanzen:</b><br>' . PHP_EOL;
            $mailText .= 'Defekte Instanzen:' . PHP_EOL;
        }
        $instanceError++;
        $instanceStatus = $instance['InstanceStatus'];
        if (isset($instanceStatusCodes[$instanceStatus])) {
            $err = $instanceStatusCodes[$instanceStatus];

        } else {
            $err = 'Status ' . $instanceStatus;
        }
        $col = $instanceStatus >= 200 ? 'red' : 'grey';
        $loc = IPS_GetLocation($id);
        $errorText .= '<span style="color: ' . $col . ';">&nbsp;&nbsp;&nbsp;#' . $id . ': ' . $loc . ': ' . $err . '</span><br>' . PHP_EOL;
        $mailText .= 'ID:' . $id . ': ' . $loc . ': ' . $err . PHP_EOL;
    }
}

if ($instanceError > 0) {
    $errorText .= '<br>' . PHP_EOL;
    $mailText .= PHP_EOL;
    $errorTotal += $instanceError;
}

$pfad = IPS_GetKernelDir()."scripts";
$handle=opendir ($pfad);    
while ($datei = readdir ($handle)) {
    if(strpos($datei,".ips.php")!==false) {
        $datei =explode(".",$datei);
        $files[]=$datei[0];  
    }
}
closedir($handle);

// Scripte
$scriptList = IPS_GetScriptList();
$scriptCount = count($scriptList);
$scriptError = 0;
foreach ($scriptList as $id) {
    $script = IPS_GetScript($id);
    if (!$script['ScriptIsBroken']) {
        continue;
    }
    if ($scriptError == 0) {
        $errorText .= '<b>Defekte Skripte:</b><br>' . PHP_EOL;
        $mailText .= 'Defekte Skripte:' . PHP_EOL;
    }
    $scriptError++;
    $col = 'red';
    $loc = IPS_GetLocation($id);
    $errorText .= '<span style="color: ' . $col . ';">&nbsp;&nbsp;&nbsp;#' . $id . ' : ' . $script["ScriptFile"].'</span><br>' . PHP_EOL;
    $mailText .= 'ID:' . $id . PHP_EOL;
}

if ($scriptError > 0) {
    $errorText .= '<br>' . PHP_EOL;
    $mailText .= PHP_EOL;
    $errorTotal += $scriptError;
}

// überlüssige Scripte
$scriptError = 0;
foreach($files as $file){
    if ( is_numeric($file) ){
        $key = array_search($file, $scriptList);
        if ( $key === false ){
            if ($scriptError == 0) {
                $errorText .= '<b>überflüssige Skripte:</b><br>' . PHP_EOL;
                $mailText .= 'überflüssige Skripte:' . PHP_EOL;
            }
            $scriptError++;
            $col = 'red';
            $errorText .= '<span style="color: ' . $col . ';">&nbsp;&nbsp;&nbsp;#' . $file.'.ips.php wird nicht gebraucht</span><br>' . PHP_EOL;
            $mailText .= 'ID:' . $file.'.ips.php wird nicht gebraucht' . PHP_EOL;
        }
    }
}
if ($scriptError > 0) {
    $errorText .= '<br>' . PHP_EOL;
    $mailText .= PHP_EOL;
    $errorTotal += $scriptError;
}

// fehlende Scripte
$scriptError = 0;
foreach($scriptList as $id){
    $key1 = array_search($id, $files);
    $script = IPS_GetScript($id);
    $datei = $script["ScriptFile"];
    if(strpos($datei,".ips.php")!==false) {
        $datei =explode(".",$datei);
    }
    $key2 = array_search($datei[0], $files);
    if (( $key1 === false ) && ( $key2 === false )){
            if ($scriptError == 0) {
                $errorText .= '<b>fehlende Skripte:</b><br>' . PHP_EOL;
                $mailText .= 'fehlende Skripte:' . PHP_EOL;
            }
            $scriptError++;
            $col = 'red';
            $errorText .= '<span style="color: ' . $col . ';">&nbsp;&nbsp;&nbsp;#' . $id . ' : ' . $script["ScriptFile"].' fehlt</span><br>' . PHP_EOL;
            $mailText .= '#' . $id . ' : ' . $script["ScriptFile"].' fehlt' . PHP_EOL;
    }
}
if ($scriptError > 0) {
    $errorText .= '<br>' . PHP_EOL;
    $mailText .= PHP_EOL;
    $errorTotal += $scriptError;
}

// Links
$linkList = IPS_GetLinkList();
$linkCount = count($linkList);
$linkError = 0;
foreach ($linkList as $id) {
    $link = IPS_GetLink($id);
    if (IPS_ObjectExists($link['TargetID'])) {
        continue;
    }
    if ($linkError == 0) {
        $errorText .= '<b>Defekte Links:</b><br>' . PHP_EOL;
        $mailText .= 'Defekte Links:' . PHP_EOL;
    }
    $linkError++;
    $col = 'red';
    $loc = IPS_GetLocation($id);
    $errorText .= '<span style="color: ' . $col . ';">&nbsp;&nbsp;&nbsp;#' . $id . ': ' . $loc . '</span><br>' . PHP_EOL;
    $mailText .= 'ID:' . $id . ': ' . $loc . PHP_EOL;
}

if ($linkError > 0) {
    $errorText .= '<br>' . PHP_EOL;
    $mailText .= PHP_EOL;
    $errorTotal += $linkError;
}

// Objekte
$objectList = IPS_GetObjectList();
$objectCount = count($objectList);
$objectError = 0;
foreach ($objectList as $id) {
    $obj = IPS_GetObject($id);
    $ok = true;
    $pid = $obj['ParentID'];
    if ($pid != 0 && !IPS_ObjectExists($pid)) {
        $ok = false;
    }
    $cids = $obj['ChildrenIDs'];
    foreach ($cids as $cid) {
        if (!IPS_ObjectExists($cid)) {
            $ok = false;
        }
    }
    if ($ok) {
        continue;
    }
    if ($objectError == 0) {
        $errorText .= '<b>Defekte Objekte:</b><br>' . PHP_EOL;
        $mailText .= 'Defekte Objekte:' . PHP_EOL;
    }
    $objectError++;
    $col = 'red';
    $loc = IPS_GetLocation($id);
    $errorText .= '<span style="color: ' . $col . ';">&nbsp;&nbsp;&nbsp;#' . $id . ': ' . $loc . '</span><br>' . PHP_EOL;
    $mailText .= 'ID:' . $id . ': ' . $loc . PHP_EOL;
}

if ($objectError > 0) {
    $errorText .= '<br>' . PHP_EOL;
    $mailText .= PHP_EOL;
    $errorTotal += $objectError;
}

// Events
$eventList = IPS_GetEventList();
$eventCount = count($eventList);
$eventActive = 0;
$eventError = 0;
foreach ($eventList as $id) {
    $event = IPS_GetEvent($id);
    $active = $event['EventActive'];
    if ($active) {
        $eventActive++;
    }
    $err = 0;
    $varID = $event['TriggerVariableID'];
    if ($varID != 0 && IPS_ObjectExists($varID) == false) {
        $err++;
    }
    $eventConditions = $event['EventConditions'];
    foreach ($eventConditions as $eventCondition) {
        $variableRules = $eventCondition['VariableRules'];
        foreach ($variableRules as $variableRule) {
            $varID = $variableRule['VariableID'];
            if ($varID != 0 && IPS_ObjectExists($varID) == false) {
                $err++;
            }
        }
    }
    if ($err == 0) {
        continue;
    }
    if ($eventError == 0) {
        $errorText .= '<b>Defekte Ereignisse:</b><br>' . PHP_EOL;
        $mailText .= 'Defekte Ereignisse:' . PHP_EOL;
    }
    $eventError++;
    $col = $active ? 'red' : 'grey';
    $loc = IPS_GetLocation($id);
    $errorText .= '<span style="color: ' . $col . ';">&nbsp;&nbsp;&nbsp;#' . $id . ': ' . $loc . '</span><br>' . PHP_EOL;
    $mailText .= 'ID:' . $id . ': ' . $loc .PHP_EOL;
}

if ($eventError > 0) {
    $errorText .= '<br>' . PHP_EOL;
    $mailText .= PHP_EOL;
    $errorTotal += $eventError;
}

// Module
$moduleList = IPS_GetModuleList();
$moduleCount = count($moduleList);

// Variablen
$varList = IPS_GetVariableList();
$varCount = count($varList);
$varError = 0;
foreach ($varList as $id) {
    $err = 0;
    $variable = IPS_GetVariable($id);
    $Varprofile = $variable['VariableProfile'];
    if ($Varprofile != ''){
        $profile = IPS_GetVariableProfile($Varprofile);
        if ($profile == false){
            $err += 1;
        }
    }
    $Varprofile = $variable['VariableCustomProfile'];
    if ($Varprofile != ''){
        $profile = IPS_GetVariableProfile($Varprofile);
        if ($profile == false){
            $err += 2;
        }
    }
    if ($err == 0) {
        continue;
    }
    if ($varError == 0) {
        $errorText .= '<b>Fehlende Profile:</b><br>' . PHP_EOL;
        $mailText .= 'Fehlende Profile:' . PHP_EOL;
    }
    $varError++;
    $col = $active ? 'red' : 'grey';
    $loc = IPS_GetLocation($id);
    if ($err & 1){
        $errorText .= '<span style="color: ' . $col . ';">&nbsp;&nbsp;&nbsp;#' . $id . ': ' . $loc . '"' . $variable['VariableProfile'] .'" fehlt (Standard)' . '</span><br>' . PHP_EOL;
        $mailText .= 'ID:' . $id . ': ' . $loc . '"' . $variable['VariableProfile'] . '" fehlt ' . PHP_EOL;
    }
    if ($err & 2){
        $errorText .= '<span style="color: ' . $col . ';">&nbsp;&nbsp;&nbsp;#' . $id . ': ' . $loc . '"' . $variable['VariableCustomProfile'] .'" fehlt (Custom)' . '</span><br>' . PHP_EOL;
        $mailText .= 'ID:' . $id . ': ' . $loc . '"' . $variable['VariableCustomProfile'] . '" fehlt ' . PHP_EOL;
    }
}

if ($varError > 0) {
    $errorText .= '<br>' . PHP_EOL;
    $mailText .= PHP_EOL;
    $errorTotal += $varError;
}

// VariableAction
$varError = 0;
foreach ($varList as $id) {
    $err = 0;
    $variable = IPS_GetVariable($id);
    $VarAction = $variable['VariableAction'];
    if ($VarAction > 1){
        $script = IPS_GetScript($VarAction);
        $instanz = IPS_GetInstance($VarAction);
        if (($script == false) && ($instanz == false)){
            $err += 1;
        }
    }
    
    $VarAction = $variable['VariableCustomAction'];
    if ($VarAction > 1){
        $script = IPS_GetScript($VarAction);
        $instanz = IPS_GetInstance($VarAction);
        if (($script == false) && ($instanz == false)){
            $err += 2;
        }
    }

    if ($err == 0) {
        continue;
    }
    if ($varError == 0) {
        $errorText .= '<b>Fehlende Aktions-Scripte:</b><br>' . PHP_EOL;
        $mailText .= 'Fehlende Aktions-Scripte:' . PHP_EOL;
    }
    $varError++;
    $col = $active ? 'red' : 'grey';
    $loc = IPS_GetLocation($id);
    if ($err & 1){
        $errorText .= '<span style="color: ' . $col . ';">&nbsp;&nbsp;&nbsp;#' . $id . ': ' . $loc . '"' . $variable['VariableAction'] .'" fehlt (Standard)' . '</span><br>' . PHP_EOL;
        $mailText .= 'ID:' . $id . ': ' . $loc . '"' . $variable['VariableAction'] . '" fehlt ' . PHP_EOL;
    }
    if ($err & 2){
        $errorText .= '<span style="color: ' . $col . ';">&nbsp;&nbsp;&nbsp;#' . $id . ': ' . $loc . '"' . $variable['VariableCustomAction'] .'" fehlt (Custom)' . '</span><br>' . PHP_EOL;
        $mailText .= 'ID:' . $id . ': ' . $loc . '"' . $variable['VariableCustomAction'] . '" fehlt ' . PHP_EOL;
    }
}

if ($varError > 0) {
    $errorText .= '<br>' . PHP_EOL;
    $mailText .= PHP_EOL;
    $errorTotal += $varError;
}

// Medien
$pfad = IPS_GetKernelDir();
$mediaList = IPS_GetMediaList();
$mediaCount = count($mediaList);
$mediaError = 0;
foreach ($mediaList as $id) {
    $Media = IPS_GetMedia($id);
    if ($Media['MediaType'] == 3){
        continue;
    }

    if (file_exists($pfad.$Media['MediaFile'])){
        continue;
    }
    if ($mediaError == 0) {
        $errorText .= '<b>Mediendatei:</b><br>' . PHP_EOL;
        $col = 'red';
        $errorText .= '<span style="color: ' . $col . ';">nicht vorhanden / </span>' . PHP_EOL;
        $col = 'yellow';
        $errorText .= '<span style="color: ' . $col . ';">gecached nicht gespeichert</span><br><br>' . PHP_EOL;
        $mailText .= 'Defekte Mediendatei:' . PHP_EOL;
    }
    $mediaError++;
    if (($Media['MediaIsCached']) && ($Media['MediaIsAvailable'])){
        $col = 'yellow';
        $errorText .= '<span style="color: ' . $col . ';">&nbsp;&nbsp;&nbsp;#' . $id . ': ' . $Media['MediaFile'] . ' noch nicht gespeichert</span><br>' . PHP_EOL;
        $mailText .= 'ID:' . $id . ': ' . $Media['MediaFile'] . PHP_EOL;
    }
    else{
        $col = 'red';
        $errorText .= '<span style="color: ' . $col . ';">&nbsp;&nbsp;&nbsp;#' . $id . ': ' . $Media['MediaFile'] . ' nicht vorhanden</span><br>' . PHP_EOL;
        $mailText .= 'ID:' . $id . ': ' . $Media['MediaFile'] . PHP_EOL;
    }
}

if ($mediaError > 0) {
    $errorText .= '<br>' . PHP_EOL;
    $mailText .= PHP_EOL;
    $errorTotal += $mediaError;
}

$html = '';
$html .= '<head>' . PHP_EOL;
$html .= '<style>' . PHP_EOL;
$html .= 'body { margin: 1; padding: 0; font-family: "Open Sans", sans-serif; font-size: 20px; }' . PHP_EOL;
$html .= 'table { border-collapse: collapse; border: 0px solid; margin: 0.5em;}' . PHP_EOL;
$html .= 'th, td { padding: 1; }' . PHP_EOL;
$html .= 'thead, tdata { text-align: left; }' . PHP_EOL;
$html .= '#spalte_title { width: 160px; }' . PHP_EOL;
$html .= '#spalte_value { }' . PHP_EOL;
$html .= '</style>' . PHP_EOL;
$html .= '</head>' . PHP_EOL;
$html .= '<body>' . PHP_EOL;
$html .= '<table>' . PHP_EOL;
$html .= '<colgroup><col id="spalte_title"></colgroup>' . PHP_EOL;
$html .= '<colgroup><col id="spalte_value"></colgroup>' . PHP_EOL;
$html .= '<tr><td>Instanzen</td><td>' . $instanceCount . '</td></tr>' . PHP_EOL;
$html .= '<tr><td>Scripte</td><td>' . $scriptCount . '</td></tr>' . PHP_EOL;
$html .= '<tr><td>Links</td><td>' . $linkCount . '</td></tr>' . PHP_EOL;
$html .= '<tr><td>Objekte</td><td>' . $objectCount . '</td></tr>' . PHP_EOL;
$html .= '<tr><td>Ereignisse</td><td>' . $eventCount . ' (aktiv=' . $eventActive . ')</td></tr>' . PHP_EOL;
$html .= '<tr><td>Module</td><td>' . $moduleCount . '</td></tr>' . PHP_EOL;
$html .= '<tr><td>Variablen</td><td>' . $varCount . '</td></tr>' . PHP_EOL;
$html .= '<tr><td>Medien</td><td>' . $mediaCount . '</td></tr>' . PHP_EOL;
$html .= '<tr><td>Threads</td><td>' . $threadCount . '</td></tr>' . PHP_EOL;
$html .= '<tr><td>Timer</td><td>' . $timerCount . ' (1m=' . $timer1MinCount . ', 5m=' . $timer5MinCount . ')</td></tr>' . PHP_EOL;
$html .= '</table>' . PHP_EOL;

if ($errorTotal > 0) {
    $html .= $errorText. '</body>' . PHP_EOL;
// vereinfachten Fehlertext als Mail verschiecken
    $mailBetreff =  "IPS Check"; //Betreff der E-Mail
//    SMTP_SendMail($SMTP, $mailBetreff, $mailText);
} else {
    $html .= '<br>keine Fehler<br>' . PHP_EOL . '</body>' . PHP_EOL;
}

$htmlString = 29692; // ID einer Stringvariablen mit HTML-Box Profil
$checkErrorCount = 11096; // ID einer Integervariablen für Fehleranzahl
$kernelStart = 15191; // ID einer Intergervariablen mit ~UnixTimeStamp als Profil

SetValueString($htmlString, $html);
SetValueInteger($checkErrorCount, $errorTotal);
SetValueInteger($kernelStart, $startTime);
?>

Wer bei Fehler eine Mail haben möchte // vor SMTP_SendMail entfernen und die SMTP-Instanz eingeben.

Kann man nochwas checken?

Edit: benutzte Variablen am Anfang als IDs und Unterstützung von „richtigen“ Namen von Scripten. Bei Profilen und Actionen steht dabei ob es Standard oder Custom ist was Probleme machen könnte.

Ralf

getestet und erschrocken, da sind wohl ein paar mehr Änderungen drin, nun habe ich eine Menge „überflüssige Scripte“ und „fehlende Profile“.

Spannend finde ich „entweder oder“ Meldungen :slight_smile:

#34176: Logitech Media Server Splitter\Scanner entweder "LMS.Scanner" oder "Scanner.SqueezeboxServer" fehlen
#50153: Audio\SqueezeBoxMiri\Pitch entweder "LSQ.Pitch" oder "Intensity.Squeezebox" fehlen

Vielleicht könnten die notwendigen Parameter und die Mailinstanz am Anfang des Scripts als Variablen konfiguriert werden, dann kann alles danach einfach überkopiert werden.

Hi,
ich habe alles gesammelt was im Forum schon jemals überprüft wurde und noch einige eigene Sachen hinzugefügt:-)

Überflüssige Scripte sind .ips.php Dateien im Script-Verzeichnis die IPS selbst aber anscheinend nicht mehr benutzt.

Bei den Profilen und Aktionsscripten war ich faul:-) Entweder ist Benutzerprofil und oder ist Standardprofil (oder umgedreht:-)). Werde ich auch noch eindeutiger machen glaube ich.

Ralf

Cooles Skript - auch gleich mal ausprobiert!

Eine Schwieriegkeit ist - wenn man Scripte einen eigenen Namen gegeben hat, dann meint das Skript das es nicht existiert bzw. fehlt :frowning: Könnte man das umbauen?

Top, Gruß Heiko

Moin Heiko,
was heißt eigenen Namen? Eigentlich läuft doch alles über IDs. Sorry für meine Frage aber ich hatte gerade erst meinen 2. IPS-Geburtstag:-)

Ralf

Du kannst im Scripteditor über „Skriptverwaltung“->„Umbennenen“ dem Script ein anderen Filename geben.
Ich tue das z.b. um Scripte zu kategorisiere, z.B „System.HealthCheck.ips.php“ … Kategrorie „System“ …

Gruß Heiko

Hi,
danke. Hat der Schüler in der 3. Klasse wieder was gelernt:-) Ich schaue es mir an.

Edit: Kannte ich nicht weil ich die Pro Console selten benutze.

Ralf

Hat nix mit Pro Console zu tun, ganz normal im Scripteditor der Managementconsole.

Gruß Heiko

Des weitern kann es auch ips.php Dateien geben welche nur per include / require eingebunden werden und gar nicht als Objekt in IPS angelegt sind.
Ich glaube da einen Abgleich in beide Richtungen zu machen hat noch einige Herausforderungen.
Michael

Hi Heiko,
stimmt. Bisher nie gesehen/angeschaut.

@Michael,
oder IPS_RunScript(12345) in einem Script wobei 12345 fehlt. Das passiert mir öfter und weil es keinen Fehler bzw. defekt im Script hervorruft merke ich es nicht immer.

PS: Script in #31 aktualisiert.

Ralf