Wemos D1 Mini, Paho MQTT, Datenbank, Daten in Variable

  • Hallo Zusammen,


    ich versuche momentan auf relativ einfachem Weg, die Daten von einem Wemos D1 Mini in Variablen zu speichern, damit ich mit diesen Daten später einfach weiter arbeiten kann.

    Das bereitet mir aber momentan Kopfzerbrechen, da ich in Python leider nicht so fit bin.


    Ich hole mir folgende Daten vom ESP8266:

    - Temperatur

    - Feuchtigkeit

    - Akkuspannung


    Momentan übertage ich nur die Daten von einem ESP auf einen Pi per MQTT.

    Wenn das ganze so funktioniert, wie ich mir das vorstelle, sollen noch mehrere ESP's folgen.


    Hier der Code der auf dem Pi läuft:

    Die Ausgabe sieht wie folgt aus:

    Code
    ESP_Easy/Bad_Akku/Spannung
    3.88
    ESP_Easy/Bad/Temperature
    22.79
    ESP_Easy/Bad/Humidity
    43.9

    Ich habe jetzt schon verschiedene Sachen probiert:

    So funktioniert es aber leider auch nicht, da nach dem ersten If sofort die Schleife verlassen wird.

    Auch mit elif funktioniert es nicht.


    So funktioniert es leider auch nicht:

    Ich bin auf der Suche nach einem einfachen und für einen Anfänger verständlichen Weg, damit ich jeden Wert in einer eigenen Variable habe, damit ich später diese zum Befüllen einer Datenbank verwenden kann.


    Danke für die Hilfe.

  • Wieso später? Steck den doch in dem

    Moment in die Datenbank. Oder noch besser: benutz telegraf und InfluxDB, und nimm gar kein Python dazu, das speichern in der Datenbank zu erledigen.

  • Ich habe vor das ganze in eine InfluxDB zu stecken.

    Allerdings würde ich schon gerne Python dafür verwenden, da ich einen Akku an dem Wemos habe und ich mir bei niedriger Akkuspannung über einen Telegram Bot die Meldung schicken lassen würde. Daher das ganze per Python.

    Wenn jetzt die Werte alle in einer eigenen Variable stehen würde, dann kann ich die Werte direkt in Influx importieren und zugleich noch eine Abfrage machen ob die Akkuspannung niedrig ist.

  • Das ändert doch nichts. Du kannst die Spannung genauso aus der InfluxDB abfragen. Es gibt bei den Dashboards zur Darstellung zb dann auch Trigger die man definieren kann.

  • Mit den Triggern habe ich bisher noch nicht gearbeitet, habe aber gesehen, dass es sowas gibt.

    Das selbe ist auch mit Telegraf. Ich habe mir es jetzt mal kurz durchgelesen, aber auch noch nicht wirklich verwendet.


    Ich denke mal, dass ich die Werte auch mit Python raus bekommen kann?

    Das Skript wie ich es in die InfluxDB bekomme, habe ich schon vorhanden. Da ich auch noch andere Sachen in Influx importiere.

    Daher wollte ich den Weg über Python einschlagen, da ich dies dann vermutlich auch besser verstehe.

  • Ich denke nicht, das du das besser verstehst. Das Problem ist nicht so einfach wie du denkst, und gleichzeitig soll es das aber sein, weil ja Anfänger 🤷‍♂️


    Ein paar Probleme, die du lösen musst: hast du einen kompletten Datensatz beisammen? Wenn nicht, was dann? Wenn du bei unter Spannung triggerst, machst du das dann jedes Mal, oder nur einmal, und wie merkst du dir, dass du das gemacht hast, auch über den Neustart des PI hinweg?


    Das ist alles schon gelöst für dich in den bestehenden Tools.

  • hast du einen kompletten Datensatz beisammen?

    Was meinst du damit genau?

    Ich bekomme, wie oben beschrieben, die Daten vom ESP8266 per MQTT geschickt. Auch die Topics und die Werte sind aufgeführt.


    Wenn du bei unter Spannung triggerst, machst du das dann jedes Mal, oder nur einmal, und wie merkst du dir, dass du das gemacht hast, auch über den Neustart des PI hinweg?

    Da das Skript immer läuft, kann ich mir einen Zähler dazu bauen, dann werde ich nicht jedes mal Benachrichtigt. Außerdem schaue ich täglich in Grafana und sehe normal sofort wenn die Spannung abfällt. Wir reden hier von ganz langsamen Spannungsabfall und nicht rapide.

    Zum Neustart: Ich weiß was ich jetzt schreibe, ist nicht sonderlich schön, aber ich komme absolut gut zurecht damit.

    Ich habe mir eine Readme Datei gemacht, wann welches Skript wie startet. Auch dort habe ich aufgeführt, welche Skript's ich manuell starten muss.

    Das funktioniert -für mich- gut, da ich genau weiß das ich immer in diese Datei schauen muss. So läuft das jetzt mit anderen Skript's wunderbar.


    Das ist alles schon gelöst für dich in den bestehenden Tools.

    Das glaub ich gerne. Nur habe ich davon noch weniger Ahnung.


    Ich weiß es besteht die Möglichkeit sich da einzuarbeiten. Diese Zeit fehlt mir momentan. Da ich es auch mit anderen Sachen, zb. mit meiner Heizung schon so mache, die Werte abfragen, in eine Variable speichern und dann über Python das ganze an Influx zu übergeben und es für mich auch funktioniert, wollte ich diesen Weg einfach wieder einschlagen.

  • Wenn du auf der einen Seite Leute um ihrer Erfahrung Willen um Hilfe bittest, aber dann gleichzeitig jeden Rat in den Wind schlägst, ist das schon spannend.


    Aber wenn’s denn so muss: ich hab’s schon gesagt, und ich sage es nochmal: in dem on_connect kannst du sofort deine gesamte Verarbeitung machen. Auf Unterspannung prüfen und eine Nachricht schicken, genauso wie die Werte direkt in eine Datenbank ablegen. Und genau das würde ich auch machen, wenn ich nicht Telegraf benutzen würde. Weder gibt es einen Grund, noch ist es irgendwie einfacher, da Variablen anzulegen. Das loop_forever Blockiert notwendigerweise, und damit hast du nun mal nur den on_connect-Aufruf. Doch der passt ja auch, denn nur dann, wenn Werte kommen, kann und muss was passieren.

  • Ich denke, dass wir hier ein bisschen aneinander vorbei geredet haben.

    Wenn das geht, dass ich in dem on_connect, alles in die Datenbank eintragen kann, dann will ich das natürlich auch gerne so machen.

    Mir ist nur nicht klar, wie ich das machen kann, daher habe ich nach den Variablen gefragt.


    Ich will es ganz einfach haben.

    In dem on_connect die Werte und direkt in die Datenbank.


    Die Frage ist nur, wie mache ich das, dass die Werte auch immer in der richten Spalten in der Datenbank sind, da ja 3 Werte ankommen. Spannung, Temperatur und Feuchtigkeit.

  • Die Werte landen einfach immer in der gleichen Spalte und es gibt eine Spalte die das Topic speichert.

    “The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in; we're computer professionals. We cause accidents.” — Nathaniel Borenstein

  • Das diese einfach immer in der selben Spalten laden verstehe ich nicht.


    Hier mal ein Auszug aus einem anderen Skript, wie ich in Influx was importiere:


    Ich muss diesem Skript ja mitgeben, welche Werte ich speichern will.


    Daher war meine Frage, wie ich die einzelnen Werte aus dem MQTT bekomme.


    Code: on_connect und on_message
    def on_connect(client, userdata, flags, rc):
        print("Connected with result code " + str(rc))
        client.subscribe("ESP_Easy/#")
    def on_message(client, userdata, msg):
        print(msg.topic)
        print(float(msg.payload.decode()))
    Code: Ausgabe von on_message
    ESP_Easy/Bad_Akku/Spannung
    3.88
    ESP_Easy/Bad/Temperature
    22.79
    ESP_Easy/Bad/Humidity
    43.9

    Es kommen alle Werte vom gesamten Topic.

    Wie kann ich jetzt hier die einzelnen Werte übergeben?


    Oder denke ich gerade komplett falsch?

  • Du musst unterschiedliche topics Vergeben, und das topic wird Schlüssel in dem Dictionary das du übergibst.

  • Ich sehe gerade, die Topics hast du ja. Du musst die also nur nutzen als Schlüssel. Und pro Ereignis eben einen Eintrag in die DB machen.

  • Ich prüfe so etwas immer gerne mit einem "print" bevor ich es übergebe.


    Wie kann ich mit dem allgemeinen Topic "#" ein spezielles Ausgeben lassen?


    Ich bin leider momentan nicht vor dem Pi, aber würde das mit print(msg.topic['Temperature'])funktionieren?

    Oder geht das irgendwie anders?


    print(msg.topic) bringt mir ja alle Werte die darunter liegen.

  • Das Topic ist wie es ist, einfach nur ein String. Keine „Werte darunter“. Damit kannst du umgehen wie mit jedem anderen String. Eine wie von dir gezeigte Operation mit einem String als Index geht nicht.

  • Ich sehe gerade, die Topics hast du ja. Du musst die also nur nutzen als Schlüssel.

    Kannst du mir hier genau helfen, wie ich das mache?


    Da du ja sagtest, dass mein Vorgehen nicht funktioniert, weiß ich ehrlich gesagt nicht wie ich dann an die Topics in Verbindung mit mit dem Werten alles richtig in die DB bringe?


    Die Eintragung in die InfluxDB erwartet ja irgenwie eine Übergabe, damit die Werte eingetragen werden können.


    Wie hier zb:

    Code
    "fields": {
        "Netzwerkschrank_Temp": netzwerkschranktemp
        }

    Nur wie komme ich an die Daten?


    Ich sag mal zwischendurch "Danke" für die Hilfe. Ich bin da echt nicht fit.... sorry

  • Das ist doch genau das gleiche. Du hast einen Wert, netzwerkschrank. Und ein topic, "Netzwerkschrank_Temp"


    Und genau so kannst du mit dem jetzigen topic und wert weiter verfahren.


    Code
    "fields": {
        topic: value
        }
  • Nein, das ist falsch. Rechts kann nur der Wert stehen. Links steht das topic. Mit allen seinen Komponenten. Du hast das als Variable vorliegen.

  • Hallo Wuza,


    hier ein Beispiel meiner Markisensteuerung

    Wenn man nun Testdaten füttert kommt folgendes

    Code
    mosquitto_pub -h 192.168.2.160 -t test/markise/set -m "raus"
    ------
    root@server2:/opt/homeauto# ./test.py 
    Connected with result code 0
    test/markise/set RAUS
    Raus

    Warum wird nicht "Alles Fehlerfrei" ausgegeben.

    Quote

    So funktioniert es aber leider auch nicht, da nach dem ersten If sofort die Schleife verlassen wird.

    Auch mit elif funktioniert es nicht.


    Das liegt daran, dass Fehler im Code in dieser Funktion ignoriert werden - siehe oben. Paho kapselt diese Funktion on_message in try except.

    Um Fehler zu bekommen muss man das Error Logging von Paho einschalten:

    Als Ausgabe kommt jetzt:


    Code
    DEBUG:__main__:Sending CONNECT (u0, p0, wr0, wq0, wf0, c1, k60) client_id=b''
    DEBUG:__main__:Received CONNACK (0, 0)
    Connected with result code 0
    DEBUG:__main__:Sending SUBSCRIBE (d0, m1) [(b'test/markise/set', 0)]
    DEBUG:__main__:Received SUBACK
    DEBUG:__main__:Received PUBLISH (d0, q0, r0, m0), 'test/markise/set', ...  (4 bytes)
    test/markise/set RAUS
    Raus
    ERROR:__main__:Caught exception in on_message: can only concatenate str (not "int") to str