Umgang mit asynchronen Daten

Hallo Leute,

vielleicht ist der Titel nicht ganz selbstsprechen…:slight_smile:

Worum geht es: Wenn ich Daten seriell absende, komme diese „losgelöst“ an anderer Stelle im Code als Antwort an. Je nachdem wie viel - oder wenig - Mühe sich der Programmierer des seriellen Gerätes gemacht hat, kommen dann Daten ohne Bezug auf die Anfrage zurück. Wenn ich einzelne Anfragen stelle, dann kann ich mit Glück diesen Dateneingang mit der letzte Anfrage matchen.
Gleichwohl frage ich mich, ob es nicht ein Model gibt, dass es mir ermöglicht mit hoher Sicherheit die ankommenden Daten mit einer vorher durchgeführten Anfrage erfolgreich zu matchen, auch wenn eine größere Menge an Anfragen gesendet wurde.

Habt ihr so etwas schon mal erfolgreich umgesetzt?

Joachim

Du kannst an der Stelle leider nur eine Anfrage senden und dann warten, bis die Antwort angekommen ist. Alles andere bietet nur Fehlerpotenzial.

paresy

Das kommt immer auf das Protokoll an. Ich habe gerade ein serielles Protokoll implementiert, das zu beginn immer den Nachrichtentyp sendet. Das macht es wenigstens etwas einfacher darauf zu reagieren.

Generell habe ich es so aufgebaut, dass die Scripted für senden und empfangen getrennt sind. Die empfangene Nachricht wird in eine Buffer geschrieben und dann so zerstückelt wie ich sie brauche.

Ggf. Kannst du auch die gesendeten Befehle in einen Buffer schieben und dann in Kombination auswerten.

Hallo Paresy und Firebuster,

vielen Dank für Eure ntworten. Das ist in Summe sehr unbefriedigend. Ich habe daher nach einem ganz anderem Weg gesucht und bin (wahrscheinlich) fündig geworden…
Das Gerät hat auch eine eigene Website, so das es mir mit viel Googln gelungen ist mit CURL Daten zurück zu bekommen!
Das Ergebnis von $output = curl_exec($ch); und print_r($output); sieht so aus:

{pwr:"1",hid:"0",frz:"0",eco:"0",src:"6",bri:"0",con:"0",vks:"0",hks:"0",gam:"2.2",ctp:"CT1",mod:"255",vol:"20",apr:"255",zom:"1.0",prj:"0",lgo:"0",aks:"1",dyar:"29"}

Wie kann ich jetzt auf die einzelnen Parameter zugreifen?

Joachim

War das ein Glas Wein zuviel zu Weihnachten?
Das ist JSON, damit solltest du klar kommen.
Michael

Ja, war auch mein erster Gedanke!

Bekomme aber mit

$json = json_decode($output, true);
echo $json['pwr'];
echo $json['hid'];

irgendwie nichts raus…:confused:

Joachim

Das ist ein „kaputtes“ Json :wink:

Falsch = {pwr:„1“,hid:„0“, …
Richtig = {„pwr“:„1“,„hid“:„0“,…

So könnte man es „umbauen“:

<?

$falschesJson = '{pwr:"1",hid:"0",frz:"0",eco:"0",src:"6",bri:"0",con:"0",vks:"0",hks:"0",gam:"2.2",ctp:"CT1",mod:"255",vol:"20",apr:"255",zom:"1.0",prj:"0",lgo:"0",aks:"1",dyar:"29"}';

$explodeAR = explode(',', substr($falschesJson, 1, -1));

foreach ($explodeAR as $explodeEntry) {
	$tempAR = explode(':', $explodeEntry);
	$dataAR[$tempAR[0]] = $tempAR[1];
}

print_r($dataAR);

?>

Viele Grüße,
Chris

Es ist soweit erst mal kein gültiges Json, da der Key nicht Inn Anführungsstrichen steht.

Es ist aber wahrscheinlich nicht zu erwarten, dass die Reihenfolge sich ändert oder die Daten mehrere Ebenen bekommen. Aus diesem Grund würde ich einfach mit String Operationen arbeiten.

Stimmt [emoji28]
Peinlich, ich hatte da wohl das Glas zu viel.
Dadurch das die Zahlen alle in Anführungszeichen stehen wohl irritiert gewesen.
Michael

…habe mal nach „JSON without Quotes“ gegoogelt: Das Problem scheint insbesondere dann zu bestehen, wenn die Website aus JAVE-Skript gebaut ist…

Das hier soll helfen:

$output = preg_replace('/("(.*?)"|(\w+))(\s*:\s*)\+?(0+(?=\d))?(".*?"|.)/s', '"$2$3"$4$6', $output);

Tatsächlich kommt hinterher dieses heraus:

{"pwr":"1","hid":"0","frz":"0","eco":"0","src":"6","bri":"0","con":"0","vks":"0","hks":"0","gam":"2.2","ctp":"CT1","mod":"255","vol":"20","apr":"255","zom":"1.0","prj":"0","lgo":"0","aks":"1","dyar":"29"}

Gleichwohl führt das mit

$json = json_decode($output, true);

immer noch nicht zu dem erwarteten Ergebnis…:confused:

…es fehlen offenbar noch die ’ (Hochkomma) davor und dahinter!

Wenn ich das zum Test so mache:

$output = '{"pwr":"0","hid":"0","frz":"0","eco":"0","src":"0","bri":"0","con":"0","vks":"0","hks":"0","gam":"1.8","ctp":"CT1","mod":"0","vol":"0","apr":"0","zom":"1.0","prj":"0","lgo":"0","aks":"0","dyar":"0"}';

dann funktioniert es…

Nachtrag: Eine Idee wie man das hinbekommt?

…waren nicht die Hochkommata, sondern:

$output = strip_tags($output);

war die Lösung…

Vielen Dank für den Ruck in die richtige Richtung!

Joachim

Nur mal so gefragt - meinen Post #7 nicht gesehen?
Aber viele Wege führen ja nach Rom :slight_smile:

-Chris-

Hallo Chris,

fand die Lösung mit der einen Zeile etwas charmanter…:wink: Trotzdem waren Eure Hinweise der richtige Fingerzeig!

Gleichwohl:
Wonach muss ich suchen, um nicht nur die Werte zu lesen, sondern diese auch zu setzen?

Joachim

Was meinst du mit Werte setzen? Bisher ging es hier ja nur ums lesen und du hast auch zum Gerät oder so nichts geschrieben.

-Chris-

…über den seriellen Zugriff kann man Daten lesen als auch setzen, gleichwohl ist es eher ein ziemlich direkter Ersatz der FB.
Das Gerät ist ein Videoprojektor von Acer. Die Funktionen der seriellen Schnittstelle sind leider mehr als bescheiden (inkl. der offiziellen Dokumentation). Wie schon oben beschrieben wollte ich mehr Funktionalitäten in mein Modul integrieren.
Über LAN kann ich jetzt bereits diverse Status auslesen und visualisieren sowie das Gerät über WOL einschalten, würde aber gerne auch auf diese Weg auch Statusänderung (z.B. Änderung des aktiven Eingangs) aus IPS heraus umsetzen.

Habe mich heute das erste Mal überhaupt mit cURL auseinandergesetzt, mein aktueller Stand des Moduls benutzt (noch) die serielle Schnittstelle.

Joachim

Kann dir zu fast jedem Beamer was sagen - nur nicht zu Acer :smiley: Musste mal schauen, ob du irgendwo eine Beschreibung zur Schnittstelle findest.

Kannst ja auch mal das genaue Modell posten, vlt hat jemand schon mal was damit gemacht.

Dein Acer kann nicht zufällig PJLink? Dafür hätte ich schon ein Modul :slight_smile:

-Chris-

PS: Wie man Daten an eine serielle Schnittstelle sendet steht in der IPS Doku. Oder rechte Maustaste auf dem IO und „Befehl testen“.
Aber ich würde LAN bevorzugen.

Hallo Chris,

deswegen schrieb ich oben: Seriell ist nicht so besonders toll, versuche daher spontan auf LAN umzustellen…
Frage: Lesen kann ich mit cURL, kann ich damit auch etwas setzen?

Joachim

Mit curl kann man auch einen POST machen…aber ohne mehr Infos kann man dir nicht helfen. Da gibt es viele viele verschiedene Sachen…

Woher sollen wir wissen was deine Hardware kann…
Gibt ja auch GET oder PUT.
Michael