Terminanzeige mit e-Paper am ESP32, MQTT, Node-Red und ESPHome - Teil 2 - AZ-Delivery

Der folgende Beitrag wurde uns von unserem Leser Eberhard Werminghoff zugesandt. Viel Spaß beim Lesen und Nachbasteln.

Im ersten Teil dieser kleinen Reihe haben wir das e-Paper Display in seinen Varianten gezeigt und mit dem ESP32 verbunden. Außerdem haben wir den Aufbau der Software für den Kalender abstrahiert. In diesem zweiten Teil importieren wir den Flow in Node-Red und gestalten die Ausgabe auf dem Display. Anschließend richten wir ESPHome ein und programmieren den ESP32.

  • Unseren „Flow“ nach Node-Red importieren

  • in Node-Red gibt es eine Möglichkeit, Flows untereinander auszutauschen. Dazu werden zunächst die zu teilenden Flows über einen Export in einer JSON-Datei gespeichert. Das habe ich bei mir bereits durchgeführt und stelle den Export nun hier als Download zur Verfügung. Sie hat den Namen „Kalender.json“. Die wollen wir nun in Node-Red importieren. Dazu klicken wir in Node-Red oben rechts die drei kleinen Striche (Hamburger-Menue-Symbol) an und wählen dann den Punkt „Import“ aus. Es öffnet sich das Fenster „Import“. Gleichzeitig hat sich die Karteikarte „Zwischenablage“ geöffnet. Wir klicken auf „Datei für Import auswählen“ und wählen in dem geöffneten Fenster die Datei „Kalender.json“ dort aus, wo wir sie beim Download gespeichert hatten. Ganz unten müssen wir uns noch entscheiden, wohin in Node-Red wir importieren wollen. Hier sollten wir „Neuen Flow“ auswählen. und anschließend den roten Button „Import“ drücken. In der Reiterleiste finden wir nun einen Reiter der „Abfallkalender“ heißt.

    Der Flow ist jetzt zwar importiert worden, aber es fehlt noch an einigen Kleinigkeiten, damit die Kalenderdaten aus Google abgeholt werden können.

    Als Erstes müssen wir einmal “Übernahme“ drücken, damit die vielen blauen Punkte verschwinden. Es kommt zwar eventuell die Meldung:

     „Der Arbeitsbereich enthält einige Nodes, die nicht ordnungsgemäß eingestellt sind:…“

    die soll uns aber nicht stören und bestätigen die Übernahme. Jetzt sind noch jede Menge rote Dreiecke auf vielen Elementen zu sehen. Diese Elemente senden Informationen an den MQTT Broker (wenn da nicht die roten Dreiecke wären) und meckern, weil sie keinen Broker kennen.

  • Google-Kalender in Node-Red eintragen

  • Node-Red soll die Daten aus dem Google-Kalender „Flurreinigung“ oder „Müllabfuhr“ abrufen und in einer für andere Knoten lesbaren Form darstellen. Die dafür erforderlichen Knoten gehören nicht zur Standardpalette von Node-Red und müssen von uns nachgeladen werden. Wir klicken noch einmal auf das „Hamburger-Menu-Symbol“ oben rechts und wählen „Palette verwalten“ mit einem Klick aus. In dem nun offenen Fenster wurde auf der linken Seite bereits der Reiter „Palette“ aktiviert und zeigt oben die beiden Reiter „Installierte Nodes“ und „Installation“. Dort wählen Wir „Installation“ aus und geben im Suchfeld „node-red-contrib-ical-events“ ein.

    Dort wo bei mir „Installiert“ steht, ist bei Ihnen ein „Installieren“ zu sehen. Den betätigen Sie bitte und haben die Palette von „ical“ installiert. Sie ist jetzt in der linken Spalte unter „ical“ zu finden.

    Gehen sie nun in den importierten Flow “Abfallkalender” und öffnen Sie dort den Knoten mit dem Namen “Abfallplan”. Im Bereich “Config” finden Sie neben “Calendar config” ein Pulldown menu in dem Sie “Neuen Typ ‘i-cal-config’ hinzufügen” auswählen und mit dem Stift diesen neuen Zugang editieren.

    Wir wechseln in den Google-Kalender. Dort ist oben rechts ein Zahnrad zu sehen. Dahinter verbergen sich die Einstellungen der vorhandenen Kalender. Wählen Sie Ihren Müllkalender - bei mir heißt er „Müllabfuhr“. Der kleine Pfeil nach unten öffnet ein Fenster in dem die Daten für den Kalender eingegeben werden können.

    Dort interessiert uns besonders der Punkt „Kalender integrieren“ und dort unter „Anpassen“ die „Privatadresse im iCal-Format“

    Kopieren Sie diese Adresse in die Zwischenablage. Dann wechseln Sie zurück nach Node-Red und fügen die Adresse aus der Zwischenablage im Node-Red Knoten „Abfallplan“ in das Feld “iCal/ics/caldav …. “ wieder ein.

    Im Bild oben ist nur ein kleiner Teil der Adresse zu sehen, sie ist erheblich länger.

    Nun “Aktualisieren”, “Fertig” und “Übernahme(deploy)” drücken und der Kalender ist nun für Node Red verfügbar..

    Hinweis: Es ist dringend notwendig, mindestens die Version 2.1.2 zu verwenden, weil einzelne der Datenfelder sonst unter anderen Bezeichnungen zu finden sind!

    Für die wochenweise Flurreinigung wurde ein gesonderter Kalender bei mir eingerichtet. Wenn Sie den nicht einrichten, bleibt später in der Anzeige das Feld hinter “Flurreinigung:” leer. Haben sie einen eigenen Anwendungsfall können Sie jetzt den dazugehörigen Kalender - wie oben beschrieben - einrichten.

  • MQTT Server in Node-Red eintragen

  • Die Daten aus dem Kalender haben wir mit Hilfe von Node-Red bereitgestellt und müssen sie auch über Node-Red an den Broker übermitteln. Dazu ist es erforderlich die Zugangsdaten des MQTT-Servers (Mosquitto) in Node-Red einzutragen.

    Dazu öffnen Sie in Node-Red einen beliebigen „mqtt out“-Knoten, der wie nebenstehend abgebildet ist, mit einem Doppelklick. Er kann eine abweichende Beschriftung haben, z.B. “Wochentag/A4” In der Zeile “Server” sehen Sie den Pfeil des Pull-Down-Feldes. Klicken Sie bitte einmal darauf. Danach auf die Zeile „neuen Typ ‚mqtt-broker‘ hinzufügen“ klicken. Anschließend auf den nebenstehenden Stift klicken und es öffnet sich eine Seite, die wie folgt aussieht:

    Jetzt folgen Angaben, die Ihnen schon von der Installation des Brokers bekannt sein dürften. Vergeben Sie einen frei wählbaren Namen. Neben „Server“ tragen Sie die IP-Adresse des MQTT-Servers ein, die restlichen Angaben des Reiters „Verbindung“ entnehmen Sie bitte dem vorangegangenen Bild. Die Client-ID wird automatisch vergeben, also diese bitte nicht aus dem Bild abschreiben.

    Haben Sie bei der Einrichtung einen Benutzernamen und ein Zugangspasswort für den Zugang zum MQTT_Server vergeben, tragen Sie diese im Reiter „Sicherheit“ ein.

    Die Felder hinter dem Reiter „Nachrichten“ können leer bleiben.
    „Aktualisieren“ drücken. Danach finden sie Ihren Broker in dem Feld neben „Server“ aufgelistet. „Fertig“ und „Übernahme (deploy)“ nacheinander betätigen komplettiert die Einrichtung.

    Damit die hässlichen roten Dreiecke auf allen Elementen verschwinden müssen wir jedem „mqtt out“ - Element mitteilen, welchen Broker er benutzen soll. Im Pull-Down Feld „Server“ steht noch:

    Dort finden wir den Namen, den Sie selber vergeben haben. Button „Fertig“ betätigen. Die roten Dreiecke wandeln sich in blaue Kreise . Durch eine „Übernahme (deploy)“ gehen auch die blauen Kreise weg. Die Meldung:

     „Der Arbeitsbereich enthält einige Nodes, die nicht ordnungsgemäß eingestellt sind:…“

    kennen wir bereits und ignorieren sie. Nochmals die „Übernahme (deploy) bestätigen”. Nach einer kurzen Dauer sollte unter den bearbeiteten Elementen ein „Verbunden“ zu sehen sein - also alles bestens.

  • Die Kopfzeile und die erste Überschriftzeile - „von - bis“

  • Hier sehen wir zum ersten Mal die Knoten, die durch Linien miteinander verbunden sind. Die verwendeten Knoten (nodes) werde ich hier mal erläutern. Zum Schluss gibt es die in Node-Red importierbare JSON-Datei für alle vier Funktionsblöcke.

    Der Knoten „timestamp“ stellt die Zeit in Millisekunden seit dem 01.01.1970 am Knotenausgang zur Verfügung. Eine verdammt große Zahl -aber es geht!

    Der Knoten “simpletime“ (zusätzlicher Knoten aus der Palette node-red-contrib-simpletime in der Version 2.10.03) wandelt die vom timestamp übermittelte Zahl in verschiedene Datumsformen um. Am Ausgang werden u.a. die Jahreszahl (2022), der Monat (02), der Tag (03), der Tag innerhalb der aktuellen Woche (4 für Donnerstag) und die aktuelle Kalenderwoche zur Verfügung gestellt.

    Alles das, was die Vielzahl der Knoten nicht abbilden kann, ist in einem Funktionsknoten programmierbar, erkennbar an diesem Symbol:

    Das aktuelle Datum in der Kopfzeile links wird im Funktionsknoten ‚aktuelles Datum‘ zusammengebaut. Hier der Inhalt:

     var tag = msg.mydom;
    var monat = msg.mymonthn;
    var jahr = msg.myyear;
    msg.payload = tag + "."+ monat+"."+jahr
    return msg;

    Damit wird am Ausgang das aktuelle Tagesdatum zur weiteren Verwendung bereitgestellt.

    Wer könnte mit dem Datum etwas anfangen? Richtig: MQTT - der Broker - kann das Datum gebrauchen und wir „veröffentlichen“ (publish) es mit einem „mqtt out“ Knoten. Gleichzeitig teilen wir dem Broker aber auch mit, wo er das Datum ablegen soll, damit die Abonnenten des Datums dieses auch wiederfinden. Wir teilen dem Broker also eine Art Postfach mit, wo es hin soll. Dieses Postfach heißt hier „topic“. Zu einer Nachricht an den Broker gehört also immer ein „topic“ im „mqtt out“-Knoten. Hier bei uns bekommen die „mqtt out“-Knoten den Namen des Topics.

    Hinweis: Kontrollieren Sie bei dieser Gelegenheit, ob im Feld neben „Server“ der vergebene Name Ihres MQTT-Servers steht. Wenn nicht: Pull-Down betätigen und den Server auswählen. Auch hier gilt: „Fertig“ und anschließend „Übernahme“ (rechts oben) nacheinander drücken.

    Sie sehen, dass hinter diesem Knoten die Kommunikation endet. Das Datenpaket wurde abgeliefert, also: „Mission over!“.

    In gleicher/ähnlicher Art und Weise behandeln wir die anderen zur Verfügung gestellten Daten. Unterschiedliche Daten bedeuten aber auch unterschiedliche Topics. Aber bitte mit etwas Struktur in den „Postfächern“. Alle Daten für dieses Projekt liegen unterhalb des topics „/SmartHome/Display/“. Das werden wir auch so beibehalten.

    Hinweis: Es geht nicht anders: Ordnung muss sein! Ich habe anfangs die Daten einfach alle unter dem Topic „/“ eingeordnet. Ein Umstand, den ich später bereut habe. Alle Topics mussten neu eingeordnet und somit verändert werden. Halten Sie deshalb lieber gleich von vornherein Ordnung in den Topics. Ich habe zurzeit ca. 200 Topics, wenn Sie da keine Ordnung halten, sind Sie bei der Fehlersuche verloren.

    Für die Zeile, in der Wochenanfang und -ende angezeigt werden, müssen zwei getrennte Kalenderdaten berechnet werden: Wochenbeginn und Wochenende. Die Berechnung ist individuell und gehört - wie wir oben gelesen haben - in einen Funktionsknoten, hier: dem Knoten „Woche vom - bis“.

     let dt = new Date();
    let dow = dt.getDay();

    if (dow==0)
    {
    dow=7;
    }

    Date.prototype.subtractDays = function (d) {
    this.setTime (this.getTime () - (d*24*60*60*1000));
    return this;
    }

    Date.prototype.addDays = function (d) {
    this.setTime (this.getTime () + (d*24*60*60*1000));
    return this;
    }

    let day1 = new Date().subtractDays (dow).getDate()+1; // Tag des Monats
    if (day1<10){day1 = "0"+day1;}
    let month1 = new Date().subtractDays (dow).getMonth()+1; // Monat des Jahres
    let year1 = new Date().subtractDays (dow).getFullYear(); // Kalenderjahr
    var dt1=day1 + "."+ month1 + "."+ year1;

    let day2 = new Date().addDays (7-dow).getDate(); // Tag des Monats
    if (day2 < 10) {day2 = "0"+ day2;}
    let month2 = new Date().addDays (7-dow).getMonth()+1; // Monat des Jahres
    let year2 = new Date().addDays (7-dow).getFullYear(); // Kalenderjahr
    var dt2=day2 + "."+ month2 + "."+ year2;
    msg.payload = dt1 + " - " +dt2;
    msg.year1 = dt1;
    msg.year2 = dt2;
    return msg;

    Hier und in den kommenden Zeilen sind immer wieder Knoten mit einem „abc“ auf der rechten Seite zu finden. Das sind Textknoten, um bestimmte Texte oder Zahlen auf der Benutzeroberfläche darzustellen.

    Bei mir ist der Inhalt des Displays ebenfalls noch in der Benutzeroberfläche von Node-Red zu finden (siehe Punkt 3 im Schaubild rechts unten „Anzeige in Node-Red“).


  • Die zweite Überschriftzeile - Flurreinigung

  • Hinweis: Es ist dringend notwendig, mindestens die Version 2.1.2 zu verwenden, weil einzelne der Datenfelder sonst unter anderen Bezeichnungen zu finden sind.

    Wenn Sie unter 1.1.1 keinen zweiten Kalender eingerichtet haben, können zwangsläufig hier auch keine Daten übermittelt werden (siehe Hinweis weiter unten: Thema Kreativität).

    Im Knoten „Wohnungsnummer“ wird die Weitergabe der ermittelten Informationen an den nächsten Knoten aufbereitet und abgesendet.

    An diesem Punkt ist der Einstieg für die eigene Kreativität: Ein Kalender für die Katzentoilette, wer räumt die Spülmaschine aus? u.v.a.m. Es ist schön zu sehen, dass man selbst nicht an der Reihe ist ☺. Die Daten aus dem Bemerkungsfeld des Kalenders (hier: Whg3) werden in den beiden Kopfzeilen des Displays dargestellt.

    Die Dauer der Zuständigkeit von 1 Woche wird im Google-Kalender in den Feldern „von“ und „bis“ eingetragen.

    Während der eingegebenen Dauer wird Zuständigkeit unverändert in den Kopfzeilen angezeigt.

  • Der eigentliche Abfuhrkalender

  • Unsere Tabelle hat vier Zeilen mit je vier Datenfeldern. Oben habe ich mal die erste Tabellenzeile dargestellt. Die anderen drei Tabellenzeilen sind analog dieser Zeile aufgebaut.

  • Datenspalte 1: Kurzform des Wochentages

  • In der ersten Datenspalte wird die Kurzform des Wochentages dargestellt. Diese wird aus dem Datenfeld „DTEND;VALUE=DATE:20220210“ des Kalenders im Funktionsknoten zur Kurzform umgewandelt. Diese Umwandlung wird in dem Funktionsknoten beschrieben:

     let n = msg.total;
     var i=0;
     if(n>i)
     {
         var dow = msg.payload[i].eventEnd;
         dow = new Date(dow).getUTCDay();
         switch (dow)
        {
             case 0:
             dow = 'So';
             break;
             
             case 1:
             dow = 'Mo';
             break;
             
             case 2:
             dow = 'Di';
             break;
             
             case 3:
             dow = 'Mi';
             break;
             
             case 4:
             dow = 'Do';
             break;
             
             case 5:
             dow = 'Fr';
             break;
             
             case 6:
             dow = 'Sa';
             break;
             
             default:
             dow = '--';
             break;
        }
     
     msg.payload = dow;}
     
     return msg;

    Das Ergebnis wird sofort danach an den uns bekannten Broker unter Nennung des Topics gesendet. Dieses wir für jede Zeile ebenso gemacht.

    Hinweis: Die Variable i muss für die anderen Tabellenzeilen in den eckigen Klammern fortgeschrieben werden. Also: 1,2 und 3 für 2. bis 4. Zeile.

  • Datenspalte 2: Abfuhrdatum

  • Das Abfuhrdatum ist im Google-Kalender ebenfalls im Datenfeld „DTSTART;VALUE=DATE:20220210“ zu finden. Es wird vom Kalenderknoten „Abfallplan“ in ein Format

     date: "2022-02-24 00:00 - 2022-02-25 00:00"

    umgewandelt und an den Funktionsknoten abgegeben. Die ersten 10 Stellen (“2022-02-10“) benötigen wir zur Anzeige des Abfuhrtermins. Da es aber ohnehin ein Kalender für 2022 ist, verzichte ich auf das Jahr und spare damit Platz. Das „Zurechtstutzen“ übernimmt mal wieder ein Funktionsknoten mit dem Inhalt:

     let n = msg.total;
     var i=0;
     if(n>i)
     {
         var calDay = msg.payload[i].date.substring(8,10);
         var calMonth = msg.payload[i].date.substring(5,7);
         msg.payload  = calDay + "." + calMonth + "." ;}
     
     return msg;

    Hinweis: Die Variable i muss für die anderen Tabellenzeilen in den eckigen Klammern fortgeschrieben werden. Also: 1,2 und 3 für 2. bis 4. Zeile.

    … und nun damit ab zum Broker…

  • Datenspalte 3: Ereignis

  • Die in der ICS-Datei vorhandenen oder bearbeiteten Daten können nun eins zu eins übernommen werden.

     let n = msg.total;
     var i=0;
     if(n>i)
     {
         var event = msg.payload[i].summary;
     
         msg.payload  = event;
     }
     else
     {
         msg.payload = "keine Daten";
     }
     return msg;

    Hinweis: Auch hier muss die Variable i je nach Zeile die Werte 0 bis 3 für die Zeilen 1 bis 4 durchlaufen.

  • Datenspalte 4: Akteur

  • Diese Spalte beschreibt die Zuständigkeit zu einem Ereignis. Ich habe zuhause vier farbenfrohe Tonnen grundsätzlich zur Verfügung. Die Tonnen für Bioabfall und Papier haben aber keine besondere Zuständigkeit. Sie bekommen drei „-“ in der vierten Spalte. Wenn also der Google-Kalender bei diesen Tonnen in den Bemerkungen leer ist, wird „---“ ausgegeben.

     let n = msg.total;
     var i=0;
     if(n>i)
     {
         var zustaendig = msg.payload[i].originalEvent.description;
         if (zustaendig == "")
        {
             zustaendig =" --- ";
        }
         msg.payload = zustaendig;
     }
     else
     {
         msg.payload = "---"
     }
     return msg;

    Damit haben wir eine Datenzeile beschrieben, die anderen drei sind ebenso aufgebaut. Die Tabelle ist nun bei Bedarf durch zusätzliche Zeilen/Spalten erweiter- oder modifizierbar.

    Hinweis: Auch hier muss die Variable i je nach Zeile die Werte 0 bis 3 für die Zeilen 1 bis 4 durchlaufen.

  • Die Fußzeile

  • Die Daten der Fußzeile werden nicht in Node-Red ermittelt und via MQTT an das Display geschickt, sie werden in ESPHome erzeugt und auch von dort aus dargestellt.

  • Der Start-Stopschalter für den Deep-Sleep des ESP32

  • Wir werden den ESP hauptsächlich im Deep-Sleep Modus betreiben. Das hat gerade bei Batteriebetrieb große Vorteile. Wir werden aber auch Softwareaktualisierungen über WLAN einspielen, also „over the air“ (OTA). Und genau da beginnt das Problem: Je länger die Deep-Sleep Phase dauert, um unwahrscheinlicher wird es, den ESP32 während einer Wachphase über OTA zu erreichen. Das wird umso schwieriger, je kürzer die Wachphase ist; in unserem Projekt ca. 10 bis 15 Sekunden.

    Deshalb haben wir in Node-Red zwei Schalter kreiert, die wie folgt aussehen:


    In den beiden „mqtt_out“ Knoten müssen in den Feldern „QoS“ der Konfiguration eine „2“ enthalten und im Pulldownfeld rechts neben „Retain“ ein „wahr“ eingetragen werden. Die Schalter senden ihren Zustand über das topic “/SmartHome/Display/sleep_mode” bzw. “/SmartHome/Display/ota_mode” an den Broker.

    Der Schalter „No Deep Sleep“ greift erst nach einem Reset des ESP. In einer bereits bestehenden Wachphase kann Deep-Sleep nicht verhindert werden. Nach dem Ende der angebrochenen Deep-Sleep-Phase wird der ESP nun nicht mehr in den Tiefschlaf geschickt. Nach Erreichen des Wachzustandes ist der Schalter „No Deep-Sleep“ wieder auszuschalten.

    Soll der ESP erneut in den Tiefschlaf geschickt werden, muss nun der Schalter „Start Deep-Sleep“ eingeschaltet werden. Nach Erreichen des DeepSleep kann auch dieser Schalter wieder ausgeschaltet werden.

    Alle Daten für das Display werden über einen „mqtt out“ Knoten an den MQTT-Broker übermittelt („subscribe“).


  • ESPHome

  • Einrichten des Projektes

  • Die Installation hat hoffentlich funktioniert. Ich setze nun ein funktionierendes ESPHome-System voraus. Sie haben noch nicht installiert? Dann folgen Sie diesen wenigen Schritten hier!

    Wenn alles gut installiert wurde, müsste nach der Abfrage von „esphome version“ der Bildschirm wie folgt oder ähnlich aussehen.

    Bei der Installation wurde ein Verzeichnis ESPHome auf einem von Ihnen vorgegebenen Laufwerk erzeugt. Mein Verzeichnis liegt auf dem Laufwerk „I:“.

    Dort hinein wechseln Sie mi

      >I:

    Im LW I: wechseln Sie in das Verzeichnis mit

     >I:\cd ESPHome

    Sie beginnen ein neues Projekt mit dem Namen display-4in2.yaml mit der Eingabe am Prompt und rufen gleichzeitig den wizard von ESPHome auf:

      I:\ESPHome>esphome wizard display-4in2.yaml

    Hinweis: ESPHome akzeptiert an diesem Punkt nur kleine Buchstaben, Ziffern und den Bindestrich.

    Das System ist sehr höflich und zeigt nun:

     I:\ESPHome>esphome wizard display-4in2.yaml
     Hi there!
     I'm the wizard of ESPHome :)
     And I'm here to help you get started with ESPHome.
     In 4 steps I'm going to guide you through creating a basic configuration file for your custom ESP8266/ESP32 firmware. Yay!
     
     
     
     ============= STEP 1 =============
        _____ ____ _____ ______
        / ____/ __ \| __ \| ____|
      | |   | | | | |__) | |__
      | |   | | | | _ /| __|
      | |___| |__| | | \ \| |____
        \_____\____/|_| \_\______|
     
     ===================================
     First up, please choose a name for your node.
     It should be a unique name that can be used to identify the device later.
     For example, I like calling the node in my living room livingroom.
     
     ←[1;37m(name): ←[0m

    Am Prompt geben Sie als Namen „display-4in2“ ein. Wenn Sie den Hinweis bezüglich der nutzbaren Zeichen oben nicht beachtet haben, werden Sie mit einer Fehlermeldung „belohnt“.

     ←[1;37m(name): ←[0mdisplay-4in2
     Great! Your node is now called "display-4in2".
     
     
     ============= STEP 2 =============
          ______ _____ _____
          | ____|/ ____| __ \\
          | |__ | (___ | |__) |
          | __| \___ \| ___/
          | |____ ____) | |
          |______|_____/|_|
     
     ===================================
     Now I'd like to know what microcontroller you're using so that I can compile firmwares for it.
     Are you using an ESP32 or ESP8266 platform? (Choose ESP8266 for Sonoff devices)
     
     Please enter either ESP32 or ESP8266.
     ←[1;37m(ESP32/ESP8266): ←[0m

    Nun werden Sie gefragt, ob Sie ein ESP8266 oder einen ESP32 benutzen wollen. Geben Sie „ESP32“ ein. Die Antwort des Systems ist umfangreich:

     ←[1;37m(ESP32/ESP8266): ←[0mESP32
     Thanks! You've chosen ESP32 as your platform.
     
     Next, I need to know what board you're using.
     Please go to http://docs.platformio.org/en/latest/platforms/espressif32.html#boards and choose a board.
     (Type esp01_1m for Sonoff devices)
     
     For example "nodemcu-32s".
     Options: alksesp32, az-delivery-devkit-v4, bpi-bit, briki_abc_esp32, briki_mbc-wb_esp32, d-duino-32, esp-wrover-kit, esp32-devkitlipo, esp32-evb, esp32-gateway, esp32-poe, esp32-poe-iso, esp32-pro, esp320, esp32cam, esp32dev, esp32doit-devkit-v1, esp32doit-espduino, esp32thing, esp32thing_plus, esp32vn-iot-uno, espea32, espectro32, espino32, etboard, featheresp32, featheresp32-s2, firebeetle32, fm-devkit, frogboard, healtypi4, heltec_wifi_kit_32, heltec_wifi_kit_32_v2, heltec_wifi_lora_32, heltec_wifi_lora_32_V2, heltec_wireless_stick, heltec_wireless_stick_lite, honeylemon, hornbill32dev, hornbill32minima, imbrios-logsens-v1p1, inex_openkb, intorobot, iotaap_magnolia, iotbusio, iotbusproteus, kits-edu, labplus_mpython, lolin32, lolin32_lite, lolin_d32, lolin_d32_pro, lopy, lopy4, m5stack-atom, m5stack-core-esp32, m5stack-core2, m5stack-coreink, m5stack-fire, m5stack-grey, m5stack-timer-cam, m5stick-c, magicbit, mgbot-iotik32a, mgbot-iotik32b, mhetesp32devkit, mhetesp32minikit, microduino-core-esp32, nano32, nina_w10, node32s, nodemcu-32s, nscreen-32, odroid_esp32, onehorse32dev, oroca_edubot, pico32, piranha_esp32, pocket_32, pycom_gpy, qchip, quantum, s_odi_ultra, sensesiot_weizen, sg-o_airMon, sparkfun_lora_gateway_1-channel, tinypico, ttgo-lora32-v1, ttgo-lora32-v2, ttgo-lora32-v21, ttgo-t-beam, ttgo-t-watch, ttgo-t1, ttgo-t7-v13-mini32, ttgo-t7-v14-mini32, turta_iot_node, vintlabs-devkit-v1, wemos_d1_mini32, wemosbat, wesp32, widora-air, wifiduino32, xinabox_cw02
     ←[1;37m(board): ←[0m

    Das sind die ESP32 Boards, die von ESPHome unterstützt werden. Hier geben Sie „az-delivery-devkit-v4“ ein:

     ←[1;37m(board): ←[0maz-delivery-devkit-v4
     Way to go! You've chosen az-delivery-devkit-v4 as your board.
     
     
     
     ============= STEP 3 =============
        __         ___ ______ _
        \ \       / (_) ____(_)
        \ \ /\ / / _| |__   _
          \ \/ \/ / | | __| | |
          \ /\ / | | |   | |
            \/ \/   |_|_|   |_|
     
     ===================================
     In this step, I'm going to create the configuration for WiFi.
     
     First, what's the SSID (the name) of the WiFi network display-4in2 should connect to?
     For example "Abraham Linksys".
     ←[1;37m(ssid): ←[0m

    Sie werden jetzt nach den WLAN Daten beginnend mit der SSID gefragt, die können Sie später noch einfach editieren: Also tragen Sie hier „jhkhfkj“ oder ihre eigene SSID ein und werden anschließend nach dem passenden Passwort gefragt.

     ←[1;37m(ssid): ←[0mjhkhfkj
     Thank you very much! You've just chosen "jhkhfkj" as your SSID.
     
     Now please state the password of the WiFi network so that I can connect to it (Leave empty for no password)
     
     For example "PASSWORD42"
     ←[1;37m(PSK): ←[0m

    Tragen Sie als Passwort hier „meinpasswort“ oder Ihr eigenes WLAN Passwort ein:

     ←[1;37m(PSK): ←[0mmeinpasswort
     Perfect! WiFi is now set up (you can create static IPs and so on later).
     
     
     ============= STEP 4 =============
            ____ _______
          / __ \__   __|/\\
          | | | | | | / \\
          | | | | | | / /\ \\
          | |__| | | |/ ____ \\
          \____/ |_/_/   \_\\
     
     ===================================
     Almost there! ESPHome can automatically upload custom firmwares over WiFi (over the air) and integrates into Home Assistant with a native API.
     This can be insecure if you do not trust the WiFi network. Do you want to set a password for connecting to this ESP?
     
     Press ENTER for no password
     ←[1;37m(password): ←[0m

    Nun geht es um die Aktualisierung der Software via WLAN „Over the Air („OTA“). Wenn diese Übertragung durch ein zusätzliches Passwort gesichert werden soll, geben Sie hier ein Passwort ein oder ein ENTER für kein Passwort. Wählen Sie “ENTER”.

     ←[1;37m(password): ←[0m
     
     DONE! I've now written a new configuration file to display-4in2.yaml
     
     Next steps:
      > Follow the rest of the getting started guide:
      > https://esphome.io/guides/getting_started_command_line.html#adding-some-features
      > to learn how to customize ESPHome and install it to your device.
     
     I:\ESPHome>

    Nun gibt es im Verzeichnis I:\ESPHome die Datei display-4in2.yaml

    Wenn Sie die Datei mit einem Editor (z.B. Notepad++) öffnen, sehen Sie das Grundgerüst der Konfigurationsdatei in YAML.

     esphome:
      name: display-4in2
     
     esp32:
      board: az-delivery-devkit-v4
      framework:
        type: arduino
     
     # Enable logging
     logger:
     
     # Enable Home Assistant API
     api:
      password: ""
     
     ota:
      password: ""
     
     wifi:
      ssid: "jhkhfkj"
      password: "meinpasswort"
     
       # Enable fallback hotspot (captive portal) in case wifi connection fails
      ap:
        ssid: "Display-4In2 Fallback Hotspot"
        password: "ucffbsF59pf2"
     
     captive_portal:

    Wichtige Hinweise:

    • In YAML hat das Einrücken von Zeilen eine ganz besondere Bedeutung (ähnlich wie in Python). Wer darauf nicht achtet, bekommt gnadenlos Fehlermeldungen. Es wird immer um zwei Leerzeichen - nicht den Tabulator verwenden - eingerückt.
    • Bemerkungen auf der YAML-Ebene beginnen an einem Zeilenanfang mit einem Doppelkreuz (Hash, Raute oder „#“).
    • Bemerkungen auf Programmierebene, also hinter „lambda: |-„ beginnen mit „//“
    • Nach einem Doppelpunkt kommt immer ein Leerzeichen.

    Die wesentlichsten Punkte haben wir bereits im Wizard angegeben, deshalb noch die wichtigen Ergänzungen:

    logger: Wer den Logger abschalten möchte, kann ihn einfach löschen oder durch „#“ auskommentieren. Alles was gelöscht wurde, kann im Nachhinein jederzeit wieder hinzugesetzt (neu eingegeben) werden.

    Es gibt verschiedene Level für das Logging, wir nutzen „INFO“

    api: Es gibt einen Übergang zum Programm Home Assistant. Da ich diese Software nicht benutze, habe ich die zwei Zeilen auskommentiert..

    ota: Wurde im wizard behandelt

    wifi:

    ssid: Hier die eigene SSID eingeben

    password: Hier das Passwort passend zur SSID angeben

    ap: Wenn eine Verbindung über WLAN nicht zustande kommt, wird automatisch ein Accesspoint (AP) mit den angegebenen Zugangsdaten aufgemacht. Bei geöffnetem AP in Ihrem Browser die IP des AP eingeben. Es öffnet sich eine Seite, in der alternative SSID und Passwort eingeben werden können. Sie überschreiben aber die Daten aus dem obigen Punkt „wifi“

    captive_portal: Bei einem Captive Portal kann sich ein Endgerät zunächst mit dem meist unverschlüsselten und ohne Zugangsdaten erreichbaren WLAN verbinden. In diesem Zustand wird vom Captive Portal allerdings jeder weitere Zugriff auf das dahinter liegende Netzwerk oder Internet blockiert. Das Gerät ist quasi in diesem Bereich gefangen, wovon sich die Bezeichnung ableitet (Wikipedia). Wir brauchen es nicht, werden es also aus unserer Konfiguration löschen.


  • Allgemeine Bemerkungen zu unserem ESPHome-Projekt

    • Sie sehen, dass ESPHome aus kleinen Modulen besteht, denen mannigfaltige Eigenschaften zugeordnet werden können. Es gibt insgesamt über 150 Module
    • Jedes Modul in der höchsten Ebene (ganz links) darf nur einmal vorhanden sein. Alles was die gleichen Eigenschaften hat, liegt eine Ebene tiefer.
    • Module können über die ID angesprochen werden. Jede ID darf nur einmal vorhanden sein.
    • Es gibt drei Arten von Sensoren:

      1. sensor: numerischer Inhalt
      2. binary_sensor: binärer Inhalt (z.B. true, false)
      3. text_sensor: alphanumerischer Inhalt (z.B. Datum, Uhrzeit, MQTT-Inhalte)

    Die vom ESP32 empfangenen MQTT-Daten werden in der Konfiguration unter:

       #MQTT-Empfangsdaten
      - platform: mqtt_subscribe
        id: kalenderwoche
        topic: /SmartHome/Display/Kalenderwoche

    zu finden sein.

    • font: Die zu verwendenden Zeichensätze müssen in ein Verzeichnis fonts unterhalb des Ordners esphome von Ihnen eingefügt werden. Das Dateiformat ist „ttf“. Somit können Schriftarten aus Windows (z.B. C:\Windows\Fonts\) direkt nach esphome\fonts\ kopiert werden. Die Schriftgröße ist frei wählbar. Da die deutsche Sprache neben den normalen ASCII-Zeichen auch noch Umlaute besitzt, wird für jeden Font eine Liste der zu verwendenden Zeichen in “glyphs:” hinterlegt.
    • spi: Da bei unserer Anwendung die Anzeige nicht über die SPI-Schnittstelle antwortet, werden nur zwei Pins definiert:
      clk_pin:

    und der

    mosi_pin:

    • display:
      - platform: spezifiziert das verwendete Display. Die verfügbaren Displays sind auf der Webseite von ESPHome zu finden. Hierunter werden auch die restlichen Pins definiert:
      cs_pin:,
      dc_pin:
      busy_pin:
      reset_pin:

    Die Besonderheiten z.B. Größe wird in
    model: definiert.

    In spi_id: wird auf die ID von spi: (waveshare_spi) referenziert. In

    lambda: |- kann alles das, was nicht konfiguriert werden kann, über C++ als Code „eingeschleust“ werden: In unserem Beispiel ist das die komplette Steuerung für das Display

      mqtt:
      In der Konfiguration wird an zwei Stellen eine eingehende Nachricht auf einem bestimmten Topic dazu benutzt, den deep_sleep zu verhindern (prevent) oder zu starten (enter).

        Wenn auf dem Topic deepsleep/ota_mode eine Nachricht mit dem Inhalt „ON“ in einer Wachphase eingeht, wird ein erneuter deep-sleep mit dem Befehl „deep_sleep.prevent: deep_sleep_1“ verhindert.
        Wenn auf dem Topic deepsleep/deep_sleepmode4 eine Nachricht mit dem Inhalt „ON“ in einer Wachphase eingeht, wird ein erneuter deep-sleep mit dem Befehl „deep_sleep.enter: deep_sleep_1“ gestartet.
        deep_sleep_1 ist die ID von deep_sleep.

        Es gäbe noch jede Menge Besonderheiten, die es zu erwähnen wert sind, aber den Rahmen hier absolut sprengen würde. Ich kann Ihnen nur raten, bei Fragen das Internet oder die Foren zu bemühen.

      • Das Listing der gesamten ESPHome-Konfiguration

      • Und nun die zu verwendende gesamte Konfiguration.

        ESPHome unterstützt das Auslagern von Zugangsdaten in sogenannte “secrets” (Geheimnisse). Nach einem Doppelpunkt können Sie entweder direkt z.B. Passwörter eintragen, oder mit der Direktive !secret auf eine externe Datei namens secrets.yaml verweisen (Info). Ich habe diese Datei für Sie als Template zum Download abgelegt. Dort müssen Sie die XXXXX durch Ihre Daten ersetzen. Die Datei muss sich dann im gleichen Ordner befinden.

         esphome:
          name: display-4in2
          platform: ESP32
          board: az-delivery-devkit-v4
          on_boot:
            priority: -100
            then:
              - wait_until:
                  mqtt.connected:
               # Wait for some valid temp data
              - component.update: sntp_time
              - component.update: tpl_doy
              - component.update: tpl_hour_sec
              - component.update: rssi_value_dsp
               # Give some time to get the rest of the mqtt data
              - delay: 6s
              - component.update: epaper_display
         
           
         
         # Enable logging
         logger:
          level: INFO
         
         # Enable Home Assistant API
         # api:
         #   password: "test"
         
         ota:
          password: "test"
         
         wifi:
          ssid: !secret wifi_ssid
          password: !secret wifi_password
          fast_connect: true
          manual_ip:
            static_ip: !secret wifi_static_esp_board
            gateway: !secret wifi_gateway
            subnet: 255.255.255.0
            dns1: !secret wifi_dns1  
         
           # Enable fallback hotspot (captive portal) in case wifi connection fails
          ap:
            ssid: !secret ap_ssid
            password: !secret ap_password
         
         captive_portal:
         
         time:
          - platform: sntp
            id: sntp_time
            timezone: Europe/Berlin
            servers:
              - 0.pool.ntp.org
              - 1.pool.ntp.org
              - 2.pool.ntp.org
             
             
         mqtt:
          broker: !secret mqtt_ip
          username: !secret mqtt_user
          password: !secret mqtt_password
          id: mqtt_client
          birth_message:
          will_message:
          on_message:
            - topic: /SmartHome/Display/ota_mode
              payload: 'ON'
              then:
                - deep_sleep.prevent: deep_sleep_1
            - topic: /SmartHome/Display/sleep_mode
              payload: 'ON'
              then:
                - deep_sleep.enter: deep_sleep_1
         
         
         deep_sleep:
          id: deep_sleep_1
          run_duration: 20s
          sleep_duration: 3600s
         
         
         binary_sensor:
          - platform: template
            name: "OTA Mode"
            id: ota_mode
            internal: true
            on_state:
              - if:
                  condition:
                    binary_sensor.is_on: ota_mode
                  then:
                    - deep_sleep.prevent: deep_sleep_1      
             
         sensor:
           #RSSI based on MAC-Address Waveshare-Board
          - platform: wifi_signal
            name: "WiFi Signal Sensor"
            update_interval: 30s
            id: rssi_value_dsp
             
             
             
         text_sensor:
           # Aktueller Tag im Jahr
          - platform: template
            name: "Tag im Jahr"
            lambda: |-
              auto doy = id(sntp_time).now().strftime("%j");
              return {doy};
            id: tpl_doy
            update_interval: 5s
         
           #Datum und Uhrzeit für die Fußzeile "Daten von"
          - platform: template
            name: "Stunden Minuten"
            lambda: |-
              auto time = id(sntp_time).now().strftime("%H:%M");
              return {time};
            id: tpl_hour_sec
            update_interval: 5s
           
           #MQTT-Empfangsdaten
          - platform: mqtt_subscribe
            id: kalenderwoche
            topic: /SmartHome/Display/Kalenderwoche
          - platform: mqtt_subscribe
            id: datum_akt
            topic: /SmartHome/Display/Datum
          - platform: mqtt_subscribe
            id: wochentag
            topic: /SmartHome/Display/Wochentag
          - platform: mqtt_subscribe
            id: woche_von
            topic: /SmartHome/Display/Woche1
          - platform: mqtt_subscribe
            id: woche_bis
            topic: /SmartHome/Display/Woche2
          - platform: mqtt_subscribe
            id: flurreinigung
            topic: /SmartHome/Display/Flurreinigung
             
             #Daten Zeile 1
          - platform: mqtt_subscribe
            id: wochentag1
            topic: /SmartHome/Display/A1
          - platform: mqtt_subscribe
            id: datum1
            topic: /SmartHome/Display/B1
          - platform: mqtt_subscribe
            id: ereignis1
            topic: /SmartHome/Display/C1
          - platform: mqtt_subscribe
            id: akteur1
            topic: /SmartHome/Display/D1    
             
             #Daten Zeile 2
          - platform: mqtt_subscribe
            id: wochentag2
            topic: /SmartHome/Display/A2
          - platform: mqtt_subscribe
            id: datum2
            topic: /SmartHome/Display/B2
          - platform: mqtt_subscribe
            id: ereignis2
            topic: /SmartHome/Display/C2
          - platform: mqtt_subscribe
            id: akteur2
            topic: /SmartHome/Display/D2
         
             #Daten Zeile 3
          - platform: mqtt_subscribe
            id: wochentag3
            topic: /SmartHome/Display/A3
          - platform: mqtt_subscribe
            id: datum3
            topic: /SmartHome/Display/B3
          - platform: mqtt_subscribe
            id: ereignis3
            topic: /SmartHome/Display/C3
          - platform: mqtt_subscribe
            id: akteur3
            topic: /SmartHome/Display/D3
         
             #Daten Zeile 4
          - platform: mqtt_subscribe
            id: wochentag4
            topic: /SmartHome/Display/A4
          - platform: mqtt_subscribe
            id: datum4
            topic: /SmartHome/Display/B4
          - platform: mqtt_subscribe
            id: ereignis4
            topic: /SmartHome/Display/C4
          - platform: mqtt_subscribe
            id: akteur4
            topic: /SmartHome/Display/D4
             
         
             
             
         
         # Verwendete Zeichensätze
         font:
          - file: 'fonts/comic.ttf'
            id: font1
            glyphs:
               ['&', '@', '!', ',', '.', '?', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
                '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
                'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
                'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
                'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
                'u', 'v', 'w', 'x', 'y', 'z','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/']
            size: 30
          - file: 'fonts/bahnschrift.ttf'
            id: font2
            glyphs:
               ['&', '@', '!', ',', '.', '?', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
                '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
                'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
                'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
                'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
                'u', 'v', 'w', 'x', 'y', 'z','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/']
            size: 20
          - file: 'fonts/arialbd.ttf'
            id: font3
            glyphs:
               ['&', '@', '!', ',', '.', '?', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
                '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
                'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
                'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
                'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
                'u', 'v', 'w', 'x', 'y', 'z','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/']
            size: 14
          - file: 'fonts/arial.ttf'
            id: font4
            glyphs:
               ['&', '@', '!', ',', '.', '?', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
                '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
                'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
                'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
                'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
                'u', 'v', 'w', 'x', 'y', 'z','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/']
            size: 14
         
         #Waveshare display 4.2 inch
         spi:
          clk_pin: GPIO13
          mosi_pin: GPIO14
          id: waveshare_spi
         
         display:
          - platform: waveshare_epaper
            id: epaper_display
            cs_pin: GPIO15
            dc_pin: GPIO27
            busy_pin: GPIO25
            reset_pin: GPIO26
            spi_id: waveshare_spi
            model: 4.20in
            update_interval: never
            lambda: |-
             
              // Kopfzeile
              it.printf(8, 5, id(font3), TextAlign::TOP_LEFT, "%s",id(datum_akt).state.c_str());
              it.printf(200, 5, id(font3), TextAlign::TOP_CENTER, "%s",id(wochentag).state.c_str());
              it.printf(394, 5, id(font3), TextAlign::TOP_RIGHT, "%s / %s", id(kalenderwoche).state.c_str(), id(tpl_doy).state.c_str());
              it.line(8,20,395,20);
               
              // Header der Tabelle
              it.printf(200,50,id(font2), TextAlign::TOP_CENTER, "%s - %s",id(woche_von).state.c_str(),id(woche_bis).state.c_str());
              it.printf(200,80,id(font2), TextAlign::TOP_CENTER, "Flurreinigung: %s" ,id(flurreinigung).state.c_str());
                     
              // Rahmenlinien der Tabelle
              it.line(8, 110, 395, 110);
              it.line(8, 110, 8, 270);
              it.line(395, 110, 395, 270);
              it.line(8, 270, 395, 270);
              it.line(52, 110, 52, 270);
              it.line(130, 110, 130, 270);
              it.line(320, 110, 320, 270);
              it.line(8, 150, 395, 150);
              it.line(8, 190, 395, 190);
              it.line(8, 230, 395, 230);
              // Zeile 1
              it.print(18, 125, id(font2),id(wochentag1).state.c_str());
              it.print(60, 125, id(font2),id(datum1).state.c_str());
              it.print(140, 125, id(font2),id(ereignis1).state.c_str());
              it.print(329, 125, id(font2),id(akteur1).state.c_str());
              // Zeile 2
              it.print(18, 165, id(font2),id(wochentag2).state.c_str());
              it.print(60, 165, id(font2),id(datum2).state.c_str());
              it.print(140, 165, id(font2),id(ereignis2).state.c_str());
              it.print(329, 165, id(font2),id(akteur2).state.c_str());
              // zeile 3
              it.print(18, 205, id(font2),id(wochentag3).state.c_str());
              it.print(60, 205, id(font2),id(datum3).state.c_str());
              it.print(140, 205, id(font2),id(ereignis3).state.c_str());
              it.print(329, 205, id(font2),id(akteur3).state.c_str());
              // Zeile 4
              it.print(18, 245, id(font2),id(wochentag4).state.c_str());
              it.print(60, 245, id(font2),id(datum4).state.c_str());
              it.print(140, 245, id(font2),id(ereignis4).state.c_str());
              it.print(329, 245, id(font2),id(akteur4).state.c_str());
              // Fußzeile
              it.line(8,284,395,284);
              it.printf(8,300,id(font4),TextAlign::BOTTOM_LEFT, "RSSI: %.0f dBm",id(rssi_value_dsp).state);
              it.printf(200,300, id(font4),TextAlign::BOTTOM_CENTER, "Version: 1.1");
              it.printf(397, 300, id(font4),TextAlign::BOTTOM_RIGHT,"Daten von %s", id(tpl_hour_sec).state.c_str());

        Hinweis zum Listing: Teilweise reicht die Seitenbreite nicht zur Darstellung der Zeile aus. Sie wird dann in der nächsten Zeile ganz links fortgesetzt. Beispiel: Zeile 284 und 285 sind eine Programmzeile!

        Download der Konfigurationsdatei

      • Kompilieren der Konfiguration

      • Nachdem Sie die Konfiguration geschrieben und alle Leerräume und Einrückungen überprüft haben, können Sie mit

         I:\ESPHome>esphome run display-4in2.yaml

        die Kompilierung starten. Ein umfangreicher Prozess, der einige Zeit (ca. 3min) dauern kann (abhängig vom Rechner).

        Hinweis: Der Vorgang warnt an einigen Stellen vor der Verwendung bestimmter Ports, da können Sie getrost darüber hinwegsehen. Es sind Warnungen und keine Fehler.

        Solange keine Fehlermeldungen kommen, ist die Welt in Ordnung. Irgendwann zeigt der Rechner dann diese oder ähnliche Zeilen:

         ==============SUCCESS] Took 161.02 seconds =================================
         ←[32mINFO Successfully compiled program.←[0m
         Found multiple options, please choose one:
          [1] COM13 (Silicon Labs CP210x USB to UART Bridge (COM13))
          [2] COM3 (HP hs2340 HSPA+ Mobile Broadband Module Device Management (COM3))
          [3] COM4 (HP hs2340 HSPA+ Mobile Broadband Module Device Management (COM4))
          [4] COM5 (HP hs2340 HSPA+ Mobile Broadband Module Modem)
          [5] Over The Air (192.168.2.157)
         (number):

      • Hochladen der Software in den EP32

      • Nun fragt der Rechner, über welchen Weg er die Software installieren soll: mit der [1] COM13 (die Nummer 13 kann bei Ihnen eine andere sein) oder mit [5] Over The Air (OTA).

        Hinweis: Die Übertragungsart OTA kann nur dann benutzt werden, wenn das Programm bereits einmal über die COM-Schnittstelle geladen wurde und in der Konfiguration der Teil für OTA enthalten war. Ein OTA-Teil ist zwar enthalten, aber da es das erste Mal ist, werden wir [1] die COM-Schnittstelle auswählen

         (number): 1
         esptool.py v3.2
         Serial port COM13
         Connecting.....
         Chip is ESP32-D0WDQ6 (revision 1)
         ...
         ...
         ...
         ...
         ...
         Leaving...
         Hard resetting via RTS pin...
         ←[32mINFO Successfully uploaded program.←[0m
         ←[32mINFO Starting log output from COM13 with baud rate 115200←[0m
         [18:16:18]e[I][logger:214]: Log initialized
         [18:16:18][I][app:029]: Running through setup()...
         [18:16:18][I][wifi:245]: WiFi Connecting to 'xxxxx'...
         [18:16:20][I][wifi:502]: WiFi Connected!
         [18:16:20][I][mqtt:175]: Connecting to MQTT...
         [18:16:26][W][mqtt:260]: MQTT Disconnected: TCP disconnected.
         [18:16:26][I][mqtt:175]: Connecting to MQTT...
         [18:16:26][W][wifi:119]: WiFi Connection lost... Reconnecting...
         [18:16:26][I][wifi:245]: WiFi Connecting to 'xxxxx'...
         [18:16:28][I][wifi:502]: WiFi Connected!
         [18:17:26][I][mqtt:175]: Connecting to MQTT...
         [18:17:26][I][mqtt:215]: MQTT Connected!
         [18:17:26][I][deep_sleep:040]: Scheduling Deep Sleep to start in 12000 ms
         [18:17:26][I][app:062]: setup() finished successfully!
         [18:17:26][I][app:102]: ESPHome version 2022.1.1 compiled on Feb  8 2022, 18:14:16
         [18:17:38][I][deep_sleep:103]: Beginning Deep Sleep

        Nach der Auswahl werden etliche Zeilen produziert, die informativen Charakter haben. Sie können gut sehen, was wann passiert. Ich habe nicht alle Zeilen aufgeführt - zu viel für einen Blog, daher die Zeilen mit den „…“.

        Die farbigen Zeilen am Ende werden vom Logger gesteuert. Um 18:17:38 ging die Anzeige in den Tiefschlaf. Der wird in einer Stunde beendet sein und zu einem Rest führen. Wir warten ab. -------- ER ist wach geworden!!

         [19:17:06]ets Jun  8 2016 00:22:57
         [19:17:06]
         [19:17:06]rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
         [19:17:06]configsip: 0, SPIWP:0xee
         [19:17:06]clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
         [19:17:06]mode:DIO, clock div:2
         [19:17:06]load:0x3fff0018,len:4
         [19:17:06]load:0x3fff001c,len:1044
         [19:17:06]load:0x40078000,len:10124
         [19:17:06]load:0x40080400,len:5828
         [19:17:06]entry 0x400806a8
         [19:17:06][I][logger:214]: Log initialized
         [19:17:06][I][app:029]: Running through setup()...
         [19:17:06][I][wifi:245]: WiFi Connecting to 'BUEWLAN'...
         [19:17:09][I][wifi:502]: WiFi Connected!
         [19:17:09][I][mqtt:175]: Connecting to MQTT...
         [19:17:10][I][mqtt:215]: MQTT Connected!
         [19:17:10][I][deep_sleep:040]: Scheduling Deep Sleep to start in 12000 ms
         [19:17:10][I][app:062]: setup() finished successfully!
         [19:17:10][I][app:102]: ESPHome version 2022.1.1 compiled on Feb  8 2022, 18:14:16
         [19:17:22][I][deep_sleep:103]: Beginning Deep Sleep

        Der Tiefschlaf ist beendet. Ein Reset hat die Anzeige aufgeweckt und mit neuen Daten versehen. Keine Warnung, alles Bestens.

        Theoretisch wäre es möglich, die Dauer des Tiefschlafes auf 24 Stunden zu vergrößern. Das würde ich nicht empfehlen, weil die interne Uhr des ESP32 nicht exakt läuft und sich der Aktualisierungszeitpunkt immer weiter verschieben würde. Wir sehen hier schon eine Verschiebung von 20 Sekunden. Ich empfehle einen Tiefschlaf - je nach Art des Kalenders - zwischen 1 und 4 Stunden. Wenn sich der dargestellte Kalender im Laufe des Tages ändern kann, ist eine Dauer von einer Stunde sinnvoll.

        Ich habe in der Fußzeile die Uhrzeit eingeblendet. Sie zeigt an, zu welcher Uhrzeit die Daten vom Broker abgeholt wurden. Das Datum steht in der Kopfzeile links und die zugehörige Uhrzeit in der Fußzeile rechts. Ist die Datenübertragung defekt, ist der Zeitpunkt der letztmaligen Übermittlung ablesbar.


      • Aufgetretene Fehler

      • Die Anzeige wird nicht komplett dargestellt:

        deep-sleep: besitzt eine Wachphase (run_duration: ) und display: ein update_intervall: . Das display: benötigt einige Sekunden. um die Anzeige zu aktualisieren. Wenn display: die Aktualisierung noch nicht beendet hat, der Timer für die Wachphase aber bereits abgelaufen ist, geht das System gnadenlos in den deep-sleep und kümmert sich nicht darum, ob die Aktualisierung abgeschlossen wurde oder nicht. Ergebnis: Die Anzeige hat unausgefüllte Felder. Abhilfe geht nur über eine Veränderung der beiden o.g. Timereinstellungen: run_duration: muss so groß gewählt werden, dass die Aktualisierung von display: sicher abgeschlossen wurde.

        In der jetzigen Version habe ich das update_intervall: auf never gesetzt, dadurch kommen sich die beiden Timer nicht in die Quere. Ich habe diesen Fehler für Ihre weiteren Projekte aufgeführt, da er mich einige Zeit beschäftigt hatte.

        Der Bildschirm bleibt nach einem Reset dunkel

        Bitte überprüfen Sie, ob der Schalter „Start Deep-Sleep“in Node-Red auf „Aus“ steht. Steht er auf “Ein“ wird bereits innerhalb des Setups ein Deep-Sleep initiiert. Dann wird das Setup nicht ordnungsgemäß abgeschlossen.


        Mit Ihrem jetzigen Wissen können Sie Ihre Wünsche nach einem eigenen, individuellen Kalender problemlos in die Tat umsetzen. Nun wünsche ich Ihnen viel Vergnügen mit Ihrem Display.

        Teil 1, Teil 3


        Eberhard Werminghoff

        DisplaysEsp-32Projekte für anfängerSmart home

        8 Reacties

        Andreas Wolter

        Andreas Wolter

        @Max: bitte mal versuchen, den Quelltext statt mit der Maus zu markieren und zu kopieren, statt den “Kopieren”-Button zu verwenden.
        Eventuell ist damit das Problem schon gelöst.

        Grüße,
        Andreas Wolter

        Max

        Max

        Hallo zusammen,
        erstmal sehr cooles Projekt.
        Ich habe versuch den Node-Red “Code” zu kopiern und zum laufen zu bringen.
        Leider erscheint bei mir der Fehler: “TypeError: Cannot read property ‘options’ of undefined”
        Der msg.payload ist dabei [empty].
        Ich habe das ganze schon mit dieversen Kalendern ausprobiert.
        Habt ihr einen Tipp?

        Andreas Wolter

        Andreas Wolter

        in Absprache mit Herrn Werminghoff wird es durch die Initialzündung von @Bernhard einen dritten Teil geben. Herr Werminghoff versucht, die Änderungen vorzunehmen und dann zu zeigen, die nötig sind, um einen AZ-Touch MOD verwenden zu können.
        Es gibt einige Stolpersteine, die es noch zu überwinden gilt.

        Grüße,
        Andreas Wolter
        AZ-Delivery Blog

        Eberhard

        Eberhard

        Hallo Gunnar,
        der Schlüssel auf Deine Frage liegt im Node-Red-Knoten für den Kalender. Der heiße “ical” . Also bin ich mir sicher, das es funktioniert. Du benötigt einen Link auf Deinen ical-Kalender, den Du, wie ich es beschrieben habe, eintragen musst.
        Grüße Eberhard

        Gunnar

        Gunnar

        Hallo Andreas,

        herzlichen Dank für deine Ausführung!

        Ich habe zum Thema “Kalender eintragen in Node-Red” eine Frage:
        Hier wird die Übernahme von Daten aus dem Google Kalender beschrieben. Geht das auch mit Daten aus dem Apple Kalender über iCloud? Hierbei handelt es sich auch um ical Daten, die ich schon erfolgreich als externe Kalender in Outlook eingebunden habe.
        Sollte doch dann auch passen, oder ???

        Glück auf!
        Gunnar

        Andreas Wolter

        Andreas Wolter

        @Bernhard: die Umsetzung wäre sicher möglich.
        Dabei müsste man das Projekt zerlegen. Das eine ist die Umsetzung auf dem anderen MicroController. Hier im Beitrag ist es ein ESP32. An der Stelle, wo Sie per Kommandozeile nach ESP32 suchen und das AZ Dev Kit eingeben, müssten Sie ESP8266 eingeben und nach dem D1 Mini Ausschau halten. Dann den korrekten Namen aus der angezeigten Liste eingeben.

        Das Nächste wäre die Ausgabe auf dem Display. Hier wurde ein ePaper Display verwendet. Die Einstellungen dazu finden Sie in der display-4in2.yaml ab Zeile 247. Dort müsste dann die Konfiguration geändert werden, um das TFT Touch Display des AZ Touch MOD anzusprechen.
        Wie man das Display konfiguriert, wird hier beschrieben:
        https://esphome.io/components/display/index.html

        Die Informationen zum Display, das im AZ Touch MOD verwendet wird, stehen hier:
        https://esphome.io/components/display/ili9341.html

        Das wäre zumindest ein erster Ansatz.

        Grüße,
        Andreas Wolter
        AZ-Delivery Blog

        Bernhard

        Bernhard

        Ich habe zu dem Projekt eine Frage, und zwar ließe sich das Projekt auch auf einem AZ-Touch MOD Wandgehäuseset mit 2,8 Zoll Touchscreen für ESP8266 und ESP32 – 1x AZ-Touch und dem ESP8266 umsetzen. Hier hätten wir ein schönes Gehäuse, einen Touchscreen und und und. Nur bin ich nicht Fachmann genug, um das alles zu beurteilen. Es wäre schön, wenn meine Frage vielleicht als Anregung aufgenommen würde.
        Herzlichen Dank für die vielen tollen Projekte.
        Bernhard Schmitz

        Martin Richer

        Martin Richer

        Vielen Dank für den zweiten Teil!!!
        Wird super beim nachbauen 😊

        Laat een reactie achter

        Alle opmerkingen worden voor publicatie gecontroleerd door een moderator

        Aanbevolen blogberichten

        1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
        2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
        3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
        4. ESP32 - das Multitalent - AZ-Delivery