Jump to content

[PHP] Bricklet-ID ermitteln


Recommended Posts

Eine ganz blöde Frage, ich weiss..

Also, ich habe einen Master mit LCD-Bricklet dran.

Wenn ich die Bricklet-ID in meinem Code angebe kann ich auch ganz einwandfrei meine Ausgaben machen.

Was ist aber wenn ich die ID nicht kenne? Wie frage ich in PHP die ID eines angeschlossenen Bricklets ab?

Ich würde das gerne so machen, dass ich eine Kleine Schleife in meinem Ini-Prozess machen, die mir die ID ermittelt und ich die dann im Folgecode verwenden kann.

Ich habe im Code zur Wetterstation zwar die Enumerate()-Funktion gefunden, aber ich kann das Ganze irgendwie nicht anwenden, will heissen, ich kriege es einfach nicht auf die Kette ... User zu blöd Error

Link zu diesem Kommentar
Share on other sites

Hmmm... mir fällt es ggerade schwer zu antworten, vielleicht kannst du näher ausführen was du am enumerate nicht verstanden hast. Das wäre nämlich mein Tipp gewesen: "Schau dir mal die enumerate-funktion an"...

 

Ich versuch mal zu erklären, wie das gedacht ist:

Wenn du enumerate aufrufst sagst du dem Stack damit, dass er dir alle Geräte auflisten soll. Dazu musst du vorher einen Callback definiert haben der dann für jedes Gerät aufgerufen wird. Das passiert parallel (ich glaube auch bei PHP(?)), das heißt dein restliches Programm ab "enumerate()" würde einfach weiterlaufen. Du kannst jetzt eines von zwei Dingen tun:

1. Im Callback nur die Geräte in eine globale Liste schreiben. Dort wo du enumerate gerufen hast wartest du einfach 3 Sekunden und machst erst danach weiter. Das erfordert kaum Anpassung, jetzt aber langsam (immer 3 Sekunden warten)

 

2. Einfach nichts weiter nach "enumerate()" tun und alles was du dort tun würdest direkt im Callback ausführen. Das erfordert aber etwas mehr Anpassung und du musst auch aufpassen, dass du im Callback nichts tust was lange dauert.

 

Ich hoffe ich habe jetzt erstmal nichts (für PHP) falsches erzählt und vielleicht konnte ich schon etwas Klarheit schaffen. Ansonsten habe ich vielleicht zumindest noch mehr Verwirrung stiften können :D

 

Falls du konkretere Fragen hast kann ich auch versuchen noch konkreter zu antworten :D

 

Viele Grüße

Link zu diesem Kommentar
Share on other sites

Hi AuronX,

 

Ich packe einfach mal ein kurzes Stück Code hier hin ....

        $ipcon = new IPConnection(); // Verbindung aufbauen
        
        // --------
        try {
                $ipcon->enumerate(); // Devices auflisten
                }
        catch ( Exception $e ) {
                sleep(10);
                goto connect;
                }
                
          $did = BrickletLCD20x4::DEVICE_IDENTIFIER ;          
          echo $did;
        // --------

 

Danach weiß ich immerhin, dass ich ein Gerät mit der ID 212 angeschlossen habe.

Nur brauche ich irgendwie den Weg zur uid.

 

Mein Gerätchen besteht aus einem RasPi, einem Master und einem 20x4 LCD.

Das Ganze fragt meinen Solaranlagen-Logger (ein SolarLog) zyklisch ab und schreibt die aktuellen Verbrauchs- und Ertragswerte aufs Display

So sieht man bei meiner Eigenverbrauchsanlage auf einen Blick wann es sich lohnt den Geschirrspüler oder die Waschmaschine einzuschalten.

Ich will eigentlich dahin, dass jeder sich das Dingelchen nachbauen kann, mein Image auf die SD packt und sich der Nachbau das LCD selbst initialisiert und dann seine Werte aufs Display schreibt.

Die ersten 2 Minuten lang schreibt der Raspi seine Ip aufs Display (das ist der link zur Config-Website), danach wechselt das Display auf die Details.

Das rennt soweit alles gut, nur das einmalige automatische Ermitteln der Display-UID kriege ich nicht hin. Das muss ja eigentlich nur beim allerersten Einschalten laufen und die ID ins Configfile schreiben, oder vielleicht später mal, wenn das Display ersetzt werden muss.

 

Ansonsten bin ich auch an der Konfigurationswebsite, wo man die IP des Loggers eingibt und ob es einen Verbrauchszähler gibt. Wenn ja, kann ich ein Delta ermitteln und auch aufs Display schreiben ob ich einspeise, beziehe und wieviel.

 

So'n Logger hängt ja gewöhnlich im Keller und da sieht man ein ggfls. vorhandenes Display ja nicht. Meine Bastelei steht irgendwo in der Wohnung rum und man sieht im Vorbeigehen was die Photovoltaik sagt, ohne erst Tablet oder PC anwerfen zu müssen.

 

Nur so zum Hintergrund, auch wenn das nichts mit der Programmierung zu tun hat ;)

Link zu diesem Kommentar
Share on other sites

Hallo, ich beziehe mich mal auf den Code und deine Aussagen dazu:

 

Danach weiß ich immerhin, dass ich ein Gerät mit der ID 212 angeschlossen habe.

 

Tatsächlich weißt du das nichtmal... was du hier abfragst (BrickletLCD20x4::DEVICE_IDENTIFIER) ist nur eine Konstante die die ID eines jeden LCD-bricklets enthält (siehe auch http://www.tinkerforge.com/de/doc/Software/Device_Identifier.html#device-identifier). In der Tat hast du einfach nur die Bindings danach gefragt welche Id denn ein LCD20x4 haben sollte, denn das ist es was sich hinter dieser Konstanten verbirgt.

 

Aus deinem Code geht nciht hervor, dass du tatsächlich den Enumerate-Callback verarbeitest. Das bedeutet konkret, dass alles was bei dir im try-catch steht quasi derzeit keine Funktion hat.

Was du eigentlich tun möchtest ist einen Callback für enumerate zu registrieren und dann diese Funktion zu rufen. In diesem Callback würdest du dann vergleichen ob das aktuelle Gerät gerade ein LCD20x4 ist, etwa so:

function cb_enumerate($uid, $connectedUid, $position,
                      $hardwareVersion, $firmwareVersion,
                      $deviceIdentifier, $enumerationType)
{
    if($enumerationType != IPConnection::ENUMERATION_TYPE_DISCONNECTED) {
        if($deviceIdentifier == BrickletLCD20x4::DEVICE_IDENTIFIER) {
            echo "I found an LCD20x4 with the UID " + $uid;
            return;
        }
    }
}

(Vorsicht: Ungetesteter Code und ich habe schon ewig kein PHP mehr programmiert... vielleicht verkettet man Strings ganz anders... aber das Prinzip sollte deutlich sein)

 

Obiger Code wäre jetzt ein Callback der dann wenn ein LCD entdeckt wird (das nicht gerade abgezogen wurde) dessen UID ausgibt.

 

Dazu müsstest du aber vor dem Aufruf von $ipcon->enumerate() noch folgendes einfügen:

 

$ipcon->registerCallback(IPConnection::CALLBACK_ENUMERATE, 'cb_enumerate');

 

Ah... und jetzt habe ich gerade noch den Pferdefuß bei PHP entdeckt! Nachdem du $ipcon->enumerate() gerufen hast solltest du als nächstes folgendes tun:

$ipcon->dispatchCallbacks(2.5);

 

Das bewirkt, dass für die kommenden 2.5 Sekunden (der standard-timeout aller TF-Anfragen) Callbacks verarbeitet werden. Das heißt während diese Methode läuft wird der oben genannte Callback aufgerufen und du kannst im folgenden Code Dinge tun und dir sicher sein, dass der Callback durchlief.

 

Ich versuche mich jetzt nochmal daran deinen Code in etwa so zu vervollständigen, dass er das tut was du möchtest (wie du bereits merkst, ich lese mich auch erst während des Schreibens in die Thematik ein :D):

$ipcon = new IPConnection(); // Verbindung aufbauen

// -------------

$globalUID = ""; //ich hoffe man kann in PHP einfach so globale variablen nutzen...

function cb_enumerate($uid, $connectedUid, $position,
                      $hardwareVersion, $firmwareVersion,
                      $deviceIdentifier, $enumerationType)
{
    if($enumerationType != IPConnection::ENUMERATION_TYPE_DISCONNECTED) {
        if($deviceIdentifier == BrickletLCD20x4::DEVICE_IDENTIFIER) {
            echo "I found an LCD20x4 with the UID " + $uid;
    $globalUID = $uid;
            return;
        }
    }
}

$ipcon->registerCallback(IPConnection::CALLBACK_ENUMERATE, 'cb_enumerate'); //hier sorgst du dafür, dass die enumerate-antworten auch in deiner funktion landen

try
{
$ipcon->enumerate(); // Devices auflisten
$ipcon->dispatchCallbacks(2.5); // hier wird dein callback aufgerufen...
}
catch ( Exception $e )
{
sleep(10);
goto connect;
}

//wenn ein LCD da war, dann kannst du ab hier die uid aus $globalUID auslesen... etwa so:
echo "Ich benutze ab sofort folgendes LCD: " + $globalUID;

 

Ich hoffe mein Beispielcode passt ungefähr, zumindest so, dass du das Grundprinzip verstehen konntest.

 

Viel Spaß

Jan

Link zu diesem Kommentar
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.

Gast
Reply to this topic...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...