Xiaomi Gateway Module

Hallo,

ich bin dabei ein Module fuer die Einbindung von Sensoren und as Gateway von Xiaomi.
Die ersten Funktionen sind implementiert.

Ich schreibe dafuer ein Splitter Module und ein Device Module. Als I/O funktioniert das Multicast Socket ganz gut.
Xiaomi kommuniziert ueber json kodierte Befehle.

Mit {„cmd“:„get_id_list“} an das Gateway gesendet bekommt man {„cmd“:„get_id_list_ack“,„sid“:„xxx“,„token“:„xxx“,„data“:"[„158d00011c1414“,„158d00013e3d2e“,„158d00012cb74c“]"}
zurueck. In Data stehen somit die einzelnen IDs.
Jetzt wollte ich vom Device Module aus zu jeder ID das Sensor Model auslesen. (foreach $data as $key=>$value…
„{„cmd“:„read“,„sid“:„158d00011c1414“}“

Jetzt zu meiner Frage.
Wie kann ich im Device Module alle Ergebniss vom Splitter Module abholen und ich einer php varriable zwischenspeichern?

Habs so mal versucht aber das geht nicht.


public function GetList ($ids){
            foreach ($ids as $key=>$value) {
                $payload = array ("cmd" => "read", "sid" => $value);
                $result[] = $this->SendDataToParent(json_encode(Array("DataID" => "{E496ED12-5963-4494-87F3-E537175E7418}", "Buffer" => json_encode($payload)))); 
            }
            print_r ($result);
            return $result;
        }


Danke fuer eure Hilfe.

MiniBlister

In einer Variable kannst du nichts zwischenspeichern, da die Instanz deiner Klasse nicht persistent im Speicher liegt.
Dafür gibt es aber SetBuffer und GetBuffer.
Der Rückgabewert von SendDataToParent ist der Wert von ForwardData im Splitter.
Michael

Aber wenn der Ruckgabewert von SendDataToParent der Wert vom Sptiller ForwardData ist, dann kann ich doch wie oben x mal den Rueckgabewert holen und eine Varriable schreiben.

Die Instanz muss ja so lange vorhanden sein bis der Wert da ist, oder?

Verstehe nicht was du meinst.
IPS startet jedes Mal intern ein Script, erzeugt eine Instanz aus deiner Klasse mit der InstanceID und führt dann die benötigte Funktion aus, anschließend wir alles verworfen.
SendDataToParent wartet dabei auf die Rückgabe von ForwardData. Und wie gibst du den Wert in ForwardData zurück?
Weil zum IO kannst du nicht bei SendDataToParent auf eine Rückmeldung hoffen. IPS kann nicht wissen wie die Antwort aussehen soll.
Du musst die Daten im Splitter also selbst aus verschiedenen Threads (Senden und Empfangen) zusammenführen.
Oder verstehe ich deine Frage nicht?
Michael

Hallo, danke für deine Hilfe und Entschuldige meine Unwissenheit.

Ich glaube ich versuche mich gerade schon am „Zusammenbauen“. So wie ich dich verstehe muss ich im Splitter auf das Commando cmd:read im ForwardData filtern. Sobald das kommt muss ich das foreach starten und alle Werte die ich im Splitter im RecriveData beim cmd:read_act bekomme in einen Buffer legen.

Da liegt wohl genau mein Problem. Ich dachte dieser Buffer könnte ein Array sein aber das scheint wohl nicht zu gehen, oder?

Buffer sind Strings. Aber du kannst natürlich mit serialize Objekte / Arrays in einen String speichern.
Michael

Verstehe ich richtig, dass du im Splitter für eine Anfrage Daten sammeln willst und diese dann über das return von ForwardData an das Gerät zurückgeben willst?

paresy

Ja genau das ist der Plan. Daten sammeln heißt mehrere Daten vom i/O zu holen welches in meinem Fall ein muticast UDP Socket ist.

Aber ich bekomme das derzeit nicht hin. Muss ich dafuer SetBuffer nehmen oder kann ich das auch anders lösen.

Gesendet von meinem SM-T715 mit Tapatalk

Im Normalfall hält ein Splitter keine Nutzdaten vor. Sondern schiebt die Anfrage vom Device weiter an den IO und gibt die Antwort dann an das Device zurück. Alles über die Funktion ForwardData im Splitter.
Michael

Den „Normalfall“ verstehe ich. In meinem Fall liefert aber die Anfrage vom Device nicht nur eine Antwort sondern mehrere. Ich muss also im Device warten bis alle Antworten da sind. Ich dachte das kann ich über einen Splitter machen der die Daten so lange sammelt bis die Daten komplett sind und dann an erst an das Device zurück liefert.

Gesendet von meinem SM-T715 mit Tapatalk

Warten musst du im Device ja nicht.
SendDataToParent liefert als Rückgabewert ja das Return aus ForwardData im Splitter.
Warten musst du also im Splitter.
Ohne ja das Protokoll und das Verhalten des Gateway zu kennen, kannst du ja auch bzw. zusätzlich alle empfangenen Daten im Splitter mit SendDataToChildren an die Devices verteilen.
Michael

Danke dir…und wie warte ich im Splitter?

Gesendet von meinem SM-T715 mit Tapatalk

Das… Kannst du z.B. nach dem Senden, mit einer Schleife und Sleep machen welche immer einen Buffer auf die Antwort prüft.
Dazu dann im ReceiveData vom Splitter die Antwort in eben dieses Buffer schieben.
Michael

Hallo,

hab das mal versucht. Wenn ich im Splitter die Liste aller SIDs vom IO zureuck bekomme dann Sende ich gleich die Anfrage wieder an das I/O welches Model es ist. Das Model lese ich dann in einen Buffer mit dem Namen sid ein.
Diese pruefe ich dann wie unten in einer While scheifen (das $x ist nur um zu verhindern, dass ich eine Endlosschleife bekommen.

Leider wird der Buffer nie gefuellt. Hatte ich dich falsch verstanden?

            foreach ($ids as $key=>$value) {
                $payload = array ("cmd" => "read", "sid" => $value);
                $return = @$this->SendDataToParent(json_encode(Array("DataID" => "{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}", "Buffer" => json_encode($payload))));
                $x = 0;
                while (empty($this->GetBuffer($value)) AND $x <10) {
                    IPS_Sleep(1000);
                    $this->SendDebug("test",$this->GetBuffer($value),0);
                    $this->SendDebug("test",$value,0);
                    $x++;
                }
            }
            $this->pushtochild($ids, $model, $sid);

Die IOs liefern nie etwas zurück wenn du sie mit SendDataToParent ansprichst.
Die Daten musst du selbst im ReceiveData empfangen und dort (weil es ein anderer PHP-Thread ist) in einen Buffer schreiben.
Michael

Gibt es dafür ein Beispiel?

Gibt’s hierzu schon Neuigkeiten?

Gesendet von meinem Redmi Note 2 mit Tapatalk