Rossmann-Waagen-Hack Teil 3

Wie bereits in der Make 4/24 angekündigt, kommt hier der Online-Artikel zum Thema personalisierte Datenspeicherung und Anzeige.

vorlesen Druckansicht 1 Kommentar lesen
Lesezeit: 12 Min.
Von
  • Heinz Behling
Inhaltsverzeichnis

Sie sind also immer noch an meinem "Project in work" interessiert? Das freut mich. Ich habe selbst viel dabei gelernt, teils durch Nachschlagen, teils aber auch durch Versuch und Irrtum. Wundern Sie sich also nicht, wenn ich das ein oder andere bereits erledigte doch noch ändern muss. Sie können, so meine Hoffnung, einigen Nutzen daraus ziehen, sei es über MQTT, Sensoren und ESPHome, sei es aber auch die Erkenntnis, dass man sich durch kleine Rückschläge bei der Entwicklung eines Projekts nicht entmutigen lassen muss.

Doch nun genug des epischen Vorspiels: Steigen wir wieder ein beim Umbau unserer Rossmann-Waage. Die kann ja bereits benutzerspezifisch Gewichte ermitteln und per MQTT an den Broker auf dem Home-Assistant-Server übermitteln. Diese Übermittlung muss aber noch etwas angepasst werden, damit die Home-Assistant-Datenbank besser damit zurechtkommt.

Bislang ermittelt die Waage die Gewichte von Claudia und Klaus (die sie per RFID-Chip erkennt, siehe Artikel in Make 4/24) und sendet Namen und Gewicht in einem JSON-Objekt verpackt unter dem Topic /RDM6300 an den Broker. In diesem Online-Kurs werden wir aus diesen Daten für jeden Waagenbenutzer einen Sensor in Home Assistant (HA) anlegen. Vorteil solch eines HA-Sensors: Seine Daten werden dauerhaft in der HA-Datenbank gespeichert. Damit kann man dann recht einfach den Verlauf der Daten als Grafik anzeigen, ohne sich, wie ich es zunächst vorhatte, mit einer eigenen Datenbank und dem Tool Grafana befassen zu müssen. Im Folgenden erkläre ich Ihnen die Änderungen an der Waagen-Firmware. Der Quellcode steht aber auch auf GitHub zum Download bereit.

Nun zurück zur geplanten grafischen Darstellung. Das funktioniert einfacher, wenn man die Gewichtsdaten allein in JSON verpackt und den Namen stattdessen im Topic unterbringt. So erhalten wir in unserem Beispiel zwei Topics.

  • /RDM6300/Claudia
  • /RDM6300/Klaus

In der ESPHome-Firmware der Waage sind daher im Abschnitt binary_sensor: die jeweiligen Abschnitte für die Waagenbenutzer zu ändern.

  - platform: rdm6300
    uid: 12113815
    name: "Klaus"
    id: Klaus
    on_press:
      then:
        - globals.set:
            id: person_aktuell
            value: '"Klaus"'
        - mqtt.publish_json:
            topic: /rdm6300/Klaus
            payload: |-
              root["Gewicht"] = id(hx711_value).state;  
        - switch.toggle: rdm6300power
        - display.page.show: page3
        - component.update: my_display  

Der Abschnitt für Claudia wird entsprechend bearbeitet. Achten Sie dabei unbedingt auf die Einrückungen am Beginn der Zeilen sowie die Leerzeichen hinter den Bindestrichen. Fehler dort führen dazu, dass sich die Firmware später nicht kompilieren lässt, sondern teils kryptische Fehlermeldungen erzeugt werden.

Ist Ihnen die Zeile - display.page.show: page3 aufgefallen? Sie schaltet das Display der Waage (Einbau in Make 7/23) auf eine neue Anzeigeseite um. Insgesamt soll es künftig drei Display-Seiten geben, und zwar aus gutem Grund. Einigen Leser ist aufgefallen, dass manchmal keine Daten von der Waage zu Home Assistant übertragen werden. Auch bei meinen Versuchen trat das ab und zu auf. Ursache: Die Waage muss sich nach dem Einschalten zunächst mit dem WLAN verbinden. Das dauert ein paar Sekunden. Leider erhielt man bislang aber keine Info darüber, ob die Verbindung bereits besteht. Hält man den RFID-Chip zu früh vor die Antennenspule, kann die Waage die ermittelten Daten aber nicht loswerden.

Das Waagen-Display soll daher künftig Folgendes anzeigen:

  • Warte aufs Netz (unmittelbar nach dem Einschalten)
  • Fremder wiegt XX.X kg, zusammen mit der Aufforderung, den RFID-Chip vor die Antenne zu halten (erscheint, sobald die WLAN-Verbindung aufgebaut ist)
  • Klaus oder Claudia wiegt XX,X Kg... (erscheint, wenn der RFID-Chip benutzt, der User erkannt und die Daten übertragen wurden

Diese drei Seiten werden in der Firmware im Abschnitt display eingerichtet:

display:
- platform: ili9xxx
  id: my_display
  #model: TFT 2.4
  model: ili9341
  rotation: 270
  cs_pin: GPIO14 # (Pin on display - CS)
  dc_pin: GPIO26 # (Pin on display - DC)
  reset_pin: GPIO27 # (Pin on display - RESET)


  pages:
    - id: page1
      lambda: |-
        it.fill(Color::BLACK);
        it.printf(0,0, id(my_font2), id(my_red), TextAlign::TOP_LEFT, "Warte");
        it.printf(0,90, id(my_font), id(my_cyan), TextAlign::TOP_LEFT, "aufs");
        it.printf(0,120, id(my_font2), id(my_red), TextAlign::TOP_LEFT, "Netz");
    - id: page2  
      lambda: |-
        it.fill(Color::BLACK);
        it.printf(0,0, id(my_font), id(my_red), TextAlign::TOP_LEFT, id(person_aktuell).c_str());
        it.printf(200,0, id(my_font), id(my_cyan), TextAlign::TOP_LEFT, " wiegt");
        it.printf(0,40, id(my_font2), "%4.1f", id(hx711_value).state);
        it.printf(200,60, id(my_font), TextAlign::TOP_LEFT, "Kg");
        it.printf(0,120, id(my_font3), id(my_cyan), TextAlign::TOP_LEFT, "Wenn Gewicht stabil angezeigt wird,");
        it.printf(0,150, id(my_font3), id(my_cyan), TextAlign::TOP_LEFT, "Chip an die Antenne halten!");
    - id: page3    
      lambda: |-
        it.fill(Color::BLACK);
        it.printf(0,0, id(my_font), id(my_red), TextAlign::TOP_LEFT, id(person_aktuell).c_str());
        it.printf(200,0, id(my_font), id(my_cyan), TextAlign::TOP_LEFT, " wiegt");
        it.printf(0,40, id(my_font2), "%4.1f", id(hx711_value).state);
        it.printf(200,60, id(my_font), TextAlign::TOP_LEFT, "Kg");

Unter pages: werden die Inhalte der drei Anzeigeseiten definiert. Zunächst erhält jede Seite einen Namen (-id: page1). Danach geht es in lambda weiter. Keine Angst, sie müssen kein Griechisch beherrschen. Lambda kennzeichnet nur, dass nun kein YAML-, sondern C++-Code folgt. Entsprechend enthalten die folgenden Zeilen die Ausgabebefehle. Wer sich näher damit beschäftigen möchte, findet in der ESPHome-Dokumentation dazu alles Erforderliche.

Achten Sie auch hier peinlich auf die Zeileneinrückungen. Sie kennzeichnen nämlich Anfang und Ende des Lambda-Abschnitts!

Jetzt muss noch dafür gesorgt werden, dass die drei Seiten auch zum richtigen Zeitpunkt auf dem Display erscheinen. Unmittelbar nach dem Einschalten der Waage ist automatisch die erste Seite (page1) ausgewählt. Dementsprechend erscheint "Warte aufs Netz".

Damit die zweite Seite erscheint, müssen wir die Firmware checken lassen, ob die Netzwerkverbindung aufgebaut ist. Das geschieht im Abschnitt wifi: mittels on_connect:.

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  on_connect:
    - display.page.show: page2
    - component.update: my_display  

Die Zeile - display.page.show: page2 und die darauf folgende sorgen für die Anzeigenumschaltung auf page2, sobald die WLAN-Verbindung läuft.

Was ist aber mit der dritten Seite? Die hatten wir ja schon im Abschnitt binary_sensor für jeden Benutzer eingesetzt. Das ist also schon erledigt.

Jetzt fehlen noch zwei Kleinigkeiten (sie sehen, das Projekt ist wirklich noch "in work"): Zum einen brauchen wir noch einen kleinen Zeichensatz, damit die Aufforderung auf der zweiten Seite, den RFID-Chip vor die Antenne zu halten, aufs Display passt. Das geschieht im Abschnitt font:.

font:
  - file: "fonts/Antenna-Bold.ttf"
    id: my_font
    size: 32
  - file: "fonts/Antenna-Bold.ttf"
    id: my_font2
    size: 64  
  - file: "fonts/Antenna-Bold.ttf"
    id: my_font3
    size: 16

Außerdem benötigen wir noch den Benutzernamen als globale Variable, damit wir ihn auf der dritten Seite anzeigen können. Dazu ist am Anfang des Firmware-Quellcodes hinter dem api:-Abschnitt dies einzufügen:

globals:
  - id: person_aktuell
    type: std::string
    initial_value: '"Fremder"'

Jetzt reicht es aber: Klicken Sie auf "Install", schalten Sie die Waage ein und lassen Sie die Firmware darauf installieren.