Jump to content

[PHP] Grundfunktion, Callbacks und mehrere Sensoren auslesen


numark1
 Share

Recommended Posts

Hallo zusammen !

 

Mein erster Beitrag, es sieht wohl so aus als ob ich gerade den Wald vor Bäumen nicht sehe.

 

Ich habe mir mal ein Grundset bestellt, Masterbrick, Bricklets für Temperature, Humidity, Ambilight und den RemoteSwitch.

Ich wollte mit PHP anfangen da mir das noch am meisten vertraut ist. Ich konnte die einzelnen Sensoren schon auslesen, einmal per direkter USB Verbindung und nun steckt der Stapel am Raspberry und ich kann per Browser von einem anderen Gerät einen Wert auslesen. Nun komme ich aber zu dem Problem das ich z.B. die Werte von allen 3 o.g. Sensoren mit einem Aufruf anzeigen will.

 

Zur Zeit habe ich also eine *.php Datei die den IPConnect macht und den Wert ausliest & anzeigt. Wenn ich das richtig verstehe bezieht sich der IPConnect also auf das spezifische Bricklet. Es wäre jetzt für mich logisch den IPConnect anstatt auf das Bricklet auf den Master zu legen, wenn der Connect steht spreche ich die Bricklet ID selber an und rufe den Wert ab. Ist das so korrekt ?

Gibt es dazu noch ein Beispiel ?

 

Dann kommen wir gleich zur nächsten Frage, Callbacks. Diese sind wenn ich das Prinzip verstanden habe dafür da die Werte - sofern sie sich ändern - dynamisch zu aktualisieren. Es wird der Overhead gespart wenn ich vom Gerät welches den Brickd hostet eine Anfrage an das Bricklet stelle, stattdessen ist das Bricklet im pull Mode und sendet die Daten an den Daemon. Damit könnte ich mir eine Tabelle erstellen welche für die einzelnen Zimmer die Werte ständig aktualisiert anzeigt.

 

Entschuldigt meine Fragen, evtl. wurden diese auch schon gestellt, aber ich brauch noch nen kleinen tritt in die richtige Richtung :)

 

 

Grüße Daniel

Link to comment
Share on other sites

Grundsätzlich muss ich bei den PHP-Bindings sagen, dass ich auf den EInsatz von Callbacks verzichten würde.

Das liegt daran, dass die PHP-Bindings Callbacks nur sonderbar unterstützen. Du musst eine blockierende Methode aufrufen, die die Callbacks bearbeitet, dafür passiert aber sosnt nix tolles...

 

Also mein Tipp: Bei PHP keine Callbacks

Den anderen Teil deiner Frage habe ich nicht so recht verstanden. Aber es reicht wenn du eine IPConnection für viele Bricklets nutzt.

Link to comment
Share on other sites

Ok also dann erstmal keine Callbacks in PHP.

 

@Equinox, das Auslesen der Bricklets über PHP funktioniert ja, ich möchte halt mit einem Aufruf mehrere Bricklets abfragen.

 

Zum Beispiel der Sample Code für das AmbientLight Bricklet:

 

<?php

require_once('Tinkerforge/IPConnection.php');
require_once('Tinkerforge/BrickletAmbientLight.php');

use Tinkerforge\IPConnection;
use Tinkerforge\BrickletAmbientLight;

const HOST = 'localhost';
const PORT = 4223;
const UID = '7tS'; // Change to your UID

$ipcon = new IPConnection(); // Create IP connection
$al = new BrickletAmbientLight(UID, $ipcon); // Create device object

$ipcon->connect(HOST, PORT); // Connect to brickd
// Don't use device before ipcon is connected

// Get current illuminance (unit is Lux/10)
$illuminance = $al->getIlluminance() / 10.0;

echo "Illuminance: $illuminance Lux\n";

echo "Press key to exit\n";
fgetc(fopen('php://stdin', 'r'));
$ipcon->disconnect();

?>

 

Dabei wird eine IPConnection aufgebaut, und das Bricklet mit der UID 7t2 abgefragt. Wenn ich jetzt 3 verschiedene Bricklets abfragen möchte die auf dem gleichen Master Brick hängen, kann ich das dann mit einer Abfrage auf den Master machen oder muss ich für jeden Wert ein eigenes Konstrukt bilden?

 

Mein gedanke wäre gewesen die Variable $ipcon einmal zu nutzen, und dann nur mehrere Device Objects zu erzeugen.

 

Für besseres Verständnis hier mal mein Code wie ich ihn erwartet hätte:

<?php

require_once('Tinkerforge/IPConnection.php');
require_once('Tinkerforge/BrickletAmbientLight.php');

use Tinkerforge\IPConnection;
use Tinkerforge\BrickletAmbientLight;

const HOST = 'localhost';
const PORT = 4223;
const alUID = '7tS'; // Change to your UID
const huUID = '8ef'; // UID für Humidity Bricklet

$ipcon = new IPConnection(); // Create IP connection
$al = new BrickletAmbientLight(alUID, $ipcon); // Create device object
$hu = new BrickletHumidity(huUID, $ipcon); // Device Object für Humidity

$ipcon->connect(HOST, PORT); // Connect to brickd
// Don't use device before ipcon is connected

// Get current illuminance (unit is Lux/10)
$illuminance = $al->getIlluminance() / 10.0;

// Lese Humidity aus
$humidity = $hu->getHumidity() / 10.0;

echo "Illuminance: $illuminance Lux\n";
echo "Humidity: $humidity %Rh\n";

echo "Press key to exit\n";
fgetc(fopen('php://stdin', 'r'));
$ipcon->disconnect();

?>

 

Ich hoffe ihr wisst was ich meine.

Link to comment
Share on other sites

Grundsätzlich muss ich bei den PHP-Bindings sagen, dass ich auf den EInsatz von Callbacks verzichten würde.

Das liegt daran, dass die PHP-Bindings Callbacks nur sonderbar unterstützen. Du musst eine blockierende Methode aufrufen, die die Callbacks bearbeitet, dafür passiert aber sosnt nix tolles...

 

Also mein Tipp: Bei PHP keine Callbacks

Den anderen Teil deiner Frage habe ich nicht so recht verstanden. Aber es reicht wenn du eine IPConnection für viele Bricklets nutzt.

 

Das würde ich jetzt nicht so negativ darstellen. Das Problem mit PHP und Callbacks ist, dass PHP (zumindest zum Zeitpunkt der Entwicklung der Bindings) keine Threads kannte. Daher muss das PHP Programm selbst für die Abarbeitung der Callbacks sorgen, indem es die dispatchCallbacks() Methode der IPConnection aufruft. Ob die Verwendung von Callbacks sinnvoll ist hängt natürlich auch davon ab was dein PHP Programm tut. Wenn es eine Webseite erstellt dann sind Callbacks nicht sehr sinnvoll und man fährt besser mit Gettern. Wenn ich aber auf ein Ereignis wie den Druck einen Knopfes am Dual Button Bricklet warten will dann sind Callbacks schon sinnvoll.

 

Dennoch ist die richtige Verwendung von dispatchCallbacks() nicht ganz leicht in größeren Programmen. Was dazu führt, dass man sein Programm am besten entweder vollständig auf Callbacks ausrichtet, oder sie gar nicht benutzt.

 

Mittlerweile kann PHP PThreads nutzen und man könnte Callbacks in PHP wie in den anderen Bindings auch durch einen extra Thread ausliefern lassen. Was jetzt aber bitte nicht als "Es gibt bald PHP Bindings mit Threads" verstanden werden soll :). Aber zumindest auf der TODO List steht es sich darüber noch mal Gedanken zu machen.

 

Mein gedanke wäre gewesen die Variable $ipcon einmal zu nutzen, und dann nur mehrere Device Objects zu erzeugen.

 

Für besseres Verständnis hier mal mein Code wie ich ihn erwartet hätte:

<?php

require_once('Tinkerforge/IPConnection.php');
require_once('Tinkerforge/BrickletAmbientLight.php');

use Tinkerforge\IPConnection;
use Tinkerforge\BrickletAmbientLight;

const HOST = 'localhost';
const PORT = 4223;
const alUID = '7tS'; // Change to your UID
const huUID = '8ef'; // UID für Humidity Bricklet

$ipcon = new IPConnection(); // Create IP connection
$al = new BrickletAmbientLight(alUID, $ipcon); // Create device object
$hu = new BrickletHumidity(huUID, $ipcon); // Device Object für Humidity

$ipcon->connect(HOST, PORT); // Connect to brickd
// Don't use device before ipcon is connected

// Get current illuminance (unit is Lux/10)
$illuminance = $al->getIlluminance() / 10.0;

// Lese Humidity aus
$humidity = $hu->getHumidity() / 10.0;

echo "Illuminance: $illuminance Lux\n";
echo "Humidity: $humidity %Rh\n";

echo "Press key to exit\n";
fgetc(fopen('php://stdin', 'r'));
$ipcon->disconnect();

?>

 

Ich hoffe ihr wisst was ich meine.

 

Genau so ist das gedacht. Hast du mit diesem Programm Probleme?

 

Die IPConnection stellt die Verbindung zu einem brickd her, über diese Verbindung kannst du dann alle Bricks und Bricklets erreichen die diesem brickd bekannt sind.

 

Wenn es sich um brickd auf deinem PC handelt, dann sind dass alle Stacks die per USB angeschlossen sind.

 

Wenn du die IPConnection zu einem Stack mit WIFI oder Ethernet Extension verbunden hast, dann kannst du alle Bricks und Bricklets diese Stacks darüber erreichen. Denn auf dem Stack mit WIFI oder Ethernet Extension läuft auch eine Art brickd, der sich um das Verteilen der Nachrichten kümmert.

 

Du brauchst also im Normalfall nur eine IPConnection und kannst diese dann für mehrere Devices verwenden.

Link to comment
Share on other sites

Hallo Daniel,

 

ich habe jetzt nicht genau verstanden was du meinst, allerdings sieht dein Code schon gut aus.

Du stellst einmal eine Verbindung her und kannst dann die einzelnen Bicklets abfragen.

Tinkerforge liefert auch ein Beispiel für die Ausgabe von Livedaten der Wetterstation mit mehreren Bricklets LINK.

 

Du kannst das Beispiel beliebig anpassen.

 

Vielleicht hilft dir das weiter.

 

Gruß,

Nemo

Link to comment
Share on other sites

Hallo,

 

ich bin kein PHP-Experte, aber ich denke, dass dein Code so funktionieren müsste. Hast du ihn ausprobiert? Hast du Probleme damit?

Du musst nur eine einzige IPConnection haben, die du dann in jedem Konstruktor für die Bricklets verwenden kannst, also so, wie du es im Code schon machst.

Link to comment
Share on other sites

$ipcon = new IPConnection(); // Create IP connection
$al = new BrickletAmbientLight(alUID, $ipcon); // Create device object
$hu = new BrickletHumidity(huUID, $ipcon); // Device Object für Humidity

$ipcon->connect(HOST, PORT); // Connect to brickd

 

Du verwendest die IPConnection schon bevor diese überhaupt hergestellt wird.

 

Tausch mal deine Zeilen so um

 

$ipcon = new IPConnection(); // Create IP connection
$ipcon->connect(HOST, PORT); // Connect to brickd

$al = new BrickletAmbientLight(alUID, $ipcon); // Create device object
$hu = new BrickletHumidity(huUID, $ipcon); // Device Object für Humidity

Link to comment
Share on other sites

Zum Thema Callbacks heißt es für PHP und beispielsweise den Temperature-Bricklet unter

http://www.tinkerforge.com/de/doc/Software/Bricklets/Temperature_Bricklet_PHP.html#callbacks

Callbacks für wiederkehrende Ereignisse zu verwenden ist immer zu bevorzugen gegenüber der Verwendung von Abfragen. Es wird weniger USB-Bandbreite benutzt und die Latenz ist erheblich geringer, da es keine Paketumlaufzeit gibt.

 

Die Beispiele für Callbacks in PHP sehen vernünftig aus, warum wird hier aber trotzdem davon abgeraten ? Wenn das mit Callbacks schlechter funktioniert als "teueres" Polling mit Getter-Funktionen, dann sollte ein Hinweis in die Doku rein "vom Benutzen der Callbacks in PHP ist abzuraten, weil... usw" oder bitte von den PHP Experten genauere Erklärungen, ansonsten wirkt das u.U. hier für Unsicherheiten.

 

Edit:

Das Problem mit PHP und Callbacks ist...

...Callbacks nicht sehr sinnvoll und man fährt besser mit Gettern.

Hab es jetzt erst gesehen, damit hat man erstmal eine Vorstellung. Ich würde es ev. als Randnotiz in die Doku aufnehmen, solange die PHP-Bind. noch nicht redesigned sind.

Link to comment
Share on other sites

$ipcon = new IPConnection(); // Create IP connection
$al = new BrickletAmbientLight(alUID, $ipcon); // Create device object
$hu = new BrickletHumidity(huUID, $ipcon); // Device Object für Humidity

$ipcon->connect(HOST, PORT); // Connect to brickd

 

Du verwendest die IPConnection schon bevor diese überhaupt hergestellt wird.

 

Tausch mal deine Zeilen so um

 

$ipcon = new IPConnection(); // Create IP connection
$ipcon->connect(HOST, PORT); // Connect to brickd

$al = new BrickletAmbientLight(alUID, $ipcon); // Create device object
$hu = new BrickletHumidity(huUID, $ipcon); // Device Object für Humidity

 

Nein, das ist nicht nötig. Es funktionier in beiden Weisen. Die IPConnection muss nicht verbunden sein um Device Objecte zu erzeugen.

 

 

Link to comment
Share on other sites

Zum Thema Callbacks heißt es für PHP und beispielsweise den Temperature-Bricklet unter

http://www.tinkerforge.com/de/doc/Software/Bricklets/Temperature_Bricklet_PHP.html#callbacks

Callbacks für wiederkehrende Ereignisse zu verwenden ist immer zu bevorzugen gegenüber der Verwendung von Abfragen. Es wird weniger USB-Bandbreite benutzt und die Latenz ist erheblich geringer, da es keine Paketumlaufzeit gibt.

 

Die Beispiele für Callbacks in PHP sehen vernünftig aus, warum wird hier aber trotzdem davon abgeraten ? Wenn das mit Callbacks schlechter funktioniert als "teueres" Polling mit Getter-Funktionen, dann sollte ein Hinweis in die Doku rein "vom Benutzen der Callbacks in PHP ist abzuraten, weil... usw" oder bitte von den PHP Experten genauere Erklärungen, ansonsten wirkt das u.U. hier für Unsicherheiten.

 

Ganz grundsätzlich: Callbacks funktionieren in PHP genauso gut oder schlecht wie in anderen Bindings. Es gibt hier kein Problem oder Nachteil mit Callbacks in PHP!

 

Der Punkt auf den AuronX abzielt und den ich versucht habe darzustellen ist ein anderer:

 

Ob die Verwendung von Callbacks sinnvoll ist hängt natürlich auch davon ab was dein PHP Programm tut. Wenn es eine Webseite erstellt dann sind Callbacks nicht sehr sinnvoll und man fährt besser mit Gettern. Wenn ich aber auf ein Ereignis wie den Druck einen Knopfes am Dual Button Bricklet warten will dann sind Callbacks schon sinnvoll.

 

Callbacks sind gut dafür Wertänderungen/Ereignisse mitzubekommen ohne ständig einen Getter dafür aufrufen zu müssen. Das ist vor allem in Programmen nützlich die länger laufen. Genau dies ist aber bei PHP in seiner ursprünglichen Verwendung zur Erzeugung von Websites nicht der Fall. Darauf zielte der Teil ab in dem ich Callbacks für PHP als Website-Generator als eher nicht nützlich erachte. Dies war und ist keine Aussage über Callbacks in PHP in Allgemeinen, sondern nur für diesen speziellen Fall.

 

Die Aussage, dass ich Callbacks für Website-erzeugende Programme nicht als nützlich erachte hängt nicht mit PHP zusammen sondern gilt auch für alle anderen Bindings.

 

Dennoch ist die richtige Verwendung von dispatchCallbacks() nicht ganz leicht in größeren Programmen. Was dazu führt, dass man sein Programm am besten entweder vollständig auf Callbacks ausrichtet, oder sie gar nicht benutzt.

 

Das eigentliche Problem mit Callbacks in PHP ist, dass ich mich als Nutzer der Bindings darum kümmern muss sie zu erhalten. Bei anderen Bindings passiert das automatisch, was Vorteile und auch Nachteile hat.

 

Wenn ich in PHP Callbacks verwenden will muss ich irgendwo in meinem Programm an geeigneter Stelle und zu geeigneter Zeit dispatchCallbacks() aufrufen. Am einfachsten ist dass, wenn man es so macht wie alle PHP Beispiele die Callbacks verwenden. Sie konfigurieren als erstes alles was sie brauchen und rufen dann dispatchCallbacks(-1) auf. Mit -1 aufgerufen bedeutet das: "kümmer dich für immer um eingehende Callbacks und returne niemals".

 

Dieses Muster funktioniert gut, ich muss aber mein Programm darauf hin ausrichten, dass es für immer in dispatchCallbacks(-1) stehen wird und ich dann in den Callbacks arbeiten muss.

 

Wenn ich mein Programm nicht darauf ausrichten kann, aber dennoch Callbacks verwende will, dann muss ich mir Gedanken machen darüber wann und wie ich dispatchCallbacks() aufrufe, um es mit meinem restlichen Programm zu kombinieren. Das kann im Einzelfall kompliziert werden.

 

Daher meine Aussage darüber, dass man sein PHP Programm entweder auf die Verwendung von Callbacks ausrichten sollte, oder wenn das nicht möglich ist, besser keine Callbacks verwenden sollte. Das ist als guter Rat bzw. Best-Practice-Hinweis zu sehen. Ich rate damit niemanden von Callbacks im generellen ab, ich weise aber darauf hin, dass die Verwendung von Callbacks in PHP schwieriger sein kann (aber nicht muss) als mit anderen Bindings.

Link to comment
Share on other sites

Vielen Dank für die Hilfe !

 

Ich habs jetzt hinbekommen, habe das Beispiel der Wetterstation genommen, weis auch nicht warum ich das nicht selber gefunden habe.

 

Die Callbacks lasse ich trotzdem erstmal weg da ich auf meiner Website viel interaktion habe mit Vor/Zurück, da werden die Daten sowieso neu geladen.

 

Ich kann mir nun die Brickletwerte anzeigen lassen und auch das Licht ein und ausschalten, wenn man das Prinzip erstmal verstanden hat ist es doch viel einfacher als erwartet.

Link to comment
Share on other sites

Der Punkt auf den AuronX abzielt und den ich versucht habe darzustellen ist ein anderer

 

Tut mir leid, das hätte ich in meinem Originalpost klarer kenntlich machen sollen.

 

Ich bezog mich tatsächlich lediglich auf den Einsatz im Rahmen von PHP-Webseiten

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...