WebHook aus Modul dynamisch erstellen

…ich versuche das mal:
Die Daten kommen dann in der untergeordneten Instanz hier an (Auszug):

public function ReceiveData($JSONString) 
	{
		// Empfangene Daten vom Gateway/Splitter
		$data = json_decode($JSONString);
		switch ($data->Function) {...

dort kann je nach der Aufgabe differenziert werden.

Aus der untergeordneten Instanz geht es denn per:

$this->SendDataToParent(json_encode(Array("DataID"=> "{A0DAAF26-4A2D-4350-963E-CC02E74BD414}", "Function" =...

wieder zurück zur übergeordneten Instanz

wo es im (Auszug):

public function ForwardData($JSONString) 
	 {
	 	// Empfangene Daten von der Device Instanz
	    	$data = json_decode($JSONString);
	    	
	 	switch ($data->Function) {...

wieder verarbeitet wird…

Joachim

Hallo Joachim,

soweit hatte ich das auch verstanden, aber im Splitter bekomme ich es doch dann nicht mehr in ProcessHookData :confused:

Grüße,
Kai

…spontane Idee:
Du benutzt die untergeordneten Instanzen quasi nur als „Eingabeformular“. Beim Übernehmen werden die Daten an den Splitter gesendet und dort abgelegt z.B. in Arrays, so dass Du bei Anfragen dort schaust welche Variable gesetzt bzw. abgefragt werden muss…

Was anderes fällt mir auch ad hoc nicht ein…:frowning:

Joachim

Warte im ProcessHook auf Daten in einem Buffer, welchen du in ForwardData füllst.
So kannst du Daten aus verschiedenen Threads innerhalb einer Instanz übergeben.
Michael

Gibt es dazu irgendwo ein Beispiel? :slight_smile:

Nicht wirklich nur die Doku:
GetBuffer — IP-Symcon :: Automatisierungssoftware
Michael

Wie wartet man denn dann auf den Buffer?
Mir würde da nur ein Sleep einfallen und das ist doch mit die Funktion, die man eig. meiden sollte?! :confused:

…und man braucht eine „Notbremse“ - weil es ja auch sein könnte, dass aus irgendwelchen Gründen überhaupt keine Daten kommen…

Die Variante war mir auch durch den Kopf gegangen, hatte ich aus den beiden Gründen aber wieder verworfen.

Joachim

Ich glaube es ist einfacher ohne Splitter zu arbeiten und für jeden Service einen eigenen Hook anzulegen. :smiley:
Oder gibt es noch einen Lösungsweg?

Hier mal Ausschnitte von etwas von meinem Datenaustausch, nur dass ich es immer in die andere Richtung, also Splitter zum IO nutze.


    /**
     * Wert einer Eigenschaft aus den InstanceBuffer lesen.
     * 
     * @access public
     * @param string $name Propertyname
     * @return mixed Value of Name
     */
    public function __get($name)
    {
//        $this->SendDebug('Get ' . $name, $this->GetBuffer($name), 0);
        return unserialize($this->GetBuffer($name));
    }
    /**
     * Wert einer Eigenschaft in den InstanceBuffer schreiben.
     * 
     * @access public
     * @param string $name Propertyname
     * @param mixed Value of Name
     */
    public function __set($name, $value)
    {
//        $this->SendDebug('Set ' . $name, serialize($value), 0);
        $this->SetBuffer($name, serialize($value));
    }


    public function BeispielZumGerate($Data)
    {
        $this->SendDataToChildren($Data);
        if ($this->WaitForResponse(250))    //warte auf Reply
        {
            $Buffer = $this->Buffer;
            $this->Buffer = '';
            if ($Buffer == 'irgendwas')
            {
                // Mach irgendwas, wie return $Buffer wenn dies hier ProcessHook wäre
            }
         }
     }

    public function ForwardData($JSONString)
    {
        $data = json_decode($JSONString);
        $this->Buffer = utf8_decode($data->Buffer);
        $this->SetReplyEvent = true;
        return true;
    }

    /**
     * Warte auf das SetReply Event.
     *  
     * @access private
     * @param int $Timeout Max. Zeit in ms in der dass Event eintreffen muss.
     * @return boolean True wenn das Event eintrifft, false wenn Timeout erreicht wurde.
     */
    private function WaitForResponse(int $Timeout)
    {
        for ($i = 0; $i < $Timeout / 5; $i++)
        {
            if ($this->SetReplyEvent)
            {
                $this->SetReplyEvent = false;
                return true;
            }
            else
                IPS_Sleep(5);
        }
        return false;
    }

Michael

Dankeeeeeeeeeeeeeeeee. :):):):slight_smile:
Damit klappts. :slight_smile:

Grüße,
Kai

Wenn in jeder Funktion ein Return setzt und dann in der untergeordneten Instanz einen Funktion aufrufst bekommst Du das Ergebnis auch wieder in Processhookdata zurück.

An der Stelle nicht ganz. Weil ich den Wert ja erstmal aus der anderen Instanz brauche und das scheint nur über den Buffer zu funktionieren.

Gesendet von iPhone mit Tapatalk

Das Funktioniert wenn du von unten (Device) nach oben sendest (Splitter) , dann kann der Parent dem Child einen Wert zurückgeben.

Hier ist es aber dass er von oben (Splitter) nach unten (Device) sendet und da gibt es keinen Rückgabewert.
Kann auch nicht weil es ja in diese Richtung eine 1:n Verbindung ist und du kannst ja nicht n-Rückgabewerte entgegennehmen.

Michael

Das stimmt ich nutze das von unten nach oben. Wenn man von oben nach unten geht könnte man aber über eine spezifische Funktion der untergeordneten Instanz gehen. Diese wird dann ja mit der ObjekID aufgerufen und gibt Dir dann auch im Gegensatz zu ForwardData eine Wert zurück da dann ja nur die Instanz angefragt wird und nicht wie bei Forwarddata an alle Children was weitergegeben wird.

Michael, danke für die ganze Hilfestellung. :slight_smile:
Ich hab es jetzt auch geschafft mit IPS_RequestAction() eine Variable zu schalten. (Aber noch fest im Code hinterlegt)

Mit GetProfileAction und GetProfileName muss ich rausfinden, um was für ein Profil es sich bei der Variable handelt die ich schalten möchte und meinen Wert, den ich an die Funktion übergebe ggf. umwandeln, damit sie für das Profil geeignet ist, habe ich das so richtig verstanden?

Grüße,
Kai

Setzen 6. Wer so etwas macht gehört erschossen :wink:
Zumal dann der User diese Funktionen in eigenen Scripten innerhalb von IPS sehen und nutzen könnte.
Wie war das noch mit einem Leid-- äh Leitfaden :smiley: :wink:

@Kai:
Ja, würde ich auch so sehen. Je nach Hardware bzw. Profil gibt es ja Unterschiede.

Michael

Hab ich ja glück gehabt, ich wollte erst eine Public Funktion dafür bauen. :smiley:
Aber genau das habe ich auch gedacht, dann kann jeder darauf zugreifen. :banghead:

Grüße,
Kai

Hallo,

nochmal zu der IPS_RequestAction(), eigentlich müsste ich doch nur den VariablenTyp abfragen, das Profil interessiert doch eigentlich gar nicht beim setzen der Variable.

Grüße,
Kai

Gesendet von iPhone mit Tapatalk

Wenn du an haben willst, musst du doch wissen ob an nun false oder true ist.
Michael