Jump to content

Robuster Ansatz - Verständnisfrage


DoIT
 Share

Recommended Posts

Hallo,

ich habe mal eine Verständnisfrage, vielleicht stehe ich auch nur auf dem Schlauch 😅

Im Beispiel von hier: https://www.tinkerforge.com/en/doc/Tutorials/Tutorial_Rugged/Tutorial.html wird das LCD immer nur über einen Callback aufgerufen welcher z.B. von einem Sensor oder Taster ausgelöst wurde. Und dann wird geprüft ob das Objekt für das LCD nicht None ist. Also es wurde schomal etwas zugewiesen. Was ist aber wenn das LCD schon mal angesteckt war aktuell aber nicht. Also das Objekt einen Wert hat. Hier würde es doch zu einem Laufzeitfehler kommen oder?

Gleiches Thema. Wie verhält sich das ganze wenn ich Ausgänge Schalten möchte die zwar schonmal angesteckt waren jedoch (Das Objeckt somit einen Wert hat) aktuell nicht mehr verbunden sind?

Wie sollte man dies am besten lösen?

Gibt es eine Prüfung ob das Objekt noch angeschloßen ist und reagiert? So eine Art Ping?

Eine weiter Frage wäre noch. Ich möchte außerhalb dieser Klasse die Objekte z.B. das LCD ansprechen. Wie kann ich nun sicherstellen das die Nachricht am LCD angekommen ist bzw. es zu keinem Laufzeitfehler kommt ohne jedesmal den Aufruf des Objektes in einen try catch anweisung zu packen. Denn es kann ja sein das das Display zum Beispiel noch gar nicht verbunden war. Bzw. aktuell nicht verbunden ist.

Ich hoffe mich verständlich ausgedrückt zu haben. 😀

Ich würde mich über Vorschläge oder Beispiele freuen. Danke für eure Hilfe.

 

Grüße

Link to comment
Share on other sites

Moin,

Eins vorweg: Alle Aussagen hier gelten nur, wenn du ganze Stacks ansteckst/abziehst. Hot-Plug einzelner Bricks/Bricklets an einen laufenden Stapel wird nicht unterstützt.

On 4/21/2020 at 10:01 AM, DoIT said:

Was ist aber wenn das LCD schon mal angesteckt war aktuell aber nicht. Also das Objekt einen Wert hat. Hier würde es doch zu einem Laufzeitfehler kommen oder?

Gleiches Thema. Wie verhält sich das ganze wenn ich Ausgänge Schalten möchte die zwar schonmal angesteckt waren jedoch (Das Objeckt somit einen Wert hat) aktuell nicht mehr verbunden sind?

Da gibt es mindestens die folgenden zwei Möglichkeiten:

Du kannst, wenn dein Stapel per USB angeschlossen ist, im enumerate-Callback den ENUMERATION_TYPE_DISCONNECTED verwenden: Wenn du das USB-Kabel ziehst, bekommst du das Callback für jedes Gerät im Stapel, das angeschlossen war und mindestens einmal eine Nachricht geschickt hat. Da kannst du dann das entsprechende Objekt auf None setzen. Achtung: Da sind nur der enumeration_type und die UID sinnvolle Werte, du musst dir bei den _CONNECTED und _AVAILABLE-Enumerations die UIDs speichern und in den _DISCONNECTED-Enumerations dann nachschlagen.

Alternativ kannst du bei jedem Aufruf warten, ob ein Timeout kommt (Bei Settern wie backlight_on() musst du response-expected aktivieren, sonst bekommst du das nicht mit). Da bietet es sich an eine Wrapper-Funktion zu schreiben wie z.B. (Achtung, ungetesteter Code):

from tinkerforge.ip_connection import Error

def wrapper(device, fn):
    try:
        fn()
    except Error as e:
        if e.value == Error.TIMEOUT:
            device = None

# Verwendung
wrapper(self.lcd, self.lcd.backlight_off)

# oder wenn der Aufruf Parameter hat
wrapper(self.lcd, lambda: self.lcd.write_line(0, 0, s))

Die Fehlerbehandlung kann dann natürlich beliebig komplex sein, je nachdem was du brauchst.

On 4/21/2020 at 10:01 AM, DoIT said:

Gibt es eine Prüfung ob das Objekt noch angeschloßen ist und reagiert? So eine Art Ping?

Du kannst prinzipiell prüfen, ob ein Brick/Bricklet noch da ist, indem du irgendeine Funktion davon aufrufst (Es bietet sich get_identity an, das wird von allen Bricks/Bricklets unterstützt und hat keine Nebeneffekte)

On 4/21/2020 at 10:01 AM, DoIT said:

Eine weiter Frage wäre noch. Ich möchte außerhalb dieser Klasse die Objekte z.B. das LCD ansprechen. Wie kann ich nun sicherstellen das die Nachricht am LCD angekommen ist bzw. es zu keinem Laufzeitfehler kommt ohne jedesmal den Aufruf des Objektes in einen try catch anweisung zu packen. Denn es kann ja sein das das Display zum Beispiel noch gar nicht verbunden war. Bzw. aktuell nicht verbunden ist.

Das kommt auch ganz darauf an, was du brauchst. Eine relativ einfache Variante ist es, wenn du alles was du mit dem LCD machst in zwei Gruppen aufteilst: 1. Konfiguration, die nur einmal passiert, dann aber funktionieren muss. (Das kannst du dann aus dem enumerate-Callback heraus ausführen und self.lcd nur zuweisen, wenn alles fehlerlos durchgelaufen ist) 2. Ausgaben/Anzeigen die du dauerhaft aktualisieren willst, bei denen es aber nicht kritisch ist, wenn eine Aktualisierung verloren geht, weil die nächste das ganze wieder repariert. (z.B. die Temperaturanzeige wie im Beispielcode). Bei denen kannst du mit der Fehlerbehandlung dann lax sein (z.B. ein try...except um alles nur damit das Programm nicht beendet wird)

Wenn du periodische Aufgaben hast, die definitiv durchgeführt werden müssen, musst du dir etwas komplexeres bauen, zum Beispiel eine Warteschlange von Tasks, die nacheinander abgearbeitet und bei Fehlern wiederholt werden. So eine Warteschlange kannst du dann auch von außerhalb befüllen.

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...