Registervariable...Erklärung?

Genau das mit Set- u. GetBuffer hätte ich gerne nochmal am Beispiel erklärt.
Da „hakts“ gerade, sry :o

Abgewandeltes Beispiel der vorigen Seite von mir:

<?php
if ($IPS_SENDER == "RegisterVariable") // wenn das Skript von einer RegisterVariable-Instanz aus aufgerufen worden ist
{
    $data  = RegVar_GetBuffer($IPS_INSTANCE); // bereits im Puffer der RegisterVariable-Instanz vorhandene Daten in $data kopieren
    $data .= $IPS_VALUE; // neu empfangene Daten an $data anhängen

    if (strlen($data) >= 11) // wenn $data mindestens 11 Zeichen lang ist
    {
        $datasets = str_split($data, 11)); // $data in Blöcke von bis zu 11 Zeichen zerlegen
        $data = ""; // $data leeren
        for ($i = 0; $i < count($datasets); $i++) // alle Datensätze durchgehen
        {
            if (strlen($datasets[$i]) == 11)
            {
                echo "empfangener Datensatz: ".$datasets[$i]."
";
            }
            else
            {
                $data = $datasets[$i]; // Unvollständige Daten in $data schreiben, falls der letzte Datensatz nicht genau 11 Zeichen hat
            }
        }
    }

    RegVar_SetBuffer($IPS_INSTANCE, $data); // Inhalt von $data im Puffer der RegisterVariable-Instanz speichern
}
?>

Den Teil mit dem echo darfst Du anpassen ;).

Hallo Horst,

ich habe das jetzt anhand deinem Beispiels gelöst und funktioniert auch:

<?
if ($IPS_SENDER == "RegisterVariable") // wenn das Skript von einer RegisterVariable-Instanz aus aufgerufen worden ist
{
    $data  = RegVar_GetBuffer($IPS_INSTANCE); // bereits im Puffer der RegisterVariable-Instanz vorhandene Daten in $data kopieren
    $data .= $IPS_VALUE; // neu empfangene Daten an $data anhängen

    if (strlen($data) >= 11) // wenn $data mindestens 11 Zeichen lang ist
    {
        $datasets = str_split($data, 11); // $data in Blöcke von bis zu 11 Zeichen zerlegen
        $data = ""; // $data leeren
        for ($i = 0; $i < count($datasets); $i++) // alle Datensätze durchgehen
        {
            if (strlen($datasets[$i]) == 11)
            {
            	SetValueString(32686 /*[0. Keller\Heizung\LevelJet (Keller)]*/ , $datasets[$i]);
            }
            else
            {
                $data = $datasets[$i]; // Unvollständige Daten in $data schreiben, falls der letzte Datensatz nicht genau 11 Zeichen hat
            }
        }
    }

    RegVar_SetBuffer($IPS_INSTANCE, $data); // Inhalt von $data im Puffer der RegisterVariable-Instanz speichern
}

?>

Der Buffer wird bei 11 Zeichen in die Stringvariable ID 32686 geschrieben und die triggert mein Script:

*************************************************
 Heizöl-Füllstand überwachen (LEVELJET)
*************************************************
File     : LEVELJET_LOG.ips.php
Trigger  : Variable LEVELJET
Interval : 1 Sekunde
*/


//if (GetValueString(32686 /*[0. Keller\Heizung\LevelJet (Keller)]*/ ) == "")
//   return;
//if (!IPS_SemaphoreEnter("RegisterVariable_Log_run",1))
//   return;
//IPS_Sleep(800);
$buffer = GetValueString(32686 /*[0. Keller\Heizung\LevelJet (Keller)]*/ );
//SetValueString(32686 /*[0. Keller\Heizung\LevelJet (Keller)]*/ ,"");
list($usec, $sec) = explode(" ", microtime());
$start_time = strftime("%H:%M:%S",$sec);

// Debugmodus = true schreibt Log - false beendet Logging
$ldebug = false;

// Datenblock zerlegen und Menge errechnen
$length = strlen($buffer);
if ($ldebug)
    echo "Länge: ". $length ."
";
if ($length == 11)
{
    $high_byte = ord($buffer{7});
    $low_byte = ord($buffer{6});
    $menge = $high_byte * 256 *10 + $low_byte * 10;
    SetValueInteger(55389 /*[0. Keller\Heizung\Heizöltank Füllstand (Keller)]*/ ,$menge);
}


if ($ldebug){
// Logfile öffnen (Pfad und Datei)
    $handle = fopen("H:/LevelJet/testlog.txt","a");

// Message verarbeiten
    $length = strlen($buffer);
    if ($length !== 0)
    {
        fwrite($handle,$start_time." > ");
        for ($i=0; $i<$length; $i++)
        {
            $dbyte = ord($buffer{$i});
            fwrite($handle, set_byte($dbyte)." ");
        }
        fwrite($handle,"
");
    }
    fclose($handle);
}

function set_byte($byte){
   if ($byte < 16)
      return "0".dechex($byte);
   else
      return dechex($byte);
}
//IPS_SemaphoreLeave("RegisterVariable_Log_run");
?>

Allerdings konnte ich vorhin beobachten, dass die IPS-Zeit der System-Zeit fast 2 Minuten nachhinkte und die IPS-Console bis zu 70% CPU-Leistung in Anspruch nahm und
Das konnte aber auch an der Zeile:

SetValueString(32686 /*[0. Keller\Heizung\LevelJet (Keller)]*/ ,"");

…gelegen haben, die ich jetzt mal ausdokumentiert (während ich dieses Posting schrieb) habe.
Da kam scheinbar etwas durcheinander und mein bzw. wurde das 2. Script dadurch immer wieder neu getriggert.
Jetzt scheint sich’s zu normalisieren und die Consolen-Last liegt jetz bei 10-20%.

Was ich jetzt daraus gelernt habe, man braucht also ein zusätzliches Script zum Auswerten der Registervariable, in dem Fall zumindest. Eigentlich wollte ich alles in ein Script packen.

Vielen Dank für eure Unterstützung!

man braucht also ein zusätzliches Script zum Auswerten der Registervariable

brauchst Du nicht, pack doch alles in eines.

Also Rainer, die Kommentare finde ich jetzt nicht sehr hilfreich!
Wenn für dich alles klar ist, kann ich ja verstehen, aber mir hilft das nicht weiter.
Vielleicht kannst du ja etwas mehr ins Detail gehen.

Bestimmt gibt es eine Lösung mit nur einem Script, aber ich habe dabei einiges durchgespielt und bin eben nicht zum Erfolg gekommen. Ich hätte wohl dabei das ganze ursprüngliche Script umschreiben müssen. Zukünftig weiss ich aber mit der „RegisterVariable ins Script-Schreiben-Funktion“ umzugehen (hoffe ich zumindest) und packe das von Anfang an so mit rein.

Ich habe nur richtig gestellt das man nicht mehrere Scripts zum auswerten der Registervariable braucht.
Wegen mir wertest Du sie mit 10 Scripts aus. :wink:

Wenn der Kommentar für dich nicht hilfreich war, ignoriere ihn einfach, eventuell hilft er ja anderen.

Hallo Ihr PHP-Cracks,

brauche nochmal Hilfe:

Mein Script an der Registervariable läuft absolut fein, eines bekomme ich jedoch nicht hin: zur Zeit wird das Script ja bei einer Änderung an der Variablen ausgeführt und führt abhängig davon bei mir verschiedene Dinge aus.

Nun möchte ich aber auch zyklisch über einen Timer Teile des Scriptes ausführen - z.b. das, was jetzt unter der elseif-Anweisung „Home“ steht:

$data  = $IPS_VALUE;
if ($data == "Online")
	{
	RegVar_SendText(13467 /*[XBee Wetterstation\Register Variable]*/ , chr(27)."YH".chr(15));
	IPS_Sleep(10);
	RegVar_SendText(13467 /*[XBee Wetterstation\Register Variable]*/ , chr(27)."MN".chr(1));
	IPS_Sleep(10);
	TTS_Speak(44246 /*[Mediaplayer\Text To Speech]*/, "Wetterstation! angemeldet", false);
	}
elseif ($data == "Home" or $data == "13")
	{
	IPS_Sleep(10);
.
.
.
.

Jemand eine Idee?

Vielen Dank vorab!

Wie das Skript aufgerufen worden ist lässt sich folgendermaßen unterscheiden:

if ($IPS_SENDER == "RegisterVariable")
{
    // code...
}
else if ($IPS_SENDER == "TimerEvent")
{
    // code...
}

Mehr dazu siehe Systemvariablen - IP-Symcon :: Automatisierungssoftware.

Würde das dann so gehen:

$data  = $IPS_VALUE; 
if ($data == "Online") 
    { 
    RegVar_SendText(13467 /*[XBee Wetterstation\Register Variable]*/ , chr(27)."YH".chr(15)); 
    IPS_Sleep(10); 
    RegVar_SendText(13467 /*[XBee Wetterstation\Register Variable]*/ , chr(27)."MN".chr(1)); 
    IPS_Sleep(10); 
    TTS_Speak(44246 /*[Mediaplayer\Text To Speech]*/, "Wetterstation! angemeldet", false); 
    } 
elseif ($data == "Home" or $data == "13" or $IPS_SENDER == "TimerEvent")
    { 
    IPS_Sleep(10); 
. 
. 
. 
. 

Vielen Dank fürs Schauen!

$IPS_VALUE ist für TimerEvent nicht definiert. Daher musst Du das etwas umschreiben, z.B. folgendermaßen:

$data = "";
if ($IPS_SENDER == "TimerEvent")
{
    $data = "Timer";
}
else
{
    $data = $IPS_VALUE; 
}

if ($data == "Online") 
    { 
    RegVar_SendText(13467 /*[XBee Wetterstation\Register Variable]*/ , chr(27)."YH".chr(15)); 
    IPS_Sleep(10); 
    RegVar_SendText(13467 /*[XBee Wetterstation\Register Variable]*/ , chr(27)."MN".chr(1)); 
    IPS_Sleep(10); 
    TTS_Speak(44246 /*[Mediaplayer\Text To Speech]*/, "Wetterstation! angemeldet", false); 
    } 
elseif ($data == "Home" or $data == "13" or $data == "Timer")
    { 
    IPS_Sleep(10); 
. 
. 
. 
.  

Vielen Dank Horst, Du bist echt spitze!

Ich werde es mal so probieren - und bin mir fast sicher, dass Du wieder mal eine 100%ig funktionierende Lösung gepostet hast :slight_smile:

Hallo nochmal,

ein Problem habe ich noch:

Ich möchte unterscheiden, über welches Timerereignis (es gibt 2) das Script an der Registervariable getriggert wurde.

Mit $IPS_Event habe ich schon versucht, die ID des auslösenden Timers abzufragen (siehe unten), aber irgendwie funktioniert es nicht und ich bekomme immer ein fehlerhaftes Script :frowning:

Kann jemand helfen - vielen Dank vorab!

$data = "";
if ($IPS_SENDER == "TimerEvent")
{
    $id = $IPS_Event;
    $data = "Timer";
}
else
{
    $data = $IPS_VALUE; 
}

if ($data == "Online") 
    { 
...
    } 
elseif ($data == "Home" or $data == "13" or ($data == "Timer" and $id == 12345)) //12345 = ID des Timers
    {  
...
    }

Probier’s mal mit $IPS_EVENT, also alles groß… :wink:

@dfhome:

:o:o:o Oh mann, das war es :slight_smile: Vielen lieben Dank!!!

Mein Script hat jetzt sagenhafte 1310(!) Zeilen Code und langsam blicke ich selbst nimmer durch :-))

Vielen Dank nochmals!!