Christian Geschrieben May 11, 2012 at 13:09 Geschrieben May 11, 2012 at 13:09 Servus, ich würde gern mein "Equipment" gern per PHP steuern. Erste "erfolge" hab ich ja schon gehabt, aber so richtig zufrieden bin ich irgendwie noch nicht. Zu schaffen macht mir irgendwie diese Callback-Möglichkeit in PHP. Das Script "steht" quasi jedes Mal solang der Callback läuft. selbst wenn ich z.B. angebe, dass bei einem Callback-Aktion z.B. was auf's Display geschrieben wird passiert da nix. Sobald aber der Callback zuende ist, führt er quasi alles aus und schreibt wie wild auf dem Display rum... Ich hab auch spaßeshalber die Zahl der Callbacks hochzählen lassen und da passiert schon a bissl was. Wie ist das denn gedacht dies zu nutzen? Aktuell arbeite ich nur mit dem CLI... Gruß Christian Zitieren
photron Geschrieben May 11, 2012 at 13:41 Geschrieben May 11, 2012 at 13:41 PHP hat keine Threads. Das führt erstmal dazu, dass du selbst dispatchCallbacks() aufrufen musst. Wenn du dispatchCallbacks(1) dann werden eingehende Daten vom Socket gelesen und wenn es sich um Callbacks handelt werden diese ausgeführt, falls dafür Funktion registriert wurden. Wenn du dispatchCallbacks(1) aufrufst, dann wird das eine Sekunde lang gemacht und dispatchCallbacks(1) returned auch erst nach einer Sekunde. Das heißt das dein Script an der Stelle für eine Sekunde "steht". Du kannst auch dispatchCallbacks(0) aufrufen, dann werden nur die gerade verfügbaren Daten vom Socket gelesen ohne noch eine Sekunde auf weitere Daten zu warten. Daher empfehlen ich dir dispatchCallbacks(0) aufzurufen. Du solltest weiterhin darauf achten dass du keine lange dauernden Dinge in den Callback Funktionen machst. Zitieren
Christian Geschrieben May 11, 2012 at 14:59 Autor Geschrieben May 11, 2012 at 14:59 OK, danke erst mal. Das macht das ganze zwar nicht unbedingt leichter ;-), aber ich hab mal was geschustert, was mehr oder weniger gut läuft. Findet Ihr im Wiki. Ich hab nur ein großes Problem: - beim RotaryPot läuft der Callback nach dem zweiten Durchgang der unendlichen While-Schleife nicht mehr... die Temperatur wird ständig abgefragt, die Position aber wie gesagt nach dem zweiten Durchlauf nicht mehr. Der Dispatcher läuft ja 2 sekunden und startet dann neu Aktuell kommt beispielhaft folgendes auf der Console an: D:\>php.exe -f tinkerforgeV1.php Rotary connected LCD connected rotpot: 39 pos:39.....^C Nach jedem Durchlauf der Schleife wird ja ein Punkt ausgespuckt, aber ich kann mir da den Wolf drehen ;-) rotpot: ist die Callback funktion und pos: wird ja nur einmal gelesen bevor es in die Schleife geht... Ich hab den gesamten Code schon mal soweit auskommentiert das nur noch LCD und Rotary verbunden sind. Und es ist dann nur der Rotary-Callback aktiv. Gruß Christian Zitieren
photron Geschrieben May 11, 2012 at 16:07 Geschrieben May 11, 2012 at 16:07 Ich hab gerade noch ein Problem mit den Callbacks behoben. Wenn du in einem Callback einen Getter des selben Devices aufgerufen hast konnte das zu einer TimeoutException führen. Das ist in PHP Bindings Version 1.0.2 jetzt behoben. Zu deinem Problem: Dein Script erzeugt in jeder connect_* Funktion eine neue IPConnection. Du solltest initial nur eine erzeugen un die dann in allen connect_* Funktion verwenden. So wie dein Script jetzt ist dispatcht du Callbacks nur auf der zuletzt erzeugen IPConnection der du nur das Temperature Bricklet hinzugefügt hast. Ich denke das erklärt dein Problem Zitieren
Christian Geschrieben May 11, 2012 at 18:11 Autor Geschrieben May 11, 2012 at 18:11 Ja Ok, Dann schau ich mir das am Montag gleich mal an. Hab die Sachen alle im Büro :-). Das mit der IPconnection ins mir auch schon mal aufgefallen. Ich probiers mal dann auch mit den neuen Bindings und bin mal gespannt. Vielen Dank erstmal. Gruß Chris Zitieren
Christian Geschrieben May 14, 2012 at 10:08 Autor Geschrieben May 14, 2012 at 10:08 Also ich hab mir mal die neuesten Bindings gezogen 1.0.2 und meinen Code entsprechend optimiert/korrigiert. sieht jetzt mal ganz nett aus und alles klappt soweit relativ gut. ohne diese Threads ists halt nicht so das wahre. ich lasse den Dispatcher nun 1/10-Sekunde laufen und lasse dann entsprechend die Callback-Funktionen laufen. Aktuell gibt mein Display folgendes aus: - nen Titel - die Position des Rotary Poti - die Temperatur auf eine Nachkomma-Stelle gekürzt. - die aktuelle Uhrzeit Folgende "Features" gibt’s noch oben drauf: - LCD blinkt einmal kurz auf, wenn die Temperatur über 25°C liegt. - das LCD blinkt jetzt auch nicht ununterbrochen wenn der Grenzwert überschritten ist, sondern "nur" alle 10 Sekunden mal kurz als Hinweis. - die Uhrzeit wird nur auf das LCD geschrieben wenn diese sich auch geändert hat (also quasi nur einmal pro Minute und nicht 10x pro Sekunde :-) ) Zitieren
Nitram Geschrieben May 15, 2012 at 07:09 Geschrieben May 15, 2012 at 07:09 Abhängig vom geplanten Einsatzzweck lässt sich ein längerer Callback auch mittels pcntl_fork() auslagern. Dazu gibt es ein paar einfache Klassen die öffentlich verfügbar sind, die den Aufwand zur Verwaltung erheblich reduzieren. Die Frage ist schlicht was genau notwendige Arbeiten bzw. wie stark der Informationsaustausch zwischen den Prozessen dann wird, da dies schon eine Menge zusätzlichen Codes bedarf. Auf nachfolgendem Link ist dazu ein Beispiel zu finden: http://blog.motane.lu/2009/01/02/multithreading-in-php/ Zitieren
Christian Geschrieben May 15, 2012 at 07:16 Autor Geschrieben May 15, 2012 at 07:16 wenn ich das noch richtig im Kopf hab, sind die pcntl-Funktionen nicht auf Windows-Systemen verfügar... das nur so am Rande. nur die *NIX-en wäre da noch ein Hinweis auf das PEAR-Modul System_Daemon. Mal schaun. Noch ist das alles Bastelei bei mir. Evtl werd ich doch noch auf Java umsteigen, wenn ich Muse zum lernen hab Zitieren
borg Geschrieben May 15, 2012 at 07:52 Geschrieben May 15, 2012 at 07:52 Wir hatten festgelegt das es standalone auf Linux und Windows sowie mit Apache funktionieren sollte. pcntl_fork funktioniert nicht auf Windows oder mit Apache und andere Lösungen funktionieren nur mit Windows und unter Apache sieht man ganz alt aus. Daher haben wir uns für die Lösung ohne Threads entschieden. Mal davon abgesehen: Wenn ich einen zweiten Prozess hab (wie einen System_Daemon oder mit pcntl_fork) muss man immernoch pollen um die Daten die beim geforkten Prozess aufgelaufen sind abzuholen! Dadurch würde man nicht viel gewinnen. Zitieren
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.